diff --git a/chapter-15/src/main/scala/sample/snippet/Words.scala b/chapter-15/src/main/scala/sample/snippet/Words.scala index 6b0d9d1..6d6a558 100644 --- a/chapter-15/src/main/scala/sample/snippet/Words.scala +++ b/chapter-15/src/main/scala/sample/snippet/Words.scala @@ -8,12 +8,13 @@ class Words extends DispatchSnippet { object WordHolder extends ContainerVar[String]("n/a") def dispatch = { - case "update" => update _ + case "update" => update case "show" => show _ } - def update(xhtml: NodeSeq): NodeSeq = bind("f",xhtml, - "word" -> SHtml.text(WordHolder.is, WordHolder(_)), - "submit" -> SHtml.submit("Update >>", () => println("Submitted!")) - ) + + def update = + "type=text" #> SHtml.text(WordHolder.is, WordHolder(_)) & + "type=submit" #> SHtml.submit("Update >>", () => println("Submitted!")) + def show(xhtml: NodeSeq): NodeSeq = Text(WordHolder.is) } diff --git a/chapter-15/src/main/webapp/words.html b/chapter-15/src/main/webapp/words.html index 0e2451d..f383f33 100644 --- a/chapter-15/src/main/webapp/words.html +++ b/chapter-15/src/main/webapp/words.html @@ -3,8 +3,7 @@

The current word is:

Well, thats just fantastic. See the form below if you want to update this value.

Update

- -

Word to distribute:

-
- +
+

Word to distribute:

+
diff --git a/tools/h2/docs/h2.pdf b/tools/h2/docs/h2.pdf deleted file mode 100755 index 5f10f87..0000000 Binary files a/tools/h2/docs/h2.pdf and /dev/null differ diff --git a/tools/h2/docs/html/advanced.html b/tools/h2/docs/html/advanced.html deleted file mode 100755 index f6c720d..0000000 --- a/tools/h2/docs/html/advanced.html +++ /dev/null @@ -1,787 +0,0 @@ - - - - -Advanced - - - - - - - - - - - - - - diff --git a/tools/h2/docs/html/build.html b/tools/h2/docs/html/build.html deleted file mode 100755 index 0464b9e..0000000 --- a/tools/h2/docs/html/build.html +++ /dev/null @@ -1,263 +0,0 @@ - - - - -Build - - - - - - - - - - - - - - - diff --git a/tools/h2/docs/html/changelog.html b/tools/h2/docs/html/changelog.html deleted file mode 100755 index a17d84a..0000000 --- a/tools/h2/docs/html/changelog.html +++ /dev/null @@ -1,190 +0,0 @@ - - - - -Change Log - - - - - - - - - - - - - - - diff --git a/tools/h2/docs/html/cheatSheet.html b/tools/h2/docs/html/cheatSheet.html deleted file mode 100755 index 430dec4..0000000 --- a/tools/h2/docs/html/cheatSheet.html +++ /dev/null @@ -1,170 +0,0 @@ - - - - -H2 Database Engine - - - - -
- -

H2 Database Engine Cheat Sheet

-
- -

Using H2

- - -

Documentation

-

- Reference: SQL grammar, functions, data types, tools, API
-Features: fulltext search, encryption, read-only (zip/jar), CSV, auto-reconnect, triggers, user functions

- -

Database URLs

-

-Embedded
-jdbc:h2:~/test 'test' in the user home directory
-jdbc:h2:/data/test 'test' in the directory /data
-jdbc:h2:test in the current(!) working directory
-

-In-Memory
-jdbc:h2:mem:test multiple connections in one process
-jdbc:h2:mem: unnamed private; one connection
-

-Server Mode
-jdbc:h2:tcp://localhost/~/test user home dir
-jdbc:h2:tcp://localhost//data/test absolute dir
-Server start:java -cp *.jar org.h2.tools.Server

-Settings
-jdbc:h2:..;MODE=MySQL compatibility (or HSQLDB,...)
-jdbc:h2:..;TRACE_LEVEL_FILE=3 log to *.trace.db
-

- -
-
- -

Using the JDBC API

-
-Class.forName("org.h2.Driver");
-Connection conn = DriverManager.
-    getConnection("jdbc:h2:~/test");
-conn.close();
-
- -

Connection Pool

-
-import org.h2.jdbcx.JdbcConnectionPool;
-JdbcConnectionPool cp = JdbcConnectionPool.
-    create("jdbc:h2:~/test", "sa", "sa");
-Connection conn = cp.getConnection();
-conn.close(); cp.dispose();
-
- -

Maven 2

-
-<dependency>
-    <groupId>com.h2database</groupId>
-    <artifactId>h2</artifactId>
-    <version>1.2.137</version>
-</dependency>
-
- -

Hibernate

-

- hibernate.cfg.xml (or use the HSQLDialect):

-
-<property name="dialect">
-    org.hibernate.dialect.H2Dialect
-</property>
-
- -

TopLink and Glassfish

-

- Datasource class: org.h2.jdbcx.JdbcDataSource
-oracle.toplink.essentials.platform.
-database.H2Platform -

- -
- -
- - \ No newline at end of file diff --git a/tools/h2/docs/html/datatypes.html b/tools/h2/docs/html/datatypes.html deleted file mode 100755 index ef65707..0000000 --- a/tools/h2/docs/html/datatypes.html +++ /dev/null @@ -1,495 +0,0 @@ - - - - -Data Types - - - - - - - - - - - - - - - diff --git a/tools/h2/docs/html/download.html b/tools/h2/docs/html/download.html deleted file mode 100755 index a8cca95..0000000 --- a/tools/h2/docs/html/download.html +++ /dev/null @@ -1,161 +0,0 @@ - - - - -Downloads - - - - - - - - - - - - - - - diff --git a/tools/h2/docs/html/faq.html b/tools/h2/docs/html/faq.html deleted file mode 100755 index 9cd85cf..0000000 --- a/tools/h2/docs/html/faq.html +++ /dev/null @@ -1,238 +0,0 @@ - - - - -Frequently Asked Questions - - - - - - - - - - - - - - diff --git a/tools/h2/docs/html/features.html b/tools/h2/docs/html/features.html deleted file mode 100755 index 2b17ac2..0000000 --- a/tools/h2/docs/html/features.html +++ /dev/null @@ -1,1206 +0,0 @@ - - - - -Features - - - - - - - - - - - - - - - diff --git a/tools/h2/docs/html/fragments.html b/tools/h2/docs/html/fragments.html deleted file mode 100755 index b93573f..0000000 --- a/tools/h2/docs/html/fragments.html +++ /dev/null @@ -1,119 +0,0 @@ - - - - Fragments - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/tools/h2/docs/html/frame.html b/tools/h2/docs/html/frame.html deleted file mode 100755 index 27bba98..0000000 --- a/tools/h2/docs/html/frame.html +++ /dev/null @@ -1,28 +0,0 @@ - - - - H2 Database Engine - - - - - -

H2 Database Engine

-

- Welcome to H2, the free SQL database. The main feature of H2 are:

- - -

No Javascript

-

- 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.

- Please enable Javascript, or go ahead without it: H2 Database Engine

- - \ No newline at end of file diff --git a/tools/h2/docs/html/functions.html b/tools/h2/docs/html/functions.html deleted file mode 100755 index 56a27ec..0000000 --- a/tools/h2/docs/html/functions.html +++ /dev/null @@ -1,2606 +0,0 @@ - - - - -Functions - - - - - - - - - - - - - - - diff --git a/tools/h2/docs/html/grammar.html b/tools/h2/docs/html/grammar.html deleted file mode 100755 index ca0dd59..0000000 --- a/tools/h2/docs/html/grammar.html +++ /dev/null @@ -1,2993 +0,0 @@ - - - - -SQL Grammar - - - - - - - - - - - - - - diff --git a/tools/h2/docs/html/history.html b/tools/h2/docs/html/history.html deleted file mode 100755 index 036fe3b..0000000 --- a/tools/h2/docs/html/history.html +++ /dev/null @@ -1,166 +0,0 @@ - - - - -History - - - - - - - - - - - - - - - diff --git a/tools/h2/docs/html/images/connection-mode-embedded.png b/tools/h2/docs/html/images/connection-mode-embedded.png deleted file mode 100755 index ffbccfc..0000000 Binary files a/tools/h2/docs/html/images/connection-mode-embedded.png and /dev/null differ diff --git a/tools/h2/docs/html/images/connection-mode-mixed.png b/tools/h2/docs/html/images/connection-mode-mixed.png deleted file mode 100755 index a3a3970..0000000 Binary files a/tools/h2/docs/html/images/connection-mode-mixed.png and /dev/null differ diff --git a/tools/h2/docs/html/images/connection-mode-remote.png b/tools/h2/docs/html/images/connection-mode-remote.png deleted file mode 100755 index 50bba17..0000000 Binary files a/tools/h2/docs/html/images/connection-mode-remote.png and /dev/null differ diff --git a/tools/h2/docs/html/images/console.png b/tools/h2/docs/html/images/console.png deleted file mode 100755 index 39a7ef5..0000000 Binary files a/tools/h2/docs/html/images/console.png and /dev/null differ diff --git a/tools/h2/docs/html/images/db-16.png b/tools/h2/docs/html/images/db-16.png deleted file mode 100755 index d5340e5..0000000 Binary files a/tools/h2/docs/html/images/db-16.png and /dev/null differ diff --git a/tools/h2/docs/html/images/div-d.png b/tools/h2/docs/html/images/div-d.png deleted file mode 100755 index 2bd6075..0000000 Binary files a/tools/h2/docs/html/images/div-d.png and /dev/null differ diff --git a/tools/h2/docs/html/images/div-ke.png b/tools/h2/docs/html/images/div-ke.png deleted file mode 100755 index e99a46b..0000000 Binary files a/tools/h2/docs/html/images/div-ke.png and /dev/null differ diff --git a/tools/h2/docs/html/images/div-ks.png b/tools/h2/docs/html/images/div-ks.png deleted file mode 100755 index 2e14aaf..0000000 Binary files a/tools/h2/docs/html/images/div-ks.png and /dev/null differ diff --git a/tools/h2/docs/html/images/div-le.png b/tools/h2/docs/html/images/div-le.png deleted file mode 100755 index cf1aefd..0000000 Binary files a/tools/h2/docs/html/images/div-le.png and /dev/null differ diff --git a/tools/h2/docs/html/images/div-ls.png b/tools/h2/docs/html/images/div-ls.png deleted file mode 100755 index 2fb4148..0000000 Binary files a/tools/h2/docs/html/images/div-ls.png and /dev/null differ diff --git a/tools/h2/docs/html/images/div-te.png b/tools/h2/docs/html/images/div-te.png deleted file mode 100755 index e8fed03..0000000 Binary files a/tools/h2/docs/html/images/div-te.png and /dev/null differ diff --git a/tools/h2/docs/html/images/div-ts.png b/tools/h2/docs/html/images/div-ts.png deleted file mode 100755 index 125916d..0000000 Binary files a/tools/h2/docs/html/images/div-ts.png and /dev/null differ diff --git a/tools/h2/docs/html/images/download.png b/tools/h2/docs/html/images/download.png deleted file mode 100755 index 51748dc..0000000 Binary files a/tools/h2/docs/html/images/download.png and /dev/null differ diff --git a/tools/h2/docs/html/images/h2-logo.png b/tools/h2/docs/html/images/h2-logo.png deleted file mode 100755 index 76402f0..0000000 Binary files a/tools/h2/docs/html/images/h2-logo.png and /dev/null differ diff --git a/tools/h2/docs/html/images/h2-logo_square.png b/tools/h2/docs/html/images/h2-logo_square.png deleted file mode 100755 index 2714448..0000000 Binary files a/tools/h2/docs/html/images/h2-logo_square.png and /dev/null differ diff --git a/tools/h2/docs/html/images/icon_disconnect.gif b/tools/h2/docs/html/images/icon_disconnect.gif deleted file mode 100755 index 2ece8d8..0000000 Binary files a/tools/h2/docs/html/images/icon_disconnect.gif and /dev/null differ diff --git a/tools/h2/docs/html/images/language_de.png b/tools/h2/docs/html/images/language_de.png deleted file mode 100755 index 0109c35..0000000 Binary files a/tools/h2/docs/html/images/language_de.png and /dev/null differ diff --git a/tools/h2/docs/html/images/language_en.gif b/tools/h2/docs/html/images/language_en.gif deleted file mode 100755 index a48f4ad..0000000 Binary files a/tools/h2/docs/html/images/language_en.gif and /dev/null differ diff --git a/tools/h2/docs/html/images/language_ja.gif b/tools/h2/docs/html/images/language_ja.gif deleted file mode 100755 index 5e1d040..0000000 Binary files a/tools/h2/docs/html/images/language_ja.gif and /dev/null differ diff --git a/tools/h2/docs/html/images/mail-support.png b/tools/h2/docs/html/images/mail-support.png deleted file mode 100755 index 8ff5349..0000000 Binary files a/tools/h2/docs/html/images/mail-support.png and /dev/null differ diff --git a/tools/h2/docs/html/images/performance.png b/tools/h2/docs/html/images/performance.png deleted file mode 100755 index 368fbf7..0000000 Binary files a/tools/h2/docs/html/images/performance.png and /dev/null differ diff --git a/tools/h2/docs/html/images/quickstart-1.png b/tools/h2/docs/html/images/quickstart-1.png deleted file mode 100755 index 276680c..0000000 Binary files a/tools/h2/docs/html/images/quickstart-1.png and /dev/null differ diff --git a/tools/h2/docs/html/images/quickstart-2.png b/tools/h2/docs/html/images/quickstart-2.png deleted file mode 100755 index ee9fd9d..0000000 Binary files a/tools/h2/docs/html/images/quickstart-2.png and /dev/null differ diff --git a/tools/h2/docs/html/images/quickstart-3.png b/tools/h2/docs/html/images/quickstart-3.png deleted file mode 100755 index fba9e42..0000000 Binary files a/tools/h2/docs/html/images/quickstart-3.png and /dev/null differ diff --git a/tools/h2/docs/html/images/quickstart-4.png b/tools/h2/docs/html/images/quickstart-4.png deleted file mode 100755 index 08a02b5..0000000 Binary files a/tools/h2/docs/html/images/quickstart-4.png and /dev/null differ diff --git a/tools/h2/docs/html/images/quickstart-5.png b/tools/h2/docs/html/images/quickstart-5.png deleted file mode 100755 index b2f007d..0000000 Binary files a/tools/h2/docs/html/images/quickstart-5.png and /dev/null differ diff --git a/tools/h2/docs/html/images/quickstart-6.png b/tools/h2/docs/html/images/quickstart-6.png deleted file mode 100755 index e981477..0000000 Binary files a/tools/h2/docs/html/images/quickstart-6.png and /dev/null differ diff --git a/tools/h2/docs/html/images/screenshot.png b/tools/h2/docs/html/images/screenshot.png deleted file mode 100755 index 9d7d7e6..0000000 Binary files a/tools/h2/docs/html/images/screenshot.png and /dev/null differ diff --git a/tools/h2/docs/html/index.js b/tools/h2/docs/html/index.js deleted file mode 100755 index e327f32..0000000 --- a/tools/h2/docs/html/index.js +++ /dev/null @@ -1,108 +0,0 @@ -var pages=new Array(); -var ref=new Array(); -var ignored=''; -function Page(title, file) { this.title=title; this.file=file; } -function load() { -pages[0]=new Page('SQL Grammar', 'html/grammar.html'); -pages[1]=new Page('Advanced', 'html/advanced.html'); -pages[2]=new Page('Features', 'html/features.html'); -pages[3]=new Page('ResultSet', 'javadoc/org/h2/jdbc/JdbcResultSet.html'); -pages[4]=new Page('Change Log', 'html/changelog.html'); -pages[5]=new Page('DatabaseMetaData', 'javadoc/org/h2/jdbc/JdbcDatabaseMetaData.html'); -pages[6]=new Page('ErrorCode', 'javadoc/org/h2/constant/ErrorCode.html'); -pages[7]=new Page('Functions', 'html/functions.html'); -pages[8]=new Page('Tutorial', 'html/tutorial.html'); -pages[9]=new Page('Roadmap', 'html/roadmap.html'); -pages[10]=new Page('License', 'html/license.html'); -pages[11]=new Page('Performance', 'html/performance.html'); -pages[12]=new Page('PreparedStatement', 'javadoc/org/h2/jdbc/JdbcPreparedStatement.html'); -pages[13]=new Page('SysProperties', 'javadoc/org/h2/constant/SysProperties.html'); -pages[14]=new Page('Statement', 'javadoc/org/h2/jdbc/JdbcStatement.html'); -pages[15]=new Page('SimpleResultSet', 'javadoc/org/h2/tools/SimpleResultSet.html'); -pages[16]=new Page('Connection', 'javadoc/org/h2/jdbc/JdbcConnection.html'); -pages[17]=new Page('H2 In Use and Links', 'html/links.html'); -pages[18]=new Page('CallableStatement', 'javadoc/org/h2/jdbc/JdbcCallableStatement.html'); -pages[19]=new Page('FullText', 'javadoc/org/h2/fulltext/FullText.html'); -pages[20]=new Page('Build', 'html/build.html'); -pages[21]=new Page('Frequently Asked Questions', 'html/faq.html'); -pages[22]=new Page('Data Types', 'html/datatypes.html'); -pages[23]=new Page('JaQu', 'html/jaqu.html'); -pages[24]=new Page('ResultSetMetaData', 'javadoc/org/h2/jdbc/JdbcResultSetMetaData.html'); -pages[25]=new Page('Csv', 'javadoc/org/h2/tools/Csv.html'); -pages[26]=new Page('FullTextLucene', 'javadoc/org/h2/fulltext/FullTextLucene.html'); -pages[27]=new Page('Server', 'javadoc/org/h2/tools/Server.html'); -pages[28]=new Page('JdbcDataSource', 'javadoc/org/h2/jdbcx/JdbcDataSource.html'); -pages[29]=new Page('Array', 'javadoc/org/h2/jdbc/JdbcArray.html'); -pages[30]=new Page('Blob', 'javadoc/org/h2/jdbc/JdbcBlob.html'); -pages[31]=new Page('TriggerAdapter', 'javadoc/org/h2/tools/TriggerAdapter.html'); -pages[32]=new Page('JdbcXAConnection', 'javadoc/org/h2/jdbcx/JdbcXAConnection.html'); -pages[33]=new Page('JdbcConnectionPool', 'javadoc/org/h2/jdbcx/JdbcConnectionPool.html'); -pages[34]=new Page('History', 'html/history.html'); -pages[35]=new Page('FullTextSettings', 'javadoc/org/h2/fulltext/FullTextSettings.html'); -pages[36]=new Page('H2 Database Engine', 'html/cheatSheet.html'); -pages[37]=new Page('Trigger', 'javadoc/org/h2/api/Trigger.html'); -pages[38]=new Page('RunScript', 'javadoc/org/h2/tools/RunScript.html'); -pages[39]=new Page('MultiDimension', 'javadoc/org/h2/tools/MultiDimension.html'); -pages[40]=new Page('ParameterMetaData', 'javadoc/org/h2/jdbc/JdbcParameterMetaData.html'); -pages[41]=new Page('DatabaseEventListener', 'javadoc/org/h2/api/DatabaseEventListener.html'); -pages[42]=new Page('Clob', 'javadoc/org/h2/jdbc/JdbcClob.html'); -pages[43]=new Page('SQLException', 'javadoc/org/h2/jdbc/JdbcSQLException.html'); -pages[44]=new Page('Shell', 'javadoc/org/h2/tools/Shell.html'); -pages[45]=new Page('Quickstart', 'html/quickstart.html'); -pages[46]=new Page('ChangeFileEncryption', 'javadoc/org/h2/tools/ChangeFileEncryption.html'); -pages[47]=new Page('Script', 'javadoc/org/h2/tools/Script.html'); -pages[48]=new Page('Backup', 'javadoc/org/h2/tools/Backup.html'); -pages[49]=new Page('Recover', 'javadoc/org/h2/tools/Recover.html'); -pages[50]=new Page('AggregateFunction', 'javadoc/org/h2/api/AggregateFunction.html'); -pages[51]=new Page('Installation', 'html/installation.html'); -pages[52]=new Page('Console', 'javadoc/org/h2/tools/Console.html'); -pages[53]=new Page('CreateCluster', 'javadoc/org/h2/tools/CreateCluster.html'); -pages[54]=new Page('Restore', 'javadoc/org/h2/tools/Restore.html'); -pages[55]=new Page('CompressTool', 'javadoc/org/h2/tools/CompressTool.html'); -pages[56]=new Page('DeleteDbFiles', 'javadoc/org/h2/tools/DeleteDbFiles.html'); -pages[57]=new Page('JdbcDataSourceFactory', 'javadoc/org/h2/jdbcx/JdbcDataSourceFactory.html'); -pages[58]=new Page('ConvertTraceFile', 'javadoc/org/h2/tools/ConvertTraceFile.html'); -pages[59]=new Page('Fragments', 'html/fragments.html'); -pages[60]=new Page('SimpleRowSource', 'javadoc/org/h2/tools/SimpleRowSource.html'); -pages[61]=new Page('SimpleResultSet.SimpleArray', 'javadoc/org/h2/tools/SimpleResultSet.SimpleArray.html'); -pages[62]=new Page('Savepoint', 'javadoc/org/h2/jdbc/JdbcSavepoint.html'); -pages[63]=new Page('Downloads', 'html/download.html'); -pages[64]=new Page('FullText.FullTextTrigger', 'javadoc/org/h2/fulltext/FullText.FullTextTrigger.html'); -pages[65]=new Page('FullTextLucene.FullTextTrigger', 'javadoc/org/h2/fulltext/FullTextLucene.FullTextTrigger.html'); -pages[66]=new Page('IndexInfo', 'javadoc/org/h2/fulltext/IndexInfo.html'); -pages[67]=new Page('JdbcXid', 'javadoc/org/h2/jdbcx/JdbcXid.html'); -pages[68]=new Page('TableEngine', 'javadoc/org/h2/api/TableEngine.html'); -pages[69]=new Page('API Overview', 'javadoc/overview.html'); -pages[70]=new Page('H2 Database Engine', 'html/main.html'); -pages[71]=new Page('BatchUpdateException', 'javadoc/org/h2/jdbc/JdbcBatchUpdateException.html'); -// words: 5047 -ref['_']='_DATA=9;_messages_=20;_MODIFIED=9;_QUERY=9;_rowid_=9;_text_=20'; -ref['a']='abbreviate=13;abbreviated=4;ability=9,17;able=1,2,9,10;abnormal=1;aborted=1;above=10,1,20,11,2,4;abs=h7,r6;absence=10;absolute=3,13,36,1;absolutely=10;abstraction=4;aca899=36;accept=9,2,8,10,1;acceptable=1;ACCEPTANCE=10;accepted=10;access=h2,1,23,r9,8,5,17,4,6,45,16,44,27;ACCESS_DENIED_TO_CLASS_1=h6;ACCESS_MODE_DATA=2,6;ACCESS_MODE_LOG=4;AccessControlException=4,8;accessed=11,15,3,2,1,25,9,4,8,41;accessible=1,0;accessing=2,6;accesskey=9;ACCOMPANYING=10;accordance=10;according=6,16,21,11,4;accordingly=7,8,1;account=11,10;accu=11;accumulated=11;AccuProcess=17;Achieve=h1;achieved=2,1;ACID=h1;acm=9;acme=2,0,11,41,1;ACOS=h7;acquire=10;acquired=10;across=5,7;acting=10;action=5,10,31,0,37,4,17,8;activation=9;active=33,1;actively=1;acts=2,10;actual=22,0,4,10;actually=11,2,0,1;adapter=31,51,1;addBatch=12,14;addColumn=2,15,8,4;addConnectionEventListener=32;added=4,2,10,1,8,9,11,45,15,0,6,43,13;addiction=5;addIndexInfo=35;adding=h8,r9,2,4,15,6,0,1;addInt=7;addition=10,2,5,21,1;additional=h2,r10,52,7,11,5,27,49,8,13,21;additionally=9,2;address=h1,r2,6,8,9,17,7,4,0;ADDRESS_VIEW=0;addresses=9,17,53,1;addRow=15,2,4,8;addString=7;addWords=19;Adeptia=17;admin=h0,r7,6,1,4,9;ADMIN_RIGHTS_REQUIRED=h6;administration=17,2;administrator=8,1,2,6;admission=10;ADO=h1,r17;adp=9;advanced=t1,r17,22,2,27,59;advantage=1,11,4,8;ADVISED=10;Aejaks=17;AES=2,1,0,7,6,46;affect=0,14,2,5,10,21,13;affected=14,0,12;afterLast=3;afterwards=1,11,8,2,5,20;again=1,4,55,9,17,27,21;against=h1,r10,38,4,9,27,6,8,23,13;agent=9;aggregate=h0,7,r50,6,4,2,1;AGGREGATE_NOT_FOUND_1=h6;aggregated=50;AggregateFunction=t50,r0;aggregateName=0;agree=10;agreeable=10;agreed=10;agreement=10;Ajax=17;alert=9;algorithm=h1,r2,55,7,11,4,0,6,17,34,39,8,46;algorithmString=7;alias=h0,r2,6,4,5,1,8,21,13,9,26,23,19;ALIAS_CATALOG=0;ALIAS_COLUMN_NAME=h13;ALIAS_NAME=0;ALIAS_SCHEMA=0;aliasColumnName=13,21;aliased=2,13;aliases=9,2,0;aliasing=5;aliasName=2;align=36;alive=9,2;alleged=10;alleging=10;allocate=9;allocated=0,13;allow=9,1,8,4,10,27,6,2,17,11,0,52,23,31,46,22;ALLOW_BIG_DECIMAL_EXTENSIONS=h13;ALLOW_LITERALS=h0,r1,6;allowBigDecimalExtensions=6,13;allowed=0,7,2,6,1,5,4,12,27,3,8,10;ALLOWED_CLASSES=h13;allowedClasses=1,6,13;allProceduresAreCallable=5;allTablesAreSelectable=5;almost=11,4;alone=10,55,4;alpha=4;already=h2,r6,4,8,0,1,9,10,7,28,34,33,20,19;alter=h0,r6,4,9,5,10,2;altering=6;alternative=17,9,2,4,10,1;altersequence=9;although=10;ambiguous=6;AMBIGUOUS_COLUMN_NAME_1=h6;America=10;amount=11,2,6,7,4,8,10,23,0,1;analysis=9,17,20;analyze=h0,11,r13,9,4,21,38,20;ANALYZE_AUTO=h13;ANALYZE_SAMPLE=h13;analyzeAuto=9,4,13;analyzer=9,20,59;analyzeSample=13;analyzing=17,13;andCondition=0;andrew=9;ANGLE=7;annotation=23;annual=1;ano=6;anonymous=1,13;another=h8,r2,1,6,4,7,14,11,0,12,23,10,5,17,9,53;ANSI=2,1;Ansorg=34;answers=20;ant=17,6;Antonio=34;anyone=10;anything=0,3,10;anywhere=0,1;Anzo=17;apache=17,9,2,8,21,26;api=t69,h1,2,36,r17,9,5,23,10,0,6,8,11,20,21;apos=0;app=4,9,17;apparatus=10;appear=8,11,45,6,1,7,4,10,0,21;append=1,4,2,9,0;appendChild=59;appended=0;appending=2,1;Appendix=59;AppEngine=4;AppFuse=17;Applets=9;applicable=10,9,6;applied=9,2,8;applies=2,10,21,1;apply=10,1,2,0;applying=4;approach=9;appropriate=10;appropriateness=10;approximate=5;arbitrary=14,12,22;Architectural=17;architecture=17,1;archival=10;Archive=8,7,9;archiving=10;area=21,2,9,45,1;argument=27,52,38,49,48,54,4,56,44,50,47,5,53,58,46;Arial=36;arising=10;army=17;arose=10;around=1,7,11,2,4,13;arrangement=10;ARRAY_GET=h7;ARRAY_LENGTH=h7;arrayExpression=7;ArrayIndexOutOfBoundsException=4;ArrayList=19,9;arrayType=0;art_anlytc=9;article=h17,r9;artifactId=20,36;ASC=5,0,7;ASC_OR_DESC=5,0;ascending=13,9,5,4,0;ASCII=h7,r12,4;Ashwin=34;ASIN=h7;asked=t21,r8;Aspect=17;assert=10;asserting=10;assertions=13,9;Asset=17;assign=9,6,10;assigned=8,0;associated=10,8,1;assume=10;assurances=10;asynchronous=9,4;ATAN=h7;atan2=h7;aTimestamp=7;Atom=4,63;atomic=1,0;atomically=1;Atomicity=h1;attached=27,10;attachment=20;attack=1,13,9;attacker=1,2;attempt=9,10;attempted=14;attorneys=10;attribute=8,7;attributeNamePattern=5;attributesString=7;August=2;Austria=34;authentication=1,9,2;author=9,34;AUTHORIZATION=0,9,1;authorized=10;auto=h2,r16,0,9,4,5,14,12,36,23,7,8,22;auto_increment=0,9,5,4;AUTO_RECONNECT=2,4,21,1;AUTO_SERVER=2,4,9,21;autocommit=h0,7,1,r6,11,2,16,9,4,8;autocommit_false=8;autocommit_true=8;autoCommitFailureClosesAllResultSets=5;autocomplete=9,2;autoGeneratedKeys=14,12,16;autoincrement=14,24,2;automate=17;automated=h20,r17,63,21,1;automatic=h2,r9,4;automatically=2,9,0,8,11,1,10,21,4,7,13,36,45,26,6,19,20;automation=17;availability=h1,10,r17;aValue=7;average=7,0,22;AVG=h7;AVL=9;avoid=9,2,1,11,4,8,10,0,20,13;avoided=11,20,21;aware=10;away=9;Axiom=17'; -ref['b']='backed=61,11,2;backend=11;Backgammon=17;background=36,9;backslash=4,0;backup=t48,h8,2,0,r17,9,6,54,4,11,38,47,21;backward=4,13,9;bad=11,1,9,8;Bahrain=11;balance=9;balanced=9;balancing=1;Band=17;Banking=17;Barcelona=11;base=h8,r29,61,21,11,2,5,27;BASE_TYPE=5;based=h2,r17,9,0,11,8,26,4,23,10,1,7,33;baseDir=1,4,13,27;basic=17,15,1;basis=10;bat=1,36,8;batch=14,12,9,1,5,51,11,4,71;BatchUpdateException=t71;BBS=17;bean=8;became=10;become=7,33,6,1,14,12,4,16,8,0,21;becoming=10;been=4,6,10,21,0,15,16,30,1,33,8,41,11,23,35,3,13;beforeFirst=3,15;BEGIN=9;beginning=5,25,7,2,4,8,13;behalf=10;behave=2,0;behavior=9,4,6,1,2,0,13,21;Behind=9;being=0,2,1;believes=10;belong=6,9,4;belonging=56,8;BELONGS_TO_TABLE=9;below=27,45,8,1,7,2,13;BenchA=11;BenchB=11;BenchC=11;benchmark=h11,r9,17;BenchSimple=11;beneficial=10;benefit=11;Berger=34;Berlini=34;best=5,9,0,21,1;best_row_identifier=8;bestRowNotPseudo=5;bestRowSession=5;beta=4;better=4,9,2,1,11;between=9,0,7,8,1,11,4,13,6,10;beyond=10;BGBlitz=17;big=9,2,20,21;BigDecimal=3,15,18,6,4,23,12,13,22;bigger=11,5,23,39;BIGINT=h22,r4,0;BigInteger=2;bigintType=0;billion=1;bin=8,51,23,21,1;binary=h22,r6,4,3,1,9,11,5,8,0,20;binaryType=0;bind=h1,r28;BIND_ADDRESS=h13;bindAddress=13,1;biodiversity=17;biological=17;birthday=1,23;bit=1,39,7,2,22,4,5,13;BIT_LENGTH=h7,r4;BITAND=h7;BITOR=h7;bitwise=7;BITXOR=h7;Bjorn=34;black=36;Bleyl=34;Blind=11;blob=t30,h1,22,r3,12,9,4,16,7,18,2,0,5,13,11;blobPattern=30;blobType=0;block=1,9,4,0,7,8,45;blocked=4;BLOCKSIZE=0;blockSizeInt=0;blog=h17,r9;blogspot=9;Blojsom=17;blue=36;bnf=20,4;bob=8;body=36;bogus=1;bold=36;BOM=25,7,4;Bonfanti=4;Bonita=17;bookkeeping=26,19;bookmarks=17;Books=h17;BOOL=22;BOOL_AND=h7;BOOL_OR=h7;booleanColumn=9;booleanType=0;boost=11;boot=2;booted=2;border=36;both=1,2,4,7,0,11,9,8,6,10,21;bound=9;box=9,17;BPM=17;brackets=2,4;branch=67;branches=32;breach=10;break=9,4,20;breaking=4;bring=10;broken=2,6,1;brought=10;browse=9,17;browser=h8,13,r27,52,9,17,45,4,1;brute=13,1;bTimestamp=7;buffer=1,13,9,11,34,55,0;BUFFER_LENGTH=5;buffered=0,9,11,4,1;BufferedReader=44;buffering=11;bug=h21,r4,13,20,9,49,34;bug_id=13;bugdatabase=13;bugfixes=4,9;buggy=9,8;build=t20,r9,17,2,6,8,11,4,59,63,23,0,1,51,13,21;builder=9;building=h23,20,r17,41,9,51;buildRelease=20;built=h11,r8,2,9,4,1,34,17,6;bulk=8,0;bungisoft=10;business=17,10,11;busy=1;button=9,4;bValue=7;BYTEA=22,9;bytecode=9,17;BZIP=6'; -ref['c']='cache=h2,11,35,r4,9,13,0,6,23,21;CACHE_MAX_SIZE=2,4;CACHE_SIZE=h0,r2,11,4,9;CACHE_SIZE_DEFAULT=h13;CACHE_TYPE=2,4,21;CACHE_TYPE_DEFAULT=h13;cached=0,11,4,35,13;cacheSize=13;cacheSizeDefault=13;cacheSizeIndexShift=13;cacheTypeDefault=13;caching=2,9,4,23;cafe=0;cal=18;calculate=0,1,9,7,11,2;calculated=1,9,7,11,10,13;calculating=1;calculation=9,4,6;calendar=3,12,18,9;California=10;callable=16,5,18;CallableStatement=t18,r16,9;callback=9;caller=3;CAN_ONLY_ASSIGN_TO_VARIABLE_1=h6;cancel=14,3,6,8,7,9;CANCEL_SESSION=h7;canceled=7,6,1;cancelRowUpdates=3;cannot=2,1,11,0,14,3,6,21,22;CANNOT_CHANGE_SETTING_WHEN_OPEN_1=h6;CANNOT_DROP_2=h6;CANNOT_DROP_CURRENT_USER=h6;CANNOT_DROP_LAST_COLUMN=h6;CANNOT_DROP_TABLE_1=h6;CANNOT_MIX_INDEXED_AND_UNINDEXED_PARAMS=h6;CANNOT_TRUNCATE_1=h6;capability=17;capacity=1;car=0;CARDINALITY=5,0;care=1;cascade=0,9,2;CASE_SENSITIVE=5,0;caseWhen=h7,r0;Casqueiro=34;CAST=h7,r6,9;casting=4;catalina=21;catalog=5,16,24,9,4,6,8,0,1;CATALOG_NAME=0;catalogPattern=5;cataloguing=17;category=23;cause=6,4,10,43,16,2,11,8,20,13,21;caused=10;causing=21;Cayenne=17;CBC=1;CDATA=7;CDO=17;cease=10;ceil=7;CEILING=h7;Cement=23;census=7;Center=17;Central=h20;centric=17;certain=1,2,11,4,10;certificate=1;certified=1;cfg=36;CFML=17;chain=1;chaining=1;challenge=1,9;challenger=1;chance=1;changed=4,2,0,6,19,9,11,1,48,14,3,8,20,13;ChangeFileEncryption=t46,r2,4,8;changelog=34,20;changing=h2,r4,11,8,9,14,69,46,0,13;channel=9,1;char=h7,2,22,r25,46,28;CHAR_LENGTH=7;CHAR_OCTET_LENGTH=5;character=7,0,3,4,6,25,5,12,22,2,9,42,13,10,1,44,38;CHARACTER_LENGTH=7;CHARACTER_MAXIMUM_LENGTH=0;CHARACTER_OCTET_LENGTH=0;CHARACTER_SET_NAME=0;characteristics=11;charge=10;charset=25,7,0,4;charsetName=38;charsetString=0;chartered=10;Chartrand=34;charType=0;Cheat=h36,r59;check2=h13,r9;CHECK_CONSTRAINT=0;CHECK_CONSTRAINT_VIOLATED_1=h6;CHECK_EXPRESSION=0;CHECK_OPTION=0;checkClosed=12;checked=0,7,6;checking=0,9,2,23;checklist=21,17,20;checkpoint=h0,r4,13,1;checkResults=38;checkstyle=20;checksum=2,6;chemical=17;CHF=6;child=6,9;Chile=34;Chinese=9,59;choice=10,51;choose=10,8;CHR=7;Christian=33,4,8;Christos=34;chunked=4;CID=6;cipher=h0,r2,1,46,6,9,13;circumstances=10;citizen=10;Cl1p=20;claim=h10,r1;Clara=10;Claros=17;clashes=1;CLASS_NAME=5;CLASS_NOT_FOUND_1=h6;classAndMethodName=0;classes=1,4,6,0,13,17,2,15,60;classification=17;ClassLibrary=1;classloader=9,8;classname=8,0;classNameString=0;ClassNotFoundException=4;classpath=2,0,8,6,9,45;clause=5,6,11,0,9;clean=41,20;cleaned=46;cleanup=0;clear=14,12,10,3,16;clearBatch=14,12;cleared=2,4;clearly=11;clearParameters=12;clearWarnings=14,3,16;click=8,45,1,11,21,36;clicking=8,1;client=h2,11,r1,9,8,13,4,17,0,5,6,20,22;CLIENT_TRACE_DIRECTORY=h13;clientTraceDirectory=13;clipboard=20;Clob=t42,h22,1,r3,9,12,4,16,7,18,0,2,13,11;clobPattern=42;clobType=0;CLOSE_ALL_RESULTS=14;CLOSE_CURRENT_RESULT=14;CLOSE_CURSORS_AT_COMMIT=5,16;closeAll=35;CloseListener=4;closely=5;closer=7;closeSilently=9;closing=h2,r4,0,13,11,31,9,37,36;closingDatabase=41;cluster=h1,0,r4,9,53,6,8,21;CLUSTER_ERROR_DATABASE_RUNS_ALONE=h6;CLUSTER_ERROR_DATABASE_RUNS_CLUSTERED_1=h6;clustered=6,8;clustering=h1,r9,2,6,17,4;CMS=17;cmu=9;CNT=0;COALESCE=h7;codebase=34;codebook=1;coded=1;codehaus=9;coding=20;Codist=17;COL=0;Cold=17;Coldrick=17;Collaborative=17;collapse=36;collateral=10;collation=h0,r6,2,13;COLLATION_CHANGE_WITH_DATA_TABLE_1=h6;COLLATION_NAME=0;collationName=0;collator=9,0,13;collatorCacheSize=13;collect=2;collected=2,4,6;collection=17,2,34,23,0,13;collectively=10;colNames=25;color=36;column1=9;column2=9;COLUMN_CONTAINS_NULL_VALUES_1=h6;COLUMN_COUNT=0;COLUMN_COUNT_DOES_NOT_MATCH=h6;COLUMN_DEF=5;COLUMN_DEFAULT=0;COLUMN_IS_PART_OF_INDEX_1=h6;COLUMN_LIST=0;COLUMN_MAY_BE_REFERENCED_1=h6;COLUMN_MUST_NOT_BE_NULLABLE_1=h6;COLUMN_NAME=5,0;COLUMN_NOT_FOUND_1=h6;column_privileges=8,0;COLUMN_SIZE=5;COLUMN_TYPE=5,0;columnAlias=0;columnDefinition=0;columnIndex=h3,15;columnIndexes=14,12,16;columnLabel=h3,r15;columnlist=26,19,2;columnListString=26,19;columnName=0,14,12,16,9,4,13;columnNamePattern=5;columnNameString=9;columnNoNulls=5,24;columnNullable=5,24;columnNullableUnknown=15,40,24;columnsString=7;com=9,20,2,34,10,0,7,13,17,36,11,4,59,1,41;combination=10,1,11,2,4,21;combine=9,7,10,8,0,1;combined=1,10;combining=4,10;comma=h8,r7,4,19,5,26,13,25,9,2,53,1;commaSeparatedList=19;comment=h0,11,r9,5,7;commentString=7;commercial=h10,r17,34,1;commit=h0,1,11,r16,14,5,2,12,6,32,9,7,13,21;commit_delay=11;COMMIT_ROLLBACK_NOT_ALLOWED=h6;committed=1,14,2,12,4,31,37,11,0;committer=4;committing=0,4;common=1,17,2,11,4,6,8,10,19,21;commonly=13,1;communication=17;community=11,10;comp=0;compact=0,2,9,4,13;compacted=2,0;compacting=h2,r4,0;companies=34;company=17,10;comparator=9;compare=h0,r9,39,11;compared=9,11,0,22,1;comparing=h11,r0,4,9,22;comparison=h11,2,r5,13,1,9,17,4,10,0;compatibility=h2,1,r9,4,0,7,21,36,16,23,8,22,13;compatible=13,1,9,2,4,8;compensation=9;compilation=2,4,10;compile=2,17,1;compiled=h2,r51,11,4,6,23,0,20;compiler=23,1,2,0;compiling=4;complete=2,1,4,8,9,5,10,23,20,21;completed=4;completely=1;complex=11,2,17,8;complexity=11,1;compliance=h1,r10;compliant=4,17,2,1;complicate=9;complicated=9,23,1;complies=10;comply=h10,r1;complying=10;Component=17;composed=17;compounds=17;compress=h7,r55,6,9,4;COMPRESS_LOB=h0,r1;compressed=55,9,7,6,8,10,20,1;Compresses=7;compressible=1;compressing=4,1;compression=h1,r0,4,9,7,6,8,2;COMPRESSION_ERROR=h6;CompressLZF=4;CompressTool=t55,r4;COMPUTE=9;computed=h2,r50,39,0;computedColumnExpression=0;computer=1,8,2,10,27,17,45,11;Computing=34;CONCAT=h7;concatenated=2;Concatenates=7;Concatenating=2;concatenation=4,0;concept=4,23;concerning=10;CONCUR_READ_ONLY=15,3,13;CONCUR_UPDATABLE=4,3;concurrency=h1,r16,4,5,6,9,14,2,3,17,0,21,13;concurrent=h8,r1,9,4;CONCURRENT_UPDATE_1=h6;concurrently=2,4,55,1;condition=h0,r4,10,1,23,19,7,13,9,11,5,6;conditionRightHandSide=0;conf=11;config=9;configuration=h23,1,r9,8,11,20;configure=11,4;confirmed=21;conflict=9,10;conflicting=1;confusing=1;confusingly=10;confusion=2;conjunction=10;connect=h1,21,r8,2,4,6,27,41,13,17,9,11,45,69;connect_by=9;connected=17,1;connecting=h8,2,r52,27,41,1;CONNECTION_BROKEN_1=h6;ConnectionEventListener=32;ConnectionPoolDataSource=33;connecturl=11;consequential=10;consider=11,20,1,8;Considerations=h1;considered=25,4,7,21;consistency=h1,r0,2;consistent=1,9,2,8,10;consisting=7,10;console=t52,h8,45,1,r9,4,2,11,21,13,27,20,36;CONSOLE_STREAM=h13;consoleStream=4,13;conspicuously=10;CONST=1;CONST_ID=0;constant=h0,1,r6,9,11,4,13;CONSTANT_ALREADY_EXISTS_1=h6;CONSTANT_CATALOG=0;CONSTANT_NAME=0;CONSTANT_NOT_FOUND_1=h6;CONSTANT_SCHEMA=0;constantName=0;constitute=10;constraint=h0,r6,4,9,22,2,11,1;CONSTRAINT_ALREADY_EXISTS_1=h6;CONSTRAINT_CATALOG=0;CONSTRAINT_NAME=0,4;CONSTRAINT_NOT_FOUND_1=h6;CONSTRAINT_SCHEMA=0;CONSTRAINT_TYPE=0;constraintName=0;constraintNameDefinition=0;construct=33,68;constructing=17;constructor=15,28,57,9,50,8;construed=10;consult=1;Consulting=34;consumes=9;contact=10;contained=4,10;container=17,4,8;containing=17,2,10,7,14,0,19,1;content=17,2,49,1,38,7,51,26,4,10,8;contentString=7;context=8,28,57,0,4;continue=32,10,1,31,38,37,2,8;continued=38,34;continueOnError=38;contract=10;contrib=9;contribute=10;contributing=4,20;Contribution=10,20;contributor=h10;control=h1,r10,9,17,6,23;controlled=2,10;convenient=9;Convention=10;conversion=4,7,6,9,14,0;convert=h7,r9,6,4,5,35,26,39,2,11,1,8,58,13;converted=7,12,2,4,6,9,0,25,26,10,20,22,21,13;converter=4;convertException=26;converting=2,4,7,6,8;convertInsertNullToZero=9;ConvertTraceFile=t58,r11,2,4,8;convertWord=35;conveyed=10;cooperate=10;copied=8,10;copies=10,48,53,1;Copilot=34;copy=10,8,1,9,17,5,53,20;copying=4,8,0;copyright=10;copyrighted=10;Core=5;correct=6,4,50,1;correction=10;correctly=4,8,1;correlated=5;correlation=5;corresponding=5,8;corrupt=4,1,48,21;corrupted=h2,r49,6,8,21,1;corruption=9,2,4;COS=h7;COSH=9;cost=10,11,9,0,2;COT=h7;couldn=4;count=h11,7,r14,29,9,0,4,12,6,15,23,1,13;counter=6,4;counterclaim=10;County=10;couple=17;course=9;court=10;cover=20;coverage=20,9,2,21;covered=10;Cp1252=13;CP850=44;cpu=38,11,1;crash=11;crashes=0;CrashPlan=17;CREATE_PARAMS=5;createBlob=16,9,4;createClob=16;CreateCluster=t53,h1,r4,8;CREATEDATE=0;createElement=59;createIndex=26,19;createNewFile=1;createPgServer=27,1;createResultSet=19;createStatement=16,1,2,33,6,8,13;createTable=68;CreateTableData=68;createTcpServer=27,8,9,6;createTempFile=2;createTrigger=26,19;createWebServer=27;creating=h8,2,r4,0,9,41,21,48,11,6;creation=9,10,11,8;creatively=2;cross=0,17,9,5,10,1;cross_references=8,0;cryptographic=9,1;cryptographically=1,7;cryptoloop=1;css=7,9;csv=t25,h8,0,r9,7,4,20,17,2,36,13;csvOptions=7;CSVREAD=h7,r8,9,4,0,13,1;CSVWRITE=h7,r8,0,1;CTID=2;Ctrl=9,11,8;ctx=28;cumulative=9,7;curation=17;curdate=7,9;cure=10;currency=22,24,4;CURRENT_DATE=h7,r5,1;CURRENT_TIME=h7,r5,1;CURRENT_TIMESTAMP=h7,r1,5;CURRENT_USER=7;CURRENT_VALUE=0;currently=h11,r1,9,4,14,7,8,2,23,0,6,20,51,5,21;currentTimeMillis=11;CURRVAL=h7,r9,4;cursor=3,14,5,15,9,1;curtime=7,9;curtimestamp=9;curve=17,2;CurveFit=17;custom=h2,r9,0,68,1;customarily=10;Customer=23,10;customerId=23,1;Customizing=1;CustOrder=23;cut=1;CYCLE=9'; -ref['d']='daemon=27,4,2;DaffodilDb=h2;damage=10;dangerous=21,4,6;Darri=34;dashes=7;DATA_CONVERSION_ERROR_1=h6;DATA_TYPE=5,0;DATABASE_ALREADY_OPEN_1=h6;DATABASE_CALLED_AT_SHUTDOWN=h6;DATABASE_EVENT_LISTENER=h0,r2,6,41;DATABASE_EVENT_LISTENER_OBJECT=4;DATABASE_IS_CLOSED=h6;DATABASE_IS_IN_EXCLUSIVE_MODE=h6;DATABASE_IS_NOT_PERSISTENT=h6;DATABASE_IS_READ_ONLY=h6;DATABASE_NOT_FOUND_1=h6;DATABASE_PATH=h7;DatabaseEventListener=t41,r4,9,2;DatabaseMetaData=t5,r9,4,16,8,3,21;databaseName=2;DatabasePlatform=8;databaseType=2;dataBytes=7;dataDefinitionCausesTransactionCommit=5;dataDefinitionIgnoredInTransactions=5;datasource=8,28,33,36,57,1;DATASOURCE_TRACE_LEVEL=h13;dataSourceTraceLevel=13;datatype=0,7,5,2;DATE_CONSTANT_2=h6;DATEADD=h7;DATEDIFF=h7,r4;DATEPART=9;DATETIME=22;dateType=0;David=17;day=7,10,17,20;DAY_OF_MONTH=h7;DAY_OF_WEEK=h7;DAY_OF_YEAR=h7;daylight=22;DAYNAME=h7;db1=2;DB2=h2,11,r9,0;db4o=11;DB_CLOSE_DELAY=h0,r2,11;DB_CLOSE_ON_EXIT=2;DBA=9;DBAppender=9;dbbench=11;dbbench2=11;DBCP=8;DbListener=2,41;dbMeta3=2;DBMS=17;dbname=2,4;dbs=9;dbserv=2;DbStarter=8;DbUnit=17;DbVisualizer=9,17;DDL=1,9,2,4;DDLUtils=9;deactivation=9;deadlock=h2,r6,4;DEADLOCK_1=h6;death=10;debug=2,0,20;debugging=27;DEC=22;December=34;decimal=h0,22,r7,4,6,9,11,2,5,1;DECIMAL_DIGITS=5;decimalType=0;declarative=17;declaratory=10;declare=8;declared=2,4,0;Declaring=h2;DECODE=9,7;decompiler=4,23;decompress=4;decompression=4,10;decoration=36;decrypt=h7,r2,46;decrypted=1,49;decrypting=h2,r1;decryption=46;decryptPassword=46;deductive=17;deemed=10;deep=11;DEF=0;DEFAULT_CHARACTER_SET_NAME=0;DEFAULT_COLLATION_NAME=0;DEFAULT_ESCAPE=h13;DEFAULT_LOCK_MODE=h13;DEFAULT_LOCK_TIMEOUT=h0,r2;DEFAULT_MAX_LENGTH_INPLACE_LOB=h13;DEFAULT_MAX_LENGTH_INPLACE_LOB2=h13;DEFAULT_MAX_MEMORY_UNDO=h13;DEFAULT_MAX_OPERATION_MEMORY=h13;DEFAULT_RESULT_SET_CONCURRENCY=h13;default_table_type=h0,r11;DEFAULT_TRANSACTION_ISOLATION=4;defaultEscape=4,13;defaultLockMode=13;defaultMaxLengthInplaceLob=4,13;defaultMaxLengthInplaceLob2=13;defaultMaxMemoryUndo=13;defaultMaxOperationMemory=13;defaultResultSetConcurrency=4,13;defective=10;defects=10;defend=10;defense=10;DEFERRABILITY=5,0;deferrable=5,9;deferred=9,0;define=23,0,6,9;defining=2,0,1;definitely=24;definition=h0,10,r9,23,1,2;Deflate=0,4,6,55,7;DEGREES=h7;deinterleave=39;Del=9;delay=h1,r13,0,11,9;DELAY_WRONG_PASSWORD_MAX=h13;DELAY_WRONG_PASSWORD_MIN=h13;delayed=h11,2,r4,13;delayWrongPasswordMax=13,1;delayWrongPasswordMin=13,1;DELETE_RULE=5,0;deleted=4,1,6,2,3,0,10,13;DeleteDbFiles=t56,r4,2,8;deleteOnExit=9;deleteRow=3,6;deletesAreDetected=5;deleting=4,6,65,64,69;deletion=10;delicious=17;delimiter=25,2;delta=9;demand=25,9,60;denial=1;denied=8;Denmark=34;DENSE_RANK=9;depend=0,2,11,4,34,8,23,1;dependencies=51,45;dependency=20,36,17;dependent=39,2,6,13;depending=9,25,2,8,0;deploy=9;deployment=2;deprecated=12;depth=38,11;derby=h2,11,r9,0,1;derivation=1;derivative=h10;derived=10;DES=6;DESC=0,5,9,7;descending=4,5,9,0,13;describe=10,9,11,1;described=10,9,2,1;description=h10,r28,5,1,9,8,45,2,4;descriptor=1;deserialization=22;DESERIALIZATION_FAILED_1=h6;deserialize=9;design=9;designate=10;designated=9;desired=2;desktop=17,9;destroy=8;destroyed=2;destruction=6;detail=9,6,8,0,1,7,22,4,43,21,52,2,10,63,27,20;detailed=45,10;detect=h1,r3,9,4,13,0;detected=5,6;detection=9,4;determining=10;deterministic=0,9;dev=9,4;developed=51,11;developer=h10,r17,11,32,34;developing=34,17;development=17,2,34,8,10;deviation=7;device=10,1,6,0;devx=9;Dfile=44;Dh2=13,1,20;diabetes=17;diagrams=h20,r4;dialect=8,36,4;Dick=34;dictionary=2,20;did=4,3,9,45,10,20,1;didn=4;died=1;Dieguez=34;dies=1;differ=10;difference=h7,23,r2,9,22;different=1,2,5,6,9,8,11,4,34,10,0,23,51,13;differential=10;Digest=1;digit=h0,r7,2,25,6;Digital=17;digitsInt=7;dim=39;dimension=39,2;dimensional=h2,r39;Dinamica=17;dir=49,56,46,2,48,36,54,27;direct=10,9,11,1;direction=3,14,10;directly=10,0,9,2,1,11,4,57,23;directories=9,1;dirty=1;disable=4,0,9,1,14,11,2,13,8;disabled=1,4,0,2,6,13,8,7,11,20,21;disablelastaccess=9;disabling=h1,r4,21;disadvantage=11,2;disallow=9;disappear=1;disclaimer=h10;disclaims=10;disclosed=10;Disconnect=h45,r8,0;disconnected=27,1;Disconnecting=h8;Disconnections=9;discontinue=34;disk=h2,r9,0,1,11,41,4;diskSpaceIsLow=41,4;display=8,10,24,2,4,59,0,1;displaying=9;dispose=33,10,36,8;disputes=10;distinct=7,0,11,2,6,4,13,9,5,1;distinctCount=7;distinguishable=4;distinguishing=10;distribute=10,36,21;distributed=10,9,17,32,1;distributing=10;distribution=h10,r20;distributor=10;District=10;divide=6;divided=13;division=9;DIVISION_BY_ZERO_1=h6;dll=1,2;DML=2,4,1;DOAP=63;doc=9,51,20;doclet=9;docsrc=20,9,51;document=9,59,8,10,22,20,21,1;documentation=h36,r9,10,4,1,51,8,21,11,6,59,20;documented=4,9;documenting=10;Docware=4;doesMaxRowSizeIncludeBlobs=5;doesn=4,6,9,11,2,49,23,20,21,22,1;doing=4,34,0;dollar=h0,r2;dollarQuotedString=0;domain=h0,r6,9,17;DOMAIN_CATALOG=0;DOMAIN_NAME=0;DOMAIN_SCHEMA=0;domainName=0;Donald=34;donation=17;done=1,8,22,37,62,4,23,10,0,39,31,20,41,13;donors=34;dose=17;dot=9;doubleType=0;doubt=0,1,8;down=9,13,1,11,2,27,8,0;download=t63,r9,20,36,59,1;downloaded=51;DOY=7;dp0=4;DpropertyName=1;drafter=10;drastic=2;Dreamsource=23;drive=1,9,11,21;driven=17;DRIVER_VERSION_ERROR_2=h6;DriverManager=2,6,8,5,11,36,21,1;driverString=7,0;drop=h0,r6,14,5,12,19,9,11,26,4,2;dropAll=26,19;dropIndex=19;dropped=31,37,6,0,7,4;dropping=4,9,6,1;DSL=23;DSN=1;dsName=28;DTP=9;dual=6,9,10,1;due=h10,r6,22,1;DUMMY=6;dump=49,11,2;duplicate=4,10,9,7,1;DUPLICATE_COLUMN_NAME_1=h6;DUPLICATE_KEY_1=h6;DUPLICATE_PROPERTY_1=h6;durability=h1,11,r2;durable=11;during=1,11,32;dynamic=17,9,2,60,0;dynamically=0,1'; -ref['e']='early=9,4,6;ease=34;easier=34,13,1;easiest=2;easily=17,2,15,4,23;easy=17,2,11,21,1;Ebean=17;ECB=1;ece9d8=36;EclEmma=20;eclipse=h10,r20,9,17,8;eclipseCodeStyle=20;EclipseLink=h8;ECM=17;edit=4,8;editing=4,9,8;editor=17;edu=9;EEE=7;effect=h10,r0,4,2,16,31,11,32,1;effective=10,0;effectively=10;efficient=17,11,2;either=10,21,1;elapsed=33;elect=10;electronic=10,1;element=7,29,59,8,13;elementString=7;eliminate=9,1;Elisabetta=34;else=0,3;email=6,0,20,17,7,8;embedded=h2,11,8,r1,9,6,45,4,38,17,36,23,47,20,21;Embedding=h45;embeds=1;emergency=48;EMF=17;emit=0;Emma=20;Empire=23;empty=5,16,0,29,19,13,2,4,8,1,7,6,21;emulate=11,2;emulated=2;enable=4,1,9,14,0,2,8,16,17,11,13;ENABLE_ANONYMOUS_SSL=h13;ENABLE_CLEAR_REFERENCES=21;enableAnonymousSSL=13,1;enabled=4,2,0,13,1,8,17,9,7,11,6;enabling=0,11,4,21;enclosed=0,1;encoded=7,6,1;Encodes=7;encoding=7,4,13,25,44,1;encodingString=7;encrypt=h7,r2,46,9,1;encrypted=h2,r9,1,27,6,49,46;encrypting=h2,r1;encryption=h2,1,r46,6,9,0,36,8;encryptPassword=46;ending=11,1;endless=4;endlessly=4;enforce=9,11,1;enforce_size=11;enforceability=10;enforceable=10;enforced=1;English=7,6,59,0;enough=6,11,2,4,20;ensure=1,11,2,4,20,21;ensuring=10;enter=9,8;enterprise=17;entire=10;entities=10,1;entity=10;entries=4;entry=5,8,45,2,20;enum=9;env=0;environment=h20,r8,17,57,51,2,23,0;eof=9;Epictetus=17;EPL=10;equal=4,7,16,39,2,23,0;equality=11,0;equipment=10;equitable=10;equivalent=21;Eric=4;Erik=34;err=44;ERROR_ACCESSING_LINKED_TABLE_2=h6;ERROR_CREATING_TRIGGER_OBJECT_3=h6;ERROR_EXECUTING_TRIGGER_3=h6;ERROR_OPENING_DATABASE_1=h6;ERROR_SETTING_DATABASE_EVENT_LISTENER_2=h6;errorCode=t6,r43;escape=6,25,0,4,5,14,13,9;escapeCharacter=25;escaped=2,4,0;escaping=0,2;escString=0;essential=8,36,10;established=33;estimate=7,9,11,1;estimated=0,13,1;ESTIMATED_FUNCTION_TABLE_ROWS=h13;estimatedFunctionTableRows=13;estimating=17;estoppel=10;etc=17,4;ETL=17;Eva=0;evaluate=0,9,8;evaluated=11,0,4;evaluating=7;event=32,41,9,2,17,4,6,10,0,1;every=1,10,11,2,0,13,21;Everyone=10;evolving=17;exact=9,2;exactly=0;exceeds=0,2;Excel=4;except=10,0,4,1,9,2,5,16,8,13;EXCEPTION_IN_FUNCTION_1=h6;EXCEPTION_OPENING_PORT_2=h6;exceptionThrown=41;exchange=10;exclude=11,10;excluded=10;excluding=10,2,1;exclusion=10;exclusive=h0,r2,4,1,10,6,9;exclusively=2;exe=1;EXEC=9;executable=h10,r20,17;executeBatch=14,12,9;executed=1,14,11,0,12,4,8,38,2,23,22;executeQuery=12,6,1,14,11,2;executeUpdate=14,12,4,6;executing=12,2,1,7,14,9,11,6,20;execution=9,17,38,0;EXEMPLARY=10;exercise=10;exercising=10;Exhibit=h10;existence=1,6;existing=0,4,2,19,27,26,8,1,9,11,6;existingFunctionAliasName=0;exit=h2,r0,44,52,6,8;exp=h7,r1;expand=h7,r55,9,6;expanded=8,4;expect=21,0;expected=4,6,44,9,38,45,11,0,21,1;expedites=17;expense=10;expensive=17;expensiveInStockProducts=23;experimental=4,1,2,0,21;experts=1;expiration=10;expires=1;Explain=h0,r2,4,21,1;explicit=9,2,0;explicitly=4,2,0,1;explorer=13;expNumber=0;export=9,17,4;exported_keys=8;exposed=9;express=10;expressed=10;expression=h0,11,r7,5,6,4,1,8,13;expressly=10;ext=51;extend=9,6,13,1;extended=5,15;extensible=9,4;extension=h17,r8,1,9,2,6,23;extensively=9;extent=10;external=h1,r51,2,0,20;extract=h7,r1,17;extracting=47,54'; -ref['f']='Fabric3=17;facade=2;facilitate=10;facility=2,25;fact=10,11;factor=h0,r11,2;factory=57,28,8;fail=4,1,14,12,10,9,0,13;failed=4,9,6,1;Failing=2;failure=1,2,10,21,9,4,13;falls=1;FAQ=h10,r59,20;fast=h11,r9,2,17,1,8,70,34,0,13;faster=h21,r4,11,0,1,9,34,7,2,8;fastest=2;FAT=1;FAT32=1,51;Faulhaber=4;fault=17;FEATURE_NOT_SUPPORTED_1=h6;Feb=7;February=2;Federal=10;federated=17,2;federation=17;fee=10;feed=63,25;feedback=4,34;fetch=3,14,2,13;FETCH_FORWARD=15,14,3;few=11,2,20,17,4,34,8,21,1;fff=36;ffffff=36;field=25,7,9,4,17,6,2,66,37,26,23,35,43,19,22,21,13;FIELD_COLUMNS=h19;FIELD_KEYS=h19;FIELD_SCHEMA=h19;FIELD_SCORE=h19;FIELD_TABLE=h19;fieldDelimiter=25;fieldDelimString=0;fieldSeparator=7;fieldSeparatorRead=25;fieldSeparatorWrite=25;fieldSepString=0;fifty=10;FILE_CORRUPTED_1=h6;FILE_CREATION_FAILED_1=h6;FILE_DELETE_FAILED_1=h6;FILE_ENCODING=h13;FILE_ENCRYPTION_ERROR_1=h6;FILE_LOCK=2,1,6,21;FILE_NOT_FOUND_1=h6;FILE_READ=h7,r4;FILE_RENAME_FAILED_2=h6;FILE_SEPARATOR=h13;FILE_VERSION_ERROR_1=h6;FILE_WRITE=9,4;FILE_WRITE_TOTAL=4;FileChannel=1,11;filed=10;FileDescriptor=1,11;filename=38,47,48,54,1;fileNameString=7,0;FileNotFoundException=4;FileObject=1;FileObjectDisk=4;filePassword=6;filePasswordUserPassword=6;FilePermission=8;filepwd=2;Filesystem=4,1;FileSystemZip=4;fill=2,20;fillAligned=9;filled=2;filling=2,10;filter=8,9,2,5,23,0;FILTER_CONDITION=5,0;filtered=1;FilterIn=9;FilterOut=9;final=23,21;finalize=9;finalizer=6,13;finally=2;find=9,17,2,6,0,21,1,11,4,8,20;findColumn=15,3;Finder=17;finding=4;findResource=9;finer=9;Finish=1;finished=33;Finland=34;fire=31,37,2,6;Firebird=h11;fired=9;Firefox=51,20;firewall=h8,r45,9,6;FirstName=11,7,0;fit=1,4,17,6,10;FIT4Data=17;fitness=10;fitting=17;fix=9,20;fixed=4,9,11,5,8,23,0,21,22,1;FIXED_PREC_SCALE=5;fixes=21;fixing=4;FK_NAME=5,0;FKCOLUMN_NAME=5,0;FKTABLE_CAT=5;FKTABLE_CATALOG=0;FKTABLE_NAME=5,0;FKTABLE_SCHEM=5;FKTABLE_SCHEMA=0;flag=32,35,0,9,4,6;Flash=17;flashback=9;flexible=17;fleXive=17;flipped=1;float=h21,r3,15,18,4,22,26,12,19;FLOAT4=22;FLOAT8=22;floating=2,22;floor=h7;Florent=34;fluent=9,23;flush=11,1,44,4;flushes=0,1;flushing=11,0;Flux=17;fn_dbev_startup=9;folder=17;follow=4,8,0,20,1,21,9,2,11,33,6;followed=4,3;font=36,9;footprint=2;force=27,1,0,13,9,2,11,6;forceFalse=13;foreign=5,0,9,4,6,11,2;foreignCatalogPattern=5;foreignSchemaPattern=5;foreignTable=5;forget=32;forgot=13;forgotten=6;form=10,6,7,28,4,1,8,20,13,11,2,0;format=4,7,25,2,9,67,6,22,1,11,5,49,8;FORMATDATETIME=h7;formatString=7;formatted=4,6,20;formatting=20,11,4,8;formed=34;forName=2,8,36,4,21;forth=10;forward=3;found=3,4,6,21,7,30,1,11,2,15;Foundation=10;four=7,20;fraction=9;fractional=2;Fragments=t59;frame=4;framework=17,23,8,1;France=34;Frank=34;free=17,10,33,4,30,42,29,9,36,11,7,70,8,21;freed=0,13;freeing=35;freely=1;frequently=t21,r2;Freshmeat=17;Friend=17;friendly=17,10;fromType=5;front=17;Frontend=h17;fsutil=9;fsync=1,11;FT_CREATE_INDEX=8,19;FT_DROP_ALL=19;FT_INIT=4,8,19;FT_REINDEX=19;FT_SEARCH=8,19;FT_SEARCH_DATA=8;FTL=26;FTL_CONTAINS=9;FTL_CREATE_INDEX=26,8;FTL_DROP_ALL=26;FTL_INIT=26,8;FTL_REINDEX=26;FTL_SEARCH=9,26,8,13;FTL_SEARCH_DATA=8,9;FTL_SET_OPTION=9;ftp=9,8,1;ftpPassword=20;ftpTask=9;fulfilled=10;full=19,26,5,17,8,0,9,66,11,35,23,1;fulltext=t19,64,h8,r4,9,35,26,2,36,21;FullTextLucene=t26,65,r8;FullTextSettings=t35,r19;FullTextTrigger=t65,64;fully=0,1,11,4,21,22,23,13;Fun=17;FUNCTION_ALIAS_ALREADY_EXISTS_1=h6;FUNCTION_ALIAS_NOT_FOUND_1=h6;FUNCTION_ALIASES=4,0;FUNCTION_COLUMNS=0;FUNCTION_MUST_RETURN_RESULT_SET_1=h6;FUNCTION_NOT_FOUND_1=h6;functional=9,17,2;functionality=9,26,19,2,1;FunctionMultiReturn=9;FUNCTIONS_IN_SCHEMA=h13;functionsInSchema=9,4,13;further=2,10,0;fusion=17;future=5,10,4,0,9,34,23;Fyodor=34'; -ref['g']='GAE=4;GaeVFS=4;games=17;gaps=4;garbage=2,7,4,6,34,0,13;gave=34;GBIF=17;GCJ=h21,r9,51,20,1;Gem=9;genealogy=7;general=h10,r9,17;GENERAL_ERROR_1=h6;Generalized=9;generally=11,4,10,1;generate=2,20,39,11,7,9,4,1;generate_series=9;generated=1,2,6,11,39,14,62,4,20,7,8,0;generatePreparedQuery=39;generating=h20,r1,17,11;generation=h2,r9,17;generator=7,1;Generic=45,4;genetic=11,2;Genomics=17;geocoder=17;Geocoding=17;Geographic=17;geosysin=9;Germany=34;GET_LONG=6;GET_PROPERTY=1;GET_SYSTEM_PROPERTY=0;getActiveConnections=33;getArray=29,15,3,18,61;getAsciiStream=3,42;getAttribute=5,8;getAutoCommit=16;getBaseType=61,29;getBaseTypeName=61,29;getBestRowIdentifier=5;getBigDecimal=3,18,15;getBinaryStream=3,30,1;getBlob=3,18;getBoolean=15,3,18;getBranchQualifier=67;getByName=2;getByte=15,3,18,30;getCatalog=5,16;getCatalogName=15,24;getCatalogSeparator=5;getCatalogTerm=5;getChannel=13;getCharacterStream=3,42,1;getClientInfoProperties=5;getClob=3,18;getCollatorCacheSize=13;getColumnClassName=15,24;getColumnCount=15,24,8;getColumnDisplaySize=15,24;getColumnLabel=15,24,8,21;getColumnName=2,15,24,21,13;getColumnPrivileges=5;getColumns=5,4;getColumnType=15,24;getColumnTypeName=15,24;getConcurrency=15,3;getConnection=2,6,28,8,5,33,14,36,4,32,11,1,21;getCrossReference=5;getCursorName=3;getCustomerList=23;getDatabaseMajorVersion=5;getDatabaseMinorVersion=5;getDatabaseProductName=5;getDatabaseProductVersion=5;getDate=3,18,15;getDefaultTransactionIsolation=5;getDescription=28;getDouble=15,3,18;getDriverMajorVersion=5;getDriverMinorVersion=5;getDriverName=5;getDriverVersion=5;getElementById=59;getElementsByTagName=59;getEscapeCharacter=25;getExportedKeys=5;getExtraNameCharacters=5;getFD=4,13;getFetchDirection=14,15,3;getFetchSize=14,15,3;getFieldDelimiter=25;getFieldSeparatorRead=25;getFieldSeparatorWrite=25;getFloat=15,3,18;getFormatId=67;getGeneratedKey=9,14,5,4,8;getGlobalTransactionId=67;getHelpOn=9;getHoldability=15,3,16;getHostAddress=2;getIdentifierQuoteString=5;getIgnoreList=35;getImportedKeys=5;getIndexInfo=5,35;getIndexModifier=26;getIndexPath=26,35;getInstance=39,25,55,35,8;getInt=15,3,18,9;getJDBCMajorVersion=5;getJDBCMinorVersion=5;getLocalHost=4;getLoginTimeout=28,33;getLogWriter=28;getLong=15,3,18,6;getMatrix=2;getMaxBinaryLiteralLength=5;getMaxCatalogNameLength=5;getMaxCharLiteralLength=5;getMaxColumnNameLength=5;getMaxColumnsInGroupBy=5;getMaxColumnsInIndex=5;getMaxColumnsInOrderBy=5;getMaxColumnsInSelect=5;getMaxColumnsInTable=5;getMaxConnections=5,33;getMaxCursorNameLength=5;getMaxFieldSize=14;getMaxIndexLength=5;getMaxProcedureNameLength=5;getMaxQueryTimeout=13;getMaxRows=14;getMaxRowSize=5;getMaxSchemaNameLength=5;getMaxStatementLength=5;getMaxStatements=5;getMaxTableNameLength=5;getMaxTablesInSelect=5;getMaxUserNameLength=5;getMessage=43;getMetaData=15,12,3,16,2,8;getMoreResults=14;getNullString=25;getNumericFunctions=5;getObject=3,18,15,24,9,13,21,22;getObjectInstance=57;getObjectSize=9;getOrderList=23;getParameterClassName=40;getParameterCount=40;getParameterMetaData=12,8;getParameterMode=40;getParameterType=40;getParameterTypeName=40;getPassword=28;getPlatformMBeanServer=9;getPooledConnection=28;getPort=27;getPrecision=40,15,24;getPrimaryKeys=5,4;getProcedureColumns=5,4;getProcedures=5,4;getProcedureTerm=5;getProductList=23;getProperty=6,0,1;getQueryTimeout=14;getRef=3,18;getReference=28;getResourceFrom=9;getResult=39,50;getResultSet=29,14;getResultSetConcurrency=14;getResultSetHoldability=14,5;getResultSetType=14;getRow=15,3;getRowSeparatorWrite=25;getRuntime=2,4;getSavepointId=62,6;getSavepointName=62,6;getScale=40,15,24;getSchemaName=15,24;getSchemas=5;getSchemaTerm=5;getScriptDirectory=13;getSearchStringEscape=5;getService=27;getServletContext=8;getShort=15,3,18;getSQL=43;getSQLKeywords=5;getSQLStateType=5;getStatement=15,3;getStatus=27;getString=15,3,18,6,4,8,1;getStringFunctions=5;getSubString=42;getSuperTables=5;getSuperTypes=5;getSystemFunctions=5;getTableName=2,15,24,13;getTablePrivileges=5;getTables=5,9,2,4;getTableTypes=5;getTime=3,18,15;getTimeDateFunctions=5;getTimestamp=3,18,15;getting=4;getTop=11;getTransactionIsolation=16;getTransactionTimeout=32;getType=50,15,3;getTypeInfo=5;getTypeMap=16;getUDTs=5;getUnicodeStream=3;getUpdateCount=14;getURL=3,18,2,5,28,27;getUser=28;getUserName=5;getVersionColumns=5;getWarnings=14,15,3,16;getWordList=35;getXAConnection=28;getXAResource=32;gif=9;Gilbert=34;GIS=17;GiST=9;given=19,0,27,6,29,26,10,42,44,50,35,17,4,7,33,22,13;glassfish=h8,36,r17,21;Glenn=34;global=0,67,4,9,2,35;Glossary=h1;Gluco=17;gmbh=9,34;GMT=7,8;GNU=17,1;Golden=17;goodwill=10;google=9,4,59,20,63,21;google_translate_element=59;googleTranslateElementInit=59;got=4,6,20;gov=7;governed=10;Government=h10;Graceful=h2;Grails=17;grained=9;Grajciar=4;grammar=t0,r5,16,20,2,36,59,1;grant=h10,0,r6,5,9;granted=10,6;GRANTEDROLE=0;grantee=5,0;GRANTEETYPE=0;grantor=5,0,10;granularity=9;graph=9;Graphical=17;Gray=34;GREATEST=h7;Greece=34;greedy=11;greenspun=9;Greenwich=8;groovy=9,23;group=5,0,10,6,20,59,17,4,1,9,2,34,21,13;GROUP_CONCAT=h7;groupBy=23;groupId=20,36;grouping=7,9,0;groupware=17;Grover=34;guarantee=1,2;guaranteed=6,8;guesses=11;GUEST=0;GUI=9,17,8;guide=9;guidelines=20;Gustav=34;GZIP=0'; -ref['h']='h2client=20;H2Console=8;h2database=9,20,7,34,36,4,10;h2db=9;H2Dialect=8,36,4;H2DRIVERS=8;h2errors=13;h2jaqu=23,20;h2map=9;h2osgi=17;H2Platform=8,36;H2Sharp=17,1;h2small=4,20;H2spatial=9;hack=13;had=4,34,10;Haidinyak=34;half=11,2,4,0;HALF_DONE=0;hand=h0;handing=17;handle=17,32;handling=h2,r7,4,20;happen=6,8,1;happened=10;Harbor=17;hard=1,11,9;harder=1;hardware=10,1,49;harmless=11;Harmony=21;Harpal=34;hasChanged=19;hash=h0,11,7,r1,19,9,4,2,6,8,13;hashcode=9;hashed=1;hashing=9,1;HashMap=35;HashSet=19,35;Hashtable=57;having=0,1,4,9,2,17,5,10,23;HBCI=17;head=9,59;header=4,6;Health=17;heap=4,6;HeapDumpOnOutOfMemoryError=20;height=36;held=10,1;hello=8,6,7,4,9,2,0,15,1;HelloWorld=20;Helma=17;helped=4;Helvetica=36;HenPlus=17;here=2,1,8,9,50,11,20,21;hereafter=10;hereby=10;herein=10;hereof=10;hereto=10;hereunder=10;heterogeneous=17;Heureuse=33,8;hex=h0,r7,5,6;HEX_STRING_ODD_1=h6;HEX_STRING_WRONG_1=h6;hexadecimal=6,0,7;hexNumber=0;HEXTORAW=h7;hibernate=h8,36,r4,23,17,9,1;Hibicius=17;hidden=4,9;hide=h43,r4,8;HIDE_SQL=h43;hiding=43,10;high=h1,r2,5,17,0,21;higher=1,9,0,7,14,11,2,4,3,20;highest=7,41;Highlight=17,59;Hilbert=2;hint=16,9;hispanic=17;history=t34,r8,4,59;hit=19,1;HOLD_CURSORS_OVER_COMMIT=5,16;holdability=16,5,14,15,3;holding=1;home=4,8,2,36,45,59,13,1;homed=1;homepage=9;hook=2,6;hopefully=1;host=2,53,1;hot=9,11,8;hotspot=4;hour=h7,r20;hover=36;however=2,1,8,0,11,10,20,14,4,23,21,48,34,16,55,41;href=7;hsql=9,20;hsqldb=h2,11,r9,8,10,0,34,1,36;HSQLDialect=36;htm=9;html=9,20,34,51,10,17,7,4,22,1;http=h1,r9,8,7,34,10,20,13,17,45,4,59,27;human=49,8;hypersonic=34,9'; -ref['i']='iBatis=23;IBM=9,2;Iceland=34;icon=8,52,45;IDE=23;idea=h23,r8,2;identical=0,1;identified=11,10;identifier=h1,r5,67,9,7,2,4,8,0,13,22;IDENTIFIERS_TO_UPPER=h13;identifiersToUpper=4,13;identify=10;identity=h7,22,r0,4,9;identityType=0;idiomatic=17;ids=4;IDX_=9;IDX_ID=6;idx_name=2;IDX_TEST_ID=6;IDX_TEST_NAME=0;IDX_U_NAME=2;IDXNAME=0;IEEEremainder=6;ifExists=2,9,27,6,1;IFNULL=h7,r6,8;iframe=4;igniterealtime=9;ignore=h2,r35,19,9,11,1;IGNORE_UNKNOWN_SETTINGS=2;IGNORECASE=h0,r2;ignored=14,5,4,7,29,2,0,28,16,12,3,25,15,32,6,22;IGNOREDRIVERPRIVILEGES=2;ignoreList=h35;iict=9;iii=10;ikvm=1;ikvmc=1;IllegalStateException=4;image=17,22,9,20;ImageMapper=17;immediately=0,1,4,31,37,16;immutable=2;Imola=11;impact=11;implement=9,2,23,0,17,37,26,10,68,7,50,6,41,19;implementation=4,31,17,2,15,23,1,8,20,61,9,11,34,0,68,13;implemented=4,1,2,9,15,21;implementing=17,4;implication=10;implicitly=0,6;implied=10;import=h11,r2,8,28,23,33,9,36,4,10,0;important=11,9,7,4,1,43,21;imported=2;imported_keys=8;importedKey=5;importedKeyNotDeferrable=5;Importing=h8;impose=10;impossible=10;improve=9,11,2,13,1,17,8,21;improved=4,9,11,2;improvement=2,4;improving=4,34;IN_DOUBT=0,1;Inability=h10;Inactive=1;Inc=34,1;incidental=10;include=10,20,2,8,4,9,0,1,38,5,13,11,26,6,19;included=4,10,2,8,1,9,11,23,20,0,21;including=10,2,9,17,8,0,1,48,5,20;incoming=1;incompatible=6,1;incomplete=4;inconsistency=10;inconsistent=16,0;incorrect=h21,r4,11,6;incorrectly=4;increase=9,11,6,34,1;increased=9;increment=0,5,4,6,22;incremented=0;incrementInt=0;incurred=10;Indemnified=10;indemnify=10;indemnity=10;independent=63,17,39,7,2,5,0;INDEX_ALREADY_EXISTS_1=h6;INDEX_BELONGS_TO_CONSTRAINT_1=h6;INDEX_CLASS=4,0;index_info=8;INDEX_NAME=5,0;INDEX_NOT_FOUND_1=h6;INDEX_QUALIFIER=5;INDEX_TYPE=0;INDEX_TYPE_NAME=0;indexColumn=h66,r19,0;indexed=19,4,8,2,6,0;indexes=h11,2,35,r4,9,0,5,19,66,26,1,21,23;indexExistingRows=26,19;indexExpression=7;indexId=35;IndexInfo=t66,r35;indexing=9;indexModifier=26;indexName=0;IndexOutOfBoundsException=4;indexPath=26;indicates=7;indication=21;indices=19,23;indirect=10;indirectly=10;individual=10;individually=1;InetAddress=2,4;INF=8;info=4,2,5,35,8,0;inform=10,41;information_schema=4,6,0,9,2,1;informed=10;infringe=10;infringed=10;infringement=10;infringing=10;ini=11;init=11,8,2,4,26,19,31,9,37,50,41;initial=h10,r2;InitialContext=28,0;initialization=4,20,1;initialize=8,19,1,26,6;initialized=h35,r31,4,13;initializing=31,37,4,6;initially=9,10;initiate=10;initiation=10;inject=1;injection=h1,r0,17,9,2,23;injury=10;inline=2,22;inner=0,9,11,2,5,4,1;innerJoin=23;InnoDB=11;innodb_flush_log_at_trx_commit=11;input=3,30,1,44,12,9,16,42,36,50,5,6,4;inputFileName=25;InputStream=3,12,18,30,44,16,42,13,9,22;inputString=7;inputTypes=50;insecure=2;insensitive=2,0,3,25,9,7,15,4,13;insert=h3,0,7,11,37,r6,5,14,9,4,1,8,2,31,12,65,64;insertAll=23;inserted=1,7,2,3,8,0;inserting=h8,r4,2,1,65,9,64;insertion=11;insertRow=3,6;insertsAreDetected=5,9;inside=0,6,9,62,2,4,8,22;inspect=27;install=h1,r20,9,51,45,2,8,21;Install4j=21;installation=t51,h1,45,r11,59,8,10,20,21;installed=8,1,4,2,20;installer=51,20,63,45,36;installing=h51,r1,4;instance=h1,r55,35,25,2,4,8;instead=h2,r9,4,0,23,6,1,7,8,20,11,34,31,27,13,22,21;institutes=17,10;INSTR=h7;instrument=9;Instrumentation=9;INT2=22;INT4=22;INT8=22;integer=2,22,23,4,13,7,5,0,9,11,15,6;integrate=9,34,10,20;integrated=23,17;integration=17;integrity=0,2,5,9,6,21,1;intellectual=h10;intelliBO=17;intended=10,22,1;interaction=2;interactive=9,44,17,8;interesting=1;interleave=39;interleaving=39,2;intermediate=5;intern=9,6;internal=9,6,23;internally=2,9,7,32,15,16,23,21,22,1;International=10;internet=13,1;interpreted=7,8,0;interprets=11;interrupting=9;interruption=10;intersect=0,4,9,5,1;interval=9,17,7;inTouch=17;intType=0;intValue=2;INV_INS=2;invalid=24,6,12,14,0,4,16,10;INVALID_CLASS_2=h6;INVALID_DATABASE_NAME_1=h6;INVALID_PARAMETER_COUNT_2=h6;INVALID_USE_OF_AGGREGATE_FUNCTION_1=h6;INVALID_VALUE_2=h6;Invert=13;invocation=50;INVOICE=2;involve=6,1;involved=4,13;IO_EXCEPTION_1=h6;IO_EXCEPTION_2=h6;IOException=25;IP_ADDRESS=2;ipAddress=2;IPT=17;IPv4=1;IPv6=1;iReport=9;irstv=9;IS_AUTOINCREMENT=5;IS_COMPUTED=0;IS_DEFAULT=5,0;IS_GENERATED=0;IS_GRANTABLE=5,0;IS_NULLABLE=5,0;IS_PRIME=2;IS_UPDATABLE=0;isAfterLast=3,4;isAutoIncrement=15,24;isBeforeFirst=3,4;isCaseSensitive=15,24;isCatalogAtStart=5;isClosed=14,15,3,16;isCurrency=15,24;isDefinitelyWritable=15,24;isDesktopSupported=9;isFirst=3;isInitialized=35;isLast=3;isNullable=40,15,24;ISO=8,1;ISO_8601=9;isolated=1;isolation=h1,r16,5,2,8,21;isPoolable=14;isPrime=2;isProbablePrime=2;isReadOnly=5,15,16,24,2;isRunning=27;isSameRM=32;isSearchable=15,24;isSigned=40,15,24;issue=9,4,20,21,1,17;issued=33,10;isValid=16;isWritable=15,24;Italian=4;Italy=34;item=6,10,1;iteration=1,7,17;iterationInt=7;itself=2,10,23,15,6,1,9,11,32,13;iTunes=17;Iyama=34'; -ref['j']='J2EE=17;j2se=9;Jackcess=9;Jackrabbit=17;Jakarta=2;Jakob=34;Jala=17;JAMWiki=17;Janino=9;January=6;Japan=34;Japanese=9,4,59;jaqu=t23,r4,20,9,59;jar=h2,63,r8,20,4,1,36,21,11,23,9,45,0,7,51;jarClient=20,4;jarJaqu=23,20;jarSmall=20;jasonbrome=9;JAVA_CLASS=0;JAVA_HOME=20;JAVA_METHOD=0;JAVA_OBJECT=7;JAVA_SPECIFICATION_VERSION=h13;javac=2,0;javaClass=2,58;javadoc=9,4,51,8,20,59,23;javadocImpl=20;JavaEE=17;javascript=9,17,59,8;javax=28,0,1,2,57;Jayaprakash=34;JBoss=17,8;jBPM=17;JCL=2;JConsole=9;jcr=9,20,17;JdbcConnectionPool=t33,r36,8,4;JdbcDataSource=t28,r57,8,36,4;JdbcDataSourceFactory=t57;JdbcSQLException=43;JdbcUtils=9;jdbcx=8,36,28,33;JdbcXAConnection=t32,r4;JdbcXid=t67;JDK=9,20,51,4,6,8,52,11,1;JDO=17;Jena=17;Jenkov=34;JEQUEL=23;JGeocoder=17;JGrass=17;jira=9;JMatter=17;JMX=9;JNDI=28,0;jnlp=h8;Joachim=34;job=17,11,4;Joe=6,8;john=8,0;join=9,0,5,11,8,21,2,4,6,1;joined=11,4,34;Joist=23;jones=8;Joonas=34;Jopr=17;JoSQL=23;JotBot=17;JPA=23,17;JPasswordField=2;JPOX=17;jps=11;JRE=20;JRuby=17;JSON=9;jsp=9;JSR=17;JSSE=1;jstack=11;JTS=9;judged=9;judgment=10;judicial=10;Jun=34;junctions=20;June=10;JUnit=17;jurisdiction=10;jury=10;JVM=h11,r4,9,2,27,21'; -ref['k']='Kaspersky=8;keep=h11,r2,9,17,20,1;KEEP_CURRENT_RESULT=14;keeping=9,11;kept=0,22,9,25,11,4,7,2,26,19,13,1;kernel=4,9,17,7;Kerry=4;KEY_COLUMN_USAGE=9;KEY_SEQ=5;keyBytes=7;keystore=1,9;keyStorePassword=1;keyString=9;keyword=h1,r5,0,4,59;Kidd=34;kill=9,11,27;killed=27,4;killing=9,4,1;kind=10,0,2,11,4,13;knife=17;knowledge=10,17;known=h21,r40,0,1,9,51,2,4,10;Kupolov=34'; -ref['l']='label=3,15,24,9,21;lack=17;lang=22,6,0,9,2,4,21,1,40,23;language=17,23,1,10,9,2;laptop=1;large=h1,r4,9,22,2,11,0,13,3,8,17,20;LARGE_RESULT_BUFFER_SIZE=h13;LARGE_TRANSACTIONS=h13;larger=h10,r4,0,2,9,7,11,13,21,1;largeResultBufferSize=13;largest=7;largeTransactions=9,4,13;LAST_MODIFICATION=0;LASTVAL=4;late=9;later=4,9,15,2,6,41;latest=11,63,20;latin1=9;latitude=17;Launch=8;law=10;lawsuit=10;layer=17,1,11;layout=h2,r9;lazy=9;LCASE=7;LDAP=6;Leach=1;lead=9,4;leading=7,2;leak=9;learning=17;least=h7,r2,3,10,1,11,6,20;leaving=11;left=h7,r0,36,8,9,45,11,6,21;leftmost=7;legacy=17;legal=12,10,20;LEGEND=9;len=30,42,7;length=h7,r3,5,12,30,16,42,1,18,0,23,4,13,9,8;lengthInt=7;less=4,11,9,0,1;let=17,45,8;letter=25,2,7,4;level=h1,r2,16,5,0,4,9,11,20,13,34,23,8,21;liability=h10;liable=10;lib=8,21,11;libraries=34,9,17,20;library=h23,r17,8,9,1;licensable=10;license=t10,r20,17,11,59,21;licensed=h10,r20;licensees=10;Lies=1;life=17;Liftweb=17;light=17;lightweight=9,17;LIKE_ESCAPE_ERROR_1=h6;likely=4,10;limit=h1,21,r5,26,19,0,2,8,14,9,11,10,13;limitation=h1,10,r0,2,21;limited=2,5,0,11,4,8,10,1;Limiting=h1;limitInt=26,19;LINE_SEPARATOR=h13;lineSeparator=25;lineSepString=7;link=t17,h1,r0,9,36,7,2,59,21;LINK_SCHEMA=h7;linked=h0,1,r9,2,4,6,13,7,43,21;LinkedList=9;LINQ=23;Linux=21,17,51,11,6,20;LiquiBase=17;LIQUidFORM=23;listed=h11,r4,2,8,9,5,6,43,58,1;listen=1,17;listener=h8,r32,1,2,41,9,0,4,6;listening=27,1;literal=h1,r0,5,6,7,4;LITERAL_PREFIX=5;LITERAL_SUFFIX=5;LITERALS_ARE_NOT_ALLOWED=h6;litigation=10;little=1,7,2,10;live=9;LLC=34;load=8,1,9,17,6;loaded=7,4,6,0,13;loader=2,6,9,4,21;loading=h1,r4,13,11;lob=4,13,1,9,2,6,0,8,21;LOB_FILES_PER_DIRECTORY=h13;LOB_IN_DATABASE=h13;lobCloseBetweenReads=h13;lobFilesPerDirectory=13;lobInDatabase=4,13,9;local=h2,r0,12,4,5,8,9,38,45,20,13,1;LOCAL_TYPE_NAME=5;localdb=17;locale=7;localeString=7;localhost=1,8,2,27,36,9,7,45,6;localized=5;LOCATE=h7,r6,17;located=1;location=7,8,2,57,17,53,10,1;locatorsUpdateCopy=5;lock=h1,2,r9,6,0,4,13,7,16,8;LOCK_MODE=h0,7,r1,16,11,4,13,21;LOCK_TIMEOUT=h0,7,r6,2;LOCK_TIMEOUT_1=h6;LOCK_TYPE=0;locked=6,1,4,0;locking=h1,2,r9,0,6,16,11,4,21;log=t4,h7,34,r9,2,28,0,1,36,11,63,8,20,13;log10=h7;Log4j=2;LOG_ALL_ERRORS=h13;LOG_ALL_ERRORS_FILE=h13;logAllErrors=13;logAllErrorsFile=13;Logback=9,2;logFileId=7;logged=31,37,45,2;logging=h2,r17;logic=17,4;login=h8,45,r28,13,21,9,4,1;LONGBLOB=22;longer=4,9,1,11,6,34,0;longitude=17;LONGTEXT=22;LONGVARBINARY=22;LONGVARCHAR=22;lookup=9,11,28,4;loop=8,4,25,11,1;lose=1;losing=11,10,1;loss=10,13;losses=10;lossless=2;losslessly=55;lost=1,2,10,0,11,6;lot=4,11,1,34,8,21;low=h2,r5,41,9,34,0;lower=h7,r9,2,1,39,4,6;lowercase=7,2;lowest=7,11;LPAD=h7;LRU=13;LTRIM=h7;Lubomir=4;Lucene=h8,r26,4,9;Lumber=34;Luntbuild=17;Lutin=34;lying=10;LZF=0,55,7,4,1'; -ref['m']='Mac=51,44,17,20,13,21,1;machine=2,1,6,8,0,13,45,11,4,10;Macromedia=17;made=10,0,1,11,2,15,3;Magnolia=17;mail=9,17,20;mailing=4,10;mainly=1,17,11,4;maintained=10;maintenance=69;major=5;MajorVersion=5;making=10,1;malfunction=10;Man=17;manag=9;manage=17;management=17,9,34,10;ManagementFactory=9;manager=17,32,9,6,8,0,1;manipulate=1;manipulation=h0,r5,11,1;manner=10;manual=17,2,4,34,0;manually=1,11,2,27,4,6,10,0;many=11,2,4,1,13,34,8,30,0,51,21,9,20;map=29,16,3,18,9,5,23,13;mapped=22,2,13,0,21,1;mapping=h2,r17,3,23,8,11,21;margin=36;mark=25,7,4,6;marked=1;marker=25;markets=17;Markup=17;Martin=34;master=9;MAT=20;match=6,4,0,9,38,2,5,19;Matcher=0;matches=7;matching=2,0;material=10;materialized=9,2,4;math=7,15,6,1,2,9,23,0,22;mathematicians=1;matrix=2,9;matter=h10,r5,2,3,1;Maven=h20,36,r9,4,63;mavenInstallLocal=20;max=h7,r0,6,9,33,39,14,41,2,1;MAX_COMPACT_COUNT=h13;MAX_COMPACT_TIME=h13;MAX_FILE_RETRY=h13;MAX_LENGTH_INPLACE_LOB=h0,r1;MAX_LOG_SIZE=h0;MAX_MEMORY_ROWS=h0,r1;MAX_MEMORY_ROWS_DISTINCT=h13;MAX_MEMORY_UNDO=h0,r9,4,13,1;MAX_OPERATION_MEMORY=h0,r13;MAX_RECONNECT=h13;MAX_TRACE_DATA_LENGTH=h13;MAX_VALUE=22,4,13;maxCompactCount=4,13;maxCompactTime=4,0,13;maxConnections=33;maxFileRetry=13;MAXIMUM_SCALE=5,0;maxMemory=9,2,4;maxMemoryRowsDistinct=4,13;maxMillisToWait=9;maxQueryTimeout=13;maxReconnect=13;maxrows=14,8;maxTraceDataLength=13;MAXVALUE=9;maybe=9,2,8;MBean=9;McKoi=h2;McLeod=34;mean=10,0,1,3,2,11,25,7,8,14,4,15,5,13,9,6;meaning=28,29,4,0,1,7,2,33,6,13;meant=1,0;measurable=4;measure=11;measured=11,2;mechanism=4,1,10,9,2,6,23;media=17,10;Median=0;medium=11,10,1;MEDIUMBLOB=22;MEDIUMINT=22;MEDIUMTEXT=22;megabytes=2,0;meier=8;Melbourne=11;mem=2,36,9,4,6,23,1;memFS=1;memLZF=1;memo=22;memory=h11,2,r0,1,9,4,22,6,13,7,8,20,21,34,35,36;MEMORY_FREE=h7,r1;MEMORY_USED=h7,r1;menu=21;merchantability=10;merchantable=10;merge=h0,r4,9,6,21,1;Merge_=9;merged=1;merging=4,20;message=h8,r4,43,19,6,1,2,20,21;met=10;meta=12,8,3,16,4,9,2,5,15,24,0;metadata=9,12,17,4,0,1;meteorite=1;METHOD_NOT_ALLOWED_FOR_PREPARED_STATEMENT=h6;METHOD_NOT_ALLOWED_FOR_QUERY=h6;METHOD_NOT_FOUND_1=h6;METHOD_ONLY_ALLOWED_FOR_QUERY=h6;METHODS_MUST_HAVE_DIFFERENT_PARAMETER_COUNTS_2=h6;Micro=34;Microarray=17;Microsoft=h1,r4,23;middleware=17;midnight=22;might=2,10,21;migrate=4,9;migration=9,8;mill=34;Miller=2;million=17,1;MILLISECOND=13,0,7,2,1,11;min=h7,r39,9,4;MIN_COLUMN_NAME_MAP=h13;MIN_VALUE=7,9;MIN_WRITE_DELAY=h13;minColumnNameMap=13;mine=20;Mini=8;MiniConnectionPoolManager=17,33;minimal=19;minimum=5,0,13,1,17,51,10;MINIMUM_SCALE=5,0;Minneapolis=34;minor=5;MinorVersion=5;MINUS=0,5,1;minute=h7,r17,33,4,1;MINVALUE=9;minWriteDelay=13;Mirror=h63;Misc=9;Miscellaneous=h10;mismatch=6;missing=9,4,7,8;mix=6;mixed=h2,r9,29,6,22;mixing=6,23;MMM=7;MOD=h7;mode=h2,8,0,r4,1,9,6,11,21,45,13,48,36,40,43,7,5;model=17;modeling=17;Modern=h11;modification=h10,r9;modified=10,1,9,2,4,19;modifier=26,0;modify=10,2,9,6;modifying=1,2;modules=10,9,17,11;modulo=9,7;moment=9;monitor=20;Monitoring=17;Mono=1;monospace=9;month=h7,r10;MONTHNAME=h7;Morton=2;mostly=11;move=3,14,15,9,8,13;moved=3,2;moveToCurrentRow=3;moveToInsertRow=3;Moving=h2;Mozilla=51,10,20;MPL=10;msi=1;MSSQLServer=2,0,9;much=4,8,1,2,23;Mueller=34;multi=h2,1,r4,39,9,0,17,23,8,21,11,6;MULTI_THREADED=h0,r21,9,7,4,1;MultiDimension=t39;multiple=h2,8,11,10,r4,0,5,1,9,6,21,36,16,55,50,3,20;multithreaded=7;multithreading=h2,r4,55,9;multiuser=17;music=17;MUST_GROUP_BY_COLUMN_1=h6;mutually=10;MVC=17;mvcc=h1,r9,4,6,0,13,21;MY_DATA=0;MY_SQRT=0;MyDecimal=6;MyListener=0;Myna=17;mysql=h2,11,r9,4,0,8,13,1,7,36;Mystic=20;myTable=9;MyTrigger=6,0;MyTunesRss=17'; -ref['n']='naive=9;Naked=17;NAME_UNIQUE=0;nameCtx=57;named=2,5,16,6;nameString=7;naming=28,0,57;nanoseconds=7;National=17;Nations=10;native=h8,r9,4,19,51,2,34,20,1;NativeJ=1;nativeSQL=16,14;natural=h23,r9,0,5,4,1;nature=10;navigate=8;NCGC=17;NCHAR=22;NCLOB=22;necessarily=2,10;necessary=10,26,4,8,19;needed=8,9,26,4,10,19;negative=7,4,0;negligence=10;negotiations=10;NEITHER=10;NeoOffice=8;nested=4,9,7,0,20;net=h1,r9,17,2,23,63,20;NetBeans=8;netstat=6;NetSuxxess=34;network=1,9,8,17,45,11,2,4,6,34;never=1,2,6,0,7,11,4,43,19,22;newAggregateName=0;newConstantName=0;newConstraintName=0;newDomainName=0;newer=11,51,4,8,21,1;newest=4,8;newFunctionAliasName=0;newIndexName=0;newInstance=4;newline=44,4,0;newly=0;newName=0,9;newRoleName=0;newRow=31,37,19,2;newSequenceName=0;Newsfeed=4,20;newsgroups=10;newTableAlias=0;newTransactionName=0;newTriggerName=0;newUserName=0;newViewName=0;next=h4,21,r3,14,8,0,15,7,6,9,2,1,60,25,31,22;NEXT_PRIME=2;nextPrime=2;nextProbablePrime=2;NEXTVAL=h7,r4;nice=4;NIH=17;nio=1;NIO_CLEANER_HACK=h13;NIO_LOAD_MAPPED=h13;nioCleanerHack=13;nioLoadMapped=13;nioMapped=1;nLine=7;NLS_DATE_FORMAT=9;nnnnnnnnn=0,22;NO_DATA_AVAILABLE=h6;NO_DEFAULT_SET_1=h6;NO_DISK_SPACE_AVAILABLE=h6;NO_WAIT=0;nobody=10;NOCACHE=9;NOCHECK=0;NODATA=0;node=4,9,1,6,7,13;non=4,10,5,1,6,17,7,50,2,0,21,22;NON_UNIQUE=5,0;nonce=9;noncompliance=10;none=0,1,36,6;nopack=21;NOPASSWORDS=0;NOR=10;normal=36,6,0;normally=0,1,2,4,41,19;Northern=10;NOSETTINGS=0;NOT_ENOUGH_RIGHTS_FOR_1=h6;NOT_ON_UPDATABLE_ROW=h6;notation=9,0;note=2,11,8,0,1,17,7,16,10,20;nothing=31,7,14,10,23;notice=h10,r1;notified=41;notifies=1;notify=10,13;notifying=10;Notwithstanding=10;novelist=17;NOWAIT=0;npl=6;NSIS=20;NTEXT=22;NTFS=51;NULL_NOT_ALLOWED=h6;NULL_TO_DEFAULT=9;nullable=5,24,0,40,2,4,6;nullConcatIsNull=4;NULLIF=h7;nullPlusNonNullIsNull=5;NullPointerException=4,21;NULLS_FIRST=5;NULLS_LAST=5;nullsAreSortedAtEnd=5;nullsAreSortedAtStart=5;nullsAreSortedHigh=5;nullsAreSortedLow=5;Nullsoft=20;nullString=25,7,0;NUM_INPUT_PARAMS=5;NUM_OUTPUT_PARAMS=5;NUM_PREC_RADIX=5;NUM_RESULT_SETS=5;NumberFormatException=4;numeric=h7,r11,5,0,22,4;NUMERIC_PRECISION=0;NUMERIC_PRECISION_RADIX=0;NUMERIC_SCALE=0;NUMERIC_VALUE_OUT_OF_RANGE=h6;numerical=0;Nuxeo=17;NVARCHAR=22;NVARCHAR2=22;NVL2=9;nWire=17'; -ref['o']='obey=1;obj=57;OBJECT_CACHE=h13;OBJECT_CACHE_MAX_PER_ELEMENT_SIZE=h13;OBJECT_CACHE_SIZE=h13;OBJECT_CLOSED=h6;objectCache=13;objectCacheMaxPerElementSize=13;objectCacheSize=13;objectName=0;objectToSize=9;obligation=h10;obsolete=9;obtain=10;obtained=10;occur=4,6,1,55,38,2,34,8,0;occurred=6,14,31,37,4,41,33,1;occurrence=7,17;octal=7;OCTET_LENGTH=h7,r4;October=10;odbc=h1,r5,2,9;odbcad32=1;odd=6;off=0,16,11,2,1;offer=10,2;offered=10;offering=10;official=4;offset=26,19,30,8,2,0,42,4;offsetInt=26,19;Ohloh=17;oid=22,9,2;OL_D_ID=11;OL_I_ID=11;OL_O_ID=11;OL_W_ID=11;OLAP=9;old=4,31,0,37,2,8,1,16,10,19;older=h63,r4,21,13,22,1;oldRow=31,37,19,2;Oliver=34;omissions=10;once=31,37,50,11,3,9,4,6,10,23,1;onePhase=32;online=h8,r17;OntoBroker=17;ontology=17,34;Ontoprise=17;Oort=4;openBrowser=27;opened=2,4,1,11,41,6,8,37,0,31,27,21,13;openfire=9;opengeospatial=9;OpenGIS=9;OpenGroove=17;opening=h2,21,r4,0,11,8,9,6,41,13;OpenJDK=1;OpenJPA=9,17;openlinksw=9;OpenOffice=h8,r2,20;OpenSocial=17;OpenSource=17;OpenTelegard=17;operand=h0;operating=2,1,51,8;OPERATION_NOT_SUPPORTED_WITH_VIEWS_2=h6;operator=7,0,9;optimization=h11,r9,4,16,13,5,0;optimize=9,13,11,2;OPTIMIZE_DISTINCT=h13;OPTIMIZE_EVALUATABLE_SUBQUERIES=h13;OPTIMIZE_IN_LIST=h13;OPTIMIZE_IS_NULL=h13;OPTIMIZE_OR=h13;OPTIMIZE_REUSE_RESULTS=h0;OPTIMIZE_SUBQUERY_CACHE=h13;OPTIMIZE_TWO_EQUALS=h13;optimized=39,11,9;optimizeDistinct=13;optimizeDropDependencies=4;optimizeEvaluatableSubqueries=13;optimizeGroupSorted=4;optimizeIn=4;optimizeInJoin=4;optimizeInList=4,13;optimizeIsNull=4,13;optimizeMinMax=4;optimizeNot=4;optimizeOr=13;optimizer=h11,r9,2,0,4,13,21;optimizeSubqueryCache=13;optimizeTwoEquals=13;optional=9,7,5,8,2,34,0,1;optionally=9,8,0;ora=9;ora_rowscn=9;oracle=h2,11,r9,8,0,17,36,4;OraclePlatform=8;orafusion=9;orchestration=17;order=h0,r9,5,4,7,6,2,23,10,1,25,11,37,31,33,8;ORDER_BY_NOT_IN_RESULT=h6;ORDER_LINE=11;orderBy=23;ordered=5;orderId=23;ordering=7;ORDINAL_POSITION=5,0;ordinary=10;organization=17;oriented=17;origin=10;original=10,7,39,1,55,2,26,53,34,0;originally=1;originalSchemaString=0;originalString=7;originalTableString=0;originate=10;originator=10;Orion=17;ORM=17,23;orphan=6;OSDE=17;OSGi=9,17;OSGITrigger=9;Osmond=34;osoa=17;othersDeletesAreVisible=5;othersInsertsAreVisible=5;othersUpdatesAreVisible=5;otherType=0;otherwise=10,7,3,8,2,0,1,52,14,11,4,6,24;OUT_OF_MEMORY=h6;outer=5,9,0,21,7,2,4,6,13;OutOfMemory=21;outperforms=17;output=30,9,6,42,47,4,20;outputFileName=25;OutputStream=47,30,42;outside=31,37,36,4,8;outstanding=10;overflow=34,9,6,1;OVERFLOW_FOR_TYPE_1=h6;overflowExceptions=4;overhead=1,22;overload=6;override=25,4,2,9;overview=t69,h2,r70,17;overwrite=1,9;overwritten=1,7,11,0;OWL=17;own=5,10,1,2,3,8,9,17;ownDeletesAreVisible=5;owned=10;owner=9,0,1;ownership=10;ownerUserName=0;ownInsertsAreVisible=5;ownUpdatesAreVisible=5'; -ref['p']='P2C=9;P5H2=17;P_ID=6;pack200=21;package=17,2,8,20,4,23,1;pad=7;padding=36,7;paddingString=7;page=h2,17,r4,9,8,1,0,5,13,45,11,10,51,20;PAGE_SIZE=h13,r2,4;PAGE_STORE=4;PAGE_STORE_INTERNAL_COUNT=h13;PAGE_STORE_TRIM=h13;PageBtreeIndex=4;pageLanguage=59;PageParser=20;pageSize=2,13;pageStore=4;pageStoreInternalCount=13;pageStoreTrim=4,13;pagination=4;panel=8;Paradox=1;paragraphs=1;parallel=1;param=8,40,0;parameter_meta=8;PARAMETER_NOT_SET_1=h6;parameterIndex=h12,r18;parameterized=9;ParameterMetaData=t40,r12;parameterModeIn=40;parameterName=h18;paramIndex=18;parent=6,9,4;parentheses=0;parenthesis=9,0;parse=19,7,6,20;PARSE_ERROR_1=h6;PARSE_INT=4;parsed=8,7,11,6;PARSEDATETIME=h7,r6;parseInt=4,0;parseKey=19;parser=4,20,9;parsing=9,11,2,4;part=0,10,6,9,11,2,4,8,23,20;Part1=9;Partial=9;Partially=2,16;Participant=10;participate=10;particular=10;particularly=2;parties=10;Partition=9;partitioning=9;partners=10;partnership=17;party=10;pass=2,4;passed=2,50,5,4,0;passes=2;passing=h2,r4,1;passwordString=7,0;past=10;paste=9,20;Pastebin=20;patch=4,20,8;patches=h20,r9,4;patent=10;path=2,26,8,35,4,0,48,17,6,20,21,1;Pathogen=17;pattern=30,5,42,8,4,0,1,9,17;paused=0;pay=10;payment=10;pdf=9,59;pending=2;people=23,20;per=h11,r1,2,0,5,9,13,7,8,6,10;percent=10;perform=10,6;performance=t11,r9,1,2,4,10,13,21,17,38,59,8;performed=1,31,37,23;period=10;permission=8;permits=10;permitted=10;persist=2;persisted=22,7,2,4,8,1;persistence=17,8,23;persistent=0,2,11,4,6,9,17,16;Persister=17;person=10,0,1;personal=10;Pete=34;Peter=4;PFGRC=17;PG_DEFAULT_CLIENT_ENCODING=h13;pgAllowOthers=27,1;pgClientEncoding=4,13;pgDaemon=27,4;pgPort=27;PgServer=4;phantom=1;PhantomReference=9;phase=h1,r0,17,2,32,21;philip=9;phpMyAdmin=9;phrase=10,9;physical=32,2,4,1;Pickle=17;pid=6,11;pieces=1;PierPaolo=4;Piman=17;ping=9;pipe=7;PIVOT=9;PK_NAME=5,0;PKCOLUMN_NAME=5,0;PKTABLE_CAT=5;PKTABLE_CATALOG=0;PKTABLE_NAME=5,0;PKTABLE_SCHEM=5;PKTABLE_SCHEMA=0;place=9,0,1,4;placed=8;plain=1,2;plaintext=1;plan=4,11,0,2,21,23;planned=h9,r23;platform=h51,11,r8,17,63,34,52,2,36,6,20,21;play=17;please=20,1,2,21,0,11,4,8,17,45,16,7,6;plug=17,2,20;pluggable=h1,r9;plugin=17,9,8,20;plus=9,10;pmd=9;point=1,2,8,41,22,9,62,11,4,34,20,21;PointBase=34;pointer=9,4;pointing=1;Pojo=17;Poker=34;Poland=34;poleposition=h11,r17;polling=1;pool=h8,11,36,r33,0,32,9,17,4;poolable=14;pooled=28,14,33,4;PooledConnection=28,9;pooling=5;poor=1;Poormans=17;pop=1;popular=9;populate=2;populated=15;population=7;port=h8,r27,1,2,9,6;portability=h20,r34;portable=9,0;ported=10,2;porting=17,34,10;portions=10;portlet=17;Portugal=34;pos=30,42,0,5;position=h7,r3,30,42,15,60,9,36,6,0,41;positioned=5,25,6;possibility=10,4;possibly=9,2,6;post=17,20,21;postgresql=h2,11,r9,1,4,8,0,21;posting=20;potential=17,10;potentially=4,5,27;pow=1,7;power=h7,r1,2,13,4,10,0,21;poweroff=1;practicable=10;practice=6,10;pre=36,0,1;precision=22,5,15,7,40,4,0,24,6,9;precisionInt=22;Prefer=9;PREFERDOSLIKELINEENDS=2;Preferences=8,20;preferred=10,13;prefix=19,4,2,1,9,7,5,6,0,13;PREFIX_TEMP_FILE=h13;prefixes=13,7;prefixTempFile=13;prep=6,39,11,1;prepare=h0,r32,35,1,9,6,10;prepareCall=16;prepared=h11,r16,1,39,12,9,4,32,35,3,14,2,40,13;PreparedStatement=t12,r16,22,6,4,1,39,35,8,9,11,23,13;prepareStatement=16,11,6,13,1;prepended=4;preserved=27;press=11,8;prevent=0,8;previous=3,10,9,11,4,1;previously=4,8;price=23,0;primary=5,0,6,4,19,9,11,8,2,3,17,26,23,1;PRIMARY_KEY=5,8,0;PRIMARY_KEY_E=4;primaryCatalogPattern=5;primaryKey=23;primarySchemaPattern=5;primaryTable=5;primitive=23,1,22;printed=8,6;println=11,8,1;printStackTrace=43;PrintStream=44,43;PrintWriter=28,43;prior=10;prioritize=20;priority=h9,r1;private=23,2,36,4;PRIVILEGE=5,9,6;PRIVILEGE_TYPE=0;PRO=17;probability=1;probably=19,9,11,4,21;problem=h1,20,21,r2,4,9,11,6,8,0,22,28,38,49,13;problematic=9;proc=9;procedure=h2,r5,9,8;PROCEDURE_CAT=5;procedure_columns=8;PROCEDURE_NAME=5;PROCEDURE_SCHEM=5;PROCEDURE_TYPE=5;procedureNamePattern=5;procedureNoResult=5;procedureReturnsResult=5;process=h11,8,r1,2,17,4,9,6,20,36,10,0,7,13,21;processed=4;processes=2,1,17,4,9;processing=17,14;processors=9;produce=4,14,8,21;product=h17,r23,10,5,1,21;productCount=23;ProductGroup=23;productId=23;productInfos=23;production=1,21;productName=23;ProductPrice=23;prof=11;prof_start=8;prof_stop=8;profile=11;profiler=h11,r38,4;profiling=h11,r4,8;Profit=10,17;program=10,8,1,52,17,11,45;programmed=17;programming=17,10;progress=48,54,56,46,47,21;prohibited=16,10,1;prohibits=10;project=h17,23,21,63,r20,9,4,34,1;prominent=10;prompt=1,8;promptly=10;proof=4,34,23;prop=2,20;propagated=1;properly=10;properties=h1,r9,4,13,8,2,5,6,7,11;property=h10,r13,4,1,6,9,25,36,2,5,8,21,14,11,0,7,3;prospectively=10;protect=1,2,9,23;protected=1,4,8;protecting=1;protection=h1,r27,21;protocol=h1,r0,9,2,17,11,32,8;prototyping=2;prove=10,1;proven=1;provide=1,23,20,17,10,8,9,11,32,4;provided=10,2,5,1,0;provider=17,9;providing=h20,r9,17,4;provision=10;proxy=17;pseudo=7,9,5,1;PSEUDO_COLUMN=5;PSM=9;psqlodbc=1;psqlodbc_08_04=4;ptnOption=9;public=h10,r23,8,2,0,6,9,20,1,28,26,4,57,50,33,19,7;PUBLIC_STATIC_JAVA_METHOD_NOT_FOUND_1=h6;publicly=10;publish=10,9,11;published=10,11,34;publishing=17;Pulakka=34;pure=23,9,2,4;purpose=10,17;pursuant=10;pushd=4;put=2,8,10,21,1;putStream=9;pwd=2,6,46,1,44,38,47,27,53'; -ref['q']='Quaere=23;qualified=0,4,21;qualify=10;quality=17,4,10;quantified=5;QUANTITY=0;quarter=h7;queries=4,11,9,0,2,1,13,6,23,39,38,69,8;query_indexed_int=11;query_indexed_string=11;query_string=11;QUERY_TIMEOUT=h0;Querydsl=23;querying=2;queryString=7,26,19;question=t21,r20;QUEUE=0;QUEUE_SIZE=0;quick=1;quicker=17;quickly=17,2;Quickstart=t45,r70,59;Quickstarter=8;quiet=48,54,56,46,47,4;QUIT=11;quite=11,4,9,8,21,1;quote=0,5,22,1,25,9,2,4,3;quoted=h0,r2,26,4,19,25,7,6,8,1;quotedName=0;quoting=4'; -ref['r']='race=1;RAD=17;RADIANS=h7;radix=5,0;rail=20;Railo=17;railroad=h20,r4;RAM=9;Ramiere=34;ran=11,6;RAND=h7,r1;random=1,7,11,2,9,8,21;RANDOM_UUID=h7,r1;RandomAccessFile=13,1,4;randomized=2,34,21;randomly=1,9;range=h0,r39,2,9,11,6;ranging=17;RANK=9;rapid=2;Rapidshare=20;rate=1;ratio=4;raw=8,22,26,19,1;RAWTOHEX=h7;RazorSQL=17;Razuna=17;RDF=17;reached=6;READ_COMMITTED=0;READ_FROM=9;read_hot=11;READ_UNCOMMITTED=0,21;readable=49,8,1;reader=3,12,25,38,19,16,42,44,18,9,17,22,13;readFromURL=9;reading=h8,1,r25,9,4,7,2,30;readonly=h7,r0,16,9,2,4;readPassword=2;readRow=60;ready=8,1;real=h22,11,r9,13;really=11;realtime=8,17;realType=0;reason=1,11,6,43,21,34,20,22;reasonable=10,9,11;reasonably=10;reasoning=1;Rebuild=9;receipt=10;received=10;receives=10;recent=1;recently=4,1;recipient=10;recognized=8;recommendations=17;recommended=8,51,11,2,4,22,1;recompile=0,13;RECOMPILE_ALWAYS=h13;recompileAlways=13;reconnect=h2,r4,36,13;RECONNECT_CHECK_DELAY=h13;reconnectCheckDelay=13;record=1,9,2,0,17,11,5,13;recover=t49,h1,r4,32,21,9,11,2,6,8;recovering=41,49,8,13;recovery=h2,r9,4,6,32,8,0;recreate=1;recreated=2;recursion=4;Recursive=9;red=8;RedBase=10;redeployment=8;Redirects=44;redo=13;REDO_BUFFER_SIZE=h13;redoBufferSize=13;reduce=1,9,7,11,2,4,6,0;redundancy=7;redundant=9,2,1;Ref=3,18,12;REF_GENERATION=5;refactorings=17;refColumnName=0;refer=0,1;reference=5,28,4,57,6,3,0,2,15,12,8,9,36,11,59,35,21;referenced=0,5,6;referencing=h2,r6;referential=h0,r6,5,2,21,1;REFERENTIAL_INTEGRITY=h0,r21;REFERENTIAL_INTEGRITY_VIOLATED_CHILD_EXISTS_1=h6;REFERENTIAL_INTEGRITY_VIOLATED_PARENT_MISSING_1=h6;referentialConstraint=0;referred=10;reflect=9;reflection=9,34;refman=9;reformed=10;refreshRow=3;refTableName=0;regardless=2;REGEXP=0,9,6;REGEXP_REPLACE=h7;regexString=7;region=23;register=32,1,9,17,28;registered=2,28,6,8,10,41,1;registerOutParameter=18;regression=21;regular=0,9,2,11,7,6,23,1;regularly=20,21,1;regulation=h10;reindex=19,26;reject=9;rejected=0;related=10,6,9,2;relates=17;relating=10;Relation=17;relational=17;relative=3,21,2,13,1;relatively=1,11,4,22;release=h21,r2,16,15,4,30,42,1,29,9,10,0,51,6,20;released=2,1,10,9,17,16,63,0;releaseSavepoint=16;relevance=26,19;relevant=9,8,10;reliability=21;reliable=h21,r1;relies=15,6;reload=9;relying=6;remain=10,2;remainder=6,10;remaining=9,11,1;remarks=0,5,8,1;remember=9,2;remembered=2,3;remote=h1,r2,9,6,8,38,27;REMOTE_CONNECTION_NOT_ALLOWED=h6;remotely=8,2,1;remoting=17;remove=0,35,7,31,37,32,26,19,9,4,10;removeAllIndexes=35;removeAllTriggers=19;removeConnectionEventListener=32;removed=7,4,0;removeIndexInfo=35;removeIndexModifier=26;removing=9,4,1;rename=h0,r9,6,8,10,13;renamed=2,4,6,10,0;renaming=h2,r4,0;repair=10;repeat=h7,r1;repeatable=1;repeated=7,4;repeating=9;replace=h7,r9,11,4,1;replaceAll=7;replaced=15;replacement=23,7,13;replacementString=7;replay=9;replicating=9;replication=9,17;repo=20;report=20,21,9;reported=14,3,16,21,4,34,8;Reporting=h20;repositories=17;repository=h20,63,r17,9,4;representation=7,43,10,0;represented=2;representing=7;reproduce=10;reproduced=20;reproducing=2;REPRODUCTION=10;request=h20,21,r9,14,2,11,8;requested=14;require=h2,r23,17,11,6,1,9,69,10,0;requirement=h10,51,23,r39,2,1;res=20,9;research=17;resellers=10;reserve=13,4,10;RESERVE_MEMORY=h13;reserved=h1,r10;reserveMemory=13;reset=60,15,3,13,9,11,0;reside=2,4,8,1;resistant=9;resize=9;resizing=9;resolution=0;resolved=2,10;resort=13;resource=17,9,29,15,30,8,42,4,0,1;respect=10,4;respective=2,1;respond=16;responding=48,0;response=9,17,1;responsibilities=10;responsibility=h10;responsible=10;rest=9,17;restart=0,1,7,11,4,8;restarted=4;restarting=8;restore=t54,h8,r6,0,1;restrict=0,9,2,10,1;restricted=5;Restricting=h1;restriction=h23,r8,1;RESULT_SET_NOT_SCROLLABLE=h6;RESULT_SET_NOT_UPDATABLE=h6;RESULT_SET_READONLY=h6;resulting=1,10,6,8;resultSetConcurrency=16;resultSetHoldability=16;ResultSetMetaData=t24,r2,15,21,40,12,3,8,13;resultSetType=16;retrieval=17;retrieve=8,33,15,11;Retrotranslator=4,20;retry=13;RETURN_LOB_OBJECTS=h13;returned=7,19,3,26,4,40,29,0,5,1,12,24,11,15,39,13;returning=h2,r7,0,1;returnLobObjects=13;RETURNS_RESULT=0;reuse=9,8,0,1;reuseSpace=4;revealed=1;reverse=0,4,1;revised=10;revisions=10;revoke=h0,r6;revoked=10;revolutions=1;RFC=1;rgb=36;RIFE=17;right=h0,10,7,r9,8,4,6,21;rightmost=7;rioyxlgt=0;risk=10,1,13;risky=27;rnd=8;roadmap=t9,h34,r59,20;Rojas=34;role=h0,r6,2,9;ROLE_ALREADY_EXISTS_1=h6;ROLE_ALREADY_GRANTED_1=h6;ROLE_CAN_NOT_BE_DROPPED_1=h6;ROLE_NOT_FOUND_1=h6;roleName=0;ROLES_AND_RIGHT_CANNOT_BE_MIXED=h6;Roll=16,32,2,0;rollback=h0,r14,4,16,5,37,31,12,6,2,32,9,1;rolled=0,1,62,2,7,6,16,22;rolling=0,14,13;room=1;root=6,20;ROUND=h7,r1,0;rounded=2,7,14,0;rounding=22;ROUNDMAGIC=h7;ROW_NOT_FOUND_WHEN_DELETING_1=h6;ROW_NUMBER=9;rowCount=3,7;rowCountInt=0;rowDeleted=3;rowid=9;rowInserted=3;RowList=4;rownum=h7,r9,5,4,1;rowNumber=3;rowSeparatorWrite=25;RowSource=15;rowUpdated=3;royalty=10;RPAD=h7;RPM=1;rss=17,63;RTRIM=h7;Ruby=9,17;rubyforge=9;rule=7,25,0,1;runFinalize=h13;RUNNING_TOTAL=7;RunScript=t38,h0,r8,2,9,4,1,47,13;runtime=2,9,4,51,11,6,8,41,20;runTool=48,52,54,56,44,38,47,53,27,49,58,46,4;Russian=4;Rutema=17;rwd=1,2;rws=2,1'; -ref['s']='S_I_ID=11;S_QUANTITY=11;S_UNKNOWN=6;S_W_ID=11;Safari=13;safe=4,55,2,16,1;safely=2;safety=16;Sainsbury=4;sale=10;salt=h0,r1,2;Salz=1;Sam=4;sample=h45,r2,9,0,7,11,6,4,23,1,70,38,8,21,13;SAMPLE_SIZE=0;SamplesTest=23;sans=36;Santa=10;Sat=7;SATA=9;Sava=17;save=41,1,8;saved=8;savepoint=t62,h0,r16,6,2,5,21;SAVEPOINT_IS_INVALID_1=h6;SAVEPOINT_IS_NAMED=h6;SAVEPOINT_IS_UNNAMED=h6;savepointName=0;saving=22,1;saying=2;Scala=17,4,23;scalar=39,2;SCALAR_SUBQUERY_CONTAINS_MORE_THAN_ONE_ROW=h6;scalarColumn=39;scale=3,18,5,15,40,2,12,24,0,9,4,22;scaleInt=22;scan=9,11,4,0,1;scanned=11;scanner=h11;scanning=41;scapegoat=9;scheduler=17;SCHEMA_ALREADY_EXISTS_1=h6;SCHEMA_CAN_NOT_BE_DROPPED_1=h6;SCHEMA_NAME=0;SCHEMA_NAME_MUST_MATCH=h6;SCHEMA_NOT_FOUND_1=h6;SCHEMA_OWNER=0;SCHEMA_SEARCH_PATH=h0;schemaName=0,7,31,37,2;schemaNameString=26,19;schemaPattern=5;SCHEMATA=0;sciences=17;scope=5,7;SCOPE_CATALOG=5;SCOPE_IDENTITY=h7,r4;SCOPE_SCHEMA=5;SCOPE_TABLE=5;scoped=8;score=h19,r26,4;scrambling=9;scratch=34;script=t47,h8,0,r38,4,2,9,1,59,11,58,13,17,45,49,10,51;Scriptable=20;scriptDirectory=13;Scriptella=17;scripting=9,17;scrollable=6,2,3;sE2rtPiUKtT=2;Seam=17;SEARCH_PATH=9;searchable=24,5,0;searchData=19,26,8;Searches=26,30,42,19,15,3;searching=17,4,6;searchString=7;second=h7,r1,2,14,33,11,4,28,29,9,0,32,3,16,6,8;SECOND_PRIMARY_KEY=h6;Secondary=0,9;secret=1;section=10,0,9,2,4,8;secure=h2,r1,34,9,17,7,10;SECURE_RAND=h7,r1;secureserv=2;securing=1;security=h1,2,r8,9,45,28,22;seed=7,1;seek=4;seems=21,9,11,10,1;SELECT_FOR_UPDATE_MVCC=h13;selectCount=23;selectDistinct=23;selected=7,9,4,8,0,1;selectExpression=0;selectForUpdateMvcc=9,4,13;selectivity=h7,11,r0,13;self=11,6,1;SELF_REFERENCING_COL_NAME=5;sell=10;selling=10;semantic=17;SemanticWeb=17;semicolon=8,7,2;SemmleCode=17;send=9,17,2,4,20,13;sending=12,20;sensitivity=2;sent=2,4,1;sentence=2;sentinel=11;Sepang=11;separate=h11,r2,10,0,1,55;separated=h8,r7,19,2,5,26,13,25,53,1;separately=2;separating=6;separator=25,7,5,13,9;September=10;SEQ_ID=0;SeQuaLite=17;sequence=h0,r6,9,4,7,5,2;SEQUENCE_ALREADY_EXISTS_1=h6;SEQUENCE_BELONGS_TO_A_TABLE_1=h6;SEQUENCE_CATALOG=0;SEQUENCE_NAME=0;SEQUENCE_NOT_FOUND_1=h6;SEQUENCE_SCHEMA=0;sequenceName=0,4;sequenceString=7;sequential=11;sequentially=11;Sergi=4;serializable=1,2,0;Serialization=22;SERIALIZATION_FAILED_1=h6;serialize=9;serialized=h1,r4,3,6,9,2,28,21,22;series=10;serif=36;serve=17,10;server1=1;server2=1;SERVER_CACHED_OBJECTS=h13;SERVER_RESULT_SET_FETCH_SIZE=h13;serverCachedObjects=13,1;serverList=53,1;serverListString=0;serverResultSetFetchSize=14,3,13;ServerSocket=9;service=h1,r27,17,9,51,28,4,52,11;servicing=10;servlet=h8,r9,17,4;Sesar=17;session=h8,r7,6,0,9,4,17,11,2,16,13;SESSION_ID=h7,r0,1;SESSION_START=0;SESSION_STATE=2,0;sessionId=7;sessionInt=7;SET_PROPERTY=1;setArray=12;setAsciiStream=12,18,42;setAttribute=59;setAutoCommit=16;setBigDecimal=6,12,18,13;setBinaryStream=12,18,30,9,22,1;setBlob=12;setBoolean=12,18;setByte=12,30,18,22;setCatalog=16;setCharacterStream=12,18,42,22,1;setClob=12;setColumns=19;setCursorName=14;setDate=12,18;setDescription=28;setDouble=12,18;setErr=44;setEscapeCharacter=25;setEscapeProcessing=14;setFetchDirection=14,3;setFetchSize=14,3;setFieldDelimiter=25;setFieldSeparatorRead=25;setFieldSeparatorWrite=25;setFloat=12,18;setHoldability=16;setIgnoreList=19;setIn=44;setInitialized=35;setInReader=44;setInt=12,18;setLineSeparator=25;setLoginTimeout=28,33;setLogWriter=28;setLong=12,18;setMaxConnections=33;setMaxFieldSize=14;setMaxRows=14,3,1;setNull=12,18;setNullString=25;setObject=12,18,22,9,11,4;setPassword=28,9;setPasswordChars=28;setPoolable=14;setPort=9;setProgress=41;setProperty=1,2,13;setQueryTimeout=14,6;setReadOnly=16,9,4;setRef=12;setRowSeparatorWrite=25;setSavepoint=16,6;setShort=12,18;setString=42,12,18,22,1;setTcpNoDelay=9;setTime=12,18;setTimestamp=12,18;settlement=10;setTransactionIsolation=16;setTransactionTimeout=32;setTypeMap=16;setUnicodeStream=12;setup=9,1;setURL=28,12,18;setUser=28;several=17,1;sfs=9;SFTP=9;SHA=1,2;SHA256=7,8;shadow=9;shall=10;ShapeLogic=17;share=9,34,10,0,1;SHARE_LINKED_CONNECTIONS=h13;shared=1,9,17,2,8,13,21;shareLinkedConnections=13,1;Sheet=h36,r59;shell=t44,h8,r4,9,17,51;Shellbook=17;Shift=9;short=5,3,15,18,22,12,9,11,20,13,1;shorter=7,22;show=h0,r4,8,1,9,38,11;shown=45,8;showResults=38;shrink=9,4;shrinking=4;shutdown=h0,r2,27,4,6,11,8;shutdownTcpServer=27,4,8;shutting=27,8;side=h0,r1,8,9,17,45,2,22;sigmod=9;SIGN=h7,r0;signal=2,1;signed=40,24,22,8;Significant=20;significantly=11;Signsoft=17;Sigurdsson=34;silently=19;similar=h23,r11,9,4,0,17,7,2,8,10;similarity=17;Simon=17;simple=11,17,2,0,1,8,4,20,61,9,15,34,33,13;SimpleArray=t61;SimpleDateFormat=7;SimpleORM=17;simpler=11,23;simpleResultSet=t15,61,h2,r4,8,19,9,60;SimpleRowSource=t60,r15,9,4;simplest=2,8;simplicity=17,1;simplified=11;simplifies=2,4;simplify=9,4,20;simply=2,20;simulate=1,2;simulation=17;SIN=h7,r6;since=4,13,1;single=0,11,2,22,9,1,4,6,10,13;singleton=39;SINH=9;site=9,20;situation=h2,r21,1,11;six=10;size=h2,21,11,r4,13,0,1,22,9,5,36,7,24,14,6,3;skill=10;skip=0;SkyCash=34;slash=9,4;slave=9;sleep=1;SLF4J=2,9,0;slight=11;slightly=11,4;Slovensky=4;slow=h21,r11,9,4,2,1,13,7,34,8;slower=11,2,1,4,21,0;slowest=11;slowing=0;slowly=11;small=11,4,17,2,3,1,52,9,7,8;SMALLDATETIME=22;smaller=4,23,7,2,5,16,14,11,20;smallest=7;SMALLINT=h22,r11;smallintType=0;SmartFoxServer=17;SMPT=9;Snapshot=h20,r8;snippet=8;Social=17;socket=h1,r2,9,13,4,6;SOCKET_CONNECT_RETRY=h13;SOCKET_CONNECT_TIMEOUT=h13;socketConnectRetry=13;socketConnectTimeout=13;Soerensen=34;soft=11,2,35,4,21;SOFT_=2;SOFT_LRU=2,4,21;SoftHashMap=35;software=h20,51,r10,17,1,34,9,45,49,21;sold=10;soldOutProducts=23;sole=10;solely=10;solid=36;Solo=17;solution=17,8,1,6,11,2,13;solve=6,9,0;solved=21;somebody=3,11;somehow=9;something=6,45,23;sometimes=4,2,11,13,1,21,8;soon=27,10;sophisticated=2;sort=0,9,13,1,5;SORT_NULLS_HIGH=h13;SORT_TYPE=5,0;sorted=h11,r5,4,2,13,1;sorting=h1,r9,17,2,4,13;sortNullsHigh=5,13;sound=7;soundex=h7;SOURCE_DATA_TYPE=5,0;sourceCode=2;sourceCodeString=0;sourceforge=9,63,20;sourceSchemaString=7;space=h7,2,r0,9,6,11,41,4,1,8,20,22;SPARQL=17;spatial=9,17,2;spec=4,6,16;special=h8,r7,2,10,9,44,38,11,4,1;SPECIAL_SIN=6;specialized=2;specially=9,11,4,27,13,1;specific=5,3,9,2,15,7,6,8,1;SPECIFIC_NAME=5;specification=21,17,9,6,20,13;specifies=2,5,9,7;specify=2,0;specifying=2,0;speed=11,4,0,1;speedup=9;spellcheck=20;spelling=20;spends=1;spent=34;split=1,9,11,2,4,23,0,20,13;SPLIT_FILE_SIZE_SHIFT=h13;splitFileSizeShift=13;sponsored=11;spots=11;spread=11,34;Spring=h8,r17;Springfuse=17;SpringTrigger=9;sql1992=9;sql_2003_standard=9;SQL_DATA_TYPE=5;SQL_DATETIME_SUB=5;SQLData=9;SQLInjection=9;SQLite=11;SQLJ=9;SQLOrm=17;sqlStateSQL99=5;sqlType=18,12,15;SQLWarning=14,15,3,16;sqrt=h7,r6,9,0;square=7,2;Squill=23;Squirrel=17,9;SquirrelSQL=9;sr5tech=9;src=20,51,8,2,4,23,9,11,59;ssl=h1,r2,27,8,13;SSL_DH_anon_WITH_RC4_128_MD5=13,1;SSLServerSocket=1;SSLSocket=1;stable=h21,63,r4;stack=43,4,6,20,17,11,8,21,1,51,13;stackable=1;stackTrace=43;standalone=8,9,17,15,53,33,6;standard=h1,r44,9,7,2,43,17,15,4;standardized=1;standby=9,1;standing=4;stands=23,34,1;startCollecting=11;started=8,1,2,4,52,27,11,6,34,23,20,21;starting=h8,1,r29,30,42,13,9,2,4,39,7,5,6;startInt=7,0;startTranslate=59;startup=h11,r8,9,2,4,13,21;startWebServer=27,4;stat=6,1;state=h10,23,r9,43,41,2,1,5,37,4,0,31,33;stated=10;STATEMENT_START=0;STATEMENT_WAS_CANCELED=h6;stating=10;statistics=h11,r4,9,58,0;status=27,0;statute=h10;stay=7,10,0;STDDEV=7;STDDEV_POP=h7;STDDEV_SAMP=h7;step=h45,r14,3,1,2,11,10,8;Stepan=4;Steve=34;Steward=10;still=4,1,2,8,21,11,16,6,0,20;STOCK=11;stolen=1;stop=h8,1,r27,4,9,2,35,21;stopCollecting=11;stoppage=10;stopped=8,2,4,1,27,6;stopping=h8,r9,1;stopWords=9;storage=1,4,11,9,0,20;STORAGE_TYPE=0;store=4,1,9,22,2,5,11,8,13;STORE_DOCUMENT_TEXT_IN_INDEX=h26;stored=h2,21,r1,4,8,13,9,0,26,5,6,22,11,54,19;storesLowerCaseIdentifiers=5,9;storesLowerCaseQuotedIdentifiers=5;storesMixedCaseIdentifiers=5;storesMixedCaseQuotedIdentifiers=5;storesUpperCaseIdentifiers=5;storesUpperCaseQuotedIdentifiers=5;storing=h1,r22,4;story=17;StorYBook=17;str=42;straight=20;strange=4;strategy=11,41;stream=12,3,30,42,44,43,47,4,16,0,9,17,1,13;StreamCruncher=17;streamed=22;streaming=9,2,4;strength=0;stress=2,21;STRICT=10;STRING_FORMAT_ERROR_1=h6;StringBuilder=0;STRINGDECODE=h7,r6;STRINGENCODE=h7;STRINGTOUTF8=h7,r6;strong=1,9,2;structural=11;structure=h51,r17,10,9;Stuck=17;Studios=17;style=36,6,59,20;stylesheet=7;St\u00e9phane=34;subclass=22;Subclipse=20;subdirectories=4;subject=10;sublicense=10;Submit=20;submitted=8;subqueries=5,2,4,0,9,13;subquery=9,6,7,4,13;SUBQUERY_IS_NOT_SINGLE_COLUMN=h6;subscribe=9;subselect=4;subsequent=10;subsequently=10;subset=29,1;substance=10;SUBSTR=7;substring=h7,r42,1;substructure=17;subtract=7;Subversion=h63;succeed=24,2;successful=13,1,11,15,27,3,21;successfully=1,8;suddenly=1;sufficient=10,2;sufficiently=10;suffix=9,11,5,8,0;suggest=11;suggested=14,3,0;suggestion=9;suitable=10;suite=17,20,13,1;sum=h7,r9,6,0;SUM_OR_AVG_ON_WRONG_DATATYPE_1=h6;summand=h0;summary=h10,r17,20;sun=8,9,51,2,20,13,21,11,0;Sunday=7;super=5;super_tables=8;super_types=8;superseded=3;SUPERTABLE_NAME=5;supplied=55,7,2,46;supplier=10;supply=1;Supporters=h34;supporting=17,9,1;supportsAlterTableWithAddColumn=5;supportsAlterTableWithDropColumn=5;supportsANSI92EntryLevelSQL=5;supportsANSI92FullSQL=5;supportsANSI92IntermediateSQL=5;supportsBatchUpdates=5;supportsCatalogsInDataManipulation=5;supportsCatalogsInIndexDefinitions=5;supportsCatalogsInPrivilegeDefinitions=5;supportsCatalogsInProcedureCalls=5;supportsCatalogsInTableDefinitions=5;supportsColumnAliasing=5;supportsConvert=5;supportsCoreSQLGrammar=5;supportsCorrelatedSubqueries=5;supportsDataDefinitionAndDataManipulationTransactions=5;supportsDataManipulationTransactionsOnly=5;supportsDifferentTableCorrelationNames=5;supportsExpressionsInOrderBy=5;supportsExtendedSQLGrammar=5;supportsFullOuterJoins=5;supportsGetGeneratedKeys=5;supportsGroupBy=5;supportsGroupByBeyondSelect=5;supportsGroupByUnrelated=5;supportsIntegrityEnhancementFacility=5;supportsLikeEscapeClause=5;supportsLimitedOuterJoins=5;supportsMinimumSQLGrammar=5;supportsMixedCaseIdentifiers=5;supportsMixedCaseQuotedIdentifiers=5;supportsMultipleOpenResults=5;supportsMultipleResultSets=5;supportsMultipleTransactions=5;supportsNamedParameters=5;supportsNonNullableColumns=5;supportsOpenCursorsAcrossCommit=5;supportsOpenCursorsAcrossRollback=5;supportsOpenStatementsAcrossCommit=5;supportsOpenStatementsAcrossRollback=5;supportsOrderByUnrelated=5;supportsOuterJoins=5;supportsPositionedDelete=5;supportsPositionedUpdate=5;supportsResultSetConcurrency=5;supportsResultSetHoldability=5;supportsResultSetType=5;supportsSavepoints=5;supportsSchemasInDataManipulation=5;supportsSchemasInIndexDefinitions=5;supportsSchemasInPrivilegeDefinitions=5;supportsSchemasInProcedureCalls=5;supportsSchemasInTableDefinitions=5;supportsSelectForUpdate=5;supportsStatementPooling=5;supportsStoredFunctionsUsingCallSyntax=5;supportsStoredProcedures=5;supportsSubqueriesInComparisons=5;supportsSubqueriesInExists=5;supportsSubqueriesInIns=5;supportsSubqueriesInQuantifieds=5;supportsTableCorrelationNames=5;supportsTransactionIsolationLevel=5;supportsTransactions=5;supportsUnion=5;supportsUnionAll=5;supposed=1;sure=1,20,9,8,10;surrounded=1;survive=10,1;swap=2;swapped=2;Sweden=34;swing=2,34;Swiss=17;switch=6,0,20,1;switched=11,16,1,7,5,4,0;switches=0,16,11,1;switching=h20,r11,4,0;switchSource=20;switchSourceJdk13=6;Switzerland=34;SWT=17;Sybase=9;SymmetricDS=17;sync=h0,r4,13,1,9,11;SYNC_METHOD=h13;synchronization=17;synchronize=9,17,2,1;synchronized=4,1,2,16,20;synchronizing=2;synchronous=1;synchronously=1;syncMethod=4,13;SYNONYM=9;syntax=h0,7,23,8,r22,9,38,14,5,6,2,4;SYNTAX_ERROR_1=h6;SYNTAX_ERROR_2=h6;SYS_PROP=6;SYSDATE=7,5,1;sysdummy1=9;sysibm=9;SysProperties=t13,r1;SYSTEM_ERRORS=9;system_range=4,11,7,8,0;SYSTIME=5,1;SYSTIMESTAMP=5,1;syswow64=1'; -ref['t']='tab=9,27,20;TABLE_CAT=5;TABLE_CATALOG=0,5;TABLE_CLASS=4,0;TABLE_DISTINCT=7;TABLE_NAME=5,0;TABLE_OR_VIEW_ALREADY_EXISTS_1=h6;TABLE_OR_VIEW_NOT_FOUND_1=h6;table_privileges=8,0;TABLE_SCHEM=5;TABLE_SCHEMA=0;TABLE_TYPE=5,0,8;tableAlias=0;TableBase=68;TableEngine=t68,r0;tableEngineName=0;tableExpression=0;tableId=2;tableIndexOther=5;tableName=0,5,31,37,9,2,23;tableNamePattern=5;tableNameString=26,19;tableScan=4;tablespaces=9;tag=8,2,9,0;Tahoma=36;tail=9;taken=11,10;talking=4;TAN=h7;TANH=9;Tanuki=1;target=h20,r1,48,54,7,47,5,53,8,0;targeted=17;targetSchemaString=7;targetSqlType=12,18;Task=62,6,1;taxon=17;tcp=h8,r2,27,1,52,9,6,36,4,13;TCP_NODELAY=9;tcpAllowOthers=6,27,8,1;tcpDaemon=27,4;tcpPassword=27,8;tcpPort=1,27,8;tcpServer=8;tcpShutdown=27,8;tcpShutdownForce=27;tcpSSL=27;Team=20;technical=1;technologies=17;technology=23;telling=10;temp=6,13,2,0,9,7;template=20,9,11,2;temporarily=11;temporary=4,0,2,13,9,20,1;term=h0,r10,5,35,4,1;terminate=10,52,2,1;termination=h10,r2,1;TERTIARY=0;test1=9;test2=7,0,9;TEST_1=9;TEST_2=9;TEST_A=6;TEST_B=6;TEST_ID=6;TEST_ID_PARENT=6;test_mem=2;TEST_ROLE=6;TEST_ROLE_2=6;TEST_SCHEMA=6,0;TEST_SEQ=7,6;TEST_USER=6;TEST_VIEW=6,0;TestAll=20;testAnonymousTypes3=23;testCount=23;TestCsv=8;testdb=2;TestDiskSpaceLeak=9;tested=h11,r1,51,23,21,2,4,0,13;testGroup=23;testing=h8,r4,17,11,0,1,2,6,16,34;testLength=23;TestMultiDimension=2;testSelectManyCompoundFrom2=23;testSelectSimple2=23;testSimple=20;TestUndoLogMemory=9;testWhereSimple2=23;testWhereSimple3=23;testWhereSimple4=23;TestWrite=1;textarea=36,9;textual=1;thanks=4,34;thedevcloud=9;themselves=10;theoretical=4;theoretically=4;theory=10,23,1;thereafter=10;therefore=2,1,29,11,4,8,10,20;thereof=10;things=9,1;third=10,8,1;Thomas=34,0;those=1,2,10,21,8,11,17,9,4,34,23,7,50;thousand=1,17;thread=1,2,4,27,16,9,11,14,8;threaded=4,9,11,2,8;threading=0,21;ThreadLocal=9;three=2,8,17,11,5;threshold=1;threw=4;throttle=h0;throttling=0;through=10,1,70;Throwable=43;throwException=19;throwing=h2;thrown=h6,r4,2,0,13,33,1;thus=17;tilde=6,28;TIME_CONSTANT_2=h6;timeout=h2,1,r28,14,33,0,32,16,9,6,13,4,7;timestamp=h0,22,r7,3,18,15,12,9,2,6,8,11,4,23;TIMESTAMP_CONSTANT_2=h6;TIMESTAMPDIFF=7,4;timestampType=0;timeType=0;timezone=9,4,22;timeZoneString=7;Timing=8;TINYBLOB=22;TINYINT=h22,r6,11;tinyintType=0;TINYTEXT=22;title=10,9,8;titled=10;TLS=h1,r2;TMENDRSCAN=32;TMFAIL=32;TMJOIN=32,4;TMNOFLAGS=32;TMRESUME=32;TMSTARTRSCAN=32;TMSUCCESS=32;TMSUSPEND=32;TO_BINARY=6;TO_CHAR=9;TO_DATE=9;TO_NUMBER=9;toBinaryString=6;TODAY=7,5,1;toDegrees=7;todo=9;together=1,60,6;tokenizer=9;tolerant=17;TOM=0;Tomcat=8,21,4;too=3,2,4,6,9,11,34,0;took=11;toolbar=8;Toolkit=17;Toolset=17;top=9,36,8,0,2,21;Topic=2,27,0;toplink=h8,36,r17;toRadians=7;tort=10;toString=43,2,4,0;total=11,23,8,7,9,2,0;toType=5;toward=17;tpc=11;tptp=9;trac=9;trace=h2,11,r43,9,4,13,6,8,27,58,0,1,49,20,21,17,36;TRACE_CONNECTION_NOT_CLOSED=h6;TRACE_FILE_ERROR_2=h6;TRACE_IO=h13;TRACE_LEVEL=h0;TRACE_LEVEL_FILE=2,11,0,36;TRACE_LEVEL_SYSTEM_OUT=2,0;TRACE_MAX_FILE_SIZE=h0,r2;traceError=27;traceFile=11,2,58;traceIO=13;tracing=2,17;tracking=20;trademark=10;trailing=7,22;TRANSACTION_=5;TRANSACTION_ID=h7;transaction_isolation=8;TRANSACTION_NOT_FOUND_1=h6;TRANSACTION_READ_COMMITTED=16,5;TRANSACTION_READ_UNCOMMITTED=16;TRANSACTION_SERIALIZABLE=16;transactional=9,0;transactionally=9,8;transactionName=0,1;transfer=10,17,4;transferred=2,1;Transform=9,17;transformation=9;translate=h21,r59,16,20;translate_a=59;translated=4,20,9,2,6,16,34;TranslateElement=59;Translating=h20,r21;translation=4,9,20;transmission=1;transmitted=1,2;transparent=17;Transport=1;TransportServer=9;tray=8,52;treat=9;treatment=17;Trede=34;tree=9,2,8,39,11;trial=10;trick=2;tried=10;tries=1,6,11,2,27,13;TRIG_INS=0;trigger=t37,h0,2,r4,6,31,9,19,26,1,7,36,34,65,64,13;TRIGGER_A=6;TRIGGER_ALREADY_EXISTS_1=h6;TRIGGER_CATALOG=0;TRIGGER_NAME=0;TRIGGER_NOT_FOUND_1=h6;TRIGGER_SCHEMA=0;TRIGGER_TYPE=0;TRIGGER_XYZ=6;TriggerAdapter=t31,r4;triggered=31,37;triggeredClassName=0;triggerName=31,37,0,2;TriggerPassData=4;TriggerSample=2,6;Trim=h7,r13;trimmed=4;TRUNC=9;truncate=h7,0,r9,30,42,6,13;truncated=6,7,2,4,0,13;Trust=1;try=4,1,9,2,11,8,20,21;trying=h6,r4,1,11,2,8;Tune=17;Tuning=h11,r4;turns=20;Tutorial=t8,r45,70,59;twelve=10;twice=6,2,4,8,13,1;txt=9,20,8,4,13;TYPE_CAT=5;TYPE_FORWARD_ONLY=15,5,3;type_info=8,0;TYPE_NAME=5,0;TYPE_SCHEM=5;TYPE_SCROLL_INSENSITIVE=3;TYPE_SCROLL_SENSITIVE=5,3;typeName=18,12;typeNamePattern=5;typeNoNulls=5;typeNullable=5;typeSearchable=5;typically=17,2;typing=8;typos=1;TYPTYPMOD=4'; -ref['u']='UCASE=7;Ucchino=4;uDig=17;udts=8;UID=6;UID_INDEX_0=6;unavailability=10;unchanged=2;unclosed=13;uncommitted=1,9,7,4,16;uncompressed=55,1;undefined=6,0;under=10,20,17,2,8,23,21,1;underline=36;underlined=10;underlying=0,1,17;understand=1,17,10,11,49;undetected=1;undo=9,0,11,4,1;UNDO_BLOCK_SIZE=9;UNDO_LOG=h0,r11;undone=31,37;unencrypted=1,9;unenforceable=10;unexpected=2,4,6,20;Unfortunately=11,4,1,8;unicode=7,34,22,1;uninitialized=4;uninstall=h1;uninterruptible=1;union=0,9,5,4,2,6,1;unique=h1,r0,5,6,2,9,4,7,11,3,22;UNIQUE_INDEX_NAME=6,0;UNIQUE_NAME=0;uniqueness=11;unit=7,11,9,4;United=h10;unitPrice=23;UNITS_IN_STOCK=23;unitsInStock=23;unitString=7;Universal=17;Universally=h1,r22;unknown=h2,r5,6,9,7,0,1;UNKNOWN_DATA_TYPE_1=h6;UNKNOWN_MODE_1=h6;unless=9,2,8,10,0,1;unlike=4,23,0,22,8;unlimited=22;unloading=21;unmodified=10;unnamed=16,36,6;unnecessary=20;unofficial=4;unquoted=5,0,7,13;unreleased=h4;unsafe=2;unsigned=5;UNSIGNED_ATTRIBUTE=5;unstable=4;unsuccessful=1,13;unsupported=12,6,3;UNSUPPORTED_CIPHER=h6;UNSUPPORTED_COMPRESSION_ALGORITHM_1=h6;UNSUPPORTED_COMPRESSION_OPTIONS_1=h6;UNSUPPORTED_JAVA_VERSION=h6;UNSUPPORTED_LOCK_METHOD_1=h6;UNSUPPORTED_OUTER_JOIN_CONDITION_1=h6;UNSUPPORTED_SETTING_1=h6;until=2,0,1,25,16,11,27,33,4,8,13;unused=5,57,33;unzip=51;updatable=3,6,9,2,4,8;UPDATE_RULE=5,0;updateArray=3;updateAsciiStream=3;updateBigDecimal=3;updateBinaryStream=3;updateBlob=3;updateBoolean=3;updateByte=3;updateCharacterStream=3;updateClob=3;updated=5,3,8,7,2,4,0;updateDate=3;updateDouble=3;updateFloat=3;updateInt=3;updateLong=3;updateNull=3;updateObject=3;updateRef=3;updateRow=3,6;updatesAreDetected=5;updateShort=3;updateString=3;updateTime=3;updateTimestamp=3;updateX=3;updating=h11,r4,5,3,65,9,64,6,13;upgrade=h8;Upgrading=11;upload=9,20;uploadBuild=20;uploaded=20;upon=10;upper=h7,r2,39;UPPER_NAME=2;uppercase=5,0,7,35,25,8,13;UPS=1;urgently=20;URL_FORMAT_ERROR_2=h6;urlSource=53,1;urlString=7,0;urlTarget=53,1;USA=34,17;usable=17;usage=h11,1,r6,9,4;USD=17;useful=2,27,8;USER_ALREADY_EXISTS_1=h6;USER_DATA_TYPE_ALREADY_EXISTS_1=h6;USER_DATA_TYPE_NOT_FOUND_1=h6;USER_HOME=h13;USER_NAME=0;USER_NOT_FOUND_1=h6;USER_OR_ROLE_NOT_FOUND_1=h6;username=0,8,2,21;userPassword=6;userpwd=2;userString=7,0;usesLocalFilePerTable=5;usesLocalFiles=5;usual=1;usually=2,0,8,1,13,32,11,21,9,26,28,4,38,19;UTE=9;UTF=7,4,44,38,0,13;UTF8=7;UTF8TOSTRING=h7;util=2,9,11,23,22,4;utility=17;utilization=10;utilize=17,10;UUID=h1,22,r4,7;uuidType=0;UUIs=1'; -ref['v']='vacuum=9;val=4,18;valid=16,3,6,0,10,1;validation=9,4;validity=10;validly=10;valuable=34;value1=9;value2=9;VALUE_TOO_LARGE_FOR_PRECISION_1=h6;VALUE_TOO_LONG_2=h6;ValueExpression=9;valueOf=23,2,4,1;valueString=7,9;Van=4;var=9,4,59;VAR_POP=h7;VAR_SAMP=h7;VARBINARY=22;varchar=h22,r6,8,2,11,26,19,0,9,7,40,5,15,4,1;VARCHAR2=22;VARCHAR_CASESENSITIVE=22;VARCHAR_IGNORECASE=h22;varcharIgnorecaseType=0;varcharType=0;variable=h8,r2,20,9,7,11,6,0;variableName=7,0;variance=7;variant=1;various=4,17,11,2,8,1;vary=11;Vasilakis=34;vector=1;vendor=33,4;venue=10;verify=20;versa=2,6;version_columns=8;versus=20;vertical=36;very=4,9,11,1,34,22,17,2,41,21,7,8,13;VERYSMALLINT=6;veto=2;via=2,10,17;vice=2,6;view=h0,r6,9,4,17,2,1,11,5;VIEW_ALREADY_EXISTS_1=h6;view_bug=13;VIEW_DEFINITION=0;VIEW_IS_INVALID_2=h6;VIEW_NOT_FOUND_1=h6;viewed=1;viewName=0;Vince=4;violate=6;violated=4,6,0;virtual=2,4,0,6,11,13,1;virtuoso=9;virus=h11;viruses=11;visible=5,3,8,1;vision=17;visit=10;visitor=4;Vista=51;Visual=17;Vladykin=4;VMs=9;Volunteer=17;VPDA=17;vulnerability=1'; -ref['w']='W3C=17;w3schools=9;waCustomers=23;wait=1,33,2,11,27,9,16,41,13;Waiting=13;waives=10;wakes=1;warConsole=8;warning=14,3,16,45,8,0,1;warranties=10;warranty=h10;wasNull=15,3,18;watchdog=1,2;Water=17;watermark=1;Watson=34;Wayback=10;weak=2,4,1;WEAK_=4;web=h8,r17,27,52,9,20,2,1,10,21;WEB_MAX_VALUE_LENGTH=h13;webAllowOthers=27,4,8,1;WebappClassLoader=21;webclient=9;webDaemon=27,4;weblica=17;Weblog=17;webMaxValueLength=4,13;webPort=27,4,8;WebServlet=8;webSSL=27,4;week=h7,r21;weight=17,36,9;welcome=9,70,11,20;were=4,31,9,37,8;Werkzeugkasten=17;whenever=1,2,9,7,11,0;wherever=8,17,11;whether=h5,r10,14,15,3,24,2,26,35,37,31,27,19;while=6,2,8,4,1,48,11,0,5,21,25,9,16,10,7;whitespace=0;whole=22,9,11,0,1;whom=10;why=h11,34,21,23,r2;wide=10,2;widely=10;width=9;wiki=9,17;wikipedia=1,9,17,6;Wildam=34;wildcard=0,9;William=34;window=h1,r8,45,4,51,13,21,52,11,63,27,6,20,36,2,44;winexe=1;wireless=4;wiscorp=9;withdraw=10;withdrawn=10;within=h8,r2,4,10,0,9,37,1,31,7,6,14,33,41,21,13;without=10,9,0,2,4,1,8,52,44,7,27,23,21,13;wizard=11,8;word=h35,1,r19,9,34,20;workaround=4,21,8,1;Workbench=17;workflow=17;workgroup=17;working=4,21,1,7,2,36;world=h11,r7,6,8,4,10,1,9,2,15,0;worldwide=10;worry=2;wrapper=1,9,11,4;write=25,1,9,2,11,4,30,24,17,16,23,7,12,8,13,49;write_back_cache_experiments=9;WRITE_DELAY=h0,r11,1;writecache_enabled=9;WriteLine=1;writer=25,28,42,43,1,17,9,8;writeRow=25,4;writing=h8,r25,4,9,10,1,7,6,34,30,0,13;written=1,2,25,17,0,7,4,30,23,51,27,33,20,21,13;wrong=h1,r4,6,13,21,9;WRONG_PASSWORD_FORMAT=h6;WRONG_USER_OR_PASSWORD=h6;WRONG_XID_FORMAT_1=h6;wrote=34,20;www=9,34,17,7,11,10,1'; -ref['x']='X11=8;x4juli=2;XA_OK=32;XAConnection=28,9,6;XAException=32;xAllowOthers=27;xares=32;XAResource=32;xcdsql=9;xid=32;XID_TEST=0;xml=7,8,23,9,2,36,20,22,1;XMLATTR=h7;XMLCDATA=h7;XMLCOMMENT=h7;XMLNODE=h7;XMLSTARTDOC=h7;XMLTEXT=h7;Xmx128m=6;XOR=1,7;Xrunhprof=11,38;XTEA=1,2,0,7,46,6;XYZ=6'; -ref['y']='yajsw=9;year=h7,r4,0,22,10;Yes=2,5,21;yet=27,4,3,21,1,2,23,9,45,0,7,33,8,46,13;yield=1;York=10;yourself=11,20,21;yyyy=7,0,22,6'; -ref['z']='Zen=17;zero=h7,1,r2,6,9,32;zip=h2,r8,0,4,63,1,9,7,36,54,48,6;zipFileName=48,54,2,1;zone=3,12,8'; -// totalRelations: 12468 -ignored=';first;function;option;byte;contain;string;the;you;closed;java;information;say;use;must;could;who;now;parameter;column;using;would;execute;over;print;source;end;list;should;open;long;about;data;good;how;current;has;return;supported;same;transaction;test;method;update;more;its;work;them;this;name;example;for;from;error;version;server;required;delete;available;number;read;not;create;resultset;code;out;well;just;where;feature;take;some;static;created;void;jdbc;default;sensitive;database;after;object;double;url;org;want;even;these;following;setting;which;but;system;null;need;also;index;his;table;possible;time;result;connection;any;sqlexception;line;search;row;case;such;start;come;text;false;before;called;support;main;other;two;represent;will;what;new;are;tool;throw;last;check;way;password;look;give;than;sql;does;close;back;file;defined;used;query;int;change;true;only;engine;with;was;know;statement;all;calling;don;your;make;their;that;one;directory;when;then;key;call;array;see;into;command;maximum;exist;like;date;may;always;operation;boolean;interface;running;user;help;specified;conn;add;type;run;application;have;exception;think;most;each;get;they;value;because;and;can;class;driver;schema;set;arg;select;there;'; -} diff --git a/tools/h2/docs/html/installation.html b/tools/h2/docs/html/installation.html deleted file mode 100755 index fc1eb17..0000000 --- a/tools/h2/docs/html/installation.html +++ /dev/null @@ -1,202 +0,0 @@ - - - - -Installation - - - - - - - - - - - - - - - diff --git a/tools/h2/docs/html/jaqu.html b/tools/h2/docs/html/jaqu.html deleted file mode 100755 index 7f3bb40..0000000 --- a/tools/h2/docs/html/jaqu.html +++ /dev/null @@ -1,378 +0,0 @@ - - - - -JaQu - - - - - - - - - - - - - - - diff --git a/tools/h2/docs/html/license.html b/tools/h2/docs/html/license.html deleted file mode 100755 index b8de01f..0000000 --- a/tools/h2/docs/html/license.html +++ /dev/null @@ -1,342 +0,0 @@ - - - - -License - - - - - - - - - - - - - - - diff --git a/tools/h2/docs/html/links.html b/tools/h2/docs/html/links.html deleted file mode 100755 index 8ded09d..0000000 --- a/tools/h2/docs/html/links.html +++ /dev/null @@ -1,602 +0,0 @@ - - - - -H2 In Use and Links - - - - - - - - - - - - - - - diff --git a/tools/h2/docs/html/main.html b/tools/h2/docs/html/main.html deleted file mode 100755 index 15765d8..0000000 --- a/tools/h2/docs/html/main.html +++ /dev/null @@ -1,138 +0,0 @@ - - - - -H2 Database Engine - - - - - - - - - - - - - - - diff --git a/tools/h2/docs/html/mainWeb.html b/tools/h2/docs/html/mainWeb.html deleted file mode 100755 index 6d72812..0000000 --- a/tools/h2/docs/html/mainWeb.html +++ /dev/null @@ -1,187 +0,0 @@ - - - - -H2 Database Engine - - - - - - -
- - -

H2 Database Engine

-

- Welcome to H2, the Java SQL database. The main features of H2 are:

-
    -
  • Very fast, open source, JDBC API
  • Embedded and server modes; in-memory databases
  • Browser based Console application
  • Small footprint: around 1 MB jar file size
- - - - - - - - - - - - - - -
- - - - - -
-

Download

- Version 1.2.137 (2010-06-06):
- download - - Windows Installer (4 MB) -
- download - - All Platforms (zip, 5 MB) -
- All Downloads -
-
    - - -
-

Support

-

- English Google Group
- Japanese Google Group

- For non-technical issues, use:
- -

-
-
-

Features

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
H2DerbyHSQLDBMySQLPostgreSQL
Pure JavaYesYesYesNoNo
Memory ModeYesYesYesNoNo
Transaction IsolationYesYesNoYesYes
Cost Based OptimizerYesYesNoYesYes
Encrypted DatabaseYesYesNoNoNo
ODBC DriverYesNoNoYesYes
Fulltext SearchYesNoNoYesYes
Multi Version ConcurrencyYesNoNoYesYes
Footprint (jar/dll size)~1 MB~2 MB~600 KB~4 MB~6 MB
-

- See also the detailed comparison.

-
- - -
-

News

-

- Newsfeeds: - Full text (Atom) - or Header only (RSS).

- Email Newsletter: Subscribe to H2 Database News (Google account required) to get informed about new releases. Your email address is only used in this context.

-
-
 
- - -
-

Contribute

-

- You can contribute to the development of H2 by sending feedback and bug reports, or translate the H2 Console application (for details, start the H2 Console and select Options / Translate). To donate money, click on the PayPal button below. You will be listed as a supporter:

-
-

- - - - -

-
-
-
- -
diff --git a/tools/h2/docs/html/navigation.js b/tools/h2/docs/html/navigation.js deleted file mode 100755 index 9e8842e..0000000 --- a/tools/h2/docs/html/navigation.js +++ /dev/null @@ -1,166 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ - -function loadFrameset() { - var a = location.search.split('&'); - var page = decodeURIComponent(a[0].substr(1)); - var frame = a[1]; - if(page && frame){ - var s = "top." + frame + ".location.replace('" + page + "')"; - eval(s); - } - return; -} - -function frameMe(frame) { - if(location.host.indexOf('h2database') < 0) { - // allow translation - return; - } - var frameset = "frame.html"; // name of the frameset page - if(frame == null) { - frame = 'main'; - } - page = new String(self.document.location); - var pos = page.lastIndexOf("/") + 1; - var file = page.substr(pos); - file = encodeURIComponent(file); - if(window.name != frame) { - var s = frameset + "?" + file + "&" + frame; - top.location.replace(s); - } else { - highlightFrame(); - } - return; -} - -function addHighlight(page, word, count) { - if(count > 0) { - if(top.main.document.location.href.indexOf(page) > 0 && top.main.document.body && top.main.document.body.innerHTML) { - highlight(); - } else { - window.setTimeout('addHighlight("'+page+'","'+word+'",'+(count-1)+')', 10); - } - } -} - -function highlightFrame() { - var url = new String(top.main.location.href); - if(url.indexOf('?highlight=') < 0) { - return; - } else { - var page = url.split('?highlight='); - var word = decodeURIComponent(page[1]); - top.main.document.body.innerHTML = highlightSearchTerms(top.main.document.body, word); - top.main.location = '#firstFound'; - // window.setTimeout('goFirstFound()', 1); - } -} - -function highlight() { - var url = new String(document.location.href); - if(url.indexOf('?highlight=') < 0) { - return; - } else { - var page = url.split('highlight=')[1].split('&')[0]; - var search = decodeURIComponent(url.split('search=')[1].split('#')[0]); - var word = decodeURIComponent(page); - document.body.innerHTML = highlightSearchTerms(document.body, word); - document.location = '#firstFound'; - document.getElementById('search').value = search; - listWords(search, ''); - } -} - -function goFirstFound() { - top.main.location = '#firstFound'; -/* - var page = new String(parent.main.location); - alert('first: ' + page); - page = page.split('#')[0]; - paramSplit = page.split('?'); - page = paramSplit[0]; - page += '#firstFound'; - if(paramSplit.length > 0) { - page += '?' + paramSplit[1]; - } - top.main.location = page; -*/ -} - -function highlightSearchTerms(body, searchText) { - matchColor = "ffff00,00ffff,00ff00,ff8080,ff0080".split(','); - highlightEndTag = ""; - searchArray = searchText.split(","); - if (!body || typeof(body.innerHTML) == "undefined") { - return false; - } - var bodyText = body.innerHTML; - for (var i = 0; i < searchArray.length; i++) { - var color = matchColor[i % matchColor.length]; - highlightStartTag = ""; - bodyText = doHighlight(bodyText, searchArray[i], highlightStartTag, highlightEndTag); - } - return bodyText; -} - -function doHighlight(bodyText, searchTerm, highlightStartTag, highlightEndTag) { - if(searchTerm == undefined || searchTerm=="") { - return bodyText; - } - var newText = ""; - var i = -1; - var lcSearchTerm = searchTerm.toLowerCase(); - var lcBodyText = bodyText.toLowerCase(); - while (bodyText.length > 0) { - i = lcBodyText.indexOf(lcSearchTerm, i+1); - if (i < 0) { - newText += bodyText; - bodyText = ""; - } else { - // skip anything inside an HTML tag - if (bodyText.lastIndexOf(">", i) >= bodyText.lastIndexOf("<", i)) { - // skip anything inside a - - - - - - - - - - - diff --git a/tools/h2/docs/html/quickstart.html b/tools/h2/docs/html/quickstart.html deleted file mode 100755 index 50b5639..0000000 --- a/tools/h2/docs/html/quickstart.html +++ /dev/null @@ -1,183 +0,0 @@ - - - - -Quickstart - - - - - - - - - - - - - - - diff --git a/tools/h2/docs/html/roadmap.html b/tools/h2/docs/html/roadmap.html deleted file mode 100755 index 419a87e..0000000 --- a/tools/h2/docs/html/roadmap.html +++ /dev/null @@ -1,136 +0,0 @@ - - - - -Roadmap - - - - - - - - - - - - - - - diff --git a/tools/h2/docs/html/search.js b/tools/h2/docs/html/search.js deleted file mode 100755 index c3b6845..0000000 --- a/tools/h2/docs/html/search.js +++ /dev/null @@ -1,265 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ - -var pages = new Array(); -var ref = new Array(); -var ignored = ''; -var firstLink = null; -var firstLinkWord = null; - -String.prototype.endsWith = function(suffix) { - var startPos = this.length - suffix.length; - if (startPos < 0) { - return false; - } - return (this.lastIndexOf(suffix, startPos) == startPos); -}; - -function listWords(value, open) { - value = replaceOtherChars(value); - value = trim(value); - if (pages.length == 0) { - load(); - } - var table = document.getElementById('result'); - while (table.rows.length > 0) { - table.deleteRow(0); - } - firstLink = null; - var clear = document.getElementById('clear'); - if (value.length == 0) { - clear.style.display = 'none'; - return true; - } - clear.style.display = ''; - var keywords = value.split(' '); - if (keywords.length > 1) { - listAnd(keywords); - return true; - } - if (value.length < 3) { - max = 100; - } else { - max = 1000; - } - value = value.toLowerCase(); - var r = ref[value.substring(0, 1)]; - if (r == undefined) { - return true; - } - var x = 0; - var words = r.split(';'); - var count = 0; - for ( var i = 0; i < words.length; i++) { - var wordRef = words[i]; - if (wordRef.toLowerCase().indexOf(value) == 0) { - count++; - } - } - for ( var i = 0; i < words.length && (x <= max); i++) { - var wordRef = words[i]; - if (wordRef.toLowerCase().indexOf(value) == 0) { - word = wordRef.split("=")[0]; - var tr = table.insertRow(x++); - var td = document.createElement('td'); - var tdClass = document.createAttribute('class'); - tdClass.nodeValue = 'searchKeyword'; - td.setAttributeNode(tdClass); - - var ah = document.createElement('a'); - var href = document.createAttribute('href'); - href.nodeValue = 'javascript:set("' + word + '");'; - var link = document.createTextNode(word); - ah.setAttributeNode(href); - ah.appendChild(link); - td.appendChild(ah); - tr.appendChild(td); - piList = wordRef.split("=")[1].split(","); - if (count < 20 || open == word) { - x = addReferences(x, piList, word); - } - } - } - if (x == 0) { - if (ignored.indexOf(';' + value + ';') >= 0) { - noResults(table, 'Common word (not indexed)'); - } else { - noResults(table, 'No results found!'); - } - } - return true; -} - -function set(v) { - if (pages.length == 0) { - load(); - } - var search = document.getElementById('search').value; - listWords(search, v); - document.getElementById('search').focus(); - window.scrollBy(-20, 0); -} - -function goFirst() { - var table = document.getElementById('result'); - if (firstLink != null) { - go(firstLink, firstLinkWord); - } - return false; -} - -function go(pageId, word) { - var page = pages[pageId]; - var load = '../' + page.file + '?highlight=' + encodeURIComponent(word); - if (top.main) { - if (!top.main.location.href.endsWith(page.file)) { - top.main.location = load; - } - } else { - if (!document.location.href.endsWith(page.file)) { - var search = document.getElementById('search').value; - document.location = load + '&search=' + encodeURIComponent(search); - } - } -} - -function listAnd(keywords) { - var count = new Array(); - var weight = new Array(); - for ( var i = 0; i < pages.length; i++) { - count[i] = 0; - weight[i] = 0; - } - for ( var i = 0; i < keywords.length; i++) { - var value = keywords[i].toLowerCase(); - var r = ref[value.substring(0, 1)]; - if (r == undefined) { - return true; - } - var words = r.split(';'); - for ( var j = 0; j < words.length; j++) { - var wordRef = words[j]; - if (wordRef.toLowerCase().indexOf(value) == 0) { - piList = wordRef.split("=")[1].split(","); - var w = 1; - for ( var k = 0; k < piList.length; k++) { - var pi = piList[k]; - if (pi.charAt(0) == 't') { - pi = pi.substring(1); - w = 10000; - } else if (pi.charAt(0) == 'h') { - pi = pi.substring(1); - w = 100; - } else if (pi.charAt(0) == 'r') { - pi = pi.substring(1); - w = 1; - } - if (count[pi] >= i) { - if (count[pi] == i) { - count[pi]++; - } - weight[pi] += w; - } - } - } - } - } - var x = 0; - var table = document.getElementById('result'); - var piList = new Array(); - var piWeight = new Array(); - for ( var i = 0; i < pages.length; i++) { - if (count[i] >= keywords.length) { - piList[x] = '' + i; - piWeight[x] = weight[i]; - x++; - } - } - // sort - for ( var i = 1, j; i < x; i++) { - var tw = piWeight[i]; - var ti = piList[i]; - for (j = i - 1; j >= 0 && (piWeight[j] < tw); j--) { - piWeight[j + 1] = piWeight[j]; - piList[j + 1] = piList[j]; - } - piWeight[j + 1] = tw; - piList[j + 1] = ti; - } - addReferences(0, piList, keywords); - if (piList.length == 0) { - noResults(table, 'No results found'); - } -} - -function addReferences(x, piList, word) { - var table = document.getElementById('result'); - for ( var j = 0; j < piList.length; j++) { - var pi = piList[j]; - if (pi.charAt(0) == 't') { - pi = pi.substring(1); - } else if (pi.charAt(0) == 'h') { - pi = pi.substring(1); - } else if (pi.charAt(0) == 'r') { - pi = pi.substring(1); - } - var tr = table.insertRow(x++); - var td = document.createElement('td'); - var tdClass = document.createAttribute('class'); - tdClass.nodeValue = 'searchLink'; - td.setAttributeNode(tdClass); - var ah = document.createElement('a'); - var href = document.createAttribute('href'); - var thisLink = 'javascript:go(' + pi + ', "' + word + '")'; - if (firstLink == null) { - firstLink = pi; - firstLinkWord = word; - } - href.nodeValue = thisLink; - ah.setAttributeNode(href); - var page = pages[pi]; - var link = document.createTextNode(page.title); - ah.appendChild(link); - td.appendChild(ah); - tr.appendChild(td); - } - return x; -} - -function trim(s) { - while (s.charAt(0) == ' ' && s.length > 0) { - s = s.substring(1); - } - while (s.charAt(s.length - 1) == ' ' && s.length > 0) { - s = s.substring(0, s.length - 1); - } - return s; -} - -function replaceOtherChars(s) { - var x = ""; - for ( var i = 0; i < s.length; i++) { - var c = s.charAt(i); - if ("\t\r\n\"'.,:;!&/\\?%@`[]{}()+-=<>|*^~#$".indexOf(c) >= 0) { - c = " "; - } - x += c; - } - return x; -} - -function noResults(table, message) { - var tr = table.insertRow(0); - var td = document.createElement('td'); - var tdClass = document.createAttribute('class'); - tdClass.nodeValue = 'searchKeyword'; - td.setAttributeNode(tdClass); - var text = document.createTextNode(message); - td.appendChild(text); - tr.appendChild(td); -} - diff --git a/tools/h2/docs/html/source.html b/tools/h2/docs/html/source.html deleted file mode 100755 index 3912a1c..0000000 --- a/tools/h2/docs/html/source.html +++ /dev/null @@ -1,69 +0,0 @@ - - -Source Code Viewer - - -
-
-    
-        
-        
-    
-
- - - -
- - - -
diff --git a/tools/h2/docs/html/sourceError.html b/tools/h2/docs/html/sourceError.html deleted file mode 100755 index 5ce78e3..0000000 --- a/tools/h2/docs/html/sourceError.html +++ /dev/null @@ -1,237 +0,0 @@ - - - - -Error Analyzer - - - - - - - - -

Error Analyzer

-Home
-

- Input  Details  Source Code

-
-
-

Paste the error message and stack trace below and click on 'Details' or 'Source Code':

- -
-
-

Error Code:

-

Product Version:

-

Message:

-

-

More Information:

- -
-
- - -
-

Stack Trace:

- -
-

Source File:
- Raw file (fast; only Firefox)

- -
-
- - - diff --git a/tools/h2/docs/html/stylesheet.css b/tools/h2/docs/html/stylesheet.css deleted file mode 100755 index efdd0ce..0000000 --- a/tools/h2/docs/html/stylesheet.css +++ /dev/null @@ -1,335 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ - -td, input, select, textarea, body, code, pre, td, th { - font: 9pt/130% Tahoma, Arial, Helvetica, sans-serif; - font-weight: normal; -} - -h1, h2, h3, h4, h5 { - font: 9pt Tahoma, Arial, Helvetica, sans-serif; - font-weight: bold; -} - -td, input, select, textarea, body, code, pre { - font-size: 9pt; -} - -pre { - background-color: #ece9d8; - border: 1px solid rgb(172, 168, 153); - padding: 4px; -} - -code { - background-color: #ece9d8; - padding: 0px 2px; -} - -img { - border: 0px; -} - -body { - max-width: 800px; - clear: both; - width: 800px; - margin: 0 auto; -} - -h1 { - background-color: #0000bb; - padding: 2px 4px 2px 4px; - color: #fff; - font-size: 15pt; - line-height: normal; -} - -h2 { - font-size: 13pt; - margin-top: 1.5em; -} - -h3 { - font-size: 11pt; - margin-top: 1.5em; -} - -h4 { - font-size: 9pt; - margin-top: 1.5em; -} - -hr { - color: #CCC; - background-color: #CCC; - height: 1px; - border: 0px solid blue; -} - -table { - background-color: #ffffff; - border-collapse: collapse; - border: 1px solid #aca899; -} - -th { - text-align: left; - background-color: #ece9d8; - border: 1px solid #aca899; - padding: 2px; -} - -td { - background-color: #ffffff; - text-align: left; - vertical-align: top; - border: 1px solid #aca899; - padding: 2px; -} - -form { -} - -ul, ol { - list-style-position: outside; - padding-left: 20px; -} - -li { - margin-top: 2px; -} - -a { - text-decoration: none; - color: #0000ff; -} - -a:hover { - text-decoration: underline; -} - -em.u { - text-decoration: underline; - font-style: normal; -} - -.menu { - margin: 10px 10px 10px 10px; -} - -table.search { - width: 100%; - border: 0px; -} - -tr.search { - border: 0px; -} - -td.search { - border: 0px; - padding: 2px 0px 2px 10px; -} - -td.searchKeyword { - border: 0px; - padding: 0px 0px 0px 2px; -} - -td.searchKeyword a { - text-decoration: none; - color: #000000; -} - -td.searchKeyword a:hover { - text-decoration: underline; -} - -td.searchLink { - border: 0px; - padding: 0px 0px 0px 32px; - text-indent: -16px; -} - -td.searchLink a { - text-decoration: none; - color: #0000ff; -} - -td.searchLink a:hover { - text-decoration: underline; -} - -table.nav { - border: 0px; -} - -tr.nav { - border: 0px; -} - -td.nav { - border: 0px; -} - -table.content { - width: 100%; - height: 100%; - border: 0px; -} - -tr.content { - border:0px; -} - -td.content { - border:0px; -} - -.contentDiv { - margin:10px; -} - -.content { - margin: 10px 10px 10px 0px; -} - -.screenshot { - border: 1px outset #800; - padding: 10px; - margin: 10px 0px; -} - -.compareFeature { -} - -.compareY { - color: #050; -} - -.compareN { - color: #800; -} - -table.index { - width: 100%; - border: 0px; - padding: 0px; - margin: 0px; - border: 0px none; - border-collapse: collapse; -} - -/* width: 570px; - width: 190px; - */ - -td.index { - width: 33%; - border: 0px; - padding: 0px; - margin: 0px; - border: 0px none; - border-collapse: collapse; - vertical-align: top; -} - -.railroad { - border: 0px; - padding: 0px; - margin: 0px; - border-collapse: collapse; - vertical-align: top; -} - -.c { - padding: 1px 3px; - margin: 0px 0px; - border: 2px solid; - -moz-border-radius: 0.4em; - border-radius: 0.4em; - background-color: #fff; -} - -.ts { - border: 0px; - padding: 0px; - margin: 0px; - border-collapse: collapse; - vertical-align: top; - height: 24px; - background-image: url(images/div-ts.png); - width: 16px; -} - -.ls { - border: 0px; - padding: 0px; - margin: 0px; - border-collapse: collapse; - vertical-align: top; - height: 24px; - background-image: url(images/div-ls.png); - width: 16px; -} - -.ks { - border: 0px; - padding: 0px; - margin: 0px; - border-collapse: collapse; - vertical-align: top; - height: 24px; - background-image: url(images/div-ks.png); - width: 16px; -} - -.te { - border: 0px; - padding: 0px; - margin: 0px; - border-collapse: collapse; - vertical-align: top; - height: 24px; - background-image: url(images/div-te.png); - width: 16px; -} - -.le { - border: 0px; - padding: 0px; - margin: 0px; - border-collapse: collapse; - vertical-align: top; - height: 24px; - background-image: url(images/div-le.png); - width: 16px; -} - -.ke { - border: 0px; - padding: 0px; - margin: 0px; - border-collapse: collapse; - vertical-align: top; - height: 24px; - background-image: url(images/div-ke.png); - width: 16px; -} - -.d { - border: 0px; - padding: 0px; - margin: 0px; - border-collapse: collapse; - vertical-align: top; - height: 24px; - background-image: url(images/div-d.png); - background-repeat: repeat-x; - min-width: 16px; -} diff --git a/tools/h2/docs/html/stylesheetPdf.css b/tools/h2/docs/html/stylesheetPdf.css deleted file mode 100755 index 48d4701..0000000 --- a/tools/h2/docs/html/stylesheetPdf.css +++ /dev/null @@ -1,155 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ - -td, input, select, textarea, body, code, pre, td, th { - font: 9pt Tahoma, Arial, Helvetica, sans-serif; - font-weight: normal; -} - -h1, h2, h3, h4, h5 { - font: 9pt Arial, Helvetica, sans-serif; - font-weight: bold; -} - -td, input, select, textarea, body, code, pre { - font-size: 9pt; -} - -pre { - background-color: #ece9d8; - border: 1px solid rgb(172, 168, 153); - padding: 4px; -} - -img { - border: 0px; -} - -body { - margin: 0px; -} - -h1 { - background-color: #0000bb; - padding: 2px 4px 2px 4px; - color: #fff; - font-size: 15pt; - line-height: normal; -} - -h2 { - font-size: 13pt; - margin-top: 1.5em; -} - -h3 { - font-size: 11pt; - margin-top: 1.5em; -} - -h4 { - font-size: 9pt; - margin-top: 1.5em; -} - -hr { - color: #CCC; - background-color: #CCC; - height: 1px; - border: 0px solid blue; -} - -table { - background-color: #ffffff; - border-collapse: collapse; - border: 1px solid #aca899; -} - -th { - font-size: 9pt; - font-weight: normal; - text-align: left; - background-color: #ece9d8; - border: 1px solid #aca899; - padding: 2px; -} - -td { - background-color: #ffffff; - font-size: 9pt; - text-align: left; - vertical-align: top; - border: 1px solid #aca899; - padding: 2px; - margin: 0px; -} - -form { -} - -ul, ol { - list-style-position: outside; - padding-left: 20px; -} - -li { - margin-top: 2px; -} - -a { - text-decoration: none; - color: #0000ff; -} - -a:hover { - text-decoration: underline; -} - -em.u { - text-decoration: underline; - font-style: normal; -} - -.screenshot { - border: 1px outset #888; - padding: 10px; - margin: 10px 0px; -} - -.compareFeature { -} - -.compareY { - color: #050; -} - -.compareN { - color: #800; -} - -table.index { - width: 100%; - border: 0px; - padding: 0px; - margin: 0px; - border: 0px none; - border-collapse: collapse; -} - -/* width: 570px; - width: 190px; - */ - -td.index { - width: 33%; - border: 0px; - padding: 0px; - margin: 0px; - border: 0px none; - border-collapse: collapse; - vertical-align: top; -} diff --git a/tools/h2/docs/html/tutorial.html b/tools/h2/docs/html/tutorial.html deleted file mode 100755 index b5a8073..0000000 --- a/tools/h2/docs/html/tutorial.html +++ /dev/null @@ -1,856 +0,0 @@ - - - - -Tutorial - - - - - - - - - - - - - - - diff --git a/tools/h2/docs/index.html b/tools/h2/docs/index.html deleted file mode 100755 index a370af8..0000000 --- a/tools/h2/docs/index.html +++ /dev/null @@ -1,41 +0,0 @@ - - - - -H2 Database Engine - - - - - -

H2 Database Engine

-

-Welcome to H2, the free SQL database. The main feature of H2 are: -

- - -

No Javascript

-

-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. -Please enable Javascript, or go ahead without it: -

-H2 Database Engine -

- - diff --git a/tools/h2/docs/javadoc/animate.js b/tools/h2/docs/javadoc/animate.js deleted file mode 100755 index b704a60..0000000 --- a/tools/h2/docs/javadoc/animate.js +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ - -function on(id) { - return switchTag(id, 'titleOff', 'detailOn'); -} - -function off(id) { - return switchTag(id, '', 'detail'); -} - -function allDetails() { - for (i = 0;; i++) { - x = document.getElementById('_' + i); - if (x == null) { - break; - } - switchTag(i, 'titleOff', 'detailOn'); - } - return false; -} - -function switchTag(id, title, detail) { - if (document.getElementById('__' + id) != null) { - document.getElementById('__' + id).className = title; - document.getElementById('_' + id).className = detail; - } - return false; -} - -function openLink() { - page = new String(self.document.location); - var pos = page.lastIndexOf("#") + 1; - if (pos == 0) { - return; - } - var ref = page.substr(pos); - link = decodeURIComponent(ref); - el = document.getElementById(link); - if (el.nodeName.toLowerCase() == 'h4') { - // constant - return true; - } - el = el.parentNode.parentNode; - window.scrollTo(0, el.offsetTop); - on(el.id.substr(2)); - return false; -} \ No newline at end of file diff --git a/tools/h2/docs/javadoc/classes.html b/tools/h2/docs/javadoc/classes.html deleted file mode 100755 index d298c72..0000000 --- a/tools/h2/docs/javadoc/classes.html +++ /dev/null @@ -1,92 +0,0 @@ - - - - - - H2 Documentation - - - - - - -
-
- diff --git a/tools/h2/docs/javadoc/index.html b/tools/h2/docs/javadoc/index.html deleted file mode 100755 index d4a33bd..0000000 --- a/tools/h2/docs/javadoc/index.html +++ /dev/null @@ -1,24 +0,0 @@ - - - - - - H2 Documentation - - - - - - - -<body> - Sorry, Lynx is not supported -</body> - - - diff --git a/tools/h2/docs/javadoc/org/h2/api/AggregateFunction.html b/tools/h2/docs/javadoc/org/h2/api/AggregateFunction.html deleted file mode 100755 index 66bc97b..0000000 --- a/tools/h2/docs/javadoc/org/h2/api/AggregateFunction.html +++ /dev/null @@ -1,66 +0,0 @@ - - - -AggregateFunction - - - -
-

AggregateFunction

-A user-defined aggregate function needs to implement this interface. - The class must be public and must have a public non-argument constructor.

- - - - - - - - - - - - - -
Methods
void -add(Object value) -
This method is called once for each row.
-
void -add(Object value) throws SQLException -
This method is called once for each row. - If the aggregate function is called with multiple parameters, - those are passed as array.
-
Parameters:
-
value - the value(s) for this row
-
Object -getResult() -
This method returns the computed aggregate value.
-
Object -getResult() throws SQLException -
This method returns the computed aggregate value.
-
Returns:
-
the aggregated value
-
int -getType(int[] inputTypes) -
This method must return the SQL type of the method, given the SQL type of - the input data.
-
int -getType(int[] inputTypes) throws SQLException -
This method must return the SQL type of the method, given the SQL type of - the input data. The method should check here if the number of parameters - passed is correct, and if not it should throw an exception.
-
Parameters:
-
inputTypes - the SQL type of the parameters
-
Returns:
-
the SQL type of the result
-
void -init(Connection conn) -
This method is called when the aggregate function is used.
-
void -init(Connection conn) throws SQLException -
This method is called when the aggregate function is used. - A new object is created for each invocation.
-
Parameters:
-
conn - a connection to the database
-
-
diff --git a/tools/h2/docs/javadoc/org/h2/api/DatabaseEventListener.html b/tools/h2/docs/javadoc/org/h2/api/DatabaseEventListener.html deleted file mode 100755 index 48d897b..0000000 --- a/tools/h2/docs/javadoc/org/h2/api/DatabaseEventListener.html +++ /dev/null @@ -1,90 +0,0 @@ - - - -DatabaseEventListener - - - -
-

DatabaseEventListener

-A class that implements this interface can get notified about exceptions - and other events. A database event listener can be registered when - connecting to a database. Example database URL: - jdbc:h2:test;DATABASE_EVENT_LISTENER='com.acme.DbListener'

- - - - - - - - - - - - - - - - - - - -
Methods
void -closingDatabase() -
This method is called before the database is closed normally.
-
void -closingDatabase() -
This method is called before the database is closed normally. It is save - to connect to the database and execute statements at this point, however - the connection must be closed before the method returns.
-
void -diskSpaceIsLow() -
This method is called if the disk space is very low.
-
void -diskSpaceIsLow() -
This method is called if the disk space is very low. One strategy is to - inform the user and wait for it to clean up disk space. The database - should not be accessed from within this method (even to close it).
-
void -exceptionThrown(SQLException e, String sql) -
This method is called if an exception occurred.
-
void -exceptionThrown(SQLException e, String sql) -
This method is called if an exception occurred.
-
Parameters:
-
e - the exception
-
sql - the SQL statement
-
void -init(String url) -
This method is called just after creating the object.
-
void -init(String url) -
This method is called just after creating the object. - This is done when opening the database if the listener is specified - in the database URL, but may be later if the listener is set at - runtime with the SET SQL statement.
-
Parameters:
-
url - - the database URL
-
void -opened() -
This method is called after the database has been opened.
-
void -opened() -
This method is called after the database has been opened. - It is save to connect to the database and execute statements at this point.
-
void -setProgress(int state, String name, int x, int max) -
This method is called for long running events, such as recovering, - scanning a file or building an index.
-
void -setProgress(int state, String name, int x, int max) -
This method is called for long running events, such as recovering, - scanning a file or building an index.
-
Parameters:
-
state - the state
-
name - the object name
-
x - the current position
-
max - the highest value
-
-
diff --git a/tools/h2/docs/javadoc/org/h2/api/TableEngine.html b/tools/h2/docs/javadoc/org/h2/api/TableEngine.html deleted file mode 100755 index 49bfecb..0000000 --- a/tools/h2/docs/javadoc/org/h2/api/TableEngine.html +++ /dev/null @@ -1,27 +0,0 @@ - - - -TableEngine - - - -
-

TableEngine

-A class that implements this interface can create custom table - implementations.

- - - - -
Methods
TableBase -createTable(CreateTableData data) -
Create new table.
-
TableBase -createTable(CreateTableData data) -
Create new table.
-
Parameters:
-
data - the data to construct the table
-
Returns:
-
the created table
-
-
diff --git a/tools/h2/docs/javadoc/org/h2/api/Trigger.html b/tools/h2/docs/javadoc/org/h2/api/Trigger.html deleted file mode 100755 index 3c38ec8..0000000 --- a/tools/h2/docs/javadoc/org/h2/api/Trigger.html +++ /dev/null @@ -1,118 +0,0 @@ - - - -Trigger - - - -
-

Trigger

-A class that implements this interface can be used as a trigger.

- - - - - - - - - - - - - -
Methods
void -close() -
This method is called when the database is closed.
-
void -close() throws SQLException -
This method is called when the database is closed. - If the method throws an exception, it will be logged, but - closing the database will continue.
-
Throws:
-
SQLException
-
void -fire(Connection conn, Object[] oldRow, Object[] newRow) -
This method is called for each triggered action.
-
void -fire(Connection conn, Object[] oldRow, Object[] newRow) throws SQLException -
This method is called for each triggered action. The method is called - immediately when the operation occurred (before it is committed). A - transaction rollback will also rollback the operations that were done - within the trigger, if the operations occurred within the same database. - If the trigger changes state outside the database, a rollback trigger - should be used. -

- The row arrays contain all columns of the table, in the same order - as defined in the table. -

-
Parameters:
-
conn - a connection to the database
-
oldRow - the old row, or null if no old row is available (for - INSERT)
-
newRow - the new row, or null if no new row is available (for - DELETE)
-
Throws:
-
SQLException - if the operation must be undone
-
void -init(Connection conn, String schemaName, String triggerName, String tableName, boolean before, int type) -
This method is called by the database engine once when initializing the - trigger.
-
void -init(Connection conn, String schemaName, String triggerName, String tableName, boolean before, int type) throws SQLException -
This method is called by the database engine once when initializing the - trigger. It is called when the trigger is created, as well as when the - database is opened.
-
Parameters:
-
conn - a connection to the database
-
schemaName - the name of the schema
-
triggerName - the name of the trigger used in the CREATE TRIGGER - statement
-
tableName - the name of the table
-
before - whether the fire method is called before or after the - operation is performed
-
type - the operation type: INSERT, UPDATE, or DELETE
-
void -remove() -
This method is called when the trigger is dropped.
-
void -remove() throws SQLException -
This method is called when the trigger is dropped.
-
Throws:
-
SQLException
-
-
- - - - -
Fields
static int -DELETE = 4 -
static int -INSERT = 1 -
static int -SELECT = 8 -
static int -UPDATE = 2 -
-

INSERT - = 1 -

-
The trigger is called for INSERT statements.
-
-

UPDATE - = 2 -

-
The trigger is called for UPDATE statements.
-
-

DELETE - = 4 -

-
The trigger is called for DELETE statements.
-
-

SELECT - = 8 -

-
The trigger is called for SELECT statements.
-
-
diff --git a/tools/h2/docs/javadoc/org/h2/constant/ErrorCode.html b/tools/h2/docs/javadoc/org/h2/constant/ErrorCode.html deleted file mode 100755 index 9b245a4..0000000 --- a/tools/h2/docs/javadoc/org/h2/constant/ErrorCode.html +++ /dev/null @@ -1,2228 +0,0 @@ - - - -ErrorCode - - - -
-

ErrorCode

-This class defines the error codes used for SQL exceptions. - Error messages are formatted as follows: -
- { error message (possibly translated; may include quoted data) }
- { error message in English if different }
- { SQL statement if applicable }
- { [ error code - build number ] }
- Example: -
- Syntax error in SQL statement "SELECT * FORM[*] TEST ";
- SQL statement: select * form test [42000-125]
- The [*] marks the position of the syntax error - (FORM instead of FROM in this case). - The error code is 42000, and the build number is 125, - meaning version 1.2.125.

-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Fields
static int -ACCESS_DENIED_TO_CLASS_1 = 90134 -
static int -ADMIN_RIGHTS_REQUIRED = 90040 -
static int -AGGREGATE_NOT_FOUND_1 = 90132 -
static int -AMBIGUOUS_COLUMN_NAME_1 = 90059 -
static int -CANNOT_CHANGE_SETTING_WHEN_OPEN_1 = 90133 -
static int -CANNOT_DROP_2 = 90107 -
static int -CANNOT_DROP_CURRENT_USER = 90019 -
static int -CANNOT_DROP_LAST_COLUMN = 90084 -
static int -CANNOT_DROP_TABLE_1 = 90118 -
static int -CANNOT_MIX_INDEXED_AND_UNINDEXED_PARAMS = 90123 -
static int -CANNOT_TRUNCATE_1 = 90106 -
static int -CAN_ONLY_ASSIGN_TO_VARIABLE_1 = 90137 -
static int -CHECK_CONSTRAINT_VIOLATED_1 = 23000 -
static int -CLASS_NOT_FOUND_1 = 90086 -
static int -CLUSTER_ERROR_DATABASE_RUNS_ALONE = 90093 -
static int -CLUSTER_ERROR_DATABASE_RUNS_CLUSTERED_1 = 90094 -
static int -COLLATION_CHANGE_WITH_DATA_TABLE_1 = 90089 -
static int -COLUMN_CONTAINS_NULL_VALUES_1 = 90081 -
static int -COLUMN_COUNT_DOES_NOT_MATCH = 21002 -
static int -COLUMN_IS_PART_OF_INDEX_1 = 90075 -
static int -COLUMN_MAY_BE_REFERENCED_1 = 90083 -
static int -COLUMN_MUST_NOT_BE_NULLABLE_1 = 90023 -
static int -COLUMN_NOT_FOUND_1 = 42122 -
static int -COMMIT_ROLLBACK_NOT_ALLOWED = 90058 -
static int -COMPRESSION_ERROR = 90104 -
static int -CONCURRENT_UPDATE_1 = 90131 -
static int -CONNECTION_BROKEN_1 = 90067 -
static int -CONSTANT_ALREADY_EXISTS_1 = 90114 -
static int -CONSTANT_NOT_FOUND_1 = 90115 -
static int -CONSTRAINT_ALREADY_EXISTS_1 = 90045 -
static int -CONSTRAINT_NOT_FOUND_1 = 90057 -
static int -DATABASE_ALREADY_OPEN_1 = 90020 -
static int -DATABASE_CALLED_AT_SHUTDOWN = 90121 -
static int -DATABASE_IS_CLOSED = 90098 -
static int -DATABASE_IS_IN_EXCLUSIVE_MODE = 90135 -
static int -DATABASE_IS_NOT_PERSISTENT = 90126 -
static int -DATABASE_IS_READ_ONLY = 90097 -
static int -DATABASE_NOT_FOUND_1 = 90013 -
static int -DATA_CONVERSION_ERROR_1 = 90021 -
static int -DATE_CONSTANT_2 = 90009 -
static int -DEADLOCK_1 = 40001 -
static int -DESERIALIZATION_FAILED_1 = 90027 -
static int -DIVISION_BY_ZERO_1 = 22012 -
static int -DRIVER_VERSION_ERROR_2 = 90047 -
static int -DUPLICATE_COLUMN_NAME_1 = 42121 -
static int -DUPLICATE_KEY_1 = 23001 -
static int -DUPLICATE_PROPERTY_1 = 90066 -
static int -ERROR_ACCESSING_LINKED_TABLE_2 = 90111 -
static int -ERROR_CREATING_TRIGGER_OBJECT_3 = 90043 -
static int -ERROR_EXECUTING_TRIGGER_3 = 90044 -
static int -ERROR_OPENING_DATABASE_1 = 8000 -
static int -ERROR_SETTING_DATABASE_EVENT_LISTENER_2 = 90099 -
static int -EXCEPTION_IN_FUNCTION_1 = 90105 -
static int -EXCEPTION_OPENING_PORT_2 = 90061 -
static int -FEATURE_NOT_SUPPORTED_1 = 50100 -
static int -FILE_CORRUPTED_1 = 90030 -
static int -FILE_CREATION_FAILED_1 = 90062 -
static int -FILE_DELETE_FAILED_1 = 90025 -
static int -FILE_ENCRYPTION_ERROR_1 = 90049 -
static int -FILE_NOT_FOUND_1 = 90124 -
static int -FILE_RENAME_FAILED_2 = 90024 -
static int -FILE_VERSION_ERROR_1 = 90048 -
static int -FUNCTION_ALIAS_ALREADY_EXISTS_1 = 90076 -
static int -FUNCTION_ALIAS_NOT_FOUND_1 = 90077 -
static int -FUNCTION_MUST_RETURN_RESULT_SET_1 = 90000 -
static int -FUNCTION_NOT_FOUND_1 = 90022 -
static int -GENERAL_ERROR_1 = 50000 -
static int -HEX_STRING_ODD_1 = 90003 -
static int -HEX_STRING_WRONG_1 = 90004 -
static int -INDEX_ALREADY_EXISTS_1 = 42111 -
static int -INDEX_BELONGS_TO_CONSTRAINT_1 = 90085 -
static int -INDEX_NOT_FOUND_1 = 42112 -
static int -INVALID_CLASS_2 = 90125 -
static int -INVALID_DATABASE_NAME_1 = 90138 -
static int -INVALID_PARAMETER_COUNT_2 = 7001 -
static int -INVALID_USE_OF_AGGREGATE_FUNCTION_1 = 90054 -
static int -INVALID_VALUE_2 = 90008 -
static int -IO_EXCEPTION_1 = 90028 -
static int -IO_EXCEPTION_2 = 90031 -
static int -LIKE_ESCAPE_ERROR_1 = 22025 -
static int -LITERALS_ARE_NOT_ALLOWED = 90116 -
static int -LOCK_TIMEOUT_1 = 50200 -
static int -METHODS_MUST_HAVE_DIFFERENT_PARAMETER_COUNTS_2 = 90073 -
static int -METHOD_NOT_ALLOWED_FOR_PREPARED_STATEMENT = 90130 -
static int -METHOD_NOT_ALLOWED_FOR_QUERY = 90001 -
static int -METHOD_NOT_FOUND_1 = 90087 -
static int -METHOD_ONLY_ALLOWED_FOR_QUERY = 90002 -
static int -MUST_GROUP_BY_COLUMN_1 = 90016 -
static int -NOT_ENOUGH_RIGHTS_FOR_1 = 90096 -
static int -NOT_ON_UPDATABLE_ROW = 90029 -
static int -NO_DATA_AVAILABLE = 2000 -
static int -NO_DEFAULT_SET_1 = 90056 -
static int -NO_DISK_SPACE_AVAILABLE = 90100 -
static int -NULL_NOT_ALLOWED = 90006 -
static int -NUMERIC_VALUE_OUT_OF_RANGE = 22003 -
static int -OBJECT_CLOSED = 90007 -
static int -OPERATION_NOT_SUPPORTED_WITH_VIEWS_2 = 90122 -
static int -ORDER_BY_NOT_IN_RESULT = 90068 -
static int -OUT_OF_MEMORY = 90108 -
static int -OVERFLOW_FOR_TYPE_1 = 90110 -
static int -PARAMETER_NOT_SET_1 = 90012 -
static int -PARSE_ERROR_1 = 90014 -
static int -PUBLIC_STATIC_JAVA_METHOD_NOT_FOUND_1 = 90139 -
static int -REFERENTIAL_INTEGRITY_VIOLATED_CHILD_EXISTS_1 = 23003 -
static int -REFERENTIAL_INTEGRITY_VIOLATED_PARENT_MISSING_1 = 23002 -
static int -REMOTE_CONNECTION_NOT_ALLOWED = 90117 -
static int -RESULT_SET_NOT_SCROLLABLE = 90128 -
static int -RESULT_SET_NOT_UPDATABLE = 90127 -
static int -RESULT_SET_READONLY = 90140 -
static int -ROLES_AND_RIGHT_CANNOT_BE_MIXED = 90072 -
static int -ROLE_ALREADY_EXISTS_1 = 90069 -
static int -ROLE_ALREADY_GRANTED_1 = 90074 -
static int -ROLE_CAN_NOT_BE_DROPPED_1 = 90091 -
static int -ROLE_NOT_FOUND_1 = 90070 -
static int -ROW_NOT_FOUND_WHEN_DELETING_1 = 90112 -
static int -SAVEPOINT_IS_INVALID_1 = 90063 -
static int -SAVEPOINT_IS_NAMED = 90065 -
static int -SAVEPOINT_IS_UNNAMED = 90064 -
static int -SCALAR_SUBQUERY_CONTAINS_MORE_THAN_ONE_ROW = 90053 -
static int -SCHEMA_ALREADY_EXISTS_1 = 90078 -
static int -SCHEMA_CAN_NOT_BE_DROPPED_1 = 90090 -
static int -SCHEMA_NAME_MUST_MATCH = 90080 -
static int -SCHEMA_NOT_FOUND_1 = 90079 -
static int -SECOND_PRIMARY_KEY = 90017 -
static int -SEQUENCE_ALREADY_EXISTS_1 = 90035 -
static int -SEQUENCE_BELONGS_TO_A_TABLE_1 = 90082 -
static int -SEQUENCE_NOT_FOUND_1 = 90036 -
static int -SERIALIZATION_FAILED_1 = 90026 -
static int -STATEMENT_WAS_CANCELED = 90051 -
static int -STRING_FORMAT_ERROR_1 = 90095 -
static int -SUBQUERY_IS_NOT_SINGLE_COLUMN = 90052 -
static int -SUM_OR_AVG_ON_WRONG_DATATYPE_1 = 90015 -
static int -SYNTAX_ERROR_1 = 42000 -
static int -SYNTAX_ERROR_2 = 42001 -
static int -TABLE_OR_VIEW_ALREADY_EXISTS_1 = 42101 -
static int -TABLE_OR_VIEW_NOT_FOUND_1 = 42102 -
static int -TIMESTAMP_CONSTANT_2 = 90011 -
static int -TIME_CONSTANT_2 = 90010 -
static int -TRACE_CONNECTION_NOT_CLOSED = 90018 -
static int -TRACE_FILE_ERROR_2 = 90034 -
static int -TRANSACTION_NOT_FOUND_1 = 90129 -
static int -TRIGGER_ALREADY_EXISTS_1 = 90041 -
static int -TRIGGER_NOT_FOUND_1 = 90042 -
static int -UNKNOWN_DATA_TYPE_1 = 50004 -
static int -UNKNOWN_MODE_1 = 90088 -
static int -UNSUPPORTED_CIPHER = 90055 -
static int -UNSUPPORTED_COMPRESSION_ALGORITHM_1 = 90103 -
static int -UNSUPPORTED_COMPRESSION_OPTIONS_1 = 90102 -
static int -UNSUPPORTED_JAVA_VERSION = 90092 -
static int -UNSUPPORTED_LOCK_METHOD_1 = 90060 -
static int -UNSUPPORTED_OUTER_JOIN_CONDITION_1 = 90136 -
static int -UNSUPPORTED_SETTING_1 = 90113 -
static int -URL_FORMAT_ERROR_2 = 90046 -
static int -USER_ALREADY_EXISTS_1 = 90033 -
static int -USER_DATA_TYPE_ALREADY_EXISTS_1 = 90119 -
static int -USER_DATA_TYPE_NOT_FOUND_1 = 90120 -
static int -USER_NOT_FOUND_1 = 90032 -
static int -USER_OR_ROLE_NOT_FOUND_1 = 90071 -
static int -VALUE_TOO_LARGE_FOR_PRECISION_1 = 90039 -
static int -VALUE_TOO_LONG_2 = 90005 -
static int -VIEW_ALREADY_EXISTS_1 = 90038 -
static int -VIEW_IS_INVALID_2 = 90109 -
static int -VIEW_NOT_FOUND_1 = 90037 -
static int -WRONG_PASSWORD_FORMAT = 90050 -
static int -WRONG_USER_OR_PASSWORD = 8004 -
static int -WRONG_XID_FORMAT_1 = 90101 -
-

NO_DATA_AVAILABLE - = 2000 -

-
The error with code 2000 is thrown when - the result set is positioned before the first or after the last row, or - not on a valid row for the given operation. - Example of wrong usage: -
- ResultSet rs = stat.executeQuery("SELECT * FROM DUAL");
- rs.getString(1);
- Correct: -
- ResultSet rs = stat.executeQuery("SELECT * FROM DUAL");
- rs.next();
- rs.getString(1);
-
-

COLUMN_COUNT_DOES_NOT_MATCH - = 21002 -

-
The error with code 21002 is thrown when the number of - columns does not match. Possible reasons are: for an INSERT or MERGE - statement, the column count does not match the table or the column list - specified. For a SELECT UNION statement, both queries return a different - number of columns. For a constraint, the number of referenced and - referencing columns does not match. Example: -
- CREATE TABLE TEST(ID INT, NAME VARCHAR);
- INSERT INTO TEST VALUES('Hello');
-
-

NUMERIC_VALUE_OUT_OF_RANGE - = 22003 -

-
The error with code 22003 is thrown when a value is out of - range when converting to another data type. Example: -
- CALL CAST(1000000 AS TINYINT);
-
-

DIVISION_BY_ZERO_1 - = 22012 -

-
The error with code 22012 is thrown when trying to divide - a value by zero. Example: -
- CALL 1/0;
-
-

LIKE_ESCAPE_ERROR_1 - = 22025 -

-
The error with code 22025 is thrown when using an invalid - escape character sequence for LIKE or REGEXP. The default escape - character is '\'. The escape character is required when searching for - the characters '%', '_' and the escape character itself. That means if - you want to search for the text '10%', you need to use LIKE '10\%'. If - you want to search for 'C:\temp' you need to use 'C:\\temp'. The escape - character can be changed using the ESCAPE clause as in LIKE '10+%' ESCAPE - '+'. Example of wrong usage: -
- CALL 'C:\temp' LIKE 'C:\temp';
- CALL '1+1' LIKE '1+1' ESCAPE '+';
- Correct: -
- CALL 'C:\temp' LIKE 'C:\\temp';
- CALL '1+1' LIKE '1++1' ESCAPE '+';
-
-

CHECK_CONSTRAINT_VIOLATED_1 - = 23000 -

-
The error with code 23000 is thrown when a check - constraint is violated. Example: -
- CREATE TABLE TEST(ID INT CHECK ID>0);
- INSERT INTO TEST VALUES(0);
-
-

DUPLICATE_KEY_1 - = 23001 -

-
The error with code 23001 is thrown when trying to insert - a row that would violate a unique index or primary key. Example: -
- CREATE TABLE TEST(ID INT PRIMARY KEY);
- INSERT INTO TEST VALUES(1);
- INSERT INTO TEST VALUES(1);
-
-

REFERENTIAL_INTEGRITY_VIOLATED_PARENT_MISSING_1 - = 23002 -

-
The error with code 23002 is thrown when trying to insert - or update a row that would violate a referential constraint, because the - referenced row does not exist. Example: -
- CREATE TABLE PARENT(ID INT);
- CREATE TABLE CHILD(P_ID INT REFERENCES PARENT(ID));
- INSERT INTO CHILD VALUES(1);
-
-

REFERENTIAL_INTEGRITY_VIOLATED_CHILD_EXISTS_1 - = 23003 -

-
The error with code 23003 is thrown when trying to delete - or update a row when this would violate a referential constraint, because - there is a child row that would become an orphan. Example: -
- CREATE TABLE PARENT(ID INT);
- CREATE TABLE CHILD(P_ID INT REFERENCES PARENT(ID));
- INSERT INTO PARENT VALUES(1);
- INSERT INTO CHILD VALUES(1);
- DELETE FROM PARENT;
-
-

DEADLOCK_1 - = 40001 -

-
The error with code 40001 is thrown when the database - engine has detected a deadlock. The transaction of this session has been - rolled back to solve the problem. A deadlock occurs when a session tries - to lock a table another session has locked, while the other session wants - to lock a table the first session has locked. As an example, session 1 - has locked table A, while session 2 has locked table B. If session 1 now - tries to lock table B and session 2 tries to lock table A, a deadlock has - occurred. Deadlocks that involve more than two sessions are also possible. - To solve deadlock problems, an application should lock tables always in - the same order, such as always lock table A before locking table B. For - details, see Wikipedia - Deadlock.
-
-

SYNTAX_ERROR_1 - = 42000 -

-
The error with code 42000 is thrown when - trying to execute an invalid SQL statement. - Example: -
- CREATE ALIAS REMAINDER FOR "IEEEremainder";
-
-

SYNTAX_ERROR_2 - = 42001 -

-
The error with code 42001 is thrown when - trying to execute an invalid SQL statement. - Example: -
- CREATE TABLE TEST(ID INT);
- INSERT INTO TEST(1);
-
-

TABLE_OR_VIEW_ALREADY_EXISTS_1 - = 42101 -

-
The error with code 42101 is thrown when - trying to create a table or view if an object with this name already exists. - Example: -
- CREATE TABLE TEST(ID INT);
- CREATE TABLE TEST(ID INT PRIMARY KEY);
-
-

TABLE_OR_VIEW_NOT_FOUND_1 - = 42102 -

-
The error with code 42102 is thrown when - trying to query, modify or drop a table or view that does not exists - in this schema and database. A common cause is that the wrong - database was opened. - Example: -
- SELECT * FROM ABC;
-
-

INDEX_ALREADY_EXISTS_1 - = 42111 -

-
The error with code 42111 is thrown when - trying to create an index if an index with the same name already exists. - Example: -
- CREATE TABLE TEST(ID INT, NAME VARCHAR);
- CREATE INDEX IDX_ID ON TEST(ID);
- CREATE TABLE ADDRESS(ID INT);
- CREATE INDEX IDX_ID ON ADDRESS(ID);
-
-

INDEX_NOT_FOUND_1 - = 42112 -

-
The error with code 42112 is thrown when - trying to drop or reference an index that does not exist. - Example: -
- DROP INDEX ABC;
-
-

DUPLICATE_COLUMN_NAME_1 - = 42121 -

-
The error with code 42121 is thrown when trying to create - a table or insert into a table and use the same column name twice. - Example: -
- CREATE TABLE TEST(ID INT, ID INT);
-
-

COLUMN_NOT_FOUND_1 - = 42122 -

-
The error with code 42122 is thrown when - referencing an non-existing column. - Example: -
- CREATE TABLE TEST(ID INT);
- SELECT NAME FROM TEST;
-
-

GENERAL_ERROR_1 - = 50000 -

-
The error with code 50000 is thrown when - something unexpected occurs, for example an internal stack - overflow. For details about the problem, see the cause of the - exception in the stack trace.
-
-

UNKNOWN_DATA_TYPE_1 - = 50004 -

-
The error with code 50004 is thrown when - creating a table with an unsupported data type, or - when the data type is unknown because parameters are used. - Example: -
- CREATE TABLE TEST(ID VERYSMALLINT);
-
-

FEATURE_NOT_SUPPORTED_1 - = 50100 -

-
The error with code 50100 is thrown when calling an - unsupported JDBC method or database feature. See the stack trace for - details.
-
-

LOCK_TIMEOUT_1 - = 50200 -

-
The error with code 50200 is thrown when - another connection locked an object longer than the lock timeout - set for this connection, or when a deadlock occurred. - Example: -
- CREATE TABLE TEST(ID INT);
- -- connection 1:
- SET AUTOCOMMIT FALSE;
- INSERT INTO TEST VALUES(1);
- -- connection 2:
- SET AUTOCOMMIT FALSE;
- INSERT INTO TEST VALUES(1);
-
-

INVALID_PARAMETER_COUNT_2 - = 7001 -

-
The error with code 7001 is thrown when - trying to call a function with the wrong number of parameters. - Example: -
- CALL ABS(1, 2)
-
-

ERROR_OPENING_DATABASE_1 - = 8000 -

-
The error with code 8000 is thrown when - there was a problem trying to create a database lock. - See the message and cause for details.
-
-

WRONG_USER_OR_PASSWORD - = 8004 -

-
The error with code 8004 is thrown when - there is no such user registered in the database, when - the user password does not match, or when the database encryption password - does not match (if database encryption is used).
-
-

FUNCTION_MUST_RETURN_RESULT_SET_1 - = 90000 -

-
The error with code 90000 is thrown when - a function that does not return a result set was used in the FROM clause. - Example: -
- SELECT * FROM SIN(1);
-
-

METHOD_NOT_ALLOWED_FOR_QUERY - = 90001 -

-
The error with code 90001 is thrown when - Statement.executeUpdate() was called for a SELECT statement. - This is not allowed according to the JDBC specs.
-
-

METHOD_ONLY_ALLOWED_FOR_QUERY - = 90002 -

-
The error with code 90002 is thrown when - Statement.executeQuery() was called for a statement that does - not return a result set (for example, an UPDATE statement). - This is not allowed according to the JDBC specs.
-
-

HEX_STRING_ODD_1 - = 90003 -

-
The error with code 90003 is thrown when - trying to convert a String to a binary value. Two hex digits - per byte are required. Example of wrong usage: -
- CALL X'00023';
- Hexadecimal string with odd number of characters: 00023
- Correct: -
- CALL X'000023';
-
-

HEX_STRING_WRONG_1 - = 90004 -

-
The error with code 90004 is thrown when - trying to convert a text to binary, but the expression contains - a non-hexadecimal character. - Example: -
- CALL X'ABCDEFGH';
- CALL CAST('ABCDEFGH' AS BINARY);
- Conversion from text to binary is supported, but the text must - represent the hexadecimal encoded bytes.
-
-

VALUE_TOO_LONG_2 - = 90005 -

-
The error with code 90005 is thrown when - trying to insert a value that is too long for the column. - Example: -
- CREATE TABLE TEST(ID INT, NAME VARCHAR(2));
- INSERT INTO TEST VALUES(1, 'Hello');
-
-

NULL_NOT_ALLOWED - = 90006 -

-
The error with code 90006 is thrown when - trying to insert NULL into a column that does not allow NULL. - Example: -
- CREATE TABLE TEST(ID INT, NAME VARCHAR NOT NULL);
- INSERT INTO TEST(ID) VALUES(1);
-
-

OBJECT_CLOSED - = 90007 -

-
The error with code 90007 is thrown when - trying to call a JDBC method on an object that has been closed.
-
-

INVALID_VALUE_2 - = 90008 -

-
The error with code 90008 is thrown when - trying to use a value that is not valid for the given operation. - Example: -
- CREATE SEQUENCE TEST INCREMENT 0;
-
-

DATE_CONSTANT_2 - = 90009 -

-
The error with code 90009 is thrown when - a text can not be converted to a date constant. - Example: -
- CALL DATE '2007-January-01';
-
-

TIME_CONSTANT_2 - = 90010 -

-
The error with code 90010 is thrown when - a text can not be converted to a time constant. - Example: -
- CALL TIME '14:61:00';
-
-

TIMESTAMP_CONSTANT_2 - = 90011 -

-
The error with code 90011 is thrown when - a text can not be converted to a timestamp constant. - Example: -
- CALL TIMESTAMP '2001-02-30 12:00:00';
-
-

PARAMETER_NOT_SET_1 - = 90012 -

-
The error with code 90012 is thrown when - trying to execute a statement with an parameter. - Example: -
- CALL SIN(?);
-
-

DATABASE_NOT_FOUND_1 - = 90013 -

-
The error with code 90013 is thrown when - trying to open a database that does not exist using the flag IFEXISTS=TRUE, - or when trying to access a database object with a catalog name that does - not match the database name. - Example: -
- CREATE TABLE TEST(ID INT);
- SELECT XYZ.PUBLIC.TEST.ID FROM TEST;
-
-

PARSE_ERROR_1 - = 90014 -

-
The error with code 90014 is thrown when - trying to parse a date with an unsupported format string, or - when the date can not be parsed. - Example: -
- CALL PARSEDATETIME('2001 January', 'yyyy mm');
-
-

SUM_OR_AVG_ON_WRONG_DATATYPE_1 - = 90015 -

-
The error with code 90015 is thrown when - using an aggregate function with a data type that is not supported. - Example: -
- SELECT SUM('Hello') FROM DUAL;
-
-

MUST_GROUP_BY_COLUMN_1 - = 90016 -

-
The error with code 90016 is thrown when - a column was used in the expression list or the order by clause - of a group or aggregate query, and that column is not in the GROUP BY clause. - Example of wrong usage: -
- CREATE TABLE TEST(ID INT, NAME VARCHAR);
- INSERT INTO TEST VALUES(1, 'Hello'), (2, 'World');
- SELECT ID, MAX(NAME) FROM TEST;
- Column ID must be in the GROUP BY list.
- Correct: -
- SELECT ID, MAX(NAME) FROM TEST GROUP BY ID;
-
-

SECOND_PRIMARY_KEY - = 90017 -

-
The error with code 90017 is thrown when - trying to define a second primary key constraint for this table. - Example: -
- CREATE TABLE TEST(ID INT PRIMARY KEY, NAME VARCHAR);
- ALTER TABLE TEST ADD CONSTRAINT PK PRIMARY KEY(NAME);
-
-

TRACE_CONNECTION_NOT_CLOSED - = 90018 -

-
The error with code 90018 is thrown when - the connection was opened, but never closed. In the finalizer of the - connection, this forgotten close was detected and the connection was - closed automatically, but relying on the finalizer is not good practice - as it is not guaranteed and behavior is virtual machine dependent. The - application should close the connection. This exception only appears in - the .trace.db file. Example of wrong usage: -
- Connection conn;
- conn = DriverManager.getConnection("jdbc:h2:˜/test");
- conn = null;
- The connection was not closed by the application and is
- garbage collected
- Correct: -
- conn.close();
-
-

CANNOT_DROP_CURRENT_USER - = 90019 -

-
The error with code 90019 is thrown when - trying to drop the current user, if there are no other admin users. - Example: -
- DROP USER SA;
-
-

DATABASE_ALREADY_OPEN_1 - = 90020 -

-
The error with code 90020 is thrown when trying to open a - database in embedded mode if this database is already in use in another - process (or in a different class loader). Multiple connections to the - same database are supported in the following cases: -
  • In embedded mode (URL of the form jdbc:h2:~/test) if all - connections are opened within the same process and class loader. -
  • In server and cluster mode (URL of the form - jdbc:h2:tcp://localhost/test) using remote connections. -
- The mixed mode is also supported. This mode requires to start a server - in the same process where the database is open in embedded mode.
-
-

DATA_CONVERSION_ERROR_1 - = 90021 -

-
The error with code 90021 is thrown when - trying to convert a value to a data type where the conversion is undefined, - or when an error occurred trying to convert. - Example: -
- CALL CAST(DATE '2001-01-01' AS BOOLEAN);
- CALL CAST('CHF 99.95' AS INT);
-
-

FUNCTION_NOT_FOUND_1 - = 90022 -

-
The error with code 90022 is thrown when - trying to call a unknown function. - Example: -
- CALL SPECIAL_SIN(10);
-
-

COLUMN_MUST_NOT_BE_NULLABLE_1 - = 90023 -

-
The error with code 90023 is thrown when - trying to set a primary key on a nullable column. - Example: -
- CREATE TABLE TEST(ID INT, NAME VARCHAR);
- ALTER TABLE TEST ADD CONSTRAINT PK PRIMARY KEY(ID);
-
-

FILE_RENAME_FAILED_2 - = 90024 -

-
The error with code 90024 is thrown when - a file could not be renamed.
-
-

FILE_DELETE_FAILED_1 - = 90025 -

-
The error with code 90025 is thrown when - a file could not be deleted, because it is still in use - (only in Windows), or because an error occurred when deleting.
-
-

SERIALIZATION_FAILED_1 - = 90026 -

-
The error with code 90026 is thrown when - an object could not be serialized.
-
-

DESERIALIZATION_FAILED_1 - = 90027 -

-
The error with code 90027 is thrown when - an object could not be de-serialized.
-
-

IO_EXCEPTION_1 - = 90028 -

-
The error with code 90028 is thrown when - an input / output error occurred. For more information, see the root - cause of the exception.
-
-

NOT_ON_UPDATABLE_ROW - = 90029 -

-
The error with code 90029 is thrown when - calling ResultSet.deleteRow(), insertRow(), or updateRow() - when the current row is not updatable. - Example: -
- ResultSet rs = stat.executeQuery("SELECT * FROM TEST");
- rs.next();
- rs.insertRow();
-
-

FILE_CORRUPTED_1 - = 90030 -

-
The error with code 90030 is thrown when - the database engine has detected a checksum mismatch in the data - or index. To solve this problem, restore a backup or use the - Recovery tool (org.h2.tools.Recover).
-
-

IO_EXCEPTION_2 - = 90031 -

-
The error with code 90031 is thrown when - an input / output error occurred. For more information, see the root - cause of the exception.
-
-

USER_NOT_FOUND_1 - = 90032 -

-
The error with code 90032 is thrown when - trying to drop or alter a user that does not exist. - Example: -
- DROP USER TEST_USER;
-
-

USER_ALREADY_EXISTS_1 - = 90033 -

-
The error with code 90033 is thrown when - trying to create a user or role if a user with this name already exists. - Example: -
- CREATE USER TEST_USER;
- CREATE USER TEST_USER;
-
-

TRACE_FILE_ERROR_2 - = 90034 -

-
The error with code 90034 is thrown when - writing to the trace file failed, for example because the there - is an I/O exception. This message is printed to System.out, - but only once.
-
-

SEQUENCE_ALREADY_EXISTS_1 - = 90035 -

-
The error with code 90035 is thrown when - trying to create a sequence if a sequence with this name already - exists. - Example: -
- CREATE SEQUENCE TEST_SEQ;
- CREATE SEQUENCE TEST_SEQ;
-
-

SEQUENCE_NOT_FOUND_1 - = 90036 -

-
The error with code 90036 is thrown when - trying to access a sequence that does not exist. - Example: -
- SELECT NEXT VALUE FOR SEQUENCE XYZ;
-
-

VIEW_NOT_FOUND_1 - = 90037 -

-
The error with code 90037 is thrown when - trying to drop or alter a view that does not exist. - Example: -
- DROP VIEW XYZ;
-
-

VIEW_ALREADY_EXISTS_1 - = 90038 -

-
The error with code 90038 is thrown when - trying to create a view if a view with this name already - exists. - Example: -
- CREATE VIEW DUMMY AS SELECT * FROM DUAL;
- CREATE VIEW DUMMY AS SELECT * FROM DUAL;
-
-

VALUE_TOO_LARGE_FOR_PRECISION_1 - = 90039 -

-
The error with code 90039 is thrown when - trying to convert a decimal value to lower precision if the - value is out of range for this precision. - Example: -
- SELECT * FROM TABLE(X DECIMAL(2, 2) = (123.34));
-
-

ADMIN_RIGHTS_REQUIRED - = 90040 -

-
The error with code 90040 is thrown when - a user that is not administrator tries to execute a statement - that requires admin privileges.
-
-

TRIGGER_ALREADY_EXISTS_1 - = 90041 -

-
The error with code 90041 is thrown when - trying to create a trigger and there is already a trigger with that name. -
- CREATE TABLE TEST(ID INT);
- CREATE TRIGGER TRIGGER_A AFTER INSERT ON TEST
-      CALL "org.h2.samples.TriggerSample$MyTrigger";
- CREATE TRIGGER TRIGGER_A AFTER INSERT ON TEST
-      CALL "org.h2.samples.TriggerSample$MyTrigger";
-
-

TRIGGER_NOT_FOUND_1 - = 90042 -

-
The error with code 90042 is thrown when - trying to drop a trigger that does not exist. - Example: -
- DROP TRIGGER TRIGGER_XYZ;
-
-

ERROR_CREATING_TRIGGER_OBJECT_3 - = 90043 -

-
The error with code 90043 is thrown when - there is an error initializing the trigger, for example because the - class does not implement the Trigger interface. - See the root cause for details. - Example: -
- CREATE TABLE TEST(ID INT);
- CREATE TRIGGER TRIGGER_A AFTER INSERT ON TEST
-      CALL "java.lang.String";
-
-

ERROR_EXECUTING_TRIGGER_3 - = 90044 -

-
The error with code 90044 is thrown when - an exception or error occurred while calling the triggers fire method. - See the root cause for details.
-
-

CONSTRAINT_ALREADY_EXISTS_1 - = 90045 -

-
The error with code 90045 is thrown when - trying to create a constraint if an object with this name already exists. - Example: -
- CREATE TABLE TEST(ID INT NOT NULL);
- ALTER TABLE TEST ADD CONSTRAINT PK PRIMARY KEY(ID);
- ALTER TABLE TEST ADD CONSTRAINT PK PRIMARY KEY(ID);
-
-

URL_FORMAT_ERROR_2 - = 90046 -

-
The error with code 90046 is thrown when - trying to open a connection to a database using an unsupported URL format. - Please see the documentation on the supported URL format and examples. - Example: -
- jdbc:h2:;;
-
-

DRIVER_VERSION_ERROR_2 - = 90047 -

-
The error with code 90047 is thrown when - trying to connect to a TCP server with an incompatible client.
-
-

FILE_VERSION_ERROR_1 - = 90048 -

-
The error with code 90048 is thrown when - the file header of a database files (*.db) does not match the - expected version, or if it is corrupted.
-
-

FILE_ENCRYPTION_ERROR_1 - = 90049 -

-
The error with code 90049 is thrown when - trying to open an encrypted database with the wrong file encryption - password or algorithm.
-
-

WRONG_PASSWORD_FORMAT - = 90050 -

-
The error with code 90050 is thrown when trying to open an - encrypted database, but not separating the file password from the user - password. The file password is specified in the password field, before - the user password. A single space needs to be added between 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. - Example of wrong usage: -
- String url = "jdbc:h2:˜/test;CIPHER=AES";
- String passwords = "filePasswordUserPassword";
- DriverManager.getConnection(url, "sa", pwds);
- Correct: -
- String url = "jdbc:h2:˜/test;CIPHER=AES";
- String passwords = "filePassword userPassword";
- DriverManager.getConnection(url, "sa", pwds);
-
-

STATEMENT_WAS_CANCELED - = 90051 -

-
The error with code 90051 is thrown when - a statement was canceled using Statement.cancel() or - when the query timeout has been reached. - Examples: -
- stat.setQueryTimeout(1);
- stat.cancel();
-
-

SUBQUERY_IS_NOT_SINGLE_COLUMN - = 90052 -

-
The error with code 90052 is thrown when - a subquery that is used as a value contains more than one column. - Example of wrong usage: -
- CREATE TABLE TEST(ID INT);
- INSERT INTO TEST VALUES(1), (2);
- SELECT * FROM TEST WHERE ID IN (SELECT 1, 2 FROM DUAL);
- Correct: -
- CREATE TABLE TEST(ID INT);
- INSERT INTO TEST VALUES(1), (2);
- SELECT * FROM TEST WHERE ID IN (1, 2);
-
-

SCALAR_SUBQUERY_CONTAINS_MORE_THAN_ONE_ROW - = 90053 -

-
The error with code 90053 is thrown when - a subquery that is used as a value contains more than one row. - Example: -
- CREATE TABLE TEST(ID INT, NAME VARCHAR);
- INSERT INTO TEST VALUES(1, 'Hello'), (1, 'World');
- SELECT X, (SELECT NAME FROM TEST WHERE ID=X) FROM DUAL;
-
-

INVALID_USE_OF_AGGREGATE_FUNCTION_1 - = 90054 -

-
The error with code 90054 is thrown when - an aggregate function is used where it is not allowed. - Example: -
- CREATE TABLE TEST(ID INT);
- INSERT INTO TEST VALUES(1), (2);
- SELECT MAX(ID) FROM TEST WHERE ID = MAX(ID) GROUP BY ID;
-
-

UNSUPPORTED_CIPHER - = 90055 -

-
The error with code 90055 is thrown when - trying to open a database with an unsupported cipher algorithm. - Supported are AES and XTEA. - Example: -
- jdbc:h2:~/test;CIPHER=DES
-
-

NO_DEFAULT_SET_1 - = 90056 -

-
The error with code 90056 is thrown when - updating or deleting from a table with a foreign key constraint - that should set the default value, but there is no default value defined. - Example: -
- CREATE TABLE TEST(ID INT, PARENT INT);
- INSERT INTO TEST VALUES(1, 1), (2, 1);
- ALTER TABLE TEST ADD CONSTRAINT TEST_ID_PARENT
-   FOREIGN KEY(PARENT) REFERENCES(ID) ON DELETE SET DEFAULT;
-   DELETE FROM TEST WHERE ID=1;
-
-

CONSTRAINT_NOT_FOUND_1 - = 90057 -

-
The error with code 90057 is thrown when - trying to drop a constraint that does not exist. - Example: -
- CREATE TABLE TEST(ID INT);
- ALTER TABLE TEST DROP CONSTRAINT CID;
-
-

COMMIT_ROLLBACK_NOT_ALLOWED - = 90058 -

-
The error with code 90058 is thrown when trying to call - commit or rollback inside a trigger, or when trying to call a method - inside a trigger that implicitly commits the current transaction, if an - object is locked. This is not because it would release the lock too - early.
-
-

AMBIGUOUS_COLUMN_NAME_1 - = 90059 -

-
The error with code 90059 is thrown when - a query contains a column that could belong to multiple tables. - Example: -
- CREATE TABLE PARENT(ID INT, NAME VARCHAR);
- CREATE TABLE CHILD(PID INT, NAME VARCHAR);
- SELECT ID, NAME FROM PARENT P, CHILD C WHERE P.ID = C.PID;
-
-

UNSUPPORTED_LOCK_METHOD_1 - = 90060 -

-
The error with code 90060 is thrown when - trying to use a file locking mechanism that is not supported. - Currently only FILE (the default) and SOCKET are supported - Example: -
- jdbc:h2:~/test;FILE_LOCK=LDAP
-
-

EXCEPTION_OPENING_PORT_2 - = 90061 -

-
The error with code 90061 is thrown when - trying to start a server if a server is already running on the same port. - It could also be a firewall problem. To find out if another server is - already running, run the following command on Windows: -
- netstat -ano
- The column PID is the process id as listed in the Task Manager. - For Linux, use: -
- netstat -npl
-
-

FILE_CREATION_FAILED_1 - = 90062 -

-
The error with code 90062 is thrown when - a directory or file could not be created. This can occur when - trying to create a directory if a file with the same name already - exists, or vice versa.
-
-

SAVEPOINT_IS_INVALID_1 - = 90063 -

-
The error with code 90063 is thrown when - trying to rollback to a savepoint that is not defined. - Example: -
- ROLLBACK TO SAVEPOINT S_UNKNOWN;
-
-

SAVEPOINT_IS_UNNAMED - = 90064 -

-
The error with code 90064 is thrown when - Savepoint.getSavepointName() is called on an unnamed savepoint. - Example: -
- Savepoint sp = conn.setSavepoint();
- sp.getSavepointName();
-
-

SAVEPOINT_IS_NAMED - = 90065 -

-
The error with code 90065 is thrown when - Savepoint.getSavepointId() is called on a named savepoint. - Example: -
- Savepoint sp = conn.setSavepoint("Joe");
- sp.getSavepointId();
-
-

DUPLICATE_PROPERTY_1 - = 90066 -

-
The error with code 90066 is thrown when - the same property appears twice in the database URL or in - the connection properties. - Example: -
- jdbc:h2:~/test;LOCK_TIMEOUT=0;LOCK_TIMEOUT=1
-
-

CONNECTION_BROKEN_1 - = 90067 -

-
The error with code 90067 is thrown when - the connection to the database is lost. A possible reason - is that the database connection has been closed due to a shutdown, - or that the server is stopped. Other causes could be: - the server is not an H2 server, or the network connection is broken.
-
-

ORDER_BY_NOT_IN_RESULT - = 90068 -

-
The error with code 90068 is thrown when the given - expression that is used in the ORDER BY is not in the result list. This - is required for distinct queries, otherwise the result would be - ambiguous. - Example of wrong usage: -
- CREATE TABLE TEST(ID INT, NAME VARCHAR);
- INSERT INTO TEST VALUES(2, 'Hello'), (1, 'Hello');
- SELECT DISTINCT NAME FROM TEST ORDER BY ID;
- Order by expression ID must be in the result list in this case
- Correct: -
- SELECT DISTINCT ID, NAME FROM TEST ORDER BY ID;
-
-

ROLE_ALREADY_EXISTS_1 - = 90069 -

-
The error with code 90069 is thrown when - trying to create a role if an object with this name already exists. - Example: -
- CREATE ROLE TEST_ROLE;
- CREATE ROLE TEST_ROLE;
-
-

ROLE_NOT_FOUND_1 - = 90070 -

-
The error with code 90070 is thrown when - trying to drop or grant a role that does not exists. - Example: -
- DROP ROLE TEST_ROLE_2;
-
-

USER_OR_ROLE_NOT_FOUND_1 - = 90071 -

-
The error with code 90071 is thrown when - trying to grant or revoke if no role or user with that name exists. - Example: -
- GRANT SELECT ON TEST TO UNKNOWN;
-
-

ROLES_AND_RIGHT_CANNOT_BE_MIXED - = 90072 -

-
The error with code 90072 is thrown when - trying to grant or revoke if no role or user with that name exists. - Example: -
- GRANT SELECT, TEST_ROLE ON TEST TO SA;
-
-

METHODS_MUST_HAVE_DIFFERENT_PARAMETER_COUNTS_2 - = 90073 -

-
The error with code 90073 is thrown when trying to create - an alias for a Java method, if two methods exists in this class that have - this name and the same number of parameters. - Example of wrong usage: -
- CREATE ALIAS GET_LONG FOR
-      "java.lang.Long.getLong";
- Correct: -
- CREATE ALIAS GET_LONG FOR
-      "java.lang.Long.getLong(java.lang.String, java.lang.Long)";
-
-

ROLE_ALREADY_GRANTED_1 - = 90074 -

-
The error with code 90074 is thrown when - trying to grant a role that has already been granted. - Example: -
- CREATE ROLE TEST_A;
- CREATE ROLE TEST_B;
- GRANT TEST_A TO TEST_B;
- GRANT TEST_B TO TEST_A;
-
-

COLUMN_IS_PART_OF_INDEX_1 - = 90075 -

-
The error with code 90075 is thrown when - trying to alter a table and allow null for a column that is part of a - primary key or hash index. - Example: -
- CREATE TABLE TEST(ID INT PRIMARY KEY);
- ALTER TABLE TEST ALTER COLUMN ID NULL;
-
-

FUNCTION_ALIAS_ALREADY_EXISTS_1 - = 90076 -

-
The error with code 90076 is thrown when - trying to create a function alias for a system function or for a function - that is already defined. - Example: -
- CREATE ALIAS SQRT FOR "java.lang.Math.sqrt"
-
-

FUNCTION_ALIAS_NOT_FOUND_1 - = 90077 -

-
The error with code 90077 is thrown when - trying to drop a system function or a function alias that does not exist. - Example: -
- DROP ALIAS SQRT;
-
-

SCHEMA_ALREADY_EXISTS_1 - = 90078 -

-
The error with code 90078 is thrown when - trying to create a schema if an object with this name already exists. - Example: -
- CREATE SCHEMA TEST_SCHEMA;
- CREATE SCHEMA TEST_SCHEMA;
-
-

SCHEMA_NOT_FOUND_1 - = 90079 -

-
The error with code 90079 is thrown when - trying to drop a schema that does not exist. - Example: -
- DROP SCHEMA UNKNOWN;
-
-

SCHEMA_NAME_MUST_MATCH - = 90080 -

-
The error with code 90080 is thrown when - trying to rename a object to a different schema, or when trying to - create a related object in another schema. - For CREATE LINKED TABLE, it is thrown when multiple tables with that - name exist in different schemas. - Example: -
- CREATE SCHEMA TEST_SCHEMA;
- CREATE TABLE TEST(ID INT);
- CREATE INDEX TEST_ID ON TEST(ID);
- ALTER INDEX TEST_ID RENAME TO TEST_SCHEMA.IDX_TEST_ID;
-
-

COLUMN_CONTAINS_NULL_VALUES_1 - = 90081 -

-
The error with code 90081 is thrown when - trying to alter a column to not allow NULL, if there - is already data in the table where this column is NULL. - Example: -
- CREATE TABLE TEST(ID INT);
- INSERT INTO TEST VALUES(NULL);
- ALTER TABLE TEST ALTER COLUMN ID VARCHAR NOT NULL;
-
-

SEQUENCE_BELONGS_TO_A_TABLE_1 - = 90082 -

-
The error with code 90082 is thrown when - trying to drop a system generated sequence.
-
-

COLUMN_MAY_BE_REFERENCED_1 - = 90083 -

-
The error with code 90083 is thrown when - trying to drop a column that is part of a constraint. - Example: -
- CREATE TABLE TEST(ID INT, PID INT REFERENCES(ID));
- ALTER TABLE TEST DROP COLUMN PID;
-
-

CANNOT_DROP_LAST_COLUMN - = 90084 -

-
The error with code 90084 is thrown when - trying to drop the last column of a table. - Example: -
- CREATE TABLE TEST(ID INT);
- ALTER TABLE TEST DROP COLUMN ID;
-
-

INDEX_BELONGS_TO_CONSTRAINT_1 - = 90085 -

-
The error with code 90085 is thrown when - trying to manually drop an index that was generated by the system - because of a unique or referential constraint. To find out what - constraint causes the problem, run: -
- SELECT * FROM INFORMATION_SCHEMA.CONSTRAINTS
- WHERE UNIQUE_INDEX_NAME = '<index name>';
- Example of wrong usage: -
- CREATE TABLE TEST(ID INT, CONSTRAINT UID UNIQUE(ID));
- DROP INDEX UID_INDEX_0;
- Index UID_INDEX_0 belongs to a constraint
- Correct: -
- ALTER TABLE TEST DROP CONSTRAINT UID;
-
-

CLASS_NOT_FOUND_1 - = 90086 -

-
The error with code 90086 is thrown when - a class can not be loaded because it is not in the classpath - or because a related class is not in the classpath. - Example: -
- CREATE ALIAS TEST FOR "java.lang.invalid.Math.sqrt";
-
-

METHOD_NOT_FOUND_1 - = 90087 -

-
The error with code 90087 is thrown when - the specified method was not found in the class. - Example: -
- CREATE ALIAS TO_BINARY FOR "java.lang.Long.toBinaryString(long)";
- CALL TO_BINARY(10, 2);
-
-

UNKNOWN_MODE_1 - = 90088 -

-
The error with code 90088 is thrown when - trying to switch to an unknown mode. - Example: -
- SET MODE UNKNOWN;
-
-

COLLATION_CHANGE_WITH_DATA_TABLE_1 - = 90089 -

-
The error with code 90089 is thrown when - trying to change the collation while there was already data in - the database. The collation of the database must be set when the - database is empty. - Example of wrong usage: -
- CREATE TABLE TEST(NAME VARCHAR PRIMARY KEY);
- INSERT INTO TEST VALUES('Hello', 'World');
- SET COLLATION DE;
- Collation cannot be changed because there is a data table: PUBLIC.TEST
- Correct: -
- SET COLLATION DE;
- CREATE TABLE TEST(NAME VARCHAR PRIMARY KEY);
- INSERT INTO TEST VALUES('Hello', 'World');
-
-

SCHEMA_CAN_NOT_BE_DROPPED_1 - = 90090 -

-
The error with code 90090 is thrown when - trying to drop a schema that may not be dropped (the schema PUBLIC - and the schema INFORMATION_SCHEMA). - Example: -
- DROP SCHEMA PUBLIC;
-
-

ROLE_CAN_NOT_BE_DROPPED_1 - = 90091 -

-
The error with code 90091 is thrown when - trying to drop the role PUBLIC. - Example: -
- DROP ROLE PUBLIC;
-
-

UNSUPPORTED_JAVA_VERSION - = 90092 -

-
The error with code 90092 is thrown when - the source code is not compiled for the Java platform used. - At runtime, the existence of the class java.sql.Savepoint is checked. - To run this database in JDK 1.3, it is first required to switch the - source code to JDK 1.3 using ant switchSourceJdk13.
-
-

CLUSTER_ERROR_DATABASE_RUNS_ALONE - = 90093 -

-
The error with code 90093 is thrown when - trying to connect to a clustered database that runs in standalone - mode. This can happen if clustering is not enabled on the database, - or if one of the clients disabled clustering because it can not see - the other cluster node.
-
-

CLUSTER_ERROR_DATABASE_RUNS_CLUSTERED_1 - = 90094 -

-
The error with code 90094 is thrown when - trying to connect to a clustered database that runs together with a - different cluster node setting than what is used when trying to connect.
-
-

STRING_FORMAT_ERROR_1 - = 90095 -

-
The error with code 90095 is thrown when - calling the method STRINGDECODE with an invalid escape sequence. - Only Java style escape sequences and Java properties file escape - sequences are supported. - Example: -
- CALL STRINGDECODE('\i');
-
-

NOT_ENOUGH_RIGHTS_FOR_1 - = 90096 -

-
The error with code 90096 is thrown when - trying to perform an operation with a non-admin user if the - user does not have enough rights.
-
-

DATABASE_IS_READ_ONLY - = 90097 -

-
The error with code 90097 is thrown when - trying to delete or update a database if it is open in read-only mode. - Example: -
- jdbc:h2:~/test;ACCESS_MODE_DATA=R
- CREATE TABLE TEST(ID INT);
-
-

DATABASE_IS_CLOSED - = 90098 -

-
The error with code 90098 is thrown when the database has - been closed, for example because the system ran out of memory or because - the self-destruction counter has reached zero. This counter is only used - for recovery testing, and not set in normal operation.
-
-

ERROR_SETTING_DATABASE_EVENT_LISTENER_2 - = 90099 -

-
The error with code 90099 is thrown when an error occurred - trying to initialize the database event listener. Example: -
- jdbc:h2:˜/test;DATABASE_EVENT_LISTENER='java.lang.String'
-
-

NO_DISK_SPACE_AVAILABLE - = 90100 -

-
The error with code 90100 is thrown when - there is no more space available on the device where the database - files are stored.
-
-

WRONG_XID_FORMAT_1 - = 90101 -

-
The error with code 90101 is thrown when - the XA API detected unsupported transaction names. This can happen - when mixing application generated transaction names and transaction names - generated by this databases XAConnection API.
-
-

UNSUPPORTED_COMPRESSION_OPTIONS_1 - = 90102 -

-
The error with code 90102 is thrown when - trying to use unsupported options for the given compression algorithm. - Example of wrong usage: -
- CALL COMPRESS(STRINGTOUTF8(SPACE(100)), 'DEFLATE l 10');
- Correct: -
- CALL COMPRESS(STRINGTOUTF8(SPACE(100)), 'DEFLATE l 9');
-
-

UNSUPPORTED_COMPRESSION_ALGORITHM_1 - = 90103 -

-
The error with code 90103 is thrown when - trying to use an unsupported compression algorithm. - Example: -
- CALL COMPRESS(STRINGTOUTF8(SPACE(100)), 'BZIP');
-
-

COMPRESSION_ERROR - = 90104 -

-
The error with code 90104 is thrown when - the data can not be de-compressed. - Example: -
- CALL EXPAND(X'00FF');
-
-

EXCEPTION_IN_FUNCTION_1 - = 90105 -

-
The error with code 90105 is thrown when - an exception occurred in a user-defined method. - Example: -
- CREATE ALIAS SYS_PROP FOR "java.lang.System.getProperty";
- CALL SYS_PROP(NULL);
-
-

CANNOT_TRUNCATE_1 - = 90106 -

-
The error with code 90106 is thrown when - trying to truncate a table that can not be truncated. - Tables with referential integrity constraints can not be truncated. - Also, system tables and view can not be truncated. - Example: -
- TRUNCATE TABLE INFORMATION_SCHEMA.SETTINGS;
-
-

CANNOT_DROP_2 - = 90107 -

-
The error with code 90107 is thrown when - trying to drop an object because another object would become invalid. - Example: -
- CREATE TABLE COUNT(X INT);
- CREATE TABLE ITEMS(ID INT DEFAULT SELECT MAX(X)+1 FROM COUNT);
- DROP TABLE COUNT;
-
-

OUT_OF_MEMORY - = 90108 -

-
The error with code 90108 is thrown when not enough heap - memory was available. A possible solutions is to increase the memory size - using java -Xmx128m .... Another solution is to reduce - the cache size.
-
-

VIEW_IS_INVALID_2 - = 90109 -

-
The error with code 90109 is thrown when - trying to run a query against an invalid view. - Example: -
- CREATE FORCE VIEW TEST_VIEW AS SELECT * FROM TEST;
- SELECT * FROM TEST_VIEW;
-
-

OVERFLOW_FOR_TYPE_1 - = 90110 -

-
The error with code 90110 is thrown when - the result of the calculation does not fit in the given data type. - Example: -
- CALL -CAST(-128 AS TINYINT);
-
-

ERROR_ACCESSING_LINKED_TABLE_2 - = 90111 -

-
The error with code 90111 is thrown when - an exception occurred while accessing a linked table.
-
-

ROW_NOT_FOUND_WHEN_DELETING_1 - = 90112 -

-
The error with code 90112 is thrown when a row was deleted - twice while locking was disabled. This is an intern exception that should - never be thrown to the application, because such deleted should be - detected and the resulting exception ignored inside the database engine. -
- Row not found when trying to delete from index UID_INDEX_0
-
-

UNSUPPORTED_SETTING_1 - = 90113 -

-
The error with code 90113 is thrown when - the database URL contains unsupported settings. - Example: -
- jdbc:h2:~/test;UNKNOWN=TRUE
-
-

CONSTANT_ALREADY_EXISTS_1 - = 90114 -

-
The error with code 90114 is thrown when - trying to create a constant if a constant with this name already exists. - Example: -
- CREATE CONSTANT TEST VALUE 1;
- CREATE CONSTANT TEST VALUE 1;
-
-

CONSTANT_NOT_FOUND_1 - = 90115 -

-
The error with code 90115 is thrown when - trying to drop a constant that does not exists. - Example: -
- DROP CONSTANT UNKNOWN;
-
-

LITERALS_ARE_NOT_ALLOWED - = 90116 -

-
The error with code 90116 is thrown when - trying use a literal in a SQL statement if literals are disabled. - If literals are disabled, use PreparedStatement and parameters instead - of literals in the SQL statement. - Example: -
- SET ALLOW_LITERALS NONE;
- CALL 1+1;
-
-

REMOTE_CONNECTION_NOT_ALLOWED - = 90117 -

-
The error with code 90117 is thrown when - trying to connect to a TCP server from another machine, if remote - connections are not allowed. To allow remote connections, - start the TCP server using the option -tcpAllowOthers as in: -
- java org.h2.tools.Server -tcp -tcpAllowOthers
- Or, when starting the server from an application, use: -
- Server server = Server.createTcpServer("-tcpAllowOthers");
- server.start();
-
-

CANNOT_DROP_TABLE_1 - = 90118 -

-
The error with code 90118 is thrown when - trying to drop a table can not be dropped. - Example: -
- DROP TABLE INFORMATION_SCHEMA.SETTINGS;
-
-

USER_DATA_TYPE_ALREADY_EXISTS_1 - = 90119 -

-
The error with code 90119 is thrown when - trying to create a domain if an object with this name already exists, - or when trying to overload a built-in data type. - Example: -
- CREATE DOMAIN INTEGER AS VARCHAR;
- CREATE DOMAIN EMAIL AS VARCHAR CHECK LOCATE('@', VALUE) > 0;
- CREATE DOMAIN EMAIL AS VARCHAR CHECK LOCATE('@', VALUE) > 0;
-
-

USER_DATA_TYPE_NOT_FOUND_1 - = 90120 -

-
The error with code 90120 is thrown when - trying to drop a domain that doesn't exists. - Example: -
- DROP DOMAIN UNKNOWN;
-
-

DATABASE_CALLED_AT_SHUTDOWN - = 90121 -

-
The error with code 90121 is thrown when - a database operation is started while the virtual machine exits - (for example in a shutdown hook), or when the session is closed.
-
-

OPERATION_NOT_SUPPORTED_WITH_VIEWS_2 - = 90122 -

-
The error with code 90122 is thrown when - trying to altering, adding or dropping columns of a table that has views. - Example: -
- CREATE TABLE TEST(ID INT);
- CREATE VIEW TEST_VIEW AS SELECT * FROM TEST;
- ALTER TABLE TEST ADD COLUMN NAME VARCHAR;
-
-

CANNOT_MIX_INDEXED_AND_UNINDEXED_PARAMS - = 90123 -

-
The error with code 90123 is thrown when - trying mix regular parameters and indexed parameters in the same statement. - Example: -
- SELECT ?, ?1 FROM DUAL;
-
-

FILE_NOT_FOUND_1 - = 90124 -

-
The error with code 90124 is thrown when - trying to access a file that doesn't exist. This can occur when trying to - read a lob if the lob file has been deleted by another application.
-
-

INVALID_CLASS_2 - = 90125 -

-
The error with code 90125 is thrown when - PreparedStatement.setBigDecimal is called - with object that extends the class BigDecimal, and the system property - h2.allowBigDecimalExtensions is not set. Using extensions of BigDecimal is - dangerous because the database relies on the behavior of BigDecimal. - Example of wrong usage: -
- BigDecimal bd = new MyDecimal("$10.3");
- prep.setBigDecimal(1, bd);
- Invalid class, expected java.math.BigDecimal but got MyDecimal
- Correct: -
- BigDecimal bd = new BigDecimal("10.3");
- prep.setBigDecimal(1, bd);
-
-

DATABASE_IS_NOT_PERSISTENT - = 90126 -

-
The error with code 90126 is thrown when - trying to call the BACKUP statement for an in-memory database. - Example: -
- jdbc:h2:mem:
- BACKUP TO 'test.zip';
-
-

RESULT_SET_NOT_UPDATABLE - = 90127 -

-
The error with code 90127 is thrown when - trying to update or delete a row in a result set if the result set is - not updatable. Result sets are only updatable if the statement was - created with updatable concurrency, and if the result set contains - all columns of the primary key or of a unique index of a table.
-
-

RESULT_SET_NOT_SCROLLABLE - = 90128 -

-
The error with code 90128 is thrown when - trying to call a method of the ResultSet that is only supported - for scrollable result sets, and the result set is not scrollable. - Example: -
- rs.first();
-
-

TRANSACTION_NOT_FOUND_1 - = 90129 -

-
The error with code 90129 is thrown when - trying to commit a transaction that doesn't exist. - Example: -
- PREPARE COMMIT ABC;
- COMMIT TRANSACTION TEST;
-
-

METHOD_NOT_ALLOWED_FOR_PREPARED_STATEMENT - = 90130 -

-
The error with code 90130 is thrown when - an execute method of PreparedStatement was called with a SQL statement. - This is not allowed according to the JDBC specification. Instead, use - an execute method of Statement. - Example of wrong usage: -
- PreparedStatement prep = conn.prepareStatement("SELECT * FROM TEST");
- prep.execute("DELETE FROM TEST");
- Correct: -
- Statement stat = conn.createStatement();
- stat.execute("DELETE FROM TEST");
-
-

CONCURRENT_UPDATE_1 - = 90131 -

-
The error with code 90131 is thrown when - using multi version concurrency control, and trying to update the same - row from within two connections at the same time. - Example: -
- jdbc:h2:~/test;MVCC=TRUE
- Session 1:
- CREATE TABLE TEST(ID INT);
- INSERT INTO TEST VALUES(1);
- SET AUTOCOMMIT FALSE;
- UPDATE TEST SET ID = 2;
- Session 2:
- SET AUTOCOMMIT FALSE;
- UPDATE TEST SET ID = 3;
-
-

AGGREGATE_NOT_FOUND_1 - = 90132 -

-
The error with code 90132 is thrown when - trying to drop a user-defined aggregate function that doesn't exist. - Example: -
- DROP AGGREGATE UNKNOWN;
-
-

CANNOT_CHANGE_SETTING_WHEN_OPEN_1 - = 90133 -

-
The error with code 90133 is thrown when - trying to change a specific database property while the database is already - open. The MVCC property needs to be set in the first connection - (in the connection opening the database) and can not be changed later on.
-
-

ACCESS_DENIED_TO_CLASS_1 - = 90134 -

-
The error with code 90134 is thrown when - trying to load a Java class that is not part of the allowed classes. - By default, all classes are allowed, but this can be changed using the system - property h2.allowedClasses.
-
-

DATABASE_IS_IN_EXCLUSIVE_MODE - = 90135 -

-
The error with code 90135 is thrown when - trying to open a connection to a database that is currently open - in exclusive mode. The exclusive mode is set using: -
- SET EXCLUSIVE TRUE;
-
-

UNSUPPORTED_OUTER_JOIN_CONDITION_1 - = 90136 -

-
The error with code 90136 is thrown when - executing a query that used an unsupported outer join condition. - Example: -
- SELECT * FROM DUAL A LEFT JOIN DUAL B ON B.X=(SELECT MAX(X) FROM DUAL);
-
-

CAN_ONLY_ASSIGN_TO_VARIABLE_1 - = 90137 -

-
The error with code 90137 is thrown when - trying to assign a value to something that is not a variable. -
- SELECT AMOUNT, SET(@V, IFNULL(@V, 0)+AMOUNT) FROM TEST;
-
-

INVALID_DATABASE_NAME_1 - = 90138 -

-
The error with code 90138 is thrown when - - trying to open a persistent database using an incorrect database name. - The name of a persistent database contains the path and file name prefix - where the data is stored. The file name part of a database name must be - at least two characters. - - Example of wrong usage: -
- DriverManager.getConnection("jdbc:h2:~/t");
- DriverManager.getConnection("jdbc:h2:~/test/");
- Correct: -
- DriverManager.getConnection("jdbc:h2:~/te");
- DriverManager.getConnection("jdbc:h2:~/test/te");
-
-

PUBLIC_STATIC_JAVA_METHOD_NOT_FOUND_1 - = 90139 -

-
The error with code 90139 is thrown when - the specified public static Java method was not found in the class. - Example: -
- CREATE ALIAS TEST FOR "java.lang.Math.test";
-
-

RESULT_SET_READONLY - = 90140 -

-
The error with code 90140 is thrown when trying to update or - delete a row in a result set if the statement was not created with - updatable concurrency. Result sets are only updatable if the statement - was created with updatable concurrency, and if the result set contains - all columns of the primary key or of a unique index of a table.
-
-
diff --git a/tools/h2/docs/javadoc/org/h2/constant/SysProperties.html b/tools/h2/docs/javadoc/org/h2/constant/SysProperties.html deleted file mode 100755 index 599586d..0000000 --- a/tools/h2/docs/javadoc/org/h2/constant/SysProperties.html +++ /dev/null @@ -1,894 +0,0 @@ - - - -SysProperties - - - -
-

SysProperties

-The constants defined in this class are initialized from system properties. - Some system properties are per machine settings, and others are as a last - resort and temporary solution to work around a problem in the application or - database engine. Also, there are system properties to enable features that - are not yet fully tested or that are not backward compatible. -

- System properties can be set when starting the virtual machine: -

- -
- java -Dh2.baseDir=/temp
- - They can be set within the application, but this must be done before loading - any classes of this database (before loading the JDBC driver): - -
- System.setProperty("h2.baseDir", "/temp");


- - - - - - - - - - -
Methods
static int -getCollatorCacheSize() -
System property h2.collatorCacheSize (default: 32000).
-
static int -getCollatorCacheSize() -
System property h2.collatorCacheSize (default: 32000).
- The cache size for collation keys (in elements). Used when a collator has - been set for the database.
-
Returns:
-
the current value
-
static int -getMaxQueryTimeout() -
System property h2.maxQueryTimeout (default: 0).
-
static int -getMaxQueryTimeout() -
System property h2.maxQueryTimeout (default: 0).
- The maximum timeout of a query. The default is 0, meaning no limit.
-
Returns:
-
the current value
-
static String -getScriptDirectory() -
System property h2.scriptDirectory (default: empty - string).
-
static String -getScriptDirectory() -
System property h2.scriptDirectory (default: empty - string).
- Relative or absolute directory where the script files are stored to or - read from.
-
Returns:
-
the current value
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Fields
static boolean -ALIAS_COLUMN_NAME -
static String -ALLOWED_CLASSES -
static boolean -ALLOW_BIG_DECIMAL_EXTENSIONS -
static int -ANALYZE_AUTO -
static int -ANALYZE_SAMPLE -
static String -BIND_ADDRESS -
static String -BROWSER -
static int -CACHE_SIZE_DEFAULT -
static String -CACHE_TYPE_DEFAULT -
static boolean -CHECK -
static boolean -CHECK2 -
static String -CLIENT_TRACE_DIRECTORY -
static boolean -CONSOLE_STREAM -
static int -DATASOURCE_TRACE_LEVEL -
static String -DEFAULT_ESCAPE -
static int -DEFAULT_LOCK_MODE -
static int -DEFAULT_MAX_LENGTH_INPLACE_LOB -
static int -DEFAULT_MAX_LENGTH_INPLACE_LOB2 -
static int -DEFAULT_MAX_MEMORY_UNDO -
static int -DEFAULT_MAX_OPERATION_MEMORY -
static int -DEFAULT_RESULT_SET_CONCURRENCY -
static int -DELAY_WRONG_PASSWORD_MAX -
static int -DELAY_WRONG_PASSWORD_MIN -
static boolean -ENABLE_ANONYMOUS_SSL -
static int -ESTIMATED_FUNCTION_TABLE_ROWS -
static String -FILE_ENCODING -
static String -FILE_SEPARATOR -
static boolean -FUNCTIONS_IN_SCHEMA -
static boolean -IDENTIFIERS_TO_UPPER -
static String -JAVA_SPECIFICATION_VERSION -
static int -LARGE_RESULT_BUFFER_SIZE -
static boolean -LARGE_TRANSACTIONS -
static String -LINE_SEPARATOR -
static int -LOB_FILES_PER_DIRECTORY -
static boolean -LOB_IN_DATABASE -
static boolean -LOG_ALL_ERRORS -
static String -LOG_ALL_ERRORS_FILE -
static int -MAX_COMPACT_COUNT -
static int -MAX_COMPACT_TIME -
static int -MAX_FILE_RETRY -
static int -MAX_MEMORY_ROWS_DISTINCT -
static int -MAX_RECONNECT -
static long -MAX_TRACE_DATA_LENGTH -
static int -MIN_COLUMN_NAME_MAP -
static int -MIN_WRITE_DELAY -
static boolean -NIO_CLEANER_HACK -
static boolean -NIO_LOAD_MAPPED -
static boolean -OBJECT_CACHE -
static int -OBJECT_CACHE_MAX_PER_ELEMENT_SIZE -
static int -OBJECT_CACHE_SIZE -
static boolean -OPTIMIZE_DISTINCT -
static boolean -OPTIMIZE_EVALUATABLE_SUBQUERIES -
static boolean -OPTIMIZE_IN_LIST -
static boolean -OPTIMIZE_IS_NULL -
static boolean -OPTIMIZE_OR -
static boolean -OPTIMIZE_SUBQUERY_CACHE -
static boolean -OPTIMIZE_TWO_EQUALS -
static int -PAGE_SIZE -
static boolean -PAGE_STORE_INTERNAL_COUNT -
static boolean -PAGE_STORE_TRIM -
static String -PG_DEFAULT_CLIENT_ENCODING -
static String -PREFIX_TEMP_FILE -
static boolean -RECOMPILE_ALWAYS -
static int -RECONNECT_CHECK_DELAY -
static int -REDO_BUFFER_SIZE -
static int -RESERVE_MEMORY -
static boolean -RETURN_LOB_OBJECTS -
static boolean -SELECT_FOR_UPDATE_MVCC -
static int -SERVER_CACHED_OBJECTS -
static int -SERVER_RESULT_SET_FETCH_SIZE -
static boolean -SHARE_LINKED_CONNECTIONS -
static int -SOCKET_CONNECT_RETRY -
static int -SOCKET_CONNECT_TIMEOUT -
static boolean -SORT_NULLS_HIGH -
static long -SPLIT_FILE_SIZE_SHIFT -
static String -SYNC_METHOD -
static boolean -TRACE_IO -
static String -USER_HOME -
static int -WEB_MAX_VALUE_LENGTH -
static boolean -lobCloseBetweenReads -
static boolean -runFinalize -
-

ALIAS_COLUMN_NAME - -

-
System property h2.aliasColumnName (default: false).
- When enabled, aliased columns (as in SELECT ID AS I FROM TEST) return the - alias (I in this case) in ResultSetMetaData.getColumnName() and 'null' in - getTableName(). If disabled, the real column name (ID in this case) and - table name is returned. This setting only affects the default mode. -
- When using different modes, this feature is disabled for compatibility - for all databases except MySQL. For MySQL, it is always enabled.
-
-

ALLOWED_CLASSES - -

-
System property h2.allowedClasses (default: *).
- Comma separated list of class names or prefixes.
-
-

ALLOW_BIG_DECIMAL_EXTENSIONS - -

-
System property h2.allowBigDecimalExtensions (default: - false).
- When enabled, classes that extend BigDecimal are supported in - PreparedStatement.setBigDecimal.
-
-

ANALYZE_AUTO - -

-
System property h2.analyzeAuto (default: 0).
- After changing this many rows, ANALYZE is automatically run for a table. - Automatically running ANALYZE is disabled if set to 0. If set to 1000, - then ANALYZE will run against each user table after about 1000 changes to - that table. The time between running ANALYZE doubles each time since - starting the database. It is not run on local temporary tables, and - tables that have a trigger on SELECT.
-
-

ANALYZE_SAMPLE - -

-
System property h2.analyzeSample (default: 10000).
- The default sample size when analyzing a table.
-
-

BIND_ADDRESS - -

-
System property h2.bindAddress (default: null).
- Comma separated list of class names or prefixes.
-
-

BROWSER - -

-
System property h2.browser (default: null).
- The preferred browser to use. If not set, the default browser is used. - For Windows, to use the Internet Explorer, set this property to 'explorer'. - For Mac OS, if the default browser is not Safari and you want to use Safari, - use: java -Dh2.browser="open,-a,Safari,%url" ....
-
-

CACHE_SIZE_DEFAULT - -

-
System property h2.cacheSizeDefault (default: 16384).
- The default cache size in KB.
-
-

CACHE_TYPE_DEFAULT - -

-
System property h2.cacheTypeDefault (default: LRU).
- How many time the cache size value is divided by two to get the index - cache size. The index cache size is calculated like this: cacheSize >> - cacheSizeIndexShift.
-
-

CHECK - -

-
System property h2.check (default: true).
- Assertions in the database engine.
-
-

CHECK2 - -

-
System property h2.check2 (default: true).
- Additional assertions in the database engine.
-
-

CLIENT_TRACE_DIRECTORY - -

-
System property h2.clientTraceDirectory (default: - trace.db/).
- Directory where the trace files of the JDBC client are stored (only for - client / server).
-
-

CONSOLE_STREAM - -

-
System property h2.consoleStream (default: true).
- H2 Console: stream query results.
-
-

DATASOURCE_TRACE_LEVEL - -

-
System property h2.dataSourceTraceLevel (default: 1).
- The trace level of the data source implementation. Default is 1 for - error.
-
-

DEFAULT_ESCAPE - -

-
System property h2.defaultEscape (default: \).
- The default escape character for LIKE comparisons. To select no escape - character, use an empty string.
-
-

DEFAULT_LOCK_MODE - -

-
System property h2.defaultLockMode (default: 3).
- The default value for the LOCK_MODE setting.
-
-

DEFAULT_MAX_LENGTH_INPLACE_LOB - -

-
System property h2.defaultMaxLengthInplaceLob - (default: 4096).
- The default maximum length of an LOB that is stored in the database file.
-
-

DEFAULT_MAX_LENGTH_INPLACE_LOB2 - -

-
System property h2.defaultMaxLengthInplaceLob2 - (default: 128).
- The default maximum length of an LOB that is stored with the record itself. - Only used if h2.lobInDatabase is enabled.
-
-

DEFAULT_MAX_MEMORY_UNDO - -

-
System property h2.defaultMaxMemoryUndo (default: 50000).
- The default value for the MAX_MEMORY_UNDO setting.
-
-

DEFAULT_MAX_OPERATION_MEMORY - -

-
System property h2.defaultMaxOperationMemory (default: - 100000).
- The default for the setting MAX_OPERATION_MEMORY.
-
-

DEFAULT_RESULT_SET_CONCURRENCY - -

-
System property h2.defaultResultSetConcurrency (default: - ResultSet.CONCUR_READ_ONLY).
- The default result set concurrency for statements created with - Connection.createStatement() or prepareStatement(String sql).
-
-

DELAY_WRONG_PASSWORD_MAX - -

-
System property h2.delayWrongPasswordMax (default: 4000).
- The maximum delay in milliseconds before an exception is thrown for using - the wrong user name or password. This slows down brute force attacks. The - delay is reset after a successful login. The value 0 means there is no - maximum delay.
-
-

DELAY_WRONG_PASSWORD_MIN - -

-
System property h2.delayWrongPasswordMin (default: 250).
- The minimum delay in milliseconds before an exception is thrown for using - the wrong user name or password. This slows down brute force attacks. The - delay is reset to this value after a successful login. Unsuccessful - logins will double the time until DELAY_WRONG_PASSWORD_MAX. - To disable the delay, set this system property to 0.
-
-

ENABLE_ANONYMOUS_SSL - -

-
System property h2.enableAnonymousSSL (default: true).
- When using SSL connection, the anonymous cipher suite - SSL_DH_anon_WITH_RC4_128_MD5 should be enabled.
-
-

ESTIMATED_FUNCTION_TABLE_ROWS - -

-
System property h2.estimatedFunctionTableRows (default: - 1000).
- The estimated number of rows in a function table (for example, CSVREAD or - FTL_SEARCH). This value is used by the optimizer.
-
-

FILE_ENCODING - -

-
System property file.encoding (default: Cp1252).
- It is usually set by the system and is the default encoding used for the - RunScript and CSV tool.
-
-

FILE_SEPARATOR - -

-
System property file.separator (default: /).
- It is usually set by the system, and used to build absolute file names.
-
-

FUNCTIONS_IN_SCHEMA - -

-
System property h2.functionsInSchema (default: - false).
- If set, all functions are stored in a schema. Specially, the SCRIPT statement - will always include the schema name in the CREATE ALIAS statement. - This is not backward compatible with H2 versions 1.2.134 and older.
-
-

IDENTIFIERS_TO_UPPER - -

-
System property h2.identifiersToUpper (default: true).
- Unquoted identifiers in SQL statements are case insensitive and converted - to uppercase.
-
-

JAVA_SPECIFICATION_VERSION - -

-
System property java.specification.version.
- It is set by the system. Examples: 1.4, 1.5, 1.6.
-
-

LARGE_RESULT_BUFFER_SIZE - -

-
System property h2.largeResultBufferSize (default: 4096).
- Buffer size for large result sets. Set this value to 0 to disable the - buffer.
-
-

LARGE_TRANSACTIONS - -

-
System property h2.largeTransactions (default: false).
- Support very large transactions
-
-

LINE_SEPARATOR - -

-
System property line.separator (default: \n).
- It is usually set by the system, and used by the script and trace tools.
-
-

LOB_FILES_PER_DIRECTORY - -

-
System property h2.lobFilesPerDirectory (default: 256).
- Maximum number of LOB files per directory.
-
-

LOB_IN_DATABASE - -

-
System property h2.lobInDatabase (default: false).
- Store LOB files in the database.
-
-

LOG_ALL_ERRORS - -

-
System property h2.logAllErrors (default: false).
- Write stack traces of any kind of error to a file.
-
-

LOG_ALL_ERRORS_FILE - -

-
System property h2.logAllErrorsFile (default: - h2errors.txt).
- File name to log errors.
-
-

MAX_COMPACT_COUNT - -

-
System property h2.maxCompactCount - (default: Integer.MAX_VALUE).
- The maximum number of pages to move when closing a database.
-
-

MAX_COMPACT_TIME - -

-
System property h2.maxCompactTime (default: 1000).
- The maximum time in milliseconds used to compact a database when closing.
-
-

MAX_FILE_RETRY - -

-
System property h2.maxFileRetry (default: 16).
- Number of times to retry file delete and rename. in Windows, files can't - be deleted if they are open. Waiting a bit can help (sometimes the - Windows Explorer opens the files for a short time) may help. Sometimes, - running garbage collection may close files if the user forgot to call - Connection.close() or InputStream.close().
-
-

MAX_MEMORY_ROWS_DISTINCT - -

-
System property h2.maxMemoryRowsDistinct (default: - Integer.MAX_VALUE).
- The maximum number of rows kept in-memory for SELECT DISTINCT queries. If - more than this number of rows are in a result set, a temporary table is - used.
-
-

MAX_RECONNECT - -

-
System property h2.maxReconnect (default: 3).
- The maximum number of tries to reconnect in a row.
-
-

MAX_TRACE_DATA_LENGTH - -

-
System property h2.maxTraceDataLength (default: 65535).
- The maximum size of a LOB value that is written as data to the trace system.
-
-

MIN_COLUMN_NAME_MAP - -

-
System property h2.minColumnNameMap (default: 3).
- The minimum number of columns where a hash table is created when result set - methods with column name (instead of column index) parameter are called.
-
-

MIN_WRITE_DELAY - -

-
System property h2.minWriteDelay (default: 5).
- The minimum write delay that causes commits to be delayed.
-
-

NIO_CLEANER_HACK - -

-
System property h2.nioCleanerHack (default: true).
- If possible, use a hack to un-map the mapped file. See also - http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4724038
-
-

NIO_LOAD_MAPPED - -

-
System property h2.nioLoadMapped (default: false).
- If the mapped buffer should be loaded when the file is opened. - This can improve performance.
-
-

OBJECT_CACHE - -

-
System property h2.objectCache (default: true).
- Cache commonly used objects (integers, strings).
-
-

OBJECT_CACHE_MAX_PER_ELEMENT_SIZE - -

-
System property h2.objectCacheMaxPerElementSize (default: - 4096).
- Maximum size of an object in the cache.
-
-

OBJECT_CACHE_SIZE - -

-
System property h2.objectCacheSize (default: 1024).
- Maximum size of an object in the cache. - This value must be a power of 2.
-
-

OPTIMIZE_DISTINCT - -

-
System property h2.optimizeDistinct (default: true).
- Improve the performance of simple DISTINCT queries if an index is - available for the given column. The optimization is used if: -
    -
  • The select is a single column query without condition
  • -
  • The query contains only one table, and no group by
  • -
  • There is only one table involved
  • -
  • There is an ascending index on the column
  • -
  • The selectivity of the column is below 20
  • -
-
-

OPTIMIZE_EVALUATABLE_SUBQUERIES - -

-
System property h2.optimizeEvaluatableSubqueries (default: - true).
- Optimize subqueries that are not dependent on the outer query.
-
-

OPTIMIZE_IN_LIST - -

-
System property h2.optimizeInList (default: true).
- Optimize IN(...) and IN(SELECT ...) comparisons. This includes - optimization for SELECT, DELETE, and UPDATE.
-
-

OPTIMIZE_IS_NULL - -

-
System property h2.optimizeIsNull (default: false).
- Use an index for condition of the form columnName IS NULL.
-
-

OPTIMIZE_OR - -

-
System property h2.optimizeOr (default: false).
- Convert (C=? OR C=?) to (C IN(?, ?)).
-
-

OPTIMIZE_SUBQUERY_CACHE - -

-
System property h2.optimizeSubqueryCache (default: true).
- Cache subquery results.
-
-

OPTIMIZE_TWO_EQUALS - -

-
System property h2.optimizeTwoEquals (default: true).
- Optimize expressions of the form A=B AND B=1. In this case, AND A=1 is - added so an index on A can be used.
-
-

PAGE_SIZE - -

-
System property h2.pageSize (default: 2048).
- The page size to use for new databases.
-
-

PAGE_STORE_INTERNAL_COUNT - -

-
System property h2.pageStoreInternalCount (default: false).
- Update the row counts on a node level.
-
-

PAGE_STORE_TRIM - -

-
System property h2.pageStoreTrim (default: true).
- Trim the database size when closing.
-
-

PG_DEFAULT_CLIENT_ENCODING - -

-
System property h2.pgClientEncoding (default: UTF-8).
- Default client encoding for PG server. It is used if the client does not - sends his encoding.
-
-

PREFIX_TEMP_FILE - -

-
System property h2.prefixTempFile (default: h2.temp).
- The prefix for temporary files in the temp directory.
-
-

RECOMPILE_ALWAYS - -

-
System property h2.recompileAlways (default: false).
- Always recompile prepared statements.
-
-

RECONNECT_CHECK_DELAY - -

-
System property h2.reconnectCheckDelay (default: 200).
- Check the .lock.db file every this many milliseconds to detect that the - database was changed. The process writing to the database must first - notify a change in the .lock.db file, then wait twice this many - milliseconds before updating the database.
-
-

REDO_BUFFER_SIZE - -

-
System property h2.redoBufferSize (default: 262144).
- Size of the redo buffer (used at startup when recovering).
-
-

RESERVE_MEMORY - -

-
System property h2.reserveMemory (default: 524288).
- This many bytes in main memory are allocated as a reserve. This reserve - is freed up when if no memory is available, so that rolling back a large - transaction is easier.
-
-

RETURN_LOB_OBJECTS - -

-
System property h2.returnLobObjects (default: true).
- When true, ResultSet.getObject for CLOB or BLOB will return a - java.sql.Clob / java.sql.Blob object. When set to false, it will return a - java.io.Reader / java.io.InputStream.
-
-

SELECT_FOR_UPDATE_MVCC - -

-
System property h2.selectForUpdateMvcc (default: false).
- If set, SELECT .. FOR UPDATE queries lock the rows when using MVCC.
-
-

SERVER_CACHED_OBJECTS - -

-
System property h2.serverCachedObjects (default: 64).
- TCP Server: number of cached objects per session.
-
-

SERVER_RESULT_SET_FETCH_SIZE - -

-
System property h2.serverResultSetFetchSize - (default: 100).
- The default result set fetch size when using the server mode.
-
-

SHARE_LINKED_CONNECTIONS - -

-
System property h2.shareLinkedConnections - (default: true).
- Linked connections should be shared, that means connections to the same - database should be used for all linked tables that connect to the same - database.
-
-

SOCKET_CONNECT_RETRY - -

-
System property h2.socketConnectRetry (default: 16).
- The number of times to retry opening a socket. Windows sometimes fails - to open a socket, see bug - http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6213296
-
-

SOCKET_CONNECT_TIMEOUT - -

-
System property h2.socketConnectTimeout (default: 2000).
- The timeout in milliseconds to connect to a server.
-
-

SORT_NULLS_HIGH - -

-
System property h2.sortNullsHigh (default: false).
- Invert the default sorting behavior for NULL values, such that NULL - values are sorted to the end of a result set in an ascending sort and to - the beginning of a result set in a descending sort.
-
-

SPLIT_FILE_SIZE_SHIFT - -

-
System property h2.splitFileSizeShift (default: 30).
- The maximum file size of a split file is 1L << x.
-
-

SYNC_METHOD - -

-
System property h2.syncMethod (default: sync).
- What method to call when closing the database, on checkpoint, and on - CHECKPOINT SYNC. The following options are supported: - "sync" (default): RandomAccessFile.getFD().sync(); - "force": RandomAccessFile.getChannel().force(true); - "forceFalse": RandomAccessFile.getChannel().force(false); - "": do not call a method (fast but there is a risk of data loss - on power failure).
-
-

TRACE_IO - -

-
System property h2.traceIO (default: false).
- Trace all I/O operations.
-
-

USER_HOME - -

-
System property user.home (empty string if not set).
- It is usually set by the system, and used as a replacement for ~ in file - names.
-
-

WEB_MAX_VALUE_LENGTH - -

-
System property h2.webMaxValueLength (default: 100000).
- The H2 Console will abbreviate (truncate) result values larger than this size. - The data in the database is not truncated, it is only to avoid out of memory - in the H2 Console application.
-
-

lobCloseBetweenReads - -

-
System property h2.lobCloseBetweenReads (default: false).
- Close LOB files between read operations.
-
-

runFinalize - -

-
System property h2.runFinalize (default: true).
- Run finalizers to detect unclosed connections.
-
-
diff --git a/tools/h2/docs/javadoc/org/h2/fulltext/FullText.FullTextTrigger.html b/tools/h2/docs/javadoc/org/h2/fulltext/FullText.FullTextTrigger.html deleted file mode 100755 index 2ce3bb2..0000000 --- a/tools/h2/docs/javadoc/org/h2/fulltext/FullText.FullTextTrigger.html +++ /dev/null @@ -1,35 +0,0 @@ - - - -FullText.FullTextTrigger - - - -
-

FullText.FullTextTrigger

-Trigger updates the index when a inserting, updating, or deleting a row.

- - - - - - - -
Methods
void -delete(Object[] row) -
Delete a row from the index.
-
void -delete(Object[] row) throws SQLException -
Delete a row from the index.
-
Parameters:
-
row - the row
-
void -insert(Object[] row) -
Add a row to the index.
-
void -insert(Object[] row) throws SQLException -
Add a row to the index.
-
Parameters:
-
row - the row
-
-
diff --git a/tools/h2/docs/javadoc/org/h2/fulltext/FullText.html b/tools/h2/docs/javadoc/org/h2/fulltext/FullText.html deleted file mode 100755 index fb02e21..0000000 --- a/tools/h2/docs/javadoc/org/h2/fulltext/FullText.html +++ /dev/null @@ -1,356 +0,0 @@ - - - -FullText - - - -
-

FullText

-This class implements the native full text search. - Most methods can be called using SQL statements as well.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Methods
static void -addWords(FullTextSettings setting, HashSet set, Reader reader) -
Add all words in the given text to the hash set.
-
static void -addWords(FullTextSettings setting, HashSet set, Reader reader) -
Add all words in the given text to the hash set.
-
Parameters:
-
setting - the fulltext settings
-
set - the hash set
-
reader - the reader
-
static void -addWords(FullTextSettings setting, HashSet set, String text) -
Add all words in the given text to the hash set.
-
static void -addWords(FullTextSettings setting, HashSet set, String text) -
Add all words in the given text to the hash set.
-
Parameters:
-
setting - the fulltext settings
-
set - the hash set
-
text - the text
-
static void -createIndex(Connection conn, String schema, String table, String columnList) -
Create a new full text index for a table and column list.
-
static void -createIndex(Connection conn, String schema, String table, String columnList) throws SQLException -
Create a new full text index for a table and column list. Each table may - only have one index at any time.
-
Parameters:
-
conn - the connection
-
schema - the schema name of the table (case sensitive)
-
table - the table name (case sensitive)
-
columnList - the column list (null for all columns)
-
static SimpleResultSet -createResultSet(boolean data) -
Create an empty search result and initialize the columns.
-
static SimpleResultSet -createResultSet(boolean data) -
Create an empty search result and initialize the columns.
-
Parameters:
-
data - true if the result set should contain the primary key data as - an array.
-
Returns:
-
the empty result set
-
static void -createTrigger(Connection conn, String schema, String table) -
Create the trigger.
-
static void -createTrigger(Connection conn, String schema, String table) throws SQLException -
Create the trigger.
-
Parameters:
-
conn - the database connection
-
schema - the schema name
-
table - the table name
-
static void -dropAll(Connection conn) -
Drops all full text indexes from the database.
-
static void -dropAll(Connection conn) throws SQLException -
Drops all full text indexes from the database.
-
Parameters:
-
conn - the connection
-
static void -dropIndex(Connection conn, String schema, String table) -
Drop an existing full text index for a table.
-
static void -dropIndex(Connection conn, String schema, String table) throws SQLException -
Drop an existing full text index for a table. This method returns - silently if no index for this table exists.
-
Parameters:
-
conn - the connection
-
schema - the schema name of the table (case sensitive)
-
table - the table name (case sensitive)
-
static boolean -hasChanged(Object[] oldRow, Object[] newRow, int[] indexColumns) -
Check if a the indexed columns of a row probably have changed.
-
static boolean -hasChanged(Object[] oldRow, Object[] newRow, int[] indexColumns) -
Check if a the indexed columns of a row probably have changed. It may - return true even if the change was minimal (for example from 0.0 to - 0.00).
-
Parameters:
-
oldRow - the old row
-
newRow - the new row
-
indexColumns - the indexed columns
-
Returns:
-
true if the indexed columns don't match
-
static void -indexExistingRows(Connection conn, String schema, String table) -
Add the existing data to the index.
-
static void -indexExistingRows(Connection conn, String schema, String table) throws SQLException -
Add the existing data to the index.
-
Parameters:
-
conn - the database connection
-
schema - the schema name
-
table - the table name
-
static void -init(Connection conn) -
Initializes full text search functionality for this database.
-
static void -init(Connection conn) throws SQLException -
Initializes full text search functionality for this database. This adds - the following Java functions to the database: -
    -
  • FT_CREATE_INDEX(schemaNameString, tableNameString, - columnListString)
  • -
  • FT_SEARCH(queryString, limitInt, offsetInt): result set
  • -
  • FT_REINDEX()
  • -
  • FT_DROP_ALL()
  • -
- It also adds a schema FT to the database where bookkeeping information - is stored. This function may be called from a Java application, or by - using the SQL statements: - -
- CREATE ALIAS IF NOT EXISTS FT_INIT FOR
-      "org.h2.fulltext.FullText.init";
- CALL FT_INIT();
-
Parameters:
-
conn - the connection
-
static Object[][] -parseKey(Connection conn, String key) -
Parse a primary key condition into the primary key columns.
-
static Object[][] -parseKey(Connection conn, String key) -
Parse a primary key condition into the primary key columns.
-
Parameters:
-
conn - the database connection
-
key - the primary key condition as a string
-
Returns:
-
an array containing the column name list and the data list
-
static void -reindex(Connection conn) -
Re-creates the full text index for this database.
-
static void -reindex(Connection conn) throws SQLException -
Re-creates the full text index for this database. Calling this method is - usually not needed, as the index is kept up-to-date automatically.
-
Parameters:
-
conn - the connection
-
static void -removeAllTriggers(Connection conn, String prefix) -
Remove all triggers that start with the given prefix.
-
static void -removeAllTriggers(Connection conn, String prefix) throws SQLException -
Remove all triggers that start with the given prefix.
-
Parameters:
-
conn - the database connection
-
prefix - the prefix
-
static ResultSet -search(Connection conn, String text, int limit, int offset) -
Searches from the full text index for this database.
-
static ResultSet -search(Connection conn, String text, int limit, int offset) throws SQLException -
Searches from the full text index for this database. - The returned result set has the following column: -
  • QUERY (varchar): the query to use to get the data. - The query does not include 'SELECT * FROM '. Example: - PUBLIC.TEST WHERE ID = 1 -
  • SCORE (float) the relevance score. This value is always 1.0 - for the native fulltext search. -
-
Parameters:
-
conn - the connection
-
text - the search query
-
limit - the maximum number of rows or 0 for no limit
-
offset - the offset or 0 for no offset
-
Returns:
-
the result set
-
static ResultSet -search(Connection conn, String text, int limit, int offset, boolean data) -
Do the search.
-
static ResultSet -search(Connection conn, String text, int limit, int offset, boolean data) throws SQLException -
Do the search.
-
Parameters:
-
conn - the database connection
-
text - the query
-
limit - the limit
-
offset - the offset
-
data - whether the raw data should be returned
-
Returns:
-
the result set
-
static ResultSet -searchData(Connection conn, String text, int limit, int offset) -
Searches from the full text index for this database.
-
static ResultSet -searchData(Connection conn, String text, int limit, int offset) throws SQLException -
Searches from the full text index for this database. The result contains - the primary key data as an array. The returned result set has the - following columns: -
    -
  • SCHEMA (varchar): the schema name. Example: PUBLIC
  • -
  • TABLE (varchar): the table name. Example: TEST
  • -
  • COLUMNS (array of varchar): comma separated list of quoted column - names. The column names are quoted if necessary. Example: (ID)
  • -
  • KEYS (array of values): comma separated list of values. Example: (1) -
  • -
  • SCORE (float) the relevance score. This value is always 1.0 - for the native fulltext search. -
  • -
-
Parameters:
-
conn - the connection
-
text - the search query
-
limit - the maximum number of rows or 0 for no limit
-
offset - the offset or 0 for no offset
-
Returns:
-
the result set
-
static void -setColumns(int[] index, ArrayList keys, ArrayList columns) -
Set the column indices of a set of keys.
-
static void -setColumns(int[] index, ArrayList keys, ArrayList columns) throws SQLException -
Set the column indices of a set of keys.
-
Parameters:
-
index - the column indices (will be modified)
-
keys - the key list
-
columns - the column list
-
static void -setIgnoreList(Connection conn, String commaSeparatedList) -
Change the ignore list.
-
static void -setIgnoreList(Connection conn, String commaSeparatedList) throws SQLException -
Change the ignore list. The ignore list is a comma separated list of - common words that must not be indexed. The default ignore list is empty. - If indexes already exist at the time this list is changed, reindex must - be called.
-
Parameters:
-
conn - the connection
-
commaSeparatedList - the list
-
static SQLException -throwException(String message) -
Throw a SQLException with the given message.
-
static SQLException -throwException(String message) throws SQLException -
Throw a SQLException with the given message.
-
Parameters:
-
message - the message
-
Returns:
-
never returns normally
-
Throws:
-
SQLException - the exception
-
-
- - - - - -
Fields
static String -FIELD_COLUMNS = "COLUMNS" -
static String -FIELD_KEYS = "KEYS" -
static String -FIELD_SCHEMA = "SCHEMA" -
static String -FIELD_SCORE = "SCORE" -
static String -FIELD_TABLE = "TABLE" -
-

FIELD_COLUMNS - = "COLUMNS" -

-
A column name of the result set returned by the searchData method.
-
-

FIELD_KEYS - = "KEYS" -

-
A column name of the result set returned by the searchData method.
-
-

FIELD_SCHEMA - = "SCHEMA" -

-
A column name of the result set returned by the searchData method.
-
-

FIELD_SCORE - = "SCORE" -

-
The hit score.
-
-

FIELD_TABLE - = "TABLE" -

-
A column name of the result set returned by the searchData method.
-
-
diff --git a/tools/h2/docs/javadoc/org/h2/fulltext/FullTextLucene.FullTextTrigger.html b/tools/h2/docs/javadoc/org/h2/fulltext/FullTextLucene.FullTextTrigger.html deleted file mode 100755 index 624b54d..0000000 --- a/tools/h2/docs/javadoc/org/h2/fulltext/FullTextLucene.FullTextTrigger.html +++ /dev/null @@ -1,35 +0,0 @@ - - - -FullTextLucene.FullTextTrigger - - - -
-

FullTextLucene.FullTextTrigger

-Trigger updates the index when a inserting, updating, or deleting a row.

- - - - - - - -
Methods
void -delete(Object[] row) -
Delete a row from the index.
-
void -delete(Object[] row) throws SQLException -
Delete a row from the index.
-
Parameters:
-
row - the row
-
void -insert(Object[] row) -
Add a row to the index.
-
void -insert(Object[] row) throws SQLException -
Add a row to the index.
-
Parameters:
-
row - the row
-
-
diff --git a/tools/h2/docs/javadoc/org/h2/fulltext/FullTextLucene.html b/tools/h2/docs/javadoc/org/h2/fulltext/FullTextLucene.html deleted file mode 100755 index fcdb571..0000000 --- a/tools/h2/docs/javadoc/org/h2/fulltext/FullTextLucene.html +++ /dev/null @@ -1,232 +0,0 @@ - - - -FullTextLucene - - - -
-

FullTextLucene

-This class implements the full text search based on Apache Lucene. - Most methods can be called using SQL statements as well.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Methods
static SQLException -convertException(Exception e) -
Convert an exception to a fulltext exception.
-
static SQLException -convertException(Exception e) -
Convert an exception to a fulltext exception.
-
Parameters:
-
e - the original exception
-
Returns:
-
the converted SQL exception
-
static void -createIndex(Connection conn, String schema, String table, String columnList) -
Create a new full text index for a table and column list.
-
static void -createIndex(Connection conn, String schema, String table, String columnList) throws SQLException -
Create a new full text index for a table and column list. Each table may - only have one index at any time.
-
Parameters:
-
conn - the connection
-
schema - the schema name of the table (case sensitive)
-
table - the table name (case sensitive)
-
columnList - the column list (null for all columns)
-
static void -createTrigger(Connection conn, String schema, String table) -
Create the trigger.
-
static void -createTrigger(Connection conn, String schema, String table) throws SQLException -
Create the trigger.
-
Parameters:
-
conn - the database connection
-
schema - the schema name
-
table - the table name
-
static void -dropAll(Connection conn) -
Drops all full text indexes from the database.
-
static void -dropAll(Connection conn) throws SQLException -
Drops all full text indexes from the database.
-
Parameters:
-
conn - the connection
-
static IndexModifier -getIndexModifier(Connection conn) -
Get the index modifier for the given connection.
-
static IndexModifier -getIndexModifier(Connection conn) throws SQLException -
Get the index modifier for the given connection.
-
Parameters:
-
conn - the connection
-
Returns:
-
the index modifier
-
static String -getIndexPath(Connection conn) -
Get the path of the Lucene index for this database.
-
static String -getIndexPath(Connection conn) throws SQLException -
Get the path of the Lucene index for this database.
-
Parameters:
-
conn - the database connection
-
Returns:
-
the path
-
static void -indexExistingRows(Connection conn, String schema, String table) -
Add the existing data to the index.
-
static void -indexExistingRows(Connection conn, String schema, String table) throws SQLException -
Add the existing data to the index.
-
Parameters:
-
conn - the database connection
-
schema - the schema name
-
table - the table name
-
static void -init(Connection conn) -
Initializes full text search functionality for this database.
-
static void -init(Connection conn) throws SQLException -
Initializes full text search functionality for this database. This adds - the following Java functions to the database: -
    -
  • FTL_CREATE_INDEX(schemaNameString, tableNameString, - columnListString)
  • -
  • FTL_SEARCH(queryString, limitInt, offsetInt): result set
  • -
  • FTL_REINDEX()
  • -
  • FTL_DROP_ALL()
  • -
- It also adds a schema FTL to the database where bookkeeping information - is stored. This function may be called from a Java application, or by - using the SQL statements: - -
- CREATE ALIAS IF NOT EXISTS FTL_INIT FOR
-      "org.h2.fulltext.FullTextLucene.init";
- CALL FTL_INIT();
-
Parameters:
-
conn - the connection
-
static void -reindex(Connection conn) -
Re-creates the full text index for this database.
-
static void -reindex(Connection conn) throws SQLException -
Re-creates the full text index for this database. Calling this method is - usually not needed, as the index is kept up-to-date automatically.
-
Parameters:
-
conn - the connection
-
static void -removeIndexModifier(IndexModifier indexModifier, String indexPath) -
Close the index modifier and remove it from the index modifier set.
-
static void -removeIndexModifier(IndexModifier indexModifier, String indexPath) throws SQLException -
Close the index modifier and remove it from the index modifier set.
-
Parameters:
-
indexModifier - the index modifier
-
indexPath - the index path
-
static ResultSet -search(Connection conn, String text, int limit, int offset) -
Searches from the full text index for this database.
-
static ResultSet -search(Connection conn, String text, int limit, int offset) throws SQLException -
Searches from the full text index for this database. - The returned result set has the following column: -
  • QUERY (varchar): the query to use to get the data. - The query does not include 'SELECT * FROM '. Example: - PUBLIC.TEST WHERE ID = 1 -
  • SCORE (float) the relevance score as returned by Lucene. -
-
Parameters:
-
conn - the connection
-
text - the search query
-
limit - the maximum number of rows or 0 for no limit
-
offset - the offset or 0 for no offset
-
Returns:
-
the result set
-
static ResultSet -search(Connection conn, String text, int limit, int offset, boolean data) -
Do the search.
-
static ResultSet -search(Connection conn, String text, int limit, int offset, boolean data) throws SQLException -
Do the search.
-
Parameters:
-
conn - the database connection
-
text - the query
-
limit - the limit
-
offset - the offset
-
data - whether the raw data should be returned
-
Returns:
-
the result set
-
static ResultSet -searchData(Connection conn, String text, int limit, int offset) -
Searches from the full text index for this database.
-
static ResultSet -searchData(Connection conn, String text, int limit, int offset) throws SQLException -
Searches from the full text index for this database. The result contains - the primary key data as an array. The returned result set has the - following columns: -
    -
  • SCHEMA (varchar): the schema name. Example: PUBLIC
  • -
  • TABLE (varchar): the table name. Example: TEST
  • -
  • COLUMNS (array of varchar): comma separated list of quoted column - names. The column names are quoted if necessary. Example: (ID)
  • -
  • KEYS (array of values): comma separated list of values. Example: (1) -
  • SCORE (float) the relevance score as returned by Lucene. -
  • -
-
Parameters:
-
conn - the connection
-
text - the search query
-
limit - the maximum number of rows or 0 for no limit
-
offset - the offset or 0 for no offset
-
Returns:
-
the result set
-
-
- -
Fields
static boolean -STORE_DOCUMENT_TEXT_IN_INDEX -
-

STORE_DOCUMENT_TEXT_IN_INDEX - -

-
Whether the text content should be stored in the Lucene index.
-
-
diff --git a/tools/h2/docs/javadoc/org/h2/fulltext/FullTextSettings.html b/tools/h2/docs/javadoc/org/h2/fulltext/FullTextSettings.html deleted file mode 100755 index 16fcab6..0000000 --- a/tools/h2/docs/javadoc/org/h2/fulltext/FullTextSettings.html +++ /dev/null @@ -1,223 +0,0 @@ - - - -FullTextSettings - - - -
-

FullTextSettings

-The global settings of a full text search.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Methods
static void -closeAll() -
Close all fulltext settings, freeing up memory.
-
static void -closeAll() -
Close all fulltext settings, freeing up memory.
-
static String -getIndexPath(Connection conn) -
Get the file system path.
-
static String -getIndexPath(Connection conn) throws SQLException -
Get the file system path.
-
Parameters:
-
conn - the connection
-
Returns:
-
the file system path
-
static FullTextSettings -getInstance(Connection conn) -
Get or create the fulltext settings for this database.
-
static FullTextSettings -getInstance(Connection conn) throws SQLException -
Get or create the fulltext settings for this database.
-
Parameters:
-
conn - the connection
-
Returns:
-
the settings
-
-FullTextSettings() -
Create a new instance.
-
-FullTextSettings() -
Create a new instance.
-
void -addIndexInfo(IndexInfo index) -
Add an index.
-
void -addIndexInfo(IndexInfo index) -
Add an index.
-
Parameters:
-
index - the index
-
String -convertWord(String word) -
Convert a word to uppercase.
-
String -convertWord(String word) -
Convert a word to uppercase. This method returns null if the word is in - the ignore list.
-
Parameters:
-
word - the word to convert and check
-
Returns:
-
the uppercase version of the word or null
-
HashSet -getIgnoreList() -
Get the ignore list.
-
HashSet -getIgnoreList() -
Get the ignore list.
-
Returns:
-
the ignore list
-
IndexInfo -getIndexInfo(int indexId) -
Get the index information for the given index id.
-
IndexInfo -getIndexInfo(int indexId) -
Get the index information for the given index id.
-
Parameters:
-
indexId - the index id
-
Returns:
-
the index info
-
HashMap -getWordList() -
Get the word list.
-
HashMap -getWordList() -
Get the word list.
-
Returns:
-
the word list
-
boolean -isInitialized() -
Get the initialized flag.
-
boolean -isInitialized() -
Get the initialized flag.
-
Returns:
-
whether this instance is initialized
-
PreparedStatement -prepare(Connection conn, String sql) -
Prepare a statement.
-
PreparedStatement -prepare(Connection conn, String sql) throws SQLException -
Prepare a statement. The statement is cached in a soft reference cache.
-
Parameters:
-
conn - the connection
-
sql - the statement
-
Returns:
-
the prepared statement
-
void -removeAllIndexes() -
Remove all indexes from the settings.
-
void -removeAllIndexes() -
Remove all indexes from the settings.
-
void -removeIndexInfo(IndexInfo index) -
Remove an index from the settings.
-
void -removeIndexInfo(IndexInfo index) -
Remove an index from the settings.
-
Parameters:
-
index - the index to remove
-
void -setInitialized(boolean b) -
Set the initialized flag.
-
void -setInitialized(boolean b) -
Set the initialized flag.
-
Parameters:
-
b - the new value
-
-
- - - - - - -
Fields
static HashMap -SETTINGS -
static SoftHashMap -cache -
static HashSet -ignoreList -
static HashMap -indexes -
static boolean -initialized -
static HashMap -words -
-

SETTINGS - -

-
The settings of open indexes.
-
-

cache - -

-
The prepared statement cache.
-
-

ignoreList - -

-
The set of words not to index (stop words).
-
-

indexes - -

-
The set of indexes in this database.
-
-

initialized - -

-
Whether this instance has been initialized.
-
-

words - -

-
The set of words / terms.
-
-
diff --git a/tools/h2/docs/javadoc/org/h2/fulltext/IndexInfo.html b/tools/h2/docs/javadoc/org/h2/fulltext/IndexInfo.html deleted file mode 100755 index 2f29718..0000000 --- a/tools/h2/docs/javadoc/org/h2/fulltext/IndexInfo.html +++ /dev/null @@ -1,61 +0,0 @@ - - - -IndexInfo - - - -
-

IndexInfo

-The settings of one full text search index.

-
- - - - - - -
Fields
static String[] -columns -
static int -id -
static int[] -indexColumns -
static int[] -keys -
static String -schema -
static String -table -
-

columns - -

-
The column names.
-
-

id - -

-
The index id.
-
-

indexColumns - -

-
The column indexes of the index columns.
-
-

keys - -

-
The column indexes of the key columns.
-
-

schema - -

-
The schema name.
-
-

table - -

-
The table name.
-
-
diff --git a/tools/h2/docs/javadoc/org/h2/jdbc/JdbcArray.html b/tools/h2/docs/javadoc/org/h2/jdbc/JdbcArray.html deleted file mode 100755 index c416268..0000000 --- a/tools/h2/docs/javadoc/org/h2/jdbc/JdbcArray.html +++ /dev/null @@ -1,168 +0,0 @@ - - - -Array - - - -
-

Array

-Represents an ARRAY value.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Methods
void -free() -
Release all resources of this object.
-
void -free() -
Release all resources of this object.
-
Object -getArray() -
Returns the value as a Java array.
-
Object -getArray() throws SQLException -
Returns the value as a Java array. - This method always returns an Object[].
-
Returns:
-
the Object array
-
Object -getArray(Map map) -
Returns the value as a Java array.
-
Object -getArray(Map map) throws SQLException -
Returns the value as a Java array. - This method always returns an Object[].
-
Parameters:
-
map - is ignored. Only empty or null maps are supported
-
Returns:
-
the Object array
-
Object -getArray(long index, int count) -
Returns the value as a Java array.
-
Object -getArray(long index, int count) throws SQLException -
Returns the value as a Java array. A subset of the array is returned, - starting from the index (1 meaning the first element) and up to the given - object count. This method always returns an Object[].
-
Parameters:
-
index - the start index of the subset (starting with 1)
-
count - the maximum number of values
-
Returns:
-
the Object array
-
Object -getArray(long index, int count, Map map) -
Returns the value as a Java array.
-
Object -getArray(long index, int count, Map map) throws SQLException -
Returns the value as a Java array. A subset of the array is returned, - starting from the index (1 meaning the first element) and up to the given - object count. This method always returns an Object[].
-
Parameters:
-
index - the start index of the subset (starting with 1)
-
count - the maximum number of values
-
map - is ignored. Only empty or null maps are supported
-
Returns:
-
the Object array
-
int -getBaseType() -
Returns the base type of the array.
-
int -getBaseType() throws SQLException -
Returns the base type of the array. This database does support mixed type - arrays and therefore there is no base type.
-
Returns:
-
Types.NULL
-
String -getBaseTypeName() -
Returns the base type name of the array.
-
String -getBaseTypeName() throws SQLException -
Returns the base type name of the array. This database does support mixed - type arrays and therefore there is no base type.
-
Returns:
-
"NULL"
-
ResultSet -getResultSet() -
Returns the value as a result set.
-
ResultSet -getResultSet() throws SQLException -
Returns the value as a result set. - The first column contains the index - (starting with 1) and the second column the value.
-
Returns:
-
the result set
-
ResultSet -getResultSet(Map map) -
Returns the value as a result set.
-
ResultSet -getResultSet(Map map) throws SQLException -
Returns the value as a result set. The first column contains the index - (starting with 1) and the second column the value.
-
Parameters:
-
map - is ignored. Only empty or null maps are supported
-
Returns:
-
the result set
-
ResultSet -getResultSet(long index, int count) -
Returns the value as a result set.
-
ResultSet -getResultSet(long index, int count) throws SQLException -
Returns the value as a result set. The first column contains the index - (starting with 1) and the second column the value. A subset of the array - is returned, starting from the index (1 meaning the first element) and - up to the given object count.
-
Parameters:
-
index - the start index of the subset (starting with 1)
-
count - the maximum number of values
-
Returns:
-
the result set
-
ResultSet -getResultSet(long index, int count, Map map) -
Returns the value as a result set.
-
ResultSet -getResultSet(long index, int count, Map map) throws SQLException -
Returns the value as a result set. - The first column contains the index - (starting with 1) and the second column the value. - A subset of the array is returned, starting from the index - (1 meaning the first element) and up to the given object count.
-
Parameters:
-
index - the start index of the subset (starting with 1)
-
count - the maximum number of values
-
map - is ignored. Only empty or null maps are supported
-
Returns:
-
the result set
-
-
diff --git a/tools/h2/docs/javadoc/org/h2/jdbc/JdbcBatchUpdateException.html b/tools/h2/docs/javadoc/org/h2/jdbc/JdbcBatchUpdateException.html deleted file mode 100755 index efc73cb..0000000 --- a/tools/h2/docs/javadoc/org/h2/jdbc/JdbcBatchUpdateException.html +++ /dev/null @@ -1,11 +0,0 @@ - - - -BatchUpdateException - - - -
-

BatchUpdateException

-Represents a batch update database exception.

-
diff --git a/tools/h2/docs/javadoc/org/h2/jdbc/JdbcBlob.html b/tools/h2/docs/javadoc/org/h2/jdbc/JdbcBlob.html deleted file mode 100755 index 4fe9ea3..0000000 --- a/tools/h2/docs/javadoc/org/h2/jdbc/JdbcBlob.html +++ /dev/null @@ -1,174 +0,0 @@ - - - -Blob - - - -
-

Blob

-Represents a BLOB value.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Methods
void -free() -
Release all resources of this object.
-
void -free() -
Release all resources of this object.
-
InputStream -getBinaryStream() -
Returns the input stream.
-
InputStream -getBinaryStream() throws SQLException -
Returns the input stream.
-
Returns:
-
the input stream
-
Throws:
-
SQLException
-
InputStream -getBinaryStream(long pos, long length) -
[Not supported] Returns the input stream, starting from an offset.
-
InputStream -getBinaryStream(long pos, long length) throws SQLException -
[Not supported] Returns the input stream, starting from an offset.
-
Parameters:
-
pos - where to start reading
-
length - the number of bytes that will be read
-
Returns:
-
the input stream to read
-
Throws:
-
SQLException
-
byte[] -getBytes(long pos, int length) -
Returns some bytes of the object.
-
byte[] -getBytes(long pos, int length) throws SQLException -
Returns some bytes of the object.
-
Parameters:
-
pos - the index, the first byte is at position 1
-
length - the number of bytes
-
Returns:
-
the bytes, at most length bytes
-
Throws:
-
SQLException
-
long -length() -
Returns the length.
-
long -length() throws SQLException -
Returns the length.
-
Returns:
-
the length
-
Throws:
-
SQLException
-
long -position(byte[] pattern, long start) -
[Not supported] Searches a pattern and return the position.
-
long -position(byte[] pattern, long start) throws SQLException -
[Not supported] Searches a pattern and return the position.
-
Parameters:
-
pattern - the pattern to search
-
start - the index, the first byte is at position 1
-
Returns:
-
the position (first byte is at position 1), or -1 for not found
-
Throws:
-
SQLException
-
long -position(Blob blobPattern, long start) -
[Not supported] Searches a pattern and return the position.
-
long -position(Blob blobPattern, long start) throws SQLException -
[Not supported] Searches a pattern and return the position.
-
Parameters:
-
blobPattern - the pattern to search
-
start - the index, the first byte is at position 1
-
Returns:
-
the position (first byte is at position 1), or -1 for not found
-
Throws:
-
SQLException
-
OutputStream -setBinaryStream(long pos) -
[Not supported] Returns an output stream.
-
OutputStream -setBinaryStream(long pos) throws SQLException -
[Not supported] Returns an output stream.
-
Parameters:
-
pos - where to start writing
-
Returns:
-
the output stream to write into
-
Throws:
-
SQLException
-
int -setBytes(long pos, byte[] bytes) -
[Not supported] Sets some bytes of the object.
-
int -setBytes(long pos, byte[] bytes) throws SQLException -
[Not supported] Sets some bytes of the object.
-
Parameters:
-
pos - the write position
-
bytes - the bytes to set
-
Returns:
-
how many bytes have been written
-
Throws:
-
SQLException
-
int -setBytes(long pos, byte[] bytes, int offset, int len) -
[Not supported] Sets some bytes of the object.
-
int -setBytes(long pos, byte[] bytes, int offset, int len) throws SQLException -
[Not supported] Sets some bytes of the object.
-
Parameters:
-
pos - the write position
-
bytes - the bytes to set
-
offset - the bytes offset
-
len - the number of bytes to write
-
Returns:
-
how many bytes have been written
-
Throws:
-
SQLException
-
void -truncate(long len) -
[Not supported] Truncates the object.
-
void -truncate(long len) throws SQLException -
[Not supported] Truncates the object.
-
Parameters:
-
len - the new length
-
Throws:
-
SQLException
-
-
diff --git a/tools/h2/docs/javadoc/org/h2/jdbc/JdbcCallableStatement.html b/tools/h2/docs/javadoc/org/h2/jdbc/JdbcCallableStatement.html deleted file mode 100755 index 4295d66..0000000 --- a/tools/h2/docs/javadoc/org/h2/jdbc/JdbcCallableStatement.html +++ /dev/null @@ -1,724 +0,0 @@ - - - -CallableStatement - - - -
-

CallableStatement

-Represents a callable statement.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Methods
Array -getArray(int parameterIndex) -
[Not supported]
-
Array -getArray(int parameterIndex) throws SQLException -
[Not supported]
-
Array -getArray(String parameterName) -
[Not supported]
-
Array -getArray(String parameterName) throws SQLException -
[Not supported]
-
BigDecimal -getBigDecimal(int parameterIndex, int scale) -
[Not supported]
-
BigDecimal -getBigDecimal(int parameterIndex, int scale) throws SQLException -
[Not supported]
-
BigDecimal -getBigDecimal(int parameterIndex) -
[Not supported]
-
BigDecimal -getBigDecimal(int parameterIndex) throws SQLException -
[Not supported]
-
BigDecimal -getBigDecimal(String parameterName) -
[Not supported]
-
BigDecimal -getBigDecimal(String parameterName) throws SQLException -
[Not supported]
-
Blob -getBlob(int parameterIndex) -
[Not supported]
-
Blob -getBlob(int parameterIndex) throws SQLException -
[Not supported]
-
Blob -getBlob(String parameterName) -
[Not supported]
-
Blob -getBlob(String parameterName) throws SQLException -
[Not supported]
-
boolean -getBoolean(int parameterIndex) -
[Not supported]
-
boolean -getBoolean(int parameterIndex) throws SQLException -
[Not supported]
-
boolean -getBoolean(String parameterName) -
[Not supported]
-
boolean -getBoolean(String parameterName) throws SQLException -
[Not supported]
-
byte -getByte(int parameterIndex) -
[Not supported]
-
byte -getByte(int parameterIndex) throws SQLException -
[Not supported]
-
byte -getByte(String parameterName) -
[Not supported]
-
byte -getByte(String parameterName) throws SQLException -
[Not supported]
-
byte[] -getBytes(int parameterIndex) -
[Not supported]
-
byte[] -getBytes(int parameterIndex) throws SQLException -
[Not supported]
-
byte[] -getBytes(String parameterName) -
[Not supported]
-
byte[] -getBytes(String parameterName) throws SQLException -
[Not supported]
-
Clob -getClob(int parameterIndex) -
[Not supported]
-
Clob -getClob(int parameterIndex) throws SQLException -
[Not supported]
-
Clob -getClob(String parameterName) -
[Not supported]
-
Clob -getClob(String parameterName) throws SQLException -
[Not supported]
-
Date -getDate(int parameterIndex) -
[Not supported]
-
Date -getDate(int parameterIndex) throws SQLException -
[Not supported]
-
Date -getDate(int parameterIndex, Calendar cal) -
[Not supported]
-
Date -getDate(int parameterIndex, Calendar cal) throws SQLException -
[Not supported]
-
Date -getDate(String parameterName, Calendar cal) -
[Not supported]
-
Date -getDate(String parameterName, Calendar cal) throws SQLException -
[Not supported]
-
Date -getDate(String parameterName) -
[Not supported]
-
Date -getDate(String parameterName) throws SQLException -
[Not supported]
-
double -getDouble(int parameterIndex) -
[Not supported]
-
double -getDouble(int parameterIndex) throws SQLException -
[Not supported]
-
double -getDouble(String parameterName) -
[Not supported]
-
double -getDouble(String parameterName) throws SQLException -
[Not supported]
-
float -getFloat(int parameterIndex) -
[Not supported]
-
float -getFloat(int parameterIndex) throws SQLException -
[Not supported]
-
float -getFloat(String parameterName) -
[Not supported]
-
float -getFloat(String parameterName) throws SQLException -
[Not supported]
-
int -getInt(int parameterIndex) -
[Not supported]
-
int -getInt(int parameterIndex) throws SQLException -
[Not supported]
-
int -getInt(String parameterName) -
[Not supported]
-
int -getInt(String parameterName) throws SQLException -
[Not supported]
-
long -getLong(int parameterIndex) -
[Not supported]
-
long -getLong(int parameterIndex) throws SQLException -
[Not supported]
-
long -getLong(String parameterName) -
[Not supported]
-
long -getLong(String parameterName) throws SQLException -
[Not supported]
-
Object -getObject(int parameterIndex) -
[Not supported]
-
Object -getObject(int parameterIndex) throws SQLException -
[Not supported]
-
Object -getObject(int parameterIndex, Map map) -
[Not supported]
-
Object -getObject(int parameterIndex, Map map) throws SQLException -
[Not supported]
-
Object -getObject(String parameterName, Map map) -
[Not supported]
-
Object -getObject(String parameterName, Map map) throws SQLException -
[Not supported]
-
Object -getObject(String parameterName) -
[Not supported]
-
Object -getObject(String parameterName) throws SQLException -
[Not supported]
-
Ref -getRef(int parameterIndex) -
[Not supported]
-
Ref -getRef(int parameterIndex) throws SQLException -
[Not supported]
-
Ref -getRef(String parameterName) -
[Not supported]
-
Ref -getRef(String parameterName) throws SQLException -
[Not supported]
-
short -getShort(int parameterIndex) -
[Not supported]
-
short -getShort(int parameterIndex) throws SQLException -
[Not supported]
-
short -getShort(String parameterName) -
[Not supported]
-
short -getShort(String parameterName) throws SQLException -
[Not supported]
-
String -getString(int parameterIndex) -
[Not supported]
-
String -getString(int parameterIndex) throws SQLException -
[Not supported]
-
String -getString(String parameterName) -
[Not supported]
-
String -getString(String parameterName) throws SQLException -
[Not supported]
-
Time -getTime(int parameterIndex) -
[Not supported]
-
Time -getTime(int parameterIndex) throws SQLException -
[Not supported]
-
Time -getTime(int parameterIndex, Calendar cal) -
[Not supported]
-
Time -getTime(int parameterIndex, Calendar cal) throws SQLException -
[Not supported]
-
Time -getTime(String parameterName, Calendar cal) -
[Not supported]
-
Time -getTime(String parameterName, Calendar cal) throws SQLException -
[Not supported]
-
Time -getTime(String parameterName) -
[Not supported]
-
Time -getTime(String parameterName) throws SQLException -
[Not supported]
-
Timestamp -getTimestamp(int parameterIndex) -
[Not supported]
-
Timestamp -getTimestamp(int parameterIndex) throws SQLException -
[Not supported]
-
Timestamp -getTimestamp(int parameterIndex, Calendar cal) -
[Not supported]
-
Timestamp -getTimestamp(int parameterIndex, Calendar cal) throws SQLException -
[Not supported]
-
Timestamp -getTimestamp(String parameterName, Calendar cal) -
[Not supported]
-
Timestamp -getTimestamp(String parameterName, Calendar cal) throws SQLException -
[Not supported]
-
Timestamp -getTimestamp(String parameterName) -
[Not supported]
-
Timestamp -getTimestamp(String parameterName) throws SQLException -
[Not supported]
-
URL -getURL(String parameterName) -
[Not supported]
-
URL -getURL(String parameterName) throws SQLException -
[Not supported]
-
URL -getURL(int parameterIndex) -
[Not supported]
-
URL -getURL(int parameterIndex) throws SQLException -
[Not supported]
-
void -registerOutParameter(int parameterIndex, int sqlType) -
[Not supported]
-
void -registerOutParameter(int parameterIndex, int sqlType) throws SQLException -
[Not supported]
-
void -registerOutParameter(int parameterIndex, int sqlType, int scale) -
[Not supported]
-
void -registerOutParameter(int parameterIndex, int sqlType, int scale) throws SQLException -
[Not supported]
-
void -registerOutParameter(int paramIndex, int sqlType, String typeName) -
[Not supported]
-
void -registerOutParameter(int paramIndex, int sqlType, String typeName) throws SQLException -
[Not supported]
-
void -registerOutParameter(String parameterName, int sqlType, String typeName) -
[Not supported]
-
void -registerOutParameter(String parameterName, int sqlType, String typeName) throws SQLException -
[Not supported]
-
void -registerOutParameter(String parameterName, int sqlType, int scale) -
[Not supported]
-
void -registerOutParameter(String parameterName, int sqlType, int scale) throws SQLException -
[Not supported]
-
void -registerOutParameter(String parameterName, int sqlType) -
[Not supported]
-
void -registerOutParameter(String parameterName, int sqlType) throws SQLException -
[Not supported]
-
void -setAsciiStream(String parameterName, InputStream x, int length) -
[Not supported]
-
void -setAsciiStream(String parameterName, InputStream x, int length) throws SQLException -
[Not supported]
-
void -setBigDecimal(String parameterName, BigDecimal x) -
[Not supported]
-
void -setBigDecimal(String parameterName, BigDecimal x) throws SQLException -
[Not supported]
-
void -setBinaryStream(String parameterName, InputStream x, int length) -
[Not supported]
-
void -setBinaryStream(String parameterName, InputStream x, int length) throws SQLException -
[Not supported]
-
void -setBoolean(String parameterName, boolean x) -
[Not supported]
-
void -setBoolean(String parameterName, boolean x) throws SQLException -
[Not supported]
-
void -setByte(String parameterName, byte x) -
[Not supported]
-
void -setByte(String parameterName, byte x) throws SQLException -
[Not supported]
-
void -setBytes(String parameterName, byte[] x) -
[Not supported]
-
void -setBytes(String parameterName, byte[] x) throws SQLException -
[Not supported]
-
void -setCharacterStream(String parameterName, Reader reader, int length) -
[Not supported]
-
void -setCharacterStream(String parameterName, Reader reader, int length) throws SQLException -
[Not supported]
-
void -setDate(String parameterName, Date x, Calendar cal) -
[Not supported]
-
void -setDate(String parameterName, Date x, Calendar cal) throws SQLException -
[Not supported]
-
void -setDate(String parameterName, Date x) -
[Not supported]
-
void -setDate(String parameterName, Date x) throws SQLException -
[Not supported]
-
void -setDouble(String parameterName, double x) -
[Not supported]
-
void -setDouble(String parameterName, double x) throws SQLException -
[Not supported]
-
void -setFloat(String parameterName, float x) -
[Not supported]
-
void -setFloat(String parameterName, float x) throws SQLException -
[Not supported]
-
void -setInt(String parameterName, int x) -
[Not supported]
-
void -setInt(String parameterName, int x) throws SQLException -
[Not supported]
-
void -setLong(String parameterName, long x) -
[Not supported]
-
void -setLong(String parameterName, long x) throws SQLException -
[Not supported]
-
void -setNull(String parameterName, int sqlType, String typeName) -
[Not supported]
-
void -setNull(String parameterName, int sqlType, String typeName) throws SQLException -
[Not supported]
-
void -setNull(String parameterName, int sqlType) -
[Not supported]
-
void -setNull(String parameterName, int sqlType) throws SQLException -
[Not supported]
-
void -setObject(String parameterName, Object x) -
[Not supported]
-
void -setObject(String parameterName, Object x) throws SQLException -
[Not supported]
-
void -setObject(String parameterName, Object x, int targetSqlType) -
[Not supported]
-
void -setObject(String parameterName, Object x, int targetSqlType) throws SQLException -
[Not supported]
-
void -setObject(String parameterName, Object x, int targetSqlType, int scale) -
[Not supported]
-
void -setObject(String parameterName, Object x, int targetSqlType, int scale) throws SQLException -
[Not supported]
-
void -setShort(String parameterName, short x) -
[Not supported]
-
void -setShort(String parameterName, short x) throws SQLException -
[Not supported]
-
void -setString(String parameterName, String x) -
[Not supported]
-
void -setString(String parameterName, String x) throws SQLException -
[Not supported]
-
void -setTime(String parameterName, Time x, Calendar cal) -
[Not supported]
-
void -setTime(String parameterName, Time x, Calendar cal) throws SQLException -
[Not supported]
-
void -setTime(String parameterName, Time x) -
[Not supported]
-
void -setTime(String parameterName, Time x) throws SQLException -
[Not supported]
-
void -setTimestamp(String parameterName, Timestamp x, Calendar cal) -
[Not supported]
-
void -setTimestamp(String parameterName, Timestamp x, Calendar cal) throws SQLException -
[Not supported]
-
void -setTimestamp(String parameterName, Timestamp x) -
[Not supported]
-
void -setTimestamp(String parameterName, Timestamp x) throws SQLException -
[Not supported]
-
void -setURL(String parameterName, URL val) -
[Not supported]
-
void -setURL(String parameterName, URL val) throws SQLException -
[Not supported]
-
boolean -wasNull() -
[Not supported]
-
boolean -wasNull() throws SQLException -
[Not supported]
-
-
diff --git a/tools/h2/docs/javadoc/org/h2/jdbc/JdbcClob.html b/tools/h2/docs/javadoc/org/h2/jdbc/JdbcClob.html deleted file mode 100755 index a8c9a03..0000000 --- a/tools/h2/docs/javadoc/org/h2/jdbc/JdbcClob.html +++ /dev/null @@ -1,132 +0,0 @@ - - - -Clob - - - -
-

Clob

-Represents a CLOB value.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Methods
void -free() -
Release all resources of this object.
-
void -free() -
Release all resources of this object.
-
InputStream -getAsciiStream() -
Returns the input stream.
-
InputStream -getAsciiStream() throws SQLException -
Returns the input stream.
-
Returns:
-
the input stream
-
Reader -getCharacterStream() -
Returns the reader.
-
Reader -getCharacterStream() throws SQLException -
Returns the reader.
-
Returns:
-
the reader
-
String -getSubString(long pos, int length) -
Returns a substring.
-
String -getSubString(long pos, int length) throws SQLException -
Returns a substring.
-
Parameters:
-
pos - the position (the first character is at position 1)
-
length - the number of characters
-
Returns:
-
the string
-
long -length() -
Returns the length.
-
long -length() throws SQLException -
Returns the length.
-
Returns:
-
the length
-
long -position(String pattern, long start) -
[Not supported] Searches a pattern and return the position.
-
long -position(String pattern, long start) throws SQLException -
[Not supported] Searches a pattern and return the position.
-
long -position(Clob clobPattern, long start) -
[Not supported] Searches a pattern and return the position.
-
long -position(Clob clobPattern, long start) throws SQLException -
[Not supported] Searches a pattern and return the position.
-
OutputStream -setAsciiStream(long pos) -
[Not supported] Returns an output stream.
-
OutputStream -setAsciiStream(long pos) throws SQLException -
[Not supported] Returns an output stream.
-
Writer -setCharacterStream(long pos) -
[Not supported] Returns a writer starting from a given position.
-
Writer -setCharacterStream(long pos) throws SQLException -
[Not supported] Returns a writer starting from a given position.
-
int -setString(long pos, String str) -
[Not supported] Sets a substring.
-
int -setString(long pos, String str) throws SQLException -
[Not supported] Sets a substring.
-
int -setString(long pos, String str, int offset, int len) -
[Not supported] Sets a substring.
-
int -setString(long pos, String str, int offset, int len) throws SQLException -
[Not supported] Sets a substring.
-
void -truncate(long len) -
[Not supported] Truncates the object.
-
void -truncate(long len) throws SQLException -
[Not supported] Truncates the object.
-
-
diff --git a/tools/h2/docs/javadoc/org/h2/jdbc/JdbcConnection.html b/tools/h2/docs/javadoc/org/h2/jdbc/JdbcConnection.html deleted file mode 100755 index 426825a..0000000 --- a/tools/h2/docs/javadoc/org/h2/jdbc/JdbcConnection.html +++ /dev/null @@ -1,575 +0,0 @@ - - - -Connection - - - -
-

Connection

-

- Represents a connection (session) to a database. -

-

- Thread safety: the connection is thread-safe, because access - is synchronized. However, for compatibility with other databases, a - connection should only be used in one thread at any time. -



- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Methods
void -clearWarnings() -
Clears all warnings.
-
void -clearWarnings() throws SQLException -
Clears all warnings.
-
void -close() -
Closes this connection.
-
void -close() throws SQLException -
Closes this connection. All open statements, prepared statements and - result sets that where created by this connection become invalid after - calling this method. If there is an uncommitted transaction, it will be - rolled back.
-
void -commit() -
Commits the current transaction.
-
void -commit() throws SQLException -
Commits the current transaction. This call has only an effect if - auto commit is switched off.
-
Throws:
-
SQLException - if the connection is closed
-
Blob -createBlob() -
Create a new empty Blob object.
-
Blob -createBlob() throws SQLException -
Create a new empty Blob object.
-
Returns:
-
the object
-
Value -createBlob(InputStream x, long length) -
Create a Blob value from this input stream.
-
Value -createBlob(InputStream x, long length) -
Create a Blob value from this input stream.
-
Parameters:
-
x - the input stream
-
length - the length (if smaller or equal than 0, all data until the - end of file is read)
-
Returns:
-
the value
-
Clob -createClob() -
Create a new empty Clob object.
-
Clob -createClob() throws SQLException -
Create a new empty Clob object.
-
Returns:
-
the object
-
Value -createClob(Reader x, long length) -
Create a Clob value from this reader.
-
Value -createClob(Reader x, long length) -
Create a Clob value from this reader.
-
Parameters:
-
x - the reader
-
length - the length (if smaller or equal than 0, all data until the - end of file is read)
-
Returns:
-
the value
-
Statement -createStatement() -
Creates a new statement.
-
Statement -createStatement() throws SQLException -
Creates a new statement.
-
Returns:
-
the new statement
-
Throws:
-
SQLException - if the connection is closed
-
Statement -createStatement(int resultSetType, int resultSetConcurrency) -
Creates a statement with the specified result set type and concurrency.
-
Statement -createStatement(int resultSetType, int resultSetConcurrency) throws SQLException -
Creates a statement with the specified result set type and concurrency.
-
Returns:
-
the statement
-
Throws:
-
SQLException - if the connection is closed or the result set type or - concurrency are not supported
-
Statement -createStatement(int resultSetType, int resultSetConcurrency, int resultSetHoldability) -
Creates a statement with the specified result set type, concurrency, and - holdability.
-
Statement -createStatement(int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException -
Creates a statement with the specified result set type, concurrency, and - holdability.
-
Returns:
-
the statement
-
Throws:
-
SQLException - if the connection is closed or the result set type, - concurrency, or holdability are not supported
-
boolean -getAutoCommit() -
Gets the current setting for auto commit.
-
boolean -getAutoCommit() throws SQLException -
Gets the current setting for auto commit.
-
Returns:
-
true for on, false for off
-
Throws:
-
SQLException - if the connection is closed
-
String -getCatalog() -
Gets the current catalog name.
-
String -getCatalog() throws SQLException -
Gets the current catalog name.
-
Returns:
-
the catalog name
-
Throws:
-
SQLException - if the connection is closed
-
int -getHoldability() -
Returns the current result set holdability.
-
int -getHoldability() throws SQLException -
Returns the current result set holdability.
-
Returns:
-
the holdability
-
Throws:
-
SQLException - if the connection is closed
-
DatabaseMetaData -getMetaData() -
Gets the database meta data for this database.
-
DatabaseMetaData -getMetaData() throws SQLException -
Gets the database meta data for this database.
-
Returns:
-
the database meta data
-
Throws:
-
SQLException - if the connection is closed
-
int -getTransactionIsolation() -
Returns the current transaction isolation level.
-
int -getTransactionIsolation() throws SQLException -
Returns the current transaction isolation level.
-
Returns:
-
the isolation level.
-
Throws:
-
SQLException - if the connection is closed
-
Map -getTypeMap() -
Gets the type map.
-
Map -getTypeMap() throws SQLException -
Gets the type map.
-
Returns:
-
null
-
Throws:
-
SQLException - if the connection is closed
-
SQLWarning -getWarnings() -
Gets the first warning reported by calls on this object.
-
SQLWarning -getWarnings() throws SQLException -
Gets the first warning reported by calls on this object.
-
Returns:
-
null
-
boolean -isClosed() -
Returns true if this connection has been closed.
-
boolean -isClosed() throws SQLException -
Returns true if this connection has been closed.
-
Returns:
-
true if close was called
-
boolean -isReadOnly() -
Returns true if the database is read-only.
-
boolean -isReadOnly() throws SQLException -
Returns true if the database is read-only.
-
Returns:
-
if the database is read-only
-
Throws:
-
SQLException - if the connection is closed
-
boolean -isValid(int timeout) -
Returns true if this connection is still valid.
-
boolean -isValid(int timeout) -
Returns true if this connection is still valid.
-
Parameters:
-
timeout - the number of seconds to wait for the database to respond - (ignored)
-
Returns:
-
true if the connection is valid.
-
String -nativeSQL(String sql) -
Translates a SQL statement into the database grammar.
-
String -nativeSQL(String sql) throws SQLException -
Translates a SQL statement into the database grammar.
-
Returns:
-
the translated statement
-
Throws:
-
SQLException - if the connection is closed
-
CallableStatement -prepareCall(String sql) -
Creates a new callable statement.
-
CallableStatement -prepareCall(String sql) throws SQLException -
Creates a new callable statement.
-
Returns:
-
the callable statement
-
Throws:
-
SQLException - if the connection is closed or the statement is not valid
-
CallableStatement -prepareCall(String sql, int resultSetType, int resultSetConcurrency) -
Creates a callable statement with the specified result set type and - concurrency.
-
CallableStatement -prepareCall(String sql, int resultSetType, int resultSetConcurrency) throws SQLException -
Creates a callable statement with the specified result set type and - concurrency.
-
Returns:
-
the callable statement
-
Throws:
-
SQLException - if the connection is closed or the result set type or - concurrency are not supported
-
CallableStatement -prepareCall(String sql, int resultSetType, int resultSetConcurrency, int resultSetHoldability) -
Creates a callable statement with the specified result set type, - concurrency, and holdability.
-
CallableStatement -prepareCall(String sql, int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException -
Creates a callable statement with the specified result set type, - concurrency, and holdability.
-
Returns:
-
the callable statement
-
Throws:
-
SQLException - if the connection is closed or the result set type, - concurrency, or holdability are not supported
-
PreparedStatement -prepareStatement(String sql) -
Creates a new prepared statement.
-
PreparedStatement -prepareStatement(String sql) throws SQLException -
Creates a new prepared statement.
-
Returns:
-
the prepared statement
-
Throws:
-
SQLException - if the connection is closed
-
PreparedStatement -prepareStatement(String sql, int resultSetType, int resultSetConcurrency) -
Creates a prepared statement with the specified result set type and - concurrency.
-
PreparedStatement -prepareStatement(String sql, int resultSetType, int resultSetConcurrency) throws SQLException -
Creates a prepared statement with the specified result set type and - concurrency.
-
Returns:
-
the prepared statement
-
Throws:
-
SQLException - if the connection is closed or the result set type or - concurrency are not supported
-
PreparedStatement -prepareStatement(String sql, int resultSetType, int resultSetConcurrency, int resultSetHoldability) -
Creates a prepared statement with the specified result set type, - concurrency, and holdability.
-
PreparedStatement -prepareStatement(String sql, int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException -
Creates a prepared statement with the specified result set type, - concurrency, and holdability.
-
Returns:
-
the prepared statement
-
Throws:
-
SQLException - if the connection is closed or the result set type, - concurrency, or holdability are not supported
-
PreparedStatement -prepareStatement(String sql, int autoGeneratedKeys) -
Creates a new prepared statement.
-
PreparedStatement -prepareStatement(String sql, int autoGeneratedKeys) throws SQLException -
Creates a new prepared statement. This method just calls - prepareStatement(String sql).
-
Returns:
-
the prepared statement
-
Throws:
-
SQLException - if the connection is closed
-
PreparedStatement -prepareStatement(String sql, int[] columnIndexes) -
Creates a new prepared statement.
-
PreparedStatement -prepareStatement(String sql, int[] columnIndexes) throws SQLException -
Creates a new prepared statement. This method just calls - prepareStatement(String sql).
-
Returns:
-
the prepared statement
-
Throws:
-
SQLException - if the connection is closed
-
PreparedStatement -prepareStatement(String sql, String[] columnNames) -
Creates a new prepared statement.
-
PreparedStatement -prepareStatement(String sql, String[] columnNames) throws SQLException -
Creates a new prepared statement. This method just calls - prepareStatement(String sql).
-
Returns:
-
the prepared statement
-
Throws:
-
SQLException - if the connection is closed
-
void -releaseSavepoint(Savepoint savepoint) -
Releases a savepoint.
-
void -releaseSavepoint(Savepoint savepoint) throws SQLException -
Releases a savepoint.
-
Parameters:
-
savepoint - the savepoint to release
-
void -rollback() -
Rolls back the current transaction.
-
void -rollback() throws SQLException -
Rolls back the current transaction. This call has only an effect if - auto commit is switched off.
-
Throws:
-
SQLException - if the connection is closed
-
void -rollback(Savepoint savepoint) -
Rolls back to a savepoint.
-
void -rollback(Savepoint savepoint) throws SQLException -
Rolls back to a savepoint.
-
Parameters:
-
savepoint - the savepoint
-
void -setAutoCommit(boolean autoCommit) -
Switches auto commit on or off.
-
void -setAutoCommit(boolean autoCommit) throws SQLException -
Switches auto commit on or off. Calling this function does not commit the - current transaction.
-
Parameters:
-
autoCommit - true for auto commit on, false for off
-
Throws:
-
SQLException - if the connection is closed
-
void -setCatalog(String catalog) -
Set the default catalog name.
-
void -setCatalog(String catalog) throws SQLException -
Set the default catalog name. - This call is ignored.
-
Throws:
-
SQLException - if the connection is closed
-
void -setHoldability(int holdability) -
Changes the current result set holdability.
-
void -setHoldability(int holdability) throws SQLException -
Changes the current result set holdability.
-
Parameters:
-
holdability - ResultSet.HOLD_CURSORS_OVER_COMMIT or - ResultSet.CLOSE_CURSORS_AT_COMMIT;
-
Throws:
-
SQLException - if the connection is closed or the holdability is not - supported
-
void -setReadOnly(boolean readOnly) -
According to the JDBC specs, this - setting is only a hint to the database to enable optimizations - it does - not cause writes to be prohibited.
-
void -setReadOnly(boolean readOnly) throws SQLException -
According to the JDBC specs, this - setting is only a hint to the database to enable optimizations - it does - not cause writes to be prohibited.
-
Throws:
-
SQLException - if the connection is closed
-
Savepoint -setSavepoint() -
Creates a new unnamed savepoint.
-
Savepoint -setSavepoint() throws SQLException -
Creates a new unnamed savepoint.
-
Returns:
-
the new savepoint
-
Savepoint -setSavepoint(String name) -
Creates a new named savepoint.
-
Savepoint -setSavepoint(String name) throws SQLException -
Creates a new named savepoint.
-
Parameters:
-
name - the savepoint name
-
Returns:
-
the new savepoint
-
void -setTransactionIsolation(int level) -
Changes the current transaction isolation level.
-
void -setTransactionIsolation(int level) throws SQLException -
Changes the current transaction isolation level. Calling this method will - commit an open transaction, even if the new level is the same as the old - one, except if the level is not supported. Internally, this method calls - SET LOCK_MODE. The following isolation levels are supported: -
    -
  • Connection.TRANSACTION_READ_UNCOMMITTED = SET LOCK_MODE 0: no - locking (should only be used for testing).
  • -
  • Connection.TRANSACTION_SERIALIZABLE = SET LOCK_MODE 1: table level - locking.
  • -
  • Connection.TRANSACTION_READ_COMMITTED = SET LOCK_MODE 3: table - level locking, but read locks are released immediately (default).
  • -
- This setting is not persistent. Please note that using - TRANSACTION_READ_UNCOMMITTED while at the same time using multiple - connections may result in inconsistent transactions.
-
Parameters:
-
level - the new transaction isolation level: - Connection.TRANSACTION_READ_UNCOMMITTED, - Connection.TRANSACTION_READ_COMMITTED, or - Connection.TRANSACTION_SERIALIZABLE
-
Throws:
-
SQLException - if the connection is closed or the isolation level - is not supported
-
void -setTypeMap(Map map) -
[Partially supported] Sets the type map.
-
void -setTypeMap(Map map) throws SQLException -
[Partially supported] Sets the type map. This is only supported if the - map is empty or null.
-
-
diff --git a/tools/h2/docs/javadoc/org/h2/jdbc/JdbcDatabaseMetaData.html b/tools/h2/docs/javadoc/org/h2/jdbc/JdbcDatabaseMetaData.html deleted file mode 100755 index 600f620..0000000 --- a/tools/h2/docs/javadoc/org/h2/jdbc/JdbcDatabaseMetaData.html +++ /dev/null @@ -1,2367 +0,0 @@ - - - -DatabaseMetaData - - - -
-

DatabaseMetaData

-Represents the meta data for a database.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Methods
boolean -allProceduresAreCallable() -
Checks if all procedures callable.
-
boolean -allProceduresAreCallable() -
Checks if all procedures callable.
-
Returns:
-
true
-
boolean -allTablesAreSelectable() -
Checks if it possible to query all tables returned by getTables.
-
boolean -allTablesAreSelectable() -
Checks if it possible to query all tables returned by getTables.
-
Returns:
-
true
-
boolean -autoCommitFailureClosesAllResultSets() -
Returns whether an exception while auto commit is on closes all result sets.
-
boolean -autoCommitFailureClosesAllResultSets() -
Returns whether an exception while auto commit is on closes all result sets.
-
Returns:
-
false
-
boolean -dataDefinitionCausesTransactionCommit() -
Returns whether CREATE/DROP commit an open transaction.
-
boolean -dataDefinitionCausesTransactionCommit() -
Returns whether CREATE/DROP commit an open transaction.
-
Returns:
-
true
-
boolean -dataDefinitionIgnoredInTransactions() -
Returns whether CREATE/DROP do not affect transactions.
-
boolean -dataDefinitionIgnoredInTransactions() -
Returns whether CREATE/DROP do not affect transactions.
-
Returns:
-
false
-
boolean -deletesAreDetected(int type) -
Returns whether deletes are detected.
-
boolean -deletesAreDetected(int type) -
Returns whether deletes are detected.
-
Parameters:
-
type - the result set type
-
Returns:
-
false
-
boolean -doesMaxRowSizeIncludeBlobs() -
Returns whether the maximum row size includes blobs.
-
boolean -doesMaxRowSizeIncludeBlobs() -
Returns whether the maximum row size includes blobs.
-
Returns:
-
false
-
ResultSet -getAttributes(String catalog, String schemaPattern, String typeNamePattern, String attributeNamePattern) -
[Not supported]
-
ResultSet -getAttributes(String catalog, String schemaPattern, String typeNamePattern, String attributeNamePattern) throws SQLException -
[Not supported]
-
ResultSet -getBestRowIdentifier(String catalogPattern, String schemaPattern, String tableName, int scope, boolean nullable) -
Gets the list of columns that best identifier a row in a table.
-
ResultSet -getBestRowIdentifier(String catalogPattern, String schemaPattern, String tableName, int scope, boolean nullable) throws SQLException -
Gets the list of columns that best identifier a row in a table. - The list is ordered by SCOPE. - -
    -
  • 1 SCOPE (short) scope of result (always bestRowSession) -
  • 2 COLUMN_NAME (String) column name -
  • 3 DATA_TYPE (short) SQL data type, see also java.sql.Types -
  • 4 TYPE_NAME (String) type name -
  • 5 COLUMN_SIZE (int) precision -
  • 6 BUFFER_LENGTH (int) unused -
  • 7 DECIMAL_DIGITS (short) scale -
  • 8 PSEUDO_COLUMN (short) (always bestRowNotPseudo) -
-
Parameters:
-
catalogPattern - null (to get all objects) or the catalog name
-
schemaPattern - null (to get all objects) or a schema name - (uppercase for unquoted names)
-
tableName - table name (must be specified)
-
scope - ignored
-
nullable - ignored
-
Returns:
-
the primary key index
-
Throws:
-
SQLException - if the connection is closed
-
String -getCatalogSeparator() -
Returns the catalog separator.
-
String -getCatalogSeparator() -
Returns the catalog separator.
-
Returns:
-
"."
-
String -getCatalogTerm() -
Returns the term for "catalog".
-
String -getCatalogTerm() -
Returns the term for "catalog".
-
Returns:
-
"catalog"
-
ResultSet -getCatalogs() -
Gets the list of catalogs.
-
ResultSet -getCatalogs() throws SQLException -
Gets the list of catalogs. - The result set is sorted by TABLE_CAT. - -
    -
  • 1 TABLE_CAT (String) catalog name -
-
Returns:
-
the catalog list
-
Throws:
-
SQLException - if the connection is closed
-
ResultSet -getClientInfoProperties() -
[Not supported] Returns the client info properties.
-
ResultSet -getClientInfoProperties() throws SQLException -
[Not supported] Returns the client info properties.
-
ResultSet -getColumnPrivileges(String catalogPattern, String schemaPattern, String table, String columnNamePattern) -
Gets the list of column privileges.
-
ResultSet -getColumnPrivileges(String catalogPattern, String schemaPattern, String table, String columnNamePattern) throws SQLException -
Gets the list of column privileges. The result set is sorted by - COLUMN_NAME and PRIVILEGE - -
    -
  • 1 TABLE_CAT (String) table catalog
  • -
  • 2 TABLE_SCHEM (String) table schema
  • -
  • 3 TABLE_NAME (String) table name
  • -
  • 4 COLUMN_NAME (String) column name
  • -
  • 5 GRANTOR (String) grantor of access
  • -
  • 6 GRANTEE (String) grantee of access
  • -
  • 7 PRIVILEGE (String) SELECT, INSERT, UPDATE, DELETE or REFERENCES - (only one per row)
  • -
  • 8 IS_GRANTABLE (String) YES means the grantee can grant access to - others
  • -
-
Parameters:
-
catalogPattern - null (to get all objects) or the catalog name
-
schemaPattern - null (to get all objects) or a schema name (uppercase for - unquoted names)
-
table - a table name (uppercase for unquoted names)
-
columnNamePattern - null (to get all objects) or a column name - (uppercase for unquoted names)
-
Returns:
-
the list of privileges
-
Throws:
-
SQLException - if the connection is closed
-
ResultSet -getColumns(String catalogPattern, String schemaPattern, String tableNamePattern, String columnNamePattern) -
Gets the list of columns.
-
ResultSet -getColumns(String catalogPattern, String schemaPattern, String tableNamePattern, String columnNamePattern) throws SQLException -
Gets the list of columns. The result set is sorted by TABLE_SCHEM, - TABLE_NAME, and ORDINAL_POSITION. - -
    -
  • 1 TABLE_CAT (String) table catalog
  • -
  • 2 TABLE_SCHEM (String) table schema
  • -
  • 3 TABLE_NAME (String) table name
  • -
  • 4 COLUMN_NAME (String) column name
  • -
  • 5 DATA_TYPE (short) data type (see java.sql.Types)
  • -
  • 6 TYPE_NAME (String) data type name ("INTEGER", "VARCHAR",...)
  • -
  • 7 COLUMN_SIZE (int) precision
  • -
  • 8 BUFFER_LENGTH (int) unused
  • -
  • 9 DECIMAL_DIGITS (int) scale (0 for INTEGER and VARCHAR)
  • -
  • 10 NUM_PREC_RADIX (int) radix (always 10)
  • -
  • 11 NULLABLE (int) columnNoNulls or columnNullable
  • -
  • 12 REMARKS (String) comment (always empty)
  • -
  • 13 COLUMN_DEF (String) default value
  • -
  • 14 SQL_DATA_TYPE (int) unused
  • -
  • 15 SQL_DATETIME_SUB (int) unused
  • -
  • 16 CHAR_OCTET_LENGTH (int) unused
  • -
  • 17 ORDINAL_POSITION (int) the column index (1,2,...)
  • -
  • 18 IS_NULLABLE (String) "NO" or "YES"
  • -
  • 19 SCOPE_CATALOG (String) always null
  • -
  • 20 SCOPE_SCHEMA (String) always null
  • -
  • 21 SCOPE_TABLE (String) always null
  • -
  • 22 SOURCE_DATA_TYPE (short) null
  • -
  • 23 IS_AUTOINCREMENT (String) "NO" or "YES"
  • -
-
Parameters:
-
catalogPattern - null (to get all objects) or the catalog name
-
schemaPattern - null (to get all objects) or a schema name - (uppercase for unquoted names)
-
tableNamePattern - null (to get all objects) or a table name - (uppercase for unquoted names)
-
columnNamePattern - null (to get all objects) or a column name - (uppercase for unquoted names)
-
Returns:
-
the list of columns
-
Throws:
-
SQLException - if the connection is closed
-
Connection -getConnection() -
Returns the connection that created this object.
-
Connection -getConnection() -
Returns the connection that created this object.
-
Returns:
-
the connection
-
ResultSet -getCrossReference(String primaryCatalogPattern, String primarySchemaPattern, String primaryTable, String foreignCatalogPattern, String foreignSchemaPattern, String foreignTable) -
Gets the list of foreign key columns that references a table, as well as - the list of primary key columns that are references by a table.
-
ResultSet -getCrossReference(String primaryCatalogPattern, String primarySchemaPattern, String primaryTable, String foreignCatalogPattern, String foreignSchemaPattern, String foreignTable) throws SQLException -
Gets the list of foreign key columns that references a table, as well as - the list of primary key columns that are references by a table. The - result set is sorted by FKTABLE_CAT, FKTABLE_SCHEM, FKTABLE_NAME, - FK_NAME, KEY_SEQ. - -
    -
  • 1 PKTABLE_CAT (String) primary catalog
  • -
  • 2 PKTABLE_SCHEM (String) primary schema
  • -
  • 3 PKTABLE_NAME (String) primary table
  • -
  • 4 PKCOLUMN_NAME (String) primary column
  • -
  • 5 FKTABLE_CAT (String) foreign catalog
  • -
  • 6 FKTABLE_SCHEM (String) foreign schema
  • -
  • 7 FKTABLE_NAME (String) foreign table
  • -
  • 8 FKCOLUMN_NAME (String) foreign column
  • -
  • 9 KEY_SEQ (short) sequence number (1,2,...)
  • -
  • 10 UPDATE_RULE (short) action on update (see - DatabaseMetaData.importedKey...)
  • -
  • 11 DELETE_RULE (short) action on delete (see - DatabaseMetaData.importedKey...)
  • -
  • 12 FK_NAME (String) foreign key name
  • -
  • 13 PK_NAME (String) primary key name
  • -
  • 14 DEFERRABILITY (short) deferrable or not (always - importedKeyNotDeferrable)
  • -
-
Parameters:
-
primaryCatalogPattern - null or the catalog name
-
primarySchemaPattern - the schema name of the primary table - (optional)
-
primaryTable - the name of the primary table (must be specified)
-
foreignCatalogPattern - null or the catalog name
-
foreignSchemaPattern - the schema name of the foreign table - (optional)
-
foreignTable - the name of the foreign table (must be specified)
-
Returns:
-
the result set
-
Throws:
-
SQLException - if the connection is closed
-
int -getDatabaseMajorVersion() -
Gets the major version of the database.
-
int -getDatabaseMajorVersion() -
Gets the major version of the database.
-
Returns:
-
the major version
-
int -getDatabaseMinorVersion() -
Gets the minor version of the database.
-
int -getDatabaseMinorVersion() -
Gets the minor version of the database.
-
Returns:
-
the minor version
-
String -getDatabaseProductName() -
Gets the database product name.
-
String -getDatabaseProductName() -
Gets the database product name.
-
Returns:
-
the product name ("H2")
-
String -getDatabaseProductVersion() -
Gets the product version of the database.
-
String -getDatabaseProductVersion() -
Gets the product version of the database.
-
Returns:
-
the product version
-
int -getDefaultTransactionIsolation() -
Returns the default transaction isolation level.
-
int -getDefaultTransactionIsolation() -
Returns the default transaction isolation level.
-
Returns:
-
Connection.TRANSACTION_READ_COMMITTED
-
int -getDriverMajorVersion() -
Returns the major version of this driver.
-
int -getDriverMajorVersion() -
Returns the major version of this driver.
-
Returns:
-
the major version number
-
int -getDriverMinorVersion() -
Returns the minor version of this driver.
-
int -getDriverMinorVersion() -
Returns the minor version of this driver.
-
Returns:
-
the minor version number
-
String -getDriverName() -
Gets the name of the JDBC driver.
-
String -getDriverName() -
Gets the name of the JDBC driver.
-
Returns:
-
the driver name ("H2 JDBC Driver")
-
String -getDriverVersion() -
Gets the version number of the driver.
-
String -getDriverVersion() -
Gets the version number of the driver. The format is - [MajorVersion].[MinorVersion].
-
Returns:
-
the version number
-
ResultSet -getExportedKeys(String catalogPattern, String schemaPattern, String tableName) -
Gets the list of foreign key columns that reference a table.
-
ResultSet -getExportedKeys(String catalogPattern, String schemaPattern, String tableName) throws SQLException -
Gets the list of foreign key columns that reference a table. The result - set is sorted by FKTABLE_CAT, FKTABLE_SCHEM, FKTABLE_NAME, FK_NAME, - KEY_SEQ. - -
    -
  • 1 PKTABLE_CAT (String) primary catalog
  • -
  • 2 PKTABLE_SCHEM (String) primary schema
  • -
  • 3 PKTABLE_NAME (String) primary table
  • -
  • 4 PKCOLUMN_NAME (String) primary column
  • -
  • 5 FKTABLE_CAT (String) foreign catalog
  • -
  • 6 FKTABLE_SCHEM (String) foreign schema
  • -
  • 7 FKTABLE_NAME (String) foreign table
  • -
  • 8 FKCOLUMN_NAME (String) foreign column
  • -
  • 9 KEY_SEQ (short) sequence number (1,2,...)
  • -
  • 10 UPDATE_RULE (short) action on update (see - DatabaseMetaData.importedKey...)
  • -
  • 11 DELETE_RULE (short) action on delete (see - DatabaseMetaData.importedKey...)
  • -
  • 12 FK_NAME (String) foreign key name
  • -
  • 13 PK_NAME (String) primary key name
  • -
  • 14 DEFERRABILITY (short) deferrable or not (always - importedKeyNotDeferrable)
  • -
-
Parameters:
-
catalogPattern - null or the catalog name
-
schemaPattern - the schema name of the primary table
-
tableName - the name of the primary table
-
Returns:
-
the result set
-
Throws:
-
SQLException - if the connection is closed
-
String -getExtraNameCharacters() -
Returns the characters that are allowed for identifiers in addiction to - A-Z, a-z, 0-9 and '_'.
-
String -getExtraNameCharacters() -
Returns the characters that are allowed for identifiers in addiction to - A-Z, a-z, 0-9 and '_'.
-
Returns:
-
an empty String ("")
-
String -getIdentifierQuoteString() -
Returns the string used to quote identifiers.
-
String -getIdentifierQuoteString() -
Returns the string used to quote identifiers.
-
Returns:
-
a double quote
-
ResultSet -getImportedKeys(String catalogPattern, String schemaPattern, String tableName) -
Gets the list of primary key columns that are referenced by a table.
-
ResultSet -getImportedKeys(String catalogPattern, String schemaPattern, String tableName) throws SQLException -
Gets the list of primary key columns that are referenced by a table. The - result set is sorted by PKTABLE_CAT, PKTABLE_SCHEM, PKTABLE_NAME, - FK_NAME, KEY_SEQ. - -
    -
  • 1 PKTABLE_CAT (String) primary catalog
  • -
  • 2 PKTABLE_SCHEM (String) primary schema
  • -
  • 3 PKTABLE_NAME (String) primary table
  • -
  • 4 PKCOLUMN_NAME (String) primary column
  • -
  • 5 FKTABLE_CAT (String) foreign catalog
  • -
  • 6 FKTABLE_SCHEM (String) foreign schema
  • -
  • 7 FKTABLE_NAME (String) foreign table
  • -
  • 8 FKCOLUMN_NAME (String) foreign column
  • -
  • 9 KEY_SEQ (short) sequence number (1, 2, ...)
  • -
  • 10 UPDATE_RULE (short) action on update (see - DatabaseMetaData.importedKey...)
  • -
  • 11 DELETE_RULE (short) action on delete (see - DatabaseMetaData.importedKey...)
  • -
  • 12 FK_NAME (String) foreign key name
  • -
  • 13 PK_NAME (String) primary key name
  • -
  • 14 DEFERRABILITY (short) deferrable or not (always - importedKeyNotDeferrable)
  • -
-
Parameters:
-
catalogPattern - null (to get all objects) or the catalog name
-
schemaPattern - the schema name of the foreign table
-
tableName - the name of the foreign table
-
Returns:
-
the result set
-
Throws:
-
SQLException - if the connection is closed
-
ResultSet -getIndexInfo(String catalogPattern, String schemaPattern, String tableName, boolean unique, boolean approximate) -
Gets the list of indexes for this database.
-
ResultSet -getIndexInfo(String catalogPattern, String schemaPattern, String tableName, boolean unique, boolean approximate) throws SQLException -
Gets the list of indexes for this database. The primary key index (if - there is one) is also listed, with the name PRIMARY_KEY. The result set - is sorted by NON_UNIQUE ('false' first), TYPE, TABLE_SCHEM, INDEX_NAME, - and ORDINAL_POSITION. - -
    -
  • 1 TABLE_CAT (String) table catalog
  • -
  • 2 TABLE_SCHEM (String) table schema
  • -
  • 3 TABLE_NAME (String) table name
  • -
  • 4 NON_UNIQUE (boolean) 'false' for unique, 'true' for non-unique -
  • -
  • 5 INDEX_QUALIFIER (String) index catalog
  • -
  • 6 INDEX_NAME (String) index name
  • -
  • 7 TYPE (short) the index type (always tableIndexOther)
  • -
  • 8 ORDINAL_POSITION (short) column index (1, 2, ...)
  • -
  • 9 COLUMN_NAME (String) column name
  • -
  • 10 ASC_OR_DESC (String) ascending or descending (always 'A')
  • -
  • 11 CARDINALITY (int) numbers of unique values
  • -
  • 12 PAGES (int) number of pages use (always 0)
  • -
  • 13 FILTER_CONDITION (String) filter condition (always empty)
  • -
  • 14 SORT_TYPE (int) the sort type bit map: 1=DESCENDING, - 2=NULLS_FIRST, 4=NULLS_LAST
  • -
-
Parameters:
-
catalogPattern - null or the catalog name
-
schemaPattern - null (to get all objects) or a schema name - (uppercase for unquoted names)
-
tableName - table name (must be specified)
-
unique - only unique indexes
-
approximate - is ignored
-
Returns:
-
the list of indexes and columns
-
Throws:
-
SQLException - if the connection is closed
-
int -getJDBCMajorVersion() -
Gets the major version of the supported JDBC API.
-
int -getJDBCMajorVersion() -
Gets the major version of the supported JDBC API.
-
Returns:
-
the major version (3)
-
int -getJDBCMinorVersion() -
Gets the minor version of the supported JDBC API.
-
int -getJDBCMinorVersion() -
Gets the minor version of the supported JDBC API.
-
Returns:
-
the minor version (0)
-
int -getMaxBinaryLiteralLength() -
Returns the maximum length for hex values (characters).
-
int -getMaxBinaryLiteralLength() -
Returns the maximum length for hex values (characters).
-
Returns:
-
0 for limit is unknown
-
int -getMaxCatalogNameLength() -
Returns the maximum length for a catalog name.
-
int -getMaxCatalogNameLength() -
Returns the maximum length for a catalog name.
-
Returns:
-
0 for limit is unknown
-
int -getMaxCharLiteralLength() -
Returns the maximum length for literals.
-
int -getMaxCharLiteralLength() -
Returns the maximum length for literals.
-
Returns:
-
0 for limit is unknown
-
int -getMaxColumnNameLength() -
Returns the maximum length for column names.
-
int -getMaxColumnNameLength() -
Returns the maximum length for column names.
-
Returns:
-
0 for limit is unknown
-
int -getMaxColumnsInGroupBy() -
Returns the maximum number of columns in GROUP BY.
-
int -getMaxColumnsInGroupBy() -
Returns the maximum number of columns in GROUP BY.
-
Returns:
-
0 for limit is unknown
-
int -getMaxColumnsInIndex() -
Returns the maximum number of columns in CREATE INDEX.
-
int -getMaxColumnsInIndex() -
Returns the maximum number of columns in CREATE INDEX.
-
Returns:
-
0 for limit is unknown
-
int -getMaxColumnsInOrderBy() -
Returns the maximum number of columns in ORDER BY.
-
int -getMaxColumnsInOrderBy() -
Returns the maximum number of columns in ORDER BY.
-
Returns:
-
0 for limit is unknown
-
int -getMaxColumnsInSelect() -
Returns the maximum number of columns in SELECT.
-
int -getMaxColumnsInSelect() -
Returns the maximum number of columns in SELECT.
-
Returns:
-
0 for limit is unknown
-
int -getMaxColumnsInTable() -
Returns the maximum number of columns in CREATE TABLE.
-
int -getMaxColumnsInTable() -
Returns the maximum number of columns in CREATE TABLE.
-
Returns:
-
0 for limit is unknown
-
int -getMaxConnections() -
Returns the maximum number of open connection.
-
int -getMaxConnections() -
Returns the maximum number of open connection.
-
Returns:
-
0 for limit is unknown
-
int -getMaxCursorNameLength() -
Returns the maximum length for a cursor name.
-
int -getMaxCursorNameLength() -
Returns the maximum length for a cursor name.
-
Returns:
-
0 for limit is unknown
-
int -getMaxIndexLength() -
Returns the maximum length for an index (in bytes).
-
int -getMaxIndexLength() -
Returns the maximum length for an index (in bytes).
-
Returns:
-
0 for limit is unknown
-
int -getMaxProcedureNameLength() -
Returns the maximum length for a procedure name.
-
int -getMaxProcedureNameLength() -
Returns the maximum length for a procedure name.
-
Returns:
-
0 for limit is unknown
-
int -getMaxRowSize() -
Returns the maximum size of a row (in bytes).
-
int -getMaxRowSize() -
Returns the maximum size of a row (in bytes).
-
Returns:
-
0 for limit is unknown
-
int -getMaxSchemaNameLength() -
Returns the maximum length for a schema name.
-
int -getMaxSchemaNameLength() -
Returns the maximum length for a schema name.
-
Returns:
-
0 for limit is unknown
-
int -getMaxStatementLength() -
Returns the maximum length of a statement.
-
int -getMaxStatementLength() -
Returns the maximum length of a statement.
-
Returns:
-
0 for limit is unknown
-
int -getMaxStatements() -
Returns the maximum number of open statements.
-
int -getMaxStatements() -
Returns the maximum number of open statements.
-
Returns:
-
0 for limit is unknown
-
int -getMaxTableNameLength() -
Returns the maximum length for a table name.
-
int -getMaxTableNameLength() -
Returns the maximum length for a table name.
-
Returns:
-
0 for limit is unknown
-
int -getMaxTablesInSelect() -
Returns the maximum number of tables in a SELECT.
-
int -getMaxTablesInSelect() -
Returns the maximum number of tables in a SELECT.
-
Returns:
-
0 for limit is unknown
-
int -getMaxUserNameLength() -
Returns the maximum length for a user name.
-
int -getMaxUserNameLength() -
Returns the maximum length for a user name.
-
Returns:
-
0 for limit is unknown
-
String -getNumericFunctions() -
Returns the list of numeric functions supported by this database.
-
String -getNumericFunctions() throws SQLException -
Returns the list of numeric functions supported by this database.
-
Returns:
-
the list
-
ResultSet -getPrimaryKeys(String catalogPattern, String schemaPattern, String tableName) -
Gets the primary key columns for a table.
-
ResultSet -getPrimaryKeys(String catalogPattern, String schemaPattern, String tableName) throws SQLException -
Gets the primary key columns for a table. The result set is sorted by - TABLE_SCHEM, and COLUMN_NAME (and not by KEY_SEQ). - -
    -
  • 1 TABLE_CAT (String) table catalog
  • -
  • 2 TABLE_SCHEM (String) table schema
  • -
  • 3 TABLE_NAME (String) table name
  • -
  • 4 COLUMN_NAME (String) column name
  • -
  • 5 KEY_SEQ (short) the column index of this column (1,2,...)
  • -
  • 6 PK_NAME (String) the name of the primary key index
  • -
-
Parameters:
-
catalogPattern - null or the catalog name
-
schemaPattern - null (to get all objects) or a schema name - (uppercase for unquoted names)
-
tableName - table name (must be specified)
-
Returns:
-
the list of primary key columns
-
Throws:
-
SQLException - if the connection is closed
-
ResultSet -getProcedureColumns(String catalogPattern, String schemaPattern, String procedureNamePattern, String columnNamePattern) -
Gets the list of procedure columns.
-
ResultSet -getProcedureColumns(String catalogPattern, String schemaPattern, String procedureNamePattern, String columnNamePattern) throws SQLException -
Gets the list of procedure columns. The result set is sorted by - PROCEDURE_SCHEM, PROCEDURE_NAME, NUM_INPUT_PARAMS, and POS. - There are potentially multiple procedures with the same name, each with a - different number of input parameters. - -
    -
  • 1 PROCEDURE_CAT (String) catalog
  • -
  • 2 PROCEDURE_SCHEM (String) schema
  • -
  • 3 PROCEDURE_NAME (String) name
  • -
  • 4 COLUMN_NAME (String) column name
  • -
  • 5 COLUMN_TYPE (short) column type
  • -
  • 6 DATA_TYPE (short) sql type
  • -
  • 7 TYPE_NAME (String) type name
  • -
  • 8 PRECISION (int) precision
  • -
  • 9 LENGTH (int) length
  • -
  • 10 SCALE (short) scale
  • -
  • 11 RADIX (int) always 10
  • -
  • 12 NULLABLE (short) nullable
  • -
  • 13 REMARKS (String) description
  • -
  • 14 COLUMN_DEF (String) always null
  • -
  • 15 SQL_DATA_TYPE (int) for future use, always 0
  • -
  • 16 SQL_DATETIME_SUB (int) for future use, always 0
  • -
  • 17 CHAR_OCTET_LENGTH (int) always null
  • -
  • 18 ORDINAL_POSITION (int) the parameter index - starting from 1 (0 is the return value)
  • -
  • 19 IS_NULLABLE (String) always "YES"
  • -
  • 20 SPECIFIC_NAME (String) name
  • -
-
Parameters:
-
catalogPattern - null or the catalog name
-
schemaPattern - null (to get all objects) or a schema name - (uppercase for unquoted names)
-
procedureNamePattern - the procedure name pattern
-
columnNamePattern - the procedure name pattern
-
Returns:
-
the procedure columns
-
Throws:
-
SQLException - if the connection is closed
-
String -getProcedureTerm() -
Returns the term for "procedure".
-
String -getProcedureTerm() -
Returns the term for "procedure".
-
Returns:
-
"procedure"
-
ResultSet -getProcedures(String catalogPattern, String schemaPattern, String procedureNamePattern) -
Gets the list of procedures.
-
ResultSet -getProcedures(String catalogPattern, String schemaPattern, String procedureNamePattern) throws SQLException -
Gets the list of procedures. The result set is sorted by PROCEDURE_SCHEM, - PROCEDURE_NAME, and NUM_INPUT_PARAMS. There are potentially multiple - procedures with the same name, each with a different number of input - parameters. - -
    -
  • 1 PROCEDURE_CAT (String) catalog
  • -
  • 2 PROCEDURE_SCHEM (String) schema
  • -
  • 3 PROCEDURE_NAME (String) name
  • -
  • 4 NUM_INPUT_PARAMS (int) the number of arguments
  • -
  • 5 NUM_OUTPUT_PARAMS (int) for future use, always 0
  • -
  • 6 NUM_RESULT_SETS (int) for future use, always 0
  • -
  • 7 REMARKS (String) description
  • -
  • 8 PROCEDURE_TYPE (short) if this procedure returns a result - (procedureNoResult or procedureReturnsResult)
  • -
  • 9 SPECIFIC_NAME (String) name
  • -
-
Parameters:
-
catalogPattern - null or the catalog name
-
schemaPattern - null (to get all objects) or a schema name - (uppercase for unquoted names)
-
procedureNamePattern - the procedure name pattern
-
Returns:
-
the procedures
-
Throws:
-
SQLException - if the connection is closed
-
int -getResultSetHoldability() -
Gets the result set holdability.
-
int -getResultSetHoldability() -
Gets the result set holdability.
-
Returns:
-
ResultSet.CLOSE_CURSORS_AT_COMMIT
-
String -getSQLKeywords() -
Gets the comma-separated list of all SQL keywords that are not supported - as table/column/index name, in addition to the SQL-92 keywords.
-
String -getSQLKeywords() -
Gets the comma-separated list of all SQL keywords that are not supported - as table/column/index name, in addition to the SQL-92 keywords. The list - returned is: -
- LIMIT,MINUS,ROWNUM,SYSDATE,SYSTIME,SYSTIMESTAMP,TODAY
- The complete list of keywords (including SQL-92 keywords) is: -
- CROSS, CURRENT_DATE, CURRENT_TIME, CURRENT_TIMESTAMP, DISTINCT,
- EXCEPT, EXISTS, FALSE, FOR, FROM, FULL, GROUP, HAVING, INNER,
- INTERSECT, IS, JOIN, LIKE, LIMIT, MINUS, NATURAL, NOT, NULL, ON,
- ORDER, PRIMARY, ROWNUM, SELECT, SYSDATE, SYSTIME, SYSTIMESTAMP,
- TODAY, TRUE, UNION, UNIQUE, WHERE
-
Returns:
-
a list of additional the keywords
-
int -getSQLStateType() -
Gets the SQL State type.
-
int -getSQLStateType() -
Gets the SQL State type.
-
Returns:
-
DatabaseMetaData.sqlStateSQL99
-
String -getSchemaTerm() -
Returns the term for "schema".
-
String -getSchemaTerm() -
Returns the term for "schema".
-
Returns:
-
"schema"
-
ResultSet -getSchemas() -
Gets the list of schemas.
-
ResultSet -getSchemas() throws SQLException -
Gets the list of schemas. - The result set is sorted by TABLE_SCHEM. - -
    -
  • 1 TABLE_SCHEM (String) schema name -
  • 2 TABLE_CATALOG (String) catalog name -
  • 3 IS_DEFAULT (boolean) if this is the default schema -
-
Returns:
-
the schema list
-
Throws:
-
SQLException - if the connection is closed
-
String -getSearchStringEscape() -
Returns the default escape character for DatabaseMetaData search - patterns.
-
String -getSearchStringEscape() -
Returns the default escape character for DatabaseMetaData search - patterns.
-
Returns:
-
the default escape character (always '\', independent on the - mode)
-
String -getStringFunctions() -
Returns the list of string functions supported by this database.
-
String -getStringFunctions() throws SQLException -
Returns the list of string functions supported by this database.
-
Returns:
-
the list
-
ResultSet -getSuperTables(String catalog, String schemaPattern, String tableNamePattern) -
Get the list of super tables of a table.
-
ResultSet -getSuperTables(String catalog, String schemaPattern, String tableNamePattern) throws SQLException -
Get the list of super tables of a table. This method currently returns an - empty result set. -
    -
  • 1 TABLE_CAT (String) table catalog
  • -
  • 2 TABLE_SCHEM (String) table schema
  • -
  • 3 TABLE_NAME (String) table name
  • -
  • 4 SUPERTABLE_NAME (String) the name of the super table
  • -
-
Parameters:
-
catalog - null (to get all objects) or the catalog name
-
schemaPattern - null (to get all objects) or a schema name (uppercase for - unquoted names)
-
tableNamePattern - null (to get all objects) or a table name pattern - (uppercase for unquoted names)
-
Returns:
-
an empty result set
-
ResultSet -getSuperTypes(String catalog, String schemaPattern, String typeNamePattern) -
[Not supported]
-
ResultSet -getSuperTypes(String catalog, String schemaPattern, String typeNamePattern) throws SQLException -
[Not supported]
-
String -getSystemFunctions() -
Returns the list of system functions supported by this database.
-
String -getSystemFunctions() throws SQLException -
Returns the list of system functions supported by this database.
-
Returns:
-
the list
-
ResultSet -getTablePrivileges(String catalogPattern, String schemaPattern, String tableNamePattern) -
Gets the list of table privileges.
-
ResultSet -getTablePrivileges(String catalogPattern, String schemaPattern, String tableNamePattern) throws SQLException -
Gets the list of table privileges. The result set is sorted by - TABLE_SCHEM, TABLE_NAME, and PRIVILEGE. - -
    -
  • 1 TABLE_CAT (String) table catalog
  • -
  • 2 TABLE_SCHEM (String) table schema
  • -
  • 3 TABLE_NAME (String) table name
  • -
  • 4 GRANTOR (String) grantor of access
  • -
  • 5 GRANTEE (String) grantee of access
  • -
  • 6 PRIVILEGE (String) SELECT, INSERT, UPDATE, DELETE or REFERENCES - (only one per row)
  • -
  • 7 IS_GRANTABLE (String) YES means the grantee can grant access to - others
  • -
-
Parameters:
-
catalogPattern - null (to get all objects) or the catalog name
-
schemaPattern - null (to get all objects) or a schema name - (uppercase for unquoted names)
-
tableNamePattern - null (to get all objects) or a table name - (uppercase for unquoted names)
-
Returns:
-
the list of privileges
-
Throws:
-
SQLException - if the connection is closed
-
ResultSet -getTableTypes() -
Gets the list of table types.
-
ResultSet -getTableTypes() throws SQLException -
Gets the list of table types. This call returns a result set with three - records: "SYSTEM TABLE", "TABLE", "and "VIEW". - The result set is sorted by TABLE_TYPE. - -
    -
  • 1 TABLE_TYPE (String) table type -
-
Returns:
-
the table types
-
Throws:
-
SQLException - if the connection is closed
-
ResultSet -getTables(String catalogPattern, String schemaPattern, String tableNamePattern, String[] types) -
Gets the list of tables in the database.
-
ResultSet -getTables(String catalogPattern, String schemaPattern, String tableNamePattern, String[] types) throws SQLException -
Gets the list of tables in the database. The result set is sorted by - TABLE_TYPE, TABLE_SCHEM, and TABLE_NAME. - -
    -
  • 1 TABLE_CAT (String) table catalog
  • -
  • 2 TABLE_SCHEM (String) table schema
  • -
  • 3 TABLE_NAME (String) table name
  • -
  • 4 TABLE_TYPE (String) table type
  • -
  • 5 REMARKS (String) comment
  • -
  • 6 TYPE_CAT (String) always null
  • -
  • 7 TYPE_SCHEM (String) always null
  • -
  • 8 TYPE_NAME (String) always null
  • -
  • 9 SELF_REFERENCING_COL_NAME (String) always null
  • -
  • 10 REF_GENERATION (String) always null
  • -
  • 11 SQL (String) the create table statement or NULL for systems tables -
  • -
-
Parameters:
-
catalogPattern - null (to get all objects) or the catalog name
-
schemaPattern - null (to get all objects) or a schema name - (uppercase for unquoted names)
-
tableNamePattern - null (to get all objects) or a table name - (uppercase for unquoted names)
-
types - null or a list of table types
-
Returns:
-
the list of columns
-
Throws:
-
SQLException - if the connection is closed
-
String -getTimeDateFunctions() -
Returns the list of date and time functions supported by this database.
-
String -getTimeDateFunctions() throws SQLException -
Returns the list of date and time functions supported by this database.
-
Returns:
-
the list
-
ResultSet -getTypeInfo() -
Gets the list of data types.
-
ResultSet -getTypeInfo() throws SQLException -
Gets the list of data types. The result set is sorted by DATA_TYPE and - afterwards by how closely the data type maps to the corresponding JDBC - SQL type (best match first). - -
    -
  • 1 TYPE_NAME (String) type name
  • -
  • 2 DATA_TYPE (short) SQL data type - see also java.sql.Types
  • -
  • 3 PRECISION (int) maximum precision
  • -
  • 4 LITERAL_PREFIX (String) prefix used to quote a literal
  • -
  • 5 LITERAL_SUFFIX (String) suffix used to quote a literal
  • -
  • 6 CREATE_PARAMS (String) parameters used (may be null)
  • -
  • 7 NULLABLE (short) typeNoNulls (NULL not allowed) or typeNullable -
  • -
  • 8 CASE_SENSITIVE (boolean) case sensitive
  • -
  • 9 SEARCHABLE (short) typeSearchable
  • -
  • 10 UNSIGNED_ATTRIBUTE (boolean) unsigned
  • -
  • 11 FIXED_PREC_SCALE (boolean) fixed precision
  • -
  • 12 AUTO_INCREMENT (boolean) auto increment
  • -
  • 13 LOCAL_TYPE_NAME (String) localized version of the data type
  • -
  • 14 MINIMUM_SCALE (short) minimum scale
  • -
  • 15 MAXIMUM_SCALE (short) maximum scale
  • -
  • 16 SQL_DATA_TYPE (int) unused
  • -
  • 17 SQL_DATETIME_SUB (int) unused
  • -
  • 18 NUM_PREC_RADIX (int) 2 for binary, 10 for decimal
  • -
-
Returns:
-
the list of data types
-
Throws:
-
SQLException - if the connection is closed
-
ResultSet -getUDTs(String catalog, String schemaPattern, String typeNamePattern, int[] types) -
Gets the list of user-defined data types.
-
ResultSet -getUDTs(String catalog, String schemaPattern, String typeNamePattern, int[] types) throws SQLException -
Gets the list of user-defined data types. - This call returns an empty result set. - -
    -
  • 1 TYPE_CAT (String) catalog -
  • 2 TYPE_SCHEM (String) schema -
  • 3 TYPE_NAME (String) type name -
  • 4 CLASS_NAME (String) Java class -
  • 5 DATA_TYPE (short) SQL Type - see also java.sql.Types -
  • 6 REMARKS (String) description -
  • 7 BASE_TYPE (short) base type - see also java.sql.Types -
-
Parameters:
-
catalog - ignored
-
schemaPattern - ignored
-
typeNamePattern - ignored
-
types - ignored
-
Returns:
-
an empty result set
-
Throws:
-
SQLException - if the connection is closed
-
String -getURL() -
Returns the database URL for this connection.
-
String -getURL() throws SQLException -
Returns the database URL for this connection.
-
Returns:
-
the url
-
String -getUserName() -
Returns the user name as passed to DriverManager.getConnection(url, user, - password).
-
String -getUserName() throws SQLException -
Returns the user name as passed to DriverManager.getConnection(url, user, - password).
-
Returns:
-
the user name
-
ResultSet -getVersionColumns(String catalog, String schema, String tableName) -
Get the list of columns that are update when any value is updated.
-
ResultSet -getVersionColumns(String catalog, String schema, String tableName) throws SQLException -
Get the list of columns that are update when any value is updated. - The result set is always empty. - -
    -
  • 1 SCOPE (int) not used -
  • 2 COLUMN_NAME (String) column name -
  • 3 DATA_TYPE (int) SQL data type - see also java.sql.Types -
  • 4 TYPE_NAME (String) data type name -
  • 5 COLUMN_SIZE (int) precision -
  • 6 BUFFER_LENGTH (int) length (bytes) -
  • 7 DECIMAL_DIGITS (int) scale -
  • 8 PSEUDO_COLUMN (int) is this column a pseudo column -
-
Parameters:
-
catalog - null (to get all objects) or the catalog name
-
schema - null (to get all objects) or a schema name
-
tableName - table name (must be specified)
-
Returns:
-
an empty result set
-
Throws:
-
SQLException - if the connection is closed
-
boolean -insertsAreDetected(int type) -
Returns whether inserts are detected.
-
boolean -insertsAreDetected(int type) -
Returns whether inserts are detected.
-
Parameters:
-
type - the result set type
-
Returns:
-
false
-
boolean -isCatalogAtStart() -
Returns whether the catalog is at the beginning.
-
boolean -isCatalogAtStart() -
Returns whether the catalog is at the beginning.
-
Returns:
-
true
-
boolean -isReadOnly() -
Returns the same as Connection.isReadOnly().
-
boolean -isReadOnly() throws SQLException -
Returns the same as Connection.isReadOnly().
-
Returns:
-
if read only optimization is switched on
-
boolean -locatorsUpdateCopy() -
Does the database make a copy before updating.
-
boolean -locatorsUpdateCopy() -
Does the database make a copy before updating.
-
Returns:
-
false
-
boolean -nullPlusNonNullIsNull() -
Returns whether NULL+1 is NULL or not.
-
boolean -nullPlusNonNullIsNull() -
Returns whether NULL+1 is NULL or not.
-
Returns:
-
true
-
boolean -nullsAreSortedAtEnd() -
Checks is NULL values are sorted at the end (no matter if ASC or DESC is - used).
-
boolean -nullsAreSortedAtEnd() -
Checks is NULL values are sorted at the end (no matter if ASC or DESC is - used).
-
Returns:
-
false
-
boolean -nullsAreSortedAtStart() -
Checks is NULL values are sorted at the beginning (no matter if ASC or - DESC is used).
-
boolean -nullsAreSortedAtStart() -
Checks is NULL values are sorted at the beginning (no matter if ASC or - DESC is used).
-
Returns:
-
false
-
boolean -nullsAreSortedHigh() -
Checks is NULL values are sorted high (bigger than any non-null values).
-
boolean -nullsAreSortedHigh() -
Checks is NULL values are sorted high (bigger than any non-null values).
-
Returns:
-
false by default; true if the system property h2.sortNullsHigh is - set to true
-
boolean -nullsAreSortedLow() -
Checks is NULL values are sorted low (smaller than any non-null values).
-
boolean -nullsAreSortedLow() -
Checks is NULL values are sorted low (smaller than any non-null values).
-
Returns:
-
true by default; false if the system property h2.sortNullsHigh is - set to true
-
boolean -othersDeletesAreVisible(int type) -
Returns whether other deletes are visible.
-
boolean -othersDeletesAreVisible(int type) -
Returns whether other deletes are visible.
-
Parameters:
-
type - the result set type
-
Returns:
-
false
-
boolean -othersInsertsAreVisible(int type) -
Returns whether other inserts are visible.
-
boolean -othersInsertsAreVisible(int type) -
Returns whether other inserts are visible.
-
Parameters:
-
type - the result set type
-
Returns:
-
false
-
boolean -othersUpdatesAreVisible(int type) -
Returns whether other updates are visible.
-
boolean -othersUpdatesAreVisible(int type) -
Returns whether other updates are visible.
-
Parameters:
-
type - the result set type
-
Returns:
-
false
-
boolean -ownDeletesAreVisible(int type) -
Returns whether own deletes are visible.
-
boolean -ownDeletesAreVisible(int type) -
Returns whether own deletes are visible.
-
Parameters:
-
type - the result set type
-
Returns:
-
false
-
boolean -ownInsertsAreVisible(int type) -
Returns whether own inserts are visible.
-
boolean -ownInsertsAreVisible(int type) -
Returns whether own inserts are visible.
-
Parameters:
-
type - the result set type
-
Returns:
-
false
-
boolean -ownUpdatesAreVisible(int type) -
Returns whether own updates are visible.
-
boolean -ownUpdatesAreVisible(int type) -
Returns whether own updates are visible.
-
Parameters:
-
type - the result set type
-
Returns:
-
true
-
boolean -storesLowerCaseIdentifiers() -
Checks if for CREATE TABLE Test(ID INT), getTables returns test as the - table name.
-
boolean -storesLowerCaseIdentifiers() -
Checks if for CREATE TABLE Test(ID INT), getTables returns test as the - table name.
-
Returns:
-
false
-
boolean -storesLowerCaseQuotedIdentifiers() -
Checks if for CREATE TABLE "Test"(ID INT), getTables returns test as the - table name.
-
boolean -storesLowerCaseQuotedIdentifiers() -
Checks if for CREATE TABLE "Test"(ID INT), getTables returns test as the - table name.
-
Returns:
-
false
-
boolean -storesMixedCaseIdentifiers() -
Checks if for CREATE TABLE Test(ID INT), getTables returns Test as the - table name.
-
boolean -storesMixedCaseIdentifiers() -
Checks if for CREATE TABLE Test(ID INT), getTables returns Test as the - table name.
-
Returns:
-
false
-
boolean -storesMixedCaseQuotedIdentifiers() -
Checks if for CREATE TABLE "Test"(ID INT), getTables returns Test as the - table name.
-
boolean -storesMixedCaseQuotedIdentifiers() -
Checks if for CREATE TABLE "Test"(ID INT), getTables returns Test as the - table name.
-
Returns:
-
true
-
boolean -storesUpperCaseIdentifiers() -
Checks if for CREATE TABLE Test(ID INT), getTables returns TEST as the - table name.
-
boolean -storesUpperCaseIdentifiers() -
Checks if for CREATE TABLE Test(ID INT), getTables returns TEST as the - table name.
-
Returns:
-
true
-
boolean -storesUpperCaseQuotedIdentifiers() -
Checks if for CREATE TABLE "Test"(ID INT), getTables returns TEST as the - table name.
-
boolean -storesUpperCaseQuotedIdentifiers() -
Checks if for CREATE TABLE "Test"(ID INT), getTables returns TEST as the - table name.
-
Returns:
-
false
-
boolean -supportsANSI92EntryLevelSQL() -
Returns whether SQL-92 entry level grammar is supported.
-
boolean -supportsANSI92EntryLevelSQL() -
Returns whether SQL-92 entry level grammar is supported.
-
Returns:
-
true
-
boolean -supportsANSI92FullSQL() -
Returns whether SQL-92 full level grammar is supported.
-
boolean -supportsANSI92FullSQL() -
Returns whether SQL-92 full level grammar is supported.
-
Returns:
-
false
-
boolean -supportsANSI92IntermediateSQL() -
Returns whether SQL-92 intermediate level grammar is supported.
-
boolean -supportsANSI92IntermediateSQL() -
Returns whether SQL-92 intermediate level grammar is supported.
-
Returns:
-
false
-
boolean -supportsAlterTableWithAddColumn() -
Returns whether alter table with add column is supported.
-
boolean -supportsAlterTableWithAddColumn() -
Returns whether alter table with add column is supported.
-
Returns:
-
true
-
boolean -supportsAlterTableWithDropColumn() -
Returns whether alter table with drop column is supported.
-
boolean -supportsAlterTableWithDropColumn() -
Returns whether alter table with drop column is supported.
-
Returns:
-
true
-
boolean -supportsBatchUpdates() -
Returns whether batch updates are supported.
-
boolean -supportsBatchUpdates() -
Returns whether batch updates are supported.
-
Returns:
-
true
-
boolean -supportsCatalogsInDataManipulation() -
Returns whether the catalog name in INSERT, UPDATE, DELETE is supported.
-
boolean -supportsCatalogsInDataManipulation() -
Returns whether the catalog name in INSERT, UPDATE, DELETE is supported.
-
Returns:
-
true
-
boolean -supportsCatalogsInIndexDefinitions() -
Returns whether the catalog name in CREATE INDEX is supported.
-
boolean -supportsCatalogsInIndexDefinitions() -
Returns whether the catalog name in CREATE INDEX is supported.
-
Returns:
-
true
-
boolean -supportsCatalogsInPrivilegeDefinitions() -
Returns whether the catalog name in GRANT is supported.
-
boolean -supportsCatalogsInPrivilegeDefinitions() -
Returns whether the catalog name in GRANT is supported.
-
Returns:
-
true
-
boolean -supportsCatalogsInProcedureCalls() -
Returns whether the catalog name in procedure calls is supported.
-
boolean -supportsCatalogsInProcedureCalls() -
Returns whether the catalog name in procedure calls is supported.
-
Returns:
-
false
-
boolean -supportsCatalogsInTableDefinitions() -
Returns whether the catalog name in CREATE TABLE is supported.
-
boolean -supportsCatalogsInTableDefinitions() -
Returns whether the catalog name in CREATE TABLE is supported.
-
Returns:
-
true
-
boolean -supportsColumnAliasing() -
Returns whether column aliasing is supported.
-
boolean -supportsColumnAliasing() -
Returns whether column aliasing is supported.
-
Returns:
-
true
-
boolean -supportsConvert() -
Returns whether CONVERT is supported.
-
boolean -supportsConvert() -
Returns whether CONVERT is supported.
-
Returns:
-
true
-
boolean -supportsConvert(int fromType, int toType) -
Returns whether CONVERT is supported for one datatype to another.
-
boolean -supportsConvert(int fromType, int toType) -
Returns whether CONVERT is supported for one datatype to another.
-
Parameters:
-
fromType - the source SQL type
-
toType - the target SQL type
-
Returns:
-
true
-
boolean -supportsCoreSQLGrammar() -
Returns whether ODBC Core SQL grammar is supported.
-
boolean -supportsCoreSQLGrammar() -
Returns whether ODBC Core SQL grammar is supported.
-
Returns:
-
true
-
boolean -supportsCorrelatedSubqueries() -
Returns whether correlated subqueries are supported.
-
boolean -supportsCorrelatedSubqueries() -
Returns whether correlated subqueries are supported.
-
Returns:
-
true
-
boolean -supportsDataDefinitionAndDataManipulationTransactions() -
Returns whether data manipulation and CREATE/DROP is supported in - transactions.
-
boolean -supportsDataDefinitionAndDataManipulationTransactions() -
Returns whether data manipulation and CREATE/DROP is supported in - transactions.
-
Returns:
-
false
-
boolean -supportsDataManipulationTransactionsOnly() -
Returns whether only data manipulations are supported in transactions.
-
boolean -supportsDataManipulationTransactionsOnly() -
Returns whether only data manipulations are supported in transactions.
-
Returns:
-
true
-
boolean -supportsDifferentTableCorrelationNames() -
Returns whether table correlation names (table alias) are restricted to - be different than table names.
-
boolean -supportsDifferentTableCorrelationNames() -
Returns whether table correlation names (table alias) are restricted to - be different than table names.
-
Returns:
-
false
-
boolean -supportsExpressionsInOrderBy() -
Returns whether expression in ORDER BY are supported.
-
boolean -supportsExpressionsInOrderBy() -
Returns whether expression in ORDER BY are supported.
-
Returns:
-
true
-
boolean -supportsExtendedSQLGrammar() -
Returns whether ODBC Extended SQL grammar is supported.
-
boolean -supportsExtendedSQLGrammar() -
Returns whether ODBC Extended SQL grammar is supported.
-
Returns:
-
false
-
boolean -supportsFullOuterJoins() -
Returns whether full outer joins are supported.
-
boolean -supportsFullOuterJoins() -
Returns whether full outer joins are supported.
-
Returns:
-
false
-
boolean -supportsGetGeneratedKeys() -
Does the database support getGeneratedKeys.
-
boolean -supportsGetGeneratedKeys() -
Does the database support getGeneratedKeys.
-
Returns:
-
true
-
boolean -supportsGroupBy() -
Returns whether GROUP BY is supported.
-
boolean -supportsGroupBy() -
Returns whether GROUP BY is supported.
-
Returns:
-
true
-
boolean -supportsGroupByBeyondSelect() -
Checks whether a GROUP BY clause can use columns that are not in the - SELECT clause, provided that it specifies all the columns in the SELECT - clause.
-
boolean -supportsGroupByBeyondSelect() -
Checks whether a GROUP BY clause can use columns that are not in the - SELECT clause, provided that it specifies all the columns in the SELECT - clause.
-
Returns:
-
true
-
boolean -supportsGroupByUnrelated() -
Returns whether GROUP BY is supported if the column is not in the SELECT - list.
-
boolean -supportsGroupByUnrelated() -
Returns whether GROUP BY is supported if the column is not in the SELECT - list.
-
Returns:
-
true
-
boolean -supportsIntegrityEnhancementFacility() -
Returns whether referential integrity is supported.
-
boolean -supportsIntegrityEnhancementFacility() -
Returns whether referential integrity is supported.
-
Returns:
-
true
-
boolean -supportsLikeEscapeClause() -
Returns whether LIKE...
-
boolean -supportsLikeEscapeClause() -
Returns whether LIKE... ESCAPE is supported.
-
Returns:
-
true
-
boolean -supportsLimitedOuterJoins() -
Returns whether limited outer joins are supported.
-
boolean -supportsLimitedOuterJoins() -
Returns whether limited outer joins are supported.
-
Returns:
-
true
-
boolean -supportsMinimumSQLGrammar() -
Returns whether ODBC Minimum SQL grammar is supported.
-
boolean -supportsMinimumSQLGrammar() -
Returns whether ODBC Minimum SQL grammar is supported.
-
Returns:
-
true
-
boolean -supportsMixedCaseIdentifiers() -
Checks if for CREATE TABLE Test(ID INT), getTables returns Test as the - table name.
-
boolean -supportsMixedCaseIdentifiers() -
Checks if for CREATE TABLE Test(ID INT), getTables returns Test as the - table name.
-
Returns:
-
false
-
boolean -supportsMixedCaseQuotedIdentifiers() -
Checks if a table created with CREATE TABLE "Test"(ID INT) is a different - table than a table created with CREATE TABLE TEST(ID INT).
-
boolean -supportsMixedCaseQuotedIdentifiers() -
Checks if a table created with CREATE TABLE "Test"(ID INT) is a different - table than a table created with CREATE TABLE TEST(ID INT).
-
Returns:
-
true
-
boolean -supportsMultipleOpenResults() -
Does the database support multiple open result sets.
-
boolean -supportsMultipleOpenResults() -
Does the database support multiple open result sets.
-
Returns:
-
true
-
boolean -supportsMultipleResultSets() -
Returns whether multiple result sets are supported.
-
boolean -supportsMultipleResultSets() -
Returns whether multiple result sets are supported.
-
Returns:
-
false
-
boolean -supportsMultipleTransactions() -
Returns whether multiple transactions (on different connections) are - supported.
-
boolean -supportsMultipleTransactions() -
Returns whether multiple transactions (on different connections) are - supported.
-
Returns:
-
true
-
boolean -supportsNamedParameters() -
Does the database support named parameters.
-
boolean -supportsNamedParameters() -
Does the database support named parameters.
-
Returns:
-
false
-
boolean -supportsNonNullableColumns() -
Returns whether columns with NOT NULL are supported.
-
boolean -supportsNonNullableColumns() -
Returns whether columns with NOT NULL are supported.
-
Returns:
-
true
-
boolean -supportsOpenCursorsAcrossCommit() -
Returns whether open result sets across commits are supported.
-
boolean -supportsOpenCursorsAcrossCommit() -
Returns whether open result sets across commits are supported.
-
Returns:
-
false
-
boolean -supportsOpenCursorsAcrossRollback() -
Returns whether open result sets across rollback are supported.
-
boolean -supportsOpenCursorsAcrossRollback() -
Returns whether open result sets across rollback are supported.
-
Returns:
-
false
-
boolean -supportsOpenStatementsAcrossCommit() -
Returns whether open statements across commit are supported.
-
boolean -supportsOpenStatementsAcrossCommit() -
Returns whether open statements across commit are supported.
-
Returns:
-
true
-
boolean -supportsOpenStatementsAcrossRollback() -
Returns whether open statements across rollback are supported.
-
boolean -supportsOpenStatementsAcrossRollback() -
Returns whether open statements across rollback are supported.
-
Returns:
-
true
-
boolean -supportsOrderByUnrelated() -
Returns whether ORDER BY is supported if the column is not in the SELECT - list.
-
boolean -supportsOrderByUnrelated() -
Returns whether ORDER BY is supported if the column is not in the SELECT - list.
-
Returns:
-
true
-
boolean -supportsOuterJoins() -
Returns whether outer joins are supported.
-
boolean -supportsOuterJoins() -
Returns whether outer joins are supported.
-
Returns:
-
true
-
boolean -supportsPositionedDelete() -
Returns whether positioned deletes are supported.
-
boolean -supportsPositionedDelete() -
Returns whether positioned deletes are supported.
-
Returns:
-
true
-
boolean -supportsPositionedUpdate() -
Returns whether positioned updates are supported.
-
boolean -supportsPositionedUpdate() -
Returns whether positioned updates are supported.
-
Returns:
-
true
-
boolean -supportsResultSetConcurrency(int type, int concurrency) -
Returns whether a specific result set concurrency is supported.
-
boolean -supportsResultSetConcurrency(int type, int concurrency) -
Returns whether a specific result set concurrency is supported. - ResultSet.TYPE_SCROLL_SENSITIVE is not supported.
-
Parameters:
-
type - the result set type
-
concurrency - the result set concurrency
-
Returns:
-
true if the type is not ResultSet.TYPE_SCROLL_SENSITIVE
-
boolean -supportsResultSetHoldability(int holdability) -
Does this database supports a result set holdability.
-
boolean -supportsResultSetHoldability(int holdability) -
Does this database supports a result set holdability.
-
Parameters:
-
holdability - ResultSet.HOLD_CURSORS_OVER_COMMIT or - CLOSE_CURSORS_AT_COMMIT
-
Returns:
-
true if the holdability is ResultSet.CLOSE_CURSORS_AT_COMMIT
-
boolean -supportsResultSetType(int type) -
Returns whether a specific result set type is supported.
-
boolean -supportsResultSetType(int type) -
Returns whether a specific result set type is supported. - ResultSet.TYPE_SCROLL_SENSITIVE is not supported.
-
Parameters:
-
type - the result set type
-
Returns:
-
true for all types except ResultSet.TYPE_FORWARD_ONLY
-
boolean -supportsSavepoints() -
Does the database support savepoints.
-
boolean -supportsSavepoints() -
Does the database support savepoints.
-
Returns:
-
true
-
boolean -supportsSchemasInDataManipulation() -
Returns whether the schema name in INSERT, UPDATE, DELETE is supported.
-
boolean -supportsSchemasInDataManipulation() -
Returns whether the schema name in INSERT, UPDATE, DELETE is supported.
-
Returns:
-
true
-
boolean -supportsSchemasInIndexDefinitions() -
Returns whether the schema name in CREATE INDEX is supported.
-
boolean -supportsSchemasInIndexDefinitions() -
Returns whether the schema name in CREATE INDEX is supported.
-
Returns:
-
true
-
boolean -supportsSchemasInPrivilegeDefinitions() -
Returns whether the schema name in GRANT is supported.
-
boolean -supportsSchemasInPrivilegeDefinitions() -
Returns whether the schema name in GRANT is supported.
-
Returns:
-
true
-
boolean -supportsSchemasInProcedureCalls() -
Returns whether the schema name in procedure calls is supported.
-
boolean -supportsSchemasInProcedureCalls() -
Returns whether the schema name in procedure calls is supported.
-
Returns:
-
true
-
boolean -supportsSchemasInTableDefinitions() -
Returns whether the schema name in CREATE TABLE is supported.
-
boolean -supportsSchemasInTableDefinitions() -
Returns whether the schema name in CREATE TABLE is supported.
-
Returns:
-
true
-
boolean -supportsSelectForUpdate() -
Returns whether SELECT ...
-
boolean -supportsSelectForUpdate() -
Returns whether SELECT ... FOR UPDATE is supported.
-
Returns:
-
true
-
boolean -supportsStatementPooling() -
Does the database support statement pooling.
-
boolean -supportsStatementPooling() -
Does the database support statement pooling.
-
Returns:
-
false
-
boolean -supportsStoredFunctionsUsingCallSyntax() -
Returns whether the database supports calling functions using the call syntax.
-
boolean -supportsStoredFunctionsUsingCallSyntax() -
Returns whether the database supports calling functions using the call syntax.
-
Returns:
-
true
-
boolean -supportsStoredProcedures() -
Returns whether stored procedures are supported.
-
boolean -supportsStoredProcedures() -
Returns whether stored procedures are supported.
-
Returns:
-
false
-
boolean -supportsSubqueriesInComparisons() -
Returns whether subqueries (SELECT) in comparisons are supported.
-
boolean -supportsSubqueriesInComparisons() -
Returns whether subqueries (SELECT) in comparisons are supported.
-
Returns:
-
true
-
boolean -supportsSubqueriesInExists() -
Returns whether SELECT in EXISTS is supported.
-
boolean -supportsSubqueriesInExists() -
Returns whether SELECT in EXISTS is supported.
-
Returns:
-
true
-
boolean -supportsSubqueriesInIns() -
Returns whether IN(SELECT...) is supported.
-
boolean -supportsSubqueriesInIns() -
Returns whether IN(SELECT...) is supported.
-
Returns:
-
true
-
boolean -supportsSubqueriesInQuantifieds() -
Returns whether subqueries in quantified expression are supported.
-
boolean -supportsSubqueriesInQuantifieds() -
Returns whether subqueries in quantified expression are supported.
-
Returns:
-
true
-
boolean -supportsTableCorrelationNames() -
Returns whether table correlation names (table alias) are supported.
-
boolean -supportsTableCorrelationNames() -
Returns whether table correlation names (table alias) are supported.
-
Returns:
-
true
-
boolean -supportsTransactionIsolationLevel(int level) -
Returns whether a specific transaction isolation level is supported.
-
boolean -supportsTransactionIsolationLevel(int level) -
Returns whether a specific transaction isolation level is supported.
-
Parameters:
-
level - the transaction isolation level (Connection.TRANSACTION_*)
-
Returns:
-
true
-
boolean -supportsTransactions() -
Returns whether transactions are supported.
-
boolean -supportsTransactions() -
Returns whether transactions are supported.
-
Returns:
-
true
-
boolean -supportsUnion() -
Returns whether UNION SELECT is supported.
-
boolean -supportsUnion() -
Returns whether UNION SELECT is supported.
-
Returns:
-
true
-
boolean -supportsUnionAll() -
Returns whether UNION ALL SELECT is supported.
-
boolean -supportsUnionAll() -
Returns whether UNION ALL SELECT is supported.
-
Returns:
-
true
-
boolean -updatesAreDetected(int type) -
Returns whether updates are detected.
-
boolean -updatesAreDetected(int type) -
Returns whether updates are detected.
-
Parameters:
-
type - the result set type
-
Returns:
-
false
-
boolean -usesLocalFilePerTable() -
Checks if this database use one file per table.
-
boolean -usesLocalFilePerTable() -
Checks if this database use one file per table.
-
Returns:
-
false
-
boolean -usesLocalFiles() -
Checks if this database store data in local files.
-
boolean -usesLocalFiles() -
Checks if this database store data in local files.
-
Returns:
-
true
-
-
diff --git a/tools/h2/docs/javadoc/org/h2/jdbc/JdbcParameterMetaData.html b/tools/h2/docs/javadoc/org/h2/jdbc/JdbcParameterMetaData.html deleted file mode 100755 index 09aa625..0000000 --- a/tools/h2/docs/javadoc/org/h2/jdbc/JdbcParameterMetaData.html +++ /dev/null @@ -1,136 +0,0 @@ - - - -ParameterMetaData - - - -
-

ParameterMetaData

-Information about the parameters of a prepared statement.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Methods
String -getParameterClassName(int param) -
Returns the Java class name of the parameter.
-
String -getParameterClassName(int param) throws SQLException -
Returns the Java class name of the parameter. - "java.lang.String" is returned if the type is not known.
-
Parameters:
-
param - the column index (1,2,...)
-
Returns:
-
the Java class name
-
int -getParameterCount() -
Returns the number of parameters.
-
int -getParameterCount() throws SQLException -
Returns the number of parameters.
-
Returns:
-
the number
-
int -getParameterMode(int param) -
Returns the parameter mode.
-
int -getParameterMode(int param) throws SQLException -
Returns the parameter mode. - Always returns parameterModeIn.
-
Parameters:
-
param - the column index (1,2,...)
-
Returns:
-
parameterModeIn
-
int -getParameterType(int param) -
Returns the parameter type.
-
int -getParameterType(int param) throws SQLException -
Returns the parameter type. - java.sql.Types.VARCHAR is returned if the data type is not known.
-
Parameters:
-
param - the column index (1,2,...)
-
Returns:
-
the data type
-
String -getParameterTypeName(int param) -
Returns the parameter type name.
-
String -getParameterTypeName(int param) throws SQLException -
Returns the parameter type name. - "VARCHAR" is returned if the type is not known.
-
Parameters:
-
param - the column index (1,2,...)
-
Returns:
-
the type name
-
int -getPrecision(int param) -
Returns the parameter precision.
-
int -getPrecision(int param) throws SQLException -
Returns the parameter precision. - The value 0 is returned if the precision is not known.
-
Parameters:
-
param - the column index (1,2,...)
-
Returns:
-
the precision
-
int -getScale(int param) -
Returns the parameter scale.
-
int -getScale(int param) throws SQLException -
Returns the parameter scale. - The value 0 is returned if the scale is not known.
-
Parameters:
-
param - the column index (1,2,...)
-
Returns:
-
the scale
-
int -isNullable(int param) -
Checks if this is nullable parameter.
-
int -isNullable(int param) throws SQLException -
Checks if this is nullable parameter. - Returns ResultSetMetaData.columnNullableUnknown..
-
Parameters:
-
param - the column index (1,2,...)
-
Returns:
-
ResultSetMetaData.columnNullableUnknown
-
boolean -isSigned(int param) -
Checks if this parameter is signed.
-
boolean -isSigned(int param) throws SQLException -
Checks if this parameter is signed. - It always returns true.
-
Parameters:
-
param - the column index (1,2,...)
-
Returns:
-
true
-
-
diff --git a/tools/h2/docs/javadoc/org/h2/jdbc/JdbcPreparedStatement.html b/tools/h2/docs/javadoc/org/h2/jdbc/JdbcPreparedStatement.html deleted file mode 100755 index 447c32e..0000000 --- a/tools/h2/docs/javadoc/org/h2/jdbc/JdbcPreparedStatement.html +++ /dev/null @@ -1,845 +0,0 @@ - - - -PreparedStatement - - - -
-

PreparedStatement

-Represents a prepared statement.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Methods
void -addBatch(String sql) -
Calling this method is not legal on a PreparedStatement.
-
void -addBatch(String sql) throws SQLException -
Calling this method is not legal on a PreparedStatement.
-
Throws:
-
SQLException - Unsupported Feature
-
void -addBatch() -
Adds the current settings to the batch.
-
void -addBatch() throws SQLException -
Adds the current settings to the batch.
-
boolean -checkClosed(boolean write) -
boolean -checkClosed(boolean write) throws SQLException -
-
void -clearBatch() -
Clears the batch.
-
void -clearBatch() throws SQLException -
Clears the batch.
-
void -clearParameters() -
Clears all parameters.
-
void -clearParameters() throws SQLException -
Clears all parameters.
-
Throws:
-
SQLException - if this object is closed or invalid
-
void -close() -
Closes this statement.
-
void -close() throws SQLException -
Closes this statement. - All result sets that where created by this statement - become invalid after calling this method.
-
boolean -execute() -
Executes an arbitrary statement.
-
boolean -execute() throws SQLException -
Executes an arbitrary statement. If another result set exists for this - statement, this will be closed (even if this statement fails). If auto - commit is on, and the statement is not a select, this statement will be - committed.
-
Returns:
-
true if a result set is available, false if not
-
Throws:
-
SQLException - if this object is closed or invalid
-
boolean -execute(String sql) -
Calling this method is not legal on a PreparedStatement.
-
boolean -execute(String sql) throws SQLException -
Calling this method is not legal on a PreparedStatement.
-
Throws:
-
SQLException - Unsupported Feature
-
boolean -execute(String sql, int autoGeneratedKeys) -
Calling this method is not legal on a PreparedStatement.
-
boolean -execute(String sql, int autoGeneratedKeys) throws SQLException -
Calling this method is not legal on a PreparedStatement.
-
Throws:
-
SQLException - Unsupported Feature
-
boolean -execute(String sql, int[] columnIndexes) -
Calling this method is not legal on a PreparedStatement.
-
boolean -execute(String sql, int[] columnIndexes) throws SQLException -
Calling this method is not legal on a PreparedStatement.
-
Throws:
-
SQLException - Unsupported Feature
-
boolean -execute(String sql, String[] columnNames) -
Calling this method is not legal on a PreparedStatement.
-
boolean -execute(String sql, String[] columnNames) throws SQLException -
Calling this method is not legal on a PreparedStatement.
-
Throws:
-
SQLException - Unsupported Feature
-
int[] -executeBatch() -
Executes the batch.
-
int[] -executeBatch() throws SQLException -
Executes the batch.
-
Returns:
-
the array of update counts
-
ResultSet -executeQuery() -
Executes a query (select statement) and returns the result set.
-
ResultSet -executeQuery() throws SQLException -
Executes a query (select statement) and returns the result set. If - another result set exists for this statement, this will be closed (even - if this statement fails).
-
Returns:
-
the result set
-
Throws:
-
SQLException - if this object is closed or invalid
-
ResultSet -executeQuery(String sql) -
Calling this method is not legal on a PreparedStatement.
-
ResultSet -executeQuery(String sql) throws SQLException -
Calling this method is not legal on a PreparedStatement.
-
Throws:
-
SQLException - Unsupported Feature
-
int -executeUpdate() -
Executes a statement (insert, update, delete, create, drop, commit, - rollback) and returns the update count.
-
int -executeUpdate() throws SQLException -
Executes a statement (insert, update, delete, create, drop, commit, - rollback) and returns the update count. If another result set exists for - this statement, this will be closed (even if this statement fails). - - If the statement is a create or drop and does not throw an exception, the - current transaction (if any) is committed after executing the statement. - If auto commit is on, this statement will be committed.
-
Returns:
-
the update count (number of row affected by an insert, update or - delete, or 0 if no rows or the statement was a create, drop, - commit or rollback)
-
Throws:
-
SQLException - if this object is closed or invalid
-
int -executeUpdate(String sql) -
Calling this method is not legal on a PreparedStatement.
-
int -executeUpdate(String sql) throws SQLException -
Calling this method is not legal on a PreparedStatement.
-
Throws:
-
SQLException - Unsupported Feature
-
int -executeUpdate(String sql, int autoGeneratedKeys) -
Calling this method is not legal on a PreparedStatement.
-
int -executeUpdate(String sql, int autoGeneratedKeys) throws SQLException -
Calling this method is not legal on a PreparedStatement.
-
Throws:
-
SQLException - Unsupported Feature
-
int -executeUpdate(String sql, int[] columnIndexes) -
Calling this method is not legal on a PreparedStatement.
-
int -executeUpdate(String sql, int[] columnIndexes) throws SQLException -
Calling this method is not legal on a PreparedStatement.
-
Throws:
-
SQLException - Unsupported Feature
-
int -executeUpdate(String sql, String[] columnNames) -
Calling this method is not legal on a PreparedStatement.
-
int -executeUpdate(String sql, String[] columnNames) throws SQLException -
Calling this method is not legal on a PreparedStatement.
-
Throws:
-
SQLException - Unsupported Feature
-
ResultSetMetaData -getMetaData() -
Gets the result set metadata of the query returned when the statement is - executed.
-
ResultSetMetaData -getMetaData() throws SQLException -
Gets the result set metadata of the query returned when the statement is - executed. If this is not a query, this method returns null.
-
Returns:
-
the meta data or null if this is not a query
-
Throws:
-
SQLException - if this object is closed
-
ParameterMetaData -getParameterMetaData() -
Get the parameter meta data of this prepared statement.
-
ParameterMetaData -getParameterMetaData() throws SQLException -
Get the parameter meta data of this prepared statement.
-
Returns:
-
the meta data
-
void -setArray(int parameterIndex, Array x) -
[Not supported] Sets the value of a parameter as a Array.
-
void -setArray(int parameterIndex, Array x) throws SQLException -
[Not supported] Sets the value of a parameter as a Array.
-
void -setAsciiStream(int parameterIndex, InputStream x, int length) -
Sets the value of a parameter as an ASCII stream.
-
void -setAsciiStream(int parameterIndex, InputStream x, int length) throws SQLException -
Sets the value of a parameter as an ASCII stream. - This method does not close the stream. - The stream may be closed after executing the statement.
-
Parameters:
-
parameterIndex - the parameter index (1, 2, ...)
-
x - the value
-
length - the number of bytes
-
Throws:
-
SQLException - if this object is closed
-
void -setAsciiStream(int parameterIndex, InputStream x, long length) -
Sets the value of a parameter as an ASCII stream.
-
void -setAsciiStream(int parameterIndex, InputStream x, long length) throws SQLException -
Sets the value of a parameter as an ASCII stream. - This method does not close the stream. - The stream may be closed after executing the statement.
-
Parameters:
-
parameterIndex - the parameter index (1, 2, ...)
-
x - the value
-
length - the number of bytes
-
Throws:
-
SQLException - if this object is closed
-
void -setAsciiStream(int parameterIndex, InputStream x) -
Sets the value of a parameter as an ASCII stream.
-
void -setAsciiStream(int parameterIndex, InputStream x) throws SQLException -
Sets the value of a parameter as an ASCII stream. - This method does not close the stream. - The stream may be closed after executing the statement.
-
Parameters:
-
parameterIndex - the parameter index (1, 2, ...)
-
x - the value
-
Throws:
-
SQLException - if this object is closed
-
void -setBigDecimal(int parameterIndex, BigDecimal x) -
Sets the value of a parameter.
-
void -setBigDecimal(int parameterIndex, BigDecimal x) throws SQLException -
Sets the value of a parameter.
-
Parameters:
-
parameterIndex - the parameter index (1, 2, ...)
-
x - the value
-
Throws:
-
SQLException - if this object is closed
-
void -setBinaryStream(int parameterIndex, InputStream x, long length) -
Sets the value of a parameter as an input stream.
-
void -setBinaryStream(int parameterIndex, InputStream x, long length) throws SQLException -
Sets the value of a parameter as an input stream. - This method does not close the stream. - The stream may be closed after executing the statement.
-
Parameters:
-
parameterIndex - the parameter index (1, 2, ...)
-
x - the value
-
length - the number of bytes
-
Throws:
-
SQLException - if this object is closed
-
void -setBinaryStream(int parameterIndex, InputStream x, int length) -
Sets the value of a parameter as an input stream.
-
void -setBinaryStream(int parameterIndex, InputStream x, int length) throws SQLException -
Sets the value of a parameter as an input stream. - This method does not close the stream. - The stream may be closed after executing the statement.
-
Parameters:
-
parameterIndex - the parameter index (1, 2, ...)
-
x - the value
-
length - the number of bytes
-
Throws:
-
SQLException - if this object is closed
-
void -setBinaryStream(int parameterIndex, InputStream x) -
Sets the value of a parameter as an input stream.
-
void -setBinaryStream(int parameterIndex, InputStream x) throws SQLException -
Sets the value of a parameter as an input stream. - This method does not close the stream. - The stream may be closed after executing the statement.
-
Parameters:
-
parameterIndex - the parameter index (1, 2, ...)
-
x - the value
-
Throws:
-
SQLException - if this object is closed
-
void -setBlob(int parameterIndex, Blob x) -
Sets the value of a parameter as a Blob.
-
void -setBlob(int parameterIndex, Blob x) throws SQLException -
Sets the value of a parameter as a Blob.
-
Parameters:
-
parameterIndex - the parameter index (1, 2, ...)
-
x - the value
-
Throws:
-
SQLException - if this object is closed
-
void -setBlob(int parameterIndex, InputStream x) -
Sets the value of a parameter as a Blob.
-
void -setBlob(int parameterIndex, InputStream x) throws SQLException -
Sets the value of a parameter as a Blob. - This method does not close the stream. - The stream may be closed after executing the statement.
-
Parameters:
-
parameterIndex - the parameter index (1, 2, ...)
-
x - the value
-
Throws:
-
SQLException - if this object is closed
-
void -setBlob(int parameterIndex, InputStream x, long length) -
Sets the value of a parameter as a Blob.
-
void -setBlob(int parameterIndex, InputStream x, long length) throws SQLException -
Sets the value of a parameter as a Blob. - This method does not close the stream. - The stream may be closed after executing the statement.
-
Parameters:
-
parameterIndex - the parameter index (1, 2, ...)
-
x - the value
-
Throws:
-
SQLException - if this object is closed
-
void -setBoolean(int parameterIndex, boolean x) -
Sets the value of a parameter.
-
void -setBoolean(int parameterIndex, boolean x) throws SQLException -
Sets the value of a parameter.
-
Parameters:
-
parameterIndex - the parameter index (1, 2, ...)
-
x - the value
-
Throws:
-
SQLException - if this object is closed
-
void -setByte(int parameterIndex, byte x) -
Sets the value of a parameter.
-
void -setByte(int parameterIndex, byte x) throws SQLException -
Sets the value of a parameter.
-
Parameters:
-
parameterIndex - the parameter index (1, 2, ...)
-
x - the value
-
Throws:
-
SQLException - if this object is closed
-
void -setBytes(int parameterIndex, byte[] x) -
Sets the value of a parameter as a byte array.
-
void -setBytes(int parameterIndex, byte[] x) throws SQLException -
Sets the value of a parameter as a byte array.
-
Parameters:
-
parameterIndex - the parameter index (1, 2, ...)
-
x - the value
-
Throws:
-
SQLException - if this object is closed
-
void -setCharacterStream(int parameterIndex, Reader x, int length) -
Sets the value of a parameter as a character stream.
-
void -setCharacterStream(int parameterIndex, Reader x, int length) throws SQLException -
Sets the value of a parameter as a character stream. - This method does not close the reader. - The reader may be closed after executing the statement.
-
Parameters:
-
parameterIndex - the parameter index (1, 2, ...)
-
x - the value
-
length - the number of bytes
-
Throws:
-
SQLException - if this object is closed
-
void -setCharacterStream(int parameterIndex, Reader x) -
Sets the value of a parameter as a character stream.
-
void -setCharacterStream(int parameterIndex, Reader x) throws SQLException -
Sets the value of a parameter as a character stream. - This method does not close the reader. - The reader may be closed after executing the statement.
-
Parameters:
-
parameterIndex - the parameter index (1, 2, ...)
-
x - the value
-
Throws:
-
SQLException - if this object is closed
-
void -setCharacterStream(int parameterIndex, Reader x, long length) -
Sets the value of a parameter as a character stream.
-
void -setCharacterStream(int parameterIndex, Reader x, long length) throws SQLException -
Sets the value of a parameter as a character stream. - This method does not close the reader. - The reader may be closed after executing the statement.
-
Parameters:
-
parameterIndex - the parameter index (1, 2, ...)
-
x - the value
-
length - the number of bytes
-
Throws:
-
SQLException - if this object is closed
-
void -setClob(int parameterIndex, Clob x) -
Sets the value of a parameter as a Clob.
-
void -setClob(int parameterIndex, Clob x) throws SQLException -
Sets the value of a parameter as a Clob.
-
Parameters:
-
parameterIndex - the parameter index (1, 2, ...)
-
x - the value
-
Throws:
-
SQLException - if this object is closed
-
void -setClob(int parameterIndex, Reader x) -
Sets the value of a parameter as a Clob.
-
void -setClob(int parameterIndex, Reader x) throws SQLException -
Sets the value of a parameter as a Clob. - This method does not close the reader. - The reader may be closed after executing the statement.
-
Parameters:
-
parameterIndex - the parameter index (1, 2, ...)
-
x - the value
-
Throws:
-
SQLException - if this object is closed
-
void -setClob(int parameterIndex, Reader x, long length) -
Sets the value of a parameter as a Clob.
-
void -setClob(int parameterIndex, Reader x, long length) throws SQLException -
Sets the value of a parameter as a Clob. - This method does not close the reader. - The reader may be closed after executing the statement.
-
Parameters:
-
parameterIndex - the parameter index (1, 2, ...)
-
x - the value
-
Throws:
-
SQLException - if this object is closed
-
void -setDate(int parameterIndex, Date x) -
Sets the value of a parameter.
-
void -setDate(int parameterIndex, Date x) throws SQLException -
Sets the value of a parameter.
-
Parameters:
-
parameterIndex - the parameter index (1, 2, ...)
-
x - the value
-
Throws:
-
SQLException - if this object is closed
-
void -setDate(int parameterIndex, Date x, Calendar calendar) -
Sets the date using a specified time zone.
-
void -setDate(int parameterIndex, Date x, Calendar calendar) throws SQLException -
Sets the date using a specified time zone. The value will be converted to - the local time zone.
-
Parameters:
-
parameterIndex - the parameter index (1, 2, ...)
-
x - the value
-
calendar - the calendar
-
Throws:
-
SQLException - if this object is closed
-
void -setDouble(int parameterIndex, double x) -
Sets the value of a parameter.
-
void -setDouble(int parameterIndex, double x) throws SQLException -
Sets the value of a parameter.
-
Parameters:
-
parameterIndex - the parameter index (1, 2, ...)
-
x - the value
-
Throws:
-
SQLException - if this object is closed
-
void -setFloat(int parameterIndex, float x) -
Sets the value of a parameter.
-
void -setFloat(int parameterIndex, float x) throws SQLException -
Sets the value of a parameter.
-
Parameters:
-
parameterIndex - the parameter index (1, 2, ...)
-
x - the value
-
Throws:
-
SQLException - if this object is closed
-
void -setInt(int parameterIndex, int x) -
Sets the value of a parameter.
-
void -setInt(int parameterIndex, int x) throws SQLException -
Sets the value of a parameter.
-
Parameters:
-
parameterIndex - the parameter index (1, 2, ...)
-
x - the value
-
Throws:
-
SQLException - if this object is closed
-
void -setLong(int parameterIndex, long x) -
Sets the value of a parameter.
-
void -setLong(int parameterIndex, long x) throws SQLException -
Sets the value of a parameter.
-
Parameters:
-
parameterIndex - the parameter index (1, 2, ...)
-
x - the value
-
Throws:
-
SQLException - if this object is closed
-
void -setNull(int parameterIndex, int sqlType) -
Sets a parameter to null.
-
void -setNull(int parameterIndex, int sqlType) throws SQLException -
Sets a parameter to null.
-
Parameters:
-
parameterIndex - the parameter index (1, 2, ...)
-
sqlType - the data type (Types.x)
-
Throws:
-
SQLException - if this object is closed
-
void -setNull(int parameterIndex, int sqlType, String typeName) -
Sets a parameter to null.
-
void -setNull(int parameterIndex, int sqlType, String typeName) throws SQLException -
Sets a parameter to null.
-
Parameters:
-
parameterIndex - the parameter index (1, 2, ...)
-
sqlType - the data type (Types.x)
-
typeName - this parameter is ignored
-
Throws:
-
SQLException - if this object is closed
-
void -setObject(int parameterIndex, Object x) -
Sets the value of a parameter.
-
void -setObject(int parameterIndex, Object x) throws SQLException -
Sets the value of a parameter.
-
Parameters:
-
parameterIndex - the parameter index (1, 2, ...)
-
x - the value
-
Throws:
-
SQLException - if this object is closed
-
void -setObject(int parameterIndex, Object x, int targetSqlType) -
Sets the value of a parameter.
-
void -setObject(int parameterIndex, Object x, int targetSqlType) throws SQLException -
Sets the value of a parameter. The object is converted, if required, to - the specified data type before sending to the database.
-
Parameters:
-
parameterIndex - the parameter index (1, 2, ...)
-
x - the value, null is allowed
-
targetSqlType - the type as defined in java.sql.Types
-
Throws:
-
SQLException - if this object is closed
-
void -setObject(int parameterIndex, Object x, int targetSqlType, int scale) -
Sets the value of a parameter.
-
void -setObject(int parameterIndex, Object x, int targetSqlType, int scale) throws SQLException -
Sets the value of a parameter. The object is converted, if required, to - the specified data type before sending to the database.
-
Parameters:
-
parameterIndex - the parameter index (1, 2, ...)
-
x - the value, null is allowed
-
targetSqlType - the type as defined in java.sql.Types
-
scale - is ignored
-
Throws:
-
SQLException - if this object is closed
-
void -setRef(int parameterIndex, Ref x) -
[Not supported] Sets the value of a column as a reference.
-
void -setRef(int parameterIndex, Ref x) throws SQLException -
[Not supported] Sets the value of a column as a reference.
-
void -setShort(int parameterIndex, short x) -
Sets the value of a parameter.
-
void -setShort(int parameterIndex, short x) throws SQLException -
Sets the value of a parameter.
-
Parameters:
-
parameterIndex - the parameter index (1, 2, ...)
-
x - the value
-
Throws:
-
SQLException - if this object is closed
-
void -setString(int parameterIndex, String x) -
Sets the value of a parameter.
-
void -setString(int parameterIndex, String x) throws SQLException -
Sets the value of a parameter.
-
Parameters:
-
parameterIndex - the parameter index (1, 2, ...)
-
x - the value
-
Throws:
-
SQLException - if this object is closed
-
void -setTime(int parameterIndex, Time x) -
Sets the value of a parameter.
-
void -setTime(int parameterIndex, Time x) throws SQLException -
Sets the value of a parameter.
-
Parameters:
-
parameterIndex - the parameter index (1, 2, ...)
-
x - the value
-
Throws:
-
SQLException - if this object is closed
-
void -setTime(int parameterIndex, Time x, Calendar calendar) -
Sets the time using a specified time zone.
-
void -setTime(int parameterIndex, Time x, Calendar calendar) throws SQLException -
Sets the time using a specified time zone. The value will be converted to - the local time zone.
-
Parameters:
-
parameterIndex - the parameter index (1, 2, ...)
-
x - the value
-
calendar - the calendar
-
Throws:
-
SQLException - if this object is closed
-
void -setTimestamp(int parameterIndex, Timestamp x) -
Sets the value of a parameter.
-
void -setTimestamp(int parameterIndex, Timestamp x) throws SQLException -
Sets the value of a parameter.
-
Parameters:
-
parameterIndex - the parameter index (1, 2, ...)
-
x - the value
-
Throws:
-
SQLException - if this object is closed
-
void -setTimestamp(int parameterIndex, Timestamp x, Calendar calendar) -
Sets the timestamp using a specified time zone.
-
void -setTimestamp(int parameterIndex, Timestamp x, Calendar calendar) throws SQLException -
Sets the timestamp using a specified time zone. The value will be - converted to the local time zone.
-
Parameters:
-
parameterIndex - the parameter index (1, 2, ...)
-
x - the value
-
calendar - the calendar
-
Throws:
-
SQLException - if this object is closed
-
void -setURL(int parameterIndex, URL x) -
[Not supported]
-
void -setURL(int parameterIndex, URL x) throws SQLException -
[Not supported]
-
void -setUnicodeStream(int parameterIndex, InputStream x, int length) -
[Not supported] This feature is deprecated and not supported.
-
void -setUnicodeStream(int parameterIndex, InputStream x, int length) throws SQLException -
[Not supported] This feature is deprecated and not supported.
-
-
diff --git a/tools/h2/docs/javadoc/org/h2/jdbc/JdbcResultSet.html b/tools/h2/docs/javadoc/org/h2/jdbc/JdbcResultSet.html deleted file mode 100755 index 69b3cf4..0000000 --- a/tools/h2/docs/javadoc/org/h2/jdbc/JdbcResultSet.html +++ /dev/null @@ -1,2300 +0,0 @@ - - - -ResultSet - - - -
-

ResultSet

-

- Represents a result set. -

-

- Column labels are case-insensitive, quotes are not supported. The first column - has the column index 1. -

-

- Updatable result sets: - Result sets are updatable when the result only contains columns from one - table, and if it contains all columns of a unique index (primary key or - other) of this table. Key columns may not contain NULL (because multiple rows - with NULL could exist). In updatable result sets, own changes are visible, - but not own inserts and deletes. -



- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Methods
boolean -absolute(int rowNumber) -
Moves the current position to a specific row.
-
boolean -absolute(int rowNumber) throws SQLException -
Moves the current position to a specific row.
-
Parameters:
-
rowNumber - the row number. 0 is not allowed, 1 means the first row, - 2 the second. -1 means the last row, -2 the row before the - last row. If the value is too large, the position is moved - after the last row, if if the value is too small it is moved - before the first row.
-
Returns:
-
true if there is a row available, false if not
-
Throws:
-
SQLException - if the result set is closed
-
void -afterLast() -
Moves the current position to after the last row, that means after the end.
-
void -afterLast() throws SQLException -
Moves the current position to after the last row, that means after the end.
-
Throws:
-
SQLException - if the result set is closed
-
void -beforeFirst() -
Moves the current position to before the first row, that means resets the - result set.
-
void -beforeFirst() throws SQLException -
Moves the current position to before the first row, that means resets the - result set.
-
Throws:
-
SQLException - if the result set is closed
-
void -cancelRowUpdates() -
Cancels updating a row.
-
void -cancelRowUpdates() throws SQLException -
Cancels updating a row.
-
Throws:
-
SQLException - if the result set is closed or if the current row is - the insert row
-
void -clearWarnings() -
Clears all warnings.
-
void -clearWarnings() throws SQLException -
Clears all warnings.
-
void -close() -
Closes the result set.
-
void -close() throws SQLException -
Closes the result set.
-
void -deleteRow() -
Deletes the current row.
-
void -deleteRow() throws SQLException -
Deletes the current row.
-
Throws:
-
SQLException - if the result set is closed, if the current row is - the insert row or if not on a valid row, or if the result set - it not updatable
-
int -findColumn(String columnLabel) -
Searches for a specific column in the result set.
-
int -findColumn(String columnLabel) throws SQLException -
Searches for a specific column in the result set. A case-insensitive - search is made.
-
Parameters:
-
columnLabel - the column label
-
Returns:
-
the column index (1,2,...)
-
Throws:
-
SQLException - if the column is not found or if the result set is - closed
-
boolean -first() -
Moves the current position to the first row.
-
boolean -first() throws SQLException -
Moves the current position to the first row. This is the same as calling - beforeFirst() followed by next().
-
Returns:
-
true if there is a row available, false if not
-
Throws:
-
SQLException - if the result set is closed
-
Array -getArray(int columnIndex) -
Returns the value of the specified column as an Array.
-
Array -getArray(int columnIndex) throws SQLException -
Returns the value of the specified column as an Array.
-
Parameters:
-
columnIndex - (1,2,...)
-
Returns:
-
the value
-
Throws:
-
SQLException - if the column is not found or if the result set is - closed
-
Array -getArray(String columnLabel) -
Returns the value of the specified column as an Array.
-
Array -getArray(String columnLabel) throws SQLException -
Returns the value of the specified column as an Array.
-
Parameters:
-
columnLabel - the column label
-
Returns:
-
the value
-
Throws:
-
SQLException - if the column is not found or if the result set is - closed
-
InputStream -getAsciiStream(int columnIndex) -
Returns the value of the specified column as input stream.
-
InputStream -getAsciiStream(int columnIndex) throws SQLException -
Returns the value of the specified column as input stream.
-
Parameters:
-
columnIndex - (1,2,...)
-
Returns:
-
the value
-
Throws:
-
SQLException - if the column is not found or if the result set is - closed
-
InputStream -getAsciiStream(String columnLabel) -
Returns the value of the specified column as input stream.
-
InputStream -getAsciiStream(String columnLabel) throws SQLException -
Returns the value of the specified column as input stream.
-
Parameters:
-
columnLabel - the column label
-
Returns:
-
the value
-
Throws:
-
SQLException - if the column is not found or if the result set is - closed
-
BigDecimal -getBigDecimal(int columnIndex) -
Returns the value of the specified column as a String.
-
BigDecimal -getBigDecimal(int columnIndex) throws SQLException -
Returns the value of the specified column as a String.
-
Parameters:
-
columnIndex - (1,2,...)
-
Returns:
-
the value
-
Throws:
-
SQLException - if the column is not found or if the result set is closed
-
BigDecimal -getBigDecimal(String columnLabel) -
Returns the value of the specified column as a String.
-
BigDecimal -getBigDecimal(String columnLabel) throws SQLException -
Returns the value of the specified column as a String.
-
Parameters:
-
columnLabel - the column label
-
Returns:
-
the value
-
Throws:
-
SQLException - if the column is not found or if the result set is closed
-
BigDecimal -getBigDecimal(String columnLabel, int scale) -
Returns the value of the specified column as a String.
-
BigDecimal -getBigDecimal(String columnLabel, int scale) throws SQLException -
Returns the value of the specified column as a String.
-
Parameters:
-
columnLabel - the column label
-
Returns:
-
the value
-
Throws:
-
SQLException - if the column is not found or if the result set is - closed
-
BigDecimal -getBigDecimal(int columnIndex, int scale) -
Returns the value of the specified column as a String.
-
BigDecimal -getBigDecimal(int columnIndex, int scale) throws SQLException -
Returns the value of the specified column as a String.
-
Parameters:
-
columnIndex - (1,2,...)
-
Returns:
-
the value
-
Throws:
-
SQLException - if the column is not found or if the result set is - closed
-
InputStream -getBinaryStream(int columnIndex) -
Returns the value of the specified column as input stream.
-
InputStream -getBinaryStream(int columnIndex) throws SQLException -
Returns the value of the specified column as input stream.
-
Parameters:
-
columnIndex - (1,2,...)
-
Returns:
-
the value
-
Throws:
-
SQLException - if the column is not found or if the result set is - closed
-
InputStream -getBinaryStream(String columnLabel) -
Returns the value of the specified column as input stream.
-
InputStream -getBinaryStream(String columnLabel) throws SQLException -
Returns the value of the specified column as input stream.
-
Parameters:
-
columnLabel - the column label
-
Returns:
-
the value
-
Throws:
-
SQLException - if the column is not found or if the result set is - closed
-
Blob -getBlob(int columnIndex) -
Returns the value of the specified column as a Blob.
-
Blob -getBlob(int columnIndex) throws SQLException -
Returns the value of the specified column as a Blob.
-
Parameters:
-
columnIndex - (1,2,...)
-
Returns:
-
the value
-
Throws:
-
SQLException - if the column is not found or if the result set is - closed
-
Blob -getBlob(String columnLabel) -
Returns the value of the specified column as a Blob.
-
Blob -getBlob(String columnLabel) throws SQLException -
Returns the value of the specified column as a Blob.
-
Parameters:
-
columnLabel - the column label
-
Returns:
-
the value
-
Throws:
-
SQLException - if the column is not found or if the result set is - closed
-
boolean -getBoolean(int columnIndex) -
Returns the value of the specified column as a boolean.
-
boolean -getBoolean(int columnIndex) throws SQLException -
Returns the value of the specified column as a boolean.
-
Parameters:
-
columnIndex - (1,2,...)
-
Returns:
-
the value
-
Throws:
-
SQLException - if the column is not found or if the result set is - closed
-
boolean -getBoolean(String columnLabel) -
Returns the value of the specified column as a boolean.
-
boolean -getBoolean(String columnLabel) throws SQLException -
Returns the value of the specified column as a boolean.
-
Parameters:
-
columnLabel - the column label
-
Returns:
-
the value
-
Throws:
-
SQLException - if the column is not found or if the result set is - closed
-
byte -getByte(int columnIndex) -
Returns the value of the specified column as a byte.
-
byte -getByte(int columnIndex) throws SQLException -
Returns the value of the specified column as a byte.
-
Parameters:
-
columnIndex - (1,2,...)
-
Returns:
-
the value
-
Throws:
-
SQLException - if the column is not found or if the result set is - closed
-
byte -getByte(String columnLabel) -
Returns the value of the specified column as a byte.
-
byte -getByte(String columnLabel) throws SQLException -
Returns the value of the specified column as a byte.
-
Parameters:
-
columnLabel - the column label
-
Returns:
-
the value
-
Throws:
-
SQLException - if the column is not found or if the result set is - closed
-
byte[] -getBytes(int columnIndex) -
Returns the value of the specified column as a byte array.
-
byte[] -getBytes(int columnIndex) throws SQLException -
Returns the value of the specified column as a byte array.
-
Parameters:
-
columnIndex - (1,2,...)
-
Returns:
-
the value
-
Throws:
-
SQLException - if the column is not found or if the result set is - closed
-
byte[] -getBytes(String columnLabel) -
Returns the value of the specified column as a byte array.
-
byte[] -getBytes(String columnLabel) throws SQLException -
Returns the value of the specified column as a byte array.
-
Parameters:
-
columnLabel - the column label
-
Returns:
-
the value
-
Throws:
-
SQLException - if the column is not found or if the result set is - closed
-
Reader -getCharacterStream(int columnIndex) -
Returns the value of the specified column as input stream.
-
Reader -getCharacterStream(int columnIndex) throws SQLException -
Returns the value of the specified column as input stream.
-
Parameters:
-
columnIndex - (1,2,...)
-
Returns:
-
the value
-
Throws:
-
SQLException - if the column is not found or if the result set is - closed
-
Reader -getCharacterStream(String columnLabel) -
Returns the value of the specified column as input stream.
-
Reader -getCharacterStream(String columnLabel) throws SQLException -
Returns the value of the specified column as input stream.
-
Parameters:
-
columnLabel - the column label
-
Returns:
-
the value
-
Throws:
-
SQLException - if the column is not found or if the result set is - closed
-
Clob -getClob(int columnIndex) -
Returns the value of the specified column as a Clob.
-
Clob -getClob(int columnIndex) throws SQLException -
Returns the value of the specified column as a Clob.
-
Parameters:
-
columnIndex - (1,2,...)
-
Returns:
-
the value
-
Throws:
-
SQLException - if the column is not found or if the result set is - closed
-
Clob -getClob(String columnLabel) -
Returns the value of the specified column as a Clob.
-
Clob -getClob(String columnLabel) throws SQLException -
Returns the value of the specified column as a Clob.
-
Parameters:
-
columnLabel - the column label
-
Returns:
-
the value
-
Throws:
-
SQLException - if the column is not found or if the result set is - closed
-
int -getConcurrency() -
Gets the result set concurrency.
-
int -getConcurrency() throws SQLException -
Gets the result set concurrency. Result sets are only updatable if the - statement was created with updatable concurrency, and if the result set - contains all columns of the primary key or of a unique index of a table.
-
Returns:
-
ResultSet.CONCUR_UPDATABLE if the result set is updatable, or - ResultSet.CONCUR_READ_ONLY otherwise
-
String -getCursorName() -
[Not supported] Gets the cursor name if it was defined.
-
String -getCursorName() throws SQLException -
[Not supported] Gets the cursor name if it was defined. This feature is - superseded by updateX methods. This method throws a SQLException because - cursor names are not supported.
-
Date -getDate(int columnIndex) -
Returns the value of the specified column as a java.sql.Date.
-
Date -getDate(int columnIndex) throws SQLException -
Returns the value of the specified column as a java.sql.Date.
-
Parameters:
-
columnIndex - (1,2,...)
-
Returns:
-
the value
-
Throws:
-
SQLException - if the column is not found or if the result set is closed
-
Date -getDate(String columnLabel) -
Returns the value of the specified column as a java.sql.Date.
-
Date -getDate(String columnLabel) throws SQLException -
Returns the value of the specified column as a java.sql.Date.
-
Parameters:
-
columnLabel - the column label
-
Returns:
-
the value
-
Throws:
-
SQLException - if the column is not found or if the result set is closed
-
Date -getDate(int columnIndex, Calendar calendar) -
Returns the value of the specified column as a java.sql.Date using a - specified time zone.
-
Date -getDate(int columnIndex, Calendar calendar) throws SQLException -
Returns the value of the specified column as a java.sql.Date using a - specified time zone.
-
Parameters:
-
columnIndex - (1,2,...)
-
calendar - the calendar
-
Returns:
-
the value
-
Throws:
-
SQLException - if the column is not found or if the result set is - closed
-
Date -getDate(String columnLabel, Calendar calendar) -
Returns the value of the specified column as a java.sql.Date using a - specified time zone.
-
Date -getDate(String columnLabel, Calendar calendar) throws SQLException -
Returns the value of the specified column as a java.sql.Date using a - specified time zone.
-
Parameters:
-
columnLabel - the column label
-
calendar - the calendar
-
Returns:
-
the value
-
Throws:
-
SQLException - if the column is not found or if the result set is - closed
-
double -getDouble(int columnIndex) -
Returns the value of the specified column as a double.
-
double -getDouble(int columnIndex) throws SQLException -
Returns the value of the specified column as a double.
-
Parameters:
-
columnIndex - (1,2,...)
-
Returns:
-
the value
-
Throws:
-
SQLException - if the column is not found or if the result set is - closed
-
double -getDouble(String columnLabel) -
Returns the value of the specified column as a double.
-
double -getDouble(String columnLabel) throws SQLException -
Returns the value of the specified column as a double.
-
Parameters:
-
columnLabel - the column label
-
Returns:
-
the value
-
Throws:
-
SQLException - if the column is not found or if the result set is - closed
-
int -getFetchDirection() -
Gets the fetch direction.
-
int -getFetchDirection() throws SQLException -
Gets the fetch direction.
-
Returns:
-
the direction: FETCH_FORWARD
-
int -getFetchSize() -
Gets the number of rows suggested to read in one step.
-
int -getFetchSize() throws SQLException -
Gets the number of rows suggested to read in one step.
-
Returns:
-
the current fetch size
-
float -getFloat(int columnIndex) -
Returns the value of the specified column as a float.
-
float -getFloat(int columnIndex) throws SQLException -
Returns the value of the specified column as a float.
-
Parameters:
-
columnIndex - (1,2,...)
-
Returns:
-
the value
-
Throws:
-
SQLException - if the column is not found or if the result set is - closed
-
float -getFloat(String columnLabel) -
Returns the value of the specified column as a float.
-
float -getFloat(String columnLabel) throws SQLException -
Returns the value of the specified column as a float.
-
Parameters:
-
columnLabel - the column label
-
Returns:
-
the value
-
Throws:
-
SQLException - if the column is not found or if the result set is - closed
-
int -getHoldability() -
Returns the current result set holdability.
-
int -getHoldability() throws SQLException -
Returns the current result set holdability.
-
Returns:
-
the holdability
-
Throws:
-
SQLException - if the connection is closed
-
int -getInt(int columnIndex) -
Returns the value of the specified column as an int.
-
int -getInt(int columnIndex) throws SQLException -
Returns the value of the specified column as an int.
-
Parameters:
-
columnIndex - (1,2,...)
-
Returns:
-
the value
-
Throws:
-
SQLException - if the column is not found or if the result set is closed
-
int -getInt(String columnLabel) -
Returns the value of the specified column as an int.
-
int -getInt(String columnLabel) throws SQLException -
Returns the value of the specified column as an int.
-
Parameters:
-
columnLabel - the column label
-
Returns:
-
the value
-
Throws:
-
SQLException - if the column is not found or if the result set is closed
-
long -getLong(int columnIndex) -
Returns the value of the specified column as a long.
-
long -getLong(int columnIndex) throws SQLException -
Returns the value of the specified column as a long.
-
Parameters:
-
columnIndex - (1,2,...)
-
Returns:
-
the value
-
Throws:
-
SQLException - if the column is not found or if the result set is - closed
-
long -getLong(String columnLabel) -
Returns the value of the specified column as a long.
-
long -getLong(String columnLabel) throws SQLException -
Returns the value of the specified column as a long.
-
Parameters:
-
columnLabel - the column label
-
Returns:
-
the value
-
Throws:
-
SQLException - if the column is not found or if the result set is - closed
-
ResultSetMetaData -getMetaData() -
Gets the meta data of this result set.
-
ResultSetMetaData -getMetaData() throws SQLException -
Gets the meta data of this result set.
-
Returns:
-
the meta data
-
Object -getObject(int columnIndex) -
Returns a column value as a Java object.
-
Object -getObject(int columnIndex) throws SQLException -
Returns a column value as a Java object. For BINARY data, the data is - de-serialized into a Java Object.
-
Parameters:
-
columnIndex - (1,2,...)
-
Returns:
-
the value or null
-
Throws:
-
SQLException - if the column is not found or if the result set is - closed
-
Object -getObject(String columnLabel) -
Returns a column value as a Java object.
-
Object -getObject(String columnLabel) throws SQLException -
Returns a column value as a Java object. For BINARY data, the data is - de-serialized into a Java Object.
-
Parameters:
-
columnLabel - the column label
-
Returns:
-
the value or null
-
Throws:
-
SQLException - if the column is not found or if the result set is - closed
-
Object -getObject(int columnIndex, Map map) -
[Not supported] Gets a column as a object using the specified type - mapping.
-
Object -getObject(int columnIndex, Map map) throws SQLException -
[Not supported] Gets a column as a object using the specified type - mapping.
-
Object -getObject(String columnLabel, Map map) -
[Not supported] Gets a column as a object using the specified type - mapping.
-
Object -getObject(String columnLabel, Map map) throws SQLException -
[Not supported] Gets a column as a object using the specified type - mapping.
-
Ref -getRef(int columnIndex) -
[Not supported] Gets a column as a reference.
-
Ref -getRef(int columnIndex) throws SQLException -
[Not supported] Gets a column as a reference.
-
Ref -getRef(String columnLabel) -
[Not supported] Gets a column as a reference.
-
Ref -getRef(String columnLabel) throws SQLException -
[Not supported] Gets a column as a reference.
-
int -getRow() -
Gets the current row number.
-
int -getRow() throws SQLException -
Gets the current row number. The first row is row 1, the second 2 and so - on. This method returns 0 before the first and after the last row.
-
Returns:
-
the row number
-
short -getShort(int columnIndex) -
Returns the value of the specified column as a short.
-
short -getShort(int columnIndex) throws SQLException -
Returns the value of the specified column as a short.
-
Parameters:
-
columnIndex - (1,2,...)
-
Returns:
-
the value
-
Throws:
-
SQLException - if the column is not found or if the result set is - closed
-
short -getShort(String columnLabel) -
Returns the value of the specified column as a short.
-
short -getShort(String columnLabel) throws SQLException -
Returns the value of the specified column as a short.
-
Parameters:
-
columnLabel - the column label
-
Returns:
-
the value
-
Throws:
-
SQLException - if the column is not found or if the result set is - closed
-
Statement -getStatement() -
Returns the statement that created this object.
-
Statement -getStatement() throws SQLException -
Returns the statement that created this object.
-
Returns:
-
the statement or prepared statement, or null if created by a - DatabaseMetaData call.
-
String -getString(int columnIndex) -
Returns the value of the specified column as a String.
-
String -getString(int columnIndex) throws SQLException -
Returns the value of the specified column as a String.
-
Parameters:
-
columnIndex - (1,2,...)
-
Returns:
-
the value
-
Throws:
-
SQLException - if the column is not found or if the result set is closed
-
String -getString(String columnLabel) -
Returns the value of the specified column as a String.
-
String -getString(String columnLabel) throws SQLException -
Returns the value of the specified column as a String.
-
Parameters:
-
columnLabel - the column label
-
Returns:
-
the value
-
Throws:
-
SQLException - if the column is not found or if the result set is closed
-
Time -getTime(int columnIndex) -
Returns the value of the specified column as a java.sql.Time.
-
Time -getTime(int columnIndex) throws SQLException -
Returns the value of the specified column as a java.sql.Time.
-
Parameters:
-
columnIndex - (1,2,...)
-
Returns:
-
the value
-
Throws:
-
SQLException - if the column is not found or if the result set is closed
-
Time -getTime(String columnLabel) -
Returns the value of the specified column as a java.sql.Time.
-
Time -getTime(String columnLabel) throws SQLException -
Returns the value of the specified column as a java.sql.Time.
-
Parameters:
-
columnLabel - the column label
-
Returns:
-
the value
-
Throws:
-
SQLException - if the column is not found or if the result set is closed
-
Time -getTime(int columnIndex, Calendar calendar) -
Returns the value of the specified column as a java.sql.Time using a - specified time zone.
-
Time -getTime(int columnIndex, Calendar calendar) throws SQLException -
Returns the value of the specified column as a java.sql.Time using a - specified time zone.
-
Parameters:
-
columnIndex - (1,2,...)
-
calendar - the calendar
-
Returns:
-
the value
-
Throws:
-
SQLException - if the column is not found or if the result set is - closed
-
Time -getTime(String columnLabel, Calendar calendar) -
Returns the value of the specified column as a java.sql.Time using a - specified time zone.
-
Time -getTime(String columnLabel, Calendar calendar) throws SQLException -
Returns the value of the specified column as a java.sql.Time using a - specified time zone.
-
Parameters:
-
columnLabel - the column label
-
calendar - the calendar
-
Returns:
-
the value
-
Throws:
-
SQLException - if the column is not found or if the result set is - closed
-
Timestamp -getTimestamp(int columnIndex) -
Returns the value of the specified column as a java.sql.Timestamp.
-
Timestamp -getTimestamp(int columnIndex) throws SQLException -
Returns the value of the specified column as a java.sql.Timestamp.
-
Parameters:
-
columnIndex - (1,2,...)
-
Returns:
-
the value
-
Throws:
-
SQLException - if the column is not found or if the result set is closed
-
Timestamp -getTimestamp(String columnLabel) -
Returns the value of the specified column as a java.sql.Timestamp.
-
Timestamp -getTimestamp(String columnLabel) throws SQLException -
Returns the value of the specified column as a java.sql.Timestamp.
-
Parameters:
-
columnLabel - the column label
-
Returns:
-
the value
-
Throws:
-
SQLException - if the column is not found or if the result set is closed
-
Timestamp -getTimestamp(int columnIndex, Calendar calendar) -
Returns the value of the specified column as a java.sql.Timestamp using a - specified time zone.
-
Timestamp -getTimestamp(int columnIndex, Calendar calendar) throws SQLException -
Returns the value of the specified column as a java.sql.Timestamp using a - specified time zone.
-
Parameters:
-
columnIndex - (1,2,...)
-
calendar - the calendar
-
Returns:
-
the value
-
Throws:
-
SQLException - if the column is not found or if the result set is - closed
-
Timestamp -getTimestamp(String columnLabel, Calendar calendar) -
Returns the value of the specified column as a java.sql.Timestamp.
-
Timestamp -getTimestamp(String columnLabel, Calendar calendar) throws SQLException -
Returns the value of the specified column as a java.sql.Timestamp.
-
Parameters:
-
columnLabel - the column label
-
calendar - the calendar
-
Returns:
-
the value
-
Throws:
-
SQLException - if the column is not found or if the result set is - closed
-
int -getType() -
Get the result set type.
-
int -getType() throws SQLException -
Get the result set type.
-
Returns:
-
the result set type (TYPE_FORWARD_ONLY, TYPE_SCROLL_INSENSITIVE - or TYPE_SCROLL_SENSITIVE)
-
Throws:
-
SQLException - if the column is not found or if the result set is - closed
-
URL -getURL(int columnIndex) -
[Not supported]
-
URL -getURL(int columnIndex) throws SQLException -
[Not supported]
-
URL -getURL(String columnLabel) -
[Not supported]
-
URL -getURL(String columnLabel) throws SQLException -
[Not supported]
-
InputStream -getUnicodeStream(int columnIndex) -
[Not supported]
-
InputStream -getUnicodeStream(int columnIndex) throws SQLException -
[Not supported]
-
InputStream -getUnicodeStream(String columnLabel) -
[Not supported]
-
InputStream -getUnicodeStream(String columnLabel) throws SQLException -
[Not supported]
-
SQLWarning -getWarnings() -
Gets the first warning reported by calls on this object.
-
SQLWarning -getWarnings() throws SQLException -
Gets the first warning reported by calls on this object.
-
Returns:
-
null
-
void -insertRow() -
Inserts the current row.
-
void -insertRow() throws SQLException -
Inserts the current row. The current position must be the insert row.
-
Throws:
-
SQLException - if the result set is closed or if not on the insert - row, or if the result set it not updatable
-
boolean -isAfterLast() -
Checks if the current position is after the last row, that means next() - was called and returned false, and there was at least one row.
-
boolean -isAfterLast() throws SQLException -
Checks if the current position is after the last row, that means next() - was called and returned false, and there was at least one row.
-
Returns:
-
if there are results and the current position is after the last row
-
Throws:
-
SQLException - if the result set is closed
-
boolean -isBeforeFirst() -
Checks if the current position is before the first row, that means next() - was not called yet, and there is at least one row.
-
boolean -isBeforeFirst() throws SQLException -
Checks if the current position is before the first row, that means next() - was not called yet, and there is at least one row.
-
Returns:
-
if there are results and the current position is before the first row
-
Throws:
-
SQLException - if the result set is closed
-
boolean -isClosed() -
Returns whether this result set is closed.
-
boolean -isClosed() throws SQLException -
Returns whether this result set is closed.
-
Returns:
-
true if the result set is closed
-
boolean -isFirst() -
Checks if the current position is row 1, that means next() was called - once and returned true.
-
boolean -isFirst() throws SQLException -
Checks if the current position is row 1, that means next() was called - once and returned true.
-
Returns:
-
if the current position is the first row
-
Throws:
-
SQLException - if the result set is closed
-
boolean -isLast() -
Checks if the current position is the last row, that means next() was - called and did not yet returned false, but will in the next call.
-
boolean -isLast() throws SQLException -
Checks if the current position is the last row, that means next() was - called and did not yet returned false, but will in the next call.
-
Returns:
-
if the current position is the last row
-
Throws:
-
SQLException - if the result set is closed
-
boolean -last() -
Moves the current position to the last row.
-
boolean -last() throws SQLException -
Moves the current position to the last row.
-
Returns:
-
true if there is a row available, false if not
-
Throws:
-
SQLException - if the result set is closed
-
void -moveToCurrentRow() -
Moves the current position to the current row.
-
void -moveToCurrentRow() throws SQLException -
Moves the current position to the current row.
-
Throws:
-
SQLException - if the result set is closed or is not updatable
-
void -moveToInsertRow() -
Moves the current position to the insert row.
-
void -moveToInsertRow() throws SQLException -
Moves the current position to the insert row. The current row is remembered.
-
Throws:
-
SQLException - if the result set is closed or is not updatable
-
boolean -() -
Moves the cursor to the next row of the result set.
-
boolean -() throws SQLException -
Moves the cursor to the next row of the result set.
-
Returns:
-
true if successful, false if there are no more rows
-
boolean -() -
Moves the cursor to the last row, or row before first row if the current - position is the first row.
-
boolean -() throws SQLException -
Moves the cursor to the last row, or row before first row if the current - position is the first row.
-
Returns:
-
true if there is a row available, false if not
-
Throws:
-
SQLException - if the result set is closed
-
void -refreshRow() -
Re-reads the current row from the database.
-
void -refreshRow() throws SQLException -
Re-reads the current row from the database.
-
Throws:
-
SQLException - if the result set is closed or if the current row is - the insert row or if the row has been deleted or if not on a - valid row
-
boolean -relative(int rowCount) -
Moves the current position to a specific row relative to the current row.
-
boolean -relative(int rowCount) throws SQLException -
Moves the current position to a specific row relative to the current row.
-
Parameters:
-
rowCount - 0 means don't do anything, 1 is the next row, -1 the - previous. If the value is too large, the position is moved - after the last row, if if the value is too small it is moved - before the first row.
-
Returns:
-
true if there is a row available, false if not
-
Throws:
-
SQLException - if the result set is closed
-
boolean -rowDeleted() -
Detects if the row was deleted (by somebody else or the caller).
-
boolean -rowDeleted() throws SQLException -
Detects if the row was deleted (by somebody else or the caller).
-
Returns:
-
false because this driver does not detect this
-
boolean -rowInserted() -
Detects if the row was inserted.
-
boolean -rowInserted() throws SQLException -
Detects if the row was inserted.
-
Returns:
-
false because this driver does not detect this
-
boolean -rowUpdated() -
Detects if the row was updated (by somebody else or the caller).
-
boolean -rowUpdated() throws SQLException -
Detects if the row was updated (by somebody else or the caller).
-
Returns:
-
false because this driver does not detect this
-
void -setFetchDirection(int direction) -
[Not supported] - Sets (changes) the fetch direction for this result set.
-
void -setFetchDirection(int direction) throws SQLException -
[Not supported] - Sets (changes) the fetch direction for this result set. This method - should only be called for scrollable result sets, otherwise it will throw - an exception (no matter what direction is used).
-
Parameters:
-
direction - the new fetch direction
-
Throws:
-
SQLException - Unsupported Feature if the method is called for a - forward-only result set
-
void -setFetchSize(int rows) -
Sets the number of rows suggested to read in one step.
-
void -setFetchSize(int rows) throws SQLException -
Sets the number of rows suggested to read in one step. This value cannot - be higher than the maximum rows (setMaxRows) set by the statement or - prepared statement, otherwise an exception is throws. Setting the value - to 0 will set the default value. The default value can be changed using - the system property h2.serverResultSetFetchSize.
-
Parameters:
-
rows - the number of rows
-
void -updateArray(int columnIndex, Array x) -
[Not supported]
-
void -updateArray(int columnIndex, Array x) throws SQLException -
[Not supported]
-
void -updateArray(String columnLabel, Array x) -
[Not supported]
-
void -updateArray(String columnLabel, Array x) throws SQLException -
[Not supported]
-
void -updateAsciiStream(int columnIndex, InputStream x, int length) -
Updates a column in the current or insert row.
-
void -updateAsciiStream(int columnIndex, InputStream x, int length) throws SQLException -
Updates a column in the current or insert row.
-
Parameters:
-
columnIndex - (1,2,...)
-
x - the value
-
length - the number of characters
-
Throws:
-
SQLException - if the result set is closed or not updatable
-
void -updateAsciiStream(int columnIndex, InputStream x) -
Updates a column in the current or insert row.
-
void -updateAsciiStream(int columnIndex, InputStream x) throws SQLException -
Updates a column in the current or insert row.
-
Parameters:
-
columnIndex - (1,2,...)
-
x - the value
-
Throws:
-
SQLException - if the result set is closed or not updatable
-
void -updateAsciiStream(int columnIndex, InputStream x, long length) -
Updates a column in the current or insert row.
-
void -updateAsciiStream(int columnIndex, InputStream x, long length) throws SQLException -
Updates a column in the current or insert row.
-
Parameters:
-
columnIndex - (1,2,...)
-
x - the value
-
length - the number of characters
-
Throws:
-
SQLException - if the result set is closed or not updatable
-
void -updateAsciiStream(String columnLabel, InputStream x, int length) -
Updates a column in the current or insert row.
-
void -updateAsciiStream(String columnLabel, InputStream x, int length) throws SQLException -
Updates a column in the current or insert row.
-
Parameters:
-
columnLabel - the column label
-
x - the value
-
length - the number of characters
-
Throws:
-
SQLException - if the result set is closed or not updatable
-
void -updateAsciiStream(String columnLabel, InputStream x) -
Updates a column in the current or insert row.
-
void -updateAsciiStream(String columnLabel, InputStream x) throws SQLException -
Updates a column in the current or insert row.
-
Parameters:
-
columnLabel - the column label
-
x - the value
-
Throws:
-
SQLException - if the result set is closed
-
void -updateAsciiStream(String columnLabel, InputStream x, long length) -
Updates a column in the current or insert row.
-
void -updateAsciiStream(String columnLabel, InputStream x, long length) throws SQLException -
Updates a column in the current or insert row.
-
Parameters:
-
columnLabel - the column label
-
x - the value
-
length - the number of characters
-
Throws:
-
SQLException - if the result set is closed or not updatable
-
void -updateBigDecimal(int columnIndex, BigDecimal x) -
Updates a column in the current or insert row.
-
void -updateBigDecimal(int columnIndex, BigDecimal x) throws SQLException -
Updates a column in the current or insert row.
-
Parameters:
-
columnIndex - (1,2,...)
-
x - the value
-
Throws:
-
SQLException - if the result set is closed or not updatable
-
void -updateBigDecimal(String columnLabel, BigDecimal x) -
Updates a column in the current or insert row.
-
void -updateBigDecimal(String columnLabel, BigDecimal x) throws SQLException -
Updates a column in the current or insert row.
-
Parameters:
-
columnLabel - the column label
-
x - the value
-
Throws:
-
SQLException - if the result set is closed or not updatable
-
void -updateBinaryStream(int columnIndex, InputStream x, int length) -
Updates a column in the current or insert row.
-
void -updateBinaryStream(int columnIndex, InputStream x, int length) throws SQLException -
Updates a column in the current or insert row.
-
Parameters:
-
columnIndex - (1,2,...)
-
x - the value
-
length - the number of characters
-
Throws:
-
SQLException - if the result set is closed or not updatable
-
void -updateBinaryStream(int columnIndex, InputStream x) -
Updates a column in the current or insert row.
-
void -updateBinaryStream(int columnIndex, InputStream x) throws SQLException -
Updates a column in the current or insert row.
-
Parameters:
-
columnIndex - (1,2,...)
-
x - the value
-
Throws:
-
SQLException - if the result set is closed or not updatable
-
void -updateBinaryStream(int columnIndex, InputStream x, long length) -
Updates a column in the current or insert row.
-
void -updateBinaryStream(int columnIndex, InputStream x, long length) throws SQLException -
Updates a column in the current or insert row.
-
Parameters:
-
columnIndex - (1,2,...)
-
x - the value
-
length - the number of characters
-
Throws:
-
SQLException - if the result set is closed or not updatable
-
void -updateBinaryStream(String columnLabel, InputStream x) -
Updates a column in the current or insert row.
-
void -updateBinaryStream(String columnLabel, InputStream x) throws SQLException -
Updates a column in the current or insert row.
-
Parameters:
-
columnLabel - the column label
-
x - the value
-
Throws:
-
SQLException - if the result set is closed or not updatable
-
void -updateBinaryStream(String columnLabel, InputStream x, int length) -
Updates a column in the current or insert row.
-
void -updateBinaryStream(String columnLabel, InputStream x, int length) throws SQLException -
Updates a column in the current or insert row.
-
Parameters:
-
columnLabel - the column label
-
x - the value
-
length - the number of characters
-
Throws:
-
SQLException - if the result set is closed or not updatable
-
void -updateBinaryStream(String columnLabel, InputStream x, long length) -
Updates a column in the current or insert row.
-
void -updateBinaryStream(String columnLabel, InputStream x, long length) throws SQLException -
Updates a column in the current or insert row.
-
Parameters:
-
columnLabel - the column label
-
x - the value
-
length - the number of characters
-
Throws:
-
SQLException - if the result set is closed or not updatable
-
void -updateBlob(int columnIndex, InputStream x) -
Updates a column in the current or insert row.
-
void -updateBlob(int columnIndex, InputStream x) throws SQLException -
Updates a column in the current or insert row.
-
Parameters:
-
columnIndex - (1,2,...)
-
x - the value
-
Throws:
-
SQLException - if the result set is closed or not updatable
-
void -updateBlob(int columnIndex, InputStream x, long length) -
Updates a column in the current or insert row.
-
void -updateBlob(int columnIndex, InputStream x, long length) throws SQLException -
Updates a column in the current or insert row.
-
Parameters:
-
columnIndex - (1,2,...)
-
x - the value
-
length - the length
-
Throws:
-
SQLException - if the result set is closed or not updatable
-
void -updateBlob(int columnIndex, Blob x) -
Updates a column in the current or insert row.
-
void -updateBlob(int columnIndex, Blob x) throws SQLException -
Updates a column in the current or insert row.
-
Parameters:
-
columnIndex - (1,2,...)
-
x - the value
-
Throws:
-
SQLException - if the result set is closed or not updatable
-
void -updateBlob(String columnLabel, Blob x) -
Updates a column in the current or insert row.
-
void -updateBlob(String columnLabel, Blob x) throws SQLException -
Updates a column in the current or insert row.
-
Parameters:
-
columnLabel - the column label
-
x - the value
-
Throws:
-
SQLException - if the result set is closed or not updatable
-
void -updateBlob(String columnLabel, InputStream x) -
Updates a column in the current or insert row.
-
void -updateBlob(String columnLabel, InputStream x) throws SQLException -
Updates a column in the current or insert row.
-
Parameters:
-
columnLabel - the column label
-
x - the value
-
Throws:
-
SQLException - if the result set is closed or not updatable
-
void -updateBlob(String columnLabel, InputStream x, long length) -
Updates a column in the current or insert row.
-
void -updateBlob(String columnLabel, InputStream x, long length) throws SQLException -
Updates a column in the current or insert row.
-
Parameters:
-
columnLabel - the column label
-
x - the value
-
length - the length
-
Throws:
-
SQLException - if the result set is closed or not updatable
-
void -updateBoolean(int columnIndex, boolean x) -
Updates a column in the current or insert row.
-
void -updateBoolean(int columnIndex, boolean x) throws SQLException -
Updates a column in the current or insert row.
-
Parameters:
-
columnIndex - (1,2,...)
-
x - the value
-
Throws:
-
SQLException - if the result set is closed or not updatable
-
void -updateBoolean(String columnLabel, boolean x) -
Updates a column in the current or insert row.
-
void -updateBoolean(String columnLabel, boolean x) throws SQLException -
Updates a column in the current or insert row.
-
Parameters:
-
columnLabel - the column label
-
x - the value
-
Throws:
-
SQLException - if result set is closed or not updatable
-
void -updateByte(int columnIndex, byte x) -
Updates a column in the current or insert row.
-
void -updateByte(int columnIndex, byte x) throws SQLException -
Updates a column in the current or insert row.
-
Parameters:
-
columnIndex - (1,2,...)
-
x - the value
-
Throws:
-
SQLException - if the result set is closed or not updatable
-
void -updateByte(String columnLabel, byte x) -
Updates a column in the current or insert row.
-
void -updateByte(String columnLabel, byte x) throws SQLException -
Updates a column in the current or insert row.
-
Parameters:
-
columnLabel - the column label
-
x - the value
-
Throws:
-
SQLException - if the result set is closed or not updatable
-
void -updateBytes(int columnIndex, byte[] x) -
Updates a column in the current or insert row.
-
void -updateBytes(int columnIndex, byte[] x) throws SQLException -
Updates a column in the current or insert row.
-
Parameters:
-
columnIndex - (1,2,...)
-
x - the value
-
Throws:
-
SQLException - if the result set is closed or not updatable
-
void -updateBytes(String columnLabel, byte[] x) -
Updates a column in the current or insert row.
-
void -updateBytes(String columnLabel, byte[] x) throws SQLException -
Updates a column in the current or insert row.
-
Parameters:
-
columnLabel - the column label
-
x - the value
-
Throws:
-
SQLException - if the result set is closed or not updatable
-
void -updateCharacterStream(int columnIndex, Reader x, long length) -
Updates a column in the current or insert row.
-
void -updateCharacterStream(int columnIndex, Reader x, long length) throws SQLException -
Updates a column in the current or insert row.
-
Parameters:
-
columnIndex - (1,2,...)
-
x - the value
-
length - the number of characters
-
Throws:
-
SQLException - if the result set is closed or not updatable
-
void -updateCharacterStream(int columnIndex, Reader x, int length) -
Updates a column in the current or insert row.
-
void -updateCharacterStream(int columnIndex, Reader x, int length) throws SQLException -
Updates a column in the current or insert row.
-
Parameters:
-
columnIndex - (1,2,...)
-
x - the value
-
length - the number of characters
-
Throws:
-
SQLException - if the result set is closed or not updatable
-
void -updateCharacterStream(int columnIndex, Reader x) -
Updates a column in the current or insert row.
-
void -updateCharacterStream(int columnIndex, Reader x) throws SQLException -
Updates a column in the current or insert row.
-
Parameters:
-
columnIndex - (1,2,...)
-
x - the value
-
Throws:
-
SQLException - if the result set is closed or not updatable
-
void -updateCharacterStream(String columnLabel, Reader x, int length) -
Updates a column in the current or insert row.
-
void -updateCharacterStream(String columnLabel, Reader x, int length) throws SQLException -
Updates a column in the current or insert row.
-
Parameters:
-
columnLabel - the column label
-
x - the value
-
length - the number of characters
-
Throws:
-
SQLException - if the result set is closed or not updatable
-
void -updateCharacterStream(String columnLabel, Reader x) -
Updates a column in the current or insert row.
-
void -updateCharacterStream(String columnLabel, Reader x) throws SQLException -
Updates a column in the current or insert row.
-
Parameters:
-
columnLabel - the column label
-
x - the value
-
Throws:
-
SQLException - if the result set is closed or not updatable
-
void -updateCharacterStream(String columnLabel, Reader x, long length) -
Updates a column in the current or insert row.
-
void -updateCharacterStream(String columnLabel, Reader x, long length) throws SQLException -
Updates a column in the current or insert row.
-
Parameters:
-
columnLabel - the column label
-
x - the value
-
length - the number of characters
-
Throws:
-
SQLException - if the result set is closed or not updatable
-
void -updateClob(int columnIndex, Clob x) -
Updates a column in the current or insert row.
-
void -updateClob(int columnIndex, Clob x) throws SQLException -
Updates a column in the current or insert row.
-
Parameters:
-
columnIndex - (1,2,...)
-
x - the value
-
Throws:
-
SQLException - if the result set is closed or not updatable
-
void -updateClob(int columnIndex, Reader x) -
Updates a column in the current or insert row.
-
void -updateClob(int columnIndex, Reader x) throws SQLException -
Updates a column in the current or insert row.
-
Parameters:
-
columnIndex - (1,2,...)
-
x - the value
-
Throws:
-
SQLException - if the result set is closed or not updatable
-
void -updateClob(int columnIndex, Reader x, long length) -
Updates a column in the current or insert row.
-
void -updateClob(int columnIndex, Reader x, long length) throws SQLException -
Updates a column in the current or insert row.
-
Parameters:
-
columnIndex - (1,2,...)
-
x - the value
-
length - the length
-
Throws:
-
SQLException - if the result set is closed or not updatable
-
void -updateClob(String columnLabel, Clob x) -
Updates a column in the current or insert row.
-
void -updateClob(String columnLabel, Clob x) throws SQLException -
Updates a column in the current or insert row.
-
Parameters:
-
columnLabel - the column label
-
x - the value
-
Throws:
-
SQLException - if the result set is closed or not updatable
-
void -updateClob(String columnLabel, Reader x) -
Updates a column in the current or insert row.
-
void -updateClob(String columnLabel, Reader x) throws SQLException -
Updates a column in the current or insert row.
-
Parameters:
-
columnLabel - the column label
-
x - the value
-
Throws:
-
SQLException - if the result set is closed or not updatable
-
void -updateClob(String columnLabel, Reader x, long length) -
Updates a column in the current or insert row.
-
void -updateClob(String columnLabel, Reader x, long length) throws SQLException -
Updates a column in the current or insert row.
-
Parameters:
-
columnLabel - the column label
-
x - the value
-
length - the length
-
Throws:
-
SQLException - if the result set is closed or not updatable
-
void -updateDate(int columnIndex, Date x) -
Updates a column in the current or insert row.
-
void -updateDate(int columnIndex, Date x) throws SQLException -
Updates a column in the current or insert row.
-
Parameters:
-
columnIndex - (1,2,...)
-
x - the value
-
Throws:
-
SQLException - if the result set is closed or not updatable
-
void -updateDate(String columnLabel, Date x) -
Updates a column in the current or insert row.
-
void -updateDate(String columnLabel, Date x) throws SQLException -
Updates a column in the current or insert row.
-
Parameters:
-
columnLabel - the column label
-
x - the value
-
Throws:
-
SQLException - if the result set is closed or not updatable
-
void -updateDouble(int columnIndex, double x) -
Updates a column in the current or insert row.
-
void -updateDouble(int columnIndex, double x) throws SQLException -
Updates a column in the current or insert row.
-
Parameters:
-
columnIndex - (1,2,...)
-
x - the value
-
Throws:
-
SQLException - if the result set is closed or not updatable
-
void -updateDouble(String columnLabel, double x) -
Updates a column in the current or insert row.
-
void -updateDouble(String columnLabel, double x) throws SQLException -
Updates a column in the current or insert row.
-
Parameters:
-
columnLabel - the column label
-
x - the value
-
Throws:
-
SQLException - if the result set is closed or not updatable
-
void -updateFloat(int columnIndex, float x) -
Updates a column in the current or insert row.
-
void -updateFloat(int columnIndex, float x) throws SQLException -
Updates a column in the current or insert row.
-
Parameters:
-
columnIndex - (1,2,...)
-
x - the value
-
Throws:
-
SQLException - if the result set is closed or not updatable
-
void -updateFloat(String columnLabel, float x) -
Updates a column in the current or insert row.
-
void -updateFloat(String columnLabel, float x) throws SQLException -
Updates a column in the current or insert row.
-
Parameters:
-
columnLabel - the column label
-
x - the value
-
Throws:
-
SQLException - if the result set is closed or not updatable
-
void -updateInt(int columnIndex, int x) -
Updates a column in the current or insert row.
-
void -updateInt(int columnIndex, int x) throws SQLException -
Updates a column in the current or insert row.
-
Parameters:
-
columnIndex - (1,2,...)
-
x - the value
-
Throws:
-
SQLException - if the result set is closed or not updatable
-
void -updateInt(String columnLabel, int x) -
Updates a column in the current or insert row.
-
void -updateInt(String columnLabel, int x) throws SQLException -
Updates a column in the current or insert row.
-
Parameters:
-
columnLabel - the column label
-
x - the value
-
Throws:
-
SQLException - if the result set is closed or not updatable
-
void -updateLong(int columnIndex, long x) -
Updates a column in the current or insert row.
-
void -updateLong(int columnIndex, long x) throws SQLException -
Updates a column in the current or insert row.
-
Parameters:
-
columnIndex - (1,2,...)
-
x - the value
-
Throws:
-
SQLException - if the result set is closed or not updatable
-
void -updateLong(String columnLabel, long x) -
Updates a column in the current or insert row.
-
void -updateLong(String columnLabel, long x) throws SQLException -
Updates a column in the current or insert row.
-
Parameters:
-
columnLabel - the column label
-
x - the value
-
Throws:
-
SQLException - if the result set is closed or not updatable
-
void -updateNull(int columnIndex) -
Updates a column in the current or insert row.
-
void -updateNull(int columnIndex) throws SQLException -
Updates a column in the current or insert row.
-
Parameters:
-
columnIndex - (1,2,...)
-
Throws:
-
SQLException - if the result set is closed or not updatable
-
void -updateNull(String columnLabel) -
Updates a column in the current or insert row.
-
void -updateNull(String columnLabel) throws SQLException -
Updates a column in the current or insert row.
-
Parameters:
-
columnLabel - the column label
-
Throws:
-
SQLException - if the result set is closed or not updatable
-
void -updateObject(int columnIndex, Object x, int scale) -
Updates a column in the current or insert row.
-
void -updateObject(int columnIndex, Object x, int scale) throws SQLException -
Updates a column in the current or insert row.
-
Parameters:
-
columnIndex - (1,2,...)
-
x - the value
-
scale - is ignored
-
Throws:
-
SQLException - if the result set is closed or not updatable
-
void -updateObject(String columnLabel, Object x, int scale) -
Updates a column in the current or insert row.
-
void -updateObject(String columnLabel, Object x, int scale) throws SQLException -
Updates a column in the current or insert row.
-
Parameters:
-
columnLabel - the column label
-
x - the value
-
scale - is ignored
-
Throws:
-
SQLException - if the result set is closed or not updatable
-
void -updateObject(int columnIndex, Object x) -
Updates a column in the current or insert row.
-
void -updateObject(int columnIndex, Object x) throws SQLException -
Updates a column in the current or insert row.
-
Parameters:
-
columnIndex - (1,2,...)
-
x - the value
-
Throws:
-
SQLException - if the result set is closed or not updatable
-
void -updateObject(String columnLabel, Object x) -
Updates a column in the current or insert row.
-
void -updateObject(String columnLabel, Object x) throws SQLException -
Updates a column in the current or insert row.
-
Parameters:
-
columnLabel - the column label
-
x - the value
-
Throws:
-
SQLException - if the result set is closed or not updatable
-
void -updateRef(int columnIndex, Ref x) -
[Not supported]
-
void -updateRef(int columnIndex, Ref x) throws SQLException -
[Not supported]
-
void -updateRef(String columnLabel, Ref x) -
[Not supported]
-
void -updateRef(String columnLabel, Ref x) throws SQLException -
[Not supported]
-
void -updateRow() -
Updates the current row.
-
void -updateRow() throws SQLException -
Updates the current row.
-
Throws:
-
SQLException - if the result set is closed, if the current row is - the insert row or if not on a valid row, or if the result set - it not updatable
-
void -updateShort(int columnIndex, short x) -
Updates a column in the current or insert row.
-
void -updateShort(int columnIndex, short x) throws SQLException -
Updates a column in the current or insert row.
-
Parameters:
-
columnIndex - (1,2,...)
-
x - the value
-
Throws:
-
SQLException - if the result set is closed or not updatable
-
void -updateShort(String columnLabel, short x) -
Updates a column in the current or insert row.
-
void -updateShort(String columnLabel, short x) throws SQLException -
Updates a column in the current or insert row.
-
Parameters:
-
columnLabel - the column label
-
x - the value
-
Throws:
-
SQLException - if the result set is closed or not updatable
-
void -updateString(int columnIndex, String x) -
Updates a column in the current or insert row.
-
void -updateString(int columnIndex, String x) throws SQLException -
Updates a column in the current or insert row.
-
Parameters:
-
columnIndex - (1,2,...)
-
x - the value
-
Throws:
-
SQLException - if the result set is closed or not updatable
-
void -updateString(String columnLabel, String x) -
Updates a column in the current or insert row.
-
void -updateString(String columnLabel, String x) throws SQLException -
Updates a column in the current or insert row.
-
Parameters:
-
columnLabel - the column label
-
x - the value
-
Throws:
-
SQLException - if the result set is closed or not updatable
-
void -updateTime(int columnIndex, Time x) -
Updates a column in the current or insert row.
-
void -updateTime(int columnIndex, Time x) throws SQLException -
Updates a column in the current or insert row.
-
Parameters:
-
columnIndex - (1,2,...)
-
x - the value
-
Throws:
-
SQLException - if the result set is closed or not updatable
-
void -updateTime(String columnLabel, Time x) -
Updates a column in the current or insert row.
-
void -updateTime(String columnLabel, Time x) throws SQLException -
Updates a column in the current or insert row.
-
Parameters:
-
columnLabel - the column label
-
x - the value
-
Throws:
-
SQLException - if the result set is closed or not updatable
-
void -updateTimestamp(int columnIndex, Timestamp x) -
Updates a column in the current or insert row.
-
void -updateTimestamp(int columnIndex, Timestamp x) throws SQLException -
Updates a column in the current or insert row.
-
Parameters:
-
columnIndex - (1,2,...)
-
x - the value
-
Throws:
-
SQLException - if the result set is closed or not updatable
-
void -updateTimestamp(String columnLabel, Timestamp x) -
Updates a column in the current or insert row.
-
void -updateTimestamp(String columnLabel, Timestamp x) throws SQLException -
Updates a column in the current or insert row.
-
Parameters:
-
columnLabel - the column label
-
x - the value
-
Throws:
-
SQLException - if the result set is closed or not updatable
-
boolean -wasNull() -
Returns whether the last column accessed was a null value.
-
boolean -wasNull() throws SQLException -
Returns whether the last column accessed was a null value.
-
Returns:
-
true if the last column accessed was a null value
-
-
diff --git a/tools/h2/docs/javadoc/org/h2/jdbc/JdbcResultSetMetaData.html b/tools/h2/docs/javadoc/org/h2/jdbc/JdbcResultSetMetaData.html deleted file mode 100755 index f9085c4..0000000 --- a/tools/h2/docs/javadoc/org/h2/jdbc/JdbcResultSetMetaData.html +++ /dev/null @@ -1,343 +0,0 @@ - - - -ResultSetMetaData - - - -
-

ResultSetMetaData

-Represents the meta data for a ResultSet.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Methods
String -getCatalogName(int column) -
Returns the catalog name.
-
String -getCatalogName(int column) throws SQLException -
Returns the catalog name.
-
Parameters:
-
column - the column index (1,2,...)
-
Returns:
-
the catalog name
-
Throws:
-
SQLException - if the result set is closed or invalid
-
String -getColumnClassName(int column) -
Gets the Java class name of the object that will be returned - if ResultSet.getObject is called.
-
String -getColumnClassName(int column) throws SQLException -
Gets the Java class name of the object that will be returned - if ResultSet.getObject is called.
-
Parameters:
-
column - the column index (1,2,...)
-
Returns:
-
the Java class name
-
Throws:
-
SQLException - if the result set is closed or invalid
-
int -getColumnCount() -
Returns the number of columns.
-
int -getColumnCount() throws SQLException -
Returns the number of columns.
-
Returns:
-
the number of columns
-
Throws:
-
SQLException - if the result set is closed or invalid
-
int -getColumnDisplaySize(int column) -
Gets the maximum display size for this column.
-
int -getColumnDisplaySize(int column) throws SQLException -
Gets the maximum display size for this column.
-
Parameters:
-
column - the column index (1,2,...)
-
Returns:
-
the display size
-
Throws:
-
SQLException - if the result set is closed or invalid
-
String -getColumnLabel(int column) -
Returns the column label.
-
String -getColumnLabel(int column) throws SQLException -
Returns the column label.
-
Parameters:
-
column - the column index (1,2,...)
-
Returns:
-
the column label
-
Throws:
-
SQLException - if the result set is closed or invalid
-
String -getColumnName(int column) -
Returns the column name.
-
String -getColumnName(int column) throws SQLException -
Returns the column name.
-
Parameters:
-
column - the column index (1,2,...)
-
Returns:
-
the column name
-
Throws:
-
SQLException - if the result set is closed or invalid
-
int -getColumnType(int column) -
Returns the data type of a column.
-
int -getColumnType(int column) throws SQLException -
Returns the data type of a column. - See also java.sql.Type.
-
Parameters:
-
column - the column index (1,2,...)
-
Returns:
-
the data type
-
Throws:
-
SQLException - if the result set is closed or invalid
-
String -getColumnTypeName(int column) -
Returns the data type name of a column.
-
String -getColumnTypeName(int column) throws SQLException -
Returns the data type name of a column.
-
Parameters:
-
column - the column index (1,2,...)
-
Returns:
-
the data type name
-
Throws:
-
SQLException - if the result set is closed or invalid
-
int -getPrecision(int column) -
Gets the precision for this column.
-
int -getPrecision(int column) throws SQLException -
Gets the precision for this column. - This method always returns 0.
-
Parameters:
-
column - the column index (1,2,...)
-
Returns:
-
the precision
-
Throws:
-
SQLException - if the result set is closed or invalid
-
int -getScale(int column) -
Gets the scale for this column.
-
int -getScale(int column) throws SQLException -
Gets the scale for this column. - This method always returns 0.
-
Parameters:
-
column - the column index (1,2,...)
-
Returns:
-
the scale
-
Throws:
-
SQLException - if the result set is closed or invalid
-
String -getSchemaName(int column) -
Returns the schema name.
-
String -getSchemaName(int column) throws SQLException -
Returns the schema name.
-
Parameters:
-
column - the column index (1,2,...)
-
Returns:
-
the schema name
-
Throws:
-
SQLException - if the result set is closed or invalid
-
String -getTableName(int column) -
Returns the table name.
-
String -getTableName(int column) throws SQLException -
Returns the table name.
-
Parameters:
-
column - the column index (1,2,...)
-
Returns:
-
the table name
-
Throws:
-
SQLException - if the result set is closed or invalid
-
boolean -isAutoIncrement(int column) -
Checks if this an autoincrement column.
-
boolean -isAutoIncrement(int column) throws SQLException -
Checks if this an autoincrement column. - It always returns false.
-
Parameters:
-
column - the column index (1,2,...)
-
Returns:
-
false
-
Throws:
-
SQLException - if the result set is closed or invalid
-
boolean -isCaseSensitive(int column) -
Checks if this column is case sensitive.
-
boolean -isCaseSensitive(int column) throws SQLException -
Checks if this column is case sensitive. - It always returns true.
-
Parameters:
-
column - the column index (1,2,...)
-
Returns:
-
true
-
Throws:
-
SQLException - if the result set is closed or invalid
-
boolean -isCurrency(int column) -
Checks if this is a currency column.
-
boolean -isCurrency(int column) throws SQLException -
Checks if this is a currency column. - It always returns false.
-
Parameters:
-
column - the column index (1,2,...)
-
Returns:
-
false
-
Throws:
-
SQLException - if the result set is closed or invalid
-
boolean -isDefinitelyWritable(int column) -
Checks whether a write on this column will definitely succeed.
-
boolean -isDefinitelyWritable(int column) throws SQLException -
Checks whether a write on this column will definitely succeed. - It always returns false.
-
Parameters:
-
column - the column index (1,2,...)
-
Returns:
-
false
-
Throws:
-
SQLException - if the result set is closed or invalid
-
int -isNullable(int column) -
Checks if this is nullable column.
-
int -isNullable(int column) throws SQLException -
Checks if this is nullable column. Returns - ResultSetMetaData.columnNullableUnknown if this is not a column of a - table. Otherwise, it returns ResultSetMetaData.columnNoNulls if the - column is not nullable, and ResultSetMetaData.columnNullable if it is - nullable.
-
Parameters:
-
column - the column index (1,2,...)
-
Returns:
-
ResultSetMetaData.column*
-
Throws:
-
SQLException - if the result set is closed or invalid
-
boolean -isReadOnly(int column) -
Checks if this column is read only.
-
boolean -isReadOnly(int column) throws SQLException -
Checks if this column is read only. - It always returns false.
-
Parameters:
-
column - the column index (1,2,...)
-
Returns:
-
false
-
Throws:
-
SQLException - if the result set is closed or invalid
-
boolean -isSearchable(int column) -
Checks if this column is searchable.
-
boolean -isSearchable(int column) throws SQLException -
Checks if this column is searchable. - It always returns true.
-
Parameters:
-
column - the column index (1,2,...)
-
Returns:
-
true
-
Throws:
-
SQLException - if the result set is closed or invalid
-
boolean -isSigned(int column) -
Checks if this column is signed.
-
boolean -isSigned(int column) throws SQLException -
Checks if this column is signed. - It always returns true.
-
Parameters:
-
column - the column index (1,2,...)
-
Returns:
-
true
-
Throws:
-
SQLException - if the result set is closed or invalid
-
boolean -isWritable(int column) -
Checks whether it is possible for a write on this column to succeed.
-
boolean -isWritable(int column) throws SQLException -
Checks whether it is possible for a write on this column to succeed. - It always returns true.
-
Parameters:
-
column - the column index (1,2,...)
-
Returns:
-
true
-
Throws:
-
SQLException - if the result set is closed or invalid
-
-
diff --git a/tools/h2/docs/javadoc/org/h2/jdbc/JdbcSQLException.html b/tools/h2/docs/javadoc/org/h2/jdbc/JdbcSQLException.html deleted file mode 100755 index 35d39c7..0000000 --- a/tools/h2/docs/javadoc/org/h2/jdbc/JdbcSQLException.html +++ /dev/null @@ -1,108 +0,0 @@ - - - -SQLException - - - -
-

SQLException

-Represents a database exception.

- - - - - - - - - - - - - - - - - - - - - - -
Methods
-JdbcSQLException(String message, String sql, String state, int errorCode, Throwable cause, String stackTrace) -
Creates a SQLException.
-
-JdbcSQLException(String message, String sql, String state, int errorCode, Throwable cause, String stackTrace) -
Creates a SQLException.
-
Parameters:
-
message - the reason
-
sql - the SQL statement
-
state - the SQL state
-
errorCode - the error code
-
cause - the exception that was the reason for this exception
-
stackTrace - the stack trace
-
String -getMessage() -
Get the detail error message.
-
String -getMessage() -
Get the detail error message.
-
Returns:
-
the message
-
String -getSQL() -
Returns the SQL statement.
-
String -getSQL() -
Returns the SQL statement. - SQL statements that contain '--hide--' are not listed.
-
Returns:
-
the SQL statement
-
void -printStackTrace() -
Prints the stack trace to the standard error stream.
-
void -printStackTrace() -
Prints the stack trace to the standard error stream.
-
void -printStackTrace(PrintWriter s) -
Prints the stack trace to the specified print writer.
-
void -printStackTrace(PrintWriter s) -
Prints the stack trace to the specified print writer.
-
Parameters:
-
s - the print writer
-
void -printStackTrace(PrintStream s) -
Prints the stack trace to the specified print stream.
-
void -printStackTrace(PrintStream s) -
Prints the stack trace to the specified print stream.
-
Parameters:
-
s - the print stream
-
String -toString() -
Returns the class name, the message, and in the server mode, the stack - trace of the server
-
String -toString() -
Returns the class name, the message, and in the server mode, the stack - trace of the server
-
Returns:
-
the string representation
-
-
- -
Fields
static String -HIDE_SQL = "--hide--" -
-

HIDE_SQL - = "--hide--" -

-
If the SQL statement contains this text, then it is never added to the - SQL exception. Hiding the SQL statement may be important if it contains a - passwords, such as a CREATE LINKED TABLE statement.
-
-
diff --git a/tools/h2/docs/javadoc/org/h2/jdbc/JdbcSavepoint.html b/tools/h2/docs/javadoc/org/h2/jdbc/JdbcSavepoint.html deleted file mode 100755 index 47cf23e..0000000 --- a/tools/h2/docs/javadoc/org/h2/jdbc/JdbcSavepoint.html +++ /dev/null @@ -1,37 +0,0 @@ - - - -Savepoint - - - -
-

Savepoint

-A savepoint is a point inside a transaction to where a transaction can be - rolled back. The tasks that where done before the savepoint are not rolled - back in this case.

- - - - - - - -
Methods
int -getSavepointId() -
Get the generated id of this savepoint.
-
int -getSavepointId() throws SQLException -
Get the generated id of this savepoint.
-
Returns:
-
the id
-
String -getSavepointName() -
Get the name of this savepoint.
-
String -getSavepointName() throws SQLException -
Get the name of this savepoint.
-
Returns:
-
the name
-
-
diff --git a/tools/h2/docs/javadoc/org/h2/jdbc/JdbcStatement.html b/tools/h2/docs/javadoc/org/h2/jdbc/JdbcStatement.html deleted file mode 100755 index 3d823b6..0000000 --- a/tools/h2/docs/javadoc/org/h2/jdbc/JdbcStatement.html +++ /dev/null @@ -1,589 +0,0 @@ - - - -Statement - - - -
-

Statement

-Represents a statement.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Methods
void -addBatch(String sql) -
Adds a statement to the batch.
-
void -addBatch(String sql) throws SQLException -
Adds a statement to the batch.
-
Parameters:
-
sql - the SQL statement
-
void -cancel() -
Cancels a currently running statement.
-
void -cancel() throws SQLException -
Cancels a currently running statement. - This method must be called from within another - thread than the execute method.
-
Throws:
-
SQLException - if this object is closed
-
void -clearBatch() -
Clears the batch.
-
void -clearBatch() throws SQLException -
Clears the batch.
-
void -clearWarnings() -
Clears all warnings.
-
void -clearWarnings() throws SQLException -
Clears all warnings. As this driver does not support warnings, - this call is ignored.
-
void -close() -
Closes this statement.
-
void -close() throws SQLException -
Closes this statement. - All result sets that where created by this statement - become invalid after calling this method.
-
boolean -execute(String sql) -
Executes an arbitrary statement.
-
boolean -execute(String sql) throws SQLException -
Executes an arbitrary statement. If another result set exists for this - statement, this will be closed (even if this statement fails). - - If the statement is a create or drop and does not throw an exception, the - current transaction (if any) is committed after executing the statement. - If auto commit is on, and the statement is not a select, this statement - will be committed.
-
Parameters:
-
sql - the SQL statement to execute
-
Returns:
-
true if a result set is available, false if not
-
boolean -execute(String sql, int autoGeneratedKeys) -
Executes a statement and returns the update count.
-
boolean -execute(String sql, int autoGeneratedKeys) throws SQLException -
Executes a statement and returns the update count. - This method just calls execute(String sql).
-
Parameters:
-
sql - the SQL statement
-
Returns:
-
the update count (number of row affected by an insert, - update or delete, or 0 if no rows or the statement was a - create, drop, commit or rollback)
-
Throws:
-
SQLException - if a database error occurred or a - select statement was executed
-
boolean -execute(String sql, int[] columnIndexes) -
Executes a statement and returns the update count.
-
boolean -execute(String sql, int[] columnIndexes) throws SQLException -
Executes a statement and returns the update count. - This method just calls execute(String sql).
-
Parameters:
-
sql - the SQL statement
-
Returns:
-
the update count (number of row affected by an insert, - update or delete, or 0 if no rows or the statement was a - create, drop, commit or rollback)
-
Throws:
-
SQLException - if a database error occurred or a - select statement was executed
-
boolean -execute(String sql, String[] columnNames) -
Executes a statement and returns the update count.
-
boolean -execute(String sql, String[] columnNames) throws SQLException -
Executes a statement and returns the update count. - This method just calls execute(String sql).
-
Parameters:
-
sql - the SQL statement
-
Returns:
-
the update count (number of row affected by an insert, - update or delete, or 0 if no rows or the statement was a - create, drop, commit or rollback)
-
Throws:
-
SQLException - if a database error occurred or a - select statement was executed
-
int[] -executeBatch() -
Executes the batch.
-
int[] -executeBatch() throws SQLException -
Executes the batch.
-
Returns:
-
the array of update counts
-
ResultSet -executeQuery(String sql) -
Executes a query (select statement) and returns the result set.
-
ResultSet -executeQuery(String sql) throws SQLException -
Executes a query (select statement) and returns the result set. - If another result set exists for this statement, this will be closed - (even if this statement fails).
-
Parameters:
-
sql - the SQL statement to execute
-
Returns:
-
the result set
-
int -executeUpdate(String sql) -
Executes a statement (insert, update, delete, create, drop) - and returns the update count.
-
int -executeUpdate(String sql) throws SQLException -
Executes a statement (insert, update, delete, create, drop) - and returns the update count. - If another result set exists for this statement, this will be closed - (even if this statement fails). - - If the statement is a create or drop and does not throw an exception, - the current transaction (if any) is committed after executing the statement. - If auto commit is on, this statement will be committed.
-
Parameters:
-
sql - the SQL statement
-
Returns:
-
the update count (number of row affected by an insert, - update or delete, or 0 if no rows or the statement was a - create, drop, commit or rollback)
-
Throws:
-
SQLException - if a database error occurred or a - select statement was executed
-
int -executeUpdate(String sql, int autoGeneratedKeys) -
Executes a statement and returns the update count.
-
int -executeUpdate(String sql, int autoGeneratedKeys) throws SQLException -
Executes a statement and returns the update count. - This method just calls executeUpdate(String sql).
-
Parameters:
-
sql - the SQL statement
-
Returns:
-
the update count (number of row affected by an insert, - update or delete, or 0 if no rows or the statement was a - create, drop, commit or rollback)
-
Throws:
-
SQLException - if a database error occurred or a - select statement was executed
-
int -executeUpdate(String sql, int[] columnIndexes) -
Executes a statement and returns the update count.
-
int -executeUpdate(String sql, int[] columnIndexes) throws SQLException -
Executes a statement and returns the update count. - This method just calls executeUpdate(String sql).
-
Parameters:
-
sql - the SQL statement
-
Returns:
-
the update count (number of row affected by an insert, - update or delete, or 0 if no rows or the statement was a - create, drop, commit or rollback)
-
Throws:
-
SQLException - if a database error occurred or a - select statement was executed
-
int -executeUpdate(String sql, String[] columnNames) -
Executes a statement and returns the update count.
-
int -executeUpdate(String sql, String[] columnNames) throws SQLException -
Executes a statement and returns the update count. - This method just calls executeUpdate(String sql).
-
Parameters:
-
sql - the SQL statement
-
Returns:
-
the update count (number of row affected by an insert, - update or delete, or 0 if no rows or the statement was a - create, drop, commit or rollback)
-
Throws:
-
SQLException - if a database error occurred or a - select statement was executed
-
Connection -getConnection() -
Returns the connection that created this object.
-
Connection -getConnection() -
Returns the connection that created this object.
-
Returns:
-
the connection
-
int -getFetchDirection() -
Gets the fetch direction.
-
int -getFetchDirection() throws SQLException -
Gets the fetch direction.
-
Returns:
-
FETCH_FORWARD
-
Throws:
-
SQLException - if this object is closed
-
int -getFetchSize() -
Gets the number of rows suggested to read in one step.
-
int -getFetchSize() throws SQLException -
Gets the number of rows suggested to read in one step.
-
Returns:
-
the current fetch size
-
Throws:
-
SQLException - if this object is closed
-
ResultSet -getGeneratedKeys() -
Return a result set that contains the last generated autoincrement key - for this connection.
-
ResultSet -getGeneratedKeys() throws SQLException -
Return a result set that contains the last generated autoincrement key - for this connection.
-
Returns:
-
the result set with one row and one column containing the key
-
Throws:
-
SQLException - if this object is closed
-
int -getMaxFieldSize() -
Gets the maximum number of bytes for a result set column.
-
int -getMaxFieldSize() throws SQLException -
Gets the maximum number of bytes for a result set column.
-
Returns:
-
always 0 for no limit
-
Throws:
-
SQLException - if this object is closed
-
int -getMaxRows() -
Gets the maximum number of rows for a ResultSet.
-
int -getMaxRows() throws SQLException -
Gets the maximum number of rows for a ResultSet.
-
Returns:
-
the number of rows where 0 means no limit
-
Throws:
-
SQLException - if this object is closed
-
boolean -getMoreResults() -
Moves to the next result set - however there is always only one result - set.
-
boolean -getMoreResults() throws SQLException -
Moves to the next result set - however there is always only one result - set. This call also closes the current result set (if there is one). - Returns true if there is a next result set (that means - it always - returns false).
-
Returns:
-
false
-
Throws:
-
SQLException - if this object is closed.
-
boolean -getMoreResults(int current) -
Move to the next result set.
-
boolean -getMoreResults(int current) throws SQLException -
Move to the next result set. - This method always returns false.
-
Parameters:
-
current - Statement.CLOSE_CURRENT_RESULT, - Statement.KEEP_CURRENT_RESULT, - or Statement.CLOSE_ALL_RESULTS
-
Returns:
-
false
-
int -getQueryTimeout() -
Gets the current query timeout in seconds.
-
int -getQueryTimeout() throws SQLException -
Gets the current query timeout in seconds. - This method will return 0 if no query timeout is set. - The result is rounded to the next second.
-
Returns:
-
the timeout in seconds
-
Throws:
-
SQLException - if this object is closed
-
ResultSet -getResultSet() -
Returns the last result set produces by this statement.
-
ResultSet -getResultSet() throws SQLException -
Returns the last result set produces by this statement.
-
Returns:
-
the result set
-
int -getResultSetConcurrency() -
Gets the result set concurrency created by this object.
-
int -getResultSetConcurrency() throws SQLException -
Gets the result set concurrency created by this object.
-
Returns:
-
the concurrency
-
int -getResultSetHoldability() -
Gets the result set holdability.
-
int -getResultSetHoldability() throws SQLException -
Gets the result set holdability.
-
Returns:
-
the holdability
-
int -getResultSetType() -
Gets the result set type.
-
int -getResultSetType() throws SQLException -
Gets the result set type.
-
Returns:
-
the type
-
Throws:
-
SQLException - if this object is closed
-
int -getUpdateCount() -
Returns the last update count of this statement.
-
int -getUpdateCount() throws SQLException -
Returns the last update count of this statement.
-
Returns:
-
the update count (number of row affected by an insert, - update or delete, or 0 if no rows or the statement was a - create, drop, commit or rollback; -1 if the statement was a select).
-
Throws:
-
SQLException - if this object is closed or invalid
-
SQLWarning -getWarnings() -
Gets the first warning reported by calls on this object.
-
SQLWarning -getWarnings() throws SQLException -
Gets the first warning reported by calls on this object. - This driver does not support warnings, and will always return null.
-
Returns:
-
null
-
boolean -isClosed() -
Returns whether this statement is closed.
-
boolean -isClosed() throws SQLException -
Returns whether this statement is closed.
-
Returns:
-
true if the statement is closed
-
boolean -isPoolable() -
Returns whether this object is poolable.
-
boolean -isPoolable() -
Returns whether this object is poolable.
-
Returns:
-
false
-
void -setCursorName(String name) -
Sets the name of the cursor.
-
void -setCursorName(String name) throws SQLException -
Sets the name of the cursor. This call is ignored.
-
Parameters:
-
name - ignored
-
Throws:
-
SQLException - if this object is closed
-
void -setEscapeProcessing(boolean enable) -
Enables or disables processing or JDBC escape syntax.
-
void -setEscapeProcessing(boolean enable) throws SQLException -
Enables or disables processing or JDBC escape syntax. - See also Connection.nativeSQL.
-
Parameters:
-
enable - - true (default) or false (no conversion is attempted)
-
Throws:
-
SQLException - if this object is closed
-
void -setFetchDirection(int direction) -
Sets the fetch direction.
-
void -setFetchDirection(int direction) throws SQLException -
Sets the fetch direction. - This call is ignored by this driver.
-
Parameters:
-
direction - ignored
-
Throws:
-
SQLException - if this object is closed
-
void -setFetchSize(int rows) -
Sets the number of rows suggested to read in one step.
-
void -setFetchSize(int rows) throws SQLException -
Sets the number of rows suggested to read in one step. - This value cannot be higher than the maximum rows (setMaxRows) - set by the statement or prepared statement, otherwise an exception - is throws. Setting the value to 0 will set the default value. - The default value can be changed using the system property - h2.serverResultSetFetchSize.
-
Parameters:
-
rows - the number of rows
-
Throws:
-
SQLException - if this object is closed
-
void -setMaxFieldSize(int max) -
Sets the maximum number of bytes for a result set column.
-
void -setMaxFieldSize(int max) throws SQLException -
Sets the maximum number of bytes for a result set column. - This method does currently do nothing for this driver.
-
Parameters:
-
max - the maximum size - ignored
-
Throws:
-
SQLException - if this object is closed
-
void -setMaxRows(int maxRows) -
Gets the maximum number of rows for a ResultSet.
-
void -setMaxRows(int maxRows) throws SQLException -
Gets the maximum number of rows for a ResultSet.
-
Parameters:
-
maxRows - the number of rows where 0 means no limit
-
Throws:
-
SQLException - if this object is closed
-
void -setPoolable(boolean poolable) -
Requests that this object should be pooled or not.
-
void -setPoolable(boolean poolable) -
Requests that this object should be pooled or not. - This call is ignored.
-
Parameters:
-
poolable - the requested value
-
void -setQueryTimeout(int seconds) -
Sets the current query timeout in seconds.
-
void -setQueryTimeout(int seconds) throws SQLException -
Sets the current query timeout in seconds. Calling this method will - commit an open transaction, even if the value is the same as before. - Changing the value will affect all statements of this connection. This - method does not commit a transaction, and rolling back a transaction does - not affect this setting.
-
Parameters:
-
seconds - the timeout in seconds - 0 means no timeout, values - smaller 0 will throw an exception
-
Throws:
-
SQLException - if this object is closed
-
-
diff --git a/tools/h2/docs/javadoc/org/h2/jdbcx/JdbcConnectionPool.html b/tools/h2/docs/javadoc/org/h2/jdbcx/JdbcConnectionPool.html deleted file mode 100755 index 85dcd85..0000000 --- a/tools/h2/docs/javadoc/org/h2/jdbcx/JdbcConnectionPool.html +++ /dev/null @@ -1,150 +0,0 @@ - - - -JdbcConnectionPool - - - -
-

JdbcConnectionPool

-A simple standalone JDBC connection pool. - It is based on the - - MiniConnectionPoolManager written by Christian d'Heureuse (Java 1.5) - . It is used as follows: -
- import java.sql.*;
- import org.h2.jdbcx.JdbcConnectionPool;
- public class Test {
-     public static void main(String... args) throws Exception {
-         JdbcConnectionPool cp = JdbcConnectionPool.create(
-             "jdbc:h2:~/test", "sa", "sa");
-         for (String sql : args) {
-             Connection conn = cp.getConnection();
-             conn.createStatement().execute(sql);
-             conn.close();
-         }
-         cp.dispose();
-     }
- }


- - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Methods
static JdbcConnectionPool -create(ConnectionPoolDataSource dataSource) -
Constructs a new connection pool.
-
static JdbcConnectionPool -create(ConnectionPoolDataSource dataSource) -
Constructs a new connection pool.
-
Parameters:
-
dataSource - the data source to create connections
-
Returns:
-
the connection pool
-
static JdbcConnectionPool -create(String url, String user, String password) -
Constructs a new connection pool for H2 databases.
-
static JdbcConnectionPool -create(String url, String user, String password) -
Constructs a new connection pool for H2 databases.
-
Parameters:
-
url - the database URL of the H2 connection
-
user - the user name
-
password - the password
-
Returns:
-
the connection pool
-
void -dispose() -
Closes all unused pooled connections.
-
void -dispose() throws SQLException -
Closes all unused pooled connections.
-
int -getActiveConnections() -
Returns the number of active (open) connections of this pool.
-
int -getActiveConnections() -
Returns the number of active (open) connections of this pool. This is the - number of Connection objects that have been issued by - getConnection() for which Connection.close() has - not yet been called.
-
Returns:
-
the number of active connections.
-
Connection -getConnection() -
Retrieves a connection from the connection pool.
-
Connection -getConnection() throws SQLException -
Retrieves a connection from the connection pool. If - maxConnections connections are already in use, the method - waits until a connection becomes available or timeout - seconds elapsed. When the application is finished using the connection, - it must close it in order to return it to the pool. - If no connection becomes available within the given timeout, an exception - with SQL state 08001 and vendor code 8001 is thrown.
-
Returns:
-
a new Connection object.
-
Throws:
-
SQLException - when a new connection could not be established, - or a timeout occurred
-
int -getLoginTimeout() -
Gets the maximum time in seconds to wait for a free connection.
-
int -getLoginTimeout() -
Gets the maximum time in seconds to wait for a free connection.
-
Returns:
-
the timeout in seconds
-
int -getMaxConnections() -
Gets the maximum number of connections to use.
-
int -getMaxConnections() -
Gets the maximum number of connections to use.
-
Returns:
-
the max the maximum number of connections
-
void -setLoginTimeout(int seconds) -
Sets the maximum time in seconds to wait for a free connection.
-
void -setLoginTimeout(int seconds) -
Sets the maximum time in seconds to wait for a free connection. - The default timeout is 5 minutes. Calling this method with the - value 0 will set the timeout to the default value.
-
Parameters:
-
seconds - the timeout, 0 meaning the default
-
void -setMaxConnections(int max) -
Sets the maximum number of connections to use from now on.
-
void -setMaxConnections(int max) -
Sets the maximum number of connections to use from now on. - The default value is 10 connections.
-
Parameters:
-
max - the maximum number of connections
-
-
diff --git a/tools/h2/docs/javadoc/org/h2/jdbcx/JdbcDataSource.html b/tools/h2/docs/javadoc/org/h2/jdbcx/JdbcDataSource.html deleted file mode 100755 index 23585e3..0000000 --- a/tools/h2/docs/javadoc/org/h2/jdbcx/JdbcDataSource.html +++ /dev/null @@ -1,288 +0,0 @@ - - - -JdbcDataSource - - - -
-

JdbcDataSource

-A data source for H2 database connections. It is a factory for XAConnection - and Connection objects. This class is usually registered in a JNDI naming - service. To create a data source object and register it with a JNDI service, - use the following code: - -
- import org.h2.jdbcx.JdbcDataSource;
- import javax.naming.Context;
- import javax.naming.InitialContext;
- JdbcDataSource ds = new JdbcDataSource();
- ds.setURL("jdbc:h2:˜/test");
- ds.setUser("sa");
- ds.setPassword("sa");
- Context ctx = new InitialContext();
- ctx.bind("jdbc/dsName", ds);
- - To use a data source that is already registered, use the following code: - -
- import java.sql.Connection;
- import javax.sql.DataSource;
- import javax.naming.Context;
- import javax.naming.InitialContext;
- Context ctx = new InitialContext();
- DataSource ds = (DataSource) ctx.lookup("jdbc/dsName");
- Connection conn = ds.getConnection();
- - In this example the user name and password are serialized as - well; this may be a security problem in some cases.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Methods
-JdbcDataSource() -
The public constructor.
-
-JdbcDataSource() -
The public constructor.
-
Connection -getConnection() -
Open a new connection using the current URL, user name and password.
-
Connection -getConnection() throws SQLException -
Open a new connection using the current URL, user name and password.
-
Returns:
-
the connection
-
Connection -getConnection(String user, String password) -
Open a new connection using the current URL and the specified user name - and password.
-
Connection -getConnection(String user, String password) throws SQLException -
Open a new connection using the current URL and the specified user name - and password.
-
Parameters:
-
user - the user name
-
password - the password
-
Returns:
-
the connection
-
String -getDescription() -
Get the current description.
-
String -getDescription() -
Get the current description.
-
Returns:
-
the description
-
PrintWriter -getLogWriter() -
Get the current log writer for this object.
-
PrintWriter -getLogWriter() -
Get the current log writer for this object.
-
Returns:
-
the log writer
-
int -getLoginTimeout() -
Get the login timeout in seconds, 0 meaning no timeout.
-
int -getLoginTimeout() -
Get the login timeout in seconds, 0 meaning no timeout.
-
Returns:
-
the timeout in seconds
-
String -getPassword() -
Get the current password.
-
String -getPassword() -
Get the current password.
-
Returns:
-
the password
-
PooledConnection -getPooledConnection() -
Open a new pooled connection using the current URL, user name and password.
-
PooledConnection -getPooledConnection() throws SQLException -
Open a new pooled connection using the current URL, user name and password.
-
Returns:
-
the connection
-
PooledConnection -getPooledConnection(String user, String password) -
Open a new pooled connection using the current URL and the specified user - name and password.
-
PooledConnection -getPooledConnection(String user, String password) throws SQLException -
Open a new pooled connection using the current URL and the specified user - name and password.
-
Parameters:
-
user - the user name
-
password - the password
-
Returns:
-
the connection
-
Reference -getReference() -
Get a new reference for this object, using the current settings.
-
Reference -getReference() -
Get a new reference for this object, using the current settings.
-
Returns:
-
the new reference
-
String -getURL() -
Get the current URL.
-
String -getURL() -
Get the current URL.
-
Returns:
-
the URL
-
String -getUser() -
Get the current user name.
-
String -getUser() -
Get the current user name.
-
Returns:
-
the user name
-
XAConnection -getXAConnection() -
Open a new XA connection using the current URL, user name and password.
-
XAConnection -getXAConnection() throws SQLException -
Open a new XA connection using the current URL, user name and password.
-
Returns:
-
the connection
-
XAConnection -getXAConnection(String user, String password) -
Open a new XA connection using the current URL and the specified user - name and password.
-
XAConnection -getXAConnection(String user, String password) throws SQLException -
Open a new XA connection using the current URL and the specified user - name and password.
-
Parameters:
-
user - the user name
-
password - the password
-
Returns:
-
the connection
-
void -setDescription(String description) -
Set the description.
-
void -setDescription(String description) -
Set the description.
-
Parameters:
-
description - the new description
-
void -setLogWriter(PrintWriter out) -
Set the current log writer for this object.
-
void -setLogWriter(PrintWriter out) -
Set the current log writer for this object. - This value is ignored by this database.
-
Parameters:
-
out - the log writer
-
void -setLoginTimeout(int timeout) -
Set the login timeout in seconds, 0 meaning no timeout.
-
void -setLoginTimeout(int timeout) -
Set the login timeout in seconds, 0 meaning no timeout. - The default value is 0. - This value is ignored by this database.
-
Parameters:
-
timeout - the timeout in seconds
-
void -setPassword(String password) -
Set the current password.
-
void -setPassword(String password) -
Set the current password.
-
Parameters:
-
password - the new password.
-
void -setPasswordChars(char[] password) -
Set the current password in the form of a char array.
-
void -setPasswordChars(char[] password) -
Set the current password in the form of a char array.
-
Parameters:
-
password - the new password in the form of a char array.
-
void -setURL(String url) -
Set the current URL.
-
void -setURL(String url) -
Set the current URL.
-
Parameters:
-
url - the new URL
-
void -setUser(String user) -
Set the current user name.
-
void -setUser(String user) -
Set the current user name.
-
Parameters:
-
user - the new user name
-
-
diff --git a/tools/h2/docs/javadoc/org/h2/jdbcx/JdbcDataSourceFactory.html b/tools/h2/docs/javadoc/org/h2/jdbcx/JdbcDataSourceFactory.html deleted file mode 100755 index 981534c..0000000 --- a/tools/h2/docs/javadoc/org/h2/jdbcx/JdbcDataSourceFactory.html +++ /dev/null @@ -1,43 +0,0 @@ - - - -JdbcDataSourceFactory - - - -
-

JdbcDataSourceFactory

-This class is used to create new DataSource objects. - An application should not use this class directly.

- - - - - - - -
Methods
-JdbcDataSourceFactory() -
The public constructor to create new factory objects.
-
-JdbcDataSourceFactory() -
The public constructor to create new factory objects.
-
Object -getObjectInstance(Object obj, Name name, Context nameCtx, Hashtable environment) -
Creates a new object using the specified location or reference - information.
-
Object -getObjectInstance(Object obj, Name name, Context nameCtx, Hashtable environment) -
Creates a new object using the specified location or reference - information.
-
Parameters:
-
obj - the reference (this factory only supports objects of type - javax.naming.Reference)
-
name - unused
-
nameCtx - unused
-
environment - unused
-
Returns:
-
the new JdbcDataSource, or null if the reference class name is - not JdbcDataSource.
-
-
diff --git a/tools/h2/docs/javadoc/org/h2/jdbcx/JdbcXAConnection.html b/tools/h2/docs/javadoc/org/h2/jdbcx/JdbcXAConnection.html deleted file mode 100755 index 9d7072f..0000000 --- a/tools/h2/docs/javadoc/org/h2/jdbcx/JdbcXAConnection.html +++ /dev/null @@ -1,209 +0,0 @@ - - - -JdbcXAConnection - - - -
-

JdbcXAConnection

-This class provides support for distributed transactions. - An application developer usually does not use this interface. - It is used by the transaction manager internally.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Methods
void -addConnectionEventListener(ConnectionEventListener listener) -
Register a new listener for the connection.
-
void -addConnectionEventListener(ConnectionEventListener listener) -
Register a new listener for the connection.
-
Parameters:
-
listener - the event listener
-
void -close() -
Close the physical connection.
-
void -close() throws SQLException -
Close the physical connection. - This method is usually called by the connection pool.
-
Throws:
-
SQLException
-
void -commit(Xid xid, boolean onePhase) -
Commit a transaction.
-
void -commit(Xid xid, boolean onePhase) throws XAException -
Commit a transaction.
-
Parameters:
-
xid - the transaction id
-
onePhase - use a one-phase protocol if true
-
Throws:
-
XAException
-
void -end(Xid xid, int flags) -
End a transaction.
-
void -end(Xid xid, int flags) throws XAException -
End a transaction.
-
Parameters:
-
xid - the transaction id
-
flags - TMSUCCESS, TMFAIL, or TMSUSPEND
-
Throws:
-
XAException
-
void -forget(Xid xid) -
Forget a transaction.
-
void -forget(Xid xid) -
Forget a transaction. - This method does not have an effect for this database.
-
Parameters:
-
xid - the transaction id
-
Connection -getConnection() -
Get a connection that is a handle to the physical connection.
-
Connection -getConnection() throws SQLException -
Get a connection that is a handle to the physical connection. This method - is usually called by the connection pool. This method closes the last - connection handle if one exists.
-
Returns:
-
the connection
-
int -getTransactionTimeout() -
Get the transaction timeout.
-
int -getTransactionTimeout() -
Get the transaction timeout.
-
Returns:
-
0
-
XAResource -getXAResource() -
Get the XAResource object.
-
XAResource -getXAResource() -
Get the XAResource object.
-
Returns:
-
itself
-
boolean -isSameRM(XAResource xares) -
Checks if this is the same XAResource.
-
boolean -isSameRM(XAResource xares) -
Checks if this is the same XAResource.
-
Parameters:
-
xares - the other object
-
Returns:
-
true if this is the same object
-
int -prepare(Xid xid) -
Prepare a transaction.
-
int -prepare(Xid xid) throws XAException -
Prepare a transaction.
-
Parameters:
-
xid - the transaction id
-
Returns:
-
XA_OK
-
Throws:
-
XAException
-
Xid[] -recover(int flag) -
Get the list of prepared transaction branches.
-
Xid[] -recover(int flag) throws XAException -
Get the list of prepared transaction branches. - This method is called by the transaction manager during recovery.
-
Parameters:
-
flag - TMSTARTRSCAN, TMENDRSCAN, or TMNOFLAGS. If no other flags are set, - TMNOFLAGS must be used.
-
Returns:
-
zero or more Xid objects
-
Throws:
-
XAException
-
void -removeConnectionEventListener(ConnectionEventListener listener) -
Remove the event listener.
-
void -removeConnectionEventListener(ConnectionEventListener listener) -
Remove the event listener.
-
Parameters:
-
listener - the event listener
-
void -rollback(Xid xid) -
Roll back a transaction.
-
void -rollback(Xid xid) throws XAException -
Roll back a transaction.
-
Parameters:
-
xid - the transaction id
-
Throws:
-
XAException
-
boolean -setTransactionTimeout(int seconds) -
Set the transaction timeout.
-
boolean -setTransactionTimeout(int seconds) -
Set the transaction timeout.
-
Parameters:
-
seconds - ignored
-
Returns:
-
false
-
void -start(Xid xid, int flags) -
Start or continue to work on a transaction.
-
void -start(Xid xid, int flags) throws XAException -
Start or continue to work on a transaction.
-
Parameters:
-
xid - the transaction id
-
flags - TMNOFLAGS, TMJOIN, or TMRESUME
-
Throws:
-
XAException
-
-
diff --git a/tools/h2/docs/javadoc/org/h2/jdbcx/JdbcXid.html b/tools/h2/docs/javadoc/org/h2/jdbcx/JdbcXid.html deleted file mode 100755 index adccb73..0000000 --- a/tools/h2/docs/javadoc/org/h2/jdbcx/JdbcXid.html +++ /dev/null @@ -1,46 +0,0 @@ - - - -JdbcXid - - - -
-

JdbcXid

-An object of this class represents a transaction id.

- - - - - - - - - - -
Methods
byte[] -getBranchQualifier() -
The transaction branch identifier.
-
byte[] -getBranchQualifier() -
The transaction branch identifier.
-
Returns:
-
the identifier
-
int -getFormatId() -
Get the format id.
-
int -getFormatId() -
Get the format id.
-
Returns:
-
the format id
-
byte[] -getGlobalTransactionId() -
The global transaction identifier.
-
byte[] -getGlobalTransactionId() -
The global transaction identifier.
-
Returns:
-
the transaction id
-
-
diff --git a/tools/h2/docs/javadoc/org/h2/tools/Backup.html b/tools/h2/docs/javadoc/org/h2/tools/Backup.html deleted file mode 100755 index 40bb9d7..0000000 --- a/tools/h2/docs/javadoc/org/h2/tools/Backup.html +++ /dev/null @@ -1,67 +0,0 @@ - - - -Backup - - - -
-

Backup

-Creates a backup of a database. -
- This tool copies all database files. The database must be closed before using - this tool. To create a backup while the database is in use, run the BACKUP - SQL statement. In an emergency, for example if the application is not - responding, creating a backup using the Backup tool is possible by using the - quiet mode. However, if the database is changed while the backup is running - in quiet mode, the backup could be corrupt.

- - - - - - - - - - -
Methods
static void -execute(String zipFileName, String directory, String db, boolean quiet) -
Backs up database files.
-
static void -execute(String zipFileName, String directory, String db, boolean quiet) throws SQLException -
Backs up database files.
-
Parameters:
-
zipFileName - the name of the target backup file (including path)
-
directory - the source directory name
-
db - the source database name (null if there is only one database)
-
quiet - don't print progress information
-
Throws:
-
SQLException
-
static void -main(String... args) -
Options are case sensitive.
-
static void -main(String... args) throws SQLException -
Options are case sensitive. Supported options are: - - - - - - - - - - - -
[-help] or [-?]Print the list of options
[-file <filename>]The target file name (default: backup.zip)
[-dir <dir>]The source directory (default: .)
[-db <database>]Source database; not required if there is only one
[-quiet]Do not print progress information
-
Parameters:
-
args - the command line arguments
-
void -runTool(String... args) -
void -runTool(String... args) throws SQLException -
-
-
diff --git a/tools/h2/docs/javadoc/org/h2/tools/ChangeFileEncryption.html b/tools/h2/docs/javadoc/org/h2/tools/ChangeFileEncryption.html deleted file mode 100755 index 573f2ff..0000000 --- a/tools/h2/docs/javadoc/org/h2/tools/ChangeFileEncryption.html +++ /dev/null @@ -1,71 +0,0 @@ - - - -ChangeFileEncryption - - - -
-

ChangeFileEncryption

-Allows changing the database file encryption password or algorithm. -
- This tool can not be used to change a password of a user. - The database must be closed before using this tool.

- - - - - - - - - - -
Methods
static void -execute(String dir, String db, String cipher, char[] decryptPassword, char[] encryptPassword, boolean quiet) -
Changes the password for a database.
-
static void -execute(String dir, String db, String cipher, char[] decryptPassword, char[] encryptPassword, boolean quiet) throws SQLException -
Changes the password for a database. - The passwords must be supplied as char arrays and are cleaned in this method. - The database must be closed before calling this method.
-
Parameters:
-
dir - the directory (. for the current directory)
-
db - the database name (null for all databases)
-
cipher - the cipher (AES, XTEA)
-
decryptPassword - the decryption password as a char array
-
encryptPassword - the encryption password as a char array
-
quiet - don't print progress information
-
Throws:
-
SQLException
-
static void -main(String... args) -
Options are case sensitive.
-
static void -main(String... args) throws SQLException -
Options are case sensitive. Supported options are: - - - - - - - - - - - - - - - -
[-help] or [-?]Print the list of options
[-cipher type]The encryption type (AES or XTEA)
[-dir <dir>]The database directory (default: .)
[-db <database>]Database name (all databases if not set)
[-decrypt <pwd>]The decryption password (if not set: not yet encrypted)
[-encrypt <pwd>]The encryption password (if not set: do not encrypt)
[-quiet]Do not print progress information
-
Parameters:
-
args - the command line arguments
-
void -runTool(String... args) -
void -runTool(String... args) throws SQLException -
-
-
diff --git a/tools/h2/docs/javadoc/org/h2/tools/CompressTool.html b/tools/h2/docs/javadoc/org/h2/tools/CompressTool.html deleted file mode 100755 index 98172fb..0000000 --- a/tools/h2/docs/javadoc/org/h2/tools/CompressTool.html +++ /dev/null @@ -1,58 +0,0 @@ - - - -CompressTool - - - -
-

CompressTool

-A tool to losslessly compress data, and expand the compressed data again.

- - - - - - - - - - -
Methods
static CompressTool -getInstance() -
Get a new instance.
-
static CompressTool -getInstance() -
Get a new instance. Each instance uses a separate buffer, so multiple - instances can be used concurrently. However each instance alone is not - multithreading safe.
-
Returns:
-
a new instance
-
byte[] -compress(byte[] in, String algorithm) -
Compressed the data using the specified algorithm.
-
byte[] -compress(byte[] in, String algorithm) -
Compressed the data using the specified algorithm. If no algorithm is - supplied, LZF is used
-
Parameters:
-
in - the byte array with the original data
-
algorithm - the algorithm (LZF, DEFLATE)
-
Returns:
-
the compressed data
-
Throws:
-
SQLException - if a error occurs
-
byte[] -expand(byte[] in) -
Expands the compressed data.
-
byte[] -expand(byte[] in) -
Expands the compressed data.
-
Parameters:
-
in - the byte array with the compressed data
-
Returns:
-
the uncompressed data
-
Throws:
-
SQLException - if a error occurs
-
-
diff --git a/tools/h2/docs/javadoc/org/h2/tools/Console.html b/tools/h2/docs/javadoc/org/h2/tools/Console.html deleted file mode 100755 index 0889307..0000000 --- a/tools/h2/docs/javadoc/org/h2/tools/Console.html +++ /dev/null @@ -1,58 +0,0 @@ - - - -Console - - - -
-

Console

-Starts the H2 Console (web-) server, as well as the TCP and PG server.

- - - - - - - -
Methods
static void -main(String... args) -
When running without options, -tcp, -web, -browser and -pg are started.
-
static void -main(String... args) throws SQLException -
When running without options, -tcp, -web, -browser and -pg are started. -
- Options are case sensitive. Supported options are: - - - - - - - - - - - - - -
[-help] or [-?]Print the list of options
[-web]Start the web server with the H2 Console
[-tool]Start the icon or window that allows to start a browser
[-browser]Start a browser connecting to the web server
[-tcp]Start the TCP server
[-pg]Start the PG server
- For each Server, additional options are available; - for details, see the Server tool.
- If a service can not be started, the program - terminates with an exit code of 1.
-
Parameters:
-
args - the command line arguments
-
void -runTool(String... args) -
This tool starts the H2 Console (web-) server, as well as the TCP and PG - server.
-
void -runTool(String... args) throws SQLException -
This tool starts the H2 Console (web-) server, as well as the TCP and PG - server. For JDK 1.6, a system tray icon is created, for platforms that - support it. Otherwise, a small window opens.
-
Parameters:
-
args - the command line arguments
-
-
diff --git a/tools/h2/docs/javadoc/org/h2/tools/ConvertTraceFile.html b/tools/h2/docs/javadoc/org/h2/tools/ConvertTraceFile.html deleted file mode 100755 index d4e1946..0000000 --- a/tools/h2/docs/javadoc/org/h2/tools/ConvertTraceFile.html +++ /dev/null @@ -1,44 +0,0 @@ - - - -ConvertTraceFile - - - -
-

ConvertTraceFile

-Converts a .trace.db file to a SQL script and Java source code. -
- SQL statement statistics are listed as well.

- - - - - - - -
Methods
static void -main(String... args) -
Options are case sensitive.
-
static void -main(String... args) throws SQLException -
Options are case sensitive. Supported options are: - - - - - - - - - -
[-help] or [-?]Print the list of options
[-traceFile <file>]The trace file name (default: test.trace.db)
[-script <file>]The script file name (default: test.sql)
[-javaClass <file>]The Java directory and class file name (default: Test)
-
Parameters:
-
args - the command line arguments
-
void -runTool(String... args) -
void -runTool(String... args) throws SQLException -
-
-
diff --git a/tools/h2/docs/javadoc/org/h2/tools/CreateCluster.html b/tools/h2/docs/javadoc/org/h2/tools/CreateCluster.html deleted file mode 100755 index 57b502d..0000000 --- a/tools/h2/docs/javadoc/org/h2/tools/CreateCluster.html +++ /dev/null @@ -1,65 +0,0 @@ - - - -CreateCluster - - - -
-

CreateCluster

-Creates a cluster from a standalone database. -
- Copies a database to another location if required.

- - - - - - - - - - -
Methods
static void -main(String... args) -
Options are case sensitive.
-
static void -main(String... args) throws SQLException -
Options are case sensitive. Supported options are: - - - - - - - - - - - - - -
[-help] or [-?]Print the list of options
[-urlSource "<url>"]The database URL of the source database (jdbc:h2:...)
[-urlTarget "<url>"]The database URL of the target database (jdbc:h2:...)
[-user <user>]The user name (default: sa)
[-password <pwd>]The password
[-serverList <list>]The comma separated list of host names or IP addresses
-
Parameters:
-
args - the command line arguments
-
void -execute(String urlSource, String urlTarget, String user, String password, String serverList) -
Creates a cluster.
-
void -execute(String urlSource, String urlTarget, String user, String password, String serverList) throws SQLException -
Creates a cluster.
-
Parameters:
-
urlSource - the database URL of the original database
-
urlTarget - the database URL of the copy
-
user - the user name
-
password - the password
-
serverList - the server list
-
Throws:
-
SQLException
-
void -runTool(String... args) -
void -runTool(String... args) throws SQLException -
-
-
diff --git a/tools/h2/docs/javadoc/org/h2/tools/Csv.html b/tools/h2/docs/javadoc/org/h2/tools/Csv.html deleted file mode 100755 index 4f19d1d..0000000 --- a/tools/h2/docs/javadoc/org/h2/tools/Csv.html +++ /dev/null @@ -1,278 +0,0 @@ - - - -Csv - - - -
-

Csv

-A facility to read from and write to CSV (comma separated values) files. When - reading, the BOM (the byte-order-mark) character 0xfeff at the beginning of - the file is ignored.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Methods
static Csv -getInstance() -
Get a new object of this class.
-
static Csv -getInstance() -
Get a new object of this class.
-
Returns:
-
the new instance
-
char -getEscapeCharacter() -
Get the current escape character.
-
char -getEscapeCharacter() -
Get the current escape character.
-
Returns:
-
the escape character
-
char -getFieldDelimiter() -
Get the current field delimiter.
-
char -getFieldDelimiter() -
Get the current field delimiter.
-
Returns:
-
the field delimiter
-
char -getFieldSeparatorRead() -
Get the current field separator for reading.
-
char -getFieldSeparatorRead() -
Get the current field separator for reading.
-
Returns:
-
the field separator
-
String -getFieldSeparatorWrite() -
Get the current field separator for writing.
-
String -getFieldSeparatorWrite() -
Get the current field separator for writing.
-
Returns:
-
the field separator
-
String -getNullString() -
Get the current null string.
-
String -getNullString() -
Get the current null string.
-
Returns:
-
the null string.
-
String -getRowSeparatorWrite() -
Get the current row separator for writing.
-
String -getRowSeparatorWrite() -
Get the current row separator for writing.
-
Returns:
-
the row separator
-
ResultSet -read(String inputFileName, String[] colNames, String charset) -
Reads from the CSV file and returns a result set.
-
ResultSet -read(String inputFileName, String[] colNames, String charset) throws SQLException -
Reads from the CSV file and returns a result set. The rows in the result - set are created on demand, that means the file is kept open until all - rows are read or the result set is closed. -
- If the columns are read from the CSV file, then the following rules are - used: columns names that start with a letter or '_', and only - contain letters, '_', and digits, are considered case insensitive - and are converted to uppercase. Other column names are considered - case sensitive (that means they need to be quoted when accessed).
-
Parameters:
-
inputFileName - the file name
-
colNames - or null if the column names should be read from the CSV - file
-
charset - the charset or null to use the system default charset - (see system property file.encoding)
-
Returns:
-
the result set
-
Throws:
-
SQLException
-
ResultSet -read(Reader reader, String[] colNames) -
Reads CSV data from a reader and returns a result set.
-
ResultSet -read(Reader reader, String[] colNames) throws IOException -
Reads CSV data from a reader and returns a result set. The rows in the - result set are created on demand, that means the reader is kept open - until all rows are read or the result set is closed.
-
Parameters:
-
reader - the reader
-
colNames - or null if the column names should be read from the CSV file
-
Returns:
-
the result set
-
Throws:
-
SQLException, - IOException
-
void -setEscapeCharacter(char escapeCharacter) -
Set the escape character (used to escape the field delimiter).
-
void -setEscapeCharacter(char escapeCharacter) -
Set the escape character (used to escape the field delimiter). The - default is " (a double quote). The value 0 means no escape character is used.
-
Parameters:
-
escapeCharacter - the escape character
-
void -setFieldDelimiter(char fieldDelimiter) -
Set the field delimiter.
-
void -setFieldDelimiter(char fieldDelimiter) -
Set the field delimiter. The default is " (a double quote). - The value 0 means no field delimiter is used.
-
Parameters:
-
fieldDelimiter - the field delimiter
-
void -setFieldSeparatorRead(char fieldSeparatorRead) -
Override the field separator for reading.
-
void -setFieldSeparatorRead(char fieldSeparatorRead) -
Override the field separator for reading. The default is ','.
-
Parameters:
-
fieldSeparatorRead - the field separator
-
void -setFieldSeparatorWrite(String fieldSeparatorWrite) -
Override the field separator for writing.
-
void -setFieldSeparatorWrite(String fieldSeparatorWrite) -
Override the field separator for writing. The default is ",".
-
Parameters:
-
fieldSeparatorWrite - the field separator
-
void -setLineSeparator(String lineSeparator) -
Set the line separator.
-
void -setLineSeparator(String lineSeparator) -
Set the line separator.
-
Parameters:
-
lineSeparator - the line separator
-
void -setNullString(String nullString) -
Set the value that represents NULL.
-
void -setNullString(String nullString) -
Set the value that represents NULL.
-
Parameters:
-
nullString - the null
-
void -setRowSeparatorWrite(String rowSeparatorWrite) -
Override the end-of-row marker for writing.
-
void -setRowSeparatorWrite(String rowSeparatorWrite) -
Override the end-of-row marker for writing. The default is null. After - writing the end-of-row marker, a line feed is written (\n or \r\n - depending on the system settings).
-
Parameters:
-
rowSeparatorWrite - the row separator
-
int -write(Writer writer, ResultSet rs) -
Writes the result set to a file in the CSV format.
-
int -write(Writer writer, ResultSet rs) throws SQLException -
Writes the result set to a file in the CSV format.
-
Parameters:
-
writer - the writer
-
rs - the result set
-
Returns:
-
the number of rows written
-
Throws:
-
SQLException
-
int -write(String outputFileName, ResultSet rs, String charset) -
Writes the result set to a file in the CSV format.
-
int -write(String outputFileName, ResultSet rs, String charset) throws SQLException -
Writes the result set to a file in the CSV format. The result set is read - using the following loop: - -
- while (rs.next()) {
-     writeRow(row);
- }
-
Parameters:
-
outputFileName - the name of the csv file
-
rs - the result set - the result set must be positioned before the - first row.
-
charset - the charset or null to use the system default charset - (see system property file.encoding)
-
Returns:
-
the number of rows written
-
Throws:
-
SQLException
-
int -write(Connection conn, String outputFileName, String sql, String charset) -
Writes the result set of a query to a file in the CSV format.
-
int -write(Connection conn, String outputFileName, String sql, String charset) throws SQLException -
Writes the result set of a query to a file in the CSV format.
-
Parameters:
-
conn - the connection
-
outputFileName - the file name
-
sql - the query
-
charset - the charset or null to use the system default charset - (see system property file.encoding)
-
Returns:
-
the number of rows written
-
Throws:
-
SQLException
-
-
diff --git a/tools/h2/docs/javadoc/org/h2/tools/DeleteDbFiles.html b/tools/h2/docs/javadoc/org/h2/tools/DeleteDbFiles.html deleted file mode 100755 index 7683909..0000000 --- a/tools/h2/docs/javadoc/org/h2/tools/DeleteDbFiles.html +++ /dev/null @@ -1,59 +0,0 @@ - - - -DeleteDbFiles - - - -
-

DeleteDbFiles

-Deletes all files belonging to a database. -
- The database must be closed before calling this tool.

- - - - - - - - - - -
Methods
static void -execute(String dir, String db, boolean quiet) -
Deletes the database files.
-
static void -execute(String dir, String db, boolean quiet) throws SQLException -
Deletes the database files.
-
Parameters:
-
dir - the directory
-
db - the database name (null for all databases)
-
quiet - don't print progress information
-
Throws:
-
SQLException
-
static void -main(String... args) -
Options are case sensitive.
-
static void -main(String... args) throws SQLException -
Options are case sensitive. Supported options are: - - - - - - - - - -
[-help] or [-?]Print the list of options
[-dir <dir>]The directory (default: .)
[-db <database>]The database name
[-quiet]Do not print progress information
-
Parameters:
-
args - the command line arguments
-
void -runTool(String... args) -
void -runTool(String... args) throws SQLException -
-
-
diff --git a/tools/h2/docs/javadoc/org/h2/tools/MultiDimension.html b/tools/h2/docs/javadoc/org/h2/tools/MultiDimension.html deleted file mode 100755 index 6ca6cdd..0000000 --- a/tools/h2/docs/javadoc/org/h2/tools/MultiDimension.html +++ /dev/null @@ -1,97 +0,0 @@ - - - -MultiDimension - - - -
-

MultiDimension

-A tool to help an application execute multi-dimensional range queries. - The algorithm used is database independent, the only requirement - is that the engine supports a range index (for example b-tree).

- - - - - - - - - - - - - - - - - - - -
Methods
static MultiDimension -getInstance() -
Get the singleton.
-
static MultiDimension -getInstance() -
Get the singleton.
-
Returns:
-
the singleton
-
int -compare(long[] a, long[] b) -
int -compare(long[] a, long[] b) -
-
int -deinterleave(long scalar, int dimensions, int dim) -
Gets one of the original multi-dimensional values from a scalar value.
-
int -deinterleave(long scalar, int dimensions, int dim) -
Gets one of the original multi-dimensional values from a scalar value.
-
Parameters:
-
scalar - the scalar value
-
dimensions - the number of dimensions
-
dim - the dimension of the returned value (starting from 0)
-
Returns:
-
the value
-
String -generatePreparedQuery(String table, String scalarColumn, String[] columns) -
Generates an optimized multi-dimensional range query.
-
String -generatePreparedQuery(String table, String scalarColumn, String[] columns) -
Generates an optimized multi-dimensional range query. - The query contains parameters. It can only be used with the H2 database.
-
Parameters:
-
table - the table name
-
columns - the list of columns
-
scalarColumn - the column name of the computed scalar column
-
Returns:
-
the query
-
ResultSet -getResult(PreparedStatement prep, int[] min, int[] max) -
Executes a prepared query that was generated using generatePreparedQuery.
-
ResultSet -getResult(PreparedStatement prep, int[] min, int[] max) throws SQLException -
Executes a prepared query that was generated using generatePreparedQuery.
-
Parameters:
-
prep - the prepared statement
-
min - the lower values
-
max - the upper values
-
Returns:
-
the result set
-
long -interleave(int[] values) -
Convert the multi-dimensional value into a one-dimensional (scalar) value.
-
long -interleave(int[] values) -
Convert the multi-dimensional value into a one-dimensional (scalar) value. - This is done by interleaving the bits of the values. - Each values must be bigger or equal to 0. The maximum value - is dependent on the number of dimensions. For two keys, it is 32 bit, - for 3: 21 bit, 4: 16 bit, 5: 12 bit, 6: 10 bit, 7: 9 bit, 8: 8 bit.
-
Parameters:
-
values - the multi-dimensional value
-
Returns:
-
the scalar value
-
-
diff --git a/tools/h2/docs/javadoc/org/h2/tools/Recover.html b/tools/h2/docs/javadoc/org/h2/tools/Recover.html deleted file mode 100755 index c5e251f..0000000 --- a/tools/h2/docs/javadoc/org/h2/tools/Recover.html +++ /dev/null @@ -1,64 +0,0 @@ - - - -Recover - - - -
-

Recover

-Helps recovering a corrupted database.

- - - - - - - - - - -
Methods
static void -execute(String dir, String db) -
Dumps the contents of a database to a SQL script file.
-
static void -execute(String dir, String db) throws SQLException -
Dumps the contents of a database to a SQL script file.
-
Parameters:
-
dir - the directory
-
db - the database name (null for all databases)
-
static void -main(String... args) -
Options are case sensitive.
-
static void -main(String... args) throws SQLException -
Options are case sensitive. Supported options are: - - - - - - - - - -
[-help] or [-?]Print the list of options
[-dir <dir>]The directory (default: .)
[-db <database>]The database name (all databases if not set)
[-trace]Print additional trace information
- Encrypted databases need to be decrypted first.
-
Parameters:
-
args - the command line arguments
-
void -runTool(String... args) -
Dumps the contents of a database file to a human readable text file.
-
void -runTool(String... args) throws SQLException -
Dumps the contents of a database file to a human readable text file. This - text file can be used to recover most of the data. This tool does not - open the database and can be used even if the database files are - corrupted. A database can get corrupted if there is a bug in the database - engine or file system software, or if an application writes into the - database file that doesn't understand the the file format, or if there is - a hardware problem.
-
Parameters:
-
args - the command line arguments
-
-
diff --git a/tools/h2/docs/javadoc/org/h2/tools/Restore.html b/tools/h2/docs/javadoc/org/h2/tools/Restore.html deleted file mode 100755 index 4f27f8e..0000000 --- a/tools/h2/docs/javadoc/org/h2/tools/Restore.html +++ /dev/null @@ -1,60 +0,0 @@ - - - -Restore - - - -
-

Restore

-Restores a H2 database by extracting the database files from a .zip file.

- - - - - - - - - - -
Methods
static void -execute(String zipFileName, String directory, String db, boolean quiet) -
Restores database files.
-
static void -execute(String zipFileName, String directory, String db, boolean quiet) throws SQLException -
Restores database files.
-
Parameters:
-
zipFileName - the name of the backup file
-
directory - the directory name
-
db - the database name (null for all databases)
-
quiet - don't print progress information
-
Throws:
-
SQLException
-
static void -main(String... args) -
Options are case sensitive.
-
static void -main(String... args) throws SQLException -
Options are case sensitive. Supported options are: - - - - - - - - - - - -
[-help] or [-?]Print the list of options
[-file <filename>]The source file name (default: backup.zip)
[-dir <dir>]The target directory (default: .)
[-db <database>]The target database name (as stored if not set)
[-quiet]Do not print progress information
-
Parameters:
-
args - the command line arguments
-
void -runTool(String... args) -
void -runTool(String... args) throws SQLException -
-
-
diff --git a/tools/h2/docs/javadoc/org/h2/tools/RunScript.html b/tools/h2/docs/javadoc/org/h2/tools/RunScript.html deleted file mode 100755 index 8b96eff..0000000 --- a/tools/h2/docs/javadoc/org/h2/tools/RunScript.html +++ /dev/null @@ -1,98 +0,0 @@ - - - -RunScript - - - -
-

RunScript

-Runs a SQL script against a database.

- - - - - - - - - - - - - -
Methods
static ResultSet -execute(Connection conn, Reader reader) -
Executes the SQL commands in a script file against a database.
-
static ResultSet -execute(Connection conn, Reader reader) throws SQLException -
Executes the SQL commands in a script file against a database.
-
Parameters:
-
conn - the connection to a database
-
reader - the reader
-
Returns:
-
the last result set
-
static void -execute(String url, String user, String password, String fileName, String charsetName, boolean continueOnError) -
Executes the SQL commands in a script file against a database.
-
static void -execute(String url, String user, String password, String fileName, String charsetName, boolean continueOnError) throws SQLException -
Executes the SQL commands in a script file against a database.
-
Parameters:
-
url - the database URL
-
user - the user name
-
password - the password
-
fileName - the script file
-
charsetName - the character set name or null for UTF-8
-
continueOnError - if execution should be continued if an error occurs
-
static void -main(String... args) -
Options are case sensitive.
-
static void -main(String... args) throws SQLException -
Options are case sensitive. Supported options are: - - - - - - - - - - - - - - - - - - - - - -
[-help] or [-?]Print the list of options
[-url "<url>"]The database URL (jdbc:...)
[-user <user>]The user name (default: sa)
[-password <pwd>]The password
[-script <file>]The script file to run (default: backup.sql)
[-driver <class>]The JDBC driver class to use (not required in most cases)
[-showResults]Show the statements and the results of queries
[-checkResults]Check if the query results match the expected results
[-continueOnError]Continue even if the script contains errors
[-options ...]RUNSCRIPT options (embedded H2; -*Results not supported)
-
Parameters:
-
args - the command line arguments
-
void -runTool(String... args) -
Executes the contents of a SQL script file against a database.
-
void -runTool(String... args) throws SQLException -
Executes the contents of a SQL script file against a database. - This tool is usually used to create a database from script. - It can also be used to analyze performance problems by running - the tool using Java profiler settings such as: -
- java -Xrunhprof:cpu=samples,depth=16 ...
- To include local files when using remote databases, use the special - syntax: -
- @INCLUDE fileName
- This syntax is only supported by this tool. Embedded RUNSCRIPT SQL - statements will be executed by the database.
-
Parameters:
-
args - the command line arguments
-
-
diff --git a/tools/h2/docs/javadoc/org/h2/tools/Script.html b/tools/h2/docs/javadoc/org/h2/tools/Script.html deleted file mode 100755 index 8ae4128..0000000 --- a/tools/h2/docs/javadoc/org/h2/tools/Script.html +++ /dev/null @@ -1,76 +0,0 @@ - - - -Script - - - -
-

Script

-Creates a SQL script file by extracting the schema and data of a database.

- - - - - - - - - - - - - -
Methods
static void -execute(String url, String user, String password, String fileName) -
Backs up a database to a SQL script file.
-
static void -execute(String url, String user, String password, String fileName) throws SQLException -
Backs up a database to a SQL script file.
-
Parameters:
-
url - the database URL
-
user - the user name
-
password - the password
-
fileName - the script file
-
static void -execute(String url, String user, String password, OutputStream out) -
Backs up a database to a stream.
-
static void -execute(String url, String user, String password, OutputStream out) throws SQLException -
Backs up a database to a stream. The stream is not closed.
-
Parameters:
-
url - the database URL
-
user - the user name
-
password - the password
-
out - the output stream
-
static void -main(String... args) -
Options are case sensitive.
-
static void -main(String... args) throws SQLException -
Options are case sensitive. Supported options are: - - - - - - - - - - - - - - - -
[-help] or [-?]Print the list of options
[-url "<url>"]The database URL (jdbc:...)
[-user <user>]The user name (default: sa)
[-password <pwd>]The password
[-script <file>]The target script file name (default: backup.sql)
[-options ...]A list of options (only for embedded H2, see RUNSCRIPT)
[-quiet]Do not print progress information
-
Parameters:
-
args - the command line arguments
-
void -runTool(String... args) -
void -runTool(String... args) throws SQLException -
-
-
diff --git a/tools/h2/docs/javadoc/org/h2/tools/Server.html b/tools/h2/docs/javadoc/org/h2/tools/Server.html deleted file mode 100755 index 0b1c354..0000000 --- a/tools/h2/docs/javadoc/org/h2/tools/Server.html +++ /dev/null @@ -1,274 +0,0 @@ - - - -Server - - - -
-

Server

-Starts the H2 Console (web-) server, TCP, and PG server.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Methods
static Server -createPgServer(String... args) -
Create a new PG server, but does not start it yet.
-
static Server -createPgServer(String... args) throws SQLException -
Create a new PG server, but does not start it yet. - Example: -
- Server server =
-     Server.createPgServer("-pgAllowOthers").start();
-
Parameters:
-
args - the argument list
-
Returns:
-
the server
-
static Server -createTcpServer(String... args) -
Create a new TCP server, but does not start it yet.
-
static Server -createTcpServer(String... args) throws SQLException -
Create a new TCP server, but does not start it yet. Example: - -
- Server server = Server.createTcpServer(
-     new String[] { "-tcpAllowOthers" }).start();
-
Parameters:
-
args - the argument list
-
Returns:
-
the server
-
static Server -createWebServer(String... args) -
Create a new web server, but does not start it yet.
-
static Server -createWebServer(String... args) throws SQLException -
Create a new web server, but does not start it yet. Example: - -
- Server server = Server.createWebServer(
-     new String[] { "-trace" }).start();
-
Parameters:
-
args - the argument list
-
Returns:
-
the server
-
static void -main(String... args) -
When running without options, -tcp, -web, -browser and -pg are started.
-
static void -main(String... args) throws SQLException -
When running without options, -tcp, -web, -browser and -pg are started. -
- Options are case sensitive. Supported options are: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
[-help] or [-?]Print the list of options
[-web]Start the web server with the H2 Console
[-webAllowOthers]Allow other computers to connect - see below
[-webDaemon]Use a daemon thread
[-webPort <port>]The port (default: 8082)
[-webSSL]Use encrypted (HTTPS) connections
[-browser]Start a browser connecting to the web server
[-tcp]Start the TCP server
[-tcpAllowOthers]Allow other computers to connect - see below
[-tcpDaemon]Use a daemon thread
[-tcpPort <port>]The port (default: 9092)
[-tcpSSL]Use encrypted (SSL) connections
[-tcpPassword <pwd>]The password for shutting down a TCP server
[-tcpShutdown "<url>"]Stop the TCP server; example: tcp://localhost
[-tcpShutdownForce]Do not wait until all connections are closed
[-pg]Start the PG server
[-pgAllowOthers]Allow other computers to connect - see below
[-pgDaemon]Use a daemon thread
[-pgPort <port>]The port (default: 5435)
[-baseDir <dir>]The base directory for H2 databases (all servers)
[-ifExists]Only existing databases may be opened (all servers)
[-trace]Print additional trace information (all servers)
- The options -xAllowOthers are potentially risky. -
- For details, see Advanced Topics / Protection against Remote Access.
-
Parameters:
-
args - the command line arguments
-
static void -openBrowser(String url) -
Open a new browser tab or window with the given URL.
-
static void -openBrowser(String url) -
Open a new browser tab or window with the given URL.
-
Parameters:
-
url - the URL to open
-
static void -shutdownTcpServer(String url, String password, boolean force, boolean all) -
Shutdown one or all TCP server.
-
static void -shutdownTcpServer(String url, String password, boolean force, boolean all) throws SQLException -
Shutdown one or all TCP server. If force is set to false, the server will not - allow new connections, but not kill existing connections, instead it will - stop if the last connection is closed. If force is set to true, existing - connections are killed. After calling the method with force=false, it is - not possible to call it again with force=true because new connections are - not allowed. Example: - -
- Server.shutdownTcpServer(
-     "tcp://localhost:9094", password, true, false);
-
Parameters:
-
url - example: tcp://localhost:9094
-
password - the password to use ("" for no password)
-
force - the shutdown (don't wait)
-
all - whether all TCP servers that are running in the JVM - should be stopped
-
static void -startWebServer(Connection conn) -
Start a web server and a browser that uses the given connection.
-
static void -startWebServer(Connection conn) throws SQLException -
Start a web server and a browser that uses the given connection. The - current transaction is preserved. This is specially useful to manually - inspect the database when debugging. This method return as soon as the - user has disconnected.
-
Parameters:
-
conn - the database connection (the database must be open)
-
-Server(Service service, String... args) -
Create a new server for the given service.
-
-Server(Service service, String... args) throws SQLException -
Create a new server for the given service.
-
Parameters:
-
service - the service
-
args - the command line arguments
-
int -getPort() -
Gets the port this server is listening on.
-
int -getPort() -
Gets the port this server is listening on.
-
Returns:
-
the port
-
Service -getService() -
Get the service attached to this server.
-
Service -getService() -
Get the service attached to this server.
-
Returns:
-
the service
-
String -getStatus() -
Get the status of this server.
-
String -getStatus() -
Get the status of this server.
-
Returns:
-
the status
-
String -getURL() -
Gets the URL of this server.
-
String -getURL() -
Gets the URL of this server.
-
Returns:
-
the url
-
boolean -isRunning(boolean traceError) -
Checks if the server is running.
-
boolean -isRunning(boolean traceError) -
Checks if the server is running.
-
Parameters:
-
traceError - if errors should be written
-
Returns:
-
if the server is running
-
void -runTool(String... args) -
void -runTool(String... args) throws SQLException -
-
Server -start() -
Tries to start the server.
-
Server -start() throws SQLException -
Tries to start the server.
-
Returns:
-
the server if successful
-
Throws:
-
SQLException - if the server could not be started
-
void -stop() -
Stops the server.
-
void -stop() -
Stops the server.
-
-
diff --git a/tools/h2/docs/javadoc/org/h2/tools/Shell.html b/tools/h2/docs/javadoc/org/h2/tools/Shell.html deleted file mode 100755 index a5a60f4..0000000 --- a/tools/h2/docs/javadoc/org/h2/tools/Shell.html +++ /dev/null @@ -1,95 +0,0 @@ - - - -Shell - - - -
-

Shell

-Interactive command line tool to access a database using JDBC.

- - - - - - - - - - - - - - - - - - - -
Methods
static void -main(String... args) -
Options are case sensitive.
-
static void -main(String... args) throws SQLException -
Options are case sensitive. Supported options are: - - - - - - - - - - - - - -
[-help] or [-?]Print the list of options
[-url "<url>"]The database URL (jdbc:h2:...)
[-user <user>]The user name
[-password <pwd>]The password
[-driver <class>]The JDBC driver class to use (not required in most cases)
[-sql "<statements>"]Execute the SQL statements and exit
- If special characters don't work as expected, you may need to use - -Dfile.encoding=UTF-8 (Mac OS X) or CP850 (Windows).
-
Parameters:
-
args - the command line arguments
-
void -print(String s) -
Print the string without newline, and flush.
-
void -print(String s) -
Print the string without newline, and flush.
-
Parameters:
-
s - the string to print
-
void -runTool(String... args) -
Run the shell tool with the given command line settings.
-
void -runTool(String... args) throws SQLException -
Run the shell tool with the given command line settings.
-
Parameters:
-
args - the command line settings
-
void -setErr(PrintStream err) -
Sets the standard error stream.
-
void -setErr(PrintStream err) -
Sets the standard error stream.
-
Parameters:
-
err - the new standard error stream
-
void -setIn(InputStream in) -
Redirects the standard input.
-
void -setIn(InputStream in) -
Redirects the standard input. By default, System.in is used.
-
Parameters:
-
in - the input stream to use
-
void -setInReader(BufferedReader reader) -
Redirects the standard input.
-
void -setInReader(BufferedReader reader) -
Redirects the standard input. By default, System.in is used.
-
Parameters:
-
reader - the input stream reader to use
-
-
diff --git a/tools/h2/docs/javadoc/org/h2/tools/SimpleResultSet.SimpleArray.html b/tools/h2/docs/javadoc/org/h2/tools/SimpleResultSet.SimpleArray.html deleted file mode 100755 index b8c4875..0000000 --- a/tools/h2/docs/javadoc/org/h2/tools/SimpleResultSet.SimpleArray.html +++ /dev/null @@ -1,47 +0,0 @@ - - - -SimpleResultSet.SimpleArray - - - -
-

SimpleResultSet.SimpleArray

-A simple array implementation, - backed by an object array

- - - - - - - - - - -
Methods
Object -getArray() -
Get the object array.
-
Object -getArray() -
Get the object array.
-
Returns:
-
the object array
-
int -getBaseType() -
Get the base type of this array.
-
int -getBaseType() -
Get the base type of this array.
-
Returns:
-
Types.NULL
-
String -getBaseTypeName() -
Get the base type name of this array.
-
String -getBaseTypeName() -
Get the base type name of this array.
-
Returns:
-
"NULL"
-
-
diff --git a/tools/h2/docs/javadoc/org/h2/tools/SimpleResultSet.html b/tools/h2/docs/javadoc/org/h2/tools/SimpleResultSet.html deleted file mode 100755 index 50f49ef..0000000 --- a/tools/h2/docs/javadoc/org/h2/tools/SimpleResultSet.html +++ /dev/null @@ -1,905 +0,0 @@ - - - -SimpleResultSet - - - -
-

SimpleResultSet

-This class is a simple result set and meta data implementation. - It can be used in Java functions that return a result set. - Only the most basic methods are implemented, the others throw an exception. - This implementation is standalone, and only relies on standard classes. - It can be extended easily if required. - - An application can create a result set using the following code: - -
- SimpleResultSet rs = new SimpleResultSet();
- rs.addColumn("ID", Types.INTEGER, 10, 0);
- rs.addColumn("NAME", Types.VARCHAR, 255, 0);
- rs.addRow(0, "Hello" });
- rs.addRow(1, "World" });


- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Methods
-SimpleResultSet() -
This constructor is used if the result set is later populated with addRow.
-
-SimpleResultSet() -
This constructor is used if the result set is later populated with addRow.
-
-SimpleResultSet(SimpleRowSource source) -
This constructor is used if the result set should retrieve the rows using - the specified row source object.
-
-SimpleResultSet(SimpleRowSource source) -
This constructor is used if the result set should retrieve the rows using - the specified row source object.
-
Parameters:
-
source - the row source
-
void -addColumn(String name, int sqlType, int precision, int scale) -
Adds a column to the result set.
-
void -addColumn(String name, int sqlType, int precision, int scale) -
Adds a column to the result set. - All columns must be added before adding rows.
-
Parameters:
-
name - null is replaced with C1, C2,...
-
sqlType - the value returned in getColumnType(..) (ignored internally)
-
precision - the precision
-
scale - the scale
-
void -addRow(Object... row) -
Add a new row to the result set.
-
void -addRow(Object... row) -
Add a new row to the result set. - Do not use this method when using a RowSource.
-
Parameters:
-
row - the row as an array of objects
-
void -beforeFirst() -
Moves the current position to before the first row, that means resets the - result set.
-
void -beforeFirst() throws SQLException -
Moves the current position to before the first row, that means resets the - result set.
-
void -close() -
Closes the result set and releases the resources.
-
void -close() -
Closes the result set and releases the resources.
-
int -findColumn(String columnLabel) -
Searches for a specific column in the result set.
-
int -findColumn(String columnLabel) throws SQLException -
Searches for a specific column in the result set. A case-insensitive - search is made.
-
Parameters:
-
columnLabel - the column label
-
Returns:
-
the column index (1,2,...)
-
Throws:
-
SQLException - if the column is not found or if the result set is - closed
-
Array -getArray(int columnIndex) -
Returns the value as a java.sql.Array.
-
Array -getArray(int columnIndex) throws SQLException -
Returns the value as a java.sql.Array.
-
Parameters:
-
columnIndex - (1,2,...)
-
Returns:
-
the value
-
Array -getArray(String columnLabel) -
Returns the value as a java.sql.Array.
-
Array -getArray(String columnLabel) throws SQLException -
Returns the value as a java.sql.Array.
-
Parameters:
-
columnLabel - the column label
-
Returns:
-
the value
-
BigDecimal -getBigDecimal(int columnIndex) -
Returns the value as a java.math.BigDecimal.
-
BigDecimal -getBigDecimal(int columnIndex) throws SQLException -
Returns the value as a java.math.BigDecimal.
-
Parameters:
-
columnIndex - (1,2,...)
-
Returns:
-
the value
-
BigDecimal -getBigDecimal(String columnLabel) -
Returns the value as a java.math.BigDecimal.
-
BigDecimal -getBigDecimal(String columnLabel) throws SQLException -
Returns the value as a java.math.BigDecimal.
-
Parameters:
-
columnLabel - the column label
-
Returns:
-
the value
-
boolean -getBoolean(int columnIndex) -
Returns the value as a boolean.
-
boolean -getBoolean(int columnIndex) throws SQLException -
Returns the value as a boolean.
-
Parameters:
-
columnIndex - (1,2,...)
-
Returns:
-
the value
-
boolean -getBoolean(String columnLabel) -
Returns the value as a boolean.
-
boolean -getBoolean(String columnLabel) throws SQLException -
Returns the value as a boolean.
-
Parameters:
-
columnLabel - the column label
-
Returns:
-
the value
-
byte -getByte(int columnIndex) -
Returns the value as a byte.
-
byte -getByte(int columnIndex) throws SQLException -
Returns the value as a byte.
-
Parameters:
-
columnIndex - (1,2,...)
-
Returns:
-
the value
-
byte -getByte(String columnLabel) -
Returns the value as a byte.
-
byte -getByte(String columnLabel) throws SQLException -
Returns the value as a byte.
-
Parameters:
-
columnLabel - the column label
-
Returns:
-
the value
-
byte[] -getBytes(int columnIndex) -
Returns the value as a byte array.
-
byte[] -getBytes(int columnIndex) throws SQLException -
Returns the value as a byte array.
-
Parameters:
-
columnIndex - (1,2,...)
-
Returns:
-
the value
-
byte[] -getBytes(String columnLabel) -
Returns the value as a byte array.
-
byte[] -getBytes(String columnLabel) throws SQLException -
Returns the value as a byte array.
-
Parameters:
-
columnLabel - the column label
-
Returns:
-
the value
-
String -getCatalogName(int columnIndex) -
Returns null.
-
String -getCatalogName(int columnIndex) -
Returns null.
-
Parameters:
-
columnIndex - (1,2,...)
-
Returns:
-
null
-
String -getColumnClassName(int columnIndex) -
Returns null.
-
String -getColumnClassName(int columnIndex) -
Returns null.
-
Parameters:
-
columnIndex - (1,2,...)
-
Returns:
-
null
-
int -getColumnCount() -
Returns the column count.
-
int -getColumnCount() -
Returns the column count.
-
Returns:
-
the column count
-
int -getColumnDisplaySize(int columnIndex) -
Returns 15.
-
int -getColumnDisplaySize(int columnIndex) -
Returns 15.
-
Parameters:
-
columnIndex - (1,2,...)
-
Returns:
-
15
-
String -getColumnLabel(int columnIndex) -
Returns the column label.
-
String -getColumnLabel(int columnIndex) throws SQLException -
Returns the column label.
-
Parameters:
-
columnIndex - (1,2,...)
-
Returns:
-
the column label
-
String -getColumnName(int columnIndex) -
Returns the column name.
-
String -getColumnName(int columnIndex) throws SQLException -
Returns the column name.
-
Parameters:
-
columnIndex - (1,2,...)
-
Returns:
-
the column name
-
int -getColumnType(int columnIndex) -
Returns the SQL type.
-
int -getColumnType(int columnIndex) throws SQLException -
Returns the SQL type.
-
Parameters:
-
columnIndex - (1,2,...)
-
Returns:
-
the SQL type
-
String -getColumnTypeName(int columnIndex) -
Returns null.
-
String -getColumnTypeName(int columnIndex) -
Returns null.
-
Parameters:
-
columnIndex - (1,2,...)
-
Returns:
-
null
-
int -getConcurrency() -
Returns ResultSet.CONCUR_READ_ONLY.
-
int -getConcurrency() -
Returns ResultSet.CONCUR_READ_ONLY.
-
Returns:
-
CONCUR_READ_ONLY
-
Date -getDate(int columnIndex) -
Returns the value as an java.sql.Date.
-
Date -getDate(int columnIndex) throws SQLException -
Returns the value as an java.sql.Date.
-
Parameters:
-
columnIndex - (1,2,...)
-
Returns:
-
the value
-
Date -getDate(String columnLabel) -
Returns the value as a java.sql.Date.
-
Date -getDate(String columnLabel) throws SQLException -
Returns the value as a java.sql.Date.
-
Parameters:
-
columnLabel - the column label
-
Returns:
-
the value
-
double -getDouble(int columnIndex) -
Returns the value as an double.
-
double -getDouble(int columnIndex) throws SQLException -
Returns the value as an double.
-
Parameters:
-
columnIndex - (1,2,...)
-
Returns:
-
the value
-
double -getDouble(String columnLabel) -
Returns the value as a double.
-
double -getDouble(String columnLabel) throws SQLException -
Returns the value as a double.
-
Parameters:
-
columnLabel - the column label
-
Returns:
-
the value
-
int -getFetchDirection() -
Returns ResultSet.FETCH_FORWARD.
-
int -getFetchDirection() -
Returns ResultSet.FETCH_FORWARD.
-
Returns:
-
FETCH_FORWARD
-
int -getFetchSize() -
Returns 0.
-
int -getFetchSize() -
Returns 0.
-
Returns:
-
0
-
float -getFloat(int columnIndex) -
Returns the value as a float.
-
float -getFloat(int columnIndex) throws SQLException -
Returns the value as a float.
-
Parameters:
-
columnIndex - (1,2,...)
-
Returns:
-
the value
-
float -getFloat(String columnLabel) -
Returns the value as a float.
-
float -getFloat(String columnLabel) throws SQLException -
Returns the value as a float.
-
Parameters:
-
columnLabel - the column label
-
Returns:
-
the value
-
int -getHoldability() -
Returns the current result set holdability.
-
int -getHoldability() -
Returns the current result set holdability.
-
Returns:
-
the holdability
-
int -getInt(int columnIndex) -
Returns the value as an int.
-
int -getInt(int columnIndex) throws SQLException -
Returns the value as an int.
-
Parameters:
-
columnIndex - (1,2,...)
-
Returns:
-
the value
-
int -getInt(String columnLabel) -
Returns the value as an int.
-
int -getInt(String columnLabel) throws SQLException -
Returns the value as an int.
-
Parameters:
-
columnLabel - the column label
-
Returns:
-
the value
-
long -getLong(int columnIndex) -
Returns the value as a long.
-
long -getLong(int columnIndex) throws SQLException -
Returns the value as a long.
-
Parameters:
-
columnIndex - (1,2,...)
-
Returns:
-
the value
-
long -getLong(String columnLabel) -
Returns the value as a long.
-
long -getLong(String columnLabel) throws SQLException -
Returns the value as a long.
-
Parameters:
-
columnLabel - the column label
-
Returns:
-
the value
-
ResultSetMetaData -getMetaData() -
Returns a reference to itself.
-
ResultSetMetaData -getMetaData() -
Returns a reference to itself.
-
Returns:
-
this
-
Object -getObject(int columnIndex) -
Returns the value as an Object.
-
Object -getObject(int columnIndex) throws SQLException -
Returns the value as an Object.
-
Parameters:
-
columnIndex - (1,2,...)
-
Returns:
-
the value
-
Object -getObject(String columnLabel) -
Returns the value as an Object.
-
Object -getObject(String columnLabel) throws SQLException -
Returns the value as an Object.
-
Parameters:
-
columnLabel - the column label
-
Returns:
-
the value
-
int -getPrecision(int columnIndex) -
Returns the precision.
-
int -getPrecision(int columnIndex) throws SQLException -
Returns the precision.
-
Parameters:
-
columnIndex - (1,2,...)
-
Returns:
-
the precision
-
int -getRow() -
Returns the row number (1, 2,...) or 0 for no row.
-
int -getRow() -
Returns the row number (1, 2,...) or 0 for no row.
-
Returns:
-
0
-
int -getScale(int columnIndex) -
Returns the scale.
-
int -getScale(int columnIndex) throws SQLException -
Returns the scale.
-
Parameters:
-
columnIndex - (1,2,...)
-
Returns:
-
the scale
-
String -getSchemaName(int columnIndex) -
Returns null.
-
String -getSchemaName(int columnIndex) -
Returns null.
-
Parameters:
-
columnIndex - (1,2,...)
-
Returns:
-
null
-
short -getShort(int columnIndex) -
Returns the value as a short.
-
short -getShort(int columnIndex) throws SQLException -
Returns the value as a short.
-
Parameters:
-
columnIndex - (1,2,...)
-
Returns:
-
the value
-
short -getShort(String columnLabel) -
Returns the value as a short.
-
short -getShort(String columnLabel) throws SQLException -
Returns the value as a short.
-
Parameters:
-
columnLabel - the column label
-
Returns:
-
the value
-
Statement -getStatement() -
Returns null.
-
Statement -getStatement() -
Returns null.
-
Returns:
-
null
-
String -getString(int columnIndex) -
Returns the value as a String.
-
String -getString(int columnIndex) throws SQLException -
Returns the value as a String.
-
Parameters:
-
columnIndex - (1,2,...)
-
Returns:
-
the value
-
String -getString(String columnLabel) -
Returns the value as a String.
-
String -getString(String columnLabel) throws SQLException -
Returns the value as a String.
-
Parameters:
-
columnLabel - the column label
-
Returns:
-
the value
-
String -getTableName(int columnIndex) -
Returns null.
-
String -getTableName(int columnIndex) -
Returns null.
-
Parameters:
-
columnIndex - (1,2,...)
-
Returns:
-
null
-
Time -getTime(int columnIndex) -
Returns the value as an java.sql.Time.
-
Time -getTime(int columnIndex) throws SQLException -
Returns the value as an java.sql.Time.
-
Parameters:
-
columnIndex - (1,2,...)
-
Returns:
-
the value
-
Time -getTime(String columnLabel) -
Returns the value as a java.sql.Time.
-
Time -getTime(String columnLabel) throws SQLException -
Returns the value as a java.sql.Time.
-
Parameters:
-
columnLabel - the column label
-
Returns:
-
the value
-
Timestamp -getTimestamp(int columnIndex) -
Returns the value as an java.sql.Timestamp.
-
Timestamp -getTimestamp(int columnIndex) throws SQLException -
Returns the value as an java.sql.Timestamp.
-
Parameters:
-
columnIndex - (1,2,...)
-
Returns:
-
the value
-
Timestamp -getTimestamp(String columnLabel) -
Returns the value as a java.sql.Timestamp.
-
Timestamp -getTimestamp(String columnLabel) throws SQLException -
Returns the value as a java.sql.Timestamp.
-
Parameters:
-
columnLabel - the column label
-
Returns:
-
the value
-
int -getType() -
Returns ResultSet.TYPE_FORWARD_ONLY.
-
int -getType() -
Returns ResultSet.TYPE_FORWARD_ONLY.
-
Returns:
-
TYPE_FORWARD_ONLY
-
SQLWarning -getWarnings() -
Returns null.
-
SQLWarning -getWarnings() -
Returns null.
-
Returns:
-
null
-
boolean -isAutoIncrement(int columnIndex) -
Returns false.
-
boolean -isAutoIncrement(int columnIndex) -
Returns false.
-
Parameters:
-
columnIndex - (1,2,...)
-
Returns:
-
false
-
boolean -isCaseSensitive(int columnIndex) -
Returns true.
-
boolean -isCaseSensitive(int columnIndex) -
Returns true.
-
Parameters:
-
columnIndex - (1,2,...)
-
Returns:
-
true
-
boolean -isClosed() -
Returns whether this result set has been closed.
-
boolean -isClosed() -
Returns whether this result set has been closed.
-
Returns:
-
true if the result set was closed
-
boolean -isCurrency(int columnIndex) -
Returns false.
-
boolean -isCurrency(int columnIndex) -
Returns false.
-
Parameters:
-
columnIndex - (1,2,...)
-
Returns:
-
false
-
boolean -isDefinitelyWritable(int columnIndex) -
Returns false.
-
boolean -isDefinitelyWritable(int columnIndex) -
Returns false.
-
Parameters:
-
columnIndex - (1,2,...)
-
Returns:
-
false
-
int -isNullable(int columnIndex) -
Returns ResultSetMetaData.columnNullableUnknown.
-
int -isNullable(int columnIndex) -
Returns ResultSetMetaData.columnNullableUnknown.
-
Parameters:
-
columnIndex - (1,2,...)
-
Returns:
-
columnNullableUnknown
-
boolean -isReadOnly(int columnIndex) -
Returns true.
-
boolean -isReadOnly(int columnIndex) -
Returns true.
-
Parameters:
-
columnIndex - (1,2,...)
-
Returns:
-
true
-
boolean -isSearchable(int columnIndex) -
Returns true.
-
boolean -isSearchable(int columnIndex) -
Returns true.
-
Parameters:
-
columnIndex - (1,2,...)
-
Returns:
-
true
-
boolean -isSigned(int columnIndex) -
Returns true.
-
boolean -isSigned(int columnIndex) -
Returns true.
-
Parameters:
-
columnIndex - (1,2,...)
-
Returns:
-
true
-
boolean -isWritable(int columnIndex) -
Returns false.
-
boolean -isWritable(int columnIndex) -
Returns false.
-
Parameters:
-
columnIndex - (1,2,...)
-
Returns:
-
false
-
boolean -() -
Moves the cursor to the next row of the result set.
-
boolean -() throws SQLException -
Moves the cursor to the next row of the result set.
-
Returns:
-
true if successful, false if there are no more rows
-
boolean -wasNull() -
Returns whether the last column accessed was null.
-
boolean -wasNull() -
Returns whether the last column accessed was null.
-
Returns:
-
true if the last column accessed was null
-
-
diff --git a/tools/h2/docs/javadoc/org/h2/tools/SimpleRowSource.html b/tools/h2/docs/javadoc/org/h2/tools/SimpleRowSource.html deleted file mode 100755 index a4848d2..0000000 --- a/tools/h2/docs/javadoc/org/h2/tools/SimpleRowSource.html +++ /dev/null @@ -1,47 +0,0 @@ - - - -SimpleRowSource - - - -
-

SimpleRowSource

-This interface is for classes that create rows on demand. - It is used together with SimpleResultSet to create a dynamic result set.

- - - - - - - - - - -
Methods
void -close() -
Close the row source.
-
void -close() -
Close the row source.
-
Object[] -readRow() -
Get the next row.
-
Object[] -readRow() throws SQLException -
Get the next row. Must return null if no more rows are available.
-
Returns:
-
the row or null
-
Throws:
-
SQLException
-
void -reset() -
Reset the position (before the first row).
-
void -reset() throws SQLException -
Reset the position (before the first row).
-
Throws:
-
SQLException - if this operation is not supported
-
-
diff --git a/tools/h2/docs/javadoc/org/h2/tools/TriggerAdapter.html b/tools/h2/docs/javadoc/org/h2/tools/TriggerAdapter.html deleted file mode 100755 index 109e055..0000000 --- a/tools/h2/docs/javadoc/org/h2/tools/TriggerAdapter.html +++ /dev/null @@ -1,113 +0,0 @@ - - - -TriggerAdapter - - - -
-

TriggerAdapter

-An adapter for the trigger interface that allows to use the ResultSet - interface instead of a row array.

- - - - - - - - - - - - - - - - -
Methods
void -close() -
This method is called when the trigger is dropped.
-
void -close() throws SQLException -
This method is called when the trigger is dropped. - The default implementation does nothing.
-
Throws:
-
SQLException
-
void -fire(Connection conn, Object[] oldRow, Object[] newRow) -
This method is called for each triggered action.
-
void -fire(Connection conn, Object[] oldRow, Object[] newRow) throws SQLException -
This method is called for each triggered action. The method is called - immediately when the operation occurred (before it is committed). A - transaction rollback will also rollback the operations that were done - within the trigger, if the operations occurred within the same database. - If the trigger changes state outside the database, a rollback trigger - should be used. -

- The row arrays contain all columns of the table, in the same order - as defined in the table. -

-

- The default implementation calls the fire method with the ResultSet - parameters. -

-
Parameters:
-
conn - a connection to the database
-
oldRow - the old row, or null if no old row is available (for - INSERT)
-
newRow - the new row, or null if no new row is available (for - DELETE)
-
Throws:
-
SQLException - if the operation must be undone
-
void -fire(Connection conn, ResultSet oldRow, ResultSet newRow) -
This method is called for each triggered action by the default - fire(Connection conn, Object[] oldRow, Object[] newRow) method.
-
void -fire(Connection conn, ResultSet oldRow, ResultSet newRow) throws SQLException -
This method is called for each triggered action by the default - fire(Connection conn, Object[] oldRow, Object[] newRow) method. - ResultSet.next does not need to be called (and calling it has no effect; - it will always return true).
-
Parameters:
-
conn - a connection to the database
-
oldRow - the old row, or null if no old row is available (for - INSERT)
-
newRow - the new row, or null if no new row is available (for - DELETE)
-
Throws:
-
SQLException - if the operation must be undone
-
void -init(Connection conn, String schemaName, String triggerName, String tableName, boolean before, int type) -
This method is called by the database engine once when initializing the - trigger.
-
void -init(Connection conn, String schemaName, String triggerName, String tableName, boolean before, int type) throws SQLException -
This method is called by the database engine once when initializing the - trigger. It is called when the trigger is created, as well as when the - database is opened. The default implementation initialized the result - sets.
-
Parameters:
-
conn - a connection to the database
-
schemaName - the name of the schema
-
triggerName - the name of the trigger used in the CREATE TRIGGER - statement
-
tableName - the name of the table
-
before - whether the fire method is called before or after the - operation is performed
-
type - the operation type: INSERT, UPDATE, or DELETE
-
void -remove() -
This method is called when the database is closed.
-
void -remove() throws SQLException -
This method is called when the database is closed. - If the method throws an exception, it will be logged, but - closing the database will continue. - The default implementation does nothing.
-
Throws:
-
SQLException
-
-
diff --git a/tools/h2/docs/javadoc/overview.html b/tools/h2/docs/javadoc/overview.html deleted file mode 100755 index 7844daa..0000000 --- a/tools/h2/docs/javadoc/overview.html +++ /dev/null @@ -1,38 +0,0 @@ - - - - - - API Overview - - - - - -
-
- -

API Overview

- -

JDBC API

- -

-Use the JDBC API to connect to a database and execute queries. -

- -

Tools API

- -

-The Tools API can be used to do maintenance operations, -such as deleting database files or changing the database file password, -that do not require a connection to the database. -

- -
- - diff --git a/tools/h2/docs/javadoc/stylesheet.css b/tools/h2/docs/javadoc/stylesheet.css deleted file mode 100755 index 93e1b7c..0000000 --- a/tools/h2/docs/javadoc/stylesheet.css +++ /dev/null @@ -1,172 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ - -td, input, select, textarea, body, code, pre, td, th { - font: 9pt/130% Tahoma, Arial, Helvetica, sans-serif; - font-weight: normal; -} - -pre { - background-color: #ece9d8; - border: 1px solid rgb(172, 168, 153); - padding: 4px; -} - -body { - margin: 0px; - max-width: 800px; -} - -h1 { - background-color: #0000bb; - padding: 2px 4px 2px 4px; - color: #fff; - font-size: 15pt; - line-height: normal; -} - -h2 { - font-size: 13pt; -} - -h3 { - font-size: 11pt; -} - -h4 { - font-size: 10pt; -} - -hr { - color: #CCC; - background-color: #CCC; - height: 1px; - border: 0px solid blue; -} - -.menu { - margin: 10px 10px 10px 10px; -} - -.block { - border: 0px; -} - -.titleOff { - display: none; -} - -.detail { - border: 0px; - display: none; -} - -.detailOn { - border: 0px; -} - -td.return { - white-space:nowrap; - width: 1%; -} - -td.method { - width: 99%; -} - -.deprecated { - text-decoration: line-through; -} - -.methodText { - color: #000000; - font-weight: normal; - margin: 0px 0px 0px 20px; -} - -.method { -} - -.fieldText { - margin: 6px 20px 6px 20px; -} - -.methodName { - font-weight: bold; -} - -.itemTitle { -} -/* font-weight: bold; */ - -.item { - margin: 0px 0px 0px 20px; -} - -table { - background-color: #ffffff; - border-collapse: collapse; - border: 1px solid #aca899; -} - -th { - text-align: left; - background-color: #ece9d8; - border: 1px solid #aca899; - padding: 2px; -} - -td { - background-color: #ffffff; - text-align: left; - vertical-align:top; - border: 1px solid #aca899; - padding: 2px; -} - - -ul, ol { - list-style-position: outside; - padding-left: 20px; -} - -li { - margin-top: 8px; - line-height: 100%; -} - -a { - text-decoration: none; - color: #0000ff; -} - -a:hover { - text-decoration: underline; -} - -table.content { - width: 100%; - height: 100%; - border: 0px; -} - -tr.content { - border:0px; - border-left:1px solid #aca899; -} - -td.content { - border:0px; - border-left:1px solid #aca899; -} - -.contentDiv { - margin:10px; -} - - - diff --git a/tools/h2/src/docsrc/help/help.csv b/tools/h2/src/docsrc/help/help.csv deleted file mode 100755 index d82ec30..0000000 --- a/tools/h2/src/docsrc/help/help.csv +++ /dev/null @@ -1,3499 +0,0 @@ -# Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, -# Version 1.0, and under the Eclipse Public License, Version 1.0 -# (http://h2database.com/html/license.html). -# Initial Developer: H2 Group -"SECTION","TOPIC","SYNTAX","TEXT","EXAMPLE" -"Commands (DML)","SELECT"," -SELECT [ TOP term ] [ DISTINCT | ALL ] selectExpression [,...] -FROM tableExpression [,...] [ WHERE expression ] -[ GROUP BY expression [,...] ] [ HAVING expression ] -[ { UNION [ ALL ] | MINUS | EXCEPT | INTERSECT } select ] [ ORDER BY order [,...] ] -[ LIMIT expression [ OFFSET expression ] [ SAMPLE_SIZE rowCountInt ] ] -[ FOR UPDATE ] -"," -Selects data from a table or multiple tables. -GROUP BY groups the the result by the given expression(s). -HAVING filter rows after grouping. -ORDER BY sorts the result by the given column(s) or expression(s). -UNION combines the result of this query with the results of another query. - -LIMIT limits the number of rows returned by the query, OFFSET specified -how many rows to skip. SAMPLE_SIZE limits the number of rows read for -aggregate queries. - -Multiple set operators (UNION/INTERSECT/MINUS/EXPECT) are evaluated -from left to right. For compatibility with other databases and future versions -of H2 please use parentheses. - -If FOR UPDATE is specified, the tables are locked for writing. When using -MVCC, only the selected rows are locked as in an UPDATE statement. -In this case, aggregate, GROUP BY, DISTINCT queries or joins -are not allowed in this case. -"," -SELECT * FROM TEST; -SELECT * FROM TEST ORDER BY NAME; -SELECT ID, COUNT(*) FROM TEST GROUP BY ID; -SELECT NAME, COUNT(*) FROM TEST GROUP BY NAME HAVING COUNT(*) > 2; -SELECT 'ID' COL, MAX(ID) AS MAX FROM TEST UNION SELECT 'NAME', MAX(NAME) FROM TEST; -SELECT * FROM TEST LIMIT 1000; -SELECT * FROM (SELECT ID, COUNT(*) FROM TEST - GROUP BY ID UNION SELECT NULL, COUNT(*) FROM TEST) - ORDER BY 1 NULLS LAST; -" - -"Commands (DML)","INSERT"," -INSERT INTO tableName [ ( columnName [,...] ) ] -{ VALUES { ( { DEFAULT | expression } [,...] ) } [,...] | select } -"," -Inserts a new row / new rows into a table. -"," -INSERT INTO TEST VALUES(1, 'Hello') -" - -"Commands (DML)","UPDATE"," -UPDATE tableName [ [ AS ] newTableAlias ] SET { columnName= { DEFAULT | expression } } [,...] -[ WHERE expression ] -"," -Updates data in a table. -"," -UPDATE TEST SET NAME='Hi' WHERE ID=1; -UPDATE PERSON P SET NAME=(SELECT A.NAME FROM ADDRESS A WHERE A.ID=P.ID); -" - -"Commands (DML)","DELETE"," -DELETE FROM tableName [ WHERE expression ] -"," -Deletes rows form a table. -"," -DELETE FROM TEST WHERE ID=2 -" - -"Commands (DML)","BACKUP"," -BACKUP TO fileNameString -"," -Backs up the database files to a .zip file. Objects are not locked. -Admin rights are required to execute this command. -"," -BACKUP TO 'backup.zip' -" - -"Commands (DML)","CALL"," -CALL expression -"," -Calculates a simple expression. -"," -CALL 15*25 -" - -"Commands (DML)","EXPLAIN"," -EXPLAIN { [ PLAN FOR ] | ANALYZE } { select | insert | update | delete } -"," -Shows the execution plan for a statement. -When using EXPLAIN ANALYZE, the statement is actually executed, and the query plan -will include the actual row scan count for each table. -"," -EXPLAIN SELECT * FROM TEST WHERE ID=1 -" - -"Commands (DML)","MERGE"," -MERGE INTO tableName [ ( columnName [,...] ) ] -[ KEY ( columnName [,...] ) ] -{ VALUES { ( { DEFAULT | expression } [,...] ) } [,...] | select } -"," -Updates existing rows, and insert rows that don't exist. If no key column is -specified, the primary key columns are used to find the row. If more than one -row per new row is affected, an exception is thrown. If the table contains an -auto-incremented key or identity column, and the row was updated, the generated -key is set to 0; otherwise it is set to the new key. -"," -MERGE INTO TEST KEY(ID) VALUES(2, 'World') -" - -"Commands (DML)","RUNSCRIPT"," -RUNSCRIPT FROM fileNameString [ COMPRESSION { DEFLATE | LZF | ZIP | GZIP } ] -[ CIPHER cipher PASSWORD string ] [ CHARSET charsetString ] -"," -Runs a SQL script from a file. The script is a text file containing SQL -statements; each statement must end with ';'. This command can be used to -restore a database from a backup. The password must be in single quotes; it is -case sensitive and can contain spaces. - -The compression algorithm must match the one used when creating the script. When -using encryption, only DEFLATE and LZF are supported (LZF is faster but uses more space). -Instead of a file, an URL may be used. - -Admin rights are required to execute this command. -"," -RUNSCRIPT FROM 'backup' -" - -"Commands (DML)","SCRIPT"," -SCRIPT [ SIMPLE ] [ NODATA ] [ NOPASSWORDS ] [ NOSETTINGS ] -[ DROP ] [ BLOCKSIZE blockSizeInt ] -[ TO fileNameString [ COMPRESSION { DEFLATE | LZF | ZIP | GZIP } ] - [ CIPHER cipher PASSWORD string ] ] -"," -Creates a SQL script from the database. - -SIMPLE does not use multi-row insert statements. -NODATA will not emit INSERT statements. -If the DROP option is specified, drop statements are created for tables, views, -and sequences. If the block size is set, CLOB and BLOB values larger than this -size are split into separate blocks. - -If no file name is specified, the -script is returned as a result set. This command can be used to create a backup -of the database. For long term storage, it is more portable than copying the -database files. - -If a file name is specified, then the whole -script (including insert statements) is written to this file, and a result set -without the insert statements is returned. When using encryption, only DEFLATE -and LZF are supported (LZF is faster but uses more space). - -This command locks objects while it is running. The password must be in -single quotes; it is case sensitive and can contain spaces. -"," -SCRIPT NODATA -" - -"Commands (DML)","SHOW"," -SHOW { SCHEMAS | TABLES [ FROM schemaName ] | - COLUMNS FROM tableName [ FROM schemaName ] } -"," -Lists the schemas, tables, or the columns of a table. -"," -SHOW TABLES -" - -"Commands (DDL)","ALTER INDEX RENAME"," -ALTER INDEX indexName RENAME TO newIndexName -"," -Renames an index. -This command commits an open transaction. -"," -ALTER INDEX IDXNAME RENAME TO IDX_TEST_NAME -" - -"Commands (DDL)","ALTER SEQUENCE"," -ALTER SEQUENCE sequenceName [ RESTART WITH long ] [ INCREMENT BY long ] -"," -Changes the next value and the increment of a sequence. -This command does not commit the current transaction; however the new value is used by other -transactions immediately, and rolling back this command has no effect. -"," -ALTER SEQUENCE SEQ_ID RESTART WITH 1000 -" - -"Commands (DDL)","ALTER TABLE ADD"," -ALTER TABLE tableName ADD name dataType [ DEFAULT expression ] -[ [ NOT ] NULL ] [ AUTO_INCREMENT | IDENTITY ] [ BEFORE columnName ] -"," -Adds a new column to a table. -This command commits an open transaction. -"," -ALTER TABLE TEST ADD CREATEDATE TIMESTAMP -" - -"Commands (DDL)","ALTER TABLE ADD CONSTRAINT"," -ALTER TABLE tableName ADD constraint [ CHECK | NOCHECK ] -"," -Adds a constraint to a table. If NOCHECK is specified, existing rows are not -checked for consistency (the default is to check consistency for existing rows). -The required indexes are automatically created if they don't exist yet. -It is not possible to disable checking for unique constraints. -This command commits an open transaction. -"," -ALTER TABLE TEST ADD CONSTRAINT NAME_UNIQUE UNIQUE(NAME) -" - -"Commands (DDL)","ALTER TABLE ALTER"," -ALTER TABLE tableName ALTER COLUMN columnName -{ { dataType [ DEFAULT expression ] [ [ NOT ] NULL ] [ AUTO_INCREMENT | IDENTITY ] } - | { RENAME TO name } - | { RESTART WITH long } - | { SELECTIVITY int } - | { SET DEFAULT expression } - | { SET NULL } - | { SET NOT NULL } } -"," -Changes the data type of a column, rename a column, -change the identity value, or change the selectivity. - -Changing the data type fails if the data can not be converted. - -RESTART changes the next value of an auto increment column. -The column must already be an auto increment column. -For RESTART, the same transactional rules as for ALTER SEQUENCE apply. - -SELECTIVITY sets the selectivity (1-100) for a column. -Setting the selectivity to 0 means the default value. -Selectivity is used by the cost based optimizer to calculate the estimated cost of an index. -Selectivity 100 means values are unique, 10 means every distinct value appears 10 times on average. - -SET DEFAULT changes the default value of a column. - -SET NULL sets a column to allow NULL. The row may not be part of a primary key. -Single column indexes on this column are dropped. - -SET NOT NULL sets a column to not allow NULL. Rows may not contains NULL in this column. - -This command commits an open transaction. -"," -ALTER TABLE TEST ALTER COLUMN NAME CLOB; -ALTER TABLE TEST ALTER COLUMN NAME RENAME TO TEXT; -ALTER TABLE TEST ALTER COLUMN ID RESTART WITH 10000; -ALTER TABLE TEST ALTER COLUMN NAME SELECTIVITY 100; -ALTER TABLE TEST ALTER COLUMN NAME SET DEFAULT ''; -ALTER TABLE TEST ALTER COLUMN NAME SET NOT NULL; -ALTER TABLE TEST ALTER COLUMN NAME SET NULL; -" - -"Commands (DDL)","ALTER TABLE DROP COLUMN"," -ALTER TABLE tableName DROP COLUMN columnName -"," -Removes a column from a table. -This command commits an open transaction. -"," -ALTER TABLE TEST DROP COLUMN NAME -" - -"Commands (DDL)","ALTER TABLE DROP CONSTRAINT"," -ALTER TABLE tableName DROP { CONSTRAINT [ IF EXISTS ] constraintName | PRIMARY KEY } -"," -Removes a constraint or a primary key from a table. -This command commits an open transaction. -"," -ALTER TABLE TEST DROP CONSTRAINT UNIQUE_NAME -" - -"Commands (DDL)","ALTER TABLE SET"," -ALTER TABLE tableName SET REFERENTIAL_INTEGRITY - { FALSE | TRUE [ CHECK | NOCHECK ] } -"," -Disables or enables referential integrity checking for a table. This command can -be used inside a transaction. Enabling referential integrity does not check -existing data, except if CHECK is specified. Use SET REFERENTIAL_INTEGRITY to -disable it for all tables; the global flag and the flag for each table are -independent. - -This command commits an open transaction. -"," -ALTER TABLE TEST SET REFERENTIAL_INTEGRITY FALSE -" - -"Commands (DDL)","ALTER TABLE RENAME"," -ALTER TABLE tableName RENAME TO newName -"," -Renames a table. -This command commits an open transaction. -"," -ALTER TABLE TEST RENAME TO MY_DATA -" - -"Commands (DDL)","ALTER USER ADMIN"," -ALTER USER userName ADMIN { TRUE | FALSE } -"," -Switches the admin flag of a user on or off. - -Only unquoted or uppercase user names are allowed. -Admin rights are required to execute this command. -This command commits an open transaction. -"," -ALTER USER TOM ADMIN TRUE -" - -"Commands (DDL)","ALTER USER RENAME"," -ALTER USER userName RENAME TO newUserName -"," -Renames a user. -After renaming a user, the password becomes invalid and needs to be changed as well. - -Only unquoted or uppercase user names are allowed. -Admin rights are required to execute this command. -This command commits an open transaction. -"," -ALTER USER TOM RENAME TO THOMAS -" - -"Commands (DDL)","ALTER USER SET PASSWORD"," -ALTER USER userName SET { PASSWORD string | SALT bytes HASH bytes } -"," -Changes the password of a user. -Only unquoted or uppercase user names are allowed. -The password must be enclosed in single quotes. It is case sensitive -and can contain spaces. The salt and hash values are hex strings. - -Admin rights are required to execute this command. -This command commits an open transaction. -"," -ALTER USER SA SET PASSWORD 'rioyxlgt' -" - -"Commands (DDL)","ALTER VIEW"," -ALTER VIEW viewName RECOMPILE -"," -Recompiles a view after the underlying tables have been changed or created. -This command is used for views created using CREATE FORCE VIEW. -This command commits an open transaction. -"," -ALTER VIEW ADDRESS_VIEW RECOMPILE -" - -"Commands (DDL)","ANALYZE"," -ANALYZE [ SAMPLE_SIZE rowCountInt ] -"," -Updates the selectivity statistics of all tables. The selectivity is used by the -cost based optimizer to select the best index for a given query. If no sample -size is set, up to 10000 rows per table are read. The value 0 means all rows are -read. The selectivity can be set manually using ALTER TABLE ALTER COLUMN -SELECTIVITY. Manual values are overwritten by this statement. The selectivity is -available in the INFORMATION_SCHEMA.COLUMNS table. - -This command commits an open transaction. -"," -ANALYZE SAMPLE_SIZE 1000 -" - -"Commands (DDL)","COMMENT"," -COMMENT ON -{ { COLUMN [ schemaName. ] tableName.columnName } - | { { TABLE | VIEW | CONSTANT | CONSTRAINT | ALIAS | INDEX | ROLE - | SCHEMA | SEQUENCE | TRIGGER | USER | DOMAIN } [ schemaName. ] objectName } } -IS expression -"," -Sets the comment of a database object. Use NULL to remove the comment. - -Admin rights are required to execute this command. -This command commits an open transaction. -"," -COMMENT ON TABLE TEST IS 'Table used for testing' -" - -"Commands (DDL)","CREATE AGGREGATE"," -CREATE AGGREGATE [ IF NOT EXISTS ] newAggregateName FOR className -"," -Creates a new user-defined aggregate function. The method name must be the full -qualified class name. The class must implement the interface -org.h2.api.AggregateFunction. - -Admin rights are required to execute this command. -This command commits an open transaction. -"," -CREATE AGGREGATE MEDIAN FOR ""com.acme.db.Median"" -" - -"Commands (DDL)","CREATE ALIAS"," -CREATE ALIAS [ IF NOT EXISTS ] newFunctionAliasName [ DETERMINISTIC ] -{ FOR classAndMethodName | AS sourceCodeString } -"," -Creates a new function alias. Deterministic functions must always return the -same value for the same parameters. The result of such functions is cached if possible. - -The method name must be the full qualified class and method name, -and may optionally include the parameter classes as in -""java.lang.Integer.parseInt(java.lang.String, int)""). The class and the method -must both be public, and the method must be static. The class must be available -in the classpath of the database engine (when using the server mode, -it must be in the classpath of the server). - -When defining a function alias with source code, the Sun javac is compiler -is used if the tools.jar is in the classpath. If not, javac is run as a separate process. -Only the source code is stored in the database; the class is compiled each time -the database is re-opened. Source code is usually passed -as dollar quoted text to avoid escaping problems. If import statements are used, -then the tag @CODE must be added before the method. - -If the method throws a SQLException, it is directly re-thrown to the calling application; -all other exceptions are first converted to a SQLException. - -If the first parameter of the Java function is a java.sql.Connection, then a -connection to the database is provided. This connection must not be closed. -If the class contains multiple methods with the given name but different -parameter count, all methods are mapped. - -Admin rights are required to execute this command. -This command commits an open transaction. -"," -CREATE ALIAS MY_SQRT FOR ""java.lang.Math.sqrt""; -CREATE ALIAS GET_SYSTEM_PROPERTY FOR ""java.lang.System.getProperty""; -CALL GET_SYSTEM_PROPERTY('java.class.path'); -CALL GET_SYSTEM_PROPERTY('com.acme.test', 'true'); -CREATE ALIAS REVERSE AS $$ String reverse(String s) { return new StringBuilder(s).reverse().toString(); } $$; -CALL REVERSE('Test'); -" - -"Commands (DDL)","CREATE CONSTANT"," -CREATE CONSTANT [ IF NOT EXISTS ] newConstantName VALUE expression -"," -Creates a new constant. -This command commits an open transaction. -"," -CREATE CONSTANT ONE VALUE 1 -" - -"Commands (DDL)","CREATE DOMAIN"," -CREATE DOMAIN [ IF NOT EXISTS ] newDomainName AS dataType -[ DEFAULT expression ] [ [ NOT ] NULL ] [ SELECTIVITY selectivity ] -[ CHECK condition ] -"," -Creates a new data type (domain). The check condition must evaluate to true or -to NULL (to prevent NULL, use NOT NULL). In the condition, the term VALUE refers -to the value being tested. - -This command commits an open transaction. -"," -CREATE DOMAIN EMAIL AS VARCHAR(255) CHECK (POSITION('@', VALUE) > 1) -" - -"Commands (DDL)","CREATE INDEX"," -CREATE { [ UNIQUE ] [ HASH ] INDEX [ IF NOT EXISTS ] newIndexName - | PRIMARY KEY [ HASH ] } -ON tableName ( indexColumn [,...] ) -"," -Creates a new index. -This command commits an open transaction. - -Hash indexes are meant for in-memory databases and memory tables (CREATE MEMORY TABLE). -For other tables, or if the index contains multiple columns, the HASH keyword is ignored. -Hash indexes can only test for equality, and do not support range queries (similar to a hash table). -Non-unique keys are supported. -"," -CREATE INDEX IDXNAME ON TEST(NAME) -" - -"Commands (DDL)","CREATE LINKED TABLE"," -CREATE [ [ GLOBAL | LOCAL ] TEMPORARY ] LINKED TABLE [ IF NOT EXISTS ] -name ( driverString, urlString, userString, passwordString, -[ originalSchemaString, ] originalTableString ) [ EMIT UPDATES | READONLY ] -"," -Creates a table link to an external table. The driver name may be empty if the -driver is already loaded. If the schema name is not set, only one table with -that name may exist in the target database. - -Usually, for update statements, the old rows are deleted first and then the new -rows are inserted. It is possible to emit update statements (except on -rollback), however in this case multi-row unique key updates may not always -work. Linked tables to the same database share one connection. - -If a query is used instead of the original table name, the table is read only. -Queries must be enclosed in parenthesis: (SELECT * FROM ORDERS). - -To use JNDI to get the connection, the driver class must be a -javax.naming.Context (for example javax.naming.InitialContext), and the URL must -be the resource name (for example java:comp/env/jdbc/Test). - -Admin rights are required to execute this command. -This command commits an open transaction. -"," -CREATE LINKED TABLE LINK('org.h2.Driver', 'jdbc:h2:test2', 'sa', 'sa', 'TEST'); -CREATE LINKED TABLE LINK('', 'jdbc:h2:test2', 'sa', 'sa', - '(SELECT * FROM TEST WHERE ID>0)'); -CREATE LINKED TABLE LINK('javax.naming.InitialContext', - 'java:comp/env/jdbc/Test', NULL, NULL, '(SELECT * FROM TEST WHERE ID>0)'); -" - -"Commands (DDL)","CREATE ROLE"," -CREATE ROLE [ IF NOT EXISTS ] newRoleName -"," -Creates a new role. -This command commits an open transaction. -"," -CREATE ROLE READONLY -" - -"Commands (DDL)","CREATE SCHEMA"," -CREATE SCHEMA [ IF NOT EXISTS ] name [ AUTHORIZATION ownerUserName ] -"," -Creates a new schema. If no owner is specified, the current user is used. The -user that executes the command must have admin rights, as well as the owner. -Specifying the owner currently has no effect. - -This command commits an open transaction. -"," -CREATE SCHEMA TEST_SCHEMA AUTHORIZATION SA -" - -"Commands (DDL)","CREATE SEQUENCE"," -CREATE SEQUENCE [ IF NOT EXISTS ] newSequenceName [ START WITH long ] -[ INCREMENT BY long ] [ CACHE long ] -"," -Creates a new sequence. The data type of a sequence is BIGINT. Used values are -never re-used, even when the transaction is rolled back. The cache is the number -of pre-allocated numbers. If the system crashes without closing the database, at -most this many numbers are lost. The default cache size is 32. - -This command commits an open transaction. -"," -CREATE SEQUENCE SEQ_ID -" - -"Commands (DDL)","CREATE TABLE"," -CREATE [ CACHED | MEMORY ] [ TEMP | [ GLOBAL | LOCAL ] TEMPORARY ] -TABLE [ IF NOT EXISTS ] name -{ { ( { columnDefinition | constraint } [,...] ) [ AS select ] } - | { AS select } } -[ ENGINE tableEngineName ] [ NOT PERSISTENT ] -"," -Creates a new table. - -Cached tables (the default for regular tables) are persistent, -and the number of rows is not limited by the main memory. -Memory tables (the default for temporary tables) are persistent, -but the index data is kept in main memory, -that means memory tables should not get too large. - -Temporary tables are deleted when closing or opening a database. -Temporary tables can be global (accessible by all connections) -or local (only accessible by the current connection). -The default for temporary tables is global. -Indexes of temporary tables are kept fully in main memory, -unless the temporary table is created using CREATE CACHED ... TABLE. - -The ENGINE option is only required when custom table implementations are used. -The table engine class must implement the interface org.h2.api.TableEngine. - -Tables with the NOT PERSISTENT modifier are kept fully in memory, and all -rows are lost when the database is closed. - -This command commits an open transaction. -"," -CREATE TABLE TEST(ID INT PRIMARY KEY, NAME VARCHAR(255)) -" - -"Commands (DDL)","CREATE TRIGGER"," -CREATE TRIGGER [ IF NOT EXISTS ] newTriggerName { BEFORE | AFTER | INSTEAD OF } -{ INSERT | UPDATE | DELETE | SELECT | ROLLBACK } [,...] ON tableName [ FOR EACH ROW ] -[ QUEUE int ] [ NOWAIT ] CALL triggeredClassName -"," -Creates a new trigger. The trigger class must be public. Inner classes are not supported. -The class must be available in the classpath of the -database engine (when using the server mode, it must be in the classpath of the server). - -'BEFORE' triggers are called after data conversion is made, default values are set, -null and length constraint checks have been made; -but before other constraints have been checked. -If there are multiple triggers, the order in which they are called is undefined. - -Only row based 'AFTER' trigger can be called on rollback. -Exceptions that occur within such triggers are ignored. - -'INSTEAD OF' triggers are implicitly row based and behave like 'BEFORE' triggers. -Only the first such trigger is called. Such triggers on views are supported. - -The MERGE statement will call both INSERT and UPDATE triggers. -Not supported are SELECT triggers with the option FOR EACH ROW, -and AFTER SELECT triggers. - -Committing or rolling back a transaction within a trigger is not allowed, -except for SELECT triggers. - -This command commits an open transaction. -"," -CREATE TRIGGER TRIG_INS BEFORE INSERT ON TEST FOR EACH ROW CALL ""MyTrigger"" -" -"Commands (DDL)","CREATE USER"," -CREATE USER [ IF NOT EXISTS ] newUserName -{ PASSWORD string | SALT bytes HASH bytes } [ ADMIN ] -"," -Creates a new user. For compatibility, only unquoted or uppercase user names are allowed. -The password must be in single quotes. It is case sensitive and can contain spaces. -The salt and hash values are hex strings. - -Admin rights are required to execute this command. -This command commits an open transaction. -"," -CREATE USER GUEST PASSWORD 'abc' -" - -"Commands (DDL)","CREATE VIEW"," -CREATE [ FORCE ] VIEW [ IF NOT EXISTS ] newViewName -[ ( columnName [,...] ) ] AS select -"," -Creates a new view. If the force option is used, then the view is created even -if the underlying table(s) don't exist. - -Admin rights are required to execute this command. -This command commits an open transaction. -"," -CREATE VIEW TEST_VIEW AS SELECT * FROM TEST WHERE ID < 100 -" - -"Commands (DDL)","DROP AGGREGATE"," -DROP AGGREGATE [ IF EXISTS ] aggregateName -"," -Drops an existing user-defined aggregate function. - -Admin rights are required to execute this command. -This command commits an open transaction. -"," -CREATE AGGREGATE MEDIAN -" - -"Commands (DDL)","DROP ALIAS"," -DROP ALIAS [ IF EXISTS ] existingFunctionAliasName -"," -Drops an existing function alias. - -Admin rights are required to execute this command. -This command commits an open transaction. -"," -CREATE ALIAS MY_SQRT -" - -"Commands (DDL)","DROP ALL OBJECTS"," -DROP ALL OBJECTS [ DELETE FILES ] -"," -Drops all existing views, tables, sequences, schemas, function aliases, roles, -user-defined aggregate functions, domains, and users (except the current user). -If DELETE FILES is specified, the database files will be removed when the last -user disconnects from the database. Warning: this command can not be rolled -back. - -Admin rights are required to execute this command. -"," -DROP ALL OBJECTS -" - -"Commands (DDL)","DROP CONSTANT"," -DROP CONSTANT [ IF EXISTS ] constantName -"," -Drops a constant. -This command commits an open transaction. -"," -DROP CONSTANT ONE -" - -"Commands (DDL)","DROP DOMAIN"," -DROP DOMAIN [ IF EXISTS ] domainName -"," -Drops a data type (domain). -This command commits an open transaction. -"," -DROP DOMAIN EMAIL -" - -"Commands (DDL)","DROP INDEX"," -DROP INDEX [ IF EXISTS ] indexName -"," -Drops an index. -This command commits an open transaction. -"," -DROP INDEX IF EXISTS IDXNAME -" - -"Commands (DDL)","DROP ROLE"," -DROP ROLE [ IF EXISTS ] roleName -"," -Drops a role. -This command commits an open transaction. -"," -DROP ROLE READONLY -" - -"Commands (DDL)","DROP SCHEMA"," -DROP SCHEMA [ IF EXISTS ] schemaName -"," -Drops a schema. -This command commits an open transaction. -"," -DROP SCHEMA TEST_SCHEMA -" - -"Commands (DDL)","DROP SEQUENCE"," -DROP SEQUENCE [ IF EXISTS ] sequenceName -"," -Drops a sequence. -This command commits an open transaction. -"," -DROP SEQUENCE SEQ_ID -" - -"Commands (DDL)","DROP TABLE"," -DROP TABLE [ IF EXISTS ] tableName [,...] -"," -Drops an existing table, or a list of existing tables. -This command commits an open transaction. -This will also drop all views that depend on this table. -"," -DROP TABLE TEST -" - -"Commands (DDL)","DROP TRIGGER"," -DROP TRIGGER [ IF EXISTS ] triggerName -"," -Drops an existing trigger. -This command commits an open transaction. -"," -DROP TRIGGER TRIG_INS -" - -"Commands (DDL)","DROP USER"," -DROP USER [ IF EXISTS ] userName -"," -Drops a user. The current user cannot be dropped. -For compatibility, only unquoted or uppercase user names are allowed. - -Admin rights are required to execute this command. -This command commits an open transaction. -"," -DROP USER TOM -" - -"Commands (DDL)","DROP VIEW"," -DROP VIEW [ IF EXISTS ] viewName -"," -Drops a view. -This command commits an open transaction. -This will also drop all views that depend on this view. -"," -DROP VIEW TEST_VIEW -" - -"Commands (DDL)","TRUNCATE TABLE"," -TRUNCATE TABLE tableName -"," -Removes all rows from a table. Unlike DELETE FROM without where clause, this -command can not be rolled back. This command is faster than DELETE without where -clause. Only regular data tables without foreign key constraints can be -truncated. Linked tables can't be truncated. - -This command commits an open transaction. -"," -TRUNCATE TABLE TEST -" - -"Commands (Other)","CHECKPOINT"," -CHECKPOINT -"," -Flushes the data to disk and switches to a new transaction log if possible. - -Admin rights are required to execute this command. -"," -CHECKPOINT -" - -"Commands (Other)","CHECKPOINT SYNC"," -CHECKPOINT SYNC -"," -Flushes the data to disk and and forces all system buffers be written -to the underlying device. - -Admin rights are required to execute this command. -"," -CHECKPOINT SYNC -" - -"Commands (Other)","COMMIT"," -COMMIT [ WORK ] -"," -Commits a transaction. -"," -COMMIT -" - -"Commands (Other)","COMMIT TRANSACTION"," -COMMIT TRANSACTION transactionName -"," -Sets the resolution of an in-doubt transaction to 'commit'. - -Admin rights are required to execute this command. -This command is part of the 2-phase-commit protocol. -"," -COMMIT TRANSACTION XID_TEST -" - -"Commands (Other)","GRANT RIGHT"," -GRANT { SELECT | INSERT | UPDATE | DELETE | ALL } [,...] ON -tableName [,...] TO { PUBLIC | userName | roleName } -"," -Grants rights for a table to a user or role. - -Admin rights are required to execute this command. -This command commits an open transaction. -"," -GRANT SELECT ON TEST TO READONLY -" - -"Commands (Other)","GRANT ROLE"," -GRANT roleName TO { PUBLIC | userName | roleName } -"," -Grants a role to a user or role. - -Admin rights are required to execute this command. -This command commits an open transaction. -"," -GRANT READONLY TO PUBLIC -" - -"Commands (Other)","HELP"," -HELP [ anything [...] ] -"," -Displays the help pages of SQL commands or keywords. -"," -HELP SELECT -" - -"Commands (Other)","PREPARE COMMIT"," -PREPARE COMMIT newTransactionName -"," -Prepares committing a transaction. -This command is part of the 2-phase-commit protocol. -"," -PREPARE COMMIT XID_TEST -" - -"Commands (Other)","REVOKE RIGHT"," -REVOKE { SELECT | INSERT | UPDATE | DELETE | ALL } [,...] ON -tableName [,...] FROM { PUBLIC | userName | roleName } -"," -Removes rights for a table from a user or role. - -Admin rights are required to execute this command. -This command commits an open transaction. -"," -REVOKE SELECT ON TEST FROM READONLY -" - -"Commands (Other)","REVOKE ROLE"," -REVOKE roleName FROM { PUBLIC | userName | roleName } -"," -Removes a role from a user or role. - -Admin rights are required to execute this command. -This command commits an open transaction. -"," -REVOKE READONLY FROM TOM -" - -"Commands (Other)","ROLLBACK"," -ROLLBACK [ TO SAVEPOINT savepointName ] -"," -Rolls back a transaction. If a savepoint name is used, the transaction is only -rolled back to the specified savepoint. -"," -ROLLBACK -" - -"Commands (Other)","ROLLBACK TRANSACTION"," -ROLLBACK TRANSACTION transactionName -"," -Sets the resolution of an in-doubt transaction to 'rollback'. - -Admin rights are required to execute this command. -This command is part of the 2-phase-commit protocol. -"," -ROLLBACK TRANSACTION XID_TEST -" - -"Commands (Other)","SAVEPOINT"," -SAVEPOINT savepointName -"," -Create a new savepoint. See also ROLLBACK. -Savepoints are only valid until the transaction is committed or rolled back. -"," -SAVEPOINT HALF_DONE -" - -"Commands (Other)","SET @"," -SET @variableName [ = ] expression -"," -Updates a user-defined variable. -This command does not commit a transaction, and rollback does not affect it. -"," -SET @TOTAL=0 -" - -"Commands (Other)","SET ALLOW_LITERALS"," -SET ALLOW_LITERALS { NONE | ALL | NUMBERS } -"," -This setting can help solve the SQL injection problem. By default, text and -number literals are allowed in SQL statements. However, this enables SQL -injection if the application dynamically builds SQL statements. SQL injection is -not possible if user data is set using parameters ('?'). - -NONE means literals of any kind are not allowed, only parameters and constants -are allowed. NUMBERS mean only numerical and boolean literals are allowed. ALL -means all literals are allowed (default). - -See also CREATE CONSTANT. - -Admin rights are required to execute this command. -This command commits an open transaction. -This setting is persistent. -This setting can be appended to the database URL: jdbc:h2:test;ALLOW_LITERALS=NONE -"," -SET ALLOW_LITERALS NONE -" - -"Commands (Other)","SET AUTOCOMMIT"," -SET AUTOCOMMIT { TRUE | ON | FALSE | OFF } -"," -Switches auto commit on or off. -This setting can be appended to the database URL: jdbc:h2:test;AUTOCOMMIT=OFF - -however this will not work as expected when using a connection pool -(the connection pool manager will re-enable autocommit when returning -the connection to the pool, so autocommit will only be disabled the first -time the connection is used. -"," -SET AUTOCOMMIT OFF -" - -"Commands (Other)","SET CACHE_SIZE"," -SET CACHE_SIZE int -"," -Sets the size of the cache in KB (each KB being 1024 bytes) for the current database. -The default value is 16384 (16 MB). The value is rounded to the next higher power of two. -Depending on the virtual machine, the actual memory required may be higher. - -This setting is persistent and affects all connections as there is only one cache per database. -This setting only affects the database engine (the server in a client/server environment). -It has no effect for in-memory databases. - -Admin rights are required to execute this command. -This command commits an open transaction. -This setting is persistent. -This setting can be appended to the database URL: jdbc:h2:test;CACHE_SIZE=8192 -"," -SET CACHE_SIZE 8192 -" - -"Commands (Other)","SET CLUSTER"," -SET CLUSTER serverListString -"," -This command should not be used directly by an application, the statement is -executed automatically by the system. The behavior may change in future -releases. Sets the cluster server list. An empty string switches off the cluster -mode. Switching on the cluster mode requires admin rights, but any user can -switch it off (this is automatically done when the client detects the other -server is not responding). - -This command is effective immediately, but does not commit an open transaction. -"," -SET CLUSTER '' -" - -"Commands (Other)","SET COLLATION"," -SET [ DATABASE ] COLLATION -{ OFF | collationName [ STRENGTH { PRIMARY | SECONDARY | TERTIARY | IDENTICAL } ] } -"," -Sets the collation used for comparing strings. This command can only be executed -if there are no tables defined. See java.text.Collator for details about -STRENGTH. - -Admin rights are required to execute this command. -This command commits an open transaction. -This setting is persistent. -"," -SET COLLATION ENGLISH -" - -"Commands (Other)","SET COMPRESS_LOB"," -SET COMPRESS_LOB { NO | LZF | DEFLATE } -"," -Sets the compression algorithm for BLOB and CLOB data. Compression is usually -slower, but needs less disk space. LZF is faster but uses more space. - -Admin rights are required to execute this command. -This command commits an open transaction. -This setting is persistent. -"," -SET COMPRESS_LOB LZF -" - -"Commands (Other)","SET DATABASE_EVENT_LISTENER"," -SET DATABASE_EVENT_LISTENER classNameString -"," -Sets the event listener class. An empty string ('') means no listener should be -used. This setting is not persistent. - -Admin rights are required to execute this command, except if it is set when -opening the database (in this case it is reset just after opening the database). -This setting can be appended to the database URL: jdbc:h2:test;DATABASE_EVENT_LISTENER='sample.MyListener' -"," -SET DATABASE_EVENT_LISTENER 'sample.MyListener' -" - -"Commands (Other)","SET DB_CLOSE_DELAY"," -SET DB_CLOSE_DELAY int -"," -Sets the delay for closing a database if all connections are closed. The value --1 means the database is never closed until the close delay is set to some other -value or SHUTDOWN is called. The value 0 means no delay (default; the database -is closed if the last connection to it is closed). Values 1 and larger mean the -number of seconds the database is left open after closing the last connection. - -If the application exits normally or System.exit is called, the database is -closed immediately, even if a delay is set. - -Admin rights are required to execute this command. -This command commits an open transaction. -This setting is persistent. -This setting can be appended to the database URL: jdbc:h2:test;DB_CLOSE_DELAY=-1 -"," -SET DB_CLOSE_DELAY -1 -" - -"Commands (Other)","SET DEFAULT_LOCK_TIMEOUT"," -SET DEFAULT LOCK_TIMEOUT int -"," -Sets the default lock timeout (in milliseconds) in this database that is used -for the new sessions. The default value for this setting is 1000 (one second). - -Admin rights are required to execute this command. -This command commits an open transaction. -This setting is persistent. -"," -SET DEFAULT_LOCK_TIMEOUT 5000 -" - -"Commands (Other)","SET DEFAULT_TABLE_TYPE"," -SET DEFAULT_TABLE_TYPE { MEMORY | CACHED } -"," -Sets the default table storage type that is used when creating new tables. -Memory tables are kept fully in the main memory (including indexes), however -the data is still stored in the database file. The size of memory tables is -limited by the memory. The default is CACHED. - -Admin rights are required to execute this command. -This command commits an open transaction. -This setting is persistent. -"," -SET DEFAULT_TABLE_TYPE MEMORY -" - -"Commands (Other)","SET EXCLUSIVE"," -SET EXCLUSIVE { 0 | 1 | 2 } -"," -Switched the database to exclusive mode (1, 2) and back to normal mode (0). - -In exclusive mode, new connections are rejected, and operations by -other connections are paused until the exclusive mode is disabled. -When using the value 1, existing connections stay open. -When using the value 2, all existing connections are closed -(and current transactions are rolled back) except the connection -that executes SET EXCLUSIVE. -Only the connection that set the exclusive mode can disable it. -When the connection is closed, it is automatically disabled. - -Admin rights are required to execute this command. -This command commits an open transaction. -"," -SET EXCLUSIVE 1 -" - -"Commands (Other)","SET IGNORECASE"," -SET IGNORECASE { TRUE | FALSE } -"," -If IGNORECASE is enabled, text columns in newly created tables will be -case-insensitive. Already existing tables are not affected. The effect of -case-insensitive columns is similar to using a collation with strength PRIMARY. -Case-insensitive columns are compared faster than when using a collation. - -Admin rights are required to execute this command. -This command commits an open transaction. -This setting is persistent. -"," -SET IGNORECASE TRUE -" - -"Commands (Other)","SET LOCK_MODE"," -SET LOCK_MODE int -"," -Sets the lock mode. The values 0, 1, 2, and 3 are supported. The default is 3 -(READ_COMMITTED). This setting affects all connections. - -The value 0 means no locking (should only be used for testing; also known as -READ_UNCOMMITTED). Please note that using SET LOCK_MODE 0 while at the same time -using multiple connections may result in inconsistent transactions. - -The value 1 means table level locking (also known as SERIALIZABLE). - -The value 2 means table level locking with garbage collection (if the -application does not close all connections). - -The value 3 means table level locking, but read locks are released immediately -(default; also known as READ_COMMITTED). - -Admin rights are required to execute this command. -This command commits an open transaction. -This setting is persistent. -This setting can be appended to the database URL: jdbc:h2:test;LOCK_MODE=3 -"," -SET LOCK_MODE 1 -" - -"Commands (Other)","SET LOCK_TIMEOUT"," -SET LOCK_TIMEOUT int -"," -Sets the lock timeout (in milliseconds) for the current session. The default -value for this setting is 1000 (one second). - -This command does not commit a transaction, and rollback does not affect it. -This setting can be appended to the database URL: jdbc:h2:test;LOCK_TIMEOUT=10000 -"," -SET LOCK_TIMEOUT 1000 -" - -"Commands (Other)","SET MAX_LENGTH_INPLACE_LOB"," -SET MAX_LENGTH_INPLACE_LOB int -"," -Sets the maximum size of an in-place LOB object. LOB objects larger that this -size are stored in a separate file, otherwise stored directly in the database -(in-place). The default max size is 1024. - -Admin rights are required to execute this command. -This command commits an open transaction. -This setting is persistent. -"," -SET MAX_LENGTH_INPLACE_LOB 128 -" - -"Commands (Other)","SET MAX_LOG_SIZE"," -SET MAX_LOG_SIZE int -"," -Sets the maximum size of the transaction log, in megabytes. If the log exceeds the -limit, a new stream is created. Old streams (that are not used for recovery) are -freed automatically. The default max size is 2 MB. - -Admin rights are required to execute this command. -This command commits an open transaction. -This setting is persistent. -"," -SET MAX_LOG_SIZE 2 -" - -"Commands (Other)","SET MAX_MEMORY_ROWS"," -SET MAX_MEMORY_ROWS int -"," -The maximum number of rows in a result set that are kept in-memory. If more rows -are read, then the rows are buffered to disk. The default value is 10000. - -Admin rights are required to execute this command. -This command commits an open transaction. -This setting is persistent. -"," -SET MAX_MEMORY_ROWS 1000 -" - -"Commands (Other)","SET MAX_MEMORY_UNDO"," -SET MAX_MEMORY_UNDO int -"," -The maximum number of undo records per a session that are kept in-memory. -If a transaction is larger, the records are buffered to disk. -The default value is 50000. -Changes to tables without a primary key can not be buffered to disk. -This setting is not supported when using multi-version concurrency. - -Admin rights are required to execute this command. -This command commits an open transaction. -This setting is persistent. -"," -SET MAX_MEMORY_UNDO 1000 -" - -"Commands (Other)","SET MAX_OPERATION_MEMORY"," -SET MAX_OPERATION_MEMORY int -"," -Sets the maximum memory used for large operations (delete and insert), in bytes. -Operations that use more memory are buffered to disk, slowing down the -operation. The default max size is 100000. 0 means no limit. - -This setting is not persistent. -Admin rights are required to execute this command. -This setting can be appended to the database URL: jdbc:h2:test;MAX_OPERATION_MEMORY=10000 -"," -SET MAX_OPERATION_MEMORY 0 -" - -"Commands (Other)","SET MODE"," -SET MODE { REGULAR | DB2 | DERBY | HSQLDB | MSSQLSERVER | MYSQL | ORACLE | POSTGRESQL } -"," -Changes to another database compatibility mode. For details, see Compatibility -Modes in the feature section. - -This setting is not persistent. -Admin rights are required to execute this command. -This command commits an open transaction. -This setting can be appended to the database URL: jdbc:h2:test;MODE=MYSQL -"," -SET MODE HSQLDB -" - -"Commands (Other)","SET MULTI_THREADED"," -SET MULTI_THREADED { 0 | 1 } -"," -Enabled (1) or disabled (0) multi-threading inside the database engine. By -default, this setting is disabled. Currently, enabling this is experimental -only. - -This is a global setting, which means it is not possible to open multiple databases with different modes at the same time in the same virtual machine. -This setting is not persistent, however the value is kept until the virtual machine exits or it is changed. - -Admin rights are required to execute this command. -This command commits an open transaction. -This setting can be appended to the database URL: jdbc:h2:test;MULTI_THREADED=1 -"," -SET MULTI_THREADED 1 -" - -"Commands (Other)","SET OPTIMIZE_REUSE_RESULTS"," -SET OPTIMIZE_REUSE_RESULTS { 0 | 1 } -"," -Enabled (1) or disabled (0) the result reuse optimization. If enabled, -subqueries and views used as subqueries are only re-run if the data in one of -the tables was changed. This option is enabled by default. - -Admin rights are required to execute this command. -This command commits an open transaction. -This setting can be appended to the database URL: jdbc:h2:test;OPTIMIZE_REUSE_RESULTS=0 -"," -SET OPTIMIZE_REUSE_RESULTS 0 -" - -"Commands (Other)","SET PASSWORD"," -SET PASSWORD string -"," -Changes the password of the current user. The password must be in single quotes. -It is case sensitive and can contain spaces. - -This command commits an open transaction. -"," -SET PASSWORD 'abcstzri!.5' -" - -"Commands (Other)","SET QUERY_TIMEOUT"," -SET QUERY_TIMEOUT int -"," -Set the query timeout of the current session to the given value. The timeout is -in milliseconds. All kinds of statements will throw an exception if they take -longer than the given value. The default timeout is 0, meaning no timeout. - -This command does not commit a transaction, and rollback does not affect it. -"," -SET QUERY_TIMEOUT 10000 -" - -"Commands (Other)","SET REFERENTIAL_INTEGRITY"," -SET REFERENTIAL_INTEGRITY { TRUE | FALSE } -"," -Disabled or enables referential integrity checking for the whole database. -Enabling it does not check existing data. Use ALTER TABLE SET to disable it only -for one table. - -This setting is not persistent. -This command commits an open transaction. -Admin rights are required to execute this command. -"," -SET REFERENTIAL_INTEGRITY FALSE -" - -"Commands (Other)","SET SALT HASH"," -SET SALT bytes HASH bytes -"," -Sets the password salt and hash for the current user. The password must be in -single quotes. It is case sensitive and can contain spaces. - -This command commits an open transaction. -"," -SET SALT '00' HASH '1122' -" - -"Commands (Other)","SET SCHEMA"," -SET SCHEMA schemaName -"," -Changes the default schema of the current connection. The default schema is used -in statements where no schema is set explicitly. The default schema for new -connections is PUBLIC. - -This command does not commit a transaction, and rollback does not affect it. -This setting can be appended to the database URL: jdbc:h2:test;SCHEMA=ABC -"," -SET SCHEMA INFORMATION_SCHEMA -" - -"Commands (Other)","SET SCHEMA_SEARCH_PATH"," -SET SCHEMA_SEARCH_PATH schemaName [,...] -"," -Changes the schema search path of the current connection. The default schema is -used in statements where no schema is set explicitly. The default schema for new -connections is PUBLIC. - -This command does not commit a transaction, and rollback does not affect it. -This setting can be appended to the database URL: jdbc:h2:test;SCHEMA_SEARCH_PATH=ABC,DEF -"," -SET SCHEMA_SEARCH_PATH INFORMATION_SCHEMA, PUBLIC -" - -"Commands (Other)","SET THROTTLE"," -SET THROTTLE int -"," -Sets the throttle for the current connection. The value is the number of -milliseconds delay after each 50 ms. The default value is 0 (throttling -disabled). - -This command does not commit a transaction, and rollback does not affect it. -This setting can be appended to the database URL: jdbc:h2:test;THROTTLE=50 -"," -SET THROTTLE 200 -" - -"Commands (Other)","SET TRACE_LEVEL"," -SET { TRACE_LEVEL_FILE | TRACE_LEVEL_SYSTEM_OUT } int -"," -Sets the trace level for file the file or system out stream. Levels are: 0=off, -1=error, 2=info, 3=debug. The default level is 1 for file and 0 for system out. -To use SLF4J, append ;TRACE_LEVEL_FILE=4 to the database URL when opening the database. - -This setting is not persistent. -Admin rights are required to execute this command. -This command does not commit a transaction, and rollback does not affect it. -This setting can be appended to the database URL: jdbc:h2:test;TRACE_LEVEL_SYSTEM_OUT=3 -"," -SET TRACE_LEVEL_SYSTEM_OUT 3 -" - -"Commands (Other)","SET TRACE_MAX_FILE_SIZE"," -SET TRACE_MAX_FILE_SIZE int -"," -Sets the maximum trace file size. If the file exceeds the limit, the file is -renamed to .old and a new file is created. If another .old file exists, it is -deleted. The default max size is 16 MB. - -This setting is persistent. -Admin rights are required to execute this command. -This command commits an open transaction. -This setting can be appended to the database URL: jdbc:h2:test;TRACE_MAX_FILE_SIZE=3 -"," -SET TRACE_MAX_FILE_SIZE 10 -" - -"Commands (Other)","SET UNDO_LOG"," -SET UNDO_LOG int -"," -Enables (1) or disables (0) the per session undo log. The undo log is enabled by -default. When disabled, transactions can not be rolled back. This setting should -only be used for bulk operations that don't need to be atomic. - -This command commits an open transaction. -"," -SET UNDO_LOG 0 -" - -"Commands (Other)","SET WRITE_DELAY"," -SET WRITE_DELAY int -"," -Set the maximum delay between a commit and flushing the log, in milliseconds. -This setting is persistent. The default is 500 ms. - -Admin rights are required to execute this command. -This command commits an open transaction. -This setting can be appended to the database URL: jdbc:h2:test;WRITE_DELAY=0 -"," -SET WRITE_DELAY 2000 -" - -"Commands (Other)","SHUTDOWN"," -SHUTDOWN [ IMMEDIATELY | COMPACT ] -"," -This statement closes all open connections to the database and closes the -database. This command is usually not required, as the database is -closed automatically when the last connection to it is closed. - -If no option is used, then the database is closed normally. -All connections are closed, open transactions are rolled back. - -SHUTDOWN COMPACT fully compacts the database (re-creating the database may further reduce the database size). -If the database is closed normally (using SHUTDOWN or by closing all connections), then the database is also compacted, -but only for at most the time defined by the system property h2.maxCompactTime (see there). - -SHUTDOWN IMMEDIATELY closes the database files without any cleanup and without compacting. - -Admin rights are required to execute this command. -"," -SHUTDOWN COMPACT -" - -"Other Grammar","Alias"," -name -"," -An alias is a name that is only valid in the context of the statement. -"," -A -" - -"Other Grammar","And Condition"," -condition [ { AND condition } [...] ] -"," -Value or condition. -"," -ID=1 AND NAME='Hi' -" - -"Other Grammar","Array"," -( expression [,...] ) -"," -An array of values. -"," -(1, 2) -" - -"Other Grammar","Boolean"," -TRUE | FALSE -"," -A boolean value. -"," -TRUE -" - -"Other Grammar","Bytes"," -X'hex' -"," -A binary value. The hex value is not case sensitive. -"," -X'01FF' -" - -"Other Grammar","Case"," -CASE expression { WHEN expression THEN expression } [...] -[ ELSE expression ] END -"," -Returns the first expression where the value is equal to the test expression. If -no else part is specified, return NULL. -"," -CASE CNT WHEN 0 THEN 'No' WHEN 1 THEN 'One' ELSE 'Some' END -" - -"Other Grammar","Case When"," -CASE { WHEN expression THEN expression} [...] -[ ELSE expression ] END -"," -Returns the first expression where the condition is true. If no else part is -specified, return NULL. -"," -CASE WHEN CNT<10 THEN 'Low' ELSE 'High' END -" - -"Other Grammar","Cipher"," -{ AES | XTEA } -"," -Two algorithms are supported, AES (AES-128) and XTEA (using 32 rounds). The AES -algorithm is about half as fast as XTEA. -"," -AES -" - -"Other Grammar","Column Definition"," -columnName dataType { DEFAULT expression | AS computedColumnExpression } [ [ NOT ] NULL ] -[ { AUTO_INCREMENT | IDENTITY } [ ( startInt [, incrementInt ] ) ] ] -[ SELECTIVITY selectivity ] [ PRIMARY KEY [ HASH ] | UNIQUE ] -"," -Default expressions are used if no explicit value was used when adding a row. -The computed column expression is evaluated and assigned whenever the row changes. - -Identity and auto-increment columns are columns with a sequence as the -default. The column declared as the identity columns is implicitly the -primary key column of this table (unlike auto-increment columns). -"," -CREATE TABLE TEST(ID INT PRIMARY KEY, NAME VARCHAR(255) DEFAULT ''); -CREATE TABLE TEST(ID BIGINT IDENTITY); -CREATE TABLE TEST(QUANTITY INT, PRICE DECIMAL, AMOUNT DECIMAL AS QUANTITY*PRICE); -" - -"Other Grammar","Comments"," --- anythingUntilEndOfLine | // anythingUntilEndOfLine | /* anythingUntilEndComment */ -"," -Comments can be used anywhere in a command and are ignored by the database. Line -comments end with a newline. Block comments cannot be nested, but can be -multiple lines long. -"," -// This is a comment -" - -"Other Grammar","Compare"," -<> | <= | >= | = | < | > | != -"," -Comparison operator. The operator != is the same as <>. -"," -<> -" - -"Other Grammar","Condition"," -operand [ conditionRightHandSide ] | NOT condition | EXISTS ( select ) -"," -Boolean value or condition. -"," -ID<>2 -" - -"Other Grammar","Condition Right Hand Side"," -compare { { { ALL | ANY | SOME } ( select ) } | operand } - | IS [ NOT ] NULL - | BETWEEN operand AND operand - | IN ( { select | expression [,...] } ) - | [ NOT ] LIKE operand [ ESCAPE string ] - | [ NOT ] REGEXP operand -"," -The right hand side of a condition. - -When comparing with LIKE, the wildcards characters are _ (any one character) -and % (any characters). The database uses an index when comparing with LIKE -except if the operand starts with a wildcard. To search for the characters % and -_, the characters need to be escaped. The default escape character is \ (backslash). -To select no escape character, use ESCAPE '' (empty string). -At most one escape character is allowed. -Each character that follows the escape character in the pattern needs to match exactly. -Patterns that end with an escape character are invalid and the expression returns NULL. - -When comparing with REGEXP, regular expression matching is used. -See Java Matcher.find for details. -"," -LIKE 'Jo%' -" - -"Other Grammar","Constraint"," -[ constraintNameDefinition ] { - CHECK expression | UNIQUE ( columnName [,...] ) - | referentialConstraint } - | PRIMARY KEY [ HASH ] ( columnName [,...] ) -"," -Defines a constraint. The check condition must evaluate to true or to NULL (to -prevent NULL, use NOT NULL). -"," -PRIMARY KEY(ID, NAME) -" - -"Other Grammar","Constraint Name Definition"," -CONSTRAINT [ IF NOT EXISTS ] newConstraintName -"," -Defines a constraint name. -"," -CONSTRAINT CONST_ID -" - -"Other Grammar","Csv Options"," -charsetString [, fieldSepString [, fieldDelimString [, escString [, nullString]]]]] -"," -Optional parameters for CSVREAD and CSVWRITE. -"," -CALL CSVWRITE('test2.csv', 'SELECT * FROM TEST', 'UTF-8', '|'); -" - -"Other Grammar","Data Type"," -intType | booleanType | tinyintType | smallintType | bigintType | identityType - | decimalType | doubleType | realType | dateType | timeType | timestampType - | binaryType | otherType | varcharType | varcharIgnorecaseType | charType - | blobType | clobType | uuidType | arrayType -"," -A data type definition. -"," -INT -" - -"Other Grammar","Date"," -DATE 'yyyy-MM-dd' -"," -A date literal. The limitations are the same as for the Java data type -java.sql.Date, but for compatibility with other databases the suggested minimum -and maximum years are 0001 and 9999. -"," -DATE '2004-12-31' -" - -"Other Grammar","Decimal"," -[ + | - ] number [ . number ] -"," -Number with fixed precision and scale. -"," --1600.05 -" - -"Other Grammar","Digit"," -0-9 -"," -A digit. -"," -0 -" - -"Other Grammar","Dollar Quoted String"," -$$anythingExceptTwoDollarSigns$$ -"," -A string starts and ends with two dollar signs. Two dollar signs are not allowed -within the text. A whitespace is required before the first set of dollar signs. -No escaping is required within the text. -"," -$$John's car$$ -" - -"Other Grammar","Double"," -[ + | - ] { { number [ . number ] } | { . number } } [ E [ + | - ] expNumber [...] ] ] -"," -The limitations are the same as for the Java data type Double. -"," --1.4e-10 -" - -"Other Grammar","Expression"," -andCondition [ { OR andCondition } [...] ] -"," -Value or condition. -"," -ID=1 OR NAME='Hi' -" - -"Other Grammar","Factor"," -term [ { { * | / } term } [...] ] -"," -A value or a numeric factor. -"," -ID * 10 -" - -"Other Grammar","Hex"," -{ { digit | a-f | A-F } { digit | a-f | A-F } } [...] -"," -The hexadecimal representation of a number or of bytes. Two characters are one -byte. -"," -cafe -" - -"Other Grammar","Hex Number"," -[ + | - ] 0x hex -"," -A number written in hexadecimal notation. -"," -0xff -" - -"Other Grammar","Index Column"," -columnName [ ASC | DESC ] [ NULLS { FIRST | LAST } ] -"," -Indexes this column in ascending or descending order. Usually it is not required -to specify the order; however doing so will speed up large queries that order -the column in the same way. -"," -NAME -" - -"Other Grammar","Int"," -[ + | - ] number -"," -The maximum integer number is 2147483647, the minimum is -2147483648. -"," -10 -" - -"Other Grammar","Long"," -[ + | - ] number -"," -Long numbers are between -9223372036854775808 and 9223372036854775807. -"," -100000 -" - -"Other Grammar","Name"," -{ { A-Z|_ } [ { A-Z|_|0-9 } [...] ] } | quotedName -"," -Names are not case sensitive. There is no maximum name length. -"," -TEST -" - -"Other Grammar","Null"," -NULL -"," -NULL is a value without data type and means 'unknown value'. -"," -NULL -" - -"Other Grammar","Number"," -digit [...] -"," -The maximum length of the number depends on the data type used. -"," -100 -" - -"Other Grammar","Operand"," -summand [ { || summand } [...] ] -"," -A value or a concatenation of values. -"," -'Hi' || ' Eva' -" - -"Other Grammar","Order"," -{ int | expression } [ ASC | DESC ] [ NULLS { FIRST | LAST } ] -"," -Sorts the result by the given column number, or by an expression. If the -expression is a single parameter, then the value is interpreted as a column -number. Negative column numbers reverse the sort order. -"," -NAME DESC NULLS LAST -" - -"Other Grammar","Quoted Name"," -""anythingExceptDoubleQuote"" -"," -Quoted names are case sensitive, and can contain spaces. There is no maximum -name length. Two double quotes can be used to create a single double quote -inside an identifier. -"," -""FirstName"" -" - -"Other Grammar","Referential Constraint"," -FOREIGN KEY ( columnName [,...] ) -REFERENCES [ refTableName ] [ ( refColumnName [,...] ) ] -[ ON DELETE { CASCADE | RESTRICT | NO ACTION | SET { DEFAULT | NULL } } ] -[ ON UPDATE { CASCADE | SET { DEFAULT | NULL } } ] -"," -Defines a referential constraint. If the table name is not specified, then the -same table is referenced. RESTRICT is the default action. -As this database does not support deferred checking, -RESTRICT and NO ACTION will both throw an exception if the constraint is violated. -If the referenced columns are not specified, then the primary key columns are used. -The required indexes are automatically created if required. -Some tables may not be referenced, such as metadata tables. -"," -FOREIGN KEY(ID) REFERENCES TEST(ID) -" - -"Other Grammar","Select Expression"," -* | expression [ [ AS ] columnAlias ] | tableAlias.* -"," -An expression in a SELECT statement. -"," -ID AS VALUE -" - -"Other Grammar","String"," -'anythingExceptSingleQuote' -"," -A string starts and ends with a single quote. Two single quotes can be used to -create a single quote inside a string. -"," -'John''s car' -" - -"Other Grammar","Summand"," -factor [ { { + | - } factor } [...] ] -"," -A value or a numeric sum. - -Please note the text concatenation operator is ||. -"," -ID + 20 -" - -"Other Grammar","Table Expression"," -{ [ schemaName. ] tableName | ( select ) } [ [ AS ] newTableAlias ] -[ { { LEFT | RIGHT } [ OUTER ] | [ INNER ] | CROSS | NATURAL } - JOIN tableExpression [ ON expression ] ] -"," -Joins a table. The join expression is not supported for cross and natural joins. -A natural join is an inner join, where the condition is automatically on the -columns with the same name. -"," -TEST AS T LEFT JOIN TEST AS T1 ON T.ID = T1.ID -" - -"Other Grammar","Term"," -value - | columnName - | ?[ int ] - | NEXT VALUE FOR sequenceName - | function - | { - | + } term - | ( expression ) - | select - | case - | caseWhen - | tableAlias.columnName -"," -A value. Parameters can be indexed, for example ?1 meaning the first parameter. -"," -'Hello' -" - -"Other Grammar","Time"," -TIME 'hh:mm:ss' -"," -A time literal. -"," -TIME '23:59:59' -" - -"Other Grammar","Timestamp"," -TIMESTAMP 'yyyy-MM-dd hh:mm:ss[.nnnnnnnnn]' -"," -A timestamp literal. The limitations are the same as for the Java data type -java.sql.Timestamp, but for compatibility with other databases the suggested -minimum and maximum years are 0001 and 9999. -"," -TIMESTAMP '2005-12-31 23:59:59' -" - -"Other Grammar","Value"," -string | dollarQuotedString | hexNumber | int | long | decimal | double - | date | time | timestamp | boolean | bytes | array | null -"," -A value of any data type, or null. -"," -10 -" - -"Data Types","INT Type"," -INT | INTEGER | MEDIUMINT | INT4 | SIGNED -"," -Possible values: -2147483648 to 2147483647. - -Mapped to java.lang.Integer. -"," -INT -" - -"Data Types","BOOLEAN Type"," -BOOLEAN | BIT | BOOL -"," -Possible values: TRUE and FALSE. - -Mapped to java.lang.Boolean. -"," -BOOLEAN -" - -"Data Types","TINYINT Type"," -TINYINT -"," -Possible values are: -128 to 127. - -Mapped to java.lang.Byte. -"," -TINYINT -" - -"Data Types","SMALLINT Type"," -SMALLINT | INT2 | YEAR -"," -Possible values: -32768 to 32767. - -Mapped to java.lang.Short. -"," -SMALLINT -" - -"Data Types","BIGINT Type"," -BIGINT | INT8 -"," -Possible values: -9223372036854775808 to 9223372036854775807. - -Mapped to java.lang.Long. -"," -BIGINT -" - -"Data Types","IDENTITY Type"," -IDENTITY -"," -Auto-Increment value. Possible values: -9223372036854775808 to -9223372036854775807. Used values are never re-used, even when the transaction is -rolled back. - -Mapped to java.lang.Long. -"," -IDENTITY -" - -"Data Types","DECIMAL Type"," -{ DECIMAL | NUMBER | DEC | NUMERIC } ( precisionInt [ , scaleInt ] ) -"," -Data type with fixed precision and scale. This data type is recommended for -storing currency values. - -Mapped to java.math.BigDecimal. -"," -DECIMAL(20, 2) -" - -"Data Types","DOUBLE Type"," -{ DOUBLE [ PRECISION ] | FLOAT | FLOAT4 | FLOAT8 } -"," -Floating point number. Should not be used to represent currency values, because -of rounding problems. - -Mapped to java.lang.Double. -"," -DOUBLE -" - -"Data Types","REAL Type"," -REAL -"," -Single precision floating point number. Should not be used to represent currency -values, because of rounding problems. - -Mapped to java.lang.Float. -"," -REAL -" - -"Data Types","TIME Type"," -TIME -"," -The format is hh:mm:ss. - -Mapped to java.sql.Time. When converted to a java.sql.Date, the date is set to 1970-01-01. -"," -TIME -" - -"Data Types","DATE Type"," -DATE -"," -The format is yyyy-MM-dd. - -Mapped to java.sql.Date, with the time set to 00:00:00 -(or to the next possible time if midnight doesn't exist for the given date and timezone due to a daylight saving change). -"," -DATE -" - -"Data Types","TIMESTAMP Type"," -{ TIMESTAMP | DATETIME | SMALLDATETIME } -"," -The format is yyyy-MM-dd hh:mm:ss[.nnnnnnnnn]. - -Mapped to java.sql.Timestamp (java.util.Date is also supported). -"," -TIMESTAMP -" - -"Data Types","BINARY Type"," -{ BINARY | VARBINARY | LONGVARBINARY | RAW | BYTEA } [ ( precisionInt ) ] -"," -Represents a byte array. For very long arrays, use BLOB. -The maximum size is 2 GB, but the whole object is kept in -memory when using this data type. The precision is a size constraint; -only the actual data is persisted. For large text data BLOB or CLOB -should be used. - -Mapped to byte[]. -"," -BINARY(1000) -" - -"Data Types","OTHER Type"," -OTHER -"," -This type allows storing serialized Java objects. Internally, a byte array is -used. Serialization and deserialization is done on the client side only. -Deserialization is only done get getObject is called. Java operations cannot be -executed inside the database engine for security reasons. Use -PreparedStatement.setObject to store values. - -Mapped to java.lang.Object (or any subclass). -"," -OTHER -" - -"Data Types","VARCHAR Type"," -{ VARCHAR | LONGVARCHAR | VARCHAR2 | NVARCHAR - | NVARCHAR2 | VARCHAR_CASESENSITIVE} [ ( precisionInt ) ] -"," -Unicode String. Use two single quotes ('') to create a quote. The maximum precision -is Integer.MAX_VALUE. The precision is a size constraint; only the actual data is -persisted. The whole text is kept in memory when using this data type. For large text data CLOB -should be used; see there for details. - -Mapped to java.lang.String. -"," -VARCHAR(255) -" - -"Data Types","VARCHAR_IGNORECASE Type"," -VARCHAR_IGNORECASE [ ( precisionInt ) ] -"," -Same as VARCHAR, but not case sensitive when comparing. Stored in mixed case. -The maximum precision is Integer.MAX_VALUE characters, but the whole text is kept in -memory when using this data type. For large text data CLOB should be used; -see there for details. - -Mapped to java.lang.String. -"," -VARCHAR_IGNORECASE -" - -"Data Types","CHAR Type"," -{ CHAR | CHARACTER | NCHAR } [ ( precisionInt ) ] -"," -This type is supported for compatibility with other databases and older -applications. The difference to VARCHAR is that trailing spaces are ignored and -not persisted. Unicode String. Use two single quotes ('') to create a quote. -The maximum precision is Integer.MAX_VALUE. The precision is a size constraint; -only the actual data is persisted. The whole text is kept in memory when using -this data type. For large text data CLOB should be used; see there for details. - -Mapped to java.lang.String. -"," -CHAR(10) -" - -"Data Types","BLOB Type"," -{ BLOB | TINYBLOB | MEDIUMBLOB | LONGBLOB | IMAGE | OID } [ ( precisionInt ) ] -"," -Like BINARY, but intended for very large values such as files or images. Unlike -when using BINARY, large objects are not kept fully in-memory. Use -PreparedStatement.setBinaryStream to store values. See also CLOB and -Advanced / Large Objects. - -Mapped to java.sql.Blob (java.io.InputStream is also supported). -"," -BLOB -" - -"Data Types","CLOB Type"," -{ CLOB | TINYTEXT | TEXT | MEDIUMTEXT | LONGTEXT | NTEXT | NCLOB } [ ( precisionInt ) ] -"," -CLOB is like VARCHAR, but intended for very large values. Unlike when using -VARCHAR, large CLOB objects are not kept fully in-memory; instead, they are streamed. -CLOB should be used for documents and texts with arbitrary size such as XML or -HTML documents, text files, or memo fields of unlimited size. Use -PreparedStatement.setCharacterStream to store values. See also Advanced / Large Objects. - -VARCHAR should be used for text with relatively short average size (for example -shorter than 200 characters). Short CLOB values are stored inline, but there is -an overhead compared to VARCHAR. - -Mapped to java.sql.Clob (java.io.Reader is also supported). -"," -CLOB -" - -"Data Types","UUID Type"," -UUID -"," -Universally unique identifier. This is a 128 bit value. Use -PreparedStatement.setBytes or setString to store values. - -Mapped to java.util.UUID. -"," -UUID -" - -"Data Types","ARRAY Type"," -ARRAY -"," -An array of values. Use a value list (1, 2) or PreparedStatement.setObject(.., -new Object[] {..}) to store values. - -Mapped to java.lang.Object[] (arrays of any non-primitive type are also supported). -"," -ARRAY -" - -"Functions (Aggregate)","AVG"," -AVG ( [ DISTINCT ] { int | long | decimal | double } ) -"," -The average (mean) value. -If no rows are selected, the result is NULL. -Aggregates are only allowed in select statements. -The returned value is of the same data type as the parameter. -"," -AVG(X) -" - -"Functions (Aggregate)","BOOL_AND"," -BOOL_AND(boolean) -"," -Returns true if all expressions are true. -If no rows are selected, the result is NULL. -Aggregates are only allowed in select statements. -"," -BOOL_AND(ID>10) -" - -"Functions (Aggregate)","BOOL_OR"," -BOOL_OR(boolean) -"," -Returns true if any expression is true. -If no rows are selected, the result is NULL. -Aggregates are only allowed in select statements. -"," -BOOL_OR(NAME LIKE 'W%') -" - -"Functions (Aggregate)","COUNT"," -COUNT( { * | { [ DISTINCT ] expression } } ) -"," -The count of all row, or of the non-null values. -This method returns a long. -If no rows are selected, the result is 0. -Aggregates are only allowed in select statements. -"," -COUNT(*) -" - -"Functions (Aggregate)","GROUP_CONCAT"," -GROUP_CONCAT ( [ DISTINCT ] string -[ ORDER BY { expression [ ASC | DESC ] } [,...] ] -[ SEPARATOR expression ] ) -"," -Concatenates strings with a separator. -The default separator is a ',' (without space). -This method returns a string. -If no rows are selected, the result is NULL. -Aggregates are only allowed in select statements. -"," -GROUP_CONCAT(NAME ORDER BY ID SEPARATOR ', ') -" - -"Functions (Aggregate)","MAX"," -MAX(value) -"," -The highest value. -If no rows are selected, the result is NULL. -Aggregates are only allowed in select statements. -The returned value is of the same data type as the parameter. -"," -MAX(NAME) -" - -"Functions (Aggregate)","MIN"," -MIN(value) -"," -The lowest value. -If no rows are selected, the result is NULL. -Aggregates are only allowed in select statements. -The returned value is of the same data type as the parameter. -"," -MIN(NAME) -" - -"Functions (Aggregate)","SUM"," -SUM( [ DISTINCT ] { int | long | decimal | double } ) -"," -The sum of all values. -If no rows are selected, the result is NULL. -Aggregates are only allowed in select statements. -The returned value is of the same data type as the parameter. -"," -SUM(X) -" - -"Functions (Aggregate)","SELECTIVITY"," -SELECTIVITY(value) -"," -Estimates the selectivity (0-100) of a value. -The value is defined as (100 * distinctCount / rowCount). -The selectivity of 0 rows is 0 (unknown). -Up to 10000 values are kept in memory. -Aggregates are only allowed in select statements. -"," -SELECT SELECTIVITY(FIRSTNAME), SELECTIVITY(NAME) FROM TEST WHERE ROWNUM()<20000 -" - -"Functions (Aggregate)","STDDEV_POP"," -STDDEV_POP( [ DISTINCT ] double ) -"," -The population standard deviation. -This method returns a double. -If no rows are selected, the result is NULL. -Aggregates are only allowed in select statements. -"," -STDDEV_POP(X) -" - -"Functions (Aggregate)","STDDEV_SAMP"," -STDDEV_SAMP( [ DISTINCT ] double ) -"," -The sample standard deviation. -This method returns a double. -If no rows are selected, the result is NULL. -Aggregates are only allowed in select statements. -"," -STDDEV(X) -" - -"Functions (Aggregate)","VAR_POP"," -VAR_POP( [ DISTINCT ] double ) -"," -The population variance (square of the population standard deviation). -This method returns a double. -If no rows are selected, the result is NULL. -Aggregates are only allowed in select statements. -"," -VAR_POP(X) -" - -"Functions (Aggregate)","VAR_SAMP"," -VAR_SAMP( [ DISTINCT ] double ) -"," -The sample variance (square of the sample standard deviation). -This method returns a double. -If no rows are selected, the result is NULL. -Aggregates are only allowed in select statements. -"," -VAR_SAMP(X) -" - -"Functions (Numeric)","ABS"," -ABS ( { int | long | decimal | double } ) -"," -See also Java Math.abs. -Please note that Math.abs(Integer.MIN_VALUE) == Integer.MIN_VALUE and Math.abs(Long.MIN_VALUE) == Long.MIN_VALUE. -The returned value is of the same data type as the parameter. -"," -ABS(ID) -" - -"Functions (Numeric)","ACOS"," -ACOS(double) -"," -See also Java Math.* functions. -This method returns a double. -"," -ACOS(D) -" - -"Functions (Numeric)","ASIN"," -ASIN(double) -"," -See also Java Math.* functions. -This method returns a double. -"," -ASIN(D) -" - -"Functions (Numeric)","ATAN"," -ATAN(double) -"," -See also Java Math.* functions. -This method returns a double. -"," -ATAN(D) -" - -"Functions (Numeric)","COS"," -COS(double) -"," -See also Java Math.* functions. -This method returns a double. -"," -COS(ANGLE) -" - -"Functions (Numeric)","COT"," -COT(double) -"," -See also Java Math.* functions. -This method returns a double. -"," -COT(ANGLE) -" - -"Functions (Numeric)","SIN"," -SIN(double) -"," -See also Java Math.* functions. -This method returns a double. -"," -SIN(ANGLE) -" - -"Functions (Numeric)","TAN"," -TAN(double) -"," -See also Java Math.* functions. -This method returns a double. -"," -TAN(ANGLE) -" - -"Functions (Numeric)","ATAN2"," -ATAN2(double, double) -"," -See also Java Math.atan2. -This method returns a double. -"," -ATAN2(X, Y) -" - -"Functions (Numeric)","BITAND"," -BITAND(long, long) -"," -The bitwise AND operation. -This method returns a long. -See also Java operator &. -"," -BITAND(A, B) -" - -"Functions (Numeric)","BITOR"," -BITOR(long, long) -"," -The bitwise OR operation. -This method returns a long. -See also Java operator |. -"," -BITOR(A, B) -" - -"Functions (Numeric)","BITXOR"," -BITXOR(long, long) -"," -The bitwise XOR operation. -This method returns a long. -See also Java operator ^. -"," -BITXOR(A, B) -" - -"Functions (Numeric)","MOD"," -MOD(long, long) -"," -The modulo operation. -This method returns a long. -See also Java operator %. -"," -MOD(A, B) -" - -"Functions (Numeric)","CEILING"," -CEILING(double) -"," -See also Java Math.ceil. -This method returns a double. -"," -LOG(A) -" - -"Functions (Numeric)","DEGREES"," -DEGREES(double) -"," -See also Java Math.toDegrees. -This method returns a double. -"," -DEGREES(A) -" - -"Functions (Numeric)","EXP"," -EXP(double) -"," -See also Java Math.exp. -This method returns a double. -"," -EXP(A) -" - -"Functions (Numeric)","FLOOR"," -FLOOR(double) -"," -See also Java Math.floor. -This method returns a double. -"," -FLOOR(A) -" - -"Functions (Numeric)","LOG"," -LOG(double) -"," -See also Java Math.log. -This method returns a double. -"," -LOG(A) -" - -"Functions (Numeric)","LOG10"," -LOG10(double) -"," -See also Java Math.log10 (in Java 5). -This method returns a double. -"," -LOG10(A) -" - -"Functions (Numeric)","RADIANS"," -RADIANS(double) -"," -See also Java Math.toRadians. -This method returns a double. -"," -RADIANS(A) -" - -"Functions (Numeric)","SQRT"," -SQRT(double) -"," -See also Java Math.sqrt. -This method returns a double. -"," -SQRT(A) -" - -"Functions (Numeric)","PI"," -PI() -"," -See also Java Math.PI. -This method returns a double. -"," -PI() -" - -"Functions (Numeric)","POWER"," -POWER(double, double) -"," -See also Java Math.pow. -This method returns a double. -"," -POWER(A, B) -" - -"Functions (Numeric)","RAND"," -RAND( [ int ] ) -"," -Calling the function without parameter returns the next a pseudo random number. -Calling it with an parameter seeds the session's random number generator. -This method returns a double. -"," -RAND() -" - -"Functions (Numeric)","RANDOM_UUID"," -RANDOM_UUID() -"," -Returns a new UUID with 122 pseudo random bits. -"," -RANDOM_UUID() -" - -"Functions (Numeric)","ROUND"," -ROUND(double, digitsInt) -"," -Rounds to a number of digits. -This method returns a double. -"," -ROUND(VALUE, 2) -" - -"Functions (Numeric)","ROUNDMAGIC"," -ROUNDMAGIC(double) -"," -This function rounds numbers in a good way, but it is slow. -It has a special handling for numbers around 0. -Only numbers smaller or equal +/-1000000000000 are supported. -The value is converted to a String internally, and then the last last 4 characters are checked. -'000x' becomes '0000' and '999x' becomes '999999', which is rounded automatically. -This method returns a double. -"," -ROUNDMAGIC(VALUE/3*3) -" - -"Functions (Numeric)","SECURE_RAND"," -SECURE_RAND(int) -"," -Generates a number of cryptographically secure random numbers. -This method returns bytes. -"," -CALL SECURE_RAND(16) -" - -"Functions (Numeric)","SIGN"," -SIGN ( { int | long | decimal | double } ) -"," -Returns -1 if the value is smaller 0, 0 if zero, and otherwise 1. -"," -SIGN(VALUE) -" - -"Functions (Numeric)","ENCRYPT"," -ENCRYPT(algorithmString, keyBytes, dataBytes) -"," -Encrypts data using a key. -Supported algorithms are XTEA and AES. -The block size is 16 bytes. -This method returns bytes. -"," -CALL ENCRYPT('AES', '00', STRINGTOUTF8('Test')) -" - -"Functions (Numeric)","DECRYPT"," -DECRYPT(algorithmString, keyBytes, dataBytes) -"," -Decrypts data using a key. -Supported algorithms are XTEA and AES. -The block size is 16 bytes. -This method returns bytes. -"," -CALL TRIM(CHAR(0) FROM UTF8TOSTRING( - DECRYPT('AES', '00', '3fabb4de8f1ee2e97d7793bab2db1116'))) -" - -"Functions (Numeric)","HASH"," -HASH(algorithmString, dataBytes, iterationInt) -"," -Calculate the hash value using an algorithm, and repeat this process for a number of iterations. -Currently, the only algorithm supported is SHA256. -This method returns bytes. -"," -CALL HASH('SHA256', STRINGTOUTF8('Password'), 1000) -" - -"Functions (Numeric)","TRUNCATE"," -TRUNCATE(double, digitsInt) -"," -Truncates to a number of digits (to the next value closer to 0). -This method returns a double. -"," -TRUNCATE(VALUE, 2) -" - -"Functions (Numeric)","COMPRESS"," -COMPRESS(dataBytes [, algorithmString]) -"," -Compresses the data using the specified compression algorithm. -Supported algorithms are: LZF (faster but lower compression; default), and DEFLATE (higher compression). -Compression does not always reduce size. Very small objects and objects with little redundancy may get larger. -This method returns bytes. -"," -COMPRESS(STRINGTOUTF8('Test')) -" - -"Functions (Numeric)","EXPAND"," -EXPAND(bytes) -"," -Expands data that was compressed using the COMPRESS function. -This method returns bytes. -"," -UTF8TOSTRING(EXPAND(COMPRESS(STRINGTOUTF8('Test')))) -" - -"Functions (Numeric)","ZERO"," -ZERO() -"," -Returns the value 0. This function can be used even if numeric literals are disabled. -"," -ZERO() -" - -"Functions (String)","ASCII"," -ASCII(string) -"," -Returns the ASCII value of the first character in the string. -This method returns an int. -"," -ASCII('Hi') -" -"Functions (String)","BIT_LENGTH"," -BIT_LENGTH(string) -"," -Returns the number of bits in a string. -This method returns a long. -For BLOB, CLOB, BYTES and JAVA_OBJECT, the precision is used. Each character needs 16 bits. -"," -BIT_LENGTH(NAME) -" - -"Functions (String)","LENGTH"," -{ LENGTH | CHAR_LENGTH | CHARACTER_LENGTH } ( string ) -"," -Returns the number of characters in a string. -This method returns a long. -For BLOB, CLOB, BYTES and JAVA_OBJECT, the precision is used. -"," -LENGTH(NAME) -" - -"Functions (String)","OCTET_LENGTH"," -OCTET_LENGTH(string) -"," -Returns the number of bytes in a string. -This method returns a long. -For BLOB, CLOB, BYTES and JAVA_OBJECT, the precision is used. -Each character needs 2 bytes. -"," -OCTET_LENGTH(NAME) -" - -"Functions (String)","CHAR"," -{ CHAR | CHR } ( int ) -"," -Returns the character that represents the ASCII value. -This method returns a string. -"," -CHAR(65) -" - -"Functions (String)","CONCAT"," -CONCAT(string, string [,...]) -"," -Combines strings. -This method returns a string. -"," -CONCAT(NAME, '!') -" - -"Functions (String)","DIFFERENCE"," -DIFFERENCE(string, string) -"," -Returns the difference between the sounds of two strings. -This method returns an int. -"," -DIFFERENCE(T1.NAME, T2.NAME) -" - -"Functions (String)","HEXTORAW"," -HEXTORAW(string) -"," -Converts a hex representation of a string to a string. -4 hex characters per string character are used. -"," -HEXTORAW(DATA) -" - -"Functions (String)","RAWTOHEX"," -RAWTOHEX(string) -"," -Converts a string to the hex representation. -4 hex characters per string character are used. -This method returns a string. -"," -RAWTOHEX(DATA) -" - -"Functions (String)","INSTR"," -INSTR(string, searchString, [, startInt]) -"," -Returns the location of a search string in a string (s). -If a start position is used, the characters before it are ignored. -If position is negative, the rightmost location is returned. -0 is returned if the search string is not found. -"," -INSTR(EMAIL,'@') -" - -"Functions (String)","INSERT Function"," -INSERT(originalString, startInt, lengthInt, addString) -"," -Inserts a additional string into the original string at a specified start position. -The length specifies the number of characters that are removed at the start position in the original string. -This method returns a string. -"," -INSERT(NAME, 1, 1, ' ') -" - -"Functions (String)","LOWER"," -{ LOWER | LCASE } ( string ) -"," -Converts a string to lowercase. -"," -LOWER(NAME) -" - -"Functions (String)","UPPER"," -{ UPPER | UCASE } ( string ) -"," -Converts a string to uppercase. -"," -UPPER(NAME) -" - -"Functions (String)","LEFT"," -LEFT(string, int) -"," -Returns the leftmost number of characters. -"," -LEFT(NAME, 3) -" - -"Functions (String)","RIGHT"," -RIGHT(string, int) -"," -Returns the rightmost number of characters. -"," -RIGHT(NAME, 3) -" - -"Functions (String)","LOCATE"," -LOCATE(searchString, string [, startInt]) -"," -Returns the location of a search string in a string. -If a start position is used, the characters before it are ignored. -If position is negative, the rightmost location is returned. -0 is returned if the search string is not found. -"," -LOCATE('.', NAME) -" - -"Functions (String)","POSITION"," -POSITION(searchString, string) -"," -Returns the location of a search string in a string. See also LOCATE. -"," -POSITION('.', NAME) -" - -"Functions (String)","LPAD"," -LPAD(string, int[, paddingString]) -"," -Left pad the string to the specified length. -If the length is shorter than the string, it will be truncated at the end. -If the padding string is not set, spaces will be used. -"," -LPAD(AMOUNT, 10, '*') -" - -"Functions (String)","RPAD"," -RPAD(string, int[, paddingString]) -"," -Right pad the string to the specified length. -If the length is shorter than the string, it will be truncated. -If the padding string is not set, spaces will be used. -"," -RPAD(TEXT, 10, '-') -" - -"Functions (String)","LTRIM"," -LTRIM(string) -"," -Removes all leading spaces from a string. -"," -LTRIM(NAME) -" - -"Functions (String)","RTRIM"," -RTRIM(string) -"," -Removes all trailing spaces from a string. -"," -RTRIM(NAME) -" - -"Functions (String)","TRIM"," -TRIM ( [ { LEADING | TRAILING | BOTH } [ string ] FROM ] string ) -"," -Removes all leading spaces, trailing spaces, or spaces at both ends, from a string. -Other characters can be removed as well. -"," -TRIM(BOTH '_' FROM NAME) -" - -"Functions (String)","REGEXP_REPLACE"," -REGEXP_REPLACE(inputString, regexString, replacementString) -"," -Replaces each substring that matches a regular expression. -For details, see the Java String.replaceAll() method. -If any parameter is null, the result is null. -"," -REGEXP_REPLACE('Hello World', ' +', ' ') -" - -"Functions (String)","REPEAT"," -REPEAT(string, int) -"," -Returns a string repeated some number of times. -"," -REPEAT(NAME || ' ', 10) -" - -"Functions (String)","REPLACE"," -REPLACE(string, searchString [, replacementString]) -"," -Replaces all occurrences of a search string in a text with another string. -If no replacement is specified, the search string is removed from the original string. -If any parameter is null, the result is null. -"," -REPLACE(NAME, ' ') -" - -"Functions (String)","SOUNDEX"," -SOUNDEX(string) -"," -Returns a four character code representing the sound of a string. -See also http://www.archives.gov/genealogy/census/soundex.html . -This method returns a string. -"," -SOUNDEX(NAME) -" - -"Functions (String)","SPACE"," -SPACE(int) -"," -Returns a string consisting of a number of spaces. -"," -SPACE(80) -" - -"Functions (String)","STRINGDECODE"," -STRINGDECODE(string) -"," -Converts a encoded string using the Java string literal encoding format. -Special characters are \b, \t, \n, \f, \r, \"", \\, \, \u. -This method returns a string. -"," -CALL STRINGENCODE(STRINGDECODE('Lines 1\nLine 2')) -" - -"Functions (String)","STRINGENCODE"," -STRINGENCODE(string) -"," -Encodes special characters in a string using the Java string literal encoding format. -Special characters are \b, \t, \n, \f, \r, \"", \\, \, \u. -This method returns a string. -"," -CALL STRINGENCODE(STRINGDECODE('Lines 1\nLine 2')) -" - -"Functions (String)","STRINGTOUTF8"," -STRINGTOUTF8(string) -"," -Encodes a string to a byte array using the UTF8 encoding format. -This method returns bytes. -"," -CALL UTF8TOSTRING(STRINGTOUTF8('This is a test')) -" - -"Functions (String)","SUBSTRING"," -{ SUBSTRING | SUBSTR } ( string, startInt [, lengthInt ] ) -"," -Returns a substring of a string starting at a position. -The length is optional. -Also supported is: SUBSTRING(string FROM start [FOR length]). -"," -SUBSTR(NAME, 1) -" - -"Functions (String)","UTF8TOSTRING"," -UTF8TOSTRING(bytes) -"," -Decodes a byte array in the UTF8 format to a string. -"," -CALL UTF8TOSTRING(STRINGTOUTF8('This is a test')) -" - -"Functions (String)","XMLATTR"," -XMLATTR(nameString, valueString) -"," -Creates an XML attribute element of the form name=""value"". -The value is encoded as XML text. -This method returns a string. -"," -CALL XMLNODE('a', XMLATTR('href', 'http://h2database.com')) -" - -"Functions (String)","XMLNODE"," -XMLNODE(elementString [, attributesString [, contentString]]) -"," -Create an XML node element. -This method returns a string. -"," -CALL XMLNODE('a', XMLATTR('href', 'http://h2database.com'), 'H2') -" - -"Functions (String)","XMLCOMMENT"," -XMLCOMMENT(commentString) -"," -Creates an XML comment. -Two dashes (--) are converted to - -. -This method returns a string. -"," -CALL XMLCOMMENT('Test') -" - -"Functions (String)","XMLCDATA"," -XMLCDATA(valueString) -"," -Creates an XML CDATA element. -If the value contains ']]>', an XML text element is created instead. -This method returns a string. -"," -CALL XMLCDATA('data') -" - -"Functions (String)","XMLSTARTDOC"," -XMLSTARTDOC() -"," -The string '' is returned. -"," -CALL XMLSTARTDOC() -" - -"Functions (String)","XMLTEXT"," -XMLTEXT(valueString) -"," -Creates an XML text element. -This method returns a string. -"," -CALL XMLTEXT('test') -" - -"Functions (Time and Date)","CURRENT_DATE"," -{ CURRENT_DATE [ () ] | CURDATE() | SYSDATE | TODAY } -"," -Returns the current date. -"," -CURRENT_DATE() -" - -"Functions (Time and Date)","CURRENT_TIME"," -{ CURRENT_TIME [ () ] | CURTIME() } -"," -Returns the current time. -"," -CURRENT_TIME() -" - -"Functions (Time and Date)","CURRENT_TIMESTAMP"," -{ CURRENT_TIMESTAMP [ ( [ int ] ) ] | NOW( [ int ] ) } -"," -Returns the current timestamp. -The precision parameter for nanoseconds precision is optional. -"," -CURRENT_TIMESTAMP() -" - -"Functions (Time and Date)","DATEADD"," -DATEADD(unitString, addInt, timestamp) -"," -Adds units to a timestamp. The string indicates the unit. -Use negative values to subtract units. -The same units as in the EXTRACT function are supported. -This method returns a timestamp. -"," -DATEADD('MONTH', 1, DATE '2001-01-31') -" - -"Functions (Time and Date)","DATEDIFF"," -{ DATEDIFF | TIMESTAMPDIFF } (unitString, aTimestamp, bTimestamp) -"," -Returns the difference between two timestamps. -This method returns a long. -The string indicates the unit. -The same units as in the EXTRACT function are supported. -TIMESTAMPDIFF is supported for MySQL compatibility. -"," -DATEDIFF('YEAR', T1.CREATED, T2.CREATED) -" - -"Functions (Time and Date)","DAYNAME"," -DAYNAME(date) -"," -Returns the name of the day (in English). -"," -DAYNAME(CREATED) -" - -"Functions (Time and Date)","DAY_OF_MONTH"," -DAY_OF_MONTH(date) -"," -Returns the day of the month (1-31). -"," -DAY_OF_MONTH(CREATED) -" - -"Functions (Time and Date)","DAY_OF_WEEK"," -DAY_OF_WEEK(date) -"," -Returns the day of the week (1 means Sunday). -"," -DAY_OF_WEEK(CREATED) -" - -"Functions (Time and Date)","DAY_OF_YEAR"," -DAY_OF_YEAR(date) -"," -Returns the day of the year (1-366). -"," -DAY_OF_YEAR(CREATED) -" - -"Functions (Time and Date)","EXTRACT"," -EXTRACT ( { YEAR | YY | MONTH | MM | DAY | DD | DAY_OF_YEAR - | DOY | HOUR | HH | MINUTE | MI | SECOND | SS | MILLISECOND | MS } - FROM timestamp ) -"," -Returns a specific value from a timestamps. -This method returns an int. -"," -EXTRACT(SECOND FROM CURRENT_TIMESTAMP) -" - -"Functions (Time and Date)","FORMATDATETIME"," -FORMATDATETIME ( timestamp, formatString -[ , localeString [ , timeZoneString ] ] ) -"," -Formats a date, time or timestamp as a string. -The most important format characters are: -y year, M month, d day, H hour, m minute, s second. -For details of the format, see java.text.SimpleDateFormat. -This method returns a string. -"," -CALL FORMATDATETIME(TIMESTAMP '2001-02-03 04:05:06', - 'EEE, d MMM yyyy HH:mm:ss z', 'en', 'GMT') -" - -"Functions (Time and Date)","HOUR"," -HOUR(timestamp) -"," -Returns the hour (0-23) from a timestamp. -"," -HOUR(CREATED) -" - -"Functions (Time and Date)","MINUTE"," -MINUTE(timestamp) -"," -Returns the minute (0-59) from a timestamp. -"," -MINUTE(CREATED) -" - -"Functions (Time and Date)","MONTH"," -MONTH(timestamp) -"," -Returns the month (1-12) from a timestamp. -"," -MONTH(CREATED) -" - -"Functions (Time and Date)","MONTHNAME"," -MONTHNAME(date) -"," -Returns the name of the month (in English). -"," -MONTHNAME(CREATED) -" - -"Functions (Time and Date)","PARSEDATETIME"," -PARSEDATETIME(string, formatString -[, localeString [, timeZoneString]]) -"," -Parses a string and returns a timestamp. -The most important format characters are: -y year, M month, d day, H hour, m minute, s second. -For details of the format, see java.text.SimpleDateFormat. -"," -CALL PARSEDATETIME('Sat, 3 Feb 2001 03:05:06 GMT', - 'EEE, d MMM yyyy HH:mm:ss z', 'en', 'GMT') -" - -"Functions (Time and Date)","QUARTER"," -QUARTER(timestamp) -"," -Returns the quarter (1-4) from a timestamp. -"," -QUARTER(CREATED) -" - -"Functions (Time and Date)","SECOND"," -SECOND(timestamp) -"," -Returns the second (0-59) from a timestamp. -"," -SECOND(CREATED) -" - -"Functions (Time and Date)","WEEK"," -WEEK(timestamp) -"," -Returns the week (1-53) from a timestamp. -This method uses the current system locale. -"," -WEEK(CREATED) -" - -"Functions (Time and Date)","YEAR"," -YEAR(timestamp) -"," -Returns the year from a timestamp. -"," -YEAR(CREATED) -" - -"Functions (System)","ARRAY_GET"," -ARRAY_GET(arrayExpression, indexExpression) -"," -Returns one element of an array. -This method returns a string. -"," -CALL ARRAY_GET(('Hello', 'World'), 2) -" - -"Functions (System)","ARRAY_LENGTH"," -ARRAY_GET(arrayExpression) -"," -Returns the length of an array. -"," -CALL ARRAY_LENGTH(('Hello', 'World')) -" - -"Functions (System)","AUTOCOMMIT"," -AUTOCOMMIT() -"," -Returns true if auto commit is switched on for this session. -"," -AUTOCOMMIT() -" - -"Functions (System)","CANCEL_SESSION"," -CANCEL_SESSION(sessionInt) -"," -Cancels the currently executing statement of another session. -The method only works if the multithreaded kernel is enabled (see SET MULTI_THREADED). -Returns true if the statement was canceled, false if the session is closed or no statement is currently executing. - -Admin rights are required to execute this command. -"," -CANCEL_SESSION(3) -" - -"Functions (System)","CASEWHEN Function"," -CASEWHEN(boolean, aValue, bValue) -"," -Returns 'a' if the boolean expression is true, otherwise 'b'. -Returns the same data type as the parameter. -"," -CASEWHEN(ID=1, 'A', 'B') -" - -"Functions (System)","CAST"," -CAST(value AS dataType) -"," -Converts a value to another data type. When converting a text to a number, the default Java conversion -rules are used (prefixes 0x or # for hexadecimal numbers, prefix 0 for octal numbers). -"," -CAST(NAME AS INT) -" - -"Functions (System)","COALESCE"," -COALESCE(aValue, bValue [,...]) -"," -Returns the first value that is not null. -"," -COALESCE(A, B, C) -" - -"Functions (System)","CONVERT"," -CONVERT(value, dataType) -"," -Converts a value to another data type. -"," -CONVERT(NAME, INT) -" - -"Functions (System)","CURRVAL"," -CURRVAL( [ schemaName, ] sequenceString ) -"," -Returns the current (last) value of the sequence, independent of the session. -If the sequence was just created, the method returns (start - interval). -If the schema name is not set, the current schema is used. -If the schema name is not set, the sequence name is converted to uppercase (for compatibility). -This method returns a long. -"," -CURRVAL('TEST_SEQ') -" - -"Functions (System)","CSVREAD"," -CSVREAD(fileNameString [, columnsString [, csvOptions ] ] ) -"," -Returns the result set of reading the CSV (comma separated values) file. -For each parameter, NULL means the default value should be used. - -If the column names are specified (a list of column names separated with the -fieldSeparator), those are used, otherwise (or if they are set to NULL) the first line of -the file is interpreted as the column names. -In that case, column names that contain no special characters (only letters, '_', -and digits; similar to the rule for Java identifiers) are considered case insensitive. -Other column names are case sensitive, that means you need to use quoted identifiers -(see below). - -The default charset is the default value for this system, and the default field separator -is a comma. Missing unquoted values as well as data that matches nullString is -parsed as NULL. All columns of type VARCHAR. - -The BOM (the byte-order-mark) character 0xfeff at the beginning of the file is ignored. - -This function can be used like a table: SELECT * FROM CSVREAD(...). -Instead of a file, an URL may be used, for example -jar:file:///c:/temp/example.zip!/org/example/nested.zip. - -Admin rights are required to execute this command. -"," -CALL CSVREAD('test.csv'); --- Read a file containing the columns ID, NAME with --- UTF-8 encoding and the pipe (|) as field separator -CALL CSVREAD('test2.csv', 'ID|NAME', 'UTF-8', '|'); --- Read a semicolon-separated file -SELECT * FROM CSVREAD('data/test.csv', NULL, NULL, ';'); -SELECT ""Last Name"" FROM CSVREAD('address.csv'); -" - -"Functions (System)","CSVWRITE"," -CSVWRITE ( fileNameString, queryString [, csvOptions [, lineSepString] ] ) -"," -Writes a CSV (comma separated values). The file is overwritten if it exists. -If only a file name is specified, it will be written to the current working directory. -For each parameter, NULL means the default value should be used. -The default charset is the default value for this system, and the default field separator is a comma. - -The values are converted to text using the default string representation; -if another conversion is required you need to change the select statement accordingly. -The parameter nullString is used when writing NULL (by default nothing is written -when NULL appears). The default line separator is the default value for this -system ('line.separator' system property). - -The returned value is the number or rows written. -Admin rights are required to execute this command. -"," -CALL CSVWRITE('test.csv', 'SELECT * FROM TEST'); --- Write a file with UTF-8 encoding and the pipe (|) as field separator -CALL CSVWRITE('test2.csv', 'SELECT * FROM TEST', 'UTF-8', '|'); -" - -"Functions (System)","DATABASE"," -DATABASE() -"," -Returns the name of the database. -"," -CALL DATABASE(); -" - -"Functions (System)","DATABASE_PATH"," -DATABASE_PATH() -"," -Returns the directory of the database files and the database name, if it is file -based. Returns NULL otherwise. -"," -CALL DATABASE_PATH(); -" - -"Functions (System)","FILE_READ"," -FILE_READ(fileNameString [,encodingString]) -"," -Returns the contents of a file. If only one parameter is supplied, the data are -returned as a BLOB. If two parameters are used, the data is returned as a CLOB -(text). The second parameter is the character set to use, NULL meaning the -default character set for this system. File names and URLs are supported. -Admin rights are required to execute this command. -"," -SELECT LENGTH(FILE_READ('~/.h2.server.properties')) LEN; -SELECT FILE_READ('http://localhost:8182/stylesheet.css', NULL) CSS; -" - -"Functions (System)","GREATEST"," -GREATEST(aValue, bValue [,...]) -"," -Returns the largest value that is not NULL, or NULL if all values are NULL. -"," -CALL GREATEST(1, 2, 3); -" - -"Functions (System)","IDENTITY"," -IDENTITY() -"," -Returns the last inserted identity value for this session. -This value changes whenever a new sequence number was generated, -even within a trigger or Java function. See also SCOPE_IDENTITY(). -This method returns a long. -"," -CALL IDENTITY(); -" - -"Functions (System)","IFNULL"," -IFNULL(aValue, bValue) -"," -Returns the value of 'a' if it is not null, otherwise 'b'. -"," -CALL IFNULL(NULL, ''); -" - -"Functions (System)","LEAST"," -LEAST(aValue, bValue [,...]) -"," -Returns the smallest value that is not NULL, or NULL if all values are NULL. -"," -CALL LEAST(1, 2, 3); -" - -"Functions (System)","LOCK_MODE"," -LOCK_MODE() -"," -Returns the current lock mode. See SET LOCK_MODE. -This method returns an int. -"," -CALL LOCK_MODE(); -" - -"Functions (System)","LOCK_TIMEOUT"," -LOCK_TIMEOUT() -"," -Returns the lock timeout of the current session (in milliseconds). -"," -LOCK_TIMEOUT() -" - -"Functions (System)","LINK_SCHEMA"," -LINK_SCHEMA(targetSchemaString, driverString, urlString, -userString, passwordString, sourceSchemaString) -"," -Creates table links for all tables in a schema. -If tables with the same name already exist, they are dropped first. -The target schema is created automatically if it does not yet exist. -The driver name may be empty if the driver is already loaded. -The list of tables linked is returned in the form of a result set. -Admin rights are required to execute this command. -"," -CALL LINK_SCHEMA('TEST2', '', 'jdbc:h2:test2', 'sa', 'sa', 'PUBLIC'); -" - -"Functions (System)","MEMORY_FREE"," -MEMORY_FREE() -"," -Returns the free memory in KB (where 1024 bytes is a KB). -This method returns an int. -The garbage is run before returning the value. -Admin rights are required to execute this command. -"," -MEMORY_FREE() -" - -"Functions (System)","MEMORY_USED"," -MEMORY_USED() -"," -Returns the used memory in KB (where 1024 bytes is a KB). -This method returns an int. -The garbage is run before returning the value. -Admin rights are required to execute this command. -"," -MEMORY_USED() -" - -"Functions (System)","NEXTVAL"," -NEXTVAL ( [ schemaName, ] sequenceString ) -"," -Returns the next value of the sequence. -Used values are never re-used, even when the transaction is rolled back. -If the schema name is not set, the current schema is used, and the sequence name is converted to uppercase (for compatibility). -This method returns a long. -"," -NEXTVAL('TEST_SEQ') -" - -"Functions (System)","NULLIF"," -NULLIF(aValue, bValue) -"," -Returns NULL if 'a' is equals to 'b', otherwise 'a'. -"," -NULLIF(A, B) -" - -"Functions (System)","READONLY"," -READONLY() -"," -Returns true if the database is read-only. -"," -READONLY() -" - -"Functions (System)","ROWNUM"," -ROWNUM() -"," -Returns the number of the current row. -This method returns an int. -This function is supported for SELECT statements, as well as for DELETE and UPDATE. -The first row has the row number 1, and is calculated before ordering and grouping the result set, -but after evaluating index conditions (even when the index conditions are specified in an outer query). -To get the row number after ordering and grouping, use a subquery. -"," -SELECT ROWNUM(), * FROM TEST; -SELECT ROWNUM(), * FROM (SELECT * FROM TEST ORDER BY NAME); -SELECT ID FROM (SELECT T.*, ROWNUM AS R FROM TEST T) WHERE R BETWEEN 2 AND 3; -" - -"Functions (System)","SCHEMA"," -SCHEMA() -"," -Returns the name of the default schema for this session. -"," -CALL SCHEMA() -" - -"Functions (System)","SCOPE_IDENTITY"," -SCOPE_IDENTITY() -"," -Returns the last inserted identity value for this session for the current scope. -Changes within triggers and Java functions are ignored. See also IDENTITY(). -This method returns a long. -"," -CALL SCOPE_IDENTITY(); -" - -"Functions (System)","SESSION_ID"," -SESSION_ID() -"," -Returns the unique session id number for the current database connection. -This id stays the same while the connection is open. -This method returns an int. -The database engine may re-use a session id after the connection is closed. -"," -CALL SESSION_ID() -" - -"Functions (System)","SET"," -SET(@variableName, value) -"," -Updates a variable with the given value. -The new value is returned. -When used in a query, the value is updated in the order the rows are read. -This can be used to implement running totals / cumulative sums. -"," -SELECT X, SET(@I, IFNULL(@I, 0)+X) RUNNING_TOTAL FROM SYSTEM_RANGE(1, 10) -" - -"Functions (System)","TABLE"," -{ TABLE | TABLE_DISTINCT } ( { name dataType = expression } [,...] ) -"," -Returns the result set. TABLE_DISTINCT removes duplicate rows. -"," -SELECT * FROM TABLE(ID INT=(1, 2), NAME VARCHAR=('Hello', 'World')) -" - -"Functions (System)","TRANSACTION_ID"," -TRANSACTION_ID() -"," -Returns the current transaction id for this session. -This method returns NULL if there is no uncommitted change, or if the the database is not persisted. -Otherwise a value of the following form is returned: -logFileId-position-sessionId. -This method returns a string. -The value is unique across database restarts (values are not re-used). -"," -CALL TRANSACTION_ID() -" - -"Functions (System)","USER"," -{ USER | CURRENT_USER } () -"," -Returns the name of the current user of this session. -"," -CURRENT_USER() -" - -"System Tables","Information Schema"," -INFORMATION_SCHEMA -"," -To get the list of system tables, execute the statement SELECT * FROM -INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = 'INFORMATION_SCHEMA' -"," - -" -"System Tables","Range Table"," -SYSTEM_RANGE(start, end) -"," -Contains all values from start to end (this is a dynamic table). -"," -SYSTEM_RANGE(0, 100) -" diff --git a/tools/h2/src/docsrc/html/advanced.html b/tools/h2/src/docsrc/html/advanced.html deleted file mode 100755 index 1700066..0000000 --- a/tools/h2/src/docsrc/html/advanced.html +++ /dev/null @@ -1,1341 +0,0 @@ - - - - -Advanced - - - - -
- - -

Advanced

- - Result Sets
- - Large Objects
- - Linked Tables
- - Transaction Isolation
- - Multi-Version Concurrency Control (MVCC)
- - Clustering / High Availability
- - Two Phase Commit
- - Compatibility
- - Standards Compliance
- - Run as Windows Service
- - ODBC Driver
- - Using H2 in Microsoft .NET
- - ACID
- - Durability Problems
- - Using the Recover Tool
- - File Locking Protocols
- - File Locking Method 'Serialized'
- - Protection against SQL Injection
- - Protection against Remote Access
- - Restricting Class Loading and Usage
- - Security Protocols
- - SSL/TLS Connections
- - Universally Unique Identifiers (UUID)
- - Settings Read from System Properties
- - Setting the Server Bind Address
- - Pluggable File System
- - Limits and Limitations
- - Glossary and Links
- -

Result Sets

- -

Statements that Return a Result Set

-

-The following statements return a result set: SELECT, EXPLAIN, CALL, SCRIPT, SHOW, HELP. -All other statements return an update count. -

- -

Limiting the Number of Rows

-

-Before the result is returned to the application, all rows are read by the database. -Server side cursors are not supported currently. -If only the first few rows are interesting for the application, then the -result set size should be limited to improve the performance. -This can be done using LIMIT in a query -(example: SELECT * FROM TEST LIMIT 100), -or by using Statement.setMaxRows(max). -

- -

Large Result Sets and External Sorting

-

-For large result set, the result is buffered to disk. The threshold can be defined using the statement -SET MAX_MEMORY_ROWS. -If ORDER BY is used, 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. -

- -

Large Objects

- -

Storing and Reading Large Objects

-

-If it is possible that the objects don't fit into memory, then the data type -CLOB (for textual data) or BLOB (for binary data) should be used. -For these data types, the objects are not fully read into memory, by using streams. -To store a BLOB, use PreparedStatement.setBinaryStream. To store a CLOB, use -PreparedStatement.setCharacterStream. To read a BLOB, use ResultSet.getBinaryStream, -and to read a CLOB, use ResultSet.getCharacterStream. -When using the client/server mode, large BLOB and CLOB data is stored in a temporary file -on the client side. -

- -

When to use CLOB/BLOB

-

-This database stores large LOB (CLOB and BLOB) objects as separate files. -Small LOB objects are stored in-place, the threshold can be set using -MAX_LENGTH_INPLACE_LOB, -but there is still an overhead to use CLOB/BLOB. Because of this, BLOB and CLOB -should never be used for columns with a maximum size below about 200 bytes. -The best threshold depends on the use case; reading in-place objects is faster -than reading from separate files, but slows down the performance of operations -that don't involve this column. -

- -

Large Object Compression

-

-CLOB and BLOB values can be compressed by using -SET COMPRESS_LOB. -The LZF algorithm is faster but needs more disk space. By default compression is disabled, which usually speeds up write -operations. If you store many large compressible values such as XML, HTML, text, and uncompressed binary files, -then compressing can save a lot of disk space (sometimes more than 50%), and read operations may even be faster. -

- -

Linked Tables

-

-This database supports linked tables, which means tables that don't exist in the current database but -are just links to another database. To create such a link, use the -CREATE LINKED TABLE statement: -

-
-CREATE LINKED TABLE LINK('org.postgresql.Driver', 'jdbc:postgresql:test', 'sa', 'sa', 'TEST');
-
-

-You can then access the table in the usual way. -Whenever the linked table is accessed, the database issues specific queries over JDBC. -Using the example above, if you issue the query SELECT * FROM LINK WHERE ID=1, -then the following query is run against the PostgreSQL database: SELECT * FROM TEST WHERE ID=?. -The same happens for insert and update statements. Only simple statements are executed against the -target database, that means no joins. Prepared statements are used where possible. -

-

-To view the statements that are executed against the target table, set the trace level to 3. -

-

-If multiple linked tables point to the same database (using the same database URL), the connection -is shared. To disable this, set the system property h2.shareLinkedConnections=false. -

-

-The statement CREATE LINKED TABLE -supports an optional schema name parameter. -

- -

Transaction Isolation

-

-Transaction isolation is provided for all data manipulation language (DML) statements. -Most data definition language (DDL) statements commit the current transaction. -See the Grammar for details. -

-

-This database supports the following transaction isolation levels: -

-
    -
  • Read Committed
    - This is the default level. - Read locks are released immediately. - Higher concurrency is possible when using this level.
    - To enable, execute the SQL statement SET LOCK_MODE 3
    - or append ;LOCK_MODE=3 to the database URL: jdbc:h2:~/test;LOCK_MODE=3 -
  • -Serializable
    - To enable, execute the SQL statement SET LOCK_MODE 1
    - or append ;LOCK_MODE=1 to the database URL: jdbc:h2:~/test;LOCK_MODE=1 -
  • Read Uncommitted
    - This level means that transaction isolation is disabled.
    - To enable, execute the SQL statement SET LOCK_MODE 0
    - or append ;LOCK_MODE=0 to the database URL: jdbc:h2:~/test;LOCK_MODE=0 -
  • -
-

-When using the isolation level 'serializable', dirty reads, non-repeatable reads, and phantom reads are prohibited. -

-
    -
  • Dirty Reads
    - Means a connection can read uncommitted changes made by another connection.
    - Possible with: read uncommitted -
  • Non-Repeatable Reads
    - 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.
    - Possible with: read uncommitted, read committed -
  • Phantom Reads
    - 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.
    - Possible with: read uncommitted, read committed -
  • -
- -

Table Level Locking

-

-The database allows multiple concurrent connections to the same database. -To make sure all connections only see consistent data, table level locking is used by default. -This mechanism does not allow high concurrency, but is very fast. -Shared locks and exclusive locks are supported. -Before reading from a table, the database tries to add a shared lock to the table -(this is only possible if there is no exclusive lock on the object by another connection). -If the shared lock is added successfully, the table can be read. It is allowed that -other connections also have a shared lock on the same object. If a connection wants -to write to a table (update or delete a row), an exclusive lock is required. To get the -exclusive lock, other connection must not have any locks on the object. After the -connection commits, all locks are released. -This database keeps all locks in memory. -

- -

Lock Timeout

-

-If a connection cannot get a lock on an object, the connection waits for some amount -of time (the lock timeout). During this time, hopefully the connection holding the -lock commits and it is then possible to get the lock. If this is not possible because -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. -

- -

Multi-Version Concurrency Control (MVCC)

-

-The MVCC feature allows higher concurrency than using (table level or row level) locks. -When using MVCC in this database, delete, insert and update operations will only issue a -shared lock on the table. An exclusive lock is still used when adding or removing columns, -when dropping the table, and when using SELECT ... FOR UPDATE. -Connections only 'see' committed data, and own changes. That means, if connection A updates -a row but doesn't commit this change yet, connection B will see the old value. -Only when the change is committed, the new value is visible by other connections -(read committed). If multiple connections concurrently try to update the same row, the -database waits until it can apply the change, but at most until the lock timeout expires. -

-

-To use the MVCC feature, append ;MVCC=TRUE to the database URL: -

-
-jdbc:h2:~/test;MVCC=TRUE
-
-

-MVCC is disabled by default. The MVCC feature is not fully tested yet. -The limitations of the MVCC mode are: it can not be used at the same time as -MULTI_THREADED=TRUE; -the complete undo log must fit in memory when using multi-version concurrency -(the setting MAX_MEMORY_UNDO has no effect). -It is not possible to enable or disable this setting while the database is already open. -The setting must be specified in the first connection (the one that opens the database). -

- -

Clustering / High Availability

-

-This database supports a simple clustering / high availability mechanism. The architecture is: -two database servers run on two different computers, and on both computers is a copy of the -same database. If both servers run, each database operation is executed on both computers. -If one server fails (power, hardware or network failure), the other server can still continue to work. -From this point on, the operations will be executed only on one server until the other server -is back up. -

-Clustering can only be used in the server mode (the embedded mode does not support clustering). -The cluster can be re-created using the CreateCluster tool without stopping -the remaining server. Applications that are still connected are automatically disconnected, -however when appending ;AUTO_RECONNECT=TRUE, they will recover from that. -

-To initialize the cluster, use the following steps: -

-
    -
  • Create a database -
  • Use the CreateCluster tool to copy the database to - another location and initialize the clustering. - Afterwards, you have two databases containing the same data. -
  • Start two servers (one for each copy of the database) -
  • You are now ready to connect to the databases with the client application(s) -
- -

Using the CreateCluster Tool

-

-To understand how clustering works, please try out the following example. -In this example, the two databases reside on the same computer, but usually, the -databases will be on different servers. -

-
    -
  • Create two directories: server1, server2. - Each directory will simulate a directory on a computer. -
  • Start a TCP server pointing to the first directory. - You can do this using the command line: -
    -java org.h2.tools.Server
    -    -tcp -tcpPort 9101
    -    -baseDir server1
    -
    -
  • Start a second TCP server pointing to the second directory. - This will simulate a server running on a second (redundant) computer. - You can do this using the command line: -
    -java org.h2.tools.Server
    -    -tcp -tcpPort 9102
    -    -baseDir server2
    -
    -
  • Use the CreateCluster tool to initialize clustering. - This will automatically create a new, empty database if it does not exist. - Run the tool on the command line: -
    -java org.h2.tools.CreateCluster
    -    -urlSource jdbc:h2:tcp://localhost:9101/~/test
    -    -urlTarget jdbc:h2:tcp://localhost:9102/~/test
    -    -user sa
    -    -serverList localhost:9101,localhost:9102
    -
    -
  • You can now connect to the databases using -an application or the H2 Console using the JDBC URL -jdbc:h2:tcp://localhost:9101,localhost:9102/~/test -
  • If you stop a server (by killing the process), -you will notice that the other machine continues to work, -and therefore the database is still accessible. -
  • To restore the cluster, you first need to delete the -database that failed, then restart the server that was stopped, -and re-run the CreateCluster tool. -
- -

Detect Which Cluster Instances are Running

-

-To find out which cluster nodes are currently running, execute the following SQL statement: -

-
-SELECT VALUE FROM INFORMATION_SCHEMA.SETTINGS WHERE NAME='CLUSTER'
-
-

-If the result is '' (two single quotes), then the cluster mode is disabled. Otherwise, the list of -servers is returned, enclosed in single quote. Example: 'server1:9191,server2:9191'. -

- -

Clustering Algorithm and Limitations

-

-Read-only queries are only executed against the first cluster node, but all other statements are -executed against all nodes. There is currently no load balancing made to avoid problems with -transactions. The following functions may yield different results on different cluster nodes and must be -executed with care: RANDOM_UUID(), SECURE_RAND(), SESSION_ID(), -MEMORY_FREE(), MEMORY_USED(), CSVREAD(), CSVWRITE(), RAND() [when not using a seed]. -Those functions should not be used directly in modifying statements -(for example INSERT, UPDATE, MERGE). However, they can be used -in read-only statements and the result can then be used for modifying statements. -

-

-When using the cluster modes, result sets are read fully in memory by the client, so that -there is no problem if the server dies that executed the query. Result sets must fit in memory -on the client side. -

- -

Two Phase Commit

-

-The two phase commit protocol is supported. 2-phase-commit works as follows: -

-
    -
  • Autocommit needs to be switched off -
  • A transaction is started, for example by inserting a row -
  • The transaction is marked 'prepared' by executing the SQL statement - PREPARE COMMIT transactionName -
  • The transaction can now be committed or rolled back -
  • If a problem occurs before the transaction was successfully committed or rolled back - (for example because a network problem occurred), the transaction is in the state 'in-doubt' -
  • When re-connecting to the database, the in-doubt transactions can be listed - with SELECT * FROM INFORMATION_SCHEMA.IN_DOUBT -
  • Each transaction in this list must now be committed or rolled back by executing - COMMIT TRANSACTION transactionName or - ROLLBACK TRANSACTION transactionName -
  • The database needs to be closed and re-opened to apply the changes -
- -

Compatibility

-

-This database is (up to a certain point) compatible to other databases such as HSQLDB, MySQL and PostgreSQL. -There are certain areas where H2 is incompatible. -

- -

Transaction Commit when Autocommit is On

-

-At this time, this database engine commits a transaction (if autocommit is switched on) just before returning the result. -For a query, this means the transaction is committed even before the application scans through the result set, and before the result set is closed. -Other database engines may commit the transaction in this case when the result set is closed. -

- -

Keywords / Reserved Words

-

-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: -

- -CROSS, CURRENT_DATE, CURRENT_TIME, CURRENT_TIMESTAMP, DISTINCT, EXCEPT, EXISTS, FALSE, -FOR, FROM, FULL, GROUP, HAVING, INNER, INTERSECT, IS, JOIN, LIKE, LIMIT, MINUS, NATURAL, NOT, NULL, -ON, ORDER, PRIMARY, ROWNUM, SELECT, SYSDATE, SYSTIME, SYSTIMESTAMP, TODAY, TRUE, UNION, -UNIQUE, WHERE - -

-Certain words of this list are keywords because they are functions that can be used without '()' for compatibility, -for example CURRENT_TIMESTAMP. -

- -

Standards Compliance

-

-This database tries to be as much standard compliant as possible. For the SQL language, ANSI/ISO is the main -standard. There are several versions that refer to the release date: SQL-92, SQL:1999, and SQL:2003. -Unfortunately, the standard documentation is not freely available. Another problem is that important features -are not standardized. Whenever this is the case, this database tries to be compatible to other databases. -

- -

Run as Windows Service

-

-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. -is included in the installation. Batch files are provided to install, start, stop and uninstall the -H2 Database Engine Service. This service contains the TCP Server and the H2 Console web application. -The batch files are located in the directory h2/service. -

- -

Install the Service

-

-The service needs to be registered as a Windows Service first. -To do that, double click on 1_install_service.bat. -If successful, a command prompt window will pop up and disappear immediately. If not, a message will appear. -

- -

Start the Service

-

-You can start the H2 Database Engine Service using the service manager of Windows, -or by double clicking on 2_start_service.bat. -Please note that the batch file does not print an error message if the service is not installed. -

- -

Connect to the H2 Console

-

-After installing and starting the service, you can connect to the H2 Console application using a browser. -Double clicking on 3_start_browser.bat to do that. The -default port (8082) is hard coded in the batch file. -

- -

Stop the Service

-

-To stop the service, double click on 4_stop_service.bat. -Please note that the batch file does not print an error message if the service is not installed or started. -

- -

Uninstall the Service

-

-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. -

- -

ODBC Driver

-

-This database does not come with its own ODBC driver at this time, -but it supports the PostgreSQL network protocol. -Therefore, the PostgreSQL ODBC driver can be used. -Support for the PostgreSQL network protocol is quite new and should be viewed -as experimental. It should not be used for production applications. -

-

-To use the PostgreSQL ODBC driver on 64 bit versions of Windows, -first run c:/windows/syswow64/odbcad32.exe. -At this point you set up your DSN just like you would on any other system. -See also: -Re: ODBC Driver on Windows 64 bit -

- -

ODBC Installation

-

-First, the ODBC driver must be installed. -Any recent PostgreSQL ODBC driver should work, however version 8.2 (psqlodbc-08_02*) or newer is recommended. -The Windows version of the PostgreSQL ODBC driver is available at -http://www.postgresql.org/ftp/odbc/versions/msi. -

- -

Starting the Server

-

-After installing the ODBC driver, start the H2 Server using the command line: -

-
-java -cp h2*.jar org.h2.tools.Server
-
-

-The PG Server (PG for PostgreSQL protocol) is started as well. -By default, databases are stored in the current working directory where the server is started. -Use -baseDir to save databases in another directory, for example the user home directory: -

-
-java -cp h2*.jar org.h2.tools.Server -baseDir ~
-
-

-The PG server can be started and stopped from within a Java application as follows: -

-
-Server server = Server.createPgServer("-baseDir", "~");
-server.start();
-...
-server.stop();
-
-

-By default, only connections from localhost are allowed. To allow remote connections, use --pgAllowOthers when starting the server. -

- -

ODBC Configuration

-

-After installing the driver, a new Data Source must be added. In Windows, -run odbcad32.exe to open the Data Source Administrator. Then click on 'Add...' -and select the PostgreSQL Unicode driver. Then click 'Finish'. -You will be able to change the connection properties: -

- - - - - - - - - - -
PropertyExampleRemarks
Data SourceH2 TestThe name of the ODBC Data Source
Databasetest - The database name. Only simple names are supported at this time;
- relative or absolute path are not supported in the database name.
- By default, the database is stored in the current working directory
- where the Server is started except when the -baseDir setting is used.
- The name must be at least 3 characters. -
ServerlocalhostThe server name or IP address.
By default, only remote connections are allowed
User NamesaThe database user name.
SSL ModedisabledAt this time, SSL is not supported.
Port5435The port where the PG Server is listening.
PasswordsaThe database password.
-

-To improve performance, please enable 'server side prepare' under Options / Datasource / Page 2 / Server side prepare. -

-

-Afterwards, you may use this data source. -

- -

PG Protocol Support Limitations

-

-At this time, only a subset of the PostgreSQL network protocol is implemented. -Also, there may be compatibility problems on the SQL level, with the catalog, or with text encoding. -Problems are fixed as they are found. -Currently, statements can not be canceled when using the PG protocol. -

-

-PostgreSQL ODBC Driver Setup requires a database password; that means it -is not possible to connect to H2 databases without password. This is a limitation -of the ODBC driver. -

- -

Security Considerations

-

-Currently, the PG Server does not support challenge response or encrypt passwords. -This may be a problem if an attacker can listen to the data transferred between the ODBC driver -and the server, because the password is readable to the attacker. -Also, it is currently not possible to use encrypted SSL connections. -Therefore the ODBC driver should not be used where security is important. -

- -

Using H2 in Microsoft .NET

-

-The database can be used from Microsoft .NET even without using Java, by using IKVM.NET. -You can access a H2 database on .NET using the JDBC API, or using the ADO.NET interface. -

- -

Using the ADO.NET API on .NET

-

-An implementation of the ADO.NET interface is available in the open source project -H2Sharp. -

- -

Using the JDBC API on .NET

-
  • Install the .NET Framework from Microsoft. - Mono has not yet been tested. -
  • Install IKVM.NET. -
  • Copy the h2*.jar file to ikvm/bin -
  • Run the H2 Console using: - ikvm -jar h2*.jar -
  • Convert the H2 Console to an .exe file using: - ikvmc -target:winexe h2*.jar. - You may ignore the warnings. -
  • Create a .dll file using (change the version accordingly): - ikvmc.exe -target:library -version:1.0.69.0 h2*.jar -
-

-If you want your C# application use H2, you need to add the h2.dll and the -IKVM.OpenJDK.ClassLibrary.dll to your C# solution. Here some sample code: -

-
-using System;
-using java.sql;
-
-class Test
-{
-    static public void Main()
-    {
-        org.h2.Driver.load();
-        Connection conn = DriverManager.getConnection("jdbc:h2:~/test", "sa", "sa");
-        Statement stat = conn.createStatement();
-        ResultSet rs = stat.executeQuery("SELECT 'Hello World'");
-        while (rs.next())
-        {
-            Console.WriteLine(rs.getString(1));
-        }
-    }
-}
-
- -

ACID

-

-In the database world, ACID stands for: -

-
    -
  • Atomicity: transactions must be atomic, meaning either all tasks are performed or none. -
  • Consistency: all operations must comply with the defined constraints. -
  • Isolation: transactions must be isolated from each other. -
  • Durability: committed transaction will not be lost. -
- -

Atomicity

-

-Transactions in this database are always atomic. -

- -

Consistency

-

-By default, this database is always in a consistent state. -Referential integrity rules are enforced except when -explicitly disabled. -

- -

Isolation

-

-For H2, as with most other database systems, the default isolation level is 'read committed'. -This provides better performance, but also means that transactions are not completely isolated. -H2 supports the transaction isolation levels 'serializable', 'read committed', and 'read uncommitted'. -

- -

Durability

-

-This database does not guarantee that all committed transactions survive a power failure. -Tests show that all databases sometimes lose transactions on power failure (for details, see below). -Where losing transactions is not acceptable, a laptop or UPS (uninterruptible power supply) should be used. -If durability is required for all possible cases of hardware failure, clustering should be used, -such as the H2 clustering mode. -

- -

Durability Problems

-

-Complete durability means all committed transaction survive a power failure. -Some databases claim they can guarantee durability, but such claims are wrong. -A durability test was run against H2, HSQLDB, PostgreSQL, and Derby. -All of those databases sometimes lose committed transactions. -The test is included in the H2 download, see org.h2.test.poweroff.Test. -

- -

Ways to (Not) Achieve Durability

-

-Making sure that committed transactions are not lost is more complicated than it seems first. -To guarantee complete durability, a database must ensure that the log record is on the hard drive -before the commit call returns. To do that, databases use different methods. One -is to use the 'synchronous write' file access mode. In Java, RandomAccessFile -supports the modes rws and rwd: -

-
    -
  • rwd: every update to the file's content is written synchronously to the underlying storage device. -
  • rws: in addition to rwd, every update to the metadata is written synchronously.
  • -
-

-A test (org.h2.test.poweroff.TestWrite) with one of those modes achieves -around 50 thousand write operations per second. -Even when the operating system write buffer is disabled, the write rate is around 50 thousand operations per second. -This feature does not force changes to disk because it does not flush all buffers. -The test updates the same byte in the file again and again. If the hard drive was able to write at this rate, -then the disk would need to make at least 50 thousand revolutions per second, or 3 million RPM -(revolutions per minute). There are no such hard drives. The hard drive used for the test is about 7200 RPM, -or about 120 revolutions per second. There is an overhead, so the maximum write rate must be lower than that. -

-

-Calling fsync flushes the buffers. There are two ways to do that in Java: -

-
    -
  • FileDescriptor.sync(). The documentation says that this forces all system -buffers to synchronize with the underlying device. -This method is supposed to return after all in-memory modified copies of buffers associated with this file descriptor -have been written to the physical medium. -
  • FileChannel.force() (since JDK 1.4). This method is supposed -to force any updates to this channel's file to be written to the storage device that contains it. -
-

-By default, MySQL calls fsync for each commit. When using one of those methods, only around 60 write operations -per second can be achieved, which is consistent with the RPM rate of the hard drive used. -Unfortunately, even when calling FileDescriptor.sync() or -FileChannel.force(), -data is not always persisted to the hard drive, because most hard drives do not obey -fsync(): see -Your Hard Drive Lies to You. -In Mac OS X, fsync does not flush hard drive buffers. See -Bad fsync?. -So the situation is confusing, and tests prove there is a problem. -

-

-Trying to flush hard drive buffers is hard, and if you do the performance is very bad. -First you need to make sure that the hard drive actually flushes all buffers. -Tests show that this can not be done in a reliable way. -Then the maximum number of transactions is around 60 per second. -Because of those reasons, the default behavior of H2 is to delay writing committed transactions. -

-

-In H2, after a power failure, a bit more than one second of committed transactions may be lost. -To change the behavior, use SET WRITE_DELAY and -CHECKPOINT SYNC. -Most other databases support commit delay as well. -In the performance comparison, commit delay was used for all databases that support it. -

- -

Running the Durability Test

-

-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. -One computer just listens, while the test application is run (and power is cut) on the other computer. -The computer with the listener application opens a TCP/IP port and listens for an incoming connection. -The second computer first connects to the listener, and then created the databases and starts inserting -records. The connection is set to 'autocommit', which means after each inserted record a commit is performed -automatically. Afterwards, the test computer notifies the listener that this record was inserted successfully. -The listener computer displays the last inserted record number every 10 seconds. Now, switch off the power -manually, then restart the computer, and run the application again. You will find out that in most cases, -none of the databases contains all the records that the listener computer knows about. For details, please -consult the source code of the listener and test application. -

- -

Using the Recover Tool

-

-The Recover tool can be used to extract the contents of a database file, even if the database is corrupted. -It also extracts the content of the transaction log and large objects (CLOB or BLOB). -To run the tool, type on the command line: -

-
-java -cp h2*.jar org.h2.tools.Recover
-
-

-For each database in the current directory, a text file will be created. -This file contains raw insert statements (for the data) and data definition (DDL) statements to recreate -the schema of the database. This file can be executed using the RunScript tool or a -RUNSCRIPT FROM SQL statement. The script includes at least one -CREATE USER statement. If you run the script against a database that was created with the same -user, or if there are conflicting users, running the script will fail. Consider running the script -against a database that was created with a user name that is not in the script. -

-

-The Recover tool creates a SQL script from database file. It also processes the transaction log. -

- -

File Locking Protocols

-

-Multiple concurrent connections to the same database are supported, however a database file -can only be open for reading and writing (in embedded mode) by one process at the same time. -Otherwise, the processes would overwrite each others data and corrupt the database file. -To protect against this problem, whenever a database is opened, a lock file is created -to signal other processes that the database is in use. If the database is closed, or if the process that opened -the database stops normally, this lock file is deleted. -

-In special cases (if the process did not terminate normally, for example because -there was a power failure), 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. -However, this software uses a challenge-response protocol to protect the database -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'. -

-

-The file locking protocols have the following limitation: if a shared file system is used, -and the machine with the lock owner is sent to sleep (standby or hibernate), -another machine may take over. If the machine that originally held the lock -wakes up, the database may become corrupt. If this situation can occur, -the application must ensure the database is closed when the application -is put to sleep. -

- -

File Locking Method 'File'

-

-The default method for database file locking is the 'File Method'. The algorithm is: -

-
    -
  • If the lock file does not exist, it is created (using the atomic operation -File.createNewFile). -Then, the process waits a little bit (20 ms) and checks the file again. If the file was changed -during this time, the operation is aborted. This protects against a race condition -when one process deletes the lock file just after another one create it, and a third process creates -the file again. It does not occur if there are only two writers. -
  • -If the file can be created, a random number is inserted together with the locking method -('file'). Afterwards, a watchdog thread is started that -checks regularly (every second once by default) if the file was deleted or modified by -another (challenger) thread / process. Whenever that occurs, the file is overwritten with the -old data. The watchdog thread runs with high priority so that a change to the lock file does -not get through undetected even if the system is very busy. However, the watchdog thread -does use very little resources (CPU time), because it waits most of the time. Also, the watchdog only reads from the hard disk -and does not write to it. -
  • -If the lock file exists and was recently modified, the process waits for some time (up to two seconds). -If it was still changed, an exception is thrown (database is locked). This is done to eliminate race conditions with many concurrent -writers. Afterwards, the file is overwritten with a new version (challenge). -After that, the thread waits for 2 seconds. -If there is a watchdog thread protecting the file, he will overwrite the change -and this process will fail to lock the database. -However, if there is no watchdog thread, the lock file will still be as written by -this thread. In this case, the file is deleted and atomically created again. -The watchdog thread is started in this case and the file is locked. -
-

-This algorithm is tested with over 100 concurrent threads. In some cases, when there are -many concurrent threads trying to lock the database, they block each other (meaning -the file cannot be locked by any of them) for some time. However, the file never gets -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. -

- -

File Locking Method 'Socket'

-

-There is a second locking mechanism implemented, but disabled by default. -To use it, append ;FILE_LOCK=SOCKET to the database URL. -The algorithm is: -

-
    -
  • If the lock file does not exist, it is created. -Then a server socket is opened on a defined port, and kept open. -The port and IP address of the process that opened the database is written -into the lock file. -
  • If the lock file exists, and the lock method is 'file', then the software switches -to the 'file' method. -
  • If the lock file exists, and the lock method is 'socket', then the process -checks if the port is in use. If the original process is still running, the port is in use -and this process throws an exception (database is in use). If the original process -died (for example due to a power failure, or abnormal termination of the virtual machine), -then the port was released. The new process deletes the lock file and starts again. -
-

-This method does not require a watchdog thread actively polling (reading) the same -file every second. The problem with this method is, if the file is stored on a network -share, two processes (running on different computers) could still open the same -database files, if they do not have a direct TCP/IP connection. -

- -

File Locking Method 'Serialized'

-

-This locking mode allows to open multiple connections to the same database. -The connections may be opened from multiple processes and from different computers. -When writing to the database, access is automatically synchronized internally. Write operations -are slower than when using the server mode, and concurrency is relatively poor. -The advantage of this mode is that there is no need to start a server. -

-

-To enable this feature, append ;FILE_LOCK=SERIALIZED to the database URL. -

-

-This feature is relatively new. When using it for production, please ensure -your use case is well tested (if possible with automated test cases). -

- -

Protection against SQL Injection

-

What is SQL Injection

-

-This database engine provides a solution for the security vulnerability known as 'SQL Injection'. -Here is a short description of what SQL injection means. -Some applications build SQL statements with embedded user input such as: -

-
-String sql = "SELECT * FROM USERS WHERE PASSWORD='"+pwd+"'";
-ResultSet rs = conn.createStatement().executeQuery(sql);
-
-

-If this mechanism is used anywhere in the application, and user input is not correctly filtered or encoded, -it is possible for a user to inject SQL functionality or statements by using specially built input -such as (in this example) this password: ' OR ''='. -In this case the statement becomes: -

-
-SELECT * FROM USERS WHERE PASSWORD='' OR ''='';
-
-

-Which is always true no matter what the password stored in the database is. -For more information about SQL Injection, see Glossary and Links. -

- -

Disabling Literals

-

-SQL Injection is not possible if user input is not directly embedded in SQL statements. -A simple solution for the problem above is to use a prepared statement: -

-
-String sql = "SELECT * FROM USERS WHERE PASSWORD=?";
-PreparedStatement prep = conn.prepareStatement(sql);
-prep.setString(1, pwd);
-ResultSet rs = prep.executeQuery();
-
-

-This database provides a way to enforce usage of parameters when passing user input -to the database. This is done by disabling embedded literals in SQL statements. -To do this, execute the statement: -

-
-SET ALLOW_LITERALS NONE;
-
-

-Afterwards, SQL statements with text and number literals are not allowed any more. -That means, SQL statement of the form WHERE NAME='abc' -or WHERE CustomerId=10 will fail. -It is still possible to use prepared statements and parameters as described above. Also, it is still possible to generate -SQL statements dynamically, and use the Statement API, as long as the SQL statements -do not include literals. -There is also a second mode where number literals are allowed: -SET ALLOW_LITERALS NUMBERS. -To allow all literals, execute SET ALLOW_LITERALS ALL -(this is the default setting). Literals can only be enabled or disabled by an administrator. -

- -

Using Constants

-

-Disabling literals also means disabling hard-coded 'constant' literals. This database supports -defining constants using the CREATE CONSTANT command. -Constants can be defined only -when literals are enabled, but used even when literals are disabled. To avoid name clashes -with column names, constants can be defined in other schemas: -

-
-CREATE SCHEMA CONST AUTHORIZATION SA;
-CREATE CONSTANT CONST.ACTIVE VALUE 'Active';
-CREATE CONSTANT CONST.INACTIVE VALUE 'Inactive';
-SELECT * FROM USERS WHERE TYPE=CONST.ACTIVE;
-
-

-Even when literals are enabled, it is better to use constants instead -of hard-coded number or text literals in queries or views. With constants, typos are found at compile -time, the source code is easier to understand and change. -

- -

Using the ZERO() Function

-

-It is not required to create a constant for the number 0 as there is already a built-in function ZERO(): -

-
-SELECT * FROM USERS WHERE LENGTH(PASSWORD)=ZERO();
-
- -

Protection against Remote Access

-

-By default this database does not allow connections from other machines when starting the H2 Console, -the TCP server, or the PG server. Remote access can be enabled using the command line -options -webAllowOthers, -tcpAllowOthers, -pgAllowOthers. -If you enable remote access, please also consider using the options --baseDir, -ifExists, so that remote -users can not create new databases or access existing databases with weak passwords. -When using the option -baseDir, only databases within that directory may be accessed. -Ensure the existing accessible databases are protected using strong passwords. -

- -

Restricting Class Loading and Usage

-

-By default there is no restriction on loading classes and executing Java code for admins. -That means an admin may call system functions such as -System.setProperty by executing: -

-
-CREATE ALIAS SET_PROPERTY FOR "java.lang.System.setProperty";
-CALL SET_PROPERTY('abc', '1');
-CREATE ALIAS GET_PROPERTY FOR "java.lang.System.getProperty";
-CALL GET_PROPERTY('abc');
-
-

-To restrict users (including admins) from loading classes and executing code, -the list of allowed classes can be set in the system property -h2.allowedClasses -in the form of a comma separated list of classes or patterns (items ending with *). -By default all classes are allowed. Example: -

-
-java -Dh2.allowedClasses=java.lang.Math,com.acme.*
-
-

-This mechanism is used for all user classes, including database event listeners, -trigger classes, user-defined functions, user-defined aggregate functions, and JDBC -driver classes (with the exception of the H2 driver) when using the H2 Console. -

- -

Security Protocols

-

-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. -

- -

User Password Encryption

-

-When a user tries to connect to a database, the combination of -user name, @, and password are hashed using SHA-256, and this hash value -is transmitted to the database. -This step does not protect against an attacker that re-uses the value if he is able to listen to the -(unencrypted) transmission between the client and the server. -But, the passwords are never transmitted as plain text, -even when using an unencrypted connection between client and server. -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. -

-When a new database or user is created, a new random salt value is generated. -The size of the salt is 64 bits. Using the random salt reduces the risk of an -attacker pre-calculating hash values for many different (commonly used) passwords. -

-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 -user-password hash value with the stored salt value and calculates the -hash value. Other products use multiple iterations (hash the hash value again and again), -but this is not done in this product to reduce the risk of denial of service attacks -(where the attacker tries to connect with bogus passwords, and the server -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 accessible remotely, -then the iteration count is not required at all. -

- -

File Encryption

-

-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. -

-When a user tries to connect to an encrypted database, the combination of -file@ and the file password is hashed using SHA-256. This hash value is -transmitted to the server. -

-When a new database file is created, a new cryptographically secure -random salt value is generated. The size of the salt is 64 bits. -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. -

-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. -

-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. -

-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. -

-Therefore, the block cipher mode 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. -

-Database encryption is meant for securing the database while it is not in use (stolen laptop and so on). -It is not meant for cases where the attacker has access to files while the database is in use. -When he has write access, he can for example replace pieces of files with pieces of older versions -and manipulate data like this. -

-File encryption slows down the performance of the database engine. Compared to unencrypted mode, -database operations take about 2.2 times longer when using XTEA, and 2.5 times longer using AES (embedded mode). -

- -

Wrong Password / User Name Delay

-

-To protect against remote brute force password attacks, the delay after each unsuccessful -login gets double as long. Use the system properties h2.delayWrongPasswordMin -and h2.delayWrongPasswordMax to change the minimum (the default is 250 milliseconds) -or maximum delay (the default is 4000 milliseconds, or 4 seconds). The delay only -applies for those using the wrong password. Normally there is no delay for a user that knows the correct -password, with one exception: after using the wrong password, there is a delay of up to (randomly distributed) -the same delay as for a wrong password. This is to protect against parallel brute force attacks, -so that an attacker needs to wait for the whole delay. Delays are synchronized. This is also required -to protect against parallel attacks. -

-

-There is only one exception message for both wrong user and for wrong password, -to make it harder to get the list of user names. It is not possible from the stack trace to see -if the user name was wrong or the password. -

- -

HTTPS Connections

-

-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. -

- -

SSL/TLS Connections

-

-Remote SSL/TLS connections are supported using the Java Secure Socket Extension -(SSLServerSocket, SSLSocket). By default, anonymous SSL is enabled. -The default cipher suite is SSL_DH_anon_WITH_RC4_128_MD5. -

-

-To use your own keystore, set the system properties javax.net.ssl.keyStore and -javax.net.ssl.keyStorePassword before starting the H2 server and client. -See also -Customizing the Default Key and Trust Stores, Store Types, and Store Passwords -for more information. -

-

-To disable anonymous SSL, set the system property h2.enableAnonymousSSL to false. -

- -

Universally Unique Identifiers (UUID)

-

-This database supports UUIDs. Also supported is a function to create new UUIDs using -a cryptographically strong pseudo random number generator. -With random UUIDs, the chance of two having the same value can be calculated -using the probability theory. See also 'Birthday Paradox'. -Standardized randomly generated UUIDs have 122 random bits. -4 bits are used for the version (Randomly generated UUID), and 2 bits for the variant (Leach-Salz). -This database supports generating such UUIDs using the built-in function -RANDOM_UUID(). -Here is a small program to estimate the probability of having two identical UUIDs -after generating a number of values: -

-
-public class Test {
-    public static void main(String[] args) throws Exception {
-        double x = Math.pow(2, 122);
-        for (int i = 35; i < 62; i++) {
-            double n = Math.pow(2, i);
-            double p = 1 - Math.exp(-(n * n) / 2 / x);
-            System.out.println("2^" + i + "=" + (1L << i) +
-                    " probability: 0" +
-                    String.valueOf(1 + p).substring(1));
-        }
-    }
-}
-
-

-Some values are: -

- - - - - -
Number of UUIsProbability of Duplicates
2^36=68'719'476'7360.000'000'000'000'000'4
2^41=2'199'023'255'5520.000'000'000'000'4
2^46=70'368'744'177'6640.000'000'000'4
-

-To help non-mathematicians understand what those numbers mean, here a comparison: -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. -

- -

Settings Read from System Properties

-

-Some settings of the database can be set on the command line using --DpropertyName=value. It is usually not required to change those settings manually. -The settings are case sensitive. -Example: -

-
-java -Dh2.serverCachedObjects=256 org.h2.tools.Server
-
-

-The current value of the settings can be read in the table -INFORMATION_SCHEMA.SETTINGS. -

-

-For a complete list of settings, see -SysProperties. -

- -

Setting the Server Bind Address

-

-Usually server sockets accept connections on any/all local addresses. -This may be a problem on multi-homed hosts. -To bind only to one address, use the system property h2.bindAddress. -This setting is used for both regular server sockets and for SSL server sockets. -IPv4 and IPv6 address formats are supported. -

- -

Pluggable File System

-

-This database supports a pluggable file system API. The file system implementation -is selected using a file name prefix. The following file systems are included: -

-
  • zip: read-only zip-file based file system. Format: zip:/zipFileName!/fileName. -
  • nio: file system that uses FileChannel instead of RandomAccessFile (faster in some operating systems). -
  • nioMapped: file system that uses memory mapped files (faster in some operating systems). -
  • split: file system that splits files in 1 GB files (stackable with other file systems). -
  • memFS: in-memory file system (slower than mem; experimental; mainly used for testing the database engine itself). -
  • memLZF: compressing in-memory file system (slower than memFS but uses less memory; experimental; mainly used for testing the database engine itself). -
-

-As an example, to use the the nio file system, use the following database URL: -jdbc:h2:nio:~/test. -

-

-To register a new file system, extend the classes org.h2.store.fs.FileSystem, FileObject, -and call the method FileSystem.register before using it. -

- -

Limits and Limitations

-

-This database has the following known limitations: -

-
    -
  • Database file size limits (excluding BLOB and CLOB data): - With the default storage mechanism, the maximum file size is currently 256 GB for the data, and 256 GB for the index. - With the page store (experimental): 4 TB or higher. -
  • BLOB and CLOB size limit: every CLOB or BLOB can be up to 256 GB. -
  • The maximum file size for FAT or FAT32 file systems is 4 GB. That means when using FAT or FAT32, -the limit is 4 GB for the data. This is the limitation of the file system. The database does provide a -workaround for this problem, it is to use the file name prefix split:. In that case files are split into -files of 1 GB by default. An example database URL is: -jdbc:h2:split:~/test. -
  • The maximum number of rows per table is 2'147'483'648. -
  • Main memory requirements: The larger the database, the more main memory is required. - With the default storage mechanism, the minimum main memory required for a 12 GB database is around 240 MB. - With the page store (experimental), the minimum main memory required is much lower, around 1 MB for each 8 GB database file size. -
  • Limit on the complexity of SQL statements. -Statements of the following form will result in a stack overflow exception: -
    -SELECT * FROM DUAL WHERE X = 1
    -OR X = 2 OR X = 2 OR X = 2 OR X = 2 OR X = 2
    --- repeat previous line 500 times --
    -
    -
  • There is no limit for the following entities, except the memory and storage capacity: - maximum identifier length (table name, column name, and so on); - maximum number of tables, columns, indexes, triggers, and other database objects; - maximum statement length, number of parameters per statement, tables per statement, expressions - in order by, group by, having, and so on; - maximum rows per query; - maximum columns per table, columns per index, indexes per table, lob columns per table, and so on; - maximum row length, index row length, select row length; - maximum length of a varchar column, decimal column, literal in a statement. -
  • For limitations on data types, see the documentation of the respective Java data type - or the data type documentation of this database. -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
TermDescription
AES-128A block encryption algorithm. See also: Wikipedia: - AES
Birthday ParadoxDescribes the higher than expected probability that two - persons in a room have the same birthday. Also valid for randomly - generated UUIDs. See also: Wikipedia: - Birthday Paradox
DigestProtocol to protect a password (but not to protect data). - See also: RFC - 2617: HTTP Digest Access Authentication
GCJCompiler for Java. GNU - Compiler for the Java and NativeJ - (commercial)
HTTPSA protocol to provide security to HTTP connections. See - also: RFC 2818: - HTTP Over TLS
Modes of OperationWikipedia: - Block cipher modes of operation
SaltRandom number to increase the security of passwords. See - also: Wikipedia: - Key derivation function
SHA-256A cryptographic one-way hash function. See also: Wikipedia: SHA - hash functions
SQL InjectionA security vulnerability where an application embeds SQL - statements or expressions in user input. See also: Wikipedia: - SQL Injection
Watermark AttackSecurity problem of certain encryption programs where the - existence of certain data can be proven without decrypting. For more - information, search in the internet for 'watermark attack - cryptoloop'
SSL/TLSSecure Sockets Layer / Transport Layer Security. See also: - Java Secure Socket - Extension (JSSE)
XTEAA block encryption algorithm. See also: Wikipedia: XTEA
- -
diff --git a/tools/h2/src/docsrc/html/build.html b/tools/h2/src/docsrc/html/build.html deleted file mode 100755 index adb3a4d..0000000 --- a/tools/h2/src/docsrc/html/build.html +++ /dev/null @@ -1,292 +0,0 @@ - - - - -Build - - - - -
- - -

Build

- - Portability
- - Environment
- - Building the Software
- - Build Targets
- - Using Maven 2
- - Translating
- - Providing Patches
- - Reporting Problems or Requests
- - Automated Build
- - Generating Railroad Diagrams
- -

Portability

-

-This database is written in Java and therefore works on many platforms. -It can also be compiled to a native executable using GCJ. -

-

-For Java 1.4, the jar file needs to be converted first using -Retrotranslator. -

- -

Environment

-

-To run this database, a Java Runtime Environment (JRE) version 1.5 or higher is required. -

-

-To create the database executables, the following software stack was used. -To use this database, it is not required to install this software however. -

- - -

Building the Software

-

-You need to install a JDK, for example the Sun JDK version 1.5 or 1.6. -Ensure that Java binary directory is included in the PATH environment variable, and that -the environment variable JAVA_HOME points to your Java installation. -On the command line, go to the directory h2 and execute the following command: -

-
-build -?
-
-

-For Linux and OS X, use ./build.sh instead of build. -

-

-You will get a list of targets. If you want to build the jar file, execute (Windows): -

-
-build jar
-
- -

Switching the Source Code

-

-By default the source code uses Java 1.5 features, however Java 1.6 is supported as well. -To switch the source code to the installed version of Java, run: -

-
-build switchSource
-
- -

Build Targets

-

-The build system can generate smaller jar files as well. The following targets are currently supported: -

-
  • jarClient - creates the file h2client.jar. This only contains the JDBC client. -
  • jarSmall - creates the file h2small.jar. - This only contains the embedded database. Debug information is disabled. -
  • jarJaqu - creates the file h2jaqu.jar. - This only contains the JaQu (Java Query) implementation. All other jar files do not include JaQu. -
  • javadocImpl creates the Javadocs of the implementation. -
-

-To create the file h2client.jar, go to the directory h2 and execute the following command: -

-
-build jarClient
-
- -

Using Maven 2

-

Using a Central Repository

-

-You can include the database in your Maven 2 project as a dependency. -Example: -

-
-<dependency>
-    <groupId>com.h2database</groupId>
-    <artifactId>h2</artifactId>
-    <version>${version}</version>
-</dependency>
-
-

-New versions of this database are first uploaded to http://hsql.sourceforge.net/m2-repo/ and then automatically -synchronized with the main Maven repository; however after a new release it may take a few hours before -they are available there. -

- -

Using Snapshot Version

-

-To build a h2-*-SNAPSHOT.jar file and upload it the to the local Maven 2 repository, execute the following command: -

-
-build mavenInstallLocal
-
-

-Afterwards, you can include the database in your Maven 2 project as a dependency: -

-
-<dependency>
-    <groupId>com.h2database</groupId>
-    <artifactId>h2</artifactId>
-    <version>1.0-SNAPSHOT</version>
-</dependency>
-
- -

Translating

-

-The translation of this software is split into the following parts: -

-
    -
  • H2 Console: src/main/org/h2/server/web/res/_text_*.prop -
  • Error messages: src/main/org/h2/res/_messages_*.prop -
-

-To translate the H2 Console, start it and select Preferences / Translate. -After you are done, send the translated *.prop file to the Google Group. -The web site is currently translated using Google. -

- -

Providing Patches

-

-If you like to provide patches, please consider the following guidelines to simplify merging them: -

-
  • Only use Java 1.5 features (do not use Java 1.6) (see Environment). -
  • Follow the coding style used in the project, and use Checkstyle (see above) to verify. - For example, do not use tabs (use spaces instead). - The checkstyle configuration is in src/installer/checkstyle.xml. -
  • A template of the Eclipse settings are in - src/installer/eclipse.settings/*. If you want to use them, - you need to copy them to the .settings directory. - The formatting options (eclipseCodeStyle) are also included. -
  • Please provide test cases and integrate them into the test suite. - For Java level tests, see src/test/org/h2/test/TestAll.java. - For SQL level tests, see src/test/org/h2/test/test.in.txt or - testSimple.in.txt. -
  • The test cases should cover at least 90% of the changed and new code; - use a code coverage tool to verify that (see above). - or use the build target coverage. -
  • Verify that you did not break other features: run the test cases by executing - build test. -
  • Provide end user documentation if required (src/docsrc/html/*). -
  • Document grammar changes in src/docsrc/help/help.csv -
  • Provide a change log entry (src/docsrc/html/changelog.html). -
  • Verify the spelling using build spellcheck. If required - add the new words to src/tools/org/h2/build/doc/dictionary.txt. -
  • Run src/installer/buildRelease to find and fix formatting errors. -
  • Verify the formatting using build docs and - build javadoc. -
  • Submit patches as .patch files (compressed if big). - To create a patch using Eclipse, use Team / Create Patch. -
-

-For legal reasons, patches need to be public in the form of an email to the -group, or in the form -of an issue report or attachment. -Significant contributions need to include the following statement: -

-

-"I wrote the code, it's mine, and I'm contributing it to H2 for distribution -multiple-licensed under the H2 License, version 1.0, and under the -Eclipse Public License, version 1.0 (http://h2database.com/html/license.html)." -

- -

Reporting Problems or Requests

-

-Please consider the following checklist if you have a question, want to report a problem, -or if you have a feature request: -

-
  • Feature requests are always welcome, even if the feature is already on the - roadmap. Your mail will help prioritize feature requests. - If you urgently need a feature, consider providing a patch. -
  • Before posting problems, check the - FAQ and do a Google search. -
  • When got an unexpected exception, please try the - Error Analyzer tool. If this doesn't help, - please report the problem, including the complete error message and stack trace, - and the root cause stack trace(s). -
  • When sending source code, please use a public web clipboard such as - Pastebin, - Cl1p, or - Mystic Paste - to avoid formatting problems. - Please keep test cases as simple and short as possible, - but so that the problem can still be reproduced. - As a template, use: - HelloWorld.java. - Method that simply call other methods should be avoided, - as well as unnecessary exception handling. - Please use the JDBC API and no external tools or libraries. - The test should include all required initialization code, and - should be started with the main method. -
  • For large attachments, use a public temporary storage such as - Rapidshare. -
  • Google Group versus issue tracking: - Use the - Google Group - for questions or if you are not sure it's a bug. - If you are sure it's a bug, you can create an - issue, - but you don't need to (sending an email to the group is enough). - Please note that only few people monitor the issue tracking system. -
  • For out-of-memory problems, please analyze the problem yourself first, - for example using the command line option - -XX:+HeapDumpOnOutOfMemoryError - and a memory analysis tool such as the - Eclipse Memory Analyzer (MAT). -
  • It may take a few days to get an answers. Please do not double post. -
- -

Automated Build

-

-This build process is automated and runs regularly. -The build process includes running the tests and code coverage, using the command line -./build.sh clean jar coverage -Dh2.ftpPassword=... uploadBuild. -The last results are available here: -

- - -

Generating Railroad Diagrams

-

-The railroad diagrams are HTML, formatted as nested tables. -The diagrams are generated as follows: -

-
  • The BNF parser (org.h2.bnf.Bnf) reads and parses the BNF from the file help.csv. -
  • The page parser (org.h2.server.web.PageParser) reads the template HTML file and fills in the diagrams. -
  • The rail images (one straight, four junctions, two turns) are generated using a simple Java application. -
-

-To generate railroad diagrams for other grammars, see the package org.h2.jcr. -This package is used to generate the SQL-2 railroad diagrams for the JCR 2.0 specification. -

- -
- diff --git a/tools/h2/src/docsrc/html/changelog.html b/tools/h2/src/docsrc/html/changelog.html deleted file mode 100755 index 1eb2c46..0000000 --- a/tools/h2/src/docsrc/html/changelog.html +++ /dev/null @@ -1,698 +0,0 @@ - - - - -Change Log - - - - -
- - -

Change Log

- -

Next Version (unreleased)

-
  • - -
- -

Version 1.2.137 (2010-06-06)

-
  • Statements with a nested query and a condition that was always NULL threw an - IndexOutOfBoundsException. Example: select * from (select null as x) where x=1 -
  • Experimental feature to support very large transactions (except when using MVCC). - To enable, set the system property h2.largeTransactions to true. - If enabled, changes to tables without a primary key can be buffered to disk. - The plan is to enable this feature by default in version 1.3.x. -
  • H2 Console: editing result sets is now also working for database other than H2, - if they do support updatable result sets. Add "@edit" before the query. - Only limited testing has been done on this feature, - some data types may not work (please provide feedback if you find issues). -
  • Cluster: an open transaction was committed when a cluster node was stopped - (because disabling the cluster executes SET CLUSTER '', which committed the transaction). - Transaction are no longer committed when calling SET CLUSTER. Issue 199. -
  • Cluster: non-admin users couldn't connect to the cluster and couldn't disable the cluster. Issue 201. -
  • Cluster: NEXTVAL('sequence') was only called on one cluster node, - therefore sequence values could get out of sync. -
  • Version 1.2.136 could not be converted to Java 1.4 - (because the Retrotranslator doesn't support BigDecimal.precision). - A workaround has been implemented. -
  • The error code of IO exceptions in CSV functions was incorrect. -
  • The TriggerPassData example now uses a prefix (the database name). -
  • The wrong exception was thrown when trying to reference a table that doesn't support references - such as a table in the information schema. -
  • Server.shutdownTcpServer can now stop all TCP servers on this JVM. -
  • JdbcConnectionPool: the default connection timeout is now 30 seconds (it used to be 5 minutes). -
  • LOB storage: LOBs added with "h2.lobInDatabase" enabled couldn't - be read later with this option disabled. -
- -

Version 1.2.136 (2010-05-24)

-
  • When using ORDER BY and there are both ascending and descending indexes, the database used - the first index even when the second one could be used for sorting. -
  • Conditions of the form columnName IS NULL now use an index. To disable this feature, - set the system property h2.optimizeIsNull to false. -
  • H2 Console: when the settings were not stored yet (for example when running for the first time), - the last recently used settings were not stored. A workaround was to create the file - ".h2.server.properties" manually in the current user home directory, with the contents: - webAllowOthers=false, webPort=8082, webSSL=false, - 0=Generic H2 (Embedded)|org.h2.Driver|jdbc\:h2\:~/test|sa - (where a comma is a newline). -
  • The source code is now switched to Java 6 (JDK 1.6) by default. - Java 5 (JDK 1.5) is still supported, and the jar file is still compiled for Java 5. -
  • The BOM (the byte-order-mark) character 0xfeff at the beginning of the file is ignored. - This is for compatibility with Microsoft Excel. -
  • When opening an existing database, the cache size is set to at most - half the amount of memory available for the virtual machine - (Runtime.getRuntime().maxMemory()), even if the cache size setting stored in the database - is larger. Setting the cache size in the database URL or explicitly using SET CACHE_SIZE - overrides this value (even if larger than the physical memory). -
  • INFORMATION_SCHEMA.SETTINGS: the cache size is now returned in KB. -
  • New system property h2.selectForUpdateMvcc, the default is false (the feature is disabled). - When enabled, SELECT ... FOR UPDATE only locks the selected rows in the MVCC mode. - Aggregate or GROUP BY queries are not allowed in this case. -
  • Profiler: improved message if there was no stack trace. -
  • The H2 Console can now be used within another application, in a frame or iframe. Issue 197. -
  • Recover tool: the statistics section now includes page type counts again. -
  • Queries with multiple IN(...) conditions sometimes return the wrong results when there was a multi-column index for the column. -
  • Queries with IN(..., NULL) did sometimes return the wrong results when there was a index for the column. -
  • DECIMAL: faster precision and memory usage calculations. -
  • A new class org.h2.tools.TriggerAdapter allows to use the ResultSet interface within trigger implementations. -
  • A subselect which used an index could lead to wrong results. Fixed. -
  • Creating a cached temporary non persistent table with a primary key threw a NullPointerException. -
- -

Version 1.2.135 (2010-05-08)

-
  • Temporary files were not deleted when using large transactions, disabling autocommit, - and closing the session without committing. -
  • Queries using multiple IN(..) conditions on the same table could cause repeated rows in the result set. -
  • Translation: Lubomir Grajciar translated the H2 Console as well as all error message to Slovensky. Thanks a lot! -
  • There was a possible Java level deadlock when opening an uninitialized database and using - a file system that also opened a database. -
  • When killing the process while the database was writing a checkpoint, while it was closing, - or while running recovery (while removing temporary tables from a previous run), the database could become corrupt. - A new test case has been implemented to ensure such problems can not occur in the future. -
  • File system: new method FileSystem.setReadOnly. -
  • The page size for new databases can now be set in the database URL using ;PAGE_SIZE=512. - Currently this feature is only used to simplify testing. -
  • New system property h2.functionsInSchema (default is false). - If enabled, the SCRIPT statement always includes the schema name in the CREATE ALIAS statement - (even if the schema is PUBLIC). This is not backward compatible with H2 versions 1.2.134 and older. -
  • Functions: it is no longer required to add a space after a comma in the parameter list. - Example: CREATE ALIAS PARSE_INT FOR "java.lang.Integer.parseInt(java.lang.String,int)" -
  • Functions now reside within a schema, similar to sequences. - If you do create such functions in schemas other than PUBLIC, then the database - can not be opened with older versions of H2. -
  • Cluster: after a cluster node failed, the second cluster node can now be re-created - and started without having to stop the first cluster node, and without having to stop - running applications. To do that, append ;AUTO_RECONNECT=TRUE to the database URL. -
  • Auto-reconnect: if another connection uses the database in exclusive mode - then this connection will try to re-connect until the exclusive mode ends. - This is important when using the cluster mode. -
  • SET EXCLUSIVE now supports 0 (disable), 1 (enable), and 2 (enable and close all other connections). -
  • Installing the H2 as a service should now work on Windows 7. - The batch files now explicitly set the directory using pushd "%~dp0". -
  • Temporary tables can now be 'cached', that means indexes of temporary tables - can be persisted. This enables very large temporary tables (both local and global). -
  • The CreateCluster tool now sets the source database in exclusive mode - before copying data to the new database. -
  • The H2 Console now stream results one statement / result set at a time (using chunked transfer encoding). - To disable, set the system property h2.consoleStream to false. - This feature is not supported when using a servlet container. -
  • The H2 Console did not call the CreateCluster tool with the correctly escaped parameters. -
  • Improved PostgreSQL compatibility for ALTER TABLE ALTER COLUMN. -
  • Commas at the end of INSERT ... VALUES (), (), are now supported. -
  • The H2 Console "Start Browser" button now works even when the IP - address changes while the tool runs (for example, because a wireless connection - breaks, or when enabling / disabling the network connection). -
  • When casting from float or double to BigDecimal, the result was - sometimes unexpected, because "new BigDecimal(double val)" was used. - Now "BigDecimal.valueOf(double val)" and "new BigDecimal(Float.toString(f))" are used. - But it is still not recommended to use float or double for currency values - (see data type documentation). -
  • Global temporary tables are now deleted when closing the database. - Before, they were deleted when opening the database the next time. -
  • UNIQUE was not listed as a keyword. -
  • Improved error message when an non-SQL-exception occurred in a user - defined function. The method name and parameters are included in the error message. -
  • For some queries, the exception did not include the SQL statement. Example: - select x from system_range(1, 2) group by 'a'. -
  • The Shell tool will execute SQL statements passed as using the command line - parameter -sql. -
  • If InetAddress.getLocalHost() fails, the database should now throw an exception. -
  • New columns INFORMATION_SCHEMA.INDEXES.INDEX_CLASS and - INFORMATION_SCHEMA.TABLES.TABLE_CLASS. -
  • INFORMATION_SCHEMA.INDEXES.SQL now contains the CREATE INDEX statement - instead of just the fully qualified index name. -
- -

Version 1.2.134 (2010-04-23)

-
  • New system property h2.analyzeAuto (default 0 meaning disabled) to - automatically run ANALYZE after that many changes to a table. - For details, see the Javadoc of this system property. - The plan is to set this property to 2000 in version 1.3.x. -
  • JdbcXAConnection.start() does not support TMJOIN. Issue 189. -
  • MySQL compatibility: TIMESTAMPDIFF is now an alias for DATEDIFF. -
  • MERGE did not respect foreign key and check constraints. -
  • ALTER TABLE ALTER COLUMN: changing the data type of a column - no longer makes it nullable. -
  • When using AUTO_SERVER=TRUE, the server is now started as a daemon thread. - This was a problem when using Tomcat and a connection pool. -
  • Servers can now be started as a daemon thread using the command line options - -tcpDaemon, -pgDaemon, and -webDaemon. -
  • H2 Console: the built-in commands are now documented. -
  • REPLACE: if any parameter is null, the result is null. -
  • Queries with DISTINCT and ORDER BY will now use the index on ORDER BY if possible. - This is specially important for queries used inside IN(SELECT ...). -
  • The new statement EXPLAIN ANALYZE executes the statement, - and displays the query plan with the actual row scan count for each table. -
  • H2 Console: the auto-complete feature didn't quote column names - that need quoting. Issue 186. -
  • The experimental LOB storage mechanism now supports all features of the - old one. To use it, set the system property "h2.lobInDatabase" to "true". - If you have used this feature in version 1.2.133, you need to export - and re-import the database using SCRIPT / RUNSCRIPT. -
  • The functions isBeforeFirst() and isAfterLast() were not compliant to the - JDBC spec. If the ResultSet contains no rows, they must return false. Fixed. -
  • Filesystem parameters like "split:" didn't work in server mode with baseDir set. -
  • If baseDir is set, and a database name is given which points to a directory outside - the baseDir (eg. "../dbname"), an exception is thrown. -
- -

Version 1.2.133 (2010-04-10)

-
  • A new experimental LOB storage mechanism is available. - When enabled, CLOB and BLOB data is stored in hidden tables in the database. - To use it, set the system property "h2.lobInDatabase" to "true". - Compression is not yet implemented. Duplicate objects are only stored once. - Usually writing is slower, but reading is faster (mainly because of caching). -
  • The Shell tool threw a NumberFormatException on a empty statement. -
  • The h2small-*.jar did not support "drop all objects delete files". - Now it is supported (the DeleteDbFiles tool is now included). -
  • Operations that don't fit in memory are now faster. - Temporary file handling was changed. -
  • The default maximum log stream size is now 2 MB. This is a good value - according to some performance tests. -
  • New system property "h2.syncMethod" to configure what method to call when - closing the database, on checkpoint, and on CHECKPOINT SYNC. The default is "sync" which - calls RandomAccessFile.getFD().sync(). -
  • ROWNUM could not be used for pagination. The follow query returned no rows: - select x from (select *, rownum as r from system_range(1, 3)) where r=2; -
  • Workaround for a java.sql.Date issue: years above 9999 are not formatted correctly. - When calling ResultSet.getString() on a date value, an alternative formatting algorithm is used. -
  • Prepared statements with nested subqueries did not always return the correct result. Example: - select ?, ?, (select count(*) from test t, (select id from test where 0=?) t2 where t2.id=t.id) from test -
  • When using MULTI_THREADED=TRUE, the exception following exception could be thrown: - "object already exists: TABLES" -
  • Comparison of integer columns against float numbers was not always correct. Issue 182. -
  • H2 Console: Editing the result of a multi-line queries failed. Issue 183. -
  • H2 Console: if the settings file (.h2.properties) can't be accessed, the exception is now ignored. -
- -

Version 1.2.132 (2010-03-21)

-
  • The implementation of a Java to C (source code level) converter has been started. - The plan is: it should be possible to convert H2 (or a part of it) to C so that the database - can be run without a JVM. This will be a long term project (it may take a year or so). -
  • User defined table implementation can now be used using CREATE TABLE ... ENGINE. - Thanks to Sergi Vladykin for implementing this feature! -
  • Improved MS SQL Server compatibility: support string concatenation using "+". - Thanks to Stepan for the patch! -
  • When using the multi-threaded mode, running ANALYZE concurrently in multiple - connections could throw an exception. -
  • The MERGE statement is now about 30% faster when using a PreparedStatement. -
  • Multi-column indexes where the second or later column was descending did not always - produce correct results (rows were missing in the result set, or the result set was empty). -
  • When using large transactions or a small log size, the database could get very slow - (profiling shows the hotspot is in FileObjectDisk.sync()). -
  • The Shell tool now prints the stack trace when the list mode is enabled. -
  • CREATE ALIAS ... AS: Compilation was incorrect if the source code contained - characters that are not supported by the default file encoding. -
  • Issue 176: the JdbcDataSource now also supports a 'description' property. -
  • The Shell tool threw a ArrayIndexOutOfBoundsException after 20 statements. -
  • When using the small version of H2 ('jarClient'), the first call to - Connection.createBlob (or similar) could throw a ClassNotFoundException - because the file org.h2.store.fs.FileSystemZip is not included. This missing class - is now ignored. -
  • Literals of type BIGINT now have the correct data type. -
- -

Version 1.2.131 (2010-03-05)

-
  • Older versions of H2 (version 1.2.127 and older) could not connect to a new version (version 1.2.129 and newer). - The connection blocked when trying to connect. Now the connection no longer blocks, instead a SQL exception is thrown. -
  • In versions 1.2.129 and 1.2.130, a database could not be opened sometimes - after dropping tables or indexes, and then creating new indexes for existing tables. - The exception contained the text "parent not found" (version 1.2.129) or - "Table not found" (version 1.2.130). -
  • After the database was closed, a null pointer exception could occur in Database.flush. -
  • An ArrayIndexOutOfBoundsException could occur in the page store (eg. on "delete from table"). Fixed. -
- -

Version 1.2.130 (2010-02-26)

-
  • EXPLAIN: The query plan now contains ".tableScan" if a table scan is used. -
  • IN(..): when combining and IN(..) condition with a condition that didn't use an index, - the result could contain duplicate rows. -
  • IN(..): the index was not used if there were multiple IN(..) conditions. -
  • For foreign key constraints, the metadata column - INFORMATION_SCHEMA.INDEXES.CONSTRAINT_NAME was not set for non-unique indexes. -
  • PostgreSQL compatibility: when using the following exception was thrown: - Column "T.TYPTYPMOD" not found. Fixed. This is only when using psqlodbc_08_04*. -
  • A tool to migrate an old database from the non-page store format to the - newest version has been added in src/tools/org/h2/dev/util/Migrate.java. This file is not - included in the jar file currently. -
  • When using temporary tables, the database didn't shrink sometimes when closing. - Also, sometimes a database could not recover normally. -
  • Large transactions could run out of heap space. The maximum size of a transaction is now much larger. -
  • The default setting for the system property h2.webMaxValueLength is now 100000 (it was 10000 before). -
  • Creating a database was delayed about 2 seconds if the directory didn't exist. -
  • Implemented INIT feature. If the database URL contains ";INIT=...;" then the DDL or DML commands - following are executed on startup. Example URL: jdbc:h2:mem:test;INIT=RUNSCRIPT FROM '~/create.sql' - (patch from Kerry Sainsbury). -
- -

Version 1.2.129 (2010-02-19)

-
  • The methods of the CloseListener are added to the Trigger interface. - The interface CloseListener is removed. This is potentially a breaking change for existing triggers. -
  • CREATE ALIAS: error message when compiling Java code have been improved. -
  • MVCC: creating a table with an incorrect constraint could cause strange errors. -
  • Hash indexes now are only used for single column indexes. -
  • The cache types WEAK_* and TQ are no longer supported. - A weak reference cache never frees up memory so it's the same as - having a very large cache size. The TQ cache was not included in the - jar file since a longer time, and was not tested. -
  • The file system abstraction no longer throws SQL exceptions. -
  • DatabaseEventListener.diskSpaceIsLow has changed. -
  • The CompressTool no longer throw as SQL exceptions. Instead, it throws runtime exceptions. -
  • SimpleResultSet.addColumn and addRow now can throw a IllegalStateException - instead of a SQLException. -
  • When doing an index lookup, decimal values with the same value but different scale - (for example 0.00 and 0.0) where not considered equal in version 1.2.128. - Now they are (unlike BigDecimal.equals()). -
  • The BNF parser now uses the visitor pattern. -
  • Converting a UUID to bytes was incorrect. Because of that, updatable result sets on - tables with UUID primary key did not work. -
  • The database URL property DATABASE_EVENT_LISTENER_OBJECT is no longer supported - (there are problems passing objects when the PostgreSQL driver is installed as well). -
  • H2 Console: asynchronous login (using a DatabaseEventListener) is no longer supported. -
  • A workaround for a Windows socket problem has been implemented. Thanks a lot to Sergi Vladykin. -
  • The Recover tool did not convert correctly convert CLOB data with non-ASCII characters. -
  • Tools: the method run(String... args) has been renamed to runTool(String... args). -
  • Server.startWebServer(Connection) was not working as expected. -
  • The database URL option ACCESS_MODE_LOG is no longer supported. -
  • The database URL option RECOVER has currently no effect. -
  • Converting an old (non-page store) database is no longer supported using this version. -
  • The following system properties are no longer supported: - h2.overflowExceptions, h2.optimizeDropDependencies, h2.optimizeGroupSorted, - h2.optimizeMinMax, h2.optimizeNot, h2.optimizeIn, h2.optimizeInJoin, h2.reuseSpace*. - Most of then were there for a long time, but always with the same value. - There was no unit test with the other value. So changing them was potentially dangerous - (not a lot, but still). -
  • The setting LOG has currently no effect (it only had an effect when the page store was disabled). -
  • Disabling the page store is no longer supported. The old storage mechanism - has been removed, shrinking the jar file size by almost 10%. -
  • The translated resources are now stored in UTF-8 format. -
  • The Windows service wrapper now detects if multiple versions of H2 are installed. -
- -

Version 1.2.128 (2010-01-30)

-
  • There are known errors on rollback when the page store is disabled and at the same time - MVCC is used. See http://code.google.com/p/h2database/issues/detail?id=158 -
  • The DeleteDbFiles tool deleted all files in the .lob.db directory, - even files that didn't belong to the database. -
  • Automatic conversion of old databases to the page store format failed - if the database contained LOB files. -
  • Nested subqueries didn't work for INSERT INTO and IN(..). - Example: insert into test ((select 1)); -
  • If the database was already closed using SHUTDOWN IMMEDIATELY, closing a second - connection could throw a NullPointerException if there was a local temporary table. -
  • Less classes are loaded when using the database in embedded mode. -
  • The information schema tables are only initialized when needed. - This reduces memory usage and speeds up creating in-memory databases. - Each in-memory database needs about 8 KB of heap memory. -
  • Nested UNION/INTERSECT queries with brackets could produce the wrong result if used within a subquery. Example: - select count(*) from (select 1 union (select 2 intersect select 2)) x; -
  • Comparing an column against a constant expression with a higher precision or length - than the column could give wrong results (the expression was truncated before comparing). -
  • Improved PostgreSQL compatibility (support SHOW DEFAULT_TRANSACTION_ISOLATION). -
  • Documentation: the javadocs for Csv.write and read used the wrong default charset. -
  • MVCC: if the table was locked in exclusive mode (such as SELECT ... FOR UPDATE), another session - could query the table. This is now longer possible. -
  • If a FOR UPDATE query was executed twice (using a PreparedStatement), the table was not locked. -
  • Triggers: INSTEAD OF triggers are now supported. - Such triggers can be defined on views. -
  • New system property h2.identifiersToUpper. If set to false, - identifiers in SQL statements are case sensitive even if they are not quoted. -
  • Slightly improved performance if the table is already locked. -
  • CompressLZF: faster decompression. -
  • PgServer: the wrong size was sent for VARCHAR data. - Thanks again to Sergi Vladykin for the patch. -
  • Serialized access mode (server-less multi-connection mode): fixed getGeneratedKeys() for sequences. -
- -

Version 1.2.127 (2010-01-15)

-
  • Serialized access mode (server-less multi-connection mode): sequences did not work as expected - (there were gaps in generated values when using multiple connections). -
  • Page store: new databases can not be opened with older versions. -
  • Page store: adding data to new database is now faster. -
  • File system: getting the file name from a path is now faster. This should - speed up BLOB and CLOB access. -
  • PgServer: incorrect SQL types were returned in result set meta data. - Concurrently opening a database could fail (PG catalog initialization was not synchronized). - Thanks a lot to Sergi Vladykin for providing the patches! -
  • SHOW COLUMNS did not work correctly if there where multiple indexes - on the same columns. -
  • Page store: the wrong write count was written to the database header. - This could cause the server-less multi-connection mode to fail. -
  • Result sets larger than 2 GB threw an exception "Negative seek offset". Fixed. -
  • If the system property h2.check was set to false, an ArrayIndexOutOfBoundsException could occur. -
  • Alter table is now supported even if a table has views defined. -
  • Fulltext search: exceptions within the fulltext search package had the wrong SQL state. -
  • The Lucene fulltext search ignored transaction rollback. Fixed using a trigger on rollback. -
  • Trigger can now be called on rollback. -
  • The shell script h2.sh ignored command line line arguments. -
  • When running H2 in the Google AppEngine for Java, a AccessControlException could be thrown - when trying to open a read-only database. Fixed. -
  • The user home directory prefix (~) is now only expanded when followed by a slash - or backslash, or standing alone. -
  • Native fulltext search: before inserting or deleting data, FT_INIT() had to be called. - This is no longer required. -
  • The .trace.db file is now only created if required. -
  • Shell tool: improved PostgreSQL compatibility. -
  • Trying to open a database in read-only mode when a .lock.db file exists will now fail - with a nice error message. -
  • H2 Console: data that is too long is now abbreviated as follows: text... (100000 characters). - A large binary is abbreviated as follows: abcdef... (100000 bytes). -
  • Faster data conversion from BIGINT or INT to DECIMAL. -
  • Server-less multi-connection mode: try to delete log files if switching between read/write operations. -
  • CompressLZF: Faster decompress and improved javadocs -
- -

Version 1.2.126 (2009-12-18)

-
  • The ChangeFileEncryption tool will now fail with an exception - if the database is still in use. The Backup tool will also fail except when running in quiet mode. -
  • CSVREAD: when reading the column names from the CSV file, column names that contain - no special characters are considered case insensitive now. -
  • Optimization index conditions of the form 'column=NULL' (which is always false; unlike 'column IS NULL'). -
  • Script command and tool: the primary key constraint is now listed before inserting the data. - This will result in a smaller database when using the page store. -
  • Statements with IN(SELECT..) conditions could produce the wrong result. - Example: index on id, name; query: select * from test where id between 1 and 3 and name in (select 'World'). -
  • Statements with IN(..) conditions could produce the wrong result when using views or nested select statements. - Example: index on id; index on name; query: select * from (select * from test) where id=1 and name in('a', 'b'). - select * from (select * from test) where id=1 and name in('Hello', 'World'). -
  • Page store: a rollback of a relatively large transaction could fail with an ArrayIndexOutOfBoundsException - or a 'row not found' exception in the PageBtreeIndex in some cases. -
  • JaQu: the decompiler has been improved, and a few test cases already work. It is still incomplete however. -
  • LIKE: any letter is now allowed after the escape character (which is still '\' by default). - Previously, an exception was thrown (unlike other databases) if it was not the escape character, '_' or '%'. - If the escape character appears at the end of the pattern, the result is it is ignored (like PostgreSQL and MS SQL Server). -
  • The reserve heap memory is no longer used. -
  • Database.checkpoint() could throw a NullPointerException. -
- -

Version 1.2.125 (2009-12-06)

-
  • Lucene fulltext search: the Lucene field names now match the table column names, - except if the column names start with _ (in which case another _ is prepended). - Unfortunately this change means existing fulltext indexes need to be re-built. -
  • The shell tool now has a very simple statement history. -
  • The zip file system implementation now supports the '~' home directory prefix. - Example database URL: jdbc:h2:zip:~/test.zip!/test -
  • Right outer joins on tables that were already 'inner joined' was processed incorrectly. -
  • Temporary files from LOB objects were not deleted early enough when using the server mode. -
  • Trying to alter a temporary table threw a strange exception. - It is still not possible to do that, but the exception message is better now. -
  • When the system property h2.maxMemoryRowsDistinct was set, and - using SELECT DISTINCT, the temporary table was not correctly dropped. - This could cause problems in recovery when the process was killed. -
  • Trigger that are called before a select statement are now supported. - This allows to create tables that work like materialized views. -
  • Non-row based triggers were called even if the action didn't match the - declared action (INSERT triggers were also called when deleting rows). - This has been changed. The MERGE statement calls both INSERT and DELETE triggers. -
  • Statements with IN(..) conditions could produce the wrong result or a data conversion error (since version 1.2.120). - Examples: index on id, name, condition: id=1 and name in('Hello', 'x'); index on id, query: - select * from (select * from test) where id=1 and name in('Hello', 'World'). -
  • The CompressTool was not multithreading safe. Because of this, the following database - operations where also not multithreading safe (even when using different databases): the SCRIPT command - (only when using compression), the COMPRESS function, and storing CLOB or BLOB data (only when compression is enabled). -
  • The compression algorithm "LZF" is now about 33% faster than before when compressing small block - (around 2 KB). It is much faster than Deflate, but the compression ratio is lower. - Some of the optimizations are from Sam Van Oort, thanks a lot! -
  • Compressing large blocks of data didn't work when using the "Deflate" compression algorithm. - Compressing a lot of data could run out of heap memory. -
  • The test cases don't access the file system directly, this simplifies GAE for Java testing. - Thanks to Vince Bonfanti. -
  • More bugs in the server-less multi-connection mode have been fixed. -
  • When running against an old database, the SCRIPT statement could generate a - SQL script that contained duplicate indexes (PRIMARY_KEY_E). -
  • JdbcConnectionPool.getConnection() could throw a NullPointerException. -
  • User defined functions: the source code is now available using - SELECT SOURCE FROM INFORMATION_SCHEMA.FUNCTION_ALIASES. -
  • User defined functions with source code didn't work after re-opening the database. -
  • The newsfeeds are now Atom 1.0 standard compliant. -
  • The database is now closed after an out of memory exception, because - the database could get corrupt otherwise. -
  • Better error message if both AUTO_SERVER and SERIALIZED parameters are set to TRUE. -
  • Drop table did not delete lob files in old file store (not PAGE_STORE). -
- -

Version 1.2.124 (2009-11-20)

-
  • Clustering: there is now a way to detect which cluster instances are running. -
  • ConvertTraceFile: the SQL statement statistics are better formatted (newline are removed). -
  • The file lock thread is now stopped when the database is closed. -
  • Issue 140: the Script tool now supports writing to a stream. -
  • Issue 138: the trace output of Statement.execute(String, int) and executeUpdate was incorrect. -
  • Page store: new databases can not be opened with older versions. -
  • Page store: multi-column indexes didn't work if the cache was very small. -
  • Page store: opening a database could theoretically result in an endless loop. -
  • Page store: adding large indexed columns could get very slow. -
  • Page store: after a duplicate key exception, an ArrayIndexOutOfBoundsException could be thrown (only for very large rows). -
  • Page store: the recover tool sometimes generated a script file that contained duplicate data. -
  • Page store: sometimes opening a read-only database failed. -
  • Page store: opening a database sometimes failed if large rows where updated, or if a table was truncated before. -
  • Page store: when using a very small page size (128 bytes or smaller), writing a large row could result in an endless recursion. This is only a theoretical problem, as the page size is 2 KB. -
  • Page store: getting the min value from a descending index with NULL entries could return the wrong result. -
  • Page store: improved auto-recovery after power failure. -
  • The JDBC client did not detect that it was not talking to an H2 server. This could result in strange exceptions when trying to connect to another kind of server. -
  • User defined functions can be created with source code. Example: CREATE ALIAS HI AS 'String hi() { return "Hello"; }' -
  • Database file lock: the exception "lock file modified in the future" is no longer thrown; instead, opening the file will be delayed by 2 seconds. -
  • Inserting LOBs got slower each time the process was restarted. It could loop endlessly after about 1000 process restarts. -
  • Issue 117: Multi-version concurrency: concurrent MERGE statements now work. -
  • Improved read-only database detection. -
- -

Version 1.2.123 (2009-11-08)

-
  • Page store: new databases can not be opened with older versions. -
  • Page store: updating large rows (rows with more than 2000 bytes of data) - could corrupt the database. -
  • Page store: inserting very large rows failed with ArrayIndexOutOfBoundsException. -
  • When using multi-threaded kernel mode, setting disabling locking (LOCK_MODE=0) - will now throw an exception. At this time this combination will result in corruption when - multiple threads try to update the same table. -
  • The fulltext search methods and fields are now protected instead of private, - to make the classes more easily extensible. -
  • The Lucene fulltext search now also returns the score. -
  • New function SCOPE_IDENTITY() to avoid problems when inserting - rows in a trigger. -
  • Statement.getGeneratedKeys() returned the wrong value if a trigger - changed the identity value after inserting the row. -
  • Improved error messages: identifiers and values are now quoted. -
  • Improved error message when casting a value failed: - the column name and type is included in the message. -
  • Improved support for GAE for Java thanks to Vince Bonfanti. -
- -

Version 1.2.122 (2009-10-28)

-
  • The native fulltext search now supports streaming CLOB data. -
  • If the database URL ends with ;PAGE_STORE=TRUE and a database in - the old format exists, it is automatically converted to the new page store format - if possible. A backup of the database is created first. Automatic conversion is not supported - if the database was not closed normally (if it contains uncommitted transactions). -
  • Dropping the current user is now allowed if another admin user exists. -
  • Values of type BINARY or BLOB could not be converted to the data type OTHER. -
  • SHUTDOWN COMPACT now fully compacts the database. -
  • New system properties h2.maxCompactCount and h2.maxCompactTime - to allow changing the default behavior (at most 2 seconds compacting when closing the database). -
  • New sorted insert optimization (see Performance / Database Performance Tuning). -
  • Issue 116: The files h2*-sources.jar and h2*-javadoc.jar are - now in the Maven repository. -
  • Page store: opening a large database was slow if it was not closed before. -
  • Page store: new write and read counters in the meta data table. Use - SELECT * FROM INFORMATION_SCHEMA.SETTINGS WHERE NAME IN( - 'info.FILE_WRITE_TOTAL', 'info.FILE_WRITE', 'info.FILE_READ', - 'info.CACHE_MAX_SIZE', 'info.CACHE_SIZE') -
  • The SQL syntax is documented using (railroad) diagrams. - The diagrams are HTML. -
  • The documentation is no longer available in Japanese because the - translation was too much out of sync. Please use the Google translation instead. -
  • Certain queries were not sorted if subselect queries were involved -
  • More bugs in the server-less multi-connection mode have been fixed: - 90097 The database is read only, caches must be cleared on reconnect, etc. -
- -

Version 1.2.121 (2009-10-11)

-
  • Better support GaeVFS (Google App Engine Virtual File System) thanks to Thanks to Vince Bonfanti. -
  • CSVREAD didn't close the file. Thanks to Vince Bonfanti for the patch! -
  • If a database in the old format exists, it is now used. - The system property is used for new databases, or if databases exist - in both formats. In any case, the flag in the URL overrides this logic. -
  • Page store bugs were fixed. Large values in indexed columns could corrupt the index. -
  • The page store did not work when using Retrotranslator (because the Retrotranslator doesn't - support Integer.reverse and Long.reverse). -
  • New system property h2.pageStoreTrim to disable shrinking the database when closing - (disabled by default, meaning by default the database is trimmed). -
- -

Version 1.2.120 (2009-10-04)

-
  • This is a beta version. -
  • Large updates could throw an ArrayIndexOutOfBoundsException in RowList.writeRow. -
  • In version 1.2, the following system properties are now enabled by default: - h2.pageStore, h2.nullConcatIsNull, h2.optimizeInList. The default value for - h2.defaultMaxLengthInplaceLob is now 4096 (it was 1024 with version 1.1). -
  • New databases are now stored in the new 'page store' file format. - Existing databases are kept in the old file format. To use the old file format, - append ;PAGE_STORE=FALSE to the database URL or set the system property h2.pageStore to false. -
  • Issue 125: Renaming primary keys was not persistent. Fixed. - Unfortunately, databases created by this version can not be opened with older versions because of this change. -
  • Issue 124: Hibernate schema validation failed for decimal/numeric columns. - This problem is fixed in the Hibernate dialect that is included with H2 - (src/tools/org/hibernate/dialect/H2Dialect.java.txt), but not in Hibernate yet. -
  • PostgreSQL compatibility: function LASTVAL() as an alias for IDENTITY(). -
  • Linked tables now support default values when inserting, updating or merging. -
  • Bugfixes in the page store. -
  • Possibility to set a vendor id in Constants.java, so that unofficial builds are distinguishable - from official releases. -
  • Allow writing to linked tables in readonly databases. -
- -

Version 1.1.119 (2009-09-26)

-
  • SQL statements in the exception message are no longer included if they contain '--hide--'. -
  • Temporary local tables did not always work after reconnect if AUTO_SERVER=TRUE -
  • New system property h2.defaultMaxLengthInplaceLob to change the default maximum size - of an in-place LOB object. -
  • New system property h2.nullConcatIsNull to change the default null concatenation behavior. - The default will be enabled in version 1.2. -
  • The cache algorithm TQ is disabled in this version, because it is unstable, and - because the current implementation does not have any measurable advantages over the default. -
  • New committer: Christian Peter. He works for Docware and - helped a lot finding and fixing bugs, and generally improving the database. He is now a committer. -
  • ChangeFileEncryption did not work with Lob subdirectories. Fixed. -
  • Issue 121: JaQu: new simple update and merge methods. -
  • Issue 120: JaQu didn't close result sets. -
  • Issue 119: JaQu creates wrong WHERE conditions on some inputs. -
  • The new page store mechanism is now alpha-level quality. The next release - will most likely be "1.2.120 beta" where this mode is enabled by default. To use - it right now, append ;PAGE_STORE=TRUE to the database URL. The file format - of this mode will probably not change any more. -
  • SELECT COUNT(*) FROM SYSTEM_RANGE(...) returned the wrong result. Fixed. -
  • The Recover tool now also processes the log files, however applying those changes - is still a manual process. -
  • New sample application that shows how to pass data to a trigger. -
  • More bugs in the server-less multi-connection mode have been fixed: - On Windows, two processes could write to the same database at the same time. -
  • When loading triggers or other client classes - (static functions, database event listener, user aggregate functions, other JDBC drivers), - the database now uses the context class loader if the class could not be found using Class.forName(). -
  • Updating many rows with the same CLOB or BLOB values could result in FileNotFoundException. -
  • Statement.getConnection() threw an exception if the connection was already closed. -
  • The native fulltext index kept a reference to a database after the database was closed. -
  • Non-unique in-memory hash indexes are now supported. Thanks a lot to Sergi Vladykin for the patch! -
  • The optimizer does a better job for joins if indexes are missing. -
- -

Version 1.1.118 (2009-09-04)

-
  • SHOW COLUMNS only listed indexed columns. -
  • When calling SHUTDOWN IMMEDIATELY in the server mode, the .trace.db file was not closed. -
  • DatabaseMetaData.getPrimaryKeys: the wrong constraint name was reported - if there was another constraint on the same table and columns. -
  • AUTO_INCREMENT now works in the same way in ALTER TABLE ALTER COLUMN - as in CREATE TABLE (it does not create a primary key). -
  • Native fulltext search: before searching, FT_INIT() had to be called. - This is no longer required. -
  • Better support GaeVFS (Google App Engine Virtual File System). -
  • JaQu: the plan is to support natural (pure Java / Scala) conditions such as - (id == 1 && name.equals("Test")). A proof of concept decompiler is now included (it doesn't work yet). -
  • Various bugfixes and improvements in the page store mechanism (still experimental). -
  • PreparedStatement.setObject now converts a java.lang.Character to a string. -
  • H2 Console: PierPaolo Ucchino has completed the Italian translation. Thanks a lot! -
  • Various tools now use Java 5 var-args, such as main the methods and SimpleResultSet.addRow. -
  • H2 Console: indexes of tables of non-default schemas are now also listed. -
  • Issue 111: Multi-version concurrency / duplicate primary key after rollback. -
  • Issue 110: Multi-version concurrency / wrong exception is thrown. -
  • Parser: sequenceName.NEXTVAL and CURRVAL did not respect the schema search path. -
  • Issue 101: The following sequence could throw the exception "Row not found when trying to delete": - start a transaction, insert many rows, delete many rows, rollback. The number of rows depends - on the cache size. -
  • The stack trace of very common exceptions is no longer written to the .trace.db file by default. -
  • An optimization for OR is implemented, but disabled by default. - Expressions of the type X=1 OR X=2 are converted to X IN(1, 2). - To enable, set the system property h2.optimizeInList to true before loading the H2 JDBC driver. -
  • An optimization for IN(..) and IN(SELECT...) is implemented, but disabled by default. - To enable, set the system property h2.optimizeInList to true before loading the H2 JDBC driver. - If enabled, this overrides h2.optimizeIn and h2.optimizeInJoin. Unlike now, this optimization - will also speed up updates and deletes. -
- -

Version 1.1.117 (2009-08-09)

-
  • New committer: Sam Van Oort has been contributing to H2 since quite some time - in many ways (on the mailing list, documentation, and in the form of patches). - He is now a committer. -
  • JaQu: the order of the fields in the database no longer needs to match the order in the database. -
  • Issue 103: MVCC: the setting MAX_MEMORY_UNDO can currently not be supported when using - multi-version concurrency, that means the complete undo log must fit in memory. -
  • LIKE: the escape mechanism can now be disable using ESCAPE ''. - The default escape character can be changed using the system property h2.defaultEscape. - The default is still '\' (as in MySQL and PostgreSQL). -
  • Views using functions were not re-evaluated when necessary. -
  • Improved MySQL compatibility for SHOW COLUMNS. -
  • Improved PostgreSQL compatibility for timestamp literals with timezone. -
  • Sergi Vladykin translated the error messages to Russian. Thanks a lot! -
  • Support for Java 6 DatabaseMetaData.getTables, getColumns, getProcedures, and getProcedureColumns. -
  • Issue 101: Rollback of a large transaction (more than 100000 rows) could fail. -
  • Various bugfixes and improvements in the page store mechanism (still experimental). -
  • The functions LENGTH, OCTET_LENGTH, and BIT_LENGTH now return BIGINT. -
  • Data types CLOB and BLOB: the maximum precision was Integer.MAX_VALUE, it is now Long.MAX_VALUE. -
  • Multi-threaded kernel: creating and dropping temporary database objects - and the potentially free pages list was not correctly synchronized. Thanks a lot - to Eric Faulhaber for the test case and patch! -
  • Parsing SQL script files is now faster. -
  • CSV reading is now faster. -
  • SimpleResultSet.newInstance(SimpleRowSource rs) did not work. -
- -

Version 1.1.116 (2009-07-18)

-
  • Server-less multi-connection mode: more bugs are fixed. -
  • The built-in help (INFORMATION_SCHEMA.HELP) is smaller, shrinking the jar file size a bit. -
  • H2 Console: column of tables of non-default schemas are now also listed, - except for schemas starting with 'INFO'. -
  • ALTER TABLE: removing an auto-increment or identity column didn't remove the sequence. -
  • Creating indexes is now a bit faster. -
  • PG Server: new system property h2.pgClientEncoding to explicitly set the encoding - for clients that don't send the encoding (the default encoding is UTF-8). - Thanks a lot to Sergi Vladykin for the patch! -
  • PG Server: improved compatibility by using the type ids of the PostgreSQL driver. - Thanks a lot to Sergi Vladykin for the patch! -
  • H2 Console: Oracle system tables are no longer listed, improving performance. -
  • Result sets are now read-only except if the statement or prepared statement was created - with the concurrency ResultSet.CONCUR_UPDATABLE. This change is required because the old behavior - (all result set are updatable) violated the JDBC spec. For backward compatibility, use the - system property h2.defaultResultSetConcurrency. -
  • New system property h2.defaultResultSetConcurrency to change the default result set concurrency. -
  • JDBC: using an invalid result set type or concurrency now throws an exception. -
  • If a pooled connection was not closed but garbage collected, a NullPointerException could occur. -
  • Fulltext search: a NullPointerException was thrown when updating a value that - was NULL previously. -
  • The Recover tool did not work with .data.db files of the wrong size. -
  • Triggers: if there was an exception when initializing a trigger, this exception could be hidden, - and in some cases (specially when using the Lucene fulltext index mechanism) a NullPointerException was - thrown later on. Now the exception that occurred on init is thrown when changing data. -
  • The soft-references cache (CACHE_TYPE=SOFT_LRU) could throw a NullPointerException. -
  • To enable the new page store mechanism, append ;PAGE_STORE=TRUE to the database URL. - or set the system property h2.pageStore to true. - This mechanism is still experimental, and the file format will change, but it is quite stable now. -
- -
- diff --git a/tools/h2/src/docsrc/html/cheatSheet.html b/tools/h2/src/docsrc/html/cheatSheet.html deleted file mode 100755 index f21fbfe..0000000 --- a/tools/h2/src/docsrc/html/cheatSheet.html +++ /dev/null @@ -1,199 +0,0 @@ - - - - -H2 Database Engine - - - - -
- -

H2 Database Engine Cheat Sheet

-
- -

Using H2

- - -

Documentation

-

-Reference: -SQL grammar, -functions, -data types, -tools, -API -
-Features: -fulltext search, -encryption, -read-only -(zip/jar), -CSV, -auto-reconnect, -triggers, -user functions -

- -

Database URLs

-

-Embedded
-jdbc:h2:~/test 'test' in the user home directory
-jdbc:h2:/data/test 'test' in the directory /data
-jdbc:h2:test in the current(!) working directory
-

-In-Memory
-jdbc:h2:mem:test multiple connections in one process
-jdbc:h2:mem: unnamed private; one connection
-

-Server Mode
-jdbc:h2:tcp://localhost/~/test user home dir
-jdbc:h2:tcp://localhost//data/test absolute dir
-Server start:java -cp *.jar org.h2.tools.Server -

-Settings
-jdbc:h2:..;MODE=MySQL compatibility (or HSQLDB,...)
-jdbc:h2:..;TRACE_LEVEL_FILE=3 log to *.trace.db
-

- -
-
- -

Using the JDBC API

-
-Class.forName("org.h2.Driver");
-Connection conn = DriverManager.
-    getConnection("jdbc:h2:~/test");
-conn.close();
-
- -

Connection Pool

-
-import org.h2.jdbcx.JdbcConnectionPool;
-JdbcConnectionPool cp = JdbcConnectionPool.
-    create("jdbc:h2:~/test", "sa", "sa");
-Connection conn = cp.getConnection();
-conn.close(); cp.dispose();
-
- -

Maven 2

-
-<dependency>
-    <groupId>com.h2database</groupId>
-    <artifactId>h2</artifactId>
-    <version>${version}</version>
-</dependency>
-
- -

Hibernate

-

-hibernate.cfg.xml (or use the HSQLDialect): -

-
-<property name="dialect">
-    org.hibernate.dialect.H2Dialect
-</property>
-
- -

TopLink and Glassfish

-

-Datasource class: org.h2.jdbcx.JdbcDataSource
-oracle.toplink.essentials.platform.
-database.H2Platform -

- -
- -
- - \ No newline at end of file diff --git a/tools/h2/src/docsrc/html/datatypes.html b/tools/h2/src/docsrc/html/datatypes.html deleted file mode 100755 index e7174cd..0000000 --- a/tools/h2/src/docsrc/html/datatypes.html +++ /dev/null @@ -1,63 +0,0 @@ - - - - -Data Types - - - - -
- - -

Data Types

- - - - - - -
- - ${item.topic}
-
-
- - ${item.topic}
-
-
- - ${item.topic}
-
-
- - - - -

${item.topic}

- -${item.railroad} - - -

${item.text}

-

Example:

-

${item.example}

-
- -
- diff --git a/tools/h2/src/docsrc/html/download.html b/tools/h2/src/docsrc/html/download.html deleted file mode 100755 index 944ce41..0000000 --- a/tools/h2/src/docsrc/html/download.html +++ /dev/null @@ -1,63 +0,0 @@ - - - - -Downloads - - - - -
- - -

Downloads

- -

Version ${version} (${versionDate})

-

-Windows Installer -
-Platform-Independent Zip -
-

- -

Version ${stableVersion} (${stableVersionDate}, Last Stable)

-

-Windows Installer
-Platform-Independent Zip
-

- -

Download Mirror and Older Versions

-

-Platform-Independent Zip
-

- -

Jar File

-

-Maven.org
-Sourceforge.net
-Latest Automated Build (not released) -

- -

Subversion Source Repository

-

-Google Code -

- -

-For details about changes, see the Change Log. -

- -

News and Project Information

-

-Atom Feed
-RSS Feed
-DOAP File (what is this) -

- -
- diff --git a/tools/h2/src/docsrc/html/faq.html b/tools/h2/src/docsrc/html/faq.html deleted file mode 100755 index c0b20b1..0000000 --- a/tools/h2/src/docsrc/html/faq.html +++ /dev/null @@ -1,263 +0,0 @@ - - - - -Frequently Asked Questions - - - - -
- - -

Frequently Asked Questions

- - - I Have a Problem or Feature Request
- - Are there Known Bugs? When is the Next Release?
- - Is this Database Engine Open Source?
- - My Query is Slow
- - How to Create a New Database?
- - How to Connect to a Database?
- - Where are the Database Files Stored?
- - What is the Size Limit (Maximum Size) of a Database?
- - Is it Reliable?
- - Why is Opening my Database Slow?
- - Column Names are Incorrect?
- - Float is Double?
- - Is the GCJ Version Stable? Faster?
- - How to Translate this Project?
- -

I Have a Problem or Feature Request

-

-Please read the support checklist. -

- -

Are there Known Bugs? When is the Next Release?

-

-Usually, bugs get fixes as they are found. There is a release every few weeks. -Here is the list of known and confirmed issues: -

-
  • Apache Harmony: there seems to be a bug in Harmony that affects H2. - See HARMONY-6505. -
  • Tomcat and Glassfish 3 set most static fields (final or non-final) to null when - unloading a web application. This can cause a NullPointerException in H2 versions - 1.1.107 and older, and may still not work in newer versions. Please report it if you - run into this issue. In Tomcat >= 6.0 this behavior can be disabled by setting the - system property org.apache.catalina.loader.WebappClassLoader.ENABLE_CLEAR_REFERENCES=false, - however Tomcat may then run out of memory. A known workaround is to - put the h2*.jar file in a shared lib directory - (common/lib). -
  • Some problems have been found with right outer join. Internally, it is converted - to left outer join, which does not always produce the same results as other databases - when used in combination with other joins. -
  • When using Install4j before 4.1.4 on Linux and enabling pack200, - the h2*.jar becomes corrupted by the install process, causing application failure. - A workaround is to add an empty file h2*.jar.nopack - next to the h2*.jar file. - This problem is solved in Install4j 4.1.4. -
-

-For a complete list, see Open Issues. -

- -

Is this Database Engine Open Source?

-

-Yes. It is free to use and distribute, and the source code is included. -See also under license. -

- -

My Query is Slow

-

-Slow SELECT (or DELETE, UPDATE, MERGE) -statement can have multiple reasons. Follow this checklist: -

-
    -
  • Run ANALYZE (see documentation for details). -
  • Run the query with EXPLAIN and check if indexes are used - (see documentation for details). -
  • If required, create additional indexes and try again using - ANALYZE and EXPLAIN. -
  • If it doesn't help please report the problem. -
  • -
- -

How to Create a New Database?

-

-By default, a new database is automatically created if it does not yet exist. -See Creating New Databases. -

- -

How to Connect to a Database?

-

-The database driver is org.h2.Driver, -and the database URL starts with jdbc:h2:. -To connect to a database using JDBC, use the following code: -

-
-Class.forName("org.h2.Driver");
-Connection conn = DriverManager.getConnection("jdbc:h2:~/test", "sa", "");
-
- -

Where are the Database Files Stored?

-

-When using database URLs like jdbc:h2:~/test, -the database is stored in the user directory. -For Windows, this is usually C:\Documents and Settings\<userName>. -If the base directory is not set (as in jdbc:h2:test), -the database files are stored in the directory where the application is started -(the current working directory). When using the H2 Console application from the start menu, -this is <Installation Directory>/bin. -The base directory can be set in the database URL. A fixed or relative path can be used. When using the URL -jdbc:h2:file:data/sample, the database is stored in the directory -data (relative to the current working directory). -The directory is created automatically if it does not yet exist. It is also possible to use the -fully qualified directory name (and for Windows, drive name). -Example: jdbc:h2:file:C:/data/test -

- -

What is the Size Limit (Maximum Size) of a Database?

-

-See Limits and Limitations. -

- -

Is it Reliable?

-

-That is not easy to say. It is still a quite new product. A lot of tests have been written, -and the code coverage of these tests is very high. Randomized stress tests -are run regularly. But there are probably still -bugs that have not yet been found (as with most software). Some features are known -to be dangerous, they are only supported for situations where performance is more important -than reliability. Those dangerous features are: -

-
  • Using the transaction isolation level READ_UNCOMMITTED - (LOCK_MODE 0) while at the same time using multiple - connections. -
  • Disabling database file protection using (setting FILE_LOCK to - NO in the database URL). -
  • Disabling referential integrity using SET REFERENTIAL_INTEGRITY FALSE. -
-

-In addition to that, running out of memory should be avoided. -In older versions, OutOfMemory errors while using the database could corrupt a databases. -

-

-Some areas of this database are not fully tested. -When using one of those features for production, please ensure your use case -is well tested (if possible with automated test cases). -Those areas are: -

-
    -
  • Platforms other than Windows XP, Linux, Mac OS X, or JVMs other than Sun 1.5 or 1.6 -
  • The feature MULTI_THREADED -
  • The features AUTO_SERVER and - AUTO_RECONNECT -
  • The file locking method 'Serialized' -
  • The MVCC (multi version concurrency) mode -
  • Cluster mode, 2-phase commit, savepoints -
  • 24/7 operation -
  • Some operations on databases larger than 500 MB may be slower than expected -
  • The optimizer may not always select the best plan -
  • Fulltext search -
  • Operations on LOBs over 2 GB -
-

-Areas considered experimental are: -

-
    -
  • The PostgreSQL server -
  • Multi-threading within the engine using SET MULTI_THREADED=1 -
  • Compatibility modes for other databases (only some features are implemented) -
  • The soft reference cache (CACHE_TYPE=SOFT_LRU). It might not improve performance, - and out of memory issues have been reported. -
-

-Some users have reported that after a power failure, the database cannot be opened sometimes. -In this case, use a backup of the database or the Recover tool. Please report such problems. -The plan is that the database automatically recovers in all situations. -

- -

Column Names are Incorrect?

-

-For the query SELECT ID AS X FROM TEST the method -ResultSetMetaData.getColumnName() returns ID, I expect it to -return X. What's wrong? -

-

-This is not a bug. According the the JDBC specification, the method -ResultSetMetaData.getColumnName() should return the name of the column -and not the alias name. If you need the alias name, use -ResultSetMetaData.getColumnLabel(). -Some other database don't work like this yet (they don't follow the JDBC specification). -If you need compatibility with those databases, use the Compatibility Mode, -or set the system property h2.aliasColumnName. -

-

-This also applies to DatabaseMetaData calls that return a result set. -The columns in the JDBC API are column labels, not column names. -

- -

Float is Double?

-

-For a table defined as CREATE TABLE TEST(X FLOAT) the method -ResultSet.getObject() returns a java.lang.Double, I expect it to -return a java.lang.Float. What's wrong? -

-

-This is not a bug. According the the JDBC specification, the JDBC data type FLOAT -is equivalent to DOUBLE, and both are mapped to java.lang.Double. -See also - -Mapping SQL and Java Types - 8.3.10 FLOAT.

- -

Why is Opening my Database Slow?

-

-To find out what the problem is, use the H2 Console and click on "Test Connection" -instead of "Login". After the "Login Successful" appears, click on it (it's a link). -This will list the top stack traces. Then either analyze this yourself, or -post those stack traces in the Google Group. -

-

-To find out what the problem is, open the database in embedded mode using the H2 Console. -This will print progress information. If you have many lines with 'Creating index' it is an indication that the -database was not closed the last time. -

-

-Other possible reasons are: the database is very big (many GB), or contains linked tables -that are slow to open. -

- -

Is the GCJ Version Stable? Faster?

-

-The GCJ version is not as stable as the Java version. -When running the regression test with the GCJ version, sometimes the application just stops -at what seems to be a random point without error message. -Currently, the GCJ version is also slower than when using the Sun VM. -However, the startup of the GCJ version is faster than when using a VM. -

- -

How to Translate this Project?

-

-For more information, see -Build/Translating. -

- -
diff --git a/tools/h2/src/docsrc/html/features.html b/tools/h2/src/docsrc/html/features.html deleted file mode 100755 index 3a76e3b..0000000 --- a/tools/h2/src/docsrc/html/features.html +++ /dev/null @@ -1,1733 +0,0 @@ - - - - -Features - - - - -
- - -

Features

- - - Feature List
- - Comparison to Other Database Engines
- - H2 in Use
- - Connection Modes
- - Database URL Overview
- - Connecting to an Embedded (Local) Database
- - In-Memory Databases
- - Database Files Encryption
- - Database File Locking
- - Opening a Database Only if it Already Exists
- - Closing a Database
- - Ignore Unknown Settings
- - Changing Other Settings when Opening a Connection
- - Custom File Access Mode
- - Multiple Connections
- - Database File Layout
- - Logging and Recovery
- - Compatibility
- - Auto-Reconnect
- - Automatic Mixed Mode
- - Page Size
- - Using the Trace Options
- - Using Other Logging APIs
- - Read Only Databases
- - Read Only Databases in Zip or Jar File
- - Graceful Handling of Low Disk Space Situations
- - Computed Columns / Function Based Index
- - Multi-Dimensional Indexes
- - Using Passwords
- - User-Defined Functions and Stored Procedures
- - Triggers
- - Compacting a Database
- - Cache Settings
- -

Feature List

-

Main Features

-
    -
  • Very fast database engine -
  • Open source -
  • Written in Java -
  • Supports standard SQL, JDBC API -
  • Embedded and Server mode, Clustering support -
  • Strong security features -
  • The PostgreSQL ODBC driver can be used -
  • Multi version concurrency -
- -

Additional Features

-
    -
  • Disk based or in-memory databases and tables, read-only database support, temporary tables -
  • Transaction support (read committed and serializable transaction isolation), 2-phase-commit -
  • Multiple connections, table level locking -
  • Cost based optimizer, using a genetic algorithm for complex queries, zero-administration -
  • Scrollable and updatable result set support, large result set, external result sorting, - functions can return a result set -
  • Encrypted database (AES or XTEA), SHA-256 password encryption, encryption functions, SSL -
- -

SQL Support

-
    -
  • Support for multiple schemas, information schema -
  • Referential integrity / foreign key constraints with cascade, check constraints -
  • Inner and outer joins, subqueries, read only views and inline views -
  • Triggers and Java functions / stored procedures -
  • Many built-in functions, including XML and lossless data compression -
  • Wide range of data types including large objects (BLOB/CLOB) and arrays -
  • Sequence and autoincrement columns, computed columns (can be used for function based indexes) -
  • ORDER BY, GROUP BY, HAVING, UNION, LIMIT, TOP -
  • Collation support, users, roles -
  • Compatibility modes for IBM DB2, Apache Derby, HSQLDB, - MS SQL Server, MySQL, Oracle, and PostgreSQL. -
- -

Security Features

-
    -
  • Includes a solution for the SQL injection problem -
  • User password authentication uses SHA-256 and salt -
  • For server mode connections, user passwords are never transmitted in plain text over the network - (even when using insecure connections; this only applies to the TCP server and not to the H2 Console however; - it also doesn't apply if you set the password in the database URL) -
  • All database files (including script files that can be used to backup data) can be -encrypted using AES-128 and XTEA encryption algorithms -
  • The remote JDBC driver supports TCP/IP connections over SSL/TLS -
  • The built-in web server supports connections over SSL/TLS -
  • Passwords can be sent to the database using char arrays instead of Strings -
- -

Other Features and Tools

-
    -
  • Small footprint (smaller than 1 MB), low memory requirements -
  • Multiple index types (b-tree, tree, hash) -
  • Support for multi-dimensional indexes -
  • CSV (comma separated values) file support -
  • Support for linked tables, and a built-in virtual 'range' table -
  • EXPLAIN PLAN support, sophisticated trace options -
  • Database closing can be delayed or disabled to improve the performance -
  • Web-based Console application (translated to many languages) with autocomplete -
  • The database can generate SQL script files -
  • Contains a recovery tool that can dump the contents of the database -
  • Support for variables (for example to calculate running totals) -
  • Automatic re-compilation of prepared statements -
  • Uses a small number of database files -
  • Uses a checksum for each record and log entry for data integrity -
  • Well tested (high code coverage, randomized stress tests) -
- -

Comparison to Other Database Engines

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
FeatureH2DerbyHSQLDBMySQLPostgreSQL
Pure JavaYesYesYesNoNo
Embedded Mode (Java)YesYesYesNoNo
Performance (Embedded)FastSlowFastN/AN/A
In-Memory ModeYesYesYesNoNo
Transaction IsolationYesYesNoYesYes
Cost Based OptimizerYesYesNoYesYes
Explain PlanYesNoYesYesYes
ClusteringYesNoNoYesYes
Encrypted DatabaseYesYesNoNoNo
Linked TablesYesNoPartially *1Partially *2No
ODBC DriverYesNoNoYesYes
Fulltext SearchYesNoNoYesYes
User-Defined DatatypesYesNoNoYesYes
Files per DatabaseFewManyFewManyMany
Table Level LockingYesYesNoYesYes
Row Level LockingYes *9YesNoYesYes
Multi Version ConcurrencyYesNoNoYesYes
Role Based SecurityYesYes *3YesYesYes
Updatable Result SetsYesYes *7NoYesYes
SequencesYesNoYesNoYes
Limit and OffsetYesNoYesYesYes
Temporary TablesYesYes *4YesYesYes
Information SchemaYesNo *8No *8YesYes
Computed ColumnsYesNoNoNoYes *6
Case Insensitive ColumnsYesNoYesYesYes *6
Custom Aggregate FunctionsYesNoNoYesYes
Footprint (jar/dll size)~1 MB *5~2 MB~700 KB~4 MB~6 MB
-

-*1 HSQLDB supports text tables.
-*2 MySQL supports linked MySQL tables under the name 'federated tables'.
-*3 Derby support for roles based security and password checking as an option.
-*4 Derby only supports global temporary tables.
-*5 The default H2 jar file contains debug information, jar files for other databases do not.
-*6 PostgreSQL supports functional indexes.
-*7 Derby only supports updatable result sets if the query is not sorted.
-*8 Derby and HSQLDB don't support standard compliant information schema tables.
-*9 H2 supports row level locks when using multi version concurrency. -

- -

Derby and HSQLDB

-

-After an unexpected process termination (for example power failure), H2 can usually -recover safely and automatically without any user interaction. For Derby and HSQLDB, -some manual steps are required ('Another instance of Derby may have already booted the database' / -'The database is already in use by another process'). -

- -

DaffodilDb and One$Db

-

-It looks like the development of this database has stopped. The last release was February 2006. -

- -

McKoi

-

-It looks like the development of this database has stopped. The last release was August 2004 -

- -

H2 in Use

-

-For a list of applications that work with or use H2, see: -Links. -

- -

Connection Modes

-

-The following connection modes are supported: -

-
    -
  • Embedded mode (local connections using JDBC) -
  • Server mode (remote connections using JDBC or ODBC over TCP/IP) -
  • Mixed mode (local and remote connections at the same time) -
- -

Embedded Mode

-

-In embedded mode, an application opens a database from within the same JVM using JDBC. -This is the fastest and easiest connection mode. -The disadvantage is that a database may only be open in one virtual machine (and class loader) at any time. -As in all modes, both persistent and in-memory databases are supported. -There is no limit on the number of database open concurrently, -or on the number of open connections. -

-The database is embedded in the application - -

Server Mode

-

-When using the server mode (sometimes called remote mode or client/server mode), -an application opens a database remotely using the JDBC or ODBC API. -A server needs to be started within the same or another virtual machine, or on another computer. -Many applications can connect to the same database at the same time, by connecting to this server. -Internally, the server process opens the database(s) in embedded mode. -

-

-The server mode is slower than the embedded mode, because all data is transferred over TCP/IP. -As in all modes, both persistent and in-memory databases are supported. -There is no limit on the number of database open concurrently per server, -or on the number of open connections. -

-The database is running in a server; the application connects to the server - -

Mixed Mode

-

-The mixed mode is a combination of the embedded and the server mode. -The first application that connects to a database does that in embedded mode, but also starts -a server so that other applications (running in different processes or virtual machines) can -concurrently access the same data. The local connections are as fast as if -the database is used in just the embedded mode, while the remote -connections are a bit slower. -

-The server can be started and stopped from within the application (using the server API), -or automatically (automatic mixed mode). When using the automatic mixed mode, -all clients that want to connect to the database (no matter if -it's an local or remote connection) can do so using the exact same database URL. -

-The database and the server is running inside the application; another application connects remotely - -

Database URL Overview

-

-This database supports multiple connection modes and connection settings. -This is achieved using different database URLs. Settings in the URLs are not case sensitive. -

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
TopicURL Format and Examples
Embedded (local) connection - jdbc:h2:[file:][<path>]<databaseName>
- jdbc:h2:~/test
- jdbc:h2:file:/data/sample
- jdbc:h2:file:C:/data/sample (Windows only)
-
In-memory (private)jdbc:h2:mem:
In-memory (named) - jdbc:h2:mem:<databaseName>
- jdbc:h2:mem:test_mem -
Server mode (remote connections)
using TCP/IP
- jdbc:h2:tcp://<server>[:<port>]/[<path>]<databaseName>
- jdbc:h2:tcp://localhost/~/test
- jdbc:h2:tcp://dbserv:8084/~/sample - jdbc:h2:tcp://localhost/mem:test
-
Server mode (remote connections)
using SSL/TLS
- jdbc:h2:ssl://<server>[:<port>]/<databaseName>
- jdbc:h2:ssl://secureserv:8085/~/sample; -
Using encrypted files - jdbc:h2:<url>;CIPHER=[AES|XTEA]
- jdbc:h2:ssl://secureserv/~/testdb;CIPHER=AES
- jdbc:h2:file:~/secure;CIPHER=XTEA
-
File locking methods - jdbc:h2:<url>;FILE_LOCK={FILE|SOCKET|NO}
- jdbc:h2:file:~/private;CIPHER=XTEA;FILE_LOCK=SOCKET
-
Only open if it already exists - jdbc:h2:<url>;IFEXISTS=TRUE
- jdbc:h2:file:~/sample;IFEXISTS=TRUE
-
Don't close the database when the VM exits - jdbc:h2:<url>;DB_CLOSE_ON_EXIT=FALSE -
Execute SQL on connection - jdbc:h2:<url>;INIT=RUNSCRIPT FROM '~/create.sql'
- jdbc:h2:file:~/sample;INIT=RUNSCRIPT FROM '~/create.sql'\\;RUNSCRIPT FROM '~/populate.sql'
-
User name and/or password - jdbc:h2:<url>[;USER=<username>][;PASSWORD=<value>]
- jdbc:h2:file:~/sample;USER=sa;PASSWORD=123
-
Debug trace settings - jdbc:h2:<url>;TRACE_LEVEL_FILE=<level 0..3>
- jdbc:h2:file:~/sample;TRACE_LEVEL_FILE=3
-
Ignore unknown settings - jdbc:h2:<url>;IGNORE_UNKNOWN_SETTINGS=TRUE
-
Custom file access mode - jdbc:h2:<url>;ACCESS_MODE_DATA=rws
-
Database in a zip file - jdbc:h2:zip:<zipFileName>!/<databaseName>
- jdbc:h2:zip:~/db.zip!/test -
Compatibility mode - jdbc:h2:<url>;MODE=<databaseType>
- jdbc:h2:~/test;MODE=MYSQL -
Auto-reconnect - jdbc:h2:<url>;AUTO_RECONNECT=TRUE
- jdbc:h2:tcp://localhost/~/test;AUTO_RECONNECT=TRUE -
Automatic mixed mode - jdbc:h2:<url>;AUTO_SERVER=TRUE
- jdbc:h2:~/test;AUTO_SERVER=TRUE -
Page size - jdbc:h2:<url>;PAGE_SIZE=512
-
Changing other settings - jdbc:h2:<url>;<setting>=<value>[;<setting>=<value>...]
- jdbc:h2:file:~/sample;TRACE_LEVEL_SYSTEM_OUT=3
-
- -

Connecting to an Embedded (Local) Database

-

-The database URL for connecting to a local database is -jdbc:h2:[file:][<path>]<databaseName>. -The prefix file: is optional. If no or only a relative path is used, then the current working -directory is used as a starting point. The case sensitivity of the path and database name depend on the -operating system, however it is recommended to use lowercase letters only. -The database name must be at least three characters long -(a limitation of File.createTempFile). -To point to the user home directory, use ~/, as in: jdbc:h2:~/test. -

- -

In-Memory Databases

-

-For certain use cases (for example: rapid prototyping, testing, high performance -operations, read-only databases), it may not be required to persist data, or persist changes to the data. -This database supports the in-memory mode, where the data is not persisted. -

-In some cases, only one connection to a in-memory database is required. -This means the database to be opened is private. In this case, the database URL is -jdbc:h2:mem: Opening two connections within the same virtual machine -means opening two different (private) databases. -

-Sometimes multiple connections to the same in-memory database are required. -In this case, the database URL must include a name. Example: jdbc:h2:mem:db1. -Accessing the same database using this URL only works within the same virtual machine and -class loader environment. -

-In-memory can be accessed remotely -(or from multiple processes in the same machine) using TCP/IP or SSL/TLS. -An example database URL is: jdbc:h2:tcp://localhost/mem:db1. -

-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 -jdbc:h2:mem:test;DB_CLOSE_DELAY=-1. -

- -

Database Files Encryption

-

-The database files can be encrypted. Two encryption algorithms are supported: AES and XTEA. -To use file encryption, you need to specify the encryption algorithm (the 'cipher') -and the file password (in addition to the user password) when connecting to the database. -

- -

Creating a New Database with File Encryption

-

-By default, a new database is automatically created if it does not exist yet. -To create an encrypted database, connect to it as it would already exist. -

- -

Connecting to an Encrypted Database

-

-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 separates the file password -and the user password; the file password itself may not contain spaces. File passwords -and user passwords are case sensitive. Here is an example to connect to a -password-encrypted database: -

-
-Class.forName("org.h2.Driver");
-String url = "jdbc:h2:~/test;CIPHER=AES";
-String user = "sa";
-String pwds = "filepwd userpwd";
-conn = DriverManager.
-    getConnection(url, user, pwds);
-
- -

Encrypting or Decrypting a Database

-

-To encrypt an existing database, use the ChangeFileEncryption tool. -This tool can also decrypt an encrypted database, or change the file encryption key. -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: -

-
-java -cp h2*.jar org.h2.tools.ChangeFileEncryption -dir ~ -db test -cipher AES -encrypt filepwd
-
- -

Database File Locking

-

-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. -

-The following file locking methods are implemented: -

-
    -
  • The default method is FILE and uses a watchdog thread to -protect the database file. The watchdog reads the lock file each second. -
  • 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 one (and always the same) computer. -
  • 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. -Failing to do so will result in a corrupted database. -Using the method NO forces the database to not create a lock file at all. -Please note that this is unsafe as another process is able to open the same database, -possibly leading to data corruption.
-

-To open the database with a different file locking method, use the parameter -FILE_LOCK. -The following code opens the database with the 'socket' locking method: -

-
-String url = "jdbc:h2:~/test;FILE_LOCK=SOCKET";
-
-

-For more information about the algorithms, see -Advanced / File Locking Protocols. -

- -

Opening a Database Only if it Already Exists

-

-By default, when an application calls DriverManager.getConnection(url, ...) -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 databases, and only allow to open -existing databases. To do this, add ;IFEXISTS=TRUE -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: -

-
-String url = "jdbc:h2:/data/sample;IFEXISTS=TRUE";
-
- -

Closing a Database

- -

Delayed Database Closing

-

-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 one 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. The following statement -will keep a database open for 10 seconds after the last connection was closed: -

-
-SET DB_CLOSE_DELAY 10
-
-

-The value -1 means the database is not 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: jdbc:h2:~/test;DB_CLOSE_DELAY=10. -

- -

Don't Close a Database when the VM Exits

-

-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, 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. -The first connection (the one that is opening the database) needs to -set the option in the database URL (it is not possible to change the setting afterwards). -The database URL to disable database closing on exit is: -

-
-String url = "jdbc:h2:~/test;DB_CLOSE_ON_EXIT=FALSE";
-
- -

Execute SQL on Connection

-

-Sometimes, particularly for in-memory databases, it is useful to be able to execute DDL or DML -commands automatically when a client connects to a database. This functionality is enabled via -the INIT property. Note that multiple commands may be passed to INIT, but the semicolon delimiter -must be escaped, as in the example below. -

-
-String url = "jdbc:h2:mem;INIT=RUNSCRIPT FROM '~/create.sql'\\;RUNSCRIPT FROM '~/populate.sql'";
-
- -

Ignore Unknown Settings

-

-Some applications (for example OpenOffice.org Base) pass some additional parameters -when connecting to the database. Why those parameters are passed is unknown. -The parameters PREFERDOSLIKELINEENDS and -IGNOREDRIVERPRIVILEGES are such examples; -they are simply ignored to improve the compatibility with OpenOffice.org. If an application -passes other parameters when connecting to the database, usually the database throws an exception -saying the parameter is not supported. It is possible to ignored such parameters by adding -;IGNORE_UNKNOWN_SETTINGS=TRUE to the database URL. -

- -

Changing Other Settings when Opening a Connection

-

-In addition to the settings already described, -other database settings can be passed in the database URL. -Adding ;setting=value at the end of a database URL is the -same as executing the statement SET setting value just after -connecting. For a list of supported settings, see SQL Grammar. -

- -

Custom File Access Mode

-

-Usually, the database opens the database file with the access mode -rw, meaning read-write (except for read only databases, -where the mode r is used). -To open a database in read-only mode if the database file is not read-only, use -ACCESS_MODE_DATA=r. -Also supported are rws and rwd. -This setting must be specified in the database URL: -

-
-String url = "jdbc:h2:~/test;ACCESS_MODE_DATA=rws";
-
-

-For more information see Durability Problems. -On many operating systems the access mode rws does not guarantee that the data is written to the disk. -

- -

Multiple Connections

- -

Opening Multiple Databases at the Same Time

-

-An application can open multiple databases at the same time, including multiple -connections to the same database. The number of open database is only limited by the memory available. -

- -

Multiple Connections to the Same Database: Client/Server

-

-If you want to access the same database at the same time from different processes or computers, -you need to use the client / server mode. In this case, one process acts as the server, and the -other processes (that could reside on other computers as well) connect to the server via TCP/IP -(or SSL/TLS over TCP/IP for improved security). -

- -

Multithreading Support

-

-This database is multithreading-safe. That means, if an application is multi-threaded, it does not need -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. -

-

-An application should normally use one connection per thread. This database synchronizes -access to the same connection, but other databases may not do this. -

- -

Locking, Lock-Timeout, Deadlocks

-

-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). -All locks are released when the transaction commits or rolls back. -When using the default transaction isolation level 'read committed', read locks are already released after each statement. -

-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 a connection cannot get a lock for a specified time, -then a lock timeout exception is thrown. -

-Usually, SELECT statements 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. -The following statements generate locks: -

- - - - - - - - - - - - - - - - - - - - - -
Type of LockSQL Statement
ReadSELECT * FROM TEST;
- CALL SELECT MAX(ID) FROM TEST;
- SCRIPT;
WriteSELECT * FROM TEST WHERE 1=0 FOR UPDATE;
WriteINSERT INTO TEST VALUES(1, 'Hello');
- INSERT INTO TEST SELECT * FROM TEST;
- UPDATE TEST SET NAME='Hi';
- DELETE FROM TEST;
WriteALTER TABLE TEST ...;
- CREATE INDEX ... ON TEST ...;
- DROP INDEX ...;
-

-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 <milliseconds>. -The initial lock timeout (that is the timeout used for new connections) can be set using the SQL command -SET DEFAULT_LOCK_TIMEOUT <milliseconds>. The default lock timeout is persistent. -

- -

Database File Layout

-

-The following files are created for persistent databases: -

- - - - - - -
File NameDescriptionNumber of Files
- test.h2.db - - Database file.
- Contains the transaction log, indexes, and data for all tables.
- Format: <database>.h2.db -
- 1 per database -
- test.lock.db - - Database lock file.
- Automatically (re-)created while the database is in use.
- Format: <database>.lock.db -
- 1 per database (only if in use) -
- test.trace.db - - Trace file (if the trace option is enabled).
- Contains trace information.
- Format: <database>.trace.db
- Renamed to <database>.trace.db.old is too big. -
- 0 or 1 per database -
- test.lobs.db/* - - Directory containing one file for each
- BLOB or CLOB value larger than a certain size.
- Format: <id>.t<tableId>.lob.db -
- 1 per large object -
- test.123.temp.db - - Temporary file.
- Contains a temporary blob or a large result set.
- Format: <database>.<id>.temp.db -
- 1 per object -
- -

Moving and Renaming Database Files

-

-Database name and location are not stored inside the database files. -

-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 of the same database start with the same -name and the respective extensions are unchanged). -

-As there is no platform specific data in the files, they can be moved to other operating systems -without problems. -

- -

Backup

-

-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. -

-To backup data while the database is running, the SQL command SCRIPT can be used. -

- -

Logging and Recovery

-

-Whenever data is modified in the database and those changes are committed, the changes are written -to the transaction log (except for in-memory objects). The changes to the main data area itself are usually written -later on, to optimize disk access. If there is a power failure, the main data area is not up-to-date, -but because the changes are in the transaction log, the next time the database is opened, the changes -are re-applied automatically. -

- -

Compatibility

-

-All database engines behave a little bit different. Where possible, H2 supports the ANSI SQL standard, -and tries to be compatible to other databases. There are still a few differences however: -

-

-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). -

- -

Compatibility Modes

-

-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 differences to the regular mode: -

- -

DB2 Compatibility Mode

-

-To use the IBM DB2 mode, use the database URL jdbc:h2:~/test;MODE=DB2 -or the SQL statement SET MODE DB2. -

-
  • For aliased columns, ResultSetMetaData.getColumnName() - returns the alias name and getTableName() returns - null. -
  • Support for the syntax [OFFSET .. ROW] [FETCH ... ONLY] - as an alternative for LIMIT .. OFFSET. -
  • Concatenating NULL with another value - results in the other value. -
- -

Derby Compatibility Mode

-

-To use the Apache Derby mode, use the database URL jdbc:h2:~/test;MODE=Derby -or the SQL statement SET MODE Derby. -

-
  • For aliased columns, ResultSetMetaData.getColumnName() - returns the alias name and getTableName() returns - null. -
  • For unique indexes, NULL is distinct. - That means only one row with NULL in one of the columns is allowed. -
  • Concatenating NULL with another value - results in the other value. -
- -

HSQLDB Compatibility Mode

-

-To use the HSQLDB mode, use the database URL jdbc:h2:~/test;MODE=HSQLDB -or the SQL statement SET MODE HSQLDB. -

-
  • For aliased columns, ResultSetMetaData.getColumnName() - returns the alias name and getTableName() returns - null. -
  • When converting the scale of decimal data, the number is only converted if the new scale is - smaller than the current scale. Usually, the scale is converted and 0s are added if required. -
  • For unique indexes, NULL is distinct. - That means only one row with NULL in one of the columns is allowed. -
  • Text can be concatenated using '+'. -
- -

MS SQL Server Compatibility Mode

-

-To use the MS SQL Server mode, use the database URL jdbc:h2:~/test;MODE=MSSQLServer -or the SQL statement SET MODE MSSQLServer. -

-
  • For aliased columns, ResultSetMetaData.getColumnName() - returns the alias name and getTableName() returns - null. -
  • Identifiers may be quoted using square brackets as in [Test]. -
  • For unique indexes, NULL is distinct. - That means only one row with NULL in one of the columns is allowed. -
  • Concatenating NULL with another value - results in the other value. -
  • Text can be concatenated using '+'. -
- -

MySQL Compatibility Mode

-

-To use the MySQL mode, use the database URL jdbc:h2:~/test;MODE=MySQL -or the SQL statement SET MODE MySQL. -

-
  • 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. -
  • Creating indexes in the CREATE TABLE statement is allowed using - INDEX(..) or KEY(..). - Example: create table test(id int primary key, name varchar(255), key idx_name(name)); -
  • Meta data calls return identifiers in lower case. -
  • When converting a floating point number to an integer, the fractional - digits are not truncated, but the value is rounded. -
  • Concatenating NULL with another value - results in the other value. -
- -

Oracle Compatibility Mode

-

-To use the Oracle mode, use the database URL jdbc:h2:~/test;MODE=Oracle -or the SQL statement SET MODE Oracle. -

-
  • For aliased columns, ResultSetMetaData.getColumnName() - returns the alias name and getTableName() returns - null. -
  • When using unique indexes, multiple rows with NULL - in all columns are allowed, however it is not allowed to have multiple rows with the - same values otherwise. -
  • Concatenating NULL with another value - results in the other value. -
- -

PostgreSQL Compatibility Mode

-

-To use the PostgreSQL mode, use the database URL jdbc:h2:~/test;MODE=PostgreSQL -or the SQL statement SET MODE PostgreSQL. -

-
  • For aliased columns, ResultSetMetaData.getColumnName() - returns the alias name and getTableName() returns - null. -
  • When converting a floating point number to an integer, the fractional - digits are not be truncated, but the value is rounded. -
  • The system columns CTID and - OID are supported. -
- -

Auto-Reconnect

-

-The auto-reconnect feature causes the JDBC driver to reconnect to -the database if the connection is lost. The automatic re-connect only -occurs when auto-commit is enabled; if auto-commit is disabled, an exception is thrown. -To enable this mode, append ;AUTO_RECONNECT=TRUE to the database URL. -

-

-Re-connecting will open a new session. After an automatic re-connect, -variables and local temporary tables definitions (excluding data) are re-created. -The contents of the system table INFORMATION_SCHEMA.SESSION_STATE -contains all client side state that is re-created. -

-

-If another connection uses the database in exclusive mode (enabled using SET EXCLUSIVE 1 -or SET EXCLUSIVE 2), then this connection will try to re-connect until the exclusive mode ends. -

- -

Automatic Mixed Mode

-

-Multiple processes can access the same database without having to start the server manually. -To do that, append ;AUTO_SERVER=TRUE to the database URL. -You can use the same database URL independent of whether the database is already open or not. -This feature doesn't work with in-memory databases. -

-

-When using this mode, the first connection to the database is made in embedded mode, -and additionally a server is started internally (as a daemon thread). -If the database is already open in another process, the server mode is used automatically. -

-

-The application that opens the first connection to the database uses the embedded mode, -which is faster than the server mode. Therefore the main application should open -the database first if possible. The first connection automatically starts a server on a random port. -This server allows remote connections, however only to this database (to ensure that, -the client reads .lock.db file and sends the the random key that is stored there to the server). -When the first connection is closed, the server stops. If other (remote) connections are still -open, one of them will then start a server (auto-reconnect is enabled automatically). -

-

-All processes need to have access to the database files. -If the first connection is closed (the connection that started the server), open transactions of other connections will be rolled back -(this may not be a problem if you don't disable autocommit). -Explicit client/server connections (using jdbc:h2:tcp:// or ssl://) are not supported. -This mode is not supported for in-memory databases. -

-

-Here is an example how to use this mode. Application 1 and 2 are not necessarily started -on the same computer, but they need to have access to the database files. Application 1 -and 2 are typically two different processes (however they could run within the same process). -

-
-// Application 1:
-DriverManager.getConnection("jdbc:h2:/data/test;AUTO_SERVER=TRUE");
-
-// Application 2:
-DriverManager.getConnection("jdbc:h2:/data/test;AUTO_SERVER=TRUE");
-
- -

Page Size

-

-The page size for new databases is 2 KB (2048), unless the system property -h2.pageSize is set to a different value, or the page size is set -explicitly in the database URL using PAGE_SIZE=. The page size of -existing databases can not be changed. -

- -

Using the Trace Options

-

-To find problems in an application, it is sometimes good to see what database operations -where executed. This database offers the following trace features: -

-
    -
  • Trace to System.out and/or to a file -
  • Support for trace levels OFF, ERROR, INFO, DEBUG -
  • The maximum size of the trace file can be set -
  • It is possible to generate Java source code from the trace file -
  • Trace can be enabled at runtime by manually creating a file -
- -

Trace Options

-

-The simplest way to enable the trace option is setting it in the database URL. -There are two settings, one for System.out -(TRACE_LEVEL_SYSTEM_OUT) tracing, -and one for file tracing (TRACE_LEVEL_FILE). -The trace levels are -0 for OFF, -1 for ERROR (the default), -2 for INFO, and -3 for DEBUG. -A database URL with both levels set to DEBUG is: -

-
-jdbc:h2:~/test;TRACE_LEVEL_FILE=3;TRACE_LEVEL_SYSTEM_OUT=3
-
-

-The trace level can be changed at runtime by executing the SQL command -SET TRACE_LEVEL_SYSTEM_OUT level (for System.out tracing) -or SET TRACE_LEVEL_FILE level (for file tracing). -Example: -

-
-SET TRACE_LEVEL_SYSTEM_OUT 3
-
- -

Setting the Maximum Size of the Trace File

-

-When using a high trace level, the trace file can get very big quickly. -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 such file exists, it is deleted. -To limit the size to a certain number of megabytes, use -SET TRACE_MAX_FILE_SIZE mb. -Example: -

-
-SET TRACE_MAX_FILE_SIZE 1
-
- -

Java Code Generation

-

-When setting the trace level to INFO or DEBUG, -Java source code is generated as well. This simplifies reproducing problems. The trace file looks like this: -

-
-...
-12-20 20:58:09 jdbc[0]:
-/**/dbMeta3.getURL();
-12-20 20:58:09 jdbc[0]:
-/**/dbMeta3.getTables(null, "", null, new String[]{"TABLE", "VIEW"});
-...
-
-

-To filter the Java source code, use the ConvertTraceFile tool as follows: -

-
-java -cp h2*.jar org.h2.tools.ConvertTraceFile
-    -traceFile "~/test.trace.db" -javaClass "Test"
-
-

-The generated file Test.java 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. -

- -

Using Other Logging APIs

-

-By default, this database uses its own native 'trace' facility. This facility is called 'trace' and not -'log' within this database to avoid confusion with the transaction log. Trace messages can be -written to both file and System.out. -In most cases, this is sufficient, however sometimes it is better to use the same -facility as the application, for example Log4j. To do that, this database support SLF4J. -

-

-SLF4J is a simple facade for various logging APIs -and allows to plug in the desired implementation at deployment time. -SLF4J supports implementations such as Logback, Log4j, Jakarta Commons Logging (JCL), -Java logging, x4juli, and Simple Log. -

-

-To enable SLF4J, set the file trace level to 4 in the database URL: -

-
-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 the file <database>.trace.db for error messages. -

- -

Read Only Databases

-

-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 and CALL statements are allowed. -To create a read-only database, close the database. -Then, make the database file read-only. -When you open the database now, it 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(). -

-

-Using the Custom Access Mode r -the database can also be opened in read-only mode, even if the database file is not read only. -

- -

Read Only Databases in Zip or Jar File

-

-To create a read-only database in a zip file, first create a regular persistent database, and then create a backup. -The database must not have pending changes, that means you need to close all connections to the database first. -If you are using a database named test, an easy way to create a zip file is using the -Backup tool. You can start the tool from the command line, or from within the -H2 Console (Tools - Backup). Please note that the database must be closed when the backup -is created. Therefore, the SQL statement BACKUP TO can not be used. -

-

-When the zip file is created, you can open the database in the zip file using the following database URL: -

-
-jdbc:h2:zip:~/data.zip!/test
-
-

-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; therefore large databases are supported as well. The same indexes are used as when using -a regular database. -

- -

Graceful Handling of Low Disk Space Situations

-

-If the database needs more disk space, it calls the database event listener if one is installed. -The application may then delete temporary files, or display a message and wait until -the user has resolved the problem. To install a listener, run the SQL statement -SET DATABASE_EVENT_LISTENER or use a database 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. -

- -

Opening a Corrupted Database

-

-If a database cannot 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. -

- -

Computed Columns / Function Based Index

-

-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, create a computed column with the upper-case version of the original column, -and create an index for this column: -

-
-CREATE TABLE ADDRESS(
-    ID INT PRIMARY KEY,
-    NAME VARCHAR,
-    UPPER_NAME VARCHAR AS UPPER(NAME)
-);
-CREATE INDEX IDX_U_NAME ON ADDRESS(UPPER_NAME);
-
-

-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: -

-
-INSERT INTO ADDRESS(ID, NAME) VALUES(1, 'Miller');
-SELECT * FROM ADDRESS WHERE UPPER_NAME='MILLER';
-
- -

Multi-Dimensional Indexes

-

-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. -

-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). -

-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. -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. -

- -

Using Passwords

- -

Using Secure Passwords

-

-Remember that weak passwords can be broken regardless of the encryption and security protocols. -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: -

-i'sE2rtPiUKtT from the sentence it's easy to remember this password if you know the trick. -

- -

Passwords: Using Char Arrays instead of Strings

-

-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). -

-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. -

-This database supports using char arrays instead of string to pass user and file passwords. -The following code can be used to do that: -

-
-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();
-    }
-}
-
-

-This example requires Java 1.6. -When using Swing, use javax.swing.JPasswordField. -

- -

Passing the User Name and/or Password in the URL

-

-Instead of passing the user name as a separate parameter as in - -Connection conn = DriverManager. - getConnection("jdbc:h2:~/test", "sa", "123"); - -the user name (and/or password) can be supplied in the URL itself: - -Connection conn = DriverManager. - getConnection("jdbc:h2:~/test;USER=sa;PASSWORD=123"); - -The settings in the URL override the settings passed as a separate parameter. -

- -

User-Defined Functions and Stored Procedures

-

-In addition to the built-in functions, this database supports user-defined Java functions. -In this database, Java functions can be used as stored procedures as well. -A function must be declared (registered) before it can be used. -A function can be defined using source code, or as a reference to -a compiled class that is available in the classpath. By default, the -function aliases are stored in the current schema. -

- -

Referencing a Compiled Method

-

-When referencing a method, the class must already be compiled and -included in the classpath where the database is running. -Only static Java methods are supported; both the class and the method must be public. -Example Java class: -

-
-package acme;
-import java.math.*;
-public class Function {
-    public static boolean isPrime(int value) {
-        return new BigInteger(String.valueOf(value)).isProbablePrime(100);
-    }
-}
-
-

-The Java function must be registered in the database by calling CREATE ALIAS ... FOR: -

-
-CREATE ALIAS IS_PRIME FOR "acme.Function.isPrime";
-
-

-For a complete sample application, see src/test/org/h2/samples/Function.java. -

- -

Declaring Functions as Source Code

-

-When defining a function alias with source code, the database tries to compile -the source code using the Sun Java compiler (the class com.sun.tools.javac.Main) -if the tools.jar is in the classpath. If not, javac is run as a separate -process. Only the source code is stored in the database; the class is compiled each time -the database is re-opened. Source code is usually passed -as dollar quoted text to avoid escaping problems, however single quotes -can be used as well. Example: -

-
-CREATE ALIAS NEXT_PRIME AS $$
-String nextPrime(String value) {
-    return new BigInteger(value).nextProbablePrime().toString();
-}
-$$;
-
-

-The method name (nextPrime in the example above) is ignored. -By default, the three packages java.util, java.math, java.sql are imported. -If different import statements are required, they must be declared at the beginning -and separated with the tag @CODE: -

-
-CREATE ALIAS IP_ADDRESS AS $$
-import java.net.*;
-@CODE
-String ipAddress(String host) throws Exception {
-    return InetAddress.getByName(host).getHostAddress();
-}
-$$;
-
-

-The following template is used to create a complete Java class: -

-
-package org.h2.dynamic;
-< import statements before the tag @CODE; if not set:
-import java.util.*;
-import java.math.*;
-import java.sql.*;
->
-public class <aliasName> {
-    public static <sourceCode>
-}
-
- -

Function Data Type Mapping

-

-Functions that accept non-nullable parameters such as int -will not be called if one of those parameters is NULL. -Instead, 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. -

-

-SQL types are mapped to Java classes and vice-versa as in the JDBC API. For details, see Data Types. -There are two special cases: java.lang.Object is mapped to -OTHER (a serialized object). Therefore, -java.lang.Object can not be used -to match all SQL types (matching all SQL types is not supported). The second special case is Object[]: -arrays of any class are mapped to ARRAY. -

- -

Functions That Require a 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. -

- -

Functions Throwing an Exception

-

-If a function throws an exception, then the current statement is rolled back -and the exception is thrown to the application. -SQLException are directly re-thrown to the calling application; -all other exceptions are first converted to a SQLException. -

- -

Functions Returning a Result Set

-

-Functions may returns a result set. Such a function can be called with the CALL statement: -

-
-public static ResultSet query(Connection conn, String sql) throws SQLException {
-    return conn.createStatement().executeQuery(sql);
-}
-
-CREATE ALIAS QUERY FOR "org.h2.samples.Function.query";
-CALL QUERY('SELECT * FROM TEST');
-
- -

Using SimpleResultSet

-

-A function can create a result set using the SimpleResultSet tool: -

-
-import org.h2.tools.SimpleResultSet;
-...
-public static ResultSet simpleResultSet() throws SQLException {
-    SimpleResultSet rs = new SimpleResultSet();
-    rs.addColumn("ID", Types.INTEGER, 10, 0);
-    rs.addColumn("NAME", Types.VARCHAR, 255, 0);
-    rs.addRow(0, "Hello");
-    rs.addRow(1, "World");
-    return rs;
-}
-
-CREATE ALIAS SIMPLE FOR "org.h2.samples.Function.simpleResultSet";
-CALL SIMPLE();
-
- -

Using a Function as 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 (maybe 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. -

-
-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(x, y);
-        }
-    }
-    return rs;
-}
-
-CREATE ALIAS MATRIX FOR "org.h2.samples.Function.getMatrix";
-SELECT * FROM MATRIX(4) ORDER BY X, Y;
-
- -

Triggers

-

-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. -It is also possible to use triggers to simulate materialized views. -For a complete sample application, see src/test/org/h2/samples/TriggerSample.java. -A Java trigger must implement the interface org.h2.api.Trigger. The trigger class must be available -in the classpath of the database engine (when using the server mode, it must be in the classpath -of the server). -

-
-import org.h2.api.Trigger;
-...
-public class TriggerSample implements Trigger {
-    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 {
-    }
-}
-
-

-The connection can be used to query or update data in other tables. -The trigger then needs to be defined in the database: -

-
-CREATE TRIGGER INV_INS AFTER INSERT ON INVOICE
-    FOR EACH ROW CALL "org.h2.samples.TriggerSample"
-
-

-The trigger can be used to veto a change by throwing a SQLException. -

- -

Compacting a Database

-

-Empty space in the database file re-used automatically. When closing the database, -the database is automatically compacted for up to 1 second by default. To compact more, -use the SQL statement SHUTDOWN COMPACT. However re-creating the database may further -reduce the database size because this will re-build the indexes. -Here is a sample function to do this: -

-
-public static void compact(String dir, String dbName,
-        String user, String password) throws Exception {
-    String url = "jdbc:h2:" + dir + "/" + dbName;
-    String file = "data/test.sql";
-    Script.execute(url, user, password, file);
-    DeleteDbFiles.execute(dir, dbName, true);
-    RunScript.execute(url, user, password, file, null, false);
-}
-
-

-See also the sample application org.h2.samples.Compact. -The commands SCRIPT / RUNSCRIPT can be used as well to create a backup -of a database and re-build the database from the script. -

- -

Cache Settings

-

-The database keeps most frequently used data in the main memory. -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=131072), or it can be changed at runtime using -SET CACHE_SIZE size. -The size of the cache, as represented by CACHE_SIZE is measured in KB, with each KB being 1024 bytes. -This setting has no effect for in-memory databases. -For persistent databases, the setting is stored in the database and re-used when the database is opened -the next time. However, when opening an existing database, the cache size is set to at most -half the amount of memory available for the virtual machine (Runtime.getRuntime().maxMemory()), -even if the cache size setting stored in the database is larger; however the setting stored in the database -is kept. Setting the cache size in the database URL or explicitly using SET CACHE_SIZE -overrides this value (even if larger than the physical memory). -To get the current used maximum cache size, use the query -SELECT * FROM INFORMATION_SCHEMA.SETTINGS WHERE NAME = 'info.CACHE_MAX_SIZE' -

-Also included is an experimental second level soft reference cache. Rows in this cache are only garbage collected -on low memory. By default the second level cache is disabled. To enable it, -use the prefix SOFT_. Example: jdbc:h2:~/test;CACHE_TYPE=SOFT_LRU. -The cache might not actually improve performance. If you plan to use it, -please run your own test cases first. -

-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. -

- -
- diff --git a/tools/h2/src/docsrc/html/fragments.html b/tools/h2/src/docsrc/html/fragments.html deleted file mode 100755 index b93573f..0000000 --- a/tools/h2/src/docsrc/html/fragments.html +++ /dev/null @@ -1,119 +0,0 @@ - - - - Fragments - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/tools/h2/src/docsrc/html/frame.html b/tools/h2/src/docsrc/html/frame.html deleted file mode 100755 index 81a748c..0000000 --- a/tools/h2/src/docsrc/html/frame.html +++ /dev/null @@ -1,40 +0,0 @@ - - - - H2 Database Engine - - - - - -

H2 Database Engine

-

-Welcome to H2, the free SQL database. The main feature of H2 are: -

-
    -
  • It is free to use for everybody, source code is included -
  • Written in Java, but also available as native executable -
  • JDBC and (partial) ODBC API -
  • Embedded and client/server modes -
  • Clustering is supported -
  • A web client is included -
- -

No Javascript

-

-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. -

-Please enable Javascript, or go ahead without it: -H2 Database Engine -

- - \ No newline at end of file diff --git a/tools/h2/src/docsrc/html/functions.html b/tools/h2/src/docsrc/html/functions.html deleted file mode 100755 index 32f03eb..0000000 --- a/tools/h2/src/docsrc/html/functions.html +++ /dev/null @@ -1,176 +0,0 @@ - - - - -Functions - - - - -
- - -

Functions

- -

Aggregate Functions

- - - - - - -
- - ${item.topic}
-
-
- - ${item.topic}
-
-
- - ${item.topic}
-
-
- - -

Numeric Functions

- - - - - - -
- - ${item.topic}
-
-
- - ${item.topic}
-
-
- - ${item.topic}
-
-
- - -

String Functions

- - - - - - -
- - ${item.topic}
-
-
- - ${item.topic}
-
-
- - ${item.topic}
-
-
- - -

Time and Date Functions

- - - - - - -
- - ${item.topic}
-
-
- - ${item.topic}
-
-
- - ${item.topic}
-
-
- - -

System Functions

- - - - - - -
- - ${item.topic}
-
-
- - ${item.topic}
-
-
- - ${item.topic}
-
-
- - - -

${item.topic}

- -${item.railroad} - - -

${item.text}

-

Example:

-

${item.example}

-
- -
- diff --git a/tools/h2/src/docsrc/html/grammar.html b/tools/h2/src/docsrc/html/grammar.html deleted file mode 100755 index 5aa04a5..0000000 --- a/tools/h2/src/docsrc/html/grammar.html +++ /dev/null @@ -1,193 +0,0 @@ - - - - -SQL Grammar - - - - -
- - -

SQL Grammar

-

Commands (Data Manipulation)

- - - - - - -
- - ${item.topic}
-
-
- - ${item.topic}
-
-
- - ${item.topic}
-
-
- - -

Commands (Data Definition)

- - - - - - -
- - ${item.topic}
-
-
- - ${item.topic}
-
-
- - ${item.topic}
-
-
- - -

Commands (Other)

- - - - - - -
- - ${item.topic}
-
-
- - ${item.topic}
-
-
- - ${item.topic}
-
-
- - -

Other Grammar

- - - - - - -
- - ${item.topic}
-
-
- - ${item.topic}
-
-
- - ${item.topic}
-
-
- - -

System Tables

-

-Information Schema
-Range Table
-

- - -

${item.topic}

- -${item.railroad} - - -

${item.text}

-

Example:

-

-${item.example}

-
- - -

${item.topic}

- -${item.railroad} - - -

${item.text}

-

Example:

-

${item.example}

-
- -

Information Schema

-

-The system tables in the schema INFORMATION_SCHEMA contain the meta data -of all tables in the database as well as the current settings. -

- - - - - - - -
TableColumns
${item.topic}${item.syntax}
- -

Range Table

-

-The range table is a dynamic system table that contains all values from a start to an end value. -The table contains one column called X. Both the start and end values are included in the result. -The table is used as follows: -

-

Example:

-
-SELECT X FROM SYSTEM_RANGE(1, 10);
-
- -
diff --git a/tools/h2/src/docsrc/html/history.html b/tools/h2/src/docsrc/html/history.html deleted file mode 100755 index 807cb3b..0000000 --- a/tools/h2/src/docsrc/html/history.html +++ /dev/null @@ -1,130 +0,0 @@ - - - - -History - - - - -
- - -

History and Roadmap

- - Change Log
- - Roadmap
- - History of this Database Engine
- - Why Java
- - Supporters
- -

Change Log

-

-The up-to-date change log is available at - -http://www.h2database.com/html/changelog.html - -

- -

Roadmap

-

-The current roadmap is available at - -http://www.h2database.com/html/roadmap.html - -

- -

History of this Database Engine

-

-The development of H2 was started in May 2004, -but it was first published on December 14th 2005. -The main author of H2, Thomas Mueller, is also the original developer of Hypersonic SQL. -In 2001, he joined PointBase Inc. where he wrote PointBase Micro, a commercial Java SQL database. -At that point, he had to discontinue Hypersonic SQL. The HSQLDB Group was formed -to continued to work on the Hypersonic SQL codebase. -The name H2 stands for Hypersonic 2, however H2 does not share code with -Hypersonic SQL or HSQLDB. H2 is built from scratch. -

- -

Why Java

-

-The main reasons to use a Java database are: -

-
    -
  • Very simple to integrate in Java applications -
  • Support for many different platforms -
  • More secure than native applications (no buffer overflows) -
  • User defined functions (or triggers) run very fast -
  • Unicode support -
-

-Some think Java is too slow for low level operations, -but this is no longer true. Garbage collection for example is -now faster than manual memory management. -

-Developing Java code is faster than developing C or C++ code. When using Java, -most time can be spent on improving the algorithms instead of -porting the code to different platforms or doing memory management. -Features such as Unicode and network libraries are already built-in. -In Java, writing secure code is easier because buffer overflows can not occur. -Features such as reflection can be used for randomized testing. -

-Java is future proof: a lot of companies support Java. Java is now open source. -

-To increase the portability and ease of use, this software depends on -very few libraries. Features that are not available in open source -Java implementations (such as Swing) are not used, or only used for optional features. -

- -

Supporters

-

-Many thanks for those who reported bugs, gave valuable feedback, -spread the word, and translated this project. Also many thanks to the donors: -

- - -
- diff --git a/tools/h2/src/docsrc/html/images/connection-mode-embedded.png b/tools/h2/src/docsrc/html/images/connection-mode-embedded.png deleted file mode 100755 index ffbccfc..0000000 Binary files a/tools/h2/src/docsrc/html/images/connection-mode-embedded.png and /dev/null differ diff --git a/tools/h2/src/docsrc/html/images/connection-mode-mixed.png b/tools/h2/src/docsrc/html/images/connection-mode-mixed.png deleted file mode 100755 index a3a3970..0000000 Binary files a/tools/h2/src/docsrc/html/images/connection-mode-mixed.png and /dev/null differ diff --git a/tools/h2/src/docsrc/html/images/connection-mode-remote.png b/tools/h2/src/docsrc/html/images/connection-mode-remote.png deleted file mode 100755 index 50bba17..0000000 Binary files a/tools/h2/src/docsrc/html/images/connection-mode-remote.png and /dev/null differ diff --git a/tools/h2/src/docsrc/html/images/console.png b/tools/h2/src/docsrc/html/images/console.png deleted file mode 100755 index 39a7ef5..0000000 Binary files a/tools/h2/src/docsrc/html/images/console.png and /dev/null differ diff --git a/tools/h2/src/docsrc/html/images/db-16.png b/tools/h2/src/docsrc/html/images/db-16.png deleted file mode 100755 index d5340e5..0000000 Binary files a/tools/h2/src/docsrc/html/images/db-16.png and /dev/null differ diff --git a/tools/h2/src/docsrc/html/images/download.png b/tools/h2/src/docsrc/html/images/download.png deleted file mode 100755 index 51748dc..0000000 Binary files a/tools/h2/src/docsrc/html/images/download.png and /dev/null differ diff --git a/tools/h2/src/docsrc/html/images/h2-logo.png b/tools/h2/src/docsrc/html/images/h2-logo.png deleted file mode 100755 index 76402f0..0000000 Binary files a/tools/h2/src/docsrc/html/images/h2-logo.png and /dev/null differ diff --git a/tools/h2/src/docsrc/html/images/h2-logo_square.png b/tools/h2/src/docsrc/html/images/h2-logo_square.png deleted file mode 100755 index 2714448..0000000 Binary files a/tools/h2/src/docsrc/html/images/h2-logo_square.png and /dev/null differ diff --git a/tools/h2/src/docsrc/html/images/icon_disconnect.gif b/tools/h2/src/docsrc/html/images/icon_disconnect.gif deleted file mode 100755 index 2ece8d8..0000000 Binary files a/tools/h2/src/docsrc/html/images/icon_disconnect.gif and /dev/null differ diff --git a/tools/h2/src/docsrc/html/images/language_de.png b/tools/h2/src/docsrc/html/images/language_de.png deleted file mode 100755 index 0109c35..0000000 Binary files a/tools/h2/src/docsrc/html/images/language_de.png and /dev/null differ diff --git a/tools/h2/src/docsrc/html/images/language_en.gif b/tools/h2/src/docsrc/html/images/language_en.gif deleted file mode 100755 index a48f4ad..0000000 Binary files a/tools/h2/src/docsrc/html/images/language_en.gif and /dev/null differ diff --git a/tools/h2/src/docsrc/html/images/language_ja.gif b/tools/h2/src/docsrc/html/images/language_ja.gif deleted file mode 100755 index 5e1d040..0000000 Binary files a/tools/h2/src/docsrc/html/images/language_ja.gif and /dev/null differ diff --git a/tools/h2/src/docsrc/html/images/mail-support.png b/tools/h2/src/docsrc/html/images/mail-support.png deleted file mode 100755 index 8ff5349..0000000 Binary files a/tools/h2/src/docsrc/html/images/mail-support.png and /dev/null differ diff --git a/tools/h2/src/docsrc/html/images/performance.png b/tools/h2/src/docsrc/html/images/performance.png deleted file mode 100755 index 368fbf7..0000000 Binary files a/tools/h2/src/docsrc/html/images/performance.png and /dev/null differ diff --git a/tools/h2/src/docsrc/html/images/quickstart-1.png b/tools/h2/src/docsrc/html/images/quickstart-1.png deleted file mode 100755 index 276680c..0000000 Binary files a/tools/h2/src/docsrc/html/images/quickstart-1.png and /dev/null differ diff --git a/tools/h2/src/docsrc/html/images/quickstart-2.png b/tools/h2/src/docsrc/html/images/quickstart-2.png deleted file mode 100755 index ee9fd9d..0000000 Binary files a/tools/h2/src/docsrc/html/images/quickstart-2.png and /dev/null differ diff --git a/tools/h2/src/docsrc/html/images/quickstart-3.png b/tools/h2/src/docsrc/html/images/quickstart-3.png deleted file mode 100755 index fba9e42..0000000 Binary files a/tools/h2/src/docsrc/html/images/quickstart-3.png and /dev/null differ diff --git a/tools/h2/src/docsrc/html/images/quickstart-4.png b/tools/h2/src/docsrc/html/images/quickstart-4.png deleted file mode 100755 index 08a02b5..0000000 Binary files a/tools/h2/src/docsrc/html/images/quickstart-4.png and /dev/null differ diff --git a/tools/h2/src/docsrc/html/images/quickstart-5.png b/tools/h2/src/docsrc/html/images/quickstart-5.png deleted file mode 100755 index b2f007d..0000000 Binary files a/tools/h2/src/docsrc/html/images/quickstart-5.png and /dev/null differ diff --git a/tools/h2/src/docsrc/html/images/quickstart-6.png b/tools/h2/src/docsrc/html/images/quickstart-6.png deleted file mode 100755 index e981477..0000000 Binary files a/tools/h2/src/docsrc/html/images/quickstart-6.png and /dev/null differ diff --git a/tools/h2/src/docsrc/html/images/screenshot.png b/tools/h2/src/docsrc/html/images/screenshot.png deleted file mode 100755 index 9d7d7e6..0000000 Binary files a/tools/h2/src/docsrc/html/images/screenshot.png and /dev/null differ diff --git a/tools/h2/src/docsrc/html/installation.html b/tools/h2/src/docsrc/html/installation.html deleted file mode 100755 index 395d633..0000000 --- a/tools/h2/src/docsrc/html/installation.html +++ /dev/null @@ -1,114 +0,0 @@ - - - - -Installation - - - - -
- - -

Installation

- - - Requirements
- - Supported Platforms
- - Installing the Software
- - Directory Structure
- -

Requirements

-

-To run the database, the following minimum software stack is known to work: -

-
    -
  • Windows XP or Vista, Mac OS X, or Linux -
  • Recommended Windows file system: NTFS (FAT32 only supports files up to 4 GB) -
  • Sun JDK 1.5 or newer -
  • Mozilla Firefox -
- -

Supported Platforms

-

-As this database is written in Java, it can run on many different platforms. -It is tested with Java 1.5 and 1.6 but can also be compiled to native code using GCJ. -The source code does not use features of Java 1.6. Currently, the database is -developed and tested on Windows XP and Mac OS X using the Sun JDK 1.5, but it also -works in many other operating systems and using other Java runtime environments. -

- -

Installing the Software

-

-To install the software, run the installer or unzip it to a directory of your choice. -

- -

Directory Structure

-

-After installing, you should get the following directory structure: -

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
DirectoryContents
binJAR and batch files
docsDocumentation
docs/htmlHTML pages
docs/javadocJavadoc files
extExternal dependencies (downloaded when building)
serviceTools to run the database as a Windows Service
srcSource files
src/docsrcDocumentation sources
src/installerInstaller, shell, and release build script
src/mainDatabase engine source code
src/testTest source code
src/toolsTools and database adapters source code
- -
- diff --git a/tools/h2/src/docsrc/html/jaqu.html b/tools/h2/src/docsrc/html/jaqu.html deleted file mode 100755 index da3dce9..0000000 --- a/tools/h2/src/docsrc/html/jaqu.html +++ /dev/null @@ -1,328 +0,0 @@ - - - - -JaQu - - - - -
- - -

JaQu

- - What is JaQu
- - Differences to Other Data Access Tools
- - Current State
- - Building the JaQu Library
- - Requirements
- - Example Code
- - Configuration
- - Natural Syntax
- - Other Ideas
- - Similar Projects
- -

What is JaQu

-

-JaQu stands for Java Query and allows to access databases using pure Java. -JaQu provides a fluent interface (or internal DSL) to access a database. -JaQu is something like LINQ for Java (LINQ stands for "language integrated query" and is a -Microsoft .NET technology). The following JaQu code: -

-
-Product p = new Product();
-List<Product> soldOutProducts =
-    db.from(p).where(p.unitsInStock).is(0).select();
-
-

-stands for the SQL statement: -

-
-SELECT * FROM PRODUCTS P
-WHERE P.UNITS_IN_STOCK = 0
-
- -

Differences to Other Data Access Tools

-

-Unlike SQL, JaQu can be easily integrated in Java applications. Because JaQu is pure Java, -auto-complete in the IDE and Javadoc and are supported. Type checking is performed by the compiler. -JaQu fully protects against SQL injection. -

-

-JaQu is more a replacement for JDBC than it is a replacement for tools like Hibernate. -With JaQu, you don't write SQL statements as Strings. -JaQu is much smaller and simpler than other persistence frameworks such as Hibernate, -but it also does not provide all the features of those. -Unlike iBatis and Hibernate, no XML or annotation based configuration is required; -instead the configuration (if required at all) is done in pure Java, in the application itself. -

-

-JaQu does not require or contain any data caching mechanism. Like JDBC and iBatis, -JaQu provides full control over when and what SQL statements are executed -(but without having to write SQL statements as Strings). -

- -

Restrictions

-

-Primitive types (eg. boolean, int, long, double) are not supported. -Use java.lang.Boolean, Integer, Long, Double instead. -

- -

Why in Java?

-

-Most people use Java in their application. Mixing Java and another language (for example Scala or Groovy) -in the same application is complicated: you would need to split the application and database code. -

- -

Current State

-

-Currently, JaQu is only tested with the H2 database. The API may change in future versions. -JaQu is not part of the h2 jar file, however the source code is included in H2, under: -

-
  • src/test/org/h2/test/jaqu/* (samples and tests) -
  • src/tools/org/h2/jaqu/* (framework) -
- -

Building the JaQu Library

-

-To create the JaQu jar file, run: build jarJaqu. This will create the file bin/h2jaqu.jar. -

- -

Requirements

-

-JaQu requires Java 1.5. Annotations are not need. -Currently, JaQu is only tested with the H2 database engine, however in theory it should -work with any database that supports the JDBC API. -

- -

Example Code

-
-package org.h2.test.jaqu;
-import java.math.BigDecimal;
-import java.util.List;
-import org.h2.jaqu.Db;
-import static org.h2.jaqu.Function.*;
-
-public class Test {
-    Db db;
-
-    public static void main(String[] args) throws Exception {
-        new SamplesTest().test();
-    }
-
-    public void test() throws Exception {
-        db = Db.open("jdbc:h2:mem:", "sa", "sa");
-        db.insertAll(Product.getProductList());
-        db.insertAll(Customer.getCustomerList());
-        db.insertAll(Order.getOrderList());
-        testLength();
-        testCount();
-        testGroup();
-        testSelectManyCompoundFrom2();
-        testWhereSimple4();
-        testSelectSimple2();
-        testAnonymousTypes3();
-        testWhereSimple2();
-        testWhereSimple3();
-        db.close();
-    }
-
-    private void testWhereSimple2() throws Exception {
-        Product p = new Product();
-        List<Product> soldOutProducts =
-            db.from(p).
-            where(p.unitsInStock).is(0).
-            orderBy(p.productId).select();
-    }
-
-    private void testWhereSimple3() throws Exception {
-        Product p = new Product();
-        List<Product> expensiveInStockProducts =
-            db.from(p).
-            where(p.unitsInStock).bigger(0).
-            and(p.unitPrice).bigger(3.0).
-            orderBy(p.productId).select();
-    }
-
-    private void testWhereSimple4() throws Exception {
-        Customer c = new Customer();
-        List<Customer> waCustomers =
-            db.from(c).
-            where(c.region).is("WA").
-            select();
-    }
-
-    private void testSelectSimple2() throws Exception {
-        Product p = new Product();
-        List<String> productNames =
-            db.from(p).
-            orderBy(p.productId).select(p.productName);
-    }
-
-    public static class ProductPrice {
-        public String productName;
-        public String category;
-        public Double price;
-    }
-
-    private void testAnonymousTypes3() throws Exception {
-        final Product p = new Product();
-        List<ProductPrice> productInfos =
-            db.from(p).orderBy(p.productId).
-            select(new ProductPrice() {{
-                    productName = p.productName;
-                    category = p.category;
-                    price = p.unitPrice;
-            }});
-    }
-
-    public static class CustOrder {
-        public String customerId;
-        public Integer orderId;
-        public BigDecimal total;
-    }
-
-    private void testSelectManyCompoundFrom2() throws Exception {
-        final Customer c = new Customer();
-        final Order o = new Order();
-        List<CustOrder> orders =
-            db.from(c).
-            innerJoin(o).on(c.customerId).is(o.customerId).
-            where(o.total).smaller(new BigDecimal("500.00")).
-            orderBy(1).
-            select(new CustOrder() {{
-                customerId = c.customerId;
-                orderId = o.orderId;
-                total = o.total;
-            }});
-    }
-
-    private void testLength() throws Exception {
-        Product p = new Product();
-        List<Integer> lengths =
-            db.from(p).
-            where(length(p.productName)).smaller(10).
-            orderBy(1).
-            selectDistinct(length(p.productName));
-    }
-
-    private void testCount() throws Exception {
-        long count = db.from(new Product()).selectCount();
-    }
-
-    public static class ProductGroup {
-        public String category;
-        public Long productCount;
-    }
-
-    private void testGroup() throws Exception {
-        final Product p = new Product();
-        List<ProductGroup> list =
-            db.from(p).
-            groupBy(p.category).
-            orderBy(1).
-            select(new ProductGroup() {{
-                category = p.category;
-                productCount = count();
-            }});
-    }
-
-}
-
- -

Configuration

-

-JaQu does not require any configuration when using the default mapping. -To define table indices, or if you want to map a class to a table with a different name, -or a field to a column with another name, create a function called define in the data class. -Example: -

-
-public class Product implements Table {
-
-    public Integer productId;
-    public String productName;
-    public String category;
-    public Double unitPrice;
-    public Integer unitsInStock;
-
-    public void define() {
-        tableName("Product");
-        primaryKey(productId);
-        index(productName, category);
-    }
-
-}
-
-

-The method define() contains the mapping definition. It is called once -when the class is used for the first time. Like annotations, the mapping is defined in the class itself. -Unlike when using annotations, the compiler can check the syntax even for multi-column -objects (multi-column indexes, multi-column primary keys and so on). -Because the definition is written in regular Java, the configuration can depend on the environment. -This is not possible using annotations. -Unlike XML mapping configuration, the configuration is integrated in the class itself. -

- -

Natural Syntax

-

The plan is to support more natural (pure Java) syntax in conditions. -To do that, the condition class is de-compiled to a SQL condition. -A proof of concept decompiler is included (but it doesn't work yet). -The planned syntax is: -

-
-long count = db.from(co).
-    where(new Filter() { public boolean where() {
-        return co.id == x
-            && co.name.equals(name)
-            && co.value == new BigDecimal("1")
-            && co.amount == 1L
-            && co.birthday.before(new java.util.Date())
-            && co.created.before(java.sql.Timestamp.valueOf("2005-05-05 05:05:05"))
-            && co.time.before(java.sql.Time.valueOf("23:23:23"));
-        } }).selectCount();
-
- -

Other Ideas

-

-This project has just been started, and nothing is fixed yet. -Some ideas for what to implement are: -

-
  • Support queries on collections (instead of using a database). -
  • Provide API level compatibility with JPA (so that JaQu can be used as an extension of JPA). -
  • Internally use a JPA implementation (for example Hibernate) instead of SQL directly. -
  • Use PreparedStatements and cache them. -
- -

Similar Projects

-

-Cement Framework
-Dreamsource ORM
-Empire-db
-JEQUEL: Java Embedded QUEry Language
-Joist
-JoSQL
-LIQUidFORM
-Quaere (Alias implementation)
-Quaere
-Querydsl
-Squill
-

- -
- diff --git a/tools/h2/src/docsrc/html/license.html b/tools/h2/src/docsrc/html/license.html deleted file mode 100755 index 2be1b25..0000000 --- a/tools/h2/src/docsrc/html/license.html +++ /dev/null @@ -1,701 +0,0 @@ - - - - -License - - - - -
- - -

License

- -

Summary and License FAQ

-

-H2 is dual licensed and available under a modified version of the -MPL 1.1 (Mozilla Public License) -or under the (unmodified) EPL 1.0 (Eclipse Public License). -The changes to the MPL are underlined. -There is a License FAQ for both the MPL and the EPL, most of that is applicable to the H2 License as well. -

-
    -
  • You can use H2 for free. You can integrate it into your application (including commercial applications), - and you can distribute it. -
  • Files containing only your code are not covered by this license (it is 'commercial friendly'). -
  • Modifications to the H2 source code must be published. -
  • You don't need to provide the source code of H2 if you did not modify anything. -
- -

-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: 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. It seems 'bungisoft' does not exist any more, but you can use the -Wayback Machine and visit old web pages of http://www.bungisoft.com. -

-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. -

- -

H2 License, Version 1.0

- -

1. Definitions

-

1.0.1. "Commercial Use" -means distribution or otherwise making the Covered Code available to a third party. -

-

1.1. "Contributor" -means each entity that creates or contributes to the creation of Modifications. -

-

1.2. "Contributor Version" -means the combination of the Original Code, prior Modifications used by a Contributor, -and the Modifications made by that particular Contributor. -

-

1.3. "Covered Code" -means the Original Code or Modifications or the combination of the Original Code and -Modifications, in each case including portions thereof. -

-

1.4. "Electronic Distribution Mechanism" -means a mechanism generally accepted in the software development community for the -electronic transfer of data. -

-

1.5. "Executable" -means Covered Code in any form other than Source Code. -

-

1.6. "Initial Developer" -means the individual or entity identified as the Initial Developer in the Source Code -notice required by Exhibit A. -

-

1.7. "Larger Work" -means a work which combines Covered Code or portions thereof with code not governed -by the terms of this License. -

-

1.8. "License" -means this document. -

-

1.8.1. "Licensable" -means having the right to grant, to the maximum extent possible, whether at the -time of the initial grant or subsequently acquired, any and all of the rights -conveyed herein. -

-

1.9. "Modifications" -means any addition to or deletion from the substance or structure of either the -Original Code or any previous Modifications. When Covered Code is released as a -series of files, a Modification is: -

-

1.9.a. Any addition to or deletion from the contents of a file -containing Original Code or previous Modifications. -

-

1.9.b. Any new file that contains any part of the Original Code or -previous Modifications. -

-

1.10. "Original Code" -means Source Code of computer software code which is described in the Source Code -notice required by Exhibit A as Original Code, and which, -at the time of its release under this License is not already Covered Code governed -by this License. -

-

1.10.1. "Patent Claims" -means any patent claim(s), now owned or hereafter acquired, including without -limitation, method, process, and apparatus claims, in any patent Licensable by -grantor. -

-

1.11. "Source Code" -means the preferred form of the Covered Code for making modifications to it, -including all modules it contains, plus any associated interface definition files, -scripts used to control compilation and installation of an Executable, or source -code differential comparisons against either the Original Code or another well known, -available Covered Code of the Contributor's choice. The Source Code can be in a -compressed or archival form, provided the appropriate decompression or de-archiving -software is widely available for no charge. -

-

1.12. "You" (or "Your") -means an individual or a legal entity exercising rights under, and complying with -all of the terms of, this License or a future version of this License issued under -Section 6.1. For legal entities, "You" includes any entity -which controls, is controlled by, or is under common control with You. For purposes of -this definition, "control" means (a) the power, direct or indirect, to cause the -direction or management of such entity, whether by contract or otherwise, or (b) -ownership of more than fifty percent (50%) of the outstanding shares or beneficial -ownership of such entity. -

- -

2. Source Code License

-

2.1. The Initial Developer Grant

-

-The Initial Developer hereby grants You a world-wide, royalty-free, non-exclusive -license, subject to third party intellectual property claims: -

-

2.1.a. under intellectual property rights (other than patent or -trademark) Licensable by Initial Developer to use, reproduce, modify, display, perform, -sublicense and distribute the Original Code (or portions thereof) with or without -Modifications, and/or as part of a Larger Work; and -

-

2.1.b. under Patents Claims infringed by the making, using or selling -of Original Code, to make, have made, use, practice, sell, and offer for sale, and/or -otherwise dispose of the Original Code (or portions thereof). -

-

2.1.c. the licenses granted in this Section 2.1 -(a) and (b) are effective on -the date Initial Developer first distributes Original Code under the terms of this -License. -

-

2.1.d. Notwithstanding Section 2.1 (b) -above, no patent license is granted: 1) for code that You delete from the Original Code; -2) separate from the Original Code; or 3) for infringements caused by: i) the -modification of the Original Code or ii) the combination of the Original Code with other -software or devices. -

- -

2.2. Contributor Grant

-

-Subject to third party intellectual property claims, each Contributor hereby grants You -a world-wide, royalty-free, non-exclusive license -

-

2.2.a. under intellectual property rights (other than patent or trademark) -Licensable by Contributor, to use, reproduce, modify, display, perform, sublicense and -distribute the Modifications created by such Contributor (or portions thereof) either on -an unmodified basis, with other Modifications, as Covered Code and/or as part of a Larger -Work; and -

-

2.2.b. under Patent Claims infringed by the making, using, or selling of -Modifications made by that Contributor either alone and/or in combination with its -Contributor Version (or portions of such combination), to make, use, sell, offer for -sale, have made, and/or otherwise dispose of: 1) Modifications made by that Contributor -(or portions thereof); and 2) the combination of Modifications made by that Contributor -with its Contributor Version (or portions of such combination). -

-

2.2.c. the licenses granted in Sections 2.2 -(a) and 2.2 (b) are effective -on the date Contributor first makes Commercial Use of the Covered Code. -

-

2.2.c. Notwithstanding Section 2.2 (b) -above, no patent license is granted: 1) for any code that Contributor has deleted from -the Contributor Version; 2) separate from the Contributor Version; 3) for infringements -caused by: i) third party modifications of Contributor Version or ii) the combination of -Modifications made by that Contributor with other software (except as part of the -Contributor Version) or other devices; or 4) under Patent Claims infringed by Covered Code -in the absence of Modifications made by that Contributor. -

- -

3. Distribution Obligations

-

3.1. Application of License

-

-The Modifications which You create or to which You contribute are governed by the terms -of this License, including without limitation Section 2.2. 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 6.1, -and You must include a copy of this License with every copy of the Source Code You -distribute. You may not offer or impose any terms on any Source Code version that alters or -restricts the applicable version of this License or the recipients' rights hereunder. -However, You may include an additional document offering the additional rights described in -Section 3.5. -

- -

3.2. Availability of Source Code

-

-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, -must remain available for at least twelve (12) months after the date it initially became -available, or at least six (6) months after a subsequent version of that particular -Modification has been made available to such recipients. You are responsible for ensuring -that the Source Code version remains available even if the Electronic Distribution -Mechanism is maintained by a third party. -

- -

3.3. Description of Modifications

-

-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 -(a) the Source Code, and (b) in any notice in an Executable version or related documentation -in which You describe the origin or ownership of the Covered Code. -

- -

3.4. Intellectual Property Matters

-

3.4.a. Third Party Claims: -If Contributor has knowledge that a license under a third party's intellectual property -rights is required to exercise the rights granted by such Contributor under Sections -2.1 or 2.2, Contributor must include a -text file with the Source Code distribution titled "LEGAL" which describes the claim and the -party making the claim in sufficient detail that a recipient will know whom to contact. If -Contributor obtains such knowledge after the Modification is made available as described in -Section 3.2, Contributor shall promptly modify the LEGAL file in -all copies Contributor makes available thereafter and shall take other steps (such as -notifying appropriate mailing lists or newsgroups) reasonably calculated to inform those who -received the Covered Code that new knowledge has been obtained. -

-

3.4.b. Contributor APIs: -If Contributor's Modifications include an application programming interface and Contributor -has knowledge of patent licenses which are reasonably necessary to implement that -API, Contributor must also include this information in the legal file. -

-

3.4.c. Representations: -Contributor represents that, except as disclosed pursuant to Section 3.4 -(a) above, Contributor believes that Contributor's Modifications -are Contributor's original creation(s) and/or Contributor has sufficient rights to grant the -rights conveyed by this License. -

- -

3.5. Required Notices

-

-You must duplicate the notice in Exhibit 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 -Modification(s) You may add your name as a Contributor to the notice described in -Exhibit A. You must also duplicate this License in any documentation -for the Source Code where You describe recipients' rights or ownership rights relating to -Covered Code. You may choose to offer, and to charge a fee for, warranty, support, indemnity -or liability obligations to one or more recipients of Covered Code. However, You may do so -only on Your own behalf, and not on behalf of the Initial Developer or any Contributor. You -must make it absolutely clear than any such warranty, support, indemnity or liability -obligation is offered by You alone, and You hereby agree to indemnify the Initial Developer -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. -

- -

3.6. Distribution of Executable Versions

-

-You may distribute Covered Code in Executable form only if the requirements of Sections -3.1, 3.2, -3.3, 3.4 and -3.5 have been met for that Covered Code, and if You include a -notice stating that the Source Code version of the Covered Code is available under the terms -of this License, including a description of how and where You have fulfilled the obligations -of Section 3.2. The notice must be conspicuously included in any -notice in an Executable version, related documentation or collateral in which You describe -recipients' rights relating to the Covered Code. You may distribute the Executable version of -Covered Code or ownership rights under a license of Your choice, which may contain terms -different from this License, provided that You are in compliance with the terms of this -License and that the license for the Executable version does not attempt to limit or alter the -recipient's rights in the Source Code version from the rights set forth in this License. If -You distribute the Executable version under a different license You must make it absolutely -clear that any terms which differ from this License are offered by You alone, not by the -Initial Developer or any Contributor. You hereby agree to indemnify the Initial Developer and -every Contributor for any liability incurred by the Initial Developer or such Contributor as -a result of any such terms You offer. -

- -

3.7. Larger Works

-

-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. -

- -

4. Inability to Comply Due to Statute or Regulation.

-

-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 -legal file described in Section -3.4 and must be included with all distributions of the Source Code. -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. -

- -

5. Application of this License.

-

-This License applies to code to which the Initial Developer has attached the notice in -Exhibit A and to related Covered Code. -

- -

6. Versions of the License.

- -

6.1. New Versions

-

-The H2 Group may publish revised and/or new versions -of the License from time to time. Each version will be given a distinguishing version number. -

- -

6.2. Effect of New Versions

-

-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 H2 Group. -No one other than the H2 Group has the right to modify the terms applicable to Covered Code -created under this License. -

- -

6.3. Derivative Works

-

-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 "H2 Group", "H2" -or any confusingly similar phrase do not appear in your license (except to note that -your license differs from this License) and (b) otherwise make it clear that Your version of -the license contains terms which differ from the H2 License. -(Filling in the name of the Initial Developer, Original Code or Contributor in the -notice described in Exhibit A shall not of themselves be deemed to -be modifications of this License.) -

- -

7. Disclaimer of Warranty

-

-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 -the covered code is with you. Should any covered code prove defective in any respect, you -(not the initial developer or any other contributor) assume the cost of any necessary -servicing, repair or correction. This disclaimer of warranty constitutes an essential part -of this license. No use of any covered code is authorized hereunder except under this -disclaimer. -

- -

8. Termination

-

8.1. This License and the rights granted hereunder will terminate -automatically if You fail to comply with terms herein and fail to cure such breach -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. -

- -

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: -

-

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 -Sections 2.1 and/or 2.2 of this -License shall, upon 60 days notice from Participant terminate prospectively, unless if -within 60 days after receipt of notice You either: (i) agree in writing to pay -Participant a mutually agreeable reasonable royalty for Your past and future use of -Modifications made by such Participant, or (ii) withdraw Your litigation claim with -respect to the Contributor Version against such Participant. If within 60 days of -notice, a reasonable royalty and payment arrangement are not mutually agreed upon in -writing by the parties or the litigation claim is not withdrawn, the rights granted by -Participant to You under Sections 2.1 and/or -2.2 automatically terminate at the expiration of the 60 day -notice period specified above. -

-

8.2.b. any software, hardware, or device, other than such Participant's -Contributor Version, directly or indirectly infringes any patent, then any rights -granted to You by such Participant under Sections 2.1(b) -and 2.2(b) are revoked effective as of the date You first -made, used, sold, distributed, or had made, Modifications made by that Participant. -

- -

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 -initiation of patent infringement litigation, then the reasonable value of the licenses -granted by such Participant under Sections 2.1 or -2.2 shall be taken into account in determining the amount or -value of any payment or license. -

- -

8.4. In the event of termination under Sections -8.1 or 8.2 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. -

- -

9. Limitation of Liability

-

-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 -consequential damages of any character including, without limitation, damages for loss -of goodwill, work stoppage, computer failure or malfunction, or any and all other -commercial damages or losses, even if such party shall have been informed of the -possibility of such damages. This limitation of liability shall not apply to liability -for death or personal injury resulting from such party's negligence to the extent -applicable law prohibits such limitation. Some jurisdictions do not allow the exclusion -or limitation of incidental or consequential damages, so this exclusion and limitation -may not apply to you. -

- -

10. United States Government End Users

-

-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. -

- -

11. Miscellaneous

-

-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 California law provisions (except to the extent applicable law, if any, -provides otherwise), excluding its conflict-of-law provisions. With respect to -disputes in which at least one party is a citizen of, or an entity chartered or -registered to do business in United States of America, any litigation relating to -this License shall be subject to the jurisdiction of the Federal Courts of the Northern District of California, with venue lying in Santa Clara County, California, -with the losing party responsible for costs, including without limitation, court -costs and reasonable attorneys' fees and expenses. The application of the United -Nations Convention on Contracts for the International Sale of Goods is expressly -excluded. Any law or regulation which provides that the language of a contract -shall be construed against the drafter shall not apply to this License. -

- -

12. Responsibility for Claims

-

-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. -

- -

13. Multiple-Licensed Code

-

-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 -described in Exhibit A. -

- -

Exhibit A

-
-Multiple-Licensed under the H2 License, Version 1.0,
-and under the Eclipse Public License, Version 1.0
-(http://h2database.com/html/license.html).
-Initial Developer: H2 Group
-
- -

Eclipse Public License - Version 1.0

-

-THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS ECLIPSE -PUBLIC LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF -THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT. -

- -

1. DEFINITIONS

-

-"Contribution" means: -

-a) in the case of the initial Contributor, the initial code and documentation -distributed under this Agreement, and -

-b) in the case of each subsequent Contributor: -

-i) changes to the Program, and -

-ii) additions to the Program; -

-where such changes and/or additions to the Program originate from and are -distributed by that particular Contributor. A Contribution 'originates' from a -Contributor if it was added to the Program by such Contributor itself or anyone -acting on such Contributor's behalf. Contributions do not include additions to -the Program which: (i) are separate modules of software distributed in conjunction -with the Program under their own license agreement, and (ii) are not derivative -works of the Program. -

-"Contributor" means any person or entity that distributes the Program. -

-"Licensed Patents " mean patent claims licensable by a Contributor which are -necessarily infringed by the use or sale of its Contribution alone or when combined -with the Program. -

-"Program" means the Contributions distributed in accordance with this Agreement. -

-"Recipient" means anyone who receives the Program under this Agreement, -including all Contributors. -

- -

2. GRANT OF RIGHTS

-

-a) Subject to the terms of this Agreement, each Contributor hereby grants Recipient -a non-exclusive, worldwide, royalty-free copyright license to reproduce, prepare -derivative works of, publicly display, publicly perform, distribute and sublicense the -Contribution of such Contributor, if any, and such derivative works, in source code -and object code form. -

-b) Subject to the terms of this Agreement, each Contributor hereby grants -Recipient a non-exclusive, worldwide, royalty-free patent license under Licensed -Patents to make, use, sell, offer to sell, import and otherwise transfer the -Contribution of such Contributor, if any, in source code and object code form. -This patent license shall apply to the combination of the Contribution and the -Program if, at the time the Contribution is added by the Contributor, such addition -of the Contribution causes such combination to be covered by the Licensed -Patents. The patent license shall not apply to any other combinations which -include the Contribution. No hardware per se is licensed hereunder. -

-c) Recipient understands that although each Contributor grants the licenses to -its Contributions set forth herein, no assurances are provided by any Contributor -that the Program does not infringe the patent or other intellectual property -rights of any other entity. Each Contributor disclaims any liability to Recipient -for claims brought by any other entity based on infringement of intellectual -property rights or otherwise. As a condition to exercising the rights and licenses -granted hereunder, each Recipient hereby assumes sole responsibility to secure -any other intellectual property rights needed, if any. For example, if a third party -patent license is required to allow Recipient to distribute the Program, it is -Recipient's responsibility to acquire that license before distributing the Program. -

-d) Each Contributor represents that to its knowledge it has sufficient copyright -rights in its Contribution, if any, to grant the copyright license set forth in this -Agreement. -

- -

3. REQUIREMENTS

-

-A Contributor may choose to distribute the Program in object code form -under its own license agreement, provided that: -

-a) it complies with the terms and conditions of this Agreement; and -

-b) its license agreement: -

-i) effectively disclaims on behalf of all Contributors all warranties and conditions, -express and implied, including warranties or conditions of title and -non-infringement, and implied warranties or conditions of merchantability and -fitness for a particular purpose; -

-ii) effectively excludes on behalf of all Contributors all liability for damages, -including direct, indirect, special, incidental and consequential damages, -such as lost profits; -

-iii) states that any provisions which differ from this Agreement are offered by -that Contributor alone and not by any other party; and -

-iv) states that source code for the Program is available from such Contributor, -and informs licensees how to obtain it in a reasonable manner on or through -a medium customarily used for software exchange. -

-When the Program is made available in source code form: -

-a) it must be made available under this Agreement; and -

-b) a copy of this Agreement must be included with each copy of the Program. -

-Contributors may not remove or alter any copyright notices contained within -the Program. -

-Each Contributor must identify itself as the originator of its Contribution, -if any, in a manner that reasonably allows subsequent Recipients to identify -the originator of the Contribution. -

- -

4. COMMERCIAL DISTRIBUTION

-

-Commercial distributors of software may accept certain responsibilities with -respect to end users, business partners and the like. While this license is -intended to facilitate the commercial use of the Program, the Contributor -who includes the Program in a commercial product offering should do so -in a manner which does not create potential liability for other Contributors. -Therefore, if a Contributor includes the Program in a commercial product -offering, such Contributor ("Commercial Contributor") hereby agrees to -defend and indemnify every other Contributor ("Indemnified Contributor") -against any losses, damages and costs (collectively "Losses") arising from -claims, lawsuits and other legal actions brought by a third party against the -Indemnified Contributor to the extent caused by the acts or omissions of -such Commercial Contributor in connection with its distribution of the -Program in a commercial product offering. The obligations in this section -do not apply to any claims or Losses relating to any actual or alleged -intellectual property infringement. In order to qualify, an Indemnified -Contributor must: a) promptly notify the Commercial Contributor in writing -of such claim, and b) allow the Commercial Contributor to control, and -cooperate with the Commercial Contributor in, the defense and any related -settlement negotiations. The Indemnified Contributor may participate in -any such claim at its own expense. -

-For example, a Contributor might include the Program in a commercial -product offering, Product X. That Contributor is then a Commercial -Contributor. If that Commercial Contributor then makes performance -claims, or offers warranties related to Product X, those performance -claims and warranties are such Commercial Contributor's responsibility -alone. Under this section, the Commercial Contributor would have to -defend claims against the other Contributors related to those performance -claims and warranties, and if a court requires any other Contributor to pay -any damages as a result, the Commercial Contributor must pay those damages. -

- -

5. NO WARRANTY

-

-EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM -IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR -CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, -WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, -NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR -PURPOSE. Each Recipient is solely responsible for determining the -appropriateness of using and distributing the Program and assumes all -risks associated with its exercise of rights under this Agreement, including -but not limited to the risks and costs of program errors, compliance with -applicable laws, damage to or loss of data, programs or equipment, and -unavailability or interruption of operations. -

- -

6. DISCLAIMER OF LIABILITY

-

-EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER -RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR -ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION LOST -PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, -WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE -USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY -RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY -OF SUCH DAMAGES. -

- -

7. GENERAL

-

-If any provision of this Agreement is invalid or unenforceable under applicable -law, it shall not affect the validity or enforceability of the remainder of the -terms of this Agreement, and without further action by the parties hereto, -such provision shall be reformed to the minimum extent necessary to make -such provision valid and enforceable. -

-If Recipient institutes patent litigation against any entity (including a cross-claim -or counterclaim in a lawsuit) alleging that the Program itself (excluding -combinations of the Program with other software or hardware) infringes such -Recipient's patent(s), then such Recipient's rights granted under Section -2(b) shall terminate as of the date such litigation is filed. -

-All Recipient's rights under this Agreement shall terminate if it fails to comply -with any of the material terms or conditions of this Agreement and does -not cure such failure in a reasonable period of time after becoming aware -of such noncompliance. If all Recipient's rights under this Agreement -terminate, Recipient agrees to cease use and distribution of the Program -as soon as reasonably practicable. However, Recipient's obligations under -this Agreement and any licenses granted by Recipient relating to the -Program shall continue and survive. -

-Everyone is permitted to copy and distribute copies of this Agreement, but -in order to avoid inconsistency the Agreement is copyrighted and may only -be modified in the following manner. The Agreement Steward reserves the -right to publish new versions (including revisions) of this Agreement from -time to time. No one other than the Agreement Steward has the right to -modify this Agreement. The Eclipse Foundation is the initial Agreement -Steward. The Eclipse Foundation may assign the responsibility to serve as -the Agreement Steward to a suitable separate entity. Each new version of -the Agreement will be given a distinguishing version number. The Program -(including Contributions) may always be distributed subject to the version -of the Agreement under which it was received. In addition, after a new -version of the Agreement is published, Contributor may elect to distribute -the Program (including its Contributions) under the new version. Except as -expressly stated in Sections 2(a) and 2(b) above, Recipient receives no rights -or licenses to the intellectual property of any Contributor under this -Agreement, whether expressly, by implication, estoppel or otherwise. -All rights in the Program not expressly granted under this Agreement are -reserved. -

-This Agreement is governed by the laws of the State of New York -and the intellectual property laws of the United States of America. -No party to this Agreement will bring a legal action under this Agreement more -than one year after the cause of action arose. Each party waives its rights -to a jury trial in any resulting litigation. -

- -
- diff --git a/tools/h2/src/docsrc/html/links.html b/tools/h2/src/docsrc/html/links.html deleted file mode 100755 index 0bc79b1..0000000 --- a/tools/h2/src/docsrc/html/links.html +++ /dev/null @@ -1,639 +0,0 @@ - - - - -H2 In Use and Links - - - - -
- - -

H2 In Use and Links

-

-Those are just a few links to products using or supporting H2. -If you want to add a link, please send it to the support email address or post it in the group. -

- -

Books

- -Seam In Action - -

Extensions

- -Grails H2 Database Plugin -
- -h2osgi: OSGi for the H2 Database -
- -H2Sharp: ADO.NET interface for the H2 database engine -
- -H2 Spatial: spatial functions to H2 database - -

Blog Articles

- -Analyzing CSVs with H2 in under 10 minutes (2009-12-07)
- -Efficient sorting and iteration on large databases (2009-06-15)
- -Porting Flexive to the H2 Database (2008-12-05)
- -H2 Database with GlassFish (2008-11-24)
- -Using H2 Database with Glassfish and Toplink (2008-08-07)
- -H2 Database - Performance Tracing (2008-04-30)
- -Testing your JDBC data access layer with DBUnit and H2 (2007-09-18)
- -Open Source Databases Comparison (2007-09-11)
- -The Codist: The Open Source Frameworks I Use (2007-07-23)
- -The Codist: SQL Injections: How Not To Get Stuck (2007-05-08)
- -One Man Band: (Helma + H2) == "to easy" (2007-03-11)
- -David Coldrick's Weblog: New Version of H2 Database Released (2007-01-06)
- -The Codist: Write Your Own Database, Again (2006-11-13)
- -

Project Pages

- -Ohloh
- -Freshmeat Project Page
- -Free Open Source Software For Us
- -Wikipedia
- -Java Source Net
- -Linux Package Manager
- -

Database Frontends / Tools

- -

-DB Solo
-SQL query tool. -

- -

-DbVisualizer
-Database tool. -

- -

-Execute Query
-Database utility written in Java. -

- -

-[fleXive]
-JavaEE 5 open source framework for the development of complex and evolving (web-)applications. -

- -

-HenPlus
-HenPlus is a SQL shell written in Java. -

- -

-RazorSQL
-An SQL query tool, database browser, SQL editor, and database administration tool. -

- -

-SQL Developer
-Universal Database Frontend. -

- -

-SQL Workbench/J
-Free DBMS-independent SQL tool. -

- -

-SQuirreL SQL Client
-Graphical tool to view the structure of a database, browse the data, issue SQL commands etc. -

- -

-SQuirreL DB Copy Plugin
-Tool to copy data from one database to another. -

- -

Products and Projects

- -

-AccuProcess
-Visual business process modeling and simulation software for business users. -

- -

-Adeptia BPM
-A Business Process Management (BPM) suite to quickly and easily automate business processes and workflows. -

- -

-Adeptia Integration
-Process-centric, services-based application integration suite. -

- -

-Aejaks
-A server-side scripting environment to build AJAX enabled web applications. -

- -

-Axiom Stack
-A web framework that let's you write dynamic web applications with Zen-like simplicity. -

- -

-Apache Cayenne
-Open source persistence framework providing object-relational mapping (ORM) and remoting services. -

- -

-Apache Jackrabbit
-Open source implementation of the Java Content Repository API (JCR). -

- -

-Apache OpenJPA
-Open source implementation of the Java Persistence API (JPA). -

- -

-AppFuse
-Helps building web applications. -

- -

-BGBlitz
-The Swiss army knife of Backgammon. -

- -

-Blojsom
-Java-based multi-blog, multi-user software package (Mac OS X Weblog Server). -

- -

-Bonita
-Open source workflow solution for handing long-running, user-oriented processes -providing out of the box workflow and business process management features. -

- -

-Bookmarks Portlet
-JSR 168 compliant bookmarks management portlet application. -

- -

-Claros inTouch
-Ajax communication suite with mail, addresses, notes, IM, and rss reader. -

- -

-CrashPlan PRO Server
-Easy and cross platform backup solution for business and service providers. -

- -

-DbUnit
-A JUnit extension (also usable with Ant) targeted for database-driven projects. -

- -

-Dinamica Framework
-Ajax/J2EE framework for RAD development (mainly oriented toward hispanic markets). -

- -

-Ebean ORM Persistence Layer
-Open source Java Object Relational Mapping tool. -

- -

-Eclipse CDO
-The CDO (Connected Data Objects) Model Repository is a distributed shared model framework for EMF models, -and a fast server-based O/R mapping solution. -

- -

-Epictetus
-Free cross platform database tool. -

- -

-Fabric3
-Fabric3 is a project implementing a federated service network based on the Service Component Architecture specification (http://www.osoa.org). -

- -

-FIT4Data
-A testing framework for data management applications built on the Java implementation of FIT. -

- -

-Flux
-Java job scheduler, file transfer, workflow, and BPM. -

- -

-GBIF Integrated Publishing Toolkit (IPT)
-The GBIF IPT is an open source, Java based web application that connects and serves -three types of biodiversity data: taxon primary occurrence data, -taxon checklists and general resource metadata. -

- -

-GNU Gluco Control
-Helps you to manage your diabetes. -

- -

-Golden T Studios
-Fun-to-play games with a simple interface. -

- -

-Group Session
-Open source web groupware. -

- -

-HA-JDBC
-High-Availability JDBC: A JDBC proxy that provides light-weight, transparent, fault tolerant clustering capability to any underlying JDBC driver. -

- -

-Harbor
-Pojo Application Server. -

- -

-Hibernate
-Relational persistence for idiomatic Java (O-R mapping tool). -

- -

-Hibicius
-Online Banking Client for the HBCI protocol. -

- -

-ImageMapper
-ImageMapper frees users from having to use file browsers to view their images. -They get fast access to images and easy cataloguing of them via a user friendly -interface. -

- -

-JAMWiki
-Java-based Wiki engine. -

- -

-Jala
-Open source collection of JavaScript modules. -

- -

-Java Simon
-Simple Monitoring API. -

- -

-JBoss jBPM
-A platform for executable process languages ranging from business process management (BPM) over workflow to service orchestration. -

- -

-JBoss Jopr
-An enterprise management solution for JBoss middleware projects and other application technologies. -

- -

-JGeocoder
-Free Java geocoder. Geocoding is the process of estimating a latitude and longitude for a given location. -

- -

-JGrass
-Java Geographic Resources Analysis Support System. -Free, multi platform, open source GIS based on the GIS framework of uDig. -

- -

-Jena
-Java framework for building Semantic Web applications. -

- -

-JMatter
-Framework for constructing workgroup business applications based on the Naked Objects Architectural Pattern. -

- -

-JotBot
-Records your day at user defined intervals. -

- -

-JPOX
-Java persistent objects. -

- -

-Liftweb
-A Scala-based, secure, developer friendly web framework. -

- -

-LiquiBase
-A tool to manage database changes and refactorings. -

- -

-Luntbuild
-Build automation and management tool. -

- -

-localdb
-A tool that locates the full file path of the folder containing the database files. -

- -

-Magnolia
-Microarray Data Management and Export System for PFGRC -(Pathogen Functional Genomics Resource Center) Microarrays. -

- -

-MiniConnectionPoolManager
-A lightweight standalone JDBC connection pool manager. -

- -

-Mr. Persister
-Simple, small and fast object relational mapping. -

- -

-Myna Application Server
-Java web app that provides dynamic web content and Java libraries access from JavaScript. -

- -

-MyTunesRss
-MyTunesRSS lets you listen to your music wherever you are. -

- -

-NCGC CurveFit
-From: NIH Chemical Genomics Center, National Institutes of Health, USA. -An open source application in the life sciences research field. This -application handles chemical structures and biological responses of -thousands of compounds with the potential to handle million+ compounds. -It utilizes an embedded H2 database to enable flexible query/retrieval -of all data including advanced chemical substructure and similarity -searching. The application highlights an automated curve fitting and -classification algorithm that outperforms commercial packages in the -field. Commercial alternatives are typically small desktop software -that handle a few dose response curves at a time. A couple of -commercial packages that do handle several thousand curves are very -expensive tools (>60k USD) that require manual curation of analysis -by the user; require a license to Oracle; lack advanced -query/retrieval; and the ability to handle chemical structures. -

- -

-Nuxeo
-Standards-based, open source platform for building ECM applications. -

- -

-nWire
-Eclipse plug-in which expedites Java development. -It's main purpose is to help developers find code quicker and easily -understand how it relates to the rest of the application, thus, -understand the application structure. -

- -

-Ontology Works
-This company provides semantic technologies including deductive -information repositories (the Ontology Works Knowledge Servers), -semantic information fusion and semantic federation of legacy -databases, ontology-based domain modeling, and management of the -distributed enterprise. -

- -

-Ontoprise OntoBroker
-SemanticWeb-Middleware. It supports all W3C Semantic Web recommendations: -OWL, RDF, RDFS, SPARQL, and F-Logic. -

- -

-Open Anzo
-Semantic Application Server. -

- -

-OpenTelegard
-An OpenSource BBS Software written in JRuby. -

- -

-OpenGroove
-OpenGroove is a groupware program that allows users to synchronize data. -

- -

-OpenSocial Development Environment (OSDE)
-Development tool for OpenSocial application. -

- -

-Orion
-J2EE Application Server. -

- -

-P5H2
-A library for the Processing programming language and environment. -

- -

-Phase-6
-A computer based learning software. -

- -

-Pickle
-Pickle is a Java library containing classes for persistence, concurrency, and logging. -

- -

-Piman
-Water treatment projects data management. -

- -

-PolePosition
-Open source database benchmark. -

- -

-Poormans
-Very basic CMS running as a SWT application and generating static html pages. -

- -

-Railo
-Railo is an alternative engine for the Cold Fusion Markup Language, that compiles code -programmed in CFML into Java bytecode and executes it on a servlet engine. -

- -

-Razuna
-Open source Digital Asset Management System with integrated Web Content Management. -

- -

-RIFE
-A full-stack web application framework with tools and APIs to implement most common web features. -

- -

-Rutema
-Rutema is a test execution and management tool for heterogeneous development environments written in Ruby. -

- -

-Sava
-Open-source web-based content management system. -

- -

-Scriptella
-ETL (Extract-Transform-Load) and script execution tool. -

- -

-Sesar
-Dependency Injection Container with Aspect Oriented Programming. -

- -

-SemmleCode
-Eclipse plugin to help you improve software quality. -

- -

-SeQuaLite
-A free, light-weight, java data access framework. -

- -

-ShapeLogic
-Toolkit for declarative programming, image processing and computer vision. -

- -

-Shellbook
-Desktop publishing application. -

- -

-Signsoft intelliBO
-Persistence middleware supporting the JDO specification. -

- -

-SimpleORM
-Simple Java Object Relational Mapping. -

- -

-SymmetricDS
-A web-enabled, database independent, data synchronization/replication software. -

- -

-SmartFoxServer
-Platform for developing multiuser applications and games with Macromedia Flash. -

- -

-Social Bookmarks Friend Finder
-A GUI application that allows you to find users with similar bookmarks to the user specified (for delicious.com). -

- -

-Springfuse
-Code generation For Spring, Spring MVC & Hibernate. -

- -

-SQLOrm
-Java Object Relation Mapping. -

- -

-StorYBook
-A summary-based tool for novelist and script writers. It helps to keep the overview over the various traces a story has. -

- -

-StreamCruncher
-Event (stream) processing kernel. -

- -

-Tune Backup
-Easy-to-use backup solution for your iTunes library. -

- -

-weblica
-Desktop CMS. -

- -

-Web of Web
-Collaborative and realtime interactive media platform for the web. -

- -

-Werkzeugkasten
-Minimum Java Toolset. -

- -

-VPDA
-View providers driven applications is a Java based application framework -for building applications composed from server components - view providers. -

- -

-Volunteer database
-A database front end to register volunteers, partnership and donation for a Non Profit organization. -

- -
- diff --git a/tools/h2/src/docsrc/html/main.html b/tools/h2/src/docsrc/html/main.html deleted file mode 100755 index 3284559..0000000 --- a/tools/h2/src/docsrc/html/main.html +++ /dev/null @@ -1,42 +0,0 @@ - - - - -H2 Database Engine - - - - -
- - -

H2 Database Engine

-

-Welcome to H2, the free Java SQL database engine. -

- -

-Quickstart -
-Get a fast overview. -

- -

-Tutorial -
-Go through the samples. -

- -

-Features -
-See what this database can do and how to use these features. -

- -
- diff --git a/tools/h2/src/docsrc/html/mainWeb.html b/tools/h2/src/docsrc/html/mainWeb.html deleted file mode 100755 index a50ca21..0000000 --- a/tools/h2/src/docsrc/html/mainWeb.html +++ /dev/null @@ -1,204 +0,0 @@ - - - - -H2 Database Engine - - - - - - -
- - -

H2 Database Engine

-

-Welcome to H2, the Java SQL database. The main features of H2 are: -

-
    -
  • Very fast, open source, JDBC API -
  • Embedded and server modes; in-memory databases -
  • Browser based Console application -
  • Small footprint: around 1 MB jar file size -
- - - - - - - - - - - - - - -
- - - - - -
-

Download

- Version ${version} (${versionDate}): -
- download - - Windows Installer (4 MB) -
- download - - All Platforms (zip, 5 MB) -
- All Downloads -
-
    - - -
-

Support

-

- English Google Group
- Japanese Google Group

- For non-technical issues, use:
- -

-
-
-

Features

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
H2DerbyHSQLDBMySQLPostgreSQL
Pure JavaYesYesYesNoNo
Memory ModeYesYesYesNoNo
Transaction IsolationYesYesNoYesYes
Cost Based OptimizerYesYesNoYesYes
Encrypted DatabaseYesYesNoNoNo
ODBC DriverYesNoNoYesYes
Fulltext SearchYesNoNoYesYes
Multi Version ConcurrencyYesNoNoYesYes
Footprint (jar/dll size)~1 MB~2 MB~600 KB~4 MB~6 MB
-

- See also the detailed comparison. -

-
- - -
-

News

-

- Newsfeeds: - Full text (Atom) - or Header only (RSS). -

- Email Newsletter: Subscribe to - - H2 Database News (Google account required) - to get informed about new releases. - Your email address is only used in this context. -

-
-
 
- - -
-

Contribute

-

- You can contribute to the development of H2 by sending feedback and bug - reports, or translate the H2 Console application (for details, start the H2 Console - and select Options / Translate). - To donate money, click on the PayPal button below. You will be listed as a supporter: -

-
-

- - - - -

-
-
-
- -
diff --git a/tools/h2/src/docsrc/html/navigation.js b/tools/h2/src/docsrc/html/navigation.js deleted file mode 100755 index 9e8842e..0000000 --- a/tools/h2/src/docsrc/html/navigation.js +++ /dev/null @@ -1,166 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ - -function loadFrameset() { - var a = location.search.split('&'); - var page = decodeURIComponent(a[0].substr(1)); - var frame = a[1]; - if(page && frame){ - var s = "top." + frame + ".location.replace('" + page + "')"; - eval(s); - } - return; -} - -function frameMe(frame) { - if(location.host.indexOf('h2database') < 0) { - // allow translation - return; - } - var frameset = "frame.html"; // name of the frameset page - if(frame == null) { - frame = 'main'; - } - page = new String(self.document.location); - var pos = page.lastIndexOf("/") + 1; - var file = page.substr(pos); - file = encodeURIComponent(file); - if(window.name != frame) { - var s = frameset + "?" + file + "&" + frame; - top.location.replace(s); - } else { - highlightFrame(); - } - return; -} - -function addHighlight(page, word, count) { - if(count > 0) { - if(top.main.document.location.href.indexOf(page) > 0 && top.main.document.body && top.main.document.body.innerHTML) { - highlight(); - } else { - window.setTimeout('addHighlight("'+page+'","'+word+'",'+(count-1)+')', 10); - } - } -} - -function highlightFrame() { - var url = new String(top.main.location.href); - if(url.indexOf('?highlight=') < 0) { - return; - } else { - var page = url.split('?highlight='); - var word = decodeURIComponent(page[1]); - top.main.document.body.innerHTML = highlightSearchTerms(top.main.document.body, word); - top.main.location = '#firstFound'; - // window.setTimeout('goFirstFound()', 1); - } -} - -function highlight() { - var url = new String(document.location.href); - if(url.indexOf('?highlight=') < 0) { - return; - } else { - var page = url.split('highlight=')[1].split('&')[0]; - var search = decodeURIComponent(url.split('search=')[1].split('#')[0]); - var word = decodeURIComponent(page); - document.body.innerHTML = highlightSearchTerms(document.body, word); - document.location = '#firstFound'; - document.getElementById('search').value = search; - listWords(search, ''); - } -} - -function goFirstFound() { - top.main.location = '#firstFound'; -/* - var page = new String(parent.main.location); - alert('first: ' + page); - page = page.split('#')[0]; - paramSplit = page.split('?'); - page = paramSplit[0]; - page += '#firstFound'; - if(paramSplit.length > 0) { - page += '?' + paramSplit[1]; - } - top.main.location = page; -*/ -} - -function highlightSearchTerms(body, searchText) { - matchColor = "ffff00,00ffff,00ff00,ff8080,ff0080".split(','); - highlightEndTag = "
"; - searchArray = searchText.split(","); - if (!body || typeof(body.innerHTML) == "undefined") { - return false; - } - var bodyText = body.innerHTML; - for (var i = 0; i < searchArray.length; i++) { - var color = matchColor[i % matchColor.length]; - highlightStartTag = ""; - bodyText = doHighlight(bodyText, searchArray[i], highlightStartTag, highlightEndTag); - } - return bodyText; -} - -function doHighlight(bodyText, searchTerm, highlightStartTag, highlightEndTag) { - if(searchTerm == undefined || searchTerm=="") { - return bodyText; - } - var newText = ""; - var i = -1; - var lcSearchTerm = searchTerm.toLowerCase(); - var lcBodyText = bodyText.toLowerCase(); - while (bodyText.length > 0) { - i = lcBodyText.indexOf(lcSearchTerm, i+1); - if (i < 0) { - newText += bodyText; - bodyText = ""; - } else { - // skip anything inside an HTML tag - if (bodyText.lastIndexOf(">", i) >= bodyText.lastIndexOf("<", i)) { - // skip anything inside a - -
- - -

Performance

- - Performance Comparison
- - PolePosition Benchmark
- - Application Profiling
- - Database Profiling
- - Database Performance Tuning
- - Using the Built-In Profiler
- - Fast Database Import
- -

Performance Comparison

-

-In many cases H2 is faster than other -(open source and not open source) database engines. -Please note this is mostly a single connection benchmark run on one computer. -

- -

Embedded

- - - - - - - - - - - - - - - - - - - - -
Test CaseUnitH2HSQLDBDerby
Simple: Initms5475322594
Simple: Query (random)ms2503911515
Simple: Query (sequential)ms1883131406
Simple: Update (random)ms812175017704
Simple: Delete (sequential)ms2032508843
Simple: Memory UsageMB71111
BenchA: Initms5787193328
BenchA: Transactionsms3047240612907
BenchA: Memory UsageMB101510
BenchB: Initms2141240611562
BenchB: Transactionsms112513753625
BenchB: Memory UsageMB9118
BenchC: Initms6885944500
BenchC: Transactionsms1906640626047
BenchC: Memory UsageMB111711
Executed statements#322929322929322929
Total timems114857479874031
Statements per second#2811743174362
- -

Client-Server

- - - - - - - - - - - - - - - - - - - - -
Test CaseUnitH2HSQLDBDerbyPostgreSQLMySQL
Simple: Initms27822656562545633484
Simple: Query (random)ms30932703668848123860
Simple: Query (sequential)ms29692594643747193625
Simple: Update (random)ms296935311825059535125
Simple: Delete (sequential)ms10471250687524852390
Simple: Memory UsageMB7111400
BenchA: Initms22502453603143283625
BenchA: Transactionsms102509016214841560911172
BenchA: Memory UsageMB10151001
BenchB: Initms950010672226091960913406
BenchB: Transactionsms27342656387546882531
BenchB: Memory UsageMB10111111
BenchC: Initms18601484689022193438
BenchC: Transactionsms90466326618641117037421
BenchC: Memory UsageMB12171301
Executed statements#322929322929322929322929322929
Total timems485001022811234058068860077
Statements per second#66583157261640025375
- -

Benchmark Results and Comments

- -

H2

-

-Version 1.1.114 (2009-06-01) was used for the test. -For simpler operations, the performance of H2 is about the same as for HSQLDB. -For more complex queries, the query optimizer is very important. -However H2 is not very fast in every case, certain kind of queries may still be slow. -One situation where is H2 is slow is large result sets, because they are buffered to -disk if more than a certain number of records are returned. -The advantage of buffering is, there is no limit on the result set size. -The open/close time is almost fixed, because of the file locking protocol: the engine waits -some time after opening a database to ensure the database files are not opened by another process. -

- -

HSQLDB

-

-Version 1.8.0.10 was used for the test. -Cached tables are used in this test (hsqldb.default_table_type=cached), -and the write delay is 1 second (SET WRITE_DELAY 1). -HSQLDB is fast when using simple operations. -HSQLDB is very slow in the last test (BenchC: Transactions), probably because is has a bad query optimizer. -One query where HSQLDB is slow is a two-table join: -

-
-SELECT COUNT(DISTINCT S_I_ID) FROM ORDER_LINE, STOCK
-WHERE OL_W_ID=? AND OL_D_ID=? AND OL_O_ID<? AND OL_O_ID>=?
-AND S_W_ID=? AND S_I_ID=OL_I_ID AND S_QUANTITY<?
-
-

-The PolePosition benchmark also shows that the query optimizer does not do a very good job for some queries. -Another disadvantage of HSQLDB is the slow startup / shutdown time (currently not listed) when using bigger databases. -The reason is, a backup of the whole data is made whenever the database is opened or closed. -

- -

Derby

-

-Version 10.4.2.0 was used for the test. Derby is clearly the slowest embedded database in this test. -This seems to be a structural problem, because all operations are really slow. -It will be hard for the developers of Derby to improve the performance to a reasonable level. -A few problems have been identified: leaving autocommit on is a problem for Derby. -If it is switched off during the whole test, the results are about 20% better for Derby. -Derby does not call FileDescriptor.sync() or FileChannel.force(..) on each commit. -Derby supports a testing mode (system property derby.system.durability=test) -where durability is disabled. According to the documentation, this setting should be used for testing only, -as the database may not recover after a crash. Enabling this setting improves performance -by a factor of 2.6 (embedded mode) or 1.4 (server mode). Even if enabled, Derby is still less -than half as fast as H2 in default mode. -

- -

PostgreSQL

-

-Version 8.3.7 was used for the test. -The following options where changed in postgresql.conf: -fsync = off, commit_delay = 1000. -PostgreSQL is run in server mode. It looks like the base performance is slower than -MySQL, the reason could be the network layer. -The memory usage number is incorrect, because only the memory usage of the JDBC driver is measured. -

- -

MySQL

-

-Version 5.1.34-community was used for the test. -MySQL was run with the InnoDB backend. -The setting innodb_flush_log_at_trx_commit -(found in the my.ini file) was set to 0. Otherwise (and by default), MySQL is really slow -(around 140 statements per second in this test) because it tries to flush the data to disk for each commit. -For small transactions (when autocommit is on) this is really slow. -But many use cases use small or relatively small transactions. -Too bad this setting is not listed in the configuration wizard, -and it always overwritten when using the wizard. -You need to change this setting manually in the file my.ini, and then restart the service. -The memory usage number is incorrect, because only the memory usage of the JDBC driver is measured. -

- -

Firebird

-

-Firebird 1.5 (default installation) was tested, but the results are not published currently. -It is possible to run the performance test with the Firebird database, -and any information on how to configure Firebird for higher performance are welcome. -

- -

Why Oracle / MS SQL Server / DB2 are Not Listed

-

-The license of these databases does not allow to publish benchmark results. -This doesn't mean that they are fast. They are in fact quite slow, -and need a lot of memory. But you will need to test this yourself. -SQLite was not tested because the JDBC driver doesn't support transactions. -

- -

About this Benchmark

- -

How to Run

-

-This test was executed as follows: -

-
-build benchmark
-
- -

Separate Process per Database

-

-For each database, a new process is started, to ensure the previous test does not impact -the current test. -

- -

Number of Connections

-

-This is mostly a single-connection benchmark. -BenchB uses multiple connections; the other tests use one connection. -

- -

Real-World Tests

-

-Good benchmarks emulate real-world use cases. This benchmark includes 4 test cases: -BenchSimple uses one table and many small updates / deletes. -BenchA is similar to the TPC-A test, but single connection / single threaded (see also: www.tpc.org). -BenchB is similar to the TPC-B test, using multiple connections (one thread per connection). -BenchC is similar to the TPC-C test, but single connection / single threaded. -

- -

Comparing Embedded with Server Databases

-

-This is mainly a benchmark for embedded databases (where the application runs in the same -virtual machine as the database engine). However MySQL and PostgreSQL are not Java -databases and cannot be embedded into a Java application. -For the Java databases, both embedded and server modes are tested. -

- -

Test Platform

-

-This test is run on Windows XP with the virus scanner switched off. -The VM used is Sun JDK 1.5. -

- -

Multiple Runs

-

-When a Java benchmark is run first, the code is not fully compiled and -therefore runs slower than when running multiple times. A benchmark -should always run the same test multiple times and ignore the first run(s). -This benchmark runs three times, but only the last run is measured. -

- -

Memory Usage

-

-It is not enough to measure the time taken, the memory usage is important as well. -Performance can be improved by using a bigger cache, but the amount of memory is limited. -HSQLDB tables are kept fully in memory by default; this benchmark -uses 'disk based' tables for all databases. -Unfortunately, it is not so easy to calculate the memory usage of PostgreSQL -and MySQL, because they run in a different process than the test. This benchmark currently -does not print memory usage of those databases. -

- -

Delayed Operations

-

-Some databases delay some operations (for example flushing the buffers) -until after the benchmark is run. This benchmark waits between -each database tested, and each database runs in a different process (sequentially). -

- -

Transaction Commit / Durability

-

-Durability means transaction committed to the database will not be lost. -Some databases (for example MySQL) try to enforce this by default by -calling fsync() to flush the buffers, but -most hard drives don't actually flush all data. Calling the method slows down transaction commit a lot, -but doesn't always make data durable. When comparing the results, it is important to -think about the effect. Many database suggest to 'batch' operations when possible. -This benchmark switches off autocommit when loading the data, and calls commit after each 1000 -inserts. However many applications need 'short' transactions at runtime (a commit after each update). -This benchmark commits after each update / delete in the simple benchmark, and after each -business transaction in the other benchmarks. For databases that support delayed commits, -a delay of one second is used. -

- -

Using Prepared Statements

-

-Wherever possible, the test cases use prepared statements. -

- -

Currently Not Tested: Startup Time

-

-The startup time of a database engine is important as well for embedded use. -This time is not measured currently. -Also, not tested is the time used to create a database and open an existing database. -Here, one (wrapper) connection is opened at the start, -and for each step a new connection is opened and then closed. -

- -

PolePosition Benchmark

-

-The PolePosition is an open source benchmark. The algorithms are all quite simple. -It was developed / sponsored by db4o. -

- - - - - - - - - - - - - - - - - - - - - - -
Test CaseUnitH2HSQLDBMySQL
Melbourne writems3692492022
Melbourne readms474993
Melbourne read_hotms244395
Melbourne deletems147133176
Sepang writems96512013213
Sepang readms7659483455
Sepang read_hotms7898593563
Sepang deletems138415966214
Bahrain writems118613876904
Bahrain query_indexed_stringms336170693
Bahrain query_stringms180643970341243
Bahrain query_indexed_intms104134678
Bahrain updatems19187159
Bahrain deletems12157296812
Imola retrievems1981944036
Barcelona writems4138323191
Barcelona readms1191601177
Barcelona queryms205169101
Barcelona deletems3883193287
Totalms267245396287112
-

-There are a few problems with the PolePosition test: -

-
  • -HSQLDB uses in-memory tables by default while H2 uses persistent tables. The HSQLDB version -included in PolePosition does not support changing this, so you need to replace -poleposition-0.20/lib/hsqldb.jar with a newer version (for example -hsqldb-1.8.0.7.jar), -and then use the setting -hsqldb.connecturl=jdbc:hsqldb:file:data/hsqldb/dbbench2;hsqldb.default_table_type=cached;sql.enforce_size=true -in the file Jdbc.properties. -
  • HSQLDB keeps the database open between tests, while H2 closes the database (losing all the cache). -To change that, use the database URL jdbc:h2:file:data/h2/dbbench;DB_CLOSE_DELAY=-1 -
  • The amount of cache memory is quite important, specially for the PolePosition test. -Unfortunately, the PolePosition test does not take this into account. -
- -

Application Profiling

- -

Analyze First

-

-Before trying to optimize performance, it is important to understand where the problem is (what part of the application is slow). -Blind optimization or optimization based on guesses should be avoided, because usually it is not an efficient strategy. -There are various ways to analyze an application. Sometimes two implementations can be compared using -System.currentTimeMillis(). But this does not work for complex applications with many modules, and for memory problems. -

-

-A simple way to profile an application is to use the built-in profiling tool of java. Example: -

-
-java -Xrunhprof:cpu=samples,depth=16 com.acme.Test
-
-

-Unfortunately, it is only possible to profile the application from start to end. Another solution is to create -a number of full thread dumps. To do that, first run jps -l to get the process id, and then -run jstack <pid> or kill -QUIT <pid> (Linux) or press -Ctrl+C (Windows). -

-

-A simple profiling tool is included in H2. To use it, the application needs to be changed slightly. Example: -

-
-import org.h2.util;
-...
-profiler = new Profiler();
-profiler.startCollecting();
-// application code
-profiler.stopCollecting();
-System.out.println(profiler.getTop(3));
-
-

-The profiler is built into the H2 Console tool, to analyze databases that open slowly. -To use it, run the H2 Console, and then click on 'Test Connection'. -Afterwards, click on "Test successful" and you get the most common stack traces, -which helps to find out why it took so long to connect. You will only get the stack traces -if opening the database took more than a few seconds. -

- -

Database Profiling

-

-The ConvertTraceFile tool generates SQL statement statistics at the end of the SQL script file. -The format used is similar to the profiling data generated when using java -Xrunhprof. -As an example, execute the the following script using the H2 Console: -

-
-SET TRACE_LEVEL_FILE 3;
-DROP TABLE IF EXISTS TEST;
-CREATE TABLE TEST(ID INT PRIMARY KEY, NAME VARCHAR(255));
-@LOOP 1000 INSERT INTO TEST VALUES(?, ?);
-SET TRACE_LEVEL_FILE 0;
-
-

-Now convert the .trace.db file using the ConvertTraceFile tool: -

-
-java -cp h2*.jar org.h2.tools.ConvertTraceFile
-    -traceFile "~/test.trace.db" -script "~/test.sql"
-
-

-The generated file test.sql will contain the SQL statements as well as the -following profiling data (results vary): -

-
------------------------------------------
--- SQL Statement Statistics
--- time: total time in milliseconds (accumulated)
--- count: how many times the statement ran
--- result: total update count or row count
------------------------------------------
--- self accu    time   count  result sql
---  62%  62%     158    1000    1000 INSERT INTO TEST VALUES(?, ?);
---  37% 100%      93       1       0 CREATE TABLE TEST(ID INT PRIMARY KEY, NAME VARCHAR(255));
---   0% 100%       0       1       0 DROP TABLE IF EXISTS TEST;
---   0% 100%       0       1       0 SET TRACE_LEVEL_FILE 3;
-
- -

Database Performance Tuning

- -

Keep Connections Open or Use a Connection Pool

-

-If your application opens and closes connections a lot (for example, for each request), -you should consider using a connection pool. -Opening a connection using DriverManager.getConnection is specially slow -if the database is closed. By default the database is closed if the last connection is closed. -

-If you open and close connections a lot but don't want to use a connection pool, -consider keeping a 'sentinel' connection open for as long as the application runs, -or use delayed database closing. See also -Closing a database. -

- -

Use a Modern JVM

-

-Newer JVMs are faster. Upgrading to the latest version of your JVM can provide a "free" boost to performance. -Switching from the default Client JVM to the Server JVM using the -server command-line -option improves performance at the cost of a slight increase in start-up time. -

- -

Virus Scanners

-

-Some virus scanners scan files every time they are accessed. -It is very important for performance that database files are not scanned for viruses. -The database engine never interprets the data stored in the files as programs, -that means even if somebody would store a virus in a database file, this would -be harmless (when the virus does not run, it cannot spread). -Some virus scanners allow to exclude files by suffix. Ensure files ending with .db are not scanned. -

- -

Using the Trace Options

-

-If the performance hot spots are in the database engine, in many cases the performance -can be optimized by creating additional indexes, or changing the schema. Sometimes the -application does not directly generate the SQL statements, for example if an O/R mapping tool -is used. To view the SQL statements and JDBC API calls, you can use the trace options. -For more information, see Using the Trace Options. -

- -

Index Usage

-

-This database uses indexes to improve the performance of -SELECT, UPDATE, DELETE. -If a column is used in the WHERE clause of a query, and if an index exists on this column, -then the index can be used. Multi-column indexes are used if all or the first columns of the index are used. -Both equality lookup and range scans are supported. -Indexes are used to order result sets, but only if the condition uses the same index or no index at all. -The results are sorted in memory if required. -Indexes are created automatically for primary key and unique constraints. -Indexes are also created for foreign key constraints, if required. -For other columns, indexes need to be created manually using the CREATE INDEX statement. -

- -

Optimizer

-

-This database uses a cost based optimizer. For simple and queries and queries with medium complexity -(less than 7 tables in the join), the expected cost (running time) of all possible plans is calculated, -and the plan with the lowest cost is used. For more complex queries, the algorithm first tries -all possible combinations for the first few tables, and the remaining tables added using a greedy algorithm -(this works well for most joins). Afterwards a genetic algorithm is used to test at most 2000 distinct plans. -Only left-deep plans are evaluated. -

- -

Expression Optimization

-

-After the statement is parsed, all expressions are simplified automatically if possible. Operations -are evaluated only once if all parameters are constant. Functions are also optimized, but only -if the function is constant (always returns the same result for the same parameter values). -If the WHERE clause is always false, then the table is not accessed at all. -

- -

COUNT(*) Optimization

-

-If the query only counts all rows of a table, then the data is not accessed. -However, this is only possible if no WHERE clause is used, that means it only works for -queries of the form SELECT COUNT(*) FROM table. -

- -

Updating Optimizer Statistics / Column Selectivity

-

-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. -

-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', -the index on NAME or the index on FIRSTNAME. It is not possible to use both indexes at the same time. -Which index is used depends on the selectivity of the column. The selectivity describes the 'uniqueness' of -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. -

-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. -

- -

In-Memory (Hash) Indexes

-

-Using in-memory indexes, specially in-memory hash indexes, can speed up -queries and data manipulation. -

-

In-memory indexes are automatically used -for in-memory databases, but can also be created for persistent databases -using CREATE MEMORY TABLE. In many cases, -the rows itself will also be kept in-memory. Please note this may cause memory -problems for large tables. -

-

-In-memory hash indexes are backed by a hash table and are usually faster than -regular indexes. However, hash indexes only supports direct lookup (WHERE ID = ?) -but not range scan (WHERE ID < ?). To use hash indexes, use HASH as in: -CREATE UNIQUE HASH INDEX and -CREATE TABLE ...(ID INT PRIMARY KEY HASH,...). -

- -

Use Prepared Statements

-

-If possible, use prepared statements with parameters. -

- -

Prepared Statements and IN(...)

-

-Avoid generating SQL statements with a variable size IN(...) list. -Instead, use a prepared statement with arrays as in the following example: -

-
-PreparedStatement prep = conn.prepareStatement(
-    "SELECT * FROM TABLE(X INT=?) T INNER JOIN TEST ON T.X=TEST.ID");
-prep.setObject(1, new Object[] { "1", "2" });
-ResultSet rs = prep.executeQuery();
-
- -

Optimization Examples

-

-See src/test/org/h2/samples/optimizations.sql for a few examples of queries -that benefit from special optimizations built into the database. -

- -

Cache Size and Type

-

-By default the cache size of H2 is quite small. Consider using a larger cache size, or enable -the second level soft reference cache. See also Cache Settings. -

- -

Data Types

-

-Each data type has different storage and performance characteristics: -

-
  • The DECIMAL/NUMERIC type is slower - and requires more storage than the REAL and DOUBLE types. -
  • Text types are slower to read, write, and compare than numeric types and generally require more storage. -
  • See Large Objects for information on - BINARY vs. BLOB - and VARCHAR vs. CLOB performance. -
  • Parsing and formatting takes longer for the - TIME, DATE, and - TIMESTAMP types than the numeric types. -
  • SMALLINT/TINYINT/BOOLEAN are not significantly smaller or faster - to work with than INTEGER in most modes. -
- -

Sorted Insert Optimization

-

-To reduce disk space usage and speed up table creation, an -optimization for sorted inserts is available. When used, b-tree pages -are split at the insertion point. To use this optimization, add SORTED -before the SELECT statement: -

-
-CREATE TABLE TEST(ID INT PRIMARY KEY, NAME VARCHAR) AS
-    SORTED SELECT X, SPACE(100) FROM SYSTEM_RANGE(1, 100);
-INSERT INTO TEST
-    SORTED SELECT X, SPACE(100) FROM SYSTEM_RANGE(101, 200);
-
- -

Using the Built-In Profiler

-

-A very simple Java profiler is built-in. To use it, use the following template: -

-
-import org.h2.util.Profiler;
-Profiler prof = new Profiler();
-prof.startCollecting();
-// .... some long running process, at least a few seconds
-prof.stopCollecting();
-System.out.println(prof.getTop(3));
-
- -

Fast Database Import

-

-To speed up large imports, consider using the following options temporarily: -

-
  • SET CACHE_SIZE (a large cache is faster) -
  • SET LOCK_MODE 0 (disable locking) -
  • SET UNDO_LOG 0 (disable the session undo log) -
-

-These options can be set in the database URL: -jdbc:h2:~/test;CACHE_SIZE=65536;LOCK_MODE=0;UNDO_LOG=0. -Most of those options are not recommended for regular use, that means you need to reset them after use. -

- -
diff --git a/tools/h2/src/docsrc/html/quickstart.html b/tools/h2/src/docsrc/html/quickstart.html deleted file mode 100755 index b57b7b4..0000000 --- a/tools/h2/src/docsrc/html/quickstart.html +++ /dev/null @@ -1,100 +0,0 @@ - - - - -Quickstart - - - - -
- - -

Quickstart

- - Embedding H2 in an Application
- - The H2 Console Application
- -

Embedding H2 in an Application

-

-This database can be used in embedded mode, or in server mode. To use it in embedded mode, you need to: -

-
    -
  • Add the h2*.jar to the classpath (H2 does not have any dependencies) -
  • Use the JDBC driver class: org.h2.Driver -
  • The database URL jdbc:h2:~/test opens the database test in your user home directory -
  • A new database is automatically created -
- -

The H2 Console Application

-

-The Console lets you access a SQL database using a browser interface. -
-Web Browser - H2 Console Server - H2 Database -
-If you don't have Windows XP, or if something does not work as expected, -please see the detailed description in the Tutorial. -

- -

Step-by-Step

- -

Installation

-

-Install the software using the Windows Installer (if you did not yet do that). -

- -

Start the Console

-

-Click [Start], [All Programs], [H2], and [H2 Console (Command Line)]:
-screenshot: start H2 Console
-A new console window appears:
-screenshot: H2 running
-Also, a new browser page should open with the URL http://localhost:8082. -You may get a security warning from the firewall. If you don't want other computers in the network to access the database -on your machine, you can let the firewall block these connections. Only local connections are required at this time. -

- -

Login

-

-Select [Generic H2] and click [Connect]:
- screenshot: login
- You are now logged in. -

- -

Sample

-

-Click on the [Sample SQL Script]:
- screenshot: click on the sample SQL script
- The SQL commands appear in the command area.
-

- -

Execute

-

-Click [Run]
-screenshot: click Run
-On the left side, a new entry TEST is added below the database icon. -The operations and results of the statements are shown below the script.
-screenshot: see the result
-

- -

Disconnect

-

-Click on [Disconnect]:
-Disconnect icon
-to close the connection. -

- -

End

-

-Close the console window. -For more information, see the Tutorial. -

- -
- diff --git a/tools/h2/src/docsrc/html/roadmap.html b/tools/h2/src/docsrc/html/roadmap.html deleted file mode 100755 index 51d45f1..0000000 --- a/tools/h2/src/docsrc/html/roadmap.html +++ /dev/null @@ -1,508 +0,0 @@ - - - - -Roadmap - - - - -
- - -

Roadmap

-

-New (feature) requests will usually be added at the very end of the list. The priority is increased for important and popular requests. -Of course, patches are always welcome, but are not always applied as is. -See also Providing Patches. -

- -

Version 1.3.x: Planned Changes

-
  • Enable h2.lobInDatabase (store CLOB and BLOB in the database file). -
  • Set h2.analyzeAuto to 2000 (automatic ANALYZE). -
  • Enable h2.functionsInSchema (allow to store functions in a schema). -
  • Enable h2.selectForUpdateMvcc (MVCC and SELECT FOR UPDATE). -
  • Enable h2.largeTransactions (support for very large transactions). - Change documentation for MAX_MEMORY_UNDO in help.csv, because - now changes to tables without a primary key can be buffered to disk. - Later, change MAX_MEMORY_UNDO to reflect number of bytes instead of record - (also remove Constants.UNDO_BLOCK_SIZE). - Later, change undo log file format (fillAligned no longer required; var int). -
- -

Priority 1

-
  • Bugfixes -
  • Support very large transactions. Reduce memory usage of undo log (TestUndoLogMemory). -
  • More tests with MULTI_THREADED=1 -
  • Optimization: result set caching (like MySQL); option to disable -
  • Server side cursors -
- -

Priority 2

-
  • Support nested outer joins (see todo.txt, issues 145, 177, 203). -
  • Improve test code coverage. -
  • Test multi-threaded in-memory db access. -
  • Full outer joins. -
  • Clustering: support mixed clustering mode (one embedded, others in server mode). -
  • Clustering: reads should be randomly distributed (optional) or to a designated database on RAM (parameter: READ_FROM=3). -
  • PostgreSQL catalog: use BEFORE SELECT triggers instead of views over metadata tables. -
  • Test very large databases and LOBs (up to 256 GB). -
  • Support hints for the optimizer (which index to use, enforce the join order). -
  • Sequence: add features [NO] MINVALUE, MAXVALUE, CYCLE. -
  • Access rights: remember the owner of an object. Create, alter and drop privileges. COMMENT: allow owner of object to change it. -
  • Deferred integrity checking (DEFERRABLE INITIALLY DEFERRED). -
  • Groovy Stored Procedures: http://groovy.codehaus.org/Groovy+SQL -
  • Add a migration guide (list differences between databases). -
  • Migrate database tool (also from other database engines). -
  • Optimization: automatic index creation suggestion using the trace file? -
  • Compression performance: don't allocate buffers, compress / expand in to out buffer. -
  • Rebuild index functionality to shrink index size and improve performance. -
  • Don't use deleteOnExit (bug 4513817: File.deleteOnExit consumes memory). -
  • Console: add accesskey to most important commands (A, AREA, BUTTON, INPUT, LABEL, LEGEND, TEXTAREA). -
  • Test performance again with SQL Server, Oracle, DB2. -
  • Test with Spatial DB in a box / JTS: http://www.opengeospatial.org/standards/sfs - OpenGIS Implementation Specification. -
  • Write more tests and documentation for MVCC (Multi Version Concurrency Control). -
  • Find a tool to view large text file (larger than 100 MB), with find, page up and down (like less), truncate before / after. -
  • Implement, test, document XAConnection and so on. -
  • Pluggable data type (for streaming, hashing, compression, validation, conversion, encryption). -
  • CHECK: find out what makes CHECK=TRUE slow, move to CHECK2. -
  • Index usage for (ID, NAME)=(1, 'Hi'); document. -
  • Make DDL (Data Definition) operations transactional. -
  • RANK() and DENSE_RANK(), Partition using OVER(). -
  • Set a connection read only (Connection.setReadOnly) or using a connection parameter. -
  • Optimizer: use an index for IS NULL and IS NOT NULL (including linked tables). - ID IS NOT NULL could be converted to ID >= Integer.MIN_VALUE. -
  • Access rights: finer grained access control (grant access for specific functions). -
  • Version check: docs / web console (using Javascript), and maybe in the library (using TCP/IP). -
  • Web server classloader: override findResource / getResourceFrom. -
  • Cost for embedded temporary view is calculated wrong, if result is constant. -
  • Comparison: pluggable sort order: natural sort. -
  • Count index range query (count(*) where id between 10 and 20). -
  • Performance: update in-place. -
  • Recursive Queries (see details). -
  • Eclipse plugin. -
  • Asynchronous queries to support publish/subscribe: SELECT ... FOR READ WAIT [maxMillisToWait]. -
  • Fulltext search Lucene: analyzer configuration. -
  • Fulltext search (native): reader / tokenizer / filter. -
  • Linked schema using CSV files: one schema for a directory of files; support indexes for CSV files. -
  • iReport to support H2. -
  • Implement missing JDBC API (CallableStatement,...). -
  • Compression of the cache. -
  • Include SMPT (mail) client (alert on cluster failure, low disk space,...). -
  • Drop with restrict (currently cascade is the default). -
  • JSON parser and functions. -
  • Server: client ping from time to time (to avoid timeout - is timeout a problem?). -
  • Copy database: tool with config GUI and batch mode, extensible (example: compare). -
  • Document, implement tool for long running transactions using user-defined compensation statements. -
  • Support SET TABLE DUAL READONLY. -
  • GCJ: what is the state now? -
  • Events for: database Startup, Connections, Login attempts, Disconnections, Prepare (after parsing), Web Server. See http://docs.openlinksw.com/virtuoso/fn_dbev_startup.html -
  • Optimization: log compression. -
  • ROW_NUMBER() OVER([ORDER BY columnName]). -
  • Support standard INFORMATION_SCHEMA tables, as defined in http://www.contrib.andrew.cmu.edu/~shadow/sql/sql1992.txt - specially KEY_COLUMN_USAGE: http://dev.mysql.com/doc/refman/5.0/en/information-schema.html, http://www.xcdsql.org/Misc/INFORMATION_SCHEMA%20With%20Rolenames.gif -
  • Compatibility: in MySQL, HSQLDB, /0.0 is NULL; in PostgreSQL, Derby: division by zero. -
  • Functional tables should accept parameters from other tables (see FunctionMultiReturn) SELECT * FROM TEST T, P2C(T.A, T.R). -
  • Custom class loader to reload functions on demand. -
  • Clustering: when a database is back alive, automatically synchronize with the master. -
  • Test http://mysql-je.sourceforge.net/ -
  • Performance: automatically build in-memory indexes if the whole table is in memory. -
  • H2 Console: the webclient could support more features like phpMyAdmin. -
  • Use Janino to convert Java to C++. -
  • The HELP information schema can be directly exposed in the Console. -
  • Maybe use the 0x1234 notation for binary fields, see MS SQL Server. -
  • Support Oracle CONNECT BY in some way: http://www.adp-gmbh.ch/ora/sql/connect_by.html http://philip.greenspun.com/sql/trees.html -
  • SQL Server 2005, Oracle: support COUNT(*) OVER(). See http://www.orafusion.com/art_anlytc.htm -
  • SQL 2003: http://www.wiscorp.com/sql_2003_standard.zip -
  • Version column (number/sequence and timestamp based). -
  • Optimize getGeneratedKey: send last identity after each execute (server). -
  • Test and document UPDATE TEST SET (ID, NAME) = (SELECT ID*10, NAME || '!' FROM TEST T WHERE T.ID=TEST.ID). -
  • Max memory rows / max undo log size: use block count / row size not row count. -
  • Support 123L syntax as in Java; example: SELECT (2000000000*2). -
  • Implement point-in-time recovery. -
  • LIKE: improved version for larger texts (currently using naive search). -
  • Automatically convert to the next 'higher' data type whenever there is an overflow. -
  • Throw an exception when the application calls getInt on a Long (optional). -
  • Default date format for input and output (local date constants). -
  • Support custom Collators. -
  • Document ROWNUM usage for reports: SELECT ROWNUM, * FROM (subquery). -
  • File system that writes to two file systems (replication, replicating file system). -
  • Standalone tool to get relevant system properties and add it to the trace output. -
  • Support 'call proc(1=value)' (PostgreSQL, Oracle). -
  • Console: improve editing data (Tab, Shift-Tab, Enter, Up, Down, Shift+Del?). -
  • Console: autocomplete Ctrl+Space inserts template. -
  • Option to encrypt .trace.db file. -
  • Write Behind Cache on SATA leads to data corruption See also http://sr5tech.com/write_back_cache_experiments.htm and http://www.jasonbrome.com/blog/archives/2004/04/03/writecache_enabled.html -
  • Functions with unknown return or parameter data types: serialize / deserialize. -
  • Auto-Update feature for database, .jar file. -
  • ResultSet SimpleResultSet.readFromURL(String url): id varchar, state varchar, released timestamp. -
  • Partial indexing (see PostgreSQL). -
  • Add GUI to build a custom version (embedded, fulltext,...) using build flags. -
  • http://rubyforge.org/projects/hypersonic/ -
  • Add comparator (x === y) : (x = y or (x is null and y is null)). -
  • Add a sample application that runs the H2 unit test and writes the result to a file (so it can be included in the user app). -
  • Count on a column that can not be null could be optimized to COUNT(*). -
  • Table order: ALTER TABLE TEST ORDER BY NAME DESC (MySQL compatibility). -
  • Issue 159: System property for the H2 Console and TCP configuration (which .h2.server.properties and .h2.keystore to use). -
  • Backup tool should work with other databases as well. -
  • Console: -ifExists doesn't work for the console. Add a flag to disable other dbs. -
  • Check if 'FSUTIL behavior set disablelastaccess 1' improves the performance (fsutil behavior query disablelastaccess). -
  • Java static code analysis: http://pmd.sourceforge.net/ -
  • Java static code analysis: http://www.eclipse.org/tptp/ -
  • Compatibility for CREATE SCHEMA AUTHORIZATION. -
  • Implement Clob / Blob truncate and the remaining functionality. -
  • Tree join functionality. -
  • Add multiple columns at the same time with ALTER TABLE .. ADD .. ADD ... -
  • Use JDK 1.4 file locking for the database file and for the lock file (but not yet by default); writing a system property to detect concurrent access from the same VM (different classloaders). -
  • Pure SQL triggers (example: update parent table if the child table is changed). -
  • Add H2 to Gem (Ruby install system). -
  • Order conditions inside AND / OR to optimize the performance. -
  • Support Oracle functions: TRUNC, NVL2, TO_CHAR, TO_DATE, TO_NUMBER. -
  • Support linked JCR tables -
  • Read InputStream when executing, as late as possible (maybe only embedded mode). Problem with re-execute. -
  • Native fulltext search: min word length; store word positions -
  • Add an option to the SCRIPT command to generate only portable / standard SQL -
  • Updatable Views (simple cases first) -
  • Improve create index performance -
  • Implement more JDBC 4.0 features -
  • Support TRANSFORM / PIVOT as in MS Access -
  • SELECT * FROM (VALUES (...), (...), ....) AS alias(f1, ...) -
  • Support updatable views with join on primary keys (to extend a table) -
  • Public interface for functions (not public static) -
  • Support reading the transaction log. -
  • Eliminate undo log records if stored on disk (just one pointer per block, not per record) -
  • Feature matrix as in i-net software. -
  • Updatable result set on table without primary key or unique index. -
  • Use LinkedList instead of ArrayList where applicable. -
  • Allow execution time prepare for SELECT * FROM CSVREAD(?, 'columnNameString') -
  • Support % operator (modulo). -
  • Support JMX: create an MBean for each database and server (support JConsole). - See http://thedevcloud.blogspot.com/2008/10/displaying-hsql-database-manager-in.html - http://java.sun.com/j2se/1.5.0/docs/api/java/lang/management/ManagementFactory.html#getPlatformMBeanServer() - http://java.sun.com/j2se/1.5.0/docs/guide/management/agent.html -
  • Support nested transactions. -
  • Add a benchmark for big databases, and one for many users. -
  • Compression in the result set (repeating values in the same column) over TCP/IP. -
  • Support curtimestamp (like curtime, curdate). -
  • Support ANALYZE {TABLE|INDEX} tableName COMPUTE|ESTIMATE|DELETE STATISTICS ptnOption options. -
  • Release locks (shared or exclusive) on demand -
  • Support OUTER UNION -
  • Support parameterized views (similar to CSVREAD, but using just SQL for the definition) -
  • A way (JDBC driver) to map an URL (jdbc:h2map:c1) to a connection object -
  • Option for SCRIPT to only process one or a set of tables, and append to a file -
  • Support linked tables to the current database -
  • Support dynamic linked schema (automatically adding/updating/removing tables) -
  • Clustering: adding a node should be very fast and without interrupting clients (very short lock) -
  • Compatibility with Derby: VALUES(1), (2); SELECT * FROM (VALUES (1), (2)) AS myTable(c1) -
  • Compatibility: # is the start of a single line comment (MySQL) but date quote (Access). Mode specific -
  • Run benchmarks with JDK 1.5, JDK 1.6, java -server -
  • Optimizations: faster hash function for strings, byte arrays -
  • DatabaseEventListener: callback for all operations (including expected time, RUNSCRIPT) and cancel functionality -
  • Benchmark: add a graph to show how databases scale (performance/database size) -
  • Implement a SQLData interface to map your data over to a custom object -
  • In the MySQL and PostgreSQL mode, use lower case identifiers by default (DatabaseMetaData.storesLowerCaseIdentifiers = true) -
  • Support multiple directories (on different hard drives) for the same database -
  • Server protocol: use challenge response authentication, but client sends hash(user+password) encrypted with response -
  • Support EXEC[UTE] (doesn't return a result set, compatible to MS SQL Server) -
  • Support native XML data type -
  • Support triggers with a string property or option: SpringTrigger, OSGITrigger -
  • Ability to resize the cache array when resizing the cache -
  • Time based cache writing (one second after writing the log) -
  • Check state of H2 driver for DDLUtils: https://issues.apache.org/jira/browse/DDLUTILS-185 -
  • Index usage for REGEXP LIKE. -
  • Compatibility: add a role DBA (like ADMIN). -
  • Better support multiple processors for in-memory databases. -
  • Support N'text' -
  • Support compatibility for jdbc:hsqldb:res: -
  • Provide an Java SQL builder with standard and H2 syntax -
  • Trace: write OS, file system, JVM,... when opening the database -
  • Support indexes for views (probably requires materialized views) -
  • Document SET SEARCH_PATH, BEGIN, EXECUTE, parameters -
  • Browser: use Desktop.isDesktopSupported and browse when using JDK 1.6 -
  • Server: use one listener (detect if the request comes from an PG or TCP client) -
  • Support data type INTERVAL -
  • Optimize SELECT MIN(ID), MAX(ID), COUNT(*) FROM TEST WHERE ID BETWEEN 100 AND 200 -
  • Sequence: PostgreSQL compatibility (rename, create) http://www.postgresql.org/docs/8.2/static/sql-altersequence.html -
  • DISTINCT: support large result sets by sorting on all columns (additionally) and then removing duplicates. -
  • Support a special trigger on all tables to allow building a transaction log reader. -
  • File system with a background writer thread; test if this is faster -
  • Better document the source code -
  • Support select * from dual a left join dual b on b.x=(select max(x) from dual) -
  • Optimization: don't lock when the database is read-only -
  • Issue 146: Support merge join. -
  • Integrate spatial functions from http://geosysin.iict.ch/irstv-trac/wiki/H2spatial/Download -
  • Cluster: hot deploy (adding a node at runtime) -
  • Compact databases without having to close the database (vacuum). -
  • Support COSH, SINH, and TANH functions -
  • Oracle: support DECODE method (convert to CASE WHEN). -
  • Native search: support "phrase search", wildcard search (* and ?), case-insensitive search, boolean operators, and grouping -
  • Improve documentation of access rights -
  • Support ENUM data type (see MySQL, PostgreSQL, MS SQL Server, maybe others) -
  • Remember the user defined data type (domain) of a column -
  • Support Jackcess (MS Access databases) -
  • Built-in methods to write large objects (BLOB and CLOB): FILE_WRITE('test.txt', 'Hello World') -
  • MVCC: support transactionally consistent backups using SCRIPT -
  • Improve time to open large databases (see mail 'init time for distributed setup') -
  • Move Maven 2 repository from hsql.sf.net to h2database.sf.net -
  • Java 1.5 tool: JdbcUtils.closeSilently(s1, s2,...) -
  • Javadoc: document design patterns used -
  • Write an article about SQLInjection (h2/src/docsrc/html/images/SQLInjection.txt) -
  • Convert SQL-injection-2.txt to html document, include SQLInjection.java sample -
  • Support OUT parameters in user-defined procedures. -
  • Web site design: http://www.igniterealtime.org/projects/openfire/index.jsp -
  • HSQLDB compatibility: Openfire server uses: CREATE SCHEMA PUBLIC AUTHORIZATION DBA; - CREATE USER SA PASSWORD ""; GRANT DBA TO SA; SET SCHEMA PUBLIC -
  • Translation: use ${.} in help.csv -
  • Translated .pdf -
  • MySQL compatibility: update test1 t1, test2 t2 set t1.id = t2.id where t1.id = t2.id; -
  • Recovery tool: bad blocks should be converted to INSERT INTO SYSTEM_ERRORS(...), and things should go into the .trace.db file -
  • RECOVER=2 to backup the database, run recovery, open the database -
  • Recovery should work with encrypted databases -
  • Corruption: new error code, add help -
  • Space reuse: after init, scan all storages and free those that don't belong to a live database object -
  • Use FilterIn / FilterOut putStream? -
  • Access rights: add missing features (users should be 'owner' of objects; missing rights for sequences; dropping objects) -
  • Support NOCACHE table option (Oracle). -
  • Support table partitioning. -
  • Index usage for UPDATE ... WHERE .. IN (SELECT...) -
  • Add regular javadocs (using the default doclet, but another css) to the homepage. -
  • The database should be kept open for a longer time when using the server mode. -
  • Javadocs: for each tool, add a copy & paste sample in the class level. -
  • Javadocs: add @author tags. -
  • Fluent API for tools: Server.createTcpServer().setPort(9081).setPassword(password).start(); -
  • MySQL compatibility: real SQL statement for DESCRIBE TEST -
  • Use a default delay of 1 second before closing a database. -
  • Write (log) to system table before adding to internal data structures. -
  • Support very large deletes and updates. -
  • Doclet (javadocs): constructors are not listed. -
  • Support direct lookup for MIN and MAX when using WHERE (see todo.txt / Direct Lookup). -
  • Support other array types (String[], double[]) in PreparedStatement.setObject(int, Object); -
  • MVCC should not be memory bound (uncommitted data is kept in memory in the delta index; maybe using a regular b-tree index solves the problem). -
  • Oracle compatibility: support NLS_DATE_FORMAT. -
  • Cluster: add feature to make sure cluster nodes can not get out of sync (for example by stopping one process). -
  • H2 Console: support CLOB/BLOB download using a link. -
  • Support flashback queries as in Oracle. -
  • Import / Export of fixed with text files. -
  • Support getGeneratedKeys to return multiple rows when used with batch updates. - This is supported by MySQL, but not Derby. Both PostgreSQL and HSQLDB don't support getGeneratedKeys. - Also support it when using INSERT ... SELECT. -
  • HSQLDB compatibility: automatic data type for SUM if value is the value is too big (by default use the same type as the data). -
  • Improve the optimizer to select the right index for special cases: where id between 2 and 4 and booleanColumn -
  • Linked tables: make hidden columns available (Oracle: rowid and ora_rowscn columns). -
  • H2 Console: in-place autocomplete. -
  • Support large databases: split database files to multiple directories / disks (similar to tablespaces). -
  • Support to assign a primary key index a user defined name. -
  • H2 Console: support configuration option for fixed width (monospace) font. -
  • Native fulltext search: support analyzers (specially for Chinese, Japanese). -
  • Automatically compact databases from time to time (as a background process). -
  • Support GRANT SELECT, UPDATE ON *. -
  • Test Eclipse DTP. -
  • H2 Console: autocomplete: keep the previous setting -
  • MySQL, MS SQL Server compatibility: support case sensitive (mixed case) identifiers without quotes. -
  • executeBatch: option to stop at the first failed statement. -
  • Implement OLAP features as described here: http://www.devx.com/getHelpOn/10MinuteSolution/16573/0/page/5 -
  • Support Oracle ROWID (unique identifier for each row). -
  • Server mode: improve performance for batch updates. -
  • Applets: support read-only databases in a zip file (accessed as a resource). -
  • Long running queries / errors / trace system table. -
  • H2 Console should support JaQu directly. -
  • H2 Console: support single file upload and directory download (optional). -
  • Document FTL_SEARCH, FTL_SEARCH_DATA. -
  • Sequences: CURRVAL should be session specific. Compatibility with PostgreSQL. -
  • Support DatabaseMetaData.insertsAreDetected: updatable result sets should detect inserts. -
  • Auto-server: add option to define the IP address range or list. -
  • Index creation using deterministic functions. -
  • Support DELETE with TOP or LIMIT. See also: http://dev.mysql.com/doc/refman/5.1/de/delete.html -
  • ANALYZE: for unique indexes that allow null, count the number of null. -
  • AUTO_SERVER: support changing IP addresses (disable a network while the database is open). -
  • Avoid using java.util.Calendar internally because it's slow, complicated, and buggy. -
  • Support TRUNCATE .. CASCADE like PostgreSQL. -
  • Support opening a database that is in the classpath, maybe using a new file system. -
  • Fulltext search: lazy result generation using SimpleRowSource. -
  • Support transformation to join for user defined functions, as for IN(SELECT...). -
  • Fulltext search: support alternative syntax: WHERE FTL_CONTAINS(name, 'hello'). -
  • MySQL compatibility: support REPLACE, see http://dev.mysql.com/doc/refman/5.1/de/replace.html -
  • MySQL compatibility: support INSERT INTO table SET column1 = value1, column2 = value2 -
  • Docs: add a one line description for each functions and SQL statements at the top (in the link section). -
  • Javadoc search: weight for titles should be higher ('random' should list Functions as the best match). -
  • Replace information_schema tables with regular tables that are automatically re-built when needed. Use indexes. -
  • Delete temporary files or objects using finalize. -
  • Oracle compatibility: support calling 0-parameters functions without parenthesis. Make constants obsolete. -
  • MySQL, HSQLDB compatibility: support where 'a'=1 (not supported by Derby, PostgreSQL) -
  • Allow calling function with no parameters without parenthesis. See http://code.google.com/p/h2database/issues/detail?id=50 -
  • CSV: currently # is a line comment and can start at any field. Make it optional. -
  • Finer granularity for SLF4J trace - See http://code.google.com/p/h2database/issues/detail?id=62 -
  • Add database creation date and time to the database. -
  • Support ASSERTIONS. -
  • Support multi-threaded kernel with multi-version concurrency. -
  • MySQL compatibility: support comparing 1='a' -
  • Support PostgreSQL lock modes: http://www.postgresql.org/docs/8.3/static/explicit-locking.html -
  • PostgreSQL compatibility: test DbVisualizer and Squirrel SQL using a new PostgreSQL JDBC driver. -
  • RunScript should be able to read from system in (or quite mode for Shell). -
  • Natural join: support select x from dual natural join dual. -
  • Natural join: somehow support this: select a.x, b.x, x from dual a natural join dual b -
  • Use the Java service provider mechanism to register file systems and function libraries. -
  • MySQL compatibility: for auto_increment columns, convert 0 to next value (as when inserting NULL). -
  • Optimization for multi-column IN: use an index if possible. Example: (A, B) IN((1, 2), (2, 3)). -
  • Optimization for EXISTS: convert to inner join or IN(..) if possible. -
  • Functions: support hashcode(value); cryptographic and fast -
  • Serialized file lock: support long running queries. -
  • Network: use 127.0.0.1 if other addresses don't work. -
  • Pluggable network protocol (currently Socket/ServerSocket over TCP/IP) - see also TransportServer with master slave replication. -
  • Select for update in mvcc mode: only lock the selected records. -
  • Support reading JCR data: one table per node type; query table; cache option -
  • OSGi: create a sample application, test, document. -
  • help.csv: use complete examples for functions; run as test case. -
  • Functions to calculate the memory and disk space usage of a table, a row, or a value. -
  • Re-implement PooledConnection; use a lightweight connection object. -
  • Doclet: convert tests in javadocs to a java class. -
  • Doclet: format fields like methods, but support sorting by name and value. -
  • Doclet: shrink the html files. -
  • MySQL compatibility: support REPLACE - See http://code.google.com/p/h2database/issues/detail?id=73 -
  • MySQL compatibility: support SET NAMES 'latin1' - See also http://code.google.com/p/h2database/issues/detail?id=56 -
  • MySQL compatibility: DELETE .. FROM .. USING - See http://dev.mysql.com/doc/refman/5.0/en/delete.html -
  • Allow to scan index backwards starting with a value (to better support ORDER BY DESC). -
  • Java Service Wrapper: try http://yajsw.sourceforge.net/ -
  • Batch parameter for INSERT, UPDATE, and DELETE, and commit after each batch. See also MySQL DELETE. -
  • MySQL compatibility: support ALTER TABLE .. MODIFY COLUMN. -
  • Use a lazy and auto-close input stream (open resource when reading, close on eof). -
  • PostgreSQL compatibility: generate_series. -
  • Connection pool: 'reset session' command (delete temp tables, rollback, autocommit true). -
  • Improve SQL documentation, see http://www.w3schools.com/sql/ -
  • MySQL compatibility: DatabaseMetaData.stores*() methods should return the same values. Test with SquirrelSQL. -
  • MS SQL Server compatibility: support DATEPART syntax. -
  • Oracle compatibility: support CREATE OR REPLACE VIEW syntax. -
  • Sybase/DB2/Oracle compatibility: support out parameters in stored procedures - See http://code.google.com/p/h2database/issues/detail?id=83 -
  • Support INTERVAL data type (see Oracle and others). -
  • Combine Server and Console tool (only keep Server). -
  • Store the Lucene index in the database itself. -
  • Support standard MERGE statement: http://en.wikipedia.org/wiki/Merge_%28SQL%29 -
  • Oracle compatibility: support DECODE(x, ...). -
  • Console: Start Browser: if ip number changed, try localhost instead. -
  • MVCC: compare concurrent update behavior with PostgreSQL and Oracle. -
  • HSQLDB compatibility: CREATE FUNCTION (maybe using a Function interface). -
  • HSQLDB compatibility: support CALL "java.lang.Math.sqrt"(2.0) -
  • Support comma as the decimal separator in the CSV tool. -
  • Compatibility: Support jdbc:default:connection using ThreadLocal (part of SQLJ) -
  • Compatibility: Java functions with SQLJ Part1 http://www.acm.org/sigmod/record/issues/9912/standards.pdf.gz -
  • Compatibility: Java functions with SQL/PSM (Persistent Stored Modules) - need to find the documentation. -
  • CACHE_SIZE: automatically use a fraction of Runtime.maxMemory - maybe automatically the second level cache. -
  • Support date/time/timestamp as documented in http://en.wikipedia.org/wiki/ISO_8601 -
  • PostgreSQL compatibility: when in PG mode, treat BYTEA data like PG. -
  • MySQL compatibility: REPLACE http://dev.mysql.com/doc/refman/6.0/en/replace.html -
  • Support =ANY(array) as in PostgreSQL. See also http://www.postgresql.org/docs/8.0/interactive/arrays.html -
  • IBM DB2 compatibility: support PREVIOUS VALUE FOR sequence. -
  • MySQL compatibility: alter table add index i(c), add constraint c foreign key(c) references t(c); -
  • Compatibility: use different LIKE ESCAPE characters depending on the mode (disable for Derby, HSQLDB, DB2, Oracle, MSSQLServer). -
  • Oracle compatibility: support CREATE SYNONYM table FOR schema.table. -
  • Optimize A=? OR B=? to UNION if the cost is lower. -
  • FTP: document the server, including -ftpTask option to execute / kill remote processes -
  • FTP: problems with multithreading? -
  • FTP: implement SFTP / FTPS -
  • FTP: access to a database (.csv for a table, a directory for a schema, a file for a lob, a script.sql file). -
  • More secure default configuration if remote access is enabled. -
  • Improve database file locking (maybe use native file locking). The current approach seems to be problematic - if the file system is on a remote share (see Google Group 'Lock file modification time is in the future'). -
  • Document internal features such as BELONGS_TO_TABLE, NULL_TO_DEFAULT, SEQUENCE. -
  • Issue 107: Prefer using the ORDER BY index if LIMIT is used. -
  • An index on (id, name) should be used for a query: select * from t where s=? order by i -
  • Support reading sequences using DatabaseMetaData.getTables(null, null, null, new String[]{"SEQUENCE"}). - See PostgreSQL. -
  • Add option to enable TCP_NODELAY using Socket.setTcpNoDelay(true). -
  • Maybe disallow = within database names (jdbc:h2:mem:MODE=DB2 means database name MODE=DB2). -
  • Fast alter table add column. -
  • Improve concurrency for in-memory database operations. -
  • Issue 122: Support for connection aliases for remote tcp connections. -
  • Fast scrambling (strong encryption doesn't help if the password is included in the application). -
  • Support using system properties in database URLs (may be a security problem). -
  • Issue 126: The index name should be "IDX_" plus the constraint name unless there is a conflict, in which case append a number. -
  • Issue 127: Support activation/deactivation of triggers -
  • Issue 130: Custom log event listeners -
  • Issue 131: IBM DB2 compatibility: sysibm.sysdummy1 -
  • Issue 132: Use Java enum trigger type. -
  • Issue 134: IBM DB2 compatibility: session global variables. -
  • Cluster: support load balance with values for each server / auto detect. -
  • FTL_SET_OPTION(keyString, valueString) with key stopWords at first. -
  • Pluggable access control mechanism. -
  • Fulltext search (Lucene): support streaming CLOB data. -
  • Document/example how to create and read an encrypted script file. -
  • Check state of https://issues.apache.org/jira/browse/OPENJPA-1367 (H2 does support cross joins). -
  • Fulltext search (Lucene): only prefix column names with _ if they already start with _. Instead of DATA / QUERY / modified use _DATA, _QUERY, _MODIFIED if possible. -
  • Support a way to create or read compressed encrypted script files using an API. -
  • Scripting language support (Javascript). -
  • The network client should better detect if the server is not an H2 server and fail early. -
  • H2 Console: support CLOB/BLOB upload. -
  • Move away from system properties where possible. -
  • Database file lock: detect hibernate / standby / very slow threads (compare system time). -
  • Automatic detection of redundant indexes. -
  • Maybe reject join without "on" (except natural join). -
  • Implement GiST (Generalized Search Tree for Secondary Storage). -
  • Function to read a number of bytes/characters from an BLOB or CLOB. -
  • Issue 156: Support SELECT ? UNION SELECT ?. -
  • Automatic mixed mode: support a port range list (to avoid firewall problems). -
  • Support the pseudo column rowid, oid, _rowid_. -
  • H2 Console / large result sets: stream early instead of keeping a whole result in-memory -
  • Support TRUNCATE for linked tables. -
  • UNION: evaluate INTERSECT before UNION (like most other database except Oracle). -
  • Delay creating the information schema, and share metadata columns. -
  • TCP Server: use a nonce (number used once) to protect unencrypted channels against replay attacks. -
  • Simplify running scripts and recovery: CREATE FORCE USER (overwrites an existing user). -
  • Support CREATE DATABASE LINK (a custom JDBC driver is already supported). -
  • Issue 163: Allow to create foreign keys on metadata types. -
  • Logback: write a native DBAppender. -
  • Cache size: don't use more cache than what is available. -
  • Tree index: Instead of an AVL tree, use a general balanced trees or a scapegoat tree. -
  • User defined functions: allow to store the bytecode (of just the class, or the jar file of the extension) in the database. -
  • Compatibility: ResultSet.getObject() on a CLOB (TEXT) should return String for PostgreSQL and MySQL. -
  • Optimizer: WHERE X=? AND Y IN(?), it always uses the index on Y. Should be cost based. -
  • Support ALTER SCHEMA name RENAME TO newName (rename schema). -
  • Make the cache scan resistant (currently a small cache is faster than a large cache for large table scans). -
  • Issue 178: Optimizer: index usage when both ascending and descending indexes are available -
  • Issue 179: Related subqueries in HAVING clause -
  • IBM DB2 compatibility: NOT NULL WITH DEFAULT. Similar to MySQL Mode.convertInsertNullToZero. -
  • Creating primary key: always create a constraint. -
  • Support a data type "timestamp with timezone" using java.util.Calendar. -
  • Maybe use a different page layout: keep the data at the head of the page, and ignore the tail - (don't store / read it). This may increase write / read performance depending on the file system. -
  • Indexes of temporary tables are currently kept in-memory. Is this how it should be? -
  • The Shell tool should support the same built-in commands as the H2 Console. -
  • Maybe use PhantomReference instead of finalize. -
  • Database file name suffix: a way to use no or a different suffix (for example using a slash). -
  • Database file name suffix: should only have one dot by default. Example: .h2db -
  • Issue 196: Function based indexes -
  • Fix the disk space leak (killing the process at the exact right moment will increase - the disk space usage; this space is not re-used). See TestDiskSpaceLeak.java -
  • ROWNUM: Oracle compatibility when used within a subquery. Issue 198. -
  • Allow to access the database over HTTP (possibly using port 80) and a servlet in a REST way. -
  • ODBC: encrypted databases are not supported because the ;CIPHER= can not be set. -
  • Support CLOB and BLOB update, specially conn.createBlob().setBinaryStream(1); -
  • Triggers: support user defined execution order. Oracle: - CREATE OR REPLACE TRIGGER TEST_2 BEFORE INSERT - ON TEST FOR EACH ROW FOLLOWS TEST_1. - SQL specifies that multiple triggers should be fired in time-of-creation order. - PostgreSQL uses name order, which was judged to be more convenient. - Derby: triggers are fired in the order in which they were created. -
  • PostgreSQL compatibility: combine "users" and "roles". See: - http://www.postgresql.org/docs/8.1/interactive/user-manag.html -
  • Support NULL with a type: @meta CALL CAST(NULL AS INT) should return INT. - See the ValueExpression.java (currently it returns the type of the value; - it could have it's own type/precision/scale optionally, for example when created from CAST, - which is implemented in Function.java). -
  • Improve documentation of system properties: only list the property names, default values, and description. -
  • Support running totals / cumulative sum using SUM(..) OVER(..). -
  • Improve object memory size calculation. Use constants for known VMs, or use reflection to call java.lang.instrument.Instrumentation.getObjectSize(Object objectToSize) -
- -

Not Planned

-
    -
  • HSQLDB (did) support this: select id i from test where i<0 (other databases don't). Supporting it may break compatibility. -
  • String.intern (so that Strings can be compared with ==) will not be used because some VMs have problems when used extensively. -
  • In prepared statements, identifier names (table names and so on) can not be parameterized. Adding such a feature would complicate the source code without providing reasonable speedup, and would slow down regular prepared statements. -
- -
- diff --git a/tools/h2/src/docsrc/html/search.js b/tools/h2/src/docsrc/html/search.js deleted file mode 100755 index c3b6845..0000000 --- a/tools/h2/src/docsrc/html/search.js +++ /dev/null @@ -1,265 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ - -var pages = new Array(); -var ref = new Array(); -var ignored = ''; -var firstLink = null; -var firstLinkWord = null; - -String.prototype.endsWith = function(suffix) { - var startPos = this.length - suffix.length; - if (startPos < 0) { - return false; - } - return (this.lastIndexOf(suffix, startPos) == startPos); -}; - -function listWords(value, open) { - value = replaceOtherChars(value); - value = trim(value); - if (pages.length == 0) { - load(); - } - var table = document.getElementById('result'); - while (table.rows.length > 0) { - table.deleteRow(0); - } - firstLink = null; - var clear = document.getElementById('clear'); - if (value.length == 0) { - clear.style.display = 'none'; - return true; - } - clear.style.display = ''; - var keywords = value.split(' '); - if (keywords.length > 1) { - listAnd(keywords); - return true; - } - if (value.length < 3) { - max = 100; - } else { - max = 1000; - } - value = value.toLowerCase(); - var r = ref[value.substring(0, 1)]; - if (r == undefined) { - return true; - } - var x = 0; - var words = r.split(';'); - var count = 0; - for ( var i = 0; i < words.length; i++) { - var wordRef = words[i]; - if (wordRef.toLowerCase().indexOf(value) == 0) { - count++; - } - } - for ( var i = 0; i < words.length && (x <= max); i++) { - var wordRef = words[i]; - if (wordRef.toLowerCase().indexOf(value) == 0) { - word = wordRef.split("=")[0]; - var tr = table.insertRow(x++); - var td = document.createElement('td'); - var tdClass = document.createAttribute('class'); - tdClass.nodeValue = 'searchKeyword'; - td.setAttributeNode(tdClass); - - var ah = document.createElement('a'); - var href = document.createAttribute('href'); - href.nodeValue = 'javascript:set("' + word + '");'; - var link = document.createTextNode(word); - ah.setAttributeNode(href); - ah.appendChild(link); - td.appendChild(ah); - tr.appendChild(td); - piList = wordRef.split("=")[1].split(","); - if (count < 20 || open == word) { - x = addReferences(x, piList, word); - } - } - } - if (x == 0) { - if (ignored.indexOf(';' + value + ';') >= 0) { - noResults(table, 'Common word (not indexed)'); - } else { - noResults(table, 'No results found!'); - } - } - return true; -} - -function set(v) { - if (pages.length == 0) { - load(); - } - var search = document.getElementById('search').value; - listWords(search, v); - document.getElementById('search').focus(); - window.scrollBy(-20, 0); -} - -function goFirst() { - var table = document.getElementById('result'); - if (firstLink != null) { - go(firstLink, firstLinkWord); - } - return false; -} - -function go(pageId, word) { - var page = pages[pageId]; - var load = '../' + page.file + '?highlight=' + encodeURIComponent(word); - if (top.main) { - if (!top.main.location.href.endsWith(page.file)) { - top.main.location = load; - } - } else { - if (!document.location.href.endsWith(page.file)) { - var search = document.getElementById('search').value; - document.location = load + '&search=' + encodeURIComponent(search); - } - } -} - -function listAnd(keywords) { - var count = new Array(); - var weight = new Array(); - for ( var i = 0; i < pages.length; i++) { - count[i] = 0; - weight[i] = 0; - } - for ( var i = 0; i < keywords.length; i++) { - var value = keywords[i].toLowerCase(); - var r = ref[value.substring(0, 1)]; - if (r == undefined) { - return true; - } - var words = r.split(';'); - for ( var j = 0; j < words.length; j++) { - var wordRef = words[j]; - if (wordRef.toLowerCase().indexOf(value) == 0) { - piList = wordRef.split("=")[1].split(","); - var w = 1; - for ( var k = 0; k < piList.length; k++) { - var pi = piList[k]; - if (pi.charAt(0) == 't') { - pi = pi.substring(1); - w = 10000; - } else if (pi.charAt(0) == 'h') { - pi = pi.substring(1); - w = 100; - } else if (pi.charAt(0) == 'r') { - pi = pi.substring(1); - w = 1; - } - if (count[pi] >= i) { - if (count[pi] == i) { - count[pi]++; - } - weight[pi] += w; - } - } - } - } - } - var x = 0; - var table = document.getElementById('result'); - var piList = new Array(); - var piWeight = new Array(); - for ( var i = 0; i < pages.length; i++) { - if (count[i] >= keywords.length) { - piList[x] = '' + i; - piWeight[x] = weight[i]; - x++; - } - } - // sort - for ( var i = 1, j; i < x; i++) { - var tw = piWeight[i]; - var ti = piList[i]; - for (j = i - 1; j >= 0 && (piWeight[j] < tw); j--) { - piWeight[j + 1] = piWeight[j]; - piList[j + 1] = piList[j]; - } - piWeight[j + 1] = tw; - piList[j + 1] = ti; - } - addReferences(0, piList, keywords); - if (piList.length == 0) { - noResults(table, 'No results found'); - } -} - -function addReferences(x, piList, word) { - var table = document.getElementById('result'); - for ( var j = 0; j < piList.length; j++) { - var pi = piList[j]; - if (pi.charAt(0) == 't') { - pi = pi.substring(1); - } else if (pi.charAt(0) == 'h') { - pi = pi.substring(1); - } else if (pi.charAt(0) == 'r') { - pi = pi.substring(1); - } - var tr = table.insertRow(x++); - var td = document.createElement('td'); - var tdClass = document.createAttribute('class'); - tdClass.nodeValue = 'searchLink'; - td.setAttributeNode(tdClass); - var ah = document.createElement('a'); - var href = document.createAttribute('href'); - var thisLink = 'javascript:go(' + pi + ', "' + word + '")'; - if (firstLink == null) { - firstLink = pi; - firstLinkWord = word; - } - href.nodeValue = thisLink; - ah.setAttributeNode(href); - var page = pages[pi]; - var link = document.createTextNode(page.title); - ah.appendChild(link); - td.appendChild(ah); - tr.appendChild(td); - } - return x; -} - -function trim(s) { - while (s.charAt(0) == ' ' && s.length > 0) { - s = s.substring(1); - } - while (s.charAt(s.length - 1) == ' ' && s.length > 0) { - s = s.substring(0, s.length - 1); - } - return s; -} - -function replaceOtherChars(s) { - var x = ""; - for ( var i = 0; i < s.length; i++) { - var c = s.charAt(i); - if ("\t\r\n\"'.,:;!&/\\?%@`[]{}()+-=<>|*^~#$".indexOf(c) >= 0) { - c = " "; - } - x += c; - } - return x; -} - -function noResults(table, message) { - var tr = table.insertRow(0); - var td = document.createElement('td'); - var tdClass = document.createAttribute('class'); - tdClass.nodeValue = 'searchKeyword'; - td.setAttributeNode(tdClass); - var text = document.createTextNode(message); - td.appendChild(text); - tr.appendChild(td); -} - diff --git a/tools/h2/src/docsrc/html/source.html b/tools/h2/src/docsrc/html/source.html deleted file mode 100755 index 3912a1c..0000000 --- a/tools/h2/src/docsrc/html/source.html +++ /dev/null @@ -1,69 +0,0 @@ - - -Source Code Viewer - - -
-
-    
-        
-        
-    
-
- - - -
- - - -
diff --git a/tools/h2/src/docsrc/html/sourceError.html b/tools/h2/src/docsrc/html/sourceError.html deleted file mode 100755 index 7dc7bd2..0000000 --- a/tools/h2/src/docsrc/html/sourceError.html +++ /dev/null @@ -1,240 +0,0 @@ - - - - -Error Analyzer - - - - - - - - -

Error Analyzer

-Home
-

- Input  - Details  - Source Code -

-
-
-

Paste the error message and stack trace below and click on 'Details' or 'Source Code':

- -
-
-

Error Code:

-

Product Version:

-

Message:

-

-

More Information:

- -
-
- - -
-

Stack Trace:

- -
-

Source File:
- Raw file (fast; only Firefox)

- -
-
- - - diff --git a/tools/h2/src/docsrc/html/stylesheet.css b/tools/h2/src/docsrc/html/stylesheet.css deleted file mode 100755 index efdd0ce..0000000 --- a/tools/h2/src/docsrc/html/stylesheet.css +++ /dev/null @@ -1,335 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ - -td, input, select, textarea, body, code, pre, td, th { - font: 9pt/130% Tahoma, Arial, Helvetica, sans-serif; - font-weight: normal; -} - -h1, h2, h3, h4, h5 { - font: 9pt Tahoma, Arial, Helvetica, sans-serif; - font-weight: bold; -} - -td, input, select, textarea, body, code, pre { - font-size: 9pt; -} - -pre { - background-color: #ece9d8; - border: 1px solid rgb(172, 168, 153); - padding: 4px; -} - -code { - background-color: #ece9d8; - padding: 0px 2px; -} - -img { - border: 0px; -} - -body { - max-width: 800px; - clear: both; - width: 800px; - margin: 0 auto; -} - -h1 { - background-color: #0000bb; - padding: 2px 4px 2px 4px; - color: #fff; - font-size: 15pt; - line-height: normal; -} - -h2 { - font-size: 13pt; - margin-top: 1.5em; -} - -h3 { - font-size: 11pt; - margin-top: 1.5em; -} - -h4 { - font-size: 9pt; - margin-top: 1.5em; -} - -hr { - color: #CCC; - background-color: #CCC; - height: 1px; - border: 0px solid blue; -} - -table { - background-color: #ffffff; - border-collapse: collapse; - border: 1px solid #aca899; -} - -th { - text-align: left; - background-color: #ece9d8; - border: 1px solid #aca899; - padding: 2px; -} - -td { - background-color: #ffffff; - text-align: left; - vertical-align: top; - border: 1px solid #aca899; - padding: 2px; -} - -form { -} - -ul, ol { - list-style-position: outside; - padding-left: 20px; -} - -li { - margin-top: 2px; -} - -a { - text-decoration: none; - color: #0000ff; -} - -a:hover { - text-decoration: underline; -} - -em.u { - text-decoration: underline; - font-style: normal; -} - -.menu { - margin: 10px 10px 10px 10px; -} - -table.search { - width: 100%; - border: 0px; -} - -tr.search { - border: 0px; -} - -td.search { - border: 0px; - padding: 2px 0px 2px 10px; -} - -td.searchKeyword { - border: 0px; - padding: 0px 0px 0px 2px; -} - -td.searchKeyword a { - text-decoration: none; - color: #000000; -} - -td.searchKeyword a:hover { - text-decoration: underline; -} - -td.searchLink { - border: 0px; - padding: 0px 0px 0px 32px; - text-indent: -16px; -} - -td.searchLink a { - text-decoration: none; - color: #0000ff; -} - -td.searchLink a:hover { - text-decoration: underline; -} - -table.nav { - border: 0px; -} - -tr.nav { - border: 0px; -} - -td.nav { - border: 0px; -} - -table.content { - width: 100%; - height: 100%; - border: 0px; -} - -tr.content { - border:0px; -} - -td.content { - border:0px; -} - -.contentDiv { - margin:10px; -} - -.content { - margin: 10px 10px 10px 0px; -} - -.screenshot { - border: 1px outset #800; - padding: 10px; - margin: 10px 0px; -} - -.compareFeature { -} - -.compareY { - color: #050; -} - -.compareN { - color: #800; -} - -table.index { - width: 100%; - border: 0px; - padding: 0px; - margin: 0px; - border: 0px none; - border-collapse: collapse; -} - -/* width: 570px; - width: 190px; - */ - -td.index { - width: 33%; - border: 0px; - padding: 0px; - margin: 0px; - border: 0px none; - border-collapse: collapse; - vertical-align: top; -} - -.railroad { - border: 0px; - padding: 0px; - margin: 0px; - border-collapse: collapse; - vertical-align: top; -} - -.c { - padding: 1px 3px; - margin: 0px 0px; - border: 2px solid; - -moz-border-radius: 0.4em; - border-radius: 0.4em; - background-color: #fff; -} - -.ts { - border: 0px; - padding: 0px; - margin: 0px; - border-collapse: collapse; - vertical-align: top; - height: 24px; - background-image: url(images/div-ts.png); - width: 16px; -} - -.ls { - border: 0px; - padding: 0px; - margin: 0px; - border-collapse: collapse; - vertical-align: top; - height: 24px; - background-image: url(images/div-ls.png); - width: 16px; -} - -.ks { - border: 0px; - padding: 0px; - margin: 0px; - border-collapse: collapse; - vertical-align: top; - height: 24px; - background-image: url(images/div-ks.png); - width: 16px; -} - -.te { - border: 0px; - padding: 0px; - margin: 0px; - border-collapse: collapse; - vertical-align: top; - height: 24px; - background-image: url(images/div-te.png); - width: 16px; -} - -.le { - border: 0px; - padding: 0px; - margin: 0px; - border-collapse: collapse; - vertical-align: top; - height: 24px; - background-image: url(images/div-le.png); - width: 16px; -} - -.ke { - border: 0px; - padding: 0px; - margin: 0px; - border-collapse: collapse; - vertical-align: top; - height: 24px; - background-image: url(images/div-ke.png); - width: 16px; -} - -.d { - border: 0px; - padding: 0px; - margin: 0px; - border-collapse: collapse; - vertical-align: top; - height: 24px; - background-image: url(images/div-d.png); - background-repeat: repeat-x; - min-width: 16px; -} diff --git a/tools/h2/src/docsrc/html/stylesheetPdf.css b/tools/h2/src/docsrc/html/stylesheetPdf.css deleted file mode 100755 index 48d4701..0000000 --- a/tools/h2/src/docsrc/html/stylesheetPdf.css +++ /dev/null @@ -1,155 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ - -td, input, select, textarea, body, code, pre, td, th { - font: 9pt Tahoma, Arial, Helvetica, sans-serif; - font-weight: normal; -} - -h1, h2, h3, h4, h5 { - font: 9pt Arial, Helvetica, sans-serif; - font-weight: bold; -} - -td, input, select, textarea, body, code, pre { - font-size: 9pt; -} - -pre { - background-color: #ece9d8; - border: 1px solid rgb(172, 168, 153); - padding: 4px; -} - -img { - border: 0px; -} - -body { - margin: 0px; -} - -h1 { - background-color: #0000bb; - padding: 2px 4px 2px 4px; - color: #fff; - font-size: 15pt; - line-height: normal; -} - -h2 { - font-size: 13pt; - margin-top: 1.5em; -} - -h3 { - font-size: 11pt; - margin-top: 1.5em; -} - -h4 { - font-size: 9pt; - margin-top: 1.5em; -} - -hr { - color: #CCC; - background-color: #CCC; - height: 1px; - border: 0px solid blue; -} - -table { - background-color: #ffffff; - border-collapse: collapse; - border: 1px solid #aca899; -} - -th { - font-size: 9pt; - font-weight: normal; - text-align: left; - background-color: #ece9d8; - border: 1px solid #aca899; - padding: 2px; -} - -td { - background-color: #ffffff; - font-size: 9pt; - text-align: left; - vertical-align: top; - border: 1px solid #aca899; - padding: 2px; - margin: 0px; -} - -form { -} - -ul, ol { - list-style-position: outside; - padding-left: 20px; -} - -li { - margin-top: 2px; -} - -a { - text-decoration: none; - color: #0000ff; -} - -a:hover { - text-decoration: underline; -} - -em.u { - text-decoration: underline; - font-style: normal; -} - -.screenshot { - border: 1px outset #888; - padding: 10px; - margin: 10px 0px; -} - -.compareFeature { -} - -.compareY { - color: #050; -} - -.compareN { - color: #800; -} - -table.index { - width: 100%; - border: 0px; - padding: 0px; - margin: 0px; - border: 0px none; - border-collapse: collapse; -} - -/* width: 570px; - width: 190px; - */ - -td.index { - width: 33%; - border: 0px; - padding: 0px; - margin: 0px; - border: 0px none; - border-collapse: collapse; - vertical-align: top; -} diff --git a/tools/h2/src/docsrc/html/tutorial.html b/tools/h2/src/docsrc/html/tutorial.html deleted file mode 100755 index 2322548..0000000 --- a/tools/h2/src/docsrc/html/tutorial.html +++ /dev/null @@ -1,1160 +0,0 @@ - - - - -Tutorial - - - - -
- - -

Tutorial

- - Starting and Using the H2 Console
- - Special H2 Console Syntax
- - Settings of the H2 Console
- - Connecting to a Database using JDBC
- - Creating New Databases
- - Using the Server
- - Using Hibernate
- - Using TopLink and Glassfish
- - Using EclipseLink
- - Using Databases in Web Applications
- - CSV (Comma Separated Values) Support
- - Upgrade, Backup, and Restore
- - Command Line Tools
- - The Shell Tool
- - Using OpenOffice Base
- - Java Web Start / JNLP
- - Using a Connection Pool
- - Fulltext Search
- - User-Defined Variables
- - Date and Time
- - Using Spring
- -

Starting and Using the H2 Console

-

-The H2 Console 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. -

-Web Browser - H2 Console Server - H2 Database -

-This is a client / server application, so both a server and a client (a browser) are required to run it. -

-Depending on your platform and environment, there are multiple ways to start the application: -

- - - - - - - - - - - - - - - - - - -
OSStart
Windows - Click [Start], [All Programs], [H2], and [H2 Console (Command Line)]
- When using the Sun JDK 1.5, a window with the title 'H2 Console ' should appear. - When using the Sun JDK 1.6, an icon will be added to the system tray: - [H2 icon]
- If you don't get the window and 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 at http://localhost:8082. -
Windows - Open a file browser, navigate to h2/bin, and - double click on h2.bat.
- A console window appears. If there is a problem, you will see an error message - in this window. A browser window will open and point to the Login page - (URL: http://localhost:8082). -
Any - Double click on the h2*.jar file. - This only works if the .jar suffix is associated with java. -
Any - Open a console window, navigate to the directory h2/bin and type: -
java -cp h2*.jar org.h2.tools.Server
-
- -

Firewall

-

-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 application 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. -

-

-It has been reported that when using Kaspersky 7.0 with firewall, the H2 Console is very slow when -connecting over the IP address. A workaround is to connect using localhost, however this only works -on the local machine. -

-

-A small firewall is already built into the server: other computers may not connect to the server by default. -To change this, go to 'Preferences' and select 'Allow connections from other computers'. -

- -

Testing Java

-

-To find out which version of Java is installed, open a command prompt and type: -

-
-java -version
-
-

-If you get an error message, you may need to add the Java binary directory to the path environment variable. -

- -

Error Message 'Port may be in use'

-

-You can only start one instance of the H2 Console, -otherwise you will get the following error message: -"The Web server could not be started. Possible cause: another server is already running...". -It is possible to start multiple console applications on the same computer (using different ports), -but this is usually not required as the console supports multiple concurrent connections. -

- -

Using another Port

-

-If the port is in use by another application, you may want to start the H2 Console on a different port. -This can be done by changing the port in the file .h2.server.properties. This file is stored -in the user directory (for Windows, this is usually in Documents and Settings/<username>). -The relevant entry is webPort. -

- -

Connecting to the Server using a Browser

-

-If the server started successfully, you can connect to it using a web browser. -JavaScript needs to be enabled. -If you started the server on the same computer as the browser, open the URL http://localhost:8082. -If you want to connect to the application from another computer, you need to provide the IP address of the server, for example: -http://192.168.0.2:8082. -If you enabled SSL on the server side, the URL needs to start with https://. -

- -

Multiple Concurrent Sessions

-

-Multiple concurrent browser sessions are supported. As that the database objects reside on the server, -the amount of concurrent work is limited by the memory available to the server application. -

- -

Login

-

-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]. -

-You can save and reuse previously saved settings. The settings are stored in a properties file -(see Settings of the H2 Console). -

- -

Error Messages

-

-Error messages in are shown in red. You can show/hide the stack trace of the exception -by clicking on the message. -

- -

Adding Database Drivers

-

-Additional database drivers to connect to other databases (MySQL, PostgreSQL, HSQLDB,...) -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. -

-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. -

- -

Using the H2 Console

-

-The H2 Console application has three main panels: the toolbar on top, the tree on the left, and the query / result panel on the right. -The database objects (for example, tables) are listed on the left panel. -Type in a SQL command on the query panel and click 'Run'. The result of the command appears just below the command. -

- -

Inserting Table Names or Column Names

-

-The table name and column names can be inserted in the script by clicking them in the tree. -If you click on a table while the query is empty, then SELECT * FROM ... is added as well. -While typing a query, the table that was used is automatically expanded in the tree. -For example if you type SELECT * FROM TEST T WHERE T. then the table TEST is automatically expanded in the tree. -

- -

Disconnecting and Stopping the Application

-

-To log out of the database, click 'Disconnect' in the toolbar panel. -However, the server is still running and ready to accept new sessions. -

-To stop the server, right click on the system tray icon and select [Exit]. -If you don't have the system tray icon, -navigate to [Preferences] and click [Shutdown], -press [Ctrl]+[C] in the console where the server was started (Windows), -or close the console window. -

- -

Special H2 Console Syntax

-

-The H2 Console supports a few built-in commands. -Those are interpreted within the H2 Console, that means they work with any database. -They need to be at the beginning of a statement (before any remarks), -otherwise they are not parsed correctly. If in doubt, add ';' before the command. -

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Command(s)Description
- @autocommit_true;
- @autocommit_false; -
- Enable or disable autocommit. -
- @cancel; - - Cancel the currently running statement. -
- @columns null null TEST;
- @index_info null null TEST;
- @tables;
- @tables null null TEST;
-
- Call the corresponding DatabaseMetaData.get method. - Patterns are case sensitive (usually identifiers are uppercase). - For information about the parameters, see the Javadoc documentation. - Missing parameters at the end are set to null. The complete list of commands is: - - @attributes @best_row_identifier @catalogs @columns - @column_privileges @cross_references @exported_keys - @imported_keys @index_info @primary_keys @procedures - @procedure_columns @schemas @super_tables @super_types - @tables @table_privileges @table_types @type_info @udts - @version_columns - -
- @edit select * from test; - - Use an updatable result set. -
- @generated insert into test() values(); - - Show the result of Statement.getGeneratedKeys(). -
- @history; - - Show the command history. -
- @info; - - Display the result of various Connection and DatabaseMetaData methods. -
- @list select * from test; - - Show the result set in list format (each column on its own line, with row numbers). -
- @loop 1000 select ?, ?/*rnd*/;
- @loop 1000 @statement select ?; -
- Run the statement this many times. - Parameters (?) are set using a loop from 0 up to x - 1. - Random values are used for each ?/*rnd*/. - A Statement object is used instead of a PreparedStatement if @statement is used. - Result sets are read until ResultSet.next() returns false. - Timing information is printed. -
- @maxrows 20; - - Set the maximum number of rows to display. -
- @memory; - - Show the used and free memory. This will call System.gc(). -
- @meta select 1; - - List the ResultSetMetaData after running the query. -
- @parameter_meta select ?; - - Show the result of the PreparedStatement.getParameterMetaData() calls. - The statement is not executed. -
- @prof_start;
- call hash('SHA256', '', 1000000);
- @prof_stop; -
- Start / stop the built-in profiling tool. - The top 3 stack traces of the statement(s) between start and stop are listed - (if there are 3). -
- @transaction_isolation;
- @transaction_isolation 2; -
- Display (without parameters) or change - (with parameters 1, 2, 4, 8) the transaction isolation level. -
- -

Settings of the H2 Console

-

-The settings of the H2 Console are stored in a configuration file -called .h2.server.properties in you user home directory. -For Windows installations, the user home directory is usually C:\Documents and Settings\[username]. -The configuration file contains the settings of the application and is automatically created when the H2 Console is first started. -

- -

Connecting to a Database using JDBC

-

-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: -

-
-import java.sql.*;
-public class Test {
-    public static void main(String[] a)
-            throws Exception {
-        Class.forName("org.h2.Driver");
-        Connection conn = DriverManager.
-            getConnection("jdbc:h2:~/test", "sa", "");
-        // add application code here
-        conn.close();
-    }
-}
-
-

-This code first loads the driver (Class.forName(...)) -and then opens a connection (using DriverManager.getConnection()). -The driver name is "org.h2.Driver". -The database URL always needs to start with jdbc:h2: -to be recognized by this database. The second parameter in the getConnection() call -is the user name (sa for System Administrator in this example). The third parameter is the password. -In this database, user names are not case sensitive, but passwords are. -

- -

Creating New Databases

-

-By default, if the database specified in the URL does not yet exist, a new (empty) -database is created automatically. The user that created the database automatically becomes -the administrator of this database. -

-

-Auto-creating new database can be disabled, see -Opening a Database Only if it Already Exists. -

- -

Using the Server

-

-H2 currently supports three server: a web server (for the H2 Console), -a TCP server (for client/server connections) and an PG server (for PostgreSQL clients). -Please note that only the web server supports browser connections. -The servers can be started in different ways, one is using the Server tool. -

- -

Starting the Server Tool from Command Line

-

-To start the Server tool from the command line with the default settings, run: -

-
-java -cp h2*.jar org.h2.tools.Server
-
-

-This will start the tool with the default options. To get the list of options and default values, run: -

-
-java -cp h2*.jar org.h2.tools.Server -?
-
-

-There are options available to use other ports, and start or not start parts. -

- -

Connecting to the TCP Server

-

-To remotely connect to a database using the TCP server, use the following driver and database URL: -

-
    -
  • JDBC driver class: org.h2.Driver -
  • Database URL: jdbc:h2:tcp://localhost/~/test -
-

-For details about the database URL, see also in Features. -Please note that you can't connection with a web browser to this URL. -You can only connect using a H2 client (over JDBC). -

- -

Starting the TCP Server within an Application

-

-Servers can also be started and stopped from within an application. Sample code: -

-
-import org.h2.tools.Server;
-...
-// start the TCP Server
-Server server = Server.createTcpServer(args).start();
-...
-// stop the TCP Server
-server.stop();
-
- -

Stopping a TCP Server from Another Process

-

-The TCP server can be stopped from another process. -To stop the server from the command line, run: -

-
-java org.h2.tools.Server -tcpShutdown tcp://localhost:9092
-
-

-To stop the server from a user application, use the following code: -

-
-org.h2.tools.Server.shutdownTcpServer("tcp://localhost:9094");
-
-

-This function will only stop the TCP server. -If other server were started in the same process, they will continue to run. -To avoid recovery when the databases are opened the next time, -all connections to the databases should be closed before calling this method. -To stop a remote server, remote connections must be enabled on the server. -Shutting down a TCP server can be protected using the option -tcpPassword -(the same password must be used to start and stop the TCP server). -

- -

Using Hibernate

-

-This database supports Hibernate version 3.1 and newer. You can use the HSQLDB Dialect, -or the native H2 Dialect. Unfortunately the H2 Dialect included in some versions of Hibernate is buggy. -A patch -for Hibernate has been submitted and is now applied. The dialect for the newest version of Hibernate -is also available at src/tools/org/hibernate/dialect/H2Dialect.java.txt. -You can rename it to H2Dialect.java and include this as a patch in your application, -or upgrade to a version of Hibernate where this is fixed. -

-

-When using compatibility modes such as MODE=MySQL when using Hibernate -is not supported when using H2Dialect. -

- - -

-To use H2 with Glassfish (or Sun AS), set the Datasource Classname to -org.h2.jdbcx.JdbcDataSource. You can set this in the GUI -at Application Server - Resources - JDBC - Connection Pools, -or by editing the file sun-resources.xml: at element -jdbc-connection-pool, set the attribute -datasource-classname to org.h2.jdbcx.JdbcDataSource. -

-

-The H2 database is compatible with HSQLDB and PostgreSQL. -To take advantage of H2 specific features, use the H2Platform. -The source code of this platform is included in H2 at -src/tools/oracle/toplink/essentials/platform/database/DatabasePlatform.java.txt. -You will need to copy this file to your application, and rename it to .java. -To enable it, change the following setting in persistence.xml: -

-
-<property
-    name="toplink.target-database"
-    value="oracle.toplink.essentials.platform.database.H2Platform"/>
-
-

-In old versions of Glassfish, the property name is toplink.platform.class.name. -

-

-To use H2 within Glassfish, copy the h2*.jar to the directory glassfish/glassfish/lib. -

- - -

-To use H2 in EclipseLink, use the platform class org.eclipse.persistence.platform.database.H2Platform. -If this platform is not available in your version of EclipseLink, you can use the OraclePlatform instead in many case. -See also H2Platform. -

- -

Using Databases in Web Applications

-

-There are multiple ways to access a database from within web -applications. Here are some examples if you use Tomcat or JBoss. -

- -

Embedded Mode

-

-The (currently) simplest solution is to use the database in the -embedded mode, that means open a connection in your application when -it starts (a good solution is using a Servlet Listener, see below), or -when a session starts. A database can be accessed from multiple -sessions and applications at the same time, as long as they run in the -same process. Most Servlet Containers (for example Tomcat) are just -using one process, so this is not a problem (unless you run Tomcat in -clustered mode). Tomcat uses multiple threads and multiple -classloaders. If multiple applications access the same database at the -same time, you need to put the database jar in the shared/lib or -server/lib directory. It is a good idea to open the database when the -web application starts, and close it when the web application stops. -If using multiple applications, only one (any) of them needs to do -that. In the application, an idea is to use one connection per -Session, or even one connection per request (action). Those -connections should be closed after use if possible (but it's not that -bad if they don't get closed). -

- -

Server Mode

-

-The server mode is similar, but it allows you to run the server in another process. -

- -

Using a Servlet Listener to Start and Stop a Database

-

-Add the h2*.jar file to your web application, and -add the following snippet to your web.xml file (between the -context-param and the filter section): -

-
-<listener>
-    <listener-class>org.h2.server.web.DbStarter</listener-class>
-</listener>
-
-

-For details on how to access the database, see the file DbStarter.java. -By default this tool opens an embedded connection -using the database URL jdbc:h2:~/test, -user name sa, and password sa. -If you want to use this connection within your servlet, you can access as follows: -

-
-Connection conn = getServletContext().getAttribute("connection");
-
-

-DbStarter can also start the TCP server, however this is disabled by default. -To enable it, use the parameter db.tcpServer in the file web.xml. -Here is the complete list of options. -These options need to be placed between the description tag -and the listener / filter tags: -

-
-<context-param>
-    <param-name>db.url</param-name>
-    <param-value>jdbc:h2:~/test</param-value>
-</context-param>
-<context-param>
-    <param-name>db.user</param-name>
-    <param-value>sa</param-value>
-</context-param>
-<context-param>
-    <param-name>db.password</param-name>
-    <param-value>sa</param-value>
-</context-param>
-<context-param>
-    <param-name>db.tcpServer</param-name>
-    <param-value>-tcpAllowOthers</param-value>
-</context-param>
-
-

-When the web application is stopped, the database connection will be closed automatically. -If the TCP server is started within the DbStarter, it will also be stopped automatically. -

- -

Using the H2 Console Servlet

-

-The H2 Console is a standalone application and includes its own web server, but it can be -used as a servlet as well. To do that, include the the h2*.jar file in your application, and -add the following configuration to your web.xml: -

-
-<servlet>
-    <servlet-name>H2Console</servlet-name>
-    <servlet-class>org.h2.server.web.WebServlet</servlet-class>
-    <!--
-    <init-param>
-        <param-name>webAllowOthers</param-name>
-        <param-value></param-value>
-    </init-param>
-    <init-param>
-        <param-name>trace</param-name>
-        <param-value></param-value>
-    </init-param>
-    -->
-    <load-on-startup>1</load-on-startup>
-</servlet>
-<servlet-mapping>
-    <servlet-name>H2Console</servlet-name>
-    <url-pattern>/console/*</url-pattern>
-</servlet-mapping>
-
-

-For details, see also src/tools/WEB-INF/web.xml. -

-

-To create a web application with just the H2 Console, run the following command: -

-
-build warConsole
-
- -

CSV (Comma Separated Values) Support

-

-The CSV file support can be used inside the database using the functions -CSVREAD and CSVWRITE, -or it can be used outside the database as a standalone tool. -

- -

Reading a CSV File from Within a Database

-

-A CSV file can be read using the function CSVREAD. Example: -

-
-SELECT * FROM CSVREAD('test.csv');
-
- -

Importing Data from a CSV File

-

-A fast way to load or import data (sometimes called 'bulk load') from a CSV file is -to combine table creation with import. -Optionally, the column names and data types can be set when creating the table. -Another option is to use INSERT INTO ... SELECT. -

-
-CREATE TABLE TEST AS SELECT * FROM CSVREAD('test.csv');
-CREATE TABLE TEST(ID INT PRIMARY KEY, NAME VARCHAR(255))
-    AS SELECT * FROM CSVREAD('test.csv');
-
- -

Writing a CSV File from Within a Database

-

-The built-in function CSVWRITE can be used to create a CSV file from a query. -Example: -

-
-CREATE TABLE TEST(ID INT, NAME VARCHAR);
-INSERT INTO TEST VALUES(1, 'Hello'), (2, 'World');
-CALL CSVWRITE('test.csv', 'SELECT * FROM TEST');
-
- -

Writing a CSV File from a Java Application

-

-The Csv tool can be used in a Java application even when not using a database at all. -Example: -

-
-import java.sql.*;
-import org.h2.tools.Csv;
-import org.h2.tools.SimpleResultSet;
-public class TestCsv {
-    public static void main(String[] args) throws Exception {
-        SimpleResultSet rs = new SimpleResultSet();
-        rs.addColumn("NAME", Types.VARCHAR, 255, 0);
-        rs.addColumn("EMAIL", Types.VARCHAR, 255, 0);
-        rs.addRow("Bob Meier", "bob.meier@abcde.abc");
-        rs.addRow("John Jones", "john.jones@abcde.abc");
-        Csv.getInstance().write("data/test.csv", rs, null);
-    }
-}
-
- -

Reading a CSV File from a Java Application

-

-It is possible to read a CSV file without opening a database. -Example: -

-
-import java.sql.*;
-import org.h2.tools.Csv;
-public class TestCsv {
-    public static void main(String[] args) throws Exception {
-        ResultSet rs = Csv.getInstance().
-            read("data/test.csv", null, null);
-        ResultSetMetaData meta = rs.getMetaData();
-        while (rs.next()) {
-            for (int i = 0; i < meta.getColumnCount(); i++) {
-                System.out.println(
-                    meta.getColumnLabel(i + 1) + ": " +
-                    rs.getString(i + 1));
-            }
-            System.out.println();
-        }
-        rs.close();
-    }
-}
-
- -

Upgrade, Backup, and Restore

- -

Database Upgrade

-

-The recommended way to upgrade from one version of the database engine to the next -version is to create a backup of the database (in the form of a SQL script) using the old engine, -and then execute the SQL script using the new engine. -

- -

Backup using the Script Tool

-

-There are different ways to backup a database. For example, it is possible to copy the database files. -However, this is not recommended while the database is in use. Also, the database files are not human readable -and quite large. The recommended way to backup a database is to create a compressed SQL script file. -This can be done using the Script tool: -

-
-java org.h2.tools.Script -url jdbc:h2:~/test -user sa -script test.zip -options compression zip
-
-

-It is also possible to use the SQL command SCRIPT to create the backup of the database. -For more information about the options, see the SQL command SCRIPT. -The backup can be done remotely, however the file will be created on the server side. -The built in FTP server could be used to retrieve the file from the server. -

- -

Restore from a Script

-

-To restore a database from a SQL script file, you can use the RunScript tool: -

-
-java org.h2.tools.RunScript -url jdbc:h2:~/test -user sa -script test.zip -options compression zip
-
-

-For more information about the options, see the SQL command RUNSCRIPT. -The restore can be done remotely, however the file needs to be on the server side. -The built in FTP server could be used to copy the file to the server. -It is also possible to use the SQL command RUNSCRIPT to execute a SQL script. -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. -

- -

Online Backup

-

-The BACKUP SQL statement and the Backup tool both create a zip file -with all database files. However, the contents of this file are not human readable. -

-Unlike than the SCRIPT statement, the BACKUP statement does not lock the -database objects when using the multi-threaded mode, and therefore does not block other users. -The resulting backup is transactionally consistent: -

-
-BACKUP TO 'backup.zip'
-
-

-The Backup tool (org.h2.tools.Backup) can not be used to create a online backup; -the database must not be in use while running this program. -

-

-Creating a backup by copying the database files while the database is running is not supported, -except if the file systems support creating snapshots. The problem is that it can't -be guaranteed that the data is copied in the right order. -

- -

Command Line Tools

-

-This database comes with a number of command line tools. To get more information about a tool, -start it with the parameter '-?', for example: -

-
-java -cp h2*.jar org.h2.tools.Backup -?
-
-

-The command line tools are: -

-
  • Backup creates a backup of a database. -
  • ChangeFileEncryption allows changing the file encryption password or algorithm of a database. -
  • Console starts the browser based H2 Console. -
  • ConvertTraceFile converts a .trace.db file to a Java application and SQL script. -
  • CreateCluster creates a cluster from a standalone database. -
  • DeleteDbFiles deletes all files belonging to a database. -
  • Recover helps recovering a corrupted database. -
  • Restore restores a backup of a database. -
  • RunScript runs a SQL script against a database. -
  • Script allows converting a database to a SQL script for backup or migration. -
  • Server is used in the server mode to start a H2 server. -
  • Shell is a command line database tool. -
-

-The tools can also be called from an application by calling the main or another public method. -For details, see the Javadoc documentation. -

- -

The Shell Tool

-

-The Shell tool is a simple interactive command line tool. To start it, type: -

-
-java -cp h2*.jar org.h2.tools.Shell
-
-

-You will be asked for a database URL, JDBC driver, user name, and password. -The connection setting can also be set as command line parameters. -After connecting, you will get the list of options. -The built-in commands don't need to end with a semicolon, but -SQL statements are only executed if the line ends with a semicolon ;. -This allows to enter multi-line statements: -

-
-sql> select * from test
-...> where id = 0;
-
-

-By default, results are printed as a table. For results with many column, consider using the list mode: -

-
-sql> list
-Result list mode is now on
-sql> select * from test;
-ID  : 1
-NAME: Hello
-
-ID  : 2
-NAME: World
-(2 rows, 0 ms)
-
- -

Using OpenOffice Base

-

-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. -The steps to connect to a H2 database are: -

-
  • Start OpenOffice Writer, go to [Tools], [Options] -
  • Make sure you have selected a Java runtime environment in OpenOffice.org / Java -
  • Click [Class Path...], [Add Archive...] -
  • Select your h2 jar file (location is up to you, could be wherever you choose) -
  • Click [OK] (as much as needed), stop OpenOffice (including the Quickstarter) -
  • Start OpenOffice Base -
  • Connect to an existing database; select [JDBC]; [Next] -
  • Example datasource URL: jdbc:h2:~/test -
  • JDBC driver class: org.h2.Driver -
-

-Now you can access the database stored in the current users home directory. -

-

-To use H2 in NeoOffice (OpenOffice without X11): -

-
  • In NeoOffice, go to [NeoOffice], [Preferences] -
  • Look for the page under [NeoOffice], [Java] -
  • Click [Class Path], [Add Archive...] -
  • Select your h2 jar file (location is up to you, could be wherever you choose) -
  • Click [OK] (as much as needed), restart NeoOffice. -
-

-Now, when creating a new database using the "Database Wizard" : -

-
  • Click [File], [New], [Database]. -
  • Select [Connect to existing database] and the select [JDBC]. Click next. -
  • Example datasource URL: jdbc:h2:~/test -
  • JDBC driver class: org.h2.Driver -
-

-Another solution to use H2 in NeoOffice is: -

-
  • Package the h2 jar within an extension package -
  • Install it as a Java extension in NeoOffice -
-

-This can be done by create it using the NetBeans OpenOffice plugin. -See also Extensions Development. -

- -

Java Web Start / JNLP

-

-When using Java Web Start / JNLP (Java Network Launch Protocol), permissions tags must be set in the .jnlp file, -and the application .jar file must be signed. Otherwise, when trying to write to the file system, the following -exception will occur: java.security.AccessControlException: -access denied (java.io.FilePermission ... read). -Example permission tags: -

-
-<security>
-    <all-permissions/>
-</security>
-
- -

Using a Connection Pool

-

-For H2, opening a connection is fast if the database is already open. -Still, using a connection pool improves performance if you open and close connections a lot. -A simple connection pool is included in H2. It is based on the -Mini Connection Pool Manager -from Christian d'Heureuse. There are other, more complex, open source connection pools available, -for example the Apache Commons DBCP. -For H2, it is about twice as faster to get a connection from the built-in connection pool than to get -one using DriverManager.getConnection().The build-in connection pool is used as follows: -

-
-import java.sql.*;
-import org.h2.jdbcx.JdbcConnectionPool;
-public class Test {
-    public static void main(String[] args) throws Exception {
-        JdbcConnectionPool cp = JdbcConnectionPool.create(
-            "jdbc:h2:~/test", "sa", "sa");
-        for (int i = 0; i < args.length; i++) {
-            Connection conn = cp.getConnection();
-            conn.createStatement().execute(args[i]);
-            conn.close();
-        }
-        cp.dispose();
-    }
-}
-
- -

Fulltext Search

-

-H2 includes two fulltext search implementations. One is using Apache Lucene, -and the other (the native implementation) stores the index data in special -tables in the database. -

- -

Using the Native Fulltext Search

-

-To initialize, call: -

-
-CREATE ALIAS IF NOT EXISTS FT_INIT FOR "org.h2.fulltext.FullText.init";
-CALL FT_INIT();
-
-

-You need to initialize it in each database where you want to use it. -Afterwards, you can create a fulltext index for a table using: -

-
-CREATE TABLE TEST(ID INT PRIMARY KEY, NAME VARCHAR);
-INSERT INTO TEST VALUES(1, 'Hello World');
-CALL FT_CREATE_INDEX('PUBLIC', 'TEST', NULL);
-
-

-PUBLIC is the schema name, TEST is the table name. The list of column names (column separated) is optional, -in this case all columns are indexed. The index is updated in realtime. -To search the index, use the following query: -

-
-SELECT * FROM FT_SEARCH('Hello', 0, 0);
-
-

-This will produce a result set that contains the query needed to retrieve the data: -

-
-QUERY: "PUBLIC"."TEST" WHERE "ID"=1
-
-

-To get the raw data, use FT_SEARCH_DATA('Hello', 0, 0);. -The result contains the columns SCHEMA (the schema name), -TABLE (the table name), -COLUMNS (an array of column names), and -KEYS (an array of objects). -To join a table, use a join as in: -SELECT T.* FROM FT_SEARCH_DATA('Hello', 0, 0) FT, TEST T -WHERE FT.TABLE='TEST' AND T.ID=FT.KEYS[0]; -

-

-You can also call the index from within a Java application: -

-
-org.h2.fulltext.FullText.search(conn, text, limit, offset);
-org.h2.fulltext.FullText.searchData(conn, text, limit, offset);
-
- -

Using the Lucene Fulltext Search

-

-To use the Lucene full text search, you need the Lucene library in the classpath. -How to do that depends on the application; if you use the H2 Console, you can add the Lucene -jar file to the environment variables H2DRIVERS or -CLASSPATH. -To initialize the Lucene fulltext search in a database, call: -

-
-CREATE ALIAS IF NOT EXISTS FTL_INIT FOR "org.h2.fulltext.FullTextLucene.init";
-CALL FTL_INIT();
-
-

-You need to initialize it in each database where you want to use it. -Afterwards, you can create a full text index for a table using: -

-
-CREATE TABLE TEST(ID INT PRIMARY KEY, NAME VARCHAR);
-INSERT INTO TEST VALUES(1, 'Hello World');
-CALL FTL_CREATE_INDEX('PUBLIC', 'TEST', NULL);
-
-

-PUBLIC is the schema name, TEST is the table name. The list of column names (column separated) is optional, -in this case all columns are indexed. The index is updated in realtime. To search the index, -use the following query: -

-
-SELECT * FROM FTL_SEARCH('Hello', 0, 0);
-
-

-This will produce a result set that contains the query needed to retrieve the data: -

-
-QUERY: "PUBLIC"."TEST" WHERE "ID"=1
-
-

-To get the raw data, use FTL_SEARCH_DATA('Hello', 0, 0);. -The result contains the columns SCHEMA (the schema name), -TABLE (the table name), -COLUMNS (an array of column names), -and KEYS (an array of objects). To join a table, use a join as in: -SELECT T.* FROM FTL_SEARCH_DATA('Hello', 0, 0) FT, TEST T -WHERE FT.TABLE='TEST' AND T.ID=FT.KEYS[0]; -

-

-You can also call the index from within a Java application: -

-
-org.h2.fulltext.FullTextLucene.search(conn, text, limit, offset);
-org.h2.fulltext.FullTextLucene.searchData(conn, text, limit, offset);
-
- -

User-Defined Variables

-

-This database supports user-defined variables. Variables start with @ and can be used wherever -expressions or parameters are allowed. Variables are not persisted and session scoped, that means only visible -from within the session in which they are defined. A value is usually assigned using the SET command: -

-
-SET @USER = 'Joe';
-
-

-The value can also be changed using the SET() method. This is useful in queries: -

-
-SET @TOTAL = NULL;
-SELECT X, SET(@TOTAL, IFNULL(@TOTAL, 1.) * X) F FROM SYSTEM_RANGE(1, 50);
-
-

-Variables that are not set evaluate to NULL. -The data type of a user-defined variable is the data type -of the value assigned to it, that means it is not necessary (or possible) to declare variable names before using them. -There are no restrictions on the assigned values; large objects (LOBs) are supported as well. -

- -

Date and Time

-

-Date, time and timestamp values support ISO 8601 formatting, including time zone: -

-
-CALL TIMESTAMP '2008-01-01 12:00:00+01:00';
-
-

-If the time zone is not set, the value is parsed using the current time zone setting of the system. -Date and time information is stored in H2 database files in GMT (Greenwich Mean Time). -If the database is opened using another system time zone, the date and time will change accordingly. -If you want to move a database from one time zone to the other and don't want this to happen, -you need to create a SQL script file using the SCRIPT command or -Script tool, and then load -the database using the RUNSCRIPT command -or the RunScript tool in the new time zone. -

- -

Using Spring

-

-Use the following configuration to start and stop the H2 TCP server using the Spring Framework: -

-
-<bean id = "org.h2.tools.Server"
-            class="org.h2.tools.Server"
-            factory-method="createTcpServer"
-            init-method="start"
-            destroy-method="stop">
-    <constructor-arg value="-tcp,-tcpAllowOthers,true,-tcpPort,8043" />
-</bean>
-
-

-The destroy-method will help prevent exceptions on hot-redeployment or when restarting the server. -

- -
- diff --git a/tools/h2/src/docsrc/images/connection-modes.svg b/tools/h2/src/docsrc/images/connection-modes.svg deleted file mode 100755 index fb4b78f..0000000 --- a/tools/h2/src/docsrc/images/connection-modes.svg +++ /dev/null @@ -1,1118 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - image/svg+xml - - - - - - - - - - Application - - - - - Application - - - - - - - - - - - - - - H2 Database - - H2 Server - - - - Application - - - - - - - - - - H2 Database - - - - - - - - - - - - - H2 Database - - H2 Server - Embedded - Remote - Mixed Mode - - - Application - - - diff --git a/tools/h2/src/docsrc/images/console.png b/tools/h2/src/docsrc/images/console.png deleted file mode 100755 index 39a7ef5..0000000 Binary files a/tools/h2/src/docsrc/images/console.png and /dev/null differ diff --git a/tools/h2/src/docsrc/images/console.svg b/tools/h2/src/docsrc/images/console.svg deleted file mode 100755 index eb65dc0..0000000 --- a/tools/h2/src/docsrc/images/console.svg +++ /dev/null @@ -1,515 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - image/svg+xml - - - - - - - - - - - - - - - - - - H2Database - WebBrowser - - - H2ConsoleServer - - - diff --git a/tools/h2/src/docsrc/images/db-16.png b/tools/h2/src/docsrc/images/db-16.png deleted file mode 100755 index d5340e5..0000000 Binary files a/tools/h2/src/docsrc/images/db-16.png and /dev/null differ diff --git a/tools/h2/src/docsrc/images/db-22.png b/tools/h2/src/docsrc/images/db-22.png deleted file mode 100755 index 95ba9c7..0000000 Binary files a/tools/h2/src/docsrc/images/db-22.png and /dev/null differ diff --git a/tools/h2/src/docsrc/images/db-24.png b/tools/h2/src/docsrc/images/db-24.png deleted file mode 100755 index 04b5d2b..0000000 Binary files a/tools/h2/src/docsrc/images/db-24.png and /dev/null differ diff --git a/tools/h2/src/docsrc/images/db-32.png b/tools/h2/src/docsrc/images/db-32.png deleted file mode 100755 index f269e13..0000000 Binary files a/tools/h2/src/docsrc/images/db-32.png and /dev/null differ diff --git a/tools/h2/src/docsrc/images/db.svg b/tools/h2/src/docsrc/images/db.svg deleted file mode 100755 index d4dedbd..0000000 --- a/tools/h2/src/docsrc/images/db.svg +++ /dev/null @@ -1,308 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - image/svg+xml - - - - - - - - - - - - - - - - diff --git a/tools/h2/src/docsrc/images/favicon.ico b/tools/h2/src/docsrc/images/favicon.ico deleted file mode 100755 index 6e0f78a..0000000 Binary files a/tools/h2/src/docsrc/images/favicon.ico and /dev/null differ diff --git a/tools/h2/src/docsrc/images/h2-16.png b/tools/h2/src/docsrc/images/h2-16.png deleted file mode 100755 index 2dee09e..0000000 Binary files a/tools/h2/src/docsrc/images/h2-16.png and /dev/null differ diff --git a/tools/h2/src/docsrc/images/h2-24.png b/tools/h2/src/docsrc/images/h2-24.png deleted file mode 100755 index 1d83623..0000000 Binary files a/tools/h2/src/docsrc/images/h2-24.png and /dev/null differ diff --git a/tools/h2/src/docsrc/images/h2-32.png b/tools/h2/src/docsrc/images/h2-32.png deleted file mode 100755 index 7e6c3e8..0000000 Binary files a/tools/h2/src/docsrc/images/h2-32.png and /dev/null differ diff --git a/tools/h2/src/docsrc/images/h2-64.png b/tools/h2/src/docsrc/images/h2-64.png deleted file mode 100755 index 754cc59..0000000 Binary files a/tools/h2/src/docsrc/images/h2-64.png and /dev/null differ diff --git a/tools/h2/src/docsrc/images/h2-logo.png b/tools/h2/src/docsrc/images/h2-logo.png deleted file mode 100755 index 52ebd8e..0000000 Binary files a/tools/h2/src/docsrc/images/h2-logo.png and /dev/null differ diff --git a/tools/h2/src/docsrc/images/h2-logo.svg b/tools/h2/src/docsrc/images/h2-logo.svg deleted file mode 100755 index 7e0c976..0000000 --- a/tools/h2/src/docsrc/images/h2-logo.svg +++ /dev/null @@ -1,186 +0,0 @@ - - - - - - - - - - - - - - - - - - - - image/svg+xml - - - - - - - - - - - - H2 - png - font - - diff --git a/tools/h2/src/docsrc/images/screenshot.png b/tools/h2/src/docsrc/images/screenshot.png deleted file mode 100755 index f9e388f..0000000 Binary files a/tools/h2/src/docsrc/images/screenshot.png and /dev/null differ diff --git a/tools/h2/src/docsrc/index.html b/tools/h2/src/docsrc/index.html deleted file mode 100755 index a370af8..0000000 --- a/tools/h2/src/docsrc/index.html +++ /dev/null @@ -1,41 +0,0 @@ - - - - -H2 Database Engine - - - - - -

H2 Database Engine

-

-Welcome to H2, the free SQL database. The main feature of H2 are: -

- - -

No Javascript

-

-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. -Please enable Javascript, or go ahead without it: -

-H2 Database Engine -

- - diff --git a/tools/h2/src/docsrc/javadoc/animate.js b/tools/h2/src/docsrc/javadoc/animate.js deleted file mode 100755 index b704a60..0000000 --- a/tools/h2/src/docsrc/javadoc/animate.js +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ - -function on(id) { - return switchTag(id, 'titleOff', 'detailOn'); -} - -function off(id) { - return switchTag(id, '', 'detail'); -} - -function allDetails() { - for (i = 0;; i++) { - x = document.getElementById('_' + i); - if (x == null) { - break; - } - switchTag(i, 'titleOff', 'detailOn'); - } - return false; -} - -function switchTag(id, title, detail) { - if (document.getElementById('__' + id) != null) { - document.getElementById('__' + id).className = title; - document.getElementById('_' + id).className = detail; - } - return false; -} - -function openLink() { - page = new String(self.document.location); - var pos = page.lastIndexOf("#") + 1; - if (pos == 0) { - return; - } - var ref = page.substr(pos); - link = decodeURIComponent(ref); - el = document.getElementById(link); - if (el.nodeName.toLowerCase() == 'h4') { - // constant - return true; - } - el = el.parentNode.parentNode; - window.scrollTo(0, el.offsetTop); - on(el.id.substr(2)); - return false; -} \ No newline at end of file diff --git a/tools/h2/src/docsrc/javadoc/classes.html b/tools/h2/src/docsrc/javadoc/classes.html deleted file mode 100755 index d298c72..0000000 --- a/tools/h2/src/docsrc/javadoc/classes.html +++ /dev/null @@ -1,92 +0,0 @@ - - - - - - H2 Documentation - - - - - - -
-
- diff --git a/tools/h2/src/docsrc/javadoc/index.html b/tools/h2/src/docsrc/javadoc/index.html deleted file mode 100755 index d4a33bd..0000000 --- a/tools/h2/src/docsrc/javadoc/index.html +++ /dev/null @@ -1,24 +0,0 @@ - - - - - - H2 Documentation - - - - - - - -<body> - Sorry, Lynx is not supported -</body> - - - diff --git a/tools/h2/src/docsrc/javadoc/overview.html b/tools/h2/src/docsrc/javadoc/overview.html deleted file mode 100755 index 7844daa..0000000 --- a/tools/h2/src/docsrc/javadoc/overview.html +++ /dev/null @@ -1,38 +0,0 @@ - - - - - - API Overview - - - - - -
-
- -

API Overview

- -

JDBC API

- -

-Use the JDBC API to connect to a database and execute queries. -

- -

Tools API

- -

-The Tools API can be used to do maintenance operations, -such as deleting database files or changing the database file password, -that do not require a connection to the database. -

- -
- - diff --git a/tools/h2/src/docsrc/javadoc/stylesheet.css b/tools/h2/src/docsrc/javadoc/stylesheet.css deleted file mode 100755 index 93e1b7c..0000000 --- a/tools/h2/src/docsrc/javadoc/stylesheet.css +++ /dev/null @@ -1,172 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ - -td, input, select, textarea, body, code, pre, td, th { - font: 9pt/130% Tahoma, Arial, Helvetica, sans-serif; - font-weight: normal; -} - -pre { - background-color: #ece9d8; - border: 1px solid rgb(172, 168, 153); - padding: 4px; -} - -body { - margin: 0px; - max-width: 800px; -} - -h1 { - background-color: #0000bb; - padding: 2px 4px 2px 4px; - color: #fff; - font-size: 15pt; - line-height: normal; -} - -h2 { - font-size: 13pt; -} - -h3 { - font-size: 11pt; -} - -h4 { - font-size: 10pt; -} - -hr { - color: #CCC; - background-color: #CCC; - height: 1px; - border: 0px solid blue; -} - -.menu { - margin: 10px 10px 10px 10px; -} - -.block { - border: 0px; -} - -.titleOff { - display: none; -} - -.detail { - border: 0px; - display: none; -} - -.detailOn { - border: 0px; -} - -td.return { - white-space:nowrap; - width: 1%; -} - -td.method { - width: 99%; -} - -.deprecated { - text-decoration: line-through; -} - -.methodText { - color: #000000; - font-weight: normal; - margin: 0px 0px 0px 20px; -} - -.method { -} - -.fieldText { - margin: 6px 20px 6px 20px; -} - -.methodName { - font-weight: bold; -} - -.itemTitle { -} -/* font-weight: bold; */ - -.item { - margin: 0px 0px 0px 20px; -} - -table { - background-color: #ffffff; - border-collapse: collapse; - border: 1px solid #aca899; -} - -th { - text-align: left; - background-color: #ece9d8; - border: 1px solid #aca899; - padding: 2px; -} - -td { - background-color: #ffffff; - text-align: left; - vertical-align:top; - border: 1px solid #aca899; - padding: 2px; -} - - -ul, ol { - list-style-position: outside; - padding-left: 20px; -} - -li { - margin-top: 8px; - line-height: 100%; -} - -a { - text-decoration: none; - color: #0000ff; -} - -a:hover { - text-decoration: underline; -} - -table.content { - width: 100%; - height: 100%; - border: 0px; -} - -tr.content { - border:0px; - border-left:1px solid #aca899; -} - -td.content { - border:0px; - border-left:1px solid #aca899; -} - -.contentDiv { - margin:10px; -} - - - diff --git a/tools/h2/src/docsrc/text/_docs_en.utf8.txt b/tools/h2/src/docsrc/text/_docs_en.utf8.txt deleted file mode 100755 index d1076ec..0000000 --- a/tools/h2/src/docsrc/text/_docs_en.utf8.txt +++ /dev/null @@ -1,10575 +0,0 @@ -@advanced_1000_h1 -Advanced - -@advanced_1001_a - Result Sets - -@advanced_1002_a - Large Objects - -@advanced_1003_a - Linked Tables - -@advanced_1004_a - Transaction Isolation - -@advanced_1005_a - Multi-Version Concurrency Control (MVCC) - -@advanced_1006_a - Clustering / High Availability - -@advanced_1007_a - Two Phase Commit - -@advanced_1008_a - Compatibility - -@advanced_1009_a - Standards Compliance - -@advanced_1010_a - Run as Windows Service - -@advanced_1011_a - ODBC Driver - -@advanced_1012_a - Using H2 in Microsoft .NET - -@advanced_1013_a - ACID - -@advanced_1014_a - Durability Problems - -@advanced_1015_a - Using the Recover Tool - -@advanced_1016_a - File Locking Protocols - -@advanced_1017_a - File Locking Method 'Serialized' - -@advanced_1018_a - Protection against SQL Injection - -@advanced_1019_a - Protection against Remote Access - -@advanced_1020_a - Restricting Class Loading and Usage - -@advanced_1021_a - Security Protocols - -@advanced_1022_a - SSL/TLS Connections - -@advanced_1023_a - Universally Unique Identifiers (UUID) - -@advanced_1024_a - Settings Read from System Properties - -@advanced_1025_a - Setting the Server Bind Address - -@advanced_1026_a - Pluggable File System - -@advanced_1027_a - Limits and Limitations - -@advanced_1028_a - Glossary and Links - -@advanced_1029_h2 -Result Sets - -@advanced_1030_h3 -Statements that Return a Result Set - -@advanced_1031_p - The following statements return a result set: SELECT, EXPLAIN, CALL, SCRIPT, SHOW, HELP. All other statements return an update count. - -@advanced_1032_h3 -Limiting the Number of Rows - -@advanced_1033_p - Before the result is returned to the application, all rows are read by the database. Server side cursors are not supported currently. If only the first few rows are interesting for the application, then the result set size should be limited to improve the performance. This can be done using LIMIT in a query (example: SELECT * FROM TEST LIMIT 100), or by using Statement.setMaxRows(max). - -@advanced_1034_h3 -Large Result Sets and External Sorting - -@advanced_1035_p - For large result set, the result is buffered to disk. The threshold can be defined using the statement SET MAX_MEMORY_ROWS. If ORDER BY is used, 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. - -@advanced_1036_h2 -Large Objects - -@advanced_1037_h3 -Storing and Reading Large Objects - -@advanced_1038_p - If it is possible that the objects don't fit into memory, then the data type CLOB (for textual data) or BLOB (for binary data) should be used. For these data types, the objects are not fully read into memory, by using streams. To store a BLOB, use PreparedStatement.setBinaryStream. To store a CLOB, use PreparedStatement.setCharacterStream. To read a BLOB, use ResultSet.getBinaryStream, and to read a CLOB, use ResultSet.getCharacterStream. When using the client/server mode, large BLOB and CLOB data is stored in a temporary file on the client side. - -@advanced_1039_h3 -When to use CLOB/BLOB - -@advanced_1040_p - This database stores large LOB (CLOB and BLOB) objects as separate files. Small LOB objects are stored in-place, the threshold can be set using MAX_LENGTH_INPLACE_LOB, but there is still an overhead to use CLOB/BLOB. Because of this, BLOB and CLOB should never be used for columns with a maximum size below about 200 bytes. The best threshold depends on the use case; reading in-place objects is faster than reading from separate files, but slows down the performance of operations that don't involve this column. - -@advanced_1041_h3 -Large Object Compression - -@advanced_1042_p - CLOB and BLOB values can be compressed by using SET COMPRESS_LOB. The LZF algorithm is faster but needs more disk space. By default compression is disabled, which usually speeds up write operations. If you store many large compressible values such as XML, HTML, text, and uncompressed binary files, then compressing can save a lot of disk space (sometimes more than 50%), and read operations may even be faster. - -@advanced_1043_h2 -Linked Tables - -@advanced_1044_p - This database supports linked tables, which means tables that don't exist in the current database but are just links to another database. To create such a link, use the CREATE LINKED TABLE statement: - -@advanced_1045_p - You can then access the table in the usual way. Whenever the linked table is accessed, the database issues specific queries over JDBC. Using the example above, if you issue the query SELECT * FROM LINK WHERE ID=1, then the following query is run against the PostgreSQL database: SELECT * FROM TEST WHERE ID=?. The same happens for insert and update statements. Only simple statements are executed against the target database, that means no joins. Prepared statements are used where possible. - -@advanced_1046_p - To view the statements that are executed against the target table, set the trace level to 3. - -@advanced_1047_p - If multiple linked tables point to the same database (using the same database URL), the connection is shared. To disable this, set the system property h2.shareLinkedConnections=false. - -@advanced_1048_p - The statement CREATE LINKED TABLE supports an optional schema name parameter. - -@advanced_1049_h2 -Transaction Isolation - -@advanced_1050_p - Transaction isolation is provided for all data manipulation language (DML) statements. Most data definition language (DDL) statements commit the current transaction. See the Grammar for details. - -@advanced_1051_p - This database supports the following transaction isolation levels: - -@advanced_1052_b -Read Committed - -@advanced_1053_li - This is the default level. Read locks are released immediately. Higher concurrency is possible when using this level. - -@advanced_1054_li - To enable, execute the SQL statement SET LOCK_MODE 3 - -@advanced_1055_li - or append ;LOCK_MODE=3 to the database URL: jdbc:h2:~/test;LOCK_MODE=3 - -@advanced_1056_b -Serializable - -@advanced_1057_li - To enable, execute the SQL statement SET LOCK_MODE 1 - -@advanced_1058_li - or append ;LOCK_MODE=1 to the database URL: jdbc:h2:~/test;LOCK_MODE=1 - -@advanced_1059_b -Read Uncommitted - -@advanced_1060_li - This level means that transaction isolation is disabled. - -@advanced_1061_li - To enable, execute the SQL statement SET LOCK_MODE 0 - -@advanced_1062_li - or append ;LOCK_MODE=0 to the database URL: jdbc:h2:~/test;LOCK_MODE=0 - -@advanced_1063_p - When using the isolation level 'serializable', dirty reads, non-repeatable reads, and phantom reads are prohibited. - -@advanced_1064_b -Dirty Reads - -@advanced_1065_li - Means a connection can read uncommitted changes made by another connection. - -@advanced_1066_li - Possible with: read uncommitted - -@advanced_1067_b -Non-Repeatable Reads - -@advanced_1068_li - 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. - -@advanced_1069_li - Possible with: read uncommitted, read committed - -@advanced_1070_b -Phantom Reads - -@advanced_1071_li - 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. - -@advanced_1072_li - Possible with: read uncommitted, read committed - -@advanced_1073_h3 -Table Level Locking - -@advanced_1074_p - The database allows multiple concurrent connections to the same database. To make sure all connections only see consistent data, table level locking is used by default. This mechanism does not allow high concurrency, but is very fast. Shared locks and exclusive locks are supported. Before reading from a table, the database tries to add a shared lock to the table (this is only possible if there is no exclusive lock on the object by another connection). If the shared lock is added successfully, the table can be read. It is allowed that other connections also have a shared lock on the same object. If a connection wants to write to a table (update or delete a row), an exclusive lock is required. To get the exclusive lock, other connection must not have any locks on the object. After the connection commits, all locks are released. This database keeps all locks in memory. - -@advanced_1075_h3 -Lock Timeout - -@advanced_1076_p - If a connection cannot get a lock on an object, the connection waits for some amount of time (the lock timeout). During this time, hopefully the connection holding the lock commits and it is then possible to get the lock. If this is not possible because 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. - -@advanced_1077_h2 -Multi-Version Concurrency Control (MVCC) - -@advanced_1078_p - The MVCC feature allows higher concurrency than using (table level or row level) locks. When using MVCC in this database, delete, insert and update operations will only issue a shared lock on the table. An exclusive lock is still used when adding or removing columns, when dropping the table, and when using SELECT ... FOR UPDATE. Connections only 'see' committed data, and own changes. That means, if connection A updates a row but doesn't commit this change yet, connection B will see the old value. Only when the change is committed, the new value is visible by other connections (read committed). If multiple connections concurrently try to update the same row, the database waits until it can apply the change, but at most until the lock timeout expires. - -@advanced_1079_p - To use the MVCC feature, append ;MVCC=TRUE to the database URL: - -@advanced_1080_p - MVCC is disabled by default. The MVCC feature is not fully tested yet. The limitations of the MVCC mode are: it can not be used at the same time as MULTI_THREADED=TRUE; the complete undo log must fit in memory when using multi-version concurrency (the setting MAX_MEMORY_UNDO has no effect). It is not possible to enable or disable this setting while the database is already open. The setting must be specified in the first connection (the one that opens the database). - -@advanced_1081_h2 -Clustering / High Availability - -@advanced_1082_p - This database supports a simple clustering / high availability mechanism. The architecture is: two database servers run on two different computers, and on both computers is a copy of the same database. If both servers run, each database operation is executed on both computers. If one server fails (power, hardware or network failure), the other server can still continue to work. From this point on, the operations will be executed only on one server until the other server is back up. - -@advanced_1083_p - Clustering can only be used in the server mode (the embedded mode does not support clustering). The cluster can be re-created using the CreateCluster tool without stopping the remaining server. Applications that are still connected are automatically disconnected, however when appending ;AUTO_RECONNECT=TRUE, they will recover from that. - -@advanced_1084_p - To initialize the cluster, use the following steps: - -@advanced_1085_li -Create a database - -@advanced_1086_li -Use the CreateCluster tool to copy the database to another location and initialize the clustering. Afterwards, you have two databases containing the same data. - -@advanced_1087_li -Start two servers (one for each copy of the database) - -@advanced_1088_li -You are now ready to connect to the databases with the client application(s) - -@advanced_1089_h3 -Using the CreateCluster Tool - -@advanced_1090_p - To understand how clustering works, please try out the following example. In this example, the two databases reside on the same computer, but usually, the databases will be on different servers. - -@advanced_1091_li -Create two directories: server1, server2. Each directory will simulate a directory on a computer. - -@advanced_1092_li -Start a TCP server pointing to the first directory. You can do this using the command line: - -@advanced_1093_li -Start a second TCP server pointing to the second directory. This will simulate a server running on a second (redundant) computer. You can do this using the command line: - -@advanced_1094_li -Use the CreateCluster tool to initialize clustering. This will automatically create a new, empty database if it does not exist. Run the tool on the command line: - -@advanced_1095_li -You can now connect to the databases using an application or the H2 Console using the JDBC URL jdbc:h2:tcp://localhost:9101,localhost:9102/~/test - -@advanced_1096_li -If you stop a server (by killing the process), you will notice that the other machine continues to work, and therefore the database is still accessible. - -@advanced_1097_li -To restore the cluster, you first need to delete the database that failed, then restart the server that was stopped, and re-run the CreateCluster tool. - -@advanced_1098_h3 -Detect Which Cluster Instances are Running - -@advanced_1099_p - To find out which cluster nodes are currently running, execute the following SQL statement: - -@advanced_1100_p - If the result is '' (two single quotes), then the cluster mode is disabled. Otherwise, the list of servers is returned, enclosed in single quote. Example: 'server1:9191,server2:9191'. - -@advanced_1101_h3 -Clustering Algorithm and Limitations - -@advanced_1102_p - Read-only queries are only executed against the first cluster node, but all other statements are executed against all nodes. There is currently no load balancing made to avoid problems with transactions. The following functions may yield different results on different cluster nodes and must be executed with care: RANDOM_UUID(), SECURE_RAND(), SESSION_ID(), MEMORY_FREE(), MEMORY_USED(), CSVREAD(), CSVWRITE(), RAND() [when not using a seed]. Those functions should not be used directly in modifying statements (for example INSERT, UPDATE, MERGE). However, they can be used in read-only statements and the result can then be used for modifying statements. - -@advanced_1103_p - When using the cluster modes, result sets are read fully in memory by the client, so that there is no problem if the server dies that executed the query. Result sets must fit in memory on the client side. - -@advanced_1104_h2 -Two Phase Commit - -@advanced_1105_p - The two phase commit protocol is supported. 2-phase-commit works as follows: - -@advanced_1106_li -Autocommit needs to be switched off - -@advanced_1107_li -A transaction is started, for example by inserting a row - -@advanced_1108_li -The transaction is marked 'prepared' by executing the SQL statement PREPARE COMMIT transactionName - -@advanced_1109_li -The transaction can now be committed or rolled back - -@advanced_1110_li -If a problem occurs before the transaction was successfully committed or rolled back (for example because a network problem occurred), the transaction is in the state 'in-doubt' - -@advanced_1111_li -When re-connecting to the database, the in-doubt transactions can be listed with SELECT * FROM INFORMATION_SCHEMA.IN_DOUBT - -@advanced_1112_li -Each transaction in this list must now be committed or rolled back by executing COMMIT TRANSACTION transactionName or ROLLBACK TRANSACTION transactionName - -@advanced_1113_li -The database needs to be closed and re-opened to apply the changes - -@advanced_1114_h2 -Compatibility - -@advanced_1115_p - This database is (up to a certain point) compatible to other databases such as HSQLDB, MySQL and PostgreSQL. There are certain areas where H2 is incompatible. - -@advanced_1116_h3 -Transaction Commit when Autocommit is On - -@advanced_1117_p - At this time, this database engine commits a transaction (if autocommit is switched on) just before returning the result. For a query, this means the transaction is committed even before the application scans through the result set, and before the result set is closed. Other database engines may commit the transaction in this case when the result set is closed. - -@advanced_1118_h3 -Keywords / Reserved Words - -@advanced_1119_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: - -@advanced_1120_code - CROSS, CURRENT_DATE, CURRENT_TIME, CURRENT_TIMESTAMP, DISTINCT, EXCEPT, EXISTS, FALSE, FOR, FROM, FULL, GROUP, HAVING, INNER, INTERSECT, IS, JOIN, LIKE, LIMIT, MINUS, NATURAL, NOT, NULL, ON, ORDER, PRIMARY, ROWNUM, SELECT, SYSDATE, SYSTIME, SYSTIMESTAMP, TODAY, TRUE, UNION, UNIQUE, WHERE - -@advanced_1121_p - Certain words of this list are keywords because they are functions that can be used without '()' for compatibility, for example CURRENT_TIMESTAMP. - -@advanced_1122_h2 -Standards Compliance - -@advanced_1123_p - This database tries to be as much standard compliant as possible. For the SQL language, ANSI/ISO is the main standard. There are several versions that refer to the release date: SQL-92, SQL:1999, and SQL:2003. Unfortunately, the standard documentation is not freely available. Another problem is that important features are not standardized. Whenever this is the case, this database tries to be compatible to other databases. - -@advanced_1124_h2 -Run as Windows Service - -@advanced_1125_p - 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. is included in the installation. Batch files are provided to install, start, stop and uninstall the H2 Database Engine Service. This service contains the TCP Server and the H2 Console web application. The batch files are located in the directory h2/service. - -@advanced_1126_h3 -Install the Service - -@advanced_1127_p - The service needs to be registered as a Windows Service first. To do that, double click on 1_install_service.bat. If successful, a command prompt window will pop up and disappear immediately. If not, a message will appear. - -@advanced_1128_h3 -Start the Service - -@advanced_1129_p - You can start the H2 Database Engine Service using the service manager of Windows, or by double clicking on 2_start_service.bat. Please note that the batch file does not print an error message if the service is not installed. - -@advanced_1130_h3 -Connect to the H2 Console - -@advanced_1131_p - After installing and starting the service, you can connect to the H2 Console application using a browser. Double clicking on 3_start_browser.bat to do that. The default port (8082) is hard coded in the batch file. - -@advanced_1132_h3 -Stop the Service - -@advanced_1133_p - To stop the service, double click on 4_stop_service.bat. Please note that the batch file does not print an error message if the service is not installed or started. - -@advanced_1134_h3 -Uninstall the Service - -@advanced_1135_p - 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. - -@advanced_1136_h2 -ODBC Driver - -@advanced_1137_p - This database does not come with its own ODBC driver at this time, but it supports the PostgreSQL network protocol. Therefore, the PostgreSQL ODBC driver can be used. Support for the PostgreSQL network protocol is quite new and should be viewed as experimental. It should not be used for production applications. - -@advanced_1138_p - To use the PostgreSQL ODBC driver on 64 bit versions of Windows, first run c:/windows/syswow64/odbcad32.exe. At this point you set up your DSN just like you would on any other system. See also: Re: ODBC Driver on Windows 64 bit - -@advanced_1139_h3 -ODBC Installation - -@advanced_1140_p - First, the ODBC driver must be installed. Any recent PostgreSQL ODBC driver should work, however version 8.2 (psqlodbc-08_02*) or newer is recommended. The Windows version of the PostgreSQL ODBC driver is available at http://www.postgresql.org/ftp/odbc/versions/msi. - -@advanced_1141_h3 -Starting the Server - -@advanced_1142_p - After installing the ODBC driver, start the H2 Server using the command line: - -@advanced_1143_p - The PG Server (PG for PostgreSQL protocol) is started as well. By default, databases are stored in the current working directory where the server is started. Use -baseDir to save databases in another directory, for example the user home directory: - -@advanced_1144_p - The PG server can be started and stopped from within a Java application as follows: - -@advanced_1145_p - By default, only connections from localhost are allowed. To allow remote connections, use -pgAllowOthers when starting the server. - -@advanced_1146_h3 -ODBC Configuration - -@advanced_1147_p - After installing the driver, a new Data Source must be added. In Windows, run odbcad32.exe to open the Data Source Administrator. Then click on 'Add...' and select the PostgreSQL Unicode driver. Then click 'Finish'. You will be able to change the connection properties: - -@advanced_1148_th -Property - -@advanced_1149_th -Example - -@advanced_1150_th -Remarks - -@advanced_1151_td -Data Source - -@advanced_1152_td -H2 Test - -@advanced_1153_td -The name of the ODBC Data Source - -@advanced_1154_td -Database - -@advanced_1155_td -test - -@advanced_1156_td - The database name. Only simple names are supported at this time; - -@advanced_1157_td - relative or absolute path are not supported in the database name. - -@advanced_1158_td - By default, the database is stored in the current working directory - -@advanced_1159_td - where the Server is started except when the -baseDir setting is used. - -@advanced_1160_td - The name must be at least 3 characters. - -@advanced_1161_td -Server - -@advanced_1162_td -localhost - -@advanced_1163_td -The server name or IP address. - -@advanced_1164_td -By default, only remote connections are allowed - -@advanced_1165_td -User Name - -@advanced_1166_td -sa - -@advanced_1167_td -The database user name. - -@advanced_1168_td -SSL Mode - -@advanced_1169_td -disabled - -@advanced_1170_td -At this time, SSL is not supported. - -@advanced_1171_td -Port - -@advanced_1172_td -5435 - -@advanced_1173_td -The port where the PG Server is listening. - -@advanced_1174_td -Password - -@advanced_1175_td -sa - -@advanced_1176_td -The database password. - -@advanced_1177_p - To improve performance, please enable 'server side prepare' under Options / Datasource / Page 2 / Server side prepare. - -@advanced_1178_p - Afterwards, you may use this data source. - -@advanced_1179_h3 -PG Protocol Support Limitations - -@advanced_1180_p - At this time, only a subset of the PostgreSQL network protocol is implemented. Also, there may be compatibility problems on the SQL level, with the catalog, or with text encoding. Problems are fixed as they are found. Currently, statements can not be canceled when using the PG protocol. - -@advanced_1181_p - PostgreSQL ODBC Driver Setup requires a database password; that means it is not possible to connect to H2 databases without password. This is a limitation of the ODBC driver. - -@advanced_1182_h3 -Security Considerations - -@advanced_1183_p - Currently, the PG Server does not support challenge response or encrypt passwords. This may be a problem if an attacker can listen to the data transferred between the ODBC driver and the server, because the password is readable to the attacker. Also, it is currently not possible to use encrypted SSL connections. Therefore the ODBC driver should not be used where security is important. - -@advanced_1184_h2 -Using H2 in Microsoft .NET - -@advanced_1185_p - The database can be used from Microsoft .NET even without using Java, by using IKVM.NET. You can access a H2 database on .NET using the JDBC API, or using the ADO.NET interface. - -@advanced_1186_h3 -Using the ADO.NET API on .NET - -@advanced_1187_p - An implementation of the ADO.NET interface is available in the open source project H2Sharp. - -@advanced_1188_h3 -Using the JDBC API on .NET - -@advanced_1189_li -Install the .NET Framework from Microsoft. Mono has not yet been tested. - -@advanced_1190_li -Install IKVM.NET. - -@advanced_1191_li -Copy the h2*.jar file to ikvm/bin - -@advanced_1192_li -Run the H2 Console using: ikvm -jar h2*.jar - -@advanced_1193_li -Convert the H2 Console to an .exe file using: ikvmc -target:winexe h2*.jar. You may ignore the warnings. - -@advanced_1194_li -Create a .dll file using (change the version accordingly): ikvmc.exe -target:library -version:1.0.69.0 h2*.jar - -@advanced_1195_p - If you want your C# application use H2, you need to add the h2.dll and the IKVM.OpenJDK.ClassLibrary.dll to your C# solution. Here some sample code: - -@advanced_1196_h2 -ACID - -@advanced_1197_p - In the database world, ACID stands for: - -@advanced_1198_li -Atomicity: transactions must be atomic, meaning either all tasks are performed or none. - -@advanced_1199_li -Consistency: all operations must comply with the defined constraints. - -@advanced_1200_li -Isolation: transactions must be isolated from each other. - -@advanced_1201_li -Durability: committed transaction will not be lost. - -@advanced_1202_h3 -Atomicity - -@advanced_1203_p - Transactions in this database are always atomic. - -@advanced_1204_h3 -Consistency - -@advanced_1205_p - By default, this database is always in a consistent state. Referential integrity rules are enforced except when explicitly disabled. - -@advanced_1206_h3 -Isolation - -@advanced_1207_p - For H2, as with most other database systems, the default isolation level is 'read committed'. This provides better performance, but also means that transactions are not completely isolated. H2 supports the transaction isolation levels 'serializable', 'read committed', and 'read uncommitted'. - -@advanced_1208_h3 -Durability - -@advanced_1209_p - This database does not guarantee that all committed transactions survive a power failure. Tests show that all databases sometimes lose transactions on power failure (for details, see below). Where losing transactions is not acceptable, a laptop or UPS (uninterruptible power supply) should be used. If durability is required for all possible cases of hardware failure, clustering should be used, such as the H2 clustering mode. - -@advanced_1210_h2 -Durability Problems - -@advanced_1211_p - Complete durability means all committed transaction survive a power failure. Some databases claim they can guarantee durability, but such claims are wrong. A durability test was run against H2, HSQLDB, PostgreSQL, and Derby. All of those databases sometimes lose committed transactions. The test is included in the H2 download, see org.h2.test.poweroff.Test. - -@advanced_1212_h3 -Ways to (Not) Achieve Durability - -@advanced_1213_p - Making sure that committed transactions are not lost is more complicated than it seems first. To guarantee complete durability, a database must ensure that the log record is on the hard drive before the commit call returns. To do that, databases use different methods. One is to use the 'synchronous write' file access mode. In Java, RandomAccessFile supports the modes rws and rwd: - -@advanced_1214_code -rwd - -@advanced_1215_li -: every update to the file's content is written synchronously to the underlying storage device. - -@advanced_1216_code -rws - -@advanced_1217_li -: in addition to rwd, every update to the metadata is written synchronously. - -@advanced_1218_p - A test (org.h2.test.poweroff.TestWrite) with one of those modes achieves around 50 thousand write operations per second. Even when the operating system write buffer is disabled, the write rate is around 50 thousand operations per second. This feature does not force changes to disk because it does not flush all buffers. The test updates the same byte in the file again and again. If the hard drive was able to write at this rate, then the disk would need to make at least 50 thousand revolutions per second, or 3 million RPM (revolutions per minute). There are no such hard drives. The hard drive used for the test is about 7200 RPM, or about 120 revolutions per second. There is an overhead, so the maximum write rate must be lower than that. - -@advanced_1219_p - Calling fsync flushes the buffers. There are two ways to do that in Java: - -@advanced_1220_code -FileDescriptor.sync() - -@advanced_1221_li -. The documentation says that this forces all system buffers to synchronize with the underlying device. This method is supposed to return after all in-memory modified copies of buffers associated with this file descriptor have been written to the physical medium. - -@advanced_1222_code -FileChannel.force() - -@advanced_1223_li - (since JDK 1.4). This method is supposed to force any updates to this channel's file to be written to the storage device that contains it. - -@advanced_1224_p - By default, MySQL calls fsync for each commit. When using one of those methods, only around 60 write operations per second can be achieved, which is consistent with the RPM rate of the hard drive used. Unfortunately, even when calling FileDescriptor.sync() or FileChannel.force(), data is not always persisted to the hard drive, because most hard drives do not obey fsync(): see Your Hard Drive Lies to You. In Mac OS X, fsync does not flush hard drive buffers. See Bad fsync?. So the situation is confusing, and tests prove there is a problem. - -@advanced_1225_p - Trying to flush hard drive buffers is hard, and if you do the performance is very bad. First you need to make sure that the hard drive actually flushes all buffers. Tests show that this can not be done in a reliable way. Then the maximum number of transactions is around 60 per second. Because of those reasons, the default behavior of H2 is to delay writing committed transactions. - -@advanced_1226_p - In H2, after a power failure, a bit more than one second of committed transactions may be lost. To change the behavior, use SET WRITE_DELAY and CHECKPOINT SYNC. Most other databases support commit delay as well. In the performance comparison, commit delay was used for all databases that support it. - -@advanced_1227_h3 -Running the Durability Test - -@advanced_1228_p - 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. One computer just listens, while the test application is run (and power is cut) on the other computer. The computer with the listener application opens a TCP/IP port and listens for an incoming connection. The second computer first connects to the listener, and then created the databases and starts inserting records. The connection is set to 'autocommit', which means after each inserted record a commit is performed automatically. Afterwards, the test computer notifies the listener that this record was inserted successfully. The listener computer displays the last inserted record number every 10 seconds. Now, switch off the power manually, then restart the computer, and run the application again. You will find out that in most cases, none of the databases contains all the records that the listener computer knows about. For details, please consult the source code of the listener and test application. - -@advanced_1229_h2 -Using the Recover Tool - -@advanced_1230_p - The Recover tool can be used to extract the contents of a database file, even if the database is corrupted. It also extracts the content of the transaction log and large objects (CLOB or BLOB). To run the tool, type on the command line: - -@advanced_1231_p - For each database in the current directory, a text file will be created. This file contains raw insert statements (for the data) and data definition (DDL) statements to recreate the schema of the database. This file can be executed using the RunScript tool or a RUNSCRIPT FROM SQL statement. The script includes at least one CREATE USER statement. If you run the script against a database that was created with the same user, or if there are conflicting users, running the script will fail. Consider running the script against a database that was created with a user name that is not in the script. - -@advanced_1232_p - The Recover tool creates a SQL script from database file. It also processes the transaction log. - -@advanced_1233_h2 -File Locking Protocols - -@advanced_1234_p - Multiple concurrent connections to the same database are supported, however a database file can only be open for reading and writing (in embedded mode) by one process at the same time. Otherwise, the processes would overwrite each others data and corrupt the database file. To protect against this problem, whenever a database is opened, a lock file is created to signal other processes that the database is in use. If the database is closed, or if the process that opened the database stops normally, this lock file is deleted. - -@advanced_1235_p - In special cases (if the process did not terminate normally, for example because there was a power failure), 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. However, this software uses a challenge-response protocol to protect the database 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'. - -@advanced_1236_p - The file locking protocols have the following limitation: if a shared file system is used, and the machine with the lock owner is sent to sleep (standby or hibernate), another machine may take over. If the machine that originally held the lock wakes up, the database may become corrupt. If this situation can occur, the application must ensure the database is closed when the application is put to sleep. - -@advanced_1237_h3 -File Locking Method 'File' - -@advanced_1238_p - The default method for database file locking is the 'File Method'. The algorithm is: - -@advanced_1239_li -If the lock file does not exist, it is created (using the atomic operation File.createNewFile). Then, the process waits a little bit (20 ms) and checks the file again. If the file was changed during this time, the operation is aborted. This protects against a race condition when one process deletes the lock file just after another one create it, and a third process creates the file again. It does not occur if there are only two writers. - -@advanced_1240_li - If the file can be created, a random number is inserted together with the locking method ('file'). Afterwards, a watchdog thread is started that checks regularly (every second once by default) if the file was deleted or modified by another (challenger) thread / process. Whenever that occurs, the file is overwritten with the old data. The watchdog thread runs with high priority so that a change to the lock file does not get through undetected even if the system is very busy. However, the watchdog thread does use very little resources (CPU time), because it waits most of the time. Also, the watchdog only reads from the hard disk and does not write to it. - -@advanced_1241_li - If the lock file exists and was recently modified, the process waits for some time (up to two seconds). If it was still changed, an exception is thrown (database is locked). This is done to eliminate race conditions with many concurrent writers. Afterwards, the file is overwritten with a new version (challenge). After that, the thread waits for 2 seconds. If there is a watchdog thread protecting the file, he will overwrite the change and this process will fail to lock the database. However, if there is no watchdog thread, the lock file will still be as written by this thread. In this case, the file is deleted and atomically created again. The watchdog thread is started in this case and the file is locked. - -@advanced_1242_p - This algorithm is tested with over 100 concurrent threads. In some cases, when there are many concurrent threads trying to lock the database, they block each other (meaning the file cannot be locked by any of them) for some time. However, the file never gets 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. - -@advanced_1243_h3 -File Locking Method 'Socket' - -@advanced_1244_p - There is a second locking mechanism implemented, but disabled by default. To use it, append ;FILE_LOCK=SOCKET to the database URL. The algorithm is: - -@advanced_1245_li -If the lock file does not exist, it is created. Then a server socket is opened on a defined port, and kept open. The port and IP address of the process that opened the database is written into the lock file. - -@advanced_1246_li -If the lock file exists, and the lock method is 'file', then the software switches to the 'file' method. - -@advanced_1247_li -If the lock file exists, and the lock method is 'socket', then the process checks if the port is in use. If the original process is still running, the port is in use and this process throws an exception (database is in use). If the original process died (for example due to a power failure, or abnormal termination of the virtual machine), then the port was released. The new process deletes the lock file and starts again. - -@advanced_1248_p - This method does not require a watchdog thread actively polling (reading) the same file every second. The problem with this method is, if the file is stored on a network share, two processes (running on different computers) could still open the same database files, if they do not have a direct TCP/IP connection. - -@advanced_1249_h2 -File Locking Method 'Serialized' - -@advanced_1250_p - This locking mode allows to open multiple connections to the same database. The connections may be opened from multiple processes and from different computers. When writing to the database, access is automatically synchronized internally. Write operations are slower than when using the server mode, and concurrency is relatively poor. The advantage of this mode is that there is no need to start a server. - -@advanced_1251_p - To enable this feature, append ;FILE_LOCK=SERIALIZED to the database URL. - -@advanced_1252_p - This feature is relatively new. When using it for production, please ensure your use case is well tested (if possible with automated test cases). - -@advanced_1253_h2 -Protection against SQL Injection - -@advanced_1254_h3 -What is SQL Injection - -@advanced_1255_p - This database engine provides a solution for the security vulnerability known as 'SQL Injection'. Here is a short description of what SQL injection means. Some applications build SQL statements with embedded user input such as: - -@advanced_1256_p - If this mechanism is used anywhere in the application, and user input is not correctly filtered or encoded, it is possible for a user to inject SQL functionality or statements by using specially built input such as (in this example) this password: ' OR ''='. In this case the statement becomes: - -@advanced_1257_p - Which is always true no matter what the password stored in the database is. For more information about SQL Injection, see Glossary and Links. - -@advanced_1258_h3 -Disabling Literals - -@advanced_1259_p - SQL Injection is not possible if user input is not directly embedded in SQL statements. A simple solution for the problem above is to use a prepared statement: - -@advanced_1260_p - This database provides a way to enforce usage of parameters when passing user input to the database. This is done by disabling embedded literals in SQL statements. To do this, execute the statement: - -@advanced_1261_p - Afterwards, SQL statements with text and number literals are not allowed any more. That means, SQL statement of the form WHERE NAME='abc' or WHERE CustomerId=10 will fail. It is still possible to use prepared statements and parameters as described above. Also, it is still possible to generate SQL statements dynamically, and use the Statement API, as long as the SQL statements do not include literals. There is also a second mode where number literals are allowed: SET ALLOW_LITERALS NUMBERS. To allow all literals, execute SET ALLOW_LITERALS ALL (this is the default setting). Literals can only be enabled or disabled by an administrator. - -@advanced_1262_h3 -Using Constants - -@advanced_1263_p - Disabling literals also means disabling hard-coded 'constant' literals. This database supports defining constants using the CREATE CONSTANT command. Constants can be defined only when literals are enabled, but used even when literals are disabled. To avoid name clashes with column names, constants can be defined in other schemas: - -@advanced_1264_p - Even when literals are enabled, it is better to use constants instead of hard-coded number or text literals in queries or views. With constants, typos are found at compile time, the source code is easier to understand and change. - -@advanced_1265_h3 -Using the ZERO() Function - -@advanced_1266_p - It is not required to create a constant for the number 0 as there is already a built-in function ZERO(): - -@advanced_1267_h2 -Protection against Remote Access - -@advanced_1268_p - By default this database does not allow connections from other machines when starting the H2 Console, the TCP server, or the PG server. Remote access can be enabled using the command line options -webAllowOthers, -tcpAllowOthers, -pgAllowOthers. If you enable remote access, please also consider using the options -baseDir, -ifExists, so that remote users can not create new databases or access existing databases with weak passwords. When using the option -baseDir, only databases within that directory may be accessed. Ensure the existing accessible databases are protected using strong passwords. - -@advanced_1269_h2 -Restricting Class Loading and Usage - -@advanced_1270_p - By default there is no restriction on loading classes and executing Java code for admins. That means an admin may call system functions such as System.setProperty by executing: - -@advanced_1271_p - To restrict users (including admins) from loading classes and executing code, the list of allowed classes can be set in the system property h2.allowedClasses in the form of a comma separated list of classes or patterns (items ending with *). By default all classes are allowed. Example: - -@advanced_1272_p - This mechanism is used for all user classes, including database event listeners, trigger classes, user-defined functions, user-defined aggregate functions, and JDBC driver classes (with the exception of the H2 driver) when using the H2 Console. - -@advanced_1273_h2 -Security Protocols - -@advanced_1274_p - 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. - -@advanced_1275_h3 -User Password Encryption - -@advanced_1276_p - When a user tries to connect to a database, the combination of user name, @, and password are hashed using SHA-256, and this hash value is transmitted to the database. This step does not protect against an attacker that re-uses the value if he is able to listen to the (unencrypted) transmission between the client and the server. But, the passwords are never transmitted as plain text, even when using an unencrypted connection between client and server. 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. - -@advanced_1277_p - When a new database or user is created, a new random salt value is generated. The size of the salt is 64 bits. Using the random salt reduces the risk of an attacker pre-calculating hash values for many different (commonly used) passwords. - -@advanced_1278_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 user-password hash value with the stored salt value and calculates the hash value. Other products use multiple iterations (hash the hash value again and again), but this is not done in this product to reduce the risk of denial of service attacks (where the attacker tries to connect with bogus passwords, and the server 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 accessible remotely, then the iteration count is not required at all. - -@advanced_1279_h3 -File Encryption - -@advanced_1280_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. - -@advanced_1281_p - When a user tries to connect to an encrypted database, the combination of file@ and the file password is hashed using SHA-256. This hash value is transmitted to the server. - -@advanced_1282_p - When a new database file is created, a new cryptographically secure random salt value is generated. The size of the salt is 64 bits. 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. - -@advanced_1283_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. - -@advanced_1284_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. - -@advanced_1285_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. - -@advanced_1286_p - Therefore, the block cipher mode 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. - -@advanced_1287_p - Database encryption is meant for securing the database while it is not in use (stolen laptop and so on). It is not meant for cases where the attacker has access to files while the database is in use. When he has write access, he can for example replace pieces of files with pieces of older versions and manipulate data like this. - -@advanced_1288_p - File encryption slows down the performance of the database engine. Compared to unencrypted mode, database operations take about 2.2 times longer when using XTEA, and 2.5 times longer using AES (embedded mode). - -@advanced_1289_h3 -Wrong Password / User Name Delay - -@advanced_1290_p - To protect against remote brute force password attacks, the delay after each unsuccessful login gets double as long. Use the system properties h2.delayWrongPasswordMin and h2.delayWrongPasswordMax to change the minimum (the default is 250 milliseconds) or maximum delay (the default is 4000 milliseconds, or 4 seconds). The delay only applies for those using the wrong password. Normally there is no delay for a user that knows the correct password, with one exception: after using the wrong password, there is a delay of up to (randomly distributed) the same delay as for a wrong password. This is to protect against parallel brute force attacks, so that an attacker needs to wait for the whole delay. Delays are synchronized. This is also required to protect against parallel attacks. - -@advanced_1291_p - There is only one exception message for both wrong user and for wrong password, to make it harder to get the list of user names. It is not possible from the stack trace to see if the user name was wrong or the password. - -@advanced_1292_h3 -HTTPS Connections - -@advanced_1293_p - 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. - -@advanced_1294_h2 -SSL/TLS Connections - -@advanced_1295_p - Remote SSL/TLS connections are supported using the Java Secure Socket Extension (SSLServerSocket, SSLSocket). By default, anonymous SSL is enabled. The default cipher suite is SSL_DH_anon_WITH_RC4_128_MD5. - -@advanced_1296_p - To use your own keystore, set the system properties javax.net.ssl.keyStore and javax.net.ssl.keyStorePassword before starting the H2 server and client. See also Customizing the Default Key and Trust Stores, Store Types, and Store Passwords for more information. - -@advanced_1297_p - To disable anonymous SSL, set the system property h2.enableAnonymousSSL to false. - -@advanced_1298_h2 -Universally Unique Identifiers (UUID) - -@advanced_1299_p - This database supports UUIDs. Also supported is a function to create new UUIDs using a cryptographically strong pseudo random number generator. With random UUIDs, the chance of two having the same value can be calculated using the probability theory. See also 'Birthday Paradox'. Standardized randomly generated UUIDs have 122 random bits. 4 bits are used for the version (Randomly generated UUID), and 2 bits for the variant (Leach-Salz). This database supports generating such UUIDs using the built-in function RANDOM_UUID(). Here is a small program to estimate the probability of having two identical UUIDs after generating a number of values: - -@advanced_1300_p - Some values are: - -@advanced_1301_th -Number of UUIs - -@advanced_1302_th -Probability of Duplicates - -@advanced_1303_td -2^36=68'719'476'736 - -@advanced_1304_td -0.000'000'000'000'000'4 - -@advanced_1305_td -2^41=2'199'023'255'552 - -@advanced_1306_td -0.000'000'000'000'4 - -@advanced_1307_td -2^46=70'368'744'177'664 - -@advanced_1308_td -0.000'000'000'4 - -@advanced_1309_p - To help non-mathematicians understand what those numbers mean, here a comparison: 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. - -@advanced_1310_h2 -Settings Read from System Properties - -@advanced_1311_p - Some settings of the database can be set on the command line using -DpropertyName=value. It is usually not required to change those settings manually. The settings are case sensitive. Example: - -@advanced_1312_p - The current value of the settings can be read in the table INFORMATION_SCHEMA.SETTINGS. - -@advanced_1313_p - For a complete list of settings, see SysProperties. - -@advanced_1314_h2 -Setting the Server Bind Address - -@advanced_1315_p - Usually server sockets accept connections on any/all local addresses. This may be a problem on multi-homed hosts. To bind only to one address, use the system property h2.bindAddress. This setting is used for both regular server sockets and for SSL server sockets. IPv4 and IPv6 address formats are supported. - -@advanced_1316_h2 -Pluggable File System - -@advanced_1317_p - This database supports a pluggable file system API. The file system implementation is selected using a file name prefix. The following file systems are included: - -@advanced_1318_code -zip: - -@advanced_1319_li - read-only zip-file based file system. Format: zip:/zipFileName!/fileName. - -@advanced_1320_code -nio: - -@advanced_1321_li - file system that uses FileChannel instead of RandomAccessFile (faster in some operating systems). - -@advanced_1322_code -nioMapped: - -@advanced_1323_li - file system that uses memory mapped files (faster in some operating systems). - -@advanced_1324_code -split: - -@advanced_1325_li - file system that splits files in 1 GB files (stackable with other file systems). - -@advanced_1326_code -memFS: - -@advanced_1327_li - in-memory file system (slower than mem; experimental; mainly used for testing the database engine itself). - -@advanced_1328_code -memLZF: - -@advanced_1329_li - compressing in-memory file system (slower than memFS but uses less memory; experimental; mainly used for testing the database engine itself). - -@advanced_1330_p - As an example, to use the the nio file system, use the following database URL: jdbc:h2:nio:~/test. - -@advanced_1331_p - To register a new file system, extend the classes org.h2.store.fs.FileSystem, FileObject, and call the method FileSystem.register before using it. - -@advanced_1332_h2 -Limits and Limitations - -@advanced_1333_p - This database has the following known limitations: - -@advanced_1334_li -Database file size limits (excluding BLOB and CLOB data): With the default storage mechanism, the maximum file size is currently 256 GB for the data, and 256 GB for the index. With the page store (experimental): 4 TB or higher. - -@advanced_1335_li -BLOB and CLOB size limit: every CLOB or BLOB can be up to 256 GB. - -@advanced_1336_li -The maximum file size for FAT or FAT32 file systems is 4 GB. That means when using FAT or FAT32, the limit is 4 GB for the data. This is the limitation of the file system. The database does provide a workaround for this problem, it is to use the file name prefix split:. In that case files are split into files of 1 GB by default. An example database URL is: jdbc:h2:split:~/test. - -@advanced_1337_li -The maximum number of rows per table is 2'147'483'648. - -@advanced_1338_li -Main memory requirements: The larger the database, the more main memory is required. With the default storage mechanism, the minimum main memory required for a 12 GB database is around 240 MB. With the page store (experimental), the minimum main memory required is much lower, around 1 MB for each 8 GB database file size. - -@advanced_1339_li -Limit on the complexity of SQL statements. Statements of the following form will result in a stack overflow exception: - -@advanced_1340_li -There is no limit for the following entities, except the memory and storage capacity: maximum identifier length (table name, column name, and so on); maximum number of tables, columns, indexes, triggers, and other database objects; maximum statement length, number of parameters per statement, tables per statement, expressions in order by, group by, having, and so on; maximum rows per query; maximum columns per table, columns per index, indexes per table, lob columns per table, and so on; maximum row length, index row length, select row length; maximum length of a varchar column, decimal column, literal in a statement. - -@advanced_1341_li -For limitations on data types, see the documentation of the respective Java data type or the data type documentation of this database. - -@advanced_1342_h2 -Glossary and Links - -@advanced_1343_th -Term - -@advanced_1344_th -Description - -@advanced_1345_td -AES-128 - -@advanced_1346_td -A block encryption algorithm. See also: Wikipedia: AES - -@advanced_1347_td -Birthday Paradox - -@advanced_1348_td -Describes the higher than expected probability that two persons in a room have the same birthday. Also valid for randomly generated UUIDs. See also: Wikipedia: Birthday Paradox - -@advanced_1349_td -Digest - -@advanced_1350_td -Protocol to protect a password (but not to protect data). See also: RFC 2617: HTTP Digest Access Authentication - -@advanced_1351_td -GCJ - -@advanced_1352_td -Compiler for Java. GNU Compiler for the Java and NativeJ (commercial) - -@advanced_1353_td -HTTPS - -@advanced_1354_td -A protocol to provide security to HTTP connections. See also: RFC 2818: HTTP Over TLS - -@advanced_1355_td -Modes of Operation - -@advanced_1356_a -Wikipedia: Block cipher modes of operation - -@advanced_1357_td -Salt - -@advanced_1358_td -Random number to increase the security of passwords. See also: Wikipedia: Key derivation function - -@advanced_1359_td -SHA-256 - -@advanced_1360_td -A cryptographic one-way hash function. See also: Wikipedia: SHA hash functions - -@advanced_1361_td -SQL Injection - -@advanced_1362_td -A security vulnerability where an application embeds SQL statements or expressions in user input. See also: Wikipedia: SQL Injection - -@advanced_1363_td -Watermark Attack - -@advanced_1364_td -Security problem of certain encryption programs where the existence of certain data can be proven without decrypting. For more information, search in the internet for 'watermark attack cryptoloop' - -@advanced_1365_td -SSL/TLS - -@advanced_1366_td -Secure Sockets Layer / Transport Layer Security. See also: Java Secure Socket Extension (JSSE) - -@advanced_1367_td -XTEA - -@advanced_1368_td -A block encryption algorithm. See also: Wikipedia: XTEA - -@build_1000_h1 -Build - -@build_1001_a - Portability - -@build_1002_a - Environment - -@build_1003_a - Building the Software - -@build_1004_a - Build Targets - -@build_1005_a - Using Maven 2 - -@build_1006_a - Translating - -@build_1007_a - Providing Patches - -@build_1008_a - Reporting Problems or Requests - -@build_1009_a - Automated Build - -@build_1010_a - Generating Railroad Diagrams - -@build_1011_h2 -Portability - -@build_1012_p - This database is written in Java and therefore works on many platforms. It can also be compiled to a native executable using GCJ. - -@build_1013_p - For Java 1.4, the jar file needs to be converted first using Retrotranslator. - -@build_1014_h2 -Environment - -@build_1015_p - To run this database, a Java Runtime Environment (JRE) version 1.5 or higher is required. - -@build_1016_p - To create the database executables, the following software stack was used. To use this database, it is not required to install this software however. - -@build_1017_li -Mac OS X and Windows XP - -@build_1018_a -Sun JDK Version 1.5 and 1.6 - -@build_1019_a -Eclipse Version 3.4 - -@build_1020_li -Eclipse Plugins: Subclipse, Eclipse Checkstyle Plug-in, EclEmma Java Code Coverage 1.3.0 - -@build_1021_a -Emma Java Code Coverage - -@build_1022_a -Mozilla Firefox - -@build_1023_a -OpenOffice - -@build_1024_a -NSIS 2.38 - -@build_1025_li - (Nullsoft Scriptable Install System) - -@build_1026_a -Maven - -@build_1027_h2 -Building the Software - -@build_1028_p - You need to install a JDK, for example the Sun JDK version 1.5 or 1.6. Ensure that Java binary directory is included in the PATH environment variable, and that the environment variable JAVA_HOME points to your Java installation. On the command line, go to the directory h2 and execute the following command: - -@build_1029_p - For Linux and OS X, use ./build.sh instead of build. - -@build_1030_p - You will get a list of targets. If you want to build the jar file, execute (Windows): - -@build_1031_h3 -Switching the Source Code - -@build_1032_p - By default the source code uses Java 1.5 features, however Java 1.6 is supported as well. To switch the source code to the installed version of Java, run: - -@build_1033_h2 -Build Targets - -@build_1034_p - The build system can generate smaller jar files as well. The following targets are currently supported: - -@build_1035_code -jarClient - -@build_1036_li - creates the file h2client.jar. This only contains the JDBC client. - -@build_1037_code -jarSmall - -@build_1038_li - creates the file h2small.jar. This only contains the embedded database. Debug information is disabled. - -@build_1039_code -jarJaqu - -@build_1040_li - creates the file h2jaqu.jar. This only contains the JaQu (Java Query) implementation. All other jar files do not include JaQu. - -@build_1041_code -javadocImpl - -@build_1042_li - creates the Javadocs of the implementation. - -@build_1043_p - To create the file h2client.jar, go to the directory h2 and execute the following command: - -@build_1044_h2 -Using Maven 2 - -@build_1045_h3 -Using a Central Repository - -@build_1046_p - You can include the database in your Maven 2 project as a dependency. Example: - -@build_1047_p - New versions of this database are first uploaded to http://hsql.sourceforge.net/m2-repo/ and then automatically synchronized with the main Maven repository; however after a new release it may take a few hours before they are available there. - -@build_1048_h3 -Using Snapshot Version - -@build_1049_p - To build a h2-*-SNAPSHOT.jar file and upload it the to the local Maven 2 repository, execute the following command: - -@build_1050_p - Afterwards, you can include the database in your Maven 2 project as a dependency: - -@build_1051_h2 -Translating - -@build_1052_p - The translation of this software is split into the following parts: - -@build_1053_li -H2 Console: src/main/org/h2/server/web/res/_text_*.prop - -@build_1054_li -Error messages: src/main/org/h2/res/_messages_*.prop - -@build_1055_p - To translate the H2 Console, start it and select Preferences / Translate. After you are done, send the translated *.prop file to the Google Group. The web site is currently translated using Google. - -@build_1056_h2 -Providing Patches - -@build_1057_p - If you like to provide patches, please consider the following guidelines to simplify merging them: - -@build_1058_li -Only use Java 1.5 features (do not use Java 1.6) (see Environment). - -@build_1059_li -Follow the coding style used in the project, and use Checkstyle (see above) to verify. For example, do not use tabs (use spaces instead). The checkstyle configuration is in src/installer/checkstyle.xml. - -@build_1060_li -A template of the Eclipse settings are in src/installer/eclipse.settings/*. If you want to use them, you need to copy them to the .settings directory. The formatting options (eclipseCodeStyle) are also included. - -@build_1061_li -Please provide test cases and integrate them into the test suite. For Java level tests, see src/test/org/h2/test/TestAll.java. For SQL level tests, see src/test/org/h2/test/test.in.txt or testSimple.in.txt. - -@build_1062_li -The test cases should cover at least 90% of the changed and new code; use a code coverage tool to verify that (see above). or use the build target coverage. - -@build_1063_li -Verify that you did not break other features: run the test cases by executing build test. - -@build_1064_li -Provide end user documentation if required (src/docsrc/html/*). - -@build_1065_li -Document grammar changes in src/docsrc/help/help.csv - -@build_1066_li -Provide a change log entry (src/docsrc/html/changelog.html). - -@build_1067_li -Verify the spelling using build spellcheck. If required add the new words to src/tools/org/h2/build/doc/dictionary.txt. - -@build_1068_li -Run src/installer/buildRelease to find and fix formatting errors. - -@build_1069_li -Verify the formatting using build docs and build javadoc. - -@build_1070_li -Submit patches as .patch files (compressed if big). To create a patch using Eclipse, use Team / Create Patch. - -@build_1071_p - For legal reasons, patches need to be public in the form of an email to the group, or in the form of an issue report or attachment. Significant contributions need to include the following statement: - -@build_1072_p - "I wrote the code, it's mine, and I'm contributing it to H2 for distribution multiple-licensed under the H2 License, version 1.0, and under the Eclipse Public License, version 1.0 (http://h2database.com/html/license.html)." - -@build_1073_h2 -Reporting Problems or Requests - -@build_1074_p - Please consider the following checklist if you have a question, want to report a problem, or if you have a feature request: - -@build_1075_li -Feature requests are always welcome, even if the feature is already on the roadmap. Your mail will help prioritize feature requests. If you urgently need a feature, consider providing a patch. - -@build_1076_li -Before posting problems, check the FAQ and do a Google search. - -@build_1077_li -When got an unexpected exception, please try the Error Analyzer tool. If this doesn't help, please report the problem, including the complete error message and stack trace, and the root cause stack trace(s). - -@build_1078_li -When sending source code, please use a public web clipboard such as Pastebin, Cl1p, or Mystic Paste to avoid formatting problems. Please keep test cases as simple and short as possible, but so that the problem can still be reproduced. As a template, use: HelloWorld.java. Method that simply call other methods should be avoided, as well as unnecessary exception handling. Please use the JDBC API and no external tools or libraries. The test should include all required initialization code, and should be started with the main method. - -@build_1079_li -For large attachments, use a public temporary storage such as Rapidshare. - -@build_1080_li -Google Group versus issue tracking: Use the Google Group for questions or if you are not sure it's a bug. If you are sure it's a bug, you can create an issue, but you don't need to (sending an email to the group is enough). Please note that only few people monitor the issue tracking system. - -@build_1081_li -For out-of-memory problems, please analyze the problem yourself first, for example using the command line option -XX:+HeapDumpOnOutOfMemoryError and a memory analysis tool such as the Eclipse Memory Analyzer (MAT). - -@build_1082_li -It may take a few days to get an answers. Please do not double post. - -@build_1083_h2 -Automated Build - -@build_1084_p - This build process is automated and runs regularly. The build process includes running the tests and code coverage, using the command line ./build.sh clean jar coverage -Dh2.ftpPassword=... uploadBuild. The last results are available here: - -@build_1085_a -Test Output - -@build_1086_a -Code Coverage Summary - -@build_1087_a -Code Coverage Details (download, 1.3 MB) - -@build_1088_a -Build Newsfeed - -@build_1089_a -Latest Jar File (download, 1 MB) - -@build_1090_h2 -Generating Railroad Diagrams - -@build_1091_p - The railroad diagrams are HTML, formatted as nested tables. The diagrams are generated as follows: - -@build_1092_li -The BNF parser (org.h2.bnf.Bnf) reads and parses the BNF from the file help.csv. - -@build_1093_li -The page parser (org.h2.server.web.PageParser) reads the template HTML file and fills in the diagrams. - -@build_1094_li -The rail images (one straight, four junctions, two turns) are generated using a simple Java application. - -@build_1095_p - To generate railroad diagrams for other grammars, see the package org.h2.jcr. This package is used to generate the SQL-2 railroad diagrams for the JCR 2.0 specification. - -@changelog_1000_h1 -Change Log - -@changelog_1001_h2 -Next Version (unreleased) - -@changelog_1002_li -- - -@changelog_1003_h2 -Version 1.2.137 (2010-06-06) - -@changelog_1004_li -Statements with a nested query and a condition that was always NULL threw an IndexOutOfBoundsException. Example: select * from (select null as x) where x=1 - -@changelog_1005_li -Experimental feature to support very large transactions (except when using MVCC). To enable, set the system property h2.largeTransactions to true. If enabled, changes to tables without a primary key can be buffered to disk. The plan is to enable this feature by default in version 1.3.x. - -@changelog_1006_li -H2 Console: editing result sets is now also working for database other than H2, if they do support updatable result sets. Add "@edit" before the query. Only limited testing has been done on this feature, some data types may not work (please provide feedback if you find issues). - -@changelog_1007_li -Cluster: an open transaction was committed when a cluster node was stopped (because disabling the cluster executes SET CLUSTER '', which committed the transaction). Transaction are no longer committed when calling SET CLUSTER. Issue 199. - -@changelog_1008_li -Cluster: non-admin users couldn't connect to the cluster and couldn't disable the cluster. Issue 201. - -@changelog_1009_li -Cluster: NEXTVAL('sequence') was only called on one cluster node, therefore sequence values could get out of sync. - -@changelog_1010_li -Version 1.2.136 could not be converted to Java 1.4 (because the Retrotranslator doesn't support BigDecimal.precision). A workaround has been implemented. - -@changelog_1011_li -The error code of IO exceptions in CSV functions was incorrect. - -@changelog_1012_li -The TriggerPassData example now uses a prefix (the database name). - -@changelog_1013_li -The wrong exception was thrown when trying to reference a table that doesn't support references such as a table in the information schema. - -@changelog_1014_li -Server.shutdownTcpServer can now stop all TCP servers on this JVM. - -@changelog_1015_li -JdbcConnectionPool: the default connection timeout is now 30 seconds (it used to be 5 minutes). - -@changelog_1016_li -LOB storage: LOBs added with "h2.lobInDatabase" enabled couldn't be read later with this option disabled. - -@changelog_1017_h2 -Version 1.2.136 (2010-05-24) - -@changelog_1018_li -When using ORDER BY and there are both ascending and descending indexes, the database used the first index even when the second one could be used for sorting. - -@changelog_1019_li -Conditions of the form columnName IS NULL now use an index. To disable this feature, set the system property h2.optimizeIsNull to false. - -@changelog_1020_li -H2 Console: when the settings were not stored yet (for example when running for the first time), the last recently used settings were not stored. A workaround was to create the file ".h2.server.properties" manually in the current user home directory, with the contents: webAllowOthers=false, webPort=8082, webSSL=false, 0=Generic H2 (Embedded)|org.h2.Driver|jdbc\:h2\:~/test|sa (where a comma is a newline). - -@changelog_1021_li -The source code is now switched to Java 6 (JDK 1.6) by default. Java 5 (JDK 1.5) is still supported, and the jar file is still compiled for Java 5. - -@changelog_1022_li -The BOM (the byte-order-mark) character 0xfeff at the beginning of the file is ignored. This is for compatibility with Microsoft Excel. - -@changelog_1023_li -When opening an existing database, the cache size is set to at most half the amount of memory available for the virtual machine (Runtime.getRuntime().maxMemory()), even if the cache size setting stored in the database is larger. Setting the cache size in the database URL or explicitly using SET CACHE_SIZE overrides this value (even if larger than the physical memory). - -@changelog_1024_li -INFORMATION_SCHEMA.SETTINGS: the cache size is now returned in KB. - -@changelog_1025_li -New system property h2.selectForUpdateMvcc, the default is false (the feature is disabled). When enabled, SELECT ... FOR UPDATE only locks the selected rows in the MVCC mode. Aggregate or GROUP BY queries are not allowed in this case. - -@changelog_1026_li -Profiler: improved message if there was no stack trace. - -@changelog_1027_li -The H2 Console can now be used within another application, in a frame or iframe. Issue 197. - -@changelog_1028_li -Recover tool: the statistics section now includes page type counts again. - -@changelog_1029_li -Queries with multiple IN(...) conditions sometimes return the wrong results when there was a multi-column index for the column. - -@changelog_1030_li -Queries with IN(..., NULL) did sometimes return the wrong results when there was a index for the column. - -@changelog_1031_li -DECIMAL: faster precision and memory usage calculations. - -@changelog_1032_li -A new class org.h2.tools.TriggerAdapter allows to use the ResultSet interface within trigger implementations. - -@changelog_1033_li -A subselect which used an index could lead to wrong results. Fixed. - -@changelog_1034_li -Creating a cached temporary non persistent table with a primary key threw a NullPointerException. - -@changelog_1035_h2 -Version 1.2.135 (2010-05-08) - -@changelog_1036_li -Temporary files were not deleted when using large transactions, disabling autocommit, and closing the session without committing. - -@changelog_1037_li -Queries using multiple IN(..) conditions on the same table could cause repeated rows in the result set. - -@changelog_1038_li -Translation: Lubomir Grajciar translated the H2 Console as well as all error message to Slovensky. Thanks a lot! - -@changelog_1039_li -There was a possible Java level deadlock when opening an uninitialized database and using a file system that also opened a database. - -@changelog_1040_li -When killing the process while the database was writing a checkpoint, while it was closing, or while running recovery (while removing temporary tables from a previous run), the database could become corrupt. A new test case has been implemented to ensure such problems can not occur in the future. - -@changelog_1041_li -File system: new method FileSystem.setReadOnly. - -@changelog_1042_li -The page size for new databases can now be set in the database URL using ;PAGE_SIZE=512. Currently this feature is only used to simplify testing. - -@changelog_1043_li -New system property h2.functionsInSchema (default is false). If enabled, the SCRIPT statement always includes the schema name in the CREATE ALIAS statement (even if the schema is PUBLIC). This is not backward compatible with H2 versions 1.2.134 and older. - -@changelog_1044_li -Functions: it is no longer required to add a space after a comma in the parameter list. Example: CREATE ALIAS PARSE_INT FOR "java.lang.Integer.parseInt(java.lang.String,int)" - -@changelog_1045_li -Functions now reside within a schema, similar to sequences. If you do create such functions in schemas other than PUBLIC, then the database can not be opened with older versions of H2. - -@changelog_1046_li -Cluster: after a cluster node failed, the second cluster node can now be re-created and started without having to stop the first cluster node, and without having to stop running applications. To do that, append ;AUTO_RECONNECT=TRUE to the database URL. - -@changelog_1047_li -Auto-reconnect: if another connection uses the database in exclusive mode then this connection will try to re-connect until the exclusive mode ends. This is important when using the cluster mode. - -@changelog_1048_li -SET EXCLUSIVE now supports 0 (disable), 1 (enable), and 2 (enable and close all other connections). - -@changelog_1049_li -Installing the H2 as a service should now work on Windows 7. The batch files now explicitly set the directory using pushd "%~dp0". - -@changelog_1050_li -Temporary tables can now be 'cached', that means indexes of temporary tables can be persisted. This enables very large temporary tables (both local and global). - -@changelog_1051_li -The CreateCluster tool now sets the source database in exclusive mode before copying data to the new database. - -@changelog_1052_li -The H2 Console now stream results one statement / result set at a time (using chunked transfer encoding). To disable, set the system property h2.consoleStream to false. This feature is not supported when using a servlet container. - -@changelog_1053_li -The H2 Console did not call the CreateCluster tool with the correctly escaped parameters. - -@changelog_1054_li -Improved PostgreSQL compatibility for ALTER TABLE ALTER COLUMN. - -@changelog_1055_li -Commas at the end of INSERT ... VALUES (), (), are now supported. - -@changelog_1056_li -The H2 Console "Start Browser" button now works even when the IP address changes while the tool runs (for example, because a wireless connection breaks, or when enabling / disabling the network connection). - -@changelog_1057_li -When casting from float or double to BigDecimal, the result was sometimes unexpected, because "new BigDecimal(double val)" was used. Now "BigDecimal.valueOf(double val)" and "new BigDecimal(Float.toString(f))" are used. But it is still not recommended to use float or double for currency values (see data type documentation). - -@changelog_1058_li -Global temporary tables are now deleted when closing the database. Before, they were deleted when opening the database the next time. - -@changelog_1059_li -UNIQUE was not listed as a keyword. - -@changelog_1060_li -Improved error message when an non-SQL-exception occurred in a user defined function. The method name and parameters are included in the error message. - -@changelog_1061_li -For some queries, the exception did not include the SQL statement. Example: select x from system_range(1, 2) group by 'a'. - -@changelog_1062_li -The Shell tool will execute SQL statements passed as using the command line parameter -sql. - -@changelog_1063_li -If InetAddress.getLocalHost() fails, the database should now throw an exception. - -@changelog_1064_li -New columns INFORMATION_SCHEMA.INDEXES.INDEX_CLASS and INFORMATION_SCHEMA.TABLES.TABLE_CLASS. - -@changelog_1065_li -INFORMATION_SCHEMA.INDEXES.SQL now contains the CREATE INDEX statement instead of just the fully qualified index name. - -@changelog_1066_h2 -Version 1.2.134 (2010-04-23) - -@changelog_1067_li -New system property h2.analyzeAuto (default 0 meaning disabled) to automatically run ANALYZE after that many changes to a table. For details, see the Javadoc of this system property. The plan is to set this property to 2000 in version 1.3.x. - -@changelog_1068_li -JdbcXAConnection.start() does not support TMJOIN. Issue 189. - -@changelog_1069_li -MySQL compatibility: TIMESTAMPDIFF is now an alias for DATEDIFF. - -@changelog_1070_li -MERGE did not respect foreign key and check constraints. - -@changelog_1071_li -ALTER TABLE ALTER COLUMN: changing the data type of a column no longer makes it nullable. - -@changelog_1072_li -When using AUTO_SERVER=TRUE, the server is now started as a daemon thread. This was a problem when using Tomcat and a connection pool. - -@changelog_1073_li -Servers can now be started as a daemon thread using the command line options -tcpDaemon, -pgDaemon, and -webDaemon. - -@changelog_1074_li -H2 Console: the built-in commands are now documented. - -@changelog_1075_li -REPLACE: if any parameter is null, the result is null. - -@changelog_1076_li -Queries with DISTINCT and ORDER BY will now use the index on ORDER BY if possible. This is specially important for queries used inside IN(SELECT ...). - -@changelog_1077_li -The new statement EXPLAIN ANALYZE executes the statement, and displays the query plan with the actual row scan count for each table. - -@changelog_1078_li -H2 Console: the auto-complete feature didn't quote column names that need quoting. Issue 186. - -@changelog_1079_li -The experimental LOB storage mechanism now supports all features of the old one. To use it, set the system property "h2.lobInDatabase" to "true". If you have used this feature in version 1.2.133, you need to export and re-import the database using SCRIPT / RUNSCRIPT. - -@changelog_1080_li -The functions isBeforeFirst() and isAfterLast() were not compliant to the JDBC spec. If the ResultSet contains no rows, they must return false. Fixed. - -@changelog_1081_li -Filesystem parameters like "split:" didn't work in server mode with baseDir set. - -@changelog_1082_li -If baseDir is set, and a database name is given which points to a directory outside the baseDir (eg. "../dbname"), an exception is thrown. - -@changelog_1083_h2 -Version 1.2.133 (2010-04-10) - -@changelog_1084_li -A new experimental LOB storage mechanism is available. When enabled, CLOB and BLOB data is stored in hidden tables in the database. To use it, set the system property "h2.lobInDatabase" to "true". Compression is not yet implemented. Duplicate objects are only stored once. Usually writing is slower, but reading is faster (mainly because of caching). - -@changelog_1085_li -The Shell tool threw a NumberFormatException on a empty statement. - -@changelog_1086_li -The h2small-*.jar did not support "drop all objects delete files". Now it is supported (the DeleteDbFiles tool is now included). - -@changelog_1087_li -Operations that don't fit in memory are now faster. Temporary file handling was changed. - -@changelog_1088_li -The default maximum log stream size is now 2 MB. This is a good value according to some performance tests. - -@changelog_1089_li -New system property "h2.syncMethod" to configure what method to call when closing the database, on checkpoint, and on CHECKPOINT SYNC. The default is "sync" which calls RandomAccessFile.getFD().sync(). - -@changelog_1090_li -ROWNUM could not be used for pagination. The follow query returned no rows: select x from (select *, rownum as r from system_range(1, 3)) where r=2; - -@changelog_1091_li -Workaround for a java.sql.Date issue: years above 9999 are not formatted correctly. When calling ResultSet.getString() on a date value, an alternative formatting algorithm is used. - -@changelog_1092_li -Prepared statements with nested subqueries did not always return the correct result. Example: select ?, ?, (select count(*) from test t, (select id from test where 0=?) t2 where t2.id=t.id) from test - -@changelog_1093_li -When using MULTI_THREADED=TRUE, the exception following exception could be thrown: "object already exists: TABLES" - -@changelog_1094_li -Comparison of integer columns against float numbers was not always correct. Issue 182. - -@changelog_1095_li -H2 Console: Editing the result of a multi-line queries failed. Issue 183. - -@changelog_1096_li -H2 Console: if the settings file (.h2.properties) can't be accessed, the exception is now ignored. - -@changelog_1097_h2 -Version 1.2.132 (2010-03-21) - -@changelog_1098_li -The implementation of a Java to C (source code level) converter has been started. The plan is: it should be possible to convert H2 (or a part of it) to C so that the database can be run without a JVM. This will be a long term project (it may take a year or so). - -@changelog_1099_li -User defined table implementation can now be used using CREATE TABLE ... ENGINE. Thanks to Sergi Vladykin for implementing this feature! - -@changelog_1100_li -Improved MS SQL Server compatibility: support string concatenation using "+". Thanks to Stepan for the patch! - -@changelog_1101_li -When using the multi-threaded mode, running ANALYZE concurrently in multiple connections could throw an exception. - -@changelog_1102_li -The MERGE statement is now about 30% faster when using a PreparedStatement. - -@changelog_1103_li -Multi-column indexes where the second or later column was descending did not always produce correct results (rows were missing in the result set, or the result set was empty). - -@changelog_1104_li -When using large transactions or a small log size, the database could get very slow (profiling shows the hotspot is in FileObjectDisk.sync()). - -@changelog_1105_li -The Shell tool now prints the stack trace when the list mode is enabled. - -@changelog_1106_li -CREATE ALIAS ... AS: Compilation was incorrect if the source code contained characters that are not supported by the default file encoding. - -@changelog_1107_li -Issue 176: the JdbcDataSource now also supports a 'description' property. - -@changelog_1108_li -The Shell tool threw a ArrayIndexOutOfBoundsException after 20 statements. - -@changelog_1109_li -When using the small version of H2 ('jarClient'), the first call to Connection.createBlob (or similar) could throw a ClassNotFoundException because the file org.h2.store.fs.FileSystemZip is not included. This missing class is now ignored. - -@changelog_1110_li -Literals of type BIGINT now have the correct data type. - -@changelog_1111_h2 -Version 1.2.131 (2010-03-05) - -@changelog_1112_li -Older versions of H2 (version 1.2.127 and older) could not connect to a new version (version 1.2.129 and newer). The connection blocked when trying to connect. Now the connection no longer blocks, instead a SQL exception is thrown. - -@changelog_1113_li -In versions 1.2.129 and 1.2.130, a database could not be opened sometimes after dropping tables or indexes, and then creating new indexes for existing tables. The exception contained the text "parent not found" (version 1.2.129) or "Table not found" (version 1.2.130). - -@changelog_1114_li -After the database was closed, a null pointer exception could occur in Database.flush. - -@changelog_1115_li -An ArrayIndexOutOfBoundsException could occur in the page store (eg. on "delete from table"). Fixed. - -@changelog_1116_h2 -Version 1.2.130 (2010-02-26) - -@changelog_1117_li -EXPLAIN: The query plan now contains ".tableScan" if a table scan is used. - -@changelog_1118_li -IN(..): when combining and IN(..) condition with a condition that didn't use an index, the result could contain duplicate rows. - -@changelog_1119_li -IN(..): the index was not used if there were multiple IN(..) conditions. - -@changelog_1120_li -For foreign key constraints, the metadata column INFORMATION_SCHEMA.INDEXES.CONSTRAINT_NAME was not set for non-unique indexes. - -@changelog_1121_li -PostgreSQL compatibility: when using the following exception was thrown: Column "T.TYPTYPMOD" not found. Fixed. This is only when using psqlodbc_08_04*. - -@changelog_1122_li -A tool to migrate an old database from the non-page store format to the newest version has been added in src/tools/org/h2/dev/util/Migrate.java. This file is not included in the jar file currently. - -@changelog_1123_li -When using temporary tables, the database didn't shrink sometimes when closing. Also, sometimes a database could not recover normally. - -@changelog_1124_li -Large transactions could run out of heap space. The maximum size of a transaction is now much larger. - -@changelog_1125_li -The default setting for the system property h2.webMaxValueLength is now 100000 (it was 10000 before). - -@changelog_1126_li -Creating a database was delayed about 2 seconds if the directory didn't exist. - -@changelog_1127_li -Implemented INIT feature. If the database URL contains ";INIT=...;" then the DDL or DML commands following are executed on startup. Example URL: jdbc:h2:mem:test;INIT=RUNSCRIPT FROM '~/create.sql' (patch from Kerry Sainsbury). - -@changelog_1128_h2 -Version 1.2.129 (2010-02-19) - -@changelog_1129_li -The methods of the CloseListener are added to the Trigger interface. The interface CloseListener is removed. This is potentially a breaking change for existing triggers. - -@changelog_1130_li -CREATE ALIAS: error message when compiling Java code have been improved. - -@changelog_1131_li -MVCC: creating a table with an incorrect constraint could cause strange errors. - -@changelog_1132_li -Hash indexes now are only used for single column indexes. - -@changelog_1133_li -The cache types WEAK_* and TQ are no longer supported. A weak reference cache never frees up memory so it's the same as having a very large cache size. The TQ cache was not included in the jar file since a longer time, and was not tested. - -@changelog_1134_li -The file system abstraction no longer throws SQL exceptions. - -@changelog_1135_li -DatabaseEventListener.diskSpaceIsLow has changed. - -@changelog_1136_li -The CompressTool no longer throw as SQL exceptions. Instead, it throws runtime exceptions. - -@changelog_1137_li -SimpleResultSet.addColumn and addRow now can throw a IllegalStateException instead of a SQLException. - -@changelog_1138_li -When doing an index lookup, decimal values with the same value but different scale (for example 0.00 and 0.0) where not considered equal in version 1.2.128. Now they are (unlike BigDecimal.equals()). - -@changelog_1139_li -The BNF parser now uses the visitor pattern. - -@changelog_1140_li -Converting a UUID to bytes was incorrect. Because of that, updatable result sets on tables with UUID primary key did not work. - -@changelog_1141_li -The database URL property DATABASE_EVENT_LISTENER_OBJECT is no longer supported (there are problems passing objects when the PostgreSQL driver is installed as well). - -@changelog_1142_li -H2 Console: asynchronous login (using a DatabaseEventListener) is no longer supported. - -@changelog_1143_li -A workaround for a Windows socket problem has been implemented. Thanks a lot to Sergi Vladykin. - -@changelog_1144_li -The Recover tool did not convert correctly convert CLOB data with non-ASCII characters. - -@changelog_1145_li -Tools: the method run(String... args) has been renamed to runTool(String... args). - -@changelog_1146_li -Server.startWebServer(Connection) was not working as expected. - -@changelog_1147_li -The database URL option ACCESS_MODE_LOG is no longer supported. - -@changelog_1148_li -The database URL option RECOVER has currently no effect. - -@changelog_1149_li -Converting an old (non-page store) database is no longer supported using this version. - -@changelog_1150_li -The following system properties are no longer supported: h2.overflowExceptions, h2.optimizeDropDependencies, h2.optimizeGroupSorted, h2.optimizeMinMax, h2.optimizeNot, h2.optimizeIn, h2.optimizeInJoin, h2.reuseSpace*. Most of then were there for a long time, but always with the same value. There was no unit test with the other value. So changing them was potentially dangerous (not a lot, but still). - -@changelog_1151_li -The setting LOG has currently no effect (it only had an effect when the page store was disabled). - -@changelog_1152_li -Disabling the page store is no longer supported. The old storage mechanism has been removed, shrinking the jar file size by almost 10%. - -@changelog_1153_li -The translated resources are now stored in UTF-8 format. - -@changelog_1154_li -The Windows service wrapper now detects if multiple versions of H2 are installed. - -@changelog_1155_h2 -Version 1.2.128 (2010-01-30) - -@changelog_1156_li -There are known errors on rollback when the page store is disabled and at the same time MVCC is used. See http://code.google.com/p/h2database/issues/detail?id=158 - -@changelog_1157_li -The DeleteDbFiles tool deleted all files in the .lob.db directory, even files that didn't belong to the database. - -@changelog_1158_li -Automatic conversion of old databases to the page store format failed if the database contained LOB files. - -@changelog_1159_li -Nested subqueries didn't work for INSERT INTO and IN(..). Example: insert into test ((select 1)); - -@changelog_1160_li -If the database was already closed using SHUTDOWN IMMEDIATELY, closing a second connection could throw a NullPointerException if there was a local temporary table. - -@changelog_1161_li -Less classes are loaded when using the database in embedded mode. - -@changelog_1162_li -The information schema tables are only initialized when needed. This reduces memory usage and speeds up creating in-memory databases. Each in-memory database needs about 8 KB of heap memory. - -@changelog_1163_li -Nested UNION/INTERSECT queries with brackets could produce the wrong result if used within a subquery. Example: select count(*) from (select 1 union (select 2 intersect select 2)) x; - -@changelog_1164_li -Comparing an column against a constant expression with a higher precision or length than the column could give wrong results (the expression was truncated before comparing). - -@changelog_1165_li -Improved PostgreSQL compatibility (support SHOW DEFAULT_TRANSACTION_ISOLATION). - -@changelog_1166_li -Documentation: the javadocs for Csv.write and read used the wrong default charset. - -@changelog_1167_li -MVCC: if the table was locked in exclusive mode (such as SELECT ... FOR UPDATE), another session could query the table. This is now longer possible. - -@changelog_1168_li -If a FOR UPDATE query was executed twice (using a PreparedStatement), the table was not locked. - -@changelog_1169_li -Triggers: INSTEAD OF triggers are now supported. Such triggers can be defined on views. - -@changelog_1170_li -New system property h2.identifiersToUpper. If set to false, identifiers in SQL statements are case sensitive even if they are not quoted. - -@changelog_1171_li -Slightly improved performance if the table is already locked. - -@changelog_1172_li -CompressLZF: faster decompression. - -@changelog_1173_li -PgServer: the wrong size was sent for VARCHAR data. Thanks again to Sergi Vladykin for the patch. - -@changelog_1174_li -Serialized access mode (server-less multi-connection mode): fixed getGeneratedKeys() for sequences. - -@changelog_1175_h2 -Version 1.2.127 (2010-01-15) - -@changelog_1176_li -Serialized access mode (server-less multi-connection mode): sequences did not work as expected (there were gaps in generated values when using multiple connections). - -@changelog_1177_li -Page store: new databases can not be opened with older versions. - -@changelog_1178_li -Page store: adding data to new database is now faster. - -@changelog_1179_li -File system: getting the file name from a path is now faster. This should speed up BLOB and CLOB access. - -@changelog_1180_li -PgServer: incorrect SQL types were returned in result set meta data. Concurrently opening a database could fail (PG catalog initialization was not synchronized). Thanks a lot to Sergi Vladykin for providing the patches! - -@changelog_1181_li -SHOW COLUMNS did not work correctly if there where multiple indexes on the same columns. - -@changelog_1182_li -Page store: the wrong write count was written to the database header. This could cause the server-less multi-connection mode to fail. - -@changelog_1183_li -Result sets larger than 2 GB threw an exception "Negative seek offset". Fixed. - -@changelog_1184_li -If the system property h2.check was set to false, an ArrayIndexOutOfBoundsException could occur. - -@changelog_1185_li -Alter table is now supported even if a table has views defined. - -@changelog_1186_li -Fulltext search: exceptions within the fulltext search package had the wrong SQL state. - -@changelog_1187_li -The Lucene fulltext search ignored transaction rollback. Fixed using a trigger on rollback. - -@changelog_1188_li -Trigger can now be called on rollback. - -@changelog_1189_li -The shell script h2.sh ignored command line line arguments. - -@changelog_1190_li -When running H2 in the Google AppEngine for Java, a AccessControlException could be thrown when trying to open a read-only database. Fixed. - -@changelog_1191_li -The user home directory prefix (~) is now only expanded when followed by a slash or backslash, or standing alone. - -@changelog_1192_li -Native fulltext search: before inserting or deleting data, FT_INIT() had to be called. This is no longer required. - -@changelog_1193_li -The .trace.db file is now only created if required. - -@changelog_1194_li -Shell tool: improved PostgreSQL compatibility. - -@changelog_1195_li -Trying to open a database in read-only mode when a .lock.db file exists will now fail with a nice error message. - -@changelog_1196_li -H2 Console: data that is too long is now abbreviated as follows: text... (100000 characters). A large binary is abbreviated as follows: abcdef... (100000 bytes). - -@changelog_1197_li -Faster data conversion from BIGINT or INT to DECIMAL. - -@changelog_1198_li -Server-less multi-connection mode: try to delete log files if switching between read/write operations. - -@changelog_1199_li -CompressLZF: Faster decompress and improved javadocs - -@changelog_1200_h2 -Version 1.2.126 (2009-12-18) - -@changelog_1201_li -The ChangeFileEncryption tool will now fail with an exception if the database is still in use. The Backup tool will also fail except when running in quiet mode. - -@changelog_1202_li -CSVREAD: when reading the column names from the CSV file, column names that contain no special characters are considered case insensitive now. - -@changelog_1203_li -Optimization index conditions of the form 'column=NULL' (which is always false; unlike 'column IS NULL'). - -@changelog_1204_li -Script command and tool: the primary key constraint is now listed before inserting the data. This will result in a smaller database when using the page store. - -@changelog_1205_li -Statements with IN(SELECT..) conditions could produce the wrong result. Example: index on id, name; query: select * from test where id between 1 and 3 and name in (select 'World'). - -@changelog_1206_li -Statements with IN(..) conditions could produce the wrong result when using views or nested select statements. Example: index on id; index on name; query: select * from (select * from test) where id=1 and name in('a', 'b'). select * from (select * from test) where id=1 and name in('Hello', 'World'). - -@changelog_1207_li -Page store: a rollback of a relatively large transaction could fail with an ArrayIndexOutOfBoundsException or a 'row not found' exception in the PageBtreeIndex in some cases. - -@changelog_1208_li -JaQu: the decompiler has been improved, and a few test cases already work. It is still incomplete however. - -@changelog_1209_li -LIKE: any letter is now allowed after the escape character (which is still '\' by default). Previously, an exception was thrown (unlike other databases) if it was not the escape character, '_' or '%'. If the escape character appears at the end of the pattern, the result is it is ignored (like PostgreSQL and MS SQL Server). - -@changelog_1210_li -The reserve heap memory is no longer used. - -@changelog_1211_li -Database.checkpoint() could throw a NullPointerException. - -@changelog_1212_h2 -Version 1.2.125 (2009-12-06) - -@changelog_1213_li -Lucene fulltext search: the Lucene field names now match the table column names, except if the column names start with _ (in which case another _ is prepended). Unfortunately this change means existing fulltext indexes need to be re-built. - -@changelog_1214_li -The shell tool now has a very simple statement history. - -@changelog_1215_li -The zip file system implementation now supports the '~' home directory prefix. Example database URL: jdbc:h2:zip:~/test.zip!/test - -@changelog_1216_li -Right outer joins on tables that were already 'inner joined' was processed incorrectly. - -@changelog_1217_li -Temporary files from LOB objects were not deleted early enough when using the server mode. - -@changelog_1218_li -Trying to alter a temporary table threw a strange exception. It is still not possible to do that, but the exception message is better now. - -@changelog_1219_li -When the system property h2.maxMemoryRowsDistinct was set, and using SELECT DISTINCT, the temporary table was not correctly dropped. This could cause problems in recovery when the process was killed. - -@changelog_1220_li -Trigger that are called before a select statement are now supported. This allows to create tables that work like materialized views. - -@changelog_1221_li -Non-row based triggers were called even if the action didn't match the declared action (INSERT triggers were also called when deleting rows). This has been changed. The MERGE statement calls both INSERT and DELETE triggers. - -@changelog_1222_li -Statements with IN(..) conditions could produce the wrong result or a data conversion error (since version 1.2.120). Examples: index on id, name, condition: id=1 and name in('Hello', 'x'); index on id, query: select * from (select * from test) where id=1 and name in('Hello', 'World'). - -@changelog_1223_li -The CompressTool was not multithreading safe. Because of this, the following database operations where also not multithreading safe (even when using different databases): the SCRIPT command (only when using compression), the COMPRESS function, and storing CLOB or BLOB data (only when compression is enabled). - -@changelog_1224_li -The compression algorithm "LZF" is now about 33% faster than before when compressing small block (around 2 KB). It is much faster than Deflate, but the compression ratio is lower. Some of the optimizations are from Sam Van Oort, thanks a lot! - -@changelog_1225_li -Compressing large blocks of data didn't work when using the "Deflate" compression algorithm. Compressing a lot of data could run out of heap memory. - -@changelog_1226_li -The test cases don't access the file system directly, this simplifies GAE for Java testing. Thanks to Vince Bonfanti. - -@changelog_1227_li -More bugs in the server-less multi-connection mode have been fixed. - -@changelog_1228_li -When running against an old database, the SCRIPT statement could generate a SQL script that contained duplicate indexes (PRIMARY_KEY_E). - -@changelog_1229_li -JdbcConnectionPool.getConnection() could throw a NullPointerException. - -@changelog_1230_li -User defined functions: the source code is now available using SELECT SOURCE FROM INFORMATION_SCHEMA.FUNCTION_ALIASES. - -@changelog_1231_li -User defined functions with source code didn't work after re-opening the database. - -@changelog_1232_li -The newsfeeds are now Atom 1.0 standard compliant. - -@changelog_1233_li -The database is now closed after an out of memory exception, because the database could get corrupt otherwise. - -@changelog_1234_li -Better error message if both AUTO_SERVER and SERIALIZED parameters are set to TRUE. - -@changelog_1235_li -Drop table did not delete lob files in old file store (not PAGE_STORE). - -@changelog_1236_h2 -Version 1.2.124 (2009-11-20) - -@changelog_1237_li -Clustering: there is now a way to detect which cluster instances are running. - -@changelog_1238_li -ConvertTraceFile: the SQL statement statistics are better formatted (newline are removed). - -@changelog_1239_li -The file lock thread is now stopped when the database is closed. - -@changelog_1240_li -Issue 140: the Script tool now supports writing to a stream. - -@changelog_1241_li -Issue 138: the trace output of Statement.execute(String, int) and executeUpdate was incorrect. - -@changelog_1242_li -Page store: new databases can not be opened with older versions. - -@changelog_1243_li -Page store: multi-column indexes didn't work if the cache was very small. - -@changelog_1244_li -Page store: opening a database could theoretically result in an endless loop. - -@changelog_1245_li -Page store: adding large indexed columns could get very slow. - -@changelog_1246_li -Page store: after a duplicate key exception, an ArrayIndexOutOfBoundsException could be thrown (only for very large rows). - -@changelog_1247_li -Page store: the recover tool sometimes generated a script file that contained duplicate data. - -@changelog_1248_li -Page store: sometimes opening a read-only database failed. - -@changelog_1249_li -Page store: opening a database sometimes failed if large rows where updated, or if a table was truncated before. - -@changelog_1250_li -Page store: when using a very small page size (128 bytes or smaller), writing a large row could result in an endless recursion. This is only a theoretical problem, as the page size is 2 KB. - -@changelog_1251_li -Page store: getting the min value from a descending index with NULL entries could return the wrong result. - -@changelog_1252_li -Page store: improved auto-recovery after power failure. - -@changelog_1253_li -The JDBC client did not detect that it was not talking to an H2 server. This could result in strange exceptions when trying to connect to another kind of server. - -@changelog_1254_li -User defined functions can be created with source code. Example: CREATE ALIAS HI AS 'String hi() { return "Hello"; }' - -@changelog_1255_li -Database file lock: the exception "lock file modified in the future" is no longer thrown; instead, opening the file will be delayed by 2 seconds. - -@changelog_1256_li -Inserting LOBs got slower each time the process was restarted. It could loop endlessly after about 1000 process restarts. - -@changelog_1257_li -Issue 117: Multi-version concurrency: concurrent MERGE statements now work. - -@changelog_1258_li -Improved read-only database detection. - -@changelog_1259_h2 -Version 1.2.123 (2009-11-08) - -@changelog_1260_li -Page store: new databases can not be opened with older versions. - -@changelog_1261_li -Page store: updating large rows (rows with more than 2000 bytes of data) could corrupt the database. - -@changelog_1262_li -Page store: inserting very large rows failed with ArrayIndexOutOfBoundsException. - -@changelog_1263_li -When using multi-threaded kernel mode, setting disabling locking (LOCK_MODE=0) will now throw an exception. At this time this combination will result in corruption when multiple threads try to update the same table. - -@changelog_1264_li -The fulltext search methods and fields are now protected instead of private, to make the classes more easily extensible. - -@changelog_1265_li -The Lucene fulltext search now also returns the score. - -@changelog_1266_li - New function SCOPE_IDENTITY() to avoid problems when inserting rows in a trigger. - -@changelog_1267_li -Statement.getGeneratedKeys() returned the wrong value if a trigger changed the identity value after inserting the row. - -@changelog_1268_li -Improved error messages: identifiers and values are now quoted. - -@changelog_1269_li -Improved error message when casting a value failed: the column name and type is included in the message. - -@changelog_1270_li -Improved support for GAE for Java thanks to Vince Bonfanti. - -@changelog_1271_h2 -Version 1.2.122 (2009-10-28) - -@changelog_1272_li -The native fulltext search now supports streaming CLOB data. - -@changelog_1273_li -If the database URL ends with ;PAGE_STORE=TRUE and a database in the old format exists, it is automatically converted to the new page store format if possible. A backup of the database is created first. Automatic conversion is not supported if the database was not closed normally (if it contains uncommitted transactions). - -@changelog_1274_li -Dropping the current user is now allowed if another admin user exists. - -@changelog_1275_li -Values of type BINARY or BLOB could not be converted to the data type OTHER. - -@changelog_1276_li -SHUTDOWN COMPACT now fully compacts the database. - -@changelog_1277_li -New system properties h2.maxCompactCount and h2.maxCompactTime to allow changing the default behavior (at most 2 seconds compacting when closing the database). - -@changelog_1278_li -New sorted insert optimization (see Performance / Database Performance Tuning). - -@changelog_1279_li -Issue 116: The files h2*-sources.jar and h2*-javadoc.jar are now in the Maven repository. - -@changelog_1280_li -Page store: opening a large database was slow if it was not closed before. - -@changelog_1281_li -Page store: new write and read counters in the meta data table. Use SELECT * FROM INFORMATION_SCHEMA.SETTINGS WHERE NAME IN( 'info.FILE_WRITE_TOTAL', 'info.FILE_WRITE', 'info.FILE_READ', 'info.CACHE_MAX_SIZE', 'info.CACHE_SIZE') - -@changelog_1282_li -The SQL syntax is documented using (railroad) diagrams. The diagrams are HTML. - -@changelog_1283_li -The documentation is no longer available in Japanese because the translation was too much out of sync. Please use the Google translation instead. - -@changelog_1284_li -Certain queries were not sorted if subselect queries were involved - -@changelog_1285_li -More bugs in the server-less multi-connection mode have been fixed: 90097 The database is read only, caches must be cleared on reconnect, etc. - -@changelog_1286_h2 -Version 1.2.121 (2009-10-11) - -@changelog_1287_li -Better support GaeVFS (Google App Engine Virtual File System) thanks to Thanks to Vince Bonfanti. - -@changelog_1288_li -CSVREAD didn't close the file. Thanks to Vince Bonfanti for the patch! - -@changelog_1289_li -If a database in the old format exists, it is now used. The system property is used for new databases, or if databases exist in both formats. In any case, the flag in the URL overrides this logic. - -@changelog_1290_li -Page store bugs were fixed. Large values in indexed columns could corrupt the index. - -@changelog_1291_li -The page store did not work when using Retrotranslator (because the Retrotranslator doesn't support Integer.reverse and Long.reverse). - -@changelog_1292_li -New system property h2.pageStoreTrim to disable shrinking the database when closing (disabled by default, meaning by default the database is trimmed). - -@changelog_1293_h2 -Version 1.2.120 (2009-10-04) - -@changelog_1294_li -This is a beta version. - -@changelog_1295_li -Large updates could throw an ArrayIndexOutOfBoundsException in RowList.writeRow. - -@changelog_1296_li -In version 1.2, the following system properties are now enabled by default: h2.pageStore, h2.nullConcatIsNull, h2.optimizeInList. The default value for h2.defaultMaxLengthInplaceLob is now 4096 (it was 1024 with version 1.1). - -@changelog_1297_li -New databases are now stored in the new 'page store' file format. Existing databases are kept in the old file format. To use the old file format, append ;PAGE_STORE=FALSE to the database URL or set the system property h2.pageStore to false. - -@changelog_1298_li -Issue 125: Renaming primary keys was not persistent. Fixed. Unfortunately, databases created by this version can not be opened with older versions because of this change. - -@changelog_1299_li -Issue 124: Hibernate schema validation failed for decimal/numeric columns. This problem is fixed in the Hibernate dialect that is included with H2 (src/tools/org/hibernate/dialect/H2Dialect.java.txt), but not in Hibernate yet. - -@changelog_1300_li -PostgreSQL compatibility: function LASTVAL() as an alias for IDENTITY(). - -@changelog_1301_li -Linked tables now support default values when inserting, updating or merging. - -@changelog_1302_li -Bugfixes in the page store. - -@changelog_1303_li -Possibility to set a vendor id in Constants.java, so that unofficial builds are distinguishable from official releases. - -@changelog_1304_li -Allow writing to linked tables in readonly databases. - -@changelog_1305_h2 -Version 1.1.119 (2009-09-26) - -@changelog_1306_li -SQL statements in the exception message are no longer included if they contain '--hide--'. - -@changelog_1307_li -Temporary local tables did not always work after reconnect if AUTO_SERVER=TRUE - -@changelog_1308_li -New system property h2.defaultMaxLengthInplaceLob to change the default maximum size of an in-place LOB object. - -@changelog_1309_li -New system property h2.nullConcatIsNull to change the default null concatenation behavior. The default will be enabled in version 1.2. - -@changelog_1310_li -The cache algorithm TQ is disabled in this version, because it is unstable, and because the current implementation does not have any measurable advantages over the default. - -@changelog_1311_li -New committer: Christian Peter. He works for Docware and helped a lot finding and fixing bugs, and generally improving the database. He is now a committer. - -@changelog_1312_li -ChangeFileEncryption did not work with Lob subdirectories. Fixed. - -@changelog_1313_li -Issue 121: JaQu: new simple update and merge methods. - -@changelog_1314_li -Issue 120: JaQu didn't close result sets. - -@changelog_1315_li -Issue 119: JaQu creates wrong WHERE conditions on some inputs. - -@changelog_1316_li -The new page store mechanism is now alpha-level quality. The next release will most likely be "1.2.120 beta" where this mode is enabled by default. To use it right now, append ;PAGE_STORE=TRUE to the database URL. The file format of this mode will probably not change any more. - -@changelog_1317_li -SELECT COUNT(*) FROM SYSTEM_RANGE(...) returned the wrong result. Fixed. - -@changelog_1318_li -The Recover tool now also processes the log files, however applying those changes is still a manual process. - -@changelog_1319_li -New sample application that shows how to pass data to a trigger. - -@changelog_1320_li -More bugs in the server-less multi-connection mode have been fixed: On Windows, two processes could write to the same database at the same time. - -@changelog_1321_li -When loading triggers or other client classes (static functions, database event listener, user aggregate functions, other JDBC drivers), the database now uses the context class loader if the class could not be found using Class.forName(). - -@changelog_1322_li -Updating many rows with the same CLOB or BLOB values could result in FileNotFoundException. - -@changelog_1323_li -Statement.getConnection() threw an exception if the connection was already closed. - -@changelog_1324_li -The native fulltext index kept a reference to a database after the database was closed. - -@changelog_1325_li -Non-unique in-memory hash indexes are now supported. Thanks a lot to Sergi Vladykin for the patch! - -@changelog_1326_li -The optimizer does a better job for joins if indexes are missing. - -@changelog_1327_h2 -Version 1.1.118 (2009-09-04) - -@changelog_1328_li -SHOW COLUMNS only listed indexed columns. - -@changelog_1329_li -When calling SHUTDOWN IMMEDIATELY in the server mode, the .trace.db file was not closed. - -@changelog_1330_li -DatabaseMetaData.getPrimaryKeys: the wrong constraint name was reported if there was another constraint on the same table and columns. - -@changelog_1331_li -AUTO_INCREMENT now works in the same way in ALTER TABLE ALTER COLUMN as in CREATE TABLE (it does not create a primary key). - -@changelog_1332_li -Native fulltext search: before searching, FT_INIT() had to be called. This is no longer required. - -@changelog_1333_li -Better support GaeVFS (Google App Engine Virtual File System). - -@changelog_1334_li -JaQu: the plan is to support natural (pure Java / Scala) conditions such as (id == 1 && name.equals("Test")). A proof of concept decompiler is now included (it doesn't work yet). - -@changelog_1335_li -Various bugfixes and improvements in the page store mechanism (still experimental). - -@changelog_1336_li -PreparedStatement.setObject now converts a java.lang.Character to a string. - -@changelog_1337_li -H2 Console: PierPaolo Ucchino has completed the Italian translation. Thanks a lot! - -@changelog_1338_li -Various tools now use Java 5 var-args, such as main the methods and SimpleResultSet.addRow. - -@changelog_1339_li -H2 Console: indexes of tables of non-default schemas are now also listed. - -@changelog_1340_li -Issue 111: Multi-version concurrency / duplicate primary key after rollback. - -@changelog_1341_li -Issue 110: Multi-version concurrency / wrong exception is thrown. - -@changelog_1342_li -Parser: sequenceName.NEXTVAL and CURRVAL did not respect the schema search path. - -@changelog_1343_li -Issue 101: The following sequence could throw the exception "Row not found when trying to delete": start a transaction, insert many rows, delete many rows, rollback. The number of rows depends on the cache size. - -@changelog_1344_li -The stack trace of very common exceptions is no longer written to the .trace.db file by default. - -@changelog_1345_li -An optimization for OR is implemented, but disabled by default. Expressions of the type X=1 OR X=2 are converted to X IN(1, 2). To enable, set the system property h2.optimizeInList to true before loading the H2 JDBC driver. - -@changelog_1346_li -An optimization for IN(..) and IN(SELECT...) is implemented, but disabled by default. To enable, set the system property h2.optimizeInList to true before loading the H2 JDBC driver. If enabled, this overrides h2.optimizeIn and h2.optimizeInJoin. Unlike now, this optimization will also speed up updates and deletes. - -@changelog_1347_h2 -Version 1.1.117 (2009-08-09) - -@changelog_1348_li -New committer: Sam Van Oort has been contributing to H2 since quite some time in many ways (on the mailing list, documentation, and in the form of patches). He is now a committer. - -@changelog_1349_li -JaQu: the order of the fields in the database no longer needs to match the order in the database. - -@changelog_1350_li -Issue 103: MVCC: the setting MAX_MEMORY_UNDO can currently not be supported when using multi-version concurrency, that means the complete undo log must fit in memory. - -@changelog_1351_li -LIKE: the escape mechanism can now be disable using ESCAPE ''. The default escape character can be changed using the system property h2.defaultEscape. The default is still '\' (as in MySQL and PostgreSQL). - -@changelog_1352_li -Views using functions were not re-evaluated when necessary. - -@changelog_1353_li -Improved MySQL compatibility for SHOW COLUMNS. - -@changelog_1354_li -Improved PostgreSQL compatibility for timestamp literals with timezone. - -@changelog_1355_li -Sergi Vladykin translated the error messages to Russian. Thanks a lot! - -@changelog_1356_li -Support for Java 6 DatabaseMetaData.getTables, getColumns, getProcedures, and getProcedureColumns. - -@changelog_1357_li -Issue 101: Rollback of a large transaction (more than 100000 rows) could fail. - -@changelog_1358_li -Various bugfixes and improvements in the page store mechanism (still experimental). - -@changelog_1359_li -The functions LENGTH, OCTET_LENGTH, and BIT_LENGTH now return BIGINT. - -@changelog_1360_li -Data types CLOB and BLOB: the maximum precision was Integer.MAX_VALUE, it is now Long.MAX_VALUE. - -@changelog_1361_li -Multi-threaded kernel: creating and dropping temporary database objects and the potentially free pages list was not correctly synchronized. Thanks a lot to Eric Faulhaber for the test case and patch! - -@changelog_1362_li -Parsing SQL script files is now faster. - -@changelog_1363_li -CSV reading is now faster. - -@changelog_1364_li -SimpleResultSet.newInstance(SimpleRowSource rs) did not work. - -@changelog_1365_h2 -Version 1.1.116 (2009-07-18) - -@changelog_1366_li -Server-less multi-connection mode: more bugs are fixed. - -@changelog_1367_li -The built-in help (INFORMATION_SCHEMA.HELP) is smaller, shrinking the jar file size a bit. - -@changelog_1368_li -H2 Console: column of tables of non-default schemas are now also listed, except for schemas starting with 'INFO'. - -@changelog_1369_li -ALTER TABLE: removing an auto-increment or identity column didn't remove the sequence. - -@changelog_1370_li -Creating indexes is now a bit faster. - -@changelog_1371_li -PG Server: new system property h2.pgClientEncoding to explicitly set the encoding for clients that don't send the encoding (the default encoding is UTF-8). Thanks a lot to Sergi Vladykin for the patch! - -@changelog_1372_li -PG Server: improved compatibility by using the type ids of the PostgreSQL driver. Thanks a lot to Sergi Vladykin for the patch! - -@changelog_1373_li -H2 Console: Oracle system tables are no longer listed, improving performance. - -@changelog_1374_li -Result sets are now read-only except if the statement or prepared statement was created with the concurrency ResultSet.CONCUR_UPDATABLE. This change is required because the old behavior (all result set are updatable) violated the JDBC spec. For backward compatibility, use the system property h2.defaultResultSetConcurrency. - -@changelog_1375_li -New system property h2.defaultResultSetConcurrency to change the default result set concurrency. - -@changelog_1376_li -JDBC: using an invalid result set type or concurrency now throws an exception. - -@changelog_1377_li -If a pooled connection was not closed but garbage collected, a NullPointerException could occur. - -@changelog_1378_li -Fulltext search: a NullPointerException was thrown when updating a value that was NULL previously. - -@changelog_1379_li -The Recover tool did not work with .data.db files of the wrong size. - -@changelog_1380_li -Triggers: if there was an exception when initializing a trigger, this exception could be hidden, and in some cases (specially when using the Lucene fulltext index mechanism) a NullPointerException was thrown later on. Now the exception that occurred on init is thrown when changing data. - -@changelog_1381_li -The soft-references cache (CACHE_TYPE=SOFT_LRU) could throw a NullPointerException. - -@changelog_1382_li -To enable the new page store mechanism, append ;PAGE_STORE=TRUE to the database URL. or set the system property h2.pageStore to true. This mechanism is still experimental, and the file format will change, but it is quite stable now. - -@cheatSheet_1000_h1 -H2 Database Engine Cheat Sheet - -@cheatSheet_1001_h2 -Using H2 - -@cheatSheet_1002_a -H2 - -@cheatSheet_1003_li - is open source, free to use and distribute. - -@cheatSheet_1004_a -Download - -@cheatSheet_1005_li -: jar, installer (Windows), zip. - -@cheatSheet_1006_li -To start the H2 Console tool, double click the jar file, or run java -jar h2*.jar, h2.bat, or h2.sh. - -@cheatSheet_1007_a -A new database is automatically created - -@cheatSheet_1008_a -by default - -@cheatSheet_1009_li -. - -@cheatSheet_1010_a -Closing the last connection closes the database - -@cheatSheet_1011_li -. - -@cheatSheet_1012_h2 -Documentation - -@cheatSheet_1013_p - Reference: SQL grammar, functions, data types, tools, API - -@cheatSheet_1014_a -Features - -@cheatSheet_1015_p -: fulltext search, encryption, read-only (zip/jar), CSV, auto-reconnect, triggers, user functions - -@cheatSheet_1016_a -Database URLs - -@cheatSheet_1017_a -Embedded - -@cheatSheet_1018_code -jdbc:h2:~/test - -@cheatSheet_1019_p - 'test' in the user home directory - -@cheatSheet_1020_code -jdbc:h2:/data/test - -@cheatSheet_1021_p - 'test' in the directory /data - -@cheatSheet_1022_code -jdbc:h2:test - -@cheatSheet_1023_p - in the current(!) working directory - -@cheatSheet_1024_a -In-Memory - -@cheatSheet_1025_code -jdbc:h2:mem:test - -@cheatSheet_1026_p - multiple connections in one process - -@cheatSheet_1027_code -jdbc:h2:mem: - -@cheatSheet_1028_p - unnamed private; one connection - -@cheatSheet_1029_a -Server Mode - -@cheatSheet_1030_code -jdbc:h2:tcp://localhost/~/test - -@cheatSheet_1031_p - user home dir - -@cheatSheet_1032_code -jdbc:h2:tcp://localhost//data/test - -@cheatSheet_1033_p - absolute dir - -@cheatSheet_1034_a -Server start - -@cheatSheet_1035_p -:java -cp *.jar org.h2.tools.Server - -@cheatSheet_1036_a -Settings - -@cheatSheet_1037_code -jdbc:h2:..;MODE=MySQL - -@cheatSheet_1038_a -compatibility (or HSQLDB,...) - -@cheatSheet_1039_code -jdbc:h2:..;TRACE_LEVEL_FILE=3 - -@cheatSheet_1040_a -log to *.trace.db - -@cheatSheet_1041_a -Using the JDBC API - -@cheatSheet_1042_a -Connection Pool - -@cheatSheet_1043_a -Maven 2 - -@cheatSheet_1044_a -Hibernate - -@cheatSheet_1045_p - hibernate.cfg.xml (or use the HSQLDialect): - -@cheatSheet_1046_a -TopLink and Glassfish - -@cheatSheet_1047_p - Datasource class: org.h2.jdbcx.JdbcDataSource - -@cheatSheet_1048_code -oracle.toplink.essentials.platform. - -@cheatSheet_1049_code -database.H2Platform - -@download_1000_h1 -Downloads - -@download_1001_h3 -Version 1.2.137 (2010-06-06) - -@download_1002_a -Windows Installer - -@download_1003_a -Platform-Independent Zip - -@download_1004_h3 -Version 1.2.136 (2010-05-24, Last Stable) - -@download_1005_a -Windows Installer - -@download_1006_a -Platform-Independent Zip - -@download_1007_h3 -Download Mirror and Older Versions - -@download_1008_a -Platform-Independent Zip - -@download_1009_h3 -Jar File - -@download_1010_a -Maven.org - -@download_1011_a -Sourceforge.net - -@download_1012_a -Latest Automated Build (not released) - -@download_1013_h3 -Subversion Source Repository - -@download_1014_a -Google Code - -@download_1015_p - For details about changes, see the Change Log. - -@download_1016_h3 -News and Project Information - -@download_1017_a -Atom Feed - -@download_1018_a -RSS Feed - -@download_1019_a -DOAP File - -@download_1020_p - (what is this) - -@faq_1000_h1 -Frequently Asked Questions - -@faq_1001_a - I Have a Problem or Feature Request - -@faq_1002_a - Are there Known Bugs? When is the Next Release? - -@faq_1003_a - Is this Database Engine Open Source? - -@faq_1004_a - My Query is Slow - -@faq_1005_a - How to Create a New Database? - -@faq_1006_a - How to Connect to a Database? - -@faq_1007_a - Where are the Database Files Stored? - -@faq_1008_a - What is the Size Limit (Maximum Size) of a Database? - -@faq_1009_a - Is it Reliable? - -@faq_1010_a - Why is Opening my Database Slow? - -@faq_1011_a - Column Names are Incorrect? - -@faq_1012_a - Float is Double? - -@faq_1013_a - Is the GCJ Version Stable? Faster? - -@faq_1014_a - How to Translate this Project? - -@faq_1015_h3 -I Have a Problem or Feature Request - -@faq_1016_p - Please read the support checklist. - -@faq_1017_h3 -Are there Known Bugs? When is the Next Release? - -@faq_1018_p - Usually, bugs get fixes as they are found. There is a release every few weeks. Here is the list of known and confirmed issues: - -@faq_1019_li -Apache Harmony: there seems to be a bug in Harmony that affects H2. See HARMONY-6505. - -@faq_1020_li -Tomcat and Glassfish 3 set most static fields (final or non-final) to null when unloading a web application. This can cause a NullPointerException in H2 versions 1.1.107 and older, and may still not work in newer versions. Please report it if you run into this issue. In Tomcat >= 6.0 this behavior can be disabled by setting the system property org.apache.catalina.loader.WebappClassLoader.ENABLE_CLEAR_REFERENCES=false, however Tomcat may then run out of memory. A known workaround is to put the h2*.jar file in a shared lib directory (common/lib). - -@faq_1021_li -Some problems have been found with right outer join. Internally, it is converted to left outer join, which does not always produce the same results as other databases when used in combination with other joins. - -@faq_1022_li -When using Install4j before 4.1.4 on Linux and enabling pack200, the h2*.jar becomes corrupted by the install process, causing application failure. A workaround is to add an empty file h2*.jar.nopack next to the h2*.jar file. This problem is solved in Install4j 4.1.4. - -@faq_1023_p - For a complete list, see Open Issues. - -@faq_1024_h3 -Is this Database Engine Open Source? - -@faq_1025_p - Yes. It is free to use and distribute, and the source code is included. See also under license. - -@faq_1026_h3 -My Query is Slow - -@faq_1027_p - Slow SELECT (or DELETE, UPDATE, MERGE) statement can have multiple reasons. Follow this checklist: - -@faq_1028_li -Run ANALYZE (see documentation for details). - -@faq_1029_li -Run the query with EXPLAIN and check if indexes are used (see documentation for details). - -@faq_1030_li -If required, create additional indexes and try again using ANALYZE and EXPLAIN. - -@faq_1031_li -If it doesn't help please report the problem. - -@faq_1032_h3 -How to Create a New Database? - -@faq_1033_p - By default, a new database is automatically created if it does not yet exist. See Creating New Databases. - -@faq_1034_h3 -How to Connect to a Database? - -@faq_1035_p - The database driver is org.h2.Driver, and the database URL starts with jdbc:h2:. To connect to a database using JDBC, use the following code: - -@faq_1036_h3 -Where are the Database Files Stored? - -@faq_1037_p - When using database URLs like jdbc:h2:~/test, the database is stored in the user directory. For Windows, this is usually C:\Documents and Settings\<userName>. If the base directory is not set (as in jdbc:h2:test), the database files are stored in the directory where the application is started (the current working directory). When using the H2 Console application from the start menu, this is <Installation Directory>/bin. The base directory can be set in the database URL. A fixed or relative path can be used. When using the URL jdbc:h2:file:data/sample, the database is stored in the directory data (relative to the current working directory). The directory is created automatically if it does not yet exist. It is also possible to use the fully qualified directory name (and for Windows, drive name). Example: jdbc:h2:file:C:/data/test - -@faq_1038_h3 -What is the Size Limit (Maximum Size) of a Database? - -@faq_1039_p - See Limits and Limitations. - -@faq_1040_h3 -Is it Reliable? - -@faq_1041_p - That is not easy to say. It is still a quite new product. A lot of tests have been written, and the code coverage of these tests is very high. Randomized stress tests are run regularly. But there are probably still bugs that have not yet been found (as with most software). Some features are known to be dangerous, they are only supported for situations where performance is more important than reliability. Those dangerous features are: - -@faq_1042_li -Using the transaction isolation level READ_UNCOMMITTED (LOCK_MODE 0) while at the same time using multiple connections. - -@faq_1043_li -Disabling database file protection using (setting FILE_LOCK to NO in the database URL). - -@faq_1044_li -Disabling referential integrity using SET REFERENTIAL_INTEGRITY FALSE. - -@faq_1045_p - In addition to that, running out of memory should be avoided. In older versions, OutOfMemory errors while using the database could corrupt a databases. - -@faq_1046_p - Some areas of this database are not fully tested. When using one of those features for production, please ensure your use case is well tested (if possible with automated test cases). Those areas are: - -@faq_1047_li -Platforms other than Windows XP, Linux, Mac OS X, or JVMs other than Sun 1.5 or 1.6 - -@faq_1048_li -The feature MULTI_THREADED - -@faq_1049_li -The features AUTO_SERVER and AUTO_RECONNECT - -@faq_1050_li -The file locking method 'Serialized' - -@faq_1051_li -The MVCC (multi version concurrency) mode - -@faq_1052_li -Cluster mode, 2-phase commit, savepoints - -@faq_1053_li -24/7 operation - -@faq_1054_li -Some operations on databases larger than 500 MB may be slower than expected - -@faq_1055_li -The optimizer may not always select the best plan - -@faq_1056_li -Fulltext search - -@faq_1057_li -Operations on LOBs over 2 GB - -@faq_1058_p - Areas considered experimental are: - -@faq_1059_li -The PostgreSQL server - -@faq_1060_li -Multi-threading within the engine using SET MULTI_THREADED=1 - -@faq_1061_li -Compatibility modes for other databases (only some features are implemented) - -@faq_1062_li -The soft reference cache (CACHE_TYPE=SOFT_LRU). It might not improve performance, and out of memory issues have been reported. - -@faq_1063_p - Some users have reported that after a power failure, the database cannot be opened sometimes. In this case, use a backup of the database or the Recover tool. Please report such problems. The plan is that the database automatically recovers in all situations. - -@faq_1064_h3 -Column Names are Incorrect? - -@faq_1065_p - For the query SELECT ID AS X FROM TEST the method ResultSetMetaData.getColumnName() returns ID, I expect it to return X. What's wrong? - -@faq_1066_p - This is not a bug. According the the JDBC specification, the method ResultSetMetaData.getColumnName() should return the name of the column and not the alias name. If you need the alias name, use ResultSetMetaData.getColumnLabel(). Some other database don't work like this yet (they don't follow the JDBC specification). If you need compatibility with those databases, use the Compatibility Mode, or set the system property h2.aliasColumnName. - -@faq_1067_p - This also applies to DatabaseMetaData calls that return a result set. The columns in the JDBC API are column labels, not column names. - -@faq_1068_h3 -Float is Double? - -@faq_1069_p - For a table defined as CREATE TABLE TEST(X FLOAT) the method ResultSet.getObject() returns a java.lang.Double, I expect it to return a java.lang.Float. What's wrong? - -@faq_1070_p - This is not a bug. According the the JDBC specification, the JDBC data type FLOAT is equivalent to DOUBLE, and both are mapped to java.lang.Double. See also Mapping SQL and Java Types - 8.3.10 FLOAT. - -@faq_1071_h3 -Why is Opening my Database Slow? - -@faq_1072_p - To find out what the problem is, use the H2 Console and click on "Test Connection" instead of "Login". After the "Login Successful" appears, click on it (it's a link). This will list the top stack traces. Then either analyze this yourself, or post those stack traces in the Google Group. - -@faq_1073_p - To find out what the problem is, open the database in embedded mode using the H2 Console. This will print progress information. If you have many lines with 'Creating index' it is an indication that the database was not closed the last time. - -@faq_1074_p - Other possible reasons are: the database is very big (many GB), or contains linked tables that are slow to open. - -@faq_1075_h3 -Is the GCJ Version Stable? Faster? - -@faq_1076_p - The GCJ version is not as stable as the Java version. When running the regression test with the GCJ version, sometimes the application just stops at what seems to be a random point without error message. Currently, the GCJ version is also slower than when using the Sun VM. However, the startup of the GCJ version is faster than when using a VM. - -@faq_1077_h3 -How to Translate this Project? - -@faq_1078_p - For more information, see Build/Translating. - -@features_1000_h1 -Features - -@features_1001_a - Feature List - -@features_1002_a - Comparison to Other Database Engines - -@features_1003_a - H2 in Use - -@features_1004_a - Connection Modes - -@features_1005_a - Database URL Overview - -@features_1006_a - Connecting to an Embedded (Local) Database - -@features_1007_a - In-Memory Databases - -@features_1008_a - Database Files Encryption - -@features_1009_a - Database File Locking - -@features_1010_a - Opening a Database Only if it Already Exists - -@features_1011_a - Closing a Database - -@features_1012_a - Ignore Unknown Settings - -@features_1013_a - Changing Other Settings when Opening a Connection - -@features_1014_a - Custom File Access Mode - -@features_1015_a - Multiple Connections - -@features_1016_a - Database File Layout - -@features_1017_a - Logging and Recovery - -@features_1018_a - Compatibility - -@features_1019_a - Auto-Reconnect - -@features_1020_a - Automatic Mixed Mode - -@features_1021_a - Page Size - -@features_1022_a - Using the Trace Options - -@features_1023_a - Using Other Logging APIs - -@features_1024_a - Read Only Databases - -@features_1025_a - Read Only Databases in Zip or Jar File - -@features_1026_a - Graceful Handling of Low Disk Space Situations - -@features_1027_a - Computed Columns / Function Based Index - -@features_1028_a - Multi-Dimensional Indexes - -@features_1029_a - Using Passwords - -@features_1030_a - User-Defined Functions and Stored Procedures - -@features_1031_a - Triggers - -@features_1032_a - Compacting a Database - -@features_1033_a - Cache Settings - -@features_1034_h2 -Feature List - -@features_1035_h3 -Main Features - -@features_1036_li -Very fast database engine - -@features_1037_li -Open source - -@features_1038_li -Written in Java - -@features_1039_li -Supports standard SQL, JDBC API - -@features_1040_li -Embedded and Server mode, Clustering support - -@features_1041_li -Strong security features - -@features_1042_li -The PostgreSQL ODBC driver can be used - -@features_1043_li -Multi version concurrency - -@features_1044_h3 -Additional Features - -@features_1045_li -Disk based or in-memory databases and tables, read-only database support, temporary tables - -@features_1046_li -Transaction support (read committed and serializable transaction isolation), 2-phase-commit - -@features_1047_li -Multiple connections, table level locking - -@features_1048_li -Cost based optimizer, using a genetic algorithm for complex queries, zero-administration - -@features_1049_li -Scrollable and updatable result set support, large result set, external result sorting, functions can return a result set - -@features_1050_li -Encrypted database (AES or XTEA), SHA-256 password encryption, encryption functions, SSL - -@features_1051_h3 -SQL Support - -@features_1052_li -Support for multiple schemas, information schema - -@features_1053_li -Referential integrity / foreign key constraints with cascade, check constraints - -@features_1054_li -Inner and outer joins, subqueries, read only views and inline views - -@features_1055_li -Triggers and Java functions / stored procedures - -@features_1056_li -Many built-in functions, including XML and lossless data compression - -@features_1057_li -Wide range of data types including large objects (BLOB/CLOB) and arrays - -@features_1058_li -Sequence and autoincrement columns, computed columns (can be used for function based indexes) - -@features_1059_code -ORDER BY, GROUP BY, HAVING, UNION, LIMIT, TOP - -@features_1060_li -Collation support, users, roles - -@features_1061_li -Compatibility modes for IBM DB2, Apache Derby, HSQLDB, MS SQL Server, MySQL, Oracle, and PostgreSQL. - -@features_1062_h3 -Security Features - -@features_1063_li -Includes a solution for the SQL injection problem - -@features_1064_li -User password authentication uses SHA-256 and salt - -@features_1065_li -For server mode connections, user passwords are never transmitted in plain text over the network (even when using insecure connections; this only applies to the TCP server and not to the H2 Console however; it also doesn't apply if you set the password in the database URL) - -@features_1066_li -All database files (including script files that can be used to backup data) can be encrypted using AES-128 and XTEA encryption algorithms - -@features_1067_li -The remote JDBC driver supports TCP/IP connections over SSL/TLS - -@features_1068_li -The built-in web server supports connections over SSL/TLS - -@features_1069_li -Passwords can be sent to the database using char arrays instead of Strings - -@features_1070_h3 -Other Features and Tools - -@features_1071_li -Small footprint (smaller than 1 MB), low memory requirements - -@features_1072_li -Multiple index types (b-tree, tree, hash) - -@features_1073_li -Support for multi-dimensional indexes - -@features_1074_li -CSV (comma separated values) file support - -@features_1075_li -Support for linked tables, and a built-in virtual 'range' table - -@features_1076_code -EXPLAIN PLAN - -@features_1077_li - support, sophisticated trace options - -@features_1078_li -Database closing can be delayed or disabled to improve the performance - -@features_1079_li -Web-based Console application (translated to many languages) with autocomplete - -@features_1080_li -The database can generate SQL script files - -@features_1081_li -Contains a recovery tool that can dump the contents of the database - -@features_1082_li -Support for variables (for example to calculate running totals) - -@features_1083_li -Automatic re-compilation of prepared statements - -@features_1084_li -Uses a small number of database files - -@features_1085_li -Uses a checksum for each record and log entry for data integrity - -@features_1086_li -Well tested (high code coverage, randomized stress tests) - -@features_1087_h2 -Comparison to Other Database Engines - -@features_1088_th -Feature - -@features_1089_th -H2 - -@features_1090_a -Derby - -@features_1091_a -HSQLDB - -@features_1092_a -MySQL - -@features_1093_a -PostgreSQL - -@features_1094_td -Pure Java - -@features_1095_td -Yes - -@features_1096_td -Yes - -@features_1097_td -Yes - -@features_1098_td -No - -@features_1099_td -No - -@features_1100_td -Embedded Mode (Java) - -@features_1101_td -Yes - -@features_1102_td -Yes - -@features_1103_td -Yes - -@features_1104_td -No - -@features_1105_td -No - -@features_1106_td -Performance (Embedded) - -@features_1107_td -Fast - -@features_1108_td -Slow - -@features_1109_td -Fast - -@features_1110_td -N/A - -@features_1111_td -N/A - -@features_1112_td -In-Memory Mode - -@features_1113_td -Yes - -@features_1114_td -Yes - -@features_1115_td -Yes - -@features_1116_td -No - -@features_1117_td -No - -@features_1118_td -Transaction Isolation - -@features_1119_td -Yes - -@features_1120_td -Yes - -@features_1121_td -No - -@features_1122_td -Yes - -@features_1123_td -Yes - -@features_1124_td -Cost Based Optimizer - -@features_1125_td -Yes - -@features_1126_td -Yes - -@features_1127_td -No - -@features_1128_td -Yes - -@features_1129_td -Yes - -@features_1130_td -Explain Plan - -@features_1131_td -Yes - -@features_1132_td -No - -@features_1133_td -Yes - -@features_1134_td -Yes - -@features_1135_td -Yes - -@features_1136_td -Clustering - -@features_1137_td -Yes - -@features_1138_td -No - -@features_1139_td -No - -@features_1140_td -Yes - -@features_1141_td -Yes - -@features_1142_td -Encrypted Database - -@features_1143_td -Yes - -@features_1144_td -Yes - -@features_1145_td -No - -@features_1146_td -No - -@features_1147_td -No - -@features_1148_td -Linked Tables - -@features_1149_td -Yes - -@features_1150_td -No - -@features_1151_td -Partially *1 - -@features_1152_td -Partially *2 - -@features_1153_td -No - -@features_1154_td -ODBC Driver - -@features_1155_td -Yes - -@features_1156_td -No - -@features_1157_td -No - -@features_1158_td -Yes - -@features_1159_td -Yes - -@features_1160_td -Fulltext Search - -@features_1161_td -Yes - -@features_1162_td -No - -@features_1163_td -No - -@features_1164_td -Yes - -@features_1165_td -Yes - -@features_1166_td -User-Defined Datatypes - -@features_1167_td -Yes - -@features_1168_td -No - -@features_1169_td -No - -@features_1170_td -Yes - -@features_1171_td -Yes - -@features_1172_td -Files per Database - -@features_1173_td -Few - -@features_1174_td -Many - -@features_1175_td -Few - -@features_1176_td -Many - -@features_1177_td -Many - -@features_1178_td -Table Level Locking - -@features_1179_td -Yes - -@features_1180_td -Yes - -@features_1181_td -No - -@features_1182_td -Yes - -@features_1183_td -Yes - -@features_1184_td -Row Level Locking - -@features_1185_td -Yes *9 - -@features_1186_td -Yes - -@features_1187_td -No - -@features_1188_td -Yes - -@features_1189_td -Yes - -@features_1190_td -Multi Version Concurrency - -@features_1191_td -Yes - -@features_1192_td -No - -@features_1193_td -No - -@features_1194_td -Yes - -@features_1195_td -Yes - -@features_1196_td -Role Based Security - -@features_1197_td -Yes - -@features_1198_td -Yes *3 - -@features_1199_td -Yes - -@features_1200_td -Yes - -@features_1201_td -Yes - -@features_1202_td -Updatable Result Sets - -@features_1203_td -Yes - -@features_1204_td -Yes *7 - -@features_1205_td -No - -@features_1206_td -Yes - -@features_1207_td -Yes - -@features_1208_td -Sequences - -@features_1209_td -Yes - -@features_1210_td -No - -@features_1211_td -Yes - -@features_1212_td -No - -@features_1213_td -Yes - -@features_1214_td -Limit and Offset - -@features_1215_td -Yes - -@features_1216_td -No - -@features_1217_td -Yes - -@features_1218_td -Yes - -@features_1219_td -Yes - -@features_1220_td -Temporary Tables - -@features_1221_td -Yes - -@features_1222_td -Yes *4 - -@features_1223_td -Yes - -@features_1224_td -Yes - -@features_1225_td -Yes - -@features_1226_td -Information Schema - -@features_1227_td -Yes - -@features_1228_td -No *8 - -@features_1229_td -No *8 - -@features_1230_td -Yes - -@features_1231_td -Yes - -@features_1232_td -Computed Columns - -@features_1233_td -Yes - -@features_1234_td -No - -@features_1235_td -No - -@features_1236_td -No - -@features_1237_td -Yes *6 - -@features_1238_td -Case Insensitive Columns - -@features_1239_td -Yes - -@features_1240_td -No - -@features_1241_td -Yes - -@features_1242_td -Yes - -@features_1243_td -Yes *6 - -@features_1244_td -Custom Aggregate Functions - -@features_1245_td -Yes - -@features_1246_td -No - -@features_1247_td -No - -@features_1248_td -Yes - -@features_1249_td -Yes - -@features_1250_td -Footprint (jar/dll size) - -@features_1251_td -~1 MB *5 - -@features_1252_td -~2 MB - -@features_1253_td -~700 KB - -@features_1254_td -~4 MB - -@features_1255_td -~6 MB - -@features_1256_p - *1 HSQLDB supports text tables. - -@features_1257_p - *2 MySQL supports linked MySQL tables under the name 'federated tables'. - -@features_1258_p - *3 Derby support for roles based security and password checking as an option. - -@features_1259_p - *4 Derby only supports global temporary tables. - -@features_1260_p - *5 The default H2 jar file contains debug information, jar files for other databases do not. - -@features_1261_p - *6 PostgreSQL supports functional indexes. - -@features_1262_p - *7 Derby only supports updatable result sets if the query is not sorted. - -@features_1263_p - *8 Derby and HSQLDB don't support standard compliant information schema tables. - -@features_1264_p - *9 H2 supports row level locks when using multi version concurrency. - -@features_1265_h3 -Derby and HSQLDB - -@features_1266_p - After an unexpected process termination (for example power failure), H2 can usually recover safely and automatically without any user interaction. For Derby and HSQLDB, some manual steps are required ('Another instance of Derby may have already booted the database' / 'The database is already in use by another process'). - -@features_1267_h3 -DaffodilDb and One$Db - -@features_1268_p - It looks like the development of this database has stopped. The last release was February 2006. - -@features_1269_h3 -McKoi - -@features_1270_p - It looks like the development of this database has stopped. The last release was August 2004 - -@features_1271_h2 -H2 in Use - -@features_1272_p - For a list of applications that work with or use H2, see: Links. - -@features_1273_h2 -Connection Modes - -@features_1274_p - The following connection modes are supported: - -@features_1275_li -Embedded mode (local connections using JDBC) - -@features_1276_li -Server mode (remote connections using JDBC or ODBC over TCP/IP) - -@features_1277_li -Mixed mode (local and remote connections at the same time) - -@features_1278_h3 -Embedded Mode - -@features_1279_p - In embedded mode, an application opens a database from within the same JVM using JDBC. This is the fastest and easiest connection mode. The disadvantage is that a database may only be open in one virtual machine (and class loader) at any time. As in all modes, both persistent and in-memory databases are supported. There is no limit on the number of database open concurrently, or on the number of open connections. - -@features_1280_h3 -Server Mode - -@features_1281_p - When using the server mode (sometimes called remote mode or client/server mode), an application opens a database remotely using the JDBC or ODBC API. A server needs to be started within the same or another virtual machine, or on another computer. Many applications can connect to the same database at the same time, by connecting to this server. Internally, the server process opens the database(s) in embedded mode. - -@features_1282_p - The server mode is slower than the embedded mode, because all data is transferred over TCP/IP. As in all modes, both persistent and in-memory databases are supported. There is no limit on the number of database open concurrently per server, or on the number of open connections. - -@features_1283_h3 -Mixed Mode - -@features_1284_p - The mixed mode is a combination of the embedded and the server mode. The first application that connects to a database does that in embedded mode, but also starts a server so that other applications (running in different processes or virtual machines) can concurrently access the same data. The local connections are as fast as if the database is used in just the embedded mode, while the remote connections are a bit slower. - -@features_1285_p - The server can be started and stopped from within the application (using the server API), or automatically (automatic mixed mode). When using the automatic mixed mode, all clients that want to connect to the database (no matter if it's an local or remote connection) can do so using the exact same database URL. - -@features_1286_h2 -Database URL Overview - -@features_1287_p - This database supports multiple connection modes and connection settings. This is achieved using different database URLs. Settings in the URLs are not case sensitive. - -@features_1288_th -Topic - -@features_1289_th -URL Format and Examples - -@features_1290_a -Embedded (local) connection - -@features_1291_td - jdbc:h2:[file:][<path>]<databaseName> - -@features_1292_td - jdbc:h2:~/test - -@features_1293_td - jdbc:h2:file:/data/sample - -@features_1294_td - jdbc:h2:file:C:/data/sample (Windows only) - -@features_1295_a -In-memory (private) - -@features_1296_td -jdbc:h2:mem: - -@features_1297_a -In-memory (named) - -@features_1298_td - jdbc:h2:mem:<databaseName> - -@features_1299_td - jdbc:h2:mem:test_mem - -@features_1300_a -Server mode (remote connections) - -@features_1301_a - using TCP/IP - -@features_1302_td - jdbc:h2:tcp://<server>[:<port>]/[<path>]<databaseName> - -@features_1303_td - jdbc:h2:tcp://localhost/~/test - -@features_1304_td - jdbc:h2:tcp://dbserv:8084/~/sample jdbc:h2:tcp://localhost/mem:test - -@features_1305_a -Server mode (remote connections) - -@features_1306_a - using SSL/TLS - -@features_1307_td - jdbc:h2:ssl://<server>[:<port>]/<databaseName> - -@features_1308_td - jdbc:h2:ssl://secureserv:8085/~/sample; - -@features_1309_a -Using encrypted files - -@features_1310_td - jdbc:h2:<url>;CIPHER=[AES|XTEA] - -@features_1311_td - jdbc:h2:ssl://secureserv/~/testdb;CIPHER=AES - -@features_1312_td - jdbc:h2:file:~/secure;CIPHER=XTEA - -@features_1313_a -File locking methods - -@features_1314_td - jdbc:h2:<url>;FILE_LOCK={FILE|SOCKET|NO} - -@features_1315_td - jdbc:h2:file:~/private;CIPHER=XTEA;FILE_LOCK=SOCKET - -@features_1316_a -Only open if it already exists - -@features_1317_td - jdbc:h2:<url>;IFEXISTS=TRUE - -@features_1318_td - jdbc:h2:file:~/sample;IFEXISTS=TRUE - -@features_1319_a -Don't close the database when the VM exits - -@features_1320_td - jdbc:h2:<url>;DB_CLOSE_ON_EXIT=FALSE - -@features_1321_a -Execute SQL on connection - -@features_1322_td - jdbc:h2:<url>;INIT=RUNSCRIPT FROM '~/create.sql' - -@features_1323_td - jdbc:h2:file:~/sample;INIT=RUNSCRIPT FROM '~/create.sql'\\;RUNSCRIPT FROM '~/populate.sql' - -@features_1324_a -User name and/or password - -@features_1325_td - jdbc:h2:<url>[;USER=<username>][;PASSWORD=<value>] - -@features_1326_td - jdbc:h2:file:~/sample;USER=sa;PASSWORD=123 - -@features_1327_a -Debug trace settings - -@features_1328_td - jdbc:h2:<url>;TRACE_LEVEL_FILE=<level 0..3> - -@features_1329_td - jdbc:h2:file:~/sample;TRACE_LEVEL_FILE=3 - -@features_1330_a -Ignore unknown settings - -@features_1331_td - jdbc:h2:<url>;IGNORE_UNKNOWN_SETTINGS=TRUE - -@features_1332_a -Custom file access mode - -@features_1333_td - jdbc:h2:<url>;ACCESS_MODE_DATA=rws - -@features_1334_a -Database in a zip file - -@features_1335_td - jdbc:h2:zip:<zipFileName>!/<databaseName> - -@features_1336_td - jdbc:h2:zip:~/db.zip!/test - -@features_1337_a -Compatibility mode - -@features_1338_td - jdbc:h2:<url>;MODE=<databaseType> - -@features_1339_td - jdbc:h2:~/test;MODE=MYSQL - -@features_1340_a -Auto-reconnect - -@features_1341_td - jdbc:h2:<url>;AUTO_RECONNECT=TRUE - -@features_1342_td - jdbc:h2:tcp://localhost/~/test;AUTO_RECONNECT=TRUE - -@features_1343_a -Automatic mixed mode - -@features_1344_td - jdbc:h2:<url>;AUTO_SERVER=TRUE - -@features_1345_td - jdbc:h2:~/test;AUTO_SERVER=TRUE - -@features_1346_a -Page size - -@features_1347_td - jdbc:h2:<url>;PAGE_SIZE=512 - -@features_1348_a -Changing other settings - -@features_1349_td - jdbc:h2:<url>;<setting>=<value>[;<setting>=<value>...] - -@features_1350_td - jdbc:h2:file:~/sample;TRACE_LEVEL_SYSTEM_OUT=3 - -@features_1351_h2 -Connecting to an Embedded (Local) Database - -@features_1352_p - The database URL for connecting to a local database is jdbc:h2:[file:][<path>]<databaseName>. The prefix file: is optional. If no or only a relative path is used, then the current working directory is used as a starting point. The case sensitivity of the path and database name depend on the operating system, however it is recommended to use lowercase letters only. The database name must be at least three characters long (a limitation of File.createTempFile). To point to the user home directory, use ~/, as in: jdbc:h2:~/test. - -@features_1353_h2 -In-Memory Databases - -@features_1354_p - For certain use cases (for example: rapid prototyping, testing, high performance operations, read-only databases), it may not be required to persist data, or persist changes to the data. This database supports the in-memory mode, where the data is not persisted. - -@features_1355_p - In some cases, only one connection to a in-memory database is required. This means the database to be opened is private. In this case, the database URL is jdbc:h2:mem: Opening two connections within the same virtual machine means opening two different (private) databases. - -@features_1356_p - Sometimes multiple connections to the same in-memory database are required. In this case, the database URL must include a name. Example: jdbc:h2:mem:db1. Accessing the same database using this URL only works within the same virtual machine and class loader environment. - -@features_1357_p - In-memory can be accessed remotely (or from multiple processes in the same machine) using TCP/IP or SSL/TLS. An example database URL is: jdbc:h2:tcp://localhost/mem:db1. - -@features_1358_p - 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 jdbc:h2:mem:test;DB_CLOSE_DELAY=-1. - -@features_1359_h2 -Database Files Encryption - -@features_1360_p - The database files can be encrypted. Two encryption algorithms are supported: AES and XTEA. To use file encryption, you need to specify the encryption algorithm (the 'cipher') and the file password (in addition to the user password) when connecting to the database. - -@features_1361_h3 -Creating a New Database with File Encryption - -@features_1362_p - By default, a new database is automatically created if it does not exist yet. To create an encrypted database, connect to it as it would already exist. - -@features_1363_h3 -Connecting to an Encrypted Database - -@features_1364_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 separates the file password and the user password; the file password itself may not contain spaces. File passwords and user passwords are case sensitive. Here is an example to connect to a password-encrypted database: - -@features_1365_h3 -Encrypting or Decrypting a Database - -@features_1366_p - To encrypt an existing database, use the ChangeFileEncryption tool. This tool can also decrypt an encrypted database, or change the file encryption key. 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: - -@features_1367_h2 -Database File Locking - -@features_1368_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. - -@features_1369_p - The following file locking methods are implemented: - -@features_1370_li -The default method is FILE and uses a watchdog thread to protect the database file. The watchdog reads the lock file each second. - -@features_1371_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 one (and always the same) computer. - -@features_1372_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. Failing to do so will result in a corrupted database. Using the method NO forces the database to not create a lock file at all. Please note that this is unsafe as another process is able to open the same database, possibly leading to data corruption. - -@features_1373_p - To open the database with a different file locking method, use the parameter FILE_LOCK. The following code opens the database with the 'socket' locking method: - -@features_1374_p - For more information about the algorithms, see Advanced / File Locking Protocols. - -@features_1375_h2 -Opening a Database Only if it Already Exists - -@features_1376_p - By default, when an application calls DriverManager.getConnection(url, ...) 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 databases, and only allow to open existing databases. To do this, add ;IFEXISTS=TRUE 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: - -@features_1377_h2 -Closing a Database - -@features_1378_h3 -Delayed Database Closing - -@features_1379_p - 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 one 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. The following statement will keep a database open for 10 seconds after the last connection was closed: - -@features_1380_p - The value -1 means the database is not 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: jdbc:h2:~/test;DB_CLOSE_DELAY=10. - -@features_1381_h3 -Don't Close a Database when the VM Exits - -@features_1382_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, 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. The first connection (the one that is opening the database) needs to set the option in the database URL (it is not possible to change the setting afterwards). The database URL to disable database closing on exit is: - -@features_1383_h2 -Execute SQL on Connection - -@features_1384_p - Sometimes, particularly for in-memory databases, it is useful to be able to execute DDL or DML commands automatically when a client connects to a database. This functionality is enabled via the INIT property. Note that multiple commands may be passed to INIT, but the semicolon delimiter must be escaped, as in the example below. - -@features_1385_h2 -Ignore Unknown Settings - -@features_1386_p - Some applications (for example OpenOffice.org Base) pass some additional parameters when connecting to the database. Why those parameters are passed is unknown. The parameters PREFERDOSLIKELINEENDS and IGNOREDRIVERPRIVILEGES are such examples; they are simply ignored to improve the compatibility with OpenOffice.org. If an application passes other parameters when connecting to the database, usually the database throws an exception saying the parameter is not supported. It is possible to ignored such parameters by adding ;IGNORE_UNKNOWN_SETTINGS=TRUE to the database URL. - -@features_1387_h2 -Changing Other Settings when Opening a Connection - -@features_1388_p - In addition to the settings already described, other database settings can be passed in the database URL. Adding ;setting=value at the end of a database URL is the same as executing the statement SET setting value just after connecting. For a list of supported settings, see SQL Grammar. - -@features_1389_h2 -Custom File Access Mode - -@features_1390_p - Usually, the database opens the database file with the access mode rw, meaning read-write (except for read only databases, where the mode r is used). To open a database in read-only mode if the database file is not read-only, use ACCESS_MODE_DATA=r. Also supported are rws and rwd. This setting must be specified in the database URL: - -@features_1391_p - For more information see Durability Problems. On many operating systems the access mode rws does not guarantee that the data is written to the disk. - -@features_1392_h2 -Multiple Connections - -@features_1393_h3 -Opening Multiple Databases at the Same Time - -@features_1394_p - An application can open multiple databases at the same time, including multiple connections to the same database. The number of open database is only limited by the memory available. - -@features_1395_h3 -Multiple Connections to the Same Database: Client/Server - -@features_1396_p - If you want to access the same database at the same time from different processes or computers, you need to use the client / server mode. In this case, one process acts as the server, and the other processes (that could reside on other computers as well) connect to the server via TCP/IP (or SSL/TLS over TCP/IP for improved security). - -@features_1397_h3 -Multithreading Support - -@features_1398_p - This database is multithreading-safe. That means, if an application is multi-threaded, it does not need 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. - -@features_1399_p - An application should normally use one connection per thread. This database synchronizes access to the same connection, but other databases may not do this. - -@features_1400_h3 -Locking, Lock-Timeout, Deadlocks - -@features_1401_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). All locks are released when the transaction commits or rolls back. When using the default transaction isolation level 'read committed', read locks are already released after each statement. - -@features_1402_p - 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 a connection cannot get a lock for a specified time, then a lock timeout exception is thrown. - -@features_1403_p - Usually, SELECT statements 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. The following statements generate locks: - -@features_1404_th -Type of Lock - -@features_1405_th -SQL Statement - -@features_1406_td -Read - -@features_1407_td -SELECT * FROM TEST; - -@features_1408_td - CALL SELECT MAX(ID) FROM TEST; - -@features_1409_td - SCRIPT; - -@features_1410_td -Write - -@features_1411_td -SELECT * FROM TEST WHERE 1=0 FOR UPDATE; - -@features_1412_td -Write - -@features_1413_td -INSERT INTO TEST VALUES(1, 'Hello'); - -@features_1414_td - INSERT INTO TEST SELECT * FROM TEST; - -@features_1415_td - UPDATE TEST SET NAME='Hi'; - -@features_1416_td - DELETE FROM TEST; - -@features_1417_td -Write - -@features_1418_td -ALTER TABLE TEST ...; - -@features_1419_td - CREATE INDEX ... ON TEST ...; - -@features_1420_td - DROP INDEX ...; - -@features_1421_p - 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 <milliseconds>. The initial lock timeout (that is the timeout used for new connections) can be set using the SQL command SET DEFAULT_LOCK_TIMEOUT <milliseconds>. The default lock timeout is persistent. - -@features_1422_h2 -Database File Layout - -@features_1423_p - The following files are created for persistent databases: - -@features_1424_th -File Name - -@features_1425_th -Description - -@features_1426_th -Number of Files - -@features_1427_td - test.h2.db - -@features_1428_td - Database file. - -@features_1429_td - Contains the transaction log, indexes, and data for all tables. - -@features_1430_td - Format: <database>.h2.db - -@features_1431_td - 1 per database - -@features_1432_td - test.lock.db - -@features_1433_td - Database lock file. - -@features_1434_td - Automatically (re-)created while the database is in use. - -@features_1435_td - Format: <database>.lock.db - -@features_1436_td - 1 per database (only if in use) - -@features_1437_td - test.trace.db - -@features_1438_td - Trace file (if the trace option is enabled). - -@features_1439_td - Contains trace information. - -@features_1440_td - Format: <database>.trace.db - -@features_1441_td - Renamed to <database>.trace.db.old is too big. - -@features_1442_td - 0 or 1 per database - -@features_1443_td - test.lobs.db/* - -@features_1444_td - Directory containing one file for each - -@features_1445_td - BLOB or CLOB value larger than a certain size. - -@features_1446_td - Format: <id>.t<tableId>.lob.db - -@features_1447_td - 1 per large object - -@features_1448_td - test.123.temp.db - -@features_1449_td - Temporary file. - -@features_1450_td - Contains a temporary blob or a large result set. - -@features_1451_td - Format: <database>.<id>.temp.db - -@features_1452_td - 1 per object - -@features_1453_h3 -Moving and Renaming Database Files - -@features_1454_p - Database name and location are not stored inside the database files. - -@features_1455_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 of the same database start with the same name and the respective extensions are unchanged). - -@features_1456_p - As there is no platform specific data in the files, they can be moved to other operating systems without problems. - -@features_1457_h3 -Backup - -@features_1458_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. - -@features_1459_p - To backup data while the database is running, the SQL command SCRIPT can be used. - -@features_1460_h2 -Logging and Recovery - -@features_1461_p - Whenever data is modified in the database and those changes are committed, the changes are written to the transaction log (except for in-memory objects). The changes to the main data area itself are usually written later on, to optimize disk access. If there is a power failure, the main data area is not up-to-date, but because the changes are in the transaction log, the next time the database is opened, the changes are re-applied automatically. - -@features_1462_h2 -Compatibility - -@features_1463_p - All database engines behave a little bit different. Where possible, H2 supports the ANSI SQL standard, and tries to be compatible to other databases. There are still a few differences however: - -@features_1464_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). - -@features_1465_h3 -Compatibility Modes - -@features_1466_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 differences to the regular mode: - -@features_1467_h3 -DB2 Compatibility Mode - -@features_1468_p - To use the IBM DB2 mode, use the database URL jdbc:h2:~/test;MODE=DB2 or the SQL statement SET MODE DB2. - -@features_1469_li -For aliased columns, ResultSetMetaData.getColumnName() returns the alias name and getTableName() returns null. - -@features_1470_li -Support for the syntax [OFFSET .. ROW] [FETCH ... ONLY] as an alternative for LIMIT .. OFFSET. - -@features_1471_li -Concatenating NULL with another value results in the other value. - -@features_1472_h3 -Derby Compatibility Mode - -@features_1473_p - To use the Apache Derby mode, use the database URL jdbc:h2:~/test;MODE=Derby or the SQL statement SET MODE Derby. - -@features_1474_li -For aliased columns, ResultSetMetaData.getColumnName() returns the alias name and getTableName() returns null. - -@features_1475_li -For unique indexes, NULL is distinct. That means only one row with NULL in one of the columns is allowed. - -@features_1476_li -Concatenating NULL with another value results in the other value. - -@features_1477_h3 -HSQLDB Compatibility Mode - -@features_1478_p - To use the HSQLDB mode, use the database URL jdbc:h2:~/test;MODE=HSQLDB or the SQL statement SET MODE HSQLDB. - -@features_1479_li -For aliased columns, ResultSetMetaData.getColumnName() returns the alias name and getTableName() returns null. - -@features_1480_li -When converting the scale of decimal data, the number is only converted if the new scale is smaller than the current scale. Usually, the scale is converted and 0s are added if required. - -@features_1481_li -For unique indexes, NULL is distinct. That means only one row with NULL in one of the columns is allowed. - -@features_1482_li -Text can be concatenated using '+'. - -@features_1483_h3 -MS SQL Server Compatibility Mode - -@features_1484_p - To use the MS SQL Server mode, use the database URL jdbc:h2:~/test;MODE=MSSQLServer or the SQL statement SET MODE MSSQLServer. - -@features_1485_li -For aliased columns, ResultSetMetaData.getColumnName() returns the alias name and getTableName() returns null. - -@features_1486_li -Identifiers may be quoted using square brackets as in [Test]. - -@features_1487_li -For unique indexes, NULL is distinct. That means only one row with NULL in one of the columns is allowed. - -@features_1488_li -Concatenating NULL with another value results in the other value. - -@features_1489_li -Text can be concatenated using '+'. - -@features_1490_h3 -MySQL Compatibility Mode - -@features_1491_p - To use the MySQL mode, use the database URL jdbc:h2:~/test;MODE=MySQL or the SQL statement SET MODE MySQL. - -@features_1492_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. - -@features_1493_li -Creating indexes in the CREATE TABLE statement is allowed using INDEX(..) or KEY(..). Example: create table test(id int primary key, name varchar(255), key idx_name(name)); - -@features_1494_li -Meta data calls return identifiers in lower case. - -@features_1495_li -When converting a floating point number to an integer, the fractional digits are not truncated, but the value is rounded. - -@features_1496_li -Concatenating NULL with another value results in the other value. - -@features_1497_h3 -Oracle Compatibility Mode - -@features_1498_p - To use the Oracle mode, use the database URL jdbc:h2:~/test;MODE=Oracle or the SQL statement SET MODE Oracle. - -@features_1499_li -For aliased columns, ResultSetMetaData.getColumnName() returns the alias name and getTableName() returns null. - -@features_1500_li -When using unique indexes, multiple rows with NULL in all columns are allowed, however it is not allowed to have multiple rows with the same values otherwise. - -@features_1501_li -Concatenating NULL with another value results in the other value. - -@features_1502_h3 -PostgreSQL Compatibility Mode - -@features_1503_p - To use the PostgreSQL mode, use the database URL jdbc:h2:~/test;MODE=PostgreSQL or the SQL statement SET MODE PostgreSQL. - -@features_1504_li -For aliased columns, ResultSetMetaData.getColumnName() returns the alias name and getTableName() returns null. - -@features_1505_li -When converting a floating point number to an integer, the fractional digits are not be truncated, but the value is rounded. - -@features_1506_li -The system columns CTID and OID are supported. - -@features_1507_h2 -Auto-Reconnect - -@features_1508_p - The auto-reconnect feature causes the JDBC driver to reconnect to the database if the connection is lost. The automatic re-connect only occurs when auto-commit is enabled; if auto-commit is disabled, an exception is thrown. To enable this mode, append ;AUTO_RECONNECT=TRUE to the database URL. - -@features_1509_p - Re-connecting will open a new session. After an automatic re-connect, variables and local temporary tables definitions (excluding data) are re-created. The contents of the system table INFORMATION_SCHEMA.SESSION_STATE contains all client side state that is re-created. - -@features_1510_p - If another connection uses the database in exclusive mode (enabled using SET EXCLUSIVE 1 or SET EXCLUSIVE 2), then this connection will try to re-connect until the exclusive mode ends. - -@features_1511_h2 -Automatic Mixed Mode - -@features_1512_p - Multiple processes can access the same database without having to start the server manually. To do that, append ;AUTO_SERVER=TRUE to the database URL. You can use the same database URL independent of whether the database is already open or not. This feature doesn't work with in-memory databases. - -@features_1513_p - When using this mode, the first connection to the database is made in embedded mode, and additionally a server is started internally (as a daemon thread). If the database is already open in another process, the server mode is used automatically. - -@features_1514_p - The application that opens the first connection to the database uses the embedded mode, which is faster than the server mode. Therefore the main application should open the database first if possible. The first connection automatically starts a server on a random port. This server allows remote connections, however only to this database (to ensure that, the client reads .lock.db file and sends the the random key that is stored there to the server). When the first connection is closed, the server stops. If other (remote) connections are still open, one of them will then start a server (auto-reconnect is enabled automatically). - -@features_1515_p - All processes need to have access to the database files. If the first connection is closed (the connection that started the server), open transactions of other connections will be rolled back (this may not be a problem if you don't disable autocommit). Explicit client/server connections (using jdbc:h2:tcp:// or ssl://) are not supported. This mode is not supported for in-memory databases. - -@features_1516_p - Here is an example how to use this mode. Application 1 and 2 are not necessarily started on the same computer, but they need to have access to the database files. Application 1 and 2 are typically two different processes (however they could run within the same process). - -@features_1517_h2 -Page Size - -@features_1518_p - The page size for new databases is 2 KB (2048), unless the system property h2.pageSize is set to a different value, or the page size is set explicitly in the database URL using PAGE_SIZE=. The page size of existing databases can not be changed. - -@features_1519_h2 -Using the Trace Options - -@features_1520_p - To find problems in an application, it is sometimes good to see what database operations where executed. This database offers the following trace features: - -@features_1521_li -Trace to System.out and/or to a file - -@features_1522_li -Support for trace levels OFF, ERROR, INFO, DEBUG - -@features_1523_li -The maximum size of the trace file can be set - -@features_1524_li -It is possible to generate Java source code from the trace file - -@features_1525_li -Trace can be enabled at runtime by manually creating a file - -@features_1526_h3 -Trace Options - -@features_1527_p - The simplest way to enable the trace option is setting it in the database URL. There are two settings, one for System.out (TRACE_LEVEL_SYSTEM_OUT) tracing, and one for file tracing (TRACE_LEVEL_FILE). The trace levels are 0 for OFF, 1 for ERROR (the default), 2 for INFO, and 3 for DEBUG. A database URL with both levels set to DEBUG is: - -@features_1528_p - The trace level can be changed at runtime by executing the SQL command SET TRACE_LEVEL_SYSTEM_OUT level (for System.out tracing) or SET TRACE_LEVEL_FILE level (for file tracing). Example: - -@features_1529_h3 -Setting the Maximum Size of the Trace File - -@features_1530_p - When using a high trace level, the trace file can get very big quickly. 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 such file exists, it is deleted. To limit the size to a certain number of megabytes, use SET TRACE_MAX_FILE_SIZE mb. Example: - -@features_1531_h3 -Java Code Generation - -@features_1532_p - When setting the trace level to INFO or DEBUG, Java source code is generated as well. This simplifies reproducing problems. The trace file looks like this: - -@features_1533_p - To filter the Java source code, use the ConvertTraceFile tool as follows: - -@features_1534_p - The generated file Test.java 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. - -@features_1535_h2 -Using Other Logging APIs - -@features_1536_p - By default, this database uses its own native 'trace' facility. This facility is called 'trace' and not 'log' within this database to avoid confusion with the transaction log. Trace messages can be written to both file and System.out. In most cases, this is sufficient, however sometimes it is better to use the same facility as the application, for example Log4j. To do that, this database support SLF4J. - -@features_1537_a -SLF4J - -@features_1538_p - is a simple facade for various logging APIs and allows to plug in the desired implementation at deployment time. SLF4J supports implementations such as Logback, Log4j, Jakarta Commons Logging (JCL), Java logging, x4juli, and Simple Log. - -@features_1539_p - To enable SLF4J, set the file trace level to 4 in the database URL: - -@features_1540_p - 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 the file <database>.trace.db for error messages. - -@features_1541_h2 -Read Only Databases - -@features_1542_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 and CALL statements are allowed. To create a read-only database, close the database. Then, make the database file read-only. When you open the database now, it 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(). - -@features_1543_p - Using the Custom Access Mode r the database can also be opened in read-only mode, even if the database file is not read only. - -@features_1544_h2 -Read Only Databases in Zip or Jar File - -@features_1545_p - To create a read-only database in a zip file, first create a regular persistent database, and then create a backup. The database must not have pending changes, that means you need to close all connections to the database first. If you are using a database named test, an easy way to create a zip file is using the Backup tool. You can start the tool from the command line, or from within the H2 Console (Tools - Backup). Please note that the database must be closed when the backup is created. Therefore, the SQL statement BACKUP TO can not be used. - -@features_1546_p - When the zip file is created, you can open the database in the zip file using the following database URL: - -@features_1547_p - 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; therefore large databases are supported as well. The same indexes are used as when using a regular database. - -@features_1548_h2 -Graceful Handling of Low Disk Space Situations - -@features_1549_p - If the database needs more disk space, it calls the database event listener if one is installed. The application may then delete temporary files, or display a message and wait until the user has resolved the problem. To install a listener, run the SQL statement SET DATABASE_EVENT_LISTENER or use a database 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. - -@features_1550_h3 -Opening a Corrupted Database - -@features_1551_p - If a database cannot 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. - -@features_1552_h2 -Computed Columns / Function Based Index - -@features_1553_p - 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, create a computed column with the upper-case version of the original column, and create an index for this column: - -@features_1554_p - 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: - -@features_1555_h2 -Multi-Dimensional Indexes - -@features_1556_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. - -@features_1557_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). - -@features_1558_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. 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. - -@features_1559_h2 -Using Passwords - -@features_1560_h3 -Using Secure Passwords - -@features_1561_p - Remember that weak passwords can be broken regardless of the encryption and security protocols. 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: - -@features_1562_code -i'sE2rtPiUKtT - -@features_1563_p - from the sentence it's easy to remember this password if you know the trick. - -@features_1564_h3 -Passwords: Using Char Arrays instead of Strings - -@features_1565_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). - -@features_1566_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. - -@features_1567_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: - -@features_1568_p - This example requires Java 1.6. When using Swing, use javax.swing.JPasswordField. - -@features_1569_h3 -Passing the User Name and/or Password in the URL - -@features_1570_p - Instead of passing the user name as a separate parameter as in Connection conn = DriverManager. getConnection("jdbc:h2:~/test", "sa", "123"); the user name (and/or password) can be supplied in the URL itself: Connection conn = DriverManager. getConnection("jdbc:h2:~/test;USER=sa;PASSWORD=123"); The settings in the URL override the settings passed as a separate parameter. - -@features_1571_h2 -User-Defined Functions and Stored Procedures - -@features_1572_p - In addition to the built-in functions, this database supports user-defined Java functions. In this database, Java functions can be used as stored procedures as well. A function must be declared (registered) before it can be used. A function can be defined using source code, or as a reference to a compiled class that is available in the classpath. By default, the function aliases are stored in the current schema. - -@features_1573_h3 -Referencing a Compiled Method - -@features_1574_p - When referencing a method, the class must already be compiled and included in the classpath where the database is running. Only static Java methods are supported; both the class and the method must be public. Example Java class: - -@features_1575_p - The Java function must be registered in the database by calling CREATE ALIAS ... FOR: - -@features_1576_p - For a complete sample application, see src/test/org/h2/samples/Function.java. - -@features_1577_h3 -Declaring Functions as Source Code - -@features_1578_p - When defining a function alias with source code, the database tries to compile the source code using the Sun Java compiler (the class com.sun.tools.javac.Main) if the tools.jar is in the classpath. If not, javac is run as a separate process. Only the source code is stored in the database; the class is compiled each time the database is re-opened. Source code is usually passed as dollar quoted text to avoid escaping problems, however single quotes can be used as well. Example: - -@features_1579_p - The method name (nextPrime in the example above) is ignored. By default, the three packages java.util, java.math, java.sql are imported. If different import statements are required, they must be declared at the beginning and separated with the tag @CODE: - -@features_1580_p - The following template is used to create a complete Java class: - -@features_1581_h3 -Function Data Type Mapping - -@features_1582_p - Functions that accept non-nullable parameters such as int will not be called if one of those parameters is NULL. Instead, 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. - -@features_1583_p - SQL types are mapped to Java classes and vice-versa as in the JDBC API. For details, see Data Types. There are two special cases: java.lang.Object is mapped to OTHER (a serialized object). Therefore, java.lang.Object can not be used to match all SQL types (matching all SQL types is not supported). The second special case is Object[]: arrays of any class are mapped to ARRAY. - -@features_1584_h3 -Functions That Require a Connection - -@features_1585_p - 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. - -@features_1586_h3 -Functions Throwing an Exception - -@features_1587_p - If a function throws an exception, then the current statement is rolled back and the exception is thrown to the application. SQLException are directly re-thrown to the calling application; all other exceptions are first converted to a SQLException. - -@features_1588_h3 -Functions Returning a Result Set - -@features_1589_p - Functions may returns a result set. Such a function can be called with the CALL statement: - -@features_1590_h3 -Using SimpleResultSet - -@features_1591_p - A function can create a result set using the SimpleResultSet tool: - -@features_1592_h3 -Using a Function as a Table - -@features_1593_p - 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 (maybe 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. - -@features_1594_h2 -Triggers - -@features_1595_p - 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. It is also possible to use triggers to simulate materialized views. For a complete sample application, see src/test/org/h2/samples/TriggerSample.java. A Java trigger must implement the interface org.h2.api.Trigger. The trigger class must be available in the classpath of the database engine (when using the server mode, it must be in the classpath of the server). - -@features_1596_p - The connection can be used to query or update data in other tables. The trigger then needs to be defined in the database: - -@features_1597_p - The trigger can be used to veto a change by throwing a SQLException. - -@features_1598_h2 -Compacting a Database - -@features_1599_p - Empty space in the database file re-used automatically. When closing the database, the database is automatically compacted for up to 1 second by default. To compact more, use the SQL statement SHUTDOWN COMPACT. However re-creating the database may further reduce the database size because this will re-build the indexes. Here is a sample function to do this: - -@features_1600_p - See also the sample application org.h2.samples.Compact. The commands SCRIPT / RUNSCRIPT can be used as well to create a backup of a database and re-build the database from the script. - -@features_1601_h2 -Cache Settings - -@features_1602_p - The database keeps most frequently used data in the main memory. 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=131072), or it can be changed at runtime using SET CACHE_SIZE size. The size of the cache, as represented by CACHE_SIZE is measured in KB, with each KB being 1024 bytes. This setting has no effect for in-memory databases. For persistent databases, the setting is stored in the database and re-used when the database is opened the next time. However, when opening an existing database, the cache size is set to at most half the amount of memory available for the virtual machine (Runtime.getRuntime().maxMemory()), even if the cache size setting stored in the database is larger; however the setting stored in the database is kept. Setting the cache size in the database URL or explicitly using SET CACHE_SIZE overrides this value (even if larger than the physical memory). To get the current used maximum cache size, use the query SELECT * FROM INFORMATION_SCHEMA.SETTINGS WHERE NAME = 'info.CACHE_MAX_SIZE' - -@features_1603_p - Also included is an experimental second level soft reference cache. Rows in this cache are only garbage collected on low memory. By default the second level cache is disabled. To enable it, use the prefix SOFT_. Example: jdbc:h2:~/test;CACHE_TYPE=SOFT_LRU. The cache might not actually improve performance. If you plan to use it, please run your own test cases first. - -@features_1604_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. - -@fragments_1000_b -Search: - -@fragments_1001_td -Highlight keyword(s) - -@fragments_1002_a -Home - -@fragments_1003_a -Download - -@fragments_1004_a -Cheat Sheet - -@fragments_1005_b -Documentation - -@fragments_1006_a -Quickstart - -@fragments_1007_a -Installation - -@fragments_1008_a -Tutorial - -@fragments_1009_a -Features - -@fragments_1010_a -Performance - -@fragments_1011_a -Advanced - -@fragments_1012_b -Reference - -@fragments_1013_a -SQL Grammar - -@fragments_1014_a -Functions - -@fragments_1015_a -Data Types - -@fragments_1016_a -Javadoc - -@fragments_1017_a -PDF (1 MB) - -@fragments_1018_b -Support - -@fragments_1019_a -FAQ - -@fragments_1020_a -Error Analyzer - -@fragments_1021_a -Google Group (English) - -@fragments_1022_a -Google Group (Japanese) - -@fragments_1023_a -Google Group (Chinese) - -@fragments_1024_b -Appendix - -@fragments_1025_a -JaQu - -@fragments_1026_a -Build - -@fragments_1027_a -History & Roadmap - -@fragments_1028_a -Links - -@fragments_1029_a -License - -@fragments_1030_td -  - -@frame_1000_h1 -H2 Database Engine - -@frame_1001_p - Welcome to H2, the free SQL database. The main feature of H2 are: - -@frame_1002_li -It is free to use for everybody, source code is included - -@frame_1003_li -Written in Java, but also available as native executable - -@frame_1004_li -JDBC and (partial) ODBC API - -@frame_1005_li -Embedded and client/server modes - -@frame_1006_li -Clustering is supported - -@frame_1007_li -A web client is included - -@frame_1008_h2 -No Javascript - -@frame_1009_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. - -@frame_1010_p - Please enable Javascript, or go ahead without it: H2 Database Engine - -@history_1000_h1 -History and Roadmap - -@history_1001_a - Change Log - -@history_1002_a - Roadmap - -@history_1003_a - History of this Database Engine - -@history_1004_a - Why Java - -@history_1005_a - Supporters - -@history_1006_h2 -Change Log - -@history_1007_p - The up-to-date change log is available at http://www.h2database.com/html/changelog.html - -@history_1008_h2 -Roadmap - -@history_1009_p - The current roadmap is available at http://www.h2database.com/html/roadmap.html - -@history_1010_h2 -History of this Database Engine - -@history_1011_p - The development of H2 was started in May 2004, but it was first published on December 14th 2005. The main author of H2, Thomas Mueller, is also the original developer of Hypersonic SQL. In 2001, he joined PointBase Inc. where he wrote PointBase Micro, a commercial Java SQL database. At that point, he had to discontinue Hypersonic SQL. The HSQLDB Group was formed to continued to work on the Hypersonic SQL codebase. The name H2 stands for Hypersonic 2, however H2 does not share code with Hypersonic SQL or HSQLDB. H2 is built from scratch. - -@history_1012_h2 -Why Java - -@history_1013_p - The main reasons to use a Java database are: - -@history_1014_li -Very simple to integrate in Java applications - -@history_1015_li -Support for many different platforms - -@history_1016_li -More secure than native applications (no buffer overflows) - -@history_1017_li -User defined functions (or triggers) run very fast - -@history_1018_li -Unicode support - -@history_1019_p - Some think Java is too slow for low level operations, but this is no longer true. Garbage collection for example is now faster than manual memory management. - -@history_1020_p - Developing Java code is faster than developing C or C++ code. When using Java, most time can be spent on improving the algorithms instead of porting the code to different platforms or doing memory management. Features such as Unicode and network libraries are already built-in. In Java, writing secure code is easier because buffer overflows can not occur. Features such as reflection can be used for randomized testing. - -@history_1021_p - Java is future proof: a lot of companies support Java. Java is now open source. - -@history_1022_p - To increase the portability and ease of use, this software depends on very few libraries. Features that are not available in open source Java implementations (such as Swing) are not used, or only used for optional features. - -@history_1023_h2 -Supporters - -@history_1024_p - Many thanks for those who reported bugs, gave valuable feedback, spread the word, and translated this project. Also many thanks to the donors: - -@history_1025_a -Code Lutin, France - -@history_1026_a -Code 42 Software, Inc., Minneapolis - -@history_1027_a -NetSuxxess GmbH, Germany - -@history_1028_a -Poker Copilot, Steve McLeod, Germany - -@history_1029_a -SkyCash, Poland - -@history_1030_a -Lumber-mill, Inc., Japan - -@history_1031_li -Martin Wildam, Austria - -@history_1032_li -Donald Bleyl, USA - -@history_1033_li -Frank Berger, Germany - -@history_1034_li -Ashwin Jayaprakash, USA - -@history_1035_li -Florent Ramiere, France - -@history_1036_li -Jun Iyama, Japan - -@history_1037_li -Antonio Casqueiro, Portugal - -@history_1038_li -Oliver Computing LLC, USA - -@history_1039_li -Harpal Grover Consulting Inc., USA - -@history_1040_li -Elisabetta Berlini, Italy - -@history_1041_li -William Gilbert, USA - -@history_1042_li -Antonio Dieguez Rojas, Chile - -@history_1043_a -Ontology Works, USA - -@history_1044_li -Pete Haidinyak, USA - -@history_1045_li -William Osmond, USA - -@history_1046_li -Joachim Ansorg, Germany - -@history_1047_li -Oliver Soerensen, Germany - -@history_1048_li -Christos Vasilakis, Greece - -@history_1049_li -Fyodor Kupolov, Denmark - -@history_1050_li -Jakob Jenkov, Denmark - -@history_1051_li -Stéphane Chartrand, Switzerland - -@history_1052_li -Glenn Kidd, USA - -@history_1053_li -Gustav Trede, Sweden - -@history_1054_li -Joonas Pulakka, Finland - -@history_1055_li -Bjorn Darri Sigurdsson, Iceland - -@history_1056_li -Iyama Jun, Japan - -@history_1057_li -Gray Watson, USA - -@history_1058_li -Erik Dick, Germany - -@installation_1000_h1 -Installation - -@installation_1001_a - Requirements - -@installation_1002_a - Supported Platforms - -@installation_1003_a - Installing the Software - -@installation_1004_a - Directory Structure - -@installation_1005_h2 -Requirements - -@installation_1006_p - To run the database, the following minimum software stack is known to work: - -@installation_1007_li -Windows XP or Vista, Mac OS X, or Linux - -@installation_1008_li -Recommended Windows file system: NTFS (FAT32 only supports files up to 4 GB) - -@installation_1009_li -Sun JDK 1.5 or newer - -@installation_1010_li -Mozilla Firefox - -@installation_1011_h2 -Supported Platforms - -@installation_1012_p - As this database is written in Java, it can run on many different platforms. It is tested with Java 1.5 and 1.6 but can also be compiled to native code using GCJ. The source code does not use features of Java 1.6. Currently, the database is developed and tested on Windows XP and Mac OS X using the Sun JDK 1.5, but it also works in many other operating systems and using other Java runtime environments. - -@installation_1013_h2 -Installing the Software - -@installation_1014_p - To install the software, run the installer or unzip it to a directory of your choice. - -@installation_1015_h2 -Directory Structure - -@installation_1016_p - After installing, you should get the following directory structure: - -@installation_1017_th -Directory - -@installation_1018_th -Contents - -@installation_1019_td -bin - -@installation_1020_td -JAR and batch files - -@installation_1021_td -docs - -@installation_1022_td -Documentation - -@installation_1023_td -docs/html - -@installation_1024_td -HTML pages - -@installation_1025_td -docs/javadoc - -@installation_1026_td -Javadoc files - -@installation_1027_td -ext - -@installation_1028_td -External dependencies (downloaded when building) - -@installation_1029_td -service - -@installation_1030_td -Tools to run the database as a Windows Service - -@installation_1031_td -src - -@installation_1032_td -Source files - -@installation_1033_td -src/docsrc - -@installation_1034_td -Documentation sources - -@installation_1035_td -src/installer - -@installation_1036_td -Installer, shell, and release build script - -@installation_1037_td -src/main - -@installation_1038_td -Database engine source code - -@installation_1039_td -src/test - -@installation_1040_td -Test source code - -@installation_1041_td -src/tools - -@installation_1042_td -Tools and database adapters source code - -@jaqu_1000_h1 -JaQu - -@jaqu_1001_a - What is JaQu - -@jaqu_1002_a - Differences to Other Data Access Tools - -@jaqu_1003_a - Current State - -@jaqu_1004_a - Building the JaQu Library - -@jaqu_1005_a - Requirements - -@jaqu_1006_a - Example Code - -@jaqu_1007_a - Configuration - -@jaqu_1008_a - Natural Syntax - -@jaqu_1009_a - Other Ideas - -@jaqu_1010_a - Similar Projects - -@jaqu_1011_h2 -What is JaQu - -@jaqu_1012_p - JaQu stands for Java Query and allows to access databases using pure Java. JaQu provides a fluent interface (or internal DSL) to access a database. JaQu is something like LINQ for Java (LINQ stands for "language integrated query" and is a Microsoft .NET technology). The following JaQu code: - -@jaqu_1013_p - stands for the SQL statement: - -@jaqu_1014_h2 -Differences to Other Data Access Tools - -@jaqu_1015_p - Unlike SQL, JaQu can be easily integrated in Java applications. Because JaQu is pure Java, auto-complete in the IDE and Javadoc and are supported. Type checking is performed by the compiler. JaQu fully protects against SQL injection. - -@jaqu_1016_p - JaQu is more a replacement for JDBC than it is a replacement for tools like Hibernate. With JaQu, you don't write SQL statements as Strings. JaQu is much smaller and simpler than other persistence frameworks such as Hibernate, but it also does not provide all the features of those. Unlike iBatis and Hibernate, no XML or annotation based configuration is required; instead the configuration (if required at all) is done in pure Java, in the application itself. - -@jaqu_1017_p - JaQu does not require or contain any data caching mechanism. Like JDBC and iBatis, JaQu provides full control over when and what SQL statements are executed (but without having to write SQL statements as Strings). - -@jaqu_1018_h3 -Restrictions - -@jaqu_1019_p - Primitive types (eg. boolean, int, long, double) are not supported. Use java.lang.Boolean, Integer, Long, Double instead. - -@jaqu_1020_h3 -Why in Java? - -@jaqu_1021_p - Most people use Java in their application. Mixing Java and another language (for example Scala or Groovy) in the same application is complicated: you would need to split the application and database code. - -@jaqu_1022_h2 -Current State - -@jaqu_1023_p - Currently, JaQu is only tested with the H2 database. The API may change in future versions. JaQu is not part of the h2 jar file, however the source code is included in H2, under: - -@jaqu_1024_code -src/test/org/h2/test/jaqu/* - -@jaqu_1025_li - (samples and tests) - -@jaqu_1026_code -src/tools/org/h2/jaqu/* - -@jaqu_1027_li - (framework) - -@jaqu_1028_h2 -Building the JaQu Library - -@jaqu_1029_p - To create the JaQu jar file, run: build jarJaqu. This will create the file bin/h2jaqu.jar. - -@jaqu_1030_h2 -Requirements - -@jaqu_1031_p - JaQu requires Java 1.5. Annotations are not need. Currently, JaQu is only tested with the H2 database engine, however in theory it should work with any database that supports the JDBC API. - -@jaqu_1032_h2 -Example Code - -@jaqu_1033_h2 -Configuration - -@jaqu_1034_p - JaQu does not require any configuration when using the default mapping. To define table indices, or if you want to map a class to a table with a different name, or a field to a column with another name, create a function called define in the data class. Example: - -@jaqu_1035_p - The method define() contains the mapping definition. It is called once when the class is used for the first time. Like annotations, the mapping is defined in the class itself. Unlike when using annotations, the compiler can check the syntax even for multi-column objects (multi-column indexes, multi-column primary keys and so on). Because the definition is written in regular Java, the configuration can depend on the environment. This is not possible using annotations. Unlike XML mapping configuration, the configuration is integrated in the class itself. - -@jaqu_1036_h2 -Natural Syntax - -@jaqu_1037_p -The plan is to support more natural (pure Java) syntax in conditions. To do that, the condition class is de-compiled to a SQL condition. A proof of concept decompiler is included (but it doesn't work yet). The planned syntax is: - -@jaqu_1038_h2 -Other Ideas - -@jaqu_1039_p - This project has just been started, and nothing is fixed yet. Some ideas for what to implement are: - -@jaqu_1040_li -Support queries on collections (instead of using a database). - -@jaqu_1041_li -Provide API level compatibility with JPA (so that JaQu can be used as an extension of JPA). - -@jaqu_1042_li -Internally use a JPA implementation (for example Hibernate) instead of SQL directly. - -@jaqu_1043_li -Use PreparedStatements and cache them. - -@jaqu_1044_h2 -Similar Projects - -@jaqu_1045_a -Cement Framework - -@jaqu_1046_a -Dreamsource ORM - -@jaqu_1047_a -Empire-db - -@jaqu_1048_a -JEQUEL: Java Embedded QUEry Language - -@jaqu_1049_a -Joist - -@jaqu_1050_a -JoSQL - -@jaqu_1051_a -LIQUidFORM - -@jaqu_1052_a -Quaere (Alias implementation) - -@jaqu_1053_a -Quaere - -@jaqu_1054_a -Querydsl - -@jaqu_1055_a -Squill - -@license_1000_h1 -License - -@license_1001_h2 -Summary and License FAQ - -@license_1002_p - H2 is dual licensed and available under a modified version of the MPL 1.1 (Mozilla Public License) or under the (unmodified) EPL 1.0 (Eclipse Public License). The changes to the MPL are - -@license_1003_em -underlined. There is a License FAQ for both the MPL and the EPL, most of that is applicable to the H2 License as well. - -@license_1004_li -You can use H2 for free. You can integrate it into your application (including commercial applications), and you can distribute it. - -@license_1005_li -Files containing only your code are not covered by this license (it is 'commercial friendly'). - -@license_1006_li -Modifications to the H2 source code must be published. - -@license_1007_li -You don't need to provide the source code of H2 if you did not modify anything. - -@license_1008_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: 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. It seems 'bungisoft' does not exist any more, but you can use the Wayback Machine and visit old web pages of http://www.bungisoft.com. - -@license_1009_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. - -@license_1010_h2 -H2 License, Version 1.0 - -@license_1011_h3 -1. Definitions - -@license_1012_b -1.0.1. "Commercial Use" - -@license_1013_p - means distribution or otherwise making the Covered Code available to a third party. - -@license_1014_b -1.1. "Contributor" - -@license_1015_p - means each entity that creates or contributes to the creation of Modifications. - -@license_1016_b -1.2. "Contributor Version" - -@license_1017_p - means the combination of the Original Code, prior Modifications used by a Contributor, and the Modifications made by that particular Contributor. - -@license_1018_b -1.3. "Covered Code" - -@license_1019_p - means the Original Code or Modifications or the combination of the Original Code and Modifications, in each case including portions thereof. - -@license_1020_b -1.4. "Electronic Distribution Mechanism" - -@license_1021_p - means a mechanism generally accepted in the software development community for the electronic transfer of data. - -@license_1022_b -1.5. "Executable" - -@license_1023_p - means Covered Code in any form other than Source Code. - -@license_1024_b -1.6. "Initial Developer" - -@license_1025_p - means the individual or entity identified as the Initial Developer in the Source Code notice required by Exhibit A. - -@license_1026_b -1.7. "Larger Work" - -@license_1027_p - means a work which combines Covered Code or portions thereof with code not governed by the terms of this License. - -@license_1028_b -1.8. "License" - -@license_1029_p - means this document. - -@license_1030_b -1.8.1. "Licensable" - -@license_1031_p - means having the right to grant, to the maximum extent possible, whether at the time of the initial grant or subsequently acquired, any and all of the rights conveyed herein. - -@license_1032_b -1.9. "Modifications" - -@license_1033_p - means any addition to or deletion from the substance or structure of either the Original Code or any previous Modifications. When Covered Code is released as a series of files, a Modification is: - -@license_1034_p -1.9.a. Any addition to or deletion from the contents of a file containing Original Code or previous Modifications. - -@license_1035_p -1.9.b. Any new file that contains any part of the Original Code or previous Modifications. - -@license_1036_b -1.10. "Original Code" - -@license_1037_p - means Source Code of computer software code which is described in the Source Code notice required by Exhibit A as Original Code, and which, at the time of its release under this License is not already Covered Code governed by this License. - -@license_1038_b -1.10.1. "Patent Claims" - -@license_1039_p - means any patent claim(s), now owned or hereafter acquired, including without limitation, method, process, and apparatus claims, in any patent Licensable by grantor. - -@license_1040_b -1.11. "Source Code" - -@license_1041_p - means the preferred form of the Covered Code for making modifications to it, including all modules it contains, plus any associated interface definition files, scripts used to control compilation and installation of an Executable, or source code differential comparisons against either the Original Code or another well known, available Covered Code of the Contributor's choice. The Source Code can be in a compressed or archival form, provided the appropriate decompression or de-archiving software is widely available for no charge. - -@license_1042_b -1.12. "You" (or "Your") - -@license_1043_p - means an individual or a legal entity exercising rights under, and complying with all of the terms of, this License or a future version of this License issued under Section 6.1. For legal entities, "You" includes any entity which controls, is controlled by, or is under common control with You. For purposes of this definition, "control" means (a) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (b) ownership of more than fifty percent (50%) of the outstanding shares or beneficial ownership of such entity. - -@license_1044_h3 -2. Source Code License - -@license_1045_h4 -2.1. The Initial Developer Grant - -@license_1046_p - The Initial Developer hereby grants You a world-wide, royalty-free, non-exclusive license, subject to third party intellectual property claims: - -@license_1047_p -2.1.a. under intellectual property rights (other than patent or trademark) Licensable by Initial Developer to use, reproduce, modify, display, perform, sublicense and distribute the Original Code (or portions thereof) with or without Modifications, and/or as part of a Larger Work; and - -@license_1048_p -2.1.b. under Patents Claims infringed by the making, using or selling of Original Code, to make, have made, use, practice, sell, and offer for sale, and/or otherwise dispose of the Original Code (or portions thereof). - -@license_1049_p -2.1.c. the licenses granted in this Section 2.1 (a) and (b) are effective on the date Initial Developer first distributes Original Code under the terms of this License. - -@license_1050_p -2.1.d. Notwithstanding Section 2.1 (b) above, no patent license is granted: 1) for code that You delete from the Original Code; 2) separate from the Original Code; or 3) for infringements caused by: i) the modification of the Original Code or ii) the combination of the Original Code with other software or devices. - -@license_1051_h4 -2.2. Contributor Grant - -@license_1052_p - Subject to third party intellectual property claims, each Contributor hereby grants You a world-wide, royalty-free, non-exclusive license - -@license_1053_p -2.2.a. under intellectual property rights (other than patent or trademark) Licensable by Contributor, to use, reproduce, modify, display, perform, sublicense and distribute the Modifications created by such Contributor (or portions thereof) either on an unmodified basis, with other Modifications, as Covered Code and/or as part of a Larger Work; and - -@license_1054_p -2.2.b. under Patent Claims infringed by the making, using, or selling of Modifications made by that Contributor either alone and/or in combination with its Contributor Version (or portions of such combination), to make, use, sell, offer for sale, have made, and/or otherwise dispose of: 1) Modifications made by that Contributor (or portions thereof); and 2) the combination of Modifications made by that Contributor with its Contributor Version (or portions of such combination). - -@license_1055_p -2.2.c. the licenses granted in Sections 2.2 (a) and 2.2 (b) are effective on the date Contributor first makes Commercial Use of the Covered Code. - -@license_1056_p -2.2.c. Notwithstanding Section 2.2 (b) above, no patent license is granted: 1) for any code that Contributor has deleted from the Contributor Version; 2) separate from the Contributor Version; 3) for infringements caused by: i) third party modifications of Contributor Version or ii) the combination of Modifications made by that Contributor with other software (except as part of the Contributor Version) or other devices; or 4) under Patent Claims infringed by Covered Code in the absence of Modifications made by that Contributor. - -@license_1057_h3 -3. Distribution Obligations - -@license_1058_h4 -3.1. Application of License - -@license_1059_p - The Modifications which You create or to which You contribute are governed by the terms of this License, including without limitation Section 2.2. 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 6.1, and You must include a copy of this License with every copy of the Source Code You distribute. You may not offer or impose any terms on any Source Code version that alters or restricts the applicable version of this License or the recipients' rights hereunder. However, You may include an additional document offering the additional rights described in Section 3.5. - -@license_1060_h4 -3.2. Availability of Source Code - -@license_1061_p - 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, must remain available for at least twelve (12) months after the date it initially became available, or at least six (6) months after a subsequent version of that particular Modification has been made available to such recipients. You are responsible for ensuring that the Source Code version remains available even if the Electronic Distribution Mechanism is maintained by a third party. - -@license_1062_h4 -3.3. Description of Modifications - -@license_1063_p - 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 (a) the Source Code, and (b) in any notice in an Executable version or related documentation in which You describe the origin or ownership of the Covered Code. - -@license_1064_h4 -3.4. Intellectual Property Matters - -@license_1065_b -3.4.a. Third Party Claims: - -@license_1066_p - If Contributor has knowledge that a license under a third party's intellectual property rights is required to exercise the rights granted by such Contributor under Sections 2.1 or 2.2, Contributor must include a text file with the Source Code distribution titled "LEGAL" which describes the claim and the party making the claim in sufficient detail that a recipient will know whom to contact. If Contributor obtains such knowledge after the Modification is made available as described in Section 3.2, Contributor shall promptly modify the LEGAL file in all copies Contributor makes available thereafter and shall take other steps (such as notifying appropriate mailing lists or newsgroups) reasonably calculated to inform those who received the Covered Code that new knowledge has been obtained. - -@license_1067_b -3.4.b. Contributor APIs: - -@license_1068_p - If Contributor's Modifications include an application programming interface and Contributor has knowledge of patent licenses which are reasonably necessary to implement that API, Contributor must also include this information in the legal file. - -@license_1069_b -3.4.c. Representations: - -@license_1070_p - Contributor represents that, except as disclosed pursuant to Section 3.4 (a) above, Contributor believes that Contributor's Modifications are Contributor's original creation(s) and/or Contributor has sufficient rights to grant the rights conveyed by this License. - -@license_1071_h4 -3.5. Required Notices - -@license_1072_p - You must duplicate the notice in Exhibit 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 Modification(s) You may add your name as a Contributor to the notice described in Exhibit A. You must also duplicate this License in any documentation for the Source Code where You describe recipients' rights or ownership rights relating to Covered Code. You may choose to offer, and to charge a fee for, warranty, support, indemnity or liability obligations to one or more recipients of Covered Code. However, You may do so only on Your own behalf, and not on behalf of the Initial Developer or any Contributor. You must make it absolutely clear than any such warranty, support, indemnity or liability obligation is offered by You alone, and You hereby agree to indemnify the Initial Developer 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. - -@license_1073_h4 -3.6. Distribution of Executable Versions - -@license_1074_p - You may distribute Covered Code in Executable form only if the requirements of Sections 3.1, 3.2, 3.3, 3.4 and 3.5 have been met for that Covered Code, and if You include a notice stating that the Source Code version of the Covered Code is available under the terms of this License, including a description of how and where You have fulfilled the obligations of Section 3.2. The notice must be conspicuously included in any notice in an Executable version, related documentation or collateral in which You describe recipients' rights relating to the Covered Code. You may distribute the Executable version of Covered Code or ownership rights under a license of Your choice, which may contain terms different from this License, provided that You are in compliance with the terms of this License and that the license for the Executable version does not attempt to limit or alter the recipient's rights in the Source Code version from the rights set forth in this License. If You distribute the Executable version under a different license You must make it absolutely clear that any terms which differ from this License are offered by You alone, not by the Initial Developer or any Contributor. You hereby agree to indemnify the Initial Developer and every Contributor for any liability incurred by the Initial Developer or such Contributor as a result of any such terms You offer. - -@license_1075_h4 -3.7. Larger Works - -@license_1076_p - 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. - -@license_1077_h3 -4. Inability to Comply Due to Statute or Regulation. - -@license_1078_p - 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 legal file described in Section 3.4 and must be included with all distributions of the Source Code. 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. - -@license_1079_h3 -5. Application of this License. - -@license_1080_p - This License applies to code to which the Initial Developer has attached the notice in Exhibit A and to related Covered Code. - -@license_1081_h3 -6. Versions of the License. - -@license_1082_h4 -6.1. New Versions - -@license_1083_p - The - -@license_1084_em -H2 Group may publish revised and/or new versions of the License from time to time. Each version will be given a distinguishing version number. - -@license_1085_h4 -6.2. Effect of New Versions - -@license_1086_p - 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 - -@license_1087_em -H2 Group. No one other than the - -@license_1088_em -H2 Group has the right to modify the terms applicable to Covered Code created under this License. - -@license_1089_h4 -6.3. Derivative Works - -@license_1090_p - 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 - -@license_1091_em -"H2 Group", "H2" or any confusingly similar phrase do not appear in your license (except to note that your license differs from this License) and (b) otherwise make it clear that Your version of the license contains terms which differ from the - -@license_1092_em -H2 License. (Filling in the name of the Initial Developer, Original Code or Contributor in the notice described in Exhibit A shall not of themselves be deemed to be modifications of this License.) - -@license_1093_h3 -7. Disclaimer of Warranty - -@license_1094_p - 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 the covered code is with you. Should any covered code prove defective in any respect, you (not the initial developer or any other contributor) assume the cost of any necessary servicing, repair or correction. This disclaimer of warranty constitutes an essential part of this license. No use of any covered code is authorized hereunder except under this disclaimer. - -@license_1095_h3 -8. Termination - -@license_1096_p -8.1. This License and the rights granted hereunder will terminate automatically if You fail to comply with terms herein and fail to cure such breach 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. - -@license_1097_p -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: - -@license_1098_p -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 Sections 2.1 and/or 2.2 of this License shall, upon 60 days notice from Participant terminate prospectively, unless if within 60 days after receipt of notice You either: (i) agree in writing to pay Participant a mutually agreeable reasonable royalty for Your past and future use of Modifications made by such Participant, or (ii) withdraw Your litigation claim with respect to the Contributor Version against such Participant. If within 60 days of notice, a reasonable royalty and payment arrangement are not mutually agreed upon in writing by the parties or the litigation claim is not withdrawn, the rights granted by Participant to You under Sections 2.1 and/or 2.2 automatically terminate at the expiration of the 60 day notice period specified above. - -@license_1099_p -8.2.b. any software, hardware, or device, other than such Participant's Contributor Version, directly or indirectly infringes any patent, then any rights granted to You by such Participant under Sections 2.1(b) and 2.2(b) are revoked effective as of the date You first made, used, sold, distributed, or had made, Modifications made by that Participant. - -@license_1100_p -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 initiation of patent infringement litigation, then the reasonable value of the licenses granted by such Participant under Sections 2.1 or 2.2 shall be taken into account in determining the amount or value of any payment or license. - -@license_1101_p -8.4. In the event of termination under Sections 8.1 or 8.2 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. - -@license_1102_h3 -9. Limitation of Liability - -@license_1103_p - 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 consequential damages of any character including, without limitation, damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses, even if such party shall have been informed of the possibility of such damages. This limitation of liability shall not apply to liability for death or personal injury resulting from such party's negligence to the extent applicable law prohibits such limitation. Some jurisdictions do not allow the exclusion or limitation of incidental or consequential damages, so this exclusion and limitation may not apply to you. - -@license_1104_h3 -10. United States Government End Users - -@license_1105_p - 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. - -@license_1106_h3 -11. Miscellaneous - -@license_1107_p - 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 California law provisions (except to the extent applicable law, if any, provides otherwise), excluding its conflict-of-law provisions. With respect to disputes in which at least one party is a citizen of, or an entity chartered or registered to do business in United States of America, any litigation relating to this License shall be subject to the jurisdiction of the Federal Courts of the Northern District of California, with venue lying in Santa Clara County, California, with the losing party responsible for costs, including without limitation, court costs and reasonable attorneys' fees and expenses. The application of the United Nations Convention on Contracts for the International Sale of Goods is expressly excluded. Any law or regulation which provides that the language of a contract shall be construed against the drafter shall not apply to this License. - -@license_1108_h3 -12. Responsibility for Claims - -@license_1109_p - 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. - -@license_1110_h3 -13. Multiple-Licensed Code - -@license_1111_p - 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 described in Exhibit A. - -@license_1112_h3 -Exhibit A - -@license_1113_h2 -Eclipse Public License - Version 1.0 - -@license_1114_p - THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS ECLIPSE PUBLIC LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT. - -@license_1115_h3 -1. DEFINITIONS - -@license_1116_p - "Contribution" means: - -@license_1117_p - a) in the case of the initial Contributor, the initial code and documentation distributed under this Agreement, and - -@license_1118_p - b) in the case of each subsequent Contributor: - -@license_1119_p - i) changes to the Program, and - -@license_1120_p - ii) additions to the Program; - -@license_1121_p - where such changes and/or additions to the Program originate from and are distributed by that particular Contributor. A Contribution 'originates' from a Contributor if it was added to the Program by such Contributor itself or anyone acting on such Contributor's behalf. Contributions do not include additions to the Program which: (i) are separate modules of software distributed in conjunction with the Program under their own license agreement, and (ii) are not derivative works of the Program. - -@license_1122_p - "Contributor" means any person or entity that distributes the Program. - -@license_1123_p - "Licensed Patents " mean patent claims licensable by a Contributor which are necessarily infringed by the use or sale of its Contribution alone or when combined with the Program. - -@license_1124_p - "Program" means the Contributions distributed in accordance with this Agreement. - -@license_1125_p - "Recipient" means anyone who receives the Program under this Agreement, including all Contributors. - -@license_1126_h3 -2. GRANT OF RIGHTS - -@license_1127_p - a) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free copyright license to reproduce, prepare derivative works of, publicly display, publicly perform, distribute and sublicense the Contribution of such Contributor, if any, and such derivative works, in source code and object code form. - -@license_1128_p - b) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free patent license under Licensed Patents to make, use, sell, offer to sell, import and otherwise transfer the Contribution of such Contributor, if any, in source code and object code form. This patent license shall apply to the combination of the Contribution and the Program if, at the time the Contribution is added by the Contributor, such addition of the Contribution causes such combination to be covered by the Licensed Patents. The patent license shall not apply to any other combinations which include the Contribution. No hardware per se is licensed hereunder. - -@license_1129_p - c) Recipient understands that although each Contributor grants the licenses to its Contributions set forth herein, no assurances are provided by any Contributor that the Program does not infringe the patent or other intellectual property rights of any other entity. Each Contributor disclaims any liability to Recipient for claims brought by any other entity based on infringement of intellectual property rights or otherwise. As a condition to exercising the rights and licenses granted hereunder, each Recipient hereby assumes sole responsibility to secure any other intellectual property rights needed, if any. For example, if a third party patent license is required to allow Recipient to distribute the Program, it is Recipient's responsibility to acquire that license before distributing the Program. - -@license_1130_p - d) Each Contributor represents that to its knowledge it has sufficient copyright rights in its Contribution, if any, to grant the copyright license set forth in this Agreement. - -@license_1131_h3 -3. REQUIREMENTS - -@license_1132_p - A Contributor may choose to distribute the Program in object code form under its own license agreement, provided that: - -@license_1133_p - a) it complies with the terms and conditions of this Agreement; and - -@license_1134_p - b) its license agreement: - -@license_1135_p - i) effectively disclaims on behalf of all Contributors all warranties and conditions, express and implied, including warranties or conditions of title and non-infringement, and implied warranties or conditions of merchantability and fitness for a particular purpose; - -@license_1136_p - ii) effectively excludes on behalf of all Contributors all liability for damages, including direct, indirect, special, incidental and consequential damages, such as lost profits; - -@license_1137_p - iii) states that any provisions which differ from this Agreement are offered by that Contributor alone and not by any other party; and - -@license_1138_p - iv) states that source code for the Program is available from such Contributor, and informs licensees how to obtain it in a reasonable manner on or through a medium customarily used for software exchange. - -@license_1139_p - When the Program is made available in source code form: - -@license_1140_p - a) it must be made available under this Agreement; and - -@license_1141_p - b) a copy of this Agreement must be included with each copy of the Program. - -@license_1142_p - Contributors may not remove or alter any copyright notices contained within the Program. - -@license_1143_p - Each Contributor must identify itself as the originator of its Contribution, if any, in a manner that reasonably allows subsequent Recipients to identify the originator of the Contribution. - -@license_1144_h3 -4. COMMERCIAL DISTRIBUTION - -@license_1145_p - Commercial distributors of software may accept certain responsibilities with respect to end users, business partners and the like. While this license is intended to facilitate the commercial use of the Program, the Contributor who includes the Program in a commercial product offering should do so in a manner which does not create potential liability for other Contributors. Therefore, if a Contributor includes the Program in a commercial product offering, such Contributor ("Commercial Contributor") hereby agrees to defend and indemnify every other Contributor ("Indemnified Contributor") against any losses, damages and costs (collectively "Losses") arising from claims, lawsuits and other legal actions brought by a third party against the Indemnified Contributor to the extent caused by the acts or omissions of such Commercial Contributor in connection with its distribution of the Program in a commercial product offering. The obligations in this section do not apply to any claims or Losses relating to any actual or alleged intellectual property infringement. In order to qualify, an Indemnified Contributor must: a) promptly notify the Commercial Contributor in writing of such claim, and b) allow the Commercial Contributor to control, and cooperate with the Commercial Contributor in, the defense and any related settlement negotiations. The Indemnified Contributor may participate in any such claim at its own expense. - -@license_1146_p - For example, a Contributor might include the Program in a commercial product offering, Product X. That Contributor is then a Commercial Contributor. If that Commercial Contributor then makes performance claims, or offers warranties related to Product X, those performance claims and warranties are such Commercial Contributor's responsibility alone. Under this section, the Commercial Contributor would have to defend claims against the other Contributors related to those performance claims and warranties, and if a court requires any other Contributor to pay any damages as a result, the Commercial Contributor must pay those damages. - -@license_1147_h3 -5. NO WARRANTY - -@license_1148_p - EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is solely responsible for determining the appropriateness of using and distributing the Program and assumes all risks associated with its exercise of rights under this Agreement, including but not limited to the risks and costs of program errors, compliance with applicable laws, damage to or loss of data, programs or equipment, and unavailability or interruption of operations. - -@license_1149_h3 -6. DISCLAIMER OF LIABILITY - -@license_1150_p - EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. - -@license_1151_h3 -7. GENERAL - -@license_1152_p - If any provision of this Agreement is invalid or unenforceable under applicable law, it shall not affect the validity or enforceability of the remainder of the terms of this Agreement, and without further action by the parties hereto, such provision shall be reformed to the minimum extent necessary to make such provision valid and enforceable. - -@license_1153_p - If Recipient institutes patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Program itself (excluding combinations of the Program with other software or hardware) infringes such Recipient's patent(s), then such Recipient's rights granted under Section 2(b) shall terminate as of the date such litigation is filed. - -@license_1154_p - All Recipient's rights under this Agreement shall terminate if it fails to comply with any of the material terms or conditions of this Agreement and does not cure such failure in a reasonable period of time after becoming aware of such noncompliance. If all Recipient's rights under this Agreement terminate, Recipient agrees to cease use and distribution of the Program as soon as reasonably practicable. However, Recipient's obligations under this Agreement and any licenses granted by Recipient relating to the Program shall continue and survive. - -@license_1155_p - Everyone is permitted to copy and distribute copies of this Agreement, but in order to avoid inconsistency the Agreement is copyrighted and may only be modified in the following manner. The Agreement Steward reserves the right to publish new versions (including revisions) of this Agreement from time to time. No one other than the Agreement Steward has the right to modify this Agreement. The Eclipse Foundation is the initial Agreement Steward. The Eclipse Foundation may assign the responsibility to serve as the Agreement Steward to a suitable separate entity. Each new version of the Agreement will be given a distinguishing version number. The Program (including Contributions) may always be distributed subject to the version of the Agreement under which it was received. In addition, after a new version of the Agreement is published, Contributor may elect to distribute the Program (including its Contributions) under the new version. Except as expressly stated in Sections 2(a) and 2(b) above, Recipient receives no rights or licenses to the intellectual property of any Contributor under this Agreement, whether expressly, by implication, estoppel or otherwise. All rights in the Program not expressly granted under this Agreement are reserved. - -@license_1156_p - This Agreement is governed by the laws of the State of New York and the intellectual property laws of the United States of America. No party to this Agreement will bring a legal action under this Agreement more than one year after the cause of action arose. Each party waives its rights to a jury trial in any resulting litigation. - -@links_1000_h1 -H2 In Use and Links - -@links_1001_p - Those are just a few links to products using or supporting H2. If you want to add a link, please send it to the support email address or post it in the group. - -@links_1002_h2 -Books - -@links_1003_a - Seam In Action - -@links_1004_h2 -Extensions - -@links_1005_a - Grails H2 Database Plugin - -@links_1006_a - h2osgi: OSGi for the H2 Database - -@links_1007_a - H2Sharp: ADO.NET interface for the H2 database engine - -@links_1008_a - H2 Spatial: spatial functions to H2 database - -@links_1009_h2 -Blog Articles - -@links_1010_a - Analyzing CSVs with H2 in under 10 minutes (2009-12-07) - -@links_1011_a - Efficient sorting and iteration on large databases (2009-06-15) - -@links_1012_a - Porting Flexive to the H2 Database (2008-12-05) - -@links_1013_a - H2 Database with GlassFish (2008-11-24) - -@links_1014_a - Using H2 Database with Glassfish and Toplink (2008-08-07) - -@links_1015_a - H2 Database - Performance Tracing (2008-04-30) - -@links_1016_a - Testing your JDBC data access layer with DBUnit and H2 (2007-09-18) - -@links_1017_a - Open Source Databases Comparison (2007-09-11) - -@links_1018_a - The Codist: The Open Source Frameworks I Use (2007-07-23) - -@links_1019_a - The Codist: SQL Injections: How Not To Get Stuck (2007-05-08) - -@links_1020_a - One Man Band: (Helma + H2) == "to easy" (2007-03-11) - -@links_1021_a - David Coldrick's Weblog: New Version of H2 Database Released (2007-01-06) - -@links_1022_a - The Codist: Write Your Own Database, Again (2006-11-13) - -@links_1023_h2 -Project Pages - -@links_1024_a - Ohloh - -@links_1025_a - Freshmeat Project Page - -@links_1026_a - Free Open Source Software For Us - -@links_1027_a - Wikipedia - -@links_1028_a - Java Source Net - -@links_1029_a - Linux Package Manager - -@links_1030_h2 -Database Frontends / Tools - -@links_1031_a - DB Solo - -@links_1032_p - SQL query tool. - -@links_1033_a - DbVisualizer - -@links_1034_p - Database tool. - -@links_1035_a - Execute Query - -@links_1036_p - Database utility written in Java. - -@links_1037_a - [fleXive] - -@links_1038_p - JavaEE 5 open source framework for the development of complex and evolving (web-)applications. - -@links_1039_a - HenPlus - -@links_1040_p - HenPlus is a SQL shell written in Java. - -@links_1041_a - RazorSQL - -@links_1042_p - An SQL query tool, database browser, SQL editor, and database administration tool. - -@links_1043_a - SQL Developer - -@links_1044_p - Universal Database Frontend. - -@links_1045_a - SQL Workbench/J - -@links_1046_p - Free DBMS-independent SQL tool. - -@links_1047_a - SQuirreL SQL Client - -@links_1048_p - Graphical tool to view the structure of a database, browse the data, issue SQL commands etc. - -@links_1049_a - SQuirreL DB Copy Plugin - -@links_1050_p - Tool to copy data from one database to another. - -@links_1051_h2 -Products and Projects - -@links_1052_a - AccuProcess - -@links_1053_p - Visual business process modeling and simulation software for business users. - -@links_1054_a - Adeptia BPM - -@links_1055_p - A Business Process Management (BPM) suite to quickly and easily automate business processes and workflows. - -@links_1056_a - Adeptia Integration - -@links_1057_p - Process-centric, services-based application integration suite. - -@links_1058_a - Aejaks - -@links_1059_p - A server-side scripting environment to build AJAX enabled web applications. - -@links_1060_a - Axiom Stack - -@links_1061_p - A web framework that let's you write dynamic web applications with Zen-like simplicity. - -@links_1062_a - Apache Cayenne - -@links_1063_p - Open source persistence framework providing object-relational mapping (ORM) and remoting services. - -@links_1064_a - Apache Jackrabbit - -@links_1065_p - Open source implementation of the Java Content Repository API (JCR). - -@links_1066_a - Apache OpenJPA - -@links_1067_p - Open source implementation of the Java Persistence API (JPA). - -@links_1068_a - AppFuse - -@links_1069_p - Helps building web applications. - -@links_1070_a - BGBlitz - -@links_1071_p - The Swiss army knife of Backgammon. - -@links_1072_a - Blojsom - -@links_1073_p - Java-based multi-blog, multi-user software package (Mac OS X Weblog Server). - -@links_1074_a - Bonita - -@links_1075_p - Open source workflow solution for handing long-running, user-oriented processes providing out of the box workflow and business process management features. - -@links_1076_a - Bookmarks Portlet - -@links_1077_p - JSR 168 compliant bookmarks management portlet application. - -@links_1078_a - Claros inTouch - -@links_1079_p - Ajax communication suite with mail, addresses, notes, IM, and rss reader. - -@links_1080_a - CrashPlan PRO Server - -@links_1081_p - Easy and cross platform backup solution for business and service providers. - -@links_1082_a - DbUnit - -@links_1083_p - A JUnit extension (also usable with Ant) targeted for database-driven projects. - -@links_1084_a - Dinamica Framework - -@links_1085_p - Ajax/J2EE framework for RAD development (mainly oriented toward hispanic markets). - -@links_1086_a - Ebean ORM Persistence Layer - -@links_1087_p - Open source Java Object Relational Mapping tool. - -@links_1088_a - Eclipse CDO - -@links_1089_p - The CDO (Connected Data Objects) Model Repository is a distributed shared model framework for EMF models, and a fast server-based O/R mapping solution. - -@links_1090_a - Epictetus - -@links_1091_p - Free cross platform database tool. - -@links_1092_a - Fabric3 - -@links_1093_p - Fabric3 is a project implementing a federated service network based on the Service Component Architecture specification (http://www.osoa.org). - -@links_1094_a - FIT4Data - -@links_1095_p - A testing framework for data management applications built on the Java implementation of FIT. - -@links_1096_a - Flux - -@links_1097_p - Java job scheduler, file transfer, workflow, and BPM. - -@links_1098_a - GBIF Integrated Publishing Toolkit (IPT) - -@links_1099_p - The GBIF IPT is an open source, Java based web application that connects and serves three types of biodiversity data: taxon primary occurrence data, taxon checklists and general resource metadata. - -@links_1100_a - GNU Gluco Control - -@links_1101_p - Helps you to manage your diabetes. - -@links_1102_a - Golden T Studios - -@links_1103_p - Fun-to-play games with a simple interface. - -@links_1104_a - Group Session - -@links_1105_p - Open source web groupware. - -@links_1106_a - HA-JDBC - -@links_1107_p - High-Availability JDBC: A JDBC proxy that provides light-weight, transparent, fault tolerant clustering capability to any underlying JDBC driver. - -@links_1108_a - Harbor - -@links_1109_p - Pojo Application Server. - -@links_1110_a - Hibernate - -@links_1111_p - Relational persistence for idiomatic Java (O-R mapping tool). - -@links_1112_a - Hibicius - -@links_1113_p - Online Banking Client for the HBCI protocol. - -@links_1114_a - ImageMapper - -@links_1115_p - ImageMapper frees users from having to use file browsers to view their images. They get fast access to images and easy cataloguing of them via a user friendly interface. - -@links_1116_a - JAMWiki - -@links_1117_p - Java-based Wiki engine. - -@links_1118_a - Jala - -@links_1119_p - Open source collection of JavaScript modules. - -@links_1120_a - Java Simon - -@links_1121_p - Simple Monitoring API. - -@links_1122_a - JBoss jBPM - -@links_1123_p - A platform for executable process languages ranging from business process management (BPM) over workflow to service orchestration. - -@links_1124_a - JBoss Jopr - -@links_1125_p - An enterprise management solution for JBoss middleware projects and other application technologies. - -@links_1126_a - JGeocoder - -@links_1127_p - Free Java geocoder. Geocoding is the process of estimating a latitude and longitude for a given location. - -@links_1128_a - JGrass - -@links_1129_p - Java Geographic Resources Analysis Support System. Free, multi platform, open source GIS based on the GIS framework of uDig. - -@links_1130_a - Jena - -@links_1131_p - Java framework for building Semantic Web applications. - -@links_1132_a - JMatter - -@links_1133_p - Framework for constructing workgroup business applications based on the Naked Objects Architectural Pattern. - -@links_1134_a - JotBot - -@links_1135_p - Records your day at user defined intervals. - -@links_1136_a - JPOX - -@links_1137_p - Java persistent objects. - -@links_1138_a - Liftweb - -@links_1139_p - A Scala-based, secure, developer friendly web framework. - -@links_1140_a - LiquiBase - -@links_1141_p - A tool to manage database changes and refactorings. - -@links_1142_a - Luntbuild - -@links_1143_p - Build automation and management tool. - -@links_1144_a - localdb - -@links_1145_p - A tool that locates the full file path of the folder containing the database files. - -@links_1146_a - Magnolia - -@links_1147_p - Microarray Data Management and Export System for PFGRC (Pathogen Functional Genomics Resource Center) Microarrays. - -@links_1148_a - MiniConnectionPoolManager - -@links_1149_p - A lightweight standalone JDBC connection pool manager. - -@links_1150_a - Mr. Persister - -@links_1151_p - Simple, small and fast object relational mapping. - -@links_1152_a - Myna Application Server - -@links_1153_p - Java web app that provides dynamic web content and Java libraries access from JavaScript. - -@links_1154_a - MyTunesRss - -@links_1155_p - MyTunesRSS lets you listen to your music wherever you are. - -@links_1156_a - NCGC CurveFit - -@links_1157_p - From: NIH Chemical Genomics Center, National Institutes of Health, USA. An open source application in the life sciences research field. This application handles chemical structures and biological responses of thousands of compounds with the potential to handle million+ compounds. It utilizes an embedded H2 database to enable flexible query/retrieval of all data including advanced chemical substructure and similarity searching. The application highlights an automated curve fitting and classification algorithm that outperforms commercial packages in the field. Commercial alternatives are typically small desktop software that handle a few dose response curves at a time. A couple of commercial packages that do handle several thousand curves are very expensive tools (>60k USD) that require manual curation of analysis by the user; require a license to Oracle; lack advanced query/retrieval; and the ability to handle chemical structures. - -@links_1158_a - Nuxeo - -@links_1159_p - Standards-based, open source platform for building ECM applications. - -@links_1160_a - nWire - -@links_1161_p - Eclipse plug-in which expedites Java development. It's main purpose is to help developers find code quicker and easily understand how it relates to the rest of the application, thus, understand the application structure. - -@links_1162_a - Ontology Works - -@links_1163_p - This company provides semantic technologies including deductive information repositories (the Ontology Works Knowledge Servers), semantic information fusion and semantic federation of legacy databases, ontology-based domain modeling, and management of the distributed enterprise. - -@links_1164_a - Ontoprise OntoBroker - -@links_1165_p - SemanticWeb-Middleware. It supports all W3C Semantic Web recommendations: OWL, RDF, RDFS, SPARQL, and F-Logic. - -@links_1166_a - Open Anzo - -@links_1167_p - Semantic Application Server. - -@links_1168_a - OpenTelegard - -@links_1169_p - An OpenSource BBS Software written in JRuby. - -@links_1170_a - OpenGroove - -@links_1171_p - OpenGroove is a groupware program that allows users to synchronize data. - -@links_1172_a - OpenSocial Development Environment (OSDE) - -@links_1173_p - Development tool for OpenSocial application. - -@links_1174_a - Orion - -@links_1175_p - J2EE Application Server. - -@links_1176_a - P5H2 - -@links_1177_p - A library for the Processing programming language and environment. - -@links_1178_a - Phase-6 - -@links_1179_p - A computer based learning software. - -@links_1180_a - Pickle - -@links_1181_p - Pickle is a Java library containing classes for persistence, concurrency, and logging. - -@links_1182_a - Piman - -@links_1183_p - Water treatment projects data management. - -@links_1184_a - PolePosition - -@links_1185_p - Open source database benchmark. - -@links_1186_a - Poormans - -@links_1187_p - Very basic CMS running as a SWT application and generating static html pages. - -@links_1188_a - Railo - -@links_1189_p - Railo is an alternative engine for the Cold Fusion Markup Language, that compiles code programmed in CFML into Java bytecode and executes it on a servlet engine. - -@links_1190_a - Razuna - -@links_1191_p - Open source Digital Asset Management System with integrated Web Content Management. - -@links_1192_a - RIFE - -@links_1193_p - A full-stack web application framework with tools and APIs to implement most common web features. - -@links_1194_a - Rutema - -@links_1195_p - Rutema is a test execution and management tool for heterogeneous development environments written in Ruby. - -@links_1196_a - Sava - -@links_1197_p - Open-source web-based content management system. - -@links_1198_a - Scriptella - -@links_1199_p - ETL (Extract-Transform-Load) and script execution tool. - -@links_1200_a - Sesar - -@links_1201_p - Dependency Injection Container with Aspect Oriented Programming. - -@links_1202_a - SemmleCode - -@links_1203_p - Eclipse plugin to help you improve software quality. - -@links_1204_a - SeQuaLite - -@links_1205_p - A free, light-weight, java data access framework. - -@links_1206_a - ShapeLogic - -@links_1207_p - Toolkit for declarative programming, image processing and computer vision. - -@links_1208_a - Shellbook - -@links_1209_p - Desktop publishing application. - -@links_1210_a - Signsoft intelliBO - -@links_1211_p - Persistence middleware supporting the JDO specification. - -@links_1212_a - SimpleORM - -@links_1213_p - Simple Java Object Relational Mapping. - -@links_1214_a - SymmetricDS - -@links_1215_p - A web-enabled, database independent, data synchronization/replication software. - -@links_1216_a - SmartFoxServer - -@links_1217_p - Platform for developing multiuser applications and games with Macromedia Flash. - -@links_1218_a - Social Bookmarks Friend Finder - -@links_1219_p - A GUI application that allows you to find users with similar bookmarks to the user specified (for delicious.com). - -@links_1220_a - Springfuse - -@links_1221_p - Code generation For Spring, Spring MVC & Hibernate. - -@links_1222_a - SQLOrm - -@links_1223_p - Java Object Relation Mapping. - -@links_1224_a - StorYBook - -@links_1225_p - A summary-based tool for novelist and script writers. It helps to keep the overview over the various traces a story has. - -@links_1226_a - StreamCruncher - -@links_1227_p - Event (stream) processing kernel. - -@links_1228_a - Tune Backup - -@links_1229_p - Easy-to-use backup solution for your iTunes library. - -@links_1230_a - weblica - -@links_1231_p - Desktop CMS. - -@links_1232_a - Web of Web - -@links_1233_p - Collaborative and realtime interactive media platform for the web. - -@links_1234_a - Werkzeugkasten - -@links_1235_p - Minimum Java Toolset. - -@links_1236_a - VPDA - -@links_1237_p - View providers driven applications is a Java based application framework for building applications composed from server components - view providers. - -@links_1238_a - Volunteer database - -@links_1239_p - A database front end to register volunteers, partnership and donation for a Non Profit organization. - -@mainWeb_1000_h1 -H2 Database Engine - -@mainWeb_1001_p - Welcome to H2, the Java SQL database. The main features of H2 are: - -@mainWeb_1002_li -Very fast, open source, JDBC API - -@mainWeb_1003_li -Embedded and server modes; in-memory databases - -@mainWeb_1004_li -Browser based Console application - -@mainWeb_1005_li -Small footprint: around 1 MB jar file size - -@mainWeb_1006_h3 -Download - -@mainWeb_1007_td - Version 1.2.137 (2010-06-06): - -@mainWeb_1008_a -Windows Installer (4 MB) - -@mainWeb_1009_a -All Platforms (zip, 5 MB) - -@mainWeb_1010_a -All Downloads - -@mainWeb_1011_td -    - -@mainWeb_1012_h3 -Support - -@mainWeb_1013_a -English Google Group - -@mainWeb_1014_a -Japanese Google Group - -@mainWeb_1015_p - For non-technical issues, use: - -@mainWeb_1016_h3 -Features - -@mainWeb_1017_th -H2 - -@mainWeb_1018_a -Derby - -@mainWeb_1019_a -HSQLDB - -@mainWeb_1020_a -MySQL - -@mainWeb_1021_a -PostgreSQL - -@mainWeb_1022_td -Pure Java - -@mainWeb_1023_td -Yes - -@mainWeb_1024_td -Yes - -@mainWeb_1025_td -Yes - -@mainWeb_1026_td -No - -@mainWeb_1027_td -No - -@mainWeb_1028_td -Memory Mode - -@mainWeb_1029_td -Yes - -@mainWeb_1030_td -Yes - -@mainWeb_1031_td -Yes - -@mainWeb_1032_td -No - -@mainWeb_1033_td -No - -@mainWeb_1034_td -Transaction Isolation - -@mainWeb_1035_td -Yes - -@mainWeb_1036_td -Yes - -@mainWeb_1037_td -No - -@mainWeb_1038_td -Yes - -@mainWeb_1039_td -Yes - -@mainWeb_1040_td -Cost Based Optimizer - -@mainWeb_1041_td -Yes - -@mainWeb_1042_td -Yes - -@mainWeb_1043_td -No - -@mainWeb_1044_td -Yes - -@mainWeb_1045_td -Yes - -@mainWeb_1046_td -Encrypted Database - -@mainWeb_1047_td -Yes - -@mainWeb_1048_td -Yes - -@mainWeb_1049_td -No - -@mainWeb_1050_td -No - -@mainWeb_1051_td -No - -@mainWeb_1052_td -ODBC Driver - -@mainWeb_1053_td -Yes - -@mainWeb_1054_td -No - -@mainWeb_1055_td -No - -@mainWeb_1056_td -Yes - -@mainWeb_1057_td -Yes - -@mainWeb_1058_td -Fulltext Search - -@mainWeb_1059_td -Yes - -@mainWeb_1060_td -No - -@mainWeb_1061_td -No - -@mainWeb_1062_td -Yes - -@mainWeb_1063_td -Yes - -@mainWeb_1064_td -Multi Version Concurrency - -@mainWeb_1065_td -Yes - -@mainWeb_1066_td -No - -@mainWeb_1067_td -No - -@mainWeb_1068_td -Yes - -@mainWeb_1069_td -Yes - -@mainWeb_1070_td -Footprint (jar/dll size) - -@mainWeb_1071_td -~1 MB - -@mainWeb_1072_td -~2 MB - -@mainWeb_1073_td -~600 KB - -@mainWeb_1074_td -~4 MB - -@mainWeb_1075_td -~6 MB - -@mainWeb_1076_p - See also the detailed comparison. - -@mainWeb_1077_h3 -News - -@mainWeb_1078_b -Newsfeeds: - -@mainWeb_1079_a -Full text (Atom) - -@mainWeb_1080_p - or Header only (RSS). - -@mainWeb_1081_b -Email Newsletter: - -@mainWeb_1082_p - Subscribe to H2 Database News (Google account required) to get informed about new releases. Your email address is only used in this context. - -@mainWeb_1083_td -  - -@mainWeb_1084_h3 -Contribute - -@mainWeb_1085_p - You can contribute to the development of H2 by sending feedback and bug reports, or translate the H2 Console application (for details, start the H2 Console and select Options / Translate). To donate money, click on the PayPal button below. You will be listed as a supporter: - -@main_1000_h1 -H2 Database Engine - -@main_1001_p - Welcome to H2, the free Java SQL database engine. - -@main_1002_a -Quickstart - -@main_1003_p - Get a fast overview. - -@main_1004_a -Tutorial - -@main_1005_p - Go through the samples. - -@main_1006_a -Features - -@main_1007_p - See what this database can do and how to use these features. - -@performance_1000_h1 -Performance - -@performance_1001_a - Performance Comparison - -@performance_1002_a - PolePosition Benchmark - -@performance_1003_a - Application Profiling - -@performance_1004_a - Database Profiling - -@performance_1005_a - Database Performance Tuning - -@performance_1006_a - Using the Built-In Profiler - -@performance_1007_a - Fast Database Import - -@performance_1008_h2 -Performance Comparison - -@performance_1009_p - In many cases H2 is faster than other (open source and not open source) database engines. Please note this is mostly a single connection benchmark run on one computer. - -@performance_1010_h3 -Embedded - -@performance_1011_th -Test Case - -@performance_1012_th -Unit - -@performance_1013_th -H2 - -@performance_1014_th -HSQLDB - -@performance_1015_th -Derby - -@performance_1016_td -Simple: Init - -@performance_1017_td -ms - -@performance_1018_td -547 - -@performance_1019_td -532 - -@performance_1020_td -2594 - -@performance_1021_td -Simple: Query (random) - -@performance_1022_td -ms - -@performance_1023_td -250 - -@performance_1024_td -391 - -@performance_1025_td -1515 - -@performance_1026_td -Simple: Query (sequential) - -@performance_1027_td -ms - -@performance_1028_td -188 - -@performance_1029_td -313 - -@performance_1030_td -1406 - -@performance_1031_td -Simple: Update (random) - -@performance_1032_td -ms - -@performance_1033_td -812 - -@performance_1034_td -1750 - -@performance_1035_td -17704 - -@performance_1036_td -Simple: Delete (sequential) - -@performance_1037_td -ms - -@performance_1038_td -203 - -@performance_1039_td -250 - -@performance_1040_td -8843 - -@performance_1041_td -Simple: Memory Usage - -@performance_1042_td -MB - -@performance_1043_td -7 - -@performance_1044_td -11 - -@performance_1045_td -11 - -@performance_1046_td -BenchA: Init - -@performance_1047_td -ms - -@performance_1048_td -578 - -@performance_1049_td -719 - -@performance_1050_td -3328 - -@performance_1051_td -BenchA: Transactions - -@performance_1052_td -ms - -@performance_1053_td -3047 - -@performance_1054_td -2406 - -@performance_1055_td -12907 - -@performance_1056_td -BenchA: Memory Usage - -@performance_1057_td -MB - -@performance_1058_td -10 - -@performance_1059_td -15 - -@performance_1060_td -10 - -@performance_1061_td -BenchB: Init - -@performance_1062_td -ms - -@performance_1063_td -2141 - -@performance_1064_td -2406 - -@performance_1065_td -11562 - -@performance_1066_td -BenchB: Transactions - -@performance_1067_td -ms - -@performance_1068_td -1125 - -@performance_1069_td -1375 - -@performance_1070_td -3625 - -@performance_1071_td -BenchB: Memory Usage - -@performance_1072_td -MB - -@performance_1073_td -9 - -@performance_1074_td -11 - -@performance_1075_td -8 - -@performance_1076_td -BenchC: Init - -@performance_1077_td -ms - -@performance_1078_td -688 - -@performance_1079_td -594 - -@performance_1080_td -4500 - -@performance_1081_td -BenchC: Transactions - -@performance_1082_td -ms - -@performance_1083_td -1906 - -@performance_1084_td -64062 - -@performance_1085_td -6047 - -@performance_1086_td -BenchC: Memory Usage - -@performance_1087_td -MB - -@performance_1088_td -11 - -@performance_1089_td -17 - -@performance_1090_td -11 - -@performance_1091_td -Executed statements - -@performance_1092_td -# - -@performance_1093_td -322929 - -@performance_1094_td -322929 - -@performance_1095_td -322929 - -@performance_1096_td -Total time - -@performance_1097_td -ms - -@performance_1098_td -11485 - -@performance_1099_td -74798 - -@performance_1100_td -74031 - -@performance_1101_td -Statements per second - -@performance_1102_td -# - -@performance_1103_td -28117 - -@performance_1104_td -4317 - -@performance_1105_td -4362 - -@performance_1106_h3 -Client-Server - -@performance_1107_th -Test Case - -@performance_1108_th -Unit - -@performance_1109_th -H2 - -@performance_1110_th -HSQLDB - -@performance_1111_th -Derby - -@performance_1112_th -PostgreSQL - -@performance_1113_th -MySQL - -@performance_1114_td -Simple: Init - -@performance_1115_td -ms - -@performance_1116_td -2782 - -@performance_1117_td -2656 - -@performance_1118_td -5625 - -@performance_1119_td -4563 - -@performance_1120_td -3484 - -@performance_1121_td -Simple: Query (random) - -@performance_1122_td -ms - -@performance_1123_td -3093 - -@performance_1124_td -2703 - -@performance_1125_td -6688 - -@performance_1126_td -4812 - -@performance_1127_td -3860 - -@performance_1128_td -Simple: Query (sequential) - -@performance_1129_td -ms - -@performance_1130_td -2969 - -@performance_1131_td -2594 - -@performance_1132_td -6437 - -@performance_1133_td -4719 - -@performance_1134_td -3625 - -@performance_1135_td -Simple: Update (random) - -@performance_1136_td -ms - -@performance_1137_td -2969 - -@performance_1138_td -3531 - -@performance_1139_td -18250 - -@performance_1140_td -5953 - -@performance_1141_td -5125 - -@performance_1142_td -Simple: Delete (sequential) - -@performance_1143_td -ms - -@performance_1144_td -1047 - -@performance_1145_td -1250 - -@performance_1146_td -6875 - -@performance_1147_td -2485 - -@performance_1148_td -2390 - -@performance_1149_td -Simple: Memory Usage - -@performance_1150_td -MB - -@performance_1151_td -7 - -@performance_1152_td -11 - -@performance_1153_td -14 - -@performance_1154_td -0 - -@performance_1155_td -0 - -@performance_1156_td -BenchA: Init - -@performance_1157_td -ms - -@performance_1158_td -2250 - -@performance_1159_td -2453 - -@performance_1160_td -6031 - -@performance_1161_td -4328 - -@performance_1162_td -3625 - -@performance_1163_td -BenchA: Transactions - -@performance_1164_td -ms - -@performance_1165_td -10250 - -@performance_1166_td -9016 - -@performance_1167_td -21484 - -@performance_1168_td -15609 - -@performance_1169_td -11172 - -@performance_1170_td -BenchA: Memory Usage - -@performance_1171_td -MB - -@performance_1172_td -10 - -@performance_1173_td -15 - -@performance_1174_td -10 - -@performance_1175_td -0 - -@performance_1176_td -1 - -@performance_1177_td -BenchB: Init - -@performance_1178_td -ms - -@performance_1179_td -9500 - -@performance_1180_td -10672 - -@performance_1181_td -22609 - -@performance_1182_td -19609 - -@performance_1183_td -13406 - -@performance_1184_td -BenchB: Transactions - -@performance_1185_td -ms - -@performance_1186_td -2734 - -@performance_1187_td -2656 - -@performance_1188_td -3875 - -@performance_1189_td -4688 - -@performance_1190_td -2531 - -@performance_1191_td -BenchB: Memory Usage - -@performance_1192_td -MB - -@performance_1193_td -10 - -@performance_1194_td -11 - -@performance_1195_td -11 - -@performance_1196_td -1 - -@performance_1197_td -1 - -@performance_1198_td -BenchC: Init - -@performance_1199_td -ms - -@performance_1200_td -1860 - -@performance_1201_td -1484 - -@performance_1202_td -6890 - -@performance_1203_td -2219 - -@performance_1204_td -3438 - -@performance_1205_td -BenchC: Transactions - -@performance_1206_td -ms - -@performance_1207_td -9046 - -@performance_1208_td -63266 - -@performance_1209_td -18641 - -@performance_1210_td -11703 - -@performance_1211_td -7421 - -@performance_1212_td -BenchC: Memory Usage - -@performance_1213_td -MB - -@performance_1214_td -12 - -@performance_1215_td -17 - -@performance_1216_td -13 - -@performance_1217_td -0 - -@performance_1218_td -1 - -@performance_1219_td -Executed statements - -@performance_1220_td -# - -@performance_1221_td -322929 - -@performance_1222_td -322929 - -@performance_1223_td -322929 - -@performance_1224_td -322929 - -@performance_1225_td -322929 - -@performance_1226_td -Total time - -@performance_1227_td -ms - -@performance_1228_td -48500 - -@performance_1229_td -102281 - -@performance_1230_td -123405 - -@performance_1231_td -80688 - -@performance_1232_td -60077 - -@performance_1233_td -Statements per second - -@performance_1234_td -# - -@performance_1235_td -6658 - -@performance_1236_td -3157 - -@performance_1237_td -2616 - -@performance_1238_td -4002 - -@performance_1239_td -5375 - -@performance_1240_h3 -Benchmark Results and Comments - -@performance_1241_h4 -H2 - -@performance_1242_p - Version 1.1.114 (2009-06-01) was used for the test. For simpler operations, the performance of H2 is about the same as for HSQLDB. For more complex queries, the query optimizer is very important. However H2 is not very fast in every case, certain kind of queries may still be slow. One situation where is H2 is slow is large result sets, because they are buffered to disk if more than a certain number of records are returned. The advantage of buffering is, there is no limit on the result set size. The open/close time is almost fixed, because of the file locking protocol: the engine waits some time after opening a database to ensure the database files are not opened by another process. - -@performance_1243_h4 -HSQLDB - -@performance_1244_p - Version 1.8.0.10 was used for the test. Cached tables are used in this test (hsqldb.default_table_type=cached), and the write delay is 1 second (SET WRITE_DELAY 1). HSQLDB is fast when using simple operations. HSQLDB is very slow in the last test (BenchC: Transactions), probably because is has a bad query optimizer. One query where HSQLDB is slow is a two-table join: - -@performance_1245_p - The PolePosition benchmark also shows that the query optimizer does not do a very good job for some queries. Another disadvantage of HSQLDB is the slow startup / shutdown time (currently not listed) when using bigger databases. The reason is, a backup of the whole data is made whenever the database is opened or closed. - -@performance_1246_h4 -Derby - -@performance_1247_p - Version 10.4.2.0 was used for the test. Derby is clearly the slowest embedded database in this test. This seems to be a structural problem, because all operations are really slow. It will be hard for the developers of Derby to improve the performance to a reasonable level. A few problems have been identified: leaving autocommit on is a problem for Derby. If it is switched off during the whole test, the results are about 20% better for Derby. Derby does not call FileDescriptor.sync() or FileChannel.force(..) on each commit. Derby supports a testing mode (system property derby.system.durability=test) where durability is disabled. According to the documentation, this setting should be used for testing only, as the database may not recover after a crash. Enabling this setting improves performance by a factor of 2.6 (embedded mode) or 1.4 (server mode). Even if enabled, Derby is still less than half as fast as H2 in default mode. - -@performance_1248_h4 -PostgreSQL - -@performance_1249_p - Version 8.3.7 was used for the test. The following options where changed in postgresql.conf: fsync = off, commit_delay = 1000. PostgreSQL is run in server mode. It looks like the base performance is slower than MySQL, the reason could be the network layer. The memory usage number is incorrect, because only the memory usage of the JDBC driver is measured. - -@performance_1250_h4 -MySQL - -@performance_1251_p - Version 5.1.34-community was used for the test. MySQL was run with the InnoDB backend. The setting innodb_flush_log_at_trx_commit (found in the my.ini file) was set to 0. Otherwise (and by default), MySQL is really slow (around 140 statements per second in this test) because it tries to flush the data to disk for each commit. For small transactions (when autocommit is on) this is really slow. But many use cases use small or relatively small transactions. Too bad this setting is not listed in the configuration wizard, and it always overwritten when using the wizard. You need to change this setting manually in the file my.ini, and then restart the service. The memory usage number is incorrect, because only the memory usage of the JDBC driver is measured. - -@performance_1252_h4 -Firebird - -@performance_1253_p - Firebird 1.5 (default installation) was tested, but the results are not published currently. It is possible to run the performance test with the Firebird database, and any information on how to configure Firebird for higher performance are welcome. - -@performance_1254_h4 -Why Oracle / MS SQL Server / DB2 are Not Listed - -@performance_1255_p - The license of these databases does not allow to publish benchmark results. This doesn't mean that they are fast. They are in fact quite slow, and need a lot of memory. But you will need to test this yourself. SQLite was not tested because the JDBC driver doesn't support transactions. - -@performance_1256_h3 -About this Benchmark - -@performance_1257_h4 -How to Run - -@performance_1258_p - This test was executed as follows: - -@performance_1259_h4 -Separate Process per Database - -@performance_1260_p - For each database, a new process is started, to ensure the previous test does not impact the current test. - -@performance_1261_h4 -Number of Connections - -@performance_1262_p - This is mostly a single-connection benchmark. BenchB uses multiple connections; the other tests use one connection. - -@performance_1263_h4 -Real-World Tests - -@performance_1264_p - Good benchmarks emulate real-world use cases. This benchmark includes 4 test cases: BenchSimple uses one table and many small updates / deletes. BenchA is similar to the TPC-A test, but single connection / single threaded (see also: www.tpc.org). BenchB is similar to the TPC-B test, using multiple connections (one thread per connection). BenchC is similar to the TPC-C test, but single connection / single threaded. - -@performance_1265_h4 -Comparing Embedded with Server Databases - -@performance_1266_p - This is mainly a benchmark for embedded databases (where the application runs in the same virtual machine as the database engine). However MySQL and PostgreSQL are not Java databases and cannot be embedded into a Java application. For the Java databases, both embedded and server modes are tested. - -@performance_1267_h4 -Test Platform - -@performance_1268_p - This test is run on Windows XP with the virus scanner switched off. The VM used is Sun JDK 1.5. - -@performance_1269_h4 -Multiple Runs - -@performance_1270_p - When a Java benchmark is run first, the code is not fully compiled and therefore runs slower than when running multiple times. A benchmark should always run the same test multiple times and ignore the first run(s). This benchmark runs three times, but only the last run is measured. - -@performance_1271_h4 -Memory Usage - -@performance_1272_p - It is not enough to measure the time taken, the memory usage is important as well. Performance can be improved by using a bigger cache, but the amount of memory is limited. HSQLDB tables are kept fully in memory by default; this benchmark uses 'disk based' tables for all databases. Unfortunately, it is not so easy to calculate the memory usage of PostgreSQL and MySQL, because they run in a different process than the test. This benchmark currently does not print memory usage of those databases. - -@performance_1273_h4 -Delayed Operations - -@performance_1274_p - Some databases delay some operations (for example flushing the buffers) until after the benchmark is run. This benchmark waits between each database tested, and each database runs in a different process (sequentially). - -@performance_1275_h4 -Transaction Commit / Durability - -@performance_1276_p - Durability means transaction committed to the database will not be lost. Some databases (for example MySQL) try to enforce this by default by calling fsync() to flush the buffers, but most hard drives don't actually flush all data. Calling the method slows down transaction commit a lot, but doesn't always make data durable. When comparing the results, it is important to think about the effect. Many database suggest to 'batch' operations when possible. This benchmark switches off autocommit when loading the data, and calls commit after each 1000 inserts. However many applications need 'short' transactions at runtime (a commit after each update). This benchmark commits after each update / delete in the simple benchmark, and after each business transaction in the other benchmarks. For databases that support delayed commits, a delay of one second is used. - -@performance_1277_h4 -Using Prepared Statements - -@performance_1278_p - Wherever possible, the test cases use prepared statements. - -@performance_1279_h4 -Currently Not Tested: Startup Time - -@performance_1280_p - The startup time of a database engine is important as well for embedded use. This time is not measured currently. Also, not tested is the time used to create a database and open an existing database. Here, one (wrapper) connection is opened at the start, and for each step a new connection is opened and then closed. - -@performance_1281_h2 -PolePosition Benchmark - -@performance_1282_p - The PolePosition is an open source benchmark. The algorithms are all quite simple. It was developed / sponsored by db4o. - -@performance_1283_th -Test Case - -@performance_1284_th -Unit - -@performance_1285_th -H2 - -@performance_1286_th -HSQLDB - -@performance_1287_th -MySQL - -@performance_1288_td -Melbourne write - -@performance_1289_td -ms - -@performance_1290_td -369 - -@performance_1291_td -249 - -@performance_1292_td -2022 - -@performance_1293_td -Melbourne read - -@performance_1294_td -ms - -@performance_1295_td -47 - -@performance_1296_td -49 - -@performance_1297_td -93 - -@performance_1298_td -Melbourne read_hot - -@performance_1299_td -ms - -@performance_1300_td -24 - -@performance_1301_td -43 - -@performance_1302_td -95 - -@performance_1303_td -Melbourne delete - -@performance_1304_td -ms - -@performance_1305_td -147 - -@performance_1306_td -133 - -@performance_1307_td -176 - -@performance_1308_td -Sepang write - -@performance_1309_td -ms - -@performance_1310_td -965 - -@performance_1311_td -1201 - -@performance_1312_td -3213 - -@performance_1313_td -Sepang read - -@performance_1314_td -ms - -@performance_1315_td -765 - -@performance_1316_td -948 - -@performance_1317_td -3455 - -@performance_1318_td -Sepang read_hot - -@performance_1319_td -ms - -@performance_1320_td -789 - -@performance_1321_td -859 - -@performance_1322_td -3563 - -@performance_1323_td -Sepang delete - -@performance_1324_td -ms - -@performance_1325_td -1384 - -@performance_1326_td -1596 - -@performance_1327_td -6214 - -@performance_1328_td -Bahrain write - -@performance_1329_td -ms - -@performance_1330_td -1186 - -@performance_1331_td -1387 - -@performance_1332_td -6904 - -@performance_1333_td -Bahrain query_indexed_string - -@performance_1334_td -ms - -@performance_1335_td -336 - -@performance_1336_td -170 - -@performance_1337_td -693 - -@performance_1338_td -Bahrain query_string - -@performance_1339_td -ms - -@performance_1340_td -18064 - -@performance_1341_td -39703 - -@performance_1342_td -41243 - -@performance_1343_td -Bahrain query_indexed_int - -@performance_1344_td -ms - -@performance_1345_td -104 - -@performance_1346_td -134 - -@performance_1347_td -678 - -@performance_1348_td -Bahrain update - -@performance_1349_td -ms - -@performance_1350_td -191 - -@performance_1351_td -87 - -@performance_1352_td -159 - -@performance_1353_td -Bahrain delete - -@performance_1354_td -ms - -@performance_1355_td -1215 - -@performance_1356_td -729 - -@performance_1357_td -6812 - -@performance_1358_td -Imola retrieve - -@performance_1359_td -ms - -@performance_1360_td -198 - -@performance_1361_td -194 - -@performance_1362_td -4036 - -@performance_1363_td -Barcelona write - -@performance_1364_td -ms - -@performance_1365_td -413 - -@performance_1366_td -832 - -@performance_1367_td -3191 - -@performance_1368_td -Barcelona read - -@performance_1369_td -ms - -@performance_1370_td -119 - -@performance_1371_td -160 - -@performance_1372_td -1177 - -@performance_1373_td -Barcelona query - -@performance_1374_td -ms - -@performance_1375_td -20 - -@performance_1376_td -5169 - -@performance_1377_td -101 - -@performance_1378_td -Barcelona delete - -@performance_1379_td -ms - -@performance_1380_td -388 - -@performance_1381_td -319 - -@performance_1382_td -3287 - -@performance_1383_td -Total - -@performance_1384_td -ms - -@performance_1385_td -26724 - -@performance_1386_td -53962 - -@performance_1387_td -87112 - -@performance_1388_p - There are a few problems with the PolePosition test: - -@performance_1389_li - HSQLDB uses in-memory tables by default while H2 uses persistent tables. The HSQLDB version included in PolePosition does not support changing this, so you need to replace poleposition-0.20/lib/hsqldb.jar with a newer version (for example hsqldb-1.8.0.7.jar), and then use the setting hsqldb.connecturl=jdbc:hsqldb:file:data/hsqldb/dbbench2;hsqldb.default_table_type=cached;sql.enforce_size=true in the file Jdbc.properties. - -@performance_1390_li -HSQLDB keeps the database open between tests, while H2 closes the database (losing all the cache). To change that, use the database URL jdbc:h2:file:data/h2/dbbench;DB_CLOSE_DELAY=-1 - -@performance_1391_li -The amount of cache memory is quite important, specially for the PolePosition test. Unfortunately, the PolePosition test does not take this into account. - -@performance_1392_h2 -Application Profiling - -@performance_1393_h3 -Analyze First - -@performance_1394_p - Before trying to optimize performance, it is important to understand where the problem is (what part of the application is slow). Blind optimization or optimization based on guesses should be avoided, because usually it is not an efficient strategy. There are various ways to analyze an application. Sometimes two implementations can be compared using System.currentTimeMillis(). But this does not work for complex applications with many modules, and for memory problems. - -@performance_1395_p - A simple way to profile an application is to use the built-in profiling tool of java. Example: - -@performance_1396_p - Unfortunately, it is only possible to profile the application from start to end. Another solution is to create a number of full thread dumps. To do that, first run jps -l to get the process id, and then run jstack <pid> or kill -QUIT <pid> (Linux) or press Ctrl+C (Windows). - -@performance_1397_p - A simple profiling tool is included in H2. To use it, the application needs to be changed slightly. Example: - -@performance_1398_p - The profiler is built into the H2 Console tool, to analyze databases that open slowly. To use it, run the H2 Console, and then click on 'Test Connection'. Afterwards, click on "Test successful" and you get the most common stack traces, which helps to find out why it took so long to connect. You will only get the stack traces if opening the database took more than a few seconds. - -@performance_1399_h2 -Database Profiling - -@performance_1400_p - The ConvertTraceFile tool generates SQL statement statistics at the end of the SQL script file. The format used is similar to the profiling data generated when using java -Xrunhprof. As an example, execute the the following script using the H2 Console: - -@performance_1401_p - Now convert the .trace.db file using the ConvertTraceFile tool: - -@performance_1402_p - The generated file test.sql will contain the SQL statements as well as the following profiling data (results vary): - -@performance_1403_h2 -Database Performance Tuning - -@performance_1404_h3 -Keep Connections Open or Use a Connection Pool - -@performance_1405_p - If your application opens and closes connections a lot (for example, for each request), you should consider using a connection pool. Opening a connection using DriverManager.getConnection is specially slow if the database is closed. By default the database is closed if the last connection is closed. - -@performance_1406_p - If you open and close connections a lot but don't want to use a connection pool, consider keeping a 'sentinel' connection open for as long as the application runs, or use delayed database closing. See also Closing a database. - -@performance_1407_h3 -Use a Modern JVM - -@performance_1408_p - Newer JVMs are faster. Upgrading to the latest version of your JVM can provide a "free" boost to performance. Switching from the default Client JVM to the Server JVM using the -server command-line option improves performance at the cost of a slight increase in start-up time. - -@performance_1409_h3 -Virus Scanners - -@performance_1410_p - Some virus scanners scan files every time they are accessed. It is very important for performance that database files are not scanned for viruses. The database engine never interprets the data stored in the files as programs, that means even if somebody would store a virus in a database file, this would be harmless (when the virus does not run, it cannot spread). Some virus scanners allow to exclude files by suffix. Ensure files ending with .db are not scanned. - -@performance_1411_h3 -Using the Trace Options - -@performance_1412_p - If the performance hot spots are in the database engine, in many cases the performance can be optimized by creating additional indexes, or changing the schema. Sometimes the application does not directly generate the SQL statements, for example if an O/R mapping tool is used. To view the SQL statements and JDBC API calls, you can use the trace options. For more information, see Using the Trace Options. - -@performance_1413_h3 -Index Usage - -@performance_1414_p - This database uses indexes to improve the performance of SELECT, UPDATE, DELETE. If a column is used in the WHERE clause of a query, and if an index exists on this column, then the index can be used. Multi-column indexes are used if all or the first columns of the index are used. Both equality lookup and range scans are supported. Indexes are used to order result sets, but only if the condition uses the same index or no index at all. The results are sorted in memory if required. Indexes are created automatically for primary key and unique constraints. Indexes are also created for foreign key constraints, if required. For other columns, indexes need to be created manually using the CREATE INDEX statement. - -@performance_1415_h3 -Optimizer - -@performance_1416_p - This database uses a cost based optimizer. For simple and queries and queries with medium complexity (less than 7 tables in the join), the expected cost (running time) of all possible plans is calculated, and the plan with the lowest cost is used. For more complex queries, the algorithm first tries all possible combinations for the first few tables, and the remaining tables added using a greedy algorithm (this works well for most joins). Afterwards a genetic algorithm is used to test at most 2000 distinct plans. Only left-deep plans are evaluated. - -@performance_1417_h3 -Expression Optimization - -@performance_1418_p - After the statement is parsed, all expressions are simplified automatically if possible. Operations are evaluated only once if all parameters are constant. Functions are also optimized, but only if the function is constant (always returns the same result for the same parameter values). If the WHERE clause is always false, then the table is not accessed at all. - -@performance_1419_h3 -COUNT(*) Optimization - -@performance_1420_p - If the query only counts all rows of a table, then the data is not accessed. However, this is only possible if no WHERE clause is used, that means it only works for queries of the form SELECT COUNT(*) FROM table. - -@performance_1421_h3 -Updating Optimizer Statistics / Column Selectivity - -@performance_1422_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. - -@performance_1423_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', the index on NAME or the index on FIRSTNAME. It is not possible to use both indexes at the same time. Which index is used depends on the selectivity of the column. The selectivity describes the 'uniqueness' of 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. - -@performance_1424_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. - -@performance_1425_h3 -In-Memory (Hash) Indexes - -@performance_1426_p - Using in-memory indexes, specially in-memory hash indexes, can speed up queries and data manipulation. - -@performance_1427_p -In-memory indexes are automatically used for in-memory databases, but can also be created for persistent databases using CREATE MEMORY TABLE. In many cases, the rows itself will also be kept in-memory. Please note this may cause memory problems for large tables. - -@performance_1428_p - In-memory hash indexes are backed by a hash table and are usually faster than regular indexes. However, hash indexes only supports direct lookup (WHERE ID = ?) but not range scan (WHERE ID < ?). To use hash indexes, use HASH as in: CREATE UNIQUE HASH INDEX and CREATE TABLE ...(ID INT PRIMARY KEY HASH,...). - -@performance_1429_h3 -Use Prepared Statements - -@performance_1430_p - If possible, use prepared statements with parameters. - -@performance_1431_h3 -Prepared Statements and IN(...) - -@performance_1432_p - Avoid generating SQL statements with a variable size IN(...) list. Instead, use a prepared statement with arrays as in the following example: - -@performance_1433_h3 -Optimization Examples - -@performance_1434_p - See src/test/org/h2/samples/optimizations.sql for a few examples of queries that benefit from special optimizations built into the database. - -@performance_1435_h3 -Cache Size and Type - -@performance_1436_p - By default the cache size of H2 is quite small. Consider using a larger cache size, or enable the second level soft reference cache. See also Cache Settings. - -@performance_1437_h3 -Data Types - -@performance_1438_p - Each data type has different storage and performance characteristics: - -@performance_1439_li -The DECIMAL/NUMERIC type is slower and requires more storage than the REAL and DOUBLE types. - -@performance_1440_li -Text types are slower to read, write, and compare than numeric types and generally require more storage. - -@performance_1441_li -See Large Objects for information on BINARY vs. BLOB and VARCHAR vs. CLOB performance. - -@performance_1442_li -Parsing and formatting takes longer for the TIME, DATE, and TIMESTAMP types than the numeric types. - -@performance_1443_code -SMALLINT/TINYINT/BOOLEAN - -@performance_1444_li - are not significantly smaller or faster to work with than INTEGER in most modes. - -@performance_1445_h3 -Sorted Insert Optimization - -@performance_1446_p - To reduce disk space usage and speed up table creation, an optimization for sorted inserts is available. When used, b-tree pages are split at the insertion point. To use this optimization, add SORTED before the SELECT statement: - -@performance_1447_h2 -Using the Built-In Profiler - -@performance_1448_p - A very simple Java profiler is built-in. To use it, use the following template: - -@performance_1449_h2 -Fast Database Import - -@performance_1450_p - To speed up large imports, consider using the following options temporarily: - -@performance_1451_code -SET CACHE_SIZE - -@performance_1452_li - (a large cache is faster) - -@performance_1453_code -SET LOCK_MODE 0 - -@performance_1454_li - (disable locking) - -@performance_1455_code -SET UNDO_LOG 0 - -@performance_1456_li - (disable the session undo log) - -@performance_1457_p - These options can be set in the database URL: jdbc:h2:~/test;CACHE_SIZE=65536;LOCK_MODE=0;UNDO_LOG=0. Most of those options are not recommended for regular use, that means you need to reset them after use. - -@quickstart_1000_h1 -Quickstart - -@quickstart_1001_a - Embedding H2 in an Application - -@quickstart_1002_a - The H2 Console Application - -@quickstart_1003_h2 -Embedding H2 in an Application - -@quickstart_1004_p - This database can be used in embedded mode, or in server mode. To use it in embedded mode, you need to: - -@quickstart_1005_li -Add the h2*.jar to the classpath (H2 does not have any dependencies) - -@quickstart_1006_li -Use the JDBC driver class: org.h2.Driver - -@quickstart_1007_li -The database URL jdbc:h2:~/test opens the database test in your user home directory - -@quickstart_1008_li -A new database is automatically created - -@quickstart_1009_h2 -The H2 Console Application - -@quickstart_1010_p - The Console lets you access a SQL database using a browser interface. - -@quickstart_1011_p - If you don't have Windows XP, or if something does not work as expected, please see the detailed description in the Tutorial. - -@quickstart_1012_h3 -Step-by-Step - -@quickstart_1013_h4 -Installation - -@quickstart_1014_p - Install the software using the Windows Installer (if you did not yet do that). - -@quickstart_1015_h4 -Start the Console - -@quickstart_1016_p - Click [Start], [All Programs], [H2], and [H2 Console (Command Line)]: - -@quickstart_1017_p - A new console window appears: - -@quickstart_1018_p - Also, a new browser page should open with the URL http://localhost:8082. You may get a security warning from the firewall. If you don't want other computers in the network to access the database on your machine, you can let the firewall block these connections. Only local connections are required at this time. - -@quickstart_1019_h4 -Login - -@quickstart_1020_p - Select [Generic H2] and click [Connect]: - -@quickstart_1021_p - You are now logged in. - -@quickstart_1022_h4 -Sample - -@quickstart_1023_p - Click on the [Sample SQL Script]: - -@quickstart_1024_p - The SQL commands appear in the command area. - -@quickstart_1025_h4 -Execute - -@quickstart_1026_p - Click [Run] - -@quickstart_1027_p - On the left side, a new entry TEST is added below the database icon. The operations and results of the statements are shown below the script. - -@quickstart_1028_h4 -Disconnect - -@quickstart_1029_p - Click on [Disconnect]: - -@quickstart_1030_p - to close the connection. - -@quickstart_1031_h4 -End - -@quickstart_1032_p - Close the console window. For more information, see the Tutorial. - -@roadmap_1000_h1 -Roadmap - -@roadmap_1001_p - New (feature) requests will usually be added at the very end of the list. The priority is increased for important and popular requests. Of course, patches are always welcome, but are not always applied as is. See also Providing Patches. - -@roadmap_1002_h2 -Version 1.3.x: Planned Changes - -@roadmap_1003_li -Enable h2.lobInDatabase (store CLOB and BLOB in the database file). - -@roadmap_1004_li -Set h2.analyzeAuto to 2000 (automatic ANALYZE). - -@roadmap_1005_li -Enable h2.functionsInSchema (allow to store functions in a schema). - -@roadmap_1006_li -Enable h2.selectForUpdateMvcc (MVCC and SELECT FOR UPDATE). - -@roadmap_1007_li -Enable h2.largeTransactions (support for very large transactions). Change documentation for MAX_MEMORY_UNDO in help.csv, because now changes to tables without a primary key can be buffered to disk. Later, change MAX_MEMORY_UNDO to reflect number of bytes instead of record (also remove Constants.UNDO_BLOCK_SIZE). Later, change undo log file format (fillAligned no longer required; var int). - -@roadmap_1008_h2 -Priority 1 - -@roadmap_1009_li -Bugfixes - -@roadmap_1010_li -Support very large transactions. Reduce memory usage of undo log (TestUndoLogMemory). - -@roadmap_1011_li -More tests with MULTI_THREADED=1 - -@roadmap_1012_li -Optimization: result set caching (like MySQL); option to disable - -@roadmap_1013_li -Server side cursors - -@roadmap_1014_h2 -Priority 2 - -@roadmap_1015_li -Support nested outer joins (see todo.txt, issues 145, 177, 203). - -@roadmap_1016_li -Improve test code coverage. - -@roadmap_1017_li -Test multi-threaded in-memory db access. - -@roadmap_1018_li -Full outer joins. - -@roadmap_1019_li -Clustering: support mixed clustering mode (one embedded, others in server mode). - -@roadmap_1020_li -Clustering: reads should be randomly distributed (optional) or to a designated database on RAM (parameter: READ_FROM=3). - -@roadmap_1021_li -PostgreSQL catalog: use BEFORE SELECT triggers instead of views over metadata tables. - -@roadmap_1022_li -Test very large databases and LOBs (up to 256 GB). - -@roadmap_1023_li -Support hints for the optimizer (which index to use, enforce the join order). - -@roadmap_1024_li -Sequence: add features [NO] MINVALUE, MAXVALUE, CYCLE. - -@roadmap_1025_li -Access rights: remember the owner of an object. Create, alter and drop privileges. COMMENT: allow owner of object to change it. - -@roadmap_1026_li -Deferred integrity checking (DEFERRABLE INITIALLY DEFERRED). - -@roadmap_1027_li -Groovy Stored Procedures: http://groovy.codehaus.org/Groovy+SQL - -@roadmap_1028_li -Add a migration guide (list differences between databases). - -@roadmap_1029_li -Migrate database tool (also from other database engines). - -@roadmap_1030_li -Optimization: automatic index creation suggestion using the trace file? - -@roadmap_1031_li -Compression performance: don't allocate buffers, compress / expand in to out buffer. - -@roadmap_1032_li -Rebuild index functionality to shrink index size and improve performance. - -@roadmap_1033_li -Don't use deleteOnExit (bug 4513817: File.deleteOnExit consumes memory). - -@roadmap_1034_li -Console: add accesskey to most important commands (A, AREA, BUTTON, INPUT, LABEL, LEGEND, TEXTAREA). - -@roadmap_1035_li -Test performance again with SQL Server, Oracle, DB2. - -@roadmap_1036_li -Test with Spatial DB in a box / JTS: http://www.opengeospatial.org/standards/sfs - OpenGIS Implementation Specification. - -@roadmap_1037_li -Write more tests and documentation for MVCC (Multi Version Concurrency Control). - -@roadmap_1038_li -Find a tool to view large text file (larger than 100 MB), with find, page up and down (like less), truncate before / after. - -@roadmap_1039_li -Implement, test, document XAConnection and so on. - -@roadmap_1040_li -Pluggable data type (for streaming, hashing, compression, validation, conversion, encryption). - -@roadmap_1041_li -CHECK: find out what makes CHECK=TRUE slow, move to CHECK2. - -@roadmap_1042_li -Index usage for (ID, NAME)=(1, 'Hi'); document. - -@roadmap_1043_li -Make DDL (Data Definition) operations transactional. - -@roadmap_1044_li -RANK() and DENSE_RANK(), Partition using OVER(). - -@roadmap_1045_li -Set a connection read only (Connection.setReadOnly) or using a connection parameter. - -@roadmap_1046_li -Optimizer: use an index for IS NULL and IS NOT NULL (including linked tables). ID IS NOT NULL could be converted to ID >= Integer.MIN_VALUE. - -@roadmap_1047_li -Access rights: finer grained access control (grant access for specific functions). - -@roadmap_1048_li -Version check: docs / web console (using Javascript), and maybe in the library (using TCP/IP). - -@roadmap_1049_li -Web server classloader: override findResource / getResourceFrom. - -@roadmap_1050_li -Cost for embedded temporary view is calculated wrong, if result is constant. - -@roadmap_1051_li -Comparison: pluggable sort order: natural sort. - -@roadmap_1052_li -Count index range query (count(*) where id between 10 and 20). - -@roadmap_1053_li -Performance: update in-place. - -@roadmap_1054_li -Recursive Queries (see details). - -@roadmap_1055_li -Eclipse plugin. - -@roadmap_1056_li -Asynchronous queries to support publish/subscribe: SELECT ... FOR READ WAIT [maxMillisToWait]. - -@roadmap_1057_li -Fulltext search Lucene: analyzer configuration. - -@roadmap_1058_li -Fulltext search (native): reader / tokenizer / filter. - -@roadmap_1059_li -Linked schema using CSV files: one schema for a directory of files; support indexes for CSV files. - -@roadmap_1060_li -iReport to support H2. - -@roadmap_1061_li -Implement missing JDBC API (CallableStatement,...). - -@roadmap_1062_li -Compression of the cache. - -@roadmap_1063_li -Include SMPT (mail) client (alert on cluster failure, low disk space,...). - -@roadmap_1064_li -Drop with restrict (currently cascade is the default). - -@roadmap_1065_li -JSON parser and functions. - -@roadmap_1066_li -Server: client ping from time to time (to avoid timeout - is timeout a problem?). - -@roadmap_1067_li -Copy database: tool with config GUI and batch mode, extensible (example: compare). - -@roadmap_1068_li -Document, implement tool for long running transactions using user-defined compensation statements. - -@roadmap_1069_li -Support SET TABLE DUAL READONLY. - -@roadmap_1070_li -GCJ: what is the state now? - -@roadmap_1071_li -Events for: database Startup, Connections, Login attempts, Disconnections, Prepare (after parsing), Web Server. See http://docs.openlinksw.com/virtuoso/fn_dbev_startup.html - -@roadmap_1072_li -Optimization: log compression. - -@roadmap_1073_li -ROW_NUMBER() OVER([ORDER BY columnName]). - -@roadmap_1074_li -Support standard INFORMATION_SCHEMA tables, as defined in http://www.contrib.andrew.cmu.edu/~shadow/sql/sql1992.txt - specially KEY_COLUMN_USAGE: http://dev.mysql.com/doc/refman/5.0/en/information-schema.html, http://www.xcdsql.org/Misc/INFORMATION_SCHEMA%20With%20Rolenames.gif - -@roadmap_1075_li -Compatibility: in MySQL, HSQLDB, /0.0 is NULL; in PostgreSQL, Derby: division by zero. - -@roadmap_1076_li -Functional tables should accept parameters from other tables (see FunctionMultiReturn) SELECT * FROM TEST T, P2C(T.A, T.R). - -@roadmap_1077_li -Custom class loader to reload functions on demand. - -@roadmap_1078_li -Clustering: when a database is back alive, automatically synchronize with the master. - -@roadmap_1079_li -Test http://mysql-je.sourceforge.net/ - -@roadmap_1080_li -Performance: automatically build in-memory indexes if the whole table is in memory. - -@roadmap_1081_li -H2 Console: the webclient could support more features like phpMyAdmin. - -@roadmap_1082_li -Use Janino to convert Java to C++. - -@roadmap_1083_li -The HELP information schema can be directly exposed in the Console. - -@roadmap_1084_li -Maybe use the 0x1234 notation for binary fields, see MS SQL Server. - -@roadmap_1085_li -Support Oracle CONNECT BY in some way: http://www.adp-gmbh.ch/ora/sql/connect_by.html http://philip.greenspun.com/sql/trees.html - -@roadmap_1086_li -SQL Server 2005, Oracle: support COUNT(*) OVER(). See http://www.orafusion.com/art_anlytc.htm - -@roadmap_1087_li -SQL 2003: http://www.wiscorp.com/sql_2003_standard.zip - -@roadmap_1088_li -Version column (number/sequence and timestamp based). - -@roadmap_1089_li -Optimize getGeneratedKey: send last identity after each execute (server). - -@roadmap_1090_li -Test and document UPDATE TEST SET (ID, NAME) = (SELECT ID*10, NAME || '!' FROM TEST T WHERE T.ID=TEST.ID). - -@roadmap_1091_li -Max memory rows / max undo log size: use block count / row size not row count. - -@roadmap_1092_li -Support 123L syntax as in Java; example: SELECT (2000000000*2). - -@roadmap_1093_li -Implement point-in-time recovery. - -@roadmap_1094_li -LIKE: improved version for larger texts (currently using naive search). - -@roadmap_1095_li -Automatically convert to the next 'higher' data type whenever there is an overflow. - -@roadmap_1096_li -Throw an exception when the application calls getInt on a Long (optional). - -@roadmap_1097_li -Default date format for input and output (local date constants). - -@roadmap_1098_li -Support custom Collators. - -@roadmap_1099_li -Document ROWNUM usage for reports: SELECT ROWNUM, * FROM (subquery). - -@roadmap_1100_li -File system that writes to two file systems (replication, replicating file system). - -@roadmap_1101_li -Standalone tool to get relevant system properties and add it to the trace output. - -@roadmap_1102_li -Support 'call proc(1=value)' (PostgreSQL, Oracle). - -@roadmap_1103_li -Console: improve editing data (Tab, Shift-Tab, Enter, Up, Down, Shift+Del?). - -@roadmap_1104_li -Console: autocomplete Ctrl+Space inserts template. - -@roadmap_1105_li -Option to encrypt .trace.db file. - -@roadmap_1106_li -Write Behind Cache on SATA leads to data corruption See also http://sr5tech.com/write_back_cache_experiments.htm and http://www.jasonbrome.com/blog/archives/2004/04/03/writecache_enabled.html - -@roadmap_1107_li -Functions with unknown return or parameter data types: serialize / deserialize. - -@roadmap_1108_li -Auto-Update feature for database, .jar file. - -@roadmap_1109_li -ResultSet SimpleResultSet.readFromURL(String url): id varchar, state varchar, released timestamp. - -@roadmap_1110_li -Partial indexing (see PostgreSQL). - -@roadmap_1111_li -Add GUI to build a custom version (embedded, fulltext,...) using build flags. - -@roadmap_1112_li -http://rubyforge.org/projects/hypersonic/ - -@roadmap_1113_li -Add comparator (x === y) : (x = y or (x is null and y is null)). - -@roadmap_1114_li -Add a sample application that runs the H2 unit test and writes the result to a file (so it can be included in the user app). - -@roadmap_1115_li -Count on a column that can not be null could be optimized to COUNT(*). - -@roadmap_1116_li -Table order: ALTER TABLE TEST ORDER BY NAME DESC (MySQL compatibility). - -@roadmap_1117_li -Issue 159: System property for the H2 Console and TCP configuration (which .h2.server.properties and .h2.keystore to use). - -@roadmap_1118_li -Backup tool should work with other databases as well. - -@roadmap_1119_li -Console: -ifExists doesn't work for the console. Add a flag to disable other dbs. - -@roadmap_1120_li -Check if 'FSUTIL behavior set disablelastaccess 1' improves the performance (fsutil behavior query disablelastaccess). - -@roadmap_1121_li -Java static code analysis: http://pmd.sourceforge.net/ - -@roadmap_1122_li -Java static code analysis: http://www.eclipse.org/tptp/ - -@roadmap_1123_li -Compatibility for CREATE SCHEMA AUTHORIZATION. - -@roadmap_1124_li -Implement Clob / Blob truncate and the remaining functionality. - -@roadmap_1125_li -Tree join functionality. - -@roadmap_1126_li -Add multiple columns at the same time with ALTER TABLE .. ADD .. ADD ... - -@roadmap_1127_li -Use JDK 1.4 file locking for the database file and for the lock file (but not yet by default); writing a system property to detect concurrent access from the same VM (different classloaders). - -@roadmap_1128_li -Pure SQL triggers (example: update parent table if the child table is changed). - -@roadmap_1129_li -Add H2 to Gem (Ruby install system). - -@roadmap_1130_li -Order conditions inside AND / OR to optimize the performance. - -@roadmap_1131_li -Support Oracle functions: TRUNC, NVL2, TO_CHAR, TO_DATE, TO_NUMBER. - -@roadmap_1132_li -Support linked JCR tables - -@roadmap_1133_li -Read InputStream when executing, as late as possible (maybe only embedded mode). Problem with re-execute. - -@roadmap_1134_li -Native fulltext search: min word length; store word positions - -@roadmap_1135_li -Add an option to the SCRIPT command to generate only portable / standard SQL - -@roadmap_1136_li -Updatable Views (simple cases first) - -@roadmap_1137_li -Improve create index performance - -@roadmap_1138_li -Implement more JDBC 4.0 features - -@roadmap_1139_li -Support TRANSFORM / PIVOT as in MS Access - -@roadmap_1140_li -SELECT * FROM (VALUES (...), (...), ....) AS alias(f1, ...) - -@roadmap_1141_li -Support updatable views with join on primary keys (to extend a table) - -@roadmap_1142_li -Public interface for functions (not public static) - -@roadmap_1143_li -Support reading the transaction log. - -@roadmap_1144_li -Eliminate undo log records if stored on disk (just one pointer per block, not per record) - -@roadmap_1145_li -Feature matrix as in i-net software. - -@roadmap_1146_li -Updatable result set on table without primary key or unique index. - -@roadmap_1147_li -Use LinkedList instead of ArrayList where applicable. - -@roadmap_1148_li -Allow execution time prepare for SELECT * FROM CSVREAD(?, 'columnNameString') - -@roadmap_1149_li -Support % operator (modulo). - -@roadmap_1150_li -Support JMX: create an MBean for each database and server (support JConsole). See http://thedevcloud.blogspot.com/2008/10/displaying-hsql-database-manager-in.html http://java.sun.com/j2se/1.5.0/docs/api/java/lang/management/ManagementFactory.html#getPlatformMBeanServer() http://java.sun.com/j2se/1.5.0/docs/guide/management/agent.html - -@roadmap_1151_li -Support nested transactions. - -@roadmap_1152_li -Add a benchmark for big databases, and one for many users. - -@roadmap_1153_li -Compression in the result set (repeating values in the same column) over TCP/IP. - -@roadmap_1154_li -Support curtimestamp (like curtime, curdate). - -@roadmap_1155_li -Support ANALYZE {TABLE|INDEX} tableName COMPUTE|ESTIMATE|DELETE STATISTICS ptnOption options. - -@roadmap_1156_li -Release locks (shared or exclusive) on demand - -@roadmap_1157_li -Support OUTER UNION - -@roadmap_1158_li -Support parameterized views (similar to CSVREAD, but using just SQL for the definition) - -@roadmap_1159_li -A way (JDBC driver) to map an URL (jdbc:h2map:c1) to a connection object - -@roadmap_1160_li -Option for SCRIPT to only process one or a set of tables, and append to a file - -@roadmap_1161_li -Support linked tables to the current database - -@roadmap_1162_li -Support dynamic linked schema (automatically adding/updating/removing tables) - -@roadmap_1163_li -Clustering: adding a node should be very fast and without interrupting clients (very short lock) - -@roadmap_1164_li -Compatibility with Derby: VALUES(1), (2); SELECT * FROM (VALUES (1), (2)) AS myTable(c1) - -@roadmap_1165_li -Compatibility: # is the start of a single line comment (MySQL) but date quote (Access). Mode specific - -@roadmap_1166_li -Run benchmarks with JDK 1.5, JDK 1.6, java -server - -@roadmap_1167_li -Optimizations: faster hash function for strings, byte arrays - -@roadmap_1168_li -DatabaseEventListener: callback for all operations (including expected time, RUNSCRIPT) and cancel functionality - -@roadmap_1169_li -Benchmark: add a graph to show how databases scale (performance/database size) - -@roadmap_1170_li -Implement a SQLData interface to map your data over to a custom object - -@roadmap_1171_li -In the MySQL and PostgreSQL mode, use lower case identifiers by default (DatabaseMetaData.storesLowerCaseIdentifiers = true) - -@roadmap_1172_li -Support multiple directories (on different hard drives) for the same database - -@roadmap_1173_li -Server protocol: use challenge response authentication, but client sends hash(user+password) encrypted with response - -@roadmap_1174_li -Support EXEC[UTE] (doesn't return a result set, compatible to MS SQL Server) - -@roadmap_1175_li -Support native XML data type - -@roadmap_1176_li -Support triggers with a string property or option: SpringTrigger, OSGITrigger - -@roadmap_1177_li -Ability to resize the cache array when resizing the cache - -@roadmap_1178_li -Time based cache writing (one second after writing the log) - -@roadmap_1179_li -Check state of H2 driver for DDLUtils: https://issues.apache.org/jira/browse/DDLUTILS-185 - -@roadmap_1180_li -Index usage for REGEXP LIKE. - -@roadmap_1181_li -Compatibility: add a role DBA (like ADMIN). - -@roadmap_1182_li -Better support multiple processors for in-memory databases. - -@roadmap_1183_li -Support N'text' - -@roadmap_1184_li -Support compatibility for jdbc:hsqldb:res: - -@roadmap_1185_li -Provide an Java SQL builder with standard and H2 syntax - -@roadmap_1186_li -Trace: write OS, file system, JVM,... when opening the database - -@roadmap_1187_li -Support indexes for views (probably requires materialized views) - -@roadmap_1188_li -Document SET SEARCH_PATH, BEGIN, EXECUTE, parameters - -@roadmap_1189_li -Browser: use Desktop.isDesktopSupported and browse when using JDK 1.6 - -@roadmap_1190_li -Server: use one listener (detect if the request comes from an PG or TCP client) - -@roadmap_1191_li -Support data type INTERVAL - -@roadmap_1192_li -Optimize SELECT MIN(ID), MAX(ID), COUNT(*) FROM TEST WHERE ID BETWEEN 100 AND 200 - -@roadmap_1193_li -Sequence: PostgreSQL compatibility (rename, create) http://www.postgresql.org/docs/8.2/static/sql-altersequence.html - -@roadmap_1194_li -DISTINCT: support large result sets by sorting on all columns (additionally) and then removing duplicates. - -@roadmap_1195_li -Support a special trigger on all tables to allow building a transaction log reader. - -@roadmap_1196_li -File system with a background writer thread; test if this is faster - -@roadmap_1197_li -Better document the source code - -@roadmap_1198_li -Support select * from dual a left join dual b on b.x=(select max(x) from dual) - -@roadmap_1199_li -Optimization: don't lock when the database is read-only - -@roadmap_1200_li -Issue 146: Support merge join. - -@roadmap_1201_li -Integrate spatial functions from http://geosysin.iict.ch/irstv-trac/wiki/H2spatial/Download - -@roadmap_1202_li -Cluster: hot deploy (adding a node at runtime) - -@roadmap_1203_li -Compact databases without having to close the database (vacuum). - -@roadmap_1204_li -Support COSH, SINH, and TANH functions - -@roadmap_1205_li -Oracle: support DECODE method (convert to CASE WHEN). - -@roadmap_1206_li -Native search: support "phrase search", wildcard search (* and ?), case-insensitive search, boolean operators, and grouping - -@roadmap_1207_li -Improve documentation of access rights - -@roadmap_1208_li -Support ENUM data type (see MySQL, PostgreSQL, MS SQL Server, maybe others) - -@roadmap_1209_li -Remember the user defined data type (domain) of a column - -@roadmap_1210_li -Support Jackcess (MS Access databases) - -@roadmap_1211_li -Built-in methods to write large objects (BLOB and CLOB): FILE_WRITE('test.txt', 'Hello World') - -@roadmap_1212_li -MVCC: support transactionally consistent backups using SCRIPT - -@roadmap_1213_li -Improve time to open large databases (see mail 'init time for distributed setup') - -@roadmap_1214_li -Move Maven 2 repository from hsql.sf.net to h2database.sf.net - -@roadmap_1215_li -Java 1.5 tool: JdbcUtils.closeSilently(s1, s2,...) - -@roadmap_1216_li -Javadoc: document design patterns used - -@roadmap_1217_li -Write an article about SQLInjection (h2/src/docsrc/html/images/SQLInjection.txt) - -@roadmap_1218_li -Convert SQL-injection-2.txt to html document, include SQLInjection.java sample - -@roadmap_1219_li -Support OUT parameters in user-defined procedures. - -@roadmap_1220_li -Web site design: http://www.igniterealtime.org/projects/openfire/index.jsp - -@roadmap_1221_li -HSQLDB compatibility: Openfire server uses: CREATE SCHEMA PUBLIC AUTHORIZATION DBA; CREATE USER SA PASSWORD ""; GRANT DBA TO SA; SET SCHEMA PUBLIC - -@roadmap_1222_li -Translation: use ?? in help.csv - -@roadmap_1223_li -Translated .pdf - -@roadmap_1224_li -MySQL compatibility: update test1 t1, test2 t2 set t1.id = t2.id where t1.id = t2.id; - -@roadmap_1225_li -Recovery tool: bad blocks should be converted to INSERT INTO SYSTEM_ERRORS(...), and things should go into the .trace.db file - -@roadmap_1226_li -RECOVER=2 to backup the database, run recovery, open the database - -@roadmap_1227_li -Recovery should work with encrypted databases - -@roadmap_1228_li -Corruption: new error code, add help - -@roadmap_1229_li -Space reuse: after init, scan all storages and free those that don't belong to a live database object - -@roadmap_1230_li -Use FilterIn / FilterOut putStream? - -@roadmap_1231_li -Access rights: add missing features (users should be 'owner' of objects; missing rights for sequences; dropping objects) - -@roadmap_1232_li -Support NOCACHE table option (Oracle). - -@roadmap_1233_li -Support table partitioning. - -@roadmap_1234_li -Index usage for UPDATE ... WHERE .. IN (SELECT...) - -@roadmap_1235_li -Add regular javadocs (using the default doclet, but another css) to the homepage. - -@roadmap_1236_li -The database should be kept open for a longer time when using the server mode. - -@roadmap_1237_li -Javadocs: for each tool, add a copy & paste sample in the class level. - -@roadmap_1238_li -Javadocs: add @author tags. - -@roadmap_1239_li -Fluent API for tools: Server.createTcpServer().setPort(9081).setPassword(password).start(); - -@roadmap_1240_li -MySQL compatibility: real SQL statement for DESCRIBE TEST - -@roadmap_1241_li -Use a default delay of 1 second before closing a database. - -@roadmap_1242_li -Write (log) to system table before adding to internal data structures. - -@roadmap_1243_li -Support very large deletes and updates. - -@roadmap_1244_li -Doclet (javadocs): constructors are not listed. - -@roadmap_1245_li -Support direct lookup for MIN and MAX when using WHERE (see todo.txt / Direct Lookup). - -@roadmap_1246_li -Support other array types (String[], double[]) in PreparedStatement.setObject(int, Object); - -@roadmap_1247_li -MVCC should not be memory bound (uncommitted data is kept in memory in the delta index; maybe using a regular b-tree index solves the problem). - -@roadmap_1248_li -Oracle compatibility: support NLS_DATE_FORMAT. - -@roadmap_1249_li -Cluster: add feature to make sure cluster nodes can not get out of sync (for example by stopping one process). - -@roadmap_1250_li -H2 Console: support CLOB/BLOB download using a link. - -@roadmap_1251_li -Support flashback queries as in Oracle. - -@roadmap_1252_li -Import / Export of fixed with text files. - -@roadmap_1253_li -Support getGeneratedKeys to return multiple rows when used with batch updates. This is supported by MySQL, but not Derby. Both PostgreSQL and HSQLDB don't support getGeneratedKeys. Also support it when using INSERT ... SELECT. - -@roadmap_1254_li -HSQLDB compatibility: automatic data type for SUM if value is the value is too big (by default use the same type as the data). - -@roadmap_1255_li -Improve the optimizer to select the right index for special cases: where id between 2 and 4 and booleanColumn - -@roadmap_1256_li -Linked tables: make hidden columns available (Oracle: rowid and ora_rowscn columns). - -@roadmap_1257_li -H2 Console: in-place autocomplete. - -@roadmap_1258_li -Support large databases: split database files to multiple directories / disks (similar to tablespaces). - -@roadmap_1259_li -Support to assign a primary key index a user defined name. - -@roadmap_1260_li -H2 Console: support configuration option for fixed width (monospace) font. - -@roadmap_1261_li -Native fulltext search: support analyzers (specially for Chinese, Japanese). - -@roadmap_1262_li -Automatically compact databases from time to time (as a background process). - -@roadmap_1263_li -Support GRANT SELECT, UPDATE ON *. - -@roadmap_1264_li -Test Eclipse DTP. - -@roadmap_1265_li -H2 Console: autocomplete: keep the previous setting - -@roadmap_1266_li -MySQL, MS SQL Server compatibility: support case sensitive (mixed case) identifiers without quotes. - -@roadmap_1267_li -executeBatch: option to stop at the first failed statement. - -@roadmap_1268_li -Implement OLAP features as described here: http://www.devx.com/getHelpOn/10MinuteSolution/16573/0/page/5 - -@roadmap_1269_li -Support Oracle ROWID (unique identifier for each row). - -@roadmap_1270_li -Server mode: improve performance for batch updates. - -@roadmap_1271_li -Applets: support read-only databases in a zip file (accessed as a resource). - -@roadmap_1272_li -Long running queries / errors / trace system table. - -@roadmap_1273_li -H2 Console should support JaQu directly. - -@roadmap_1274_li -H2 Console: support single file upload and directory download (optional). - -@roadmap_1275_li -Document FTL_SEARCH, FTL_SEARCH_DATA. - -@roadmap_1276_li -Sequences: CURRVAL should be session specific. Compatibility with PostgreSQL. - -@roadmap_1277_li -Support DatabaseMetaData.insertsAreDetected: updatable result sets should detect inserts. - -@roadmap_1278_li -Auto-server: add option to define the IP address range or list. - -@roadmap_1279_li -Index creation using deterministic functions. - -@roadmap_1280_li -Support DELETE with TOP or LIMIT. See also: http://dev.mysql.com/doc/refman/5.1/de/delete.html - -@roadmap_1281_li -ANALYZE: for unique indexes that allow null, count the number of null. - -@roadmap_1282_li -AUTO_SERVER: support changing IP addresses (disable a network while the database is open). - -@roadmap_1283_li -Avoid using java.util.Calendar internally because it's slow, complicated, and buggy. - -@roadmap_1284_li -Support TRUNCATE .. CASCADE like PostgreSQL. - -@roadmap_1285_li -Support opening a database that is in the classpath, maybe using a new file system. - -@roadmap_1286_li -Fulltext search: lazy result generation using SimpleRowSource. - -@roadmap_1287_li -Support transformation to join for user defined functions, as for IN(SELECT...). - -@roadmap_1288_li -Fulltext search: support alternative syntax: WHERE FTL_CONTAINS(name, 'hello'). - -@roadmap_1289_li -MySQL compatibility: support REPLACE, see http://dev.mysql.com/doc/refman/5.1/de/replace.html - -@roadmap_1290_li -MySQL compatibility: support INSERT INTO table SET column1 = value1, column2 = value2 - -@roadmap_1291_li -Docs: add a one line description for each functions and SQL statements at the top (in the link section). - -@roadmap_1292_li -Javadoc search: weight for titles should be higher ('random' should list Functions as the best match). - -@roadmap_1293_li -Replace information_schema tables with regular tables that are automatically re-built when needed. Use indexes. - -@roadmap_1294_li -Delete temporary files or objects using finalize. - -@roadmap_1295_li -Oracle compatibility: support calling 0-parameters functions without parenthesis. Make constants obsolete. - -@roadmap_1296_li -MySQL, HSQLDB compatibility: support where 'a'=1 (not supported by Derby, PostgreSQL) - -@roadmap_1297_li -Allow calling function with no parameters without parenthesis. See http://code.google.com/p/h2database/issues/detail?id=50 - -@roadmap_1298_li -CSV: currently # is a line comment and can start at any field. Make it optional. - -@roadmap_1299_li -Finer granularity for SLF4J trace - See http://code.google.com/p/h2database/issues/detail?id=62 - -@roadmap_1300_li -Add database creation date and time to the database. - -@roadmap_1301_li -Support ASSERTIONS. - -@roadmap_1302_li -Support multi-threaded kernel with multi-version concurrency. - -@roadmap_1303_li -MySQL compatibility: support comparing 1='a' - -@roadmap_1304_li -Support PostgreSQL lock modes: http://www.postgresql.org/docs/8.3/static/explicit-locking.html - -@roadmap_1305_li -PostgreSQL compatibility: test DbVisualizer and Squirrel SQL using a new PostgreSQL JDBC driver. - -@roadmap_1306_li -RunScript should be able to read from system in (or quite mode for Shell). - -@roadmap_1307_li -Natural join: support select x from dual natural join dual. - -@roadmap_1308_li -Natural join: somehow support this: select a.x, b.x, x from dual a natural join dual b - -@roadmap_1309_li -Use the Java service provider mechanism to register file systems and function libraries. - -@roadmap_1310_li -MySQL compatibility: for auto_increment columns, convert 0 to next value (as when inserting NULL). - -@roadmap_1311_li -Optimization for multi-column IN: use an index if possible. Example: (A, B) IN((1, 2), (2, 3)). - -@roadmap_1312_li -Optimization for EXISTS: convert to inner join or IN(..) if possible. - -@roadmap_1313_li -Functions: support hashcode(value); cryptographic and fast - -@roadmap_1314_li -Serialized file lock: support long running queries. - -@roadmap_1315_li -Network: use 127.0.0.1 if other addresses don't work. - -@roadmap_1316_li -Pluggable network protocol (currently Socket/ServerSocket over TCP/IP) - see also TransportServer with master slave replication. - -@roadmap_1317_li -Select for update in mvcc mode: only lock the selected records. - -@roadmap_1318_li -Support reading JCR data: one table per node type; query table; cache option - -@roadmap_1319_li -OSGi: create a sample application, test, document. - -@roadmap_1320_li -help.csv: use complete examples for functions; run as test case. - -@roadmap_1321_li -Functions to calculate the memory and disk space usage of a table, a row, or a value. - -@roadmap_1322_li -Re-implement PooledConnection; use a lightweight connection object. - -@roadmap_1323_li -Doclet: convert tests in javadocs to a java class. - -@roadmap_1324_li -Doclet: format fields like methods, but support sorting by name and value. - -@roadmap_1325_li -Doclet: shrink the html files. - -@roadmap_1326_li -MySQL compatibility: support REPLACE - See http://code.google.com/p/h2database/issues/detail?id=73 - -@roadmap_1327_li -MySQL compatibility: support SET NAMES 'latin1' - See also http://code.google.com/p/h2database/issues/detail?id=56 - -@roadmap_1328_li -MySQL compatibility: DELETE .. FROM .. USING - See http://dev.mysql.com/doc/refman/5.0/en/delete.html - -@roadmap_1329_li -Allow to scan index backwards starting with a value (to better support ORDER BY DESC). - -@roadmap_1330_li -Java Service Wrapper: try http://yajsw.sourceforge.net/ - -@roadmap_1331_li -Batch parameter for INSERT, UPDATE, and DELETE, and commit after each batch. See also MySQL DELETE. - -@roadmap_1332_li -MySQL compatibility: support ALTER TABLE .. MODIFY COLUMN. - -@roadmap_1333_li -Use a lazy and auto-close input stream (open resource when reading, close on eof). - -@roadmap_1334_li -PostgreSQL compatibility: generate_series. - -@roadmap_1335_li -Connection pool: 'reset session' command (delete temp tables, rollback, autocommit true). - -@roadmap_1336_li -Improve SQL documentation, see http://www.w3schools.com/sql/ - -@roadmap_1337_li -MySQL compatibility: DatabaseMetaData.stores*() methods should return the same values. Test with SquirrelSQL. - -@roadmap_1338_li -MS SQL Server compatibility: support DATEPART syntax. - -@roadmap_1339_li -Oracle compatibility: support CREATE OR REPLACE VIEW syntax. - -@roadmap_1340_li -Sybase/DB2/Oracle compatibility: support out parameters in stored procedures - See http://code.google.com/p/h2database/issues/detail?id=83 - -@roadmap_1341_li -Support INTERVAL data type (see Oracle and others). - -@roadmap_1342_li -Combine Server and Console tool (only keep Server). - -@roadmap_1343_li -Store the Lucene index in the database itself. - -@roadmap_1344_li -Support standard MERGE statement: http://en.wikipedia.org/wiki/Merge_%28SQL%29 - -@roadmap_1345_li -Oracle compatibility: support DECODE(x, ...). - -@roadmap_1346_li -Console: Start Browser: if ip number changed, try localhost instead. - -@roadmap_1347_li -MVCC: compare concurrent update behavior with PostgreSQL and Oracle. - -@roadmap_1348_li -HSQLDB compatibility: CREATE FUNCTION (maybe using a Function interface). - -@roadmap_1349_li -HSQLDB compatibility: support CALL "java.lang.Math.sqrt"(2.0) - -@roadmap_1350_li -Support comma as the decimal separator in the CSV tool. - -@roadmap_1351_li -Compatibility: Support jdbc:default:connection using ThreadLocal (part of SQLJ) - -@roadmap_1352_li -Compatibility: Java functions with SQLJ Part1 http://www.acm.org/sigmod/record/issues/9912/standards.pdf.gz - -@roadmap_1353_li -Compatibility: Java functions with SQL/PSM (Persistent Stored Modules) - need to find the documentation. - -@roadmap_1354_li -CACHE_SIZE: automatically use a fraction of Runtime.maxMemory - maybe automatically the second level cache. - -@roadmap_1355_li -Support date/time/timestamp as documented in http://en.wikipedia.org/wiki/ISO_8601 - -@roadmap_1356_li -PostgreSQL compatibility: when in PG mode, treat BYTEA data like PG. - -@roadmap_1357_li -MySQL compatibility: REPLACE http://dev.mysql.com/doc/refman/6.0/en/replace.html - -@roadmap_1358_li -Support =ANY(array) as in PostgreSQL. See also http://www.postgresql.org/docs/8.0/interactive/arrays.html - -@roadmap_1359_li -IBM DB2 compatibility: support PREVIOUS VALUE FOR sequence. - -@roadmap_1360_li -MySQL compatibility: alter table add index i(c), add constraint c foreign key(c) references t(c); - -@roadmap_1361_li -Compatibility: use different LIKE ESCAPE characters depending on the mode (disable for Derby, HSQLDB, DB2, Oracle, MSSQLServer). - -@roadmap_1362_li -Oracle compatibility: support CREATE SYNONYM table FOR schema.table. - -@roadmap_1363_li -Optimize A=? OR B=? to UNION if the cost is lower. - -@roadmap_1364_li -FTP: document the server, including -ftpTask option to execute / kill remote processes - -@roadmap_1365_li -FTP: problems with multithreading? - -@roadmap_1366_li -FTP: implement SFTP / FTPS - -@roadmap_1367_li -FTP: access to a database (.csv for a table, a directory for a schema, a file for a lob, a script.sql file). - -@roadmap_1368_li -More secure default configuration if remote access is enabled. - -@roadmap_1369_li -Improve database file locking (maybe use native file locking). The current approach seems to be problematic if the file system is on a remote share (see Google Group 'Lock file modification time is in the future'). - -@roadmap_1370_li -Document internal features such as BELONGS_TO_TABLE, NULL_TO_DEFAULT, SEQUENCE. - -@roadmap_1371_li -Issue 107: Prefer using the ORDER BY index if LIMIT is used. - -@roadmap_1372_li -An index on (id, name) should be used for a query: select * from t where s=? order by i - -@roadmap_1373_li -Support reading sequences using DatabaseMetaData.getTables(null, null, null, new String[]{"SEQUENCE"}). See PostgreSQL. - -@roadmap_1374_li -Add option to enable TCP_NODELAY using Socket.setTcpNoDelay(true). - -@roadmap_1375_li -Maybe disallow = within database names (jdbc:h2:mem:MODE=DB2 means database name MODE=DB2). - -@roadmap_1376_li -Fast alter table add column. - -@roadmap_1377_li -Improve concurrency for in-memory database operations. - -@roadmap_1378_li -Issue 122: Support for connection aliases for remote tcp connections. - -@roadmap_1379_li -Fast scrambling (strong encryption doesn't help if the password is included in the application). - -@roadmap_1380_li -Support using system properties in database URLs (may be a security problem). - -@roadmap_1381_li -Issue 126: The index name should be "IDX_" plus the constraint name unless there is a conflict, in which case append a number. - -@roadmap_1382_li -Issue 127: Support activation/deactivation of triggers - -@roadmap_1383_li -Issue 130: Custom log event listeners - -@roadmap_1384_li -Issue 131: IBM DB2 compatibility: sysibm.sysdummy1 - -@roadmap_1385_li -Issue 132: Use Java enum trigger type. - -@roadmap_1386_li -Issue 134: IBM DB2 compatibility: session global variables. - -@roadmap_1387_li -Cluster: support load balance with values for each server / auto detect. - -@roadmap_1388_li -FTL_SET_OPTION(keyString, valueString) with key stopWords at first. - -@roadmap_1389_li -Pluggable access control mechanism. - -@roadmap_1390_li -Fulltext search (Lucene): support streaming CLOB data. - -@roadmap_1391_li -Document/example how to create and read an encrypted script file. - -@roadmap_1392_li -Check state of https://issues.apache.org/jira/browse/OPENJPA-1367 (H2 does support cross joins). - -@roadmap_1393_li -Fulltext search (Lucene): only prefix column names with _ if they already start with _. Instead of DATA / QUERY / modified use _DATA, _QUERY, _MODIFIED if possible. - -@roadmap_1394_li -Support a way to create or read compressed encrypted script files using an API. - -@roadmap_1395_li -Scripting language support (Javascript). - -@roadmap_1396_li -The network client should better detect if the server is not an H2 server and fail early. - -@roadmap_1397_li -H2 Console: support CLOB/BLOB upload. - -@roadmap_1398_li -Move away from system properties where possible. - -@roadmap_1399_li -Database file lock: detect hibernate / standby / very slow threads (compare system time). - -@roadmap_1400_li -Automatic detection of redundant indexes. - -@roadmap_1401_li -Maybe reject join without "on" (except natural join). - -@roadmap_1402_li -Implement GiST (Generalized Search Tree for Secondary Storage). - -@roadmap_1403_li -Function to read a number of bytes/characters from an BLOB or CLOB. - -@roadmap_1404_li -Issue 156: Support SELECT ? UNION SELECT ?. - -@roadmap_1405_li -Automatic mixed mode: support a port range list (to avoid firewall problems). - -@roadmap_1406_li -Support the pseudo column rowid, oid, _rowid_. - -@roadmap_1407_li -H2 Console / large result sets: stream early instead of keeping a whole result in-memory - -@roadmap_1408_li -Support TRUNCATE for linked tables. - -@roadmap_1409_li -UNION: evaluate INTERSECT before UNION (like most other database except Oracle). - -@roadmap_1410_li -Delay creating the information schema, and share metadata columns. - -@roadmap_1411_li -TCP Server: use a nonce (number used once) to protect unencrypted channels against replay attacks. - -@roadmap_1412_li -Simplify running scripts and recovery: CREATE FORCE USER (overwrites an existing user). - -@roadmap_1413_li -Support CREATE DATABASE LINK (a custom JDBC driver is already supported). - -@roadmap_1414_li -Issue 163: Allow to create foreign keys on metadata types. - -@roadmap_1415_li -Logback: write a native DBAppender. - -@roadmap_1416_li -Cache size: don't use more cache than what is available. - -@roadmap_1417_li -Tree index: Instead of an AVL tree, use a general balanced trees or a scapegoat tree. - -@roadmap_1418_li -User defined functions: allow to store the bytecode (of just the class, or the jar file of the extension) in the database. - -@roadmap_1419_li -Compatibility: ResultSet.getObject() on a CLOB (TEXT) should return String for PostgreSQL and MySQL. - -@roadmap_1420_li -Optimizer: WHERE X=? AND Y IN(?), it always uses the index on Y. Should be cost based. - -@roadmap_1421_li -Support ALTER SCHEMA name RENAME TO newName (rename schema). - -@roadmap_1422_li -Make the cache scan resistant (currently a small cache is faster than a large cache for large table scans). - -@roadmap_1423_li -Issue 178: Optimizer: index usage when both ascending and descending indexes are available - -@roadmap_1424_li -Issue 179: Related subqueries in HAVING clause - -@roadmap_1425_li -IBM DB2 compatibility: NOT NULL WITH DEFAULT. Similar to MySQL Mode.convertInsertNullToZero. - -@roadmap_1426_li -Creating primary key: always create a constraint. - -@roadmap_1427_li -Support a data type "timestamp with timezone" using java.util.Calendar. - -@roadmap_1428_li -Maybe use a different page layout: keep the data at the head of the page, and ignore the tail (don't store / read it). This may increase write / read performance depending on the file system. - -@roadmap_1429_li -Indexes of temporary tables are currently kept in-memory. Is this how it should be? - -@roadmap_1430_li -The Shell tool should support the same built-in commands as the H2 Console. - -@roadmap_1431_li -Maybe use PhantomReference instead of finalize. - -@roadmap_1432_li -Database file name suffix: a way to use no or a different suffix (for example using a slash). - -@roadmap_1433_li -Database file name suffix: should only have one dot by default. Example: .h2db - -@roadmap_1434_li -Issue 196: Function based indexes - -@roadmap_1435_li -Fix the disk space leak (killing the process at the exact right moment will increase the disk space usage; this space is not re-used). See TestDiskSpaceLeak.java - -@roadmap_1436_li -ROWNUM: Oracle compatibility when used within a subquery. Issue 198. - -@roadmap_1437_li -Allow to access the database over HTTP (possibly using port 80) and a servlet in a REST way. - -@roadmap_1438_li -ODBC: encrypted databases are not supported because the ;CIPHER= can not be set. - -@roadmap_1439_li -Support CLOB and BLOB update, specially conn.createBlob().setBinaryStream(1); - -@roadmap_1440_li -Triggers: support user defined execution order. Oracle: CREATE OR REPLACE TRIGGER TEST_2 BEFORE INSERT ON TEST FOR EACH ROW FOLLOWS TEST_1. SQL specifies that multiple triggers should be fired in time-of-creation order. PostgreSQL uses name order, which was judged to be more convenient. Derby: triggers are fired in the order in which they were created. - -@roadmap_1441_li -PostgreSQL compatibility: combine "users" and "roles". See: http://www.postgresql.org/docs/8.1/interactive/user-manag.html - -@roadmap_1442_li -Support NULL with a type: @meta CALL CAST(NULL AS INT) should return INT. See the ValueExpression.java (currently it returns the type of the value; it could have it's own type/precision/scale optionally, for example when created from CAST, which is implemented in Function.java). - -@roadmap_1443_li -Improve documentation of system properties: only list the property names, default values, and description. - -@roadmap_1444_li -Support running totals / cumulative sum using SUM(..) OVER(..). - -@roadmap_1445_li -Improve object memory size calculation. Use constants for known VMs, or use reflection to call java.lang.instrument.Instrumentation.getObjectSize(Object objectToSize) - -@roadmap_1446_h2 -Not Planned - -@roadmap_1447_li -HSQLDB (did) support this: select id i from test where i<0 (other databases don't). Supporting it may break compatibility. - -@roadmap_1448_li -String.intern (so that Strings can be compared with ==) will not be used because some VMs have problems when used extensively. - -@roadmap_1449_li -In prepared statements, identifier names (table names and so on) can not be parameterized. Adding such a feature would complicate the source code without providing reasonable speedup, and would slow down regular prepared statements. - -@sourceError_1000_h1 -Error Analyzer - -@sourceError_1001_a -Home - -@sourceError_1002_a -Input - -@sourceError_1003_h2 -  Details  Source Code - -@sourceError_1004_p -Paste the error message and stack trace below and click on 'Details' or 'Source Code': - -@sourceError_1005_b -Error Code: - -@sourceError_1006_b -Product Version: - -@sourceError_1007_b -Message: - -@sourceError_1008_b -More Information: - -@sourceError_1009_b -Stack Trace: - -@sourceError_1010_b -Source File: - -@sourceError_1011_p - Raw file - -@sourceError_1012_p - (fast; only Firefox) - -@tutorial_1000_h1 -Tutorial - -@tutorial_1001_a - Starting and Using the H2 Console - -@tutorial_1002_a - Special H2 Console Syntax - -@tutorial_1003_a - Settings of the H2 Console - -@tutorial_1004_a - Connecting to a Database using JDBC - -@tutorial_1005_a - Creating New Databases - -@tutorial_1006_a - Using the Server - -@tutorial_1007_a - Using Hibernate - -@tutorial_1008_a - Using TopLink and Glassfish - -@tutorial_1009_a - Using EclipseLink - -@tutorial_1010_a - Using Databases in Web Applications - -@tutorial_1011_a - CSV (Comma Separated Values) Support - -@tutorial_1012_a - Upgrade, Backup, and Restore - -@tutorial_1013_a - Command Line Tools - -@tutorial_1014_a - The Shell Tool - -@tutorial_1015_a - Using OpenOffice Base - -@tutorial_1016_a - Java Web Start / JNLP - -@tutorial_1017_a - Using a Connection Pool - -@tutorial_1018_a - Fulltext Search - -@tutorial_1019_a - User-Defined Variables - -@tutorial_1020_a - Date and Time - -@tutorial_1021_a - Using Spring - -@tutorial_1022_h2 -Starting and Using the H2 Console - -@tutorial_1023_p - The H2 Console 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. - -@tutorial_1024_p - This is a client / server application, so both a server and a client (a browser) are required to run it. - -@tutorial_1025_p - Depending on your platform and environment, there are multiple ways to start the application: - -@tutorial_1026_th -OS - -@tutorial_1027_th -Start - -@tutorial_1028_td -Windows - -@tutorial_1029_td - Click [Start], [All Programs], [H2], and [H2 Console (Command Line)] - -@tutorial_1030_td - When using the Sun JDK 1.5, a window with the title 'H2 Console ' should appear. When using the Sun JDK 1.6, an icon will be added to the system tray: - -@tutorial_1031_td - If you don't get the window and 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 at http://localhost:8082. - -@tutorial_1032_td -Windows - -@tutorial_1033_td - Open a file browser, navigate to h2/bin, and double click on h2.bat. - -@tutorial_1034_td - A console window appears. If there is a problem, you will see an error message in this window. A browser window will open and point to the Login page (URL: http://localhost:8082). - -@tutorial_1035_td -Any - -@tutorial_1036_td - Double click on the h2*.jar file. This only works if the .jar suffix is associated with java. - -@tutorial_1037_td -Any - -@tutorial_1038_td - Open a console window, navigate to the directory h2/bin and type: - -@tutorial_1039_h3 -Firewall - -@tutorial_1040_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 application 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. - -@tutorial_1041_p - It has been reported that when using Kaspersky 7.0 with firewall, the H2 Console is very slow when connecting over the IP address. A workaround is to connect using localhost, however this only works on the local machine. - -@tutorial_1042_p - A small firewall is already built into the server: other computers may not connect to the server by default. To change this, go to 'Preferences' and select 'Allow connections from other computers'. - -@tutorial_1043_h3 -Testing Java - -@tutorial_1044_p - To find out which version of Java is installed, open a command prompt and type: - -@tutorial_1045_p - If you get an error message, you may need to add the Java binary directory to the path environment variable. - -@tutorial_1046_h3 -Error Message 'Port may be in use' - -@tutorial_1047_p - You can only start one instance of the H2 Console, otherwise you will get the following error message: "The Web server could not be started. Possible cause: another server is already running...". It is possible to start multiple console applications on the same computer (using different ports), but this is usually not required as the console supports multiple concurrent connections. - -@tutorial_1048_h3 -Using another Port - -@tutorial_1049_p - If the port is in use by another application, you may want to start the H2 Console on a different port. This can be done by changing the port in the file .h2.server.properties. This file is stored in the user directory (for Windows, this is usually in Documents and Settings/<username>). The relevant entry is webPort. - -@tutorial_1050_h3 -Connecting to the Server using a Browser - -@tutorial_1051_p - If the server started successfully, you can connect to it using a web browser. JavaScript needs to be enabled. If you started the server on the same computer as the browser, open the URL http://localhost:8082. If you want to connect to the application from another computer, you need to provide the IP address of the server, for example: http://192.168.0.2:8082. If you enabled SSL on the server side, the URL needs to start with https://. - -@tutorial_1052_h3 -Multiple Concurrent Sessions - -@tutorial_1053_p - Multiple concurrent browser sessions are supported. As that the database objects reside on the server, the amount of concurrent work is limited by the memory available to the server application. - -@tutorial_1054_h3 -Login - -@tutorial_1055_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]. - -@tutorial_1056_p - You can save and reuse previously saved settings. The settings are stored in a properties file (see Settings of the H2 Console). - -@tutorial_1057_h3 -Error Messages - -@tutorial_1058_p - Error messages in are shown in red. You can show/hide the stack trace of the exception by clicking on the message. - -@tutorial_1059_h3 -Adding Database Drivers - -@tutorial_1060_p - Additional database drivers to connect to other databases (MySQL, PostgreSQL, HSQLDB,...) 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. - -@tutorial_1061_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. - -@tutorial_1062_h3 -Using the H2 Console - -@tutorial_1063_p - The H2 Console application has three main panels: the toolbar on top, the tree on the left, and the query / result panel on the right. The database objects (for example, tables) are listed on the left panel. Type in a SQL command on the query panel and click 'Run'. The result of the command appears just below the command. - -@tutorial_1064_h3 -Inserting Table Names or Column Names - -@tutorial_1065_p - The table name and column names can be inserted in the script by clicking them in the tree. If you click on a table while the query is empty, then SELECT * FROM ... is added as well. While typing a query, the table that was used is automatically expanded in the tree. For example if you type SELECT * FROM TEST T WHERE T. then the table TEST is automatically expanded in the tree. - -@tutorial_1066_h3 -Disconnecting and Stopping the Application - -@tutorial_1067_p - To log out of the database, click 'Disconnect' in the toolbar panel. However, the server is still running and ready to accept new sessions. - -@tutorial_1068_p - To stop the server, right click on the system tray icon and select [Exit]. If you don't have the system tray icon, navigate to [Preferences] and click [Shutdown], press [Ctrl]+[C] in the console where the server was started (Windows), or close the console window. - -@tutorial_1069_h2 -Special H2 Console Syntax - -@tutorial_1070_p - The H2 Console supports a few built-in commands. Those are interpreted within the H2 Console, that means they work with any database. They need to be at the beginning of a statement (before any remarks), otherwise they are not parsed correctly. If in doubt, add ';' before the command. - -@tutorial_1071_th -Command(s) - -@tutorial_1072_th -Description - -@tutorial_1073_td - @autocommit_true; - -@tutorial_1074_td - @autocommit_false; - -@tutorial_1075_td - Enable or disable autocommit. - -@tutorial_1076_td - @cancel; - -@tutorial_1077_td - Cancel the currently running statement. - -@tutorial_1078_td - @columns null null TEST; - -@tutorial_1079_td - @index_info null null TEST; - -@tutorial_1080_td - @tables; - -@tutorial_1081_td - @tables null null TEST; - -@tutorial_1082_td - Call the corresponding DatabaseMetaData.get method. Patterns are case sensitive (usually identifiers are uppercase). For information about the parameters, see the Javadoc documentation. Missing parameters at the end are set to null. The complete list of commands is: @attributes @best_row_identifier @catalogs @columns @column_privileges @cross_references @exported_keys @imported_keys @index_info @primary_keys @procedures @procedure_columns @schemas @super_tables @super_types @tables @table_privileges @table_types @type_info @udts @version_columns - -@tutorial_1083_td - @edit select * from test; - -@tutorial_1084_td - Use an updatable result set. - -@tutorial_1085_td - @generated insert into test() values(); - -@tutorial_1086_td - Show the result of Statement.getGeneratedKeys(). - -@tutorial_1087_td - @history; - -@tutorial_1088_td - Show the command history. - -@tutorial_1089_td - @info; - -@tutorial_1090_td - Display the result of various Connection and DatabaseMetaData methods. - -@tutorial_1091_td - @list select * from test; - -@tutorial_1092_td - Show the result set in list format (each column on its own line, with row numbers). - -@tutorial_1093_td - @loop 1000 select ?, ?/*rnd*/; - -@tutorial_1094_td - @loop 1000 @statement select ?; - -@tutorial_1095_td - Run the statement this many times. Parameters (?) are set using a loop from 0 up to x - 1. Random values are used for each ?/*rnd*/. A Statement object is used instead of a PreparedStatement if @statement is used. Result sets are read until ResultSet.next() returns false. Timing information is printed. - -@tutorial_1096_td - @maxrows 20; - -@tutorial_1097_td - Set the maximum number of rows to display. - -@tutorial_1098_td - @memory; - -@tutorial_1099_td - Show the used and free memory. This will call System.gc(). - -@tutorial_1100_td - @meta select 1; - -@tutorial_1101_td - List the ResultSetMetaData after running the query. - -@tutorial_1102_td - @parameter_meta select ?; - -@tutorial_1103_td - Show the result of the PreparedStatement.getParameterMetaData() calls. The statement is not executed. - -@tutorial_1104_td - @prof_start; - -@tutorial_1105_td - call hash('SHA256', '', 1000000); - -@tutorial_1106_td - @prof_stop; - -@tutorial_1107_td - Start / stop the built-in profiling tool. The top 3 stack traces of the statement(s) between start and stop are listed (if there are 3). - -@tutorial_1108_td - @transaction_isolation; - -@tutorial_1109_td - @transaction_isolation 2; - -@tutorial_1110_td - Display (without parameters) or change (with parameters 1, 2, 4, 8) the transaction isolation level. - -@tutorial_1111_h2 -Settings of the H2 Console - -@tutorial_1112_p - The settings of the H2 Console are stored in a configuration file called .h2.server.properties in you user home directory. For Windows installations, the user home directory is usually C:\Documents and Settings\[username]. The configuration file contains the settings of the application and is automatically created when the H2 Console is first started. - -@tutorial_1113_h2 -Connecting to a Database using JDBC - -@tutorial_1114_p - 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: - -@tutorial_1115_p - This code first loads the driver (Class.forName(...)) and then opens a connection (using DriverManager.getConnection()). The driver name is "org.h2.Driver". The database URL always needs to start with jdbc:h2: to be recognized by this database. The second parameter in the getConnection() call is the user name (sa for System Administrator in this example). The third parameter is the password. In this database, user names are not case sensitive, but passwords are. - -@tutorial_1116_h2 -Creating New Databases - -@tutorial_1117_p - By default, if the database specified in the URL does not yet exist, a new (empty) database is created automatically. The user that created the database automatically becomes the administrator of this database. - -@tutorial_1118_p - Auto-creating new database can be disabled, see Opening a Database Only if it Already Exists. - -@tutorial_1119_h2 -Using the Server - -@tutorial_1120_p - H2 currently supports three server: a web server (for the H2 Console), a TCP server (for client/server connections) and an PG server (for PostgreSQL clients). Please note that only the web server supports browser connections. The servers can be started in different ways, one is using the Server tool. - -@tutorial_1121_h3 -Starting the Server Tool from Command Line - -@tutorial_1122_p - To start the Server tool from the command line with the default settings, run: - -@tutorial_1123_p - This will start the tool with the default options. To get the list of options and default values, run: - -@tutorial_1124_p - There are options available to use other ports, and start or not start parts. - -@tutorial_1125_h3 -Connecting to the TCP Server - -@tutorial_1126_p - To remotely connect to a database using the TCP server, use the following driver and database URL: - -@tutorial_1127_li -JDBC driver class: org.h2.Driver - -@tutorial_1128_li -Database URL: jdbc:h2:tcp://localhost/~/test - -@tutorial_1129_p - For details about the database URL, see also in Features. Please note that you can't connection with a web browser to this URL. You can only connect using a H2 client (over JDBC). - -@tutorial_1130_h3 -Starting the TCP Server within an Application - -@tutorial_1131_p - Servers can also be started and stopped from within an application. Sample code: - -@tutorial_1132_h3 -Stopping a TCP Server from Another Process - -@tutorial_1133_p - The TCP server can be stopped from another process. To stop the server from the command line, run: - -@tutorial_1134_p - To stop the server from a user application, use the following code: - -@tutorial_1135_p - This function will only stop the TCP server. If other server were started in the same process, they will continue to run. To avoid recovery when the databases are opened the next time, all connections to the databases should be closed before calling this method. To stop a remote server, remote connections must be enabled on the server. Shutting down a TCP server can be protected using the option -tcpPassword (the same password must be used to start and stop the TCP server). - -@tutorial_1136_h2 -Using Hibernate - -@tutorial_1137_p - This database supports Hibernate version 3.1 and newer. You can use the HSQLDB Dialect, or the native H2 Dialect. Unfortunately the H2 Dialect included in some versions of Hibernate is buggy. A patch for Hibernate has been submitted and is now applied. The dialect for the newest version of Hibernate is also available at src/tools/org/hibernate/dialect/H2Dialect.java.txt. You can rename it to H2Dialect.java and include this as a patch in your application, or upgrade to a version of Hibernate where this is fixed. - -@tutorial_1138_p - When using compatibility modes such as MODE=MySQL when using Hibernate is not supported when using H2Dialect. - -@tutorial_1139_h2 -Using TopLink and Glassfish - -@tutorial_1140_p - To use H2 with Glassfish (or Sun AS), set the Datasource Classname to org.h2.jdbcx.JdbcDataSource. You can set this in the GUI at Application Server - Resources - JDBC - Connection Pools, or by editing the file sun-resources.xml: at element jdbc-connection-pool, set the attribute datasource-classname to org.h2.jdbcx.JdbcDataSource. - -@tutorial_1141_p - The H2 database is compatible with HSQLDB and PostgreSQL. To take advantage of H2 specific features, use the H2Platform. The source code of this platform is included in H2 at src/tools/oracle/toplink/essentials/platform/database/DatabasePlatform.java.txt. You will need to copy this file to your application, and rename it to .java. To enable it, change the following setting in persistence.xml: - -@tutorial_1142_p - In old versions of Glassfish, the property name is toplink.platform.class.name. - -@tutorial_1143_p - To use H2 within Glassfish, copy the h2*.jar to the directory glassfish/glassfish/lib. - -@tutorial_1144_h2 -Using EclipseLink - -@tutorial_1145_p - To use H2 in EclipseLink, use the platform class org.eclipse.persistence.platform.database.H2Platform. If this platform is not available in your version of EclipseLink, you can use the OraclePlatform instead in many case. See also H2Platform. - -@tutorial_1146_h2 -Using Databases in Web Applications - -@tutorial_1147_p - There are multiple ways to access a database from within web applications. Here are some examples if you use Tomcat or JBoss. - -@tutorial_1148_h3 -Embedded Mode - -@tutorial_1149_p - The (currently) simplest solution is to use the database in the embedded mode, that means open a connection in your application when it starts (a good solution is using a Servlet Listener, see below), or when a session starts. A database can be accessed from multiple sessions and applications at the same time, as long as they run in the same process. Most Servlet Containers (for example Tomcat) are just using one process, so this is not a problem (unless you run Tomcat in clustered mode). Tomcat uses multiple threads and multiple classloaders. If multiple applications access the same database at the same time, you need to put the database jar in the shared/lib or server/lib directory. It is a good idea to open the database when the web application starts, and close it when the web application stops. If using multiple applications, only one (any) of them needs to do that. In the application, an idea is to use one connection per Session, or even one connection per request (action). Those connections should be closed after use if possible (but it's not that bad if they don't get closed). - -@tutorial_1150_h3 -Server Mode - -@tutorial_1151_p - The server mode is similar, but it allows you to run the server in another process. - -@tutorial_1152_h3 -Using a Servlet Listener to Start and Stop a Database - -@tutorial_1153_p - Add the h2*.jar file to your web application, and add the following snippet to your web.xml file (between the context-param and the filter section): - -@tutorial_1154_p - For details on how to access the database, see the file DbStarter.java. By default this tool opens an embedded connection using the database URL jdbc:h2:~/test, user name sa, and password sa. If you want to use this connection within your servlet, you can access as follows: - -@tutorial_1155_code -DbStarter - -@tutorial_1156_p - can also start the TCP server, however this is disabled by default. To enable it, use the parameter db.tcpServer in the file web.xml. Here is the complete list of options. These options need to be placed between the description tag and the listener / filter tags: - -@tutorial_1157_p - When the web application is stopped, the database connection will be closed automatically. If the TCP server is started within the DbStarter, it will also be stopped automatically. - -@tutorial_1158_h3 -Using the H2 Console Servlet - -@tutorial_1159_p - The H2 Console is a standalone application and includes its own web server, but it can be used as a servlet as well. To do that, include the the h2*.jar file in your application, and add the following configuration to your web.xml: - -@tutorial_1160_p - For details, see also src/tools/WEB-INF/web.xml. - -@tutorial_1161_p - To create a web application with just the H2 Console, run the following command: - -@tutorial_1162_h2 -CSV (Comma Separated Values) Support - -@tutorial_1163_p - The CSV file support can be used inside the database using the functions CSVREAD and CSVWRITE, or it can be used outside the database as a standalone tool. - -@tutorial_1164_h3 -Reading a CSV File from Within a Database - -@tutorial_1165_p - A CSV file can be read using the function CSVREAD. Example: - -@tutorial_1166_h3 -Importing Data from a CSV File - -@tutorial_1167_p - A fast way to load or import data (sometimes called 'bulk load') from a CSV file is to combine table creation with import. Optionally, the column names and data types can be set when creating the table. Another option is to use INSERT INTO ... SELECT. - -@tutorial_1168_h3 -Writing a CSV File from Within a Database - -@tutorial_1169_p - The built-in function CSVWRITE can be used to create a CSV file from a query. Example: - -@tutorial_1170_h3 -Writing a CSV File from a Java Application - -@tutorial_1171_p - The Csv tool can be used in a Java application even when not using a database at all. Example: - -@tutorial_1172_h3 -Reading a CSV File from a Java Application - -@tutorial_1173_p - It is possible to read a CSV file without opening a database. Example: - -@tutorial_1174_h2 -Upgrade, Backup, and Restore - -@tutorial_1175_h3 -Database Upgrade - -@tutorial_1176_p - The recommended way to upgrade from one version of the database engine to the next version is to create a backup of the database (in the form of a SQL script) using the old engine, and then execute the SQL script using the new engine. - -@tutorial_1177_h3 -Backup using the Script Tool - -@tutorial_1178_p - There are different ways to backup a database. For example, it is possible to copy the database files. However, this is not recommended while the database is in use. Also, the database files are not human readable and quite large. The recommended way to backup a database is to create a compressed SQL script file. This can be done using the Script tool: - -@tutorial_1179_p - It is also possible to use the SQL command SCRIPT to create the backup of the database. For more information about the options, see the SQL command SCRIPT. The backup can be done remotely, however the file will be created on the server side. The built in FTP server could be used to retrieve the file from the server. - -@tutorial_1180_h3 -Restore from a Script - -@tutorial_1181_p - To restore a database from a SQL script file, you can use the RunScript tool: - -@tutorial_1182_p - For more information about the options, see the SQL command RUNSCRIPT. The restore can be done remotely, however the file needs to be on the server side. The built in FTP server could be used to copy the file to the server. It is also possible to use the SQL command RUNSCRIPT to execute a SQL script. 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. - -@tutorial_1183_h3 -Online Backup - -@tutorial_1184_p - The BACKUP SQL statement and the Backup tool both create a zip file with all database files. However, the contents of this file are not human readable. - -@tutorial_1185_p - Unlike than the SCRIPT statement, the BACKUP statement does not lock the database objects when using the multi-threaded mode, and therefore does not block other users. The resulting backup is transactionally consistent: - -@tutorial_1186_p - The Backup tool (org.h2.tools.Backup) can not be used to create a online backup; the database must not be in use while running this program. - -@tutorial_1187_p - Creating a backup by copying the database files while the database is running is not supported, except if the file systems support creating snapshots. The problem is that it can't be guaranteed that the data is copied in the right order. - -@tutorial_1188_h2 -Command Line Tools - -@tutorial_1189_p - This database comes with a number of command line tools. To get more information about a tool, start it with the parameter '-?', for example: - -@tutorial_1190_p - The command line tools are: - -@tutorial_1191_code -Backup - -@tutorial_1192_li - creates a backup of a database. - -@tutorial_1193_code -ChangeFileEncryption - -@tutorial_1194_li - allows changing the file encryption password or algorithm of a database. - -@tutorial_1195_code -Console - -@tutorial_1196_li - starts the browser based H2 Console. - -@tutorial_1197_code -ConvertTraceFile - -@tutorial_1198_li - converts a .trace.db file to a Java application and SQL script. - -@tutorial_1199_code -CreateCluster - -@tutorial_1200_li - creates a cluster from a standalone database. - -@tutorial_1201_code -DeleteDbFiles - -@tutorial_1202_li - deletes all files belonging to a database. - -@tutorial_1203_code -Recover - -@tutorial_1204_li - helps recovering a corrupted database. - -@tutorial_1205_code -Restore - -@tutorial_1206_li - restores a backup of a database. - -@tutorial_1207_code -RunScript - -@tutorial_1208_li - runs a SQL script against a database. - -@tutorial_1209_code -Script - -@tutorial_1210_li - allows converting a database to a SQL script for backup or migration. - -@tutorial_1211_code -Server - -@tutorial_1212_li - is used in the server mode to start a H2 server. - -@tutorial_1213_code -Shell - -@tutorial_1214_li - is a command line database tool. - -@tutorial_1215_p - The tools can also be called from an application by calling the main or another public method. For details, see the Javadoc documentation. - -@tutorial_1216_h2 -The Shell Tool - -@tutorial_1217_p - The Shell tool is a simple interactive command line tool. To start it, type: - -@tutorial_1218_p - You will be asked for a database URL, JDBC driver, user name, and password. The connection setting can also be set as command line parameters. After connecting, you will get the list of options. The built-in commands don't need to end with a semicolon, but SQL statements are only executed if the line ends with a semicolon ;. This allows to enter multi-line statements: - -@tutorial_1219_p - By default, results are printed as a table. For results with many column, consider using the list mode: - -@tutorial_1220_h2 -Using OpenOffice Base - -@tutorial_1221_p - 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. The steps to connect to a H2 database are: - -@tutorial_1222_li -Start OpenOffice Writer, go to [Tools], [Options] - -@tutorial_1223_li -Make sure you have selected a Java runtime environment in OpenOffice.org / Java - -@tutorial_1224_li -Click [Class Path...], [Add Archive...] - -@tutorial_1225_li -Select your h2 jar file (location is up to you, could be wherever you choose) - -@tutorial_1226_li -Click [OK] (as much as needed), stop OpenOffice (including the Quickstarter) - -@tutorial_1227_li -Start OpenOffice Base - -@tutorial_1228_li -Connect to an existing database; select [JDBC]; [Next] - -@tutorial_1229_li -Example datasource URL: jdbc:h2:~/test - -@tutorial_1230_li -JDBC driver class: org.h2.Driver - -@tutorial_1231_p - Now you can access the database stored in the current users home directory. - -@tutorial_1232_p - To use H2 in NeoOffice (OpenOffice without X11): - -@tutorial_1233_li -In NeoOffice, go to [NeoOffice], [Preferences] - -@tutorial_1234_li -Look for the page under [NeoOffice], [Java] - -@tutorial_1235_li -Click [Class Path], [Add Archive...] - -@tutorial_1236_li -Select your h2 jar file (location is up to you, could be wherever you choose) - -@tutorial_1237_li -Click [OK] (as much as needed), restart NeoOffice. - -@tutorial_1238_p - Now, when creating a new database using the "Database Wizard" : - -@tutorial_1239_li -Click [File], [New], [Database]. - -@tutorial_1240_li -Select [Connect to existing database] and the select [JDBC]. Click next. - -@tutorial_1241_li -Example datasource URL: jdbc:h2:~/test - -@tutorial_1242_li -JDBC driver class: org.h2.Driver - -@tutorial_1243_p - Another solution to use H2 in NeoOffice is: - -@tutorial_1244_li -Package the h2 jar within an extension package - -@tutorial_1245_li -Install it as a Java extension in NeoOffice - -@tutorial_1246_p - This can be done by create it using the NetBeans OpenOffice plugin. See also Extensions Development. - -@tutorial_1247_h2 -Java Web Start / JNLP - -@tutorial_1248_p - When using Java Web Start / JNLP (Java Network Launch Protocol), permissions tags must be set in the .jnlp file, and the application .jar file must be signed. Otherwise, when trying to write to the file system, the following exception will occur: java.security.AccessControlException: access denied (java.io.FilePermission ... read). Example permission tags: - -@tutorial_1249_h2 -Using a Connection Pool - -@tutorial_1250_p - For H2, opening a connection is fast if the database is already open. Still, using a connection pool improves performance if you open and close connections a lot. A simple connection pool is included in H2. It is based on the Mini Connection Pool Manager from Christian d'Heureuse. There are other, more complex, open source connection pools available, for example the Apache Commons DBCP. For H2, it is about twice as faster to get a connection from the built-in connection pool than to get one using DriverManager.getConnection().The build-in connection pool is used as follows: - -@tutorial_1251_h2 -Fulltext Search - -@tutorial_1252_p - H2 includes two fulltext search implementations. One is using Apache Lucene, and the other (the native implementation) stores the index data in special tables in the database. - -@tutorial_1253_h3 -Using the Native Fulltext Search - -@tutorial_1254_p - To initialize, call: - -@tutorial_1255_p - You need to initialize it in each database where you want to use it. Afterwards, you can create a fulltext index for a table using: - -@tutorial_1256_p - PUBLIC is the schema name, TEST is the table name. The list of column names (column separated) is optional, in this case all columns are indexed. The index is updated in realtime. To search the index, use the following query: - -@tutorial_1257_p - This will produce a result set that contains the query needed to retrieve the data: - -@tutorial_1258_p - To get the raw data, use FT_SEARCH_DATA('Hello', 0, 0);. The result contains the columns SCHEMA (the schema name), TABLE (the table name), COLUMNS (an array of column names), and KEYS (an array of objects). To join a table, use a join as in: SELECT T.* FROM FT_SEARCH_DATA('Hello', 0, 0) FT, TEST T WHERE FT.TABLE='TEST' AND T.ID=FT.KEYS[0]; - -@tutorial_1259_p - You can also call the index from within a Java application: - -@tutorial_1260_h3 -Using the Lucene Fulltext Search - -@tutorial_1261_p - To use the Lucene full text search, you need the Lucene library in the classpath. How to do that depends on the application; if you use the H2 Console, you can add the Lucene jar file to the environment variables H2DRIVERS or CLASSPATH. To initialize the Lucene fulltext search in a database, call: - -@tutorial_1262_p - You need to initialize it in each database where you want to use it. Afterwards, you can create a full text index for a table using: - -@tutorial_1263_p - PUBLIC is the schema name, TEST is the table name. The list of column names (column separated) is optional, in this case all columns are indexed. The index is updated in realtime. To search the index, use the following query: - -@tutorial_1264_p - This will produce a result set that contains the query needed to retrieve the data: - -@tutorial_1265_p - To get the raw data, use FTL_SEARCH_DATA('Hello', 0, 0);. The result contains the columns SCHEMA (the schema name), TABLE (the table name), COLUMNS (an array of column names), and KEYS (an array of objects). To join a table, use a join as in: SELECT T.* FROM FTL_SEARCH_DATA('Hello', 0, 0) FT, TEST T WHERE FT.TABLE='TEST' AND T.ID=FT.KEYS[0]; - -@tutorial_1266_p - You can also call the index from within a Java application: - -@tutorial_1267_h2 -User-Defined Variables - -@tutorial_1268_p - This database supports user-defined variables. Variables start with @ and can be used wherever expressions or parameters are allowed. Variables are not persisted and session scoped, that means only visible from within the session in which they are defined. A value is usually assigned using the SET command: - -@tutorial_1269_p - The value can also be changed using the SET() method. This is useful in queries: - -@tutorial_1270_p - Variables that are not set evaluate to NULL. The data type of a user-defined variable is the data type of the value assigned to it, that means it is not necessary (or possible) to declare variable names before using them. There are no restrictions on the assigned values; large objects (LOBs) are supported as well. - -@tutorial_1271_h2 -Date and Time - -@tutorial_1272_p - Date, time and timestamp values support ISO 8601 formatting, including time zone: - -@tutorial_1273_p - If the time zone is not set, the value is parsed using the current time zone setting of the system. Date and time information is stored in H2 database files in GMT (Greenwich Mean Time). If the database is opened using another system time zone, the date and time will change accordingly. If you want to move a database from one time zone to the other and don't want this to happen, you need to create a SQL script file using the SCRIPT command or Script tool, and then load the database using the RUNSCRIPT command or the RunScript tool in the new time zone. - -@tutorial_1274_h2 -Using Spring - -@tutorial_1275_p - Use the following configuration to start and stop the H2 TCP server using the Spring Framework: - -@tutorial_1276_p - The destroy-method will help prevent exceptions on hot-redeployment or when restarting the server. - diff --git a/tools/h2/src/docsrc/text/_docs_ja.utf8.txt b/tools/h2/src/docsrc/text/_docs_ja.utf8.txt deleted file mode 100755 index 1535077..0000000 --- a/tools/h2/src/docsrc/text/_docs_ja.utf8.txt +++ /dev/null @@ -1,10575 +0,0 @@ -@advanced_1000_h1 -#Advanced - -@advanced_1001_a -# Result Sets - -@advanced_1002_a -# Large Objects - -@advanced_1003_a -# Linked Tables - -@advanced_1004_a -# Transaction Isolation - -@advanced_1005_a -# Multi-Version Concurrency Control (MVCC) - -@advanced_1006_a -# Clustering / High Availability - -@advanced_1007_a -# Two Phase Commit - -@advanced_1008_a -# Compatibility - -@advanced_1009_a -# Standards Compliance - -@advanced_1010_a -# Run as Windows Service - -@advanced_1011_a -# ODBC Driver - -@advanced_1012_a -# Using H2 in Microsoft .NET - -@advanced_1013_a -# ACID - -@advanced_1014_a -# Durability Problems - -@advanced_1015_a -# Using the Recover Tool - -@advanced_1016_a -# File Locking Protocols - -@advanced_1017_a -# File Locking Method 'Serialized' - -@advanced_1018_a -# Protection against SQL Injection - -@advanced_1019_a -# Protection against Remote Access - -@advanced_1020_a -# Restricting Class Loading and Usage - -@advanced_1021_a -# Security Protocols - -@advanced_1022_a -# SSL/TLS Connections - -@advanced_1023_a -# Universally Unique Identifiers (UUID) - -@advanced_1024_a -# Settings Read from System Properties - -@advanced_1025_a -# Setting the Server Bind Address - -@advanced_1026_a -# Pluggable File System - -@advanced_1027_a -# Limits and Limitations - -@advanced_1028_a -# Glossary and Links - -@advanced_1029_h2 -Result Sets - -@advanced_1030_h3 -#Statements that Return a Result Set - -@advanced_1031_p -# The following statements return a result set: SELECT, EXPLAIN, CALL, SCRIPT, SHOW, HELP. All other statements return an update count. - -@advanced_1032_h3 -行数の制限 - -@advanced_1033_p -# Before the result is returned to the application, all rows are read by the database. Server side cursors are not supported currently. If only the first few rows are interesting for the application, then the result set size should be limited to improve the performance. This can be done using LIMIT in a query (example: SELECT * FROM TEST LIMIT 100), or by using Statement.setMaxRows(max). - -@advanced_1034_h3 -大きなResult Set と外部ソート - -@advanced_1035_p -# For large result set, the result is buffered to disk. The threshold can be defined using the statement SET MAX_MEMORY_ROWS. If ORDER BY is used, 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. - -@advanced_1036_h2 -大きなオブジェクト - -@advanced_1037_h3 -大きなオブジェクトのソートと読み込み - -@advanced_1038_p -# If it is possible that the objects don't fit into memory, then the data type CLOB (for textual data) or BLOB (for binary data) should be used. For these data types, the objects are not fully read into memory, by using streams. To store a BLOB, use PreparedStatement.setBinaryStream. To store a CLOB, use PreparedStatement.setCharacterStream. To read a BLOB, use ResultSet.getBinaryStream, and to read a CLOB, use ResultSet.getCharacterStream. When using the client/server mode, large BLOB and CLOB data is stored in a temporary file on the client side. - -@advanced_1039_h3 -#When to use CLOB/BLOB - -@advanced_1040_p -# This database stores large LOB (CLOB and BLOB) objects as separate files. Small LOB objects are stored in-place, the threshold can be set using MAX_LENGTH_INPLACE_LOB, but there is still an overhead to use CLOB/BLOB. Because of this, BLOB and CLOB should never be used for columns with a maximum size below about 200 bytes. The best threshold depends on the use case; reading in-place objects is faster than reading from separate files, but slows down the performance of operations that don't involve this column. - -@advanced_1041_h3 -#Large Object Compression - -@advanced_1042_p -# CLOB and BLOB values can be compressed by using SET COMPRESS_LOB. The LZF algorithm is faster but needs more disk space. By default compression is disabled, which usually speeds up write operations. If you store many large compressible values such as XML, HTML, text, and uncompressed binary files, then compressing can save a lot of disk space (sometimes more than 50%), and read operations may even be faster. - -@advanced_1043_h2 -リンクテーブル - -@advanced_1044_p -# This database supports linked tables, which means tables that don't exist in the current database but are just links to another database. To create such a link, use the CREATE LINKED TABLE statement: - -@advanced_1045_p -# You can then access the table in the usual way. Whenever the linked table is accessed, the database issues specific queries over JDBC. Using the example above, if you issue the query SELECT * FROM LINK WHERE ID=1, then the following query is run against the PostgreSQL database: SELECT * FROM TEST WHERE ID=?. The same happens for insert and update statements. Only simple statements are executed against the target database, that means no joins. Prepared statements are used where possible. - -@advanced_1046_p -# To view the statements that are executed against the target table, set the trace level to 3. - -@advanced_1047_p -# If multiple linked tables point to the same database (using the same database URL), the connection is shared. To disable this, set the system property h2.shareLinkedConnections=false. - -@advanced_1048_p -# The statement CREATE LINKED TABLE supports an optional schema name parameter. - -@advanced_1049_h2 -トランザクション分離 - -@advanced_1050_p -# Transaction isolation is provided for all data manipulation language (DML) statements. Most data definition language (DDL) statements commit the current transaction. See the Grammar for details. - -@advanced_1051_p -# This database supports the following transaction isolation levels: - -@advanced_1052_b -Read Committed (コミット済み読み取り) - -@advanced_1053_li -# This is the default level. Read locks are released immediately. Higher concurrency is possible when using this level. - -@advanced_1054_li -# To enable, execute the SQL statement SET LOCK_MODE 3 - -@advanced_1055_li -# or append ;LOCK_MODE=3 to the database URL: jdbc:h2:~/test;LOCK_MODE=3 - -@advanced_1056_b -Serializable (直列化) - -@advanced_1057_li -# To enable, execute the SQL statement SET LOCK_MODE 1 - -@advanced_1058_li -# or append ;LOCK_MODE=1 to the database URL: jdbc:h2:~/test;LOCK_MODE=1 - -@advanced_1059_b -Read Uncommitted (非コミット読み取り) - -@advanced_1060_li -# This level means that transaction isolation is disabled. - -@advanced_1061_li -# To enable, execute the SQL statement SET LOCK_MODE 0 - -@advanced_1062_li -# or append ;LOCK_MODE=0 to the database URL: jdbc:h2:~/test;LOCK_MODE=0 - -@advanced_1063_p -# When using the isolation level 'serializable', dirty reads, non-repeatable reads, and phantom reads are prohibited. - -@advanced_1064_b -Dirty Reads (ダーティリード) - -@advanced_1065_li -# Means a connection can read uncommitted changes made by another connection. - -@advanced_1066_li -# Possible with: read uncommitted - -@advanced_1067_b -Non-Repeatable Reads (反復不可能読み取り) - -@advanced_1068_li -# 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. - -@advanced_1069_li -# Possible with: read uncommitted, read committed - -@advanced_1070_b -Phantom Reads (ファントムリード) - -@advanced_1071_li -# 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. - -@advanced_1072_li -# Possible with: read uncommitted, read committed - -@advanced_1073_h3 -テーブルレベルロック - -@advanced_1074_p -# The database allows multiple concurrent connections to the same database. To make sure all connections only see consistent data, table level locking is used by default. This mechanism does not allow high concurrency, but is very fast. Shared locks and exclusive locks are supported. Before reading from a table, the database tries to add a shared lock to the table (this is only possible if there is no exclusive lock on the object by another connection). If the shared lock is added successfully, the table can be read. It is allowed that other connections also have a shared lock on the same object. If a connection wants to write to a table (update or delete a row), an exclusive lock is required. To get the exclusive lock, other connection must not have any locks on the object. After the connection commits, all locks are released. This database keeps all locks in memory. - -@advanced_1075_h3 -ロックタイムアウト - -@advanced_1076_p -# If a connection cannot get a lock on an object, the connection waits for some amount of time (the lock timeout). During this time, hopefully the connection holding the lock commits and it is then possible to get the lock. If this is not possible because 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. - -@advanced_1077_h2 -#Multi-Version Concurrency Control (MVCC) - -@advanced_1078_p -# The MVCC feature allows higher concurrency than using (table level or row level) locks. When using MVCC in this database, delete, insert and update operations will only issue a shared lock on the table. An exclusive lock is still used when adding or removing columns, when dropping the table, and when using SELECT ... FOR UPDATE. Connections only 'see' committed data, and own changes. That means, if connection A updates a row but doesn't commit this change yet, connection B will see the old value. Only when the change is committed, the new value is visible by other connections (read committed). If multiple connections concurrently try to update the same row, the database waits until it can apply the change, but at most until the lock timeout expires. - -@advanced_1079_p -# To use the MVCC feature, append ;MVCC=TRUE to the database URL: - -@advanced_1080_p -# MVCC is disabled by default. The MVCC feature is not fully tested yet. The limitations of the MVCC mode are: it can not be used at the same time as MULTI_THREADED=TRUE; the complete undo log must fit in memory when using multi-version concurrency (the setting MAX_MEMORY_UNDO has no effect). It is not possible to enable or disable this setting while the database is already open. The setting must be specified in the first connection (the one that opens the database). - -@advanced_1081_h2 -クラスタリング / 高可用性 - -@advanced_1082_p -# This database supports a simple clustering / high availability mechanism. The architecture is: two database servers run on two different computers, and on both computers is a copy of the same database. If both servers run, each database operation is executed on both computers. If one server fails (power, hardware or network failure), the other server can still continue to work. From this point on, the operations will be executed only on one server until the other server is back up. - -@advanced_1083_p -# Clustering can only be used in the server mode (the embedded mode does not support clustering). The cluster can be re-created using the CreateCluster tool without stopping the remaining server. Applications that are still connected are automatically disconnected, however when appending ;AUTO_RECONNECT=TRUE, they will recover from that. - -@advanced_1084_p -# To initialize the cluster, use the following steps: - -@advanced_1085_li -#Create a database - -@advanced_1086_li -#Use the CreateCluster tool to copy the database to another location and initialize the clustering. Afterwards, you have two databases containing the same data. - -@advanced_1087_li -#Start two servers (one for each copy of the database) - -@advanced_1088_li -#You are now ready to connect to the databases with the client application(s) - -@advanced_1089_h3 -CreateClusterツールを使用する - -@advanced_1090_p -# To understand how clustering works, please try out the following example. In this example, the two databases reside on the same computer, but usually, the databases will be on different servers. - -@advanced_1091_li -#Create two directories: server1, server2. Each directory will simulate a directory on a computer. - -@advanced_1092_li -#Start a TCP server pointing to the first directory. You can do this using the command line: - -@advanced_1093_li -#Start a second TCP server pointing to the second directory. This will simulate a server running on a second (redundant) computer. You can do this using the command line: - -@advanced_1094_li -#Use the CreateCluster tool to initialize clustering. This will automatically create a new, empty database if it does not exist. Run the tool on the command line: - -@advanced_1095_li -#You can now connect to the databases using an application or the H2 Console using the JDBC URL jdbc:h2:tcp://localhost:9101,localhost:9102/~/test - -@advanced_1096_li -#If you stop a server (by killing the process), you will notice that the other machine continues to work, and therefore the database is still accessible. - -@advanced_1097_li -#To restore the cluster, you first need to delete the database that failed, then restart the server that was stopped, and re-run the CreateCluster tool. - -@advanced_1098_h3 -#Detect Which Cluster Instances are Running - -@advanced_1099_p -# To find out which cluster nodes are currently running, execute the following SQL statement: - -@advanced_1100_p -# If the result is '' (two single quotes), then the cluster mode is disabled. Otherwise, the list of servers is returned, enclosed in single quote. Example: 'server1:9191,server2:9191'. - -@advanced_1101_h3 -クラスタリングアルゴリズムと制限 - -@advanced_1102_p -# Read-only queries are only executed against the first cluster node, but all other statements are executed against all nodes. There is currently no load balancing made to avoid problems with transactions. The following functions may yield different results on different cluster nodes and must be executed with care: RANDOM_UUID(), SECURE_RAND(), SESSION_ID(), MEMORY_FREE(), MEMORY_USED(), CSVREAD(), CSVWRITE(), RAND() [when not using a seed]. Those functions should not be used directly in modifying statements (for example INSERT, UPDATE, MERGE). However, they can be used in read-only statements and the result can then be used for modifying statements. - -@advanced_1103_p -# When using the cluster modes, result sets are read fully in memory by the client, so that there is no problem if the server dies that executed the query. Result sets must fit in memory on the client side. - -@advanced_1104_h2 -2フェーズコミット - -@advanced_1105_p -# The two phase commit protocol is supported. 2-phase-commit works as follows: - -@advanced_1106_li -#Autocommit needs to be switched off - -@advanced_1107_li -#A transaction is started, for example by inserting a row - -@advanced_1108_li -#The transaction is marked 'prepared' by executing the SQL statement PREPARE COMMIT transactionName - -@advanced_1109_li -#The transaction can now be committed or rolled back - -@advanced_1110_li -#If a problem occurs before the transaction was successfully committed or rolled back (for example because a network problem occurred), the transaction is in the state 'in-doubt' - -@advanced_1111_li -#When re-connecting to the database, the in-doubt transactions can be listed with SELECT * FROM INFORMATION_SCHEMA.IN_DOUBT - -@advanced_1112_li -#Each transaction in this list must now be committed or rolled back by executing COMMIT TRANSACTION transactionName or ROLLBACK TRANSACTION transactionName - -@advanced_1113_li -#The database needs to be closed and re-opened to apply the changes - -@advanced_1114_h2 -互換性 - -@advanced_1115_p -# This database is (up to a certain point) compatible to other databases such as HSQLDB, MySQL and PostgreSQL. There are certain areas where H2 is incompatible. - -@advanced_1116_h3 -オートコミットがONの時のトランザクションコミット - -@advanced_1117_p -# At this time, this database engine commits a transaction (if autocommit is switched on) just before returning the result. For a query, this means the transaction is committed even before the application scans through the result set, and before the result set is closed. Other database engines may commit the transaction in this case when the result set is closed. - -@advanced_1118_h3 -キーワード / 予約語 - -@advanced_1119_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: - -@advanced_1120_code -# CROSS, CURRENT_DATE, CURRENT_TIME, CURRENT_TIMESTAMP, DISTINCT, EXCEPT, EXISTS, FALSE, FOR, FROM, FULL, GROUP, HAVING, INNER, INTERSECT, IS, JOIN, LIKE, LIMIT, MINUS, NATURAL, NOT, NULL, ON, ORDER, PRIMARY, ROWNUM, SELECT, SYSDATE, SYSTIME, SYSTIMESTAMP, TODAY, TRUE, UNION, UNIQUE, WHERE - -@advanced_1121_p -# Certain words of this list are keywords because they are functions that can be used without '()' for compatibility, for example CURRENT_TIMESTAMP. - -@advanced_1122_h2 -#Standards Compliance - -@advanced_1123_p -# This database tries to be as much standard compliant as possible. For the SQL language, ANSI/ISO is the main standard. There are several versions that refer to the release date: SQL-92, SQL:1999, and SQL:2003. Unfortunately, the standard documentation is not freely available. Another problem is that important features are not standardized. Whenever this is the case, this database tries to be compatible to other databases. - -@advanced_1124_h2 -Windowsサービスとして実行する - -@advanced_1125_p -# 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. is included in the installation. Batch files are provided to install, start, stop and uninstall the H2 Database Engine Service. This service contains the TCP Server and the H2 Console web application. The batch files are located in the directory h2/service. - -@advanced_1126_h3 -サービスをインストールする - -@advanced_1127_p -# The service needs to be registered as a Windows Service first. To do that, double click on 1_install_service.bat. If successful, a command prompt window will pop up and disappear immediately. If not, a message will appear. - -@advanced_1128_h3 -サービスを起動する - -@advanced_1129_p -# You can start the H2 Database Engine Service using the service manager of Windows, or by double clicking on 2_start_service.bat. Please note that the batch file does not print an error message if the service is not installed. - -@advanced_1130_h3 -H2コンソールに接続する - -@advanced_1131_p -# After installing and starting the service, you can connect to the H2 Console application using a browser. Double clicking on 3_start_browser.bat to do that. The default port (8082) is hard coded in the batch file. - -@advanced_1132_h3 -サービスを終了する - -@advanced_1133_p -# To stop the service, double click on 4_stop_service.bat. Please note that the batch file does not print an error message if the service is not installed or started. - -@advanced_1134_h3 -サービスのアンインストール - -@advanced_1135_p -# 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. - -@advanced_1136_h2 -ODBCドライバ - -@advanced_1137_p -# This database does not come with its own ODBC driver at this time, but it supports the PostgreSQL network protocol. Therefore, the PostgreSQL ODBC driver can be used. Support for the PostgreSQL network protocol is quite new and should be viewed as experimental. It should not be used for production applications. - -@advanced_1138_p -# To use the PostgreSQL ODBC driver on 64 bit versions of Windows, first run c:/windows/syswow64/odbcad32.exe. At this point you set up your DSN just like you would on any other system. See also: Re: ODBC Driver on Windows 64 bit - -@advanced_1139_h3 -ODBCインストール - -@advanced_1140_p -# First, the ODBC driver must be installed. Any recent PostgreSQL ODBC driver should work, however version 8.2 (psqlodbc-08_02*) or newer is recommended. The Windows version of the PostgreSQL ODBC driver is available at http://www.postgresql.org/ftp/odbc/versions/msi. - -@advanced_1141_h3 -サーバーの起動 - -@advanced_1142_p -# After installing the ODBC driver, start the H2 Server using the command line: - -@advanced_1143_p -# The PG Server (PG for PostgreSQL protocol) is started as well. By default, databases are stored in the current working directory where the server is started. Use -baseDir to save databases in another directory, for example the user home directory: - -@advanced_1144_p -# The PG server can be started and stopped from within a Java application as follows: - -@advanced_1145_p -# By default, only connections from localhost are allowed. To allow remote connections, use -pgAllowOthers when starting the server. - -@advanced_1146_h3 -ODBC設定 - -@advanced_1147_p -# After installing the driver, a new Data Source must be added. In Windows, run odbcad32.exe to open the Data Source Administrator. Then click on 'Add...' and select the PostgreSQL Unicode driver. Then click 'Finish'. You will be able to change the connection properties: - -@advanced_1148_th -プロパティ - -@advanced_1149_th -例 - -@advanced_1150_th -コメント - -@advanced_1151_td -Data Source - -@advanced_1152_td -H2 Test - -@advanced_1153_td -ODBCデータソースの名称 - -@advanced_1154_td -Database - -@advanced_1155_td -test - -@advanced_1156_td -# The database name. Only simple names are supported at this time; - -@advanced_1157_td -# relative or absolute path are not supported in the database name. - -@advanced_1158_td -# By default, the database is stored in the current working directory - -@advanced_1159_td -# where the Server is started except when the -baseDir setting is used. - -@advanced_1160_td -# The name must be at least 3 characters. - -@advanced_1161_td -Server - -@advanced_1162_td -localhost - -@advanced_1163_td -サーバー名、またはIPアドレス - -@advanced_1164_td -デフォルトでは、リモート接続のみ許可されています。 - -@advanced_1165_td -User Name - -@advanced_1166_td -sa - -@advanced_1167_td -データベースのユーザー名 - -@advanced_1168_td -SSL Mode - -@advanced_1169_td -disabled - -@advanced_1170_td -現時点で、SSLはサポートされていません。 - -@advanced_1171_td -Port - -@advanced_1172_td -5435 - -@advanced_1173_td -PGサーバーが傾聴しているポート - -@advanced_1174_td -Password - -@advanced_1175_td -sa - -@advanced_1176_td -データベースパスワード - -@advanced_1177_p -# To improve performance, please enable 'server side prepare' under Options / Datasource / Page 2 / Server side prepare. - -@advanced_1178_p -# Afterwards, you may use this data source. - -@advanced_1179_h3 -PGプロトコルサポートの制限 - -@advanced_1180_p -# At this time, only a subset of the PostgreSQL network protocol is implemented. Also, there may be compatibility problems on the SQL level, with the catalog, or with text encoding. Problems are fixed as they are found. Currently, statements can not be canceled when using the PG protocol. - -@advanced_1181_p -# PostgreSQL ODBC Driver Setup requires a database password; that means it is not possible to connect to H2 databases without password. This is a limitation of the ODBC driver. - -@advanced_1182_h3 -セキュリティ考慮 - -@advanced_1183_p -# Currently, the PG Server does not support challenge response or encrypt passwords. This may be a problem if an attacker can listen to the data transferred between the ODBC driver and the server, because the password is readable to the attacker. Also, it is currently not possible to use encrypted SSL connections. Therefore the ODBC driver should not be used where security is important. - -@advanced_1184_h2 -#Using H2 in Microsoft .NET - -@advanced_1185_p -# The database can be used from Microsoft .NET even without using Java, by using IKVM.NET. You can access a H2 database on .NET using the JDBC API, or using the ADO.NET interface. - -@advanced_1186_h3 -#Using the ADO.NET API on .NET - -@advanced_1187_p -# An implementation of the ADO.NET interface is available in the open source project H2Sharp. - -@advanced_1188_h3 -#Using the JDBC API on .NET - -@advanced_1189_li -#Install the .NET Framework from Microsoft. Mono has not yet been tested. - -@advanced_1190_li -#Install IKVM.NET. - -@advanced_1191_li -#Copy the h2*.jar file to ikvm/bin - -@advanced_1192_li -#Run the H2 Console using: ikvm -jar h2*.jar - -@advanced_1193_li -#Convert the H2 Console to an .exe file using: ikvmc -target:winexe h2*.jar. You may ignore the warnings. - -@advanced_1194_li -#Create a .dll file using (change the version accordingly): ikvmc.exe -target:library -version:1.0.69.0 h2*.jar - -@advanced_1195_p -# If you want your C# application use H2, you need to add the h2.dll and the IKVM.OpenJDK.ClassLibrary.dll to your C# solution. Here some sample code: - -@advanced_1196_h2 -ACID - -@advanced_1197_p -# In the database world, ACID stands for: - -@advanced_1198_li -#Atomicity: transactions must be atomic, meaning either all tasks are performed or none. - -@advanced_1199_li -#Consistency: all operations must comply with the defined constraints. - -@advanced_1200_li -#Isolation: transactions must be isolated from each other. - -@advanced_1201_li -#Durability: committed transaction will not be lost. - -@advanced_1202_h3 -Atomicity (原子性) - -@advanced_1203_p -# Transactions in this database are always atomic. - -@advanced_1204_h3 -Consistency (一貫性) - -@advanced_1205_p -# By default, this database is always in a consistent state. Referential integrity rules are enforced except when explicitly disabled. - -@advanced_1206_h3 -Isolation (独立性 / 分離性) - -@advanced_1207_p -# For H2, as with most other database systems, the default isolation level is 'read committed'. This provides better performance, but also means that transactions are not completely isolated. H2 supports the transaction isolation levels 'serializable', 'read committed', and 'read uncommitted'. - -@advanced_1208_h3 -Durability (永続性) - -@advanced_1209_p -# This database does not guarantee that all committed transactions survive a power failure. Tests show that all databases sometimes lose transactions on power failure (for details, see below). Where losing transactions is not acceptable, a laptop or UPS (uninterruptible power supply) should be used. If durability is required for all possible cases of hardware failure, clustering should be used, such as the H2 clustering mode. - -@advanced_1210_h2 -永続性問題 - -@advanced_1211_p -# Complete durability means all committed transaction survive a power failure. Some databases claim they can guarantee durability, but such claims are wrong. A durability test was run against H2, HSQLDB, PostgreSQL, and Derby. All of those databases sometimes lose committed transactions. The test is included in the H2 download, see org.h2.test.poweroff.Test. - -@advanced_1212_h3 -永続性を実現する (しない) 方法 - -@advanced_1213_p -# Making sure that committed transactions are not lost is more complicated than it seems first. To guarantee complete durability, a database must ensure that the log record is on the hard drive before the commit call returns. To do that, databases use different methods. One is to use the 'synchronous write' file access mode. In Java, RandomAccessFile supports the modes rws and rwd: - -@advanced_1214_code -#rwd - -@advanced_1215_li -#: every update to the file's content is written synchronously to the underlying storage device. - -@advanced_1216_code -#rws - -@advanced_1217_li -#: in addition to rwd, every update to the metadata is written synchronously. - -@advanced_1218_p -# A test (org.h2.test.poweroff.TestWrite) with one of those modes achieves around 50 thousand write operations per second. Even when the operating system write buffer is disabled, the write rate is around 50 thousand operations per second. This feature does not force changes to disk because it does not flush all buffers. The test updates the same byte in the file again and again. If the hard drive was able to write at this rate, then the disk would need to make at least 50 thousand revolutions per second, or 3 million RPM (revolutions per minute). There are no such hard drives. The hard drive used for the test is about 7200 RPM, or about 120 revolutions per second. There is an overhead, so the maximum write rate must be lower than that. - -@advanced_1219_p -# Calling fsync flushes the buffers. There are two ways to do that in Java: - -@advanced_1220_code -#FileDescriptor.sync() - -@advanced_1221_li -#. The documentation says that this forces all system buffers to synchronize with the underlying device. This method is supposed to return after all in-memory modified copies of buffers associated with this file descriptor have been written to the physical medium. - -@advanced_1222_code -#FileChannel.force() - -@advanced_1223_li -# (since JDK 1.4). This method is supposed to force any updates to this channel's file to be written to the storage device that contains it. - -@advanced_1224_p -# By default, MySQL calls fsync for each commit. When using one of those methods, only around 60 write operations per second can be achieved, which is consistent with the RPM rate of the hard drive used. Unfortunately, even when calling FileDescriptor.sync() or FileChannel.force(), data is not always persisted to the hard drive, because most hard drives do not obey fsync(): see Your Hard Drive Lies to You. In Mac OS X, fsync does not flush hard drive buffers. See Bad fsync?. So the situation is confusing, and tests prove there is a problem. - -@advanced_1225_p -# Trying to flush hard drive buffers is hard, and if you do the performance is very bad. First you need to make sure that the hard drive actually flushes all buffers. Tests show that this can not be done in a reliable way. Then the maximum number of transactions is around 60 per second. Because of those reasons, the default behavior of H2 is to delay writing committed transactions. - -@advanced_1226_p -# In H2, after a power failure, a bit more than one second of committed transactions may be lost. To change the behavior, use SET WRITE_DELAY and CHECKPOINT SYNC. Most other databases support commit delay as well. In the performance comparison, commit delay was used for all databases that support it. - -@advanced_1227_h3 -永続性テストを実行する - -@advanced_1228_p -# 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. One computer just listens, while the test application is run (and power is cut) on the other computer. The computer with the listener application opens a TCP/IP port and listens for an incoming connection. The second computer first connects to the listener, and then created the databases and starts inserting records. The connection is set to 'autocommit', which means after each inserted record a commit is performed automatically. Afterwards, the test computer notifies the listener that this record was inserted successfully. The listener computer displays the last inserted record number every 10 seconds. Now, switch off the power manually, then restart the computer, and run the application again. You will find out that in most cases, none of the databases contains all the records that the listener computer knows about. For details, please consult the source code of the listener and test application. - -@advanced_1229_h2 -リカバーツールを使用する - -@advanced_1230_p -# The Recover tool can be used to extract the contents of a database file, even if the database is corrupted. It also extracts the content of the transaction log and large objects (CLOB or BLOB). To run the tool, type on the command line: - -@advanced_1231_p -# For each database in the current directory, a text file will be created. This file contains raw insert statements (for the data) and data definition (DDL) statements to recreate the schema of the database. This file can be executed using the RunScript tool or a RUNSCRIPT FROM SQL statement. The script includes at least one CREATE USER statement. If you run the script against a database that was created with the same user, or if there are conflicting users, running the script will fail. Consider running the script against a database that was created with a user name that is not in the script. - -@advanced_1232_p -# The Recover tool creates a SQL script from database file. It also processes the transaction log. - -@advanced_1233_h2 -ファイルロックプロトコル - -@advanced_1234_p -# Multiple concurrent connections to the same database are supported, however a database file can only be open for reading and writing (in embedded mode) by one process at the same time. Otherwise, the processes would overwrite each others data and corrupt the database file. To protect against this problem, whenever a database is opened, a lock file is created to signal other processes that the database is in use. If the database is closed, or if the process that opened the database stops normally, this lock file is deleted. - -@advanced_1235_p -# In special cases (if the process did not terminate normally, for example because there was a power failure), 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. However, this software uses a challenge-response protocol to protect the database 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'. - -@advanced_1236_p -# The file locking protocols have the following limitation: if a shared file system is used, and the machine with the lock owner is sent to sleep (standby or hibernate), another machine may take over. If the machine that originally held the lock wakes up, the database may become corrupt. If this situation can occur, the application must ensure the database is closed when the application is put to sleep. - -@advanced_1237_h3 -ファイルロックメソッド "File" - -@advanced_1238_p -# The default method for database file locking is the 'File Method'. The algorithm is: - -@advanced_1239_li -#If the lock file does not exist, it is created (using the atomic operation File.createNewFile). Then, the process waits a little bit (20 ms) and checks the file again. If the file was changed during this time, the operation is aborted. This protects against a race condition when one process deletes the lock file just after another one create it, and a third process creates the file again. It does not occur if there are only two writers. - -@advanced_1240_li -# If the file can be created, a random number is inserted together with the locking method ('file'). Afterwards, a watchdog thread is started that checks regularly (every second once by default) if the file was deleted or modified by another (challenger) thread / process. Whenever that occurs, the file is overwritten with the old data. The watchdog thread runs with high priority so that a change to the lock file does not get through undetected even if the system is very busy. However, the watchdog thread does use very little resources (CPU time), because it waits most of the time. Also, the watchdog only reads from the hard disk and does not write to it. - -@advanced_1241_li -# If the lock file exists and was recently modified, the process waits for some time (up to two seconds). If it was still changed, an exception is thrown (database is locked). This is done to eliminate race conditions with many concurrent writers. Afterwards, the file is overwritten with a new version (challenge). After that, the thread waits for 2 seconds. If there is a watchdog thread protecting the file, he will overwrite the change and this process will fail to lock the database. However, if there is no watchdog thread, the lock file will still be as written by this thread. In this case, the file is deleted and atomically created again. The watchdog thread is started in this case and the file is locked. - -@advanced_1242_p -# This algorithm is tested with over 100 concurrent threads. In some cases, when there are many concurrent threads trying to lock the database, they block each other (meaning the file cannot be locked by any of them) for some time. However, the file never gets 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. - -@advanced_1243_h3 -ファイルロックメソッド "Socket" - -@advanced_1244_p -# There is a second locking mechanism implemented, but disabled by default. To use it, append ;FILE_LOCK=SOCKET to the database URL. The algorithm is: - -@advanced_1245_li -#If the lock file does not exist, it is created. Then a server socket is opened on a defined port, and kept open. The port and IP address of the process that opened the database is written into the lock file. - -@advanced_1246_li -#If the lock file exists, and the lock method is 'file', then the software switches to the 'file' method. - -@advanced_1247_li -#If the lock file exists, and the lock method is 'socket', then the process checks if the port is in use. If the original process is still running, the port is in use and this process throws an exception (database is in use). If the original process died (for example due to a power failure, or abnormal termination of the virtual machine), then the port was released. The new process deletes the lock file and starts again. - -@advanced_1248_p -# This method does not require a watchdog thread actively polling (reading) the same file every second. The problem with this method is, if the file is stored on a network share, two processes (running on different computers) could still open the same database files, if they do not have a direct TCP/IP connection. - -@advanced_1249_h2 -#File Locking Method 'Serialized' - -@advanced_1250_p -# This locking mode allows to open multiple connections to the same database. The connections may be opened from multiple processes and from different computers. When writing to the database, access is automatically synchronized internally. Write operations are slower than when using the server mode, and concurrency is relatively poor. The advantage of this mode is that there is no need to start a server. - -@advanced_1251_p -# To enable this feature, append ;FILE_LOCK=SERIALIZED to the database URL. - -@advanced_1252_p -# This feature is relatively new. When using it for production, please ensure your use case is well tested (if possible with automated test cases). - -@advanced_1253_h2 -SQLインジェクションに対する防御 - -@advanced_1254_h3 -SQLインジェクションとは - -@advanced_1255_p -# This database engine provides a solution for the security vulnerability known as 'SQL Injection'. Here is a short description of what SQL injection means. Some applications build SQL statements with embedded user input such as: - -@advanced_1256_p -# If this mechanism is used anywhere in the application, and user input is not correctly filtered or encoded, it is possible for a user to inject SQL functionality or statements by using specially built input such as (in this example) this password: ' OR ''='. In this case the statement becomes: - -@advanced_1257_p -# Which is always true no matter what the password stored in the database is. For more information about SQL Injection, see Glossary and Links. - -@advanced_1258_h3 -リテラルを無効にする - -@advanced_1259_p -# SQL Injection is not possible if user input is not directly embedded in SQL statements. A simple solution for the problem above is to use a prepared statement: - -@advanced_1260_p -# This database provides a way to enforce usage of parameters when passing user input to the database. This is done by disabling embedded literals in SQL statements. To do this, execute the statement: - -@advanced_1261_p -# Afterwards, SQL statements with text and number literals are not allowed any more. That means, SQL statement of the form WHERE NAME='abc' or WHERE CustomerId=10 will fail. It is still possible to use prepared statements and parameters as described above. Also, it is still possible to generate SQL statements dynamically, and use the Statement API, as long as the SQL statements do not include literals. There is also a second mode where number literals are allowed: SET ALLOW_LITERALS NUMBERS. To allow all literals, execute SET ALLOW_LITERALS ALL (this is the default setting). Literals can only be enabled or disabled by an administrator. - -@advanced_1262_h3 -定数を使用する - -@advanced_1263_p -# Disabling literals also means disabling hard-coded 'constant' literals. This database supports defining constants using the CREATE CONSTANT command. Constants can be defined only when literals are enabled, but used even when literals are disabled. To avoid name clashes with column names, constants can be defined in other schemas: - -@advanced_1264_p -# Even when literals are enabled, it is better to use constants instead of hard-coded number or text literals in queries or views. With constants, typos are found at compile time, the source code is easier to understand and change. - -@advanced_1265_h3 -ZERO() 関数を使用する - -@advanced_1266_p -# It is not required to create a constant for the number 0 as there is already a built-in function ZERO(): - -@advanced_1267_h2 -#Protection against Remote Access - -@advanced_1268_p -# By default this database does not allow connections from other machines when starting the H2 Console, the TCP server, or the PG server. Remote access can be enabled using the command line options -webAllowOthers, -tcpAllowOthers, -pgAllowOthers. If you enable remote access, please also consider using the options -baseDir, -ifExists, so that remote users can not create new databases or access existing databases with weak passwords. When using the option -baseDir, only databases within that directory may be accessed. Ensure the existing accessible databases are protected using strong passwords. - -@advanced_1269_h2 -#Restricting Class Loading and Usage - -@advanced_1270_p -# By default there is no restriction on loading classes and executing Java code for admins. That means an admin may call system functions such as System.setProperty by executing: - -@advanced_1271_p -# To restrict users (including admins) from loading classes and executing code, the list of allowed classes can be set in the system property h2.allowedClasses in the form of a comma separated list of classes or patterns (items ending with *). By default all classes are allowed. Example: - -@advanced_1272_p -# This mechanism is used for all user classes, including database event listeners, trigger classes, user-defined functions, user-defined aggregate functions, and JDBC driver classes (with the exception of the H2 driver) when using the H2 Console. - -@advanced_1273_h2 -セキュリティプロトコル - -@advanced_1274_p -# 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. - -@advanced_1275_h3 -ユーザーパスワードの暗号化 - -@advanced_1276_p -# When a user tries to connect to a database, the combination of user name, @, and password are hashed using SHA-256, and this hash value is transmitted to the database. This step does not protect against an attacker that re-uses the value if he is able to listen to the (unencrypted) transmission between the client and the server. But, the passwords are never transmitted as plain text, even when using an unencrypted connection between client and server. 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. - -@advanced_1277_p -# When a new database or user is created, a new random salt value is generated. The size of the salt is 64 bits. Using the random salt reduces the risk of an attacker pre-calculating hash values for many different (commonly used) passwords. - -@advanced_1278_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 user-password hash value with the stored salt value and calculates the hash value. Other products use multiple iterations (hash the hash value again and again), but this is not done in this product to reduce the risk of denial of service attacks (where the attacker tries to connect with bogus passwords, and the server 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 accessible remotely, then the iteration count is not required at all. - -@advanced_1279_h3 -ファイル暗号化 - -@advanced_1280_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. - -@advanced_1281_p -# When a user tries to connect to an encrypted database, the combination of file@ and the file password is hashed using SHA-256. This hash value is transmitted to the server. - -@advanced_1282_p -# When a new database file is created, a new cryptographically secure random salt value is generated. The size of the salt is 64 bits. 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. - -@advanced_1283_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. - -@advanced_1284_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. - -@advanced_1285_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. - -@advanced_1286_p -# Therefore, the block cipher mode 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. - -@advanced_1287_p -# Database encryption is meant for securing the database while it is not in use (stolen laptop and so on). It is not meant for cases where the attacker has access to files while the database is in use. When he has write access, he can for example replace pieces of files with pieces of older versions and manipulate data like this. - -@advanced_1288_p -# File encryption slows down the performance of the database engine. Compared to unencrypted mode, database operations take about 2.2 times longer when using XTEA, and 2.5 times longer using AES (embedded mode). - -@advanced_1289_h3 -#Wrong Password / User Name Delay - -@advanced_1290_p -# To protect against remote brute force password attacks, the delay after each unsuccessful login gets double as long. Use the system properties h2.delayWrongPasswordMin and h2.delayWrongPasswordMax to change the minimum (the default is 250 milliseconds) or maximum delay (the default is 4000 milliseconds, or 4 seconds). The delay only applies for those using the wrong password. Normally there is no delay for a user that knows the correct password, with one exception: after using the wrong password, there is a delay of up to (randomly distributed) the same delay as for a wrong password. This is to protect against parallel brute force attacks, so that an attacker needs to wait for the whole delay. Delays are synchronized. This is also required to protect against parallel attacks. - -@advanced_1291_p -# There is only one exception message for both wrong user and for wrong password, to make it harder to get the list of user names. It is not possible from the stack trace to see if the user name was wrong or the password. - -@advanced_1292_h3 -HTTPS 接続 - -@advanced_1293_p -# 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. - -@advanced_1294_h2 -SSL/TLS 接続 - -@advanced_1295_p -# Remote SSL/TLS connections are supported using the Java Secure Socket Extension (SSLServerSocket, SSLSocket). By default, anonymous SSL is enabled. The default cipher suite is SSL_DH_anon_WITH_RC4_128_MD5. - -@advanced_1296_p -# To use your own keystore, set the system properties javax.net.ssl.keyStore and javax.net.ssl.keyStorePassword before starting the H2 server and client. See also Customizing the Default Key and Trust Stores, Store Types, and Store Passwords for more information. - -@advanced_1297_p -# To disable anonymous SSL, set the system property h2.enableAnonymousSSL to false. - -@advanced_1298_h2 -汎用一意識別子 (UUID) - -@advanced_1299_p -# This database supports UUIDs. Also supported is a function to create new UUIDs using a cryptographically strong pseudo random number generator. With random UUIDs, the chance of two having the same value can be calculated using the probability theory. See also 'Birthday Paradox'. Standardized randomly generated UUIDs have 122 random bits. 4 bits are used for the version (Randomly generated UUID), and 2 bits for the variant (Leach-Salz). This database supports generating such UUIDs using the built-in function RANDOM_UUID(). Here is a small program to estimate the probability of having two identical UUIDs after generating a number of values: - -@advanced_1300_p -# Some values are: - -@advanced_1301_th -#Number of UUIs - -@advanced_1302_th -#Probability of Duplicates - -@advanced_1303_td -#2^36=68'719'476'736 - -@advanced_1304_td -#0.000'000'000'000'000'4 - -@advanced_1305_td -#2^41=2'199'023'255'552 - -@advanced_1306_td -#0.000'000'000'000'4 - -@advanced_1307_td -#2^46=70'368'744'177'664 - -@advanced_1308_td -#0.000'000'000'4 - -@advanced_1309_p -# To help non-mathematicians understand what those numbers mean, here a comparison: 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. - -@advanced_1310_h2 -システムプロパティから読み込まれた設定 - -@advanced_1311_p -# Some settings of the database can be set on the command line using -DpropertyName=value. It is usually not required to change those settings manually. The settings are case sensitive. Example: - -@advanced_1312_p -# The current value of the settings can be read in the table INFORMATION_SCHEMA.SETTINGS. - -@advanced_1313_p -# For a complete list of settings, see SysProperties. - -@advanced_1314_h2 -#Setting the Server Bind Address - -@advanced_1315_p -# Usually server sockets accept connections on any/all local addresses. This may be a problem on multi-homed hosts. To bind only to one address, use the system property h2.bindAddress. This setting is used for both regular server sockets and for SSL server sockets. IPv4 and IPv6 address formats are supported. - -@advanced_1316_h2 -#Pluggable File System - -@advanced_1317_p -# This database supports a pluggable file system API. The file system implementation is selected using a file name prefix. The following file systems are included: - -@advanced_1318_code -#zip: - -@advanced_1319_li -# read-only zip-file based file system. Format: zip:/zipFileName!/fileName. - -@advanced_1320_code -#nio: - -@advanced_1321_li -# file system that uses FileChannel instead of RandomAccessFile (faster in some operating systems). - -@advanced_1322_code -#nioMapped: - -@advanced_1323_li -# file system that uses memory mapped files (faster in some operating systems). - -@advanced_1324_code -#split: - -@advanced_1325_li -# file system that splits files in 1 GB files (stackable with other file systems). - -@advanced_1326_code -#memFS: - -@advanced_1327_li -# in-memory file system (slower than mem; experimental; mainly used for testing the database engine itself). - -@advanced_1328_code -#memLZF: - -@advanced_1329_li -# compressing in-memory file system (slower than memFS but uses less memory; experimental; mainly used for testing the database engine itself). - -@advanced_1330_p -# As an example, to use the the nio file system, use the following database URL: jdbc:h2:nio:~/test. - -@advanced_1331_p -# To register a new file system, extend the classes org.h2.store.fs.FileSystem, FileObject, and call the method FileSystem.register before using it. - -@advanced_1332_h2 -#Limits and Limitations - -@advanced_1333_p -# This database has the following known limitations: - -@advanced_1334_li -#Database file size limits (excluding BLOB and CLOB data): With the default storage mechanism, the maximum file size is currently 256 GB for the data, and 256 GB for the index. With the page store (experimental): 4 TB or higher. - -@advanced_1335_li -#BLOB and CLOB size limit: every CLOB or BLOB can be up to 256 GB. - -@advanced_1336_li -#The maximum file size for FAT or FAT32 file systems is 4 GB. That means when using FAT or FAT32, the limit is 4 GB for the data. This is the limitation of the file system. The database does provide a workaround for this problem, it is to use the file name prefix split:. In that case files are split into files of 1 GB by default. An example database URL is: jdbc:h2:split:~/test. - -@advanced_1337_li -#The maximum number of rows per table is 2'147'483'648. - -@advanced_1338_li -#Main memory requirements: The larger the database, the more main memory is required. With the default storage mechanism, the minimum main memory required for a 12 GB database is around 240 MB. With the page store (experimental), the minimum main memory required is much lower, around 1 MB for each 8 GB database file size. - -@advanced_1339_li -#Limit on the complexity of SQL statements. Statements of the following form will result in a stack overflow exception: - -@advanced_1340_li -#There is no limit for the following entities, except the memory and storage capacity: maximum identifier length (table name, column name, and so on); maximum number of tables, columns, indexes, triggers, and other database objects; maximum statement length, number of parameters per statement, tables per statement, expressions in order by, group by, having, and so on; maximum rows per query; maximum columns per table, columns per index, indexes per table, lob columns per table, and so on; maximum row length, index row length, select row length; maximum length of a varchar column, decimal column, literal in a statement. - -@advanced_1341_li -#For limitations on data types, see the documentation of the respective Java data type or the data type documentation of this database. - -@advanced_1342_h2 -用語集とリンク - -@advanced_1343_th -用語 - -@advanced_1344_th -説明 - -@advanced_1345_td -AES-128 - -@advanced_1346_td -#A block encryption algorithm. See also: Wikipedia: AES - -@advanced_1347_td -Birthday Paradox - -@advanced_1348_td -#Describes the higher than expected probability that two persons in a room have the same birthday. Also valid for randomly generated UUIDs. See also: Wikipedia: Birthday Paradox - -@advanced_1349_td -Digest - -@advanced_1350_td -#Protocol to protect a password (but not to protect data). See also: RFC 2617: HTTP Digest Access Authentication - -@advanced_1351_td -GCJ - -@advanced_1352_td -#Compiler for Java. GNU Compiler for the Java and NativeJ (commercial) - -@advanced_1353_td -HTTPS - -@advanced_1354_td -#A protocol to provide security to HTTP connections. See also: RFC 2818: HTTP Over TLS - -@advanced_1355_td -Modes of Operation - -@advanced_1356_a -#Wikipedia: Block cipher modes of operation - -@advanced_1357_td -Salt - -@advanced_1358_td -#Random number to increase the security of passwords. See also: Wikipedia: Key derivation function - -@advanced_1359_td -SHA-256 - -@advanced_1360_td -#A cryptographic one-way hash function. See also: Wikipedia: SHA hash functions - -@advanced_1361_td -SQLインジェクション - -@advanced_1362_td -#A security vulnerability where an application embeds SQL statements or expressions in user input. See also: Wikipedia: SQL Injection - -@advanced_1363_td -Watermark Attack (透かし攻撃) - -@advanced_1364_td -#Security problem of certain encryption programs where the existence of certain data can be proven without decrypting. For more information, search in the internet for 'watermark attack cryptoloop' - -@advanced_1365_td -SSL/TLS - -@advanced_1366_td -#Secure Sockets Layer / Transport Layer Security. See also: Java Secure Socket Extension (JSSE) - -@advanced_1367_td -XTEA - -@advanced_1368_td -#A block encryption algorithm. See also: Wikipedia: XTEA - -@build_1000_h1 -ビルド - -@build_1001_a -# Portability - -@build_1002_a -# Environment - -@build_1003_a -# Building the Software - -@build_1004_a -# Build Targets - -@build_1005_a -# Using Maven 2 - -@build_1006_a -# Translating - -@build_1007_a -# Providing Patches - -@build_1008_a -# Reporting Problems or Requests - -@build_1009_a -# Automated Build - -@build_1010_a -# Generating Railroad Diagrams - -@build_1011_h2 -ポータビリティ - -@build_1012_p -# This database is written in Java and therefore works on many platforms. It can also be compiled to a native executable using GCJ. - -@build_1013_p -# For Java 1.4, the jar file needs to be converted first using Retrotranslator. - -@build_1014_h2 -環境 - -@build_1015_p -# To run this database, a Java Runtime Environment (JRE) version 1.5 or higher is required. - -@build_1016_p -# To create the database executables, the following software stack was used. To use this database, it is not required to install this software however. - -@build_1017_li -#Mac OS X and Windows XP - -@build_1018_a -#Sun JDK Version 1.5 and 1.6 - -@build_1019_a -#Eclipse Version 3.4 - -@build_1020_li -#Eclipse Plugins: Subclipse, Eclipse Checkstyle Plug-in, EclEmma Java Code Coverage 1.3.0 - -@build_1021_a -#Emma Java Code Coverage - -@build_1022_a -#Mozilla Firefox - -@build_1023_a -#OpenOffice - -@build_1024_a -#NSIS 2.38 - -@build_1025_li -# (Nullsoft Scriptable Install System) - -@build_1026_a -#Maven - -@build_1027_h2 -ソフトウェアのビルド - -@build_1028_p -# You need to install a JDK, for example the Sun JDK version 1.5 or 1.6. Ensure that Java binary directory is included in the PATH environment variable, and that the environment variable JAVA_HOME points to your Java installation. On the command line, go to the directory h2 and execute the following command: - -@build_1029_p -# For Linux and OS X, use ./build.sh instead of build. - -@build_1030_p -# You will get a list of targets. If you want to build the jar file, execute (Windows): - -@build_1031_h3 -#Switching the Source Code - -@build_1032_p -# By default the source code uses Java 1.5 features, however Java 1.6 is supported as well. To switch the source code to the installed version of Java, run: - -@build_1033_h2 -#Build Targets - -@build_1034_p -# The build system can generate smaller jar files as well. The following targets are currently supported: - -@build_1035_code -#jarClient - -@build_1036_li -# creates the file h2client.jar. This only contains the JDBC client. - -@build_1037_code -#jarSmall - -@build_1038_li -# creates the file h2small.jar. This only contains the embedded database. Debug information is disabled. - -@build_1039_code -#jarJaqu - -@build_1040_li -# creates the file h2jaqu.jar. This only contains the JaQu (Java Query) implementation. All other jar files do not include JaQu. - -@build_1041_code -#javadocImpl - -@build_1042_li -# creates the Javadocs of the implementation. - -@build_1043_p -# To create the file h2client.jar, go to the directory h2 and execute the following command: - -@build_1044_h2 -Maven 2 の利用 - -@build_1045_h3 -Centralリポジトリの利用 - -@build_1046_p -# You can include the database in your Maven 2 project as a dependency. Example: - -@build_1047_p -# New versions of this database are first uploaded to http://hsql.sourceforge.net/m2-repo/ and then automatically synchronized with the main Maven repository; however after a new release it may take a few hours before they are available there. - -@build_1048_h3 -スナップショットバージョンの利用 - -@build_1049_p -# To build a h2-*-SNAPSHOT.jar file and upload it the to the local Maven 2 repository, execute the following command: - -@build_1050_p -# Afterwards, you can include the database in your Maven 2 project as a dependency: - -@build_1051_h2 -#Translating - -@build_1052_p -# The translation of this software is split into the following parts: - -@build_1053_li -#H2 Console: src/main/org/h2/server/web/res/_text_*.prop - -@build_1054_li -#Error messages: src/main/org/h2/res/_messages_*.prop - -@build_1055_p -# To translate the H2 Console, start it and select Preferences / Translate. After you are done, send the translated *.prop file to the Google Group. The web site is currently translated using Google. - -@build_1056_h2 -#Providing Patches - -@build_1057_p -# If you like to provide patches, please consider the following guidelines to simplify merging them: - -@build_1058_li -#Only use Java 1.5 features (do not use Java 1.6) (see Environment). - -@build_1059_li -#Follow the coding style used in the project, and use Checkstyle (see above) to verify. For example, do not use tabs (use spaces instead). The checkstyle configuration is in src/installer/checkstyle.xml. - -@build_1060_li -#A template of the Eclipse settings are in src/installer/eclipse.settings/*. If you want to use them, you need to copy them to the .settings directory. The formatting options (eclipseCodeStyle) are also included. - -@build_1061_li -#Please provide test cases and integrate them into the test suite. For Java level tests, see src/test/org/h2/test/TestAll.java. For SQL level tests, see src/test/org/h2/test/test.in.txt or testSimple.in.txt. - -@build_1062_li -#The test cases should cover at least 90% of the changed and new code; use a code coverage tool to verify that (see above). or use the build target coverage. - -@build_1063_li -#Verify that you did not break other features: run the test cases by executing build test. - -@build_1064_li -#Provide end user documentation if required (src/docsrc/html/*). - -@build_1065_li -#Document grammar changes in src/docsrc/help/help.csv - -@build_1066_li -#Provide a change log entry (src/docsrc/html/changelog.html). - -@build_1067_li -#Verify the spelling using build spellcheck. If required add the new words to src/tools/org/h2/build/doc/dictionary.txt. - -@build_1068_li -#Run src/installer/buildRelease to find and fix formatting errors. - -@build_1069_li -#Verify the formatting using build docs and build javadoc. - -@build_1070_li -#Submit patches as .patch files (compressed if big). To create a patch using Eclipse, use Team / Create Patch. - -@build_1071_p -# For legal reasons, patches need to be public in the form of an email to the group, or in the form of an issue report or attachment. Significant contributions need to include the following statement: - -@build_1072_p -# "I wrote the code, it's mine, and I'm contributing it to H2 for distribution multiple-licensed under the H2 License, version 1.0, and under the Eclipse Public License, version 1.0 (http://h2database.com/html/license.html)." - -@build_1073_h2 -#Reporting Problems or Requests - -@build_1074_p -# Please consider the following checklist if you have a question, want to report a problem, or if you have a feature request: - -@build_1075_li -#Feature requests are always welcome, even if the feature is already on the roadmap. Your mail will help prioritize feature requests. If you urgently need a feature, consider providing a patch. - -@build_1076_li -#Before posting problems, check the FAQ and do a Google search. - -@build_1077_li -#When got an unexpected exception, please try the Error Analyzer tool. If this doesn't help, please report the problem, including the complete error message and stack trace, and the root cause stack trace(s). - -@build_1078_li -#When sending source code, please use a public web clipboard such as Pastebin, Cl1p, or Mystic Paste to avoid formatting problems. Please keep test cases as simple and short as possible, but so that the problem can still be reproduced. As a template, use: HelloWorld.java. Method that simply call other methods should be avoided, as well as unnecessary exception handling. Please use the JDBC API and no external tools or libraries. The test should include all required initialization code, and should be started with the main method. - -@build_1079_li -#For large attachments, use a public temporary storage such as Rapidshare. - -@build_1080_li -#Google Group versus issue tracking: Use the Google Group for questions or if you are not sure it's a bug. If you are sure it's a bug, you can create an issue, but you don't need to (sending an email to the group is enough). Please note that only few people monitor the issue tracking system. - -@build_1081_li -#For out-of-memory problems, please analyze the problem yourself first, for example using the command line option -XX:+HeapDumpOnOutOfMemoryError and a memory analysis tool such as the Eclipse Memory Analyzer (MAT). - -@build_1082_li -#It may take a few days to get an answers. Please do not double post. - -@build_1083_h2 -#Automated Build - -@build_1084_p -# This build process is automated and runs regularly. The build process includes running the tests and code coverage, using the command line ./build.sh clean jar coverage -Dh2.ftpPassword=... uploadBuild. The last results are available here: - -@build_1085_a -#Test Output - -@build_1086_a -#Code Coverage Summary - -@build_1087_a -#Code Coverage Details (download, 1.3 MB) - -@build_1088_a -#Build Newsfeed - -@build_1089_a -#Latest Jar File (download, 1 MB) - -@build_1090_h2 -#Generating Railroad Diagrams - -@build_1091_p -# The railroad diagrams are HTML, formatted as nested tables. The diagrams are generated as follows: - -@build_1092_li -#The BNF parser (org.h2.bnf.Bnf) reads and parses the BNF from the file help.csv. - -@build_1093_li -#The page parser (org.h2.server.web.PageParser) reads the template HTML file and fills in the diagrams. - -@build_1094_li -#The rail images (one straight, four junctions, two turns) are generated using a simple Java application. - -@build_1095_p -# To generate railroad diagrams for other grammars, see the package org.h2.jcr. This package is used to generate the SQL-2 railroad diagrams for the JCR 2.0 specification. - -@changelog_1000_h1 -変更履歴 - -@changelog_1001_h2 -#Next Version (unreleased) - -@changelog_1002_li -#- - -@changelog_1003_h2 -#Version 1.2.137 (2010-06-06) - -@changelog_1004_li -#Statements with a nested query and a condition that was always NULL threw an IndexOutOfBoundsException. Example: select * from (select null as x) where x=1 - -@changelog_1005_li -#Experimental feature to support very large transactions (except when using MVCC). To enable, set the system property h2.largeTransactions to true. If enabled, changes to tables without a primary key can be buffered to disk. The plan is to enable this feature by default in version 1.3.x. - -@changelog_1006_li -#H2 Console: editing result sets is now also working for database other than H2, if they do support updatable result sets. Add "@edit" before the query. Only limited testing has been done on this feature, some data types may not work (please provide feedback if you find issues). - -@changelog_1007_li -#Cluster: an open transaction was committed when a cluster node was stopped (because disabling the cluster executes SET CLUSTER '', which committed the transaction). Transaction are no longer committed when calling SET CLUSTER. Issue 199. - -@changelog_1008_li -#Cluster: non-admin users couldn't connect to the cluster and couldn't disable the cluster. Issue 201. - -@changelog_1009_li -#Cluster: NEXTVAL('sequence') was only called on one cluster node, therefore sequence values could get out of sync. - -@changelog_1010_li -#Version 1.2.136 could not be converted to Java 1.4 (because the Retrotranslator doesn't support BigDecimal.precision). A workaround has been implemented. - -@changelog_1011_li -#The error code of IO exceptions in CSV functions was incorrect. - -@changelog_1012_li -#The TriggerPassData example now uses a prefix (the database name). - -@changelog_1013_li -#The wrong exception was thrown when trying to reference a table that doesn't support references such as a table in the information schema. - -@changelog_1014_li -#Server.shutdownTcpServer can now stop all TCP servers on this JVM. - -@changelog_1015_li -#JdbcConnectionPool: the default connection timeout is now 30 seconds (it used to be 5 minutes). - -@changelog_1016_li -#LOB storage: LOBs added with "h2.lobInDatabase" enabled couldn't be read later with this option disabled. - -@changelog_1017_h2 -#Version 1.2.136 (2010-05-24) - -@changelog_1018_li -#When using ORDER BY and there are both ascending and descending indexes, the database used the first index even when the second one could be used for sorting. - -@changelog_1019_li -#Conditions of the form columnName IS NULL now use an index. To disable this feature, set the system property h2.optimizeIsNull to false. - -@changelog_1020_li -#H2 Console: when the settings were not stored yet (for example when running for the first time), the last recently used settings were not stored. A workaround was to create the file ".h2.server.properties" manually in the current user home directory, with the contents: webAllowOthers=false, webPort=8082, webSSL=false, 0=Generic H2 (Embedded)|org.h2.Driver|jdbc\:h2\:~/test|sa (where a comma is a newline). - -@changelog_1021_li -#The source code is now switched to Java 6 (JDK 1.6) by default. Java 5 (JDK 1.5) is still supported, and the jar file is still compiled for Java 5. - -@changelog_1022_li -#The BOM (the byte-order-mark) character 0xfeff at the beginning of the file is ignored. This is for compatibility with Microsoft Excel. - -@changelog_1023_li -#When opening an existing database, the cache size is set to at most half the amount of memory available for the virtual machine (Runtime.getRuntime().maxMemory()), even if the cache size setting stored in the database is larger. Setting the cache size in the database URL or explicitly using SET CACHE_SIZE overrides this value (even if larger than the physical memory). - -@changelog_1024_li -#INFORMATION_SCHEMA.SETTINGS: the cache size is now returned in KB. - -@changelog_1025_li -#New system property h2.selectForUpdateMvcc, the default is false (the feature is disabled). When enabled, SELECT ... FOR UPDATE only locks the selected rows in the MVCC mode. Aggregate or GROUP BY queries are not allowed in this case. - -@changelog_1026_li -#Profiler: improved message if there was no stack trace. - -@changelog_1027_li -#The H2 Console can now be used within another application, in a frame or iframe. Issue 197. - -@changelog_1028_li -#Recover tool: the statistics section now includes page type counts again. - -@changelog_1029_li -#Queries with multiple IN(...) conditions sometimes return the wrong results when there was a multi-column index for the column. - -@changelog_1030_li -#Queries with IN(..., NULL) did sometimes return the wrong results when there was a index for the column. - -@changelog_1031_li -#DECIMAL: faster precision and memory usage calculations. - -@changelog_1032_li -#A new class org.h2.tools.TriggerAdapter allows to use the ResultSet interface within trigger implementations. - -@changelog_1033_li -#A subselect which used an index could lead to wrong results. Fixed. - -@changelog_1034_li -#Creating a cached temporary non persistent table with a primary key threw a NullPointerException. - -@changelog_1035_h2 -#Version 1.2.135 (2010-05-08) - -@changelog_1036_li -#Temporary files were not deleted when using large transactions, disabling autocommit, and closing the session without committing. - -@changelog_1037_li -#Queries using multiple IN(..) conditions on the same table could cause repeated rows in the result set. - -@changelog_1038_li -#Translation: Lubomir Grajciar translated the H2 Console as well as all error message to Slovensky. Thanks a lot! - -@changelog_1039_li -#There was a possible Java level deadlock when opening an uninitialized database and using a file system that also opened a database. - -@changelog_1040_li -#When killing the process while the database was writing a checkpoint, while it was closing, or while running recovery (while removing temporary tables from a previous run), the database could become corrupt. A new test case has been implemented to ensure such problems can not occur in the future. - -@changelog_1041_li -#File system: new method FileSystem.setReadOnly. - -@changelog_1042_li -#The page size for new databases can now be set in the database URL using ;PAGE_SIZE=512. Currently this feature is only used to simplify testing. - -@changelog_1043_li -#New system property h2.functionsInSchema (default is false). If enabled, the SCRIPT statement always includes the schema name in the CREATE ALIAS statement (even if the schema is PUBLIC). This is not backward compatible with H2 versions 1.2.134 and older. - -@changelog_1044_li -#Functions: it is no longer required to add a space after a comma in the parameter list. Example: CREATE ALIAS PARSE_INT FOR "java.lang.Integer.parseInt(java.lang.String,int)" - -@changelog_1045_li -#Functions now reside within a schema, similar to sequences. If you do create such functions in schemas other than PUBLIC, then the database can not be opened with older versions of H2. - -@changelog_1046_li -#Cluster: after a cluster node failed, the second cluster node can now be re-created and started without having to stop the first cluster node, and without having to stop running applications. To do that, append ;AUTO_RECONNECT=TRUE to the database URL. - -@changelog_1047_li -#Auto-reconnect: if another connection uses the database in exclusive mode then this connection will try to re-connect until the exclusive mode ends. This is important when using the cluster mode. - -@changelog_1048_li -#SET EXCLUSIVE now supports 0 (disable), 1 (enable), and 2 (enable and close all other connections). - -@changelog_1049_li -#Installing the H2 as a service should now work on Windows 7. The batch files now explicitly set the directory using pushd "%~dp0". - -@changelog_1050_li -#Temporary tables can now be 'cached', that means indexes of temporary tables can be persisted. This enables very large temporary tables (both local and global). - -@changelog_1051_li -#The CreateCluster tool now sets the source database in exclusive mode before copying data to the new database. - -@changelog_1052_li -#The H2 Console now stream results one statement / result set at a time (using chunked transfer encoding). To disable, set the system property h2.consoleStream to false. This feature is not supported when using a servlet container. - -@changelog_1053_li -#The H2 Console did not call the CreateCluster tool with the correctly escaped parameters. - -@changelog_1054_li -#Improved PostgreSQL compatibility for ALTER TABLE ALTER COLUMN. - -@changelog_1055_li -#Commas at the end of INSERT ... VALUES (), (), are now supported. - -@changelog_1056_li -#The H2 Console "Start Browser" button now works even when the IP address changes while the tool runs (for example, because a wireless connection breaks, or when enabling / disabling the network connection). - -@changelog_1057_li -#When casting from float or double to BigDecimal, the result was sometimes unexpected, because "new BigDecimal(double val)" was used. Now "BigDecimal.valueOf(double val)" and "new BigDecimal(Float.toString(f))" are used. But it is still not recommended to use float or double for currency values (see data type documentation). - -@changelog_1058_li -#Global temporary tables are now deleted when closing the database. Before, they were deleted when opening the database the next time. - -@changelog_1059_li -#UNIQUE was not listed as a keyword. - -@changelog_1060_li -#Improved error message when an non-SQL-exception occurred in a user defined function. The method name and parameters are included in the error message. - -@changelog_1061_li -#For some queries, the exception did not include the SQL statement. Example: select x from system_range(1, 2) group by 'a'. - -@changelog_1062_li -#The Shell tool will execute SQL statements passed as using the command line parameter -sql. - -@changelog_1063_li -#If InetAddress.getLocalHost() fails, the database should now throw an exception. - -@changelog_1064_li -#New columns INFORMATION_SCHEMA.INDEXES.INDEX_CLASS and INFORMATION_SCHEMA.TABLES.TABLE_CLASS. - -@changelog_1065_li -#INFORMATION_SCHEMA.INDEXES.SQL now contains the CREATE INDEX statement instead of just the fully qualified index name. - -@changelog_1066_h2 -#Version 1.2.134 (2010-04-23) - -@changelog_1067_li -#New system property h2.analyzeAuto (default 0 meaning disabled) to automatically run ANALYZE after that many changes to a table. For details, see the Javadoc of this system property. The plan is to set this property to 2000 in version 1.3.x. - -@changelog_1068_li -#JdbcXAConnection.start() does not support TMJOIN. Issue 189. - -@changelog_1069_li -#MySQL compatibility: TIMESTAMPDIFF is now an alias for DATEDIFF. - -@changelog_1070_li -#MERGE did not respect foreign key and check constraints. - -@changelog_1071_li -#ALTER TABLE ALTER COLUMN: changing the data type of a column no longer makes it nullable. - -@changelog_1072_li -#When using AUTO_SERVER=TRUE, the server is now started as a daemon thread. This was a problem when using Tomcat and a connection pool. - -@changelog_1073_li -#Servers can now be started as a daemon thread using the command line options -tcpDaemon, -pgDaemon, and -webDaemon. - -@changelog_1074_li -#H2 Console: the built-in commands are now documented. - -@changelog_1075_li -#REPLACE: if any parameter is null, the result is null. - -@changelog_1076_li -#Queries with DISTINCT and ORDER BY will now use the index on ORDER BY if possible. This is specially important for queries used inside IN(SELECT ...). - -@changelog_1077_li -#The new statement EXPLAIN ANALYZE executes the statement, and displays the query plan with the actual row scan count for each table. - -@changelog_1078_li -#H2 Console: the auto-complete feature didn't quote column names that need quoting. Issue 186. - -@changelog_1079_li -#The experimental LOB storage mechanism now supports all features of the old one. To use it, set the system property "h2.lobInDatabase" to "true". If you have used this feature in version 1.2.133, you need to export and re-import the database using SCRIPT / RUNSCRIPT. - -@changelog_1080_li -#The functions isBeforeFirst() and isAfterLast() were not compliant to the JDBC spec. If the ResultSet contains no rows, they must return false. Fixed. - -@changelog_1081_li -#Filesystem parameters like "split:" didn't work in server mode with baseDir set. - -@changelog_1082_li -#If baseDir is set, and a database name is given which points to a directory outside the baseDir (eg. "../dbname"), an exception is thrown. - -@changelog_1083_h2 -#Version 1.2.133 (2010-04-10) - -@changelog_1084_li -#A new experimental LOB storage mechanism is available. When enabled, CLOB and BLOB data is stored in hidden tables in the database. To use it, set the system property "h2.lobInDatabase" to "true". Compression is not yet implemented. Duplicate objects are only stored once. Usually writing is slower, but reading is faster (mainly because of caching). - -@changelog_1085_li -#The Shell tool threw a NumberFormatException on a empty statement. - -@changelog_1086_li -#The h2small-*.jar did not support "drop all objects delete files". Now it is supported (the DeleteDbFiles tool is now included). - -@changelog_1087_li -#Operations that don't fit in memory are now faster. Temporary file handling was changed. - -@changelog_1088_li -#The default maximum log stream size is now 2 MB. This is a good value according to some performance tests. - -@changelog_1089_li -#New system property "h2.syncMethod" to configure what method to call when closing the database, on checkpoint, and on CHECKPOINT SYNC. The default is "sync" which calls RandomAccessFile.getFD().sync(). - -@changelog_1090_li -#ROWNUM could not be used for pagination. The follow query returned no rows: select x from (select *, rownum as r from system_range(1, 3)) where r=2; - -@changelog_1091_li -#Workaround for a java.sql.Date issue: years above 9999 are not formatted correctly. When calling ResultSet.getString() on a date value, an alternative formatting algorithm is used. - -@changelog_1092_li -#Prepared statements with nested subqueries did not always return the correct result. Example: select ?, ?, (select count(*) from test t, (select id from test where 0=?) t2 where t2.id=t.id) from test - -@changelog_1093_li -#When using MULTI_THREADED=TRUE, the exception following exception could be thrown: "object already exists: TABLES" - -@changelog_1094_li -#Comparison of integer columns against float numbers was not always correct. Issue 182. - -@changelog_1095_li -#H2 Console: Editing the result of a multi-line queries failed. Issue 183. - -@changelog_1096_li -#H2 Console: if the settings file (.h2.properties) can't be accessed, the exception is now ignored. - -@changelog_1097_h2 -#Version 1.2.132 (2010-03-21) - -@changelog_1098_li -#The implementation of a Java to C (source code level) converter has been started. The plan is: it should be possible to convert H2 (or a part of it) to C so that the database can be run without a JVM. This will be a long term project (it may take a year or so). - -@changelog_1099_li -#User defined table implementation can now be used using CREATE TABLE ... ENGINE. Thanks to Sergi Vladykin for implementing this feature! - -@changelog_1100_li -#Improved MS SQL Server compatibility: support string concatenation using "+". Thanks to Stepan for the patch! - -@changelog_1101_li -#When using the multi-threaded mode, running ANALYZE concurrently in multiple connections could throw an exception. - -@changelog_1102_li -#The MERGE statement is now about 30% faster when using a PreparedStatement. - -@changelog_1103_li -#Multi-column indexes where the second or later column was descending did not always produce correct results (rows were missing in the result set, or the result set was empty). - -@changelog_1104_li -#When using large transactions or a small log size, the database could get very slow (profiling shows the hotspot is in FileObjectDisk.sync()). - -@changelog_1105_li -#The Shell tool now prints the stack trace when the list mode is enabled. - -@changelog_1106_li -#CREATE ALIAS ... AS: Compilation was incorrect if the source code contained characters that are not supported by the default file encoding. - -@changelog_1107_li -#Issue 176: the JdbcDataSource now also supports a 'description' property. - -@changelog_1108_li -#The Shell tool threw a ArrayIndexOutOfBoundsException after 20 statements. - -@changelog_1109_li -#When using the small version of H2 ('jarClient'), the first call to Connection.createBlob (or similar) could throw a ClassNotFoundException because the file org.h2.store.fs.FileSystemZip is not included. This missing class is now ignored. - -@changelog_1110_li -#Literals of type BIGINT now have the correct data type. - -@changelog_1111_h2 -#Version 1.2.131 (2010-03-05) - -@changelog_1112_li -#Older versions of H2 (version 1.2.127 and older) could not connect to a new version (version 1.2.129 and newer). The connection blocked when trying to connect. Now the connection no longer blocks, instead a SQL exception is thrown. - -@changelog_1113_li -#In versions 1.2.129 and 1.2.130, a database could not be opened sometimes after dropping tables or indexes, and then creating new indexes for existing tables. The exception contained the text "parent not found" (version 1.2.129) or "Table not found" (version 1.2.130). - -@changelog_1114_li -#After the database was closed, a null pointer exception could occur in Database.flush. - -@changelog_1115_li -#An ArrayIndexOutOfBoundsException could occur in the page store (eg. on "delete from table"). Fixed. - -@changelog_1116_h2 -#Version 1.2.130 (2010-02-26) - -@changelog_1117_li -#EXPLAIN: The query plan now contains ".tableScan" if a table scan is used. - -@changelog_1118_li -#IN(..): when combining and IN(..) condition with a condition that didn't use an index, the result could contain duplicate rows. - -@changelog_1119_li -#IN(..): the index was not used if there were multiple IN(..) conditions. - -@changelog_1120_li -#For foreign key constraints, the metadata column INFORMATION_SCHEMA.INDEXES.CONSTRAINT_NAME was not set for non-unique indexes. - -@changelog_1121_li -#PostgreSQL compatibility: when using the following exception was thrown: Column "T.TYPTYPMOD" not found. Fixed. This is only when using psqlodbc_08_04*. - -@changelog_1122_li -#A tool to migrate an old database from the non-page store format to the newest version has been added in src/tools/org/h2/dev/util/Migrate.java. This file is not included in the jar file currently. - -@changelog_1123_li -#When using temporary tables, the database didn't shrink sometimes when closing. Also, sometimes a database could not recover normally. - -@changelog_1124_li -#Large transactions could run out of heap space. The maximum size of a transaction is now much larger. - -@changelog_1125_li -#The default setting for the system property h2.webMaxValueLength is now 100000 (it was 10000 before). - -@changelog_1126_li -#Creating a database was delayed about 2 seconds if the directory didn't exist. - -@changelog_1127_li -#Implemented INIT feature. If the database URL contains ";INIT=...;" then the DDL or DML commands following are executed on startup. Example URL: jdbc:h2:mem:test;INIT=RUNSCRIPT FROM '~/create.sql' (patch from Kerry Sainsbury). - -@changelog_1128_h2 -#Version 1.2.129 (2010-02-19) - -@changelog_1129_li -#The methods of the CloseListener are added to the Trigger interface. The interface CloseListener is removed. This is potentially a breaking change for existing triggers. - -@changelog_1130_li -#CREATE ALIAS: error message when compiling Java code have been improved. - -@changelog_1131_li -#MVCC: creating a table with an incorrect constraint could cause strange errors. - -@changelog_1132_li -#Hash indexes now are only used for single column indexes. - -@changelog_1133_li -#The cache types WEAK_* and TQ are no longer supported. A weak reference cache never frees up memory so it's the same as having a very large cache size. The TQ cache was not included in the jar file since a longer time, and was not tested. - -@changelog_1134_li -#The file system abstraction no longer throws SQL exceptions. - -@changelog_1135_li -#DatabaseEventListener.diskSpaceIsLow has changed. - -@changelog_1136_li -#The CompressTool no longer throw as SQL exceptions. Instead, it throws runtime exceptions. - -@changelog_1137_li -#SimpleResultSet.addColumn and addRow now can throw a IllegalStateException instead of a SQLException. - -@changelog_1138_li -#When doing an index lookup, decimal values with the same value but different scale (for example 0.00 and 0.0) where not considered equal in version 1.2.128. Now they are (unlike BigDecimal.equals()). - -@changelog_1139_li -#The BNF parser now uses the visitor pattern. - -@changelog_1140_li -#Converting a UUID to bytes was incorrect. Because of that, updatable result sets on tables with UUID primary key did not work. - -@changelog_1141_li -#The database URL property DATABASE_EVENT_LISTENER_OBJECT is no longer supported (there are problems passing objects when the PostgreSQL driver is installed as well). - -@changelog_1142_li -#H2 Console: asynchronous login (using a DatabaseEventListener) is no longer supported. - -@changelog_1143_li -#A workaround for a Windows socket problem has been implemented. Thanks a lot to Sergi Vladykin. - -@changelog_1144_li -#The Recover tool did not convert correctly convert CLOB data with non-ASCII characters. - -@changelog_1145_li -#Tools: the method run(String... args) has been renamed to runTool(String... args). - -@changelog_1146_li -#Server.startWebServer(Connection) was not working as expected. - -@changelog_1147_li -#The database URL option ACCESS_MODE_LOG is no longer supported. - -@changelog_1148_li -#The database URL option RECOVER has currently no effect. - -@changelog_1149_li -#Converting an old (non-page store) database is no longer supported using this version. - -@changelog_1150_li -#The following system properties are no longer supported: h2.overflowExceptions, h2.optimizeDropDependencies, h2.optimizeGroupSorted, h2.optimizeMinMax, h2.optimizeNot, h2.optimizeIn, h2.optimizeInJoin, h2.reuseSpace*. Most of then were there for a long time, but always with the same value. There was no unit test with the other value. So changing them was potentially dangerous (not a lot, but still). - -@changelog_1151_li -#The setting LOG has currently no effect (it only had an effect when the page store was disabled). - -@changelog_1152_li -#Disabling the page store is no longer supported. The old storage mechanism has been removed, shrinking the jar file size by almost 10%. - -@changelog_1153_li -#The translated resources are now stored in UTF-8 format. - -@changelog_1154_li -#The Windows service wrapper now detects if multiple versions of H2 are installed. - -@changelog_1155_h2 -#Version 1.2.128 (2010-01-30) - -@changelog_1156_li -#There are known errors on rollback when the page store is disabled and at the same time MVCC is used. See http://code.google.com/p/h2database/issues/detail?id=158 - -@changelog_1157_li -#The DeleteDbFiles tool deleted all files in the .lob.db directory, even files that didn't belong to the database. - -@changelog_1158_li -#Automatic conversion of old databases to the page store format failed if the database contained LOB files. - -@changelog_1159_li -#Nested subqueries didn't work for INSERT INTO and IN(..). Example: insert into test ((select 1)); - -@changelog_1160_li -#If the database was already closed using SHUTDOWN IMMEDIATELY, closing a second connection could throw a NullPointerException if there was a local temporary table. - -@changelog_1161_li -#Less classes are loaded when using the database in embedded mode. - -@changelog_1162_li -#The information schema tables are only initialized when needed. This reduces memory usage and speeds up creating in-memory databases. Each in-memory database needs about 8 KB of heap memory. - -@changelog_1163_li -#Nested UNION/INTERSECT queries with brackets could produce the wrong result if used within a subquery. Example: select count(*) from (select 1 union (select 2 intersect select 2)) x; - -@changelog_1164_li -#Comparing an column against a constant expression with a higher precision or length than the column could give wrong results (the expression was truncated before comparing). - -@changelog_1165_li -#Improved PostgreSQL compatibility (support SHOW DEFAULT_TRANSACTION_ISOLATION). - -@changelog_1166_li -#Documentation: the javadocs for Csv.write and read used the wrong default charset. - -@changelog_1167_li -#MVCC: if the table was locked in exclusive mode (such as SELECT ... FOR UPDATE), another session could query the table. This is now longer possible. - -@changelog_1168_li -#If a FOR UPDATE query was executed twice (using a PreparedStatement), the table was not locked. - -@changelog_1169_li -#Triggers: INSTEAD OF triggers are now supported. Such triggers can be defined on views. - -@changelog_1170_li -#New system property h2.identifiersToUpper. If set to false, identifiers in SQL statements are case sensitive even if they are not quoted. - -@changelog_1171_li -#Slightly improved performance if the table is already locked. - -@changelog_1172_li -#CompressLZF: faster decompression. - -@changelog_1173_li -#PgServer: the wrong size was sent for VARCHAR data. Thanks again to Sergi Vladykin for the patch. - -@changelog_1174_li -#Serialized access mode (server-less multi-connection mode): fixed getGeneratedKeys() for sequences. - -@changelog_1175_h2 -#Version 1.2.127 (2010-01-15) - -@changelog_1176_li -#Serialized access mode (server-less multi-connection mode): sequences did not work as expected (there were gaps in generated values when using multiple connections). - -@changelog_1177_li -#Page store: new databases can not be opened with older versions. - -@changelog_1178_li -#Page store: adding data to new database is now faster. - -@changelog_1179_li -#File system: getting the file name from a path is now faster. This should speed up BLOB and CLOB access. - -@changelog_1180_li -#PgServer: incorrect SQL types were returned in result set meta data. Concurrently opening a database could fail (PG catalog initialization was not synchronized). Thanks a lot to Sergi Vladykin for providing the patches! - -@changelog_1181_li -#SHOW COLUMNS did not work correctly if there where multiple indexes on the same columns. - -@changelog_1182_li -#Page store: the wrong write count was written to the database header. This could cause the server-less multi-connection mode to fail. - -@changelog_1183_li -#Result sets larger than 2 GB threw an exception "Negative seek offset". Fixed. - -@changelog_1184_li -#If the system property h2.check was set to false, an ArrayIndexOutOfBoundsException could occur. - -@changelog_1185_li -#Alter table is now supported even if a table has views defined. - -@changelog_1186_li -#Fulltext search: exceptions within the fulltext search package had the wrong SQL state. - -@changelog_1187_li -#The Lucene fulltext search ignored transaction rollback. Fixed using a trigger on rollback. - -@changelog_1188_li -#Trigger can now be called on rollback. - -@changelog_1189_li -#The shell script h2.sh ignored command line line arguments. - -@changelog_1190_li -#When running H2 in the Google AppEngine for Java, a AccessControlException could be thrown when trying to open a read-only database. Fixed. - -@changelog_1191_li -#The user home directory prefix (~) is now only expanded when followed by a slash or backslash, or standing alone. - -@changelog_1192_li -#Native fulltext search: before inserting or deleting data, FT_INIT() had to be called. This is no longer required. - -@changelog_1193_li -#The .trace.db file is now only created if required. - -@changelog_1194_li -#Shell tool: improved PostgreSQL compatibility. - -@changelog_1195_li -#Trying to open a database in read-only mode when a .lock.db file exists will now fail with a nice error message. - -@changelog_1196_li -#H2 Console: data that is too long is now abbreviated as follows: text... (100000 characters). A large binary is abbreviated as follows: abcdef... (100000 bytes). - -@changelog_1197_li -#Faster data conversion from BIGINT or INT to DECIMAL. - -@changelog_1198_li -#Server-less multi-connection mode: try to delete log files if switching between read/write operations. - -@changelog_1199_li -#CompressLZF: Faster decompress and improved javadocs - -@changelog_1200_h2 -#Version 1.2.126 (2009-12-18) - -@changelog_1201_li -#The ChangeFileEncryption tool will now fail with an exception if the database is still in use. The Backup tool will also fail except when running in quiet mode. - -@changelog_1202_li -#CSVREAD: when reading the column names from the CSV file, column names that contain no special characters are considered case insensitive now. - -@changelog_1203_li -#Optimization index conditions of the form 'column=NULL' (which is always false; unlike 'column IS NULL'). - -@changelog_1204_li -#Script command and tool: the primary key constraint is now listed before inserting the data. This will result in a smaller database when using the page store. - -@changelog_1205_li -#Statements with IN(SELECT..) conditions could produce the wrong result. Example: index on id, name; query: select * from test where id between 1 and 3 and name in (select 'World'). - -@changelog_1206_li -#Statements with IN(..) conditions could produce the wrong result when using views or nested select statements. Example: index on id; index on name; query: select * from (select * from test) where id=1 and name in('a', 'b'). select * from (select * from test) where id=1 and name in('Hello', 'World'). - -@changelog_1207_li -#Page store: a rollback of a relatively large transaction could fail with an ArrayIndexOutOfBoundsException or a 'row not found' exception in the PageBtreeIndex in some cases. - -@changelog_1208_li -#JaQu: the decompiler has been improved, and a few test cases already work. It is still incomplete however. - -@changelog_1209_li -#LIKE: any letter is now allowed after the escape character (which is still '\' by default). Previously, an exception was thrown (unlike other databases) if it was not the escape character, '_' or '%'. If the escape character appears at the end of the pattern, the result is it is ignored (like PostgreSQL and MS SQL Server). - -@changelog_1210_li -#The reserve heap memory is no longer used. - -@changelog_1211_li -#Database.checkpoint() could throw a NullPointerException. - -@changelog_1212_h2 -#Version 1.2.125 (2009-12-06) - -@changelog_1213_li -#Lucene fulltext search: the Lucene field names now match the table column names, except if the column names start with _ (in which case another _ is prepended). Unfortunately this change means existing fulltext indexes need to be re-built. - -@changelog_1214_li -#The shell tool now has a very simple statement history. - -@changelog_1215_li -#The zip file system implementation now supports the '~' home directory prefix. Example database URL: jdbc:h2:zip:~/test.zip!/test - -@changelog_1216_li -#Right outer joins on tables that were already 'inner joined' was processed incorrectly. - -@changelog_1217_li -#Temporary files from LOB objects were not deleted early enough when using the server mode. - -@changelog_1218_li -#Trying to alter a temporary table threw a strange exception. It is still not possible to do that, but the exception message is better now. - -@changelog_1219_li -#When the system property h2.maxMemoryRowsDistinct was set, and using SELECT DISTINCT, the temporary table was not correctly dropped. This could cause problems in recovery when the process was killed. - -@changelog_1220_li -#Trigger that are called before a select statement are now supported. This allows to create tables that work like materialized views. - -@changelog_1221_li -#Non-row based triggers were called even if the action didn't match the declared action (INSERT triggers were also called when deleting rows). This has been changed. The MERGE statement calls both INSERT and DELETE triggers. - -@changelog_1222_li -#Statements with IN(..) conditions could produce the wrong result or a data conversion error (since version 1.2.120). Examples: index on id, name, condition: id=1 and name in('Hello', 'x'); index on id, query: select * from (select * from test) where id=1 and name in('Hello', 'World'). - -@changelog_1223_li -#The CompressTool was not multithreading safe. Because of this, the following database operations where also not multithreading safe (even when using different databases): the SCRIPT command (only when using compression), the COMPRESS function, and storing CLOB or BLOB data (only when compression is enabled). - -@changelog_1224_li -#The compression algorithm "LZF" is now about 33% faster than before when compressing small block (around 2 KB). It is much faster than Deflate, but the compression ratio is lower. Some of the optimizations are from Sam Van Oort, thanks a lot! - -@changelog_1225_li -#Compressing large blocks of data didn't work when using the "Deflate" compression algorithm. Compressing a lot of data could run out of heap memory. - -@changelog_1226_li -#The test cases don't access the file system directly, this simplifies GAE for Java testing. Thanks to Vince Bonfanti. - -@changelog_1227_li -#More bugs in the server-less multi-connection mode have been fixed. - -@changelog_1228_li -#When running against an old database, the SCRIPT statement could generate a SQL script that contained duplicate indexes (PRIMARY_KEY_E). - -@changelog_1229_li -#JdbcConnectionPool.getConnection() could throw a NullPointerException. - -@changelog_1230_li -#User defined functions: the source code is now available using SELECT SOURCE FROM INFORMATION_SCHEMA.FUNCTION_ALIASES. - -@changelog_1231_li -#User defined functions with source code didn't work after re-opening the database. - -@changelog_1232_li -#The newsfeeds are now Atom 1.0 standard compliant. - -@changelog_1233_li -#The database is now closed after an out of memory exception, because the database could get corrupt otherwise. - -@changelog_1234_li -#Better error message if both AUTO_SERVER and SERIALIZED parameters are set to TRUE. - -@changelog_1235_li -#Drop table did not delete lob files in old file store (not PAGE_STORE). - -@changelog_1236_h2 -#Version 1.2.124 (2009-11-20) - -@changelog_1237_li -#Clustering: there is now a way to detect which cluster instances are running. - -@changelog_1238_li -#ConvertTraceFile: the SQL statement statistics are better formatted (newline are removed). - -@changelog_1239_li -#The file lock thread is now stopped when the database is closed. - -@changelog_1240_li -#Issue 140: the Script tool now supports writing to a stream. - -@changelog_1241_li -#Issue 138: the trace output of Statement.execute(String, int) and executeUpdate was incorrect. - -@changelog_1242_li -#Page store: new databases can not be opened with older versions. - -@changelog_1243_li -#Page store: multi-column indexes didn't work if the cache was very small. - -@changelog_1244_li -#Page store: opening a database could theoretically result in an endless loop. - -@changelog_1245_li -#Page store: adding large indexed columns could get very slow. - -@changelog_1246_li -#Page store: after a duplicate key exception, an ArrayIndexOutOfBoundsException could be thrown (only for very large rows). - -@changelog_1247_li -#Page store: the recover tool sometimes generated a script file that contained duplicate data. - -@changelog_1248_li -#Page store: sometimes opening a read-only database failed. - -@changelog_1249_li -#Page store: opening a database sometimes failed if large rows where updated, or if a table was truncated before. - -@changelog_1250_li -#Page store: when using a very small page size (128 bytes or smaller), writing a large row could result in an endless recursion. This is only a theoretical problem, as the page size is 2 KB. - -@changelog_1251_li -#Page store: getting the min value from a descending index with NULL entries could return the wrong result. - -@changelog_1252_li -#Page store: improved auto-recovery after power failure. - -@changelog_1253_li -#The JDBC client did not detect that it was not talking to an H2 server. This could result in strange exceptions when trying to connect to another kind of server. - -@changelog_1254_li -#User defined functions can be created with source code. Example: CREATE ALIAS HI AS 'String hi() { return "Hello"; }' - -@changelog_1255_li -#Database file lock: the exception "lock file modified in the future" is no longer thrown; instead, opening the file will be delayed by 2 seconds. - -@changelog_1256_li -#Inserting LOBs got slower each time the process was restarted. It could loop endlessly after about 1000 process restarts. - -@changelog_1257_li -#Issue 117: Multi-version concurrency: concurrent MERGE statements now work. - -@changelog_1258_li -#Improved read-only database detection. - -@changelog_1259_h2 -#Version 1.2.123 (2009-11-08) - -@changelog_1260_li -#Page store: new databases can not be opened with older versions. - -@changelog_1261_li -#Page store: updating large rows (rows with more than 2000 bytes of data) could corrupt the database. - -@changelog_1262_li -#Page store: inserting very large rows failed with ArrayIndexOutOfBoundsException. - -@changelog_1263_li -#When using multi-threaded kernel mode, setting disabling locking (LOCK_MODE=0) will now throw an exception. At this time this combination will result in corruption when multiple threads try to update the same table. - -@changelog_1264_li -#The fulltext search methods and fields are now protected instead of private, to make the classes more easily extensible. - -@changelog_1265_li -#The Lucene fulltext search now also returns the score. - -@changelog_1266_li -# New function SCOPE_IDENTITY() to avoid problems when inserting rows in a trigger. - -@changelog_1267_li -#Statement.getGeneratedKeys() returned the wrong value if a trigger changed the identity value after inserting the row. - -@changelog_1268_li -#Improved error messages: identifiers and values are now quoted. - -@changelog_1269_li -#Improved error message when casting a value failed: the column name and type is included in the message. - -@changelog_1270_li -#Improved support for GAE for Java thanks to Vince Bonfanti. - -@changelog_1271_h2 -#Version 1.2.122 (2009-10-28) - -@changelog_1272_li -#The native fulltext search now supports streaming CLOB data. - -@changelog_1273_li -#If the database URL ends with ;PAGE_STORE=TRUE and a database in the old format exists, it is automatically converted to the new page store format if possible. A backup of the database is created first. Automatic conversion is not supported if the database was not closed normally (if it contains uncommitted transactions). - -@changelog_1274_li -#Dropping the current user is now allowed if another admin user exists. - -@changelog_1275_li -#Values of type BINARY or BLOB could not be converted to the data type OTHER. - -@changelog_1276_li -#SHUTDOWN COMPACT now fully compacts the database. - -@changelog_1277_li -#New system properties h2.maxCompactCount and h2.maxCompactTime to allow changing the default behavior (at most 2 seconds compacting when closing the database). - -@changelog_1278_li -#New sorted insert optimization (see Performance / Database Performance Tuning). - -@changelog_1279_li -#Issue 116: The files h2*-sources.jar and h2*-javadoc.jar are now in the Maven repository. - -@changelog_1280_li -#Page store: opening a large database was slow if it was not closed before. - -@changelog_1281_li -#Page store: new write and read counters in the meta data table. Use SELECT * FROM INFORMATION_SCHEMA.SETTINGS WHERE NAME IN( 'info.FILE_WRITE_TOTAL', 'info.FILE_WRITE', 'info.FILE_READ', 'info.CACHE_MAX_SIZE', 'info.CACHE_SIZE') - -@changelog_1282_li -#The SQL syntax is documented using (railroad) diagrams. The diagrams are HTML. - -@changelog_1283_li -#The documentation is no longer available in Japanese because the translation was too much out of sync. Please use the Google translation instead. - -@changelog_1284_li -#Certain queries were not sorted if subselect queries were involved - -@changelog_1285_li -#More bugs in the server-less multi-connection mode have been fixed: 90097 The database is read only, caches must be cleared on reconnect, etc. - -@changelog_1286_h2 -#Version 1.2.121 (2009-10-11) - -@changelog_1287_li -#Better support GaeVFS (Google App Engine Virtual File System) thanks to Thanks to Vince Bonfanti. - -@changelog_1288_li -#CSVREAD didn't close the file. Thanks to Vince Bonfanti for the patch! - -@changelog_1289_li -#If a database in the old format exists, it is now used. The system property is used for new databases, or if databases exist in both formats. In any case, the flag in the URL overrides this logic. - -@changelog_1290_li -#Page store bugs were fixed. Large values in indexed columns could corrupt the index. - -@changelog_1291_li -#The page store did not work when using Retrotranslator (because the Retrotranslator doesn't support Integer.reverse and Long.reverse). - -@changelog_1292_li -#New system property h2.pageStoreTrim to disable shrinking the database when closing (disabled by default, meaning by default the database is trimmed). - -@changelog_1293_h2 -#Version 1.2.120 (2009-10-04) - -@changelog_1294_li -#This is a beta version. - -@changelog_1295_li -#Large updates could throw an ArrayIndexOutOfBoundsException in RowList.writeRow. - -@changelog_1296_li -#In version 1.2, the following system properties are now enabled by default: h2.pageStore, h2.nullConcatIsNull, h2.optimizeInList. The default value for h2.defaultMaxLengthInplaceLob is now 4096 (it was 1024 with version 1.1). - -@changelog_1297_li -#New databases are now stored in the new 'page store' file format. Existing databases are kept in the old file format. To use the old file format, append ;PAGE_STORE=FALSE to the database URL or set the system property h2.pageStore to false. - -@changelog_1298_li -#Issue 125: Renaming primary keys was not persistent. Fixed. Unfortunately, databases created by this version can not be opened with older versions because of this change. - -@changelog_1299_li -#Issue 124: Hibernate schema validation failed for decimal/numeric columns. This problem is fixed in the Hibernate dialect that is included with H2 (src/tools/org/hibernate/dialect/H2Dialect.java.txt), but not in Hibernate yet. - -@changelog_1300_li -#PostgreSQL compatibility: function LASTVAL() as an alias for IDENTITY(). - -@changelog_1301_li -#Linked tables now support default values when inserting, updating or merging. - -@changelog_1302_li -#Bugfixes in the page store. - -@changelog_1303_li -#Possibility to set a vendor id in Constants.java, so that unofficial builds are distinguishable from official releases. - -@changelog_1304_li -#Allow writing to linked tables in readonly databases. - -@changelog_1305_h2 -#Version 1.1.119 (2009-09-26) - -@changelog_1306_li -#SQL statements in the exception message are no longer included if they contain '--hide--'. - -@changelog_1307_li -#Temporary local tables did not always work after reconnect if AUTO_SERVER=TRUE - -@changelog_1308_li -#New system property h2.defaultMaxLengthInplaceLob to change the default maximum size of an in-place LOB object. - -@changelog_1309_li -#New system property h2.nullConcatIsNull to change the default null concatenation behavior. The default will be enabled in version 1.2. - -@changelog_1310_li -#The cache algorithm TQ is disabled in this version, because it is unstable, and because the current implementation does not have any measurable advantages over the default. - -@changelog_1311_li -#New committer: Christian Peter. He works for Docware and helped a lot finding and fixing bugs, and generally improving the database. He is now a committer. - -@changelog_1312_li -#ChangeFileEncryption did not work with Lob subdirectories. Fixed. - -@changelog_1313_li -#Issue 121: JaQu: new simple update and merge methods. - -@changelog_1314_li -#Issue 120: JaQu didn't close result sets. - -@changelog_1315_li -#Issue 119: JaQu creates wrong WHERE conditions on some inputs. - -@changelog_1316_li -#The new page store mechanism is now alpha-level quality. The next release will most likely be "1.2.120 beta" where this mode is enabled by default. To use it right now, append ;PAGE_STORE=TRUE to the database URL. The file format of this mode will probably not change any more. - -@changelog_1317_li -#SELECT COUNT(*) FROM SYSTEM_RANGE(...) returned the wrong result. Fixed. - -@changelog_1318_li -#The Recover tool now also processes the log files, however applying those changes is still a manual process. - -@changelog_1319_li -#New sample application that shows how to pass data to a trigger. - -@changelog_1320_li -#More bugs in the server-less multi-connection mode have been fixed: On Windows, two processes could write to the same database at the same time. - -@changelog_1321_li -#When loading triggers or other client classes (static functions, database event listener, user aggregate functions, other JDBC drivers), the database now uses the context class loader if the class could not be found using Class.forName(). - -@changelog_1322_li -#Updating many rows with the same CLOB or BLOB values could result in FileNotFoundException. - -@changelog_1323_li -#Statement.getConnection() threw an exception if the connection was already closed. - -@changelog_1324_li -#The native fulltext index kept a reference to a database after the database was closed. - -@changelog_1325_li -#Non-unique in-memory hash indexes are now supported. Thanks a lot to Sergi Vladykin for the patch! - -@changelog_1326_li -#The optimizer does a better job for joins if indexes are missing. - -@changelog_1327_h2 -#Version 1.1.118 (2009-09-04) - -@changelog_1328_li -#SHOW COLUMNS only listed indexed columns. - -@changelog_1329_li -#When calling SHUTDOWN IMMEDIATELY in the server mode, the .trace.db file was not closed. - -@changelog_1330_li -#DatabaseMetaData.getPrimaryKeys: the wrong constraint name was reported if there was another constraint on the same table and columns. - -@changelog_1331_li -#AUTO_INCREMENT now works in the same way in ALTER TABLE ALTER COLUMN as in CREATE TABLE (it does not create a primary key). - -@changelog_1332_li -#Native fulltext search: before searching, FT_INIT() had to be called. This is no longer required. - -@changelog_1333_li -#Better support GaeVFS (Google App Engine Virtual File System). - -@changelog_1334_li -#JaQu: the plan is to support natural (pure Java / Scala) conditions such as (id == 1 && name.equals("Test")). A proof of concept decompiler is now included (it doesn't work yet). - -@changelog_1335_li -#Various bugfixes and improvements in the page store mechanism (still experimental). - -@changelog_1336_li -#PreparedStatement.setObject now converts a java.lang.Character to a string. - -@changelog_1337_li -#H2 Console: PierPaolo Ucchino has completed the Italian translation. Thanks a lot! - -@changelog_1338_li -#Various tools now use Java 5 var-args, such as main the methods and SimpleResultSet.addRow. - -@changelog_1339_li -#H2 Console: indexes of tables of non-default schemas are now also listed. - -@changelog_1340_li -#Issue 111: Multi-version concurrency / duplicate primary key after rollback. - -@changelog_1341_li -#Issue 110: Multi-version concurrency / wrong exception is thrown. - -@changelog_1342_li -#Parser: sequenceName.NEXTVAL and CURRVAL did not respect the schema search path. - -@changelog_1343_li -#Issue 101: The following sequence could throw the exception "Row not found when trying to delete": start a transaction, insert many rows, delete many rows, rollback. The number of rows depends on the cache size. - -@changelog_1344_li -#The stack trace of very common exceptions is no longer written to the .trace.db file by default. - -@changelog_1345_li -#An optimization for OR is implemented, but disabled by default. Expressions of the type X=1 OR X=2 are converted to X IN(1, 2). To enable, set the system property h2.optimizeInList to true before loading the H2 JDBC driver. - -@changelog_1346_li -#An optimization for IN(..) and IN(SELECT...) is implemented, but disabled by default. To enable, set the system property h2.optimizeInList to true before loading the H2 JDBC driver. If enabled, this overrides h2.optimizeIn and h2.optimizeInJoin. Unlike now, this optimization will also speed up updates and deletes. - -@changelog_1347_h2 -#Version 1.1.117 (2009-08-09) - -@changelog_1348_li -#New committer: Sam Van Oort has been contributing to H2 since quite some time in many ways (on the mailing list, documentation, and in the form of patches). He is now a committer. - -@changelog_1349_li -#JaQu: the order of the fields in the database no longer needs to match the order in the database. - -@changelog_1350_li -#Issue 103: MVCC: the setting MAX_MEMORY_UNDO can currently not be supported when using multi-version concurrency, that means the complete undo log must fit in memory. - -@changelog_1351_li -#LIKE: the escape mechanism can now be disable using ESCAPE ''. The default escape character can be changed using the system property h2.defaultEscape. The default is still '\' (as in MySQL and PostgreSQL). - -@changelog_1352_li -#Views using functions were not re-evaluated when necessary. - -@changelog_1353_li -#Improved MySQL compatibility for SHOW COLUMNS. - -@changelog_1354_li -#Improved PostgreSQL compatibility for timestamp literals with timezone. - -@changelog_1355_li -#Sergi Vladykin translated the error messages to Russian. Thanks a lot! - -@changelog_1356_li -#Support for Java 6 DatabaseMetaData.getTables, getColumns, getProcedures, and getProcedureColumns. - -@changelog_1357_li -#Issue 101: Rollback of a large transaction (more than 100000 rows) could fail. - -@changelog_1358_li -#Various bugfixes and improvements in the page store mechanism (still experimental). - -@changelog_1359_li -#The functions LENGTH, OCTET_LENGTH, and BIT_LENGTH now return BIGINT. - -@changelog_1360_li -#Data types CLOB and BLOB: the maximum precision was Integer.MAX_VALUE, it is now Long.MAX_VALUE. - -@changelog_1361_li -#Multi-threaded kernel: creating and dropping temporary database objects and the potentially free pages list was not correctly synchronized. Thanks a lot to Eric Faulhaber for the test case and patch! - -@changelog_1362_li -#Parsing SQL script files is now faster. - -@changelog_1363_li -#CSV reading is now faster. - -@changelog_1364_li -#SimpleResultSet.newInstance(SimpleRowSource rs) did not work. - -@changelog_1365_h2 -#Version 1.1.116 (2009-07-18) - -@changelog_1366_li -#Server-less multi-connection mode: more bugs are fixed. - -@changelog_1367_li -#The built-in help (INFORMATION_SCHEMA.HELP) is smaller, shrinking the jar file size a bit. - -@changelog_1368_li -#H2 Console: column of tables of non-default schemas are now also listed, except for schemas starting with 'INFO'. - -@changelog_1369_li -#ALTER TABLE: removing an auto-increment or identity column didn't remove the sequence. - -@changelog_1370_li -#Creating indexes is now a bit faster. - -@changelog_1371_li -#PG Server: new system property h2.pgClientEncoding to explicitly set the encoding for clients that don't send the encoding (the default encoding is UTF-8). Thanks a lot to Sergi Vladykin for the patch! - -@changelog_1372_li -#PG Server: improved compatibility by using the type ids of the PostgreSQL driver. Thanks a lot to Sergi Vladykin for the patch! - -@changelog_1373_li -#H2 Console: Oracle system tables are no longer listed, improving performance. - -@changelog_1374_li -#Result sets are now read-only except if the statement or prepared statement was created with the concurrency ResultSet.CONCUR_UPDATABLE. This change is required because the old behavior (all result set are updatable) violated the JDBC spec. For backward compatibility, use the system property h2.defaultResultSetConcurrency. - -@changelog_1375_li -#New system property h2.defaultResultSetConcurrency to change the default result set concurrency. - -@changelog_1376_li -#JDBC: using an invalid result set type or concurrency now throws an exception. - -@changelog_1377_li -#If a pooled connection was not closed but garbage collected, a NullPointerException could occur. - -@changelog_1378_li -#Fulltext search: a NullPointerException was thrown when updating a value that was NULL previously. - -@changelog_1379_li -#The Recover tool did not work with .data.db files of the wrong size. - -@changelog_1380_li -#Triggers: if there was an exception when initializing a trigger, this exception could be hidden, and in some cases (specially when using the Lucene fulltext index mechanism) a NullPointerException was thrown later on. Now the exception that occurred on init is thrown when changing data. - -@changelog_1381_li -#The soft-references cache (CACHE_TYPE=SOFT_LRU) could throw a NullPointerException. - -@changelog_1382_li -#To enable the new page store mechanism, append ;PAGE_STORE=TRUE to the database URL. or set the system property h2.pageStore to true. This mechanism is still experimental, and the file format will change, but it is quite stable now. - -@cheatSheet_1000_h1 -#H2 Database Engine Cheat Sheet - -@cheatSheet_1001_h2 -#Using H2 - -@cheatSheet_1002_a -H2 - -@cheatSheet_1003_li -# is open source, free to use and distribute. - -@cheatSheet_1004_a -ダウンロード - -@cheatSheet_1005_li -#: jar, installer (Windows), zip. - -@cheatSheet_1006_li -#To start the H2 Console tool, double click the jar file, or run java -jar h2*.jar, h2.bat, or h2.sh. - -@cheatSheet_1007_a -#A new database is automatically created - -@cheatSheet_1008_a -#by default - -@cheatSheet_1009_li -#. - -@cheatSheet_1010_a -#Closing the last connection closes the database - -@cheatSheet_1011_li -#. - -@cheatSheet_1012_h2 -ドキュメント - -@cheatSheet_1013_p -# Reference: SQL grammar, functions, data types, tools, API - -@cheatSheet_1014_a -特徴 - -@cheatSheet_1015_p -#: fulltext search, encryption, read-only (zip/jar), CSV, auto-reconnect, triggers, user functions - -@cheatSheet_1016_a -#Database URLs - -@cheatSheet_1017_a -#Embedded - -@cheatSheet_1018_code -jdbc:h2:~/test - -@cheatSheet_1019_p -# 'test' in the user home directory - -@cheatSheet_1020_code -#jdbc:h2:/data/test - -@cheatSheet_1021_p -# 'test' in the directory /data - -@cheatSheet_1022_code -#jdbc:h2:test - -@cheatSheet_1023_p -# in the current(!) working directory - -@cheatSheet_1024_a -#In-Memory - -@cheatSheet_1025_code -#jdbc:h2:mem:test - -@cheatSheet_1026_p -# multiple connections in one process - -@cheatSheet_1027_code -jdbc:h2:mem: - -@cheatSheet_1028_p -# unnamed private; one connection - -@cheatSheet_1029_a -サーバーモード - -@cheatSheet_1030_code -#jdbc:h2:tcp://localhost/~/test - -@cheatSheet_1031_p -# user home dir - -@cheatSheet_1032_code -#jdbc:h2:tcp://localhost//data/test - -@cheatSheet_1033_p -# absolute dir - -@cheatSheet_1034_a -#Server start - -@cheatSheet_1035_p -#:java -cp *.jar org.h2.tools.Server - -@cheatSheet_1036_a -#Settings - -@cheatSheet_1037_code -#jdbc:h2:..;MODE=MySQL - -@cheatSheet_1038_a -#compatibility (or HSQLDB,...) - -@cheatSheet_1039_code -#jdbc:h2:..;TRACE_LEVEL_FILE=3 - -@cheatSheet_1040_a -#log to *.trace.db - -@cheatSheet_1041_a -#Using the JDBC API - -@cheatSheet_1042_a -#Connection Pool - -@cheatSheet_1043_a -#Maven 2 - -@cheatSheet_1044_a -#Hibernate - -@cheatSheet_1045_p -# hibernate.cfg.xml (or use the HSQLDialect): - -@cheatSheet_1046_a -#TopLink and Glassfish - -@cheatSheet_1047_p -# Datasource class: org.h2.jdbcx.JdbcDataSource - -@cheatSheet_1048_code -#oracle.toplink.essentials.platform. - -@cheatSheet_1049_code -#database.H2Platform - -@download_1000_h1 -ダウンロード - -@download_1001_h3 -#Version 1.2.137 (2010-06-06) - -@download_1002_a -Windows Installer - -@download_1003_a -Platform-Independent Zip - -@download_1004_h3 -#Version 1.2.136 (2010-05-24, Last Stable) - -@download_1005_a -Windows Installer - -@download_1006_a -Platform-Independent Zip - -@download_1007_h3 -#Download Mirror and Older Versions - -@download_1008_a -Platform-Independent Zip - -@download_1009_h3 -#Jar File - -@download_1010_a -#Maven.org - -@download_1011_a -#Sourceforge.net - -@download_1012_a -#Latest Automated Build (not released) - -@download_1013_h3 -サブバージョンのソースリポジトリ - -@download_1014_a -Google Code - -@download_1015_p -# For details about changes, see the Change Log. - -@download_1016_h3 -#News and Project Information - -@download_1017_a -#Atom Feed - -@download_1018_a -#RSS Feed - -@download_1019_a -#DOAP File - -@download_1020_p -# (what is this) - -@faq_1000_h1 -F A Q - -@faq_1001_a -# I Have a Problem or Feature Request - -@faq_1002_a -# Are there Known Bugs? When is the Next Release? - -@faq_1003_a -# Is this Database Engine Open Source? - -@faq_1004_a -# My Query is Slow - -@faq_1005_a -# How to Create a New Database? - -@faq_1006_a -# How to Connect to a Database? - -@faq_1007_a -# Where are the Database Files Stored? - -@faq_1008_a -# What is the Size Limit (Maximum Size) of a Database? - -@faq_1009_a -# Is it Reliable? - -@faq_1010_a -# Why is Opening my Database Slow? - -@faq_1011_a -# Column Names are Incorrect? - -@faq_1012_a -# Float is Double? - -@faq_1013_a -# Is the GCJ Version Stable? Faster? - -@faq_1014_a -# How to Translate this Project? - -@faq_1015_h3 -#I Have a Problem or Feature Request - -@faq_1016_p -# Please read the support checklist. - -@faq_1017_h3 -#Are there Known Bugs? When is the Next Release? - -@faq_1018_p -# Usually, bugs get fixes as they are found. There is a release every few weeks. Here is the list of known and confirmed issues: - -@faq_1019_li -#Apache Harmony: there seems to be a bug in Harmony that affects H2. See HARMONY-6505. - -@faq_1020_li -#Tomcat and Glassfish 3 set most static fields (final or non-final) to null when unloading a web application. This can cause a NullPointerException in H2 versions 1.1.107 and older, and may still not work in newer versions. Please report it if you run into this issue. In Tomcat >= 6.0 this behavior can be disabled by setting the system property org.apache.catalina.loader.WebappClassLoader.ENABLE_CLEAR_REFERENCES=false, however Tomcat may then run out of memory. A known workaround is to put the h2*.jar file in a shared lib directory (common/lib). - -@faq_1021_li -#Some problems have been found with right outer join. Internally, it is converted to left outer join, which does not always produce the same results as other databases when used in combination with other joins. - -@faq_1022_li -#When using Install4j before 4.1.4 on Linux and enabling pack200, the h2*.jar becomes corrupted by the install process, causing application failure. A workaround is to add an empty file h2*.jar.nopack next to the h2*.jar file. This problem is solved in Install4j 4.1.4. - -@faq_1023_p -# For a complete list, see Open Issues. - -@faq_1024_h3 -このデータベースエンジンはオープンソースですか? - -@faq_1025_p -# Yes. It is free to use and distribute, and the source code is included. See also under license. - -@faq_1026_h3 -#My Query is Slow - -@faq_1027_p -# Slow SELECT (or DELETE, UPDATE, MERGE) statement can have multiple reasons. Follow this checklist: - -@faq_1028_li -#Run ANALYZE (see documentation for details). - -@faq_1029_li -#Run the query with EXPLAIN and check if indexes are used (see documentation for details). - -@faq_1030_li -#If required, create additional indexes and try again using ANALYZE and EXPLAIN. - -@faq_1031_li -#If it doesn't help please report the problem. - -@faq_1032_h3 -新規データベースの構築方法は? - -@faq_1033_p -# By default, a new database is automatically created if it does not yet exist. See Creating New Databases. - -@faq_1034_h3 -データベースへの接続方法は? - -@faq_1035_p -# The database driver is org.h2.Driver, and the database URL starts with jdbc:h2:. To connect to a database using JDBC, use the following code: - -@faq_1036_h3 -データベースのファイルはどこに保存されますか? - -@faq_1037_p -# When using database URLs like jdbc:h2:~/test, the database is stored in the user directory. For Windows, this is usually C:\Documents and Settings\<userName>. If the base directory is not set (as in jdbc:h2:test), the database files are stored in the directory where the application is started (the current working directory). When using the H2 Console application from the start menu, this is <Installation Directory>/bin. The base directory can be set in the database URL. A fixed or relative path can be used. When using the URL jdbc:h2:file:data/sample, the database is stored in the directory data (relative to the current working directory). The directory is created automatically if it does not yet exist. It is also possible to use the fully qualified directory name (and for Windows, drive name). Example: jdbc:h2:file:C:/data/test - -@faq_1038_h3 -#What is the Size Limit (Maximum Size) of a Database? - -@faq_1039_p -# See Limits and Limitations. - -@faq_1040_h3 -これは信頼できるデータベースですか? - -@faq_1041_p -# That is not easy to say. It is still a quite new product. A lot of tests have been written, and the code coverage of these tests is very high. Randomized stress tests are run regularly. But there are probably still bugs that have not yet been found (as with most software). Some features are known to be dangerous, they are only supported for situations where performance is more important than reliability. Those dangerous features are: - -@faq_1042_li -#Using the transaction isolation level READ_UNCOMMITTED (LOCK_MODE 0) while at the same time using multiple connections. - -@faq_1043_li -#Disabling database file protection using (setting FILE_LOCK to NO in the database URL). - -@faq_1044_li -#Disabling referential integrity using SET REFERENTIAL_INTEGRITY FALSE. - -@faq_1045_p -# In addition to that, running out of memory should be avoided. In older versions, OutOfMemory errors while using the database could corrupt a databases. - -@faq_1046_p -# Some areas of this database are not fully tested. When using one of those features for production, please ensure your use case is well tested (if possible with automated test cases). Those areas are: - -@faq_1047_li -#Platforms other than Windows XP, Linux, Mac OS X, or JVMs other than Sun 1.5 or 1.6 - -@faq_1048_li -#The feature MULTI_THREADED - -@faq_1049_li -#The features AUTO_SERVER and AUTO_RECONNECT - -@faq_1050_li -#The file locking method 'Serialized' - -@faq_1051_li -#The MVCC (multi version concurrency) mode - -@faq_1052_li -#Cluster mode, 2-phase commit, savepoints - -@faq_1053_li -#24/7 operation - -@faq_1054_li -#Some operations on databases larger than 500 MB may be slower than expected - -@faq_1055_li -#The optimizer may not always select the best plan - -@faq_1056_li -#Fulltext search - -@faq_1057_li -#Operations on LOBs over 2 GB - -@faq_1058_p -# Areas considered experimental are: - -@faq_1059_li -#The PostgreSQL server - -@faq_1060_li -#Multi-threading within the engine using SET MULTI_THREADED=1 - -@faq_1061_li -#Compatibility modes for other databases (only some features are implemented) - -@faq_1062_li -#The soft reference cache (CACHE_TYPE=SOFT_LRU). It might not improve performance, and out of memory issues have been reported. - -@faq_1063_p -# Some users have reported that after a power failure, the database cannot be opened sometimes. In this case, use a backup of the database or the Recover tool. Please report such problems. The plan is that the database automatically recovers in all situations. - -@faq_1064_h3 -#Column Names are Incorrect? - -@faq_1065_p -# For the query SELECT ID AS X FROM TEST the method ResultSetMetaData.getColumnName() returns ID, I expect it to return X. What's wrong? - -@faq_1066_p -# This is not a bug. According the the JDBC specification, the method ResultSetMetaData.getColumnName() should return the name of the column and not the alias name. If you need the alias name, use ResultSetMetaData.getColumnLabel(). Some other database don't work like this yet (they don't follow the JDBC specification). If you need compatibility with those databases, use the Compatibility Mode, or set the system property h2.aliasColumnName. - -@faq_1067_p -# This also applies to DatabaseMetaData calls that return a result set. The columns in the JDBC API are column labels, not column names. - -@faq_1068_h3 -#Float is Double? - -@faq_1069_p -# For a table defined as CREATE TABLE TEST(X FLOAT) the method ResultSet.getObject() returns a java.lang.Double, I expect it to return a java.lang.Float. What's wrong? - -@faq_1070_p -# This is not a bug. According the the JDBC specification, the JDBC data type FLOAT is equivalent to DOUBLE, and both are mapped to java.lang.Double. See also Mapping SQL and Java Types - 8.3.10 FLOAT. - -@faq_1071_h3 -#Why is Opening my Database Slow? - -@faq_1072_p -# To find out what the problem is, use the H2 Console and click on "Test Connection" instead of "Login". After the "Login Successful" appears, click on it (it's a link). This will list the top stack traces. Then either analyze this yourself, or post those stack traces in the Google Group. - -@faq_1073_p -# To find out what the problem is, open the database in embedded mode using the H2 Console. This will print progress information. If you have many lines with 'Creating index' it is an indication that the database was not closed the last time. - -@faq_1074_p -# Other possible reasons are: the database is very big (many GB), or contains linked tables that are slow to open. - -@faq_1075_h3 -#Is the GCJ Version Stable? Faster? - -@faq_1076_p -# The GCJ version is not as stable as the Java version. When running the regression test with the GCJ version, sometimes the application just stops at what seems to be a random point without error message. Currently, the GCJ version is also slower than when using the Sun VM. However, the startup of the GCJ version is faster than when using a VM. - -@faq_1077_h3 -このプロジェクトの翻訳方法は? - -@faq_1078_p -# For more information, see Build/Translating. - -@features_1000_h1 -特徴 - -@features_1001_a -# Feature List - -@features_1002_a -# Comparison to Other Database Engines - -@features_1003_a -# H2 in Use - -@features_1004_a -# Connection Modes - -@features_1005_a -# Database URL Overview - -@features_1006_a -# Connecting to an Embedded (Local) Database - -@features_1007_a -# In-Memory Databases - -@features_1008_a -# Database Files Encryption - -@features_1009_a -# Database File Locking - -@features_1010_a -# Opening a Database Only if it Already Exists - -@features_1011_a -# Closing a Database - -@features_1012_a -# Ignore Unknown Settings - -@features_1013_a -# Changing Other Settings when Opening a Connection - -@features_1014_a -# Custom File Access Mode - -@features_1015_a -# Multiple Connections - -@features_1016_a -# Database File Layout - -@features_1017_a -# Logging and Recovery - -@features_1018_a -# Compatibility - -@features_1019_a -# Auto-Reconnect - -@features_1020_a -# Automatic Mixed Mode - -@features_1021_a -# Page Size - -@features_1022_a -# Using the Trace Options - -@features_1023_a -# Using Other Logging APIs - -@features_1024_a -# Read Only Databases - -@features_1025_a -# Read Only Databases in Zip or Jar File - -@features_1026_a -# Graceful Handling of Low Disk Space Situations - -@features_1027_a -# Computed Columns / Function Based Index - -@features_1028_a -# Multi-Dimensional Indexes - -@features_1029_a -# Using Passwords - -@features_1030_a -# User-Defined Functions and Stored Procedures - -@features_1031_a -# Triggers - -@features_1032_a -# Compacting a Database - -@features_1033_a -# Cache Settings - -@features_1034_h2 -特徴一覧 - -@features_1035_h3 -主な特徴 - -@features_1036_li -#Very fast database engine - -@features_1037_li -#Open source - -@features_1038_li -#Written in Java - -@features_1039_li -#Supports standard SQL, JDBC API - -@features_1040_li -#Embedded and Server mode, Clustering support - -@features_1041_li -#Strong security features - -@features_1042_li -#The PostgreSQL ODBC driver can be used - -@features_1043_li -#Multi version concurrency - -@features_1044_h3 -追加された特徴 - -@features_1045_li -#Disk based or in-memory databases and tables, read-only database support, temporary tables - -@features_1046_li -#Transaction support (read committed and serializable transaction isolation), 2-phase-commit - -@features_1047_li -#Multiple connections, table level locking - -@features_1048_li -#Cost based optimizer, using a genetic algorithm for complex queries, zero-administration - -@features_1049_li -#Scrollable and updatable result set support, large result set, external result sorting, functions can return a result set - -@features_1050_li -#Encrypted database (AES or XTEA), SHA-256 password encryption, encryption functions, SSL - -@features_1051_h3 -SQLサポート - -@features_1052_li -#Support for multiple schemas, information schema - -@features_1053_li -#Referential integrity / foreign key constraints with cascade, check constraints - -@features_1054_li -#Inner and outer joins, subqueries, read only views and inline views - -@features_1055_li -#Triggers and Java functions / stored procedures - -@features_1056_li -#Many built-in functions, including XML and lossless data compression - -@features_1057_li -#Wide range of data types including large objects (BLOB/CLOB) and arrays - -@features_1058_li -#Sequence and autoincrement columns, computed columns (can be used for function based indexes) - -@features_1059_code -ORDER BY, GROUP BY, HAVING, UNION, LIMIT, TOP - -@features_1060_li -#Collation support, users, roles - -@features_1061_li -#Compatibility modes for IBM DB2, Apache Derby, HSQLDB, MS SQL Server, MySQL, Oracle, and PostgreSQL. - -@features_1062_h3 -セキュリティの特徴 - -@features_1063_li -#Includes a solution for the SQL injection problem - -@features_1064_li -#User password authentication uses SHA-256 and salt - -@features_1065_li -#For server mode connections, user passwords are never transmitted in plain text over the network (even when using insecure connections; this only applies to the TCP server and not to the H2 Console however; it also doesn't apply if you set the password in the database URL) - -@features_1066_li -#All database files (including script files that can be used to backup data) can be encrypted using AES-128 and XTEA encryption algorithms - -@features_1067_li -#The remote JDBC driver supports TCP/IP connections over SSL/TLS - -@features_1068_li -#The built-in web server supports connections over SSL/TLS - -@features_1069_li -#Passwords can be sent to the database using char arrays instead of Strings - -@features_1070_h3 -他の特徴とツール - -@features_1071_li -#Small footprint (smaller than 1 MB), low memory requirements - -@features_1072_li -#Multiple index types (b-tree, tree, hash) - -@features_1073_li -#Support for multi-dimensional indexes - -@features_1074_li -#CSV (comma separated values) file support - -@features_1075_li -#Support for linked tables, and a built-in virtual 'range' table - -@features_1076_code -#EXPLAIN PLAN - -@features_1077_li -# support, sophisticated trace options - -@features_1078_li -#Database closing can be delayed or disabled to improve the performance - -@features_1079_li -#Web-based Console application (translated to many languages) with autocomplete - -@features_1080_li -#The database can generate SQL script files - -@features_1081_li -#Contains a recovery tool that can dump the contents of the database - -@features_1082_li -#Support for variables (for example to calculate running totals) - -@features_1083_li -#Automatic re-compilation of prepared statements - -@features_1084_li -#Uses a small number of database files - -@features_1085_li -#Uses a checksum for each record and log entry for data integrity - -@features_1086_li -#Well tested (high code coverage, randomized stress tests) - -@features_1087_h2 -他のデータベースエンジンと比較する - -@features_1088_th -特徴 - -@features_1089_th -H2 - -@features_1090_a -Derby - -@features_1091_a -HSQLDB - -@features_1092_a -MySQL - -@features_1093_a -PostgreSQL - -@features_1094_td -Pure Java - -@features_1095_td -対応 - -@features_1096_td -対応 - -@features_1097_td -対応 - -@features_1098_td -非対応 - -@features_1099_td -非対応 - -@features_1100_td -エンベッドモード (Java) - -@features_1101_td -対応 - -@features_1102_td -対応 - -@features_1103_td -対応 - -@features_1104_td -非対応 - -@features_1105_td -非対応 - -@features_1106_td -パフォーマンス (エンベッド) - -@features_1107_td -速い - -@features_1108_td -遅い - -@features_1109_td -速い - -@features_1110_td -該当なし - -@features_1111_td -該当なし - -@features_1112_td -#In-Memory Mode - -@features_1113_td -対応 - -@features_1114_td -対応 - -@features_1115_td -対応 - -@features_1116_td -非対応 - -@features_1117_td -非対応 - -@features_1118_td -トランザクション分離 - -@features_1119_td -対応 - -@features_1120_td -対応 - -@features_1121_td -非対応 - -@features_1122_td -対応 - -@features_1123_td -対応 - -@features_1124_td -コストベースオプティマイザ - -@features_1125_td -対応 - -@features_1126_td -対応 - -@features_1127_td -非対応 - -@features_1128_td -対応 - -@features_1129_td -対応 - -@features_1130_td -#Explain Plan - -@features_1131_td -対応 - -@features_1132_td -非対応 - -@features_1133_td -対応 - -@features_1134_td -対応 - -@features_1135_td -対応 - -@features_1136_td -クラスタリング - -@features_1137_td -対応 - -@features_1138_td -非対応 - -@features_1139_td -非対応 - -@features_1140_td -対応 - -@features_1141_td -対応 - -@features_1142_td -暗号化データベース - -@features_1143_td -対応 - -@features_1144_td -対応 - -@features_1145_td -非対応 - -@features_1146_td -非対応 - -@features_1147_td -非対応 - -@features_1148_td -リンクテーブル - -@features_1149_td -対応 - -@features_1150_td -非対応 - -@features_1151_td -#Partially *1 - -@features_1152_td -#Partially *2 - -@features_1153_td -非対応 - -@features_1154_td -ODBCドライバ - -@features_1155_td -対応 - -@features_1156_td -非対応 - -@features_1157_td -非対応 - -@features_1158_td -対応 - -@features_1159_td -対応 - -@features_1160_td -フルテキストサーチ - -@features_1161_td -対応 - -@features_1162_td -非対応 - -@features_1163_td -非対応 - -@features_1164_td -対応 - -@features_1165_td -対応 - -@features_1166_td -#User-Defined Datatypes - -@features_1167_td -対応 - -@features_1168_td -非対応 - -@features_1169_td -非対応 - -@features_1170_td -対応 - -@features_1171_td -対応 - -@features_1172_td -データベースごとのファイル - -@features_1173_td -少 - -@features_1174_td -多 - -@features_1175_td -少 - -@features_1176_td -多 - -@features_1177_td -多 - -@features_1178_td -テーブルレベルロック - -@features_1179_td -対応 - -@features_1180_td -対応 - -@features_1181_td -非対応 - -@features_1182_td -対応 - -@features_1183_td -対応 - -@features_1184_td -#Row Level Locking - -@features_1185_td -#Yes *9 - -@features_1186_td -対応 - -@features_1187_td -非対応 - -@features_1188_td -対応 - -@features_1189_td -対応 - -@features_1190_td -#Multi Version Concurrency - -@features_1191_td -対応 - -@features_1192_td -非対応 - -@features_1193_td -非対応 - -@features_1194_td -対応 - -@features_1195_td -対応 - -@features_1196_td -#Role Based Security - -@features_1197_td -対応 - -@features_1198_td -#Yes *3 - -@features_1199_td -対応 - -@features_1200_td -対応 - -@features_1201_td -対応 - -@features_1202_td -#Updatable Result Sets - -@features_1203_td -対応 - -@features_1204_td -#Yes *7 - -@features_1205_td -非対応 - -@features_1206_td -対応 - -@features_1207_td -対応 - -@features_1208_td -#Sequences - -@features_1209_td -対応 - -@features_1210_td -非対応 - -@features_1211_td -対応 - -@features_1212_td -非対応 - -@features_1213_td -対応 - -@features_1214_td -#Limit and Offset - -@features_1215_td -対応 - -@features_1216_td -非対応 - -@features_1217_td -対応 - -@features_1218_td -対応 - -@features_1219_td -対応 - -@features_1220_td -#Temporary Tables - -@features_1221_td -対応 - -@features_1222_td -#Yes *4 - -@features_1223_td -対応 - -@features_1224_td -対応 - -@features_1225_td -対応 - -@features_1226_td -#Information Schema - -@features_1227_td -対応 - -@features_1228_td -#No *8 - -@features_1229_td -#No *8 - -@features_1230_td -対応 - -@features_1231_td -対応 - -@features_1232_td -#Computed Columns - -@features_1233_td -対応 - -@features_1234_td -非対応 - -@features_1235_td -非対応 - -@features_1236_td -非対応 - -@features_1237_td -#Yes *6 - -@features_1238_td -#Case Insensitive Columns - -@features_1239_td -対応 - -@features_1240_td -非対応 - -@features_1241_td -対応 - -@features_1242_td -対応 - -@features_1243_td -#Yes *6 - -@features_1244_td -#Custom Aggregate Functions - -@features_1245_td -対応 - -@features_1246_td -非対応 - -@features_1247_td -非対応 - -@features_1248_td -対応 - -@features_1249_td -対応 - -@features_1250_td -フットプリント (jar/dll size) - -@features_1251_td -#~1 MB *5 - -@features_1252_td -#~2 MB - -@features_1253_td -#~700 KB - -@features_1254_td -#~4 MB - -@features_1255_td -#~6 MB - -@features_1256_p -# *1 HSQLDB supports text tables. - -@features_1257_p -# *2 MySQL supports linked MySQL tables under the name 'federated tables'. - -@features_1258_p -# *3 Derby support for roles based security and password checking as an option. - -@features_1259_p -# *4 Derby only supports global temporary tables. - -@features_1260_p -# *5 The default H2 jar file contains debug information, jar files for other databases do not. - -@features_1261_p -# *6 PostgreSQL supports functional indexes. - -@features_1262_p -# *7 Derby only supports updatable result sets if the query is not sorted. - -@features_1263_p -# *8 Derby and HSQLDB don't support standard compliant information schema tables. - -@features_1264_p -# *9 H2 supports row level locks when using multi version concurrency. - -@features_1265_h3 -DerbyとHSQLDB - -@features_1266_p -# After an unexpected process termination (for example power failure), H2 can usually recover safely and automatically without any user interaction. For Derby and HSQLDB, some manual steps are required ('Another instance of Derby may have already booted the database' / 'The database is already in use by another process'). - -@features_1267_h3 -DaffodilDbとOne$Db - -@features_1268_p -# It looks like the development of this database has stopped. The last release was February 2006. - -@features_1269_h3 -McKoi - -@features_1270_p -# It looks like the development of this database has stopped. The last release was August 2004 - -@features_1271_h2 -#H2 in Use - -@features_1272_p -# For a list of applications that work with or use H2, see: Links. - -@features_1273_h2 -接続モード - -@features_1274_p -# The following connection modes are supported: - -@features_1275_li -#Embedded mode (local connections using JDBC) - -@features_1276_li -#Server mode (remote connections using JDBC or ODBC over TCP/IP) - -@features_1277_li -#Mixed mode (local and remote connections at the same time) - -@features_1278_h3 -エンベッドモード - -@features_1279_p -# In embedded mode, an application opens a database from within the same JVM using JDBC. This is the fastest and easiest connection mode. The disadvantage is that a database may only be open in one virtual machine (and class loader) at any time. As in all modes, both persistent and in-memory databases are supported. There is no limit on the number of database open concurrently, or on the number of open connections. - -@features_1280_h3 -サーバーモード - -@features_1281_p -# When using the server mode (sometimes called remote mode or client/server mode), an application opens a database remotely using the JDBC or ODBC API. A server needs to be started within the same or another virtual machine, or on another computer. Many applications can connect to the same database at the same time, by connecting to this server. Internally, the server process opens the database(s) in embedded mode. - -@features_1282_p -# The server mode is slower than the embedded mode, because all data is transferred over TCP/IP. As in all modes, both persistent and in-memory databases are supported. There is no limit on the number of database open concurrently per server, or on the number of open connections. - -@features_1283_h3 -#Mixed Mode - -@features_1284_p -# The mixed mode is a combination of the embedded and the server mode. The first application that connects to a database does that in embedded mode, but also starts a server so that other applications (running in different processes or virtual machines) can concurrently access the same data. The local connections are as fast as if the database is used in just the embedded mode, while the remote connections are a bit slower. - -@features_1285_p -# The server can be started and stopped from within the application (using the server API), or automatically (automatic mixed mode). When using the automatic mixed mode, all clients that want to connect to the database (no matter if it's an local or remote connection) can do so using the exact same database URL. - -@features_1286_h2 -データベースURL概要 - -@features_1287_p -# This database supports multiple connection modes and connection settings. This is achieved using different database URLs. Settings in the URLs are not case sensitive. - -@features_1288_th -トピック - -@features_1289_th -URLフォーマットと例 - -@features_1290_a -エンベッド (ローカル) 接続 - -@features_1291_td -# jdbc:h2:[file:][<path>]<databaseName> - -@features_1292_td -# jdbc:h2:~/test - -@features_1293_td -# jdbc:h2:file:/data/sample - -@features_1294_td -# jdbc:h2:file:C:/data/sample (Windows only) - -@features_1295_a -#In-memory (private) - -@features_1296_td -jdbc:h2:mem: - -@features_1297_a -#In-memory (named) - -@features_1298_td -# jdbc:h2:mem:<databaseName> - -@features_1299_td -# jdbc:h2:mem:test_mem - -@features_1300_a -#Server mode (remote connections) - -@features_1301_a -# using TCP/IP - -@features_1302_td -# jdbc:h2:tcp://<server>[:<port>]/[<path>]<databaseName> - -@features_1303_td -# jdbc:h2:tcp://localhost/~/test - -@features_1304_td -# jdbc:h2:tcp://dbserv:8084/~/sample jdbc:h2:tcp://localhost/mem:test - -@features_1305_a -#Server mode (remote connections) - -@features_1306_a -# using SSL/TLS - -@features_1307_td -# jdbc:h2:ssl://<server>[:<port>]/<databaseName> - -@features_1308_td -# jdbc:h2:ssl://secureserv:8085/~/sample; - -@features_1309_a -#Using encrypted files - -@features_1310_td -# jdbc:h2:<url>;CIPHER=[AES|XTEA] - -@features_1311_td -# jdbc:h2:ssl://secureserv/~/testdb;CIPHER=AES - -@features_1312_td -# jdbc:h2:file:~/secure;CIPHER=XTEA - -@features_1313_a -#File locking methods - -@features_1314_td -# jdbc:h2:<url>;FILE_LOCK={FILE|SOCKET|NO} - -@features_1315_td -# jdbc:h2:file:~/private;CIPHER=XTEA;FILE_LOCK=SOCKET - -@features_1316_a -#Only open if it already exists - -@features_1317_td -# jdbc:h2:<url>;IFEXISTS=TRUE - -@features_1318_td -# jdbc:h2:file:~/sample;IFEXISTS=TRUE - -@features_1319_a -#Don't close the database when the VM exits - -@features_1320_td -# jdbc:h2:<url>;DB_CLOSE_ON_EXIT=FALSE - -@features_1321_a -#Execute SQL on connection - -@features_1322_td -# jdbc:h2:<url>;INIT=RUNSCRIPT FROM '~/create.sql' - -@features_1323_td -# jdbc:h2:file:~/sample;INIT=RUNSCRIPT FROM '~/create.sql'\\;RUNSCRIPT FROM '~/populate.sql' - -@features_1324_a -#User name and/or password - -@features_1325_td -# jdbc:h2:<url>[;USER=<username>][;PASSWORD=<value>] - -@features_1326_td -# jdbc:h2:file:~/sample;USER=sa;PASSWORD=123 - -@features_1327_a -#Debug trace settings - -@features_1328_td -# jdbc:h2:<url>;TRACE_LEVEL_FILE=<level 0..3> - -@features_1329_td -# jdbc:h2:file:~/sample;TRACE_LEVEL_FILE=3 - -@features_1330_a -#Ignore unknown settings - -@features_1331_td -# jdbc:h2:<url>;IGNORE_UNKNOWN_SETTINGS=TRUE - -@features_1332_a -#Custom file access mode - -@features_1333_td -# jdbc:h2:<url>;ACCESS_MODE_DATA=rws - -@features_1334_a -#Database in a zip file - -@features_1335_td -# jdbc:h2:zip:<zipFileName>!/<databaseName> - -@features_1336_td -# jdbc:h2:zip:~/db.zip!/test - -@features_1337_a -#Compatibility mode - -@features_1338_td -# jdbc:h2:<url>;MODE=<databaseType> - -@features_1339_td -# jdbc:h2:~/test;MODE=MYSQL - -@features_1340_a -#Auto-reconnect - -@features_1341_td -# jdbc:h2:<url>;AUTO_RECONNECT=TRUE - -@features_1342_td -# jdbc:h2:tcp://localhost/~/test;AUTO_RECONNECT=TRUE - -@features_1343_a -#Automatic mixed mode - -@features_1344_td -# jdbc:h2:<url>;AUTO_SERVER=TRUE - -@features_1345_td -# jdbc:h2:~/test;AUTO_SERVER=TRUE - -@features_1346_a -#Page size - -@features_1347_td -# jdbc:h2:<url>;PAGE_SIZE=512 - -@features_1348_a -#Changing other settings - -@features_1349_td -# jdbc:h2:<url>;<setting>=<value>[;<setting>=<value>...] - -@features_1350_td -# jdbc:h2:file:~/sample;TRACE_LEVEL_SYSTEM_OUT=3 - -@features_1351_h2 -エンベッド (ローカル) データベースに接続 - -@features_1352_p -# The database URL for connecting to a local database is jdbc:h2:[file:][<path>]<databaseName>. The prefix file: is optional. If no or only a relative path is used, then the current working directory is used as a starting point. The case sensitivity of the path and database name depend on the operating system, however it is recommended to use lowercase letters only. The database name must be at least three characters long (a limitation of File.createTempFile). To point to the user home directory, use ~/, as in: jdbc:h2:~/test. - -@features_1353_h2 -#In-Memory Databases - -@features_1354_p -# For certain use cases (for example: rapid prototyping, testing, high performance operations, read-only databases), it may not be required to persist data, or persist changes to the data. This database supports the in-memory mode, where the data is not persisted. - -@features_1355_p -# In some cases, only one connection to a in-memory database is required. This means the database to be opened is private. In this case, the database URL is jdbc:h2:mem: Opening two connections within the same virtual machine means opening two different (private) databases. - -@features_1356_p -# Sometimes multiple connections to the same in-memory database are required. In this case, the database URL must include a name. Example: jdbc:h2:mem:db1. Accessing the same database using this URL only works within the same virtual machine and class loader environment. - -@features_1357_p -# In-memory can be accessed remotely (or from multiple processes in the same machine) using TCP/IP or SSL/TLS. An example database URL is: jdbc:h2:tcp://localhost/mem:db1. - -@features_1358_p -# 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 jdbc:h2:mem:test;DB_CLOSE_DELAY=-1. - -@features_1359_h2 -#Database Files Encryption - -@features_1360_p -# The database files can be encrypted. Two encryption algorithms are supported: AES and XTEA. To use file encryption, you need to specify the encryption algorithm (the 'cipher') and the file password (in addition to the user password) when connecting to the database. - -@features_1361_h3 -#Creating a New Database with File Encryption - -@features_1362_p -# By default, a new database is automatically created if it does not exist yet. To create an encrypted database, connect to it as it would already exist. - -@features_1363_h3 -#Connecting to an Encrypted Database - -@features_1364_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 separates the file password and the user password; the file password itself may not contain spaces. File passwords and user passwords are case sensitive. Here is an example to connect to a password-encrypted database: - -@features_1365_h3 -#Encrypting or Decrypting a Database - -@features_1366_p -# To encrypt an existing database, use the ChangeFileEncryption tool. This tool can also decrypt an encrypted database, or change the file encryption key. 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: - -@features_1367_h2 -データベースファイルロック - -@features_1368_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. - -@features_1369_p -# The following file locking methods are implemented: - -@features_1370_li -#The default method is FILE and uses a watchdog thread to protect the database file. The watchdog reads the lock file each second. - -@features_1371_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 one (and always the same) computer. - -@features_1372_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. Failing to do so will result in a corrupted database. Using the method NO forces the database to not create a lock file at all. Please note that this is unsafe as another process is able to open the same database, possibly leading to data corruption. - -@features_1373_p -# To open the database with a different file locking method, use the parameter FILE_LOCK. The following code opens the database with the 'socket' locking method: - -@features_1374_p -# For more information about the algorithms, see Advanced / File Locking Protocols. - -@features_1375_h2 -すでに存在する場合のみ、データベースを開く - -@features_1376_p -# By default, when an application calls DriverManager.getConnection(url, ...) 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 databases, and only allow to open existing databases. To do this, add ;IFEXISTS=TRUE 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: - -@features_1377_h2 -#Closing a Database - -@features_1378_h3 -データベースの遅延終了 - -@features_1379_p -# 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 one 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. The following statement will keep a database open for 10 seconds after the last connection was closed: - -@features_1380_p -# The value -1 means the database is not 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: jdbc:h2:~/test;DB_CLOSE_DELAY=10. - -@features_1381_h3 -#Don't Close a Database when the VM Exits - -@features_1382_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, 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. The first connection (the one that is opening the database) needs to set the option in the database URL (it is not possible to change the setting afterwards). The database URL to disable database closing on exit is: - -@features_1383_h2 -#Execute SQL on Connection - -@features_1384_p -# Sometimes, particularly for in-memory databases, it is useful to be able to execute DDL or DML commands automatically when a client connects to a database. This functionality is enabled via the INIT property. Note that multiple commands may be passed to INIT, but the semicolon delimiter must be escaped, as in the example below. - -@features_1385_h2 -未知の設定を無視 - -@features_1386_p -# Some applications (for example OpenOffice.org Base) pass some additional parameters when connecting to the database. Why those parameters are passed is unknown. The parameters PREFERDOSLIKELINEENDS and IGNOREDRIVERPRIVILEGES are such examples; they are simply ignored to improve the compatibility with OpenOffice.org. If an application passes other parameters when connecting to the database, usually the database throws an exception saying the parameter is not supported. It is possible to ignored such parameters by adding ;IGNORE_UNKNOWN_SETTINGS=TRUE to the database URL. - -@features_1387_h2 -接続が開始された時に他の設定を変更する - -@features_1388_p -# In addition to the settings already described, other database settings can be passed in the database URL. Adding ;setting=value at the end of a database URL is the same as executing the statement SET setting value just after connecting. For a list of supported settings, see SQL Grammar. - -@features_1389_h2 -カスタムファイル アクセスモード - -@features_1390_p -# Usually, the database opens the database file with the access mode rw, meaning read-write (except for read only databases, where the mode r is used). To open a database in read-only mode if the database file is not read-only, use ACCESS_MODE_DATA=r. Also supported are rws and rwd. This setting must be specified in the database URL: - -@features_1391_p -# For more information see Durability Problems. On many operating systems the access mode rws does not guarantee that the data is written to the disk. - -@features_1392_h2 -複数の接続 - -@features_1393_h3 -同時に複数のデータベースを開く - -@features_1394_p -# An application can open multiple databases at the same time, including multiple connections to the same database. The number of open database is only limited by the memory available. - -@features_1395_h3 ->同じデータベースへの複数の接続: クライアント/サーバー - -@features_1396_p -# If you want to access the same database at the same time from different processes or computers, you need to use the client / server mode. In this case, one process acts as the server, and the other processes (that could reside on other computers as well) connect to the server via TCP/IP (or SSL/TLS over TCP/IP for improved security). - -@features_1397_h3 -マルチスレッドサポート - -@features_1398_p -# This database is multithreading-safe. That means, if an application is multi-threaded, it does not need 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. - -@features_1399_p -# An application should normally use one connection per thread. This database synchronizes access to the same connection, but other databases may not do this. - -@features_1400_h3 -ロック、ロックタイムアウト、デッドロック - -@features_1401_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). All locks are released when the transaction commits or rolls back. When using the default transaction isolation level 'read committed', read locks are already released after each statement. - -@features_1402_p -# 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 a connection cannot get a lock for a specified time, then a lock timeout exception is thrown. - -@features_1403_p -# Usually, SELECT statements 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. The following statements generate locks: - -@features_1404_th -ロックの種類 - -@features_1405_th -SQLステートメント - -@features_1406_td -Read - -@features_1407_td -#SELECT * FROM TEST; - -@features_1408_td -# CALL SELECT MAX(ID) FROM TEST; - -@features_1409_td -# SCRIPT; - -@features_1410_td -Write - -@features_1411_td -#SELECT * FROM TEST WHERE 1=0 FOR UPDATE; - -@features_1412_td -Write - -@features_1413_td -#INSERT INTO TEST VALUES(1, 'Hello'); - -@features_1414_td -# INSERT INTO TEST SELECT * FROM TEST; - -@features_1415_td -# UPDATE TEST SET NAME='Hi'; - -@features_1416_td -# DELETE FROM TEST; - -@features_1417_td -Write - -@features_1418_td -#ALTER TABLE TEST ...; - -@features_1419_td -# CREATE INDEX ... ON TEST ...; - -@features_1420_td -# DROP INDEX ...; - -@features_1421_p -# 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 <milliseconds>. The initial lock timeout (that is the timeout used for new connections) can be set using the SQL command SET DEFAULT_LOCK_TIMEOUT <milliseconds>. The default lock timeout is persistent. - -@features_1422_h2 -データベースファイルレイアウト - -@features_1423_p -# The following files are created for persistent databases: - -@features_1424_th -ファイル名 - -@features_1425_th -説明 - -@features_1426_th -ファイル数 - -@features_1427_td -# test.h2.db - -@features_1428_td -# Database file. - -@features_1429_td -# Contains the transaction log, indexes, and data for all tables. - -@features_1430_td -# Format: <database>.h2.db - -@features_1431_td -# 1 per database - -@features_1432_td -# test.lock.db - -@features_1433_td -# Database lock file. - -@features_1434_td -# Automatically (re-)created while the database is in use. - -@features_1435_td -# Format: <database>.lock.db - -@features_1436_td -# 1 per database (only if in use) - -@features_1437_td -# test.trace.db - -@features_1438_td -# Trace file (if the trace option is enabled). - -@features_1439_td -# Contains trace information. - -@features_1440_td -# Format: <database>.trace.db - -@features_1441_td -# Renamed to <database>.trace.db.old is too big. - -@features_1442_td -# 0 or 1 per database - -@features_1443_td -# test.lobs.db/* - -@features_1444_td -# Directory containing one file for each - -@features_1445_td -# BLOB or CLOB value larger than a certain size. - -@features_1446_td -# Format: <id>.t<tableId>.lob.db - -@features_1447_td -# 1 per large object - -@features_1448_td -# test.123.temp.db - -@features_1449_td -# Temporary file. - -@features_1450_td -# Contains a temporary blob or a large result set. - -@features_1451_td -# Format: <database>.<id>.temp.db - -@features_1452_td -# 1 per object - -@features_1453_h3 -データベースファイルの移動と改名 - -@features_1454_p -# Database name and location are not stored inside the database files. - -@features_1455_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 of the same database start with the same name and the respective extensions are unchanged). - -@features_1456_p -# As there is no platform specific data in the files, they can be moved to other operating systems without problems. - -@features_1457_h3 -バックアップ - -@features_1458_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. - -@features_1459_p -# To backup data while the database is running, the SQL command SCRIPT can be used. - -@features_1460_h2 -ログとリカバリー - -@features_1461_p -# Whenever data is modified in the database and those changes are committed, the changes are written to the transaction log (except for in-memory objects). The changes to the main data area itself are usually written later on, to optimize disk access. If there is a power failure, the main data area is not up-to-date, but because the changes are in the transaction log, the next time the database is opened, the changes are re-applied automatically. - -@features_1462_h2 -互換性 - -@features_1463_p -# All database engines behave a little bit different. Where possible, H2 supports the ANSI SQL standard, and tries to be compatible to other databases. There are still a few differences however: - -@features_1464_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). - -@features_1465_h3 -互換モード - -@features_1466_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 differences to the regular mode: - -@features_1467_h3 -#DB2 Compatibility Mode - -@features_1468_p -# To use the IBM DB2 mode, use the database URL jdbc:h2:~/test;MODE=DB2 or the SQL statement SET MODE DB2. - -@features_1469_li -#For aliased columns, ResultSetMetaData.getColumnName() returns the alias name and getTableName() returns null. - -@features_1470_li -#Support for the syntax [OFFSET .. ROW] [FETCH ... ONLY] as an alternative for LIMIT .. OFFSET. - -@features_1471_li -#Concatenating NULL with another value results in the other value. - -@features_1472_h3 -#Derby Compatibility Mode - -@features_1473_p -# To use the Apache Derby mode, use the database URL jdbc:h2:~/test;MODE=Derby or the SQL statement SET MODE Derby. - -@features_1474_li -#For aliased columns, ResultSetMetaData.getColumnName() returns the alias name and getTableName() returns null. - -@features_1475_li -#For unique indexes, NULL is distinct. That means only one row with NULL in one of the columns is allowed. - -@features_1476_li -#Concatenating NULL with another value results in the other value. - -@features_1477_h3 -#HSQLDB Compatibility Mode - -@features_1478_p -# To use the HSQLDB mode, use the database URL jdbc:h2:~/test;MODE=HSQLDB or the SQL statement SET MODE HSQLDB. - -@features_1479_li -#For aliased columns, ResultSetMetaData.getColumnName() returns the alias name and getTableName() returns null. - -@features_1480_li -#When converting the scale of decimal data, the number is only converted if the new scale is smaller than the current scale. Usually, the scale is converted and 0s are added if required. - -@features_1481_li -#For unique indexes, NULL is distinct. That means only one row with NULL in one of the columns is allowed. - -@features_1482_li -#Text can be concatenated using '+'. - -@features_1483_h3 -#MS SQL Server Compatibility Mode - -@features_1484_p -# To use the MS SQL Server mode, use the database URL jdbc:h2:~/test;MODE=MSSQLServer or the SQL statement SET MODE MSSQLServer. - -@features_1485_li -#For aliased columns, ResultSetMetaData.getColumnName() returns the alias name and getTableName() returns null. - -@features_1486_li -#Identifiers may be quoted using square brackets as in [Test]. - -@features_1487_li -#For unique indexes, NULL is distinct. That means only one row with NULL in one of the columns is allowed. - -@features_1488_li -#Concatenating NULL with another value results in the other value. - -@features_1489_li -#Text can be concatenated using '+'. - -@features_1490_h3 -#MySQL Compatibility Mode - -@features_1491_p -# To use the MySQL mode, use the database URL jdbc:h2:~/test;MODE=MySQL or the SQL statement SET MODE MySQL. - -@features_1492_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. - -@features_1493_li -#Creating indexes in the CREATE TABLE statement is allowed using INDEX(..) or KEY(..). Example: create table test(id int primary key, name varchar(255), key idx_name(name)); - -@features_1494_li -#Meta data calls return identifiers in lower case. - -@features_1495_li -#When converting a floating point number to an integer, the fractional digits are not truncated, but the value is rounded. - -@features_1496_li -#Concatenating NULL with another value results in the other value. - -@features_1497_h3 -#Oracle Compatibility Mode - -@features_1498_p -# To use the Oracle mode, use the database URL jdbc:h2:~/test;MODE=Oracle or the SQL statement SET MODE Oracle. - -@features_1499_li -#For aliased columns, ResultSetMetaData.getColumnName() returns the alias name and getTableName() returns null. - -@features_1500_li -#When using unique indexes, multiple rows with NULL in all columns are allowed, however it is not allowed to have multiple rows with the same values otherwise. - -@features_1501_li -#Concatenating NULL with another value results in the other value. - -@features_1502_h3 -#PostgreSQL Compatibility Mode - -@features_1503_p -# To use the PostgreSQL mode, use the database URL jdbc:h2:~/test;MODE=PostgreSQL or the SQL statement SET MODE PostgreSQL. - -@features_1504_li -#For aliased columns, ResultSetMetaData.getColumnName() returns the alias name and getTableName() returns null. - -@features_1505_li -#When converting a floating point number to an integer, the fractional digits are not be truncated, but the value is rounded. - -@features_1506_li -#The system columns CTID and OID are supported. - -@features_1507_h2 -#Auto-Reconnect - -@features_1508_p -# The auto-reconnect feature causes the JDBC driver to reconnect to the database if the connection is lost. The automatic re-connect only occurs when auto-commit is enabled; if auto-commit is disabled, an exception is thrown. To enable this mode, append ;AUTO_RECONNECT=TRUE to the database URL. - -@features_1509_p -# Re-connecting will open a new session. After an automatic re-connect, variables and local temporary tables definitions (excluding data) are re-created. The contents of the system table INFORMATION_SCHEMA.SESSION_STATE contains all client side state that is re-created. - -@features_1510_p -# If another connection uses the database in exclusive mode (enabled using SET EXCLUSIVE 1 or SET EXCLUSIVE 2), then this connection will try to re-connect until the exclusive mode ends. - -@features_1511_h2 -#Automatic Mixed Mode - -@features_1512_p -# Multiple processes can access the same database without having to start the server manually. To do that, append ;AUTO_SERVER=TRUE to the database URL. You can use the same database URL independent of whether the database is already open or not. This feature doesn't work with in-memory databases. - -@features_1513_p -# When using this mode, the first connection to the database is made in embedded mode, and additionally a server is started internally (as a daemon thread). If the database is already open in another process, the server mode is used automatically. - -@features_1514_p -# The application that opens the first connection to the database uses the embedded mode, which is faster than the server mode. Therefore the main application should open the database first if possible. The first connection automatically starts a server on a random port. This server allows remote connections, however only to this database (to ensure that, the client reads .lock.db file and sends the the random key that is stored there to the server). When the first connection is closed, the server stops. If other (remote) connections are still open, one of them will then start a server (auto-reconnect is enabled automatically). - -@features_1515_p -# All processes need to have access to the database files. If the first connection is closed (the connection that started the server), open transactions of other connections will be rolled back (this may not be a problem if you don't disable autocommit). Explicit client/server connections (using jdbc:h2:tcp:// or ssl://) are not supported. This mode is not supported for in-memory databases. - -@features_1516_p -# Here is an example how to use this mode. Application 1 and 2 are not necessarily started on the same computer, but they need to have access to the database files. Application 1 and 2 are typically two different processes (however they could run within the same process). - -@features_1517_h2 -#Page Size - -@features_1518_p -# The page size for new databases is 2 KB (2048), unless the system property h2.pageSize is set to a different value, or the page size is set explicitly in the database URL using PAGE_SIZE=. The page size of existing databases can not be changed. - -@features_1519_h2 -トレースオプションを使用する - -@features_1520_p -# To find problems in an application, it is sometimes good to see what database operations where executed. This database offers the following trace features: - -@features_1521_li -#Trace to System.out and/or to a file - -@features_1522_li -#Support for trace levels OFF, ERROR, INFO, DEBUG - -@features_1523_li -#The maximum size of the trace file can be set - -@features_1524_li -#It is possible to generate Java source code from the trace file - -@features_1525_li -#Trace can be enabled at runtime by manually creating a file - -@features_1526_h3 -トレースオプション - -@features_1527_p -# The simplest way to enable the trace option is setting it in the database URL. There are two settings, one for System.out (TRACE_LEVEL_SYSTEM_OUT) tracing, and one for file tracing (TRACE_LEVEL_FILE). The trace levels are 0 for OFF, 1 for ERROR (the default), 2 for INFO, and 3 for DEBUG. A database URL with both levels set to DEBUG is: - -@features_1528_p -# The trace level can be changed at runtime by executing the SQL command SET TRACE_LEVEL_SYSTEM_OUT level (for System.out tracing) or SET TRACE_LEVEL_FILE level (for file tracing). Example: - -@features_1529_h3 -トレースファイルの最大サイズを設定 - -@features_1530_p -# When using a high trace level, the trace file can get very big quickly. 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 such file exists, it is deleted. To limit the size to a certain number of megabytes, use SET TRACE_MAX_FILE_SIZE mb. Example: - -@features_1531_h3 -Javaコード生成 - -@features_1532_p -# When setting the trace level to INFO or DEBUG, Java source code is generated as well. This simplifies reproducing problems. The trace file looks like this: - -@features_1533_p -# To filter the Java source code, use the ConvertTraceFile tool as follows: - -@features_1534_p -# The generated file Test.java 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. - -@features_1535_h2 -#Using Other Logging APIs - -@features_1536_p -# By default, this database uses its own native 'trace' facility. This facility is called 'trace' and not 'log' within this database to avoid confusion with the transaction log. Trace messages can be written to both file and System.out. In most cases, this is sufficient, however sometimes it is better to use the same facility as the application, for example Log4j. To do that, this database support SLF4J. - -@features_1537_a -#SLF4J - -@features_1538_p -# is a simple facade for various logging APIs and allows to plug in the desired implementation at deployment time. SLF4J supports implementations such as Logback, Log4j, Jakarta Commons Logging (JCL), Java logging, x4juli, and Simple Log. - -@features_1539_p -# To enable SLF4J, set the file trace level to 4 in the database URL: - -@features_1540_p -# 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 the file <database>.trace.db for error messages. - -@features_1541_h2 -読み取り専用データベース - -@features_1542_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 and CALL statements are allowed. To create a read-only database, close the database. Then, make the database file read-only. When you open the database now, it 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(). - -@features_1543_p -# Using the Custom Access Mode r the database can also be opened in read-only mode, even if the database file is not read only. - -@features_1544_h2 -#Read Only Databases in Zip or Jar File - -@features_1545_p -# To create a read-only database in a zip file, first create a regular persistent database, and then create a backup. The database must not have pending changes, that means you need to close all connections to the database first. If you are using a database named test, an easy way to create a zip file is using the Backup tool. You can start the tool from the command line, or from within the H2 Console (Tools - Backup). Please note that the database must be closed when the backup is created. Therefore, the SQL statement BACKUP TO can not be used. - -@features_1546_p -# When the zip file is created, you can open the database in the zip file using the following database URL: - -@features_1547_p -# 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; therefore large databases are supported as well. The same indexes are used as when using a regular database. - -@features_1548_h2 -ディスクスペースが少ない状況での正しい取り扱い - -@features_1549_p -# If the database needs more disk space, it calls the database event listener if one is installed. The application may then delete temporary files, or display a message and wait until the user has resolved the problem. To install a listener, run the SQL statement SET DATABASE_EVENT_LISTENER or use a database 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. - -@features_1550_h3 -破損したデータベースを開く - -@features_1551_p -# If a database cannot 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. - -@features_1552_h2 -computed column / ベースインデックスの機能 - -@features_1553_p -# 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, create a computed column with the upper-case version of the original column, and create an index for this column: - -@features_1554_p -# 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: - -@features_1555_h2 -多次元インデックス - -@features_1556_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. - -@features_1557_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). - -@features_1558_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. 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. - -@features_1559_h2 -パスワードを使用する - -@features_1560_h3 -安全なパスワードを使用する - -@features_1561_p -# Remember that weak passwords can be broken regardless of the encryption and security protocols. 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: - -@features_1562_code -#i'sE2rtPiUKtT - -@features_1563_p -# from the sentence it's easy to remember this password if you know the trick. - -@features_1564_h3 -パスワード: Stringの代わりにChar Arraysを使用する - -@features_1565_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). - -@features_1566_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. - -@features_1567_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: - -@features_1568_p -# This example requires Java 1.6. When using Swing, use javax.swing.JPasswordField. - -@features_1569_h3 -ユーザー名 と (または) パスワードをURLで認証する - -@features_1570_p -# Instead of passing the user name as a separate parameter as in Connection conn = DriverManager. getConnection("jdbc:h2:~/test", "sa", "123"); the user name (and/or password) can be supplied in the URL itself: Connection conn = DriverManager. getConnection("jdbc:h2:~/test;USER=sa;PASSWORD=123"); The settings in the URL override the settings passed as a separate parameter. - -@features_1571_h2 -ユーザー定義の関数とストアドプロシージャ - -@features_1572_p -# In addition to the built-in functions, this database supports user-defined Java functions. In this database, Java functions can be used as stored procedures as well. A function must be declared (registered) before it can be used. A function can be defined using source code, or as a reference to a compiled class that is available in the classpath. By default, the function aliases are stored in the current schema. - -@features_1573_h3 -#Referencing a Compiled Method - -@features_1574_p -# When referencing a method, the class must already be compiled and included in the classpath where the database is running. Only static Java methods are supported; both the class and the method must be public. Example Java class: - -@features_1575_p -# The Java function must be registered in the database by calling CREATE ALIAS ... FOR: - -@features_1576_p -# For a complete sample application, see src/test/org/h2/samples/Function.java. - -@features_1577_h3 -#Declaring Functions as Source Code - -@features_1578_p -# When defining a function alias with source code, the database tries to compile the source code using the Sun Java compiler (the class com.sun.tools.javac.Main) if the tools.jar is in the classpath. If not, javac is run as a separate process. Only the source code is stored in the database; the class is compiled each time the database is re-opened. Source code is usually passed as dollar quoted text to avoid escaping problems, however single quotes can be used as well. Example: - -@features_1579_p -# The method name (nextPrime in the example above) is ignored. By default, the three packages java.util, java.math, java.sql are imported. If different import statements are required, they must be declared at the beginning and separated with the tag @CODE: - -@features_1580_p -# The following template is used to create a complete Java class: - -@features_1581_h3 -データタイプマッピング関数 - -@features_1582_p -# Functions that accept non-nullable parameters such as int will not be called if one of those parameters is NULL. Instead, 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. - -@features_1583_p -# SQL types are mapped to Java classes and vice-versa as in the JDBC API. For details, see Data Types. There are two special cases: java.lang.Object is mapped to OTHER (a serialized object). Therefore, java.lang.Object can not be used to match all SQL types (matching all SQL types is not supported). The second special case is Object[]: arrays of any class are mapped to ARRAY. - -@features_1584_h3 -#Functions That Require a Connection - -@features_1585_p -# 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. - -@features_1586_h3 -#Functions Throwing an Exception - -@features_1587_p -# If a function throws an exception, then the current statement is rolled back and the exception is thrown to the application. SQLException are directly re-thrown to the calling application; all other exceptions are first converted to a SQLException. - -@features_1588_h3 -#Functions Returning a Result Set - -@features_1589_p -# Functions may returns a result set. Such a function can be called with the CALL statement: - -@features_1590_h3 -SimpleResultSetを使用する - -@features_1591_p -# A function can create a result set using the SimpleResultSet tool: - -@features_1592_h3 -関数をテーブルとして使用する - -@features_1593_p -# 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 (maybe 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. - -@features_1594_h2 -トリガー - -@features_1595_p -# 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. It is also possible to use triggers to simulate materialized views. For a complete sample application, see src/test/org/h2/samples/TriggerSample.java. A Java trigger must implement the interface org.h2.api.Trigger. The trigger class must be available in the classpath of the database engine (when using the server mode, it must be in the classpath of the server). - -@features_1596_p -# The connection can be used to query or update data in other tables. The trigger then needs to be defined in the database: - -@features_1597_p -# The trigger can be used to veto a change by throwing a SQLException. - -@features_1598_h2 -データベースをコンパクトにする - -@features_1599_p -# Empty space in the database file re-used automatically. When closing the database, the database is automatically compacted for up to 1 second by default. To compact more, use the SQL statement SHUTDOWN COMPACT. However re-creating the database may further reduce the database size because this will re-build the indexes. Here is a sample function to do this: - -@features_1600_p -# See also the sample application org.h2.samples.Compact. The commands SCRIPT / RUNSCRIPT can be used as well to create a backup of a database and re-build the database from the script. - -@features_1601_h2 -キャッシュの設定 - -@features_1602_p -# The database keeps most frequently used data in the main memory. 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=131072), or it can be changed at runtime using SET CACHE_SIZE size. The size of the cache, as represented by CACHE_SIZE is measured in KB, with each KB being 1024 bytes. This setting has no effect for in-memory databases. For persistent databases, the setting is stored in the database and re-used when the database is opened the next time. However, when opening an existing database, the cache size is set to at most half the amount of memory available for the virtual machine (Runtime.getRuntime().maxMemory()), even if the cache size setting stored in the database is larger; however the setting stored in the database is kept. Setting the cache size in the database URL or explicitly using SET CACHE_SIZE overrides this value (even if larger than the physical memory). To get the current used maximum cache size, use the query SELECT * FROM INFORMATION_SCHEMA.SETTINGS WHERE NAME = 'info.CACHE_MAX_SIZE' - -@features_1603_p -# Also included is an experimental second level soft reference cache. Rows in this cache are only garbage collected on low memory. By default the second level cache is disabled. To enable it, use the prefix SOFT_. Example: jdbc:h2:~/test;CACHE_TYPE=SOFT_LRU. The cache might not actually improve performance. If you plan to use it, please run your own test cases first. - -@features_1604_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. - -@fragments_1000_b -#Search: - -@fragments_1001_td -#Highlight keyword(s) - -@fragments_1002_a -ホーム - -@fragments_1003_a -ダウンロード - -@fragments_1004_a -#Cheat Sheet - -@fragments_1005_b -ドキュメント - -@fragments_1006_a -クイックスタート - -@fragments_1007_a -インストール - -@fragments_1008_a -チュートリアル - -@fragments_1009_a -特徴 - -@fragments_1010_a -パフォーマンス - -@fragments_1011_a -#Advanced - -@fragments_1012_b -#Reference - -@fragments_1013_a -#SQL Grammar - -@fragments_1014_a -#Functions - -@fragments_1015_a -データ型 - -@fragments_1016_a -#Javadoc - -@fragments_1017_a -#PDF (1 MB) - -@fragments_1018_b -サポート - -@fragments_1019_a -#FAQ - -@fragments_1020_a -#Error Analyzer - -@fragments_1021_a -#Google Group (English) - -@fragments_1022_a -#Google Group (Japanese) - -@fragments_1023_a -#Google Group (Chinese) - -@fragments_1024_b -#Appendix - -@fragments_1025_a -#JaQu - -@fragments_1026_a -ビルド - -@fragments_1027_a -#History & Roadmap - -@fragments_1028_a -#Links - -@fragments_1029_a -ライセンス - -@fragments_1030_td -  - -@frame_1000_h1 -H2 データベース エンジン - -@frame_1001_p -# Welcome to H2, the free SQL database. The main feature of H2 are: - -@frame_1002_li -#It is free to use for everybody, source code is included - -@frame_1003_li -#Written in Java, but also available as native executable - -@frame_1004_li -#JDBC and (partial) ODBC API - -@frame_1005_li -#Embedded and client/server modes - -@frame_1006_li -#Clustering is supported - -@frame_1007_li -#A web client is included - -@frame_1008_h2 -#No Javascript - -@frame_1009_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. - -@frame_1010_p -# Please enable Javascript, or go ahead without it: H2 Database Engine - -@history_1000_h1 -歴史とロードマップ - -@history_1001_a -# Change Log - -@history_1002_a -# Roadmap - -@history_1003_a -# History of this Database Engine - -@history_1004_a -# Why Java - -@history_1005_a -# Supporters - -@history_1006_h2 -変更履歴 - -@history_1007_p -# The up-to-date change log is available at http://www.h2database.com/html/changelog.html - -@history_1008_h2 -ロードマップ - -@history_1009_p -# The current roadmap is available at http://www.h2database.com/html/roadmap.html - -@history_1010_h2 -このデータベースエンジンの歴史 - -@history_1011_p -# The development of H2 was started in May 2004, but it was first published on December 14th 2005. The main author of H2, Thomas Mueller, is also the original developer of Hypersonic SQL. In 2001, he joined PointBase Inc. where he wrote PointBase Micro, a commercial Java SQL database. At that point, he had to discontinue Hypersonic SQL. The HSQLDB Group was formed to continued to work on the Hypersonic SQL codebase. The name H2 stands for Hypersonic 2, however H2 does not share code with Hypersonic SQL or HSQLDB. H2 is built from scratch. - -@history_1012_h2 -なぜJavaなのか - -@history_1013_p -# The main reasons to use a Java database are: - -@history_1014_li -#Very simple to integrate in Java applications - -@history_1015_li -#Support for many different platforms - -@history_1016_li -#More secure than native applications (no buffer overflows) - -@history_1017_li -#User defined functions (or triggers) run very fast - -@history_1018_li -#Unicode support - -@history_1019_p -# Some think Java is too slow for low level operations, but this is no longer true. Garbage collection for example is now faster than manual memory management. - -@history_1020_p -# Developing Java code is faster than developing C or C++ code. When using Java, most time can be spent on improving the algorithms instead of porting the code to different platforms or doing memory management. Features such as Unicode and network libraries are already built-in. In Java, writing secure code is easier because buffer overflows can not occur. Features such as reflection can be used for randomized testing. - -@history_1021_p -# Java is future proof: a lot of companies support Java. Java is now open source. - -@history_1022_p -# To increase the portability and ease of use, this software depends on very few libraries. Features that are not available in open source Java implementations (such as Swing) are not used, or only used for optional features. - -@history_1023_h2 -支援者 - -@history_1024_p -# Many thanks for those who reported bugs, gave valuable feedback, spread the word, and translated this project. Also many thanks to the donors: - -@history_1025_a -#Code Lutin, France - -@history_1026_a -#Code 42 Software, Inc., Minneapolis - -@history_1027_a -#NetSuxxess GmbH, Germany - -@history_1028_a -#Poker Copilot, Steve McLeod, Germany - -@history_1029_a -#SkyCash, Poland - -@history_1030_a -#Lumber-mill, Inc., Japan - -@history_1031_li -#Martin Wildam, Austria - -@history_1032_li -#Donald Bleyl, USA - -@history_1033_li -#Frank Berger, Germany - -@history_1034_li -#Ashwin Jayaprakash, USA - -@history_1035_li -#Florent Ramiere, France - -@history_1036_li -#Jun Iyama, Japan - -@history_1037_li -#Antonio Casqueiro, Portugal - -@history_1038_li -#Oliver Computing LLC, USA - -@history_1039_li -#Harpal Grover Consulting Inc., USA - -@history_1040_li -#Elisabetta Berlini, Italy - -@history_1041_li -#William Gilbert, USA - -@history_1042_li -#Antonio Dieguez Rojas, Chile - -@history_1043_a -#Ontology Works, USA - -@history_1044_li -#Pete Haidinyak, USA - -@history_1045_li -#William Osmond, USA - -@history_1046_li -#Joachim Ansorg, Germany - -@history_1047_li -#Oliver Soerensen, Germany - -@history_1048_li -#Christos Vasilakis, Greece - -@history_1049_li -#Fyodor Kupolov, Denmark - -@history_1050_li -#Jakob Jenkov, Denmark - -@history_1051_li -#Stéphane Chartrand, Switzerland - -@history_1052_li -#Glenn Kidd, USA - -@history_1053_li -#Gustav Trede, Sweden - -@history_1054_li -#Joonas Pulakka, Finland - -@history_1055_li -#Bjorn Darri Sigurdsson, Iceland - -@history_1056_li -#Iyama Jun, Japan - -@history_1057_li -#Gray Watson, USA - -@history_1058_li -#Erik Dick, Germany - -@installation_1000_h1 -インストール - -@installation_1001_a -# Requirements - -@installation_1002_a -# Supported Platforms - -@installation_1003_a -# Installing the Software - -@installation_1004_a -# Directory Structure - -@installation_1005_h2 -必要条件 - -@installation_1006_p -# To run the database, the following minimum software stack is known to work: - -@installation_1007_li -#Windows XP or Vista, Mac OS X, or Linux - -@installation_1008_li -#Recommended Windows file system: NTFS (FAT32 only supports files up to 4 GB) - -@installation_1009_li -#Sun JDK 1.5 or newer - -@installation_1010_li -#Mozilla Firefox - -@installation_1011_h2 -サポートされているプラットフォーム - -@installation_1012_p -# As this database is written in Java, it can run on many different platforms. It is tested with Java 1.5 and 1.6 but can also be compiled to native code using GCJ. The source code does not use features of Java 1.6. Currently, the database is developed and tested on Windows XP and Mac OS X using the Sun JDK 1.5, but it also works in many other operating systems and using other Java runtime environments. - -@installation_1013_h2 -ソフトウェアのインストール - -@installation_1014_p -# To install the software, run the installer or unzip it to a directory of your choice. - -@installation_1015_h2 -ディレクトリ構成 - -@installation_1016_p -# After installing, you should get the following directory structure: - -@installation_1017_th -ディレクトリ - -@installation_1018_th -コンテンツ - -@installation_1019_td -bin - -@installation_1020_td -JARとbatchファイル - -@installation_1021_td -docs - -@installation_1022_td -ドキュメント - -@installation_1023_td -docs/html - -@installation_1024_td -HTMLページ - -@installation_1025_td -docs/javadoc - -@installation_1026_td -Javadocファイル - -@installation_1027_td -#ext - -@installation_1028_td -#External dependencies (downloaded when building) - -@installation_1029_td -service - -@installation_1030_td -Windows Serviceとしてデータベースを実行するツール - -@installation_1031_td -src - -@installation_1032_td -Sourceファイル - -@installation_1033_td -#src/docsrc - -@installation_1034_td -#Documentation sources - -@installation_1035_td -#src/installer - -@installation_1036_td -#Installer, shell, and release build script - -@installation_1037_td -#src/main - -@installation_1038_td -#Database engine source code - -@installation_1039_td -#src/test - -@installation_1040_td -#Test source code - -@installation_1041_td -#src/tools - -@installation_1042_td -#Tools and database adapters source code - -@jaqu_1000_h1 -#JaQu - -@jaqu_1001_a -# What is JaQu - -@jaqu_1002_a -# Differences to Other Data Access Tools - -@jaqu_1003_a -# Current State - -@jaqu_1004_a -# Building the JaQu Library - -@jaqu_1005_a -# Requirements - -@jaqu_1006_a -# Example Code - -@jaqu_1007_a -# Configuration - -@jaqu_1008_a -# Natural Syntax - -@jaqu_1009_a -# Other Ideas - -@jaqu_1010_a -# Similar Projects - -@jaqu_1011_h2 -#What is JaQu - -@jaqu_1012_p -# JaQu stands for Java Query and allows to access databases using pure Java. JaQu provides a fluent interface (or internal DSL) to access a database. JaQu is something like LINQ for Java (LINQ stands for "language integrated query" and is a Microsoft .NET technology). The following JaQu code: - -@jaqu_1013_p -# stands for the SQL statement: - -@jaqu_1014_h2 -#Differences to Other Data Access Tools - -@jaqu_1015_p -# Unlike SQL, JaQu can be easily integrated in Java applications. Because JaQu is pure Java, auto-complete in the IDE and Javadoc and are supported. Type checking is performed by the compiler. JaQu fully protects against SQL injection. - -@jaqu_1016_p -# JaQu is more a replacement for JDBC than it is a replacement for tools like Hibernate. With JaQu, you don't write SQL statements as Strings. JaQu is much smaller and simpler than other persistence frameworks such as Hibernate, but it also does not provide all the features of those. Unlike iBatis and Hibernate, no XML or annotation based configuration is required; instead the configuration (if required at all) is done in pure Java, in the application itself. - -@jaqu_1017_p -# JaQu does not require or contain any data caching mechanism. Like JDBC and iBatis, JaQu provides full control over when and what SQL statements are executed (but without having to write SQL statements as Strings). - -@jaqu_1018_h3 -#Restrictions - -@jaqu_1019_p -# Primitive types (eg. boolean, int, long, double) are not supported. Use java.lang.Boolean, Integer, Long, Double instead. - -@jaqu_1020_h3 -#Why in Java? - -@jaqu_1021_p -# Most people use Java in their application. Mixing Java and another language (for example Scala or Groovy) in the same application is complicated: you would need to split the application and database code. - -@jaqu_1022_h2 -#Current State - -@jaqu_1023_p -# Currently, JaQu is only tested with the H2 database. The API may change in future versions. JaQu is not part of the h2 jar file, however the source code is included in H2, under: - -@jaqu_1024_code -#src/test/org/h2/test/jaqu/* - -@jaqu_1025_li -# (samples and tests) - -@jaqu_1026_code -#src/tools/org/h2/jaqu/* - -@jaqu_1027_li -# (framework) - -@jaqu_1028_h2 -#Building the JaQu Library - -@jaqu_1029_p -# To create the JaQu jar file, run: build jarJaqu. This will create the file bin/h2jaqu.jar. - -@jaqu_1030_h2 -必要条件 - -@jaqu_1031_p -# JaQu requires Java 1.5. Annotations are not need. Currently, JaQu is only tested with the H2 database engine, however in theory it should work with any database that supports the JDBC API. - -@jaqu_1032_h2 -#Example Code - -@jaqu_1033_h2 -#Configuration - -@jaqu_1034_p -# JaQu does not require any configuration when using the default mapping. To define table indices, or if you want to map a class to a table with a different name, or a field to a column with another name, create a function called define in the data class. Example: - -@jaqu_1035_p -# The method define() contains the mapping definition. It is called once when the class is used for the first time. Like annotations, the mapping is defined in the class itself. Unlike when using annotations, the compiler can check the syntax even for multi-column objects (multi-column indexes, multi-column primary keys and so on). Because the definition is written in regular Java, the configuration can depend on the environment. This is not possible using annotations. Unlike XML mapping configuration, the configuration is integrated in the class itself. - -@jaqu_1036_h2 -#Natural Syntax - -@jaqu_1037_p -#The plan is to support more natural (pure Java) syntax in conditions. To do that, the condition class is de-compiled to a SQL condition. A proof of concept decompiler is included (but it doesn't work yet). The planned syntax is: - -@jaqu_1038_h2 -#Other Ideas - -@jaqu_1039_p -# This project has just been started, and nothing is fixed yet. Some ideas for what to implement are: - -@jaqu_1040_li -#Support queries on collections (instead of using a database). - -@jaqu_1041_li -#Provide API level compatibility with JPA (so that JaQu can be used as an extension of JPA). - -@jaqu_1042_li -#Internally use a JPA implementation (for example Hibernate) instead of SQL directly. - -@jaqu_1043_li -#Use PreparedStatements and cache them. - -@jaqu_1044_h2 -#Similar Projects - -@jaqu_1045_a -#Cement Framework - -@jaqu_1046_a -#Dreamsource ORM - -@jaqu_1047_a -#Empire-db - -@jaqu_1048_a -#JEQUEL: Java Embedded QUEry Language - -@jaqu_1049_a -#Joist - -@jaqu_1050_a -#JoSQL - -@jaqu_1051_a -#LIQUidFORM - -@jaqu_1052_a -#Quaere (Alias implementation) - -@jaqu_1053_a -#Quaere - -@jaqu_1054_a -#Querydsl - -@jaqu_1055_a -#Squill - -@license_1000_h1 -ライセンス - -@license_1001_h2 -#Summary and License FAQ - -@license_1002_p -# H2 is dual licensed and available under a modified version of the MPL 1.1 (Mozilla Public License) or under the (unmodified) EPL 1.0 (Eclipse Public License). The changes to the MPL are - -@license_1003_em -#underlined. There is a License FAQ for both the MPL and the EPL, most of that is applicable to the H2 License as well. - -@license_1004_li -#You can use H2 for free. You can integrate it into your application (including commercial applications), and you can distribute it. - -@license_1005_li -#Files containing only your code are not covered by this license (it is 'commercial friendly'). - -@license_1006_li -#Modifications to the H2 source code must be published. - -@license_1007_li -#You don't need to provide the source code of H2 if you did not modify anything. - -@license_1008_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: 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. It seems 'bungisoft' does not exist any more, but you can use the Wayback Machine and visit old web pages of http://www.bungisoft.com. - -@license_1009_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. - -@license_1010_h2 -#H2 License, Version 1.0 - -@license_1011_h3 -#1. Definitions - -@license_1012_b -#1.0.1. "Commercial Use" - -@license_1013_p -# means distribution or otherwise making the Covered Code available to a third party. - -@license_1014_b -#1.1. "Contributor" - -@license_1015_p -# means each entity that creates or contributes to the creation of Modifications. - -@license_1016_b -#1.2. "Contributor Version" - -@license_1017_p -# means the combination of the Original Code, prior Modifications used by a Contributor, and the Modifications made by that particular Contributor. - -@license_1018_b -#1.3. "Covered Code" - -@license_1019_p -# means the Original Code or Modifications or the combination of the Original Code and Modifications, in each case including portions thereof. - -@license_1020_b -#1.4. "Electronic Distribution Mechanism" - -@license_1021_p -# means a mechanism generally accepted in the software development community for the electronic transfer of data. - -@license_1022_b -#1.5. "Executable" - -@license_1023_p -# means Covered Code in any form other than Source Code. - -@license_1024_b -#1.6. "Initial Developer" - -@license_1025_p -# means the individual or entity identified as the Initial Developer in the Source Code notice required by Exhibit A. - -@license_1026_b -#1.7. "Larger Work" - -@license_1027_p -# means a work which combines Covered Code or portions thereof with code not governed by the terms of this License. - -@license_1028_b -#1.8. "License" - -@license_1029_p -# means this document. - -@license_1030_b -#1.8.1. "Licensable" - -@license_1031_p -# means having the right to grant, to the maximum extent possible, whether at the time of the initial grant or subsequently acquired, any and all of the rights conveyed herein. - -@license_1032_b -#1.9. "Modifications" - -@license_1033_p -# means any addition to or deletion from the substance or structure of either the Original Code or any previous Modifications. When Covered Code is released as a series of files, a Modification is: - -@license_1034_p -#1.9.a. Any addition to or deletion from the contents of a file containing Original Code or previous Modifications. - -@license_1035_p -#1.9.b. Any new file that contains any part of the Original Code or previous Modifications. - -@license_1036_b -#1.10. "Original Code" - -@license_1037_p -# means Source Code of computer software code which is described in the Source Code notice required by Exhibit A as Original Code, and which, at the time of its release under this License is not already Covered Code governed by this License. - -@license_1038_b -#1.10.1. "Patent Claims" - -@license_1039_p -# means any patent claim(s), now owned or hereafter acquired, including without limitation, method, process, and apparatus claims, in any patent Licensable by grantor. - -@license_1040_b -#1.11. "Source Code" - -@license_1041_p -# means the preferred form of the Covered Code for making modifications to it, including all modules it contains, plus any associated interface definition files, scripts used to control compilation and installation of an Executable, or source code differential comparisons against either the Original Code or another well known, available Covered Code of the Contributor's choice. The Source Code can be in a compressed or archival form, provided the appropriate decompression or de-archiving software is widely available for no charge. - -@license_1042_b -#1.12. "You" (or "Your") - -@license_1043_p -# means an individual or a legal entity exercising rights under, and complying with all of the terms of, this License or a future version of this License issued under Section 6.1. For legal entities, "You" includes any entity which controls, is controlled by, or is under common control with You. For purposes of this definition, "control" means (a) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (b) ownership of more than fifty percent (50%) of the outstanding shares or beneficial ownership of such entity. - -@license_1044_h3 -#2. Source Code License - -@license_1045_h4 -#2.1. The Initial Developer Grant - -@license_1046_p -# The Initial Developer hereby grants You a world-wide, royalty-free, non-exclusive license, subject to third party intellectual property claims: - -@license_1047_p -#2.1.a. under intellectual property rights (other than patent or trademark) Licensable by Initial Developer to use, reproduce, modify, display, perform, sublicense and distribute the Original Code (or portions thereof) with or without Modifications, and/or as part of a Larger Work; and - -@license_1048_p -#2.1.b. under Patents Claims infringed by the making, using or selling of Original Code, to make, have made, use, practice, sell, and offer for sale, and/or otherwise dispose of the Original Code (or portions thereof). - -@license_1049_p -#2.1.c. the licenses granted in this Section 2.1 (a) and (b) are effective on the date Initial Developer first distributes Original Code under the terms of this License. - -@license_1050_p -#2.1.d. Notwithstanding Section 2.1 (b) above, no patent license is granted: 1) for code that You delete from the Original Code; 2) separate from the Original Code; or 3) for infringements caused by: i) the modification of the Original Code or ii) the combination of the Original Code with other software or devices. - -@license_1051_h4 -#2.2. Contributor Grant - -@license_1052_p -# Subject to third party intellectual property claims, each Contributor hereby grants You a world-wide, royalty-free, non-exclusive license - -@license_1053_p -#2.2.a. under intellectual property rights (other than patent or trademark) Licensable by Contributor, to use, reproduce, modify, display, perform, sublicense and distribute the Modifications created by such Contributor (or portions thereof) either on an unmodified basis, with other Modifications, as Covered Code and/or as part of a Larger Work; and - -@license_1054_p -#2.2.b. under Patent Claims infringed by the making, using, or selling of Modifications made by that Contributor either alone and/or in combination with its Contributor Version (or portions of such combination), to make, use, sell, offer for sale, have made, and/or otherwise dispose of: 1) Modifications made by that Contributor (or portions thereof); and 2) the combination of Modifications made by that Contributor with its Contributor Version (or portions of such combination). - -@license_1055_p -#2.2.c. the licenses granted in Sections 2.2 (a) and 2.2 (b) are effective on the date Contributor first makes Commercial Use of the Covered Code. - -@license_1056_p -#2.2.c. Notwithstanding Section 2.2 (b) above, no patent license is granted: 1) for any code that Contributor has deleted from the Contributor Version; 2) separate from the Contributor Version; 3) for infringements caused by: i) third party modifications of Contributor Version or ii) the combination of Modifications made by that Contributor with other software (except as part of the Contributor Version) or other devices; or 4) under Patent Claims infringed by Covered Code in the absence of Modifications made by that Contributor. - -@license_1057_h3 -#3. Distribution Obligations - -@license_1058_h4 -#3.1. Application of License - -@license_1059_p -# The Modifications which You create or to which You contribute are governed by the terms of this License, including without limitation Section 2.2. 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 6.1, and You must include a copy of this License with every copy of the Source Code You distribute. You may not offer or impose any terms on any Source Code version that alters or restricts the applicable version of this License or the recipients' rights hereunder. However, You may include an additional document offering the additional rights described in Section 3.5. - -@license_1060_h4 -#3.2. Availability of Source Code - -@license_1061_p -# 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, must remain available for at least twelve (12) months after the date it initially became available, or at least six (6) months after a subsequent version of that particular Modification has been made available to such recipients. You are responsible for ensuring that the Source Code version remains available even if the Electronic Distribution Mechanism is maintained by a third party. - -@license_1062_h4 -#3.3. Description of Modifications - -@license_1063_p -# 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 (a) the Source Code, and (b) in any notice in an Executable version or related documentation in which You describe the origin or ownership of the Covered Code. - -@license_1064_h4 -#3.4. Intellectual Property Matters - -@license_1065_b -#3.4.a. Third Party Claims: - -@license_1066_p -# If Contributor has knowledge that a license under a third party's intellectual property rights is required to exercise the rights granted by such Contributor under Sections 2.1 or 2.2, Contributor must include a text file with the Source Code distribution titled "LEGAL" which describes the claim and the party making the claim in sufficient detail that a recipient will know whom to contact. If Contributor obtains such knowledge after the Modification is made available as described in Section 3.2, Contributor shall promptly modify the LEGAL file in all copies Contributor makes available thereafter and shall take other steps (such as notifying appropriate mailing lists or newsgroups) reasonably calculated to inform those who received the Covered Code that new knowledge has been obtained. - -@license_1067_b -#3.4.b. Contributor APIs: - -@license_1068_p -# If Contributor's Modifications include an application programming interface and Contributor has knowledge of patent licenses which are reasonably necessary to implement that API, Contributor must also include this information in the legal file. - -@license_1069_b -#3.4.c. Representations: - -@license_1070_p -# Contributor represents that, except as disclosed pursuant to Section 3.4 (a) above, Contributor believes that Contributor's Modifications are Contributor's original creation(s) and/or Contributor has sufficient rights to grant the rights conveyed by this License. - -@license_1071_h4 -#3.5. Required Notices - -@license_1072_p -# You must duplicate the notice in Exhibit 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 Modification(s) You may add your name as a Contributor to the notice described in Exhibit A. You must also duplicate this License in any documentation for the Source Code where You describe recipients' rights or ownership rights relating to Covered Code. You may choose to offer, and to charge a fee for, warranty, support, indemnity or liability obligations to one or more recipients of Covered Code. However, You may do so only on Your own behalf, and not on behalf of the Initial Developer or any Contributor. You must make it absolutely clear than any such warranty, support, indemnity or liability obligation is offered by You alone, and You hereby agree to indemnify the Initial Developer 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. - -@license_1073_h4 -#3.6. Distribution of Executable Versions - -@license_1074_p -# You may distribute Covered Code in Executable form only if the requirements of Sections 3.1, 3.2, 3.3, 3.4 and 3.5 have been met for that Covered Code, and if You include a notice stating that the Source Code version of the Covered Code is available under the terms of this License, including a description of how and where You have fulfilled the obligations of Section 3.2. The notice must be conspicuously included in any notice in an Executable version, related documentation or collateral in which You describe recipients' rights relating to the Covered Code. You may distribute the Executable version of Covered Code or ownership rights under a license of Your choice, which may contain terms different from this License, provided that You are in compliance with the terms of this License and that the license for the Executable version does not attempt to limit or alter the recipient's rights in the Source Code version from the rights set forth in this License. If You distribute the Executable version under a different license You must make it absolutely clear that any terms which differ from this License are offered by You alone, not by the Initial Developer or any Contributor. You hereby agree to indemnify the Initial Developer and every Contributor for any liability incurred by the Initial Developer or such Contributor as a result of any such terms You offer. - -@license_1075_h4 -#3.7. Larger Works - -@license_1076_p -# 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. - -@license_1077_h3 -#4. Inability to Comply Due to Statute or Regulation. - -@license_1078_p -# 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 legal file described in Section 3.4 and must be included with all distributions of the Source Code. 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. - -@license_1079_h3 -#5. Application of this License. - -@license_1080_p -# This License applies to code to which the Initial Developer has attached the notice in Exhibit A and to related Covered Code. - -@license_1081_h3 -#6. Versions of the License. - -@license_1082_h4 -#6.1. New Versions - -@license_1083_p -# The - -@license_1084_em -#H2 Group may publish revised and/or new versions of the License from time to time. Each version will be given a distinguishing version number. - -@license_1085_h4 -#6.2. Effect of New Versions - -@license_1086_p -# 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 - -@license_1087_em -#H2 Group. No one other than the - -@license_1088_em -#H2 Group has the right to modify the terms applicable to Covered Code created under this License. - -@license_1089_h4 -#6.3. Derivative Works - -@license_1090_p -# 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 - -@license_1091_em -#"H2 Group", "H2" or any confusingly similar phrase do not appear in your license (except to note that your license differs from this License) and (b) otherwise make it clear that Your version of the license contains terms which differ from the - -@license_1092_em -#H2 License. (Filling in the name of the Initial Developer, Original Code or Contributor in the notice described in Exhibit A shall not of themselves be deemed to be modifications of this License.) - -@license_1093_h3 -#7. Disclaimer of Warranty - -@license_1094_p -# 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 the covered code is with you. Should any covered code prove defective in any respect, you (not the initial developer or any other contributor) assume the cost of any necessary servicing, repair or correction. This disclaimer of warranty constitutes an essential part of this license. No use of any covered code is authorized hereunder except under this disclaimer. - -@license_1095_h3 -#8. Termination - -@license_1096_p -#8.1. This License and the rights granted hereunder will terminate automatically if You fail to comply with terms herein and fail to cure such breach 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. - -@license_1097_p -#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: - -@license_1098_p -#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 Sections 2.1 and/or 2.2 of this License shall, upon 60 days notice from Participant terminate prospectively, unless if within 60 days after receipt of notice You either: (i) agree in writing to pay Participant a mutually agreeable reasonable royalty for Your past and future use of Modifications made by such Participant, or (ii) withdraw Your litigation claim with respect to the Contributor Version against such Participant. If within 60 days of notice, a reasonable royalty and payment arrangement are not mutually agreed upon in writing by the parties or the litigation claim is not withdrawn, the rights granted by Participant to You under Sections 2.1 and/or 2.2 automatically terminate at the expiration of the 60 day notice period specified above. - -@license_1099_p -#8.2.b. any software, hardware, or device, other than such Participant's Contributor Version, directly or indirectly infringes any patent, then any rights granted to You by such Participant under Sections 2.1(b) and 2.2(b) are revoked effective as of the date You first made, used, sold, distributed, or had made, Modifications made by that Participant. - -@license_1100_p -#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 initiation of patent infringement litigation, then the reasonable value of the licenses granted by such Participant under Sections 2.1 or 2.2 shall be taken into account in determining the amount or value of any payment or license. - -@license_1101_p -#8.4. In the event of termination under Sections 8.1 or 8.2 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. - -@license_1102_h3 -#9. Limitation of Liability - -@license_1103_p -# 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 consequential damages of any character including, without limitation, damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses, even if such party shall have been informed of the possibility of such damages. This limitation of liability shall not apply to liability for death or personal injury resulting from such party's negligence to the extent applicable law prohibits such limitation. Some jurisdictions do not allow the exclusion or limitation of incidental or consequential damages, so this exclusion and limitation may not apply to you. - -@license_1104_h3 -#10. United States Government End Users - -@license_1105_p -# 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. - -@license_1106_h3 -#11. Miscellaneous - -@license_1107_p -# 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 California law provisions (except to the extent applicable law, if any, provides otherwise), excluding its conflict-of-law provisions. With respect to disputes in which at least one party is a citizen of, or an entity chartered or registered to do business in United States of America, any litigation relating to this License shall be subject to the jurisdiction of the Federal Courts of the Northern District of California, with venue lying in Santa Clara County, California, with the losing party responsible for costs, including without limitation, court costs and reasonable attorneys' fees and expenses. The application of the United Nations Convention on Contracts for the International Sale of Goods is expressly excluded. Any law or regulation which provides that the language of a contract shall be construed against the drafter shall not apply to this License. - -@license_1108_h3 -#12. Responsibility for Claims - -@license_1109_p -# 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. - -@license_1110_h3 -#13. Multiple-Licensed Code - -@license_1111_p -# 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 described in Exhibit A. - -@license_1112_h3 -#Exhibit A - -@license_1113_h2 -#Eclipse Public License - Version 1.0 - -@license_1114_p -# THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS ECLIPSE PUBLIC LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT. - -@license_1115_h3 -#1. DEFINITIONS - -@license_1116_p -# "Contribution" means: - -@license_1117_p -# a) in the case of the initial Contributor, the initial code and documentation distributed under this Agreement, and - -@license_1118_p -# b) in the case of each subsequent Contributor: - -@license_1119_p -# i) changes to the Program, and - -@license_1120_p -# ii) additions to the Program; - -@license_1121_p -# where such changes and/or additions to the Program originate from and are distributed by that particular Contributor. A Contribution 'originates' from a Contributor if it was added to the Program by such Contributor itself or anyone acting on such Contributor's behalf. Contributions do not include additions to the Program which: (i) are separate modules of software distributed in conjunction with the Program under their own license agreement, and (ii) are not derivative works of the Program. - -@license_1122_p -# "Contributor" means any person or entity that distributes the Program. - -@license_1123_p -# "Licensed Patents " mean patent claims licensable by a Contributor which are necessarily infringed by the use or sale of its Contribution alone or when combined with the Program. - -@license_1124_p -# "Program" means the Contributions distributed in accordance with this Agreement. - -@license_1125_p -# "Recipient" means anyone who receives the Program under this Agreement, including all Contributors. - -@license_1126_h3 -#2. GRANT OF RIGHTS - -@license_1127_p -# a) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free copyright license to reproduce, prepare derivative works of, publicly display, publicly perform, distribute and sublicense the Contribution of such Contributor, if any, and such derivative works, in source code and object code form. - -@license_1128_p -# b) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free patent license under Licensed Patents to make, use, sell, offer to sell, import and otherwise transfer the Contribution of such Contributor, if any, in source code and object code form. This patent license shall apply to the combination of the Contribution and the Program if, at the time the Contribution is added by the Contributor, such addition of the Contribution causes such combination to be covered by the Licensed Patents. The patent license shall not apply to any other combinations which include the Contribution. No hardware per se is licensed hereunder. - -@license_1129_p -# c) Recipient understands that although each Contributor grants the licenses to its Contributions set forth herein, no assurances are provided by any Contributor that the Program does not infringe the patent or other intellectual property rights of any other entity. Each Contributor disclaims any liability to Recipient for claims brought by any other entity based on infringement of intellectual property rights or otherwise. As a condition to exercising the rights and licenses granted hereunder, each Recipient hereby assumes sole responsibility to secure any other intellectual property rights needed, if any. For example, if a third party patent license is required to allow Recipient to distribute the Program, it is Recipient's responsibility to acquire that license before distributing the Program. - -@license_1130_p -# d) Each Contributor represents that to its knowledge it has sufficient copyright rights in its Contribution, if any, to grant the copyright license set forth in this Agreement. - -@license_1131_h3 -#3. REQUIREMENTS - -@license_1132_p -# A Contributor may choose to distribute the Program in object code form under its own license agreement, provided that: - -@license_1133_p -# a) it complies with the terms and conditions of this Agreement; and - -@license_1134_p -# b) its license agreement: - -@license_1135_p -# i) effectively disclaims on behalf of all Contributors all warranties and conditions, express and implied, including warranties or conditions of title and non-infringement, and implied warranties or conditions of merchantability and fitness for a particular purpose; - -@license_1136_p -# ii) effectively excludes on behalf of all Contributors all liability for damages, including direct, indirect, special, incidental and consequential damages, such as lost profits; - -@license_1137_p -# iii) states that any provisions which differ from this Agreement are offered by that Contributor alone and not by any other party; and - -@license_1138_p -# iv) states that source code for the Program is available from such Contributor, and informs licensees how to obtain it in a reasonable manner on or through a medium customarily used for software exchange. - -@license_1139_p -# When the Program is made available in source code form: - -@license_1140_p -# a) it must be made available under this Agreement; and - -@license_1141_p -# b) a copy of this Agreement must be included with each copy of the Program. - -@license_1142_p -# Contributors may not remove or alter any copyright notices contained within the Program. - -@license_1143_p -# Each Contributor must identify itself as the originator of its Contribution, if any, in a manner that reasonably allows subsequent Recipients to identify the originator of the Contribution. - -@license_1144_h3 -#4. COMMERCIAL DISTRIBUTION - -@license_1145_p -# Commercial distributors of software may accept certain responsibilities with respect to end users, business partners and the like. While this license is intended to facilitate the commercial use of the Program, the Contributor who includes the Program in a commercial product offering should do so in a manner which does not create potential liability for other Contributors. Therefore, if a Contributor includes the Program in a commercial product offering, such Contributor ("Commercial Contributor") hereby agrees to defend and indemnify every other Contributor ("Indemnified Contributor") against any losses, damages and costs (collectively "Losses") arising from claims, lawsuits and other legal actions brought by a third party against the Indemnified Contributor to the extent caused by the acts or omissions of such Commercial Contributor in connection with its distribution of the Program in a commercial product offering. The obligations in this section do not apply to any claims or Losses relating to any actual or alleged intellectual property infringement. In order to qualify, an Indemnified Contributor must: a) promptly notify the Commercial Contributor in writing of such claim, and b) allow the Commercial Contributor to control, and cooperate with the Commercial Contributor in, the defense and any related settlement negotiations. The Indemnified Contributor may participate in any such claim at its own expense. - -@license_1146_p -# For example, a Contributor might include the Program in a commercial product offering, Product X. That Contributor is then a Commercial Contributor. If that Commercial Contributor then makes performance claims, or offers warranties related to Product X, those performance claims and warranties are such Commercial Contributor's responsibility alone. Under this section, the Commercial Contributor would have to defend claims against the other Contributors related to those performance claims and warranties, and if a court requires any other Contributor to pay any damages as a result, the Commercial Contributor must pay those damages. - -@license_1147_h3 -#5. NO WARRANTY - -@license_1148_p -# EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is solely responsible for determining the appropriateness of using and distributing the Program and assumes all risks associated with its exercise of rights under this Agreement, including but not limited to the risks and costs of program errors, compliance with applicable laws, damage to or loss of data, programs or equipment, and unavailability or interruption of operations. - -@license_1149_h3 -#6. DISCLAIMER OF LIABILITY - -@license_1150_p -# EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. - -@license_1151_h3 -#7. GENERAL - -@license_1152_p -# If any provision of this Agreement is invalid or unenforceable under applicable law, it shall not affect the validity or enforceability of the remainder of the terms of this Agreement, and without further action by the parties hereto, such provision shall be reformed to the minimum extent necessary to make such provision valid and enforceable. - -@license_1153_p -# If Recipient institutes patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Program itself (excluding combinations of the Program with other software or hardware) infringes such Recipient's patent(s), then such Recipient's rights granted under Section 2(b) shall terminate as of the date such litigation is filed. - -@license_1154_p -# All Recipient's rights under this Agreement shall terminate if it fails to comply with any of the material terms or conditions of this Agreement and does not cure such failure in a reasonable period of time after becoming aware of such noncompliance. If all Recipient's rights under this Agreement terminate, Recipient agrees to cease use and distribution of the Program as soon as reasonably practicable. However, Recipient's obligations under this Agreement and any licenses granted by Recipient relating to the Program shall continue and survive. - -@license_1155_p -# Everyone is permitted to copy and distribute copies of this Agreement, but in order to avoid inconsistency the Agreement is copyrighted and may only be modified in the following manner. The Agreement Steward reserves the right to publish new versions (including revisions) of this Agreement from time to time. No one other than the Agreement Steward has the right to modify this Agreement. The Eclipse Foundation is the initial Agreement Steward. The Eclipse Foundation may assign the responsibility to serve as the Agreement Steward to a suitable separate entity. Each new version of the Agreement will be given a distinguishing version number. The Program (including Contributions) may always be distributed subject to the version of the Agreement under which it was received. In addition, after a new version of the Agreement is published, Contributor may elect to distribute the Program (including its Contributions) under the new version. Except as expressly stated in Sections 2(a) and 2(b) above, Recipient receives no rights or licenses to the intellectual property of any Contributor under this Agreement, whether expressly, by implication, estoppel or otherwise. All rights in the Program not expressly granted under this Agreement are reserved. - -@license_1156_p -# This Agreement is governed by the laws of the State of New York and the intellectual property laws of the United States of America. No party to this Agreement will bring a legal action under this Agreement more than one year after the cause of action arose. Each party waives its rights to a jury trial in any resulting litigation. - -@links_1000_h1 -#H2 In Use and Links - -@links_1001_p -# Those are just a few links to products using or supporting H2. If you want to add a link, please send it to the support email address or post it in the group. - -@links_1002_h2 -#Books - -@links_1003_a -# Seam In Action - -@links_1004_h2 -#Extensions - -@links_1005_a -# Grails H2 Database Plugin - -@links_1006_a -# h2osgi: OSGi for the H2 Database - -@links_1007_a -# H2Sharp: ADO.NET interface for the H2 database engine - -@links_1008_a -# H2 Spatial: spatial functions to H2 database - -@links_1009_h2 -#Blog Articles - -@links_1010_a -# Analyzing CSVs with H2 in under 10 minutes (2009-12-07) - -@links_1011_a -# Efficient sorting and iteration on large databases (2009-06-15) - -@links_1012_a -# Porting Flexive to the H2 Database (2008-12-05) - -@links_1013_a -# H2 Database with GlassFish (2008-11-24) - -@links_1014_a -# Using H2 Database with Glassfish and Toplink (2008-08-07) - -@links_1015_a -# H2 Database - Performance Tracing (2008-04-30) - -@links_1016_a -# Testing your JDBC data access layer with DBUnit and H2 (2007-09-18) - -@links_1017_a -# Open Source Databases Comparison (2007-09-11) - -@links_1018_a -# The Codist: The Open Source Frameworks I Use (2007-07-23) - -@links_1019_a -# The Codist: SQL Injections: How Not To Get Stuck (2007-05-08) - -@links_1020_a -# One Man Band: (Helma + H2) == "to easy" (2007-03-11) - -@links_1021_a -# David Coldrick's Weblog: New Version of H2 Database Released (2007-01-06) - -@links_1022_a -# The Codist: Write Your Own Database, Again (2006-11-13) - -@links_1023_h2 -#Project Pages - -@links_1024_a -# Ohloh - -@links_1025_a -# Freshmeat Project Page - -@links_1026_a -# Free Open Source Software For Us - -@links_1027_a -# Wikipedia - -@links_1028_a -# Java Source Net - -@links_1029_a -# Linux Package Manager - -@links_1030_h2 -#Database Frontends / Tools - -@links_1031_a -# DB Solo - -@links_1032_p -# SQL query tool. - -@links_1033_a -# DbVisualizer - -@links_1034_p -# Database tool. - -@links_1035_a -# Execute Query - -@links_1036_p -# Database utility written in Java. - -@links_1037_a -# [fleXive] - -@links_1038_p -# JavaEE 5 open source framework for the development of complex and evolving (web-)applications. - -@links_1039_a -# HenPlus - -@links_1040_p -# HenPlus is a SQL shell written in Java. - -@links_1041_a -# RazorSQL - -@links_1042_p -# An SQL query tool, database browser, SQL editor, and database administration tool. - -@links_1043_a -# SQL Developer - -@links_1044_p -# Universal Database Frontend. - -@links_1045_a -# SQL Workbench/J - -@links_1046_p -# Free DBMS-independent SQL tool. - -@links_1047_a -# SQuirreL SQL Client - -@links_1048_p -# Graphical tool to view the structure of a database, browse the data, issue SQL commands etc. - -@links_1049_a -# SQuirreL DB Copy Plugin - -@links_1050_p -# Tool to copy data from one database to another. - -@links_1051_h2 -#Products and Projects - -@links_1052_a -# AccuProcess - -@links_1053_p -# Visual business process modeling and simulation software for business users. - -@links_1054_a -# Adeptia BPM - -@links_1055_p -# A Business Process Management (BPM) suite to quickly and easily automate business processes and workflows. - -@links_1056_a -# Adeptia Integration - -@links_1057_p -# Process-centric, services-based application integration suite. - -@links_1058_a -# Aejaks - -@links_1059_p -# A server-side scripting environment to build AJAX enabled web applications. - -@links_1060_a -# Axiom Stack - -@links_1061_p -# A web framework that let's you write dynamic web applications with Zen-like simplicity. - -@links_1062_a -# Apache Cayenne - -@links_1063_p -# Open source persistence framework providing object-relational mapping (ORM) and remoting services. - -@links_1064_a -# Apache Jackrabbit - -@links_1065_p -# Open source implementation of the Java Content Repository API (JCR). - -@links_1066_a -# Apache OpenJPA - -@links_1067_p -# Open source implementation of the Java Persistence API (JPA). - -@links_1068_a -# AppFuse - -@links_1069_p -# Helps building web applications. - -@links_1070_a -# BGBlitz - -@links_1071_p -# The Swiss army knife of Backgammon. - -@links_1072_a -# Blojsom - -@links_1073_p -# Java-based multi-blog, multi-user software package (Mac OS X Weblog Server). - -@links_1074_a -# Bonita - -@links_1075_p -# Open source workflow solution for handing long-running, user-oriented processes providing out of the box workflow and business process management features. - -@links_1076_a -# Bookmarks Portlet - -@links_1077_p -# JSR 168 compliant bookmarks management portlet application. - -@links_1078_a -# Claros inTouch - -@links_1079_p -# Ajax communication suite with mail, addresses, notes, IM, and rss reader. - -@links_1080_a -# CrashPlan PRO Server - -@links_1081_p -# Easy and cross platform backup solution for business and service providers. - -@links_1082_a -# DbUnit - -@links_1083_p -# A JUnit extension (also usable with Ant) targeted for database-driven projects. - -@links_1084_a -# Dinamica Framework - -@links_1085_p -# Ajax/J2EE framework for RAD development (mainly oriented toward hispanic markets). - -@links_1086_a -# Ebean ORM Persistence Layer - -@links_1087_p -# Open source Java Object Relational Mapping tool. - -@links_1088_a -# Eclipse CDO - -@links_1089_p -# The CDO (Connected Data Objects) Model Repository is a distributed shared model framework for EMF models, and a fast server-based O/R mapping solution. - -@links_1090_a -# Epictetus - -@links_1091_p -# Free cross platform database tool. - -@links_1092_a -# Fabric3 - -@links_1093_p -# Fabric3 is a project implementing a federated service network based on the Service Component Architecture specification (http://www.osoa.org). - -@links_1094_a -# FIT4Data - -@links_1095_p -# A testing framework for data management applications built on the Java implementation of FIT. - -@links_1096_a -# Flux - -@links_1097_p -# Java job scheduler, file transfer, workflow, and BPM. - -@links_1098_a -# GBIF Integrated Publishing Toolkit (IPT) - -@links_1099_p -# The GBIF IPT is an open source, Java based web application that connects and serves three types of biodiversity data: taxon primary occurrence data, taxon checklists and general resource metadata. - -@links_1100_a -# GNU Gluco Control - -@links_1101_p -# Helps you to manage your diabetes. - -@links_1102_a -# Golden T Studios - -@links_1103_p -# Fun-to-play games with a simple interface. - -@links_1104_a -# Group Session - -@links_1105_p -# Open source web groupware. - -@links_1106_a -# HA-JDBC - -@links_1107_p -# High-Availability JDBC: A JDBC proxy that provides light-weight, transparent, fault tolerant clustering capability to any underlying JDBC driver. - -@links_1108_a -# Harbor - -@links_1109_p -# Pojo Application Server. - -@links_1110_a -# Hibernate - -@links_1111_p -# Relational persistence for idiomatic Java (O-R mapping tool). - -@links_1112_a -# Hibicius - -@links_1113_p -# Online Banking Client for the HBCI protocol. - -@links_1114_a -# ImageMapper - -@links_1115_p -# ImageMapper frees users from having to use file browsers to view their images. They get fast access to images and easy cataloguing of them via a user friendly interface. - -@links_1116_a -# JAMWiki - -@links_1117_p -# Java-based Wiki engine. - -@links_1118_a -# Jala - -@links_1119_p -# Open source collection of JavaScript modules. - -@links_1120_a -# Java Simon - -@links_1121_p -# Simple Monitoring API. - -@links_1122_a -# JBoss jBPM - -@links_1123_p -# A platform for executable process languages ranging from business process management (BPM) over workflow to service orchestration. - -@links_1124_a -# JBoss Jopr - -@links_1125_p -# An enterprise management solution for JBoss middleware projects and other application technologies. - -@links_1126_a -# JGeocoder - -@links_1127_p -# Free Java geocoder. Geocoding is the process of estimating a latitude and longitude for a given location. - -@links_1128_a -# JGrass - -@links_1129_p -# Java Geographic Resources Analysis Support System. Free, multi platform, open source GIS based on the GIS framework of uDig. - -@links_1130_a -# Jena - -@links_1131_p -# Java framework for building Semantic Web applications. - -@links_1132_a -# JMatter - -@links_1133_p -# Framework for constructing workgroup business applications based on the Naked Objects Architectural Pattern. - -@links_1134_a -# JotBot - -@links_1135_p -# Records your day at user defined intervals. - -@links_1136_a -# JPOX - -@links_1137_p -# Java persistent objects. - -@links_1138_a -# Liftweb - -@links_1139_p -# A Scala-based, secure, developer friendly web framework. - -@links_1140_a -# LiquiBase - -@links_1141_p -# A tool to manage database changes and refactorings. - -@links_1142_a -# Luntbuild - -@links_1143_p -# Build automation and management tool. - -@links_1144_a -# localdb - -@links_1145_p -# A tool that locates the full file path of the folder containing the database files. - -@links_1146_a -# Magnolia - -@links_1147_p -# Microarray Data Management and Export System for PFGRC (Pathogen Functional Genomics Resource Center) Microarrays. - -@links_1148_a -# MiniConnectionPoolManager - -@links_1149_p -# A lightweight standalone JDBC connection pool manager. - -@links_1150_a -# Mr. Persister - -@links_1151_p -# Simple, small and fast object relational mapping. - -@links_1152_a -# Myna Application Server - -@links_1153_p -# Java web app that provides dynamic web content and Java libraries access from JavaScript. - -@links_1154_a -# MyTunesRss - -@links_1155_p -# MyTunesRSS lets you listen to your music wherever you are. - -@links_1156_a -# NCGC CurveFit - -@links_1157_p -# From: NIH Chemical Genomics Center, National Institutes of Health, USA. An open source application in the life sciences research field. This application handles chemical structures and biological responses of thousands of compounds with the potential to handle million+ compounds. It utilizes an embedded H2 database to enable flexible query/retrieval of all data including advanced chemical substructure and similarity searching. The application highlights an automated curve fitting and classification algorithm that outperforms commercial packages in the field. Commercial alternatives are typically small desktop software that handle a few dose response curves at a time. A couple of commercial packages that do handle several thousand curves are very expensive tools (>60k USD) that require manual curation of analysis by the user; require a license to Oracle; lack advanced query/retrieval; and the ability to handle chemical structures. - -@links_1158_a -# Nuxeo - -@links_1159_p -# Standards-based, open source platform for building ECM applications. - -@links_1160_a -# nWire - -@links_1161_p -# Eclipse plug-in which expedites Java development. It's main purpose is to help developers find code quicker and easily understand how it relates to the rest of the application, thus, understand the application structure. - -@links_1162_a -# Ontology Works - -@links_1163_p -# This company provides semantic technologies including deductive information repositories (the Ontology Works Knowledge Servers), semantic information fusion and semantic federation of legacy databases, ontology-based domain modeling, and management of the distributed enterprise. - -@links_1164_a -# Ontoprise OntoBroker - -@links_1165_p -# SemanticWeb-Middleware. It supports all W3C Semantic Web recommendations: OWL, RDF, RDFS, SPARQL, and F-Logic. - -@links_1166_a -# Open Anzo - -@links_1167_p -# Semantic Application Server. - -@links_1168_a -# OpenTelegard - -@links_1169_p -# An OpenSource BBS Software written in JRuby. - -@links_1170_a -# OpenGroove - -@links_1171_p -# OpenGroove is a groupware program that allows users to synchronize data. - -@links_1172_a -# OpenSocial Development Environment (OSDE) - -@links_1173_p -# Development tool for OpenSocial application. - -@links_1174_a -# Orion - -@links_1175_p -# J2EE Application Server. - -@links_1176_a -# P5H2 - -@links_1177_p -# A library for the Processing programming language and environment. - -@links_1178_a -# Phase-6 - -@links_1179_p -# A computer based learning software. - -@links_1180_a -# Pickle - -@links_1181_p -# Pickle is a Java library containing classes for persistence, concurrency, and logging. - -@links_1182_a -# Piman - -@links_1183_p -# Water treatment projects data management. - -@links_1184_a -# PolePosition - -@links_1185_p -# Open source database benchmark. - -@links_1186_a -# Poormans - -@links_1187_p -# Very basic CMS running as a SWT application and generating static html pages. - -@links_1188_a -# Railo - -@links_1189_p -# Railo is an alternative engine for the Cold Fusion Markup Language, that compiles code programmed in CFML into Java bytecode and executes it on a servlet engine. - -@links_1190_a -# Razuna - -@links_1191_p -# Open source Digital Asset Management System with integrated Web Content Management. - -@links_1192_a -# RIFE - -@links_1193_p -# A full-stack web application framework with tools and APIs to implement most common web features. - -@links_1194_a -# Rutema - -@links_1195_p -# Rutema is a test execution and management tool for heterogeneous development environments written in Ruby. - -@links_1196_a -# Sava - -@links_1197_p -# Open-source web-based content management system. - -@links_1198_a -# Scriptella - -@links_1199_p -# ETL (Extract-Transform-Load) and script execution tool. - -@links_1200_a -# Sesar - -@links_1201_p -# Dependency Injection Container with Aspect Oriented Programming. - -@links_1202_a -# SemmleCode - -@links_1203_p -# Eclipse plugin to help you improve software quality. - -@links_1204_a -# SeQuaLite - -@links_1205_p -# A free, light-weight, java data access framework. - -@links_1206_a -# ShapeLogic - -@links_1207_p -# Toolkit for declarative programming, image processing and computer vision. - -@links_1208_a -# Shellbook - -@links_1209_p -# Desktop publishing application. - -@links_1210_a -# Signsoft intelliBO - -@links_1211_p -# Persistence middleware supporting the JDO specification. - -@links_1212_a -# SimpleORM - -@links_1213_p -# Simple Java Object Relational Mapping. - -@links_1214_a -# SymmetricDS - -@links_1215_p -# A web-enabled, database independent, data synchronization/replication software. - -@links_1216_a -# SmartFoxServer - -@links_1217_p -# Platform for developing multiuser applications and games with Macromedia Flash. - -@links_1218_a -# Social Bookmarks Friend Finder - -@links_1219_p -# A GUI application that allows you to find users with similar bookmarks to the user specified (for delicious.com). - -@links_1220_a -# Springfuse - -@links_1221_p -# Code generation For Spring, Spring MVC & Hibernate. - -@links_1222_a -# SQLOrm - -@links_1223_p -# Java Object Relation Mapping. - -@links_1224_a -# StorYBook - -@links_1225_p -# A summary-based tool for novelist and script writers. It helps to keep the overview over the various traces a story has. - -@links_1226_a -# StreamCruncher - -@links_1227_p -# Event (stream) processing kernel. - -@links_1228_a -# Tune Backup - -@links_1229_p -# Easy-to-use backup solution for your iTunes library. - -@links_1230_a -# weblica - -@links_1231_p -# Desktop CMS. - -@links_1232_a -# Web of Web - -@links_1233_p -# Collaborative and realtime interactive media platform for the web. - -@links_1234_a -# Werkzeugkasten - -@links_1235_p -# Minimum Java Toolset. - -@links_1236_a -# VPDA - -@links_1237_p -# View providers driven applications is a Java based application framework for building applications composed from server components - view providers. - -@links_1238_a -# Volunteer database - -@links_1239_p -# A database front end to register volunteers, partnership and donation for a Non Profit organization. - -@mainWeb_1000_h1 -H2 データベース エンジン - -@mainWeb_1001_p -# Welcome to H2, the Java SQL database. The main features of H2 are: - -@mainWeb_1002_li -#Very fast, open source, JDBC API - -@mainWeb_1003_li -#Embedded and server modes; in-memory databases - -@mainWeb_1004_li -#Browser based Console application - -@mainWeb_1005_li -#Small footprint: around 1 MB jar file size - -@mainWeb_1006_h3 -ダウンロード - -@mainWeb_1007_td -# Version 1.2.137 (2010-06-06): - -@mainWeb_1008_a -#Windows Installer (4 MB) - -@mainWeb_1009_a -#All Platforms (zip, 5 MB) - -@mainWeb_1010_a -#All Downloads - -@mainWeb_1011_td -    - -@mainWeb_1012_h3 -サポート - -@mainWeb_1013_a -Google グループ (English) - -@mainWeb_1014_a -Google グループ (Japanese) - -@mainWeb_1015_p -# For non-technical issues, use: - -@mainWeb_1016_h3 -特徴 - -@mainWeb_1017_th -H2 - -@mainWeb_1018_a -Derby - -@mainWeb_1019_a -HSQLDB - -@mainWeb_1020_a -MySQL - -@mainWeb_1021_a -PostgreSQL - -@mainWeb_1022_td -Pure Java - -@mainWeb_1023_td -対応 - -@mainWeb_1024_td -対応 - -@mainWeb_1025_td -対応 - -@mainWeb_1026_td -非対応 - -@mainWeb_1027_td -非対応 - -@mainWeb_1028_td -#Memory Mode - -@mainWeb_1029_td -対応 - -@mainWeb_1030_td -対応 - -@mainWeb_1031_td -対応 - -@mainWeb_1032_td -非対応 - -@mainWeb_1033_td -非対応 - -@mainWeb_1034_td -トランザクション分離 - -@mainWeb_1035_td -対応 - -@mainWeb_1036_td -対応 - -@mainWeb_1037_td -非対応 - -@mainWeb_1038_td -対応 - -@mainWeb_1039_td -対応 - -@mainWeb_1040_td -コストベースオプティマイザ - -@mainWeb_1041_td -対応 - -@mainWeb_1042_td -対応 - -@mainWeb_1043_td -非対応 - -@mainWeb_1044_td -対応 - -@mainWeb_1045_td -対応 - -@mainWeb_1046_td -暗号化データベース - -@mainWeb_1047_td -対応 - -@mainWeb_1048_td -対応 - -@mainWeb_1049_td -非対応 - -@mainWeb_1050_td -非対応 - -@mainWeb_1051_td -非対応 - -@mainWeb_1052_td -ODBCドライバ - -@mainWeb_1053_td -対応 - -@mainWeb_1054_td -非対応 - -@mainWeb_1055_td -非対応 - -@mainWeb_1056_td -対応 - -@mainWeb_1057_td -対応 - -@mainWeb_1058_td -フルテキストサーチ - -@mainWeb_1059_td -対応 - -@mainWeb_1060_td -非対応 - -@mainWeb_1061_td -非対応 - -@mainWeb_1062_td -対応 - -@mainWeb_1063_td -対応 - -@mainWeb_1064_td -#Multi Version Concurrency - -@mainWeb_1065_td -対応 - -@mainWeb_1066_td -非対応 - -@mainWeb_1067_td -非対応 - -@mainWeb_1068_td -対応 - -@mainWeb_1069_td -対応 - -@mainWeb_1070_td -フットプリント (jar/dll size) - -@mainWeb_1071_td -#~1 MB - -@mainWeb_1072_td -#~2 MB - -@mainWeb_1073_td -#~600 KB - -@mainWeb_1074_td -#~4 MB - -@mainWeb_1075_td -#~6 MB - -@mainWeb_1076_p -# See also the detailed comparison. - -@mainWeb_1077_h3 -ニュース - -@mainWeb_1078_b -ニュースフィード: - -@mainWeb_1079_a -#Full text (Atom) - -@mainWeb_1080_p -# or Header only (RSS). - -@mainWeb_1081_b -Email ニュースレター: - -@mainWeb_1082_p -# Subscribe to H2 Database News (Google account required) to get informed about new releases. Your email address is only used in this context. - -@mainWeb_1083_td -  - -@mainWeb_1084_h3 -寄稿する - -@mainWeb_1085_p -# You can contribute to the development of H2 by sending feedback and bug reports, or translate the H2 Console application (for details, start the H2 Console and select Options / Translate). To donate money, click on the PayPal button below. You will be listed as a supporter: - -@main_1000_h1 -H2 データベース エンジン - -@main_1001_p -# Welcome to H2, the free Java SQL database engine. - -@main_1002_a -クイックスタート - -@main_1003_p -# Get a fast overview. - -@main_1004_a -チュートリアル - -@main_1005_p -# Go through the samples. - -@main_1006_a -特徴 - -@main_1007_p -# See what this database can do and how to use these features. - -@performance_1000_h1 -パフォーマンス - -@performance_1001_a -# Performance Comparison - -@performance_1002_a -# PolePosition Benchmark - -@performance_1003_a -# Application Profiling - -@performance_1004_a -# Database Profiling - -@performance_1005_a -# Database Performance Tuning - -@performance_1006_a -# Using the Built-In Profiler - -@performance_1007_a -# Fast Database Import - -@performance_1008_h2 -#Performance Comparison - -@performance_1009_p -# In many cases H2 is faster than other (open source and not open source) database engines. Please note this is mostly a single connection benchmark run on one computer. - -@performance_1010_h3 -#Embedded - -@performance_1011_th -#Test Case - -@performance_1012_th -#Unit - -@performance_1013_th -H2 - -@performance_1014_th -HSQLDB - -@performance_1015_th -Derby - -@performance_1016_td -#Simple: Init - -@performance_1017_td -#ms - -@performance_1018_td -#547 - -@performance_1019_td -#532 - -@performance_1020_td -#2594 - -@performance_1021_td -#Simple: Query (random) - -@performance_1022_td -#ms - -@performance_1023_td -#250 - -@performance_1024_td -#391 - -@performance_1025_td -#1515 - -@performance_1026_td -#Simple: Query (sequential) - -@performance_1027_td -#ms - -@performance_1028_td -#188 - -@performance_1029_td -#313 - -@performance_1030_td -#1406 - -@performance_1031_td -#Simple: Update (random) - -@performance_1032_td -#ms - -@performance_1033_td -#812 - -@performance_1034_td -#1750 - -@performance_1035_td -#17704 - -@performance_1036_td -#Simple: Delete (sequential) - -@performance_1037_td -#ms - -@performance_1038_td -#203 - -@performance_1039_td -#250 - -@performance_1040_td -#8843 - -@performance_1041_td -#Simple: Memory Usage - -@performance_1042_td -#MB - -@performance_1043_td -#7 - -@performance_1044_td -#11 - -@performance_1045_td -#11 - -@performance_1046_td -#BenchA: Init - -@performance_1047_td -#ms - -@performance_1048_td -#578 - -@performance_1049_td -#719 - -@performance_1050_td -#3328 - -@performance_1051_td -#BenchA: Transactions - -@performance_1052_td -#ms - -@performance_1053_td -#3047 - -@performance_1054_td -#2406 - -@performance_1055_td -#12907 - -@performance_1056_td -#BenchA: Memory Usage - -@performance_1057_td -#MB - -@performance_1058_td -#10 - -@performance_1059_td -#15 - -@performance_1060_td -#10 - -@performance_1061_td -#BenchB: Init - -@performance_1062_td -#ms - -@performance_1063_td -#2141 - -@performance_1064_td -#2406 - -@performance_1065_td -#11562 - -@performance_1066_td -#BenchB: Transactions - -@performance_1067_td -#ms - -@performance_1068_td -#1125 - -@performance_1069_td -#1375 - -@performance_1070_td -#3625 - -@performance_1071_td -#BenchB: Memory Usage - -@performance_1072_td -#MB - -@performance_1073_td -#9 - -@performance_1074_td -#11 - -@performance_1075_td -#8 - -@performance_1076_td -#BenchC: Init - -@performance_1077_td -#ms - -@performance_1078_td -#688 - -@performance_1079_td -#594 - -@performance_1080_td -#4500 - -@performance_1081_td -#BenchC: Transactions - -@performance_1082_td -#ms - -@performance_1083_td -#1906 - -@performance_1084_td -#64062 - -@performance_1085_td -#6047 - -@performance_1086_td -#BenchC: Memory Usage - -@performance_1087_td -#MB - -@performance_1088_td -#11 - -@performance_1089_td -#17 - -@performance_1090_td -#11 - -@performance_1091_td -#Executed statements - -@performance_1092_td -## - -@performance_1093_td -#322929 - -@performance_1094_td -#322929 - -@performance_1095_td -#322929 - -@performance_1096_td -#Total time - -@performance_1097_td -#ms - -@performance_1098_td -#11485 - -@performance_1099_td -#74798 - -@performance_1100_td -#74031 - -@performance_1101_td -#Statements per second - -@performance_1102_td -## - -@performance_1103_td -#28117 - -@performance_1104_td -#4317 - -@performance_1105_td -#4362 - -@performance_1106_h3 -#Client-Server - -@performance_1107_th -#Test Case - -@performance_1108_th -#Unit - -@performance_1109_th -H2 - -@performance_1110_th -HSQLDB - -@performance_1111_th -Derby - -@performance_1112_th -PostgreSQL - -@performance_1113_th -MySQL - -@performance_1114_td -#Simple: Init - -@performance_1115_td -#ms - -@performance_1116_td -#2782 - -@performance_1117_td -#2656 - -@performance_1118_td -#5625 - -@performance_1119_td -#4563 - -@performance_1120_td -#3484 - -@performance_1121_td -#Simple: Query (random) - -@performance_1122_td -#ms - -@performance_1123_td -#3093 - -@performance_1124_td -#2703 - -@performance_1125_td -#6688 - -@performance_1126_td -#4812 - -@performance_1127_td -#3860 - -@performance_1128_td -#Simple: Query (sequential) - -@performance_1129_td -#ms - -@performance_1130_td -#2969 - -@performance_1131_td -#2594 - -@performance_1132_td -#6437 - -@performance_1133_td -#4719 - -@performance_1134_td -#3625 - -@performance_1135_td -#Simple: Update (random) - -@performance_1136_td -#ms - -@performance_1137_td -#2969 - -@performance_1138_td -#3531 - -@performance_1139_td -#18250 - -@performance_1140_td -#5953 - -@performance_1141_td -#5125 - -@performance_1142_td -#Simple: Delete (sequential) - -@performance_1143_td -#ms - -@performance_1144_td -#1047 - -@performance_1145_td -#1250 - -@performance_1146_td -#6875 - -@performance_1147_td -#2485 - -@performance_1148_td -#2390 - -@performance_1149_td -#Simple: Memory Usage - -@performance_1150_td -#MB - -@performance_1151_td -#7 - -@performance_1152_td -#11 - -@performance_1153_td -#14 - -@performance_1154_td -#0 - -@performance_1155_td -#0 - -@performance_1156_td -#BenchA: Init - -@performance_1157_td -#ms - -@performance_1158_td -#2250 - -@performance_1159_td -#2453 - -@performance_1160_td -#6031 - -@performance_1161_td -#4328 - -@performance_1162_td -#3625 - -@performance_1163_td -#BenchA: Transactions - -@performance_1164_td -#ms - -@performance_1165_td -#10250 - -@performance_1166_td -#9016 - -@performance_1167_td -#21484 - -@performance_1168_td -#15609 - -@performance_1169_td -#11172 - -@performance_1170_td -#BenchA: Memory Usage - -@performance_1171_td -#MB - -@performance_1172_td -#10 - -@performance_1173_td -#15 - -@performance_1174_td -#10 - -@performance_1175_td -#0 - -@performance_1176_td -#1 - -@performance_1177_td -#BenchB: Init - -@performance_1178_td -#ms - -@performance_1179_td -#9500 - -@performance_1180_td -#10672 - -@performance_1181_td -#22609 - -@performance_1182_td -#19609 - -@performance_1183_td -#13406 - -@performance_1184_td -#BenchB: Transactions - -@performance_1185_td -#ms - -@performance_1186_td -#2734 - -@performance_1187_td -#2656 - -@performance_1188_td -#3875 - -@performance_1189_td -#4688 - -@performance_1190_td -#2531 - -@performance_1191_td -#BenchB: Memory Usage - -@performance_1192_td -#MB - -@performance_1193_td -#10 - -@performance_1194_td -#11 - -@performance_1195_td -#11 - -@performance_1196_td -#1 - -@performance_1197_td -#1 - -@performance_1198_td -#BenchC: Init - -@performance_1199_td -#ms - -@performance_1200_td -#1860 - -@performance_1201_td -#1484 - -@performance_1202_td -#6890 - -@performance_1203_td -#2219 - -@performance_1204_td -#3438 - -@performance_1205_td -#BenchC: Transactions - -@performance_1206_td -#ms - -@performance_1207_td -#9046 - -@performance_1208_td -#63266 - -@performance_1209_td -#18641 - -@performance_1210_td -#11703 - -@performance_1211_td -#7421 - -@performance_1212_td -#BenchC: Memory Usage - -@performance_1213_td -#MB - -@performance_1214_td -#12 - -@performance_1215_td -#17 - -@performance_1216_td -#13 - -@performance_1217_td -#0 - -@performance_1218_td -#1 - -@performance_1219_td -#Executed statements - -@performance_1220_td -## - -@performance_1221_td -#322929 - -@performance_1222_td -#322929 - -@performance_1223_td -#322929 - -@performance_1224_td -#322929 - -@performance_1225_td -#322929 - -@performance_1226_td -#Total time - -@performance_1227_td -#ms - -@performance_1228_td -#48500 - -@performance_1229_td -#102281 - -@performance_1230_td -#123405 - -@performance_1231_td -#80688 - -@performance_1232_td -#60077 - -@performance_1233_td -#Statements per second - -@performance_1234_td -## - -@performance_1235_td -#6658 - -@performance_1236_td -#3157 - -@performance_1237_td -#2616 - -@performance_1238_td -#4002 - -@performance_1239_td -#5375 - -@performance_1240_h3 -#Benchmark Results and Comments - -@performance_1241_h4 -H2 - -@performance_1242_p -# Version 1.1.114 (2009-06-01) was used for the test. For simpler operations, the performance of H2 is about the same as for HSQLDB. For more complex queries, the query optimizer is very important. However H2 is not very fast in every case, certain kind of queries may still be slow. One situation where is H2 is slow is large result sets, because they are buffered to disk if more than a certain number of records are returned. The advantage of buffering is, there is no limit on the result set size. The open/close time is almost fixed, because of the file locking protocol: the engine waits some time after opening a database to ensure the database files are not opened by another process. - -@performance_1243_h4 -HSQLDB - -@performance_1244_p -# Version 1.8.0.10 was used for the test. Cached tables are used in this test (hsqldb.default_table_type=cached), and the write delay is 1 second (SET WRITE_DELAY 1). HSQLDB is fast when using simple operations. HSQLDB is very slow in the last test (BenchC: Transactions), probably because is has a bad query optimizer. One query where HSQLDB is slow is a two-table join: - -@performance_1245_p -# The PolePosition benchmark also shows that the query optimizer does not do a very good job for some queries. Another disadvantage of HSQLDB is the slow startup / shutdown time (currently not listed) when using bigger databases. The reason is, a backup of the whole data is made whenever the database is opened or closed. - -@performance_1246_h4 -Derby - -@performance_1247_p -# Version 10.4.2.0 was used for the test. Derby is clearly the slowest embedded database in this test. This seems to be a structural problem, because all operations are really slow. It will be hard for the developers of Derby to improve the performance to a reasonable level. A few problems have been identified: leaving autocommit on is a problem for Derby. If it is switched off during the whole test, the results are about 20% better for Derby. Derby does not call FileDescriptor.sync() or FileChannel.force(..) on each commit. Derby supports a testing mode (system property derby.system.durability=test) where durability is disabled. According to the documentation, this setting should be used for testing only, as the database may not recover after a crash. Enabling this setting improves performance by a factor of 2.6 (embedded mode) or 1.4 (server mode). Even if enabled, Derby is still less than half as fast as H2 in default mode. - -@performance_1248_h4 -PostgreSQL - -@performance_1249_p -# Version 8.3.7 was used for the test. The following options where changed in postgresql.conf: fsync = off, commit_delay = 1000. PostgreSQL is run in server mode. It looks like the base performance is slower than MySQL, the reason could be the network layer. The memory usage number is incorrect, because only the memory usage of the JDBC driver is measured. - -@performance_1250_h4 -MySQL - -@performance_1251_p -# Version 5.1.34-community was used for the test. MySQL was run with the InnoDB backend. The setting innodb_flush_log_at_trx_commit (found in the my.ini file) was set to 0. Otherwise (and by default), MySQL is really slow (around 140 statements per second in this test) because it tries to flush the data to disk for each commit. For small transactions (when autocommit is on) this is really slow. But many use cases use small or relatively small transactions. Too bad this setting is not listed in the configuration wizard, and it always overwritten when using the wizard. You need to change this setting manually in the file my.ini, and then restart the service. The memory usage number is incorrect, because only the memory usage of the JDBC driver is measured. - -@performance_1252_h4 -#Firebird - -@performance_1253_p -# Firebird 1.5 (default installation) was tested, but the results are not published currently. It is possible to run the performance test with the Firebird database, and any information on how to configure Firebird for higher performance are welcome. - -@performance_1254_h4 -#Why Oracle / MS SQL Server / DB2 are Not Listed - -@performance_1255_p -# The license of these databases does not allow to publish benchmark results. This doesn't mean that they are fast. They are in fact quite slow, and need a lot of memory. But you will need to test this yourself. SQLite was not tested because the JDBC driver doesn't support transactions. - -@performance_1256_h3 -#About this Benchmark - -@performance_1257_h4 -#How to Run - -@performance_1258_p -# This test was executed as follows: - -@performance_1259_h4 -#Separate Process per Database - -@performance_1260_p -# For each database, a new process is started, to ensure the previous test does not impact the current test. - -@performance_1261_h4 -#Number of Connections - -@performance_1262_p -# This is mostly a single-connection benchmark. BenchB uses multiple connections; the other tests use one connection. - -@performance_1263_h4 -#Real-World Tests - -@performance_1264_p -# Good benchmarks emulate real-world use cases. This benchmark includes 4 test cases: BenchSimple uses one table and many small updates / deletes. BenchA is similar to the TPC-A test, but single connection / single threaded (see also: www.tpc.org). BenchB is similar to the TPC-B test, using multiple connections (one thread per connection). BenchC is similar to the TPC-C test, but single connection / single threaded. - -@performance_1265_h4 -#Comparing Embedded with Server Databases - -@performance_1266_p -# This is mainly a benchmark for embedded databases (where the application runs in the same virtual machine as the database engine). However MySQL and PostgreSQL are not Java databases and cannot be embedded into a Java application. For the Java databases, both embedded and server modes are tested. - -@performance_1267_h4 -#Test Platform - -@performance_1268_p -# This test is run on Windows XP with the virus scanner switched off. The VM used is Sun JDK 1.5. - -@performance_1269_h4 -#Multiple Runs - -@performance_1270_p -# When a Java benchmark is run first, the code is not fully compiled and therefore runs slower than when running multiple times. A benchmark should always run the same test multiple times and ignore the first run(s). This benchmark runs three times, but only the last run is measured. - -@performance_1271_h4 -#Memory Usage - -@performance_1272_p -# It is not enough to measure the time taken, the memory usage is important as well. Performance can be improved by using a bigger cache, but the amount of memory is limited. HSQLDB tables are kept fully in memory by default; this benchmark uses 'disk based' tables for all databases. Unfortunately, it is not so easy to calculate the memory usage of PostgreSQL and MySQL, because they run in a different process than the test. This benchmark currently does not print memory usage of those databases. - -@performance_1273_h4 -#Delayed Operations - -@performance_1274_p -# Some databases delay some operations (for example flushing the buffers) until after the benchmark is run. This benchmark waits between each database tested, and each database runs in a different process (sequentially). - -@performance_1275_h4 -#Transaction Commit / Durability - -@performance_1276_p -# Durability means transaction committed to the database will not be lost. Some databases (for example MySQL) try to enforce this by default by calling fsync() to flush the buffers, but most hard drives don't actually flush all data. Calling the method slows down transaction commit a lot, but doesn't always make data durable. When comparing the results, it is important to think about the effect. Many database suggest to 'batch' operations when possible. This benchmark switches off autocommit when loading the data, and calls commit after each 1000 inserts. However many applications need 'short' transactions at runtime (a commit after each update). This benchmark commits after each update / delete in the simple benchmark, and after each business transaction in the other benchmarks. For databases that support delayed commits, a delay of one second is used. - -@performance_1277_h4 -#Using Prepared Statements - -@performance_1278_p -# Wherever possible, the test cases use prepared statements. - -@performance_1279_h4 -#Currently Not Tested: Startup Time - -@performance_1280_p -# The startup time of a database engine is important as well for embedded use. This time is not measured currently. Also, not tested is the time used to create a database and open an existing database. Here, one (wrapper) connection is opened at the start, and for each step a new connection is opened and then closed. - -@performance_1281_h2 -#PolePosition Benchmark - -@performance_1282_p -# The PolePosition is an open source benchmark. The algorithms are all quite simple. It was developed / sponsored by db4o. - -@performance_1283_th -#Test Case - -@performance_1284_th -#Unit - -@performance_1285_th -H2 - -@performance_1286_th -HSQLDB - -@performance_1287_th -MySQL - -@performance_1288_td -#Melbourne write - -@performance_1289_td -#ms - -@performance_1290_td -#369 - -@performance_1291_td -#249 - -@performance_1292_td -#2022 - -@performance_1293_td -#Melbourne read - -@performance_1294_td -#ms - -@performance_1295_td -#47 - -@performance_1296_td -#49 - -@performance_1297_td -#93 - -@performance_1298_td -#Melbourne read_hot - -@performance_1299_td -#ms - -@performance_1300_td -#24 - -@performance_1301_td -#43 - -@performance_1302_td -#95 - -@performance_1303_td -#Melbourne delete - -@performance_1304_td -#ms - -@performance_1305_td -#147 - -@performance_1306_td -#133 - -@performance_1307_td -#176 - -@performance_1308_td -#Sepang write - -@performance_1309_td -#ms - -@performance_1310_td -#965 - -@performance_1311_td -#1201 - -@performance_1312_td -#3213 - -@performance_1313_td -#Sepang read - -@performance_1314_td -#ms - -@performance_1315_td -#765 - -@performance_1316_td -#948 - -@performance_1317_td -#3455 - -@performance_1318_td -#Sepang read_hot - -@performance_1319_td -#ms - -@performance_1320_td -#789 - -@performance_1321_td -#859 - -@performance_1322_td -#3563 - -@performance_1323_td -#Sepang delete - -@performance_1324_td -#ms - -@performance_1325_td -#1384 - -@performance_1326_td -#1596 - -@performance_1327_td -#6214 - -@performance_1328_td -#Bahrain write - -@performance_1329_td -#ms - -@performance_1330_td -#1186 - -@performance_1331_td -#1387 - -@performance_1332_td -#6904 - -@performance_1333_td -#Bahrain query_indexed_string - -@performance_1334_td -#ms - -@performance_1335_td -#336 - -@performance_1336_td -#170 - -@performance_1337_td -#693 - -@performance_1338_td -#Bahrain query_string - -@performance_1339_td -#ms - -@performance_1340_td -#18064 - -@performance_1341_td -#39703 - -@performance_1342_td -#41243 - -@performance_1343_td -#Bahrain query_indexed_int - -@performance_1344_td -#ms - -@performance_1345_td -#104 - -@performance_1346_td -#134 - -@performance_1347_td -#678 - -@performance_1348_td -#Bahrain update - -@performance_1349_td -#ms - -@performance_1350_td -#191 - -@performance_1351_td -#87 - -@performance_1352_td -#159 - -@performance_1353_td -#Bahrain delete - -@performance_1354_td -#ms - -@performance_1355_td -#1215 - -@performance_1356_td -#729 - -@performance_1357_td -#6812 - -@performance_1358_td -#Imola retrieve - -@performance_1359_td -#ms - -@performance_1360_td -#198 - -@performance_1361_td -#194 - -@performance_1362_td -#4036 - -@performance_1363_td -#Barcelona write - -@performance_1364_td -#ms - -@performance_1365_td -#413 - -@performance_1366_td -#832 - -@performance_1367_td -#3191 - -@performance_1368_td -#Barcelona read - -@performance_1369_td -#ms - -@performance_1370_td -#119 - -@performance_1371_td -#160 - -@performance_1372_td -#1177 - -@performance_1373_td -#Barcelona query - -@performance_1374_td -#ms - -@performance_1375_td -#20 - -@performance_1376_td -#5169 - -@performance_1377_td -#101 - -@performance_1378_td -#Barcelona delete - -@performance_1379_td -#ms - -@performance_1380_td -#388 - -@performance_1381_td -#319 - -@performance_1382_td -#3287 - -@performance_1383_td -#Total - -@performance_1384_td -#ms - -@performance_1385_td -#26724 - -@performance_1386_td -#53962 - -@performance_1387_td -#87112 - -@performance_1388_p -# There are a few problems with the PolePosition test: - -@performance_1389_li -# HSQLDB uses in-memory tables by default while H2 uses persistent tables. The HSQLDB version included in PolePosition does not support changing this, so you need to replace poleposition-0.20/lib/hsqldb.jar with a newer version (for example hsqldb-1.8.0.7.jar), and then use the setting hsqldb.connecturl=jdbc:hsqldb:file:data/hsqldb/dbbench2;hsqldb.default_table_type=cached;sql.enforce_size=true in the file Jdbc.properties. - -@performance_1390_li -#HSQLDB keeps the database open between tests, while H2 closes the database (losing all the cache). To change that, use the database URL jdbc:h2:file:data/h2/dbbench;DB_CLOSE_DELAY=-1 - -@performance_1391_li -#The amount of cache memory is quite important, specially for the PolePosition test. Unfortunately, the PolePosition test does not take this into account. - -@performance_1392_h2 -#Application Profiling - -@performance_1393_h3 -#Analyze First - -@performance_1394_p -# Before trying to optimize performance, it is important to understand where the problem is (what part of the application is slow). Blind optimization or optimization based on guesses should be avoided, because usually it is not an efficient strategy. There are various ways to analyze an application. Sometimes two implementations can be compared using System.currentTimeMillis(). But this does not work for complex applications with many modules, and for memory problems. - -@performance_1395_p -# A simple way to profile an application is to use the built-in profiling tool of java. Example: - -@performance_1396_p -# Unfortunately, it is only possible to profile the application from start to end. Another solution is to create a number of full thread dumps. To do that, first run jps -l to get the process id, and then run jstack <pid> or kill -QUIT <pid> (Linux) or press Ctrl+C (Windows). - -@performance_1397_p -# A simple profiling tool is included in H2. To use it, the application needs to be changed slightly. Example: - -@performance_1398_p -# The profiler is built into the H2 Console tool, to analyze databases that open slowly. To use it, run the H2 Console, and then click on 'Test Connection'. Afterwards, click on "Test successful" and you get the most common stack traces, which helps to find out why it took so long to connect. You will only get the stack traces if opening the database took more than a few seconds. - -@performance_1399_h2 -#Database Profiling - -@performance_1400_p -# The ConvertTraceFile tool generates SQL statement statistics at the end of the SQL script file. The format used is similar to the profiling data generated when using java -Xrunhprof. As an example, execute the the following script using the H2 Console: - -@performance_1401_p -# Now convert the .trace.db file using the ConvertTraceFile tool: - -@performance_1402_p -# The generated file test.sql will contain the SQL statements as well as the following profiling data (results vary): - -@performance_1403_h2 -#Database Performance Tuning - -@performance_1404_h3 -#Keep Connections Open or Use a Connection Pool - -@performance_1405_p -# If your application opens and closes connections a lot (for example, for each request), you should consider using a connection pool. Opening a connection using DriverManager.getConnection is specially slow if the database is closed. By default the database is closed if the last connection is closed. - -@performance_1406_p -# If you open and close connections a lot but don't want to use a connection pool, consider keeping a 'sentinel' connection open for as long as the application runs, or use delayed database closing. See also Closing a database. - -@performance_1407_h3 -#Use a Modern JVM - -@performance_1408_p -# Newer JVMs are faster. Upgrading to the latest version of your JVM can provide a "free" boost to performance. Switching from the default Client JVM to the Server JVM using the -server command-line option improves performance at the cost of a slight increase in start-up time. - -@performance_1409_h3 -#Virus Scanners - -@performance_1410_p -# Some virus scanners scan files every time they are accessed. It is very important for performance that database files are not scanned for viruses. The database engine never interprets the data stored in the files as programs, that means even if somebody would store a virus in a database file, this would be harmless (when the virus does not run, it cannot spread). Some virus scanners allow to exclude files by suffix. Ensure files ending with .db are not scanned. - -@performance_1411_h3 -トレースオプションを使用する - -@performance_1412_p -# If the performance hot spots are in the database engine, in many cases the performance can be optimized by creating additional indexes, or changing the schema. Sometimes the application does not directly generate the SQL statements, for example if an O/R mapping tool is used. To view the SQL statements and JDBC API calls, you can use the trace options. For more information, see Using the Trace Options. - -@performance_1413_h3 -#Index Usage - -@performance_1414_p -# This database uses indexes to improve the performance of SELECT, UPDATE, DELETE. If a column is used in the WHERE clause of a query, and if an index exists on this column, then the index can be used. Multi-column indexes are used if all or the first columns of the index are used. Both equality lookup and range scans are supported. Indexes are used to order result sets, but only if the condition uses the same index or no index at all. The results are sorted in memory if required. Indexes are created automatically for primary key and unique constraints. Indexes are also created for foreign key constraints, if required. For other columns, indexes need to be created manually using the CREATE INDEX statement. - -@performance_1415_h3 -#Optimizer - -@performance_1416_p -# This database uses a cost based optimizer. For simple and queries and queries with medium complexity (less than 7 tables in the join), the expected cost (running time) of all possible plans is calculated, and the plan with the lowest cost is used. For more complex queries, the algorithm first tries all possible combinations for the first few tables, and the remaining tables added using a greedy algorithm (this works well for most joins). Afterwards a genetic algorithm is used to test at most 2000 distinct plans. Only left-deep plans are evaluated. - -@performance_1417_h3 -#Expression Optimization - -@performance_1418_p -# After the statement is parsed, all expressions are simplified automatically if possible. Operations are evaluated only once if all parameters are constant. Functions are also optimized, but only if the function is constant (always returns the same result for the same parameter values). If the WHERE clause is always false, then the table is not accessed at all. - -@performance_1419_h3 -#COUNT(*) Optimization - -@performance_1420_p -# If the query only counts all rows of a table, then the data is not accessed. However, this is only possible if no WHERE clause is used, that means it only works for queries of the form SELECT COUNT(*) FROM table. - -@performance_1421_h3 -#Updating Optimizer Statistics / Column Selectivity - -@performance_1422_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. - -@performance_1423_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', the index on NAME or the index on FIRSTNAME. It is not possible to use both indexes at the same time. Which index is used depends on the selectivity of the column. The selectivity describes the 'uniqueness' of 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. - -@performance_1424_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. - -@performance_1425_h3 -#In-Memory (Hash) Indexes - -@performance_1426_p -# Using in-memory indexes, specially in-memory hash indexes, can speed up queries and data manipulation. - -@performance_1427_p -#In-memory indexes are automatically used for in-memory databases, but can also be created for persistent databases using CREATE MEMORY TABLE. In many cases, the rows itself will also be kept in-memory. Please note this may cause memory problems for large tables. - -@performance_1428_p -# In-memory hash indexes are backed by a hash table and are usually faster than regular indexes. However, hash indexes only supports direct lookup (WHERE ID = ?) but not range scan (WHERE ID < ?). To use hash indexes, use HASH as in: CREATE UNIQUE HASH INDEX and CREATE TABLE ...(ID INT PRIMARY KEY HASH,...). - -@performance_1429_h3 -#Use Prepared Statements - -@performance_1430_p -# If possible, use prepared statements with parameters. - -@performance_1431_h3 -#Prepared Statements and IN(...) - -@performance_1432_p -# Avoid generating SQL statements with a variable size IN(...) list. Instead, use a prepared statement with arrays as in the following example: - -@performance_1433_h3 -#Optimization Examples - -@performance_1434_p -# See src/test/org/h2/samples/optimizations.sql for a few examples of queries that benefit from special optimizations built into the database. - -@performance_1435_h3 -#Cache Size and Type - -@performance_1436_p -# By default the cache size of H2 is quite small. Consider using a larger cache size, or enable the second level soft reference cache. See also Cache Settings. - -@performance_1437_h3 -データ型 - -@performance_1438_p -# Each data type has different storage and performance characteristics: - -@performance_1439_li -#The DECIMAL/NUMERIC type is slower and requires more storage than the REAL and DOUBLE types. - -@performance_1440_li -#Text types are slower to read, write, and compare than numeric types and generally require more storage. - -@performance_1441_li -#See Large Objects for information on BINARY vs. BLOB and VARCHAR vs. CLOB performance. - -@performance_1442_li -#Parsing and formatting takes longer for the TIME, DATE, and TIMESTAMP types than the numeric types. - -@performance_1443_code -#SMALLINT/TINYINT/BOOLEAN - -@performance_1444_li -# are not significantly smaller or faster to work with than INTEGER in most modes. - -@performance_1445_h3 -#Sorted Insert Optimization - -@performance_1446_p -# To reduce disk space usage and speed up table creation, an optimization for sorted inserts is available. When used, b-tree pages are split at the insertion point. To use this optimization, add SORTED before the SELECT statement: - -@performance_1447_h2 -#Using the Built-In Profiler - -@performance_1448_p -# A very simple Java profiler is built-in. To use it, use the following template: - -@performance_1449_h2 -#Fast Database Import - -@performance_1450_p -# To speed up large imports, consider using the following options temporarily: - -@performance_1451_code -#SET CACHE_SIZE - -@performance_1452_li -# (a large cache is faster) - -@performance_1453_code -#SET LOCK_MODE 0 - -@performance_1454_li -# (disable locking) - -@performance_1455_code -#SET UNDO_LOG 0 - -@performance_1456_li -# (disable the session undo log) - -@performance_1457_p -# These options can be set in the database URL: jdbc:h2:~/test;CACHE_SIZE=65536;LOCK_MODE=0;UNDO_LOG=0. Most of those options are not recommended for regular use, that means you need to reset them after use. - -@quickstart_1000_h1 -クイックスタート - -@quickstart_1001_a -# Embedding H2 in an Application - -@quickstart_1002_a -# The H2 Console Application - -@quickstart_1003_h2 -アプリケーションのエンベッドH2 - -@quickstart_1004_p -# This database can be used in embedded mode, or in server mode. To use it in embedded mode, you need to: - -@quickstart_1005_li -#Add the h2*.jar to the classpath (H2 does not have any dependencies) - -@quickstart_1006_li -#Use the JDBC driver class: org.h2.Driver - -@quickstart_1007_li -#The database URL jdbc:h2:~/test opens the database test in your user home directory - -@quickstart_1008_li -#A new database is automatically created - -@quickstart_1009_h2 -H2 コンソール アプリケーション - -@quickstart_1010_p -# The Console lets you access a SQL database using a browser interface. - -@quickstart_1011_p -# If you don't have Windows XP, or if something does not work as expected, please see the detailed description in the Tutorial. - -@quickstart_1012_h3 -手順 - -@quickstart_1013_h4 -インストール - -@quickstart_1014_p -# Install the software using the Windows Installer (if you did not yet do that). - -@quickstart_1015_h4 -コンソールを起動する - -@quickstart_1016_p -# Click [Start], [All Programs], [H2], and [H2 Console (Command Line)]: - -@quickstart_1017_p -# A new console window appears: - -@quickstart_1018_p -# Also, a new browser page should open with the URL http://localhost:8082. You may get a security warning from the firewall. If you don't want other computers in the network to access the database on your machine, you can let the firewall block these connections. Only local connections are required at this time. - -@quickstart_1019_h4 -ログイン - -@quickstart_1020_p -# Select [Generic H2] and click [Connect]: - -@quickstart_1021_p -# You are now logged in. - -@quickstart_1022_h4 -サンプル - -@quickstart_1023_p -# Click on the [Sample SQL Script]: - -@quickstart_1024_p -# The SQL commands appear in the command area. - -@quickstart_1025_h4 -実行する - -@quickstart_1026_p -# Click [Run] - -@quickstart_1027_p -# On the left side, a new entry TEST is added below the database icon. The operations and results of the statements are shown below the script. - -@quickstart_1028_h4 -切断 - -@quickstart_1029_p -# Click on [Disconnect]: - -@quickstart_1030_p -# to close the connection. - -@quickstart_1031_h4 -終了 - -@quickstart_1032_p -# Close the console window. For more information, see the Tutorial. - -@roadmap_1000_h1 -ロードマップ - -@roadmap_1001_p -# New (feature) requests will usually be added at the very end of the list. The priority is increased for important and popular requests. Of course, patches are always welcome, but are not always applied as is. See also Providing Patches. - -@roadmap_1002_h2 -#Version 1.3.x: Planned Changes - -@roadmap_1003_li -#Enable h2.lobInDatabase (store CLOB and BLOB in the database file). - -@roadmap_1004_li -#Set h2.analyzeAuto to 2000 (automatic ANALYZE). - -@roadmap_1005_li -#Enable h2.functionsInSchema (allow to store functions in a schema). - -@roadmap_1006_li -#Enable h2.selectForUpdateMvcc (MVCC and SELECT FOR UPDATE). - -@roadmap_1007_li -#Enable h2.largeTransactions (support for very large transactions). Change documentation for MAX_MEMORY_UNDO in help.csv, because now changes to tables without a primary key can be buffered to disk. Later, change MAX_MEMORY_UNDO to reflect number of bytes instead of record (also remove Constants.UNDO_BLOCK_SIZE). Later, change undo log file format (fillAligned no longer required; var int). - -@roadmap_1008_h2 -#Priority 1 - -@roadmap_1009_li -#Bugfixes - -@roadmap_1010_li -#Support very large transactions. Reduce memory usage of undo log (TestUndoLogMemory). - -@roadmap_1011_li -#More tests with MULTI_THREADED=1 - -@roadmap_1012_li -#Optimization: result set caching (like MySQL); option to disable - -@roadmap_1013_li -#Server side cursors - -@roadmap_1014_h2 -#Priority 2 - -@roadmap_1015_li -#Support nested outer joins (see todo.txt, issues 145, 177, 203). - -@roadmap_1016_li -#Improve test code coverage. - -@roadmap_1017_li -#Test multi-threaded in-memory db access. - -@roadmap_1018_li -#Full outer joins. - -@roadmap_1019_li -#Clustering: support mixed clustering mode (one embedded, others in server mode). - -@roadmap_1020_li -#Clustering: reads should be randomly distributed (optional) or to a designated database on RAM (parameter: READ_FROM=3). - -@roadmap_1021_li -#PostgreSQL catalog: use BEFORE SELECT triggers instead of views over metadata tables. - -@roadmap_1022_li -#Test very large databases and LOBs (up to 256 GB). - -@roadmap_1023_li -#Support hints for the optimizer (which index to use, enforce the join order). - -@roadmap_1024_li -#Sequence: add features [NO] MINVALUE, MAXVALUE, CYCLE. - -@roadmap_1025_li -#Access rights: remember the owner of an object. Create, alter and drop privileges. COMMENT: allow owner of object to change it. - -@roadmap_1026_li -#Deferred integrity checking (DEFERRABLE INITIALLY DEFERRED). - -@roadmap_1027_li -#Groovy Stored Procedures: http://groovy.codehaus.org/Groovy+SQL - -@roadmap_1028_li -#Add a migration guide (list differences between databases). - -@roadmap_1029_li -#Migrate database tool (also from other database engines). - -@roadmap_1030_li -#Optimization: automatic index creation suggestion using the trace file? - -@roadmap_1031_li -#Compression performance: don't allocate buffers, compress / expand in to out buffer. - -@roadmap_1032_li -#Rebuild index functionality to shrink index size and improve performance. - -@roadmap_1033_li -#Don't use deleteOnExit (bug 4513817: File.deleteOnExit consumes memory). - -@roadmap_1034_li -#Console: add accesskey to most important commands (A, AREA, BUTTON, INPUT, LABEL, LEGEND, TEXTAREA). - -@roadmap_1035_li -#Test performance again with SQL Server, Oracle, DB2. - -@roadmap_1036_li -#Test with Spatial DB in a box / JTS: http://www.opengeospatial.org/standards/sfs - OpenGIS Implementation Specification. - -@roadmap_1037_li -#Write more tests and documentation for MVCC (Multi Version Concurrency Control). - -@roadmap_1038_li -#Find a tool to view large text file (larger than 100 MB), with find, page up and down (like less), truncate before / after. - -@roadmap_1039_li -#Implement, test, document XAConnection and so on. - -@roadmap_1040_li -#Pluggable data type (for streaming, hashing, compression, validation, conversion, encryption). - -@roadmap_1041_li -#CHECK: find out what makes CHECK=TRUE slow, move to CHECK2. - -@roadmap_1042_li -#Index usage for (ID, NAME)=(1, 'Hi'); document. - -@roadmap_1043_li -#Make DDL (Data Definition) operations transactional. - -@roadmap_1044_li -#RANK() and DENSE_RANK(), Partition using OVER(). - -@roadmap_1045_li -#Set a connection read only (Connection.setReadOnly) or using a connection parameter. - -@roadmap_1046_li -#Optimizer: use an index for IS NULL and IS NOT NULL (including linked tables). ID IS NOT NULL could be converted to ID >= Integer.MIN_VALUE. - -@roadmap_1047_li -#Access rights: finer grained access control (grant access for specific functions). - -@roadmap_1048_li -#Version check: docs / web console (using Javascript), and maybe in the library (using TCP/IP). - -@roadmap_1049_li -#Web server classloader: override findResource / getResourceFrom. - -@roadmap_1050_li -#Cost for embedded temporary view is calculated wrong, if result is constant. - -@roadmap_1051_li -#Comparison: pluggable sort order: natural sort. - -@roadmap_1052_li -#Count index range query (count(*) where id between 10 and 20). - -@roadmap_1053_li -#Performance: update in-place. - -@roadmap_1054_li -#Recursive Queries (see details). - -@roadmap_1055_li -#Eclipse plugin. - -@roadmap_1056_li -#Asynchronous queries to support publish/subscribe: SELECT ... FOR READ WAIT [maxMillisToWait]. - -@roadmap_1057_li -#Fulltext search Lucene: analyzer configuration. - -@roadmap_1058_li -#Fulltext search (native): reader / tokenizer / filter. - -@roadmap_1059_li -#Linked schema using CSV files: one schema for a directory of files; support indexes for CSV files. - -@roadmap_1060_li -#iReport to support H2. - -@roadmap_1061_li -#Implement missing JDBC API (CallableStatement,...). - -@roadmap_1062_li -#Compression of the cache. - -@roadmap_1063_li -#Include SMPT (mail) client (alert on cluster failure, low disk space,...). - -@roadmap_1064_li -#Drop with restrict (currently cascade is the default). - -@roadmap_1065_li -#JSON parser and functions. - -@roadmap_1066_li -#Server: client ping from time to time (to avoid timeout - is timeout a problem?). - -@roadmap_1067_li -#Copy database: tool with config GUI and batch mode, extensible (example: compare). - -@roadmap_1068_li -#Document, implement tool for long running transactions using user-defined compensation statements. - -@roadmap_1069_li -#Support SET TABLE DUAL READONLY. - -@roadmap_1070_li -#GCJ: what is the state now? - -@roadmap_1071_li -#Events for: database Startup, Connections, Login attempts, Disconnections, Prepare (after parsing), Web Server. See http://docs.openlinksw.com/virtuoso/fn_dbev_startup.html - -@roadmap_1072_li -#Optimization: log compression. - -@roadmap_1073_li -#ROW_NUMBER() OVER([ORDER BY columnName]). - -@roadmap_1074_li -#Support standard INFORMATION_SCHEMA tables, as defined in http://www.contrib.andrew.cmu.edu/~shadow/sql/sql1992.txt - specially KEY_COLUMN_USAGE: http://dev.mysql.com/doc/refman/5.0/en/information-schema.html, http://www.xcdsql.org/Misc/INFORMATION_SCHEMA%20With%20Rolenames.gif - -@roadmap_1075_li -#Compatibility: in MySQL, HSQLDB, /0.0 is NULL; in PostgreSQL, Derby: division by zero. - -@roadmap_1076_li -#Functional tables should accept parameters from other tables (see FunctionMultiReturn) SELECT * FROM TEST T, P2C(T.A, T.R). - -@roadmap_1077_li -#Custom class loader to reload functions on demand. - -@roadmap_1078_li -#Clustering: when a database is back alive, automatically synchronize with the master. - -@roadmap_1079_li -#Test http://mysql-je.sourceforge.net/ - -@roadmap_1080_li -#Performance: automatically build in-memory indexes if the whole table is in memory. - -@roadmap_1081_li -#H2 Console: the webclient could support more features like phpMyAdmin. - -@roadmap_1082_li -#Use Janino to convert Java to C++. - -@roadmap_1083_li -#The HELP information schema can be directly exposed in the Console. - -@roadmap_1084_li -#Maybe use the 0x1234 notation for binary fields, see MS SQL Server. - -@roadmap_1085_li -#Support Oracle CONNECT BY in some way: http://www.adp-gmbh.ch/ora/sql/connect_by.html http://philip.greenspun.com/sql/trees.html - -@roadmap_1086_li -#SQL Server 2005, Oracle: support COUNT(*) OVER(). See http://www.orafusion.com/art_anlytc.htm - -@roadmap_1087_li -#SQL 2003: http://www.wiscorp.com/sql_2003_standard.zip - -@roadmap_1088_li -#Version column (number/sequence and timestamp based). - -@roadmap_1089_li -#Optimize getGeneratedKey: send last identity after each execute (server). - -@roadmap_1090_li -#Test and document UPDATE TEST SET (ID, NAME) = (SELECT ID*10, NAME || '!' FROM TEST T WHERE T.ID=TEST.ID). - -@roadmap_1091_li -#Max memory rows / max undo log size: use block count / row size not row count. - -@roadmap_1092_li -#Support 123L syntax as in Java; example: SELECT (2000000000*2). - -@roadmap_1093_li -#Implement point-in-time recovery. - -@roadmap_1094_li -#LIKE: improved version for larger texts (currently using naive search). - -@roadmap_1095_li -#Automatically convert to the next 'higher' data type whenever there is an overflow. - -@roadmap_1096_li -#Throw an exception when the application calls getInt on a Long (optional). - -@roadmap_1097_li -#Default date format for input and output (local date constants). - -@roadmap_1098_li -#Support custom Collators. - -@roadmap_1099_li -#Document ROWNUM usage for reports: SELECT ROWNUM, * FROM (subquery). - -@roadmap_1100_li -#File system that writes to two file systems (replication, replicating file system). - -@roadmap_1101_li -#Standalone tool to get relevant system properties and add it to the trace output. - -@roadmap_1102_li -#Support 'call proc(1=value)' (PostgreSQL, Oracle). - -@roadmap_1103_li -#Console: improve editing data (Tab, Shift-Tab, Enter, Up, Down, Shift+Del?). - -@roadmap_1104_li -#Console: autocomplete Ctrl+Space inserts template. - -@roadmap_1105_li -#Option to encrypt .trace.db file. - -@roadmap_1106_li -#Write Behind Cache on SATA leads to data corruption See also http://sr5tech.com/write_back_cache_experiments.htm and http://www.jasonbrome.com/blog/archives/2004/04/03/writecache_enabled.html - -@roadmap_1107_li -#Functions with unknown return or parameter data types: serialize / deserialize. - -@roadmap_1108_li -#Auto-Update feature for database, .jar file. - -@roadmap_1109_li -#ResultSet SimpleResultSet.readFromURL(String url): id varchar, state varchar, released timestamp. - -@roadmap_1110_li -#Partial indexing (see PostgreSQL). - -@roadmap_1111_li -#Add GUI to build a custom version (embedded, fulltext,...) using build flags. - -@roadmap_1112_li -#http://rubyforge.org/projects/hypersonic/ - -@roadmap_1113_li -#Add comparator (x === y) : (x = y or (x is null and y is null)). - -@roadmap_1114_li -#Add a sample application that runs the H2 unit test and writes the result to a file (so it can be included in the user app). - -@roadmap_1115_li -#Count on a column that can not be null could be optimized to COUNT(*). - -@roadmap_1116_li -#Table order: ALTER TABLE TEST ORDER BY NAME DESC (MySQL compatibility). - -@roadmap_1117_li -#Issue 159: System property for the H2 Console and TCP configuration (which .h2.server.properties and .h2.keystore to use). - -@roadmap_1118_li -#Backup tool should work with other databases as well. - -@roadmap_1119_li -#Console: -ifExists doesn't work for the console. Add a flag to disable other dbs. - -@roadmap_1120_li -#Check if 'FSUTIL behavior set disablelastaccess 1' improves the performance (fsutil behavior query disablelastaccess). - -@roadmap_1121_li -#Java static code analysis: http://pmd.sourceforge.net/ - -@roadmap_1122_li -#Java static code analysis: http://www.eclipse.org/tptp/ - -@roadmap_1123_li -#Compatibility for CREATE SCHEMA AUTHORIZATION. - -@roadmap_1124_li -#Implement Clob / Blob truncate and the remaining functionality. - -@roadmap_1125_li -#Tree join functionality. - -@roadmap_1126_li -#Add multiple columns at the same time with ALTER TABLE .. ADD .. ADD ... - -@roadmap_1127_li -#Use JDK 1.4 file locking for the database file and for the lock file (but not yet by default); writing a system property to detect concurrent access from the same VM (different classloaders). - -@roadmap_1128_li -#Pure SQL triggers (example: update parent table if the child table is changed). - -@roadmap_1129_li -#Add H2 to Gem (Ruby install system). - -@roadmap_1130_li -#Order conditions inside AND / OR to optimize the performance. - -@roadmap_1131_li -#Support Oracle functions: TRUNC, NVL2, TO_CHAR, TO_DATE, TO_NUMBER. - -@roadmap_1132_li -#Support linked JCR tables - -@roadmap_1133_li -#Read InputStream when executing, as late as possible (maybe only embedded mode). Problem with re-execute. - -@roadmap_1134_li -#Native fulltext search: min word length; store word positions - -@roadmap_1135_li -#Add an option to the SCRIPT command to generate only portable / standard SQL - -@roadmap_1136_li -#Updatable Views (simple cases first) - -@roadmap_1137_li -#Improve create index performance - -@roadmap_1138_li -#Implement more JDBC 4.0 features - -@roadmap_1139_li -#Support TRANSFORM / PIVOT as in MS Access - -@roadmap_1140_li -#SELECT * FROM (VALUES (...), (...), ....) AS alias(f1, ...) - -@roadmap_1141_li -#Support updatable views with join on primary keys (to extend a table) - -@roadmap_1142_li -#Public interface for functions (not public static) - -@roadmap_1143_li -#Support reading the transaction log. - -@roadmap_1144_li -#Eliminate undo log records if stored on disk (just one pointer per block, not per record) - -@roadmap_1145_li -#Feature matrix as in i-net software. - -@roadmap_1146_li -#Updatable result set on table without primary key or unique index. - -@roadmap_1147_li -#Use LinkedList instead of ArrayList where applicable. - -@roadmap_1148_li -#Allow execution time prepare for SELECT * FROM CSVREAD(?, 'columnNameString') - -@roadmap_1149_li -#Support % operator (modulo). - -@roadmap_1150_li -#Support JMX: create an MBean for each database and server (support JConsole). See http://thedevcloud.blogspot.com/2008/10/displaying-hsql-database-manager-in.html http://java.sun.com/j2se/1.5.0/docs/api/java/lang/management/ManagementFactory.html#getPlatformMBeanServer() http://java.sun.com/j2se/1.5.0/docs/guide/management/agent.html - -@roadmap_1151_li -#Support nested transactions. - -@roadmap_1152_li -#Add a benchmark for big databases, and one for many users. - -@roadmap_1153_li -#Compression in the result set (repeating values in the same column) over TCP/IP. - -@roadmap_1154_li -#Support curtimestamp (like curtime, curdate). - -@roadmap_1155_li -#Support ANALYZE {TABLE|INDEX} tableName COMPUTE|ESTIMATE|DELETE STATISTICS ptnOption options. - -@roadmap_1156_li -#Release locks (shared or exclusive) on demand - -@roadmap_1157_li -#Support OUTER UNION - -@roadmap_1158_li -#Support parameterized views (similar to CSVREAD, but using just SQL for the definition) - -@roadmap_1159_li -#A way (JDBC driver) to map an URL (jdbc:h2map:c1) to a connection object - -@roadmap_1160_li -#Option for SCRIPT to only process one or a set of tables, and append to a file - -@roadmap_1161_li -#Support linked tables to the current database - -@roadmap_1162_li -#Support dynamic linked schema (automatically adding/updating/removing tables) - -@roadmap_1163_li -#Clustering: adding a node should be very fast and without interrupting clients (very short lock) - -@roadmap_1164_li -#Compatibility with Derby: VALUES(1), (2); SELECT * FROM (VALUES (1), (2)) AS myTable(c1) - -@roadmap_1165_li -#Compatibility: # is the start of a single line comment (MySQL) but date quote (Access). Mode specific - -@roadmap_1166_li -#Run benchmarks with JDK 1.5, JDK 1.6, java -server - -@roadmap_1167_li -#Optimizations: faster hash function for strings, byte arrays - -@roadmap_1168_li -#DatabaseEventListener: callback for all operations (including expected time, RUNSCRIPT) and cancel functionality - -@roadmap_1169_li -#Benchmark: add a graph to show how databases scale (performance/database size) - -@roadmap_1170_li -#Implement a SQLData interface to map your data over to a custom object - -@roadmap_1171_li -#In the MySQL and PostgreSQL mode, use lower case identifiers by default (DatabaseMetaData.storesLowerCaseIdentifiers = true) - -@roadmap_1172_li -#Support multiple directories (on different hard drives) for the same database - -@roadmap_1173_li -#Server protocol: use challenge response authentication, but client sends hash(user+password) encrypted with response - -@roadmap_1174_li -#Support EXEC[UTE] (doesn't return a result set, compatible to MS SQL Server) - -@roadmap_1175_li -#Support native XML data type - -@roadmap_1176_li -#Support triggers with a string property or option: SpringTrigger, OSGITrigger - -@roadmap_1177_li -#Ability to resize the cache array when resizing the cache - -@roadmap_1178_li -#Time based cache writing (one second after writing the log) - -@roadmap_1179_li -#Check state of H2 driver for DDLUtils: https://issues.apache.org/jira/browse/DDLUTILS-185 - -@roadmap_1180_li -#Index usage for REGEXP LIKE. - -@roadmap_1181_li -#Compatibility: add a role DBA (like ADMIN). - -@roadmap_1182_li -#Better support multiple processors for in-memory databases. - -@roadmap_1183_li -#Support N'text' - -@roadmap_1184_li -#Support compatibility for jdbc:hsqldb:res: - -@roadmap_1185_li -#Provide an Java SQL builder with standard and H2 syntax - -@roadmap_1186_li -#Trace: write OS, file system, JVM,... when opening the database - -@roadmap_1187_li -#Support indexes for views (probably requires materialized views) - -@roadmap_1188_li -#Document SET SEARCH_PATH, BEGIN, EXECUTE, parameters - -@roadmap_1189_li -#Browser: use Desktop.isDesktopSupported and browse when using JDK 1.6 - -@roadmap_1190_li -#Server: use one listener (detect if the request comes from an PG or TCP client) - -@roadmap_1191_li -#Support data type INTERVAL - -@roadmap_1192_li -#Optimize SELECT MIN(ID), MAX(ID), COUNT(*) FROM TEST WHERE ID BETWEEN 100 AND 200 - -@roadmap_1193_li -#Sequence: PostgreSQL compatibility (rename, create) http://www.postgresql.org/docs/8.2/static/sql-altersequence.html - -@roadmap_1194_li -#DISTINCT: support large result sets by sorting on all columns (additionally) and then removing duplicates. - -@roadmap_1195_li -#Support a special trigger on all tables to allow building a transaction log reader. - -@roadmap_1196_li -#File system with a background writer thread; test if this is faster - -@roadmap_1197_li -#Better document the source code - -@roadmap_1198_li -#Support select * from dual a left join dual b on b.x=(select max(x) from dual) - -@roadmap_1199_li -#Optimization: don't lock when the database is read-only - -@roadmap_1200_li -#Issue 146: Support merge join. - -@roadmap_1201_li -#Integrate spatial functions from http://geosysin.iict.ch/irstv-trac/wiki/H2spatial/Download - -@roadmap_1202_li -#Cluster: hot deploy (adding a node at runtime) - -@roadmap_1203_li -#Compact databases without having to close the database (vacuum). - -@roadmap_1204_li -#Support COSH, SINH, and TANH functions - -@roadmap_1205_li -#Oracle: support DECODE method (convert to CASE WHEN). - -@roadmap_1206_li -#Native search: support "phrase search", wildcard search (* and ?), case-insensitive search, boolean operators, and grouping - -@roadmap_1207_li -#Improve documentation of access rights - -@roadmap_1208_li -#Support ENUM data type (see MySQL, PostgreSQL, MS SQL Server, maybe others) - -@roadmap_1209_li -#Remember the user defined data type (domain) of a column - -@roadmap_1210_li -#Support Jackcess (MS Access databases) - -@roadmap_1211_li -#Built-in methods to write large objects (BLOB and CLOB): FILE_WRITE('test.txt', 'Hello World') - -@roadmap_1212_li -#MVCC: support transactionally consistent backups using SCRIPT - -@roadmap_1213_li -#Improve time to open large databases (see mail 'init time for distributed setup') - -@roadmap_1214_li -#Move Maven 2 repository from hsql.sf.net to h2database.sf.net - -@roadmap_1215_li -#Java 1.5 tool: JdbcUtils.closeSilently(s1, s2,...) - -@roadmap_1216_li -#Javadoc: document design patterns used - -@roadmap_1217_li -#Write an article about SQLInjection (h2/src/docsrc/html/images/SQLInjection.txt) - -@roadmap_1218_li -#Convert SQL-injection-2.txt to html document, include SQLInjection.java sample - -@roadmap_1219_li -#Support OUT parameters in user-defined procedures. - -@roadmap_1220_li -#Web site design: http://www.igniterealtime.org/projects/openfire/index.jsp - -@roadmap_1221_li -#HSQLDB compatibility: Openfire server uses: CREATE SCHEMA PUBLIC AUTHORIZATION DBA; CREATE USER SA PASSWORD ""; GRANT DBA TO SA; SET SCHEMA PUBLIC - -@roadmap_1222_li -#Translation: use ?? in help.csv - -@roadmap_1223_li -#Translated .pdf - -@roadmap_1224_li -#MySQL compatibility: update test1 t1, test2 t2 set t1.id = t2.id where t1.id = t2.id; - -@roadmap_1225_li -#Recovery tool: bad blocks should be converted to INSERT INTO SYSTEM_ERRORS(...), and things should go into the .trace.db file - -@roadmap_1226_li -#RECOVER=2 to backup the database, run recovery, open the database - -@roadmap_1227_li -#Recovery should work with encrypted databases - -@roadmap_1228_li -#Corruption: new error code, add help - -@roadmap_1229_li -#Space reuse: after init, scan all storages and free those that don't belong to a live database object - -@roadmap_1230_li -#Use FilterIn / FilterOut putStream? - -@roadmap_1231_li -#Access rights: add missing features (users should be 'owner' of objects; missing rights for sequences; dropping objects) - -@roadmap_1232_li -#Support NOCACHE table option (Oracle). - -@roadmap_1233_li -#Support table partitioning. - -@roadmap_1234_li -#Index usage for UPDATE ... WHERE .. IN (SELECT...) - -@roadmap_1235_li -#Add regular javadocs (using the default doclet, but another css) to the homepage. - -@roadmap_1236_li -#The database should be kept open for a longer time when using the server mode. - -@roadmap_1237_li -#Javadocs: for each tool, add a copy & paste sample in the class level. - -@roadmap_1238_li -#Javadocs: add @author tags. - -@roadmap_1239_li -#Fluent API for tools: Server.createTcpServer().setPort(9081).setPassword(password).start(); - -@roadmap_1240_li -#MySQL compatibility: real SQL statement for DESCRIBE TEST - -@roadmap_1241_li -#Use a default delay of 1 second before closing a database. - -@roadmap_1242_li -#Write (log) to system table before adding to internal data structures. - -@roadmap_1243_li -#Support very large deletes and updates. - -@roadmap_1244_li -#Doclet (javadocs): constructors are not listed. - -@roadmap_1245_li -#Support direct lookup for MIN and MAX when using WHERE (see todo.txt / Direct Lookup). - -@roadmap_1246_li -#Support other array types (String[], double[]) in PreparedStatement.setObject(int, Object); - -@roadmap_1247_li -#MVCC should not be memory bound (uncommitted data is kept in memory in the delta index; maybe using a regular b-tree index solves the problem). - -@roadmap_1248_li -#Oracle compatibility: support NLS_DATE_FORMAT. - -@roadmap_1249_li -#Cluster: add feature to make sure cluster nodes can not get out of sync (for example by stopping one process). - -@roadmap_1250_li -#H2 Console: support CLOB/BLOB download using a link. - -@roadmap_1251_li -#Support flashback queries as in Oracle. - -@roadmap_1252_li -#Import / Export of fixed with text files. - -@roadmap_1253_li -#Support getGeneratedKeys to return multiple rows when used with batch updates. This is supported by MySQL, but not Derby. Both PostgreSQL and HSQLDB don't support getGeneratedKeys. Also support it when using INSERT ... SELECT. - -@roadmap_1254_li -#HSQLDB compatibility: automatic data type for SUM if value is the value is too big (by default use the same type as the data). - -@roadmap_1255_li -#Improve the optimizer to select the right index for special cases: where id between 2 and 4 and booleanColumn - -@roadmap_1256_li -#Linked tables: make hidden columns available (Oracle: rowid and ora_rowscn columns). - -@roadmap_1257_li -#H2 Console: in-place autocomplete. - -@roadmap_1258_li -#Support large databases: split database files to multiple directories / disks (similar to tablespaces). - -@roadmap_1259_li -#Support to assign a primary key index a user defined name. - -@roadmap_1260_li -#H2 Console: support configuration option for fixed width (monospace) font. - -@roadmap_1261_li -#Native fulltext search: support analyzers (specially for Chinese, Japanese). - -@roadmap_1262_li -#Automatically compact databases from time to time (as a background process). - -@roadmap_1263_li -#Support GRANT SELECT, UPDATE ON *. - -@roadmap_1264_li -#Test Eclipse DTP. - -@roadmap_1265_li -#H2 Console: autocomplete: keep the previous setting - -@roadmap_1266_li -#MySQL, MS SQL Server compatibility: support case sensitive (mixed case) identifiers without quotes. - -@roadmap_1267_li -#executeBatch: option to stop at the first failed statement. - -@roadmap_1268_li -#Implement OLAP features as described here: http://www.devx.com/getHelpOn/10MinuteSolution/16573/0/page/5 - -@roadmap_1269_li -#Support Oracle ROWID (unique identifier for each row). - -@roadmap_1270_li -#Server mode: improve performance for batch updates. - -@roadmap_1271_li -#Applets: support read-only databases in a zip file (accessed as a resource). - -@roadmap_1272_li -#Long running queries / errors / trace system table. - -@roadmap_1273_li -#H2 Console should support JaQu directly. - -@roadmap_1274_li -#H2 Console: support single file upload and directory download (optional). - -@roadmap_1275_li -#Document FTL_SEARCH, FTL_SEARCH_DATA. - -@roadmap_1276_li -#Sequences: CURRVAL should be session specific. Compatibility with PostgreSQL. - -@roadmap_1277_li -#Support DatabaseMetaData.insertsAreDetected: updatable result sets should detect inserts. - -@roadmap_1278_li -#Auto-server: add option to define the IP address range or list. - -@roadmap_1279_li -#Index creation using deterministic functions. - -@roadmap_1280_li -#Support DELETE with TOP or LIMIT. See also: http://dev.mysql.com/doc/refman/5.1/de/delete.html - -@roadmap_1281_li -#ANALYZE: for unique indexes that allow null, count the number of null. - -@roadmap_1282_li -#AUTO_SERVER: support changing IP addresses (disable a network while the database is open). - -@roadmap_1283_li -#Avoid using java.util.Calendar internally because it's slow, complicated, and buggy. - -@roadmap_1284_li -#Support TRUNCATE .. CASCADE like PostgreSQL. - -@roadmap_1285_li -#Support opening a database that is in the classpath, maybe using a new file system. - -@roadmap_1286_li -#Fulltext search: lazy result generation using SimpleRowSource. - -@roadmap_1287_li -#Support transformation to join for user defined functions, as for IN(SELECT...). - -@roadmap_1288_li -#Fulltext search: support alternative syntax: WHERE FTL_CONTAINS(name, 'hello'). - -@roadmap_1289_li -#MySQL compatibility: support REPLACE, see http://dev.mysql.com/doc/refman/5.1/de/replace.html - -@roadmap_1290_li -#MySQL compatibility: support INSERT INTO table SET column1 = value1, column2 = value2 - -@roadmap_1291_li -#Docs: add a one line description for each functions and SQL statements at the top (in the link section). - -@roadmap_1292_li -#Javadoc search: weight for titles should be higher ('random' should list Functions as the best match). - -@roadmap_1293_li -#Replace information_schema tables with regular tables that are automatically re-built when needed. Use indexes. - -@roadmap_1294_li -#Delete temporary files or objects using finalize. - -@roadmap_1295_li -#Oracle compatibility: support calling 0-parameters functions without parenthesis. Make constants obsolete. - -@roadmap_1296_li -#MySQL, HSQLDB compatibility: support where 'a'=1 (not supported by Derby, PostgreSQL) - -@roadmap_1297_li -#Allow calling function with no parameters without parenthesis. See http://code.google.com/p/h2database/issues/detail?id=50 - -@roadmap_1298_li -#CSV: currently # is a line comment and can start at any field. Make it optional. - -@roadmap_1299_li -#Finer granularity for SLF4J trace - See http://code.google.com/p/h2database/issues/detail?id=62 - -@roadmap_1300_li -#Add database creation date and time to the database. - -@roadmap_1301_li -#Support ASSERTIONS. - -@roadmap_1302_li -#Support multi-threaded kernel with multi-version concurrency. - -@roadmap_1303_li -#MySQL compatibility: support comparing 1='a' - -@roadmap_1304_li -#Support PostgreSQL lock modes: http://www.postgresql.org/docs/8.3/static/explicit-locking.html - -@roadmap_1305_li -#PostgreSQL compatibility: test DbVisualizer and Squirrel SQL using a new PostgreSQL JDBC driver. - -@roadmap_1306_li -#RunScript should be able to read from system in (or quite mode for Shell). - -@roadmap_1307_li -#Natural join: support select x from dual natural join dual. - -@roadmap_1308_li -#Natural join: somehow support this: select a.x, b.x, x from dual a natural join dual b - -@roadmap_1309_li -#Use the Java service provider mechanism to register file systems and function libraries. - -@roadmap_1310_li -#MySQL compatibility: for auto_increment columns, convert 0 to next value (as when inserting NULL). - -@roadmap_1311_li -#Optimization for multi-column IN: use an index if possible. Example: (A, B) IN((1, 2), (2, 3)). - -@roadmap_1312_li -#Optimization for EXISTS: convert to inner join or IN(..) if possible. - -@roadmap_1313_li -#Functions: support hashcode(value); cryptographic and fast - -@roadmap_1314_li -#Serialized file lock: support long running queries. - -@roadmap_1315_li -#Network: use 127.0.0.1 if other addresses don't work. - -@roadmap_1316_li -#Pluggable network protocol (currently Socket/ServerSocket over TCP/IP) - see also TransportServer with master slave replication. - -@roadmap_1317_li -#Select for update in mvcc mode: only lock the selected records. - -@roadmap_1318_li -#Support reading JCR data: one table per node type; query table; cache option - -@roadmap_1319_li -#OSGi: create a sample application, test, document. - -@roadmap_1320_li -#help.csv: use complete examples for functions; run as test case. - -@roadmap_1321_li -#Functions to calculate the memory and disk space usage of a table, a row, or a value. - -@roadmap_1322_li -#Re-implement PooledConnection; use a lightweight connection object. - -@roadmap_1323_li -#Doclet: convert tests in javadocs to a java class. - -@roadmap_1324_li -#Doclet: format fields like methods, but support sorting by name and value. - -@roadmap_1325_li -#Doclet: shrink the html files. - -@roadmap_1326_li -#MySQL compatibility: support REPLACE - See http://code.google.com/p/h2database/issues/detail?id=73 - -@roadmap_1327_li -#MySQL compatibility: support SET NAMES 'latin1' - See also http://code.google.com/p/h2database/issues/detail?id=56 - -@roadmap_1328_li -#MySQL compatibility: DELETE .. FROM .. USING - See http://dev.mysql.com/doc/refman/5.0/en/delete.html - -@roadmap_1329_li -#Allow to scan index backwards starting with a value (to better support ORDER BY DESC). - -@roadmap_1330_li -#Java Service Wrapper: try http://yajsw.sourceforge.net/ - -@roadmap_1331_li -#Batch parameter for INSERT, UPDATE, and DELETE, and commit after each batch. See also MySQL DELETE. - -@roadmap_1332_li -#MySQL compatibility: support ALTER TABLE .. MODIFY COLUMN. - -@roadmap_1333_li -#Use a lazy and auto-close input stream (open resource when reading, close on eof). - -@roadmap_1334_li -#PostgreSQL compatibility: generate_series. - -@roadmap_1335_li -#Connection pool: 'reset session' command (delete temp tables, rollback, autocommit true). - -@roadmap_1336_li -#Improve SQL documentation, see http://www.w3schools.com/sql/ - -@roadmap_1337_li -#MySQL compatibility: DatabaseMetaData.stores*() methods should return the same values. Test with SquirrelSQL. - -@roadmap_1338_li -#MS SQL Server compatibility: support DATEPART syntax. - -@roadmap_1339_li -#Oracle compatibility: support CREATE OR REPLACE VIEW syntax. - -@roadmap_1340_li -#Sybase/DB2/Oracle compatibility: support out parameters in stored procedures - See http://code.google.com/p/h2database/issues/detail?id=83 - -@roadmap_1341_li -#Support INTERVAL data type (see Oracle and others). - -@roadmap_1342_li -#Combine Server and Console tool (only keep Server). - -@roadmap_1343_li -#Store the Lucene index in the database itself. - -@roadmap_1344_li -#Support standard MERGE statement: http://en.wikipedia.org/wiki/Merge_%28SQL%29 - -@roadmap_1345_li -#Oracle compatibility: support DECODE(x, ...). - -@roadmap_1346_li -#Console: Start Browser: if ip number changed, try localhost instead. - -@roadmap_1347_li -#MVCC: compare concurrent update behavior with PostgreSQL and Oracle. - -@roadmap_1348_li -#HSQLDB compatibility: CREATE FUNCTION (maybe using a Function interface). - -@roadmap_1349_li -#HSQLDB compatibility: support CALL "java.lang.Math.sqrt"(2.0) - -@roadmap_1350_li -#Support comma as the decimal separator in the CSV tool. - -@roadmap_1351_li -#Compatibility: Support jdbc:default:connection using ThreadLocal (part of SQLJ) - -@roadmap_1352_li -#Compatibility: Java functions with SQLJ Part1 http://www.acm.org/sigmod/record/issues/9912/standards.pdf.gz - -@roadmap_1353_li -#Compatibility: Java functions with SQL/PSM (Persistent Stored Modules) - need to find the documentation. - -@roadmap_1354_li -#CACHE_SIZE: automatically use a fraction of Runtime.maxMemory - maybe automatically the second level cache. - -@roadmap_1355_li -#Support date/time/timestamp as documented in http://en.wikipedia.org/wiki/ISO_8601 - -@roadmap_1356_li -#PostgreSQL compatibility: when in PG mode, treat BYTEA data like PG. - -@roadmap_1357_li -#MySQL compatibility: REPLACE http://dev.mysql.com/doc/refman/6.0/en/replace.html - -@roadmap_1358_li -#Support =ANY(array) as in PostgreSQL. See also http://www.postgresql.org/docs/8.0/interactive/arrays.html - -@roadmap_1359_li -#IBM DB2 compatibility: support PREVIOUS VALUE FOR sequence. - -@roadmap_1360_li -#MySQL compatibility: alter table add index i(c), add constraint c foreign key(c) references t(c); - -@roadmap_1361_li -#Compatibility: use different LIKE ESCAPE characters depending on the mode (disable for Derby, HSQLDB, DB2, Oracle, MSSQLServer). - -@roadmap_1362_li -#Oracle compatibility: support CREATE SYNONYM table FOR schema.table. - -@roadmap_1363_li -#Optimize A=? OR B=? to UNION if the cost is lower. - -@roadmap_1364_li -#FTP: document the server, including -ftpTask option to execute / kill remote processes - -@roadmap_1365_li -#FTP: problems with multithreading? - -@roadmap_1366_li -#FTP: implement SFTP / FTPS - -@roadmap_1367_li -#FTP: access to a database (.csv for a table, a directory for a schema, a file for a lob, a script.sql file). - -@roadmap_1368_li -#More secure default configuration if remote access is enabled. - -@roadmap_1369_li -#Improve database file locking (maybe use native file locking). The current approach seems to be problematic if the file system is on a remote share (see Google Group 'Lock file modification time is in the future'). - -@roadmap_1370_li -#Document internal features such as BELONGS_TO_TABLE, NULL_TO_DEFAULT, SEQUENCE. - -@roadmap_1371_li -#Issue 107: Prefer using the ORDER BY index if LIMIT is used. - -@roadmap_1372_li -#An index on (id, name) should be used for a query: select * from t where s=? order by i - -@roadmap_1373_li -#Support reading sequences using DatabaseMetaData.getTables(null, null, null, new String[]{"SEQUENCE"}). See PostgreSQL. - -@roadmap_1374_li -#Add option to enable TCP_NODELAY using Socket.setTcpNoDelay(true). - -@roadmap_1375_li -#Maybe disallow = within database names (jdbc:h2:mem:MODE=DB2 means database name MODE=DB2). - -@roadmap_1376_li -#Fast alter table add column. - -@roadmap_1377_li -#Improve concurrency for in-memory database operations. - -@roadmap_1378_li -#Issue 122: Support for connection aliases for remote tcp connections. - -@roadmap_1379_li -#Fast scrambling (strong encryption doesn't help if the password is included in the application). - -@roadmap_1380_li -#Support using system properties in database URLs (may be a security problem). - -@roadmap_1381_li -#Issue 126: The index name should be "IDX_" plus the constraint name unless there is a conflict, in which case append a number. - -@roadmap_1382_li -#Issue 127: Support activation/deactivation of triggers - -@roadmap_1383_li -#Issue 130: Custom log event listeners - -@roadmap_1384_li -#Issue 131: IBM DB2 compatibility: sysibm.sysdummy1 - -@roadmap_1385_li -#Issue 132: Use Java enum trigger type. - -@roadmap_1386_li -#Issue 134: IBM DB2 compatibility: session global variables. - -@roadmap_1387_li -#Cluster: support load balance with values for each server / auto detect. - -@roadmap_1388_li -#FTL_SET_OPTION(keyString, valueString) with key stopWords at first. - -@roadmap_1389_li -#Pluggable access control mechanism. - -@roadmap_1390_li -#Fulltext search (Lucene): support streaming CLOB data. - -@roadmap_1391_li -#Document/example how to create and read an encrypted script file. - -@roadmap_1392_li -#Check state of https://issues.apache.org/jira/browse/OPENJPA-1367 (H2 does support cross joins). - -@roadmap_1393_li -#Fulltext search (Lucene): only prefix column names with _ if they already start with _. Instead of DATA / QUERY / modified use _DATA, _QUERY, _MODIFIED if possible. - -@roadmap_1394_li -#Support a way to create or read compressed encrypted script files using an API. - -@roadmap_1395_li -#Scripting language support (Javascript). - -@roadmap_1396_li -#The network client should better detect if the server is not an H2 server and fail early. - -@roadmap_1397_li -#H2 Console: support CLOB/BLOB upload. - -@roadmap_1398_li -#Move away from system properties where possible. - -@roadmap_1399_li -#Database file lock: detect hibernate / standby / very slow threads (compare system time). - -@roadmap_1400_li -#Automatic detection of redundant indexes. - -@roadmap_1401_li -#Maybe reject join without "on" (except natural join). - -@roadmap_1402_li -#Implement GiST (Generalized Search Tree for Secondary Storage). - -@roadmap_1403_li -#Function to read a number of bytes/characters from an BLOB or CLOB. - -@roadmap_1404_li -#Issue 156: Support SELECT ? UNION SELECT ?. - -@roadmap_1405_li -#Automatic mixed mode: support a port range list (to avoid firewall problems). - -@roadmap_1406_li -#Support the pseudo column rowid, oid, _rowid_. - -@roadmap_1407_li -#H2 Console / large result sets: stream early instead of keeping a whole result in-memory - -@roadmap_1408_li -#Support TRUNCATE for linked tables. - -@roadmap_1409_li -#UNION: evaluate INTERSECT before UNION (like most other database except Oracle). - -@roadmap_1410_li -#Delay creating the information schema, and share metadata columns. - -@roadmap_1411_li -#TCP Server: use a nonce (number used once) to protect unencrypted channels against replay attacks. - -@roadmap_1412_li -#Simplify running scripts and recovery: CREATE FORCE USER (overwrites an existing user). - -@roadmap_1413_li -#Support CREATE DATABASE LINK (a custom JDBC driver is already supported). - -@roadmap_1414_li -#Issue 163: Allow to create foreign keys on metadata types. - -@roadmap_1415_li -#Logback: write a native DBAppender. - -@roadmap_1416_li -#Cache size: don't use more cache than what is available. - -@roadmap_1417_li -#Tree index: Instead of an AVL tree, use a general balanced trees or a scapegoat tree. - -@roadmap_1418_li -#User defined functions: allow to store the bytecode (of just the class, or the jar file of the extension) in the database. - -@roadmap_1419_li -#Compatibility: ResultSet.getObject() on a CLOB (TEXT) should return String for PostgreSQL and MySQL. - -@roadmap_1420_li -#Optimizer: WHERE X=? AND Y IN(?), it always uses the index on Y. Should be cost based. - -@roadmap_1421_li -#Support ALTER SCHEMA name RENAME TO newName (rename schema). - -@roadmap_1422_li -#Make the cache scan resistant (currently a small cache is faster than a large cache for large table scans). - -@roadmap_1423_li -#Issue 178: Optimizer: index usage when both ascending and descending indexes are available - -@roadmap_1424_li -#Issue 179: Related subqueries in HAVING clause - -@roadmap_1425_li -#IBM DB2 compatibility: NOT NULL WITH DEFAULT. Similar to MySQL Mode.convertInsertNullToZero. - -@roadmap_1426_li -#Creating primary key: always create a constraint. - -@roadmap_1427_li -#Support a data type "timestamp with timezone" using java.util.Calendar. - -@roadmap_1428_li -#Maybe use a different page layout: keep the data at the head of the page, and ignore the tail (don't store / read it). This may increase write / read performance depending on the file system. - -@roadmap_1429_li -#Indexes of temporary tables are currently kept in-memory. Is this how it should be? - -@roadmap_1430_li -#The Shell tool should support the same built-in commands as the H2 Console. - -@roadmap_1431_li -#Maybe use PhantomReference instead of finalize. - -@roadmap_1432_li -#Database file name suffix: a way to use no or a different suffix (for example using a slash). - -@roadmap_1433_li -#Database file name suffix: should only have one dot by default. Example: .h2db - -@roadmap_1434_li -#Issue 196: Function based indexes - -@roadmap_1435_li -#Fix the disk space leak (killing the process at the exact right moment will increase the disk space usage; this space is not re-used). See TestDiskSpaceLeak.java - -@roadmap_1436_li -#ROWNUM: Oracle compatibility when used within a subquery. Issue 198. - -@roadmap_1437_li -#Allow to access the database over HTTP (possibly using port 80) and a servlet in a REST way. - -@roadmap_1438_li -#ODBC: encrypted databases are not supported because the ;CIPHER= can not be set. - -@roadmap_1439_li -#Support CLOB and BLOB update, specially conn.createBlob().setBinaryStream(1); - -@roadmap_1440_li -#Triggers: support user defined execution order. Oracle: CREATE OR REPLACE TRIGGER TEST_2 BEFORE INSERT ON TEST FOR EACH ROW FOLLOWS TEST_1. SQL specifies that multiple triggers should be fired in time-of-creation order. PostgreSQL uses name order, which was judged to be more convenient. Derby: triggers are fired in the order in which they were created. - -@roadmap_1441_li -#PostgreSQL compatibility: combine "users" and "roles". See: http://www.postgresql.org/docs/8.1/interactive/user-manag.html - -@roadmap_1442_li -#Support NULL with a type: @meta CALL CAST(NULL AS INT) should return INT. See the ValueExpression.java (currently it returns the type of the value; it could have it's own type/precision/scale optionally, for example when created from CAST, which is implemented in Function.java). - -@roadmap_1443_li -#Improve documentation of system properties: only list the property names, default values, and description. - -@roadmap_1444_li -#Support running totals / cumulative sum using SUM(..) OVER(..). - -@roadmap_1445_li -#Improve object memory size calculation. Use constants for known VMs, or use reflection to call java.lang.instrument.Instrumentation.getObjectSize(Object objectToSize) - -@roadmap_1446_h2 -#Not Planned - -@roadmap_1447_li -#HSQLDB (did) support this: select id i from test where i<0 (other databases don't). Supporting it may break compatibility. - -@roadmap_1448_li -#String.intern (so that Strings can be compared with ==) will not be used because some VMs have problems when used extensively. - -@roadmap_1449_li -#In prepared statements, identifier names (table names and so on) can not be parameterized. Adding such a feature would complicate the source code without providing reasonable speedup, and would slow down regular prepared statements. - -@sourceError_1000_h1 -#Error Analyzer - -@sourceError_1001_a -ホーム - -@sourceError_1002_a -#Input - -@sourceError_1003_h2 -#  Details  Source Code - -@sourceError_1004_p -#Paste the error message and stack trace below and click on 'Details' or 'Source Code': - -@sourceError_1005_b -#Error Code: - -@sourceError_1006_b -#Product Version: - -@sourceError_1007_b -#Message: - -@sourceError_1008_b -#More Information: - -@sourceError_1009_b -#Stack Trace: - -@sourceError_1010_b -#Source File: - -@sourceError_1011_p -# Raw file - -@sourceError_1012_p -# (fast; only Firefox) - -@tutorial_1000_h1 -チュートリアル - -@tutorial_1001_a -# Starting and Using the H2 Console - -@tutorial_1002_a -# Special H2 Console Syntax - -@tutorial_1003_a -# Settings of the H2 Console - -@tutorial_1004_a -# Connecting to a Database using JDBC - -@tutorial_1005_a -# Creating New Databases - -@tutorial_1006_a -# Using the Server - -@tutorial_1007_a -# Using Hibernate - -@tutorial_1008_a -# Using TopLink and Glassfish - -@tutorial_1009_a -# Using EclipseLink - -@tutorial_1010_a -# Using Databases in Web Applications - -@tutorial_1011_a -# CSV (Comma Separated Values) Support - -@tutorial_1012_a -# Upgrade, Backup, and Restore - -@tutorial_1013_a -# Command Line Tools - -@tutorial_1014_a -# The Shell Tool - -@tutorial_1015_a -# Using OpenOffice Base - -@tutorial_1016_a -# Java Web Start / JNLP - -@tutorial_1017_a -# Using a Connection Pool - -@tutorial_1018_a -# Fulltext Search - -@tutorial_1019_a -# User-Defined Variables - -@tutorial_1020_a -# Date and Time - -@tutorial_1021_a -# Using Spring - -@tutorial_1022_h2 -起動とH2コンソールの使用 - -@tutorial_1023_p -# The H2 Console 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. - -@tutorial_1024_p -# This is a client / server application, so both a server and a client (a browser) are required to run it. - -@tutorial_1025_p -# Depending on your platform and environment, there are multiple ways to start the application: - -@tutorial_1026_th -OS - -@tutorial_1027_th -起動 - -@tutorial_1028_td -Windows - -@tutorial_1029_td -# Click [Start], [All Programs], [H2], and [H2 Console (Command Line)] - -@tutorial_1030_td -# When using the Sun JDK 1.5, a window with the title 'H2 Console ' should appear. When using the Sun JDK 1.6, an icon will be added to the system tray: - -@tutorial_1031_td -# If you don't get the window and 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 at http://localhost:8082. - -@tutorial_1032_td -Windows - -@tutorial_1033_td -# Open a file browser, navigate to h2/bin, and double click on h2.bat. - -@tutorial_1034_td -# A console window appears. If there is a problem, you will see an error message in this window. A browser window will open and point to the Login page (URL: http://localhost:8082). - -@tutorial_1035_td -Any - -@tutorial_1036_td -# Double click on the h2*.jar file. This only works if the .jar suffix is associated with java. - -@tutorial_1037_td -Any - -@tutorial_1038_td -# Open a console window, navigate to the directory h2/bin and type: - -@tutorial_1039_h3 -ファイアウォール - -@tutorial_1040_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 application 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. - -@tutorial_1041_p -# It has been reported that when using Kaspersky 7.0 with firewall, the H2 Console is very slow when connecting over the IP address. A workaround is to connect using localhost, however this only works on the local machine. - -@tutorial_1042_p -# A small firewall is already built into the server: other computers may not connect to the server by default. To change this, go to 'Preferences' and select 'Allow connections from other computers'. - -@tutorial_1043_h3 -Javaをテストする - -@tutorial_1044_p -# To find out which version of Java is installed, open a command prompt and type: - -@tutorial_1045_p -# If you get an error message, you may need to add the Java binary directory to the path environment variable. - -@tutorial_1046_h3 -#Error Message 'Port may be in use' - -@tutorial_1047_p -# You can only start one instance of the H2 Console, otherwise you will get the following error message: "The Web server could not be started. Possible cause: another server is already running...". It is possible to start multiple console applications on the same computer (using different ports), but this is usually not required as the console supports multiple concurrent connections. - -@tutorial_1048_h3 -他のポートを使用する - -@tutorial_1049_p -# If the port is in use by another application, you may want to start the H2 Console on a different port. This can be done by changing the port in the file .h2.server.properties. This file is stored in the user directory (for Windows, this is usually in Documents and Settings/<username>). The relevant entry is webPort. - -@tutorial_1050_h3 -ブラウザを使用してサーバーに接続 - -@tutorial_1051_p -# If the server started successfully, you can connect to it using a web browser. JavaScript needs to be enabled. If you started the server on the same computer as the browser, open the URL http://localhost:8082. If you want to connect to the application from another computer, you need to provide the IP address of the server, for example: http://192.168.0.2:8082. If you enabled SSL on the server side, the URL needs to start with https://. - -@tutorial_1052_h3 -複数の同時セッション - -@tutorial_1053_p -# Multiple concurrent browser sessions are supported. As that the database objects reside on the server, the amount of concurrent work is limited by the memory available to the server application. - -@tutorial_1054_h3 -ログイン - -@tutorial_1055_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]. - -@tutorial_1056_p -# You can save and reuse previously saved settings. The settings are stored in a properties file (see Settings of the H2 Console). - -@tutorial_1057_h3 -エラーメッセージ - -@tutorial_1058_p -# Error messages in are shown in red. You can show/hide the stack trace of the exception by clicking on the message. - -@tutorial_1059_h3 -データベースドライバの追加 - -@tutorial_1060_p -# Additional database drivers to connect to other databases (MySQL, PostgreSQL, HSQLDB,...) 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. - -@tutorial_1061_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. - -@tutorial_1062_h3 -#Using the H2 Console - -@tutorial_1063_p -# The H2 Console application has three main panels: the toolbar on top, the tree on the left, and the query / result panel on the right. The database objects (for example, tables) are listed on the left panel. Type in a SQL command on the query panel and click 'Run'. The result of the command appears just below the command. - -@tutorial_1064_h3 -テーブル名、またはカラム名をインサートする - -@tutorial_1065_p -# The table name and column names can be inserted in the script by clicking them in the tree. If you click on a table while the query is empty, then SELECT * FROM ... is added as well. While typing a query, the table that was used is automatically expanded in the tree. For example if you type SELECT * FROM TEST T WHERE T. then the table TEST is automatically expanded in the tree. - -@tutorial_1066_h3 -切断とアプリケーションの終了 - -@tutorial_1067_p -# To log out of the database, click 'Disconnect' in the toolbar panel. However, the server is still running and ready to accept new sessions. - -@tutorial_1068_p -# To stop the server, right click on the system tray icon and select [Exit]. If you don't have the system tray icon, navigate to [Preferences] and click [Shutdown], press [Ctrl]+[C] in the console where the server was started (Windows), or close the console window. - -@tutorial_1069_h2 -#Special H2 Console Syntax - -@tutorial_1070_p -# The H2 Console supports a few built-in commands. Those are interpreted within the H2 Console, that means they work with any database. They need to be at the beginning of a statement (before any remarks), otherwise they are not parsed correctly. If in doubt, add ';' before the command. - -@tutorial_1071_th -#Command(s) - -@tutorial_1072_th -説明 - -@tutorial_1073_td -# @autocommit_true; - -@tutorial_1074_td -# @autocommit_false; - -@tutorial_1075_td -# Enable or disable autocommit. - -@tutorial_1076_td -# @cancel; - -@tutorial_1077_td -# Cancel the currently running statement. - -@tutorial_1078_td -# @columns null null TEST; - -@tutorial_1079_td -# @index_info null null TEST; - -@tutorial_1080_td -# @tables; - -@tutorial_1081_td -# @tables null null TEST; - -@tutorial_1082_td -# Call the corresponding DatabaseMetaData.get method. Patterns are case sensitive (usually identifiers are uppercase). For information about the parameters, see the Javadoc documentation. Missing parameters at the end are set to null. The complete list of commands is: @attributes @best_row_identifier @catalogs @columns @column_privileges @cross_references @exported_keys @imported_keys @index_info @primary_keys @procedures @procedure_columns @schemas @super_tables @super_types @tables @table_privileges @table_types @type_info @udts @version_columns - -@tutorial_1083_td -# @edit select * from test; - -@tutorial_1084_td -# Use an updatable result set. - -@tutorial_1085_td -# @generated insert into test() values(); - -@tutorial_1086_td -# Show the result of Statement.getGeneratedKeys(). - -@tutorial_1087_td -# @history; - -@tutorial_1088_td -# Show the command history. - -@tutorial_1089_td -# @info; - -@tutorial_1090_td -# Display the result of various Connection and DatabaseMetaData methods. - -@tutorial_1091_td -# @list select * from test; - -@tutorial_1092_td -# Show the result set in list format (each column on its own line, with row numbers). - -@tutorial_1093_td -# @loop 1000 select ?, ?/*rnd*/; - -@tutorial_1094_td -# @loop 1000 @statement select ?; - -@tutorial_1095_td -# Run the statement this many times. Parameters (?) are set using a loop from 0 up to x - 1. Random values are used for each ?/*rnd*/. A Statement object is used instead of a PreparedStatement if @statement is used. Result sets are read until ResultSet.next() returns false. Timing information is printed. - -@tutorial_1096_td -# @maxrows 20; - -@tutorial_1097_td -# Set the maximum number of rows to display. - -@tutorial_1098_td -# @memory; - -@tutorial_1099_td -# Show the used and free memory. This will call System.gc(). - -@tutorial_1100_td -# @meta select 1; - -@tutorial_1101_td -# List the ResultSetMetaData after running the query. - -@tutorial_1102_td -# @parameter_meta select ?; - -@tutorial_1103_td -# Show the result of the PreparedStatement.getParameterMetaData() calls. The statement is not executed. - -@tutorial_1104_td -# @prof_start; - -@tutorial_1105_td -# call hash('SHA256', '', 1000000); - -@tutorial_1106_td -# @prof_stop; - -@tutorial_1107_td -# Start / stop the built-in profiling tool. The top 3 stack traces of the statement(s) between start and stop are listed (if there are 3). - -@tutorial_1108_td -# @transaction_isolation; - -@tutorial_1109_td -# @transaction_isolation 2; - -@tutorial_1110_td -# Display (without parameters) or change (with parameters 1, 2, 4, 8) the transaction isolation level. - -@tutorial_1111_h2 -#Settings of the H2 Console - -@tutorial_1112_p -# The settings of the H2 Console are stored in a configuration file called .h2.server.properties in you user home directory. For Windows installations, the user home directory is usually C:\Documents and Settings\[username]. The configuration file contains the settings of the application and is automatically created when the H2 Console is first started. - -@tutorial_1113_h2 -JDBCを使用してデータベースに接続 - -@tutorial_1114_p -# 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: - -@tutorial_1115_p -# This code first loads the driver (Class.forName(...)) and then opens a connection (using DriverManager.getConnection()). The driver name is "org.h2.Driver". The database URL always needs to start with jdbc:h2: to be recognized by this database. The second parameter in the getConnection() call is the user name (sa for System Administrator in this example). The third parameter is the password. In this database, user names are not case sensitive, but passwords are. - -@tutorial_1116_h2 -新しいデータベースを作成する - -@tutorial_1117_p -# By default, if the database specified in the URL does not yet exist, a new (empty) database is created automatically. The user that created the database automatically becomes the administrator of this database. - -@tutorial_1118_p -# Auto-creating new database can be disabled, see Opening a Database Only if it Already Exists. - -@tutorial_1119_h2 -サーバーを使用する - -@tutorial_1120_p -# H2 currently supports three server: a web server (for the H2 Console), a TCP server (for client/server connections) and an PG server (for PostgreSQL clients). Please note that only the web server supports browser connections. The servers can be started in different ways, one is using the Server tool. - -@tutorial_1121_h3 -#Starting the Server Tool from Command Line - -@tutorial_1122_p -# To start the Server tool from the command line with the default settings, run: - -@tutorial_1123_p -# This will start the tool with the default options. To get the list of options and default values, run: - -@tutorial_1124_p -# There are options available to use other ports, and start or not start parts. - -@tutorial_1125_h3 -TCPサーバーに接続する - -@tutorial_1126_p -# To remotely connect to a database using the TCP server, use the following driver and database URL: - -@tutorial_1127_li -#JDBC driver class: org.h2.Driver - -@tutorial_1128_li -#Database URL: jdbc:h2:tcp://localhost/~/test - -@tutorial_1129_p -# For details about the database URL, see also in Features. Please note that you can't connection with a web browser to this URL. You can only connect using a H2 client (over JDBC). - -@tutorial_1130_h3 -#Starting the TCP Server within an Application - -@tutorial_1131_p -# Servers can also be started and stopped from within an application. Sample code: - -@tutorial_1132_h3 -他の過程からTCPサーバーを終了する - -@tutorial_1133_p -# The TCP server can be stopped from another process. To stop the server from the command line, run: - -@tutorial_1134_p -# To stop the server from a user application, use the following code: - -@tutorial_1135_p -# This function will only stop the TCP server. If other server were started in the same process, they will continue to run. To avoid recovery when the databases are opened the next time, all connections to the databases should be closed before calling this method. To stop a remote server, remote connections must be enabled on the server. Shutting down a TCP server can be protected using the option -tcpPassword (the same password must be used to start and stop the TCP server). - -@tutorial_1136_h2 -Hibernateを使用する - -@tutorial_1137_p -# This database supports Hibernate version 3.1 and newer. You can use the HSQLDB Dialect, or the native H2 Dialect. Unfortunately the H2 Dialect included in some versions of Hibernate is buggy. A patch for Hibernate has been submitted and is now applied. The dialect for the newest version of Hibernate is also available at src/tools/org/hibernate/dialect/H2Dialect.java.txt. You can rename it to H2Dialect.java and include this as a patch in your application, or upgrade to a version of Hibernate where this is fixed. - -@tutorial_1138_p -# When using compatibility modes such as MODE=MySQL when using Hibernate is not supported when using H2Dialect. - -@tutorial_1139_h2 -#Using TopLink and Glassfish - -@tutorial_1140_p -# To use H2 with Glassfish (or Sun AS), set the Datasource Classname to org.h2.jdbcx.JdbcDataSource. You can set this in the GUI at Application Server - Resources - JDBC - Connection Pools, or by editing the file sun-resources.xml: at element jdbc-connection-pool, set the attribute datasource-classname to org.h2.jdbcx.JdbcDataSource. - -@tutorial_1141_p -# The H2 database is compatible with HSQLDB and PostgreSQL. To take advantage of H2 specific features, use the H2Platform. The source code of this platform is included in H2 at src/tools/oracle/toplink/essentials/platform/database/DatabasePlatform.java.txt. You will need to copy this file to your application, and rename it to .java. To enable it, change the following setting in persistence.xml: - -@tutorial_1142_p -# In old versions of Glassfish, the property name is toplink.platform.class.name. - -@tutorial_1143_p -# To use H2 within Glassfish, copy the h2*.jar to the directory glassfish/glassfish/lib. - -@tutorial_1144_h2 -#Using EclipseLink - -@tutorial_1145_p -# To use H2 in EclipseLink, use the platform class org.eclipse.persistence.platform.database.H2Platform. If this platform is not available in your version of EclipseLink, you can use the OraclePlatform instead in many case. See also H2Platform. - -@tutorial_1146_h2 -Webアプリケーションで データベースを使用する - -@tutorial_1147_p -# There are multiple ways to access a database from within web applications. Here are some examples if you use Tomcat or JBoss. - -@tutorial_1148_h3 -エンベッドモード - -@tutorial_1149_p -# The (currently) simplest solution is to use the database in the embedded mode, that means open a connection in your application when it starts (a good solution is using a Servlet Listener, see below), or when a session starts. A database can be accessed from multiple sessions and applications at the same time, as long as they run in the same process. Most Servlet Containers (for example Tomcat) are just using one process, so this is not a problem (unless you run Tomcat in clustered mode). Tomcat uses multiple threads and multiple classloaders. If multiple applications access the same database at the same time, you need to put the database jar in the shared/lib or server/lib directory. It is a good idea to open the database when the web application starts, and close it when the web application stops. If using multiple applications, only one (any) of them needs to do that. In the application, an idea is to use one connection per Session, or even one connection per request (action). Those connections should be closed after use if possible (but it's not that bad if they don't get closed). - -@tutorial_1150_h3 -サーバーモード - -@tutorial_1151_p -# The server mode is similar, but it allows you to run the server in another process. - -@tutorial_1152_h3 -データベースの起動と終了にServletリスナーを使用する - -@tutorial_1153_p -# Add the h2*.jar file to your web application, and add the following snippet to your web.xml file (between the context-param and the filter section): - -@tutorial_1154_p -# For details on how to access the database, see the file DbStarter.java. By default this tool opens an embedded connection using the database URL jdbc:h2:~/test, user name sa, and password sa. If you want to use this connection within your servlet, you can access as follows: - -@tutorial_1155_code -#DbStarter - -@tutorial_1156_p -# can also start the TCP server, however this is disabled by default. To enable it, use the parameter db.tcpServer in the file web.xml. Here is the complete list of options. These options need to be placed between the description tag and the listener / filter tags: - -@tutorial_1157_p -# When the web application is stopped, the database connection will be closed automatically. If the TCP server is started within the DbStarter, it will also be stopped automatically. - -@tutorial_1158_h3 -#Using the H2 Console Servlet - -@tutorial_1159_p -# The H2 Console is a standalone application and includes its own web server, but it can be used as a servlet as well. To do that, include the the h2*.jar file in your application, and add the following configuration to your web.xml: - -@tutorial_1160_p -# For details, see also src/tools/WEB-INF/web.xml. - -@tutorial_1161_p -# To create a web application with just the H2 Console, run the following command: - -@tutorial_1162_h2 -CSV (Comma Separated Values) サポート - -@tutorial_1163_p -# The CSV file support can be used inside the database using the functions CSVREAD and CSVWRITE, or it can be used outside the database as a standalone tool. - -@tutorial_1164_h3 -データベース内からCSVファイルを読み込む - -@tutorial_1165_p -# A CSV file can be read using the function CSVREAD. Example: - -@tutorial_1166_h3 -#Importing Data from a CSV File - -@tutorial_1167_p -# A fast way to load or import data (sometimes called 'bulk load') from a CSV file is to combine table creation with import. Optionally, the column names and data types can be set when creating the table. Another option is to use INSERT INTO ... SELECT. - -@tutorial_1168_h3 -データベース内からCSVファイルに書き込む - -@tutorial_1169_p -# The built-in function CSVWRITE can be used to create a CSV file from a query. Example: - -@tutorial_1170_h3 -JavaアプリケーションからCSVファイルに書き込む - -@tutorial_1171_p -# The Csv tool can be used in a Java application even when not using a database at all. Example: - -@tutorial_1172_h3 -JavaアプリケーションからCSVファイルを読み込む - -@tutorial_1173_p -# It is possible to read a CSV file without opening a database. Example: - -@tutorial_1174_h2 -アップグレード、 バックアップ、修復 - -@tutorial_1175_h3 -データベースのアップグレー - -@tutorial_1176_p -# The recommended way to upgrade from one version of the database engine to the next version is to create a backup of the database (in the form of a SQL script) using the old engine, and then execute the SQL script using the new engine. - -@tutorial_1177_h3 -バックアップ - -@tutorial_1178_p -# There are different ways to backup a database. For example, it is possible to copy the database files. However, this is not recommended while the database is in use. Also, the database files are not human readable and quite large. The recommended way to backup a database is to create a compressed SQL script file. This can be done using the Script tool: - -@tutorial_1179_p -# It is also possible to use the SQL command SCRIPT to create the backup of the database. For more information about the options, see the SQL command SCRIPT. The backup can be done remotely, however the file will be created on the server side. The built in FTP server could be used to retrieve the file from the server. - -@tutorial_1180_h3 -修復 - -@tutorial_1181_p -# To restore a database from a SQL script file, you can use the RunScript tool: - -@tutorial_1182_p -# For more information about the options, see the SQL command RUNSCRIPT. The restore can be done remotely, however the file needs to be on the server side. The built in FTP server could be used to copy the file to the server. It is also possible to use the SQL command RUNSCRIPT to execute a SQL script. 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. - -@tutorial_1183_h3 -オンラインバックアップ - -@tutorial_1184_p -# The BACKUP SQL statement and the Backup tool both create a zip file with all database files. However, the contents of this file are not human readable. - -@tutorial_1185_p -# Unlike than the SCRIPT statement, the BACKUP statement does not lock the database objects when using the multi-threaded mode, and therefore does not block other users. The resulting backup is transactionally consistent: - -@tutorial_1186_p -# The Backup tool (org.h2.tools.Backup) can not be used to create a online backup; the database must not be in use while running this program. - -@tutorial_1187_p -# Creating a backup by copying the database files while the database is running is not supported, except if the file systems support creating snapshots. The problem is that it can't be guaranteed that the data is copied in the right order. - -@tutorial_1188_h2 -#Command Line Tools - -@tutorial_1189_p -# This database comes with a number of command line tools. To get more information about a tool, start it with the parameter '-?', for example: - -@tutorial_1190_p -# The command line tools are: - -@tutorial_1191_code -バックアップ - -@tutorial_1192_li -# creates a backup of a database. - -@tutorial_1193_code -#ChangeFileEncryption - -@tutorial_1194_li -# allows changing the file encryption password or algorithm of a database. - -@tutorial_1195_code -#Console - -@tutorial_1196_li -# starts the browser based H2 Console. - -@tutorial_1197_code -#ConvertTraceFile - -@tutorial_1198_li -# converts a .trace.db file to a Java application and SQL script. - -@tutorial_1199_code -#CreateCluster - -@tutorial_1200_li -# creates a cluster from a standalone database. - -@tutorial_1201_code -#DeleteDbFiles - -@tutorial_1202_li -# deletes all files belonging to a database. - -@tutorial_1203_code -#Recover - -@tutorial_1204_li -# helps recovering a corrupted database. - -@tutorial_1205_code -#Restore - -@tutorial_1206_li -# restores a backup of a database. - -@tutorial_1207_code -#RunScript - -@tutorial_1208_li -# runs a SQL script against a database. - -@tutorial_1209_code -#Script - -@tutorial_1210_li -# allows converting a database to a SQL script for backup or migration. - -@tutorial_1211_code -Server - -@tutorial_1212_li -# is used in the server mode to start a H2 server. - -@tutorial_1213_code -#Shell - -@tutorial_1214_li -# is a command line database tool. - -@tutorial_1215_p -# The tools can also be called from an application by calling the main or another public method. For details, see the Javadoc documentation. - -@tutorial_1216_h2 -#The Shell Tool - -@tutorial_1217_p -# The Shell tool is a simple interactive command line tool. To start it, type: - -@tutorial_1218_p -# You will be asked for a database URL, JDBC driver, user name, and password. The connection setting can also be set as command line parameters. After connecting, you will get the list of options. The built-in commands don't need to end with a semicolon, but SQL statements are only executed if the line ends with a semicolon ;. This allows to enter multi-line statements: - -@tutorial_1219_p -# By default, results are printed as a table. For results with many column, consider using the list mode: - -@tutorial_1220_h2 -OpenOffice Baseを使用する - -@tutorial_1221_p -# 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. The steps to connect to a H2 database are: - -@tutorial_1222_li -#Start OpenOffice Writer, go to [Tools], [Options] - -@tutorial_1223_li -#Make sure you have selected a Java runtime environment in OpenOffice.org / Java - -@tutorial_1224_li -#Click [Class Path...], [Add Archive...] - -@tutorial_1225_li -#Select your h2 jar file (location is up to you, could be wherever you choose) - -@tutorial_1226_li -#Click [OK] (as much as needed), stop OpenOffice (including the Quickstarter) - -@tutorial_1227_li -#Start OpenOffice Base - -@tutorial_1228_li -#Connect to an existing database; select [JDBC]; [Next] - -@tutorial_1229_li -#Example datasource URL: jdbc:h2:~/test - -@tutorial_1230_li -#JDBC driver class: org.h2.Driver - -@tutorial_1231_p -# Now you can access the database stored in the current users home directory. - -@tutorial_1232_p -# To use H2 in NeoOffice (OpenOffice without X11): - -@tutorial_1233_li -#In NeoOffice, go to [NeoOffice], [Preferences] - -@tutorial_1234_li -#Look for the page under [NeoOffice], [Java] - -@tutorial_1235_li -#Click [Class Path], [Add Archive...] - -@tutorial_1236_li -#Select your h2 jar file (location is up to you, could be wherever you choose) - -@tutorial_1237_li -#Click [OK] (as much as needed), restart NeoOffice. - -@tutorial_1238_p -# Now, when creating a new database using the "Database Wizard" : - -@tutorial_1239_li -#Click [File], [New], [Database]. - -@tutorial_1240_li -#Select [Connect to existing database] and the select [JDBC]. Click next. - -@tutorial_1241_li -#Example datasource URL: jdbc:h2:~/test - -@tutorial_1242_li -#JDBC driver class: org.h2.Driver - -@tutorial_1243_p -# Another solution to use H2 in NeoOffice is: - -@tutorial_1244_li -#Package the h2 jar within an extension package - -@tutorial_1245_li -#Install it as a Java extension in NeoOffice - -@tutorial_1246_p -# This can be done by create it using the NetBeans OpenOffice plugin. See also Extensions Development. - -@tutorial_1247_h2 -Java Web Start / JNLP - -@tutorial_1248_p -# When using Java Web Start / JNLP (Java Network Launch Protocol), permissions tags must be set in the .jnlp file, and the application .jar file must be signed. Otherwise, when trying to write to the file system, the following exception will occur: java.security.AccessControlException: access denied (java.io.FilePermission ... read). Example permission tags: - -@tutorial_1249_h2 -#Using a Connection Pool - -@tutorial_1250_p -# For H2, opening a connection is fast if the database is already open. Still, using a connection pool improves performance if you open and close connections a lot. A simple connection pool is included in H2. It is based on the Mini Connection Pool Manager from Christian d'Heureuse. There are other, more complex, open source connection pools available, for example the Apache Commons DBCP. For H2, it is about twice as faster to get a connection from the built-in connection pool than to get one using DriverManager.getConnection().The build-in connection pool is used as follows: - -@tutorial_1251_h2 -フルテキストサーチ - -@tutorial_1252_p -# H2 includes two fulltext search implementations. One is using Apache Lucene, and the other (the native implementation) stores the index data in special tables in the database. - -@tutorial_1253_h3 -#Using the Native Fulltext Search - -@tutorial_1254_p -# To initialize, call: - -@tutorial_1255_p -# You need to initialize it in each database where you want to use it. Afterwards, you can create a fulltext index for a table using: - -@tutorial_1256_p -# PUBLIC is the schema name, TEST is the table name. The list of column names (column separated) is optional, in this case all columns are indexed. The index is updated in realtime. To search the index, use the following query: - -@tutorial_1257_p -# This will produce a result set that contains the query needed to retrieve the data: - -@tutorial_1258_p -# To get the raw data, use FT_SEARCH_DATA('Hello', 0, 0);. The result contains the columns SCHEMA (the schema name), TABLE (the table name), COLUMNS (an array of column names), and KEYS (an array of objects). To join a table, use a join as in: SELECT T.* FROM FT_SEARCH_DATA('Hello', 0, 0) FT, TEST T WHERE FT.TABLE='TEST' AND T.ID=FT.KEYS[0]; - -@tutorial_1259_p -# You can also call the index from within a Java application: - -@tutorial_1260_h3 -Luceneフルテキストサーチを使用する - -@tutorial_1261_p -# To use the Lucene full text search, you need the Lucene library in the classpath. How to do that depends on the application; if you use the H2 Console, you can add the Lucene jar file to the environment variables H2DRIVERS or CLASSPATH. To initialize the Lucene fulltext search in a database, call: - -@tutorial_1262_p -# You need to initialize it in each database where you want to use it. Afterwards, you can create a full text index for a table using: - -@tutorial_1263_p -# PUBLIC is the schema name, TEST is the table name. The list of column names (column separated) is optional, in this case all columns are indexed. The index is updated in realtime. To search the index, use the following query: - -@tutorial_1264_p -# This will produce a result set that contains the query needed to retrieve the data: - -@tutorial_1265_p -# To get the raw data, use FTL_SEARCH_DATA('Hello', 0, 0);. The result contains the columns SCHEMA (the schema name), TABLE (the table name), COLUMNS (an array of column names), and KEYS (an array of objects). To join a table, use a join as in: SELECT T.* FROM FTL_SEARCH_DATA('Hello', 0, 0) FT, TEST T WHERE FT.TABLE='TEST' AND T.ID=FT.KEYS[0]; - -@tutorial_1266_p -# You can also call the index from within a Java application: - -@tutorial_1267_h2 -#User-Defined Variables - -@tutorial_1268_p -# This database supports user-defined variables. Variables start with @ and can be used wherever expressions or parameters are allowed. Variables are not persisted and session scoped, that means only visible from within the session in which they are defined. A value is usually assigned using the SET command: - -@tutorial_1269_p -# The value can also be changed using the SET() method. This is useful in queries: - -@tutorial_1270_p -# Variables that are not set evaluate to NULL. The data type of a user-defined variable is the data type of the value assigned to it, that means it is not necessary (or possible) to declare variable names before using them. There are no restrictions on the assigned values; large objects (LOBs) are supported as well. - -@tutorial_1271_h2 -#Date and Time - -@tutorial_1272_p -# Date, time and timestamp values support ISO 8601 formatting, including time zone: - -@tutorial_1273_p -# If the time zone is not set, the value is parsed using the current time zone setting of the system. Date and time information is stored in H2 database files in GMT (Greenwich Mean Time). If the database is opened using another system time zone, the date and time will change accordingly. If you want to move a database from one time zone to the other and don't want this to happen, you need to create a SQL script file using the SCRIPT command or Script tool, and then load the database using the RUNSCRIPT command or the RunScript tool in the new time zone. - -@tutorial_1274_h2 -#Using Spring - -@tutorial_1275_p -# Use the following configuration to start and stop the H2 TCP server using the Spring Framework: - -@tutorial_1276_p -# The destroy-method will help prevent exceptions on hot-redeployment or when restarting the server. - diff --git a/tools/h2/src/docsrc/textbase/_docs_en.properties b/tools/h2/src/docsrc/textbase/_docs_en.properties deleted file mode 100755 index 66bb223..0000000 --- a/tools/h2/src/docsrc/textbase/_docs_en.properties +++ /dev/null @@ -1,3525 +0,0 @@ -advanced_1000_h1=Advanced -advanced_1001_a=\ Result Sets -advanced_1002_a=\ Large Objects -advanced_1003_a=\ Linked Tables -advanced_1004_a=\ Transaction Isolation -advanced_1005_a=\ Multi-Version Concurrency Control (MVCC) -advanced_1006_a=\ Clustering / High Availability -advanced_1007_a=\ Two Phase Commit -advanced_1008_a=\ Compatibility -advanced_1009_a=\ Standards Compliance -advanced_1010_a=\ Run as Windows Service -advanced_1011_a=\ ODBC Driver -advanced_1012_a=\ Using H2 in Microsoft .NET -advanced_1013_a=\ ACID -advanced_1014_a=\ Durability Problems -advanced_1015_a=\ Using the Recover Tool -advanced_1016_a=\ File Locking Protocols -advanced_1017_a=\ File Locking Method 'Serialized' -advanced_1018_a=\ Protection against SQL Injection -advanced_1019_a=\ Protection against Remote Access -advanced_1020_a=\ Restricting Class Loading and Usage -advanced_1021_a=\ Security Protocols -advanced_1022_a=\ SSL/TLS Connections -advanced_1023_a=\ Universally Unique Identifiers (UUID) -advanced_1024_a=\ Settings Read from System Properties -advanced_1025_a=\ Setting the Server Bind Address -advanced_1026_a=\ Pluggable File System -advanced_1027_a=\ Limits and Limitations -advanced_1028_a=\ Glossary and Links -advanced_1029_h2=Result Sets -advanced_1030_h3=Statements that Return a Result Set -advanced_1031_p=\ The following statements return a result set\: SELECT, EXPLAIN, CALL, SCRIPT, SHOW, HELP. All other statements return an update count. -advanced_1032_h3=Limiting the Number of Rows -advanced_1033_p=\ Before the result is returned to the application, all rows are read by the database. Server side cursors are not supported currently. If only the first few rows are interesting for the application, then the result set size should be limited to improve the performance. This can be done using LIMIT in a query (example\: SELECT * FROM TEST LIMIT 100), or by using Statement.setMaxRows(max). -advanced_1034_h3=Large Result Sets and External Sorting -advanced_1035_p=\ For large result set, the result is buffered to disk. The threshold can be defined using the statement SET MAX_MEMORY_ROWS. If ORDER BY is used, 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. -advanced_1036_h2=Large Objects -advanced_1037_h3=Storing and Reading Large Objects -advanced_1038_p=\ If it is possible that the objects don't fit into memory, then the data type CLOB (for textual data) or BLOB (for binary data) should be used. For these data types, the objects are not fully read into memory, by using streams. To store a BLOB, use PreparedStatement.setBinaryStream. To store a CLOB, use PreparedStatement.setCharacterStream. To read a BLOB, use ResultSet.getBinaryStream, and to read a CLOB, use ResultSet.getCharacterStream. When using the client/server mode, large BLOB and CLOB data is stored in a temporary file on the client side. -advanced_1039_h3=When to use CLOB/BLOB -advanced_1040_p=\ This database stores large LOB (CLOB and BLOB) objects as separate files. Small LOB objects are stored in-place, the threshold can be set using MAX_LENGTH_INPLACE_LOB, but there is still an overhead to use CLOB/BLOB. Because of this, BLOB and CLOB should never be used for columns with a maximum size below about 200 bytes. The best threshold depends on the use case; reading in-place objects is faster than reading from separate files, but slows down the performance of operations that don't involve this column. -advanced_1041_h3=Large Object Compression -advanced_1042_p=\ CLOB and BLOB values can be compressed by using SET COMPRESS_LOB. The LZF algorithm is faster but needs more disk space. By default compression is disabled, which usually speeds up write operations. If you store many large compressible values such as XML, HTML, text, and uncompressed binary files, then compressing can save a lot of disk space (sometimes more than 50%), and read operations may even be faster. -advanced_1043_h2=Linked Tables -advanced_1044_p=\ This database supports linked tables, which means tables that don't exist in the current database but are just links to another database. To create such a link, use the CREATE LINKED TABLE statement\: -advanced_1045_p=\ You can then access the table in the usual way. Whenever the linked table is accessed, the database issues specific queries over JDBC. Using the example above, if you issue the query SELECT * FROM LINK WHERE ID\=1, then the following query is run against the PostgreSQL database\: SELECT * FROM TEST WHERE ID\=?. The same happens for insert and update statements. Only simple statements are executed against the target database, that means no joins. Prepared statements are used where possible. -advanced_1046_p=\ To view the statements that are executed against the target table, set the trace level to 3. -advanced_1047_p=\ If multiple linked tables point to the same database (using the same database URL), the connection is shared. To disable this, set the system property h2.shareLinkedConnections\=false. -advanced_1048_p=\ The statement CREATE LINKED TABLE supports an optional schema name parameter. -advanced_1049_h2=Transaction Isolation -advanced_1050_p=\ Transaction isolation is provided for all data manipulation language (DML) statements. Most data definition language (DDL) statements commit the current transaction. See the Grammar for details. -advanced_1051_p=\ This database supports the following transaction isolation levels\: -advanced_1052_b=Read Committed -advanced_1053_li=\ This is the default level. Read locks are released immediately. Higher concurrency is possible when using this level. -advanced_1054_li=\ To enable, execute the SQL statement SET LOCK_MODE 3 -advanced_1055_li=\ or append ;LOCK_MODE\=3 to the database URL\: jdbc\:h2\:~/test;LOCK_MODE\=3 -advanced_1056_b=Serializable -advanced_1057_li=\ To enable, execute the SQL statement SET LOCK_MODE 1 -advanced_1058_li=\ or append ;LOCK_MODE\=1 to the database URL\: jdbc\:h2\:~/test;LOCK_MODE\=1 -advanced_1059_b=Read Uncommitted -advanced_1060_li=\ This level means that transaction isolation is disabled. -advanced_1061_li=\ To enable, execute the SQL statement SET LOCK_MODE 0 -advanced_1062_li=\ or append ;LOCK_MODE\=0 to the database URL\: jdbc\:h2\:~/test;LOCK_MODE\=0 -advanced_1063_p=\ When using the isolation level 'serializable', dirty reads, non-repeatable reads, and phantom reads are prohibited. -advanced_1064_b=Dirty Reads -advanced_1065_li=\ Means a connection can read uncommitted changes made by another connection. -advanced_1066_li=\ Possible with\: read uncommitted -advanced_1067_b=Non-Repeatable Reads -advanced_1068_li=\ 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. -advanced_1069_li=\ Possible with\: read uncommitted, read committed -advanced_1070_b=Phantom Reads -advanced_1071_li=\ 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. -advanced_1072_li=\ Possible with\: read uncommitted, read committed -advanced_1073_h3=Table Level Locking -advanced_1074_p=\ The database allows multiple concurrent connections to the same database. To make sure all connections only see consistent data, table level locking is used by default. This mechanism does not allow high concurrency, but is very fast. Shared locks and exclusive locks are supported. Before reading from a table, the database tries to add a shared lock to the table (this is only possible if there is no exclusive lock on the object by another connection). If the shared lock is added successfully, the table can be read. It is allowed that other connections also have a shared lock on the same object. If a connection wants to write to a table (update or delete a row), an exclusive lock is required. To get the exclusive lock, other connection must not have any locks on the object. After the connection commits, all locks are released. This database keeps all locks in memory. -advanced_1075_h3=Lock Timeout -advanced_1076_p=\ If a connection cannot get a lock on an object, the connection waits for some amount of time (the lock timeout). During this time, hopefully the connection holding the lock commits and it is then possible to get the lock. If this is not possible because 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. -advanced_1077_h2=Multi-Version Concurrency Control (MVCC) -advanced_1078_p=\ The MVCC feature allows higher concurrency than using (table level or row level) locks. When using MVCC in this database, delete, insert and update operations will only issue a shared lock on the table. An exclusive lock is still used when adding or removing columns, when dropping the table, and when using SELECT ... FOR UPDATE. Connections only 'see' committed data, and own changes. That means, if connection A updates a row but doesn't commit this change yet, connection B will see the old value. Only when the change is committed, the new value is visible by other connections (read committed). If multiple connections concurrently try to update the same row, the database waits until it can apply the change, but at most until the lock timeout expires. -advanced_1079_p=\ To use the MVCC feature, append ;MVCC\=TRUE to the database URL\: -advanced_1080_p=\ MVCC is disabled by default. The MVCC feature is not fully tested yet. The limitations of the MVCC mode are\: it can not be used at the same time as MULTI_THREADED\=TRUE; the complete undo log must fit in memory when using multi-version concurrency (the setting MAX_MEMORY_UNDO has no effect). It is not possible to enable or disable this setting while the database is already open. The setting must be specified in the first connection (the one that opens the database). -advanced_1081_h2=Clustering / High Availability -advanced_1082_p=\ This database supports a simple clustering / high availability mechanism. The architecture is\: two database servers run on two different computers, and on both computers is a copy of the same database. If both servers run, each database operation is executed on both computers. If one server fails (power, hardware or network failure), the other server can still continue to work. From this point on, the operations will be executed only on one server until the other server is back up. -advanced_1083_p=\ Clustering can only be used in the server mode (the embedded mode does not support clustering). The cluster can be re-created using the CreateCluster tool without stopping the remaining server. Applications that are still connected are automatically disconnected, however when appending ;AUTO_RECONNECT\=TRUE, they will recover from that. -advanced_1084_p=\ To initialize the cluster, use the following steps\: -advanced_1085_li=Create a database -advanced_1086_li=Use the CreateCluster tool to copy the database to another location and initialize the clustering. Afterwards, you have two databases containing the same data. -advanced_1087_li=Start two servers (one for each copy of the database) -advanced_1088_li=You are now ready to connect to the databases with the client application(s) -advanced_1089_h3=Using the CreateCluster Tool -advanced_1090_p=\ To understand how clustering works, please try out the following example. In this example, the two databases reside on the same computer, but usually, the databases will be on different servers. -advanced_1091_li=Create two directories\: server1, server2. Each directory will simulate a directory on a computer. -advanced_1092_li=Start a TCP server pointing to the first directory. You can do this using the command line\: -advanced_1093_li=Start a second TCP server pointing to the second directory. This will simulate a server running on a second (redundant) computer. You can do this using the command line\: -advanced_1094_li=Use the CreateCluster tool to initialize clustering. This will automatically create a new, empty database if it does not exist. Run the tool on the command line\: -advanced_1095_li=You can now connect to the databases using an application or the H2 Console using the JDBC URL jdbc\:h2\:tcp\://localhost\:9101,localhost\:9102/~/test -advanced_1096_li=If you stop a server (by killing the process), you will notice that the other machine continues to work, and therefore the database is still accessible. -advanced_1097_li=To restore the cluster, you first need to delete the database that failed, then restart the server that was stopped, and re-run the CreateCluster tool. -advanced_1098_h3=Detect Which Cluster Instances are Running -advanced_1099_p=\ To find out which cluster nodes are currently running, execute the following SQL statement\: -advanced_1100_p=\ If the result is '' (two single quotes), then the cluster mode is disabled. Otherwise, the list of servers is returned, enclosed in single quote. Example\: 'server1\:9191,server2\:9191'. -advanced_1101_h3=Clustering Algorithm and Limitations -advanced_1102_p=\ Read-only queries are only executed against the first cluster node, but all other statements are executed against all nodes. There is currently no load balancing made to avoid problems with transactions. The following functions may yield different results on different cluster nodes and must be executed with care\: RANDOM_UUID(), SECURE_RAND(), SESSION_ID(), MEMORY_FREE(), MEMORY_USED(), CSVREAD(), CSVWRITE(), RAND() [when not using a seed]. Those functions should not be used directly in modifying statements (for example INSERT, UPDATE, MERGE). However, they can be used in read-only statements and the result can then be used for modifying statements. -advanced_1103_p=\ When using the cluster modes, result sets are read fully in memory by the client, so that there is no problem if the server dies that executed the query. Result sets must fit in memory on the client side. -advanced_1104_h2=Two Phase Commit -advanced_1105_p=\ The two phase commit protocol is supported. 2-phase-commit works as follows\: -advanced_1106_li=Autocommit needs to be switched off -advanced_1107_li=A transaction is started, for example by inserting a row -advanced_1108_li=The transaction is marked 'prepared' by executing the SQL statement PREPARE COMMIT transactionName -advanced_1109_li=The transaction can now be committed or rolled back -advanced_1110_li=If a problem occurs before the transaction was successfully committed or rolled back (for example because a network problem occurred), the transaction is in the state 'in-doubt' -advanced_1111_li=When re-connecting to the database, the in-doubt transactions can be listed with SELECT * FROM INFORMATION_SCHEMA.IN_DOUBT -advanced_1112_li=Each transaction in this list must now be committed or rolled back by executing COMMIT TRANSACTION transactionName or ROLLBACK TRANSACTION transactionName -advanced_1113_li=The database needs to be closed and re-opened to apply the changes -advanced_1114_h2=Compatibility -advanced_1115_p=\ This database is (up to a certain point) compatible to other databases such as HSQLDB, MySQL and PostgreSQL. There are certain areas where H2 is incompatible. -advanced_1116_h3=Transaction Commit when Autocommit is On -advanced_1117_p=\ At this time, this database engine commits a transaction (if autocommit is switched on) just before returning the result. For a query, this means the transaction is committed even before the application scans through the result set, and before the result set is closed. Other database engines may commit the transaction in this case when the result set is closed. -advanced_1118_h3=Keywords / Reserved Words -advanced_1119_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\: -advanced_1120_code=\ CROSS, CURRENT_DATE, CURRENT_TIME, CURRENT_TIMESTAMP, DISTINCT, EXCEPT, EXISTS, FALSE, FOR, FROM, FULL, GROUP, HAVING, INNER, INTERSECT, IS, JOIN, LIKE, LIMIT, MINUS, NATURAL, NOT, NULL, ON, ORDER, PRIMARY, ROWNUM, SELECT, SYSDATE, SYSTIME, SYSTIMESTAMP, TODAY, TRUE, UNION, UNIQUE, WHERE -advanced_1121_p=\ Certain words of this list are keywords because they are functions that can be used without '()' for compatibility, for example CURRENT_TIMESTAMP. -advanced_1122_h2=Standards Compliance -advanced_1123_p=\ This database tries to be as much standard compliant as possible. For the SQL language, ANSI/ISO is the main standard. There are several versions that refer to the release date\: SQL-92, SQL\:1999, and SQL\:2003. Unfortunately, the standard documentation is not freely available. Another problem is that important features are not standardized. Whenever this is the case, this database tries to be compatible to other databases. -advanced_1124_h2=Run as Windows Service -advanced_1125_p=\ 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. is included in the installation. Batch files are provided to install, start, stop and uninstall the H2 Database Engine Service. This service contains the TCP Server and the H2 Console web application. The batch files are located in the directory h2/service. -advanced_1126_h3=Install the Service -advanced_1127_p=\ The service needs to be registered as a Windows Service first. To do that, double click on 1_install_service.bat. If successful, a command prompt window will pop up and disappear immediately. If not, a message will appear. -advanced_1128_h3=Start the Service -advanced_1129_p=\ You can start the H2 Database Engine Service using the service manager of Windows, or by double clicking on 2_start_service.bat. Please note that the batch file does not print an error message if the service is not installed. -advanced_1130_h3=Connect to the H2 Console -advanced_1131_p=\ After installing and starting the service, you can connect to the H2 Console application using a browser. Double clicking on 3_start_browser.bat to do that. The default port (8082) is hard coded in the batch file. -advanced_1132_h3=Stop the Service -advanced_1133_p=\ To stop the service, double click on 4_stop_service.bat. Please note that the batch file does not print an error message if the service is not installed or started. -advanced_1134_h3=Uninstall the Service -advanced_1135_p=\ 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. -advanced_1136_h2=ODBC Driver -advanced_1137_p=\ This database does not come with its own ODBC driver at this time, but it supports the PostgreSQL network protocol. Therefore, the PostgreSQL ODBC driver can be used. Support for the PostgreSQL network protocol is quite new and should be viewed as experimental. It should not be used for production applications. -advanced_1138_p=\ To use the PostgreSQL ODBC driver on 64 bit versions of Windows, first run c\:/windows/syswow64/odbcad32.exe. At this point you set up your DSN just like you would on any other system. See also\: Re\: ODBC Driver on Windows 64 bit -advanced_1139_h3=ODBC Installation -advanced_1140_p=\ First, the ODBC driver must be installed. Any recent PostgreSQL ODBC driver should work, however version 8.2 (psqlodbc-08_02*) or newer is recommended. The Windows version of the PostgreSQL ODBC driver is available at http\://www.postgresql.org/ftp/odbc/versions/msi. -advanced_1141_h3=Starting the Server -advanced_1142_p=\ After installing the ODBC driver, start the H2 Server using the command line\: -advanced_1143_p=\ The PG Server (PG for PostgreSQL protocol) is started as well. By default, databases are stored in the current working directory where the server is started. Use -baseDir to save databases in another directory, for example the user home directory\: -advanced_1144_p=\ The PG server can be started and stopped from within a Java application as follows\: -advanced_1145_p=\ By default, only connections from localhost are allowed. To allow remote connections, use -pgAllowOthers when starting the server. -advanced_1146_h3=ODBC Configuration -advanced_1147_p=\ After installing the driver, a new Data Source must be added. In Windows, run odbcad32.exe to open the Data Source Administrator. Then click on 'Add...' and select the PostgreSQL Unicode driver. Then click 'Finish'. You will be able to change the connection properties\: -advanced_1148_th=Property -advanced_1149_th=Example -advanced_1150_th=Remarks -advanced_1151_td=Data Source -advanced_1152_td=H2 Test -advanced_1153_td=The name of the ODBC Data Source -advanced_1154_td=Database -advanced_1155_td=test -advanced_1156_td=\ The database name. Only simple names are supported at this time; -advanced_1157_td=\ relative or absolute path are not supported in the database name. -advanced_1158_td=\ By default, the database is stored in the current working directory -advanced_1159_td=\ where the Server is started except when the -baseDir setting is used. -advanced_1160_td=\ The name must be at least 3 characters. -advanced_1161_td=Server -advanced_1162_td=localhost -advanced_1163_td=The server name or IP address. -advanced_1164_td=By default, only remote connections are allowed -advanced_1165_td=User Name -advanced_1166_td=sa -advanced_1167_td=The database user name. -advanced_1168_td=SSL Mode -advanced_1169_td=disabled -advanced_1170_td=At this time, SSL is not supported. -advanced_1171_td=Port -advanced_1172_td=5435 -advanced_1173_td=The port where the PG Server is listening. -advanced_1174_td=Password -advanced_1175_td=sa -advanced_1176_td=The database password. -advanced_1177_p=\ To improve performance, please enable 'server side prepare' under Options / Datasource / Page 2 / Server side prepare. -advanced_1178_p=\ Afterwards, you may use this data source. -advanced_1179_h3=PG Protocol Support Limitations -advanced_1180_p=\ At this time, only a subset of the PostgreSQL network protocol is implemented. Also, there may be compatibility problems on the SQL level, with the catalog, or with text encoding. Problems are fixed as they are found. Currently, statements can not be canceled when using the PG protocol. -advanced_1181_p=\ PostgreSQL ODBC Driver Setup requires a database password; that means it is not possible to connect to H2 databases without password. This is a limitation of the ODBC driver. -advanced_1182_h3=Security Considerations -advanced_1183_p=\ Currently, the PG Server does not support challenge response or encrypt passwords. This may be a problem if an attacker can listen to the data transferred between the ODBC driver and the server, because the password is readable to the attacker. Also, it is currently not possible to use encrypted SSL connections. Therefore the ODBC driver should not be used where security is important. -advanced_1184_h2=Using H2 in Microsoft .NET -advanced_1185_p=\ The database can be used from Microsoft .NET even without using Java, by using IKVM.NET. You can access a H2 database on .NET using the JDBC API, or using the ADO.NET interface. -advanced_1186_h3=Using the ADO.NET API on .NET -advanced_1187_p=\ An implementation of the ADO.NET interface is available in the open source project H2Sharp. -advanced_1188_h3=Using the JDBC API on .NET -advanced_1189_li=Install the .NET Framework from Microsoft. Mono has not yet been tested. -advanced_1190_li=Install IKVM.NET. -advanced_1191_li=Copy the h2*.jar file to ikvm/bin -advanced_1192_li=Run the H2 Console using\: ikvm -jar h2*.jar -advanced_1193_li=Convert the H2 Console to an .exe file using\: ikvmc -target\:winexe h2*.jar. You may ignore the warnings. -advanced_1194_li=Create a .dll file using (change the version accordingly)\: ikvmc.exe -target\:library -version\:1.0.69.0 h2*.jar -advanced_1195_p=\ If you want your C\# application use H2, you need to add the h2.dll and the IKVM.OpenJDK.ClassLibrary.dll to your C\# solution. Here some sample code\: -advanced_1196_h2=ACID -advanced_1197_p=\ In the database world, ACID stands for\: -advanced_1198_li=Atomicity\: transactions must be atomic, meaning either all tasks are performed or none. -advanced_1199_li=Consistency\: all operations must comply with the defined constraints. -advanced_1200_li=Isolation\: transactions must be isolated from each other. -advanced_1201_li=Durability\: committed transaction will not be lost. -advanced_1202_h3=Atomicity -advanced_1203_p=\ Transactions in this database are always atomic. -advanced_1204_h3=Consistency -advanced_1205_p=\ By default, this database is always in a consistent state. Referential integrity rules are enforced except when explicitly disabled. -advanced_1206_h3=Isolation -advanced_1207_p=\ For H2, as with most other database systems, the default isolation level is 'read committed'. This provides better performance, but also means that transactions are not completely isolated. H2 supports the transaction isolation levels 'serializable', 'read committed', and 'read uncommitted'. -advanced_1208_h3=Durability -advanced_1209_p=\ This database does not guarantee that all committed transactions survive a power failure. Tests show that all databases sometimes lose transactions on power failure (for details, see below). Where losing transactions is not acceptable, a laptop or UPS (uninterruptible power supply) should be used. If durability is required for all possible cases of hardware failure, clustering should be used, such as the H2 clustering mode. -advanced_1210_h2=Durability Problems -advanced_1211_p=\ Complete durability means all committed transaction survive a power failure. Some databases claim they can guarantee durability, but such claims are wrong. A durability test was run against H2, HSQLDB, PostgreSQL, and Derby. All of those databases sometimes lose committed transactions. The test is included in the H2 download, see org.h2.test.poweroff.Test. -advanced_1212_h3=Ways to (Not) Achieve Durability -advanced_1213_p=\ Making sure that committed transactions are not lost is more complicated than it seems first. To guarantee complete durability, a database must ensure that the log record is on the hard drive before the commit call returns. To do that, databases use different methods. One is to use the 'synchronous write' file access mode. In Java, RandomAccessFile supports the modes rws and rwd\: -advanced_1214_code=rwd -advanced_1215_li=\: every update to the file's content is written synchronously to the underlying storage device. -advanced_1216_code=rws -advanced_1217_li=\: in addition to rwd, every update to the metadata is written synchronously. -advanced_1218_p=\ A test (org.h2.test.poweroff.TestWrite) with one of those modes achieves around 50 thousand write operations per second. Even when the operating system write buffer is disabled, the write rate is around 50 thousand operations per second. This feature does not force changes to disk because it does not flush all buffers. The test updates the same byte in the file again and again. If the hard drive was able to write at this rate, then the disk would need to make at least 50 thousand revolutions per second, or 3 million RPM (revolutions per minute). There are no such hard drives. The hard drive used for the test is about 7200 RPM, or about 120 revolutions per second. There is an overhead, so the maximum write rate must be lower than that. -advanced_1219_p=\ Calling fsync flushes the buffers. There are two ways to do that in Java\: -advanced_1220_code=FileDescriptor.sync() -advanced_1221_li=. The documentation says that this forces all system buffers to synchronize with the underlying device. This method is supposed to return after all in-memory modified copies of buffers associated with this file descriptor have been written to the physical medium. -advanced_1222_code=FileChannel.force() -advanced_1223_li=\ (since JDK 1.4). This method is supposed to force any updates to this channel's file to be written to the storage device that contains it. -advanced_1224_p=\ By default, MySQL calls fsync for each commit. When using one of those methods, only around 60 write operations per second can be achieved, which is consistent with the RPM rate of the hard drive used. Unfortunately, even when calling FileDescriptor.sync() or FileChannel.force(), data is not always persisted to the hard drive, because most hard drives do not obey fsync()\: see Your Hard Drive Lies to You. In Mac OS X, fsync does not flush hard drive buffers. See Bad fsync?. So the situation is confusing, and tests prove there is a problem. -advanced_1225_p=\ Trying to flush hard drive buffers is hard, and if you do the performance is very bad. First you need to make sure that the hard drive actually flushes all buffers. Tests show that this can not be done in a reliable way. Then the maximum number of transactions is around 60 per second. Because of those reasons, the default behavior of H2 is to delay writing committed transactions. -advanced_1226_p=\ In H2, after a power failure, a bit more than one second of committed transactions may be lost. To change the behavior, use SET WRITE_DELAY and CHECKPOINT SYNC. Most other databases support commit delay as well. In the performance comparison, commit delay was used for all databases that support it. -advanced_1227_h3=Running the Durability Test -advanced_1228_p=\ 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. One computer just listens, while the test application is run (and power is cut) on the other computer. The computer with the listener application opens a TCP/IP port and listens for an incoming connection. The second computer first connects to the listener, and then created the databases and starts inserting records. The connection is set to 'autocommit', which means after each inserted record a commit is performed automatically. Afterwards, the test computer notifies the listener that this record was inserted successfully. The listener computer displays the last inserted record number every 10 seconds. Now, switch off the power manually, then restart the computer, and run the application again. You will find out that in most cases, none of the databases contains all the records that the listener computer knows about. For details, please consult the source code of the listener and test application. -advanced_1229_h2=Using the Recover Tool -advanced_1230_p=\ The Recover tool can be used to extract the contents of a database file, even if the database is corrupted. It also extracts the content of the transaction log and large objects (CLOB or BLOB). To run the tool, type on the command line\: -advanced_1231_p=\ For each database in the current directory, a text file will be created. This file contains raw insert statements (for the data) and data definition (DDL) statements to recreate the schema of the database. This file can be executed using the RunScript tool or a RUNSCRIPT FROM SQL statement. The script includes at least one CREATE USER statement. If you run the script against a database that was created with the same user, or if there are conflicting users, running the script will fail. Consider running the script against a database that was created with a user name that is not in the script. -advanced_1232_p=\ The Recover tool creates a SQL script from database file. It also processes the transaction log. -advanced_1233_h2=File Locking Protocols -advanced_1234_p=\ Multiple concurrent connections to the same database are supported, however a database file can only be open for reading and writing (in embedded mode) by one process at the same time. Otherwise, the processes would overwrite each others data and corrupt the database file. To protect against this problem, whenever a database is opened, a lock file is created to signal other processes that the database is in use. If the database is closed, or if the process that opened the database stops normally, this lock file is deleted. -advanced_1235_p=\ In special cases (if the process did not terminate normally, for example because there was a power failure), 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. However, this software uses a challenge-response protocol to protect the database 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'. -advanced_1236_p=\ The file locking protocols have the following limitation\: if a shared file system is used, and the machine with the lock owner is sent to sleep (standby or hibernate), another machine may take over. If the machine that originally held the lock wakes up, the database may become corrupt. If this situation can occur, the application must ensure the database is closed when the application is put to sleep. -advanced_1237_h3=File Locking Method 'File' -advanced_1238_p=\ The default method for database file locking is the 'File Method'. The algorithm is\: -advanced_1239_li=If the lock file does not exist, it is created (using the atomic operation File.createNewFile). Then, the process waits a little bit (20 ms) and checks the file again. If the file was changed during this time, the operation is aborted. This protects against a race condition when one process deletes the lock file just after another one create it, and a third process creates the file again. It does not occur if there are only two writers. -advanced_1240_li=\ If the file can be created, a random number is inserted together with the locking method ('file'). Afterwards, a watchdog thread is started that checks regularly (every second once by default) if the file was deleted or modified by another (challenger) thread / process. Whenever that occurs, the file is overwritten with the old data. The watchdog thread runs with high priority so that a change to the lock file does not get through undetected even if the system is very busy. However, the watchdog thread does use very little resources (CPU time), because it waits most of the time. Also, the watchdog only reads from the hard disk and does not write to it. -advanced_1241_li=\ If the lock file exists and was recently modified, the process waits for some time (up to two seconds). If it was still changed, an exception is thrown (database is locked). This is done to eliminate race conditions with many concurrent writers. Afterwards, the file is overwritten with a new version (challenge). After that, the thread waits for 2 seconds. If there is a watchdog thread protecting the file, he will overwrite the change and this process will fail to lock the database. However, if there is no watchdog thread, the lock file will still be as written by this thread. In this case, the file is deleted and atomically created again. The watchdog thread is started in this case and the file is locked. -advanced_1242_p=\ This algorithm is tested with over 100 concurrent threads. In some cases, when there are many concurrent threads trying to lock the database, they block each other (meaning the file cannot be locked by any of them) for some time. However, the file never gets 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. -advanced_1243_h3=File Locking Method 'Socket' -advanced_1244_p=\ There is a second locking mechanism implemented, but disabled by default. To use it, append ;FILE_LOCK\=SOCKET to the database URL. The algorithm is\: -advanced_1245_li=If the lock file does not exist, it is created. Then a server socket is opened on a defined port, and kept open. The port and IP address of the process that opened the database is written into the lock file. -advanced_1246_li=If the lock file exists, and the lock method is 'file', then the software switches to the 'file' method. -advanced_1247_li=If the lock file exists, and the lock method is 'socket', then the process checks if the port is in use. If the original process is still running, the port is in use and this process throws an exception (database is in use). If the original process died (for example due to a power failure, or abnormal termination of the virtual machine), then the port was released. The new process deletes the lock file and starts again. -advanced_1248_p=\ This method does not require a watchdog thread actively polling (reading) the same file every second. The problem with this method is, if the file is stored on a network share, two processes (running on different computers) could still open the same database files, if they do not have a direct TCP/IP connection. -advanced_1249_h2=File Locking Method 'Serialized' -advanced_1250_p=\ This locking mode allows to open multiple connections to the same database. The connections may be opened from multiple processes and from different computers. When writing to the database, access is automatically synchronized internally. Write operations are slower than when using the server mode, and concurrency is relatively poor. The advantage of this mode is that there is no need to start a server. -advanced_1251_p=\ To enable this feature, append ;FILE_LOCK\=SERIALIZED to the database URL. -advanced_1252_p=\ This feature is relatively new. When using it for production, please ensure your use case is well tested (if possible with automated test cases). -advanced_1253_h2=Protection against SQL Injection -advanced_1254_h3=What is SQL Injection -advanced_1255_p=\ This database engine provides a solution for the security vulnerability known as 'SQL Injection'. Here is a short description of what SQL injection means. Some applications build SQL statements with embedded user input such as\: -advanced_1256_p=\ If this mechanism is used anywhere in the application, and user input is not correctly filtered or encoded, it is possible for a user to inject SQL functionality or statements by using specially built input such as (in this example) this password\: ' OR ''\='. In this case the statement becomes\: -advanced_1257_p=\ Which is always true no matter what the password stored in the database is. For more information about SQL Injection, see Glossary and Links. -advanced_1258_h3=Disabling Literals -advanced_1259_p=\ SQL Injection is not possible if user input is not directly embedded in SQL statements. A simple solution for the problem above is to use a prepared statement\: -advanced_1260_p=\ This database provides a way to enforce usage of parameters when passing user input to the database. This is done by disabling embedded literals in SQL statements. To do this, execute the statement\: -advanced_1261_p=\ Afterwards, SQL statements with text and number literals are not allowed any more. That means, SQL statement of the form WHERE NAME\='abc' or WHERE CustomerId\=10 will fail. It is still possible to use prepared statements and parameters as described above. Also, it is still possible to generate SQL statements dynamically, and use the Statement API, as long as the SQL statements do not include literals. There is also a second mode where number literals are allowed\: SET ALLOW_LITERALS NUMBERS. To allow all literals, execute SET ALLOW_LITERALS ALL (this is the default setting). Literals can only be enabled or disabled by an administrator. -advanced_1262_h3=Using Constants -advanced_1263_p=\ Disabling literals also means disabling hard-coded 'constant' literals. This database supports defining constants using the CREATE CONSTANT command. Constants can be defined only when literals are enabled, but used even when literals are disabled. To avoid name clashes with column names, constants can be defined in other schemas\: -advanced_1264_p=\ Even when literals are enabled, it is better to use constants instead of hard-coded number or text literals in queries or views. With constants, typos are found at compile time, the source code is easier to understand and change. -advanced_1265_h3=Using the ZERO() Function -advanced_1266_p=\ It is not required to create a constant for the number 0 as there is already a built-in function ZERO()\: -advanced_1267_h2=Protection against Remote Access -advanced_1268_p=\ By default this database does not allow connections from other machines when starting the H2 Console, the TCP server, or the PG server. Remote access can be enabled using the command line options -webAllowOthers, -tcpAllowOthers, -pgAllowOthers. If you enable remote access, please also consider using the options -baseDir, -ifExists, so that remote users can not create new databases or access existing databases with weak passwords. When using the option -baseDir, only databases within that directory may be accessed. Ensure the existing accessible databases are protected using strong passwords. -advanced_1269_h2=Restricting Class Loading and Usage -advanced_1270_p=\ By default there is no restriction on loading classes and executing Java code for admins. That means an admin may call system functions such as System.setProperty by executing\: -advanced_1271_p=\ To restrict users (including admins) from loading classes and executing code, the list of allowed classes can be set in the system property h2.allowedClasses in the form of a comma separated list of classes or patterns (items ending with *). By default all classes are allowed. Example\: -advanced_1272_p=\ This mechanism is used for all user classes, including database event listeners, trigger classes, user-defined functions, user-defined aggregate functions, and JDBC driver classes (with the exception of the H2 driver) when using the H2 Console. -advanced_1273_h2=Security Protocols -advanced_1274_p=\ 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. -advanced_1275_h3=User Password Encryption -advanced_1276_p=\ When a user tries to connect to a database, the combination of user name, @, and password are hashed using SHA-256, and this hash value is transmitted to the database. This step does not protect against an attacker that re-uses the value if he is able to listen to the (unencrypted) transmission between the client and the server. But, the passwords are never transmitted as plain text, even when using an unencrypted connection between client and server. 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. -advanced_1277_p=\ When a new database or user is created, a new random salt value is generated. The size of the salt is 64 bits. Using the random salt reduces the risk of an attacker pre-calculating hash values for many different (commonly used) passwords. -advanced_1278_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 user-password hash value with the stored salt value and calculates the hash value. Other products use multiple iterations (hash the hash value again and again), but this is not done in this product to reduce the risk of denial of service attacks (where the attacker tries to connect with bogus passwords, and the server 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 accessible remotely, then the iteration count is not required at all. -advanced_1279_h3=File Encryption -advanced_1280_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. -advanced_1281_p=\ When a user tries to connect to an encrypted database, the combination of file@ and the file password is hashed using SHA-256. This hash value is transmitted to the server. -advanced_1282_p=\ When a new database file is created, a new cryptographically secure random salt value is generated. The size of the salt is 64 bits. 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. -advanced_1283_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. -advanced_1284_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. -advanced_1285_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. -advanced_1286_p=\ Therefore, the block cipher mode 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. -advanced_1287_p=\ Database encryption is meant for securing the database while it is not in use (stolen laptop and so on). It is not meant for cases where the attacker has access to files while the database is in use. When he has write access, he can for example replace pieces of files with pieces of older versions and manipulate data like this. -advanced_1288_p=\ File encryption slows down the performance of the database engine. Compared to unencrypted mode, database operations take about 2.2 times longer when using XTEA, and 2.5 times longer using AES (embedded mode). -advanced_1289_h3=Wrong Password / User Name Delay -advanced_1290_p=\ To protect against remote brute force password attacks, the delay after each unsuccessful login gets double as long. Use the system properties h2.delayWrongPasswordMin and h2.delayWrongPasswordMax to change the minimum (the default is 250 milliseconds) or maximum delay (the default is 4000 milliseconds, or 4 seconds). The delay only applies for those using the wrong password. Normally there is no delay for a user that knows the correct password, with one exception\: after using the wrong password, there is a delay of up to (randomly distributed) the same delay as for a wrong password. This is to protect against parallel brute force attacks, so that an attacker needs to wait for the whole delay. Delays are synchronized. This is also required to protect against parallel attacks. -advanced_1291_p=\ There is only one exception message for both wrong user and for wrong password, to make it harder to get the list of user names. It is not possible from the stack trace to see if the user name was wrong or the password. -advanced_1292_h3=HTTPS Connections -advanced_1293_p=\ 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. -advanced_1294_h2=SSL/TLS Connections -advanced_1295_p=\ Remote SSL/TLS connections are supported using the Java Secure Socket Extension (SSLServerSocket, SSLSocket). By default, anonymous SSL is enabled. The default cipher suite is SSL_DH_anon_WITH_RC4_128_MD5. -advanced_1296_p=\ To use your own keystore, set the system properties javax.net.ssl.keyStore and javax.net.ssl.keyStorePassword before starting the H2 server and client. See also Customizing the Default Key and Trust Stores, Store Types, and Store Passwords for more information. -advanced_1297_p=\ To disable anonymous SSL, set the system property h2.enableAnonymousSSL to false. -advanced_1298_h2=Universally Unique Identifiers (UUID) -advanced_1299_p=\ This database supports UUIDs. Also supported is a function to create new UUIDs using a cryptographically strong pseudo random number generator. With random UUIDs, the chance of two having the same value can be calculated using the probability theory. See also 'Birthday Paradox'. Standardized randomly generated UUIDs have 122 random bits. 4 bits are used for the version (Randomly generated UUID), and 2 bits for the variant (Leach-Salz). This database supports generating such UUIDs using the built-in function RANDOM_UUID(). Here is a small program to estimate the probability of having two identical UUIDs after generating a number of values\: -advanced_1300_p=\ Some values are\: -advanced_1301_th=Number of UUIs -advanced_1302_th=Probability of Duplicates -advanced_1303_td=2^36\=68'719'476'736 -advanced_1304_td=0.000'000'000'000'000'4 -advanced_1305_td=2^41\=2'199'023'255'552 -advanced_1306_td=0.000'000'000'000'4 -advanced_1307_td=2^46\=70'368'744'177'664 -advanced_1308_td=0.000'000'000'4 -advanced_1309_p=\ To help non-mathematicians understand what those numbers mean, here a comparison\: 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. -advanced_1310_h2=Settings Read from System Properties -advanced_1311_p=\ Some settings of the database can be set on the command line using -DpropertyName\=value. It is usually not required to change those settings manually. The settings are case sensitive. Example\: -advanced_1312_p=\ The current value of the settings can be read in the table INFORMATION_SCHEMA.SETTINGS. -advanced_1313_p=\ For a complete list of settings, see SysProperties. -advanced_1314_h2=Setting the Server Bind Address -advanced_1315_p=\ Usually server sockets accept connections on any/all local addresses. This may be a problem on multi-homed hosts. To bind only to one address, use the system property h2.bindAddress. This setting is used for both regular server sockets and for SSL server sockets. IPv4 and IPv6 address formats are supported. -advanced_1316_h2=Pluggable File System -advanced_1317_p=\ This database supports a pluggable file system API. The file system implementation is selected using a file name prefix. The following file systems are included\: -advanced_1318_code=zip\: -advanced_1319_li=\ read-only zip-file based file system. Format\: zip\:/zipFileName\!/fileName. -advanced_1320_code=nio\: -advanced_1321_li=\ file system that uses FileChannel instead of RandomAccessFile (faster in some operating systems). -advanced_1322_code=nioMapped\: -advanced_1323_li=\ file system that uses memory mapped files (faster in some operating systems). -advanced_1324_code=split\: -advanced_1325_li=\ file system that splits files in 1 GB files (stackable with other file systems). -advanced_1326_code=memFS\: -advanced_1327_li=\ in-memory file system (slower than mem; experimental; mainly used for testing the database engine itself). -advanced_1328_code=memLZF\: -advanced_1329_li=\ compressing in-memory file system (slower than memFS but uses less memory; experimental; mainly used for testing the database engine itself). -advanced_1330_p=\ As an example, to use the the nio file system, use the following database URL\: jdbc\:h2\:nio\:~/test. -advanced_1331_p=\ To register a new file system, extend the classes org.h2.store.fs.FileSystem, FileObject, and call the method FileSystem.register before using it. -advanced_1332_h2=Limits and Limitations -advanced_1333_p=\ This database has the following known limitations\: -advanced_1334_li=Database file size limits (excluding BLOB and CLOB data)\: With the default storage mechanism, the maximum file size is currently 256 GB for the data, and 256 GB for the index. With the page store (experimental)\: 4 TB or higher. -advanced_1335_li=BLOB and CLOB size limit\: every CLOB or BLOB can be up to 256 GB. -advanced_1336_li=The maximum file size for FAT or FAT32 file systems is 4 GB. That means when using FAT or FAT32, the limit is 4 GB for the data. This is the limitation of the file system. The database does provide a workaround for this problem, it is to use the file name prefix split\:. In that case files are split into files of 1 GB by default. An example database URL is\: jdbc\:h2\:split\:~/test. -advanced_1337_li=The maximum number of rows per table is 2'147'483'648. -advanced_1338_li=Main memory requirements\: The larger the database, the more main memory is required. With the default storage mechanism, the minimum main memory required for a 12 GB database is around 240 MB. With the page store (experimental), the minimum main memory required is much lower, around 1 MB for each 8 GB database file size. -advanced_1339_li=Limit on the complexity of SQL statements. Statements of the following form will result in a stack overflow exception\: -advanced_1340_li=There is no limit for the following entities, except the memory and storage capacity\: maximum identifier length (table name, column name, and so on); maximum number of tables, columns, indexes, triggers, and other database objects; maximum statement length, number of parameters per statement, tables per statement, expressions in order by, group by, having, and so on; maximum rows per query; maximum columns per table, columns per index, indexes per table, lob columns per table, and so on; maximum row length, index row length, select row length; maximum length of a varchar column, decimal column, literal in a statement. -advanced_1341_li=For limitations on data types, see the documentation of the respective Java data type or the data type documentation of this database. -advanced_1342_h2=Glossary and Links -advanced_1343_th=Term -advanced_1344_th=Description -advanced_1345_td=AES-128 -advanced_1346_td=A block encryption algorithm. See also\: Wikipedia\: AES -advanced_1347_td=Birthday Paradox -advanced_1348_td=Describes the higher than expected probability that two persons in a room have the same birthday. Also valid for randomly generated UUIDs. See also\: Wikipedia\: Birthday Paradox -advanced_1349_td=Digest -advanced_1350_td=Protocol to protect a password (but not to protect data). See also\: RFC 2617\: HTTP Digest Access Authentication -advanced_1351_td=GCJ -advanced_1352_td=Compiler for Java. GNU Compiler for the Java and NativeJ (commercial) -advanced_1353_td=HTTPS -advanced_1354_td=A protocol to provide security to HTTP connections. See also\: RFC 2818\: HTTP Over TLS -advanced_1355_td=Modes of Operation -advanced_1356_a=Wikipedia\: Block cipher modes of operation -advanced_1357_td=Salt -advanced_1358_td=Random number to increase the security of passwords. See also\: Wikipedia\: Key derivation function -advanced_1359_td=SHA-256 -advanced_1360_td=A cryptographic one-way hash function. See also\: Wikipedia\: SHA hash functions -advanced_1361_td=SQL Injection -advanced_1362_td=A security vulnerability where an application embeds SQL statements or expressions in user input. See also\: Wikipedia\: SQL Injection -advanced_1363_td=Watermark Attack -advanced_1364_td=Security problem of certain encryption programs where the existence of certain data can be proven without decrypting. For more information, search in the internet for 'watermark attack cryptoloop' -advanced_1365_td=SSL/TLS -advanced_1366_td=Secure Sockets Layer / Transport Layer Security. See also\: Java Secure Socket Extension (JSSE) -advanced_1367_td=XTEA -advanced_1368_td=A block encryption algorithm. See also\: Wikipedia\: XTEA -build_1000_h1=Build -build_1001_a=\ Portability -build_1002_a=\ Environment -build_1003_a=\ Building the Software -build_1004_a=\ Build Targets -build_1005_a=\ Using Maven 2 -build_1006_a=\ Translating -build_1007_a=\ Providing Patches -build_1008_a=\ Reporting Problems or Requests -build_1009_a=\ Automated Build -build_1010_a=\ Generating Railroad Diagrams -build_1011_h2=Portability -build_1012_p=\ This database is written in Java and therefore works on many platforms. It can also be compiled to a native executable using GCJ. -build_1013_p=\ For Java 1.4, the jar file needs to be converted first using Retrotranslator. -build_1014_h2=Environment -build_1015_p=\ To run this database, a Java Runtime Environment (JRE) version 1.5 or higher is required. -build_1016_p=\ To create the database executables, the following software stack was used. To use this database, it is not required to install this software however. -build_1017_li=Mac OS X and Windows XP -build_1018_a=Sun JDK Version 1.5 and 1.6 -build_1019_a=Eclipse Version 3.4 -build_1020_li=Eclipse Plugins\: Subclipse, Eclipse Checkstyle Plug-in, EclEmma Java Code Coverage 1.3.0 -build_1021_a=Emma Java Code Coverage -build_1022_a=Mozilla Firefox -build_1023_a=OpenOffice -build_1024_a=NSIS 2.38 -build_1025_li=\ (Nullsoft Scriptable Install System) -build_1026_a=Maven -build_1027_h2=Building the Software -build_1028_p=\ You need to install a JDK, for example the Sun JDK version 1.5 or 1.6. Ensure that Java binary directory is included in the PATH environment variable, and that the environment variable JAVA_HOME points to your Java installation. On the command line, go to the directory h2 and execute the following command\: -build_1029_p=\ For Linux and OS X, use ./build.sh instead of build. -build_1030_p=\ You will get a list of targets. If you want to build the jar file, execute (Windows)\: -build_1031_h3=Switching the Source Code -build_1032_p=\ By default the source code uses Java 1.5 features, however Java 1.6 is supported as well. To switch the source code to the installed version of Java, run\: -build_1033_h2=Build Targets -build_1034_p=\ The build system can generate smaller jar files as well. The following targets are currently supported\: -build_1035_code=jarClient -build_1036_li=\ creates the file h2client.jar. This only contains the JDBC client. -build_1037_code=jarSmall -build_1038_li=\ creates the file h2small.jar. This only contains the embedded database. Debug information is disabled. -build_1039_code=jarJaqu -build_1040_li=\ creates the file h2jaqu.jar. This only contains the JaQu (Java Query) implementation. All other jar files do not include JaQu. -build_1041_code=javadocImpl -build_1042_li=\ creates the Javadocs of the implementation. -build_1043_p=\ To create the file h2client.jar, go to the directory h2 and execute the following command\: -build_1044_h2=Using Maven 2 -build_1045_h3=Using a Central Repository -build_1046_p=\ You can include the database in your Maven 2 project as a dependency. Example\: -build_1047_p=\ New versions of this database are first uploaded to http\://hsql.sourceforge.net/m2-repo/ and then automatically synchronized with the main Maven repository; however after a new release it may take a few hours before they are available there. -build_1048_h3=Using Snapshot Version -build_1049_p=\ To build a h2-*-SNAPSHOT.jar file and upload it the to the local Maven 2 repository, execute the following command\: -build_1050_p=\ Afterwards, you can include the database in your Maven 2 project as a dependency\: -build_1051_h2=Translating -build_1052_p=\ The translation of this software is split into the following parts\: -build_1053_li=H2 Console\: src/main/org/h2/server/web/res/_text_*.prop -build_1054_li=Error messages\: src/main/org/h2/res/_messages_*.prop -build_1055_p=\ To translate the H2 Console, start it and select Preferences / Translate. After you are done, send the translated *.prop file to the Google Group. The web site is currently translated using Google. -build_1056_h2=Providing Patches -build_1057_p=\ If you like to provide patches, please consider the following guidelines to simplify merging them\: -build_1058_li=Only use Java 1.5 features (do not use Java 1.6) (see Environment). -build_1059_li=Follow the coding style used in the project, and use Checkstyle (see above) to verify. For example, do not use tabs (use spaces instead). The checkstyle configuration is in src/installer/checkstyle.xml. -build_1060_li=A template of the Eclipse settings are in src/installer/eclipse.settings/*. If you want to use them, you need to copy them to the .settings directory. The formatting options (eclipseCodeStyle) are also included. -build_1061_li=Please provide test cases and integrate them into the test suite. For Java level tests, see src/test/org/h2/test/TestAll.java. For SQL level tests, see src/test/org/h2/test/test.in.txt or testSimple.in.txt. -build_1062_li=The test cases should cover at least 90% of the changed and new code; use a code coverage tool to verify that (see above). or use the build target coverage. -build_1063_li=Verify that you did not break other features\: run the test cases by executing build test. -build_1064_li=Provide end user documentation if required (src/docsrc/html/*). -build_1065_li=Document grammar changes in src/docsrc/help/help.csv -build_1066_li=Provide a change log entry (src/docsrc/html/changelog.html). -build_1067_li=Verify the spelling using build spellcheck. If required add the new words to src/tools/org/h2/build/doc/dictionary.txt. -build_1068_li=Run src/installer/buildRelease to find and fix formatting errors. -build_1069_li=Verify the formatting using build docs and build javadoc. -build_1070_li=Submit patches as .patch files (compressed if big). To create a patch using Eclipse, use Team / Create Patch. -build_1071_p=\ For legal reasons, patches need to be public in the form of an email to the group, or in the form of an issue report or attachment. Significant contributions need to include the following statement\: -build_1072_p=\ "I wrote the code, it's mine, and I'm contributing it to H2 for distribution multiple-licensed under the H2 License, version 1.0, and under the Eclipse Public License, version 1.0 (http\://h2database.com/html/license.html)." -build_1073_h2=Reporting Problems or Requests -build_1074_p=\ Please consider the following checklist if you have a question, want to report a problem, or if you have a feature request\: -build_1075_li=Feature requests are always welcome, even if the feature is already on the roadmap. Your mail will help prioritize feature requests. If you urgently need a feature, consider providing a patch. -build_1076_li=Before posting problems, check the FAQ and do a Google search. -build_1077_li=When got an unexpected exception, please try the Error Analyzer tool. If this doesn't help, please report the problem, including the complete error message and stack trace, and the root cause stack trace(s). -build_1078_li=When sending source code, please use a public web clipboard such as Pastebin, Cl1p, or Mystic Paste to avoid formatting problems. Please keep test cases as simple and short as possible, but so that the problem can still be reproduced. As a template, use\: HelloWorld.java. Method that simply call other methods should be avoided, as well as unnecessary exception handling. Please use the JDBC API and no external tools or libraries. The test should include all required initialization code, and should be started with the main method. -build_1079_li=For large attachments, use a public temporary storage such as Rapidshare. -build_1080_li=Google Group versus issue tracking\: Use the Google Group for questions or if you are not sure it's a bug. If you are sure it's a bug, you can create an issue, but you don't need to (sending an email to the group is enough). Please note that only few people monitor the issue tracking system. -build_1081_li=For out-of-memory problems, please analyze the problem yourself first, for example using the command line option -XX\:+HeapDumpOnOutOfMemoryError and a memory analysis tool such as the Eclipse Memory Analyzer (MAT). -build_1082_li=It may take a few days to get an answers. Please do not double post. -build_1083_h2=Automated Build -build_1084_p=\ This build process is automated and runs regularly. The build process includes running the tests and code coverage, using the command line ./build.sh clean jar coverage -Dh2.ftpPassword\=... uploadBuild. The last results are available here\: -build_1085_a=Test Output -build_1086_a=Code Coverage Summary -build_1087_a=Code Coverage Details (download, 1.3 MB) -build_1088_a=Build Newsfeed -build_1089_a=Latest Jar File (download, 1 MB) -build_1090_h2=Generating Railroad Diagrams -build_1091_p=\ The railroad diagrams are HTML, formatted as nested tables. The diagrams are generated as follows\: -build_1092_li=The BNF parser (org.h2.bnf.Bnf) reads and parses the BNF from the file help.csv. -build_1093_li=The page parser (org.h2.server.web.PageParser) reads the template HTML file and fills in the diagrams. -build_1094_li=The rail images (one straight, four junctions, two turns) are generated using a simple Java application. -build_1095_p=\ To generate railroad diagrams for other grammars, see the package org.h2.jcr. This package is used to generate the SQL-2 railroad diagrams for the JCR 2.0 specification. -changelog_1000_h1=Change Log -changelog_1001_h2=Next Version (unreleased) -changelog_1002_li=- -changelog_1003_h2=Version 1.2.137 (2010-06-06) -changelog_1004_li=Statements with a nested query and a condition that was always NULL threw an IndexOutOfBoundsException. Example\: select * from (select null as x) where x\=1 -changelog_1005_li=Experimental feature to support very large transactions (except when using MVCC). To enable, set the system property h2.largeTransactions to true. If enabled, changes to tables without a primary key can be buffered to disk. The plan is to enable this feature by default in version 1.3.x. -changelog_1006_li=H2 Console\: editing result sets is now also working for database other than H2, if they do support updatable result sets. Add "@edit" before the query. Only limited testing has been done on this feature, some data types may not work (please provide feedback if you find issues). -changelog_1007_li=Cluster\: an open transaction was committed when a cluster node was stopped (because disabling the cluster executes SET CLUSTER '', which committed the transaction). Transaction are no longer committed when calling SET CLUSTER. Issue 199. -changelog_1008_li=Cluster\: non-admin users couldn't connect to the cluster and couldn't disable the cluster. Issue 201. -changelog_1009_li=Cluster\: NEXTVAL('sequence') was only called on one cluster node, therefore sequence values could get out of sync. -changelog_1010_li=Version 1.2.136 could not be converted to Java 1.4 (because the Retrotranslator doesn't support BigDecimal.precision). A workaround has been implemented. -changelog_1011_li=The error code of IO exceptions in CSV functions was incorrect. -changelog_1012_li=The TriggerPassData example now uses a prefix (the database name). -changelog_1013_li=The wrong exception was thrown when trying to reference a table that doesn't support references such as a table in the information schema. -changelog_1014_li=Server.shutdownTcpServer can now stop all TCP servers on this JVM. -changelog_1015_li=JdbcConnectionPool\: the default connection timeout is now 30 seconds (it used to be 5 minutes). -changelog_1016_li=LOB storage\: LOBs added with "h2.lobInDatabase" enabled couldn't be read later with this option disabled. -changelog_1017_h2=Version 1.2.136 (2010-05-24) -changelog_1018_li=When using ORDER BY and there are both ascending and descending indexes, the database used the first index even when the second one could be used for sorting. -changelog_1019_li=Conditions of the form columnName IS NULL now use an index. To disable this feature, set the system property h2.optimizeIsNull to false. -changelog_1020_li=H2 Console\: when the settings were not stored yet (for example when running for the first time), the last recently used settings were not stored. A workaround was to create the file ".h2.server.properties" manually in the current user home directory, with the contents\: webAllowOthers\=false, webPort\=8082, webSSL\=false, 0\=Generic H2 (Embedded)|org.h2.Driver|jdbc\\\:h2\\\:~/test|sa (where a comma is a newline). -changelog_1021_li=The source code is now switched to Java 6 (JDK 1.6) by default. Java 5 (JDK 1.5) is still supported, and the jar file is still compiled for Java 5. -changelog_1022_li=The BOM (the byte-order-mark) character 0xfeff at the beginning of the file is ignored. This is for compatibility with Microsoft Excel. -changelog_1023_li=When opening an existing database, the cache size is set to at most half the amount of memory available for the virtual machine (Runtime.getRuntime().maxMemory()), even if the cache size setting stored in the database is larger. Setting the cache size in the database URL or explicitly using SET CACHE_SIZE overrides this value (even if larger than the physical memory). -changelog_1024_li=INFORMATION_SCHEMA.SETTINGS\: the cache size is now returned in KB. -changelog_1025_li=New system property h2.selectForUpdateMvcc, the default is false (the feature is disabled). When enabled, SELECT ... FOR UPDATE only locks the selected rows in the MVCC mode. Aggregate or GROUP BY queries are not allowed in this case. -changelog_1026_li=Profiler\: improved message if there was no stack trace. -changelog_1027_li=The H2 Console can now be used within another application, in a frame or iframe. Issue 197. -changelog_1028_li=Recover tool\: the statistics section now includes page type counts again. -changelog_1029_li=Queries with multiple IN(...) conditions sometimes return the wrong results when there was a multi-column index for the column. -changelog_1030_li=Queries with IN(..., NULL) did sometimes return the wrong results when there was a index for the column. -changelog_1031_li=DECIMAL\: faster precision and memory usage calculations. -changelog_1032_li=A new class org.h2.tools.TriggerAdapter allows to use the ResultSet interface within trigger implementations. -changelog_1033_li=A subselect which used an index could lead to wrong results. Fixed. -changelog_1034_li=Creating a cached temporary non persistent table with a primary key threw a NullPointerException. -changelog_1035_h2=Version 1.2.135 (2010-05-08) -changelog_1036_li=Temporary files were not deleted when using large transactions, disabling autocommit, and closing the session without committing. -changelog_1037_li=Queries using multiple IN(..) conditions on the same table could cause repeated rows in the result set. -changelog_1038_li=Translation\: Lubomir Grajciar translated the H2 Console as well as all error message to Slovensky. Thanks a lot\! -changelog_1039_li=There was a possible Java level deadlock when opening an uninitialized database and using a file system that also opened a database. -changelog_1040_li=When killing the process while the database was writing a checkpoint, while it was closing, or while running recovery (while removing temporary tables from a previous run), the database could become corrupt. A new test case has been implemented to ensure such problems can not occur in the future. -changelog_1041_li=File system\: new method FileSystem.setReadOnly. -changelog_1042_li=The page size for new databases can now be set in the database URL using ;PAGE_SIZE\=512. Currently this feature is only used to simplify testing. -changelog_1043_li=New system property h2.functionsInSchema (default is false). If enabled, the SCRIPT statement always includes the schema name in the CREATE ALIAS statement (even if the schema is PUBLIC). This is not backward compatible with H2 versions 1.2.134 and older. -changelog_1044_li=Functions\: it is no longer required to add a space after a comma in the parameter list. Example\: CREATE ALIAS PARSE_INT FOR "java.lang.Integer.parseInt(java.lang.String,int)" -changelog_1045_li=Functions now reside within a schema, similar to sequences. If you do create such functions in schemas other than PUBLIC, then the database can not be opened with older versions of H2. -changelog_1046_li=Cluster\: after a cluster node failed, the second cluster node can now be re-created and started without having to stop the first cluster node, and without having to stop running applications. To do that, append ;AUTO_RECONNECT\=TRUE to the database URL. -changelog_1047_li=Auto-reconnect\: if another connection uses the database in exclusive mode then this connection will try to re-connect until the exclusive mode ends. This is important when using the cluster mode. -changelog_1048_li=SET EXCLUSIVE now supports 0 (disable), 1 (enable), and 2 (enable and close all other connections). -changelog_1049_li=Installing the H2 as a service should now work on Windows 7. The batch files now explicitly set the directory using pushd "%~dp0". -changelog_1050_li=Temporary tables can now be 'cached', that means indexes of temporary tables can be persisted. This enables very large temporary tables (both local and global). -changelog_1051_li=The CreateCluster tool now sets the source database in exclusive mode before copying data to the new database. -changelog_1052_li=The H2 Console now stream results one statement / result set at a time (using chunked transfer encoding). To disable, set the system property h2.consoleStream to false. This feature is not supported when using a servlet container. -changelog_1053_li=The H2 Console did not call the CreateCluster tool with the correctly escaped parameters. -changelog_1054_li=Improved PostgreSQL compatibility for ALTER TABLE ALTER COLUMN. -changelog_1055_li=Commas at the end of INSERT ... VALUES (), (), are now supported. -changelog_1056_li=The H2 Console "Start Browser" button now works even when the IP address changes while the tool runs (for example, because a wireless connection breaks, or when enabling / disabling the network connection). -changelog_1057_li=When casting from float or double to BigDecimal, the result was sometimes unexpected, because "new BigDecimal(double val)" was used. Now "BigDecimal.valueOf(double val)" and "new BigDecimal(Float.toString(f))" are used. But it is still not recommended to use float or double for currency values (see data type documentation). -changelog_1058_li=Global temporary tables are now deleted when closing the database. Before, they were deleted when opening the database the next time. -changelog_1059_li=UNIQUE was not listed as a keyword. -changelog_1060_li=Improved error message when an non-SQL-exception occurred in a user defined function. The method name and parameters are included in the error message. -changelog_1061_li=For some queries, the exception did not include the SQL statement. Example\: select x from system_range(1, 2) group by 'a'. -changelog_1062_li=The Shell tool will execute SQL statements passed as using the command line parameter -sql. -changelog_1063_li=If InetAddress.getLocalHost() fails, the database should now throw an exception. -changelog_1064_li=New columns INFORMATION_SCHEMA.INDEXES.INDEX_CLASS and INFORMATION_SCHEMA.TABLES.TABLE_CLASS. -changelog_1065_li=INFORMATION_SCHEMA.INDEXES.SQL now contains the CREATE INDEX statement instead of just the fully qualified index name. -changelog_1066_h2=Version 1.2.134 (2010-04-23) -changelog_1067_li=New system property h2.analyzeAuto (default 0 meaning disabled) to automatically run ANALYZE after that many changes to a table. For details, see the Javadoc of this system property. The plan is to set this property to 2000 in version 1.3.x. -changelog_1068_li=JdbcXAConnection.start() does not support TMJOIN. Issue 189. -changelog_1069_li=MySQL compatibility\: TIMESTAMPDIFF is now an alias for DATEDIFF. -changelog_1070_li=MERGE did not respect foreign key and check constraints. -changelog_1071_li=ALTER TABLE ALTER COLUMN\: changing the data type of a column no longer makes it nullable. -changelog_1072_li=When using AUTO_SERVER\=TRUE, the server is now started as a daemon thread. This was a problem when using Tomcat and a connection pool. -changelog_1073_li=Servers can now be started as a daemon thread using the command line options -tcpDaemon, -pgDaemon, and -webDaemon. -changelog_1074_li=H2 Console\: the built-in commands are now documented. -changelog_1075_li=REPLACE\: if any parameter is null, the result is null. -changelog_1076_li=Queries with DISTINCT and ORDER BY will now use the index on ORDER BY if possible. This is specially important for queries used inside IN(SELECT ...). -changelog_1077_li=The new statement EXPLAIN ANALYZE executes the statement, and displays the query plan with the actual row scan count for each table. -changelog_1078_li=H2 Console\: the auto-complete feature didn't quote column names that need quoting. Issue 186. -changelog_1079_li=The experimental LOB storage mechanism now supports all features of the old one. To use it, set the system property "h2.lobInDatabase" to "true". If you have used this feature in version 1.2.133, you need to export and re-import the database using SCRIPT / RUNSCRIPT. -changelog_1080_li=The functions isBeforeFirst() and isAfterLast() were not compliant to the JDBC spec. If the ResultSet contains no rows, they must return false. Fixed. -changelog_1081_li=Filesystem parameters like "split\:" didn't work in server mode with baseDir set. -changelog_1082_li=If baseDir is set, and a database name is given which points to a directory outside the baseDir (eg. "../dbname"), an exception is thrown. -changelog_1083_h2=Version 1.2.133 (2010-04-10) -changelog_1084_li=A new experimental LOB storage mechanism is available. When enabled, CLOB and BLOB data is stored in hidden tables in the database. To use it, set the system property "h2.lobInDatabase" to "true". Compression is not yet implemented. Duplicate objects are only stored once. Usually writing is slower, but reading is faster (mainly because of caching). -changelog_1085_li=The Shell tool threw a NumberFormatException on a empty statement. -changelog_1086_li=The h2small-*.jar did not support "drop all objects delete files". Now it is supported (the DeleteDbFiles tool is now included). -changelog_1087_li=Operations that don't fit in memory are now faster. Temporary file handling was changed. -changelog_1088_li=The default maximum log stream size is now 2 MB. This is a good value according to some performance tests. -changelog_1089_li=New system property "h2.syncMethod" to configure what method to call when closing the database, on checkpoint, and on CHECKPOINT SYNC. The default is "sync" which calls RandomAccessFile.getFD().sync(). -changelog_1090_li=ROWNUM could not be used for pagination. The follow query returned no rows\: select x from (select *, rownum as r from system_range(1, 3)) where r\=2; -changelog_1091_li=Workaround for a java.sql.Date issue\: years above 9999 are not formatted correctly. When calling ResultSet.getString() on a date value, an alternative formatting algorithm is used. -changelog_1092_li=Prepared statements with nested subqueries did not always return the correct result. Example\: select ?, ?, (select count(*) from test t, (select id from test where 0\=?) t2 where t2.id\=t.id) from test -changelog_1093_li=When using MULTI_THREADED\=TRUE, the exception following exception could be thrown\: "object already exists\: TABLES" -changelog_1094_li=Comparison of integer columns against float numbers was not always correct. Issue 182. -changelog_1095_li=H2 Console\: Editing the result of a multi-line queries failed. Issue 183. -changelog_1096_li=H2 Console\: if the settings file (.h2.properties) can't be accessed, the exception is now ignored. -changelog_1097_h2=Version 1.2.132 (2010-03-21) -changelog_1098_li=The implementation of a Java to C (source code level) converter has been started. The plan is\: it should be possible to convert H2 (or a part of it) to C so that the database can be run without a JVM. This will be a long term project (it may take a year or so). -changelog_1099_li=User defined table implementation can now be used using CREATE TABLE ... ENGINE. Thanks to Sergi Vladykin for implementing this feature\! -changelog_1100_li=Improved MS SQL Server compatibility\: support string concatenation using "+". Thanks to Stepan for the patch\! -changelog_1101_li=When using the multi-threaded mode, running ANALYZE concurrently in multiple connections could throw an exception. -changelog_1102_li=The MERGE statement is now about 30% faster when using a PreparedStatement. -changelog_1103_li=Multi-column indexes where the second or later column was descending did not always produce correct results (rows were missing in the result set, or the result set was empty). -changelog_1104_li=When using large transactions or a small log size, the database could get very slow (profiling shows the hotspot is in FileObjectDisk.sync()). -changelog_1105_li=The Shell tool now prints the stack trace when the list mode is enabled. -changelog_1106_li=CREATE ALIAS ... AS\: Compilation was incorrect if the source code contained characters that are not supported by the default file encoding. -changelog_1107_li=Issue 176\: the JdbcDataSource now also supports a 'description' property. -changelog_1108_li=The Shell tool threw a ArrayIndexOutOfBoundsException after 20 statements. -changelog_1109_li=When using the small version of H2 ('jarClient'), the first call to Connection.createBlob (or similar) could throw a ClassNotFoundException because the file org.h2.store.fs.FileSystemZip is not included. This missing class is now ignored. -changelog_1110_li=Literals of type BIGINT now have the correct data type. -changelog_1111_h2=Version 1.2.131 (2010-03-05) -changelog_1112_li=Older versions of H2 (version 1.2.127 and older) could not connect to a new version (version 1.2.129 and newer). The connection blocked when trying to connect. Now the connection no longer blocks, instead a SQL exception is thrown. -changelog_1113_li=In versions 1.2.129 and 1.2.130, a database could not be opened sometimes after dropping tables or indexes, and then creating new indexes for existing tables. The exception contained the text "parent not found" (version 1.2.129) or "Table not found" (version 1.2.130). -changelog_1114_li=After the database was closed, a null pointer exception could occur in Database.flush. -changelog_1115_li=An ArrayIndexOutOfBoundsException could occur in the page store (eg. on "delete from table"). Fixed. -changelog_1116_h2=Version 1.2.130 (2010-02-26) -changelog_1117_li=EXPLAIN\: The query plan now contains ".tableScan" if a table scan is used. -changelog_1118_li=IN(..)\: when combining and IN(..) condition with a condition that didn't use an index, the result could contain duplicate rows. -changelog_1119_li=IN(..)\: the index was not used if there were multiple IN(..) conditions. -changelog_1120_li=For foreign key constraints, the metadata column INFORMATION_SCHEMA.INDEXES.CONSTRAINT_NAME was not set for non-unique indexes. -changelog_1121_li=PostgreSQL compatibility\: when using the following exception was thrown\: Column "T.TYPTYPMOD" not found. Fixed. This is only when using psqlodbc_08_04*. -changelog_1122_li=A tool to migrate an old database from the non-page store format to the newest version has been added in src/tools/org/h2/dev/util/Migrate.java. This file is not included in the jar file currently. -changelog_1123_li=When using temporary tables, the database didn't shrink sometimes when closing. Also, sometimes a database could not recover normally. -changelog_1124_li=Large transactions could run out of heap space. The maximum size of a transaction is now much larger. -changelog_1125_li=The default setting for the system property h2.webMaxValueLength is now 100000 (it was 10000 before). -changelog_1126_li=Creating a database was delayed about 2 seconds if the directory didn't exist. -changelog_1127_li=Implemented INIT feature. If the database URL contains ";INIT\=...;" then the DDL or DML commands following are executed on startup. Example URL\: jdbc\:h2\:mem\:test;INIT\=RUNSCRIPT FROM '~/create.sql' (patch from Kerry Sainsbury). -changelog_1128_h2=Version 1.2.129 (2010-02-19) -changelog_1129_li=The methods of the CloseListener are added to the Trigger interface. The interface CloseListener is removed. This is potentially a breaking change for existing triggers. -changelog_1130_li=CREATE ALIAS\: error message when compiling Java code have been improved. -changelog_1131_li=MVCC\: creating a table with an incorrect constraint could cause strange errors. -changelog_1132_li=Hash indexes now are only used for single column indexes. -changelog_1133_li=The cache types WEAK_* and TQ are no longer supported. A weak reference cache never frees up memory so it's the same as having a very large cache size. The TQ cache was not included in the jar file since a longer time, and was not tested. -changelog_1134_li=The file system abstraction no longer throws SQL exceptions. -changelog_1135_li=DatabaseEventListener.diskSpaceIsLow has changed. -changelog_1136_li=The CompressTool no longer throw as SQL exceptions. Instead, it throws runtime exceptions. -changelog_1137_li=SimpleResultSet.addColumn and addRow now can throw a IllegalStateException instead of a SQLException. -changelog_1138_li=When doing an index lookup, decimal values with the same value but different scale (for example 0.00 and 0.0) where not considered equal in version 1.2.128. Now they are (unlike BigDecimal.equals()). -changelog_1139_li=The BNF parser now uses the visitor pattern. -changelog_1140_li=Converting a UUID to bytes was incorrect. Because of that, updatable result sets on tables with UUID primary key did not work. -changelog_1141_li=The database URL property DATABASE_EVENT_LISTENER_OBJECT is no longer supported (there are problems passing objects when the PostgreSQL driver is installed as well). -changelog_1142_li=H2 Console\: asynchronous login (using a DatabaseEventListener) is no longer supported. -changelog_1143_li=A workaround for a Windows socket problem has been implemented. Thanks a lot to Sergi Vladykin. -changelog_1144_li=The Recover tool did not convert correctly convert CLOB data with non-ASCII characters. -changelog_1145_li=Tools\: the method run(String... args) has been renamed to runTool(String... args). -changelog_1146_li=Server.startWebServer(Connection) was not working as expected. -changelog_1147_li=The database URL option ACCESS_MODE_LOG is no longer supported. -changelog_1148_li=The database URL option RECOVER has currently no effect. -changelog_1149_li=Converting an old (non-page store) database is no longer supported using this version. -changelog_1150_li=The following system properties are no longer supported\: h2.overflowExceptions, h2.optimizeDropDependencies, h2.optimizeGroupSorted, h2.optimizeMinMax, h2.optimizeNot, h2.optimizeIn, h2.optimizeInJoin, h2.reuseSpace*. Most of then were there for a long time, but always with the same value. There was no unit test with the other value. So changing them was potentially dangerous (not a lot, but still). -changelog_1151_li=The setting LOG has currently no effect (it only had an effect when the page store was disabled). -changelog_1152_li=Disabling the page store is no longer supported. The old storage mechanism has been removed, shrinking the jar file size by almost 10%. -changelog_1153_li=The translated resources are now stored in UTF-8 format. -changelog_1154_li=The Windows service wrapper now detects if multiple versions of H2 are installed. -changelog_1155_h2=Version 1.2.128 (2010-01-30) -changelog_1156_li=There are known errors on rollback when the page store is disabled and at the same time MVCC is used. See http\://code.google.com/p/h2database/issues/detail?id\=158 -changelog_1157_li=The DeleteDbFiles tool deleted all files in the .lob.db directory, even files that didn't belong to the database. -changelog_1158_li=Automatic conversion of old databases to the page store format failed if the database contained LOB files. -changelog_1159_li=Nested subqueries didn't work for INSERT INTO and IN(..). Example\: insert into test ((select 1)); -changelog_1160_li=If the database was already closed using SHUTDOWN IMMEDIATELY, closing a second connection could throw a NullPointerException if there was a local temporary table. -changelog_1161_li=Less classes are loaded when using the database in embedded mode. -changelog_1162_li=The information schema tables are only initialized when needed. This reduces memory usage and speeds up creating in-memory databases. Each in-memory database needs about 8 KB of heap memory. -changelog_1163_li=Nested UNION/INTERSECT queries with brackets could produce the wrong result if used within a subquery. Example\: select count(*) from (select 1 union (select 2 intersect select 2)) x; -changelog_1164_li=Comparing an column against a constant expression with a higher precision or length than the column could give wrong results (the expression was truncated before comparing). -changelog_1165_li=Improved PostgreSQL compatibility (support SHOW DEFAULT_TRANSACTION_ISOLATION). -changelog_1166_li=Documentation\: the javadocs for Csv.write and read used the wrong default charset. -changelog_1167_li=MVCC\: if the table was locked in exclusive mode (such as SELECT ... FOR UPDATE), another session could query the table. This is now longer possible. -changelog_1168_li=If a FOR UPDATE query was executed twice (using a PreparedStatement), the table was not locked. -changelog_1169_li=Triggers\: INSTEAD OF triggers are now supported. Such triggers can be defined on views. -changelog_1170_li=New system property h2.identifiersToUpper. If set to false, identifiers in SQL statements are case sensitive even if they are not quoted. -changelog_1171_li=Slightly improved performance if the table is already locked. -changelog_1172_li=CompressLZF\: faster decompression. -changelog_1173_li=PgServer\: the wrong size was sent for VARCHAR data. Thanks again to Sergi Vladykin for the patch. -changelog_1174_li=Serialized access mode (server-less multi-connection mode)\: fixed getGeneratedKeys() for sequences. -changelog_1175_h2=Version 1.2.127 (2010-01-15) -changelog_1176_li=Serialized access mode (server-less multi-connection mode)\: sequences did not work as expected (there were gaps in generated values when using multiple connections). -changelog_1177_li=Page store\: new databases can not be opened with older versions. -changelog_1178_li=Page store\: adding data to new database is now faster. -changelog_1179_li=File system\: getting the file name from a path is now faster. This should speed up BLOB and CLOB access. -changelog_1180_li=PgServer\: incorrect SQL types were returned in result set meta data. Concurrently opening a database could fail (PG catalog initialization was not synchronized). Thanks a lot to Sergi Vladykin for providing the patches\! -changelog_1181_li=SHOW COLUMNS did not work correctly if there where multiple indexes on the same columns. -changelog_1182_li=Page store\: the wrong write count was written to the database header. This could cause the server-less multi-connection mode to fail. -changelog_1183_li=Result sets larger than 2 GB threw an exception "Negative seek offset". Fixed. -changelog_1184_li=If the system property h2.check was set to false, an ArrayIndexOutOfBoundsException could occur. -changelog_1185_li=Alter table is now supported even if a table has views defined. -changelog_1186_li=Fulltext search\: exceptions within the fulltext search package had the wrong SQL state. -changelog_1187_li=The Lucene fulltext search ignored transaction rollback. Fixed using a trigger on rollback. -changelog_1188_li=Trigger can now be called on rollback. -changelog_1189_li=The shell script h2.sh ignored command line line arguments. -changelog_1190_li=When running H2 in the Google AppEngine for Java, a AccessControlException could be thrown when trying to open a read-only database. Fixed. -changelog_1191_li=The user home directory prefix (~) is now only expanded when followed by a slash or backslash, or standing alone. -changelog_1192_li=Native fulltext search\: before inserting or deleting data, FT_INIT() had to be called. This is no longer required. -changelog_1193_li=The .trace.db file is now only created if required. -changelog_1194_li=Shell tool\: improved PostgreSQL compatibility. -changelog_1195_li=Trying to open a database in read-only mode when a .lock.db file exists will now fail with a nice error message. -changelog_1196_li=H2 Console\: data that is too long is now abbreviated as follows\: text... (100000 characters). A large binary is abbreviated as follows\: abcdef... (100000 bytes). -changelog_1197_li=Faster data conversion from BIGINT or INT to DECIMAL. -changelog_1198_li=Server-less multi-connection mode\: try to delete log files if switching between read/write operations. -changelog_1199_li=CompressLZF\: Faster decompress and improved javadocs -changelog_1200_h2=Version 1.2.126 (2009-12-18) -changelog_1201_li=The ChangeFileEncryption tool will now fail with an exception if the database is still in use. The Backup tool will also fail except when running in quiet mode. -changelog_1202_li=CSVREAD\: when reading the column names from the CSV file, column names that contain no special characters are considered case insensitive now. -changelog_1203_li=Optimization index conditions of the form 'column\=NULL' (which is always false; unlike 'column IS NULL'). -changelog_1204_li=Script command and tool\: the primary key constraint is now listed before inserting the data. This will result in a smaller database when using the page store. -changelog_1205_li=Statements with IN(SELECT..) conditions could produce the wrong result. Example\: index on id, name; query\: select * from test where id between 1 and 3 and name in (select 'World'). -changelog_1206_li=Statements with IN(..) conditions could produce the wrong result when using views or nested select statements. Example\: index on id; index on name; query\: select * from (select * from test) where id\=1 and name in('a', 'b'). select * from (select * from test) where id\=1 and name in('Hello', 'World'). -changelog_1207_li=Page store\: a rollback of a relatively large transaction could fail with an ArrayIndexOutOfBoundsException or a 'row not found' exception in the PageBtreeIndex in some cases. -changelog_1208_li=JaQu\: the decompiler has been improved, and a few test cases already work. It is still incomplete however. -changelog_1209_li=LIKE\: any letter is now allowed after the escape character (which is still '\\' by default). Previously, an exception was thrown (unlike other databases) if it was not the escape character, '_' or '%'. If the escape character appears at the end of the pattern, the result is it is ignored (like PostgreSQL and MS SQL Server). -changelog_1210_li=The reserve heap memory is no longer used. -changelog_1211_li=Database.checkpoint() could throw a NullPointerException. -changelog_1212_h2=Version 1.2.125 (2009-12-06) -changelog_1213_li=Lucene fulltext search\: the Lucene field names now match the table column names, except if the column names start with _ (in which case another _ is prepended). Unfortunately this change means existing fulltext indexes need to be re-built. -changelog_1214_li=The shell tool now has a very simple statement history. -changelog_1215_li=The zip file system implementation now supports the '~' home directory prefix. Example database URL\: jdbc\:h2\:zip\:~/test.zip\!/test -changelog_1216_li=Right outer joins on tables that were already 'inner joined' was processed incorrectly. -changelog_1217_li=Temporary files from LOB objects were not deleted early enough when using the server mode. -changelog_1218_li=Trying to alter a temporary table threw a strange exception. It is still not possible to do that, but the exception message is better now. -changelog_1219_li=When the system property h2.maxMemoryRowsDistinct was set, and using SELECT DISTINCT, the temporary table was not correctly dropped. This could cause problems in recovery when the process was killed. -changelog_1220_li=Trigger that are called before a select statement are now supported. This allows to create tables that work like materialized views. -changelog_1221_li=Non-row based triggers were called even if the action didn't match the declared action (INSERT triggers were also called when deleting rows). This has been changed. The MERGE statement calls both INSERT and DELETE triggers. -changelog_1222_li=Statements with IN(..) conditions could produce the wrong result or a data conversion error (since version 1.2.120). Examples\: index on id, name, condition\: id\=1 and name in('Hello', 'x'); index on id, query\: select * from (select * from test) where id\=1 and name in('Hello', 'World'). -changelog_1223_li=The CompressTool was not multithreading safe. Because of this, the following database operations where also not multithreading safe (even when using different databases)\: the SCRIPT command (only when using compression), the COMPRESS function, and storing CLOB or BLOB data (only when compression is enabled). -changelog_1224_li=The compression algorithm "LZF" is now about 33% faster than before when compressing small block (around 2 KB). It is much faster than Deflate, but the compression ratio is lower. Some of the optimizations are from Sam Van Oort, thanks a lot\! -changelog_1225_li=Compressing large blocks of data didn't work when using the "Deflate" compression algorithm. Compressing a lot of data could run out of heap memory. -changelog_1226_li=The test cases don't access the file system directly, this simplifies GAE for Java testing. Thanks to Vince Bonfanti. -changelog_1227_li=More bugs in the server-less multi-connection mode have been fixed. -changelog_1228_li=When running against an old database, the SCRIPT statement could generate a SQL script that contained duplicate indexes (PRIMARY_KEY_E). -changelog_1229_li=JdbcConnectionPool.getConnection() could throw a NullPointerException. -changelog_1230_li=User defined functions\: the source code is now available using SELECT SOURCE FROM INFORMATION_SCHEMA.FUNCTION_ALIASES. -changelog_1231_li=User defined functions with source code didn't work after re-opening the database. -changelog_1232_li=The newsfeeds are now Atom 1.0 standard compliant. -changelog_1233_li=The database is now closed after an out of memory exception, because the database could get corrupt otherwise. -changelog_1234_li=Better error message if both AUTO_SERVER and SERIALIZED parameters are set to TRUE. -changelog_1235_li=Drop table did not delete lob files in old file store (not PAGE_STORE). -changelog_1236_h2=Version 1.2.124 (2009-11-20) -changelog_1237_li=Clustering\: there is now a way to detect which cluster instances are running. -changelog_1238_li=ConvertTraceFile\: the SQL statement statistics are better formatted (newline are removed). -changelog_1239_li=The file lock thread is now stopped when the database is closed. -changelog_1240_li=Issue 140\: the Script tool now supports writing to a stream. -changelog_1241_li=Issue 138\: the trace output of Statement.execute(String, int) and executeUpdate was incorrect. -changelog_1242_li=Page store\: new databases can not be opened with older versions. -changelog_1243_li=Page store\: multi-column indexes didn't work if the cache was very small. -changelog_1244_li=Page store\: opening a database could theoretically result in an endless loop. -changelog_1245_li=Page store\: adding large indexed columns could get very slow. -changelog_1246_li=Page store\: after a duplicate key exception, an ArrayIndexOutOfBoundsException could be thrown (only for very large rows). -changelog_1247_li=Page store\: the recover tool sometimes generated a script file that contained duplicate data. -changelog_1248_li=Page store\: sometimes opening a read-only database failed. -changelog_1249_li=Page store\: opening a database sometimes failed if large rows where updated, or if a table was truncated before. -changelog_1250_li=Page store\: when using a very small page size (128 bytes or smaller), writing a large row could result in an endless recursion. This is only a theoretical problem, as the page size is 2 KB. -changelog_1251_li=Page store\: getting the min value from a descending index with NULL entries could return the wrong result. -changelog_1252_li=Page store\: improved auto-recovery after power failure. -changelog_1253_li=The JDBC client did not detect that it was not talking to an H2 server. This could result in strange exceptions when trying to connect to another kind of server. -changelog_1254_li=User defined functions can be created with source code. Example\: CREATE ALIAS HI AS 'String hi() { return "Hello"; }' -changelog_1255_li=Database file lock\: the exception "lock file modified in the future" is no longer thrown; instead, opening the file will be delayed by 2 seconds. -changelog_1256_li=Inserting LOBs got slower each time the process was restarted. It could loop endlessly after about 1000 process restarts. -changelog_1257_li=Issue 117\: Multi-version concurrency\: concurrent MERGE statements now work. -changelog_1258_li=Improved read-only database detection. -changelog_1259_h2=Version 1.2.123 (2009-11-08) -changelog_1260_li=Page store\: new databases can not be opened with older versions. -changelog_1261_li=Page store\: updating large rows (rows with more than 2000 bytes of data) could corrupt the database. -changelog_1262_li=Page store\: inserting very large rows failed with ArrayIndexOutOfBoundsException. -changelog_1263_li=When using multi-threaded kernel mode, setting disabling locking (LOCK_MODE\=0) will now throw an exception. At this time this combination will result in corruption when multiple threads try to update the same table. -changelog_1264_li=The fulltext search methods and fields are now protected instead of private, to make the classes more easily extensible. -changelog_1265_li=The Lucene fulltext search now also returns the score. -changelog_1266_li=\ New function SCOPE_IDENTITY() to avoid problems when inserting rows in a trigger. -changelog_1267_li=Statement.getGeneratedKeys() returned the wrong value if a trigger changed the identity value after inserting the row. -changelog_1268_li=Improved error messages\: identifiers and values are now quoted. -changelog_1269_li=Improved error message when casting a value failed\: the column name and type is included in the message. -changelog_1270_li=Improved support for GAE for Java thanks to Vince Bonfanti. -changelog_1271_h2=Version 1.2.122 (2009-10-28) -changelog_1272_li=The native fulltext search now supports streaming CLOB data. -changelog_1273_li=If the database URL ends with ;PAGE_STORE\=TRUE and a database in the old format exists, it is automatically converted to the new page store format if possible. A backup of the database is created first. Automatic conversion is not supported if the database was not closed normally (if it contains uncommitted transactions). -changelog_1274_li=Dropping the current user is now allowed if another admin user exists. -changelog_1275_li=Values of type BINARY or BLOB could not be converted to the data type OTHER. -changelog_1276_li=SHUTDOWN COMPACT now fully compacts the database. -changelog_1277_li=New system properties h2.maxCompactCount and h2.maxCompactTime to allow changing the default behavior (at most 2 seconds compacting when closing the database). -changelog_1278_li=New sorted insert optimization (see Performance / Database Performance Tuning). -changelog_1279_li=Issue 116\: The files h2*-sources.jar and h2*-javadoc.jar are now in the Maven repository. -changelog_1280_li=Page store\: opening a large database was slow if it was not closed before. -changelog_1281_li=Page store\: new write and read counters in the meta data table. Use SELECT * FROM INFORMATION_SCHEMA.SETTINGS WHERE NAME IN( 'info.FILE_WRITE_TOTAL', 'info.FILE_WRITE', 'info.FILE_READ', 'info.CACHE_MAX_SIZE', 'info.CACHE_SIZE') -changelog_1282_li=The SQL syntax is documented using (railroad) diagrams. The diagrams are HTML. -changelog_1283_li=The documentation is no longer available in Japanese because the translation was too much out of sync. Please use the Google translation instead. -changelog_1284_li=Certain queries were not sorted if subselect queries were involved -changelog_1285_li=More bugs in the server-less multi-connection mode have been fixed\: 90097 The database is read only, caches must be cleared on reconnect, etc. -changelog_1286_h2=Version 1.2.121 (2009-10-11) -changelog_1287_li=Better support GaeVFS (Google App Engine Virtual File System) thanks to Thanks to Vince Bonfanti. -changelog_1288_li=CSVREAD didn't close the file. Thanks to Vince Bonfanti for the patch\! -changelog_1289_li=If a database in the old format exists, it is now used. The system property is used for new databases, or if databases exist in both formats. In any case, the flag in the URL overrides this logic. -changelog_1290_li=Page store bugs were fixed. Large values in indexed columns could corrupt the index. -changelog_1291_li=The page store did not work when using Retrotranslator (because the Retrotranslator doesn't support Integer.reverse and Long.reverse). -changelog_1292_li=New system property h2.pageStoreTrim to disable shrinking the database when closing (disabled by default, meaning by default the database is trimmed). -changelog_1293_h2=Version 1.2.120 (2009-10-04) -changelog_1294_li=This is a beta version. -changelog_1295_li=Large updates could throw an ArrayIndexOutOfBoundsException in RowList.writeRow. -changelog_1296_li=In version 1.2, the following system properties are now enabled by default\: h2.pageStore, h2.nullConcatIsNull, h2.optimizeInList. The default value for h2.defaultMaxLengthInplaceLob is now 4096 (it was 1024 with version 1.1). -changelog_1297_li=New databases are now stored in the new 'page store' file format. Existing databases are kept in the old file format. To use the old file format, append ;PAGE_STORE\=FALSE to the database URL or set the system property h2.pageStore to false. -changelog_1298_li=Issue 125\: Renaming primary keys was not persistent. Fixed. Unfortunately, databases created by this version can not be opened with older versions because of this change. -changelog_1299_li=Issue 124\: Hibernate schema validation failed for decimal/numeric columns. This problem is fixed in the Hibernate dialect that is included with H2 (src/tools/org/hibernate/dialect/H2Dialect.java.txt), but not in Hibernate yet. -changelog_1300_li=PostgreSQL compatibility\: function LASTVAL() as an alias for IDENTITY(). -changelog_1301_li=Linked tables now support default values when inserting, updating or merging. -changelog_1302_li=Bugfixes in the page store. -changelog_1303_li=Possibility to set a vendor id in Constants.java, so that unofficial builds are distinguishable from official releases. -changelog_1304_li=Allow writing to linked tables in readonly databases. -changelog_1305_h2=Version 1.1.119 (2009-09-26) -changelog_1306_li=SQL statements in the exception message are no longer included if they contain '--hide--'. -changelog_1307_li=Temporary local tables did not always work after reconnect if AUTO_SERVER\=TRUE -changelog_1308_li=New system property h2.defaultMaxLengthInplaceLob to change the default maximum size of an in-place LOB object. -changelog_1309_li=New system property h2.nullConcatIsNull to change the default null concatenation behavior. The default will be enabled in version 1.2. -changelog_1310_li=The cache algorithm TQ is disabled in this version, because it is unstable, and because the current implementation does not have any measurable advantages over the default. -changelog_1311_li=New committer\: Christian Peter. He works for Docware and helped a lot finding and fixing bugs, and generally improving the database. He is now a committer. -changelog_1312_li=ChangeFileEncryption did not work with Lob subdirectories. Fixed. -changelog_1313_li=Issue 121\: JaQu\: new simple update and merge methods. -changelog_1314_li=Issue 120\: JaQu didn't close result sets. -changelog_1315_li=Issue 119\: JaQu creates wrong WHERE conditions on some inputs. -changelog_1316_li=The new page store mechanism is now alpha-level quality. The next release will most likely be "1.2.120 beta" where this mode is enabled by default. To use it right now, append ;PAGE_STORE\=TRUE to the database URL. The file format of this mode will probably not change any more. -changelog_1317_li=SELECT COUNT(*) FROM SYSTEM_RANGE(...) returned the wrong result. Fixed. -changelog_1318_li=The Recover tool now also processes the log files, however applying those changes is still a manual process. -changelog_1319_li=New sample application that shows how to pass data to a trigger. -changelog_1320_li=More bugs in the server-less multi-connection mode have been fixed\: On Windows, two processes could write to the same database at the same time. -changelog_1321_li=When loading triggers or other client classes (static functions, database event listener, user aggregate functions, other JDBC drivers), the database now uses the context class loader if the class could not be found using Class.forName(). -changelog_1322_li=Updating many rows with the same CLOB or BLOB values could result in FileNotFoundException. -changelog_1323_li=Statement.getConnection() threw an exception if the connection was already closed. -changelog_1324_li=The native fulltext index kept a reference to a database after the database was closed. -changelog_1325_li=Non-unique in-memory hash indexes are now supported. Thanks a lot to Sergi Vladykin for the patch\! -changelog_1326_li=The optimizer does a better job for joins if indexes are missing. -changelog_1327_h2=Version 1.1.118 (2009-09-04) -changelog_1328_li=SHOW COLUMNS only listed indexed columns. -changelog_1329_li=When calling SHUTDOWN IMMEDIATELY in the server mode, the .trace.db file was not closed. -changelog_1330_li=DatabaseMetaData.getPrimaryKeys\: the wrong constraint name was reported if there was another constraint on the same table and columns. -changelog_1331_li=AUTO_INCREMENT now works in the same way in ALTER TABLE ALTER COLUMN as in CREATE TABLE (it does not create a primary key). -changelog_1332_li=Native fulltext search\: before searching, FT_INIT() had to be called. This is no longer required. -changelog_1333_li=Better support GaeVFS (Google App Engine Virtual File System). -changelog_1334_li=JaQu\: the plan is to support natural (pure Java / Scala) conditions such as (id \=\= 1 && name.equals("Test")). A proof of concept decompiler is now included (it doesn't work yet). -changelog_1335_li=Various bugfixes and improvements in the page store mechanism (still experimental). -changelog_1336_li=PreparedStatement.setObject now converts a java.lang.Character to a string. -changelog_1337_li=H2 Console\: PierPaolo Ucchino has completed the Italian translation. Thanks a lot\! -changelog_1338_li=Various tools now use Java 5 var-args, such as main the methods and SimpleResultSet.addRow. -changelog_1339_li=H2 Console\: indexes of tables of non-default schemas are now also listed. -changelog_1340_li=Issue 111\: Multi-version concurrency / duplicate primary key after rollback. -changelog_1341_li=Issue 110\: Multi-version concurrency / wrong exception is thrown. -changelog_1342_li=Parser\: sequenceName.NEXTVAL and CURRVAL did not respect the schema search path. -changelog_1343_li=Issue 101\: The following sequence could throw the exception "Row not found when trying to delete"\: start a transaction, insert many rows, delete many rows, rollback. The number of rows depends on the cache size. -changelog_1344_li=The stack trace of very common exceptions is no longer written to the .trace.db file by default. -changelog_1345_li=An optimization for OR is implemented, but disabled by default. Expressions of the type X\=1 OR X\=2 are converted to X IN(1, 2). To enable, set the system property h2.optimizeInList to true before loading the H2 JDBC driver. -changelog_1346_li=An optimization for IN(..) and IN(SELECT...) is implemented, but disabled by default. To enable, set the system property h2.optimizeInList to true before loading the H2 JDBC driver. If enabled, this overrides h2.optimizeIn and h2.optimizeInJoin. Unlike now, this optimization will also speed up updates and deletes. -changelog_1347_h2=Version 1.1.117 (2009-08-09) -changelog_1348_li=New committer\: Sam Van Oort has been contributing to H2 since quite some time in many ways (on the mailing list, documentation, and in the form of patches). He is now a committer. -changelog_1349_li=JaQu\: the order of the fields in the database no longer needs to match the order in the database. -changelog_1350_li=Issue 103\: MVCC\: the setting MAX_MEMORY_UNDO can currently not be supported when using multi-version concurrency, that means the complete undo log must fit in memory. -changelog_1351_li=LIKE\: the escape mechanism can now be disable using ESCAPE ''. The default escape character can be changed using the system property h2.defaultEscape. The default is still '\\' (as in MySQL and PostgreSQL). -changelog_1352_li=Views using functions were not re-evaluated when necessary. -changelog_1353_li=Improved MySQL compatibility for SHOW COLUMNS. -changelog_1354_li=Improved PostgreSQL compatibility for timestamp literals with timezone. -changelog_1355_li=Sergi Vladykin translated the error messages to Russian. Thanks a lot\! -changelog_1356_li=Support for Java 6 DatabaseMetaData.getTables, getColumns, getProcedures, and getProcedureColumns. -changelog_1357_li=Issue 101\: Rollback of a large transaction (more than 100000 rows) could fail. -changelog_1358_li=Various bugfixes and improvements in the page store mechanism (still experimental). -changelog_1359_li=The functions LENGTH, OCTET_LENGTH, and BIT_LENGTH now return BIGINT. -changelog_1360_li=Data types CLOB and BLOB\: the maximum precision was Integer.MAX_VALUE, it is now Long.MAX_VALUE. -changelog_1361_li=Multi-threaded kernel\: creating and dropping temporary database objects and the potentially free pages list was not correctly synchronized. Thanks a lot to Eric Faulhaber for the test case and patch\! -changelog_1362_li=Parsing SQL script files is now faster. -changelog_1363_li=CSV reading is now faster. -changelog_1364_li=SimpleResultSet.newInstance(SimpleRowSource rs) did not work. -changelog_1365_h2=Version 1.1.116 (2009-07-18) -changelog_1366_li=Server-less multi-connection mode\: more bugs are fixed. -changelog_1367_li=The built-in help (INFORMATION_SCHEMA.HELP) is smaller, shrinking the jar file size a bit. -changelog_1368_li=H2 Console\: column of tables of non-default schemas are now also listed, except for schemas starting with 'INFO'. -changelog_1369_li=ALTER TABLE\: removing an auto-increment or identity column didn't remove the sequence. -changelog_1370_li=Creating indexes is now a bit faster. -changelog_1371_li=PG Server\: new system property h2.pgClientEncoding to explicitly set the encoding for clients that don't send the encoding (the default encoding is UTF-8). Thanks a lot to Sergi Vladykin for the patch\! -changelog_1372_li=PG Server\: improved compatibility by using the type ids of the PostgreSQL driver. Thanks a lot to Sergi Vladykin for the patch\! -changelog_1373_li=H2 Console\: Oracle system tables are no longer listed, improving performance. -changelog_1374_li=Result sets are now read-only except if the statement or prepared statement was created with the concurrency ResultSet.CONCUR_UPDATABLE. This change is required because the old behavior (all result set are updatable) violated the JDBC spec. For backward compatibility, use the system property h2.defaultResultSetConcurrency. -changelog_1375_li=New system property h2.defaultResultSetConcurrency to change the default result set concurrency. -changelog_1376_li=JDBC\: using an invalid result set type or concurrency now throws an exception. -changelog_1377_li=If a pooled connection was not closed but garbage collected, a NullPointerException could occur. -changelog_1378_li=Fulltext search\: a NullPointerException was thrown when updating a value that was NULL previously. -changelog_1379_li=The Recover tool did not work with .data.db files of the wrong size. -changelog_1380_li=Triggers\: if there was an exception when initializing a trigger, this exception could be hidden, and in some cases (specially when using the Lucene fulltext index mechanism) a NullPointerException was thrown later on. Now the exception that occurred on init is thrown when changing data. -changelog_1381_li=The soft-references cache (CACHE_TYPE\=SOFT_LRU) could throw a NullPointerException. -changelog_1382_li=To enable the new page store mechanism, append ;PAGE_STORE\=TRUE to the database URL. or set the system property h2.pageStore to true. This mechanism is still experimental, and the file format will change, but it is quite stable now. -cheatSheet_1000_h1=H2 Database Engine Cheat Sheet -cheatSheet_1001_h2=Using H2 -cheatSheet_1002_a=H2 -cheatSheet_1003_li=\ is open source, free to use and distribute. -cheatSheet_1004_a=Download -cheatSheet_1005_li=\: jar, installer (Windows), zip. -cheatSheet_1006_li=To start the H2 Console tool, double click the jar file, or run java -jar h2*.jar, h2.bat, or h2.sh. -cheatSheet_1007_a=A new database is automatically created -cheatSheet_1008_a=by default -cheatSheet_1009_li=. -cheatSheet_1010_a=Closing the last connection closes the database -cheatSheet_1011_li=. -cheatSheet_1012_h2=Documentation -cheatSheet_1013_p=\ Reference\: SQL grammar, functions, data types, tools, API -cheatSheet_1014_a=Features -cheatSheet_1015_p=\: fulltext search, encryption, read-only (zip/jar), CSV, auto-reconnect, triggers, user functions -cheatSheet_1016_a=Database URLs -cheatSheet_1017_a=Embedded -cheatSheet_1018_code=jdbc\:h2\:~/test -cheatSheet_1019_p=\ 'test' in the user home directory -cheatSheet_1020_code=jdbc\:h2\:/data/test -cheatSheet_1021_p=\ 'test' in the directory /data -cheatSheet_1022_code=jdbc\:h2\:test -cheatSheet_1023_p=\ in the current(\!) working directory -cheatSheet_1024_a=In-Memory -cheatSheet_1025_code=jdbc\:h2\:mem\:test -cheatSheet_1026_p=\ multiple connections in one process -cheatSheet_1027_code=jdbc\:h2\:mem\: -cheatSheet_1028_p=\ unnamed private; one connection -cheatSheet_1029_a=Server Mode -cheatSheet_1030_code=jdbc\:h2\:tcp\://localhost/~/test -cheatSheet_1031_p=\ user home dir -cheatSheet_1032_code=jdbc\:h2\:tcp\://localhost//data/test -cheatSheet_1033_p=\ absolute dir -cheatSheet_1034_a=Server start -cheatSheet_1035_p=\:java -cp *.jar org.h2.tools.Server -cheatSheet_1036_a=Settings -cheatSheet_1037_code=jdbc\:h2\:..;MODE\=MySQL -cheatSheet_1038_a=compatibility (or HSQLDB,...) -cheatSheet_1039_code=jdbc\:h2\:..;TRACE_LEVEL_FILE\=3 -cheatSheet_1040_a=log to *.trace.db -cheatSheet_1041_a=Using the JDBC API -cheatSheet_1042_a=Connection Pool -cheatSheet_1043_a=Maven 2 -cheatSheet_1044_a=Hibernate -cheatSheet_1045_p=\ hibernate.cfg.xml (or use the HSQLDialect)\: -cheatSheet_1046_a=TopLink and Glassfish -cheatSheet_1047_p=\ Datasource class\: org.h2.jdbcx.JdbcDataSource -cheatSheet_1048_code=oracle.toplink.essentials.platform. -cheatSheet_1049_code=database.H2Platform -download_1000_h1=Downloads -download_1001_h3=Version 1.2.137 (2010-06-06) -download_1002_a=Windows Installer -download_1003_a=Platform-Independent Zip -download_1004_h3=Version 1.2.136 (2010-05-24, Last Stable) -download_1005_a=Windows Installer -download_1006_a=Platform-Independent Zip -download_1007_h3=Download Mirror and Older Versions -download_1008_a=Platform-Independent Zip -download_1009_h3=Jar File -download_1010_a=Maven.org -download_1011_a=Sourceforge.net -download_1012_a=Latest Automated Build (not released) -download_1013_h3=Subversion Source Repository -download_1014_a=Google Code -download_1015_p=\ For details about changes, see the Change Log. -download_1016_h3=News and Project Information -download_1017_a=Atom Feed -download_1018_a=RSS Feed -download_1019_a=DOAP File -download_1020_p=\ (what is this) -faq_1000_h1=Frequently Asked Questions -faq_1001_a=\ I Have a Problem or Feature Request -faq_1002_a=\ Are there Known Bugs? When is the Next Release? -faq_1003_a=\ Is this Database Engine Open Source? -faq_1004_a=\ My Query is Slow -faq_1005_a=\ How to Create a New Database? -faq_1006_a=\ How to Connect to a Database? -faq_1007_a=\ Where are the Database Files Stored? -faq_1008_a=\ What is the Size Limit (Maximum Size) of a Database? -faq_1009_a=\ Is it Reliable? -faq_1010_a=\ Why is Opening my Database Slow? -faq_1011_a=\ Column Names are Incorrect? -faq_1012_a=\ Float is Double? -faq_1013_a=\ Is the GCJ Version Stable? Faster? -faq_1014_a=\ How to Translate this Project? -faq_1015_h3=I Have a Problem or Feature Request -faq_1016_p=\ Please read the support checklist. -faq_1017_h3=Are there Known Bugs? When is the Next Release? -faq_1018_p=\ Usually, bugs get fixes as they are found. There is a release every few weeks. Here is the list of known and confirmed issues\: -faq_1019_li=Apache Harmony\: there seems to be a bug in Harmony that affects H2. See HARMONY-6505. -faq_1020_li=Tomcat and Glassfish 3 set most static fields (final or non-final) to null when unloading a web application. This can cause a NullPointerException in H2 versions 1.1.107 and older, and may still not work in newer versions. Please report it if you run into this issue. In Tomcat >\= 6.0 this behavior can be disabled by setting the system property org.apache.catalina.loader.WebappClassLoader.ENABLE_CLEAR_REFERENCES\=false, however Tomcat may then run out of memory. A known workaround is to put the h2*.jar file in a shared lib directory (common/lib). -faq_1021_li=Some problems have been found with right outer join. Internally, it is converted to left outer join, which does not always produce the same results as other databases when used in combination with other joins. -faq_1022_li=When using Install4j before 4.1.4 on Linux and enabling pack200, the h2*.jar becomes corrupted by the install process, causing application failure. A workaround is to add an empty file h2*.jar.nopack next to the h2*.jar file. This problem is solved in Install4j 4.1.4. -faq_1023_p=\ For a complete list, see Open Issues. -faq_1024_h3=Is this Database Engine Open Source? -faq_1025_p=\ Yes. It is free to use and distribute, and the source code is included. See also under license. -faq_1026_h3=My Query is Slow -faq_1027_p=\ Slow SELECT (or DELETE, UPDATE, MERGE) statement can have multiple reasons. Follow this checklist\: -faq_1028_li=Run ANALYZE (see documentation for details). -faq_1029_li=Run the query with EXPLAIN and check if indexes are used (see documentation for details). -faq_1030_li=If required, create additional indexes and try again using ANALYZE and EXPLAIN. -faq_1031_li=If it doesn't help please report the problem. -faq_1032_h3=How to Create a New Database? -faq_1033_p=\ By default, a new database is automatically created if it does not yet exist. See Creating New Databases. -faq_1034_h3=How to Connect to a Database? -faq_1035_p=\ The database driver is org.h2.Driver, and the database URL starts with jdbc\:h2\:. To connect to a database using JDBC, use the following code\: -faq_1036_h3=Where are the Database Files Stored? -faq_1037_p=\ When using database URLs like jdbc\:h2\:~/test, the database is stored in the user directory. For Windows, this is usually C\:\\Documents and Settings\\<userName>. If the base directory is not set (as in jdbc\:h2\:test), the database files are stored in the directory where the application is started (the current working directory). When using the H2 Console application from the start menu, this is <Installation Directory>/bin. The base directory can be set in the database URL. A fixed or relative path can be used. When using the URL jdbc\:h2\:file\:data/sample, the database is stored in the directory data (relative to the current working directory). The directory is created automatically if it does not yet exist. It is also possible to use the fully qualified directory name (and for Windows, drive name). Example\: jdbc\:h2\:file\:C\:/data/test -faq_1038_h3=What is the Size Limit (Maximum Size) of a Database? -faq_1039_p=\ See Limits and Limitations. -faq_1040_h3=Is it Reliable? -faq_1041_p=\ That is not easy to say. It is still a quite new product. A lot of tests have been written, and the code coverage of these tests is very high. Randomized stress tests are run regularly. But there are probably still bugs that have not yet been found (as with most software). Some features are known to be dangerous, they are only supported for situations where performance is more important than reliability. Those dangerous features are\: -faq_1042_li=Using the transaction isolation level READ_UNCOMMITTED (LOCK_MODE 0) while at the same time using multiple connections. -faq_1043_li=Disabling database file protection using (setting FILE_LOCK to NO in the database URL). -faq_1044_li=Disabling referential integrity using SET REFERENTIAL_INTEGRITY FALSE. -faq_1045_p=\ In addition to that, running out of memory should be avoided. In older versions, OutOfMemory errors while using the database could corrupt a databases. -faq_1046_p=\ Some areas of this database are not fully tested. When using one of those features for production, please ensure your use case is well tested (if possible with automated test cases). Those areas are\: -faq_1047_li=Platforms other than Windows XP, Linux, Mac OS X, or JVMs other than Sun 1.5 or 1.6 -faq_1048_li=The feature MULTI_THREADED -faq_1049_li=The features AUTO_SERVER and AUTO_RECONNECT -faq_1050_li=The file locking method 'Serialized' -faq_1051_li=The MVCC (multi version concurrency) mode -faq_1052_li=Cluster mode, 2-phase commit, savepoints -faq_1053_li=24/7 operation -faq_1054_li=Some operations on databases larger than 500 MB may be slower than expected -faq_1055_li=The optimizer may not always select the best plan -faq_1056_li=Fulltext search -faq_1057_li=Operations on LOBs over 2 GB -faq_1058_p=\ Areas considered experimental are\: -faq_1059_li=The PostgreSQL server -faq_1060_li=Multi-threading within the engine using SET MULTI_THREADED\=1 -faq_1061_li=Compatibility modes for other databases (only some features are implemented) -faq_1062_li=The soft reference cache (CACHE_TYPE\=SOFT_LRU). It might not improve performance, and out of memory issues have been reported. -faq_1063_p=\ Some users have reported that after a power failure, the database cannot be opened sometimes. In this case, use a backup of the database or the Recover tool. Please report such problems. The plan is that the database automatically recovers in all situations. -faq_1064_h3=Column Names are Incorrect? -faq_1065_p=\ For the query SELECT ID AS X FROM TEST the method ResultSetMetaData.getColumnName() returns ID, I expect it to return X. What's wrong? -faq_1066_p=\ This is not a bug. According the the JDBC specification, the method ResultSetMetaData.getColumnName() should return the name of the column and not the alias name. If you need the alias name, use ResultSetMetaData.getColumnLabel(). Some other database don't work like this yet (they don't follow the JDBC specification). If you need compatibility with those databases, use the Compatibility Mode, or set the system property h2.aliasColumnName. -faq_1067_p=\ This also applies to DatabaseMetaData calls that return a result set. The columns in the JDBC API are column labels, not column names. -faq_1068_h3=Float is Double? -faq_1069_p=\ For a table defined as CREATE TABLE TEST(X FLOAT) the method ResultSet.getObject() returns a java.lang.Double, I expect it to return a java.lang.Float. What's wrong? -faq_1070_p=\ This is not a bug. According the the JDBC specification, the JDBC data type FLOAT is equivalent to DOUBLE, and both are mapped to java.lang.Double. See also Mapping SQL and Java Types - 8.3.10 FLOAT. -faq_1071_h3=Why is Opening my Database Slow? -faq_1072_p=\ To find out what the problem is, use the H2 Console and click on "Test Connection" instead of "Login". After the "Login Successful" appears, click on it (it's a link). This will list the top stack traces. Then either analyze this yourself, or post those stack traces in the Google Group. -faq_1073_p=\ To find out what the problem is, open the database in embedded mode using the H2 Console. This will print progress information. If you have many lines with 'Creating index' it is an indication that the database was not closed the last time. -faq_1074_p=\ Other possible reasons are\: the database is very big (many GB), or contains linked tables that are slow to open. -faq_1075_h3=Is the GCJ Version Stable? Faster? -faq_1076_p=\ The GCJ version is not as stable as the Java version. When running the regression test with the GCJ version, sometimes the application just stops at what seems to be a random point without error message. Currently, the GCJ version is also slower than when using the Sun VM. However, the startup of the GCJ version is faster than when using a VM. -faq_1077_h3=How to Translate this Project? -faq_1078_p=\ For more information, see Build/Translating. -features_1000_h1=Features -features_1001_a=\ Feature List -features_1002_a=\ Comparison to Other Database Engines -features_1003_a=\ H2 in Use -features_1004_a=\ Connection Modes -features_1005_a=\ Database URL Overview -features_1006_a=\ Connecting to an Embedded (Local) Database -features_1007_a=\ In-Memory Databases -features_1008_a=\ Database Files Encryption -features_1009_a=\ Database File Locking -features_1010_a=\ Opening a Database Only if it Already Exists -features_1011_a=\ Closing a Database -features_1012_a=\ Ignore Unknown Settings -features_1013_a=\ Changing Other Settings when Opening a Connection -features_1014_a=\ Custom File Access Mode -features_1015_a=\ Multiple Connections -features_1016_a=\ Database File Layout -features_1017_a=\ Logging and Recovery -features_1018_a=\ Compatibility -features_1019_a=\ Auto-Reconnect -features_1020_a=\ Automatic Mixed Mode -features_1021_a=\ Page Size -features_1022_a=\ Using the Trace Options -features_1023_a=\ Using Other Logging APIs -features_1024_a=\ Read Only Databases -features_1025_a=\ Read Only Databases in Zip or Jar File -features_1026_a=\ Graceful Handling of Low Disk Space Situations -features_1027_a=\ Computed Columns / Function Based Index -features_1028_a=\ Multi-Dimensional Indexes -features_1029_a=\ Using Passwords -features_1030_a=\ User-Defined Functions and Stored Procedures -features_1031_a=\ Triggers -features_1032_a=\ Compacting a Database -features_1033_a=\ Cache Settings -features_1034_h2=Feature List -features_1035_h3=Main Features -features_1036_li=Very fast database engine -features_1037_li=Open source -features_1038_li=Written in Java -features_1039_li=Supports standard SQL, JDBC API -features_1040_li=Embedded and Server mode, Clustering support -features_1041_li=Strong security features -features_1042_li=The PostgreSQL ODBC driver can be used -features_1043_li=Multi version concurrency -features_1044_h3=Additional Features -features_1045_li=Disk based or in-memory databases and tables, read-only database support, temporary tables -features_1046_li=Transaction support (read committed and serializable transaction isolation), 2-phase-commit -features_1047_li=Multiple connections, table level locking -features_1048_li=Cost based optimizer, using a genetic algorithm for complex queries, zero-administration -features_1049_li=Scrollable and updatable result set support, large result set, external result sorting, functions can return a result set -features_1050_li=Encrypted database (AES or XTEA), SHA-256 password encryption, encryption functions, SSL -features_1051_h3=SQL Support -features_1052_li=Support for multiple schemas, information schema -features_1053_li=Referential integrity / foreign key constraints with cascade, check constraints -features_1054_li=Inner and outer joins, subqueries, read only views and inline views -features_1055_li=Triggers and Java functions / stored procedures -features_1056_li=Many built-in functions, including XML and lossless data compression -features_1057_li=Wide range of data types including large objects (BLOB/CLOB) and arrays -features_1058_li=Sequence and autoincrement columns, computed columns (can be used for function based indexes) -features_1059_code=ORDER BY, GROUP BY, HAVING, UNION, LIMIT, TOP -features_1060_li=Collation support, users, roles -features_1061_li=Compatibility modes for IBM DB2, Apache Derby, HSQLDB, MS SQL Server, MySQL, Oracle, and PostgreSQL. -features_1062_h3=Security Features -features_1063_li=Includes a solution for the SQL injection problem -features_1064_li=User password authentication uses SHA-256 and salt -features_1065_li=For server mode connections, user passwords are never transmitted in plain text over the network (even when using insecure connections; this only applies to the TCP server and not to the H2 Console however; it also doesn't apply if you set the password in the database URL) -features_1066_li=All database files (including script files that can be used to backup data) can be encrypted using AES-128 and XTEA encryption algorithms -features_1067_li=The remote JDBC driver supports TCP/IP connections over SSL/TLS -features_1068_li=The built-in web server supports connections over SSL/TLS -features_1069_li=Passwords can be sent to the database using char arrays instead of Strings -features_1070_h3=Other Features and Tools -features_1071_li=Small footprint (smaller than 1 MB), low memory requirements -features_1072_li=Multiple index types (b-tree, tree, hash) -features_1073_li=Support for multi-dimensional indexes -features_1074_li=CSV (comma separated values) file support -features_1075_li=Support for linked tables, and a built-in virtual 'range' table -features_1076_code=EXPLAIN PLAN -features_1077_li=\ support, sophisticated trace options -features_1078_li=Database closing can be delayed or disabled to improve the performance -features_1079_li=Web-based Console application (translated to many languages) with autocomplete -features_1080_li=The database can generate SQL script files -features_1081_li=Contains a recovery tool that can dump the contents of the database -features_1082_li=Support for variables (for example to calculate running totals) -features_1083_li=Automatic re-compilation of prepared statements -features_1084_li=Uses a small number of database files -features_1085_li=Uses a checksum for each record and log entry for data integrity -features_1086_li=Well tested (high code coverage, randomized stress tests) -features_1087_h2=Comparison to Other Database Engines -features_1088_th=Feature -features_1089_th=H2 -features_1090_a=Derby -features_1091_a=HSQLDB -features_1092_a=MySQL -features_1093_a=PostgreSQL -features_1094_td=Pure Java -features_1095_td=Yes -features_1096_td=Yes -features_1097_td=Yes -features_1098_td=No -features_1099_td=No -features_1100_td=Embedded Mode (Java) -features_1101_td=Yes -features_1102_td=Yes -features_1103_td=Yes -features_1104_td=No -features_1105_td=No -features_1106_td=Performance (Embedded) -features_1107_td=Fast -features_1108_td=Slow -features_1109_td=Fast -features_1110_td=N/A -features_1111_td=N/A -features_1112_td=In-Memory Mode -features_1113_td=Yes -features_1114_td=Yes -features_1115_td=Yes -features_1116_td=No -features_1117_td=No -features_1118_td=Transaction Isolation -features_1119_td=Yes -features_1120_td=Yes -features_1121_td=No -features_1122_td=Yes -features_1123_td=Yes -features_1124_td=Cost Based Optimizer -features_1125_td=Yes -features_1126_td=Yes -features_1127_td=No -features_1128_td=Yes -features_1129_td=Yes -features_1130_td=Explain Plan -features_1131_td=Yes -features_1132_td=No -features_1133_td=Yes -features_1134_td=Yes -features_1135_td=Yes -features_1136_td=Clustering -features_1137_td=Yes -features_1138_td=No -features_1139_td=No -features_1140_td=Yes -features_1141_td=Yes -features_1142_td=Encrypted Database -features_1143_td=Yes -features_1144_td=Yes -features_1145_td=No -features_1146_td=No -features_1147_td=No -features_1148_td=Linked Tables -features_1149_td=Yes -features_1150_td=No -features_1151_td=Partially *1 -features_1152_td=Partially *2 -features_1153_td=No -features_1154_td=ODBC Driver -features_1155_td=Yes -features_1156_td=No -features_1157_td=No -features_1158_td=Yes -features_1159_td=Yes -features_1160_td=Fulltext Search -features_1161_td=Yes -features_1162_td=No -features_1163_td=No -features_1164_td=Yes -features_1165_td=Yes -features_1166_td=User-Defined Datatypes -features_1167_td=Yes -features_1168_td=No -features_1169_td=No -features_1170_td=Yes -features_1171_td=Yes -features_1172_td=Files per Database -features_1173_td=Few -features_1174_td=Many -features_1175_td=Few -features_1176_td=Many -features_1177_td=Many -features_1178_td=Table Level Locking -features_1179_td=Yes -features_1180_td=Yes -features_1181_td=No -features_1182_td=Yes -features_1183_td=Yes -features_1184_td=Row Level Locking -features_1185_td=Yes *9 -features_1186_td=Yes -features_1187_td=No -features_1188_td=Yes -features_1189_td=Yes -features_1190_td=Multi Version Concurrency -features_1191_td=Yes -features_1192_td=No -features_1193_td=No -features_1194_td=Yes -features_1195_td=Yes -features_1196_td=Role Based Security -features_1197_td=Yes -features_1198_td=Yes *3 -features_1199_td=Yes -features_1200_td=Yes -features_1201_td=Yes -features_1202_td=Updatable Result Sets -features_1203_td=Yes -features_1204_td=Yes *7 -features_1205_td=No -features_1206_td=Yes -features_1207_td=Yes -features_1208_td=Sequences -features_1209_td=Yes -features_1210_td=No -features_1211_td=Yes -features_1212_td=No -features_1213_td=Yes -features_1214_td=Limit and Offset -features_1215_td=Yes -features_1216_td=No -features_1217_td=Yes -features_1218_td=Yes -features_1219_td=Yes -features_1220_td=Temporary Tables -features_1221_td=Yes -features_1222_td=Yes *4 -features_1223_td=Yes -features_1224_td=Yes -features_1225_td=Yes -features_1226_td=Information Schema -features_1227_td=Yes -features_1228_td=No *8 -features_1229_td=No *8 -features_1230_td=Yes -features_1231_td=Yes -features_1232_td=Computed Columns -features_1233_td=Yes -features_1234_td=No -features_1235_td=No -features_1236_td=No -features_1237_td=Yes *6 -features_1238_td=Case Insensitive Columns -features_1239_td=Yes -features_1240_td=No -features_1241_td=Yes -features_1242_td=Yes -features_1243_td=Yes *6 -features_1244_td=Custom Aggregate Functions -features_1245_td=Yes -features_1246_td=No -features_1247_td=No -features_1248_td=Yes -features_1249_td=Yes -features_1250_td=Footprint (jar/dll size) -features_1251_td=~1 MB *5 -features_1252_td=~2 MB -features_1253_td=~700 KB -features_1254_td=~4 MB -features_1255_td=~6 MB -features_1256_p=\ *1 HSQLDB supports text tables. -features_1257_p=\ *2 MySQL supports linked MySQL tables under the name 'federated tables'. -features_1258_p=\ *3 Derby support for roles based security and password checking as an option. -features_1259_p=\ *4 Derby only supports global temporary tables. -features_1260_p=\ *5 The default H2 jar file contains debug information, jar files for other databases do not. -features_1261_p=\ *6 PostgreSQL supports functional indexes. -features_1262_p=\ *7 Derby only supports updatable result sets if the query is not sorted. -features_1263_p=\ *8 Derby and HSQLDB don't support standard compliant information schema tables. -features_1264_p=\ *9 H2 supports row level locks when using multi version concurrency. -features_1265_h3=Derby and HSQLDB -features_1266_p=\ After an unexpected process termination (for example power failure), H2 can usually recover safely and automatically without any user interaction. For Derby and HSQLDB, some manual steps are required ('Another instance of Derby may have already booted the database' / 'The database is already in use by another process'). -features_1267_h3=DaffodilDb and One$Db -features_1268_p=\ It looks like the development of this database has stopped. The last release was February 2006. -features_1269_h3=McKoi -features_1270_p=\ It looks like the development of this database has stopped. The last release was August 2004 -features_1271_h2=H2 in Use -features_1272_p=\ For a list of applications that work with or use H2, see\: Links. -features_1273_h2=Connection Modes -features_1274_p=\ The following connection modes are supported\: -features_1275_li=Embedded mode (local connections using JDBC) -features_1276_li=Server mode (remote connections using JDBC or ODBC over TCP/IP) -features_1277_li=Mixed mode (local and remote connections at the same time) -features_1278_h3=Embedded Mode -features_1279_p=\ In embedded mode, an application opens a database from within the same JVM using JDBC. This is the fastest and easiest connection mode. The disadvantage is that a database may only be open in one virtual machine (and class loader) at any time. As in all modes, both persistent and in-memory databases are supported. There is no limit on the number of database open concurrently, or on the number of open connections. -features_1280_h3=Server Mode -features_1281_p=\ When using the server mode (sometimes called remote mode or client/server mode), an application opens a database remotely using the JDBC or ODBC API. A server needs to be started within the same or another virtual machine, or on another computer. Many applications can connect to the same database at the same time, by connecting to this server. Internally, the server process opens the database(s) in embedded mode. -features_1282_p=\ The server mode is slower than the embedded mode, because all data is transferred over TCP/IP. As in all modes, both persistent and in-memory databases are supported. There is no limit on the number of database open concurrently per server, or on the number of open connections. -features_1283_h3=Mixed Mode -features_1284_p=\ The mixed mode is a combination of the embedded and the server mode. The first application that connects to a database does that in embedded mode, but also starts a server so that other applications (running in different processes or virtual machines) can concurrently access the same data. The local connections are as fast as if the database is used in just the embedded mode, while the remote connections are a bit slower. -features_1285_p=\ The server can be started and stopped from within the application (using the server API), or automatically (automatic mixed mode). When using the automatic mixed mode, all clients that want to connect to the database (no matter if it's an local or remote connection) can do so using the exact same database URL. -features_1286_h2=Database URL Overview -features_1287_p=\ This database supports multiple connection modes and connection settings. This is achieved using different database URLs. Settings in the URLs are not case sensitive. -features_1288_th=Topic -features_1289_th=URL Format and Examples -features_1290_a=Embedded (local) connection -features_1291_td=\ jdbc\:h2\:[file\:][<path>]<databaseName> -features_1292_td=\ jdbc\:h2\:~/test -features_1293_td=\ jdbc\:h2\:file\:/data/sample -features_1294_td=\ jdbc\:h2\:file\:C\:/data/sample (Windows only) -features_1295_a=In-memory (private) -features_1296_td=jdbc\:h2\:mem\: -features_1297_a=In-memory (named) -features_1298_td=\ jdbc\:h2\:mem\:<databaseName> -features_1299_td=\ jdbc\:h2\:mem\:test_mem -features_1300_a=Server mode (remote connections) -features_1301_a=\ using TCP/IP -features_1302_td=\ jdbc\:h2\:tcp\://<server>[\:<port>]/[<path>]<databaseName> -features_1303_td=\ jdbc\:h2\:tcp\://localhost/~/test -features_1304_td=\ jdbc\:h2\:tcp\://dbserv\:8084/~/sample jdbc\:h2\:tcp\://localhost/mem\:test -features_1305_a=Server mode (remote connections) -features_1306_a=\ using SSL/TLS -features_1307_td=\ jdbc\:h2\:ssl\://<server>[\:<port>]/<databaseName> -features_1308_td=\ jdbc\:h2\:ssl\://secureserv\:8085/~/sample; -features_1309_a=Using encrypted files -features_1310_td=\ jdbc\:h2\:<url>;CIPHER\=[AES|XTEA] -features_1311_td=\ jdbc\:h2\:ssl\://secureserv/~/testdb;CIPHER\=AES -features_1312_td=\ jdbc\:h2\:file\:~/secure;CIPHER\=XTEA -features_1313_a=File locking methods -features_1314_td=\ jdbc\:h2\:<url>;FILE_LOCK\={FILE|SOCKET|NO} -features_1315_td=\ jdbc\:h2\:file\:~/private;CIPHER\=XTEA;FILE_LOCK\=SOCKET -features_1316_a=Only open if it already exists -features_1317_td=\ jdbc\:h2\:<url>;IFEXISTS\=TRUE -features_1318_td=\ jdbc\:h2\:file\:~/sample;IFEXISTS\=TRUE -features_1319_a=Don't close the database when the VM exits -features_1320_td=\ jdbc\:h2\:<url>;DB_CLOSE_ON_EXIT\=FALSE -features_1321_a=Execute SQL on connection -features_1322_td=\ jdbc\:h2\:<url>;INIT\=RUNSCRIPT FROM '~/create.sql' -features_1323_td=\ jdbc\:h2\:file\:~/sample;INIT\=RUNSCRIPT FROM '~/create.sql'\\\\;RUNSCRIPT FROM '~/populate.sql' -features_1324_a=User name and/or password -features_1325_td=\ jdbc\:h2\:<url>[;USER\=<username>][;PASSWORD\=<value>] -features_1326_td=\ jdbc\:h2\:file\:~/sample;USER\=sa;PASSWORD\=123 -features_1327_a=Debug trace settings -features_1328_td=\ jdbc\:h2\:<url>;TRACE_LEVEL_FILE\=<level 0..3> -features_1329_td=\ jdbc\:h2\:file\:~/sample;TRACE_LEVEL_FILE\=3 -features_1330_a=Ignore unknown settings -features_1331_td=\ jdbc\:h2\:<url>;IGNORE_UNKNOWN_SETTINGS\=TRUE -features_1332_a=Custom file access mode -features_1333_td=\ jdbc\:h2\:<url>;ACCESS_MODE_DATA\=rws -features_1334_a=Database in a zip file -features_1335_td=\ jdbc\:h2\:zip\:<zipFileName>\!/<databaseName> -features_1336_td=\ jdbc\:h2\:zip\:~/db.zip\!/test -features_1337_a=Compatibility mode -features_1338_td=\ jdbc\:h2\:<url>;MODE\=<databaseType> -features_1339_td=\ jdbc\:h2\:~/test;MODE\=MYSQL -features_1340_a=Auto-reconnect -features_1341_td=\ jdbc\:h2\:<url>;AUTO_RECONNECT\=TRUE -features_1342_td=\ jdbc\:h2\:tcp\://localhost/~/test;AUTO_RECONNECT\=TRUE -features_1343_a=Automatic mixed mode -features_1344_td=\ jdbc\:h2\:<url>;AUTO_SERVER\=TRUE -features_1345_td=\ jdbc\:h2\:~/test;AUTO_SERVER\=TRUE -features_1346_a=Page size -features_1347_td=\ jdbc\:h2\:<url>;PAGE_SIZE\=512 -features_1348_a=Changing other settings -features_1349_td=\ jdbc\:h2\:<url>;<setting>\=<value>[;<setting>\=<value>...] -features_1350_td=\ jdbc\:h2\:file\:~/sample;TRACE_LEVEL_SYSTEM_OUT\=3 -features_1351_h2=Connecting to an Embedded (Local) Database -features_1352_p=\ The database URL for connecting to a local database is jdbc\:h2\:[file\:][<path>]<databaseName>. The prefix file\: is optional. If no or only a relative path is used, then the current working directory is used as a starting point. The case sensitivity of the path and database name depend on the operating system, however it is recommended to use lowercase letters only. The database name must be at least three characters long (a limitation of File.createTempFile). To point to the user home directory, use ~/, as in\: jdbc\:h2\:~/test. -features_1353_h2=In-Memory Databases -features_1354_p=\ For certain use cases (for example\: rapid prototyping, testing, high performance operations, read-only databases), it may not be required to persist data, or persist changes to the data. This database supports the in-memory mode, where the data is not persisted. -features_1355_p=\ In some cases, only one connection to a in-memory database is required. This means the database to be opened is private. In this case, the database URL is jdbc\:h2\:mem\: Opening two connections within the same virtual machine means opening two different (private) databases. -features_1356_p=\ Sometimes multiple connections to the same in-memory database are required. In this case, the database URL must include a name. Example\: jdbc\:h2\:mem\:db1. Accessing the same database using this URL only works within the same virtual machine and class loader environment. -features_1357_p=\ In-memory can be accessed remotely (or from multiple processes in the same machine) using TCP/IP or SSL/TLS. An example database URL is\: jdbc\:h2\:tcp\://localhost/mem\:db1. -features_1358_p=\ 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 jdbc\:h2\:mem\:test;DB_CLOSE_DELAY\=-1. -features_1359_h2=Database Files Encryption -features_1360_p=\ The database files can be encrypted. Two encryption algorithms are supported\: AES and XTEA. To use file encryption, you need to specify the encryption algorithm (the 'cipher') and the file password (in addition to the user password) when connecting to the database. -features_1361_h3=Creating a New Database with File Encryption -features_1362_p=\ By default, a new database is automatically created if it does not exist yet. To create an encrypted database, connect to it as it would already exist. -features_1363_h3=Connecting to an Encrypted Database -features_1364_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 separates the file password and the user password; the file password itself may not contain spaces. File passwords and user passwords are case sensitive. Here is an example to connect to a password-encrypted database\: -features_1365_h3=Encrypting or Decrypting a Database -features_1366_p=\ To encrypt an existing database, use the ChangeFileEncryption tool. This tool can also decrypt an encrypted database, or change the file encryption key. 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\: -features_1367_h2=Database File Locking -features_1368_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. -features_1369_p=\ The following file locking methods are implemented\: -features_1370_li=The default method is FILE and uses a watchdog thread to protect the database file. The watchdog reads the lock file each second. -features_1371_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 one (and always the same) computer. -features_1372_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. Failing to do so will result in a corrupted database. Using the method NO forces the database to not create a lock file at all. Please note that this is unsafe as another process is able to open the same database, possibly leading to data corruption. -features_1373_p=\ To open the database with a different file locking method, use the parameter FILE_LOCK. The following code opens the database with the 'socket' locking method\: -features_1374_p=\ For more information about the algorithms, see Advanced / File Locking Protocols. -features_1375_h2=Opening a Database Only if it Already Exists -features_1376_p=\ By default, when an application calls DriverManager.getConnection(url, ...) 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 databases, and only allow to open existing databases. To do this, add ;IFEXISTS\=TRUE 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\: -features_1377_h2=Closing a Database -features_1378_h3=Delayed Database Closing -features_1379_p=\ 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 one 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. The following statement will keep a database open for 10 seconds after the last connection was closed\: -features_1380_p=\ The value -1 means the database is not 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\: jdbc\:h2\:~/test;DB_CLOSE_DELAY\=10. -features_1381_h3=Don't Close a Database when the VM Exits -features_1382_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, 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. The first connection (the one that is opening the database) needs to set the option in the database URL (it is not possible to change the setting afterwards). The database URL to disable database closing on exit is\: -features_1383_h2=Execute SQL on Connection -features_1384_p=\ Sometimes, particularly for in-memory databases, it is useful to be able to execute DDL or DML commands automatically when a client connects to a database. This functionality is enabled via the INIT property. Note that multiple commands may be passed to INIT, but the semicolon delimiter must be escaped, as in the example below. -features_1385_h2=Ignore Unknown Settings -features_1386_p=\ Some applications (for example OpenOffice.org Base) pass some additional parameters when connecting to the database. Why those parameters are passed is unknown. The parameters PREFERDOSLIKELINEENDS and IGNOREDRIVERPRIVILEGES are such examples; they are simply ignored to improve the compatibility with OpenOffice.org. If an application passes other parameters when connecting to the database, usually the database throws an exception saying the parameter is not supported. It is possible to ignored such parameters by adding ;IGNORE_UNKNOWN_SETTINGS\=TRUE to the database URL. -features_1387_h2=Changing Other Settings when Opening a Connection -features_1388_p=\ In addition to the settings already described, other database settings can be passed in the database URL. Adding ;setting\=value at the end of a database URL is the same as executing the statement SET setting value just after connecting. For a list of supported settings, see SQL Grammar. -features_1389_h2=Custom File Access Mode -features_1390_p=\ Usually, the database opens the database file with the access mode rw, meaning read-write (except for read only databases, where the mode r is used). To open a database in read-only mode if the database file is not read-only, use ACCESS_MODE_DATA\=r. Also supported are rws and rwd. This setting must be specified in the database URL\: -features_1391_p=\ For more information see Durability Problems. On many operating systems the access mode rws does not guarantee that the data is written to the disk. -features_1392_h2=Multiple Connections -features_1393_h3=Opening Multiple Databases at the Same Time -features_1394_p=\ An application can open multiple databases at the same time, including multiple connections to the same database. The number of open database is only limited by the memory available. -features_1395_h3=Multiple Connections to the Same Database\: Client/Server -features_1396_p=\ If you want to access the same database at the same time from different processes or computers, you need to use the client / server mode. In this case, one process acts as the server, and the other processes (that could reside on other computers as well) connect to the server via TCP/IP (or SSL/TLS over TCP/IP for improved security). -features_1397_h3=Multithreading Support -features_1398_p=\ This database is multithreading-safe. That means, if an application is multi-threaded, it does not need 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. -features_1399_p=\ An application should normally use one connection per thread. This database synchronizes access to the same connection, but other databases may not do this. -features_1400_h3=Locking, Lock-Timeout, Deadlocks -features_1401_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). All locks are released when the transaction commits or rolls back. When using the default transaction isolation level 'read committed', read locks are already released after each statement. -features_1402_p=\ 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 a connection cannot get a lock for a specified time, then a lock timeout exception is thrown. -features_1403_p=\ Usually, SELECT statements 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. The following statements generate locks\: -features_1404_th=Type of Lock -features_1405_th=SQL Statement -features_1406_td=Read -features_1407_td=SELECT * FROM TEST; -features_1408_td=\ CALL SELECT MAX(ID) FROM TEST; -features_1409_td=\ SCRIPT; -features_1410_td=Write -features_1411_td=SELECT * FROM TEST WHERE 1\=0 FOR UPDATE; -features_1412_td=Write -features_1413_td=INSERT INTO TEST VALUES(1, 'Hello'); -features_1414_td=\ INSERT INTO TEST SELECT * FROM TEST; -features_1415_td=\ UPDATE TEST SET NAME\='Hi'; -features_1416_td=\ DELETE FROM TEST; -features_1417_td=Write -features_1418_td=ALTER TABLE TEST ...; -features_1419_td=\ CREATE INDEX ... ON TEST ...; -features_1420_td=\ DROP INDEX ...; -features_1421_p=\ 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 <milliseconds>. The initial lock timeout (that is the timeout used for new connections) can be set using the SQL command SET DEFAULT_LOCK_TIMEOUT <milliseconds>. The default lock timeout is persistent. -features_1422_h2=Database File Layout -features_1423_p=\ The following files are created for persistent databases\: -features_1424_th=File Name -features_1425_th=Description -features_1426_th=Number of Files -features_1427_td=\ test.h2.db -features_1428_td=\ Database file. -features_1429_td=\ Contains the transaction log, indexes, and data for all tables. -features_1430_td=\ Format\: <database>.h2.db -features_1431_td=\ 1 per database -features_1432_td=\ test.lock.db -features_1433_td=\ Database lock file. -features_1434_td=\ Automatically (re-)created while the database is in use. -features_1435_td=\ Format\: <database>.lock.db -features_1436_td=\ 1 per database (only if in use) -features_1437_td=\ test.trace.db -features_1438_td=\ Trace file (if the trace option is enabled). -features_1439_td=\ Contains trace information. -features_1440_td=\ Format\: <database>.trace.db -features_1441_td=\ Renamed to <database>.trace.db.old is too big. -features_1442_td=\ 0 or 1 per database -features_1443_td=\ test.lobs.db/* -features_1444_td=\ Directory containing one file for each -features_1445_td=\ BLOB or CLOB value larger than a certain size. -features_1446_td=\ Format\: <id>.t<tableId>.lob.db -features_1447_td=\ 1 per large object -features_1448_td=\ test.123.temp.db -features_1449_td=\ Temporary file. -features_1450_td=\ Contains a temporary blob or a large result set. -features_1451_td=\ Format\: <database>.<id>.temp.db -features_1452_td=\ 1 per object -features_1453_h3=Moving and Renaming Database Files -features_1454_p=\ Database name and location are not stored inside the database files. -features_1455_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 of the same database start with the same name and the respective extensions are unchanged). -features_1456_p=\ As there is no platform specific data in the files, they can be moved to other operating systems without problems. -features_1457_h3=Backup -features_1458_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. -features_1459_p=\ To backup data while the database is running, the SQL command SCRIPT can be used. -features_1460_h2=Logging and Recovery -features_1461_p=\ Whenever data is modified in the database and those changes are committed, the changes are written to the transaction log (except for in-memory objects). The changes to the main data area itself are usually written later on, to optimize disk access. If there is a power failure, the main data area is not up-to-date, but because the changes are in the transaction log, the next time the database is opened, the changes are re-applied automatically. -features_1462_h2=Compatibility -features_1463_p=\ All database engines behave a little bit different. Where possible, H2 supports the ANSI SQL standard, and tries to be compatible to other databases. There are still a few differences however\: -features_1464_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). -features_1465_h3=Compatibility Modes -features_1466_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 differences to the regular mode\: -features_1467_h3=DB2 Compatibility Mode -features_1468_p=\ To use the IBM DB2 mode, use the database URL jdbc\:h2\:~/test;MODE\=DB2 or the SQL statement SET MODE DB2. -features_1469_li=For aliased columns, ResultSetMetaData.getColumnName() returns the alias name and getTableName() returns null. -features_1470_li=Support for the syntax [OFFSET .. ROW] [FETCH ... ONLY] as an alternative for LIMIT .. OFFSET. -features_1471_li=Concatenating NULL with another value results in the other value. -features_1472_h3=Derby Compatibility Mode -features_1473_p=\ To use the Apache Derby mode, use the database URL jdbc\:h2\:~/test;MODE\=Derby or the SQL statement SET MODE Derby. -features_1474_li=For aliased columns, ResultSetMetaData.getColumnName() returns the alias name and getTableName() returns null. -features_1475_li=For unique indexes, NULL is distinct. That means only one row with NULL in one of the columns is allowed. -features_1476_li=Concatenating NULL with another value results in the other value. -features_1477_h3=HSQLDB Compatibility Mode -features_1478_p=\ To use the HSQLDB mode, use the database URL jdbc\:h2\:~/test;MODE\=HSQLDB or the SQL statement SET MODE HSQLDB. -features_1479_li=For aliased columns, ResultSetMetaData.getColumnName() returns the alias name and getTableName() returns null. -features_1480_li=When converting the scale of decimal data, the number is only converted if the new scale is smaller than the current scale. Usually, the scale is converted and 0s are added if required. -features_1481_li=For unique indexes, NULL is distinct. That means only one row with NULL in one of the columns is allowed. -features_1482_li=Text can be concatenated using '+'. -features_1483_h3=MS SQL Server Compatibility Mode -features_1484_p=\ To use the MS SQL Server mode, use the database URL jdbc\:h2\:~/test;MODE\=MSSQLServer or the SQL statement SET MODE MSSQLServer. -features_1485_li=For aliased columns, ResultSetMetaData.getColumnName() returns the alias name and getTableName() returns null. -features_1486_li=Identifiers may be quoted using square brackets as in [Test]. -features_1487_li=For unique indexes, NULL is distinct. That means only one row with NULL in one of the columns is allowed. -features_1488_li=Concatenating NULL with another value results in the other value. -features_1489_li=Text can be concatenated using '+'. -features_1490_h3=MySQL Compatibility Mode -features_1491_p=\ To use the MySQL mode, use the database URL jdbc\:h2\:~/test;MODE\=MySQL or the SQL statement SET MODE MySQL. -features_1492_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. -features_1493_li=Creating indexes in the CREATE TABLE statement is allowed using INDEX(..) or KEY(..). Example\: create table test(id int primary key, name varchar(255), key idx_name(name)); -features_1494_li=Meta data calls return identifiers in lower case. -features_1495_li=When converting a floating point number to an integer, the fractional digits are not truncated, but the value is rounded. -features_1496_li=Concatenating NULL with another value results in the other value. -features_1497_h3=Oracle Compatibility Mode -features_1498_p=\ To use the Oracle mode, use the database URL jdbc\:h2\:~/test;MODE\=Oracle or the SQL statement SET MODE Oracle. -features_1499_li=For aliased columns, ResultSetMetaData.getColumnName() returns the alias name and getTableName() returns null. -features_1500_li=When using unique indexes, multiple rows with NULL in all columns are allowed, however it is not allowed to have multiple rows with the same values otherwise. -features_1501_li=Concatenating NULL with another value results in the other value. -features_1502_h3=PostgreSQL Compatibility Mode -features_1503_p=\ To use the PostgreSQL mode, use the database URL jdbc\:h2\:~/test;MODE\=PostgreSQL or the SQL statement SET MODE PostgreSQL. -features_1504_li=For aliased columns, ResultSetMetaData.getColumnName() returns the alias name and getTableName() returns null. -features_1505_li=When converting a floating point number to an integer, the fractional digits are not be truncated, but the value is rounded. -features_1506_li=The system columns CTID and OID are supported. -features_1507_h2=Auto-Reconnect -features_1508_p=\ The auto-reconnect feature causes the JDBC driver to reconnect to the database if the connection is lost. The automatic re-connect only occurs when auto-commit is enabled; if auto-commit is disabled, an exception is thrown. To enable this mode, append ;AUTO_RECONNECT\=TRUE to the database URL. -features_1509_p=\ Re-connecting will open a new session. After an automatic re-connect, variables and local temporary tables definitions (excluding data) are re-created. The contents of the system table INFORMATION_SCHEMA.SESSION_STATE contains all client side state that is re-created. -features_1510_p=\ If another connection uses the database in exclusive mode (enabled using SET EXCLUSIVE 1 or SET EXCLUSIVE 2), then this connection will try to re-connect until the exclusive mode ends. -features_1511_h2=Automatic Mixed Mode -features_1512_p=\ Multiple processes can access the same database without having to start the server manually. To do that, append ;AUTO_SERVER\=TRUE to the database URL. You can use the same database URL independent of whether the database is already open or not. This feature doesn't work with in-memory databases. -features_1513_p=\ When using this mode, the first connection to the database is made in embedded mode, and additionally a server is started internally (as a daemon thread). If the database is already open in another process, the server mode is used automatically. -features_1514_p=\ The application that opens the first connection to the database uses the embedded mode, which is faster than the server mode. Therefore the main application should open the database first if possible. The first connection automatically starts a server on a random port. This server allows remote connections, however only to this database (to ensure that, the client reads .lock.db file and sends the the random key that is stored there to the server). When the first connection is closed, the server stops. If other (remote) connections are still open, one of them will then start a server (auto-reconnect is enabled automatically). -features_1515_p=\ All processes need to have access to the database files. If the first connection is closed (the connection that started the server), open transactions of other connections will be rolled back (this may not be a problem if you don't disable autocommit). Explicit client/server connections (using jdbc\:h2\:tcp\:// or ssl\://) are not supported. This mode is not supported for in-memory databases. -features_1516_p=\ Here is an example how to use this mode. Application 1 and 2 are not necessarily started on the same computer, but they need to have access to the database files. Application 1 and 2 are typically two different processes (however they could run within the same process). -features_1517_h2=Page Size -features_1518_p=\ The page size for new databases is 2 KB (2048), unless the system property h2.pageSize is set to a different value, or the page size is set explicitly in the database URL using PAGE_SIZE\=. The page size of existing databases can not be changed. -features_1519_h2=Using the Trace Options -features_1520_p=\ To find problems in an application, it is sometimes good to see what database operations where executed. This database offers the following trace features\: -features_1521_li=Trace to System.out and/or to a file -features_1522_li=Support for trace levels OFF, ERROR, INFO, DEBUG -features_1523_li=The maximum size of the trace file can be set -features_1524_li=It is possible to generate Java source code from the trace file -features_1525_li=Trace can be enabled at runtime by manually creating a file -features_1526_h3=Trace Options -features_1527_p=\ The simplest way to enable the trace option is setting it in the database URL. There are two settings, one for System.out (TRACE_LEVEL_SYSTEM_OUT) tracing, and one for file tracing (TRACE_LEVEL_FILE). The trace levels are 0 for OFF, 1 for ERROR (the default), 2 for INFO, and 3 for DEBUG. A database URL with both levels set to DEBUG is\: -features_1528_p=\ The trace level can be changed at runtime by executing the SQL command SET TRACE_LEVEL_SYSTEM_OUT level (for System.out tracing) or SET TRACE_LEVEL_FILE level (for file tracing). Example\: -features_1529_h3=Setting the Maximum Size of the Trace File -features_1530_p=\ When using a high trace level, the trace file can get very big quickly. 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 such file exists, it is deleted. To limit the size to a certain number of megabytes, use SET TRACE_MAX_FILE_SIZE mb. Example\: -features_1531_h3=Java Code Generation -features_1532_p=\ When setting the trace level to INFO or DEBUG, Java source code is generated as well. This simplifies reproducing problems. The trace file looks like this\: -features_1533_p=\ To filter the Java source code, use the ConvertTraceFile tool as follows\: -features_1534_p=\ The generated file Test.java 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. -features_1535_h2=Using Other Logging APIs -features_1536_p=\ By default, this database uses its own native 'trace' facility. This facility is called 'trace' and not 'log' within this database to avoid confusion with the transaction log. Trace messages can be written to both file and System.out. In most cases, this is sufficient, however sometimes it is better to use the same facility as the application, for example Log4j. To do that, this database support SLF4J. -features_1537_a=SLF4J -features_1538_p=\ is a simple facade for various logging APIs and allows to plug in the desired implementation at deployment time. SLF4J supports implementations such as Logback, Log4j, Jakarta Commons Logging (JCL), Java logging, x4juli, and Simple Log. -features_1539_p=\ To enable SLF4J, set the file trace level to 4 in the database URL\: -features_1540_p=\ 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 the file <database>.trace.db for error messages. -features_1541_h2=Read Only Databases -features_1542_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 and CALL statements are allowed. To create a read-only database, close the database. Then, make the database file read-only. When you open the database now, it 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(). -features_1543_p=\ Using the Custom Access Mode r the database can also be opened in read-only mode, even if the database file is not read only. -features_1544_h2=Read Only Databases in Zip or Jar File -features_1545_p=\ To create a read-only database in a zip file, first create a regular persistent database, and then create a backup. The database must not have pending changes, that means you need to close all connections to the database first. If you are using a database named test, an easy way to create a zip file is using the Backup tool. You can start the tool from the command line, or from within the H2 Console (Tools - Backup). Please note that the database must be closed when the backup is created. Therefore, the SQL statement BACKUP TO can not be used. -features_1546_p=\ When the zip file is created, you can open the database in the zip file using the following database URL\: -features_1547_p=\ 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; therefore large databases are supported as well. The same indexes are used as when using a regular database. -features_1548_h2=Graceful Handling of Low Disk Space Situations -features_1549_p=\ If the database needs more disk space, it calls the database event listener if one is installed. The application may then delete temporary files, or display a message and wait until the user has resolved the problem. To install a listener, run the SQL statement SET DATABASE_EVENT_LISTENER or use a database 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. -features_1550_h3=Opening a Corrupted Database -features_1551_p=\ If a database cannot 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. -features_1552_h2=Computed Columns / Function Based Index -features_1553_p=\ 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, create a computed column with the upper-case version of the original column, and create an index for this column\: -features_1554_p=\ 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\: -features_1555_h2=Multi-Dimensional Indexes -features_1556_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. -features_1557_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). -features_1558_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. 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. -features_1559_h2=Using Passwords -features_1560_h3=Using Secure Passwords -features_1561_p=\ Remember that weak passwords can be broken regardless of the encryption and security protocols. 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\: -features_1562_code=i'sE2rtPiUKtT -features_1563_p=\ from the sentence it's easy to remember this password if you know the trick. -features_1564_h3=Passwords\: Using Char Arrays instead of Strings -features_1565_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). -features_1566_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. -features_1567_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\: -features_1568_p=\ This example requires Java 1.6. When using Swing, use javax.swing.JPasswordField. -features_1569_h3=Passing the User Name and/or Password in the URL -features_1570_p=\ Instead of passing the user name as a separate parameter as in Connection conn \= DriverManager. getConnection("jdbc\:h2\:~/test", "sa", "123"); the user name (and/or password) can be supplied in the URL itself\: Connection conn \= DriverManager. getConnection("jdbc\:h2\:~/test;USER\=sa;PASSWORD\=123"); The settings in the URL override the settings passed as a separate parameter. -features_1571_h2=User-Defined Functions and Stored Procedures -features_1572_p=\ In addition to the built-in functions, this database supports user-defined Java functions. In this database, Java functions can be used as stored procedures as well. A function must be declared (registered) before it can be used. A function can be defined using source code, or as a reference to a compiled class that is available in the classpath. By default, the function aliases are stored in the current schema. -features_1573_h3=Referencing a Compiled Method -features_1574_p=\ When referencing a method, the class must already be compiled and included in the classpath where the database is running. Only static Java methods are supported; both the class and the method must be public. Example Java class\: -features_1575_p=\ The Java function must be registered in the database by calling CREATE ALIAS ... FOR\: -features_1576_p=\ For a complete sample application, see src/test/org/h2/samples/Function.java. -features_1577_h3=Declaring Functions as Source Code -features_1578_p=\ When defining a function alias with source code, the database tries to compile the source code using the Sun Java compiler (the class com.sun.tools.javac.Main) if the tools.jar is in the classpath. If not, javac is run as a separate process. Only the source code is stored in the database; the class is compiled each time the database is re-opened. Source code is usually passed as dollar quoted text to avoid escaping problems, however single quotes can be used as well. Example\: -features_1579_p=\ The method name (nextPrime in the example above) is ignored. By default, the three packages java.util, java.math, java.sql are imported. If different import statements are required, they must be declared at the beginning and separated with the tag @CODE\: -features_1580_p=\ The following template is used to create a complete Java class\: -features_1581_h3=Function Data Type Mapping -features_1582_p=\ Functions that accept non-nullable parameters such as int will not be called if one of those parameters is NULL. Instead, 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. -features_1583_p=\ SQL types are mapped to Java classes and vice-versa as in the JDBC API. For details, see Data Types. There are two special cases\: java.lang.Object is mapped to OTHER (a serialized object). Therefore, java.lang.Object can not be used to match all SQL types (matching all SQL types is not supported). The second special case is Object[]\: arrays of any class are mapped to ARRAY. -features_1584_h3=Functions That Require a Connection -features_1585_p=\ 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. -features_1586_h3=Functions Throwing an Exception -features_1587_p=\ If a function throws an exception, then the current statement is rolled back and the exception is thrown to the application. SQLException are directly re-thrown to the calling application; all other exceptions are first converted to a SQLException. -features_1588_h3=Functions Returning a Result Set -features_1589_p=\ Functions may returns a result set. Such a function can be called with the CALL statement\: -features_1590_h3=Using SimpleResultSet -features_1591_p=\ A function can create a result set using the SimpleResultSet tool\: -features_1592_h3=Using a Function as a Table -features_1593_p=\ 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 (maybe 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. -features_1594_h2=Triggers -features_1595_p=\ 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. It is also possible to use triggers to simulate materialized views. For a complete sample application, see src/test/org/h2/samples/TriggerSample.java. A Java trigger must implement the interface org.h2.api.Trigger. The trigger class must be available in the classpath of the database engine (when using the server mode, it must be in the classpath of the server). -features_1596_p=\ The connection can be used to query or update data in other tables. The trigger then needs to be defined in the database\: -features_1597_p=\ The trigger can be used to veto a change by throwing a SQLException. -features_1598_h2=Compacting a Database -features_1599_p=\ Empty space in the database file re-used automatically. When closing the database, the database is automatically compacted for up to 1 second by default. To compact more, use the SQL statement SHUTDOWN COMPACT. However re-creating the database may further reduce the database size because this will re-build the indexes. Here is a sample function to do this\: -features_1600_p=\ See also the sample application org.h2.samples.Compact. The commands SCRIPT / RUNSCRIPT can be used as well to create a backup of a database and re-build the database from the script. -features_1601_h2=Cache Settings -features_1602_p=\ The database keeps most frequently used data in the main memory. 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\=131072), or it can be changed at runtime using SET CACHE_SIZE size. The size of the cache, as represented by CACHE_SIZE is measured in KB, with each KB being 1024 bytes. This setting has no effect for in-memory databases. For persistent databases, the setting is stored in the database and re-used when the database is opened the next time. However, when opening an existing database, the cache size is set to at most half the amount of memory available for the virtual machine (Runtime.getRuntime().maxMemory()), even if the cache size setting stored in the database is larger; however the setting stored in the database is kept. Setting the cache size in the database URL or explicitly using SET CACHE_SIZE overrides this value (even if larger than the physical memory). To get the current used maximum cache size, use the query SELECT * FROM INFORMATION_SCHEMA.SETTINGS WHERE NAME \= 'info.CACHE_MAX_SIZE' -features_1603_p=\ Also included is an experimental second level soft reference cache. Rows in this cache are only garbage collected on low memory. By default the second level cache is disabled. To enable it, use the prefix SOFT_. Example\: jdbc\:h2\:~/test;CACHE_TYPE\=SOFT_LRU. The cache might not actually improve performance. If you plan to use it, please run your own test cases first. -features_1604_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. -fragments_1000_b=Search\: -fragments_1001_td=Highlight keyword(s) -fragments_1002_a=Home -fragments_1003_a=Download -fragments_1004_a=Cheat Sheet -fragments_1005_b=Documentation -fragments_1006_a=Quickstart -fragments_1007_a=Installation -fragments_1008_a=Tutorial -fragments_1009_a=Features -fragments_1010_a=Performance -fragments_1011_a=Advanced -fragments_1012_b=Reference -fragments_1013_a=SQL Grammar -fragments_1014_a=Functions -fragments_1015_a=Data Types -fragments_1016_a=Javadoc -fragments_1017_a=PDF (1 MB) -fragments_1018_b=Support -fragments_1019_a=FAQ -fragments_1020_a=Error Analyzer -fragments_1021_a=Google Group (English) -fragments_1022_a=Google Group (Japanese) -fragments_1023_a=Google Group (Chinese) -fragments_1024_b=Appendix -fragments_1025_a=JaQu -fragments_1026_a=Build -fragments_1027_a=History & Roadmap -fragments_1028_a=Links -fragments_1029_a=License -fragments_1030_td=  -frame_1000_h1=H2 Database Engine -frame_1001_p=\ Welcome to H2, the free SQL database. The main feature of H2 are\: -frame_1002_li=It is free to use for everybody, source code is included -frame_1003_li=Written in Java, but also available as native executable -frame_1004_li=JDBC and (partial) ODBC API -frame_1005_li=Embedded and client/server modes -frame_1006_li=Clustering is supported -frame_1007_li=A web client is included -frame_1008_h2=No Javascript -frame_1009_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. -frame_1010_p=\ Please enable Javascript, or go ahead without it\: H2 Database Engine -history_1000_h1=History and Roadmap -history_1001_a=\ Change Log -history_1002_a=\ Roadmap -history_1003_a=\ History of this Database Engine -history_1004_a=\ Why Java -history_1005_a=\ Supporters -history_1006_h2=Change Log -history_1007_p=\ The up-to-date change log is available at http\://www.h2database.com/html/changelog.html -history_1008_h2=Roadmap -history_1009_p=\ The current roadmap is available at http\://www.h2database.com/html/roadmap.html -history_1010_h2=History of this Database Engine -history_1011_p=\ The development of H2 was started in May 2004, but it was first published on December 14th 2005. The main author of H2, Thomas Mueller, is also the original developer of Hypersonic SQL. In 2001, he joined PointBase Inc. where he wrote PointBase Micro, a commercial Java SQL database. At that point, he had to discontinue Hypersonic SQL. The HSQLDB Group was formed to continued to work on the Hypersonic SQL codebase. The name H2 stands for Hypersonic 2, however H2 does not share code with Hypersonic SQL or HSQLDB. H2 is built from scratch. -history_1012_h2=Why Java -history_1013_p=\ The main reasons to use a Java database are\: -history_1014_li=Very simple to integrate in Java applications -history_1015_li=Support for many different platforms -history_1016_li=More secure than native applications (no buffer overflows) -history_1017_li=User defined functions (or triggers) run very fast -history_1018_li=Unicode support -history_1019_p=\ Some think Java is too slow for low level operations, but this is no longer true. Garbage collection for example is now faster than manual memory management. -history_1020_p=\ Developing Java code is faster than developing C or C++ code. When using Java, most time can be spent on improving the algorithms instead of porting the code to different platforms or doing memory management. Features such as Unicode and network libraries are already built-in. In Java, writing secure code is easier because buffer overflows can not occur. Features such as reflection can be used for randomized testing. -history_1021_p=\ Java is future proof\: a lot of companies support Java. Java is now open source. -history_1022_p=\ To increase the portability and ease of use, this software depends on very few libraries. Features that are not available in open source Java implementations (such as Swing) are not used, or only used for optional features. -history_1023_h2=Supporters -history_1024_p=\ Many thanks for those who reported bugs, gave valuable feedback, spread the word, and translated this project. Also many thanks to the donors\: -history_1025_a=Code Lutin, France -history_1026_a=Code 42 Software, Inc., Minneapolis -history_1027_a=NetSuxxess GmbH, Germany -history_1028_a=Poker Copilot, Steve McLeod, Germany -history_1029_a=SkyCash, Poland -history_1030_a=Lumber-mill, Inc., Japan -history_1031_li=Martin Wildam, Austria -history_1032_li=Donald Bleyl, USA -history_1033_li=Frank Berger, Germany -history_1034_li=Ashwin Jayaprakash, USA -history_1035_li=Florent Ramiere, France -history_1036_li=Jun Iyama, Japan -history_1037_li=Antonio Casqueiro, Portugal -history_1038_li=Oliver Computing LLC, USA -history_1039_li=Harpal Grover Consulting Inc., USA -history_1040_li=Elisabetta Berlini, Italy -history_1041_li=William Gilbert, USA -history_1042_li=Antonio Dieguez Rojas, Chile -history_1043_a=Ontology Works, USA -history_1044_li=Pete Haidinyak, USA -history_1045_li=William Osmond, USA -history_1046_li=Joachim Ansorg, Germany -history_1047_li=Oliver Soerensen, Germany -history_1048_li=Christos Vasilakis, Greece -history_1049_li=Fyodor Kupolov, Denmark -history_1050_li=Jakob Jenkov, Denmark -history_1051_li=Stéphane Chartrand, Switzerland -history_1052_li=Glenn Kidd, USA -history_1053_li=Gustav Trede, Sweden -history_1054_li=Joonas Pulakka, Finland -history_1055_li=Bjorn Darri Sigurdsson, Iceland -history_1056_li=Iyama Jun, Japan -history_1057_li=Gray Watson, USA -history_1058_li=Erik Dick, Germany -installation_1000_h1=Installation -installation_1001_a=\ Requirements -installation_1002_a=\ Supported Platforms -installation_1003_a=\ Installing the Software -installation_1004_a=\ Directory Structure -installation_1005_h2=Requirements -installation_1006_p=\ To run the database, the following minimum software stack is known to work\: -installation_1007_li=Windows XP or Vista, Mac OS X, or Linux -installation_1008_li=Recommended Windows file system\: NTFS (FAT32 only supports files up to 4 GB) -installation_1009_li=Sun JDK 1.5 or newer -installation_1010_li=Mozilla Firefox -installation_1011_h2=Supported Platforms -installation_1012_p=\ As this database is written in Java, it can run on many different platforms. It is tested with Java 1.5 and 1.6 but can also be compiled to native code using GCJ. The source code does not use features of Java 1.6. Currently, the database is developed and tested on Windows XP and Mac OS X using the Sun JDK 1.5, but it also works in many other operating systems and using other Java runtime environments. -installation_1013_h2=Installing the Software -installation_1014_p=\ To install the software, run the installer or unzip it to a directory of your choice. -installation_1015_h2=Directory Structure -installation_1016_p=\ After installing, you should get the following directory structure\: -installation_1017_th=Directory -installation_1018_th=Contents -installation_1019_td=bin -installation_1020_td=JAR and batch files -installation_1021_td=docs -installation_1022_td=Documentation -installation_1023_td=docs/html -installation_1024_td=HTML pages -installation_1025_td=docs/javadoc -installation_1026_td=Javadoc files -installation_1027_td=ext -installation_1028_td=External dependencies (downloaded when building) -installation_1029_td=service -installation_1030_td=Tools to run the database as a Windows Service -installation_1031_td=src -installation_1032_td=Source files -installation_1033_td=src/docsrc -installation_1034_td=Documentation sources -installation_1035_td=src/installer -installation_1036_td=Installer, shell, and release build script -installation_1037_td=src/main -installation_1038_td=Database engine source code -installation_1039_td=src/test -installation_1040_td=Test source code -installation_1041_td=src/tools -installation_1042_td=Tools and database adapters source code -jaqu_1000_h1=JaQu -jaqu_1001_a=\ What is JaQu -jaqu_1002_a=\ Differences to Other Data Access Tools -jaqu_1003_a=\ Current State -jaqu_1004_a=\ Building the JaQu Library -jaqu_1005_a=\ Requirements -jaqu_1006_a=\ Example Code -jaqu_1007_a=\ Configuration -jaqu_1008_a=\ Natural Syntax -jaqu_1009_a=\ Other Ideas -jaqu_1010_a=\ Similar Projects -jaqu_1011_h2=What is JaQu -jaqu_1012_p=\ JaQu stands for Java Query and allows to access databases using pure Java. JaQu provides a fluent interface (or internal DSL) to access a database. JaQu is something like LINQ for Java (LINQ stands for "language integrated query" and is a Microsoft .NET technology). The following JaQu code\: -jaqu_1013_p=\ stands for the SQL statement\: -jaqu_1014_h2=Differences to Other Data Access Tools -jaqu_1015_p=\ Unlike SQL, JaQu can be easily integrated in Java applications. Because JaQu is pure Java, auto-complete in the IDE and Javadoc and are supported. Type checking is performed by the compiler. JaQu fully protects against SQL injection. -jaqu_1016_p=\ JaQu is more a replacement for JDBC than it is a replacement for tools like Hibernate. With JaQu, you don't write SQL statements as Strings. JaQu is much smaller and simpler than other persistence frameworks such as Hibernate, but it also does not provide all the features of those. Unlike iBatis and Hibernate, no XML or annotation based configuration is required; instead the configuration (if required at all) is done in pure Java, in the application itself. -jaqu_1017_p=\ JaQu does not require or contain any data caching mechanism. Like JDBC and iBatis, JaQu provides full control over when and what SQL statements are executed (but without having to write SQL statements as Strings). -jaqu_1018_h3=Restrictions -jaqu_1019_p=\ Primitive types (eg. boolean, int, long, double) are not supported. Use java.lang.Boolean, Integer, Long, Double instead. -jaqu_1020_h3=Why in Java? -jaqu_1021_p=\ Most people use Java in their application. Mixing Java and another language (for example Scala or Groovy) in the same application is complicated\: you would need to split the application and database code. -jaqu_1022_h2=Current State -jaqu_1023_p=\ Currently, JaQu is only tested with the H2 database. The API may change in future versions. JaQu is not part of the h2 jar file, however the source code is included in H2, under\: -jaqu_1024_code=src/test/org/h2/test/jaqu/* -jaqu_1025_li=\ (samples and tests) -jaqu_1026_code=src/tools/org/h2/jaqu/* -jaqu_1027_li=\ (framework) -jaqu_1028_h2=Building the JaQu Library -jaqu_1029_p=\ To create the JaQu jar file, run\: build jarJaqu. This will create the file bin/h2jaqu.jar. -jaqu_1030_h2=Requirements -jaqu_1031_p=\ JaQu requires Java 1.5. Annotations are not need. Currently, JaQu is only tested with the H2 database engine, however in theory it should work with any database that supports the JDBC API. -jaqu_1032_h2=Example Code -jaqu_1033_h2=Configuration -jaqu_1034_p=\ JaQu does not require any configuration when using the default mapping. To define table indices, or if you want to map a class to a table with a different name, or a field to a column with another name, create a function called define in the data class. Example\: -jaqu_1035_p=\ The method define() contains the mapping definition. It is called once when the class is used for the first time. Like annotations, the mapping is defined in the class itself. Unlike when using annotations, the compiler can check the syntax even for multi-column objects (multi-column indexes, multi-column primary keys and so on). Because the definition is written in regular Java, the configuration can depend on the environment. This is not possible using annotations. Unlike XML mapping configuration, the configuration is integrated in the class itself. -jaqu_1036_h2=Natural Syntax -jaqu_1037_p=The plan is to support more natural (pure Java) syntax in conditions. To do that, the condition class is de-compiled to a SQL condition. A proof of concept decompiler is included (but it doesn't work yet). The planned syntax is\: -jaqu_1038_h2=Other Ideas -jaqu_1039_p=\ This project has just been started, and nothing is fixed yet. Some ideas for what to implement are\: -jaqu_1040_li=Support queries on collections (instead of using a database). -jaqu_1041_li=Provide API level compatibility with JPA (so that JaQu can be used as an extension of JPA). -jaqu_1042_li=Internally use a JPA implementation (for example Hibernate) instead of SQL directly. -jaqu_1043_li=Use PreparedStatements and cache them. -jaqu_1044_h2=Similar Projects -jaqu_1045_a=Cement Framework -jaqu_1046_a=Dreamsource ORM -jaqu_1047_a=Empire-db -jaqu_1048_a=JEQUEL\: Java Embedded QUEry Language -jaqu_1049_a=Joist -jaqu_1050_a=JoSQL -jaqu_1051_a=LIQUidFORM -jaqu_1052_a=Quaere (Alias implementation) -jaqu_1053_a=Quaere -jaqu_1054_a=Querydsl -jaqu_1055_a=Squill -license_1000_h1=License -license_1001_h2=Summary and License FAQ -license_1002_p=\ H2 is dual licensed and available under a modified version of the MPL 1.1 (Mozilla Public License) or under the (unmodified) EPL 1.0 (Eclipse Public License). The changes to the MPL are -license_1003_em=underlined. There is a License FAQ for both the MPL and the EPL, most of that is applicable to the H2 License as well. -license_1004_li=You can use H2 for free. You can integrate it into your application (including commercial applications), and you can distribute it. -license_1005_li=Files containing only your code are not covered by this license (it is 'commercial friendly'). -license_1006_li=Modifications to the H2 source code must be published. -license_1007_li=You don't need to provide the source code of H2 if you did not modify anything. -license_1008_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\: 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. It seems 'bungisoft' does not exist any more, but you can use the Wayback Machine and visit old web pages of http\://www.bungisoft.com. -license_1009_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. -license_1010_h2=H2 License, Version 1.0 -license_1011_h3=1. Definitions -license_1012_b=1.0.1. "Commercial Use" -license_1013_p=\ means distribution or otherwise making the Covered Code available to a third party. -license_1014_b=1.1. "Contributor" -license_1015_p=\ means each entity that creates or contributes to the creation of Modifications. -license_1016_b=1.2. "Contributor Version" -license_1017_p=\ means the combination of the Original Code, prior Modifications used by a Contributor, and the Modifications made by that particular Contributor. -license_1018_b=1.3. "Covered Code" -license_1019_p=\ means the Original Code or Modifications or the combination of the Original Code and Modifications, in each case including portions thereof. -license_1020_b=1.4. "Electronic Distribution Mechanism" -license_1021_p=\ means a mechanism generally accepted in the software development community for the electronic transfer of data. -license_1022_b=1.5. "Executable" -license_1023_p=\ means Covered Code in any form other than Source Code. -license_1024_b=1.6. "Initial Developer" -license_1025_p=\ means the individual or entity identified as the Initial Developer in the Source Code notice required by Exhibit A. -license_1026_b=1.7. "Larger Work" -license_1027_p=\ means a work which combines Covered Code or portions thereof with code not governed by the terms of this License. -license_1028_b=1.8. "License" -license_1029_p=\ means this document. -license_1030_b=1.8.1. "Licensable" -license_1031_p=\ means having the right to grant, to the maximum extent possible, whether at the time of the initial grant or subsequently acquired, any and all of the rights conveyed herein. -license_1032_b=1.9. "Modifications" -license_1033_p=\ means any addition to or deletion from the substance or structure of either the Original Code or any previous Modifications. When Covered Code is released as a series of files, a Modification is\: -license_1034_p=1.9.a. Any addition to or deletion from the contents of a file containing Original Code or previous Modifications. -license_1035_p=1.9.b. Any new file that contains any part of the Original Code or previous Modifications. -license_1036_b=1.10. "Original Code" -license_1037_p=\ means Source Code of computer software code which is described in the Source Code notice required by Exhibit A as Original Code, and which, at the time of its release under this License is not already Covered Code governed by this License. -license_1038_b=1.10.1. "Patent Claims" -license_1039_p=\ means any patent claim(s), now owned or hereafter acquired, including without limitation, method, process, and apparatus claims, in any patent Licensable by grantor. -license_1040_b=1.11. "Source Code" -license_1041_p=\ means the preferred form of the Covered Code for making modifications to it, including all modules it contains, plus any associated interface definition files, scripts used to control compilation and installation of an Executable, or source code differential comparisons against either the Original Code or another well known, available Covered Code of the Contributor's choice. The Source Code can be in a compressed or archival form, provided the appropriate decompression or de-archiving software is widely available for no charge. -license_1042_b=1.12. "You" (or "Your") -license_1043_p=\ means an individual or a legal entity exercising rights under, and complying with all of the terms of, this License or a future version of this License issued under Section 6.1. For legal entities, "You" includes any entity which controls, is controlled by, or is under common control with You. For purposes of this definition, "control" means (a) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (b) ownership of more than fifty percent (50%) of the outstanding shares or beneficial ownership of such entity. -license_1044_h3=2. Source Code License -license_1045_h4=2.1. The Initial Developer Grant -license_1046_p=\ The Initial Developer hereby grants You a world-wide, royalty-free, non-exclusive license, subject to third party intellectual property claims\: -license_1047_p=2.1.a. under intellectual property rights (other than patent or trademark) Licensable by Initial Developer to use, reproduce, modify, display, perform, sublicense and distribute the Original Code (or portions thereof) with or without Modifications, and/or as part of a Larger Work; and -license_1048_p=2.1.b. under Patents Claims infringed by the making, using or selling of Original Code, to make, have made, use, practice, sell, and offer for sale, and/or otherwise dispose of the Original Code (or portions thereof). -license_1049_p=2.1.c. the licenses granted in this Section 2.1 (a) and (b) are effective on the date Initial Developer first distributes Original Code under the terms of this License. -license_1050_p=2.1.d. Notwithstanding Section 2.1 (b) above, no patent license is granted\: 1) for code that You delete from the Original Code; 2) separate from the Original Code; or 3) for infringements caused by\: i) the modification of the Original Code or ii) the combination of the Original Code with other software or devices. -license_1051_h4=2.2. Contributor Grant -license_1052_p=\ Subject to third party intellectual property claims, each Contributor hereby grants You a world-wide, royalty-free, non-exclusive license -license_1053_p=2.2.a. under intellectual property rights (other than patent or trademark) Licensable by Contributor, to use, reproduce, modify, display, perform, sublicense and distribute the Modifications created by such Contributor (or portions thereof) either on an unmodified basis, with other Modifications, as Covered Code and/or as part of a Larger Work; and -license_1054_p=2.2.b. under Patent Claims infringed by the making, using, or selling of Modifications made by that Contributor either alone and/or in combination with its Contributor Version (or portions of such combination), to make, use, sell, offer for sale, have made, and/or otherwise dispose of\: 1) Modifications made by that Contributor (or portions thereof); and 2) the combination of Modifications made by that Contributor with its Contributor Version (or portions of such combination). -license_1055_p=2.2.c. the licenses granted in Sections 2.2 (a) and 2.2 (b) are effective on the date Contributor first makes Commercial Use of the Covered Code. -license_1056_p=2.2.c. Notwithstanding Section 2.2 (b) above, no patent license is granted\: 1) for any code that Contributor has deleted from the Contributor Version; 2) separate from the Contributor Version; 3) for infringements caused by\: i) third party modifications of Contributor Version or ii) the combination of Modifications made by that Contributor with other software (except as part of the Contributor Version) or other devices; or 4) under Patent Claims infringed by Covered Code in the absence of Modifications made by that Contributor. -license_1057_h3=3. Distribution Obligations -license_1058_h4=3.1. Application of License -license_1059_p=\ The Modifications which You create or to which You contribute are governed by the terms of this License, including without limitation Section 2.2. 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 6.1, and You must include a copy of this License with every copy of the Source Code You distribute. You may not offer or impose any terms on any Source Code version that alters or restricts the applicable version of this License or the recipients' rights hereunder. However, You may include an additional document offering the additional rights described in Section 3.5. -license_1060_h4=3.2. Availability of Source Code -license_1061_p=\ 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, must remain available for at least twelve (12) months after the date it initially became available, or at least six (6) months after a subsequent version of that particular Modification has been made available to such recipients. You are responsible for ensuring that the Source Code version remains available even if the Electronic Distribution Mechanism is maintained by a third party. -license_1062_h4=3.3. Description of Modifications -license_1063_p=\ 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 (a) the Source Code, and (b) in any notice in an Executable version or related documentation in which You describe the origin or ownership of the Covered Code. -license_1064_h4=3.4. Intellectual Property Matters -license_1065_b=3.4.a. Third Party Claims\: -license_1066_p=\ If Contributor has knowledge that a license under a third party's intellectual property rights is required to exercise the rights granted by such Contributor under Sections 2.1 or 2.2, Contributor must include a text file with the Source Code distribution titled "LEGAL" which describes the claim and the party making the claim in sufficient detail that a recipient will know whom to contact. If Contributor obtains such knowledge after the Modification is made available as described in Section 3.2, Contributor shall promptly modify the LEGAL file in all copies Contributor makes available thereafter and shall take other steps (such as notifying appropriate mailing lists or newsgroups) reasonably calculated to inform those who received the Covered Code that new knowledge has been obtained. -license_1067_b=3.4.b. Contributor APIs\: -license_1068_p=\ If Contributor's Modifications include an application programming interface and Contributor has knowledge of patent licenses which are reasonably necessary to implement that API, Contributor must also include this information in the legal file. -license_1069_b=3.4.c. Representations\: -license_1070_p=\ Contributor represents that, except as disclosed pursuant to Section 3.4 (a) above, Contributor believes that Contributor's Modifications are Contributor's original creation(s) and/or Contributor has sufficient rights to grant the rights conveyed by this License. -license_1071_h4=3.5. Required Notices -license_1072_p=\ You must duplicate the notice in Exhibit 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 Modification(s) You may add your name as a Contributor to the notice described in Exhibit A. You must also duplicate this License in any documentation for the Source Code where You describe recipients' rights or ownership rights relating to Covered Code. You may choose to offer, and to charge a fee for, warranty, support, indemnity or liability obligations to one or more recipients of Covered Code. However, You may do so only on Your own behalf, and not on behalf of the Initial Developer or any Contributor. You must make it absolutely clear than any such warranty, support, indemnity or liability obligation is offered by You alone, and You hereby agree to indemnify the Initial Developer 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. -license_1073_h4=3.6. Distribution of Executable Versions -license_1074_p=\ You may distribute Covered Code in Executable form only if the requirements of Sections 3.1, 3.2, 3.3, 3.4 and 3.5 have been met for that Covered Code, and if You include a notice stating that the Source Code version of the Covered Code is available under the terms of this License, including a description of how and where You have fulfilled the obligations of Section 3.2. The notice must be conspicuously included in any notice in an Executable version, related documentation or collateral in which You describe recipients' rights relating to the Covered Code. You may distribute the Executable version of Covered Code or ownership rights under a license of Your choice, which may contain terms different from this License, provided that You are in compliance with the terms of this License and that the license for the Executable version does not attempt to limit or alter the recipient's rights in the Source Code version from the rights set forth in this License. If You distribute the Executable version under a different license You must make it absolutely clear that any terms which differ from this License are offered by You alone, not by the Initial Developer or any Contributor. You hereby agree to indemnify the Initial Developer and every Contributor for any liability incurred by the Initial Developer or such Contributor as a result of any such terms You offer. -license_1075_h4=3.7. Larger Works -license_1076_p=\ 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. -license_1077_h3=4. Inability to Comply Due to Statute or Regulation. -license_1078_p=\ 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 legal file described in Section 3.4 and must be included with all distributions of the Source Code. 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. -license_1079_h3=5. Application of this License. -license_1080_p=\ This License applies to code to which the Initial Developer has attached the notice in Exhibit A and to related Covered Code. -license_1081_h3=6. Versions of the License. -license_1082_h4=6.1. New Versions -license_1083_p=\ The -license_1084_em=H2 Group may publish revised and/or new versions of the License from time to time. Each version will be given a distinguishing version number. -license_1085_h4=6.2. Effect of New Versions -license_1086_p=\ 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 -license_1087_em=H2 Group. No one other than the -license_1088_em=H2 Group has the right to modify the terms applicable to Covered Code created under this License. -license_1089_h4=6.3. Derivative Works -license_1090_p=\ 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 -license_1091_em="H2 Group", "H2" or any confusingly similar phrase do not appear in your license (except to note that your license differs from this License) and (b) otherwise make it clear that Your version of the license contains terms which differ from the -license_1092_em=H2 License. (Filling in the name of the Initial Developer, Original Code or Contributor in the notice described in Exhibit A shall not of themselves be deemed to be modifications of this License.) -license_1093_h3=7. Disclaimer of Warranty -license_1094_p=\ 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 the covered code is with you. Should any covered code prove defective in any respect, you (not the initial developer or any other contributor) assume the cost of any necessary servicing, repair or correction. This disclaimer of warranty constitutes an essential part of this license. No use of any covered code is authorized hereunder except under this disclaimer. -license_1095_h3=8. Termination -license_1096_p=8.1. This License and the rights granted hereunder will terminate automatically if You fail to comply with terms herein and fail to cure such breach 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. -license_1097_p=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\: -license_1098_p=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 Sections 2.1 and/or 2.2 of this License shall, upon 60 days notice from Participant terminate prospectively, unless if within 60 days after receipt of notice You either\: (i) agree in writing to pay Participant a mutually agreeable reasonable royalty for Your past and future use of Modifications made by such Participant, or (ii) withdraw Your litigation claim with respect to the Contributor Version against such Participant. If within 60 days of notice, a reasonable royalty and payment arrangement are not mutually agreed upon in writing by the parties or the litigation claim is not withdrawn, the rights granted by Participant to You under Sections 2.1 and/or 2.2 automatically terminate at the expiration of the 60 day notice period specified above. -license_1099_p=8.2.b. any software, hardware, or device, other than such Participant's Contributor Version, directly or indirectly infringes any patent, then any rights granted to You by such Participant under Sections 2.1(b) and 2.2(b) are revoked effective as of the date You first made, used, sold, distributed, or had made, Modifications made by that Participant. -license_1100_p=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 initiation of patent infringement litigation, then the reasonable value of the licenses granted by such Participant under Sections 2.1 or 2.2 shall be taken into account in determining the amount or value of any payment or license. -license_1101_p=8.4. In the event of termination under Sections 8.1 or 8.2 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. -license_1102_h3=9. Limitation of Liability -license_1103_p=\ 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 consequential damages of any character including, without limitation, damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses, even if such party shall have been informed of the possibility of such damages. This limitation of liability shall not apply to liability for death or personal injury resulting from such party's negligence to the extent applicable law prohibits such limitation. Some jurisdictions do not allow the exclusion or limitation of incidental or consequential damages, so this exclusion and limitation may not apply to you. -license_1104_h3=10. United States Government End Users -license_1105_p=\ 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. -license_1106_h3=11. Miscellaneous -license_1107_p=\ 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 California law provisions (except to the extent applicable law, if any, provides otherwise), excluding its conflict-of-law provisions. With respect to disputes in which at least one party is a citizen of, or an entity chartered or registered to do business in United States of America, any litigation relating to this License shall be subject to the jurisdiction of the Federal Courts of the Northern District of California, with venue lying in Santa Clara County, California, with the losing party responsible for costs, including without limitation, court costs and reasonable attorneys' fees and expenses. The application of the United Nations Convention on Contracts for the International Sale of Goods is expressly excluded. Any law or regulation which provides that the language of a contract shall be construed against the drafter shall not apply to this License. -license_1108_h3=12. Responsibility for Claims -license_1109_p=\ 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. -license_1110_h3=13. Multiple-Licensed Code -license_1111_p=\ 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 described in Exhibit A. -license_1112_h3=Exhibit A -license_1113_h2=Eclipse Public License - Version 1.0 -license_1114_p=\ THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS ECLIPSE PUBLIC LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT. -license_1115_h3=1. DEFINITIONS -license_1116_p=\ "Contribution" means\: -license_1117_p=\ a) in the case of the initial Contributor, the initial code and documentation distributed under this Agreement, and -license_1118_p=\ b) in the case of each subsequent Contributor\: -license_1119_p=\ i) changes to the Program, and -license_1120_p=\ ii) additions to the Program; -license_1121_p=\ where such changes and/or additions to the Program originate from and are distributed by that particular Contributor. A Contribution 'originates' from a Contributor if it was added to the Program by such Contributor itself or anyone acting on such Contributor's behalf. Contributions do not include additions to the Program which\: (i) are separate modules of software distributed in conjunction with the Program under their own license agreement, and (ii) are not derivative works of the Program. -license_1122_p=\ "Contributor" means any person or entity that distributes the Program. -license_1123_p=\ "Licensed Patents " mean patent claims licensable by a Contributor which are necessarily infringed by the use or sale of its Contribution alone or when combined with the Program. -license_1124_p=\ "Program" means the Contributions distributed in accordance with this Agreement. -license_1125_p=\ "Recipient" means anyone who receives the Program under this Agreement, including all Contributors. -license_1126_h3=2. GRANT OF RIGHTS -license_1127_p=\ a) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free copyright license to reproduce, prepare derivative works of, publicly display, publicly perform, distribute and sublicense the Contribution of such Contributor, if any, and such derivative works, in source code and object code form. -license_1128_p=\ b) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free patent license under Licensed Patents to make, use, sell, offer to sell, import and otherwise transfer the Contribution of such Contributor, if any, in source code and object code form. This patent license shall apply to the combination of the Contribution and the Program if, at the time the Contribution is added by the Contributor, such addition of the Contribution causes such combination to be covered by the Licensed Patents. The patent license shall not apply to any other combinations which include the Contribution. No hardware per se is licensed hereunder. -license_1129_p=\ c) Recipient understands that although each Contributor grants the licenses to its Contributions set forth herein, no assurances are provided by any Contributor that the Program does not infringe the patent or other intellectual property rights of any other entity. Each Contributor disclaims any liability to Recipient for claims brought by any other entity based on infringement of intellectual property rights or otherwise. As a condition to exercising the rights and licenses granted hereunder, each Recipient hereby assumes sole responsibility to secure any other intellectual property rights needed, if any. For example, if a third party patent license is required to allow Recipient to distribute the Program, it is Recipient's responsibility to acquire that license before distributing the Program. -license_1130_p=\ d) Each Contributor represents that to its knowledge it has sufficient copyright rights in its Contribution, if any, to grant the copyright license set forth in this Agreement. -license_1131_h3=3. REQUIREMENTS -license_1132_p=\ A Contributor may choose to distribute the Program in object code form under its own license agreement, provided that\: -license_1133_p=\ a) it complies with the terms and conditions of this Agreement; and -license_1134_p=\ b) its license agreement\: -license_1135_p=\ i) effectively disclaims on behalf of all Contributors all warranties and conditions, express and implied, including warranties or conditions of title and non-infringement, and implied warranties or conditions of merchantability and fitness for a particular purpose; -license_1136_p=\ ii) effectively excludes on behalf of all Contributors all liability for damages, including direct, indirect, special, incidental and consequential damages, such as lost profits; -license_1137_p=\ iii) states that any provisions which differ from this Agreement are offered by that Contributor alone and not by any other party; and -license_1138_p=\ iv) states that source code for the Program is available from such Contributor, and informs licensees how to obtain it in a reasonable manner on or through a medium customarily used for software exchange. -license_1139_p=\ When the Program is made available in source code form\: -license_1140_p=\ a) it must be made available under this Agreement; and -license_1141_p=\ b) a copy of this Agreement must be included with each copy of the Program. -license_1142_p=\ Contributors may not remove or alter any copyright notices contained within the Program. -license_1143_p=\ Each Contributor must identify itself as the originator of its Contribution, if any, in a manner that reasonably allows subsequent Recipients to identify the originator of the Contribution. -license_1144_h3=4. COMMERCIAL DISTRIBUTION -license_1145_p=\ Commercial distributors of software may accept certain responsibilities with respect to end users, business partners and the like. While this license is intended to facilitate the commercial use of the Program, the Contributor who includes the Program in a commercial product offering should do so in a manner which does not create potential liability for other Contributors. Therefore, if a Contributor includes the Program in a commercial product offering, such Contributor ("Commercial Contributor") hereby agrees to defend and indemnify every other Contributor ("Indemnified Contributor") against any losses, damages and costs (collectively "Losses") arising from claims, lawsuits and other legal actions brought by a third party against the Indemnified Contributor to the extent caused by the acts or omissions of such Commercial Contributor in connection with its distribution of the Program in a commercial product offering. The obligations in this section do not apply to any claims or Losses relating to any actual or alleged intellectual property infringement. In order to qualify, an Indemnified Contributor must\: a) promptly notify the Commercial Contributor in writing of such claim, and b) allow the Commercial Contributor to control, and cooperate with the Commercial Contributor in, the defense and any related settlement negotiations. The Indemnified Contributor may participate in any such claim at its own expense. -license_1146_p=\ For example, a Contributor might include the Program in a commercial product offering, Product X. That Contributor is then a Commercial Contributor. If that Commercial Contributor then makes performance claims, or offers warranties related to Product X, those performance claims and warranties are such Commercial Contributor's responsibility alone. Under this section, the Commercial Contributor would have to defend claims against the other Contributors related to those performance claims and warranties, and if a court requires any other Contributor to pay any damages as a result, the Commercial Contributor must pay those damages. -license_1147_h3=5. NO WARRANTY -license_1148_p=\ EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is solely responsible for determining the appropriateness of using and distributing the Program and assumes all risks associated with its exercise of rights under this Agreement, including but not limited to the risks and costs of program errors, compliance with applicable laws, damage to or loss of data, programs or equipment, and unavailability or interruption of operations. -license_1149_h3=6. DISCLAIMER OF LIABILITY -license_1150_p=\ EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. -license_1151_h3=7. GENERAL -license_1152_p=\ If any provision of this Agreement is invalid or unenforceable under applicable law, it shall not affect the validity or enforceability of the remainder of the terms of this Agreement, and without further action by the parties hereto, such provision shall be reformed to the minimum extent necessary to make such provision valid and enforceable. -license_1153_p=\ If Recipient institutes patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Program itself (excluding combinations of the Program with other software or hardware) infringes such Recipient's patent(s), then such Recipient's rights granted under Section 2(b) shall terminate as of the date such litigation is filed. -license_1154_p=\ All Recipient's rights under this Agreement shall terminate if it fails to comply with any of the material terms or conditions of this Agreement and does not cure such failure in a reasonable period of time after becoming aware of such noncompliance. If all Recipient's rights under this Agreement terminate, Recipient agrees to cease use and distribution of the Program as soon as reasonably practicable. However, Recipient's obligations under this Agreement and any licenses granted by Recipient relating to the Program shall continue and survive. -license_1155_p=\ Everyone is permitted to copy and distribute copies of this Agreement, but in order to avoid inconsistency the Agreement is copyrighted and may only be modified in the following manner. The Agreement Steward reserves the right to publish new versions (including revisions) of this Agreement from time to time. No one other than the Agreement Steward has the right to modify this Agreement. The Eclipse Foundation is the initial Agreement Steward. The Eclipse Foundation may assign the responsibility to serve as the Agreement Steward to a suitable separate entity. Each new version of the Agreement will be given a distinguishing version number. The Program (including Contributions) may always be distributed subject to the version of the Agreement under which it was received. In addition, after a new version of the Agreement is published, Contributor may elect to distribute the Program (including its Contributions) under the new version. Except as expressly stated in Sections 2(a) and 2(b) above, Recipient receives no rights or licenses to the intellectual property of any Contributor under this Agreement, whether expressly, by implication, estoppel or otherwise. All rights in the Program not expressly granted under this Agreement are reserved. -license_1156_p=\ This Agreement is governed by the laws of the State of New York and the intellectual property laws of the United States of America. No party to this Agreement will bring a legal action under this Agreement more than one year after the cause of action arose. Each party waives its rights to a jury trial in any resulting litigation. -links_1000_h1=H2 In Use and Links -links_1001_p=\ Those are just a few links to products using or supporting H2. If you want to add a link, please send it to the support email address or post it in the group. -links_1002_h2=Books -links_1003_a=\ Seam In Action -links_1004_h2=Extensions -links_1005_a=\ Grails H2 Database Plugin -links_1006_a=\ h2osgi\: OSGi for the H2 Database -links_1007_a=\ H2Sharp\: ADO.NET interface for the H2 database engine -links_1008_a=\ H2 Spatial\: spatial functions to H2 database -links_1009_h2=Blog Articles -links_1010_a=\ Analyzing CSVs with H2 in under 10 minutes (2009-12-07) -links_1011_a=\ Efficient sorting and iteration on large databases (2009-06-15) -links_1012_a=\ Porting Flexive to the H2 Database (2008-12-05) -links_1013_a=\ H2 Database with GlassFish (2008-11-24) -links_1014_a=\ Using H2 Database with Glassfish and Toplink (2008-08-07) -links_1015_a=\ H2 Database - Performance Tracing (2008-04-30) -links_1016_a=\ Testing your JDBC data access layer with DBUnit and H2 (2007-09-18) -links_1017_a=\ Open Source Databases Comparison (2007-09-11) -links_1018_a=\ The Codist\: The Open Source Frameworks I Use (2007-07-23) -links_1019_a=\ The Codist\: SQL Injections\: How Not To Get Stuck (2007-05-08) -links_1020_a=\ One Man Band\: (Helma + H2) \=\= "to easy" (2007-03-11) -links_1021_a=\ David Coldrick's Weblog\: New Version of H2 Database Released (2007-01-06) -links_1022_a=\ The Codist\: Write Your Own Database, Again (2006-11-13) -links_1023_h2=Project Pages -links_1024_a=\ Ohloh -links_1025_a=\ Freshmeat Project Page -links_1026_a=\ Free Open Source Software For Us -links_1027_a=\ Wikipedia -links_1028_a=\ Java Source Net -links_1029_a=\ Linux Package Manager -links_1030_h2=Database Frontends / Tools -links_1031_a=\ DB Solo -links_1032_p=\ SQL query tool. -links_1033_a=\ DbVisualizer -links_1034_p=\ Database tool. -links_1035_a=\ Execute Query -links_1036_p=\ Database utility written in Java. -links_1037_a=\ [fleXive] -links_1038_p=\ JavaEE 5 open source framework for the development of complex and evolving (web-)applications. -links_1039_a=\ HenPlus -links_1040_p=\ HenPlus is a SQL shell written in Java. -links_1041_a=\ RazorSQL -links_1042_p=\ An SQL query tool, database browser, SQL editor, and database administration tool. -links_1043_a=\ SQL Developer -links_1044_p=\ Universal Database Frontend. -links_1045_a=\ SQL Workbench/J -links_1046_p=\ Free DBMS-independent SQL tool. -links_1047_a=\ SQuirreL SQL Client -links_1048_p=\ Graphical tool to view the structure of a database, browse the data, issue SQL commands etc. -links_1049_a=\ SQuirreL DB Copy Plugin -links_1050_p=\ Tool to copy data from one database to another. -links_1051_h2=Products and Projects -links_1052_a=\ AccuProcess -links_1053_p=\ Visual business process modeling and simulation software for business users. -links_1054_a=\ Adeptia BPM -links_1055_p=\ A Business Process Management (BPM) suite to quickly and easily automate business processes and workflows. -links_1056_a=\ Adeptia Integration -links_1057_p=\ Process-centric, services-based application integration suite. -links_1058_a=\ Aejaks -links_1059_p=\ A server-side scripting environment to build AJAX enabled web applications. -links_1060_a=\ Axiom Stack -links_1061_p=\ A web framework that let's you write dynamic web applications with Zen-like simplicity. -links_1062_a=\ Apache Cayenne -links_1063_p=\ Open source persistence framework providing object-relational mapping (ORM) and remoting services. -links_1064_a=\ Apache Jackrabbit -links_1065_p=\ Open source implementation of the Java Content Repository API (JCR). -links_1066_a=\ Apache OpenJPA -links_1067_p=\ Open source implementation of the Java Persistence API (JPA). -links_1068_a=\ AppFuse -links_1069_p=\ Helps building web applications. -links_1070_a=\ BGBlitz -links_1071_p=\ The Swiss army knife of Backgammon. -links_1072_a=\ Blojsom -links_1073_p=\ Java-based multi-blog, multi-user software package (Mac OS X Weblog Server). -links_1074_a=\ Bonita -links_1075_p=\ Open source workflow solution for handing long-running, user-oriented processes providing out of the box workflow and business process management features. -links_1076_a=\ Bookmarks Portlet -links_1077_p=\ JSR 168 compliant bookmarks management portlet application. -links_1078_a=\ Claros inTouch -links_1079_p=\ Ajax communication suite with mail, addresses, notes, IM, and rss reader. -links_1080_a=\ CrashPlan PRO Server -links_1081_p=\ Easy and cross platform backup solution for business and service providers. -links_1082_a=\ DbUnit -links_1083_p=\ A JUnit extension (also usable with Ant) targeted for database-driven projects. -links_1084_a=\ Dinamica Framework -links_1085_p=\ Ajax/J2EE framework for RAD development (mainly oriented toward hispanic markets). -links_1086_a=\ Ebean ORM Persistence Layer -links_1087_p=\ Open source Java Object Relational Mapping tool. -links_1088_a=\ Eclipse CDO -links_1089_p=\ The CDO (Connected Data Objects) Model Repository is a distributed shared model framework for EMF models, and a fast server-based O/R mapping solution. -links_1090_a=\ Epictetus -links_1091_p=\ Free cross platform database tool. -links_1092_a=\ Fabric3 -links_1093_p=\ Fabric3 is a project implementing a federated service network based on the Service Component Architecture specification (http\://www.osoa.org). -links_1094_a=\ FIT4Data -links_1095_p=\ A testing framework for data management applications built on the Java implementation of FIT. -links_1096_a=\ Flux -links_1097_p=\ Java job scheduler, file transfer, workflow, and BPM. -links_1098_a=\ GBIF Integrated Publishing Toolkit (IPT) -links_1099_p=\ The GBIF IPT is an open source, Java based web application that connects and serves three types of biodiversity data\: taxon primary occurrence data, taxon checklists and general resource metadata. -links_1100_a=\ GNU Gluco Control -links_1101_p=\ Helps you to manage your diabetes. -links_1102_a=\ Golden T Studios -links_1103_p=\ Fun-to-play games with a simple interface. -links_1104_a=\ Group Session -links_1105_p=\ Open source web groupware. -links_1106_a=\ HA-JDBC -links_1107_p=\ High-Availability JDBC\: A JDBC proxy that provides light-weight, transparent, fault tolerant clustering capability to any underlying JDBC driver. -links_1108_a=\ Harbor -links_1109_p=\ Pojo Application Server. -links_1110_a=\ Hibernate -links_1111_p=\ Relational persistence for idiomatic Java (O-R mapping tool). -links_1112_a=\ Hibicius -links_1113_p=\ Online Banking Client for the HBCI protocol. -links_1114_a=\ ImageMapper -links_1115_p=\ ImageMapper frees users from having to use file browsers to view their images. They get fast access to images and easy cataloguing of them via a user friendly interface. -links_1116_a=\ JAMWiki -links_1117_p=\ Java-based Wiki engine. -links_1118_a=\ Jala -links_1119_p=\ Open source collection of JavaScript modules. -links_1120_a=\ Java Simon -links_1121_p=\ Simple Monitoring API. -links_1122_a=\ JBoss jBPM -links_1123_p=\ A platform for executable process languages ranging from business process management (BPM) over workflow to service orchestration. -links_1124_a=\ JBoss Jopr -links_1125_p=\ An enterprise management solution for JBoss middleware projects and other application technologies. -links_1126_a=\ JGeocoder -links_1127_p=\ Free Java geocoder. Geocoding is the process of estimating a latitude and longitude for a given location. -links_1128_a=\ JGrass -links_1129_p=\ Java Geographic Resources Analysis Support System. Free, multi platform, open source GIS based on the GIS framework of uDig. -links_1130_a=\ Jena -links_1131_p=\ Java framework for building Semantic Web applications. -links_1132_a=\ JMatter -links_1133_p=\ Framework for constructing workgroup business applications based on the Naked Objects Architectural Pattern. -links_1134_a=\ JotBot -links_1135_p=\ Records your day at user defined intervals. -links_1136_a=\ JPOX -links_1137_p=\ Java persistent objects. -links_1138_a=\ Liftweb -links_1139_p=\ A Scala-based, secure, developer friendly web framework. -links_1140_a=\ LiquiBase -links_1141_p=\ A tool to manage database changes and refactorings. -links_1142_a=\ Luntbuild -links_1143_p=\ Build automation and management tool. -links_1144_a=\ localdb -links_1145_p=\ A tool that locates the full file path of the folder containing the database files. -links_1146_a=\ Magnolia -links_1147_p=\ Microarray Data Management and Export System for PFGRC (Pathogen Functional Genomics Resource Center) Microarrays. -links_1148_a=\ MiniConnectionPoolManager -links_1149_p=\ A lightweight standalone JDBC connection pool manager. -links_1150_a=\ Mr. Persister -links_1151_p=\ Simple, small and fast object relational mapping. -links_1152_a=\ Myna Application Server -links_1153_p=\ Java web app that provides dynamic web content and Java libraries access from JavaScript. -links_1154_a=\ MyTunesRss -links_1155_p=\ MyTunesRSS lets you listen to your music wherever you are. -links_1156_a=\ NCGC CurveFit -links_1157_p=\ From\: NIH Chemical Genomics Center, National Institutes of Health, USA. An open source application in the life sciences research field. This application handles chemical structures and biological responses of thousands of compounds with the potential to handle million+ compounds. It utilizes an embedded H2 database to enable flexible query/retrieval of all data including advanced chemical substructure and similarity searching. The application highlights an automated curve fitting and classification algorithm that outperforms commercial packages in the field. Commercial alternatives are typically small desktop software that handle a few dose response curves at a time. A couple of commercial packages that do handle several thousand curves are very expensive tools (>60k USD) that require manual curation of analysis by the user; require a license to Oracle; lack advanced query/retrieval; and the ability to handle chemical structures. -links_1158_a=\ Nuxeo -links_1159_p=\ Standards-based, open source platform for building ECM applications. -links_1160_a=\ nWire -links_1161_p=\ Eclipse plug-in which expedites Java development. It's main purpose is to help developers find code quicker and easily understand how it relates to the rest of the application, thus, understand the application structure. -links_1162_a=\ Ontology Works -links_1163_p=\ This company provides semantic technologies including deductive information repositories (the Ontology Works Knowledge Servers), semantic information fusion and semantic federation of legacy databases, ontology-based domain modeling, and management of the distributed enterprise. -links_1164_a=\ Ontoprise OntoBroker -links_1165_p=\ SemanticWeb-Middleware. It supports all W3C Semantic Web recommendations\: OWL, RDF, RDFS, SPARQL, and F-Logic. -links_1166_a=\ Open Anzo -links_1167_p=\ Semantic Application Server. -links_1168_a=\ OpenTelegard -links_1169_p=\ An OpenSource BBS Software written in JRuby. -links_1170_a=\ OpenGroove -links_1171_p=\ OpenGroove is a groupware program that allows users to synchronize data. -links_1172_a=\ OpenSocial Development Environment (OSDE) -links_1173_p=\ Development tool for OpenSocial application. -links_1174_a=\ Orion -links_1175_p=\ J2EE Application Server. -links_1176_a=\ P5H2 -links_1177_p=\ A library for the Processing programming language and environment. -links_1178_a=\ Phase-6 -links_1179_p=\ A computer based learning software. -links_1180_a=\ Pickle -links_1181_p=\ Pickle is a Java library containing classes for persistence, concurrency, and logging. -links_1182_a=\ Piman -links_1183_p=\ Water treatment projects data management. -links_1184_a=\ PolePosition -links_1185_p=\ Open source database benchmark. -links_1186_a=\ Poormans -links_1187_p=\ Very basic CMS running as a SWT application and generating static html pages. -links_1188_a=\ Railo -links_1189_p=\ Railo is an alternative engine for the Cold Fusion Markup Language, that compiles code programmed in CFML into Java bytecode and executes it on a servlet engine. -links_1190_a=\ Razuna -links_1191_p=\ Open source Digital Asset Management System with integrated Web Content Management. -links_1192_a=\ RIFE -links_1193_p=\ A full-stack web application framework with tools and APIs to implement most common web features. -links_1194_a=\ Rutema -links_1195_p=\ Rutema is a test execution and management tool for heterogeneous development environments written in Ruby. -links_1196_a=\ Sava -links_1197_p=\ Open-source web-based content management system. -links_1198_a=\ Scriptella -links_1199_p=\ ETL (Extract-Transform-Load) and script execution tool. -links_1200_a=\ Sesar -links_1201_p=\ Dependency Injection Container with Aspect Oriented Programming. -links_1202_a=\ SemmleCode -links_1203_p=\ Eclipse plugin to help you improve software quality. -links_1204_a=\ SeQuaLite -links_1205_p=\ A free, light-weight, java data access framework. -links_1206_a=\ ShapeLogic -links_1207_p=\ Toolkit for declarative programming, image processing and computer vision. -links_1208_a=\ Shellbook -links_1209_p=\ Desktop publishing application. -links_1210_a=\ Signsoft intelliBO -links_1211_p=\ Persistence middleware supporting the JDO specification. -links_1212_a=\ SimpleORM -links_1213_p=\ Simple Java Object Relational Mapping. -links_1214_a=\ SymmetricDS -links_1215_p=\ A web-enabled, database independent, data synchronization/replication software. -links_1216_a=\ SmartFoxServer -links_1217_p=\ Platform for developing multiuser applications and games with Macromedia Flash. -links_1218_a=\ Social Bookmarks Friend Finder -links_1219_p=\ A GUI application that allows you to find users with similar bookmarks to the user specified (for delicious.com). -links_1220_a=\ Springfuse -links_1221_p=\ Code generation For Spring, Spring MVC & Hibernate. -links_1222_a=\ SQLOrm -links_1223_p=\ Java Object Relation Mapping. -links_1224_a=\ StorYBook -links_1225_p=\ A summary-based tool for novelist and script writers. It helps to keep the overview over the various traces a story has. -links_1226_a=\ StreamCruncher -links_1227_p=\ Event (stream) processing kernel. -links_1228_a=\ Tune Backup -links_1229_p=\ Easy-to-use backup solution for your iTunes library. -links_1230_a=\ weblica -links_1231_p=\ Desktop CMS. -links_1232_a=\ Web of Web -links_1233_p=\ Collaborative and realtime interactive media platform for the web. -links_1234_a=\ Werkzeugkasten -links_1235_p=\ Minimum Java Toolset. -links_1236_a=\ VPDA -links_1237_p=\ View providers driven applications is a Java based application framework for building applications composed from server components - view providers. -links_1238_a=\ Volunteer database -links_1239_p=\ A database front end to register volunteers, partnership and donation for a Non Profit organization. -mainWeb_1000_h1=H2 Database Engine -mainWeb_1001_p=\ Welcome to H2, the Java SQL database. The main features of H2 are\: -mainWeb_1002_li=Very fast, open source, JDBC API -mainWeb_1003_li=Embedded and server modes; in-memory databases -mainWeb_1004_li=Browser based Console application -mainWeb_1005_li=Small footprint\: around 1 MB jar file size -mainWeb_1006_h3=Download -mainWeb_1007_td=\ Version 1.2.137 (2010-06-06)\: -mainWeb_1008_a=Windows Installer (4 MB) -mainWeb_1009_a=All Platforms (zip, 5 MB) -mainWeb_1010_a=All Downloads -mainWeb_1011_td=    -mainWeb_1012_h3=Support -mainWeb_1013_a=English Google Group -mainWeb_1014_a=Japanese Google Group -mainWeb_1015_p=\ For non-technical issues, use\: -mainWeb_1016_h3=Features -mainWeb_1017_th=H2 -mainWeb_1018_a=Derby -mainWeb_1019_a=HSQLDB -mainWeb_1020_a=MySQL -mainWeb_1021_a=PostgreSQL -mainWeb_1022_td=Pure Java -mainWeb_1023_td=Yes -mainWeb_1024_td=Yes -mainWeb_1025_td=Yes -mainWeb_1026_td=No -mainWeb_1027_td=No -mainWeb_1028_td=Memory Mode -mainWeb_1029_td=Yes -mainWeb_1030_td=Yes -mainWeb_1031_td=Yes -mainWeb_1032_td=No -mainWeb_1033_td=No -mainWeb_1034_td=Transaction Isolation -mainWeb_1035_td=Yes -mainWeb_1036_td=Yes -mainWeb_1037_td=No -mainWeb_1038_td=Yes -mainWeb_1039_td=Yes -mainWeb_1040_td=Cost Based Optimizer -mainWeb_1041_td=Yes -mainWeb_1042_td=Yes -mainWeb_1043_td=No -mainWeb_1044_td=Yes -mainWeb_1045_td=Yes -mainWeb_1046_td=Encrypted Database -mainWeb_1047_td=Yes -mainWeb_1048_td=Yes -mainWeb_1049_td=No -mainWeb_1050_td=No -mainWeb_1051_td=No -mainWeb_1052_td=ODBC Driver -mainWeb_1053_td=Yes -mainWeb_1054_td=No -mainWeb_1055_td=No -mainWeb_1056_td=Yes -mainWeb_1057_td=Yes -mainWeb_1058_td=Fulltext Search -mainWeb_1059_td=Yes -mainWeb_1060_td=No -mainWeb_1061_td=No -mainWeb_1062_td=Yes -mainWeb_1063_td=Yes -mainWeb_1064_td=Multi Version Concurrency -mainWeb_1065_td=Yes -mainWeb_1066_td=No -mainWeb_1067_td=No -mainWeb_1068_td=Yes -mainWeb_1069_td=Yes -mainWeb_1070_td=Footprint (jar/dll size) -mainWeb_1071_td=~1 MB -mainWeb_1072_td=~2 MB -mainWeb_1073_td=~600 KB -mainWeb_1074_td=~4 MB -mainWeb_1075_td=~6 MB -mainWeb_1076_p=\ See also the detailed comparison. -mainWeb_1077_h3=News -mainWeb_1078_b=Newsfeeds\: -mainWeb_1079_a=Full text (Atom) -mainWeb_1080_p=\ or Header only (RSS). -mainWeb_1081_b=Email Newsletter\: -mainWeb_1082_p=\ Subscribe to H2 Database News (Google account required) to get informed about new releases. Your email address is only used in this context. -mainWeb_1083_td=  -mainWeb_1084_h3=Contribute -mainWeb_1085_p=\ You can contribute to the development of H2 by sending feedback and bug reports, or translate the H2 Console application (for details, start the H2 Console and select Options / Translate). To donate money, click on the PayPal button below. You will be listed as a supporter\: -main_1000_h1=H2 Database Engine -main_1001_p=\ Welcome to H2, the free Java SQL database engine. -main_1002_a=Quickstart -main_1003_p=\ Get a fast overview. -main_1004_a=Tutorial -main_1005_p=\ Go through the samples. -main_1006_a=Features -main_1007_p=\ See what this database can do and how to use these features. -performance_1000_h1=Performance -performance_1001_a=\ Performance Comparison -performance_1002_a=\ PolePosition Benchmark -performance_1003_a=\ Application Profiling -performance_1004_a=\ Database Profiling -performance_1005_a=\ Database Performance Tuning -performance_1006_a=\ Using the Built-In Profiler -performance_1007_a=\ Fast Database Import -performance_1008_h2=Performance Comparison -performance_1009_p=\ In many cases H2 is faster than other (open source and not open source) database engines. Please note this is mostly a single connection benchmark run on one computer. -performance_1010_h3=Embedded -performance_1011_th=Test Case -performance_1012_th=Unit -performance_1013_th=H2 -performance_1014_th=HSQLDB -performance_1015_th=Derby -performance_1016_td=Simple\: Init -performance_1017_td=ms -performance_1018_td=547 -performance_1019_td=532 -performance_1020_td=2594 -performance_1021_td=Simple\: Query (random) -performance_1022_td=ms -performance_1023_td=250 -performance_1024_td=391 -performance_1025_td=1515 -performance_1026_td=Simple\: Query (sequential) -performance_1027_td=ms -performance_1028_td=188 -performance_1029_td=313 -performance_1030_td=1406 -performance_1031_td=Simple\: Update (random) -performance_1032_td=ms -performance_1033_td=812 -performance_1034_td=1750 -performance_1035_td=17704 -performance_1036_td=Simple\: Delete (sequential) -performance_1037_td=ms -performance_1038_td=203 -performance_1039_td=250 -performance_1040_td=8843 -performance_1041_td=Simple\: Memory Usage -performance_1042_td=MB -performance_1043_td=7 -performance_1044_td=11 -performance_1045_td=11 -performance_1046_td=BenchA\: Init -performance_1047_td=ms -performance_1048_td=578 -performance_1049_td=719 -performance_1050_td=3328 -performance_1051_td=BenchA\: Transactions -performance_1052_td=ms -performance_1053_td=3047 -performance_1054_td=2406 -performance_1055_td=12907 -performance_1056_td=BenchA\: Memory Usage -performance_1057_td=MB -performance_1058_td=10 -performance_1059_td=15 -performance_1060_td=10 -performance_1061_td=BenchB\: Init -performance_1062_td=ms -performance_1063_td=2141 -performance_1064_td=2406 -performance_1065_td=11562 -performance_1066_td=BenchB\: Transactions -performance_1067_td=ms -performance_1068_td=1125 -performance_1069_td=1375 -performance_1070_td=3625 -performance_1071_td=BenchB\: Memory Usage -performance_1072_td=MB -performance_1073_td=9 -performance_1074_td=11 -performance_1075_td=8 -performance_1076_td=BenchC\: Init -performance_1077_td=ms -performance_1078_td=688 -performance_1079_td=594 -performance_1080_td=4500 -performance_1081_td=BenchC\: Transactions -performance_1082_td=ms -performance_1083_td=1906 -performance_1084_td=64062 -performance_1085_td=6047 -performance_1086_td=BenchC\: Memory Usage -performance_1087_td=MB -performance_1088_td=11 -performance_1089_td=17 -performance_1090_td=11 -performance_1091_td=Executed statements -performance_1092_td=\# -performance_1093_td=322929 -performance_1094_td=322929 -performance_1095_td=322929 -performance_1096_td=Total time -performance_1097_td=ms -performance_1098_td=11485 -performance_1099_td=74798 -performance_1100_td=74031 -performance_1101_td=Statements per second -performance_1102_td=\# -performance_1103_td=28117 -performance_1104_td=4317 -performance_1105_td=4362 -performance_1106_h3=Client-Server -performance_1107_th=Test Case -performance_1108_th=Unit -performance_1109_th=H2 -performance_1110_th=HSQLDB -performance_1111_th=Derby -performance_1112_th=PostgreSQL -performance_1113_th=MySQL -performance_1114_td=Simple\: Init -performance_1115_td=ms -performance_1116_td=2782 -performance_1117_td=2656 -performance_1118_td=5625 -performance_1119_td=4563 -performance_1120_td=3484 -performance_1121_td=Simple\: Query (random) -performance_1122_td=ms -performance_1123_td=3093 -performance_1124_td=2703 -performance_1125_td=6688 -performance_1126_td=4812 -performance_1127_td=3860 -performance_1128_td=Simple\: Query (sequential) -performance_1129_td=ms -performance_1130_td=2969 -performance_1131_td=2594 -performance_1132_td=6437 -performance_1133_td=4719 -performance_1134_td=3625 -performance_1135_td=Simple\: Update (random) -performance_1136_td=ms -performance_1137_td=2969 -performance_1138_td=3531 -performance_1139_td=18250 -performance_1140_td=5953 -performance_1141_td=5125 -performance_1142_td=Simple\: Delete (sequential) -performance_1143_td=ms -performance_1144_td=1047 -performance_1145_td=1250 -performance_1146_td=6875 -performance_1147_td=2485 -performance_1148_td=2390 -performance_1149_td=Simple\: Memory Usage -performance_1150_td=MB -performance_1151_td=7 -performance_1152_td=11 -performance_1153_td=14 -performance_1154_td=0 -performance_1155_td=0 -performance_1156_td=BenchA\: Init -performance_1157_td=ms -performance_1158_td=2250 -performance_1159_td=2453 -performance_1160_td=6031 -performance_1161_td=4328 -performance_1162_td=3625 -performance_1163_td=BenchA\: Transactions -performance_1164_td=ms -performance_1165_td=10250 -performance_1166_td=9016 -performance_1167_td=21484 -performance_1168_td=15609 -performance_1169_td=11172 -performance_1170_td=BenchA\: Memory Usage -performance_1171_td=MB -performance_1172_td=10 -performance_1173_td=15 -performance_1174_td=10 -performance_1175_td=0 -performance_1176_td=1 -performance_1177_td=BenchB\: Init -performance_1178_td=ms -performance_1179_td=9500 -performance_1180_td=10672 -performance_1181_td=22609 -performance_1182_td=19609 -performance_1183_td=13406 -performance_1184_td=BenchB\: Transactions -performance_1185_td=ms -performance_1186_td=2734 -performance_1187_td=2656 -performance_1188_td=3875 -performance_1189_td=4688 -performance_1190_td=2531 -performance_1191_td=BenchB\: Memory Usage -performance_1192_td=MB -performance_1193_td=10 -performance_1194_td=11 -performance_1195_td=11 -performance_1196_td=1 -performance_1197_td=1 -performance_1198_td=BenchC\: Init -performance_1199_td=ms -performance_1200_td=1860 -performance_1201_td=1484 -performance_1202_td=6890 -performance_1203_td=2219 -performance_1204_td=3438 -performance_1205_td=BenchC\: Transactions -performance_1206_td=ms -performance_1207_td=9046 -performance_1208_td=63266 -performance_1209_td=18641 -performance_1210_td=11703 -performance_1211_td=7421 -performance_1212_td=BenchC\: Memory Usage -performance_1213_td=MB -performance_1214_td=12 -performance_1215_td=17 -performance_1216_td=13 -performance_1217_td=0 -performance_1218_td=1 -performance_1219_td=Executed statements -performance_1220_td=\# -performance_1221_td=322929 -performance_1222_td=322929 -performance_1223_td=322929 -performance_1224_td=322929 -performance_1225_td=322929 -performance_1226_td=Total time -performance_1227_td=ms -performance_1228_td=48500 -performance_1229_td=102281 -performance_1230_td=123405 -performance_1231_td=80688 -performance_1232_td=60077 -performance_1233_td=Statements per second -performance_1234_td=\# -performance_1235_td=6658 -performance_1236_td=3157 -performance_1237_td=2616 -performance_1238_td=4002 -performance_1239_td=5375 -performance_1240_h3=Benchmark Results and Comments -performance_1241_h4=H2 -performance_1242_p=\ Version 1.1.114 (2009-06-01) was used for the test. For simpler operations, the performance of H2 is about the same as for HSQLDB. For more complex queries, the query optimizer is very important. However H2 is not very fast in every case, certain kind of queries may still be slow. One situation where is H2 is slow is large result sets, because they are buffered to disk if more than a certain number of records are returned. The advantage of buffering is, there is no limit on the result set size. The open/close time is almost fixed, because of the file locking protocol\: the engine waits some time after opening a database to ensure the database files are not opened by another process. -performance_1243_h4=HSQLDB -performance_1244_p=\ Version 1.8.0.10 was used for the test. Cached tables are used in this test (hsqldb.default_table_type\=cached), and the write delay is 1 second (SET WRITE_DELAY 1). HSQLDB is fast when using simple operations. HSQLDB is very slow in the last test (BenchC\: Transactions), probably because is has a bad query optimizer. One query where HSQLDB is slow is a two-table join\: -performance_1245_p=\ The PolePosition benchmark also shows that the query optimizer does not do a very good job for some queries. Another disadvantage of HSQLDB is the slow startup / shutdown time (currently not listed) when using bigger databases. The reason is, a backup of the whole data is made whenever the database is opened or closed. -performance_1246_h4=Derby -performance_1247_p=\ Version 10.4.2.0 was used for the test. Derby is clearly the slowest embedded database in this test. This seems to be a structural problem, because all operations are really slow. It will be hard for the developers of Derby to improve the performance to a reasonable level. A few problems have been identified\: leaving autocommit on is a problem for Derby. If it is switched off during the whole test, the results are about 20% better for Derby. Derby does not call FileDescriptor.sync() or FileChannel.force(..) on each commit. Derby supports a testing mode (system property derby.system.durability\=test) where durability is disabled. According to the documentation, this setting should be used for testing only, as the database may not recover after a crash. Enabling this setting improves performance by a factor of 2.6 (embedded mode) or 1.4 (server mode). Even if enabled, Derby is still less than half as fast as H2 in default mode. -performance_1248_h4=PostgreSQL -performance_1249_p=\ Version 8.3.7 was used for the test. The following options where changed in postgresql.conf\: fsync \= off, commit_delay \= 1000. PostgreSQL is run in server mode. It looks like the base performance is slower than MySQL, the reason could be the network layer. The memory usage number is incorrect, because only the memory usage of the JDBC driver is measured. -performance_1250_h4=MySQL -performance_1251_p=\ Version 5.1.34-community was used for the test. MySQL was run with the InnoDB backend. The setting innodb_flush_log_at_trx_commit (found in the my.ini file) was set to 0. Otherwise (and by default), MySQL is really slow (around 140 statements per second in this test) because it tries to flush the data to disk for each commit. For small transactions (when autocommit is on) this is really slow. But many use cases use small or relatively small transactions. Too bad this setting is not listed in the configuration wizard, and it always overwritten when using the wizard. You need to change this setting manually in the file my.ini, and then restart the service. The memory usage number is incorrect, because only the memory usage of the JDBC driver is measured. -performance_1252_h4=Firebird -performance_1253_p=\ Firebird 1.5 (default installation) was tested, but the results are not published currently. It is possible to run the performance test with the Firebird database, and any information on how to configure Firebird for higher performance are welcome. -performance_1254_h4=Why Oracle / MS SQL Server / DB2 are Not Listed -performance_1255_p=\ The license of these databases does not allow to publish benchmark results. This doesn't mean that they are fast. They are in fact quite slow, and need a lot of memory. But you will need to test this yourself. SQLite was not tested because the JDBC driver doesn't support transactions. -performance_1256_h3=About this Benchmark -performance_1257_h4=How to Run -performance_1258_p=\ This test was executed as follows\: -performance_1259_h4=Separate Process per Database -performance_1260_p=\ For each database, a new process is started, to ensure the previous test does not impact the current test. -performance_1261_h4=Number of Connections -performance_1262_p=\ This is mostly a single-connection benchmark. BenchB uses multiple connections; the other tests use one connection. -performance_1263_h4=Real-World Tests -performance_1264_p=\ Good benchmarks emulate real-world use cases. This benchmark includes 4 test cases\: BenchSimple uses one table and many small updates / deletes. BenchA is similar to the TPC-A test, but single connection / single threaded (see also\: www.tpc.org). BenchB is similar to the TPC-B test, using multiple connections (one thread per connection). BenchC is similar to the TPC-C test, but single connection / single threaded. -performance_1265_h4=Comparing Embedded with Server Databases -performance_1266_p=\ This is mainly a benchmark for embedded databases (where the application runs in the same virtual machine as the database engine). However MySQL and PostgreSQL are not Java databases and cannot be embedded into a Java application. For the Java databases, both embedded and server modes are tested. -performance_1267_h4=Test Platform -performance_1268_p=\ This test is run on Windows XP with the virus scanner switched off. The VM used is Sun JDK 1.5. -performance_1269_h4=Multiple Runs -performance_1270_p=\ When a Java benchmark is run first, the code is not fully compiled and therefore runs slower than when running multiple times. A benchmark should always run the same test multiple times and ignore the first run(s). This benchmark runs three times, but only the last run is measured. -performance_1271_h4=Memory Usage -performance_1272_p=\ It is not enough to measure the time taken, the memory usage is important as well. Performance can be improved by using a bigger cache, but the amount of memory is limited. HSQLDB tables are kept fully in memory by default; this benchmark uses 'disk based' tables for all databases. Unfortunately, it is not so easy to calculate the memory usage of PostgreSQL and MySQL, because they run in a different process than the test. This benchmark currently does not print memory usage of those databases. -performance_1273_h4=Delayed Operations -performance_1274_p=\ Some databases delay some operations (for example flushing the buffers) until after the benchmark is run. This benchmark waits between each database tested, and each database runs in a different process (sequentially). -performance_1275_h4=Transaction Commit / Durability -performance_1276_p=\ Durability means transaction committed to the database will not be lost. Some databases (for example MySQL) try to enforce this by default by calling fsync() to flush the buffers, but most hard drives don't actually flush all data. Calling the method slows down transaction commit a lot, but doesn't always make data durable. When comparing the results, it is important to think about the effect. Many database suggest to 'batch' operations when possible. This benchmark switches off autocommit when loading the data, and calls commit after each 1000 inserts. However many applications need 'short' transactions at runtime (a commit after each update). This benchmark commits after each update / delete in the simple benchmark, and after each business transaction in the other benchmarks. For databases that support delayed commits, a delay of one second is used. -performance_1277_h4=Using Prepared Statements -performance_1278_p=\ Wherever possible, the test cases use prepared statements. -performance_1279_h4=Currently Not Tested\: Startup Time -performance_1280_p=\ The startup time of a database engine is important as well for embedded use. This time is not measured currently. Also, not tested is the time used to create a database and open an existing database. Here, one (wrapper) connection is opened at the start, and for each step a new connection is opened and then closed. -performance_1281_h2=PolePosition Benchmark -performance_1282_p=\ The PolePosition is an open source benchmark. The algorithms are all quite simple. It was developed / sponsored by db4o. -performance_1283_th=Test Case -performance_1284_th=Unit -performance_1285_th=H2 -performance_1286_th=HSQLDB -performance_1287_th=MySQL -performance_1288_td=Melbourne write -performance_1289_td=ms -performance_1290_td=369 -performance_1291_td=249 -performance_1292_td=2022 -performance_1293_td=Melbourne read -performance_1294_td=ms -performance_1295_td=47 -performance_1296_td=49 -performance_1297_td=93 -performance_1298_td=Melbourne read_hot -performance_1299_td=ms -performance_1300_td=24 -performance_1301_td=43 -performance_1302_td=95 -performance_1303_td=Melbourne delete -performance_1304_td=ms -performance_1305_td=147 -performance_1306_td=133 -performance_1307_td=176 -performance_1308_td=Sepang write -performance_1309_td=ms -performance_1310_td=965 -performance_1311_td=1201 -performance_1312_td=3213 -performance_1313_td=Sepang read -performance_1314_td=ms -performance_1315_td=765 -performance_1316_td=948 -performance_1317_td=3455 -performance_1318_td=Sepang read_hot -performance_1319_td=ms -performance_1320_td=789 -performance_1321_td=859 -performance_1322_td=3563 -performance_1323_td=Sepang delete -performance_1324_td=ms -performance_1325_td=1384 -performance_1326_td=1596 -performance_1327_td=6214 -performance_1328_td=Bahrain write -performance_1329_td=ms -performance_1330_td=1186 -performance_1331_td=1387 -performance_1332_td=6904 -performance_1333_td=Bahrain query_indexed_string -performance_1334_td=ms -performance_1335_td=336 -performance_1336_td=170 -performance_1337_td=693 -performance_1338_td=Bahrain query_string -performance_1339_td=ms -performance_1340_td=18064 -performance_1341_td=39703 -performance_1342_td=41243 -performance_1343_td=Bahrain query_indexed_int -performance_1344_td=ms -performance_1345_td=104 -performance_1346_td=134 -performance_1347_td=678 -performance_1348_td=Bahrain update -performance_1349_td=ms -performance_1350_td=191 -performance_1351_td=87 -performance_1352_td=159 -performance_1353_td=Bahrain delete -performance_1354_td=ms -performance_1355_td=1215 -performance_1356_td=729 -performance_1357_td=6812 -performance_1358_td=Imola retrieve -performance_1359_td=ms -performance_1360_td=198 -performance_1361_td=194 -performance_1362_td=4036 -performance_1363_td=Barcelona write -performance_1364_td=ms -performance_1365_td=413 -performance_1366_td=832 -performance_1367_td=3191 -performance_1368_td=Barcelona read -performance_1369_td=ms -performance_1370_td=119 -performance_1371_td=160 -performance_1372_td=1177 -performance_1373_td=Barcelona query -performance_1374_td=ms -performance_1375_td=20 -performance_1376_td=5169 -performance_1377_td=101 -performance_1378_td=Barcelona delete -performance_1379_td=ms -performance_1380_td=388 -performance_1381_td=319 -performance_1382_td=3287 -performance_1383_td=Total -performance_1384_td=ms -performance_1385_td=26724 -performance_1386_td=53962 -performance_1387_td=87112 -performance_1388_p=\ There are a few problems with the PolePosition test\: -performance_1389_li=\ HSQLDB uses in-memory tables by default while H2 uses persistent tables. The HSQLDB version included in PolePosition does not support changing this, so you need to replace poleposition-0.20/lib/hsqldb.jar with a newer version (for example hsqldb-1.8.0.7.jar), and then use the setting hsqldb.connecturl\=jdbc\:hsqldb\:file\:data/hsqldb/dbbench2;hsqldb.default_table_type\=cached;sql.enforce_size\=true in the file Jdbc.properties. -performance_1390_li=HSQLDB keeps the database open between tests, while H2 closes the database (losing all the cache). To change that, use the database URL jdbc\:h2\:file\:data/h2/dbbench;DB_CLOSE_DELAY\=-1 -performance_1391_li=The amount of cache memory is quite important, specially for the PolePosition test. Unfortunately, the PolePosition test does not take this into account. -performance_1392_h2=Application Profiling -performance_1393_h3=Analyze First -performance_1394_p=\ Before trying to optimize performance, it is important to understand where the problem is (what part of the application is slow). Blind optimization or optimization based on guesses should be avoided, because usually it is not an efficient strategy. There are various ways to analyze an application. Sometimes two implementations can be compared using System.currentTimeMillis(). But this does not work for complex applications with many modules, and for memory problems. -performance_1395_p=\ A simple way to profile an application is to use the built-in profiling tool of java. Example\: -performance_1396_p=\ Unfortunately, it is only possible to profile the application from start to end. Another solution is to create a number of full thread dumps. To do that, first run jps -l to get the process id, and then run jstack <pid> or kill -QUIT <pid> (Linux) or press Ctrl+C (Windows). -performance_1397_p=\ A simple profiling tool is included in H2. To use it, the application needs to be changed slightly. Example\: -performance_1398_p=\ The profiler is built into the H2 Console tool, to analyze databases that open slowly. To use it, run the H2 Console, and then click on 'Test Connection'. Afterwards, click on "Test successful" and you get the most common stack traces, which helps to find out why it took so long to connect. You will only get the stack traces if opening the database took more than a few seconds. -performance_1399_h2=Database Profiling -performance_1400_p=\ The ConvertTraceFile tool generates SQL statement statistics at the end of the SQL script file. The format used is similar to the profiling data generated when using java -Xrunhprof. As an example, execute the the following script using the H2 Console\: -performance_1401_p=\ Now convert the .trace.db file using the ConvertTraceFile tool\: -performance_1402_p=\ The generated file test.sql will contain the SQL statements as well as the following profiling data (results vary)\: -performance_1403_h2=Database Performance Tuning -performance_1404_h3=Keep Connections Open or Use a Connection Pool -performance_1405_p=\ If your application opens and closes connections a lot (for example, for each request), you should consider using a connection pool. Opening a connection using DriverManager.getConnection is specially slow if the database is closed. By default the database is closed if the last connection is closed. -performance_1406_p=\ If you open and close connections a lot but don't want to use a connection pool, consider keeping a 'sentinel' connection open for as long as the application runs, or use delayed database closing. See also Closing a database. -performance_1407_h3=Use a Modern JVM -performance_1408_p=\ Newer JVMs are faster. Upgrading to the latest version of your JVM can provide a "free" boost to performance. Switching from the default Client JVM to the Server JVM using the -server command-line option improves performance at the cost of a slight increase in start-up time. -performance_1409_h3=Virus Scanners -performance_1410_p=\ Some virus scanners scan files every time they are accessed. It is very important for performance that database files are not scanned for viruses. The database engine never interprets the data stored in the files as programs, that means even if somebody would store a virus in a database file, this would be harmless (when the virus does not run, it cannot spread). Some virus scanners allow to exclude files by suffix. Ensure files ending with .db are not scanned. -performance_1411_h3=Using the Trace Options -performance_1412_p=\ If the performance hot spots are in the database engine, in many cases the performance can be optimized by creating additional indexes, or changing the schema. Sometimes the application does not directly generate the SQL statements, for example if an O/R mapping tool is used. To view the SQL statements and JDBC API calls, you can use the trace options. For more information, see Using the Trace Options. -performance_1413_h3=Index Usage -performance_1414_p=\ This database uses indexes to improve the performance of SELECT, UPDATE, DELETE. If a column is used in the WHERE clause of a query, and if an index exists on this column, then the index can be used. Multi-column indexes are used if all or the first columns of the index are used. Both equality lookup and range scans are supported. Indexes are used to order result sets, but only if the condition uses the same index or no index at all. The results are sorted in memory if required. Indexes are created automatically for primary key and unique constraints. Indexes are also created for foreign key constraints, if required. For other columns, indexes need to be created manually using the CREATE INDEX statement. -performance_1415_h3=Optimizer -performance_1416_p=\ This database uses a cost based optimizer. For simple and queries and queries with medium complexity (less than 7 tables in the join), the expected cost (running time) of all possible plans is calculated, and the plan with the lowest cost is used. For more complex queries, the algorithm first tries all possible combinations for the first few tables, and the remaining tables added using a greedy algorithm (this works well for most joins). Afterwards a genetic algorithm is used to test at most 2000 distinct plans. Only left-deep plans are evaluated. -performance_1417_h3=Expression Optimization -performance_1418_p=\ After the statement is parsed, all expressions are simplified automatically if possible. Operations are evaluated only once if all parameters are constant. Functions are also optimized, but only if the function is constant (always returns the same result for the same parameter values). If the WHERE clause is always false, then the table is not accessed at all. -performance_1419_h3=COUNT(*) Optimization -performance_1420_p=\ If the query only counts all rows of a table, then the data is not accessed. However, this is only possible if no WHERE clause is used, that means it only works for queries of the form SELECT COUNT(*) FROM table. -performance_1421_h3=Updating Optimizer Statistics / Column Selectivity -performance_1422_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. -performance_1423_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', the index on NAME or the index on FIRSTNAME. It is not possible to use both indexes at the same time. Which index is used depends on the selectivity of the column. The selectivity describes the 'uniqueness' of 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. -performance_1424_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. -performance_1425_h3=In-Memory (Hash) Indexes -performance_1426_p=\ Using in-memory indexes, specially in-memory hash indexes, can speed up queries and data manipulation. -performance_1427_p=In-memory indexes are automatically used for in-memory databases, but can also be created for persistent databases using CREATE MEMORY TABLE. In many cases, the rows itself will also be kept in-memory. Please note this may cause memory problems for large tables. -performance_1428_p=\ In-memory hash indexes are backed by a hash table and are usually faster than regular indexes. However, hash indexes only supports direct lookup (WHERE ID \= ?) but not range scan (WHERE ID < ?). To use hash indexes, use HASH as in\: CREATE UNIQUE HASH INDEX and CREATE TABLE ...(ID INT PRIMARY KEY HASH,...). -performance_1429_h3=Use Prepared Statements -performance_1430_p=\ If possible, use prepared statements with parameters. -performance_1431_h3=Prepared Statements and IN(...) -performance_1432_p=\ Avoid generating SQL statements with a variable size IN(...) list. Instead, use a prepared statement with arrays as in the following example\: -performance_1433_h3=Optimization Examples -performance_1434_p=\ See src/test/org/h2/samples/optimizations.sql for a few examples of queries that benefit from special optimizations built into the database. -performance_1435_h3=Cache Size and Type -performance_1436_p=\ By default the cache size of H2 is quite small. Consider using a larger cache size, or enable the second level soft reference cache. See also Cache Settings. -performance_1437_h3=Data Types -performance_1438_p=\ Each data type has different storage and performance characteristics\: -performance_1439_li=The DECIMAL/NUMERIC type is slower and requires more storage than the REAL and DOUBLE types. -performance_1440_li=Text types are slower to read, write, and compare than numeric types and generally require more storage. -performance_1441_li=See Large Objects for information on BINARY vs. BLOB and VARCHAR vs. CLOB performance. -performance_1442_li=Parsing and formatting takes longer for the TIME, DATE, and TIMESTAMP types than the numeric types. -performance_1443_code=SMALLINT/TINYINT/BOOLEAN -performance_1444_li=\ are not significantly smaller or faster to work with than INTEGER in most modes. -performance_1445_h3=Sorted Insert Optimization -performance_1446_p=\ To reduce disk space usage and speed up table creation, an optimization for sorted inserts is available. When used, b-tree pages are split at the insertion point. To use this optimization, add SORTED before the SELECT statement\: -performance_1447_h2=Using the Built-In Profiler -performance_1448_p=\ A very simple Java profiler is built-in. To use it, use the following template\: -performance_1449_h2=Fast Database Import -performance_1450_p=\ To speed up large imports, consider using the following options temporarily\: -performance_1451_code=SET CACHE_SIZE -performance_1452_li=\ (a large cache is faster) -performance_1453_code=SET LOCK_MODE 0 -performance_1454_li=\ (disable locking) -performance_1455_code=SET UNDO_LOG 0 -performance_1456_li=\ (disable the session undo log) -performance_1457_p=\ These options can be set in the database URL\: jdbc\:h2\:~/test;CACHE_SIZE\=65536;LOCK_MODE\=0;UNDO_LOG\=0. Most of those options are not recommended for regular use, that means you need to reset them after use. -quickstart_1000_h1=Quickstart -quickstart_1001_a=\ Embedding H2 in an Application -quickstart_1002_a=\ The H2 Console Application -quickstart_1003_h2=Embedding H2 in an Application -quickstart_1004_p=\ This database can be used in embedded mode, or in server mode. To use it in embedded mode, you need to\: -quickstart_1005_li=Add the h2*.jar to the classpath (H2 does not have any dependencies) -quickstart_1006_li=Use the JDBC driver class\: org.h2.Driver -quickstart_1007_li=The database URL jdbc\:h2\:~/test opens the database test in your user home directory -quickstart_1008_li=A new database is automatically created -quickstart_1009_h2=The H2 Console Application -quickstart_1010_p=\ The Console lets you access a SQL database using a browser interface. -quickstart_1011_p=\ If you don't have Windows XP, or if something does not work as expected, please see the detailed description in the Tutorial. -quickstart_1012_h3=Step-by-Step -quickstart_1013_h4=Installation -quickstart_1014_p=\ Install the software using the Windows Installer (if you did not yet do that). -quickstart_1015_h4=Start the Console -quickstart_1016_p=\ Click [Start], [All Programs], [H2], and [H2 Console (Command Line)]\: -quickstart_1017_p=\ A new console window appears\: -quickstart_1018_p=\ Also, a new browser page should open with the URL http\://localhost\:8082. You may get a security warning from the firewall. If you don't want other computers in the network to access the database on your machine, you can let the firewall block these connections. Only local connections are required at this time. -quickstart_1019_h4=Login -quickstart_1020_p=\ Select [Generic H2] and click [Connect]\: -quickstart_1021_p=\ You are now logged in. -quickstart_1022_h4=Sample -quickstart_1023_p=\ Click on the [Sample SQL Script]\: -quickstart_1024_p=\ The SQL commands appear in the command area. -quickstart_1025_h4=Execute -quickstart_1026_p=\ Click [Run] -quickstart_1027_p=\ On the left side, a new entry TEST is added below the database icon. The operations and results of the statements are shown below the script. -quickstart_1028_h4=Disconnect -quickstart_1029_p=\ Click on [Disconnect]\: -quickstart_1030_p=\ to close the connection. -quickstart_1031_h4=End -quickstart_1032_p=\ Close the console window. For more information, see the Tutorial. -roadmap_1000_h1=Roadmap -roadmap_1001_p=\ New (feature) requests will usually be added at the very end of the list. The priority is increased for important and popular requests. Of course, patches are always welcome, but are not always applied as is. See also Providing Patches. -roadmap_1002_h2=Version 1.3.x\: Planned Changes -roadmap_1003_li=Enable h2.lobInDatabase (store CLOB and BLOB in the database file). -roadmap_1004_li=Set h2.analyzeAuto to 2000 (automatic ANALYZE). -roadmap_1005_li=Enable h2.functionsInSchema (allow to store functions in a schema). -roadmap_1006_li=Enable h2.selectForUpdateMvcc (MVCC and SELECT FOR UPDATE). -roadmap_1007_li=Enable h2.largeTransactions (support for very large transactions). Change documentation for MAX_MEMORY_UNDO in help.csv, because now changes to tables without a primary key can be buffered to disk. Later, change MAX_MEMORY_UNDO to reflect number of bytes instead of record (also remove Constants.UNDO_BLOCK_SIZE). Later, change undo log file format (fillAligned no longer required; var int). -roadmap_1008_h2=Priority 1 -roadmap_1009_li=Bugfixes -roadmap_1010_li=Support very large transactions. Reduce memory usage of undo log (TestUndoLogMemory). -roadmap_1011_li=More tests with MULTI_THREADED\=1 -roadmap_1012_li=Optimization\: result set caching (like MySQL); option to disable -roadmap_1013_li=Server side cursors -roadmap_1014_h2=Priority 2 -roadmap_1015_li=Support nested outer joins (see todo.txt, issues 145, 177, 203). -roadmap_1016_li=Improve test code coverage. -roadmap_1017_li=Test multi-threaded in-memory db access. -roadmap_1018_li=Full outer joins. -roadmap_1019_li=Clustering\: support mixed clustering mode (one embedded, others in server mode). -roadmap_1020_li=Clustering\: reads should be randomly distributed (optional) or to a designated database on RAM (parameter\: READ_FROM\=3). -roadmap_1021_li=PostgreSQL catalog\: use BEFORE SELECT triggers instead of views over metadata tables. -roadmap_1022_li=Test very large databases and LOBs (up to 256 GB). -roadmap_1023_li=Support hints for the optimizer (which index to use, enforce the join order). -roadmap_1024_li=Sequence\: add features [NO] MINVALUE, MAXVALUE, CYCLE. -roadmap_1025_li=Access rights\: remember the owner of an object. Create, alter and drop privileges. COMMENT\: allow owner of object to change it. -roadmap_1026_li=Deferred integrity checking (DEFERRABLE INITIALLY DEFERRED). -roadmap_1027_li=Groovy Stored Procedures\: http\://groovy.codehaus.org/Groovy+SQL -roadmap_1028_li=Add a migration guide (list differences between databases). -roadmap_1029_li=Migrate database tool (also from other database engines). -roadmap_1030_li=Optimization\: automatic index creation suggestion using the trace file? -roadmap_1031_li=Compression performance\: don't allocate buffers, compress / expand in to out buffer. -roadmap_1032_li=Rebuild index functionality to shrink index size and improve performance. -roadmap_1033_li=Don't use deleteOnExit (bug 4513817\: File.deleteOnExit consumes memory). -roadmap_1034_li=Console\: add accesskey to most important commands (A, AREA, BUTTON, INPUT, LABEL, LEGEND, TEXTAREA). -roadmap_1035_li=Test performance again with SQL Server, Oracle, DB2. -roadmap_1036_li=Test with Spatial DB in a box / JTS\: http\://www.opengeospatial.org/standards/sfs - OpenGIS Implementation Specification. -roadmap_1037_li=Write more tests and documentation for MVCC (Multi Version Concurrency Control). -roadmap_1038_li=Find a tool to view large text file (larger than 100 MB), with find, page up and down (like less), truncate before / after. -roadmap_1039_li=Implement, test, document XAConnection and so on. -roadmap_1040_li=Pluggable data type (for streaming, hashing, compression, validation, conversion, encryption). -roadmap_1041_li=CHECK\: find out what makes CHECK\=TRUE slow, move to CHECK2. -roadmap_1042_li=Index usage for (ID, NAME)\=(1, 'Hi'); document. -roadmap_1043_li=Make DDL (Data Definition) operations transactional. -roadmap_1044_li=RANK() and DENSE_RANK(), Partition using OVER(). -roadmap_1045_li=Set a connection read only (Connection.setReadOnly) or using a connection parameter. -roadmap_1046_li=Optimizer\: use an index for IS NULL and IS NOT NULL (including linked tables). ID IS NOT NULL could be converted to ID >\= Integer.MIN_VALUE. -roadmap_1047_li=Access rights\: finer grained access control (grant access for specific functions). -roadmap_1048_li=Version check\: docs / web console (using Javascript), and maybe in the library (using TCP/IP). -roadmap_1049_li=Web server classloader\: override findResource / getResourceFrom. -roadmap_1050_li=Cost for embedded temporary view is calculated wrong, if result is constant. -roadmap_1051_li=Comparison\: pluggable sort order\: natural sort. -roadmap_1052_li=Count index range query (count(*) where id between 10 and 20). -roadmap_1053_li=Performance\: update in-place. -roadmap_1054_li=Recursive Queries (see details). -roadmap_1055_li=Eclipse plugin. -roadmap_1056_li=Asynchronous queries to support publish/subscribe\: SELECT ... FOR READ WAIT [maxMillisToWait]. -roadmap_1057_li=Fulltext search Lucene\: analyzer configuration. -roadmap_1058_li=Fulltext search (native)\: reader / tokenizer / filter. -roadmap_1059_li=Linked schema using CSV files\: one schema for a directory of files; support indexes for CSV files. -roadmap_1060_li=iReport to support H2. -roadmap_1061_li=Implement missing JDBC API (CallableStatement,...). -roadmap_1062_li=Compression of the cache. -roadmap_1063_li=Include SMPT (mail) client (alert on cluster failure, low disk space,...). -roadmap_1064_li=Drop with restrict (currently cascade is the default). -roadmap_1065_li=JSON parser and functions. -roadmap_1066_li=Server\: client ping from time to time (to avoid timeout - is timeout a problem?). -roadmap_1067_li=Copy database\: tool with config GUI and batch mode, extensible (example\: compare). -roadmap_1068_li=Document, implement tool for long running transactions using user-defined compensation statements. -roadmap_1069_li=Support SET TABLE DUAL READONLY. -roadmap_1070_li=GCJ\: what is the state now? -roadmap_1071_li=Events for\: database Startup, Connections, Login attempts, Disconnections, Prepare (after parsing), Web Server. See http\://docs.openlinksw.com/virtuoso/fn_dbev_startup.html -roadmap_1072_li=Optimization\: log compression. -roadmap_1073_li=ROW_NUMBER() OVER([ORDER BY columnName]). -roadmap_1074_li=Support standard INFORMATION_SCHEMA tables, as defined in http\://www.contrib.andrew.cmu.edu/~shadow/sql/sql1992.txt - specially KEY_COLUMN_USAGE\: http\://dev.mysql.com/doc/refman/5.0/en/information-schema.html, http\://www.xcdsql.org/Misc/INFORMATION_SCHEMA%20With%20Rolenames.gif -roadmap_1075_li=Compatibility\: in MySQL, HSQLDB, /0.0 is NULL; in PostgreSQL, Derby\: division by zero. -roadmap_1076_li=Functional tables should accept parameters from other tables (see FunctionMultiReturn) SELECT * FROM TEST T, P2C(T.A, T.R). -roadmap_1077_li=Custom class loader to reload functions on demand. -roadmap_1078_li=Clustering\: when a database is back alive, automatically synchronize with the master. -roadmap_1079_li=Test http\://mysql-je.sourceforge.net/ -roadmap_1080_li=Performance\: automatically build in-memory indexes if the whole table is in memory. -roadmap_1081_li=H2 Console\: the webclient could support more features like phpMyAdmin. -roadmap_1082_li=Use Janino to convert Java to C++. -roadmap_1083_li=The HELP information schema can be directly exposed in the Console. -roadmap_1084_li=Maybe use the 0x1234 notation for binary fields, see MS SQL Server. -roadmap_1085_li=Support Oracle CONNECT BY in some way\: http\://www.adp-gmbh.ch/ora/sql/connect_by.html http\://philip.greenspun.com/sql/trees.html -roadmap_1086_li=SQL Server 2005, Oracle\: support COUNT(*) OVER(). See http\://www.orafusion.com/art_anlytc.htm -roadmap_1087_li=SQL 2003\: http\://www.wiscorp.com/sql_2003_standard.zip -roadmap_1088_li=Version column (number/sequence and timestamp based). -roadmap_1089_li=Optimize getGeneratedKey\: send last identity after each execute (server). -roadmap_1090_li=Test and document UPDATE TEST SET (ID, NAME) \= (SELECT ID*10, NAME || '\!' FROM TEST T WHERE T.ID\=TEST.ID). -roadmap_1091_li=Max memory rows / max undo log size\: use block count / row size not row count. -roadmap_1092_li=Support 123L syntax as in Java; example\: SELECT (2000000000*2). -roadmap_1093_li=Implement point-in-time recovery. -roadmap_1094_li=LIKE\: improved version for larger texts (currently using naive search). -roadmap_1095_li=Automatically convert to the next 'higher' data type whenever there is an overflow. -roadmap_1096_li=Throw an exception when the application calls getInt on a Long (optional). -roadmap_1097_li=Default date format for input and output (local date constants). -roadmap_1098_li=Support custom Collators. -roadmap_1099_li=Document ROWNUM usage for reports\: SELECT ROWNUM, * FROM (subquery). -roadmap_1100_li=File system that writes to two file systems (replication, replicating file system). -roadmap_1101_li=Standalone tool to get relevant system properties and add it to the trace output. -roadmap_1102_li=Support 'call proc(1\=value)' (PostgreSQL, Oracle). -roadmap_1103_li=Console\: improve editing data (Tab, Shift-Tab, Enter, Up, Down, Shift+Del?). -roadmap_1104_li=Console\: autocomplete Ctrl+Space inserts template. -roadmap_1105_li=Option to encrypt .trace.db file. -roadmap_1106_li=Write Behind Cache on SATA leads to data corruption See also http\://sr5tech.com/write_back_cache_experiments.htm and http\://www.jasonbrome.com/blog/archives/2004/04/03/writecache_enabled.html -roadmap_1107_li=Functions with unknown return or parameter data types\: serialize / deserialize. -roadmap_1108_li=Auto-Update feature for database, .jar file. -roadmap_1109_li=ResultSet SimpleResultSet.readFromURL(String url)\: id varchar, state varchar, released timestamp. -roadmap_1110_li=Partial indexing (see PostgreSQL). -roadmap_1111_li=Add GUI to build a custom version (embedded, fulltext,...) using build flags. -roadmap_1112_li=http\://rubyforge.org/projects/hypersonic/ -roadmap_1113_li=Add comparator (x \=\=\= y) \: (x \= y or (x is null and y is null)). -roadmap_1114_li=Add a sample application that runs the H2 unit test and writes the result to a file (so it can be included in the user app). -roadmap_1115_li=Count on a column that can not be null could be optimized to COUNT(*). -roadmap_1116_li=Table order\: ALTER TABLE TEST ORDER BY NAME DESC (MySQL compatibility). -roadmap_1117_li=Issue 159\: System property for the H2 Console and TCP configuration (which .h2.server.properties and .h2.keystore to use). -roadmap_1118_li=Backup tool should work with other databases as well. -roadmap_1119_li=Console\: -ifExists doesn't work for the console. Add a flag to disable other dbs. -roadmap_1120_li=Check if 'FSUTIL behavior set disablelastaccess 1' improves the performance (fsutil behavior query disablelastaccess). -roadmap_1121_li=Java static code analysis\: http\://pmd.sourceforge.net/ -roadmap_1122_li=Java static code analysis\: http\://www.eclipse.org/tptp/ -roadmap_1123_li=Compatibility for CREATE SCHEMA AUTHORIZATION. -roadmap_1124_li=Implement Clob / Blob truncate and the remaining functionality. -roadmap_1125_li=Tree join functionality. -roadmap_1126_li=Add multiple columns at the same time with ALTER TABLE .. ADD .. ADD ... -roadmap_1127_li=Use JDK 1.4 file locking for the database file and for the lock file (but not yet by default); writing a system property to detect concurrent access from the same VM (different classloaders). -roadmap_1128_li=Pure SQL triggers (example\: update parent table if the child table is changed). -roadmap_1129_li=Add H2 to Gem (Ruby install system). -roadmap_1130_li=Order conditions inside AND / OR to optimize the performance. -roadmap_1131_li=Support Oracle functions\: TRUNC, NVL2, TO_CHAR, TO_DATE, TO_NUMBER. -roadmap_1132_li=Support linked JCR tables -roadmap_1133_li=Read InputStream when executing, as late as possible (maybe only embedded mode). Problem with re-execute. -roadmap_1134_li=Native fulltext search\: min word length; store word positions -roadmap_1135_li=Add an option to the SCRIPT command to generate only portable / standard SQL -roadmap_1136_li=Updatable Views (simple cases first) -roadmap_1137_li=Improve create index performance -roadmap_1138_li=Implement more JDBC 4.0 features -roadmap_1139_li=Support TRANSFORM / PIVOT as in MS Access -roadmap_1140_li=SELECT * FROM (VALUES (...), (...), ....) AS alias(f1, ...) -roadmap_1141_li=Support updatable views with join on primary keys (to extend a table) -roadmap_1142_li=Public interface for functions (not public static) -roadmap_1143_li=Support reading the transaction log. -roadmap_1144_li=Eliminate undo log records if stored on disk (just one pointer per block, not per record) -roadmap_1145_li=Feature matrix as in i-net software. -roadmap_1146_li=Updatable result set on table without primary key or unique index. -roadmap_1147_li=Use LinkedList instead of ArrayList where applicable. -roadmap_1148_li=Allow execution time prepare for SELECT * FROM CSVREAD(?, 'columnNameString') -roadmap_1149_li=Support % operator (modulo). -roadmap_1150_li=Support JMX\: create an MBean for each database and server (support JConsole). See http\://thedevcloud.blogspot.com/2008/10/displaying-hsql-database-manager-in.html http\://java.sun.com/j2se/1.5.0/docs/api/java/lang/management/ManagementFactory.html\#getPlatformMBeanServer() http\://java.sun.com/j2se/1.5.0/docs/guide/management/agent.html -roadmap_1151_li=Support nested transactions. -roadmap_1152_li=Add a benchmark for big databases, and one for many users. -roadmap_1153_li=Compression in the result set (repeating values in the same column) over TCP/IP. -roadmap_1154_li=Support curtimestamp (like curtime, curdate). -roadmap_1155_li=Support ANALYZE {TABLE|INDEX} tableName COMPUTE|ESTIMATE|DELETE STATISTICS ptnOption options. -roadmap_1156_li=Release locks (shared or exclusive) on demand -roadmap_1157_li=Support OUTER UNION -roadmap_1158_li=Support parameterized views (similar to CSVREAD, but using just SQL for the definition) -roadmap_1159_li=A way (JDBC driver) to map an URL (jdbc\:h2map\:c1) to a connection object -roadmap_1160_li=Option for SCRIPT to only process one or a set of tables, and append to a file -roadmap_1161_li=Support linked tables to the current database -roadmap_1162_li=Support dynamic linked schema (automatically adding/updating/removing tables) -roadmap_1163_li=Clustering\: adding a node should be very fast and without interrupting clients (very short lock) -roadmap_1164_li=Compatibility with Derby\: VALUES(1), (2); SELECT * FROM (VALUES (1), (2)) AS myTable(c1) -roadmap_1165_li=Compatibility\: \# is the start of a single line comment (MySQL) but date quote (Access). Mode specific -roadmap_1166_li=Run benchmarks with JDK 1.5, JDK 1.6, java -server -roadmap_1167_li=Optimizations\: faster hash function for strings, byte arrays -roadmap_1168_li=DatabaseEventListener\: callback for all operations (including expected time, RUNSCRIPT) and cancel functionality -roadmap_1169_li=Benchmark\: add a graph to show how databases scale (performance/database size) -roadmap_1170_li=Implement a SQLData interface to map your data over to a custom object -roadmap_1171_li=In the MySQL and PostgreSQL mode, use lower case identifiers by default (DatabaseMetaData.storesLowerCaseIdentifiers \= true) -roadmap_1172_li=Support multiple directories (on different hard drives) for the same database -roadmap_1173_li=Server protocol\: use challenge response authentication, but client sends hash(user+password) encrypted with response -roadmap_1174_li=Support EXEC[UTE] (doesn't return a result set, compatible to MS SQL Server) -roadmap_1175_li=Support native XML data type -roadmap_1176_li=Support triggers with a string property or option\: SpringTrigger, OSGITrigger -roadmap_1177_li=Ability to resize the cache array when resizing the cache -roadmap_1178_li=Time based cache writing (one second after writing the log) -roadmap_1179_li=Check state of H2 driver for DDLUtils\: https\://issues.apache.org/jira/browse/DDLUTILS-185 -roadmap_1180_li=Index usage for REGEXP LIKE. -roadmap_1181_li=Compatibility\: add a role DBA (like ADMIN). -roadmap_1182_li=Better support multiple processors for in-memory databases. -roadmap_1183_li=Support N'text' -roadmap_1184_li=Support compatibility for jdbc\:hsqldb\:res\: -roadmap_1185_li=Provide an Java SQL builder with standard and H2 syntax -roadmap_1186_li=Trace\: write OS, file system, JVM,... when opening the database -roadmap_1187_li=Support indexes for views (probably requires materialized views) -roadmap_1188_li=Document SET SEARCH_PATH, BEGIN, EXECUTE, parameters -roadmap_1189_li=Browser\: use Desktop.isDesktopSupported and browse when using JDK 1.6 -roadmap_1190_li=Server\: use one listener (detect if the request comes from an PG or TCP client) -roadmap_1191_li=Support data type INTERVAL -roadmap_1192_li=Optimize SELECT MIN(ID), MAX(ID), COUNT(*) FROM TEST WHERE ID BETWEEN 100 AND 200 -roadmap_1193_li=Sequence\: PostgreSQL compatibility (rename, create) http\://www.postgresql.org/docs/8.2/static/sql-altersequence.html -roadmap_1194_li=DISTINCT\: support large result sets by sorting on all columns (additionally) and then removing duplicates. -roadmap_1195_li=Support a special trigger on all tables to allow building a transaction log reader. -roadmap_1196_li=File system with a background writer thread; test if this is faster -roadmap_1197_li=Better document the source code -roadmap_1198_li=Support select * from dual a left join dual b on b.x\=(select max(x) from dual) -roadmap_1199_li=Optimization\: don't lock when the database is read-only -roadmap_1200_li=Issue 146\: Support merge join. -roadmap_1201_li=Integrate spatial functions from http\://geosysin.iict.ch/irstv-trac/wiki/H2spatial/Download -roadmap_1202_li=Cluster\: hot deploy (adding a node at runtime) -roadmap_1203_li=Compact databases without having to close the database (vacuum). -roadmap_1204_li=Support COSH, SINH, and TANH functions -roadmap_1205_li=Oracle\: support DECODE method (convert to CASE WHEN). -roadmap_1206_li=Native search\: support "phrase search", wildcard search (* and ?), case-insensitive search, boolean operators, and grouping -roadmap_1207_li=Improve documentation of access rights -roadmap_1208_li=Support ENUM data type (see MySQL, PostgreSQL, MS SQL Server, maybe others) -roadmap_1209_li=Remember the user defined data type (domain) of a column -roadmap_1210_li=Support Jackcess (MS Access databases) -roadmap_1211_li=Built-in methods to write large objects (BLOB and CLOB)\: FILE_WRITE('test.txt', 'Hello World') -roadmap_1212_li=MVCC\: support transactionally consistent backups using SCRIPT -roadmap_1213_li=Improve time to open large databases (see mail 'init time for distributed setup') -roadmap_1214_li=Move Maven 2 repository from hsql.sf.net to h2database.sf.net -roadmap_1215_li=Java 1.5 tool\: JdbcUtils.closeSilently(s1, s2,...) -roadmap_1216_li=Javadoc\: document design patterns used -roadmap_1217_li=Write an article about SQLInjection (h2/src/docsrc/html/images/SQLInjection.txt) -roadmap_1218_li=Convert SQL-injection-2.txt to html document, include SQLInjection.java sample -roadmap_1219_li=Support OUT parameters in user-defined procedures. -roadmap_1220_li=Web site design\: http\://www.igniterealtime.org/projects/openfire/index.jsp -roadmap_1221_li=HSQLDB compatibility\: Openfire server uses\: CREATE SCHEMA PUBLIC AUTHORIZATION DBA; CREATE USER SA PASSWORD ""; GRANT DBA TO SA; SET SCHEMA PUBLIC -roadmap_1222_li=Translation\: use ?? in help.csv -roadmap_1223_li=Translated .pdf -roadmap_1224_li=MySQL compatibility\: update test1 t1, test2 t2 set t1.id \= t2.id where t1.id \= t2.id; -roadmap_1225_li=Recovery tool\: bad blocks should be converted to INSERT INTO SYSTEM_ERRORS(...), and things should go into the .trace.db file -roadmap_1226_li=RECOVER\=2 to backup the database, run recovery, open the database -roadmap_1227_li=Recovery should work with encrypted databases -roadmap_1228_li=Corruption\: new error code, add help -roadmap_1229_li=Space reuse\: after init, scan all storages and free those that don't belong to a live database object -roadmap_1230_li=Use FilterIn / FilterOut putStream? -roadmap_1231_li=Access rights\: add missing features (users should be 'owner' of objects; missing rights for sequences; dropping objects) -roadmap_1232_li=Support NOCACHE table option (Oracle). -roadmap_1233_li=Support table partitioning. -roadmap_1234_li=Index usage for UPDATE ... WHERE .. IN (SELECT...) -roadmap_1235_li=Add regular javadocs (using the default doclet, but another css) to the homepage. -roadmap_1236_li=The database should be kept open for a longer time when using the server mode. -roadmap_1237_li=Javadocs\: for each tool, add a copy & paste sample in the class level. -roadmap_1238_li=Javadocs\: add @author tags. -roadmap_1239_li=Fluent API for tools\: Server.createTcpServer().setPort(9081).setPassword(password).start(); -roadmap_1240_li=MySQL compatibility\: real SQL statement for DESCRIBE TEST -roadmap_1241_li=Use a default delay of 1 second before closing a database. -roadmap_1242_li=Write (log) to system table before adding to internal data structures. -roadmap_1243_li=Support very large deletes and updates. -roadmap_1244_li=Doclet (javadocs)\: constructors are not listed. -roadmap_1245_li=Support direct lookup for MIN and MAX when using WHERE (see todo.txt / Direct Lookup). -roadmap_1246_li=Support other array types (String[], double[]) in PreparedStatement.setObject(int, Object); -roadmap_1247_li=MVCC should not be memory bound (uncommitted data is kept in memory in the delta index; maybe using a regular b-tree index solves the problem). -roadmap_1248_li=Oracle compatibility\: support NLS_DATE_FORMAT. -roadmap_1249_li=Cluster\: add feature to make sure cluster nodes can not get out of sync (for example by stopping one process). -roadmap_1250_li=H2 Console\: support CLOB/BLOB download using a link. -roadmap_1251_li=Support flashback queries as in Oracle. -roadmap_1252_li=Import / Export of fixed with text files. -roadmap_1253_li=Support getGeneratedKeys to return multiple rows when used with batch updates. This is supported by MySQL, but not Derby. Both PostgreSQL and HSQLDB don't support getGeneratedKeys. Also support it when using INSERT ... SELECT. -roadmap_1254_li=HSQLDB compatibility\: automatic data type for SUM if value is the value is too big (by default use the same type as the data). -roadmap_1255_li=Improve the optimizer to select the right index for special cases\: where id between 2 and 4 and booleanColumn -roadmap_1256_li=Linked tables\: make hidden columns available (Oracle\: rowid and ora_rowscn columns). -roadmap_1257_li=H2 Console\: in-place autocomplete. -roadmap_1258_li=Support large databases\: split database files to multiple directories / disks (similar to tablespaces). -roadmap_1259_li=Support to assign a primary key index a user defined name. -roadmap_1260_li=H2 Console\: support configuration option for fixed width (monospace) font. -roadmap_1261_li=Native fulltext search\: support analyzers (specially for Chinese, Japanese). -roadmap_1262_li=Automatically compact databases from time to time (as a background process). -roadmap_1263_li=Support GRANT SELECT, UPDATE ON *. -roadmap_1264_li=Test Eclipse DTP. -roadmap_1265_li=H2 Console\: autocomplete\: keep the previous setting -roadmap_1266_li=MySQL, MS SQL Server compatibility\: support case sensitive (mixed case) identifiers without quotes. -roadmap_1267_li=executeBatch\: option to stop at the first failed statement. -roadmap_1268_li=Implement OLAP features as described here\: http\://www.devx.com/getHelpOn/10MinuteSolution/16573/0/page/5 -roadmap_1269_li=Support Oracle ROWID (unique identifier for each row). -roadmap_1270_li=Server mode\: improve performance for batch updates. -roadmap_1271_li=Applets\: support read-only databases in a zip file (accessed as a resource). -roadmap_1272_li=Long running queries / errors / trace system table. -roadmap_1273_li=H2 Console should support JaQu directly. -roadmap_1274_li=H2 Console\: support single file upload and directory download (optional). -roadmap_1275_li=Document FTL_SEARCH, FTL_SEARCH_DATA. -roadmap_1276_li=Sequences\: CURRVAL should be session specific. Compatibility with PostgreSQL. -roadmap_1277_li=Support DatabaseMetaData.insertsAreDetected\: updatable result sets should detect inserts. -roadmap_1278_li=Auto-server\: add option to define the IP address range or list. -roadmap_1279_li=Index creation using deterministic functions. -roadmap_1280_li=Support DELETE with TOP or LIMIT. See also\: http\://dev.mysql.com/doc/refman/5.1/de/delete.html -roadmap_1281_li=ANALYZE\: for unique indexes that allow null, count the number of null. -roadmap_1282_li=AUTO_SERVER\: support changing IP addresses (disable a network while the database is open). -roadmap_1283_li=Avoid using java.util.Calendar internally because it's slow, complicated, and buggy. -roadmap_1284_li=Support TRUNCATE .. CASCADE like PostgreSQL. -roadmap_1285_li=Support opening a database that is in the classpath, maybe using a new file system. -roadmap_1286_li=Fulltext search\: lazy result generation using SimpleRowSource. -roadmap_1287_li=Support transformation to join for user defined functions, as for IN(SELECT...). -roadmap_1288_li=Fulltext search\: support alternative syntax\: WHERE FTL_CONTAINS(name, 'hello'). -roadmap_1289_li=MySQL compatibility\: support REPLACE, see http\://dev.mysql.com/doc/refman/5.1/de/replace.html -roadmap_1290_li=MySQL compatibility\: support INSERT INTO table SET column1 \= value1, column2 \= value2 -roadmap_1291_li=Docs\: add a one line description for each functions and SQL statements at the top (in the link section). -roadmap_1292_li=Javadoc search\: weight for titles should be higher ('random' should list Functions as the best match). -roadmap_1293_li=Replace information_schema tables with regular tables that are automatically re-built when needed. Use indexes. -roadmap_1294_li=Delete temporary files or objects using finalize. -roadmap_1295_li=Oracle compatibility\: support calling 0-parameters functions without parenthesis. Make constants obsolete. -roadmap_1296_li=MySQL, HSQLDB compatibility\: support where 'a'\=1 (not supported by Derby, PostgreSQL) -roadmap_1297_li=Allow calling function with no parameters without parenthesis. See http\://code.google.com/p/h2database/issues/detail?id\=50 -roadmap_1298_li=CSV\: currently \# is a line comment and can start at any field. Make it optional. -roadmap_1299_li=Finer granularity for SLF4J trace - See http\://code.google.com/p/h2database/issues/detail?id\=62 -roadmap_1300_li=Add database creation date and time to the database. -roadmap_1301_li=Support ASSERTIONS. -roadmap_1302_li=Support multi-threaded kernel with multi-version concurrency. -roadmap_1303_li=MySQL compatibility\: support comparing 1\='a' -roadmap_1304_li=Support PostgreSQL lock modes\: http\://www.postgresql.org/docs/8.3/static/explicit-locking.html -roadmap_1305_li=PostgreSQL compatibility\: test DbVisualizer and Squirrel SQL using a new PostgreSQL JDBC driver. -roadmap_1306_li=RunScript should be able to read from system in (or quite mode for Shell). -roadmap_1307_li=Natural join\: support select x from dual natural join dual. -roadmap_1308_li=Natural join\: somehow support this\: select a.x, b.x, x from dual a natural join dual b -roadmap_1309_li=Use the Java service provider mechanism to register file systems and function libraries. -roadmap_1310_li=MySQL compatibility\: for auto_increment columns, convert 0 to next value (as when inserting NULL). -roadmap_1311_li=Optimization for multi-column IN\: use an index if possible. Example\: (A, B) IN((1, 2), (2, 3)). -roadmap_1312_li=Optimization for EXISTS\: convert to inner join or IN(..) if possible. -roadmap_1313_li=Functions\: support hashcode(value); cryptographic and fast -roadmap_1314_li=Serialized file lock\: support long running queries. -roadmap_1315_li=Network\: use 127.0.0.1 if other addresses don't work. -roadmap_1316_li=Pluggable network protocol (currently Socket/ServerSocket over TCP/IP) - see also TransportServer with master slave replication. -roadmap_1317_li=Select for update in mvcc mode\: only lock the selected records. -roadmap_1318_li=Support reading JCR data\: one table per node type; query table; cache option -roadmap_1319_li=OSGi\: create a sample application, test, document. -roadmap_1320_li=help.csv\: use complete examples for functions; run as test case. -roadmap_1321_li=Functions to calculate the memory and disk space usage of a table, a row, or a value. -roadmap_1322_li=Re-implement PooledConnection; use a lightweight connection object. -roadmap_1323_li=Doclet\: convert tests in javadocs to a java class. -roadmap_1324_li=Doclet\: format fields like methods, but support sorting by name and value. -roadmap_1325_li=Doclet\: shrink the html files. -roadmap_1326_li=MySQL compatibility\: support REPLACE - See http\://code.google.com/p/h2database/issues/detail?id\=73 -roadmap_1327_li=MySQL compatibility\: support SET NAMES 'latin1' - See also http\://code.google.com/p/h2database/issues/detail?id\=56 -roadmap_1328_li=MySQL compatibility\: DELETE .. FROM .. USING - See http\://dev.mysql.com/doc/refman/5.0/en/delete.html -roadmap_1329_li=Allow to scan index backwards starting with a value (to better support ORDER BY DESC). -roadmap_1330_li=Java Service Wrapper\: try http\://yajsw.sourceforge.net/ -roadmap_1331_li=Batch parameter for INSERT, UPDATE, and DELETE, and commit after each batch. See also MySQL DELETE. -roadmap_1332_li=MySQL compatibility\: support ALTER TABLE .. MODIFY COLUMN. -roadmap_1333_li=Use a lazy and auto-close input stream (open resource when reading, close on eof). -roadmap_1334_li=PostgreSQL compatibility\: generate_series. -roadmap_1335_li=Connection pool\: 'reset session' command (delete temp tables, rollback, autocommit true). -roadmap_1336_li=Improve SQL documentation, see http\://www.w3schools.com/sql/ -roadmap_1337_li=MySQL compatibility\: DatabaseMetaData.stores*() methods should return the same values. Test with SquirrelSQL. -roadmap_1338_li=MS SQL Server compatibility\: support DATEPART syntax. -roadmap_1339_li=Oracle compatibility\: support CREATE OR REPLACE VIEW syntax. -roadmap_1340_li=Sybase/DB2/Oracle compatibility\: support out parameters in stored procedures - See http\://code.google.com/p/h2database/issues/detail?id\=83 -roadmap_1341_li=Support INTERVAL data type (see Oracle and others). -roadmap_1342_li=Combine Server and Console tool (only keep Server). -roadmap_1343_li=Store the Lucene index in the database itself. -roadmap_1344_li=Support standard MERGE statement\: http\://en.wikipedia.org/wiki/Merge_%28SQL%29 -roadmap_1345_li=Oracle compatibility\: support DECODE(x, ...). -roadmap_1346_li=Console\: Start Browser\: if ip number changed, try localhost instead. -roadmap_1347_li=MVCC\: compare concurrent update behavior with PostgreSQL and Oracle. -roadmap_1348_li=HSQLDB compatibility\: CREATE FUNCTION (maybe using a Function interface). -roadmap_1349_li=HSQLDB compatibility\: support CALL "java.lang.Math.sqrt"(2.0) -roadmap_1350_li=Support comma as the decimal separator in the CSV tool. -roadmap_1351_li=Compatibility\: Support jdbc\:default\:connection using ThreadLocal (part of SQLJ) -roadmap_1352_li=Compatibility\: Java functions with SQLJ Part1 http\://www.acm.org/sigmod/record/issues/9912/standards.pdf.gz -roadmap_1353_li=Compatibility\: Java functions with SQL/PSM (Persistent Stored Modules) - need to find the documentation. -roadmap_1354_li=CACHE_SIZE\: automatically use a fraction of Runtime.maxMemory - maybe automatically the second level cache. -roadmap_1355_li=Support date/time/timestamp as documented in http\://en.wikipedia.org/wiki/ISO_8601 -roadmap_1356_li=PostgreSQL compatibility\: when in PG mode, treat BYTEA data like PG. -roadmap_1357_li=MySQL compatibility\: REPLACE http\://dev.mysql.com/doc/refman/6.0/en/replace.html -roadmap_1358_li=Support \=ANY(array) as in PostgreSQL. See also http\://www.postgresql.org/docs/8.0/interactive/arrays.html -roadmap_1359_li=IBM DB2 compatibility\: support PREVIOUS VALUE FOR sequence. -roadmap_1360_li=MySQL compatibility\: alter table add index i(c), add constraint c foreign key(c) references t(c); -roadmap_1361_li=Compatibility\: use different LIKE ESCAPE characters depending on the mode (disable for Derby, HSQLDB, DB2, Oracle, MSSQLServer). -roadmap_1362_li=Oracle compatibility\: support CREATE SYNONYM table FOR schema.table. -roadmap_1363_li=Optimize A\=? OR B\=? to UNION if the cost is lower. -roadmap_1364_li=FTP\: document the server, including -ftpTask option to execute / kill remote processes -roadmap_1365_li=FTP\: problems with multithreading? -roadmap_1366_li=FTP\: implement SFTP / FTPS -roadmap_1367_li=FTP\: access to a database (.csv for a table, a directory for a schema, a file for a lob, a script.sql file). -roadmap_1368_li=More secure default configuration if remote access is enabled. -roadmap_1369_li=Improve database file locking (maybe use native file locking). The current approach seems to be problematic if the file system is on a remote share (see Google Group 'Lock file modification time is in the future'). -roadmap_1370_li=Document internal features such as BELONGS_TO_TABLE, NULL_TO_DEFAULT, SEQUENCE. -roadmap_1371_li=Issue 107\: Prefer using the ORDER BY index if LIMIT is used. -roadmap_1372_li=An index on (id, name) should be used for a query\: select * from t where s\=? order by i -roadmap_1373_li=Support reading sequences using DatabaseMetaData.getTables(null, null, null, new String[]{"SEQUENCE"}). See PostgreSQL. -roadmap_1374_li=Add option to enable TCP_NODELAY using Socket.setTcpNoDelay(true). -roadmap_1375_li=Maybe disallow \= within database names (jdbc\:h2\:mem\:MODE\=DB2 means database name MODE\=DB2). -roadmap_1376_li=Fast alter table add column. -roadmap_1377_li=Improve concurrency for in-memory database operations. -roadmap_1378_li=Issue 122\: Support for connection aliases for remote tcp connections. -roadmap_1379_li=Fast scrambling (strong encryption doesn't help if the password is included in the application). -roadmap_1380_li=Support using system properties in database URLs (may be a security problem). -roadmap_1381_li=Issue 126\: The index name should be "IDX_" plus the constraint name unless there is a conflict, in which case append a number. -roadmap_1382_li=Issue 127\: Support activation/deactivation of triggers -roadmap_1383_li=Issue 130\: Custom log event listeners -roadmap_1384_li=Issue 131\: IBM DB2 compatibility\: sysibm.sysdummy1 -roadmap_1385_li=Issue 132\: Use Java enum trigger type. -roadmap_1386_li=Issue 134\: IBM DB2 compatibility\: session global variables. -roadmap_1387_li=Cluster\: support load balance with values for each server / auto detect. -roadmap_1388_li=FTL_SET_OPTION(keyString, valueString) with key stopWords at first. -roadmap_1389_li=Pluggable access control mechanism. -roadmap_1390_li=Fulltext search (Lucene)\: support streaming CLOB data. -roadmap_1391_li=Document/example how to create and read an encrypted script file. -roadmap_1392_li=Check state of https\://issues.apache.org/jira/browse/OPENJPA-1367 (H2 does support cross joins). -roadmap_1393_li=Fulltext search (Lucene)\: only prefix column names with _ if they already start with _. Instead of DATA / QUERY / modified use _DATA, _QUERY, _MODIFIED if possible. -roadmap_1394_li=Support a way to create or read compressed encrypted script files using an API. -roadmap_1395_li=Scripting language support (Javascript). -roadmap_1396_li=The network client should better detect if the server is not an H2 server and fail early. -roadmap_1397_li=H2 Console\: support CLOB/BLOB upload. -roadmap_1398_li=Move away from system properties where possible. -roadmap_1399_li=Database file lock\: detect hibernate / standby / very slow threads (compare system time). -roadmap_1400_li=Automatic detection of redundant indexes. -roadmap_1401_li=Maybe reject join without "on" (except natural join). -roadmap_1402_li=Implement GiST (Generalized Search Tree for Secondary Storage). -roadmap_1403_li=Function to read a number of bytes/characters from an BLOB or CLOB. -roadmap_1404_li=Issue 156\: Support SELECT ? UNION SELECT ?. -roadmap_1405_li=Automatic mixed mode\: support a port range list (to avoid firewall problems). -roadmap_1406_li=Support the pseudo column rowid, oid, _rowid_. -roadmap_1407_li=H2 Console / large result sets\: stream early instead of keeping a whole result in-memory -roadmap_1408_li=Support TRUNCATE for linked tables. -roadmap_1409_li=UNION\: evaluate INTERSECT before UNION (like most other database except Oracle). -roadmap_1410_li=Delay creating the information schema, and share metadata columns. -roadmap_1411_li=TCP Server\: use a nonce (number used once) to protect unencrypted channels against replay attacks. -roadmap_1412_li=Simplify running scripts and recovery\: CREATE FORCE USER (overwrites an existing user). -roadmap_1413_li=Support CREATE DATABASE LINK (a custom JDBC driver is already supported). -roadmap_1414_li=Issue 163\: Allow to create foreign keys on metadata types. -roadmap_1415_li=Logback\: write a native DBAppender. -roadmap_1416_li=Cache size\: don't use more cache than what is available. -roadmap_1417_li=Tree index\: Instead of an AVL tree, use a general balanced trees or a scapegoat tree. -roadmap_1418_li=User defined functions\: allow to store the bytecode (of just the class, or the jar file of the extension) in the database. -roadmap_1419_li=Compatibility\: ResultSet.getObject() on a CLOB (TEXT) should return String for PostgreSQL and MySQL. -roadmap_1420_li=Optimizer\: WHERE X\=? AND Y IN(?), it always uses the index on Y. Should be cost based. -roadmap_1421_li=Support ALTER SCHEMA name RENAME TO newName (rename schema). -roadmap_1422_li=Make the cache scan resistant (currently a small cache is faster than a large cache for large table scans). -roadmap_1423_li=Issue 178\: Optimizer\: index usage when both ascending and descending indexes are available -roadmap_1424_li=Issue 179\: Related subqueries in HAVING clause -roadmap_1425_li=IBM DB2 compatibility\: NOT NULL WITH DEFAULT. Similar to MySQL Mode.convertInsertNullToZero. -roadmap_1426_li=Creating primary key\: always create a constraint. -roadmap_1427_li=Support a data type "timestamp with timezone" using java.util.Calendar. -roadmap_1428_li=Maybe use a different page layout\: keep the data at the head of the page, and ignore the tail (don't store / read it). This may increase write / read performance depending on the file system. -roadmap_1429_li=Indexes of temporary tables are currently kept in-memory. Is this how it should be? -roadmap_1430_li=The Shell tool should support the same built-in commands as the H2 Console. -roadmap_1431_li=Maybe use PhantomReference instead of finalize. -roadmap_1432_li=Database file name suffix\: a way to use no or a different suffix (for example using a slash). -roadmap_1433_li=Database file name suffix\: should only have one dot by default. Example\: .h2db -roadmap_1434_li=Issue 196\: Function based indexes -roadmap_1435_li=Fix the disk space leak (killing the process at the exact right moment will increase the disk space usage; this space is not re-used). See TestDiskSpaceLeak.java -roadmap_1436_li=ROWNUM\: Oracle compatibility when used within a subquery. Issue 198. -roadmap_1437_li=Allow to access the database over HTTP (possibly using port 80) and a servlet in a REST way. -roadmap_1438_li=ODBC\: encrypted databases are not supported because the ;CIPHER\= can not be set. -roadmap_1439_li=Support CLOB and BLOB update, specially conn.createBlob().setBinaryStream(1); -roadmap_1440_li=Triggers\: support user defined execution order. Oracle\: CREATE OR REPLACE TRIGGER TEST_2 BEFORE INSERT ON TEST FOR EACH ROW FOLLOWS TEST_1. SQL specifies that multiple triggers should be fired in time-of-creation order. PostgreSQL uses name order, which was judged to be more convenient. Derby\: triggers are fired in the order in which they were created. -roadmap_1441_li=PostgreSQL compatibility\: combine "users" and "roles". See\: http\://www.postgresql.org/docs/8.1/interactive/user-manag.html -roadmap_1442_li=Support NULL with a type\: @meta CALL CAST(NULL AS INT) should return INT. See the ValueExpression.java (currently it returns the type of the value; it could have it's own type/precision/scale optionally, for example when created from CAST, which is implemented in Function.java). -roadmap_1443_li=Improve documentation of system properties\: only list the property names, default values, and description. -roadmap_1444_li=Support running totals / cumulative sum using SUM(..) OVER(..). -roadmap_1445_li=Improve object memory size calculation. Use constants for known VMs, or use reflection to call java.lang.instrument.Instrumentation.getObjectSize(Object objectToSize) -roadmap_1446_h2=Not Planned -roadmap_1447_li=HSQLDB (did) support this\: select id i from test where i<0 (other databases don't). Supporting it may break compatibility. -roadmap_1448_li=String.intern (so that Strings can be compared with \=\=) will not be used because some VMs have problems when used extensively. -roadmap_1449_li=In prepared statements, identifier names (table names and so on) can not be parameterized. Adding such a feature would complicate the source code without providing reasonable speedup, and would slow down regular prepared statements. -sourceError_1000_h1=Error Analyzer -sourceError_1001_a=Home -sourceError_1002_a=Input -sourceError_1003_h2=  Details  Source Code -sourceError_1004_p=Paste the error message and stack trace below and click on 'Details' or 'Source Code'\: -sourceError_1005_b=Error Code\: -sourceError_1006_b=Product Version\: -sourceError_1007_b=Message\: -sourceError_1008_b=More Information\: -sourceError_1009_b=Stack Trace\: -sourceError_1010_b=Source File\: -sourceError_1011_p=\ Raw file -sourceError_1012_p=\ (fast; only Firefox) -tutorial_1000_h1=Tutorial -tutorial_1001_a=\ Starting and Using the H2 Console -tutorial_1002_a=\ Special H2 Console Syntax -tutorial_1003_a=\ Settings of the H2 Console -tutorial_1004_a=\ Connecting to a Database using JDBC -tutorial_1005_a=\ Creating New Databases -tutorial_1006_a=\ Using the Server -tutorial_1007_a=\ Using Hibernate -tutorial_1008_a=\ Using TopLink and Glassfish -tutorial_1009_a=\ Using EclipseLink -tutorial_1010_a=\ Using Databases in Web Applications -tutorial_1011_a=\ CSV (Comma Separated Values) Support -tutorial_1012_a=\ Upgrade, Backup, and Restore -tutorial_1013_a=\ Command Line Tools -tutorial_1014_a=\ The Shell Tool -tutorial_1015_a=\ Using OpenOffice Base -tutorial_1016_a=\ Java Web Start / JNLP -tutorial_1017_a=\ Using a Connection Pool -tutorial_1018_a=\ Fulltext Search -tutorial_1019_a=\ User-Defined Variables -tutorial_1020_a=\ Date and Time -tutorial_1021_a=\ Using Spring -tutorial_1022_h2=Starting and Using the H2 Console -tutorial_1023_p=\ The H2 Console 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. -tutorial_1024_p=\ This is a client / server application, so both a server and a client (a browser) are required to run it. -tutorial_1025_p=\ Depending on your platform and environment, there are multiple ways to start the application\: -tutorial_1026_th=OS -tutorial_1027_th=Start -tutorial_1028_td=Windows -tutorial_1029_td=\ Click [Start], [All Programs], [H2], and [H2 Console (Command Line)] -tutorial_1030_td=\ When using the Sun JDK 1.5, a window with the title 'H2 Console ' should appear. When using the Sun JDK 1.6, an icon will be added to the system tray\: -tutorial_1031_td=\ If you don't get the window and 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 at http\://localhost\:8082. -tutorial_1032_td=Windows -tutorial_1033_td=\ Open a file browser, navigate to h2/bin, and double click on h2.bat. -tutorial_1034_td=\ A console window appears. If there is a problem, you will see an error message in this window. A browser window will open and point to the Login page (URL\: http\://localhost\:8082). -tutorial_1035_td=Any -tutorial_1036_td=\ Double click on the h2*.jar file. This only works if the .jar suffix is associated with java. -tutorial_1037_td=Any -tutorial_1038_td=\ Open a console window, navigate to the directory h2/bin and type\: -tutorial_1039_h3=Firewall -tutorial_1040_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 application 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. -tutorial_1041_p=\ It has been reported that when using Kaspersky 7.0 with firewall, the H2 Console is very slow when connecting over the IP address. A workaround is to connect using localhost, however this only works on the local machine. -tutorial_1042_p=\ A small firewall is already built into the server\: other computers may not connect to the server by default. To change this, go to 'Preferences' and select 'Allow connections from other computers'. -tutorial_1043_h3=Testing Java -tutorial_1044_p=\ To find out which version of Java is installed, open a command prompt and type\: -tutorial_1045_p=\ If you get an error message, you may need to add the Java binary directory to the path environment variable. -tutorial_1046_h3=Error Message 'Port may be in use' -tutorial_1047_p=\ You can only start one instance of the H2 Console, otherwise you will get the following error message\: "The Web server could not be started. Possible cause\: another server is already running...". It is possible to start multiple console applications on the same computer (using different ports), but this is usually not required as the console supports multiple concurrent connections. -tutorial_1048_h3=Using another Port -tutorial_1049_p=\ If the port is in use by another application, you may want to start the H2 Console on a different port. This can be done by changing the port in the file .h2.server.properties. This file is stored in the user directory (for Windows, this is usually in Documents and Settings/<username>). The relevant entry is webPort. -tutorial_1050_h3=Connecting to the Server using a Browser -tutorial_1051_p=\ If the server started successfully, you can connect to it using a web browser. JavaScript needs to be enabled. If you started the server on the same computer as the browser, open the URL http\://localhost\:8082. If you want to connect to the application from another computer, you need to provide the IP address of the server, for example\: http\://192.168.0.2\:8082. If you enabled SSL on the server side, the URL needs to start with https\://. -tutorial_1052_h3=Multiple Concurrent Sessions -tutorial_1053_p=\ Multiple concurrent browser sessions are supported. As that the database objects reside on the server, the amount of concurrent work is limited by the memory available to the server application. -tutorial_1054_h3=Login -tutorial_1055_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]. -tutorial_1056_p=\ You can save and reuse previously saved settings. The settings are stored in a properties file (see Settings of the H2 Console). -tutorial_1057_h3=Error Messages -tutorial_1058_p=\ Error messages in are shown in red. You can show/hide the stack trace of the exception by clicking on the message. -tutorial_1059_h3=Adding Database Drivers -tutorial_1060_p=\ Additional database drivers to connect to other databases (MySQL, PostgreSQL, HSQLDB,...) 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. -tutorial_1061_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. -tutorial_1062_h3=Using the H2 Console -tutorial_1063_p=\ The H2 Console application has three main panels\: the toolbar on top, the tree on the left, and the query / result panel on the right. The database objects (for example, tables) are listed on the left panel. Type in a SQL command on the query panel and click 'Run'. The result of the command appears just below the command. -tutorial_1064_h3=Inserting Table Names or Column Names -tutorial_1065_p=\ The table name and column names can be inserted in the script by clicking them in the tree. If you click on a table while the query is empty, then SELECT * FROM ... is added as well. While typing a query, the table that was used is automatically expanded in the tree. For example if you type SELECT * FROM TEST T WHERE T. then the table TEST is automatically expanded in the tree. -tutorial_1066_h3=Disconnecting and Stopping the Application -tutorial_1067_p=\ To log out of the database, click 'Disconnect' in the toolbar panel. However, the server is still running and ready to accept new sessions. -tutorial_1068_p=\ To stop the server, right click on the system tray icon and select [Exit]. If you don't have the system tray icon, navigate to [Preferences] and click [Shutdown], press [Ctrl]+[C] in the console where the server was started (Windows), or close the console window. -tutorial_1069_h2=Special H2 Console Syntax -tutorial_1070_p=\ The H2 Console supports a few built-in commands. Those are interpreted within the H2 Console, that means they work with any database. They need to be at the beginning of a statement (before any remarks), otherwise they are not parsed correctly. If in doubt, add ';' before the command. -tutorial_1071_th=Command(s) -tutorial_1072_th=Description -tutorial_1073_td=\ @autocommit_true; -tutorial_1074_td=\ @autocommit_false; -tutorial_1075_td=\ Enable or disable autocommit. -tutorial_1076_td=\ @cancel; -tutorial_1077_td=\ Cancel the currently running statement. -tutorial_1078_td=\ @columns null null TEST; -tutorial_1079_td=\ @index_info null null TEST; -tutorial_1080_td=\ @tables; -tutorial_1081_td=\ @tables null null TEST; -tutorial_1082_td=\ Call the corresponding DatabaseMetaData.get method. Patterns are case sensitive (usually identifiers are uppercase). For information about the parameters, see the Javadoc documentation. Missing parameters at the end are set to null. The complete list of commands is\: @attributes @best_row_identifier @catalogs @columns @column_privileges @cross_references @exported_keys @imported_keys @index_info @primary_keys @procedures @procedure_columns @schemas @super_tables @super_types @tables @table_privileges @table_types @type_info @udts @version_columns -tutorial_1083_td=\ @edit select * from test; -tutorial_1084_td=\ Use an updatable result set. -tutorial_1085_td=\ @generated insert into test() values(); -tutorial_1086_td=\ Show the result of Statement.getGeneratedKeys(). -tutorial_1087_td=\ @history; -tutorial_1088_td=\ Show the command history. -tutorial_1089_td=\ @info; -tutorial_1090_td=\ Display the result of various Connection and DatabaseMetaData methods. -tutorial_1091_td=\ @list select * from test; -tutorial_1092_td=\ Show the result set in list format (each column on its own line, with row numbers). -tutorial_1093_td=\ @loop 1000 select ?, ?/*rnd*/; -tutorial_1094_td=\ @loop 1000 @statement select ?; -tutorial_1095_td=\ Run the statement this many times. Parameters (?) are set using a loop from 0 up to x - 1. Random values are used for each ?/*rnd*/. A Statement object is used instead of a PreparedStatement if @statement is used. Result sets are read until ResultSet.next() returns false. Timing information is printed. -tutorial_1096_td=\ @maxrows 20; -tutorial_1097_td=\ Set the maximum number of rows to display. -tutorial_1098_td=\ @memory; -tutorial_1099_td=\ Show the used and free memory. This will call System.gc(). -tutorial_1100_td=\ @meta select 1; -tutorial_1101_td=\ List the ResultSetMetaData after running the query. -tutorial_1102_td=\ @parameter_meta select ?; -tutorial_1103_td=\ Show the result of the PreparedStatement.getParameterMetaData() calls. The statement is not executed. -tutorial_1104_td=\ @prof_start; -tutorial_1105_td=\ call hash('SHA256', '', 1000000); -tutorial_1106_td=\ @prof_stop; -tutorial_1107_td=\ Start / stop the built-in profiling tool. The top 3 stack traces of the statement(s) between start and stop are listed (if there are 3). -tutorial_1108_td=\ @transaction_isolation; -tutorial_1109_td=\ @transaction_isolation 2; -tutorial_1110_td=\ Display (without parameters) or change (with parameters 1, 2, 4, 8) the transaction isolation level. -tutorial_1111_h2=Settings of the H2 Console -tutorial_1112_p=\ The settings of the H2 Console are stored in a configuration file called .h2.server.properties in you user home directory. For Windows installations, the user home directory is usually C\:\\Documents and Settings\\[username]. The configuration file contains the settings of the application and is automatically created when the H2 Console is first started. -tutorial_1113_h2=Connecting to a Database using JDBC -tutorial_1114_p=\ 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\: -tutorial_1115_p=\ This code first loads the driver (Class.forName(...)) and then opens a connection (using DriverManager.getConnection()). The driver name is "org.h2.Driver". The database URL always needs to start with jdbc\:h2\: to be recognized by this database. The second parameter in the getConnection() call is the user name (sa for System Administrator in this example). The third parameter is the password. In this database, user names are not case sensitive, but passwords are. -tutorial_1116_h2=Creating New Databases -tutorial_1117_p=\ By default, if the database specified in the URL does not yet exist, a new (empty) database is created automatically. The user that created the database automatically becomes the administrator of this database. -tutorial_1118_p=\ Auto-creating new database can be disabled, see Opening a Database Only if it Already Exists. -tutorial_1119_h2=Using the Server -tutorial_1120_p=\ H2 currently supports three server\: a web server (for the H2 Console), a TCP server (for client/server connections) and an PG server (for PostgreSQL clients). Please note that only the web server supports browser connections. The servers can be started in different ways, one is using the Server tool. -tutorial_1121_h3=Starting the Server Tool from Command Line -tutorial_1122_p=\ To start the Server tool from the command line with the default settings, run\: -tutorial_1123_p=\ This will start the tool with the default options. To get the list of options and default values, run\: -tutorial_1124_p=\ There are options available to use other ports, and start or not start parts. -tutorial_1125_h3=Connecting to the TCP Server -tutorial_1126_p=\ To remotely connect to a database using the TCP server, use the following driver and database URL\: -tutorial_1127_li=JDBC driver class\: org.h2.Driver -tutorial_1128_li=Database URL\: jdbc\:h2\:tcp\://localhost/~/test -tutorial_1129_p=\ For details about the database URL, see also in Features. Please note that you can't connection with a web browser to this URL. You can only connect using a H2 client (over JDBC). -tutorial_1130_h3=Starting the TCP Server within an Application -tutorial_1131_p=\ Servers can also be started and stopped from within an application. Sample code\: -tutorial_1132_h3=Stopping a TCP Server from Another Process -tutorial_1133_p=\ The TCP server can be stopped from another process. To stop the server from the command line, run\: -tutorial_1134_p=\ To stop the server from a user application, use the following code\: -tutorial_1135_p=\ This function will only stop the TCP server. If other server were started in the same process, they will continue to run. To avoid recovery when the databases are opened the next time, all connections to the databases should be closed before calling this method. To stop a remote server, remote connections must be enabled on the server. Shutting down a TCP server can be protected using the option -tcpPassword (the same password must be used to start and stop the TCP server). -tutorial_1136_h2=Using Hibernate -tutorial_1137_p=\ This database supports Hibernate version 3.1 and newer. You can use the HSQLDB Dialect, or the native H2 Dialect. Unfortunately the H2 Dialect included in some versions of Hibernate is buggy. A patch for Hibernate has been submitted and is now applied. The dialect for the newest version of Hibernate is also available at src/tools/org/hibernate/dialect/H2Dialect.java.txt. You can rename it to H2Dialect.java and include this as a patch in your application, or upgrade to a version of Hibernate where this is fixed. -tutorial_1138_p=\ When using compatibility modes such as MODE\=MySQL when using Hibernate is not supported when using H2Dialect. -tutorial_1139_h2=Using TopLink and Glassfish -tutorial_1140_p=\ To use H2 with Glassfish (or Sun AS), set the Datasource Classname to org.h2.jdbcx.JdbcDataSource. You can set this in the GUI at Application Server - Resources - JDBC - Connection Pools, or by editing the file sun-resources.xml\: at element jdbc-connection-pool, set the attribute datasource-classname to org.h2.jdbcx.JdbcDataSource. -tutorial_1141_p=\ The H2 database is compatible with HSQLDB and PostgreSQL. To take advantage of H2 specific features, use the H2Platform. The source code of this platform is included in H2 at src/tools/oracle/toplink/essentials/platform/database/DatabasePlatform.java.txt. You will need to copy this file to your application, and rename it to .java. To enable it, change the following setting in persistence.xml\: -tutorial_1142_p=\ In old versions of Glassfish, the property name is toplink.platform.class.name. -tutorial_1143_p=\ To use H2 within Glassfish, copy the h2*.jar to the directory glassfish/glassfish/lib. -tutorial_1144_h2=Using EclipseLink -tutorial_1145_p=\ To use H2 in EclipseLink, use the platform class org.eclipse.persistence.platform.database.H2Platform. If this platform is not available in your version of EclipseLink, you can use the OraclePlatform instead in many case. See also H2Platform. -tutorial_1146_h2=Using Databases in Web Applications -tutorial_1147_p=\ There are multiple ways to access a database from within web applications. Here are some examples if you use Tomcat or JBoss. -tutorial_1148_h3=Embedded Mode -tutorial_1149_p=\ The (currently) simplest solution is to use the database in the embedded mode, that means open a connection in your application when it starts (a good solution is using a Servlet Listener, see below), or when a session starts. A database can be accessed from multiple sessions and applications at the same time, as long as they run in the same process. Most Servlet Containers (for example Tomcat) are just using one process, so this is not a problem (unless you run Tomcat in clustered mode). Tomcat uses multiple threads and multiple classloaders. If multiple applications access the same database at the same time, you need to put the database jar in the shared/lib or server/lib directory. It is a good idea to open the database when the web application starts, and close it when the web application stops. If using multiple applications, only one (any) of them needs to do that. In the application, an idea is to use one connection per Session, or even one connection per request (action). Those connections should be closed after use if possible (but it's not that bad if they don't get closed). -tutorial_1150_h3=Server Mode -tutorial_1151_p=\ The server mode is similar, but it allows you to run the server in another process. -tutorial_1152_h3=Using a Servlet Listener to Start and Stop a Database -tutorial_1153_p=\ Add the h2*.jar file to your web application, and add the following snippet to your web.xml file (between the context-param and the filter section)\: -tutorial_1154_p=\ For details on how to access the database, see the file DbStarter.java. By default this tool opens an embedded connection using the database URL jdbc\:h2\:~/test, user name sa, and password sa. If you want to use this connection within your servlet, you can access as follows\: -tutorial_1155_code=DbStarter -tutorial_1156_p=\ can also start the TCP server, however this is disabled by default. To enable it, use the parameter db.tcpServer in the file web.xml. Here is the complete list of options. These options need to be placed between the description tag and the listener / filter tags\: -tutorial_1157_p=\ When the web application is stopped, the database connection will be closed automatically. If the TCP server is started within the DbStarter, it will also be stopped automatically. -tutorial_1158_h3=Using the H2 Console Servlet -tutorial_1159_p=\ The H2 Console is a standalone application and includes its own web server, but it can be used as a servlet as well. To do that, include the the h2*.jar file in your application, and add the following configuration to your web.xml\: -tutorial_1160_p=\ For details, see also src/tools/WEB-INF/web.xml. -tutorial_1161_p=\ To create a web application with just the H2 Console, run the following command\: -tutorial_1162_h2=CSV (Comma Separated Values) Support -tutorial_1163_p=\ The CSV file support can be used inside the database using the functions CSVREAD and CSVWRITE, or it can be used outside the database as a standalone tool. -tutorial_1164_h3=Reading a CSV File from Within a Database -tutorial_1165_p=\ A CSV file can be read using the function CSVREAD. Example\: -tutorial_1166_h3=Importing Data from a CSV File -tutorial_1167_p=\ A fast way to load or import data (sometimes called 'bulk load') from a CSV file is to combine table creation with import. Optionally, the column names and data types can be set when creating the table. Another option is to use INSERT INTO ... SELECT. -tutorial_1168_h3=Writing a CSV File from Within a Database -tutorial_1169_p=\ The built-in function CSVWRITE can be used to create a CSV file from a query. Example\: -tutorial_1170_h3=Writing a CSV File from a Java Application -tutorial_1171_p=\ The Csv tool can be used in a Java application even when not using a database at all. Example\: -tutorial_1172_h3=Reading a CSV File from a Java Application -tutorial_1173_p=\ It is possible to read a CSV file without opening a database. Example\: -tutorial_1174_h2=Upgrade, Backup, and Restore -tutorial_1175_h3=Database Upgrade -tutorial_1176_p=\ The recommended way to upgrade from one version of the database engine to the next version is to create a backup of the database (in the form of a SQL script) using the old engine, and then execute the SQL script using the new engine. -tutorial_1177_h3=Backup using the Script Tool -tutorial_1178_p=\ There are different ways to backup a database. For example, it is possible to copy the database files. However, this is not recommended while the database is in use. Also, the database files are not human readable and quite large. The recommended way to backup a database is to create a compressed SQL script file. This can be done using the Script tool\: -tutorial_1179_p=\ It is also possible to use the SQL command SCRIPT to create the backup of the database. For more information about the options, see the SQL command SCRIPT. The backup can be done remotely, however the file will be created on the server side. The built in FTP server could be used to retrieve the file from the server. -tutorial_1180_h3=Restore from a Script -tutorial_1181_p=\ To restore a database from a SQL script file, you can use the RunScript tool\: -tutorial_1182_p=\ For more information about the options, see the SQL command RUNSCRIPT. The restore can be done remotely, however the file needs to be on the server side. The built in FTP server could be used to copy the file to the server. It is also possible to use the SQL command RUNSCRIPT to execute a SQL script. 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. -tutorial_1183_h3=Online Backup -tutorial_1184_p=\ The BACKUP SQL statement and the Backup tool both create a zip file with all database files. However, the contents of this file are not human readable. -tutorial_1185_p=\ Unlike than the SCRIPT statement, the BACKUP statement does not lock the database objects when using the multi-threaded mode, and therefore does not block other users. The resulting backup is transactionally consistent\: -tutorial_1186_p=\ The Backup tool (org.h2.tools.Backup) can not be used to create a online backup; the database must not be in use while running this program. -tutorial_1187_p=\ Creating a backup by copying the database files while the database is running is not supported, except if the file systems support creating snapshots. The problem is that it can't be guaranteed that the data is copied in the right order. -tutorial_1188_h2=Command Line Tools -tutorial_1189_p=\ This database comes with a number of command line tools. To get more information about a tool, start it with the parameter '-?', for example\: -tutorial_1190_p=\ The command line tools are\: -tutorial_1191_code=Backup -tutorial_1192_li=\ creates a backup of a database. -tutorial_1193_code=ChangeFileEncryption -tutorial_1194_li=\ allows changing the file encryption password or algorithm of a database. -tutorial_1195_code=Console -tutorial_1196_li=\ starts the browser based H2 Console. -tutorial_1197_code=ConvertTraceFile -tutorial_1198_li=\ converts a .trace.db file to a Java application and SQL script. -tutorial_1199_code=CreateCluster -tutorial_1200_li=\ creates a cluster from a standalone database. -tutorial_1201_code=DeleteDbFiles -tutorial_1202_li=\ deletes all files belonging to a database. -tutorial_1203_code=Recover -tutorial_1204_li=\ helps recovering a corrupted database. -tutorial_1205_code=Restore -tutorial_1206_li=\ restores a backup of a database. -tutorial_1207_code=RunScript -tutorial_1208_li=\ runs a SQL script against a database. -tutorial_1209_code=Script -tutorial_1210_li=\ allows converting a database to a SQL script for backup or migration. -tutorial_1211_code=Server -tutorial_1212_li=\ is used in the server mode to start a H2 server. -tutorial_1213_code=Shell -tutorial_1214_li=\ is a command line database tool. -tutorial_1215_p=\ The tools can also be called from an application by calling the main or another public method. For details, see the Javadoc documentation. -tutorial_1216_h2=The Shell Tool -tutorial_1217_p=\ The Shell tool is a simple interactive command line tool. To start it, type\: -tutorial_1218_p=\ You will be asked for a database URL, JDBC driver, user name, and password. The connection setting can also be set as command line parameters. After connecting, you will get the list of options. The built-in commands don't need to end with a semicolon, but SQL statements are only executed if the line ends with a semicolon ;. This allows to enter multi-line statements\: -tutorial_1219_p=\ By default, results are printed as a table. For results with many column, consider using the list mode\: -tutorial_1220_h2=Using OpenOffice Base -tutorial_1221_p=\ 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. The steps to connect to a H2 database are\: -tutorial_1222_li=Start OpenOffice Writer, go to [Tools], [Options] -tutorial_1223_li=Make sure you have selected a Java runtime environment in OpenOffice.org / Java -tutorial_1224_li=Click [Class Path...], [Add Archive...] -tutorial_1225_li=Select your h2 jar file (location is up to you, could be wherever you choose) -tutorial_1226_li=Click [OK] (as much as needed), stop OpenOffice (including the Quickstarter) -tutorial_1227_li=Start OpenOffice Base -tutorial_1228_li=Connect to an existing database; select [JDBC]; [Next] -tutorial_1229_li=Example datasource URL\: jdbc\:h2\:~/test -tutorial_1230_li=JDBC driver class\: org.h2.Driver -tutorial_1231_p=\ Now you can access the database stored in the current users home directory. -tutorial_1232_p=\ To use H2 in NeoOffice (OpenOffice without X11)\: -tutorial_1233_li=In NeoOffice, go to [NeoOffice], [Preferences] -tutorial_1234_li=Look for the page under [NeoOffice], [Java] -tutorial_1235_li=Click [Class Path], [Add Archive...] -tutorial_1236_li=Select your h2 jar file (location is up to you, could be wherever you choose) -tutorial_1237_li=Click [OK] (as much as needed), restart NeoOffice. -tutorial_1238_p=\ Now, when creating a new database using the "Database Wizard" \: -tutorial_1239_li=Click [File], [New], [Database]. -tutorial_1240_li=Select [Connect to existing database] and the select [JDBC]. Click next. -tutorial_1241_li=Example datasource URL\: jdbc\:h2\:~/test -tutorial_1242_li=JDBC driver class\: org.h2.Driver -tutorial_1243_p=\ Another solution to use H2 in NeoOffice is\: -tutorial_1244_li=Package the h2 jar within an extension package -tutorial_1245_li=Install it as a Java extension in NeoOffice -tutorial_1246_p=\ This can be done by create it using the NetBeans OpenOffice plugin. See also Extensions Development. -tutorial_1247_h2=Java Web Start / JNLP -tutorial_1248_p=\ When using Java Web Start / JNLP (Java Network Launch Protocol), permissions tags must be set in the .jnlp file, and the application .jar file must be signed. Otherwise, when trying to write to the file system, the following exception will occur\: java.security.AccessControlException\: access denied (java.io.FilePermission ... read). Example permission tags\: -tutorial_1249_h2=Using a Connection Pool -tutorial_1250_p=\ For H2, opening a connection is fast if the database is already open. Still, using a connection pool improves performance if you open and close connections a lot. A simple connection pool is included in H2. It is based on the Mini Connection Pool Manager from Christian d'Heureuse. There are other, more complex, open source connection pools available, for example the Apache Commons DBCP. For H2, it is about twice as faster to get a connection from the built-in connection pool than to get one using DriverManager.getConnection().The build-in connection pool is used as follows\: -tutorial_1251_h2=Fulltext Search -tutorial_1252_p=\ H2 includes two fulltext search implementations. One is using Apache Lucene, and the other (the native implementation) stores the index data in special tables in the database. -tutorial_1253_h3=Using the Native Fulltext Search -tutorial_1254_p=\ To initialize, call\: -tutorial_1255_p=\ You need to initialize it in each database where you want to use it. Afterwards, you can create a fulltext index for a table using\: -tutorial_1256_p=\ PUBLIC is the schema name, TEST is the table name. The list of column names (column separated) is optional, in this case all columns are indexed. The index is updated in realtime. To search the index, use the following query\: -tutorial_1257_p=\ This will produce a result set that contains the query needed to retrieve the data\: -tutorial_1258_p=\ To get the raw data, use FT_SEARCH_DATA('Hello', 0, 0);. The result contains the columns SCHEMA (the schema name), TABLE (the table name), COLUMNS (an array of column names), and KEYS (an array of objects). To join a table, use a join as in\: SELECT T.* FROM FT_SEARCH_DATA('Hello', 0, 0) FT, TEST T WHERE FT.TABLE\='TEST' AND T.ID\=FT.KEYS[0]; -tutorial_1259_p=\ You can also call the index from within a Java application\: -tutorial_1260_h3=Using the Lucene Fulltext Search -tutorial_1261_p=\ To use the Lucene full text search, you need the Lucene library in the classpath. How to do that depends on the application; if you use the H2 Console, you can add the Lucene jar file to the environment variables H2DRIVERS or CLASSPATH. To initialize the Lucene fulltext search in a database, call\: -tutorial_1262_p=\ You need to initialize it in each database where you want to use it. Afterwards, you can create a full text index for a table using\: -tutorial_1263_p=\ PUBLIC is the schema name, TEST is the table name. The list of column names (column separated) is optional, in this case all columns are indexed. The index is updated in realtime. To search the index, use the following query\: -tutorial_1264_p=\ This will produce a result set that contains the query needed to retrieve the data\: -tutorial_1265_p=\ To get the raw data, use FTL_SEARCH_DATA('Hello', 0, 0);. The result contains the columns SCHEMA (the schema name), TABLE (the table name), COLUMNS (an array of column names), and KEYS (an array of objects). To join a table, use a join as in\: SELECT T.* FROM FTL_SEARCH_DATA('Hello', 0, 0) FT, TEST T WHERE FT.TABLE\='TEST' AND T.ID\=FT.KEYS[0]; -tutorial_1266_p=\ You can also call the index from within a Java application\: -tutorial_1267_h2=User-Defined Variables -tutorial_1268_p=\ This database supports user-defined variables. Variables start with @ and can be used wherever expressions or parameters are allowed. Variables are not persisted and session scoped, that means only visible from within the session in which they are defined. A value is usually assigned using the SET command\: -tutorial_1269_p=\ The value can also be changed using the SET() method. This is useful in queries\: -tutorial_1270_p=\ Variables that are not set evaluate to NULL. The data type of a user-defined variable is the data type of the value assigned to it, that means it is not necessary (or possible) to declare variable names before using them. There are no restrictions on the assigned values; large objects (LOBs) are supported as well. -tutorial_1271_h2=Date and Time -tutorial_1272_p=\ Date, time and timestamp values support ISO 8601 formatting, including time zone\: -tutorial_1273_p=\ If the time zone is not set, the value is parsed using the current time zone setting of the system. Date and time information is stored in H2 database files in GMT (Greenwich Mean Time). If the database is opened using another system time zone, the date and time will change accordingly. If you want to move a database from one time zone to the other and don't want this to happen, you need to create a SQL script file using the SCRIPT command or Script tool, and then load the database using the RUNSCRIPT command or the RunScript tool in the new time zone. -tutorial_1274_h2=Using Spring -tutorial_1275_p=\ Use the following configuration to start and stop the H2 TCP server using the Spring Framework\: -tutorial_1276_p=\ The destroy-method will help prevent exceptions on hot-redeployment or when restarting the server. diff --git a/tools/h2/src/docsrc/textbase/_messages_en.prop b/tools/h2/src/docsrc/textbase/_messages_en.prop deleted file mode 100755 index 18fb37e..0000000 --- a/tools/h2/src/docsrc/textbase/_messages_en.prop +++ /dev/null @@ -1,168 +0,0 @@ -.translator=Thomas Mueller -02000=No data is available -07001=Invalid parameter count for {0}, expected count: {1} -08000=Error opening database: {0} -08004=Wrong user name or password -21S02=Column count does not match -22003=Numeric value out of range -22012=Division by zero: {0} -22025=Error in LIKE ESCAPE: {0} -23000=Check constraint violation: {0} -23001=Unique index or primary key violation: {0} -23002=Referential integrity constraint violation: {0} -23003=Referential integrity constraint violation: {0} -40001=Deadlock detected. The current transaction was rolled back. Details: {0} -42000=Syntax error in SQL statement {0} -42001=Syntax error in SQL statement {0}; expected {1} -42S01=Table {0} already exists -42S02=Table {0} not found -42S11=Index {0} already exists -42S12=Index {0} not found -42S21=Duplicate column name {0} -42S22=Column {0} not found -42S32=Setting {0} not found -90000=Function {0} must return a result set -90001=Method is not allowed for a query. Use execute or executeQuery instead of executeUpdate -90002=Method is only allowed for a query. Use execute or executeUpdate instead of executeQuery -90003=Hexadecimal string with odd number of characters: {0} -90004=Hexadecimal string contains non-hex character: {0} -90005=Value too long for column {0}: {1} -90006=NULL not allowed for column {0} -90007=The object is already closed -90008=Invalid value {0} for parameter {1} -90009=Cannot parse date constant {0}, cause: {1} -90010=Cannot parse time constant {0}, cause: {1} -90011=Cannot parse timestamp constant {0}, cause: {1} -90012=Parameter {0} is not set -90013=Database {0} not found -90014=Error parsing {0} -90015=SUM or AVG on wrong data type for {0} -90016=Column {0} must be in the GROUP BY list -90017=Attempt to define a second primary key -90018=The connection was not closed by the application and is garbage collected -90019=Cannot drop the current user -90020=Database may be already in use: {0}. Possible solutions: close all other connection(s); use the server mode -90021=Data conversion error converting {0} -90022=Function {0} not found -90023=Column {0} must not be nullable -90024=Error while renaming file {0} to {1} -90025=Cannot delete file {0} -90026=Serialization failed, cause: {0} -90027=Deserialization failed, cause: {0} -90028=IO Exception: {0} -90029=Currently not on an updatable row -90030=File corrupted while reading record: {0}. Possible solution: use the recovery tool -90031=IO Exception: {0}; {1} -90032=User {0} not found -90033=User {0} already exists -90034=Log file error: {0}, cause: {1} -90035=Sequence {0} already exists -90036=Sequence {0} not found -90037=View {0} not found -90038=View {0} already exists -90039=The value is too large for the precision {0} -90040=Admin rights are required for this operation -90041=Trigger {0} already exists -90042=Trigger {0} not found -90043=Error creating or initializing trigger {0} object, class {1}, cause: {2}; see root cause for details -90044=Error executing trigger {0}, class {1}, cause : {2}; see root cause for details -90045=Constraint {0} already exists -90046=URL format error; must be {0} but is {1} -90047=Version mismatch, driver version is {0} but server version is {1} -90048=Unsupported database file version or invalid file header in file {0} -90049=Encryption error in file {0} -90050=Wrong password format, must be: file password user password -90051=Statement was canceled or the session timed out -90052=Subquery is not a single column query -90053=Scalar subquery contains more than one row -90054=Invalid use of aggregate function {0} -90055=Unsupported cipher {0} -90056=No default value is set for column {0} -90057=Constraint {0} not found -90058=Commit or rollback is not allowed within a trigger -90059=Ambiguous column name {0} -90060=Unsupported file lock method {0} -90061=Exception opening port {0} (port may be in use), cause: {1} -90062=Error while creating file {0} -90063=Savepoint is invalid: {0} -90064=Savepoint is unnamed -90065=Savepoint is named -90066=Duplicate property {0} -90067=Connection is broken: {0} -90068=Order by expression {0} must be in the result list in this case -90069=Role {0} already exists -90070=Role {0} not found -90071=User or role {0} not found -90072=Roles and rights cannot be mixed -90073=Matching Java methods must have different parameter counts: {0} and {1} -90074=Role {0} already granted -90075=Column is part of the index {0} -90076=Function alias {0} already exists -90077=Function alias {0} not found -90078=Schema {0} already exists -90079=Schema {0} not found -90080=Schema name must match -90081=Column {0} contains null values -90082=Sequence {0} belongs to a table -90083=Column may be referenced by {0} -90084=Cannot drop last column {0} -90085=Index {0} belongs to a constraint -90086=Class {0} not found -90087=Method {0} not found -90088=Unknown mode {0} -90089=Collation cannot be changed because there is a data table: {0} -90090=Schema {0} cannot be dropped -90091=Role {0} cannot be dropped -90092=This Java version is not supported (Java 1.4 is required) -90093=Clustering error - database currently runs in standalone mode -90094=Clustering error - database currently runs in cluster mode, server list: {0} -90095=String format error: {0} -90096=Not enough rights for object {0} -90097=The database is read only -90098=The database has been closed -90099=Error setting database event listener {0}, cause: {1} -90100=No disk space available -90101=Wrong XID format: {0} -90102=Unsupported compression options: {0} -90103=Unsupported compression algorithm: {0} -90104=Compression error -90105=Exception calling user-defined function: {0} -90106=Cannot truncate {0} -90107=Cannot drop {0} because {1} depends on it -90108=Out of memory. -90109=View {0} is invalid: {1} -90110={0} out of range -90111=Error accessing linked table with SQL statement {0}, cause: {1} -90112=Row not found when trying to delete from index {0} -90113=Unsupported connection setting {0} -90114=Constant {0} already exists -90115=Constant {0} not found -90116=Literals of this kind are not allowed -90117=Remote connections to this server are not allowed, see -tcpAllowOthers -90118=Cannot drop table {0} -90119=User data type {0} already exists -90120=User data type {0} not found -90121=Database is already closed (to disable automatic closing at VM shutdown, add ";DB_CLOSE_ON_EXIT=FALSE" to the db URL) -90122=Operation not supported for table {0} when there are views on the table: {1} -90123=Cannot mix indexed and non-indexed parameters -90124=File not found: {0} -90125=Invalid class, expected {0} but got {1} -90126=Database is not persistent -90127=The result set is not updatable. The query must select all columns from a unique key. Only one table may be selected. -90128=The result set is not scrollable and can not be reset. You may need to use conn.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ..). -90129=Transaction {0} not found -90130=This method is not allowed for a prepared statement; use a regular statement instead. -90131=Concurrent update in table {0}: another transaction has updated or deleted the same row -90132=Aggregate {0} not found -90133=Cannot change the setting {0} when the database is already open -90134=Access to the class {0} is denied -90135=The database is open in exclusive mode; can not open additional connections -90136=Unsupported outer join condition: {0} -90137=Can only assign to a variable, not to: {0} -90138=Invalid database name: {0} -90139=The public static Java method was not found: {0} -90140=The result set is readonly. You may need to use conn.createStatement(.., ResultSet.CONCUR_UPDATABLE). -HY000=General error: {0} -HY004=Unknown data type: {0} -HYC00=Feature not supported: {0} -HYT00=Timeout trying to lock table {0} diff --git a/tools/h2/src/docsrc/textbase/_text_en.prop b/tools/h2/src/docsrc/textbase/_text_en.prop deleted file mode 100755 index 79d0a33..0000000 --- a/tools/h2/src/docsrc/textbase/_text_en.prop +++ /dev/null @@ -1,149 +0,0 @@ -.translator=Thomas Mueller -a.help=Help -a.language=English -a.lynxNotSupported=Sorry, Lynx not supported yet -a.password=Password -a.remoteConnectionsDisabled=Sorry, remote connections ('webAllowOthers') are disabled on this server. -a.title=H2 Console -a.tools=Tools -a.user=User Name -admin.executing=Executing -admin.ip=IP -admin.lastAccess=Last Access -admin.lastQuery=Last Query -admin.url=URL -adminAllow=Allowed clients -adminConnection=Connection security -adminHttp=Use unencrypted HTTP connections -adminHttps=Use encrypted SSL (HTTPS) connections -adminLocal=Only allow local connections -adminLogin=Administration Login -adminLoginCancel=Cancel -adminLoginOk=OK -adminLogout=Logout -adminOthers=Allow connections from other computers -adminPort=Port number -adminPortWeb=Web server port number -adminRestart=Changes take effect after restarting the server. -adminSave=Save -adminSessions=Active Sessions -adminShutdown=Shutdown -adminTitle=H2 Console Preferences -adminTranslateHelp=Translate or improve the translation of the H2 Console. -adminTranslateStart=Translate -helpAction=Action -helpAddAnotherRow=Add another row -helpAddDrivers=Adding Database Drivers -helpAddDriversText=Additional database drivers can be registered by adding the Jar file location of the driver to the 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. -helpAddRow=Add a new row -helpCommandHistory=Shows the Command History -helpCreateTable=Create a new table -helpDeleteRow=Remove a row -helpDisconnect=Disconnects from the database -helpDisplayThis=Displays this Help Page -helpDropTable=Delete the table if it exists -helpExecuteCurrent=Executes the current SQL statement -helpIcon=Icon -helpImportantCommands=Important Commands -helpOperations=Operations -helpQuery=Query the table -helpSampleSQL=Sample SQL Script -helpStatements=SQL statements -helpUpdate=Change data in a row -helpWithColumnsIdName=with ID and NAME columns -login.connect=Connect -login.driverClass=Driver Class -login.driverNotFound=Database driver not found
See in the Help for how to add drivers -login.goAdmin=Preferences -login.jdbcUrl=JDBC URL -login.language=Language -login.login=Login -login.remove=Remove -login.save=Save -login.savedSetting=Saved Settings -login.settingName=Setting Name -login.testConnection=Test Connection -login.testSuccessful=Test successful -login.welcome=H2 Console -result.1row=1 row -result.autoCommitOff=Auto commit is now OFF -result.autoCommitOn=Auto commit is now ON -result.bytes=bytes -result.characters=characters -result.maxrowsSet=Max rowcount is set -result.noRows=no rows -result.noRunningStatement=There is currently no running statement -result.rows=rows -result.statementWasCanceled=The statement was canceled -result.updateCount=Update count -resultEdit.add=Add -resultEdit.cancel=Cancel -resultEdit.delete=Delete -resultEdit.edit=Edit -resultEdit.editResult=Edit -resultEdit.save=Save -toolbar.all=All -toolbar.autoCommit=Auto commit -toolbar.autoComplete=Auto complete -toolbar.autoComplete.full=Full -toolbar.autoComplete.normal=Normal -toolbar.autoComplete.off=Off -toolbar.cancelStatement=Cancel the current statement -toolbar.clear=Clear -toolbar.commit=Commit -toolbar.disconnect=Disconnect -toolbar.history=Command history -toolbar.maxRows=Max rows -toolbar.refresh=Refresh -toolbar.rollback=Rollback -toolbar.run=Run (Ctrl+Enter) -toolbar.sqlStatement=SQL statement -tools.backup=Backup -tools.backup.help=Creates a backup of a database. -tools.changeFileEncryption=ChangeFileEncryption -tools.changeFileEncryption.help=Allows changing the database file encryption password and algorithm. -tools.cipher=Cipher (AES or XTEA) -tools.commandLine=Command line -tools.convertTraceFile=ConvertTraceFile -tools.convertTraceFile.help=Converts a .trace.db file to a Java application and SQL script. -tools.createCluster=CreateCluster -tools.createCluster.help=Creates a cluster from a standalone database. -tools.databaseName=Database name -tools.decryptionPassword=Decryption password -tools.deleteDbFiles=DeleteDbFiles -tools.deleteDbFiles.help=Deletes all files belonging to a database. -tools.directory=Directory -tools.encryptionPassword=Encryption password -tools.javaDirectoryClassName=Java directory and class name -tools.recover=Recover -tools.recover.help=Helps recovering a corrupted database. -tools.restore=Restore -tools.restore.help=Restores a database backup. -tools.result=Result -tools.run=Run -tools.runScript=RunScript -tools.runScript.help=Runs a SQL script. -tools.script=Script -tools.script.help=Allows to convert a database to a SQL script for backup or migration. -tools.scriptFileName=Script file name -tools.serverList=Server list -tools.sourceDatabaseName=Source database name -tools.sourceDatabaseURL=Source database URL -tools.sourceDirectory=Source directory -tools.sourceFileName=Source file name -tools.sourceScriptFileName=Source script file name -tools.targetDatabaseName=Target database name -tools.targetDatabaseURL=Target database URL -tools.targetDirectory=Target directory -tools.targetFileName=Target file name -tools.targetScriptFileName=Target script file name -tools.traceFileName=Trace file name -tree.admin=Admin -tree.current=Current value -tree.hashed=Hashed -tree.increment=Increment -tree.indexes=Indexes -tree.nonUnique=Non unique -tree.sequences=Sequences -tree.unique=Unique -tree.users=Users diff --git a/tools/h2/src/installer/buildRelease.bat b/tools/h2/src/installer/buildRelease.bat deleted file mode 100755 index dede345..0000000 --- a/tools/h2/src/installer/buildRelease.bat +++ /dev/null @@ -1,31 +0,0 @@ -@echo off -echo %time:~0,8% Start - -setlocal -cd ../.. -set today=%date:~6%%date:~3,2%%date:~0,2% -rmdir /s /q ..\h2web-%today% 2>nul -rmdir /s /q ..\h2web 2>nul -mkdir ..\h2web - -rmdir /s /q bin 2>nul -rmdir /s /q temp 2>nul -call java15 >nul 2>nul -call build -quiet - -call java16 >nul 2>nul -call build -quiet compile -call build -quiet spellcheck javadocImpl jarClient - -echo %time:~0,8% JDK 1.5 -call java15 >nul 2>nul -call build -quiet clean compile installer mavenDeployCentral - -rem call build -quiet compile benchmark -rem == Copy the benchmark results and update the performance page and diagram - -call java15 >nul 2>nul -call build -quiet switchSource -ren ..\h2web h2web-%today% - -echo %time:~0,8% Done diff --git a/tools/h2/src/installer/buildRelease.sh b/tools/h2/src/installer/buildRelease.sh deleted file mode 100755 index 2403f93..0000000 --- a/tools/h2/src/installer/buildRelease.sh +++ /dev/null @@ -1,31 +0,0 @@ -#!/bin/sh -echo $(date "+%H:%M:%S") Start -cd ../.. -rm -rf ../h2web -mkdir ../h2web - -rm -rf bin -rm -rf temp -JAVA_HOME=$JAVA15 -PATH=$JAVA15/bin:$PATH -./build.sh -quiet - -JAVA_HOME=$JAVA16 -PATH=$JAVA16/bin:$PATH -./build.sh -quiet compile -./build.sh -quiet spellcheck javadocImpl jarClient - -echo $(date "+%H:%M:%S") JDK 1.5 -JAVA_HOME=$JAVA15 -PATH=$JAVA15/bin:$PATH -./build.sh -quiet clean compile installer mavenDeployCentral - -# ./build.sh -quiet compile benchmark -# == Copy the benchmark results -# == and update the performance page and diagram - -JAVA_HOME=$JAVA15 -PATH=$JAVA15/bin:$PATH -./build.sh -quiet switchSource - -echo $(date "+%H:%M:%S") Done diff --git a/tools/h2/src/installer/checkstyle.xml b/tools/h2/src/installer/checkstyle.xml deleted file mode 100755 index 1bd0614..0000000 --- a/tools/h2/src/installer/checkstyle.xml +++ /dev/null @@ -1,91 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/tools/h2/src/installer/eclipse.settings/eclipseCodeStyle.xml b/tools/h2/src/installer/eclipse.settings/eclipseCodeStyle.xml deleted file mode 100755 index 9ca6d3d..0000000 --- a/tools/h2/src/installer/eclipse.settings/eclipseCodeStyle.xml +++ /dev/null @@ -1,269 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/tools/h2/src/installer/eclipse.settings/org.eclipse.core.resources.prefs b/tools/h2/src/installer/eclipse.settings/org.eclipse.core.resources.prefs deleted file mode 100755 index 99f26c0..0000000 --- a/tools/h2/src/installer/eclipse.settings/org.eclipse.core.resources.prefs +++ /dev/null @@ -1,2 +0,0 @@ -eclipse.preferences.version=1 -encoding/=UTF-8 diff --git a/tools/h2/src/installer/eclipse.settings/org.eclipse.jdt.core.prefs b/tools/h2/src/installer/eclipse.settings/org.eclipse.jdt.core.prefs deleted file mode 100755 index 2c2017e..0000000 --- a/tools/h2/src/installer/eclipse.settings/org.eclipse.jdt.core.prefs +++ /dev/null @@ -1,74 +0,0 @@ -eclipse.preferences.version=1 -org.eclipse.jdt.core.builder.cleanOutputFolder=clean -org.eclipse.jdt.core.builder.duplicateResourceTask=warning -org.eclipse.jdt.core.builder.invalidClasspath=abort -org.eclipse.jdt.core.builder.recreateModifiedClassFileInOutputFolder=ignore -org.eclipse.jdt.core.builder.resourceCopyExclusionFilter=*.launch,*.class -org.eclipse.jdt.core.circularClasspath=error -org.eclipse.jdt.core.classpath.exclusionPatterns=enabled -org.eclipse.jdt.core.classpath.multipleOutputLocations=enabled -org.eclipse.jdt.core.compiler.maxProblemPerUnit=100 -org.eclipse.jdt.core.compiler.problem.annotationSuperInterface=warning -org.eclipse.jdt.core.compiler.problem.autoboxing=ignore -org.eclipse.jdt.core.compiler.problem.comparingIdentical=warning -org.eclipse.jdt.core.compiler.problem.deadCode=warning -org.eclipse.jdt.core.compiler.problem.deprecation=warning -org.eclipse.jdt.core.compiler.problem.deprecationInDeprecatedCode=disabled -org.eclipse.jdt.core.compiler.problem.deprecationWhenOverridingDeprecatedMethod=disabled -org.eclipse.jdt.core.compiler.problem.discouragedReference=warning -org.eclipse.jdt.core.compiler.problem.emptyStatement=warning -org.eclipse.jdt.core.compiler.problem.fallthroughCase=ignore -org.eclipse.jdt.core.compiler.problem.fatalOptionalError=enabled -org.eclipse.jdt.core.compiler.problem.fieldHiding=warning -org.eclipse.jdt.core.compiler.problem.finalParameterBound=warning -org.eclipse.jdt.core.compiler.problem.finallyBlockNotCompletingNormally=warning -org.eclipse.jdt.core.compiler.problem.forbiddenReference=error -org.eclipse.jdt.core.compiler.problem.hiddenCatchBlock=warning -org.eclipse.jdt.core.compiler.problem.incompatibleNonInheritedInterfaceMethod=warning -org.eclipse.jdt.core.compiler.problem.incompleteEnumSwitch=ignore -org.eclipse.jdt.core.compiler.problem.indirectStaticAccess=warning -org.eclipse.jdt.core.compiler.problem.localVariableHiding=warning -org.eclipse.jdt.core.compiler.problem.methodWithConstructorName=warning -org.eclipse.jdt.core.compiler.problem.missingDeprecatedAnnotation=ignore -org.eclipse.jdt.core.compiler.problem.missingHashCodeMethod=warning -org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=ignore -org.eclipse.jdt.core.compiler.problem.missingSerialVersion=warning -org.eclipse.jdt.core.compiler.problem.missingSynchronizedOnInheritedMethod=warning -org.eclipse.jdt.core.compiler.problem.noEffectAssignment=warning -org.eclipse.jdt.core.compiler.problem.noImplicitStringConversion=warning -org.eclipse.jdt.core.compiler.problem.nonExternalizedStringLiteral=ignore -org.eclipse.jdt.core.compiler.problem.nullReference=warning -org.eclipse.jdt.core.compiler.problem.overridingPackageDefaultMethod=warning -org.eclipse.jdt.core.compiler.problem.parameterAssignment=ignore -org.eclipse.jdt.core.compiler.problem.possibleAccidentalBooleanAssignment=warning -org.eclipse.jdt.core.compiler.problem.potentialNullReference=ignore -org.eclipse.jdt.core.compiler.problem.rawTypeReference=warning -org.eclipse.jdt.core.compiler.problem.redundantNullCheck=warning -org.eclipse.jdt.core.compiler.problem.redundantSuperinterface=warning -org.eclipse.jdt.core.compiler.problem.specialParameterHidingField=disabled -org.eclipse.jdt.core.compiler.problem.staticAccessReceiver=warning -org.eclipse.jdt.core.compiler.problem.suppressWarnings=enabled -org.eclipse.jdt.core.compiler.problem.syntheticAccessEmulation=warning -org.eclipse.jdt.core.compiler.problem.typeParameterHiding=warning -org.eclipse.jdt.core.compiler.problem.uncheckedTypeOperation=warning -org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock=warning -org.eclipse.jdt.core.compiler.problem.unhandledWarningToken=warning -org.eclipse.jdt.core.compiler.problem.unnecessaryElse=warning -org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck=warning -org.eclipse.jdt.core.compiler.problem.unqualifiedFieldAccess=ignore -org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException=warning -org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionExemptExceptionAndThrowable=enabled -org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionIncludeDocCommentReference=enabled -org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionWhenOverriding=enabled -org.eclipse.jdt.core.compiler.problem.unusedImport=warning -org.eclipse.jdt.core.compiler.problem.unusedLabel=warning -org.eclipse.jdt.core.compiler.problem.unusedLocal=warning -org.eclipse.jdt.core.compiler.problem.unusedParameter=warning -org.eclipse.jdt.core.compiler.problem.unusedParameterIncludeDocCommentReference=enabled -org.eclipse.jdt.core.compiler.problem.unusedParameterWhenImplementingAbstract=disabled -org.eclipse.jdt.core.compiler.problem.unusedParameterWhenOverridingConcrete=disabled -org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=warning -org.eclipse.jdt.core.compiler.problem.unusedWarningToken=warning -org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=warning -org.eclipse.jdt.core.incompatibleJDKLevel=ignore -org.eclipse.jdt.core.incompleteClasspath=error diff --git a/tools/h2/src/installer/eclipse.settings/org.eclipse.jdt.launching.prefs b/tools/h2/src/installer/eclipse.settings/org.eclipse.jdt.launching.prefs deleted file mode 100755 index d211d32..0000000 --- a/tools/h2/src/installer/eclipse.settings/org.eclipse.jdt.launching.prefs +++ /dev/null @@ -1,2 +0,0 @@ -eclipse.preferences.version=1 -org.eclipse.jdt.launching.PREF_STRICTLY_COMPATIBLE_JRE_NOT_AVAILABLE=warning diff --git a/tools/h2/src/installer/eclipse.settings/org.eclipse.jdt.ui.prefs b/tools/h2/src/installer/eclipse.settings/org.eclipse.jdt.ui.prefs deleted file mode 100755 index 629c2b9..0000000 --- a/tools/h2/src/installer/eclipse.settings/org.eclipse.jdt.ui.prefs +++ /dev/null @@ -1,53 +0,0 @@ -eclipse.preferences.version=1 -editor_save_participant_org.eclipse.jdt.ui.postsavelistener.cleanup=true -sp_cleanup.add_default_serial_version_id=true -sp_cleanup.add_generated_serial_version_id=false -sp_cleanup.add_missing_annotations=false -sp_cleanup.add_missing_deprecated_annotations=true -sp_cleanup.add_missing_methods=false -sp_cleanup.add_missing_nls_tags=false -sp_cleanup.add_missing_override_annotations=true -sp_cleanup.add_serial_version_id=false -sp_cleanup.always_use_blocks=true -sp_cleanup.always_use_parentheses_in_expressions=true -sp_cleanup.always_use_this_for_non_static_field_access=false -sp_cleanup.always_use_this_for_non_static_method_access=false -sp_cleanup.convert_to_enhanced_for_loop=false -sp_cleanup.correct_indentation=false -sp_cleanup.format_source_code=false -sp_cleanup.format_source_code_changes_only=false -sp_cleanup.make_local_variable_final=false -sp_cleanup.make_parameters_final=false -sp_cleanup.make_private_fields_final=true -sp_cleanup.make_type_abstract_if_missing_method=false -sp_cleanup.make_variable_declarations_final=false -sp_cleanup.never_use_blocks=false -sp_cleanup.never_use_parentheses_in_expressions=false -sp_cleanup.on_save_use_additional_actions=true -sp_cleanup.organize_imports=false -sp_cleanup.qualify_static_field_accesses_with_declaring_class=false -sp_cleanup.qualify_static_member_accesses_through_instances_with_declaring_class=true -sp_cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class=true -sp_cleanup.qualify_static_member_accesses_with_declaring_class=false -sp_cleanup.qualify_static_method_accesses_with_declaring_class=false -sp_cleanup.remove_private_constructors=true -sp_cleanup.remove_trailing_whitespaces=true -sp_cleanup.remove_trailing_whitespaces_all=true -sp_cleanup.remove_trailing_whitespaces_ignore_empty=false -sp_cleanup.remove_unnecessary_casts=false -sp_cleanup.remove_unnecessary_nls_tags=false -sp_cleanup.remove_unused_imports=false -sp_cleanup.remove_unused_local_variables=false -sp_cleanup.remove_unused_private_fields=true -sp_cleanup.remove_unused_private_members=false -sp_cleanup.remove_unused_private_methods=true -sp_cleanup.remove_unused_private_types=true -sp_cleanup.sort_members=false -sp_cleanup.sort_members_all=false -sp_cleanup.use_blocks=false -sp_cleanup.use_blocks_only_for_return_and_throw=false -sp_cleanup.use_parentheses_in_expressions=false -sp_cleanup.use_this_for_non_static_field_access=false -sp_cleanup.use_this_for_non_static_field_access_only_if_necessary=true -sp_cleanup.use_this_for_non_static_method_access=false -sp_cleanup.use_this_for_non_static_method_access_only_if_necessary=true diff --git a/tools/h2/src/installer/favicon.ico b/tools/h2/src/installer/favicon.ico deleted file mode 100755 index 6e0f78a..0000000 Binary files a/tools/h2/src/installer/favicon.ico and /dev/null differ diff --git a/tools/h2/src/installer/h2.bat b/tools/h2/src/installer/h2.bat deleted file mode 100755 index 0a7c721..0000000 --- a/tools/h2/src/installer/h2.bat +++ /dev/null @@ -1,2 +0,0 @@ -@java -cp "h2.jar;%H2DRIVERS%;%CLASSPATH%" org.h2.tools.Console %* -@if errorlevel 1 pause \ No newline at end of file diff --git a/tools/h2/src/installer/h2.nsi b/tools/h2/src/installer/h2.nsi deleted file mode 100755 index bc10e04..0000000 --- a/tools/h2/src/installer/h2.nsi +++ /dev/null @@ -1,179 +0,0 @@ - !include "MUI.nsh" - - SetCompressor /SOLID lzma - Name "H2" - Icon "favicon.ico" - OutFile "../../../h2web/h2-setup.exe" - CRCCheck on - - InstallDir "$PROGRAMFILES\H2" - InstallDirRegKey HKCU "Software\H2" "" - RequestExecutionLevel highest - -;-------------------------------- -;Variables - - Var MUI_TEMP - Var STARTMENU_FOLDER - -;-------------------------------- -;Interface Settings - - !define MUI_ABORTWARNING - -;-------------------------------- -;Language Selection Dialog Settings - - ;Remember the installer language - !define MUI_LANGDLL_REGISTRY_ROOT "HKCU" - !define MUI_LANGDLL_REGISTRY_KEY "Software\H2" - !define MUI_LANGDLL_REGISTRY_VALUENAME "Installer Language" - -;-------------------------------- -;Pages - - !insertmacro MUI_PAGE_DIRECTORY - - ;Start Menu Folder Page Configuration - !define MUI_STARTMENUPAGE_REGISTRY_ROOT "HKCU" - !define MUI_STARTMENUPAGE_REGISTRY_KEY "Software\H2" - !define MUI_STARTMENUPAGE_REGISTRY_VALUENAME "Start Menu Folder" - !define MUI_FINISHPAGE_SHOWREADME "$INSTDIR\docs\index.html" - - !insertmacro MUI_PAGE_STARTMENU Application $STARTMENU_FOLDER - !insertmacro MUI_PAGE_INSTFILES - !insertmacro MUI_PAGE_FINISH - - !insertmacro MUI_UNPAGE_CONFIRM - !insertmacro MUI_UNPAGE_INSTFILES - -;-------------------------------- -;Languages - - !insertmacro MUI_LANGUAGE "English" # first language is the default language - !insertmacro MUI_LANGUAGE "German" - !insertmacro MUI_LANGUAGE "Spanish" - !insertmacro MUI_LANGUAGE "French" - !insertmacro MUI_LANGUAGE "SimpChinese" - !insertmacro MUI_LANGUAGE "TradChinese" - !insertmacro MUI_LANGUAGE "Japanese" - !insertmacro MUI_LANGUAGE "Korean" - !insertmacro MUI_LANGUAGE "Italian" - !insertmacro MUI_LANGUAGE "Dutch" - !insertmacro MUI_LANGUAGE "Danish" - !insertmacro MUI_LANGUAGE "Swedish" - !insertmacro MUI_LANGUAGE "Norwegian" - !insertmacro MUI_LANGUAGE "Finnish" - !insertmacro MUI_LANGUAGE "Greek" - !insertmacro MUI_LANGUAGE "Russian" - !insertmacro MUI_LANGUAGE "Portuguese" - !insertmacro MUI_LANGUAGE "PortugueseBR" - !insertmacro MUI_LANGUAGE "Polish" - !insertmacro MUI_LANGUAGE "Ukrainian" - !insertmacro MUI_LANGUAGE "Czech" - !insertmacro MUI_LANGUAGE "Slovak" - !insertmacro MUI_LANGUAGE "Croatian" - !insertmacro MUI_LANGUAGE "Bulgarian" - !insertmacro MUI_LANGUAGE "Hungarian" - !insertmacro MUI_LANGUAGE "Romanian" - !insertmacro MUI_LANGUAGE "Latvian" - !insertmacro MUI_LANGUAGE "Macedonian" - !insertmacro MUI_LANGUAGE "Estonian" - !insertmacro MUI_LANGUAGE "Turkish" - !insertmacro MUI_LANGUAGE "Lithuanian" - !insertmacro MUI_LANGUAGE "Catalan" - !insertmacro MUI_LANGUAGE "Slovenian" - !insertmacro MUI_LANGUAGE "Serbian" - !insertmacro MUI_LANGUAGE "SerbianLatin" - !insertmacro MUI_LANGUAGE "Arabic" - !insertmacro MUI_LANGUAGE "Farsi" - !insertmacro MUI_LANGUAGE "Hebrew" - !insertmacro MUI_LANGUAGE "Indonesian" - !insertmacro MUI_LANGUAGE "Mongolian" - !insertmacro MUI_LANGUAGE "Luxembourgish" - !insertmacro MUI_LANGUAGE "Albanian" - !insertmacro MUI_LANGUAGE "Breton" - !insertmacro MUI_LANGUAGE "Belarusian" - !insertmacro MUI_LANGUAGE "Icelandic" - !insertmacro MUI_LANGUAGE "Malaysian" - !insertmacro MUI_LANGUAGE "Bosnian" - !insertmacro MUI_LANGUAGE "Kurdish" - -;-------------------------------- -;Reserve Files - - ;These files should be inserted before other files in the data block - ;Keep these lines before any File command - ;Only for solid compression (by default, solid compression is enabled for BZIP2 and LZMA) - - !insertmacro MUI_RESERVEFILE_LANGDLL - -;-------------------------------- -;Installer Sections - -Section "All" - - SetOutPath "$INSTDIR\src" - File /r /x CVS /x .cvsignore /x .svn ..\..\src\*.* - SetOutPath "$INSTDIR\bin" - File /x CVS /x .cvsignore ..\..\bin\h2* - SetOutPath "$INSTDIR\docs" - File /r /x CVS /x .cvsignore /x .jar ..\..\docs\*.* - SetOutPath "$INSTDIR\service" - File /r /x CVS /x .cvsignore /x .svn ..\..\service\*.* - SetOutPath "$INSTDIR" - File /r /x CVS /x .cvsignore ..\..\build.bat - File /r /x CVS /x .cvsignore ..\..\build.sh - File /r /x CVS /x .cvsignore ..\..\build.xml - - WriteRegStr HKCU "Software\H2" "" $INSTDIR - WriteRegStr HKCU "Software\Microsoft\Windows\CurrentVersion\Uninstall\H2" "DisplayName" "H2" - WriteRegStr HKCU "Software\Microsoft\Windows\CurrentVersion\Uninstall\H2" "UninstallString" "$INSTDIR\Uninstall.exe" - WriteRegStr HKCU "Software\Microsoft\Windows\CurrentVersion\Uninstall\H2" "InstallLocation" "$INSTDIR" - WriteRegStr HKCU "Software\Microsoft\Windows\CurrentVersion\Uninstall\H2" "DisplayIcon" "$INSTDIR\src\installer\favicon.ico" - WriteRegStr HKCU "Software\Microsoft\Windows\CurrentVersion\Uninstall\H2" "NoModify" "1" - WriteRegStr HKCU "Software\Microsoft\Windows\CurrentVersion\Uninstall\H2" "NoRepair" "1" - - WriteUninstaller "$INSTDIR\Uninstall.exe" - - !insertmacro MUI_STARTMENU_WRITE_BEGIN Application - SetOutPath "$INSTDIR\bin" - CreateDirectory "$SMPROGRAMS\$STARTMENU_FOLDER" - CreateShortCut "$SMPROGRAMS\$STARTMENU_FOLDER\H2 Console.lnk" "cmd" "/c h2w.bat" "$INSTDIR\src\installer\favicon.ico" 0 SW_SHOWMINIMIZED "" "Start the Console" - CreateShortCut "$SMPROGRAMS\$STARTMENU_FOLDER\H2 Console (Command Line).lnk" "cmd" "/c h2.bat" "$INSTDIR\src\installer\favicon.ico" 0 SW_SHOWMINIMIZED "" "Start the Console from command line (using h2.bat)" - CreateShortCut "$SMPROGRAMS\$STARTMENU_FOLDER\H2 Documentation.lnk" "$INSTDIR\docs\index.html" -; CreateShortCut "$SMPROGRAMS\$STARTMENU_FOLDER\Uninstall.lnk" "$INSTDIR\Uninstall.exe" - !insertmacro MUI_STARTMENU_WRITE_END - -SectionEnd - -;-------------------------------- -;Uninstaller Section - -Section "Uninstall" - - SetOutPath "$INSTDIR\.." - RMDir /r "$INSTDIR" - Delete "$INSTDIR\Uninstall.exe" - - !insertmacro MUI_STARTMENU_GETFOLDER Application $MUI_TEMP - - Delete "$SMPROGRAMS\$MUI_TEMP\*.lnk" - - ;Delete empty start menu parent diretories - StrCpy $MUI_TEMP "$SMPROGRAMS\$MUI_TEMP" - - startMenuDeleteLoop: - ClearErrors - RMDir $MUI_TEMP - GetFullPathName $MUI_TEMP "$MUI_TEMP\.." - - IfErrors startMenuDeleteLoopDone - - StrCmp $MUI_TEMP $SMPROGRAMS startMenuDeleteLoopDone startMenuDeleteLoop - startMenuDeleteLoopDone: - - DeleteRegKey HKCU "Software\H2" - DeleteRegKey HKCU "Software\Microsoft\Windows\CurrentVersion\Uninstall\H2" - -SectionEnd diff --git a/tools/h2/src/installer/h2.sh b/tools/h2/src/installer/h2.sh deleted file mode 100755 index d96a9b5..0000000 --- a/tools/h2/src/installer/h2.sh +++ /dev/null @@ -1,10 +0,0 @@ -#!/bin/sh -cp=h2.jar -if [ -n "$H2DRIVERS" ] ; then - cp="$cp:$H2DRIVERS" -fi -if [ -n "$CLASSPATH" ] ; then - cp="$cp:$CLASSPATH" -fi -java -cp "$cp" org.h2.tools.Console $@ - diff --git a/tools/h2/src/installer/h2w.bat b/tools/h2/src/installer/h2w.bat deleted file mode 100755 index c7d8d26..0000000 --- a/tools/h2/src/installer/h2w.bat +++ /dev/null @@ -1,2 +0,0 @@ -@start javaw -cp "h2.jar;%H2DRIVERS%;%CLASSPATH%" org.h2.tools.Console %* -@if errorlevel 1 pause \ No newline at end of file diff --git a/tools/h2/src/installer/openoffice.txt b/tools/h2/src/installer/openoffice.txt deleted file mode 100755 index 238831a..0000000 --- a/tools/h2/src/installer/openoffice.txt +++ /dev/null @@ -1,125 +0,0 @@ -REM ***** BASIC ***** - -Sub Main - H2Pdf -End Sub - -sub H2Pdf - BaseDir = "file:///C:/data/h2database/" - REM BaseDir = "file:///Users/tmueller/data/" - - Url = BaseDir & "h2/docs/html/onePage.html" - dim FileProperties(1) As New com.sun.star.beans.PropertyValue - FileProperties(0).Name = "FilterName" - FileProperties(0).Value = "HTML (StarWriter)" - FileProperties(1).Name = "UpdateDocMode" - FileProperties(1).Value = 3 'full update - document = StarDesktop.loadComponentFromURL(Url, "_blank", 0, FileProperties) - docs = ThisComponent.CurrentController.Frame - dispatcher = createUnoService("com.sun.star.frame.DispatchHelper") - dispatcher.executeDispatch(docs, ".uno:UpdateAll", "", 0, Array()) - StyleFamilies = document.StyleFamilies - - ParagraphStyles = StyleFamilies.getByName("ParagraphStyles") - BodyStyle = ParagraphStyles.getByName("Text body") - BodyStyle.ParaOrphans = 2 - BodyStyle.ParaWidows = 2 - - HeadingStyle = ParagraphStyles.getByName("Heading 1") - HeadingStyle.BreakType = 3 ' Insert Page Break Before - HeadingStyle.ParaKeepTogether = false - - images = document.GraphicObjects - For i = 0 to images.getCount() - 1 - image = images.getByIndex(i) - if image.Size.Width <> image.ActualSize.Width or image.Size.Height <> image.ActualSize.Height then - image.Size.Width = image.ActualSize.Width - image.Size.Height = image.ActualSize.Height - wait 100 - end if - Next - dispatcher.executeDispatch(docs, ".uno:UpdateAll", "", 0, Array()) - - PageStyles = StyleFamilies.getByName("PageStyles") - - Standard = PageStyles.getByName("HTML") - Standard.FooterIsOn = True - - dispatcher.executeDispatch(docs, ".uno:UpdateAll", "", 0, Array()) - - oText = Standard.FooterText - oText.setString("") - PageNumber = document.createInstance("com.sun.star.text.TextField.PageNumber") - PageNumber.NumberingType = 4 ' magic constant: 4=Arabic numbers - PageNumber.SubType = 1 ' magic constant: use current page number - - PageCount = document.createInstance("com.sun.star.text.TextField.PageCount") - PageCount.NumberingType = 4 ' magic constant: 4=Arabic numbers - - FooterCursor = oText.Text.createTextCursor() - oText.insertString(FooterCursor, Chr(09)& Chr(09), False) - oText.insertTextContent(FooterCursor, PageNumber, False) - oText.insertString(FooterCursor, " of ", False) - oText.insertTextContent(FooterCursor, PageCount, False) - - Cursor = document.Text.createTextCursor() - Cursor.gotoStart(false) - Cursor.gotoNextParagraph(false) - Cursor.gotoNextParagraph(false) - - dispatcher.executeDispatch(docs, ".uno:UpdateAll", "", 0, Array()) - - toc = document.createInstance("com.sun.star.text.ContentIndex") - toc.Title= "Table of Contents" - toc.CreateFromOutline = True - toc.Level = 4 - toc.IsProtected = false - document.Text.insertTextContent(Cursor, toc, false) - - Cursor.gotoStart(false) - result = true - while result - result = Cursor.gotoNextParagraph(false) - if Cursor.ParaStyleName = "Heading 1" then - Cursor.BreakType = 4 ' Insert Page Break After - end if - wend - - dim linkStart(0) As New com.sun.star.beans.PropertyValue - dim linkEnd(0) As New com.sun.star.beans.PropertyValue - - For i = 1 To 4 - oLevel = toc.LevelFormat.getByIndex(i) - x = DimArray(5) - x = Array(linkStart, oLevel(0), oLevel(1), oLevel(2), oLevel(3), linkEnd) - old = oLevel(0) - linkStart(0).Name = "TokenType" - linkStart(0).Value = "TokenHyperlinkStart" - linkStart(0).Handle = -1 - linkStart(0).State = com.sun.star.beans.PropertyState.DIRECT_VALUE - linkEnd(0).Name = "TokenType" - linkEnd(0).Value = "TokenHyperlinkEnd" - linkEnd(0).Handle = -1 - linkEnd(0).State = com.sun.star.beans.PropertyState.DIRECT_VALUE - toc.LevelFormat.replaceByIndex(i, x) - next - - dispatcher.executeDispatch(docs, ".uno:UpdateAll", "", 0, Array()) - toc.update() - dispatcher.executeDispatch(docs, ".uno:UpdateAll", "", 0, Array()) - toc.update() - dispatcher.executeDispatch(docs, ".uno:UpdateAll", "", 0, Array()) - - pdfTemp = BaseDir & "h2web/h2temp.pdf" - pdf = BaseDir & "h2web/h2.pdf" - - dim pdfProperties(1) as new com.sun.star.beans.PropertyValue - pdfProperties(0).Name = "FilterName" - pdfProperties(0).Value = "writer_pdf_Export" - document.storeToURL(pdfTemp, pdfProperties()) - - fileAccessService = createUnoService("com.sun.star.ucb.SimpleFileAccess") - fileAccessService.move(pdfTemp, pdf) - - ThisComponent.close(true) -end sub diff --git a/tools/h2/src/installer/pom-template.xml b/tools/h2/src/installer/pom-template.xml deleted file mode 100755 index eabf6d4..0000000 --- a/tools/h2/src/installer/pom-template.xml +++ /dev/null @@ -1,22 +0,0 @@ - - 4.0.0 - com.h2database - h2 - @version@ - jar - H2 Database Engine - http://www.h2database.com - H2 Database Engine - - - The H2 License, Version 1.0 - http://h2database.com/html/license.html - repo - - - - http://h2database.googlecode.com/svn/trunk - - - - \ No newline at end of file diff --git a/tools/h2/src/installer/release.txt b/tools/h2/src/installer/release.txt deleted file mode 100755 index 7b0a975..0000000 --- a/tools/h2/src/installer/release.txt +++ /dev/null @@ -1,22 +0,0 @@ -Update Constants.java - change version and build number -Update changelog.html - add new version, remove oldest -Update newsfeed.sql - add new version, remove oldest -Minor version change: change sourceError.html and source.html -Network protocol change: verify TCP_PROTOCOL_VERSION_* (old clients must be compatible!) -Benchmark: use latest versions of other dbs, change version(s) in performance.html -Run ./buildRelease.sh / buildRelease.bat - -Scan for viruses -Test installer, H2 Console (test new languages) -Check docs, versions and links in main, downloads, build numbers -Check the PDF file size - -Upload to SourceForge -Upload to ftp://h2database.com -Upload to http://code.google.com/p/h2database/downloads/list -svn commit -svn copy: /svn/trunk /svn/tags/version-1.1.x; Version 1.1.x (yyyy-mm-dd) -Newsletter: prepare (always to BCC) -Newsletter: send to h2-database-jp@googlegroups.com; h2-database@googlegroups.com; h2database-news@googlegroups.com; ... -Add to freshmeat -Close bugs: http://code.google.com/p/h2database/issues/list diff --git a/tools/h2/src/main/META-INF/MANIFEST.MF b/tools/h2/src/main/META-INF/MANIFEST.MF deleted file mode 100755 index 32420e5..0000000 --- a/tools/h2/src/main/META-INF/MANIFEST.MF +++ /dev/null @@ -1,15 +0,0 @@ -Manifest-Version: 1.0 -Implementation-Title: ${title} -Implementation-URL: http://www.h2database.com -Implementation-Version: ${version} -Build-Jdk: ${buildJdk} -Created-By: ${createdBy} -${mainClassTag} -Bundle-Activator: org.h2.util.DbDriverActivator -Bundle-ManifestVersion: 2 -Bundle-Name: H2 Database Engine -Bundle-SymbolicName: org.h2 -Bundle-Vendor: H2 Group -Bundle-Version: ${version} -DynamicImport-Package: * -Export-Package: org.h2,org.h2.api,org.h2.fulltext,org.h2.jdbcx,org.h2.tools,org.h2.util diff --git a/tools/h2/src/main/META-INF/services/java.sql.Driver b/tools/h2/src/main/META-INF/services/java.sql.Driver deleted file mode 100755 index 679185a..0000000 --- a/tools/h2/src/main/META-INF/services/java.sql.Driver +++ /dev/null @@ -1 +0,0 @@ -org.h2.Driver \ No newline at end of file diff --git a/tools/h2/src/main/org/h2/Driver.java b/tools/h2/src/main/org/h2/Driver.java deleted file mode 100755 index a2c5e6e..0000000 --- a/tools/h2/src/main/org/h2/Driver.java +++ /dev/null @@ -1,146 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2; - -import java.sql.Connection; -import java.sql.DriverManager; -import java.sql.DriverPropertyInfo; -import java.sql.SQLException; -import java.util.Properties; - -import org.h2.engine.Constants; -import org.h2.jdbc.JdbcConnection; -import org.h2.message.DbException; -import org.h2.message.TraceSystem; - -/** - * The database driver. An application should not use this class directly. The - * only thing the application needs to do is load the driver. This can be done - * using Class.forName. To load the driver and open a database connection, use - * the following code: - * - *
- * Class.forName("org.h2.Driver");
- * Connection conn = DriverManager.getConnection(
- *      "jdbc:h2:˜/test", "sa", "sa");
- * 
- */ -public class Driver implements java.sql.Driver { - - private static final Driver INSTANCE = new Driver(); - private static volatile boolean registered; - - static { - load(); - } - - /** - * Open a database connection. - * This method should not be called by an application. - * Instead, the method DriverManager.getConnection should be used. - * - * @param url the database URL - * @param info the connection properties - * @return the new connection - */ - public Connection connect(String url, Properties info) throws SQLException { - try { - if (info == null) { - info = new Properties(); - } - if (!acceptsURL(url)) { - return null; - } - return new JdbcConnection(url, info); - } catch (Exception e) { - throw DbException.toSQLException(e); - } - } - - /** - * Check if the driver understands this URL. - * This method should not be called by an application. - * - * @param url the database URL - * @return if the driver understands the URL - */ - public boolean acceptsURL(String url) { - return url != null && url.startsWith(Constants.START_URL); - } - - /** - * Get the major version number of the driver. - * This method should not be called by an application. - * - * @return the major version number - */ - public int getMajorVersion() { - return Constants.VERSION_MAJOR; - } - - /** - * Get the minor version number of the driver. - * This method should not be called by an application. - * - * @return the minor version number - */ - public int getMinorVersion() { - return Constants.VERSION_MINOR; - } - - /** - * Get the list of supported properties. - * This method should not be called by an application. - * - * @param url the database URL - * @param info the connection properties - * @return a zero length array - */ - public DriverPropertyInfo[] getPropertyInfo(String url, Properties info) { - return new DriverPropertyInfo[0]; - } - - /** - * Check if this driver is compliant to the JDBC specification. - * This method should not be called by an application. - * - * @return true - */ - public boolean jdbcCompliant() { - return true; - } - - /** - * INTERNAL - */ - public static synchronized Driver load() { - try { - if (!registered) { - registered = true; - DriverManager.registerDriver(INSTANCE); - } - } catch (SQLException e) { - TraceSystem.traceThrowable(e); - } - return INSTANCE; - } - - /** - * INTERNAL - */ - public static synchronized void unload() { - try { - if (registered) { - registered = false; - DriverManager.deregisterDriver(INSTANCE); - } - } catch (SQLException e) { - TraceSystem.traceThrowable(e); - } - } - -} diff --git a/tools/h2/src/main/org/h2/api/AggregateFunction.java b/tools/h2/src/main/org/h2/api/AggregateFunction.java deleted file mode 100755 index 8b7645c..0000000 --- a/tools/h2/src/main/org/h2/api/AggregateFunction.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.api; - -import java.sql.Connection; -import java.sql.SQLException; - -/** - * A user-defined aggregate function needs to implement this interface. - * The class must be public and must have a public non-argument constructor. - */ -public interface AggregateFunction { - - /** - * This method is called when the aggregate function is used. - * A new object is created for each invocation. - * - * @param conn a connection to the database - */ - void init(Connection conn) throws SQLException; - - /** - * This method must return the SQL type of the method, given the SQL type of - * the input data. The method should check here if the number of parameters - * passed is correct, and if not it should throw an exception. - * - * @param inputTypes the SQL type of the parameters - * @return the SQL type of the result - */ - int getType(int[] inputTypes) throws SQLException; - - /** - * This method is called once for each row. - * If the aggregate function is called with multiple parameters, - * those are passed as array. - * - * @param value the value(s) for this row - */ - void add(Object value) throws SQLException; - - /** - * This method returns the computed aggregate value. - * - * @return the aggregated value - */ - Object getResult() throws SQLException; - -} \ No newline at end of file diff --git a/tools/h2/src/main/org/h2/api/DatabaseEventListener.java b/tools/h2/src/main/org/h2/api/DatabaseEventListener.java deleted file mode 100755 index 0cbf089..0000000 --- a/tools/h2/src/main/org/h2/api/DatabaseEventListener.java +++ /dev/null @@ -1,96 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.api; - -import java.sql.SQLException; -import java.util.EventListener; - -/** - * A class that implements this interface can get notified about exceptions - * and other events. A database event listener can be registered when - * connecting to a database. Example database URL: - * jdbc:h2:test;DATABASE_EVENT_LISTENER='com.acme.DbListener' - */ -public interface DatabaseEventListener extends EventListener { - - /** - * This state is used when scanning the database file. - */ - int STATE_SCAN_FILE = 0; - - /** - * This state is used when re-creating an index. - */ - int STATE_CREATE_INDEX = 1; - - /** - * This state is used when re-applying the transaction log or rolling back - * uncommitted transactions. - */ - int STATE_RECOVER = 2; - - /** - * This state is used during the BACKUP command. - */ - int STATE_BACKUP_FILE = 3; - - /** - * This state is used after re-connecting to a database (if auto-reconnect - * is enabled). - */ - int STATE_RECONNECTED = 4; - - /** - * This method is called just after creating the object. - * This is done when opening the database if the listener is specified - * in the database URL, but may be later if the listener is set at - * runtime with the SET SQL statement. - * - * @param url - the database URL - */ - void init(String url); - - /** - * This method is called after the database has been opened. - * It is save to connect to the database and execute statements at this point. - */ - void opened(); - - /** - * This method is called if the disk space is very low. One strategy is to - * inform the user and wait for it to clean up disk space. The database - * should not be accessed from within this method (even to close it). - */ - void diskSpaceIsLow(); - - /** - * This method is called if an exception occurred. - * - * @param e the exception - * @param sql the SQL statement - */ - void exceptionThrown(SQLException e, String sql); - - /** - * This method is called for long running events, such as recovering, - * scanning a file or building an index. - * - * @param state the state - * @param name the object name - * @param x the current position - * @param max the highest value - */ - void setProgress(int state, String name, int x, int max); - - /** - * This method is called before the database is closed normally. It is save - * to connect to the database and execute statements at this point, however - * the connection must be closed before the method returns. - */ - void closingDatabase(); - -} diff --git a/tools/h2/src/main/org/h2/api/TableEngine.java b/tools/h2/src/main/org/h2/api/TableEngine.java deleted file mode 100755 index 8241d54..0000000 --- a/tools/h2/src/main/org/h2/api/TableEngine.java +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.api; - -import org.h2.table.TableBase; -import org.h2.command.ddl.CreateTableData; - -/** - * A class that implements this interface can create custom table - * implementations. - * - * @author Sergi Vladykin - */ -public interface TableEngine { - - /** - * Create new table. - * - * @param data the data to construct the table - * @return the created table - */ - TableBase createTable(CreateTableData data); - -} diff --git a/tools/h2/src/main/org/h2/api/Trigger.java b/tools/h2/src/main/org/h2/api/Trigger.java deleted file mode 100755 index ad8abfc..0000000 --- a/tools/h2/src/main/org/h2/api/Trigger.java +++ /dev/null @@ -1,91 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.api; - -import java.sql.Connection; -import java.sql.SQLException; - -/** - * A class that implements this interface can be used as a trigger. - */ -public interface Trigger { - - /** - * The trigger is called for INSERT statements. - */ - int INSERT = 1; - - /** - * The trigger is called for UPDATE statements. - */ - int UPDATE = 2; - - /** - * The trigger is called for DELETE statements. - */ - int DELETE = 4; - - /** - * The trigger is called for SELECT statements. - */ - int SELECT = 8; - - /** - * This method is called by the database engine once when initializing the - * trigger. It is called when the trigger is created, as well as when the - * database is opened. - * - * @param conn a connection to the database - * @param schemaName the name of the schema - * @param triggerName the name of the trigger used in the CREATE TRIGGER - * statement - * @param tableName the name of the table - * @param before whether the fire method is called before or after the - * operation is performed - * @param type the operation type: INSERT, UPDATE, or DELETE - */ - void init(Connection conn, String schemaName, String triggerName, String tableName, boolean before, int type) - throws SQLException; - - /** - * This method is called for each triggered action. The method is called - * immediately when the operation occurred (before it is committed). A - * transaction rollback will also rollback the operations that were done - * within the trigger, if the operations occurred within the same database. - * If the trigger changes state outside the database, a rollback trigger - * should be used. - *

- * The row arrays contain all columns of the table, in the same order - * as defined in the table. - *

- * - * @param conn a connection to the database - * @param oldRow the old row, or null if no old row is available (for - * INSERT) - * @param newRow the new row, or null if no new row is available (for - * DELETE) - * @throws SQLException if the operation must be undone - */ - void fire(Connection conn, Object[] oldRow, Object[] newRow) throws SQLException; - - /** - * This method is called when the database is closed. - * If the method throws an exception, it will be logged, but - * closing the database will continue. - * - * @throws SQLException - */ - void close() throws SQLException; - - /** - * This method is called when the trigger is dropped. - * - * @throws SQLException - */ - void remove() throws SQLException; - -} diff --git a/tools/h2/src/main/org/h2/api/package.html b/tools/h2/src/main/org/h2/api/package.html deleted file mode 100755 index 53d385d..0000000 --- a/tools/h2/src/main/org/h2/api/package.html +++ /dev/null @@ -1,15 +0,0 @@ - - - - -Javadoc package documentation -

- -Contains interfaces for user-defined extensions, such as triggers and user-defined aggregate functions. - -

\ No newline at end of file diff --git a/tools/h2/src/main/org/h2/bnf/Bnf.java b/tools/h2/src/main/org/h2/bnf/Bnf.java deleted file mode 100755 index 93dad11..0000000 --- a/tools/h2/src/main/org/h2/bnf/Bnf.java +++ /dev/null @@ -1,336 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.bnf; - -import java.io.ByteArrayInputStream; -import java.io.IOException; -import java.io.InputStreamReader; -import java.io.Reader; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.StringTokenizer; -import org.h2.server.web.DbContextRule; -import org.h2.tools.Csv; -import org.h2.util.New; -import org.h2.util.StringUtils; -import org.h2.util.Utils; - -/** - * This class can read a file that is similar to BNF (Backus-Naur form). - * It is made specially to support SQL grammar. - */ -public class Bnf { - - /** - * The rule map. The key is lowercase, and all spaces - * are replaces with underscore. - */ - private final HashMap ruleMap = New.hashMap(); - private String syntax; - private String currentToken; - private String[] tokens; - private char firstChar; - private int index; - private Rule lastRepeat; - private ArrayList statements; - private String currentTopic; - - /** - * Create an instance using the grammar specified in the CSV file. - * - * @param csv if not specified, the help.csv is used - * @return a new instance - */ - public static Bnf getInstance(Reader csv) throws SQLException, IOException { - Bnf bnf = new Bnf(); - if (csv == null) { - byte[] data = Utils.getResource("/org/h2/res/help.csv"); - csv = new InputStreamReader(new ByteArrayInputStream(data)); - } - bnf.parse(csv); - return bnf; - } - - private void addFixedRule(String name, int fixedType) { - Rule rule = new RuleFixed(fixedType); - addRule(name, "Fixed", rule); - } - - private RuleHead addRule(String topic, String section, Rule rule) { - RuleHead head = new RuleHead(section, topic, rule); - String key = StringUtils.toLowerEnglish(topic.trim().replace(' ', '_')); - if (ruleMap.get(key) != null) { - throw new AssertionError("already exists: " + topic); - } - ruleMap.put(key, head); - return head; - } - - private void parse(Reader csv) throws SQLException, IOException { - Rule functions = null; - statements = New.arrayList(); - ResultSet rs = Csv.getInstance().read(csv, null); - for (int id = 0; rs.next(); id++) { - String section = rs.getString("SECTION").trim(); - if (section.startsWith("System")) { - continue; - } - String topic = rs.getString("TOPIC"); - syntax = rs.getString("SYNTAX").trim(); - currentTopic = section; - tokens = tokenize(); - index = 0; - Rule rule = parseRule(); - if (section.startsWith("Command")) { - rule = new RuleList(rule, new RuleElement(";\n\n", currentTopic), false); - } - RuleHead head = addRule(topic, section, rule); - if (section.startsWith("Function")) { - if (functions == null) { - functions = rule; - } else { - functions = new RuleList(rule, functions, true); - } - } else if (section.startsWith("Commands")) { - statements.add(head); - } - } - addRule("@func@", "Function", functions); - addFixedRule("@ymd@", RuleFixed.YMD); - addFixedRule("@hms@", RuleFixed.HMS); - addFixedRule("@nanos@", RuleFixed.NANOS); - addFixedRule("anything_except_single_quote", RuleFixed.ANY_EXCEPT_SINGLE_QUOTE); - addFixedRule("anything_except_double_quote", RuleFixed.ANY_EXCEPT_DOUBLE_QUOTE); - addFixedRule("anything_until_end_of_line", RuleFixed.ANY_UNTIL_EOL); - addFixedRule("anything_until_end_comment", RuleFixed.ANY_UNTIL_END); - addFixedRule("anything_except_two_dollar_signs", RuleFixed.ANY_EXCEPT_2_DOLLAR); - addFixedRule("anything", RuleFixed.ANY_WORD); - addFixedRule("@hex_start@", RuleFixed.HEX_START); - addFixedRule("@concat@", RuleFixed.CONCAT); - addFixedRule("@az_@", RuleFixed.AZ_UNDERSCORE); - addFixedRule("@af@", RuleFixed.AF); - addFixedRule("@digit@", RuleFixed.DIGIT); - addFixedRule("@open_bracket@", RuleFixed.OPEN_BRACKET); - addFixedRule("@close_bracket@", RuleFixed.CLOSE_BRACKET); - } - - /** - * Parse the syntax and let the rule call the visitor. - * - * @param visitor the visitor - * @param s the syntax to parse - */ - public void visit(BnfVisitor visitor, String s) { - this.syntax = s; - tokens = tokenize(); - index = 0; - Rule rule = parseRule(); - rule.setLinks(ruleMap); - rule.accept(visitor); - } - - /** - * Convert convert ruleLink to rule_link. - * - * @param token the token - * @return the rule map key - */ - public static String getRuleMapKey(String token) { - StringBuilder buff = new StringBuilder(); - for (char ch : token.toCharArray()) { - if (Character.isUpperCase(ch)) { - buff.append('_').append(Character.toLowerCase(ch)); - } else { - buff.append(ch); - } - } - return buff.toString(); - } - - /** - * Get the rule head for the given title. - * - * @param title the title - * @return the rule head, or null - */ - public RuleHead getRuleHead(String title) { - return ruleMap.get(title); - } - - private Rule parseRule() { - read(); - return parseOr(); - } - - private Rule parseOr() { - Rule r = parseList(); - if (firstChar == '|') { - read(); - r = new RuleList(r, parseOr(), true); - } - lastRepeat = r; - return r; - } - - private Rule parseList() { - Rule r = parseToken(); - if (firstChar != '|' && firstChar != ']' && firstChar != '}' && firstChar != 0) { - r = new RuleList(r, parseList(), false); - } - lastRepeat = r; - return r; - } - - private Rule parseToken() { - Rule r; - if ((firstChar >= 'A' && firstChar <= 'Z') || (firstChar >= 'a' && firstChar <= 'z')) { - // r = new RuleElement(currentToken+ " syntax:" + syntax); - r = new RuleElement(currentToken, currentTopic); - } else if (firstChar == '[') { - read(); - Rule r2 = parseOr(); - r = new RuleOptional(r2); - if (firstChar != ']') { - throw new AssertionError("expected ], got " + currentToken + " syntax:" + syntax); - } - } else if (firstChar == '{') { - read(); - r = parseOr(); - if (firstChar != '}') { - throw new AssertionError("expected }, got " + currentToken + " syntax:" + syntax); - } - } else if ("@commaDots@".equals(currentToken)) { - r = new RuleList(new RuleElement(",", currentTopic), lastRepeat, false); - r = new RuleRepeat(r, true); - } else if ("@dots@".equals(currentToken)) { - r = new RuleRepeat(lastRepeat, false); - } else { - r = new RuleElement(currentToken, currentTopic); - } - lastRepeat = r; - read(); - return r; - } - - private void read() { - if (index < tokens.length) { - currentToken = tokens[index++]; - firstChar = currentToken.charAt(0); - } else { - currentToken = ""; - firstChar = 0; - } - } - - private String[] tokenize() { - ArrayList list = New.arrayList(); - syntax = StringUtils.replaceAll(syntax, "yyyy-MM-dd", "@ymd@"); - syntax = StringUtils.replaceAll(syntax, "hh:mm:ss", "@hms@"); - syntax = StringUtils.replaceAll(syntax, "nnnnnnnnn", "@nanos@"); - syntax = StringUtils.replaceAll(syntax, "function", "@func@"); - syntax = StringUtils.replaceAll(syntax, "0x", "@hexStart@"); - syntax = StringUtils.replaceAll(syntax, ",...", "@commaDots@"); - syntax = StringUtils.replaceAll(syntax, "...", "@dots@"); - syntax = StringUtils.replaceAll(syntax, "||", "@concat@"); - syntax = StringUtils.replaceAll(syntax, "a-z|_", "@az_@"); - syntax = StringUtils.replaceAll(syntax, "A-Z|_", "@az_@"); - syntax = StringUtils.replaceAll(syntax, "a-f", "@af@"); - syntax = StringUtils.replaceAll(syntax, "A-F", "@af@"); - syntax = StringUtils.replaceAll(syntax, "0-9", "@digit@"); - syntax = StringUtils.replaceAll(syntax, "'['", "@openBracket@"); - syntax = StringUtils.replaceAll(syntax, "']'", "@closeBracket@"); - StringTokenizer tokenizer = getTokenizer(syntax); - while (tokenizer.hasMoreTokens()) { - String s = tokenizer.nextToken(); - // avoid duplicate strings - s = StringUtils.cache(s); - if (s.length() == 1) { - if (" \r\n".indexOf(s.charAt(0)) >= 0) { - continue; - } - } - list.add(s); - } - return list.toArray(new String[list.size()]); - } - - /** - * Get the list of tokens that can follow. - * This is the main autocomplete method. - * The returned map for the query 'S' may look like this: - *
-     * key: 1#SELECT, value: ELECT
-     * key: 1#SET, value: ET
-     * 
- * - * @param query the start of the statement - * @return the map of possible token types / tokens - */ - public HashMap getNextTokenList(String query) { - Sentence sentence = new Sentence(); - sentence.setQuery(query); - for (RuleHead head : statements) { - if (!head.getSection().startsWith("Commands")) { - continue; - } - sentence.start(); - head.getRule().addNextTokenList(sentence); - } - return sentence.getNext(); - } - - /** - * Cross-link all statements with each other. - * This method is called after updating the topics. - */ - public void linkStatements() { - for (RuleHead r : ruleMap.values()) { - r.getRule().setLinks(ruleMap); - } - } - - /** - * Update a topic with a context specific rule. - * This is used for autocomplete support. - * - * @param topic the topic - * @param rule the database context rule - */ - public void updateTopic(String topic, DbContextRule rule) { - topic = StringUtils.toLowerEnglish(topic); - RuleHead head = ruleMap.get(topic); - if (head == null) { - head = new RuleHead("db", topic, rule); - ruleMap.put(topic, head); - statements.add(head); - } else { - head.setRule(rule); - } - } - - /** - * Get the list of possible statements. - * - * @return the list of statements - */ - public ArrayList getStatements() { - return statements; - } - - /** - * Get the tokenizer for the given syntax. - * - * @param s the syntax - * @return the tokenizer - */ - public StringTokenizer getTokenizer(String s) { - return new StringTokenizer(s, " [](){}|.,\r\n<>:-+*/=<\">!'$", true); - } - -} diff --git a/tools/h2/src/main/org/h2/bnf/BnfVisitor.java b/tools/h2/src/main/org/h2/bnf/BnfVisitor.java deleted file mode 100755 index f49390c..0000000 --- a/tools/h2/src/main/org/h2/bnf/BnfVisitor.java +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.bnf; - -import java.util.ArrayList; - -/** - * The visitor interface for BNF rules. - */ -public interface BnfVisitor { - - /** - * Visit a rule element. - * - * @param keyword whether this is a keyword - * @param name the element name - * @param link the linked rule if it's not a keyword - */ - void visitRuleElement(boolean keyword, String name, Rule link); - - /** - * Visit a repeat rule. - * - * @param comma whether the comma is repeated as well - * @param rule the element to repeat - */ - void visitRuleRepeat(boolean comma, Rule rule); - - /** - * Visit a fixed rule. - * - * @param type the type - */ - void visitRuleFixed(int type); - - /** - * Visit a rule list. - * - * @param or true for OR, false for AND - * @param list the rules - */ - void visitRuleList(boolean or, ArrayList list); - - /** - * Visit an optional rule. - * - * @param rule the rule - */ - void visitRuleOptional(Rule rule); - -} diff --git a/tools/h2/src/main/org/h2/bnf/Rule.java b/tools/h2/src/main/org/h2/bnf/Rule.java deleted file mode 100755 index d993048..0000000 --- a/tools/h2/src/main/org/h2/bnf/Rule.java +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.bnf; - -import java.util.HashMap; - -/** - * Represents a BNF rule. - */ -public interface Rule { - - /** - * Get the name of the rule. - * - * @return the name - */ - String name(); - - /** - * Update cross references. - * - * @param ruleMap the reference map - */ - void setLinks(HashMap ruleMap); - - /** - * Add the next possible token for a query. - * Used for autocomplete support. - * - * @param sentence the sentence context - */ - void addNextTokenList(Sentence sentence); - - /** - * Remove a token from a sentence. Used for autocomplete support. - * If there was a match, the query in the sentence is updated - * (the matched token is removed). - * - * @param sentence - * the sentence context - * @return false if not a match or a partial match, true if a full match - */ - boolean matchRemove(Sentence sentence); - - /** - * Call the visit method in the given visitor. - * - * @param visitor the visitor - */ - void accept(BnfVisitor visitor); - -} diff --git a/tools/h2/src/main/org/h2/bnf/RuleElement.java b/tools/h2/src/main/org/h2/bnf/RuleElement.java deleted file mode 100755 index ab44f06..0000000 --- a/tools/h2/src/main/org/h2/bnf/RuleElement.java +++ /dev/null @@ -1,114 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.bnf; - -import java.util.HashMap; - -import org.h2.util.StringUtils; - -/** - * A single terminal rule in a BNF object. - */ -public class RuleElement implements Rule { - - private boolean keyword; - private String name; - private Rule link; - private int type; - - RuleElement(String name, String topic) { - this.name = name; - if (name.length() == 1 || name.equals(StringUtils.toUpperEnglish(name))) { - keyword = true; - } - topic = StringUtils.toLowerEnglish(topic); - this.type = topic.startsWith("function") ? Sentence.FUNCTION : Sentence.KEYWORD; - } - - public String toString() { - return name; - } - - public void accept(BnfVisitor visitor) { - visitor.visitRuleElement(keyword, name, link); - } - - public String name() { - return name; - } - - public void setLinks(HashMap ruleMap) { - if (link != null) { - link.setLinks(ruleMap); - } - if (keyword) { - return; - } - String test = Bnf.getRuleMapKey(name); - for (int i = 0; i < test.length(); i++) { - String t = test.substring(i); - RuleHead r = ruleMap.get(t); - if (r != null) { - link = r.getRule(); - return; - } - } - throw new AssertionError("Unknown " + name + "/" + test); - } - - public boolean matchRemove(Sentence sentence) { - if (sentence.shouldStop()) { - return false; - } - String query = sentence.getQuery(); - if (query.length() == 0) { - return false; - } - if (keyword) { - String up = sentence.getQueryUpper(); - if (up.startsWith(name)) { - query = query.substring(name.length()); - while (!"_".equals(name) && query.length() > 0 && Character.isWhitespace(query.charAt(0))) { - query = query.substring(1); - } - sentence.setQuery(query); - return true; - } - return false; - } - if (!link.matchRemove(sentence)) { - return false; - } - if (name != null && !name.startsWith("@") && (link.name() == null || !link.name().startsWith("@"))) { - query = sentence.getQuery(); - while (query.length() > 0 && Character.isWhitespace(query.charAt(0))) { - query = query.substring(1); - } - sentence.setQuery(query); - } - return true; - } - - public void addNextTokenList(Sentence sentence) { - if (sentence.shouldStop()) { - return; - } - if (keyword) { - String query = sentence.getQuery(); - String q = query.trim(); - String up = sentence.getQueryUpper().trim(); - if (q.length() == 0 || name.startsWith(up)) { - if (q.length() < name.length()) { - sentence.add(name, name.substring(q.length()), type); - } - } - return; - } - link.addNextTokenList(sentence); - } - -} diff --git a/tools/h2/src/main/org/h2/bnf/RuleFixed.java b/tools/h2/src/main/org/h2/bnf/RuleFixed.java deleted file mode 100755 index b6d51c6..0000000 --- a/tools/h2/src/main/org/h2/bnf/RuleFixed.java +++ /dev/null @@ -1,278 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.bnf; - -import java.util.HashMap; - -/** - * Represents a hard coded terminal rule in a BNF object. - */ -public class RuleFixed implements Rule { - public static final int YMD = 0, HMS = 1, NANOS = 2; - public static final int ANY_EXCEPT_SINGLE_QUOTE = 3; - public static final int ANY_EXCEPT_DOUBLE_QUOTE = 4; - public static final int ANY_UNTIL_EOL = 5; - public static final int ANY_UNTIL_END = 6; - public static final int ANY_WORD = 7; - public static final int ANY_EXCEPT_2_DOLLAR = 8; - public static final int HEX_START = 10, CONCAT = 11, AZ_UNDERSCORE = 12, AF = 13, DIGIT = 14; - public static final int OPEN_BRACKET = 15, CLOSE_BRACKET = 16; - - private final int type; - - RuleFixed(int type) { - this.type = type; - } - - public String toString() { - switch(type) { - case YMD: - return "2000-01-01"; - case HMS: - return "12:00"; - case NANOS: - return "0"; - case ANY_UNTIL_EOL: - case ANY_EXCEPT_SINGLE_QUOTE: - case ANY_EXCEPT_DOUBLE_QUOTE: - case ANY_WORD: - case ANY_EXCEPT_2_DOLLAR: - case ANY_UNTIL_END: { - return "XYZ"; - } - case HEX_START: - return "0x"; - case CONCAT: - return "||"; - case AZ_UNDERSCORE: - return "A"; - case AF: - return "F"; - case DIGIT: - return "0"; - case OPEN_BRACKET: - return "["; - case CLOSE_BRACKET: - return "]"; - default: - throw new AssertionError("type="+type); - } - } - - public void accept(BnfVisitor visitor) { - visitor.visitRuleFixed(type); - } - - public String name() { - return "type="+type; - } - - public void setLinks(HashMap ruleMap) { - // nothing to do - } - - public boolean matchRemove(Sentence sentence) { - if (sentence.shouldStop()) { - return false; - } - String query = sentence.getQuery(); - if (query.length() == 0) { - return false; - } - String s = query; - switch(type) { - case YMD: - while (s.length() > 0 && "0123456789- ".indexOf(s.charAt(0)) >= 0) { - s = s.substring(1); - } - break; - case HMS: - while (s.length() > 0 && "0123456789:. ".indexOf(s.charAt(0)) >= 0) { - s = s.substring(1); - } - break; - case NANOS: - while (s.length() > 0 && Character.isDigit(s.charAt(0))) { - s = s.substring(1); - } - break; - case ANY_WORD: - while (s.length() > 0 && Character.isWhitespace(s.charAt(0))) { - s = s.substring(1); - } - break; - case ANY_UNTIL_END: - while (s.length() > 1 && s.startsWith("*/")) { - s = s.substring(1); - } - break; - case ANY_UNTIL_EOL: - while (s.length() > 0 && s.charAt(0) != '\n') { - s = s.substring(1); - } - break; - case ANY_EXCEPT_SINGLE_QUOTE: - while (true) { - while (s.length() > 0 && s.charAt(0) != '\'') { - s = s.substring(1); - } - if (s.startsWith("''")) { - s = s.substring(2); - } else { - break; - } - } - break; - case ANY_EXCEPT_DOUBLE_QUOTE: - while (true) { - while (s.length() > 0 && s.charAt(0) != '\"') { - s = s.substring(1); - } - if (s.startsWith("\"\"")) { - s = s.substring(2); - } else { - break; - } - } - break; - case ANY_EXCEPT_2_DOLLAR: - while (true) { - while (s.length() > 0 && !s.startsWith("$$")) { - s = s.substring(1); - } - break; - } - break; - case HEX_START: - if (s.startsWith("0X") || s.startsWith("0x")) { - s = s.substring(2); - } else if (s.startsWith("0")) { - s = s.substring(1); - } - break; - case CONCAT: - if (s.startsWith("||")) { - s = s.substring(2); - } else if (s.startsWith("|")) { - s = s.substring(1); - } - break; - case AZ_UNDERSCORE: - if (s.length() > 0 && (Character.isLetter(s.charAt(0)) || s.charAt(0) == '_')) { - s = s.substring(1); - } - break; - case AF: - if (s.length() > 0) { - char ch = Character.toUpperCase(s.charAt(0)); - if (ch >= 'A' && ch <= 'F') { - s = s.substring(1); - } - } - break; - case DIGIT: - if (s.length() > 0 && Character.isDigit(s.charAt(0))) { - s = s.substring(1); - } - break; - case OPEN_BRACKET: - s = s.substring(1); - break; - case CLOSE_BRACKET: - s = s.substring(1); - break; - default: - throw new AssertionError("type=" + type); - } - if (s.equals(query)) { - return false; - } - sentence.setQuery(s); - return true; - } - - public void addNextTokenList(Sentence sentence) { - if (sentence.shouldStop()) { - return; - } - String query = sentence.getQuery(); - switch(type) { - case YMD: - if (query.length() == 0) { - sentence.add("2006-01-01", "2006-01-01", Sentence.KEYWORD); - } - break; - case HMS: - if (query.length() == 0) { - sentence.add("12:00:00", "12:00:00", Sentence.KEYWORD); - } - break; - case NANOS: - if (query.length() == 0) { - sentence.add("nanoseconds", "0", Sentence.KEYWORD); - } - break; - case ANY_EXCEPT_SINGLE_QUOTE: - if (query.length() == 0) { - sentence.add("anything", "Hello World", Sentence.KEYWORD); - sentence.add("'", "'", Sentence.KEYWORD); - } - break; - case ANY_EXCEPT_2_DOLLAR: - if (query.length() == 0) { - sentence.add("anything", "Hello World", Sentence.KEYWORD); - sentence.add("'", "'", Sentence.KEYWORD); - } - break; - case ANY_EXCEPT_DOUBLE_QUOTE: - if (query.length() == 0) { - sentence.add("anything", "identifier", Sentence.KEYWORD); - } - break; - case ANY_WORD: - break; - case HEX_START: - if (query.length() == 0) { - sentence.add("0x", "0x", Sentence.KEYWORD); - } else if ("0".equals(query)) { - sentence.add("0x", "x", Sentence.KEYWORD); - } - break; - case CONCAT: - if (query.length() == 0) { - sentence.add("||", "||", Sentence.KEYWORD); - } else if ("|".equals(query)) { - sentence.add("||", "|", Sentence.KEYWORD); - } - break; - case AZ_UNDERSCORE: - if (query.length() == 0) { - sentence.add("character", "A", Sentence.KEYWORD); - } - break; - case AF: - if (query.length() == 0) { - sentence.add("hex character", "0A", Sentence.KEYWORD); - } - break; - case DIGIT: - if (query.length() == 0) { - sentence.add("digit", "1", Sentence.KEYWORD); - } - break; - case OPEN_BRACKET: - sentence.add("[", "[", Sentence.KEYWORD); - break; - case CLOSE_BRACKET: - sentence.add("]", "]", Sentence.KEYWORD); - break; - default: - throw new AssertionError("type="+type); - } - } - -} diff --git a/tools/h2/src/main/org/h2/bnf/RuleHead.java b/tools/h2/src/main/org/h2/bnf/RuleHead.java deleted file mode 100755 index 7b21ed9..0000000 --- a/tools/h2/src/main/org/h2/bnf/RuleHead.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.bnf; - -/** - * Represents the head of a BNF rule. - */ -public class RuleHead { - private final String section; - private final String topic; - private Rule rule; - - RuleHead(String section, String topic, Rule rule) { - this.section = section; - this.topic = topic; - this.rule = rule; - } - - public String getTopic() { - return topic; - } - - public Rule getRule() { - return rule; - } - - void setRule(Rule rule) { - this.rule = rule; - } - - public String getSection() { - return section; - } - -} diff --git a/tools/h2/src/main/org/h2/bnf/RuleList.java b/tools/h2/src/main/org/h2/bnf/RuleList.java deleted file mode 100755 index 4ce384d..0000000 --- a/tools/h2/src/main/org/h2/bnf/RuleList.java +++ /dev/null @@ -1,112 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.bnf; - -import java.util.ArrayList; -import java.util.HashMap; -import org.h2.util.New; -import org.h2.util.StatementBuilder; - -/** - * Represents a sequence of BNF rules, or a list of alternative rules. - */ -public class RuleList implements Rule { - - private boolean or; - private ArrayList list; - private boolean mapSet; - - RuleList(Rule first, Rule next, boolean or) { - list = New.arrayList(); - if (first instanceof RuleList && ((RuleList) first).or == or) { - list.addAll(((RuleList) first).list); - } else { - list.add(first); - } - if (next instanceof RuleList && ((RuleList) next).or == or) { - list.addAll(((RuleList) next).list); - } else { - list.add(next); - } - this.or = or; - } - - public String toString() { - StatementBuilder buff = new StatementBuilder(); - if (or) { - buff.append('{'); - for (Rule r : list) { - buff.appendExceptFirst("|"); - buff.append(r.toString()); - } - buff.append('}'); - } else { - for (Rule r : list) { - buff.appendExceptFirst(" "); - buff.append(r.toString()); - } - } - return buff.toString(); - } - - public void accept(BnfVisitor visitor) { - visitor.visitRuleList(or, list); - } - - public String name() { - return null; - } - - public void setLinks(HashMap ruleMap) { - if (!mapSet) { - for (Rule r : list) { - r.setLinks(ruleMap); - } - mapSet = true; - } - } - - public boolean matchRemove(Sentence sentence) { - String query = sentence.getQuery(); - if (query.length() == 0) { - return false; - } - if (or) { - for (Rule r : list) { - if (r.matchRemove(sentence)) { - return true; - } - } - return false; - } - for (Rule r : list) { - if (!r.matchRemove(sentence)) { - return false; - } - } - return true; - } - - public void addNextTokenList(Sentence sentence) { - String old = sentence.getQuery(); - if (or) { - for (Rule r : list) { - sentence.setQuery(old); - r.addNextTokenList(sentence); - } - } else { - for (Rule r : list) { - r.addNextTokenList(sentence); - if (!r.matchRemove(sentence)) { - break; - } - } - } - sentence.setQuery(old); - } - -} diff --git a/tools/h2/src/main/org/h2/bnf/RuleOptional.java b/tools/h2/src/main/org/h2/bnf/RuleOptional.java deleted file mode 100755 index db23050..0000000 --- a/tools/h2/src/main/org/h2/bnf/RuleOptional.java +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.bnf; - -import java.util.HashMap; - -/** - * Represents an optional BNF rule. - */ -public class RuleOptional implements Rule { - private Rule rule; - private boolean mapSet; - - RuleOptional(Rule rule) { - this.rule = rule; - } - - public String toString() { - return "[" + rule.toString() + "]"; - } - - public void accept(BnfVisitor visitor) { - visitor.visitRuleOptional(rule); - } - - public String name() { - return null; - } - - public void setLinks(HashMap ruleMap) { - if (!mapSet) { - rule.setLinks(ruleMap); - mapSet = true; - } - } - - public boolean matchRemove(Sentence sentence) { - if (sentence.shouldStop()) { - return false; - } - String query = sentence.getQuery(); - if (query.length() == 0) { - return true; - } - if (!rule.matchRemove(sentence)) { - return true; - } - return true; - } - - public void addNextTokenList(Sentence sentence) { - if (sentence.shouldStop()) { - return; - } - rule.addNextTokenList(sentence); - } - -} diff --git a/tools/h2/src/main/org/h2/bnf/RuleRepeat.java b/tools/h2/src/main/org/h2/bnf/RuleRepeat.java deleted file mode 100755 index 29f9937..0000000 --- a/tools/h2/src/main/org/h2/bnf/RuleRepeat.java +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.bnf; - -import java.util.HashMap; - -/** - * Represents a loop in a BNF object. - */ -public class RuleRepeat implements Rule { - - private final Rule rule; - private final boolean comma; - - RuleRepeat(Rule rule, boolean comma) { - this.rule = rule; - this.comma = comma; - } - - public String toString() { - return "..."; - } - - public void accept(BnfVisitor visitor) { - visitor.visitRuleRepeat(comma, rule); - } - - public String name() { - return rule.name(); - } - - public void setLinks(HashMap ruleMap) { - // rule.setLinks(ruleMap); - } - - public boolean matchRemove(Sentence sentence) { - if (sentence.shouldStop()) { - return false; - } - String query = sentence.getQuery(); - if (query.length() == 0) { - return false; - } - while (true) { - if (!rule.matchRemove(sentence)) { - return true; - } - if (sentence.getQuery().length() == 0) { - return true; - } - } - } - - public void addNextTokenList(Sentence sentence) { - if (sentence.shouldStop()) { - return; - } - String old = sentence.getQuery(); - while (true) { - rule.addNextTokenList(sentence); - if (!rule.matchRemove(sentence) || old.equals(sentence.getQuery())) { - break; - } - } - sentence.setQuery(old); - } - -} diff --git a/tools/h2/src/main/org/h2/bnf/Sentence.java b/tools/h2/src/main/org/h2/bnf/Sentence.java deleted file mode 100755 index 1fb14e7..0000000 --- a/tools/h2/src/main/org/h2/bnf/Sentence.java +++ /dev/null @@ -1,220 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.bnf; - -import java.util.HashMap; -import java.util.HashSet; - -import org.h2.server.web.DbSchema; -import org.h2.server.web.DbTableOrView; -import org.h2.util.New; -import org.h2.util.StringUtils; - -/** - * A query context object. It contains the list of table and alias objects. - * Used for autocomplete. - */ -public class Sentence { - - /** - * This token type means the possible choices of the item depend on the context. - * For example the item represents a table name of the current database. - */ - public static final int CONTEXT = 0; - - /** - * The token type for a keyword. - */ - static final int KEYWORD = 1; - - /** - * The token type for a function name. - */ - static final int FUNCTION = 2; - - private static final long MAX_PROCESSING_TIME = 100; - - /** - * The map of next tokens in the form type#tokenName token. - */ - private HashMap next = New.hashMap(); - - /** - * The complete query string. - */ - private String query; - - /** - * The uppercase version of the query string. - */ - private String queryUpper; - - private long stopAt; - private DbSchema lastMatchedSchema; - private DbTableOrView lastMatchedTable; - private DbTableOrView lastTable; - private HashSet tables; - private HashMap aliases; - - /** - * Start the timer to make sure processing doesn't take too long. - */ - void start() { - stopAt = System.currentTimeMillis() + MAX_PROCESSING_TIME; - } - - /** - * Check if it's time to stop processing. - * Processing auto-complete shouldn't take more than a few milliseconds. - * - * @return true if it's time to stop processing - */ - boolean shouldStop() { - return System.currentTimeMillis() > stopAt; - } - - /** - * Add a word to the set of next tokens. - * - * @param n the token name - * @param string an example text - * @param type the token type - */ - public void add(String n, String string, int type) { - next.put(type+"#"+n, string); - } - - /** - * Add an alias name and object - * - * @param alias the alias name - * @param table the alias table - */ - public void addAlias(String alias, DbTableOrView table) { - if (aliases == null) { - aliases = New.hashMap(); - } - aliases.put(alias, table); - } - - /** - * Add a table. - * - * @param table the table - */ - public void addTable(DbTableOrView table) { - lastTable = table; - if (tables == null) { - tables = New.hashSet(); - } - tables.add(table); - } - - /** - * Get the set of tables. - * - * @return the set of tables - */ - public HashSet getTables() { - return tables; - } - - /** - * Get the alias map. - * - * @return the alias map - */ - public HashMap getAliases() { - return aliases; - } - - /** - * Get the last added table. - * - * @return the last table - */ - public DbTableOrView getLastTable() { - return lastTable; - } - - /** - * Get the last matched schema if the last match was a schema. - * - * @return the last schema or null - */ - public DbSchema getLastMatchedSchema() { - return lastMatchedSchema; - } - - /** - * Set the last matched schema if the last match was a schema, - * or null if it was not. - * - * @param schema the last matched schema or null - */ - public void setLastMatchedSchema(DbSchema schema) { - this.lastMatchedSchema = schema; - } - - /** - * Set the last matched table if the last match was a table. - * - * @param table the last matched table or null - */ - public void setLastMatchedTable(DbTableOrView table) { - this.lastMatchedTable = table; - } - - /** - * Get the last matched table if the last match was a table. - * - * @return the last table or null - */ - public DbTableOrView getLastMatchedTable() { - return lastMatchedTable; - } - - /** - * Set the query string. - * - * @param query the query string - */ - public void setQuery(String query) { - if (!StringUtils.equals(this.query, query)) { - this.query = query; - this.queryUpper = StringUtils.toUpperEnglish(query); - } - } - - /** - * Get the query string. - * - * @return the query - */ - public String getQuery() { - return query; - } - - /** - * Get the uppercase version of the query string. - * - * @return the uppercase query - */ - public String getQueryUpper() { - return queryUpper; - } - - /** - * Get the map of next tokens. - * - * @return the next token map - */ - HashMap getNext() { - return next; - } - -} diff --git a/tools/h2/src/main/org/h2/bnf/package.html b/tools/h2/src/main/org/h2/bnf/package.html deleted file mode 100755 index 987d7a1..0000000 --- a/tools/h2/src/main/org/h2/bnf/package.html +++ /dev/null @@ -1,15 +0,0 @@ - - - - -Javadoc package documentation -

- -The implementation of the BNF (Backus-Naur form) parser and tool. - -

\ No newline at end of file diff --git a/tools/h2/src/main/org/h2/command/Command.java b/tools/h2/src/main/org/h2/command/Command.java deleted file mode 100755 index 91436b8..0000000 --- a/tools/h2/src/main/org/h2/command/Command.java +++ /dev/null @@ -1,264 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.command; - -import java.sql.SQLException; -import java.util.ArrayList; -import org.h2.constant.ErrorCode; -import org.h2.engine.Constants; -import org.h2.engine.Database; -import org.h2.engine.Session; -import org.h2.expression.ParameterInterface; -import org.h2.message.DbException; -import org.h2.message.Trace; -import org.h2.message.TraceObject; -import org.h2.result.ResultInterface; - -/** - * Represents a SQL statement. This object is only used on the server side. - */ -public abstract class Command implements CommandInterface { - - /** - * The session. - */ - protected final Session session; - - /** - * The trace module. - */ - protected final Trace trace; - - /** - * The last start time. - */ - protected long startTime; - - /** - * If this query was canceled. - */ - private volatile boolean cancel; - - private final String sql; - - public Command(Parser parser, String sql) { - this.session = parser.getSession(); - this.sql = sql; - trace = session.getDatabase().getTrace(Trace.COMMAND); - } - - /** - * Check if this command is transactional. - * If it is not, then it forces the current transaction to commit. - * - * @return true if it is - */ - public abstract boolean isTransactional(); - - /** - * Check if this command is a query. - * - * @return true if it is - */ - public abstract boolean isQuery(); - - /** - * Get the list of parameters. - * - * @return the list of parameters - */ - public abstract ArrayList< ? extends ParameterInterface> getParameters(); - - /** - * Check if this command is read only. - * - * @return true if it is - */ - public abstract boolean isReadOnly(); - - /** - * Get an empty result set containing the meta data. - * - * @return an empty result set - */ - public abstract ResultInterface queryMeta(); - - /** - * Execute an updating statement, if this is possible. - * - * @return the update count - * @throws SQLException if the command is not an updating statement - */ - public int update() { - throw DbException.get(ErrorCode.METHOD_NOT_ALLOWED_FOR_QUERY); - } - - /** - * Execute a query statement, if this is possible. - * - * @param maxrows the maximum number of rows returned - * @return the local result set - * @throws SQLException if the command is not a query - */ - public ResultInterface query(int maxrows) { - throw DbException.get(ErrorCode.METHOD_ONLY_ALLOWED_FOR_QUERY); - } - - public final ResultInterface getMetaData() { - return queryMeta(); - } - - /** - * Execute a query and return the result. - * This method prepares everything and calls {@link #query(int)} finally. - * - * @param maxrows the maximum number of rows to return - * @param scrollable if the result set must be scrollable (ignored) - * @return the result set - */ - public ResultInterface executeQuery(int maxrows, boolean scrollable) { - startTime = System.currentTimeMillis(); - Database database = session.getDatabase(); - Object sync = database.isMultiThreaded() ? (Object) session : (Object) database; - session.waitIfExclusiveModeEnabled(); - synchronized (sync) { - try { - database.checkPowerOff(); - session.setCurrentCommand(this, startTime); - return query(maxrows); - } catch (DbException e) { - e.addSQL(sql); - database.exceptionThrown(e.getSQLException(), sql); - throw e; - } finally { - stop(); - } - } - } - - /** - * Start the stopwatch. - */ - void start() { - startTime = System.currentTimeMillis(); - } - - /** - * Check if this command has been canceled, and throw an exception if yes. - * - * @throws SQLException if the statement has been canceled - */ - public void checkCanceled() { - if (cancel) { - cancel = false; - throw DbException.get(ErrorCode.STATEMENT_WAS_CANCELED); - } - } - - private void stop() { - session.closeTemporaryResults(); - session.setCurrentCommand(null, 0); - if (!isTransactional()) { - session.commit(true); - } else if (session.getAutoCommit()) { - session.commit(false); - } else if (session.getDatabase().isMultiThreaded()) { - Database db = session.getDatabase(); - if (db != null) { - if (db.getLockMode() == Constants.LOCK_MODE_READ_COMMITTED) { - session.unlockReadLocks(); - } - } - } - if (trace.isInfoEnabled()) { - long time = System.currentTimeMillis() - startTime; - if (time > Constants.SLOW_QUERY_LIMIT_MS) { - trace.info("slow query: " + time); - } - } - } - - public int executeUpdate() { - long start = startTime = System.currentTimeMillis(); - Database database = session.getDatabase(); - Object sync = database.isMultiThreaded() ? (Object) session : (Object) database; - session.waitIfExclusiveModeEnabled(); - boolean callStop = true; - session.getDatabase().beforeWriting(); - synchronized (sync) { - int rollback = session.getLogId(); - session.setCurrentCommand(this, startTime); - try { - while (true) { - database.checkPowerOff(); - try { - return update(); - } catch (DbException e) { - if (e.getErrorCode() == ErrorCode.CONCURRENT_UPDATE_1) { - long now = System.currentTimeMillis(); - if (now - start > session.getLockTimeout()) { - throw DbException.get(ErrorCode.LOCK_TIMEOUT_1, e.getCause(), ""); - } - try { - if (sync == database) { - database.wait(10); - } else { - Thread.sleep(10); - } - } catch (InterruptedException e1) { - // ignore - } - continue; - } - throw e; - } catch (Throwable e) { - throw DbException.convert(e); - } - } - } catch (DbException e) { - e = e.addSQL(sql); - SQLException s = e.getSQLException(); - database.exceptionThrown(s, sql); - database.checkPowerOff(); - if (s.getErrorCode() == ErrorCode.DEADLOCK_1) { - session.rollback(); - } else if (s.getErrorCode() == ErrorCode.OUT_OF_MEMORY) { - // there is a serious problem: - // the transaction may be applied partially - // in this case we need to panic: - // close the database - callStop = false; - session.getDatabase().shutdownImmediately(); - throw e; - } else { - session.rollbackTo(rollback, false); - } - throw e; - } finally { - try { - if (callStop) { - stop(); - } - } finally { - session.getDatabase().afterWriting(); - } - } - } - } - - public void close() { - // nothing to do - } - - public void cancel() { - this.cancel = true; - } - - public String toString() { - return TraceObject.toString(sql, getParameters()); - } -} diff --git a/tools/h2/src/main/org/h2/command/CommandContainer.java b/tools/h2/src/main/org/h2/command/CommandContainer.java deleted file mode 100755 index dcda8ad..0000000 --- a/tools/h2/src/main/org/h2/command/CommandContainer.java +++ /dev/null @@ -1,93 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.command; - -import java.util.ArrayList; -import org.h2.expression.Parameter; -import org.h2.expression.ParameterInterface; -import org.h2.result.ResultInterface; -import org.h2.value.Value; - -/** - * Represents a single SQL statements. - * It wraps a prepared statement. - */ -public class CommandContainer extends Command { - - private Prepared prepared; - - CommandContainer(Parser parser, String sql, Prepared prepared) { - super(parser, sql); - prepared.setCommand(this); - this.prepared = prepared; - } - - public ArrayList< ? extends ParameterInterface> getParameters() { - return prepared.getParameters(); - } - - public boolean isTransactional() { - return prepared.isTransactional(); - } - - public boolean isQuery() { - return prepared.isQuery(); - } - - private void recompileIfRequired() { - if (prepared.needRecompile()) { - // TODO test with 'always recompile' - prepared.setModificationMetaId(0); - String sql = prepared.getSQL(); - ArrayList oldParams = prepared.getParameters(); - Parser parser = new Parser(session); - prepared = parser.parseOnly(sql); - long mod = prepared.getModificationMetaId(); - prepared.setModificationMetaId(0); - ArrayList newParams = prepared.getParameters(); - for (int i = 0; i < newParams.size(); i++) { - Parameter old = oldParams.get(i); - if (old.isValueSet()) { - Value v = old.getValue(session); - Parameter p = newParams.get(i); - p.setValue(v); - } - } - prepared.prepare(); - prepared.setModificationMetaId(mod); - } - } - - public int update() { - recompileIfRequired(); - // TODO query time: should keep lock time separate from running time - start(); - prepared.checkParameters(); - int updateCount = prepared.update(); - prepared.trace(startTime, updateCount); - return updateCount; - } - - public ResultInterface query(int maxrows) { - recompileIfRequired(); - // TODO query time: should keep lock time separate from running time - start(); - prepared.checkParameters(); - ResultInterface result = prepared.query(maxrows); - prepared.trace(startTime, result.getRowCount()); - return result; - } - - public boolean isReadOnly() { - return prepared.isReadOnly(); - } - - public ResultInterface queryMeta() { - return prepared.queryMeta(); - } - -} diff --git a/tools/h2/src/main/org/h2/command/CommandInterface.java b/tools/h2/src/main/org/h2/command/CommandInterface.java deleted file mode 100755 index 52d36cc..0000000 --- a/tools/h2/src/main/org/h2/command/CommandInterface.java +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.command; - -import java.util.ArrayList; -import org.h2.expression.ParameterInterface; -import org.h2.result.ResultInterface; - -/** - * Represents a SQL statement. - */ -public interface CommandInterface { - - /** - * Check if this is a query. - * - * @return true if it is a query - */ - boolean isQuery(); - - /** - * Get the parameters (if any). - * - * @return the parameters - */ - ArrayList< ? extends ParameterInterface> getParameters(); - - /** - * Execute the query. - * - * @param maxRows the maximum number of rows returned - * @param scrollable if the result set must be scrollable - * @return the result - */ - ResultInterface executeQuery(int maxRows, boolean scrollable); - - /** - * Execute the statement - * - * @return the update count - */ - int executeUpdate(); - - /** - * Close the statement. - */ - void close(); - - /** - * Cancel the statement if it is still processing. - */ - void cancel(); - - /** - * Get an empty result set containing the meta data of the result. - * - * @return the empty result - */ - ResultInterface getMetaData(); -} diff --git a/tools/h2/src/main/org/h2/command/CommandList.java b/tools/h2/src/main/org/h2/command/CommandList.java deleted file mode 100755 index 755e9a0..0000000 --- a/tools/h2/src/main/org/h2/command/CommandList.java +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.command; - -import java.util.ArrayList; -import org.h2.expression.ParameterInterface; -import org.h2.result.ResultInterface; - -/** - * Represents a list of SQL statements. - */ -public class CommandList extends Command { - - private final Command command; - private final String remaining; - - public CommandList(Parser parser, String sql, Command c, String remaining) { - super(parser, sql); - this.command = c; - this.remaining = remaining; - } - - public ArrayList< ? extends ParameterInterface> getParameters() { - return command.getParameters(); - } - - private void executeRemaining() { - Command remainingCommand = session.prepareLocal(remaining); - if (remainingCommand.isQuery()) { - remainingCommand.query(0); - } else { - remainingCommand.update(); - } - } - - public int update() { - int updateCount = command.executeUpdate(); - executeRemaining(); - return updateCount; - } - - public ResultInterface query(int maxrows) { - ResultInterface result = command.query(maxrows); - executeRemaining(); - return result; - } - - public boolean isQuery() { - return command.isQuery(); - } - - public boolean isTransactional() { - return true; - } - - public boolean isReadOnly() { - return false; - } - - public ResultInterface queryMeta() { - return command.queryMeta(); - } - -} diff --git a/tools/h2/src/main/org/h2/command/CommandRemote.java b/tools/h2/src/main/org/h2/command/CommandRemote.java deleted file mode 100755 index 5d81258..0000000 --- a/tools/h2/src/main/org/h2/command/CommandRemote.java +++ /dev/null @@ -1,257 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.command; - -import java.io.IOException; -import java.util.ArrayList; -import org.h2.constant.SysProperties; -import org.h2.engine.Constants; -import org.h2.engine.SessionRemote; -import org.h2.expression.ParameterInterface; -import org.h2.expression.ParameterRemote; -import org.h2.message.DbException; -import org.h2.message.Trace; -import org.h2.message.TraceObject; -import org.h2.result.ResultInterface; -import org.h2.result.ResultRemote; -import org.h2.util.New; -import org.h2.value.Transfer; -import org.h2.value.Value; - -/** - * Represents the client-side part of a SQL statement. - * This class is not used in embedded mode. - */ -public class CommandRemote implements CommandInterface { - - private final ArrayList transferList; - private final ArrayList parameters; - private final Trace trace; - private final String sql; - private final int fetchSize; - private SessionRemote session; - private int id; - private boolean isQuery; - private boolean readonly; - private int paramCount; - private int created; - - public CommandRemote(SessionRemote session, ArrayList transferList, String sql, int fetchSize) { - this.transferList = transferList; - trace = session.getTrace(); - this.sql = sql; - parameters = New.arrayList(); - prepare(session, true); - // set session late because prepare might fail - in this case we don't - // need to close the object - this.session = session; - this.fetchSize = fetchSize; - created = session.getLastReconnect(); - } - - private void prepare(SessionRemote s, boolean createParams) { - id = s.getNextId(); - paramCount = 0; - boolean readParams = s.getClientVersion() >= Constants.TCP_PROTOCOL_VERSION; - for (int i = 0, count = 0; i < transferList.size(); i++) { - try { - Transfer transfer = transferList.get(i); - if (readParams && createParams) { - s.traceOperation("SESSION_PREPARE_READ_PARAMS", id); - transfer.writeInt(SessionRemote.SESSION_PREPARE_READ_PARAMS).writeInt(id).writeString(sql); - } else { - s.traceOperation("SESSION_PREPARE", id); - transfer.writeInt(SessionRemote.SESSION_PREPARE).writeInt(id).writeString(sql); - } - s.done(transfer); - isQuery = transfer.readBoolean(); - readonly = transfer.readBoolean(); - paramCount = transfer.readInt(); - if (createParams) { - parameters.clear(); - for (int j = 0; j < paramCount; j++) { - if (readParams) { - ParameterRemote p = new ParameterRemote(j); - p.readMetaData(transfer); - parameters.add(p); - } else { - parameters.add(new ParameterRemote(j)); - } - } - } - } catch (IOException e) { - s.removeServer(e, i--, ++count); - } - } - } - - public boolean isQuery() { - return isQuery; - } - - public ArrayList getParameters() { - return parameters; - } - - private void prepareIfRequired() { - if (session.getLastReconnect() != created) { - // in this case we need to prepare again in every case - id = Integer.MIN_VALUE; - } - session.checkClosed(); - if (id <= session.getCurrentId() - SysProperties.SERVER_CACHED_OBJECTS) { - // object is too old - we need to prepare again - prepare(session, false); - } - } - - public ResultInterface getMetaData() { - synchronized (session) { - if (!isQuery) { - return null; - } - int objectId = session.getNextId(); - ResultRemote result = null; - for (int i = 0, count = 0; i < transferList.size(); i++) { - prepareIfRequired(); - Transfer transfer = transferList.get(i); - try { - session.traceOperation("COMMAND_GET_META_DATA", id); - transfer.writeInt(SessionRemote.COMMAND_GET_META_DATA).writeInt(id).writeInt(objectId); - session.done(transfer); - int columnCount = transfer.readInt(); - result = new ResultRemote(session, transfer, objectId, columnCount, Integer.MAX_VALUE); - break; - } catch (IOException e) { - session.removeServer(e, i--, ++count); - } - } - session.autoCommitIfCluster(); - return result; - } - } - - public ResultInterface executeQuery(int maxRows, boolean scrollable) { - checkParameters(); - synchronized (session) { - int objectId = session.getNextId(); - ResultRemote result = null; - for (int i = 0, count = 0; i < transferList.size(); i++) { - prepareIfRequired(); - Transfer transfer = transferList.get(i); - try { - session.traceOperation("COMMAND_EXECUTE_QUERY", id); - transfer.writeInt(SessionRemote.COMMAND_EXECUTE_QUERY).writeInt(id).writeInt(objectId).writeInt( - maxRows); - int fetch; - if (session.isClustered() || scrollable) { - fetch = Integer.MAX_VALUE; - } else { - fetch = fetchSize; - } - transfer.writeInt(fetch); - sendParameters(transfer); - session.done(transfer); - int columnCount = transfer.readInt(); - if (result != null) { - result.close(); - result = null; - } - result = new ResultRemote(session, transfer, objectId, columnCount, fetch); - if (readonly) { - break; - } - } catch (IOException e) { - session.removeServer(e, i--, ++count); - } - } - session.autoCommitIfCluster(); - session.readSessionState(); - return result; - } - } - - public int executeUpdate() { - checkParameters(); - synchronized (session) { - int updateCount = 0; - boolean autoCommit = false; - for (int i = 0, count = 0; i < transferList.size(); i++) { - prepareIfRequired(); - Transfer transfer = transferList.get(i); - try { - session.traceOperation("COMMAND_EXECUTE_UPDATE", id); - transfer.writeInt(SessionRemote.COMMAND_EXECUTE_UPDATE).writeInt(id); - sendParameters(transfer); - session.done(transfer); - updateCount = transfer.readInt(); - autoCommit = transfer.readBoolean(); - } catch (IOException e) { - session.removeServer(e, i--, ++count); - } - } - session.setAutoCommit(autoCommit); - session.autoCommitIfCluster(); - session.readSessionState(); - return updateCount; - } - } - - private void checkParameters() { - for (ParameterInterface p : parameters) { - p.checkSet(); - } - } - - private void sendParameters(Transfer transfer) throws IOException { - int len = parameters.size(); - transfer.writeInt(len); - for (ParameterInterface p : parameters) { - transfer.writeValue(p.getParamValue()); - } - } - - public void close() { - if (session == null || session.isClosed()) { - return; - } - synchronized (session) { - session.traceOperation("COMMAND_CLOSE", id); - for (Transfer transfer : transferList) { - try { - transfer.writeInt(SessionRemote.COMMAND_CLOSE).writeInt(id); - } catch (IOException e) { - trace.error("close", e); - } - } - } - session = null; - try { - for (ParameterInterface p : parameters) { - Value v = p.getParamValue(); - if (v != null) { - v.close(); - } - } - } catch (DbException e) { - trace.error("close", e); - } - parameters.clear(); - } - - /** - * Cancel this current statement. - */ - public void cancel() { - session.cancelStatement(id); - } - - public String toString() { - return TraceObject.toString(sql, getParameters()); - } - -} diff --git a/tools/h2/src/main/org/h2/command/Parser.java b/tools/h2/src/main/org/h2/command/Parser.java deleted file mode 100755 index 6345b27..0000000 --- a/tools/h2/src/main/org/h2/command/Parser.java +++ /dev/null @@ -1,4959 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.command; - -import java.math.BigDecimal; -import java.math.BigInteger; -import java.text.Collator; -import java.util.ArrayList; -import java.util.HashSet; -import org.h2.api.Trigger; -import org.h2.command.ddl.AlterIndexRename; -import org.h2.command.ddl.AlterTableAddConstraint; -import org.h2.command.ddl.AlterTableAlterColumn; -import org.h2.command.ddl.AlterTableDropConstraint; -import org.h2.command.ddl.AlterTableRename; -import org.h2.command.ddl.AlterTableRenameColumn; -import org.h2.command.ddl.AlterUser; -import org.h2.command.ddl.AlterView; -import org.h2.command.ddl.Analyze; -import org.h2.command.ddl.CreateAggregate; -import org.h2.command.ddl.CreateConstant; -import org.h2.command.ddl.CreateFunctionAlias; -import org.h2.command.ddl.CreateIndex; -import org.h2.command.ddl.CreateLinkedTable; -import org.h2.command.ddl.CreateRole; -import org.h2.command.ddl.CreateSchema; -import org.h2.command.ddl.CreateSequence; -import org.h2.command.ddl.CreateTable; -import org.h2.command.ddl.CreateTableData; -import org.h2.command.ddl.CreateTrigger; -import org.h2.command.ddl.CreateUser; -import org.h2.command.ddl.CreateUserDataType; -import org.h2.command.ddl.CreateView; -import org.h2.command.ddl.DeallocateProcedure; -import org.h2.command.ddl.DropAggregate; -import org.h2.command.ddl.DropConstant; -import org.h2.command.ddl.DropDatabase; -import org.h2.command.ddl.DropFunctionAlias; -import org.h2.command.ddl.DropIndex; -import org.h2.command.ddl.DropRole; -import org.h2.command.ddl.DropSchema; -import org.h2.command.ddl.DropSequence; -import org.h2.command.ddl.DropTable; -import org.h2.command.ddl.DropTrigger; -import org.h2.command.ddl.DropUser; -import org.h2.command.ddl.DropUserDataType; -import org.h2.command.ddl.DropView; -import org.h2.command.ddl.GrantRevoke; -import org.h2.command.ddl.PrepareProcedure; -import org.h2.command.ddl.SetComment; -import org.h2.command.ddl.TruncateTable; -import org.h2.command.dml.AlterSequence; -import org.h2.command.dml.AlterTableSet; -import org.h2.command.dml.BackupCommand; -import org.h2.command.dml.Call; -import org.h2.command.dml.Delete; -import org.h2.command.dml.ExecuteProcedure; -import org.h2.command.dml.Explain; -import org.h2.command.dml.Insert; -import org.h2.command.dml.Merge; -import org.h2.command.dml.NoOperation; -import org.h2.command.dml.Query; -import org.h2.command.dml.RunScriptCommand; -import org.h2.command.dml.ScriptCommand; -import org.h2.command.dml.Select; -import org.h2.command.dml.SelectOrderBy; -import org.h2.command.dml.SelectUnion; -import org.h2.command.dml.Set; -import org.h2.command.dml.SetTypes; -import org.h2.command.dml.TransactionCommand; -import org.h2.command.dml.Update; -import org.h2.constant.ErrorCode; -import org.h2.constant.SysProperties; -import org.h2.constraint.ConstraintReferential; -import org.h2.engine.Constants; -import org.h2.engine.Database; -import org.h2.engine.DbObject; -import org.h2.engine.FunctionAlias; -import org.h2.engine.Procedure; -import org.h2.engine.Right; -import org.h2.engine.Session; -import org.h2.engine.Setting; -import org.h2.engine.User; -import org.h2.engine.UserAggregate; -import org.h2.engine.UserDataType; -import org.h2.expression.Aggregate; -import org.h2.expression.Alias; -import org.h2.expression.CompareLike; -import org.h2.expression.Comparison; -import org.h2.expression.ConditionAndOr; -import org.h2.expression.ConditionExists; -import org.h2.expression.ConditionIn; -import org.h2.expression.ConditionInSelect; -import org.h2.expression.ConditionNot; -import org.h2.expression.Expression; -import org.h2.expression.ExpressionColumn; -import org.h2.expression.ExpressionList; -import org.h2.expression.Function; -import org.h2.expression.FunctionCall; -import org.h2.expression.JavaAggregate; -import org.h2.expression.JavaFunction; -import org.h2.expression.Operation; -import org.h2.expression.Parameter; -import org.h2.expression.Rownum; -import org.h2.expression.SequenceValue; -import org.h2.expression.Subquery; -import org.h2.expression.TableFunction; -import org.h2.expression.ValueExpression; -import org.h2.expression.Variable; -import org.h2.expression.Wildcard; -import org.h2.index.Index; -import org.h2.message.DbException; -import org.h2.result.SortOrder; -import org.h2.schema.Schema; -import org.h2.schema.Sequence; -import org.h2.table.Column; -import org.h2.table.FunctionTable; -import org.h2.table.IndexColumn; -import org.h2.table.RangeTable; -import org.h2.table.Table; -import org.h2.table.TableFilter; -import org.h2.table.TableView; -import org.h2.util.Utils; -import org.h2.util.MathUtils; -import org.h2.util.New; -import org.h2.util.StatementBuilder; -import org.h2.util.StringUtils; -import org.h2.value.CompareMode; -import org.h2.value.DataType; -import org.h2.value.Value; -import org.h2.value.ValueBoolean; -import org.h2.value.ValueBytes; -import org.h2.value.ValueDate; -import org.h2.value.ValueDecimal; -import org.h2.value.ValueInt; -import org.h2.value.ValueLong; -import org.h2.value.ValueString; -import org.h2.value.ValueTime; -import org.h2.value.ValueTimestamp; - -/** - * The parser is used to convert a SQL statement string to an command object. - */ -public class Parser { - - // used during the tokenizer phase - private static final int CHAR_END = 1, CHAR_VALUE = 2, CHAR_QUOTED = 3; - private static final int CHAR_NAME = 4, CHAR_SPECIAL_1 = 5, CHAR_SPECIAL_2 = 6; - private static final int CHAR_STRING = 7, CHAR_DOT = 8, CHAR_DOLLAR_QUOTED_STRING = 9; - - // this are token types - private static final int KEYWORD = 1, IDENTIFIER = 2, PARAMETER = 3, END = 4, VALUE = 5; - private static final int EQUAL = 6, BIGGER_EQUAL = 7, BIGGER = 8; - private static final int SMALLER = 9, SMALLER_EQUAL = 10, NOT_EQUAL = 11, AT = 12; - private static final int MINUS = 13, PLUS = 14, STRING_CONCAT = 15; - private static final int OPEN = 16, CLOSE = 17, NULL = 18, TRUE = 19, FALSE = 20; - private static final int CURRENT_TIMESTAMP = 21, CURRENT_DATE = 22, CURRENT_TIME = 23, ROWNUM = 24; - - private final Database database; - private final Session session; - - private int[] characterTypes; - private int currentTokenType; - private String currentToken; - private boolean currentTokenQuoted; - private Value currentValue; - private String sqlCommand; - private String originalSQL; - private char[] sqlCommandChars; - private int lastParseIndex; - private int parseIndex; - private CreateView createView; - private Prepared currentPrepared; - private Select currentSelect; - private ArrayList parameters; - private String schemaName; - private ArrayList expectedList; - private boolean rightsChecked; - private boolean recompileAlways; - private ArrayList indexedParameterList; - private boolean identifiersToUpper = SysProperties.IDENTIFIERS_TO_UPPER; - - public Parser(Session session) { - database = session.getDatabase(); - this.session = session; - } - - /** - * Parse the statement and prepare it for execution. - * - * @param sql the SQL statement to parse - * @return the prepared object - */ - public Prepared prepare(String sql) { - Prepared p = parse(sql); - p.prepare(); - return p; - } - - /** - * Parse the statement, but don't prepare it for execution. - * - * @param sql the SQL statement to parse - * @return the prepared object - */ - public Prepared parseOnly(String sql) { - return parse(sql); - } - - /** - * Parse a statement or a list of statements, and prepare it for execution. - * - * @param sql the SQL statement to parse - * @return the command object - */ - public Command prepareCommand(String sql) { - try { - Prepared p = parse(sql); - p.prepare(); - Command c = new CommandContainer(this, sql, p); - p.setCommand(c); - if (isToken(";")) { - String remaining = originalSQL.substring(parseIndex); - if (remaining.trim().length() != 0) { - CommandList list = new CommandList(this, sql, c, remaining); - // list.addCommand(c); - // do { - // c = parseCommand(); - // list.addCommand(c); - // } while(currentToken.equals(";")); - c = list; - } - } else if (currentTokenType != END) { - throw getSyntaxError(); - } - return c; - } catch (DbException e) { - throw e.addSQL(originalSQL); - } - } - - private Prepared parse(String sql) { - Prepared p; - try { - // first, try the fast variant - p = parse(sql, false); - } catch (DbException e) { - if (e.getErrorCode() == ErrorCode.SYNTAX_ERROR_1) { - // now, get the detailed exception - p = parse(sql, true); - } else { - throw e.addSQL(sql); - } - } - p.setPrepareAlways(recompileAlways); - p.setParameterList(parameters); - return p; - } - - private Prepared parse(String sql, boolean withExpectedList) { - initialize(sql); - if (withExpectedList) { - expectedList = New.arrayList(); - } else { - expectedList = null; - } - parameters = New.arrayList(); - currentSelect = null; - currentPrepared = null; - createView = null; - recompileAlways = false; - indexedParameterList = null; - read(); - return parsePrepared(); - } - - private Prepared parsePrepared() { - int start = lastParseIndex; - Prepared c = null; - String token = currentToken; - if (token.length() == 0) { - c = new NoOperation(session); - } else { - char first = token.charAt(0); - switch (first) { - case '(': - c = parseSelect(); - break; - case 'a': - case 'A': - if (readIf("ALTER")) { - c = parseAlter(); - } else if (readIf("ANALYZE")) { - c = parseAnalyze(); - } - break; - case 'b': - case 'B': - if (readIf("BACKUP")) { - c = parseBackup(); - } else if (readIf("BEGIN")) { - c = parseBegin(); - } - break; - case 'c': - case 'C': - if (readIf("COMMIT")) { - c = parseCommit(); - } else if (readIf("CREATE")) { - c = parseCreate(); - } else if (readIf("CALL")) { - c = parseCall(); - } else if (readIf("CHECKPOINT")) { - c = parseCheckpoint(); - } else if (readIf("COMMENT")) { - c = parseComment(); - } - break; - case 'd': - case 'D': - if (readIf("DELETE")) { - c = parseDelete(); - } else if (readIf("DROP")) { - c = parseDrop(); - } else if (readIf("DECLARE")) { - // support for DECLARE GLOBAL TEMPORARY TABLE... - c = parseCreate(); - } else if (readIf("DEALLOCATE")) { - c = parseDeallocate(); - } - break; - case 'e': - case 'E': - if (readIf("EXPLAIN")) { - c = parseExplain(); - } else if (readIf("EXECUTE")) { - c = parseExecute(); - } - break; - case 'f': - case 'F': - if (isToken("FROM")) { - c = parseSelect(); - } - break; - case 'g': - case 'G': - if (readIf("GRANT")) { - c = parseGrantRevoke(GrantRevoke.GRANT); - } - break; - case 'h': - case 'H': - if (readIf("HELP")) { - c = parseHelp(); - } - break; - case 'i': - case 'I': - if (readIf("INSERT")) { - c = parseInsert(); - } - break; - case 'm': - case 'M': - if (readIf("MERGE")) { - c = parseMerge(); - } - break; - case 'p': - case 'P': - if (readIf("PREPARE")) { - c = parsePrepare(); - } - break; - case 'r': - case 'R': - if (readIf("ROLLBACK")) { - c = parseRollback(); - } else if (readIf("REVOKE")) { - c = parseGrantRevoke(GrantRevoke.REVOKE); - } else if (readIf("RUNSCRIPT")) { - c = parseRunScript(); - } else if (readIf("RELEASE")) { - c = parseReleaseSavepoint(); - } - break; - case 's': - case 'S': - if (isToken("SELECT")) { - c = parseSelect(); - } else if (readIf("SET")) { - c = parseSet(); - } else if (readIf("SAVEPOINT")) { - c = parseSavepoint(); - } else if (readIf("SCRIPT")) { - c = parseScript(); - } else if (readIf("SHUTDOWN")) { - c = parseShutdown(); - } else if (readIf("SHOW")) { - c = parseShow(); - } - break; - case 't': - case 'T': - if (readIf("TRUNCATE")) { - c = parseTruncate(); - } - break; - case 'u': - case 'U': - if (readIf("UPDATE")) { - c = parseUpdate(); - } - break; - case 'v': - case 'V': - if (readIf("VALUES")) { - c = parseCall(); - } - break; - case 'w': - case 'W': - if (readIf("WITH")) { - c = parserWith(); - } - break; - default: - throw getSyntaxError(); - } - if (indexedParameterList != null) { - for (int i = 0; i < indexedParameterList.size(); i++) { - if (indexedParameterList.get(i) == null) { - indexedParameterList.set(i, new Parameter(i)); - } - } - parameters = indexedParameterList; - } - if (readIf("{")) { - do { - int index = (int) readLong() - 1; - if (index < 0 || index >= parameters.size()) { - throw getSyntaxError(); - } - Parameter p = parameters.get(index); - if (p == null) { - throw getSyntaxError(); - } - read(":"); - Expression expr = readExpression(); - expr = expr.optimize(session); - p.setValue(expr.getValue(session)); - } while (readIf(",")); - read("}"); - for (Parameter p : parameters) { - p.checkSet(); - } - parameters.clear(); - } - } - if (c == null) { - throw getSyntaxError(); - } - setSQL(c, null, start); - return c; - } - - private DbException getSyntaxError() { - if (expectedList == null || expectedList.size() == 0) { - return DbException.getSyntaxError(sqlCommand, parseIndex); - } - StatementBuilder buff = new StatementBuilder(); - for (String e : expectedList) { - buff.appendExceptFirst(", "); - buff.append(e); - } - return DbException.getSyntaxError(sqlCommand, parseIndex, buff.toString()); - } - - private Prepared parseBackup() { - BackupCommand command = new BackupCommand(session); - read("TO"); - command.setFileName(readExpression()); - return command; - } - - private Prepared parseAnalyze() { - Analyze command = new Analyze(session); - if (readIf("SAMPLE_SIZE")) { - command.setTop(getPositiveInt()); - } - return command; - } - - private TransactionCommand parseBegin() { - TransactionCommand command; - if (!readIf("WORK")) { - readIf("TRANSACTION"); - } - command = new TransactionCommand(session, TransactionCommand.BEGIN); - return command; - } - - private TransactionCommand parseCommit() { - TransactionCommand command; - if (readIf("TRANSACTION")) { - command = new TransactionCommand(session, TransactionCommand.COMMIT_TRANSACTION); - command.setTransactionName(readUniqueIdentifier()); - return command; - } - command = new TransactionCommand(session, TransactionCommand.COMMIT); - readIf("WORK"); - return command; - } - - private TransactionCommand parseShutdown() { - int type = TransactionCommand.SHUTDOWN; - if (readIf("IMMEDIATELY")) { - type = TransactionCommand.SHUTDOWN_IMMEDIATELY; - } else if (readIf("COMPACT")) { - type = TransactionCommand.SHUTDOWN_COMPACT; - } else { - readIf("SCRIPT"); - } - return new TransactionCommand(session, type); - } - - private TransactionCommand parseRollback() { - TransactionCommand command; - if (readIf("TRANSACTION")) { - command = new TransactionCommand(session, TransactionCommand.ROLLBACK_TRANSACTION); - command.setTransactionName(readUniqueIdentifier()); - return command; - } - if (readIf("TO")) { - read("SAVEPOINT"); - command = new TransactionCommand(session, TransactionCommand.ROLLBACK_TO_SAVEPOINT); - command.setSavepointName(readUniqueIdentifier()); - } else { - readIf("WORK"); - command = new TransactionCommand(session, TransactionCommand.ROLLBACK); - } - return command; - } - - private Prepared parsePrepare() { - if (readIf("COMMIT")) { - TransactionCommand command = new TransactionCommand(session, TransactionCommand.PREPARE_COMMIT); - command.setTransactionName(readUniqueIdentifier()); - return command; - } - String procedureName = readAliasIdentifier(); - if (readIf("(")) { - ArrayList list = New.arrayList(); - for (int i = 0;; i++) { - Column column = parseColumnForTable("C" + i, true); - list.add(column); - if (readIf(")")) { - break; - } - read(","); - } - } - read("AS"); - Prepared prep = parsePrepared(); - PrepareProcedure command = new PrepareProcedure(session); - command.setProcedureName(procedureName); - command.setPrepared(prep); - return command; - } - - private TransactionCommand parseSavepoint() { - TransactionCommand command = new TransactionCommand(session, TransactionCommand.SAVEPOINT); - command.setSavepointName(readUniqueIdentifier()); - return command; - } - - private Prepared parseReleaseSavepoint() { - Prepared command = new NoOperation(session); - readIf("SAVEPOINT"); - readUniqueIdentifier(); - return command; - } - - private Schema getSchema() { - if (schemaName == null) { - return null; - } - Schema schema = database.findSchema(schemaName); - if (schema == null) { - if (equalsToken("SESSION", schemaName)) { - // for local temporary tables - schema = database.getSchema(session.getCurrentSchemaName()); - } else { - throw DbException.get(ErrorCode.SCHEMA_NOT_FOUND_1, schemaName); - } - } - return schema; - } - - private Column readTableColumn(TableFilter filter) { - String tableAlias = null; - String columnName = readColumnIdentifier(); - if (readIf(".")) { - tableAlias = columnName; - columnName = readColumnIdentifier(); - if (readIf(".")) { - String schema = tableAlias; - tableAlias = columnName; - columnName = readColumnIdentifier(); - if (readIf(".")) { - String catalogName = schema; - schema = tableAlias; - tableAlias = columnName; - columnName = readColumnIdentifier(); - if (!equalsToken(catalogName, database.getShortName())) { - throw DbException.get(ErrorCode.DATABASE_NOT_FOUND_1, catalogName); - } - } - if (!equalsToken(schema, filter.getTable().getSchema().getName())) { - throw DbException.get(ErrorCode.SCHEMA_NOT_FOUND_1, schema); - } - } - if (!equalsToken(tableAlias, filter.getTableAlias())) { - throw DbException.get(ErrorCode.TABLE_OR_VIEW_NOT_FOUND_1, tableAlias); - } - } - return filter.getTable().getColumn(columnName); - } - - private Update parseUpdate() { - Update command = new Update(session); - currentPrepared = command; - int start = lastParseIndex; - TableFilter filter = readSimpleTableFilter(); - command.setTableFilter(filter); - read("SET"); - if (readIf("(")) { - ArrayList columns = New.arrayList(); - do { - Column column = readTableColumn(filter); - columns.add(column); - } while (readIf(",")); - read(")"); - read("="); - Expression expression = readExpression(); - for (int i = 0; i < columns.size(); i++) { - Column column = columns.get(i); - Function f = Function.getFunction(database, "ARRAY_GET"); - f.setParameter(0, expression); - f.setParameter(1, ValueExpression.get(ValueInt.get(i + 1))); - f.doneWithParameters(); - command.setAssignment(column, f); - } - } else { - do { - Column column = readTableColumn(filter); - read("="); - Expression expression; - if (readIf("DEFAULT")) { - expression = ValueExpression.getDefault(); - } else { - expression = readExpression(); - } - command.setAssignment(column, expression); - } while (readIf(",")); - } - if (readIf("WHERE")) { - Expression condition = readExpression(); - command.setCondition(condition); - } - setSQL(command, "UPDATE", start); - return command; - } - - private TableFilter readSimpleTableFilter() { - Table table = readTableOrView(); - String alias = null; - if (readIf("AS")) { - alias = readAliasIdentifier(); - } else if (currentTokenType == IDENTIFIER) { - if (!equalsToken("SET", currentToken)) { - // SET is not a keyword (PostgreSQL supports it as a table name) - alias = readAliasIdentifier(); - } - } - return new TableFilter(session, table, alias, rightsChecked, currentSelect); - } - - private Delete parseDelete() { - Delete command = new Delete(session); - currentPrepared = command; - int start = lastParseIndex; - readIf("FROM"); - TableFilter filter = readSimpleTableFilter(); - command.setTableFilter(filter); - if (readIf("WHERE")) { - Expression condition = readExpression(); - command.setCondition(condition); - } - setSQL(command, "DELETE", start); - return command; - } - - private IndexColumn[] parseIndexColumnList() { - ArrayList columns = New.arrayList(); - do { - IndexColumn column = new IndexColumn(); - column.columnName = readColumnIdentifier(); - columns.add(column); - if (readIf("ASC")) { - // ignore - } else if (readIf("DESC")) { - column.sortType = SortOrder.DESCENDING; - } - if (readIf("NULLS")) { - if (readIf("FIRST")) { - column.sortType |= SortOrder.NULLS_FIRST; - } else { - read("LAST"); - column.sortType |= SortOrder.NULLS_LAST; - } - } - } while (readIf(",")); - read(")"); - return columns.toArray(new IndexColumn[columns.size()]); - } - - private String[] parseColumnList() { - ArrayList columns = New.arrayList(); - do { - String columnName = readColumnIdentifier(); - columns.add(columnName); - } while (readIfMore()); - return columns.toArray(new String[columns.size()]); - } - - private Column[] parseColumnList(Table table) { - ArrayList columns = New.arrayList(); - HashSet set = New.hashSet(); - if (!readIf(")")) { - do { - Column column = table.getColumn(readColumnIdentifier()); - if (!set.add(column)) { - throw DbException.get(ErrorCode.DUPLICATE_COLUMN_NAME_1, column.getSQL()); - } - columns.add(column); - } while (readIfMore()); - } - return columns.toArray(new Column[columns.size()]); - } - - private boolean readIfMore() { - if (readIf(",")) { - return !readIf(")"); - } - read(")"); - return false; - } - - private Prepared parseHelp() { - StringBuilder buff = new StringBuilder("SELECT * FROM INFORMATION_SCHEMA.HELP"); - int i = 0; - ArrayList paramValues = New.arrayList(); - while (currentTokenType != END) { - String s = currentToken; - read(); - if (i == 0) { - buff.append(" WHERE "); - } else { - buff.append(" AND "); - } - i++; - buff.append("UPPER(TOPIC) LIKE ?"); - paramValues.add(ValueString.get("%" + s + "%")); - } - return prepare(session, buff.toString(), paramValues); - } - - private Prepared parseShow() { - ArrayList paramValues = New.arrayList(); - StringBuilder buff = new StringBuilder("SELECT "); - if (readIf("CLIENT_ENCODING")) { - // for PostgreSQL compatibility - buff.append("'UNICODE' AS CLIENT_ENCODING FROM DUAL"); - } else if (readIf("DEFAULT_TRANSACTION_ISOLATION")) { - // for PostgreSQL compatibility - buff.append("'read committed' AS DEFAULT_TRANSACTION_ISOLATION FROM DUAL"); - } else if (readIf("DATESTYLE")) { - // for PostgreSQL compatibility - buff.append("'ISO' AS DATESTYLE FROM DUAL"); - } else if (readIf("SERVER_VERSION")) { - // for PostgreSQL compatibility - buff.append("'8.1.4' AS SERVER_VERSION FROM DUAL"); - } else if (readIf("SERVER_ENCODING")) { - // for PostgreSQL compatibility - buff.append("'UTF8' AS SERVER_ENCODING FROM DUAL"); - } else if (readIf("TABLES")) { - // for MySQL compatibility - String schema = Constants.SCHEMA_MAIN; - if (readIf("FROM")) { - schema = readUniqueIdentifier(); - } - buff.append("TABLE_NAME, TABLE_SCHEMA FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA=? ORDER BY TABLE_NAME"); - paramValues.add(ValueString.get(schema)); - } else if (readIf("COLUMNS")) { - // for MySQL compatibility - read("FROM"); - String tableName = readUniqueIdentifier(); - paramValues.add(ValueString.get(tableName)); - String schema = Constants.SCHEMA_MAIN; - if (readIf("FROM")) { - schema = readUniqueIdentifier(); - } - buff.append("C.COLUMN_NAME FIELD, " + - "C.TYPE_NAME || '(' || C.NUMERIC_PRECISION || ')' TYPE, " + - "C.IS_NULLABLE \"NULL\", " + - "CASE (SELECT MAX(I.INDEX_TYPE_NAME) FROM " + - "INFORMATION_SCHEMA.INDEXES I " + - "WHERE I.TABLE_SCHEMA=C.TABLE_SCHEMA " + - "AND I.TABLE_NAME=C.TABLE_NAME " + - "AND I.COLUMN_NAME=C.COLUMN_NAME)" + - "WHEN 'PRIMARY KEY' THEN 'PRI' " + - "WHEN 'UNIQUE INDEX' THEN 'UNI' ELSE '' END KEY, " + - "IFNULL(COLUMN_DEFAULT, 'NULL') DEFAULT " + - "FROM INFORMATION_SCHEMA.COLUMNS C " + - "WHERE C.TABLE_NAME=? AND C.TABLE_SCHEMA=? " + - "ORDER BY C.ORDINAL_POSITION"); - paramValues.add(ValueString.get(schema)); - } else if (readIf("DATABASES") || readIf("SCHEMAS")) { - // for MySQL compatibility - buff.append("SCHEMA_NAME FROM INFORMATION_SCHEMA.SCHEMATA"); - } - return prepare(session, buff.toString(), paramValues); - } - - private Prepared prepare(Session s, String sql, ArrayList paramValues) { - Prepared prep = s.prepare(sql); - ArrayList params = prep.getParameters(); - for (int i = 0; params != null && i < params.size(); i++) { - Parameter p = params.get(i); - p.setValue(paramValues.get(i)); - } - return prep; - } - - private boolean isSelect() { - int start = lastParseIndex; - while (readIf("(")) { - // need to read ahead, it could be a nested union: - // ((select 1) union (select 1)) - } - boolean select = isToken("SELECT") || isToken("FROM"); - parseIndex = start; - read(); - return select; - } - - private Merge parseMerge() { - Merge command = new Merge(session); - currentPrepared = command; - read("INTO"); - Table table = readTableOrView(); - command.setTable(table); - if (readIf("(")) { - if (isSelect()) { - command.setQuery(parseSelect()); - read(")"); - return command; - } - Column[] columns = parseColumnList(table); - command.setColumns(columns); - } - if (readIf("KEY")) { - read("("); - Column[] keys = parseColumnList(table); - command.setKeys(keys); - } - if (readIf("VALUES")) { - do { - ArrayList values = New.arrayList(); - read("("); - if (!readIf(")")) { - do { - if (readIf("DEFAULT")) { - values.add(null); - } else { - values.add(readExpression()); - } - } while (readIfMore()); - } - command.addRow(values.toArray(new Expression[values.size()])); - } while (readIf(",")); - } else { - command.setQuery(parseSelect()); - } - return command; - } - - private Insert parseInsert() { - Insert command = new Insert(session); - currentPrepared = command; - read("INTO"); - Table table = readTableOrView(); - command.setTable(table); - if (readIf("SORTED")) { - command.setSortedInsertMode(true); - } - if (readIf("(")) { - if (isSelect()) { - command.setQuery(parseSelect()); - read(")"); - return command; - } - Column[] columns = parseColumnList(table); - command.setColumns(columns); - } - if (readIf("DEFAULT")) { - read("VALUES"); - Expression[] expr = { }; - command.addRow(expr); - } else if (readIf("VALUES")) { - read("("); - do { - ArrayList values = New.arrayList(); - if (!readIf(")")) { - do { - if (readIf("DEFAULT")) { - values.add(null); - } else { - values.add(readExpression()); - } - } while (readIfMore()); - } - command.addRow(values.toArray(new Expression[values.size()])); - // the following condition will allow (..),; and (..); - } while (readIf(",") && readIf("(")); - } else { - command.setQuery(parseSelect()); - } - return command; - } - - private TableFilter readTableFilter(boolean fromOuter) { - Table table; - String alias = null; - if (readIf("(")) { - if (isSelect()) { - int start = lastParseIndex; - Query query = parseSelectUnion(); - read(")"); - query = parseSelectUnionExtension(query, start, true); - ArrayList params = New.arrayList(); - for (int i = 0; i < parameters.size(); i++) { - params.add(parameters.get(i)); - } - query.setParameterList(params); - query.init(); - Session s; - if (createView != null) { - s = database.getSystemSession(); - } else { - s = session; - } - alias = session.getNextSystemIdentifier(sqlCommand); - table = TableView.createTempView(s, session.getUser(), alias, query, currentSelect); - } else { - TableFilter top = readTableFilter(fromOuter); - top = readJoin(top, currentSelect, fromOuter); - read(")"); - alias = readFromAlias(null); - if (alias != null) { - top.setAlias(alias); - } - return top; - } - } else { - String tableName = readIdentifierWithSchema(null); - Schema schema = getSchema(); - if (readIf("(")) { - Schema mainSchema = database.getSchema(Constants.SCHEMA_MAIN); - if (equalsToken(tableName, RangeTable.NAME)) { - Expression min = readExpression(); - read(","); - Expression max = readExpression(); - read(")"); - table = new RangeTable(mainSchema, min, max); - } else { - Expression func = readFunction(schema, tableName); - if (!(func instanceof FunctionCall)) { - throw getSyntaxError(); - } - table = new FunctionTable(mainSchema, session, func, (FunctionCall) func); - } - } else if (equalsToken("DUAL", tableName)) { - table = getDualTable(); - } else { - table = readTableOrView(tableName); - } - } - alias = readFromAlias(alias); - return new TableFilter(session, table, alias, rightsChecked, currentSelect); - } - - private String readFromAlias(String alias) { - if (readIf("AS")) { - alias = readAliasIdentifier(); - } else if (currentTokenType == IDENTIFIER) { - // left and right are not keywords (because they are functions as - // well) - if (!isToken("LEFT") && !isToken("RIGHT") && !isToken("FULL")) { - alias = readAliasIdentifier(); - } - } - return alias; - } - - private Prepared parseTruncate() { - read("TABLE"); - Table table = readTableOrView(); - TruncateTable command = new TruncateTable(session); - command.setTable(table); - return command; - } - - private boolean readIfExists(boolean ifExists) { - if (readIf("IF")) { - read("EXISTS"); - ifExists = true; - } - return ifExists; - } - - private Prepared parseComment() { - int type = 0; - read("ON"); - boolean column = false; - if (readIf("TABLE") || readIf("VIEW")) { - type = DbObject.TABLE_OR_VIEW; - } else if (readIf("COLUMN")) { - column = true; - type = DbObject.TABLE_OR_VIEW; - } else if (readIf("CONSTANT")) { - type = DbObject.CONSTANT; - } else if (readIf("CONSTRAINT")) { - type = DbObject.CONSTRAINT; - } else if (readIf("ALIAS")) { - type = DbObject.FUNCTION_ALIAS; - } else if (readIf("INDEX")) { - type = DbObject.INDEX; - } else if (readIf("ROLE")) { - type = DbObject.ROLE; - } else if (readIf("SCHEMA")) { - type = DbObject.SCHEMA; - } else if (readIf("SEQUENCE")) { - type = DbObject.SEQUENCE; - } else if (readIf("TRIGGER")) { - type = DbObject.TRIGGER; - } else if (readIf("USER")) { - type = DbObject.USER; - } else if (readIf("DOMAIN")) { - type = DbObject.USER_DATATYPE; - } else { - throw getSyntaxError(); - } - SetComment command = new SetComment(session); - String objectName = readIdentifierWithSchema(); - if (column) { - String columnName = objectName; - objectName = schemaName; - schemaName = session.getCurrentSchemaName(); - if (readIf(".")) { - schemaName = objectName; - objectName = columnName; - columnName = readUniqueIdentifier(); - } - command.setColumn(true); - command.setColumnName(columnName); - } - command.setSchemaName(schemaName); - command.setObjectName(objectName); - command.setObjectType(type); - read("IS"); - command.setCommentExpression(readExpression()); - return command; - } - - private Prepared parseDrop() { - if (readIf("TABLE")) { - boolean ifExists = readIfExists(false); - String tableName = readIdentifierWithSchema(); - DropTable command = new DropTable(session, getSchema()); - command.setTableName(tableName); - while (readIf(",")) { - tableName = readIdentifierWithSchema(); - DropTable next = new DropTable(session, getSchema()); - next.setTableName(tableName); - command.addNextDropTable(next); - } - ifExists = readIfExists(ifExists); - command.setIfExists(ifExists); - if (readIf("CASCADE")) { - readIf("CONSTRAINTS"); - } - return command; - } else if (readIf("INDEX")) { - boolean ifExists = readIfExists(false); - String indexName = readIdentifierWithSchema(); - DropIndex command = new DropIndex(session, getSchema()); - command.setIndexName(indexName); - ifExists = readIfExists(ifExists); - command.setIfExists(ifExists); - return command; - } else if (readIf("USER")) { - boolean ifExists = readIfExists(false); - DropUser command = new DropUser(session); - command.setUserName(readUniqueIdentifier()); - ifExists = readIfExists(ifExists); - readIf("CASCADE"); - command.setIfExists(ifExists); - return command; - } else if (readIf("SEQUENCE")) { - boolean ifExists = readIfExists(false); - String sequenceName = readIdentifierWithSchema(); - DropSequence command = new DropSequence(session, getSchema()); - command.setSequenceName(sequenceName); - ifExists = readIfExists(ifExists); - command.setIfExists(ifExists); - return command; - } else if (readIf("CONSTANT")) { - boolean ifExists = readIfExists(false); - String constantName = readIdentifierWithSchema(); - DropConstant command = new DropConstant(session, getSchema()); - command.setConstantName(constantName); - ifExists = readIfExists(ifExists); - command.setIfExists(ifExists); - return command; - } else if (readIf("TRIGGER")) { - boolean ifExists = readIfExists(false); - String triggerName = readIdentifierWithSchema(); - DropTrigger command = new DropTrigger(session, getSchema()); - command.setTriggerName(triggerName); - ifExists = readIfExists(ifExists); - command.setIfExists(ifExists); - return command; - } else if (readIf("VIEW")) { - boolean ifExists = readIfExists(false); - String viewName = readIdentifierWithSchema(); - DropView command = new DropView(session, getSchema()); - command.setViewName(viewName); - ifExists = readIfExists(ifExists); - command.setIfExists(ifExists); - return command; - } else if (readIf("ROLE")) { - boolean ifExists = readIfExists(false); - DropRole command = new DropRole(session); - command.setRoleName(readUniqueIdentifier()); - ifExists = readIfExists(ifExists); - command.setIfExists(ifExists); - return command; - } else if (readIf("ALIAS")) { - boolean ifExists = readIfExists(false); - String aliasName = readIdentifierWithSchema(); - DropFunctionAlias command = new DropFunctionAlias(session, getSchema()); - command.setAliasName(aliasName); - ifExists = readIfExists(ifExists); - command.setIfExists(ifExists); - return command; - } else if (readIf("SCHEMA")) { - boolean ifExists = readIfExists(false); - DropSchema command = new DropSchema(session); - command.setSchemaName(readUniqueIdentifier()); - ifExists = readIfExists(ifExists); - command.setIfExists(ifExists); - return command; - } else if (readIf("ALL")) { - read("OBJECTS"); - DropDatabase command = new DropDatabase(session); - command.setDropAllObjects(true); - if (readIf("DELETE")) { - read("FILES"); - command.setDeleteFiles(true); - } - return command; - } else if (readIf("DOMAIN")) { - return parseDropUserDataType(); - } else if (readIf("TYPE")) { - return parseDropUserDataType(); - } else if (readIf("DATATYPE")) { - return parseDropUserDataType(); - } else if (readIf("AGGREGATE")) { - return parseDropAggregate(); - } - throw getSyntaxError(); - } - - private DropUserDataType parseDropUserDataType() { - boolean ifExists = readIfExists(false); - DropUserDataType command = new DropUserDataType(session); - command.setTypeName(readUniqueIdentifier()); - ifExists = readIfExists(ifExists); - command.setIfExists(ifExists); - return command; - } - - private DropAggregate parseDropAggregate() { - boolean ifExists = readIfExists(false); - DropAggregate command = new DropAggregate(session); - command.setName(readUniqueIdentifier()); - ifExists = readIfExists(ifExists); - command.setIfExists(ifExists); - return command; - } - - private TableFilter readJoin(TableFilter top, Select command, boolean fromOuter) { - TableFilter last = top; - while (true) { - if (readIf("RIGHT")) { - readIf("OUTER"); - read("JOIN"); - // the right hand side is the 'inner' table usually - TableFilter newTop = readTableFilter(fromOuter); - newTop = readJoin(newTop, command, true); - Expression on = null; - if (readIf("ON")) { - on = readExpression(); - } - newTop.addJoin(top, true, on); - top = newTop; - last = newTop; - } else if (readIf("LEFT")) { - readIf("OUTER"); - read("JOIN"); - TableFilter join = readTableFilter(true); - top = readJoin(top, command, true); - Expression on = null; - if (readIf("ON")) { - on = readExpression(); - } - top.addJoin(join, true, on); - last = join; - } else if (readIf("FULL")) { - throw this.getSyntaxError(); - } else if (readIf("INNER")) { - read("JOIN"); - TableFilter join = readTableFilter(fromOuter); - top = readJoin(top, command, false); - Expression on = null; - if (readIf("ON")) { - on = readExpression(); - } - top.addJoin(join, fromOuter, on); - last = join; - } else if (readIf("JOIN")) { - TableFilter join = readTableFilter(fromOuter); - top = readJoin(top, command, false); - Expression on = null; - if (readIf("ON")) { - on = readExpression(); - } - top.addJoin(join, fromOuter, on); - last = join; - } else if (readIf("CROSS")) { - read("JOIN"); - TableFilter join = readTableFilter(fromOuter); - top.addJoin(join, fromOuter, null); - last = join; - } else if (readIf("NATURAL")) { - read("JOIN"); - TableFilter join = readTableFilter(fromOuter); - Column[] tableCols = last.getTable().getColumns(); - Column[] joinCols = join.getTable().getColumns(); - String tableSchema = last.getTable().getSchema().getName(); - String joinSchema = join.getTable().getSchema().getName(); - Expression on = null; - for (Column tc : tableCols) { - String tableColumnName = tc.getName(); - for (Column c : joinCols) { - String joinColumnName = c.getName(); - if (equalsToken(tableColumnName, joinColumnName)) { - join.addNaturalJoinColumn(c); - Expression tableExpr = new ExpressionColumn(database, tableSchema, last - .getTableAlias(), tableColumnName); - Expression joinExpr = new ExpressionColumn(database, joinSchema, join - .getTableAlias(), joinColumnName); - Expression equal = new Comparison(session, Comparison.EQUAL, tableExpr, joinExpr); - if (on == null) { - on = equal; - } else { - on = new ConditionAndOr(ConditionAndOr.AND, on, equal); - } - } - } - } - top.addJoin(join, fromOuter, on); - last = join; - } else { - break; - } - } - return top; - } - - private Prepared parseExecute() { - ExecuteProcedure command = new ExecuteProcedure(session); - String procedureName = readAliasIdentifier(); - Procedure p = session.getProcedure(procedureName); - if (p == null) { - throw DbException.get(ErrorCode.FUNCTION_ALIAS_NOT_FOUND_1, procedureName); - } - command.setProcedure(p); - if (readIf("(")) { - for (int i = 0;; i++) { - command.setExpression(i, readExpression()); - if (readIf(")")) { - break; - } - read(","); - } - } - return command; - } - - private DeallocateProcedure parseDeallocate() { - readIf("PLAN"); - String procedureName = readAliasIdentifier(); - DeallocateProcedure command = new DeallocateProcedure(session); - command.setProcedureName(procedureName); - return command; - } - - private Explain parseExplain() { - Explain command = new Explain(session); - if (readIf("ANALYZE")) { - command.setExecuteCommand(true); - } else { - if (readIf("PLAN")) { - readIf("FOR"); - } - } - if (isToken("SELECT") || isToken("FROM") || isToken("(")) { - command.setCommand(parseSelect()); - } else if (readIf("DELETE")) { - command.setCommand(parseDelete()); - } else if (readIf("UPDATE")) { - command.setCommand(parseUpdate()); - } else if (readIf("INSERT")) { - command.setCommand(parseInsert()); - } else if (readIf("MERGE")) { - command.setCommand(parseMerge()); - } else { - throw getSyntaxError(); - } - return command; - } - - private Query parseSelect() { - int paramIndex = parameters.size(); - Query command = parseSelectUnion(); - ArrayList params = New.arrayList(); - for (int i = paramIndex; i < parameters.size(); i++) { - params.add(parameters.get(i)); - } - command.setParameterList(params); - command.init(); - return command; - } - - private Query parseSelectUnion() { - int start = lastParseIndex; - Query command = parseSelectSub(); - return parseSelectUnionExtension(command, start, false); - } - - private Query parseSelectUnionExtension(Query command, int start, boolean unionOnly) { - while (true) { - if (readIf("UNION")) { - SelectUnion union = new SelectUnion(session, command); - if (readIf("ALL")) { - union.setUnionType(SelectUnion.UNION_ALL); - } else { - readIf("DISTINCT"); - union.setUnionType(SelectUnion.UNION); - } - union.setRight(parseSelectSub()); - command = union; - } else if (readIf("MINUS") || readIf("EXCEPT")) { - SelectUnion union = new SelectUnion(session, command); - union.setUnionType(SelectUnion.EXCEPT); - union.setRight(parseSelectSub()); - command = union; - } else if (readIf("INTERSECT")) { - SelectUnion union = new SelectUnion(session, command); - union.setUnionType(SelectUnion.INTERSECT); - union.setRight(parseSelectSub()); - command = union; - } else { - break; - } - } - if (!unionOnly) { - parseEndOfQuery(command); - } - setSQL(command, null, start); - return command; - } - - private void parseEndOfQuery(Query command) { - if (readIf("ORDER")) { - read("BY"); - Select oldSelect = currentSelect; - if (command instanceof Select) { - currentSelect = (Select) command; - } - ArrayList orderList = New.arrayList(); - do { - boolean canBeNumber = true; - if (readIf("=")) { - canBeNumber = false; - } - SelectOrderBy order = new SelectOrderBy(); - Expression expr = readExpression(); - if (canBeNumber && expr instanceof ValueExpression && expr.getType() == Value.INT) { - order.columnIndexExpr = expr; - } else if (expr instanceof Parameter) { - recompileAlways = true; - order.columnIndexExpr = expr; - } else { - order.expression = expr; - } - if (readIf("DESC")) { - order.descending = true; - } else { - readIf("ASC"); - } - if (readIf("NULLS")) { - if (readIf("FIRST")) { - order.nullsFirst = true; - } else { - read("LAST"); - order.nullsLast = true; - } - } - orderList.add(order); - } while (readIf(",")); - command.setOrder(orderList); - currentSelect = oldSelect; - } - if (database.getMode().supportOffsetFetch) { - // make sure aggregate functions will not work here - Select temp = currentSelect; - currentSelect = null; - - // http://sqlpro.developpez.com/SQL2008/ - if (readIf("OFFSET")) { - command.setOffset(readExpression().optimize(session)); - if (!readIf("ROW")) { - read("ROWS"); - } - } - if (readIf("FETCH")) { - read("FIRST"); - if (readIf("ROW")) { - command.setLimit(ValueExpression.get(ValueInt.get(1))); - } else { - Expression limit = readExpression().optimize(session); - command.setLimit(limit); - if (!readIf("ROW")) { - read("ROWS"); - } - } - read("ONLY"); - } - - currentSelect = temp; - } - if (readIf("LIMIT")) { - Select temp = currentSelect; - // make sure aggregate functions will not work here - currentSelect = null; - Expression limit = readExpression().optimize(session); - command.setLimit(limit); - if (readIf("OFFSET")) { - Expression offset = readExpression().optimize(session); - command.setOffset(offset); - } else if (readIf(",")) { - // MySQL: [offset, ] rowcount - Expression offset = limit; - limit = readExpression().optimize(session); - command.setOffset(offset); - command.setLimit(limit); - } - if (readIf("SAMPLE_SIZE")) { - command.setSampleSize(getPositiveInt()); - } - currentSelect = temp; - } - if (readIf("FOR")) { - if (readIf("UPDATE")) { - if (readIf("OF")) { - do { - readIdentifierWithSchema(); - } while (readIf(",")); - } else if (readIf("NOWAIT")) { - // TODO parser: select for update nowait: should not wait - } else if (readIf("WITH")) { - // Hibernate / Derby support - read("RR"); - } - command.setForUpdate(true); - } else if (readIf("READ")) { - read("ONLY"); - if (readIf("WITH")) { - read("RS"); - } - } - } - } - - private Query parseSelectSub() { - if (readIf("(")) { - Query command = parseSelectUnion(); - read(")"); - return command; - } - Select select = parseSelectSimple(); - return select; - } - - private void parseSelectSimpleFromPart(Select command) { - do { - TableFilter filter = readTableFilter(false); - parseJoinTableFilter(filter, command); - } while (readIf(",")); - } - - private void parseJoinTableFilter(TableFilter top, Select command) { - top = readJoin(top, command, top.isJoinOuter()); - command.addTableFilter(top, true); - boolean isOuter = false; - while (true) { - TableFilter join = top.getJoin(); - if (join == null) { - break; - } - isOuter = isOuter | join.isJoinOuter(); - if (isOuter) { - command.addTableFilter(join, false); - } else { - // make flat so the optimizer can work better - Expression on = join.getJoinCondition(); - if (on != null) { - command.addCondition(on); - } - join.removeJoinCondition(); - top.removeJoin(); - command.addTableFilter(join, true); - } - top = join; - } - } - - private void parseSelectSimpleSelectPart(Select command) { - Select temp = currentSelect; - // make sure aggregate functions will not work in TOP and LIMIT - currentSelect = null; - if (readIf("TOP")) { - // can't read more complex expressions here because - // SELECT TOP 1 +? A FROM TEST could mean - // SELECT TOP (1+?) A FROM TEST or - // SELECT TOP 1 (+?) AS A FROM TEST - Expression limit = readTerm().optimize(session); - command.setLimit(limit); - } else if (readIf("LIMIT")) { - Expression offset = readTerm().optimize(session); - command.setOffset(offset); - Expression limit = readTerm().optimize(session); - command.setLimit(limit); - } - currentSelect = temp; - if (readIf("DISTINCT")) { - command.setDistinct(true); - } else { - readIf("ALL"); - } - ArrayList expressions = New.arrayList(); - do { - if (readIf("*")) { - expressions.add(new Wildcard(null, null)); - } else { - Expression expr = readExpression(); - if (readIf("AS") || currentTokenType == IDENTIFIER) { - String alias = readAliasIdentifier(); - expr = new Alias(expr, alias, database.getMode().aliasColumnName); - } - expressions.add(expr); - } - } while (readIf(",")); - command.setExpressions(expressions); - } - - private Select parseSelectSimple() { - boolean fromFirst; - if (readIf("SELECT")) { - fromFirst = false; - } else if (readIf("FROM")) { - fromFirst = true; - } else { - throw getSyntaxError(); - } - Select command = new Select(session); - int start = lastParseIndex; - Select oldSelect = currentSelect; - currentSelect = command; - currentPrepared = command; - if (fromFirst) { - parseSelectSimpleFromPart(command); - read("SELECT"); - parseSelectSimpleSelectPart(command); - } else { - parseSelectSimpleSelectPart(command); - if (!readIf("FROM")) { - // select without FROM: convert to SELECT ... FROM - // SYSTEM_RANGE(1,1) - Table dual = getDualTable(); - TableFilter filter = new TableFilter(session, dual, null, rightsChecked, currentSelect); - command.addTableFilter(filter, true); - } else { - parseSelectSimpleFromPart(command); - } - } - if (readIf("WHERE")) { - Expression condition = readExpression(); - command.addCondition(condition); - } - // the group by is read for the outer select (or not a select) - // so that columns that are not grouped can be used - currentSelect = oldSelect; - if (readIf("GROUP")) { - read("BY"); - command.setGroupQuery(); - ArrayList list = New.arrayList(); - do { - Expression expr = readExpression(); - list.add(expr); - } while (readIf(",")); - command.setGroupBy(list); - } - currentSelect = command; - if (readIf("HAVING")) { - command.setGroupQuery(); - Expression condition = readExpression(); - command.setHaving(condition); - } - command.setParameterList(parameters); - currentSelect = oldSelect; - setSQL(command, "SELECT", start); - return command; - } - - private Table getDualTable() { - Schema main = database.findSchema(Constants.SCHEMA_MAIN); - Expression one = ValueExpression.get(ValueLong.get(1)); - return new RangeTable(main, one, one); - } - - private void setSQL(Prepared command, String start, int startIndex) { - String sql = originalSQL.substring(startIndex, lastParseIndex).trim(); - if (start != null) { - sql = start + " " + sql; - } - command.setSQL(sql); - } - - private Expression readExpression() { - Expression r = readAnd(); - while (readIf("OR")) { - r = new ConditionAndOr(ConditionAndOr.OR, r, readAnd()); - } - return r; - } - - private Expression readAnd() { - Expression r = readCondition(); - while (readIf("AND")) { - r = new ConditionAndOr(ConditionAndOr.AND, r, readCondition()); - } - return r; - } - - private Expression readCondition() { - if (readIf("NOT")) { - return new ConditionNot(readCondition()); - } - if (readIf("EXISTS")) { - read("("); - Query query = parseSelect(); - // can not reduce expression because it might be a union except - // query with distinct - read(")"); - return new ConditionExists(query); - } - Expression r = readConcat(); - while (true) { - // special case: NOT NULL is not part of an expression (as in CREATE - // TABLE TEST(ID INT DEFAULT 0 NOT NULL)) - int backup = parseIndex; - boolean not = false; - if (readIf("NOT")) { - not = true; - if (isToken("NULL")) { - // this really only works for NOT NULL! - parseIndex = backup; - currentToken = "NOT"; - break; - } - } - if (readIf("LIKE")) { - Expression b = readConcat(); - Expression esc = null; - if (readIf("ESCAPE")) { - esc = readConcat(); - } - recompileAlways = true; - r = new CompareLike(database.getCompareMode(), r, b, esc, false); - } else if (readIf("REGEXP")) { - Expression b = readConcat(); - r = new CompareLike(database.getCompareMode(), r, b, null, true); - } else if (readIf("IS")) { - int type; - if (readIf("NOT")) { - type = Comparison.IS_NOT_NULL; - } else { - type = Comparison.IS_NULL; - } - read("NULL"); - r = new Comparison(session, type, r, null); - } else if (readIf("IN")) { - read("("); - if (readIf(")")) { - r = ValueExpression.get(ValueBoolean.get(false)); - } else { - if (isSelect()) { - Query query = parseSelect(); - r = new ConditionInSelect(database, r, query, false, Comparison.EQUAL); - } else { - ArrayList v = New.arrayList(); - Expression last; - do { - last = readExpression(); - v.add(last); - } while (readIf(",")); - if (v.size() == 1 && (last instanceof Subquery)) { - Subquery s = (Subquery) last; - Query q = s.getQuery(); - r = new ConditionInSelect(database, r, q, false, Comparison.EQUAL); - } else { - r = new ConditionIn(database, r, v); - } - } - read(")"); - } - } else if (readIf("BETWEEN")) { - Expression low = readConcat(); - read("AND"); - Expression high = readConcat(); - Expression condLow = new Comparison(session, Comparison.SMALLER_EQUAL, low, r); - Expression condHigh = new Comparison(session, Comparison.BIGGER_EQUAL, high, r); - r = new ConditionAndOr(ConditionAndOr.AND, condLow, condHigh); - } else { - int compareType = getCompareType(currentTokenType); - if (compareType < 0) { - break; - } - read(); - if (readIf("ALL")) { - read("("); - Query query = parseSelect(); - r = new ConditionInSelect(database, r, query, true, compareType); - read(")"); - } else if (readIf("ANY") || readIf("SOME")) { - read("("); - Query query = parseSelect(); - r = new ConditionInSelect(database, r, query, false, compareType); - read(")"); - } else { - Expression right = readConcat(); - if (readIf("(") && readIf("+") && readIf(")")) { - // support for a subset of old-fashioned Oracle outer - // join with (+) - if (r instanceof ExpressionColumn && right instanceof ExpressionColumn) { - ExpressionColumn leftCol = (ExpressionColumn) r; - ExpressionColumn rightCol = (ExpressionColumn) right; - ArrayList filters = currentSelect.getTopFilters(); - for (TableFilter f : filters) { - while (f != null) { - leftCol.mapColumns(f, 0); - rightCol.mapColumns(f, 0); - f = f.getJoin(); - } - } - TableFilter leftFilter = leftCol.getTableFilter(); - TableFilter rightFilter = rightCol.getTableFilter(); - r = new Comparison(session, compareType, r, right); - if (leftFilter != null && rightFilter != null) { - int idx = filters.indexOf(rightFilter); - if (idx >= 0) { - filters.remove(idx); - leftFilter.addJoin(rightFilter, true, r); - } else { - rightFilter.mapAndAddFilter(r); - } - r = ValueExpression.get(ValueBoolean.get(true)); - } - } - } else { - r = new Comparison(session, compareType, r, right); - } - } - } - if (not) { - r = new ConditionNot(r); - } - } - return r; - } - - private Expression readConcat() { - Expression r = readSum(); - while (true) { - if (readIf("||")) { - r = new Operation(Operation.CONCAT, r, readSum()); - } else if (readIf("~")) { - if (readIf("*")) { - Function function = Function.getFunction(database, "CAST"); - function.setDataType(new Column("X", Value.STRING_IGNORECASE)); - function.setParameter(0, r); - r = function; - } - r = new CompareLike(database.getCompareMode(), r, readSum(), null, true); - } else if (readIf("!~")) { - if (readIf("*")) { - Function function = Function.getFunction(database, "CAST"); - function.setDataType(new Column("X", Value.STRING_IGNORECASE)); - function.setParameter(0, r); - r = function; - } - r = new ConditionNot(new CompareLike(database.getCompareMode(), r, readSum(), null, true)); - } else { - return r; - } - } - } - - private Expression readSum() { - Expression r = readFactor(); - while (true) { - if (readIf("+")) { - r = new Operation(Operation.PLUS, r, readFactor()); - } else if (readIf("-")) { - r = new Operation(Operation.MINUS, r, readFactor()); - } else { - return r; - } - } - } - - private Expression readFactor() { - Expression r = readTerm(); - while (true) { - if (readIf("*")) { - r = new Operation(Operation.MULTIPLY, r, readTerm()); - } else if (readIf("/")) { - r = new Operation(Operation.DIVIDE, r, readTerm()); - } else { - return r; - } - } - } - - private Expression readAggregate(int aggregateType) { - if (currentSelect == null) { - throw getSyntaxError(); - } - currentSelect.setGroupQuery(); - Expression r; - if (aggregateType == Aggregate.COUNT) { - if (readIf("*")) { - r = new Aggregate(Aggregate.COUNT_ALL, null, currentSelect, false); - } else { - boolean distinct = readIf("DISTINCT"); - Expression on = readExpression(); - if (on instanceof Wildcard && !distinct) { - // PostgreSQL compatibility: count(t.*) - r = new Aggregate(Aggregate.COUNT_ALL, null, currentSelect, false); - } else { - r = new Aggregate(Aggregate.COUNT, on, currentSelect, distinct); - } - } - } else if (aggregateType == Aggregate.GROUP_CONCAT) { - boolean distinct = readIf("DISTINCT"); - Aggregate agg = new Aggregate(Aggregate.GROUP_CONCAT, readExpression(), currentSelect, distinct); - if (readIf("ORDER")) { - read("BY"); - agg.setOrder(parseSimpleOrderList()); - } - if (readIf("SEPARATOR")) { - agg.setSeparator(readExpression()); - } - r = agg; - } else { - boolean distinct = readIf("DISTINCT"); - r = new Aggregate(aggregateType, readExpression(), currentSelect, distinct); - } - read(")"); - return r; - } - - private ArrayList parseSimpleOrderList() { - ArrayList orderList = New.arrayList(); - do { - SelectOrderBy order = new SelectOrderBy(); - Expression expr = readExpression(); - order.expression = expr; - if (readIf("DESC")) { - order.descending = true; - } else { - readIf("ASC"); - } - orderList.add(order); - } while (readIf(",")); - return orderList; - } - - private JavaFunction readJavaFunction(Schema schema, String functionName) { - FunctionAlias functionAlias = null; - if (schema != null) { - functionAlias = schema.findFunction(functionName); - } else { - functionAlias = findFunctionAlias(session.getCurrentSchemaName(), functionName); - } - if (functionAlias == null) { - throw DbException.get(ErrorCode.FUNCTION_NOT_FOUND_1, functionName); - } - Expression[] args; - ArrayList argList = New.arrayList(); - int numArgs = 0; - while (!readIf(")")) { - if (numArgs++ > 0) { - read(","); - } - argList.add(readExpression()); - } - args = new Expression[numArgs]; - argList.toArray(args); - JavaFunction func = new JavaFunction(functionAlias, args); - return func; - } - - private JavaAggregate readJavaAggregate(UserAggregate aggregate) { - ArrayList params = New.arrayList(); - do { - params.add(readExpression()); - } while(readIf(",")); - read(")"); - Expression[] list = new Expression[params.size()]; - params.toArray(list); - JavaAggregate agg = new JavaAggregate(aggregate, list, currentSelect); - currentSelect.setGroupQuery(); - return agg; - } - - private Expression readFunction(Schema schema, String name) { - if (schema != null) { - return readJavaFunction(schema, name); - } - int agg = Aggregate.getAggregateType(name); - if (agg >= 0) { - return readAggregate(agg); - } - Function function = Function.getFunction(database, name); - if (function == null) { - UserAggregate aggregate = database.findAggregate(name); - if (aggregate != null) { - return readJavaAggregate(aggregate); - } - return readJavaFunction(null, name); - } - switch (function.getFunctionType()) { - case Function.CAST: { - function.setParameter(0, readExpression()); - read("AS"); - Column type = parseColumn(null); - function.setDataType(type); - read(")"); - break; - } - case Function.CONVERT: { - function.setParameter(0, readExpression()); - read(","); - Column type = parseColumn(null); - function.setDataType(type); - read(")"); - break; - } - case Function.EXTRACT: { - function.setParameter(0, ValueExpression.get(ValueString.get(currentToken))); - read(); - read("FROM"); - function.setParameter(1, readExpression()); - read(")"); - break; - } - case Function.DATE_DIFF: { - if (Function.isDatePart(currentToken)) { - function.setParameter(0, ValueExpression.get(ValueString.get(currentToken))); - read(); - } else { - function.setParameter(0, readExpression()); - } - read(","); - function.setParameter(1, readExpression()); - read(","); - function.setParameter(2, readExpression()); - read(")"); - break; - } - case Function.SUBSTRING: { - function.setParameter(0, readExpression()); - if (!readIf(",")) { - read("FROM"); - } - function.setParameter(1, readExpression()); - if (readIf("FOR") || readIf(",")) { - function.setParameter(2, readExpression()); - } - read(")"); - break; - } - case Function.POSITION: { - // can't read expression because IN would be read too early - function.setParameter(0, readConcat()); - if (!readIf(",")) { - read("IN"); - } - function.setParameter(1, readExpression()); - read(")"); - break; - } - case Function.TRIM: { - Expression space = null; - if (readIf("LEADING")) { - function = Function.getFunction(database, "LTRIM"); - if (!readIf("FROM")) { - space = readExpression(); - read("FROM"); - } - } else if (readIf("TRAILING")) { - function = Function.getFunction(database, "RTRIM"); - if (!readIf("FROM")) { - space = readExpression(); - read("FROM"); - } - } else if (readIf("BOTH")) { - if (!readIf("FROM")) { - space = readExpression(); - read("FROM"); - } - } - Expression p0 = readExpression(); - if (readIf(",")) { - space = readExpression(); - } else if (readIf("FROM")) { - space = p0; - p0 = readExpression(); - } - function.setParameter(0, p0); - if (space != null) { - function.setParameter(1, space); - } - read(")"); - break; - } - case Function.TABLE: - case Function.TABLE_DISTINCT: { - int i = 0; - ArrayList columns = New.arrayList(); - do { - String columnName = readAliasIdentifier(); - Column column = parseColumn(columnName); - columns.add(column); - read("="); - function.setParameter(i, readExpression()); - i++; - } while (readIf(",")); - read(")"); - TableFunction tf = (TableFunction) function; - tf.setColumns(columns); - break; - } - default: - if (!readIf(")")) { - int i = 0; - do { - function.setParameter(i++, readExpression()); - } while (readIf(",")); - read(")"); - } - } - function.doneWithParameters(); - return function; - } - - private Function readFunctionWithoutParameters(String name) { - if (readIf("(")) { - read(")"); - } - Function function = Function.getFunction(database, name); - function.doneWithParameters(); - return function; - } - - private Expression readWildcardOrSequenceValue(String schema, String objectName) { - if (readIf("*")) { - return new Wildcard(schema, objectName); - } - if (schema == null) { - schema = session.getCurrentSchemaName(); - } - if (readIf("NEXTVAL")) { - Sequence sequence = findSequence(schema, objectName); - if (sequence != null) { - return new SequenceValue(sequence); - } - } else if (readIf("CURRVAL")) { - Sequence sequence = findSequence(schema, objectName); - if (sequence != null) { - Function function = Function.getFunction(database, "CURRVAL"); - function.setParameter(0, ValueExpression.get(ValueString.get(sequence.getSchema().getName()))); - function.setParameter(1, ValueExpression.get(ValueString.get(sequence.getName()))); - function.doneWithParameters(); - return function; - } - } - return null; - } - - private Expression readTermObjectDot(String objectName) { - Expression expr = readWildcardOrSequenceValue(null, objectName); - if (expr != null) { - return expr; - } - String name = readColumnIdentifier(); - Schema s = database.findSchema(objectName); - if (s != null && readIf("(")) { - // only if the token before the dot is a valid schema name, - // otherwise the old style Oracle outer join doesn't work: - // t.x = t2.x(+) - return readFunction(s, name); - } else if (readIf(".")) { - String schema = objectName; - objectName = name; - expr = readWildcardOrSequenceValue(schema, objectName); - if (expr != null) { - return expr; - } - name = readColumnIdentifier(); - if (readIf("(")) { - String databaseName = schema; - if (!equalsToken(database.getShortName(), databaseName)) { - throw DbException.get(ErrorCode.DATABASE_NOT_FOUND_1, databaseName); - } - schema = objectName; - objectName = name; - return readFunction(database.getSchema(schema), name); - } else if (readIf(".")) { - String databaseName = schema; - if (!equalsToken(database.getShortName(), databaseName)) { - throw DbException.get(ErrorCode.DATABASE_NOT_FOUND_1, databaseName); - } - schema = objectName; - objectName = name; - expr = readWildcardOrSequenceValue(schema, objectName); - if (expr != null) { - return expr; - } - name = readColumnIdentifier(); - return new ExpressionColumn(database, schema, objectName, name); - } - return new ExpressionColumn(database, schema, objectName, name); - } - return new ExpressionColumn(database, null, objectName, name); - } - - private Expression readTerm() { - Expression r; - switch (currentTokenType) { - case AT: - read(); - r = new Variable(session, readAliasIdentifier()); - if (readIf(":=")) { - Expression value = readExpression(); - Function function = Function.getFunction(database, "SET"); - function.setParameter(0, r); - function.setParameter(1, value); - r = function; - } - break; - case PARAMETER: - // there must be no space between ? and the number - boolean indexed = Character.isDigit(sqlCommandChars[parseIndex]); - read(); - Parameter p; - if (indexed && currentTokenType == VALUE && currentValue.getType() == Value.INT) { - if (indexedParameterList == null) { - if (parameters == null) { - // this can occur when parsing expressions only (for example check constraints) - throw getSyntaxError(); - } else if (parameters.size() > 0) { - throw DbException.get(ErrorCode.CANNOT_MIX_INDEXED_AND_UNINDEXED_PARAMS); - } - indexedParameterList = New.arrayList(); - } - int index = currentValue.getInt() - 1; - if (index < 0 || index >= Constants.MAX_PARAMETER_INDEX) { - throw DbException.getInvalidValueException("" + index, "Parameter Index"); - } - if (indexedParameterList.size() <= index) { - indexedParameterList.ensureCapacity(index + 1); - while (indexedParameterList.size() <= index) { - indexedParameterList.add(null); - } - } - p = indexedParameterList.get(index); - if (p == null) { - p = new Parameter(index); - indexedParameterList.set(index, p); - } - read(); - } else { - if (indexedParameterList != null) { - throw DbException.get(ErrorCode.CANNOT_MIX_INDEXED_AND_UNINDEXED_PARAMS); - } - p = new Parameter(parameters.size()); - } - parameters.add(p); - r = p; - break; - case KEYWORD: - if (isToken("SELECT") || isToken("FROM")) { - Query query = parseSelect(); - r = new Subquery(query); - } else { - throw getSyntaxError(); - } - break; - case IDENTIFIER: - String name = currentToken; - if (currentTokenQuoted) { - read(); - if (readIf("(")) { - r = readFunction(null, name); - } else if (readIf(".")) { - r = readTermObjectDot(name); - } else { - r = new ExpressionColumn(database, null, null, name); - } - } else { - read(); - if (equalsToken("X", name) && currentTokenType == VALUE && currentValue.getType() == Value.STRING) { - read(); - byte[] buffer = Utils.convertStringToBytes(currentValue.getString()); - r = ValueExpression.get(ValueBytes.getNoCopy(buffer)); - } else if (readIf(".")) { - r = readTermObjectDot(name); - } else if (equalsToken("CASE", name)) { - // CASE must be processed before (, - // otherwise CASE(3) would be a function call, which it is - // not - if (isToken("WHEN")) { - r = readWhen(null); - } else { - Expression left = readExpression(); - r = readWhen(left); - } - } else if (readIf("(")) { - r = readFunction(null, name); - } else if (equalsToken("CURRENT_USER", name)) { - r = readFunctionWithoutParameters("USER"); - } else if (equalsToken("CURRENT", name)) { - if (readIf("TIMESTAMP")) { - r = readFunctionWithoutParameters("CURRENT_TIMESTAMP"); - } else if (readIf("TIME")) { - r = readFunctionWithoutParameters("CURRENT_TIME"); - } else if (readIf("DATE")) { - r = readFunctionWithoutParameters("CURRENT_DATE"); - } else { - r = new ExpressionColumn(database, null, null, name); - } - } else if (equalsToken("NEXT", name) && readIf("VALUE")) { - read("FOR"); - Sequence sequence = readSequence(); - r = new SequenceValue(sequence); - } else if (equalsToken("DATE", name) && currentTokenType == VALUE && currentValue.getType() == Value.STRING) { - String date = currentValue.getString(); - read(); - r = ValueExpression.get(ValueDate.get(ValueDate.parseDate(date))); - } else if (equalsToken("TIME", name) && currentTokenType == VALUE && currentValue.getType() == Value.STRING) { - String time = currentValue.getString(); - read(); - r = ValueExpression.get(ValueTime.get(ValueTime.parseTime(time))); - } else if (equalsToken("TIMESTAMP", name) && currentTokenType == VALUE - && currentValue.getType() == Value.STRING) { - String timestamp = currentValue.getString(); - read(); - r = ValueExpression.get(ValueTimestamp.getNoCopy(ValueTimestamp.parseTimestamp(timestamp))); - } else if (equalsToken("E", name) && currentTokenType == VALUE && currentValue.getType() == Value.STRING) { - String text = currentValue.getString(); - read(); - r = ValueExpression.get(ValueString.get(text)); - } else { - r = new ExpressionColumn(database, null, null, name); - } - } - break; - case MINUS: - read(); - if (currentTokenType == VALUE) { - r = ValueExpression.get(currentValue.negate()); - if (r.getType() == Value.LONG && r.getValue(session).getLong() == Integer.MIN_VALUE) { - // convert Integer.MIN_VALUE to type 'int' - // (Integer.MAX_VALUE+1 is of type 'long') - r = ValueExpression.get(ValueInt.get(Integer.MIN_VALUE)); - } else if (r.getType() == Value.DECIMAL && r.getValue(session).getBigDecimal().compareTo(ValueLong.MIN_BD) == 0) { - // convert Long.MIN_VALUE to type 'long' - // (Long.MAX_VALUE+1 is of type 'decimal') - r = ValueExpression.get(ValueLong.get(Long.MIN_VALUE)); - } - read(); - } else { - r = new Operation(Operation.NEGATE, readTerm(), null); - } - break; - case PLUS: - read(); - r = readTerm(); - break; - case OPEN: - read(); - r = readExpression(); - if (readIf(",")) { - ArrayList list = New.arrayList(); - list.add(r); - do { - r = readExpression(); - list.add(r); - } while (readIf(",")); - Expression[] array = new Expression[list.size()]; - list.toArray(array); - r = new ExpressionList(array); - } - read(")"); - break; - case TRUE: - read(); - r = ValueExpression.get(ValueBoolean.get(true)); - break; - case FALSE: - read(); - r = ValueExpression.get(ValueBoolean.get(false)); - break; - case CURRENT_TIME: - read(); - r = readFunctionWithoutParameters("CURRENT_TIME"); - break; - case CURRENT_DATE: - read(); - r = readFunctionWithoutParameters("CURRENT_DATE"); - break; - case CURRENT_TIMESTAMP: { - Function function = Function.getFunction(database, "CURRENT_TIMESTAMP"); - read(); - if (readIf("(")) { - if (!readIf(")")) { - function.setParameter(0, readExpression()); - read(")"); - } - } - function.doneWithParameters(); - r = function; - break; - } - case ROWNUM: - read(); - if (readIf("(")) { - read(")"); - } - r = new Rownum(currentSelect == null ? currentPrepared : currentSelect); - break; - case NULL: - read(); - r = ValueExpression.getNull(); - break; - case VALUE: - r = ValueExpression.get(currentValue); - read(); - break; - default: - throw getSyntaxError(); - } - if (readIf("[")) { - Function function = Function.getFunction(database, "ARRAY_GET"); - function.setParameter(0, r); - r = readExpression(); - r = new Operation(Operation.PLUS, r, ValueExpression.get(ValueInt.get(1))); - function.setParameter(1, r); - r = function; - read("]"); - } - if (readIf("::")) { - // PostgreSQL compatibility - Column col = parseColumn(null); - Function function = Function.getFunction(database, "CAST"); - function.setDataType(col); - function.setParameter(0, r); - r = function; - } - return r; - } - - private Expression readWhen(Expression left) { - if (readIf("END")) { - readIf("CASE"); - return ValueExpression.getNull(); - } - if (readIf("ELSE")) { - Expression elsePart = readExpression(); - read("END"); - readIf("CASE"); - return elsePart; - } - readIf("WHEN"); - Expression when = readExpression(); - if (left != null) { - when = new Comparison(session, Comparison.EQUAL, left, when); - } - read("THEN"); - Expression then = readExpression(); - Expression elsePart = readWhen(left); - Function function = Function.getFunction(session.getDatabase(), "CASEWHEN"); - function.setParameter(0, when); - function.setParameter(1, then); - function.setParameter(2, elsePart); - function.doneWithParameters(); - return function; - } - - private int getPositiveInt() { - int v = getInt(); - if (v < 0) { - throw DbException.getInvalidValueException("" + v, "positive integer"); - } - return v; - } - - private int getInt() { - boolean minus = false; - if (currentTokenType == MINUS) { - minus = true; - read(); - } else if (currentTokenType == PLUS) { - read(); - } - if (currentTokenType != VALUE || currentValue.getType() != Value.INT) { - throw DbException.getSyntaxError(sqlCommand, parseIndex, "integer"); - } - int i = currentValue.getInt(); - read(); - return minus ? -i : i; - } - - private long readLong() { - boolean minus = false; - if (currentTokenType == MINUS) { - minus = true; - read(); - } - if (currentTokenType != VALUE - || (currentValue.getType() != Value.INT && currentValue.getType() != Value.LONG)) { - throw DbException.getSyntaxError(sqlCommand, parseIndex, "long"); - } - long i = currentValue.getLong(); - read(); - return minus ? -i : i; - } - - private boolean readBooleanSetting() { - if (currentTokenType == VALUE) { - boolean result = currentValue.getBoolean().booleanValue(); - read(); - return result; - } - if (readIf("TRUE") || readIf("ON")) { - return true; - } else if (readIf("FALSE") || readIf("OFF")) { - return false; - } else { - throw getSyntaxError(); - } - } - - private String readString() { - Expression expr = readExpression().optimize(session); - if (!(expr instanceof ValueExpression)) { - throw DbException.getSyntaxError(sqlCommand, parseIndex, "string"); - } - String s = expr.getValue(session).getString(); - return s; - } - - private String readIdentifierWithSchema(String defaultSchemaName) { - if (currentTokenType != IDENTIFIER) { - throw DbException.getSyntaxError(sqlCommand, parseIndex, "identifier"); - } - String s = currentToken; - read(); - schemaName = defaultSchemaName; - if (readIf(".")) { - schemaName = s; - if (currentTokenType != IDENTIFIER) { - throw DbException.getSyntaxError(sqlCommand, parseIndex, "identifier"); - } - s = currentToken; - read(); - } - if (equalsToken(".", currentToken)) { - if (equalsToken(schemaName, database.getShortName())) { - read("."); - schemaName = s; - if (currentTokenType != IDENTIFIER) { - throw DbException.getSyntaxError(sqlCommand, parseIndex, "identifier"); - } - s = currentToken; - read(); - } - } - return s; - } - - private String readIdentifierWithSchema() { - return readIdentifierWithSchema(session.getCurrentSchemaName()); - } - - private String readAliasIdentifier() { - return readColumnIdentifier(); - } - - private String readUniqueIdentifier() { - return readColumnIdentifier(); - } - - private String readColumnIdentifier() { - if (currentTokenType != IDENTIFIER) { - throw DbException.getSyntaxError(sqlCommand, parseIndex, "identifier"); - } - String s = currentToken; - read(); - return s; - } - - private void read(String expected) { - if (currentTokenQuoted || !equalsToken(expected, currentToken)) { - throw DbException.getSyntaxError(sqlCommand, parseIndex, expected); - } - read(); - } - - private boolean readIf(String token) { - if (!currentTokenQuoted && equalsToken(token, currentToken)) { - read(); - return true; - } - addExpected(token); - return false; - } - - private boolean isToken(String token) { - boolean result = equalsToken(token, currentToken) && !currentTokenQuoted; - if (result) { - return true; - } - addExpected(token); - return false; - } - - private boolean equalsToken(String a, String b) { - if (a.equals(b)) { - return true; - } - if (!identifiersToUpper && a.equalsIgnoreCase(b)) { - return true; - } - return false; - } - - private void addExpected(String token) { - if (expectedList != null) { - expectedList.add(token); - } - } - - private void read() { - currentTokenQuoted = false; - if (expectedList != null) { - expectedList.clear(); - } - int[] types = characterTypes; - lastParseIndex = parseIndex; - int i = parseIndex; - int type = types[i]; - while (type == 0) { - type = types[++i]; - } - int start = i; - char[] chars = sqlCommandChars; - char c = chars[i++]; - currentToken = ""; - switch (type) { - case CHAR_NAME: - while (true) { - type = types[i]; - if (type != CHAR_NAME && type != CHAR_VALUE) { - break; - } - i++; - } - currentToken = StringUtils.fromCacheOrNew(sqlCommand.substring(start, i)); - currentTokenType = getTokenType(currentToken); - parseIndex = i; - return; - case CHAR_QUOTED: { - String result = null; - while (true) { - for (int begin = i;; i++) { - if (chars[i] == '\"') { - if (result == null) { - result = sqlCommand.substring(begin, i); - } else { - result += sqlCommand.substring(begin - 1, i); - } - break; - } - } - if (chars[++i] != '\"') { - break; - } - i++; - } - currentToken = StringUtils.fromCacheOrNew(result); - parseIndex = i; - currentTokenQuoted = true; - currentTokenType = IDENTIFIER; - return; - } - case CHAR_SPECIAL_2: - if (types[i] == CHAR_SPECIAL_2) { - i++; - } - currentToken = sqlCommand.substring(start, i); - currentTokenType = getSpecialType(currentToken); - parseIndex = i; - return; - case CHAR_SPECIAL_1: - currentToken = sqlCommand.substring(start, i); - currentTokenType = getSpecialType(currentToken); - parseIndex = i; - return; - case CHAR_VALUE: - if (c == '0' && chars[i] == 'X') { - // hex number - long number = 0; - start += 2; - i++; - while (true) { - c = chars[i]; - if ((c < '0' || c > '9') && (c < 'A' || c > 'F')) { - checkLiterals(false); - currentValue = ValueInt.get((int) number); - currentTokenType = VALUE; - currentToken = "0"; - parseIndex = i; - return; - } - number = (number << 4) + c - (c >= 'A' ? ('A' - 0xa) : ('0')); - if (number > Integer.MAX_VALUE) { - readHexDecimal(start, i); - return; - } - i++; - } - } - long number = c - '0'; - while (true) { - c = chars[i]; - if (c < '0' || c > '9') { - if (c == '.') { - readDecimal(start, i); - break; - } - if (c == 'E') { - readDecimal(start, i); - break; - } - checkLiterals(false); - currentValue = ValueInt.get((int) number); - currentTokenType = VALUE; - currentToken = "0"; - parseIndex = i; - break; - } - number = number * 10 + (c - '0'); - if (number > Integer.MAX_VALUE) { - readDecimal(start, i); - break; - } - i++; - } - return; - case CHAR_DOT: - if (types[i] != CHAR_VALUE) { - currentTokenType = KEYWORD; - currentToken = "."; - parseIndex = i; - return; - } - readDecimal(i - 1, i); - return; - case CHAR_STRING: { - String result = null; - while (true) { - for (int begin = i;; i++) { - if (chars[i] == '\'') { - if (result == null) { - result = sqlCommand.substring(begin, i); - } else { - result += sqlCommand.substring(begin - 1, i); - } - break; - } - } - if (chars[++i] != '\'') { - break; - } - i++; - } - currentToken = "'"; - checkLiterals(true); - currentValue = ValueString.get(StringUtils.fromCacheOrNew(result)); - parseIndex = i; - currentTokenType = VALUE; - return; - } - case CHAR_DOLLAR_QUOTED_STRING: { - String result = null; - int begin = i - 1; - while (types[i] == CHAR_DOLLAR_QUOTED_STRING) { - i++; - } - result = sqlCommand.substring(begin, i); - currentToken = "'"; - checkLiterals(true); - currentValue = ValueString.get(StringUtils.fromCacheOrNew(result)); - parseIndex = i; - currentTokenType = VALUE; - return; - } - case CHAR_END: - currentToken = ""; - currentTokenType = END; - parseIndex = i; - return; - default: - throw getSyntaxError(); - } - } - - private void checkLiterals(boolean text) { - if (!session.getAllowLiterals()) { - int allowed = database.getAllowLiterals(); - if (allowed == Constants.ALLOW_LITERALS_NONE || (text && allowed != Constants.ALLOW_LITERALS_ALL)) { - throw DbException.get(ErrorCode.LITERALS_ARE_NOT_ALLOWED); - } - } - } - - private void readHexDecimal(int start, int i) { - char[] chars = sqlCommandChars; - char c; - do { - c = chars[++i]; - } while ((c >= '0' && c <= '9') || (c >= 'A' && c <= 'F')); - parseIndex = i; - String sub = sqlCommand.substring(start, i); - BigDecimal bd = new BigDecimal(new BigInteger(sub, 16)); - checkLiterals(false); - currentValue = ValueDecimal.get(bd); - currentTokenType = VALUE; - } - - private void readDecimal(int start, int i) { - char[] chars = sqlCommandChars; - int[] types = characterTypes; - // go until the first non-number - while (true) { - int t = types[i]; - if (t != CHAR_DOT && t != CHAR_VALUE) { - break; - } - i++; - } - boolean containsE = false; - if (chars[i] == 'E' || chars[i] == 'e') { - containsE = true; - i++; - if (chars[i] == '+' || chars[i] == '-') { - i++; - } - if (types[i] != CHAR_VALUE) { - throw getSyntaxError(); - } - while (types[++i] == CHAR_VALUE) { - // go until the first non-number - } - } - parseIndex = i; - String sub = sqlCommand.substring(start, i); - checkLiterals(false); - if (!containsE && sub.indexOf('.') < 0) { - BigInteger bi = new BigInteger(sub); - if (bi.compareTo(ValueLong.MAX) <= 0) { - currentValue = ValueLong.get(bi.longValue()); - currentTokenType = VALUE; - return; - } - } - BigDecimal bd; - try { - bd = new BigDecimal(sub); - } catch (NumberFormatException e) { - throw DbException.get(ErrorCode.DATA_CONVERSION_ERROR_1, e, sub); - } - currentValue = ValueDecimal.get(bd); - currentTokenType = VALUE; - } - - public Session getSession() { - return session; - } - - private void initialize(String sql) { - if (sql == null) { - sql = ""; - } - originalSQL = sql; - sqlCommand = sql; - int len = sql.length() + 1; - char[] command = new char[len]; - int[] types = new int[len]; - len--; - sql.getChars(0, len, command, 0); - boolean changed = false; - command[len] = ' '; - int startLoop = 0; - int lastType = 0; - for (int i = 0; i < len; i++) { - char c = command[i]; - int type = 0; - switch (c) { - case '/': - if (command[i + 1] == '*') { - // block comment - changed = true; - command[i] = ' '; - command[i + 1] = ' '; - startLoop = i; - i += 2; - checkRunOver(i, len, startLoop); - while (command[i] != '*' || command[i + 1] != '/') { - command[i++] = ' '; - checkRunOver(i, len, startLoop); - } - command[i] = ' '; - command[i + 1] = ' '; - i++; - } else if (command[i + 1] == '/') { - // single line comment - changed = true; - startLoop = i; - while (true) { - c = command[i]; - if (c == '\n' || c == '\r' || i >= len - 1) { - break; - } - command[i++] = ' '; - checkRunOver(i, len, startLoop); - } - } else { - type = CHAR_SPECIAL_1; - } - break; - case '-': - if (command[i + 1] == '-') { - // single line comment - changed = true; - startLoop = i; - while (true) { - c = command[i]; - if (c == '\n' || c == '\r' || i >= len - 1) { - break; - } - command[i++] = ' '; - checkRunOver(i, len, startLoop); - } - } else { - type = CHAR_SPECIAL_1; - } - break; - case '$': - if (command[i + 1] == '$' && (i == 0 || command[i - 1] <= ' ')) { - // dollar quoted string - changed = true; - command[i] = ' '; - command[i + 1] = ' '; - startLoop = i; - i += 2; - checkRunOver(i, len, startLoop); - while (command[i] != '$' || command[i + 1] != '$') { - types[i++] = CHAR_DOLLAR_QUOTED_STRING; - checkRunOver(i, len, startLoop); - } - command[i] = ' '; - command[i + 1] = ' '; - i++; - } else { - if (lastType == CHAR_NAME || lastType == CHAR_VALUE) { - // $ inside an identifier is supported - type = CHAR_NAME; - } else { - // but not at the start, to support PostgreSQL $1 - type = CHAR_SPECIAL_1; - } - } - break; - case '(': - case ')': - case '{': - case '}': - case '*': - case ',': - case ';': - case '+': - case '%': - case '?': - case '@': - case ']': - type = CHAR_SPECIAL_1; - break; - case '!': - case '<': - case '>': - case '|': - case '=': - case ':': - case '~': - type = CHAR_SPECIAL_2; - break; - case '.': - type = CHAR_DOT; - break; - case '\'': - type = types[i] = CHAR_STRING; - startLoop = i; - while (command[++i] != '\'') { - checkRunOver(i, len, startLoop); - } - break; - case '[': - if (database.getMode().squareBracketQuotedNames) { - // SQL Server alias for " - command[i] = '"'; - changed = true; - type = types[i] = CHAR_QUOTED; - startLoop = i; - while (command[++i] != ']') { - checkRunOver(i, len, startLoop); - } - command[i] = '"'; - } else { - type = CHAR_SPECIAL_1; - } - break; - case '`': - // MySQL alias for ", but not case sensitive - command[i] = '"'; - changed = true; - type = types[i] = CHAR_QUOTED; - startLoop = i; - while (command[++i] != '`') { - checkRunOver(i, len, startLoop); - c = command[i]; - command[i] = Character.toUpperCase(c); - } - command[i] = '"'; - break; - case '\"': - type = types[i] = CHAR_QUOTED; - startLoop = i; - while (command[++i] != '\"') { - checkRunOver(i, len, startLoop); - } - break; - case '_': - type = CHAR_NAME; - break; - default: - if (c >= 'a' && c <= 'z') { - if (identifiersToUpper) { - command[i] = (char) (c - ('a' - 'A')); - changed = true; - } - type = CHAR_NAME; - } else if (c >= 'A' && c <= 'Z') { - type = CHAR_NAME; - } else if (c >= '0' && c <= '9') { - type = CHAR_VALUE; - } else { - if (Character.isJavaIdentifierPart(c)) { - type = CHAR_NAME; - if (identifiersToUpper) { - char u = Character.toUpperCase(c); - if (u != c) { - command[i] = u; - changed = true; - } - } - } - } - } - types[i] = type; - lastType = type; - } - sqlCommandChars = command; - types[len] = CHAR_END; - characterTypes = types; - if (changed) { - sqlCommand = new String(command); - } - parseIndex = 0; - } - - private void checkRunOver(int i, int len, int startLoop) { - if (i >= len) { - parseIndex = startLoop; - throw getSyntaxError(); - } - } - - private int getSpecialType(String s) { - char c0 = s.charAt(0); - if (s.length() == 1) { - switch (c0) { - case '?': - case '$': - return PARAMETER; - case '@': - return AT; - case '+': - return PLUS; - case '-': - return MINUS; - case '{': - case '}': - case '*': - case '/': - case ';': - case ',': - case ':': - case '[': - case ']': - case '~': - return KEYWORD; - case '(': - return OPEN; - case ')': - return CLOSE; - case '<': - return SMALLER; - case '>': - return BIGGER; - case '=': - return EQUAL; - default: - break; - } - } else if (s.length() == 2) { - switch (c0) { - case ':': - if ("::".equals(s)) { - return KEYWORD; - } else if (":=".equals(s)) { - return KEYWORD; - } - break; - case '>': - if (">=".equals(s)) { - return BIGGER_EQUAL; - } - break; - case '<': - if ("<=".equals(s)) { - return SMALLER_EQUAL; - } else if ("<>".equals(s)) { - return NOT_EQUAL; - } - break; - case '!': - if ("!=".equals(s)) { - return NOT_EQUAL; - } else if ("!~".equals(s)) { - return KEYWORD; - } - break; - case '|': - if ("||".equals(s)) { - return STRING_CONCAT; - } - break; - } - } - throw getSyntaxError(); - } - - private int getTokenType(String s) { - int len = s.length(); - if (len == 0) { - throw getSyntaxError(); - } - if (!identifiersToUpper) { - // if not yet converted to uppercase, do it now - s = StringUtils.toUpperEnglish(s); - } - return getSaveTokenType(s, database.getMode().supportOffsetFetch); - } - - private boolean isKeyword(String s) { - if (!identifiersToUpper) { - // if not yet converted to uppercase, do it now - s = StringUtils.toUpperEnglish(s); - } - return isKeyword(s, false); - } - - /** - * Checks if this string is a SQL keyword. - * - * @param s the token to check - * @param supportOffsetFetch if OFFSET and FETCH are keywords - * @return true if it is a keyword - */ - public static boolean isKeyword(String s, boolean supportOffsetFetch) { - if (s == null || s.length() == 0) { - return false; - } - return getSaveTokenType(s, supportOffsetFetch) != IDENTIFIER; - } - - private static int getSaveTokenType(String s, boolean supportOffsetFetch) { - switch (s.charAt(0)) { - case 'C': - if (s.equals("CURRENT_TIMESTAMP")) { - return CURRENT_TIMESTAMP; - } else if (s.equals("CURRENT_TIME")) { - return CURRENT_TIME; - } else if (s.equals("CURRENT_DATE")) { - return CURRENT_DATE; - } - return getKeywordOrIdentifier(s, "CROSS", KEYWORD); - case 'D': - return getKeywordOrIdentifier(s, "DISTINCT", KEYWORD); - case 'E': - if ("EXCEPT".equals(s)) { - return KEYWORD; - } - return getKeywordOrIdentifier(s, "EXISTS", KEYWORD); - case 'F': - if ("FROM".equals(s)) { - return KEYWORD; - } else if ("FOR".equals(s)) { - return KEYWORD; - } else if ("FULL".equals(s)) { - return KEYWORD; - } else if (supportOffsetFetch && "FETCH".equals(s)) { - return KEYWORD; - } - return getKeywordOrIdentifier(s, "FALSE", FALSE); - case 'G': - return getKeywordOrIdentifier(s, "GROUP", KEYWORD); - case 'H': - return getKeywordOrIdentifier(s, "HAVING", KEYWORD); - case 'I': - if ("INNER".equals(s)) { - return KEYWORD; - } else if ("INTERSECT".equals(s)) { - return KEYWORD; - } - return getKeywordOrIdentifier(s, "IS", KEYWORD); - case 'J': - return getKeywordOrIdentifier(s, "JOIN", KEYWORD); - case 'L': - if ("LIMIT".equals(s)) { - return KEYWORD; - } - return getKeywordOrIdentifier(s, "LIKE", KEYWORD); - case 'M': - return getKeywordOrIdentifier(s, "MINUS", KEYWORD); - case 'N': - if ("NOT".equals(s)) { - return KEYWORD; - } else if ("NATURAL".equals(s)) { - return KEYWORD; - } - return getKeywordOrIdentifier(s, "NULL", NULL); - case 'O': - if ("ON".equals(s)) { - return KEYWORD; - } else if (supportOffsetFetch && "OFFSET".equals(s)) { - return KEYWORD; - } - return getKeywordOrIdentifier(s, "ORDER", KEYWORD); - case 'P': - return getKeywordOrIdentifier(s, "PRIMARY", KEYWORD); - case 'R': - return getKeywordOrIdentifier(s, "ROWNUM", ROWNUM); - case 'S': - if (s.equals("SYSTIMESTAMP")) { - return CURRENT_TIMESTAMP; - } else if (s.equals("SYSTIME")) { - return CURRENT_TIME; - } else if (s.equals("SYSDATE")) { - return CURRENT_TIMESTAMP; - } - return getKeywordOrIdentifier(s, "SELECT", KEYWORD); - case 'T': - if ("TODAY".equals(s)) { - return CURRENT_DATE; - } - return getKeywordOrIdentifier(s, "TRUE", TRUE); - case 'U': - if ("UNIQUE".equals(s)) { - return KEYWORD; - } - return getKeywordOrIdentifier(s, "UNION", KEYWORD); - case 'W': - return getKeywordOrIdentifier(s, "WHERE", KEYWORD); - default: - return IDENTIFIER; - } - } - - private static int getKeywordOrIdentifier(String s1, String s2, int keywordType) { - if (s1.equals(s2)) { - return keywordType; - } - return IDENTIFIER; - } - - private Column parseColumnForTable(String columnName, boolean defaultNullable) { - Column column; - boolean isIdentity = false; - if (readIf("IDENTITY") || readIf("SERIAL")) { - column = new Column(columnName, Value.LONG); - column.setOriginalSQL("IDENTITY"); - parseAutoIncrement(column); - column.setPrimaryKey(true); - } else { - column = parseColumn(columnName); - } - if (readIf("NOT")) { - read("NULL"); - column.setNullable(false); - } else if (readIf("NULL")) { - column.setNullable(true); - } else { - column.setNullable(defaultNullable); - } - if (readIf("AS")) { - if (isIdentity) { - getSyntaxError(); - } - Expression expr = readExpression(); - column.setComputedExpression(expr); - } else if (readIf("DEFAULT")) { - Expression defaultExpression = readExpression(); - column.setDefaultExpression(session, defaultExpression); - } else if (readIf("GENERATED")) { - if (!readIf("ALWAYS")) { - read("BY"); - read("DEFAULT"); - } - read("AS"); - read("IDENTITY"); - long start = 1, increment = 1; - if (readIf("(")) { - read("START"); - readIf("WITH"); - start = readLong(); - readIf(","); - if (readIf("INCREMENT")) { - readIf("BY"); - increment = readLong(); - } - read(")"); - } - column.setPrimaryKey(true); - column.setAutoIncrement(true, start, increment); - } - if (readIf("NOT")) { - read("NULL"); - column.setNullable(false); - } else { - readIf("NULL"); - } - if (readIf("AUTO_INCREMENT")) { - parseAutoIncrement(column); - if (readIf("NOT")) { - read("NULL"); - } - } else if (readIf("IDENTITY")) { - parseAutoIncrement(column); - column.setPrimaryKey(true); - if (readIf("NOT")) { - read("NULL"); - } - } - if (readIf("NULL_TO_DEFAULT")) { - column.setConvertNullToDefault(true); - } - if (readIf("SEQUENCE")) { - Sequence sequence = readSequence(); - column.setSequence(sequence); - } - if (readIf("SELECTIVITY")) { - int value = getPositiveInt(); - column.setSelectivity(value); - } - String comment = readCommentIf(); - if (comment != null) { - column.setComment(comment); - } - return column; - } - - private void parseAutoIncrement(Column column) { - long start = 1, increment = 1; - if (readIf("(")) { - start = readLong(); - if (readIf(",")) { - increment = readLong(); - } - read(")"); - } - column.setAutoIncrement(true, start, increment); - } - - private String readCommentIf() { - if (readIf("COMMENT")) { - readIf("IS"); - return readString(); - } - return null; - } - - private Column parseColumn(String columnName) { - String original = currentToken; - boolean regular = false; - if (readIf("LONG")) { - if (readIf("RAW")) { - original += " RAW"; - } - } else if (readIf("DOUBLE")) { - if (readIf("PRECISION")) { - original += " PRECISION"; - } - } else if (readIf("CHARACTER")) { - if (readIf("VARYING")) { - original += " VARYING"; - } - } else { - regular = true; - } - long precision = -1; - int displaySize = -1; - int scale = -1; - String comment = null; - Column templateColumn = null; - DataType dataType; - if (!identifiersToUpper) { - original = StringUtils.toUpperEnglish(original); - } - UserDataType userDataType = database.findUserDataType(original); - if (userDataType != null) { - templateColumn = userDataType.getColumn(); - dataType = DataType.getDataType(templateColumn.getType()); - comment = templateColumn.getComment(); - original = templateColumn.getOriginalSQL(); - precision = templateColumn.getPrecision(); - displaySize = templateColumn.getDisplaySize(); - scale = templateColumn.getScale(); - } else { - dataType = DataType.getTypeByName(original); - if (dataType == null) { - throw DbException.get(ErrorCode.UNKNOWN_DATA_TYPE_1, currentToken); - } - } - if (database.getIgnoreCase() && dataType.type == Value.STRING && !equalsToken("VARCHAR_CASESENSITIVE", original)) { - original = "VARCHAR_IGNORECASE"; - dataType = DataType.getTypeByName(original); - } - if (dataType.type == Value.NULL) { - // We do support NULL in the database meta data, - // but not actually when creating tables. - throw DbException.get(ErrorCode.UNKNOWN_DATA_TYPE_1, original); - } - if (regular) { - read(); - } - precision = precision == -1 ? dataType.defaultPrecision : precision; - displaySize = displaySize == -1 ? dataType.defaultDisplaySize : displaySize; - scale = scale == -1 ? dataType.defaultScale : scale; - if (dataType.supportsPrecision || dataType.supportsScale) { - if (readIf("(")) { - long p = readLong(); - if (readIf("K")) { - p *= 1024; - } else if (readIf("M")) { - p *= 1024 * 1024; - } else if (readIf("G")) { - p *= 1024 * 1024 * 1024; - } - if (p > Long.MAX_VALUE) { - p = Long.MAX_VALUE; - } - original += "(" + p; - // Oracle syntax - readIf("CHAR"); - if (dataType.supportsScale) { - if (readIf(",")) { - scale = getInt(); - original += ", " + scale; - } else { - // special case: TIMESTAMP(5) actually means TIMESTAMP(23, 5) - if (dataType.type == Value.TIMESTAMP) { - scale = MathUtils.convertLongToInt(p); - p = precision; - } else { - scale = 0; - } - } - } - precision = p; - displaySize = MathUtils.convertLongToInt(precision); - original += ")"; - read(")"); - } - } else if (readIf("(")) { - // Support for MySQL: INT(11), MEDIUMINT(8) and so on. - // Just ignore the precision. - getPositiveInt(); - read(")"); - } - if (readIf("FOR")) { - read("BIT"); - read("DATA"); - if (dataType.type == Value.STRING) { - dataType = DataType.getTypeByName("BINARY"); - } - } - // MySQL compatibility - readIf("UNSIGNED"); - int type = dataType.type; - Column column = new Column(columnName, type, precision, scale, displaySize); - if (templateColumn != null) { - column.setNullable(templateColumn.isNullable()); - column.setDefaultExpression(session, templateColumn.getDefaultExpression()); - int selectivity = templateColumn.getSelectivity(); - if (selectivity != Constants.SELECTIVITY_DEFAULT) { - column.setSelectivity(selectivity); - } - Expression checkConstraint = templateColumn.getCheckConstraint(session, columnName); - if (checkConstraint != null) { - column.addCheckConstraint(session, checkConstraint); - } - } - column.setComment(comment); - column.setOriginalSQL(original); - return column; - } - - private Prepared parseCreate() { - boolean force = readIf("FORCE"); - if (readIf("VIEW")) { - return parseCreateView(force); - } else if (readIf("ALIAS")) { - return parseCreateFunctionAlias(force); - } else if (readIf("SEQUENCE")) { - return parseCreateSequence(); - } else if (readIf("USER")) { - return parseCreateUser(); - } else if (readIf("TRIGGER")) { - return parseCreateTrigger(force); - } else if (readIf("ROLE")) { - return parseCreateRole(); - } else if (readIf("SCHEMA")) { - return parseCreateSchema(); - } else if (readIf("CONSTANT")) { - return parseCreateConstant(); - } else if (readIf("DOMAIN")) { - return parseCreateUserDataType(); - } else if (readIf("TYPE")) { - return parseCreateUserDataType(); - } else if (readIf("DATATYPE")) { - return parseCreateUserDataType(); - } else if (readIf("AGGREGATE")) { - return parseCreateAggregate(force); - } else if (readIf("LINKED")) { - return parseCreateLinkedTable(false, false, force); - } - // tables or linked tables - boolean memory = false, cached = false; - if (readIf("MEMORY")) { - memory = true; - } else if (readIf("CACHED")) { - cached = true; - } - if (readIf("LOCAL")) { - read("TEMPORARY"); - if (readIf("LINKED")) { - return parseCreateLinkedTable(true, false, force); - } - read("TABLE"); - return parseCreateTable(true, false, cached); - } else if (readIf("GLOBAL")) { - read("TEMPORARY"); - if (readIf("LINKED")) { - return parseCreateLinkedTable(true, true, force); - } - read("TABLE"); - return parseCreateTable(true, true, cached); - } else if (readIf("TEMP") || readIf("TEMPORARY")) { - if (readIf("LINKED")) { - return parseCreateLinkedTable(true, true, force); - } - read("TABLE"); - return parseCreateTable(true, true, cached); - } else if (readIf("TABLE")) { - if (!cached && !memory) { - int defaultMode; - Setting setting = database.findSetting(SetTypes.getTypeName(SetTypes.DEFAULT_TABLE_TYPE)); - defaultMode = setting == null ? Table.TYPE_CACHED : setting.getIntValue(); - cached = defaultMode == Table.TYPE_CACHED; - } - return parseCreateTable(false, false, cached); - } else { - boolean hash = false, primaryKey = false, unique = false; - String indexName = null; - Schema oldSchema = null; - boolean ifNotExists = false; - if (readIf("PRIMARY")) { - read("KEY"); - if (readIf("HASH")) { - hash = true; - } - primaryKey = true; - if (!isToken("ON")) { - ifNotExists = readIfNoExists(); - indexName = readIdentifierWithSchema(null); - oldSchema = getSchema(); - } - } else { - if (readIf("UNIQUE")) { - unique = true; - } - if (readIf("HASH")) { - hash = true; - } - if (readIf("INDEX")) { - if (!isToken("ON")) { - ifNotExists = readIfNoExists(); - indexName = readIdentifierWithSchema(null); - oldSchema = getSchema(); - } - } else { - throw getSyntaxError(); - } - } - read("ON"); - String tableName = readIdentifierWithSchema(); - checkSchema(oldSchema); - CreateIndex command = new CreateIndex(session, getSchema()); - command.setIfNotExists(ifNotExists); - command.setHash(hash); - command.setPrimaryKey(primaryKey); - command.setTableName(tableName); - command.setUnique(unique); - command.setIndexName(indexName); - command.setComment(readCommentIf()); - read("("); - command.setIndexColumns(parseIndexColumnList()); - return command; - } - } - - private boolean addRoleOrRight(GrantRevoke command) { - if (readIf("SELECT")) { - command.addRight(Right.SELECT); - return false; - } else if (readIf("DELETE")) { - command.addRight(Right.DELETE); - return false; - } else if (readIf("INSERT")) { - command.addRight(Right.INSERT); - return false; - } else if (readIf("UPDATE")) { - command.addRight(Right.UPDATE); - return false; - } else if (readIf("ALL")) { - command.addRight(Right.ALL); - return false; - } else if (readIf("CONNECT")) { - // ignore this right - return false; - } else if (readIf("RESOURCE")) { - // ignore this right - return false; - } else { - command.addRoleName(readUniqueIdentifier()); - return true; - } - } - - private GrantRevoke parseGrantRevoke(int operationType) { - GrantRevoke command = new GrantRevoke(session); - command.setOperationType(operationType); - boolean isRoleBased = addRoleOrRight(command); - while (readIf(",")) { - boolean next = addRoleOrRight(command); - if (next != isRoleBased) { - throw DbException.get(ErrorCode.ROLES_AND_RIGHT_CANNOT_BE_MIXED); - } - } - if (!isRoleBased) { - if (readIf("ON")) { - do { - Table table = readTableOrView(); - command.addTable(table); - } while (readIf(",")); - } - } - if (operationType == GrantRevoke.GRANT) { - read("TO"); - } else { - read("FROM"); - } - command.setGranteeName(readUniqueIdentifier()); - return command; - } - - private Call parseCall() { - Call command = new Call(session); - currentPrepared = command; - command.setExpression(readExpression()); - return command; - } - - private CreateRole parseCreateRole() { - CreateRole command = new CreateRole(session); - command.setIfNotExists(readIfNoExists()); - command.setRoleName(readUniqueIdentifier()); - return command; - } - - private CreateSchema parseCreateSchema() { - CreateSchema command = new CreateSchema(session); - command.setIfNotExists(readIfNoExists()); - command.setSchemaName(readUniqueIdentifier()); - if (readIf("AUTHORIZATION")) { - command.setAuthorization(readUniqueIdentifier()); - } else { - command.setAuthorization(session.getUser().getName()); - } - return command; - } - - private CreateSequence parseCreateSequence() { - boolean ifNotExists = readIfNoExists(); - String sequenceName = readIdentifierWithSchema(); - CreateSequence command = new CreateSequence(session, getSchema()); - command.setIfNotExists(ifNotExists); - command.setSequenceName(sequenceName); - while (true) { - if (readIf("START")) { - readIf("WITH"); - command.setStartWith(readExpression()); - } else if (readIf("INCREMENT")) { - readIf("BY"); - command.setIncrement(readExpression()); - } else if (readIf("CACHE")) { - command.setCacheSize(readExpression()); - } else if (readIf("BELONGS_TO_TABLE")) { - command.setBelongsToTable(true); - } else { - break; - } - } - return command; - } - - private boolean readIfNoExists() { - if (readIf("IF")) { - read("NOT"); - read("EXISTS"); - return true; - } - return false; - } - - private CreateConstant parseCreateConstant() { - boolean ifNotExists = readIfNoExists(); - String constantName = readIdentifierWithSchema(); - Schema schema = getSchema(); - if (isKeyword(constantName)) { - throw DbException.get(ErrorCode.CONSTANT_ALREADY_EXISTS_1, constantName); - } - read("VALUE"); - Expression expr = readExpression(); - CreateConstant command = new CreateConstant(session, schema); - command.setConstantName(constantName); - command.setExpression(expr); - command.setIfNotExists(ifNotExists); - return command; - } - - private CreateAggregate parseCreateAggregate(boolean force) { - boolean ifNotExists = readIfNoExists(); - CreateAggregate command = new CreateAggregate(session); - command.setForce(force); - String name = readIdentifierWithSchema(); - if (isKeyword(name) || Function.getFunction(database, name) != null || Aggregate.getAggregateType(name) >= 0) { - throw DbException.get(ErrorCode.FUNCTION_ALIAS_ALREADY_EXISTS_1, name); - } - command.setName(name); - command.setSchema(getSchema()); - command.setIfNotExists(ifNotExists); - read("FOR"); - command.setJavaClassMethod(readUniqueIdentifier()); - return command; - } - - private CreateUserDataType parseCreateUserDataType() { - boolean ifNotExists = readIfNoExists(); - CreateUserDataType command = new CreateUserDataType(session); - command.setTypeName(readUniqueIdentifier()); - read("AS"); - Column col = parseColumnForTable("VALUE", true); - if (readIf("CHECK")) { - Expression expr = readExpression(); - col.addCheckConstraint(session, expr); - } - col.rename(null); - command.setColumn(col); - command.setIfNotExists(ifNotExists); - return command; - } - - private CreateTrigger parseCreateTrigger(boolean force) { - boolean ifNotExists = readIfNoExists(); - String triggerName = readIdentifierWithSchema(null); - Schema schema = getSchema(); - boolean insteadOf, isBefore; - if (readIf("INSTEAD")) { - read("OF"); - isBefore = true; - insteadOf = true; - } else if (readIf("BEFORE")) { - insteadOf = false; - isBefore = true; - } else { - read("AFTER"); - insteadOf = false; - isBefore = false; - } - int typeMask = 0; - boolean onRollback = false; - do { - if (readIf("INSERT")) { - typeMask |= Trigger.INSERT; - } else if (readIf("UPDATE")) { - typeMask |= Trigger.UPDATE; - } else if (readIf("DELETE")) { - typeMask |= Trigger.DELETE; - } else if (readIf("SELECT")) { - typeMask |= Trigger.SELECT; - } else if (readIf("ROLLBACK")) { - onRollback = true; - } else { - throw getSyntaxError(); - } - } while (readIf(",")); - read("ON"); - String tableName = readIdentifierWithSchema(); - checkSchema(schema); - CreateTrigger command = new CreateTrigger(session, getSchema()); - command.setForce(force); - command.setTriggerName(triggerName); - command.setIfNotExists(ifNotExists); - command.setInsteadOf(insteadOf); - command.setBefore(isBefore); - command.setOnRollback(onRollback); - command.setTypeMask(typeMask); - command.setTableName(tableName); - if (readIf("FOR")) { - read("EACH"); - read("ROW"); - command.setRowBased(true); - } else { - command.setRowBased(false); - } - if (readIf("QUEUE")) { - command.setQueueSize(getPositiveInt()); - } - command.setNoWait(readIf("NOWAIT")); - read("CALL"); - command.setTriggerClassName(readUniqueIdentifier()); - return command; - } - - private CreateUser parseCreateUser() { - CreateUser command = new CreateUser(session); - command.setIfNotExists(readIfNoExists()); - command.setUserName(readUniqueIdentifier()); - command.setComment(readCommentIf()); - if (readIf("PASSWORD")) { - command.setPassword(readExpression()); - } else if (readIf("SALT")) { - command.setSalt(readExpression()); - read("HASH"); - command.setHash(readExpression()); - } else if (readIf("IDENTIFIED")) { - read("BY"); - // uppercase if not quoted - command.setPassword(ValueExpression.get(ValueString.get(readColumnIdentifier()))); - } else { - throw getSyntaxError(); - } - if (readIf("ADMIN")) { - command.setAdmin(true); - } - return command; - } - - private CreateFunctionAlias parseCreateFunctionAlias(boolean force) { - boolean ifNotExists = readIfNoExists(); - String aliasName = readIdentifierWithSchema(); - if (isKeyword(aliasName) || Function.getFunction(database, aliasName) != null || Aggregate.getAggregateType(aliasName) >= 0) { - throw DbException.get(ErrorCode.FUNCTION_ALIAS_ALREADY_EXISTS_1, aliasName); - } - CreateFunctionAlias command = new CreateFunctionAlias(session, getSchema()); - command.setForce(force); - command.setAliasName(aliasName); - command.setIfNotExists(ifNotExists); - command.setDeterministic(readIf("DETERMINISTIC")); - if (readIf("AS")) { - command.setSource(readString()); - } else { - read("FOR"); - command.setJavaClassMethod(readUniqueIdentifier()); - } - return command; - } - - private Query parserWith() { - String tempViewName = readIdentifierWithSchema(); - Schema schema = getSchema(); - Table recursiveTable; - read("("); - ArrayList columns = New.arrayList(); - String[] cols = parseColumnList(); - for (String c : cols) { - columns.add(new Column(c, Value.STRING)); - } - CreateTableData data = new CreateTableData(); - data.id = database.allocateObjectId(); - data.tableName = tempViewName; - data.temporary = true; - data.persistData = true; - data.persistIndexes = false; - data.create = true; - data.session = session; - recursiveTable = schema.createTable(data); - session.addLocalTempTable(recursiveTable); - String querySQL = StringUtils.fromCacheOrNew(sqlCommand.substring(parseIndex)); - read("AS"); - Query withQuery = parseSelect(); - withQuery.prepare(); - session.removeLocalTempTable(recursiveTable); - int id = database.allocateObjectId(); - TableView view = new TableView(schema, id, tempViewName, querySQL, null, cols, session, true); - view.setTemporary(true); - // view.setOnCommitDrop(true); - session.addLocalTempTable(view); - Query query = parseSelect(); - query.prepare(); - query.setPrepareAlways(true); - // session.removeLocalTempTable(view); - return query; - } - - private CreateView parseCreateView(boolean force) { - boolean ifNotExists = readIfNoExists(); - String viewName = readIdentifierWithSchema(); - CreateView command = new CreateView(session, getSchema()); - this.createView = command; - command.setViewName(viewName); - command.setIfNotExists(ifNotExists); - command.setComment(readCommentIf()); - if (readIf("(")) { - String[] cols = parseColumnList(); - command.setColumnNames(cols); - } - String select = StringUtils.fromCacheOrNew(sqlCommand.substring(parseIndex)); - read("AS"); - try { - Query query = parseSelect(); - query.prepare(); - command.setSelect(query); - } catch (DbException e) { - if (force) { - command.setSelectSQL(select); - } else { - throw e; - } - } - return command; - } - - private TransactionCommand parseCheckpoint() { - TransactionCommand command; - if (readIf("SYNC")) { - command = new TransactionCommand(session, TransactionCommand.CHECKPOINT_SYNC); - } else { - command = new TransactionCommand(session, TransactionCommand.CHECKPOINT); - } - return command; - } - - private Prepared parseAlter() { - if (readIf("TABLE")) { - return parseAlterTable(); - } else if (readIf("USER")) { - return parseAlterUser(); - } else if (readIf("INDEX")) { - return parseAlterIndex(); - } else if (readIf("SEQUENCE")) { - return parseAlterSequence(); - } else if (readIf("VIEW")) { - return parseAlterView(); - } - throw getSyntaxError(); - } - - private void checkSchema(Schema old) { - if (old != null && getSchema() != old) { - throw DbException.get(ErrorCode.SCHEMA_NAME_MUST_MATCH); - } - } - - private AlterIndexRename parseAlterIndex() { - String indexName = readIdentifierWithSchema(); - Schema old = getSchema(); - AlterIndexRename command = new AlterIndexRename(session); - command.setOldIndex(getSchema().getIndex(indexName)); - read("RENAME"); - read("TO"); - String newName = readIdentifierWithSchema(old.getName()); - checkSchema(old); - command.setNewName(newName); - return command; - } - - private AlterView parseAlterView() { - AlterView command = new AlterView(session); - String viewName = readIdentifierWithSchema(); - Table tableView = getSchema().findTableOrView(session, viewName); - if (!(tableView instanceof TableView)) { - throw DbException.get(ErrorCode.VIEW_NOT_FOUND_1, viewName); - } - TableView view = (TableView) tableView; - command.setView(view); - read("RECOMPILE"); - return command; - } - - private AlterSequence parseAlterSequence() { - String sequenceName = readIdentifierWithSchema(); - Sequence sequence = getSchema().getSequence(sequenceName); - AlterSequence command = new AlterSequence(session, sequence.getSchema()); - command.setSequence(sequence); - if (readIf("RESTART")) { - read("WITH"); - command.setStartWith(readExpression()); - } - if (readIf("INCREMENT")) { - read("BY"); - command.setIncrement(readExpression()); - } - return command; - } - - private AlterUser parseAlterUser() { - String userName = readUniqueIdentifier(); - if (readIf("SET")) { - AlterUser command = new AlterUser(session); - command.setType(AlterUser.SET_PASSWORD); - command.setUser(database.getUser(userName)); - if (readIf("PASSWORD")) { - command.setPassword(readExpression()); - } else if (readIf("SALT")) { - command.setSalt(readExpression()); - read("HASH"); - command.setHash(readExpression()); - } else { - throw getSyntaxError(); - } - return command; - } else if (readIf("RENAME")) { - read("TO"); - AlterUser command = new AlterUser(session); - command.setType(AlterUser.RENAME); - command.setUser(database.getUser(userName)); - String newName = readUniqueIdentifier(); - command.setNewName(newName); - return command; - } else if (readIf("ADMIN")) { - AlterUser command = new AlterUser(session); - command.setType(AlterUser.ADMIN); - User user = database.getUser(userName); - command.setUser(user); - if (readIf("TRUE")) { - command.setAdmin(true); - } else if (readIf("FALSE")) { - command.setAdmin(false); - } else { - throw getSyntaxError(); - } - return command; - } - throw getSyntaxError(); - } - - private void readIfEqualOrTo() { - if (!readIf("=")) { - readIf("TO"); - } - } - - private Prepared parseSet() { - if (readIf("@")) { - Set command = new Set(session, SetTypes.VARIABLE); - command.setString(readAliasIdentifier()); - readIfEqualOrTo(); - command.setExpression(readExpression()); - return command; - } else if (readIf("AUTOCOMMIT")) { - readIfEqualOrTo(); - boolean value = readBooleanSetting(); - int setting = value ? TransactionCommand.AUTOCOMMIT_TRUE : TransactionCommand.AUTOCOMMIT_FALSE; - return new TransactionCommand(session, setting); - } else if (readIf("MVCC")) { - readIfEqualOrTo(); - boolean value = readBooleanSetting(); - Set command = new Set(session, SetTypes.MVCC); - command.setInt(value ? 1 : 0); - return command; - } else if (readIf("EXCLUSIVE")) { - readIfEqualOrTo(); - Set command = new Set(session, SetTypes.EXCLUSIVE); - command.setExpression(readExpression()); - return command; - } else if (readIf("IGNORECASE")) { - readIfEqualOrTo(); - boolean value = readBooleanSetting(); - Set command = new Set(session, SetTypes.IGNORECASE); - command.setInt(value ? 1 : 0); - return command; - } else if (readIf("PASSWORD")) { - readIfEqualOrTo(); - AlterUser command = new AlterUser(session); - command.setType(AlterUser.SET_PASSWORD); - command.setUser(session.getUser()); - command.setPassword(readExpression()); - return command; - } else if (readIf("SALT")) { - readIfEqualOrTo(); - AlterUser command = new AlterUser(session); - command.setType(AlterUser.SET_PASSWORD); - command.setUser(session.getUser()); - command.setSalt(readExpression()); - read("HASH"); - command.setHash(readExpression()); - return command; - } else if (readIf("MODE")) { - readIfEqualOrTo(); - Set command = new Set(session, SetTypes.MODE); - command.setString(readAliasIdentifier()); - return command; - } else if (readIf("COMPRESS_LOB")) { - readIfEqualOrTo(); - Set command = new Set(session, SetTypes.COMPRESS_LOB); - if (currentTokenType == VALUE) { - command.setString(readString()); - } else { - command.setString(readUniqueIdentifier()); - } - return command; - } else if (readIf("DATABASE")) { - readIfEqualOrTo(); - read("COLLATION"); - return parseSetCollation(); - } else if (readIf("COLLATION")) { - readIfEqualOrTo(); - return parseSetCollation(); - } else if (readIf("CLUSTER")) { - readIfEqualOrTo(); - Set command = new Set(session, SetTypes.CLUSTER); - command.setString(readString()); - return command; - } else if (readIf("DATABASE_EVENT_LISTENER")) { - readIfEqualOrTo(); - Set command = new Set(session, SetTypes.DATABASE_EVENT_LISTENER); - command.setString(readString()); - return command; - } else if (readIf("ALLOW_LITERALS")) { - readIfEqualOrTo(); - Set command = new Set(session, SetTypes.ALLOW_LITERALS); - if (readIf("NONE")) { - command.setInt(Constants.ALLOW_LITERALS_NONE); - } else if (readIf("ALL")) { - command.setInt(Constants.ALLOW_LITERALS_ALL); - } else if (readIf("NUMBERS")) { - command.setInt(Constants.ALLOW_LITERALS_NUMBERS); - } else { - command.setInt(getPositiveInt()); - } - return command; - } else if (readIf("DEFAULT_TABLE_TYPE")) { - readIfEqualOrTo(); - Set command = new Set(session, SetTypes.DEFAULT_TABLE_TYPE); - if (readIf("MEMORY")) { - command.setInt(Table.TYPE_MEMORY); - } else if (readIf("CACHED")) { - command.setInt(Table.TYPE_CACHED); - } else { - command.setInt(getPositiveInt()); - } - return command; - } else if (readIf("CREATE")) { - readIfEqualOrTo(); - // Derby compatibility (CREATE=TRUE in the database URL) - read(); - return new NoOperation(session); - } else if (readIf("HSQLDB.DEFAULT_TABLE_TYPE")) { - readIfEqualOrTo(); - read(); - return new NoOperation(session); - } else if (readIf("PAGE_STORE")) { - readIfEqualOrTo(); - read(); - return new NoOperation(session); - } else if (readIf("CACHE_TYPE")) { - readIfEqualOrTo(); - read(); - return new NoOperation(session); - } else if (readIf("FILE_LOCK")) { - readIfEqualOrTo(); - read(); - return new NoOperation(session); - } else if (readIf("DB_CLOSE_ON_EXIT")) { - readIfEqualOrTo(); - read(); - return new NoOperation(session); - } else if (readIf("AUTO_SERVER")) { - readIfEqualOrTo(); - read(); - return new NoOperation(session); - } else if (readIf("AUTO_RECONNECT")) { - readIfEqualOrTo(); - read(); - return new NoOperation(session); - } else if (readIf("ASSERT")) { - readIfEqualOrTo(); - read(); - return new NoOperation(session); - } else if (readIf("ACCESS_MODE_DATA")) { - readIfEqualOrTo(); - read(); - return new NoOperation(session); - } else if (readIf("OPEN_NEW")) { - readIfEqualOrTo(); - read(); - return new NoOperation(session); - } else if (readIf("PAGE_SIZE")) { - readIfEqualOrTo(); - read(); - return new NoOperation(session); - } else if (readIf("RECOVER")) { - readIfEqualOrTo(); - read(); - return new NoOperation(session); - } else if (readIf("SCHEMA")) { - readIfEqualOrTo(); - Set command = new Set(session, SetTypes.SCHEMA); - command.setString(readAliasIdentifier()); - return command; - } else if (readIf("DATESTYLE")) { - // PostgreSQL compatibility - readIfEqualOrTo(); - if (!readIf("ISO")) { - String s = readString(); - if (!equalsToken(s, "ISO")) { - throw getSyntaxError(); - } - } - return new NoOperation(session); - } else if (readIf("SEARCH_PATH") || readIf(SetTypes.getTypeName(SetTypes.SCHEMA_SEARCH_PATH))) { - readIfEqualOrTo(); - Set command = new Set(session, SetTypes.SCHEMA_SEARCH_PATH); - ArrayList list = New.arrayList(); - list.add(readAliasIdentifier()); - while (readIf(",")) { - list.add(readAliasIdentifier()); - } - String[] schemaNames = new String[list.size()]; - list.toArray(schemaNames); - command.setStringArray(schemaNames); - return command; - } else { - if (isToken("LOGSIZE")) { - // HSQLDB compatibility - currentToken = SetTypes.getTypeName(SetTypes.MAX_LOG_SIZE); - } - int type = SetTypes.getType(currentToken); - if (type < 0) { - throw getSyntaxError(); - } - read(); - readIfEqualOrTo(); - Set command = new Set(session, type); - command.setExpression(readExpression()); - return command; - } - } - - private Set parseSetCollation() { - Set command = new Set(session, SetTypes.COLLATION); - String name = readAliasIdentifier(); - command.setString(name); - if (equalsToken(name, CompareMode.OFF)) { - return command; - } - Collator coll = CompareMode.getCollator(name); - if (coll == null) { - throw getSyntaxError(); - } - if (readIf("STRENGTH")) { - if (readIf("PRIMARY")) { - command.setInt(Collator.PRIMARY); - } else if (readIf("SECONDARY")) { - command.setInt(Collator.SECONDARY); - } else if (readIf("TERTIARY")) { - command.setInt(Collator.TERTIARY); - } else if (readIf("IDENTICAL")) { - command.setInt(Collator.IDENTICAL); - } - } else { - command.setInt(coll.getStrength()); - } - return command; - } - - private RunScriptCommand parseRunScript() { - RunScriptCommand command = new RunScriptCommand(session); - read("FROM"); - command.setFileNameExpr(readExpression()); - if (readIf("COMPRESSION")) { - command.setCompressionAlgorithm(readUniqueIdentifier()); - } - if (readIf("CIPHER")) { - command.setCipher(readUniqueIdentifier()); - if (readIf("PASSWORD")) { - command.setPassword(readString().toCharArray()); - } - } - if (readIf("CHARSET")) { - command.setCharset(readString()); - } - return command; - } - - private ScriptCommand parseScript() { - ScriptCommand command = new ScriptCommand(session); - boolean data = true, passwords = true, settings = true, dropTables = false, simple = false; - if (readIf("SIMPLE")) { - simple = true; - } - if (readIf("NODATA")) { - data = false; - } - if (readIf("NOPASSWORDS")) { - passwords = false; - } - if (readIf("NOSETTINGS")) { - settings = false; - } - if (readIf("DROP")) { - dropTables = true; - } - if (readIf("BLOCKSIZE")) { - long blockSize = readLong(); - command.setLobBlockSize(blockSize); - } - command.setData(data); - command.setPasswords(passwords); - command.setSettings(settings); - command.setDrop(dropTables); - command.setSimple(simple); - if (readIf("TO")) { - command.setFileNameExpr(readExpression()); - if (readIf("COMPRESSION")) { - command.setCompressionAlgorithm(readUniqueIdentifier()); - } - if (readIf("CIPHER")) { - command.setCipher(readUniqueIdentifier()); - if (readIf("PASSWORD")) { - command.setPassword(readString().toCharArray()); - } - } - } - return command; - } - - private Table readTableOrView() { - return readTableOrView(readIdentifierWithSchema(null)); - } - - private Table readTableOrView(String tableName) { - // same algorithm than readSequence - if (schemaName != null) { - return getSchema().getTableOrView(session, tableName); - } - Table table = database.getSchema(session.getCurrentSchemaName()).findTableOrView(session, tableName); - if (table != null) { - return table; - } - String[] schemaNames = session.getSchemaSearchPath(); - for (int i = 0; schemaNames != null && i < schemaNames.length; i++) { - Schema s = database.getSchema(schemaNames[i]); - table = s.findTableOrView(session, tableName); - if (table != null) { - return table; - } - } - throw DbException.get(ErrorCode.TABLE_OR_VIEW_NOT_FOUND_1, tableName); - } - - private FunctionAlias findFunctionAlias(String schema, String aliasName) { - FunctionAlias functionAlias = database.getSchema(schema).findFunction(aliasName); - if (functionAlias != null) { - return functionAlias; - } - String[] schemaNames = session.getSchemaSearchPath(); - if (schemaNames != null) { - for (String n : schemaNames) { - functionAlias = database.getSchema(n).findFunction(aliasName); - if (functionAlias != null) { - return functionAlias; - } - } - } - return null; - } - - private Sequence findSequence(String schema, String sequenceName) { - Sequence sequence = database.getSchema(schema).findSequence(sequenceName); - if (sequence != null) { - return sequence; - } - String[] schemaNames = session.getSchemaSearchPath(); - if (schemaNames != null) { - for (String n : schemaNames) { - sequence = database.getSchema(n).findSequence(sequenceName); - if (sequence != null) { - return sequence; - } - } - } - return null; - } - - private Sequence readSequence() { - // same algorithm as readTableOrView - String sequenceName = readIdentifierWithSchema(null); - if (schemaName != null) { - return getSchema().getSequence(sequenceName); - } - Sequence sequence = findSequence(session.getCurrentSchemaName(), sequenceName); - if (sequence != null) { - return sequence; - } - throw DbException.get(ErrorCode.SEQUENCE_NOT_FOUND_1, sequenceName); - } - - private Prepared parseAlterTable() { - Table table = readTableOrView(); - if (readIf("ADD")) { - Prepared command = parseAlterTableAddConstraintIf(table.getName(), table.getSchema()); - if (command != null) { - return command; - } - return parseAlterTableAddColumn(table); - } else if (readIf("SET")) { - read("REFERENTIAL_INTEGRITY"); - int type; - if (readIf("TRUE")) { - type = AlterTableSet.REFERENTIAL_INTEGRITY_TRUE; - } else { - read("FALSE"); - type = AlterTableSet.REFERENTIAL_INTEGRITY_FALSE; - } - AlterTableSet command = new AlterTableSet(session, table.getSchema(), type); - command.setTableName(table.getName()); - if (readIf("CHECK")) { - command.setCheckExisting(true); - } else if (readIf("NOCHECK")) { - command.setCheckExisting(false); - } - return command; - } else if (readIf("RENAME")) { - read("TO"); - String newName = readIdentifierWithSchema(table.getSchema().getName()); - checkSchema(table.getSchema()); - AlterTableRename command = new AlterTableRename(session, getSchema()); - command.setOldTable(table); - command.setNewTableName(newName); - return command; - } else if (readIf("DROP")) { - if (readIf("CONSTRAINT")) { - boolean ifExists = readIfExists(false); - String constraintName = readIdentifierWithSchema(table.getSchema().getName()); - ifExists = readIfExists(ifExists); - checkSchema(table.getSchema()); - AlterTableDropConstraint command = new AlterTableDropConstraint(session, getSchema(), ifExists); - command.setConstraintName(constraintName); - return command; - } else if (readIf("PRIMARY")) { - read("KEY"); - Index idx = table.getPrimaryKey(); - DropIndex command = new DropIndex(session, table.getSchema()); - command.setIndexName(idx.getName()); - return command; - } else { - readIf("COLUMN"); - AlterTableAlterColumn command = new AlterTableAlterColumn(session, table.getSchema()); - command.setType(AlterTableAlterColumn.DROP); - String columnName = readColumnIdentifier(); - command.setTable(table); - command.setOldColumn(table.getColumn(columnName)); - return command; - } - } else if (readIf("ALTER")) { - readIf("COLUMN"); - String columnName = readColumnIdentifier(); - Column column = table.getColumn(columnName); - if (readIf("RENAME")) { - read("TO"); - AlterTableRenameColumn command = new AlterTableRenameColumn(session); - command.setTable(table); - command.setColumn(column); - String newName = readColumnIdentifier(); - command.setNewColumnName(newName); - return command; - } else if (readIf("DROP")) { - // PostgreSQL compatibility - if (readIf("DEFAULT")) { - AlterTableAlterColumn command = new AlterTableAlterColumn(session, table.getSchema()); - command.setTable(table); - command.setOldColumn(column); - command.setType(AlterTableAlterColumn.DEFAULT); - command.setDefaultExpression(null); - return command; - } - read("NOT"); - read("NULL"); - AlterTableAlterColumn command = new AlterTableAlterColumn(session, table.getSchema()); - command.setTable(table); - command.setOldColumn(column); - command.setType(AlterTableAlterColumn.NULL); - return command; - } else if (readIf("TYPE")) { - // PostgreSQL compatibility - return parseAlterTableAlterColumnType(table, columnName, column); - } else if (readIf("SET")) { - if (readIf("DATA")) { - // Derby compatibility - read("TYPE"); - return parseAlterTableAlterColumnType(table, columnName, column); - } - AlterTableAlterColumn command = new AlterTableAlterColumn(session, table.getSchema()); - command.setTable(table); - command.setOldColumn(column); - if (readIf("NULL")) { - command.setType(AlterTableAlterColumn.NULL); - return command; - } else if (readIf("NOT")) { - read("NULL"); - command.setType(AlterTableAlterColumn.NOT_NULL); - return command; - } else if (readIf("DEFAULT")) { - Expression defaultExpression = readExpression(); - command.setType(AlterTableAlterColumn.DEFAULT); - command.setDefaultExpression(defaultExpression); - return command; - } - } else if (readIf("RESTART")) { - readIf("WITH"); - Expression start = readExpression(); - AlterSequence command = new AlterSequence(session, table.getSchema()); - command.setColumn(column); - command.setStartWith(start); - return command; - } else if (readIf("SELECTIVITY")) { - AlterTableAlterColumn command = new AlterTableAlterColumn(session, table.getSchema()); - command.setTable(table); - command.setType(AlterTableAlterColumn.SELECTIVITY); - command.setOldColumn(column); - command.setSelectivity(readExpression()); - return command; - } else { - return parseAlterTableAlterColumnType(table, columnName, column); - } - } - throw getSyntaxError(); - } - - private AlterTableAlterColumn parseAlterTableAlterColumnType(Table table, String columnName, Column column) { - Column newColumn = parseColumnForTable(columnName, column.isNullable()); - AlterTableAlterColumn command = new AlterTableAlterColumn(session, table.getSchema()); - command.setTable(table); - command.setType(AlterTableAlterColumn.CHANGE_TYPE); - command.setOldColumn(column); - command.setNewColumn(newColumn); - return command; - } - - private AlterTableAlterColumn parseAlterTableAddColumn(Table table) { - readIf("COLUMN"); - Schema schema = table.getSchema(); - AlterTableAlterColumn command = new AlterTableAlterColumn(session, schema); - command.setType(AlterTableAlterColumn.ADD); - command.setTable(table); - String columnName = readColumnIdentifier(); - Column column = parseColumnForTable(columnName, true); - command.setNewColumn(column); - if (readIf("BEFORE")) { - command.setAddBefore(readColumnIdentifier()); - } - return command; - } - - private int parseAction() { - if (readIf("CASCADE")) { - return ConstraintReferential.CASCADE; - } else if (readIf("RESTRICT")) { - return ConstraintReferential.RESTRICT; - } else if (readIf("NO")) { - read("ACTION"); - return ConstraintReferential.RESTRICT; - } else { - read("SET"); - if (readIf("NULL")) { - return ConstraintReferential.SET_NULL; - } - read("DEFAULT"); - return ConstraintReferential.SET_DEFAULT; - } - } - - private Prepared parseAlterTableAddConstraintIf(String tableName, Schema schema) { - String constraintName = null, comment = null; - boolean ifNotExists = false; - if (readIf("CONSTRAINT")) { - ifNotExists = readIfNoExists(); - constraintName = readIdentifierWithSchema(schema.getName()); - checkSchema(schema); - comment = readCommentIf(); - } - if (readIf("PRIMARY")) { - read("KEY"); - AlterTableAddConstraint command = new AlterTableAddConstraint(session, schema, ifNotExists); - command.setType(AlterTableAddConstraint.PRIMARY_KEY); - command.setComment(comment); - command.setConstraintName(constraintName); - command.setTableName(tableName); - if (readIf("HASH")) { - command.setPrimaryKeyHash(true); - } - read("("); - command.setIndexColumns(parseIndexColumnList()); - if (readIf("INDEX")) { - String indexName = readIdentifierWithSchema(); - command.setIndex(getSchema().findIndex(session, indexName)); - } - return command; - } else if (database.getMode().indexDefinitionInCreateTable && (readIf("INDEX") || readIf("KEY"))) { - // MySQL - CreateIndex command = new CreateIndex(session, schema); - command.setComment(comment); - command.setTableName(tableName); - if (!readIf("(")) { - command.setIndexName(readUniqueIdentifier()); - read("("); - } - command.setIndexColumns(parseIndexColumnList()); - return command; - } - AlterTableAddConstraint command; - if (readIf("CHECK")) { - command = new AlterTableAddConstraint(session, schema, ifNotExists); - command.setType(AlterTableAddConstraint.CHECK); - command.setCheckExpression(readExpression()); - } else if (readIf("UNIQUE")) { - readIf("KEY"); - readIf("INDEX"); - command = new AlterTableAddConstraint(session, schema, ifNotExists); - command.setType(AlterTableAddConstraint.UNIQUE); - if (!readIf("(")) { - constraintName = readUniqueIdentifier(); - read("("); - } - command.setIndexColumns(parseIndexColumnList()); - if (readIf("INDEX")) { - String indexName = readIdentifierWithSchema(); - command.setIndex(getSchema().findIndex(session, indexName)); - } - } else if (readIf("FOREIGN")) { - command = new AlterTableAddConstraint(session, schema, ifNotExists); - command.setType(AlterTableAddConstraint.REFERENTIAL); - read("KEY"); - read("("); - command.setIndexColumns(parseIndexColumnList()); - if (readIf("INDEX")) { - String indexName = readIdentifierWithSchema(); - command.setIndex(schema.findIndex(session, indexName)); - } - read("REFERENCES"); - parseReferences(command, schema, tableName); - } else { - if (constraintName != null) { - throw getSyntaxError(); - } - return null; - } - if (readIf("NOCHECK")) { - command.setCheckExisting(false); - } else { - readIf("CHECK"); - command.setCheckExisting(true); - } - command.setTableName(tableName); - command.setConstraintName(constraintName); - command.setComment(comment); - return command; - } - - private void parseReferences(AlterTableAddConstraint command, Schema schema, String tableName) { - if (readIf("(")) { - command.setRefTableName(schema, tableName); - command.setRefIndexColumns(parseIndexColumnList()); - } else { - String refTableName = readIdentifierWithSchema(schema.getName()); - command.setRefTableName(getSchema(), refTableName); - if (readIf("(")) { - command.setRefIndexColumns(parseIndexColumnList()); - } - } - if (readIf("INDEX")) { - String indexName = readIdentifierWithSchema(); - command.setRefIndex(getSchema().findIndex(session, indexName)); - } - while (readIf("ON")) { - if (readIf("DELETE")) { - command.setDeleteAction(parseAction()); - } else { - read("UPDATE"); - command.setUpdateAction(parseAction()); - } - } - if (readIf("NOT")) { - read("DEFERRABLE"); - } else { - readIf("DEFERRABLE"); - } - } - - private CreateLinkedTable parseCreateLinkedTable(boolean temp, boolean globalTemp, boolean force) { - read("TABLE"); - boolean ifNotExists = readIfNoExists(); - String tableName = readIdentifierWithSchema(); - CreateLinkedTable command = new CreateLinkedTable(session, getSchema()); - command.setTemporary(temp); - command.setGlobalTemporary(globalTemp); - command.setForce(force); - command.setIfNotExists(ifNotExists); - command.setTableName(tableName); - command.setComment(readCommentIf()); - read("("); - command.setDriver(readString()); - read(","); - command.setUrl(readString()); - read(","); - command.setUser(readString()); - read(","); - command.setPassword(readString()); - read(","); - String originalTable = readString(); - if (readIf(",")) { - command.setOriginalSchema(originalTable); - originalTable = readString(); - } - command.setOriginalTable(originalTable); - read(")"); - if (readIf("EMIT")) { - read("UPDATES"); - command.setEmitUpdates(true); - } else if (readIf("READONLY")) { - command.setReadOnly(true); - } - return command; - } - - private CreateTable parseCreateTable(boolean temp, boolean globalTemp, boolean persistIndexes) { - boolean ifNotExists = readIfNoExists(); - String tableName = readIdentifierWithSchema(); - if (temp && globalTemp && equalsToken("SESSION", schemaName)) { - // support weird syntax: declare global temporary table session.xy - // (...) not logged - schemaName = session.getCurrentSchemaName(); - globalTemp = false; - } - Schema schema = getSchema(); - CreateTable command = new CreateTable(session, schema); - command.setPersistIndexes(persistIndexes); - command.setTemporary(temp); - command.setGlobalTemporary(globalTemp); - command.setIfNotExists(ifNotExists); - command.setTableName(tableName); - command.setComment(readCommentIf()); - if (readIf("AS")) { - if (readIf("SORTED")) { - command.setSortedInsertMode(true); - } - command.setQuery(parseSelect()); - } else { - read("("); - if (!readIf(")")) { - do { - Prepared c = parseAlterTableAddConstraintIf(tableName, schema); - if (c != null) { - command.addConstraintCommand(c); - } else { - String columnName = readColumnIdentifier(); - Column column = parseColumnForTable(columnName, true); - if (column.isAutoIncrement() && column.isPrimaryKey()) { - column.setPrimaryKey(false); - IndexColumn[] cols = { new IndexColumn() }; - cols[0].columnName = column.getName(); - AlterTableAddConstraint pk = new AlterTableAddConstraint(session, schema, false); - pk.setType(AlterTableAddConstraint.PRIMARY_KEY); - pk.setTableName(tableName); - pk.setIndexColumns(cols); - command.addConstraintCommand(pk); - } - command.addColumn(column); - String constraintName = null; - if (readIf("CONSTRAINT")) { - constraintName = readColumnIdentifier(); - } - if (readIf("PRIMARY")) { - read("KEY"); - boolean hash = readIf("HASH"); - IndexColumn[] cols = { new IndexColumn() }; - cols[0].columnName = column.getName(); - AlterTableAddConstraint pk = new AlterTableAddConstraint(session, schema, false); - pk.setPrimaryKeyHash(hash); - pk.setType(AlterTableAddConstraint.PRIMARY_KEY); - pk.setTableName(tableName); - pk.setIndexColumns(cols); - command.addConstraintCommand(pk); - if (readIf("AUTO_INCREMENT")) { - parseAutoIncrement(column); - } - } else if (readIf("UNIQUE")) { - AlterTableAddConstraint unique = new AlterTableAddConstraint(session, schema, false); - unique.setConstraintName(constraintName); - unique.setType(AlterTableAddConstraint.UNIQUE); - IndexColumn[] cols = { new IndexColumn() }; - cols[0].columnName = columnName; - unique.setIndexColumns(cols); - unique.setTableName(tableName); - command.addConstraintCommand(unique); - } - if (readIf("NOT")) { - read("NULL"); - column.setNullable(false); - } else { - readIf("NULL"); - } - if (readIf("CHECK")) { - Expression expr = readExpression(); - column.addCheckConstraint(session, expr); - } - if (readIf("REFERENCES")) { - AlterTableAddConstraint ref = new AlterTableAddConstraint(session, schema, false); - ref.setConstraintName(constraintName); - ref.setType(AlterTableAddConstraint.REFERENTIAL); - IndexColumn[] cols = { new IndexColumn() }; - cols[0].columnName = columnName; - ref.setIndexColumns(cols); - ref.setTableName(tableName); - parseReferences(ref, schema, tableName); - command.addConstraintCommand(ref); - } - } - } while (readIfMore()); - } - if (readIf("AS")) { - if (readIf("SORTED")) { - command.setSortedInsertMode(true); - } - command.setQuery(parseSelect()); - } - } - if (readIf("ENGINE")) { - command.setTableEngine(readUniqueIdentifier()); - } - if (temp) { - if (readIf("ON")) { - read("COMMIT"); - if (readIf("DROP")) { - command.setOnCommitDrop(); - } else if (readIf("DELETE")) { - read("ROWS"); - command.setOnCommitTruncate(); - } - } else if (readIf("NOT")) { - if (readIf("PERSISTENT")) { - command.setPersistData(false); - } else { - read("LOGGED"); - } - } - } else if (!persistIndexes && readIf("NOT")) { - read("PERSISTENT"); - command.setPersistData(false); - } - if (readIf("HIDDEN")) { - command.setHidden(true); - } - return command; - } - - private int getCompareType(int tokenType) { - switch (tokenType) { - case EQUAL: - return Comparison.EQUAL; - case BIGGER_EQUAL: - return Comparison.BIGGER_EQUAL; - case BIGGER: - return Comparison.BIGGER; - case SMALLER: - return Comparison.SMALLER; - case SMALLER_EQUAL: - return Comparison.SMALLER_EQUAL; - case NOT_EQUAL: - return Comparison.NOT_EQUAL; - default: - return -1; - } - } - - /** - * Add double quotes around an identifier if required. - * - * @param s the identifier - * @return the quoted identifier - */ - public static String quoteIdentifier(String s) { - if (s == null || s.length() == 0) { - return "\"\""; - } - char c = s.charAt(0); - // lowercase a-z is quoted as well - if ((!Character.isLetter(c) && c != '_') || Character.isLowerCase(c)) { - return StringUtils.quoteIdentifier(s); - } - for (int i = 0; i < s.length(); i++) { - c = s.charAt(i); - if ((!Character.isLetterOrDigit(c) && c != '_') || Character.isLowerCase(c)) { - return StringUtils.quoteIdentifier(s); - } - } - if (Parser.isKeyword(s, true)) { - return StringUtils.quoteIdentifier(s); - } - return s; - } - - public void setRightsChecked(boolean rightsChecked) { - this.rightsChecked = rightsChecked; - } - - /** - * Parse a SQL code snippet that represents an expression. - * - * @param sql the code snippet - * @return the expression object - * @throws SQLException if the code snippet could not be parsed - */ - public Expression parseExpression(String sql) { - parameters = New.arrayList(); - initialize(sql); - read(); - return readExpression(); - } - -} diff --git a/tools/h2/src/main/org/h2/command/Prepared.java b/tools/h2/src/main/org/h2/command/Prepared.java deleted file mode 100755 index 5f48d5f..0000000 --- a/tools/h2/src/main/org/h2/command/Prepared.java +++ /dev/null @@ -1,413 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.command; - -import java.util.ArrayList; -import org.h2.constant.ErrorCode; -import org.h2.constant.SysProperties; -import org.h2.engine.Database; -import org.h2.engine.Session; -import org.h2.expression.Expression; -import org.h2.expression.Parameter; -import org.h2.message.DbException; -import org.h2.result.ResultInterface; -import org.h2.util.StatementBuilder; -import org.h2.value.Value; - -/** - * A prepared statement. - */ -public abstract class Prepared { - - /** - * The session. - */ - protected Session session; - - /** - * The SQL string. - */ - protected String sqlStatement; - - /** - * Whether to create a new object (for indexes). - */ - protected boolean create = true; - - /** - * The list of parameters. - */ - protected ArrayList parameters; - - /** - * If the query should be prepared before each execution. This is set for - * queries with LIKE ?, because the query plan depends on the parameter - * value. - */ - protected boolean prepareAlways; - - private long modificationMetaId; - private Command command; - private int objectId; - private int currentRowNumber; - private int rowScanCount; - - /** - * Create a new object. - * - * @param session the session - */ - public Prepared(Session session) { - this.session = session; - modificationMetaId = session.getDatabase().getModificationMetaId(); - } - - /** - * Check if this command is transactional. - * If it is not, then it forces the current transaction to commit. - * - * @return true if it is - */ - public abstract boolean isTransactional(); - - /** - * Get an empty result set containing the meta data. - * - * @return the result set - */ - public abstract ResultInterface queryMeta(); - - /** - * Check if this command is read only. - * - * @return true if it is - */ - public boolean isReadOnly() { - return false; - } - - /** - * Check if the statement needs to be re-compiled. - * - * @return true if it must - */ - public boolean needRecompile() { - Database db = session.getDatabase(); - if (db == null) { - throw DbException.get(ErrorCode.CONNECTION_BROKEN_1, "database closed"); - } - // parser: currently, compiling every create/drop/... twice - // because needRecompile return true even for the first execution - return SysProperties.RECOMPILE_ALWAYS || prepareAlways || modificationMetaId < db.getModificationMetaId(); - } - - /** - * Get the meta data modification id of the database when this statement was - * compiled. - * - * @return the meta data modification id - */ - long getModificationMetaId() { - return modificationMetaId; - } - - /** - * Set the meta data modification id of this statement. - * - * @param id the new id - */ - void setModificationMetaId(long id) { - this.modificationMetaId = id; - } - - /** - * Set the parameter list of this statement. - * - * @param parameters the parameter list - */ - public void setParameterList(ArrayList parameters) { - this.parameters = parameters; - } - - /** - * Get the parameter list. - * - * @return the parameter list - */ - public ArrayList getParameters() { - return parameters; - } - - /** - * Check if all parameters have been set. - * - * @throws SQLException if any parameter has not been set - */ - protected void checkParameters() { - for (int i = 0; parameters != null && i < parameters.size(); i++) { - Parameter param = parameters.get(i); - param.checkSet(); - } - } - - /** - * Set the command. - * - * @param command the new command - */ - public void setCommand(Command command) { - this.command = command; - } - - /** - * Check if this object is a query. - * - * @return true if it is - */ - public boolean isQuery() { - return false; - } - - /** - * Prepare this statement. - * - * @throws SQLException - */ - public void prepare() { - // nothing to do - } - - /** - * Execute the statement. - * - * @return the update count - * @throws SQLException if it is a query - */ - public int update() { - throw DbException.get(ErrorCode.METHOD_NOT_ALLOWED_FOR_QUERY); - } - - /** - * Execute the query. - * - * @param maxrows the maximum number of rows to return - * @return the result set - * @throws SQLException if it is not a query - */ - public ResultInterface query(int maxrows) { - throw DbException.get(ErrorCode.METHOD_ONLY_ALLOWED_FOR_QUERY); - } - - /** - * Set the SQL statement. - * - * @param sql the SQL statement - */ - public void setSQL(String sql) { - this.sqlStatement = sql; - } - - /** - * Get the SQL statement. - * - * @return the SQL statement - */ - public String getSQL() { - return sqlStatement; - } - - /** - * Get the object id to use for the database object that is created in this - * statement. This id is only set when the object is persistent. - * If not set, this method returns 0. - * - * @return the object id or 0 if not set - */ - protected int getCurrentObjectId() { - return objectId; - } - - /** - * Get the current object id, or get a new id from the database. The object - * id is used when creating new database object (CREATE statement). - * - * @return the object id - */ - protected int getObjectId() { - int id = objectId; - if (id == 0) { - id = session.getDatabase().allocateObjectId(); - } else { - objectId = 0; - } - return id; - } - - /** - * Get the SQL statement with the execution plan. - * - * @return the execution plan - */ - public String getPlanSQL() { - return null; - } - - /** - * Check if this statement was canceled. - * - * @throws SQLException if it was canceled - */ - public void checkCanceled() { - session.checkCanceled(); - Command c = command != null ? command : session.getCurrentCommand(); - if (c != null) { - c.checkCanceled(); - } - } - - /** - * Set the object id for this statement. - * - * @param i the object id - */ - public void setObjectId(int i) { - this.objectId = i; - this.create = false; - } - - /** - * Set the session for this statement. - * - * @param currentSession the new session - */ - public void setSession(Session currentSession) { - this.session = currentSession; - } - - /** - * Print information about the statement executed if info trace level is - * enabled. - * - * @param startTime when the statement was started - * @param count the update count - */ - void trace(long startTime, int count) { - if (session.getTrace().isInfoEnabled()) { - long time = System.currentTimeMillis() - startTime; - String params; - if (parameters.size() > 0) { - StatementBuilder buff = new StatementBuilder(" {"); - int i = 0; - for (Expression e : parameters) { - buff.appendExceptFirst(", "); - Value v = e.getValue(session); - buff.append(++i).append(": ").append(v.getTraceSQL()); - } - params = buff.append('}').toString(); - } else { - params = ""; - } - session.getTrace().infoSQL(sqlStatement, params, count, time); - } - } - - /** - * Set the prepare always flag. - * If set, the statement is re-compiled whenever it is executed. - * - * @param prepareAlways the new value - */ - public void setPrepareAlways(boolean prepareAlways) { - this.prepareAlways = prepareAlways; - } - - /** - * Set the current row number. - * - * @param rowNumber the row number - */ - protected void setCurrentRowNumber(int rowNumber) { - if ((++rowScanCount & 127) == 0) { - checkCanceled(); - } - this.currentRowNumber = rowNumber; - } - - /** - * Get the current row number. - * - * @return the row number - */ - public int getCurrentRowNumber() { - return currentRowNumber; - } - - /** - * Convert the statement to a String. - * - * @return the SQL statement - */ - public String toString() { - return sqlStatement; - } - - /** - * Get the SQL snippet of the value list. - * - * @param values the value list - * @return the SQL snippet - */ - protected String getSQL(Value[] values) { - StatementBuilder buff = new StatementBuilder(); - for (Value v : values) { - buff.appendExceptFirst(", "); - if (v != null) { - buff.append(v.getSQL()); - } - } - return buff.toString(); - } - - /** - * Get the SQL snippet of the expression list. - * - * @param list the expression list - * @return the SQL snippet - */ - protected String getSQL(Expression[] list) { - StatementBuilder buff = new StatementBuilder(); - for (Expression e : list) { - buff.appendExceptFirst(", "); - if (e != null) { - buff.append(e.getSQL()); - } - } - return buff.toString(); - } - - /** - * Set the SQL statement of the exception to the given row. - * - * @param e the exception - * @param rowId the row number - * @param values the values of the row - * @return the exception - */ - protected DbException setRow(DbException e, int rowId, String values) { - StringBuilder buff = new StringBuilder(); - if (sqlStatement != null) { - buff.append(sqlStatement); - } - buff.append(" -- "); - if (rowId > 0) { - buff.append("row #").append(rowId + 1).append(' '); - } - buff.append('(').append(values).append(')'); - return e.addSQL(buff.toString()); - } - -} diff --git a/tools/h2/src/main/org/h2/command/ddl/AlterIndexRename.java b/tools/h2/src/main/org/h2/command/ddl/AlterIndexRename.java deleted file mode 100755 index 22e0ede..0000000 --- a/tools/h2/src/main/org/h2/command/ddl/AlterIndexRename.java +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.command.ddl; - -import org.h2.constant.ErrorCode; -import org.h2.engine.Database; -import org.h2.engine.Right; -import org.h2.engine.Session; -import org.h2.index.Index; -import org.h2.message.DbException; -import org.h2.schema.Schema; - -/** - * This class represents the statement - * ALTER INDEX RENAME - */ -public class AlterIndexRename extends DefineCommand { - - private Index oldIndex; - private String newIndexName; - - public AlterIndexRename(Session session) { - super(session); - } - - public void setOldIndex(Index index) { - oldIndex = index; - } - - public void setNewName(String name) { - newIndexName = name; - } - - public int update() { - session.commit(true); - Database db = session.getDatabase(); - Schema schema = oldIndex.getSchema(); - if (schema.findIndex(session, newIndexName) != null || newIndexName.equals(oldIndex.getName())) { - throw DbException.get(ErrorCode.INDEX_ALREADY_EXISTS_1, newIndexName); - } - session.getUser().checkRight(oldIndex.getTable(), Right.ALL); - db.renameSchemaObject(session, oldIndex, newIndexName); - return 0; - } - -} diff --git a/tools/h2/src/main/org/h2/command/ddl/AlterTableAddConstraint.java b/tools/h2/src/main/org/h2/command/ddl/AlterTableAddConstraint.java deleted file mode 100755 index 6b2e466..0000000 --- a/tools/h2/src/main/org/h2/command/ddl/AlterTableAddConstraint.java +++ /dev/null @@ -1,415 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.command.ddl; - -import java.util.ArrayList; -import java.util.HashSet; -import org.h2.constant.ErrorCode; -import org.h2.constraint.Constraint; -import org.h2.constraint.ConstraintCheck; -import org.h2.constraint.ConstraintReferential; -import org.h2.constraint.ConstraintUnique; -import org.h2.engine.Constants; -import org.h2.engine.Database; -import org.h2.engine.Right; -import org.h2.engine.Session; -import org.h2.expression.Expression; -import org.h2.index.Index; -import org.h2.index.IndexType; -import org.h2.message.DbException; -import org.h2.schema.Schema; -import org.h2.table.Column; -import org.h2.table.IndexColumn; -import org.h2.table.Table; -import org.h2.table.TableFilter; -import org.h2.util.New; - -/** - * This class represents the statement - * ALTER TABLE ADD CONSTRAINT - */ -public class AlterTableAddConstraint extends SchemaCommand { - - /** - * The type of a ALTER TABLE ADD CHECK statement. - */ - public static final int CHECK = 0; - - /** - * The type of a ALTER TABLE ADD UNIQUE statement. - */ - public static final int UNIQUE = 1; - - /** - * The type of a ALTER TABLE ADD FOREIGN KEY statement. - */ - public static final int REFERENTIAL = 2; - - /** - * The type of a ALTER TABLE ADD PRIMARY KEY statement. - */ - public static final int PRIMARY_KEY = 3; - - private int type; - private String constraintName; - private String tableName; - private IndexColumn[] indexColumns; - private int deleteAction; - private int updateAction; - private Schema refSchema; - private String refTableName; - private IndexColumn[] refIndexColumns; - private Expression checkExpression; - private Index index, refIndex; - private String comment; - private boolean checkExisting; - private boolean primaryKeyHash; - private boolean ifNotExists; - - public AlterTableAddConstraint(Session session, Schema schema, boolean ifNotExists) { - super(session, schema); - this.ifNotExists = ifNotExists; - } - - private String generateConstraintName(Table table) { - if (constraintName == null) { - constraintName = getSchema().getUniqueConstraintName(session, table); - } - return constraintName; - } - - public int update() { - try { - return tryUpdate(); - } finally { - getSchema().freeUniqueName(constraintName); - } - } - - /** - * Try to execute the statement. - * - * @return the update count - */ - public int tryUpdate() { - session.commit(true); - Database db = session.getDatabase(); - Table table = getSchema().getTableOrView(session, tableName); - if (getSchema().findConstraint(session, constraintName) != null) { - if (ifNotExists) { - return 0; - } - throw DbException.get(ErrorCode.CONSTRAINT_ALREADY_EXISTS_1, constraintName); - } - session.getUser().checkRight(table, Right.ALL); - table.lock(session, true, true); - Constraint constraint; - switch (type) { - case PRIMARY_KEY: { - IndexColumn.mapColumns(indexColumns, table); - index = table.findPrimaryKey(); - ArrayList constraints = table.getConstraints(); - for (int i = 0; constraints != null && i < constraints.size(); i++) { - Constraint c = constraints.get(i); - if (Constraint.PRIMARY_KEY.equals(c.getConstraintType())) { - throw DbException.get(ErrorCode.SECOND_PRIMARY_KEY); - } - } - if (index != null) { - // if there is an index, it must match with the one declared - // we don't test ascending / descending - IndexColumn[] pkCols = index.getIndexColumns(); - if (pkCols.length != indexColumns.length) { - throw DbException.get(ErrorCode.SECOND_PRIMARY_KEY); - } - for (int i = 0; i < pkCols.length; i++) { - if (pkCols[i].column != indexColumns[i].column) { - throw DbException.get(ErrorCode.SECOND_PRIMARY_KEY); - } - } - } - if (index == null) { - IndexType indexType = IndexType.createPrimaryKey(table.isPersistIndexes(), primaryKeyHash); - String indexName = table.getSchema().getUniqueIndexName(session, table, Constants.PREFIX_PRIMARY_KEY); - int id = getObjectId(); - try { - index = table.addIndex(session, indexName, id, indexColumns, indexType, true, null); - } finally { - getSchema().freeUniqueName(indexName); - } - } - index.getIndexType().setBelongsToConstraint(true); - int constraintId = getObjectId(); - String name = generateConstraintName(table); - ConstraintUnique pk = new ConstraintUnique(getSchema(), constraintId, name, table, true); - pk.setColumns(indexColumns); - pk.setIndex(index, true); - constraint = pk; - break; - } - case UNIQUE: { - IndexColumn.mapColumns(indexColumns, table); - boolean isOwner = false; - if (index != null && canUseUniqueIndex(index, table, indexColumns)) { - isOwner = true; - index.getIndexType().setBelongsToConstraint(true); - } else { - index = getUniqueIndex(table, indexColumns); - if (index == null) { - index = createIndex(table, indexColumns, true); - isOwner = true; - } - } - int id = getObjectId(); - String name = generateConstraintName(table); - ConstraintUnique unique = new ConstraintUnique(getSchema(), id, name, table, false); - unique.setColumns(indexColumns); - unique.setIndex(index, isOwner); - constraint = unique; - break; - } - case CHECK: { - int id = getObjectId(); - String name = generateConstraintName(table); - ConstraintCheck check = new ConstraintCheck(getSchema(), id, name, table); - TableFilter filter = new TableFilter(session, table, null, false, null); - checkExpression.mapColumns(filter, 0); - checkExpression = checkExpression.optimize(session); - check.setExpression(checkExpression); - check.setTableFilter(filter); - constraint = check; - if (checkExisting) { - check.checkExistingData(session); - } - break; - } - case REFERENTIAL: { - Table refTable = refSchema.getTableOrView(session, refTableName); - session.getUser().checkRight(refTable, Right.ALL); - if (!refTable.canReference()) { - throw DbException.get(ErrorCode.FEATURE_NOT_SUPPORTED_1, "Reference " + refTable.getSQL()); - } - boolean isOwner = false; - IndexColumn.mapColumns(indexColumns, table); - if (index != null && canUseIndex(index, table, indexColumns)) { - isOwner = true; - index.getIndexType().setBelongsToConstraint(true); - } else { - index = getIndex(table, indexColumns); - if (index == null) { - index = createIndex(table, indexColumns, false); - isOwner = true; - } - } - if (refIndexColumns == null) { - Index refIdx = refTable.getPrimaryKey(); - refIndexColumns = refIdx.getIndexColumns(); - } else { - IndexColumn.mapColumns(refIndexColumns, refTable); - } - if (refIndexColumns.length != indexColumns.length) { - throw DbException.get(ErrorCode.COLUMN_COUNT_DOES_NOT_MATCH); - } - boolean isRefOwner = false; - if (refIndex != null && refIndex.getTable() == refTable) { - isRefOwner = true; - refIndex.getIndexType().setBelongsToConstraint(true); - } else { - refIndex = null; - } - if (refIndex == null) { - refIndex = getUniqueIndex(refTable, refIndexColumns); - if (refIndex == null) { - refIndex = createIndex(refTable, refIndexColumns, true); - isRefOwner = true; - } - } - int id = getObjectId(); - String name = generateConstraintName(table); - ConstraintReferential ref = new ConstraintReferential(getSchema(), id, name, table); - ref.setColumns(indexColumns); - ref.setIndex(index, isOwner); - ref.setRefTable(refTable); - ref.setRefColumns(refIndexColumns); - ref.setRefIndex(refIndex, isRefOwner); - if (checkExisting) { - ref.checkExistingData(session); - } - constraint = ref; - refTable.addConstraint(constraint); - ref.setDeleteAction(deleteAction); - ref.setUpdateAction(updateAction); - break; - } - default: - throw DbException.throwInternalError("type=" + type); - } - // parent relationship is already set with addConstraint - constraint.setComment(comment); - if (table.isTemporary() && !table.isGlobalTemporary()) { - session.addLocalTempTableConstraint(constraint); - } else { - db.addSchemaObject(session, constraint); - } - table.addConstraint(constraint); - return 0; - } - - private Index createIndex(Table t, IndexColumn[] cols, boolean unique) { - int indexId = getObjectId(); - IndexType indexType; - if (unique) { - // for unique constraints - indexType = IndexType.createUnique(t.isPersistIndexes(), false); - } else { - // constraints - indexType = IndexType.createNonUnique(t.isPersistIndexes()); - } - indexType.setBelongsToConstraint(true); - String prefix = constraintName == null ? "CONSTRAINT" : constraintName; - String indexName = t.getSchema().getUniqueIndexName(session, t, prefix + "_INDEX_"); - try { - return t.addIndex(session, indexName, indexId, cols, indexType, true, null); - } finally { - getSchema().freeUniqueName(indexName); - } - } - - public void setDeleteAction(int action) { - this.deleteAction = action; - } - - public void setUpdateAction(int action) { - this.updateAction = action; - } - - private Index getUniqueIndex(Table t, IndexColumn[] cols) { - for (Index idx : t.getIndexes()) { - if (canUseUniqueIndex(idx, t, cols)) { - return idx; - } - } - return null; - } - - private Index getIndex(Table t, IndexColumn[] cols) { - for (Index idx : t.getIndexes()) { - if (canUseIndex(idx, t, cols)) { - return idx; - } - } - return null; - } - - private boolean canUseUniqueIndex(Index idx, Table table, IndexColumn[] cols) { - if (idx.getTable() != table || !idx.getIndexType().isUnique()) { - return false; - } - Column[] indexCols = idx.getColumns(); - if (indexCols.length > cols.length) { - return false; - } - HashSet set = New.hashSet(); - for (IndexColumn c : cols) { - set.add(c.column); - } - for (Column c : indexCols) { - // all columns of the index must be part of the list, - // but not all columns of the list need to be part of the index - if (!set.contains(c)) { - return false; - } - } - return true; - } - - private boolean canUseIndex(Index existingIndex, Table table, IndexColumn[] cols) { - if (existingIndex.getTable() != table || existingIndex.getCreateSQL() == null) { - // can't use the scan index or index of another table - return false; - } - Column[] indexCols = existingIndex.getColumns(); - if (indexCols.length < cols.length) { - return false; - } - for (IndexColumn col : cols) { - // all columns of the list must be part of the index, - // but not all columns of the index need to be part of the list - // holes are not allowed (index=a,b,c & list=a,b is ok; but list=a,c - // is not) - int idx = existingIndex.getColumnIndex(col.column); - if (idx < 0 || idx >= cols.length) { - return false; - } - } - return true; - } - - public void setConstraintName(String constraintName) { - this.constraintName = constraintName; - } - - public void setType(int type) { - this.type = type; - } - - public int getType() { - return type; - } - - public void setCheckExpression(Expression expression) { - this.checkExpression = expression; - } - - public void setTableName(String tableName) { - this.tableName = tableName; - } - - public void setIndexColumns(IndexColumn[] indexColumns) { - this.indexColumns = indexColumns; - } - - public IndexColumn[] getIndexColumns() { - return indexColumns; - } - - /** - * Set the referenced table. - * - * @param refSchema the schema - * @param ref the table name - */ - public void setRefTableName(Schema refSchema, String ref) { - this.refSchema = refSchema; - this.refTableName = ref; - } - - public void setRefIndexColumns(IndexColumn[] indexColumns) { - this.refIndexColumns = indexColumns; - } - - public void setIndex(Index index) { - this.index = index; - } - - public void setRefIndex(Index refIndex) { - this.refIndex = refIndex; - } - - public void setComment(String comment) { - this.comment = comment; - } - - public void setCheckExisting(boolean b) { - this.checkExisting = b; - } - - public void setPrimaryKeyHash(boolean b) { - this.primaryKeyHash = b; - } - -} diff --git a/tools/h2/src/main/org/h2/command/ddl/AlterTableAlterColumn.java b/tools/h2/src/main/org/h2/command/ddl/AlterTableAlterColumn.java deleted file mode 100755 index 6e80bcc..0000000 --- a/tools/h2/src/main/org/h2/command/ddl/AlterTableAlterColumn.java +++ /dev/null @@ -1,491 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.command.ddl; - -import java.util.ArrayList; -import java.util.List; -import org.h2.command.Parser; -import org.h2.command.Prepared; -import org.h2.constant.ErrorCode; -import org.h2.constraint.Constraint; -import org.h2.constraint.ConstraintReferential; -import org.h2.engine.Database; -import org.h2.engine.DbObject; -import org.h2.engine.Right; -import org.h2.engine.Session; -import org.h2.expression.Expression; -import org.h2.index.Index; -import org.h2.index.IndexType; -import org.h2.message.DbException; -import org.h2.result.ResultInterface; -import org.h2.schema.Schema; -import org.h2.schema.SchemaObject; -import org.h2.schema.Sequence; -import org.h2.schema.TriggerObject; -import org.h2.table.Column; -import org.h2.table.Table; -import org.h2.table.TableView; -import org.h2.util.New; - -/** - * This class represents the statements - * ALTER TABLE ADD, - * ALTER TABLE ALTER COLUMN, - * ALTER TABLE ALTER COLUMN RESTART, - * ALTER TABLE ALTER COLUMN SELECTIVITY, - * ALTER TABLE ALTER COLUMN SET DEFAULT, - * ALTER TABLE ALTER COLUMN SET NOT NULL, - * ALTER TABLE ALTER COLUMN SET NULL, - * ALTER TABLE DROP COLUMN - */ -public class AlterTableAlterColumn extends SchemaCommand { - - /** - * The type of a ALTER TABLE ALTER COLUMN SET NOT NULL statement. - */ - public static final int NOT_NULL = 0; - - /** - * The type of a ALTER TABLE ALTER COLUMN SET NULL statement. - */ - public static final int NULL = 1; - - /** - * The type of a ALTER TABLE ALTER COLUMN SET DEFAULT statement. - */ - public static final int DEFAULT = 2; - - /** - * The type of a ALTER TABLE ALTER COLUMN statement that changes the column - * data type. - */ - public static final int CHANGE_TYPE = 3; - - /** - * The type of a ALTER TABLE ADD statement. - */ - public static final int ADD = 4; - - /** - * The type of a ALTER TABLE DROP COLUMN statement. - */ - public static final int DROP = 5; - - /** - * The type of a ALTER TABLE ALTER COLUMN SELECTIVITY statement. - */ - public static final int SELECTIVITY = 6; - - private Table table; - private Column oldColumn; - private Column newColumn; - private int type; - private Expression defaultExpression; - private Expression newSelectivity; - private String addBefore; - - public AlterTableAlterColumn(Session session, Schema schema) { - super(session, schema); - } - - public void setTable(Table table) { - this.table = table; - } - - public void setOldColumn(Column oldColumn) { - this.oldColumn = oldColumn; - } - - public void setAddBefore(String before) { - this.addBefore = before; - } - - public int update() { - session.commit(true); - Database db = session.getDatabase(); - session.getUser().checkRight(table, Right.ALL); - table.checkSupportAlter(); - table.lock(session, true, true); - Sequence sequence = oldColumn == null ? null : oldColumn.getSequence(); - switch (type) { - case NOT_NULL: { - if (!oldColumn.isNullable()) { - // no change - break; - } - checkNoNullValues(); - oldColumn.setNullable(false); - db.update(session, table); - break; - } - case NULL: { - if (oldColumn.isNullable()) { - // no change - break; - } - checkNullable(); - oldColumn.setNullable(true); - db.update(session, table); - break; - } - case DEFAULT: { - oldColumn.setSequence(null); - oldColumn.setDefaultExpression(session, defaultExpression); - removeSequence(sequence); - db.update(session, table); - break; - } - case CHANGE_TYPE: { - oldColumn.setSequence(null); - oldColumn.setDefaultExpression(session, null); - oldColumn.setConvertNullToDefault(false); - if (oldColumn.isNullable() && !newColumn.isNullable()) { - checkNoNullValues(); - } else if (!oldColumn.isNullable() && newColumn.isNullable()) { - checkNullable(); - } - convertAutoIncrementColumn(newColumn); - copyData(); - break; - } - case ADD: { - convertAutoIncrementColumn(newColumn); - copyData(); - break; - } - case DROP: { - if (table.getColumns().length == 1) { - throw DbException.get(ErrorCode.CANNOT_DROP_LAST_COLUMN, oldColumn.getSQL()); - } - table.checkColumnIsNotReferenced(oldColumn); - dropSingleColumnIndexes(); - copyData(); - break; - } - case SELECTIVITY: { - int value = newSelectivity.optimize(session).getValue(session).getInt(); - oldColumn.setSelectivity(value); - db.update(session, table); - break; - } - default: - DbException.throwInternalError("type=" + type); - } - return 0; - } - - private void convertAutoIncrementColumn(Column c) { - if (c.isAutoIncrement()) { - if (c.isPrimaryKey()) { - c.setOriginalSQL("IDENTITY"); - } else { - int objId = getObjectId(); - c.convertAutoIncrementToSequence(session, getSchema(), objId, table.isTemporary()); - } - } - } - - private void removeSequence(Sequence sequence) { - if (sequence != null) { - table.removeSequence(session, sequence); - sequence.setBelongsToTable(false); - Database db = session.getDatabase(); - db.removeSchemaObject(session, sequence); - } - } - - private void copyData() { - if (table.isTemporary()) { - throw DbException.getUnsupportedException("TEMP TABLE"); - } - Database db = session.getDatabase(); - String tempName = db.getTempTableName(session); - Column[] columns = table.getColumns(); - ArrayList newColumns = New.arrayList(); - Table newTable = cloneTableStructure(columns, db, tempName, newColumns); - List views; - try { - views = checkViews(table, newTable); - } catch (DbException e) { - execute("DROP TABLE " + newTable.getName(), true); - throw DbException.get(ErrorCode.VIEW_IS_INVALID_2, e, getSQL(), e.getMessage()); - } - String tableName = table.getName(); - execute("DROP TABLE " + table.getSQL(), true); - db.renameSchemaObject(session, newTable, tableName); - for (DbObject child : newTable.getChildren()) { - if (child instanceof Sequence) { - continue; - } - String name = child.getName(); - if (name == null || child.getCreateSQL() == null) { - continue; - } - if (name.startsWith(tempName + "_")) { - name = name.substring(tempName.length() + 1); - SchemaObject so = (SchemaObject) child; - if (so instanceof Constraint) { - if (so.getSchema().findConstraint(session, name) != null) { - name = so.getSchema().getUniqueConstraintName(session, newTable); - } - } else if (so instanceof Index) { - if (so.getSchema().findIndex(session, name) != null) { - name = so.getSchema().getUniqueIndexName(session, newTable, name); - } - } - db.renameSchemaObject(session, so, name); - } - } - for (String view : views) { - execute(view, true); - } - } - - private Table cloneTableStructure(Column[] columns, Database db, String tempName, ArrayList newColumns) { - for (Column col : columns) { - newColumns.add(col.getClone()); - } - if (type == DROP) { - int position = oldColumn.getColumnId(); - newColumns.remove(position); - } else if (type == ADD) { - int position; - if (addBefore == null) { - position = columns.length; - } else { - position = table.getColumn(addBefore).getColumnId(); - } - newColumns.add(position, newColumn); - } else if (type == CHANGE_TYPE) { - int position = oldColumn.getColumnId(); - newColumns.remove(position); - newColumns.add(position, newColumn); - } - - // create a table object in order to get the SQL statement - // can't just use this table, because most column objects are 'shared' - // with the old table - // still need a new id because using 0 would mean: the new table tries - // to use the rows of the table 0 (the meta table) - int id = db.allocateObjectId(); - CreateTableData data = new CreateTableData(); - data.tableName = tempName; - data.id = id; - data.columns = newColumns; - data.temporary = table.isTemporary(); - data.persistData = table.isPersistData(); - data.persistIndexes = table.isPersistIndexes(); - data.create = true; - data.session = session; - Table newTable = getSchema().createTable(data); - newTable.setComment(table.getComment()); - StringBuilder buff = new StringBuilder(); - buff.append(newTable.getCreateSQL()); - StringBuilder columnList = new StringBuilder(); - for (Column nc : newColumns) { - if (columnList.length() > 0) { - columnList.append(", "); - } - if (type == ADD && nc == newColumn) { - Expression def = nc.getDefaultExpression(); - columnList.append(def == null ? "NULL" : def.getSQL()); - } else { - columnList.append(nc.getSQL()); - } - } - buff.append(" AS SELECT "); - if (columnList.length() == 0) { - // special case: insert into test select * from - buff.append('*'); - } else { - buff.append(columnList); - } - buff.append(" FROM ").append(table.getSQL()); - String newTableSQL = buff.toString(); - String newTableName = newTable.getName(); - Schema newTableSchema = newTable.getSchema(); - newTable.removeChildrenAndResources(session); - - execute(newTableSQL, true); - newTable = newTableSchema.getTableOrView(session, newTableName); - ArrayList triggers = New.arrayList(); - for (DbObject child : table.getChildren()) { - if (child instanceof Sequence) { - continue; - } else if (child instanceof Index) { - Index idx = (Index) child; - if (idx.getIndexType().getBelongsToConstraint()) { - continue; - } - } - String createSQL = child.getCreateSQL(); - if (createSQL == null) { - continue; - } - if (child instanceof TableView) { - continue; - } else if (child.getType() == DbObject.TABLE_OR_VIEW) { - DbException.throwInternalError(); - } - String quotedName = Parser.quoteIdentifier(tempName + "_" + child.getName()); - String sql = null; - if (child instanceof ConstraintReferential) { - ConstraintReferential r = (ConstraintReferential) child; - if (r.getTable() != table) { - sql = r.getCreateSQLForCopy(r.getTable(), newTable, quotedName, false); - } - } - if (sql == null) { - sql = child.getCreateSQLForCopy(newTable, quotedName); - } - if (sql != null) { - if (child instanceof TriggerObject) { - triggers.add(sql); - } else { - execute(sql, true); - } - } - } - table.setModified(); - // remove the sequences from the columns (except dropped columns) - // otherwise the sequence is dropped if the table is dropped - for (Column col : newColumns) { - Sequence seq = col.getSequence(); - if (seq != null) { - table.removeSequence(session, seq); - col.setSequence(null); - } - } - for (String sql : triggers) { - execute(sql, true); - } - return newTable; - } - - /** - * Check that all views are still valid. - * - * @param the list of SQL statements to re-create views that depend on this table - */ - private List checkViews(SchemaObject sourceTable, SchemaObject newTable) { - List viewSql = new ArrayList(); - String sourceTableName = sourceTable.getName(); - String newTableName = newTable.getName(); - Database db = sourceTable.getDatabase(); - // save the real table under a temporary name - db.renameSchemaObject(session, sourceTable, db.getTempTableName(session)); - try { - // have our new table impersonate the target table - db.renameSchemaObject(session, newTable, sourceTableName); - checkViewsAreValid(sourceTable, viewSql); - } finally { - // always put the source tables back with their proper names - try { - db.renameSchemaObject(session, newTable, newTableName); - } finally { - db.renameSchemaObject(session, sourceTable, sourceTableName); - } - } - return viewSql; - } - - /** - * Check that a table or view is still valid. - * - * @param tableOrView the table or view to check - * @param recreate the list of SQL statements to re-create views that depend - * on this table - */ - private void checkViewsAreValid(DbObject tableOrView, List recreate) { - for (DbObject view : tableOrView.getChildren()) { - if (view instanceof TableView) { - String sql = ((TableView) view).getQuery(); - // check if the query is still valid - // do not execute, not even with limit 1, because that could - // have side effects or take a very long time - session.prepare(sql); - recreate.add(view.getDropSQL()); - recreate.add(view.getCreateSQL()); - checkViewsAreValid(view, recreate); - } - } - } - - private void execute(String sql, boolean ddl) { - Prepared command = session.prepare(sql); - command.update(); - if (ddl) { - session.commit(true); - } - } - - private void dropSingleColumnIndexes() { - Database db = session.getDatabase(); - ArrayList indexes = table.getIndexes(); - for (int i = 0; i < indexes.size(); i++) { - Index index = indexes.get(i); - if (index.getCreateSQL() == null) { - continue; - } - boolean dropIndex = false; - Column[] cols = index.getColumns(); - for (Column c : cols) { - if (c == oldColumn) { - if (cols.length == 1) { - dropIndex = true; - } else { - throw DbException.get(ErrorCode.COLUMN_IS_PART_OF_INDEX_1, index.getSQL()); - } - } - } - if (dropIndex) { - db.removeSchemaObject(session, index); - indexes = table.getIndexes(); - i = -1; - } - } - } - - private void checkNullable() { - for (Index index : table.getIndexes()) { - if (index.getColumnIndex(oldColumn) < 0) { - continue; - } - IndexType indexType = index.getIndexType(); - if (indexType.isPrimaryKey() || indexType.isHash()) { - throw DbException.get(ErrorCode.COLUMN_IS_PART_OF_INDEX_1, index.getSQL()); - } - } - } - - private void checkNoNullValues() { - String sql = "SELECT COUNT(*) FROM " + table.getSQL() + " WHERE " + oldColumn.getSQL() + " IS NULL"; - Prepared command = session.prepare(sql); - ResultInterface result = command.query(0); - result.next(); - if (result.currentRow()[0].getInt() > 0) { - throw DbException.get(ErrorCode.COLUMN_CONTAINS_NULL_VALUES_1, oldColumn.getSQL()); - } - } - - public void setType(int type) { - this.type = type; - } - - public void setSelectivity(Expression selectivity) { - newSelectivity = selectivity; - } - - public void setDefaultExpression(Expression defaultExpression) { - this.defaultExpression = defaultExpression; - } - - public void setNewColumn(Column newColumn) { - this.newColumn = newColumn; - } - -} diff --git a/tools/h2/src/main/org/h2/command/ddl/AlterTableDropConstraint.java b/tools/h2/src/main/org/h2/command/ddl/AlterTableDropConstraint.java deleted file mode 100755 index 428d9ca..0000000 --- a/tools/h2/src/main/org/h2/command/ddl/AlterTableDropConstraint.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.command.ddl; - -import org.h2.constant.ErrorCode; -import org.h2.constraint.Constraint; -import org.h2.engine.Right; -import org.h2.engine.Session; -import org.h2.message.DbException; -import org.h2.schema.Schema; - -/** - * This class represents the statement - * ALTER TABLE DROP CONSTRAINT - */ -public class AlterTableDropConstraint extends SchemaCommand { - - private String constraintName; - private boolean ifExists; - - public AlterTableDropConstraint(Session session, Schema schema, boolean ifExists) { - super(session, schema); - this.ifExists = ifExists; - } - - public void setConstraintName(String string) { - constraintName = string; - } - - public int update() { - session.commit(true); - Constraint constraint = getSchema().findConstraint(session, constraintName); - if (constraint == null) { - if (!ifExists) { - throw DbException.get(ErrorCode.CONSTRAINT_NOT_FOUND_1, constraintName); - } - } else { - session.getUser().checkRight(constraint.getTable(), Right.ALL); - session.getUser().checkRight(constraint.getRefTable(), Right.ALL); - session.getDatabase().removeSchemaObject(session, constraint); - } - return 0; - } - -} diff --git a/tools/h2/src/main/org/h2/command/ddl/AlterTableRename.java b/tools/h2/src/main/org/h2/command/ddl/AlterTableRename.java deleted file mode 100755 index 8d046d8..0000000 --- a/tools/h2/src/main/org/h2/command/ddl/AlterTableRename.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.command.ddl; - -import org.h2.constant.ErrorCode; -import org.h2.engine.Database; -import org.h2.engine.Right; -import org.h2.engine.Session; -import org.h2.message.DbException; -import org.h2.schema.Schema; -import org.h2.table.Table; - -/** - * This class represents the statement - * ALTER TABLE RENAME - */ -public class AlterTableRename extends SchemaCommand { - - private Table oldTable; - private String newTableName; - - public AlterTableRename(Session session, Schema schema) { - super(session, schema); - } - - public void setOldTable(Table table) { - oldTable = table; - } - - public void setNewTableName(String name) { - newTableName = name; - } - - public int update() { - session.commit(true); - Database db = session.getDatabase(); - if (getSchema().findTableOrView(session, newTableName) != null || newTableName.equals(oldTable.getName())) { - throw DbException.get(ErrorCode.TABLE_OR_VIEW_ALREADY_EXISTS_1, newTableName); - } - session.getUser().checkRight(oldTable, Right.ALL); - if (oldTable.isTemporary()) { - throw DbException.getUnsupportedException("TEMP TABLE"); - } - db.renameSchemaObject(session, oldTable, newTableName); - return 0; - } - -} diff --git a/tools/h2/src/main/org/h2/command/ddl/AlterTableRenameColumn.java b/tools/h2/src/main/org/h2/command/ddl/AlterTableRenameColumn.java deleted file mode 100755 index 45447ad..0000000 --- a/tools/h2/src/main/org/h2/command/ddl/AlterTableRenameColumn.java +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.command.ddl; - -import org.h2.engine.Database; -import org.h2.engine.DbObject; -import org.h2.engine.Right; -import org.h2.engine.Session; -import org.h2.table.Column; -import org.h2.table.Table; - -/** - * This class represents the statement - * ALTER TABLE ALTER COLUMN RENAME - */ -public class AlterTableRenameColumn extends DefineCommand { - - private Table table; - private Column column; - private String newName; - - public AlterTableRenameColumn(Session session) { - super(session); - } - - public void setTable(Table table) { - this.table = table; - } - - public void setColumn(Column column) { - this.column = column; - } - - public void setNewColumnName(String newName) { - this.newName = newName; - } - - public int update() { - session.commit(true); - Database db = session.getDatabase(); - session.getUser().checkRight(table, Right.ALL); - table.checkSupportAlter(); - table.renameColumn(column, newName); - table.setModified(); - db.update(session, table); - for (DbObject child : table.getChildren()) { - if (child.getCreateSQL() != null) { - db.update(session, child); - } - } - return 0; - } - -} diff --git a/tools/h2/src/main/org/h2/command/ddl/AlterUser.java b/tools/h2/src/main/org/h2/command/ddl/AlterUser.java deleted file mode 100755 index e02a446..0000000 --- a/tools/h2/src/main/org/h2/command/ddl/AlterUser.java +++ /dev/null @@ -1,128 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.command.ddl; - -import org.h2.constant.ErrorCode; -import org.h2.engine.Database; -import org.h2.engine.Session; -import org.h2.engine.User; -import org.h2.expression.Expression; -import org.h2.message.DbException; -import org.h2.security.SHA256; -import org.h2.util.Utils; - -/** - * This class represents the statements - * ALTER USER ADMIN, - * ALTER USER RENAME, - * ALTER USER SET PASSWORD - */ -public class AlterUser extends DefineCommand { - - /** - * The command type to set the password. - */ - public static final int SET_PASSWORD = 0; - - /** - * The command type to rename the user. - */ - public static final int RENAME = 1; - - /** - * The command type to change the admin flag. - */ - public static final int ADMIN = 2; - - private int type; - private User user; - private String newName; - private Expression password; - private Expression salt; - private Expression hash; - private boolean admin; - - public AlterUser(Session session) { - super(session); - } - - public void setType(int type) { - this.type = type; - } - - public void setNewName(String newName) { - this.newName = newName; - } - - public void setUser(User user) { - this.user = user; - } - - public void setAdmin(boolean admin) { - this.admin = admin; - } - - public void setSalt(Expression e) { - salt = e; - } - - public void setHash(Expression e) { - hash = e; - } - - public void setPassword(Expression password) { - this.password = password; - } - - private char[] getCharArray(Expression e) { - return e.optimize(session).getValue(session).getString().toCharArray(); - } - - private byte[] getByteArray(Expression e) { - return Utils.convertStringToBytes(e.optimize(session).getValue(session).getString()); - } - - public int update() { - session.commit(true); - Database db = session.getDatabase(); - switch (type) { - case SET_PASSWORD: - if (user != session.getUser()) { - session.getUser().checkAdmin(); - } - if (hash != null && salt != null) { - user.setSaltAndHash(getByteArray(salt), getByteArray(hash)); - } else { - String name = newName == null ? user.getName() : newName; - SHA256 sha = new SHA256(); - char[] passwordChars = getCharArray(password); - byte[] userPasswordHash = sha.getKeyPasswordHash(name, passwordChars); - user.setUserPasswordHash(userPasswordHash); - } - break; - case RENAME: - session.getUser().checkAdmin(); - if (db.findUser(newName) != null || newName.equals(user.getName())) { - throw DbException.get(ErrorCode.USER_ALREADY_EXISTS_1, newName); - } - db.renameDatabaseObject(session, user, newName); - break; - case ADMIN: - session.getUser().checkAdmin(); - if (!admin) { - user.checkOwnsNoSchemas(); - } - user.setAdmin(admin); - break; - default: - DbException.throwInternalError("type=" + type); - } - db.update(session, user); - return 0; - } - -} diff --git a/tools/h2/src/main/org/h2/command/ddl/AlterView.java b/tools/h2/src/main/org/h2/command/ddl/AlterView.java deleted file mode 100755 index 62b9680..0000000 --- a/tools/h2/src/main/org/h2/command/ddl/AlterView.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.command.ddl; - -import org.h2.engine.Right; -import org.h2.engine.Session; -import org.h2.table.TableView; - -/** - * This class represents the statement - * ALTER VIEW - */ -public class AlterView extends DefineCommand { - - private TableView view; - - public AlterView(Session session) { - super(session); - } - - public void setView(TableView view) { - this.view = view; - } - - public int update() { - session.commit(true); - session.getUser().checkRight(view, Right.ALL); - view.recompile(session); - return 0; - } - -} diff --git a/tools/h2/src/main/org/h2/command/ddl/Analyze.java b/tools/h2/src/main/org/h2/command/ddl/Analyze.java deleted file mode 100755 index 914f554..0000000 --- a/tools/h2/src/main/org/h2/command/ddl/Analyze.java +++ /dev/null @@ -1,112 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.command.ddl; - -import org.h2.command.Prepared; -import org.h2.constant.SysProperties; -import org.h2.engine.Database; -import org.h2.engine.Right; -import org.h2.engine.Session; -import org.h2.result.ResultInterface; -import org.h2.table.Column; -import org.h2.table.RegularTable; -import org.h2.table.Table; -import org.h2.util.StatementBuilder; - -/** - * This class represents the statement - * ANALYZE - */ -public class Analyze extends DefineCommand { - - /** - * The sample size. - */ - private int sampleRows = SysProperties.ANALYZE_SAMPLE; - - public Analyze(Session session) { - super(session); - } - - public int update() { - session.commit(true); - session.getUser().checkAdmin(); - Database db = session.getDatabase(); - // TODO do we need to lock the table? - for (Table table : db.getAllTablesAndViews(false)) { - analyzeTable(session, table, sampleRows, true); - } - return 0; - } - - /** - * Analyze this table. - * - * @param session the session - * @param table the table - * @param sample the number of sample rows - * @param manual whether the command was called by the user - */ - public static void analyzeTable(Session session, Table table, int sample, boolean manual) { - if (!(table instanceof RegularTable) || table.isHidden() || session == null) { - return; - } - if (!manual) { - if (session.getDatabase().isSysTableLocked()) { - return; - } - if (table.hasSelectTrigger()) { - return; - } - } - if (table.isTemporary() && !table.isGlobalTemporary() - && session.findLocalTempTable(table.getName()) == null) { - return; - } - if (table.isLockedExclusively() && !table.isLockedExclusivelyBy(session)) { - return; - } - if (!session.getUser().hasRight(table, Right.SELECT)) { - return; - } - if (session.getCancel() != 0) { - // if the connection is closed and there is something to undo - return; - } - Database db = session.getDatabase(); - StatementBuilder buff = new StatementBuilder("SELECT "); - Column[] columns = table.getColumns(); - for (Column col : columns) { - buff.appendExceptFirst(", "); - buff.append("SELECTIVITY(").append(col.getSQL()).append(')'); - } - buff.append(" FROM ").append(table.getSQL()); - if (sample > 0) { - buff.append(" LIMIT 1 SAMPLE_SIZE ").append(sample); - } - String sql = buff.toString(); - Prepared command = session.prepare(sql); - ResultInterface result = command.query(0); - result.next(); - for (int j = 0; j < columns.length; j++) { - int selectivity = result.currentRow()[j].getInt(); - columns[j].setSelectivity(selectivity); - } - if (manual) { - db.update(session, table); - } else { - Session s = db.getSystemSession(); - db.update(s, table); - s.commit(true); - } - } - - public void setTop(int top) { - this.sampleRows = top; - } - -} diff --git a/tools/h2/src/main/org/h2/command/ddl/CreateAggregate.java b/tools/h2/src/main/org/h2/command/ddl/CreateAggregate.java deleted file mode 100755 index da3a940..0000000 --- a/tools/h2/src/main/org/h2/command/ddl/CreateAggregate.java +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.command.ddl; - -import org.h2.constant.ErrorCode; -import org.h2.engine.Database; -import org.h2.engine.Session; -import org.h2.engine.UserAggregate; -import org.h2.message.DbException; -import org.h2.schema.Schema; - -/** - * This class represents the statement - * CREATE AGGREGATE - */ -public class CreateAggregate extends DefineCommand { - - private Schema schema; - private String name; - private String javaClassMethod; - private boolean ifNotExists; - private boolean force; - - public CreateAggregate(Session session) { - super(session); - } - - public int update() { - session.commit(true); - session.getUser().checkAdmin(); - Database db = session.getDatabase(); - if (db.findAggregate(name) != null || schema.findFunction(name) != null) { - if (!ifNotExists) { - throw DbException.get(ErrorCode.FUNCTION_ALIAS_ALREADY_EXISTS_1, name); - } - } else { - int id = getObjectId(); - UserAggregate aggregate = new UserAggregate(db, id, name, javaClassMethod, force); - db.addDatabaseObject(session, aggregate); - } - return 0; - } - - public void setSchema(Schema schema) { - this.schema = schema; - } - - public void setName(String name) { - this.name = name; - } - - public void setJavaClassMethod(String string) { - this.javaClassMethod = string; - } - - public void setIfNotExists(boolean ifNotExists) { - this.ifNotExists = ifNotExists; - } - - public void setForce(boolean force) { - this.force = force; - } - -} diff --git a/tools/h2/src/main/org/h2/command/ddl/CreateConstant.java b/tools/h2/src/main/org/h2/command/ddl/CreateConstant.java deleted file mode 100755 index 24b3a58..0000000 --- a/tools/h2/src/main/org/h2/command/ddl/CreateConstant.java +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.command.ddl; - -import org.h2.constant.ErrorCode; -import org.h2.engine.Database; -import org.h2.engine.Session; -import org.h2.expression.Expression; -import org.h2.message.DbException; -import org.h2.schema.Constant; -import org.h2.schema.Schema; -import org.h2.value.Value; - -/** - * This class represents the statement - * CREATE CONSTANT - */ -public class CreateConstant extends SchemaCommand { - - private String constantName; - private Expression expression; - private boolean ifNotExists; - - public CreateConstant(Session session, Schema schema) { - super(session, schema); - } - - public void setIfNotExists(boolean ifNotExists) { - this.ifNotExists = ifNotExists; - } - - public int update() { - session.commit(true); - session.getUser().checkAdmin(); - Database db = session.getDatabase(); - if (getSchema().findConstant(constantName) != null) { - if (ifNotExists) { - return 0; - } - throw DbException.get(ErrorCode.CONSTANT_ALREADY_EXISTS_1, constantName); - } - int id = getObjectId(); - Constant constant = new Constant(getSchema(), id, constantName); - expression = expression.optimize(session); - Value value = expression.getValue(session); - constant.setValue(value); - db.addSchemaObject(session, constant); - return 0; - } - - public void setConstantName(String constantName) { - this.constantName = constantName; - } - - public void setExpression(Expression expr) { - this.expression = expr; - } - -} diff --git a/tools/h2/src/main/org/h2/command/ddl/CreateFunctionAlias.java b/tools/h2/src/main/org/h2/command/ddl/CreateFunctionAlias.java deleted file mode 100755 index 9f42dcd..0000000 --- a/tools/h2/src/main/org/h2/command/ddl/CreateFunctionAlias.java +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.command.ddl; - -import org.h2.constant.ErrorCode; -import org.h2.engine.Database; -import org.h2.engine.FunctionAlias; -import org.h2.engine.Session; -import org.h2.message.DbException; -import org.h2.schema.Schema; -import org.h2.util.StringUtils; - -/** - * This class represents the statement - * CREATE ALIAS - */ -public class CreateFunctionAlias extends SchemaCommand { - - private String aliasName; - private String javaClassMethod; - private boolean deterministic; - private boolean ifNotExists; - private boolean force; - private String source; - - public CreateFunctionAlias(Session session, Schema schema) { - super(session, schema); - } - - public int update() { - session.commit(true); - session.getUser().checkAdmin(); - Database db = session.getDatabase(); - if (getSchema().findFunction(aliasName) != null) { - if (!ifNotExists) { - throw DbException.get(ErrorCode.FUNCTION_ALIAS_ALREADY_EXISTS_1, aliasName); - } - } else { - int id = getObjectId(); - FunctionAlias functionAlias; - if (javaClassMethod != null) { - functionAlias = FunctionAlias.newInstance(getSchema(), id, aliasName, javaClassMethod, force); - } else { - functionAlias = FunctionAlias.newInstanceFromSource(getSchema(), id, aliasName, source, force); - } - functionAlias.setDeterministic(deterministic); - db.addSchemaObject(session, functionAlias); - } - return 0; - } - - public void setAliasName(String name) { - this.aliasName = name; - } - - /** - * Set the qualified method name after removing whitespace. - * - * @param method the qualified method name - */ - public void setJavaClassMethod(String method) { - this.javaClassMethod = StringUtils.replaceAll(method, " ", ""); - } - - public void setIfNotExists(boolean ifNotExists) { - this.ifNotExists = ifNotExists; - } - - public void setForce(boolean force) { - this.force = force; - } - - public void setDeterministic(boolean deterministic) { - this.deterministic = deterministic; - } - - public void setSource(String source) { - this.source = source; - } - -} diff --git a/tools/h2/src/main/org/h2/command/ddl/CreateIndex.java b/tools/h2/src/main/org/h2/command/ddl/CreateIndex.java deleted file mode 100755 index 9eef2c5..0000000 --- a/tools/h2/src/main/org/h2/command/ddl/CreateIndex.java +++ /dev/null @@ -1,109 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.command.ddl; - -import org.h2.constant.ErrorCode; -import org.h2.engine.Constants; -import org.h2.engine.Database; -import org.h2.engine.Right; -import org.h2.engine.Session; -import org.h2.index.IndexType; -import org.h2.message.DbException; -import org.h2.schema.Schema; -import org.h2.table.IndexColumn; -import org.h2.table.Table; - -/** - * This class represents the statement - * CREATE INDEX - */ -public class CreateIndex extends SchemaCommand { - - private String tableName; - private String indexName; - private IndexColumn[] indexColumns; - private boolean primaryKey, unique, hash; - private boolean ifNotExists; - private String comment; - - public CreateIndex(Session session, Schema schema) { - super(session, schema); - } - - public void setIfNotExists(boolean ifNotExists) { - this.ifNotExists = ifNotExists; - } - - public void setTableName(String tableName) { - this.tableName = tableName; - } - - public void setIndexName(String indexName) { - this.indexName = indexName; - } - - public void setIndexColumns(IndexColumn[] columns) { - this.indexColumns = columns; - } - - public int update() { - session.commit(true); - Database db = session.getDatabase(); - boolean persistent = db.isPersistent(); - Table table = getSchema().getTableOrView(session, tableName); - session.getUser().checkRight(table, Right.ALL); - table.lock(session, true, true); - if (!table.isPersistIndexes()) { - persistent = false; - } - int id = getObjectId(); - if (indexName == null) { - if (primaryKey) { - indexName = table.getSchema().getUniqueIndexName(session, table, Constants.PREFIX_PRIMARY_KEY); - } else { - indexName = table.getSchema().getUniqueIndexName(session, table, Constants.PREFIX_INDEX); - } - } - if (getSchema().findIndex(session, indexName) != null) { - if (ifNotExists) { - return 0; - } - throw DbException.get(ErrorCode.INDEX_ALREADY_EXISTS_1, indexName); - } - IndexType indexType; - if (primaryKey) { - if (table.findPrimaryKey() != null) { - throw DbException.get(ErrorCode.SECOND_PRIMARY_KEY); - } - indexType = IndexType.createPrimaryKey(persistent, hash); - } else if (unique) { - indexType = IndexType.createUnique(persistent, hash); - } else { - indexType = IndexType.createNonUnique(persistent, hash); - } - IndexColumn.mapColumns(indexColumns, table); - table.addIndex(session, indexName, id, indexColumns, indexType, create, comment); - return 0; - } - - public void setPrimaryKey(boolean b) { - this.primaryKey = b; - } - - public void setUnique(boolean b) { - this.unique = b; - } - - public void setHash(boolean b) { - this.hash = b; - } - - public void setComment(String comment) { - this.comment = comment; - } - -} diff --git a/tools/h2/src/main/org/h2/command/ddl/CreateLinkedTable.java b/tools/h2/src/main/org/h2/command/ddl/CreateLinkedTable.java deleted file mode 100755 index 5a4e48e..0000000 --- a/tools/h2/src/main/org/h2/command/ddl/CreateLinkedTable.java +++ /dev/null @@ -1,117 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.command.ddl; - -import org.h2.constant.ErrorCode; -import org.h2.engine.Database; -import org.h2.engine.Session; -import org.h2.message.DbException; -import org.h2.schema.Schema; -import org.h2.table.TableLink; - -/** - * This class represents the statement - * CREATE LINKED TABLE - */ -public class CreateLinkedTable extends SchemaCommand { - - private String tableName; - private String driver, url, user, password, originalSchema, originalTable; - private boolean ifNotExists; - private String comment; - private boolean emitUpdates; - private boolean force; - private boolean temporary; - private boolean globalTemporary; - private boolean readOnly; - - public CreateLinkedTable(Session session, Schema schema) { - super(session, schema); - } - - public void setTableName(String tableName) { - this.tableName = tableName; - } - - public void setDriver(String driver) { - this.driver = driver; - } - - public void setOriginalTable(String originalTable) { - this.originalTable = originalTable; - } - - public void setPassword(String password) { - this.password = password; - } - - public void setUrl(String url) { - this.url = url; - } - - public void setUser(String user) { - this.user = user; - } - - public void setIfNotExists(boolean ifNotExists) { - this.ifNotExists = ifNotExists; - } - - public int update() { - session.commit(true); - Database db = session.getDatabase(); - session.getUser().checkAdmin(); - if (getSchema().findTableOrView(session, tableName) != null) { - if (ifNotExists) { - return 0; - } - throw DbException.get(ErrorCode.TABLE_OR_VIEW_ALREADY_EXISTS_1, - tableName); - } - int id = getObjectId(); - TableLink table = getSchema().createTableLink(id, tableName, driver, url, user, password, originalSchema, originalTable, emitUpdates, force); - table.setTemporary(temporary); - table.setGlobalTemporary(globalTemporary); - table.setComment(comment); - table.setReadOnly(readOnly); - if (temporary && !globalTemporary) { - session.addLocalTempTable(table); - } else { - db.addSchemaObject(session, table); - } - return 0; - } - - public void setEmitUpdates(boolean emitUpdates) { - this.emitUpdates = emitUpdates; - } - - public void setComment(String comment) { - this.comment = comment; - } - - public void setForce(boolean force) { - this.force = force; - } - - public void setTemporary(boolean temp) { - this.temporary = temp; - } - - public void setGlobalTemporary(boolean globalTemp) { - this.globalTemporary = globalTemp; - } - - public void setReadOnly(boolean readOnly) { - this.readOnly = readOnly; - } - - public void setOriginalSchema(String originalSchema) { - this.originalSchema = originalSchema; - } - -} diff --git a/tools/h2/src/main/org/h2/command/ddl/CreateRole.java b/tools/h2/src/main/org/h2/command/ddl/CreateRole.java deleted file mode 100755 index a9249c6..0000000 --- a/tools/h2/src/main/org/h2/command/ddl/CreateRole.java +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.command.ddl; - -import org.h2.constant.ErrorCode; -import org.h2.engine.Database; -import org.h2.engine.Role; -import org.h2.engine.Session; -import org.h2.message.DbException; - -/** - * This class represents the statement - * CREATE ROLE - */ -public class CreateRole extends DefineCommand { - - private String roleName; - private boolean ifNotExists; - - public CreateRole(Session session) { - super(session); - } - - public void setIfNotExists(boolean ifNotExists) { - this.ifNotExists = ifNotExists; - } - - public void setRoleName(String name) { - this.roleName = name; - } - - public int update() { - session.getUser().checkAdmin(); - session.commit(true); - Database db = session.getDatabase(); - if (db.findUser(roleName) != null) { - throw DbException.get(ErrorCode.USER_ALREADY_EXISTS_1, roleName); - } - if (db.findRole(roleName) != null) { - if (ifNotExists) { - return 0; - } - throw DbException.get(ErrorCode.ROLE_ALREADY_EXISTS_1, roleName); - } - int id = getObjectId(); - Role role = new Role(db, id, roleName, false); - db.addDatabaseObject(session, role); - return 0; - } - -} diff --git a/tools/h2/src/main/org/h2/command/ddl/CreateSchema.java b/tools/h2/src/main/org/h2/command/ddl/CreateSchema.java deleted file mode 100755 index 1f2d588..0000000 --- a/tools/h2/src/main/org/h2/command/ddl/CreateSchema.java +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.command.ddl; - -import org.h2.constant.ErrorCode; -import org.h2.engine.Database; -import org.h2.engine.Session; -import org.h2.engine.User; -import org.h2.message.DbException; -import org.h2.schema.Schema; - -/** - * This class represents the statement - * CREATE SCHEMA - */ -public class CreateSchema extends DefineCommand { - - private String schemaName; - private String authorization; - private boolean ifNotExists; - - public CreateSchema(Session session) { - super(session); - } - - public void setIfNotExists(boolean ifNotExists) { - this.ifNotExists = ifNotExists; - } - - public int update() { - session.getUser().checkAdmin(); - session.commit(true); - Database db = session.getDatabase(); - User user = db.getUser(authorization); - user.checkAdmin(); - if (db.findSchema(schemaName) != null) { - if (ifNotExists) { - return 0; - } - throw DbException.get(ErrorCode.SCHEMA_ALREADY_EXISTS_1, schemaName); - } - int id = getObjectId(); - Schema schema = new Schema(db, id, schemaName, user, false); - db.addDatabaseObject(session, schema); - return 0; - } - - public void setSchemaName(String name) { - this.schemaName = name; - } - - public void setAuthorization(String userName) { - this.authorization = userName; - } - -} diff --git a/tools/h2/src/main/org/h2/command/ddl/CreateSequence.java b/tools/h2/src/main/org/h2/command/ddl/CreateSequence.java deleted file mode 100755 index 8584312..0000000 --- a/tools/h2/src/main/org/h2/command/ddl/CreateSequence.java +++ /dev/null @@ -1,83 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.command.ddl; - -import org.h2.constant.ErrorCode; -import org.h2.engine.Database; -import org.h2.engine.Session; -import org.h2.expression.Expression; -import org.h2.message.DbException; -import org.h2.schema.Schema; -import org.h2.schema.Sequence; - -/** - * This class represents the statement - * CREATE SEQUENCE - */ -public class CreateSequence extends SchemaCommand { - - private String sequenceName; - private boolean ifNotExists; - private Expression start; - private Expression increment; - private Expression cacheSize; - private boolean belongsToTable; - - public CreateSequence(Session session, Schema schema) { - super(session, schema); - } - - public void setSequenceName(String sequenceName) { - this.sequenceName = sequenceName; - } - - public void setIfNotExists(boolean ifNotExists) { - this.ifNotExists = ifNotExists; - } - - public int update() { - session.commit(true); - Database db = session.getDatabase(); - if (getSchema().findSequence(sequenceName) != null) { - if (ifNotExists) { - return 0; - } - throw DbException.get(ErrorCode.SEQUENCE_ALREADY_EXISTS_1, sequenceName); - } - int id = getObjectId(); - Sequence sequence = new Sequence(getSchema(), id, sequenceName, belongsToTable); - sequence.setStartValue(getLong(start, 1)); - sequence.setIncrement(getLong(increment, 1)); - sequence.setCacheSize(getLong(cacheSize, Sequence.DEFAULT_CACHE_SIZE)); - db.addSchemaObject(session, sequence); - return 0; - } - - private long getLong(Expression expr, long defaultValue) { - if (expr == null) { - return defaultValue; - } - return expr.optimize(session).getValue(session).getLong(); - } - - public void setStartWith(Expression start) { - this.start = start; - } - - public void setIncrement(Expression increment) { - this.increment = increment; - } - - public void setBelongsToTable(boolean belongsToTable) { - this.belongsToTable = belongsToTable; - } - - public void setCacheSize(Expression cacheSize) { - this.cacheSize = cacheSize; - } - -} diff --git a/tools/h2/src/main/org/h2/command/ddl/CreateTable.java b/tools/h2/src/main/org/h2/command/ddl/CreateTable.java deleted file mode 100755 index 2818987..0000000 --- a/tools/h2/src/main/org/h2/command/ddl/CreateTable.java +++ /dev/null @@ -1,277 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.command.ddl; - -import java.util.ArrayList; -import org.h2.command.Prepared; -import org.h2.command.dml.Insert; -import org.h2.command.dml.Query; -import org.h2.constant.ErrorCode; -import org.h2.engine.Database; -import org.h2.engine.Session; -import org.h2.expression.Expression; -import org.h2.message.DbException; -import org.h2.schema.Schema; -import org.h2.schema.Sequence; -import org.h2.table.Column; -import org.h2.table.IndexColumn; -import org.h2.table.Table; -import org.h2.util.New; -import org.h2.value.DataType; - -/** - * This class represents the statement - * CREATE TABLE - */ -public class CreateTable extends SchemaCommand { - - private CreateTableData data = new CreateTableData(); - private ArrayList constraintCommands = New.arrayList(); - private IndexColumn[] pkColumns; - private boolean ifNotExists; - private boolean onCommitDrop; - private boolean onCommitTruncate; - private Query asQuery; - private String comment; - private boolean sortedInsertMode; - - public CreateTable(Session session, Schema schema) { - super(session, schema); - data.persistIndexes = true; - data.persistData = true; - } - - public void setQuery(Query query) { - this.asQuery = query; - } - - public void setTemporary(boolean temporary) { - data.temporary = temporary; - } - - public void setTableName(String tableName) { - data.tableName = tableName; - } - - /** - * Add a column to this table. - * - * @param column the column to add - */ - public void addColumn(Column column) { - data.columns.add(column); - } - - /** - * Add a constraint statement to this statement. - * The primary key definition is one possible constraint statement. - * - * @param command the statement to add - */ - public void addConstraintCommand(Prepared command) { - if (command instanceof CreateIndex) { - constraintCommands.add(command); - } else { - AlterTableAddConstraint con = (AlterTableAddConstraint) command; - boolean alreadySet; - if (con.getType() == AlterTableAddConstraint.PRIMARY_KEY) { - alreadySet = setPrimaryKeyColumns(con.getIndexColumns()); - } else { - alreadySet = false; - } - if (!alreadySet) { - constraintCommands.add(command); - } - } - } - - public void setIfNotExists(boolean ifNotExists) { - this.ifNotExists = ifNotExists; - } - - public int update() { - session.commit(true); - Database db = session.getDatabase(); - if (!db.isPersistent()) { - data.persistIndexes = false; - } - if (getSchema().findTableOrView(session, data.tableName) != null) { - if (ifNotExists) { - return 0; - } - throw DbException.get(ErrorCode.TABLE_OR_VIEW_ALREADY_EXISTS_1, data.tableName); - } - if (asQuery != null) { - asQuery.prepare(); - if (data.columns.size() == 0) { - generateColumnsFromQuery(); - } else if (data.columns.size() != asQuery.getColumnCount()) { - throw DbException.get(ErrorCode.COLUMN_COUNT_DOES_NOT_MATCH); - } - } - if (pkColumns != null) { - for (Column c : data.columns) { - for (IndexColumn idxCol : pkColumns) { - if (c.getName().equals(idxCol.columnName)) { - c.setNullable(false); - } - } - } - } - ArrayList sequences = New.arrayList(); - for (Column c : data.columns) { - if (c.isAutoIncrement()) { - int objId = getObjectId(); - c.convertAutoIncrementToSequence(session, getSchema(), objId, data.temporary); - } - Sequence seq = c.getSequence(); - if (seq != null) { - sequences.add(seq); - } - } - data.id = getObjectId(); - data.create = create; - data.session = session; - Table table = getSchema().createTable(data); - table.setComment(comment); - if (data.temporary && !data.globalTemporary) { - if (onCommitDrop) { - table.setOnCommitDrop(true); - } - if (onCommitTruncate) { - table.setOnCommitTruncate(true); - } - session.addLocalTempTable(table); - } else { - db.addSchemaObject(session, table); - } - try { - for (Column c : data.columns) { - c.prepareExpression(session); - } - for (Sequence sequence : sequences) { - table.addSequence(sequence); - } - for (Prepared command : constraintCommands) { - command.update(); - } - if (asQuery != null) { - boolean old = session.isUndoLogEnabled(); - try { - session.setUndoLogEnabled(false); - Insert insert = null; - insert = new Insert(session); - insert.setSortedInsertMode(sortedInsertMode); - insert.setQuery(asQuery); - insert.setTable(table); - insert.prepare(); - insert.update(); - } finally { - session.setUndoLogEnabled(old); - } - } - } catch (DbException e) { - db.checkPowerOff(); - db.removeSchemaObject(session, table); - session.commit(true); - throw e; - } - return 0; - } - - private void generateColumnsFromQuery() { - int columnCount = asQuery.getColumnCount(); - ArrayList expressions = asQuery.getExpressions(); - for (int i = 0; i < columnCount; i++) { - Expression expr = expressions.get(i); - int type = expr.getType(); - String name = expr.getAlias(); - long precision = expr.getPrecision(); - int displaySize = expr.getDisplaySize(); - DataType dt = DataType.getDataType(type); - if (precision > 0 && (dt.defaultPrecision == 0 || (dt.defaultPrecision > precision && dt.defaultPrecision < Byte.MAX_VALUE))) { - // dont' set precision to MAX_VALUE if this is the default - precision = dt.defaultPrecision; - } - int scale = expr.getScale(); - if (scale > 0 && (dt.defaultScale == 0 || dt.defaultScale > scale)) { - scale = dt.defaultScale; - } - Column col = new Column(name, type, precision, scale, displaySize); - addColumn(col); - } - } - - /** - * Sets the primary key columns, but also check if a primary key - * with different columns is already defined. - * - * @param columns the primary key columns - * @return true if the same primary key columns where already set - */ - private boolean setPrimaryKeyColumns(IndexColumn[] columns) { - if (pkColumns != null) { - if (columns.length != pkColumns.length) { - throw DbException.get(ErrorCode.SECOND_PRIMARY_KEY); - } - for (int i = 0; i < columns.length; i++) { - if (!columns[i].columnName.equals(pkColumns[i].columnName)) { - throw DbException.get(ErrorCode.SECOND_PRIMARY_KEY); - } - } - return true; - } - this.pkColumns = columns; - return false; - } - - public void setPersistIndexes(boolean persistIndexes) { - data.persistIndexes = persistIndexes; - } - - public void setGlobalTemporary(boolean globalTemporary) { - data.globalTemporary = globalTemporary; - } - - /** - * This temporary table is dropped on commit. - */ - public void setOnCommitDrop() { - this.onCommitDrop = true; - } - - /** - * This temporary table is truncated on commit. - */ - public void setOnCommitTruncate() { - this.onCommitTruncate = true; - } - - public void setComment(String comment) { - this.comment = comment; - } - - public void setPersistData(boolean persistData) { - data.persistData = persistData; - if (!persistData) { - data.persistIndexes = false; - } - } - - public void setSortedInsertMode(boolean sortedInsertMode) { - this.sortedInsertMode = sortedInsertMode; - } - - public void setTableEngine(String tableEngine) { - data.tableEngine = tableEngine; - } - - public void setHidden(boolean isHidden) { - data.isHidden = isHidden; - } - -} diff --git a/tools/h2/src/main/org/h2/command/ddl/CreateTableData.java b/tools/h2/src/main/org/h2/command/ddl/CreateTableData.java deleted file mode 100755 index a428215..0000000 --- a/tools/h2/src/main/org/h2/command/ddl/CreateTableData.java +++ /dev/null @@ -1,80 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.command.ddl; - -import java.util.ArrayList; -import org.h2.engine.Session; -import org.h2.schema.Schema; -import org.h2.table.Column; -import org.h2.util.New; - -/** - * The data required to create a table. - */ -public class CreateTableData { - - /** - * The schema. - */ - public Schema schema; - - /** - * The table name. - */ - public String tableName; - - /** - * The object id. - */ - public int id; - - /** - * The column list. - */ - public ArrayList columns = New.arrayList(); - - /** - * Whether this is a temporary table. - */ - public boolean temporary; - - /** - * Whether the table is global temporary. - */ - public boolean globalTemporary; - - /** - * Whether the indexes should be persisted. - */ - public boolean persistIndexes; - - /** - * Whether the data should be persisted. - */ - public boolean persistData; - - /** - * Whether to create a new table. - */ - public boolean create; - - /** - * The session. - */ - public Session session; - - /** - * The table engine to use for creating the table. - */ - public String tableEngine; - - /** - * The table is hidden. - */ - public boolean isHidden; - -} diff --git a/tools/h2/src/main/org/h2/command/ddl/CreateTrigger.java b/tools/h2/src/main/org/h2/command/ddl/CreateTrigger.java deleted file mode 100755 index 49ada20..0000000 --- a/tools/h2/src/main/org/h2/command/ddl/CreateTrigger.java +++ /dev/null @@ -1,114 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.command.ddl; - -import org.h2.constant.ErrorCode; -import org.h2.engine.Database; -import org.h2.engine.Session; -import org.h2.message.DbException; -import org.h2.schema.Schema; -import org.h2.schema.TriggerObject; -import org.h2.table.Table; - -/** - * This class represents the statement - * CREATE TRIGGER - */ -public class CreateTrigger extends SchemaCommand { - - private String triggerName; - private boolean ifNotExists; - - private boolean insteadOf; - private boolean before; - private int typeMask; - private boolean rowBased; - private int queueSize = TriggerObject.DEFAULT_QUEUE_SIZE; - private boolean noWait; - private String tableName; - private String triggerClassName; - private boolean force; - private boolean onRollback; - - public CreateTrigger(Session session, Schema schema) { - super(session, schema); - } - - public void setInsteadOf(boolean insteadOf) { - this.insteadOf = insteadOf; - } - - public void setBefore(boolean before) { - this.before = before; - } - - public void setTriggerClassName(String triggerClassName) { - this.triggerClassName = triggerClassName; - } - - public void setTypeMask(int typeMask) { - this.typeMask = typeMask; - } - - public void setRowBased(boolean rowBased) { - this.rowBased = rowBased; - } - - public void setQueueSize(int size) { - this.queueSize = size; - } - - public void setNoWait(boolean noWait) { - this.noWait = noWait; - } - - public void setTableName(String tableName) { - this.tableName = tableName; - } - - public void setTriggerName(String name) { - this.triggerName = name; - } - - public void setIfNotExists(boolean ifNotExists) { - this.ifNotExists = ifNotExists; - } - - public int update() { - session.commit(true); - Database db = session.getDatabase(); - if (getSchema().findTrigger(triggerName) != null) { - if (ifNotExists) { - return 0; - } - throw DbException.get(ErrorCode.TRIGGER_ALREADY_EXISTS_1, triggerName); - } - int id = getObjectId(); - Table table = getSchema().getTableOrView(session, tableName); - TriggerObject trigger = new TriggerObject(getSchema(), id, triggerName, table); - trigger.setInsteadOf(insteadOf); - trigger.setBefore(before); - trigger.setNoWait(noWait); - trigger.setQueueSize(queueSize); - trigger.setRowBased(rowBased); - trigger.setTypeMask(typeMask); - trigger.setOnRollback(onRollback); - trigger.setTriggerClassName(session, triggerClassName, force); - db.addSchemaObject(session, trigger); - table.addTrigger(trigger); - return 0; - } - - public void setForce(boolean force) { - this.force = force; - } - - public void setOnRollback(boolean onRollback) { - this.onRollback = onRollback; - } - -} diff --git a/tools/h2/src/main/org/h2/command/ddl/CreateUser.java b/tools/h2/src/main/org/h2/command/ddl/CreateUser.java deleted file mode 100755 index 466f576..0000000 --- a/tools/h2/src/main/org/h2/command/ddl/CreateUser.java +++ /dev/null @@ -1,103 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.command.ddl; - -import org.h2.constant.ErrorCode; -import org.h2.engine.Database; -import org.h2.engine.Session; -import org.h2.engine.User; -import org.h2.expression.Expression; -import org.h2.message.DbException; -import org.h2.security.SHA256; -import org.h2.util.Utils; - -/** - * This class represents the statement - * CREATE USER - */ -public class CreateUser extends DefineCommand { - - private String userName; - private boolean admin; - private Expression password; - private Expression salt; - private Expression hash; - private boolean ifNotExists; - private String comment; - - public CreateUser(Session session) { - super(session); - } - - public void setIfNotExists(boolean ifNotExists) { - this.ifNotExists = ifNotExists; - } - - public void setUserName(String userName) { - this.userName = userName; - } - - public void setPassword(Expression password) { - this.password = password; - } - - private char[] getCharArray(Expression e) { - return e.optimize(session).getValue(session).getString().toCharArray(); - } - - private byte[] getByteArray(Expression e) { - return Utils.convertStringToBytes(e.optimize(session).getValue(session).getString()); - } - - public int update() { - session.getUser().checkAdmin(); - session.commit(true); - Database db = session.getDatabase(); - if (db.findRole(userName) != null) { - throw DbException.get(ErrorCode.ROLE_ALREADY_EXISTS_1, userName); - } - if (db.findUser(userName) != null) { - if (ifNotExists) { - return 0; - } - throw DbException.get(ErrorCode.USER_ALREADY_EXISTS_1, userName); - } - int id = getObjectId(); - User user = new User(db, id, userName, false); - user.setAdmin(admin); - user.setComment(comment); - if (hash != null && salt != null) { - user.setSaltAndHash(getByteArray(salt), getByteArray(hash)); - } else if (password != null) { - SHA256 sha = new SHA256(); - char[] passwordChars = getCharArray(password); - byte[] userPasswordHash = sha.getKeyPasswordHash(userName, passwordChars); - user.setUserPasswordHash(userPasswordHash); - } else { - throw DbException.throwInternalError(); - } - db.addDatabaseObject(session, user); - return 0; - } - - public void setSalt(Expression e) { - salt = e; - } - - public void setHash(Expression e) { - hash = e; - } - - public void setAdmin(boolean b) { - admin = b; - } - - public void setComment(String comment) { - this.comment = comment; - } - -} diff --git a/tools/h2/src/main/org/h2/command/ddl/CreateUserDataType.java b/tools/h2/src/main/org/h2/command/ddl/CreateUserDataType.java deleted file mode 100755 index 6ab141b..0000000 --- a/tools/h2/src/main/org/h2/command/ddl/CreateUserDataType.java +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.command.ddl; - -import org.h2.constant.ErrorCode; -import org.h2.engine.Database; -import org.h2.engine.Session; -import org.h2.engine.UserDataType; -import org.h2.message.DbException; -import org.h2.table.Column; -import org.h2.table.Table; -import org.h2.value.DataType; - -/** - * This class represents the statement - * CREATE DOMAIN - */ -public class CreateUserDataType extends DefineCommand { - - private String typeName; - private Column column; - private boolean ifNotExists; - - public CreateUserDataType(Session session) { - super(session); - } - - public void setTypeName(String name) { - this.typeName = name; - } - - public void setColumn(Column column) { - this.column = column; - } - - public void setIfNotExists(boolean ifNotExists) { - this.ifNotExists = ifNotExists; - } - - public int update() { - session.getUser().checkAdmin(); - session.commit(true); - Database db = session.getDatabase(); - session.getUser().checkAdmin(); - if (db.findUserDataType(typeName) != null) { - if (ifNotExists) { - return 0; - } - throw DbException.get(ErrorCode.USER_DATA_TYPE_ALREADY_EXISTS_1, typeName); - } - DataType builtIn = DataType.getTypeByName(typeName); - if (builtIn != null) { - if (!builtIn.hidden) { - throw DbException.get(ErrorCode.USER_DATA_TYPE_ALREADY_EXISTS_1, typeName); - } - Table table = session.getDatabase().getFirstUserTable(); - if (table != null) { - throw DbException.get(ErrorCode.USER_DATA_TYPE_ALREADY_EXISTS_1, typeName + " (" + table.getSQL() + ")"); - } - } - int id = getObjectId(); - UserDataType type = new UserDataType(db, id, typeName); - type.setColumn(column); - db.addDatabaseObject(session, type); - return 0; - } - -} diff --git a/tools/h2/src/main/org/h2/command/ddl/CreateView.java b/tools/h2/src/main/org/h2/command/ddl/CreateView.java deleted file mode 100755 index 2c30c66..0000000 --- a/tools/h2/src/main/org/h2/command/ddl/CreateView.java +++ /dev/null @@ -1,99 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.command.ddl; - -import org.h2.command.dml.Query; -import org.h2.constant.ErrorCode; -import org.h2.engine.Constants; -import org.h2.engine.Database; -import org.h2.engine.Session; -import org.h2.message.DbException; -import org.h2.schema.Schema; -import org.h2.table.TableView; - -/** - * This class represents the statement - * CREATE VIEW - */ -public class CreateView extends SchemaCommand { - - private Query select; - private String viewName; - private boolean ifNotExists; - private String selectSQL; - private String[] columnNames; - private String comment; - private boolean recursive; - - public CreateView(Session session, Schema schema) { - super(session, schema); - } - - public void setViewName(String name) { - viewName = name; - } - - public void setRecursive(boolean recursive) { - this.recursive = recursive; - } - - public void setSelect(Query select) { - this.select = select; - } - - public int update() { - session.commit(true); - Database db = session.getDatabase(); - if (getSchema().findTableOrView(session, viewName) != null) { - if (ifNotExists) { - return 0; - } - throw DbException.get(ErrorCode.VIEW_ALREADY_EXISTS_1, viewName); - } - int id = getObjectId(); - String querySQL; - if (select == null) { - querySQL = selectSQL; - } else { - querySQL = select.getSQL(); - } - Session sysSession = db.getSystemSession(); - TableView view; - try { - Schema schema = session.getDatabase().getSchema(session.getCurrentSchemaName()); - sysSession.setCurrentSchema(schema); - view = new TableView(getSchema(), id, viewName, querySQL, null, columnNames, sysSession, recursive); - } finally { - sysSession.setCurrentSchema(db.getSchema(Constants.SCHEMA_MAIN)); - } - view.setComment(comment); - try { - view.recompileQuery(session); - } catch (DbException e) { - // this is not strictly required - ignore exceptions, specially when using FORCE - } - db.addSchemaObject(session, view); - return 0; - } - - public void setIfNotExists(boolean ifNotExists) { - this.ifNotExists = ifNotExists; - } - - public void setSelectSQL(String selectSQL) { - this.selectSQL = selectSQL; - } - - public void setColumnNames(String[] cols) { - this.columnNames = cols; - } - - public void setComment(String comment) { - this.comment = comment; - } - -} diff --git a/tools/h2/src/main/org/h2/command/ddl/DeallocateProcedure.java b/tools/h2/src/main/org/h2/command/ddl/DeallocateProcedure.java deleted file mode 100755 index 83f603c..0000000 --- a/tools/h2/src/main/org/h2/command/ddl/DeallocateProcedure.java +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.command.ddl; - -import org.h2.engine.Session; - -/** - * This class represents the statement - * DEALLOCATE - */ -public class DeallocateProcedure extends DefineCommand { - - private String procedureName; - - public DeallocateProcedure(Session session) { - super(session); - } - - public int update() { - session.removeProcedure(procedureName); - return 0; - } - - public void setProcedureName(String name) { - this.procedureName = name; - } - -} diff --git a/tools/h2/src/main/org/h2/command/ddl/DefineCommand.java b/tools/h2/src/main/org/h2/command/ddl/DefineCommand.java deleted file mode 100755 index f2c112f..0000000 --- a/tools/h2/src/main/org/h2/command/ddl/DefineCommand.java +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.command.ddl; - -import org.h2.command.Prepared; -import org.h2.engine.Session; -import org.h2.result.ResultInterface; - -/** - * This class represents a non-transaction statement, for example a CREATE or - * DROP. - */ -public abstract class DefineCommand extends Prepared { - - /** - * Create a new command for the given session. - * - * @param session the session - */ - public DefineCommand(Session session) { - super(session); - } - - public boolean isTransactional() { - return false; - } - - public boolean isReadOnly() { - return false; - } - - public ResultInterface queryMeta() { - return null; - } - -} diff --git a/tools/h2/src/main/org/h2/command/ddl/DropAggregate.java b/tools/h2/src/main/org/h2/command/ddl/DropAggregate.java deleted file mode 100755 index 810d1f7..0000000 --- a/tools/h2/src/main/org/h2/command/ddl/DropAggregate.java +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.command.ddl; - -import org.h2.constant.ErrorCode; -import org.h2.engine.Database; -import org.h2.engine.Session; -import org.h2.engine.UserAggregate; -import org.h2.message.DbException; - -/** - * This class represents the statement - * DROP AGGREGATE - */ -public class DropAggregate extends DefineCommand { - - private String name; - private boolean ifExists; - - public DropAggregate(Session session) { - super(session); - } - - public int update() { - session.getUser().checkAdmin(); - session.commit(true); - Database db = session.getDatabase(); - UserAggregate aggregate = db.findAggregate(name); - if (aggregate == null) { - if (!ifExists) { - throw DbException.get(ErrorCode.AGGREGATE_NOT_FOUND_1, name); - } - } else { - db.removeDatabaseObject(session, aggregate); - } - return 0; - } - - public void setName(String name) { - this.name = name; - } - - public void setIfExists(boolean ifExists) { - this.ifExists = ifExists; - } - -} diff --git a/tools/h2/src/main/org/h2/command/ddl/DropConstant.java b/tools/h2/src/main/org/h2/command/ddl/DropConstant.java deleted file mode 100755 index 82b8338..0000000 --- a/tools/h2/src/main/org/h2/command/ddl/DropConstant.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.command.ddl; - -import org.h2.constant.ErrorCode; -import org.h2.engine.Database; -import org.h2.engine.Session; -import org.h2.message.DbException; -import org.h2.schema.Constant; -import org.h2.schema.Schema; - -/** - * This class represents the statement - * DROP CONSTANT - */ -public class DropConstant extends SchemaCommand { - - private String constantName; - private boolean ifExists; - - public DropConstant(Session session, Schema schema) { - super(session, schema); - } - - public void setIfExists(boolean b) { - ifExists = b; - } - - public void setConstantName(String constantName) { - this.constantName = constantName; - } - - public int update() { - session.getUser().checkAdmin(); - session.commit(true); - Database db = session.getDatabase(); - Constant constant = getSchema().findConstant(constantName); - if (constant == null) { - if (!ifExists) { - throw DbException.get(ErrorCode.CONSTANT_NOT_FOUND_1, constantName); - } - } else { - db.removeSchemaObject(session, constant); - } - return 0; - } - -} diff --git a/tools/h2/src/main/org/h2/command/ddl/DropDatabase.java b/tools/h2/src/main/org/h2/command/ddl/DropDatabase.java deleted file mode 100755 index 1b21283..0000000 --- a/tools/h2/src/main/org/h2/command/ddl/DropDatabase.java +++ /dev/null @@ -1,117 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.command.ddl; - -import java.util.ArrayList; -import org.h2.engine.Database; -import org.h2.engine.DbObject; -import org.h2.engine.Role; -import org.h2.engine.Session; -import org.h2.engine.User; -import org.h2.schema.Schema; -import org.h2.schema.SchemaObject; -import org.h2.table.Table; -import org.h2.util.New; - -/** - * This class represents the statement - * DROP ALL OBJECTS - */ -public class DropDatabase extends DefineCommand { - - private boolean dropAllObjects; - private boolean deleteFiles; - - public DropDatabase(Session session) { - super(session); - } - - public int update() { - if (dropAllObjects) { - dropAllObjects(); - } - if (deleteFiles) { - session.getDatabase().setDeleteFilesOnDisconnect(true); - } - return 0; - } - - private void dropAllObjects() { - session.getUser().checkAdmin(); - session.commit(true); - Database db = session.getDatabase(); - // TODO local temp tables are not removed - for (Schema schema : db.getAllSchemas()) { - if (schema.canDrop()) { - db.removeDatabaseObject(session, schema); - } - } - ArrayList tables = db.getAllTablesAndViews(false); - for (Table t : tables) { - if (t.getName() != null && Table.VIEW.equals(t.getTableType())) { - db.removeSchemaObject(session, t); - } - } - for (Table t : tables) { - if (t.getName() != null && Table.TABLE_LINK.equals(t.getTableType())) { - db.removeSchemaObject(session, t); - } - } - for (Table t : tables) { - if (t.getName() != null && Table.TABLE.equals(t.getTableType()) && !t.isHidden()) { - db.removeSchemaObject(session, t); - } - } - session.findLocalTempTable(null); - ArrayList list = New.arrayList(); - list.addAll(db.getAllSchemaObjects(DbObject.SEQUENCE)); - // maybe constraints and triggers on system tables will be allowed in - // the future - list.addAll(db.getAllSchemaObjects(DbObject.CONSTRAINT)); - list.addAll(db.getAllSchemaObjects(DbObject.TRIGGER)); - list.addAll(db.getAllSchemaObjects(DbObject.CONSTANT)); - list.addAll(db.getAllSchemaObjects(DbObject.FUNCTION_ALIAS)); - for (SchemaObject obj : list) { - if (obj.isHidden()) { - continue; - } - db.removeSchemaObject(session, obj); - } - for (User user : db.getAllUsers()) { - if (user != session.getUser()) { - db.removeDatabaseObject(session, user); - } - } - for (Role role : db.getAllRoles()) { - String sql = role.getCreateSQL(); - // the role PUBLIC must not be dropped - if (sql != null) { - db.removeDatabaseObject(session, role); - } - } - ArrayList dbObjects = New.arrayList(); - dbObjects.addAll(db.getAllRights()); - dbObjects.addAll(db.getAllAggregates()); - dbObjects.addAll(db.getAllUserDataTypes()); - for (DbObject obj : dbObjects) { - String sql = obj.getCreateSQL(); - // the role PUBLIC must not be dropped - if (sql != null) { - db.removeDatabaseObject(session, obj); - } - } - } - - public void setDropAllObjects(boolean b) { - this.dropAllObjects = b; - } - - public void setDeleteFiles(boolean b) { - this.deleteFiles = b; - } - -} diff --git a/tools/h2/src/main/org/h2/command/ddl/DropFunctionAlias.java b/tools/h2/src/main/org/h2/command/ddl/DropFunctionAlias.java deleted file mode 100755 index 0139953..0000000 --- a/tools/h2/src/main/org/h2/command/ddl/DropFunctionAlias.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.command.ddl; - -import org.h2.constant.ErrorCode; -import org.h2.engine.Database; -import org.h2.engine.FunctionAlias; -import org.h2.engine.Session; -import org.h2.message.DbException; -import org.h2.schema.Schema; - -/** - * This class represents the statement - * DROP ALIAS - */ -public class DropFunctionAlias extends SchemaCommand { - - private String aliasName; - private boolean ifExists; - - public DropFunctionAlias(Session session, Schema schema) { - super(session, schema); - } - - public int update() { - session.getUser().checkAdmin(); - session.commit(true); - Database db = session.getDatabase(); - FunctionAlias functionAlias = getSchema().findFunction(aliasName); - if (functionAlias == null) { - if (!ifExists) { - throw DbException.get(ErrorCode.FUNCTION_ALIAS_NOT_FOUND_1, aliasName); - } - } else { - db.removeSchemaObject(session, functionAlias); - } - return 0; - } - - public void setAliasName(String name) { - this.aliasName = name; - } - - public void setIfExists(boolean ifExists) { - this.ifExists = ifExists; - } - -} diff --git a/tools/h2/src/main/org/h2/command/ddl/DropIndex.java b/tools/h2/src/main/org/h2/command/ddl/DropIndex.java deleted file mode 100755 index abeac3f..0000000 --- a/tools/h2/src/main/org/h2/command/ddl/DropIndex.java +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.command.ddl; - -import java.util.ArrayList; -import org.h2.constant.ErrorCode; -import org.h2.constraint.Constraint; -import org.h2.engine.Database; -import org.h2.engine.Right; -import org.h2.engine.Session; -import org.h2.index.Index; -import org.h2.message.DbException; -import org.h2.schema.Schema; -import org.h2.table.Table; - -/** - * This class represents the statement - * DROP INDEX - */ -public class DropIndex extends SchemaCommand { - - private String indexName; - private boolean ifExists; - - public DropIndex(Session session, Schema schema) { - super(session, schema); - } - - public void setIfExists(boolean b) { - ifExists = b; - } - - public void setIndexName(String indexName) { - this.indexName = indexName; - } - - public int update() { - session.commit(true); - Database db = session.getDatabase(); - Index index = getSchema().findIndex(session, indexName); - if (index == null) { - if (!ifExists) { - throw DbException.get(ErrorCode.INDEX_NOT_FOUND_1, indexName); - } - } else { - Table table = index.getTable(); - session.getUser().checkRight(index.getTable(), Right.ALL); - Constraint pkConstraint = null; - ArrayList constraints = table.getConstraints(); - for (int i = 0; constraints != null && i < constraints.size(); i++) { - Constraint cons = constraints.get(i); - if (cons.usesIndex(index)) { - // can drop primary key index (for compatibility) - if (Constraint.PRIMARY_KEY.equals(cons.getConstraintType())) { - pkConstraint = cons; - } else { - throw DbException.get(ErrorCode.INDEX_BELONGS_TO_CONSTRAINT_1, indexName); - } - } - } - index.getTable().setModified(); - if (pkConstraint != null) { - db.removeSchemaObject(session, pkConstraint); - } else { - db.removeSchemaObject(session, index); - } - } - return 0; - } - -} diff --git a/tools/h2/src/main/org/h2/command/ddl/DropRole.java b/tools/h2/src/main/org/h2/command/ddl/DropRole.java deleted file mode 100755 index b175094..0000000 --- a/tools/h2/src/main/org/h2/command/ddl/DropRole.java +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.command.ddl; - -import org.h2.constant.ErrorCode; -import org.h2.engine.Constants; -import org.h2.engine.Database; -import org.h2.engine.Role; -import org.h2.engine.Session; -import org.h2.message.DbException; - -/** - * This class represents the statement - * DROP ROLE - */ -public class DropRole extends DefineCommand { - - private String roleName; - private boolean ifExists; - - public DropRole(Session session) { - super(session); - } - - public void setRoleName(String roleName) { - this.roleName = roleName; - } - - public int update() { - session.getUser().checkAdmin(); - session.commit(true); - Database db = session.getDatabase(); - if (roleName.equals(Constants.PUBLIC_ROLE_NAME)) { - throw DbException.get(ErrorCode.ROLE_CAN_NOT_BE_DROPPED_1, roleName); - } - Role role = db.findRole(roleName); - if (role == null) { - if (!ifExists) { - throw DbException.get(ErrorCode.ROLE_NOT_FOUND_1, roleName); - } - } else { - db.removeDatabaseObject(session, role); - } - return 0; - } - - public void setIfExists(boolean ifExists) { - this.ifExists = ifExists; - } - -} diff --git a/tools/h2/src/main/org/h2/command/ddl/DropSchema.java b/tools/h2/src/main/org/h2/command/ddl/DropSchema.java deleted file mode 100755 index 2a0ff6b..0000000 --- a/tools/h2/src/main/org/h2/command/ddl/DropSchema.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.command.ddl; - -import org.h2.constant.ErrorCode; -import org.h2.engine.Database; -import org.h2.engine.Session; -import org.h2.message.DbException; -import org.h2.schema.Schema; - -/** - * This class represents the statement - * DROP SCHEMA - */ -public class DropSchema extends DefineCommand { - - private String schemaName; - private boolean ifExists; - - public DropSchema(Session session) { - super(session); - } - - public void setSchemaName(String name) { - this.schemaName = name; - } - - public int update() { - session.getUser().checkAdmin(); - session.commit(true); - Database db = session.getDatabase(); - Schema schema = db.findSchema(schemaName); - if (schema == null) { - if (!ifExists) { - throw DbException.get(ErrorCode.SCHEMA_NOT_FOUND_1, schemaName); - } - } else { - if (!schema.canDrop()) { - throw DbException.get(ErrorCode.SCHEMA_CAN_NOT_BE_DROPPED_1, schemaName); - } - db.removeDatabaseObject(session, schema); - } - return 0; - } - - public void setIfExists(boolean ifExists) { - this.ifExists = ifExists; - } - -} diff --git a/tools/h2/src/main/org/h2/command/ddl/DropSequence.java b/tools/h2/src/main/org/h2/command/ddl/DropSequence.java deleted file mode 100755 index 2ed13d0..0000000 --- a/tools/h2/src/main/org/h2/command/ddl/DropSequence.java +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.command.ddl; - -import org.h2.constant.ErrorCode; -import org.h2.engine.Database; -import org.h2.engine.Session; -import org.h2.message.DbException; -import org.h2.schema.Schema; -import org.h2.schema.Sequence; - -/** - * This class represents the statement - * DROP SEQUENCE - */ -public class DropSequence extends SchemaCommand { - - private String sequenceName; - private boolean ifExists; - - public DropSequence(Session session, Schema schema) { - super(session, schema); - } - - public void setIfExists(boolean b) { - ifExists = b; - } - - public void setSequenceName(String sequenceName) { - this.sequenceName = sequenceName; - } - - public int update() { - session.getUser().checkAdmin(); - session.commit(true); - Database db = session.getDatabase(); - Sequence sequence = getSchema().findSequence(sequenceName); - if (sequence == null) { - if (!ifExists) { - throw DbException.get(ErrorCode.SEQUENCE_NOT_FOUND_1, sequenceName); - } - } else { - if (sequence.getBelongsToTable()) { - throw DbException.get(ErrorCode.SEQUENCE_BELONGS_TO_A_TABLE_1, sequenceName); - } - db.removeSchemaObject(session, sequence); - } - return 0; - } - -} diff --git a/tools/h2/src/main/org/h2/command/ddl/DropTable.java b/tools/h2/src/main/org/h2/command/ddl/DropTable.java deleted file mode 100755 index e27c2da..0000000 --- a/tools/h2/src/main/org/h2/command/ddl/DropTable.java +++ /dev/null @@ -1,99 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.command.ddl; - -import org.h2.constant.ErrorCode; -import org.h2.engine.Database; -import org.h2.engine.Right; -import org.h2.engine.Session; -import org.h2.message.DbException; -import org.h2.schema.Schema; -import org.h2.table.Table; - -/** - * This class represents the statement - * DROP TABLE - */ -public class DropTable extends SchemaCommand { - - private boolean ifExists; - private String tableName; - private Table table; - private DropTable next; - private int dropTableId; - - public DropTable(Session session, Schema schema) { - super(session, schema); - } - - /** - * Chain another drop table statement to this statement. - * - * @param drop the statement to add - */ - public void addNextDropTable(DropTable drop) { - if (next == null) { - next = drop; - } else { - next.addNextDropTable(drop); - } - } - - public void setIfExists(boolean b) { - ifExists = b; - if (next != null) { - next.setIfExists(b); - } - } - - public void setTableName(String tableName) { - this.tableName = tableName; - } - - private void prepareDrop() { - table = getSchema().findTableOrView(session, tableName); - if (table == null) { - if (!ifExists) { - throw DbException.get(ErrorCode.TABLE_OR_VIEW_NOT_FOUND_1, tableName); - } - } else { - dropTableId = table.getId(); - session.getUser().checkRight(table, Right.ALL); - if (!table.canDrop()) { - throw DbException.get(ErrorCode.CANNOT_DROP_TABLE_1, tableName); - } - table.lock(session, true, true); - } - if (next != null) { - next.prepareDrop(); - } - } - - private void executeDrop() { - // need to get the table again, because it may be dropped already - // meanwhile (dependent object, or same object) - table = getSchema().findTableOrView(session, tableName); - - if (table != null) { - table.setModified(); - Database db = session.getDatabase(); - db.removeSchemaObject(session, table); - db.getLobStorage().removeAllForTable(dropTableId); - } - if (next != null) { - next.executeDrop(); - } - } - - public int update() { - session.commit(true); - prepareDrop(); - executeDrop(); - return 0; - } - -} \ No newline at end of file diff --git a/tools/h2/src/main/org/h2/command/ddl/DropTrigger.java b/tools/h2/src/main/org/h2/command/ddl/DropTrigger.java deleted file mode 100755 index 43d78e9..0000000 --- a/tools/h2/src/main/org/h2/command/ddl/DropTrigger.java +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.command.ddl; - -import org.h2.constant.ErrorCode; -import org.h2.engine.Database; -import org.h2.engine.Right; -import org.h2.engine.Session; -import org.h2.message.DbException; -import org.h2.schema.Schema; -import org.h2.schema.TriggerObject; -import org.h2.table.Table; - -/** - * This class represents the statement - * DROP TRIGGER - */ -public class DropTrigger extends SchemaCommand { - - private String triggerName; - private boolean ifExists; - - public DropTrigger(Session session, Schema schema) { - super(session, schema); - } - - public void setIfExists(boolean b) { - ifExists = b; - } - - public void setTriggerName(String triggerName) { - this.triggerName = triggerName; - } - - public int update() { - session.commit(true); - Database db = session.getDatabase(); - TriggerObject trigger = getSchema().findTrigger(triggerName); - if (trigger == null) { - if (!ifExists) { - throw DbException.get(ErrorCode.TRIGGER_NOT_FOUND_1, triggerName); - } - } else { - Table table = trigger.getTable(); - session.getUser().checkRight(table, Right.ALL); - db.removeSchemaObject(session, trigger); - } - return 0; - } - -} diff --git a/tools/h2/src/main/org/h2/command/ddl/DropUser.java b/tools/h2/src/main/org/h2/command/ddl/DropUser.java deleted file mode 100755 index 362cbf5..0000000 --- a/tools/h2/src/main/org/h2/command/ddl/DropUser.java +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.command.ddl; - -import org.h2.constant.ErrorCode; -import org.h2.engine.Database; -import org.h2.engine.Session; -import org.h2.engine.User; -import org.h2.message.DbException; - -/** - * This class represents the statement - * DROP USER - */ -public class DropUser extends DefineCommand { - - private boolean ifExists; - private String userName; - - public DropUser(Session session) { - super(session); - } - - public void setIfExists(boolean b) { - ifExists = b; - } - - public void setUserName(String userName) { - this.userName = userName; - } - - public int update() { - session.getUser().checkAdmin(); - session.commit(true); - Database db = session.getDatabase(); - User user = db.findUser(userName); - if (user == null) { - if (!ifExists) { - throw DbException.get(ErrorCode.USER_NOT_FOUND_1, userName); - } - } else { - if (user == session.getUser()) { - int adminUserCount = 0; - for (User u : db.getAllUsers()) { - if (u.isAdmin()) { - adminUserCount++; - } - } - if (adminUserCount == 1) { - throw DbException.get(ErrorCode.CANNOT_DROP_CURRENT_USER); - } - } - user.checkOwnsNoSchemas(); - db.removeDatabaseObject(session, user); - } - return 0; - } - - public boolean isTransactional() { - return false; - } - -} diff --git a/tools/h2/src/main/org/h2/command/ddl/DropUserDataType.java b/tools/h2/src/main/org/h2/command/ddl/DropUserDataType.java deleted file mode 100755 index eff01b5..0000000 --- a/tools/h2/src/main/org/h2/command/ddl/DropUserDataType.java +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.command.ddl; - -import org.h2.constant.ErrorCode; -import org.h2.engine.Database; -import org.h2.engine.Session; -import org.h2.engine.UserDataType; -import org.h2.message.DbException; - -/** - * This class represents the statement - * DROP DOMAIN - */ -public class DropUserDataType extends DefineCommand { - - private String typeName; - private boolean ifExists; - - public DropUserDataType(Session session) { - super(session); - } - - public void setIfExists(boolean ifExists) { - this.ifExists = ifExists; - } - - public int update() { - session.getUser().checkAdmin(); - session.commit(true); - Database db = session.getDatabase(); - UserDataType type = db.findUserDataType(typeName); - if (type == null) { - if (!ifExists) { - throw DbException.get(ErrorCode.USER_DATA_TYPE_NOT_FOUND_1, typeName); - } - } else { - db.removeDatabaseObject(session, type); - } - return 0; - } - - public void setTypeName(String name) { - this.typeName = name; - } - -} diff --git a/tools/h2/src/main/org/h2/command/ddl/DropView.java b/tools/h2/src/main/org/h2/command/ddl/DropView.java deleted file mode 100755 index d9b4c7a..0000000 --- a/tools/h2/src/main/org/h2/command/ddl/DropView.java +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.command.ddl; - -import org.h2.constant.ErrorCode; -import org.h2.engine.Right; -import org.h2.engine.Session; -import org.h2.message.DbException; -import org.h2.schema.Schema; -import org.h2.table.Table; - -/** - * This class represents the statement - * DROP VIEW - */ -public class DropView extends SchemaCommand { - - private String viewName; - private boolean ifExists; - - public DropView(Session session, Schema schema) { - super(session, schema); - } - - public void setIfExists(boolean b) { - ifExists = b; - } - - public void setViewName(String viewName) { - this.viewName = viewName; - } - - public int update() { - session.commit(true); - Table view = getSchema().findTableOrView(session, viewName); - if (view == null) { - if (!ifExists) { - throw DbException.get(ErrorCode.VIEW_NOT_FOUND_1, viewName); - } - } else { - if (!Table.VIEW.equals(view.getTableType())) { - throw DbException.get(ErrorCode.VIEW_NOT_FOUND_1, viewName); - } - session.getUser().checkRight(view, Right.ALL); - view.lock(session, true, true); - session.getDatabase().removeSchemaObject(session, view); - } - return 0; - } - -} diff --git a/tools/h2/src/main/org/h2/command/ddl/GrantRevoke.java b/tools/h2/src/main/org/h2/command/ddl/GrantRevoke.java deleted file mode 100755 index b72c4fa..0000000 --- a/tools/h2/src/main/org/h2/command/ddl/GrantRevoke.java +++ /dev/null @@ -1,188 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.command.ddl; - -import java.util.ArrayList; -import org.h2.constant.ErrorCode; -import org.h2.engine.Database; -import org.h2.engine.Right; -import org.h2.engine.RightOwner; -import org.h2.engine.Role; -import org.h2.engine.Session; -import org.h2.message.DbException; -import org.h2.table.Table; -import org.h2.util.New; - -/** - * This class represents the statements - * GRANT RIGHT, - * GRANT ROLE, - * REVOKE RIGHT, - * REVOKE ROLE - */ -public class GrantRevoke extends DefineCommand { - - /** - * The operation type to grant a right. - */ - public static final int GRANT = 0; - - /** - * The operation type to revoke a right. - */ - public static final int REVOKE = 1; - - private ArrayList roleNames; - private int operationType; - private int rightMask; - private ArrayList
tables = New.arrayList(); - private RightOwner grantee; - - public GrantRevoke(Session session) { - super(session); - } - - public void setOperationType(int operationType) { - this.operationType = operationType; - } - - /** - * Add the specified right bit to the rights bitmap. - * - * @param right the right bit - */ - public void addRight(int right) { - this.rightMask |= right; - } - - /** - * Add the specified role to the list of roles. - * - * @param roleName the role - */ - public void addRoleName(String roleName) { - if (roleNames == null) { - roleNames = New.arrayList(); - } - roleNames.add(roleName); - } - - public void setGranteeName(String granteeName) { - Database db = session.getDatabase(); - grantee = db.findUser(granteeName); - if (grantee == null) { - grantee = db.findRole(granteeName); - if (grantee == null) { - throw DbException.get(ErrorCode.USER_OR_ROLE_NOT_FOUND_1, granteeName); - } - } - } - - public int update() { - session.getUser().checkAdmin(); - session.commit(true); - Database db = session.getDatabase(); - if (roleNames != null) { - for (String name : roleNames) { - Role grantedRole = db.findRole(name); - if (grantedRole == null) { - throw DbException.get(ErrorCode.ROLE_NOT_FOUND_1, name); - } - if (operationType == GRANT) { - grantRole(grantedRole); - } else if (operationType == REVOKE) { - revokeRole(grantedRole); - } else { - DbException.throwInternalError("type=" + operationType); - } - } - } else { - if (operationType == GRANT) { - grantRight(); - } else if (operationType == REVOKE) { - revokeRight(); - } else { - DbException.throwInternalError("type=" + operationType); - } - } - return 0; - } - - private void grantRight() { - Database db = session.getDatabase(); - for (Table table : tables) { - Right right = grantee.getRightForTable(table); - if (right == null) { - int id = getObjectId(); - right = new Right(db, id, grantee, rightMask, table); - grantee.grantRight(table, right); - db.addDatabaseObject(session, right); - } else { - right.setRightMask(right.getRightMask() | rightMask); - } - } - } - - private void grantRole(Role grantedRole) { - if (grantedRole != grantee && grantee.isRoleGranted(grantedRole)) { - return; - } - if (grantee instanceof Role) { - Role granteeRole = (Role) grantee; - if (grantedRole.isRoleGranted(granteeRole)) { - // cyclic role grants are not allowed - throw DbException.get(ErrorCode.ROLE_ALREADY_GRANTED_1, grantedRole.getSQL()); - } - } - Database db = session.getDatabase(); - int id = getObjectId(); - Right right = new Right(db, id, grantee, grantedRole); - db.addDatabaseObject(session, right); - grantee.grantRole(grantedRole, right); - } - - private void revokeRight() { - for (Table table : tables) { - Right right = grantee.getRightForTable(table); - if (right == null) { - continue; - } - int mask = right.getRightMask(); - int newRight = mask & ~rightMask; - Database db = session.getDatabase(); - if (newRight == 0) { - db.removeDatabaseObject(session, right); - } else { - right.setRightMask(newRight); - db.update(session, right); - } - } - } - - private void revokeRole(Role grantedRole) { - Right right = grantee.getRightForRole(grantedRole); - if (right == null) { - return; - } - Database db = session.getDatabase(); - db.removeDatabaseObject(session, right); - } - - public boolean isTransactional() { - return false; - } - - /** - * Add the specified table to the list of tables. - * - * @param table the table - */ - public void addTable(Table table) { - tables.add(table); - } - -} diff --git a/tools/h2/src/main/org/h2/command/ddl/PrepareProcedure.java b/tools/h2/src/main/org/h2/command/ddl/PrepareProcedure.java deleted file mode 100755 index 26f9e9a..0000000 --- a/tools/h2/src/main/org/h2/command/ddl/PrepareProcedure.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.command.ddl; - -import java.util.ArrayList; -import org.h2.command.Prepared; -import org.h2.engine.Procedure; -import org.h2.engine.Session; -import org.h2.expression.Parameter; -import org.h2.util.New; - -/** - * This class represents the statement - * PREPARE - */ -public class PrepareProcedure extends DefineCommand { - - private String procedureName; - private Prepared prepared; - - public PrepareProcedure(Session session) { - super(session); - } - - public void checkParameters() { - // no not check parameters - } - - public int update() { - Procedure proc = new Procedure(procedureName, prepared); - prepared.setParameterList(parameters); - prepared.setPrepareAlways(prepareAlways); - prepared.prepare(); - session.addProcedure(proc); - return 0; - } - - public void setProcedureName(String name) { - this.procedureName = name; - } - - public void setPrepared(Prepared prep) { - this.prepared = prep; - } - - public ArrayList getParameters() { - return New.arrayList(); - } - -} diff --git a/tools/h2/src/main/org/h2/command/ddl/SchemaCommand.java b/tools/h2/src/main/org/h2/command/ddl/SchemaCommand.java deleted file mode 100755 index d01ee5c..0000000 --- a/tools/h2/src/main/org/h2/command/ddl/SchemaCommand.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.command.ddl; - -import org.h2.engine.Session; -import org.h2.schema.Schema; - -/** - * This class represents a non-transaction statement that involves a schema. - */ -public abstract class SchemaCommand extends DefineCommand { - - private final Schema schema; - - /** - * Create a new command. - * - * @param session the session - * @param schema the schema - */ - public SchemaCommand(Session session, Schema schema) { - super(session); - this.schema = schema; - } - - /** - * Get the schema - * - * @return the schema - */ - protected Schema getSchema() { - return schema; - } - -} diff --git a/tools/h2/src/main/org/h2/command/ddl/SetComment.java b/tools/h2/src/main/org/h2/command/ddl/SetComment.java deleted file mode 100755 index ba58a10..0000000 --- a/tools/h2/src/main/org/h2/command/ddl/SetComment.java +++ /dev/null @@ -1,149 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.command.ddl; - -import org.h2.constant.ErrorCode; -import org.h2.engine.Comment; -import org.h2.engine.Database; -import org.h2.engine.DbObject; -import org.h2.engine.Session; -import org.h2.expression.Expression; -import org.h2.message.DbException; -import org.h2.table.Table; - -/** - * This class represents the statement - * COMMENT - */ -public class SetComment extends DefineCommand { - - private String schemaName; - private String objectName; - private boolean column; - private String columnName; - private int objectType; - private Expression expr; - - public SetComment(Session session) { - super(session); - } - - public int update() { - session.commit(true); - Database db = session.getDatabase(); - session.getUser().checkAdmin(); - DbObject object = null; - int errorCode = ErrorCode.GENERAL_ERROR_1; - if (schemaName == null) { - schemaName = session.getCurrentSchemaName(); - } - switch (objectType) { - case DbObject.CONSTANT: - object = db.getSchema(schemaName).getConstant(objectName); - break; - case DbObject.CONSTRAINT: - object = db.getSchema(schemaName).getConstraint(objectName); - break; - case DbObject.FUNCTION_ALIAS: - object = db.getSchema(schemaName).findFunction(objectName); - errorCode = ErrorCode.FUNCTION_ALIAS_NOT_FOUND_1; - break; - case DbObject.INDEX: - object = db.getSchema(schemaName).getIndex(objectName); - break; - case DbObject.ROLE: - schemaName = null; - object = db.findRole(objectName); - errorCode = ErrorCode.ROLE_NOT_FOUND_1; - break; - case DbObject.SCHEMA: - schemaName = null; - object = db.findSchema(objectName); - errorCode = ErrorCode.SCHEMA_NOT_FOUND_1; - break; - case DbObject.SEQUENCE: - object = db.getSchema(schemaName).getSequence(objectName); - break; - case DbObject.TABLE_OR_VIEW: - object = db.getSchema(schemaName).getTableOrView(session, objectName); - break; - case DbObject.TRIGGER: - object = db.getSchema(schemaName).findTrigger(objectName); - errorCode = ErrorCode.TRIGGER_NOT_FOUND_1; - break; - case DbObject.USER: - schemaName = null; - object = db.getUser(objectName); - break; - case DbObject.USER_DATATYPE: - schemaName = null; - object = db.findUserDataType(objectName); - errorCode = ErrorCode.USER_DATA_TYPE_ALREADY_EXISTS_1; - break; - default: - } - if (object == null) { - throw DbException.get(errorCode, objectName); - } - String text = expr.optimize(session).getValue(session).getString(); - if (column) { - Table table = (Table) object; - table.getColumn(columnName).setComment(text); - } else { - object.setComment(text); - } - if (column || objectType == DbObject.TABLE_OR_VIEW || objectType == DbObject.USER - || objectType == DbObject.INDEX || objectType == DbObject.CONSTRAINT) { - db.update(session, object); - } else { - Comment comment = db.findComment(object); - if (comment == null) { - if (text == null) { - // reset a non-existing comment - nothing to do - } else { - int id = getObjectId(); - comment = new Comment(db, id, object); - comment.setCommentText(text); - db.addDatabaseObject(session, comment); - } - } else { - if (text == null) { - db.removeDatabaseObject(session, comment); - } else { - comment.setCommentText(text); - db.update(session, comment); - } - } - } - return 0; - } - - public void setCommentExpression(Expression expr) { - this.expr = expr; - } - - public void setObjectName(String objectName) { - this.objectName = objectName; - } - - public void setObjectType(int objectType) { - this.objectType = objectType; - } - - public void setColumnName(String columnName) { - this.columnName = columnName; - } - - public void setSchemaName(String schemaName) { - this.schemaName = schemaName; - } - - public void setColumn(boolean column) { - this.column = column; - } - -} diff --git a/tools/h2/src/main/org/h2/command/ddl/TruncateTable.java b/tools/h2/src/main/org/h2/command/ddl/TruncateTable.java deleted file mode 100755 index 4c4d533..0000000 --- a/tools/h2/src/main/org/h2/command/ddl/TruncateTable.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.command.ddl; - -import org.h2.constant.ErrorCode; -import org.h2.engine.Right; -import org.h2.engine.Session; -import org.h2.message.DbException; -import org.h2.table.Table; - -/** - * This class represents the statement - * TRUNCATE TABLE - */ -public class TruncateTable extends DefineCommand { - - private Table table; - - public TruncateTable(Session session) { - super(session); - } - - public void setTable(Table table) { - this.table = table; - } - - public int update() { - session.commit(true); - if (!table.canTruncate()) { - throw DbException.get(ErrorCode.CANNOT_TRUNCATE_1, table.getSQL()); - } - session.getUser().checkRight(table, Right.DELETE); - table.lock(session, true, true); - table.truncate(session); - return 0; - } - -} diff --git a/tools/h2/src/main/org/h2/command/ddl/package.html b/tools/h2/src/main/org/h2/command/ddl/package.html deleted file mode 100755 index 4026b64..0000000 --- a/tools/h2/src/main/org/h2/command/ddl/package.html +++ /dev/null @@ -1,15 +0,0 @@ - - - - -Javadoc package documentation -

- -Contains DDL (data definition language) and related SQL statements. - -

\ No newline at end of file diff --git a/tools/h2/src/main/org/h2/command/dml/AlterSequence.java b/tools/h2/src/main/org/h2/command/dml/AlterSequence.java deleted file mode 100755 index 51d1969..0000000 --- a/tools/h2/src/main/org/h2/command/dml/AlterSequence.java +++ /dev/null @@ -1,87 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.command.dml; - -import org.h2.command.ddl.SchemaCommand; -import org.h2.constant.ErrorCode; -import org.h2.engine.Database; -import org.h2.engine.Right; -import org.h2.engine.Session; -import org.h2.expression.Expression; -import org.h2.message.DbException; -import org.h2.schema.Schema; -import org.h2.schema.Sequence; -import org.h2.table.Column; -import org.h2.table.Table; - -/** - * This class represents the statement - * ALTER SEQUENCE - */ -public class AlterSequence extends SchemaCommand { - - private Table table; - private Sequence sequence; - private Expression start; - private Expression increment; - - public AlterSequence(Session session, Schema schema) { - super(session, schema); - } - - public void setSequence(Sequence sequence) { - this.sequence = sequence; - } - - public boolean isTransactional() { - return true; - } - - public void setColumn(Column column) { - table = column.getTable(); - sequence = column.getSequence(); - if (sequence == null) { - throw DbException.get(ErrorCode.SEQUENCE_NOT_FOUND_1, column.getSQL()); - } - } - - public void setStartWith(Expression start) { - this.start = start; - } - - public void setIncrement(Expression increment) { - this.increment = increment; - } - - public int update() { - Database db = session.getDatabase(); - if (table != null) { - session.getUser().checkRight(table, Right.ALL); - } - if (start != null) { - long startValue = start.optimize(session).getValue(session).getLong(); - sequence.setStartValue(startValue); - } - if (increment != null) { - long incrementValue = increment.optimize(session).getValue(session).getLong(); - if (incrementValue == 0) { - throw DbException.get(ErrorCode.INVALID_VALUE_2, "0", "INCREMENT"); - } - sequence.setIncrement(incrementValue); - } - // need to use the system session, so that the update - // can be committed immediately - not committing it - // would keep other transactions from using the sequence - Session sysSession = db.getSystemSession(); - synchronized (sysSession) { - db.update(sysSession, sequence); - sysSession.commit(true); - } - return 0; - } - -} diff --git a/tools/h2/src/main/org/h2/command/dml/AlterTableSet.java b/tools/h2/src/main/org/h2/command/dml/AlterTableSet.java deleted file mode 100755 index bbb63dc..0000000 --- a/tools/h2/src/main/org/h2/command/dml/AlterTableSet.java +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.command.dml; - -import org.h2.command.ddl.SchemaCommand; -import org.h2.engine.Right; -import org.h2.engine.Session; -import org.h2.message.DbException; -import org.h2.schema.Schema; -import org.h2.table.Table; - -/** - * This class represents the statement - * ALTER TABLE SET - */ -public class AlterTableSet extends SchemaCommand { - - /** - * Enable the referential integrity. - */ - public static final int REFERENTIAL_INTEGRITY_TRUE = 0; - - /** - * Disable the referential integrity. - */ - public static final int REFERENTIAL_INTEGRITY_FALSE = 1; - - private String tableName; - private final int type; - private boolean checkExisting; - - public AlterTableSet(Session session, Schema schema, int type) { - super(session, schema); - this.type = type; - } - - public void setCheckExisting(boolean b) { - this.checkExisting = b; - } - - public boolean isTransactional() { - return true; - } - - public void setTableName(String tableName) { - this.tableName = tableName; - } - - public int update() { - Table table = getSchema().getTableOrView(session, tableName); - session.getUser().checkRight(table, Right.ALL); - table.lock(session, true, true); - switch(type) { - case REFERENTIAL_INTEGRITY_TRUE: - table.setCheckForeignKeyConstraints(session, true, checkExisting); - break; - case REFERENTIAL_INTEGRITY_FALSE: - table.setCheckForeignKeyConstraints(session, false, false); - break; - default: - DbException.throwInternalError("type="+type); - } - return 0; - } - -} diff --git a/tools/h2/src/main/org/h2/command/dml/BackupCommand.java b/tools/h2/src/main/org/h2/command/dml/BackupCommand.java deleted file mode 100755 index 5e84ed9..0000000 --- a/tools/h2/src/main/org/h2/command/dml/BackupCommand.java +++ /dev/null @@ -1,141 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.command.dml; - -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.util.ArrayList; -import java.util.zip.ZipEntry; -import java.util.zip.ZipOutputStream; -import org.h2.api.DatabaseEventListener; -import org.h2.command.Prepared; -import org.h2.constant.ErrorCode; -import org.h2.engine.Constants; -import org.h2.engine.Database; -import org.h2.engine.Session; -import org.h2.expression.Expression; -import org.h2.message.DbException; -import org.h2.result.ResultInterface; -import org.h2.store.FileLister; -import org.h2.store.PageStore; -import org.h2.util.IOUtils; - -/** - * This class represents the statement - * BACKUP - */ -public class BackupCommand extends Prepared { - - private Expression fileNameExpr; - - public BackupCommand(Session session) { - super(session); - } - - public void setFileName(Expression fileName) { - this.fileNameExpr = fileName; - } - - public int update() { - String name = fileNameExpr.getValue(session).getString(); - session.getUser().checkAdmin(); - backupTo(name); - return 0; - } - - private void backupTo(String fileName) { - Database db = session.getDatabase(); - if (!db.isPersistent()) { - throw DbException.get(ErrorCode.DATABASE_IS_NOT_PERSISTENT); - } - try { - String name = db.getName(); - name = IOUtils.getFileName(name); - OutputStream zip = IOUtils.openFileOutputStream(fileName, false); - ZipOutputStream out = new ZipOutputStream(zip); - db.flush(); - String fn; - fn = db.getName() + Constants.SUFFIX_PAGE_FILE; - backupPageStore(out, fn, db.getPageStore()); - // synchronize on the database, to avoid concurrent temp file - // creation / deletion / backup - String base = IOUtils.getParent(fn); - synchronized (db.getLobSyncObject()) { - String prefix = db.getDatabasePath(); - String dir = IOUtils.getParent(prefix); - ArrayList fileList = FileLister.getDatabaseFiles(dir, name, true); - for (String n : fileList) { - if (n.endsWith(Constants.SUFFIX_LOB_FILE)) { - backupFile(out, base, n); - } - } - } - out.close(); - zip.close(); - } catch (IOException e) { - throw DbException.convertIOException(e, fileName); - } - } - - private void backupPageStore(ZipOutputStream out, String fileName, PageStore store) throws IOException { - Database db = session.getDatabase(); - fileName = IOUtils.getFileName(fileName); - out.putNextEntry(new ZipEntry(fileName)); - int max = store.getPageCount(); - int pos = 0; - while (true) { - pos = store.copyDirect(pos, out); - if (pos < 0) { - break; - } - db.setProgress(DatabaseEventListener.STATE_BACKUP_FILE, fileName, pos, max); - } - out.closeEntry(); - } - - private void backupFile(ZipOutputStream out, String base, String fn) throws IOException { - String f = IOUtils.getAbsolutePath(fn); - base = IOUtils.getAbsolutePath(base); - if (!f.startsWith(base)) { - DbException.throwInternalError(f + " does not start with " + base); - } - f = f.substring(base.length()); - f = correctFileName(f); - out.putNextEntry(new ZipEntry(f)); - InputStream in = IOUtils.openFileInputStream(fn); - IOUtils.copyAndCloseInput(in, out); - out.closeEntry(); - } - - public boolean isTransactional() { - return true; - } - - /** - * Fix the file name, replacing backslash with slash. - * - * @param f the file name - * @return the corrected file name - */ - public static String correctFileName(String f) { - f = f.replace('\\', '/'); - if (f.startsWith("/")) { - f = f.substring(1); - } - return f; - } - - public boolean needRecompile() { - return false; - } - - public ResultInterface queryMeta() { - return null; - } - -} diff --git a/tools/h2/src/main/org/h2/command/dml/Call.java b/tools/h2/src/main/org/h2/command/dml/Call.java deleted file mode 100755 index e2e8be9..0000000 --- a/tools/h2/src/main/org/h2/command/dml/Call.java +++ /dev/null @@ -1,107 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.command.dml; - -import java.sql.ResultSet; -import org.h2.command.Prepared; -import org.h2.engine.Session; -import org.h2.expression.Expression; -import org.h2.expression.ExpressionColumn; -import org.h2.expression.ExpressionVisitor; -import org.h2.result.LocalResult; -import org.h2.result.ResultInterface; -import org.h2.table.Column; -import org.h2.value.Value; -import org.h2.value.ValueArray; -import org.h2.value.ValueResultSet; - -/** - * This class represents the statement - * CALL. - */ -public class Call extends Prepared { - - - private Expression expression; - private Expression[] expressions; - - public Call(Session session) { - super(session); - } - - public ResultInterface queryMeta() { - LocalResult result = new LocalResult(session, expressions, 1); - result.done(); - return result; - } - - public int update() { - Value v = expression.getValue(session); - int type = v.getType(); - switch(type) { - case Value.RESULT_SET: - case Value.ARRAY: - // this will throw an exception - // methods returning a result set may not be called like this. - return super.update(); - case Value.UNKNOWN: - case Value.NULL: - return 0; - default: - return v.getInt(); - } - } - - public ResultInterface query(int maxrows) { - setCurrentRowNumber(1); - Value v = expression.getValue(session); - if (v.getType() == Value.RESULT_SET) { - ResultSet rs = ((ValueResultSet) v).getResultSet(); - return LocalResult.read(session, rs, maxrows); - } else if (v.getType() == Value.ARRAY) { - Value[] list = ((ValueArray) v).getList(); - Expression[] expr = new Expression[list.length]; - for (int i = 0; i < list.length; i++) { - Value e = list[i]; - Column col = new Column("C" + (i + 1), e.getType(), e.getPrecision(), e.getScale(), e.getDisplaySize()); - expr[i] = new ExpressionColumn(session.getDatabase(), col); - } - LocalResult result = new LocalResult(session, expr, list.length); - result.addRow(list); - result.done(); - return result; - } - LocalResult result = new LocalResult(session, expressions, 1); - Value[] row = { v }; - result.addRow(row); - result.done(); - return result; - } - - public void prepare() { - expression = expression.optimize(session); - expressions = new Expression[] { expression }; - } - - public void setExpression(Expression expression) { - this.expression = expression; - } - - public boolean isQuery() { - return true; - } - - public boolean isTransactional() { - return true; - } - - public boolean isReadOnly() { - return expression.isEverything(ExpressionVisitor.READONLY); - - } - -} diff --git a/tools/h2/src/main/org/h2/command/dml/Delete.java b/tools/h2/src/main/org/h2/command/dml/Delete.java deleted file mode 100755 index 74454cf..0000000 --- a/tools/h2/src/main/org/h2/command/dml/Delete.java +++ /dev/null @@ -1,117 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.command.dml; - -import org.h2.api.Trigger; -import org.h2.command.Prepared; -import org.h2.engine.Right; -import org.h2.engine.Session; -import org.h2.engine.UndoLogRecord; -import org.h2.expression.Expression; -import org.h2.result.ResultInterface; -import org.h2.result.Row; -import org.h2.result.RowList; -import org.h2.table.PlanItem; -import org.h2.table.Table; -import org.h2.table.TableFilter; -import org.h2.util.StringUtils; - -/** - * This class represents the statement - * DELETE - */ -public class Delete extends Prepared { - - private Expression condition; - private TableFilter tableFilter; - - public Delete(Session session) { - super(session); - } - - public void setTableFilter(TableFilter tableFilter) { - this.tableFilter = tableFilter; - } - - public void setCondition(Expression condition) { - this.condition = condition; - } - - public int update() { - tableFilter.startQuery(session); - tableFilter.reset(); - Table table = tableFilter.getTable(); - session.getUser().checkRight(table, Right.DELETE); - table.fire(session, Trigger.DELETE, true); - table.lock(session, true, false); - RowList rows = new RowList(session); - try { - setCurrentRowNumber(0); - while (tableFilter.next()) { - setCurrentRowNumber(rows.size() + 1); - if (condition == null || Boolean.TRUE.equals(condition.getBooleanValue(session))) { - Row row = tableFilter.get(); - boolean done = false; - if (table.fireRow()) { - done = table.fireBeforeRow(session, row, null); - } - if (!done) { - rows.add(row); - } - } - } - int rowScanCount = 0; - for (rows.reset(); rows.hasNext();) { - if ((++rowScanCount & 127) == 0) { - checkCanceled(); - } - Row row = rows.next(); - table.removeRow(session, row); - session.log(table, UndoLogRecord.DELETE, row); - } - if (table.fireRow()) { - for (rows.reset(); rows.hasNext();) { - Row row = rows.next(); - table.fireAfterRow(session, row, null, false); - } - } - table.fire(session, Trigger.DELETE, false); - return rows.size(); - } finally { - rows.close(); - } - } - - public String getPlanSQL() { - StringBuilder buff = new StringBuilder(); - buff.append("DELETE FROM ").append(tableFilter.getPlanSQL(false)); - if (condition != null) { - buff.append("\nWHERE ").append(StringUtils.unEnclose(condition.getSQL())); - } - return buff.toString(); - } - - public void prepare() { - if (condition != null) { - condition.mapColumns(tableFilter, 0); - condition = condition.optimize(session); - condition.createIndexConditions(session, tableFilter); - } - PlanItem item = tableFilter.getBestPlanItem(session, 1); - tableFilter.setPlanItem(item); - tableFilter.prepare(); - } - - public boolean isTransactional() { - return true; - } - - public ResultInterface queryMeta() { - return null; - } - -} diff --git a/tools/h2/src/main/org/h2/command/dml/ExecuteProcedure.java b/tools/h2/src/main/org/h2/command/dml/ExecuteProcedure.java deleted file mode 100755 index 43fb6b9..0000000 --- a/tools/h2/src/main/org/h2/command/dml/ExecuteProcedure.java +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.command.dml; - -import java.util.ArrayList; -import org.h2.command.Prepared; -import org.h2.engine.Procedure; -import org.h2.engine.Session; -import org.h2.expression.Expression; -import org.h2.expression.Parameter; -import org.h2.result.ResultInterface; -import org.h2.util.New; - -/** - * This class represents the statement - * EXECUTE - */ -public class ExecuteProcedure extends Prepared { - - private ArrayList expressions = New.arrayList(); - private Procedure procedure; - - public ExecuteProcedure(Session session) { - super(session); - } - - public void setProcedure(Procedure procedure) { - this.procedure = procedure; - } - - /** - * Set the expression at the given index. - * - * @param index the index (0 based) - * @param expr the expression - */ - public void setExpression(int index, Expression expr) { - expressions.add(index, expr); - } - - private void setParameters() { - Prepared prepared = procedure.getPrepared(); - ArrayList params = prepared.getParameters(); - for (int i = 0; params != null && i < params.size() && i < expressions.size(); i++) { - Expression expr = expressions.get(i); - Parameter p = params.get(i); - p.setValue(expr.getValue(session)); - } - } - - public boolean isQuery() { - Prepared prepared = procedure.getPrepared(); - return prepared.isQuery(); - } - - public int update() { - setParameters(); - Prepared prepared = procedure.getPrepared(); - return prepared.update(); - } - - public ResultInterface query(int limit) { - setParameters(); - Prepared prepared = procedure.getPrepared(); - return prepared.query(limit); - } - - public boolean isTransactional() { - return true; - } - - public ResultInterface queryMeta() { - Prepared prepared = procedure.getPrepared(); - return prepared.queryMeta(); - } - -} diff --git a/tools/h2/src/main/org/h2/command/dml/Explain.java b/tools/h2/src/main/org/h2/command/dml/Explain.java deleted file mode 100755 index e9dfdd2..0000000 --- a/tools/h2/src/main/org/h2/command/dml/Explain.java +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.command.dml; - -import org.h2.command.Prepared; -import org.h2.engine.Session; -import org.h2.expression.Expression; -import org.h2.expression.ExpressionColumn; -import org.h2.result.LocalResult; -import org.h2.result.ResultInterface; -import org.h2.table.Column; -import org.h2.value.Value; -import org.h2.value.ValueString; - -/** - * This class represents the statement - * EXPLAIN - */ -public class Explain extends Prepared { - - private Prepared command; - private LocalResult result; - private boolean executeCommand; - - public Explain(Session session) { - super(session); - } - - public void setCommand(Prepared command) { - this.command = command; - } - - public void prepare() { - command.prepare(); - } - - public void setExecuteCommand(boolean executeCommand) { - this.executeCommand = executeCommand; - } - - public ResultInterface queryMeta() { - return query(-1); - } - - public ResultInterface query(int maxrows) { - Column column = new Column("PLAN", Value.STRING); - ExpressionColumn expr = new ExpressionColumn(session.getDatabase(), column); - Expression[] expressions = { expr }; - result = new LocalResult(session, expressions, 1); - if (maxrows >= 0) { - if (executeCommand) { - if (command.isQuery()) { - command.query(maxrows); - } else { - command.update(); - } - } - String plan = command.getPlanSQL(); - add(plan); - } - result.done(); - return result; - } - - private void add(String text) { - Value[] row = { ValueString.get(text) }; - result.addRow(row); - } - - public boolean isQuery() { - return true; - } - - public boolean isTransactional() { - return true; - } - - public boolean isReadOnly() { - return true; - } -} diff --git a/tools/h2/src/main/org/h2/command/dml/Insert.java b/tools/h2/src/main/org/h2/command/dml/Insert.java deleted file mode 100755 index bc63255..0000000 --- a/tools/h2/src/main/org/h2/command/dml/Insert.java +++ /dev/null @@ -1,238 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.command.dml; - -import java.util.ArrayList; -import org.h2.api.Trigger; -import org.h2.command.Command; -import org.h2.command.Prepared; -import org.h2.constant.ErrorCode; -import org.h2.engine.Database; -import org.h2.engine.Right; -import org.h2.engine.Session; -import org.h2.engine.UndoLogRecord; -import org.h2.expression.Expression; -import org.h2.expression.Parameter; -import org.h2.index.PageIndex; -import org.h2.message.DbException; -import org.h2.result.ResultInterface; -import org.h2.result.Row; -import org.h2.table.Column; -import org.h2.table.Table; -import org.h2.util.New; -import org.h2.util.StatementBuilder; -import org.h2.value.Value; - -/** - * This class represents the statement - * INSERT - */ -public class Insert extends Prepared { - - private Table table; - private Column[] columns; - private ArrayList list = New.arrayList(); - private Query query; - private boolean sortedInsertMode; - - public Insert(Session session) { - super(session); - } - - public void setCommand(Command command) { - super.setCommand(command); - if (query != null) { - query.setCommand(command); - } - } - - public void setTable(Table table) { - this.table = table; - } - - public void setColumns(Column[] columns) { - this.columns = columns; - } - - public void setQuery(Query query) { - this.query = query; - } - - /** - * Add a row to this merge statement. - * - * @param expr the list of values - */ - public void addRow(Expression[] expr) { - list.add(expr); - } - - public int update() { - Database db = session.getDatabase(); - PageIndex index = null; - if (sortedInsertMode && db.isPersistent()) { - index = (PageIndex) table.getScanIndex(session); - index.setSortedInsertMode(true); - } - try { - return insertRows(); - } finally { - if (index != null) { - index.setSortedInsertMode(false); - } - } - } - - private int insertRows() { - int count; - session.getUser().checkRight(table, Right.INSERT); - setCurrentRowNumber(0); - table.fire(session, Trigger.INSERT, true); - if (list.size() > 0) { - count = 0; - for (int x = 0; x < list.size(); x++) { - Expression[] expr = list.get(x); - Row newRow = table.getTemplateRow(); - setCurrentRowNumber(x + 1); - for (int i = 0; i < columns.length; i++) { - Column c = columns[i]; - int index = c.getColumnId(); - Expression e = expr[i]; - if (e != null) { - // e can be null (DEFAULT) - e = e.optimize(session); - try { - Value v = c.convert(e.getValue(session)); - newRow.setValue(index, v); - } catch (DbException ex) { - throw setRow(ex, x, getSQL(expr)); - } - } - } - table.validateConvertUpdateSequence(session, newRow); - boolean done = table.fireBeforeRow(session, null, newRow); - if (!done) { - table.lock(session, true, false); - table.addRow(session, newRow); - session.log(table, UndoLogRecord.INSERT, newRow); - table.fireAfterRow(session, null, newRow, false); - } - count++; - } - } else { - ResultInterface rows = query.query(0); - count = 0; - table.lock(session, true, false); - while (rows.next()) { - count++; - Value[] r = rows.currentRow(); - Row newRow = table.getTemplateRow(); - setCurrentRowNumber(count); - for (int j = 0; j < columns.length; j++) { - Column c = columns[j]; - int index = c.getColumnId(); - try { - Value v = c.convert(r[j]); - newRow.setValue(index, v); - } catch (DbException ex) { - throw setRow(ex, count, getSQL(r)); - } - } - table.validateConvertUpdateSequence(session, newRow); - boolean done = table.fireBeforeRow(session, null, newRow); - if (!done) { - table.addRow(session, newRow); - session.log(table, UndoLogRecord.INSERT, newRow); - table.fireAfterRow(session, null, newRow, false); - } - } - rows.close(); - } - table.fire(session, Trigger.INSERT, false); - return count; - } - - public String getPlanSQL() { - StatementBuilder buff = new StatementBuilder("INSERT INTO "); - buff.append(table.getSQL()).append('('); - for (Column c : columns) { - buff.appendExceptFirst(", "); - buff.append(c.getSQL()); - } - buff.append(")\n"); - if (list.size() > 0) { - buff.append("VALUES "); - int row = 0; - for (Expression[] expr : list) { - if (row++ > 0) { - buff.append(", "); - } - buff.append('('); - buff.resetCount(); - for (Expression e : expr) { - buff.appendExceptFirst(", "); - if (e == null) { - buff.append("DEFAULT"); - } else { - buff.append(e.getSQL()); - } - } - buff.append(')'); - } - } else { - buff.append(query.getPlanSQL()); - } - return buff.toString(); - } - - public void prepare() { - if (columns == null) { - if (list.size() > 0 && list.get(0).length == 0) { - // special case where table is used as a sequence - columns = new Column[0]; - } else { - columns = table.getColumns(); - } - } - if (list.size() > 0) { - for (Expression[] expr : list) { - if (expr.length != columns.length) { - throw DbException.get(ErrorCode.COLUMN_COUNT_DOES_NOT_MATCH); - } - for (int i = 0; i < expr.length; i++) { - Expression e = expr[i]; - if (e != null) { - e = e.optimize(session); - if (e instanceof Parameter) { - Parameter p = (Parameter) e; - p.setColumn(columns[i]); - } - expr[i] = e; - } - } - } - } else { - query.prepare(); - if (query.getColumnCount() != columns.length) { - throw DbException.get(ErrorCode.COLUMN_COUNT_DOES_NOT_MATCH); - } - } - } - - public boolean isTransactional() { - return true; - } - - public ResultInterface queryMeta() { - return null; - } - - public void setSortedInsertMode(boolean sortedInsertMode) { - this.sortedInsertMode = sortedInsertMode; - } - -} diff --git a/tools/h2/src/main/org/h2/command/dml/Merge.java b/tools/h2/src/main/org/h2/command/dml/Merge.java deleted file mode 100755 index 1a8b2e0..0000000 --- a/tools/h2/src/main/org/h2/command/dml/Merge.java +++ /dev/null @@ -1,277 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.command.dml; - -import java.util.ArrayList; -import org.h2.api.Trigger; -import org.h2.command.Command; -import org.h2.command.Prepared; -import org.h2.constant.ErrorCode; -import org.h2.engine.Right; -import org.h2.engine.Session; -import org.h2.engine.UndoLogRecord; -import org.h2.expression.Expression; -import org.h2.expression.Parameter; -import org.h2.index.Index; -import org.h2.message.DbException; -import org.h2.result.ResultInterface; -import org.h2.result.Row; -import org.h2.table.Column; -import org.h2.table.Table; -import org.h2.util.New; -import org.h2.util.StatementBuilder; -import org.h2.value.Value; -import org.h2.value.ValueLong; - -/** - * This class represents the statement - * MERGE - */ -public class Merge extends Prepared { - - private Table table; - private Column[] columns; - private Column[] keys; - private ArrayList list = New.arrayList(); - private Query query; - private Prepared update; - - public Merge(Session session) { - super(session); - } - - public void setCommand(Command command) { - super.setCommand(command); - if (query != null) { - query.setCommand(command); - } - } - - public void setTable(Table table) { - this.table = table; - } - - public void setColumns(Column[] columns) { - this.columns = columns; - } - - public void setKeys(Column[] keys) { - this.keys = keys; - } - - public void setQuery(Query query) { - this.query = query; - } - - /** - * Add a row to this merge statement. - * - * @param expr the list of values - */ - public void addRow(Expression[] expr) { - list.add(expr); - } - - public int update() { - int count; - session.getUser().checkRight(table, Right.INSERT); - session.getUser().checkRight(table, Right.UPDATE); - setCurrentRowNumber(0); - session.setLastIdentity(ValueLong.get(0)); - if (list.size() > 0) { - count = 0; - for (int x = 0; x < list.size(); x++) { - setCurrentRowNumber(x + 1); - Expression[] expr = list.get(x); - Row newRow = table.getTemplateRow(); - for (int i = 0; i < columns.length; i++) { - Column c = columns[i]; - int index = c.getColumnId(); - Expression e = expr[i]; - if (e != null) { - // e can be null (DEFAULT) - try { - Value v = c.convert(e.getValue(session)); - newRow.setValue(index, v); - } catch (DbException ex) { - throw setRow(ex, count, getSQL(expr)); - } - } - } - merge(newRow); - count++; - } - } else { - ResultInterface rows = query.query(0); - count = 0; - table.fire(session, Trigger.UPDATE | Trigger.INSERT, true); - table.lock(session, true, false); - while (rows.next()) { - count++; - Value[] r = rows.currentRow(); - Row newRow = table.getTemplateRow(); - setCurrentRowNumber(count); - for (int j = 0; j < columns.length; j++) { - Column c = columns[j]; - int index = c.getColumnId(); - try { - Value v = c.convert(r[j]); - newRow.setValue(index, v); - } catch (DbException ex) { - throw setRow(ex, count, getSQL(r)); - } - } - merge(newRow); - } - rows.close(); - table.fire(session, Trigger.UPDATE | Trigger.INSERT, false); - } - return count; - } - - private void merge(Row row) { - ArrayList k = update.getParameters(); - for (int i = 0; i < columns.length; i++) { - Column col = columns[i]; - Value v = row.getValue(col.getColumnId()); - Parameter p = k.get(i); - p.setValue(v); - } - for (int i = 0; i < keys.length; i++) { - Column col = keys[i]; - Value v = row.getValue(col.getColumnId()); - if (v == null) { - throw DbException.get(ErrorCode.COLUMN_CONTAINS_NULL_VALUES_1, col.getSQL()); - } - Parameter p = k.get(columns.length + i); - p.setValue(v); - } - int count = update.update(); - if (count == 0) { - try { - table.validateConvertUpdateSequence(session, row); - boolean done = table.fireBeforeRow(session, null, row); - if (!done) { - table.lock(session, true, false); - table.addRow(session, row); - session.log(table, UndoLogRecord.INSERT, row); - table.fireAfterRow(session, null, row, false); - } - } catch (DbException e) { - if (e.getErrorCode() == ErrorCode.DUPLICATE_KEY_1) { - // concurrent merge or insert - throw DbException.get(ErrorCode.CONCURRENT_UPDATE_1, table.getName()); - } - throw e; - } - } else if (count != 1) { - throw DbException.get(ErrorCode.DUPLICATE_KEY_1, table.getSQL()); - } - } - - public String getPlanSQL() { - StatementBuilder buff = new StatementBuilder("MERGE INTO "); - buff.append(table.getSQL()).append('('); - for (Column c : columns) { - buff.appendExceptFirst(", "); - buff.append(c.getSQL()); - } - buff.append(')'); - if (keys != null) { - buff.append(" KEY("); - buff.resetCount(); - for (Column c : keys) { - buff.appendExceptFirst(", "); - buff.append(c.getSQL()); - } - buff.append(')'); - } - buff.append('\n'); - if (list.size() > 0) { - buff.append("VALUES "); - int row = 0; - for (Expression[] expr : list) { - if (row++ > 0) { - buff.append(", "); - } - buff.append('('); - buff.resetCount(); - for (Expression e : expr) { - buff.appendExceptFirst(", "); - if (e == null) { - buff.append("DEFAULT"); - } else { - buff.append(e.getSQL()); - } - } - buff.append(')'); - } - } else { - buff.append(query.getPlanSQL()); - } - return buff.toString(); - } - - public void prepare() { - if (columns == null) { - if (list.size() > 0 && list.get(0).length == 0) { - // special case where table is used as a sequence - columns = new Column[0]; - } else { - columns = table.getColumns(); - } - } - if (list.size() > 0) { - for (Expression[] expr : list) { - if (expr.length != columns.length) { - throw DbException.get(ErrorCode.COLUMN_COUNT_DOES_NOT_MATCH); - } - for (int i = 0; i < expr.length; i++) { - Expression e = expr[i]; - if (e != null) { - expr[i] = e.optimize(session); - } - } - } - } else { - query.prepare(); - if (query.getColumnCount() != columns.length) { - throw DbException.get(ErrorCode.COLUMN_COUNT_DOES_NOT_MATCH); - } - } - if (keys == null) { - Index idx = table.getPrimaryKey(); - if (idx == null) { - throw DbException.get(ErrorCode.CONSTRAINT_NOT_FOUND_1, "PRIMARY KEY"); - } - keys = idx.getColumns(); - } - StatementBuilder buff = new StatementBuilder("UPDATE "); - buff.append(table.getSQL()).append(" SET "); - for (Column c : columns) { - buff.appendExceptFirst(", "); - buff.append(c.getSQL()).append("=?"); - } - buff.append(" WHERE "); - buff.resetCount(); - for (Column c : keys) { - buff.appendExceptFirst(" AND "); - buff.append(c.getSQL()).append("=?"); - } - String sql = buff.toString(); - update = session.prepare(sql); - } - - public boolean isTransactional() { - return true; - } - - public ResultInterface queryMeta() { - return null; - } - -} diff --git a/tools/h2/src/main/org/h2/command/dml/NoOperation.java b/tools/h2/src/main/org/h2/command/dml/NoOperation.java deleted file mode 100755 index e11fef8..0000000 --- a/tools/h2/src/main/org/h2/command/dml/NoOperation.java +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.command.dml; - -import org.h2.command.Prepared; -import org.h2.engine.Session; -import org.h2.result.ResultInterface; - -/** - * Represents an empty statement or a statement that has no effect. - */ -public class NoOperation extends Prepared { - - public NoOperation(Session session) { - super(session); - } - - public int update() { - return 0; - } - - public boolean isQuery() { - return false; - } - - public boolean isTransactional() { - return true; - } - - public boolean needRecompile() { - return false; - } - - public boolean isReadOnly() { - return true; - } - - public ResultInterface queryMeta() { - return null; - } - -} diff --git a/tools/h2/src/main/org/h2/command/dml/Optimizer.java b/tools/h2/src/main/org/h2/command/dml/Optimizer.java deleted file mode 100755 index c60ea66..0000000 --- a/tools/h2/src/main/org/h2/command/dml/Optimizer.java +++ /dev/null @@ -1,251 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.command.dml; - -import java.util.BitSet; -import java.util.Random; -import org.h2.engine.Session; -import org.h2.expression.Expression; -import org.h2.table.Plan; -import org.h2.table.PlanItem; -import org.h2.table.TableFilter; -import org.h2.util.Permutations; - -/** - * The optimizer is responsible to find the best execution plan - * for a given query. - */ -public class Optimizer { - - private static final int MAX_BRUTE_FORCE_FILTERS = 7; - private static final int MAX_BRUTE_FORCE = 2000; - private static final int MAX_GENETIC = 500; - private long start; - private BitSet switched; - - // possible plans for filters, if using brute force: - // 1 filter 1 plan - // 2 filters 2 plans - // 3 filters 6 plans - // 4 filters 24 plans - // 5 filters 120 plans - // 6 filters 720 plans - // 7 filters 5040 plans - // 8 filters 40320 plan - // 9 filters 362880 plans - // 10 filters 3628800 filters - - private TableFilter[] filters; - private Expression condition; - private Session session; - - private Plan bestPlan; - private TableFilter topFilter; - private double cost; - private Random random; - - Optimizer(TableFilter[] filters, Expression condition, Session session) { - this.filters = filters; - this.condition = condition; - this.session = session; - } - - /** - * How many filter to calculate using brute force. The remaining filters are - * selected using a greedy algorithm which has a runtime of (1 + 2 + ... + - * n) = (n * (n-1) / 2) for n filters. The brute force algorithm has a - * runtime of n * (n-1) * ... * (n-m) when calculating m brute force of n - * total. The combined runtime is (brute force) * (greedy). - * - * @param filterCount the number of filters total - * @return the number of filters to calculate using brute force - */ - private static int getMaxBruteForceFilters(int filterCount) { - int i = 0, j = filterCount, total = filterCount; - while (j > 0 && total * (j * (j - 1) / 2) < MAX_BRUTE_FORCE) { - j--; - total *= j; - i++; - } - return i; - } - - private void calculateBestPlan() { - start = System.currentTimeMillis(); - cost = -1; - if (filters.length == 1) { - testPlan(filters); - } else if (filters.length <= MAX_BRUTE_FORCE_FILTERS) { - calculateBruteForceAll(); - } else { - calculateBruteForceSome(); - random = new Random(0); - calculateGenetic(); - } - } - - private boolean canStop(int x) { - if ((x & 127) == 0) { - long t = System.currentTimeMillis() - start; - // don't calculate for simple queries (no rows or so) - if (cost >= 0 && 10 * t > cost) { - return true; - } - } - return false; - } - - private void calculateBruteForceAll() { - TableFilter[] list = new TableFilter[filters.length]; - Permutations p = Permutations.create(filters, list); - for (int x = 0; !canStop(x) && p.next(); x++) { - testPlan(list); - } - } - - private void calculateBruteForceSome() { - int bruteForce = getMaxBruteForceFilters(filters.length); - TableFilter[] list = new TableFilter[filters.length]; - Permutations p = Permutations.create(filters, list, bruteForce); - for (int x = 0; !canStop(x) && p.next(); x++) { - // find out what filters are not used yet - for (TableFilter f : filters) { - f.setUsed(false); - } - for (int i = 0; i < bruteForce; i++) { - list[i].setUsed(true); - } - // fill the remaining elements with the unused elements (greedy) - for (int i = bruteForce; i < filters.length; i++) { - double costPart = -1.0; - int bestPart = -1; - for (int j = 0; j < filters.length; j++) { - if (!filters[j].isUsed()) { - if (i == filters.length - 1) { - bestPart = j; - break; - } - list[i] = filters[j]; - Plan part = new Plan(list, i+1, condition); - double costNow = part.calculateCost(session); - if (costPart < 0 || costNow < costPart) { - costPart = costNow; - bestPart = j; - } - } - } - filters[bestPart].setUsed(true); - list[i] = filters[bestPart]; - } - testPlan(list); - } - } - - private void calculateGenetic() { - TableFilter[] best = new TableFilter[filters.length]; - TableFilter[] list = new TableFilter[filters.length]; - for (int x = 0; x < MAX_GENETIC; x++) { - if (canStop(x)) { - break; - } - boolean generateRandom = (x & 127) == 0; - if (!generateRandom) { - System.arraycopy(best, 0, list, 0, filters.length); - if (!shuffleTwo(list)) { - generateRandom = true; - } - } - if (generateRandom) { - switched = new BitSet(); - System.arraycopy(filters, 0, best, 0, filters.length); - shuffleAll(best); - System.arraycopy(best, 0, list, 0, filters.length); - } - if (testPlan(list)) { - switched = new BitSet(); - System.arraycopy(list, 0, best, 0, filters.length); - } - } - } - - private boolean testPlan(TableFilter[] list) { - Plan p = new Plan(list, list.length, condition); - double costNow = p.calculateCost(session); - if (cost < 0 || costNow < cost) { - cost = costNow; - bestPlan = p; - return true; - } - return false; - } - - private void shuffleAll(TableFilter[] f) { - for (int i = 0; i < f.length - 1; i++) { - int j = i + random.nextInt(f.length - i); - if (j != i) { - TableFilter temp = f[i]; - f[i] = f[j]; - f[j] = temp; - } - } - } - - private boolean shuffleTwo(TableFilter[] f) { - int a = 0, b = 0, i = 0; - for (; i < 20; i++) { - a = random.nextInt(f.length); - b = random.nextInt(f.length); - if (a == b) { - continue; - } - if (a < b) { - int temp = a; - a = b; - b = temp; - } - int s = a * f.length + b; - if (switched.get(s)) { - continue; - } - switched.set(s); - break; - } - if (i == 20) { - return false; - } - TableFilter temp = f[a]; - f[a] = f[b]; - f[b] = temp; - return true; - } - - /** - * Calculate the best query plan to use. - */ - void optimize() { - calculateBestPlan(); - bestPlan.removeUnusableIndexConditions(); - TableFilter[] f2 = bestPlan.getFilters(); - topFilter = f2[0]; - for (int i = 0; i < f2.length - 1; i++) { - f2[i].addJoin(f2[i + 1], false, null); - } - for (TableFilter f : f2) { - PlanItem item = bestPlan.getItem(f); - f.setPlanItem(item); - } - } - - public TableFilter getTopFilter() { - return topFilter; - } - - double getCost() { - return cost; - } - -} diff --git a/tools/h2/src/main/org/h2/command/dml/Query.java b/tools/h2/src/main/org/h2/command/dml/Query.java deleted file mode 100755 index d35847f..0000000 --- a/tools/h2/src/main/org/h2/command/dml/Query.java +++ /dev/null @@ -1,419 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.command.dml; - -import java.util.ArrayList; -import java.util.HashSet; -import org.h2.command.Prepared; -import org.h2.constant.ErrorCode; -import org.h2.engine.Database; -import org.h2.engine.Session; -import org.h2.expression.Alias; -import org.h2.expression.Expression; -import org.h2.expression.ExpressionColumn; -import org.h2.expression.ExpressionVisitor; -import org.h2.expression.Parameter; -import org.h2.expression.ValueExpression; -import org.h2.message.DbException; -import org.h2.result.LocalResult; -import org.h2.result.ResultInterface; -import org.h2.result.SortOrder; -import org.h2.table.ColumnResolver; -import org.h2.table.Table; -import org.h2.table.TableFilter; -import org.h2.util.New; -import org.h2.util.StringUtils; -import org.h2.value.Value; -import org.h2.value.ValueInt; -import org.h2.value.ValueNull; - -/** - * Represents a SELECT statement (simple, or union). - */ -public abstract class Query extends Prepared { - - /** - * The limit expression as specified in the LIMIT or TOP clause. - */ - protected Expression limitExpr; - - /** - * The offset expression as specified in the LIMIT .. OFFSET clause. - */ - protected Expression offsetExpr; - - /** - * The sample size - */ - protected int sampleSize; - - private int lastLimit; - private long lastEvaluated; - private LocalResult lastResult; - private Value[] lastParameters; - - public Query(Session session) { - super(session); - } - - /** - * Execute the query without checking the cache. - * - * @param limit the limit as specified in the JDBC method call - * @return the result - */ - protected abstract LocalResult queryWithoutCache(int limit); - - /** - * Initialize the query. - */ - public abstract void init(); - - /** - * The the list of select expressions. - * This may include invisible expressions such as order by expressions. - * - * @return the list of expressions - */ - public abstract ArrayList getExpressions(); - - /** - * Calculate the cost to execute this query. - * - * @return the cost - */ - public abstract double getCost(); - - /** - * Get all tables that are involved in this query. - * - * @return the set of tables - */ - public abstract HashSet
getTables(); - - /** - * Set the order by list. - * - * @param order the order by list - */ - public abstract void setOrder(ArrayList order); - - /** - * Set the 'for update' flag. - * - * @param forUpdate the new setting - */ - public abstract void setForUpdate(boolean forUpdate); - - /** - * Get the column count of this query. - * - * @return the column count - */ - public abstract int getColumnCount(); - - /** - * Map the columns to the given column resolver. - * - * @param resolver - * the resolver - * @param level - * the subquery level (0 is the top level query, 1 is the first - * subquery level) - */ - public abstract void mapColumns(ColumnResolver resolver, int level); - - /** - * Change the evaluatable flag. This is used when building the execution plan. - * - * @param tableFilter the table filter - * @param b the new value - */ - public abstract void setEvaluatable(TableFilter tableFilter, boolean b); - - /** - * Add a condition to the query. This is used for views. - * - * @param param the parameter - * @param columnId the column index (0 meaning the first column) - * @param comparisonType the comparison type - */ - public abstract void addGlobalCondition(Parameter param, int columnId, int comparisonType); - - /** - * Set the distinct flag. - * - * @param b the new value - */ - public abstract void setDistinct(boolean b); - - /** - * Check if this expression and all sub-expressions can fulfill a criteria. - * If any part returns false, the result is false. - * - * @param visitor the visitor - * @return if the criteria can be fulfilled - */ - public abstract boolean isEverything(ExpressionVisitor visitor); - - /** - * Update all aggregate function values. - * - * @param s the session - */ - public abstract void updateAggregate(Session s); - - /** - * Call the before triggers on all tables. - */ - public abstract void fireBeforeSelectTriggers(); - - public boolean isQuery() { - return true; - } - - public boolean isTransactional() { - return true; - } - - private boolean sameResultAsLast(Session s, Value[] params, Value[] lastParams, long lastEval) - { - Database db = s.getDatabase(); - for (int i = 0; i < params.length; i++) { - if (!db.areEqual(lastParams[i], params[i])) { - return false; - } - } - if (!isEverything(ExpressionVisitor.DETERMINISTIC) || !isEverything(ExpressionVisitor.INDEPENDENT)) { - return false; - } - if (db.getModificationDataId() > lastEval && getMaxDataModificationId() > lastEval) { - return false; - } - return true; - } - - public final Value[] getParameterValues() { - ArrayList list = getParameters(); - if (list == null) { - list = New.arrayList(); - } - Value[] params = new Value[list.size()]; - for (int i = 0; i < list.size(); i++) { - Value v = list.get(i).getParamValue(); - params[i] = v; - } - return params; - } - - public ResultInterface query(int limit) { - fireBeforeSelectTriggers(); - if (!session.getDatabase().getOptimizeReuseResults()) { - return queryWithoutCache(limit); - } - Value[] params = getParameterValues(); - long now = session.getDatabase().getModificationDataId(); - if (isEverything(ExpressionVisitor.DETERMINISTIC)) { - if (lastResult != null && !lastResult.isClosed() && limit == lastLimit) { - if (sameResultAsLast(session, params, lastParameters, lastEvaluated)) { - lastResult = lastResult.createShallowCopy(session); - if (lastResult != null) { - lastResult.reset(); - return lastResult; - } - } - } - } - lastParameters = params; - closeLastResult(); - lastResult = queryWithoutCache(limit); - this.lastEvaluated = now; - lastLimit = limit; - return lastResult; - } - - private void closeLastResult() { - if (lastResult != null) { - lastResult.close(); - } - } - - /** - * Initialize the order by list. This call may extend the expressions list. - * - * @param expressions the select list expressions - * @param expressionSQL the select list SQL snippets - * @param orderList the order by list - * @param visible the number of visible columns in the select list - * @param mustBeInResult all order by expressions must be in the select list - * @return the new list (expressions may be added) - */ - void initOrder(ArrayList expressions, ArrayList expressionSQL, ArrayList orderList, int visible, - boolean mustBeInResult) { - for (SelectOrderBy o : orderList) { - Expression e = o.expression; - if (e == null) { - continue; - } - // special case: SELECT 1 AS A FROM DUAL ORDER BY A - // (oracle supports it, but only in order by, not in group by and - // not in having): - // SELECT 1 AS A FROM DUAL ORDER BY -A - boolean isAlias = false; - int idx = expressions.size(); - if (e instanceof ExpressionColumn) { - ExpressionColumn exprCol = (ExpressionColumn) e; - String tableAlias = exprCol.getOriginalTableAliasName(); - String col = exprCol.getOriginalColumnName(); - for (int j = 0; j < visible; j++) { - boolean found = false; - Expression ec = expressions.get(j); - if (ec instanceof ExpressionColumn) { - ExpressionColumn c = (ExpressionColumn) ec; - found = col.equals(c.getColumnName()); - if (tableAlias != null && found) { - String ca = c.getOriginalTableAliasName(); - if (ca != null) { - found = tableAlias.equals(ca); - } - } - } else if (!(ec instanceof Alias)) { - continue; - } else if (tableAlias == null && col.equals(ec.getAlias())) { - found = true; - } else { - Expression ec2 = ec.getNonAliasExpression(); - if (ec2 instanceof ExpressionColumn) { - ExpressionColumn c2 = (ExpressionColumn) ec2; - String ta = exprCol.getSQL(); - // exprCol.getTableAlias(); - String tb = c2.getSQL(); - // getTableAlias(); - found = col.equals(c2.getColumnName()); - if (!StringUtils.equals(ta, tb)) { - found = false; - } - } - } - if (found) { - idx = j; - isAlias = true; - break; - } - } - } else { - String s = e.getSQL(); - for (int j = 0; expressionSQL != null && j < expressionSQL.size(); j++) { - String s2 = expressionSQL.get(j); - if (s2.equals(s)) { - idx = j; - isAlias = true; - break; - } - } - } - if (!isAlias) { - if (mustBeInResult) { - throw DbException.get(ErrorCode.ORDER_BY_NOT_IN_RESULT, e.getSQL()); - } - expressions.add(e); - String sql = e.getSQL(); - expressionSQL.add(sql); - } - o.columnIndexExpr = ValueExpression.get(ValueInt.get(idx + 1)); - } - } - - /** - * Create a {@link SortOrder} object given the list of {@link SelectOrderBy} - * objects. The expression list is extended if necessary. - * - * @param orderList a list of {@link SelectOrderBy} elements - * @param expressionCount the number of columns in the query - * @return the {@link SortOrder} object - */ - public SortOrder prepareOrder(ArrayList orderList, int expressionCount) { - int[] index = new int[orderList.size()]; - int[] sortType = new int[orderList.size()]; - for (int i = 0; i < orderList.size(); i++) { - SelectOrderBy o = orderList.get(i); - int idx; - boolean reverse = false; - Expression expr = o.columnIndexExpr; - Value v = expr.getValue(null); - if (v == ValueNull.INSTANCE) { - // parameter not yet set - order by first column - idx = 0; - } else { - idx = v.getInt(); - if (idx < 0) { - reverse = true; - idx = -idx; - } - idx -= 1; - if (idx < 0 || idx >= expressionCount) { - throw DbException.get(ErrorCode.ORDER_BY_NOT_IN_RESULT, "" + (idx + 1)); - } - } - index[i] = idx; - boolean desc = o.descending; - if (reverse) { - desc = !desc; - } - int type = desc ? SortOrder.DESCENDING : SortOrder.ASCENDING; - if (o.nullsFirst) { - type += SortOrder.NULLS_FIRST; - } else if (o.nullsLast) { - type += SortOrder.NULLS_LAST; - } - sortType[i] = type; - } - return new SortOrder(session.getDatabase(), index, sortType); - } - - public void setOffset(Expression offset) { - this.offsetExpr = offset; - } - - public void setLimit(Expression limit) { - this.limitExpr = limit; - } - - /** - * Add a parameter to the parameter list. - * - * @param param the parameter to add - */ - void addParameter(Parameter param) { - if (parameters == null) { - parameters = New.arrayList(); - } - parameters.add(param); - } - - public void setSampleSize(int sampleSize) { - this.sampleSize = sampleSize; - } - - public final long getMaxDataModificationId() { - ExpressionVisitor visitor = ExpressionVisitor.get(ExpressionVisitor.SET_MAX_DATA_MODIFICATION_ID); - isEverything(visitor); - return visitor.getMaxDataModificationId(); - } - - /** - * Visit all expressions and subqueries in this query using the visitor pattern. - * - * @param expressionVisitorType the visitor type - * @return true if no component returned false - */ - public final boolean isEverything(int expressionVisitorType) { - ExpressionVisitor visitor = ExpressionVisitor.get(expressionVisitorType); - return isEverything(visitor); - } - -} diff --git a/tools/h2/src/main/org/h2/command/dml/RunScriptCommand.java b/tools/h2/src/main/org/h2/command/dml/RunScriptCommand.java deleted file mode 100755 index c151606..0000000 --- a/tools/h2/src/main/org/h2/command/dml/RunScriptCommand.java +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.command.dml; - -import java.io.IOException; -import java.io.InputStreamReader; -import java.io.Reader; -import org.h2.command.Prepared; -import org.h2.constant.SysProperties; -import org.h2.engine.Session; -import org.h2.message.DbException; -import org.h2.result.ResultInterface; -import org.h2.util.ScriptReader; - -/** - * This class represents the statement - * RUNSCRIPT - */ -public class RunScriptCommand extends ScriptBase { - - private String charset = SysProperties.FILE_ENCODING; - - public RunScriptCommand(Session session) { - super(session); - } - - public int update() { - session.getUser().checkAdmin(); - int count = 0; - try { - openInput(); - Reader reader = new InputStreamReader(in, charset); - ScriptReader r = new ScriptReader(reader); - while (true) { - String sql = r.readStatement(); - if (sql == null) { - break; - } - execute(sql); - count++; - } - reader.close(); - } catch (IOException e) { - throw DbException.convertIOException(e, null); - } finally { - closeIO(); - } - return count; - } - - private void execute(String sql) { - try { - Prepared command = session.prepare(sql); - if (command.isQuery()) { - command.query(0); - } else { - command.update(); - } - if (session.getAutoCommit()) { - session.commit(false); - } - } catch (DbException e) { - throw e.addSQL(sql); - } - } - - public void setCharset(String charset) { - this.charset = charset; - } - - public ResultInterface queryMeta() { - return null; - } - -} diff --git a/tools/h2/src/main/org/h2/command/dml/ScriptBase.java b/tools/h2/src/main/org/h2/command/dml/ScriptBase.java deleted file mode 100755 index 2d93a23..0000000 --- a/tools/h2/src/main/org/h2/command/dml/ScriptBase.java +++ /dev/null @@ -1,236 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.command.dml; - -import java.io.BufferedInputStream; -import java.io.BufferedOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.sql.Connection; -import org.h2.command.Prepared; -import org.h2.constant.ErrorCode; -import org.h2.constant.SysProperties; -import org.h2.engine.Constants; -import org.h2.engine.Database; -import org.h2.engine.Session; -import org.h2.expression.Expression; -import org.h2.message.DbException; -import org.h2.security.SHA256; -import org.h2.store.DataHandler; -import org.h2.store.FileStore; -import org.h2.store.FileStoreInputStream; -import org.h2.store.FileStoreOutputStream; -import org.h2.store.LobStorage; -import org.h2.tools.CompressTool; -import org.h2.util.IOUtils; -import org.h2.util.SmallLRUCache; -import org.h2.util.TempFileDeleter; - -/** - * This class is the base for RunScriptCommand and ScriptCommand. - */ -public abstract class ScriptBase extends Prepared implements DataHandler { - - /** - * The default name of the script file if .zip compression is used. - */ - private static final String SCRIPT_SQL = "script.sql"; - - /** - * The output stream. - */ - protected OutputStream out; - - /** - * The input stream. - */ - protected InputStream in; - - /** - * The file name (if set). - */ - private Expression fileNameExpr; - private String fileName; - - private String cipher; - private byte[] key; - private FileStore store; - private String compressionAlgorithm; - - public ScriptBase(Session session) { - super(session); - } - - public void setCipher(String c) { - cipher = c; - } - - private boolean isEncrypted() { - return cipher != null; - } - - public void setPassword(char[] password) { - SHA256 sha = new SHA256(); - key = sha.getKeyPasswordHash("script", password); - } - - public void setFileNameExpr(Expression file) { - this.fileNameExpr = file; - } - - protected String getFileName() { - if (fileNameExpr != null && fileName == null) { - fileName = fileNameExpr.optimize(session).getValue(session).getString(); - if (fileName == null || fileName.trim().length() == 0) { - fileName = "script.sql"; - } - fileName = SysProperties.getScriptDirectory() + fileName; - } - return fileName; - } - - public boolean isTransactional() { - return false; - } - - /** - * Delete the target file. - */ - void deleteStore() { - String file = getFileName(); - if (file != null) { - IOUtils.delete(file); - } - } - - private void initStore() { - Database db = session.getDatabase(); - // script files are always in text format - String file = getFileName(); - store = FileStore.open(db, file, "rw", cipher, key); - store.setCheckedWriting(false); - store.init(); - } - - /** - * Open the output stream. - */ - void openOutput() { - String file = getFileName(); - if (file == null) { - return; - } - if (isEncrypted()) { - initStore(); - out = new FileStoreOutputStream(store, this, compressionAlgorithm); - // always use a big buffer, otherwise end-of-block is written a lot - out = new BufferedOutputStream(out, Constants.IO_BUFFER_SIZE_COMPRESS); - } else { - OutputStream o = IOUtils.openFileOutputStream(file, false); - out = new BufferedOutputStream(o, Constants.IO_BUFFER_SIZE); - out = CompressTool.wrapOutputStream(out, compressionAlgorithm, SCRIPT_SQL); - } - } - - /** - * Open the input stream. - */ - void openInput() { - String file = getFileName(); - if (file == null) { - return; - } - if (isEncrypted()) { - initStore(); - in = new FileStoreInputStream(store, this, compressionAlgorithm != null, false); - } else { - InputStream inStream; - try { - inStream = IOUtils.openFileInputStream(file); - } catch (IOException e) { - throw DbException.convertIOException(e, file); - } - in = new BufferedInputStream(inStream, Constants.IO_BUFFER_SIZE); - in = CompressTool.wrapInputStream(in, compressionAlgorithm, SCRIPT_SQL); - if (in == null) { - throw DbException.get(ErrorCode.FILE_NOT_FOUND_1, SCRIPT_SQL + " in " + file); - } - } - } - - /** - * Close input and output streams. - */ - void closeIO() { - IOUtils.closeSilently(out); - out = null; - IOUtils.closeSilently(in); - in = null; - if (store != null) { - store.closeSilently(); - store = null; - } - } - - public boolean needRecompile() { - return false; - } - - public String getDatabasePath() { - return null; - } - - public FileStore openFile(String name, String mode, boolean mustExist) { - return null; - } - - public void checkPowerOff() { - session.getDatabase().checkPowerOff(); - } - - public void checkWritingAllowed() { - session.getDatabase().checkWritingAllowed(); - } - - public void freeUpDiskSpace() { - session.getDatabase().freeUpDiskSpace(); - } - - public int getMaxLengthInplaceLob() { - return session.getDatabase().getMaxLengthInplaceLob(); - } - - public TempFileDeleter getTempFileDeleter() { - return session.getDatabase().getTempFileDeleter(); - } - - public String getLobCompressionAlgorithm(int type) { - return session.getDatabase().getLobCompressionAlgorithm(type); - } - - public void setCompressionAlgorithm(String algorithm) { - this.compressionAlgorithm = algorithm; - } - - public Object getLobSyncObject() { - return this; - } - - public SmallLRUCache getLobFileListCache() { - return null; - } - - public LobStorage getLobStorage() { - return null; - } - - public Connection getLobConnection() { - return null; - } - -} diff --git a/tools/h2/src/main/org/h2/command/dml/ScriptCommand.java b/tools/h2/src/main/org/h2/command/dml/ScriptCommand.java deleted file mode 100755 index 4211ceb..0000000 --- a/tools/h2/src/main/org/h2/command/dml/ScriptCommand.java +++ /dev/null @@ -1,571 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, Version - * 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). Initial Developer: H2 Group - */ -package org.h2.command.dml; - -import java.io.BufferedInputStream; -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStream; -import java.io.Reader; -import java.sql.Connection; -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.util.ArrayList; -import java.util.Collections; -import java.util.Comparator; -import org.h2.command.Parser; -import org.h2.constant.SysProperties; -import org.h2.constraint.Constraint; -import org.h2.engine.Comment; -import org.h2.engine.Constants; -import org.h2.engine.Database; -import org.h2.engine.DbObject; -import org.h2.engine.Right; -import org.h2.engine.Role; -import org.h2.engine.Session; -import org.h2.engine.Setting; -import org.h2.engine.User; -import org.h2.engine.UserAggregate; -import org.h2.engine.UserDataType; -import org.h2.expression.Expression; -import org.h2.expression.ExpressionColumn; -import org.h2.index.Cursor; -import org.h2.index.Index; -import org.h2.message.DbException; -import org.h2.result.LocalResult; -import org.h2.result.ResultInterface; -import org.h2.result.Row; -import org.h2.schema.Constant; -import org.h2.schema.Schema; -import org.h2.schema.SchemaObject; -import org.h2.schema.Sequence; -import org.h2.schema.TriggerObject; -import org.h2.table.Column; -import org.h2.table.PlanItem; -import org.h2.table.Table; -import org.h2.util.IOUtils; -import org.h2.util.MathUtils; -import org.h2.util.StatementBuilder; -import org.h2.util.StringUtils; -import org.h2.util.Utils; -import org.h2.value.Value; -import org.h2.value.ValueString; - -/** - * This class represents the statement - * SCRIPT - */ -public class ScriptCommand extends ScriptBase { - - private boolean passwords; - private boolean data; - private boolean settings; - private boolean drop; - private boolean simple; - private LocalResult result; - private byte[] lineSeparator; - private byte[] buffer; - private boolean tempLobTableCreated; - private int nextLobId; - private int lobBlockSize = Constants.IO_BUFFER_SIZE; - - public ScriptCommand(Session session) { - super(session); - } - - public boolean isQuery() { - return true; - } - - // TODO lock all tables for 'script' command - - public void setData(boolean data) { - this.data = data; - } - - public void setPasswords(boolean passwords) { - this.passwords = passwords; - } - - public void setSettings(boolean settings) { - this.settings = settings; - } - - public void setLobBlockSize(long blockSize) { - this.lobBlockSize = MathUtils.convertLongToInt(blockSize); - } - - public void setDrop(boolean drop) { - this.drop = drop; - } - - public ResultInterface queryMeta() { - LocalResult r = createResult(); - r.done(); - return r; - } - - private LocalResult createResult() { - Expression[] expressions = { new ExpressionColumn(session.getDatabase(), new Column("SCRIPT", - Value.STRING)) }; - return new LocalResult(session, expressions, 1); - } - - public ResultInterface query(int maxrows) { - session.getUser().checkAdmin(); - reset(); - try { - result = createResult(); - deleteStore(); - openOutput(); - if (out != null) { - buffer = new byte[Constants.IO_BUFFER_SIZE]; - } - Database db = session.getDatabase(); - if (settings) { - for (Setting setting : db.getAllSettings()) { - if (setting.getName().equals(SetTypes.getTypeName(SetTypes.CREATE_BUILD))) { - // don't add CREATE_BUILD to the script - // (it is only set when creating the database) - continue; - } - add(setting.getCreateSQL(), false); - } - } - if (out != null) { - add("", true); - } - for (User user : db.getAllUsers()) { - add(user.getCreateSQL(passwords, true), false); - } - for (Role role : db.getAllRoles()) { - add(role.getCreateSQL(true), false); - } - for (Schema schema : db.getAllSchemas()) { - add(schema.getCreateSQL(), false); - } - for (UserDataType datatype : db.getAllUserDataTypes()) { - if (drop) { - add(datatype.getDropSQL(), false); - } - add(datatype.getCreateSQL(), false); - } - for (SchemaObject obj : db.getAllSchemaObjects(DbObject.CONSTANT)) { - Constant constant = (Constant) obj; - add(constant.getCreateSQL(), false); - } - for (SchemaObject obj : db.getAllSchemaObjects(DbObject.FUNCTION_ALIAS)) { - if (drop) { - add(obj.getDropSQL(), false); - } - add(obj.getCreateSQL(), false); - } - for (UserAggregate agg : db.getAllAggregates()) { - if (drop) { - add(agg.getDropSQL(), false); - } - add(agg.getCreateSQL(), false); - } - ArrayList
tables = db.getAllTablesAndViews(false); - // sort by id, so that views are after tables and views on views - // after the base views - Collections.sort(tables, new Comparator
() { - public int compare(Table t1, Table t2) { - return t1.getId() - t2.getId(); - } - }); - for (Table table : tables) { - if (table.isHidden()) { - continue; - } - table.lock(session, false, false); - String sql = table.getCreateSQL(); - if (sql == null) { - // null for metadata tables - continue; - } - if (drop) { - add(table.getDropSQL(), false); - } - } - for (SchemaObject obj : db.getAllSchemaObjects(DbObject.SEQUENCE)) { - Sequence sequence = (Sequence) obj; - if (drop && !sequence.getBelongsToTable()) { - add(sequence.getDropSQL(), false); - } - add(sequence.getCreateSQL(), false); - } - for (Table table : tables) { - if (table.isHidden()) { - continue; - } - table.lock(session, false, false); - String sql = table.getCreateSQL(); - if (sql == null) { - // null for metadata tables - continue; - } - String tableType = table.getTableType(); - add(sql, false); - ArrayList constraints = table.getConstraints(); - if (constraints != null) { - for (Constraint constraint : constraints) { - if (Constraint.PRIMARY_KEY.equals(constraint.getConstraintType())) { - add(constraint.getCreateSQLWithoutIndexes(), false); - } - } - } - if (Table.TABLE.equals(tableType)) { - if (table.canGetRowCount()) { - String rowcount = "-- " + table.getRowCountApproximation() + " +/- SELECT COUNT(*) FROM " - + table.getSQL(); - add(rowcount, false); - } - if (data) { - PlanItem plan = table.getBestPlanItem(session, null); - Index index = plan.getIndex(); - Cursor cursor = index.find(session, null, null); - Column[] columns = table.getColumns(); - StatementBuilder buff = new StatementBuilder("INSERT INTO "); - buff.append(table.getSQL()).append('('); - for (Column col : columns) { - buff.appendExceptFirst(", "); - buff.append(Parser.quoteIdentifier(col.getName())); - } - buff.append(") VALUES"); - if (!simple) { - buff.append('\n'); - } - buff.append('('); - String ins = buff.toString(); - buff = null; - while (cursor.next()) { - Row row = cursor.get(); - if (buff == null) { - buff = new StatementBuilder(ins); - } else { - buff.append(",\n("); - } - for (int j = 0; j < row.getColumnCount(); j++) { - if (j > 0) { - buff.append(", "); - } - Value v = row.getValue(j); - if (v.getPrecision() > lobBlockSize) { - int id; - if (v.getType() == Value.CLOB) { - id = writeLobStream(v); - buff.append("SYSTEM_COMBINE_CLOB(" + id + ")"); - } else if (v.getType() == Value.BLOB) { - id = writeLobStream(v); - buff.append("SYSTEM_COMBINE_BLOB(" + id + ")"); - } else { - buff.append(v.getSQL()); - } - } else { - buff.append(v.getSQL()); - } - } - buff.append(')'); - if (simple || buff.length() > Constants.IO_BUFFER_SIZE) { - add(buff.toString(), true); - buff = null; - } - } - if (buff != null) { - add(buff.toString(), true); - } - } - } - ArrayList indexes = table.getIndexes(); - for (int j = 0; indexes != null && j < indexes.size(); j++) { - Index index = indexes.get(j); - if (!index.getIndexType().getBelongsToConstraint()) { - add(index.getCreateSQL(), false); - } - } - } - if (tempLobTableCreated) { - add("DROP TABLE IF EXISTS SYSTEM_LOB_STREAM", true); - add("CALL SYSTEM_COMBINE_BLOB(-1)", true); - add("DROP ALIAS IF EXISTS SYSTEM_COMBINE_CLOB", true); - add("DROP ALIAS IF EXISTS SYSTEM_COMBINE_BLOB", true); - tempLobTableCreated = false; - } - ArrayList constraints = db.getAllSchemaObjects(DbObject.CONSTRAINT); - Collections.sort(constraints, new Comparator() { - public int compare(SchemaObject c1, SchemaObject c2) { - return ((Constraint) c1).compareTo((Constraint) c2); - } - }); - for (SchemaObject obj : constraints) { - Constraint constraint = (Constraint) obj; - if (constraint.getTable().isHidden()) { - continue; - } - if (!Constraint.PRIMARY_KEY.equals(constraint.getConstraintType())) { - add(constraint.getCreateSQLWithoutIndexes(), false); - } - } - for (SchemaObject obj : db.getAllSchemaObjects(DbObject.TRIGGER)) { - TriggerObject trigger = (TriggerObject) obj; - add(trigger.getCreateSQL(), false); - } - for (Right right : db.getAllRights()) { - add(right.getCreateSQL(), false); - } - for (Comment comment : db.getAllComments()) { - add(comment.getCreateSQL(), false); - } - if (out != null) { - out.close(); - } - } catch (IOException e) { - throw DbException.convertIOException(e, getFileName()); - } finally { - closeIO(); - } - result.done(); - LocalResult r = result; - reset(); - return r; - } - - private int writeLobStream(Value v) throws IOException { - if (!tempLobTableCreated) { - add("CREATE TABLE IF NOT EXISTS SYSTEM_LOB_STREAM(ID INT NOT NULL, PART INT NOT NULL, CDATA VARCHAR, BDATA BINARY)", true); - add("CREATE PRIMARY KEY SYSTEM_LOB_STREAM_PRIMARY_KEY ON SYSTEM_LOB_STREAM(ID, PART)", true); - add("CREATE ALIAS IF NOT EXISTS SYSTEM_COMBINE_CLOB FOR \"" + this.getClass().getName() + ".combineClob\"", true); - add("CREATE ALIAS IF NOT EXISTS SYSTEM_COMBINE_BLOB FOR \"" + this.getClass().getName() + ".combineBlob\"", true); - tempLobTableCreated = true; - } - int id = nextLobId++; - switch (v.getType()) { - case Value.BLOB: { - byte[] bytes = new byte[lobBlockSize]; - InputStream input = v.getInputStream(); - try { - for (int i = 0;; i++) { - StringBuilder buff = new StringBuilder(lobBlockSize * 2); - buff.append("INSERT INTO SYSTEM_LOB_STREAM VALUES(" + id + ", " + i + ", NULL, '"); - int len = IOUtils.readFully(input, bytes, 0, lobBlockSize); - if (len <= 0) { - break; - } - buff.append(Utils.convertBytesToString(bytes, len)).append("')"); - String sql = buff.toString(); - add(sql, true); - } - } finally { - IOUtils.closeSilently(input); - } - break; - } - case Value.CLOB: { - char[] chars = new char[lobBlockSize]; - Reader reader = v.getReader(); - try { - for (int i = 0;; i++) { - StringBuilder buff = new StringBuilder(lobBlockSize * 2); - buff.append("INSERT INTO SYSTEM_LOB_STREAM VALUES(" + id + ", " + i + ", "); - int len = IOUtils.readFully(reader, chars, lobBlockSize); - if (len < 0) { - break; - } - buff.append(StringUtils.quoteStringSQL(new String(chars, 0, len))). - append(", NULL)"); - String sql = buff.toString(); - add(sql, true); - } - } finally { - IOUtils.closeSilently(reader); - } - break; - } - default: - DbException.throwInternalError("type:" + v.getType()); - } - return id; - } - - /** - * Combine a BLOB. - * This method is called from the script. - * When calling with id -1, the file is deleted. - * - * @param conn a connection - * @param id the lob id - * @return a stream for the combined data - */ - public static InputStream combineBlob(Connection conn, int id) throws SQLException { - if (id < 0) { - return null; - } - final ResultSet rs = getLobStream(conn, "BDATA", id); - return new InputStream() { - private InputStream current; - private boolean closed; - public int read() throws IOException { - while (true) { - try { - if (current == null) { - if (closed) { - return -1; - } - if (!rs.next()) { - close(); - return -1; - } - current = rs.getBinaryStream(1); - current = new BufferedInputStream(current); - } - int x = current.read(); - if (x >= 0) { - return x; - } - current = null; - } catch (SQLException e) { - throw DbException.convertToIOException(e); - } - } - } - public void close() throws IOException { - if (closed) { - return; - } - closed = true; - try { - rs.close(); - } catch (SQLException e) { - throw DbException.convertToIOException(e); - } - } - }; - } - - /** - * Combine a CLOB. - * This method is called from the script. - * - * @param conn a connection - * @param id the lob id - * @return a reader for the combined data - */ - public static Reader combineClob(Connection conn, int id) throws SQLException { - if (id < 0) { - return null; - } - final ResultSet rs = getLobStream(conn, "CDATA", id); - return new Reader() { - private Reader current; - private boolean closed; - public int read() throws IOException { - while (true) { - try { - if (current == null) { - if (closed) { - return -1; - } - if (!rs.next()) { - close(); - return -1; - } - current = rs.getCharacterStream(1); - current = new BufferedReader(current); - } - int x = current.read(); - if (x >= 0) { - return x; - } - current = null; - } catch (SQLException e) { - throw DbException.convertToIOException(e); - } - } - } - public void close() throws IOException { - if (closed) { - return; - } - closed = true; - try { - rs.close(); - } catch (SQLException e) { - throw DbException.convertToIOException(e); - } - } - public int read(char[] buffer, int off, int len) throws IOException { - if (len == 0) { - return 0; - } - int c = read(); - if (c == -1) { - return -1; - } - buffer[off] = (char) c; - int i = 1; - for (; i < len; i++) { - c = read(); - if (c == -1) { - break; - } - buffer[off + i] = (char) c; - } - return i; - } - }; - } - - private static ResultSet getLobStream(Connection conn, String column, int id) throws SQLException { - PreparedStatement prep = conn.prepareStatement( - "SELECT " + column + " FROM SYSTEM_LOB_STREAM WHERE ID=? ORDER BY PART"); - prep.setInt(1, id); - return prep.executeQuery(); - } - - private void reset() { - result = null; - buffer = null; - lineSeparator = StringUtils.utf8Encode(SysProperties.LINE_SEPARATOR); - } - - private void add(String s, boolean insert) throws IOException { - if (s == null) { - return; - } - s += ";"; - if (out != null) { - byte[] buff = StringUtils.utf8Encode(s); - int len = MathUtils.roundUpInt(buff.length + lineSeparator.length, Constants.FILE_BLOCK_SIZE); - buffer = Utils.copy(buff, buffer); - - if (len > buffer.length) { - buffer = new byte[len]; - } - System.arraycopy(buff, 0, buffer, 0, buff.length); - for (int i = buff.length; i < len - lineSeparator.length; i++) { - buffer[i] = ' '; - } - for (int j = 0, i = len - lineSeparator.length; i < len; i++, j++) { - buffer[i] = lineSeparator[j]; - } - out.write(buffer, 0, len); - if (!insert) { - Value[] row = { ValueString.get(s) }; - result.addRow(row); - } - } else { - Value[] row = { ValueString.get(s) }; - result.addRow(row); - } - } - - public void setSimple(boolean simple) { - this.simple = simple; - } - -} diff --git a/tools/h2/src/main/org/h2/command/dml/Select.java b/tools/h2/src/main/org/h2/command/dml/Select.java deleted file mode 100755 index 8da5f3a..0000000 --- a/tools/h2/src/main/org/h2/command/dml/Select.java +++ /dev/null @@ -1,1154 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.command.dml; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.HashMap; -import java.util.HashSet; -import org.h2.api.Trigger; -import org.h2.constant.ErrorCode; -import org.h2.constant.SysProperties; -import org.h2.engine.Constants; -import org.h2.engine.Session; -import org.h2.expression.Comparison; -import org.h2.expression.ConditionAndOr; -import org.h2.expression.Expression; -import org.h2.expression.ExpressionColumn; -import org.h2.expression.ExpressionVisitor; -import org.h2.expression.Parameter; -import org.h2.expression.Wildcard; -import org.h2.index.Cursor; -import org.h2.index.Index; -import org.h2.index.IndexType; -import org.h2.message.DbException; -import org.h2.result.LocalResult; -import org.h2.result.ResultInterface; -import org.h2.result.Row; -import org.h2.result.SearchRow; -import org.h2.result.SortOrder; -import org.h2.table.Column; -import org.h2.table.ColumnResolver; -import org.h2.table.IndexColumn; -import org.h2.table.Table; -import org.h2.table.TableFilter; -import org.h2.util.New; -import org.h2.util.StatementBuilder; -import org.h2.util.StringUtils; -import org.h2.util.ValueHashMap; -import org.h2.value.Value; -import org.h2.value.ValueArray; -import org.h2.value.ValueNull; - -/** - * This class represents a simple SELECT statement. - * - * For each select statement, - * visibleColumnCount <= distinctColumnCount <= expressionCount. - * The expression list count could include ORDER BY and GROUP BY expressions - * that are not in the select list. - * - * The call sequence is init(), mapColumns() if it's a subquery, prepare(). - * - * @author Thomas Mueller - * @author Joel Turkel (Group sorted query) - */ -public class Select extends Query { - private TableFilter topTableFilter; - private ArrayList filters = New.arrayList(); - private ArrayList topFilters = New.arrayList(); - private ArrayList expressions; - private Expression[] expressionArray; - private Expression having; - private Expression condition; - private int visibleColumnCount, distinctColumnCount; - private ArrayList orderList; - private ArrayList group; - private int[] groupIndex; - private boolean[] groupByExpression; - private boolean distinct; - private HashMap currentGroup; - private int havingIndex; - private boolean isGroupQuery, isGroupSortedQuery; - private boolean isForUpdate, isForUpdateMvcc; - private double cost; - private boolean isQuickAggregateQuery, isDistinctQuery; - private boolean isPrepared, checkInit; - private boolean sortUsingIndex; - private SortOrder sort; - private int currentGroupRowId; - - public Select(Session session) { - super(session); - } - - /** - * Add a table to the query. - * - * @param filter the table to add - * @param isTop if the table can be the first table in the query plan - */ - public void addTableFilter(TableFilter filter, boolean isTop) { - // Oracle doesn't check on duplicate aliases - // String alias = filter.getAlias(); - // if(filterNames.contains(alias)) { - // throw Message.getSQLException( - // ErrorCode.DUPLICATE_TABLE_ALIAS, alias); - // } - // filterNames.add(alias); - filters.add(filter); - if (isTop) { - topFilters.add(filter); - } - } - - public ArrayList getTopFilters() { - return topFilters; - } - - public void setExpressions(ArrayList expressions) { - this.expressions = expressions; - } - - /** - * Called if this query contains aggregate functions. - */ - public void setGroupQuery() { - isGroupQuery = true; - } - - public void setGroupBy(ArrayList group) { - this.group = group; - } - - public HashMap getCurrentGroup() { - return currentGroup; - } - - public int getCurrentGroupRowId() { - return currentGroupRowId; - } - - public void setOrder(ArrayList order) { - orderList = order; - } - - /** - * Add a condition to the list of conditions. - * - * @param cond the condition to add - */ - public void addCondition(Expression cond) { - if (condition == null) { - condition = cond; - } else { - condition = new ConditionAndOr(ConditionAndOr.AND, cond, condition); - } - } - - private void queryGroupSorted(int columnCount, LocalResult result) { - int rowNumber = 0; - setCurrentRowNumber(0); - Value[] previousKeyValues = null; - while (topTableFilter.next()) { - setCurrentRowNumber(rowNumber + 1); - if (condition == null || Boolean.TRUE.equals(condition.getBooleanValue(session))) { - rowNumber++; - Value[] keyValues = new Value[groupIndex.length]; - // update group - for (int i = 0; i < groupIndex.length; i++) { - int idx = groupIndex[i]; - Expression expr = expressions.get(idx); - keyValues[i] = expr.getValue(session); - } - - if (previousKeyValues == null) { - previousKeyValues = keyValues; - currentGroup = New.hashMap(); - } else if (!Arrays.equals(previousKeyValues, keyValues)) { - addGroupSortedRow(previousKeyValues, columnCount, result); - previousKeyValues = keyValues; - currentGroup = New.hashMap(); - } - currentGroupRowId++; - - for (int i = 0; i < columnCount; i++) { - if (groupByExpression == null || !groupByExpression[i]) { - Expression expr = expressions.get(i); - expr.updateAggregate(session); - } - } - } - } - if (previousKeyValues != null) { - addGroupSortedRow(previousKeyValues, columnCount, result); - } - } - - private void addGroupSortedRow(Value[] keyValues, int columnCount, LocalResult result) { - Value[] row = new Value[columnCount]; - for (int j = 0; groupIndex != null && j < groupIndex.length; j++) { - row[groupIndex[j]] = keyValues[j]; - } - for (int j = 0; j < columnCount; j++) { - if (groupByExpression != null && groupByExpression[j]) { - continue; - } - Expression expr = expressions.get(j); - row[j] = expr.getValue(session); - } - if (isHavingNullOrFalse(row)) { - return; - } - row = keepOnlyDistinct(row, columnCount); - result.addRow(row); - } - - private Value[] keepOnlyDistinct(Value[] row, int columnCount) { - if (columnCount == distinctColumnCount) { - return row; - } - // remove columns so that 'distinct' can filter duplicate rows - Value[] r2 = new Value[distinctColumnCount]; - System.arraycopy(row, 0, r2, 0, distinctColumnCount); - return r2; - } - - private boolean isHavingNullOrFalse(Value[] row) { - if (havingIndex >= 0) { - Value v = row[havingIndex]; - if (v == ValueNull.INSTANCE) { - return true; - } - if (!Boolean.TRUE.equals(v.getBoolean())) { - return true; - } - } - return false; - } - - private Index getGroupSortedIndex() { - if (groupIndex == null || groupByExpression == null) { - return null; - } - ArrayList indexes = topTableFilter.getTable().getIndexes(); - for (int i = 0; indexes != null && i < indexes.size(); i++) { - Index index = indexes.get(i); - if (index.getIndexType().isScan()) { - continue; - } - if (isGroupSortedIndex(topTableFilter, index)) { - return index; - } - } - return null; - } - - private boolean isGroupSortedIndex(TableFilter tableFilter, Index index) { - // check that all the GROUP BY expressions are part of the index - Column[] indexColumns = index.getColumns(); - // also check that the first columns in the index are grouped - boolean[] grouped = new boolean[indexColumns.length]; - outerLoop: - for (int i = 0; i < expressions.size(); i++) { - if (!groupByExpression[i]) { - continue; - } - Expression expr = expressions.get(i); - if (!(expr instanceof ExpressionColumn)) { - return false; - } - ExpressionColumn exprCol = (ExpressionColumn) expr; - for (int j = 0; j < indexColumns.length; ++j) { - if (tableFilter == exprCol.getTableFilter()) { - if (indexColumns[j].equals(exprCol.getColumn())) { - grouped[j] = true; - continue outerLoop; - } - } - } - // We didn't find a matching index column - // for one group by expression - return false; - } - // check that the first columns in the index are grouped - // good: index(a, b, c); group by b, a - // bad: index(a, b, c); group by a, c - for (int i = 1; i < grouped.length; i++) { - if (!grouped[i - 1] && grouped[i]) { - return false; - } - } - return true; - } - - private int getGroupByExpressionCount() { - if (groupByExpression == null) { - return 0; - } - int count = 0; - for (boolean b : groupByExpression) { - if (b) { - ++count; - } - } - return count; - } - - private void queryGroup(int columnCount, LocalResult result) { - ValueHashMap> groups = ValueHashMap.newInstance(); - int rowNumber = 0; - setCurrentRowNumber(0); - ValueArray defaultGroup = ValueArray.get(new Value[0]); - while (topTableFilter.next()) { - setCurrentRowNumber(rowNumber + 1); - if (condition == null || Boolean.TRUE.equals(condition.getBooleanValue(session))) { - Value key; - rowNumber++; - if (groupIndex == null) { - key = defaultGroup; - } else { - Value[] keyValues = new Value[groupIndex.length]; - // update group - for (int i = 0; i < groupIndex.length; i++) { - int idx = groupIndex[i]; - Expression expr = expressions.get(idx); - keyValues[i] = expr.getValue(session); - } - key = ValueArray.get(keyValues); - } - HashMap values = groups.get(key); - if (values == null) { - values = new HashMap(); - groups.put(key, values); - } - currentGroup = values; - currentGroupRowId++; - int len = columnCount; - for (int i = 0; i < len; i++) { - if (groupByExpression == null || !groupByExpression[i]) { - Expression expr = expressions.get(i); - expr.updateAggregate(session); - } - } - if (sampleSize > 0 && rowNumber >= sampleSize) { - break; - } - } - } - if (groupIndex == null && groups.size() == 0) { - groups.put(defaultGroup, new HashMap()); - } - ArrayList keys = groups.keys(); - for (Value v : keys) { - ValueArray key = (ValueArray) v; - currentGroup = groups.get(key); - Value[] keyValues = key.getList(); - Value[] row = new Value[columnCount]; - for (int j = 0; groupIndex != null && j < groupIndex.length; j++) { - row[groupIndex[j]] = keyValues[j]; - } - for (int j = 0; j < columnCount; j++) { - if (groupByExpression != null && groupByExpression[j]) { - continue; - } - Expression expr = expressions.get(j); - row[j] = expr.getValue(session); - } - if (isHavingNullOrFalse(row)) { - continue; - } - row = keepOnlyDistinct(row, columnCount); - result.addRow(row); - } - } - - /** - * Get the index that matches the ORDER BY list, if one exists. This is to - * avoid running a separate ORDER BY if an index can be used. This is - * specially important for large result sets, if only the first few rows are - * important (LIMIT is used) - * - * @return the index if one is found - */ - private Index getSortIndex() { - if (sort == null) { - return null; - } - ArrayList sortColumns = New.arrayList(); - for (int idx : sort.getIndexes()) { - if (idx < 0 || idx >= expressions.size()) { - throw DbException.getInvalidValueException("" + (idx + 1), "ORDER BY"); - } - Expression expr = expressions.get(idx); - expr = expr.getNonAliasExpression(); - if (expr.isConstant()) { - continue; - } - if (!(expr instanceof ExpressionColumn)) { - return null; - } - ExpressionColumn exprCol = (ExpressionColumn) expr; - if (exprCol.getTableFilter() != topTableFilter) { - return null; - } - sortColumns.add(exprCol.getColumn()); - } - Column[] sortCols = sortColumns.toArray(new Column[sortColumns.size()]); - int[] sortTypes = sort.getSortTypes(); - if (sortCols.length == 0) { - // sort just on constants - can use scan index - return topTableFilter.getTable().getScanIndex(session); - } - ArrayList list = topTableFilter.getTable().getIndexes(); - for (int i = 0; list != null && i < list.size(); i++) { - Index index = list.get(i); - if (index.getCreateSQL() == null) { - // can't use the scan index - continue; - } - if (index.getIndexType().isHash()) { - continue; - } - IndexColumn[] indexCols = index.getIndexColumns(); - if (indexCols.length < sortCols.length) { - continue; - } - boolean ok = true; - for (int j = 0; j < sortCols.length; j++) { - // the index and the sort order must start - // with the exact same columns - IndexColumn idxCol = indexCols[j]; - Column sortCol = sortCols[j]; - if (idxCol.column != sortCol) { - ok = false; - break; - } - if (idxCol.sortType != sortTypes[j]) { - // NULL FIRST for ascending and NULLS LAST - // for descending would actually match the default - ok = false; - break; - } - } - if (ok) { - return index; - } - } - return null; - } - - private void queryDistinct(LocalResult result, long limitRows) { - if (limitRows != 0 && offsetExpr != null) { - // limitRows must be long, otherwise we get an int overflow - // if limitRows is at or near Integer.MAX_VALUE - limitRows += offsetExpr.getValue(session).getInt(); - } - int rowNumber = 0; - setCurrentRowNumber(0); - Index index = topTableFilter.getIndex(); - SearchRow first = null; - int columnIndex = index.getColumns()[0].getColumnId(); - while (true) { - setCurrentRowNumber(rowNumber + 1); - Cursor cursor = index.findNext(session, first, null); - if (!cursor.next()) { - break; - } - SearchRow found = cursor.getSearchRow(); - Value value = found.getValue(columnIndex); - if (first == null) { - first = topTableFilter.getTable().getTemplateSimpleRow(true); - } - first.setValue(columnIndex, value); - Value[] row = { value }; - result.addRow(row); - rowNumber++; - if ((sort == null || sortUsingIndex) && limitRows != 0 && result.getRowCount() >= limitRows) { - break; - } - if (sampleSize > 0 && rowNumber >= sampleSize) { - break; - } - } - } - - private void queryFlat(int columnCount, LocalResult result, long limitRows) { - if (limitRows != 0 && offsetExpr != null) { - // limitRows must be long, otherwise we get an int overflow - // if limitRows is at or near Integer.MAX_VALUE - limitRows += offsetExpr.getValue(session).getInt(); - } - int rowNumber = 0; - setCurrentRowNumber(0); - ArrayList forUpdateRows = null; - if (isForUpdateMvcc) { - forUpdateRows = New.arrayList(); - } - while (topTableFilter.next()) { - setCurrentRowNumber(rowNumber + 1); - if (condition == null || Boolean.TRUE.equals(condition.getBooleanValue(session))) { - Value[] row = new Value[columnCount]; - for (int i = 0; i < columnCount; i++) { - Expression expr = expressions.get(i); - row[i] = expr.getValue(session); - } - if (isForUpdateMvcc) { - topTableFilter.lockRow(forUpdateRows); - } - result.addRow(row); - rowNumber++; - if ((sort == null || sortUsingIndex) && limitRows != 0 && result.getRowCount() >= limitRows) { - break; - } - if (sampleSize > 0 && rowNumber >= sampleSize) { - break; - } - } - } - if (isForUpdateMvcc) { - topTableFilter.lockRows(forUpdateRows); - } - } - - private void queryQuick(int columnCount, LocalResult result) { - Value[] row = new Value[columnCount]; - for (int i = 0; i < columnCount; i++) { - Expression expr = expressions.get(i); - row[i] = expr.getValue(session); - } - result.addRow(row); - } - - public ResultInterface queryMeta() { - LocalResult result = new LocalResult(session, expressionArray, visibleColumnCount); - result.done(); - return result; - } - - protected LocalResult queryWithoutCache(int maxRows) { - int limitRows = maxRows; - if (limitExpr != null) { - int l = limitExpr.getValue(session).getInt(); - if (limitRows == 0) { - limitRows = l; - } else { - limitRows = Math.min(l, limitRows); - } - } - int columnCount = expressions.size(); - LocalResult result = new LocalResult(session, expressionArray, visibleColumnCount); - if (!sortUsingIndex || distinct) { - result.setSortOrder(sort); - } - if (distinct && !isDistinctQuery) { - result.setDistinct(); - } - topTableFilter.startQuery(session); - topTableFilter.reset(); - boolean exclusive = isForUpdate && !isForUpdateMvcc; - topTableFilter.lock(session, exclusive, exclusive); - if (isForUpdateMvcc) { - if (isGroupQuery) { - throw DbException.getUnsupportedException("FOR UPDATE && GROUP"); - } else if (distinct) { - throw DbException.getUnsupportedException("FOR UPDATE && DISTINCT"); - } else if (isQuickAggregateQuery) { - throw DbException.getUnsupportedException("FOR UPDATE && AGGREGATE"); - } else if (topTableFilter.getJoin() != null) { - throw DbException.getUnsupportedException("FOR UPDATE && JOIN"); - } else if (topTableFilter.getJoin() != null) { - throw DbException.getUnsupportedException("FOR UPDATE && JOIN"); - } - } - if (isQuickAggregateQuery) { - queryQuick(columnCount, result); - } else if (isGroupQuery) { - if (isGroupSortedQuery) { - queryGroupSorted(columnCount, result); - } else { - queryGroup(columnCount, result); - } - } else if (isDistinctQuery) { - queryDistinct(result, limitRows); - } else { - queryFlat(columnCount, result, limitRows); - } - if (offsetExpr != null) { - result.setOffset(offsetExpr.getValue(session).getInt()); - } - if (limitRows != 0) { - result.setLimit(limitRows); - } - result.done(); - return result; - } - - private void expandColumnList() { - for (int i = 0; i < expressions.size(); i++) { - Expression expr = expressions.get(i); - if (!expr.isWildcard()) { - continue; - } - String schemaName = expr.getSchemaName(); - String tableAlias = expr.getTableAlias(); - if (tableAlias == null) { - int temp = i; - expressions.remove(i); - for (TableFilter filter : filters) { - Wildcard c2 = new Wildcard(filter.getTable().getSchema().getName(), filter.getTableAlias()); - expressions.add(i++, c2); - } - i = temp - 1; - } else { - TableFilter filter = null; - for (TableFilter f : filters) { - if (tableAlias.equals(f.getTableAlias())) { - if (schemaName == null || schemaName.equals(f.getSchemaName())) { - filter = f; - break; - } - } - } - if (filter == null) { - throw DbException.get(ErrorCode.TABLE_OR_VIEW_NOT_FOUND_1, tableAlias); - } - Table t = filter.getTable(); - String alias = filter.getTableAlias(); - expressions.remove(i); - Column[] columns = t.getColumns(); - for (Column c : columns) { - if (filter.isNaturalJoinColumn(c)) { - continue; - } - ExpressionColumn ec = new ExpressionColumn(session.getDatabase(), null, alias, c.getName()); - expressions.add(i++, ec); - } - i--; - } - } - } - - public void init() { - if (SysProperties.CHECK && checkInit) { - DbException.throwInternalError(); - } - expandColumnList(); - visibleColumnCount = expressions.size(); - ArrayList expressionSQL; - if (orderList != null || group != null) { - expressionSQL = New.arrayList(); - for (int i = 0; i < visibleColumnCount; i++) { - Expression expr = expressions.get(i); - expr = expr.getNonAliasExpression(); - String sql = expr.getSQL(); - expressionSQL.add(sql); - } - } else { - expressionSQL = null; - } - if (orderList != null) { - initOrder(expressions, expressionSQL, orderList, visibleColumnCount, distinct); - } - distinctColumnCount = expressions.size(); - if (having != null) { - expressions.add(having); - havingIndex = expressions.size() - 1; - having = null; - } else { - havingIndex = -1; - } - - // first the select list (visible columns), - // then 'ORDER BY' expressions, - // then 'HAVING' expressions, - // and 'GROUP BY' expressions at the end - if (group != null) { - groupIndex = new int[group.size()]; - for (int i = 0; i < group.size(); i++) { - Expression expr = group.get(i); - String sql = expr.getSQL(); - int found = -1; - for (int j = 0; j < expressionSQL.size(); j++) { - String s2 = expressionSQL.get(j); - if (s2.equals(sql)) { - found = j; - break; - } - } - if (found < 0) { - // special case: GROUP BY a column alias - for (int j = 0; j < expressionSQL.size(); j++) { - Expression e = expressions.get(j); - if (sql.equals(e.getAlias())) { - found = j; - break; - } - } - } - if (found < 0) { - int index = expressions.size(); - groupIndex[i] = index; - expressions.add(expr); - } else { - groupIndex[i] = found; - } - } - groupByExpression = new boolean[expressions.size()]; - for (int gi : groupIndex) { - groupByExpression[gi] = true; - } - group = null; - } - // map columns in select list and condition - for (TableFilter f : filters) { - for (Expression expr : expressions) { - expr.mapColumns(f, 0); - } - if (condition != null) { - condition.mapColumns(f, 0); - } - } - if (havingIndex >= 0) { - Expression expr = expressions.get(havingIndex); - SelectListColumnResolver res = new SelectListColumnResolver(this); - expr.mapColumns(res, 0); - } - checkInit = true; - } - - public void prepare() { - if (isPrepared) { - // sometimes a subquery is prepared twice (CREATE TABLE AS SELECT) - return; - } - if (SysProperties.CHECK && !checkInit) { - DbException.throwInternalError("not initialized"); - } - if (orderList != null) { - sort = prepareOrder(orderList, expressions.size()); - orderList = null; - } - for (int i = 0; i < expressions.size(); i++) { - Expression e = expressions.get(i); - expressions.set(i, e.optimize(session)); - } - if (condition != null) { - condition = condition.optimize(session); - for (TableFilter f : filters) { - condition.createIndexConditions(session, f); - } - } - if (isGroupQuery && groupIndex == null && havingIndex < 0 && filters.size() == 1) { - if (condition == null) { - ExpressionVisitor optimizable = ExpressionVisitor.get(ExpressionVisitor.OPTIMIZABLE_MIN_MAX_COUNT_ALL); - optimizable.setTable((filters.get(0)).getTable()); - isQuickAggregateQuery = isEverything(optimizable); - } - } - cost = preparePlan(); - if (SysProperties.OPTIMIZE_DISTINCT && distinct && !isGroupQuery && filters.size() == 1 && expressions.size() == 1 && condition == null) { - Expression expr = expressions.get(0); - expr = expr.getNonAliasExpression(); - if (expr instanceof ExpressionColumn) { - Column column = ((ExpressionColumn) expr).getColumn(); - int selectivity = column.getSelectivity(); - Index columnIndex = topTableFilter.getTable().getIndexForColumn(column, true); - if (columnIndex != null && selectivity != Constants.SELECTIVITY_DEFAULT && selectivity < 20) { - // the first column must be ascending - boolean ascending = columnIndex.getIndexColumns()[0].sortType == SortOrder.ASCENDING; - Index current = topTableFilter.getIndex(); - // if another index is faster - if (columnIndex.canFindNext() && ascending && (current == null || current.getIndexType().isScan() || columnIndex == current)) { - IndexType type = columnIndex.getIndexType(); - // hash indexes don't work, and unique single column indexes don't work - if (!type.isHash() && (!type.isUnique() || columnIndex.getColumns().length > 1)) { - topTableFilter.setIndex(columnIndex); - isDistinctQuery = true; - } - } - } - } - } - if (sort != null && !isQuickAggregateQuery && !isGroupQuery) { - Index index = getSortIndex(); - if (index != null) { - Index current = topTableFilter.getIndex(); - if (current.getIndexType().isScan() || current == index) { - topTableFilter.setIndex(index); - if (!topTableFilter.hasInComparisons()) { - // in(select ...) and in(1,2,3) my return the key is another order - sortUsingIndex = true; - } - } else if (index.getIndexColumns().length >= current.getIndexColumns().length) { - IndexColumn[] sortColumns = index.getIndexColumns(); - IndexColumn[] currentColumns = current.getIndexColumns(); - boolean swapIndex = false; - for (int i = 0; i < currentColumns.length; i++) { - if (sortColumns[i].column != currentColumns[i].column) { - swapIndex = false; - break; - } - if (sortColumns[i].sortType != currentColumns[i].sortType) { - swapIndex = true; - } - } - if (swapIndex) { - topTableFilter.setIndex(index); - sortUsingIndex = true; - } - } - } - } - if (!isQuickAggregateQuery && isGroupQuery && getGroupByExpressionCount() > 0) { - Index index = getGroupSortedIndex(); - Index current = topTableFilter.getIndex(); - if (index != null && (current.getIndexType().isScan() || current == index)) { - topTableFilter.setIndex(index); - isGroupSortedQuery = true; - } - } - expressionArray = new Expression[expressions.size()]; - expressions.toArray(expressionArray); - isPrepared = true; - } - - public double getCost() { - return cost; - } - - public HashSet
getTables() { - HashSet
set = New.hashSet(); - for (TableFilter filter : filters) { - set.add(filter.getTable()); - } - return set; - } - - public void fireBeforeSelectTriggers() { - for (TableFilter filter : filters) { - filter.getTable().fire(session, Trigger.SELECT, true); - } - } - - private double preparePlan() { - TableFilter[] topArray = topFilters.toArray(new TableFilter[topFilters.size()]); - for (TableFilter t : topArray) { - t.setFullCondition(condition); - } - - Optimizer optimizer = new Optimizer(topArray, condition, session); - optimizer.optimize(); - topTableFilter = optimizer.getTopFilter(); - double planCost = optimizer.getCost(); - - TableFilter f = topTableFilter; - while (f != null) { - f.setEvaluatable(f, true); - if (condition != null) { - condition.setEvaluatable(f, true); - } - Expression on = f.getJoinCondition(); - if (on != null) { - if (!on.isEverything(ExpressionVisitor.EVALUATABLE)) { - if (f.isJoinOuter()) { - // this will check if all columns exist - it may or may not throw an exception - on = on.optimize(session); - // it is not supported even if the columns exist - throw DbException.get(ErrorCode.UNSUPPORTED_OUTER_JOIN_CONDITION_1, on.getSQL()); - } - f.removeJoinCondition(); - // need to check that all added are bound to a table - on = on.optimize(session); - addCondition(on); - } - } - on = f.getFilterCondition(); - if (on != null) { - if (!on.isEverything(ExpressionVisitor.EVALUATABLE)) { - f.removeFilterCondition(); - addCondition(on); - } - } - // this is only important for subqueries, so they know - // the result columns are evaluatable - for (Expression e : expressions) { - e.setEvaluatable(f, true); - } - f = f.getJoin(); - } - topTableFilter.prepare(); - return planCost; - } - - public String getPlanSQL() { - // can not use the field sqlStatement because the parameter - // indexes may be incorrect: ? may be in fact ?2 for a subquery - // but indexes may be set manually as well - Expression[] exprList = expressions.toArray(new Expression[expressions.size()]); - StatementBuilder buff = new StatementBuilder("SELECT "); - if (distinct) { - buff.append("DISTINCT "); - } - for (int i = 0; i < visibleColumnCount; i++) { - buff.appendExceptFirst(", "); - buff.append(exprList[i].getSQL()); - } - buff.append("\nFROM "); - TableFilter filter = topTableFilter; - if (filter != null) { - buff.resetCount(); - int i = 0; - do { - buff.appendExceptFirst("\n"); - buff.append(filter.getPlanSQL(i++ > 0)); - filter = filter.getJoin(); - } while (filter != null); - } else { - buff.resetCount(); - int i = 0; - for (TableFilter f : filters) { - buff.appendExceptFirst("\n"); - buff.append(f.getPlanSQL(i++ > 0)); - } - } - if (condition != null) { - buff.append("\nWHERE ").append(StringUtils.unEnclose(condition.getSQL())); - } - if (groupIndex != null) { - buff.append("\nGROUP BY "); - buff.resetCount(); - for (int gi : groupIndex) { - Expression g = exprList[gi]; - g = g.getNonAliasExpression(); - buff.appendExceptFirst(", "); - buff.append(StringUtils.unEnclose(g.getSQL())); - } - } - if (group != null) { - buff.append("\nGROUP BY "); - buff.resetCount(); - for (Expression g : group) { - buff.appendExceptFirst(", "); - buff.append(StringUtils.unEnclose(g.getSQL())); - } - } - if (having != null) { - // could be set in addGlobalCondition - // in this case the query is not run directly, just getPlanSQL is - // called - Expression h = having; - buff.append("\nHAVING ").append(StringUtils.unEnclose(h.getSQL())); - } else if (havingIndex >= 0) { - Expression h = exprList[havingIndex]; - buff.append("\nHAVING ").append(StringUtils.unEnclose(h.getSQL())); - } - if (sort != null) { - buff.append("\nORDER BY ").append(sort.getSQL(exprList, visibleColumnCount)); - } - if (orderList != null) { - buff.append("\nORDER BY "); - buff.resetCount(); - for (SelectOrderBy o : orderList) { - buff.appendExceptFirst(", "); - buff.append(StringUtils.unEnclose(o.getSQL())); - } - } - if (limitExpr != null) { - buff.append("\nLIMIT ").append(StringUtils.unEnclose(limitExpr.getSQL())); - if (offsetExpr != null) { - buff.append(" OFFSET ").append(StringUtils.unEnclose(offsetExpr.getSQL())); - } - } - if (isForUpdate) { - buff.append("\nFOR UPDATE"); - } - if (isQuickAggregateQuery) { - buff.append("\n/* direct lookup */"); - } - if (isDistinctQuery) { - buff.append("\n/* distinct */"); - } - if (sortUsingIndex) { - buff.append("\n/* index sorted */"); - } - if (isGroupQuery) { - if (isGroupSortedQuery) { - buff.append("\n/* group sorted */"); - } - } - return buff.toString(); - } - - public void setDistinct(boolean b) { - distinct = b; - } - - public void setHaving(Expression having) { - this.having = having; - } - - public int getColumnCount() { - return visibleColumnCount; - } - - public TableFilter getTopTableFilter() { - return topTableFilter; - } - - public ArrayList getExpressions() { - return expressions; - } - - public void setForUpdate(boolean b) { - this.isForUpdate = b; - if (SysProperties.SELECT_FOR_UPDATE_MVCC && session.getDatabase().isMultiVersion()) { - isForUpdateMvcc = b; - } - } - - public void mapColumns(ColumnResolver resolver, int level) { - for (Expression e : expressions) { - e.mapColumns(resolver, level); - } - if (condition != null) { - condition.mapColumns(resolver, level); - } - } - - public void setEvaluatable(TableFilter tableFilter, boolean b) { - for (Expression e : expressions) { - e.setEvaluatable(tableFilter, b); - } - if (condition != null) { - condition.setEvaluatable(tableFilter, b); - } - } - - /** - * Check if this is an aggregate query with direct lookup, for example a - * query of the type SELECT COUNT(*) FROM TEST or - * SELECT MAX(ID) FROM TEST. - * - * @return true if a direct lookup is possible - */ - public boolean isQuickAggregateQuery() { - return isQuickAggregateQuery; - } - - public void addGlobalCondition(Parameter param, int columnId, int comparisonType) { - addParameter(param); - Expression comp; - Expression col = expressions.get(columnId); - col = col.getNonAliasExpression(); - if (col.isEverything(ExpressionVisitor.QUERY_COMPARABLE)) { - comp = new Comparison(session, comparisonType, col, param); - } else { - // add the parameters, so they can be set later - comp = new Comparison(session, Comparison.EQUAL, param, param); - } - comp = comp.optimize(session); - boolean addToCondition = true; - if (isGroupQuery) { - addToCondition = false; - for (int i = 0; groupIndex != null && i < groupIndex.length; i++) { - if (groupIndex[i] == columnId) { - addToCondition = true; - break; - } - } - if (!addToCondition) { - if (havingIndex >= 0) { - having = expressions.get(havingIndex); - } - if (having == null) { - having = comp; - } else { - having = new ConditionAndOr(ConditionAndOr.AND, having, comp); - } - } - } - if (addToCondition) { - if (condition == null) { - condition = comp; - } else { - condition = new ConditionAndOr(ConditionAndOr.AND, condition, comp); - } - } - } - - public void updateAggregate(Session s) { - for (Expression e : expressions) { - e.updateAggregate(s); - } - if (condition != null) { - condition.updateAggregate(s); - } - if (having != null) { - having.updateAggregate(s); - } - } - - public boolean isEverything(ExpressionVisitor visitor) { - switch(visitor.getType()) { - case ExpressionVisitor.DETERMINISTIC: { - if (isForUpdate) { - return false; - } - for (TableFilter f : filters) { - if (!f.getTable().isDeterministic()) { - return false; - } - } - break; - } - case ExpressionVisitor.SET_MAX_DATA_MODIFICATION_ID: { - for (TableFilter f : filters) { - long m = f.getTable().getMaxDataModificationId(); - visitor.addDataModificationId(m); - } - break; - } - case ExpressionVisitor.EVALUATABLE: { - if (!SysProperties.OPTIMIZE_EVALUATABLE_SUBQUERIES) { - return false; - } - break; - } - case ExpressionVisitor.GET_DEPENDENCIES: { - for (TableFilter filter : filters) { - Table table = filter.getTable(); - visitor.addDependency(table); - table.addDependencies(visitor.getDependencies()); - } - break; - } - default: - } - visitor.incrementQueryLevel(1); - boolean result = true; - for (Expression e : expressions) { - if (!e.isEverything(visitor)) { - result = false; - break; - } - } - if (result && condition != null && !condition.isEverything(visitor)) { - result = false; - } - if (result && having != null && !having.isEverything(visitor)) { - result = false; - } - visitor.incrementQueryLevel(-1); - return result; - } - - public boolean isReadOnly() { - return isEverything(ExpressionVisitor.READONLY); - } - -} diff --git a/tools/h2/src/main/org/h2/command/dml/SelectListColumnResolver.java b/tools/h2/src/main/org/h2/command/dml/SelectListColumnResolver.java deleted file mode 100755 index 19792a0..0000000 --- a/tools/h2/src/main/org/h2/command/dml/SelectListColumnResolver.java +++ /dev/null @@ -1,80 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.command.dml; - -import java.util.ArrayList; -import org.h2.expression.Expression; -import org.h2.expression.ExpressionColumn; -import org.h2.table.Column; -import org.h2.table.ColumnResolver; -import org.h2.table.TableFilter; -import org.h2.value.Value; - -/** - * This class represents a column resolver for the column list of a SELECT - * statement. It is used to resolve select column aliases in the HAVING clause. - * Example: - *

- * SELECT X/3 AS A, COUNT(*) FROM SYSTEM_RANGE(1, 10) GROUP BY A HAVING A>2; - *

- * - * @author Thomas Mueller - */ -public class SelectListColumnResolver implements ColumnResolver { - - private Select select; - private Expression[] expressions; - private Column[] columns; - - SelectListColumnResolver(Select select) { - this.select = select; - int columnCount = select.getColumnCount(); - columns = new Column[columnCount]; - expressions = new Expression[columnCount]; - ArrayList columnList = select.getExpressions(); - for (int i = 0; i < columnCount; i++) { - Expression expr = columnList.get(i); - Column column = new Column(expr.getAlias(), Value.NULL); - column.setTable(null, i); - columns[i] = column; - expressions[i] = expr.getNonAliasExpression(); - } - } - - public Column[] getColumns() { - return columns; - } - - public String getSchemaName() { - return null; - } - - public Select getSelect() { - return select; - } - - public Column[] getSystemColumns() { - return null; - } - - public String getTableAlias() { - return null; - } - - public TableFilter getTableFilter() { - return null; - } - - public Value getValue(Column column) { - return null; - } - - public Expression optimize(ExpressionColumn expressionColumn, Column column) { - return expressions[column.getColumnId()]; - } - -} diff --git a/tools/h2/src/main/org/h2/command/dml/SelectOrderBy.java b/tools/h2/src/main/org/h2/command/dml/SelectOrderBy.java deleted file mode 100755 index a6185d8..0000000 --- a/tools/h2/src/main/org/h2/command/dml/SelectOrderBy.java +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.command.dml; - -import org.h2.expression.Expression; - -/** - * Describes one element of the ORDER BY clause of a query. - */ -public class SelectOrderBy { - - /** - * The order by expression. - */ - public Expression expression; - - /** - * The column index expression. This can be a column index number (1 meaning - * the first column of the select list) or a parameter (the parameter is a - * number representing the column index number). - */ - public Expression columnIndexExpr; - - /** - * If the column should be sorted descending. - */ - public boolean descending; - - /** - * If NULL should be appear first. - */ - public boolean nullsFirst; - - /** - * If NULL should be appear at the end. - */ - public boolean nullsLast; - - public String getSQL() { - StringBuilder buff = new StringBuilder(); - if (expression != null) { - buff.append('=').append(expression.getSQL()); - } else { - buff.append(columnIndexExpr.getSQL()); - } - if (descending) { - buff.append(" DESC"); - } - if (nullsFirst) { - buff.append(" NULLS FIRST"); - } else if (nullsLast) { - buff.append(" NULLS LAST"); - } - return buff.toString(); - } - -} diff --git a/tools/h2/src/main/org/h2/command/dml/SelectUnion.java b/tools/h2/src/main/org/h2/command/dml/SelectUnion.java deleted file mode 100755 index e7852ca..0000000 --- a/tools/h2/src/main/org/h2/command/dml/SelectUnion.java +++ /dev/null @@ -1,358 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.command.dml; - -import java.util.ArrayList; -import java.util.HashSet; -import org.h2.constant.ErrorCode; -import org.h2.constant.SysProperties; -import org.h2.engine.Session; -import org.h2.expression.Expression; -import org.h2.expression.ExpressionColumn; -import org.h2.expression.ExpressionVisitor; -import org.h2.expression.Parameter; -import org.h2.expression.ValueExpression; -import org.h2.message.DbException; -import org.h2.result.LocalResult; -import org.h2.result.ResultInterface; -import org.h2.result.SortOrder; -import org.h2.table.Column; -import org.h2.table.ColumnResolver; -import org.h2.table.Table; -import org.h2.table.TableFilter; -import org.h2.util.New; -import org.h2.util.StringUtils; -import org.h2.value.Value; -import org.h2.value.ValueInt; - -/** - * Represents a union SELECT statement. - */ -public class SelectUnion extends Query { - - /** - * The type of a UNION statement. - */ - public static final int UNION = 0; - - /** - * The type of a UNION ALL statement. - */ - public static final int UNION_ALL = 1; - - /** - * The type of an EXCEPT statement. - */ - public static final int EXCEPT = 2; - - /** - * The type of an INTERSECT statement. - */ - public static final int INTERSECT = 3; - - private int unionType; - private Query left, right; - private ArrayList expressions; - private Expression[] expressionArray; - private ArrayList orderList; - private SortOrder sort; - private boolean distinct; - private boolean isPrepared, checkInit; - private boolean isForUpdate; - - public SelectUnion(Session session, Query query) { - super(session); - this.left = query; - } - - public void setUnionType(int type) { - this.unionType = type; - } - - public void setRight(Query select) { - right = select; - } - - public void setSQL(String sql) { - this.sqlStatement = sql; - } - - public void setOrder(ArrayList order) { - orderList = order; - } - - private Value[] convert(Value[] values, int columnCount) { - for (int i = 0; i < columnCount; i++) { - Expression e = expressions.get(i); - values[i] = values[i].convertTo(e.getType()); - } - return values; - } - - public ResultInterface queryMeta() { - int columnCount = left.getColumnCount(); - LocalResult result = new LocalResult(session, expressionArray, columnCount); - result.done(); - return result; - } - - protected LocalResult queryWithoutCache(int maxrows) { - if (maxrows != 0) { - if (limitExpr != null) { - maxrows = Math.min(limitExpr.getValue(session).getInt(), maxrows); - } - limitExpr = ValueExpression.get(ValueInt.get(maxrows)); - } - int columnCount = left.getColumnCount(); - LocalResult result = new LocalResult(session, expressionArray, columnCount); - result.setSortOrder(sort); - if (distinct) { - left.setDistinct(true); - right.setDistinct(true); - result.setDistinct(); - } - switch (unionType) { - case UNION: - case EXCEPT: - left.setDistinct(true); - right.setDistinct(true); - result.setDistinct(); - break; - case UNION_ALL: - break; - case INTERSECT: - left.setDistinct(true); - right.setDistinct(true); - break; - default: - DbException.throwInternalError("type=" + unionType); - } - ResultInterface l = left.query(0); - ResultInterface r = right.query(0); - l.reset(); - r.reset(); - switch (unionType) { - case UNION_ALL: - case UNION: { - while (l.next()) { - result.addRow(convert(l.currentRow(), columnCount)); - } - while (r.next()) { - result.addRow(convert(r.currentRow(), columnCount)); - } - break; - } - case EXCEPT: { - while (l.next()) { - result.addRow(convert(l.currentRow(), columnCount)); - } - while (r.next()) { - result.removeDistinct(convert(r.currentRow(), columnCount)); - } - break; - } - case INTERSECT: { - LocalResult temp = new LocalResult(session, expressionArray, columnCount); - temp.setDistinct(); - while (l.next()) { - temp.addRow(convert(l.currentRow(), columnCount)); - } - while (r.next()) { - Value[] values = convert(r.currentRow(), columnCount); - if (temp.containsDistinct(values)) { - result.addRow(values); - } - } - break; - } - default: - DbException.throwInternalError("type=" + unionType); - } - if (offsetExpr != null) { - result.setOffset(offsetExpr.getValue(session).getInt()); - } - if (limitExpr != null) { - result.setLimit(limitExpr.getValue(session).getInt()); - } - result.done(); - return result; - } - - public void init() { - if (SysProperties.CHECK && checkInit) { - DbException.throwInternalError(); - } - checkInit = true; - left.init(); - right.init(); - int len = left.getColumnCount(); - if (len != right.getColumnCount()) { - throw DbException.get(ErrorCode.COLUMN_COUNT_DOES_NOT_MATCH); - } - ArrayList le = left.getExpressions(); - // set the expressions to get the right column count and names, - // but can't validate at this time - expressions = New.arrayList(); - for (int i = 0; i < len; i++) { - Expression l = le.get(i); - expressions.add(l); - } - } - - public void prepare() { - if (isPrepared) { - // sometimes a subquery is prepared twice (CREATE TABLE AS SELECT) - return; - } - if (SysProperties.CHECK && !checkInit) { - DbException.throwInternalError("not initialized"); - } - isPrepared = true; - left.prepare(); - right.prepare(); - int len = left.getColumnCount(); - // set the correct expressions now - expressions = New.arrayList(); - ArrayList le = left.getExpressions(); - ArrayList re = right.getExpressions(); - for (int i = 0; i < len; i++) { - Expression l = le.get(i); - Expression r = re.get(i); - int type = Value.getHigherOrder(l.getType(), r.getType()); - long prec = Math.max(l.getPrecision(), r.getPrecision()); - int scale = Math.max(l.getScale(), r.getScale()); - int displaySize = Math.max(l.getDisplaySize(), r.getDisplaySize()); - Column col = new Column(l.getAlias(), type, prec, scale, displaySize); - Expression e = new ExpressionColumn(session.getDatabase(), col); - expressions.add(e); - } - if (orderList != null) { - initOrder(expressions, null, orderList, getColumnCount(), true); - sort = prepareOrder(orderList, expressions.size()); - orderList = null; - } - expressionArray = new Expression[expressions.size()]; - expressions.toArray(expressionArray); - } - - public double getCost() { - return left.getCost() + right.getCost(); - } - - public HashSet
getTables() { - HashSet
set = left.getTables(); - set.addAll(right.getTables()); - return set; - } - - public void setDistinct(boolean b) { - distinct = b; - } - - public ArrayList getExpressions() { - return expressions; - } - - public void setForUpdate(boolean forUpdate) { - left.setForUpdate(forUpdate); - right.setForUpdate(forUpdate); - isForUpdate = forUpdate; - } - - public int getColumnCount() { - return left.getColumnCount(); - } - - public void mapColumns(ColumnResolver resolver, int level) { - left.mapColumns(resolver, level); - right.mapColumns(resolver, level); - } - - public void setEvaluatable(TableFilter tableFilter, boolean b) { - left.setEvaluatable(tableFilter, b); - right.setEvaluatable(tableFilter, b); - } - - public void addGlobalCondition(Parameter param, int columnId, int comparisonType) { - addParameter(param); - switch (unionType) { - case UNION_ALL: - case UNION: - case INTERSECT: { - left.addGlobalCondition(param, columnId, comparisonType); - right.addGlobalCondition(param, columnId, comparisonType); - break; - } - case EXCEPT: { - left.addGlobalCondition(param, columnId, comparisonType); - break; - } - default: - DbException.throwInternalError("type=" + unionType); - } - } - - public String getPlanSQL() { - StringBuilder buff = new StringBuilder(); - buff.append('(').append(left.getPlanSQL()).append(')'); - switch (unionType) { - case UNION_ALL: - buff.append(" UNION ALL "); - break; - case UNION: - buff.append(" UNION "); - break; - case INTERSECT: - buff.append(" INTERSECT "); - break; - case EXCEPT: - buff.append(" EXCEPT "); - break; - default: - DbException.throwInternalError("type=" + unionType); - } - buff.append('(').append(right.getPlanSQL()).append(')'); - Expression[] exprList = expressions.toArray(new Expression[expressions.size()]); - if (sort != null) { - buff.append(" ORDER BY ").append(sort.getSQL(exprList, exprList.length)); - } - if (limitExpr != null) { - buff.append(" LIMIT ").append(StringUtils.unEnclose(limitExpr.getSQL())); - if (offsetExpr != null) { - buff.append(" OFFSET ").append(StringUtils.unEnclose(offsetExpr.getSQL())); - } - } - if (isForUpdate) { - buff.append(" FOR UPDATE"); - } - return buff.toString(); - } - - public ResultInterface query(int limit) { - // union doesn't always know the parameter list of the left and right queries - return queryWithoutCache(limit); - } - - public boolean isEverything(ExpressionVisitor visitor) { - return left.isEverything(visitor) && right.isEverything(visitor); - } - - public boolean isReadOnly() { - return left.isReadOnly() && right.isReadOnly(); - } - - public void updateAggregate(Session s) { - left.updateAggregate(s); - right.updateAggregate(s); - } - - public void fireBeforeSelectTriggers() { - left.fireBeforeSelectTriggers(); - right.fireBeforeSelectTriggers(); - } - -} diff --git a/tools/h2/src/main/org/h2/command/dml/Set.java b/tools/h2/src/main/org/h2/command/dml/Set.java deleted file mode 100755 index 748c1af..0000000 --- a/tools/h2/src/main/org/h2/command/dml/Set.java +++ /dev/null @@ -1,409 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.command.dml; - -import java.text.Collator; -import org.h2.command.Prepared; -import org.h2.compress.Compressor; -import org.h2.constant.ErrorCode; -import org.h2.engine.Database; -import org.h2.engine.Mode; -import org.h2.engine.Session; -import org.h2.engine.Setting; -import org.h2.expression.Expression; -import org.h2.expression.ValueExpression; -import org.h2.message.DbException; -import org.h2.result.ResultInterface; -import org.h2.schema.Schema; -import org.h2.table.Table; -import org.h2.tools.CompressTool; -import org.h2.util.StringUtils; -import org.h2.value.CompareMode; -import org.h2.value.ValueInt; - -/** - * This class represents the statement - * SET - */ -public class Set extends Prepared { - - private int type; - private Expression expression; - private String stringValue; - private String[] stringValueList; - - public Set(Session session, int type) { - super(session); - this.type = type; - } - - public void setString(String v) { - this.stringValue = v; - } - - public boolean isTransactional() { - switch (type) { - case SetTypes.CLUSTER: - case SetTypes.VARIABLE: - case SetTypes.QUERY_TIMEOUT: - case SetTypes.LOCK_TIMEOUT: - case SetTypes.TRACE_LEVEL_SYSTEM_OUT: - case SetTypes.TRACE_LEVEL_FILE: - case SetTypes.THROTTLE: - case SetTypes.SCHEMA: - case SetTypes.SCHEMA_SEARCH_PATH: - return true; - default: - } - return false; - } - - public int update() { - Database database = session.getDatabase(); - String name = SetTypes.getTypeName(type); - switch (type) { - case SetTypes.ALLOW_LITERALS: { - session.getUser().checkAdmin(); - int value = getIntValue(); - if (value < 0 || value > 2) { - throw DbException.getInvalidValueException("" + getIntValue(), "ALLOW_LITERALS"); - } - database.setAllowLiterals(value); - addOrUpdateSetting(name, null, value); - break; - } - case SetTypes.CACHE_SIZE: - session.getUser().checkAdmin(); - database.setCacheSize(getIntValue()); - addOrUpdateSetting(name, null, getIntValue()); - break; - case SetTypes.CLUSTER: { - String value = StringUtils.quoteStringSQL(stringValue); - if (!value.equals(database.getCluster()) && !value.equals("''")) { - // anybody can disable the cluster - // (if he can't access a cluster node) - session.getUser().checkAdmin(); - } - database.setCluster(value); - // use the system session so that the current transaction - // (if any) is not committed - addOrUpdateSetting(database.getSystemSession(), name, value, 0); - database.getSystemSession().commit(true); - break; - } - case SetTypes.COLLATION: { - session.getUser().checkAdmin(); - Table table = database.getFirstUserTable(); - if (table != null) { - throw DbException.get(ErrorCode.COLLATION_CHANGE_WITH_DATA_TABLE_1, table.getSQL()); - } - CompareMode compareMode; - StringBuilder buff = new StringBuilder(stringValue); - if (stringValue.equals(CompareMode.OFF)) { - compareMode = CompareMode.getInstance(null, 0); - } else { - int strength = getIntValue(); - buff.append(" STRENGTH "); - if (strength == Collator.IDENTICAL) { - buff.append("IDENTICAL"); - } else if (strength == Collator.PRIMARY) { - buff.append("PRIMARY"); - } else if (strength == Collator.SECONDARY) { - buff.append("SECONDARY"); - } else if (strength == Collator.TERTIARY) { - buff.append("TERTIARY"); - } - compareMode = CompareMode.getInstance(stringValue, strength); - } - addOrUpdateSetting(name, buff.toString(), 0); - database.setCompareMode(compareMode); - break; - } - case SetTypes.COMPRESS_LOB: { - session.getUser().checkAdmin(); - int algo = CompressTool.getInstance().getCompressAlgorithm(stringValue); - database.setLobCompressionAlgorithm(algo == Compressor.NO ? null : stringValue); - addOrUpdateSetting(name, stringValue, 0); - break; - } - case SetTypes.CREATE_BUILD: { - session.getUser().checkAdmin(); - if (database.isStarting()) { - // just ignore the command if not starting - // this avoids problems when running recovery scripts - int value = getIntValue(); - addOrUpdateSetting(name, null, value); - } - break; - } - case SetTypes.DATABASE_EVENT_LISTENER: { - session.getUser().checkAdmin(); - database.setEventListenerClass(stringValue); - break; - } - case SetTypes.DB_CLOSE_DELAY: { - session.getUser().checkAdmin(); - database.setCloseDelay(getIntValue()); - addOrUpdateSetting(name, null, getIntValue()); - break; - } - case SetTypes.DEFAULT_LOCK_TIMEOUT: - session.getUser().checkAdmin(); - addOrUpdateSetting(name, null, getIntValue()); - break; - case SetTypes.DEFAULT_TABLE_TYPE: - session.getUser().checkAdmin(); - addOrUpdateSetting(name, null, getIntValue()); - break; - case SetTypes.EXCLUSIVE: { - session.getUser().checkAdmin(); - int value = getIntValue(); - switch (value) { - case 0: - database.setExclusiveSession(null, false); - break; - case 1: - database.setExclusiveSession(session, false); - break; - case 2: - database.setExclusiveSession(session, true); - break; - default: - throw DbException.getInvalidValueException("" + value, "EXCLUSIVE"); - } - break; - } - case SetTypes.IGNORECASE: - session.getUser().checkAdmin(); - database.setIgnoreCase(getIntValue() == 1); - addOrUpdateSetting(name, null, getIntValue()); - break; - case SetTypes.LOCK_MODE: - session.getUser().checkAdmin(); - database.setLockMode(getIntValue()); - addOrUpdateSetting(name, null, getIntValue()); - break; - case SetTypes.LOCK_TIMEOUT: - session.setLockTimeout(getIntValue()); - break; - case SetTypes.LOG: { - int value = getIntValue(); - if (value < 0 || value > 2) { - throw DbException.getInvalidValueException("" + getIntValue(), "LOG"); - } - if (value == 0) { - session.getUser().checkAdmin(); - } - // currently no effect - break; - } - case SetTypes.MAX_LENGTH_INPLACE_LOB: { - if (getIntValue() < 0) { - throw DbException.getInvalidValueException("" + getIntValue(), "MAX_LENGTH_INPLACE_LOB"); - } - session.getUser().checkAdmin(); - database.setMaxLengthInplaceLob(getIntValue()); - addOrUpdateSetting(name, null, getIntValue()); - break; - } - case SetTypes.MAX_LOG_SIZE: - session.getUser().checkAdmin(); - database.setMaxLogSize((long) getIntValue() * 1024 * 1024); - addOrUpdateSetting(name, null, getIntValue()); - break; - case SetTypes.MAX_MEMORY_ROWS: { - session.getUser().checkAdmin(); - database.setMaxMemoryRows(getIntValue()); - addOrUpdateSetting(name, null, getIntValue()); - break; - } - case SetTypes.MAX_MEMORY_UNDO: { - if (getIntValue() < 0) { - throw DbException.getInvalidValueException("" + getIntValue(), "MAX_MEMORY_UNDO"); - } - session.getUser().checkAdmin(); - database.setMaxMemoryUndo(getIntValue()); - addOrUpdateSetting(name, null, getIntValue()); - break; - } - case SetTypes.MAX_OPERATION_MEMORY: { - session.getUser().checkAdmin(); - int value = getIntValue(); - database.setMaxOperationMemory(value); - break; - } - case SetTypes.MODE: - session.getUser().checkAdmin(); - Mode mode = Mode.getInstance(stringValue); - if (mode == null) { - throw DbException.get(ErrorCode.UNKNOWN_MODE_1, stringValue); - } - database.setMode(mode); - break; - case SetTypes.MULTI_THREADED: { - session.getUser().checkAdmin(); - database.setMultiThreaded(getIntValue() == 1); - break; - } - case SetTypes.MVCC: { - if (database.isMultiVersion() != (getIntValue() == 1)) { - throw DbException.get(ErrorCode.CANNOT_CHANGE_SETTING_WHEN_OPEN_1, "MVCC"); - } - break; - } - case SetTypes.OPTIMIZE_REUSE_RESULTS: { - session.getUser().checkAdmin(); - database.setOptimizeReuseResults(getIntValue() != 0); - break; - } - case SetTypes.QUERY_TIMEOUT: { - int value = getIntValue(); - session.setQueryTimeout(value); - break; - } - case SetTypes.REDO_LOG_BINARY: { - int value = getIntValue(); - session.setRedoLogBinary(value == 1); - break; - } - case SetTypes.REFERENTIAL_INTEGRITY: { - session.getUser().checkAdmin(); - int value = getIntValue(); - if (value < 0 || value > 1) { - throw DbException.getInvalidValueException("" + getIntValue(), "REFERENTIAL_INTEGRITY"); - } - database.setReferentialIntegrity(value == 1); - break; - } - case SetTypes.SCHEMA: { - Schema schema = database.getSchema(stringValue); - session.setCurrentSchema(schema); - break; - } - case SetTypes.SCHEMA_SEARCH_PATH: { - session.setSchemaSearchPath(stringValueList); - break; - } - case SetTypes.TRACE_LEVEL_FILE: - session.getUser().checkAdmin(); - if (getCurrentObjectId() == 0) { - // don't set the property when opening the database - // this is for compatibility with older versions, because - // this setting was persistent - database.getTraceSystem().setLevelFile(getIntValue()); - } - break; - case SetTypes.TRACE_LEVEL_SYSTEM_OUT: - session.getUser().checkAdmin(); - if (getCurrentObjectId() == 0) { - // don't set the property when opening the database - // this is for compatibility with older versions, because - // this setting was persistent - database.getTraceSystem().setLevelSystemOut(getIntValue()); - } - break; - case SetTypes.TRACE_MAX_FILE_SIZE: { - session.getUser().checkAdmin(); - int size = getIntValue() * 1024 * 1024; - database.getTraceSystem().setMaxFileSize(size); - addOrUpdateSetting(name, null, getIntValue()); - break; - } - case SetTypes.THROTTLE: { - if (getIntValue() < 0) { - throw DbException.getInvalidValueException("" + getIntValue(), "THROTTLE"); - } - session.setThrottle(getIntValue()); - break; - } - case SetTypes.UNDO_LOG: { - int value = getIntValue(); - if (value < 0 || value > 1) { - throw DbException.getInvalidValueException("" + getIntValue(), "UNDO_LOG"); - } - session.setUndoLogEnabled(value == 1); - break; - } - case SetTypes.VARIABLE: { - Expression expr = expression.optimize(session); - session.setVariable(stringValue, expr.getValue(session)); - break; - } - case SetTypes.WRITE_DELAY: { - session.getUser().checkAdmin(); - database.setWriteDelay(getIntValue()); - addOrUpdateSetting(name, null, getIntValue()); - break; - } - default: - DbException.throwInternalError("type="+type); - } - // the meta data information has changed - database.getNextModificationDataId(); - return 0; - } - - private int getIntValue() { - expression = expression.optimize(session); - return expression.getValue(session).getInt(); - } - - public void setInt(int value) { - this.expression = ValueExpression.get(ValueInt.get(value)); - } - - public void setExpression(Expression expression) { - this.expression = expression; - } - - private void addOrUpdateSetting(String name, String s, int v) { - addOrUpdateSetting(session, name, s, v); - } - - private void addOrUpdateSetting(Session session, String name, String s, int v) { - Database database = session.getDatabase(); - if (database.isReadOnly()) { - return; - } - Setting setting = database.findSetting(name); - boolean addNew = false; - if (setting == null) { - addNew = true; - int id = getObjectId(); - setting = new Setting(database, id, name); - } - if (s != null) { - if (!addNew && setting.getStringValue().equals(s)) { - return; - } - setting.setStringValue(s); - } else { - if (!addNew && setting.getIntValue() == v) { - return; - } - setting.setIntValue(v); - } - if (addNew) { - database.addDatabaseObject(session, setting); - } else { - database.update(session, setting); - } - } - - public boolean needRecompile() { - return false; - } - - public ResultInterface queryMeta() { - return null; - } - - public void setStringArray(String[] list) { - this.stringValueList = list; - } - -} diff --git a/tools/h2/src/main/org/h2/command/dml/SetTypes.java b/tools/h2/src/main/org/h2/command/dml/SetTypes.java deleted file mode 100755 index e44a481..0000000 --- a/tools/h2/src/main/org/h2/command/dml/SetTypes.java +++ /dev/null @@ -1,279 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.command.dml; - -import java.util.ArrayList; -import org.h2.util.New; - -/** - * The list of setting for a SET statement. - */ -public class SetTypes { - - /** - * The type of a SET IGNORECASE statement. - */ - public static final int IGNORECASE = 1; - - /** - * The type of a SET MAX_LOG_SIZE statement. - */ - public static final int MAX_LOG_SIZE = 2; - - /** - * The type of a SET MODE statement. - */ - public static final int MODE = 3; - - /** - * The type of a SET READONLY statement. - */ - public static final int READONLY = 4; - - /** - * The type of a SET LOCK_TIMEOUT statement. - */ - public static final int LOCK_TIMEOUT = 5; - - /** - * The type of a SET DEFAULT_LOCK_TIMEOUT statement. - */ - public static final int DEFAULT_LOCK_TIMEOUT = 6; - - /** - * The type of a SET DEFAULT_TABLE_TYPE statement. - */ - public static final int DEFAULT_TABLE_TYPE = 7; - - /** - * The type of a SET CACHE_SIZE statement. - */ - public static final int CACHE_SIZE = 8; - - /** - * The type of a SET TRACE_LEVEL_SYSTEM_OUT statement. - */ - public static final int TRACE_LEVEL_SYSTEM_OUT = 9; - - /** - * The type of a SET TRACE_LEVEL_FILE statement. - */ - public static final int TRACE_LEVEL_FILE = 10; - - /** - * The type of a SET TRACE_MAX_FILE_SIZE statement. - */ - public static final int TRACE_MAX_FILE_SIZE = 11; - - /** - * The type of a SET COLLATION statement. - */ - public static final int COLLATION = 12; - - /** - * The type of a SET CLUSTER statement. - */ - public static final int CLUSTER = 13; - - /** - * The type of a SET WRITE_DELAY statement. - */ - public static final int WRITE_DELAY = 14; - - /** - * The type of a SET DATABASE_EVENT_LISTENER statement. - */ - public static final int DATABASE_EVENT_LISTENER = 15; - - /** - * The type of a SET MAX_MEMORY_ROWS statement. - */ - public static final int MAX_MEMORY_ROWS = 16; - - /** - * The type of a SET LOCK_MODE statement. - */ - public static final int LOCK_MODE = 17; - - /** - * The type of a SET DB_CLOSE_DELAY statement. - */ - public static final int DB_CLOSE_DELAY = 18; - - /** - * The type of a SET LOG statement. - */ - public static final int LOG = 19; - - /** - * The type of a SET THROTTLE statement. - */ - public static final int THROTTLE = 20; - - /** - * The type of a SET MAX_MEMORY_UNDO statement. - */ - public static final int MAX_MEMORY_UNDO = 21; - - /** - * The type of a SET MAX_LENGTH_INPLACE_LOB statement. - */ - public static final int MAX_LENGTH_INPLACE_LOB = 22; - - /** - * The type of a SET COMPRESS_LOB statement. - */ - public static final int COMPRESS_LOB = 23; - - /** - * The type of a SET ALLOW_LITERALS statement. - */ - public static final int ALLOW_LITERALS = 24; - - /** - * The type of a SET MULTI_THREADED statement. - */ - public static final int MULTI_THREADED = 25; - - /** - * The type of a SET SCHEMA statement. - */ - public static final int SCHEMA = 26; - - /** - * The type of a SET OPTIMIZE_REUSE_RESULTS statement. - */ - public static final int OPTIMIZE_REUSE_RESULTS = 27; - - /** - * The type of a SET SCHEMA_SEARCH_PATH statement. - */ - public static final int SCHEMA_SEARCH_PATH = 28; - - /** - * The type of a SET UNDO_LOG statement. - */ - public static final int UNDO_LOG = 29; - - /** - * The type of a SET REFERENTIAL_INTEGRITY statement. - */ - public static final int REFERENTIAL_INTEGRITY = 30; - - /** - * The type of a SET MVCC statement. - */ - public static final int MVCC = 31; - - /** - * The type of a SET MAX_OPERATION_MEMORY statement. - */ - public static final int MAX_OPERATION_MEMORY = 32; - - /** - * The type of a SET EXCLUSIVE statement. - */ - public static final int EXCLUSIVE = 33; - - /** - * The type of a SET CREATE_BUILD statement. - */ - public static final int CREATE_BUILD = 34; - - /** - * The type of a SET \@VARIABLE statement. - */ - public static final int VARIABLE = 35; - - /** - * The type of a SET QUERY_TIMEOUT statement. - */ - public static final int QUERY_TIMEOUT = 36; - - /** - * The type of a SET REDO_LOG_BINARY statement. - */ - public static final int REDO_LOG_BINARY = 37; - - private static final ArrayList TYPES = New.arrayList(); - - private SetTypes() { - // utility class - } - - static { - ArrayList list = TYPES; - list.add(null); - list.add(IGNORECASE, "IGNORECASE"); - list.add(MAX_LOG_SIZE, "MAX_LOG_SIZE"); - list.add(MODE, "MODE"); - list.add(READONLY, "READONLY"); - list.add(LOCK_TIMEOUT, "LOCK_TIMEOUT"); - list.add(DEFAULT_LOCK_TIMEOUT, "DEFAULT_LOCK_TIMEOUT"); - list.add(DEFAULT_TABLE_TYPE, "DEFAULT_TABLE_TYPE"); - list.add(CACHE_SIZE, "CACHE_SIZE"); - list.add(TRACE_LEVEL_SYSTEM_OUT, "TRACE_LEVEL_SYSTEM_OUT"); - list.add(TRACE_LEVEL_FILE, "TRACE_LEVEL_FILE"); - list.add(TRACE_MAX_FILE_SIZE, "TRACE_MAX_FILE_SIZE"); - list.add(COLLATION, "COLLATION"); - list.add(CLUSTER, "CLUSTER"); - list.add(WRITE_DELAY, "WRITE_DELAY"); - list.add(DATABASE_EVENT_LISTENER, "DATABASE_EVENT_LISTENER"); - list.add(MAX_MEMORY_ROWS, "MAX_MEMORY_ROWS"); - list.add(LOCK_MODE, "LOCK_MODE"); - list.add(DB_CLOSE_DELAY, "DB_CLOSE_DELAY"); - list.add(LOG, "LOG"); - list.add(THROTTLE, "THROTTLE"); - list.add(MAX_MEMORY_UNDO, "MAX_MEMORY_UNDO"); - list.add(MAX_LENGTH_INPLACE_LOB, "MAX_LENGTH_INPLACE_LOB"); - list.add(COMPRESS_LOB, "COMPRESS_LOB"); - list.add(ALLOW_LITERALS, "ALLOW_LITERALS"); - list.add(MULTI_THREADED, "MULTI_THREADED"); - list.add(SCHEMA, "SCHEMA"); - list.add(OPTIMIZE_REUSE_RESULTS, "OPTIMIZE_REUSE_RESULTS"); - list.add(SCHEMA_SEARCH_PATH, "SCHEMA_SEARCH_PATH"); - list.add(UNDO_LOG, "UNDO_LOG"); - list.add(REFERENTIAL_INTEGRITY, "REFERENTIAL_INTEGRITY"); - list.add(MVCC, "MVCC"); - list.add(MAX_OPERATION_MEMORY, "MAX_OPERATION_MEMORY"); - list.add(EXCLUSIVE, "EXCLUSIVE"); - list.add(CREATE_BUILD, "CREATE_BUILD"); - list.add(VARIABLE, "@"); - list.add(QUERY_TIMEOUT, "QUERY_TIMEOUT"); - list.add(REDO_LOG_BINARY, "REDO_LOG_BINARY"); - } - - /** - * Get the set type number. - * - * @param name the set type name - * @return the number - */ - public static int getType(String name) { - for (int i = 0; i < getTypes().size(); i++) { - if (name.equals(getTypes().get(i))) { - return i; - } - } - return -1; - } - - public static ArrayList getTypes() { - return TYPES; - } - - /** - * Get the set type name. - * - * @param type the type number - * @return the name - */ - public static String getTypeName(int type) { - return getTypes().get(type); - } - -} diff --git a/tools/h2/src/main/org/h2/command/dml/TransactionCommand.java b/tools/h2/src/main/org/h2/command/dml/TransactionCommand.java deleted file mode 100755 index 6650912..0000000 --- a/tools/h2/src/main/org/h2/command/dml/TransactionCommand.java +++ /dev/null @@ -1,208 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.command.dml; - -import org.h2.command.Prepared; -import org.h2.engine.Database; -import org.h2.engine.Session; -import org.h2.message.DbException; -import org.h2.result.ResultInterface; - -/** - * Represents a transactional statement. - */ -public class TransactionCommand extends Prepared { - - /** - * The type of a SET AUTOCOMMIT TRUE statement. - */ - public static final int AUTOCOMMIT_TRUE = 1; - - /** - * The type of a SET AUTOCOMMIT FALSE statement. - */ - public static final int AUTOCOMMIT_FALSE = 2; - - /** - * The type of a COMMIT statement. - */ - public static final int COMMIT = 3; - - /** - * The type of a ROLLBACK statement. - */ - public static final int ROLLBACK = 4; - - /** - * The type of a CHECKPOINT statement. - */ - public static final int CHECKPOINT = 5; - - /** - * The type of a SAVEPOINT statement. - */ - public static final int SAVEPOINT = 6; - - /** - * The type of a ROLLBACK TO SAVEPOINT statement. - */ - public static final int ROLLBACK_TO_SAVEPOINT = 7; - - /** - * The type of a CHECKPOINT SYNC statement. - */ - public static final int CHECKPOINT_SYNC = 8; - - /** - * The type of a PREPARE COMMIT statement. - */ - public static final int PREPARE_COMMIT = 9; - - /** - * The type of a COMMIT TRANSACTION statement. - */ - public static final int COMMIT_TRANSACTION = 10; - - /** - * The type of a ROLLBACK TRANSACTION statement. - */ - public static final int ROLLBACK_TRANSACTION = 11; - - /** - * The type of a SHUTDOWN statement. - */ - public static final int SHUTDOWN = 12; - - /** - * The type of a SHUTDOWN IMMEDIATELY statement. - */ - public static final int SHUTDOWN_IMMEDIATELY = 13; - - /** - * The type of a SHUTDOWN COMPACT statement. - */ - public static final int SHUTDOWN_COMPACT = 14; - - /** - * The type of a BEGIN {WORK|TRANSACTION} statement. - */ - public static final int BEGIN = 15; - - private int type; - private String savepointName; - private String transactionName; - - public TransactionCommand(Session session, int type) { - super(session); - this.type = type; - } - - public void setSavepointName(String name) { - this.savepointName = name; - } - - public int update() { - switch (type) { - case AUTOCOMMIT_TRUE: - session.setAutoCommit(true); - break; - case AUTOCOMMIT_FALSE: - session.setAutoCommit(false); - break; - case BEGIN: - session.begin(); - break; - case COMMIT: - session.commit(false); - break; - case ROLLBACK: - session.rollback(); - break; - case CHECKPOINT: - session.getUser().checkAdmin(); - session.getDatabase().checkpoint(); - break; - case SAVEPOINT: - session.addSavepoint(savepointName); - break; - case ROLLBACK_TO_SAVEPOINT: - session.rollbackToSavepoint(savepointName); - break; - case CHECKPOINT_SYNC: - session.getUser().checkAdmin(); - session.getDatabase().sync(); - break; - case PREPARE_COMMIT: - session.prepareCommit(transactionName); - break; - case COMMIT_TRANSACTION: - session.getUser().checkAdmin(); - session.setPreparedTransaction(transactionName, true); - break; - case ROLLBACK_TRANSACTION: - session.getUser().checkAdmin(); - session.setPreparedTransaction(transactionName, false); - break; - case SHUTDOWN_IMMEDIATELY: - session.getUser().checkAdmin(); - session.getDatabase().shutdownImmediately(); - break; - case SHUTDOWN: - case SHUTDOWN_COMPACT: { - session.getUser().checkAdmin(); - session.commit(false); - if (type == SHUTDOWN_COMPACT) { - session.getDatabase().setCompactFully(true); - } - // close the database, but don't update the persistent setting - session.getDatabase().setCloseDelay(0); - Database db = session.getDatabase(); - // throttle, to allow testing concurrent - // execution of shutdown and query - session.throttle(); - for (Session s : db.getSessions(false)) { - if (db.isMultiThreaded()) { - synchronized (s) { - s.rollback(); - } - } else { - // if not multi-threaded, the session could already own - // the lock, which would result in a deadlock - // the other session can not concurrently do anything - // because the current session has locked the database - s.rollback(); - } - if (s != session) { - s.close(); - } - } - session.close(); - break; - } - default: - DbException.throwInternalError("type=" + type); - } - return 0; - } - - public boolean isTransactional() { - return true; - } - - public boolean needRecompile() { - return false; - } - - public void setTransactionName(String string) { - this.transactionName = string; - } - - public ResultInterface queryMeta() { - return null; - } - -} diff --git a/tools/h2/src/main/org/h2/command/dml/Update.java b/tools/h2/src/main/org/h2/command/dml/Update.java deleted file mode 100755 index 76964ed..0000000 --- a/tools/h2/src/main/org/h2/command/dml/Update.java +++ /dev/null @@ -1,185 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.command.dml; - -import org.h2.api.Trigger; -import org.h2.command.Prepared; -import org.h2.constant.ErrorCode; -import org.h2.engine.Right; -import org.h2.engine.Session; -import org.h2.expression.Expression; -import org.h2.expression.Parameter; -import org.h2.expression.ValueExpression; -import org.h2.message.DbException; -import org.h2.result.ResultInterface; -import org.h2.result.Row; -import org.h2.result.RowList; -import org.h2.table.Column; -import org.h2.table.PlanItem; -import org.h2.table.Table; -import org.h2.table.TableFilter; -import org.h2.util.StatementBuilder; -import org.h2.util.StringUtils; -import org.h2.value.Value; - -/** - * This class represents the statement - * UPDATE - */ -public class Update extends Prepared { - - private Expression condition; - private TableFilter tableFilter; - private Expression[] expressions; - - public Update(Session session) { - super(session); - } - - public void setTableFilter(TableFilter tableFilter) { - this.tableFilter = tableFilter; - Table table = tableFilter.getTable(); - expressions = new Expression[table.getColumns().length]; - } - - public void setCondition(Expression condition) { - this.condition = condition; - } - - /** - * Add an assignment of the form column = expression. - * - * @param column the column - * @param expression the expression - */ - public void setAssignment(Column column, Expression expression) { - int id = column.getColumnId(); - if (expressions[id] != null) { - throw DbException.get(ErrorCode.DUPLICATE_COLUMN_NAME_1, column - .getName()); - } - expressions[id] = expression; - if (expression instanceof Parameter) { - Parameter p = (Parameter) expression; - p.setColumn(column); - } - } - - public int update() { - tableFilter.startQuery(session); - tableFilter.reset(); - RowList rows = new RowList(session); - try { - Table table = tableFilter.getTable(); - session.getUser().checkRight(table, Right.UPDATE); - table.fire(session, Trigger.UPDATE, true); - table.lock(session, true, false); - int columnCount = table.getColumns().length; - // get the old rows, compute the new rows - setCurrentRowNumber(0); - int count = 0; - while (tableFilter.next()) { - setCurrentRowNumber(count+1); - if (condition == null || Boolean.TRUE.equals(condition.getBooleanValue(session))) { - Row oldRow = tableFilter.get(); - Row newRow = table.getTemplateRow(); - for (int i = 0; i < columnCount; i++) { - Expression newExpr = expressions[i]; - Value newValue; - if (newExpr == null) { - newValue = oldRow.getValue(i); - } else if (newExpr == ValueExpression.getDefault()) { - Column column = table.getColumn(i); - newValue = table.getDefaultValue(session, column); - } else { - Column column = table.getColumn(i); - newValue = column.convert(newExpr.getValue(session)); - } - newRow.setValue(i, newValue); - } - table.validateConvertUpdateSequence(session, newRow); - boolean done = false; - if (table.fireRow()) { - done = table.fireBeforeRow(session, oldRow, newRow); - } - if (!done) { - rows.add(oldRow); - rows.add(newRow); - } - count++; - } - } - // TODO self referencing referential integrity constraints - // don't work if update is multi-row and 'inversed' the condition! - // probably need multi-row triggers with 'deleted' and 'inserted' - // at the same time. anyway good for sql compatibility - // TODO update in-place (but if the key changes, - // we need to update all indexes) before row triggers - - // the cached row is already updated - we need the old values - table.updateRows(this, session, rows); - if (table.fireRow()) { - rows.invalidateCache(); - for (rows.reset(); rows.hasNext();) { - Row o = rows.next(); - Row n = rows.next(); - table.fireAfterRow(session, o, n, false); - } - } - table.fire(session, Trigger.UPDATE, false); - return count; - } finally { - rows.close(); - } - } - - public String getPlanSQL() { - StatementBuilder buff = new StatementBuilder("UPDATE "); - buff.append(tableFilter.getPlanSQL(false)).append("\nSET "); - Table table = tableFilter.getTable(); - int columnCount = table.getColumns().length; - for (int i = 0; i < columnCount; i++) { - Expression newExpr = expressions[i]; - if (newExpr != null) { - Column column = table.getColumn(i); - buff.appendExceptFirst(",\n"); - buff.append(column.getName()).append(" = ").append(newExpr.getSQL()); - } - } - if (condition != null) { - buff.append("\nWHERE ").append(StringUtils.unEnclose(condition.getSQL())); - } - return buff.toString(); - } - - public void prepare() { - if (condition != null) { - condition.mapColumns(tableFilter, 0); - condition = condition.optimize(session); - condition.createIndexConditions(session, tableFilter); - } - for (int i = 0; i < expressions.length; i++) { - Expression expr = expressions[i]; - if (expr != null) { - expr.mapColumns(tableFilter, 0); - expressions[i] = expr.optimize(session); - } - } - PlanItem item = tableFilter.getBestPlanItem(session, 1); - tableFilter.setPlanItem(item); - tableFilter.prepare(); - } - - public boolean isTransactional() { - return true; - } - - public ResultInterface queryMeta() { - return null; - } - -} diff --git a/tools/h2/src/main/org/h2/command/dml/package.html b/tools/h2/src/main/org/h2/command/dml/package.html deleted file mode 100755 index 8c02aa0..0000000 --- a/tools/h2/src/main/org/h2/command/dml/package.html +++ /dev/null @@ -1,15 +0,0 @@ - - - - -Javadoc package documentation -

- -Contains DML (data manipulation language) and related SQL statements. - -

\ No newline at end of file diff --git a/tools/h2/src/main/org/h2/command/package.html b/tools/h2/src/main/org/h2/command/package.html deleted file mode 100755 index 87592f8..0000000 --- a/tools/h2/src/main/org/h2/command/package.html +++ /dev/null @@ -1,15 +0,0 @@ - - - - -Javadoc package documentation -

- -This package contains the parser and the base classes for prepared SQL statements. - -

\ No newline at end of file diff --git a/tools/h2/src/main/org/h2/compress/CompressDeflate.java b/tools/h2/src/main/org/h2/compress/CompressDeflate.java deleted file mode 100755 index 2db7318..0000000 --- a/tools/h2/src/main/org/h2/compress/CompressDeflate.java +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.compress; - -import java.util.StringTokenizer; -import java.util.zip.DataFormatException; -import java.util.zip.Deflater; -import java.util.zip.Inflater; -import org.h2.constant.ErrorCode; -import org.h2.message.DbException; - -/** - * This is a wrapper class for the Deflater class. - * This algorithm supports the following options: - *
    - *
  • l or level: -1 (default), 0 (no compression), - * 1 (best speed), ..., 9 (best compression) - *
  • s or strategy: 0 (default), - * 1 (filtered), 2 (huffman only) - *
- * See also java.util.zip.Deflater for details. - */ -public class CompressDeflate implements Compressor { - - private int level = Deflater.DEFAULT_COMPRESSION; - private int strategy = Deflater.DEFAULT_STRATEGY; - - public void setOptions(String options) { - if (options == null) { - return; - } - try { - StringTokenizer tokenizer = new StringTokenizer(options); - while (tokenizer.hasMoreElements()) { - String option = tokenizer.nextToken(); - if ("level".equals(option) || "l".equals(option)) { - level = Integer.parseInt(tokenizer.nextToken()); - } else if ("strategy".equals(option) || "s".equals(option)) { - strategy = Integer.parseInt(tokenizer.nextToken()); - } - Deflater deflater = new Deflater(level); - deflater.setStrategy(strategy); - } - } catch (Exception e) { - throw DbException.get(ErrorCode.UNSUPPORTED_COMPRESSION_OPTIONS_1, options); - } - } - - public int compress(byte[] in, int inLen, byte[] out, int outPos) { - Deflater deflater = new Deflater(level); - deflater.setStrategy(strategy); - deflater.setInput(in, 0, inLen); - deflater.finish(); - int compressed = deflater.deflate(out, outPos, out.length - outPos); - while (compressed == 0) { - // the compressed length is 0, meaning compression didn't work - // (sounds like a JDK bug) - // try again, using the default strategy and compression level - strategy = Deflater.DEFAULT_STRATEGY; - level = Deflater.DEFAULT_COMPRESSION; - return compress(in, inLen, out, outPos); - } - deflater.end(); - return outPos + compressed; - } - - public int getAlgorithm() { - return Compressor.DEFLATE; - } - - public void expand(byte[] in, int inPos, int inLen, byte[] out, int outPos, int outLen) { - Inflater decompresser = new Inflater(); - decompresser.setInput(in, inPos, inLen); - decompresser.finished(); - try { - int len = decompresser.inflate(out, outPos, outLen); - if (len != outLen) { - throw new DataFormatException(len + " " + outLen); - } - } catch (DataFormatException e) { - throw DbException.get(ErrorCode.COMPRESSION_ERROR, e); - } - decompresser.end(); - } - -} diff --git a/tools/h2/src/main/org/h2/compress/CompressLZF.java b/tools/h2/src/main/org/h2/compress/CompressLZF.java deleted file mode 100755 index b099368..0000000 --- a/tools/h2/src/main/org/h2/compress/CompressLZF.java +++ /dev/null @@ -1,265 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Copyright (c) 2000-2005 Marc Alexander Lehmann - * Copyright (c) 2005 Oren J. Maurice - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ''AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO - * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; - * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package org.h2.compress; - -/** - *

- * This class implements the LZF lossless data compression algorithm. LZF is a - * Lempel-Ziv variant with byte-aligned output, and optimized for speed. - *

- *

- * Safety/Use Notes: - *

- *
    - *
  • Each instance should be used by a single thread only.
  • - *
  • The data buffers should be smaller than 1 GB.
  • - *
  • For performance reasons, safety checks on expansion are omitted.
  • - *
  • Invalid compressed data can cause an ArrayIndexOutOfBoundsException.
  • - *
- *

- * The LZF compressed format knows literal runs and back-references: - *

- *
    - *
  • Literal run: directly copy bytes from input to output.
  • - *
  • Back-reference: copy previous data to output stream, with specified - * offset from location and length. The length is at least 3 bytes.
  • - *
- *

- * The first byte of the compressed stream is the control byte. For literal - * runs, the highest three bits of the control byte are not set, the the lower - * bits are the literal run length, and the next bytes are data to copy directly - * into the output. For back-references, the highest three bits of the control - * byte are the back-reference length. If all three bits are set, then the - * back-reference length is stored in the next byte. The lower bits of the - * control byte combined with the next byte form the offset for the - * back-reference. - *

- */ -public final class CompressLZF implements Compressor { - - /** - * The number of entries in the hash table. The size is a trade-off between - * hash collisions (reduced compression) and speed (amount that fits in CPU - * cache). - */ - private static final int HASH_SIZE = 1 << 14; - - /** - * The maximum number of literals in a chunk (32). - */ - private static final int MAX_LITERAL = 1 << 5; - - /** - * The maximum offset allowed for a back-reference (8192). - */ - private static final int MAX_OFF = 1 << 13; - - /** - * The maximum back-reference length (264). - */ - private static final int MAX_REF = (1 << 8) + (1 << 3); - - /** - * Hash table for matching byte sequences (reused for performance). - */ - private int[] cachedHashTable; - - public void setOptions(String options) { - // nothing to do - } - - /** - * Return byte with lower 2 bytes being byte at index, then index+1. - */ - private static int first(byte[] in, int inPos) { - return (in[inPos] << 8) | (in[inPos + 1] & 255); - } - - /** - * Shift v 1 byte left, add value at index inPos+2. - */ - private static int next(int v, byte[] in, int inPos) { - return (v << 8) | (in[inPos + 2] & 255); - } - - /** - * Compute the address in the hash table. - */ - private static int hash(int h) { - return ((h * 2777) >> 9) & (HASH_SIZE - 1); - } - - public int compress(byte[] in, int inLen, byte[] out, int outPos) { - int inPos = 0; - if (cachedHashTable == null) { - cachedHashTable = new int[HASH_SIZE]; - } - int[] hashTab = cachedHashTable; - int literals = 0; - outPos++; - int future = first(in, 0); - while (inPos < inLen - 4) { - byte p2 = in[inPos + 2]; - // next - future = (future << 8) + (p2 & 255); - int off = hash(future); - int ref = hashTab[off]; - hashTab[off] = inPos; - if (ref < inPos - && ref > 0 - && (off = inPos - ref - 1) < MAX_OFF - && in[ref + 2] == p2 - && in[ref + 1] == (byte) (future >> 8) - && in[ref] == (byte) (future >> 16)) { - // match - int maxLen = inLen - inPos - 2; - if (maxLen > MAX_REF) { - maxLen = MAX_REF; - } - if (literals == 0) { - // multiple back-references, - // so there is no literal run control byte - outPos--; - } else { - // set the control byte at the start of the literal run - // to store the number of literals - out[outPos - literals - 1] = (byte) (literals - 1); - literals = 0; - } - int len = 3; - while (len < maxLen && in[ref + len] == in[inPos + len]) { - len++; - } - len -= 2; - if (len < 7) { - out[outPos++] = (byte) ((off >> 8) + (len << 5)); - } else { - out[outPos++] = (byte) ((off >> 8) + (7 << 5)); - out[outPos++] = (byte) (len - 7); - } - out[outPos++] = (byte) off; - // move one byte forward to allow for a literal run control byte - outPos++; - inPos += len; - // Rebuild the future, and store the last bytes to the hashtable. - // Storing hashes of the last bytes in back-reference improves - // the compression ratio and only reduces speed slightly. - future = first(in, inPos); - future = next(future, in, inPos); - hashTab[hash(future)] = inPos++; - future = next(future, in, inPos); - hashTab[hash(future)] = inPos++; - } else { - // copy one byte from input to output as part of literal - out[outPos++] = in[inPos++]; - literals++; - // at the end of this literal chunk, write the length - // to the control byte and start a new chunk - if (literals == MAX_LITERAL) { - out[outPos - literals - 1] = (byte) (literals - 1); - literals = 0; - // move ahead one byte to allow for the - // literal run control byte - outPos++; - } - } - } - // write the remaining few bytes as literals - while (inPos < inLen) { - out[outPos++] = in[inPos++]; - literals++; - if (literals == MAX_LITERAL) { - out[outPos - literals - 1] = (byte) (literals - 1); - literals = 0; - outPos++; - } - } - // writes the final literal run length to the control byte - out[outPos - literals - 1] = (byte) (literals - 1); - if (literals == 0) { - outPos--; - } - return outPos; - } - - public void expand(byte[] in, int inPos, int inLen, byte[] out, int outPos, int outLen) { - if (inPos < 0 || outPos < 0 || outLen < 0) { - throw new IllegalArgumentException(); - } - do { - int ctrl = in[inPos++] & 255; - if (ctrl < MAX_LITERAL) { - // literal run of length = ctrl + 1, - ctrl++; - // copy to output and move forward this many bytes - System.arraycopy(in, inPos, out, outPos, ctrl); - outPos += ctrl; - inPos += ctrl; - } else { - // back reference - // the highest 3 bits are the match length - int len = ctrl >> 5; - // if the length is maxed, add the next byte to the length - if (len == 7) { - len += in[inPos++] & 255; - } - // minimum back-reference is 3 bytes, - // so 2 was subtracted before storing size - len += 2; - - // ctrl is now the offset for a back-reference... - // the logical AND operation removes the length bits - ctrl = -((ctrl & 0x1f) << 8) - 1; - - // the next byte augments/increases the offset - ctrl -= in[inPos++] & 255; - - // copy the back-reference bytes from the given - // location in output to current position - ctrl += outPos; - if (outPos + len >= out.length) { - // reduce array bounds checking - throw new ArrayIndexOutOfBoundsException(); - } - for (int i = 0; i < len; i++) { - out[outPos++] = out[ctrl++]; - } - } - } while (outPos < outLen); - } - - public int getAlgorithm() { - return Compressor.LZF; - } - -} \ No newline at end of file diff --git a/tools/h2/src/main/org/h2/compress/CompressNo.java b/tools/h2/src/main/org/h2/compress/CompressNo.java deleted file mode 100755 index 0800133..0000000 --- a/tools/h2/src/main/org/h2/compress/CompressNo.java +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.compress; - -/** - * This class implements a data compression algorithm that does in fact not - * compress. This is useful if the data can not be compressed because it is - * encrypted, already compressed, or random. - */ -public class CompressNo implements Compressor { - - public int getAlgorithm() { - return Compressor.NO; - } - - public void setOptions(String options) { - // nothing to do - } - - public int compress(byte[] in, int inLen, byte[] out, int outPos) { - System.arraycopy(in, 0, out, outPos, inLen); - return outPos + inLen; - } - - public void expand(byte[] in, int inPos, int inLen, byte[] out, int outPos, int outLen) { - System.arraycopy(in, inPos, out, outPos, outLen); - } - -} diff --git a/tools/h2/src/main/org/h2/compress/Compressor.java b/tools/h2/src/main/org/h2/compress/Compressor.java deleted file mode 100755 index 89d3753..0000000 --- a/tools/h2/src/main/org/h2/compress/Compressor.java +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.compress; - - -/** - * Each data compression algorithm must implement this interface. - */ -public interface Compressor { - - /** - * No compression is used. - */ - int NO = 0; - - /** - * The LZF compression algorithm is used - */ - int LZF = 1; - - /** - * The DEFLATE compression algorithm is used. - */ - int DEFLATE = 2; - - /** - * Get the compression algorithm type. - * - * @return the type - */ - int getAlgorithm(); - - /** - * Compress a number of bytes. - * - * @param in the input data - * @param inLen the number of bytes to compress - * @param out the output area - * @param outPos the offset at the output array - * @return the end position - */ - int compress(byte[] in, int inLen, byte[] out, int outPos); - - /** - * Expand a number of compressed bytes. - * - * @param in the compressed data - * @param inPos the offset at the input array - * @param inLen the number of bytes to read - * @param out the output area - * @param outPos the offset at the output array - * @param outLen the size of the uncompressed data - */ - void expand(byte[] in, int inPos, int inLen, byte[] out, int outPos, int outLen); - - /** - * Set the compression options. This may include settings for - * higher performance but less compression. - * - * @param options the options - */ - void setOptions(String options); -} diff --git a/tools/h2/src/main/org/h2/compress/LZFInputStream.java b/tools/h2/src/main/org/h2/compress/LZFInputStream.java deleted file mode 100755 index 2bb66dd..0000000 --- a/tools/h2/src/main/org/h2/compress/LZFInputStream.java +++ /dev/null @@ -1,125 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.compress; - -import java.io.IOException; -import java.io.InputStream; -import org.h2.util.Utils; - -/** - * An input stream to read from an LZF stream. - * The data is automatically expanded. - */ -public class LZFInputStream extends InputStream { - - private final InputStream in; - private CompressLZF decompress = new CompressLZF(); - private int pos; - private int bufferLength; - private byte[] inBuffer; - private byte[] buffer; - - public LZFInputStream(InputStream in) throws IOException { - this.in = in; - if (readInt() != LZFOutputStream.MAGIC) { - throw new IOException("Not an LZFInputStream"); - } - } - - private byte[] ensureSize(byte[] buff, int len) { - return buff == null || buff.length < len ? Utils.newBytes(len) : buff; - } - - private void fillBuffer() throws IOException { - if (buffer != null && pos < bufferLength) { - return; - } - int len = readInt(); - if (decompress == null) { - // EOF - this.bufferLength = 0; - } else if (len < 0) { - len = -len; - buffer = ensureSize(buffer, len); - readFully(buffer, len); - this.bufferLength = len; - } else { - inBuffer = ensureSize(inBuffer, len); - int size = readInt(); - readFully(inBuffer, len); - buffer = ensureSize(buffer, size); - decompress.expand(inBuffer, 0, len, buffer, 0, size); - this.bufferLength = size; - } - pos = 0; - } - - private void readFully(byte[] buff, int len) throws IOException { - int off = 0; - while (len > 0) { - int l = in.read(buff, off, len); - len -= l; - off += l; - } - } - - private int readInt() throws IOException { - int x = in.read(); - if (x < 0) { - decompress = null; - return 0; - } - x = (x << 24) + (in.read() << 16) + (in.read() << 8) + in.read(); - return x; - } - - public int read() throws IOException { - fillBuffer(); - if (pos >= bufferLength) { - return -1; - } - return buffer[pos++] & 255; - } - - public int read(byte[] b) throws IOException { - return read(b, 0, b.length); - } - - public int read(byte[] b, int off, int len) throws IOException { - if (len == 0) { - return 0; - } - int read = 0; - while (len > 0) { - int r = readBlock(b, off, len); - if (r < 0) { - break; - } - read += r; - off += r; - len -= r; - } - return read == 0 ? -1 : read; - } - - private int readBlock(byte[] b, int off, int len) throws IOException { - fillBuffer(); - if (pos >= bufferLength) { - return -1; - } - int max = Math.min(len, bufferLength - pos); - max = Math.min(max, b.length - off); - System.arraycopy(buffer, pos, b, off, max); - pos += max; - return max; - } - - public void close() throws IOException { - in.close(); - } - -} diff --git a/tools/h2/src/main/org/h2/compress/LZFOutputStream.java b/tools/h2/src/main/org/h2/compress/LZFOutputStream.java deleted file mode 100755 index c9a8eb2..0000000 --- a/tools/h2/src/main/org/h2/compress/LZFOutputStream.java +++ /dev/null @@ -1,99 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.compress; - -import java.io.IOException; -import java.io.OutputStream; -import org.h2.engine.Constants; - -/** - * An output stream to write an LZF stream. - * The data is automatically compressed. - */ -public class LZFOutputStream extends OutputStream { - - /** - * The file header of a LZF file. - */ - static final int MAGIC = ('H' << 24) | ('2' << 16) | ('I' << 8) | 'S'; - - private final OutputStream out; - private final CompressLZF compress = new CompressLZF(); - private final byte[] buffer; - private int pos; - private byte[] outBuffer; - - public LZFOutputStream(OutputStream out) throws IOException { - this.out = out; - int len = Constants.IO_BUFFER_SIZE_COMPRESS; - buffer = new byte[len]; - ensureOutput(len); - writeInt(MAGIC); - } - - private void ensureOutput(int len) { - // TODO calculate the maximum overhead (worst case) for the output - // buffer - int outputLen = (len < 100 ? len + 100 : len) * 2; - if (outBuffer == null || outBuffer.length < outputLen) { - outBuffer = new byte[outputLen]; - } - } - - public void write(int b) throws IOException { - if (pos >= buffer.length) { - flush(); - } - buffer[pos++] = (byte) b; - } - - private void compressAndWrite(byte[] buff, int len) throws IOException { - if (len > 0) { - ensureOutput(len); - int compressed = compress.compress(buff, len, outBuffer, 0); - if (compressed > len) { - writeInt(-len); - out.write(buff, 0, len); - } else { - writeInt(compressed); - writeInt(len); - out.write(outBuffer, 0, compressed); - } - } - } - - private void writeInt(int x) throws IOException { - out.write((byte) (x >> 24)); - out.write((byte) (x >> 16)); - out.write((byte) (x >> 8)); - out.write((byte) x); - } - - public void write(byte[] buff, int off, int len) throws IOException { - while (len > 0) { - int copy = Math.min(buffer.length - pos, len); - System.arraycopy(buff, off, buffer, pos, copy); - pos += copy; - if (pos >= buffer.length) { - flush(); - } - off += copy; - len -= copy; - } - } - - public void flush() throws IOException { - compressAndWrite(buffer, pos); - pos = 0; - } - - public void close() throws IOException { - flush(); - out.close(); - } - -} diff --git a/tools/h2/src/main/org/h2/compress/package.html b/tools/h2/src/main/org/h2/compress/package.html deleted file mode 100755 index cb5a5fb..0000000 --- a/tools/h2/src/main/org/h2/compress/package.html +++ /dev/null @@ -1,15 +0,0 @@ - - - - -Javadoc package documentation -

- -Lossless data compression classes. - -

\ No newline at end of file diff --git a/tools/h2/src/main/org/h2/constant/ErrorCode.java b/tools/h2/src/main/org/h2/constant/ErrorCode.java deleted file mode 100755 index 7323c41..0000000 --- a/tools/h2/src/main/org/h2/constant/ErrorCode.java +++ /dev/null @@ -1,1966 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.constant; - -/** - * This class defines the error codes used for SQL exceptions. - * Error messages are formatted as follows: - *
- * { error message (possibly translated; may include quoted data) }
- * { error message in English if different }
- * { SQL statement if applicable }
- * { [ error code - build number ] }
- * 
- * Example: - *
- * Syntax error in SQL statement "SELECT * FORM[*] TEST ";
- * SQL statement: select * form test [42000-125]
- * 
- * The [*] marks the position of the syntax error - * (FORM instead of FROM in this case). - * The error code is 42000, and the build number is 125, - * meaning version 1.2.125. - */ -public class ErrorCode { - - // 02: no data - /** - * The error with code 2000 is thrown when - * the result set is positioned before the first or after the last row, or - * not on a valid row for the given operation. - * Example of wrong usage: - *
-     * ResultSet rs = stat.executeQuery("SELECT * FROM DUAL");
-     * rs.getString(1);
-     * 
- * Correct: - *
-     * ResultSet rs = stat.executeQuery("SELECT * FROM DUAL");
-     * rs.next();
-     * rs.getString(1);
-     * 
- */ - public static final int NO_DATA_AVAILABLE = 2000; - - // 07: dynamic SQL error - /** - * The error with code 7001 is thrown when - * trying to call a function with the wrong number of parameters. - * Example: - *
-     * CALL ABS(1, 2)
-     * 
- */ - public static final int INVALID_PARAMETER_COUNT_2 = 7001; - - // 08: connection exception - /** - * The error with code 8000 is thrown when - * there was a problem trying to create a database lock. - * See the message and cause for details. - */ - public static final int ERROR_OPENING_DATABASE_1 = 8000; - - /** - * The error with code 8004 is thrown when - * there is no such user registered in the database, when - * the user password does not match, or when the database encryption password - * does not match (if database encryption is used). - */ - public static final int WRONG_USER_OR_PASSWORD = 8004; - - // 21: cardinality violation - /** - * The error with code 21002 is thrown when the number of - * columns does not match. Possible reasons are: for an INSERT or MERGE - * statement, the column count does not match the table or the column list - * specified. For a SELECT UNION statement, both queries return a different - * number of columns. For a constraint, the number of referenced and - * referencing columns does not match. Example: - *
-     * CREATE TABLE TEST(ID INT, NAME VARCHAR);
-     * INSERT INTO TEST VALUES('Hello');
-     * 
- */ - public static final int COLUMN_COUNT_DOES_NOT_MATCH = 21002; - - // 22: data exception - /** - * The error with code 22003 is thrown when a value is out of - * range when converting to another data type. Example: - *
-     * CALL CAST(1000000 AS TINYINT);
-     * 
- */ - public static final int NUMERIC_VALUE_OUT_OF_RANGE = 22003; - - /** - * The error with code 22012 is thrown when trying to divide - * a value by zero. Example: - *
-     * CALL 1/0;
-     * 
- */ - public static final int DIVISION_BY_ZERO_1 = 22012; - - /** - * The error with code 22025 is thrown when using an invalid - * escape character sequence for LIKE or REGEXP. The default escape - * character is '\'. The escape character is required when searching for - * the characters '%', '_' and the escape character itself. That means if - * you want to search for the text '10%', you need to use LIKE '10\%'. If - * you want to search for 'C:\temp' you need to use 'C:\\temp'. The escape - * character can be changed using the ESCAPE clause as in LIKE '10+%' ESCAPE - * '+'. Example of wrong usage: - *
-     * CALL 'C:\temp' LIKE 'C:\temp';
-     * CALL '1+1' LIKE '1+1' ESCAPE '+';
-     * 
- * Correct: - *
-     * CALL 'C:\temp' LIKE 'C:\\temp';
-     * CALL '1+1' LIKE '1++1' ESCAPE '+';
-     * 
- */ - public static final int LIKE_ESCAPE_ERROR_1 = 22025; - - // 23: integrity constraint violation - /** - * The error with code 23000 is thrown when a check - * constraint is violated. Example: - *
-     * CREATE TABLE TEST(ID INT CHECK ID>0);
-     * INSERT INTO TEST VALUES(0);
-     * 
- */ - public static final int CHECK_CONSTRAINT_VIOLATED_1 = 23000; - - /** - * The error with code 23001 is thrown when trying to insert - * a row that would violate a unique index or primary key. Example: - *
-     * CREATE TABLE TEST(ID INT PRIMARY KEY);
-     * INSERT INTO TEST VALUES(1);
-     * INSERT INTO TEST VALUES(1);
-     * 
- */ - public static final int DUPLICATE_KEY_1 = 23001; - - /** - * The error with code 23002 is thrown when trying to insert - * or update a row that would violate a referential constraint, because the - * referenced row does not exist. Example: - *
-     * CREATE TABLE PARENT(ID INT);
-     * CREATE TABLE CHILD(P_ID INT REFERENCES PARENT(ID));
-     * INSERT INTO CHILD VALUES(1);
-     * 
- */ - public static final int REFERENTIAL_INTEGRITY_VIOLATED_PARENT_MISSING_1 = 23002; - - /** - * The error with code 23003 is thrown when trying to delete - * or update a row when this would violate a referential constraint, because - * there is a child row that would become an orphan. Example: - *
-     * CREATE TABLE PARENT(ID INT);
-     * CREATE TABLE CHILD(P_ID INT REFERENCES PARENT(ID));
-     * INSERT INTO PARENT VALUES(1);
-     * INSERT INTO CHILD VALUES(1);
-     * DELETE FROM PARENT;
-     * 
- */ - public static final int REFERENTIAL_INTEGRITY_VIOLATED_CHILD_EXISTS_1 = 23003; - - // 3B: savepoint exception - - /** - * The error with code 40001 is thrown when the database - * engine has detected a deadlock. The transaction of this session has been - * rolled back to solve the problem. A deadlock occurs when a session tries - * to lock a table another session has locked, while the other session wants - * to lock a table the first session has locked. As an example, session 1 - * has locked table A, while session 2 has locked table B. If session 1 now - * tries to lock table B and session 2 tries to lock table A, a deadlock has - * occurred. Deadlocks that involve more than two sessions are also possible. - * To solve deadlock problems, an application should lock tables always in - * the same order, such as always lock table A before locking table B. For - * details, see Wikipedia - * Deadlock. - */ - public static final int DEADLOCK_1 = 40001; - - // 42: syntax error or access rule violation - /** - * The error with code 42000 is thrown when - * trying to execute an invalid SQL statement. - * Example: - *
-     * CREATE ALIAS REMAINDER FOR "IEEEremainder";
-     * 
- */ - public static final int SYNTAX_ERROR_1 = 42000; - - /** - * The error with code 42001 is thrown when - * trying to execute an invalid SQL statement. - * Example: - *
-     * CREATE TABLE TEST(ID INT);
-     * INSERT INTO TEST(1);
-     * 
- */ - public static final int SYNTAX_ERROR_2 = 42001; - - /** - * The error with code 42101 is thrown when - * trying to create a table or view if an object with this name already exists. - * Example: - *
-     * CREATE TABLE TEST(ID INT);
-     * CREATE TABLE TEST(ID INT PRIMARY KEY);
-     * 
- */ - public static final int TABLE_OR_VIEW_ALREADY_EXISTS_1 = 42101; - - /** - * The error with code 42102 is thrown when - * trying to query, modify or drop a table or view that does not exists - * in this schema and database. A common cause is that the wrong - * database was opened. - * Example: - *
-     * SELECT * FROM ABC;
-     * 
- */ - public static final int TABLE_OR_VIEW_NOT_FOUND_1 = 42102; - - /** - * The error with code 42111 is thrown when - * trying to create an index if an index with the same name already exists. - * Example: - *
-     * CREATE TABLE TEST(ID INT, NAME VARCHAR);
-     * CREATE INDEX IDX_ID ON TEST(ID);
-     * CREATE TABLE ADDRESS(ID INT);
-     * CREATE INDEX IDX_ID ON ADDRESS(ID);
-     * 
- */ - public static final int INDEX_ALREADY_EXISTS_1 = 42111; - - /** - * The error with code 42112 is thrown when - * trying to drop or reference an index that does not exist. - * Example: - *
-     * DROP INDEX ABC;
-     * 
- */ - public static final int INDEX_NOT_FOUND_1 = 42112; - - /** - * The error with code 42121 is thrown when trying to create - * a table or insert into a table and use the same column name twice. - * Example: - *
-     * CREATE TABLE TEST(ID INT, ID INT);
-     * 
- */ - public static final int DUPLICATE_COLUMN_NAME_1 = 42121; - - /** - * The error with code 42122 is thrown when - * referencing an non-existing column. - * Example: - *
-     * CREATE TABLE TEST(ID INT);
-     * SELECT NAME FROM TEST;
-     * 
- */ - public static final int COLUMN_NOT_FOUND_1 = 42122; - - // 0A: feature not supported - - // HZ: remote database access - - // - /** - * The error with code 50000 is thrown when - * something unexpected occurs, for example an internal stack - * overflow. For details about the problem, see the cause of the - * exception in the stack trace. - */ - public static final int GENERAL_ERROR_1 = 50000; - - /** - * The error with code 50004 is thrown when - * creating a table with an unsupported data type, or - * when the data type is unknown because parameters are used. - * Example: - *
-     * CREATE TABLE TEST(ID VERYSMALLINT);
-     * 
- */ - public static final int UNKNOWN_DATA_TYPE_1 = 50004; - - /** - * The error with code 50100 is thrown when calling an - * unsupported JDBC method or database feature. See the stack trace for - * details. - */ - public static final int FEATURE_NOT_SUPPORTED_1 = 50100; - - /** - * The error with code 50200 is thrown when - * another connection locked an object longer than the lock timeout - * set for this connection, or when a deadlock occurred. - * Example: - *
-     * CREATE TABLE TEST(ID INT);
-     * -- connection 1:
-     * SET AUTOCOMMIT FALSE;
-     * INSERT INTO TEST VALUES(1);
-     * -- connection 2:
-     * SET AUTOCOMMIT FALSE;
-     * INSERT INTO TEST VALUES(1);
-     * 
- */ - public static final int LOCK_TIMEOUT_1 = 50200; - - /** - * The error with code 90000 is thrown when - * a function that does not return a result set was used in the FROM clause. - * Example: - *
-     * SELECT * FROM SIN(1);
-     * 
- */ - public static final int FUNCTION_MUST_RETURN_RESULT_SET_1 = 90000; - - /** - * The error with code 90001 is thrown when - * Statement.executeUpdate() was called for a SELECT statement. - * This is not allowed according to the JDBC specs. - */ - public static final int METHOD_NOT_ALLOWED_FOR_QUERY = 90001; - - /** - * The error with code 90002 is thrown when - * Statement.executeQuery() was called for a statement that does - * not return a result set (for example, an UPDATE statement). - * This is not allowed according to the JDBC specs. - */ - public static final int METHOD_ONLY_ALLOWED_FOR_QUERY = 90002; - - /** - * The error with code 90003 is thrown when - * trying to convert a String to a binary value. Two hex digits - * per byte are required. Example of wrong usage: - *
-     * CALL X'00023';
-     * Hexadecimal string with odd number of characters: 00023
-     * 
- * Correct: - *
-     * CALL X'000023';
-     * 
- */ - public static final int HEX_STRING_ODD_1 = 90003; - - /** - * The error with code 90004 is thrown when - * trying to convert a text to binary, but the expression contains - * a non-hexadecimal character. - * Example: - *
-     * CALL X'ABCDEFGH';
-     * CALL CAST('ABCDEFGH' AS BINARY);
-     * 
- * Conversion from text to binary is supported, but the text must - * represent the hexadecimal encoded bytes. - */ - public static final int HEX_STRING_WRONG_1 = 90004; - - /** - * The error with code 90005 is thrown when - * trying to insert a value that is too long for the column. - * Example: - *
-     * CREATE TABLE TEST(ID INT, NAME VARCHAR(2));
-     * INSERT INTO TEST VALUES(1, 'Hello');
-     * 
- */ - public static final int VALUE_TOO_LONG_2 = 90005; - - /** - * The error with code 90006 is thrown when - * trying to insert NULL into a column that does not allow NULL. - * Example: - *
-     * CREATE TABLE TEST(ID INT, NAME VARCHAR NOT NULL);
-     * INSERT INTO TEST(ID) VALUES(1);
-     * 
- */ - public static final int NULL_NOT_ALLOWED = 90006; - - /** - * The error with code 90007 is thrown when - * trying to call a JDBC method on an object that has been closed. - */ - public static final int OBJECT_CLOSED = 90007; - - /** - * The error with code 90008 is thrown when - * trying to use a value that is not valid for the given operation. - * Example: - *
-     * CREATE SEQUENCE TEST INCREMENT 0;
-     * 
- */ - public static final int INVALID_VALUE_2 = 90008; - - /** - * The error with code 90009 is thrown when - * a text can not be converted to a date constant. - * Example: - *
-     * CALL DATE '2007-January-01';
-     * 
- */ - public static final int DATE_CONSTANT_2 = 90009; - - /** - * The error with code 90010 is thrown when - * a text can not be converted to a time constant. - * Example: - *
-     * CALL TIME '14:61:00';
-     * 
- */ - public static final int TIME_CONSTANT_2 = 90010; - - /** - * The error with code 90011 is thrown when - * a text can not be converted to a timestamp constant. - * Example: - *
-     * CALL TIMESTAMP '2001-02-30 12:00:00';
-     * 
- */ - public static final int TIMESTAMP_CONSTANT_2 = 90011; - - /** - * The error with code 90012 is thrown when - * trying to execute a statement with an parameter. - * Example: - *
-     * CALL SIN(?);
-     * 
- */ - public static final int PARAMETER_NOT_SET_1 = 90012; - - /** - * The error with code 90013 is thrown when - * trying to open a database that does not exist using the flag IFEXISTS=TRUE, - * or when trying to access a database object with a catalog name that does - * not match the database name. - * Example: - *
-     * CREATE TABLE TEST(ID INT);
-     * SELECT XYZ.PUBLIC.TEST.ID FROM TEST;
-     * 
- */ - public static final int DATABASE_NOT_FOUND_1 = 90013; - - /** - * The error with code 90014 is thrown when - * trying to parse a date with an unsupported format string, or - * when the date can not be parsed. - * Example: - *
-     * CALL PARSEDATETIME('2001 January', 'yyyy mm');
-     * 
- */ - public static final int PARSE_ERROR_1 = 90014; - - /** - * The error with code 90015 is thrown when - * using an aggregate function with a data type that is not supported. - * Example: - *
-     * SELECT SUM('Hello') FROM DUAL;
-     * 
- */ - public static final int SUM_OR_AVG_ON_WRONG_DATATYPE_1 = 90015; - - /** - * The error with code 90016 is thrown when - * a column was used in the expression list or the order by clause - * of a group or aggregate query, and that column is not in the GROUP BY clause. - * Example of wrong usage: - *
-     * CREATE TABLE TEST(ID INT, NAME VARCHAR);
-     * INSERT INTO TEST VALUES(1, 'Hello'), (2, 'World');
-     * SELECT ID, MAX(NAME) FROM TEST;
-     * Column ID must be in the GROUP BY list.
-     * 
- * Correct: - *
-     * SELECT ID, MAX(NAME) FROM TEST GROUP BY ID;
-     * 
- */ - public static final int MUST_GROUP_BY_COLUMN_1 = 90016; - - /** - * The error with code 90017 is thrown when - * trying to define a second primary key constraint for this table. - * Example: - *
-     * CREATE TABLE TEST(ID INT PRIMARY KEY, NAME VARCHAR);
-     * ALTER TABLE TEST ADD CONSTRAINT PK PRIMARY KEY(NAME);
-     * 
- */ - public static final int SECOND_PRIMARY_KEY = 90017; - - /** - * The error with code 90018 is thrown when - * the connection was opened, but never closed. In the finalizer of the - * connection, this forgotten close was detected and the connection was - * closed automatically, but relying on the finalizer is not good practice - * as it is not guaranteed and behavior is virtual machine dependent. The - * application should close the connection. This exception only appears in - * the .trace.db file. Example of wrong usage: - *
-     * Connection conn;
-     * conn = DriverManager.getConnection("jdbc:h2:˜/test");
-     * conn = null;
-     * The connection was not closed by the application and is
-     * garbage collected
-     * 
- * Correct: - *
-     * conn.close();
-     * 
- */ - public static final int TRACE_CONNECTION_NOT_CLOSED = 90018; - - /** - * The error with code 90019 is thrown when - * trying to drop the current user, if there are no other admin users. - * Example: - *
-     * DROP USER SA;
-     * 
- */ - public static final int CANNOT_DROP_CURRENT_USER = 90019; - - /** - * The error with code 90020 is thrown when trying to open a - * database in embedded mode if this database is already in use in another - * process (or in a different class loader). Multiple connections to the - * same database are supported in the following cases: - *
  • In embedded mode (URL of the form jdbc:h2:~/test) if all - * connections are opened within the same process and class loader. - *
  • In server and cluster mode (URL of the form - * jdbc:h2:tcp://localhost/test) using remote connections. - *
- * The mixed mode is also supported. This mode requires to start a server - * in the same process where the database is open in embedded mode. - */ - public static final int DATABASE_ALREADY_OPEN_1 = 90020; - - /** - * The error with code 90021 is thrown when - * trying to convert a value to a data type where the conversion is undefined, - * or when an error occurred trying to convert. - * Example: - *
-     * CALL CAST(DATE '2001-01-01' AS BOOLEAN);
-     * CALL CAST('CHF 99.95' AS INT);
-     * 
- */ - public static final int DATA_CONVERSION_ERROR_1 = 90021; - - /** - * The error with code 90022 is thrown when - * trying to call a unknown function. - * Example: - *
-     * CALL SPECIAL_SIN(10);
-     * 
- */ - public static final int FUNCTION_NOT_FOUND_1 = 90022; - - /** - * The error with code 90023 is thrown when - * trying to set a primary key on a nullable column. - * Example: - *
-     * CREATE TABLE TEST(ID INT, NAME VARCHAR);
-     * ALTER TABLE TEST ADD CONSTRAINT PK PRIMARY KEY(ID);
-     * 
- */ - public static final int COLUMN_MUST_NOT_BE_NULLABLE_1 = 90023; - - /** - * The error with code 90024 is thrown when - * a file could not be renamed. - */ - public static final int FILE_RENAME_FAILED_2 = 90024; - - /** - * The error with code 90025 is thrown when - * a file could not be deleted, because it is still in use - * (only in Windows), or because an error occurred when deleting. - */ - public static final int FILE_DELETE_FAILED_1 = 90025; - - /** - * The error with code 90026 is thrown when - * an object could not be serialized. - */ - public static final int SERIALIZATION_FAILED_1 = 90026; - - /** - * The error with code 90027 is thrown when - * an object could not be de-serialized. - */ - public static final int DESERIALIZATION_FAILED_1 = 90027; - - /** - * The error with code 90028 is thrown when - * an input / output error occurred. For more information, see the root - * cause of the exception. - */ - public static final int IO_EXCEPTION_1 = 90028; - - /** - * The error with code 90029 is thrown when - * calling ResultSet.deleteRow(), insertRow(), or updateRow() - * when the current row is not updatable. - * Example: - *
-     * ResultSet rs = stat.executeQuery("SELECT * FROM TEST");
-     * rs.next();
-     * rs.insertRow();
-     * 
- */ - public static final int NOT_ON_UPDATABLE_ROW = 90029; - - /** - * The error with code 90030 is thrown when - * the database engine has detected a checksum mismatch in the data - * or index. To solve this problem, restore a backup or use the - * Recovery tool (org.h2.tools.Recover). - */ - public static final int FILE_CORRUPTED_1 = 90030; - - /** - * The error with code 90031 is thrown when - * an input / output error occurred. For more information, see the root - * cause of the exception. - */ - public static final int IO_EXCEPTION_2 = 90031; - - /** - * The error with code 90032 is thrown when - * trying to drop or alter a user that does not exist. - * Example: - *
-     * DROP USER TEST_USER;
-     * 
- */ - public static final int USER_NOT_FOUND_1 = 90032; - - /** - * The error with code 90033 is thrown when - * trying to create a user or role if a user with this name already exists. - * Example: - *
-     * CREATE USER TEST_USER;
-     * CREATE USER TEST_USER;
-     * 
- */ - public static final int USER_ALREADY_EXISTS_1 = 90033; - - /** - * The error with code 90034 is thrown when - * writing to the trace file failed, for example because the there - * is an I/O exception. This message is printed to System.out, - * but only once. - */ - public static final int TRACE_FILE_ERROR_2 = 90034; - - /** - * The error with code 90035 is thrown when - * trying to create a sequence if a sequence with this name already - * exists. - * Example: - *
-     * CREATE SEQUENCE TEST_SEQ;
-     * CREATE SEQUENCE TEST_SEQ;
-     * 
- */ - public static final int SEQUENCE_ALREADY_EXISTS_1 = 90035; - - /** - * The error with code 90036 is thrown when - * trying to access a sequence that does not exist. - * Example: - *
-     * SELECT NEXT VALUE FOR SEQUENCE XYZ;
-     * 
- */ - public static final int SEQUENCE_NOT_FOUND_1 = 90036; - - /** - * The error with code 90037 is thrown when - * trying to drop or alter a view that does not exist. - * Example: - *
-     * DROP VIEW XYZ;
-     * 
- */ - public static final int VIEW_NOT_FOUND_1 = 90037; - - /** - * The error with code 90038 is thrown when - * trying to create a view if a view with this name already - * exists. - * Example: - *
-     * CREATE VIEW DUMMY AS SELECT * FROM DUAL;
-     * CREATE VIEW DUMMY AS SELECT * FROM DUAL;
-     * 
- */ - public static final int VIEW_ALREADY_EXISTS_1 = 90038; - - /** - * The error with code 90039 is thrown when - * trying to convert a decimal value to lower precision if the - * value is out of range for this precision. - * Example: - *
-     * SELECT * FROM TABLE(X DECIMAL(2, 2) = (123.34));
-     * 
- */ - public static final int VALUE_TOO_LARGE_FOR_PRECISION_1 = 90039; - - /** - * The error with code 90040 is thrown when - * a user that is not administrator tries to execute a statement - * that requires admin privileges. - */ - public static final int ADMIN_RIGHTS_REQUIRED = 90040; - - /** - * The error with code 90041 is thrown when - * trying to create a trigger and there is already a trigger with that name. - *
-     * CREATE TABLE TEST(ID INT);
-     * CREATE TRIGGER TRIGGER_A AFTER INSERT ON TEST
-     *      CALL "org.h2.samples.TriggerSample$MyTrigger";
-     * CREATE TRIGGER TRIGGER_A AFTER INSERT ON TEST
-     *      CALL "org.h2.samples.TriggerSample$MyTrigger";
-     * 
- */ - public static final int TRIGGER_ALREADY_EXISTS_1 = 90041; - - /** - * The error with code 90042 is thrown when - * trying to drop a trigger that does not exist. - * Example: - *
-     * DROP TRIGGER TRIGGER_XYZ;
-     * 
- */ - public static final int TRIGGER_NOT_FOUND_1 = 90042; - - /** - * The error with code 90043 is thrown when - * there is an error initializing the trigger, for example because the - * class does not implement the Trigger interface. - * See the root cause for details. - * Example: - *
-     * CREATE TABLE TEST(ID INT);
-     * CREATE TRIGGER TRIGGER_A AFTER INSERT ON TEST
-     *      CALL "java.lang.String";
-     * 
- */ - public static final int ERROR_CREATING_TRIGGER_OBJECT_3 = 90043; - - /** - * The error with code 90044 is thrown when - * an exception or error occurred while calling the triggers fire method. - * See the root cause for details. - */ - public static final int ERROR_EXECUTING_TRIGGER_3 = 90044; - - /** - * The error with code 90045 is thrown when - * trying to create a constraint if an object with this name already exists. - * Example: - *
-     * CREATE TABLE TEST(ID INT NOT NULL);
-     * ALTER TABLE TEST ADD CONSTRAINT PK PRIMARY KEY(ID);
-     * ALTER TABLE TEST ADD CONSTRAINT PK PRIMARY KEY(ID);
-     * 
- */ - public static final int CONSTRAINT_ALREADY_EXISTS_1 = 90045; - - /** - * The error with code 90046 is thrown when - * trying to open a connection to a database using an unsupported URL format. - * Please see the documentation on the supported URL format and examples. - * Example: - *
-     * jdbc:h2:;;
-     * 
- */ - public static final int URL_FORMAT_ERROR_2 = 90046; - - /** - * The error with code 90047 is thrown when - * trying to connect to a TCP server with an incompatible client. - */ - public static final int DRIVER_VERSION_ERROR_2 = 90047; - - /** - * The error with code 90048 is thrown when - * the file header of a database files (*.db) does not match the - * expected version, or if it is corrupted. - */ - public static final int FILE_VERSION_ERROR_1 = 90048; - - /** - * The error with code 90049 is thrown when - * trying to open an encrypted database with the wrong file encryption - * password or algorithm. - */ - public static final int FILE_ENCRYPTION_ERROR_1 = 90049; - - /** - * The error with code 90050 is thrown when trying to open an - * encrypted database, but not separating the file password from the user - * password. The file password is specified in the password field, before - * the user password. A single space needs to be added between 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. - * Example of wrong usage: - *
-     * String url = "jdbc:h2:˜/test;CIPHER=AES";
-     * String passwords = "filePasswordUserPassword";
-     * DriverManager.getConnection(url, "sa", pwds);
-     * 
- * Correct: - *
-     * String url = "jdbc:h2:˜/test;CIPHER=AES";
-     * String passwords = "filePassword userPassword";
-     * DriverManager.getConnection(url, "sa", pwds);
-     * 
- */ - public static final int WRONG_PASSWORD_FORMAT = 90050; - - /** - * The error with code 90051 is thrown when - * a statement was canceled using Statement.cancel() or - * when the query timeout has been reached. - * Examples: - *
-     * stat.setQueryTimeout(1);
-     * stat.cancel();
-     * 
- */ - public static final int STATEMENT_WAS_CANCELED = 90051; - - /** - * The error with code 90052 is thrown when - * a subquery that is used as a value contains more than one column. - * Example of wrong usage: - *
-     * CREATE TABLE TEST(ID INT);
-     * INSERT INTO TEST VALUES(1), (2);
-     * SELECT * FROM TEST WHERE ID IN (SELECT 1, 2 FROM DUAL);
-     * 
- * Correct: - *
-     * CREATE TABLE TEST(ID INT);
-     * INSERT INTO TEST VALUES(1), (2);
-     * SELECT * FROM TEST WHERE ID IN (1, 2);
-     * 
- */ - public static final int SUBQUERY_IS_NOT_SINGLE_COLUMN = 90052; - - /** - * The error with code 90053 is thrown when - * a subquery that is used as a value contains more than one row. - * Example: - *
-     * CREATE TABLE TEST(ID INT, NAME VARCHAR);
-     * INSERT INTO TEST VALUES(1, 'Hello'), (1, 'World');
-     * SELECT X, (SELECT NAME FROM TEST WHERE ID=X) FROM DUAL;
-     * 
- */ - public static final int SCALAR_SUBQUERY_CONTAINS_MORE_THAN_ONE_ROW = 90053; - - /** - * The error with code 90054 is thrown when - * an aggregate function is used where it is not allowed. - * Example: - *
-     * CREATE TABLE TEST(ID INT);
-     * INSERT INTO TEST VALUES(1), (2);
-     * SELECT MAX(ID) FROM TEST WHERE ID = MAX(ID) GROUP BY ID;
-     * 
- */ - public static final int INVALID_USE_OF_AGGREGATE_FUNCTION_1 = 90054; - - /** - * The error with code 90055 is thrown when - * trying to open a database with an unsupported cipher algorithm. - * Supported are AES and XTEA. - * Example: - *
-     * jdbc:h2:~/test;CIPHER=DES
-     * 
- */ - public static final int UNSUPPORTED_CIPHER = 90055; - - /** - * The error with code 90056 is thrown when - * updating or deleting from a table with a foreign key constraint - * that should set the default value, but there is no default value defined. - * Example: - *
-     * CREATE TABLE TEST(ID INT, PARENT INT);
-     * INSERT INTO TEST VALUES(1, 1), (2, 1);
-     * ALTER TABLE TEST ADD CONSTRAINT TEST_ID_PARENT
-     *   FOREIGN KEY(PARENT) REFERENCES(ID) ON DELETE SET DEFAULT;
-     *   DELETE FROM TEST WHERE ID=1;
-     * 
- */ - public static final int NO_DEFAULT_SET_1 = 90056; - - /** - * The error with code 90057 is thrown when - * trying to drop a constraint that does not exist. - * Example: - *
-     * CREATE TABLE TEST(ID INT);
-     * ALTER TABLE TEST DROP CONSTRAINT CID;
-     * 
- */ - public static final int CONSTRAINT_NOT_FOUND_1 = 90057; - - /** - * The error with code 90058 is thrown when trying to call - * commit or rollback inside a trigger, or when trying to call a method - * inside a trigger that implicitly commits the current transaction, if an - * object is locked. This is not because it would release the lock too - * early. - */ - public static final int COMMIT_ROLLBACK_NOT_ALLOWED = 90058; - - /** - * The error with code 90059 is thrown when - * a query contains a column that could belong to multiple tables. - * Example: - *
-     * CREATE TABLE PARENT(ID INT, NAME VARCHAR);
-     * CREATE TABLE CHILD(PID INT, NAME VARCHAR);
-     * SELECT ID, NAME FROM PARENT P, CHILD C WHERE P.ID = C.PID;
-     * 
- */ - public static final int AMBIGUOUS_COLUMN_NAME_1 = 90059; - - /** - * The error with code 90060 is thrown when - * trying to use a file locking mechanism that is not supported. - * Currently only FILE (the default) and SOCKET are supported - * Example: - *
-     * jdbc:h2:~/test;FILE_LOCK=LDAP
-     * 
- */ - public static final int UNSUPPORTED_LOCK_METHOD_1 = 90060; - - /** - * The error with code 90061 is thrown when - * trying to start a server if a server is already running on the same port. - * It could also be a firewall problem. To find out if another server is - * already running, run the following command on Windows: - *
-     * netstat -ano
-     * 
- * The column PID is the process id as listed in the Task Manager. - * For Linux, use: - *
-     * netstat -npl
-     * 
- */ - public static final int EXCEPTION_OPENING_PORT_2 = 90061; - - /** - * The error with code 90062 is thrown when - * a directory or file could not be created. This can occur when - * trying to create a directory if a file with the same name already - * exists, or vice versa. - * - */ - public static final int FILE_CREATION_FAILED_1 = 90062; - - /** - * The error with code 90063 is thrown when - * trying to rollback to a savepoint that is not defined. - * Example: - *
-     * ROLLBACK TO SAVEPOINT S_UNKNOWN;
-     * 
- */ - public static final int SAVEPOINT_IS_INVALID_1 = 90063; - - /** - * The error with code 90064 is thrown when - * Savepoint.getSavepointName() is called on an unnamed savepoint. - * Example: - *
-     * Savepoint sp = conn.setSavepoint();
-     * sp.getSavepointName();
-     * 
- */ - public static final int SAVEPOINT_IS_UNNAMED = 90064; - - /** - * The error with code 90065 is thrown when - * Savepoint.getSavepointId() is called on a named savepoint. - * Example: - *
-     * Savepoint sp = conn.setSavepoint("Joe");
-     * sp.getSavepointId();
-     * 
- */ - public static final int SAVEPOINT_IS_NAMED = 90065; - - /** - * The error with code 90066 is thrown when - * the same property appears twice in the database URL or in - * the connection properties. - * Example: - *
-     * jdbc:h2:~/test;LOCK_TIMEOUT=0;LOCK_TIMEOUT=1
-     * 
- */ - public static final int DUPLICATE_PROPERTY_1 = 90066; - - /** - * The error with code 90067 is thrown when - * the connection to the database is lost. A possible reason - * is that the database connection has been closed due to a shutdown, - * or that the server is stopped. Other causes could be: - * the server is not an H2 server, or the network connection is broken. - */ - public static final int CONNECTION_BROKEN_1 = 90067; - - /** - * The error with code 90068 is thrown when the given - * expression that is used in the ORDER BY is not in the result list. This - * is required for distinct queries, otherwise the result would be - * ambiguous. - * Example of wrong usage: - *
-     * CREATE TABLE TEST(ID INT, NAME VARCHAR);
-     * INSERT INTO TEST VALUES(2, 'Hello'), (1, 'Hello');
-     * SELECT DISTINCT NAME FROM TEST ORDER BY ID;
-     * Order by expression ID must be in the result list in this case
-     * 
- * Correct: - *
-     * SELECT DISTINCT ID, NAME FROM TEST ORDER BY ID;
-     * 
- */ - public static final int ORDER_BY_NOT_IN_RESULT = 90068; - - /** - * The error with code 90069 is thrown when - * trying to create a role if an object with this name already exists. - * Example: - *
-     * CREATE ROLE TEST_ROLE;
-     * CREATE ROLE TEST_ROLE;
-     * 
- */ - public static final int ROLE_ALREADY_EXISTS_1 = 90069; - - /** - * The error with code 90070 is thrown when - * trying to drop or grant a role that does not exists. - * Example: - *
-     * DROP ROLE TEST_ROLE_2;
-     * 
- */ - public static final int ROLE_NOT_FOUND_1 = 90070; - - /** - * The error with code 90071 is thrown when - * trying to grant or revoke if no role or user with that name exists. - * Example: - *
-     * GRANT SELECT ON TEST TO UNKNOWN;
-     * 
- */ - public static final int USER_OR_ROLE_NOT_FOUND_1 = 90071; - - /** - * The error with code 90072 is thrown when - * trying to grant or revoke if no role or user with that name exists. - * Example: - *
-     * GRANT SELECT, TEST_ROLE ON TEST TO SA;
-     * 
- */ - public static final int ROLES_AND_RIGHT_CANNOT_BE_MIXED = 90072; - - /** - * The error with code 90073 is thrown when trying to create - * an alias for a Java method, if two methods exists in this class that have - * this name and the same number of parameters. - * Example of wrong usage: - *
-     * CREATE ALIAS GET_LONG FOR
-     *      "java.lang.Long.getLong";
-     * 
- * Correct: - *
-     * CREATE ALIAS GET_LONG FOR
-     *      "java.lang.Long.getLong(java.lang.String, java.lang.Long)";
-     * 
- */ - public static final int METHODS_MUST_HAVE_DIFFERENT_PARAMETER_COUNTS_2 = 90073; - - /** - * The error with code 90074 is thrown when - * trying to grant a role that has already been granted. - * Example: - *
-     * CREATE ROLE TEST_A;
-     * CREATE ROLE TEST_B;
-     * GRANT TEST_A TO TEST_B;
-     * GRANT TEST_B TO TEST_A;
-     * 
- */ - public static final int ROLE_ALREADY_GRANTED_1 = 90074; - - /** - * The error with code 90075 is thrown when - * trying to alter a table and allow null for a column that is part of a - * primary key or hash index. - * Example: - *
-     * CREATE TABLE TEST(ID INT PRIMARY KEY);
-     * ALTER TABLE TEST ALTER COLUMN ID NULL;
-     * 
- */ - public static final int COLUMN_IS_PART_OF_INDEX_1 = 90075; - - /** - * The error with code 90076 is thrown when - * trying to create a function alias for a system function or for a function - * that is already defined. - * Example: - *
-     * CREATE ALIAS SQRT FOR "java.lang.Math.sqrt"
-     * 
- */ - public static final int FUNCTION_ALIAS_ALREADY_EXISTS_1 = 90076; - - /** - * The error with code 90077 is thrown when - * trying to drop a system function or a function alias that does not exist. - * Example: - *
-     * DROP ALIAS SQRT;
-     * 
- */ - public static final int FUNCTION_ALIAS_NOT_FOUND_1 = 90077; - - /** - * The error with code 90078 is thrown when - * trying to create a schema if an object with this name already exists. - * Example: - *
-     * CREATE SCHEMA TEST_SCHEMA;
-     * CREATE SCHEMA TEST_SCHEMA;
-     * 
- */ - public static final int SCHEMA_ALREADY_EXISTS_1 = 90078; - - /** - * The error with code 90079 is thrown when - * trying to drop a schema that does not exist. - * Example: - *
-     * DROP SCHEMA UNKNOWN;
-     * 
- */ - public static final int SCHEMA_NOT_FOUND_1 = 90079; - - /** - * The error with code 90080 is thrown when - * trying to rename a object to a different schema, or when trying to - * create a related object in another schema. - * For CREATE LINKED TABLE, it is thrown when multiple tables with that - * name exist in different schemas. - * Example: - *
-     * CREATE SCHEMA TEST_SCHEMA;
-     * CREATE TABLE TEST(ID INT);
-     * CREATE INDEX TEST_ID ON TEST(ID);
-     * ALTER INDEX TEST_ID RENAME TO TEST_SCHEMA.IDX_TEST_ID;
-     * 
- */ - public static final int SCHEMA_NAME_MUST_MATCH = 90080; - - /** - * The error with code 90081 is thrown when - * trying to alter a column to not allow NULL, if there - * is already data in the table where this column is NULL. - * Example: - *
-     * CREATE TABLE TEST(ID INT);
-     * INSERT INTO TEST VALUES(NULL);
-     * ALTER TABLE TEST ALTER COLUMN ID VARCHAR NOT NULL;
-     * 
- */ - public static final int COLUMN_CONTAINS_NULL_VALUES_1 = 90081; - - /** - * The error with code 90082 is thrown when - * trying to drop a system generated sequence. - */ - public static final int SEQUENCE_BELONGS_TO_A_TABLE_1 = 90082; - - /** - * The error with code 90083 is thrown when - * trying to drop a column that is part of a constraint. - * Example: - *
-     * CREATE TABLE TEST(ID INT, PID INT REFERENCES(ID));
-     * ALTER TABLE TEST DROP COLUMN PID;
-     * 
- */ - public static final int COLUMN_MAY_BE_REFERENCED_1 = 90083; - - /** - * The error with code 90084 is thrown when - * trying to drop the last column of a table. - * Example: - *
-     * CREATE TABLE TEST(ID INT);
-     * ALTER TABLE TEST DROP COLUMN ID;
-     * 
- */ - public static final int CANNOT_DROP_LAST_COLUMN = 90084; - - /** - * The error with code 90085 is thrown when - * trying to manually drop an index that was generated by the system - * because of a unique or referential constraint. To find out what - * constraint causes the problem, run: - *
-     * SELECT * FROM INFORMATION_SCHEMA.CONSTRAINTS
-     * WHERE UNIQUE_INDEX_NAME = '<index name>';
-     * 
- * Example of wrong usage: - *
-     * CREATE TABLE TEST(ID INT, CONSTRAINT UID UNIQUE(ID));
-     * DROP INDEX UID_INDEX_0;
-     * Index UID_INDEX_0 belongs to a constraint
-     * 
- * Correct: - *
-     * ALTER TABLE TEST DROP CONSTRAINT UID;
-     * 
- */ - public static final int INDEX_BELONGS_TO_CONSTRAINT_1 = 90085; - - /** - * The error with code 90086 is thrown when - * a class can not be loaded because it is not in the classpath - * or because a related class is not in the classpath. - * Example: - *
-     * CREATE ALIAS TEST FOR "java.lang.invalid.Math.sqrt";
-     * 
- */ - public static final int CLASS_NOT_FOUND_1 = 90086; - - /** - * The error with code 90087 is thrown when - * the specified method was not found in the class. - * Example: - *
-     * CREATE ALIAS TO_BINARY FOR "java.lang.Long.toBinaryString(long)";
-     * CALL TO_BINARY(10, 2);
-     * 
- */ - public static final int METHOD_NOT_FOUND_1 = 90087; - - /** - * The error with code 90088 is thrown when - * trying to switch to an unknown mode. - * Example: - *
-     * SET MODE UNKNOWN;
-     * 
- */ - public static final int UNKNOWN_MODE_1 = 90088; - - /** - * The error with code 90089 is thrown when - * trying to change the collation while there was already data in - * the database. The collation of the database must be set when the - * database is empty. - * Example of wrong usage: - *
-     * CREATE TABLE TEST(NAME VARCHAR PRIMARY KEY);
-     * INSERT INTO TEST VALUES('Hello', 'World');
-     * SET COLLATION DE;
-     * Collation cannot be changed because there is a data table: PUBLIC.TEST
-     * 
- * Correct: - *
-     * SET COLLATION DE;
-     * CREATE TABLE TEST(NAME VARCHAR PRIMARY KEY);
-     * INSERT INTO TEST VALUES('Hello', 'World');
-     * 
- */ - public static final int COLLATION_CHANGE_WITH_DATA_TABLE_1 = 90089; - - /** - * The error with code 90090 is thrown when - * trying to drop a schema that may not be dropped (the schema PUBLIC - * and the schema INFORMATION_SCHEMA). - * Example: - *
-     * DROP SCHEMA PUBLIC;
-     * 
- */ - public static final int SCHEMA_CAN_NOT_BE_DROPPED_1 = 90090; - - /** - * The error with code 90091 is thrown when - * trying to drop the role PUBLIC. - * Example: - *
-     * DROP ROLE PUBLIC;
-     * 
- */ - public static final int ROLE_CAN_NOT_BE_DROPPED_1 = 90091; - - /** - * The error with code 90092 is thrown when - * the source code is not compiled for the Java platform used. - * At runtime, the existence of the class java.sql.Savepoint is checked. - * To run this database in JDK 1.3, it is first required to switch the - * source code to JDK 1.3 using ant switchSourceJdk13. - */ - public static final int UNSUPPORTED_JAVA_VERSION = 90092; - - /** - * The error with code 90093 is thrown when - * trying to connect to a clustered database that runs in standalone - * mode. This can happen if clustering is not enabled on the database, - * or if one of the clients disabled clustering because it can not see - * the other cluster node. - */ - public static final int CLUSTER_ERROR_DATABASE_RUNS_ALONE = 90093; - - /** - * The error with code 90094 is thrown when - * trying to connect to a clustered database that runs together with a - * different cluster node setting than what is used when trying to connect. - */ - public static final int CLUSTER_ERROR_DATABASE_RUNS_CLUSTERED_1 = 90094; - - /** - * The error with code 90095 is thrown when - * calling the method STRINGDECODE with an invalid escape sequence. - * Only Java style escape sequences and Java properties file escape - * sequences are supported. - * Example: - *
-     * CALL STRINGDECODE('\i');
-     * 
- */ - public static final int STRING_FORMAT_ERROR_1 = 90095; - - /** - * The error with code 90096 is thrown when - * trying to perform an operation with a non-admin user if the - * user does not have enough rights. - */ - public static final int NOT_ENOUGH_RIGHTS_FOR_1 = 90096; - - /** - * The error with code 90097 is thrown when - * trying to delete or update a database if it is open in read-only mode. - * Example: - *
-     * jdbc:h2:~/test;ACCESS_MODE_DATA=R
-     * CREATE TABLE TEST(ID INT);
-     * 
- */ - public static final int DATABASE_IS_READ_ONLY = 90097; - - /** - * The error with code 90098 is thrown when the database has - * been closed, for example because the system ran out of memory or because - * the self-destruction counter has reached zero. This counter is only used - * for recovery testing, and not set in normal operation. - */ - public static final int DATABASE_IS_CLOSED = 90098; - - /** - * The error with code 90099 is thrown when an error occurred - * trying to initialize the database event listener. Example: - *
-     * jdbc:h2:˜/test;DATABASE_EVENT_LISTENER='java.lang.String'
-     * 
- */ - public static final int ERROR_SETTING_DATABASE_EVENT_LISTENER_2 = 90099; - - /** - * The error with code 90100 is thrown when - * there is no more space available on the device where the database - * files are stored. - */ - public static final int NO_DISK_SPACE_AVAILABLE = 90100; - - /** - * The error with code 90101 is thrown when - * the XA API detected unsupported transaction names. This can happen - * when mixing application generated transaction names and transaction names - * generated by this databases XAConnection API. - */ - public static final int WRONG_XID_FORMAT_1 = 90101; - - /** - * The error with code 90102 is thrown when - * trying to use unsupported options for the given compression algorithm. - * Example of wrong usage: - *
-     * CALL COMPRESS(STRINGTOUTF8(SPACE(100)), 'DEFLATE l 10');
-     * 
- * Correct: - *
-     * CALL COMPRESS(STRINGTOUTF8(SPACE(100)), 'DEFLATE l 9');
-     * 
- */ - public static final int UNSUPPORTED_COMPRESSION_OPTIONS_1 = 90102; - - /** - * The error with code 90103 is thrown when - * trying to use an unsupported compression algorithm. - * Example: - *
-     * CALL COMPRESS(STRINGTOUTF8(SPACE(100)), 'BZIP');
-     * 
- */ - public static final int UNSUPPORTED_COMPRESSION_ALGORITHM_1 = 90103; - - /** - * The error with code 90104 is thrown when - * the data can not be de-compressed. - * Example: - *
-     * CALL EXPAND(X'00FF');
-     * 
- */ - public static final int COMPRESSION_ERROR = 90104; - - /** - * The error with code 90105 is thrown when - * an exception occurred in a user-defined method. - * Example: - *
-     * CREATE ALIAS SYS_PROP FOR "java.lang.System.getProperty";
-     * CALL SYS_PROP(NULL);
-     * 
- */ - public static final int EXCEPTION_IN_FUNCTION_1 = 90105; - - /** - * The error with code 90106 is thrown when - * trying to truncate a table that can not be truncated. - * Tables with referential integrity constraints can not be truncated. - * Also, system tables and view can not be truncated. - * Example: - *
-     * TRUNCATE TABLE INFORMATION_SCHEMA.SETTINGS;
-     * 
- */ - public static final int CANNOT_TRUNCATE_1 = 90106; - - /** - * The error with code 90107 is thrown when - * trying to drop an object because another object would become invalid. - * Example: - *
-     * CREATE TABLE COUNT(X INT);
-     * CREATE TABLE ITEMS(ID INT DEFAULT SELECT MAX(X)+1 FROM COUNT);
-     * DROP TABLE COUNT;
-     * 
- */ - public static final int CANNOT_DROP_2 = 90107; - - /** - * The error with code 90108 is thrown when not enough heap - * memory was available. A possible solutions is to increase the memory size - * using java -Xmx128m .... Another solution is to reduce - * the cache size. - */ - public static final int OUT_OF_MEMORY = 90108; - - /** - * The error with code 90109 is thrown when - * trying to run a query against an invalid view. - * Example: - *
-     * CREATE FORCE VIEW TEST_VIEW AS SELECT * FROM TEST;
-     * SELECT * FROM TEST_VIEW;
-     * 
- */ - public static final int VIEW_IS_INVALID_2 = 90109; - - /** - * The error with code 90110 is thrown when - * the result of the calculation does not fit in the given data type. - * Example: - *
-     * CALL -CAST(-128 AS TINYINT);
-     * 
- */ - public static final int OVERFLOW_FOR_TYPE_1 = 90110; - - /** - * The error with code 90111 is thrown when - * an exception occurred while accessing a linked table. - */ - public static final int ERROR_ACCESSING_LINKED_TABLE_2 = 90111; - - /** - * The error with code 90112 is thrown when a row was deleted - * twice while locking was disabled. This is an intern exception that should - * never be thrown to the application, because such deleted should be - * detected and the resulting exception ignored inside the database engine. - *
-     * Row not found when trying to delete from index UID_INDEX_0
-     * 
- */ - public static final int ROW_NOT_FOUND_WHEN_DELETING_1 = 90112; - - /** - * The error with code 90113 is thrown when - * the database URL contains unsupported settings. - * Example: - *
-     * jdbc:h2:~/test;UNKNOWN=TRUE
-     * 
- */ - public static final int UNSUPPORTED_SETTING_1 = 90113; - - /** - * The error with code 90114 is thrown when - * trying to create a constant if a constant with this name already exists. - * Example: - *
-     * CREATE CONSTANT TEST VALUE 1;
-     * CREATE CONSTANT TEST VALUE 1;
-     * 
- */ - public static final int CONSTANT_ALREADY_EXISTS_1 = 90114; - - /** - * The error with code 90115 is thrown when - * trying to drop a constant that does not exists. - * Example: - *
-     * DROP CONSTANT UNKNOWN;
-     * 
- */ - public static final int CONSTANT_NOT_FOUND_1 = 90115; - - /** - * The error with code 90116 is thrown when - * trying use a literal in a SQL statement if literals are disabled. - * If literals are disabled, use PreparedStatement and parameters instead - * of literals in the SQL statement. - * Example: - *
-     * SET ALLOW_LITERALS NONE;
-     * CALL 1+1;
-     * 
- */ - public static final int LITERALS_ARE_NOT_ALLOWED = 90116; - - /** - * The error with code 90117 is thrown when - * trying to connect to a TCP server from another machine, if remote - * connections are not allowed. To allow remote connections, - * start the TCP server using the option -tcpAllowOthers as in: - *
-     * java org.h2.tools.Server -tcp -tcpAllowOthers
-     * 
- * Or, when starting the server from an application, use: - *
-     * Server server = Server.createTcpServer("-tcpAllowOthers");
-     * server.start();
-     * 
- */ - public static final int REMOTE_CONNECTION_NOT_ALLOWED = 90117; - - /** - * The error with code 90118 is thrown when - * trying to drop a table can not be dropped. - * Example: - *
-     * DROP TABLE INFORMATION_SCHEMA.SETTINGS;
-     * 
- */ - public static final int CANNOT_DROP_TABLE_1 = 90118; - - /** - * The error with code 90119 is thrown when - * trying to create a domain if an object with this name already exists, - * or when trying to overload a built-in data type. - * Example: - *
-     * CREATE DOMAIN INTEGER AS VARCHAR;
-     * CREATE DOMAIN EMAIL AS VARCHAR CHECK LOCATE('@', VALUE) > 0;
-     * CREATE DOMAIN EMAIL AS VARCHAR CHECK LOCATE('@', VALUE) > 0;
-     * 
- */ - public static final int USER_DATA_TYPE_ALREADY_EXISTS_1 = 90119; - - /** - * The error with code 90120 is thrown when - * trying to drop a domain that doesn't exists. - * Example: - *
-     * DROP DOMAIN UNKNOWN;
-     * 
- */ - public static final int USER_DATA_TYPE_NOT_FOUND_1 = 90120; - - /** - * The error with code 90121 is thrown when - * a database operation is started while the virtual machine exits - * (for example in a shutdown hook), or when the session is closed. - */ - public static final int DATABASE_CALLED_AT_SHUTDOWN = 90121; - - /** - * The error with code 90122 is thrown when - * trying to altering, adding or dropping columns of a table that has views. - * Example: - *
-     * CREATE TABLE TEST(ID INT);
-     * CREATE VIEW TEST_VIEW AS SELECT * FROM TEST;
-     * ALTER TABLE TEST ADD COLUMN NAME VARCHAR;
-     * 
- */ - public static final int OPERATION_NOT_SUPPORTED_WITH_VIEWS_2 = 90122; - - /** - * The error with code 90123 is thrown when - * trying mix regular parameters and indexed parameters in the same statement. - * Example: - *
-     * SELECT ?, ?1 FROM DUAL;
-     * 
- */ - public static final int CANNOT_MIX_INDEXED_AND_UNINDEXED_PARAMS = 90123; - - /** - * The error with code 90124 is thrown when - * trying to access a file that doesn't exist. This can occur when trying to - * read a lob if the lob file has been deleted by another application. - */ - public static final int FILE_NOT_FOUND_1 = 90124; - - /** - * The error with code 90125 is thrown when - * PreparedStatement.setBigDecimal is called - * with object that extends the class BigDecimal, and the system property - * h2.allowBigDecimalExtensions is not set. Using extensions of BigDecimal is - * dangerous because the database relies on the behavior of BigDecimal. - * Example of wrong usage: - *
-     * BigDecimal bd = new MyDecimal("$10.3");
-     * prep.setBigDecimal(1, bd);
-     * Invalid class, expected java.math.BigDecimal but got MyDecimal
-     * 
- * Correct: - *
-     * BigDecimal bd = new BigDecimal("10.3");
-     * prep.setBigDecimal(1, bd);
-     * 
- */ - public static final int INVALID_CLASS_2 = 90125; - - /** - * The error with code 90126 is thrown when - * trying to call the BACKUP statement for an in-memory database. - * Example: - *
-     * jdbc:h2:mem:
-     * BACKUP TO 'test.zip';
-     * 
- */ - public static final int DATABASE_IS_NOT_PERSISTENT = 90126; - - /** - * The error with code 90127 is thrown when - * trying to update or delete a row in a result set if the result set is - * not updatable. Result sets are only updatable if the statement was - * created with updatable concurrency, and if the result set contains - * all columns of the primary key or of a unique index of a table. - */ - public static final int RESULT_SET_NOT_UPDATABLE = 90127; - - /** - * The error with code 90128 is thrown when - * trying to call a method of the ResultSet that is only supported - * for scrollable result sets, and the result set is not scrollable. - * Example: - *
-     * rs.first();
-     * 
- */ - public static final int RESULT_SET_NOT_SCROLLABLE = 90128; - - /** - * The error with code 90129 is thrown when - * trying to commit a transaction that doesn't exist. - * Example: - *
-     * PREPARE COMMIT ABC;
-     * COMMIT TRANSACTION TEST;
-     * 
- */ - public static final int TRANSACTION_NOT_FOUND_1 = 90129; - - /** - * The error with code 90130 is thrown when - * an execute method of PreparedStatement was called with a SQL statement. - * This is not allowed according to the JDBC specification. Instead, use - * an execute method of Statement. - * Example of wrong usage: - *
-     * PreparedStatement prep = conn.prepareStatement("SELECT * FROM TEST");
-     * prep.execute("DELETE FROM TEST");
-     * 
- * Correct: - *
-     * Statement stat = conn.createStatement();
-     * stat.execute("DELETE FROM TEST");
-     * 
- */ - public static final int METHOD_NOT_ALLOWED_FOR_PREPARED_STATEMENT = 90130; - - /** - * The error with code 90131 is thrown when - * using multi version concurrency control, and trying to update the same - * row from within two connections at the same time. - * Example: - *
-     * jdbc:h2:~/test;MVCC=TRUE
-     * Session 1:
-     * CREATE TABLE TEST(ID INT);
-     * INSERT INTO TEST VALUES(1);
-     * SET AUTOCOMMIT FALSE;
-     * UPDATE TEST SET ID = 2;
-     * Session 2:
-     * SET AUTOCOMMIT FALSE;
-     * UPDATE TEST SET ID = 3;
-     * 
- */ - public static final int CONCURRENT_UPDATE_1 = 90131; - - /** - * The error with code 90132 is thrown when - * trying to drop a user-defined aggregate function that doesn't exist. - * Example: - *
-     * DROP AGGREGATE UNKNOWN;
-     * 
- */ - public static final int AGGREGATE_NOT_FOUND_1 = 90132; - - /** - * The error with code 90133 is thrown when - * trying to change a specific database property while the database is already - * open. The MVCC property needs to be set in the first connection - * (in the connection opening the database) and can not be changed later on. - */ - public static final int CANNOT_CHANGE_SETTING_WHEN_OPEN_1 = 90133; - - /** - * The error with code 90134 is thrown when - * trying to load a Java class that is not part of the allowed classes. - * By default, all classes are allowed, but this can be changed using the system - * property h2.allowedClasses. - */ - public static final int ACCESS_DENIED_TO_CLASS_1 = 90134; - - /** - * The error with code 90135 is thrown when - * trying to open a connection to a database that is currently open - * in exclusive mode. The exclusive mode is set using: - *
-     * SET EXCLUSIVE TRUE;
-     * 
- */ - public static final int DATABASE_IS_IN_EXCLUSIVE_MODE = 90135; - - /** - * The error with code 90136 is thrown when - * executing a query that used an unsupported outer join condition. - * Example: - *
-     * SELECT * FROM DUAL A LEFT JOIN DUAL B ON B.X=(SELECT MAX(X) FROM DUAL);
-     * 
- */ - public static final int UNSUPPORTED_OUTER_JOIN_CONDITION_1 = 90136; - - /** - * The error with code 90137 is thrown when - * trying to assign a value to something that is not a variable. - *
-     * SELECT AMOUNT, SET(@V, IFNULL(@V, 0)+AMOUNT) FROM TEST;
-     * 
- */ - public static final int CAN_ONLY_ASSIGN_TO_VARIABLE_1 = 90137; - - /** - * The error with code 90138 is thrown when - * - * trying to open a persistent database using an incorrect database name. - * The name of a persistent database contains the path and file name prefix - * where the data is stored. The file name part of a database name must be - * at least two characters. - * - * Example of wrong usage: - *
-     * DriverManager.getConnection("jdbc:h2:~/t");
-     * DriverManager.getConnection("jdbc:h2:~/test/");
-     * 
- * Correct: - *
-     * DriverManager.getConnection("jdbc:h2:~/te");
-     * DriverManager.getConnection("jdbc:h2:~/test/te");
-     * 
- */ - public static final int INVALID_DATABASE_NAME_1 = 90138; - - /** - * The error with code 90139 is thrown when - * the specified public static Java method was not found in the class. - * Example: - *
-     * CREATE ALIAS TEST FOR "java.lang.Math.test";
-     * 
- */ - public static final int PUBLIC_STATIC_JAVA_METHOD_NOT_FOUND_1 = 90139; - - /** - * The error with code 90140 is thrown when trying to update or - * delete a row in a result set if the statement was not created with - * updatable concurrency. Result sets are only updatable if the statement - * was created with updatable concurrency, and if the result set contains - * all columns of the primary key or of a unique index of a table. - */ - public static final int RESULT_SET_READONLY = 90140; - - // next is 90140 - - private ErrorCode() { - // utility class - } - - /** - * INTERNAL - */ - public static boolean isCommon(int errorCode) { - switch (errorCode) { - case DATA_CONVERSION_ERROR_1: - case DUPLICATE_KEY_1: - case LOCK_TIMEOUT_1: - case NULL_NOT_ALLOWED: - case NO_DATA_AVAILABLE: - case REFERENTIAL_INTEGRITY_VIOLATED_CHILD_EXISTS_1: - case REFERENTIAL_INTEGRITY_VIOLATED_PARENT_MISSING_1: - case SYNTAX_ERROR_1: - case SYNTAX_ERROR_2: - case TABLE_OR_VIEW_ALREADY_EXISTS_1: - case TABLE_OR_VIEW_NOT_FOUND_1: - case VALUE_TOO_LARGE_FOR_PRECISION_1: - case VALUE_TOO_LONG_2: - return true; - } - return false; - } - - /** - * INTERNAL - */ - public static String getState(int errorCode) { - // To convert SQLState to error code, replace - // 21S: 210, 42S: 421, HY: 50, C: 1, T: 2 - - switch (errorCode) { - // 02: no data - case NO_DATA_AVAILABLE: return "02000"; - - // 07: dynamic SQL error - case INVALID_PARAMETER_COUNT_2: return "07001"; - - // 08: connection exception - case ERROR_OPENING_DATABASE_1: return "08000"; - case WRONG_USER_OR_PASSWORD: return "08004"; - - // 21: cardinality violation - case COLUMN_COUNT_DOES_NOT_MATCH: return "21S02"; - - // 42: syntax error or access rule violation - case SYNTAX_ERROR_1: return "42000"; - case SYNTAX_ERROR_2: return "42001"; - case TABLE_OR_VIEW_ALREADY_EXISTS_1: return "42S01"; - case TABLE_OR_VIEW_NOT_FOUND_1: return "42S02"; - case INDEX_ALREADY_EXISTS_1: return "42S11"; - case INDEX_NOT_FOUND_1: return "42S12"; - case DUPLICATE_COLUMN_NAME_1: return "42S21"; - case COLUMN_NOT_FOUND_1: return "42S22"; - - // 0A: feature not supported - - // HZ: remote database access - - // HY - case GENERAL_ERROR_1: return "HY000"; - case UNKNOWN_DATA_TYPE_1: return "HY004"; - - case FEATURE_NOT_SUPPORTED_1: return "HYC00"; - case LOCK_TIMEOUT_1: return "HYT00"; - default: - return "" + errorCode; - } - } - -} diff --git a/tools/h2/src/main/org/h2/constant/SysProperties.java b/tools/h2/src/main/org/h2/constant/SysProperties.java deleted file mode 100755 index 85adfce..0000000 --- a/tools/h2/src/main/org/h2/constant/SysProperties.java +++ /dev/null @@ -1,733 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.constant; - -import java.sql.ResultSet; -import org.h2.engine.Constants; -import org.h2.message.TraceSystem; -import org.h2.util.MathUtils; - -/** - * The constants defined in this class are initialized from system properties. - * Some system properties are per machine settings, and others are as a last - * resort and temporary solution to work around a problem in the application or - * database engine. Also, there are system properties to enable features that - * are not yet fully tested or that are not backward compatible. - *

- * System properties can be set when starting the virtual machine: - *

- * - *
- * java -Dh2.baseDir=/temp
- * 
- * - * They can be set within the application, but this must be done before loading - * any classes of this database (before loading the JDBC driver): - * - *
- * System.setProperty("h2.baseDir", "/temp");
- * 
- */ -public class SysProperties { - - /** - * INTERNAL - */ - public static final String H2_SCRIPT_DIRECTORY = "h2.scriptDirectory"; - - /** - * INTERNAL - */ - public static final String H2_MAX_QUERY_TIMEOUT = "h2.maxQueryTimeout"; - - /** - * INTERNAL - */ - public static final String H2_COLLATOR_CACHE_SIZE = "h2.collatorCacheSize"; - - /** - * System property file.encoding (default: Cp1252).
- * It is usually set by the system and is the default encoding used for the - * RunScript and CSV tool. - */ - public static final String FILE_ENCODING = getStringSetting("file.encoding", "Cp1252"); - - /** - * System property file.separator (default: /).
- * It is usually set by the system, and used to build absolute file names. - */ - public static final String FILE_SEPARATOR = getStringSetting("file.separator", "/"); - - /** - * System property java.specification.version.
- * It is set by the system. Examples: 1.4, 1.5, 1.6. - */ - public static final String JAVA_SPECIFICATION_VERSION = getStringSetting("java.specification.version", "1.4"); - - /** - * System property line.separator (default: \n).
- * It is usually set by the system, and used by the script and trace tools. - */ - public static final String LINE_SEPARATOR = getStringSetting("line.separator", "\n"); - - /** - * System property user.home (empty string if not set).
- * It is usually set by the system, and used as a replacement for ~ in file - * names. - */ - public static final String USER_HOME = getStringSetting("user.home", ""); - - /** - * System property h2.analyzeSample (default: 10000).
- * The default sample size when analyzing a table. - */ - public static final int ANALYZE_SAMPLE = getIntSetting("h2.analyzeSample", 10000); - - /** - * System property h2.analyzeAuto (default: 0).
- * After changing this many rows, ANALYZE is automatically run for a table. - * Automatically running ANALYZE is disabled if set to 0. If set to 1000, - * then ANALYZE will run against each user table after about 1000 changes to - * that table. The time between running ANALYZE doubles each time since - * starting the database. It is not run on local temporary tables, and - * tables that have a trigger on SELECT. - */ - public static final int ANALYZE_AUTO = getIntSetting("h2.analyzeAuto", 0); - - /** - * System property h2.aliasColumnName (default: false).
- * When enabled, aliased columns (as in SELECT ID AS I FROM TEST) return the - * alias (I in this case) in ResultSetMetaData.getColumnName() and 'null' in - * getTableName(). If disabled, the real column name (ID in this case) and - * table name is returned. This setting only affects the default mode. - *
- * When using different modes, this feature is disabled for compatibility - * for all databases except MySQL. For MySQL, it is always enabled. - */ - public static final boolean ALIAS_COLUMN_NAME = getBooleanSetting("h2.aliasColumnName", false); - - /** - * System property h2.allowBigDecimalExtensions (default: - * false).
- * When enabled, classes that extend BigDecimal are supported in - * PreparedStatement.setBigDecimal. - */ - public static final boolean ALLOW_BIG_DECIMAL_EXTENSIONS = getBooleanSetting("h2.allowBigDecimalExtensions", false); - - /** - * System property h2.allowedClasses (default: *).
- * Comma separated list of class names or prefixes. - */ - public static final String ALLOWED_CLASSES = getStringSetting("h2.allowedClasses", "*"); - - /** - * System property h2.browser (default: null).
- * The preferred browser to use. If not set, the default browser is used. - * For Windows, to use the Internet Explorer, set this property to 'explorer'. - * For Mac OS, if the default browser is not Safari and you want to use Safari, - * use: java -Dh2.browser="open,-a,Safari,%url" .... - */ - public static final String BROWSER = getStringSetting("h2.browser", null); - - /** - * System property h2.enableAnonymousSSL (default: true).
- * When using SSL connection, the anonymous cipher suite - * SSL_DH_anon_WITH_RC4_128_MD5 should be enabled. - */ - public static final boolean ENABLE_ANONYMOUS_SSL = getBooleanSetting("h2.enableAnonymousSSL", true); - - /** - * System property h2.bindAddress (default: null).
- * Comma separated list of class names or prefixes. - */ - public static final String BIND_ADDRESS = getStringSetting("h2.bindAddress", null); - - /** - * System property h2.cacheSizeDefault (default: 16384).
- * The default cache size in KB. - */ - public static final int CACHE_SIZE_DEFAULT = getIntSetting("h2.cacheSizeDefault", 16 * 1024); - - /** - * System property h2.cacheTypeDefault (default: LRU).
- * How many time the cache size value is divided by two to get the index - * cache size. The index cache size is calculated like this: cacheSize >> - * cacheSizeIndexShift. - */ - public static final String CACHE_TYPE_DEFAULT = getStringSetting("h2.cacheTypeDefault", "LRU"); - - /** - * System property h2.check (default: true).
- * Assertions in the database engine. - */ - public static final boolean CHECK = getBooleanSetting("h2.check", true); - - /** - * System property h2.check2 (default: true).
- * Additional assertions in the database engine. - */ - public static final boolean CHECK2 = getBooleanSetting("h2.check2", false); - - /** - * System property h2.clientTraceDirectory (default: - * trace.db/).
- * Directory where the trace files of the JDBC client are stored (only for - * client / server). - */ - public static final String CLIENT_TRACE_DIRECTORY = getStringSetting("h2.clientTraceDirectory", "trace.db/"); - - /** - * System property h2.consoleStream (default: true).
- * H2 Console: stream query results. - */ - public static final boolean CONSOLE_STREAM = getBooleanSetting("h2.consoleStream", true); - - /** - * System property h2.defaultEscape (default: \).
- * The default escape character for LIKE comparisons. To select no escape - * character, use an empty string. - */ - public static final String DEFAULT_ESCAPE = getStringSetting("h2.defaultEscape", "\\"); - - /** - * System property h2.defaultMaxOperationMemory (default: - * 100000).
- * The default for the setting MAX_OPERATION_MEMORY. - */ - public static final int DEFAULT_MAX_OPERATION_MEMORY = getIntSetting("h2.defaultMaxOperationMemory", 100000); - - /** - * System property h2.defaultMaxLengthInplaceLob - * (default: 4096).
- * The default maximum length of an LOB that is stored in the database file. - */ - public static final int DEFAULT_MAX_LENGTH_INPLACE_LOB = getIntSetting("h2.defaultMaxLengthInplaceLob", 4096); - - /** - * System property h2.defaultMaxLengthInplaceLob2 - * (default: 128).
- * The default maximum length of an LOB that is stored with the record itself. - * Only used if h2.lobInDatabase is enabled. - */ - public static final int DEFAULT_MAX_LENGTH_INPLACE_LOB2 = getIntSetting("h2.defaultMaxLengthInplaceLob2", 128); - - /** - * System property h2.defaultResultSetConcurrency (default: - * ResultSet.CONCUR_READ_ONLY).
- * The default result set concurrency for statements created with - * Connection.createStatement() or prepareStatement(String sql). - */ - public static final int DEFAULT_RESULT_SET_CONCURRENCY = getIntSetting("h2.defaultResultSetConcurrency", ResultSet.CONCUR_READ_ONLY); - - /** - * System property h2.dataSourceTraceLevel (default: 1).
- * The trace level of the data source implementation. Default is 1 for - * error. - */ - public static final int DATASOURCE_TRACE_LEVEL = getIntSetting("h2.dataSourceTraceLevel", TraceSystem.ERROR); - - /** - * System property h2.defaultMaxMemoryUndo (default: 50000).
- * The default value for the MAX_MEMORY_UNDO setting. - */ - public static final int DEFAULT_MAX_MEMORY_UNDO = getIntSetting("h2.defaultMaxMemoryUndo", 50000); - - /** - * System property h2.defaultLockMode (default: 3).
- * The default value for the LOCK_MODE setting. - */ - public static final int DEFAULT_LOCK_MODE = getIntSetting("h2.defaultLockMode", Constants.LOCK_MODE_READ_COMMITTED); - - /** - * System property h2.delayWrongPasswordMin (default: 250).
- * The minimum delay in milliseconds before an exception is thrown for using - * the wrong user name or password. This slows down brute force attacks. The - * delay is reset to this value after a successful login. Unsuccessful - * logins will double the time until DELAY_WRONG_PASSWORD_MAX. - * To disable the delay, set this system property to 0. - */ - public static final int DELAY_WRONG_PASSWORD_MIN = getIntSetting("h2.delayWrongPasswordMin", 250); - - /** - * System property h2.delayWrongPasswordMax (default: 4000).
- * The maximum delay in milliseconds before an exception is thrown for using - * the wrong user name or password. This slows down brute force attacks. The - * delay is reset after a successful login. The value 0 means there is no - * maximum delay. - */ - public static final int DELAY_WRONG_PASSWORD_MAX = getIntSetting("h2.delayWrongPasswordMax", 4000); - - /** - * System property h2.estimatedFunctionTableRows (default: - * 1000).
- * The estimated number of rows in a function table (for example, CSVREAD or - * FTL_SEARCH). This value is used by the optimizer. - */ - public static final int ESTIMATED_FUNCTION_TABLE_ROWS = getIntSetting("h2.estimatedFunctionTableRows", 1000); - - /** - * System property h2.functionsInSchema (default: - * false).
- * If set, all functions are stored in a schema. Specially, the SCRIPT statement - * will always include the schema name in the CREATE ALIAS statement. - * This is not backward compatible with H2 versions 1.2.134 and older. - */ - public static final boolean FUNCTIONS_IN_SCHEMA = getBooleanSetting("h2.functionsInSchema", false); - - /** - * System property h2.identifiersToUpper (default: true).
- * Unquoted identifiers in SQL statements are case insensitive and converted - * to uppercase. - */ - public static final boolean IDENTIFIERS_TO_UPPER = getBooleanSetting("h2.identifiersToUpper", true); - - /** - * System property h2.largeResultBufferSize (default: 4096).
- * Buffer size for large result sets. Set this value to 0 to disable the - * buffer. - */ - public static final int LARGE_RESULT_BUFFER_SIZE = getIntSetting("h2.largeResultBufferSize", 4 * 1024); - - /** - * System property h2.largeTransactions (default: false).
- * Support very large transactions - */ - public static final boolean LARGE_TRANSACTIONS = getBooleanSetting("h2.largeTransactions", false); - - /** - * System property h2.lobCloseBetweenReads (default: false).
- * Close LOB files between read operations. - */ - public static boolean lobCloseBetweenReads = getBooleanSetting("h2.lobCloseBetweenReads", false); - - /** - * System property h2.lobFilesPerDirectory (default: 256).
- * Maximum number of LOB files per directory. - */ - public static final int LOB_FILES_PER_DIRECTORY = getIntSetting("h2.lobFilesPerDirectory", 256); - - /** - * System property h2.lobInDatabase (default: false).
- * Store LOB files in the database. - */ - public static final boolean LOB_IN_DATABASE = getBooleanSetting("h2.lobInDatabase", false); - - /** - * System property h2.logAllErrors (default: false).
- * Write stack traces of any kind of error to a file. - */ - public static final boolean LOG_ALL_ERRORS = getBooleanSetting("h2.logAllErrors", false); - - /** - * System property h2.logAllErrorsFile (default: - * h2errors.txt).
- * File name to log errors. - */ - public static final String LOG_ALL_ERRORS_FILE = getStringSetting("h2.logAllErrorsFile", "h2errors.txt"); - - /** - * System property h2.maxCompactCount - * (default: Integer.MAX_VALUE).
- * The maximum number of pages to move when closing a database. - */ - public static final int MAX_COMPACT_COUNT = getIntSetting("h2.maxCompactCount", Integer.MAX_VALUE); - - /** - * System property h2.maxCompactTime (default: 1000).
- * The maximum time in milliseconds used to compact a database when closing. - */ - public static final int MAX_COMPACT_TIME = getIntSetting("h2.maxCompactTime", 1000); - - /** - * System property h2.maxFileRetry (default: 16).
- * Number of times to retry file delete and rename. in Windows, files can't - * be deleted if they are open. Waiting a bit can help (sometimes the - * Windows Explorer opens the files for a short time) may help. Sometimes, - * running garbage collection may close files if the user forgot to call - * Connection.close() or InputStream.close(). - */ - public static final int MAX_FILE_RETRY = Math.max(1, getIntSetting("h2.maxFileRetry", 16)); - - /** - * System property h2.maxMemoryRowsDistinct (default: - * Integer.MAX_VALUE).
- * The maximum number of rows kept in-memory for SELECT DISTINCT queries. If - * more than this number of rows are in a result set, a temporary table is - * used. - */ - public static final int MAX_MEMORY_ROWS_DISTINCT = getIntSetting("h2.maxMemoryRowsDistinct", Integer.MAX_VALUE); - - /** - * System property h2.maxReconnect (default: 3).
- * The maximum number of tries to reconnect in a row. - */ - public static final int MAX_RECONNECT = getIntSetting("h2.maxReconnect", 3); - - /** - * System property h2.maxTraceDataLength (default: 65535).
- * The maximum size of a LOB value that is written as data to the trace system. - */ - public static final long MAX_TRACE_DATA_LENGTH = getIntSetting("h2.maxTraceDataLength", 65535); - - /** - * System property h2.minColumnNameMap (default: 3).
- * The minimum number of columns where a hash table is created when result set - * methods with column name (instead of column index) parameter are called. - */ - public static final int MIN_COLUMN_NAME_MAP = getIntSetting("h2.minColumnNameMap", 3); - - /** - * System property h2.minWriteDelay (default: 5).
- * The minimum write delay that causes commits to be delayed. - */ - public static final int MIN_WRITE_DELAY = getIntSetting("h2.minWriteDelay", 5); - - /** - * System property h2.nioLoadMapped (default: false).
- * If the mapped buffer should be loaded when the file is opened. - * This can improve performance. - */ - public static final boolean NIO_LOAD_MAPPED = getBooleanSetting("h2.nioLoadMapped", false); - - /** - * System property h2.nioCleanerHack (default: true).
- * If possible, use a hack to un-map the mapped file. See also - * http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4724038 - */ - public static final boolean NIO_CLEANER_HACK = getBooleanSetting("h2.nioCleanerHack", true); - - /** - * System property h2.objectCache (default: true).
- * Cache commonly used objects (integers, strings). - */ - public static final boolean OBJECT_CACHE = getBooleanSetting("h2.objectCache", true); - - /** - * System property h2.objectCacheMaxPerElementSize (default: - * 4096).
- * Maximum size of an object in the cache. - */ - public static final int OBJECT_CACHE_MAX_PER_ELEMENT_SIZE = getIntSetting("h2.objectCacheMaxPerElementSize", 4096); - - /** - * System property h2.objectCacheSize (default: 1024).
- * Maximum size of an object in the cache. - * This value must be a power of 2. - */ - public static final int OBJECT_CACHE_SIZE = MathUtils.nextPowerOf2(getIntSetting("h2.objectCacheSize", 1024)); - - /** - * System property h2.optimizeDistinct (default: true).
- * Improve the performance of simple DISTINCT queries if an index is - * available for the given column. The optimization is used if: - *
    - *
  • The select is a single column query without condition
  • - *
  • The query contains only one table, and no group by
  • - *
  • There is only one table involved
  • - *
  • There is an ascending index on the column
  • - *
  • The selectivity of the column is below 20
  • - *
- */ - public static final boolean OPTIMIZE_DISTINCT = getBooleanSetting("h2.optimizeDistinct", true); - - /** - * System property h2.optimizeEvaluatableSubqueries (default: - * true).
- * Optimize subqueries that are not dependent on the outer query. - */ - public static final boolean OPTIMIZE_EVALUATABLE_SUBQUERIES = getBooleanSetting("h2.optimizeEvaluatableSubqueries", true); - - /** - * System property h2.optimizeInList (default: true).
- * Optimize IN(...) and IN(SELECT ...) comparisons. This includes - * optimization for SELECT, DELETE, and UPDATE. - */ - public static final boolean OPTIMIZE_IN_LIST = getBooleanSetting("h2.optimizeInList", true); - - /** - * System property h2.optimizeIsNull (default: false).
- * Use an index for condition of the form columnName IS NULL. - */ - public static final boolean OPTIMIZE_IS_NULL = getBooleanSetting("h2.optimizeIsNull", true); - - /** - * System property h2.optimizeOr (default: false).
- * Convert (C=? OR C=?) to (C IN(?, ?)). - */ - public static final boolean OPTIMIZE_OR = getBooleanSetting("h2.optimizeOr", false); - - /** - * System property h2.optimizeSubqueryCache (default: true).
- * Cache subquery results. - */ - public static final boolean OPTIMIZE_SUBQUERY_CACHE = getBooleanSetting("h2.optimizeSubqueryCache", true); - - /** - * System property h2.optimizeTwoEquals (default: true).
- * Optimize expressions of the form A=B AND B=1. In this case, AND A=1 is - * added so an index on A can be used. - */ - public static final boolean OPTIMIZE_TWO_EQUALS = getBooleanSetting("h2.optimizeTwoEquals", true); - - /** - * System property h2.pageSize (default: 2048).
- * The page size to use for new databases. - */ - public static final int PAGE_SIZE = getIntSetting("h2.pageSize", 2048); - - /** - * System property h2.pageStoreTrim (default: true).
- * Trim the database size when closing. - */ - public static final boolean PAGE_STORE_TRIM = getBooleanSetting("h2.pageStoreTrim", true); - - /** - * System property h2.pageStoreInternalCount (default: false).
- * Update the row counts on a node level. - */ - public static final boolean PAGE_STORE_INTERNAL_COUNT = getBooleanSetting("h2.pageStoreInternalCount", false); - - /** - * System property h2.pgClientEncoding (default: UTF-8).
- * Default client encoding for PG server. It is used if the client does not - * sends his encoding. - */ - public static final String PG_DEFAULT_CLIENT_ENCODING = getStringSetting("h2.pgClientEncoding", "UTF-8"); - - /** - * System property h2.prefixTempFile (default: h2.temp).
- * The prefix for temporary files in the temp directory. - */ - public static final String PREFIX_TEMP_FILE = getStringSetting("h2.prefixTempFile", "h2.temp"); - - /** - * System property h2.recompileAlways (default: false).
- * Always recompile prepared statements. - */ - public static final boolean RECOMPILE_ALWAYS = getBooleanSetting("h2.recompileAlways", false); - - /** - * System property h2.reconnectCheckDelay (default: 200).
- * Check the .lock.db file every this many milliseconds to detect that the - * database was changed. The process writing to the database must first - * notify a change in the .lock.db file, then wait twice this many - * milliseconds before updating the database. - */ - public static final int RECONNECT_CHECK_DELAY = getIntSetting("h2.reconnectCheckDelay", 200); - - /** - * System property h2.redoBufferSize (default: 262144).
- * Size of the redo buffer (used at startup when recovering). - */ - public static final int REDO_BUFFER_SIZE = getIntSetting("h2.redoBufferSize", 256 * 1024); - - /** - * System property h2.reserveMemory (default: 524288).
- * This many bytes in main memory are allocated as a reserve. This reserve - * is freed up when if no memory is available, so that rolling back a large - * transaction is easier. - */ - public static final int RESERVE_MEMORY = getIntSetting("h2.reserveMemory", 512 * 1024); - - /** - * System property h2.returnLobObjects (default: true).
- * When true, ResultSet.getObject for CLOB or BLOB will return a - * java.sql.Clob / java.sql.Blob object. When set to false, it will return a - * java.io.Reader / java.io.InputStream. - */ - public static final boolean RETURN_LOB_OBJECTS = getBooleanSetting("h2.returnLobObjects", true); - - /** - * System property h2.runFinalize (default: true).
- * Run finalizers to detect unclosed connections. - */ - public static boolean runFinalize = getBooleanSetting("h2.runFinalize", true); - - /** - * System property h2.selectForUpdateMvcc (default: false).
- * If set, SELECT .. FOR UPDATE queries lock the rows when using MVCC. - */ - public static final boolean SELECT_FOR_UPDATE_MVCC = getBooleanSetting("h2.selectForUpdateMvcc", false); - - /** - * System property h2.serverCachedObjects (default: 64).
- * TCP Server: number of cached objects per session. - */ - public static final int SERVER_CACHED_OBJECTS = getIntSetting("h2.serverCachedObjects", 64); - - /** - * System property h2.serverResultSetFetchSize - * (default: 100).
- * The default result set fetch size when using the server mode. - */ - public static final int SERVER_RESULT_SET_FETCH_SIZE = getIntSetting("h2.serverResultSetFetchSize", 100); - - /** - * System property h2.shareLinkedConnections - * (default: true).
- * Linked connections should be shared, that means connections to the same - * database should be used for all linked tables that connect to the same - * database. - */ - public static final boolean SHARE_LINKED_CONNECTIONS = getBooleanSetting("h2.shareLinkedConnections", true); - - /** - * System property h2.socketConnectRetry (default: 16).
- * The number of times to retry opening a socket. Windows sometimes fails - * to open a socket, see bug - * http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6213296 - */ - public static final int SOCKET_CONNECT_RETRY = getIntSetting("h2.socketConnectRetry", 16); - - /** - * System property h2.socketConnectTimeout (default: 2000).
- * The timeout in milliseconds to connect to a server. - */ - public static final int SOCKET_CONNECT_TIMEOUT = getIntSetting("h2.socketConnectTimeout", 2000); - - /** - * System property h2.sortNullsHigh (default: false).
- * Invert the default sorting behavior for NULL values, such that NULL - * values are sorted to the end of a result set in an ascending sort and to - * the beginning of a result set in a descending sort. - */ - public static final boolean SORT_NULLS_HIGH = getBooleanSetting("h2.sortNullsHigh", false); - - /** - * System property h2.splitFileSizeShift (default: 30).
- * The maximum file size of a split file is 1L << x. - */ - public static final long SPLIT_FILE_SIZE_SHIFT = getIntSetting("h2.splitFileSizeShift", 30); - - /** - * System property h2.syncMethod (default: sync).
- * What method to call when closing the database, on checkpoint, and on - * CHECKPOINT SYNC. The following options are supported: - * "sync" (default): RandomAccessFile.getFD().sync(); - * "force": RandomAccessFile.getChannel().force(true); - * "forceFalse": RandomAccessFile.getChannel().force(false); - * "": do not call a method (fast but there is a risk of data loss - * on power failure). - */ - public static final String SYNC_METHOD = getStringSetting("h2.syncMethod", "sync"); - - /** - * System property h2.traceIO (default: false).
- * Trace all I/O operations. - */ - public static final boolean TRACE_IO = getBooleanSetting("h2.traceIO", false); - - /** - * System property h2.webMaxValueLength (default: 100000).
- * The H2 Console will abbreviate (truncate) result values larger than this size. - * The data in the database is not truncated, it is only to avoid out of memory - * in the H2 Console application. - */ - public static final int WEB_MAX_VALUE_LENGTH = getIntSetting("h2.webMaxValueLength", 100000); - - private static final String H2_BASE_DIR = "h2.baseDir"; - - private SysProperties() { - // utility class - } - - private static boolean getBooleanSetting(String name, boolean defaultValue) { - String s = getProperty(name); - if (s != null) { - try { - return Boolean.valueOf(s).booleanValue(); - } catch (NumberFormatException e) { - // ignore - } - } - return defaultValue; - } - - private static String getProperty(String name) { - try { - return System.getProperty(name); - } catch (Exception e) { - // SecurityException - // applets may not do that - ignore - return null; - } - } - - /** - * INTERNAL - */ - public static String getStringSetting(String name, String defaultValue) { - String s = getProperty(name); - return s == null ? defaultValue : s; - } - - /** - * INTERNAL - */ - public static int getIntSetting(String name, int defaultValue) { - String s = getProperty(name); - if (s != null) { - try { - return Integer.decode(s).intValue(); - } catch (NumberFormatException e) { - // ignore - } - } - return defaultValue; - } - - /** - * INTERNAL - */ - public static void setBaseDir(String dir) { - if (!dir.endsWith("/")) { - dir += "/"; - } - System.setProperty(H2_BASE_DIR, dir); - } - - /** - * INTERNAL - */ - public static String getBaseDir() { - return getStringSetting(H2_BASE_DIR, null); - } - - /** - * System property h2.scriptDirectory (default: empty - * string).
- * Relative or absolute directory where the script files are stored to or - * read from. - * - * @return the current value - */ - public static String getScriptDirectory() { - return getStringSetting(H2_SCRIPT_DIRECTORY, ""); - } - - /** - * System property h2.maxQueryTimeout (default: 0).
- * The maximum timeout of a query. The default is 0, meaning no limit. - * - * @return the current value - */ - public static int getMaxQueryTimeout() { - return getIntSetting(H2_MAX_QUERY_TIMEOUT, 0); - } - - /** - * System property h2.collatorCacheSize (default: 32000).
- * The cache size for collation keys (in elements). Used when a collator has - * been set for the database. - * - * @return the current value - */ - public static int getCollatorCacheSize() { - return getIntSetting(H2_COLLATOR_CACHE_SIZE, 32000); - } - -} diff --git a/tools/h2/src/main/org/h2/constant/package.html b/tools/h2/src/main/org/h2/constant/package.html deleted file mode 100755 index b351a5e..0000000 --- a/tools/h2/src/main/org/h2/constant/package.html +++ /dev/null @@ -1,15 +0,0 @@ - - - - -Javadoc package documentation -

- -Error codes and system properties. - -

\ No newline at end of file diff --git a/tools/h2/src/main/org/h2/constraint/Constraint.java b/tools/h2/src/main/org/h2/constraint/Constraint.java deleted file mode 100755 index 016b1b3..0000000 --- a/tools/h2/src/main/org/h2/constraint/Constraint.java +++ /dev/null @@ -1,181 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.constraint; - -import org.h2.engine.DbObject; -import org.h2.engine.Session; -import org.h2.index.Index; -import org.h2.message.DbException; -import org.h2.message.Trace; -import org.h2.result.Row; -import org.h2.schema.Schema; -import org.h2.schema.SchemaObjectBase; -import org.h2.table.Column; -import org.h2.table.Table; - -/** - * The base class for constraint checking. - */ -public abstract class Constraint extends SchemaObjectBase implements Comparable { - - /** - * The constraint type name for check constraints. - */ - public static final String CHECK = "CHECK"; - - /** - * The constraint type name for referential constraints. - */ - public static final String REFERENTIAL = "REFERENTIAL"; - - /** - * The constraint type name for unique constraints. - */ - public static final String UNIQUE = "UNIQUE"; - - /** - * The constraint type name for primary key constraints. - */ - public static final String PRIMARY_KEY = "PRIMARY KEY"; - - /** - * The table for which this constraint is defined. - */ - protected Table table; - - public Constraint(Schema schema, int id, String name, Table table) { - initSchemaObjectBase(schema, id, name, Trace.CONSTRAINT); - this.table = table; - this.setTemporary(table.isTemporary()); - } - - /** - * The constraint type name - * - * @return the name - */ - public abstract String getConstraintType(); - - /** - * Check if this row fulfils the constraint. - * This method throws an exception if not. - * - * @param session the session - * @param t the table - * @param oldRow the old row - * @param newRow the new row - */ - public abstract void checkRow(Session session, Table t, Row oldRow, Row newRow); - - /** - * Check if this constraint needs the specified index. - * - * @param index the index - * @return true if the index is used - */ - public abstract boolean usesIndex(Index index); - - /** - * This index is now the owner of the specified index. - * - * @param index the index - */ - public abstract void setIndexOwner(Index index); - - /** - * Check if this constraint contains the given column. - * - * @param col the column - * @return true if it does - */ - public abstract boolean containsColumn(Column col); - - /** - * Get the SQL statement to create this constraint. - * - * @return the SQL statement - */ - public abstract String getCreateSQLWithoutIndexes(); - - /** - * Check if this constraint needs to be checked before updating the data. - * - * @return true if it must be checked before updating - */ - public abstract boolean isBefore(); - - /** - * Check the existing data. This method is called if the constraint is added - * after data has been inserted into the table. - * - * @param session the session - */ - public abstract void checkExistingData(Session session); - - /** - * This method is called after a related table has changed - * (the table was renamed, or columns have been renamed). - */ - public abstract void rebuild(); - - /** - * Get the unique index used to enforce this constraint, or null if no index - * is used. - * - * @return the index - */ - public abstract Index getUniqueIndex(); - - public void checkRename() { - // ok - } - - public int getType() { - return DbObject.CONSTRAINT; - } - - public Table getTable() { - return table; - } - - public Table getRefTable() { - return table; - } - - public String getDropSQL() { - return null; - } - - private int getConstraintTypeOrder() { - String constraintType = getConstraintType(); - if (CHECK.equals(constraintType)) { - return 0; - } else if (PRIMARY_KEY.equals(constraintType)) { - return 1; - } else if (UNIQUE.equals(constraintType)) { - return 2; - } else if (REFERENTIAL.equals(constraintType)) { - return 3; - } else { - throw DbException.throwInternalError("type: " + constraintType); - } - } - - public int compareTo(Constraint other) { - if (this == other) { - return 0; - } - int thisType = getConstraintTypeOrder(); - int otherType = other.getConstraintTypeOrder(); - return thisType - otherType; - } - - public boolean isHidden() { - return table.isHidden(); - } - -} diff --git a/tools/h2/src/main/org/h2/constraint/ConstraintCheck.java b/tools/h2/src/main/org/h2/constraint/ConstraintCheck.java deleted file mode 100755 index c617136..0000000 --- a/tools/h2/src/main/org/h2/constraint/ConstraintCheck.java +++ /dev/null @@ -1,136 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.constraint; - -import org.h2.constant.ErrorCode; -import org.h2.engine.Session; -import org.h2.expression.Expression; -import org.h2.index.Index; -import org.h2.message.DbException; -import org.h2.result.ResultInterface; -import org.h2.result.Row; -import org.h2.schema.Schema; -import org.h2.table.Column; -import org.h2.table.Table; -import org.h2.table.TableFilter; -import org.h2.util.StringUtils; - -/** - * A check constraint. - */ -public class ConstraintCheck extends Constraint { - - private TableFilter filter; - private Expression expr; - - public ConstraintCheck(Schema schema, int id, String name, Table table) { - super(schema, id, name, table); - } - - public String getConstraintType() { - return Constraint.CHECK; - } - - public void setTableFilter(TableFilter filter) { - this.filter = filter; - } - - public void setExpression(Expression expr) { - this.expr = expr; - } - - public String getCreateSQLForCopy(Table forTable, String quotedName) { - StringBuilder buff = new StringBuilder("ALTER TABLE "); - buff.append(forTable.getSQL()).append(" ADD CONSTRAINT "); - if (forTable.isHidden()) { - buff.append("IF NOT EXISTS "); - } - buff.append(quotedName); - if (comment != null) { - buff.append(" COMMENT ").append(StringUtils.quoteStringSQL(comment)); - } - buff.append(" CHECK").append(StringUtils.enclose(expr.getSQL())).append(" NOCHECK"); - return buff.toString(); - } - - private String getShortDescription() { - return getName() + ": " + expr.getSQL(); - } - - public String getCreateSQLWithoutIndexes() { - return getCreateSQL(); - } - - public String getCreateSQL() { - return getCreateSQLForCopy(table, getSQL()); - } - - public void removeChildrenAndResources(Session session) { - table.removeConstraint(this); - database.removeMeta(session, getId()); - filter = null; - expr = null; - table = null; - invalidate(); - } - - public void checkRow(Session session, Table t, Row oldRow, Row newRow) { - if (newRow == null) { - return; - } - filter.set(newRow); - // Both TRUE and NULL are ok - if (Boolean.FALSE.equals(expr.getValue(session).getBoolean())) { - throw DbException.get(ErrorCode.CHECK_CONSTRAINT_VIOLATED_1, getShortDescription()); - } - } - - public boolean usesIndex(Index index) { - return false; - } - - public void setIndexOwner(Index index) { - DbException.throwInternalError(); - } - - public boolean containsColumn(Column col) { - // TODO check constraints / containsColumn: this is cheating, maybe the - // column is not referenced - String s = col.getSQL(); - String sql = getCreateSQL(); - return sql.indexOf(s) >= 0; - } - - public Expression getExpression() { - return expr; - } - - public boolean isBefore() { - return true; - } - - public void checkExistingData(Session session) { - if (session.getDatabase().isStarting()) { - // don't check at startup - return; - } - String sql = "SELECT 1 FROM " + filter.getTable().getSQL() + " WHERE NOT(" + expr.getSQL() + ")"; - ResultInterface r = session.prepare(sql).query(1); - if (r.next()) { - throw DbException.get(ErrorCode.CHECK_CONSTRAINT_VIOLATED_1, getName()); - } - } - - public Index getUniqueIndex() { - return null; - } - - public void rebuild() { - // nothing to do - } - -} diff --git a/tools/h2/src/main/org/h2/constraint/ConstraintReferential.java b/tools/h2/src/main/org/h2/constraint/ConstraintReferential.java deleted file mode 100755 index 7007ca9..0000000 --- a/tools/h2/src/main/org/h2/constraint/ConstraintReferential.java +++ /dev/null @@ -1,643 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.constraint; - -import java.util.ArrayList; -import org.h2.command.Parser; -import org.h2.command.Prepared; -import org.h2.constant.ErrorCode; -import org.h2.engine.Session; -import org.h2.expression.Expression; -import org.h2.expression.Parameter; -import org.h2.index.Cursor; -import org.h2.index.Index; -import org.h2.message.DbException; -import org.h2.result.ResultInterface; -import org.h2.result.Row; -import org.h2.result.SearchRow; -import org.h2.schema.Schema; -import org.h2.table.Column; -import org.h2.table.IndexColumn; -import org.h2.table.Table; -import org.h2.util.StatementBuilder; -import org.h2.util.StringUtils; -import org.h2.value.Value; -import org.h2.value.ValueNull; - -/** - * A referential constraint. - */ -public class ConstraintReferential extends Constraint { - - /** - * The action is to restrict the operation. - */ - public static final int RESTRICT = 0; - - /** - * The action is to cascade the operation. - */ - public static final int CASCADE = 1; - - /** - * The action is to set the value to the default value. - */ - public static final int SET_DEFAULT = 2; - - /** - * The action is to set the value to NULL. - */ - public static final int SET_NULL = 3; - - private IndexColumn[] columns; - private IndexColumn[] refColumns; - private int deleteAction; - private int updateAction; - private Table refTable; - private Index index; - private Index refIndex; - private boolean indexOwner; - private boolean refIndexOwner; - private String deleteSQL, updateSQL; - private boolean skipOwnTable; - - public ConstraintReferential(Schema schema, int id, String name, Table table) { - super(schema, id, name, table); - } - - public String getConstraintType() { - return Constraint.REFERENTIAL; - } - - private void appendAction(StatementBuilder buff, int action) { - switch (action) { - case CASCADE: - buff.append("CASCADE"); - break; - case SET_DEFAULT: - buff.append("SET DEFAULT"); - break; - case SET_NULL: - buff.append("SET NULL"); - break; - default: - DbException.throwInternalError("action=" + action); - } - } - - /** - * Create the SQL statement of this object so a copy of the table can be made. - * - * @param forTable the table to create the object for - * @param quotedName the name of this object (quoted if necessary) - * @return the SQL statement - */ - public String getCreateSQLForCopy(Table forTable, String quotedName) { - return getCreateSQLForCopy(forTable, refTable, quotedName, true); - } - - /** - * Create the SQL statement of this object so a copy of the table can be made. - * - * @param forTable the table to create the object for - * @param forRefTable the referenced table - * @param quotedName the name of this object (quoted if necessary) - * @param internalIndex add the index name to the statement - * @return the SQL statement - */ - public String getCreateSQLForCopy(Table forTable, Table forRefTable, String quotedName, boolean internalIndex) { - StatementBuilder buff = new StatementBuilder("ALTER TABLE "); - String mainTable = forTable.getSQL(); - buff.append(mainTable).append(" ADD CONSTRAINT "); - if (forTable.isHidden()) { - buff.append("IF NOT EXISTS "); - } - buff.append(quotedName); - if (comment != null) { - buff.append(" COMMENT ").append(StringUtils.quoteStringSQL(comment)); - } - IndexColumn[] cols = columns; - IndexColumn[] refCols = refColumns; - buff.append(" FOREIGN KEY("); - for (IndexColumn c : cols) { - buff.appendExceptFirst(", "); - buff.append(c.getSQL()); - } - buff.append(')'); - if (internalIndex && indexOwner && forTable == this.table) { - buff.append(" INDEX ").append(index.getSQL()); - } - buff.append(" REFERENCES "); - String quotedRefTable; - if (this.table == this.refTable) { - // self-referencing constraints: need to use new table - quotedRefTable = forTable.getSQL(); - } else { - quotedRefTable = forRefTable.getSQL(); - } - buff.append(quotedRefTable).append('('); - buff.resetCount(); - for (IndexColumn r : refCols) { - buff.appendExceptFirst(", "); - buff.append(r.getSQL()); - } - buff.append(')'); - if (internalIndex && refIndexOwner && forTable == this.table) { - buff.append(" INDEX ").append(refIndex.getSQL()); - } - if (deleteAction != RESTRICT) { - buff.append(" ON DELETE "); - appendAction(buff, deleteAction); - } - if (updateAction != RESTRICT) { - buff.append(" ON UPDATE "); - appendAction(buff, updateAction); - } - return buff.append(" NOCHECK").toString(); - } - - - /** - * Get a short description of the constraint. This includes the constraint - * name (if set), and the constraint expression. - * - * @return the description - */ - private String getShortDescription() { - StatementBuilder buff = new StatementBuilder(getName()); - buff.append(": ").append(table.getSQL()).append(" FOREIGN KEY("); - for (IndexColumn c : columns) { - buff.appendExceptFirst(", "); - buff.append(c.getSQL()); - } - buff.append(") REFERENCES ").append(refTable.getSQL()).append('('); - buff.resetCount(); - for (IndexColumn r : refColumns) { - buff.appendExceptFirst(", "); - buff.append(r.getSQL()); - } - return buff.append(')').toString(); - } - - public String getCreateSQLWithoutIndexes() { - return getCreateSQLForCopy(table, refTable, getSQL(), false); - } - - public String getCreateSQL() { - return getCreateSQLForCopy(table, getSQL()); - } - - public void setColumns(IndexColumn[] cols) { - columns = cols; - } - - public IndexColumn[] getColumns() { - return columns; - } - - public void setRefColumns(IndexColumn[] refCols) { - refColumns = refCols; - } - - public IndexColumn[] getRefColumns() { - return refColumns; - } - - public void setRefTable(Table refTable) { - this.refTable = refTable; - if (refTable.isTemporary()) { - setTemporary(true); - } - } - - /** - * Set the index to use for this constraint. - * - * @param index the index - * @param isOwner true if the index is generated by the system and belongs - * to this constraint - */ - public void setIndex(Index index, boolean isOwner) { - this.index = index; - this.indexOwner = isOwner; - } - - /** - * Set the index of the referenced table to use for this constraint. - * - * @param refIndex the index - * @param isRefOwner true if the index is generated by the system and - * belongs to this constraint - */ - public void setRefIndex(Index refIndex, boolean isRefOwner) { - this.refIndex = refIndex; - this.refIndexOwner = isRefOwner; - } - - public void removeChildrenAndResources(Session session) { - table.removeConstraint(this); - refTable.removeConstraint(this); - if (indexOwner) { - table.removeIndexOrTransferOwnership(session, index); - } - if (refIndexOwner) { - refTable.removeIndexOrTransferOwnership(session, refIndex); - } - database.removeMeta(session, getId()); - refTable = null; - index = null; - refIndex = null; - columns = null; - refColumns = null; - deleteSQL = null; - updateSQL = null; - table = null; - invalidate(); - } - - public void checkRow(Session session, Table t, Row oldRow, Row newRow) { - if (!database.getReferentialIntegrity()) { - return; - } - if (!table.getCheckForeignKeyConstraints() || !refTable.getCheckForeignKeyConstraints()) { - return; - } - if (t == table) { - if (!skipOwnTable) { - checkRowOwnTable(session, oldRow, newRow); - } - } - if (t == refTable) { - checkRowRefTable(session, oldRow, newRow); - } - } - - private void checkRowOwnTable(Session session, Row oldRow, Row newRow) { - if (newRow == null) { - return; - } - boolean constraintColumnsEqual = oldRow != null; - for (IndexColumn col : columns) { - int idx = col.column.getColumnId(); - Value v = newRow.getValue(idx); - if (v == ValueNull.INSTANCE) { - // return early if one of the columns is NULL - return; - } - if (constraintColumnsEqual) { - if (!database.areEqual(v, oldRow.getValue(idx))) { - constraintColumnsEqual = false; - } - } - } - if (constraintColumnsEqual) { - // return early if the key columns didn't change - return; - } - if (refTable == table) { - // special case self referencing constraints: - // check the inserted row first - boolean self = true; - for (int i = 0; i < columns.length; i++) { - int idx = columns[i].column.getColumnId(); - Value v = newRow.getValue(idx); - Column refCol = refColumns[i].column; - int refIdx = refCol.getColumnId(); - Value r = newRow.getValue(refIdx); - if (!database.areEqual(r, v)) { - self = false; - break; - } - } - if (self) { - return; - } - } - Row check = refTable.getTemplateRow(); - for (int i = 0; i < columns.length; i++) { - int idx = columns[i].column.getColumnId(); - Value v = newRow.getValue(idx); - Column refCol = refColumns[i].column; - int refIdx = refCol.getColumnId(); - check.setValue(refIdx, refCol.convert(v)); - } - if (!existsRow(session, refIndex, check, null)) { - throw DbException.get(ErrorCode.REFERENTIAL_INTEGRITY_VIOLATED_PARENT_MISSING_1, - getShortDescription()); - } - } - - private boolean existsRow(Session session, Index searchIndex, SearchRow check, Row excluding) { - Table searchTable = searchIndex.getTable(); - searchTable.lock(session, false, false); - Cursor cursor = searchIndex.find(session, check, check); - while (cursor.next()) { - SearchRow found; - found = cursor.getSearchRow(); - if (excluding != null && found.getKey() == excluding.getKey()) { - continue; - } - Column[] cols = searchIndex.getColumns(); - boolean allEqual = true; - for (int i = 0; i < columns.length && i < cols.length; i++) { - int idx = cols[i].getColumnId(); - Value c = check.getValue(idx); - Value f = found.getValue(idx); - if (searchTable.compareTypeSave(c, f) != 0) { - allEqual = false; - break; - } - } - if (allEqual) { - return true; - } - } - return false; - } - - private boolean isEqual(Row oldRow, Row newRow) { - return refIndex.compareRows(oldRow, newRow) == 0; - } - - private void checkRow(Session session, Row oldRow) { - SearchRow check = table.getTemplateSimpleRow(false); - for (int i = 0; i < columns.length; i++) { - Column refCol = refColumns[i].column; - int refIdx = refCol.getColumnId(); - Column col = columns[i].column; - Value v = col.convert(oldRow.getValue(refIdx)); - check.setValue(col.getColumnId(), v); - } - // exclude the row only for self-referencing constraints - Row excluding = (refTable == table) ? oldRow : null; - if (existsRow(session, index, check, excluding)) { - throw DbException.get(ErrorCode.REFERENTIAL_INTEGRITY_VIOLATED_CHILD_EXISTS_1, - getShortDescription()); - } - } - - private void checkRowRefTable(Session session, Row oldRow, Row newRow) { - if (oldRow == null) { - // this is an insert - return; - } - if (newRow != null && isEqual(oldRow, newRow)) { - // on an update, if both old and new are the same, don't do anything - return; - } - if (newRow == null) { - // this is a delete - if (deleteAction == RESTRICT) { - checkRow(session, oldRow); - } else { - int i = deleteAction == CASCADE ? 0 : columns.length; - Prepared deleteCommand = getDelete(session); - setWhere(deleteCommand, i, oldRow); - updateWithSkipCheck(deleteCommand); - } - } else { - // this is an update - if (updateAction == RESTRICT) { - checkRow(session, oldRow); - } else { - Prepared updateCommand = getUpdate(session); - if (updateAction == CASCADE) { - ArrayList params = updateCommand.getParameters(); - for (int i = 0; i < columns.length; i++) { - Parameter param = params.get(i); - Column refCol = refColumns[i].column; - param.setValue(newRow.getValue(refCol.getColumnId())); - } - } - setWhere(updateCommand, columns.length, oldRow); - updateWithSkipCheck(updateCommand); - } - } - } - - private void updateWithSkipCheck(Prepared prep) { - // TODO constraints: maybe delay the update or support delayed checks - // (until commit) - try { - // TODO multithreaded kernel: this works only if nobody else updates - // this or the ref table at the same time - skipOwnTable = true; - prep.update(); - } finally { - skipOwnTable = false; - } - } - - private void setWhere(Prepared command, int pos, Row row) { - for (int i = 0; i < refColumns.length; i++) { - int idx = refColumns[i].column.getColumnId(); - Value v = row.getValue(idx); - ArrayList params = command.getParameters(); - Parameter param = params.get(pos + i); - param.setValue(v); - } - } - - public int getDeleteAction() { - return deleteAction; - } - - /** - * Set the action to apply (restrict, cascade,...) on a delete. - * - * @param action the action - */ - public void setDeleteAction(int action) { - if (action == deleteAction && deleteSQL == null) { - return; - } - if (deleteAction != RESTRICT) { - throw DbException.get(ErrorCode.CONSTRAINT_ALREADY_EXISTS_1, "ON DELETE"); - } - this.deleteAction = action; - buildDeleteSQL(); - } - - private void buildDeleteSQL() { - if (deleteAction == RESTRICT) { - return; - } - StatementBuilder buff = new StatementBuilder(); - if (deleteAction == CASCADE) { - buff.append("DELETE FROM ").append(table.getSQL()); - } else { - appendUpdate(buff); - } - appendWhere(buff); - deleteSQL = buff.toString(); - } - - private Prepared getUpdate(Session session) { - return prepare(session, updateSQL, updateAction); - } - - private Prepared getDelete(Session session) { - return prepare(session, deleteSQL, deleteAction); - } - - public int getUpdateAction() { - return updateAction; - } - - /** - * Set the action to apply (restrict, cascade,...) on an update. - * - * @param action the action - */ - public void setUpdateAction(int action) { - if (action == updateAction && updateSQL == null) { - return; - } - if (updateAction != RESTRICT) { - throw DbException.get(ErrorCode.CONSTRAINT_ALREADY_EXISTS_1, "ON UPDATE"); - } - this.updateAction = action; - buildUpdateSQL(); - } - - private void buildUpdateSQL() { - if (updateAction == RESTRICT) { - return; - } - StatementBuilder buff = new StatementBuilder(); - appendUpdate(buff); - appendWhere(buff); - updateSQL = buff.toString(); - } - - public void rebuild() { - buildUpdateSQL(); - buildDeleteSQL(); - } - - private Prepared prepare(Session session, String sql, int action) { - Prepared command = session.prepare(sql); - if (action != CASCADE) { - ArrayList params = command.getParameters(); - for (int i = 0; i < columns.length; i++) { - Column column = columns[i].column; - Parameter param = params.get(i); - Value value; - if (action == SET_NULL) { - value = ValueNull.INSTANCE; - } else { - Expression expr = column.getDefaultExpression(); - if (expr == null) { - throw DbException.get(ErrorCode.NO_DEFAULT_SET_1, column.getName()); - } - value = expr.getValue(session); - } - param.setValue(value); - } - } - return command; - } - - private void appendUpdate(StatementBuilder buff) { - buff.append("UPDATE ").append(table.getSQL()).append(" SET "); - buff.resetCount(); - for (IndexColumn c : columns) { - buff.appendExceptFirst(" , "); - buff.append(Parser.quoteIdentifier(c.column.getName())).append("=?"); - } - } - - private void appendWhere(StatementBuilder buff) { - buff.append(" WHERE "); - buff.resetCount(); - for (IndexColumn c : columns) { - buff.appendExceptFirst(" AND "); - buff.append(Parser.quoteIdentifier(c.column.getName())).append("=?"); - } - } - - public Table getRefTable() { - return refTable; - } - - public boolean usesIndex(Index idx) { - return idx == index || idx == refIndex; - } - - public void setIndexOwner(Index index) { - if (this.index == index) { - indexOwner = true; - } else if (this.refIndex == index) { - refIndexOwner = true; - } else { - DbException.throwInternalError(); - } - } - - public boolean containsColumn(Column col) { - for (IndexColumn c : columns) { - if (c.column == col) { - return true; - } - } - for (IndexColumn c : refColumns) { - if (c.column == col) { - return true; - } - } - return false; - } - - public boolean isBefore() { - return false; - } - - public void checkExistingData(Session session) { - if (session.getDatabase().isStarting()) { - // don't check at startup - return; - } - StatementBuilder buff = new StatementBuilder("SELECT 1 FROM (SELECT "); - for (IndexColumn c : columns) { - buff.appendExceptFirst(", "); - buff.append(c.getSQL()); - } - buff.append(" FROM ").append(table.getSQL()).append(" WHERE "); - buff.resetCount(); - for (IndexColumn c : columns) { - buff.appendExceptFirst(" AND "); - buff.append(c.getSQL()).append(" IS NOT NULL "); - } - buff.append(" ORDER BY "); - buff.resetCount(); - for (IndexColumn c : columns) { - buff.appendExceptFirst(", "); - buff.append(c.getSQL()); - } - buff.append(") C WHERE NOT EXISTS(SELECT 1 FROM "). - append(refTable.getSQL()).append(" P WHERE "); - buff.resetCount(); - int i = 0; - for (IndexColumn c : columns) { - buff.appendExceptFirst(" AND "); - buff.append("C.").append(c.getSQL()).append('='). - append("P.").append(refColumns[i++].getSQL()); - } - buff.append(')'); - String sql = buff.toString(); - ResultInterface r = session.prepare(sql).query(1); - if (r.next()) { - throw DbException.get(ErrorCode.REFERENTIAL_INTEGRITY_VIOLATED_PARENT_MISSING_1, - getShortDescription()); - } - } - - public Index getUniqueIndex() { - return refIndex; - } - -} diff --git a/tools/h2/src/main/org/h2/constraint/ConstraintUnique.java b/tools/h2/src/main/org/h2/constraint/ConstraintUnique.java deleted file mode 100755 index 82c1298..0000000 --- a/tools/h2/src/main/org/h2/constraint/ConstraintUnique.java +++ /dev/null @@ -1,149 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.constraint; - -import org.h2.command.Parser; -import org.h2.engine.Session; -import org.h2.index.Index; -import org.h2.result.Row; -import org.h2.schema.Schema; -import org.h2.table.Column; -import org.h2.table.IndexColumn; -import org.h2.table.Table; -import org.h2.util.StatementBuilder; -import org.h2.util.StringUtils; - -/** - * A unique constraint. This object always backed by a unique index. - */ -public class ConstraintUnique extends Constraint { - - private Index index; - private boolean indexOwner; - private IndexColumn[] columns; - private boolean primaryKey; - - public ConstraintUnique(Schema schema, int id, String name, Table table, boolean primaryKey) { - super(schema, id, name, table); - this.primaryKey = primaryKey; - } - - public String getConstraintType() { - return primaryKey ? Constraint.PRIMARY_KEY : Constraint.UNIQUE; - } - - public String getCreateSQLForCopy(Table forTable, String quotedName) { - return getCreateSQLForCopy(forTable, quotedName, true); - } - - private String getCreateSQLForCopy(Table forTable, String quotedName, boolean internalIndex) { - StatementBuilder buff = new StatementBuilder("ALTER TABLE "); - buff.append(forTable.getSQL()).append(" ADD CONSTRAINT "); - if (forTable.isHidden()) { - buff.append("IF NOT EXISTS "); - } - buff.append(quotedName); - if (comment != null) { - buff.append(" COMMENT ").append(StringUtils.quoteStringSQL(comment)); - } - buff.append(' ').append(getTypeName()).append('('); - for (IndexColumn c : columns) { - buff.appendExceptFirst(", "); - buff.append(Parser.quoteIdentifier(c.column.getName())); - } - buff.append(')'); - if (internalIndex && indexOwner && forTable == this.table) { - buff.append(" INDEX ").append(index.getSQL()); - } - return buff.toString(); - } - - private String getTypeName() { - if (primaryKey) { - return "PRIMARY KEY"; - } - return "UNIQUE"; - } - - public String getCreateSQLWithoutIndexes() { - return getCreateSQLForCopy(table, getSQL(), false); - } - - public String getCreateSQL() { - return getCreateSQLForCopy(table, getSQL()); - } - - public void setColumns(IndexColumn[] columns) { - this.columns = columns; - } - - public IndexColumn[] getColumns() { - return columns; - } - - /** - * Set the index to use for this unique constraint. - * - * @param index the index - * @param isOwner true if the index is generated by the system and belongs - * to this constraint - */ - public void setIndex(Index index, boolean isOwner) { - this.index = index; - this.indexOwner = isOwner; - } - - public void removeChildrenAndResources(Session session) { - table.removeConstraint(this); - if (indexOwner) { - table.removeIndexOrTransferOwnership(session, index); - } - database.removeMeta(session, getId()); - index = null; - columns = null; - table = null; - invalidate(); - } - - public void checkRow(Session session, Table t, Row oldRow, Row newRow) { - // unique index check is enough - } - - public boolean usesIndex(Index idx) { - return idx == index; - } - - public void setIndexOwner(Index index) { - indexOwner = true; - } - - public boolean containsColumn(Column col) { - for (IndexColumn c : columns) { - if (c.column == col) { - return true; - } - } - return false; - } - - public boolean isBefore() { - return true; - } - - public void checkExistingData(Session session) { - // no need to check: when creating the unique index any problems are found - } - - public Index getUniqueIndex() { - return index; - } - - public void rebuild() { - // nothing to do - } - -} diff --git a/tools/h2/src/main/org/h2/constraint/package.html b/tools/h2/src/main/org/h2/constraint/package.html deleted file mode 100755 index b068c23..0000000 --- a/tools/h2/src/main/org/h2/constraint/package.html +++ /dev/null @@ -1,15 +0,0 @@ - - - - -Javadoc package documentation -

- -Database constraints such as check constraints, unique constraints, and referential constraints. - -

\ No newline at end of file diff --git a/tools/h2/src/main/org/h2/engine/Comment.java b/tools/h2/src/main/org/h2/engine/Comment.java deleted file mode 100755 index e5533b7..0000000 --- a/tools/h2/src/main/org/h2/engine/Comment.java +++ /dev/null @@ -1,110 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.engine; - -import org.h2.message.DbException; -import org.h2.message.Trace; -import org.h2.table.Table; -import org.h2.util.StringUtils; - -/** - * Represents a database object comment. - */ -public class Comment extends DbObjectBase { - - private final int objectType; - private final String objectName; - private String commentText; - - public Comment(Database database, int id, DbObject obj) { - initDbObjectBase(database, id, getKey(obj), Trace.DATABASE); - this.objectType = obj.getType(); - this.objectName = obj.getSQL(); - } - - public String getCreateSQLForCopy(Table table, String quotedName) { - throw DbException.throwInternalError(); - } - - private static String getTypeName(int type) { - switch(type) { - case DbObject.CONSTANT: - return "CONSTANT"; - case DbObject.CONSTRAINT: - return "CONSTRAINT"; - case DbObject.FUNCTION_ALIAS: - return "ALIAS"; - case DbObject.INDEX: - return "INDEX"; - case DbObject.ROLE: - return "ROLE"; - case DbObject.SCHEMA: - return "SCHEMA"; - case DbObject.SEQUENCE: - return "SEQUENCE"; - case DbObject.TABLE_OR_VIEW: - return "TABLE"; - case DbObject.TRIGGER: - return "TRIGGER"; - case DbObject.USER: - return "USER"; - case DbObject.USER_DATATYPE: - return "DOMAIN"; - default: - // not supported by parser, but required when trying to find a comment - return "type" + type; - } - } - - public String getDropSQL() { - return null; - } - - public String getCreateSQL() { - StringBuilder buff = new StringBuilder("COMMENT ON "); - buff.append(getTypeName(objectType)).append(' ').append(objectName).append(" IS "); - if (commentText == null) { - buff.append("NULL"); - } else { - buff.append(StringUtils.quoteStringSQL(commentText)); - } - return buff.toString(); - } - - public int getType() { - return DbObject.COMMENT; - } - - public void removeChildrenAndResources(Session session) { - database.removeMeta(session, getId()); - } - - public void checkRename() { - DbException.throwInternalError(); - } - - /** - * Get the comment key name for the given database object. This key name is - * used internally to associate the comment to the object. - * - * @param obj the object - * @return the key name - */ - public static String getKey(DbObject obj) { - return getTypeName(obj.getType()) + " " + obj.getSQL(); - } - - /** - * Set the comment text. - * - * @param comment the text - */ - public void setCommentText(String comment) { - this.commentText = comment; - } - -} diff --git a/tools/h2/src/main/org/h2/engine/ConnectionInfo.java b/tools/h2/src/main/org/h2/engine/ConnectionInfo.java deleted file mode 100755 index a72cb96..0000000 --- a/tools/h2/src/main/org/h2/engine/ConnectionInfo.java +++ /dev/null @@ -1,547 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.engine; - -import java.io.File; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.HashSet; -import java.util.Properties; -import org.h2.command.dml.SetTypes; -import org.h2.constant.ErrorCode; -import org.h2.constant.SysProperties; -import org.h2.message.DbException; -import org.h2.security.SHA256; -import org.h2.util.IOUtils; -import org.h2.util.New; -import org.h2.util.StringUtils; -import org.h2.util.Utils; - -/** - * Encapsulates the connection settings, including user name and password. - */ -public class ConnectionInfo implements Cloneable { - private static final HashSet KNOWN_SETTINGS = New.hashSet(); - private Properties prop = new Properties(); - private String originalURL; - private String url; - private String user; - private byte[] filePasswordHash; - private byte[] userPasswordHash; - - /** - * The database name - */ - private String name; - private boolean remote; - private boolean ssl; - private boolean persistent; - private boolean unnamed; - - /** - * Create a connection info object. - * - * @param name the database name (including tags) - */ - public ConnectionInfo(String name) { - this.name = name; - parseName(); - } - - /** - * Create a connection info object. - * - * @param u the database URL (must start with jdbc:h2:) - * @param info the connection properties - */ - public ConnectionInfo(String u, Properties info) { - this.originalURL = u; - if (!u.startsWith(Constants.START_URL)) { - throw DbException.getInvalidValueException(u, "url"); - } - this.url = u; - readProperties(info); - readSettingsFromURL(); - setUserName(removeProperty("USER", "")); - convertPasswords(); - name = url.substring(Constants.START_URL.length()); - parseName(); - } - - static { - ArrayList list = SetTypes.getTypes(); - HashSet set = KNOWN_SETTINGS; - set.addAll(list); - String[] connectionTime = { "ACCESS_MODE_DATA", "AUTOCOMMIT", "CIPHER", - "CREATE", "CACHE_TYPE", "DB_CLOSE_ON_EXIT", "FILE_LOCK", "IGNORE_UNKNOWN_SETTINGS", "IFEXISTS", - "INIT", "PASSWORD", "RECOVER", "USER", "AUTO_SERVER", - "AUTO_RECONNECT", "OPEN_NEW", "PAGE_SIZE" }; - for (String key : connectionTime) { - if (SysProperties.CHECK && set.contains(key)) { - DbException.throwInternalError(key); - } - set.add(key); - } - } - - private static boolean isKnownSetting(String s) { - return KNOWN_SETTINGS.contains(s); - } - - public Object clone() throws CloneNotSupportedException { - ConnectionInfo clone = (ConnectionInfo) super.clone(); - clone.prop = (Properties) prop.clone(); - clone.filePasswordHash = Utils.cloneByteArray(filePasswordHash); - clone.userPasswordHash = Utils.cloneByteArray(userPasswordHash); - return clone; - } - - private void parseName() { - if (".".equals(name)) { - name = "mem:"; - } - if (name.startsWith("tcp:")) { - remote = true; - name = name.substring("tcp:".length()); - } else if (name.startsWith("ssl:")) { - remote = true; - ssl = true; - name = name.substring("ssl:".length()); - } else if (name.startsWith("mem:")) { - persistent = false; - if ("mem:".equals(name)) { - unnamed = true; - } - } else if (name.startsWith("file:")) { - name = name.substring("file:".length()); - persistent = true; - } else { - persistent = true; - } - } - - /** - * Set the base directory of persistent databases, unless the database is in - * the user home folder (~). - * - * @param dir the new base directory - */ - public void setBaseDir(String dir) { - if (persistent) { - String fileSystemPrefix = ""; - int colonIndex = name.lastIndexOf(':'); - if (colonIndex > 1) { - // cut FileSystem prefixes, but not - // C: and D: (Microsoft Windows drive letters) - fileSystemPrefix = name.substring(0, colonIndex+1); - name = name.substring(colonIndex+1); - } - String testFileName; - if (name.startsWith("~")) { - testFileName = System.getProperty("user.home") + SysProperties.FILE_SEPARATOR + name.substring(1); - } else { - testFileName = dir + SysProperties.FILE_SEPARATOR + name; - } - - File testFile = new File(testFileName); - File baseDir = new File(dir); - if (!IOUtils.isInDir(testFile, baseDir)) { - throw DbException.get(ErrorCode.IO_EXCEPTION_1, testFile.getAbsolutePath() + " outside " + - baseDir.getAbsolutePath()); - } - if (name.startsWith("~")) { - name = fileSystemPrefix + name; - } else { - name = fileSystemPrefix + dir + SysProperties.FILE_SEPARATOR + name; - } - } - } - - /** - * Check if this is a remote connection. - * - * @return true if it is - */ - public boolean isRemote() { - return remote; - } - - /** - * Check if the referenced database is persistent. - * - * @return true if it is - */ - boolean isPersistent() { - return persistent; - } - - /** - * Check if the referenced database is an unnamed in-memory database. - * - * @return true if it is - */ - boolean isUnnamedInMemory() { - return unnamed; - } - - private void readProperties(Properties info) { - Object[] list = new Object[info.size()]; - info.keySet().toArray(list); - for (Object k : list) { - String key = StringUtils.toUpperEnglish(k.toString()); - if (prop.containsKey(key)) { - throw DbException.get(ErrorCode.DUPLICATE_PROPERTY_1, key); - } - if (isKnownSetting(key)) { - prop.put(key, info.get(k)); - } - } - } - - private void readSettingsFromURL() { - int idx = url.indexOf(';'); - if (idx >= 0) { - String settings = url.substring(idx + 1); - url = url.substring(0, idx); - String[] list = StringUtils.arraySplit(settings, ';', false); - for (String setting : list) { - int equal = setting.indexOf('='); - if (equal < 0) { - throw getFormatException(); - } - String value = setting.substring(equal + 1); - String key = setting.substring(0, equal); - key = StringUtils.toUpperEnglish(key); - if (!isKnownSetting(key)) { - throw DbException.get(ErrorCode.UNSUPPORTED_SETTING_1, key); - } - String old = prop.getProperty(key); - if (old != null && !old.equals(value)) { - throw DbException.get(ErrorCode.DUPLICATE_PROPERTY_1, key); - } - prop.setProperty(key, value); - } - } - } - - private char[] removePassword() { - Object p = prop.remove("PASSWORD"); - if (p == null) { - return new char[0]; - } else if (p instanceof char[]) { - return (char[]) p; - } else { - return p.toString().toCharArray(); - } - } - - /** - * Split the password property into file password and user password if - * necessary, and convert them to the internal hash format. - */ - public void convertPasswords() { - char[] password = removePassword(); - SHA256 sha = new SHA256(); - if (getProperty("CIPHER", null) != null) { - // split password into (filePassword+' '+userPassword) - int space = -1; - for (int i = 0; i < password.length; i++) { - if (password[i] == ' ') { - space = i; - break; - } - } - if (space < 0) { - throw DbException.get(ErrorCode.WRONG_PASSWORD_FORMAT); - } - char[] np = new char[password.length - space - 1]; - char[] filePassword = new char[space]; - System.arraycopy(password, space + 1, np, 0, np.length); - System.arraycopy(password, 0, filePassword, 0, space); - Arrays.fill(password, (char) 0); - password = np; - filePasswordHash = sha.getKeyPasswordHash("file", filePassword); - } - userPasswordHash = sha.getKeyPasswordHash(user, password); - } - - /** - * Get a boolean property if it is set and return the value. - * - * @param key the property name - * @param defaultValue the default value - * @return the value - */ - public boolean getProperty(String key, boolean defaultValue) { - String x = getProperty(key, null); - if (x == null) { - return defaultValue; - } - // support 0 / 1 (like the parser) - if (x.length() == 1 && Character.isDigit(x.charAt(0))) { - return Integer.parseInt(x) != 0; - } - return Boolean.valueOf(x).booleanValue(); - } - - /** - * Remove a boolean property if it is set and return the value. - * - * @param key the property name - * @param defaultValue the default value - * @return the value - */ - public boolean removeProperty(String key, boolean defaultValue) { - String x = removeProperty(key, null); - return x == null ? defaultValue : Boolean.valueOf(x).booleanValue(); - } - - /** - * Remove a String property if it is set and return the value. - * - * @param key the property name - * @param defaultValue the default value - * @return the value - */ - String removeProperty(String key, String defaultValue) { - if (SysProperties.CHECK && !isKnownSetting(key)) { - DbException.throwInternalError(key); - } - Object x = prop.remove(key); - return x == null ? defaultValue : x.toString(); - } - - /** - * Get the unique and normalized database name (excluding settings). - * - * @return the database name - */ - String getName() { - if (persistent) { - String suffix = Constants.SUFFIX_PAGE_FILE; - String n = IOUtils.normalize(name + suffix); - String fileName = IOUtils.getFileName(n); - if (fileName.length() < suffix.length() + 1) { - throw DbException.get(ErrorCode.INVALID_DATABASE_NAME_1, name); - } - n = n.substring(0, n.length() - suffix.length()); - return IOUtils.normalize(n); - } - return name; - } - - /** - * Get the file password hash if it is set. - * - * @return the password hash or null - */ - byte[] getFilePasswordHash() { - return filePasswordHash; - } - - /** - * Get the name of the user. - * - * @return the user name - */ - public String getUserName() { - return user; - } - - /** - * Get the user password hash. - * - * @return the password hash - */ - byte[] getUserPasswordHash() { - return userPasswordHash; - } - - /** - * Get the property keys. - * - * @return the property keys - */ - String[] getKeys() { - String[] keys = new String[prop.size()]; - prop.keySet().toArray(keys); - return keys; - } - - /** - * Get the value of the given property. - * - * @param key the property key - * @return the value as a String - */ - String getProperty(String key) { - Object value = prop.get(key); - if (value == null || !(value instanceof String)) { - return null; - } - return value.toString(); - } - - /** - * Get the value of the given property. - * - * @param key the property key - * @param defaultValue the default value - * @return the value as a String - */ - public int getProperty(String key, int defaultValue) { - if (SysProperties.CHECK && !isKnownSetting(key)) { - DbException.throwInternalError(key); - } - String s = getProperty(key); - return s == null ? defaultValue : Integer.parseInt(s); - } - - /** - * Get the value of the given property. - * - * @param key the property key - * @param defaultValue the default value - * @return the value as a String - */ - public String getProperty(String key, String defaultValue) { - if (SysProperties.CHECK && !isKnownSetting(key)) { - DbException.throwInternalError(key); - } - String s = getProperty(key); - return s == null ? defaultValue : s; - } - - /** - * Get the value of the given property. - * - * @param setting the setting id - * @param defaultValue the default value - * @return the value as a String - */ - String getProperty(int setting, String defaultValue) { - String key = SetTypes.getTypeName(setting); - String s = getProperty(key); - return s == null ? defaultValue : s; - } - - /** - * Get the value of the given property. - * - * @param setting the setting id - * @param defaultValue the default value - * @return the value as an integer - */ - int getIntProperty(int setting, int defaultValue) { - String key = SetTypes.getTypeName(setting); - String s = getProperty(key, null); - try { - return s == null ? defaultValue : Integer.decode(s); - } catch (NumberFormatException e) { - return defaultValue; - } - } - - /** - * Check if this is a remote connection with SSL enabled. - * - * @return true if it is - */ - boolean isSSL() { - return ssl; - } - - /** - * Overwrite the user name. The user name is case-insensitive and stored in - * uppercase. English conversion is used. - * - * @param name the user name - */ - public void setUserName(String name) { - this.user = StringUtils.toUpperEnglish(name); - } - - /** - * Set the user password hash. - * - * @param hash the new hash value - */ - public void setUserPasswordHash(byte[] hash) { - this.userPasswordHash = hash; - } - - /** - * Set the file password hash. - * - * @param hash the new hash value - */ - public void setFilePasswordHash(byte[] hash) { - this.filePasswordHash = hash; - } - - /** - * Overwrite a property. - * - * @param key the property name - * @param value the value - */ - public void setProperty(String key, String value) { - // value is null if the value is an object - if (value != null) { - prop.setProperty(key, value); - } - } - - /** - * Get the database URL. - * - * @return the URL - */ - public String getURL() { - return url; - } - - /** - * Get the complete original database URL. - * - * @return the database URL - */ - public String getOriginalURL() { - return originalURL; - } - - /** - * Set the original database URL. - * - * @param url the database url - */ - public void setOriginalURL(String url) { - originalURL = url; - } - - /** - * Generate an URL format exception. - * - * @return the exception - */ - DbException getFormatException() { - String format = Constants.URL_FORMAT; - return DbException.get(ErrorCode.URL_FORMAT_ERROR_2, format, url); - } - - /** - * Switch to server mode, and set the server name and database key. - * - * @param serverKey the server name, '/', and the security key - */ - public void setServerKey(String serverKey) { - remote = true; - persistent = false; - this.name = serverKey; - } - -} diff --git a/tools/h2/src/main/org/h2/engine/Constants.java b/tools/h2/src/main/org/h2/engine/Constants.java deleted file mode 100755 index b8f5eb7..0000000 --- a/tools/h2/src/main/org/h2/engine/Constants.java +++ /dev/null @@ -1,373 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.engine; - -/** - * Constants are fixed values that are used in the whole database code. - */ -public class Constants { - - /** - * The build id is incremented for each public release. - */ - public static final int BUILD_ID = 137; - - /** - * The build id of the last stable release. - */ - public static final int BUILD_ID_STABLE = 136; - - /** - * If H2 is compiled to be included in a product, this should be set to - * a unique vendor id (to distinguish from official releases). - * Additionally, a version number should be set to distinguish releases. - * Example: ACME_SVN1651_BUILD3 - */ - public static final String BUILD_VENDOR_AND_VERSION = null; - - /** - * The build date is updated for each public release. - */ - public static final String BUILD_DATE = "2010-06-06"; - - /** - * The build date is updated for each public release. - */ - public static final String BUILD_DATE_STABLE = "2010-05-24"; - - /** - * The TCP protocol version number. This protocol is used by the TCP - * server and remote JDBC client. - */ - public static final int TCP_PROTOCOL_VERSION = 6; - - /** - * The major version of this database. - */ - public static final int VERSION_MAJOR = 1; - - /** - * The minor version of this database. - */ - public static final int VERSION_MINOR = 2; - - /** - * Constant meaning both numbers and text is allowed in SQL statements. - */ - public static final int ALLOW_LITERALS_ALL = 2; - - /** - * Constant meaning no literals are allowed in SQL statements. - */ - public static final int ALLOW_LITERALS_NONE = 0; - - /** - * Constant meaning only numbers are allowed in SQL statements (but no - * texts). - */ - public static final int ALLOW_LITERALS_NUMBERS = 1; - - /** - * The minimum number of entries to keep in the cache. - */ - public static final int CACHE_MIN_RECORDS = 16; - - /** - * The value of the cluster setting if clustering is disabled. - */ - public static final String CLUSTERING_DISABLED = "''"; - - /** - * The database URL used when calling a function if only the column list - * should be returned. - */ - public static final String CONN_URL_COLUMNLIST = "jdbc:columnlist:connection"; - - /** - * The database URL used when calling a function if the data should be - * returned. - */ - public static final String CONN_URL_INTERNAL = "jdbc:default:connection"; - - /** - * The cost is calculated on rowcount + this offset, - * to avoid using the wrong or no index if the table - * contains no rows _currently_ (when preparing the statement) - */ - public static final int COST_ROW_OFFSET = 1000; - - /** - * The number of milliseconds after which to check for a deadlock if locking - * is not successful. - */ - public static final int DEADLOCK_CHECK = 100; - - /** - * The default port number of the HTTP server (for the H2 Console). - * This value is also in the documentation and in the Server javadoc. - */ - public static final int DEFAULT_HTTP_PORT = 8082; - - /** - * The default value for the maximum transaction log size. - */ - public static final long DEFAULT_MAX_LOG_SIZE = 2 * 1024 * 1024; - - /** - * The default maximum length on an in-memory LOB object. - * Larger objects will be written to a temporary file. - */ - public static final int DEFAULT_MAX_LENGTH_CLIENTSIDE_LOB = 65536; - - /** - * The default maximum number of rows to be kept in memory in a result set. - */ - public static final int DEFAULT_MAX_MEMORY_ROWS = 10000; - - /** - * The default port of the TCP server. - * This port is also used in the documentation and in the Server javadoc. - */ - public static final int DEFAULT_TCP_PORT = 9092; - - /** - * The default delay in milliseconds before the transaction log is written. - */ - public static final int DEFAULT_WRITE_DELAY = 500; - - /** - * The password is hashed this many times - * to slow down dictionary attacks. - */ - public static final int ENCRYPTION_KEY_HASH_ITERATIONS = 1024; - - /** - * The block of a file. It is also the encryption block size. - */ - public static final int FILE_BLOCK_SIZE = 16; - - /** - * For testing, the lock timeout is smaller than for interactive use cases. - * This value could be increased to about 5 or 10 seconds. - */ - public static final int INITIAL_LOCK_TIMEOUT = 2000; - - /** - * The block size for I/O operations. - */ - public static final int IO_BUFFER_SIZE = 4 * 1024; - - /** - * The block size used to compress data in the LZFOutputStream. - */ - public static final int IO_BUFFER_SIZE_COMPRESS = 128 * 1024; - - /** - * The lock mode that means no locking is used at all. - */ - public static final int LOCK_MODE_OFF = 0; - - /** - * The lock mode that means read locks are acquired, but they are released - * immediately after the statement is executed. - */ - public static final int LOCK_MODE_READ_COMMITTED = 3; - - /** - * The lock mode that means table level locking is used for reads and - * writes. - */ - public static final int LOCK_MODE_TABLE = 1; - - /** - * The lock mode that means table level locking is used for reads and - * writes. If a table is locked, System.gc is called to close forgotten - * connections. - */ - public static final int LOCK_MODE_TABLE_GC = 2; - - /** - * The number of milliseconds to wait between checking the .lock.db file - * still exists once a database is locked. - */ - public static final int LOCK_SLEEP = 1000; - - /** - * The highest possible parameter index. - */ - public static final int MAX_PARAMETER_INDEX = 100000; - - /** - * The number of bytes in random salt that is used to hash passwords. - */ - public static final int SALT_LEN = 8; - - /** - * The database URL prefix of this database. - */ - public static final String START_URL = "jdbc:h2:"; - - /** - * The name prefix used for indexes that are not explicitly named. - */ - public static final String PREFIX_INDEX = "INDEX_"; - - /** - * The name prefix used for primary key constraints that are not explicitly - * named. - */ - public static final String PREFIX_PRIMARY_KEY = "PRIMARY_KEY_"; - - /** - * Every user belongs to this role. - */ - public static final String PUBLIC_ROLE_NAME = "PUBLIC"; - - /** - * The name of the default schema. - */ - public static final String SCHEMA_MAIN = "PUBLIC"; - - /** - * The default selectivity (used if the selectivity is not calculated). - */ - public static final int SELECTIVITY_DEFAULT = 50; - - /** - * The number of distinct values to keep in memory when running ANALYZE. - */ - public static final int SELECTIVITY_DISTINCT_COUNT = 10000; - - /** - * The name of the server properties file. - */ - public static final String SERVER_PROPERTIES_FILE = ".h2.server.properties"; - - /** - * Queries that take longer than this number of milliseconds are written to - * the trace file with the level info. - */ - public static final long SLOW_QUERY_LIMIT_MS = 100; - - /** - * The file name suffix of page files. - */ - public static final String SUFFIX_PAGE_FILE = ".h2.db"; - - /** - * The file name suffix of all database files. - */ - public static final String SUFFIX_DB_FILE = ".db"; - - /** - * The file name suffix of file lock files that are used to make sure a - * database is open by only one process at any time. - */ - public static final String SUFFIX_LOCK_FILE = ".lock.db"; - - /** - * The file name suffix of large object files. - */ - public static final String SUFFIX_LOB_FILE = ".lob.db"; - - /** - * The suffix of the directory name used if LOB objects are stored in a - * directory. - */ - public static final String SUFFIX_LOBS_DIRECTORY = ".lobs.db"; - - /** - * The file name suffix of temporary files. - */ - public static final String SUFFIX_TEMP_FILE = ".temp.db"; - - /** - * The file name suffix of trace files. - */ - public static final String SUFFIX_TRACE_FILE = ".trace.db"; - - /** - * The delay that is to be used if throttle has been enabled. - */ - public static final int THROTTLE_DELAY = 50; - - /** - * The maximum size of an undo log block. - */ - public static final int UNDO_BLOCK_SIZE = 1024 * 1024; - - /** - * The database URL format in simplified Backus-Naur form. - */ - public static final String URL_FORMAT = START_URL + - "{ {.|mem:}[name] | [file:]fileName | {tcp|ssl}:[//]server[:port][,server2[:port]]/name }[;key=value...]"; - - /** - * Name of the character encoding format. - */ - public static final String UTF8 = "UTF8"; - - /** - * The maximum time in milliseconds to keep the cost of a view. - * 10000 means 10 seconds. - */ - public static final int VIEW_COST_CACHE_MAX_AGE = 10000; - - /** - * The name of the index cache that is used for temporary view (subqueries - * used as tables). - */ - public static final int VIEW_INDEX_CACHE_SIZE = 64; - - /** - * Whether searching in Blob values should be supported. - */ - public static final boolean BLOB_SEARCH = false; - - /** - * The package name of user defined classes. - */ - public static final String USER_PACKAGE = "org.h2.dynamic"; - - private Constants() { - // utility class - } - - /** - * Get the version of this product, consisting of major version, minor version, - * and build id. - * - * @return the version number - */ - public static String getVersion() { - String version = VERSION_MAJOR + "." + VERSION_MINOR + "." + BUILD_ID; - if (BUILD_VENDOR_AND_VERSION != null) { - version += "_" + BUILD_VENDOR_AND_VERSION; - } - return version; - } - - /** - * Get the last stable version name. - * - * @return the version number - */ - public static Object getVersionStable() { - return "1.2." + BUILD_ID_STABLE; - } - - /** - * Get the complete version number of this database, consisting of - * the major version, the minor version, the build id, and the build date. - * - * @return the complete version - */ - public static String getFullVersion() { - return getVersion() + " (" + BUILD_DATE + ")"; - } - -} diff --git a/tools/h2/src/main/org/h2/engine/Database.java b/tools/h2/src/main/org/h2/engine/Database.java deleted file mode 100755 index e01417f..0000000 --- a/tools/h2/src/main/org/h2/engine/Database.java +++ /dev/null @@ -1,2262 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.engine; - -import java.io.IOException; -import java.sql.Connection; -import java.sql.SQLException; -import java.util.ArrayList; -import java.util.BitSet; -import java.util.Collections; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Properties; -import java.util.Set; -import java.util.StringTokenizer; -import org.h2.api.DatabaseEventListener; -import org.h2.command.ddl.CreateTableData; -import org.h2.command.dml.SetTypes; -import org.h2.constant.ErrorCode; -import org.h2.constant.SysProperties; -import org.h2.constraint.Constraint; -import org.h2.index.Cursor; -import org.h2.index.Index; -import org.h2.index.IndexType; -import org.h2.jdbc.JdbcConnection; -import org.h2.message.DbException; -import org.h2.message.Trace; -import org.h2.message.TraceSystem; -import org.h2.result.Row; -import org.h2.result.SearchRow; -import org.h2.schema.Schema; -import org.h2.schema.SchemaObject; -import org.h2.schema.Sequence; -import org.h2.schema.TriggerObject; -import org.h2.store.DataHandler; -import org.h2.store.FileLock; -import org.h2.store.FileStore; -import org.h2.store.InDoubtTransaction; -import org.h2.store.LobStorage; -import org.h2.store.PageStore; -import org.h2.store.WriterThread; -import org.h2.store.fs.FileSystemMemory; -import org.h2.table.Column; -import org.h2.table.IndexColumn; -import org.h2.table.MetaTable; -import org.h2.table.Table; -import org.h2.table.TableLinkConnection; -import org.h2.table.TableView; -import org.h2.tools.DeleteDbFiles; -import org.h2.tools.Server; -import org.h2.util.IOUtils; -import org.h2.util.MathUtils; -import org.h2.util.NetUtils; -import org.h2.util.New; -import org.h2.util.SmallLRUCache; -import org.h2.util.SourceCompiler; -import org.h2.util.StringUtils; -import org.h2.util.TempFileDeleter; -import org.h2.util.Utils; -import org.h2.value.CompareMode; -import org.h2.value.Value; -import org.h2.value.ValueInt; - -/** - * There is one database object per open database. - * - * The format of the meta data table is: - * id int, 0, objectType int, sql varchar - * - * @since 2004-04-15 22:49 - */ -public class Database implements DataHandler { - - private static int initialPowerOffCount; - - /** - * The default name of the system user. This name is only used as long as - * there is no administrator user registered. - */ - private static final String SYSTEM_USER_NAME = "DBA"; - - private final boolean persistent; - private final String databaseName; - private final String databaseShortName; - private final String databaseURL; - private final String cipher; - private final byte[] filePasswordHash; - - private final HashMap roles = New.hashMap(); - private final HashMap users = New.hashMap(); - private final HashMap settings = New.hashMap(); - private final HashMap schemas = New.hashMap(); - private final HashMap rights = New.hashMap(); - private final HashMap userDataTypes = New.hashMap(); - private final HashMap aggregates = New.hashMap(); - private final HashMap comments = New.hashMap(); - - private final Set userSessions = Collections.synchronizedSet(new HashSet()); - private Session exclusiveSession; - private final BitSet objectIds = new BitSet(); - private final Object lobSyncObject = new Object(); - - private Schema mainSchema; - private Schema infoSchema; - private int nextSessionId; - private int nextTempTableId; - private User systemUser; - private Session systemSession; - private Table meta; - private Index metaIdIndex; - private FileLock lock; - private WriterThread writer; - private boolean starting; - private TraceSystem traceSystem; - private int fileLockMethod; - private Role publicRole; - private long modificationDataId; - private long modificationMetaId; - private CompareMode compareMode; - private String cluster = Constants.CLUSTERING_DISABLED; - private boolean readOnly; - private boolean noDiskSpace; - private int writeDelay = Constants.DEFAULT_WRITE_DELAY; - private DatabaseEventListener eventListener; - private int maxMemoryRows = Constants.DEFAULT_MAX_MEMORY_ROWS; - private int maxMemoryUndo = SysProperties.DEFAULT_MAX_MEMORY_UNDO; - private int lockMode = SysProperties.DEFAULT_LOCK_MODE; - private int maxLengthInplaceLob; - private int allowLiterals = Constants.ALLOW_LITERALS_ALL; - - private int powerOffCount = initialPowerOffCount; - private int closeDelay; - private DatabaseCloser delayedCloser; - private volatile boolean closing; - private boolean ignoreCase; - private boolean deleteFilesOnDisconnect; - private String lobCompressionAlgorithm; - private boolean optimizeReuseResults = true; - private String cacheType; - private String accessModeData; - private boolean referentialIntegrity = true; - private boolean multiVersion; - private DatabaseCloser closeOnExit; - private Mode mode = Mode.getInstance(Mode.REGULAR); - private boolean multiThreaded; - private int maxOperationMemory = SysProperties.DEFAULT_MAX_OPERATION_MEMORY; - private SmallLRUCache lobFileListCache = SmallLRUCache.newInstance(128); - private boolean autoServerMode; - private Server server; - private HashMap linkConnections; - private TempFileDeleter tempFileDeleter = TempFileDeleter.getInstance(); - private PageStore pageStore; - private Properties reconnectLastLock; - private volatile long reconnectCheckNext; - private volatile boolean reconnectChangePending; - private volatile int checkpointAllowed; - private volatile boolean checkpointRunning; - private final Object reconnectSync = new Object(); - private int cacheSize; - private boolean compactFully; - private SourceCompiler compiler; - private volatile boolean metaTablesInitialized; - private boolean flushOnEachCommit; - private LobStorage lobStorage; - private int pageSize = SysProperties.PAGE_SIZE; - - public Database(ConnectionInfo ci, String cipher) { - String name = ci.getName(); - this.compareMode = CompareMode.getInstance(null, 0); - this.persistent = ci.isPersistent(); - this.filePasswordHash = ci.getFilePasswordHash(); - this.databaseName = name; - this.databaseShortName = parseDatabaseShortName(); - this.maxLengthInplaceLob = SysProperties.LOB_IN_DATABASE ? - SysProperties.DEFAULT_MAX_LENGTH_INPLACE_LOB2 : SysProperties.DEFAULT_MAX_LENGTH_INPLACE_LOB; - this.cipher = cipher; - String lockMethodName = ci.getProperty("FILE_LOCK", null); - this.accessModeData = ci.getProperty("ACCESS_MODE_DATA", "rw").toLowerCase(); - this.autoServerMode = ci.getProperty("AUTO_SERVER", false); - this.cacheSize = ci.getProperty("CACHE_SIZE", SysProperties.CACHE_SIZE_DEFAULT); - this.pageSize = ci.getProperty("PAGE_SIZE", SysProperties.PAGE_SIZE); - if ("r".equals(accessModeData)) { - readOnly = true; - } - this.fileLockMethod = FileLock.getFileLockMethod(lockMethodName); - this.databaseURL = ci.getURL(); - String listener = ci.removeProperty("DATABASE_EVENT_LISTENER", null); - if (listener != null) { - listener = StringUtils.trim(listener, true, true, "'"); - setEventListenerClass(listener); - } - this.multiVersion = ci.getProperty("MVCC", false); - boolean closeAtVmShutdown = ci.getProperty("DB_CLOSE_ON_EXIT", true); - int traceLevelFile = ci.getIntProperty(SetTypes.TRACE_LEVEL_FILE, TraceSystem.DEFAULT_TRACE_LEVEL_FILE); - int traceLevelSystemOut = ci.getIntProperty(SetTypes.TRACE_LEVEL_SYSTEM_OUT, - TraceSystem.DEFAULT_TRACE_LEVEL_SYSTEM_OUT); - this.cacheType = StringUtils.toUpperEnglish(ci.removeProperty("CACHE_TYPE", SysProperties.CACHE_TYPE_DEFAULT)); - openDatabase(traceLevelFile, traceLevelSystemOut, closeAtVmShutdown); - } - - private void openDatabase(int traceLevelFile, int traceLevelSystemOut, boolean closeAtVmShutdown) { - try { - open(traceLevelFile, traceLevelSystemOut); - if (closeAtVmShutdown) { - try { - closeOnExit = new DatabaseCloser(this, 0, true); - Runtime.getRuntime().addShutdownHook(closeOnExit); - } catch (IllegalStateException e) { - // shutdown in progress - just don't register the handler - // (maybe an application wants to write something into a - // database at shutdown time) - } catch (SecurityException e) { - // applets may not do that - ignore - // Google App Engine doesn't allow - // to instantiate classes that extend Thread - } - } - } catch (Throwable e) { - if (e instanceof OutOfMemoryError) { - e.fillInStackTrace(); - } - if (traceSystem != null) { - if (e instanceof SQLException) { - SQLException e2 = (SQLException) e; - if (e2.getErrorCode() != ErrorCode.DATABASE_ALREADY_OPEN_1) { - // only write if the database is not already in use - traceSystem.getTrace(Trace.DATABASE).error("opening " + databaseName, e); - } - } - traceSystem.close(); - } - closeOpenFilesAndUnlock(false); - throw DbException.convert(e); - } - } - - public static void setInitialPowerOffCount(int count) { - initialPowerOffCount = count; - } - - public void setPowerOffCount(int count) { - if (powerOffCount == -1) { - return; - } - powerOffCount = count; - } - - /** - * Check if two values are equal with the current comparison mode. - * - * @param a the first value - * @param b the second value - * @return true if both objects are equal - */ - public boolean areEqual(Value a, Value b) { - // can not use equals because ValueDecimal 0.0 is not equal to 0.00. - return a.compareTo(b, compareMode) == 0; - } - - /** - * Compare two values with the current comparison mode. The values may not - * be of the same type. - * - * @param a the first value - * @param b the second value - * @return 0 if both values are equal, -1 if the first value is smaller, and - * 1 otherwise - */ - public int compare(Value a, Value b) { - return a.compareTo(b, compareMode); - } - - /** - * Compare two values with the current comparison mode. The values must be - * of the same type. - * - * @param a the first value - * @param b the second value - * @return 0 if both values are equal, -1 if the first value is smaller, and - * 1 otherwise - */ - public int compareTypeSave(Value a, Value b) { - return a.compareTypeSave(b, compareMode); - } - - public long getModificationDataId() { - return modificationDataId; - } - - /** - * Set or reset the pending change flag in the .lock.db file. - * - * @param pending the new value of the flag - * @return true if the call was successful, - * false if another connection was faster - */ - synchronized boolean reconnectModified(boolean pending) { - if (readOnly || lock == null || fileLockMethod != FileLock.LOCK_SERIALIZED) { - return true; - } - try { - if (pending == reconnectChangePending) { - long now = System.currentTimeMillis(); - if (now > reconnectCheckNext) { - if (pending) { - String pos = pageStore == null ? null : "" + pageStore.getWriteCountTotal(); - lock.setProperty("logPos", pos); - lock.save(); - } - reconnectCheckNext = now + SysProperties.RECONNECT_CHECK_DELAY; - } - return true; - } - Properties old = lock.load(); - if (pending) { - if (old.getProperty("changePending") != null) { - return false; - } - getTrace().debug("wait before writing"); - Thread.sleep((int) (SysProperties.RECONNECT_CHECK_DELAY * 1.1)); - Properties now = lock.load(); - if (!now.equals(old)) { - // somebody else was faster - return false; - } - } - String pos = pageStore == null ? null : "" + pageStore.getWriteCountTotal(); - lock.setProperty("logPos", pos); - if (pending) { - lock.setProperty("changePending", "true-" + Math.random()); - } else { - lock.setProperty("changePending", null); - } - // ensure that the writer thread will - // not reset the flag before we are done - reconnectCheckNext = System.currentTimeMillis() + 2 * SysProperties.RECONNECT_CHECK_DELAY; - old = lock.save(); - if (pending) { - getTrace().debug("wait before writing again"); - Thread.sleep((int) (SysProperties.RECONNECT_CHECK_DELAY * 1.1)); - Properties now = lock.load(); - if (!now.equals(old)) { - // somebody else was faster - return false; - } - } else { - Thread.sleep(1); - } - reconnectLastLock = old; - reconnectChangePending = pending; - reconnectCheckNext = System.currentTimeMillis() + SysProperties.RECONNECT_CHECK_DELAY; - return true; - } catch (Exception e) { - getTrace().error("pending:"+ pending, e); - return false; - } - } - - public long getNextModificationDataId() { - return ++modificationDataId; - } - - public long getModificationMetaId() { - return modificationMetaId; - } - - public long getNextModificationMetaId() { - // if the meta data has been modified, the data is modified as well - // (because MetaTable returns modificationDataId) - modificationDataId++; - return modificationMetaId++; - } - - public int getPowerOffCount() { - return powerOffCount; - } - - public void checkPowerOff() { - if (powerOffCount == 0) { - return; - } - if (powerOffCount > 1) { - powerOffCount--; - return; - } - if (powerOffCount != -1) { - try { - powerOffCount = -1; - stopWriter(); - if (pageStore != null) { - try { - pageStore.close(); - } catch (DbException e) { - // ignore - } - pageStore = null; - } - if (lock != null) { - stopServer(); - if (fileLockMethod != FileLock.LOCK_SERIALIZED) { - // allow testing shutdown - lock.unlock(); - } - lock = null; - } - if (traceSystem != null) { - traceSystem.close(); - } - } catch (DbException e) { - TraceSystem.traceThrowable(e); - } - } - Engine.getInstance().close(databaseName); - throw DbException.get(ErrorCode.DATABASE_IS_CLOSED); - } - - /** - * Check if a database with the given name exists. - * - * @param name the name of the database (including path) - * @return true if one exists - */ - public static boolean exists(String name) { - return IOUtils.exists(name + Constants.SUFFIX_PAGE_FILE); - } - - /** - * Get the trace object for the given module. - * - * @param module the module name - * @return the trace object - */ - public Trace getTrace(String module) { - return traceSystem.getTrace(module); - } - - public FileStore openFile(String name, String openMode, boolean mustExist) { - if (mustExist && !IOUtils.exists(name)) { - throw DbException.get(ErrorCode.FILE_NOT_FOUND_1, name); - } - FileStore store = FileStore.open(this, name, openMode, cipher, filePasswordHash); - try { - store.init(); - } catch (DbException e) { - store.closeSilently(); - throw e; - } - return store; - } - - /** - * Check if the file password hash is correct. - * - * @param testCipher the cipher algorithm - * @param testHash the hash code - * @return true if the cipher algorithm and the password match - */ - public boolean validateFilePasswordHash(String testCipher, byte[] testHash) { - if (!StringUtils.equals(testCipher, this.cipher)) { - return false; - } - return Utils.compareSecure(testHash, filePasswordHash); - } - - private String parseDatabaseShortName() { - String n = databaseName; - if (n.endsWith(":")) { - n = null; - } - if (n != null) { - StringTokenizer tokenizer = new StringTokenizer(n, "/\\:,;"); - while (tokenizer.hasMoreTokens()) { - n = tokenizer.nextToken(); - } - } - if (n == null || n.length() == 0) { - n = "UNNAMED"; - } - return StringUtils.toUpperEnglish(n); - } - - private synchronized void open(int traceLevelFile, int traceLevelSystemOut) { - if (persistent) { - String dataFileName = databaseName + ".data.db"; - boolean existsData = IOUtils.exists(dataFileName); - String pageFileName = databaseName + Constants.SUFFIX_PAGE_FILE; - boolean existsPage = IOUtils.exists(pageFileName); - if (existsData && !existsPage) { - throw DbException.get(ErrorCode.FILE_VERSION_ERROR_1, - "Old database: " + dataFileName + " - please convert the database to a SQL script and re-create it."); - } - if (existsPage && IOUtils.isReadOnly(pageFileName)) { - // if it is already read-only because ACCESS_MODE_DATA=r - readOnly = readOnly | IOUtils.isReadOnly(pageFileName); - } - if (readOnly) { - traceSystem = new TraceSystem(null); - } else { - traceSystem = new TraceSystem(databaseName + Constants.SUFFIX_TRACE_FILE); - } - traceSystem.setLevelFile(traceLevelFile); - traceSystem.setLevelSystemOut(traceLevelSystemOut); - traceSystem.getTrace(Trace.DATABASE) - .info("opening " + databaseName + " (build " + Constants.BUILD_ID + ")"); - if (autoServerMode) { - if (readOnly || fileLockMethod == FileLock.LOCK_NO || fileLockMethod == FileLock.LOCK_SERIALIZED) { - throw DbException.getUnsupportedException("autoServerMode && (readOnly || fileLockMethod == NO" + - " || fileLockMethod == SERIALIZED)"); - } - } - String lockFileName = databaseName + Constants.SUFFIX_LOCK_FILE; - if (readOnly) { - if (IOUtils.exists(lockFileName)) { - throw DbException.get(ErrorCode.DATABASE_ALREADY_OPEN_1, "Lock file exists: " + lockFileName); - } - } - if (!readOnly && fileLockMethod != FileLock.LOCK_NO) { - lock = new FileLock(traceSystem, lockFileName, Constants.LOCK_SLEEP); - lock.lock(fileLockMethod); - if (autoServerMode) { - startServer(lock.getUniqueId()); - } - } - while (isReconnectNeeded() && !beforeWriting()) { - // wait until others stopped writing and - // until we can write (file are not open - no need to re-connect) - } - deleteOldTempFiles(); - starting = true; - getPageStore(); - starting = false; - reserveLobFileObjectIds(); - writer = WriterThread.create(this, writeDelay); - } else { - traceSystem = new TraceSystem(null); - } - systemUser = new User(this, 0, SYSTEM_USER_NAME, true); - mainSchema = new Schema(this, 0, Constants.SCHEMA_MAIN, systemUser, true); - infoSchema = new Schema(this, -1, "INFORMATION_SCHEMA", systemUser, true); - schemas.put(mainSchema.getName(), mainSchema); - schemas.put(infoSchema.getName(), infoSchema); - publicRole = new Role(this, 0, Constants.PUBLIC_ROLE_NAME, true); - roles.put(Constants.PUBLIC_ROLE_NAME, publicRole); - systemUser.setAdmin(true); - systemSession = new Session(this, systemUser, ++nextSessionId); - CreateTableData data = new CreateTableData(); - ArrayList cols = data.columns; - Column columnId = new Column("ID", Value.INT); - columnId.setNullable(false); - cols.add(columnId); - cols.add(new Column("HEAD", Value.INT)); - cols.add(new Column("TYPE", Value.INT)); - cols.add(new Column("SQL", Value.STRING)); - boolean create = true; - if (pageStore != null) { - create = pageStore.isNew(); - } - data.tableName = "SYS"; - data.id = 0; - data.temporary = false; - data.persistData = persistent; - data.persistIndexes = persistent; - data.create = create; - data.isHidden = true; - data.session = systemSession; - meta = mainSchema.createTable(data); - IndexColumn[] pkCols = IndexColumn.wrap(new Column[] { columnId }); - metaIdIndex = meta.addIndex(systemSession, "SYS_ID", 0, pkCols, IndexType.createPrimaryKey( - false, false), true, null); - objectIds.set(0); - starting = true; - Cursor cursor = metaIdIndex.find(systemSession, null, null); - // first, create all function aliases and sequences because - // they might be used in create table / view / constraints and so on - ArrayList records = New.arrayList(); - while (cursor.next()) { - MetaRecord rec = new MetaRecord(cursor.get()); - objectIds.set(rec.getId()); - records.add(rec); - } - Collections.sort(records); - for (MetaRecord rec : records) { - rec.execute(this, systemSession, eventListener); - } - // try to recompile the views that are invalid - recompileInvalidViews(systemSession); - starting = false; - addDefaultSetting(systemSession, SetTypes.DEFAULT_LOCK_TIMEOUT, null, Constants.INITIAL_LOCK_TIMEOUT); - addDefaultSetting(systemSession, SetTypes.DEFAULT_TABLE_TYPE, null, Table.TYPE_CACHED); - addDefaultSetting(systemSession, SetTypes.CACHE_SIZE, null, SysProperties.CACHE_SIZE_DEFAULT); - addDefaultSetting(systemSession, SetTypes.CLUSTER, Constants.CLUSTERING_DISABLED, 0); - addDefaultSetting(systemSession, SetTypes.WRITE_DELAY, null, Constants.DEFAULT_WRITE_DELAY); - addDefaultSetting(systemSession, SetTypes.CREATE_BUILD, null, Constants.BUILD_ID); - if (SysProperties.LOB_IN_DATABASE) { - getLobStorage().init(); - } - systemSession.commit(true); - traceSystem.getTrace(Trace.DATABASE).info("opened " + databaseName); - afterWriting(); - } - - private void startServer(String key) { - try { - server = Server.createTcpServer( - "-tcpPort", "0", - "-tcpAllowOthers", - "-tcpDaemon", - "-key", key, databaseName); - server.start(); - } catch (SQLException e) { - throw DbException.convert(e); - } - String address = NetUtils.getLocalAddress() + ":" + server.getPort(); - lock.setProperty("server", address); - lock.save(); - } - - private void stopServer() { - if (server != null) { - Server s = server; - // avoid calling stop recursively - // because stopping the server will - // try to close the database as well - server = null; - s.stop(); - } - } - - private void recompileInvalidViews(Session session) { - boolean recompileSuccessful; - do { - recompileSuccessful = false; - for (Table obj : getAllTablesAndViews(false)) { - if (obj instanceof TableView) { - TableView view = (TableView) obj; - if (view.isInvalid()) { - try { - view.recompile(session); - } catch (DbException e) { - // ignore - } - if (!view.isInvalid()) { - recompileSuccessful = true; - } - } - } - } - } while (recompileSuccessful); - // when opening a database, views are initialized before indexes, - // so they may not have the optimal plan yet - // this is not a problem, it is just nice to see the newest plan - for (Table obj : getAllTablesAndViews(false)) { - if (obj instanceof TableView) { - TableView view = (TableView) obj; - if (!view.isInvalid()) { - try { - view.recompile(systemSession); - } catch (DbException e) { - // ignore - } - } - } - } - } - - private void addDefaultSetting(Session session, int type, String stringValue, int intValue) { - if (readOnly) { - return; - } - String name = SetTypes.getTypeName(type); - if (settings.get(name) == null) { - Setting setting = new Setting(this, allocateObjectId(), name); - if (stringValue == null) { - setting.setIntValue(intValue); - } else { - setting.setStringValue(stringValue); - } - addDatabaseObject(session, setting); - } - } - - private void initMetaTables() { - if (metaTablesInitialized) { - return; - } - synchronized (infoSchema) { - if (!metaTablesInitialized) { - for (int type = 0; type < MetaTable.getMetaTableTypeCount(); type++) { - MetaTable m = new MetaTable(infoSchema, -1 - type, type); - infoSchema.add(m); - } - metaTablesInitialized = true; - } - } - } - - private synchronized void addMeta(Session session, DbObject obj) { - int id = obj.getId(); - if (id > 0 && !starting && !obj.isTemporary()) { - Row r = meta.getTemplateRow(); - MetaRecord rec = new MetaRecord(obj); - rec.setRecord(r); - objectIds.set(id); - meta.lock(session, true, true); - meta.addRow(session, r); - if (isMultiVersion()) { - // TODO this should work without MVCC, but avoid risks at the moment - session.log(meta, UndoLogRecord.INSERT, r); - } - } - } - - /** - * Remove the given object from the meta data. - * - * @param session the session - * @param id the id of the object to remove - */ - public synchronized void removeMeta(Session session, int id) { - if (id > 0 && !starting) { - SearchRow r = meta.getTemplateSimpleRow(false); - r.setValue(0, ValueInt.get(id)); - boolean wasLocked = meta.isLockedExclusivelyBy(session); - meta.lock(session, true, true); - Cursor cursor = metaIdIndex.find(session, r, r); - if (cursor.next()) { - Row found = cursor.get(); - meta.removeRow(session, found); - if (isMultiVersion()) { - // TODO this should work without MVCC, but avoid risks at the - // moment - session.log(meta, UndoLogRecord.DELETE, found); - } - objectIds.clear(id); - if (SysProperties.CHECK) { - checkMetaFree(session, id); - } - } else if (!wasLocked) { - // must not keep the lock if it was not locked - // otherwise updating sequences may cause a deadlock - meta.unlock(session); - session.unlock(meta); - } - } - } - - @SuppressWarnings("unchecked") - private HashMap getMap(int type) { - HashMap result; - switch (type) { - case DbObject.USER: - result = users; - break; - case DbObject.SETTING: - result = settings; - break; - case DbObject.ROLE: - result = roles; - break; - case DbObject.RIGHT: - result = rights; - break; - case DbObject.SCHEMA: - result = schemas; - break; - case DbObject.USER_DATATYPE: - result = userDataTypes; - break; - case DbObject.COMMENT: - result = comments; - break; - case DbObject.AGGREGATE: - result = aggregates; - break; - default: - throw DbException.throwInternalError("type=" + type); - } - return (HashMap) result; - } - - /** - * Add a schema object to the database. - * - * @param session the session - * @param obj the object to add - */ - public synchronized void addSchemaObject(Session session, SchemaObject obj) { - int id = obj.getId(); - if (id > 0 && !starting) { - checkWritingAllowed(); - } - obj.getSchema().add(obj); - addMeta(session, obj); - } - - /** - * Add an object to the database. - * - * @param session the session - * @param obj the object to add - */ - public synchronized void addDatabaseObject(Session session, DbObject obj) { - int id = obj.getId(); - if (id > 0 && !starting) { - checkWritingAllowed(); - } - HashMap map = getMap(obj.getType()); - if (obj.getType() == DbObject.USER) { - User user = (User) obj; - if (user.isAdmin() && systemUser.getName().equals(SYSTEM_USER_NAME)) { - systemUser.rename(user.getName()); - } - } - String name = obj.getName(); - if (SysProperties.CHECK && map.get(name) != null) { - DbException.throwInternalError("object already exists"); - } - addMeta(session, obj); - map.put(name, obj); - } - - /** - * Get the user defined aggregate function if it exists, or null if not. - * - * @param name the name of the user defined aggregate function - * @return the aggregate function or null - */ - public UserAggregate findAggregate(String name) { - return aggregates.get(name); - } - - /** - * Get the comment for the given database object if one exists, or null if - * not. - * - * @param object the database object - * @return the comment or null - */ - public Comment findComment(DbObject object) { - if (object.getType() == DbObject.COMMENT) { - return null; - } - String key = Comment.getKey(object); - return comments.get(key); - } - - /** - * Get the role if it exists, or null if not. - * - * @param roleName the name of the role - * @return the role or null - */ - public Role findRole(String roleName) { - return roles.get(roleName); - } - - /** - * Get the schema if it exists, or null if not. - * - * @param schemaName the name of the schema - * @return the schema or null - */ - public Schema findSchema(String schemaName) { - Schema schema = schemas.get(schemaName); - if (schema == infoSchema) { - initMetaTables(); - } - return schema; - } - - /** - * Get the setting if it exists, or null if not. - * - * @param name the name of the setting - * @return the setting or null - */ - public Setting findSetting(String name) { - return settings.get(name); - } - - /** - * Get the user if it exists, or null if not. - * - * @param name the name of the user - * @return the user or null - */ - public User findUser(String name) { - return users.get(name); - } - - /** - * Get the user defined data type if it exists, or null if not. - * - * @param name the name of the user defined data type - * @return the user defined data type or null - */ - public UserDataType findUserDataType(String name) { - return userDataTypes.get(name); - } - - /** - * Get user with the given name. This method throws an exception if the user - * does not exist. - * - * @param name the user name - * @return the user - * @throws SQLException if the user does not exist - */ - public User getUser(String name) { - User user = findUser(name); - if (user == null) { - throw DbException.get(ErrorCode.USER_NOT_FOUND_1, name); - } - return user; - } - - /** - * Create a session for the given user. - * - * @param user the user - * @return the session - * @throws SQLException if the database is in exclusive mode - */ - public synchronized Session createSession(User user) { - if (exclusiveSession != null) { - throw DbException.get(ErrorCode.DATABASE_IS_IN_EXCLUSIVE_MODE); - } - Session session = new Session(this, user, ++nextSessionId); - userSessions.add(session); - traceSystem.getTrace(Trace.SESSION).info("connecting #" + session.getId() + " to " + databaseName); - if (delayedCloser != null) { - delayedCloser.reset(); - delayedCloser = null; - } - return session; - } - - /** - * Remove a session. This method is called after the user has disconnected. - * - * @param session the session - */ - public synchronized void removeSession(Session session) { - if (session != null) { - if (exclusiveSession == session) { - exclusiveSession = null; - } - userSessions.remove(session); - if (session != systemSession) { - traceSystem.getTrace(Trace.SESSION).info("disconnecting #" + session.getId()); - } - } - if (userSessions.size() == 0 && session != systemSession) { - if (closeDelay == 0) { - close(false); - } else if (closeDelay < 0) { - return; - } else { - delayedCloser = new DatabaseCloser(this, closeDelay * 1000, false); - delayedCloser.setName("H2 Close Delay " + getShortName()); - delayedCloser.setDaemon(true); - delayedCloser.start(); - } - } - if (session != systemSession && session != null) { - traceSystem.getTrace(Trace.SESSION).info("disconnected #" + session.getId()); - } - } - - private synchronized void closeAllSessionsException(Session except) { - Session[] all = new Session[userSessions.size()]; - userSessions.toArray(all); - for (Session s : all) { - if (s != except) { - try { - // must roll back, otherwise the session is removed and - // the transaction log that contains its uncommitted operations as well - s.rollback(); - s.close(); - } catch (DbException e) { - traceSystem.getTrace(Trace.SESSION).error("disconnecting #" + s.getId(), e); - } - } - } - } - - /** - * Close the database. - * - * @param fromShutdownHook true if this method is called from the shutdown - * hook - */ - synchronized void close(boolean fromShutdownHook) { - if (closing) { - return; - } - if (fileLockMethod == FileLock.LOCK_SERIALIZED && !reconnectChangePending) { - // another connection may have written something - don't write - try { - closeOpenFilesAndUnlock(false); - } catch (DbException e) { - // ignore - } - traceSystem.close(); - Engine.getInstance().close(databaseName); - return; - } - closing = true; - stopServer(); - if (userSessions.size() > 0) { - if (!fromShutdownHook) { - return; - } - traceSystem.getTrace(Trace.DATABASE).info("closing " + databaseName + " from shutdown hook"); - closeAllSessionsException(null); - } - traceSystem.getTrace(Trace.DATABASE).info("closing " + databaseName); - if (eventListener != null) { - // allow the event listener to connect to the database - closing = false; - DatabaseEventListener e = eventListener; - // set it to null, to make sure it's called only once - eventListener = null; - e.closingDatabase(); - if (userSessions.size() > 0) { - // if a connection was opened, we can't close the database - return; - } - closing = true; - } - try { - if (systemSession != null) { - if (powerOffCount != -1) { - for (Table table : getAllTablesAndViews(false)) { - if (table.isGlobalTemporary()) { - table.removeChildrenAndResources(systemSession); - } else { - table.close(systemSession); - } - } - for (SchemaObject obj : getAllSchemaObjects(DbObject.SEQUENCE)) { - Sequence sequence = (Sequence) obj; - sequence.close(); - } - } - for (SchemaObject obj : getAllSchemaObjects(DbObject.TRIGGER)) { - TriggerObject trigger = (TriggerObject) obj; - try { - trigger.close(); - } catch (SQLException e) { - traceSystem.getTrace(Trace.DATABASE).error("close", e); - } - } - if (powerOffCount != -1) { - meta.close(systemSession); - systemSession.commit(true); - } - } - } catch (DbException e) { - traceSystem.getTrace(Trace.DATABASE).error("close", e); - } - // remove all session variables - if (persistent) { - try { - getLobStorage(); - lobStorage.removeAllForTable(LobStorage.TABLE_ID_SESSION_VARIABLE); - } catch (DbException e) { - traceSystem.getTrace(Trace.DATABASE).error("close", e); - } - } - tempFileDeleter.deleteAll(); - try { - closeOpenFilesAndUnlock(true); - } catch (DbException e) { - traceSystem.getTrace(Trace.DATABASE).error("close", e); - } - traceSystem.getTrace(Trace.DATABASE).info("closed"); - traceSystem.close(); - if (closeOnExit != null) { - closeOnExit.reset(); - try { - Runtime.getRuntime().removeShutdownHook(closeOnExit); - } catch (IllegalStateException e) { - // ignore - } catch (SecurityException e) { - // applets may not do that - ignore - } - closeOnExit = null; - } - Engine.getInstance().close(databaseName); - if (deleteFilesOnDisconnect && persistent) { - deleteFilesOnDisconnect = false; - try { - String directory = IOUtils.getParent(databaseName); - String name = IOUtils.getFileName(databaseName); - DeleteDbFiles.execute(directory, name, true); - } catch (Exception e) { - // ignore (the trace is closed already) - } - } - } - - private void stopWriter() { - if (writer != null) { - writer.stopThread(); - writer = null; - } - } - - /** - * Close all open files and unlock the database. - * - * @param flush whether writing is allowed - */ - private synchronized void closeOpenFilesAndUnlock(boolean flush) { - stopWriter(); - if (pageStore != null) { - if (flush) { - try { - pageStore.checkpoint(); - if (!readOnly) { - pageStore.compact(compactFully); - } - } catch (DbException e) { - if (e.getErrorCode() != ErrorCode.DATABASE_IS_CLOSED) { - if (SysProperties.CHECK2) { - e.printStackTrace(); - } - } - traceSystem.getTrace(Trace.DATABASE).error("close", e); - } catch (Throwable t) { - if (SysProperties.CHECK2) { - t.printStackTrace(); - } - traceSystem.getTrace(Trace.DATABASE).error("close", t); - } - } - } - reconnectModified(false); - closeFiles(); - if (persistent && lock == null && fileLockMethod != FileLock.LOCK_NO) { - // everything already closed (maybe in checkPowerOff) - // don't delete temp files in this case because - // the database could be open now (even from within another process) - return; - } - if (persistent) { - deleteOldTempFiles(); - } - if (systemSession != null) { - systemSession.close(); - systemSession = null; - } - if (lock != null) { - if (fileLockMethod == FileLock.LOCK_SERIALIZED) { - // wait before deleting the .lock file, - // otherwise other connections can not detect that - try { - Thread.sleep((int) (SysProperties.RECONNECT_CHECK_DELAY * 1.1)); - } catch (InterruptedException e) { - traceSystem.getTrace(Trace.DATABASE).error("close", e); - } - } - lock.unlock(); - lock = null; - } - } - - private void closeFiles() { - try { - synchronized (this) { - if (pageStore != null) { - pageStore.close(); - pageStore = null; - } - } - } catch (DbException e) { - traceSystem.getTrace(Trace.DATABASE).error("close", e); - } - } - - private void checkMetaFree(Session session, int id) { - SearchRow r = meta.getTemplateSimpleRow(false); - r.setValue(0, ValueInt.get(id)); - Cursor cursor = metaIdIndex.find(session, r, r); - if (cursor.next()) { - DbException.throwInternalError(); - } - } - - /** - * Allocate a new object id. - * - * @return the id - */ - public synchronized int allocateObjectId() { - int i = objectIds.nextClearBit(0); - objectIds.set(i); - return i; - } - - public ArrayList getAllAggregates() { - return New.arrayList(aggregates.values()); - } - - public ArrayList getAllComments() { - return New.arrayList(comments.values()); - } - - public int getAllowLiterals() { - if (starting) { - return Constants.ALLOW_LITERALS_ALL; - } - return allowLiterals; - } - - public ArrayList getAllRights() { - return New.arrayList(rights.values()); - } - - public ArrayList getAllRoles() { - return New.arrayList(roles.values()); - } - - /** - * Get all schema objects of the given type. - * - * @param type the object type - * @return all objects of that type - */ - public ArrayList getAllSchemaObjects(int type) { - if (type == DbObject.TABLE_OR_VIEW) { - initMetaTables(); - } - ArrayList list = New.arrayList(); - for (Schema schema : schemas.values()) { - list.addAll(schema.getAll(type)); - } - return list; - } - - /** - * Get all tables and views. - * - * @param includeMeta whether to include the meta data tables - * @return all objects of that type - */ - public ArrayList
getAllTablesAndViews(boolean includeMeta) { - if (includeMeta) { - initMetaTables(); - } - ArrayList
list = New.arrayList(); - for (Schema schema : schemas.values()) { - list.addAll(schema.getAllTablesAndViews()); - } - return list; - } - - public ArrayList getAllSchemas() { - initMetaTables(); - return New.arrayList(schemas.values()); - } - - public ArrayList getAllSettings() { - return New.arrayList(settings.values()); - } - - public ArrayList getAllUserDataTypes() { - return New.arrayList(userDataTypes.values()); - } - - public ArrayList getAllUsers() { - return New.arrayList(users.values()); - } - - public String getCacheType() { - return cacheType; - } - - public String getCluster() { - return cluster; - } - - public CompareMode getCompareMode() { - return compareMode; - } - - public String getDatabasePath() { - if (persistent) { - return IOUtils.getAbsolutePath(databaseName); - } - return null; - } - - public String getShortName() { - return databaseShortName; - } - - public String getName() { - return databaseName; - } - - /** - * Get all sessions that are currently connected to the database. - * - * @param includingSystemSession if the system session should also be - * included - * @return the list of sessions - */ - public Session[] getSessions(boolean includingSystemSession) { - ArrayList list; - // need to synchronized on userSession, otherwise the list - // may contain null elements - synchronized (userSessions) { - list = New.arrayList(userSessions); - } - // copy, to ensure the reference is stable - Session sys = systemSession; - if (includingSystemSession && sys != null) { - list.add(sys); - } - Session[] array = new Session[list.size()]; - list.toArray(array); - return array; - } - - /** - * Update an object in the system table. - * - * @param session the session - * @param obj the database object - */ - public synchronized void update(Session session, DbObject obj) { - int id = obj.getId(); - removeMeta(session, id); - addMeta(session, obj); - } - - /** - * Rename a schema object. - * - * @param session the session - * @param obj the object - * @param newName the new name - */ - public synchronized void renameSchemaObject(Session session, SchemaObject obj, String newName) { - checkWritingAllowed(); - obj.getSchema().rename(obj, newName); - updateWithChildren(session, obj); - } - - private synchronized void updateWithChildren(Session session, DbObject obj) { - ArrayList list = obj.getChildren(); - Comment comment = findComment(obj); - if (comment != null) { - DbException.throwInternalError(); - } - update(session, obj); - // remember that this scans only one level deep! - for (int i = 0; list != null && i < list.size(); i++) { - DbObject o = list.get(i); - if (o.getCreateSQL() != null) { - update(session, o); - } - } - } - - /** - * Rename a database object. - * - * @param session the session - * @param obj the object - * @param newName the new name - */ - public synchronized void renameDatabaseObject(Session session, DbObject obj, String newName) { - checkWritingAllowed(); - int type = obj.getType(); - HashMap map = getMap(type); - if (SysProperties.CHECK) { - if (!map.containsKey(obj.getName())) { - DbException.throwInternalError("not found: " + obj.getName()); - } - if (obj.getName().equals(newName) || map.containsKey(newName)) { - DbException.throwInternalError("object already exists: " + newName); - } - } - obj.checkRename(); - int id = obj.getId(); - removeMeta(session, id); - map.remove(obj.getName()); - obj.rename(newName); - map.put(newName, obj); - updateWithChildren(session, obj); - } - - /** - * Create a temporary file in the database folder. - * - * @return the file name - */ - public String createTempFile() { - try { - boolean inTempDir = readOnly; - String name = databaseName; - if (!persistent) { - name = FileSystemMemory.PREFIX + name; - } - return IOUtils.createTempFile(name, Constants.SUFFIX_TEMP_FILE, true, inTempDir); - } catch (IOException e) { - throw DbException.convertIOException(e, databaseName); - } - } - - private void reserveLobFileObjectIds() { - String prefix = IOUtils.normalize(databaseName) + "."; - String path = IOUtils.getParent(databaseName); - String[] list = IOUtils.listFiles(path); - for (String name : list) { - if (name.endsWith(Constants.SUFFIX_LOB_FILE) && IOUtils.fileStartsWith(name, prefix)) { - name = name.substring(prefix.length()); - name = name.substring(0, name.length() - Constants.SUFFIX_LOB_FILE.length()); - int dot = name.indexOf('.'); - if (dot >= 0) { - String id = name.substring(dot + 1); - int objectId = Integer.parseInt(id); - objectIds.set(objectId); - } - } - } - } - - private void deleteOldTempFiles() { - String path = IOUtils.getParent(databaseName); - String prefix = IOUtils.normalize(databaseName); - String[] list = IOUtils.listFiles(path); - for (String name : list) { - if (name.endsWith(Constants.SUFFIX_TEMP_FILE) && IOUtils.fileStartsWith(name, prefix)) { - // can't always delete the files, they may still be open - IOUtils.tryDelete(name); - } - } - } - - /** - * Get the schema. If the schema does not exist, an exception is thrown. - * - * @param schemaName the name of the schema - * @return the schema - * @throws SQLException no schema with that name exists - */ - public Schema getSchema(String schemaName) { - Schema schema = findSchema(schemaName); - if (schema == null) { - throw DbException.get(ErrorCode.SCHEMA_NOT_FOUND_1, schemaName); - } - return schema; - } - - /** - * Remove the object from the database. - * - * @param session the session - * @param obj the object to remove - */ - public synchronized void removeDatabaseObject(Session session, DbObject obj) { - checkWritingAllowed(); - String objName = obj.getName(); - int type = obj.getType(); - HashMap map = getMap(type); - if (SysProperties.CHECK && !map.containsKey(objName)) { - DbException.throwInternalError("not found: " + objName); - } - Comment comment = findComment(obj); - if (comment != null) { - removeDatabaseObject(session, comment); - } - int id = obj.getId(); - obj.removeChildrenAndResources(session); - map.remove(objName); - removeMeta(session, id); - } - - /** - * Get the first table that depends on this object. - * - * @param obj the object to find - * @param except the table to exclude (or null) - * @return the first dependent table, or null - */ - public Table getDependentTable(SchemaObject obj, Table except) { - switch (obj.getType()) { - case DbObject.COMMENT: - case DbObject.CONSTRAINT: - case DbObject.INDEX: - case DbObject.RIGHT: - case DbObject.TRIGGER: - case DbObject.USER: - return null; - default: - } - HashSet set = New.hashSet(); - for (Table t : getAllTablesAndViews(false)) { - if (except == t) { - continue; - } - set.clear(); - t.addDependencies(set); - if (set.contains(obj)) { - return t; - } - } - return null; - } - - /** - * Remove an object from the system table. - * - * @param session the session - * @param obj the object to be removed - */ - public synchronized void removeSchemaObject(Session session, SchemaObject obj) { - int type = obj.getType(); - if (type == DbObject.TABLE_OR_VIEW) { - Table table = (Table) obj; - if (table.isTemporary() && !table.isGlobalTemporary()) { - session.removeLocalTempTable(table); - return; - } - } else if (type == DbObject.INDEX) { - Index index = (Index) obj; - Table table = index.getTable(); - if (table.isTemporary() && !table.isGlobalTemporary()) { - session.removeLocalTempTableIndex(index); - return; - } - } else if (type == DbObject.CONSTRAINT) { - Constraint constraint = (Constraint) obj; - Table table = constraint.getTable(); - if (table.isTemporary() && !table.isGlobalTemporary()) { - session.removeLocalTempTableConstraint(constraint); - return; - } - } - checkWritingAllowed(); - Comment comment = findComment(obj); - if (comment != null) { - removeDatabaseObject(session, comment); - } - obj.getSchema().remove(obj); - int id = obj.getId(); - if (!starting) { - Table t = getDependentTable(obj, null); - if (t != null) { - obj.getSchema().add(obj); - throw DbException.get(ErrorCode.CANNOT_DROP_2, obj.getSQL(), t.getSQL()); - } - obj.removeChildrenAndResources(session); - } - removeMeta(session, id); - } - - /** - * Check if this database disk-based. - * - * @return true if it is disk-based, false it it is in-memory only. - */ - public boolean isPersistent() { - return persistent; - } - - public TraceSystem getTraceSystem() { - return traceSystem; - } - - public synchronized void setCacheSize(int kb) { - if (starting) { - int max = MathUtils.convertLongToInt(Utils.getMemoryMax()) / 2; - kb = Math.min(kb, max); - } - cacheSize = kb; - if (pageStore != null) { - pageStore.getCache().setMaxSize(kb); - } - } - - public synchronized void setMasterUser(User user) { - addDatabaseObject(systemSession, user); - systemSession.commit(true); - } - - public Role getPublicRole() { - return publicRole; - } - - /** - * Get a unique temporary table name. - * - * @param session the session - * @return a unique name - */ - public synchronized String getTempTableName(Session session) { - String tempName; - do { - tempName = "TEMP_TABLE_" + session.getId() + "_" + nextTempTableId++; - } while (mainSchema.findTableOrView(session, tempName) != null); - return tempName; - } - - public void setCompareMode(CompareMode compareMode) { - this.compareMode = compareMode; - } - - public void setCluster(String cluster) { - this.cluster = cluster; - } - - public void checkWritingAllowed() { - if (readOnly) { - throw DbException.get(ErrorCode.DATABASE_IS_READ_ONLY); - } - if (noDiskSpace) { - throw DbException.get(ErrorCode.NO_DISK_SPACE_AVAILABLE); - } - if (fileLockMethod == FileLock.LOCK_SERIALIZED) { - if (!reconnectChangePending) { - throw DbException.get(ErrorCode.DATABASE_IS_READ_ONLY); - } - } - } - - public boolean isReadOnly() { - return readOnly; - } - - public void setWriteDelay(int value) { - writeDelay = value; - if (writer != null) { - writer.setWriteDelay(value); - // TODO check if MIN_WRITE_DELAY is a good value - flushOnEachCommit = writeDelay < SysProperties.MIN_WRITE_DELAY; - } - } - - /** - * Check if flush-on-each-commit is enabled. - * - * @return true if it is - */ - public boolean getFlushOnEachCommit() { - return flushOnEachCommit; - } - - /** - * Get the list of in-doubt transactions. - * - * @return the list - */ - public ArrayList getInDoubtTransactions() { - return pageStore == null ? null : pageStore.getInDoubtTransactions(); - } - - /** - * Prepare a transaction. - * - * @param session the session - * @param transaction the name of the transaction - */ - public void prepareCommit(Session session, String transaction) { - if (readOnly) { - return; - } - synchronized (this) { - pageStore.prepareCommit(session, transaction); - } - } - - /** - * Commit the current transaction of the given session. - * - * @param session the session - */ - public void commit(Session session) { - if (readOnly) { - return; - } - synchronized (this) { - if (pageStore != null) { - pageStore.commit(session); - } - session.setAllCommitted(); - } - } - - /** - * Flush all pending changes to the transaction log. - */ - public void flush() { - synchronized (this) { - if (readOnly || pageStore == null) { - return; - } - pageStore.flushLog(); - } - } - - public void setEventListener(DatabaseEventListener eventListener) { - this.eventListener = eventListener; - } - - public void setEventListenerClass(String className) { - if (className == null || className.length() == 0) { - eventListener = null; - } else { - try { - eventListener = (DatabaseEventListener) Utils.loadUserClass(className).newInstance(); - String url = databaseURL; - if (cipher != null) { - url += ";CIPHER=" + cipher; - } - eventListener.init(url); - } catch (Throwable e) { - throw DbException.get(ErrorCode.ERROR_SETTING_DATABASE_EVENT_LISTENER_2, e, className, e.toString()); - } - } - } - - public synchronized void freeUpDiskSpace() { - if (eventListener != null) { - eventListener.diskSpaceIsLow(); - } - } - - /** - * Set the progress of a long running operation. - * This method calls the {@link DatabaseEventListener} if one is registered. - * - * @param state the {@link DatabaseEventListener} state - * @param name the object name - * @param x the current position - * @param max the highest value - */ - - public void setProgress(int state, String name, int x, int max) { - if (eventListener != null) { - try { - eventListener.setProgress(state, name, x, max); - } catch (Exception e2) { - // ignore this (user made) exception - } - } - } - - /** - * This method is called after an exception occurred, to inform the database - * event listener (if one is set). - * - * @param e the exception - * @param sql the SQL statement - */ - public void exceptionThrown(SQLException e, String sql) { - if (eventListener != null) { - try { - eventListener.exceptionThrown(e, sql); - } catch (Exception e2) { - // ignore this (user made) exception - } - } - } - - /** - * Synchronize the files with the file system. This method is called when - * executing the SQL statement CHECKPOINT SYNC. - */ - public void sync() { - synchronized (this) { - if (readOnly || pageStore == null) { - return; - } - pageStore.sync(); - } - } - - public int getMaxMemoryRows() { - return maxMemoryRows; - } - - public void setMaxMemoryRows(int value) { - this.maxMemoryRows = value; - } - - public void setMaxMemoryUndo(int value) { - this.maxMemoryUndo = value; - } - - public int getMaxMemoryUndo() { - return maxMemoryUndo; - } - - public void setLockMode(int lockMode) { - switch (lockMode) { - case Constants.LOCK_MODE_OFF: - if (multiThreaded) { - // currently the combination of LOCK_MODE=0 and MULTI_THREADED is not supported - throw DbException.get(ErrorCode.CANNOT_CHANGE_SETTING_WHEN_OPEN_1, "LOCK_MODE=0 & MULTI_THREADED"); - } - break; - case Constants.LOCK_MODE_READ_COMMITTED: - case Constants.LOCK_MODE_TABLE: - case Constants.LOCK_MODE_TABLE_GC: - break; - default: - throw DbException.getInvalidValueException("lock mode", "" + lockMode); - } - this.lockMode = lockMode; - } - - public int getLockMode() { - return lockMode; - } - - public synchronized void setCloseDelay(int value) { - this.closeDelay = value; - } - - public Session getSystemSession() { - return systemSession; - } - - /** - * Check if the database is in the process of closing. - * - * @return true if the database is closing - */ - public boolean isClosing() { - return closing; - } - - public void setMaxLengthInplaceLob(int value) { - this.maxLengthInplaceLob = value; - } - - public int getMaxLengthInplaceLob() { - return persistent ? maxLengthInplaceLob : Integer.MAX_VALUE; - } - - public void setIgnoreCase(boolean b) { - ignoreCase = b; - } - - public boolean getIgnoreCase() { - if (starting) { - // tables created at startup must not be converted to ignorecase - return false; - } - return ignoreCase; - } - - public synchronized void setDeleteFilesOnDisconnect(boolean b) { - this.deleteFilesOnDisconnect = b; - } - - public String getLobCompressionAlgorithm(int type) { - return lobCompressionAlgorithm; - } - - public void setLobCompressionAlgorithm(String stringValue) { - this.lobCompressionAlgorithm = stringValue; - } - - public synchronized void setMaxLogSize(long value) { - if (pageStore != null) { - pageStore.setMaxLogSize(value); - } - } - - public void setAllowLiterals(int value) { - this.allowLiterals = value; - } - - public boolean getOptimizeReuseResults() { - return optimizeReuseResults; - } - - public void setOptimizeReuseResults(boolean b) { - optimizeReuseResults = b; - } - - public Object getLobSyncObject() { - return lobSyncObject; - } - - public int getSessionCount() { - return userSessions.size(); - } - - public void setReferentialIntegrity(boolean b) { - referentialIntegrity = b; - } - - public boolean getReferentialIntegrity() { - return referentialIntegrity; - } - - /** - * Check if the database is currently opening. This is true until all stored - * SQL statements have been executed. - * - * @return true if the database is still starting - */ - public boolean isStarting() { - return starting; - } - - /** - * Check if multi version concurrency is enabled for this database. - * - * @return true if it is enabled - */ - public boolean isMultiVersion() { - return multiVersion; - } - - /** - * Called after the database has been opened and initialized. This method - * notifies the event listener if one has been set. - */ - public void opened() { - if (eventListener != null) { - eventListener.opened(); - } - if (writer != null) { - writer.startThread(); - } - } - - public void setMode(Mode mode) { - this.mode = mode; - } - - public Mode getMode() { - return mode; - } - - public boolean isMultiThreaded() { - return multiThreaded; - } - - public void setMultiThreaded(boolean multiThreaded) { - if (multiThreaded && multiVersion && this.multiThreaded != multiThreaded) { - // currently the combination of MVCC and MULTI_THREADED is not supported - throw DbException.get(ErrorCode.CANNOT_CHANGE_SETTING_WHEN_OPEN_1, "MVCC & MULTI_THREADED"); - } - this.multiThreaded = multiThreaded; - } - - public void setMaxOperationMemory(int maxOperationMemory) { - this.maxOperationMemory = maxOperationMemory; - } - - public int getMaxOperationMemory() { - return maxOperationMemory; - } - - public Session getExclusiveSession() { - return exclusiveSession; - } - - /** - * Set the session that can exclusively access the database. - * - * @param session the session - * @param closeOthers whether other sessions are closed - */ - public void setExclusiveSession(Session session, boolean closeOthers) { - this.exclusiveSession = session; - if (closeOthers) { - closeAllSessionsException(session); - } - } - - public SmallLRUCache getLobFileListCache() { - return lobFileListCache; - } - - /** - * Checks if the system table (containing the catalog) is locked. - * - * @return true if it is currently locked - */ - public boolean isSysTableLocked() { - return meta == null || meta.isLockedExclusively(); - } - - /** - * Open a new connection or get an existing connection to another database. - * - * @param driver the database driver or null - * @param url the database URL - * @param user the user name - * @param password the password - * @return the connection - */ - public TableLinkConnection getLinkConnection(String driver, String url, String user, String password) { - if (linkConnections == null) { - linkConnections = New.hashMap(); - } - return TableLinkConnection.open(linkConnections, driver, url, user, password); - } - - public String toString() { - return databaseShortName + ":" + super.toString(); - } - - /** - * Immediately close the database. - */ - public void shutdownImmediately() { - setPowerOffCount(1); - try { - checkPowerOff(); - } catch (DbException e) { - // ignore - } - closeFiles(); - } - - public TempFileDeleter getTempFileDeleter() { - return tempFileDeleter; - } - - public Trace getTrace() { - return getTrace(Trace.DATABASE); - } - - public PageStore getPageStore() { - if (pageStore == null) { - pageStore = new PageStore(this, databaseName + Constants.SUFFIX_PAGE_FILE, accessModeData, cacheSize); - if (pageSize != SysProperties.PAGE_SIZE) { - pageStore.setPageSize(pageSize); - } - pageStore.open(); - } - return pageStore; - } - - /** - * Get the first user defined table. - * - * @return the table or null if no table is defined - */ - public Table getFirstUserTable() { - for (Table table : getAllTablesAndViews(false)) { - if (table.getCreateSQL() != null) { - if (table.isHidden()) { - // LOB tables - continue; - } - return table; - } - } - return null; - } - - /** - * Check if the contents of the database was changed and therefore it is - * required to re-connect. This method waits until pending changes are - * completed. If a pending change takes too long (more than 2 seconds), the - * pending change is broken (removed from the properties file). - * - * @return true if reconnecting is required - */ - public boolean isReconnectNeeded() { - if (fileLockMethod != FileLock.LOCK_SERIALIZED) { - return false; - } - if (reconnectChangePending) { - return false; - } - long now = System.currentTimeMillis(); - if (now < reconnectCheckNext) { - return false; - } - reconnectCheckNext = now + SysProperties.RECONNECT_CHECK_DELAY; - if (lock == null) { - lock = new FileLock(traceSystem, databaseName + Constants.SUFFIX_LOCK_FILE, Constants.LOCK_SLEEP); - } - try { - Properties prop = lock.load(), first = prop; - while (true) { - if (prop.equals(reconnectLastLock)) { - return false; - } - if (prop.getProperty("changePending", null) == null) { - break; - } - if (System.currentTimeMillis() > now + SysProperties.RECONNECT_CHECK_DELAY * 10) { - if (first.equals(prop)) { - // the writing process didn't update the file - - // it may have terminated - lock.setProperty("changePending", null); - lock.save(); - break; - } - } - getTrace().debug("delay (change pending)"); - Thread.sleep(SysProperties.RECONNECT_CHECK_DELAY); - prop = lock.load(); - } - reconnectLastLock = prop; - } catch (Exception e) { - // DbException, InterruptedException - getTrace().error("readOnly:" + readOnly, e); - // ignore - } - return true; - } - - /** - * Flush all changes when using the serialized mode, and if there are - * pending changes, and some time has passed. This switches to a new - * transaction log and resets the change pending flag in - * the .lock.db file. - */ - public void checkpointIfRequired() { - if (fileLockMethod != FileLock.LOCK_SERIALIZED || readOnly || !reconnectChangePending || closing) { - return; - } - long now = System.currentTimeMillis(); - if (now > reconnectCheckNext + SysProperties.RECONNECT_CHECK_DELAY) { - if (SysProperties.CHECK && checkpointAllowed < 0) { - DbException.throwInternalError(); - } - synchronized (reconnectSync) { - if (checkpointAllowed > 0) { - return; - } - checkpointRunning = true; - } - synchronized (this) { - getTrace().debug("checkpoint start"); - flushSequences(); - checkpoint(); - reconnectModified(false); - getTrace().debug("checkpoint end"); - } - synchronized (reconnectSync) { - checkpointRunning = false; - } - } - } - - public boolean isFileLockSerialized() { - return fileLockMethod == FileLock.LOCK_SERIALIZED; - } - - private void flushSequences() { - for (SchemaObject obj : getAllSchemaObjects(DbObject.SEQUENCE)) { - Sequence sequence = (Sequence) obj; - sequence.flushWithoutMargin(); - } - } - - /** - * Flush all changes and open a new transaction log. - */ - public void checkpoint() { - if (persistent) { - synchronized (this) { - if (pageStore != null) { - pageStore.checkpoint(); - } - } - } - getTempFileDeleter().deleteUnused(); - } - - /** - * This method is called before writing to the transaction log. - * - * @return true if the call was successful and writing is allowed, - * false if another connection was faster - */ - public boolean beforeWriting() { - if (fileLockMethod != FileLock.LOCK_SERIALIZED) { - return true; - } - while (checkpointRunning) { - try { - Thread.sleep(10 + (int) (Math.random() * 10)); - } catch (Exception e) { - // ignore InterruptedException - } - } - synchronized (reconnectSync) { - if (reconnectModified(true)) { - checkpointAllowed++; - if (SysProperties.CHECK && checkpointAllowed > 20) { - throw DbException.throwInternalError(); - } - return true; - } - } - // make sure the next call to isReconnectNeeded() returns true - reconnectCheckNext = System.currentTimeMillis() - 1; - reconnectLastLock = null; - return false; - } - - /** - * This method is called after updates are finished. - */ - public void afterWriting() { - if (fileLockMethod != FileLock.LOCK_SERIALIZED) { - return; - } - synchronized (reconnectSync) { - checkpointAllowed--; - } - if (SysProperties.CHECK && checkpointAllowed < 0) { - throw DbException.throwInternalError(); - } - } - - /** - * Switch the database to read-only mode. - * - * @param readOnly the new value - */ - public void setReadOnly(boolean readOnly) { - this.readOnly = readOnly; - } - - public void setCompactFully(boolean compactFully) { - this.compactFully = compactFully; - } - - public SourceCompiler getCompiler() { - if (compiler == null) { - compiler = new SourceCompiler(); - } - return compiler; - } - - public LobStorage getLobStorage() { - if (lobStorage == null) { - lobStorage = new LobStorage(this); - } - return lobStorage; - } - - public Connection getLobConnection() { - String url = Constants.CONN_URL_INTERNAL; - JdbcConnection conn = new JdbcConnection(systemSession, systemUser.getName(), url); - conn.setTraceLevel(TraceSystem.OFF); - return conn; - } - -} diff --git a/tools/h2/src/main/org/h2/engine/DatabaseCloser.java b/tools/h2/src/main/org/h2/engine/DatabaseCloser.java deleted file mode 100755 index 62b6c18..0000000 --- a/tools/h2/src/main/org/h2/engine/DatabaseCloser.java +++ /dev/null @@ -1,96 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.engine; - -import java.lang.ref.WeakReference; - -import org.h2.message.Trace; - -/** - * This class is responsible to close a database if the application did not - * close a connection. A database closer object only exists if there is no user - * connected to the database. - */ -public class DatabaseCloser extends Thread { - - private final boolean shutdownHook; - private final Trace trace; - private volatile WeakReference databaseRef; - private int delayInMillis; - private boolean stopImmediately; - - DatabaseCloser(Database db, int delayInMillis, boolean shutdownHook) { - this.databaseRef = new WeakReference(db); - this.delayInMillis = delayInMillis; - this.shutdownHook = shutdownHook; - trace = db.getTrace(Trace.DATABASE); - } - - /** - * Stop and disable the database closer. This method is called after the - * database has been closed, or after a session has been created. - */ - public void reset() { - synchronized (this) { - databaseRef = null; - } - ThreadGroup threadGroup = getThreadGroup(); - // the threadGroup could be null if the thread was run in the meantime - if (threadGroup != null && threadGroup.activeCount() > 100) { - // in JDK 1.4 and below, all Thread objects are added to the ThreadGroup, - // and cause a memory leak if never started. - // Need to start it, otherwise it leaks memory in JDK 1.4 and below - stopImmediately = true; - try { - start(); - } catch (Throwable e) { - // ignore - } - } - } - - public void run() { - if (stopImmediately) { - return; - } - while (delayInMillis > 0) { - try { - int step = 100; - Thread.sleep(step); - delayInMillis -= step; - } catch (Exception e) { - // ignore InterruptedException - } - if (databaseRef == null) { - return; - } - } - Database database = null; - synchronized (this) { - if (databaseRef != null) { - database = databaseRef.get(); - } - } - if (database != null) { - try { - database.close(shutdownHook); - } catch (RuntimeException e) { - // this can happen when stopping a web application, - // if loading classes is no longer allowed - // it would throw an IllegalStateException - try { - trace.error("Could not close the database", e); - // if this was successful, we ignore the exception - // otherwise not - } catch (RuntimeException e2) { - throw e; - } - } - } - } - -} diff --git a/tools/h2/src/main/org/h2/engine/DbObject.java b/tools/h2/src/main/org/h2/engine/DbObject.java deleted file mode 100755 index 956d1ef..0000000 --- a/tools/h2/src/main/org/h2/engine/DbObject.java +++ /dev/null @@ -1,221 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.engine; - -import java.util.ArrayList; -import org.h2.table.Table; - -/** - * A database object such as a table, an index, or a user. - */ -public interface DbObject { - - /** - * The object is of the type table or view. - */ - int TABLE_OR_VIEW = 0; - - /** - * This object is an index. - */ - int INDEX = 1; - - /** - * This object is a user. - */ - int USER = 2; - - /** - * This object is a sequence. - */ - int SEQUENCE = 3; - - /** - * This object is a trigger. - */ - int TRIGGER = 4; - - /** - * This object is a constraint (check constraint, unique constraint, or - * referential constraint). - */ - int CONSTRAINT = 5; - - /** - * This object is a setting. - */ - int SETTING = 6; - - /** - * This object is a role. - */ - int ROLE = 7; - - /** - * This object is a right. - */ - int RIGHT = 8; - - /** - * This object is an alias for a Java function. - */ - int FUNCTION_ALIAS = 9; - - /** - * This object is a schema. - */ - int SCHEMA = 10; - - /** - * This object is a constant. - */ - int CONSTANT = 11; - - /** - * This object is a user data type (domain). - */ - int USER_DATATYPE = 12; - - /** - * This object is a comment. - */ - int COMMENT = 13; - - /** - * This object is a user-defined aggregate function. - */ - int AGGREGATE = 14; - - /** - * Tell the object that is was modified. - */ - void setModified(); - - /** - * Get the last modification id. - * - * @return the modification id - */ - long getModificationId(); - - /** - * Get the SQL name of this object (may be quoted). - * - * @return the SQL name - */ - String getSQL(); - - /** - * Get the list of dependent children (for tables, this includes indexes and - * so on). - * - * @return the list of children - */ - ArrayList getChildren(); - - /** - * Get the database. - * - * @return the database - */ - Database getDatabase(); - - /** - * Get the unique object id. - * - * @return the object id - */ - int getId(); - - /** - * Get the name. - * - * @return the name - */ - String getName(); - - /** - * Construct a CREATE ... SQL statement for this object when creating a copy - * of it. - * - * @param table the new table - * @param quotedName the quoted name - * @return the SQL statement - */ - String getCreateSQLForCopy(Table table, String quotedName); - - /** - * Construct the original CREATE ... SQL statement for this object. - * - * @return the SQL statement - */ - String getCreateSQL(); - - /** - * Construct a DROP ... SQL statement for this object. - * - * @return the SQL statement - */ - String getDropSQL(); - - /** - * Get the object type. - * - * @return the object type - */ - int getType(); - - /** - * Delete all dependent children objects and resources of this object. - * - * @param session the session - */ - void removeChildrenAndResources(Session session); - - /** - * Check if renaming is allowed. Does nothing when allowed. - * - * @throws SQLException if renaming is not allowed - */ - void checkRename(); - - /** - * Rename the object. - * - * @param newName the new name - */ - void rename(String newName); - - /** - * Check if this object is temporary (for example, a temporary table). - * - * @return true if is temporary - */ - boolean isTemporary(); - - /** - * Tell this object that it is temporary or not. - * - * @param temporary the new value - */ - void setTemporary(boolean temporary); - - /** - * Change the comment of this object. - * - * @param comment the new comment, or null for no comment - */ - void setComment(String comment); - - /** - * Get the current comment of this object. - * - * @return the comment, or null if not set - */ - String getComment(); - -} diff --git a/tools/h2/src/main/org/h2/engine/DbObjectBase.java b/tools/h2/src/main/org/h2/engine/DbObjectBase.java deleted file mode 100755 index e979b62..0000000 --- a/tools/h2/src/main/org/h2/engine/DbObjectBase.java +++ /dev/null @@ -1,171 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.engine; - -import java.util.ArrayList; -import org.h2.command.Parser; -import org.h2.message.Trace; -import org.h2.table.Table; - -/** - * The base class for all database objects. - */ -public abstract class DbObjectBase implements DbObject { - - /** - * The database. - */ - protected Database database; - - /** - * The trace module. - */ - protected Trace trace; - - /** - * The comment (if set). - */ - protected String comment; - - private int id; - private String objectName; - private long modificationId; - private boolean temporary; - - /** - * Initialize some attributes of this object. - * - * @param db the database - * @param objectId the object id - * @param name the name - * @param traceModule the trace module name - */ - protected void initDbObjectBase(Database db, int objectId, String name, String traceModule) { - this.database = db; - this.trace = db.getTrace(traceModule); - this.id = objectId; - this.objectName = name; - this.modificationId = db.getModificationMetaId(); - } - - /** - * Build a SQL statement to re-create the object, or to create a copy of the - * object with a different name or referencing a different table - * - * @param table - * the new table name - * @param quotedName - * the new quoted name - * @return the SQL statement - */ - public abstract String getCreateSQLForCopy(Table table, String quotedName); - - /** - * Build a SQL statement to re-create this object. - * - * @return the SQL statement - */ - public abstract String getCreateSQL(); - - /** - * Build a SQL statement to drop this object. - * - * @return the SQL statement - */ - public abstract String getDropSQL(); - - /** - * Get the object type. - * - * @return the object type - */ - public abstract int getType(); - - /** - * Remove all dependent objects and free all resources (files, blocks in - * files) of this object. - * - * @param session the session - */ - public abstract void removeChildrenAndResources(Session session); - - /** - * Check if this object can be renamed. System objects may not be renamed. - */ - public abstract void checkRename(); - - public void setModified() { - this.modificationId = database == null ? -1 : database.getNextModificationMetaId(); - } - - public long getModificationId() { - return modificationId; - } - - protected void setObjectName(String name) { - objectName = name; - } - - public String getSQL() { - return Parser.quoteIdentifier(objectName); - } - - public ArrayList getChildren() { - return null; - } - - public Database getDatabase() { - return database; - } - - public int getId() { - return id; - } - - public String getName() { - return objectName; - } - - /** - * Set the main attributes to null to make sure the object is no longer - * used. - */ - protected void invalidate() { - setModified(); - id = -1; - database = null; - trace = null; - objectName = null; - } - - public void rename(String newName) { - checkRename(); - objectName = newName; - setModified(); - } - - public boolean isTemporary() { - return temporary; - } - - public void setTemporary(boolean temporary) { - this.temporary = temporary; - } - - public void setComment(String comment) { - this.comment = comment; - } - - public String getComment() { - return comment; - } - - public String toString() { - return objectName + ":" + id + ":" + super.toString(); - } - -} diff --git a/tools/h2/src/main/org/h2/engine/Engine.java b/tools/h2/src/main/org/h2/engine/Engine.java deleted file mode 100755 index 26b22fc..0000000 --- a/tools/h2/src/main/org/h2/engine/Engine.java +++ /dev/null @@ -1,280 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.engine; - -import java.util.HashMap; -import org.h2.command.CommandInterface; -import org.h2.command.Parser; -import org.h2.command.dml.SetTypes; -import org.h2.constant.ErrorCode; -import org.h2.constant.SysProperties; -import org.h2.message.DbException; -import org.h2.message.Trace; -import org.h2.store.FileLock; -import org.h2.util.MathUtils; -import org.h2.util.New; -import org.h2.util.StringUtils; - -/** - * The engine contains a map of all open databases. - * It is also responsible for opening and creating new databases. - * This is a singleton class. - */ -public class Engine { - - private static final Engine INSTANCE = new Engine(); - private static final HashMap DATABASES = New.hashMap(); - private volatile long wrongPasswordDelay = SysProperties.DELAY_WRONG_PASSWORD_MIN; - - private Engine() { - // don't allow others to instantiate - } - - public static Engine getInstance() { - return INSTANCE; - } - - private Session openSession(ConnectionInfo ci, boolean ifExists, String cipher) { - String name = ci.getName(); - Database database; - boolean openNew = ci.getProperty("OPEN_NEW", false); - if (openNew || ci.isUnnamedInMemory()) { - database = null; - } else { - database = DATABASES.get(name); - } - User user = null; - boolean opened = false; - if (database == null) { - if (ifExists && !Database.exists(name)) { - throw DbException.get(ErrorCode.DATABASE_NOT_FOUND_1, name); - } - database = new Database(ci, cipher); - opened = true; - if (database.getAllUsers().size() == 0) { - // users is the last thing we add, so if no user is around, - // the database is not initialized correctly - user = new User(database, database.allocateObjectId(), ci.getUserName(), false); - user.setAdmin(true); - user.setUserPasswordHash(ci.getUserPasswordHash()); - database.setMasterUser(user); - } - if (!ci.isUnnamedInMemory()) { - DATABASES.put(name, database); - } - } - synchronized (database) { - if (opened) { - // start the thread when already synchronizing on the database - // otherwise a deadlock can occur when the writer thread - // opens a new database (as in recovery testing) - database.opened(); - } - if (database.isClosing()) { - return null; - } - if (user == null) { - if (database.validateFilePasswordHash(cipher, ci.getFilePasswordHash())) { - user = database.findUser(ci.getUserName()); - if (user != null) { - if (!user.validateUserPasswordHash(ci.getUserPasswordHash())) { - user = null; - } - } - } - if (opened && (user == null || !user.isAdmin())) { - // reset - because the user is not an admin, and has no - // right to listen to exceptions - database.setEventListener(null); - } - } - if (user == null) { - database.removeSession(null); - throw DbException.get(ErrorCode.WRONG_USER_OR_PASSWORD); - } - checkClustering(ci, database); - Session session = database.createSession(user); - return session; - } - } - - /** - * Open a database connection with the given connection information. - * - * @param ci the connection information - * @return the session - */ - public Session getSession(ConnectionInfo ci) { - try { - ConnectionInfo backup = null; - String lockMethodName = ci.getProperty("FILE_LOCK", null); - int fileLockMethod = FileLock.getFileLockMethod(lockMethodName); - if (fileLockMethod == FileLock.LOCK_SERIALIZED) { - // In serialized mode, database instance sharing is not possible - ci.setProperty("OPEN_NEW", "TRUE"); - try { - backup = (ConnectionInfo) ci.clone(); - } catch (CloneNotSupportedException e) { - throw DbException.convert(e); - } - } - Session session = openSession(ci); - validateUserAndPassword(true); - if (backup != null) { - session.setConnectionInfo(backup); - } - return session; - } catch (DbException e) { - if (e.getErrorCode() == ErrorCode.WRONG_USER_OR_PASSWORD) { - validateUserAndPassword(false); - } - throw e; - } - } - - private synchronized Session openSession(ConnectionInfo ci) { - boolean ifExists = ci.removeProperty("IFEXISTS", false); - boolean ignoreUnknownSetting = ci.removeProperty("IGNORE_UNKNOWN_SETTINGS", false); - String cipher = ci.removeProperty("CIPHER", null); - String init = ci.removeProperty("INIT", null); - Session session; - while (true) { - session = openSession(ci, ifExists, cipher); - if (session != null) { - break; - } - // we found a database that is currently closing - // wait a bit to avoid a busy loop (the method is synchronized) - try { - Thread.sleep(1); - } catch (InterruptedException e) { - // ignore - } - } - session.setAllowLiterals(true); - for (String setting : ci.getKeys()) { - String value = ci.getProperty(setting); - try { - CommandInterface command = session.prepareCommand("SET " + Parser.quoteIdentifier(setting) + " " - + value, Integer.MAX_VALUE); - command.executeUpdate(); - } catch (DbException e) { - if (!ignoreUnknownSetting) { - session.close(); - throw e; - } - } - } - if (init != null) { - try { - CommandInterface command = session.prepareCommand(init, Integer.MAX_VALUE); - command.executeUpdate(); - } catch (DbException e) { - if (!ignoreUnknownSetting) { - session.close(); - throw e; - } - } - } - session.setAllowLiterals(false); - session.commit(true); - session.getDatabase().getTrace(Trace.SESSION).info("connected #" + session.getId()); - return session; - } - - private void checkClustering(ConnectionInfo ci, Database database) { - String clusterSession = ci.getProperty(SetTypes.CLUSTER, null); - if (Constants.CLUSTERING_DISABLED.equals(clusterSession)) { - // in this case, no checking is made - // (so that a connection can be made to disable/change clustering) - return; - } - String clusterDb = database.getCluster(); - if (!Constants.CLUSTERING_DISABLED.equals(clusterDb)) { - if (!StringUtils.equals(clusterSession, clusterDb)) { - if (clusterDb.equals(Constants.CLUSTERING_DISABLED)) { - throw DbException.get(ErrorCode.CLUSTER_ERROR_DATABASE_RUNS_ALONE); - } - throw DbException.get(ErrorCode.CLUSTER_ERROR_DATABASE_RUNS_CLUSTERED_1, clusterDb); - } - } - } - - /** - * Called after a database has been closed, to remove the object from the - * list of open databases. - * - * @param name the database name - */ - public void close(String name) { - DATABASES.remove(name); - } - - /** - * This method is called after validating user name and password. If user - * name and password were correct, the sleep time is reset, otherwise this - * method waits some time (to make brute force / rainbow table attacks - * harder) and then throws a 'wrong user or password' exception. The delay - * is a bit randomized to protect against timing attacks. Also the delay - * doubles after each unsuccessful logins, to make brute force attacks - * harder. - * - * There is only one exception message both for wrong user and for - * wrong password, to make it harder to get the list of user names. This - * method must only be called from one place, so it is not possible from the - * stack trace to see if the user name was wrong or the password. - * - * @param correct if the user name or the password was correct - * @throws SQLException the exception 'wrong user or password' - */ - private void validateUserAndPassword(boolean correct) { - int min = SysProperties.DELAY_WRONG_PASSWORD_MIN; - if (correct) { - long delay = wrongPasswordDelay; - if (delay > min && delay > 0) { - // the first correct password must be blocked, - // otherwise parallel attacks are possible - synchronized (INSTANCE) { - // delay up to the last delay - // an attacker can't know how long it will be - delay = MathUtils.secureRandomInt((int) delay); - try { - Thread.sleep(delay); - } catch (InterruptedException e) { - // ignore - } - wrongPasswordDelay = min; - } - } - } else { - // this method is not synchronized on the Engine, so that - // regular successful attempts are not blocked - synchronized (INSTANCE) { - long delay = wrongPasswordDelay; - int max = SysProperties.DELAY_WRONG_PASSWORD_MAX; - if (max <= 0) { - max = Integer.MAX_VALUE; - } - wrongPasswordDelay += wrongPasswordDelay; - if (wrongPasswordDelay > max || wrongPasswordDelay < 0) { - wrongPasswordDelay = max; - } - if (min > 0) { - // a bit more to protect against timing attacks - delay += Math.abs(MathUtils.secureRandomLong() % 100); - try { - Thread.sleep(delay); - } catch (InterruptedException e) { - // ignore - } - } - throw DbException.get(ErrorCode.WRONG_USER_OR_PASSWORD); - } - } - } - -} diff --git a/tools/h2/src/main/org/h2/engine/FunctionAlias.java b/tools/h2/src/main/org/h2/engine/FunctionAlias.java deleted file mode 100755 index 485f6a1..0000000 --- a/tools/h2/src/main/org/h2/engine/FunctionAlias.java +++ /dev/null @@ -1,474 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.engine; - -import java.lang.reflect.Array; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; -import java.lang.reflect.Modifier; -import java.sql.Connection; -import java.util.ArrayList; -import java.util.Arrays; -import org.h2.command.Parser; -import org.h2.constant.ErrorCode; -import org.h2.constant.SysProperties; -import org.h2.expression.Expression; -import org.h2.message.DbException; -import org.h2.message.Trace; -import org.h2.schema.Schema; -import org.h2.schema.SchemaObjectBase; -import org.h2.table.Table; -import org.h2.util.New; -import org.h2.util.SourceCompiler; -import org.h2.util.StatementBuilder; -import org.h2.util.StringUtils; -import org.h2.util.Utils; -import org.h2.value.DataType; -import org.h2.value.Value; -import org.h2.value.ValueNull; - -/** - * Represents a user-defined function, or alias. - * - * @author Thomas Mueller - * @author Gary Tong - */ -public class FunctionAlias extends SchemaObjectBase { - - private String className; - private String methodName; - private String source; - private JavaMethod[] javaMethods; - private boolean deterministic; - - private FunctionAlias(Schema schema, int id, String name) { - initSchemaObjectBase(schema, id, name, Trace.FUNCTION); - } - - /** - * Create a new alias based on a method name. - * - * @param schema the schema - * @param id the id - * @param name the name - * @param javaClassMethod the class and method name - * @param force create the object even if the class or method does not exist - * @return the database object - */ - public static FunctionAlias newInstance(Schema schema, int id, String name, String javaClassMethod, boolean force) { - FunctionAlias alias = new FunctionAlias(schema, id, name); - int paren = javaClassMethod.indexOf('('); - int lastDot = javaClassMethod.lastIndexOf('.', paren < 0 ? javaClassMethod.length() : paren); - if (lastDot < 0) { - throw DbException.get(ErrorCode.SYNTAX_ERROR_1, javaClassMethod); - } - alias.className = javaClassMethod.substring(0, lastDot); - alias.methodName = javaClassMethod.substring(lastDot + 1); - alias.init(force); - return alias; - } - - /** - * Create a new alias based on source code. - * - * @param schema the schema - * @param id the id - * @param name the name - * @param source the source code - * @param force create the object even if the class or method does not exist - * @return the database object - */ - public static FunctionAlias newInstanceFromSource(Schema schema, int id, String name, String source, boolean force) { - FunctionAlias alias = new FunctionAlias(schema, id, name); - alias.source = source; - alias.init(force); - return alias; - } - - private void init(boolean force) { - try { - // at least try to compile the class, otherwise the data type is not - // initialized if it could be - load(); - } catch (DbException e) { - if (!force) { - throw e; - } - } - } - - private synchronized void load() { - if (javaMethods != null) { - return; - } - if (source != null) { - loadFromSource(); - } else { - loadClass(); - } - } - - private void loadFromSource() { - SourceCompiler compiler = database.getCompiler(); - synchronized (compiler) { - String fullClassName = Constants.USER_PACKAGE + "." + getName(); - compiler.setSource(fullClassName, source); - try { - Method m = compiler.getMethod(fullClassName); - JavaMethod method = new JavaMethod(m, 0); - javaMethods = new JavaMethod[] { - method - }; - } catch (DbException e) { - throw e; - } catch (Exception e) { - throw DbException.get(ErrorCode.SYNTAX_ERROR_1, e, source); - } - } - } - - private void loadClass() { - Class< ? > javaClass = Utils.loadUserClass(className); - Method[] methods = javaClass.getMethods(); - ArrayList list = New.arrayList(); - for (int i = 0; i < methods.length; i++) { - Method m = methods[i]; - if (!Modifier.isStatic(m.getModifiers())) { - continue; - } - if (m.getName().equals(methodName) || getMethodSignature(m).equals(methodName)) { - JavaMethod javaMethod = new JavaMethod(m, i); - for (JavaMethod old : list) { - if (old.getParameterCount() == javaMethod.getParameterCount()) { - throw DbException.get( - ErrorCode.METHODS_MUST_HAVE_DIFFERENT_PARAMETER_COUNTS_2, - old.toString(), javaMethod.toString() - ); - } - } - list.add(javaMethod); - } - } - if (list.size() == 0) { - throw DbException.get(ErrorCode.PUBLIC_STATIC_JAVA_METHOD_NOT_FOUND_1, methodName + " (" + className + ")"); - } - javaMethods = new JavaMethod[list.size()]; - list.toArray(javaMethods); - // Sort elements. Methods with a variable number of arguments must be at - // the end. Reason: there could be one method without parameters and one - // with a variable number. The one without parameters needs to be used - // if no parameters are given. - Arrays.sort(javaMethods); - } - - private String getMethodSignature(Method m) { - StatementBuilder buff = new StatementBuilder(m.getName()); - buff.append('('); - for (Class< ? > p : m.getParameterTypes()) { - // do not use a space here, because spaces are removed - // in CreateFunctionAlias.setJavaClassMethod() - buff.appendExceptFirst(","); - if (p.isArray()) { - buff.append(p.getComponentType().getName()).append("[]"); - } else { - buff.append(p.getName()); - } - } - return buff.append(')').toString(); - } - - public String getCreateSQLForCopy(Table table, String quotedName) { - throw DbException.throwInternalError(); - } - - public String getDropSQL() { - return "DROP ALIAS IF EXISTS " + getSQL(); - } - - public String getSQL() { - // TODO can remove this method once FUNCTIONS_IN_SCHEMA is enabled - if (SysProperties.FUNCTIONS_IN_SCHEMA || !getSchema().getName().equals(Constants.SCHEMA_MAIN)) { - return super.getSQL(); - } - return Parser.quoteIdentifier(getName()); - } - - public String getCreateSQL() { - StringBuilder buff = new StringBuilder("CREATE FORCE ALIAS "); - buff.append(getSQL()); - if (deterministic) { - buff.append(" DETERMINISTIC"); - } - if (source != null) { - buff.append(" AS ").append(StringUtils.quoteStringSQL(source)); - } else { - buff.append(" FOR ").append(Parser.quoteIdentifier(className + "." + methodName)); - } - return buff.toString(); - } - - public int getType() { - return DbObject.FUNCTION_ALIAS; - } - - public synchronized void removeChildrenAndResources(Session session) { - database.removeMeta(session, getId()); - className = null; - methodName = null; - javaMethods = null; - invalidate(); - } - - public void checkRename() { - throw DbException.getUnsupportedException("RENAME"); - } - - /** - * Find the Java method that matches the arguments. - * - * @param args the argument list - * @return the Java method - * @throws SQLException if no matching method could be found - */ - public JavaMethod findJavaMethod(Expression[] args) { - load(); - int parameterCount = args.length; - for (JavaMethod m : javaMethods) { - int count = m.getParameterCount(); - if (count == parameterCount || (m.isVarArgs() && count <= parameterCount + 1)) { - return m; - } - } - throw DbException.get(ErrorCode.METHOD_NOT_FOUND_1, methodName + " (" + className + ", parameter count: " + parameterCount + ")"); - } - - public String getJavaClassName() { - return this.className; - } - - public String getJavaMethodName() { - return this.methodName; - } - - /** - * Get the Java methods mapped by this function. - * - * @return the Java methods. - */ - public JavaMethod[] getJavaMethods() { - load(); - return javaMethods; - } - - /** - * There may be multiple Java methods that match a function name. - * Each method must have a different number of parameters however. - * This helper class represents one such method. - */ - public static class JavaMethod implements Comparable { - private final int id; - private final Method method; - private final int dataType; - private boolean hasConnectionParam; - private boolean varArgs; - private Class< ? > varArgClass; - private int paramCount; - - JavaMethod(Method method, int id) { - this.method = method; - this.id = id; - Class< ? >[] paramClasses = method.getParameterTypes(); - paramCount = paramClasses.length; - if (paramCount > 0) { - Class< ? > paramClass = paramClasses[0]; - if (Connection.class.isAssignableFrom(paramClass)) { - hasConnectionParam = true; - paramCount--; - } - } - if (paramCount > 0) { - Class< ? > lastArg = paramClasses[paramClasses.length - 1]; - if (lastArg.isArray() && FunctionAlias.isVarArgs(method)) { - varArgs = true; - varArgClass = lastArg.getComponentType(); - } - } - Class< ? > returnClass = method.getReturnType(); - dataType = DataType.getTypeFromClass(returnClass); - } - - public String toString() { - return method.toString(); - } - - /** - * Check if this function requires a database connection. - * - * @return if the function requires a connection - */ - public boolean hasConnectionParam() { - return this.hasConnectionParam; - } - - /** - * Call the user-defined function and return the value. - * - * @param session the session - * @param args the argument list - * @param columnList true if the function should only return the column list - * @return the value - */ - public Value getValue(Session session, Expression[] args, boolean columnList) { - Class< ? >[] paramClasses = method.getParameterTypes(); - Object[] params = new Object[paramClasses.length]; - int p = 0; - if (hasConnectionParam && params.length > 0) { - params[p++] = session.createConnection(columnList); - } - - // allocate array for varArgs parameters - Object varArg = null; - if (varArgs) { - int len = args.length - params.length + 1 + (hasConnectionParam ? 1 : 0); - varArg = Array.newInstance(varArgClass, len); - params[params.length - 1] = varArg; - } - - for (int a = 0; a < args.length; a++, p++) { - boolean currentIsVarArg = varArgs && p >= paramClasses.length - 1; - Class< ? > paramClass; - if (currentIsVarArg) { - paramClass = varArgClass; - } else { - paramClass = paramClasses[p]; - } - int type = DataType.getTypeFromClass(paramClass); - Value v = args[a].getValue(session); - v = v.convertTo(type); - Object o = v.getObject(); - if (o == null) { - if (paramClass.isPrimitive()) { - if (columnList) { - // if the column list is requested, the parameters may - // be null - // need to set to default value otherwise the function - // can't be called at all - o = DataType.getDefaultForPrimitiveType(paramClass); - } else { - // NULL for a java primitive: return NULL - return ValueNull.INSTANCE; - } - } - } else { - if (!paramClass.isAssignableFrom(o.getClass()) && !paramClass.isPrimitive()) { - o = DataType.convertTo(session, session.createConnection(false), v, paramClass); - } - } - if (currentIsVarArg) { - Array.set(varArg, p - params.length + 1, o); - } else { - params[p] = o; - } - } - boolean old = session.getAutoCommit(); - Value identity = session.getScopeIdentity(); - try { - session.setAutoCommit(false); - Object returnValue; - try { - returnValue = method.invoke(null, params); - if (returnValue == null) { - return ValueNull.INSTANCE; - } - } catch (InvocationTargetException e) { - StatementBuilder buff = new StatementBuilder(method.getName()); - buff.append('('); - for (Object o : params) { - buff.appendExceptFirst(", "); - buff.append(o == null ? "null" : o.toString()); - } - buff.append(')'); - throw DbException.convertInvocation(e, buff.toString()); - } catch (Exception e) { - throw DbException.convert(e); - } - Value ret = DataType.convertToValue(session, returnValue, dataType); - return ret.convertTo(dataType); - } finally { - session.setScopeIdentity(identity); - session.setAutoCommit(old); - } - } - - public Class< ? >[] getColumnClasses() { - return method.getParameterTypes(); - } - - public int getDataType() { - return dataType; - } - - public int getParameterCount() { - return paramCount; - } - - public boolean isVarArgs() { - return varArgs; - } - - public int compareTo(JavaMethod m) { - if (varArgs != m.varArgs) { - return varArgs ? 1 : -1; - } - if (paramCount != m.paramCount) { - return paramCount - m.paramCount; - } - if (hasConnectionParam != m.hasConnectionParam) { - return hasConnectionParam ? 1 : -1; - } - return id - m.id; - } - - } - - public void setDeterministic(boolean deterministic) { - this.deterministic = deterministic; - } - - public boolean isDeterministic() { - return deterministic; - } - - public String getSource() { - return source; - } - - /** - * Checks if the given method takes a variable number of arguments. For Java - * 1.4 and older, false is returned. Example: - *
-     * public static double mean(double... values)
-     * 
- * - * @param m the method to test - * @return true if the method takes a variable number of arguments. - */ - static boolean isVarArgs(Method m) { - if ("1.5".compareTo(SysProperties.JAVA_SPECIFICATION_VERSION) > 0) { - return false; - } - try { - Method isVarArgs = m.getClass().getMethod("isVarArgs"); - Boolean result = (Boolean) isVarArgs.invoke(m); - return result.booleanValue(); - } catch (Exception e) { - return false; - } - } - - -} diff --git a/tools/h2/src/main/org/h2/engine/MetaRecord.java b/tools/h2/src/main/org/h2/engine/MetaRecord.java deleted file mode 100755 index a4c4f11..0000000 --- a/tools/h2/src/main/org/h2/engine/MetaRecord.java +++ /dev/null @@ -1,143 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.engine; - -import java.sql.SQLException; -import org.h2.api.DatabaseEventListener; -import org.h2.command.Prepared; -import org.h2.message.DbException; -import org.h2.message.Trace; -import org.h2.result.SearchRow; -import org.h2.value.ValueInt; -import org.h2.value.ValueString; - -/** - * A record in the system table of the database. - * It contains the SQL statement to create the database object. - */ -public class MetaRecord implements Comparable { - - private int id; - private int objectType; - private String sql; - - public MetaRecord(SearchRow r) { - id = r.getValue(0).getInt(); - objectType = r.getValue(2).getInt(); - sql = r.getValue(3).getString(); - } - - MetaRecord(DbObject obj) { - id = obj.getId(); - objectType = obj.getType(); - sql = obj.getCreateSQL(); - } - - void setRecord(SearchRow r) { - r.setValue(0, ValueInt.get(id)); - r.setValue(1, ValueInt.get(0)); - r.setValue(2, ValueInt.get(objectType)); - r.setValue(3, ValueString.get(sql)); - } - - /** - * Execute the meta data statement. - * - * @param db the database - * @param systemSession the system session - * @param listener the database event listener - */ - void execute(Database db, Session systemSession, DatabaseEventListener listener) { - try { - Prepared command = systemSession.prepare(sql); - command.setObjectId(id); - command.update(); - } catch (DbException e) { - e = e.addSQL(sql); - SQLException s = e.getSQLException(); - db.getTrace(Trace.DATABASE).error(sql, s); - if (listener != null) { - listener.exceptionThrown(s, sql); - // continue startup in this case - } else { - throw e; - } - } - } - - public int getId() { - return id; - } - - public int getObjectType() { - return objectType; - } - - public String getSQL() { - return sql; - } - - /** - * Sort the list of meta records by 'create order'. - * - * @param other the other record - * @return -1, 0, or 1 - */ - public int compareTo(MetaRecord other) { - int c1 = getCreateOrder(getObjectType()); - int c2 = getCreateOrder(other.getObjectType()); - if (c1 != c2) { - return c1 - c2; - } - return getId() - other.getId(); - } - - /** - * Get the sort order id for this object type. Objects are created in this - * order when opening a database. - * - * @param type the database object type - * @return the sort index - */ - private int getCreateOrder(int type) { - switch(type) { - case DbObject.SETTING: - return 0; - case DbObject.USER: - return 1; - case DbObject.SCHEMA: - return 2; - case DbObject.USER_DATATYPE: - return 3; - case DbObject.SEQUENCE: - return 4; - case DbObject.CONSTANT: - return 5; - case DbObject.FUNCTION_ALIAS: - return 6; - case DbObject.TABLE_OR_VIEW: - return 7; - case DbObject.INDEX: - return 8; - case DbObject.CONSTRAINT: - return 9; - case DbObject.TRIGGER: - return 10; - case DbObject.ROLE: - return 11; - case DbObject.RIGHT: - return 12; - case DbObject.AGGREGATE: - return 13; - case DbObject.COMMENT: - return 14; - default: - throw DbException.throwInternalError("type="+type); - } - } - -} diff --git a/tools/h2/src/main/org/h2/engine/Mode.java b/tools/h2/src/main/org/h2/engine/Mode.java deleted file mode 100755 index 2e18ed4..0000000 --- a/tools/h2/src/main/org/h2/engine/Mode.java +++ /dev/null @@ -1,189 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.engine; - -import java.util.HashMap; - -import org.h2.constant.SysProperties; -import org.h2.util.New; -import org.h2.util.StringUtils; - -/** - * The compatibility modes. There is a fixed set of modes (for example - * PostgreSQL, MySQL). Each mode has different settings. - */ -public class Mode { - - /** - * The name of the default mode. - */ - public static final String REGULAR = "REGULAR"; - - private static final HashMap MODES = New.hashMap(); - - // Modes are also documented in the features section - - /** - * When enabled, aliased columns (as in SELECT ID AS I FROM TEST) return the - * alias (I in this case) in ResultSetMetaData.getColumnName() and 'null' in - * getTableName(). If disabled, the real column name (ID in this case) and - * table name is returned. - */ - public boolean aliasColumnName; - - /** - * 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. - */ - public boolean convertInsertNullToZero; - - /** - * When converting the scale of decimal data, the number is only converted - * if the new scale is smaller than the current scale. Usually, the scale is - * converted and 0s are added if required. - */ - public boolean convertOnlyToSmallerScale; - - /** - * Creating indexes in the CREATE TABLE statement is allowed using - * INDEX(..) or KEY(..). - * Example: create table test(id int primary key, name varchar(255), - * key idx_name(name)); - */ - public boolean indexDefinitionInCreateTable; - - /** - * Meta data calls return identifiers in lower case. - */ - public boolean lowerCaseIdentifiers; - - /** - * 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 operands are NULL. - */ - public boolean nullConcatIsNull; - - /** - * When converting a floating point number to an integer, the fractional - * digits are not truncated, but the value is rounded. - */ - public boolean roundWhenConvertToLong; - - /** - * Identifiers may be quoted using square brackets as in [Test]. - */ - public boolean squareBracketQuotedNames; - - /** - * Support for the syntax - * [OFFSET .. ROW|ROWS] [FETCH FIRST .. ROW|ROWS ONLY] - * as an alternative for LIMIT .. OFFSET. - */ - public boolean supportOffsetFetch; - - /** - * The system columns 'CTID' and 'OID' are supported. - */ - public boolean systemColumns; - - /** - * For unique indexes, NULL is distinct. That means only one row with NULL - * in one of the columns is allowed. - */ - public boolean uniqueIndexSingleNull; - - /** - * When using unique indexes, multiple rows with NULL in all columns - * are allowed, however it is not allowed to have multiple rows with the - * same values otherwise. - */ - public boolean uniqueIndexSingleNullExceptAllColumnsAreNull; - - /** - * Text can be concatenated using '+'. - */ - public boolean allowPlusForStringConcat; - - private String name; - - static { - Mode mode = new Mode(REGULAR); - mode.aliasColumnName = SysProperties.ALIAS_COLUMN_NAME; - mode.nullConcatIsNull = true; - add(mode); - - mode = new Mode("DB2"); - mode.aliasColumnName = true; - mode.supportOffsetFetch = true; - add(mode); - - mode = new Mode("Derby"); - mode.aliasColumnName = true; - mode.uniqueIndexSingleNull = true; - add(mode); - - mode = new Mode("HSQLDB"); - mode.aliasColumnName = true; - mode.convertOnlyToSmallerScale = true; - mode.nullConcatIsNull = true; - mode.uniqueIndexSingleNull = true; - mode.allowPlusForStringConcat = true; - add(mode); - - mode = new Mode("MSSQLServer"); - mode.aliasColumnName = true; - mode.squareBracketQuotedNames = true; - mode.uniqueIndexSingleNull = true; - mode.allowPlusForStringConcat = true; - add(mode); - - mode = new Mode("MySQL"); - mode.convertInsertNullToZero = true; - mode.indexDefinitionInCreateTable = true; - mode.lowerCaseIdentifiers = true; - mode.roundWhenConvertToLong = true; - add(mode); - - mode = new Mode("Oracle"); - mode.aliasColumnName = true; - mode.uniqueIndexSingleNullExceptAllColumnsAreNull = true; - add(mode); - - mode = new Mode("PostgreSQL"); - mode.aliasColumnName = true; - mode.nullConcatIsNull = true; - mode.roundWhenConvertToLong = true; - mode.systemColumns = true; - add(mode); - } - - private Mode(String name) { - this.name = name; - } - - private static void add(Mode mode) { - MODES.put(StringUtils.toUpperEnglish(mode.name), mode); - } - - /** - * Get the mode with the given name. - * - * @param name the name of the mode - * @return the mode object - */ - public static Mode getInstance(String name) { - return MODES.get(StringUtils.toUpperEnglish(name)); - } - - public String getName() { - return name; - } - -} diff --git a/tools/h2/src/main/org/h2/engine/Procedure.java b/tools/h2/src/main/org/h2/engine/Procedure.java deleted file mode 100755 index ef452e3..0000000 --- a/tools/h2/src/main/org/h2/engine/Procedure.java +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.engine; - -import org.h2.command.Prepared; - -/** - * Represents a procedure. Procedures are implemented for PostgreSQL - * compatibility. - */ -public class Procedure { - - private final String name; - private final Prepared prepared; - - public Procedure(String name, Prepared prepared) { - this.name = name; - this.prepared = prepared; - } - - public String getName() { - return name; - } - - public Prepared getPrepared() { - return prepared; - } - -} diff --git a/tools/h2/src/main/org/h2/engine/Right.java b/tools/h2/src/main/org/h2/engine/Right.java deleted file mode 100755 index 3510756..0000000 --- a/tools/h2/src/main/org/h2/engine/Right.java +++ /dev/null @@ -1,149 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.engine; - -import org.h2.message.DbException; -import org.h2.message.Trace; -import org.h2.table.Table; - -/** - * An access right. Rights are regular database objects, but have generated - * names. - */ -public class Right extends DbObjectBase { - - /** - * The right bit mask that means: selecting from a table is allowed. - */ - public static final int SELECT = 1; - - /** - * The right bit mask that means: deleting rows from a table is allowed. - */ - public static final int DELETE = 2; - - /** - * The right bit mask that means: inserting rows into a table is allowed. - */ - public static final int INSERT = 4; - - /** - * The right bit mask that means: updating data is allowed. - */ - public static final int UPDATE = 8; - - /** - * The right bit mask that means: select, insert, update, delete, and update - * for this object is allowed. - */ - public static final int ALL = SELECT | DELETE | INSERT | UPDATE; - - private Role grantedRole; - private int grantedRight; - private Table grantedTable; - private RightOwner grantee; - - public Right(Database db, int id, RightOwner grantee, Role grantedRole) { - initDbObjectBase(db, id, "RIGHT_"+id, Trace.USER); - this.grantee = grantee; - this.grantedRole = grantedRole; - } - - public Right(Database db, int id, RightOwner grantee, int grantedRight, Table grantedRightOnTable) { - initDbObjectBase(db, id, "" + id, Trace.USER); - this.grantee = grantee; - this.grantedRight = grantedRight; - this.grantedTable = grantedRightOnTable; - } - - private boolean appendRight(StringBuilder buff, int right, int mask, String name, boolean comma) { - if ((right & mask) != 0) { - if (comma) { - buff.append(", "); - } - buff.append(name); - return true; - } - return comma; - } - - public String getRights() { - StringBuilder buff = new StringBuilder(); - if (grantedRight == ALL) { - buff.append("ALL"); - } else { - boolean comma = false; - comma = appendRight(buff, grantedRight, SELECT, "SELECT", comma); - comma = appendRight(buff, grantedRight, DELETE, "DELETE", comma); - comma = appendRight(buff, grantedRight, INSERT, "INSERT", comma); - appendRight(buff, grantedRight, UPDATE, "UPDATE", comma); - } - return buff.toString(); - } - - public Role getGrantedRole() { - return grantedRole; - } - - public Table getGrantedTable() { - return grantedTable; - } - - public DbObject getGrantee() { - return grantee; - } - - public String getDropSQL() { - return null; - } - - public String getCreateSQLForCopy(Table table, String quotedName) { - StringBuilder buff = new StringBuilder(); - buff.append("GRANT "); - if (grantedRole != null) { - buff.append(grantedRole.getSQL()); - } else { - buff.append(getRights()).append(" ON ").append(table.getSQL()); - } - buff.append(" TO ").append(grantee.getSQL()); - return buff.toString(); - } - - public String getCreateSQL() { - return getCreateSQLForCopy(grantedTable, null); - } - - public int getType() { - return DbObject.RIGHT; - } - - public void removeChildrenAndResources(Session session) { - if (grantedTable != null) { - grantee.revokeRight(grantedTable); - } else { - grantee.revokeRole(grantedRole); - } - database.removeMeta(session, getId()); - grantedRole = null; - grantedTable = null; - grantee = null; - invalidate(); - } - - public void checkRename() { - DbException.throwInternalError(); - } - - public void setRightMask(int rightMask) { - grantedRight = rightMask; - } - - public int getRightMask() { - return grantedRight; - } - -} diff --git a/tools/h2/src/main/org/h2/engine/RightOwner.java b/tools/h2/src/main/org/h2/engine/RightOwner.java deleted file mode 100755 index cfb33ad..0000000 --- a/tools/h2/src/main/org/h2/engine/RightOwner.java +++ /dev/null @@ -1,172 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.engine; - -import java.util.HashMap; - -import org.h2.table.Table; -import org.h2.util.New; - -/** - * A right owner (sometimes called principal). - */ -public abstract class RightOwner extends DbObjectBase { - - /** - * The map of granted roles. - */ - private HashMap grantedRoles; - - /** - * The map of granted rights. - */ - private HashMap grantedRights; - - protected RightOwner(Database database, int id, String name, String traceModule) { - initDbObjectBase(database, id, name, traceModule); - } - - /** - * Check if a role has been granted for this right owner. - * - * @param grantedRole the role - * @return true if the role has been granted - */ - public boolean isRoleGranted(Role grantedRole) { - if (grantedRole == this) { - return true; - } - if (grantedRoles != null) { - for (Role role : grantedRoles.keySet()) { - if (role == grantedRole) { - return true; - } - if (role.isRoleGranted(grantedRole)) { - return true; - } - } - } - return false; - } - - /** - * Check if a right is already granted to this object or to objects that - * were granted to this object. - * - * @param table the table to check - * @param rightMask the right mask to check - * @return true if the right was already granted - */ - boolean isRightGrantedRecursive(Table table, int rightMask) { - Right right; - if (grantedRights != null) { - right = grantedRights.get(table); - if (right != null) { - if ((right.getRightMask() & rightMask) == rightMask) { - return true; - } - } - } - if (grantedRoles != null) { - for (RightOwner role : grantedRoles.keySet()) { - if (role.isRightGrantedRecursive(table, rightMask)) { - return true; - } - } - } - return false; - } - - /** - * Grant a right for the given table. Only one right object per table is - * supported. - * - * @param table the table - * @param right the right - */ - public void grantRight(Table table, Right right) { - if (grantedRights == null) { - grantedRights = New.hashMap(); - } - grantedRights.put(table, right); - } - - /** - * Revoke the right for the given table. - * - * @param table the table - */ - public void revokeRight(Table table) { - if (grantedRights == null) { - return; - } - grantedRights.remove(table); - if (grantedRights.size() == 0) { - grantedRights = null; - } - } - - /** - * Grant a role to this object. - * - * @param role the role - * @param right the right to grant - */ - public void grantRole(Role role, Right right) { - if (grantedRoles == null) { - grantedRoles = New.hashMap(); - } - grantedRoles.put(role, right); - } - - /** - * Remove the right for the given role. - * - * @param role the role to revoke - * @throws SQLException if the right has not been granted - */ - public void revokeRole(Role role) { - if (grantedRoles == null) { - return; - } - Right right = grantedRoles.get(role); - if (right == null) { - return; - } - grantedRoles.remove(role); - if (grantedRoles.size() == 0) { - grantedRoles = null; - } - } - - /** - * Get the 'grant table' right of this object. - * - * @param table the granted table - * @return the right or null if the right has not been granted - */ - public Right getRightForTable(Table table) { - if (grantedRights == null) { - return null; - } - return grantedRights.get(table); - } - - /** - * Get the 'grant role' right of this object. - * - * @param role the granted role - * @return the right or null if the right has not been granted - */ - public Right getRightForRole(Role role) { - if (grantedRoles == null) { - return null; - } - return grantedRoles.get(role); - } - -} diff --git a/tools/h2/src/main/org/h2/engine/Role.java b/tools/h2/src/main/org/h2/engine/Role.java deleted file mode 100755 index 4eb2554..0000000 --- a/tools/h2/src/main/org/h2/engine/Role.java +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.engine; - -import org.h2.message.DbException; -import org.h2.message.Trace; -import org.h2.table.Table; - -/** - * Represents a role. Roles can be granted to users, and to other roles. - */ -public class Role extends RightOwner { - - private final boolean system; - - public Role(Database database, int id, String roleName, boolean system) { - super(database, id, roleName, Trace.USER); - this.system = system; - } - - public String getCreateSQLForCopy(Table table, String quotedName) { - throw DbException.throwInternalError(); - } - - public String getDropSQL() { - return null; - } - - /** - * Get the CREATE SQL statement for this object. - * - * @param ifNotExists true if IF NOT EXISTS should be used - * @return the SQL statement - */ - public String getCreateSQL(boolean ifNotExists) { - if (system) { - return null; - } - StringBuilder buff = new StringBuilder("CREATE ROLE "); - if (ifNotExists) { - buff.append("IF NOT EXISTS "); - } - buff.append(getSQL()); - return buff.toString(); - } - - public String getCreateSQL() { - return getCreateSQL(false); - } - - public int getType() { - return DbObject.ROLE; - } - - public void removeChildrenAndResources(Session session) { - for (User user : database.getAllUsers()) { - Right right = user.getRightForRole(this); - if (right != null) { - database.removeDatabaseObject(session, right); - } - } - for (Role r2 : database.getAllRoles()) { - Right right = r2.getRightForRole(this); - if (right != null) { - database.removeDatabaseObject(session, right); - } - } - for (Right right : database.getAllRights()) { - if (right.getGrantee() == this) { - database.removeDatabaseObject(session, right); - } - } - database.removeMeta(session, getId()); - invalidate(); - } - - public void checkRename() { - // ok - } - -} diff --git a/tools/h2/src/main/org/h2/engine/Session.java b/tools/h2/src/main/org/h2/engine/Session.java deleted file mode 100755 index 0242a9d..0000000 --- a/tools/h2/src/main/org/h2/engine/Session.java +++ /dev/null @@ -1,1202 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.engine; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Random; -import org.h2.command.Command; -import org.h2.command.CommandInterface; -import org.h2.command.Parser; -import org.h2.command.Prepared; -import org.h2.command.dml.SetTypes; -import org.h2.constant.ErrorCode; -import org.h2.constant.SysProperties; -import org.h2.constraint.Constraint; -import org.h2.index.Index; -import org.h2.jdbc.JdbcConnection; -import org.h2.message.DbException; -import org.h2.message.Trace; -import org.h2.message.TraceSystem; -import org.h2.result.ResultInterface; -import org.h2.result.Row; -import org.h2.schema.Schema; -import org.h2.store.DataHandler; -import org.h2.store.InDoubtTransaction; -import org.h2.store.LobStorage; -import org.h2.table.Table; -import org.h2.util.New; -import org.h2.value.Value; -import org.h2.value.ValueLong; -import org.h2.value.ValueNull; -import org.h2.value.ValueString; - -/** - * A session represents an embedded database connection. When using the server - * mode, this object resides on the server side and communicates with a - * SessionRemote object on the client side. - */ -public class Session extends SessionWithState implements SessionFactory { - - /** - * This special log position means that the log entry has been written. - */ - public static final int LOG_WRITTEN = -1; - - /** - * The prefix of generated identifiers. It may not have letters, because - * they are case sensitive. - */ - private static final String SYSTEM_IDENTIFIER_PREFIX = "_"; - private static int nextSerialId; - - private final int serialId = nextSerialId++; - private Database database; - private ConnectionInfo connectionInfo; - private User user; - private int id; - private ArrayList
locks = New.arrayList(); - private UndoLog undoLog; - private boolean autoCommit = true; - private Random random; - private int lockTimeout; - private Value lastIdentity = ValueLong.get(0); - private Value scopeIdentity = ValueLong.get(0); - private int firstUncommittedLog = Session.LOG_WRITTEN; - private int firstUncommittedPos = Session.LOG_WRITTEN; - private HashMap savepoints; - private Exception openStackTrace = new Exception(); - private HashMap localTempTables; - private HashMap localTempTableIndexes; - private HashMap localTempTableConstraints; - private int throttle; - private long lastThrottle; - private Command currentCommand; - private boolean allowLiterals; - private String currentSchemaName; - private String[] schemaSearchPath; - private String traceModuleName; - private HashMap unlinkLobMap; - private int systemIdentifier; - private HashMap procedures; - private boolean undoLogEnabled = true; - private boolean redoLogBinary = true; - private boolean autoCommitAtTransactionEnd; - private String currentTransactionName; - private volatile long cancelAt; - private boolean closed; - private long sessionStart = System.currentTimeMillis(); - private long currentCommandStart; - private HashMap variables; - private HashSet temporaryResults; - private int queryTimeout = SysProperties.getMaxQueryTimeout(); - private boolean commitOrRollbackDisabled; - private Table waitForLock; - private int modificationId; - private int modificationIdState; - private int objectId; - - public Session() { - // to create a new session using the factory - } - - public Session(Database database, User user, int id) { - this.database = database; - this.undoLog = new UndoLog(this); - this.user = user; - this.id = id; - Setting setting = database.findSetting(SetTypes.getTypeName(SetTypes.DEFAULT_LOCK_TIMEOUT)); - this.lockTimeout = setting == null ? Constants.INITIAL_LOCK_TIMEOUT : setting.getIntValue(); - this.currentSchemaName = Constants.SCHEMA_MAIN; - } - - public SessionInterface createSession(ConnectionInfo ci) { - return Engine.getInstance().getSession(ci); - } - - public boolean setCommitOrRollbackDisabled(boolean x) { - boolean old = commitOrRollbackDisabled; - commitOrRollbackDisabled = x; - return old; - } - - private void initVariables() { - if (variables == null) { - variables = New.hashMap(); - } - } - - /** - * Set the value of the given variable for this session. - * - * @param name the name of the variable (may not be null) - * @param value the new value (may not be null) - */ - public void setVariable(String name, Value value) { - initVariables(); - modificationId++; - Value old; - if (value == ValueNull.INSTANCE) { - old = variables.remove(name); - } else { - // link LOB values, to make sure we have our own object - value = value.link(database, LobStorage.TABLE_ID_SESSION_VARIABLE); - old = variables.put(name, value); - } - if (old != null) { - // close the old value (in case it is a lob) - old.unlink(); - old.close(); - } - } - - /** - * Get the value of the specified user defined variable. This method always - * returns a value; it returns ValueNull.INSTANCE if the variable doesn't - * exist. - * - * @param name the variable name - * @return the value, or NULL - */ - public Value getVariable(String name) { - initVariables(); - Value v = variables.get(name); - return v == null ? ValueNull.INSTANCE : v; - } - - /** - * Get the list of variable names that are set for this session. - * - * @return the list of names - */ - public String[] getVariableNames() { - if (variables == null) { - return new String[0]; - } - String[] list = new String[variables.size()]; - variables.keySet().toArray(list); - return list; - } - - /** - * Get the local temporary table if one exists with that name, or null if - * not. - * - * @param name the table name - * @return the table, or null - */ - public Table findLocalTempTable(String name) { - if (localTempTables == null) { - return null; - } - return localTempTables.get(name); - } - - public ArrayList
getLocalTempTables() { - if (localTempTables == null) { - return New.arrayList(); - } - return New.arrayList(localTempTables.values()); - } - - /** - * Add a local temporary table to this session. - * - * @param table the table to add - * @throws SQLException if a table with this name already exists - */ - public void addLocalTempTable(Table table) { - if (localTempTables == null) { - localTempTables = New.hashMap(); - } - if (localTempTables.get(table.getName()) != null) { - throw DbException.get(ErrorCode.TABLE_OR_VIEW_ALREADY_EXISTS_1, table.getSQL()); - } - modificationId++; - localTempTables.put(table.getName(), table); - } - - /** - * Drop and remove the given local temporary table from this session. - * - * @param table the table - */ - public void removeLocalTempTable(Table table) { - modificationId++; - localTempTables.remove(table.getName()); - synchronized (database) { - table.removeChildrenAndResources(this); - } - } - - /** - * Get the local temporary index if one exists with that name, or null if - * not. - * - * @param name the table name - * @return the table, or null - */ - public Index findLocalTempTableIndex(String name) { - if (localTempTableIndexes == null) { - return null; - } - return localTempTableIndexes.get(name); - } - - public HashMap getLocalTempTableIndexes() { - if (localTempTableIndexes == null) { - return New.hashMap(); - } - return localTempTableIndexes; - } - - /** - * Add a local temporary index to this session. - * - * @param index the index to add - * @throws SQLException if a index with this name already exists - */ - public void addLocalTempTableIndex(Index index) { - if (localTempTableIndexes == null) { - localTempTableIndexes = New.hashMap(); - } - if (localTempTableIndexes.get(index.getName()) != null) { - throw DbException.get(ErrorCode.INDEX_ALREADY_EXISTS_1, index.getSQL()); - } - localTempTableIndexes.put(index.getName(), index); - } - - /** - * Drop and remove the given local temporary index from this session. - * - * @param index the index - */ - public void removeLocalTempTableIndex(Index index) { - if (localTempTableIndexes != null) { - localTempTableIndexes.remove(index.getName()); - synchronized (database) { - index.removeChildrenAndResources(this); - } - } - } - - /** - * Get the local temporary constraint if one exists with that name, or - * null if not. - * - * @param name the constraint name - * @return the constraint, or null - */ - public Constraint findLocalTempTableConstraint(String name) { - if (localTempTableConstraints == null) { - return null; - } - return localTempTableConstraints.get(name); - } - - /** - * Get the map of constraints for all constraints on local, temporary - * tables, if any. The map's keys are the constraints' names. - * - * @return the map of constraints, or null - */ - public HashMap getLocalTempTableConstraints() { - if (localTempTableConstraints == null) { - return New.hashMap(); - } - return localTempTableConstraints; - } - - /** - * Add a local temporary constraint to this session. - * - * @param constraint the constraint to add - * @throws SQLException if a constraint with the same name already exists - */ - public void addLocalTempTableConstraint(Constraint constraint) { - if (localTempTableConstraints == null) { - localTempTableConstraints = New.hashMap(); - } - String name = constraint.getName(); - if (localTempTableConstraints.get(name) != null) { - throw DbException.get(ErrorCode.CONSTRAINT_ALREADY_EXISTS_1, constraint.getSQL()); - } - localTempTableConstraints.put(name, constraint); - } - - /** - * Drop and remove the given local temporary constraint from this session. - * - * @param constraint the constraint - */ - public void removeLocalTempTableConstraint(Constraint constraint) { - if (localTempTableConstraints != null) { - localTempTableConstraints.remove(constraint.getName()); - synchronized (database) { - constraint.removeChildrenAndResources(this); - } - } - } - - protected void finalize() { - if (!SysProperties.runFinalize) { - return; - } - if (!closed) { - throw new RuntimeException("Not closed", openStackTrace); - } - } - - public boolean getAutoCommit() { - return autoCommit; - } - - public User getUser() { - return user; - } - - /** - * Change the autocommit setting for this session. - * - * @param b the new value - */ - public void setAutoCommit(boolean b) { - autoCommit = b; - } - - public int getLockTimeout() { - return lockTimeout; - } - - public void setLockTimeout(int lockTimeout) { - this.lockTimeout = lockTimeout; - } - - public CommandInterface prepareCommand(String sql, int fetchSize) { - return prepareLocal(sql); - } - - /** - * Parse and prepare the given SQL statement. This method also checks the - * rights. - * - * @param sql the SQL statement - * @return the prepared statement - */ - public Prepared prepare(String sql) { - return prepare(sql, false); - } - - /** - * Parse and prepare the given SQL statement. - * - * @param sql the SQL statement - * @param rightsChecked true if the rights have already been checked - * @return the prepared statement - */ - public Prepared prepare(String sql, boolean rightsChecked) { - Parser parser = new Parser(this); - parser.setRightsChecked(rightsChecked); - return parser.prepare(sql); - } - - /** - * Parse and prepare the given SQL statement. - * This method also checks if the connection has been closed. - * - * @param sql the SQL statement - * @return the prepared statement - */ - public Command prepareLocal(String sql) { - if (closed) { - throw DbException.get(ErrorCode.CONNECTION_BROKEN_1, "session closed"); - } - Parser parser = new Parser(this); - return parser.prepareCommand(sql); - } - - public Database getDatabase() { - return database; - } - - public int getPowerOffCount() { - return database.getPowerOffCount(); - } - - public void setPowerOffCount(int count) { - database.setPowerOffCount(count); - } - - /** - * Commit the current transaction. If the statement was not a data - * definition statement, and if there are temporary tables that should be - * dropped or truncated at commit, this is done as well. - * - * @param ddl if the statement was a data definition statement - */ - public void commit(boolean ddl) { - checkCommitRollback(); - currentTransactionName = null; - if (containsUncommitted()) { - // need to commit even if rollback is not possible - // (create/drop table and so on) - database.commit(this); - } - if (undoLog.size() > 0) { - // commit the rows when using MVCC - if (database.isMultiVersion()) { - ArrayList rows = New.arrayList(); - synchronized (database) { - while (undoLog.size() > 0) { - UndoLogRecord entry = undoLog.getLast(); - entry.commit(); - rows.add(entry.getRow()); - undoLog.removeLast(false); - } - for (Row r : rows) { - r.commit(); - } - } - } - undoLog.clear(); - } - if (!ddl) { - // do not clean the temp tables if the last command was a - // create/drop - cleanTempTables(false); - if (autoCommitAtTransactionEnd) { - autoCommit = true; - autoCommitAtTransactionEnd = false; - } - } - if (unlinkLobMap != null && unlinkLobMap.size() > 0) { - // need to flush the transaction log, because we can't unlink lobs if the - // commit record is not written - database.flush(); - for (Value v : unlinkLobMap.values()) { - v.unlink(); - } - unlinkLobMap = null; - } - unlockAll(); - } - - private void checkCommitRollback() { - if (commitOrRollbackDisabled && locks.size() > 0) { - throw DbException.get(ErrorCode.COMMIT_ROLLBACK_NOT_ALLOWED); - } - } - - /** - * Fully roll back the current transaction. - */ - public void rollback() { - checkCommitRollback(); - currentTransactionName = null; - boolean needCommit = false; - if (undoLog.size() > 0) { - rollbackTo(0, false); - needCommit = true; - } - if (locks.size() > 0 || needCommit) { - database.commit(this); - } - cleanTempTables(false); - unlockAll(); - if (autoCommitAtTransactionEnd) { - autoCommit = true; - autoCommitAtTransactionEnd = false; - } - } - - /** - * Partially roll back the current transaction. - * - * @param index the position to which should be rolled back - * @param trimToSize if the list should be trimmed - */ - public void rollbackTo(int index, boolean trimToSize) { - while (undoLog.size() > index) { - UndoLogRecord entry = undoLog.getLast(); - entry.undo(this); - undoLog.removeLast(trimToSize); - } - if (savepoints != null) { - String[] names = new String[savepoints.size()]; - savepoints.keySet().toArray(names); - for (String name : names) { - Integer savepointIndex = savepoints.get(name); - if (savepointIndex.intValue() > index) { - savepoints.remove(name); - } - } - } - } - - public int getLogId() { - return undoLog.size(); - } - - public int getId() { - return id; - } - - public void cancel() { - cancelAt = System.currentTimeMillis(); - } - - public void close() { - if (!closed) { - try { - database.checkPowerOff(); - cleanTempTables(true); - undoLog.clear(); - database.removeSession(this); - } finally { - closed = true; - } - } - } - - /** - * Add a lock for the given table. The object is unlocked on commit or - * rollback. - * - * @param table the table that is locked - */ - public void addLock(Table table) { - if (SysProperties.CHECK) { - if (locks.indexOf(table) >= 0) { - DbException.throwInternalError(); - } - } - locks.add(table); - } - - /** - * Add an undo log entry to this session. - * - * @param table the table - * @param type the operation type (see {@link UndoLogRecord}) - * @param row the row - */ - public void log(Table table, short type, Row row) { - log(new UndoLogRecord(table, type, row)); - } - - private void log(UndoLogRecord log) { - // called _after_ the row was inserted successfully into the table, - // otherwise rollback will try to rollback a not-inserted row - if (SysProperties.CHECK) { - int lockMode = database.getLockMode(); - if (lockMode != Constants.LOCK_MODE_OFF && !database.isMultiVersion()) { - String type = log.getTable().getTableType(); - if (locks.indexOf(log.getTable()) < 0 - && !Table.TABLE_LINK.equals(type) - && !Table.EXTERNAL_TABLE_ENGINE.equals(type)) { - DbException.throwInternalError(); - } - } - } - if (undoLogEnabled) { - undoLog.add(log); - } else { - log.commit(); - log.getRow().commit(); - } - } - - /** - * Unlock all read locks. This is done if the transaction isolation mode is - * READ_COMMITTED. - */ - public void unlockReadLocks() { - if (database.isMultiVersion()) { - // MVCC: keep shared locks (insert / update / delete) - return; - } - for (int i = 0; i < locks.size(); i++) { - Table t = locks.get(i); - if (!t.isLockedExclusively()) { - synchronized (database) { - t.unlock(this); - locks.remove(i); - } - i--; - } - } - } - - /** - * Unlock just this table. - * - * @param t the table to unlock - */ - public void unlock(Table t) { - locks.remove(t); - } - - private void unlockAll() { - if (SysProperties.CHECK) { - if (undoLog.size() > 0) { - DbException.throwInternalError(); - } - } - if (locks.size() > 0) { - synchronized (database) { - for (Table t : locks) { - t.unlock(this); - } - locks.clear(); - } - } - savepoints = null; - if (modificationIdState != modificationId) { - sessionStateChanged = true; - } - } - - private void cleanTempTables(boolean closeSession) { - if (localTempTables != null && localTempTables.size() > 0) { - synchronized (database) { - for (Table table : New.arrayList(localTempTables.values())) { - if (closeSession || table.getOnCommitDrop()) { - modificationId++; - table.setModified(); - localTempTables.remove(table.getName()); - table.removeChildrenAndResources(this); - } else if (table.getOnCommitTruncate()) { - table.truncate(this); - } - } - } - } - } - - public Random getRandom() { - if (random == null) { - random = new Random(); - } - return random; - } - - public Trace getTrace() { - if (traceModuleName == null) { - traceModuleName = Trace.JDBC + "[" + id + "]"; - } - if (closed) { - return new TraceSystem(null).getTrace(traceModuleName); - } - return database.getTrace(traceModuleName); - } - - public void setLastIdentity(Value last) { - this.scopeIdentity = last; - this.lastIdentity = last; - } - - public Value getLastIdentity() { - return lastIdentity; - } - - /** - * Called when a log entry for this session is added. The session keeps - * track of the first entry in the transaction log that is not yet committed. - * - * @param logId the transaction log id - * @param pos the position of the log entry in the transaction log - */ - public void addLogPos(int logId, int pos) { - if (firstUncommittedLog == Session.LOG_WRITTEN) { - firstUncommittedLog = logId; - firstUncommittedPos = pos; - } - } - - public int getFirstUncommittedLog() { - return firstUncommittedLog; - } - - /** - * This method is called after the transaction log has written the commit - * entry for this session. - */ - public void setAllCommitted() { - firstUncommittedLog = Session.LOG_WRITTEN; - firstUncommittedPos = Session.LOG_WRITTEN; - } - - private boolean containsUncommitted() { - return firstUncommittedLog != Session.LOG_WRITTEN; - } - - /** - * Create a savepoint that is linked to the current log position. - * - * @param name the savepoint name - */ - public void addSavepoint(String name) { - if (savepoints == null) { - savepoints = New.hashMap(); - } - savepoints.put(name, getLogId()); - } - - /** - * Undo all operations back to the log position of the given savepoint. - * - * @param name the savepoint name - */ - public void rollbackToSavepoint(String name) { - checkCommitRollback(); - if (savepoints == null) { - throw DbException.get(ErrorCode.SAVEPOINT_IS_INVALID_1, name); - } - Integer savepointIndex = savepoints.get(name); - if (savepointIndex == null) { - throw DbException.get(ErrorCode.SAVEPOINT_IS_INVALID_1, name); - } - int i = savepointIndex.intValue(); - rollbackTo(i, false); - } - - /** - * Prepare the given transaction. - * - * @param transactionName the name of the transaction - */ - public void prepareCommit(String transactionName) { - if (containsUncommitted()) { - // need to commit even if rollback is not possible (create/drop - // table and so on) - database.prepareCommit(this, transactionName); - } - currentTransactionName = transactionName; - } - - /** - * Commit or roll back the given transaction. - * - * @param transactionName the name of the transaction - * @param commit true for commit, false for rollback - */ - public void setPreparedTransaction(String transactionName, boolean commit) { - if (currentTransactionName != null && currentTransactionName.equals(transactionName)) { - if (commit) { - commit(false); - } else { - rollback(); - } - } else { - ArrayList list = database.getInDoubtTransactions(); - int state = commit ? InDoubtTransaction.COMMIT : InDoubtTransaction.ROLLBACK; - boolean found = false; - if (list != null) { - for (InDoubtTransaction p: list) { - if (p.getTransaction().equals(transactionName)) { - p.setState(state); - found = true; - break; - } - } - } - if (!found) { - throw DbException.get(ErrorCode.TRANSACTION_NOT_FOUND_1, transactionName); - } - } - } - - public boolean isClosed() { - return closed; - } - - public void setThrottle(int throttle) { - this.throttle = throttle; - } - - /** - * Wait for some time if this session is throttled (slowed down). - */ - public void throttle() { - if (throttle == 0) { - return; - } - long time = System.currentTimeMillis(); - if (lastThrottle + Constants.THROTTLE_DELAY > time) { - return; - } - lastThrottle = time + throttle; - try { - Thread.sleep(throttle); - } catch (Exception e) { - // ignore InterruptedException - } - } - - /** - * Set the current command of this session. This is done just before - * executing the statement. - * - * @param command the command - * @param startTime the time execution has been started - */ - public void setCurrentCommand(Command command, long startTime) { - this.currentCommand = command; - this.currentCommandStart = startTime; - if (queryTimeout > 0 && startTime != 0) { - cancelAt = startTime + queryTimeout; - } - } - - /** - * Check if the current transaction is canceled by calling - * Statement.cancel() or because a session timeout was set and expired. - * - * @throws SQLException if the transaction is canceled - */ - public void checkCanceled() { - throttle(); - if (cancelAt == 0) { - return; - } - long time = System.currentTimeMillis(); - if (time >= cancelAt) { - cancelAt = 0; - throw DbException.get(ErrorCode.STATEMENT_WAS_CANCELED); - } - } - - /** - * Get the cancel time. - * - * @return the time or 0 if not set - */ - public long getCancel() { - return cancelAt; - } - - public Command getCurrentCommand() { - return currentCommand; - } - - public long getCurrentCommandStart() { - return currentCommandStart; - } - - public boolean getAllowLiterals() { - return allowLiterals; - } - - public void setAllowLiterals(boolean b) { - this.allowLiterals = b; - } - - public void setCurrentSchema(Schema schema) { - modificationId++; - this.currentSchemaName = schema.getName(); - } - - public String getCurrentSchemaName() { - return currentSchemaName; - } - - /** - * Create an internal connection. This connection is used when initializing - * triggers, and when calling user defined functions. - * - * @param columnList if the url should be 'jdbc:columnlist:connection' - * @return the internal connection - */ - public JdbcConnection createConnection(boolean columnList) { - String url; - if (columnList) { - url = Constants.CONN_URL_COLUMNLIST; - } else { - url = Constants.CONN_URL_INTERNAL; - } - return new JdbcConnection(this, getUser().getName(), url); - } - - public DataHandler getDataHandler() { - return database; - } - - /** - * Remember that the given LOB value must be un-linked (disconnected from - * the table) at commit. - * - * @param v the value - */ - public void unlinkAtCommit(Value v) { - if (SysProperties.CHECK && !v.isLinked()) { - DbException.throwInternalError(); - } - if (unlinkLobMap == null) { - unlinkLobMap = New.hashMap(); - } - unlinkLobMap.put(v.toString(), v); - } - - /** - * Do not unlink this LOB value at commit any longer. - * - * @param v the value - */ - public void unlinkAtCommitStop(Value v) { - if (unlinkLobMap != null) { - unlinkLobMap.remove(v.toString()); - } - } - - /** - * Get the next system generated identifiers. The identifier returned does - * not occur within the given SQL statement. - * - * @param sql the SQL statement - * @return the new identifier - */ - public String getNextSystemIdentifier(String sql) { - String identifier; - do { - identifier = SYSTEM_IDENTIFIER_PREFIX + systemIdentifier++; - } while (sql.indexOf(identifier) >= 0); - return identifier; - } - - /** - * Add a procedure to this session. - * - * @param procedure the procedure to add - */ - public void addProcedure(Procedure procedure) { - if (procedures == null) { - procedures = New.hashMap(); - } - procedures.put(procedure.getName(), procedure); - } - - /** - * Remove a procedure from this session. - * - * @param name the name of the procedure to remove - */ - public void removeProcedure(String name) { - if (procedures != null) { - procedures.remove(name); - } - } - - /** - * Get the procedure with the given name, or null - * if none exists. - * - * @param name the procedure name - * @return the procedure or null - */ - public Procedure getProcedure(String name) { - if (procedures == null) { - return null; - } - return procedures.get(name); - } - - public void setSchemaSearchPath(String[] schemas) { - modificationId++; - this.schemaSearchPath = schemas; - } - - public String[] getSchemaSearchPath() { - return schemaSearchPath; - } - - public int hashCode() { - return serialId; - } - - public String toString() { - return "#" + serialId + " (user: " + user.getName() + ")"; - } - - public void setUndoLogEnabled(boolean b) { - this.undoLogEnabled = b; - } - - public void setRedoLogBinary(boolean b) { - this.redoLogBinary = b; - } - - public boolean isUndoLogEnabled() { - return undoLogEnabled; - } - - /** - * Begin a transaction. - */ - public void begin() { - autoCommitAtTransactionEnd = true; - autoCommit = false; - } - - public long getSessionStart() { - return sessionStart; - } - - public Table[] getLocks() { - synchronized (database) { - Table[] list = new Table[locks.size()]; - locks.toArray(list); - return list; - } - } - - /** - * Wait if the exclusive mode has been enabled for another session. This - * method returns as soon as the exclusive mode has been disabled. - */ - public void waitIfExclusiveModeEnabled() { - while (true) { - Session exclusive = database.getExclusiveSession(); - if (exclusive == null || exclusive == this) { - break; - } - try { - Thread.sleep(100); - } catch (InterruptedException e) { - // ignore - } - } - } - - /** - * Remember the result set and close it as soon as the transaction is - * committed (if it needs to be closed). This is done to delete temporary - * files as soon as possible, and free object ids of temporary tables. - * - * @param result the temporary result set - */ - public void addTemporaryResult(ResultInterface result) { - if (!result.needToClose()) { - return; - } - if (temporaryResults == null) { - temporaryResults = New.hashSet(); - } - if (temporaryResults.size() < 100) { - // reference at most 100 result sets to avoid memory problems - temporaryResults.add(result); - } - } - - /** - * Close all temporary result set. This also deletes all temporary files - * held by the result sets. - */ - public void closeTemporaryResults() { - if (temporaryResults != null) { - for (ResultInterface result : temporaryResults) { - result.close(); - } - temporaryResults = null; - } - } - - public void setQueryTimeout(int queryTimeout) { - int max = SysProperties.getMaxQueryTimeout(); - if (max != 0 && (max < queryTimeout || queryTimeout == 0)) { - // the value must be at most max - queryTimeout = max; - } - this.queryTimeout = queryTimeout; - // must reset the cancel at here, - // otherwise it is still used - this.cancelAt = 0; - } - - public int getQueryTimeout() { - return queryTimeout; - } - - public void setWaitForLock(Table table) { - this.waitForLock = table; - } - - public Table getWaitForLock() { - return waitForLock; - } - - public int getModificationId() { - return modificationId; - } - - public boolean isReconnectNeeded(boolean write) { - while (true) { - boolean reconnect = database.isReconnectNeeded(); - if (reconnect) { - return true; - } - if (write) { - if (database.beforeWriting()) { - return false; - } - } else { - return false; - } - } - } - - public void afterWriting() { - database.afterWriting(); - } - - public SessionInterface reconnect(boolean write) { - readSessionState(); - close(); - Session newSession = Engine.getInstance().getSession(connectionInfo); - newSession.sessionState = sessionState; - newSession.recreateSessionState(); - if (write) { - while (!newSession.database.beforeWriting()) { - // wait until we are allowed to write - } - } - return newSession; - } - - public void setConnectionInfo(ConnectionInfo ci) { - connectionInfo = ci; - } - - public Value getTransactionId() { - if (undoLog.size() == 0 || !database.isPersistent()) { - return ValueNull.INSTANCE; - } - return ValueString.get(firstUncommittedLog + "-" + firstUncommittedPos + "-" + id); - } - - /** - * Get the next object id. - * - * @return the next object id - */ - public int nextObjectId() { - return objectId++; - } - - public void setScopeIdentity(Value scopeIdentity) { - this.scopeIdentity = scopeIdentity; - } - - public Value getScopeIdentity() { - return scopeIdentity; - } - - public boolean isRedoLogBinaryEnabled() { - return redoLogBinary; - } - -} diff --git a/tools/h2/src/main/org/h2/engine/SessionFactory.java b/tools/h2/src/main/org/h2/engine/SessionFactory.java deleted file mode 100755 index 97be87d..0000000 --- a/tools/h2/src/main/org/h2/engine/SessionFactory.java +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.engine; - -import java.sql.SQLException; - -/** - * A class that implements this interface can create new database sessions. - */ -public interface SessionFactory { - - /** - * Create a new session. - * - * @param ci the connection parameters - * @return the new session - */ - SessionInterface createSession(ConnectionInfo ci) throws SQLException; - -} diff --git a/tools/h2/src/main/org/h2/engine/SessionInterface.java b/tools/h2/src/main/org/h2/engine/SessionInterface.java deleted file mode 100755 index 67ccfb8..0000000 --- a/tools/h2/src/main/org/h2/engine/SessionInterface.java +++ /dev/null @@ -1,96 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.engine; - -import org.h2.command.CommandInterface; -import org.h2.message.Trace; -import org.h2.store.DataHandler; - -/** - * A local or remote session. A session represents a database connection. - */ -public interface SessionInterface { - - /** - * Parse a command and prepare it for execution. - * - * @param sql the SQL statement - * @param fetchSize the number of rows to fetch in one step - * @return the prepared command - */ - CommandInterface prepareCommand(String sql, int fetchSize); - - /** - * Roll back pending transactions and close the session. - */ - void close(); - - /** - * Get the trace object - * - * @return the trace object - */ - Trace getTrace(); - - /** - * Check if close was called. - * - * @return if the session has been closed - */ - boolean isClosed(); - - /** - * Get the number of disk operations before power failure is simulated. - * This is used for testing. If not set, 0 is returned - * - * @return the number of operations, or 0 - */ - int getPowerOffCount(); - - /** - * Set the number of disk operations before power failure is simulated. - * To disable the countdown, use 0. - * - * @param i the number of operations - */ - void setPowerOffCount(int i); - - /** - * Get the data handler object. - * - * @return the data handler - */ - DataHandler getDataHandler(); - - /** - * Cancel the current or next command (called when closing a connection). - */ - void cancel(); - - /** - * Check if the database changed and therefore reconnecting is required. - * - * @param write if the next operation may be writing - * @return true if reconnecting is required - */ - boolean isReconnectNeeded(boolean write); - - /** - * Close the connection and open a new connection. - * - * @param write if the next operation may be writing - * @return the new connection - */ - SessionInterface reconnect(boolean write); - - /** - * Called after writing has ended. It needs to be called after - * isReconnectNeeded(true) returned false. - */ - void afterWriting(); - -} diff --git a/tools/h2/src/main/org/h2/engine/SessionRemote.java b/tools/h2/src/main/org/h2/engine/SessionRemote.java deleted file mode 100755 index 82706d5..0000000 --- a/tools/h2/src/main/org/h2/engine/SessionRemote.java +++ /dev/null @@ -1,663 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.engine; - -import java.io.IOException; -import java.net.Socket; -import java.sql.Connection; -import java.util.ArrayList; -import org.h2.api.DatabaseEventListener; -import org.h2.command.CommandInterface; -import org.h2.command.CommandRemote; -import org.h2.command.dml.SetTypes; -import org.h2.constant.ErrorCode; -import org.h2.constant.SysProperties; -import org.h2.expression.ParameterInterface; -import org.h2.jdbc.JdbcSQLException; -import org.h2.message.DbException; -import org.h2.message.Trace; -import org.h2.message.TraceSystem; -import org.h2.result.ResultInterface; -import org.h2.store.DataHandler; -import org.h2.store.FileStore; -import org.h2.store.LobStorage; -import org.h2.util.IOUtils; -import org.h2.util.MathUtils; -import org.h2.util.NetUtils; -import org.h2.util.New; -import org.h2.util.SmallLRUCache; -import org.h2.util.StringUtils; -import org.h2.util.TempFileDeleter; -import org.h2.util.Utils; -import org.h2.value.Transfer; -import org.h2.value.Value; -import org.h2.value.ValueString; - -/** - * The client side part of a session when using the server mode. This object - * communicates with a Session on the server side. - */ -public class SessionRemote extends SessionWithState implements SessionFactory, DataHandler { - - public static final int SESSION_PREPARE = 0; - public static final int SESSION_CLOSE = 1; - public static final int COMMAND_EXECUTE_QUERY = 2; - public static final int COMMAND_EXECUTE_UPDATE = 3; - public static final int COMMAND_CLOSE = 4; - public static final int RESULT_FETCH_ROWS = 5; - public static final int RESULT_RESET = 6; - public static final int RESULT_CLOSE = 7; - public static final int COMMAND_COMMIT = 8; - public static final int CHANGE_ID = 9; - public static final int COMMAND_GET_META_DATA = 10; - public static final int SESSION_PREPARE_READ_PARAMS = 11; - public static final int SESSION_SET_ID = 12; - public static final int SESSION_CANCEL_STATEMENT = 13; - public static final int SESSION_CHECK_KEY = 14; - - public static final int STATUS_ERROR = 0; - public static final int STATUS_OK = 1; - public static final int STATUS_CLOSED = 2; - public static final int STATUS_OK_STATE_CHANGED = 3; - - private TraceSystem traceSystem; - private Trace trace; - private ArrayList transferList = New.arrayList(); - private int nextId; - private boolean autoCommit = true; - private CommandInterface switchOffAutoCommit; - private ConnectionInfo connectionInfo; - private String databaseName; - private String cipher; - private byte[] fileEncryptionKey; - private Object lobSyncObject = new Object(); - private String sessionId; - private int clientVersion = Constants.TCP_PROTOCOL_VERSION; - private boolean autoReconnect; - private int lastReconnect; - private SessionInterface embedded; - private DatabaseEventListener eventListener; - private LobStorage lobStorage; - private boolean cluster; - - public SessionRemote() { - // nothing to do - } - - private SessionRemote(ConnectionInfo ci) { - this.connectionInfo = ci; - } - - private Transfer initTransfer(ConnectionInfo ci, String db, String server) throws IOException { - Socket socket = NetUtils.createSocket(server, Constants.DEFAULT_TCP_PORT, ci.isSSL()); - Transfer trans = new Transfer(this); - trans.setSocket(socket); - trans.setSSL(ci.isSSL()); - trans.init(); - trans.writeInt(clientVersion); - trans.writeInt(clientVersion); - trans.writeString(db); - trans.writeString(ci.getOriginalURL()); - trans.writeString(ci.getUserName()); - trans.writeBytes(ci.getUserPasswordHash()); - trans.writeBytes(ci.getFilePasswordHash()); - String[] keys = ci.getKeys(); - trans.writeInt(keys.length); - for (String key : keys) { - trans.writeString(key).writeString(ci.getProperty(key)); - } - try { - done(trans); - if (clientVersion >= Constants.TCP_PROTOCOL_VERSION) { - clientVersion = trans.readInt(); - } - } catch (DbException e) { - trans.close(); - throw e; - } - autoCommit = true; - return trans; - } - - public void cancel() { - // this method is called when closing the connection - // the statement that is currently running is not canceled in this case - // however Statement.cancel is supported - } - - /** - * Cancel the statement with the given id. - * - * @param id the statement id - */ - public void cancelStatement(int id) { - for (Transfer transfer : transferList) { - try { - Transfer trans = transfer.openNewConnection(); - trans.init(); - trans.writeInt(clientVersion); - trans.writeInt(clientVersion); - trans.writeString(null); - trans.writeString(null); - trans.writeString(sessionId); - trans.writeInt(SessionRemote.SESSION_CANCEL_STATEMENT); - trans.writeInt(id); - trans.close(); - } catch (IOException e) { - trace.debug("Could not cancel statement", e); - } - } - } - - private void switchOffAutoCommitIfCluster() { - if (autoCommit && transferList.size() > 1) { - if (switchOffAutoCommit == null) { - switchOffAutoCommit = prepareCommand("SET AUTOCOMMIT FALSE", Integer.MAX_VALUE); - } - // this will call setAutoCommit(false) - switchOffAutoCommit.executeUpdate(); - // so we need to switch it on - autoCommit = true; - cluster = true; - } - } - - public void setAutoCommit(boolean autoCommit) { - this.autoCommit = autoCommit; - } - - /** - * Calls COMMIT if the session is in cluster mode. - */ - public void autoCommitIfCluster() { - if (autoCommit && transferList != null && transferList.size() > 1) { - // server side auto commit is off because of race conditions - // (update set id=1 where id=0, but update set id=2 where id=0 is - // faster) - for (int i = 0, count = 0; i < transferList.size(); i++) { - Transfer transfer = transferList.get(i); - try { - traceOperation("COMMAND_COMMIT", 0); - transfer.writeInt(SessionRemote.COMMAND_COMMIT); - done(transfer); - } catch (IOException e) { - removeServer(e, i--, ++count); - } - } - } - } - - private String getFilePrefix(String dir) { - StringBuilder buff = new StringBuilder(dir); - buff.append('/'); - for (int i = 0; i < databaseName.length(); i++) { - char ch = databaseName.charAt(i); - if (Character.isLetterOrDigit(ch)) { - buff.append(ch); - } else { - buff.append('_'); - } - } - return buff.toString(); - } - - public int getPowerOffCount() { - return 0; - } - - public void setPowerOffCount(int count) { - throw DbException.getUnsupportedException("remote"); - } - - public SessionInterface createSession(ConnectionInfo ci) { - return new SessionRemote(ci).connectEmbeddedOrServer(false); - } - - private SessionInterface connectEmbeddedOrServer(boolean openNew) { - ConnectionInfo ci = connectionInfo; - if (ci.isRemote()) { - connectServer(ci); - return this; - } - // create the session using reflection, - // so that the JDBC layer can be compiled without it - boolean autoServerMode = Boolean.valueOf(ci.getProperty("AUTO_SERVER", "false")).booleanValue(); - ConnectionInfo backup = null; - try { - if (autoServerMode) { - backup = (ConnectionInfo) ci.clone(); - connectionInfo = (ConnectionInfo) ci.clone(); - } - SessionFactory sf = (SessionFactory) Class.forName("org.h2.engine.Session").newInstance(); - if (openNew) { - ci.setProperty("OPEN_NEW", "true"); - } - return sf.createSession(ci); - } catch (Exception re) { - DbException e = DbException.convert(re); - if (e.getErrorCode() == ErrorCode.DATABASE_ALREADY_OPEN_1) { - if (autoServerMode) { - String serverKey = ((JdbcSQLException) e.getSQLException()).getSQL(); - if (serverKey != null) { - backup.setServerKey(serverKey); - // OPEN_NEW must be removed now, otherwise - // opening a session with AUTO_SERVER fails - // if another connection is already open - backup.removeProperty("OPEN_NEW", null); - connectServer(backup); - return this; - } - } - } - throw e; - } - } - - private void connectServer(ConnectionInfo ci) { - String name = ci.getName(); - if (name.startsWith("//")) { - name = name.substring("//".length()); - } - int idx = name.indexOf('/'); - if (idx < 0) { - throw ci.getFormatException(); - } - databaseName = name.substring(idx + 1); - String server = name.substring(0, idx); - traceSystem = new TraceSystem(null); - String traceLevelFile = ci.getProperty(SetTypes.TRACE_LEVEL_FILE, null); - if (traceLevelFile != null) { - int level = Integer.parseInt(traceLevelFile); - String prefix = getFilePrefix(SysProperties.CLIENT_TRACE_DIRECTORY); - try { - String file = IOUtils.createTempFile(prefix, Constants.SUFFIX_TRACE_FILE, false, false); - traceSystem.setFileName(file); - traceSystem.setLevelFile(level); - } catch (IOException e) { - throw DbException.convertIOException(e, prefix); - } - } - String traceLevelSystemOut = ci.getProperty(SetTypes.TRACE_LEVEL_SYSTEM_OUT, null); - if (traceLevelSystemOut != null) { - int level = Integer.parseInt(traceLevelSystemOut); - traceSystem.setLevelSystemOut(level); - } - trace = traceSystem.getTrace(Trace.JDBC); - String serverList = null; - if (server.indexOf(',') >= 0) { - serverList = StringUtils.quoteStringSQL(server); - ci.setProperty("CLUSTER", serverList); - } - autoReconnect = Boolean.valueOf(ci.getProperty("AUTO_RECONNECT", "false")).booleanValue(); - // AUTO_SERVER implies AUTO_RECONNECT - boolean autoServer = Boolean.valueOf(ci.getProperty("AUTO_SERVER", "false")).booleanValue(); - if (autoServer && serverList != null) { - throw DbException.getUnsupportedException("autoServer && serverList != null"); - } - autoReconnect |= autoServer; - if (autoReconnect) { - String className = ci.getProperty("DATABASE_EVENT_LISTENER"); - if (className != null) { - className = StringUtils.trim(className, true, true, "'"); - try { - eventListener = (DatabaseEventListener) Utils.loadUserClass(className).newInstance(); - } catch (Throwable e) { - throw DbException.convert(e); - } - } - } - cipher = ci.getProperty("CIPHER"); - if (cipher != null) { - fileEncryptionKey = MathUtils.secureRandomBytes(32); - } - String[] servers = StringUtils.arraySplit(server, ',', true); - int len = servers.length; - transferList.clear(); - // TODO cluster: support at most 2 connections - boolean switchOffCluster = false; - try { - for (int i = 0; i < len; i++) { - try { - Transfer trans = initTransfer(ci, databaseName, servers[i]); - transferList.add(trans); - } catch (IOException e) { - switchOffCluster = true; - } - } - checkClosed(); - if (switchOffCluster) { - switchOffCluster(); - } - switchOffAutoCommitIfCluster(); - } catch (DbException e) { - traceSystem.close(); - throw e; - } - upgradeClientVersionIfPossible(); - } - - private void upgradeClientVersionIfPossible() { - try { - // TODO check if a newer client version can be used - // not required when sending TCP_DRIVER_VERSION_6 - CommandInterface command = prepareCommand("SELECT VALUE FROM INFORMATION_SCHEMA.SETTINGS WHERE NAME=?", 1); - ParameterInterface param = command.getParameters().get(0); - param.setValue(ValueString.get("info.BUILD_ID"), false); - ResultInterface result = command.executeQuery(1, false); - if (result.next()) { - Value[] v = result.currentRow(); - int version = v[0].getInt(); - if (version > 71) { - clientVersion = Constants.TCP_PROTOCOL_VERSION; - } - } - result.close(); - } catch (DbException e) { - trace.error("Error trying to upgrade client version", e); - // ignore - } - if (clientVersion >= Constants.TCP_PROTOCOL_VERSION) { - sessionId = Utils.convertBytesToString(MathUtils.secureRandomBytes(32)); - synchronized (this) { - for (Transfer transfer : transferList) { - try { - traceOperation("SESSION_SET_ID", 0); - transfer.writeInt(SessionRemote.SESSION_SET_ID); - transfer.writeString(sessionId); - done(transfer); - } catch (Exception e) { - trace.error("sessionSetId", e); - } - } - } - - } - } - - private void switchOffCluster() { - CommandInterface ci = prepareCommand("SET CLUSTER ''", Integer.MAX_VALUE); - ci.executeUpdate(); - } - - /** - * Remove a server from the list of cluster nodes and disables the cluster - * mode. - * - * @param e the exception (used for debugging) - * @param i the index of the server to remove - * @param count the retry count index - */ - public void removeServer(IOException e, int i, int count) { - transferList.remove(i); - if (transferList.size() == 0 && autoReconnect(count)) { - return; - } - checkClosed(); - switchOffCluster(); - } - - public CommandInterface prepareCommand(String sql, int fetchSize) { - synchronized (this) { - checkClosed(); - return new CommandRemote(this, transferList, sql, fetchSize); - } - } - - /** - * Automatically re-connect if necessary and if configured to do so. - * - * @param count the retry count index - * @return true if reconnected - */ - public boolean autoReconnect(int count) { - if (!isClosed()) { - return false; - } - if (!autoReconnect) { - return false; - } - if (!cluster && !autoCommit) { - return false; - } - if (count > SysProperties.MAX_RECONNECT) { - return false; - } - lastReconnect++; - while (true) { - try { - embedded = connectEmbeddedOrServer(false); - break; - } catch (DbException e) { - if (e.getErrorCode() != ErrorCode.DATABASE_IS_IN_EXCLUSIVE_MODE) { - throw e; - } - // exclusive mode: re-try endlessly - try { - Thread.sleep(500); - } catch (Exception e2) { - // ignore - } - } - } - if (embedded == this) { - // connected to a server somewhere else - embedded = null; - } else { - // opened an embedded connection now - - // must connect to this database in server mode - // unfortunately - connectEmbeddedOrServer(true); - } - recreateSessionState(); - if (eventListener != null) { - eventListener.setProgress(DatabaseEventListener.STATE_RECONNECTED, databaseName, count, - SysProperties.MAX_RECONNECT); - } - return true; - } - - /** - * Check if this session is closed and throws an exception if so. - * - * @throws SQLException if the session is closed - */ - public void checkClosed() { - if (isClosed()) { - throw DbException.get(ErrorCode.CONNECTION_BROKEN_1, "session closed"); - } - } - - public void close() { - if (transferList != null) { - synchronized (this) { - for (Transfer transfer : transferList) { - try { - traceOperation("SESSION_CLOSE", 0); - transfer.writeInt(SessionRemote.SESSION_CLOSE); - done(transfer); - transfer.close(); - } catch (Exception e) { - trace.error("close", e); - } - } - } - transferList = null; - } - traceSystem.close(); - if (embedded != null) { - embedded.close(); - embedded = null; - } - } - - public Trace getTrace() { - return traceSystem.getTrace(Trace.JDBC); - } - - public int getNextId() { - return nextId++; - } - - public int getCurrentId() { - return nextId; - } - - /** - * Called to flush the output after data has been sent to the server and - * just before receiving data. This method also reads the status code from - * the server and throws any exception the server sent. - * - * @param transfer the transfer object - * @throws SQLException if the server sent an exception - * @throws IOException if there is a communication problem between client - * and server - */ - public void done(Transfer transfer) throws IOException { - transfer.flush(); - int status = transfer.readInt(); - if (status == STATUS_ERROR) { - String sqlstate = transfer.readString(); - String message = transfer.readString(); - String sql = transfer.readString(); - int errorCode = transfer.readInt(); - String stackTrace = transfer.readString(); - JdbcSQLException s = new JdbcSQLException(message, sql, sqlstate, errorCode, null, stackTrace); - if (errorCode == ErrorCode.CONNECTION_BROKEN_1) { - // allow re-connect - IOException e = new IOException(s.toString()); - e.initCause(s); - throw e; - } - throw DbException.convert(s); - } else if (status == STATUS_CLOSED) { - transferList = null; - } else if (status == STATUS_OK_STATE_CHANGED) { - sessionStateChanged = true; - } else if (status == STATUS_OK) { - // ok - } else { - throw DbException.get(ErrorCode.CONNECTION_BROKEN_1, "unexpected status " + status); - } - } - - /** - * Returns true if the connection is in cluster mode. - * - * @return true if it is - */ - public boolean isClustered() { - return transferList.size() > 1; - } - - public boolean isClosed() { - return transferList == null || transferList.size() == 0; - } - - /** - * Write the operation to the trace system if debug trace is enabled. - * - * @param operation the operation performed - * @param id the id of the operation - */ - public void traceOperation(String operation, int id) { - if (trace.isDebugEnabled()) { - trace.debug(operation + " " + id); - } - } - - public void checkPowerOff() { - // ok - } - - public void checkWritingAllowed() { - // ok - } - - public void freeUpDiskSpace() { - // nothing to do - } - - public String getDatabasePath() { - return ""; - } - - public String getLobCompressionAlgorithm(int type) { - return null; - } - - public int getMaxLengthInplaceLob() { - return Constants.DEFAULT_MAX_LENGTH_CLIENTSIDE_LOB; - } - - public FileStore openFile(String name, String mode, boolean mustExist) { - if (mustExist && !IOUtils.exists(name)) { - throw DbException.get(ErrorCode.FILE_CORRUPTED_1, name); - } - FileStore store; - if (cipher == null) { - store = FileStore.open(this, name, mode); - } else { - store = FileStore.open(this, name, mode, cipher, fileEncryptionKey, 0); - } - store.setCheckedWriting(false); - try { - store.init(); - } catch (DbException e) { - store.closeSilently(); - throw e; - } - return store; - } - - public DataHandler getDataHandler() { - return this; - } - - public Object getLobSyncObject() { - return lobSyncObject; - } - - public SmallLRUCache getLobFileListCache() { - return null; - } - - public int getClientVersion() { - return clientVersion; - } - - public int getLastReconnect() { - return lastReconnect; - } - - public TempFileDeleter getTempFileDeleter() { - return TempFileDeleter.getInstance(); - } - - public boolean isReconnectNeeded(boolean write) { - return false; - } - - public SessionInterface reconnect(boolean write) { - return this; - } - - public void afterWriting() { - // nothing to do - } - - public LobStorage getLobStorage() { - if (lobStorage == null) { - lobStorage = new LobStorage(this); - } - return lobStorage; - } - - public Connection getLobConnection() { - return null; - } - -} diff --git a/tools/h2/src/main/org/h2/engine/SessionWithState.java b/tools/h2/src/main/org/h2/engine/SessionWithState.java deleted file mode 100755 index e1fde61..0000000 --- a/tools/h2/src/main/org/h2/engine/SessionWithState.java +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.engine; - -import java.util.ArrayList; -import org.h2.command.CommandInterface; -import org.h2.result.ResultInterface; -import org.h2.util.New; -import org.h2.value.Value; - -/** - * The base class for both remote and embedded sessions. - */ -public abstract class SessionWithState implements SessionInterface { - - protected ArrayList sessionState; - protected boolean sessionStateChanged; - private boolean sessionStateUpdating; - - /** - * Re-create the session state using the stored sessionState list. - */ - protected void recreateSessionState() { - if (sessionState != null && sessionState.size() > 0) { - sessionStateUpdating = true; - try { - for (String sql : sessionState) { - CommandInterface ci = prepareCommand(sql, Integer.MAX_VALUE); - ci.executeUpdate(); - } - } finally { - sessionStateUpdating = false; - sessionStateChanged = false; - } - } - } - - /** - * Read the session state if necessary. - */ - public void readSessionState() { - if (!sessionStateChanged || sessionStateUpdating) { - return; - } - sessionStateChanged = false; - sessionState = New.arrayList(); - CommandInterface ci = prepareCommand("SELECT * FROM INFORMATION_SCHEMA.SESSION_STATE", Integer.MAX_VALUE); - ResultInterface result = ci.executeQuery(0, false); - while (result.next()) { - Value[] row = result.currentRow(); - sessionState.add(row[1].getString()); - } - } - -} diff --git a/tools/h2/src/main/org/h2/engine/Setting.java b/tools/h2/src/main/org/h2/engine/Setting.java deleted file mode 100755 index c1e8269..0000000 --- a/tools/h2/src/main/org/h2/engine/Setting.java +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.engine; - -import org.h2.message.DbException; -import org.h2.message.Trace; -import org.h2.table.Table; - -/** - * A persistent database setting. - */ -public class Setting extends DbObjectBase { - - private int intValue; - private String stringValue; - - public Setting(Database database, int id, String settingName) { - initDbObjectBase(database, id, settingName, Trace.SETTING); - } - - public void setIntValue(int value) { - intValue = value; - } - - public int getIntValue() { - return intValue; - } - - public void setStringValue(String value) { - stringValue = value; - } - - public String getStringValue() { - return stringValue; - } - - public String getCreateSQLForCopy(Table table, String quotedName) { - throw DbException.throwInternalError(); - } - - public String getDropSQL() { - return null; - } - - public String getCreateSQL() { - StringBuilder buff = new StringBuilder("SET "); - buff.append(getSQL()).append(' '); - if (stringValue != null) { - buff.append(stringValue); - } else { - buff.append(intValue); - } - return buff.toString(); - } - - public int getType() { - return DbObject.SETTING; - } - - public void removeChildrenAndResources(Session session) { - database.removeMeta(session, getId()); - invalidate(); - } - - public void checkRename() { - throw DbException.getUnsupportedException("RENAME"); - } - -} diff --git a/tools/h2/src/main/org/h2/engine/UndoLog.java b/tools/h2/src/main/org/h2/engine/UndoLog.java deleted file mode 100755 index c21c06e..0000000 --- a/tools/h2/src/main/org/h2/engine/UndoLog.java +++ /dev/null @@ -1,238 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.engine; - -import java.util.ArrayList; -import java.util.HashMap; -import org.h2.constant.SysProperties; -import org.h2.message.DbException; -import org.h2.store.Data; -import org.h2.store.FileStore; -import org.h2.table.Table; -import org.h2.util.New; - -/** - * Each session keeps a undo log if rollback is required. - */ -public class UndoLog { - private Database database; - private ArrayList storedEntriesPos = New.arrayList(); - private ArrayList records = New.arrayList(); - private FileStore file; - private Data rowBuff; - private int memoryUndo; - private int storedEntries; - private HashMap tables; - - /** - * Create a new undo log for the given session. - * - * @param session the session - */ - public UndoLog(Session session) { - this.database = session.getDatabase(); - } - - /** - * Get the number of active rows in this undo log. - * - * @return the number of rows - */ - public int size() { - if (SysProperties.LARGE_TRANSACTIONS) { - return storedEntries + records.size(); - } - if (SysProperties.CHECK && memoryUndo > records.size()) { - DbException.throwInternalError(); - } - return records.size(); - } - - /** - * Clear the undo log. This method is called after the transaction is - * committed. - */ - public void clear() { - records.clear(); - storedEntries = 0; - storedEntriesPos.clear(); - memoryUndo = 0; - if (file != null) { - file.closeAndDeleteSilently(); - file = null; - rowBuff = null; - } - } - - /** - * Get the last record and remove it from the list of operations. - * - * @return the last record - */ - public UndoLogRecord getLast() { - int i = records.size() - 1; - if (SysProperties.LARGE_TRANSACTIONS) { - if (i < 0 && storedEntries > 0) { - int last = storedEntriesPos.size() - 1; - long pos = storedEntriesPos.get(last); - storedEntriesPos.remove(last); - long end = file.length(); - int bufferLength = (int) (end - pos); - Data buff = Data.create(database, bufferLength); - file.seek(pos); - file.readFully(buff.getBytes(), 0, bufferLength); - while (buff.length() < bufferLength) { - UndoLogRecord e = UndoLogRecord.loadFromBuffer(buff, this); - records.add(e); - memoryUndo++; - } - storedEntries -= records.size(); - file.setLength(pos); - file.seek(pos); - } - i = records.size() - 1; - } - UndoLogRecord entry = records.get(i); - if (entry.isStored()) { - int start = Math.max(0, i - database.getMaxMemoryUndo() / 2); - UndoLogRecord first = null; - for (int j = start; j <= i; j++) { - UndoLogRecord e = records.get(j); - if (e.isStored()) { - e.load(rowBuff, file, this); - memoryUndo++; - if (first == null) { - first = e; - } - } - } - for (int k = 0; k < i; k++) { - UndoLogRecord e = records.get(k); - e.invalidatePos(); - } - seek(first.getFilePos()); - } - return entry; - } - - /** - * Go to the right position in the file. - * - * @param file the file - */ - void seek(long filePos) { - file.seek(filePos * Constants.FILE_BLOCK_SIZE); - } - - /** - * Remove the last record from the list of operations. - * - * @param trimToSize if the undo array should shrink to conserve memory - */ - public void removeLast(boolean trimToSize) { - int i = records.size() - 1; - UndoLogRecord r = records.remove(i); - if (!r.isStored()) { - memoryUndo--; - } - if (trimToSize && i > 1024 && (i & 1023) == 0) { - records.trimToSize(); - } - } - - /** - * Append an undo log entry to the log. - * - * @param entry the entry - */ - public void add(UndoLogRecord entry) { - records.add(entry); - if (SysProperties.LARGE_TRANSACTIONS) { - memoryUndo++; - if (memoryUndo > database.getMaxMemoryUndo() && database.isPersistent() && !database.isMultiVersion()) { - if (file == null) { - String fileName = database.createTempFile(); - file = database.openFile(fileName, "rw", false); - file.setLength(FileStore.HEADER_LENGTH); - } - Data buff = Data.create(database, SysProperties.PAGE_SIZE); - for (int i = 0; i < records.size(); i++) { - UndoLogRecord r = records.get(i); - buff.checkCapacity(SysProperties.PAGE_SIZE); - r.append(buff, this); - if (i == records.size() - 1 || buff.length() > Constants.UNDO_BLOCK_SIZE) { - storedEntriesPos.add(file.getFilePointer()); - file.write(buff.getBytes(), 0, buff.length()); - buff.reset(); - } - } - storedEntries += records.size(); - memoryUndo = 0; - records.clear(); - file.autoDelete(); - return; - } - } else { - if (!entry.isStored()) { - memoryUndo++; - } - if (memoryUndo > database.getMaxMemoryUndo() && database.isPersistent() && !database.isMultiVersion()) { - if (file == null) { - String fileName = database.createTempFile(); - file = database.openFile(fileName, "rw", false); - file.seek(FileStore.HEADER_LENGTH); - rowBuff = Data.create(database, SysProperties.PAGE_SIZE); - Data buff = rowBuff; - for (int i = 0; i < records.size(); i++) { - UndoLogRecord r = records.get(i); - saveIfPossible(r, buff); - } - } else { - saveIfPossible(entry, rowBuff); - } - file.autoDelete(); - } - } - } - - private void saveIfPossible(UndoLogRecord r, Data buff) { - if (!r.isStored() && r.canStore()) { - r.save(buff, file, this); - memoryUndo--; - } - } - - /** - * Get the table id for this undo log. If the table is not registered yet, - * this is done as well. - * - * @param table the table - * @return the id - */ - int getTableId(Table table) { - int id = table.getId(); - if (tables == null) { - tables = New.hashMap(); - } - // need to overwrite the old entry, because the old object - // might be deleted in the meantime - tables.put(id, table); - return id; - } - - /** - * Get the table for this id. The table must be registered for this undo log - * first by calling getTableId. - * - * @param id the table id - * @return the table object - */ - Table getTable(int id) { - return tables.get(id); - } - -} diff --git a/tools/h2/src/main/org/h2/engine/UndoLogRecord.java b/tools/h2/src/main/org/h2/engine/UndoLogRecord.java deleted file mode 100755 index 1fb1d1f..0000000 --- a/tools/h2/src/main/org/h2/engine/UndoLogRecord.java +++ /dev/null @@ -1,287 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.engine; - -import org.h2.constant.ErrorCode; -import org.h2.constant.SysProperties; -import org.h2.index.Index; -import org.h2.message.DbException; -import org.h2.result.Row; -import org.h2.store.Data; -import org.h2.store.FileStore; -import org.h2.table.Table; -import org.h2.value.Value; - -/** - * An entry in a undo log. - */ -public class UndoLogRecord { - - /** - * Operation type meaning the row was inserted. - */ - public static final short INSERT = 0; - - /** - * Operation type meaning the row was deleted. - */ - public static final short DELETE = 1; - - private static final int IN_MEMORY = 0, STORED = 1, IN_MEMORY_INVALID = 2; - private Table table; - private Row row; - private short operation; - private short state; - private int filePos; - - /** - * Create a new undo log record - * - * @param table the table - * @param op the operation type - * @param row the row that was deleted or inserted - */ - public UndoLogRecord(Table table, short op, Row row) { - this.table = table; - this.row = row; - this.operation = op; - this.state = IN_MEMORY; - } - - /** - * Check if the log record is stored in the file. - * - * @return true if it is - */ - boolean isStored() { - return state == STORED; - } - - /** - * Check if this undo log record can be store. Only record can be stored if - * the table has a unique index. - * - * @return if it can be stored - */ - boolean canStore() { - if (SysProperties.LARGE_TRANSACTIONS) { - // actually the method is not called in this case - return true; - } - if (table.getUniqueIndex() != null) { - return true; - } - return false; - } - - /** - * Un-do the operation. If the row was inserted before, it is deleted now, - * and vice versa. - * - * @param session the session - */ - public void undo(Session session) { - Database db = session.getDatabase(); - switch (operation) { - case INSERT: - if (state == IN_MEMORY_INVALID) { - state = IN_MEMORY; - } - if (db.getLockMode() == Constants.LOCK_MODE_OFF) { - if (row.isDeleted()) { - // it might have been deleted by another thread - return; - } - } - try { - row.setDeleted(false); - table.removeRow(session, row); - table.fireAfterRow(session, row, null, true); - } catch (DbException e) { - if (session.getDatabase().getLockMode() == Constants.LOCK_MODE_OFF - && e.getErrorCode() == ErrorCode.ROW_NOT_FOUND_WHEN_DELETING_1) { - // it might have been deleted by another thread - // ignore - } else { - throw e; - } - } - break; - case DELETE: - try { - table.addRow(session, row); - table.fireAfterRow(session, null, row, true); - // reset session id, otherwise other session think - // that this row was inserted by this session - row.commit(); - } catch (DbException e) { - if (session.getDatabase().getLockMode() == Constants.LOCK_MODE_OFF - && e.getSQLException().getErrorCode() == ErrorCode.DUPLICATE_KEY_1) { - // it might have been added by another thread - // ignore - } else { - throw e; - } - } - break; - default: - DbException.throwInternalError("op=" + operation); - } - } - - /** - * Append the row to the buffer. - * - * @param buff the buffer - * @param log the undo log - */ - void append(Data buff, UndoLog log) { - int p = buff.length(); - buff.writeInt(0); - buff.writeInt(operation); - buff.writeByte(row.isDeleted() ? (byte) 1 : (byte) 0); - if (SysProperties.LARGE_TRANSACTIONS) { - buff.writeInt(log.getTableId(table)); - } - buff.writeLong(row.getKey()); - buff.writeInt(row.getSessionId()); - buff.writeInt(row.getColumnCount()); - for (int i = 0; i < row.getColumnCount(); i++) { - Value v = row.getValue(i); - buff.checkCapacity(buff.getValueLen(v)); - buff.writeValue(v); - } - buff.fillAligned(); - buff.setInt(p, (buff.length() - p) / Constants.FILE_BLOCK_SIZE); - } - - /** - * Save the row in the file using a buffer. - * - * @param buff the buffer - * @param file the file - * @param log the undo log - */ - void save(Data buff, FileStore file, UndoLog log) { - buff.reset(); - append(buff, log); - filePos = (int) (file.getFilePointer() / Constants.FILE_BLOCK_SIZE); - file.write(buff.getBytes(), 0, buff.length()); - row = null; - state = STORED; - } - - /** - * Load an undo log record row using a buffer. - * - * @param buff the buffer - * @param log the log - * @return the undo log record - */ - static UndoLogRecord loadFromBuffer(Data buff, UndoLog log) { - UndoLogRecord rec = new UndoLogRecord(null, (short) 0, null); - int pos = buff.length(); - int len = buff.readInt() * Constants.FILE_BLOCK_SIZE; - rec.load(buff, log); - buff.setPos(pos + len); - return rec; - } - - /** - * Load an undo log record row using a buffer. - * - * @param buff the buffer - * @param file the source file - * @param log the log - */ - void load(Data buff, FileStore file, UndoLog log) { - int min = Constants.FILE_BLOCK_SIZE; - log.seek(filePos); - buff.reset(); - file.readFully(buff.getBytes(), 0, min); - int len = buff.readInt() * Constants.FILE_BLOCK_SIZE; - buff.checkCapacity(len); - if (len - min > 0) { - file.readFully(buff.getBytes(), min, len - min); - } - int oldOp = operation; - load(buff, log); - if (SysProperties.CHECK) { - if (operation != oldOp) { - DbException.throwInternalError("operation=" + operation + " op=" + oldOp); - } - } - } - - private void load(Data buff, UndoLog log) { - operation = (short) buff.readInt(); - boolean deleted = buff.readByte() == 1; - if (SysProperties.LARGE_TRANSACTIONS) { - table = log.getTable(buff.readInt()); - } - long key = buff.readLong(); - int sessionId = buff.readInt(); - int columnCount = buff.readInt(); - Value[] values = new Value[columnCount]; - for (int i = 0; i < columnCount; i++) { - values[i] = buff.readValue(); - } - row = new Row(values, 1); - row.setKey(key); - row.setDeleted(deleted); - row.setSessionId(sessionId); - state = IN_MEMORY_INVALID; - } - - /** - * Get the table. - * - * @return the table - */ - public Table getTable() { - return table; - } - - /** - * Get the position in the file. - * - * @return the file position - */ - public long getFilePos() { - return filePos; - } - - /** - * This method is called after the operation was committed. - * It commits the change to the indexes. - */ - public void commit() { - for (Index index : table.getIndexes()) { - index.commit(operation, row); - } - } - - /** - * Get the row that was deleted or inserted. - * - * @return the row - */ - public Row getRow() { - return row; - } - - /** - * Change the state from IN_MEMORY to IN_MEMORY_INVALID. This method is - * called if a later record was read from the temporary file, and therefore - * the position could have changed. - */ - void invalidatePos() { - if (this.state == IN_MEMORY) { - state = IN_MEMORY_INVALID; - } - } -} diff --git a/tools/h2/src/main/org/h2/engine/User.java b/tools/h2/src/main/org/h2/engine/User.java deleted file mode 100755 index daecf6b..0000000 --- a/tools/h2/src/main/org/h2/engine/User.java +++ /dev/null @@ -1,249 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.engine; - -import java.util.ArrayList; -import java.util.Arrays; -import org.h2.constant.ErrorCode; -import org.h2.message.DbException; -import org.h2.message.Trace; -import org.h2.schema.Schema; -import org.h2.security.SHA256; -import org.h2.table.MetaTable; -import org.h2.table.RangeTable; -import org.h2.table.Table; -import org.h2.table.TableView; -import org.h2.util.MathUtils; -import org.h2.util.New; -import org.h2.util.StringUtils; -import org.h2.util.Utils; - -/** - * Represents a user object. - */ -public class User extends RightOwner { - - private final boolean systemUser; - private byte[] salt; - private byte[] passwordHash; - private boolean admin; - - public User(Database database, int id, String userName, boolean systemUser) { - super(database, id, userName, Trace.USER); - this.systemUser = systemUser; - } - - public void setAdmin(boolean admin) { - this.admin = admin; - } - - public boolean isAdmin() { - return admin; - } - - /** - * Set the salt and hash of the password for this user. - * - * @param salt the salt - * @param hash the password hash - */ - public void setSaltAndHash(byte[] salt, byte[] hash) { - this.salt = salt; - this.passwordHash = hash; - } - - /** - * Set the user name password hash. A random salt is generated as well. - * The parameter is filled with zeros after use. - * - * @param userPasswordHash the user name password hash - */ - public void setUserPasswordHash(byte[] userPasswordHash) { - if (userPasswordHash != null) { - salt = new byte[Constants.SALT_LEN]; - MathUtils.randomBytes(salt); - SHA256 sha = new SHA256(); - this.passwordHash = sha.getHashWithSalt(userPasswordHash, salt); - } - } - - public String getCreateSQLForCopy(Table table, String quotedName) { - throw DbException.throwInternalError(); - } - - public String getCreateSQL() { - return getCreateSQL(true, false); - } - - public String getDropSQL() { - return null; - } - - /** - * Checks that this user has the given rights for this database object. - * - * @param table the database object - * @param rightMask the rights required - * @throws SQLException if this user does not have the required rights - */ - public void checkRight(Table table, int rightMask) { - if (!hasRight(table, rightMask)) { - throw DbException.get(ErrorCode.NOT_ENOUGH_RIGHTS_FOR_1, table.getSQL()); - } - } - - /** - * See if this user has the given rights for this database object. - * - * @param table the database object - * @param rightMask the rights required - * @return true if the user has the rights - */ - public boolean hasRight(Table table, int rightMask) { - if (rightMask != Right.SELECT && !systemUser) { - table.checkWritingAllowed(); - } - if (admin) { - return true; - } - Role publicRole = database.getPublicRole(); - if (publicRole.isRightGrantedRecursive(table, rightMask)) { - return true; - } - if (table instanceof MetaTable || table instanceof RangeTable) { - // everybody has access to the metadata information - return true; - } - String tableType = table.getTableType(); - if (Table.VIEW.equals(tableType)) { - TableView v = (TableView) table; - if (v.getOwner() == this) { - // the owner of a view has access: - // SELECT * FROM (SELECT * FROM ...) - return true; - } - } else if (tableType == null) { - // function table - return true; - } - if (table.isTemporary() && !table.isGlobalTemporary()) { - // the owner has all rights on local temporary tables - return true; - } - if (isRightGrantedRecursive(table, rightMask)) { - return true; - } - return false; - } - - /** - * Get the CREATE SQL statement for this object. - * - * @param password true if the password (actually the salt and hash) should - * be returned - * @param ifNotExists true if IF NOT EXISTS should be used - * @return the SQL statement - */ - public String getCreateSQL(boolean password, boolean ifNotExists) { - StringBuilder buff = new StringBuilder("CREATE USER "); - if (ifNotExists) { - buff.append("IF NOT EXISTS "); - } - buff.append(getSQL()); - if (comment != null) { - buff.append(" COMMENT ").append(StringUtils.quoteStringSQL(comment)); - } - if (password) { - buff.append(" SALT '"). - append(Utils.convertBytesToString(salt)). - append("' HASH '"). - append(Utils.convertBytesToString(passwordHash)). - append('\''); - } else { - buff.append(" PASSWORD ''"); - } - if (admin) { - buff.append(" ADMIN"); - } - return buff.toString(); - } - - /** - * Check the password of this user. - * - * @param userPasswordHash the password data (the user password hash) - * @return true if the user password hash is correct - */ - public boolean validateUserPasswordHash(byte[] userPasswordHash) { - SHA256 sha = new SHA256(); - byte[] hash = sha.getHashWithSalt(userPasswordHash, salt); - return Utils.compareSecure(hash, passwordHash); - } - - /** - * Check if this user has admin rights. An exception is thrown if he does - * not have them. - * - * @throws SQLException if this user is not an admin - */ - public void checkAdmin() { - if (!admin) { - throw DbException.get(ErrorCode.ADMIN_RIGHTS_REQUIRED); - } - } - - public int getType() { - return DbObject.USER; - } - - public ArrayList getChildren() { - ArrayList children = New.arrayList(); - for (Right right : database.getAllRights()) { - if (right.getGrantee() == this) { - children.add(right); - } - } - for (Schema schema : database.getAllSchemas()) { - if (schema.getOwner() == this) { - children.add(schema); - } - } - return children; - } - - public void removeChildrenAndResources(Session session) { - for (Right right : database.getAllRights()) { - if (right.getGrantee() == this) { - database.removeDatabaseObject(session, right); - } - } - database.removeMeta(session, getId()); - salt = null; - Arrays.fill(passwordHash, (byte) 0); - passwordHash = null; - invalidate(); - } - - public void checkRename() { - // ok - } - - /** - * Check that this user does not own any schema. An exception is thrown if he - * owns one or more schemas. - * - * @throws SQLException if this user owns a schema - */ - public void checkOwnsNoSchemas() { - for (Schema s : database.getAllSchemas()) { - if (this == s.getOwner()) { - throw DbException.get(ErrorCode.CANNOT_DROP_2, getName(), s.getName()); - } - } - } - -} diff --git a/tools/h2/src/main/org/h2/engine/UserAggregate.java b/tools/h2/src/main/org/h2/engine/UserAggregate.java deleted file mode 100755 index 58d779e..0000000 --- a/tools/h2/src/main/org/h2/engine/UserAggregate.java +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.engine; - -import org.h2.api.AggregateFunction; -import org.h2.command.Parser; -import org.h2.message.DbException; -import org.h2.message.Trace; -import org.h2.table.Table; -import org.h2.util.Utils; - -/** - * Represents a user-defined aggregate function. - */ -public class UserAggregate extends DbObjectBase { - - private String className; - private Class< ? > javaClass; - - public UserAggregate(Database db, int id, String name, String className, boolean force) { - initDbObjectBase(db, id, name, Trace.FUNCTION); - this.className = className; - if (!force) { - getInstance(); - } - } - - public AggregateFunction getInstance() { - if (javaClass == null) { - javaClass = Utils.loadUserClass(className); - } - Object obj; - try { - obj = javaClass.newInstance(); - AggregateFunction agg = (AggregateFunction) obj; - return agg; - } catch (Exception e) { - throw DbException.convert(e); - } - } - - public String getCreateSQLForCopy(Table table, String quotedName) { - throw DbException.throwInternalError(); - } - - public String getDropSQL() { - return "DROP AGGREGATE IF EXISTS " + getSQL(); - } - - public String getCreateSQL() { - return "CREATE FORCE AGGREGATE " + getSQL() + " FOR " + Parser.quoteIdentifier(className); - } - - public int getType() { - return DbObject.AGGREGATE; - } - - public synchronized void removeChildrenAndResources(Session session) { - database.removeMeta(session, getId()); - className = null; - javaClass = null; - invalidate(); - } - - public void checkRename() { - throw DbException.getUnsupportedException("AGGREGATE"); - } - - public String getJavaClassName() { - return this.className; - } - -} diff --git a/tools/h2/src/main/org/h2/engine/UserDataType.java b/tools/h2/src/main/org/h2/engine/UserDataType.java deleted file mode 100755 index b6afc11..0000000 --- a/tools/h2/src/main/org/h2/engine/UserDataType.java +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.engine; - -import org.h2.message.DbException; -import org.h2.message.Trace; -import org.h2.table.Column; -import org.h2.table.Table; - -/** - * Represents a domain (user-defined data type). - */ -public class UserDataType extends DbObjectBase { - - private Column column; - - public UserDataType(Database database, int id, String name) { - initDbObjectBase(database, id, name, Trace.DATABASE); - } - - public String getCreateSQLForCopy(Table table, String quotedName) { - throw DbException.throwInternalError(); - } - - public String getDropSQL() { - return "DROP DOMAIN IF EXISTS " + getSQL(); - } - - public String getCreateSQL() { - return "CREATE DOMAIN " + getSQL() + " AS " + column.getCreateSQL(); - } - - public Column getColumn() { - return column; - } - - public int getType() { - return DbObject.USER_DATATYPE; - } - - public void removeChildrenAndResources(Session session) { - database.removeMeta(session, getId()); - } - - public void checkRename() { - // ok - } - - public void setColumn(Column column) { - this.column = column; - } - -} diff --git a/tools/h2/src/main/org/h2/engine/package.html b/tools/h2/src/main/org/h2/engine/package.html deleted file mode 100755 index c6b58e4..0000000 --- a/tools/h2/src/main/org/h2/engine/package.html +++ /dev/null @@ -1,15 +0,0 @@ - - - - -Javadoc package documentation -

- -Contains high level classes of the database and classes that don't fit in another sub-package. - -

\ No newline at end of file diff --git a/tools/h2/src/main/org/h2/expression/Aggregate.java b/tools/h2/src/main/org/h2/expression/Aggregate.java deleted file mode 100755 index 58b91dc..0000000 --- a/tools/h2/src/main/org/h2/expression/Aggregate.java +++ /dev/null @@ -1,564 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.expression; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.Comparator; -import java.util.HashMap; -import org.h2.command.dml.Select; -import org.h2.command.dml.SelectOrderBy; -import org.h2.constant.ErrorCode; -import org.h2.engine.Session; -import org.h2.index.Cursor; -import org.h2.index.Index; -import org.h2.message.DbException; -import org.h2.result.SearchRow; -import org.h2.result.SortOrder; -import org.h2.table.Column; -import org.h2.table.ColumnResolver; -import org.h2.table.Table; -import org.h2.table.TableFilter; -import org.h2.util.New; -import org.h2.util.StatementBuilder; -import org.h2.util.StringUtils; -import org.h2.value.DataType; -import org.h2.value.Value; -import org.h2.value.ValueArray; -import org.h2.value.ValueBoolean; -import org.h2.value.ValueDouble; -import org.h2.value.ValueInt; -import org.h2.value.ValueLong; -import org.h2.value.ValueNull; -import org.h2.value.ValueString; - -/** - * Implements the integrated aggregate functions, such as COUNT, MAX, SUM. - */ -public class Aggregate extends Expression { - - /** - * The aggregate type for COUNT(*). - */ - public static final int COUNT_ALL = 0; - - /** - * The aggregate type for COUNT(expression). - */ - public static final int COUNT = 1; - - /** - * The aggregate type for GROUP_CONCAT(...). - */ - public static final int GROUP_CONCAT = 2; - - /** - * The aggregate type for SUM(expression). - */ - static final int SUM = 3; - - /** - * The aggregate type for MIN(expression). - */ - static final int MIN = 4; - - /** - * The aggregate type for MAX(expression). - */ - static final int MAX = 5; - - /** - * The aggregate type for AVG(expression). - */ - static final int AVG = 6; - - /** - * The aggregate type for STDDEV_POP(expression). - */ - static final int STDDEV_POP = 7; - - /** - * The aggregate type for STDDEV_SAMP(expression). - */ - static final int STDDEV_SAMP = 8; - - /** - * The aggregate type for VAR_POP(expression). - */ - static final int VAR_POP = 9; - - /** - * The aggregate type for VAR_SAMP(expression). - */ - static final int VAR_SAMP = 10; - - /** - * The aggregate type for BOOL_OR(expression). - */ - static final int BOOL_OR = 11; - - /** - * The aggregate type for BOOL_AND(expression). - */ - static final int BOOL_AND = 12; - - /** - * The aggregate type for SELECTIVITY(expression). - */ - static final int SELECTIVITY = 13; - - private static final HashMap AGGREGATES = New.hashMap(); - - private final int type; - private final Select select; - private final boolean distinct; - - private Expression on; - private Expression separator; - private ArrayList orderList; - private SortOrder sort; - private int dataType, scale; - private long precision; - private int displaySize; - private int lastGroupRowId; - - /** - * Create a new aggregate object. - * - * @param type the aggregate type - * @param on the aggregated expression - * @param select the select statement - * @param distinct if distinct is used - */ - public Aggregate(int type, Expression on, Select select, boolean distinct) { - this.type = type; - this.on = on; - this.select = select; - this.distinct = distinct; - } - - static { - addAggregate("COUNT", COUNT); - addAggregate("SUM", SUM); - addAggregate("MIN", MIN); - addAggregate("MAX", MAX); - addAggregate("AVG", AVG); - addAggregate("GROUP_CONCAT", GROUP_CONCAT); - addAggregate("STDDEV_SAMP", STDDEV_SAMP); - addAggregate("STDDEV", STDDEV_SAMP); - addAggregate("STDDEV_POP", STDDEV_POP); - addAggregate("STDDEVP", STDDEV_POP); - addAggregate("VAR_POP", VAR_POP); - addAggregate("VARP", VAR_POP); - addAggregate("VAR_SAMP", VAR_SAMP); - addAggregate("VAR", VAR_SAMP); - addAggregate("VARIANCE", VAR_SAMP); - addAggregate("BOOL_OR", BOOL_OR); - // HSQLDB compatibility, but conflicts with >EVERY(...) - addAggregate("SOME", BOOL_OR); - addAggregate("BOOL_AND", BOOL_AND); - // HSQLDB compatibility, but conflicts with >SOME(...) - addAggregate("EVERY", BOOL_AND); - addAggregate("SELECTIVITY", SELECTIVITY); - } - - private static void addAggregate(String name, int type) { - AGGREGATES.put(name, type); - } - - /** - * Get the aggregate type for this name, or -1 if no aggregate has been - * found. - * - * @param name the aggregate function name - * @return -1 if no aggregate function has been found, or the aggregate type - */ - public static int getAggregateType(String name) { - Integer type = AGGREGATES.get(name); - return type == null ? -1 : type.intValue(); - } - - /** - * Set the order for GROUP_CONCAT. - * - * @param orderBy the order by list - */ - public void setOrder(ArrayList orderBy) { - this.orderList = orderBy; - } - - /** - * Set the separator for GROUP_CONCAT. - * - * @param separator the separator expression - */ - public void setSeparator(Expression separator) { - this.separator = separator; - } - - private SortOrder initOrder(Session session) { - int[] index = new int[orderList.size()]; - int[] sortType = new int[orderList.size()]; - for (int i = 0; i < orderList.size(); i++) { - SelectOrderBy o = orderList.get(i); - index[i] = i + 1; - int order = o.descending ? SortOrder.DESCENDING : SortOrder.ASCENDING; - sortType[i] = order; - } - return new SortOrder(session.getDatabase(), index, sortType); - } - - public void updateAggregate(Session session) { - // TODO aggregates: check nested MIN(MAX(ID)) and so on - // if(on != null) { - // on.updateAggregate(); - // } - HashMap group = select.getCurrentGroup(); - if (group == null) { - // this is a different level (the enclosing query) - return; - } - - int groupRowId = select.getCurrentGroupRowId(); - if (lastGroupRowId == groupRowId) { - // already visited - return; - } - lastGroupRowId = groupRowId; - - AggregateData data = (AggregateData) group.get(this); - if (data == null) { - data = new AggregateData(type, dataType); - group.put(this, data); - } - Value v = on == null ? null : on.getValue(session); - if (type == GROUP_CONCAT) { - if (v != ValueNull.INSTANCE) { - v = v.convertTo(Value.STRING); - if (orderList != null) { - Value[] array = new Value[1 + orderList.size()]; - array[0] = v; - for (int i = 0; i < orderList.size(); i++) { - SelectOrderBy o = orderList.get(i); - array[i + 1] = o.expression.getValue(session); - } - v = ValueArray.get(array); - } - } - } - data.add(session.getDatabase(), distinct, v); - } - - public Value getValue(Session session) { - if (select.isQuickAggregateQuery()) { - switch (type) { - case COUNT_ALL: - Table table = select.getTopTableFilter().getTable(); - return ValueLong.get(table.getRowCount(session)); - case MIN: - case MAX: - boolean first = type == MIN; - Index index = getColumnIndex(first); - int sortType = index.getIndexColumns()[0].sortType; - if ((sortType & SortOrder.DESCENDING) != 0) { - first = !first; - } - Cursor cursor = index.findFirstOrLast(session, first); - SearchRow row = cursor.getSearchRow(); - Value v; - if (row == null) { - v = ValueNull.INSTANCE; - } else { - v = row.getValue(index.getColumns()[0].getColumnId()); - } - return v; - default: - DbException.throwInternalError("type=" + type); - } - } - HashMap group = select.getCurrentGroup(); - if (group == null) { - throw DbException.get(ErrorCode.INVALID_USE_OF_AGGREGATE_FUNCTION_1, getSQL()); - } - AggregateData data = (AggregateData) group.get(this); - if (data == null) { - data = new AggregateData(type, dataType); - } - Value v = data.getValue(session.getDatabase(), distinct); - if (type == GROUP_CONCAT) { - ArrayList list = data.getList(); - if (list == null || list.size() == 0) { - return ValueNull.INSTANCE; - } - if (orderList != null) { - final SortOrder sortOrder = sort; - Collections.sort(list, new Comparator() { - public int compare(Value v1, Value v2) { - Value[] a1 = ((ValueArray) v1).getList(); - Value[] a2 = ((ValueArray) v2).getList(); - return sortOrder.compare(a1, a2); - } - }); - } - StatementBuilder buff = new StatementBuilder(); - String sep = separator == null ? "," : separator.getValue(session).getString(); - for (Value val : list) { - String s; - if (val.getType() == Value.ARRAY) { - s = ((ValueArray) val).getList()[0].getString(); - } else { - s = val.convertTo(Value.STRING).getString(); - } - if (s == null) { - continue; - } - if (sep != null) { - buff.appendExceptFirst(sep); - } - buff.append(s); - } - v = ValueString.get(buff.toString()); - } - return v; - } - - public int getType() { - return dataType; - } - - public void mapColumns(ColumnResolver resolver, int level) { - if (on != null) { - on.mapColumns(resolver, level); - } - if (orderList != null) { - for (SelectOrderBy o : orderList) { - o.expression.mapColumns(resolver, level); - } - } - if (separator != null) { - separator.mapColumns(resolver, level); - } - } - - public Expression optimize(Session session) { - if (on != null) { - on = on.optimize(session); - dataType = on.getType(); - scale = on.getScale(); - precision = on.getPrecision(); - displaySize = on.getDisplaySize(); - } - if (orderList != null) { - for (SelectOrderBy o : orderList) { - o.expression = o.expression.optimize(session); - } - sort = initOrder(session); - } - if (separator != null) { - separator = separator.optimize(session); - } - switch (type) { - case GROUP_CONCAT: - dataType = Value.STRING; - scale = 0; - precision = Integer.MAX_VALUE; - displaySize = Integer.MAX_VALUE; - break; - case COUNT_ALL: - case COUNT: - dataType = Value.LONG; - scale = 0; - precision = ValueLong.PRECISION; - displaySize = ValueLong.DISPLAY_SIZE; - break; - case SELECTIVITY: - dataType = Value.INT; - scale = 0; - precision = ValueInt.PRECISION; - displaySize = ValueInt.DISPLAY_SIZE; - break; - case SUM: - if (!DataType.supportsAdd(dataType)) { - throw DbException.get(ErrorCode.SUM_OR_AVG_ON_WRONG_DATATYPE_1, getSQL()); - } - dataType = DataType.getAddProofType(dataType); - break; - case AVG: - if (!DataType.supportsAdd(dataType)) { - throw DbException.get(ErrorCode.SUM_OR_AVG_ON_WRONG_DATATYPE_1, getSQL()); - } - break; - case MIN: - case MAX: - break; - case STDDEV_POP: - case STDDEV_SAMP: - case VAR_POP: - case VAR_SAMP: - dataType = Value.DOUBLE; - precision = ValueDouble.PRECISION; - displaySize = ValueDouble.DISPLAY_SIZE; - scale = 0; - break; - case BOOL_AND: - case BOOL_OR: - dataType = Value.BOOLEAN; - precision = ValueBoolean.PRECISION; - displaySize = ValueBoolean.DISPLAY_SIZE; - scale = 0; - break; - default: - DbException.throwInternalError("type=" + type); - } - return this; - } - - public void setEvaluatable(TableFilter tableFilter, boolean b) { - if (on != null) { - on.setEvaluatable(tableFilter, b); - } - if (orderList != null) { - for (SelectOrderBy o : orderList) { - o.expression.setEvaluatable(tableFilter, b); - } - } - if (separator != null) { - separator.setEvaluatable(tableFilter, b); - } - } - - public int getScale() { - return scale; - } - - public long getPrecision() { - return precision; - } - - public int getDisplaySize() { - return displaySize; - } - - private String getSQLGroupConcat() { - StatementBuilder buff = new StatementBuilder("GROUP_CONCAT("); - buff.append(on.getSQL()); - if (orderList != null) { - buff.append(" ORDER BY "); - for (SelectOrderBy o : orderList) { - buff.appendExceptFirst(", "); - buff.append(o.expression.getSQL()); - if (o.descending) { - buff.append(" DESC"); - } - } - } - if (separator != null) { - buff.append(" SEPARATOR ").append(separator.getSQL()); - } - return buff.append(')').toString(); - } - - public String getSQL() { - String text; - switch (type) { - case GROUP_CONCAT: - return getSQLGroupConcat(); - case COUNT_ALL: - return "COUNT(*)"; - case COUNT: - text = "COUNT"; - break; - case SELECTIVITY: - text = "SELECTIVITY"; - break; - case SUM: - text = "SUM"; - break; - case MIN: - text = "MIN"; - break; - case MAX: - text = "MAX"; - break; - case AVG: - text = "AVG"; - break; - case STDDEV_POP: - text = "STDDEV_POP"; - break; - case STDDEV_SAMP: - text = "STDDEV_SAMP"; - break; - case VAR_POP: - text = "VAR_POP"; - break; - case VAR_SAMP: - text = "VAR_SAMP"; - break; - case BOOL_AND: - text = "BOOL_AND"; - break; - case BOOL_OR: - text = "BOOL_OR"; - break; - default: - throw DbException.throwInternalError("type=" + type); - } - if (distinct) { - return text + "(DISTINCT " + on.getSQL() + ")"; - } - return text + StringUtils.enclose(on.getSQL()); - } - - private Index getColumnIndex(boolean first) { - if (on instanceof ExpressionColumn) { - ExpressionColumn col = (ExpressionColumn) on; - Column column = col.getColumn(); - TableFilter filter = col.getTableFilter(); - if (filter != null) { - Table table = filter.getTable(); - Index index = table.getIndexForColumn(column, first); - return index; - } - } - return null; - } - - public boolean isEverything(ExpressionVisitor visitor) { - if (visitor.getType() == ExpressionVisitor.OPTIMIZABLE_MIN_MAX_COUNT_ALL) { - switch (type) { - case COUNT_ALL: - return visitor.getTable().canGetRowCount(); - case MIN: - case MAX: - boolean first = type == MIN; - Index index = getColumnIndex(first); - return index != null; - default: - return false; - } - } - if (on != null && !on.isEverything(visitor)) { - return false; - } - if (separator != null && !separator.isEverything(visitor)) { - return false; - } - for (int i = 0; orderList != null && i < orderList.size(); i++) { - SelectOrderBy o = orderList.get(i); - if (!o.expression.isEverything(visitor)) { - return false; - } - } - return true; - } - - public int getCost() { - return (on == null) ? 1 : on.getCost() + 1; - } - -} diff --git a/tools/h2/src/main/org/h2/expression/AggregateData.java b/tools/h2/src/main/org/h2/expression/AggregateData.java deleted file mode 100755 index f298a76..0000000 --- a/tools/h2/src/main/org/h2/expression/AggregateData.java +++ /dev/null @@ -1,255 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.expression; - -import java.util.ArrayList; -import org.h2.engine.Constants; -import org.h2.engine.Database; -import org.h2.message.DbException; -import org.h2.util.New; -import org.h2.util.ValueHashMap; -import org.h2.value.DataType; -import org.h2.value.Value; -import org.h2.value.ValueBoolean; -import org.h2.value.ValueDouble; -import org.h2.value.ValueInt; -import org.h2.value.ValueLong; -import org.h2.value.ValueNull; - -/** - * Data stored while calculating an aggregate. - */ -class AggregateData { - private final int aggregateType; - private final int dataType; - private long count; - private ValueHashMap distinctValues; - private Value value; - private double sum, vpn; - private ArrayList list; - - AggregateData(int aggregateType, int dataType) { - this.aggregateType = aggregateType; - this.dataType = dataType; - } - - /** - * Add a value to this aggregate. - * - * @param database the database - * @param distinct if the calculation should be distinct - * @param v the value - */ - void add(Database database, boolean distinct, Value v) { - if (aggregateType == Aggregate.SELECTIVITY) { - count++; - if (distinctValues == null) { - distinctValues = ValueHashMap.newInstance(); - } - int size = distinctValues.size(); - if (size > Constants.SELECTIVITY_DISTINCT_COUNT) { - distinctValues = ValueHashMap.newInstance(); - sum += size; - } - distinctValues.put(v, this); - return; - } - if (aggregateType == Aggregate.COUNT_ALL) { - count++; - return; - } - if (v == ValueNull.INSTANCE) { - return; - } - count++; - if (distinct) { - if (distinctValues == null) { - distinctValues = ValueHashMap.newInstance(); - } - distinctValues.put(v, this); - return; - } - switch (aggregateType) { - case Aggregate.COUNT: - return; - case Aggregate.SUM: - if (value == null) { - value = v.convertTo(dataType); - } else { - v = v.convertTo(value.getType()); - value = value.add(v); - } - break; - case Aggregate.AVG: - if (value == null) { - value = v.convertTo(DataType.getAddProofType(dataType)); - } else { - v = v.convertTo(value.getType()); - value = value.add(v); - } - break; - case Aggregate.MIN: - if (value == null || database.compare(v, value) < 0) { - value = v; - } - break; - case Aggregate.MAX: - if (value == null || database.compare(v, value) > 0) { - value = v; - } - break; - case Aggregate.GROUP_CONCAT: { - if (list == null) { - list = New.arrayList(); - } - list.add(v); - break; - } - case Aggregate.STDDEV_POP: - case Aggregate.STDDEV_SAMP: - case Aggregate.VAR_POP: - case Aggregate.VAR_SAMP: { - double x = v.getDouble(); - if (count == 1) { - sum = x; - vpn = 0; - } else { - double xs = sum - (x * (count - 1)); - vpn += (xs * xs) / count / (count - 1); - sum += x; - } - break; - } - case Aggregate.BOOL_AND: - v = v.convertTo(Value.BOOLEAN); - if (value == null) { - value = v; - } else { - value = ValueBoolean.get(value.getBoolean().booleanValue() && v.getBoolean().booleanValue()); - } - break; - case Aggregate.BOOL_OR: - v = v.convertTo(Value.BOOLEAN); - if (value == null) { - value = v; - } else { - value = ValueBoolean.get(value.getBoolean().booleanValue() || v.getBoolean().booleanValue()); - } - break; - default: - DbException.throwInternalError("type=" + aggregateType); - } - } - - ArrayList getList() { - return list; - } - - /** - * Get the aggregate result. - * - * @param database the database - * @param distinct if distinct is used - * @return the value - */ - Value getValue(Database database, boolean distinct) { - if (distinct) { - count = 0; - groupDistinct(database); - } - Value v = null; - switch (aggregateType) { - case Aggregate.SELECTIVITY: { - int s = 0; - if (count == 0) { - s = 0; - } else { - sum += distinctValues.size(); - sum = 100 * sum / count; - s = (int) sum; - s = s <= 0 ? 1 : s > 100 ? 100 : s; - } - v = ValueInt.get(s); - break; - } - case Aggregate.COUNT: - case Aggregate.COUNT_ALL: - v = ValueLong.get(count); - break; - case Aggregate.SUM: - case Aggregate.MIN: - case Aggregate.MAX: - case Aggregate.BOOL_OR: - case Aggregate.BOOL_AND: - v = value; - break; - case Aggregate.AVG: - if (value != null) { - v = divide(value, count); - } - break; - case Aggregate.GROUP_CONCAT: - return null; - case Aggregate.STDDEV_POP: { - if (count < 1) { - return ValueNull.INSTANCE; - } - v = ValueDouble.get(Math.sqrt(vpn / count)); - break; - } - case Aggregate.STDDEV_SAMP: { - if (count < 2) { - return ValueNull.INSTANCE; - } - v = ValueDouble.get(Math.sqrt(vpn / (count - 1))); - break; - } - case Aggregate.VAR_POP: { - if (count < 1) { - return ValueNull.INSTANCE; - } - v = ValueDouble.get(vpn / count); - break; - } - case Aggregate.VAR_SAMP: { - if (count < 2) { - return ValueNull.INSTANCE; - } - v = ValueDouble.get(vpn / (count - 1)); - break; - } - default: - DbException.throwInternalError("type=" + aggregateType); - } - return v == null ? ValueNull.INSTANCE : v.convertTo(dataType); - } - - private Value divide(Value a, long by) { - if (by == 0) { - return ValueNull.INSTANCE; - } - int type = Value.getHigherOrder(a.getType(), Value.LONG); - Value b = ValueLong.get(by).convertTo(type); - a = a.convertTo(type).divide(b); - return a; - } - - private void groupDistinct(Database database) { - if (distinctValues == null) { - return; - } - if (aggregateType == Aggregate.COUNT) { - count = distinctValues.size(); - } else { - count = 0; - for (Value v : distinctValues.keys()) { - add(database, false, v); - } - } - } - -} diff --git a/tools/h2/src/main/org/h2/expression/Alias.java b/tools/h2/src/main/org/h2/expression/Alias.java deleted file mode 100755 index a036e9f..0000000 --- a/tools/h2/src/main/org/h2/expression/Alias.java +++ /dev/null @@ -1,109 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.expression; - -import org.h2.command.Parser; -import org.h2.engine.Session; -import org.h2.table.ColumnResolver; -import org.h2.table.TableFilter; -import org.h2.value.Value; - -/** - * A column alias as in SELECT 'Hello' AS NAME ... - */ -public class Alias extends Expression { - - private final String alias; - private Expression expr; - private boolean aliasColumnName; - - public Alias(Expression expression, String alias, boolean aliasColumnName) { - this.expr = expression; - this.alias = alias; - this.aliasColumnName = aliasColumnName; - } - - public Expression getNonAliasExpression() { - return expr; - } - - public Value getValue(Session session) { - return expr.getValue(session); - } - - public int getType() { - return expr.getType(); - } - - public void mapColumns(ColumnResolver resolver, int level) { - expr.mapColumns(resolver, level); - } - - public Expression optimize(Session session) { - expr = expr.optimize(session); - return this; - } - - public void setEvaluatable(TableFilter tableFilter, boolean b) { - expr.setEvaluatable(tableFilter, b); - } - - public int getScale() { - return expr.getScale(); - } - - public long getPrecision() { - return expr.getPrecision(); - } - - public int getDisplaySize() { - return expr.getDisplaySize(); - } - - public boolean isAutoIncrement() { - return expr.isAutoIncrement(); - } - - public String getSQL() { - return expr.getSQL() + " AS " + Parser.quoteIdentifier(alias); - } - - public void updateAggregate(Session session) { - expr.updateAggregate(session); - } - - public String getAlias() { - return alias; - } - - public int getNullable() { - return expr.getNullable(); - } - - public boolean isEverything(ExpressionVisitor visitor) { - return expr.isEverything(visitor); - } - - public int getCost() { - return expr.getCost(); - } - - public String getTableName() { - if (aliasColumnName) { - return super.getTableName(); - } - return expr.getTableName(); - } - - public String getColumnName() { - if (!(expr instanceof ExpressionColumn) || aliasColumnName) { - return super.getColumnName(); - } - return expr.getColumnName(); - } - -} diff --git a/tools/h2/src/main/org/h2/expression/CompareLike.java b/tools/h2/src/main/org/h2/expression/CompareLike.java deleted file mode 100755 index d3aaf3d..0000000 --- a/tools/h2/src/main/org/h2/expression/CompareLike.java +++ /dev/null @@ -1,404 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.expression; - -import java.util.regex.Pattern; -import java.util.regex.PatternSyntaxException; -import org.h2.constant.ErrorCode; -import org.h2.constant.SysProperties; -import org.h2.engine.Session; -import org.h2.index.IndexCondition; -import org.h2.message.DbException; -import org.h2.table.ColumnResolver; -import org.h2.table.TableFilter; -import org.h2.value.CompareMode; -import org.h2.value.Value; -import org.h2.value.ValueBoolean; -import org.h2.value.ValueNull; -import org.h2.value.ValueString; - -/** - * Pattern matching comparison expression: WHERE NAME LIKE ? - */ -public class CompareLike extends Condition { - - private static final int MATCH = 0, ONE = 1, ANY = 2; - private static final Character DEFAULT_ESCAPE_CHAR = getEscapeChar(SysProperties.DEFAULT_ESCAPE); - - private final CompareMode compareMode; - private Expression left; - private Expression right; - private Expression escape; - - private boolean isInit; - - private char[] patternChars; - private String patternString; - private int[] patternTypes; - private int patternLength; - - private final boolean regexp; - private Pattern patternRegexp; - - private boolean ignoreCase; - private boolean fastCompare; - private boolean invalidPattern; - - public CompareLike(CompareMode compareMode, Expression left, Expression right, Expression escape, boolean regexp) { - this.compareMode = compareMode; - this.regexp = regexp; - this.left = left; - this.right = right; - this.escape = escape; - } - - private static Character getEscapeChar(String s) { - return s == null || s.length() == 0 ? null : s.charAt(0); - } - - public String getSQL() { - String sql; - if (regexp) { - sql = left.getSQL() + " REGEXP " + right.getSQL(); - } else { - sql = left.getSQL() + " LIKE " + right.getSQL(); - if (escape != null) { - sql += " ESCAPE " + escape.getSQL(); - } - } - return "(" + sql + ")"; - } - - public Expression optimize(Session session) { - left = left.optimize(session); - right = right.optimize(session); - if (left.getType() == Value.STRING_IGNORECASE) { - ignoreCase = true; - } - if (left.isValueSet()) { - Value l = left.getValue(session); - if (l == ValueNull.INSTANCE) { - // NULL LIKE something > NULL - return ValueExpression.getNull(); - } - } - if (escape != null) { - escape = escape.optimize(session); - } - if (right.isValueSet() && (escape == null || escape.isValueSet())) { - if (left.isValueSet()) { - return ValueExpression.get(getValue(session)); - } - Value r = right.getValue(session); - if (r == ValueNull.INSTANCE) { - // something LIKE NULL > NULL - return ValueExpression.getNull(); - } - Value e = escape == null ? null : escape.getValue(session); - if (e == ValueNull.INSTANCE) { - return ValueExpression.getNull(); - } - String p = r.getString(); - initPattern(p, getEscapeChar(e)); - if (invalidPattern) { - return ValueExpression.getNull(); - } - if ("%".equals(p)) { - // optimization for X LIKE '%': convert to X IS NOT NULL - return new Comparison(session, Comparison.IS_NOT_NULL, left, null).optimize(session); - } - if (isFullMatch()) { - // optimization for X LIKE 'Hello': convert to X = 'Hello' - Value value = ValueString.get(patternString); - Expression expr = ValueExpression.get(value); - return new Comparison(session, Comparison.EQUAL, left, expr).optimize(session); - } - isInit = true; - } - return this; - } - - private Character getEscapeChar(Value e) { - if (e == null) { - return DEFAULT_ESCAPE_CHAR; - } - String es = e.getString(); - Character esc; - if (es == null) { - esc = DEFAULT_ESCAPE_CHAR; - } else if (es.length() == 0) { - esc = null; - } else if (es.length() > 1) { - throw DbException.get(ErrorCode.LIKE_ESCAPE_ERROR_1, es); - } else { - esc = es.charAt(0); - } - return esc; - } - - public void createIndexConditions(Session session, TableFilter filter) { - if (regexp) { - return; - } - if (!(left instanceof ExpressionColumn)) { - return; - } - ExpressionColumn l = (ExpressionColumn) left; - if (filter != l.getTableFilter()) { - return; - } - // parameters are always evaluatable, but - // we need to check the actual value now - // (at prepare time) - // otherwise we would need to prepare at execute time, - // which is maybe slower (but maybe not in this case!) - if (!right.isValueSet()) { - return; - } - if (escape != null && !escape.isValueSet()) { - return; - } - String p = right.getValue(session).getString(); - Value e = escape == null ? null : escape.getValue(session); - if (e == ValueNull.INSTANCE) { - // should already be optimized - DbException.throwInternalError(); - } - initPattern(p, getEscapeChar(e)); - if (invalidPattern) { - return; - } - if (patternLength <= 0 || patternTypes[0] != MATCH) { - // can't use an index - return; - } - int dataType = l.getColumn().getType(); - if (dataType != Value.STRING && dataType != Value.STRING_IGNORECASE && dataType != Value.STRING_FIXED) { - // column is not a varchar - can't use the index - return; - } - int maxMatch = 0; - StringBuilder buff = new StringBuilder(); - while (maxMatch < patternLength && patternTypes[maxMatch] == MATCH) { - buff.append(patternChars[maxMatch++]); - } - String begin = buff.toString(); - if (maxMatch == patternLength) { - filter.addIndexCondition(IndexCondition.get(Comparison.EQUAL, l, ValueExpression - .get(ValueString.get(begin)))); - } else { - // TODO check if this is correct according to Unicode rules - // (code points) - String end; - if (begin.length() > 0) { - filter.addIndexCondition(IndexCondition.get(Comparison.BIGGER_EQUAL, l, ValueExpression.get(ValueString - .get(begin)))); - char next = begin.charAt(begin.length() - 1); - // search the 'next' unicode character (or at least a character - // that is higher) - for (int i = 1; i < 2000; i++) { - end = begin.substring(0, begin.length() - 1) + (char) (next + i); - if (compareMode.compareString(begin, end, ignoreCase) == -1) { - filter.addIndexCondition(IndexCondition.get(Comparison.SMALLER, l, ValueExpression - .get(ValueString.get(end)))); - break; - } - } - } - } - } - - public Value getValue(Session session) { - Value l = left.getValue(session); - if (l == ValueNull.INSTANCE) { - return l; - } - if (!isInit) { - Value r = right.getValue(session); - if (r == ValueNull.INSTANCE) { - return r; - } - String p = r.getString(); - Value e = escape == null ? null : escape.getValue(session); - if (e == ValueNull.INSTANCE) { - return ValueNull.INSTANCE; - } - initPattern(p, getEscapeChar(e)); - } - if (invalidPattern) { - return ValueNull.INSTANCE; - } - String value = l.getString(); - boolean result; - if (regexp) { - // result = patternRegexp.matcher(value).matches(); - result = patternRegexp.matcher(value).find(); - } else { - result = compareAt(value, 0, 0, value.length(), patternChars, patternTypes); - } - return ValueBoolean.get(result); - } - - private boolean compare(char[] pattern, String s, int pi, int si) { - return pattern[pi] == s.charAt(si) || (!fastCompare && compareMode.equalsChars(patternString, pi, s, si, ignoreCase)); - } - - private boolean compareAt(String s, int pi, int si, int sLen, char[] pattern, int[] types) { - for (; pi < patternLength; pi++) { - switch (types[pi]) { - case MATCH: - if ((si >= sLen) || !compare(pattern, s, pi, si++)) { - return false; - } - break; - case ONE: - if (si++ >= sLen) { - return false; - } - break; - case ANY: - if (++pi >= patternLength) { - return true; - } - while (si < sLen) { - if (compare(pattern, s, pi, si) && compareAt(s, pi, si, sLen, pattern, types)) { - return true; - } - si++; - } - return false; - default: - DbException.throwInternalError(); - } - } - return si == sLen; - } - - /** - * Test if the value matches the pattern. - * - * @param testPattern the pattern - * @param value the value - * @param escapeChar the escape character - * @return true if the value matches - */ - public boolean test(String testPattern, String value, char escapeChar) { - initPattern(testPattern, escapeChar); - if (invalidPattern) { - return false; - } - return compareAt(value, 0, 0, value.length(), patternChars, patternTypes); - } - - private void initPattern(String p, Character escapeChar) { - if (compareMode.getName().equals(CompareMode.OFF) && !ignoreCase) { - fastCompare = true; - } - if (regexp) { - patternString = p; - try { - if (ignoreCase) { - patternRegexp = Pattern.compile(p, Pattern.CASE_INSENSITIVE); - } else { - patternRegexp = Pattern.compile(p); - } - } catch (PatternSyntaxException e) { - throw DbException.get(ErrorCode.LIKE_ESCAPE_ERROR_1, e, p); - } - return; - } - patternLength = 0; - if (p == null) { - patternTypes = null; - patternChars = null; - return; - } - int len = p.length(); - patternChars = new char[len]; - patternTypes = new int[len]; - boolean lastAny = false; - for (int i = 0; i < len; i++) { - char c = p.charAt(i); - int type; - if (escapeChar != null && escapeChar == c) { - if (i >= len - 1) { - invalidPattern = true; - return; - } - c = p.charAt(++i); - type = MATCH; - lastAny = false; - } else if (c == '%') { - if (lastAny) { - continue; - } - type = ANY; - lastAny = true; - } else if (c == '_') { - type = ONE; - } else { - type = MATCH; - lastAny = false; - } - patternTypes[patternLength] = type; - patternChars[patternLength++] = c; - } - for (int i = 0; i < patternLength - 1; i++) { - if ((patternTypes[i] == ANY) && (patternTypes[i + 1] == ONE)) { - patternTypes[i] = ONE; - patternTypes[i + 1] = ANY; - } - } - patternString = new String(patternChars, 0, patternLength); - } - - private boolean isFullMatch() { - if (patternTypes == null) { - return false; - } - for (int type : patternTypes) { - if (type != MATCH) { - return false; - } - } - return true; - } - - public void mapColumns(ColumnResolver resolver, int level) { - left.mapColumns(resolver, level); - right.mapColumns(resolver, level); - if (escape != null) { - escape.mapColumns(resolver, level); - } - } - - public void setEvaluatable(TableFilter tableFilter, boolean b) { - left.setEvaluatable(tableFilter, b); - right.setEvaluatable(tableFilter, b); - if (escape != null) { - escape.setEvaluatable(tableFilter, b); - } - } - - public void updateAggregate(Session session) { - left.updateAggregate(session); - right.updateAggregate(session); - if (escape != null) { - escape.updateAggregate(session); - } - } - - public boolean isEverything(ExpressionVisitor visitor) { - return left.isEverything(visitor) && right.isEverything(visitor) - && (escape == null || escape.isEverything(visitor)); - } - - public int getCost() { - return left.getCost() + right.getCost() + 3; - } - -} diff --git a/tools/h2/src/main/org/h2/expression/Comparison.java b/tools/h2/src/main/org/h2/expression/Comparison.java deleted file mode 100755 index ec5e1c9..0000000 --- a/tools/h2/src/main/org/h2/expression/Comparison.java +++ /dev/null @@ -1,478 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.expression; - -import java.util.Arrays; -import org.h2.constant.SysProperties; -import org.h2.engine.Database; -import org.h2.engine.Session; -import org.h2.index.IndexCondition; -import org.h2.message.DbException; -import org.h2.table.ColumnResolver; -import org.h2.table.TableFilter; -import org.h2.value.Value; -import org.h2.value.ValueBoolean; -import org.h2.value.ValueNull; - -/** - * Example comparison expressions are ID=1, NAME=NAME, NAME IS NULL. - */ -public class Comparison extends Condition { - - /** - * The comparison type meaning = as in ID=1. - */ - public static final int EQUAL = 0; - - /** - * The comparison type meaning >= as in ID>=1. - */ - public static final int BIGGER_EQUAL = 1; - - /** - * The comparison type meaning > as in ID>1. - */ - public static final int BIGGER = 2; - - /** - * The comparison type meaning <= as in ID<=1. - */ - public static final int SMALLER_EQUAL = 3; - - /** - * The comparison type meaning < as in ID<1. - */ - public static final int SMALLER = 4; - - /** - * The comparison type meaning <> as in ID<>1. - */ - public static final int NOT_EQUAL = 5; - - /** - * The comparison type meaning IS NULL as in NAME IS NULL. - */ - public static final int IS_NULL = 6; - - /** - * The comparison type meaning IS NOT NULL as in NAME IS NOT NULL. - */ - public static final int IS_NOT_NULL = 7; - - /** - * This is a pseudo comparison type that is only used for index conditions. - * It means the comparison will always yield FALSE. Example: 1=0. - */ - public static final int FALSE = 8; - - /** - * This is a pseudo comparison type that is only used for index conditions. - * It means equals any value of a list. Example: IN(1, 2, 3). - */ - public static final int IN_LIST = 9; - - /** - * This is a pseudo comparison type that is only used for index conditions. - * It means equals any value of a list. Example: IN(SELECT ...). - */ - public static final int IN_QUERY = 10; - - private final Database database; - private int compareType; - private Expression left; - private Expression right; - - public Comparison(Session session, int compareType, Expression left, Expression right) { - this.database = session.getDatabase(); - this.left = left; - this.right = right; - this.compareType = compareType; - } - - public String getSQL() { - String sql; - switch (compareType) { - case EQUAL: - sql = left.getSQL() + " = " + right.getSQL(); - break; - case BIGGER_EQUAL: - sql = left.getSQL() + " >= " + right.getSQL(); - break; - case BIGGER: - sql = left.getSQL() + " > " + right.getSQL(); - break; - case SMALLER_EQUAL: - sql = left.getSQL() + " <= " + right.getSQL(); - break; - case SMALLER: - sql = left.getSQL() + " < " + right.getSQL(); - break; - case NOT_EQUAL: - sql = left.getSQL() + " <> " + right.getSQL(); - break; - case IS_NULL: - sql = left.getSQL() + " IS NULL"; - break; - case IS_NOT_NULL: - sql = left.getSQL() + " IS NOT NULL"; - break; - default: - throw DbException.throwInternalError("compareType=" + compareType); - } - return "(" + sql + ")"; - } - - public Expression optimize(Session session) { - left = left.optimize(session); - if (right != null) { - right = right.optimize(session); - if (right instanceof ExpressionColumn) { - if (left.isConstant() || left instanceof Parameter) { - Expression temp = left; - left = right; - right = temp; - compareType = getReversedCompareType(compareType); - } - } - if (left instanceof ExpressionColumn) { - if (right.isConstant()) { - Value r = right.getValue(session); - if (r == ValueNull.INSTANCE) { - return ValueExpression.getNull(); - } - } else if (right instanceof Parameter) { - ((Parameter) right).setColumn(((ExpressionColumn) left).getColumn()); - } - } - } - if (compareType == IS_NULL || compareType == IS_NOT_NULL) { - if (left.isConstant()) { - return ValueExpression.get(getValue(session)); - } - } else { - if (SysProperties.CHECK && (left == null || right == null)) { - DbException.throwInternalError(); - } - if (left == ValueExpression.getNull() || right == ValueExpression.getNull()) { - // TODO NULL handling: maybe issue a warning when comparing with - // a NULL constants - return ValueExpression.getNull(); - } - if (left.isConstant() && right.isConstant()) { - return ValueExpression.get(getValue(session)); - } - } - return this; - } - - public Value getValue(Session session) { - Value l = left.getValue(session); - if (right == null) { - boolean result; - switch (compareType) { - case IS_NULL: - result = l == ValueNull.INSTANCE; - break; - case IS_NOT_NULL: - result = !(l == ValueNull.INSTANCE); - break; - default: - throw DbException.throwInternalError("type=" + compareType); - } - return ValueBoolean.get(result); - } - if (l == ValueNull.INSTANCE) { - return ValueNull.INSTANCE; - } - Value r = right.getValue(session); - if (r == ValueNull.INSTANCE) { - return ValueNull.INSTANCE; - } - int dataType = Value.getHigherOrder(left.getType(), right.getType()); - l = l.convertTo(dataType); - r = r.convertTo(dataType); - boolean result = compareNotNull(database, l, r, compareType); - return ValueBoolean.get(result); - } - - /** - * Compare two values, given the values are not NULL. - * - * @param database the database - * @param l the first value - * @param r the second value - * @param compareType the compare type - * @return the result of the comparison (1 if the first value is bigger, -1 - * if smaller, 0 if both are equal) - */ - static boolean compareNotNull(Database database, Value l, Value r, int compareType) { - boolean result; - switch (compareType) { - case EQUAL: - result = database.areEqual(l, r); - break; - case NOT_EQUAL: - result = !database.areEqual(l, r); - break; - case BIGGER_EQUAL: - result = database.compare(l, r) >= 0; - break; - case BIGGER: - result = database.compare(l, r) > 0; - break; - case SMALLER_EQUAL: - result = database.compare(l, r) <= 0; - break; - case SMALLER: - result = database.compare(l, r) < 0; - break; - default: - throw DbException.throwInternalError("type=" + compareType); - } - return result; - } - - private int getReversedCompareType(int type) { - switch (compareType) { - case EQUAL: - case NOT_EQUAL: - return type; - case BIGGER_EQUAL: - return SMALLER_EQUAL; - case BIGGER: - return SMALLER; - case SMALLER_EQUAL: - return BIGGER_EQUAL; - case SMALLER: - return BIGGER; - default: - throw DbException.throwInternalError("type=" + compareType); - } - } - - private int getNotCompareType() { - switch (compareType) { - case EQUAL: - return NOT_EQUAL; - case NOT_EQUAL: - return EQUAL; - case BIGGER_EQUAL: - return SMALLER; - case BIGGER: - return SMALLER_EQUAL; - case SMALLER_EQUAL: - return BIGGER; - case SMALLER: - return BIGGER_EQUAL; - case IS_NULL: - return IS_NOT_NULL; - case IS_NOT_NULL: - return IS_NULL; - default: - throw DbException.throwInternalError("type=" + compareType); - } - } - - public Expression getNotIfPossible(Session session) { - int type = getNotCompareType(); - return new Comparison(session, type, left, right); - } - - public void createIndexConditions(Session session, TableFilter filter) { - ExpressionColumn l = null; - if (left instanceof ExpressionColumn) { - l = (ExpressionColumn) left; - if (filter != l.getTableFilter()) { - l = null; - } - } - if (right == null) { - if (l != null) { - switch (compareType) { - case IS_NULL: - if (SysProperties.OPTIMIZE_IS_NULL) { - filter.addIndexCondition(IndexCondition.get(Comparison.EQUAL, l, ValueExpression.getNull())); - } - } - } - return; - } - ExpressionColumn r = null; - if (right instanceof ExpressionColumn) { - r = (ExpressionColumn) right; - if (filter != r.getTableFilter()) { - r = null; - } - } - // one side must be from the current filter - if (l == null && r == null) { - return; - } - if (l != null && r != null) { - return; - } - if (l == null) { - ExpressionVisitor visitor = ExpressionVisitor.get(ExpressionVisitor.NOT_FROM_RESOLVER); - visitor.setResolver(filter); - if (!left.isEverything(visitor)) { - return; - } - } else if (r == null) { - ExpressionVisitor visitor = ExpressionVisitor.get(ExpressionVisitor.NOT_FROM_RESOLVER); - visitor.setResolver(filter); - if (!right.isEverything(visitor)) { - return; - } - } else { - // if both sides are part of the same filter, it can't be used for - // index lookup - return; - } - boolean addIndex; - switch (compareType) { - case NOT_EQUAL: - addIndex = false; - break; - case EQUAL: - case BIGGER: - case BIGGER_EQUAL: - case SMALLER_EQUAL: - case SMALLER: - addIndex = true; - break; - default: - throw DbException.throwInternalError("type=" + compareType); - } - if (addIndex) { - if (l != null) { - filter.addIndexCondition(IndexCondition.get(compareType, l, right)); - } else if (r != null) { - int compareRev = getReversedCompareType(compareType); - filter.addIndexCondition(IndexCondition.get(compareRev, r, left)); - } - } - return; - } - - public void setEvaluatable(TableFilter tableFilter, boolean b) { - left.setEvaluatable(tableFilter, b); - if (right != null) { - right.setEvaluatable(tableFilter, b); - } - } - - public void updateAggregate(Session session) { - left.updateAggregate(session); - if (right != null) { - right.updateAggregate(session); - } - } - - public void addFilterConditions(TableFilter filter, boolean outerJoin) { - if (compareType == IS_NULL && outerJoin) { - // can not optimize: - // select * from test t1 left join test t2 on t1.id = t2.id where t2.id is null - // to - // select * from test t1 left join test t2 on t1.id = t2.id and t2.id is null - return; - } - super.addFilterConditions(filter, outerJoin); - } - - public void mapColumns(ColumnResolver resolver, int level) { - left.mapColumns(resolver, level); - if (right != null) { - right.mapColumns(resolver, level); - } - } - - public boolean isEverything(ExpressionVisitor visitor) { - return left.isEverything(visitor) && (right == null || right.isEverything(visitor)); - } - - public int getCost() { - return left.getCost() + (right == null ? 0 : right.getCost()) + 1; - } - - /** - * Get the other expression if this is an equals comparison and the other - * expression matches. - * - * @param match the expression that should match - * @return null if no match, the other expression if there is a match - */ - Expression getIfEquals(Expression match) { - if (compareType == EQUAL) { - String sql = match.getSQL(); - if (left.getSQL().equals(sql)) { - return right; - } else if (right.getSQL().equals(sql)) { - return left; - } - } - return null; - } - - /** - * Get an additional condition if possible. Example: given two conditions - * A=B AND B=C, the new condition A=C is returned. Given the two conditions - * A=1 OR A=2, the new condition A IN(1, 2) is returned. - * - * @param session the session - * @param other the second condition - * @param add true for AND, false for OR - * @return null or the third condition - */ - Expression getAdditional(Session session, Comparison other, boolean and) { - if (compareType == other.compareType && compareType == EQUAL) { - boolean lc = left.isConstant(), rc = right.isConstant(); - boolean l2c = other.left.isConstant(), r2c = other.right.isConstant(); - String l = left.getSQL(); - String l2 = other.left.getSQL(); - String r = right.getSQL(); - String r2 = other.right.getSQL(); - if (and) { - // a=b AND a=c - // must not compare constants. example: NOT(B=2 AND B=3) - if (!(rc && r2c) && l.equals(l2)) { - return new Comparison(session, EQUAL, right, other.right); - } else if (!(rc && l2c) && l.equals(r2)) { - return new Comparison(session, EQUAL, right, other.left); - } else if (!(lc && r2c) && r.equals(l2)) { - return new Comparison(session, EQUAL, left, other.right); - } else if (!(lc && l2c) && r.equals(r2)) { - return new Comparison(session, EQUAL, left, other.left); - } - } else { - // a=b OR a=c - Database db = session.getDatabase(); - if (rc && r2c && l.equals(l2)) { - return new ConditionIn(db, left, Arrays.asList(right, other.right)); - } else if (rc && l2c && l.equals(r2)) { - return new ConditionIn(db, left, Arrays.asList(right, other.left)); - } else if (lc && r2c && r.equals(l2)) { - return new ConditionIn(db, right, Arrays.asList(left, other.right)); - } else if (lc && l2c && r.equals(r2)) { - return new ConditionIn(db, right, Arrays.asList(left, other.left)); - } - } - } - return null; - } - - /** - * Get the left or the right sub-expression of this condition. - * - * @param getLeft true to get the left sub-expression, false to get the right - * sub-expression. - * @return the sub-expression - */ - public Expression getExpression(boolean getLeft) { - return getLeft ? this.left : right; - } - -} diff --git a/tools/h2/src/main/org/h2/expression/Condition.java b/tools/h2/src/main/org/h2/expression/Condition.java deleted file mode 100755 index cf8b454..0000000 --- a/tools/h2/src/main/org/h2/expression/Condition.java +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.expression; - -import org.h2.value.Value; -import org.h2.value.ValueBoolean; - -/** - * Represents a condition returning a boolean value, or NULL. - */ -public abstract class Condition extends Expression { - - public int getType() { - return Value.BOOLEAN; - } - - public int getScale() { - return 0; - } - - public long getPrecision() { - return ValueBoolean.PRECISION; - } - - public int getDisplaySize() { - return ValueBoolean.DISPLAY_SIZE; - } - -} diff --git a/tools/h2/src/main/org/h2/expression/ConditionAndOr.java b/tools/h2/src/main/org/h2/expression/ConditionAndOr.java deleted file mode 100755 index 0ce1fb0..0000000 --- a/tools/h2/src/main/org/h2/expression/ConditionAndOr.java +++ /dev/null @@ -1,265 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.expression; - -import org.h2.constant.SysProperties; -import org.h2.engine.Session; -import org.h2.message.DbException; -import org.h2.table.ColumnResolver; -import org.h2.table.TableFilter; -import org.h2.value.Value; -import org.h2.value.ValueBoolean; -import org.h2.value.ValueNull; - -/** - * An 'and' or 'or' condition as in WHERE ID=1 AND NAME=? - */ -public class ConditionAndOr extends Condition { - - /** - * The AND condition type as in ID=1 AND NAME='Hello'. - */ - public static final int AND = 0; - - /** - * The OR condition type as in ID=1 OR NAME='Hello'. - */ - public static final int OR = 1; - - private final int andOrType; - private Expression left, right; - - public ConditionAndOr(int andOrType, Expression left, Expression right) { - this.andOrType = andOrType; - this.left = left; - this.right = right; - if (SysProperties.CHECK && (left == null || right == null)) { - DbException.throwInternalError(); - } - } - - public String getSQL() { - String sql; - switch (andOrType) { - case AND: - sql = left.getSQL() + " AND " + right.getSQL(); - break; - case OR: - sql = left.getSQL() + " OR " + right.getSQL(); - break; - default: - throw DbException.throwInternalError("andOrType=" + andOrType); - } - return "(" + sql + ")"; - } - - public void createIndexConditions(Session session, TableFilter filter) { - if (andOrType == AND) { - left.createIndexConditions(session, filter); - right.createIndexConditions(session, filter); - } - } - - public Expression getNotIfPossible(Session session) { - // (NOT (A OR B)): (NOT(A) AND NOT(B)) - // (NOT (A AND B)): (NOT(A) OR NOT(B)) - Expression l = left.getNotIfPossible(session); - if (l == null) { - l = new ConditionNot(left); - } - Expression r = right.getNotIfPossible(session); - if (r == null) { - r = new ConditionNot(right); - } - int reversed = andOrType == AND ? OR : AND; - return new ConditionAndOr(reversed, l, r); - } - - public Value getValue(Session session) { - Value l = left.getValue(session); - Value r; - switch (andOrType) { - case AND: { - if (Boolean.FALSE.equals(l.getBoolean())) { - return l; - } - r = right.getValue(session); - if (Boolean.FALSE.equals(r.getBoolean())) { - return r; - } - if (l == ValueNull.INSTANCE) { - return l; - } - if (r == ValueNull.INSTANCE) { - return r; - } - return ValueBoolean.get(true); - } - case OR: { - if (Boolean.TRUE.equals(l.getBoolean())) { - return l; - } - r = right.getValue(session); - if (Boolean.TRUE.equals(r.getBoolean())) { - return r; - } - if (l == ValueNull.INSTANCE) { - return l; - } - if (r == ValueNull.INSTANCE) { - return r; - } - return ValueBoolean.get(false); - } - default: - throw DbException.throwInternalError("type=" + andOrType); - } - } - - public Expression optimize(Session session) { - // NULL handling: see wikipedia, - // http://www-cs-students.stanford.edu/~wlam/compsci/sqlnulls - left = left.optimize(session); - right = right.optimize(session); - int lc = left.getCost(), rc = right.getCost(); - if (rc < lc) { - Expression t = left; - left = right; - right = t; - } - // this optimization does not work in the following case, - // but NOT is optimized before: - // CREATE TABLE TEST(A INT, B INT); - // INSERT INTO TEST VALUES(1, NULL); - // SELECT * FROM TEST WHERE NOT (B=A AND B=0); // no rows - // SELECT * FROM TEST WHERE NOT (B=A AND B=0 AND A=0); // 1, NULL - if (SysProperties.OPTIMIZE_TWO_EQUALS && andOrType == AND) { - // try to add conditions (A=B AND B=1: add A=1) - if (left instanceof Comparison && right instanceof Comparison) { - Comparison compLeft = (Comparison) left; - Comparison compRight = (Comparison) right; - Expression added = compLeft.getAdditional(session, compRight, true); - if (added != null) { - added = added.optimize(session); - ConditionAndOr a = new ConditionAndOr(AND, this, added); - return a; - } - } - } - // TODO optimization: convert ((A=1 AND B=2) OR (A=1 AND B=3)) to - // (A=1 AND (B=2 OR B=3)) - if (SysProperties.OPTIMIZE_OR && andOrType == OR) { - // try to add conditions (A=B AND B=1: add A=1) - if (left instanceof Comparison && right instanceof Comparison) { - Comparison compLeft = (Comparison) left; - Comparison compRight = (Comparison) right; - Expression added = compLeft.getAdditional(session, compRight, false); - if (added != null) { - return added.optimize(session); - } - } else if (left instanceof ConditionIn && right instanceof Comparison) { - Expression added = ((ConditionIn) left).getAdditional(session, (Comparison) right); - if (added != null) { - return added.optimize(session); - } - } else if (right instanceof ConditionIn && left instanceof Comparison) { - Expression added = ((ConditionIn) right).getAdditional(session, (Comparison) left); - if (added != null) { - return added.optimize(session); - } - } - } - // TODO optimization: convert .. OR .. to UNION if the cost is lower - Value l = left.isConstant() ? left.getValue(session) : null; - Value r = right.isConstant() ? right.getValue(session) : null; - if (l == null && r == null) { - return this; - } - if (l != null && r != null) { - return ValueExpression.get(getValue(session)); - } - switch (andOrType) { - case AND: - if (l != null) { - if (Boolean.FALSE.equals(l.getBoolean())) { - return ValueExpression.get(l); - } else if (Boolean.TRUE.equals(l.getBoolean())) { - return right; - } - } else if (r != null) { - if (Boolean.FALSE.equals(r.getBoolean())) { - return ValueExpression.get(r); - } else if (Boolean.TRUE.equals(r.getBoolean())) { - return left; - } - } - break; - case OR: - if (l != null) { - if (Boolean.TRUE.equals(l.getBoolean())) { - return ValueExpression.get(l); - } else if (Boolean.FALSE.equals(l.getBoolean())) { - return right; - } - } else if (r != null) { - if (Boolean.TRUE.equals(r.getBoolean())) { - return ValueExpression.get(r); - } else if (Boolean.FALSE.equals(r.getBoolean())) { - return left; - } - } - break; - default: - DbException.throwInternalError("type=" + andOrType); - } - return this; - } - - public void addFilterConditions(TableFilter filter, boolean outerJoin) { - if (andOrType == AND) { - left.addFilterConditions(filter, outerJoin); - right.addFilterConditions(filter, outerJoin); - } else { - super.addFilterConditions(filter, outerJoin); - } - } - - public void mapColumns(ColumnResolver resolver, int level) { - left.mapColumns(resolver, level); - right.mapColumns(resolver, level); - } - - public void setEvaluatable(TableFilter tableFilter, boolean b) { - left.setEvaluatable(tableFilter, b); - right.setEvaluatable(tableFilter, b); - } - - public void updateAggregate(Session session) { - left.updateAggregate(session); - right.updateAggregate(session); - } - - public boolean isEverything(ExpressionVisitor visitor) { - return left.isEverything(visitor) && right.isEverything(visitor); - } - - public int getCost() { - return left.getCost() + right.getCost(); - } - - /** - * Get the left or the right sub-expression of this condition. - * - * @param getLeft true to get the left sub-expression, false to get the right - * sub-expression. - * @return the sub-expression - */ - public Expression getExpression(boolean getLeft) { - return getLeft ? this.left : right; - } - -} diff --git a/tools/h2/src/main/org/h2/expression/ConditionExists.java b/tools/h2/src/main/org/h2/expression/ConditionExists.java deleted file mode 100755 index 3cee510..0000000 --- a/tools/h2/src/main/org/h2/expression/ConditionExists.java +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.expression; - -import org.h2.command.dml.Query; -import org.h2.engine.Session; -import org.h2.result.ResultInterface; -import org.h2.table.ColumnResolver; -import org.h2.table.TableFilter; -import org.h2.value.Value; -import org.h2.value.ValueBoolean; - -/** - * An 'exists' condition as in WHERE EXISTS(SELECT ...) - */ -public class ConditionExists extends Condition { - - private final Query query; - - public ConditionExists(Query query) { - this.query = query; - } - - public Value getValue(Session session) { - query.setSession(session); - ResultInterface result = query.query(1); - session.addTemporaryResult(result); - boolean r = result.getRowCount() > 0; - return ValueBoolean.get(r); - } - - public Expression optimize(Session session) { - query.prepare(); - return this; - } - - public String getSQL() { - return "EXISTS(" + query.getPlanSQL() + ")"; - } - - public void updateAggregate(Session session) { - // TODO exists: is it allowed that the subquery contains aggregates? - // probably not - // select id from test group by id having exists (select * from test2 - // where id=count(test.id)) - } - - public void mapColumns(ColumnResolver resolver, int level) { - query.mapColumns(resolver, level + 1); - } - - public void setEvaluatable(TableFilter tableFilter, boolean b) { - query.setEvaluatable(tableFilter, b); - } - - public boolean isEverything(ExpressionVisitor visitor) { - return query.isEverything(visitor); - } - - public int getCost() { - return 10 + (int) (10 * query.getCost()); - } - -} diff --git a/tools/h2/src/main/org/h2/expression/ConditionIn.java b/tools/h2/src/main/org/h2/expression/ConditionIn.java deleted file mode 100755 index 07c85ad..0000000 --- a/tools/h2/src/main/org/h2/expression/ConditionIn.java +++ /dev/null @@ -1,190 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.expression; - -import java.util.List; -import org.h2.constant.SysProperties; -import org.h2.engine.Database; -import org.h2.engine.Session; -import org.h2.index.IndexCondition; -import org.h2.table.ColumnResolver; -import org.h2.table.TableFilter; -import org.h2.util.StatementBuilder; -import org.h2.value.Value; -import org.h2.value.ValueBoolean; -import org.h2.value.ValueNull; - -/** - * An 'in' condition with a list of values, as in WHERE NAME IN(...) - */ -public class ConditionIn extends Condition { - - private final Database database; - private Expression left; - private final List valueList; - private int queryLevel; - - /** - * Create a new IN(..) condition. - * - * @param database the database - * @param left the expression before IN - * @param values the value list (at least one element) - */ - public ConditionIn(Database database, Expression left, List values) { - this.database = database; - this.left = left; - this.valueList = values; - } - - public Value getValue(Session session) { - Value l = left.getValue(session); - if (l == ValueNull.INSTANCE) { - return l; - } - boolean result = false; - boolean hasNull = false; - for (Expression e : valueList) { - Value r = e.getValue(session); - if (r == ValueNull.INSTANCE) { - hasNull = true; - } else { - r = r.convertTo(l.getType()); - result = Comparison.compareNotNull(database, l, r, Comparison.EQUAL); - if (result) { - break; - } - } - } - if (!result && hasNull) { - return ValueNull.INSTANCE; - } - return ValueBoolean.get(result); - } - - public void mapColumns(ColumnResolver resolver, int level) { - left.mapColumns(resolver, level); - for (Expression e : valueList) { - e.mapColumns(resolver, level); - } - this.queryLevel = Math.max(level, this.queryLevel); - } - - public Expression optimize(Session session) { - left = left.optimize(session); - boolean constant = left.isConstant(); - if (constant && left == ValueExpression.getNull()) { - return left; - } - boolean allValuesConstant = true; - for (int i = 0; i < valueList.size(); i++) { - Expression e = valueList.get(i); - e = e.optimize(session); - if (allValuesConstant && !e.isConstant()) { - allValuesConstant = false; - } - valueList.set(i, e); - } - if (constant && allValuesConstant) { - return ValueExpression.get(getValue(session)); - } - if (valueList.size() == 1) { - Expression right = valueList.get(0); - Expression expr = new Comparison(session, Comparison.EQUAL, left, right); - expr = expr.optimize(session); - return expr; - } - return this; - } - - public void createIndexConditions(Session session, TableFilter filter) { - if (!(left instanceof ExpressionColumn)) { - return; - } - ExpressionColumn l = (ExpressionColumn) left; - if (filter != l.getTableFilter()) { - return; - } - if (SysProperties.OPTIMIZE_IN_LIST) { - ExpressionVisitor visitor = ExpressionVisitor.get(ExpressionVisitor.NOT_FROM_RESOLVER); - visitor.setResolver(filter); - for (Expression e : valueList) { - if (!e.isEverything(visitor)) { - return; - } - } - filter.addIndexCondition(IndexCondition.getInList(l, valueList)); - return; - } - } - - public void setEvaluatable(TableFilter tableFilter, boolean b) { - left.setEvaluatable(tableFilter, b); - for (Expression e : valueList) { - e.setEvaluatable(tableFilter, b); - } - } - - public String getSQL() { - StatementBuilder buff = new StatementBuilder("("); - buff.append(left.getSQL()).append(" IN("); - for (Expression e : valueList) { - buff.appendExceptFirst(", "); - buff.append(e.getSQL()); - } - return buff.append("))").toString(); - } - - public void updateAggregate(Session session) { - left.updateAggregate(session); - for (Expression e : valueList) { - e.updateAggregate(session); - } - } - - public boolean isEverything(ExpressionVisitor visitor) { - if (!left.isEverything(visitor)) { - return false; - } - return areAllValues(visitor); - } - - private boolean areAllValues(ExpressionVisitor visitor) { - for (Expression e : valueList) { - if (!e.isEverything(visitor)) { - return false; - } - } - return true; - } - - public int getCost() { - int cost = left.getCost(); - for (Expression e : valueList) { - cost += e.getCost(); - } - return cost; - } - - /** - * Add an additional element if possible. Example: given two conditions - * A IN(1, 2) OR A=3, the constant 3 is added: A IN(1, 2, 3). - * - * @param session the session - * @param other the second condition - * @return null if the condition was not added, or the new condition - */ - public Expression getAdditional(Session session, Comparison other) { - Expression add = other.getIfEquals(left); - if (add != null) { - valueList.add(add); - return this; - } - return null; - } - -} diff --git a/tools/h2/src/main/org/h2/expression/ConditionInSelect.java b/tools/h2/src/main/org/h2/expression/ConditionInSelect.java deleted file mode 100755 index 11a4294..0000000 --- a/tools/h2/src/main/org/h2/expression/ConditionInSelect.java +++ /dev/null @@ -1,142 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.expression; - -import org.h2.command.dml.Query; -import org.h2.constant.ErrorCode; -import org.h2.constant.SysProperties; -import org.h2.engine.Database; -import org.h2.engine.Session; -import org.h2.index.IndexCondition; -import org.h2.message.DbException; -import org.h2.result.ResultInterface; -import org.h2.table.ColumnResolver; -import org.h2.table.TableFilter; -import org.h2.value.Value; -import org.h2.value.ValueBoolean; -import org.h2.value.ValueNull; - -/** - * An 'in' condition with a subquery, as in WHERE ID IN(SELECT ...) - */ -public class ConditionInSelect extends Condition { - private Database database; - private Expression left; - private Query query; - private boolean all; - private int compareType; - private int queryLevel; - - public ConditionInSelect(Database database, Expression left, Query query, boolean all, int compareType) { - this.database = database; - this.left = left; - this.query = query; - this.all = all; - this.compareType = compareType; - } - - public Value getValue(Session session) { - query.setSession(session); - ResultInterface rows = query.query(0); - session.addTemporaryResult(rows); - boolean hasNull = false; - boolean result = all; - Value l = left.getValue(session); - boolean hasRow = false; - while (rows.next()) { - if (!hasRow) { - if (l == ValueNull.INSTANCE) { - return l; - } - hasRow = true; - } - boolean value; - Value r = rows.currentRow()[0]; - if (r == ValueNull.INSTANCE) { - value = false; - hasNull = true; - } else { - value = Comparison.compareNotNull(database, l, r, compareType); - } - if (!value && all) { - result = false; - break; - } else if (value && !all) { - result = true; - break; - } - } - if (!hasRow) { - return ValueBoolean.get(false); - } - if (!result && hasNull) { - return ValueNull.INSTANCE; - } - return ValueBoolean.get(result); - } - - public void mapColumns(ColumnResolver resolver, int level) { - left.mapColumns(resolver, level); - query.mapColumns(resolver, level + 1); - this.queryLevel = Math.max(level, this.queryLevel); - } - - public Expression optimize(Session session) { - left = left.optimize(session); - query.setDistinct(true); - query.prepare(); - if (query.getColumnCount() != 1) { - throw DbException.get(ErrorCode.SUBQUERY_IS_NOT_SINGLE_COLUMN); - } - // Can not optimize: the data may change - return this; - } - - public void setEvaluatable(TableFilter tableFilter, boolean b) { - left.setEvaluatable(tableFilter, b); - query.setEvaluatable(tableFilter, b); - } - - public String getSQL() { - return "(" + left.getSQL() + " IN(" + query.getPlanSQL() + "))"; - } - - public void updateAggregate(Session session) { - // TODO exists: is it allowed that the subquery contains aggregates? - // probably not - // select id from test group by id having 1 in (select * from test2 - // where id=count(test.id)) - } - - public boolean isEverything(ExpressionVisitor visitor) { - return left.isEverything(visitor) && query.isEverything(visitor); - } - - public int getCost() { - return left.getCost() + 10 + (int) (10 * query.getCost()); - } - - public void createIndexConditions(Session session, TableFilter filter) { - if (!SysProperties.OPTIMIZE_IN_LIST) { - return; - } - if (!(left instanceof ExpressionColumn)) { - return; - } - ExpressionColumn l = (ExpressionColumn) left; - if (filter != l.getTableFilter()) { - return; - } - ExpressionVisitor visitor = ExpressionVisitor.get(ExpressionVisitor.NOT_FROM_RESOLVER); - visitor.setResolver(filter); - if (!query.isEverything(visitor)) { - return; - } - filter.addIndexCondition(IndexCondition.getInQuery(l, query)); - } - -} diff --git a/tools/h2/src/main/org/h2/expression/ConditionNot.java b/tools/h2/src/main/org/h2/expression/ConditionNot.java deleted file mode 100755 index 7b371b5..0000000 --- a/tools/h2/src/main/org/h2/expression/ConditionNot.java +++ /dev/null @@ -1,92 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.expression; - -import org.h2.engine.Session; -import org.h2.table.ColumnResolver; -import org.h2.table.TableFilter; -import org.h2.value.Value; -import org.h2.value.ValueNull; - -/** - * A NOT condition. - */ -public class ConditionNot extends Condition { - - private Expression condition; - - public ConditionNot(Expression condition) { - this.condition = condition; - } - - public Expression getNotIfPossible(Session session) { - return condition; - } - - public Value getValue(Session session) { - Value v = condition.getValue(session); - if (v == ValueNull.INSTANCE) { - return v; - } - return v.convertTo(Value.BOOLEAN).negate(); - } - - public void mapColumns(ColumnResolver resolver, int level) { - condition.mapColumns(resolver, level); - } - - public Expression optimize(Session session) { - Expression e2 = condition.getNotIfPossible(session); - if (e2 != null) { - return e2.optimize(session); - } - Expression expr = condition.optimize(session); - if (expr.isConstant()) { - Value v = expr.getValue(session); - if (v == ValueNull.INSTANCE) { - return ValueExpression.getNull(); - } - return ValueExpression.get(v.convertTo(Value.BOOLEAN).negate()); - } - condition = expr; - return this; - } - - public void setEvaluatable(TableFilter tableFilter, boolean b) { - condition.setEvaluatable(tableFilter, b); - } - - public String getSQL() { - return "(NOT " + condition.getSQL() + ")"; - } - - public void updateAggregate(Session session) { - condition.updateAggregate(session); - } - - public void addFilterConditions(TableFilter filter, boolean outerJoin) { - if (outerJoin) { - // can not optimize: - // select * from test t1 left join test t2 on t1.id = t2.id where - // not t2.id is not null - // to - // select * from test t1 left join test t2 on t1.id = t2.id and - // t2.id is not null - return; - } - super.addFilterConditions(filter, outerJoin); - } - - public boolean isEverything(ExpressionVisitor visitor) { - return condition.isEverything(visitor); - } - - public int getCost() { - return condition.getCost(); - } - -} diff --git a/tools/h2/src/main/org/h2/expression/Expression.java b/tools/h2/src/main/org/h2/expression/Expression.java deleted file mode 100755 index 2781bbb..0000000 --- a/tools/h2/src/main/org/h2/expression/Expression.java +++ /dev/null @@ -1,295 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.expression; - -import org.h2.engine.Session; -import org.h2.table.Column; -import org.h2.table.ColumnResolver; -import org.h2.table.TableFilter; -import org.h2.util.StringUtils; -import org.h2.value.Value; - -/** - * An expression is a operation, a value, or a function in a query. - */ -public abstract class Expression { - - private boolean addedToFilter; - - /** - * Return the resulting value for the current row. - * - * @param session the session - * @return the result - */ - public abstract Value getValue(Session session); - - /** - * Return the data type. The data type may not be known before the - * optimization phase. - * - * @return the type - */ - public abstract int getType(); - - /** - * Map the columns of the resolver to expression columns. - * - * @param resolver the column resolver - * @param level the subquery nesting level - */ - public abstract void mapColumns(ColumnResolver resolver, int level); - - /** - * Try to optimize the expression. - * - * @param session the session - * @return the optimized expression - */ - public abstract Expression optimize(Session session); - - /** - * Tell the expression columns whether the table filter can return values now. - * This is used when optimizing the query. - * - * @param tableFilter the table filter - * @param value true if the table filter can return value - */ - public abstract void setEvaluatable(TableFilter tableFilter, boolean value); - - /** - * Get the scale of this expression. - * - * @return the scale - */ - public abstract int getScale(); - - /** - * Get the precision of this expression. - * - * @return the precision - */ - public abstract long getPrecision(); - - /** - * Get the display size of this expression. - * - * @return the display size - */ - public abstract int getDisplaySize(); - - /** - * Get the SQL statement of this expression. - * This may not always be the original SQL statement, - * specially after optimization. - * - * @return the SQL statement - */ - public abstract String getSQL(); - - /** - * Update an aggregate value. - * This method is called at statement execution time. - * It is usually called once for each row, but if the expression is used multiple - * times (for example in the column list, and as part of the HAVING expression) - * it is called multiple times - the row counter needs to be used to make sure - * the internal state is only updated once. - * - * @param session the session - */ - public abstract void updateAggregate(Session session); - - /** - * Check if this expression and all sub-expressions can fulfill a criteria. - * If any part returns false, the result is false. - * - * @param visitor the visitor - * @return if the criteria can be fulfilled - */ - public abstract boolean isEverything(ExpressionVisitor visitor); - - /** - * Estimate the cost to process the expression. - * Used when optimizing the query, to calculate the query plan - * with the lowest estimated cost. - * - * @return the estimated cost - */ - public abstract int getCost(); - - /** - * Check if this expression and all sub-expressions can fulfill a criteria. - * This is a convenience function. - * - * @param expressionVisitorType the visitor type - * @return if the criteria can be fulfilled - */ - public final boolean isEverything(int expressionVisitorType) { - ExpressionVisitor visitor = ExpressionVisitor.get(expressionVisitorType); - return isEverything(visitor); - } - - /** - * If it is possible, return the negated expression. This is used - * to optimize NOT expressions: NOT ID>10 can be converted to - * ID<=10. Returns null if negating is not possible. - * - * @param session the session - * @return the negated expression, or null - */ - public Expression getNotIfPossible(Session session) { - // by default it is not possible - return null; - } - - /** - * Check if this expression will always return the same value. - * - * @return if the expression is constant - */ - public boolean isConstant() { - return false; - } - - /** - * Is the value of a parameter set. - * - * @return if it is set - */ - public boolean isValueSet() { - return false; - } - - /** - * Check if this is an auto-increment column. - * - * @return true if it is an auto-increment column - */ - public boolean isAutoIncrement() { - return false; - } - - /** - * Get the value in form of a boolean expression. - * Returns true, false, or null. - * In this database, everything can be a condition. - * - * @param session the session - * @return the result - */ - public Boolean getBooleanValue(Session session) { - return getValue(session).getBoolean(); - } - - /** - * Create index conditions if possible and attach them to the table filter. - * - * @param session the session - * @param filter the table filter - * @throws SQLException - */ - public void createIndexConditions(Session session, TableFilter filter) { - // default is do nothing - } - - /** - * Get the column name or alias name of this expression. - * - * @return the column name - */ - public String getColumnName() { - return getAlias(); - } - - /** - * Get the schema name, or null - * - * @return the schema name - */ - public String getSchemaName() { - return null; - } - - /** - * Get the table name, or null - * - * @return the table name - */ - public String getTableName() { - return null; - } - - /** - * Check whether this expression is a column and can store null values. - * - * @return whether null values are allowed - */ - public int getNullable() { - return Column.NULLABLE_UNKNOWN; - } - - /** - * Get the table alias name or null - * if this expression does not represent a column. - * - * @return the table alias name - */ - public String getTableAlias() { - return null; - } - - /** - * Get the alias name of a column or SQL expression - * if it is not an aliased expression. - * - * @return the alias name - */ - public String getAlias() { - return StringUtils.unEnclose(getSQL()); - } - - /** - * Only returns true if the expression is a wildcard. - * - * @return if this expression is a wildcard - */ - public boolean isWildcard() { - return false; - } - - /** - * Returns the main expression, skipping aliases. - * - * @return the expression - */ - public Expression getNonAliasExpression() { - return this; - } - - /** - * Add conditions to a table filter if they can be evaluated. - * - * @param filter the table filter - * @param outerJoin if the expression is part of an outer join - */ - public void addFilterConditions(TableFilter filter, boolean outerJoin) { - if (!addedToFilter && !outerJoin && isEverything(ExpressionVisitor.EVALUATABLE)) { - filter.addFilterCondition(this, false); - addedToFilter = true; - } - } - - /** - * Convert this expression to a String. - * - * @return the string representation - */ - public String toString() { - return getSQL(); - } - -} diff --git a/tools/h2/src/main/org/h2/expression/ExpressionColumn.java b/tools/h2/src/main/org/h2/expression/ExpressionColumn.java deleted file mode 100755 index 1ace804..0000000 --- a/tools/h2/src/main/org/h2/expression/ExpressionColumn.java +++ /dev/null @@ -1,278 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.expression; - -import java.util.HashMap; -import org.h2.command.Parser; -import org.h2.command.dml.Select; -import org.h2.command.dml.SelectListColumnResolver; -import org.h2.constant.ErrorCode; -import org.h2.engine.Database; -import org.h2.engine.Session; -import org.h2.index.IndexCondition; -import org.h2.message.DbException; -import org.h2.schema.Constant; -import org.h2.schema.Schema; -import org.h2.table.Column; -import org.h2.table.ColumnResolver; -import org.h2.table.Table; -import org.h2.table.TableFilter; -import org.h2.value.Value; -import org.h2.value.ValueBoolean; - -/** - * A expression that represents a column of a table or view. - */ -public class ExpressionColumn extends Expression { - private Database database; - private String schemaName; - private String tableAlias; - private String columnName; - private ColumnResolver columnResolver; - private int queryLevel; - private Column column; - private boolean evaluatable; - - public ExpressionColumn(Database database, Column column) { - this.database = database; - this.column = column; - } - - public ExpressionColumn(Database database, String schemaName, String tableAlias, String columnName) { - this.database = database; - this.schemaName = schemaName; - this.tableAlias = tableAlias; - this.columnName = columnName; - } - - public String getSQL() { - String sql; - if (column != null) { - sql = column.getSQL(); - } else { - sql = Parser.quoteIdentifier(columnName); - } - if (tableAlias != null) { - sql = Parser.quoteIdentifier(tableAlias) + "." + sql; - } - if (schemaName != null) { - sql = Parser.quoteIdentifier(schemaName) + "." + sql; - } - return sql; - } - - public TableFilter getTableFilter() { - return columnResolver == null ? null : columnResolver.getTableFilter(); - } - - public void mapColumns(ColumnResolver resolver, int level) { - if (tableAlias != null && !tableAlias.equals(resolver.getTableAlias())) { - return; - } - if (schemaName != null && !schemaName.equals(resolver.getSchemaName())) { - return; - } - for (Column col : resolver.getColumns()) { - if (columnName.equals(col.getName())) { - mapColumn(resolver, col, level); - return; - } - } - Column[] columns = resolver.getSystemColumns(); - for (int i = 0; columns != null && i < columns.length; i++) { - Column col = columns[i]; - if (columnName.equals(col.getName())) { - mapColumn(resolver, col, level); - return; - } - } - } - - private void mapColumn(ColumnResolver resolver, Column col, int level) { - if (this.columnResolver == null) { - queryLevel = level; - column = col; - this.columnResolver = resolver; - } else if (queryLevel == level && this.columnResolver != resolver) { - if (resolver instanceof SelectListColumnResolver) { - // ignore - already mapped, that's ok - } else { - throw DbException.get(ErrorCode.AMBIGUOUS_COLUMN_NAME_1, columnName); - } - } - } - - public Expression optimize(Session session) { - if (columnResolver == null) { - Schema schema = session.getDatabase().findSchema( - tableAlias == null ? session.getCurrentSchemaName() : tableAlias); - if (schema != null) { - Constant constant = schema.findConstant(columnName); - if (constant != null) { - return constant.getValue(); - } - } - String name = columnName; - if (tableAlias != null) { - name = tableAlias + "." + name; - if (schemaName != null) { - name = schemaName + "." + name; - } - } - throw DbException.get(ErrorCode.COLUMN_NOT_FOUND_1, name); - } - return columnResolver.optimize(this, column); - } - - public void updateAggregate(Session session) { - Value now = columnResolver.getValue(column); - Select select = columnResolver.getSelect(); - if (select == null) { - throw DbException.get(ErrorCode.MUST_GROUP_BY_COLUMN_1, getSQL()); - } - HashMap values = select.getCurrentGroup(); - if (values == null) { - // this is a different level (the enclosing query) - return; - } - Value v = (Value) values.get(this); - if (v == null) { - values.put(this, now); - } else { - if (!database.areEqual(now, v)) { - throw DbException.get(ErrorCode.MUST_GROUP_BY_COLUMN_1, getSQL()); - } - } - } - - public Value getValue(Session session) { - // TODO refactor: simplify check if really part of an aggregated value / - // detection of - // usage of non-grouped by columns without aggregate function - Select select = columnResolver.getSelect(); - if (select != null) { - HashMap values = select.getCurrentGroup(); - if (values != null) { - Value v = (Value) values.get(this); - if (v != null) { - return v; - } - } - } - Value value = columnResolver.getValue(column); - if (value == null) { - throw DbException.get(ErrorCode.MUST_GROUP_BY_COLUMN_1, getSQL()); - } - return value; - } - - public int getType() { - return column.getType(); - } - - public void setEvaluatable(TableFilter tableFilter, boolean b) { - if (columnResolver != null && tableFilter == columnResolver.getTableFilter()) { - evaluatable = b; - } - } - - public Column getColumn() { - return column; - } - - public int getScale() { - return column.getScale(); - } - - public long getPrecision() { - return column.getPrecision(); - } - - public int getDisplaySize() { - return column.getDisplaySize(); - } - - public String getOriginalColumnName() { - return columnName; - } - - public String getOriginalTableAliasName() { - return tableAlias; - } - - public String getColumnName() { - return columnName != null ? columnName : column.getName(); - } - - public String getSchemaName() { - Table table = column.getTable(); - return table == null ? null : table.getSchema().getName(); - } - - public String getTableName() { - Table table = column.getTable(); - return table == null ? null : table.getName(); - } - - public String getAlias() { - return column == null ? null : column.getName(); - } - - public boolean isAutoIncrement() { - return column.getSequence() != null; - } - - public int getNullable() { - return column.isNullable() ? Column.NULLABLE : Column.NOT_NULLABLE; - } - - public boolean isEverything(ExpressionVisitor visitor) { - switch (visitor.getType()) { - case ExpressionVisitor.OPTIMIZABLE_MIN_MAX_COUNT_ALL: - return false; - case ExpressionVisitor.READONLY: - case ExpressionVisitor.DETERMINISTIC: - case ExpressionVisitor.QUERY_COMPARABLE: - return true; - case ExpressionVisitor.INDEPENDENT: - return this.queryLevel < visitor.getQueryLevel(); - case ExpressionVisitor.EVALUATABLE: - // if the current value is known (evaluatable set) - // or if this columns belongs to a 'higher level' query and is - // therefore just a parameter - return evaluatable || visitor.getQueryLevel() < this.queryLevel; - case ExpressionVisitor.SET_MAX_DATA_MODIFICATION_ID: - visitor.addDataModificationId(column.getTable().getMaxDataModificationId()); - return true; - case ExpressionVisitor.NOT_FROM_RESOLVER: - return columnResolver != visitor.getResolver(); - case ExpressionVisitor.GET_DEPENDENCIES: - visitor.addDependency(column.getTable()); - return true; - default: - throw DbException.throwInternalError("type=" + visitor.getType()); - } - } - - public int getCost() { - return 2; - } - - public void createIndexConditions(Session session, TableFilter filter) { - TableFilter tf = getTableFilter(); - if (filter == tf && column.getType() == Value.BOOLEAN) { - IndexCondition cond = IndexCondition.get(Comparison.EQUAL, this, ValueExpression - .get(ValueBoolean.get(true))); - filter.addIndexCondition(cond); - } - } - - public Expression getNotIfPossible(Session session) { - return new Comparison(session, Comparison.EQUAL, this, ValueExpression.get(ValueBoolean.get(false))); - } - -} diff --git a/tools/h2/src/main/org/h2/expression/ExpressionList.java b/tools/h2/src/main/org/h2/expression/ExpressionList.java deleted file mode 100755 index 415e3fd..0000000 --- a/tools/h2/src/main/org/h2/expression/ExpressionList.java +++ /dev/null @@ -1,111 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.expression; - -import org.h2.engine.Session; -import org.h2.table.ColumnResolver; -import org.h2.table.TableFilter; -import org.h2.util.StatementBuilder; -import org.h2.value.Value; -import org.h2.value.ValueArray; - -/** - * A list of expressions, as in (ID, NAME). - * The result of this expression is an array. - */ -public class ExpressionList extends Expression { - - private Expression[] list; - - public ExpressionList(Expression[] list) { - this.list = list; - } - - public Value getValue(Session session) { - Value[] v = new Value[list.length]; - for (int i = 0; i < list.length; i++) { - v[i] = list[i].getValue(session); - } - return ValueArray.get(v); - } - - public int getType() { - return Value.ARRAY; - } - - public void mapColumns(ColumnResolver resolver, int level) { - for (Expression e : list) { - e.mapColumns(resolver, level); - } - } - - public Expression optimize(Session session) { - boolean allConst = true; - for (int i = 0; i < list.length; i++) { - Expression e = list[i].optimize(session); - if (!e.isConstant()) { - allConst = false; - } - list[i] = e; - } - if (allConst) { - return ValueExpression.get(getValue(session)); - } - return this; - } - - public void setEvaluatable(TableFilter tableFilter, boolean b) { - for (Expression e : list) { - e.setEvaluatable(tableFilter, b); - } - } - - public int getScale() { - return 0; - } - - public long getPrecision() { - return Integer.MAX_VALUE; - } - - public int getDisplaySize() { - return Integer.MAX_VALUE; - } - - public String getSQL() { - StatementBuilder buff = new StatementBuilder("("); - for (Expression e: list) { - buff.appendExceptFirst(", "); - buff.append(e.getSQL()); - } - return buff.append(')').toString(); - } - - public void updateAggregate(Session session) { - for (Expression e : list) { - e.updateAggregate(session); - } - } - - public boolean isEverything(ExpressionVisitor visitor) { - for (Expression e : list) { - if (!e.isEverything(visitor)) { - return false; - } - } - return true; - } - - public int getCost() { - int cost = 1; - for (Expression e : list) { - cost += e.getCost(); - } - return cost; - } - -} diff --git a/tools/h2/src/main/org/h2/expression/ExpressionVisitor.java b/tools/h2/src/main/org/h2/expression/ExpressionVisitor.java deleted file mode 100755 index 188caa1..0000000 --- a/tools/h2/src/main/org/h2/expression/ExpressionVisitor.java +++ /dev/null @@ -1,212 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.expression; - -import java.util.HashSet; - -import org.h2.engine.DbObject; -import org.h2.table.ColumnResolver; -import org.h2.table.Table; - -/** - * The visitor pattern is used to iterate through all expressions of a query - * to optimize a statement. - */ -public class ExpressionVisitor { - - /** - * Is the value independent on unset parameters or on columns of a higher - * level query, or sequence values (that means can it be evaluated right - * now)? - */ - public static final int INDEPENDENT = 0; - - /** - * Are all aggregates MIN(column), MAX(column), or COUNT(*) for the given - * table (getTable)? - */ - public static final int OPTIMIZABLE_MIN_MAX_COUNT_ALL = 1; - - /** - * Does the expression return the same results for the same parameters? - */ - public static final int DETERMINISTIC = 2; - - /** - * Can the expression be evaluated, that means are all columns set to - * 'evaluatable'? - */ - public static final int EVALUATABLE = 3; - - /** - * Request to set the latest modification id. - */ - public static final int SET_MAX_DATA_MODIFICATION_ID = 4; - - /** - * Does the expression have no side effects (change the data)? - */ - public static final int READONLY = 5; - - /** - * Does an expression have no relation to the given table filter - * (getResolver)? - */ - public static final int NOT_FROM_RESOLVER = 6; - - /** - * Request to get the set of dependencies. - */ - public static final int GET_DEPENDENCIES = 7; - - /** - * Can the expression be added to a condition of an outer query. - * Example: ROWNUM() can't be added as a condition to the inner query of - * select id from (select t.*, rownum as r from test t) where r between 2 and 3; - * Also a sequence expression must not be used. - */ - public static final int QUERY_COMPARABLE = 8; - - private int queryLevel; - private Table table; - private int type; - private long maxDataModificationId; - private ColumnResolver resolver; - private HashSet dependencies; - - private ExpressionVisitor(int type) { - this.type = type; - } - - /** - * Create a new visitor object with the given type. - * - * @param type the visitor type - * @return the new visitor - */ - public static ExpressionVisitor get(int type) { - return new ExpressionVisitor(type); - } - - /** - * Add a new dependency to the set of dependencies. - * This is used for GET_DEPENDENCIES visitors. - * - * @param obj the additional dependency. - */ - public void addDependency(DbObject obj) { - dependencies.add(obj); - } - - /** - * Get the dependency set. - * This is used for GET_DEPENDENCIES visitors. - * - * @return the set - */ - public HashSet getDependencies() { - return dependencies; - } - - /** - * Set all dependencies. - * This is used for GET_DEPENDENCIES visitors. - * - * @param dependencies the dependency set - */ - public void setDependencies(HashSet dependencies) { - this.dependencies = dependencies; - } - - /** - * Increment or decrement the query level. - * - * @param offset 1 to increment, -1 to decrement - */ - public void incrementQueryLevel(int offset) { - queryLevel += offset; - } - - /** - * Get the column resolver. - * This is used for NOT_FROM_RESOLVER visitors. - * - * @return the column resolver - */ - public ColumnResolver getResolver() { - return resolver; - } - - /** - * Set the column resolver. - * This is used for NOT_FROM_RESOLVER visitors. - * - * @param resolver the column resolver - */ - public void setResolver(ColumnResolver resolver) { - this.resolver = resolver; - } - - /** - * Update the field maxDataModificationId if this value is higher - * than the current value. - * This is used for SET_MAX_DATA_MODIFICATION_ID visitors. - * - * @param value the data modification id - */ - public void addDataModificationId(long value) { - maxDataModificationId = Math.max(maxDataModificationId, value); - } - - /** - * Get the last data modification. - * This is used for SET_MAX_DATA_MODIFICATION_ID visitors. - * - * @return the maximum modification id - */ - public long getMaxDataModificationId() { - return maxDataModificationId; - } - - int getQueryLevel() { - return queryLevel; - } - - void setQueryLevel(int queryLevel) { - this.queryLevel = queryLevel; - } - - /** - * Set the table. - * This is used for OPTIMIZABLE_MIN_MAX_COUNT_ALL visitors. - * - * @param table the table - */ - public void setTable(Table table) { - this.table = table; - } - - /** - * Get the table. - * This is used for OPTIMIZABLE_MIN_MAX_COUNT_ALL visitors. - * - * @return the table - */ - public Table getTable() { - return table; - } - - /** - * Get the visitor type. - * - * @return the type - */ - public int getType() { - return type; - } - -} diff --git a/tools/h2/src/main/org/h2/expression/Function.java b/tools/h2/src/main/org/h2/expression/Function.java deleted file mode 100755 index 3b42afb..0000000 --- a/tools/h2/src/main/org/h2/expression/Function.java +++ /dev/null @@ -1,1971 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.expression; - -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.io.Reader; -import java.sql.Connection; -import java.sql.Date; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.sql.Time; -import java.sql.Timestamp; -import java.text.SimpleDateFormat; -import java.util.ArrayList; -import java.util.Calendar; -import java.util.HashMap; -import java.util.Locale; -import java.util.TimeZone; -import java.util.regex.PatternSyntaxException; -import org.h2.command.Command; -import org.h2.command.Parser; -import org.h2.constant.ErrorCode; -import org.h2.engine.Database; -import org.h2.engine.Mode; -import org.h2.engine.Session; -import org.h2.message.DbException; -import org.h2.schema.Sequence; -import org.h2.security.BlockCipher; -import org.h2.security.CipherFactory; -import org.h2.security.SHA256; -import org.h2.table.Column; -import org.h2.table.ColumnResolver; -import org.h2.table.LinkSchema; -import org.h2.table.TableFilter; -import org.h2.tools.CompressTool; -import org.h2.tools.Csv; -import org.h2.util.AutoCloseInputStream; -import org.h2.util.DateTimeUtils; -import org.h2.util.IOUtils; -import org.h2.util.JdbcUtils; -import org.h2.util.MathUtils; -import org.h2.util.New; -import org.h2.util.StatementBuilder; -import org.h2.util.StringUtils; -import org.h2.util.Utils; -import org.h2.value.DataType; -import org.h2.value.Value; -import org.h2.value.ValueArray; -import org.h2.value.ValueBoolean; -import org.h2.value.ValueBytes; -import org.h2.value.ValueDate; -import org.h2.value.ValueDouble; -import org.h2.value.ValueInt; -import org.h2.value.ValueLong; -import org.h2.value.ValueNull; -import org.h2.value.ValueResultSet; -import org.h2.value.ValueString; -import org.h2.value.ValueTime; -import org.h2.value.ValueTimestamp; -import org.h2.value.ValueUuid; - -/** - * This class implements most built-in functions of this database. - */ -public class Function extends Expression implements FunctionCall { - public static final int ABS = 0, ACOS = 1, ASIN = 2, ATAN = 3, ATAN2 = 4, BITAND = 5, BITOR = 6, BITXOR = 7, - CEILING = 8, COS = 9, COT = 10, DEGREES = 11, EXP = 12, FLOOR = 13, LOG = 14, LOG10 = 15, MOD = 16, - PI = 17, POWER = 18, RADIANS = 19, RAND = 20, ROUND = 21, ROUNDMAGIC = 22, SIGN = 23, SIN = 24, SQRT = 25, - TAN = 26, TRUNCATE = 27, SECURE_RAND = 28, HASH = 29, ENCRYPT = 30, DECRYPT = 31, COMPRESS = 32, - EXPAND = 33, ZERO = 34, RANDOM_UUID = 35; - - public static final int ASCII = 50, BIT_LENGTH = 51, CHAR = 52, CHAR_LENGTH = 53, CONCAT = 54, DIFFERENCE = 55, - HEXTORAW = 56, INSERT = 57, INSTR = 58, LCASE = 59, LEFT = 60, LENGTH = 61, LOCATE = 62, LTRIM = 63, - OCTET_LENGTH = 64, RAWTOHEX = 65, REPEAT = 66, REPLACE = 67, RIGHT = 68, RTRIM = 69, SOUNDEX = 70, - SPACE = 71, SUBSTR = 72, SUBSTRING = 73, UCASE = 74, LOWER = 75, UPPER = 76, POSITION = 77, TRIM = 78, - STRINGENCODE = 79, STRINGDECODE = 80, STRINGTOUTF8 = 81, UTF8TOSTRING = 82, XMLATTR = 83, XMLNODE = 84, - XMLCOMMENT = 85, XMLCDATA = 86, XMLSTARTDOC = 87, XMLTEXT = 88, REGEXP_REPLACE = 89, RPAD = 90, LPAD = 91; - - public static final int CURDATE = 100, CURTIME = 101, DATE_ADD = 102, DATE_DIFF = 103, DAY_NAME = 104, - DAY_OF_MONTH = 105, DAY_OF_WEEK = 106, DAY_OF_YEAR = 107, HOUR = 108, MINUTE = 109, MONTH = 110, MONTH_NAME = 111, - NOW = 112, QUARTER = 113, SECOND = 114, WEEK = 115, YEAR = 116, CURRENT_DATE = 117, CURRENT_TIME = 118, - CURRENT_TIMESTAMP = 119, EXTRACT = 120, FORMATDATETIME = 121, PARSEDATETIME = 122, - ISO_YEAR = 123, ISO_WEEK = 124, ISO_DAY_OF_WEEK = 125; - - public static final int DATABASE = 150, USER = 151, CURRENT_USER = 152, IDENTITY = 153, SCOPE_IDENTITY = 154, - AUTOCOMMIT = 155, READONLY = 156, DATABASE_PATH = 157, LOCK_TIMEOUT = 158; - - public static final int IFNULL = 200, CASEWHEN = 201, CONVERT = 202, CAST = 203, COALESCE = 204, NULLIF = 205, - CASE = 206, NEXTVAL = 207, CURRVAL = 208, ARRAY_GET = 209, CSVREAD = 210, CSVWRITE = 211, - MEMORY_FREE = 212, MEMORY_USED = 213, LOCK_MODE = 214, SCHEMA = 215, SESSION_ID = 216, ARRAY_LENGTH = 217, - LINK_SCHEMA = 218, GREATEST = 219, LEAST = 220, CANCEL_SESSION = 221, SET = 222, TABLE = 223, TABLE_DISTINCT = 224, - FILE_READ = 225, TRANSACTION_ID = 226; - - private static final int VAR_ARGS = -1; - private static final long PRECISION_UNKNOWN = -1; - - private static final HashMap FUNCTIONS = New.hashMap(); - private static final HashMap DATE_PART = New.hashMap(); - private static final SimpleDateFormat FORMAT_DAYNAME = new SimpleDateFormat("EEEE", Locale.ENGLISH); - private static final SimpleDateFormat FORMAT_MONTHNAME = new SimpleDateFormat("MMMM", Locale.ENGLISH); - private static final char[] SOUNDEX_INDEX = new char[128]; - - protected Expression[] args; - - private FunctionInfo info; - private ArrayList varArgs; - private int dataType, scale; - private long precision = PRECISION_UNKNOWN; - private int displaySize; - private Database database; - - static { - // DATE_PART - DATE_PART.put("YEAR", Calendar.YEAR); - DATE_PART.put("YYYY", Calendar.YEAR); - DATE_PART.put("YY", Calendar.YEAR); - DATE_PART.put("MONTH", Calendar.MONTH); - DATE_PART.put("MM", Calendar.MONTH); - DATE_PART.put("M", Calendar.MONTH); - DATE_PART.put("WW", Calendar.WEEK_OF_YEAR); - DATE_PART.put("WK", Calendar.WEEK_OF_YEAR); - DATE_PART.put("DAY", Calendar.DAY_OF_MONTH); - DATE_PART.put("DD", Calendar.DAY_OF_MONTH); - DATE_PART.put("D", Calendar.DAY_OF_MONTH); - DATE_PART.put("DAYOFYEAR", Calendar.DAY_OF_YEAR); - DATE_PART.put("DAY_OF_YEAR", Calendar.DAY_OF_YEAR); - DATE_PART.put("DY", Calendar.DAY_OF_YEAR); - DATE_PART.put("DOY", Calendar.DAY_OF_YEAR); - DATE_PART.put("HOUR", Calendar.HOUR_OF_DAY); - DATE_PART.put("HH", Calendar.HOUR_OF_DAY); - DATE_PART.put("MINUTE", Calendar.MINUTE); - DATE_PART.put("MI", Calendar.MINUTE); - DATE_PART.put("N", Calendar.MINUTE); - DATE_PART.put("SECOND", Calendar.SECOND); - DATE_PART.put("SS", Calendar.SECOND); - DATE_PART.put("S", Calendar.SECOND); - DATE_PART.put("MILLISECOND", Calendar.MILLISECOND); - DATE_PART.put("MS", Calendar.MILLISECOND); - - // SOUNDEX_INDEX - String index = "7AEIOUY8HW1BFPV2CGJKQSXZ3DT4L5MN6R"; - char number = 0; - for (int i = 0; i < index.length(); i++) { - char c = index.charAt(i); - if (c < '9') { - number = c; - } else { - SOUNDEX_INDEX[c] = number; - SOUNDEX_INDEX[Character.toLowerCase(c)] = number; - } - } - - // FUNCTIONS - addFunction("ABS", ABS, 1, Value.NULL); - addFunction("ACOS", ACOS, 1, Value.DOUBLE); - addFunction("ASIN", ASIN, 1, Value.DOUBLE); - addFunction("ATAN", ATAN, 1, Value.DOUBLE); - addFunction("ATAN2", ATAN2, 2, Value.DOUBLE); - addFunction("BITAND", BITAND, 2, Value.LONG); - addFunction("BITOR", BITOR, 2, Value.LONG); - addFunction("BITXOR", BITXOR, 2, Value.LONG); - addFunction("CEILING", CEILING, 1, Value.DOUBLE); - addFunction("COS", COS, 1, Value.DOUBLE); - addFunction("COT", COT, 1, Value.DOUBLE); - addFunction("DEGREES", DEGREES, 1, Value.DOUBLE); - addFunction("EXP", EXP, 1, Value.DOUBLE); - addFunction("FLOOR", FLOOR, 1, Value.DOUBLE); - addFunction("LOG", LOG, 1, Value.DOUBLE); - addFunction("LOG10", LOG10, 1, Value.DOUBLE); - addFunction("MOD", MOD, 2, Value.LONG); - addFunction("PI", PI, 0, Value.DOUBLE); - addFunction("POWER", POWER, 2, Value.DOUBLE); - addFunction("RADIANS", RADIANS, 1, Value.DOUBLE); - // RAND without argument: get the next value - // RAND with one argument: seed the random generator - addFunctionNotDeterministic("RAND", RAND, VAR_ARGS, Value.DOUBLE); - addFunction("ROUND", ROUND, 2, Value.DOUBLE); - addFunction("ROUNDMAGIC", ROUNDMAGIC, 1, Value.DOUBLE); - addFunction("SIGN", SIGN, 1, Value.INT); - addFunction("SIN", SIN, 1, Value.DOUBLE); - addFunction("SQRT", SQRT, 1, Value.DOUBLE); - addFunction("TAN", TAN, 1, Value.DOUBLE); - addFunction("TRUNCATE", TRUNCATE, 2, Value.DOUBLE); - addFunction("HASH", HASH, 3, Value.BYTES); - addFunction("ENCRYPT", ENCRYPT, 3, Value.BYTES); - addFunction("DECRYPT", DECRYPT, 3, Value.BYTES); - addFunctionNotDeterministic("SECURE_RAND", SECURE_RAND, 1, Value.BYTES); - addFunction("COMPRESS", COMPRESS, VAR_ARGS, Value.BYTES); - addFunction("EXPAND", EXPAND, 1, Value.BYTES); - addFunction("ZERO", ZERO, 0, Value.INT); - addFunctionNotDeterministic("RANDOM_UUID", RANDOM_UUID, 0, Value.UUID); - addFunctionNotDeterministic("SYS_GUID", RANDOM_UUID, 0, Value.UUID); - // string - addFunction("ASCII", ASCII, 1, Value.INT); - addFunction("BIT_LENGTH", BIT_LENGTH, 1, Value.LONG); - addFunction("CHAR", CHAR, 1, Value.STRING); - addFunction("CHR", CHAR, 1, Value.STRING); - addFunction("CHAR_LENGTH", CHAR_LENGTH, 1, Value.INT); - // same as CHAR_LENGTH - addFunction("CHARACTER_LENGTH", CHAR_LENGTH, 1, Value.INT); - addFunctionWithNull("CONCAT", CONCAT, VAR_ARGS, Value.STRING); - addFunction("DIFFERENCE", DIFFERENCE, 2, Value.INT); - addFunction("HEXTORAW", HEXTORAW, 1, Value.STRING); - addFunctionWithNull("INSERT", INSERT, 4, Value.STRING); - addFunction("LCASE", LCASE, 1, Value.STRING); - addFunction("LEFT", LEFT, 2, Value.STRING); - addFunction("LENGTH", LENGTH, 1, Value.LONG); - // 2 or 3 arguments - addFunction("LOCATE", LOCATE, VAR_ARGS, Value.INT); - // same as LOCATE with 2 arguments - addFunction("POSITION", LOCATE, 2, Value.INT); - addFunction("INSTR", INSTR, VAR_ARGS, Value.INT); - addFunction("LTRIM", LTRIM, VAR_ARGS, Value.STRING); - addFunction("OCTET_LENGTH", OCTET_LENGTH, 1, Value.LONG); - addFunction("RAWTOHEX", RAWTOHEX, 1, Value.STRING); - addFunction("REPEAT", REPEAT, 2, Value.STRING); - addFunction("REPLACE", REPLACE, VAR_ARGS, Value.STRING); - addFunction("RIGHT", RIGHT, 2, Value.STRING); - addFunction("RTRIM", RTRIM, VAR_ARGS, Value.STRING); - addFunction("SOUNDEX", SOUNDEX, 1, Value.STRING); - addFunction("SPACE", SPACE, 1, Value.STRING); - addFunction("SUBSTR", SUBSTR, VAR_ARGS, Value.STRING); - addFunction("SUBSTRING", SUBSTRING, VAR_ARGS, Value.STRING); - addFunction("UCASE", UCASE, 1, Value.STRING); - addFunction("LOWER", LOWER, 1, Value.STRING); - addFunction("UPPER", UPPER, 1, Value.STRING); - addFunction("POSITION", POSITION, 2, Value.INT); - addFunction("TRIM", TRIM, VAR_ARGS, Value.STRING); - addFunction("STRINGENCODE", STRINGENCODE, 1, Value.STRING); - addFunction("STRINGDECODE", STRINGDECODE, 1, Value.STRING); - addFunction("STRINGTOUTF8", STRINGTOUTF8, 1, Value.BYTES); - addFunction("UTF8TOSTRING", UTF8TOSTRING, 1, Value.STRING); - addFunction("XMLATTR", XMLATTR, 2, Value.STRING); - addFunctionWithNull("XMLNODE", XMLNODE, VAR_ARGS, Value.STRING); - addFunction("XMLCOMMENT", XMLCOMMENT, 1, Value.STRING); - addFunction("XMLCDATA", XMLCDATA, 1, Value.STRING); - addFunction("XMLSTARTDOC", XMLSTARTDOC, 0, Value.STRING); - addFunction("XMLTEXT", XMLTEXT, 1, Value.STRING); - addFunction("REGEXP_REPLACE", REGEXP_REPLACE, 3, Value.STRING); - addFunction("RPAD", RPAD, VAR_ARGS, Value.STRING); - addFunction("LPAD", LPAD, VAR_ARGS, Value.STRING); - - // date - addFunctionNotDeterministic("CURRENT_DATE", CURRENT_DATE, 0, Value.DATE); - addFunctionNotDeterministic("CURDATE", CURDATE, 0, Value.DATE); - addFunctionNotDeterministic("CURRENT_TIME", CURRENT_TIME, 0, Value.TIME); - addFunctionNotDeterministic("CURTIME", CURTIME, 0, Value.TIME); - addFunctionNotDeterministic("CURRENT_TIMESTAMP", CURRENT_TIMESTAMP, VAR_ARGS, Value.TIMESTAMP); - addFunctionNotDeterministic("NOW", NOW, VAR_ARGS, Value.TIMESTAMP); - addFunction("DATEADD", DATE_ADD, 3, Value.TIMESTAMP); - addFunction("DATEDIFF", DATE_DIFF, 3, Value.LONG); - addFunction("TIMESTAMPDIFF", DATE_DIFF, 3, Value.LONG); - addFunction("DAYNAME", DAY_NAME, 1, Value.STRING); - addFunction("DAYNAME", DAY_NAME, 1, Value.STRING); - addFunction("DAY", DAY_OF_MONTH, 1, Value.INT); - addFunction("DAY_OF_MONTH", DAY_OF_MONTH, 1, Value.INT); - addFunction("DAY_OF_WEEK", DAY_OF_WEEK, 1, Value.INT); - addFunction("DAY_OF_YEAR", DAY_OF_YEAR, 1, Value.INT); - addFunction("DAYOFMONTH", DAY_OF_MONTH, 1, Value.INT); - addFunction("DAYOFWEEK", DAY_OF_WEEK, 1, Value.INT); - addFunction("DAYOFYEAR", DAY_OF_YEAR, 1, Value.INT); - addFunction("HOUR", HOUR, 1, Value.INT); - addFunction("MINUTE", MINUTE, 1, Value.INT); - addFunction("MONTH", MONTH, 1, Value.INT); - addFunction("MONTHNAME", MONTH_NAME, 1, Value.STRING); - addFunction("QUARTER", QUARTER, 1, Value.INT); - addFunction("SECOND", SECOND, 1, Value.INT); - addFunction("WEEK", WEEK, 1, Value.INT); - addFunction("YEAR", YEAR, 1, Value.INT); - addFunction("EXTRACT", EXTRACT, 2, Value.INT); - addFunctionWithNull("FORMATDATETIME", FORMATDATETIME, VAR_ARGS, Value.STRING); - addFunctionWithNull("PARSEDATETIME", PARSEDATETIME, VAR_ARGS, Value.TIMESTAMP); - addFunction("ISO_YEAR", ISO_YEAR, 1, Value.INT); - addFunction("ISO_WEEK", ISO_WEEK, 1, Value.INT); - addFunction("ISO_DAY_OF_WEEK", ISO_DAY_OF_WEEK, 1, Value.INT); - // system - addFunctionNotDeterministic("DATABASE", DATABASE, 0, Value.STRING); - addFunctionNotDeterministic("USER", USER, 0, Value.STRING); - addFunctionNotDeterministic("CURRENT_USER", CURRENT_USER, 0, Value.STRING); - addFunctionNotDeterministic("IDENTITY", IDENTITY, 0, Value.LONG); - addFunctionNotDeterministic("SCOPE_IDENTITY", SCOPE_IDENTITY, 0, Value.LONG); - addFunctionNotDeterministic("IDENTITY_VAL_LOCAL", IDENTITY, 0, Value.LONG); - addFunctionNotDeterministic("LAST_INSERT_ID", IDENTITY, 0, Value.LONG); - addFunctionNotDeterministic("LASTVAL", IDENTITY, 0, Value.LONG); - addFunctionNotDeterministic("AUTOCOMMIT", AUTOCOMMIT, 0, Value.BOOLEAN); - addFunctionNotDeterministic("READONLY", READONLY, 0, Value.BOOLEAN); - addFunction("DATABASE_PATH", DATABASE_PATH, 0, Value.STRING); - addFunction("LOCK_TIMEOUT", LOCK_TIMEOUT, 0, Value.INT); - addFunctionWithNull("IFNULL", IFNULL, 2, Value.NULL); - addFunctionWithNull("CASEWHEN", CASEWHEN, 3, Value.NULL); - addFunctionWithNull("CONVERT", CONVERT, 1, Value.NULL); - addFunctionWithNull("CAST", CAST, 1, Value.NULL); - addFunctionWithNull("COALESCE", COALESCE, VAR_ARGS, Value.NULL); - addFunctionWithNull("NVL", COALESCE, VAR_ARGS, Value.NULL); - addFunctionWithNull("NULLIF", NULLIF, 2, Value.NULL); - addFunctionWithNull("CASE", CASE, VAR_ARGS, Value.NULL); - addFunctionNotDeterministic("NEXTVAL", NEXTVAL, VAR_ARGS, Value.LONG); - addFunctionNotDeterministic("CURRVAL", CURRVAL, VAR_ARGS, Value.LONG); - addFunction("ARRAY_GET", ARRAY_GET, 2, Value.STRING); - addFunction("CSVREAD", CSVREAD, VAR_ARGS, Value.RESULT_SET, false, false); - addFunction("CSVWRITE", CSVWRITE, VAR_ARGS, Value.INT, false, false); - addFunctionNotDeterministic("MEMORY_FREE", MEMORY_FREE, 0, Value.INT); - addFunctionNotDeterministic("MEMORY_USED", MEMORY_USED, 0, Value.INT); - addFunctionNotDeterministic("LOCK_MODE", LOCK_MODE, 0, Value.INT); - addFunctionNotDeterministic("SCHEMA", SCHEMA, 0, Value.STRING); - addFunctionNotDeterministic("SESSION_ID", SESSION_ID, 0, Value.INT); - addFunction("ARRAY_LENGTH", ARRAY_LENGTH, 1, Value.INT); - addFunction("LINK_SCHEMA", LINK_SCHEMA, 6, Value.RESULT_SET); - addFunctionWithNull("LEAST", LEAST, VAR_ARGS, Value.NULL); - addFunctionWithNull("GREATEST", GREATEST, VAR_ARGS, Value.NULL); - addFunction("CANCEL_SESSION", CANCEL_SESSION, 1, Value.BOOLEAN); - addFunction("SET", SET, 2, Value.NULL, false, false); - addFunction("FILE_READ", FILE_READ, VAR_ARGS, Value.NULL, false, true); - addFunctionNotDeterministic("TRANSACTION_ID", TRANSACTION_ID, 0, Value.STRING); - - // TableFunction - addFunctionWithNull("TABLE", TABLE, VAR_ARGS, Value.RESULT_SET); - addFunctionWithNull("TABLE_DISTINCT", TABLE_DISTINCT, VAR_ARGS, Value.RESULT_SET); - } - - protected Function(Database database, FunctionInfo info) { - this.database = database; - this.info = info; - if (info.parameterCount == VAR_ARGS) { - varArgs = New.arrayList(); - } else { - args = new Expression[info.parameterCount]; - } - } - - private static void addFunction(String name, int type, int parameterCount, int dataType, - boolean nullIfParameterIsNull, boolean deterministic) { - FunctionInfo info = new FunctionInfo(); - info.name = name; - info.type = type; - info.parameterCount = parameterCount; - info.dataType = dataType; - info.nullIfParameterIsNull = nullIfParameterIsNull; - info.deterministic = deterministic; - FUNCTIONS.put(name, info); - } - - private static void addFunctionNotDeterministic(String name, int type, int parameterCount, int dataType) { - addFunction(name, type, parameterCount, dataType, true, false); - } - - private static void addFunction(String name, int type, int parameterCount, int dataType) { - addFunction(name, type, parameterCount, dataType, true, true); - } - - private static void addFunctionWithNull(String name, int type, int parameterCount, int dataType) { - addFunction(name, type, parameterCount, dataType, false, true); - } - - /** - * Get the function info object for this function, or null if there is no - * such function. - * - * @param name the function name - * @return the function info - */ - public static FunctionInfo getFunctionInfo(String name) { - return FUNCTIONS.get(name); - } - - /** - * Get an instance of the given function for this database. - * If no function with this name is found, null is returned. - * - * @param database the database - * @param name the function name - * @return the function object or null - */ - public static Function getFunction(Database database, String name) { - FunctionInfo info = getFunctionInfo(name); - if (info == null) { - return null; - } - switch(info.type) { - case TABLE: - case TABLE_DISTINCT: - return new TableFunction(database, info, Long.MAX_VALUE); - default: - return new Function(database, info); - } - } - - /** - * Set the parameter expression at the given index. - * - * @param index the index (0, 1,...) - * @param param the expression - */ - public void setParameter(int index, Expression param) { - if (varArgs != null) { - varArgs.add(param); - } else { - if (index >= args.length) { - throw DbException.get(ErrorCode.INVALID_PARAMETER_COUNT_2, info.name, - "" + args.length); - } - args[index] = param; - } - } - - private strictfp double log10(double value) { - return roundmagic(StrictMath.log(value) / StrictMath.log(10)); - } - - public Value getValue(Session session) { - return getValueWithArgs(session, args); - } - - private Value getNullOrValue(Session session, Expression[] x, int i) { - if (i < x.length) { - Expression e = x[i]; - if (e != null) { - return e.getValue(session); - } - } - return null; - } - - private Value getSimpleValue(Session session, Value v0, Expression[] argList) { - Value result; - switch (info.type) { - case ABS: - result = v0.getSignum() > 0 ? v0 : v0.negate(); - break; - case ACOS: - result = ValueDouble.get(Math.acos(v0.getDouble())); - break; - case ASIN: - result = ValueDouble.get(Math.asin(v0.getDouble())); - break; - case ATAN: - result = ValueDouble.get(Math.atan(v0.getDouble())); - break; - case CEILING: - result = ValueDouble.get(Math.ceil(v0.getDouble())); - break; - case COS: - result = ValueDouble.get(Math.cos(v0.getDouble())); - break; - case COT: { - double d = Math.tan(v0.getDouble()); - if (d == 0.0) { - throw DbException.get(ErrorCode.DIVISION_BY_ZERO_1, getSQL()); - } - result = ValueDouble.get(1. / d); - break; - } - case DEGREES: - result = ValueDouble.get(Math.toDegrees(v0.getDouble())); - break; - case EXP: - result = ValueDouble.get(Math.exp(v0.getDouble())); - break; - case FLOOR: - result = ValueDouble.get(Math.floor(v0.getDouble())); - break; - case LOG: - result = ValueDouble.get(Math.log(v0.getDouble())); - break; - case LOG10: - result = ValueDouble.get(log10(v0.getDouble())); - break; - case PI: - result = ValueDouble.get(Math.PI); - break; - case RADIANS: - result = ValueDouble.get(Math.toRadians(v0.getDouble())); - break; - case RAND: { - if (v0 != null) { - session.getRandom().setSeed(v0.getInt()); - } - result = ValueDouble.get(session.getRandom().nextDouble()); - break; - } - case ROUNDMAGIC: - result = ValueDouble.get(roundmagic(v0.getDouble())); - break; - case SIGN: - result = ValueInt.get(v0.getSignum()); - break; - case SIN: - result = ValueDouble.get(Math.sin(v0.getDouble())); - break; - case SQRT: - result = ValueDouble.get(Math.sqrt(v0.getDouble())); - break; - case TAN: - result = ValueDouble.get(Math.tan(v0.getDouble())); - break; - case SECURE_RAND: - result = ValueBytes.getNoCopy(MathUtils.secureRandomBytes(v0.getInt())); - break; - case EXPAND: - result = ValueBytes.getNoCopy(CompressTool.getInstance().expand(v0.getBytesNoCopy())); - break; - case ZERO: - result = ValueInt.get(0); - break; - case RANDOM_UUID: - result = ValueUuid.getNewRandom(); - break; - // string - case ASCII: { - String s = v0.getString(); - if (s.length() == 0) { - result = ValueNull.INSTANCE; - } else { - result = ValueInt.get(s.charAt(0)); - } - break; - } - case BIT_LENGTH: - result = ValueLong.get(16 * length(v0)); - break; - case CHAR: - result = ValueString.get(String.valueOf((char) v0.getInt())); - break; - case CHAR_LENGTH: - case LENGTH: - result = ValueLong.get(length(v0)); - break; - case OCTET_LENGTH: - result = ValueLong.get(2 * length(v0)); - break; - case CONCAT: { - result = ValueNull.INSTANCE; - for (Expression e : argList) { - Value v = e.getValue(session); - if (v == ValueNull.INSTANCE) { - continue; - } - if (result == ValueNull.INSTANCE) { - result = v; - } else { - result = ValueString.get(result.getString().concat(v.getString())); - } - } - break; - } - case HEXTORAW: - result = ValueString.get(hexToRaw(v0.getString())); - break; - case LOWER: - case LCASE: - // TODO this is locale specific, need to document or provide a way - // to set the locale - result = ValueString.get(v0.getString().toLowerCase()); - break; - case RAWTOHEX: - result = ValueString.get(rawToHex(v0.getString())); - break; - case SOUNDEX: - result = ValueString.get(getSoundex(v0.getString())); - break; - case SPACE: { - int len = Math.max(0, v0.getInt()); - char[] chars = new char[len]; - for (int i = len - 1; i >= 0; i--) { - chars[i] = ' '; - } - result = ValueString.get(new String(chars)); - break; - } - case UPPER: - case UCASE: - // TODO this is locale specific, need to document or provide a way - // to set the locale - result = ValueString.get(v0.getString().toUpperCase()); - break; - case STRINGENCODE: - result = ValueString.get(StringUtils.javaEncode(v0.getString())); - break; - case STRINGDECODE: - result = ValueString.get(StringUtils.javaDecode(v0.getString())); - break; - case STRINGTOUTF8: - result = ValueBytes.getNoCopy(StringUtils.utf8Encode(v0.getString())); - break; - case UTF8TOSTRING: - result = ValueString.get(StringUtils.utf8Decode(v0.getBytesNoCopy())); - break; - case XMLCOMMENT: - result = ValueString.get(StringUtils.xmlComment(v0.getString())); - break; - case XMLCDATA: - result = ValueString.get(StringUtils.xmlCData(v0.getString())); - break; - case XMLSTARTDOC: - result = ValueString.get(StringUtils.xmlStartDoc()); - break; - case XMLTEXT: - result = ValueString.get(StringUtils.xmlText(v0.getString())); - break; - case DAY_NAME: { - synchronized (FORMAT_DAYNAME) { - result = ValueString.get(FORMAT_DAYNAME.format(v0.getDateNoCopy())); - } - break; - } - case DAY_OF_MONTH: - result = ValueInt.get(DateTimeUtils.getDatePart(v0.getDateNoCopy(), Calendar.DAY_OF_MONTH)); - break; - case DAY_OF_WEEK: - result = ValueInt.get(DateTimeUtils.getDatePart(v0.getDateNoCopy(), Calendar.DAY_OF_WEEK)); - break; - case DAY_OF_YEAR: - result = ValueInt.get(DateTimeUtils.getDatePart(v0.getDateNoCopy(), Calendar.DAY_OF_YEAR)); - break; - case HOUR: - result = ValueInt.get(DateTimeUtils.getDatePart(v0.getTimestampNoCopy(), Calendar.HOUR_OF_DAY)); - break; - case MINUTE: - result = ValueInt.get(DateTimeUtils.getDatePart(v0.getTimestampNoCopy(), Calendar.MINUTE)); - break; - case MONTH: - result = ValueInt.get(DateTimeUtils.getDatePart(v0.getDateNoCopy(), Calendar.MONTH)); - break; - case MONTH_NAME: { - synchronized (FORMAT_MONTHNAME) { - result = ValueString.get(FORMAT_MONTHNAME.format(v0.getDateNoCopy())); - } - break; - } - case QUARTER: - result = ValueInt.get((DateTimeUtils.getDatePart(v0.getDateNoCopy(), Calendar.MONTH) - 1) / 3 + 1); - break; - case SECOND: - result = ValueInt.get(DateTimeUtils.getDatePart(v0.getTimestampNoCopy(), Calendar.SECOND)); - break; - case WEEK: - result = ValueInt.get(DateTimeUtils.getDatePart(v0.getDateNoCopy(), Calendar.WEEK_OF_YEAR)); - break; - case YEAR: - result = ValueInt.get(DateTimeUtils.getDatePart(v0.getDateNoCopy(), Calendar.YEAR)); - break; - case ISO_YEAR: - result = ValueInt.get(DateTimeUtils.getIsoYear(v0.getDateNoCopy())); - break; - case ISO_WEEK: - result = ValueInt.get(DateTimeUtils.getIsoWeek(v0.getDateNoCopy())); - break; - case ISO_DAY_OF_WEEK: - result = ValueInt.get(DateTimeUtils.getIsoDayOfWeek(v0.getDateNoCopy())); - break; - case CURDATE: - case CURRENT_DATE: - // need to normalize - result = ValueDate.get(new Date(System.currentTimeMillis())); - break; - case CURTIME: - case CURRENT_TIME: - // need to normalize - result = ValueTime.get(new Time(System.currentTimeMillis())); - break; - case NOW: - case CURRENT_TIMESTAMP: { - ValueTimestamp vt = ValueTimestamp.getNoCopy(new Timestamp(System.currentTimeMillis())); - if (v0 != null) { - Mode mode = database.getMode(); - vt = (ValueTimestamp) vt.convertScale(mode.convertOnlyToSmallerScale, v0.getInt()); - } - result = vt; - break; - } - case DATABASE: - result = ValueString.get(database.getShortName()); - break; - case USER: - case CURRENT_USER: - result = ValueString.get(session.getUser().getName()); - break; - case IDENTITY: - result = session.getLastIdentity(); - break; - case SCOPE_IDENTITY: - result = session.getScopeIdentity(); - break; - case AUTOCOMMIT: - result = ValueBoolean.get(session.getAutoCommit()); - break; - case READONLY: - result = ValueBoolean.get(database.isReadOnly()); - break; - case DATABASE_PATH: { - String path = database.getDatabasePath(); - result = path == null ? (Value) ValueNull.INSTANCE : ValueString.get(path); - break; - } - case LOCK_TIMEOUT: - result = ValueInt.get(session.getLockTimeout()); - break; - case CAST: - case CONVERT: { - v0 = v0.convertTo(dataType); - Mode mode = database.getMode(); - v0 = v0.convertScale(mode.convertOnlyToSmallerScale, scale); - v0 = v0.convertPrecision(getPrecision()); - result = v0; - break; - } - case MEMORY_FREE: - session.getUser().checkAdmin(); - result = ValueInt.get(Utils.getMemoryFree()); - break; - case MEMORY_USED: - session.getUser().checkAdmin(); - result = ValueInt.get(Utils.getMemoryUsed()); - break; - case LOCK_MODE: - result = ValueInt.get(database.getLockMode()); - break; - case SCHEMA: - result = ValueString.get(session.getCurrentSchemaName()); - break; - case SESSION_ID: - result = ValueInt.get(session.getId()); - break; - case IFNULL: { - result = v0 == ValueNull.INSTANCE ? argList[1].getValue(session) : v0; - break; - } - case CASEWHEN: { - Expression expr; - if (v0 == ValueNull.INSTANCE || !v0.getBoolean().booleanValue()) { - expr = argList[2]; - } else { - expr = argList[1]; - } - Value v = expr.getValue(session); - result = v.convertTo(dataType); - break; - } - case COALESCE: { - result = v0; - for (int i = 0; i < argList.length; i++) { - Value v = i == 0 ? v0 : argList[i].getValue(session); - if (!(v == ValueNull.INSTANCE)) { - result = v.convertTo(dataType); - break; - } - } - break; - } - case GREATEST: - case LEAST: { - result = ValueNull.INSTANCE; - for (int i = 0; i < argList.length; i++) { - Value v = i == 0 ? v0 : argList[i].getValue(session); - if (!(v == ValueNull.INSTANCE)) { - v = v.convertTo(dataType); - if (result == ValueNull.INSTANCE) { - result = v; - } else { - int comp = database.compareTypeSave(result, v); - if (info.type == GREATEST && comp < 0) { - result = v; - } else if (info.type == LEAST && comp > 0) { - result = v; - } - } - } - } - break; - } - case CASE: { - result = null; - int i = 0; - for (; i < argList.length; i++) { - Value when = argList[i++].getValue(session); - if (Boolean.TRUE.equals(when)) { - result = argList[i].getValue(session); - break; - } - } - if (result == null) { - result = i < argList.length ? argList[i].getValue(session) : ValueNull.INSTANCE; - } - break; - } - case ARRAY_GET: { - if (v0.getType() == Value.ARRAY) { - Value v1 = argList[1].getValue(session); - int element = v1.getInt(); - Value[] list = ((ValueArray) v0).getList(); - if (element < 1 || element > list.length) { - result = ValueNull.INSTANCE; - } else { - result = list[element - 1]; - } - } else { - result = ValueNull.INSTANCE; - } - break; - } - case ARRAY_LENGTH: { - if (v0.getType() == Value.ARRAY) { - Value[] list = ((ValueArray) v0).getList(); - result = ValueInt.get(list.length); - } else { - result = ValueNull.INSTANCE; - } - break; - } - case CANCEL_SESSION: { - result = ValueBoolean.get(cancelStatement(session, v0.getInt())); - break; - } - case TRANSACTION_ID: { - result = session.getTransactionId(); - break; - } - default: - result = null; - } - return result; - } - - private boolean cancelStatement(Session session, int targetSessionId) { - session.getUser().checkAdmin(); - Session[] sessions = session.getDatabase().getSessions(false); - for (Session s : sessions) { - if (s.getId() == targetSessionId) { - Command c = s.getCurrentCommand(); - if (c == null) { - return false; - } - c.cancel(); - return true; - } - } - return false; - } - - private Value getValueWithArgs(Session session, Expression[] argList) { - if (info.nullIfParameterIsNull) { - for (int i = 0; i < argList.length; i++) { - if (getNullOrValue(session, argList, i) == ValueNull.INSTANCE) { - return ValueNull.INSTANCE; - } - } - } - Value v0 = getNullOrValue(session, argList, 0); - Value resultSimple = getSimpleValue(session, v0, argList); - if (resultSimple != null) { - return resultSimple; - } - Value v1 = getNullOrValue(session, argList, 1); - Value v2 = getNullOrValue(session, argList, 2); - Value v3 = getNullOrValue(session, argList, 3); - Value v4 = getNullOrValue(session, argList, 4); - Value v5 = getNullOrValue(session, argList, 5); - Value result; - switch (info.type) { - case ATAN2: - result = ValueDouble.get(Math.atan2(v0.getDouble(), v1.getDouble())); - break; - case BITAND: - result = ValueLong.get(v0.getLong() & v1.getLong()); - break; - case BITOR: - result = ValueLong.get(v0.getLong() | v1.getLong()); - break; - case BITXOR: - result = ValueLong.get(v0.getLong() ^ v1.getLong()); - break; - case MOD: { - long x = v1.getLong(); - if (x == 0) { - throw DbException.get(ErrorCode.DIVISION_BY_ZERO_1, getSQL()); - } - result = ValueLong.get(v0.getLong() % x); - break; - } - case POWER: - result = ValueDouble.get(Math.pow(v0.getDouble(), v1.getDouble())); - break; - case ROUND: { - double f = Math.pow(10., v1.getDouble()); - result = ValueDouble.get(Math.round(v0.getDouble() * f) / f); - break; - } - case TRUNCATE: { - double d = v0.getDouble(); - int p = v1.getInt(); - double f = Math.pow(10., p); - double g = d * f; - result = ValueDouble.get(((d < 0) ? Math.ceil(g) : Math.floor(g)) / f); - break; - } - case HASH: - result = ValueBytes.getNoCopy(getHash(v0.getString(), v1.getBytesNoCopy(), v2.getInt())); - break; - case ENCRYPT: - result = ValueBytes.getNoCopy(encrypt(v0.getString(), v1.getBytesNoCopy(), v2.getBytesNoCopy())); - break; - case DECRYPT: - result = ValueBytes.getNoCopy(decrypt(v0.getString(), v1.getBytesNoCopy(), v2.getBytesNoCopy())); - break; - case COMPRESS: { - String algorithm = null; - if (v1 != null) { - algorithm = v1.getString(); - } - result = ValueBytes.getNoCopy(CompressTool.getInstance().compress(v0.getBytesNoCopy(), algorithm)); - break; - } - case DIFFERENCE: - result = ValueInt.get(getDifference(v0.getString(), v1.getString())); - break; - case INSERT: { - if (v1 == ValueNull.INSTANCE || v2 == ValueNull.INSTANCE) { - result = v1; - } else { - result = ValueString.get(insert(v0.getString(), v1.getInt(), v2.getInt(), v3.getString())); - } - break; - } - case LEFT: - result = ValueString.get(left(v0.getString(), v1.getInt())); - break; - case LOCATE: { - int start = v2 == null ? 0 : v2.getInt(); - result = ValueInt.get(locate(v0.getString(), v1.getString(), start)); - break; - } - case INSTR: { - int start = v2 == null ? 0 : v2.getInt(); - result = ValueInt.get(locate(v1.getString(), v0.getString(), start)); - break; - } - case REPEAT: { - int count = Math.max(0, v1.getInt()); - result = ValueString.get(repeat(v0.getString(), count)); - break; - } - case REPLACE: { - String s0 = v0.getString(); - String s1 = v1.getString(); - String s2 = (v2 == null) ? "" : v2.getString(); - result = ValueString.get(replace(s0, s1, s2)); - break; - } - case RIGHT: - result = ValueString.get(right(v0.getString(), v1.getInt())); - break; - case LTRIM: - result = ValueString.get(StringUtils.trim(v0.getString(), true, false, v1 == null ? " " : v1.getString())); - break; - case TRIM: - result = ValueString.get(StringUtils.trim(v0.getString(), true, true, v1 == null ? " " : v1.getString())); - break; - case RTRIM: - result = ValueString.get(StringUtils.trim(v0.getString(), false, true, v1 == null ? " " : v1.getString())); - break; - case SUBSTR: - case SUBSTRING: { - String s = v0.getString(); - int length = v2 == null ? s.length() : v2.getInt(); - result = ValueString.get(substring(s, v1.getInt(), length)); - break; - } - case POSITION: - result = ValueInt.get(locate(v0.getString(), v1.getString(), 0)); - break; - case XMLATTR: - result = ValueString.get(StringUtils.xmlAttr(v0.getString(), v1.getString())); - break; - case XMLNODE: { - String attr = v1 == null ? null : v1 == ValueNull.INSTANCE ? null : v1.getString(); - String content = v2 == null ? null : v2 == ValueNull.INSTANCE ? null : v2.getString(); - result = ValueString.get(StringUtils.xmlNode(v0.getString(), attr, content)); - break; - } - case REGEXP_REPLACE: { - String regexp = v1.getString(); - try { - result = ValueString.get(v0.getString().replaceAll(regexp, v2.getString())); - } catch (PatternSyntaxException e) { - throw DbException.get(ErrorCode.LIKE_ESCAPE_ERROR_1, e, regexp); - } - break; - } - case RPAD: - result = ValueString.get(StringUtils.pad(v0.getString(), v1.getInt(), v2 == null ? null : v2.getString(), true)); - break; - case LPAD: - result = ValueString.get(StringUtils.pad(v0.getString(), v1.getInt(), v2 == null ? null : v2.getString(), false)); - break; - // date - case DATE_ADD: - result = ValueTimestamp.getNoCopy(dateadd(v0.getString(), v1.getInt(), v2.getTimestampNoCopy())); - break; - case DATE_DIFF: - result = ValueLong.get(datediff(v0.getString(), v1.getTimestampNoCopy(), v2.getTimestampNoCopy())); - break; - case EXTRACT: { - int field = getDatePart(v0.getString()); - result = ValueInt.get(DateTimeUtils.getDatePart(v1.getTimestamp(), field)); - break; - } - case FORMATDATETIME: { - if (v0 == ValueNull.INSTANCE || v1 == ValueNull.INSTANCE) { - result = ValueNull.INSTANCE; - } else { - String locale = v2 == null ? null : v2 == ValueNull.INSTANCE ? null : v2.getString(); - String tz = v3 == null ? null : v3 == ValueNull.INSTANCE ? null : v3.getString(); - result = ValueString.get(DateTimeUtils.formatDateTime(v0.getTimestamp(), v1.getString(), locale, tz)); - } - break; - } - case PARSEDATETIME: { - if (v0 == ValueNull.INSTANCE || v1 == ValueNull.INSTANCE) { - result = ValueNull.INSTANCE; - } else { - String locale = v2 == null ? null : v2 == ValueNull.INSTANCE ? null : v2.getString(); - String tz = v3 == null ? null : v3 == ValueNull.INSTANCE ? null : v3.getString(); - java.util.Date d = DateTimeUtils.parseDateTime(v0.getString(), v1.getString(), locale, tz); - result = ValueTimestamp.getNoCopy(new Timestamp(d.getTime())); - } - break; - } - case NULLIF: - result = database.areEqual(v0, v1) ? ValueNull.INSTANCE : v0; - break; - // system - case NEXTVAL: { - Sequence sequence = getSequence(session, v0, v1); - SequenceValue value = new SequenceValue(sequence); - result = value.getValue(session); - break; - } - case CURRVAL: { - Sequence sequence = getSequence(session, v0, v1); - result = ValueLong.get(sequence.getCurrentValue()); - break; - } - case CSVREAD: { - String fileName = v0.getString(); - String columnList = v1 == null ? null : v1.getString(); - String charset = v2 == null ? null : v2.getString(); - String fieldSeparatorRead = v3 == null ? null : v3.getString(); - String fieldDelimiter = v4 == null ? null : v4.getString(); - String escapeCharacter = v5 == null ? null : v5.getString(); - Value v6 = getNullOrValue(session, argList, 6); - String nullString = v6 == null ? null : v6.getString(); - Csv csv = Csv.getInstance(); - setCsvDelimiterEscape(csv, fieldSeparatorRead, fieldDelimiter, escapeCharacter); - csv.setNullString(nullString); - char fieldSeparator = csv.getFieldSeparatorRead(); - String[] columns = StringUtils.arraySplit(columnList, fieldSeparator, true); - try { - ValueResultSet vr = ValueResultSet.get(csv.read(fileName, columns, charset)); - result = vr; - } catch (SQLException e) { - throw DbException.convert(e); - } - break; - } - case LINK_SCHEMA: { - session.getUser().checkAdmin(); - Connection conn = session.createConnection(false); - ResultSet rs = LinkSchema.linkSchema(conn, v0.getString(), v1.getString(), v2.getString(), v3.getString(), - v4.getString(), v5.getString()); - result = ValueResultSet.get(rs); - break; - } - case CSVWRITE: { - session.getUser().checkAdmin(); - Connection conn = session.createConnection(false); - String charset = v2 == null ? null : v2.getString(); - String fieldSeparatorWrite = v3 == null ? null : v3.getString(); - String fieldDelimiter = v4 == null ? null : v4.getString(); - String escapeCharacter = v5 == null ? null : v5.getString(); - Value v6 = getNullOrValue(session, argList, 6); - String nullString = v6 == null ? null : v6.getString(); - Value v7 = getNullOrValue(session, argList, 7); - String lineSeparator = v7 == null ? null : v7.getString(); - Csv csv = Csv.getInstance(); - setCsvDelimiterEscape(csv, fieldSeparatorWrite, fieldDelimiter, escapeCharacter); - csv.setNullString(nullString); - if (lineSeparator != null) { - csv.setLineSeparator(lineSeparator); - } - try { - int rows = csv.write(conn, v0.getString(), v1.getString(), charset); - result = ValueInt.get(rows); - } catch (SQLException e) { - throw DbException.convert(e); - } - break; - } - case SET: { - Variable var = (Variable) argList[0]; - session.setVariable(var.getName(), v1); - result = v1; - break; - } - case FILE_READ: { - session.getUser().checkAdmin(); - String fileName = v0.getString(); - boolean blob = argList.length == 1; - try { - InputStream in = new AutoCloseInputStream(IOUtils.openFileInputStream(fileName)); - if (blob) { - result = database.getLobStorage().createBlob(in, -1); - } else { - Reader reader; - if (v1 == ValueNull.INSTANCE) { - reader = new InputStreamReader(in); - } else { - reader = new InputStreamReader(in, v1.getString()); - } - result = database.getLobStorage().createClob(reader, -1); - } - } catch (IOException e) { - throw DbException.convertIOException(e, fileName); - } - break; - } - default: - throw DbException.throwInternalError("type=" + info.type); - } - return result; - } - - private Sequence getSequence(Session session, Value v0, Value v1) { - String schemaName, sequenceName; - if (v1 == null) { - Parser p = new Parser(session); - String sql = v0.getString(); - Expression expr = p.parseExpression(sql); - if (expr instanceof ExpressionColumn) { - ExpressionColumn seq = (ExpressionColumn) expr; - schemaName = seq.getOriginalTableAliasName(); - if (schemaName == null) { - schemaName = session.getCurrentSchemaName(); - } else { - if (schemaName.equals(StringUtils.toLowerEnglish(schemaName))) { - schemaName = StringUtils.toUpperEnglish(schemaName); - } - } - sequenceName = seq.getColumnName(); - if (sequenceName.equals(StringUtils.toLowerEnglish(sequenceName))) { - sequenceName = StringUtils.toUpperEnglish(sequenceName); - } - } else { - throw DbException.getSyntaxError(sql, 1); - } - } else { - schemaName = v0.getString(); - sequenceName = v1.getString(); - } - return database.getSchema(schemaName).getSequence(sequenceName); - } - - private long length(Value v) { - switch (v.getType()) { - case Value.BLOB: - case Value.CLOB: - case Value.BYTES: - case Value.JAVA_OBJECT: - return v.getPrecision(); - default: - return v.getString().length(); - } - } - - private byte[] getPaddedArrayCopy(byte[] data, int blockSize) { - int size = MathUtils.roundUpInt(data.length, blockSize); - byte[] newData = Utils.newBytes(size); - System.arraycopy(data, 0, newData, 0, data.length); - return newData; - } - - private byte[] decrypt(String algorithm, byte[] key, byte[] data) { - BlockCipher cipher = CipherFactory.getBlockCipher(algorithm); - byte[] newKey = getPaddedArrayCopy(key, cipher.getKeyLength()); - cipher.setKey(newKey); - byte[] newData = getPaddedArrayCopy(data, BlockCipher.ALIGN); - cipher.decrypt(newData, 0, newData.length); - return newData; - } - - private byte[] encrypt(String algorithm, byte[] key, byte[] data) { - BlockCipher cipher = CipherFactory.getBlockCipher(algorithm); - byte[] newKey = getPaddedArrayCopy(key, cipher.getKeyLength()); - cipher.setKey(newKey); - byte[] newData = getPaddedArrayCopy(data, BlockCipher.ALIGN); - cipher.encrypt(newData, 0, newData.length); - return newData; - } - - private byte[] getHash(String algorithm, byte[] bytes, int iterations) { - SHA256 hash = CipherFactory.getHash(algorithm); - for (int i = 0; i < iterations; i++) { - bytes = hash.getHash(bytes, false); - } - return bytes; - } - - /** - * Check if a given string is a valid date part string. - * - * @param part the string - * @return true if it is - */ - public static boolean isDatePart(String part) { - Integer p = DATE_PART.get(StringUtils.toUpperEnglish(part)); - return p != null; - } - - private static int getDatePart(String part) { - Integer p = DATE_PART.get(StringUtils.toUpperEnglish(part)); - if (p == null) { - throw DbException.get(ErrorCode.INVALID_VALUE_2, "date part", part); - } - return p.intValue(); - } - - private static Timestamp dateadd(String part, int count, Timestamp d) { - int field = getDatePart(part); - Calendar calendar = Calendar.getInstance(); - int nanos = d.getNanos() % 1000000; - calendar.setTime(d); - calendar.add(field, count); - long t = calendar.getTime().getTime(); - Timestamp ts = new Timestamp(t); - ts.setNanos(ts.getNanos() + nanos); - return ts; - } - - private static long datediff(String part, Timestamp d1, Timestamp d2) { - // diff (yy, 31.12.2004, 1.1.2005) = 1 - int field = getDatePart(part); - Calendar calendar = Calendar.getInstance(); - long t1 = d1.getTime(), t2 = d2.getTime(); - // need to convert to UTC, otherwise we get inconsistent results with - // certain time zones (those that are 30 minutes off) - TimeZone zone = calendar.getTimeZone(); - calendar.setTime(d1); - t1 += zone.getOffset(calendar.get(Calendar.ERA), calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH), - calendar.get(Calendar.DAY_OF_MONTH), calendar.get(Calendar.DAY_OF_WEEK), calendar - .get(Calendar.MILLISECOND)); - calendar.setTime(d2); - t2 += zone.getOffset(calendar.get(Calendar.ERA), calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH), - calendar.get(Calendar.DAY_OF_MONTH), calendar.get(Calendar.DAY_OF_WEEK), calendar - .get(Calendar.MILLISECOND)); - switch (field) { - case Calendar.MILLISECOND: - return t2 - t1; - case Calendar.SECOND: - case Calendar.MINUTE: - case Calendar.HOUR_OF_DAY: { - // first 'normalize' the numbers so both are not negative - long hour = 60 * 60 * 1000; - long add = Math.min(t1 / hour * hour, t2 / hour * hour); - t1 -= add; - t2 -= add; - switch (field) { - case Calendar.SECOND: - return t2 / 1000 - t1 / 1000; - case Calendar.MINUTE: - return t2 / (60 * 1000) - t1 / (60 * 1000); - case Calendar.HOUR_OF_DAY: - return t2 / hour - t1 / hour; - default: - throw DbException.throwInternalError("field:" + field); - } - } - case Calendar.DATE: - return t2 / (24 * 60 * 60 * 1000) - t1 / (24 * 60 * 60 * 1000); - default: - break; - } - calendar.setTime(new Timestamp(t1)); - int year1 = calendar.get(Calendar.YEAR); - int month1 = calendar.get(Calendar.MONTH); - calendar.setTime(new Timestamp(t2)); - int year2 = calendar.get(Calendar.YEAR); - int month2 = calendar.get(Calendar.MONTH); - int result = year2 - year1; - if (field == Calendar.MONTH) { - result = 12 * result + (month2 - month1); - } - return result; - } - - private static String substring(String s, int start, int length) { - int len = s.length(); - start--; - if (start < 0) { - start = 0; - } - if (length < 0) { - length = 0; - } - start = (start > len) ? len : start; - if (start + length > len) { - length = len - start; - } - return s.substring(start, start + length); - } - - private static String replace(String s, String replace, String with) { - if (s == null || replace == null || with == null) { - return null; - } - if (replace.length() == 0) { - // avoid out of memory - return s; - } - StringBuilder buff = new StringBuilder(s.length()); - int start = 0; - int len = replace.length(); - while (true) { - int i = s.indexOf(replace, start); - if (i == -1) { - break; - } - buff.append(s.substring(start, i)).append(with); - start = i + len; - } - buff.append(s.substring(start)); - return buff.toString(); - } - - private static String repeat(String s, int count) { - StringBuilder buff = new StringBuilder(s.length() * count); - while (count-- > 0) { - buff.append(s); - } - return buff.toString(); - } - - private static String rawToHex(String s) { - StringBuilder buff = new StringBuilder(4 * s.length()); - for (int i = 0; i < s.length(); i++) { - String hex = Integer.toHexString(s.charAt(i) & 0xffff); - for (int j = hex.length(); j < 4; j++) { - buff.append('0'); - } - buff.append(hex); - } - return buff.toString(); - } - - private static int locate(String search, String s, int start) { - if (start < 0) { - int i = s.length() + start; - return s.lastIndexOf(search, i) + 1; - } - int i = (start == 0) ? 0 : start - 1; - return s.indexOf(search, i) + 1; - } - - private static String right(String s, int count) { - if (count < 0) { - count = 0; - } else if (count > s.length()) { - count = s.length(); - } - return s.substring(s.length() - count); - } - - private static String left(String s, int count) { - if (count < 0) { - count = 0; - } else if (count > s.length()) { - count = s.length(); - } - return s.substring(0, count); - } - - private static String insert(String s1, int start, int length, String s2) { - if (s1 == null) { - return s2; - } - if (s2 == null) { - return s1; - } - int len1 = s1.length(); - int len2 = s2.length(); - start--; - if (start < 0 || length <= 0 || len2 == 0 || start > len1) { - return s1; - } - if (start + length > len1) { - length = len1 - start; - } - return s1.substring(0, start) + s2 + s1.substring(start + length); - } - - private static String hexToRaw(String s) { - // TODO function hextoraw compatibility with oracle - int len = s.length(); - if (len % 4 != 0) { - throw DbException.get(ErrorCode.DATA_CONVERSION_ERROR_1, s); - } - StringBuilder buff = new StringBuilder(len / 4); - for (int i = 0; i < len; i += 4) { - try { - char raw = (char) Integer.parseInt(s.substring(i, i + 4), 16); - buff.append(raw); - } catch (NumberFormatException e) { - throw DbException.get(ErrorCode.DATA_CONVERSION_ERROR_1, s); - } - } - return buff.toString(); - } - - private static int getDifference(String s1, String s2) { - // TODO function difference: compatibility with SQL Server and HSQLDB - s1 = getSoundex(s1); - s2 = getSoundex(s2); - int e = 0; - for (int i = 0; i < 4; i++) { - if (s1.charAt(i) == s2.charAt(i)) { - e++; - } - } - return e; - } - - private double roundmagic(double d) { - if ((d < 0.0000000000001) && (d > -0.0000000000001)) { - return 0.0; - } - if ((d > 1000000000000.) || (d < -1000000000000.)) { - return d; - } - StringBuilder s = new StringBuilder(); - s.append(d); - if (s.toString().indexOf("E") >= 0) { - return d; - } - int len = s.length(); - if (len < 16) { - return d; - } - if (s.toString().indexOf(".") > len - 3) { - return d; - } - s.delete(len - 2, len); - len -= 2; - char c1 = s.charAt(len - 2); - char c2 = s.charAt(len - 3); - char c3 = s.charAt(len - 4); - if ((c1 == '0') && (c2 == '0') && (c3 == '0')) { - s.setCharAt(len - 1, '0'); - } else if ((c1 == '9') && (c2 == '9') && (c3 == '9')) { - s.setCharAt(len - 1, '9'); - s.append('9'); - s.append('9'); - s.append('9'); - } - return Double.valueOf(s.toString()).doubleValue(); - } - - private static String getSoundex(String s) { - int len = s.length(); - char[] chars = { '0', '0', '0', '0' }; - char lastDigit = '0'; - for (int i = 0, j = 0; i < len && j < 4; i++) { - char c = s.charAt(i); - char newDigit = c > SOUNDEX_INDEX.length ? 0 : SOUNDEX_INDEX[c]; - if (newDigit != 0) { - if (j == 0) { - chars[j++] = c; - lastDigit = newDigit; - } else if (newDigit <= '6') { - if (newDigit != lastDigit) { - chars[j++] = newDigit; - lastDigit = newDigit; - } - } else if (newDigit == '7') { - lastDigit = newDigit; - } - } - } - return new String(chars); - } - - public int getType() { - return dataType; - } - - public void mapColumns(ColumnResolver resolver, int level) { - for (Expression e : args) { - e.mapColumns(resolver, level); - } - } - - /** - * Check if the parameter count is correct. - * - * @param len the number of parameters set - * @throws SQLException if the parameter count is incorrect - */ - protected void checkParameterCount(int len) { - int min = 0, max = Integer.MAX_VALUE; - switch (info.type) { - case COALESCE: - case CSVREAD: - case LEAST: - case GREATEST: - min = 1; - break; - case NOW: - case CURRENT_TIMESTAMP: - case RAND: - max = 1; - break; - case COMPRESS: - case LTRIM: - case RTRIM: - case TRIM: - case FILE_READ: - min = 1; - max = 2; - break; - case REPLACE: - case LOCATE: - case INSTR: - case SUBSTR: - case SUBSTRING: - case LPAD: - case RPAD: - min = 2; - max = 3; - break; - case CASE: - case CONCAT: - case CSVWRITE: - min = 2; - break; - case XMLNODE: - min = 1; - max = 3; - break; - case FORMATDATETIME: - case PARSEDATETIME: - min = 2; - max = 4; - break; - case CURRVAL: - case NEXTVAL: - min = 1; - max = 2; - break; - default: - DbException.throwInternalError("type=" + info.type); - } - boolean ok = (len >= min) && (len <= max); - if (!ok) { - throw DbException.get(ErrorCode.INVALID_PARAMETER_COUNT_2, info.name, min + ".." + max); - } - } - - /** - * This method is called after all the parameters have been set. - * It checks if the parameter count is correct. - * - * @throws SQLException if the parameter count is incorrect. - */ - public void doneWithParameters() { - if (info.parameterCount == VAR_ARGS) { - int len = varArgs.size(); - checkParameterCount(len); - args = new Expression[len]; - varArgs.toArray(args); - varArgs = null; - } else { - int len = args.length; - if (len > 0 && args[len - 1] == null) { - throw DbException - .get(ErrorCode.INVALID_PARAMETER_COUNT_2, info.name, "" + len); - } - } - } - - /** - * Set the result data type of this function. - * - * @param dataType the data type - * @param precision the precision - * @param scale the scale - * @param displaySize the display size - */ - public void setDataType(int dataType, long precision, int scale, int displaySize) { - this.dataType = dataType; - this.precision = precision; - this.displaySize = displaySize; - this.scale = scale; - } - - public void setDataType(Column col) { - dataType = col.getType(); - precision = col.getPrecision(); - displaySize = col.getDisplaySize(); - scale = col.getScale(); - } - - public Expression optimize(Session session) { - boolean allConst = info.deterministic; - for (int i = 0; i < args.length; i++) { - Expression e = args[i].optimize(session); - args[i] = e; - if (!e.isConstant()) { - allConst = false; - } - } - int t, s, d; - long p; - Expression p0 = args.length < 1 ? null : args[0]; - switch (info.type) { - case IFNULL: - case NULLIF: - case COALESCE: - case LEAST: - case GREATEST: { - t = Value.UNKNOWN; - s = 0; - p = 0; - d = 0; - for (Expression e : args) { - if (e != ValueExpression.getNull() && e.getType() != Value.UNKNOWN) { - t = Value.getHigherOrder(t, e.getType()); - s = Math.max(s, e.getScale()); - p = Math.max(p, e.getPrecision()); - d = Math.max(d, e.getDisplaySize()); - } - } - if (t == Value.UNKNOWN) { - t = Value.STRING; - s = 0; - p = Integer.MAX_VALUE; - d = Integer.MAX_VALUE; - } - break; - } - case CASEWHEN: - t = Value.getHigherOrder(args[1].getType(), args[2].getType()); - p = Math.max(args[1].getPrecision(), args[2].getPrecision()); - d = Math.max(args[1].getDisplaySize(), args[2].getDisplaySize()); - s = Math.max(args[1].getScale(), args[2].getScale()); - break; - case CAST: - case CONVERT: - // data type, precision and scale is already set - t = dataType; - p = precision; - s = scale; - d = displaySize; - break; - case ABS: - case FLOOR: - case RADIANS: - case ROUND: - case TRUNCATE: - case POWER: - t = p0.getType(); - s = p0.getScale(); - p = p0.getPrecision(); - d = p0.getDisplaySize(); - if (t == Value.NULL) { - t = Value.INT; - p = ValueInt.PRECISION; - d = ValueInt.DISPLAY_SIZE; - s = 0; - } - break; - case SET: { - Expression p1 = args[1]; - t = p1.getType(); - p = p1.getPrecision(); - s = p1.getScale(); - d = p1.getDisplaySize(); - if (!(p0 instanceof Variable)) { - throw DbException.get(ErrorCode.CAN_ONLY_ASSIGN_TO_VARIABLE_1, p0.getSQL()); - } - break; - } - case FILE_READ: { - if (args.length == 1) { - t = Value.BLOB; - } else { - t = Value.CLOB; - } - p = Integer.MAX_VALUE; - s = 0; - d = Integer.MAX_VALUE; - break; - } - case SUBSTRING: - case SUBSTR: { - t = info.dataType; - p = args[0].getPrecision(); - s = 0; - if (args[1].isConstant()) { - // if only two arguments are used, - // subtract offset from first argument length - p -= args[1].getValue(session).getLong() - 1; - } - if (args.length == 3 && args[2].isConstant()) { - // if the third argument is constant it is at most this value - p = Math.min(p, args[2].getValue(session).getLong()); - } - p = Math.max(0, p); - d = MathUtils.convertLongToInt(p); - break; - } - default: - t = info.dataType; - DataType type = DataType.getDataType(t); - p = PRECISION_UNKNOWN; - d = 0; - s = type.defaultScale; - } - dataType = t; - precision = p; - scale = s; - displaySize = d; - if (allConst) { - return ValueExpression.get(getValue(session)); - } - return this; - } - - public void setEvaluatable(TableFilter tableFilter, boolean b) { - for (Expression e : args) { - if (e != null) { - e.setEvaluatable(tableFilter, b); - } - } - } - - public int getScale() { - return scale; - } - - public long getPrecision() { - if (precision == PRECISION_UNKNOWN) { - calculatePrecisionAndDisplaySize(); - } - return precision; - } - - public int getDisplaySize() { - if (precision == PRECISION_UNKNOWN) { - calculatePrecisionAndDisplaySize(); - } - return displaySize; - } - - private void calculatePrecisionAndDisplaySize() { - switch (info.type) { - case ENCRYPT: - case DECRYPT: - precision = args[2].getPrecision(); - displaySize = args[2].getDisplaySize(); - break; - case COMPRESS: - precision = args[0].getPrecision(); - displaySize = args[0].getDisplaySize(); - break; - case CHAR: - precision = 1; - displaySize = 1; - break; - case CONCAT: - precision = 0; - displaySize = 0; - for (Expression e : args) { - precision += e.getPrecision(); - displaySize = MathUtils.convertLongToInt((long) displaySize + e.getDisplaySize()); - if (precision < 0) { - precision = Long.MAX_VALUE; - } - } - break; - case HEXTORAW: - precision = (args[0].getPrecision() + 3) / 4; - displaySize = MathUtils.convertLongToInt(precision); - break; - case LCASE: - case LTRIM: - case RIGHT: - case RTRIM: - case UCASE: - case LOWER: - case UPPER: - case TRIM: - case STRINGDECODE: - case UTF8TOSTRING: - precision = args[0].getPrecision(); - displaySize = args[0].getDisplaySize(); - break; - case RAWTOHEX: - precision = args[0].getPrecision() * 4; - displaySize = MathUtils.convertLongToInt(precision); - break; - case SOUNDEX: - precision = 4; - displaySize = (int) precision; - break; - case DAY_NAME: - case MONTH_NAME: - // day and month names may be long in some languages - precision = 20; - displaySize = (int) precision; - break; - default: - DataType type = DataType.getDataType(dataType); - precision = type.defaultPrecision; - displaySize = type.defaultDisplaySize; - } - } - - public String getSQL() { - StatementBuilder buff = new StatementBuilder(info.name); - buff.append('('); - switch (info.type) { - case CAST: { - buff.append(args[0].getSQL()).append(" AS "). - append(new Column(null, dataType, precision, scale, displaySize).getCreateSQL()); - break; - } - case CONVERT: { - buff.append(args[0].getSQL()).append(','). - append(new Column(null, dataType, precision, scale, displaySize).getCreateSQL()); - break; - } - case EXTRACT: { - ValueString v = (ValueString) ((ValueExpression) args[0]).getValue(null); - buff.append(v.getString()).append(" FROM ").append(args[1].getSQL()); - break; - } - default: { - for (Expression e : args) { - buff.appendExceptFirst(", "); - buff.append(e.getSQL()); - } - } - } - return buff.append(')').toString(); - } - - public void updateAggregate(Session session) { - for (Expression e : args) { - if (e != null) { - e.updateAggregate(session); - } - } - } - - public int getFunctionType() { - return info.type; - } - - public String getName() { - return info.name; - } - - public int getParameterCount() { - return args.length; - } - - public ValueResultSet getValueForColumnList(Session session, Expression[] argList) { - switch (info.type) { - case CSVREAD: { - String fileName = argList[0].getValue(session).getString(); - if (fileName == null) { - throw DbException.get(ErrorCode.PARAMETER_NOT_SET_1, "fileName"); - } - String columnList = argList.length < 2 ? null : argList[1].getValue(session).getString(); - String charset = argList.length < 3 ? null : argList[2].getValue(session).getString(); - String fieldSeparatorRead = argList.length < 4 ? null : argList[3].getValue(session).getString(); - String fieldDelimiter = argList.length < 5 ? null : argList[4].getValue(session).getString(); - String escapeCharacter = argList.length < 6 ? null : argList[5].getValue(session).getString(); - Csv csv = Csv.getInstance(); - setCsvDelimiterEscape(csv, fieldSeparatorRead, fieldDelimiter, escapeCharacter); - char fieldSeparator = csv.getFieldSeparatorRead(); - String[] columns = StringUtils.arraySplit(columnList, fieldSeparator, true); - ResultSet rs = null; - ValueResultSet x; - try { - rs = csv.read(fileName, columns, charset); - x = ValueResultSet.getCopy(rs, 0); - } catch (SQLException e) { - throw DbException.convert(e); - } finally { - JdbcUtils.closeSilently(rs); - } - return x; - } - default: - break; - } - return (ValueResultSet) getValueWithArgs(session, argList); - } - - private void setCsvDelimiterEscape(Csv csv, String fieldSeparator, String fieldDelimiter, String escapeCharacter) { - if (fieldSeparator != null) { - csv.setFieldSeparatorWrite(fieldSeparator); - if (fieldSeparator.length() > 0) { - char fs = fieldSeparator.charAt(0); - csv.setFieldSeparatorRead(fs); - } - } - if (fieldDelimiter != null) { - char fd = fieldDelimiter.length() == 0 ? 0 : fieldDelimiter.charAt(0); - csv.setFieldDelimiter(fd); - } - if (escapeCharacter != null) { - char ec = escapeCharacter.length() == 0 ? 0 : escapeCharacter.charAt(0); - csv.setEscapeCharacter(ec); - } - } - - public Expression[] getArgs() { - return args; - } - - public boolean isEverything(ExpressionVisitor visitor) { - for (Expression e : args) { - if (e != null && !e.isEverything(visitor)) { - return false; - } - } - switch (visitor.getType()) { - case ExpressionVisitor.DETERMINISTIC: - case ExpressionVisitor.QUERY_COMPARABLE: - case ExpressionVisitor.READONLY: - return info.deterministic; - case ExpressionVisitor.EVALUATABLE: - case ExpressionVisitor.GET_DEPENDENCIES: - case ExpressionVisitor.INDEPENDENT: - case ExpressionVisitor.NOT_FROM_RESOLVER: - case ExpressionVisitor.OPTIMIZABLE_MIN_MAX_COUNT_ALL: - case ExpressionVisitor.SET_MAX_DATA_MODIFICATION_ID: - return true; - default: - throw DbException.throwInternalError("type=" + visitor.getType()); - } - } - - public int getCost() { - int cost = 3; - for (Expression e : args) { - cost += e.getCost(); - } - return cost; - } - - public boolean isDeterministic() { - return info.deterministic; - } - -} diff --git a/tools/h2/src/main/org/h2/expression/FunctionCall.java b/tools/h2/src/main/org/h2/expression/FunctionCall.java deleted file mode 100755 index f8fc150..0000000 --- a/tools/h2/src/main/org/h2/expression/FunctionCall.java +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.expression; - -import org.h2.engine.Session; -import org.h2.value.Value; -import org.h2.value.ValueResultSet; - -/** - * This interface is used by the built-in functions, - * as well as the user-defined functions. - */ -public interface FunctionCall { - - /** - * Get the name of the function. - * - * @return the name - */ - String getName(); - - /** - * Get the number of parameters. - * - * @return the number of parameters - */ - int getParameterCount(); - - /** - * Get an empty result set with the column names set. - * - * @param session the session - * @param nullArgs the argument list (some arguments may be null) - * @return the empty result set - */ - ValueResultSet getValueForColumnList(Session session, Expression[] nullArgs); - - /** - * Get the data type. - * - * @return the data type - */ - int getType(); - - /** - * Optimize the function if possible. - * - * @param session the session - * @return the optimized expression - */ - Expression optimize(Session session); - - /** - * Calculate the result. - * - * @param session the session - * @return the result - */ - Value getValue(Session session); - - /** - * Get the function arguments. - * - * @return argument list - */ - Expression[] getArgs(); - - /** - * Get the SQL snippet of the function (including arguments). - * - * @return the SQL snippet. - */ - String getSQL(); - - /** - * Whether the function always returns the same result for the same parameters. - * - * @return true if it does - */ - boolean isDeterministic(); -} diff --git a/tools/h2/src/main/org/h2/expression/FunctionInfo.java b/tools/h2/src/main/org/h2/expression/FunctionInfo.java deleted file mode 100755 index 9e51fbc..0000000 --- a/tools/h2/src/main/org/h2/expression/FunctionInfo.java +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.expression; - -/** - * This class contains information about a built-in function. - */ -class FunctionInfo { - - /** - * The name of the function. - */ - String name; - - /** - * The function type. - */ - int type; - - /** - * The data type of the return value. - */ - int dataType; - - /** - * The number of parameters. - */ - int parameterCount; - - /** - * If the result of the function is NULL if any of the parameters is NULL. - */ - boolean nullIfParameterIsNull; - - /** - * If this function always returns the same value for the same parameters. - */ - boolean deterministic; -} diff --git a/tools/h2/src/main/org/h2/expression/JavaAggregate.java b/tools/h2/src/main/org/h2/expression/JavaAggregate.java deleted file mode 100755 index b17413d..0000000 --- a/tools/h2/src/main/org/h2/expression/JavaAggregate.java +++ /dev/null @@ -1,197 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.expression; - -import java.sql.Connection; -import java.sql.SQLException; -import java.util.HashMap; -import org.h2.api.AggregateFunction; -import org.h2.command.Parser; -import org.h2.command.dml.Select; -import org.h2.constant.ErrorCode; -import org.h2.engine.Session; -import org.h2.engine.UserAggregate; -import org.h2.message.DbException; -import org.h2.table.ColumnResolver; -import org.h2.table.TableFilter; -import org.h2.util.StatementBuilder; -import org.h2.value.DataType; -import org.h2.value.Value; -import org.h2.value.ValueNull; - -/** - * This class wraps a user-defined aggregate. - */ -public class JavaAggregate extends Expression { - - private final UserAggregate userAggregate; - private final Select select; - private AggregateFunction aggregate; - private Expression[] args; - private int[] argTypes; - private int dataType; - private Connection userConnection; - private int lastGroupRowId; - - public JavaAggregate(UserAggregate userAggregate, Expression[] args, Select select) { - this.userAggregate = userAggregate; - this.args = args; - this.select = select; - } - - public int getCost() { - int cost = 5; - for (Expression e : args) { - cost += e.getCost(); - } - return cost; - } - - public long getPrecision() { - return Integer.MAX_VALUE; - } - - public int getDisplaySize() { - return Integer.MAX_VALUE; - } - - public int getScale() { - return DataType.getDataType(dataType).defaultScale; - } - - public String getSQL() { - StatementBuilder buff = new StatementBuilder(); - buff.append(Parser.quoteIdentifier(userAggregate.getName())).append('('); - for (Expression e : args) { - buff.appendExceptFirst(", "); - buff.append(e.getSQL()); - } - return buff.append(')').toString(); - } - - public int getType() { - return dataType; - } - - public boolean isEverything(ExpressionVisitor visitor) { - switch(visitor.getType()) { - case ExpressionVisitor.DETERMINISTIC: - // TODO optimization: some functions are deterministic, but we don't - // know (no setting for that) - case ExpressionVisitor.OPTIMIZABLE_MIN_MAX_COUNT_ALL: - // user defined aggregate functions can not be optimized - return false; - case ExpressionVisitor.GET_DEPENDENCIES: - visitor.addDependency(userAggregate); - break; - default: - } - for (Expression e : args) { - if (e != null && !e.isEverything(visitor)) { - return false; - } - } - return true; - } - - public void mapColumns(ColumnResolver resolver, int level) { - for (int i = 0; i < args.length; i++) { - args[i].mapColumns(resolver, level); - } - } - - public Expression optimize(Session session) { - userConnection = session.createConnection(false); - argTypes = new int[args.length]; - int[] argSqlTypes = new int[args.length]; - for (int i = 0; i < args.length; i++) { - Expression expr = args[i]; - args[i] = expr.optimize(session); - int type = expr.getType(); - argTypes[i] = type; - argSqlTypes[i] = DataType.convertTypeToSQLType(type); - } - try { - aggregate = getInstance(); - dataType = DataType.convertSQLTypeToValueType(aggregate.getType(argSqlTypes)); - } catch (SQLException e) { - throw DbException.convert(e); - } - return this; - } - - public void setEvaluatable(TableFilter tableFilter, boolean b) { - for (Expression e : args) { - e.setEvaluatable(tableFilter, b); - } - } - - private AggregateFunction getInstance() throws SQLException { - AggregateFunction agg = userAggregate.getInstance(); - agg.init(userConnection); - return agg; - } - - public Value getValue(Session session) { - HashMap group = select.getCurrentGroup(); - if (group == null) { - throw DbException.get(ErrorCode.INVALID_USE_OF_AGGREGATE_FUNCTION_1, getSQL()); - } - try { - AggregateFunction agg = (AggregateFunction) group.get(this); - if (agg == null) { - agg = getInstance(); - } - Object obj = agg.getResult(); - if (obj == null) { - return ValueNull.INSTANCE; - } - return DataType.convertToValue(session, obj, dataType); - } catch (SQLException e) { - throw DbException.convert(e); - } - } - - public void updateAggregate(Session session) { - HashMap group = select.getCurrentGroup(); - if (group == null) { - // this is a different level (the enclosing query) - return; - } - - int groupRowId = select.getCurrentGroupRowId(); - if (lastGroupRowId == groupRowId) { - // already visited - return; - } - lastGroupRowId = groupRowId; - - AggregateFunction agg = (AggregateFunction) group.get(this); - try { - if (agg == null) { - agg = getInstance(); - group.put(this, agg); - } - Object[] argValues = new Object[args.length]; - Object arg = null; - for (int i = 0; i < args.length; i++) { - Value v = args[i].getValue(session); - v = v.convertTo(argTypes[i]); - arg = v.getObject(); - argValues[i] = arg; - } - if (args.length == 1) { - agg.add(arg); - } else { - agg.add(argValues); - } - } catch (SQLException e) { - throw DbException.convert(e); - } - } - -} diff --git a/tools/h2/src/main/org/h2/expression/JavaFunction.java b/tools/h2/src/main/org/h2/expression/JavaFunction.java deleted file mode 100755 index 03232ef..0000000 --- a/tools/h2/src/main/org/h2/expression/JavaFunction.java +++ /dev/null @@ -1,150 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.expression; - -import org.h2.command.Parser; -import org.h2.engine.FunctionAlias; -import org.h2.engine.Session; -import org.h2.table.ColumnResolver; -import org.h2.table.TableFilter; -import org.h2.util.StatementBuilder; -import org.h2.value.DataType; -import org.h2.value.Value; -import org.h2.value.ValueNull; -import org.h2.value.ValueResultSet; - -/** - * This class wraps a user-defined function. - */ -public class JavaFunction extends Expression implements FunctionCall { - - private FunctionAlias functionAlias; - private FunctionAlias.JavaMethod javaMethod; - private Expression[] args; - - public JavaFunction(FunctionAlias functionAlias, Expression[] args) { - this.functionAlias = functionAlias; - this.javaMethod = functionAlias.findJavaMethod(args); - this.args = args; - } - - public Value getValue(Session session) { - return javaMethod.getValue(session, args, false); - } - - public int getType() { - return javaMethod.getDataType(); - } - - public void mapColumns(ColumnResolver resolver, int level) { - for (Expression e : args) { - e.mapColumns(resolver, level); - } - } - - public Expression optimize(Session session) { - boolean allConst = isDeterministic(); - for (int i = 0; i < args.length; i++) { - Expression e = args[i].optimize(session); - args[i] = e; - allConst &= e.isConstant(); - } - if (allConst) { - return ValueExpression.get(getValue(session)); - } - return this; - } - - public void setEvaluatable(TableFilter tableFilter, boolean b) { - for (Expression e : args) { - if (e != null) { - e.setEvaluatable(tableFilter, b); - } - } - } - - public int getScale() { - return DataType.getDataType(getType()).defaultScale; - } - - public long getPrecision() { - return Integer.MAX_VALUE; - } - - public int getDisplaySize() { - return Integer.MAX_VALUE; - } - - public String getSQL() { - StatementBuilder buff = new StatementBuilder(); - buff.append(Parser.quoteIdentifier(functionAlias.getName())).append('('); - for (Expression e : args) { - buff.appendExceptFirst(", "); - buff.append(e.getSQL()); - } - return buff.append(')').toString(); - } - - public void updateAggregate(Session session) { - for (Expression e : args) { - if (e != null) { - e.updateAggregate(session); - } - } - } - - public String getName() { - return functionAlias.getName(); - } - - public int getParameterCount() { - return javaMethod.getParameterCount(); - } - - public ValueResultSet getValueForColumnList(Session session, Expression[] argList) { - Value v = javaMethod.getValue(session, argList, true); - return v == ValueNull.INSTANCE ? null : (ValueResultSet) v; - } - - public Expression[] getArgs() { - return args; - } - - public boolean isEverything(ExpressionVisitor visitor) { - switch(visitor.getType()) { - case ExpressionVisitor.DETERMINISTIC: - if (!isDeterministic()) { - return false; - } - // only if all parameters are deterministic as well - break; - case ExpressionVisitor.GET_DEPENDENCIES: - visitor.addDependency(functionAlias); - break; - default: - } - for (Expression e : args) { - if (e != null && !e.isEverything(visitor)) { - return false; - } - } - return true; - } - - public int getCost() { - int cost = javaMethod.hasConnectionParam() ? 25 : 5; - for (Expression e : args) { - cost += e.getCost(); - } - return cost; - } - - public boolean isDeterministic() { - return functionAlias.isDeterministic(); - } - -} diff --git a/tools/h2/src/main/org/h2/expression/Operation.java b/tools/h2/src/main/org/h2/expression/Operation.java deleted file mode 100755 index 84d9db0..0000000 --- a/tools/h2/src/main/org/h2/expression/Operation.java +++ /dev/null @@ -1,278 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.expression; - -import org.h2.engine.Mode; -import org.h2.engine.Session; -import org.h2.message.DbException; -import org.h2.table.ColumnResolver; -import org.h2.table.TableFilter; -import org.h2.util.MathUtils; -import org.h2.value.DataType; -import org.h2.value.Value; -import org.h2.value.ValueNull; -import org.h2.value.ValueString; - -/** - * A mathematical expression, or string concatenation. - */ -public class Operation extends Expression { - - /** - * This operation represents a string concatenation as in 'Hello' || 'World'. - */ - public static final int CONCAT = 0; - - /** - * This operation represents an addition as in 1 + 2. - */ - public static final int PLUS = 1; - - /** - * This operation represents a subtraction as in 2 - 1. - */ - public static final int MINUS = 2; - - /** - * This operation represents a multiplication as in 2 * 3. - */ - public static final int MULTIPLY = 3; - - /** - * This operation represents a division as in 4 * 2. - */ - public static final int DIVIDE = 4; - - /** - * This operation represents a negation as in - ID. - */ - public static final int NEGATE = 5; - - private int opType; - private Expression left, right; - private int dataType; - - public Operation(int opType, Expression left, Expression right) { - this.opType = opType; - this.left = left; - this.right = right; - } - - public String getSQL() { - String sql; - switch (opType) { - case NEGATE: - // don't remove the space, otherwise it might end up some thing like - // --1 which is a line remark - sql = "- " + left.getSQL(); - break; - case CONCAT: - sql = left.getSQL() + " || " + right.getSQL(); - break; - case PLUS: - sql = left.getSQL() + " + " + right.getSQL(); - break; - case MINUS: - sql = left.getSQL() + " - " + right.getSQL(); - break; - case MULTIPLY: - sql = left.getSQL() + " * " + right.getSQL(); - break; - case DIVIDE: - sql = left.getSQL() + " / " + right.getSQL(); - break; - default: - throw DbException.throwInternalError("opType=" + opType); - } - return "(" + sql + ")"; - } - - public Value getValue(Session session) { - Value l = left.getValue(session).convertTo(dataType); - Value r = right == null ? null : right.getValue(session).convertTo(dataType); - - switch (opType) { - case NEGATE: - return l == ValueNull.INSTANCE ? l : l.negate(); - case CONCAT: { - Mode mode = session.getDatabase().getMode(); - if (l == ValueNull.INSTANCE) { - if (mode.nullConcatIsNull) { - return ValueNull.INSTANCE; - } - return r; - } else if (r == ValueNull.INSTANCE) { - if (mode.nullConcatIsNull) { - return ValueNull.INSTANCE; - } - return l; - } - String s1 = l.getString(), s2 = r.getString(); - StringBuilder buff = new StringBuilder(s1.length() + s2.length()); - buff.append(s1).append(s2); - return ValueString.get(buff.toString()); - } - case PLUS: - if (l == ValueNull.INSTANCE || r == ValueNull.INSTANCE) { - return ValueNull.INSTANCE; - } - return l.add(r); - case MINUS: - if (l == ValueNull.INSTANCE || r == ValueNull.INSTANCE) { - return ValueNull.INSTANCE; - } - return l.subtract(r); - case MULTIPLY: - if (l == ValueNull.INSTANCE || r == ValueNull.INSTANCE) { - return ValueNull.INSTANCE; - } - return l.multiply(r); - case DIVIDE: - if (l == ValueNull.INSTANCE || r == ValueNull.INSTANCE) { - return ValueNull.INSTANCE; - } - return l.divide(r); - default: - throw DbException.throwInternalError("type=" + opType); - } - } - - public void mapColumns(ColumnResolver resolver, int level) { - left.mapColumns(resolver, level); - if (right != null) { - right.mapColumns(resolver, level); - } - } - - public Expression optimize(Session session) { - left = left.optimize(session); - switch (opType) { - case NEGATE: - dataType = left.getType(); - if (dataType == Value.UNKNOWN) { - dataType = Value.DECIMAL; - } - break; - case CONCAT: - right = right.optimize(session); - dataType = Value.STRING; - if (left.isConstant() && right.isConstant()) { - return ValueExpression.get(getValue(session)); - } - break; - case PLUS: - case MINUS: - case MULTIPLY: - case DIVIDE: - right = right.optimize(session); - int l = left.getType(); - int r = right.getType(); - if ((l == Value.NULL && r == Value.NULL) || (l == Value.UNKNOWN && r == Value.UNKNOWN)) { - // (? + ?) - use decimal by default (the most safe data type) or - // string when text concatenation with + is enabled - if (opType == PLUS && session.getDatabase().getMode().allowPlusForStringConcat) { - dataType = Value.STRING; - opType = CONCAT; - } else { - dataType = Value.DECIMAL; - } - } else if (l == Value.DATE || l == Value.TIMESTAMP) { - if (r == Value.INT && (opType == PLUS || opType == MINUS)) { - // Oracle date add - Function f = Function.getFunction(session.getDatabase(), "DATEADD"); - f.setParameter(0, ValueExpression.get(ValueString.get("DAY"))); - if (opType == MINUS) { - right = new Operation(NEGATE, right, null); - right = right.optimize(session); - } - f.setParameter(1, right); - f.setParameter(2, left); - f.doneWithParameters(); - return f.optimize(session); - } else if (opType == MINUS && (l == Value.DATE || l == Value.TIMESTAMP)) { - // Oracle date subtract - Function f = Function.getFunction(session.getDatabase(), "DATEDIFF"); - f.setParameter(0, ValueExpression.get(ValueString.get("DAY"))); - f.setParameter(1, right); - f.setParameter(2, left); - f.doneWithParameters(); - return f.optimize(session); - } - } else { - dataType = Value.getHigherOrder(l, r); - if (DataType.isStringType(dataType) && session.getDatabase().getMode().allowPlusForStringConcat) { - opType = CONCAT; - } - } - break; - default: - DbException.throwInternalError("type=" + opType); - } - if (left.isConstant() && (right == null || right.isConstant())) { - return ValueExpression.get(getValue(session)); - } - return this; - } - - public void setEvaluatable(TableFilter tableFilter, boolean b) { - left.setEvaluatable(tableFilter, b); - if (right != null) { - right.setEvaluatable(tableFilter, b); - } - } - - public int getType() { - return dataType; - } - - public long getPrecision() { - if (right != null) { - switch (opType) { - case CONCAT: - return left.getPrecision() + right.getPrecision(); - default: - return Math.max(left.getPrecision(), right.getPrecision()); - } - } - return left.getPrecision(); - } - - public int getDisplaySize() { - if (right != null) { - switch (opType) { - case CONCAT: - return MathUtils.convertLongToInt((long) left.getDisplaySize() + (long) right.getDisplaySize()); - default: - return Math.max(left.getDisplaySize(), right.getDisplaySize()); - } - } - return left.getDisplaySize(); - } - - public int getScale() { - if (right != null) { - return Math.max(left.getScale(), right.getScale()); - } - return left.getScale(); - } - - public void updateAggregate(Session session) { - left.updateAggregate(session); - if (right != null) { - right.updateAggregate(session); - } - } - - public boolean isEverything(ExpressionVisitor visitor) { - return left.isEverything(visitor) && (right == null || right.isEverything(visitor)); - } - - public int getCost() { - return left.getCost() + 1 + (right == null ? 0 : right.getCost()); - } - -} diff --git a/tools/h2/src/main/org/h2/expression/Parameter.java b/tools/h2/src/main/org/h2/expression/Parameter.java deleted file mode 100755 index 15c08dc..0000000 --- a/tools/h2/src/main/org/h2/expression/Parameter.java +++ /dev/null @@ -1,163 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.expression; - -import org.h2.constant.ErrorCode; -import org.h2.engine.Session; -import org.h2.message.DbException; -import org.h2.table.Column; -import org.h2.table.ColumnResolver; -import org.h2.table.TableFilter; -import org.h2.value.Value; -import org.h2.value.ValueBoolean; -import org.h2.value.ValueNull; - -/** - * A parameter of a prepared statement. - */ -public class Parameter extends Expression implements ParameterInterface { - - private Value value; - private Column column; - private int index; - - public Parameter(int index) { - this.index = index; - } - - public String getSQL() { - return "?" + (index + 1); - } - - public void setValue(Value v, boolean closeOld) { - // don't need to close the old value as temporary files are anyway removed - this.value = v; - } - - public void setValue(Value v) { - this.value = v; - } - - public Value getParamValue() { - if (value == null) { - // to allow parameters in function tables - return ValueNull.INSTANCE; - } - return value; - } - - public Value getValue(Session session) { - return getParamValue(); - } - - public int getType() { - if (value != null) { - return value.getType(); - } - if (column != null) { - return column.getType(); - } - return Value.UNKNOWN; - } - - public void mapColumns(ColumnResolver resolver, int level) { - // can't map - } - - public void checkSet() { - if (value == null) { - throw DbException.get(ErrorCode.PARAMETER_NOT_SET_1, "#" + (index + 1)); - } - } - - public Expression optimize(Session session) { - return this; - } - - public boolean isConstant() { - return false; - } - - public boolean isValueSet() { - return value != null; - } - - public void setEvaluatable(TableFilter tableFilter, boolean b) { - // not bound - } - - public int getScale() { - if (value != null) { - return value.getScale(); - } - if (column != null) { - return column.getScale(); - } - return 0; - } - - public long getPrecision() { - if (value != null) { - return value.getPrecision(); - } - if (column != null) { - return column.getPrecision(); - } - return 0; - } - - public int getDisplaySize() { - if (value != null) { - return value.getDisplaySize(); - } - if (column != null) { - return column.getDisplaySize(); - } - return 0; - } - - public void updateAggregate(Session session) { - // nothing to do - } - - public boolean isEverything(ExpressionVisitor visitor) { - switch(visitor.getType()) { - case ExpressionVisitor.EVALUATABLE: - // the parameter _will_be_ evaluatable at execute time - case ExpressionVisitor.SET_MAX_DATA_MODIFICATION_ID: - // it is checked independently if the value is the same as the last time - case ExpressionVisitor.NOT_FROM_RESOLVER: - case ExpressionVisitor.QUERY_COMPARABLE: - case ExpressionVisitor.GET_DEPENDENCIES: - case ExpressionVisitor.OPTIMIZABLE_MIN_MAX_COUNT_ALL: - case ExpressionVisitor.DETERMINISTIC: - case ExpressionVisitor.READONLY: - return true; - case ExpressionVisitor.INDEPENDENT: - return value != null; - default: - throw DbException.throwInternalError("type="+visitor.getType()); - } - } - - public int getCost() { - return 0; - } - - public Expression getNotIfPossible(Session session) { - return new Comparison(session, Comparison.EQUAL, this, ValueExpression.get(ValueBoolean.get(false))); - } - - public void setColumn(Column column) { - this.column = column; - } - - public int getIndex() { - return index; - } - -} diff --git a/tools/h2/src/main/org/h2/expression/ParameterInterface.java b/tools/h2/src/main/org/h2/expression/ParameterInterface.java deleted file mode 100755 index d83ff2e..0000000 --- a/tools/h2/src/main/org/h2/expression/ParameterInterface.java +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.expression; - -import org.h2.value.Value; - -/** - * The interface for client side (remote) and server side parameters. - */ -public interface ParameterInterface { - - /** - * Set the value of the parameter. - * - * @param value the new value - * @param closeOld if the old value (if one is set) should be closed - */ - void setValue(Value value, boolean closeOld); - - /** - * Get the value of the parameter if set. - * - * @return the value or null - */ - Value getParamValue(); - - /** - * Check if the value is set. - * - * @throws SQLException if not set. - */ - void checkSet(); - - /** - * Get the expected data type of the parameter if no value is set, or the - * data type of the value if one is set. - * - * @return the data type - */ - int getType(); - - /** - * Get the expected precision of this parameter. - * - * @return the expected precision - */ - long getPrecision(); - - /** - * Get the expected scale of this parameter. - * - * @return the expected scale - */ - int getScale(); - - /** - * Check if this column is nullable. - * - * @return Column.NULLABLE_* - */ - int getNullable(); - -} diff --git a/tools/h2/src/main/org/h2/expression/ParameterRemote.java b/tools/h2/src/main/org/h2/expression/ParameterRemote.java deleted file mode 100755 index 86cdc8e..0000000 --- a/tools/h2/src/main/org/h2/expression/ParameterRemote.java +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.expression; - -import java.io.IOException; -import java.sql.ResultSetMetaData; -import org.h2.constant.ErrorCode; -import org.h2.message.DbException; -import org.h2.value.Transfer; -import org.h2.value.Value; - -/** - * A client side (remote) parameter. - */ -public class ParameterRemote implements ParameterInterface { - - private Value value; - private int index; - private int dataType = Value.UNKNOWN; - private long precision; - private int scale; - private int nullable = ResultSetMetaData.columnNullableUnknown; - - public ParameterRemote(int index) { - this.index = index; - } - - public void setValue(Value newValue, boolean closeOld) { - if (closeOld && value != null) { - value.close(); - } - value = newValue; - } - - public Value getParamValue() { - return value; - } - - public void checkSet() { - if (value == null) { - throw DbException.get(ErrorCode.PARAMETER_NOT_SET_1, "#" + (index + 1)); - } - } - - public int getType() { - return value == null ? dataType : value.getType(); - } - - public long getPrecision() { - return value == null ? precision : value.getPrecision(); - } - - public int getScale() { - return value == null ? scale : value.getScale(); - } - - public int getNullable() { - return nullable; - } - - /** - * Write the parameter meta data from the transfer object. - * - * @param transfer the transfer object - */ - public void readMetaData(Transfer transfer) throws IOException { - dataType = transfer.readInt(); - precision = transfer.readLong(); - scale = transfer.readInt(); - nullable = transfer.readInt(); - } - - /** - * Write the parameter meta data to the transfer object. - * - * @param transfer the transfer object - * @param p the parameter - */ - public static void writeMetaData(Transfer transfer, ParameterInterface p) throws IOException { - transfer.writeInt(p.getType()); - transfer.writeLong(p.getPrecision()); - transfer.writeInt(p.getScale()); - transfer.writeInt(p.getNullable()); - } - -} diff --git a/tools/h2/src/main/org/h2/expression/Rownum.java b/tools/h2/src/main/org/h2/expression/Rownum.java deleted file mode 100755 index e5aa8d0..0000000 --- a/tools/h2/src/main/org/h2/expression/Rownum.java +++ /dev/null @@ -1,91 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.expression; - -import org.h2.command.Prepared; -import org.h2.engine.Session; -import org.h2.message.DbException; -import org.h2.table.ColumnResolver; -import org.h2.table.TableFilter; -import org.h2.value.Value; -import org.h2.value.ValueInt; - -/** - * Represents the ROWNUM function. - */ -public class Rownum extends Expression { - - private Prepared prepared; - - public Rownum(Prepared prepared) { - this.prepared = prepared; - } - - public Value getValue(Session session) { - return ValueInt.get(prepared.getCurrentRowNumber()); - } - - public int getType() { - return Value.INT; - } - - public void mapColumns(ColumnResolver resolver, int level) { - // nothing to do - } - - public Expression optimize(Session session) { - return this; - } - - public void setEvaluatable(TableFilter tableFilter, boolean b) { - // nothing to do - } - - public int getScale() { - return 0; - } - - public long getPrecision() { - return ValueInt.PRECISION; - } - - public int getDisplaySize() { - return ValueInt.DISPLAY_SIZE; - } - - public String getSQL() { - return "ROWNUM()"; - } - - public void updateAggregate(Session session) { - // nothing to do - } - - public boolean isEverything(ExpressionVisitor visitor) { - switch(visitor.getType()) { - case ExpressionVisitor.QUERY_COMPARABLE: - case ExpressionVisitor.OPTIMIZABLE_MIN_MAX_COUNT_ALL: - case ExpressionVisitor.DETERMINISTIC: - case ExpressionVisitor.INDEPENDENT: - return false; - case ExpressionVisitor.EVALUATABLE: - case ExpressionVisitor.READONLY: - case ExpressionVisitor.NOT_FROM_RESOLVER: - case ExpressionVisitor.GET_DEPENDENCIES: - case ExpressionVisitor.SET_MAX_DATA_MODIFICATION_ID: - // if everything else is the same, the rownum is the same - return true; - default: - throw DbException.throwInternalError("type="+visitor.getType()); - } - } - - public int getCost() { - return 0; - } - -} diff --git a/tools/h2/src/main/org/h2/expression/SequenceValue.java b/tools/h2/src/main/org/h2/expression/SequenceValue.java deleted file mode 100755 index 69e8ea6..0000000 --- a/tools/h2/src/main/org/h2/expression/SequenceValue.java +++ /dev/null @@ -1,97 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.expression; - -import org.h2.engine.Session; -import org.h2.message.DbException; -import org.h2.schema.Sequence; -import org.h2.table.ColumnResolver; -import org.h2.table.TableFilter; -import org.h2.value.Value; -import org.h2.value.ValueInt; -import org.h2.value.ValueLong; - -/** - * Wraps a sequence when used in a statement. - */ -public class SequenceValue extends Expression { - - private Sequence sequence; - - public SequenceValue(Sequence sequence) { - this.sequence = sequence; - } - - public Value getValue(Session session) { - long value = sequence.getNext(session); - session.setLastIdentity(ValueLong.get(value)); - return ValueLong.get(value); - } - - public int getType() { - return Value.LONG; - } - - public void mapColumns(ColumnResolver resolver, int level) { - // nothing to do - } - - public Expression optimize(Session session) { - return this; - } - - public void setEvaluatable(TableFilter tableFilter, boolean b) { - // nothing to do - } - - public int getScale() { - return 0; - } - - public long getPrecision() { - return ValueInt.PRECISION; - } - - public int getDisplaySize() { - return ValueInt.DISPLAY_SIZE; - } - - public String getSQL() { - return "(NEXT VALUE FOR " + sequence.getSQL() +")"; - } - - public void updateAggregate(Session session) { - // nothing to do - } - - public boolean isEverything(ExpressionVisitor visitor) { - switch(visitor.getType()) { - case ExpressionVisitor.EVALUATABLE: - case ExpressionVisitor.OPTIMIZABLE_MIN_MAX_COUNT_ALL: - case ExpressionVisitor.NOT_FROM_RESOLVER: - return true; - case ExpressionVisitor.DETERMINISTIC: - case ExpressionVisitor.READONLY: - case ExpressionVisitor.INDEPENDENT: - case ExpressionVisitor.QUERY_COMPARABLE: - return false; - case ExpressionVisitor.SET_MAX_DATA_MODIFICATION_ID: - visitor.addDataModificationId(sequence.getModificationId()); - return true; - case ExpressionVisitor.GET_DEPENDENCIES: - visitor.addDependency(sequence); - return true; - default: - throw DbException.throwInternalError("type="+visitor.getType()); - } - } - - public int getCost() { - return 1; - } - -} diff --git a/tools/h2/src/main/org/h2/expression/Subquery.java b/tools/h2/src/main/org/h2/expression/Subquery.java deleted file mode 100755 index 9c912da..0000000 --- a/tools/h2/src/main/org/h2/expression/Subquery.java +++ /dev/null @@ -1,111 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.expression; - -import org.h2.command.dml.Query; -import org.h2.constant.ErrorCode; -import org.h2.engine.Session; -import org.h2.message.DbException; -import org.h2.result.ResultInterface; -import org.h2.table.ColumnResolver; -import org.h2.table.TableFilter; -import org.h2.value.Value; -import org.h2.value.ValueArray; -import org.h2.value.ValueNull; - -/** - * A query returning a single value. - * Subqueries are used inside other statements. - */ -public class Subquery extends Expression { - - private Query query; - - public Subquery(Query query) { - this.query = query; - } - - public Value getValue(Session session) { - query.setSession(session); - ResultInterface result = query.query(2); - try { - int rowcount = result.getRowCount(); - if (rowcount > 1) { - throw DbException.get(ErrorCode.SCALAR_SUBQUERY_CONTAINS_MORE_THAN_ONE_ROW); - } - Value v; - if (rowcount <= 0) { - v = ValueNull.INSTANCE; - } else { - result.next(); - Value[] values = result.currentRow(); - if (result.getVisibleColumnCount() == 1) { - v = values[0]; - } else { - v = ValueArray.get(values); - } - } - return v; - } finally { - result.close(); - } - } - - public int getType() { - return getExpression().getType(); - } - - public void mapColumns(ColumnResolver resolver, int level) { - query.mapColumns(resolver, level + 1); - } - - public Expression optimize(Session session) { - query.prepare(); - return this; - } - - public void setEvaluatable(TableFilter tableFilter, boolean b) { - query.setEvaluatable(tableFilter, b); - } - - public int getScale() { - return getExpression().getScale(); - } - - public long getPrecision() { - return getExpression().getPrecision(); - } - - public int getDisplaySize() { - return getExpression().getDisplaySize(); - } - - public String getSQL() { - return "(" + query.getPlanSQL() + ")"; - } - - public void updateAggregate(Session session) { - query.updateAggregate(session); - } - - private Expression getExpression() { - return query.getExpressions().get(0); - } - - public boolean isEverything(ExpressionVisitor visitor) { - return query.isEverything(visitor); - } - - public Query getQuery() { - return query; - } - - public int getCost() { - return 10 + (int) (10 * query.getCost()); - } - -} diff --git a/tools/h2/src/main/org/h2/expression/TableFunction.java b/tools/h2/src/main/org/h2/expression/TableFunction.java deleted file mode 100755 index da95114..0000000 --- a/tools/h2/src/main/org/h2/expression/TableFunction.java +++ /dev/null @@ -1,151 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.expression; - -import java.util.ArrayList; -import org.h2.constant.ErrorCode; -import org.h2.engine.Database; -import org.h2.engine.Session; -import org.h2.message.DbException; -import org.h2.result.LocalResult; -import org.h2.result.ResultInterface; -import org.h2.table.Column; -import org.h2.tools.SimpleResultSet; -import org.h2.util.MathUtils; -import org.h2.util.StatementBuilder; -import org.h2.value.DataType; -import org.h2.value.Value; -import org.h2.value.ValueArray; -import org.h2.value.ValueNull; -import org.h2.value.ValueResultSet; - -/** - * Implementation of the functions TABLE(..) and TABLE_DISTINCT(..). - */ -public class TableFunction extends Function { - private final boolean distinct; - private final long rowCount; - private Column[] columnList; - - TableFunction(Database database, FunctionInfo info, long rowCount) { - super(database, info); - distinct = info.type == Function.TABLE_DISTINCT; - this.rowCount = rowCount; - } - - public Value getValue(Session session) { - return getTable(session, args, false, distinct); - } - - protected void checkParameterCount(int len) { - if (len < 1) { - throw DbException.get(ErrorCode.INVALID_PARAMETER_COUNT_2, getName(), ">0"); - } - } - - public String getSQL() { - StatementBuilder buff = new StatementBuilder(getName()); - buff.append('('); - int i = 0; - for (Expression e : args) { - buff.appendExceptFirst(", "); - buff.append(columnList[i++].getCreateSQL()).append('=').append(e.getSQL()); - } - return buff.append(')').toString(); - } - - - public String getName() { - return distinct ? "TABLE_DISTINCT" : "TABLE"; - } - - public ValueResultSet getValueForColumnList(Session session, Expression[] nullArgs) { - return getTable(session, args, true, false); - } - - public void setColumns(ArrayList columns) { - this.columnList = new Column[columns.size()]; - columns.toArray(columnList); - } - - private ValueResultSet getTable(Session session, Expression[] argList, boolean onlyColumnList, boolean distinctRows) { - int len = columnList.length; - Expression[] header = new Expression[len]; - Database db = session.getDatabase(); - for (int i = 0; i < len; i++) { - Column c = columnList[i]; - ExpressionColumn col = new ExpressionColumn(db, c); - header[i] = col; - } - LocalResult result = new LocalResult(session, header, len); - if (distinctRows) { - result.setDistinct(); - } - if (!onlyColumnList) { - Value[][] list = new Value[len][]; - int rows = 0; - for (int i = 0; i < len; i++) { - Value v = argList[i].getValue(session); - if (v == ValueNull.INSTANCE) { - list[i] = new Value[0]; - } else { - ValueArray array = (ValueArray) v.convertTo(Value.ARRAY); - Value[] l = array.getList(); - list[i] = l; - rows = Math.max(rows, l.length); - } - } - for (int row = 0; row < rows; row++) { - Value[] r = new Value[len]; - for (int j = 0; j < len; j++) { - Value[] l = list[j]; - Value v; - if (l.length <= row) { - v = ValueNull.INSTANCE; - } else { - Column c = columnList[j]; - v = l[row]; - v = c.convert(v); - v = v.convertPrecision(c.getPrecision()); - v = v.convertScale(true, c.getScale()); - } - r[j] = v; - } - result.addRow(r); - } - } - result.done(); - ValueResultSet vr = ValueResultSet.get(getSimpleResultSet(result, Integer.MAX_VALUE)); - return vr; - } - - private SimpleResultSet getSimpleResultSet(ResultInterface rs, int maxrows) { - int columnCount = rs.getVisibleColumnCount(); - SimpleResultSet simple = new SimpleResultSet(); - for (int i = 0; i < columnCount; i++) { - String name = rs.getColumnName(i); - int sqlType = DataType.convertTypeToSQLType(rs.getColumnType(i)); - int precision = MathUtils.convertLongToInt(rs.getColumnPrecision(i)); - int scale = rs.getColumnScale(i); - simple.addColumn(name, sqlType, precision, scale); - } - rs.reset(); - for (int i = 0; i < maxrows && rs.next(); i++) { - Object[] list = new Object[columnCount]; - for (int j = 0; j < columnCount; j++) { - list[j] = rs.currentRow()[j].getObject(); - } - simple.addRow(list); - } - return simple; - } - - public long getRowCount() { - return rowCount; - } - -} diff --git a/tools/h2/src/main/org/h2/expression/ValueExpression.java b/tools/h2/src/main/org/h2/expression/ValueExpression.java deleted file mode 100755 index 899cd91..0000000 --- a/tools/h2/src/main/org/h2/expression/ValueExpression.java +++ /dev/null @@ -1,156 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.expression; - -import org.h2.engine.Session; -import org.h2.index.IndexCondition; -import org.h2.message.DbException; -import org.h2.table.ColumnResolver; -import org.h2.table.TableFilter; -import org.h2.value.Value; -import org.h2.value.ValueBoolean; -import org.h2.value.ValueNull; - -/** - * An expression representing a constant value. - */ -public class ValueExpression extends Expression { - /** - * The expression represents ValueNull.INSTANCE. - */ - private static final Object NULL = new ValueExpression(ValueNull.INSTANCE); - - /** - * This special expression represents the default value. It is used for - * UPDATE statements of the form SET COLUMN = DEFAULT. The value is - * ValueNull.INSTANCE, but should never be accessed. - */ - private static final Object DEFAULT = new ValueExpression(ValueNull.INSTANCE); - - private final Value value; - - private ValueExpression(Value value) { - this.value = value; - } - - /** - * Get the NULL expression. - * - * @return the NULL expression - */ - public static ValueExpression getNull() { - return (ValueExpression) NULL; - } - - /** - * Get the DEFAULT expression. - * - * @return the DEFAULT expression - */ - public static ValueExpression getDefault() { - return (ValueExpression) DEFAULT; - } - - /** - * Create a new expression with the given value. - * - * @param value the value - * @return the expression - */ - public static ValueExpression get(Value value) { - if (value == ValueNull.INSTANCE) { - return getNull(); - } - return new ValueExpression(value); - } - - public Value getValue(Session session) { - return value; - } - - public int getType() { - return value.getType(); - } - - public void createIndexConditions(Session session, TableFilter filter) { - if (value.getType() == Value.BOOLEAN) { - boolean v = ((ValueBoolean) value).getBoolean().booleanValue(); - if (!v) { - filter.addIndexCondition(IndexCondition.get(Comparison.FALSE, null, this)); - } - } - } - - public Expression getNotIfPossible(Session session) { - return new Comparison(session, Comparison.EQUAL, this, ValueExpression.get(ValueBoolean.get(false))); - } - - public void mapColumns(ColumnResolver resolver, int level) { - // nothing to do - } - - public Expression optimize(Session session) { - return this; - } - - public boolean isConstant() { - return true; - } - - public boolean isValueSet() { - return true; - } - - public void setEvaluatable(TableFilter tableFilter, boolean b) { - // nothing to do - } - - public int getScale() { - return value.getScale(); - } - - public long getPrecision() { - return value.getPrecision(); - } - - public int getDisplaySize() { - return value.getDisplaySize(); - } - - public String getSQL() { - if (this == DEFAULT) { - return "DEFAULT"; - } - return value.getSQL(); - } - - public void updateAggregate(Session session) { - // nothing to do - } - - public boolean isEverything(ExpressionVisitor visitor) { - switch (visitor.getType()) { - case ExpressionVisitor.OPTIMIZABLE_MIN_MAX_COUNT_ALL: - case ExpressionVisitor.DETERMINISTIC: - case ExpressionVisitor.READONLY: - case ExpressionVisitor.INDEPENDENT: - case ExpressionVisitor.EVALUATABLE: - case ExpressionVisitor.SET_MAX_DATA_MODIFICATION_ID: - case ExpressionVisitor.NOT_FROM_RESOLVER: - case ExpressionVisitor.GET_DEPENDENCIES: - case ExpressionVisitor.QUERY_COMPARABLE: - return true; - default: - throw DbException.throwInternalError("type=" + visitor.getType()); - } - } - - public int getCost() { - return 0; - } - -} diff --git a/tools/h2/src/main/org/h2/expression/Variable.java b/tools/h2/src/main/org/h2/expression/Variable.java deleted file mode 100755 index 29bb4b8..0000000 --- a/tools/h2/src/main/org/h2/expression/Variable.java +++ /dev/null @@ -1,98 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.expression; - -import org.h2.command.Parser; -import org.h2.engine.Session; -import org.h2.message.DbException; -import org.h2.table.ColumnResolver; -import org.h2.table.TableFilter; -import org.h2.value.Value; - -/** - * A user-defined variable, for example: @ID. - */ -public class Variable extends Expression { - - private final String name; - private Value lastValue; - - public Variable(Session session, String name) { - this.name = name; - lastValue = session.getVariable(name); - } - - public int getCost() { - return 0; - } - - public int getDisplaySize() { - return lastValue.getDisplaySize(); - } - - public long getPrecision() { - return lastValue.getPrecision(); - } - - public String getSQL() { - return "@" + Parser.quoteIdentifier(name); - } - - public int getScale() { - return lastValue.getScale(); - } - - public int getType() { - return lastValue.getType(); - } - - public Value getValue(Session session) { - lastValue = session.getVariable(name); - return lastValue; - } - - public boolean isEverything(ExpressionVisitor visitor) { - switch(visitor.getType()) { - case ExpressionVisitor.EVALUATABLE: - // the value will be evaluated at execute time - case ExpressionVisitor.SET_MAX_DATA_MODIFICATION_ID: - // it is checked independently if the value is the same as the last time - case ExpressionVisitor.OPTIMIZABLE_MIN_MAX_COUNT_ALL: - case ExpressionVisitor.READONLY: - case ExpressionVisitor.INDEPENDENT: - case ExpressionVisitor.NOT_FROM_RESOLVER: - case ExpressionVisitor.QUERY_COMPARABLE: - case ExpressionVisitor.GET_DEPENDENCIES: - return true; - case ExpressionVisitor.DETERMINISTIC: - return false; - default: - throw DbException.throwInternalError("type="+visitor.getType()); - } - } - - public void mapColumns(ColumnResolver resolver, int level) { - // nothing to do - } - - public Expression optimize(Session session) { - return this; - } - - public void setEvaluatable(TableFilter tableFilter, boolean value) { - // nothing to do - } - - public void updateAggregate(Session session) { - // nothing to do - } - - public String getName() { - return name; - } - -} diff --git a/tools/h2/src/main/org/h2/expression/Wildcard.java b/tools/h2/src/main/org/h2/expression/Wildcard.java deleted file mode 100755 index fb037cf..0000000 --- a/tools/h2/src/main/org/h2/expression/Wildcard.java +++ /dev/null @@ -1,94 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.expression; - -import org.h2.constant.ErrorCode; -import org.h2.engine.Session; -import org.h2.message.DbException; -import org.h2.table.ColumnResolver; -import org.h2.table.TableFilter; -import org.h2.util.StringUtils; -import org.h2.value.Value; - -/** - * A wildcard expression as in SELECT * FROM TEST. - * This object is only used temporarily during the parsing phase, and later - * replaced by column expressions. - */ -public class Wildcard extends Expression { - private String schema; - private String table; - - public Wildcard(String schema, String table) { - this.schema = schema; - this.table = table; - } - - public boolean isWildcard() { - return true; - } - - public Value getValue(Session session) { - throw DbException.throwInternalError(); - } - - public int getType() { - throw DbException.throwInternalError(); - } - - public void mapColumns(ColumnResolver resolver, int level) { - throw DbException.get(ErrorCode.SYNTAX_ERROR_1, table); - } - - public Expression optimize(Session session) { - throw DbException.get(ErrorCode.SYNTAX_ERROR_1, table); - } - - public void setEvaluatable(TableFilter tableFilter, boolean b) { - DbException.throwInternalError(); - } - - public int getScale() { - throw DbException.throwInternalError(); - } - - public long getPrecision() { - throw DbException.throwInternalError(); - } - - public int getDisplaySize() { - throw DbException.throwInternalError(); - } - - public String getTableAlias() { - return table; - } - - public String getSchemaName() { - return schema; - } - - public String getSQL() { - if (table == null) { - return "*"; - } - return StringUtils.quoteIdentifier(table) + ".*"; - } - - public void updateAggregate(Session session) { - DbException.throwInternalError(); - } - - public boolean isEverything(ExpressionVisitor visitor) { - throw DbException.throwInternalError(); - } - - public int getCost() { - throw DbException.throwInternalError(); - } - -} diff --git a/tools/h2/src/main/org/h2/expression/package.html b/tools/h2/src/main/org/h2/expression/package.html deleted file mode 100755 index 2dc94ec..0000000 --- a/tools/h2/src/main/org/h2/expression/package.html +++ /dev/null @@ -1,15 +0,0 @@ - - - - -Javadoc package documentation -

- -Expressions include mathematical operations, conditions, simple values, and functions. - -

\ No newline at end of file diff --git a/tools/h2/src/main/org/h2/fulltext/FullText.java b/tools/h2/src/main/org/h2/fulltext/FullText.java deleted file mode 100755 index 2d36a5e..0000000 --- a/tools/h2/src/main/org/h2/fulltext/FullText.java +++ /dev/null @@ -1,1041 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.fulltext; - -import java.io.IOException; -import java.io.Reader; -import java.io.StreamTokenizer; -import java.sql.Clob; -import java.sql.Connection; -import java.sql.DatabaseMetaData; -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.sql.Statement; -import java.sql.Types; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Iterator; -import java.util.StringTokenizer; -import org.h2.api.Trigger; -import org.h2.command.Parser; -import org.h2.engine.Session; -import org.h2.expression.Comparison; -import org.h2.expression.ConditionAndOr; -import org.h2.expression.Expression; -import org.h2.expression.ExpressionColumn; -import org.h2.expression.ValueExpression; -import org.h2.jdbc.JdbcConnection; -import org.h2.message.DbException; -import org.h2.tools.SimpleResultSet; -import org.h2.util.Utils; -import org.h2.util.IOUtils; -import org.h2.util.JdbcUtils; -import org.h2.util.New; -import org.h2.util.StatementBuilder; -import org.h2.util.StringUtils; -import org.h2.value.DataType; - -/** - * This class implements the native full text search. - * Most methods can be called using SQL statements as well. - */ -public class FullText { - - /** - * A column name of the result set returned by the searchData method. - */ - protected static final String FIELD_SCHEMA = "SCHEMA"; - - /** - * A column name of the result set returned by the searchData method. - */ - protected static final String FIELD_TABLE = "TABLE"; - - /** - * A column name of the result set returned by the searchData method. - */ - protected static final String FIELD_COLUMNS = "COLUMNS"; - - /** - * A column name of the result set returned by the searchData method. - */ - protected static final String FIELD_KEYS = "KEYS"; - - /** - * The hit score. - */ - protected static final String FIELD_SCORE = "SCORE"; - - private static final String TRIGGER_PREFIX = "FT_"; - private static final String SCHEMA = "FT"; - private static final String SELECT_MAP_BY_WORD_ID = "SELECT ROWID FROM " + SCHEMA + ".MAP WHERE WORDID=?"; - private static final String SELECT_ROW_BY_ID = "SELECT KEY, INDEXID FROM " + SCHEMA + ".ROWS WHERE ID=?"; - - /** - * The column name of the result set returned by the search method. - */ - private static final String FIELD_QUERY = "QUERY"; - - /** - * Initializes full text search functionality for this database. This adds - * the following Java functions to the database: - *
    - *
  • FT_CREATE_INDEX(schemaNameString, tableNameString, - * columnListString)
  • - *
  • FT_SEARCH(queryString, limitInt, offsetInt): result set
  • - *
  • FT_REINDEX()
  • - *
  • FT_DROP_ALL()
  • - *
- * It also adds a schema FT to the database where bookkeeping information - * is stored. This function may be called from a Java application, or by - * using the SQL statements: - * - *
-     * CREATE ALIAS IF NOT EXISTS FT_INIT FOR
-     *      "org.h2.fulltext.FullText.init";
-     * CALL FT_INIT();
-     * 
- * - * @param conn the connection - */ - public static void init(Connection conn) throws SQLException { - Statement stat = conn.createStatement(); - stat.execute("CREATE SCHEMA IF NOT EXISTS " + SCHEMA); - stat.execute("CREATE TABLE IF NOT EXISTS " + SCHEMA - + ".INDEXES(ID INT AUTO_INCREMENT PRIMARY KEY, SCHEMA VARCHAR, TABLE VARCHAR, COLUMNS VARCHAR, UNIQUE(SCHEMA, TABLE))"); - stat.execute("CREATE TABLE IF NOT EXISTS " + SCHEMA - + ".WORDS(ID INT AUTO_INCREMENT PRIMARY KEY, NAME VARCHAR, UNIQUE(NAME))"); - stat.execute("CREATE TABLE IF NOT EXISTS " + SCHEMA - + ".ROWS(ID IDENTITY, HASH INT, INDEXID INT, KEY VARCHAR, UNIQUE(HASH, INDEXID, KEY))"); - stat.execute("CREATE TABLE IF NOT EXISTS " + SCHEMA - + ".MAP(ROWID INT, WORDID INT, PRIMARY KEY(WORDID, ROWID))"); - stat.execute("CREATE TABLE IF NOT EXISTS " + SCHEMA + ".IGNORELIST(LIST VARCHAR)"); - stat.execute("CREATE ALIAS IF NOT EXISTS FT_CREATE_INDEX FOR \"" + FullText.class.getName() + ".createIndex\""); - stat.execute("CREATE ALIAS IF NOT EXISTS FT_DROP_INDEX FOR \"" + FullText.class.getName() + ".dropIndex\""); - stat.execute("CREATE ALIAS IF NOT EXISTS FT_SEARCH FOR \"" + FullText.class.getName() + ".search\""); - stat.execute("CREATE ALIAS IF NOT EXISTS FT_SEARCH_DATA FOR \"" + FullText.class.getName() + ".searchData\""); - stat.execute("CREATE ALIAS IF NOT EXISTS FT_REINDEX FOR \"" + FullText.class.getName() + ".reindex\""); - stat.execute("CREATE ALIAS IF NOT EXISTS FT_DROP_ALL FOR \"" + FullText.class.getName() + ".dropAll\""); - FullTextSettings setting = FullTextSettings.getInstance(conn); - ResultSet rs = stat.executeQuery("SELECT * FROM " + SCHEMA + ".IGNORELIST"); - while (rs.next()) { - String commaSeparatedList = rs.getString(1); - setIgnoreList(setting, commaSeparatedList); - } - rs = stat.executeQuery("SELECT * FROM " + SCHEMA + ".WORDS"); - HashMap map = setting.getWordList(); - while (rs.next()) { - String word = rs.getString("NAME"); - int id = rs.getInt("ID"); - word = setting.convertWord(word); - if (word != null) { - map.put(word, id); - } - } - setting.setInitialized(true); - } - - /** - * Create a new full text index for a table and column list. Each table may - * only have one index at any time. - * - * @param conn the connection - * @param schema the schema name of the table (case sensitive) - * @param table the table name (case sensitive) - * @param columnList the column list (null for all columns) - */ - public static void createIndex(Connection conn, String schema, String table, String columnList) throws SQLException { - init(conn); - PreparedStatement prep = conn.prepareStatement("INSERT INTO " + SCHEMA - + ".INDEXES(SCHEMA, TABLE, COLUMNS) VALUES(?, ?, ?)"); - prep.setString(1, schema); - prep.setString(2, table); - prep.setString(3, columnList); - prep.execute(); - createTrigger(conn, schema, table); - indexExistingRows(conn, schema, table); - } - - /** - * Re-creates the full text index for this database. Calling this method is - * usually not needed, as the index is kept up-to-date automatically. - * - * @param conn the connection - */ - public static void reindex(Connection conn) throws SQLException { - init(conn); - removeAllTriggers(conn, TRIGGER_PREFIX); - FullTextSettings setting = FullTextSettings.getInstance(conn); - setting.getWordList().clear(); - Statement stat = conn.createStatement(); - stat.execute("TRUNCATE TABLE " + SCHEMA + ".WORDS"); - stat.execute("TRUNCATE TABLE " + SCHEMA + ".ROWS"); - stat.execute("TRUNCATE TABLE " + SCHEMA + ".MAP"); - ResultSet rs = stat.executeQuery("SELECT * FROM " + SCHEMA + ".INDEXES"); - while (rs.next()) { - String schema = rs.getString("SCHEMA"); - String table = rs.getString("TABLE"); - createTrigger(conn, schema, table); - indexExistingRows(conn, schema, table); - } - } - - /** - * Drop an existing full text index for a table. This method returns - * silently if no index for this table exists. - * - * @param conn the connection - * @param schema the schema name of the table (case sensitive) - * @param table the table name (case sensitive) - */ - public static void dropIndex(Connection conn, String schema, String table) throws SQLException { - init(conn); - PreparedStatement prep = conn.prepareStatement("SELECT ID FROM " + SCHEMA - + ".INDEXES WHERE SCHEMA=? AND TABLE=?"); - prep.setString(1, schema); - prep.setString(2, table); - ResultSet rs = prep.executeQuery(); - if (!rs.next()) { - return; - } - int indexId = rs.getInt(1); - prep = conn.prepareStatement("DELETE FROM " + SCHEMA - + ".INDEXES WHERE ID=?"); - prep.setInt(1, indexId); - prep.execute(); - createOrDropTrigger(conn, schema, table, false); - prep = conn.prepareStatement("DELETE FROM " + SCHEMA + - ".ROWS WHERE INDEXID=? AND ROWNUM<10000"); - while (true) { - prep.setInt(1, indexId); - int deleted = prep.executeUpdate(); - if (deleted == 0) { - break; - } - } - prep = conn.prepareStatement("DELETE FROM " + SCHEMA + ".MAP M " + - "WHERE NOT EXISTS (SELECT * FROM " + SCHEMA + ".ROWS R WHERE R.ID=M.ROWID) AND ROWID<10000"); - while (true) { - int deleted = prep.executeUpdate(); - if (deleted == 0) { - break; - } - } - } - - /** - * Drops all full text indexes from the database. - * - * @param conn the connection - */ - public static void dropAll(Connection conn) throws SQLException { - init(conn); - Statement stat = conn.createStatement(); - stat.execute("DROP SCHEMA IF EXISTS " + SCHEMA); - removeAllTriggers(conn, TRIGGER_PREFIX); - FullTextSettings setting = FullTextSettings.getInstance(conn); - setting.removeAllIndexes(); - setting.getIgnoreList().clear(); - setting.getWordList().clear(); - } - - /** - * Searches from the full text index for this database. - * The returned result set has the following column: - *
  • QUERY (varchar): the query to use to get the data. - * The query does not include 'SELECT * FROM '. Example: - * PUBLIC.TEST WHERE ID = 1 - *
  • SCORE (float) the relevance score. This value is always 1.0 - * for the native fulltext search. - *
- * - * @param conn the connection - * @param text the search query - * @param limit the maximum number of rows or 0 for no limit - * @param offset the offset or 0 for no offset - * @return the result set - */ - public static ResultSet search(Connection conn, String text, int limit, int offset) throws SQLException { - try { - return search(conn, text, limit, offset, false); - } catch (DbException e) { - throw DbException.toSQLException(e); - } - } - - /** - * Searches from the full text index for this database. The result contains - * the primary key data as an array. The returned result set has the - * following columns: - *
    - *
  • SCHEMA (varchar): the schema name. Example: PUBLIC
  • - *
  • TABLE (varchar): the table name. Example: TEST
  • - *
  • COLUMNS (array of varchar): comma separated list of quoted column - * names. The column names are quoted if necessary. Example: (ID)
  • - *
  • KEYS (array of values): comma separated list of values. Example: (1) - *
  • - *
  • SCORE (float) the relevance score. This value is always 1.0 - * for the native fulltext search. - *
  • - *
- * - * @param conn the connection - * @param text the search query - * @param limit the maximum number of rows or 0 for no limit - * @param offset the offset or 0 for no offset - * @return the result set - */ - public static ResultSet searchData(Connection conn, String text, int limit, int offset) throws SQLException { - try { - return search(conn, text, limit, offset, true); - } catch (DbException e) { - throw DbException.toSQLException(e); - } - } - - /** - * Change the ignore list. The ignore list is a comma separated list of - * common words that must not be indexed. The default ignore list is empty. - * If indexes already exist at the time this list is changed, reindex must - * be called. - * - * @param conn the connection - * @param commaSeparatedList the list - */ - public static void setIgnoreList(Connection conn, String commaSeparatedList) throws SQLException { - try { - init(conn); - FullTextSettings setting = FullTextSettings.getInstance(conn); - setIgnoreList(setting, commaSeparatedList); - Statement stat = conn.createStatement(); - stat.execute("TRUNCATE TABLE " + SCHEMA + ".IGNORELIST"); - PreparedStatement prep = conn.prepareStatement("INSERT INTO " + SCHEMA + ".IGNORELIST VALUES(?)"); - prep.setString(1, commaSeparatedList); - prep.execute(); - } catch (DbException e) { - throw DbException.toSQLException(e); - } - } - - /** - * INTERNAL. - * Convert the object to a string. - * - * @param data the object - * @param type the SQL type - * @return the string - */ - protected static String asString(Object data, int type) throws SQLException { - if (data == null) { - return "NULL"; - } - switch (type) { - case Types.BIT: - case DataType.TYPE_BOOLEAN: - case Types.INTEGER: - case Types.BIGINT: - case Types.DECIMAL: - case Types.DOUBLE: - case Types.FLOAT: - case Types.NUMERIC: - case Types.REAL: - case Types.SMALLINT: - case Types.TINYINT: - case Types.DATE: - case Types.TIME: - case Types.TIMESTAMP: - case Types.LONGVARCHAR: - case Types.CHAR: - case Types.VARCHAR: - return data.toString(); - case Types.CLOB: - try { - if (data instanceof Clob) { - data = ((Clob) data).getCharacterStream(); - } - return IOUtils.readStringAndClose((Reader) data, -1); - } catch (IOException e) { - throw DbException.toSQLException(e); - } - case Types.VARBINARY: - case Types.LONGVARBINARY: - case Types.BINARY: - case Types.JAVA_OBJECT: - case Types.OTHER: - case Types.BLOB: - case Types.STRUCT: - case Types.REF: - case Types.NULL: - case Types.ARRAY: - case DataType.TYPE_DATALINK: - case Types.DISTINCT: - throw throwException("Unsupported column data type: " + type); - default: - return ""; - } - } - - /** - * Create an empty search result and initialize the columns. - * - * @param data true if the result set should contain the primary key data as - * an array. - * @return the empty result set - */ - protected static SimpleResultSet createResultSet(boolean data) { - SimpleResultSet result = new SimpleResultSet(); - if (data) { - result.addColumn(FullText.FIELD_SCHEMA, Types.VARCHAR, 0, 0); - result.addColumn(FullText.FIELD_TABLE, Types.VARCHAR, 0, 0); - result.addColumn(FullText.FIELD_COLUMNS, Types.ARRAY, 0, 0); - result.addColumn(FullText.FIELD_KEYS, Types.ARRAY, 0, 0); - } else { - result.addColumn(FullText.FIELD_QUERY, Types.VARCHAR, 0, 0); - } - result.addColumn(FullText.FIELD_SCORE, Types.FLOAT, 0, 0); - return result; - } - - /** - * Parse a primary key condition into the primary key columns. - * - * @param conn the database connection - * @param key the primary key condition as a string - * @return an array containing the column name list and the data list - */ - protected static Object[][] parseKey(Connection conn, String key) { - ArrayList columns = New.arrayList(); - ArrayList data = New.arrayList(); - JdbcConnection c = (JdbcConnection) conn; - Session session = (Session) c.getSession(); - Parser p = new Parser(session); - Expression expr = p.parseExpression(key); - addColumnData(columns, data, expr); - Object[] col = new Object[columns.size()]; - columns.toArray(col); - Object[] dat = new Object[columns.size()]; - data.toArray(dat); - Object[][] columnData = { col, dat }; - return columnData; - } - - /** - * INTERNAL. - * Convert an object to a String as used in a SQL statement. - * - * @param data the object - * @param type the SQL type - * @return the SQL String - */ - protected static String quoteSQL(Object data, int type) throws SQLException { - if (data == null) { - return "NULL"; - } - switch (type) { - case Types.BIT: - case DataType.TYPE_BOOLEAN: - case Types.INTEGER: - case Types.BIGINT: - case Types.DECIMAL: - case Types.DOUBLE: - case Types.FLOAT: - case Types.NUMERIC: - case Types.REAL: - case Types.SMALLINT: - case Types.TINYINT: - return data.toString(); - case Types.DATE: - case Types.TIME: - case Types.TIMESTAMP: - case Types.LONGVARCHAR: - case Types.CHAR: - case Types.VARCHAR: - return quoteString(data.toString()); - case Types.VARBINARY: - case Types.LONGVARBINARY: - case Types.BINARY: - return "'" + Utils.convertBytesToString((byte[]) data) + "'"; - case Types.CLOB: - case Types.JAVA_OBJECT: - case Types.OTHER: - case Types.BLOB: - case Types.STRUCT: - case Types.REF: - case Types.NULL: - case Types.ARRAY: - case DataType.TYPE_DATALINK: - case Types.DISTINCT: - throw throwException("Unsupported key data type: " + type); - default: - return ""; - } - } - - /** - * Remove all triggers that start with the given prefix. - * - * @param conn the database connection - * @param prefix the prefix - */ - protected static void removeAllTriggers(Connection conn, String prefix) throws SQLException { - Statement stat = conn.createStatement(); - ResultSet rs = stat.executeQuery("SELECT * FROM INFORMATION_SCHEMA.TRIGGERS"); - Statement stat2 = conn.createStatement(); - while (rs.next()) { - String schema = rs.getString("TRIGGER_SCHEMA"); - String name = rs.getString("TRIGGER_NAME"); - if (name.startsWith(prefix)) { - name = StringUtils.quoteIdentifier(schema) + "." + StringUtils.quoteIdentifier(name); - stat2.execute("DROP TRIGGER " + name); - } - } - } - - /** - * Set the column indices of a set of keys. - * - * @param index the column indices (will be modified) - * @param keys the key list - * @param columns the column list - */ - protected static void setColumns(int[] index, ArrayList keys, ArrayList columns) throws SQLException { - for (int i = 0; i < keys.size(); i++) { - String key = keys.get(i); - int found = -1; - for (int j = 0; found == -1 && j < columns.size(); j++) { - String column = columns.get(j); - if (column.equals(key)) { - found = j; - } - } - if (found < 0) { - throw throwException("Column not found: " + key); - } - index[i] = found; - } - } - - /** - * Do the search. - * - * @param conn the database connection - * @param text the query - * @param limit the limit - * @param offset the offset - * @param data whether the raw data should be returned - * @return the result set - */ - protected static ResultSet search(Connection conn, String text, int limit, int offset, boolean data) throws SQLException { - SimpleResultSet result = createResultSet(data); - if (conn.getMetaData().getURL().startsWith("jdbc:columnlist:")) { - // this is just to query the result set columns - return result; - } - if (text == null || text.trim().length() == 0) { - return result; - } - FullTextSettings setting = FullTextSettings.getInstance(conn); - if (!setting.isInitialized()) { - init(conn); - } - HashSet words = New.hashSet(); - addWords(setting, words, text); - HashSet rIds = null, lastRowIds = null; - HashMap allWords = setting.getWordList(); - - PreparedStatement prepSelectMapByWordId = setting.prepare(conn, SELECT_MAP_BY_WORD_ID); - for (String word : words) { - lastRowIds = rIds; - rIds = New.hashSet(); - Integer wId = allWords.get(word); - if (wId == null) { - continue; - } - prepSelectMapByWordId.setInt(1, wId.intValue()); - ResultSet rs = prepSelectMapByWordId.executeQuery(); - while (rs.next()) { - Integer rId = rs.getInt(1); - if (lastRowIds == null || lastRowIds.contains(rId)) { - rIds.add(rId); - } - } - } - if (rIds == null || rIds.size() == 0) { - return result; - } - PreparedStatement prepSelectRowById = setting.prepare(conn, SELECT_ROW_BY_ID); - int rowCount = 0; - for (int rowId : rIds) { - prepSelectRowById.setInt(1, rowId); - ResultSet rs = prepSelectRowById.executeQuery(); - if (!rs.next()) { - continue; - } - if (offset > 0) { - offset--; - } else { - String key = rs.getString(1); - int indexId = rs.getInt(2); - IndexInfo index = setting.getIndexInfo(indexId); - if (data) { - Object[][] columnData = parseKey(conn, key); - result.addRow( - index.schema, - index.table, - columnData[0], - columnData[1], - 1.0); - } else { - String query = StringUtils.quoteIdentifier(index.schema) + - "." + StringUtils.quoteIdentifier(index.table) + - " WHERE " + key; - result.addRow(query, 1.0); - } - rowCount++; - if (limit > 0 && rowCount >= limit) { - break; - } - } - } - return result; - } - - private static void addColumnData(ArrayList columns, ArrayList data, Expression expr) { - if (expr instanceof ConditionAndOr) { - ConditionAndOr and = (ConditionAndOr) expr; - Expression left = and.getExpression(true); - Expression right = and.getExpression(false); - addColumnData(columns, data, left); - addColumnData(columns, data, right); - } else { - Comparison comp = (Comparison) expr; - ExpressionColumn ec = (ExpressionColumn) comp.getExpression(true); - ValueExpression ev = (ValueExpression) comp.getExpression(false); - String columnName = ec.getColumnName(); - columns.add(columnName); - if (ev == null) { - data.add(null); - } else { - data.add(ev.getValue(null).getString()); - } - } - } - - /** - * Add all words in the given text to the hash set. - * - * @param setting the fulltext settings - * @param set the hash set - * @param reader the reader - */ - protected static void addWords(FullTextSettings setting, HashSet set, Reader reader) { - StreamTokenizer tokenizer = new StreamTokenizer(reader); - tokenizer.resetSyntax(); - tokenizer.wordChars(' ' + 1, 255); - for (char ch : " \t\n\r\f+\"*%&/()=?'!,.;:-_#@|^~`{}[]".toCharArray()) { - tokenizer.whitespaceChars(ch, ch); - } - try { - while (true) { - int token = tokenizer.nextToken(); - if (token == StreamTokenizer.TT_EOF) { - break; - } else if (token == StreamTokenizer.TT_WORD) { - String word = tokenizer.sval; - word = setting.convertWord(word); - if (word != null) { - set.add(word); - } - } - } - } catch (IOException e) { - throw DbException.convertIOException(e, "Tokenizer error"); - } - } - - /** - * Add all words in the given text to the hash set. - * - * @param setting the fulltext settings - * @param set the hash set - * @param text the text - */ - protected static void addWords(FullTextSettings setting, HashSet set, String text) { - StringTokenizer tokenizer = new StringTokenizer(text, " \t\n\r\f+\"*%&/()=?'!,.;:-_#@|^~`{}[]"); - while (tokenizer.hasMoreTokens()) { - String word = tokenizer.nextToken(); - word = setting.convertWord(word); - if (word != null) { - set.add(word); - } - } - } - - /** - * Create the trigger. - * - * @param conn the database connection - * @param schema the schema name - * @param table the table name - */ - protected static void createTrigger(Connection conn, String schema, String table) throws SQLException { - createOrDropTrigger(conn, schema, table, true); - } - - private static void createOrDropTrigger(Connection conn, String schema, String table, boolean create) throws SQLException { - Statement stat = conn.createStatement(); - String trigger = StringUtils.quoteIdentifier(schema) + "." - + StringUtils.quoteIdentifier(TRIGGER_PREFIX + table); - stat.execute("DROP TRIGGER IF EXISTS " + trigger); - if (create) { - StringBuilder buff = new StringBuilder("CREATE TRIGGER IF NOT EXISTS "); - buff.append(trigger). - append(" AFTER INSERT, UPDATE, DELETE ON "). - append(StringUtils.quoteIdentifier(schema)). - append('.'). - append(StringUtils.quoteIdentifier(table)). - append(" FOR EACH ROW CALL \""). - append(FullText.FullTextTrigger.class.getName()). - append("\""); - stat.execute(buff.toString()); - } - } - - /** - * Add the existing data to the index. - * - * @param conn the database connection - * @param schema the schema name - * @param table the table name - */ - protected static void indexExistingRows(Connection conn, String schema, String table) throws SQLException { - FullText.FullTextTrigger existing = new FullText.FullTextTrigger(); - existing.init(conn, schema, null, table, false, Trigger.INSERT); - String sql = "SELECT * FROM " + StringUtils.quoteIdentifier(schema) + "." + StringUtils.quoteIdentifier(table); - ResultSet rs = conn.createStatement().executeQuery(sql); - int columnCount = rs.getMetaData().getColumnCount(); - while (rs.next()) { - Object[] row = new Object[columnCount]; - for (int i = 0; i < columnCount; i++) { - row[i] = rs.getObject(i + 1); - } - existing.fire(conn, null, row); - } - } - - private static String quoteString(String data) { - if (data.indexOf('\'') < 0) { - return "'" + data + "'"; - } - StringBuilder buff = new StringBuilder(data.length() + 2); - buff.append('\''); - for (int i = 0; i < data.length(); i++) { - char ch = data.charAt(i); - if (ch == '\'') { - buff.append(ch); - } - buff.append(ch); - } - buff.append('\''); - return buff.toString(); - } - - private static void setIgnoreList(FullTextSettings setting, String commaSeparatedList) { - String[] list = StringUtils.arraySplit(commaSeparatedList, ',', true); - HashSet set = setting.getIgnoreList(); - for (String word : list) { - String converted = setting.convertWord(word); - if (converted != null) { - set.add(word); - } - } - } - - /** - * Check if a the indexed columns of a row probably have changed. It may - * return true even if the change was minimal (for example from 0.0 to - * 0.00). - * - * @param oldRow the old row - * @param newRow the new row - * @param indexColumns the indexed columns - * @return true if the indexed columns don't match - */ - protected static boolean hasChanged(Object[] oldRow, Object[] newRow, int[] indexColumns) { - for (int c : indexColumns) { - Object o = oldRow[c], n = newRow[c]; - if (o == null) { - if (n != null) { - return true; - } - } else if (!o.equals(n)) { - return true; - } - } - return false; - } - - /** - * Trigger updates the index when a inserting, updating, or deleting a row. - */ - public static class FullTextTrigger implements Trigger { - - protected FullTextSettings setting; - protected IndexInfo index; - protected int[] columnTypes; - protected PreparedStatement prepInsertWord, prepInsertRow, prepInsertMap; - protected PreparedStatement prepDeleteRow, prepDeleteMap; - protected PreparedStatement prepSelectRow; - - /** - * INTERNAL - */ - public void init(Connection conn, String schemaName, String triggerName, - String tableName, boolean before, int type) throws SQLException { - setting = FullTextSettings.getInstance(conn); - if (!setting.isInitialized()) { - FullText.init(conn); - } - ArrayList keyList = New.arrayList(); - DatabaseMetaData meta = conn.getMetaData(); - ResultSet rs = meta.getColumns(null, - JdbcUtils.escapeMetaDataPattern(schemaName), - JdbcUtils.escapeMetaDataPattern(tableName), - null); - ArrayList columnList = New.arrayList(); - while (rs.next()) { - columnList.add(rs.getString("COLUMN_NAME")); - } - columnTypes = new int[columnList.size()]; - index = new IndexInfo(); - index.schema = schemaName; - index.table = tableName; - index.columns = new String[columnList.size()]; - columnList.toArray(index.columns); - rs = meta.getColumns(null, - JdbcUtils.escapeMetaDataPattern(schemaName), - JdbcUtils.escapeMetaDataPattern(tableName), - null); - for (int i = 0; rs.next(); i++) { - columnTypes[i] = rs.getInt("DATA_TYPE"); - } - if (keyList.size() == 0) { - rs = meta.getPrimaryKeys(null, - JdbcUtils.escapeMetaDataPattern(schemaName), - tableName); - while (rs.next()) { - keyList.add(rs.getString("COLUMN_NAME")); - } - } - if (keyList.size() == 0) { - throw throwException("No primary key for table " + tableName); - } - ArrayList indexList = New.arrayList(); - PreparedStatement prep = conn.prepareStatement( - "SELECT ID, COLUMNS FROM " + SCHEMA + ".INDEXES WHERE SCHEMA=? AND TABLE=?"); - prep.setString(1, schemaName); - prep.setString(2, tableName); - rs = prep.executeQuery(); - if (rs.next()) { - index.id = rs.getInt(1); - String columns = rs.getString(2); - if (columns != null) { - for (String s : StringUtils.arraySplit(columns, ',', true)) { - indexList.add(s); - } - } - } - if (indexList.size() == 0) { - indexList.addAll(columnList); - } - index.keys = new int[keyList.size()]; - setColumns(index.keys, keyList, columnList); - index.indexColumns = new int[indexList.size()]; - setColumns(index.indexColumns, indexList, columnList); - setting.addIndexInfo(index); - prepInsertWord = conn.prepareStatement( - "INSERT INTO " + SCHEMA + ".WORDS(NAME) VALUES(?)"); - prepInsertRow = conn.prepareStatement( - "INSERT INTO " + SCHEMA + ".ROWS(HASH, INDEXID, KEY) VALUES(?, ?, ?)"); - prepInsertMap = conn.prepareStatement( - "INSERT INTO " + SCHEMA + ".MAP(ROWID, WORDID) VALUES(?, ?)"); - prepDeleteRow = conn.prepareStatement( - "DELETE FROM " + SCHEMA + ".ROWS WHERE HASH=? AND INDEXID=? AND KEY=?"); - prepDeleteMap = conn.prepareStatement( - "DELETE FROM " + SCHEMA + ".MAP WHERE ROWID=? AND WORDID=?"); - prepSelectRow = conn.prepareStatement( - "SELECT ID FROM " + SCHEMA + ".ROWS WHERE HASH=? AND INDEXID=? AND KEY=?"); - } - - /** - * INTERNAL - */ - public void fire(Connection conn, Object[] oldRow, Object[] newRow) - throws SQLException { - if (oldRow != null) { - if (newRow != null) { - // update - if (hasChanged(oldRow, newRow, index.indexColumns)) { - delete(oldRow); - insert(newRow); - } - } else { - // delete - delete(oldRow); - } - } else if (newRow != null) { - // insert - insert(newRow); - } - } - - /** - * INTERNAL - */ - public void close() { - setting.removeIndexInfo(index); - } - - /** - * INTERNAL - */ - public void remove() { - setting.removeIndexInfo(index); - } - - /** - * Add a row to the index. - * - * @param row the row - */ - protected void insert(Object[] row) throws SQLException { - String key = getKey(row); - int hash = key.hashCode(); - prepInsertRow.setInt(1, hash); - prepInsertRow.setInt(2, index.id); - prepInsertRow.setString(3, key); - prepInsertRow.execute(); - ResultSet rs = prepInsertRow.getGeneratedKeys(); - rs.next(); - int rowId = rs.getInt(1); - prepInsertMap.setInt(1, rowId); - int[] wordIds = getWordIds(row); - for (int id : wordIds) { - prepInsertMap.setInt(2, id); - prepInsertMap.execute(); - } - } - - /** - * Delete a row from the index. - * - * @param row the row - */ - protected void delete(Object[] row) throws SQLException { - String key = getKey(row); - int hash = key.hashCode(); - prepSelectRow.setInt(1, hash); - prepSelectRow.setInt(2, index.id); - prepSelectRow.setString(3, key); - ResultSet rs = prepSelectRow.executeQuery(); - if (rs.next()) { - int rowId = rs.getInt(1); - prepDeleteMap.setInt(1, rowId); - int[] wordIds = getWordIds(row); - for (int id : wordIds) { - prepDeleteMap.setInt(2, id); - prepDeleteMap.executeUpdate(); - } - prepDeleteRow.setInt(1, hash); - prepDeleteRow.setInt(2, index.id); - prepDeleteRow.setString(3, key); - prepDeleteRow.executeUpdate(); - } - } - - private int[] getWordIds(Object[] row) throws SQLException { - HashSet words = New.hashSet(); - for (int i = 0; i < index.indexColumns.length; i++) { - int idx = index.indexColumns[i]; - int type = columnTypes[idx]; - Object data = row[idx]; - if (type == Types.CLOB && data != null) { - Reader reader; - if (data instanceof Reader) { - reader = (Reader) data; - } else { - reader = ((Clob) data).getCharacterStream(); - } - addWords(setting, words, reader); - } else { - String string = asString(data, type); - addWords(setting, words, string); - } - } - HashMap allWords = setting.getWordList(); - int[] wordIds = new int[words.size()]; - Iterator it = words.iterator(); - for (int i = 0; it.hasNext(); i++) { - String word = it.next(); - Integer wId = allWords.get(word); - int wordId; - if (wId == null) { - prepInsertWord.setString(1, word); - prepInsertWord.execute(); - ResultSet rs = prepInsertWord.getGeneratedKeys(); - rs.next(); - wordId = rs.getInt(1); - allWords.put(word, wordId); - } else { - wordId = wId.intValue(); - } - wordIds[i] = wordId; - } - Arrays.sort(wordIds); - return wordIds; - } - - private String getKey(Object[] row) throws SQLException { - StatementBuilder buff = new StatementBuilder(); - for (int columnIndex : index.keys) { - buff.appendExceptFirst(" AND "); - buff.append(StringUtils.quoteIdentifier(index.columns[columnIndex])); - Object o = row[columnIndex]; - if (o == null) { - buff.append(" IS NULL"); - } else { - buff.append('=').append(quoteSQL(o, columnTypes[columnIndex])); - } - } - return buff.toString(); - } - - } - - /** - * INTERNAL - * Close all fulltext settings, freeing up memory. - */ - public static void closeAll() { - FullTextSettings.closeAll(); - } - - /** - * Throw a SQLException with the given message. - * - * @param message the message - * @return never returns normally - * @throws SQLException the exception - */ - protected static SQLException throwException(String message) throws SQLException { - throw new SQLException(message, "FULLTEXT"); - } - -} diff --git a/tools/h2/src/main/org/h2/fulltext/FullTextLucene.java b/tools/h2/src/main/org/h2/fulltext/FullTextLucene.java deleted file mode 100755 index 4cdd659..0000000 --- a/tools/h2/src/main/org/h2/fulltext/FullTextLucene.java +++ /dev/null @@ -1,606 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.fulltext; - -//## Java 1.4 begin ## -import java.io.IOException; -import java.sql.Connection; -import java.sql.DatabaseMetaData; -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.sql.Statement; -import java.util.ArrayList; -import java.util.HashMap; - -import org.apache.lucene.analysis.Analyzer; -import org.apache.lucene.analysis.standard.StandardAnalyzer; -import org.apache.lucene.document.DateTools; -import org.apache.lucene.document.Document; -import org.apache.lucene.document.Field; -import org.apache.lucene.index.IndexModifier; -import org.apache.lucene.index.IndexReader; -import org.apache.lucene.index.Term; -import org.apache.lucene.queryParser.QueryParser; -import org.apache.lucene.search.Hits; -import org.apache.lucene.search.IndexSearcher; -import org.apache.lucene.search.Query; -import org.apache.lucene.search.Searcher; -import org.h2.api.Trigger; -import org.h2.command.Parser; -import org.h2.engine.Session; -import org.h2.expression.ExpressionColumn; -import org.h2.jdbc.JdbcConnection; -import org.h2.store.fs.FileSystem; -import org.h2.tools.SimpleResultSet; -import org.h2.util.JdbcUtils; -import org.h2.util.New; -import org.h2.util.StatementBuilder; -import org.h2.util.StringUtils; -//## Java 1.4 end ## - -/** - * This class implements the full text search based on Apache Lucene. - * Most methods can be called using SQL statements as well. - */ -public class FullTextLucene extends FullText { - - /** - * Whether the text content should be stored in the Lucene index. - */ - protected static final boolean STORE_DOCUMENT_TEXT_IN_INDEX = Boolean.getBoolean("h2.storeDocumentTextInIndex"); - - //## Java 1.4 begin ## - private static final HashMap INDEX_MODIFIERS = New.hashMap(); - private static final String TRIGGER_PREFIX = "FTL_"; - private static final String SCHEMA = "FTL"; - private static final String LUCENE_FIELD_DATA = "_DATA"; - private static final String LUCENE_FIELD_QUERY = "_QUERY"; - private static final String LUCENE_FIELD_MODIFIED = "_modified"; - private static final String LUCENE_FIELD_COLUMN_PREFIX = "_"; - //## Java 1.4 end ## - - /** - * Initializes full text search functionality for this database. This adds - * the following Java functions to the database: - *
    - *
  • FTL_CREATE_INDEX(schemaNameString, tableNameString, - * columnListString)
  • - *
  • FTL_SEARCH(queryString, limitInt, offsetInt): result set
  • - *
  • FTL_REINDEX()
  • - *
  • FTL_DROP_ALL()
  • - *
- * It also adds a schema FTL to the database where bookkeeping information - * is stored. This function may be called from a Java application, or by - * using the SQL statements: - * - *
-     * CREATE ALIAS IF NOT EXISTS FTL_INIT FOR
-     *      "org.h2.fulltext.FullTextLucene.init";
-     * CALL FTL_INIT();
-     * 
- * - * @param conn the connection - */ - //## Java 1.4 begin ## - public static void init(Connection conn) throws SQLException { - Statement stat = conn.createStatement(); - stat.execute("CREATE SCHEMA IF NOT EXISTS " + SCHEMA); - stat.execute("CREATE TABLE IF NOT EXISTS " + SCHEMA - + ".INDEXES(SCHEMA VARCHAR, TABLE VARCHAR, COLUMNS VARCHAR, PRIMARY KEY(SCHEMA, TABLE))"); - stat.execute("CREATE ALIAS IF NOT EXISTS FTL_CREATE_INDEX FOR \"" + FullTextLucene.class.getName() + ".createIndex\""); - stat.execute("CREATE ALIAS IF NOT EXISTS FTL_SEARCH FOR \"" + FullTextLucene.class.getName() + ".search\""); - stat.execute("CREATE ALIAS IF NOT EXISTS FTL_SEARCH_DATA FOR \"" + FullTextLucene.class.getName() + ".searchData\""); - stat.execute("CREATE ALIAS IF NOT EXISTS FTL_REINDEX FOR \"" + FullTextLucene.class.getName() + ".reindex\""); - stat.execute("CREATE ALIAS IF NOT EXISTS FTL_DROP_ALL FOR \"" + FullTextLucene.class.getName() + ".dropAll\""); - try { - getIndexModifier(conn); - } catch (SQLException e) { - throw convertException(e); - } - } - //## Java 1.4 end ## - - /** - * Create a new full text index for a table and column list. Each table may - * only have one index at any time. - * - * @param conn the connection - * @param schema the schema name of the table (case sensitive) - * @param table the table name (case sensitive) - * @param columnList the column list (null for all columns) - */ - //## Java 1.4 begin ## - public static void createIndex(Connection conn, String schema, String table, String columnList) throws SQLException { - init(conn); - PreparedStatement prep = conn.prepareStatement("INSERT INTO " + SCHEMA - + ".INDEXES(SCHEMA, TABLE, COLUMNS) VALUES(?, ?, ?)"); - prep.setString(1, schema); - prep.setString(2, table); - prep.setString(3, columnList); - prep.execute(); - createTrigger(conn, schema, table); - indexExistingRows(conn, schema, table); - } - //## Java 1.4 end ## - - /** - * Re-creates the full text index for this database. Calling this method is - * usually not needed, as the index is kept up-to-date automatically. - * - * @param conn the connection - */ - //## Java 1.4 begin ## - public static void reindex(Connection conn) throws SQLException { - init(conn); - removeAllTriggers(conn, TRIGGER_PREFIX); - removeIndexFiles(conn); - Statement stat = conn.createStatement(); - ResultSet rs = stat.executeQuery("SELECT * FROM "+SCHEMA+".INDEXES"); - while (rs.next()) { - String schema = rs.getString("SCHEMA"); - String table = rs.getString("TABLE"); - createTrigger(conn, schema, table); - indexExistingRows(conn, schema, table); - } - } - //## Java 1.4 end ## - - /** - * Drops all full text indexes from the database. - * - * @param conn the connection - */ - //## Java 1.4 begin ## - public static void dropAll(Connection conn) throws SQLException { - Statement stat = conn.createStatement(); - stat.execute("DROP SCHEMA IF EXISTS " + SCHEMA); - removeAllTriggers(conn, TRIGGER_PREFIX); - removeIndexFiles(conn); - } - //## Java 1.4 end ## - - /** - * Searches from the full text index for this database. - * The returned result set has the following column: - *
  • QUERY (varchar): the query to use to get the data. - * The query does not include 'SELECT * FROM '. Example: - * PUBLIC.TEST WHERE ID = 1 - *
  • SCORE (float) the relevance score as returned by Lucene. - *
- * - * @param conn the connection - * @param text the search query - * @param limit the maximum number of rows or 0 for no limit - * @param offset the offset or 0 for no offset - * @return the result set - */ - //## Java 1.4 begin ## - public static ResultSet search(Connection conn, String text, int limit, int offset) throws SQLException { - return search(conn, text, limit, offset, false); - } - //## Java 1.4 end ## - - /** - * Searches from the full text index for this database. The result contains - * the primary key data as an array. The returned result set has the - * following columns: - *
    - *
  • SCHEMA (varchar): the schema name. Example: PUBLIC
  • - *
  • TABLE (varchar): the table name. Example: TEST
  • - *
  • COLUMNS (array of varchar): comma separated list of quoted column - * names. The column names are quoted if necessary. Example: (ID)
  • - *
  • KEYS (array of values): comma separated list of values. Example: (1) - *
  • SCORE (float) the relevance score as returned by Lucene. - *
  • - *
- * - * @param conn the connection - * @param text the search query - * @param limit the maximum number of rows or 0 for no limit - * @param offset the offset or 0 for no offset - * @return the result set - */ - //## Java 1.4 begin ## - public static ResultSet searchData(Connection conn, String text, int limit, int offset) throws SQLException { - return search(conn, text, limit, offset, true); - } - - /** - * Convert an exception to a fulltext exception. - * - * @param e the original exception - * @return the converted SQL exception - */ - protected static SQLException convertException(Exception e) { - SQLException e2 = new SQLException("Error while indexing document", "FULLTEXT"); - e2.initCause(e); - return e2; - } - - /** - * Create the trigger. - * - * @param conn the database connection - * @param schema the schema name - * @param table the table name - */ - protected static void createTrigger(Connection conn, String schema, String table) throws SQLException { - Statement stat = conn.createStatement(); - String trigger = StringUtils.quoteIdentifier(schema) + "." + StringUtils.quoteIdentifier(TRIGGER_PREFIX + table); - stat.execute("DROP TRIGGER IF EXISTS " + trigger); - StringBuilder buff = new StringBuilder("CREATE TRIGGER IF NOT EXISTS "); - // unlike the native fulltext search, the trigger is also called on rollback - buff.append(trigger). - append(" AFTER INSERT, UPDATE, DELETE, ROLLBACK ON "). - append(StringUtils.quoteIdentifier(schema)). - append('.'). - append(StringUtils.quoteIdentifier(table)). - append(" FOR EACH ROW CALL \""). - append(FullTextLucene.FullTextTrigger.class.getName()). - append("\""); - stat.execute(buff.toString()); - } - - /** - * Get the index modifier for the given connection. - * - * @param conn the connection - * @return the index modifier - */ - protected static IndexModifier getIndexModifier(Connection conn) throws SQLException { - String path = getIndexPath(conn); - IndexModifier indexer; - synchronized (INDEX_MODIFIERS) { - indexer = INDEX_MODIFIERS.get(path); - if (indexer == null) { - try { - boolean recreate = !IndexReader.indexExists(path); - Analyzer analyzer = new StandardAnalyzer(); - indexer = new IndexModifier(path, analyzer, recreate); - } catch (IOException e) { - throw convertException(e); - } - INDEX_MODIFIERS.put(path, indexer); - } - } - return indexer; - } - - /** - * Get the path of the Lucene index for this database. - * - * @param conn the database connection - * @return the path - */ - protected static String getIndexPath(Connection conn) throws SQLException { - Statement stat = conn.createStatement(); - ResultSet rs = stat.executeQuery("CALL DATABASE_PATH()"); - rs.next(); - String path = rs.getString(1); - if (path == null) { - throw throwException("Fulltext search for in-memory databases is not supported."); - } - rs.close(); - return path; - } - - /** - * Add the existing data to the index. - * - * @param conn the database connection - * @param schema the schema name - * @param table the table name - */ - protected static void indexExistingRows(Connection conn, String schema, String table) throws SQLException { - FullTextLucene.FullTextTrigger existing = new FullTextLucene.FullTextTrigger(); - existing.init(conn, schema, null, table, false, Trigger.INSERT); - String sql = "SELECT * FROM " + StringUtils.quoteIdentifier(schema) + "." + StringUtils.quoteIdentifier(table); - ResultSet rs = conn.createStatement().executeQuery(sql); - int columnCount = rs.getMetaData().getColumnCount(); - while (rs.next()) { - Object[] row = new Object[columnCount]; - for (int i = 0; i < columnCount; i++) { - row[i] = rs.getObject(i + 1); - } - existing.fire(conn, null, row); - } - } - - private static void removeIndexFiles(Connection conn) throws SQLException { - String path = getIndexPath(conn); - IndexModifier index = INDEX_MODIFIERS.get(path); - if (index != null) { - removeIndexModifier(index, path); - } - FileSystem.getInstance(path).deleteRecursive(path, false); - } - - /** - * Close the index modifier and remove it from the index modifier set. - * - * @param indexModifier the index modifier - * @param indexPath the index path - */ - protected static void removeIndexModifier(IndexModifier indexModifier, String indexPath) throws SQLException { - synchronized (INDEX_MODIFIERS) { - try { - INDEX_MODIFIERS.remove(indexPath); - indexModifier.flush(); - indexModifier.close(); - } catch (Exception e) { - throw convertException(e); - } - } - } - - /** - * Do the search. - * - * @param conn the database connection - * @param text the query - * @param limit the limit - * @param offset the offset - * @param data whether the raw data should be returned - * @return the result set - */ - protected static ResultSet search(Connection conn, String text, int limit, int offset, boolean data) throws SQLException { - SimpleResultSet result = createResultSet(data); - if (conn.getMetaData().getURL().startsWith("jdbc:columnlist:")) { - // this is just to query the result set columns - return result; - } - if (text == null || text.trim().length() == 0) { - return result; - } - String path = getIndexPath(conn); - try { - IndexModifier indexer = getIndexModifier(conn); - indexer.flush(); - IndexReader reader = IndexReader.open(path); - Analyzer analyzer = new StandardAnalyzer(); - Searcher searcher = new IndexSearcher(reader); - QueryParser parser = new QueryParser(LUCENE_FIELD_DATA, analyzer); - Query query = parser.parse(text); - Hits hits = searcher.search(query); - int max = hits.length(); - if (limit == 0) { - limit = max; - } - for (int i = 0; i < limit && i + offset < max; i++) { - Document doc = hits.doc(i + offset); - float score = hits.score(i + offset); - String q = doc.get(LUCENE_FIELD_QUERY); - if (data) { - int idx = q.indexOf(" WHERE "); - JdbcConnection c = (JdbcConnection) conn; - Session session = (Session) c.getSession(); - Parser p = new Parser(session); - String tab = q.substring(0, idx); - ExpressionColumn expr = (ExpressionColumn) p.parseExpression(tab); - String schemaName = expr.getOriginalTableAliasName(); - String tableName = expr.getColumnName(); - q = q.substring(idx + " WHERE ".length()); - Object[][] columnData = parseKey(conn, q); - result.addRow( - schemaName, - tableName, - columnData[0], - columnData[1], - score); - } else { - result.addRow(q, score); - } - } - // TODO keep it open if possible - reader.close(); - } catch (Exception e) { - throw convertException(e); - } - return result; - } - //## Java 1.4 end ## - - /** - * Trigger updates the index when a inserting, updating, or deleting a row. - */ - public static class FullTextTrigger - //## Java 1.4 begin ## - implements Trigger - //## Java 1.4 end ## - { - - //## Java 1.4 begin ## - protected String schema; - protected String table; - protected int[] keys; - protected int[] indexColumns; - protected String[] columns; - protected int[] columnTypes; - protected String indexPath; - protected IndexModifier indexModifier; - //## Java 1.4 end ## - - /** - * INTERNAL - */ - //## Java 1.4 begin ## - public void init(Connection conn, String schemaName, String triggerName, - String tableName, boolean before, int type) throws SQLException { - this.schema = schemaName; - this.table = tableName; - this.indexPath = getIndexPath(conn); - this.indexModifier = getIndexModifier(conn); - ArrayList keyList = New.arrayList(); - DatabaseMetaData meta = conn.getMetaData(); - ResultSet rs = meta.getColumns(null, - JdbcUtils.escapeMetaDataPattern(schemaName), - JdbcUtils.escapeMetaDataPattern(tableName), - null); - ArrayList columnList = New.arrayList(); - while (rs.next()) { - columnList.add(rs.getString("COLUMN_NAME")); - } - columnTypes = new int[columnList.size()]; - columns = new String[columnList.size()]; - columnList.toArray(columns); - rs = meta.getColumns(null, - JdbcUtils.escapeMetaDataPattern(schemaName), - JdbcUtils.escapeMetaDataPattern(tableName), - null); - for (int i = 0; rs.next(); i++) { - columnTypes[i] = rs.getInt("DATA_TYPE"); - } - if (keyList.size() == 0) { - rs = meta.getPrimaryKeys(null, - JdbcUtils.escapeMetaDataPattern(schemaName), - tableName); - while (rs.next()) { - keyList.add(rs.getString("COLUMN_NAME")); - } - } - if (keyList.size() == 0) { - throw throwException("No primary key for table " + tableName); - } - ArrayList indexList = New.arrayList(); - PreparedStatement prep = conn.prepareStatement( - "SELECT COLUMNS FROM " + SCHEMA - + ".INDEXES WHERE SCHEMA=? AND TABLE=?"); - prep.setString(1, schemaName); - prep.setString(2, tableName); - rs = prep.executeQuery(); - if (rs.next()) { - String cols = rs.getString(1); - if (cols != null) { - for (String s : StringUtils.arraySplit(cols, ',', true)) { - indexList.add(s); - } - } - } - if (indexList.size() == 0) { - indexList.addAll(columnList); - } - keys = new int[keyList.size()]; - setColumns(keys, keyList, columnList); - indexColumns = new int[indexList.size()]; - setColumns(indexColumns, indexList, columnList); - } - //## Java 1.4 end ## - - /** - * INTERNAL - */ - //## Java 1.4 begin ## - public void fire(Connection conn, Object[] oldRow, Object[] newRow) - throws SQLException { - if (oldRow != null) { - if (newRow != null) { - // update - if (hasChanged(oldRow, newRow, indexColumns)) { - delete(oldRow); - insert(newRow); - } - } else { - // delete - delete(oldRow); - } - } else if (newRow != null) { - // insert - insert(newRow); - } - } - //## Java 1.4 end ## - - /** - * INTERNAL - */ - //## Java 1.4 begin ## - public void close() throws SQLException { - if (indexModifier != null) { - removeIndexModifier(indexModifier, indexPath); - indexModifier = null; - } - } - //## Java 1.4 end ## - - /** - * INTERNAL - */ - public void remove() { - // ignore - } - - /** - * Add a row to the index. - * - * @param row the row - */ - protected void insert(Object[] row) throws SQLException { - String query = getQuery(row); - Document doc = new Document(); - doc.add(new Field(LUCENE_FIELD_QUERY, query, Field.Store.YES, Field.Index.UN_TOKENIZED)); - long time = System.currentTimeMillis(); - doc.add(new Field(LUCENE_FIELD_MODIFIED, DateTools.timeToString(time, DateTools.Resolution.SECOND), Field.Store.YES, Field.Index.UN_TOKENIZED)); - StatementBuilder buff = new StatementBuilder(); - for (int index : indexColumns) { - String columnName = columns[index]; - String data = asString(row[index], columnTypes[index]); - // column names that start with _ must be escaped to avoid conflicts - // with internal field names (_DATA, _QUERY, _modified) - if (columnName.startsWith(LUCENE_FIELD_COLUMN_PREFIX)) { - columnName = LUCENE_FIELD_COLUMN_PREFIX + columnName; - } - doc.add(new Field(columnName, data, Field.Store.NO, Field.Index.TOKENIZED)); - buff.appendExceptFirst(" "); - buff.append(data); - } - Field.Store storeText = STORE_DOCUMENT_TEXT_IN_INDEX ? Field.Store.YES : Field.Store.NO; - doc.add(new Field(LUCENE_FIELD_DATA, buff.toString(), storeText, - Field.Index.TOKENIZED)); - try { - indexModifier.addDocument(doc); - } catch (IOException e) { - throw convertException(e); - } - } - - /** - * Delete a row from the index. - * - * @param row the row - */ - protected void delete(Object[] row) throws SQLException { - String query = getQuery(row); - try { - Term term = new Term(LUCENE_FIELD_QUERY, query); - indexModifier.deleteDocuments(term); - } catch (IOException e) { - throw convertException(e); - } - } - - private String getQuery(Object[] row) throws SQLException { - StatementBuilder buff = new StatementBuilder(); - if (schema != null) { - buff.append(StringUtils.quoteIdentifier(schema)).append('.'); - } - buff.append(StringUtils.quoteIdentifier(table)).append(" WHERE "); - for (int columnIndex : keys) { - buff.appendExceptFirst(" AND "); - buff.append(StringUtils.quoteIdentifier(columns[columnIndex])); - Object o = row[columnIndex]; - if (o == null) { - buff.append(" IS NULL"); - } else { - buff.append('=').append(FullText.quoteSQL(o, columnTypes[columnIndex])); - } - } - return buff.toString(); - } - } - -} diff --git a/tools/h2/src/main/org/h2/fulltext/FullTextSettings.java b/tools/h2/src/main/org/h2/fulltext/FullTextSettings.java deleted file mode 100755 index 575a1aa..0000000 --- a/tools/h2/src/main/org/h2/fulltext/FullTextSettings.java +++ /dev/null @@ -1,208 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.fulltext; - -import java.sql.Connection; -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.sql.Statement; -import java.util.HashMap; -import java.util.HashSet; -import org.h2.util.New; -import org.h2.util.SoftHashMap; - -/** - * The global settings of a full text search. - */ -public class FullTextSettings { - - /** - * The settings of open indexes. - */ - protected static final HashMap SETTINGS = New.hashMap(); - - /** - * Whether this instance has been initialized. - */ - protected boolean initialized; - - /** - * The set of words not to index (stop words). - */ - protected HashSet ignoreList = New.hashSet(); - - /** - * The set of words / terms. - */ - protected HashMap words = New.hashMap(); - - /** - * The set of indexes in this database. - */ - protected HashMap indexes = New.hashMap(); - - /** - * The prepared statement cache. - */ - protected SoftHashMap cache = new SoftHashMap(); - - /** - * Create a new instance. - */ - protected FullTextSettings() { - // don't allow construction - } - - /** - * Get the ignore list. - * - * @return the ignore list - */ - protected HashSet getIgnoreList() { - return ignoreList; - } - - /** - * Get the word list. - * - * @return the word list - */ - protected HashMap getWordList() { - return words; - } - - /** - * Get the index information for the given index id. - * - * @param indexId the index id - * @return the index info - */ - protected IndexInfo getIndexInfo(int indexId) { - return indexes.get(indexId); - } - - /** - * Add an index. - * - * @param index the index - */ - protected void addIndexInfo(IndexInfo index) { - indexes.put(index.id, index); - } - - /** - * Convert a word to uppercase. This method returns null if the word is in - * the ignore list. - * - * @param word the word to convert and check - * @return the uppercase version of the word or null - */ - protected String convertWord(String word) { - // TODO this is locale specific, document - word = word.toUpperCase(); - if (ignoreList.contains(word)) { - return null; - } - return word; - } - - /** - * Get or create the fulltext settings for this database. - * - * @param conn the connection - * @return the settings - */ - protected static FullTextSettings getInstance(Connection conn) throws SQLException { - String path = getIndexPath(conn); - FullTextSettings setting = SETTINGS.get(path); - if (setting == null) { - setting = new FullTextSettings(); - SETTINGS.put(path, setting); - } - return setting; - } - - /** - * Get the file system path. - * - * @param conn the connection - * @return the file system path - */ - protected static String getIndexPath(Connection conn) throws SQLException { - Statement stat = conn.createStatement(); - ResultSet rs = stat.executeQuery("CALL IFNULL(DATABASE_PATH(), 'MEM:' || DATABASE())"); - rs.next(); - String path = rs.getString(1); - if ("MEM:UNNAMED".equals(path)) { - throw FullText.throwException("Fulltext search for private (unnamed) in-memory databases is not supported."); - } - rs.close(); - return path; - } - - /** - * Prepare a statement. The statement is cached in a soft reference cache. - * - * @param conn the connection - * @param sql the statement - * @return the prepared statement - */ - protected synchronized PreparedStatement prepare(Connection conn, String sql) throws SQLException { - PreparedStatement prep = cache.get(sql); - if (prep != null && prep.getConnection().isClosed()) { - prep = null; - } - if (prep == null) { - prep = conn.prepareStatement(sql); - cache.put(sql, prep); - } - return prep; - } - - /** - * Remove all indexes from the settings. - */ - protected void removeAllIndexes() { - indexes.clear(); - } - - /** - * Remove an index from the settings. - * - * @param index the index to remove - */ - protected void removeIndexInfo(IndexInfo index) { - indexes.remove(index.id); - } - - /** - * Set the initialized flag. - * - * @param b the new value - */ - protected void setInitialized(boolean b) { - this.initialized = b; - } - - /** - * Get the initialized flag. - * - * @return whether this instance is initialized - */ - protected boolean isInitialized() { - return initialized; - } - - /** - * Close all fulltext settings, freeing up memory. - */ - protected static void closeAll() { - SETTINGS.clear(); - } - -} diff --git a/tools/h2/src/main/org/h2/fulltext/IndexInfo.java b/tools/h2/src/main/org/h2/fulltext/IndexInfo.java deleted file mode 100755 index 16f604a..0000000 --- a/tools/h2/src/main/org/h2/fulltext/IndexInfo.java +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.fulltext; - -/** - * The settings of one full text search index. - */ -public class IndexInfo { - - /** - * The index id. - */ - protected int id; - - /** - * The schema name. - */ - protected String schema; - - /** - * The table name. - */ - protected String table; - - /** - * The column indexes of the key columns. - */ - protected int[] keys; - - /** - * The column indexes of the index columns. - */ - protected int[] indexColumns; - - /** - * The column names. - */ - protected String[] columns; -} diff --git a/tools/h2/src/main/org/h2/fulltext/package.html b/tools/h2/src/main/org/h2/fulltext/package.html deleted file mode 100755 index 8f8bb2b..0000000 --- a/tools/h2/src/main/org/h2/fulltext/package.html +++ /dev/null @@ -1,15 +0,0 @@ - - - - -Javadoc package documentation -

- -The native full text search implementation, and the wrapper for the the Lucene full text search implementation. - -

\ No newline at end of file diff --git a/tools/h2/src/main/org/h2/index/BaseIndex.java b/tools/h2/src/main/org/h2/index/BaseIndex.java deleted file mode 100755 index 0adf3e5..0000000 --- a/tools/h2/src/main/org/h2/index/BaseIndex.java +++ /dev/null @@ -1,378 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.index; - -import org.h2.constant.ErrorCode; -import org.h2.engine.Constants; -import org.h2.engine.DbObject; -import org.h2.engine.Mode; -import org.h2.engine.Session; -import org.h2.message.DbException; -import org.h2.message.Trace; -import org.h2.result.Row; -import org.h2.result.SearchRow; -import org.h2.result.SortOrder; -import org.h2.schema.SchemaObjectBase; -import org.h2.table.Column; -import org.h2.table.IndexColumn; -import org.h2.table.Table; -import org.h2.util.MathUtils; -import org.h2.util.StatementBuilder; -import org.h2.util.StringUtils; -import org.h2.value.Value; -import org.h2.value.ValueNull; - -/** - * Most index implementations extend the base index. - */ -public abstract class BaseIndex extends SchemaObjectBase implements Index { - - protected IndexColumn[] indexColumns; - protected Column[] columns; - protected int[] columnIds; - protected Table table; - protected IndexType indexType; - protected boolean isMultiVersion; - - /** - * Initialize the base index. - * - * @param newTable the table - * @param id the object id - * @param name the index name - * @param newIndexColumns the columns that are indexed or null if this is - * not yet known - * @param newIndexType the index type - */ - protected void initBaseIndex(Table newTable, int id, String name, IndexColumn[] newIndexColumns, IndexType newIndexType) { - initSchemaObjectBase(newTable.getSchema(), id, name, Trace.INDEX); - this.indexType = newIndexType; - this.table = newTable; - if (newIndexColumns != null) { - this.indexColumns = newIndexColumns; - columns = new Column[newIndexColumns.length]; - columnIds = new int[columns.length]; - for (int i = 0; i < columns.length; i++) { - Column col = newIndexColumns[i].column; - columns[i] = col; - columnIds[i] = col.getColumnId(); - } - } - } - - public int getRootPageId() { - return 0; - } - - /** - * Close this index. - * - * @param session the session - */ - public abstract void close(Session session); - - /** - * Add a row to this index. - * - * @param session the session - * @param row the row to add - */ - public abstract void add(Session session, Row row); - - /** - * Remove a row from the index. - * - * @param session the session - * @param row the row - */ - public abstract void remove(Session session, Row row); - - /** - * Create a cursor to iterate over a number of rows. - * - * @param session the session - * @param first the first row to return (null if no limit) - * @param last the last row to return (null if no limit) - * @return the cursor to iterate over the results - */ - public abstract Cursor find(Session session, SearchRow first, SearchRow last); - - /** - * Calculate the cost to find rows. - * - * @param session the session - * @param masks the condition mask - * @return the cost - */ - public abstract double getCost(Session session, int[] masks); - - /** - * Remove the index. - * - * @param session the session - */ - public abstract void remove(Session session); - - /** - * Truncate the index. - * - * @param session the session - */ - public abstract void truncate(Session session); - - /** - * Check if this index can quickly find the first or last value. - * - * @return true if it can - */ - public abstract boolean canGetFirstOrLast(); - - /** - * Find the first (or last) value of this index. The cursor returned is - * positioned on the correct row, or on null if no row has been found. - * - * @param session the session - * @param first true for the first value, false for the last - * @return a cursor (never null) - */ - public abstract Cursor findFirstOrLast(Session session, boolean first); - - /** - * Check if this index needs to be re-built. - * - * @return true if it must be re-built. - */ - public abstract boolean needRebuild(); - - public String getDropSQL() { - return null; - } - - public DbException getDuplicateKeyException() { - String sql = getName() + " ON " + table.getSQL() + "(" + getColumnListSQL() + ")"; - return DbException.get(ErrorCode.DUPLICATE_KEY_1, sql); - } - - public String getPlanSQL() { - return getSQL(); - } - - public void removeChildrenAndResources(Session session) { - table.removeIndex(this); - remove(session); - database.removeMeta(session, getId()); - } - - public boolean canFindNext() { - return false; - } - - /** - * Find a row or a list of rows that is larger and create a cursor to - * iterate over the result. The base implementation doesn't support this feature. - * - * @param session the session - * @param higherThan the lower limit (excluding) - * @param last the last row, or null for no limit - * @return the cursor - * @throws SQLException - */ - public Cursor findNext(Session session, SearchRow higherThan, SearchRow last) { - throw DbException.throwInternalError(); - } - - public int getLookupCost(long rowCount) { - return 2; - } - - /** - * Calculate the cost for the given mask as if this index was a typical - * b-tree range index. - * - * @param masks the search mask - * @param rowCount the number of rows in the index - * @return the calculated cost - */ - public long getCostRangeIndex(int[] masks, long rowCount) { - rowCount += Constants.COST_ROW_OFFSET; - long cost = rowCount; - long rows = rowCount; - int totalSelectivity = 0; - for (int i = 0; masks != null && i < columns.length; i++) { - Column column = columns[i]; - int index = column.getColumnId(); - int mask = masks[index]; - if ((mask & IndexCondition.EQUALITY) == IndexCondition.EQUALITY) { - if (i == columns.length - 1 && getIndexType().isUnique()) { - cost = getLookupCost(rowCount) + 1; - break; - } - totalSelectivity = 100 - ((100 - totalSelectivity) * (100 - column.getSelectivity()) / 100); - long distinctRows = rowCount * totalSelectivity / 100; - if (distinctRows <= 0) { - distinctRows = 1; - } - rows = Math.max(rowCount / distinctRows, 1); - cost = getLookupCost(rowCount) + rows; - } else if ((mask & IndexCondition.RANGE) == IndexCondition.RANGE) { - cost = getLookupCost(rowCount) + rows / 4; - break; - } else if ((mask & IndexCondition.START) == IndexCondition.START) { - cost = getLookupCost(rowCount) + rows / 3; - break; - } else if ((mask & IndexCondition.END) == IndexCondition.END) { - cost = rows / 3; - break; - } else { - break; - } - } - return cost; - } - - public int compareRows(SearchRow rowData, SearchRow compare) { - for (int i = 0; i < indexColumns.length; i++) { - int index = columnIds[i]; - Value v = compare.getValue(index); - if (v == null) { - // can't compare further - return 0; - } - int c = compareValues(rowData.getValue(index), v, indexColumns[i].sortType); - if (c != 0) { - return c; - } - } - return 0; - } - - public boolean containsNullAndAllowMultipleNull(SearchRow newRow) { - Mode mode = database.getMode(); - if (mode.uniqueIndexSingleNull) { - return false; - } else if (mode.uniqueIndexSingleNullExceptAllColumnsAreNull) { - for (int index : columnIds) { - Value v = newRow.getValue(index); - if (v != ValueNull.INSTANCE) { - return false; - } - } - return true; - } - for (int index : columnIds) { - Value v = newRow.getValue(index); - if (v == ValueNull.INSTANCE) { - return true; - } - } - return false; - } - - public int compareKeys(SearchRow rowData, SearchRow compare) { - long k1 = rowData.getKey(); - long k2 = compare.getKey(); - if (k1 == k2) { - if (isMultiVersion) { - int v1 = rowData.getVersion(); - int v2 = compare.getVersion(); - return MathUtils.compareInt(v2, v1); - } - return 0; - } - return k1 > k2 ? 1 : -1; - } - - private int compareValues(Value a, Value b, int sortType) { - boolean aNull = a == null, bNull = b == null; - if (aNull || bNull) { - if (aNull == bNull) { - return 0; - } - return SortOrder.compareNull(aNull, bNull, sortType); - } - int comp = table.compareTypeSave(a, b); - if ((sortType & SortOrder.DESCENDING) != 0) { - comp = -comp; - } - return comp; - } - - public int getColumnIndex(Column col) { - for (int i = 0; i < columns.length; i++) { - if (columns[i] == col) { - return i; - } - } - return -1; - } - - public String getColumnListSQL() { - StatementBuilder buff = new StatementBuilder(); - for (IndexColumn c : indexColumns) { - buff.appendExceptFirst(", "); - buff.append(c.getSQL()); - } - return buff.toString(); - } - - public String getCreateSQLForCopy(Table targetTable, String quotedName) { - StringBuilder buff = new StringBuilder("CREATE "); - buff.append(indexType.getSQL()); - buff.append(' '); - if (table.isHidden()) { - buff.append("IF NOT EXISTS "); - } - buff.append(quotedName); - buff.append(" ON ").append(targetTable.getSQL()); - if (comment != null) { - buff.append(" COMMENT ").append(StringUtils.quoteStringSQL(comment)); - } - buff.append('(').append(getColumnListSQL()).append(')'); - return buff.toString(); - } - - public String getCreateSQL() { - return getCreateSQLForCopy(table, getSQL()); - } - - public IndexColumn[] getIndexColumns() { - return indexColumns; - } - - public Column[] getColumns() { - return columns; - } - - public IndexType getIndexType() { - return indexType; - } - - public int getType() { - return DbObject.INDEX; - } - - public Table getTable() { - return table; - } - - public void commit(int operation, Row row) { - // nothing to do - } - - void setMultiVersion(boolean multiVersion) { - this.isMultiVersion = multiVersion; - } - - public Row getRow(Session session, long key) { - throw DbException.getUnsupportedException(toString()); - } - - public boolean isHidden() { - return table.isHidden(); - } - -} diff --git a/tools/h2/src/main/org/h2/index/Cursor.java b/tools/h2/src/main/org/h2/index/Cursor.java deleted file mode 100755 index 91f1789..0000000 --- a/tools/h2/src/main/org/h2/index/Cursor.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.index; - -import org.h2.result.Row; -import org.h2.result.SearchRow; - -/** - * A cursor is a helper object to iterate through an index. - * For indexes are sorted (such as the b tree index), it can iterate - * to the very end of the index. For other indexes that don't support - * that (such as a hash index), only one row is returned. - * The cursor is initially positioned before the first row, that means - * next() must be called before accessing data. - * - */ -public interface Cursor { - - /** - * Get the complete current row. - * All column are available. - * - * @return the complete row - */ - Row get(); - - /** - * Get the current row. - * Only the data for indexed columns is available in this row. - * - * @return the search row - */ - SearchRow getSearchRow(); - - /** - * Skip to the next row if one is available. - * - * @return true if another row is available - */ - boolean next(); - - /** - * Skip to the previous row if one is available. - * No filtering is made here. - * - * @return true if another row is available - */ - boolean previous(); - -} diff --git a/tools/h2/src/main/org/h2/index/FunctionCursor.java b/tools/h2/src/main/org/h2/index/FunctionCursor.java deleted file mode 100755 index b73c927..0000000 --- a/tools/h2/src/main/org/h2/index/FunctionCursor.java +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.index; - -import org.h2.message.DbException; -import org.h2.result.ResultInterface; -import org.h2.result.Row; -import org.h2.result.SearchRow; -import org.h2.value.Value; - -/** - * A cursor for a function that returns a result set. - */ -public class FunctionCursor implements Cursor { - - private ResultInterface result; - private Value[] values; - private Row row; - - FunctionCursor(ResultInterface result) { - this.result = result; - } - - public Row get() { - if (values == null) { - return null; - } - if (row == null) { - row = new Row(values, 1); - } - return row; - } - - public SearchRow getSearchRow() { - return get(); - } - - public boolean next() { - row = null; - if (result.next()) { - values = result.currentRow(); - } else { - values = null; - } - return values != null; - } - - public boolean previous() { - throw DbException.throwInternalError(); - } - -} diff --git a/tools/h2/src/main/org/h2/index/FunctionIndex.java b/tools/h2/src/main/org/h2/index/FunctionIndex.java deleted file mode 100755 index a86bb20..0000000 --- a/tools/h2/src/main/org/h2/index/FunctionIndex.java +++ /dev/null @@ -1,96 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.index; - -import org.h2.constant.SysProperties; -import org.h2.engine.Session; -import org.h2.message.DbException; -import org.h2.result.ResultInterface; -import org.h2.result.Row; -import org.h2.result.SearchRow; -import org.h2.table.FunctionTable; -import org.h2.table.IndexColumn; - -/** - * An index for a function that returns a result set. This index can only scan - * through all rows, search is not supported. - */ -public class FunctionIndex extends BaseIndex { - - private FunctionTable functionTable; - private ResultInterface result; - - public FunctionIndex(FunctionTable functionTable, IndexColumn[] columns) { - initBaseIndex(functionTable, 0, null, columns, IndexType.createNonUnique(true)); - this.functionTable = functionTable; - } - - public void close(Session session) { - // nothing to do - } - - public void add(Session session, Row row) { - throw DbException.getUnsupportedException("ALIAS"); - } - - public void remove(Session session, Row row) { - throw DbException.getUnsupportedException("ALIAS"); - } - - public Cursor find(Session session, SearchRow first, SearchRow last) { - // TODO sometimes result.reset() would be enough (but not when - // parameters are used) - result = functionTable.getResult(session); - return new FunctionCursor(result); - } - - public double getCost(Session session, int[] masks) { - if (masks != null) { - throw DbException.getUnsupportedException("ALIAS"); - } - long expectedRows; - if (functionTable.canGetRowCount()) { - expectedRows = functionTable.getRowCountApproximation(); - } else { - expectedRows = SysProperties.ESTIMATED_FUNCTION_TABLE_ROWS; - } - return expectedRows * 10; - } - - public void remove(Session session) { - throw DbException.getUnsupportedException("ALIAS"); - } - - public void truncate(Session session) { - throw DbException.getUnsupportedException("ALIAS"); - } - - public boolean needRebuild() { - return false; - } - - public void checkRename() { - throw DbException.getUnsupportedException("ALIAS"); - } - - public boolean canGetFirstOrLast() { - return false; - } - - public Cursor findFirstOrLast(Session session, boolean first) { - throw DbException.getUnsupportedException("ALIAS"); - } - - public long getRowCount(Session session) { - return functionTable.getRowCount(session); - } - - public long getRowCountApproximation() { - return functionTable.getRowCountApproximation(); - } - -} diff --git a/tools/h2/src/main/org/h2/index/HashIndex.java b/tools/h2/src/main/org/h2/index/HashIndex.java deleted file mode 100755 index a738b5d..0000000 --- a/tools/h2/src/main/org/h2/index/HashIndex.java +++ /dev/null @@ -1,119 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.index; - -import org.h2.engine.Session; -import org.h2.message.DbException; -import org.h2.result.Row; -import org.h2.result.SearchRow; -import org.h2.table.Column; -import org.h2.table.IndexColumn; -import org.h2.table.RegularTable; -import org.h2.util.ValueHashMap; -import org.h2.value.Value; - -/** - * An unique index based on an in-memory hash map. - */ -public class HashIndex extends BaseIndex { - - /** - * The index of the indexed column. - */ - protected final int indexColumn; - - private final RegularTable tableData; - private ValueHashMap rows; - - public HashIndex(RegularTable table, int id, String indexName, IndexColumn[] columns, IndexType indexType) { - initBaseIndex(table, id, indexName, columns, indexType); - this.indexColumn = columns[0].column.getColumnId(); - this.tableData = table; - reset(); - } - - private void reset() { - rows = ValueHashMap.newInstance(); - } - - public void truncate(Session session) { - reset(); - } - - public void add(Session session, Row row) { - Value key = row.getValue(indexColumn); - Object old = rows.get(key); - if (old != null) { - // TODO index duplicate key for hash indexes: is this allowed? - throw getDuplicateKeyException(); - } - rows.put(key, row.getKey()); - } - - public void remove(Session session, Row row) { - rows.remove(row.getValue(indexColumn)); - } - - public Cursor find(Session session, SearchRow first, SearchRow last) { - if (first == null || last == null) { - // TODO hash index: should additionally check if values are the same - throw DbException.throwInternalError(); - } - Row result; - Long pos = rows.get(first.getValue(indexColumn)); - if (pos == null) { - result = null; - } else { - result = tableData.getRow(session, pos.intValue()); - } - return new SingleRowCursor(result); - } - - public long getRowCount(Session session) { - return getRowCountApproximation(); - } - - public long getRowCountApproximation() { - return rows.size(); - } - - public void close(Session session) { - // nothing to do - } - - public void remove(Session session) { - // nothing to do - } - - public double getCost(Session session, int[] masks) { - for (Column column : columns) { - int index = column.getColumnId(); - int mask = masks[index]; - if ((mask & IndexCondition.EQUALITY) != IndexCondition.EQUALITY) { - return Long.MAX_VALUE; - } - } - return 2; - } - - public void checkRename() { - // ok - } - - public boolean needRebuild() { - return true; - } - - public boolean canGetFirstOrLast() { - return false; - } - - public Cursor findFirstOrLast(Session session, boolean first) { - throw DbException.getUnsupportedException("HASH"); - } - -} diff --git a/tools/h2/src/main/org/h2/index/Index.java b/tools/h2/src/main/org/h2/index/Index.java deleted file mode 100755 index 9f65aae..0000000 --- a/tools/h2/src/main/org/h2/index/Index.java +++ /dev/null @@ -1,270 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.index; - -import org.h2.engine.Session; -import org.h2.message.DbException; -import org.h2.result.Row; -import org.h2.result.SearchRow; -import org.h2.schema.SchemaObject; -import org.h2.table.Column; -import org.h2.table.IndexColumn; -import org.h2.table.Table; - -/** - * An index. Indexes are used to speed up searching data. - */ -public interface Index extends SchemaObject { - - /** - * Create a duplicate key exception with a message that contains the index name - * - * @return the exception - */ - DbException getDuplicateKeyException(); - - /** - * Get the message to show in a EXPLAIN statement. - * - * @return the plan - */ - String getPlanSQL(); - - /** - * Close this index. - * - * @param session the session used to write data - */ - void close(Session session); - - /** - * Add a row to the index. - * - * @param session the session to use - * @param row the data - */ - void add(Session session, Row row); - - /** - * Remove a row from the index. - * - * @param session the session - * @param row the data - */ - void remove(Session session, Row row); - - /** - * Find a row or a list of rows and create a cursor to iterate over the result. - * - * @param session the session - * @param first the first row, or null for no limit - * @param last the last row, or null for no limit - * @return the cursor - */ - Cursor find(Session session, SearchRow first, SearchRow last); - - /** - * Estimate the cost to search for rows given the search mask. - * There is one element per column in the search mask. - * For possible search masks, see IndexCondition. - * - * @param session the session - * @param masks the search mask - * @return the estimated cost - */ - double getCost(Session session, int[] masks); - - /** - * Remove the index. - * - * @param session the session - */ - void remove(Session session); - - /** - * Remove all rows from the index. - * - * @param session the session - */ - void truncate(Session session); - - /** - * Check if the index can directly look up the lowest or highest value of a - * column. - * - * @return true if it can - */ - boolean canGetFirstOrLast(); - - /** - * Check if the index can get the next higher value. - * - * @return true if it can - */ - boolean canFindNext(); - - /** - * Find a row or a list of rows that is larger and create a cursor to - * iterate over the result. - * - * @param session the session - * @param higherThan the lower limit (excluding) - * @param last the last row, or null for no limit - * @return the cursor - */ - Cursor findNext(Session session, SearchRow higherThan, SearchRow last); - - /** - * Find the lowest or highest value of a column. - * - * @param session the session - * @param first true if the first (lowest for ascending indexes) or last - * value should be returned - * @return a cursor or null - */ - Cursor findFirstOrLast(Session session, boolean first); - - /** - * Check if the index needs to be rebuilt. - * This method is called after opening an index. - * - * @return true if a rebuild is required. - */ - boolean needRebuild(); - - /** - * Get the row count of this table, for the given session. - * - * @param session the session - * @return the row count - */ - long getRowCount(Session session); - - /** - * Get the approximated row count for this table. - * - * @return the approximated row count - */ - long getRowCountApproximation(); - - /** - * Estimate the cost required to search a number of rows. - * - * @param rowCount the row count - * @return the estimated cost - */ - int getLookupCost(long rowCount); - - /** - * Estimate the cost required to search one row, and then iterate over the - * given number of rows. - * - * @param masks the search mask - * @param rowCount the row count - * @return the estimated cost - */ - long getCostRangeIndex(int[] masks, long rowCount); - - /** - * Compare two rows. - * - * @param rowData the first row - * @param compare the second row - * @return 0 if both rows are equal, -1 if the first row is smaller, otherwise 1 - */ - int compareRows(SearchRow rowData, SearchRow compare); - - /** - * Check if one of the columns is NULL and multiple rows with NULL are - * allowed using the current compatibility mode for unique indexes. Note: - * NULL behavior is complicated in SQL. - * - * @param newRow the row to check - * @return true if one of the columns is null and multiple nulls in unique - * indexes are allowed - */ - boolean containsNullAndAllowMultipleNull(SearchRow newRow); - - /** - * Compare the positions of two rows. - * - * @param rowData the first row - * @param compare the second row - * @return 0 if both rows are equal, -1 if the first row is smaller, otherwise 1 - */ - int compareKeys(SearchRow rowData, SearchRow compare); - - /** - * Get the index of a column in the list of index columns - * - * @param col the column - * @return the index (0 meaning first column) - */ - int getColumnIndex(Column col); - - /** - * Get the list of columns as a string. - * - * @return the list of columns - */ - String getColumnListSQL(); - - /** - * Get the indexed columns as index columns (with ordering information). - * - * @return the index columns - */ - IndexColumn[] getIndexColumns(); - - /** - * Get the indexed columns. - * - * @return the columns - */ - Column[] getColumns(); - - /** - * Get the index type. - * - * @return the index type - */ - IndexType getIndexType(); - - /** - * Get the table on which this index is based. - * - * @return the table - */ - Table getTable(); - - /** - * Commit the operation for a row. This is only important for multi-version - * indexes. - * - * @param operation the operation type - * @param row the row - */ - void commit(int operation, Row row); - - /** - * Get the root page of this index. - * - * @return the root page id - */ - int getRootPageId(); - - - /** - * Get the row with the given key. - * - * @param session the session - * @param key the unique key - * @return the row - */ - Row getRow(Session session, long key); - -} diff --git a/tools/h2/src/main/org/h2/index/IndexCondition.java b/tools/h2/src/main/org/h2/index/IndexCondition.java deleted file mode 100755 index 25cbb81..0000000 --- a/tools/h2/src/main/org/h2/index/IndexCondition.java +++ /dev/null @@ -1,323 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.index; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Comparator; -import java.util.HashSet; -import java.util.List; -import org.h2.command.dml.Query; -import org.h2.engine.Session; -import org.h2.expression.Comparison; -import org.h2.expression.Expression; -import org.h2.expression.ExpressionColumn; -import org.h2.expression.ExpressionVisitor; -import org.h2.message.DbException; -import org.h2.result.ResultInterface; -import org.h2.table.Column; -import org.h2.table.Table; -import org.h2.util.StatementBuilder; -import org.h2.value.CompareMode; -import org.h2.value.Value; - -/** - * A index condition object is made for each condition that can potentially use - * an index. This class does not extend expression, but in general there is one - * expression that maps to each index condition. - */ -public class IndexCondition { - - /** - * A bit of a search mask meaning 'equal'. - */ - public static final int EQUALITY = 1; - - /** - * A bit of a search mask meaning 'larger or equal'. - */ - public static final int START = 2; - - /** - * A bit of a search mask meaning 'smaller or equal'. - */ - public static final int END = 4; - - /** - * A search mask meaning 'between'. - */ - public static final int RANGE = START | END; - - /** - * A bit of a search mask meaning 'the condition is always false'. - */ - public static final int ALWAYS_FALSE = 8; - - private Column column; - private int compareType; - - private Expression expression; - private List expressionList; - private Query expressionQuery; - - private IndexCondition(int compareType, ExpressionColumn column, Expression expression) { - this.compareType = compareType; - this.column = column == null ? null : column.getColumn(); - this.expression = expression; - } - - /** - * Create an index condition with the given parameters. - * - * @param compareType the comparison type - * @param column the column - * @param expression the expression - * @return the index condition - */ - public static IndexCondition get(int compareType, ExpressionColumn column, Expression expression) { - return new IndexCondition(compareType, column, expression); - } - - /** - * Create an index condition with the compare type IN_LIST and with the - * given parameters. - * - * @param column the column - * @param list the expression list - * @return the index condition - */ - public static IndexCondition getInList(ExpressionColumn column, List list) { - IndexCondition cond = new IndexCondition(Comparison.IN_LIST, column, null); - cond.expressionList = list; - return cond; - } - - /** - * Create an index condition with the compare type IN_QUERY and with the - * given parameters. - * - * @param column the column - * @param query the select statement - * @return the index condition - */ - public static IndexCondition getInQuery(ExpressionColumn column, Query query) { - IndexCondition cond = new IndexCondition(Comparison.IN_QUERY, column, null); - cond.expressionQuery = query; - return cond; - } - - /** - * Get the current value of the expression. - * - * @param session the session - * @return the value - */ - public Value getCurrentValue(Session session) { - return expression.getValue(session); - } - - /** - * Get the current value list of the expression. The value list is of the - * same type as the column, distinct, and sorted. - * - * @param session the session - * @return the value list - */ - public Value[] getCurrentValueList(Session session) { - HashSet valueSet = new HashSet(); - for (Expression e : expressionList) { - Value v = e.getValue(session); - v = column.convert(v); - valueSet.add(v); - } - Value[] array = new Value[valueSet.size()]; - valueSet.toArray(array); - final CompareMode mode = session.getDatabase().getCompareMode(); - Arrays.sort(array, new Comparator() { - public int compare(Value o1, Value o2) { - return o1.compareTo(o2, mode); - } - }); - return array; - } - - /** - * Get the current result of the expression. The rows may not be of the same - * type, therefore the rows may not be unique. - * - * @param session the session - * @return the result - */ - public ResultInterface getCurrentResult(Session session) { - return expressionQuery.query(0); - } - - /** - * Get the SQL snippet of this comparison. - * - * @return the SQL snippet - */ - public String getSQL() { - if (compareType == Comparison.FALSE) { - return "FALSE"; - } - StatementBuilder buff = new StatementBuilder(); - buff.append(column.getSQL()); - switch(compareType) { - case Comparison.EQUAL: - buff.append(" = "); - break; - case Comparison.BIGGER_EQUAL: - buff.append(" >= "); - break; - case Comparison.BIGGER: - buff.append(" > "); - break; - case Comparison.SMALLER_EQUAL: - buff.append(" <= "); - break; - case Comparison.SMALLER: - buff.append(" < "); - break; - case Comparison.IN_LIST: - buff.append(" IN("); - for (Expression e : expressionList) { - buff.appendExceptFirst(", "); - buff.append(e.getSQL()); - } - buff.append(')'); - break; - case Comparison.IN_QUERY: - buff.append(" IN("); - buff.append(expressionQuery.getPlanSQL()); - buff.append(')'); - break; - default: - DbException.throwInternalError("type="+compareType); - } - if (expression != null) { - buff.append(expression.getSQL()); - } - return buff.toString(); - } - - /** - * Get the comparison bit mask. - * - * @param indexConditions all index conditions - * @return the mask - */ - public int getMask(ArrayList indexConditions) { - switch (compareType) { - case Comparison.FALSE: - return ALWAYS_FALSE; - case Comparison.EQUAL: - return EQUALITY; - case Comparison.IN_LIST: - case Comparison.IN_QUERY: - if (indexConditions.size() > 1) { - if (!column.getTable().getTableType().equals(Table.TABLE)) { - // if combined with other conditions, - // IN(..) can only be used for regular tables - // test case: - // create table test(a int, b int, primary key(id, name)); - // create unique index c on test(b, a); - // insert into test values(1, 10), (2, 20); - // select * from (select * from test) - // where a=1 and b in(10, 20); - return 0; - } - } - return EQUALITY; - case Comparison.BIGGER_EQUAL: - case Comparison.BIGGER: - return START; - case Comparison.SMALLER_EQUAL: - case Comparison.SMALLER: - return END; - default: - throw DbException.throwInternalError("type=" + compareType); - } - } - - /** - * Check if the result is always false. - * - * @return true if the result will always be false - */ - public boolean isAlwaysFalse() { - return compareType == Comparison.FALSE; - } - - /** - * Check if this index condition is of the type column larger or equal to - * value. - * - * @return true if this is a start condition - */ - public boolean isStart() { - switch (compareType) { - case Comparison.EQUAL: - case Comparison.BIGGER_EQUAL: - case Comparison.BIGGER: - return true; - default: - return false; - } - } - - /** - * Check if this index condition is of the type column smaller or equal to - * value. - * - * @return true if this is a end condition - */ - public boolean isEnd() { - switch (compareType) { - case Comparison.EQUAL: - case Comparison.SMALLER_EQUAL: - case Comparison.SMALLER: - return true; - default: - return false; - } - } - - public int getCompareType() { - return compareType; - } - - /** - * Get the referenced column. - * - * @return the column - */ - public Column getColumn() { - return column; - } - - /** - * Check if the expression can be evaluated. - * - * @return true if it can be evaluated - */ - public boolean isEvaluatable() { - if (expression != null) { - return expression.isEverything(ExpressionVisitor.EVALUATABLE); - } - if (expressionList != null) { - for (Expression e : expressionList) { - if (!e.isEverything(ExpressionVisitor.EVALUATABLE)) { - return false; - } - } - return true; - } - return expressionQuery.isEverything(ExpressionVisitor.EVALUATABLE); - } - -} diff --git a/tools/h2/src/main/org/h2/index/IndexCursor.java b/tools/h2/src/main/org/h2/index/IndexCursor.java deleted file mode 100755 index d3a89b1..0000000 --- a/tools/h2/src/main/org/h2/index/IndexCursor.java +++ /dev/null @@ -1,266 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.index; - -import java.util.ArrayList; -import java.util.HashSet; - -import org.h2.constant.SysProperties; -import org.h2.engine.Session; -import org.h2.expression.Comparison; -import org.h2.message.DbException; -import org.h2.result.ResultInterface; -import org.h2.result.Row; -import org.h2.result.SearchRow; -import org.h2.result.SortOrder; -import org.h2.table.Column; -import org.h2.table.IndexColumn; -import org.h2.table.Table; -import org.h2.value.Value; -import org.h2.value.ValueNull; - -/** - * The filter used to walk through an index. This class supports IN(..) - * and IN(SELECT ...) optimizations. - */ -public class IndexCursor implements Cursor { - private Session session; - private Index index; - private Table table; - private IndexColumn[] indexColumns; - private boolean alwaysFalse; - - private SearchRow start, end; - private Cursor cursor; - private Column inColumn; - private int inListIndex; - private Value[] inList; - private ResultInterface inResult; - private HashSet inResultTested; - - public void setIndex(Index index) { - this.index = index; - this.table = index.getTable(); - Column[] columns = table.getColumns(); - indexColumns = new IndexColumn[columns.length]; - IndexColumn[] idxCols = index.getIndexColumns(); - if (idxCols != null) { - for (int i = 0; i < columns.length; i++) { - int idx = index.getColumnIndex(columns[i]); - if (idx >= 0) { - indexColumns[i] = idxCols[idx]; - } - } - } - } - - /** - * Re-evaluate the start and end values of the index search for rows. - * - * @param s the session - * @param indexConditions the index conditions - */ - public void find(Session s, ArrayList indexConditions) { - this.session = s; - alwaysFalse = false; - start = end = null; - inList = null; - inColumn = null; - inResult = null; - inResultTested = new HashSet(); - for (IndexCondition condition : indexConditions) { - if (condition.isAlwaysFalse()) { - alwaysFalse = true; - break; - } - Column column = condition.getColumn(); - if (condition.getCompareType() == Comparison.IN_LIST) { - if (start == null && end == null) { - if (canUseIndexForIn(column)) { - this.inColumn = column; - inList = condition.getCurrentValueList(s); - inListIndex = 0; - } - } - } else if (condition.getCompareType() == Comparison.IN_QUERY) { - if (start == null && end == null) { - if (canUseIndexForIn(column)) { - this.inColumn = column; - inResult = condition.getCurrentResult(s); - } - } - } else { - Value v = condition.getCurrentValue(s); - boolean isStart = condition.isStart(); - boolean isEnd = condition.isEnd(); - int id = column.getColumnId(); - IndexColumn idxCol = indexColumns[id]; - if (idxCol != null && (idxCol.sortType & SortOrder.DESCENDING) != 0) { - // if the index column is sorted the other way, we swap end and start - // NULLS_FIRST / NULLS_LAST is not a problem, as nulls never match anyway - boolean temp = isStart; - isStart = isEnd; - isEnd = temp; - } - if (isStart) { - start = getSearchRow(start, id, v, true); - } - if (isEnd) { - end = getSearchRow(end, id, v, false); - } - if (isStart || isEnd) { - // an X=? condition will produce less rows than - // an X IN(..) condition - inColumn = null; - inList = null; - inResult = null; - } - if (!SysProperties.OPTIMIZE_IS_NULL) { - if (isStart && isEnd) { - if (v == ValueNull.INSTANCE) { - // join on a column=NULL is always false - alwaysFalse = true; - } - } - } - } - } - if (inColumn != null) { - return; - } - if (!alwaysFalse) { - cursor = index.find(s, start, end); - } - } - - private boolean canUseIndexForIn(Column column) { - if (inColumn != null) { - // only one IN(..) condition can be used at the same time - return false; - } - // The first column of the index must match this column, - // or it must be a VIEW index (where the column is null). - // Multiple IN conditions with views are not supported, see - // IndexCondition.getMask. - IndexColumn[] cols = index.getIndexColumns(); - if (cols == null) { - return true; - } - IndexColumn idxCol = cols[0]; - return idxCol == null || idxCol.column == column; - } - - private SearchRow getSearchRow(SearchRow row, int id, Value v, boolean max) { - if (row == null) { - row = table.getTemplateRow(); - } else { - v = getMax(row.getValue(id), v, max); - } - row.setValue(id, v); - return row; - } - - private Value getMax(Value a, Value b, boolean bigger) { - if (a == null) { - return b; - } else if (b == null) { - return a; - } - if (SysProperties.OPTIMIZE_IS_NULL) { - // IS NULL must be checked later - if (a == ValueNull.INSTANCE) { - return b; - } else if (b == ValueNull.INSTANCE) { - return a; - } - } - int comp = a.compareTo(b, table.getDatabase().getCompareMode()); - if (comp == 0) { - return a; - } - if (SysProperties.OPTIMIZE_IS_NULL) { - if (a == ValueNull.INSTANCE || b == ValueNull.INSTANCE) { - // column IS NULL AND column is always false - return null; - } - } - if (!bigger) { - comp = -comp; - } - return comp > 0 ? a : b; - } - - /** - * Check if the result is empty for sure. - * - * @return true if it is - */ - public boolean isAlwaysFalse() { - return alwaysFalse; - } - - public Row get() { - return cursor.get(); - } - - public SearchRow getSearchRow() { - return cursor.getSearchRow(); - } - - public boolean next() { - while (true) { - if (cursor == null) { - nextCursor(); - if (cursor == null) { - return false; - } - } - if (cursor.next()) { - return true; - } - cursor = null; - } - } - - private void nextCursor() { - if (inList != null) { - while (inListIndex < inList.length) { - Value v = inList[inListIndex++]; - if (v != ValueNull.INSTANCE) { - find(v); - break; - } - } - } else if (inResult != null) { - while (inResult.next()) { - Value v = inResult.currentRow()[0]; - if (v != ValueNull.INSTANCE) { - v = inColumn.convert(v); - if (inResultTested.add(v)) { - find(v); - break; - } - } - } - } - } - - private void find(Value v) { - v = inColumn.convert(v); - int id = inColumn.getColumnId(); - if (start == null) { - start = table.getTemplateRow(); - } - start.setValue(id, v); - cursor = index.find(session, start, start); - } - - public boolean previous() { - throw DbException.throwInternalError(); - } - -} diff --git a/tools/h2/src/main/org/h2/index/IndexType.java b/tools/h2/src/main/org/h2/index/IndexType.java deleted file mode 100755 index c81ab00..0000000 --- a/tools/h2/src/main/org/h2/index/IndexType.java +++ /dev/null @@ -1,173 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.index; - -/** - * Represents information about the properties of an index - */ -public class IndexType { - - private boolean primaryKey, persistent, unique, hash, scan; - private boolean belongsToConstraint; - - /** - * Create a primary key index. - * - * @param persistent if the index is persistent - * @param hash if a hash index should be used - * @return the index type - */ - public static IndexType createPrimaryKey(boolean persistent, boolean hash) { - IndexType type = new IndexType(); - type.primaryKey = true; - type.persistent = persistent; - type.hash = hash; - type.unique = true; - return type; - } - - /** - * Create a unique index. - * - * @param persistent if the index is persistent - * @param hash if a hash index should be used - * @return the index type - */ - public static IndexType createUnique(boolean persistent, boolean hash) { - IndexType type = new IndexType(); - type.unique = true; - type.persistent = persistent; - type.hash = hash; - return type; - } - - /** - * Create a non-unique index. - * - * @param persistent if the index is persistent - * @return the index type - */ - public static IndexType createNonUnique(boolean persistent) { - return createNonUnique(persistent, false); - } - - /** - * Create a non-unique index. - * - * @param persistent if the index is persistent - * @param hash if a hash index should be used - * @return the index type - */ - public static IndexType createNonUnique(boolean persistent, boolean hash) { - IndexType type = new IndexType(); - type.persistent = persistent; - type.hash = hash; - return type; - } - - /** - * Create a scan pseudo-index. - * - * @param persistent if the index is persistent - * @return the index type - */ - public static IndexType createScan(boolean persistent) { - IndexType type = new IndexType(); - type.persistent = persistent; - type.scan = true; - return type; - } - - /** - * Sets if this index belongs to a constraint. - * - * @param belongsToConstraint if the index belongs to a constraint - */ - public void setBelongsToConstraint(boolean belongsToConstraint) { - this.belongsToConstraint = belongsToConstraint; - } - - /** - * If the index is created because of a constraint. Such indexes are to be - * dropped once the constraint is dropped. - * - * @return if the index belongs to a constraint - */ - public boolean getBelongsToConstraint() { - return belongsToConstraint; - } - - /** - * Is this a hash index? - * - * @return true if it is a hash index - */ - public boolean isHash() { - return hash; - } - - /** - * Is this index persistent? - * - * @return true if it is persistent - */ - public boolean isPersistent() { - return persistent; - } - - /** - * Does this index belong to a primary key constraint? - * - * @return true if it references a primary key constraint - */ - public boolean isPrimaryKey() { - return primaryKey; - } - - /** - * Is this a unique index? - * - * @return true if it is - */ - public boolean isUnique() { - return unique; - } - - /** - * Get the SQL snippet to create such an index. - * - * @return the SQL snippet - */ - public String getSQL() { - StringBuilder buff = new StringBuilder(); - if (primaryKey) { - buff.append("PRIMARY KEY"); - if (hash) { - buff.append(" HASH"); - } - } else { - if (unique) { - buff.append("UNIQUE "); - } - if (hash) { - buff.append("HASH "); - } - buff.append("INDEX"); - } - return buff.toString(); - } - - /** - * Is this a table scan pseudo-index? - * - * @return true if it is - */ - public boolean isScan() { - return scan; - } - -} diff --git a/tools/h2/src/main/org/h2/index/LinkedCursor.java b/tools/h2/src/main/org/h2/index/LinkedCursor.java deleted file mode 100755 index 8d1fef4..0000000 --- a/tools/h2/src/main/org/h2/index/LinkedCursor.java +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.index; - -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.SQLException; - -import org.h2.engine.Session; -import org.h2.message.DbException; -import org.h2.result.Row; -import org.h2.result.SearchRow; -import org.h2.table.Column; -import org.h2.table.TableLink; -import org.h2.value.DataType; -import org.h2.value.Value; - -/** - * The cursor implementation for the linked index. - */ -public class LinkedCursor implements Cursor { - - private final TableLink tableLink; - private final PreparedStatement prep; - private final String sql; - private final Session session; - private final ResultSet rs; - private Row current; - - LinkedCursor(TableLink tableLink, ResultSet rs, Session session, String sql, PreparedStatement prep) { - this.session = session; - this.tableLink = tableLink; - this.rs = rs; - this.sql = sql; - this.prep = prep; - } - - public Row get() { - return current; - } - - public SearchRow getSearchRow() { - return current; - } - - public boolean next() { - try { - boolean result = rs.next(); - if (!result) { - rs.close(); - tableLink.reusePreparedStatement(prep, sql); - current = null; - return false; - } - } catch (SQLException e) { - throw DbException.convert(e); - } - current = tableLink.getTemplateRow(); - for (int i = 0; i < current.getColumnCount(); i++) { - Column col = tableLink.getColumn(i); - Value v = DataType.readValue(session, rs, i + 1, col.getType()); - current.setValue(i, v); - } - return true; - } - - public boolean previous() { - throw DbException.throwInternalError(); - } - -} diff --git a/tools/h2/src/main/org/h2/index/LinkedIndex.java b/tools/h2/src/main/org/h2/index/LinkedIndex.java deleted file mode 100755 index d746692..0000000 --- a/tools/h2/src/main/org/h2/index/LinkedIndex.java +++ /dev/null @@ -1,282 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.index; - -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import org.h2.engine.Constants; -import org.h2.engine.Session; -import org.h2.message.DbException; -import org.h2.result.Row; -import org.h2.result.SearchRow; -import org.h2.table.Column; -import org.h2.table.IndexColumn; -import org.h2.table.TableLink; -import org.h2.util.StatementBuilder; -import org.h2.value.Value; -import org.h2.value.ValueNull; - -/** - * A linked index is a index for a linked (remote) table. - * It is backed by an index on the remote table which is accessed over JDBC. - */ -public class LinkedIndex extends BaseIndex { - - private TableLink link; - private String targetTableName; - private long rowCount; - - public LinkedIndex(TableLink table, int id, IndexColumn[] columns, IndexType indexType) { - initBaseIndex(table, id, null, columns, indexType); - link = table; - targetTableName = link.getQualifiedTable(); - } - - public String getCreateSQL() { - return null; - } - - public void close(Session session) { - // nothing to do - } - - private boolean isNull(Value v) { - return v == null || v == ValueNull.INSTANCE; - } - - public void add(Session session, Row row) { - StatementBuilder buff = new StatementBuilder("INSERT INTO "); - buff.append(targetTableName).append(" VALUES("); - for (int i = 0; i < row.getColumnCount(); i++) { - Value v = row.getValue(i); - buff.appendExceptFirst(", "); - if (v == null) { - buff.append("DEFAULT"); - } else if (isNull(v)) { - buff.append("NULL"); - } else { - buff.append('?'); - } - } - buff.append(')'); - String sql = buff.toString(); - synchronized (link.getConnection()) { - try { - PreparedStatement prep = link.getPreparedStatement(sql, false); - for (int i = 0, j = 0; i < row.getColumnCount(); i++) { - Value v = row.getValue(i); - if (v != null && v != ValueNull.INSTANCE) { - v.set(prep, j + 1); - j++; - } - } - prep.executeUpdate(); - rowCount++; - } catch (Exception e) { - throw link.wrapException(sql, e); - } - } - } - - public Cursor find(Session session, SearchRow first, SearchRow last) { - StatementBuilder buff = new StatementBuilder("SELECT * FROM "); - buff.append(targetTableName).append(" T"); - for (int i = 0; first != null && i < first.getColumnCount(); i++) { - Value v = first.getValue(i); - if (v != null) { - buff.appendOnlyFirst(" WHERE "); - buff.appendExceptFirst(" AND "); - Column col = table.getColumn(i); - buff.append(col.getSQL()).append(">="); - addParameter(buff, col); - } - } - for (int i = 0; last != null && i < last.getColumnCount(); i++) { - Value v = last.getValue(i); - if (v != null) { - buff.appendOnlyFirst(" WHERE "); - buff.appendExceptFirst(" AND "); - Column col = table.getColumn(i); - buff.append(col.getSQL()).append("<="); - addParameter(buff, col); - } - } - String sql = buff.toString(); - synchronized (link.getConnection()) { - try { - PreparedStatement prep = link.getPreparedStatement(sql, true); - int j = 0; - for (int i = 0; first != null && i < first.getColumnCount(); i++) { - Value v = first.getValue(i); - if (v != null) { - v.set(prep, j + 1); - j++; - } - } - for (int i = 0; last != null && i < last.getColumnCount(); i++) { - Value v = last.getValue(i); - if (v != null) { - v.set(prep, j + 1); - j++; - } - } - ResultSet rs = prep.executeQuery(); - return new LinkedCursor(link, rs, session, sql, prep); - } catch (Exception e) { - throw link.wrapException(sql, e); - } - } - } - - private void addParameter(StatementBuilder buff, Column col) { - if (col.getType() == Value.STRING_FIXED && link.isOracle()) { - // workaround for Oracle - // create table test(id int primary key, name char(15)); - // insert into test values(1, 'Hello') - // select * from test where name = ? -- where ? = "Hello" > no rows - buff.append("CAST(? AS CHAR(").append(col.getPrecision()).append("))"); - } else { - buff.append('?'); - } - } - - public double getCost(Session session, int[] masks) { - return 100 + getCostRangeIndex(masks, rowCount + Constants.COST_ROW_OFFSET); - } - - public void remove(Session session) { - // nothing to do - } - - public void truncate(Session session) { - // nothing to do - } - - public void checkRename() { - throw DbException.getUnsupportedException("LINKED"); - } - - public boolean needRebuild() { - return false; - } - - public boolean canGetFirstOrLast() { - return false; - } - - public Cursor findFirstOrLast(Session session, boolean first) { - // TODO optimization: could get the first or last value (in any case; - // maybe not optimized) - throw DbException.getUnsupportedException("LINKED"); - } - - public void remove(Session session, Row row) { - StatementBuilder buff = new StatementBuilder("DELETE FROM "); - buff.append(targetTableName).append(" WHERE "); - for (int i = 0; i < row.getColumnCount(); i++) { - buff.appendExceptFirst("AND "); - Column col = table.getColumn(i); - buff.append(col.getSQL()); - Value v = row.getValue(i); - if (isNull(v)) { - buff.append(" IS NULL "); - } else { - buff.append('='); - addParameter(buff, col); - buff.append(' '); - } - } - String sql = buff.toString(); - synchronized (link.getConnection()) { - try { - PreparedStatement prep = link.getPreparedStatement(sql, false); - for (int i = 0, j = 0; i < row.getColumnCount(); i++) { - Value v = row.getValue(i); - if (!isNull(v)) { - v.set(prep, j + 1); - j++; - } - } - int count = prep.executeUpdate(); - rowCount -= count; - } catch (Exception e) { - throw link.wrapException(sql, e); - } - } - } - - /** - * Update a row using a UPDATE statement. This method is to be called if the - * emit updates option is enabled. - * - * @param oldRow the old data - * @param newRow the new data - */ - public void update(Row oldRow, Row newRow) { - StatementBuilder buff = new StatementBuilder("UPDATE "); - buff.append(targetTableName).append(" SET "); - for (int i = 0; i < newRow.getColumnCount(); i++) { - buff.appendExceptFirst(", "); - buff.append(table.getColumn(i).getSQL()).append('='); - Value v = newRow.getValue(i); - if (v == null) { - buff.append("DEFAULT"); - } else { - buff.append('?'); - } - } - buff.append(" WHERE "); - buff.resetCount(); - for (int i = 0; i < oldRow.getColumnCount(); i++) { - Column col = table.getColumn(i); - buff.appendExceptFirst(" AND "); - buff.append(col.getSQL()); - Value v = oldRow.getValue(i); - if (isNull(v)) { - buff.append(" IS NULL"); - } else { - buff.append('='); - addParameter(buff, col); - } - } - String sql = buff.toString(); - synchronized (link.getConnection()) { - try { - int j = 1; - PreparedStatement prep = link.getPreparedStatement(sql, false); - for (int i = 0; i < newRow.getColumnCount(); i++) { - Value v = newRow.getValue(i); - if (v != null) { - v.set(prep, j); - j++; - } - } - for (int i = 0; i < oldRow.getColumnCount(); i++) { - Value v = oldRow.getValue(i); - if (!isNull(v)) { - v.set(prep, j); - j++; - } - } - int count = prep.executeUpdate(); - // this has no effect but at least it allows to debug the update count - rowCount = rowCount + count - count; - } catch (Exception e) { - throw link.wrapException(sql, e); - } - } - } - - public long getRowCount(Session session) { - return rowCount; - } - - public long getRowCountApproximation() { - return rowCount; - } - -} diff --git a/tools/h2/src/main/org/h2/index/MetaCursor.java b/tools/h2/src/main/org/h2/index/MetaCursor.java deleted file mode 100755 index 78ec9cc..0000000 --- a/tools/h2/src/main/org/h2/index/MetaCursor.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.index; - -import java.util.ArrayList; -import org.h2.message.DbException; -import org.h2.result.Row; -import org.h2.result.SearchRow; - -/** - * An index for a meta data table. - * This index can only scan through all rows, search is not supported. - */ -public class MetaCursor implements Cursor { - - private Row current; - private ArrayList rows; - private int index; - - MetaCursor(ArrayList rows) { - this.rows = rows; - } - - public Row get() { - return current; - } - - public SearchRow getSearchRow() { - return current; - } - - public boolean next() { - current = index >= rows.size() ? null : rows.get(index++); - return current != null; - } - - public boolean previous() { - throw DbException.throwInternalError(); - } - -} diff --git a/tools/h2/src/main/org/h2/index/MetaIndex.java b/tools/h2/src/main/org/h2/index/MetaIndex.java deleted file mode 100755 index f6f453c..0000000 --- a/tools/h2/src/main/org/h2/index/MetaIndex.java +++ /dev/null @@ -1,100 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.index; - -import java.util.ArrayList; -import org.h2.engine.Session; -import org.h2.message.DbException; -import org.h2.result.Row; -import org.h2.result.SearchRow; -import org.h2.table.Column; -import org.h2.table.IndexColumn; -import org.h2.table.MetaTable; - -/** - * The index implementation for meta data tables. - */ -public class MetaIndex extends BaseIndex { - - private MetaTable meta; - private boolean scan; - - public MetaIndex(MetaTable meta, IndexColumn[] columns, boolean scan) { - initBaseIndex(meta, 0, null, columns, IndexType.createNonUnique(true)); - this.meta = meta; - this.scan = scan; - } - - public void close(Session session) { - // nothing to do - } - - public void add(Session session, Row row) { - throw DbException.getUnsupportedException("META"); - } - - public void remove(Session session, Row row) { - throw DbException.getUnsupportedException("META"); - } - - public Cursor find(Session session, SearchRow first, SearchRow last) { - ArrayList rows = meta.generateRows(session, first, last); - return new MetaCursor(rows); - } - - public double getCost(Session session, int[] masks) { - if (scan) { - return 10 * MetaTable.ROW_COUNT_APPROXIMATION; - } - return getCostRangeIndex(masks, MetaTable.ROW_COUNT_APPROXIMATION); - } - - public void truncate(Session session) { - throw DbException.getUnsupportedException("META"); - } - - public void remove(Session session) { - throw DbException.getUnsupportedException("META"); - } - - public int getColumnIndex(Column col) { - if (scan) { - // the scan index cannot use any columns - return -1; - } - return super.getColumnIndex(col); - } - - public void checkRename() { - throw DbException.getUnsupportedException("META"); - } - - public boolean needRebuild() { - return false; - } - - public String getCreateSQL() { - return null; - } - - public boolean canGetFirstOrLast() { - return false; - } - - public Cursor findFirstOrLast(Session session, boolean first) { - throw DbException.getUnsupportedException("META"); - } - - public long getRowCount(Session session) { - return MetaTable.ROW_COUNT_APPROXIMATION; - } - - public long getRowCountApproximation() { - return MetaTable.ROW_COUNT_APPROXIMATION; - } - -} diff --git a/tools/h2/src/main/org/h2/index/MultiVersionCursor.java b/tools/h2/src/main/org/h2/index/MultiVersionCursor.java deleted file mode 100755 index 595c0cb..0000000 --- a/tools/h2/src/main/org/h2/index/MultiVersionCursor.java +++ /dev/null @@ -1,185 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.index; - -import org.h2.constant.SysProperties; -import org.h2.engine.Session; -import org.h2.message.DbException; -import org.h2.result.Row; -import org.h2.result.SearchRow; -import org.h2.util.MathUtils; - -/** - * The cursor implementation for the multi-version index. - */ -public class MultiVersionCursor implements Cursor { - - private final MultiVersionIndex index; - private final Session session; - private final Cursor baseCursor, deltaCursor; - private final Object sync; - private SearchRow baseRow; - private Row deltaRow; - private boolean onBase; - private boolean end; - private boolean needNewDelta, needNewBase; - private boolean reverse; - - MultiVersionCursor(Session session, MultiVersionIndex index, Cursor base, Cursor delta, Object sync) { - this.session = session; - this.index = index; - this.baseCursor = base; - this.deltaCursor = delta; - this.sync = sync; - needNewDelta = true; - needNewBase = true; - } - - /** - * Load the current row. - */ - void loadCurrent() { - synchronized (sync) { - baseRow = baseCursor.getSearchRow(); - deltaRow = deltaCursor.get(); - needNewDelta = false; - needNewBase = false; - } - } - - private void loadNext(boolean base) { - synchronized (sync) { - if (base) { - if (step(baseCursor)) { - baseRow = baseCursor.getSearchRow(); - } else { - baseRow = null; - } - } else { - if (step(deltaCursor)) { - deltaRow = deltaCursor.get(); - } else { - deltaRow = null; - } - } - } - } - - private boolean step(Cursor cursor) { - return reverse ? cursor.previous() : cursor.next(); - } - - public Row get() { - synchronized (sync) { - if (end) { - return null; - } - return onBase ? baseCursor.get() : deltaCursor.get(); - } - } - - public SearchRow getSearchRow() { - synchronized (sync) { - if (end) { - return null; - } - return onBase ? baseCursor.getSearchRow() : deltaCursor.getSearchRow(); - } - } - - public boolean next() { - synchronized (sync) { - if (SysProperties.CHECK && end) { - DbException.throwInternalError(); - } - while (true) { - if (needNewDelta) { - loadNext(false); - needNewDelta = false; - } - if (needNewBase) { - loadNext(true); - needNewBase = false; - } - if (deltaRow == null) { - if (baseRow == null) { - end = true; - return false; - } - onBase = true; - needNewBase = true; - return true; - } - int sessionId = deltaRow.getSessionId(); - boolean isThisSession = sessionId == session.getId(); - boolean isDeleted = deltaRow.isDeleted(); - if (isThisSession && isDeleted) { - needNewDelta = true; - continue; - } - if (baseRow == null) { - if (isDeleted) { - if (isThisSession) { - end = true; - return false; - } - // the row was deleted by another session: return it - onBase = false; - needNewDelta = true; - return true; - } - DbException.throwInternalError(); - } - int compare = index.compareRows(deltaRow, baseRow); - if (compare == 0) { - // can't use compareKeys because the - // version would be compared as well - long k1 = deltaRow.getKey(); - long k2 = baseRow.getKey(); - compare = MathUtils.compareLong(k1, k2); - } - if (compare == 0) { - if (isDeleted) { - if (isThisSession) { - DbException.throwInternalError(); - } - // another session updated the row - } else { - if (isThisSession) { - onBase = false; - needNewBase = true; - needNewDelta = true; - return true; - } - // another session inserted the row: ignore - needNewBase = true; - needNewDelta = true; - continue; - } - } - if (compare > 0) { - onBase = true; - needNewBase = true; - return true; - } - onBase = false; - needNewDelta = true; - return true; - } - } - } - - public boolean previous() { - reverse = true; - try { - return next(); - } finally { - reverse = false; - } - } - -} diff --git a/tools/h2/src/main/org/h2/index/MultiVersionIndex.java b/tools/h2/src/main/org/h2/index/MultiVersionIndex.java deleted file mode 100755 index fb26204..0000000 --- a/tools/h2/src/main/org/h2/index/MultiVersionIndex.java +++ /dev/null @@ -1,327 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.index; - -import java.util.ArrayList; -import org.h2.engine.Database; -import org.h2.engine.DbObject; -import org.h2.engine.Session; -import org.h2.message.DbException; -import org.h2.result.Row; -import org.h2.result.SearchRow; -import org.h2.schema.Schema; -import org.h2.table.Column; -import org.h2.table.IndexColumn; -import org.h2.table.Table; -import org.h2.table.RegularTable; -import org.h2.value.Value; -import org.h2.value.ValueNull; - -/** - * A multi-version index is a combination of a regular index, - * and a in-memory tree index that contains uncommitted changes. - * Uncommitted changes can include new rows, and deleted rows. - */ -public class MultiVersionIndex implements Index { - - private final Index base; - private final TreeIndex delta; - private final RegularTable table; - private final Object sync; - private final Column firstColumn; - - public MultiVersionIndex(Index base, RegularTable table) { - this.base = base; - this.table = table; - IndexType deltaIndexType = IndexType.createNonUnique(false); - this.delta = new TreeIndex(table, -1, "DELTA", base.getIndexColumns(), deltaIndexType); - delta.setMultiVersion(true); - this.sync = base.getDatabase(); - this.firstColumn = base.getColumns()[0]; - } - - public void add(Session session, Row row) { - synchronized (sync) { - base.add(session, row); - if (removeIfExists(session, row)) { - // for example rolling back an delete operation - } else if (row.getSessionId() != 0) { - // don't insert rows that are added when creating an index - delta.add(session, row); - } - } - } - - public int getRootPageId() { - return base.getRootPageId(); - } - - public void close(Session session) { - synchronized (sync) { - base.close(session); - } - } - - public Cursor find(Session session, SearchRow first, SearchRow last) { - synchronized (sync) { - Cursor baseCursor = base.find(session, first, last); - Cursor deltaCursor = delta.find(session, first, last); - return new MultiVersionCursor(session, this, baseCursor, deltaCursor, sync); - } - } - - public Cursor findNext(Session session, SearchRow first, SearchRow last) { - throw DbException.throwInternalError(); - } - - public boolean canFindNext() { - // TODO possible, but more complicated - return false; - } - - public boolean canGetFirstOrLast() { - return base.canGetFirstOrLast() && delta.canGetFirstOrLast(); - } - - public Cursor findFirstOrLast(Session session, boolean first) { - if (first) { - // TODO optimization: this loops through NULL elements - Cursor cursor = find(session, null, null); - while (cursor.next()) { - SearchRow row = cursor.getSearchRow(); - Value v = row.getValue(firstColumn.getColumnId()); - if (v != ValueNull.INSTANCE) { - return cursor; - } - } - return cursor; - } - Cursor baseCursor = base.findFirstOrLast(session, false); - Cursor deltaCursor = delta.findFirstOrLast(session, false); - MultiVersionCursor cursor = new MultiVersionCursor(session, this, baseCursor, deltaCursor, sync); - cursor.loadCurrent(); - // TODO optimization: this loops through NULL elements - while (cursor.previous()) { - SearchRow row = cursor.getSearchRow(); - if (row == null) { - break; - } - Value v = row.getValue(firstColumn.getColumnId()); - if (v != ValueNull.INSTANCE) { - return cursor; - } - } - return cursor; - } - - public double getCost(Session session, int[] masks) { - return base.getCost(session, masks); - } - - public boolean needRebuild() { - return base.needRebuild(); - } - - private boolean removeIfExists(Session session, Row row) { - // maybe it was inserted by the same session just before - Cursor c = delta.find(session, row, row); - while (c.next()) { - Row r = c.get(); - if (r.getKey() == row.getKey() && r.getVersion() == row.getVersion()) { - if (r != row && table.getScanIndex(session).compareRows(r, row) != 0) { - row.setVersion(r.getVersion() + 1); - } else { - delta.remove(session, r); - return true; - } - } - } - return false; - } - - public void remove(Session session, Row row) { - synchronized (sync) { - base.remove(session, row); - if (removeIfExists(session, row)) { - // added and deleted in the same transaction: no change - } else { - delta.add(session, row); - } - } - } - - public void remove(Session session) { - synchronized (sync) { - base.remove(session); - } - } - - public void truncate(Session session) { - synchronized (sync) { - delta.truncate(session); - base.truncate(session); - } - } - - public void commit(int operation, Row row) { - synchronized (sync) { - removeIfExists(null, row); - } - } - - public int compareKeys(SearchRow rowData, SearchRow compare) { - return base.compareKeys(rowData, compare); - } - - public int compareRows(SearchRow rowData, SearchRow compare) { - return base.compareRows(rowData, compare); - } - - public int getColumnIndex(Column col) { - return base.getColumnIndex(col); - } - - public String getColumnListSQL() { - return base.getColumnListSQL(); - } - - public Column[] getColumns() { - return base.getColumns(); - } - - public IndexColumn[] getIndexColumns() { - return base.getIndexColumns(); - } - - public long getCostRangeIndex(int[] masks, long rowCount) { - return base.getCostRangeIndex(masks, rowCount); - } - - public String getCreateSQL() { - return base.getCreateSQL(); - } - - public String getCreateSQLForCopy(Table forTable, String quotedName) { - return base.getCreateSQLForCopy(forTable, quotedName); - } - - public String getDropSQL() { - return base.getDropSQL(); - } - - public DbException getDuplicateKeyException() { - return base.getDuplicateKeyException(); - } - - public IndexType getIndexType() { - return base.getIndexType(); - } - - public int getLookupCost(long rowCount) { - return base.getLookupCost(rowCount); - } - - public String getPlanSQL() { - return base.getPlanSQL(); - } - - public long getRowCount(Session session) { - return base.getRowCount(session); - } - - public Table getTable() { - return base.getTable(); - } - - public int getType() { - return base.getType(); - } - - public boolean containsNullAndAllowMultipleNull(SearchRow newRow) { - return base.containsNullAndAllowMultipleNull(newRow); - } - - public void removeChildrenAndResources(Session session) { - synchronized (sync) { - table.removeIndex(this); - remove(session); - } - } - - public String getSQL() { - return base.getSQL(); - } - - public Schema getSchema() { - return base.getSchema(); - } - - public void checkRename() { - base.checkRename(); - } - - public ArrayList getChildren() { - return base.getChildren(); - } - - public String getComment() { - return base.getComment(); - } - - public Database getDatabase() { - return base.getDatabase(); - } - - public int getId() { - return base.getId(); - } - - public long getModificationId() { - return base.getModificationId(); - } - - public String getName() { - return base.getName(); - } - - public boolean isTemporary() { - return base.isTemporary(); - } - - public void rename(String newName) { - base.rename(newName); - } - - public void setComment(String comment) { - base.setComment(comment); - } - - public void setModified() { - base.setModified(); - } - - public void setTemporary(boolean temporary) { - base.setTemporary(temporary); - } - - public long getRowCountApproximation() { - return base.getRowCountApproximation(); - } - - public Index getBaseIndex() { - return base; - } - - public Row getRow(Session session, long key) { - return base.getRow(session, key); - } - - public boolean isHidden() { - return base.isHidden(); - } - -} diff --git a/tools/h2/src/main/org/h2/index/NonUniqueHashCursor.java b/tools/h2/src/main/org/h2/index/NonUniqueHashCursor.java deleted file mode 100755 index 5bf505a..0000000 --- a/tools/h2/src/main/org/h2/index/NonUniqueHashCursor.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.index; - -import java.util.ArrayList; -import org.h2.engine.Session; -import org.h2.result.Row; -import org.h2.result.SearchRow; -import org.h2.table.RegularTable; - -/** - * Cursor implementation for non-unique hash index - * - * @author Sergi Vladykin - */ -public class NonUniqueHashCursor implements Cursor { - - private final Session session; - private final ArrayList positions; - private final RegularTable tableData; - - private int index = -1; - - public NonUniqueHashCursor(Session session, RegularTable tableData, ArrayList positions) { - this.session = session; - this.tableData = tableData; - this.positions = positions; - } - - public Row get() { - if (index < 0 || index >= positions.size()) { - return null; - } - return tableData.getRow(session, positions.get(index)); - } - - public SearchRow getSearchRow() { - return get(); - } - - public boolean next() { - return positions != null && ++index < positions.size(); - } - - public boolean previous() { - return positions != null && --index >= 0; - } - -} diff --git a/tools/h2/src/main/org/h2/index/NonUniqueHashIndex.java b/tools/h2/src/main/org/h2/index/NonUniqueHashIndex.java deleted file mode 100755 index 18572d7..0000000 --- a/tools/h2/src/main/org/h2/index/NonUniqueHashIndex.java +++ /dev/null @@ -1,95 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.index; - -import java.util.ArrayList; -import org.h2.engine.Session; -import org.h2.message.DbException; -import org.h2.result.Row; -import org.h2.result.SearchRow; -import org.h2.table.IndexColumn; -import org.h2.table.RegularTable; -import org.h2.util.New; -import org.h2.util.ValueHashMap; -import org.h2.value.Value; - -/** - * A non-unique index based on an in-memory hash map. - * - * @author Sergi Vladykin - */ -public class NonUniqueHashIndex extends HashIndex { - - private ValueHashMap> rows; - private RegularTable tableData; - private long rowCount; - - public NonUniqueHashIndex(RegularTable table, int id, String indexName, IndexColumn[] columns, IndexType indexType) { - super(table, id, indexName, columns, indexType); - this.tableData = table; - reset(); - } - - private void reset() { - rows = ValueHashMap.newInstance(); - rowCount = 0; - } - - public void truncate(Session session) { - reset(); - } - - public void add(Session session, Row row) { - Value key = row.getValue(indexColumn); - ArrayList positions = rows.get(key); - if (positions == null) { - positions = New.arrayList(); - rows.put(key, positions); - } - positions.add(row.getKey()); - rowCount++; - } - - public void remove(Session session, Row row) { - if (rowCount == 1) { - // last row in table - reset(); - } else { - Value key = row.getValue(indexColumn); - ArrayList positions = rows.get(key); - if (positions.size() == 1) { - // last row with such key - rows.remove(key); - } else { - positions.remove(row.getKey()); - } - rowCount--; - } - } - - public Cursor find(Session session, SearchRow first, SearchRow last) { - if (first == null || last == null) { - throw DbException.throwInternalError(); - } - if (first != last) { - if (compareKeys(first, last) != 0) { - throw DbException.throwInternalError(); - } - } - ArrayList positions = rows.get(first.getValue(indexColumn)); - return new NonUniqueHashCursor(session, tableData, positions); - } - - public long getRowCount(Session session) { - return rowCount; - } - - public long getRowCountApproximation() { - return rowCount; - } - -} diff --git a/tools/h2/src/main/org/h2/index/PageBtree.java b/tools/h2/src/main/org/h2/index/PageBtree.java deleted file mode 100755 index 18c0168..0000000 --- a/tools/h2/src/main/org/h2/index/PageBtree.java +++ /dev/null @@ -1,275 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.index; - -import org.h2.result.SearchRow; -import org.h2.store.Data; -import org.h2.store.Page; - -/** - * A page that contains index data. - */ -public abstract class PageBtree extends Page { - - /** - * This is a root page. - */ - static final int ROOT = 0; - - /** - * Indicator that the row count is not known. - */ - static final int UNKNOWN_ROWCOUNT = -1; - - /** - * The index. - */ - protected final PageBtreeIndex index; - - /** - * The page number of the parent. - */ - protected int parentPageId; - - /** - * The data page. - */ - protected final Data data; - - /** - * The row offsets. - */ - protected int[] offsets; - - /** - * The number of entries. - */ - protected int entryCount; - - /** - * The index data - */ - protected SearchRow[] rows; - - /** - * The start of the data area. - */ - protected int start; - - /** - * If only the position of the row is stored in the page - */ - protected boolean onlyPosition; - - /** - * Whether the data page is up-to-date. - */ - protected boolean written; - - PageBtree(PageBtreeIndex index, int pageId, Data data) { - this.index = index; - this.data = data; - setPos(pageId); - } - - /** - * Get the real row count. If required, this will read all child pages. - * - * @return the row count - */ - abstract int getRowCount(); - - /** - * Set the stored row count. This will write the page. - * - * @param rowCount the stored row count - */ - abstract void setRowCountStored(int rowCount); - - /** - * Find an entry. - * - * @param compare the row - * @param bigger if looking for a larger row - * @param add if the row should be added (check for duplicate keys) - * @param compareKeys compare the row keys as well - * @return the index of the found row - */ - int find(SearchRow compare, boolean bigger, boolean add, boolean compareKeys) { - if (compare == null) { - return 0; - } - int l = 0, r = entryCount; - int comp = 1; - while (l < r) { - int i = (l + r) >>> 1; - SearchRow row = getRow(i); - comp = index.compareRows(row, compare); - if (comp == 0) { - if (add && index.indexType.isUnique()) { - if (!index.containsNullAndAllowMultipleNull(compare)) { - throw index.getDuplicateKeyException(); - } - } - if (compareKeys) { - comp = index.compareKeys(row, compare); - if (comp == 0) { - return i; - } - } - } - if (comp > 0 || (!bigger && comp == 0)) { - r = i; - } else { - l = i + 1; - } - } - return l; - } - - /** - * Add a row if possible. If it is possible this method returns -1, otherwise - * the split point. It is always possible to add one row. - * - * @param row the row to add - * @return the split point of this page, or -1 if no split is required - */ - abstract int addRowTry(SearchRow row); - - /** - * Find the first row. - * - * @param cursor the cursor - * @param first the row to find - * @param if the row should be bigger - */ - abstract void find(PageBtreeCursor cursor, SearchRow first, boolean bigger); - - /** - * Find the last row. - * - * @param cursor the cursor - */ - abstract void last(PageBtreeCursor cursor); - - /** - * Get the row at this position. - * - * @param at the index - * @return the row - */ - SearchRow getRow(int at) { - SearchRow row = rows[at]; - if (row == null) { - row = index.readRow(data, offsets[at], onlyPosition, true); - rows[at] = row; - } else if (!index.hasData(row)) { - row = index.readRow(row.getKey()); - rows[at] = row; - } - return row; - } - - /** - * Split the index page at the given point. - * - * @param splitPoint the index where to split - * @return the new page that contains about half the entries - */ - abstract PageBtree split(int splitPoint); - - /** - * Change the page id. - * - * @param id the new page id - */ - void setPageId(int id) { - changeCount = index.getPageStore().getChangeCount(); - written = false; - index.getPageStore().removeRecord(getPos()); - setPos(id); - index.getPageStore().logUndo(this, null); - remapChildren(); - } - - /** - * Get the first child leaf page of a page. - * - * @return the page - */ - abstract PageBtreeLeaf getFirstLeaf(); - - /** - * Get the first child leaf page of a page. - * - * @return the page - */ - abstract PageBtreeLeaf getLastLeaf(); - - /** - * Change the parent page id. - * - * @param id the new parent page id - */ - void setParentPageId(int id) { - index.getPageStore().logUndo(this, data); - changeCount = index.getPageStore().getChangeCount(); - written = false; - parentPageId = id; - } - - /** - * Update the parent id of all children. - */ - abstract void remapChildren(); - - /** - * Remove a row. - * - * @param row the row to remove - * @return null if the last row didn't change, - * the deleted row if the page is now empty, - * otherwise the new last row of this page - */ - abstract SearchRow remove(SearchRow row); - - /** - * Free this page and all child pages. - */ - abstract void freeRecursive(); - - /** - * Ensure all rows are read in memory. - */ - protected void readAllRows() { - for (int i = 0; i < entryCount; i++) { - SearchRow row = rows[i]; - if (row == null) { - row = index.readRow(data, offsets[i], onlyPosition, false); - rows[i] = row; - } - } - } - - /** - * Get the estimated memory size. - * - * @return number of double words (4 bytes) - */ - public int getMemorySize() { - // four times the byte array size - return index.getPageStore().getPageSize(); - } - - public boolean canRemove() { - if (changeCount >= index.getPageStore().getChangeCount()) { - return false; - } - return true; - } - -} diff --git a/tools/h2/src/main/org/h2/index/PageBtreeCursor.java b/tools/h2/src/main/org/h2/index/PageBtreeCursor.java deleted file mode 100755 index 5575fd5..0000000 --- a/tools/h2/src/main/org/h2/index/PageBtreeCursor.java +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.index; - -import org.h2.engine.Session; -import org.h2.result.Row; -import org.h2.result.SearchRow; - -/** - * The cursor implementation for the page b-tree index. - */ -public class PageBtreeCursor implements Cursor { - - private final Session session; - private final PageBtreeIndex index; - private final SearchRow last; - private PageBtreeLeaf current; - private int i; - private SearchRow currentSearchRow; - private Row currentRow; - - PageBtreeCursor(Session session, PageBtreeIndex index, SearchRow last) { - this.session = session; - this.index = index; - this.last = last; - } - - /** - * Set the position of the current row. - * - * @param current the leaf page - * @param i the index within the page - */ - void setCurrent(PageBtreeLeaf current, int i) { - this.current = current; - this.i = i; - } - - public Row get() { - if (currentRow == null && currentSearchRow != null) { - currentRow = index.getRow(session, currentSearchRow.getKey()); - } - return currentRow; - } - - public SearchRow getSearchRow() { - return currentSearchRow; - } - - public boolean next() { - if (current == null) { - return false; - } - if (i >= current.getEntryCount()) { - current.nextPage(this); - if (current == null) { - return false; - } - } - currentSearchRow = current.getRow(i); - currentRow = null; - if (last != null && index.compareRows(currentSearchRow, last) > 0) { - currentSearchRow = null; - return false; - } - i++; - return true; - } - - public boolean previous() { - if (current == null) { - return false; - } - if (i < 0) { - current.previousPage(this); - if (current == null) { - return false; - } - } - currentSearchRow = current.getRow(i); - currentRow = null; - i--; - return true; - } - -} diff --git a/tools/h2/src/main/org/h2/index/PageBtreeIndex.java b/tools/h2/src/main/org/h2/index/PageBtreeIndex.java deleted file mode 100755 index 1bc6e9b..0000000 --- a/tools/h2/src/main/org/h2/index/PageBtreeIndex.java +++ /dev/null @@ -1,427 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.index; - -import org.h2.constant.ErrorCode; -import org.h2.constant.SysProperties; -import org.h2.engine.Session; -import org.h2.message.DbException; -import org.h2.result.Row; -import org.h2.result.SearchRow; -import org.h2.store.Data; -import org.h2.store.Page; -import org.h2.store.PageStore; -import org.h2.table.Column; -import org.h2.table.IndexColumn; -import org.h2.table.RegularTable; -import org.h2.util.MathUtils; -import org.h2.value.Value; -import org.h2.value.ValueNull; - -/** - * This is the most common type of index, a b tree index. - * Only the data of the indexed columns are stored in the index. - */ -public class PageBtreeIndex extends PageIndex { - - private PageStore store; - private RegularTable tableData; - private boolean needRebuild; - private long rowCount; - - public PageBtreeIndex(RegularTable table, int id, String indexName, IndexColumn[] columns, - IndexType indexType, boolean create, Session session) { - initBaseIndex(table, id, indexName, columns, indexType); - // int test; - // trace.setLevel(TraceSystem.DEBUG); - tableData = table; - if (!database.isPersistent() || id < 0) { - throw DbException.throwInternalError("" + indexName); - } - this.store = database.getPageStore(); - store.addIndex(this); - if (create) { - // new index - rootPageId = store.allocatePage(); - needRebuild = true; - // TODO currently the head position is stored in the log - // it should not for new tables, otherwise redo of other operations - // must ensure this page is not used for other things - store.addMeta(this, session); - PageBtreeLeaf root = PageBtreeLeaf.create(this, rootPageId, PageBtree.ROOT); - store.logUndo(root, null); - store.update(root); - } else { - rootPageId = store.getRootPageId(id); - PageBtree root = getPage(rootPageId); - rowCount = root.getRowCount(); - if (rowCount == 0 && store.isRecoveryRunning()) { - needRebuild = true; - } - } - if (trace.isDebugEnabled()) { - trace.debug("opened " + getName() +" rows:"+ rowCount); - } - } - - public void add(Session session, Row row) { - if (trace.isDebugEnabled()) { - trace.debug(getName() + " add " + row); - } - // safe memory - SearchRow newRow = getSearchRow(row); - try { - addRow(newRow); - } finally { - store.incrementChangeCount(); - } - } - - private void addRow(SearchRow newRow) { - while (true) { - PageBtree root = getPage(rootPageId); - int splitPoint = root.addRowTry(newRow); - if (splitPoint == -1) { - break; - } - if (trace.isDebugEnabled()) { - trace.debug("split " + splitPoint); - } - SearchRow pivot = root.getRow(splitPoint - 1); - store.logUndo(root, root.data); - PageBtree page1 = root; - PageBtree page2 = root.split(splitPoint); - store.logUndo(page2, null); - int id = store.allocatePage(); - page1.setPageId(id); - page1.setParentPageId(rootPageId); - page2.setParentPageId(rootPageId); - PageBtreeNode newRoot = PageBtreeNode.create(this, rootPageId, PageBtree.ROOT); - store.logUndo(newRoot, null); - newRoot.init(page1, pivot, page2); - store.update(page1); - store.update(page2); - store.update(newRoot); - root = newRoot; - } - invalidateRowCount(); - rowCount++; - } - - /** - * Create a search row for this row. - * - * @param row the row - * @return the search row - */ - private SearchRow getSearchRow(Row row) { - SearchRow r = table.getTemplateSimpleRow(columns.length == 1); - r.setKeyAndVersion(row); - for (int j = 0; j < columns.length; j++) { - int idx = columns[j].getColumnId(); - r.setValue(idx, row.getValue(idx)); - } - return r; - } - - /** - * Read the given page. - * - * @param id the page id - * @return the page - */ - PageBtree getPage(int id) { - Page p = store.getPage(id); - if (p == null) { - PageBtreeLeaf empty = PageBtreeLeaf.create(this, id, PageBtree.ROOT); - // could have been created before, but never committed - store.logUndo(empty, null); - store.update(empty); - return empty; - } else if (!(p instanceof PageBtree)) { - throw DbException.get(ErrorCode.FILE_CORRUPTED_1, "" + p); - } - return (PageBtree) p; - } - - public boolean canGetFirstOrLast() { - return true; - } - - public Cursor findNext(Session session, SearchRow first, SearchRow last) { - return find(session, first, true, last); - } - - public Cursor find(Session session, SearchRow first, SearchRow last) { - return find(session, first, false, last); - } - - private Cursor find(Session session, SearchRow first, boolean bigger, SearchRow last) { - if (SysProperties.CHECK && store == null) { - throw DbException.get(ErrorCode.OBJECT_CLOSED); - } - PageBtree root = getPage(rootPageId); - PageBtreeCursor cursor = new PageBtreeCursor(session, this, last); - root.find(cursor, first, bigger); - return cursor; - } - - public Cursor findFirstOrLast(Session session, boolean first) { - if (first) { - // TODO optimization: this loops through NULL elements - Cursor cursor = find(session, null, false, null); - while (cursor.next()) { - SearchRow row = cursor.getSearchRow(); - Value v = row.getValue(columnIds[0]); - if (v != ValueNull.INSTANCE) { - return cursor; - } - } - return cursor; - } - PageBtree root = getPage(rootPageId); - PageBtreeCursor cursor = new PageBtreeCursor(session, this, null); - root.last(cursor); - cursor.previous(); - // TODO optimization: this loops through NULL elements - do { - SearchRow row = cursor.getSearchRow(); - if (row == null) { - break; - } - Value v = row.getValue(columnIds[0]); - if (v != ValueNull.INSTANCE) { - return cursor; - } - } while (cursor.previous()); - return cursor; - } - - public double getCost(Session session, int[] masks) { - return 10 * getCostRangeIndex(masks, tableData.getRowCount(session)); - } - - public boolean needRebuild() { - return needRebuild; - } - - public void remove(Session session, Row row) { - if (trace.isDebugEnabled()) { - trace.debug(getName() + " remove " + row); - } - if (tableData.getContainsLargeObject()) { - for (int i = 0; i < row.getColumnCount(); i++) { - Value v = row.getValue(i); - if (v.isLinked()) { - session.unlinkAtCommit(v); - } - } - } - // TODO invalidate row count - // setChanged(session); - if (rowCount == 1) { - removeAllRows(); - } else { - try { - PageBtree root = getPage(rootPageId); - root.remove(row); - invalidateRowCount(); - rowCount--; - } finally { - store.incrementChangeCount(); - } - } - } - - public void remove(Session session) { - if (trace.isDebugEnabled()) { - trace.debug("remove"); - } - removeAllRows(); - store.free(rootPageId); - store.removeMeta(this, session); - } - - public void truncate(Session session) { - if (trace.isDebugEnabled()) { - trace.debug("truncate"); - } - removeAllRows(); - if (tableData.getContainsLargeObject()) { - database.getLobStorage().removeAllForTable(table.getId()); - } - tableData.setRowCount(0); - } - - private void removeAllRows() { - try { - PageBtree root = getPage(rootPageId); - root.freeRecursive(); - root = PageBtreeLeaf.create(this, rootPageId, PageBtree.ROOT); - store.removeRecord(rootPageId); - store.update(root); - rowCount = 0; - } finally { - store.incrementChangeCount(); - } - } - - public void checkRename() { - // ok - } - - /** - * Get a row from the main index. - * - * @param session the session - * @param key the row key - * @return the row - */ - public Row getRow(Session session, long key) { - return tableData.getRow(session, key); - } - - PageStore getPageStore() { - return store; - } - - public long getRowCountApproximation() { - return tableData.getRowCountApproximation(); - } - - public long getRowCount(Session session) { - return rowCount; - } - - public void close(Session session) { - if (trace.isDebugEnabled()) { - trace.debug("close"); - } - // can not close the index because it might get used afterwards, - // for example after running recovery - try { - writeRowCount(); - } finally { - store.incrementChangeCount(); - } - } - - /** - * Read a row from the data page at the given offset. - * - * @param data the data - * @param offset the offset - * @param onlyPosition whether only the position of the row is stored - * @param needData whether the row data is required - * @return the row - */ - SearchRow readRow(Data data, int offset, boolean onlyPosition, boolean needData) { - data.setPos(offset); - long key = data.readVarLong(); - if (onlyPosition) { - if (needData) { - return tableData.getRow(null, key); - } - SearchRow row = table.getTemplateSimpleRow(true); - row.setKey(key); - return row; - } - SearchRow row = table.getTemplateSimpleRow(columns.length == 1); - row.setKey(key); - for (Column col : columns) { - int idx = col.getColumnId(); - row.setValue(idx, data.readValue()); - } - return row; - } - - /** - * Get the complete row from the data index. - * - * @param key the key - * @return the row - */ - SearchRow readRow(long key) { - return tableData.getRow(null, key); - } - - /** - * Write a row to the data page at the given offset. - * - * @param data the data - * @param offset the offset - * @param onlyPosition whether only the position of the row is stored - * @param row the row to write - */ - void writeRow(Data data, int offset, SearchRow row, boolean onlyPosition) { - data.setPos(offset); - data.writeVarLong(row.getKey()); - if (!onlyPosition) { - for (Column col : columns) { - int idx = col.getColumnId(); - data.writeValue(row.getValue(idx)); - } - } - } - - /** - * Get the size of a row (only the part that is stored in the index). - * - * @param dummy a dummy data page to calculate the size - * @param row the row - * @param onlyPosition whether only the position of the row is stored - * @return the number of bytes - */ - int getRowSize(Data dummy, SearchRow row, boolean onlyPosition) { - int rowsize = Data.getVarLongLen(row.getKey()); - if (!onlyPosition) { - for (Column col : columns) { - Value v = row.getValue(col.getColumnId()); - rowsize += dummy.getValueLen(v); - } - } - return rowsize; - } - - public boolean canFindNext() { - return true; - } - - /** - * The root page has changed. - * - * @param session the session - * @param newPos the new position - */ - void setRootPageId(Session session, int newPos) { - store.removeMeta(this, session); - this.rootPageId = newPos; - store.addMeta(this, session); - store.addIndex(this); - } - - private void invalidateRowCount() { - PageBtree root = getPage(rootPageId); - root.setRowCountStored(PageData.UNKNOWN_ROWCOUNT); - } - - public void writeRowCount() { - PageBtree root = getPage(rootPageId); - root.setRowCountStored(MathUtils.convertLongToInt(rowCount)); - } - - /** - * Check whether the given row contains data. - * - * @param row the row - * @return true if it contains data - */ - boolean hasData(SearchRow row) { - return row.getValue(columns[0].getColumnId()) != null; - } - -} diff --git a/tools/h2/src/main/org/h2/index/PageBtreeLeaf.java b/tools/h2/src/main/org/h2/index/PageBtreeLeaf.java deleted file mode 100755 index b2abbb2..0000000 --- a/tools/h2/src/main/org/h2/index/PageBtreeLeaf.java +++ /dev/null @@ -1,342 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.index; - -import org.h2.constant.ErrorCode; -import org.h2.constant.SysProperties; -import org.h2.engine.Session; -import org.h2.message.DbException; -import org.h2.result.SearchRow; -import org.h2.store.Data; -import org.h2.store.Page; -import org.h2.store.PageStore; - -/** - * A b-tree leaf page that contains index data. Format: - *
    - *
  • page type: byte
  • - *
  • checksum: short
  • - *
  • parent page id (0 for root): int
  • - *
  • index id: varInt
  • - *
  • entry count: short
  • - *
  • list of offsets: short
  • - *
  • data (key: varLong, value,...)
  • - *
- */ -public class PageBtreeLeaf extends PageBtree { - - private static final int OFFSET_LENGTH = 2; - - private PageBtreeLeaf(PageBtreeIndex index, int pageId, Data data) { - super(index, pageId, data); - } - - /** - * Read a b-tree leaf page. - * - * @param index the index - * @param data the data - * @param pageId the page id - * @return the page - */ - public static Page read(PageBtreeIndex index, Data data, int pageId) { - PageBtreeLeaf p = new PageBtreeLeaf(index, pageId, data); - p.read(); - return p; - } - - /** - * Create a new page. - * - * @param index the index - * @param pageId the page id - * @param parentPageId the parent - * @return the page - */ - static PageBtreeLeaf create(PageBtreeIndex index, int pageId, int parentPageId) { - PageBtreeLeaf p = new PageBtreeLeaf(index, pageId, index.getPageStore().createData()); - index.getPageStore().logUndo(p, null); - p.parentPageId = parentPageId; - p.writeHead(); - p.start = p.data.length(); - return p; - } - - private void read() { - data.reset(); - int type = data.readByte(); - data.readShortInt(); - this.parentPageId = data.readInt(); - onlyPosition = (type & Page.FLAG_LAST) == 0; - int indexId = data.readVarInt(); - if (indexId != index.getId()) { - throw DbException.get(ErrorCode.FILE_CORRUPTED_1, - "page:" + getPos() + " expected index:" + index.getId() + - "got:" + indexId); - } - entryCount = data.readShortInt(); - offsets = new int[entryCount]; - rows = new SearchRow[entryCount]; - for (int i = 0; i < entryCount; i++) { - offsets[i] = data.readShortInt(); - } - start = data.length(); - written = true; - } - - int addRowTry(SearchRow row) { - return addRow(row, true); - } - - private int addRow(SearchRow row, boolean tryOnly) { - int rowLength = index.getRowSize(data, row, onlyPosition); - int pageSize = index.getPageStore().getPageSize(); - int last = entryCount == 0 ? pageSize : offsets[entryCount - 1]; - if (last - rowLength < start + OFFSET_LENGTH) { - if (tryOnly && entryCount > 1) { - int x = find(row, false, true, true); - if (entryCount < 5) { - // required, otherwise the index doesn't work correctly - return entryCount / 2; - } - // split near the insertion point to better fill pages - // split in half would be: - // return entryCount / 2; - int third = entryCount / 3; - return x < third ? third : x >= 2 * third ? 2 * third : x; - } - readAllRows(); - onlyPosition = true; - // change the offsets (now storing only positions) - int o = pageSize; - for (int i = 0; i < entryCount; i++) { - o -= index.getRowSize(data, getRow(i), true); - offsets[i] = o; - } - last = entryCount == 0 ? pageSize : offsets[entryCount - 1]; - rowLength = index.getRowSize(data, row, true); - if (SysProperties.CHECK && last - rowLength < start + OFFSET_LENGTH) { - throw DbException.throwInternalError(); - } - } - index.getPageStore().logUndo(this, data); - readAllRows(); - changeCount = index.getPageStore().getChangeCount(); - written = false; - int offset = last - rowLength; - int[] newOffsets = new int[entryCount + 1]; - SearchRow[] newRows = new SearchRow[entryCount + 1]; - int x; - if (entryCount == 0) { - x = 0; - } else { - x = find(row, false, true, true); - System.arraycopy(offsets, 0, newOffsets, 0, x); - System.arraycopy(rows, 0, newRows, 0, x); - if (x < entryCount) { - for (int j = x; j < entryCount; j++) { - newOffsets[j + 1] = offsets[j] - rowLength; - } - offset = (x == 0 ? pageSize : offsets[x - 1]) - rowLength; - System.arraycopy(rows, x, newRows, x + 1, entryCount - x); - } - } - entryCount++; - start += OFFSET_LENGTH; - newOffsets[x] = offset; - newRows[x] = row; - offsets = newOffsets; - rows = newRows; - index.getPageStore().update(this); - return -1; - } - - private void removeRow(int at) { - readAllRows(); - index.getPageStore().logUndo(this, data); - entryCount--; - written = false; - changeCount = index.getPageStore().getChangeCount(); - if (entryCount <= 0) { - DbException.throwInternalError(); - } - int[] newOffsets = new int[entryCount]; - SearchRow[] newRows = new SearchRow[entryCount]; - System.arraycopy(offsets, 0, newOffsets, 0, at); - System.arraycopy(rows, 0, newRows, 0, at); - int startNext = at > 0 ? offsets[at - 1] : index.getPageStore().getPageSize(); - int rowLength = startNext - offsets[at]; - for (int j = at; j < entryCount; j++) { - newOffsets[j] = offsets[j + 1] + rowLength; - } - System.arraycopy(rows, at + 1, newRows, at, entryCount - at); - start -= OFFSET_LENGTH; - offsets = newOffsets; - rows = newRows; - } - - int getEntryCount() { - return entryCount; - } - - PageBtree split(int splitPoint) { - int newPageId = index.getPageStore().allocatePage(); - PageBtreeLeaf p2 = PageBtreeLeaf.create(index, newPageId, parentPageId); - for (int i = splitPoint; i < entryCount;) { - p2.addRow(getRow(splitPoint), false); - removeRow(splitPoint); - } - return p2; - } - - PageBtreeLeaf getFirstLeaf() { - return this; - } - - PageBtreeLeaf getLastLeaf() { - return this; - } - - SearchRow remove(SearchRow row) { - int at = find(row, false, false, true); - SearchRow delete = getRow(at); - if (index.compareRows(row, delete) != 0 || delete.getKey() != row.getKey()) { - throw DbException.get(ErrorCode.ROW_NOT_FOUND_WHEN_DELETING_1, index.getSQL() + ": " + row); - } - index.getPageStore().logUndo(this, data); - if (entryCount == 1) { - // the page is now empty - return row; - } - removeRow(at); - index.getPageStore().update(this); - if (at == entryCount) { - // the last row changed - return getRow(at - 1); - } - // the last row didn't change - return null; - } - - void freeRecursive() { - index.getPageStore().logUndo(this, data); - index.getPageStore().free(getPos()); - } - - int getRowCount() { - return entryCount; - } - - void setRowCountStored(int rowCount) { - // ignore - } - - public void write() { - writeData(); - index.getPageStore().writePage(getPos(), data); - } - - private void writeHead() { - data.reset(); - data.writeByte((byte) (Page.TYPE_BTREE_LEAF | (onlyPosition ? 0 : Page.FLAG_LAST))); - data.writeShortInt(0); - data.writeInt(parentPageId); - data.writeVarInt(index.getId()); - data.writeShortInt(entryCount); - } - - private void writeData() { - if (written) { - return; - } - readAllRows(); - writeHead(); - for (int i = 0; i < entryCount; i++) { - data.writeShortInt(offsets[i]); - } - for (int i = 0; i < entryCount; i++) { - index.writeRow(data, offsets[i], rows[i], onlyPosition); - } - written = true; - } - - void find(PageBtreeCursor cursor, SearchRow first, boolean bigger) { - int i = find(first, bigger, false, false); - if (i > entryCount) { - if (parentPageId == PageBtree.ROOT) { - return; - } - PageBtreeNode next = (PageBtreeNode) index.getPage(parentPageId); - next.find(cursor, first, bigger); - return; - } - cursor.setCurrent(this, i); - } - - void last(PageBtreeCursor cursor) { - cursor.setCurrent(this, entryCount - 1); - } - - void remapChildren() { - // nothing to do - } - - /** - * Set the cursor to the first row of the next page. - * - * @param cursor the cursor - */ - void nextPage(PageBtreeCursor cursor) { - if (parentPageId == PageBtree.ROOT) { - cursor.setCurrent(null, 0); - return; - } - PageBtreeNode next = (PageBtreeNode) index.getPage(parentPageId); - next.nextPage(cursor, getPos()); - } - - /** - * Set the cursor to the last row of the previous page. - * - * @param cursor the cursor - */ - void previousPage(PageBtreeCursor cursor) { - if (parentPageId == PageBtree.ROOT) { - cursor.setCurrent(null, 0); - return; - } - PageBtreeNode next = (PageBtreeNode) index.getPage(parentPageId); - next.previousPage(cursor, getPos()); - } - - public String toString() { - return "page[" + getPos() + "] b-tree leaf table:" + index.getId() + " entries:" + entryCount; - } - - public void moveTo(Session session, int newPos) { - PageStore store = index.getPageStore(); - readAllRows(); - PageBtreeLeaf p2 = PageBtreeLeaf.create(index, newPos, parentPageId); - store.logUndo(this, data); - store.logUndo(p2, null); - p2.rows = rows; - p2.entryCount = entryCount; - p2.offsets = offsets; - p2.onlyPosition = onlyPosition; - p2.parentPageId = parentPageId; - p2.start = start; - store.update(p2); - if (parentPageId == ROOT) { - index.setRootPageId(session, newPos); - } else { - PageBtreeNode p = (PageBtreeNode) store.getPage(parentPageId); - p.moveChild(getPos(), newPos); - } - store.free(getPos()); - } - -} diff --git a/tools/h2/src/main/org/h2/index/PageBtreeNode.java b/tools/h2/src/main/org/h2/index/PageBtreeNode.java deleted file mode 100755 index 14ca200..0000000 --- a/tools/h2/src/main/org/h2/index/PageBtreeNode.java +++ /dev/null @@ -1,591 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.index; - -import org.h2.api.DatabaseEventListener; -import org.h2.constant.ErrorCode; -import org.h2.constant.SysProperties; -import org.h2.engine.Session; -import org.h2.message.DbException; -import org.h2.result.SearchRow; -import org.h2.store.Data; -import org.h2.store.Page; -import org.h2.store.PageStore; -import org.h2.util.Utils; - -/** - * A b-tree node page that contains index data. Format: - *
    - *
  • page type: byte
  • - *
  • checksum: short
  • - *
  • parent page id (0 for root): int
  • - *
  • index id: varInt
  • - *
  • count of all children (-1 if not known): int
  • - *
  • entry count: short
  • - *
  • rightmost child page id: int
  • - *
  • entries (child page id: int, offset: short)
  • - *
- * The row contains the largest key of the respective child, - * meaning row[0] contains the largest key of child[0]. - */ -public class PageBtreeNode extends PageBtree { - - private static final int CHILD_OFFSET_PAIR_LENGTH = 6; - - /** - * The page ids of the children. - */ - private int[] childPageIds; - - private int rowCountStored = UNKNOWN_ROWCOUNT; - - private int rowCount = UNKNOWN_ROWCOUNT; - - private PageBtreeNode(PageBtreeIndex index, int pageId, Data data) { - super(index, pageId, data); - } - - /** - * Read a b-tree node page. - * - * @param index the index - * @param data the data - * @param pageId the page id - * @return the page - */ - public static Page read(PageBtreeIndex index, Data data, int pageId) { - PageBtreeNode p = new PageBtreeNode(index, pageId, data); - p.read(); - return p; - } - - /** - * Create a new b-tree node page. - * - * @param index the index - * @param pageId the page id - * @param parentPageId the parent page id - * @return the page - */ - static PageBtreeNode create(PageBtreeIndex index, int pageId, int parentPageId) { - PageBtreeNode p = new PageBtreeNode(index, pageId, index.getPageStore().createData()); - index.getPageStore().logUndo(p, null); - p.parentPageId = parentPageId; - p.writeHead(); - // 4 bytes for the rightmost child page id - p.start = p.data.length() + 4; - if (SysProperties.PAGE_STORE_INTERNAL_COUNT) { - p.rowCount = 0; - } - return p; - } - - private void read() { - data.reset(); - int type = data.readByte(); - data.readShortInt(); - this.parentPageId = data.readInt(); - onlyPosition = (type & Page.FLAG_LAST) == 0; - int indexId = data.readVarInt(); - if (indexId != index.getId()) { - throw DbException.get(ErrorCode.FILE_CORRUPTED_1, - "page:" + getPos() + " expected index:" + index.getId() + - "got:" + indexId); - } - rowCount = rowCountStored = data.readInt(); - entryCount = data.readShortInt(); - childPageIds = new int[entryCount + 1]; - childPageIds[entryCount] = data.readInt(); - rows = PageStore.newSearchRows(entryCount); - offsets = Utils.newIntArray(entryCount); - for (int i = 0; i < entryCount; i++) { - childPageIds[i] = data.readInt(); - offsets[i] = data.readShortInt(); - } - check(); - start = data.length(); - written = true; - } - - /** - * Add a row. If it is possible this method returns -1, otherwise - * the split point. It is always possible to two rows. - * - * @param row the now to add - * @return the split point of this page, or -1 if no split is required - */ - private int addChildTry(SearchRow row) { - if (entryCount < 3) { - return -1; - } - int rowLength = index.getRowSize(data, row, onlyPosition); - int pageSize = index.getPageStore().getPageSize(); - int last = entryCount == 0 ? pageSize : offsets[entryCount - 1]; - if (last - rowLength < start + CHILD_OFFSET_PAIR_LENGTH) { - return entryCount / 2; - } - return -1; - } - - /** - * Add a child at the given position. - * - * @param x the position - * @param childPageId the child - * @param row the row smaller than the first row of the child and its children - */ - private void addChild(int x, int childPageId, SearchRow row) { - int rowLength = index.getRowSize(data, row, onlyPosition); - int pageSize = index.getPageStore().getPageSize(); - int last = entryCount == 0 ? pageSize : offsets[entryCount - 1]; - if (last - rowLength < start + CHILD_OFFSET_PAIR_LENGTH) { - readAllRows(); - onlyPosition = true; - // change the offsets (now storing only positions) - int o = pageSize; - for (int i = 0; i < entryCount; i++) { - o -= index.getRowSize(data, getRow(i), true); - offsets[i] = o; - } - last = entryCount == 0 ? pageSize : offsets[entryCount - 1]; - rowLength = index.getRowSize(data, row, true); - if (SysProperties.CHECK && last - rowLength < start + CHILD_OFFSET_PAIR_LENGTH) { - throw DbException.throwInternalError(); - } - } - int offset = last - rowLength; - int[] newOffsets = new int[entryCount + 1]; - SearchRow[] newRows = new SearchRow[entryCount + 1]; - int[] newChildPageIds = new int[entryCount + 2]; - if (childPageIds != null) { - System.arraycopy(childPageIds, 0, newChildPageIds, 0, x + 1); - } - if (entryCount > 0) { - System.arraycopy(offsets, 0, newOffsets, 0, x); - System.arraycopy(rows, 0, newRows, 0, x); - if (x < entryCount) { - for (int j = x; j < entryCount; j++) { - newOffsets[j + 1] = offsets[j] - rowLength; - } - offset = (x == 0 ? pageSize : offsets[x - 1]) - rowLength; - System.arraycopy(rows, x, newRows, x + 1, entryCount - x); - System.arraycopy(childPageIds, x + 1, newChildPageIds, x + 2, entryCount - x); - } - } - newOffsets[x] = offset; - newRows[x] = row; - newChildPageIds[x + 1] = childPageId; - start += CHILD_OFFSET_PAIR_LENGTH; - offsets = newOffsets; - rows = newRows; - childPageIds = newChildPageIds; - if (SysProperties.PAGE_STORE_INTERNAL_COUNT) { - if (rowCount != UNKNOWN_ROWCOUNT) { - rowCount += offset; - } - } - entryCount++; - written = false; - changeCount = index.getPageStore().getChangeCount(); - } - - int addRowTry(SearchRow row) { - while (true) { - int x = find(row, false, true, true); - PageBtree page = index.getPage(childPageIds[x]); - int splitPoint = page.addRowTry(row); - if (splitPoint == -1) { - break; - } - SearchRow pivot = page.getRow(splitPoint - 1); - index.getPageStore().logUndo(this, data); - int splitPoint2 = addChildTry(pivot); - if (splitPoint2 != -1) { - return splitPoint2; - } - PageBtree page2 = page.split(splitPoint); - readAllRows(); - addChild(x, page2.getPos(), pivot); - index.getPageStore().update(page); - index.getPageStore().update(page2); - index.getPageStore().update(this); - } - updateRowCount(1); - written = false; - changeCount = index.getPageStore().getChangeCount(); - return -1; - } - - private void updateRowCount(int offset) { - if (rowCount != UNKNOWN_ROWCOUNT) { - rowCount += offset; - } - if (rowCountStored != UNKNOWN_ROWCOUNT) { - rowCountStored = UNKNOWN_ROWCOUNT; - index.getPageStore().logUndo(this, data); - if (written) { - writeHead(); - } - index.getPageStore().update(this); - } - } - - PageBtree split(int splitPoint) { - int newPageId = index.getPageStore().allocatePage(); - PageBtreeNode p2 = PageBtreeNode.create(index, newPageId, parentPageId); - index.getPageStore().logUndo(this, data); - if (onlyPosition) { - // TODO optimize: maybe not required - p2.onlyPosition = true; - } - int firstChild = childPageIds[splitPoint]; - readAllRows(); - for (int i = splitPoint; i < entryCount;) { - p2.addChild(p2.entryCount, childPageIds[splitPoint + 1], getRow(splitPoint)); - removeChild(splitPoint); - } - int lastChild = childPageIds[splitPoint - 1]; - removeChild(splitPoint - 1); - childPageIds[splitPoint - 1] = lastChild; - if (p2.childPageIds == null) { - p2.childPageIds = new int[1]; - } - p2.childPageIds[0] = firstChild; - p2.remapChildren(); - return p2; - } - - protected void remapChildren() { - for (int child : childPageIds) { - PageBtree p = index.getPage(child); - p.setParentPageId(getPos()); - index.getPageStore().update(p); - } - } - - /** - * Initialize the page. - * - * @param page1 the first child page - * @param pivot the pivot key - * @param page2 the last child page - */ - void init(PageBtree page1, SearchRow pivot, PageBtree page2) { - entryCount = 0; - childPageIds = new int[] { page1.getPos() }; - rows = new SearchRow[0]; - offsets = Utils.EMPTY_INT_ARRAY; - addChild(0, page2.getPos(), pivot); - if (SysProperties.PAGE_STORE_INTERNAL_COUNT) { - rowCount = page1.getRowCount() + page2.getRowCount(); - } - check(); - } - - void find(PageBtreeCursor cursor, SearchRow first, boolean bigger) { - int i = find(first, bigger, false, false); - if (i > entryCount) { - if (parentPageId == PageBtree.ROOT) { - return; - } - PageBtreeNode next = (PageBtreeNode) index.getPage(parentPageId); - next.find(cursor, first, bigger); - return; - } - PageBtree page = index.getPage(childPageIds[i]); - page.find(cursor, first, bigger); - } - - void last(PageBtreeCursor cursor) { - int child = childPageIds[entryCount]; - index.getPage(child).last(cursor); - } - - PageBtreeLeaf getFirstLeaf() { - int child = childPageIds[0]; - return index.getPage(child).getFirstLeaf(); - } - - PageBtreeLeaf getLastLeaf() { - int child = childPageIds[entryCount]; - return index.getPage(child).getLastLeaf(); - } - - SearchRow remove(SearchRow row) { - int at = find(row, false, false, true); - // merge is not implemented to allow concurrent usage - // TODO maybe implement merge - PageBtree page = index.getPage(childPageIds[at]); - SearchRow last = page.remove(row); - index.getPageStore().logUndo(this, data); - updateRowCount(-1); - written = false; - changeCount = index.getPageStore().getChangeCount(); - if (last == null) { - // the last row didn't change - nothing to do - return null; - } else if (last == row) { - // this child is now empty - index.getPageStore().free(page.getPos()); - if (entryCount < 1) { - // no more children - this page is empty as well - return row; - } - if (at == entryCount) { - // removing the last child - last = getRow(at - 1); - } else { - last = null; - } - removeChild(at); - index.getPageStore().update(this); - return last; - } - // the last row is in the last child - if (at == entryCount) { - return last; - } - int child = childPageIds[at]; - removeChild(at); - // TODO this can mean only the position is now stored - // should split at the next possible moment - addChild(at, child, last); - // remove and add swapped two children, fix that - int temp = childPageIds[at]; - childPageIds[at] = childPageIds[at + 1]; - childPageIds[at + 1] = temp; - index.getPageStore().update(this); - return null; - } - - int getRowCount() { - if (rowCount == UNKNOWN_ROWCOUNT) { - int count = 0; - for (int child : childPageIds) { - PageBtree page = index.getPage(child); - count += page.getRowCount(); - index.getDatabase().setProgress(DatabaseEventListener.STATE_SCAN_FILE, index.getName(), count, Integer.MAX_VALUE); - } - rowCount = count; - } - return rowCount; - } - - void setRowCountStored(int rowCount) { - if (rowCount < 0 && SysProperties.PAGE_STORE_INTERNAL_COUNT) { - return; - } - this.rowCount = rowCount; - if (rowCountStored != rowCount) { - rowCountStored = rowCount; - index.getPageStore().logUndo(this, data); - if (written) { - changeCount = index.getPageStore().getChangeCount(); - writeHead(); - } - index.getPageStore().update(this); - } - } - - private void check() { - for (int child : childPageIds) { - if (child == 0) { - DbException.throwInternalError(); - } - } - } - - public void write() { - check(); - writeData(); - index.getPageStore().writePage(getPos(), data); - } - - private void writeHead() { - data.reset(); - data.writeByte((byte) (Page.TYPE_BTREE_NODE | (onlyPosition ? 0 : Page.FLAG_LAST))); - data.writeShortInt(0); - data.writeInt(parentPageId); - data.writeVarInt(index.getId()); - data.writeInt(rowCountStored); - data.writeShortInt(entryCount); - } - - private void writeData() { - if (written) { - return; - } - readAllRows(); - writeHead(); - data.writeInt(childPageIds[entryCount]); - for (int i = 0; i < entryCount; i++) { - data.writeInt(childPageIds[i]); - data.writeShortInt(offsets[i]); - } - for (int i = 0; i < entryCount; i++) { - index.writeRow(data, offsets[i], rows[i], onlyPosition); - } - written = true; - } - - void freeRecursive() { - index.getPageStore().logUndo(this, data); - index.getPageStore().free(getPos()); - for (int childPageId : childPageIds) { - index.getPage(childPageId).freeRecursive(); - } - } - - private void removeChild(int i) { - readAllRows(); - entryCount--; - if (SysProperties.PAGE_STORE_INTERNAL_COUNT) { - updateRowCount(-index.getPage(childPageIds[i]).getRowCount()); - } - written = false; - changeCount = index.getPageStore().getChangeCount(); - if (entryCount < 0) { - DbException.throwInternalError(); - } - SearchRow[] newRows = PageStore.newSearchRows(entryCount); - int[] newOffsets = Utils.newIntArray(entryCount); - int[] newChildPageIds = new int[entryCount + 1]; - System.arraycopy(offsets, 0, newOffsets, 0, Math.min(entryCount, i)); - System.arraycopy(rows, 0, newRows, 0, Math.min(entryCount, i)); - System.arraycopy(childPageIds, 0, newChildPageIds, 0, i); - if (entryCount > i) { - System.arraycopy(rows, i + 1, newRows, i, entryCount - i); - int startNext = i > 0 ? offsets[i - 1] : index.getPageStore().getPageSize(); - int rowLength = startNext - offsets[i]; - for (int j = i; j < entryCount; j++) { - newOffsets[j] = offsets[j + 1] + rowLength; - } - } - System.arraycopy(childPageIds, i + 1, newChildPageIds, i, entryCount - i + 1); - offsets = newOffsets; - rows = newRows; - childPageIds = newChildPageIds; - start -= CHILD_OFFSET_PAIR_LENGTH; - } - - /** - * Set the cursor to the first row of the next page. - * - * @param cursor the cursor - * @param ROW the current row - */ - void nextPage(PageBtreeCursor cursor, int pageId) { - int i; - // TODO maybe keep the index in the child page (transiently) - for (i = 0; i < childPageIds.length; i++) { - if (childPageIds[i] == pageId) { - i++; - break; - } - } - if (i > entryCount) { - if (parentPageId == PageBtree.ROOT) { - cursor.setCurrent(null, 0); - return; - } - PageBtreeNode next = (PageBtreeNode) index.getPage(parentPageId); - next.nextPage(cursor, getPos()); - return; - } - PageBtree page = index.getPage(childPageIds[i]); - PageBtreeLeaf leaf = page.getFirstLeaf(); - cursor.setCurrent(leaf, 0); - } - - /** - * Set the cursor to the last row of the previous page. - * - * @param cursor the cursor - * @param ROW the current row - */ - void previousPage(PageBtreeCursor cursor, int pageId) { - int i; - // TODO maybe keep the index in the child page (transiently) - for (i = childPageIds.length - 1; i >= 0; i--) { - if (childPageIds[i] == pageId) { - i--; - break; - } - } - if (i < 0) { - if (parentPageId == PageBtree.ROOT) { - cursor.setCurrent(null, 0); - return; - } - PageBtreeNode previous = (PageBtreeNode) index.getPage(parentPageId); - previous.previousPage(cursor, getPos()); - return; - } - PageBtree page = index.getPage(childPageIds[i]); - PageBtreeLeaf leaf = page.getLastLeaf(); - cursor.setCurrent(leaf, leaf.entryCount - 1); - } - - - public String toString() { - return "page[" + getPos() + "] b-tree node table:" + index.getId() + " entries:" + entryCount; - } - - public void moveTo(Session session, int newPos) { - PageStore store = index.getPageStore(); - store.logUndo(this, data); - PageBtreeNode p2 = PageBtreeNode.create(index, newPos, parentPageId); - readAllRows(); - p2.rowCountStored = rowCountStored; - p2.rowCount = rowCount; - p2.childPageIds = childPageIds; - p2.rows = rows; - p2.entryCount = entryCount; - p2.offsets = offsets; - p2.onlyPosition = onlyPosition; - p2.parentPageId = parentPageId; - p2.start = start; - store.update(p2); - if (parentPageId == ROOT) { - index.setRootPageId(session, newPos); - } else { - Page p = store.getPage(parentPageId); - if (!(p instanceof PageBtreeNode)) { - throw DbException.throwInternalError(); - } - PageBtreeNode n = (PageBtreeNode) p; - n.moveChild(getPos(), newPos); - } - for (int childPageId : childPageIds) { - PageBtree p = index.getPage(childPageId); - p.setParentPageId(newPos); - store.update(p); - } - store.free(getPos()); - } - - /** - * One of the children has moved to a new page. - * - * @param oldPos the old position - * @param newPos the new position - */ - void moveChild(int oldPos, int newPos) { - for (int i = 0; i < childPageIds.length; i++) { - if (childPageIds[i] == oldPos) { - index.getPageStore().logUndo(this, data); - written = false; - changeCount = index.getPageStore().getChangeCount(); - childPageIds[i] = newPos; - index.getPageStore().update(this); - return; - } - } - throw DbException.throwInternalError(); - } - -} \ No newline at end of file diff --git a/tools/h2/src/main/org/h2/index/PageData.java b/tools/h2/src/main/org/h2/index/PageData.java deleted file mode 100755 index af2bbef..0000000 --- a/tools/h2/src/main/org/h2/index/PageData.java +++ /dev/null @@ -1,234 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.index; - -import org.h2.engine.Session; -import org.h2.result.Row; -import org.h2.store.Data; -import org.h2.store.Page; - -/** - * A page that contains data rows. - */ -abstract class PageData extends Page { - - /** - * The position of the parent page id. - */ - static final int START_PARENT = 3; - - /** - * This is a root page. - */ - static final int ROOT = 0; - - /** - * Indicator that the row count is not known. - */ - static final int UNKNOWN_ROWCOUNT = -1; - - /** - * The index. - */ - protected final PageDataIndex index; - - /** - * The page number of the parent. - */ - protected int parentPageId; - - /** - * The data page. - */ - protected final Data data; - - /** - * The number of entries. - */ - protected int entryCount; - - /** - * The row keys. - */ - protected long[] keys; - - /** - * Whether the data page is up-to-date. - */ - protected boolean written; - - PageData(PageDataIndex index, int pageId, Data data) { - this.index = index; - this.data = data; - setPos(pageId); - } - - /** - * Get the real row count. If required, this will read all child pages. - * - * @return the row count - */ - abstract int getRowCount(); - - /** - * Set the stored row count. This will write the page. - * - * @param rowCount the stored row count - */ - abstract void setRowCountStored(int rowCount); - - /** - * Find an entry by key. - * - * @param key the key (may not exist) - * @return the matching or next index - */ - int find(long key) { - int l = 0, r = entryCount; - while (l < r) { - int i = (l + r) >>> 1; - long k = keys[i]; - if (k == key) { - return i; - } else if (k > key) { - r = i; - } else { - l = i + 1; - } - } - return l; - } - - /** - * Add a row if possible. If it is possible this method returns -1, otherwise - * the split point. It is always possible to add one row. - * - * @param row the now to add - * @return the split point of this page, or -1 if no split is required - */ - abstract int addRowTry(Row row); - - /** - * Get a cursor. - * - * @param session the session - * @param min the smallest key - * @param max the largest key - * @param multiVersion if the delta should be used - * @return the cursor - */ - abstract Cursor find(Session session, long min, long max, boolean multiVersion); - - /** - * Get the key at this position. - * - * @param at the index - * @return the key - */ - long getKey(int at) { - return keys[at]; - } - - /** - * Split the index page at the given point. - * - * @param splitPoint the index where to split - * @return the new page that contains about half the entries - */ - abstract PageData split(int splitPoint); - - /** - * Change the page id. - * - * @param id the new page id - */ - void setPageId(int id) { - int old = getPos(); - index.getPageStore().removeRecord(getPos()); - setPos(id); - index.getPageStore().logUndo(this, null); - remapChildren(old); - } - - /** - * Get the last key of a page. - * - * @return the last key - */ - abstract long getLastKey(); - - /** - * Get the first child leaf page of a page. - * - * @return the page - */ - abstract PageDataLeaf getFirstLeaf(); - - /** - * Change the parent page id. - * - * @param id the new parent page id - */ - void setParentPageId(int id) { - index.getPageStore().logUndo(this, data); - parentPageId = id; - if (written) { - changeCount = index.getPageStore().getChangeCount(); - data.setInt(START_PARENT, parentPageId); - } - } - - /** - * Update the parent id of all children. - * - * @param old the previous position - */ - abstract void remapChildren(int old); - - /** - * Remove a row. - * - * @param key the key of the row to remove - * @return true if this page is now empty - */ - abstract boolean remove(long key); - - /** - * Free this page and all child pages. - */ - abstract void freeRecursive(); - - /** - * Get the row for the given key. - * - * @param key the key - * @return the row - */ - abstract Row getRow(long key); - - /** - * Get the estimated memory size. - * - * @return number of double words (4 bytes) - */ - public int getMemorySize() { - // four times the byte array size - return index.getPageStore().getPageSize(); - } - - int getParentPageId() { - return parentPageId; - } - - public boolean canRemove() { - if (changeCount >= index.getPageStore().getChangeCount()) { - return false; - } - return true; - } - -} diff --git a/tools/h2/src/main/org/h2/index/PageDataCursor.java b/tools/h2/src/main/org/h2/index/PageDataCursor.java deleted file mode 100755 index f206ea0..0000000 --- a/tools/h2/src/main/org/h2/index/PageDataCursor.java +++ /dev/null @@ -1,105 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.index; - -import java.util.Iterator; -import org.h2.engine.Session; -import org.h2.message.DbException; -import org.h2.result.Row; -import org.h2.result.SearchRow; - -/** - * The cursor implementation for the page scan index. - */ -class PageDataCursor implements Cursor { - - private PageDataLeaf current; - private int idx; - private final long max; - private Row row; - private final boolean multiVersion; - private final Session session; - private Iterator delta; - - PageDataCursor(Session session, PageDataLeaf current, int idx, long max, boolean multiVersion) { - this.current = current; - this.idx = idx; - this.max = max; - this.multiVersion = multiVersion; - this.session = session; - if (multiVersion) { - delta = current.index.getDelta(); - } - } - - public Row get() { - return row; - } - - public SearchRow getSearchRow() { - return get(); - } - - public boolean next() { - if (!multiVersion) { - nextRow(); - return checkMax(); - } - while (true) { - if (delta != null) { - if (!delta.hasNext()) { - delta = null; - row = null; - continue; - } - row = delta.next(); - if (!row.isDeleted() || row.getSessionId() == session.getId()) { - continue; - } - } else { - nextRow(); - if (row != null && row.getSessionId() != 0 && row.getSessionId() != session.getId()) { - continue; - } - } - break; - } - return checkMax(); - } - - private boolean checkMax() { - if (row != null) { - if (max != Long.MAX_VALUE) { - long x = current.index.getLong(row, Long.MAX_VALUE); - if (x > max) { - row = null; - return false; - } - } - return true; - } - return false; - } - - private void nextRow() { - if (idx >= current.getEntryCount()) { - current = current.getNextPage(); - idx = 0; - if (current == null) { - row = null; - return; - } - } - row = current.getRowAt(idx); - idx++; - } - - public boolean previous() { - throw DbException.throwInternalError(); - } - -} diff --git a/tools/h2/src/main/org/h2/index/PageDataIndex.java b/tools/h2/src/main/org/h2/index/PageDataIndex.java deleted file mode 100755 index 6992e45..0000000 --- a/tools/h2/src/main/org/h2/index/PageDataIndex.java +++ /dev/null @@ -1,523 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.index; - -import java.util.Collections; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Iterator; -import java.util.List; -import org.h2.constant.ErrorCode; -import org.h2.engine.Constants; -import org.h2.engine.Session; -import org.h2.engine.UndoLogRecord; -import org.h2.message.DbException; -import org.h2.result.Row; -import org.h2.result.SearchRow; -import org.h2.store.Data; -import org.h2.store.Page; -import org.h2.store.PageStore; -import org.h2.table.Column; -import org.h2.table.IndexColumn; -import org.h2.table.RegularTable; -import org.h2.util.MathUtils; -import org.h2.util.New; -import org.h2.value.Value; -import org.h2.value.ValueNull; - -/** - * The scan index allows to access a row by key. It can be used to iterate over - * all rows of a table. Each regular table has one such object, even if no - * primary key or indexes are defined. - */ -public class PageDataIndex extends PageIndex { - - private PageStore store; - private RegularTable tableData; - private long lastKey; - private long rowCount; - private HashSet delta; - private int rowCountDiff; - private HashMap sessionRowCount; - private int mainIndexColumn = -1; - private DbException fastDuplicateKeyException; - private int memorySizePerPage; - - public PageDataIndex(RegularTable table, int id, IndexColumn[] columns, IndexType indexType, boolean create, Session session) { - initBaseIndex(table, id, table.getName() + "_DATA", columns, indexType); - - // trace = database.getTrace(Trace.PAGE_STORE + "_di"); - // trace.setLevel(TraceSystem.DEBUG); - if (database.isMultiVersion()) { - sessionRowCount = New.hashMap(); - isMultiVersion = true; - } - tableData = table; - this.store = database.getPageStore(); - store.addIndex(this); - if (!database.isPersistent()) { - throw DbException.throwInternalError(table.getName()); - } - if (create) { - rootPageId = store.allocatePage(); - store.addMeta(this, session); - PageDataLeaf root = PageDataLeaf.create(this, rootPageId, PageData.ROOT); - store.update(root); - } else { - rootPageId = store.getRootPageId(id); - PageData root = getPage(rootPageId, 0); - lastKey = root.getLastKey(); - rowCount = root.getRowCount(); - } - if (trace.isDebugEnabled()) { - trace.debug(this + " opened rows:" + rowCount); - } - table.setRowCount(rowCount); - // estimate the memory usage as follows: - // the less column, the more memory is required, - // because the more rows fit on a page - memorySizePerPage = store.getPageSize(); - int estimatedRowsPerPage = store.getPageSize() / ((1 + columns.length) * 8); - memorySizePerPage += estimatedRowsPerPage * 64; - } - - public DbException getDuplicateKeyException() { - if (fastDuplicateKeyException == null) { - fastDuplicateKeyException = super.getDuplicateKeyException(); - } - return fastDuplicateKeyException; - } - - public void add(Session session, Row row) { - boolean retry = false; - if (mainIndexColumn != -1) { - row.setKey(row.getValue(mainIndexColumn).getLong()); - } else { - if (row.getKey() == 0) { - row.setKey((int) ++lastKey); - retry = true; - } - } - if (tableData.getContainsLargeObject()) { - for (int i = 0; i < row.getColumnCount(); i++) { - Value v = row.getValue(i); - Value v2 = v.link(database, getId()); - if (v2.isLinked()) { - session.unlinkAtCommitStop(v2); - } - if (v != v2) { - row.setValue(i, v2); - } - } - } - // when using auto-generated values, it's possible that multiple - // tries are required (specially if there was originally a primary key) - if (trace.isDebugEnabled()) { - trace.debug(getName() + " add " + row); - } - long add = 0; - while (true) { - try { - addTry(session, row); - break; - } catch (DbException e) { - if (e != fastDuplicateKeyException) { - throw e; - } - if (!retry) { - throw super.getDuplicateKeyException(); - } - if (add == 0) { - // in the first re-try add a small random number, - // to avoid collisions after a re-start - row.setKey((long) (row.getKey() + Math.random() * 10000)); - } else { - row.setKey(row.getKey() + add); - } - add++; - } finally { - store.incrementChangeCount(); - } - } - lastKey = Math.max(lastKey, row.getKey() + 1); - } - - private void addTry(Session session, Row row) { - while (true) { - PageData root = getPage(rootPageId, 0); - int splitPoint = root.addRowTry(row); - if (splitPoint == -1) { - break; - } - if (trace.isDebugEnabled()) { - trace.debug(this + " split"); - } - long pivot = splitPoint == 0 ? row.getKey() : root.getKey(splitPoint - 1); - PageData page1 = root; - PageData page2 = root.split(splitPoint); - int id = store.allocatePage(); - page1.setPageId(id); - page1.setParentPageId(rootPageId); - page2.setParentPageId(rootPageId); - PageDataNode newRoot = PageDataNode.create(this, rootPageId, PageData.ROOT); - newRoot.init(page1, pivot, page2); - store.update(page1); - store.update(page2); - store.update(newRoot); - root = newRoot; - } - row.setDeleted(false); - if (database.isMultiVersion()) { - if (delta == null) { - delta = New.hashSet(); - } - boolean wasDeleted = delta.remove(row); - if (!wasDeleted) { - delta.add(row); - } - incrementRowCount(session.getId(), 1); - } - invalidateRowCount(); - rowCount++; - store.logAddOrRemoveRow(session, tableData.getId(), row, true); - } - - /** - * Read an overflow page page. - * - * @param id the page id - * @return the page - */ - PageDataOverflow getPageOverflow(int id) { - Page p = store.getPage(id); - if (p instanceof PageDataOverflow) { - return (PageDataOverflow) p; - } - throw DbException.get(ErrorCode.FILE_CORRUPTED_1, p.toString()); - } - - /** - * Read the given page. - * - * @param id the page id - * @param parent the parent, or -1 if unknown - * @return the page - */ - PageData getPage(int id, int parent) { - Page pd = store.getPage(id); - if (pd == null) { - PageDataLeaf empty = PageDataLeaf.create(this, id, parent); - // could have been created before, but never committed - store.logUndo(empty, null); - store.update(empty); - return empty; - } else if (!(pd instanceof PageData)) { - throw DbException.get(ErrorCode.FILE_CORRUPTED_1, "" + pd); - } - PageData p = (PageData) pd; - if (parent != -1) { - if (p.getParentPageId() != parent) { - throw DbException.throwInternalError(p + " parent " + p.getParentPageId() + " expected " + parent); - } - } - return p; - } - - public boolean canGetFirstOrLast() { - return false; - } - - /** - * Get the key from the row - * - * @param row the row - * @param ifEmpty the value to use if the row is empty - * @return the key - */ - long getLong(SearchRow row, long ifEmpty) { - if (row == null) { - return ifEmpty; - } - Value v = row.getValue(mainIndexColumn); - if (v == null || v == ValueNull.INSTANCE) { - return ifEmpty; - } - return v.getLong(); - } - - public Cursor find(Session session, SearchRow first, SearchRow last) { - if (first != null || last != null) { - // this index is a table scan, must not use it for lookup - throw DbException.throwInternalError(getSQL() + " " + first + " " + last); - } - PageData root = getPage(rootPageId, 0); - return root.find(session, Long.MIN_VALUE, Long.MAX_VALUE, isMultiVersion); - } - - /** - * Search for a specific row or a set of rows. - * - * @param session the session - * @param first the key of the first row - * @param last the key of the last row - * @param multiVersion if mvcc should be used - * @return the cursor - */ - Cursor find(Session session, long first, long last, boolean multiVersion) { - PageData root = getPage(rootPageId, 0); - return root.find(session, first, last, multiVersion); - } - - public Cursor findFirstOrLast(Session session, boolean first) { - throw DbException.throwInternalError(); - } - - long getLastKey() { - PageData root = getPage(rootPageId, 0); - return root.getLastKey(); - } - - public double getCost(Session session, int[] masks) { - long cost = 10 * (tableData.getRowCountApproximation() + Constants.COST_ROW_OFFSET); - return cost; - } - - public boolean needRebuild() { - return false; - } - - public void remove(Session session, Row row) { - if (tableData.getContainsLargeObject()) { - for (int i = 0; i < row.getColumnCount(); i++) { - Value v = row.getValue(i); - if (v.isLinked()) { - session.unlinkAtCommit(v); - } - } - } - if (trace.isDebugEnabled()) { - trace.debug(getName() + " remove " + row); - } - if (rowCount == 1) { - removeAllRows(); - } else { - try { - long key = row.getKey(); - PageData root = getPage(rootPageId, 0); - root.remove(key); - invalidateRowCount(); - rowCount--; - } finally { - store.incrementChangeCount(); - } - } - if (database.isMultiVersion()) { - // if storage is null, the delete flag is not yet set - row.setDeleted(true); - if (delta == null) { - delta = New.hashSet(); - } - boolean wasAdded = delta.remove(row); - if (!wasAdded) { - delta.add(row); - } - incrementRowCount(session.getId(), -1); - } - store.logAddOrRemoveRow(session, tableData.getId(), row, false); - } - - public void remove(Session session) { - if (trace.isDebugEnabled()) { - trace.debug(this + " remove"); - } - removeAllRows(); - store.free(rootPageId); - store.removeMeta(this, session); - } - - public void truncate(Session session) { - if (trace.isDebugEnabled()) { - trace.debug(this + " truncate"); - } - store.logTruncate(session, tableData.getId()); - removeAllRows(); - if (tableData.getContainsLargeObject() && tableData.isPersistData()) { - database.getLobStorage().removeAllForTable(table.getId()); - } - if (database.isMultiVersion()) { - sessionRowCount.clear(); - } - tableData.setRowCount(0); - } - - private void removeAllRows() { - try { - PageData root = getPage(rootPageId, 0); - root.freeRecursive(); - root = PageDataLeaf.create(this, rootPageId, PageData.ROOT); - store.removeRecord(rootPageId); - store.update(root); - rowCount = 0; - lastKey = 0; - } finally { - store.incrementChangeCount(); - } - } - - public void checkRename() { - throw DbException.getUnsupportedException("PAGE"); - } - - public Row getRow(Session session, long key) { - return getRow(key); - } - - /** - * Get the row with the given key. - * - * @param key the key - * @return the row - */ - public Row getRow(long key) { - PageData root = getPage(rootPageId, 0); - return root.getRow(key); - } - - PageStore getPageStore() { - return store; - } - - /** - * Read a row from the data page at the given position. - * - * @param data the data page - * @param columnCount the number of columns - * @return the row - */ - Row readRow(Data data, int columnCount) { - Value[] values = new Value[columnCount]; - for (int i = 0; i < columnCount; i++) { - values[i] = data.readValue(); - } - return tableData.createRow(values); - } - - public long getRowCountApproximation() { - return rowCount; - } - - public long getRowCount(Session session) { - if (database.isMultiVersion()) { - Integer i = sessionRowCount.get(session.getId()); - long count = i == null ? 0 : i.intValue(); - count += rowCount; - count -= rowCountDiff; - return count; - } - return rowCount; - } - - public String getCreateSQL() { - return null; - } - - public int getColumnIndex(Column col) { - // can not use this index - use the PageDelegateIndex instead - return -1; - } - - public void close(Session session) { - if (trace.isDebugEnabled()) { - trace.debug(this + " close"); - } - if (delta != null) { - delta.clear(); - } - rowCountDiff = 0; - if (sessionRowCount != null) { - sessionRowCount.clear(); - } - // can not close the index because it might get used afterwards, - // for example after running recovery - writeRowCount(); - } - - Iterator getDelta() { - if (delta == null) { - List e = Collections.emptyList(); - return e.iterator(); - } - return delta.iterator(); - } - - private void incrementRowCount(int sessionId, int count) { - if (database.isMultiVersion()) { - Integer id = sessionId; - Integer c = sessionRowCount.get(id); - int current = c == null ? 0 : c.intValue(); - sessionRowCount.put(id, current + count); - rowCountDiff += count; - } - } - - public void commit(int operation, Row row) { - if (database.isMultiVersion()) { - if (delta != null) { - delta.remove(row); - } - incrementRowCount(row.getSessionId(), operation == UndoLogRecord.DELETE ? 1 : -1); - } - } - - /** - * The root page has changed. - * - * @param session the session - * @param newPos the new position - */ - void setRootPageId(Session session, int newPos) { - store.removeMeta(this, session); - this.rootPageId = newPos; - store.addMeta(this, session); - store.addIndex(this); - } - - public void setMainIndexColumn(int mainIndexColumn) { - this.mainIndexColumn = mainIndexColumn; - } - - public int getMainIndexColumn() { - return mainIndexColumn; - } - - int getMemorySizePerPage() { - return memorySizePerPage; - } - - public String toString() { - return getName(); - } - - private void invalidateRowCount() { - PageData root = getPage(rootPageId, 0); - root.setRowCountStored(PageData.UNKNOWN_ROWCOUNT); - } - - public void writeRowCount() { - try { - PageData root = getPage(rootPageId, 0); - root.setRowCountStored(MathUtils.convertLongToInt(rowCount)); - } finally { - store.incrementChangeCount(); - } - } - - public String getPlanSQL() { - return table.getSQL() + ".tableScan"; - } - -} diff --git a/tools/h2/src/main/org/h2/index/PageDataLeaf.java b/tools/h2/src/main/org/h2/index/PageDataLeaf.java deleted file mode 100755 index 12b7263..0000000 --- a/tools/h2/src/main/org/h2/index/PageDataLeaf.java +++ /dev/null @@ -1,558 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.index; - -import java.lang.ref.SoftReference; -import java.util.Arrays; -import org.h2.constant.ErrorCode; -import org.h2.constant.SysProperties; -import org.h2.engine.Session; -import org.h2.message.DbException; -import org.h2.result.Row; -import org.h2.store.Data; -import org.h2.store.Page; -import org.h2.store.PageStore; - -/** - * A leaf page that contains data of one or multiple rows. Format: - *
    - *
  • page type: byte (0)
  • - *
  • checksum: short (1-2)
  • - *
  • parent page id (0 for root): int (3-6)
  • - *
  • table id: varInt
  • - *
  • column count: varInt
  • - *
  • entry count: short
  • - *
  • with overflow: the first overflow page id: int
  • - *
  • list of key / offset pairs (key: varLong, offset: shortInt)
  • - *
  • data
  • - *
- */ -public class PageDataLeaf extends PageData { - - /** - * The row offsets. - */ - private int[] offsets; - - /** - * The rows. - */ - private Row[] rows; - - /** - * For pages with overflow: the soft reference to the row - */ - private SoftReference rowRef; - - /** - * The page id of the first overflow page (0 if no overflow). - */ - private int firstOverflowPageId; - - /** - * The start of the data area. - */ - private int start; - - /** - * The size of the row in bytes for large rows. - */ - private int overflowRowSize; - - private int columnCount; - - private int memorySize; - - private PageDataLeaf(PageDataIndex index, int pageId, Data data) { - super(index, pageId, data); - } - - /** - * Create a new page. - * - * @param index the index - * @param pageId the page id - * @param parentPageId the parent - * @return the page - */ - static PageDataLeaf create(PageDataIndex index, int pageId, int parentPageId) { - PageDataLeaf p = new PageDataLeaf(index, pageId, index.getPageStore().createData()); - index.getPageStore().logUndo(p, null); - p.parentPageId = parentPageId; - p.columnCount = index.getTable().getColumns().length; - p.writeHead(); - p.start = p.data.length(); - return p; - } - - /** - * Read a data leaf page. - * - * @param index the index - * @param data the data - * @param pageId the page id - * @return the page - */ - public static Page read(PageDataIndex index, Data data, int pageId) { - PageDataLeaf p = new PageDataLeaf(index, pageId, data); - p.read(); - return p; - } - - private void read() { - data.reset(); - int type = data.readByte(); - data.readShortInt(); - this.parentPageId = data.readInt(); - int tableId = data.readVarInt(); - if (tableId != index.getId()) { - throw DbException.get(ErrorCode.FILE_CORRUPTED_1, - "page:" + getPos() + " expected table:" + index.getId() + - " got:" + tableId + " type:" + type); - } - columnCount = data.readVarInt(); - entryCount = data.readShortInt(); - offsets = new int[entryCount]; - keys = new long[entryCount]; - rows = new Row[entryCount]; - if (type == Page.TYPE_DATA_LEAF) { - if (entryCount != 1) { - DbException.throwInternalError("entries: " + entryCount); - } - firstOverflowPageId = data.readInt(); - } - for (int i = 0; i < entryCount; i++) { - keys[i] = data.readVarLong(); - offsets[i] = data.readShortInt(); - } - start = data.length(); - written = true; - } - - private int getRowLength(Row row) { - int size = 0; - for (int i = 0; i < columnCount; i++) { - size += data.getValueLen(row.getValue(i)); - } - return size; - } - - private int findInsertionPoint(long key) { - int x = find(key); - if (x < keys.length && keys[x] == key) { - throw index.getDuplicateKeyException(); - } - return x; - } - - int addRowTry(Row row) { - index.getPageStore().logUndo(this, data); - int rowLength = getRowLength(row); - int pageSize = index.getPageStore().getPageSize(); - int last = entryCount == 0 ? pageSize : offsets[entryCount - 1]; - int keyOffsetPairLen = 2 + Data.getVarLongLen(row.getKey()); - if (entryCount > 0 && last - rowLength < start + keyOffsetPairLen) { - int x = findInsertionPoint(row.getKey()); - if (entryCount > 1) { - if (entryCount < 5) { - // required, otherwise the index doesn't work correctly - return entryCount / 2; - } - if (index.isSortedInsertMode()) { - return x < 2 ? 1 : x > entryCount - 1 ? entryCount - 1 : x; - } - // split near the insertion point to better fill pages - // split in half would be: - // return entryCount / 2; - int third = entryCount / 3; - return x < third ? third : x >= 2 * third ? 2 * third : x; - } - return x; - } - index.getPageStore().logUndo(this, data); - int offset = last - rowLength; - int[] newOffsets = new int[entryCount + 1]; - long[] newKeys = new long[entryCount + 1]; - Row[] newRows = new Row[entryCount + 1]; - int x; - if (entryCount == 0) { - x = 0; - } else { - readAllRows(); - x = findInsertionPoint(row.getKey()); - System.arraycopy(offsets, 0, newOffsets, 0, x); - System.arraycopy(keys, 0, newKeys, 0, x); - System.arraycopy(rows, 0, newRows, 0, x); - if (x < entryCount) { - for (int j = x; j < entryCount; j++) { - newOffsets[j + 1] = offsets[j] - rowLength; - } - System.arraycopy(keys, x, newKeys, x + 1, entryCount - x); - System.arraycopy(rows, x, newRows, x + 1, entryCount - x); - } - } - written = false; - changeCount = index.getPageStore().getChangeCount(); - last = x == 0 ? pageSize : offsets[x - 1]; - offset = last - rowLength; - entryCount++; - start += keyOffsetPairLen; - newOffsets[x] = offset; - newKeys[x] = row.getKey(); - newRows[x] = row; - memorySize += row.getMemorySize(); - offsets = newOffsets; - keys = newKeys; - rows = newRows; - index.getPageStore().update(this); - if (offset < start) { - if (entryCount > 1) { - DbException.throwInternalError(); - } - // need to write the overflow page id - start += 4; - int remaining = rowLength - (pageSize - start); - // fix offset - offset = start; - offsets[x] = offset; - int previous = getPos(); - int dataOffset = pageSize; - int page = index.getPageStore().allocatePage(); - firstOverflowPageId = page; - this.overflowRowSize = pageSize + rowLength; - writeData(); - // free up the space used by the row - rowRef = new SoftReference(rows[0]); - rows[0] = null; - Data all = index.getPageStore().createData(); - all.checkCapacity(data.length()); - all.write(data.getBytes(), 0, data.length()); - data.truncate(index.getPageStore().getPageSize()); - do { - int type, size, next; - if (remaining <= pageSize - PageDataOverflow.START_LAST) { - type = Page.TYPE_DATA_OVERFLOW | Page.FLAG_LAST; - size = remaining; - next = 0; - } else { - type = Page.TYPE_DATA_OVERFLOW; - size = pageSize - PageDataOverflow.START_MORE; - next = index.getPageStore().allocatePage(); - } - PageDataOverflow overflow = PageDataOverflow.create(index.getPageStore(), page, type, previous, next, all, dataOffset, size); - index.getPageStore().update(overflow); - dataOffset += size; - remaining -= size; - previous = page; - page = next; - } while (remaining > 0); - } - return -1; - } - - private void removeRow(int i) { - index.getPageStore().logUndo(this, data); - written = false; - changeCount = index.getPageStore().getChangeCount(); - readAllRows(); - Row r = rows[i]; - if (r != null) { - memorySize += r.getMemorySize(); - } - entryCount--; - if (entryCount < 0) { - DbException.throwInternalError(); - } - freeOverflow(); - firstOverflowPageId = 0; - overflowRowSize = 0; - rowRef = null; - int keyOffsetPairLen = 2 + Data.getVarLongLen(keys[i]); - int[] newOffsets = new int[entryCount]; - long[] newKeys = new long[entryCount]; - Row[] newRows = new Row[entryCount]; - System.arraycopy(offsets, 0, newOffsets, 0, i); - System.arraycopy(keys, 0, newKeys, 0, i); - System.arraycopy(rows, 0, newRows, 0, i); - int startNext = i > 0 ? offsets[i - 1] : index.getPageStore().getPageSize(); - int rowLength = startNext - offsets[i]; - int clearStart = offsets[entryCount]; - Arrays.fill(data.getBytes(), clearStart, clearStart + rowLength, (byte) 0); - for (int j = i; j < entryCount; j++) { - newOffsets[j] = offsets[j + 1] + rowLength; - } - System.arraycopy(keys, i + 1, newKeys, i, entryCount - i); - System.arraycopy(rows, i + 1, newRows, i, entryCount - i); - start -= keyOffsetPairLen; - offsets = newOffsets; - keys = newKeys; - rows = newRows; - } - - Cursor find(Session session, long min, long max, boolean multiVersion) { - int x = find(min); - return new PageDataCursor(session, this, x, max, multiVersion); - } - - /** - * Get the row at the given index. - * - * @param at the index - * @return the row - */ - Row getRowAt(int at) { - Row r = rows[at]; - if (r == null) { - if (firstOverflowPageId == 0) { - data.setPos(offsets[at]); - r = index.readRow(data, columnCount); - } else { - if (rowRef != null) { - r = rowRef.get(); - if (r != null) { - return r; - } - } - PageStore store = index.getPageStore(); - Data buff = store.createData(); - int pageSize = store.getPageSize(); - int offset = offsets[at]; - buff.write(data.getBytes(), offset, pageSize - offset); - int next = firstOverflowPageId; - do { - PageDataOverflow page = index.getPageOverflow(next); - next = page.readInto(buff); - } while (next != 0); - overflowRowSize = pageSize + buff.length(); - buff.setPos(0); - r = index.readRow(buff, columnCount); - } - r.setKey(keys[at]); - if (firstOverflowPageId != 0) { - rowRef = new SoftReference(r); - } else { - rows[at] = r; - memorySize += r.getMemorySize(); - } - } - return r; - } - - int getEntryCount() { - return entryCount; - } - - PageData split(int splitPoint) { - int newPageId = index.getPageStore().allocatePage(); - PageDataLeaf p2 = PageDataLeaf.create(index, newPageId, parentPageId); - for (int i = splitPoint; i < entryCount;) { - int split = p2.addRowTry(getRowAt(splitPoint)); - if (split != -1) { - DbException.throwInternalError("split " + split); - } - removeRow(splitPoint); - } - return p2; - } - - long getLastKey() { - // TODO re-use keys, but remove this mechanism - if (entryCount == 0) { - return 0; - } - return getRowAt(entryCount - 1).getKey(); - } - - PageDataLeaf getNextPage() { - if (parentPageId == PageData.ROOT) { - return null; - } - PageDataNode next = (PageDataNode) index.getPage(parentPageId, -1); - return next.getNextPage(keys[entryCount - 1]); - } - - PageDataLeaf getFirstLeaf() { - return this; - } - - protected void remapChildren(int old) { - if (firstOverflowPageId == 0) { - return; - } - PageDataOverflow overflow = index.getPageOverflow(firstOverflowPageId); - overflow.setParentPageId(getPos()); - index.getPageStore().update(overflow); - } - - boolean remove(long key) { - int i = find(key); - if (keys[i] != key) { - throw DbException.get(ErrorCode.ROW_NOT_FOUND_WHEN_DELETING_1, index.getSQL() + ": " + key + " " + keys[i]); - } - index.getPageStore().logUndo(this, data); - if (entryCount == 1) { - freeRecursive(); - return true; - } - removeRow(i); - index.getPageStore().update(this); - return false; - } - - void freeRecursive() { - index.getPageStore().logUndo(this, data); - index.getPageStore().free(getPos()); - freeOverflow(); - } - - private void freeOverflow() { - if (firstOverflowPageId != 0) { - int next = firstOverflowPageId; - do { - PageDataOverflow page = index.getPageOverflow(next); - page.free(); - next = page.getNextOverflow(); - } while (next != 0); - } - } - - Row getRow(long key) { - int at = find(key); - return getRowAt(at); - } - - int getRowCount() { - return entryCount; - } - - void setRowCountStored(int rowCount) { - // ignore - } - - public void write() { - writeData(); - index.getPageStore().writePage(getPos(), data); - data.truncate(index.getPageStore().getPageSize()); - } - - private void readAllRows() { - for (int i = 0; i < entryCount; i++) { - getRowAt(i); - } - } - - private void writeHead() { - data.reset(); - int type; - if (firstOverflowPageId == 0) { - type = Page.TYPE_DATA_LEAF | Page.FLAG_LAST; - } else { - type = Page.TYPE_DATA_LEAF; - } - data.writeByte((byte) type); - data.writeShortInt(0); - if (SysProperties.CHECK2) { - if (data.length() != START_PARENT) { - DbException.throwInternalError(); - } - } - data.writeInt(parentPageId); - data.writeVarInt(index.getId()); - data.writeVarInt(columnCount); - data.writeShortInt(entryCount); - } - - private void writeData() { - if (written) { - return; - } - readAllRows(); - writeHead(); - if (firstOverflowPageId != 0) { - data.writeInt(firstOverflowPageId); - data.checkCapacity(overflowRowSize); - } - for (int i = 0; i < entryCount; i++) { - data.writeVarLong(keys[i]); - data.writeShortInt(offsets[i]); - } - for (int i = 0; i < entryCount; i++) { - data.setPos(offsets[i]); - Row r = getRowAt(i); - for (int j = 0; j < columnCount; j++) { - data.writeValue(r.getValue(j)); - } - } - written = true; - } - - public String toString() { - return "page[" + getPos() + "] data leaf table:" + index.getId() + - " entries:" + entryCount + " parent:" + parentPageId + - (firstOverflowPageId == 0 ? "" : " overflow:" + firstOverflowPageId) + - " keys:" + Arrays.toString(keys) + " offsets:" + Arrays.toString(offsets); - } - - public void moveTo(Session session, int newPos) { - PageStore store = index.getPageStore(); - // load the pages into the cache, to ensure old pages - // are written - if (parentPageId != ROOT) { - store.getPage(parentPageId); - } - store.logUndo(this, data); - PageDataLeaf p2 = PageDataLeaf.create(index, newPos, parentPageId); - readAllRows(); - p2.keys = keys; - p2.overflowRowSize = overflowRowSize; - p2.firstOverflowPageId = firstOverflowPageId; - p2.rowRef = rowRef; - p2.rows = rows; - if (firstOverflowPageId != 0) { - p2.rows[0] = getRowAt(0); - } - p2.entryCount = entryCount; - p2.offsets = offsets; - p2.start = start; - p2.remapChildren(getPos()); - p2.writeData(); - p2.data.truncate(index.getPageStore().getPageSize()); - store.update(p2); - store.free(getPos()); - if (parentPageId == ROOT) { - index.setRootPageId(session, newPos); - } else { - PageDataNode p = (PageDataNode) store.getPage(parentPageId); - p.moveChild(getPos(), newPos); - } - } - - /** - * Set the overflow page id. - * - * @param old the old overflow page id - * @param overflow the new overflow page id - */ - void setOverflow(int old, int overflow) { - if (SysProperties.CHECK && old != firstOverflowPageId) { - DbException.throwInternalError("move " + this + " " + firstOverflowPageId); - } - index.getPageStore().logUndo(this, data); - firstOverflowPageId = overflow; - if (written) { - changeCount = index.getPageStore().getChangeCount(); - writeHead(); - data.writeInt(firstOverflowPageId); - } - index.getPageStore().update(this); - } - - public int getMemorySize() { - return index.getMemorySizePerPage(); - } - -} diff --git a/tools/h2/src/main/org/h2/index/PageDataNode.java b/tools/h2/src/main/org/h2/index/PageDataNode.java deleted file mode 100755 index 0ff4877..0000000 --- a/tools/h2/src/main/org/h2/index/PageDataNode.java +++ /dev/null @@ -1,438 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.index; - -import java.util.Arrays; -import org.h2.api.DatabaseEventListener; -import org.h2.constant.ErrorCode; -import org.h2.constant.SysProperties; -import org.h2.engine.Session; -import org.h2.message.DbException; -import org.h2.result.Row; -import org.h2.store.Data; -import org.h2.store.Page; -import org.h2.store.PageStore; -import org.h2.util.Utils; - -/** - * A leaf page that contains data of one or multiple rows. Format: - *
    - *
  • page type: byte (0)
  • - *
  • checksum: short (1-2)
  • - *
  • parent page id (0 for root): int (3-6)
  • - *
  • table id: varInt
  • - *
  • count of all children (-1 if not known): int
  • - *
  • entry count: short
  • - *
  • rightmost child page id: int
  • - *
  • entries (child page id: int, key: varLong)
  • - *
- * The key is the largest key of the respective child, meaning key[0] is the - * largest key of child[0]. - */ -public class PageDataNode extends PageData { - - /** - * The page ids of the children. - */ - private int[] childPageIds; - - private int rowCountStored = UNKNOWN_ROWCOUNT; - - private int rowCount = UNKNOWN_ROWCOUNT; - - /** - * The number of bytes used in the page - */ - private int length; - - private PageDataNode(PageDataIndex index, int pageId, Data data) { - super(index, pageId, data); - } - - /** - * Create a new page. - * - * @param index the index - * @param pageId the page id - * @param parentPageId the parent - * @return the page - */ - static PageDataNode create(PageDataIndex index, int pageId, int parentPageId) { - PageDataNode p = new PageDataNode(index, pageId, index.getPageStore().createData()); - index.getPageStore().logUndo(p, null); - p.parentPageId = parentPageId; - p.writeHead(); - // 4 bytes for the rightmost child page id - p.length = p.data.length() + 4; - return p; - } - - /** - * Read a data node page. - * - * @param index the index - * @param data the data - * @param pageId the page id - * @return the page - */ - public static Page read(PageDataIndex index, Data data, int pageId) { - PageDataNode p = new PageDataNode(index, pageId, data); - p.read(); - return p; - } - - private void read() { - data.reset(); - data.readByte(); - data.readShortInt(); - this.parentPageId = data.readInt(); - int indexId = data.readVarInt(); - if (indexId != index.getId()) { - throw DbException.get(ErrorCode.FILE_CORRUPTED_1, - "page:" + getPos() + " expected index:" + index.getId() + - "got:" + indexId); - } - rowCount = rowCountStored = data.readInt(); - entryCount = data.readShortInt(); - childPageIds = new int[entryCount + 1]; - childPageIds[entryCount] = data.readInt(); - keys = Utils.newLongArray(entryCount); - for (int i = 0; i < entryCount; i++) { - childPageIds[i] = data.readInt(); - keys[i] = data.readVarLong(); - } - length = data.length(); - check(); - written = true; - } - - private void addChild(int x, int childPageId, long key) { - index.getPageStore().logUndo(this, data); - written = false; - changeCount = index.getPageStore().getChangeCount(); - long[] newKeys = new long[entryCount + 1]; - int[] newChildPageIds = new int[entryCount + 2]; - if (childPageIds != null) { - System.arraycopy(childPageIds, 0, newChildPageIds, 0, x + 1); - } - if (entryCount > 0) { - System.arraycopy(keys, 0, newKeys, 0, x); - if (x < entryCount) { - System.arraycopy(keys, x, newKeys, x + 1, entryCount - x); - System.arraycopy(childPageIds, x, newChildPageIds, x + 1, entryCount - x + 1); - } - } - newKeys[x] = key; - newChildPageIds[x + 1] = childPageId; - keys = newKeys; - childPageIds = newChildPageIds; - entryCount++; - length += 4 + Data.getVarLongLen(key); - } - - int addRowTry(Row row) { - index.getPageStore().logUndo(this, data); - int keyOffsetPairLen = 4 + Data.getVarLongLen(row.getKey()); - while (true) { - int x = find(row.getKey()); - PageData page = index.getPage(childPageIds[x], getPos()); - int splitPoint = page.addRowTry(row); - if (splitPoint == -1) { - break; - } - if (length + keyOffsetPairLen > index.getPageStore().getPageSize()) { - return entryCount / 2; - } - long pivot = splitPoint == 0 ? row.getKey() : page.getKey(splitPoint - 1); - PageData page2 = page.split(splitPoint); - index.getPageStore().update(page); - index.getPageStore().update(page2); - addChild(x, page2.getPos(), pivot); - index.getPageStore().update(this); - } - updateRowCount(1); - return -1; - } - - private void updateRowCount(int offset) { - if (rowCount != UNKNOWN_ROWCOUNT) { - rowCount += offset; - } - if (rowCountStored != UNKNOWN_ROWCOUNT) { - rowCountStored = UNKNOWN_ROWCOUNT; - index.getPageStore().logUndo(this, data); - if (written) { - writeHead(); - } - index.getPageStore().update(this); - } - } - - Cursor find(Session session, long min, long max, boolean multiVersion) { - int x = find(min); - int child = childPageIds[x]; - return index.getPage(child, getPos()).find(session, min, max, multiVersion); - } - - PageData split(int splitPoint) { - int newPageId = index.getPageStore().allocatePage(); - PageDataNode p2 = PageDataNode.create(index, newPageId, parentPageId); - int firstChild = childPageIds[splitPoint]; - for (int i = splitPoint; i < entryCount;) { - p2.addChild(p2.entryCount, childPageIds[splitPoint + 1], keys[splitPoint]); - removeChild(splitPoint); - } - int lastChild = childPageIds[splitPoint - 1]; - removeChild(splitPoint - 1); - childPageIds[splitPoint - 1] = lastChild; - p2.childPageIds[0] = firstChild; - p2.remapChildren(getPos()); - return p2; - } - - protected void remapChildren(int old) { - for (int child : childPageIds) { - PageData p = index.getPage(child, old); - p.setParentPageId(getPos()); - index.getPageStore().update(p); - } - } - - /** - * Initialize the page. - * - * @param page1 the first child page - * @param pivot the pivot key - * @param page2 the last child page - */ - void init(PageData page1, long pivot, PageData page2) { - entryCount = 1; - childPageIds = new int[] { page1.getPos(), page2.getPos() }; - keys = new long[] { pivot }; - length += 4 + Data.getVarLongLen(pivot); - check(); - } - - long getLastKey() { - return index.getPage(childPageIds[entryCount], getPos()).getLastKey(); - } - - /** - * Get the next leaf page. - * - * @param key the last key of the current page - * @return the next leaf page - */ - PageDataLeaf getNextPage(long key) { - int i = find(key) + 1; - if (i > entryCount) { - if (parentPageId == PageData.ROOT) { - return null; - } - PageDataNode next = (PageDataNode) index.getPage(parentPageId, -1); - return next.getNextPage(key); - } - PageData page = index.getPage(childPageIds[i], getPos()); - return page.getFirstLeaf(); - } - - PageDataLeaf getFirstLeaf() { - int child = childPageIds[0]; - return index.getPage(child, getPos()).getFirstLeaf(); - } - - boolean remove(long key) { - int at = find(key); - // merge is not implemented to allow concurrent usage - // TODO maybe implement merge - PageData page = index.getPage(childPageIds[at], getPos()); - boolean empty = page.remove(key); - index.getPageStore().logUndo(this, data); - updateRowCount(-1); - if (!empty) { - // the first row didn't change - nothing to do - return false; - } - // this child is now empty - index.getPageStore().free(page.getPos()); - if (entryCount < 1) { - // no more children - this page is empty as well - return true; - } - removeChild(at); - index.getPageStore().update(this); - return false; - } - - void freeRecursive() { - index.getPageStore().logUndo(this, data); - index.getPageStore().free(getPos()); - for (int childPageId : childPageIds) { - index.getPage(childPageId, getPos()).freeRecursive(); - } - } - - Row getRow(long key) { - int at = find(key); - PageData page = index.getPage(childPageIds[at], getPos()); - return page.getRow(key); - } - - int getRowCount() { - if (rowCount == UNKNOWN_ROWCOUNT) { - int count = 0; - for (int child : childPageIds) { - PageData page = index.getPage(child, getPos()); - if (getPos() == page.getPos()) { - throw DbException.throwInternalError("Page it its own child: " + getPos()); - } - count += page.getRowCount(); - index.getDatabase().setProgress(DatabaseEventListener.STATE_SCAN_FILE, index.getTable() + "." + index.getName(), count, Integer.MAX_VALUE); - } - rowCount = count; - } - return rowCount; - } - - void setRowCountStored(int rowCount) { - this.rowCount = rowCount; - if (rowCountStored != rowCount) { - rowCountStored = rowCount; - index.getPageStore().logUndo(this, data); - if (written) { - changeCount = index.getPageStore().getChangeCount(); - writeHead(); - } - index.getPageStore().update(this); - } - } - - private void check() { - for (int child : childPageIds) { - if (child == 0) { - DbException.throwInternalError(); - } - } - } - - public void write() { - writeData(); - index.getPageStore().writePage(getPos(), data); - } - - private void writeHead() { - data.reset(); - data.writeByte((byte) Page.TYPE_DATA_NODE); - data.writeShortInt(0); - if (SysProperties.CHECK2) { - if (data.length() != START_PARENT) { - DbException.throwInternalError(); - } - } - data.writeInt(parentPageId); - data.writeVarInt(index.getId()); - data.writeInt(rowCountStored); - data.writeShortInt(entryCount); - } - - private void writeData() { - if (written) { - return; - } - check(); - writeHead(); - data.writeInt(childPageIds[entryCount]); - for (int i = 0; i < entryCount; i++) { - data.writeInt(childPageIds[i]); - data.writeVarLong(keys[i]); - } - if (length != data.length()) { - DbException.throwInternalError("expected pos: " + length + " got: " + data.length()); - } - written = true; - } - - private void removeChild(int i) { - index.getPageStore().logUndo(this, data); - written = false; - changeCount = index.getPageStore().getChangeCount(); - entryCount--; - int removedKeyIndex = i < keys.length ? i : i - 1; - length -= 4 + Data.getVarLongLen(keys[removedKeyIndex]); - if (entryCount < 0) { - DbException.throwInternalError(); - } - long[] newKeys = Utils.newLongArray(entryCount); - int[] newChildPageIds = new int[entryCount + 1]; - System.arraycopy(keys, 0, newKeys, 0, Math.min(entryCount, i)); - System.arraycopy(childPageIds, 0, newChildPageIds, 0, i); - if (entryCount > i) { - System.arraycopy(keys, i + 1, newKeys, i, entryCount - i); - } - System.arraycopy(childPageIds, i + 1, newChildPageIds, i, entryCount - i + 1); - keys = newKeys; - childPageIds = newChildPageIds; - } - - public String toString() { - return "page[" + getPos() + "] data node table:" + index.getId() + " entries:" + entryCount + " " + Arrays.toString(childPageIds); - } - - public void moveTo(Session session, int newPos) { - PageStore store = index.getPageStore(); - // load the pages into the cache, to ensure old pages - // are written - for (int child : childPageIds) { - store.getPage(child); - } - if (parentPageId != ROOT) { - store.getPage(parentPageId); - } - store.logUndo(this, data); - PageDataNode p2 = PageDataNode.create(index, newPos, parentPageId); - p2.rowCountStored = rowCountStored; - p2.rowCount = rowCount; - p2.childPageIds = childPageIds; - p2.keys = keys; - p2.entryCount = entryCount; - p2.length = length; - store.update(p2); - if (parentPageId == ROOT) { - index.setRootPageId(session, newPos); - } else { - PageDataNode p = (PageDataNode) store.getPage(parentPageId); - p.moveChild(getPos(), newPos); - } - for (int child : childPageIds) { - PageData p = (PageData) store.getPage(child); - p.setParentPageId(newPos); - store.update(p); - } - store.free(getPos()); - } - - /** - * One of the children has moved to another page. - * - * @param oldPos the old position - * @param newPos the new position - */ - void moveChild(int oldPos, int newPos) { - for (int i = 0; i < childPageIds.length; i++) { - if (childPageIds[i] == oldPos) { - index.getPageStore().logUndo(this, data); - written = false; - changeCount = index.getPageStore().getChangeCount(); - childPageIds[i] = newPos; - index.getPageStore().update(this); - return; - } - } - throw DbException.throwInternalError(); - } - -} diff --git a/tools/h2/src/main/org/h2/index/PageDataOverflow.java b/tools/h2/src/main/org/h2/index/PageDataOverflow.java deleted file mode 100755 index ea491f6..0000000 --- a/tools/h2/src/main/org/h2/index/PageDataOverflow.java +++ /dev/null @@ -1,261 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.index; - -import org.h2.constant.ErrorCode; -import org.h2.constant.SysProperties; -import org.h2.engine.Session; -import org.h2.message.DbException; -import org.h2.store.Data; -import org.h2.store.Page; -import org.h2.store.PageStore; - -/** - * Overflow data for a leaf page. Format: - *
    - *
  • page type: byte (0)
  • - *
  • checksum: short (1-2)
  • - *
  • parent page id (0 for root): int (3-6)
  • - *
  • more data: next overflow page id: int (7-10)
  • - *
  • last remaining size: short (7-8)
  • - *
  • data (11-/9-)
  • - *
- */ -public class PageDataOverflow extends Page { - - /** - * The start of the data in the last overflow page. - */ - static final int START_LAST = 9; - - /** - * The start of the data in a overflow page that is not the last one. - */ - static final int START_MORE = 11; - - private static final int START_NEXT_OVERFLOW = 7; - - /** - * The page store. - */ - private final PageStore store; - - /** - * The page type. - */ - private int type; - - /** - * The parent page (overflow or leaf). - */ - private int parentPageId; - - /** - * The next overflow page, or 0. - */ - private int nextPage; - - private Data data; - - private int start; - private int size; - - /** - * Create an object from the given data page. - * - * @param leaf the leaf page - * @param pageId the page id - * @param data the data page - * @param offset the offset - */ - private PageDataOverflow(PageStore store, int pageId, Data data) { - this.store = store; - setPos(pageId); - this.data = data; - } - - /** - * Read an overflow page. - * - * @param store the page store - * @param data the data - * @param pageId the page id - * @return the page - */ - public static Page read(PageStore store, Data data, int pageId) { - PageDataOverflow p = new PageDataOverflow(store, pageId, data); - p.read(); - return p; - } - - /** - * Create a new overflow page. - * - * @param store the page store - * @param page the page id - * @param type the page type - * @param parentPageId the parent page id - * @param next the next page or 0 - * @param all the data - * @param offset the offset within the data - * @param size the number of bytes - * @return the page - */ - static PageDataOverflow create(PageStore store, int page, int type, int parentPageId, int next, Data all, int offset, int size) { - Data data = store.createData(); - PageDataOverflow p = new PageDataOverflow(store, page, data); - store.logUndo(p, null); - data.writeByte((byte) type); - data.writeShortInt(0); - data.writeInt(parentPageId); - if (type == Page.TYPE_DATA_OVERFLOW) { - data.writeInt(next); - } else { - data.writeShortInt(size); - } - p.start = data.length(); - data.write(all.getBytes(), offset, size); - p.type = type; - p.parentPageId = parentPageId; - p.nextPage = next; - p.size = size; - return p; - } - - /** - * Read the page. - */ - private void read() { - data.reset(); - type = data.readByte(); - data.readShortInt(); - parentPageId = data.readInt(); - if (type == (Page.TYPE_DATA_OVERFLOW | Page.FLAG_LAST)) { - size = data.readShortInt(); - nextPage = 0; - } else if (type == Page.TYPE_DATA_OVERFLOW) { - nextPage = data.readInt(); - size = store.getPageSize() - data.length(); - } else { - throw DbException.get(ErrorCode.FILE_CORRUPTED_1, "page:" + getPos() + " type:" + type); - } - start = data.length(); - } - - /** - * Read the data into a target buffer. - * - * @param target the target data page - * @return the next page, or 0 if no next page - */ - int readInto(Data target) { - target.checkCapacity(size); - if (type == (Page.TYPE_DATA_OVERFLOW | Page.FLAG_LAST)) { - target.write(data.getBytes(), START_LAST, size); - return 0; - } - target.write(data.getBytes(), START_MORE, size); - return nextPage; - } - - int getNextOverflow() { - return nextPage; - } - - private void writeHead() { - data.writeByte((byte) type); - data.writeShortInt(0); - data.writeInt(parentPageId); - } - - public void write() { - writeData(); - store.writePage(getPos(), data); - } - - - private void writeData() { - data.reset(); - writeHead(); - if (type == Page.TYPE_DATA_OVERFLOW) { - data.writeInt(nextPage); - } else { - data.writeShortInt(size); - } - } - - - public String toString() { - return "page[" + getPos() + "] data leaf overflow parent:" + parentPageId + " next:" + nextPage; - } - - /** - * Get the estimated memory size. - * - * @return number of double words (4 bytes) - */ - public int getMemorySize() { - // double the byte array size - return store.getPageSize() >> 1; - } - - void setParentPageId(int parent) { - store.logUndo(this, data); - this.parentPageId = parent; - } - - public void moveTo(Session session, int newPos) { - // load the pages into the cache, to ensure old pages - // are written - Page parent = store.getPage(parentPageId); - if (parent == null) { - throw DbException.throwInternalError(); - } - PageDataOverflow next = null; - if (nextPage != 0) { - next = (PageDataOverflow) store.getPage(nextPage); - } - store.logUndo(this, data); - PageDataOverflow p2 = PageDataOverflow.create(store, newPos, type, parentPageId, nextPage, data, start, size); - store.update(p2); - if (next != null) { - next.setParentPageId(newPos); - store.update(next); - } - if (parent instanceof PageDataOverflow) { - PageDataOverflow p1 = (PageDataOverflow) parent; - p1.setNext(getPos(), newPos); - } else { - PageDataLeaf p1 = (PageDataLeaf) parent; - p1.setOverflow(getPos(), newPos); - } - store.update(parent); - store.free(getPos()); - } - - private void setNext(int old, int nextPage) { - if (SysProperties.CHECK && old != this.nextPage) { - DbException.throwInternalError("move " + this + " " + nextPage); - } - store.logUndo(this, data); - this.nextPage = nextPage; - data.setInt(START_NEXT_OVERFLOW, nextPage); - } - - /** - * Free this page. - */ - void free() { - store.logUndo(this, data); - store.free(getPos()); - } - - public boolean canRemove() { - return true; - } - -} diff --git a/tools/h2/src/main/org/h2/index/PageDelegateIndex.java b/tools/h2/src/main/org/h2/index/PageDelegateIndex.java deleted file mode 100755 index b4a5c40..0000000 --- a/tools/h2/src/main/org/h2/index/PageDelegateIndex.java +++ /dev/null @@ -1,121 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.index; - -import org.h2.engine.Session; -import org.h2.message.DbException; -import org.h2.result.Row; -import org.h2.result.SearchRow; -import org.h2.store.PageStore; -import org.h2.table.Column; -import org.h2.table.IndexColumn; -import org.h2.table.RegularTable; - -/** - * An index that delegates indexing to the page data index. - */ -public class PageDelegateIndex extends PageIndex { - - private final PageDataIndex mainIndex; - - public PageDelegateIndex(RegularTable table, int id, String name, IndexType indexType, PageDataIndex mainIndex, boolean create, Session session) { - IndexColumn[] cols = IndexColumn.wrap(new Column[] { table.getColumn(mainIndex.getMainIndexColumn())}); - this.initBaseIndex(table, id, name, cols, indexType); - this.mainIndex = mainIndex; - if (!database.isPersistent() || id < 0) { - throw DbException.throwInternalError("" + name); - } - PageStore store = database.getPageStore(); - store.addIndex(this); - if (create) { - store.addMeta(this, session); - } - } - - public void add(Session session, Row row) { - // nothing to do - } - - public boolean canFindNext() { - return false; - } - - public boolean canGetFirstOrLast() { - return true; - } - - public void close(Session session) { - // nothing to do - } - - public Cursor find(Session session, SearchRow first, SearchRow last) { - long min = mainIndex.getLong(first, Long.MIN_VALUE); - long max = mainIndex.getLong(last, Long.MAX_VALUE); - return mainIndex.find(session, min, max, false); - } - - public Cursor findFirstOrLast(Session session, boolean first) { - Cursor cursor; - if (first) { - cursor = mainIndex.find(session, Long.MIN_VALUE, Long.MAX_VALUE, false); - } else { - long x = mainIndex.getLastKey(); - cursor = mainIndex.find(session, x, x, false); - } - cursor.next(); - return cursor; - } - - public Cursor findNext(Session session, SearchRow higherThan, SearchRow last) { - throw DbException.throwInternalError(); - } - - public int getColumnIndex(Column col) { - if (col.getColumnId() == mainIndex.getMainIndexColumn()) { - return 0; - } - return -1; - } - - public double getCost(Session session, int[] masks) { - return 10 * getCostRangeIndex(masks, mainIndex.getRowCount(session)); - } - - public boolean needRebuild() { - return false; - } - - public void remove(Session session, Row row) { - // nothing to do - } - - public void remove(Session session) { - mainIndex.setMainIndexColumn(-1); - session.getDatabase().getPageStore().removeMeta(this, session); - } - - public void truncate(Session session) { - // nothing to do - } - - public void checkRename() { - // ok - } - - public long getRowCount(Session session) { - return mainIndex.getRowCount(session); - } - - public long getRowCountApproximation() { - return mainIndex.getRowCountApproximation(); - } - - public void writeRowCount() { - // ignore - } - -} diff --git a/tools/h2/src/main/org/h2/index/PageIndex.java b/tools/h2/src/main/org/h2/index/PageIndex.java deleted file mode 100755 index 78a3859..0000000 --- a/tools/h2/src/main/org/h2/index/PageIndex.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.index; - - -/** - * A page store index. - */ -public abstract class PageIndex extends BaseIndex { - - /** - * The root page of this index. - */ - protected int rootPageId; - - private boolean sortedInsertMode; - - public int getRootPageId() { - return rootPageId; - } - - /** - * Write back the row count if it has changed. - */ - public abstract void writeRowCount(); - - public void setSortedInsertMode(boolean sortedInsertMode) { - this.sortedInsertMode = sortedInsertMode; - } - - boolean isSortedInsertMode() { - return sortedInsertMode; - } - -} diff --git a/tools/h2/src/main/org/h2/index/RangeCursor.java b/tools/h2/src/main/org/h2/index/RangeCursor.java deleted file mode 100755 index 1e1a26e..0000000 --- a/tools/h2/src/main/org/h2/index/RangeCursor.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.index; - -import org.h2.message.DbException; -import org.h2.result.Row; -import org.h2.result.SearchRow; -import org.h2.value.Value; -import org.h2.value.ValueLong; - -/** - * The cursor implementation for the range index. - */ -class RangeCursor implements Cursor { - - private boolean beforeFirst; - private long current; - private Row currentRow; - private long min, max; - - RangeCursor(long min, long max) { - this.min = min; - this.max = max; - beforeFirst = true; - } - - public Row get() { - return currentRow; - } - - public SearchRow getSearchRow() { - return currentRow; - } - - public boolean next() { - if (beforeFirst) { - beforeFirst = false; - current = min; - } else { - current++; - } - currentRow = new Row(new Value[]{ValueLong.get(current)}, 1); - return current <= max; - } - - public boolean previous() { - throw DbException.throwInternalError(); - } - -} diff --git a/tools/h2/src/main/org/h2/index/RangeIndex.java b/tools/h2/src/main/org/h2/index/RangeIndex.java deleted file mode 100755 index ec94819..0000000 --- a/tools/h2/src/main/org/h2/index/RangeIndex.java +++ /dev/null @@ -1,98 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.index; - -import org.h2.engine.Session; -import org.h2.message.DbException; -import org.h2.result.Row; -import org.h2.result.SearchRow; -import org.h2.table.IndexColumn; -import org.h2.table.RangeTable; - -/** - * An index for the SYSTEM_RANGE table. - * This index can only scan through all rows, search is not supported. - */ -public class RangeIndex extends BaseIndex { - - private RangeTable rangeTable; - - public RangeIndex(RangeTable table, IndexColumn[] columns) { - initBaseIndex(table, 0, "RANGE_INDEX", columns, IndexType.createNonUnique(true)); - this.rangeTable = table; - } - - public void close(Session session) { - // nothing to do - } - - public void add(Session session, Row row) { - throw DbException.getUnsupportedException("SYSTEM_RANGE"); - } - - public void remove(Session session, Row row) { - throw DbException.getUnsupportedException("SYSTEM_RANGE"); - } - - public Cursor find(Session session, SearchRow first, SearchRow last) { - long min = rangeTable.getMin(session), start = min; - long max = rangeTable.getMax(session), end = max; - try { - start = Math.max(min, first == null ? min : first.getValue(0).getLong()); - } catch (Exception e) { - // error when converting the value - ignore - } - try { - end = Math.min(max, last == null ? max : last.getValue(0).getLong()); - } catch (Exception e) { - // error when converting the value - ignore - } - return new RangeCursor(start, end); - } - - public double getCost(Session session, int[] masks) { - return 1; - } - - public String getCreateSQL() { - return null; - } - - public void remove(Session session) { - throw DbException.getUnsupportedException("SYSTEM_RANGE"); - } - - public void truncate(Session session) { - throw DbException.getUnsupportedException("SYSTEM_RANGE"); - } - - public boolean needRebuild() { - return false; - } - - public void checkRename() { - throw DbException.getUnsupportedException("SYSTEM_RANGE"); - } - - public boolean canGetFirstOrLast() { - return true; - } - - public Cursor findFirstOrLast(Session session, boolean first) { - long pos = first ? rangeTable.getMin(session) : rangeTable.getMax(session); - return new RangeCursor(pos, pos); - } - - public long getRowCount(Session session) { - return rangeTable.getRowCountApproximation(); - } - - public long getRowCountApproximation() { - return rangeTable.getRowCountApproximation(); - } - -} diff --git a/tools/h2/src/main/org/h2/index/ScanCursor.java b/tools/h2/src/main/org/h2/index/ScanCursor.java deleted file mode 100755 index b57adf1..0000000 --- a/tools/h2/src/main/org/h2/index/ScanCursor.java +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.index; - -import java.util.Iterator; -import org.h2.engine.Session; -import org.h2.message.DbException; -import org.h2.result.Row; -import org.h2.result.SearchRow; - -/** - * The cursor implementation for the scan index. - */ -public class ScanCursor implements Cursor { - private ScanIndex scan; - private Row row; - private final Session session; - private final boolean multiVersion; - private Iterator delta; - - ScanCursor(Session session, ScanIndex scan, boolean multiVersion) { - this.session = session; - this.scan = scan; - this.multiVersion = multiVersion; - if (multiVersion) { - delta = scan.getDelta(); - } - row = null; - } - - public Row get() { - return row; - } - - public SearchRow getSearchRow() { - return row; - } - - public boolean next() { - if (multiVersion) { - while (true) { - if (delta != null) { - if (!delta.hasNext()) { - delta = null; - row = null; - continue; - } - row = delta.next(); - if (!row.isDeleted() || row.getSessionId() == session.getId()) { - continue; - } - } else { - row = scan.getNextRow(session, row); - if (row != null && row.getSessionId() != 0 && row.getSessionId() != session.getId()) { - continue; - } - } - break; - } - return row != null; - } - row = scan.getNextRow(session, row); - return row != null; - } - - public boolean previous() { - throw DbException.throwInternalError(); - } - -} diff --git a/tools/h2/src/main/org/h2/index/ScanIndex.java b/tools/h2/src/main/org/h2/index/ScanIndex.java deleted file mode 100755 index 20a1e02..0000000 --- a/tools/h2/src/main/org/h2/index/ScanIndex.java +++ /dev/null @@ -1,234 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.index; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Iterator; -import java.util.List; -import org.h2.engine.Constants; -import org.h2.engine.Session; -import org.h2.engine.UndoLogRecord; -import org.h2.message.DbException; -import org.h2.result.Row; -import org.h2.result.SearchRow; -import org.h2.table.Column; -import org.h2.table.IndexColumn; -import org.h2.table.RegularTable; -import org.h2.util.New; - -/** - * The scan index is not really an 'index' in the strict sense, because it can - * not be used for direct lookup. It can only be used to iterate over all rows - * of a table. Each regular table has one such object, even if no primary key or - * indexes are defined. - */ -public class ScanIndex extends BaseIndex { - private long firstFree = -1; - private ArrayList rows = New.arrayList(); - private RegularTable tableData; - private int rowCountDiff; - private HashMap sessionRowCount; - private HashSet delta; - private long rowCount; - - public ScanIndex(RegularTable table, int id, IndexColumn[] columns, IndexType indexType) { - initBaseIndex(table, id, table.getName() + "_DATA", columns, indexType); - if (database.isMultiVersion()) { - sessionRowCount = New.hashMap(); - } - tableData = table; - } - - public void remove(Session session) { - truncate(session); - } - - public void truncate(Session session) { - rows = New.arrayList(); - firstFree = -1; - if (tableData.getContainsLargeObject() && tableData.isPersistData()) { - database.getLobStorage().removeAllForTable(table.getId()); - } - tableData.setRowCount(0); - rowCount = 0; - rowCountDiff = 0; - if (database.isMultiVersion()) { - sessionRowCount.clear(); - } - } - - public String getCreateSQL() { - return null; - } - - public void close(Session session) { - // nothing to do - } - - public Row getRow(Session session, long key) { - return rows.get((int) key); - } - - public void add(Session session, Row row) { - // in-memory - if (firstFree == -1) { - int key = rows.size(); - row.setKey(key); - rows.add(row); - } else { - long key = firstFree; - Row free = rows.get((int) key); - firstFree = free.getKey(); - row.setKey(key); - rows.set((int) key, row); - } - row.setDeleted(false); - if (database.isMultiVersion()) { - if (delta == null) { - delta = New.hashSet(); - } - boolean wasDeleted = delta.remove(row); - if (!wasDeleted) { - delta.add(row); - } - incrementRowCount(session.getId(), 1); - } - rowCount++; - } - - public void commit(int operation, Row row) { - if (database.isMultiVersion()) { - if (delta != null) { - delta.remove(row); - } - incrementRowCount(row.getSessionId(), operation == UndoLogRecord.DELETE ? 1 : -1); - } - } - - private void incrementRowCount(int sessionId, int count) { - if (database.isMultiVersion()) { - Integer id = sessionId; - Integer c = sessionRowCount.get(id); - int current = c == null ? 0 : c.intValue(); - sessionRowCount.put(id, current + count); - rowCountDiff += count; - } - } - - public void remove(Session session, Row row) { - // in-memory - if (!database.isMultiVersion() && rowCount == 1) { - rows = New.arrayList(); - firstFree = -1; - } else { - Row free = new Row(null, 1); - free.setKey(firstFree); - long key = row.getKey(); - rows.set((int) key, free); - firstFree = key; - } - if (database.isMultiVersion()) { - // if storage is null, the delete flag is not yet set - row.setDeleted(true); - if (delta == null) { - delta = New.hashSet(); - } - boolean wasAdded = delta.remove(row); - if (!wasAdded) { - delta.add(row); - } - incrementRowCount(session.getId(), -1); - } - rowCount--; - } - - public Cursor find(Session session, SearchRow first, SearchRow last) { - return new ScanCursor(session, this, database.isMultiVersion()); - } - - public double getCost(Session session, int[] masks) { - return tableData.getRowCountApproximation() + Constants.COST_ROW_OFFSET; - } - - public long getRowCount(Session session) { - if (database.isMultiVersion()) { - Integer i = sessionRowCount.get(session.getId()); - long count = i == null ? 0 : i.intValue(); - count += rowCount; - count -= rowCountDiff; - return count; - } - return rowCount; - } - - /** - * Get the next row that is stored after this row. - * - * @param session the session - * @param row the current row or null to start the scan - * @return the next row or null if there are no more rows - */ - Row getNextRow(Session session, Row row) { - long key; - if (row == null) { - key = -1; - } else { - key = row.getKey(); - } - while (true) { - key++; - if (key >= rows.size()) { - return null; - } - row = rows.get((int) key); - if (!row.isEmpty()) { - return row; - } - } - } - - public int getColumnIndex(Column col) { - // the scan index cannot use any columns - return -1; - } - - public void checkRename() { - throw DbException.getUnsupportedException("SCAN"); - } - - public boolean needRebuild() { - return false; - } - - public boolean canGetFirstOrLast() { - return false; - } - - public Cursor findFirstOrLast(Session session, boolean first) { - throw DbException.getUnsupportedException("SCAN"); - } - - Iterator getDelta() { - if (delta == null) { - List e = Collections.emptyList(); - return e.iterator(); - } - return delta.iterator(); - } - - public long getRowCountApproximation() { - return rowCount; - } - - public String getPlanSQL() { - return table.getSQL() + ".tableScan"; - } - -} diff --git a/tools/h2/src/main/org/h2/index/SingleRowCursor.java b/tools/h2/src/main/org/h2/index/SingleRowCursor.java deleted file mode 100755 index 1b503b8..0000000 --- a/tools/h2/src/main/org/h2/index/SingleRowCursor.java +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.index; - -import org.h2.message.DbException; -import org.h2.result.Row; -import org.h2.result.SearchRow; - -/** - * A cursor with at most one row. - */ -public class SingleRowCursor implements Cursor { - private Row row; - private boolean end; - - /** - * Create a new cursor. - * - * @param row - the single row (if null then cursor is empty) - */ - public SingleRowCursor(Row row) { - this.row = row; - } - - public Row get() { - return row; - } - - public SearchRow getSearchRow() { - return row; - } - - public boolean next() { - if (row == null || end) { - row = null; - return false; - } - end = true; - return true; - } - - public boolean previous() { - throw DbException.throwInternalError(); - } - -} diff --git a/tools/h2/src/main/org/h2/index/TreeCursor.java b/tools/h2/src/main/org/h2/index/TreeCursor.java deleted file mode 100755 index b22695e..0000000 --- a/tools/h2/src/main/org/h2/index/TreeCursor.java +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.index; - -import org.h2.result.Row; -import org.h2.result.SearchRow; - -/** - * The cursor implementation for a tree index. - */ -public class TreeCursor implements Cursor { - private TreeIndex tree; - private TreeNode node; - private boolean beforeFirst; - private SearchRow first, last; - - TreeCursor(TreeIndex tree, TreeNode node, SearchRow first, SearchRow last) { - this.tree = tree; - this.node = node; - this.first = first; - this.last = last; - beforeFirst = true; - } - - public Row get() { - return node == null ? null : node.row; - } - - public SearchRow getSearchRow() { - return get(); - } - - public boolean next() { - if (beforeFirst) { - beforeFirst = false; - if (node == null) { - return false; - } - if (first != null && tree.compareRows(node.row, first) < 0) { - node = tree.next(node); - } - } else { - node = tree.next(node); - } - if (node != null && last != null) { - if (tree.compareRows(node.row, last) > 0) { - node = null; - } - } - return node != null; - } - - public boolean previous() { - node = tree.previous(node); - return node != null; - } - -} diff --git a/tools/h2/src/main/org/h2/index/TreeIndex.java b/tools/h2/src/main/org/h2/index/TreeIndex.java deleted file mode 100755 index 1f8be7f..0000000 --- a/tools/h2/src/main/org/h2/index/TreeIndex.java +++ /dev/null @@ -1,424 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.index; - -import org.h2.constant.SysProperties; -import org.h2.engine.Session; -import org.h2.message.DbException; -import org.h2.result.Row; -import org.h2.result.SearchRow; -import org.h2.table.IndexColumn; -import org.h2.table.RegularTable; -import org.h2.value.Value; -import org.h2.value.ValueNull; - -/** - * The tree index is an in-memory index based on a binary AVL trees. - */ -public class TreeIndex extends BaseIndex { - - private TreeNode root; - private RegularTable tableData; - private long rowCount; - - public TreeIndex(RegularTable table, int id, String indexName, IndexColumn[] columns, IndexType indexType) { - initBaseIndex(table, id, indexName, columns, indexType); - tableData = table; - } - - public void close(Session session) { - root = null; - } - - public void add(Session session, Row row) { - TreeNode i = new TreeNode(row); - TreeNode n = root, x = n; - boolean isLeft = true; - while (true) { - if (n == null) { - if (x == null) { - root = i; - rowCount++; - return; - } - set(x, isLeft, i); - break; - } - Row r = n.row; - int compare = compareRows(row, r); - if (compare == 0) { - if (indexType.isUnique()) { - if (!containsNullAndAllowMultipleNull(row)) { - throw getDuplicateKeyException(); - } - } - compare = compareKeys(row, r); - } - isLeft = compare < 0; - x = n; - n = child(x, isLeft); - } - balance(x, isLeft); - rowCount++; - } - - private void balance(TreeNode x, boolean isLeft) { - while (true) { - int sign = isLeft ? 1 : -1; - switch (x.balance * sign) { - case 1: - x.balance = 0; - return; - case 0: - x.balance = -sign; - break; - case -1: - TreeNode l = child(x, isLeft); - if (l.balance == -sign) { - replace(x, l); - set(x, isLeft, child(l, !isLeft)); - set(l, !isLeft, x); - x.balance = 0; - l.balance = 0; - } else { - TreeNode r = child(l, !isLeft); - replace(x, r); - set(l, !isLeft, child(r, isLeft)); - set(r, isLeft, l); - set(x, isLeft, child(r, !isLeft)); - set(r, !isLeft, x); - int rb = r.balance; - x.balance = (rb == -sign) ? sign : 0; - l.balance = (rb == sign) ? -sign : 0; - r.balance = 0; - } - return; - default: - DbException.throwInternalError("b:" + x.balance * sign); - } - if (x == root) { - return; - } - isLeft = x.isFromLeft(); - x = x.parent; - } - } - - private TreeNode child(TreeNode x, boolean isLeft) { - return isLeft ? x.left : x.right; - } - - private void replace(TreeNode x, TreeNode n) { - if (x == root) { - root = n; - if (n != null) { - n.parent = null; - } - } else { - set(x.parent, x.isFromLeft(), n); - } - } - - private void set(TreeNode parent, boolean left, TreeNode n) { - if (left) { - parent.left = n; - } else { - parent.right = n; - } - if (n != null) { - n.parent = parent; - } - } - - public void remove(Session session, Row row) { - TreeNode x = findFirstNode(row, true); - if (x == null) { - throw DbException.throwInternalError("not found!"); - } - TreeNode n; - if (x.left == null) { - n = x.right; - } else if (x.right == null) { - n = x.left; - } else { - TreeNode d = x; - x = x.left; - for (TreeNode temp = x; (temp = temp.right) != null;) { - x = temp; - } - // x will be replaced with n later - n = x.left; - // swap d and x - int b = x.balance; - x.balance = d.balance; - d.balance = b; - - // set x.parent - TreeNode xp = x.parent; - TreeNode dp = d.parent; - if (d == root) { - root = x; - } - x.parent = dp; - if (dp != null) { - if (dp.right == d) { - dp.right = x; - } else { - dp.left = x; - } - } - // TODO index / tree: link d.r = x(p?).r directly - if (xp == d) { - d.parent = x; - if (d.left == x) { - x.left = d; - x.right = d.right; - } else { - x.right = d; - x.left = d.left; - } - } else { - d.parent = xp; - xp.right = d; - x.right = d.right; - x.left = d.left; - } - - if (SysProperties.CHECK && x.right == null) { - DbException.throwInternalError("tree corrupted"); - } - x.right.parent = x; - x.left.parent = x; - // set d.left, d.right - d.left = n; - if (n != null) { - n.parent = d; - } - d.right = null; - x = d; - } - rowCount--; - - boolean isLeft = x.isFromLeft(); - replace(x, n); - n = x.parent; - while (n != null) { - x = n; - int sign = isLeft ? 1 : -1; - switch (x.balance * sign) { - case -1: - x.balance = 0; - break; - case 0: - x.balance = sign; - return; - case 1: - TreeNode r = child(x, !isLeft); - int b = r.balance; - if (b * sign >= 0) { - replace(x, r); - set(x, !isLeft, child(r, isLeft)); - set(r, isLeft, x); - if (b == 0) { - x.balance = sign; - r.balance = -sign; - return; - } - x.balance = 0; - r.balance = 0; - x = r; - } else { - TreeNode l = child(r, isLeft); - replace(x, l); - b = l.balance; - set(r, isLeft, child(l, !isLeft)); - set(l, !isLeft, r); - set(x, !isLeft, child(l, isLeft)); - set(l, isLeft, x); - x.balance = (b == sign) ? -sign : 0; - r.balance = (b == -sign) ? sign : 0; - l.balance = 0; - x = l; - } - break; - default: - DbException.throwInternalError("b: " + x.balance * sign); - } - isLeft = x.isFromLeft(); - n = x.parent; - } - } - - private TreeNode findFirstNode(SearchRow row, boolean withKey) { - TreeNode x = root, result = x; - while (x != null) { - result = x; - int compare = compareRows(x.row, row); - if (compare == 0 && withKey) { - compare = compareKeys(x.row, row); - } - if (compare == 0) { - if (withKey) { - return x; - } - x = x.left; - } else if (compare > 0) { - x = x.left; - } else { - x = x.right; - } - } - return result; - } - - public Cursor find(Session session, SearchRow first, SearchRow last) { - if (first == null) { - TreeNode x = root, n; - while (x != null) { - n = x.left; - if (n == null) { - break; - } - x = n; - } - return new TreeCursor(this, x, null, last); - } - TreeNode x = findFirstNode(first, false); - return new TreeCursor(this, x, first, last); - } - - public double getCost(Session session, int[] masks) { - return getCostRangeIndex(masks, tableData.getRowCountApproximation()); - } - - public void remove(Session session) { - truncate(session); - } - - public void truncate(Session session) { - root = null; - rowCount = 0; - } - - /** - * Get the next node if there is one. - * - * @param x the node - * @return the next node or null - */ - TreeNode next(TreeNode x) { - if (x == null) { - return null; - } - TreeNode r = x.right; - if (r != null) { - x = r; - TreeNode l = x.left; - while (l != null) { - x = l; - l = x.left; - } - return x; - } - TreeNode ch = x; - x = x.parent; - while (x != null && ch == x.right) { - ch = x; - x = x.parent; - } - return x; - } - - /** - * Get the previous node if there is one. - * - * @param x the node - * @return the previous node or null - */ - TreeNode previous(TreeNode x) { - if (x == null) { - return null; - } - TreeNode l = x.left; - if (l != null) { - x = l; - TreeNode r = x.right; - while (r != null) { - x = r; - r = x.right; - } - return x; - } - TreeNode ch = x; - x = x.parent; - while (x != null && ch == x.left) { - ch = x; - x = x.parent; - } - return x; - } - - public void checkRename() { - // nothing to do - } - - public boolean needRebuild() { - return true; - } - - public boolean canGetFirstOrLast() { - return true; - } - - public Cursor findFirstOrLast(Session session, boolean first) { - if (first) { - // TODO optimization: this loops through NULL values - Cursor cursor = find(session, null, null); - while (cursor.next()) { - SearchRow row = cursor.getSearchRow(); - Value v = row.getValue(columnIds[0]); - if (v != ValueNull.INSTANCE) { - return cursor; - } - } - return cursor; - } - TreeNode x = root, n; - while (x != null) { - n = x.right; - if (n == null) { - break; - } - x = n; - } - TreeCursor cursor = new TreeCursor(this, x, null, null); - if (x == null) { - return cursor; - } - // TODO optimization: this loops through NULL elements - do { - SearchRow row = cursor.getSearchRow(); - if (row == null) { - break; - } - Value v = row.getValue(columnIds[0]); - if (v != ValueNull.INSTANCE) { - return cursor; - } - } while (cursor.previous()); - return cursor; - } - - public long getRowCount(Session session) { - return rowCount; - } - - public long getRowCountApproximation() { - return rowCount; - } - -} diff --git a/tools/h2/src/main/org/h2/index/TreeNode.java b/tools/h2/src/main/org/h2/index/TreeNode.java deleted file mode 100755 index cfe0006..0000000 --- a/tools/h2/src/main/org/h2/index/TreeNode.java +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.index; - -import org.h2.result.Row; - -/** - * Represents a index node of a tree index. - */ -class TreeNode { - - /** - * The balance. For more information, see the AVL tree documentation. - */ - int balance; - - /** - * The left child node or null. - */ - TreeNode left; - - /** - * The right child node or null. - */ - TreeNode right; - - /** - * The parent node or null if this is the root node. - */ - TreeNode parent; - - /** - * The row. - */ - Row row; - - TreeNode(Row row) { - this.row = row; - } - - /** - * Check if this node is the left child of its parent. This method returns - * true if this is the root node. - * - * @return true if this node is the root or a left child - */ - boolean isFromLeft() { - return parent == null || parent.left == this; - } - -} diff --git a/tools/h2/src/main/org/h2/index/ViewCursor.java b/tools/h2/src/main/org/h2/index/ViewCursor.java deleted file mode 100755 index 503a673..0000000 --- a/tools/h2/src/main/org/h2/index/ViewCursor.java +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.index; - -import org.h2.message.DbException; -import org.h2.result.ResultInterface; -import org.h2.result.Row; -import org.h2.result.SearchRow; -import org.h2.table.Table; -import org.h2.value.Value; -import org.h2.value.ValueNull; - -/** - * The cursor implementation of a view index. - */ -public class ViewCursor implements Cursor { - - private Table table; - private ResultInterface result; - private Row current; - - ViewCursor(Table table, ResultInterface result) { - this.table = table; - this.result = result; - } - - public Row get() { - return current; - } - - public SearchRow getSearchRow() { - return current; - } - - public boolean next() { - boolean res = result.next(); - if (!res) { - result.close(); - current = null; - return false; - } - current = table.getTemplateRow(); - Value[] values = result.currentRow(); - for (int i = 0; i < current.getColumnCount(); i++) { - Value v = i < values.length ? values[i] : ValueNull.INSTANCE; - current.setValue(i, v); - } - return true; - } - - public boolean previous() { - throw DbException.throwInternalError(); - } - -} diff --git a/tools/h2/src/main/org/h2/index/ViewIndex.java b/tools/h2/src/main/org/h2/index/ViewIndex.java deleted file mode 100755 index 65718ce..0000000 --- a/tools/h2/src/main/org/h2/index/ViewIndex.java +++ /dev/null @@ -1,285 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.index; - -import java.util.ArrayList; -import org.h2.command.dml.Query; -import org.h2.engine.Constants; -import org.h2.engine.Session; -import org.h2.expression.Comparison; -import org.h2.expression.Parameter; -import org.h2.message.DbException; -import org.h2.result.ResultInterface; -import org.h2.result.Row; -import org.h2.result.SearchRow; -import org.h2.table.Column; -import org.h2.table.TableView; -import org.h2.util.IntArray; -import org.h2.util.SmallLRUCache; -import org.h2.util.Utils; -import org.h2.value.Value; - -/** - * This object represents a virtual index for a query. - * Actually it only represents a prepared SELECT statement. - */ -public class ViewIndex extends BaseIndex { - - private final TableView view; - private final String querySQL; - private final ArrayList originalParameters; - private final SmallLRUCache costCache = SmallLRUCache.newInstance(Constants.VIEW_INDEX_CACHE_SIZE); - private boolean recursive; - private int[] indexMasks; - private String planSQL; - private Query query; - private Session createSession; - - public ViewIndex(TableView view, String querySQL, ArrayList originalParameters, boolean recursive) { - initBaseIndex(view, 0, null, null, IndexType.createNonUnique(false)); - this.view = view; - this.querySQL = querySQL; - this.originalParameters = originalParameters; - this.recursive = recursive; - columns = new Column[0]; - } - - public ViewIndex(TableView view, ViewIndex index, Session session, int[] masks) { - initBaseIndex(view, 0, null, null, IndexType.createNonUnique(false)); - this.view = view; - this.querySQL = index.querySQL; - this.originalParameters = index.originalParameters; - this.recursive = index.recursive; - this.indexMasks = masks; - this.createSession = session; - columns = new Column[0]; - query = getQuery(session, masks); - planSQL = query.getPlanSQL(); - } - - public Session getSession() { - return createSession; - } - - public String getPlanSQL() { - return planSQL; - } - - public void close(Session session) { - // nothing to do - } - - public void add(Session session, Row row) { - throw DbException.getUnsupportedException("VIEW"); - } - - public void remove(Session session, Row row) { - throw DbException.getUnsupportedException("VIEW"); - } - - /** - * A calculated cost value. - */ - static class CostElement { - - /** - * The time in milliseconds when this cost was calculated. - */ - long evaluatedAt; - - /** - * The cost. - */ - double cost; - } - - public double getCost(Session session, int[] masks) { - IntArray masksArray = new IntArray(masks == null ? Utils.EMPTY_INT_ARRAY : masks); - CostElement cachedCost = costCache.get(masksArray); - if (cachedCost != null) { - long time = System.currentTimeMillis(); - if (time < cachedCost.evaluatedAt + Constants.VIEW_COST_CACHE_MAX_AGE) { - return cachedCost.cost; - } - } - Query q = (Query) session.prepare(querySQL, true); - if (masks != null) { - IntArray paramIndex = new IntArray(); - for (int i = 0; i < masks.length; i++) { - int mask = masks[i]; - if (mask == 0) { - continue; - } - paramIndex.add(i); - } - int len = paramIndex.size(); - for (int i = 0; i < len; i++) { - int idx = paramIndex.get(i); - int mask = masks[idx]; - int nextParamIndex = q.getParameters().size() + view.getParameterOffset(); - if ((mask & IndexCondition.EQUALITY) != 0) { - Parameter param = new Parameter(nextParamIndex); - q.addGlobalCondition(param, idx, Comparison.EQUAL); - } else { - if ((mask & IndexCondition.START) != 0) { - Parameter param = new Parameter(nextParamIndex); - q.addGlobalCondition(param, idx, Comparison.BIGGER_EQUAL); - } - if ((mask & IndexCondition.END) != 0) { - Parameter param = new Parameter(nextParamIndex); - q.addGlobalCondition(param, idx, Comparison.SMALLER_EQUAL); - } - } - } - if (recursive) { - return 10; - } - String sql = q.getPlanSQL(); - q = (Query) session.prepare(sql, true); - } - double cost = q.getCost(); - cachedCost = new CostElement(); - cachedCost.evaluatedAt = System.currentTimeMillis(); - cachedCost.cost = cost; - costCache.put(masksArray, cachedCost); - return cost; - } - - public Cursor find(Session session, SearchRow first, SearchRow last) { - ArrayList paramList = query.getParameters(); - for (int i = 0; originalParameters != null && i < originalParameters.size(); i++) { - Parameter orig = originalParameters.get(i); - int idx = orig.getIndex(); - Value value = orig.getValue(session); - setParameter(paramList, idx, value); - } - int len; - if (first != null) { - len = first.getColumnCount(); - } else if (last != null) { - len = last.getColumnCount(); - } else { - len = 0; - } - int idx = originalParameters == null ? 0 : originalParameters.size(); - idx += view.getParameterOffset(); - for (int i = 0; i < len; i++) { - if (first != null) { - Value v = first.getValue(i); - if (v != null) { - int x = idx++; - setParameter(paramList, x, v); - } - } - // for equality, only one parameter is used (first == last) - if (last != null && indexMasks[i] != IndexCondition.EQUALITY) { - Value v = last.getValue(i); - if (v != null) { - int x = idx++; - setParameter(paramList, x, v); - } - } - } - ResultInterface result = query.query(0); - return new ViewCursor(table, result); - } - - private void setParameter(ArrayList paramList, int x, Value v) { - if (x >= paramList.size()) { - // the parameter may be optimized away as in - // select * from (select null as x) where x=1; - return; - } - Parameter param = paramList.get(x); - param.setValue(v); - } - - private Query getQuery(Session session, int[] masks) { - Query q = (Query) session.prepare(querySQL, true); - if (masks == null) { - return q; - } - int firstIndexParam = originalParameters == null ? 0 : originalParameters.size(); - firstIndexParam += view.getParameterOffset(); - IntArray paramIndex = new IntArray(); - for (int i = 0; i < masks.length; i++) { - int mask = masks[i]; - if (mask == 0) { - continue; - } - paramIndex.add(i); - if ((mask & IndexCondition.RANGE) == IndexCondition.RANGE) { - // two parameters for range queries: >= x AND <= y - paramIndex.add(i); - } - } - int len = paramIndex.size(); - columns = new Column[len]; - for (int i = 0; i < len;) { - int idx = paramIndex.get(i); - Column col = table.getColumn(idx); - columns[i] = col; - int mask = masks[idx]; - if ((mask & IndexCondition.EQUALITY) == IndexCondition.EQUALITY) { - Parameter param = new Parameter(firstIndexParam + i); - q.addGlobalCondition(param, idx, Comparison.EQUAL); - i++; - } else { - if ((mask & IndexCondition.START) == IndexCondition.START) { - Parameter param = new Parameter(firstIndexParam + i); - q.addGlobalCondition(param, idx, Comparison.BIGGER_EQUAL); - i++; - } - if ((mask & IndexCondition.END) == IndexCondition.END) { - Parameter param = new Parameter(firstIndexParam + i); - q.addGlobalCondition(param, idx, Comparison.SMALLER_EQUAL); - i++; - } - } - } - String sql = q.getPlanSQL(); - q = (Query) session.prepare(sql, true); - return q; - } - - public void remove(Session session) { - throw DbException.getUnsupportedException("VIEW"); - } - - public void truncate(Session session) { - throw DbException.getUnsupportedException("VIEW"); - } - - public void checkRename() { - throw DbException.getUnsupportedException("VIEW"); - } - - public boolean needRebuild() { - return false; - } - - public boolean canGetFirstOrLast() { - return false; - } - - public Cursor findFirstOrLast(Session session, boolean first) { - throw DbException.getUnsupportedException("VIEW"); - } - - public void setRecursive(boolean value) { - this.recursive = value; - } - - public long getRowCount(Session session) { - return 0; - } - - public long getRowCountApproximation() { - return 0; - } - -} diff --git a/tools/h2/src/main/org/h2/index/package.html b/tools/h2/src/main/org/h2/index/package.html deleted file mode 100755 index f249636..0000000 --- a/tools/h2/src/main/org/h2/index/package.html +++ /dev/null @@ -1,15 +0,0 @@ - - - - -Javadoc package documentation -

- -Various table index implementations, as well as cursors to navigate in an index. - -

\ No newline at end of file diff --git a/tools/h2/src/main/org/h2/jdbc/JdbcArray.java b/tools/h2/src/main/org/h2/jdbc/JdbcArray.java deleted file mode 100755 index 23d8287..0000000 --- a/tools/h2/src/main/org/h2/jdbc/JdbcArray.java +++ /dev/null @@ -1,278 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.jdbc; - -import java.sql.Array; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.sql.Types; -import java.util.Map; -import org.h2.constant.ErrorCode; -import org.h2.message.DbException; -import org.h2.message.TraceObject; -import org.h2.tools.SimpleResultSet; -import org.h2.value.Value; - -/** - * Represents an ARRAY value. - */ -public class JdbcArray extends TraceObject implements Array { - - private Value value; - private JdbcConnection conn; - - /** - * INTERNAL - */ - JdbcArray(JdbcConnection conn, Value value, int id) { - setTrace(conn.getSession().getTrace(), TraceObject.ARRAY, id); - this.conn = conn; - this.value = value; - } - - /** - * Returns the value as a Java array. - * This method always returns an Object[]. - * - * @return the Object array - */ - public Object getArray() throws SQLException { - try { - debugCodeCall("getArray"); - checkClosed(); - return get(); - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Returns the value as a Java array. - * This method always returns an Object[]. - * - * @param map is ignored. Only empty or null maps are supported - * @return the Object array - */ - public Object getArray(Map> map) throws SQLException { - try { - debugCode("getArray("+quoteMap(map)+");"); - checkMap(map); - checkClosed(); - return get(); - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Returns the value as a Java array. A subset of the array is returned, - * starting from the index (1 meaning the first element) and up to the given - * object count. This method always returns an Object[]. - * - * @param index the start index of the subset (starting with 1) - * @param count the maximum number of values - * @return the Object array - */ - public Object getArray(long index, int count) throws SQLException { - try { - debugCode("getArray(" + index + ", " + count + ");"); - checkClosed(); - return get(index, count); - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Returns the value as a Java array. A subset of the array is returned, - * starting from the index (1 meaning the first element) and up to the given - * object count. This method always returns an Object[]. - * - * @param index the start index of the subset (starting with 1) - * @param count the maximum number of values - * @param map is ignored. Only empty or null maps are supported - * @return the Object array - */ - public Object getArray(long index, int count, Map> map) throws SQLException { - try { - debugCode("getArray(" + index + ", " + count + ", " + quoteMap(map)+");"); - checkClosed(); - checkMap(map); - return get(index, count); - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Returns the base type of the array. This database does support mixed type - * arrays and therefore there is no base type. - * - * @return Types.NULL - */ - public int getBaseType() throws SQLException { - try { - debugCodeCall("getBaseType"); - checkClosed(); - return Types.NULL; - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Returns the base type name of the array. This database does support mixed - * type arrays and therefore there is no base type. - * - * @return "NULL" - */ - public String getBaseTypeName() throws SQLException { - try { - debugCodeCall("getBaseTypeName"); - checkClosed(); - return "NULL"; - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Returns the value as a result set. - * The first column contains the index - * (starting with 1) and the second column the value. - * - * @return the result set - */ - public ResultSet getResultSet() throws SQLException { - try { - debugCodeCall("getResultSet"); - checkClosed(); - return getResultSet(get(), 0); - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Returns the value as a result set. The first column contains the index - * (starting with 1) and the second column the value. - * - * @param map is ignored. Only empty or null maps are supported - * @return the result set - */ - public ResultSet getResultSet(Map> map) throws SQLException { - try { - debugCode("getResultSet("+quoteMap(map)+");"); - checkClosed(); - checkMap(map); - return getResultSet(get(), 0); - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Returns the value as a result set. The first column contains the index - * (starting with 1) and the second column the value. A subset of the array - * is returned, starting from the index (1 meaning the first element) and - * up to the given object count. - * - * @param index the start index of the subset (starting with 1) - * @param count the maximum number of values - * @return the result set - */ - public ResultSet getResultSet(long index, int count) throws SQLException { - try { - debugCode("getResultSet("+index+", " + count+");"); - checkClosed(); - return getResultSet(get(index, count), index); - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Returns the value as a result set. - * The first column contains the index - * (starting with 1) and the second column the value. - * A subset of the array is returned, starting from the index - * (1 meaning the first element) and up to the given object count. - * - * @param index the start index of the subset (starting with 1) - * @param count the maximum number of values - * @param map is ignored. Only empty or null maps are supported - * @return the result set - */ - public ResultSet getResultSet(long index, int count, Map> map) throws SQLException { - try { - debugCode("getResultSet("+index+", " + count+", " + quoteMap(map)+");"); - checkClosed(); - checkMap(map); - return getResultSet(get(index, count), index); - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Release all resources of this object. - */ - public void free() { - debugCodeCall("free"); - value = null; - } - - private ResultSet getResultSet(Object[] array, long offset) { - SimpleResultSet rs = new SimpleResultSet(); - rs.addColumn("INDEX", Types.BIGINT, 0, 0); - // TODO array result set: there are multiple data types possible - rs.addColumn("VALUE", Types.NULL, 0, 0); - for (int i = 0; i < array.length; i++) { - rs.addRow(Long.valueOf(offset + i + 1), array[i]); - } - return rs; - } - - private void checkClosed() throws SQLException { - conn.checkClosed(); - if (value == null) { - throw DbException.get(ErrorCode.OBJECT_CLOSED); - } - } - - private Object[] get() { - return (Object[]) value.convertTo(Value.ARRAY).getObject(); - } - - private Object[] get(long index, int count) { - Object[] array = get(); - if (count < 0 || count > array.length) { - throw DbException.getInvalidValueException("" + count, "count (1.." - + array.length + ")"); - } - if (index < 1 || index > array.length) { - throw DbException.getInvalidValueException("" + index, "index (1.." - + array.length + ")"); - } - Object[] subset = new Object[count]; - System.arraycopy(array, (int) (index - 1), subset, 0, count); - return subset; - } - - private void checkMap(Map> map) { - if (map != null && map.size() > 0) { - throw DbException.getUnsupportedException("map.size > 0"); - } - } - - /** - * INTERNAL - */ - public String toString() { - return getTraceObjectName() + ": " + value.getTraceSQL(); - } -} diff --git a/tools/h2/src/main/org/h2/jdbc/JdbcBatchUpdateException.java b/tools/h2/src/main/org/h2/jdbc/JdbcBatchUpdateException.java deleted file mode 100755 index 466e686..0000000 --- a/tools/h2/src/main/org/h2/jdbc/JdbcBatchUpdateException.java +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.jdbc; - -import java.io.PrintStream; -import java.io.PrintWriter; -import java.sql.BatchUpdateException; -import java.sql.SQLException; - -/** - * Represents a batch update database exception. - */ -public class JdbcBatchUpdateException extends BatchUpdateException { - - private static final long serialVersionUID = 1L; - - /** - * INTERNAL - */ - JdbcBatchUpdateException(SQLException next, int[] updateCounts) { - super(next.getMessage(), next.getSQLState(), next.getErrorCode(), updateCounts); - } - - /** - * INTERNAL - */ - public void printStackTrace() { - // The default implementation already does that, - // but we do it again to avoid problems. - // If it is not implemented, somebody might implement it - // later on which would be a problem if done in the wrong way. - printStackTrace(System.err); - } - - /** - * INTERNAL - */ - public void printStackTrace(PrintWriter s) { - if (s != null) { - super.printStackTrace(s); - if (getNextException() != null) { - getNextException().printStackTrace(s); - } - } - } - - /** - * INTERNAL - */ - public void printStackTrace(PrintStream s) { - if (s != null) { - super.printStackTrace(s); - if (getNextException() != null) { - getNextException().printStackTrace(s); - } - } - } - -} diff --git a/tools/h2/src/main/org/h2/jdbc/JdbcBlob.java b/tools/h2/src/main/org/h2/jdbc/JdbcBlob.java deleted file mode 100755 index c8e173a..0000000 --- a/tools/h2/src/main/org/h2/jdbc/JdbcBlob.java +++ /dev/null @@ -1,293 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.jdbc; - -import java.io.BufferedInputStream; -import java.io.ByteArrayOutputStream; -import java.io.InputStream; -import java.io.OutputStream; -import java.sql.Blob; -import java.sql.SQLException; - -import org.h2.constant.ErrorCode; -import org.h2.engine.Constants; -import org.h2.message.DbException; -import org.h2.message.TraceObject; -import org.h2.util.IOUtils; -import org.h2.value.Value; - -/** - * Represents a BLOB value. - */ -public class JdbcBlob extends TraceObject implements Blob { - - private Value value; - private JdbcConnection conn; - - /** - * INTERNAL - */ - public JdbcBlob(JdbcConnection conn, Value value, int id) { - setTrace(conn.getSession().getTrace(), TraceObject.BLOB, id); - this.conn = conn; - this.value = value; - } - - /** - * Returns the length. - * - * @return the length - * @throws SQLException - */ - public long length() throws SQLException { - try { - debugCodeCall("length"); - checkClosed(); - if (value.getType() == Value.BLOB) { - long precision = value.getPrecision(); - if (precision > 0) { - return precision; - } - } - long size = 0; - InputStream in = value.getInputStream(); - try { - byte[] buff = new byte[Constants.IO_BUFFER_SIZE]; - while (true) { - int len = in.read(buff, 0, Constants.IO_BUFFER_SIZE); - if (len <= 0) { - break; - } - size += len; - } - } finally { - in.close(); - } - return size; - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * [Not supported] Truncates the object. - * - * @param len the new length - * @throws SQLException - */ - public void truncate(long len) throws SQLException { - throw unsupported("LOB update"); - } - - /** - * Returns some bytes of the object. - * - * @param pos the index, the first byte is at position 1 - * @param length the number of bytes - * @return the bytes, at most length bytes - * @throws SQLException - */ - public byte[] getBytes(long pos, int length) throws SQLException { - try { - debugCode("getBytes("+pos+", "+length+");"); - checkClosed(); - ByteArrayOutputStream out = new ByteArrayOutputStream(); - InputStream in = value.getInputStream(); - try { - IOUtils.skipFully(in, pos - 1); - while (length > 0) { - int x = in.read(); - if (x < 0) { - break; - } - out.write(x); - length--; - } - } finally { - in.close(); - } - return out.toByteArray(); - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * [Not supported] Sets some bytes of the object. - * - * @param pos the write position - * @param bytes the bytes to set - * @return how many bytes have been written - * @throws SQLException - */ - public int setBytes(long pos, byte[] bytes) throws SQLException { - debugCode("setBytes("+pos+", bytes);"); - throw unsupported("LOB update"); - } - - /** - * [Not supported] Sets some bytes of the object. - * - * @param pos the write position - * @param bytes the bytes to set - * @param offset the bytes offset - * @param len the number of bytes to write - * @return how many bytes have been written - * @throws SQLException - */ - public int setBytes(long pos, byte[] bytes, int offset, int len) throws SQLException { - throw unsupported("LOB update"); - } - - /** - * Returns the input stream. - * - * @return the input stream - * @throws SQLException - */ - public InputStream getBinaryStream() throws SQLException { - try { - debugCodeCall("getBinaryStream"); - checkClosed(); - return value.getInputStream(); - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * [Not supported] Returns an output stream. - * - * @param pos where to start writing - * @return the output stream to write into - * @throws SQLException - */ - public OutputStream setBinaryStream(long pos) throws SQLException { - throw unsupported("LOB update"); - } - - /** - * [Not supported] Searches a pattern and return the position. - * - * @param pattern the pattern to search - * @param start the index, the first byte is at position 1 - * @return the position (first byte is at position 1), or -1 for not found - * @throws SQLException - */ - public long position(byte[] pattern, long start) throws SQLException { - debugCode("position(pattern, "+start+");"); - if (Constants.BLOB_SEARCH) { - try { - debugCode("position(pattern, " + start + ");"); - if (pattern == null) { - return -1; - } - if (pattern.length == 0) { - return 1; - } - // TODO performance: blob pattern search is slow - BufferedInputStream in = new BufferedInputStream(value.getInputStream()); - IOUtils.skipFully(in, start - 1); - int pos = 0; - int patternPos = 0; - while (true) { - int x = in.read(); - if (x < 0) { - break; - } - if (x == (pattern[patternPos] & 0xff)) { - if (patternPos == 0) { - in.mark(pattern.length); - } - if (patternPos == pattern.length) { - return pos - patternPos; - } - patternPos++; - } else { - if (patternPos > 0) { - in.reset(); - pos -= patternPos; - } - } - pos++; - } - return -1; - } catch (Exception e) { - throw logAndConvert(e); - } - } - throw unsupported("LOB search"); - } - - /** - * [Not supported] Searches a pattern and return the position. - * - * @param blobPattern the pattern to search - * @param start the index, the first byte is at position 1 - * @return the position (first byte is at position 1), or -1 for not found - * @throws SQLException - */ - public long position(Blob blobPattern, long start) throws SQLException { - debugCode("position(blobPattern, "+start+");"); - if (Constants.BLOB_SEARCH) { - try { - debugCode("position(blobPattern, " + start + ");"); - if (blobPattern == null) { - return -1; - } - ByteArrayOutputStream out = new ByteArrayOutputStream(); - InputStream in = blobPattern.getBinaryStream(); - while (true) { - int x = in.read(); - if (x < 0) { - break; - } - out.write(x); - } - return position(out.toByteArray(), start); - } catch (Exception e) { - throw logAndConvert(e); - } - } - throw unsupported("LOB subset"); - } - - /** - * Release all resources of this object. - */ - public void free() { - debugCodeCall("free"); - value = null; - } - - /** - * [Not supported] Returns the input stream, starting from an offset. - * - * @param pos where to start reading - * @param length the number of bytes that will be read - * @return the input stream to read - * @throws SQLException - */ - public InputStream getBinaryStream(long pos, long length) throws SQLException { - throw unsupported("LOB update"); - } - - private void checkClosed() throws SQLException { - conn.checkClosed(); - if (value == null) { - throw DbException.get(ErrorCode.OBJECT_CLOSED); - } - } - - /** - * INTERNAL - */ - public String toString() { - return getTraceObjectName() + ": " + value.getTraceSQL(); - } - -} diff --git a/tools/h2/src/main/org/h2/jdbc/JdbcCallableStatement.java b/tools/h2/src/main/org/h2/jdbc/JdbcCallableStatement.java deleted file mode 100755 index 1808882..0000000 --- a/tools/h2/src/main/org/h2/jdbc/JdbcCallableStatement.java +++ /dev/null @@ -1,914 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.jdbc; - -import java.io.InputStream; -import java.io.Reader; -import java.math.BigDecimal; -import java.net.URL; -import java.sql.Array; -import java.sql.Blob; -import java.sql.CallableStatement; -import java.sql.Clob; -import java.sql.Date; -import java.sql.Ref; -/*## Java 1.6 begin ## -import java.sql.NClob; -import java.sql.SQLXML; -import java.sql.RowId; -## Java 1.6 end ##*/ -import java.sql.SQLException; -import java.sql.Time; -import java.sql.Timestamp; -import java.util.Calendar; -import java.util.Map; -import org.h2.message.TraceObject; - -/** - * Represents a callable statement. - */ -public class JdbcCallableStatement extends JdbcPreparedStatement implements CallableStatement { - - JdbcCallableStatement(JdbcConnection conn, String sql, int id, int resultSetType, int resultSetConcurrency) { - super(conn, sql, id, resultSetType, resultSetConcurrency, false); - setTrace(session.getTrace(), TraceObject.CALLABLE_STATEMENT, id); - } - - /** - * [Not supported] - */ - public void registerOutParameter(int parameterIndex, int sqlType) throws SQLException { - throw unsupported("registerOutParameter"); - } - - /** - * [Not supported] - */ - public void registerOutParameter(int parameterIndex, int sqlType, int scale) throws SQLException { - throw unsupported("registerOutParameter"); - } - - /** - * [Not supported] - */ - public boolean wasNull() throws SQLException { - throw unsupported("wasNull"); - } - - /** - * [Not supported] - */ - public String getString(int parameterIndex) throws SQLException { - throw unsupportedGet(); - } - - /** - * [Not supported] - */ - public boolean getBoolean(int parameterIndex) throws SQLException { - throw unsupportedGet(); - } - - /** - * [Not supported] - */ - public byte getByte(int parameterIndex) throws SQLException { - throw unsupportedGet(); - } - - /** - * [Not supported] - */ - public short getShort(int parameterIndex) throws SQLException { - throw unsupportedGet(); - } - - /** - * [Not supported] - */ - public int getInt(int parameterIndex) throws SQLException { - throw unsupportedGet(); - } - - /** - * [Not supported] - */ - public long getLong(int parameterIndex) throws SQLException { - throw unsupportedGet(); - } - - /** - * [Not supported] - */ - public float getFloat(int parameterIndex) throws SQLException { - throw unsupportedGet(); - } - - /** - * [Not supported] - */ - public double getDouble(int parameterIndex) throws SQLException { - throw unsupportedGet(); - } - - /** - * [Not supported] - * @deprecated - */ - public BigDecimal getBigDecimal(int parameterIndex, int scale) throws SQLException { - throw unsupportedGet(); - } - - /** - * [Not supported] - */ - public byte[] getBytes(int parameterIndex) throws SQLException { - throw unsupportedGet(); - } - - /** - * [Not supported] - */ - public Date getDate(int parameterIndex) throws SQLException { - throw unsupportedGet(); - } - - /** - * [Not supported] - */ - public Time getTime(int parameterIndex) throws SQLException { - throw unsupportedGet(); - } - - /** - * [Not supported] - */ - public Timestamp getTimestamp(int parameterIndex) throws SQLException { - throw unsupportedGet(); - } - - /** - * [Not supported] - */ - public Object getObject(int parameterIndex) throws SQLException { - throw unsupportedGet(); - } - - /** - * [Not supported] - */ - public BigDecimal getBigDecimal(int parameterIndex) throws SQLException { - throw unsupportedGet(); - } - - /** - * [Not supported] - */ - public Object getObject(int parameterIndex, Map> map) throws SQLException { - throw unsupportedGet(); - } - - /** - * [Not supported] - */ - public Ref getRef(int parameterIndex) throws SQLException { - throw unsupportedGet(); - } - - /** - * [Not supported] - */ - public Blob getBlob(int parameterIndex) throws SQLException { - throw unsupportedGet(); - } - - /** - * [Not supported] - */ - public Clob getClob(int parameterIndex) throws SQLException { - throw unsupportedGet(); - } - - /** - * [Not supported] - */ - public Array getArray(int parameterIndex) throws SQLException { - throw unsupportedGet(); - } - - /** - * [Not supported] - */ - public Date getDate(int parameterIndex, Calendar cal) throws SQLException { - throw unsupportedGet(); - } - - /** - * [Not supported] - */ - public Time getTime(int parameterIndex, Calendar cal) throws SQLException { - throw unsupportedGet(); - } - - /** - * [Not supported] - */ - public Timestamp getTimestamp(int parameterIndex, Calendar cal) throws SQLException { - throw unsupportedGet(); - } - - /** - * [Not supported] - */ - public void registerOutParameter(int paramIndex, int sqlType, String typeName) throws SQLException { - throw unsupported("register"); - } - - /** - * [Not supported] - * - */ - public URL getURL(String parameterName) throws SQLException { - throw unsupportedParameterName(); - } - - /** - * [Not supported] - * - */ - public Timestamp getTimestamp(String parameterName, Calendar cal) throws SQLException { - throw unsupportedParameterName(); - } - - /** - * [Not supported] - */ - public Time getTime(String parameterName, Calendar cal) throws SQLException { - throw unsupportedParameterName(); - } - - /** - * [Not supported] - */ - public Date getDate(String parameterName, Calendar cal) throws SQLException { - throw unsupportedParameterName(); - } - - /** - * [Not supported] - */ - public Array getArray(String parameterName) throws SQLException { - throw unsupportedParameterName(); - } - - /** - * [Not supported] - */ - public Clob getClob(String parameterName) throws SQLException { - throw unsupportedParameterName(); - } - - /** - * [Not supported] - */ - public Blob getBlob(String parameterName) throws SQLException { - throw unsupportedParameterName(); - } - - /** - * [Not supported] - */ - public Ref getRef(String parameterName) throws SQLException { - throw unsupportedParameterName(); - } - - /** - * [Not supported] - */ - public Object getObject(String parameterName, Map> map) throws SQLException { - throw unsupportedParameterName(); - } - - /** - * [Not supported] - */ - public BigDecimal getBigDecimal(String parameterName) throws SQLException { - throw unsupportedParameterName(); - } - - /** - * [Not supported] - */ - public Object getObject(String parameterName) throws SQLException { - throw unsupportedParameterName(); - } - - /** - * [Not supported] - */ - public Timestamp getTimestamp(String parameterName) throws SQLException { - throw unsupportedParameterName(); - } - - /** - * [Not supported] - */ - public Time getTime(String parameterName) throws SQLException { - throw unsupportedParameterName(); - } - - /** - * [Not supported] - */ - public Date getDate(String parameterName) throws SQLException { - throw unsupportedParameterName(); - } - - /** - * [Not supported] - */ - public byte[] getBytes(String parameterName) throws SQLException { - throw unsupportedParameterName(); - } - - /** - * [Not supported] - */ - public double getDouble(String parameterName) throws SQLException { - throw unsupportedParameterName(); - } - - /** - * [Not supported] - */ - public float getFloat(String parameterName) throws SQLException { - throw unsupportedParameterName(); - } - - /** - * [Not supported] - */ - public long getLong(String parameterName) throws SQLException { - throw unsupportedParameterName(); - } - - /** - * [Not supported] - */ - public int getInt(String parameterName) throws SQLException { - throw unsupportedParameterName(); - } - - /** - * [Not supported] - */ - public short getShort(String parameterName) throws SQLException { - throw unsupportedParameterName(); - } - - /** - * [Not supported] - */ - public byte getByte(String parameterName) throws SQLException { - throw unsupportedParameterName(); - } - - /** - * [Not supported] - */ - public boolean getBoolean(String parameterName) throws SQLException { - throw unsupportedParameterName(); - } - - /** - * [Not supported] - */ - public String getString(String parameterName) throws SQLException { - throw unsupportedParameterName(); - } - - // --- setters -------------------------------------------------- - - /** - * [Not supported] - */ - public void setNull(String parameterName, int sqlType, String typeName) throws SQLException { - throw unsupportedParameterName(); - } - - /** - * [Not supported] - */ - public void setTimestamp(String parameterName, Timestamp x, Calendar cal) throws SQLException { - throw unsupportedParameterName(); - } - - /** - * [Not supported] - */ - public void setTime(String parameterName, Time x, Calendar cal) throws SQLException { - throw unsupportedParameterName(); - } - - /** - * [Not supported] - */ - public void setDate(String parameterName, Date x, Calendar cal) throws SQLException { - throw unsupportedParameterName(); - } - - /** - * [Not supported] - */ - public void setCharacterStream(String parameterName, Reader reader, int length) throws SQLException { - throw unsupportedParameterName(); - } - - /** - * [Not supported] - */ - public void setObject(String parameterName, Object x) throws SQLException { - throw unsupportedParameterName(); - } - - /** - * [Not supported] - */ - public void setObject(String parameterName, Object x, int targetSqlType) throws SQLException { - throw unsupportedParameterName(); - } - - /** - * [Not supported] - */ - public void setObject(String parameterName, Object x, int targetSqlType, int scale) throws SQLException { - throw unsupportedParameterName(); - } - - /** - * [Not supported] - */ - public void setBinaryStream(String parameterName, InputStream x, int length) throws SQLException { - throw unsupportedParameterName(); - } - - /** - * [Not supported] - */ -/*## Java 1.6 begin ## - public void setAsciiStream(String parameterName, InputStream x, long length) - throws SQLException { - throw unsupportedParameterName(); - } -## Java 1.6 end ##*/ - - /** - * [Not supported] - */ - public void setTimestamp(String parameterName, Timestamp x) throws SQLException { - throw unsupportedParameterName(); - } - - /** - * [Not supported] - */ - public void setTime(String parameterName, Time x) throws SQLException { - throw unsupportedParameterName(); - } - - /** - * [Not supported] - */ - public void setDate(String parameterName, Date x) throws SQLException { - throw unsupportedParameterName(); - } - - /** - * [Not supported] - */ - public void setBytes(String parameterName, byte[] x) throws SQLException { - throw unsupportedParameterName(); - } - - /** - * [Not supported] - */ - public void setString(String parameterName, String x) throws SQLException { - throw unsupportedParameterName(); - } - - /** - * [Not supported] - */ - public void setBigDecimal(String parameterName, BigDecimal x) throws SQLException { - throw unsupportedParameterName(); - } - - /** - * [Not supported] - */ - public void setDouble(String parameterName, double x) throws SQLException { - throw unsupportedParameterName(); - } - - /** - * [Not supported] - */ - public void setFloat(String parameterName, float x) throws SQLException { - throw unsupportedParameterName(); - } - - /** - * [Not supported] - */ - public void setLong(String parameterName, long x) throws SQLException { - throw unsupportedParameterName(); - } - - /** - * [Not supported] - */ - public void setInt(String parameterName, int x) throws SQLException { - throw unsupportedParameterName(); - } - - /** - * [Not supported] - */ - public void setShort(String parameterName, short x) throws SQLException { - throw unsupportedParameterName(); - } - - /** - * [Not supported] - */ - public void setByte(String parameterName, byte x) throws SQLException { - throw unsupportedParameterName(); - } - - /** - * [Not supported] - */ - public void setBoolean(String parameterName, boolean x) throws SQLException { - throw unsupportedParameterName(); - } - - /** - * [Not supported] - */ - public void setNull(String parameterName, int sqlType) throws SQLException { - throw unsupportedParameterName(); - } - - /** - * [Not supported] - */ - public void setURL(String parameterName, URL val) throws SQLException { - throw unsupportedParameterName(); - } - - /** - * [Not supported] - */ - public URL getURL(int parameterIndex) throws SQLException { - throw unsupported("url"); - } - - // --- other methods -------------------------------------------- - - /** - * [Not supported] - */ - public void registerOutParameter(String parameterName, int sqlType, String typeName) throws SQLException { - throw unsupportedParameterName(); - } - - /** - * [Not supported] - */ - public void registerOutParameter(String parameterName, int sqlType, int scale) throws SQLException { - throw unsupportedParameterName(); - } - - /** - * [Not supported] - */ - public void registerOutParameter(String parameterName, int sqlType) throws SQLException { - throw unsupportedParameterName(); - } - -// ============================================================= - - /** - * [Not supported] - */ -/*## Java 1.6 begin ## - public RowId getRowId(int parameterIndex) throws SQLException { - throw unsupported("rowId"); - } -## Java 1.6 end ##*/ - - /** - * [Not supported] - */ -/*## Java 1.6 begin ## - public RowId getRowId(String parameterName) throws SQLException { - throw unsupportedParameterName(); - } -## Java 1.6 end ##*/ - - /** - * [Not supported] - */ -/*## Java 1.6 begin ## - public void setRowId(String parameterName, RowId x) throws SQLException { - throw unsupportedParameterName(); - } -## Java 1.6 end ##*/ - - /** - * [Not supported] - */ -/*## Java 1.6 begin ## - public void setNString(String parameterName, String value) throws SQLException { - throw unsupportedParameterName(); - } -## Java 1.6 end ##*/ - - /** - * [Not supported] - */ -/*## Java 1.6 begin ## - public void setNCharacterStream(String parameterName, Reader value, long length) - throws SQLException { - throw unsupportedParameterName(); - } -## Java 1.6 end ##*/ - - /** - * [Not supported] - */ -/*## Java 1.6 begin ## - public void setNClob(String parameterName, NClob value) - throws SQLException { - throw unsupportedParameterName(); - } -## Java 1.6 end ##*/ - - /** - * [Not supported] - */ -/*## Java 1.6 begin ## - public void setClob(String parameterName, Reader reader, long length) - throws SQLException { - throw unsupportedParameterName(); - } -## Java 1.6 end ##*/ - - /** - * [Not supported] - */ -/*## Java 1.6 begin ## - public void setBlob(String parameterName, InputStream inputStream, long length) - throws SQLException { - throw unsupportedParameterName(); - } -## Java 1.6 end ##*/ - - /** - * [Not supported] - */ -/*## Java 1.6 begin ## - public void setNClob(String parameterName, Reader reader, long length) - throws SQLException { - throw unsupportedParameterName(); - } -## Java 1.6 end ##*/ - - /** - * [Not supported] - */ -/*## Java 1.6 begin ## - public NClob getNClob(int parameterIndex) throws SQLException { - throw unsupportedGet(); - } -## Java 1.6 end ##*/ - - /** - * [Not supported] - */ -/*## Java 1.6 begin ## - public NClob getNClob(String parameterName) throws SQLException { - throw unsupportedGet(); - } -## Java 1.6 end ##*/ - - /** - * [Not supported] - */ -/*## Java 1.6 begin ## - public void setSQLXML(String parameterName, SQLXML xmlObject) - throws SQLException { - throw unsupportedParameterName(); - } -## Java 1.6 end ##*/ - - /** - * [Not supported] - */ -/*## Java 1.6 begin ## - public SQLXML getSQLXML(int parameterIndex) throws SQLException { - throw unsupportedGet(); - } -## Java 1.6 end ##*/ - - /** - * [Not supported] - */ -/*## Java 1.6 begin ## - public SQLXML getSQLXML(String parameterName) throws SQLException { - throw unsupportedGet(); - } -## Java 1.6 end ##*/ - - /** - * [Not supported] - */ -/*## Java 1.6 begin ## - public String getNString(int parameterIndex) throws SQLException { - throw unsupportedGet(); - } -## Java 1.6 end ##*/ - - /** - * [Not supported] - */ -/*## Java 1.6 begin ## - public String getNString(String parameterName) throws SQLException { - throw unsupportedGet(); - } -## Java 1.6 end ##*/ - - /** - * [Not supported] - */ -/*## Java 1.6 begin ## - public Reader getNCharacterStream(int parameterIndex) throws SQLException { - throw unsupportedGet(); - } -## Java 1.6 end ##*/ - - /** - * [Not supported] - */ -/*## Java 1.6 begin ## - public Reader getNCharacterStream(String parameterName) throws SQLException { - throw unsupportedGet(); - } -## Java 1.6 end ##*/ - - /** - * [Not supported] - */ -/*## Java 1.6 begin ## - public Reader getCharacterStream(int parameterIndex) throws SQLException { - throw unsupportedGet(); - } -## Java 1.6 end ##*/ - - /** - * [Not supported] - */ -/*## Java 1.6 begin ## - public Reader getCharacterStream(String parameterName) throws SQLException { - throw unsupportedGet(); - } -## Java 1.6 end ##*/ - - /** - * [Not supported] - */ -/*## Java 1.6 begin ## - public void setBlob(String parameterName, Blob x) throws SQLException { - throw unsupportedParameterName(); - } -## Java 1.6 end ##*/ - - /** - * [Not supported] - */ -/*## Java 1.6 begin ## - public void setClob(String parameterName, Clob x) throws SQLException { - throw unsupportedParameterName(); - } -## Java 1.6 end ##*/ - - /** - * [Not supported] - */ -/*## Java 1.6 begin ## - public void setAsciiStream(String parameterName, InputStream x) - throws SQLException { - throw unsupportedParameterName(); - } -## Java 1.6 end ##*/ - - /** - * [Not supported] - */ - public void setAsciiStream(String parameterName, InputStream x, int length) throws SQLException { - throw unsupportedParameterName(); - } - - /** - * [Not supported] - */ -/*## Java 1.6 begin ## - public void setBinaryStream(String parameterName, InputStream x) - throws SQLException { - throw unsupportedParameterName(); - } -## Java 1.6 end ##*/ - - /** - * [Not supported] - */ -/*## Java 1.6 begin ## - public void setBinaryStream(String parameterName, InputStream x, long length) - throws SQLException { - throw unsupportedParameterName(); - } -## Java 1.6 end ##*/ - - /** - * [Not supported] - */ -/*## Java 1.6 begin ## - public void setBlob(String parameterName, InputStream x) - throws SQLException { - throw unsupportedParameterName(); - } -## Java 1.6 end ##*/ - - /** - * [Not supported] - */ -/*## Java 1.6 begin ## - public void setCharacterStream(String parameterName, Reader x) - throws SQLException { - throw unsupportedParameterName(); - } -## Java 1.6 end ##*/ - - /** - * [Not supported] - */ -/*## Java 1.6 begin ## - public void setCharacterStream(String parameterName, Reader x, long length) - throws SQLException { - throw unsupportedParameterName(); - } -## Java 1.6 end ##*/ - - /** - * [Not supported] - */ -/*## Java 1.6 begin ## - public void setClob(String parameterName, Reader x) throws SQLException { - throw unsupportedParameterName(); - } -## Java 1.6 end ##*/ - - /** - * [Not supported] - */ -/*## Java 1.6 begin ## - public void setNCharacterStream(String parameterName, Reader x) - throws SQLException { - throw unsupportedParameterName(); - } -## Java 1.6 end ##*/ - - /** - * [Not supported] - * @throws SQLException - */ -/*## Java 1.6 begin ## - public void setNClob(String parameterName, Reader x) throws SQLException { - throw unsupportedParameterName(); - } -## Java 1.6 end ##*/ - - private SQLException unsupportedParameterName() throws SQLException { - return unsupported("parameterName"); - } - - private SQLException unsupportedGet() throws SQLException { - return unsupported("get"); - } - -} diff --git a/tools/h2/src/main/org/h2/jdbc/JdbcClob.java b/tools/h2/src/main/org/h2/jdbc/JdbcClob.java deleted file mode 100755 index 2790bf0..0000000 --- a/tools/h2/src/main/org/h2/jdbc/JdbcClob.java +++ /dev/null @@ -1,231 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.jdbc; - -import java.io.InputStream; -import java.io.OutputStream; -import java.io.Reader; -import java.io.Writer; -import java.sql.Clob; -import java.sql.SQLException; - -import org.h2.constant.ErrorCode; -import org.h2.engine.Constants; -import org.h2.message.DbException; -import org.h2.message.TraceObject; -import org.h2.util.IOUtils; -import org.h2.value.Value; - -/*## Java 1.6 begin ## -import java.sql.NClob; -## Java 1.6 end ##*/ - -/** - * Represents a CLOB value. - */ -public class JdbcClob extends TraceObject implements Clob -/*## Java 1.6 begin ## - , NClob -## Java 1.6 end ##*/ -{ - - private Value value; - private JdbcConnection conn; - - /** - * INTERNAL - */ - public JdbcClob(JdbcConnection conn, Value value, int id) { - setTrace(conn.getSession().getTrace(), TraceObject.CLOB, id); - this.conn = conn; - this.value = value; - } - - /** - * Returns the length. - * - * @return the length - */ - public long length() throws SQLException { - try { - debugCodeCall("length"); - checkClosed(); - if (value.getType() == Value.CLOB) { - long precision = value.getPrecision(); - if (precision > 0) { - return precision; - } - } - Reader in = value.getReader(); - try { - long size = 0; - char[] buff = new char[Constants.IO_BUFFER_SIZE]; - while (true) { - int len = in.read(buff, 0, Constants.IO_BUFFER_SIZE); - if (len <= 0) { - break; - } - size += len; - } - return size; - } finally { - in.close(); - } - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * [Not supported] Truncates the object. - */ - public void truncate(long len) throws SQLException { - throw unsupported("LOB update"); - } - - /** - * Returns the input stream. - * - * @return the input stream - */ - public InputStream getAsciiStream() throws SQLException { - try { - debugCodeCall("getAsciiStream"); - checkClosed(); - String s = value.getString(); - return IOUtils.getInputStream(s); - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * [Not supported] Returns an output stream. - */ - public OutputStream setAsciiStream(long pos) throws SQLException { - throw unsupported("LOB update"); - } - - /** - * Returns the reader. - * - * @return the reader - */ - public Reader getCharacterStream() throws SQLException { - try { - debugCodeCall("getCharacterStream"); - checkClosed(); - return value.getReader(); - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * [Not supported] Returns a writer starting from a given position. - */ - public Writer setCharacterStream(long pos) throws SQLException { - throw unsupported("LOB update"); - } - - /** - * Returns a substring. - * - * @param pos the position (the first character is at position 1) - * @param length the number of characters - * @return the string - */ - public String getSubString(long pos, int length) throws SQLException { - try { - debugCode("getSubString(" + pos + ", " + length + ");"); - checkClosed(); - if (pos < 1) { - throw DbException.getInvalidValueException("pos", "" + pos); - } - if (length < 0) { - throw DbException.getInvalidValueException("length", "" + length); - } - StringBuilder buff = new StringBuilder(Math.min(4096, length)); - Reader reader = value.getReader(); - try { - IOUtils.skipFully(reader, pos - 1); - for (int i = 0; i < length; i++) { - int ch = reader.read(); - if (ch < 0) { - break; - } - buff.append((char) ch); - } - } finally { - reader.close(); - } - return buff.toString(); - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * [Not supported] Sets a substring. - */ - public int setString(long pos, String str) throws SQLException { - throw unsupported("LOB update"); - } - - /** - * [Not supported] Sets a substring. - */ - public int setString(long pos, String str, int offset, int len) throws SQLException { - throw unsupported("LOB update"); - } - - /** - * [Not supported] Searches a pattern and return the position. - */ - public long position(String pattern, long start) throws SQLException { - throw unsupported("LOB search"); - } - - /** - * [Not supported] Searches a pattern and return the position. - */ - public long position(Clob clobPattern, long start) throws SQLException { - throw unsupported("LOB search"); - } - - /** - * Release all resources of this object. - */ - public void free() { - debugCodeCall("free"); - value = null; - } - - /** - * [Not supported] Returns the reader, starting from an offset. - */ -/*## Java 1.6 begin ## - public Reader getCharacterStream(long pos, long length) throws SQLException { - throw unsupported("LOB subset"); - } -## Java 1.6 end ##*/ - - private void checkClosed() throws SQLException { - conn.checkClosed(); - if (value == null) { - throw DbException.get(ErrorCode.OBJECT_CLOSED); - } - } - - /** - * INTERNAL - */ - public String toString() { - return getTraceObjectName() + ": " + value.getTraceSQL(); - } - -} diff --git a/tools/h2/src/main/org/h2/jdbc/JdbcConnection.java b/tools/h2/src/main/org/h2/jdbc/JdbcConnection.java deleted file mode 100755 index 3ad5dfe..0000000 --- a/tools/h2/src/main/org/h2/jdbc/JdbcConnection.java +++ /dev/null @@ -1,1710 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.jdbc; - -import java.io.ByteArrayInputStream; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.io.Reader; -import java.sql.Blob; -import java.sql.CallableStatement; -import java.sql.Clob; -import java.sql.Connection; -import java.sql.DatabaseMetaData; -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.sql.SQLWarning; -import java.sql.Savepoint; -import java.sql.Statement; -import java.util.Map; -import java.util.Properties; -import org.h2.command.CommandInterface; -import org.h2.constant.ErrorCode; -import org.h2.constant.SysProperties; -import org.h2.engine.ConnectionInfo; -import org.h2.engine.Constants; -import org.h2.engine.SessionInterface; -import org.h2.engine.SessionRemote; -import org.h2.message.DbException; -import org.h2.message.Trace; -import org.h2.message.TraceObject; -import org.h2.result.ResultInterface; -import org.h2.util.Utils; -import org.h2.value.CompareMode; -import org.h2.value.Value; -import org.h2.value.ValueInt; -import org.h2.value.ValueNull; -import org.h2.value.ValueString; - -/*## Java 1.6 begin ## -import java.sql.Array; -import java.sql.NClob; -import java.sql.Struct; -import java.sql.SQLXML; -import java.sql.SQLClientInfoException; -## Java 1.6 end ##*/ - -/** - *

- * Represents a connection (session) to a database. - *

- *

- * Thread safety: the connection is thread-safe, because access - * is synchronized. However, for compatibility with other databases, a - * connection should only be used in one thread at any time. - *

- */ -public class JdbcConnection extends TraceObject implements Connection { - - /** - * The stack trace of when the connection was created. - */ - protected Exception openStackTrace; - - private String url; - private String user; - - // ResultSet.HOLD_CURSORS_OVER_COMMIT - private int holdability = 1; - - private SessionInterface session; - private CommandInterface commit, rollback; - private CommandInterface setAutoCommitTrue, setAutoCommitFalse, getAutoCommit; - private CommandInterface getReadOnly, getGeneratedKeys; - private CommandInterface setLockMode, getLockMode; - private CommandInterface setQueryTimeout, getQueryTimeout; - - //## Java 1.4 begin ## - private int savepointId; - //## Java 1.4 end ## - private Trace trace; - private boolean isInternal; - private String catalog; - private Statement executingStatement; - private CompareMode compareMode = CompareMode.getInstance(null, 0); - - /** - * INTERNAL - */ - public JdbcConnection(String url, Properties info) throws SQLException { - this(new ConnectionInfo(url, info), true); - } - - /** - * INTERNAL - */ - public JdbcConnection(ConnectionInfo ci, boolean useBaseDir) throws SQLException { - try { - if (useBaseDir) { - String baseDir = SysProperties.getBaseDir(); - if (baseDir != null) { - ci.setBaseDir(baseDir); - } - } - checkJavaVersion(); - // this will return an embedded or server connection - session = new SessionRemote().createSession(ci); - trace = session.getTrace(); - int id = getNextId(TraceObject.CONNECTION); - setTrace(trace, TraceObject.CONNECTION, id); - this.user = ci.getUserName(); - if (isInfoEnabled()) { - trace.infoCode("Connection " + getTraceObjectName() - + " = DriverManager.getConnection(" + quote(ci.getOriginalURL()) - + ", " + quote(user) + ", \"\");"); - } - this.url = ci.getURL(); - openStackTrace = new Exception("Stack Trace"); - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * INTERNAL - */ - public JdbcConnection(JdbcConnection clone) { - this.session = clone.session; - trace = session.getTrace(); - int id = getNextId(TraceObject.CONNECTION); - setTrace(trace, TraceObject.CONNECTION, id); - this.user = clone.user; - this.url = clone.url; - } - - /** - * INTERNAL - */ - public JdbcConnection(SessionInterface session, String user, String url) { - isInternal = true; - this.session = session; - trace = session.getTrace(); - int id = getNextId(TraceObject.CONNECTION); - setTrace(trace, TraceObject.CONNECTION, id); - this.user = user; - this.url = url; - } - - /** - * Creates a new statement. - * - * @return the new statement - * @throws SQLException if the connection is closed - */ - public Statement createStatement() throws SQLException { - try { - int id = getNextId(TraceObject.STATEMENT); - if (isDebugEnabled()) { - debugCodeAssign("Statement", TraceObject.STATEMENT, id, "createStatement()"); - } - checkClosed(); - return new JdbcStatement(this, id, ResultSet.TYPE_FORWARD_ONLY, SysProperties.DEFAULT_RESULT_SET_CONCURRENCY, false); - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Creates a statement with the specified result set type and concurrency. - * - * @return the statement - * @throws SQLException - * if the connection is closed or the result set type or - * concurrency are not supported - */ - public Statement createStatement(int resultSetType, int resultSetConcurrency) throws SQLException { - try { - int id = getNextId(TraceObject.STATEMENT); - if (isDebugEnabled()) { - debugCodeAssign("Statement", TraceObject.STATEMENT, id, "createStatement(" + resultSetType + ", " + resultSetConcurrency + ")"); - } - checkTypeConcurrency(resultSetType, resultSetConcurrency); - checkClosed(); - return new JdbcStatement(this, id, resultSetType, resultSetConcurrency, false); - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Creates a statement with the specified result set type, concurrency, and - * holdability. - * - * @return the statement - * @throws SQLException if the connection is closed or the result set type, - * concurrency, or holdability are not supported - */ - public Statement createStatement(int resultSetType, int resultSetConcurrency, int resultSetHoldability) - throws SQLException { - try { - int id = getNextId(TraceObject.STATEMENT); - if (isDebugEnabled()) { - debugCodeAssign("Statement", TraceObject.STATEMENT, id, - "createStatement(" + resultSetType + ", " + resultSetConcurrency + ", " + resultSetHoldability + ")"); - } - checkTypeConcurrency(resultSetType, resultSetConcurrency); - checkHoldability(resultSetHoldability); - checkClosed(); - return new JdbcStatement(this, id, resultSetType, resultSetConcurrency, false); - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Creates a new prepared statement. - * - * @return the prepared statement - * @throws SQLException - * if the connection is closed - */ - public PreparedStatement prepareStatement(String sql) throws SQLException { - try { - int id = getNextId(TraceObject.PREPARED_STATEMENT); - if (isDebugEnabled()) { - debugCodeAssign("PreparedStatement", TraceObject.PREPARED_STATEMENT, id, "prepareStatement(" + quote(sql) + ")"); - } - checkClosed(); - sql = translateSQL(sql); - return new JdbcPreparedStatement(this, sql, id, ResultSet.TYPE_FORWARD_ONLY, SysProperties.DEFAULT_RESULT_SET_CONCURRENCY, false); - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Prepare a statement that will automatically close when the result set is - * closed. This method is used to retrieve database meta data. - * - * @param sql the SQL statement. - * @return the prepared statement - */ - PreparedStatement prepareAutoCloseStatement(String sql) throws SQLException { - try { - int id = getNextId(TraceObject.PREPARED_STATEMENT); - if (isDebugEnabled()) { - debugCodeAssign("PreparedStatement", TraceObject.PREPARED_STATEMENT, id, "prepareStatement(" + quote(sql) + ")"); - } - checkClosed(); - sql = translateSQL(sql); - return new JdbcPreparedStatement(this, sql, id, ResultSet.TYPE_FORWARD_ONLY, SysProperties.DEFAULT_RESULT_SET_CONCURRENCY, true); - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Gets the database meta data for this database. - * - * @return the database meta data - * @throws SQLException - * if the connection is closed - */ - public DatabaseMetaData getMetaData() throws SQLException { - try { - int id = getNextId(TraceObject.DATABASE_META_DATA); - if (isDebugEnabled()) { - debugCodeAssign("DatabaseMetaData", TraceObject.DATABASE_META_DATA, id, "getMetaData()"); - } - checkClosed(); - return new JdbcDatabaseMetaData(this, trace, id); - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * INTERNAL - */ - public SessionInterface getSession() { - return session; - } - - /** - * Closes this connection. All open statements, prepared statements and - * result sets that where created by this connection become invalid after - * calling this method. If there is an uncommitted transaction, it will be - * rolled back. - */ - public synchronized void close() throws SQLException { - try { - debugCodeCall("close"); - openStackTrace = null; - if (executingStatement != null) { - executingStatement.cancel(); - } - if (session == null) { - return; - } - session.cancel(); - try { - synchronized (session) { - if (!session.isClosed()) { - try { - // roll back unless that would require to re-connect - // (the transaction can't be rolled back after re-connecting) - if (!session.isReconnectNeeded(true)) { - rollbackInternal(); - session.afterWriting(); - } - closePreparedCommands(); - } finally { - session.close(); - } - } - } - } finally { - session = null; - } - } catch (Exception e) { - throw logAndConvert(e); - } - } - - private void closePreparedCommands() { - commit = closeAndSetNull(commit); - rollback = closeAndSetNull(rollback); - setAutoCommitTrue = closeAndSetNull(setAutoCommitTrue); - setAutoCommitFalse = closeAndSetNull(setAutoCommitFalse); - getAutoCommit = closeAndSetNull(getAutoCommit); - getReadOnly = closeAndSetNull(getReadOnly); - getGeneratedKeys = closeAndSetNull(getGeneratedKeys); - getLockMode = closeAndSetNull(getLockMode); - setLockMode = closeAndSetNull(setLockMode); - getQueryTimeout = closeAndSetNull(getQueryTimeout); - setQueryTimeout = closeAndSetNull(setQueryTimeout); - } - - private CommandInterface closeAndSetNull(CommandInterface command) { - if (command != null) { - command.close(); - } - return null; - } - - /** - * Switches auto commit on or off. Calling this function does not commit the - * current transaction. - * - * @param autoCommit - * true for auto commit on, false for off - * @throws SQLException - * if the connection is closed - */ - public synchronized void setAutoCommit(boolean autoCommit) throws SQLException { - try { - if (isDebugEnabled()) { - debugCode("setAutoCommit(" + autoCommit + ");"); - } - checkClosed(); - if (autoCommit) { - setAutoCommitTrue = prepareCommand("SET AUTOCOMMIT TRUE", setAutoCommitTrue); - setAutoCommitTrue.executeUpdate(); - } else { - setAutoCommitFalse = prepareCommand("SET AUTOCOMMIT FALSE", setAutoCommitFalse); - setAutoCommitFalse.executeUpdate(); - } - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Gets the current setting for auto commit. - * - * @return true for on, false for off - * @throws SQLException - * if the connection is closed - */ - public synchronized boolean getAutoCommit() throws SQLException { - try { - checkClosed(); - debugCodeCall("getAutoCommit"); - return getInternalAutoCommit(); - } catch (Exception e) { - throw logAndConvert(e); - } - } - - private boolean getInternalAutoCommit() { - getAutoCommit = prepareCommand("CALL AUTOCOMMIT()", getAutoCommit); - ResultInterface result = getAutoCommit.executeQuery(0, false); - result.next(); - boolean autoCommit = result.currentRow()[0].getBoolean().booleanValue(); - result.close(); - return autoCommit; - } - - /** - * Commits the current transaction. This call has only an effect if - * auto commit is switched off. - * - * @throws SQLException - * if the connection is closed - */ - public synchronized void commit() throws SQLException { - try { - debugCodeCall("commit"); - checkClosedForWrite(); - try { - commit = prepareCommand("COMMIT", commit); - commit.executeUpdate(); - } finally { - afterWriting(); - } - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Rolls back the current transaction. This call has only an effect if - * auto commit is switched off. - * - * @throws SQLException - * if the connection is closed - */ - public synchronized void rollback() throws SQLException { - try { - debugCodeCall("rollback"); - checkClosedForWrite(); - try { - rollbackInternal(); - } finally { - afterWriting(); - } - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Returns true if this connection has been closed. - * - * @return true if close was called - */ - public boolean isClosed() throws SQLException { - try { - debugCodeCall("isClosed"); - return session == null || session.isClosed(); - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Translates a SQL statement into the database grammar. - * - * @return the translated statement - * @throws SQLException - * if the connection is closed - */ - public String nativeSQL(String sql) throws SQLException { - try { - debugCodeCall("nativeSQL", sql); - checkClosed(); - return translateSQL(sql); - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * According to the JDBC specs, this - * setting is only a hint to the database to enable optimizations - it does - * not cause writes to be prohibited. - * - * @throws SQLException - * if the connection is closed - */ - public void setReadOnly(boolean readOnly) throws SQLException { - try { - if (isDebugEnabled()) { - debugCode("setReadOnly(" + readOnly + ");"); - } - checkClosed(); - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Returns true if the database is read-only. - * - * @return if the database is read-only - * @throws SQLException - * if the connection is closed - */ - public boolean isReadOnly() throws SQLException { - try { - debugCodeCall("isReadOnly"); - checkClosed(); - getReadOnly = prepareCommand("CALL READONLY()", getReadOnly); - ResultInterface result = getReadOnly.executeQuery(0, false); - result.next(); - boolean readOnly = result.currentRow()[0].getBoolean().booleanValue(); - return readOnly; - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Set the default catalog name. - * This call is ignored. - * - * @throws SQLException if the connection is closed - */ - public void setCatalog(String catalog) throws SQLException { - try { - debugCodeCall("setCatalog", catalog); - checkClosed(); - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Gets the current catalog name. - * - * @return the catalog name - * @throws SQLException if the connection is closed - */ - public String getCatalog() throws SQLException { - try { - debugCodeCall("getCatalog"); - checkClosed(); - if (catalog == null) { - CommandInterface cat = prepareCommand("CALL DATABASE()", Integer.MAX_VALUE); - ResultInterface result = cat.executeQuery(0, false); - result.next(); - catalog = result.currentRow()[0].getString(); - cat.close(); - } - return catalog; - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Gets the first warning reported by calls on this object. - * - * @return null - */ - public SQLWarning getWarnings() throws SQLException { - try { - debugCodeCall("getWarnings"); - checkClosed(); - return null; - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Clears all warnings. - */ - public void clearWarnings() throws SQLException { - try { - debugCodeCall("clearWarnings"); - checkClosed(); - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Creates a prepared statement with the specified result set type and - * concurrency. - * - * @return the prepared statement - * @throws SQLException - * if the connection is closed or the result set type or - * concurrency are not supported - */ - public PreparedStatement prepareStatement(String sql, int resultSetType, int resultSetConcurrency) throws SQLException { - try { - int id = getNextId(TraceObject.PREPARED_STATEMENT); - if (isDebugEnabled()) { - debugCodeAssign("PreparedStatement", TraceObject.PREPARED_STATEMENT, id, "prepareStatement(" + quote(sql) + ", " + resultSetType + ", " + resultSetConcurrency + ")"); - } - checkTypeConcurrency(resultSetType, resultSetConcurrency); - checkClosed(); - sql = translateSQL(sql); - return new JdbcPreparedStatement(this, sql, id, resultSetType, resultSetConcurrency, false); - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Changes the current transaction isolation level. Calling this method will - * commit an open transaction, even if the new level is the same as the old - * one, except if the level is not supported. Internally, this method calls - * SET LOCK_MODE. The following isolation levels are supported: - *
    - *
  • Connection.TRANSACTION_READ_UNCOMMITTED = SET LOCK_MODE 0: no - * locking (should only be used for testing).
  • - *
  • Connection.TRANSACTION_SERIALIZABLE = SET LOCK_MODE 1: table level - * locking.
  • - *
  • Connection.TRANSACTION_READ_COMMITTED = SET LOCK_MODE 3: table - * level locking, but read locks are released immediately (default).
  • - *
- * This setting is not persistent. Please note that using - * TRANSACTION_READ_UNCOMMITTED while at the same time using multiple - * connections may result in inconsistent transactions. - * - * @param level the new transaction isolation level: - * Connection.TRANSACTION_READ_UNCOMMITTED, - * Connection.TRANSACTION_READ_COMMITTED, or - * Connection.TRANSACTION_SERIALIZABLE - * @throws SQLException if the connection is closed or the isolation level - * is not supported - */ - public void setTransactionIsolation(int level) throws SQLException { - try { - debugCodeCall("setTransactionIsolation", level); - checkClosed(); - int lockMode; - switch(level) { - case Connection.TRANSACTION_READ_UNCOMMITTED: - lockMode = Constants.LOCK_MODE_OFF; - break; - case Connection.TRANSACTION_READ_COMMITTED: - lockMode = Constants.LOCK_MODE_READ_COMMITTED; - break; - case Connection.TRANSACTION_REPEATABLE_READ: - case Connection.TRANSACTION_SERIALIZABLE: - lockMode = Constants.LOCK_MODE_TABLE; - break; - default: - throw DbException.getInvalidValueException("" + level, "level"); - } - commit(); - setLockMode = prepareCommand("SET LOCK_MODE ?", setLockMode); - setLockMode.getParameters().get(0).setValue(ValueInt.get(lockMode), false); - setLockMode.executeUpdate(); - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * INTERNAL - */ - public void setQueryTimeout(int seconds) throws SQLException { - try { - debugCodeCall("setQueryTimeout", seconds); - checkClosed(); - setQueryTimeout = prepareCommand("SET QUERY_TIMEOUT ?", setQueryTimeout); - setQueryTimeout.getParameters().get(0).setValue(ValueInt.get(seconds * 1000), false); - setQueryTimeout.executeUpdate(); - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * INTERNAL - */ - public int getQueryTimeout() throws SQLException { - try { - debugCodeCall("getQueryTimeout"); - checkClosed(); - getQueryTimeout = prepareCommand("SELECT VALUE FROM INFORMATION_SCHEMA.SETTINGS WHERE NAME=?", getQueryTimeout); - getQueryTimeout.getParameters().get(0).setValue(ValueString.get("QUERY_TIMEOUT"), false); - ResultInterface result = getQueryTimeout.executeQuery(0, false); - result.next(); - int queryTimeout = result.currentRow()[0].getInt(); - result.close(); - if (queryTimeout == 0) { - return 0; - } - // round to the next second, otherwise 999 millis would return 0 seconds - return (queryTimeout + 999) / 1000; - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Returns the current transaction isolation level. - * - * @return the isolation level. - * @throws SQLException if the connection is closed - */ - public int getTransactionIsolation() throws SQLException { - try { - debugCodeCall("getTransactionIsolation"); - checkClosed(); - getLockMode = prepareCommand("CALL LOCK_MODE()", getLockMode); - ResultInterface result = getLockMode.executeQuery(0, false); - result.next(); - int lockMode = result.currentRow()[0].getInt(); - result.close(); - int transactionIsolationLevel; - switch(lockMode) { - case Constants.LOCK_MODE_OFF: - transactionIsolationLevel = Connection.TRANSACTION_READ_UNCOMMITTED; - break; - case Constants.LOCK_MODE_READ_COMMITTED: - transactionIsolationLevel = Connection.TRANSACTION_READ_COMMITTED; - break; - case Constants.LOCK_MODE_TABLE: - case Constants.LOCK_MODE_TABLE_GC: - transactionIsolationLevel = Connection.TRANSACTION_SERIALIZABLE; - break; - default: - throw DbException.throwInternalError("lockMode:" + lockMode); - } - return transactionIsolationLevel; - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Changes the current result set holdability. - * - * @param holdability - * ResultSet.HOLD_CURSORS_OVER_COMMIT or - * ResultSet.CLOSE_CURSORS_AT_COMMIT; - * @throws SQLException - * if the connection is closed or the holdability is not - * supported - */ - public void setHoldability(int holdability) throws SQLException { - try { - debugCodeCall("setHoldability", holdability); - checkClosed(); - checkHoldability(holdability); - this.holdability = holdability; - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Returns the current result set holdability. - * - * @return the holdability - * @throws SQLException if the connection is closed - */ - public int getHoldability() throws SQLException { - try { - debugCodeCall("getHoldability"); - checkClosed(); - return holdability; - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Gets the type map. - * - * @return null - * @throws SQLException - * if the connection is closed - */ - public Map> getTypeMap() throws SQLException { - try { - debugCodeCall("getTypeMap"); - checkClosed(); - return null; - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * [Partially supported] Sets the type map. This is only supported if the - * map is empty or null. - */ - public void setTypeMap(Map> map) throws SQLException { - try { - debugCode("setTypeMap(" + quoteMap(map) + ");"); - checkMap(map); - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Creates a new callable statement. - * - * @return the callable statement - * @throws SQLException - * if the connection is closed or the statement is not valid - */ - public CallableStatement prepareCall(String sql) throws SQLException { - try { - int id = getNextId(TraceObject.CALLABLE_STATEMENT); - if (isDebugEnabled()) { - debugCodeAssign("CallableStatement", TraceObject.CALLABLE_STATEMENT, id, "prepareCall(" + quote(sql) + ")"); - } - checkClosed(); - sql = translateSQL(sql); - return new JdbcCallableStatement(this, sql, id, ResultSet.TYPE_FORWARD_ONLY, SysProperties.DEFAULT_RESULT_SET_CONCURRENCY); - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Creates a callable statement with the specified result set type and - * concurrency. - * - * @return the callable statement - * @throws SQLException - * if the connection is closed or the result set type or - * concurrency are not supported - */ - public CallableStatement prepareCall(String sql, int resultSetType, int resultSetConcurrency) throws SQLException { - try { - int id = getNextId(TraceObject.CALLABLE_STATEMENT); - if (isDebugEnabled()) { - debugCodeAssign("CallableStatement", TraceObject.CALLABLE_STATEMENT, id, "prepareCall(" + quote(sql) + ", " + resultSetType + ", " + resultSetConcurrency + ")"); - } - checkTypeConcurrency(resultSetType, resultSetConcurrency); - checkClosed(); - sql = translateSQL(sql); - return new JdbcCallableStatement(this, sql, id, resultSetType, resultSetConcurrency); - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Creates a callable statement with the specified result set type, - * concurrency, and holdability. - * - * @return the callable statement - * @throws SQLException - * if the connection is closed or the result set type, - * concurrency, or holdability are not supported - */ - public CallableStatement prepareCall(String sql, int resultSetType, - int resultSetConcurrency, int resultSetHoldability) throws SQLException { - try { - int id = getNextId(TraceObject.CALLABLE_STATEMENT); - if (isDebugEnabled()) { - debugCodeAssign("CallableStatement", TraceObject.CALLABLE_STATEMENT, id, - "prepareCall(" + quote(sql) + ", " + resultSetType + ", " + resultSetConcurrency + ", " - + resultSetHoldability + ")"); - } - checkTypeConcurrency(resultSetType, resultSetConcurrency); - checkHoldability(resultSetHoldability); - checkClosed(); - sql = translateSQL(sql); - return new JdbcCallableStatement(this, sql, id, resultSetType, resultSetConcurrency); - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Creates a new unnamed savepoint. - * - * @return the new savepoint - */ -//## Java 1.4 begin ## - public Savepoint setSavepoint() throws SQLException { - try { - int id = getNextId(TraceObject.SAVEPOINT); - if (isDebugEnabled()) { - debugCodeAssign("Savepoint", TraceObject.SAVEPOINT, id, "setSavepoint()"); - } - checkClosed(); - CommandInterface set = prepareCommand("SAVEPOINT " + JdbcSavepoint.getName(null, savepointId), Integer.MAX_VALUE); - set.executeUpdate(); - JdbcSavepoint savepoint = new JdbcSavepoint(this, savepointId, null, trace, id); - savepointId++; - return savepoint; - } catch (Exception e) { - throw logAndConvert(e); - } - } -//## Java 1.4 end ## - - /** - * Creates a new named savepoint. - * - * @param name the savepoint name - * @return the new savepoint - */ -//## Java 1.4 begin ## - public Savepoint setSavepoint(String name) throws SQLException { - try { - int id = getNextId(TraceObject.SAVEPOINT); - if (isDebugEnabled()) { - debugCodeAssign("Savepoint", TraceObject.SAVEPOINT, id, "setSavepoint(" + quote(name) + ")"); - } - checkClosed(); - CommandInterface set = prepareCommand("SAVEPOINT " + JdbcSavepoint.getName(name, 0), Integer.MAX_VALUE); - set.executeUpdate(); - JdbcSavepoint savepoint = new JdbcSavepoint(this, 0, name, trace, id); - return savepoint; - } catch (Exception e) { - throw logAndConvert(e); - } - } -//## Java 1.4 end ## - - /** - * Rolls back to a savepoint. - * - * @param savepoint the savepoint - */ -//## Java 1.4 begin ## - public void rollback(Savepoint savepoint) throws SQLException { - try { - JdbcSavepoint sp = convertSavepoint(savepoint); - debugCode("rollback(" + sp.getTraceObjectName() + ");"); - checkClosedForWrite(); - try { - sp.rollback(); - } finally { - afterWriting(); - } - } catch (Exception e) { - throw logAndConvert(e); - } - } -//## Java 1.4 end ## - - /** - * Releases a savepoint. - * - * @param savepoint the savepoint to release - */ -//## Java 1.4 begin ## - public void releaseSavepoint(Savepoint savepoint) throws SQLException { - try { - debugCode("releaseSavepoint(savepoint);"); - checkClosed(); - convertSavepoint(savepoint).release(); - } catch (Exception e) { - throw logAndConvert(e); - } - } - - private JdbcSavepoint convertSavepoint(Savepoint savepoint) { - if (!(savepoint instanceof JdbcSavepoint)) { - throw DbException.get(ErrorCode.SAVEPOINT_IS_INVALID_1, "" + savepoint); - } - return (JdbcSavepoint) savepoint; - } -//## Java 1.4 end ## - - /** - * Creates a prepared statement with the specified result set type, - * concurrency, and holdability. - * - * @return the prepared statement - * @throws SQLException if the connection is closed or the result set type, - * concurrency, or holdability are not supported - */ - public PreparedStatement prepareStatement(String sql, int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException { - try { - int id = getNextId(TraceObject.PREPARED_STATEMENT); - if (isDebugEnabled()) { - debugCodeAssign("PreparedStatement", TraceObject.PREPARED_STATEMENT, id, - "prepareStatement(" + quote(sql) + ", " + resultSetType + ", " + resultSetConcurrency + ", " - + resultSetHoldability + ")"); - } - checkTypeConcurrency(resultSetType, resultSetConcurrency); - checkHoldability(resultSetHoldability); - checkClosed(); - sql = translateSQL(sql); - return new JdbcPreparedStatement(this, sql, id, resultSetType, resultSetConcurrency, false); - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Creates a new prepared statement. This method just calls - * prepareStatement(String sql). - * - * @return the prepared statement - * @throws SQLException - * if the connection is closed - */ - public PreparedStatement prepareStatement(String sql, int autoGeneratedKeys) throws SQLException { - try { - if (isDebugEnabled()) { - debugCode("prepareStatement(" + quote(sql) + ", " + autoGeneratedKeys + ");"); - } - return prepareStatement(sql); - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Creates a new prepared statement. This method just calls - * prepareStatement(String sql). - * - * @return the prepared statement - * @throws SQLException - * if the connection is closed - */ - public PreparedStatement prepareStatement(String sql, int[] columnIndexes) throws SQLException { - try { - if (isDebugEnabled()) { - debugCode("prepareStatement(" + quote(sql) + ", " + quoteIntArray(columnIndexes) + ");"); - } - return prepareStatement(sql); - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Creates a new prepared statement. This method just calls - * prepareStatement(String sql). - * - * @return the prepared statement - * @throws SQLException - * if the connection is closed - */ - public PreparedStatement prepareStatement(String sql, String[] columnNames) throws SQLException { - try { - if (isDebugEnabled()) { - debugCode("prepareStatement(" + quote(sql) + ", " + quoteArray(columnNames) + ");"); - } - return prepareStatement(sql); - } catch (Exception e) { - throw logAndConvert(e); - } - } - - // ============================================================= - - private void checkJavaVersion() { - try { - //## Java 1.4 begin ## - // check for existence of this class (avoiding Class . forName) - Class< ? > clazz = java.sql.Savepoint.class; - clazz.getClass(); - //## Java 1.4 end ## - } catch (NoClassDefFoundError e) { - throw DbException.get(ErrorCode.UNSUPPORTED_JAVA_VERSION); - } - } - - /** - * Prepare an command. This will parse the SQL statement. - * - * @param sql the SQL statement - * @param fetchSize the fetch size (used in remote connections) - * @return the command - */ - CommandInterface prepareCommand(String sql, int fetchSize) { - return session.prepareCommand(sql, fetchSize); - } - - private CommandInterface prepareCommand(String sql, CommandInterface old) { - return old == null ? session.prepareCommand(sql, Integer.MAX_VALUE) : old; - } - - private int translateGetEnd(String sql, int i, char c) { - int len = sql.length(); - switch(c) { - case '$': { - if (i < len - 1 && sql.charAt(i + 1) == '$' && (i == 0 || sql.charAt(i - 1) <= ' ')) { - int j = sql.indexOf("$$", i + 2); - if (j < 0) { - throw DbException.getSyntaxError(sql, i); - } - return j + 1; - } - return i; - } - case '\'': { - int j = sql.indexOf('\'', i + 1); - if (j < 0) { - throw DbException.getSyntaxError(sql, i); - } - return j; - } - case '"': { - int j = sql.indexOf('"', i + 1); - if (j < 0) { - throw DbException.getSyntaxError(sql, i); - } - return j; - } - case '/': { - checkRunOver(i+1, len, sql); - if (sql.charAt(i + 1) == '*') { - // block comment - int j = sql.indexOf("*/", i + 2); - if (j < 0) { - throw DbException.getSyntaxError(sql, i); - } - i = j + 1; - } else if (sql.charAt(i + 1) == '/') { - // single line comment - i += 2; - while (i < len && (c = sql.charAt(i)) != '\r' && c != '\n') { - i++; - } - } - return i; - } - case '-': { - checkRunOver(i+1, len, sql); - if (sql.charAt(i + 1) == '-') { - // single line comment - i += 2; - while (i < len && (c = sql.charAt(i)) != '\r' && c != '\n') { - i++; - } - } - return i; - } - default: - throw DbException.throwInternalError("c=" + c); - } - } - - /** - * Convert JDBC escape sequences in the SQL statement. This - * method throws an exception if the SQL statement is null. - * - * @param sql the SQL statement with or without JDBC escape sequences - * @return the SQL statement without JDBC escape sequences - */ - private String translateSQL(String sql) { - return translateSQL(sql, true); - } - - /** - * Convert JDBC escape sequences in the SQL statement if required. This - * method throws an exception if the SQL statement is null. - * - * @param sql the SQL statement with or without JDBC escape sequences - * @param escapeProcessing whether escape sequences should be replaced - * @return the SQL statement without JDBC escape sequences - */ - String translateSQL(String sql, boolean escapeProcessing) { - if (sql == null) { - throw DbException.getInvalidValueException(sql, "SQL"); - } - if (!escapeProcessing) { - return sql; - } - if (sql.indexOf('{') < 0) { - return sql; - } - int len = sql.length(); - char[] chars = null; - int level = 0; - for (int i = 0; i < len; i++) { - char c = sql.charAt(i); - switch (c) { - case '\'': - case '"': - case '/': - case '-': - i = translateGetEnd(sql, i, c); - break; - case '{': - level++; - if (chars == null) { - chars = sql.toCharArray(); - } - chars[i] = ' '; - while (Character.isSpaceChar(chars[i])) { - i++; - checkRunOver(i, len, sql); - } - int start = i; - if (chars[i] >= '0' && chars[i] <= '9') { - chars[i - 1] = '{'; - while (true) { - checkRunOver(i, len, sql); - c = chars[i]; - if (c == '}') { - break; - } - switch (c) { - case '\'': - case '"': - case '/': - case '-': - i = translateGetEnd(sql, i, c); - break; - default: - } - i++; - } - level--; - break; - } else if (chars[i] == '?') { - chars[i++] = ' '; - checkRunOver(i, len, sql); - while (Character.isSpaceChar(chars[i])) { - i++; - checkRunOver(i, len, sql); - } - if (sql.charAt(i) != '=') { - throw DbException.getSyntaxError(sql, i, "="); - } - chars[i++] = ' '; - checkRunOver(i, len, sql); - while (Character.isSpaceChar(chars[i])) { - i++; - checkRunOver(i, len, sql); - } - } - while (!Character.isSpaceChar(chars[i])) { - i++; - checkRunOver(i, len, sql); - } - int remove = 0; - if (found(sql, start, "fn")) { - remove = 2; - } else if (found(sql, start, "escape")) { - break; - } else if (found(sql, start, "call")) { - break; - } else if (found(sql, start, "oj")) { - remove = 2; - } else if (found(sql, start, "ts")) { - remove = 2; - } else if (found(sql, start, "t")) { - remove = 1; - } else if (found(sql, start, "d")) { - remove = 1; - } else if (found(sql, start, "params")) { - remove = "params".length(); - } - for (i = start; remove > 0; i++, remove--) { - chars[i] = ' '; - } - break; - case '}': - if (--level < 0) { - throw DbException.getSyntaxError(sql, i); - } - chars[i] = ' '; - break; - case '$': - i = translateGetEnd(sql, i, c); - break; - default: - } - } - if (level != 0) { - throw DbException.getSyntaxError(sql, sql.length() - 1); - } - if (chars != null) { - sql = new String(chars); - } - return sql; - } - - private void checkRunOver(int i, int len, String sql) { - if (i >= len) { - throw DbException.getSyntaxError(sql, i); - } - } - - private boolean found(String sql, int start, String other) { - return sql.regionMatches(true, start, other, 0, other.length()); - } - - private void checkTypeConcurrency(int resultSetType, int resultSetConcurrency) { - switch (resultSetType) { - case ResultSet.TYPE_FORWARD_ONLY: - case ResultSet.TYPE_SCROLL_INSENSITIVE: - case ResultSet.TYPE_SCROLL_SENSITIVE: - break; - default: - throw DbException.getInvalidValueException("" + resultSetType, "resultSetType"); - } - switch (resultSetConcurrency) { - case ResultSet.CONCUR_READ_ONLY: - case ResultSet.CONCUR_UPDATABLE: - break; - default: - throw DbException.getInvalidValueException("" + resultSetConcurrency, "resultSetConcurrency"); - } - } - - private void checkHoldability(int resultSetHoldability) { - // TODO compatibility / correctness: DBPool uses - // ResultSet.HOLD_CURSORS_OVER_COMMIT - //## Java 1.4 begin ## - if (resultSetHoldability != ResultSet.HOLD_CURSORS_OVER_COMMIT - && resultSetHoldability != ResultSet.CLOSE_CURSORS_AT_COMMIT) { - throw DbException.getInvalidValueException("" + resultSetHoldability, "resultSetHoldability"); - } - //## Java 1.4 end ## - } - - /** - * INTERNAL. - * Check if this connection is closed. - * The next operation is a read request. - * - * @throws SQLException if the connection or session is closed - */ - protected void checkClosed() throws SQLException { - checkClosed(false); - } - - /** - * Check if this connection is closed. - * The next operation may be a write request. - * - * @throws SQLException if the connection or session is closed - */ - private void checkClosedForWrite() throws SQLException { - checkClosed(true); - } - - /** - * INTERNAL. - * Check if this connection is closed. - * - * @param write if the next operation is possibly writing - * @throws SQLException if the connection or session is closed - */ - protected void checkClosed(boolean write) throws SQLException { - if (session == null) { - throw DbException.get(ErrorCode.OBJECT_CLOSED); - } - if (session.isClosed()) { - throw DbException.get(ErrorCode.DATABASE_CALLED_AT_SHUTDOWN); - } - if (session.isReconnectNeeded(write)) { - trace.debug("reconnect"); - closePreparedCommands(); - session = session.reconnect(write); - setTrace(session.getTrace()); - } - } - - /** - * INTERNAL. - * Called after executing a command that could have written something. - */ - protected void afterWriting() { - session.afterWriting(); - } - - String getURL() throws SQLException { - checkClosed(); - return url; - } - - String getUser() throws SQLException { - checkClosed(); - return user; - } - - protected void finalize() { - if (!SysProperties.runFinalize) { - return; - } - if (isInternal) { - return; - } - if (session != null && openStackTrace != null) { - trace.error("Connection not closed", openStackTrace); - try { - close(); - } catch (SQLException e) { - trace.debug("finalize", e); - } - } - } - - private void rollbackInternal() { - rollback = prepareCommand("ROLLBACK", rollback); - rollback.executeUpdate(); - } - - /** - * INTERNAL - */ - public int getPowerOffCount() { - return (session == null || session.isClosed()) ? 0 : session.getPowerOffCount(); - } - - /** - * INTERNAL - */ - public void setPowerOffCount(int count) { - if (session != null) { - session.setPowerOffCount(count); - } - } - - /** - * INTERNAL - */ - public void setExecutingStatement(Statement stat) { - executingStatement = stat; - } - - /** - * INTERNAL - */ - ResultSet getGeneratedKeys(JdbcStatement stat, int id) { - getGeneratedKeys = prepareCommand("CALL SCOPE_IDENTITY()", getGeneratedKeys); - ResultInterface result = getGeneratedKeys.executeQuery(0, false); - ResultSet rs = new JdbcResultSet(this, stat, result, id, false, true, false); - return rs; - } - - /** - * Create a new empty Clob object. - * - * @return the object - */ - public Clob createClob() throws SQLException { - try { - int id = getNextId(TraceObject.CLOB); - debugCodeAssign("Clob", TraceObject.CLOB, id, "createClob()"); - checkClosedForWrite(); - try { - Value v = session.getDataHandler().getLobStorage().createClob( - new InputStreamReader( - new ByteArrayInputStream(Utils.EMPTY_BYTES)), 0); - return new JdbcClob(this, v, id); - } finally { - afterWriting(); - } - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Create a new empty Blob object. - * - * @return the object - */ - public Blob createBlob() throws SQLException { - try { - int id = getNextId(TraceObject.BLOB); - debugCodeAssign("Blob", TraceObject.BLOB, id, "createClob()"); - checkClosedForWrite(); - try { - Value v = session.getDataHandler().getLobStorage().createBlob(new ByteArrayInputStream(Utils.EMPTY_BYTES), 0); - return new JdbcBlob(this, v, id); - } finally { - afterWriting(); - } - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Create a new empty NClob object. - * - * @return the object - */ -/*## Java 1.6 begin ## - public NClob createNClob() throws SQLException { - try { - int id = getNextId(TraceObject.CLOB); - debugCodeAssign("NClob", TraceObject.CLOB, id, "createNClob()"); - checkClosedForWrite(); - try { - Value v = session.getDataHandler().getLobStorage().createClob( - new InputStreamReader( - new ByteArrayInputStream(Utils.EMPTY_BYTES)), 0); - return new JdbcClob(this, v, id); - } finally { - afterWriting(); - } - } catch (Exception e) { - throw logAndConvert(e); - } - } -## Java 1.6 end ##*/ - - /** - * [Not supported] Create a new empty SQLXML object. - */ -/*## Java 1.6 begin ## - public SQLXML createSQLXML() throws SQLException { - throw unsupported("SQLXML"); - } -## Java 1.6 end ##*/ - - /** - * [Not supported] Create a new empty Array object. - */ -/*## Java 1.6 begin ## - public Array createArrayOf(String typeName, Object[] elements) - throws SQLException { - throw unsupported("createArray"); - } -## Java 1.6 end ##*/ - - /** - * [Not supported] Create a new empty Struct object. - */ -/*## Java 1.6 begin ## - public Struct createStruct(String typeName, Object[] attributes) - throws SQLException { - throw unsupported("Struct"); - } -## Java 1.6 end ##*/ - - /** - * Returns true if this connection is still valid. - * - * @param timeout the number of seconds to wait for the database to respond - * (ignored) - * @return true if the connection is valid. - */ - public synchronized boolean isValid(int timeout) { - try { - debugCodeCall("isValid", timeout); - if (session == null || session.isClosed()) { - return false; - } - // force a network round trip (if networked) - getInternalAutoCommit(); - return true; - } catch (Exception e) { - // this method doesn't throw an exception, but it logs it - logAndConvert(e); - return false; - } - } - - /** - * [Not supported] Set a client property. - */ -/*## Java 1.6 begin ## - public void setClientInfo(String name, String value) - throws SQLClientInfoException { - throw new SQLClientInfoException(); - } -## Java 1.6 end ##*/ - - /** - * [Not supported] Set the client properties. - */ -/*## Java 1.6 begin ## - public void setClientInfo(Properties properties) throws SQLClientInfoException { - throw new SQLClientInfoException(); - } -## Java 1.6 end ##*/ - - /** - * [Not supported] Get the client properties. - */ -/*## Java 1.6 begin ## - public Properties getClientInfo() throws SQLClientInfoException { - throw new SQLClientInfoException(); - } -## Java 1.6 end ##*/ - - /** - * [Not supported] Set a client property. - */ -/*## Java 1.6 begin ## - public String getClientInfo(String name) throws SQLException { - throw unsupported("clientInfo"); - } -## Java 1.6 end ##*/ - - /** - * [Not supported] Return an object of this class if possible. - * - * @param iface the class - */ -/*## Java 1.6 begin ## - public T unwrap(Class iface) throws SQLException { - throw unsupported("unwrap"); - } -## Java 1.6 end ##*/ - - /** - * [Not supported] Checks if unwrap can return an object of this class. - * - * @param iface the class - */ -/*## Java 1.6 begin ## - public boolean isWrapperFor(Class< ? > iface) throws SQLException { - throw unsupported("isWrapperFor"); - } -## Java 1.6 end ##*/ - - /** - * Create a Clob value from this reader. - * - * @param x the reader - * @param length the length (if smaller or equal than 0, all data until the - * end of file is read) - * @return the value - */ - public Value createClob(Reader x, long length) { - if (x == null) { - return ValueNull.INSTANCE; - } - if (length <= 0) { - length = -1; - } - Value v = session.getDataHandler().getLobStorage().createClob(x, length); - return v; - } - - /** - * Create a Blob value from this input stream. - * - * @param x the input stream - * @param length the length (if smaller or equal than 0, all data until the - * end of file is read) - * @return the value - */ - public Value createBlob(InputStream x, long length) { - if (x == null) { - return ValueNull.INSTANCE; - } - if (length <= 0) { - length = -1; - } - Value v = session.getDataHandler().getLobStorage().createBlob(x, length); - return v; - } - - private void checkMap(Map> map) { - if (map != null && map.size() > 0) { - throw DbException.getUnsupportedException("map.size > 0"); - } - } - - /** - * INTERNAL - */ - public String toString() { - return getTraceObjectName() + ": url=" + url + " user=" + user; - } - - /** - * Convert an object to the default Java object for the given SQL type. For - * example, LOB objects are converted to java.sql.Clob / java.sql.Blob. - * - * @param v the value - * @return the object - */ - Object convertToDefaultObject(Value v) { - Object o; - switch (v.getType()) { - case Value.CLOB: { - if (SysProperties.RETURN_LOB_OBJECTS) { - int id = getNextId(TraceObject.CLOB); - o = new JdbcClob(this, v, id); - } else { - o = v.getObject(); - } - break; - } - case Value.BLOB: { - if (SysProperties.RETURN_LOB_OBJECTS) { - int id = getNextId(TraceObject.BLOB); - o = new JdbcBlob(this, v, id); - } else { - o = v.getObject(); - } - break; - } - case Value.JAVA_OBJECT: - o = Utils.deserialize(v.getBytesNoCopy()); - break; - default: - o = v.getObject(); - } - return o; - } - - CompareMode getCompareMode() { - return compareMode; - } - - /** - * INTERNAL - */ - public void setTraceLevel(int level) { - trace.setLevel(level); - } - -} diff --git a/tools/h2/src/main/org/h2/jdbc/JdbcDatabaseMetaData.java b/tools/h2/src/main/org/h2/jdbc/JdbcDatabaseMetaData.java deleted file mode 100755 index 64ea99c..0000000 --- a/tools/h2/src/main/org/h2/jdbc/JdbcDatabaseMetaData.java +++ /dev/null @@ -1,2846 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.jdbc; - -import java.sql.Connection; -import java.sql.DatabaseMetaData; -import java.sql.PreparedStatement; -import java.sql.ResultSet; -/*## Java 1.6 begin ## -import java.sql.RowIdLifetime; -## Java 1.6 end ##*/ -import java.sql.SQLException; - -import org.h2.constant.SysProperties; -import org.h2.engine.Constants; -import org.h2.message.Trace; -import org.h2.message.TraceObject; -import org.h2.util.StatementBuilder; -import org.h2.util.StringUtils; - -/** - * Represents the meta data for a database. - */ -public class JdbcDatabaseMetaData extends TraceObject implements DatabaseMetaData { - - private JdbcConnection conn; - - JdbcDatabaseMetaData(JdbcConnection conn, Trace trace, int id) { - setTrace(trace, TraceObject.DATABASE_META_DATA, id); - this.conn = conn; - } - - /** - * Returns the major version of this driver. - * - * @return the major version number - */ - public int getDriverMajorVersion() { - debugCodeCall("getDriverMajorVersion"); - return Constants.VERSION_MAJOR; - } - - /** - * Returns the minor version of this driver. - * - * @return the minor version number - */ - public int getDriverMinorVersion() { - debugCodeCall("getDriverMinorVersion"); - return Constants.VERSION_MINOR; - } - - /** - * Gets the database product name. - * - * @return the product name ("H2") - */ - public String getDatabaseProductName() { - debugCodeCall("getDatabaseProductName"); - // This value must stay like that, see - // http://opensource.atlassian.com/projects/hibernate/browse/HHH-2682 - return "H2"; - } - - /** - * Gets the product version of the database. - * - * @return the product version - */ - public String getDatabaseProductVersion() { - debugCodeCall("getDatabaseProductVersion"); - return Constants.getFullVersion(); - } - - /** - * Gets the name of the JDBC driver. - * - * @return the driver name ("H2 JDBC Driver") - */ - public String getDriverName() { - debugCodeCall("getDriverName"); - return "H2 JDBC Driver"; - } - - /** - * Gets the version number of the driver. The format is - * [MajorVersion].[MinorVersion]. - * - * @return the version number - */ - public String getDriverVersion() { - debugCodeCall("getDriverVersion"); - return Constants.getFullVersion(); - } - - /** - * Gets the list of tables in the database. The result set is sorted by - * TABLE_TYPE, TABLE_SCHEM, and TABLE_NAME. - * - *
    - *
  • 1 TABLE_CAT (String) table catalog
  • - *
  • 2 TABLE_SCHEM (String) table schema
  • - *
  • 3 TABLE_NAME (String) table name
  • - *
  • 4 TABLE_TYPE (String) table type
  • - *
  • 5 REMARKS (String) comment
  • - *
  • 6 TYPE_CAT (String) always null
  • - *
  • 7 TYPE_SCHEM (String) always null
  • - *
  • 8 TYPE_NAME (String) always null
  • - *
  • 9 SELF_REFERENCING_COL_NAME (String) always null
  • - *
  • 10 REF_GENERATION (String) always null
  • - *
  • 11 SQL (String) the create table statement or NULL for systems tables - *
  • - *
- * - * @param catalogPattern null (to get all objects) or the catalog name - * @param schemaPattern null (to get all objects) or a schema name - * (uppercase for unquoted names) - * @param tableNamePattern null (to get all objects) or a table name - * (uppercase for unquoted names) - * @param types null or a list of table types - * @return the list of columns - * @throws SQLException if the connection is closed - */ - public ResultSet getTables(String catalogPattern, String schemaPattern, String tableNamePattern, String[] types) throws SQLException { - try { - if (isDebugEnabled()) { - debugCode("getTables(" + quote(catalogPattern) + ", " + quote(schemaPattern) + ", " + quote(tableNamePattern) - + ", " + quoteArray(types) + ");"); - } - checkClosed(); - String tableType; - if (types != null && types.length > 0) { - StatementBuilder buff = new StatementBuilder("TABLE_TYPE IN("); - for (int i = 0; i < types.length; i++) { - buff.appendExceptFirst(", "); - buff.append('?'); - } - tableType = buff.append(')').toString(); - } else { - tableType = "TRUE"; - } - PreparedStatement prep = conn.prepareAutoCloseStatement("SELECT " - + "TABLE_CATALOG TABLE_CAT, " - + "TABLE_SCHEMA TABLE_SCHEM, " - + "TABLE_NAME, " - + "TABLE_TYPE, " - + "REMARKS, " - + "TYPE_NAME TYPE_CAT, " - + "TYPE_NAME TYPE_SCHEM, " - + "TYPE_NAME, " - + "TYPE_NAME SELF_REFERENCING_COL_NAME, " - + "TYPE_NAME REF_GENERATION, " - + "SQL " - + "FROM INFORMATION_SCHEMA.TABLES " - + "WHERE TABLE_CATALOG LIKE ? ESCAPE '\\' " - + "AND TABLE_SCHEMA LIKE ? ESCAPE '\\' " - + "AND TABLE_NAME LIKE ? ESCAPE '\\' " - + "AND (" + tableType + ") " - + "ORDER BY TABLE_TYPE, TABLE_SCHEMA, TABLE_NAME"); - prep.setString(1, getCatalogPattern(catalogPattern)); - prep.setString(2, getSchemaPattern(schemaPattern)); - prep.setString(3, getPattern(tableNamePattern)); - for (int i = 0; types != null && i < types.length; i++) { - prep.setString(4 + i, types[i]); - } - return prep.executeQuery(); - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Gets the list of columns. The result set is sorted by TABLE_SCHEM, - * TABLE_NAME, and ORDINAL_POSITION. - * - *
    - *
  • 1 TABLE_CAT (String) table catalog
  • - *
  • 2 TABLE_SCHEM (String) table schema
  • - *
  • 3 TABLE_NAME (String) table name
  • - *
  • 4 COLUMN_NAME (String) column name
  • - *
  • 5 DATA_TYPE (short) data type (see java.sql.Types)
  • - *
  • 6 TYPE_NAME (String) data type name ("INTEGER", "VARCHAR",...)
  • - *
  • 7 COLUMN_SIZE (int) precision
  • - *
  • 8 BUFFER_LENGTH (int) unused
  • - *
  • 9 DECIMAL_DIGITS (int) scale (0 for INTEGER and VARCHAR)
  • - *
  • 10 NUM_PREC_RADIX (int) radix (always 10)
  • - *
  • 11 NULLABLE (int) columnNoNulls or columnNullable
  • - *
  • 12 REMARKS (String) comment (always empty)
  • - *
  • 13 COLUMN_DEF (String) default value
  • - *
  • 14 SQL_DATA_TYPE (int) unused
  • - *
  • 15 SQL_DATETIME_SUB (int) unused
  • - *
  • 16 CHAR_OCTET_LENGTH (int) unused
  • - *
  • 17 ORDINAL_POSITION (int) the column index (1,2,...)
  • - *
  • 18 IS_NULLABLE (String) "NO" or "YES"
  • - *
  • 19 SCOPE_CATALOG (String) always null
  • - *
  • 20 SCOPE_SCHEMA (String) always null
  • - *
  • 21 SCOPE_TABLE (String) always null
  • - *
  • 22 SOURCE_DATA_TYPE (short) null
  • - *
  • 23 IS_AUTOINCREMENT (String) "NO" or "YES"
  • - *
- * - * @param catalogPattern null (to get all objects) or the catalog name - * @param schemaPattern null (to get all objects) or a schema name - * (uppercase for unquoted names) - * @param tableNamePattern null (to get all objects) or a table name - * (uppercase for unquoted names) - * @param columnNamePattern null (to get all objects) or a column name - * (uppercase for unquoted names) - * @return the list of columns - * @throws SQLException if the connection is closed - */ - public ResultSet getColumns(String catalogPattern, String schemaPattern, - String tableNamePattern, String columnNamePattern) - throws SQLException { - try { - if (isDebugEnabled()) { - debugCode("getColumns(" + quote(catalogPattern)+", " - +quote(schemaPattern)+", " - +quote(tableNamePattern)+", " - +quote(columnNamePattern)+");"); - } - checkClosed(); - PreparedStatement prep = conn.prepareAutoCloseStatement("SELECT " - + "TABLE_CATALOG TABLE_CAT, " - + "TABLE_SCHEMA TABLE_SCHEM, " - + "TABLE_NAME, " - + "COLUMN_NAME, " - + "DATA_TYPE, " - + "TYPE_NAME, " - + "CHARACTER_MAXIMUM_LENGTH COLUMN_SIZE, " - + "CHARACTER_MAXIMUM_LENGTH BUFFER_LENGTH, " - + "NUMERIC_SCALE DECIMAL_DIGITS, " - + "NUMERIC_PRECISION_RADIX NUM_PREC_RADIX, " - + "NULLABLE, " - + "REMARKS, " - + "COLUMN_DEFAULT COLUMN_DEF, " - + "DATA_TYPE SQL_DATA_TYPE, " - + "ZERO() SQL_DATETIME_SUB, " - + "CHARACTER_OCTET_LENGTH CHAR_OCTET_LENGTH, " - + "ORDINAL_POSITION, " - + "IS_NULLABLE IS_NULLABLE, " - + "CAST(SOURCE_DATA_TYPE AS VARCHAR) SCOPE_CATALOG, " - + "CAST(SOURCE_DATA_TYPE AS VARCHAR) SCOPE_SCHEMA, " - + "CAST(SOURCE_DATA_TYPE AS VARCHAR) SCOPE_TABLE, " - + "SOURCE_DATA_TYPE, " - + "CASE WHEN SEQUENCE_NAME IS NULL THEN 'NO' ELSE 'YES' END IS_AUTOINCREMENT " - + "FROM INFORMATION_SCHEMA.COLUMNS " - + "WHERE TABLE_CATALOG LIKE ? ESCAPE '\\' " - + "AND TABLE_SCHEMA LIKE ? ESCAPE '\\' " - + "AND TABLE_NAME LIKE ? ESCAPE '\\' " - + "AND COLUMN_NAME LIKE ? ESCAPE '\\' " - + "ORDER BY TABLE_SCHEM, TABLE_NAME, ORDINAL_POSITION"); - prep.setString(1, getCatalogPattern(catalogPattern)); - prep.setString(2, getSchemaPattern(schemaPattern)); - prep.setString(3, getPattern(tableNamePattern)); - prep.setString(4, getPattern(columnNamePattern)); - return prep.executeQuery(); - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Gets the list of indexes for this database. The primary key index (if - * there is one) is also listed, with the name PRIMARY_KEY. The result set - * is sorted by NON_UNIQUE ('false' first), TYPE, TABLE_SCHEM, INDEX_NAME, - * and ORDINAL_POSITION. - * - *
    - *
  • 1 TABLE_CAT (String) table catalog
  • - *
  • 2 TABLE_SCHEM (String) table schema
  • - *
  • 3 TABLE_NAME (String) table name
  • - *
  • 4 NON_UNIQUE (boolean) 'false' for unique, 'true' for non-unique - *
  • - *
  • 5 INDEX_QUALIFIER (String) index catalog
  • - *
  • 6 INDEX_NAME (String) index name
  • - *
  • 7 TYPE (short) the index type (always tableIndexOther)
  • - *
  • 8 ORDINAL_POSITION (short) column index (1, 2, ...)
  • - *
  • 9 COLUMN_NAME (String) column name
  • - *
  • 10 ASC_OR_DESC (String) ascending or descending (always 'A')
  • - *
  • 11 CARDINALITY (int) numbers of unique values
  • - *
  • 12 PAGES (int) number of pages use (always 0)
  • - *
  • 13 FILTER_CONDITION (String) filter condition (always empty)
  • - *
  • 14 SORT_TYPE (int) the sort type bit map: 1=DESCENDING, - * 2=NULLS_FIRST, 4=NULLS_LAST
  • - *
- * - * @param catalogPattern null or the catalog name - * @param schemaPattern null (to get all objects) or a schema name - * (uppercase for unquoted names) - * @param tableName table name (must be specified) - * @param unique only unique indexes - * @param approximate is ignored - * @return the list of indexes and columns - * @throws SQLException if the connection is closed - */ - public ResultSet getIndexInfo(String catalogPattern, String schemaPattern, String tableName, boolean unique, boolean approximate) - throws SQLException { - try { - if (isDebugEnabled()) { - debugCode("getIndexInfo(" + quote(catalogPattern) + ", " + quote(schemaPattern) + ", " + quote(tableName) + ", " - + unique + ", " + approximate + ");"); - } - String uniqueCondition; - if (unique) { - uniqueCondition = "NON_UNIQUE=FALSE"; - } else { - uniqueCondition = "TRUE"; - } - checkClosed(); - PreparedStatement prep = conn.prepareAutoCloseStatement("SELECT " - + "TABLE_CATALOG TABLE_CAT, " - + "TABLE_SCHEMA TABLE_SCHEM, " - + "TABLE_NAME, " - + "NON_UNIQUE, " - + "TABLE_CATALOG INDEX_QUALIFIER, " - + "INDEX_NAME, " - + "INDEX_TYPE TYPE, " - + "ORDINAL_POSITION, " - + "COLUMN_NAME, " - + "ASC_OR_DESC, " - // TODO meta data for number of unique values in an index - + "CARDINALITY, " - + "PAGES, " - + "FILTER_CONDITION, " - + "SORT_TYPE " - + "FROM INFORMATION_SCHEMA.INDEXES " - + "WHERE TABLE_CATALOG LIKE ? ESCAPE '\\' " - + "AND TABLE_SCHEMA LIKE ? ESCAPE '\\' " - + "AND (" + uniqueCondition + ") " - + "AND TABLE_NAME = ? " - + "ORDER BY NON_UNIQUE, TYPE, TABLE_SCHEM, INDEX_NAME, ORDINAL_POSITION"); - prep.setString(1, getCatalogPattern(catalogPattern)); - prep.setString(2, getSchemaPattern(schemaPattern)); - prep.setString(3, tableName); - return prep.executeQuery(); - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Gets the primary key columns for a table. The result set is sorted by - * TABLE_SCHEM, and COLUMN_NAME (and not by KEY_SEQ). - * - *
    - *
  • 1 TABLE_CAT (String) table catalog
  • - *
  • 2 TABLE_SCHEM (String) table schema
  • - *
  • 3 TABLE_NAME (String) table name
  • - *
  • 4 COLUMN_NAME (String) column name
  • - *
  • 5 KEY_SEQ (short) the column index of this column (1,2,...)
  • - *
  • 6 PK_NAME (String) the name of the primary key index
  • - *
- * - * @param catalogPattern null or the catalog name - * @param schemaPattern null (to get all objects) or a schema name - * (uppercase for unquoted names) - * @param tableName table name (must be specified) - * @return the list of primary key columns - * @throws SQLException if the connection is closed - */ - public ResultSet getPrimaryKeys(String catalogPattern, String schemaPattern, String tableName) throws SQLException { - try { - if (isDebugEnabled()) { - debugCode("getPrimaryKeys(" - +quote(catalogPattern)+", " - +quote(schemaPattern)+", " - +quote(tableName)+");"); - } - checkClosed(); - PreparedStatement prep = conn.prepareAutoCloseStatement("SELECT " - + "TABLE_CATALOG TABLE_CAT, " - + "TABLE_SCHEMA TABLE_SCHEM, " - + "TABLE_NAME, " - + "COLUMN_NAME, " - + "ORDINAL_POSITION KEY_SEQ, " - + "IFNULL(CONSTRAINT_NAME, INDEX_NAME) PK_NAME " - + "FROM INFORMATION_SCHEMA.INDEXES " - + "WHERE TABLE_CATALOG LIKE ? ESCAPE '\\' " - + "AND TABLE_SCHEMA LIKE ? ESCAPE '\\' " - + "AND TABLE_NAME = ? " - + "AND PRIMARY_KEY = TRUE " - + "ORDER BY COLUMN_NAME"); - prep.setString(1, getCatalogPattern(catalogPattern)); - prep.setString(2, getSchemaPattern(schemaPattern)); - prep.setString(3, tableName); - return prep.executeQuery(); - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Checks if all procedures callable. - * - * @return true - */ - public boolean allProceduresAreCallable() { - debugCodeCall("allProceduresAreCallable"); - return true; - } - - /** - * Checks if it possible to query all tables returned by getTables. - * - * @return true - */ - public boolean allTablesAreSelectable() { - debugCodeCall("allTablesAreSelectable"); - return true; - } - - /** - * Returns the database URL for this connection. - * - * @return the url - */ - public String getURL() throws SQLException { - try { - debugCodeCall("getURL"); - return conn.getURL(); - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Returns the user name as passed to DriverManager.getConnection(url, user, - * password). - * - * @return the user name - */ - public String getUserName() throws SQLException { - try { - debugCodeCall("getUserName"); - return conn.getUser(); - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Returns the same as Connection.isReadOnly(). - * - * @return if read only optimization is switched on - */ - public boolean isReadOnly() throws SQLException { - try { - debugCodeCall("isReadOnly"); - return conn.isReadOnly(); - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Checks is NULL values are sorted high (bigger than any non-null values). - * - * @return false by default; true if the system property h2.sortNullsHigh is - * set to true - */ - public boolean nullsAreSortedHigh() { - debugCodeCall("nullsAreSortedHigh"); - return SysProperties.SORT_NULLS_HIGH; - } - - /** - * Checks is NULL values are sorted low (smaller than any non-null values). - * - * @return true by default; false if the system property h2.sortNullsHigh is - * set to true - */ - public boolean nullsAreSortedLow() { - debugCodeCall("nullsAreSortedLow"); - return !SysProperties.SORT_NULLS_HIGH; - } - - /** - * Checks is NULL values are sorted at the beginning (no matter if ASC or - * DESC is used). - * - * @return false - */ - public boolean nullsAreSortedAtStart() { - debugCodeCall("nullsAreSortedAtStart"); - return false; - } - - /** - * Checks is NULL values are sorted at the end (no matter if ASC or DESC is - * used). - * - * @return false - */ - public boolean nullsAreSortedAtEnd() { - debugCodeCall("nullsAreSortedAtEnd"); - return false; - } - - /** - * Returns the connection that created this object. - * - * @return the connection - */ - public Connection getConnection() { - debugCodeCall("getConnection"); - return conn; - } - - /** - * Gets the list of procedures. The result set is sorted by PROCEDURE_SCHEM, - * PROCEDURE_NAME, and NUM_INPUT_PARAMS. There are potentially multiple - * procedures with the same name, each with a different number of input - * parameters. - * - *
    - *
  • 1 PROCEDURE_CAT (String) catalog
  • - *
  • 2 PROCEDURE_SCHEM (String) schema
  • - *
  • 3 PROCEDURE_NAME (String) name
  • - *
  • 4 NUM_INPUT_PARAMS (int) the number of arguments
  • - *
  • 5 NUM_OUTPUT_PARAMS (int) for future use, always 0
  • - *
  • 6 NUM_RESULT_SETS (int) for future use, always 0
  • - *
  • 7 REMARKS (String) description
  • - *
  • 8 PROCEDURE_TYPE (short) if this procedure returns a result - * (procedureNoResult or procedureReturnsResult)
  • - *
  • 9 SPECIFIC_NAME (String) name
  • - *
- * - * @param catalogPattern null or the catalog name - * @param schemaPattern null (to get all objects) or a schema name - * (uppercase for unquoted names) - * @param procedureNamePattern the procedure name pattern - * @return the procedures - * @throws SQLException if the connection is closed - */ - public ResultSet getProcedures(String catalogPattern, String schemaPattern, - String procedureNamePattern) throws SQLException { - try { - if (isDebugEnabled()) { - debugCode("getProcedures(" - +quote(catalogPattern)+", " - +quote(schemaPattern)+", " - +quote(procedureNamePattern)+");"); - } - checkClosed(); - PreparedStatement prep = conn.prepareAutoCloseStatement("SELECT " - + "ALIAS_CATALOG PROCEDURE_CAT, " - + "ALIAS_SCHEMA PROCEDURE_SCHEM, " - + "ALIAS_NAME PROCEDURE_NAME, " - + "COLUMN_COUNT NUM_INPUT_PARAMS, " - + "ZERO() NUM_OUTPUT_PARAMS, " - + "ZERO() NUM_RESULT_SETS, " - + "REMARKS, " - + "RETURNS_RESULT PROCEDURE_TYPE, " - + "ALIAS_NAME SPECIFIC_NAME " - + "FROM INFORMATION_SCHEMA.FUNCTION_ALIASES " - + "WHERE ALIAS_CATALOG LIKE ? ESCAPE '\\' " - + "AND ALIAS_SCHEMA LIKE ? ESCAPE '\\' " - + "AND ALIAS_NAME LIKE ? ESCAPE '\\' " - + "ORDER BY PROCEDURE_SCHEM, PROCEDURE_NAME, NUM_INPUT_PARAMS"); - prep.setString(1, getCatalogPattern(catalogPattern)); - prep.setString(2, getSchemaPattern(schemaPattern)); - prep.setString(3, getPattern(procedureNamePattern)); - return prep.executeQuery(); - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Gets the list of procedure columns. The result set is sorted by - * PROCEDURE_SCHEM, PROCEDURE_NAME, NUM_INPUT_PARAMS, and POS. - * There are potentially multiple procedures with the same name, each with a - * different number of input parameters. - * - *
    - *
  • 1 PROCEDURE_CAT (String) catalog
  • - *
  • 2 PROCEDURE_SCHEM (String) schema
  • - *
  • 3 PROCEDURE_NAME (String) name
  • - *
  • 4 COLUMN_NAME (String) column name
  • - *
  • 5 COLUMN_TYPE (short) column type
  • - *
  • 6 DATA_TYPE (short) sql type
  • - *
  • 7 TYPE_NAME (String) type name
  • - *
  • 8 PRECISION (int) precision
  • - *
  • 9 LENGTH (int) length
  • - *
  • 10 SCALE (short) scale
  • - *
  • 11 RADIX (int) always 10
  • - *
  • 12 NULLABLE (short) nullable
  • - *
  • 13 REMARKS (String) description
  • - *
  • 14 COLUMN_DEF (String) always null
  • - *
  • 15 SQL_DATA_TYPE (int) for future use, always 0
  • - *
  • 16 SQL_DATETIME_SUB (int) for future use, always 0
  • - *
  • 17 CHAR_OCTET_LENGTH (int) always null
  • - *
  • 18 ORDINAL_POSITION (int) the parameter index - * starting from 1 (0 is the return value)
  • - *
  • 19 IS_NULLABLE (String) always "YES"
  • - *
  • 20 SPECIFIC_NAME (String) name
  • - *
- * - * @param catalogPattern null or the catalog name - * @param schemaPattern null (to get all objects) or a schema name - * (uppercase for unquoted names) - * @param procedureNamePattern the procedure name pattern - * @param columnNamePattern the procedure name pattern - * @return the procedure columns - * @throws SQLException if the connection is closed - */ - public ResultSet getProcedureColumns(String catalogPattern, String schemaPattern, - String procedureNamePattern, String columnNamePattern) - throws SQLException { - try { - if (isDebugEnabled()) { - debugCode("getProcedureColumns(" - +quote(catalogPattern)+", " - +quote(schemaPattern)+", " - +quote(procedureNamePattern)+", " - +quote(columnNamePattern)+");"); - } - checkClosed(); - PreparedStatement prep = conn.prepareAutoCloseStatement("SELECT " - + "ALIAS_CATALOG PROCEDURE_CAT, " - + "ALIAS_SCHEMA PROCEDURE_SCHEM, " - + "ALIAS_NAME PROCEDURE_NAME, " - + "COLUMN_NAME, " - + "COLUMN_TYPE, " - + "DATA_TYPE, " - + "TYPE_NAME, " - + "PRECISION, " - + "PRECISION LENGTH, " - + "SCALE, " - + "RADIX, " - + "NULLABLE, " - + "REMARKS, " - + "COLUMN_DEFAULT COLUMN_DEF, " - + "0 SQL_DATA_TYPE, " - + "0 SQL_DATETIME_SUB, " - + "0 CHAR_OCTET_LENGTH, " - + "POS ORDINAL_POSITION, " - + "'YES' IS_NULLABLE, " - + "ALIAS_NAME SPECIFIC_NAME " - + "FROM INFORMATION_SCHEMA.FUNCTION_COLUMNS " - + "WHERE ALIAS_CATALOG LIKE ? ESCAPE '\\' " - + "AND ALIAS_SCHEMA LIKE ? ESCAPE '\\' " - + "AND ALIAS_NAME LIKE ? ESCAPE '\\' " - + "AND COLUMN_NAME LIKE ? ESCAPE '\\' " - + "ORDER BY PROCEDURE_SCHEM, PROCEDURE_NAME, ORDINAL_POSITION"); - prep.setString(1, getCatalogPattern(catalogPattern)); - prep.setString(2, getSchemaPattern(schemaPattern)); - prep.setString(3, getPattern(procedureNamePattern)); - prep.setString(4, getPattern(columnNamePattern)); - return prep.executeQuery(); - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Gets the list of schemas. - * The result set is sorted by TABLE_SCHEM. - * - *
    - *
  • 1 TABLE_SCHEM (String) schema name - *
  • 2 TABLE_CATALOG (String) catalog name - *
  • 3 IS_DEFAULT (boolean) if this is the default schema - *
- * - * @return the schema list - * @throws SQLException if the connection is closed - */ - public ResultSet getSchemas() throws SQLException { - try { - debugCodeCall("getSchemas"); - checkClosed(); - PreparedStatement prep = conn - .prepareAutoCloseStatement("SELECT " - + "SCHEMA_NAME TABLE_SCHEM, " - + "CATALOG_NAME TABLE_CATALOG, " - +" IS_DEFAULT " - + "FROM INFORMATION_SCHEMA.SCHEMATA " - + "ORDER BY SCHEMA_NAME"); - return prep.executeQuery(); - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Gets the list of catalogs. - * The result set is sorted by TABLE_CAT. - * - *
    - *
  • 1 TABLE_CAT (String) catalog name - *
- * - * @return the catalog list - * @throws SQLException if the connection is closed - */ - public ResultSet getCatalogs() throws SQLException { - try { - debugCodeCall("getCatalogs"); - checkClosed(); - PreparedStatement prep = conn.prepareAutoCloseStatement( - "SELECT CATALOG_NAME TABLE_CAT " - + "FROM INFORMATION_SCHEMA.CATALOGS"); - return prep.executeQuery(); - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Gets the list of table types. This call returns a result set with three - * records: "SYSTEM TABLE", "TABLE", "and "VIEW". - * The result set is sorted by TABLE_TYPE. - * - *
    - *
  • 1 TABLE_TYPE (String) table type - *
- * - * @return the table types - * @throws SQLException if the connection is closed - */ - public ResultSet getTableTypes() throws SQLException { - try { - debugCodeCall("getTableTypes"); - checkClosed(); - PreparedStatement prep = conn.prepareAutoCloseStatement("SELECT " - + "TYPE TABLE_TYPE " - + "FROM INFORMATION_SCHEMA.TABLE_TYPES " - + "ORDER BY TABLE_TYPE"); - return prep.executeQuery(); - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Gets the list of column privileges. The result set is sorted by - * COLUMN_NAME and PRIVILEGE - * - *
    - *
  • 1 TABLE_CAT (String) table catalog
  • - *
  • 2 TABLE_SCHEM (String) table schema
  • - *
  • 3 TABLE_NAME (String) table name
  • - *
  • 4 COLUMN_NAME (String) column name
  • - *
  • 5 GRANTOR (String) grantor of access
  • - *
  • 6 GRANTEE (String) grantee of access
  • - *
  • 7 PRIVILEGE (String) SELECT, INSERT, UPDATE, DELETE or REFERENCES - * (only one per row)
  • - *
  • 8 IS_GRANTABLE (String) YES means the grantee can grant access to - * others
  • - *
- * - * @param catalogPattern null (to get all objects) or the catalog name - * @param schemaPattern null (to get all objects) or a schema name (uppercase for - * unquoted names) - * @param table a table name (uppercase for unquoted names) - * @param columnNamePattern null (to get all objects) or a column name - * (uppercase for unquoted names) - * @return the list of privileges - * @throws SQLException if the connection is closed - */ - public ResultSet getColumnPrivileges(String catalogPattern, String schemaPattern, - String table, String columnNamePattern) throws SQLException { - try { - if (isDebugEnabled()) { - debugCode("getColumnPrivileges(" - +quote(catalogPattern)+", " - +quote(schemaPattern)+", " - +quote(table)+", " - +quote(columnNamePattern)+");"); - } - checkClosed(); - PreparedStatement prep = conn.prepareAutoCloseStatement("SELECT " - + "TABLE_CATALOG TABLE_CAT, " - + "TABLE_SCHEMA TABLE_SCHEM, " - + "TABLE_NAME, " - + "COLUMN_NAME, " - + "GRANTOR, " - + "GRANTEE, " - + "PRIVILEGE_TYPE PRIVILEGE, " - + "IS_GRANTABLE " - + "FROM INFORMATION_SCHEMA.COLUMN_PRIVILEGES " - + "WHERE TABLE_CATALOG LIKE ? ESCAPE '\\' " - + "AND TABLE_SCHEMA LIKE ? ESCAPE '\\' " - + "AND TABLE_NAME = ? " - + "AND COLUMN_NAME LIKE ? ESCAPE '\\' " - + "ORDER BY COLUMN_NAME, PRIVILEGE"); - prep.setString(1, getCatalogPattern(catalogPattern)); - prep.setString(2, getSchemaPattern(schemaPattern)); - prep.setString(3, table); - prep.setString(4, getPattern(columnNamePattern)); - return prep.executeQuery(); - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Gets the list of table privileges. The result set is sorted by - * TABLE_SCHEM, TABLE_NAME, and PRIVILEGE. - * - *
    - *
  • 1 TABLE_CAT (String) table catalog
  • - *
  • 2 TABLE_SCHEM (String) table schema
  • - *
  • 3 TABLE_NAME (String) table name
  • - *
  • 4 GRANTOR (String) grantor of access
  • - *
  • 5 GRANTEE (String) grantee of access
  • - *
  • 6 PRIVILEGE (String) SELECT, INSERT, UPDATE, DELETE or REFERENCES - * (only one per row)
  • - *
  • 7 IS_GRANTABLE (String) YES means the grantee can grant access to - * others
  • - *
- * - * @param catalogPattern null (to get all objects) or the catalog name - * @param schemaPattern null (to get all objects) or a schema name - * (uppercase for unquoted names) - * @param tableNamePattern null (to get all objects) or a table name - * (uppercase for unquoted names) - * @return the list of privileges - * @throws SQLException if the connection is closed - */ - public ResultSet getTablePrivileges(String catalogPattern, String schemaPattern, String tableNamePattern) throws SQLException { - try { - if (isDebugEnabled()) { - debugCode("getTablePrivileges(" - +quote(catalogPattern)+", " - +quote(schemaPattern)+", " - +quote(tableNamePattern)+");"); - } - checkClosed(); - PreparedStatement prep = conn.prepareAutoCloseStatement("SELECT " - + "TABLE_CATALOG TABLE_CAT, " - + "TABLE_SCHEMA TABLE_SCHEM, " - + "TABLE_NAME, " - + "GRANTOR, " - + "GRANTEE, " - + "PRIVILEGE_TYPE PRIVILEGE, " - + "IS_GRANTABLE " - + "FROM INFORMATION_SCHEMA.TABLE_PRIVILEGES " - + "WHERE TABLE_CATALOG LIKE ? ESCAPE '\\' " - + "AND TABLE_SCHEMA LIKE ? ESCAPE '\\' " - + "AND TABLE_NAME LIKE ? ESCAPE '\\' " - + "ORDER BY TABLE_SCHEM, TABLE_NAME, PRIVILEGE"); - prep.setString(1, getCatalogPattern(catalogPattern)); - prep.setString(2, getSchemaPattern(schemaPattern)); - prep.setString(3, getPattern(tableNamePattern)); - return prep.executeQuery(); - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Gets the list of columns that best identifier a row in a table. - * The list is ordered by SCOPE. - * - *
    - *
  • 1 SCOPE (short) scope of result (always bestRowSession) - *
  • 2 COLUMN_NAME (String) column name - *
  • 3 DATA_TYPE (short) SQL data type, see also java.sql.Types - *
  • 4 TYPE_NAME (String) type name - *
  • 5 COLUMN_SIZE (int) precision - *
  • 6 BUFFER_LENGTH (int) unused - *
  • 7 DECIMAL_DIGITS (short) scale - *
  • 8 PSEUDO_COLUMN (short) (always bestRowNotPseudo) - *
- * - * @param catalogPattern null (to get all objects) or the catalog name - * @param schemaPattern null (to get all objects) or a schema name - * (uppercase for unquoted names) - * @param tableName table name (must be specified) - * @param scope ignored - * @param nullable ignored - * @return the primary key index - * @throws SQLException if the connection is closed - */ - public ResultSet getBestRowIdentifier(String catalogPattern, String schemaPattern, - String tableName, int scope, boolean nullable) throws SQLException { - try { - if (isDebugEnabled()) { - debugCode("getBestRowIdentifier(" - +quote(catalogPattern)+", " - +quote(schemaPattern)+", " - +quote(tableName)+", " - +scope+", "+nullable+");"); - } - checkClosed(); - PreparedStatement prep = conn.prepareAutoCloseStatement("SELECT " - + "CAST(? AS SMALLINT) SCOPE, " - + "C.COLUMN_NAME, " - + "C.DATA_TYPE, " - + "C.TYPE_NAME, " - + "C.CHARACTER_MAXIMUM_LENGTH COLUMN_SIZE, " - + "C.CHARACTER_MAXIMUM_LENGTH BUFFER_LENGTH, " - + "CAST(C.NUMERIC_SCALE AS SMALLINT) DECIMAL_DIGITS, " - + "CAST(? AS SMALLINT) PSEUDO_COLUMN " - + "FROM INFORMATION_SCHEMA.INDEXES I, " - +" INFORMATION_SCHEMA.COLUMNS C " - + "WHERE C.TABLE_NAME = I.TABLE_NAME " - + "AND C.COLUMN_NAME = I.COLUMN_NAME " - + "AND C.TABLE_CATALOG LIKE ? ESCAPE '\\' " - + "AND C.TABLE_SCHEMA LIKE ? ESCAPE '\\' " - + "AND C.TABLE_NAME = ? " - + "AND I.PRIMARY_KEY = TRUE " - + "ORDER BY SCOPE"); - // SCOPE - prep.setInt(1, DatabaseMetaData.bestRowSession); - // PSEUDO_COLUMN - prep.setInt(2, DatabaseMetaData.bestRowNotPseudo); - prep.setString(3, getCatalogPattern(catalogPattern)); - prep.setString(4, getSchemaPattern(schemaPattern)); - prep.setString(5, tableName); - return prep.executeQuery(); - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Get the list of columns that are update when any value is updated. - * The result set is always empty. - * - *
    - *
  • 1 SCOPE (int) not used - *
  • 2 COLUMN_NAME (String) column name - *
  • 3 DATA_TYPE (int) SQL data type - see also java.sql.Types - *
  • 4 TYPE_NAME (String) data type name - *
  • 5 COLUMN_SIZE (int) precision - *
  • 6 BUFFER_LENGTH (int) length (bytes) - *
  • 7 DECIMAL_DIGITS (int) scale - *
  • 8 PSEUDO_COLUMN (int) is this column a pseudo column - *
- * - * @param catalog null (to get all objects) or the catalog name - * @param schema null (to get all objects) or a schema name - * @param tableName table name (must be specified) - * @return an empty result set - * @throws SQLException if the connection is closed - */ - public ResultSet getVersionColumns(String catalog, String schema, - String tableName) throws SQLException { - try { - if (isDebugEnabled()) { - debugCode("getVersionColumns(" - +quote(catalog)+", " - +quote(schema)+", " - +quote(tableName)+");"); - } - checkClosed(); - PreparedStatement prep = conn.prepareAutoCloseStatement("SELECT " - + "ZERO() SCOPE, " - + "COLUMN_NAME, " - + "CAST(DATA_TYPE AS INT) DATA_TYPE, " - + "TYPE_NAME, " - + "NUMERIC_PRECISION COLUMN_SIZE, " - + "NUMERIC_PRECISION BUFFER_LENGTH, " - + "NUMERIC_PRECISION DECIMAL_DIGITS, " - + "ZERO() PSEUDO_COLUMN " - + "FROM INFORMATION_SCHEMA.COLUMNS " - + "WHERE FALSE"); - return prep.executeQuery(); - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Gets the list of primary key columns that are referenced by a table. The - * result set is sorted by PKTABLE_CAT, PKTABLE_SCHEM, PKTABLE_NAME, - * FK_NAME, KEY_SEQ. - * - *
    - *
  • 1 PKTABLE_CAT (String) primary catalog
  • - *
  • 2 PKTABLE_SCHEM (String) primary schema
  • - *
  • 3 PKTABLE_NAME (String) primary table
  • - *
  • 4 PKCOLUMN_NAME (String) primary column
  • - *
  • 5 FKTABLE_CAT (String) foreign catalog
  • - *
  • 6 FKTABLE_SCHEM (String) foreign schema
  • - *
  • 7 FKTABLE_NAME (String) foreign table
  • - *
  • 8 FKCOLUMN_NAME (String) foreign column
  • - *
  • 9 KEY_SEQ (short) sequence number (1, 2, ...)
  • - *
  • 10 UPDATE_RULE (short) action on update (see - * DatabaseMetaData.importedKey...)
  • - *
  • 11 DELETE_RULE (short) action on delete (see - * DatabaseMetaData.importedKey...)
  • - *
  • 12 FK_NAME (String) foreign key name
  • - *
  • 13 PK_NAME (String) primary key name
  • - *
  • 14 DEFERRABILITY (short) deferrable or not (always - * importedKeyNotDeferrable)
  • - *
- * - * @param catalogPattern null (to get all objects) or the catalog name - * @param schemaPattern the schema name of the foreign table - * @param tableName the name of the foreign table - * @return the result set - * @throws SQLException if the connection is closed - */ - public ResultSet getImportedKeys(String catalogPattern, String schemaPattern, String tableName) throws SQLException { - try { - if (isDebugEnabled()) { - debugCode("getImportedKeys(" - +quote(catalogPattern)+", " - +quote(schemaPattern)+", " - +quote(tableName)+");"); - } - checkClosed(); - PreparedStatement prep = conn.prepareAutoCloseStatement("SELECT " - + "PKTABLE_CATALOG PKTABLE_CAT, " - + "PKTABLE_SCHEMA PKTABLE_SCHEM, " - + "PKTABLE_NAME PKTABLE_NAME, " - + "PKCOLUMN_NAME, " - + "FKTABLE_CATALOG FKTABLE_CAT, " - + "FKTABLE_SCHEMA FKTABLE_SCHEM, " - + "FKTABLE_NAME, " - + "FKCOLUMN_NAME, " - + "ORDINAL_POSITION KEY_SEQ, " - + "UPDATE_RULE, " - + "DELETE_RULE, " - + "FK_NAME, " - + "PK_NAME, " - + "DEFERRABILITY " - + "FROM INFORMATION_SCHEMA.CROSS_REFERENCES " - + "WHERE FKTABLE_CATALOG LIKE ? ESCAPE '\\' " - + "AND FKTABLE_SCHEMA LIKE ? ESCAPE '\\' " - + "AND FKTABLE_NAME = ? " - + "ORDER BY PKTABLE_CAT, PKTABLE_SCHEM, PKTABLE_NAME, FK_NAME, KEY_SEQ"); - prep.setString(1, getCatalogPattern(catalogPattern)); - prep.setString(2, getSchemaPattern(schemaPattern)); - prep.setString(3, tableName); - return prep.executeQuery(); - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Gets the list of foreign key columns that reference a table. The result - * set is sorted by FKTABLE_CAT, FKTABLE_SCHEM, FKTABLE_NAME, FK_NAME, - * KEY_SEQ. - * - *
    - *
  • 1 PKTABLE_CAT (String) primary catalog
  • - *
  • 2 PKTABLE_SCHEM (String) primary schema
  • - *
  • 3 PKTABLE_NAME (String) primary table
  • - *
  • 4 PKCOLUMN_NAME (String) primary column
  • - *
  • 5 FKTABLE_CAT (String) foreign catalog
  • - *
  • 6 FKTABLE_SCHEM (String) foreign schema
  • - *
  • 7 FKTABLE_NAME (String) foreign table
  • - *
  • 8 FKCOLUMN_NAME (String) foreign column
  • - *
  • 9 KEY_SEQ (short) sequence number (1,2,...)
  • - *
  • 10 UPDATE_RULE (short) action on update (see - * DatabaseMetaData.importedKey...)
  • - *
  • 11 DELETE_RULE (short) action on delete (see - * DatabaseMetaData.importedKey...)
  • - *
  • 12 FK_NAME (String) foreign key name
  • - *
  • 13 PK_NAME (String) primary key name
  • - *
  • 14 DEFERRABILITY (short) deferrable or not (always - * importedKeyNotDeferrable)
  • - *
- * - * @param catalogPattern null or the catalog name - * @param schemaPattern the schema name of the primary table - * @param tableName the name of the primary table - * @return the result set - * @throws SQLException if the connection is closed - */ - public ResultSet getExportedKeys(String catalogPattern, String schemaPattern, String tableName) - throws SQLException { - try { - if (isDebugEnabled()) { - debugCode("getExportedKeys(" - +quote(catalogPattern)+", " - +quote(schemaPattern)+", " - +quote(tableName)+");"); - } - checkClosed(); - PreparedStatement prep = conn.prepareAutoCloseStatement("SELECT " - + "PKTABLE_CATALOG PKTABLE_CAT, " - + "PKTABLE_SCHEMA PKTABLE_SCHEM, " - + "PKTABLE_NAME PKTABLE_NAME, " - + "PKCOLUMN_NAME, " - + "FKTABLE_CATALOG FKTABLE_CAT, " - + "FKTABLE_SCHEMA FKTABLE_SCHEM, " - + "FKTABLE_NAME, " - + "FKCOLUMN_NAME, " - + "ORDINAL_POSITION KEY_SEQ, " - + "UPDATE_RULE, " - + "DELETE_RULE, " - + "FK_NAME, " - + "PK_NAME, " - + "DEFERRABILITY " - + "FROM INFORMATION_SCHEMA.CROSS_REFERENCES " - + "WHERE PKTABLE_CATALOG LIKE ? ESCAPE '\\' " - + "AND PKTABLE_SCHEMA LIKE ? ESCAPE '\\' " - + "AND PKTABLE_NAME = ? " - + "ORDER BY FKTABLE_CAT, FKTABLE_SCHEM, FKTABLE_NAME, FK_NAME, KEY_SEQ"); - prep.setString(1, getCatalogPattern(catalogPattern)); - prep.setString(2, getSchemaPattern(schemaPattern)); - prep.setString(3, tableName); - return prep.executeQuery(); - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Gets the list of foreign key columns that references a table, as well as - * the list of primary key columns that are references by a table. The - * result set is sorted by FKTABLE_CAT, FKTABLE_SCHEM, FKTABLE_NAME, - * FK_NAME, KEY_SEQ. - * - *
    - *
  • 1 PKTABLE_CAT (String) primary catalog
  • - *
  • 2 PKTABLE_SCHEM (String) primary schema
  • - *
  • 3 PKTABLE_NAME (String) primary table
  • - *
  • 4 PKCOLUMN_NAME (String) primary column
  • - *
  • 5 FKTABLE_CAT (String) foreign catalog
  • - *
  • 6 FKTABLE_SCHEM (String) foreign schema
  • - *
  • 7 FKTABLE_NAME (String) foreign table
  • - *
  • 8 FKCOLUMN_NAME (String) foreign column
  • - *
  • 9 KEY_SEQ (short) sequence number (1,2,...)
  • - *
  • 10 UPDATE_RULE (short) action on update (see - * DatabaseMetaData.importedKey...)
  • - *
  • 11 DELETE_RULE (short) action on delete (see - * DatabaseMetaData.importedKey...)
  • - *
  • 12 FK_NAME (String) foreign key name
  • - *
  • 13 PK_NAME (String) primary key name
  • - *
  • 14 DEFERRABILITY (short) deferrable or not (always - * importedKeyNotDeferrable)
  • - *
- * - * @param primaryCatalogPattern null or the catalog name - * @param primarySchemaPattern the schema name of the primary table - * (optional) - * @param primaryTable the name of the primary table (must be specified) - * @param foreignCatalogPattern null or the catalog name - * @param foreignSchemaPattern the schema name of the foreign table - * (optional) - * @param foreignTable the name of the foreign table (must be specified) - * @return the result set - * @throws SQLException if the connection is closed - */ - public ResultSet getCrossReference(String primaryCatalogPattern, - String primarySchemaPattern, String primaryTable, String foreignCatalogPattern, - String foreignSchemaPattern, String foreignTable) throws SQLException { - try { - if (isDebugEnabled()) { - debugCode("getCrossReference(" - +quote(primaryCatalogPattern)+", " - +quote(primarySchemaPattern)+", " - +quote(primaryTable)+", " - +quote(foreignCatalogPattern)+", " - +quote(foreignSchemaPattern)+", " - +quote(foreignTable)+");"); - } - checkClosed(); - PreparedStatement prep = conn.prepareAutoCloseStatement("SELECT " - + "PKTABLE_CATALOG PKTABLE_CAT, " - + "PKTABLE_SCHEMA PKTABLE_SCHEM, " - + "PKTABLE_NAME PKTABLE_NAME, " - + "PKCOLUMN_NAME, " - + "FKTABLE_CATALOG FKTABLE_CAT, " - + "FKTABLE_SCHEMA FKTABLE_SCHEM, " - + "FKTABLE_NAME, " - + "FKCOLUMN_NAME, " - + "ORDINAL_POSITION KEY_SEQ, " - + "UPDATE_RULE, " - + "DELETE_RULE, " - + "FK_NAME, " - + "PK_NAME, " - + "DEFERRABILITY " - + "FROM INFORMATION_SCHEMA.CROSS_REFERENCES " - + "WHERE PKTABLE_CATALOG LIKE ? ESCAPE '\\' " - + "AND PKTABLE_SCHEMA LIKE ? ESCAPE '\\' " - + "AND PKTABLE_NAME = ? " - + "AND FKTABLE_CATALOG LIKE ? ESCAPE '\\' " - + "AND FKTABLE_SCHEMA LIKE ? ESCAPE '\\' " - + "AND FKTABLE_NAME = ? " - + "ORDER BY FKTABLE_CAT, FKTABLE_SCHEM, FKTABLE_NAME, FK_NAME, KEY_SEQ"); - prep.setString(1, getCatalogPattern(primaryCatalogPattern)); - prep.setString(2, getSchemaPattern(primarySchemaPattern)); - prep.setString(3, primaryTable); - prep.setString(4, getCatalogPattern(foreignCatalogPattern)); - prep.setString(5, getSchemaPattern(foreignSchemaPattern)); - prep.setString(6, foreignTable); - return prep.executeQuery(); - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Gets the list of user-defined data types. - * This call returns an empty result set. - * - *
    - *
  • 1 TYPE_CAT (String) catalog - *
  • 2 TYPE_SCHEM (String) schema - *
  • 3 TYPE_NAME (String) type name - *
  • 4 CLASS_NAME (String) Java class - *
  • 5 DATA_TYPE (short) SQL Type - see also java.sql.Types - *
  • 6 REMARKS (String) description - *
  • 7 BASE_TYPE (short) base type - see also java.sql.Types - *
- * - * @param catalog ignored - * @param schemaPattern ignored - * @param typeNamePattern ignored - * @param types ignored - * @return an empty result set - * @throws SQLException if the connection is closed - */ - public ResultSet getUDTs(String catalog, String schemaPattern, - String typeNamePattern, int[] types) throws SQLException { - try { - if (isDebugEnabled()) { - debugCode("getUDTs(" - +quote(catalog)+", " - +quote(schemaPattern)+", " - +quote(typeNamePattern)+", " - +quoteIntArray(types)+");"); - } - checkClosed(); - PreparedStatement prep = conn.prepareAutoCloseStatement("SELECT " - + "CATALOG_NAME TYPE_CAT, " - + "CATALOG_NAME TYPE_SCHEM, " - + "CATALOG_NAME TYPE_NAME, " - + "CATALOG_NAME CLASS_NAME, " - + "CAST(ZERO() AS SMALLINT) DATA_TYPE, " - + "CATALOG_NAME REMARKS, " - + "CAST(ZERO() AS SMALLINT) BASE_TYPE " - + "FROM INFORMATION_SCHEMA.CATALOGS " - + "WHERE FALSE"); - return prep.executeQuery(); - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Gets the list of data types. The result set is sorted by DATA_TYPE and - * afterwards by how closely the data type maps to the corresponding JDBC - * SQL type (best match first). - * - *
    - *
  • 1 TYPE_NAME (String) type name
  • - *
  • 2 DATA_TYPE (short) SQL data type - see also java.sql.Types
  • - *
  • 3 PRECISION (int) maximum precision
  • - *
  • 4 LITERAL_PREFIX (String) prefix used to quote a literal
  • - *
  • 5 LITERAL_SUFFIX (String) suffix used to quote a literal
  • - *
  • 6 CREATE_PARAMS (String) parameters used (may be null)
  • - *
  • 7 NULLABLE (short) typeNoNulls (NULL not allowed) or typeNullable - *
  • - *
  • 8 CASE_SENSITIVE (boolean) case sensitive
  • - *
  • 9 SEARCHABLE (short) typeSearchable
  • - *
  • 10 UNSIGNED_ATTRIBUTE (boolean) unsigned
  • - *
  • 11 FIXED_PREC_SCALE (boolean) fixed precision
  • - *
  • 12 AUTO_INCREMENT (boolean) auto increment
  • - *
  • 13 LOCAL_TYPE_NAME (String) localized version of the data type
  • - *
  • 14 MINIMUM_SCALE (short) minimum scale
  • - *
  • 15 MAXIMUM_SCALE (short) maximum scale
  • - *
  • 16 SQL_DATA_TYPE (int) unused
  • - *
  • 17 SQL_DATETIME_SUB (int) unused
  • - *
  • 18 NUM_PREC_RADIX (int) 2 for binary, 10 for decimal
  • - *
- * - * @return the list of data types - * @throws SQLException if the connection is closed - */ - public ResultSet getTypeInfo() throws SQLException { - try { - debugCodeCall("getTypeInfo"); - checkClosed(); - PreparedStatement prep = conn.prepareAutoCloseStatement("SELECT " - + "TYPE_NAME, " - + "DATA_TYPE, " - + "PRECISION, " - + "PREFIX LITERAL_PREFIX, " - + "SUFFIX LITERAL_SUFFIX, " - + "PARAMS CREATE_PARAMS, " - + "NULLABLE, " - + "CASE_SENSITIVE, " - + "SEARCHABLE, " - + "FALSE UNSIGNED_ATTRIBUTE, " - + "FALSE FIXED_PREC_SCALE, " - + "AUTO_INCREMENT, " - + "TYPE_NAME LOCAL_TYPE_NAME, " - + "MINIMUM_SCALE, " - + "MAXIMUM_SCALE, " - + "DATA_TYPE SQL_DATA_TYPE, " - + "ZERO() SQL_DATETIME_SUB, " - + "RADIX NUM_PREC_RADIX " - + "FROM INFORMATION_SCHEMA.TYPE_INFO " - + "ORDER BY DATA_TYPE, POS"); - ResultSet rs = prep.executeQuery(); - return rs; - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Checks if this database store data in local files. - * - * @return true - */ - public boolean usesLocalFiles() { - debugCodeCall("usesLocalFiles"); - return true; - } - - /** - * Checks if this database use one file per table. - * - * @return false - */ - public boolean usesLocalFilePerTable() { - debugCodeCall("usesLocalFilePerTable"); - return false; - } - - /** - * Returns the string used to quote identifiers. - * - * @return a double quote - */ - public String getIdentifierQuoteString() { - debugCodeCall("getIdentifierQuoteString"); - return "\""; - } - - /** - * Gets the comma-separated list of all SQL keywords that are not supported - * as table/column/index name, in addition to the SQL-92 keywords. The list - * returned is: - *
-     * LIMIT,MINUS,ROWNUM,SYSDATE,SYSTIME,SYSTIMESTAMP,TODAY
-     * 
- * The complete list of keywords (including SQL-92 keywords) is: - *
-     * CROSS, CURRENT_DATE, CURRENT_TIME, CURRENT_TIMESTAMP, DISTINCT,
-     * EXCEPT, EXISTS, FALSE, FOR, FROM, FULL, GROUP, HAVING, INNER,
-     * INTERSECT, IS, JOIN, LIKE, LIMIT, MINUS, NATURAL, NOT, NULL, ON,
-     * ORDER, PRIMARY, ROWNUM, SELECT, SYSDATE, SYSTIME, SYSTIMESTAMP,
-     * TODAY, TRUE, UNION, UNIQUE, WHERE
-     * 
- * - * @return a list of additional the keywords - */ - public String getSQLKeywords() { - debugCodeCall("getSQLKeywords"); - return "LIMIT,MINUS,ROWNUM,SYSDATE,SYSTIME,SYSTIMESTAMP,TODAY"; - } - - /** - * Returns the list of numeric functions supported by this database. - * - * @return the list - */ - public String getNumericFunctions() throws SQLException { - debugCodeCall("getNumericFunctions"); - return getFunctions("Functions (Numeric)"); - } - - /** - * Returns the list of string functions supported by this database. - * - * @return the list - */ - public String getStringFunctions() throws SQLException { - debugCodeCall("getStringFunctions"); - return getFunctions("Functions (String)"); - } - - /** - * Returns the list of system functions supported by this database. - * - * @return the list - */ - public String getSystemFunctions() throws SQLException { - debugCodeCall("getSystemFunctions"); - return getFunctions("Functions (System)"); - } - - /** - * Returns the list of date and time functions supported by this database. - * - * @return the list - */ - public String getTimeDateFunctions() throws SQLException { - debugCodeCall("getTimeDateFunctions"); - return getFunctions("Functions (Time and Date)"); - } - - private String getFunctions(String section) throws SQLException { - try { - checkClosed(); - PreparedStatement prep = conn.prepareAutoCloseStatement("SELECT TOPIC " - + "FROM INFORMATION_SCHEMA.HELP WHERE SECTION = ?"); - prep.setString(1, section); - ResultSet rs = prep.executeQuery(); - StatementBuilder buff = new StatementBuilder(); - while (rs.next()) { - String s = rs.getString(1).trim(); - String[] array = StringUtils.arraySplit(s, ',', true); - for (String a : array) { - buff.appendExceptFirst(","); - String f = a.trim(); - if (f.indexOf(' ') >= 0) { - // remove 'Function' from 'INSERT Function' - f = f.substring(0, f.indexOf(' ')).trim(); - } - buff.append(f); - } - } - rs.close(); - prep.close(); - return buff.toString(); - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Returns the default escape character for DatabaseMetaData search - * patterns. - * - * @return the default escape character (always '\', independent on the - * mode) - */ - public String getSearchStringEscape() { - debugCodeCall("getSearchStringEscape"); - return "\\"; - } - - /** - * Returns the characters that are allowed for identifiers in addiction to - * A-Z, a-z, 0-9 and '_'. - * - * @return an empty String ("") - */ - public String getExtraNameCharacters() { - debugCodeCall("getExtraNameCharacters"); - return ""; - } - - /** - * Returns whether alter table with add column is supported. - * @return true - */ - public boolean supportsAlterTableWithAddColumn() { - debugCodeCall("supportsAlterTableWithAddColumn"); - return true; - } - - /** - * Returns whether alter table with drop column is supported. - * - * @return true - */ - public boolean supportsAlterTableWithDropColumn() { - debugCodeCall("supportsAlterTableWithDropColumn"); - return true; - } - - /** - * Returns whether column aliasing is supported. - * - * @return true - */ - public boolean supportsColumnAliasing() { - debugCodeCall("supportsColumnAliasing"); - return true; - } - - /** - * Returns whether NULL+1 is NULL or not. - * - * @return true - */ - public boolean nullPlusNonNullIsNull() { - debugCodeCall("nullPlusNonNullIsNull"); - return true; - } - - /** - * Returns whether CONVERT is supported. - * - * @return true - */ - public boolean supportsConvert() { - debugCodeCall("supportsConvert"); - return true; - } - - /** - * Returns whether CONVERT is supported for one datatype to another. - * - * @param fromType the source SQL type - * @param toType the target SQL type - * @return true - */ - public boolean supportsConvert(int fromType, int toType) { - if (isDebugEnabled()) { - debugCode("supportsConvert("+fromType+", "+fromType+");"); - } - return true; - } - - /** - * Returns whether table correlation names (table alias) are supported. - * - * @return true - */ - public boolean supportsTableCorrelationNames() { - debugCodeCall("supportsTableCorrelationNames"); - return true; - } - - /** - * Returns whether table correlation names (table alias) are restricted to - * be different than table names. - * - * @return false - */ - public boolean supportsDifferentTableCorrelationNames() { - debugCodeCall("supportsDifferentTableCorrelationNames"); - return false; - } - - /** - * Returns whether expression in ORDER BY are supported. - * - * @return true - */ - public boolean supportsExpressionsInOrderBy() { - debugCodeCall("supportsExpressionsInOrderBy"); - return true; - } - - /** - * Returns whether ORDER BY is supported if the column is not in the SELECT - * list. - * - * @return true - */ - public boolean supportsOrderByUnrelated() { - debugCodeCall("supportsOrderByUnrelated"); - return true; - } - - /** - * Returns whether GROUP BY is supported. - * - * @return true - */ - public boolean supportsGroupBy() { - debugCodeCall("supportsGroupBy"); - return true; - } - - /** - * Returns whether GROUP BY is supported if the column is not in the SELECT - * list. - * - * @return true - */ - public boolean supportsGroupByUnrelated() { - debugCodeCall("supportsGroupByUnrelated"); - return true; - } - - /** - * Checks whether a GROUP BY clause can use columns that are not in the - * SELECT clause, provided that it specifies all the columns in the SELECT - * clause. - * - * @return true - */ - public boolean supportsGroupByBeyondSelect() { - debugCodeCall("supportsGroupByBeyondSelect"); - return true; - } - - /** - * Returns whether LIKE... ESCAPE is supported. - * - * @return true - */ - public boolean supportsLikeEscapeClause() { - debugCodeCall("supportsLikeEscapeClause"); - return true; - } - - /** - * Returns whether multiple result sets are supported. - * - * @return false - */ - public boolean supportsMultipleResultSets() { - debugCodeCall("supportsMultipleResultSets"); - return false; - } - - /** - * Returns whether multiple transactions (on different connections) are - * supported. - * - * @return true - */ - public boolean supportsMultipleTransactions() { - debugCodeCall("supportsMultipleTransactions"); - return true; - } - - /** - * Returns whether columns with NOT NULL are supported. - * - * @return true - */ - public boolean supportsNonNullableColumns() { - debugCodeCall("supportsNonNullableColumns"); - return true; - } - - /** - * Returns whether ODBC Minimum SQL grammar is supported. - * - * @return true - */ - public boolean supportsMinimumSQLGrammar() { - debugCodeCall("supportsMinimumSQLGrammar"); - return true; - } - - /** - * Returns whether ODBC Core SQL grammar is supported. - * - * @return true - */ - public boolean supportsCoreSQLGrammar() { - debugCodeCall("supportsCoreSQLGrammar"); - return true; - } - - /** - * Returns whether ODBC Extended SQL grammar is supported. - * - * @return false - */ - public boolean supportsExtendedSQLGrammar() { - debugCodeCall("supportsExtendedSQLGrammar"); - return false; - } - - /** - * Returns whether SQL-92 entry level grammar is supported. - * - * @return true - */ - public boolean supportsANSI92EntryLevelSQL() { - debugCodeCall("supportsANSI92EntryLevelSQL"); - return true; - } - - /** - * Returns whether SQL-92 intermediate level grammar is supported. - * - * @return false - */ - public boolean supportsANSI92IntermediateSQL() { - debugCodeCall("supportsANSI92IntermediateSQL"); - return false; - } - - /** - * Returns whether SQL-92 full level grammar is supported. - * - * @return false - */ - public boolean supportsANSI92FullSQL() { - debugCodeCall("supportsANSI92FullSQL"); - return false; - } - - /** - * Returns whether referential integrity is supported. - * - * @return true - */ - public boolean supportsIntegrityEnhancementFacility() { - debugCodeCall("supportsIntegrityEnhancementFacility"); - return true; - } - - /** - * Returns whether outer joins are supported. - * - * @return true - */ - public boolean supportsOuterJoins() { - debugCodeCall("supportsOuterJoins"); - return true; - } - - /** - * Returns whether full outer joins are supported. - * - * @return false - */ - public boolean supportsFullOuterJoins() { - debugCodeCall("supportsFullOuterJoins"); - return false; - } - - /** - * Returns whether limited outer joins are supported. - * - * @return true - */ - public boolean supportsLimitedOuterJoins() { - debugCodeCall("supportsLimitedOuterJoins"); - return true; - } - - /** - * Returns the term for "schema". - * - * @return "schema" - */ - public String getSchemaTerm() { - debugCodeCall("getSchemaTerm"); - return "schema"; - } - - /** - * Returns the term for "procedure". - * - * @return "procedure" - */ - public String getProcedureTerm() { - debugCodeCall("getProcedureTerm"); - return "procedure"; - } - - /** - * Returns the term for "catalog". - * - * @return "catalog" - */ - public String getCatalogTerm() { - debugCodeCall("getCatalogTerm"); - return "catalog"; - } - - /** - * Returns whether the catalog is at the beginning. - * - * @return true - */ - public boolean isCatalogAtStart() { - debugCodeCall("isCatalogAtStart"); - return true; - } - - /** - * Returns the catalog separator. - * - * @return "." - */ - public String getCatalogSeparator() { - debugCodeCall("getCatalogSeparator"); - return "."; - } - - /** - * Returns whether the schema name in INSERT, UPDATE, DELETE is supported. - * - * @return true - */ - public boolean supportsSchemasInDataManipulation() { - debugCodeCall("supportsSchemasInDataManipulation"); - return true; - } - - /** - * Returns whether the schema name in procedure calls is supported. - * - * @return true - */ - public boolean supportsSchemasInProcedureCalls() { - debugCodeCall("supportsSchemasInProcedureCalls"); - return true; - } - - /** - * Returns whether the schema name in CREATE TABLE is supported. - * - * @return true - */ - public boolean supportsSchemasInTableDefinitions() { - debugCodeCall("supportsSchemasInTableDefinitions"); - return true; - } - - /** - * Returns whether the schema name in CREATE INDEX is supported. - * - * @return true - */ - public boolean supportsSchemasInIndexDefinitions() { - debugCodeCall("supportsSchemasInIndexDefinitions"); - return true; - } - - /** - * Returns whether the schema name in GRANT is supported. - * - * @return true - */ - public boolean supportsSchemasInPrivilegeDefinitions() { - debugCodeCall("supportsSchemasInPrivilegeDefinitions"); - return true; - } - - /** - * Returns whether the catalog name in INSERT, UPDATE, DELETE is supported. - * - * @return true - */ - public boolean supportsCatalogsInDataManipulation() { - debugCodeCall("supportsCatalogsInDataManipulation"); - return true; - } - - /** - * Returns whether the catalog name in procedure calls is supported. - * - * @return false - */ - public boolean supportsCatalogsInProcedureCalls() { - debugCodeCall("supportsCatalogsInProcedureCalls"); - return false; - } - - /** - * Returns whether the catalog name in CREATE TABLE is supported. - * - * @return true - */ - public boolean supportsCatalogsInTableDefinitions() { - debugCodeCall("supportsCatalogsInTableDefinitions"); - return true; - } - - /** - * Returns whether the catalog name in CREATE INDEX is supported. - * - * @return true - */ - public boolean supportsCatalogsInIndexDefinitions() { - debugCodeCall("supportsCatalogsInIndexDefinitions"); - return true; - } - - /** - * Returns whether the catalog name in GRANT is supported. - * - * @return true - */ - public boolean supportsCatalogsInPrivilegeDefinitions() { - debugCodeCall("supportsCatalogsInPrivilegeDefinitions"); - return true; - } - - /** - * Returns whether positioned deletes are supported. - * - * @return true - */ - public boolean supportsPositionedDelete() { - debugCodeCall("supportsPositionedDelete"); - return true; - } - - /** - * Returns whether positioned updates are supported. - * - * @return true - */ - public boolean supportsPositionedUpdate() { - debugCodeCall("supportsPositionedUpdate"); - return true; - } - - /** - * Returns whether SELECT ... FOR UPDATE is supported. - * - * @return true - */ - public boolean supportsSelectForUpdate() { - debugCodeCall("supportsSelectForUpdate"); - return true; - } - - /** - * Returns whether stored procedures are supported. - * - * @return false - */ - public boolean supportsStoredProcedures() { - debugCodeCall("supportsStoredProcedures"); - return false; - } - - /** - * Returns whether subqueries (SELECT) in comparisons are supported. - * - * @return true - */ - public boolean supportsSubqueriesInComparisons() { - debugCodeCall("supportsSubqueriesInComparisons"); - return true; - } - - /** - * Returns whether SELECT in EXISTS is supported. - * - * @return true - */ - public boolean supportsSubqueriesInExists() { - debugCodeCall("supportsSubqueriesInExists"); - return true; - } - - /** - * Returns whether IN(SELECT...) is supported. - * - * @return true - */ - public boolean supportsSubqueriesInIns() { - debugCodeCall("supportsSubqueriesInIns"); - return true; - } - - /** - * Returns whether subqueries in quantified expression are supported. - * - * @return true - */ - public boolean supportsSubqueriesInQuantifieds() { - debugCodeCall("supportsSubqueriesInQuantifieds"); - return true; - } - - /** - * Returns whether correlated subqueries are supported. - * - * @return true - */ - public boolean supportsCorrelatedSubqueries() { - debugCodeCall("supportsCorrelatedSubqueries"); - return true; - } - - /** - * Returns whether UNION SELECT is supported. - * - * @return true - */ - public boolean supportsUnion() { - debugCodeCall("supportsUnion"); - return true; - } - - /** - * Returns whether UNION ALL SELECT is supported. - * - * @return true - */ - public boolean supportsUnionAll() { - debugCodeCall("supportsUnionAll"); - return true; - } - - /** - * Returns whether open result sets across commits are supported. - * - * @return false - */ - public boolean supportsOpenCursorsAcrossCommit() { - debugCodeCall("supportsOpenCursorsAcrossCommit"); - return false; - } - - /** - * Returns whether open result sets across rollback are supported. - * - * @return false - */ - public boolean supportsOpenCursorsAcrossRollback() { - debugCodeCall("supportsOpenCursorsAcrossRollback"); - return false; - } - - /** - * Returns whether open statements across commit are supported. - * - * @return true - */ - public boolean supportsOpenStatementsAcrossCommit() { - debugCodeCall("supportsOpenStatementsAcrossCommit"); - return true; - } - - /** - * Returns whether open statements across rollback are supported. - * - * @return true - */ - public boolean supportsOpenStatementsAcrossRollback() { - debugCodeCall("supportsOpenStatementsAcrossRollback"); - return true; - } - - /** - * Returns whether transactions are supported. - * - * @return true - */ - public boolean supportsTransactions() { - debugCodeCall("supportsTransactions"); - return true; - } - - /** - * Returns whether a specific transaction isolation level is supported. - * - * @param level the transaction isolation level (Connection.TRANSACTION_*) - * @return true - */ - public boolean supportsTransactionIsolationLevel(int level) { - debugCodeCall("supportsTransactionIsolationLevel"); - return true; - } - - /** - * Returns whether data manipulation and CREATE/DROP is supported in - * transactions. - * - * @return false - */ - public boolean supportsDataDefinitionAndDataManipulationTransactions() { - debugCodeCall("supportsDataDefinitionAndDataManipulationTransactions"); - return false; - } - - /** - * Returns whether only data manipulations are supported in transactions. - * - * @return true - */ - public boolean supportsDataManipulationTransactionsOnly() { - debugCodeCall("supportsDataManipulationTransactionsOnly"); - return true; - } - - /** - * Returns whether CREATE/DROP commit an open transaction. - * - * @return true - */ - public boolean dataDefinitionCausesTransactionCommit() { - debugCodeCall("dataDefinitionCausesTransactionCommit"); - return true; - } - - /** - * Returns whether CREATE/DROP do not affect transactions. - * - * @return false - */ - public boolean dataDefinitionIgnoredInTransactions() { - debugCodeCall("dataDefinitionIgnoredInTransactions"); - return false; - } - - /** - * Returns whether a specific result set type is supported. - * ResultSet.TYPE_SCROLL_SENSITIVE is not supported. - * - * @param type the result set type - * @return true for all types except ResultSet.TYPE_FORWARD_ONLY - */ - public boolean supportsResultSetType(int type) { - debugCodeCall("supportsResultSetType", type); - return type != ResultSet.TYPE_SCROLL_SENSITIVE; - } - - /** - * Returns whether a specific result set concurrency is supported. - * ResultSet.TYPE_SCROLL_SENSITIVE is not supported. - * - * @param type the result set type - * @param concurrency the result set concurrency - * @return true if the type is not ResultSet.TYPE_SCROLL_SENSITIVE - */ - public boolean supportsResultSetConcurrency(int type, int concurrency) { - if (isDebugEnabled()) { - debugCode("supportsResultSetConcurrency("+type+", "+concurrency+");"); - } - return type != ResultSet.TYPE_SCROLL_SENSITIVE; - } - - /** - * Returns whether own updates are visible. - * - * @param type the result set type - * @return true - */ - public boolean ownUpdatesAreVisible(int type) { - debugCodeCall("ownUpdatesAreVisible", type); - return true; - } - - /** - * Returns whether own deletes are visible. - * - * @param type the result set type - * @return false - */ - public boolean ownDeletesAreVisible(int type) { - debugCodeCall("ownDeletesAreVisible", type); - return false; - } - - /** - * Returns whether own inserts are visible. - * - * @param type the result set type - * @return false - */ - public boolean ownInsertsAreVisible(int type) { - debugCodeCall("ownInsertsAreVisible", type); - return false; - } - - /** - * Returns whether other updates are visible. - * - * @param type the result set type - * @return false - */ - public boolean othersUpdatesAreVisible(int type) { - debugCodeCall("othersUpdatesAreVisible", type); - return false; - } - - /** - * Returns whether other deletes are visible. - * - * @param type the result set type - * @return false - */ - public boolean othersDeletesAreVisible(int type) { - debugCodeCall("othersDeletesAreVisible", type); - return false; - } - - /** - * Returns whether other inserts are visible. - * - * @param type the result set type - * @return false - */ - public boolean othersInsertsAreVisible(int type) { - debugCodeCall("othersInsertsAreVisible", type); - return false; - } - - /** - * Returns whether updates are detected. - * - * @param type the result set type - * @return false - */ - public boolean updatesAreDetected(int type) { - debugCodeCall("updatesAreDetected", type); - return false; - } - - /** - * Returns whether deletes are detected. - * - * @param type the result set type - * @return false - */ - public boolean deletesAreDetected(int type) { - debugCodeCall("deletesAreDetected", type); - return false; - } - - /** - * Returns whether inserts are detected. - * - * @param type the result set type - * @return false - */ - public boolean insertsAreDetected(int type) { - debugCodeCall("insertsAreDetected", type); - return false; - } - - /** - * Returns whether batch updates are supported. - * - * @return true - */ - public boolean supportsBatchUpdates() { - debugCodeCall("supportsBatchUpdates"); - return true; - } - - /** - * Returns whether the maximum row size includes blobs. - * - * @return false - */ - public boolean doesMaxRowSizeIncludeBlobs() { - debugCodeCall("doesMaxRowSizeIncludeBlobs"); - return false; - } - - /** - * Returns the default transaction isolation level. - * - * @return Connection.TRANSACTION_READ_COMMITTED - */ - public int getDefaultTransactionIsolation() { - debugCodeCall("getDefaultTransactionIsolation"); - return Connection.TRANSACTION_READ_COMMITTED; - } - - /** - * Checks if for CREATE TABLE Test(ID INT), getTables returns Test as the - * table name. - * - * @return false - */ - public boolean supportsMixedCaseIdentifiers() { - debugCodeCall("supportsMixedCaseIdentifiers"); - return false; - } - - /** - * Checks if a table created with CREATE TABLE "Test"(ID INT) is a different - * table than a table created with CREATE TABLE TEST(ID INT). - * - * @return true - */ - public boolean supportsMixedCaseQuotedIdentifiers() { - debugCodeCall("supportsMixedCaseQuotedIdentifiers"); - return true; - } - - /** - * Checks if for CREATE TABLE Test(ID INT), getTables returns TEST as the - * table name. - * - * @return true - */ - public boolean storesUpperCaseIdentifiers() { - debugCodeCall("storesUpperCaseIdentifiers"); - return true; - } - - /** - * Checks if for CREATE TABLE Test(ID INT), getTables returns test as the - * table name. - * - * @return false - */ - public boolean storesLowerCaseIdentifiers() { - debugCodeCall("storesLowerCaseIdentifiers"); - return false; - } - - /** - * Checks if for CREATE TABLE Test(ID INT), getTables returns Test as the - * table name. - * - * @return false - */ - public boolean storesMixedCaseIdentifiers() { - debugCodeCall("storesMixedCaseIdentifiers"); - return false; - } - - /** - * Checks if for CREATE TABLE "Test"(ID INT), getTables returns TEST as the - * table name. - * - * @return false - */ - public boolean storesUpperCaseQuotedIdentifiers() { - debugCodeCall("storesUpperCaseQuotedIdentifiers"); - return false; - } - - /** - * Checks if for CREATE TABLE "Test"(ID INT), getTables returns test as the - * table name. - * - * @return false - */ - public boolean storesLowerCaseQuotedIdentifiers() { - debugCodeCall("storesLowerCaseQuotedIdentifiers"); - return false; - } - - /** - * Checks if for CREATE TABLE "Test"(ID INT), getTables returns Test as the - * table name. - * - * @return true - */ - public boolean storesMixedCaseQuotedIdentifiers() { - debugCodeCall("storesMixedCaseQuotedIdentifiers"); - return true; - } - - /** - * Returns the maximum length for hex values (characters). - * - * @return 0 for limit is unknown - */ - public int getMaxBinaryLiteralLength() { - debugCodeCall("getMaxBinaryLiteralLength"); - return 0; - } - - /** - * Returns the maximum length for literals. - * - * @return 0 for limit is unknown - */ - public int getMaxCharLiteralLength() { - debugCodeCall("getMaxCharLiteralLength"); - return 0; - } - - /** - * Returns the maximum length for column names. - * - * @return 0 for limit is unknown - */ - public int getMaxColumnNameLength() { - debugCodeCall("getMaxColumnNameLength"); - return 0; - } - - /** - * Returns the maximum number of columns in GROUP BY. - * - * @return 0 for limit is unknown - */ - public int getMaxColumnsInGroupBy() { - debugCodeCall("getMaxColumnsInGroupBy"); - return 0; - } - - /** - * Returns the maximum number of columns in CREATE INDEX. - * - * @return 0 for limit is unknown - */ - public int getMaxColumnsInIndex() { - debugCodeCall("getMaxColumnsInIndex"); - return 0; - } - - /** - * Returns the maximum number of columns in ORDER BY. - * - * @return 0 for limit is unknown - */ - public int getMaxColumnsInOrderBy() { - debugCodeCall("getMaxColumnsInOrderBy"); - return 0; - } - - /** - * Returns the maximum number of columns in SELECT. - * - * @return 0 for limit is unknown - */ - public int getMaxColumnsInSelect() { - debugCodeCall("getMaxColumnsInSelect"); - return 0; - } - - /** - * Returns the maximum number of columns in CREATE TABLE. - * - * @return 0 for limit is unknown - */ - public int getMaxColumnsInTable() { - debugCodeCall("getMaxColumnsInTable"); - return 0; - } - - /** - * Returns the maximum number of open connection. - * - * @return 0 for limit is unknown - */ - public int getMaxConnections() { - debugCodeCall("getMaxConnections"); - return 0; - } - - /** - * Returns the maximum length for a cursor name. - * - * @return 0 for limit is unknown - */ - public int getMaxCursorNameLength() { - debugCodeCall("getMaxCursorNameLength"); - return 0; - } - - /** - * Returns the maximum length for an index (in bytes). - * - * @return 0 for limit is unknown - */ - public int getMaxIndexLength() { - debugCodeCall("getMaxIndexLength"); - return 0; - } - - /** - * Returns the maximum length for a schema name. - * - * @return 0 for limit is unknown - */ - public int getMaxSchemaNameLength() { - debugCodeCall("getMaxSchemaNameLength"); - return 0; - } - - /** - * Returns the maximum length for a procedure name. - * - * @return 0 for limit is unknown - */ - public int getMaxProcedureNameLength() { - debugCodeCall("getMaxProcedureNameLength"); - return 0; - } - - /** - * Returns the maximum length for a catalog name. - * - * @return 0 for limit is unknown - */ - public int getMaxCatalogNameLength() { - debugCodeCall("getMaxCatalogNameLength"); - return 0; - } - - /** - * Returns the maximum size of a row (in bytes). - * - * @return 0 for limit is unknown - */ - public int getMaxRowSize() { - debugCodeCall("getMaxRowSize"); - return 0; - } - - /** - * Returns the maximum length of a statement. - * - * @return 0 for limit is unknown - */ - public int getMaxStatementLength() { - debugCodeCall("getMaxStatementLength"); - return 0; - } - - /** - * Returns the maximum number of open statements. - * - * @return 0 for limit is unknown - */ - public int getMaxStatements() { - debugCodeCall("getMaxStatements"); - return 0; - } - - /** - * Returns the maximum length for a table name. - * - * @return 0 for limit is unknown - */ - public int getMaxTableNameLength() { - debugCodeCall("getMaxTableNameLength"); - return 0; - } - - /** - * Returns the maximum number of tables in a SELECT. - * - * @return 0 for limit is unknown - */ - public int getMaxTablesInSelect() { - debugCodeCall("getMaxTablesInSelect"); - return 0; - } - - /** - * Returns the maximum length for a user name. - * - * @return 0 for limit is unknown - */ - public int getMaxUserNameLength() { - debugCodeCall("getMaxUserNameLength"); - return 0; - } - - /** - * Does the database support savepoints. - * - * @return true - */ - public boolean supportsSavepoints() { - debugCodeCall("supportsSavepoints"); - return true; - } - - /** - * Does the database support named parameters. - * - * @return false - */ - public boolean supportsNamedParameters() { - debugCodeCall("supportsNamedParameters"); - return false; - } - - /** - * Does the database support multiple open result sets. - * - * @return true - */ - public boolean supportsMultipleOpenResults() { - debugCodeCall("supportsMultipleOpenResults"); - return true; - } - - /** - * Does the database support getGeneratedKeys. - * - * @return true - */ - public boolean supportsGetGeneratedKeys() { - debugCodeCall("supportsGetGeneratedKeys"); - return true; - } - - /** - * [Not supported] - */ - public ResultSet getSuperTypes(String catalog, String schemaPattern, - String typeNamePattern) throws SQLException { - throw unsupported("superTypes"); - } - - /** - * Get the list of super tables of a table. This method currently returns an - * empty result set. - *
    - *
  • 1 TABLE_CAT (String) table catalog
  • - *
  • 2 TABLE_SCHEM (String) table schema
  • - *
  • 3 TABLE_NAME (String) table name
  • - *
  • 4 SUPERTABLE_NAME (String) the name of the super table
  • - *
- * - * @param catalog null (to get all objects) or the catalog name - * @param schemaPattern null (to get all objects) or a schema name (uppercase for - * unquoted names) - * @param tableNamePattern null (to get all objects) or a table name pattern - * (uppercase for unquoted names) - * @return an empty result set - */ - public ResultSet getSuperTables(String catalog, String schemaPattern, - String tableNamePattern) throws SQLException { - try { - if (isDebugEnabled()) { - debugCode("getSuperTables(" - +quote(catalog)+", " - +quote(schemaPattern)+", " - +quote(tableNamePattern)+");"); - } - checkClosed(); - PreparedStatement prep = conn.prepareAutoCloseStatement("SELECT " - + "CATALOG_NAME TABLE_CAT, " - + "CATALOG_NAME TABLE_SCHEM, " - + "CATALOG_NAME TABLE_NAME, " - + "CATALOG_NAME SUPERTABLE_NAME " - + "FROM INFORMATION_SCHEMA.CATALOGS " - + "WHERE FALSE"); - return prep.executeQuery(); - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * [Not supported] - */ - public ResultSet getAttributes(String catalog, String schemaPattern, - String typeNamePattern, String attributeNamePattern) - throws SQLException { - throw unsupported("attributes"); - } - - /** - * Does this database supports a result set holdability. - * - * @param holdability ResultSet.HOLD_CURSORS_OVER_COMMIT or - * CLOSE_CURSORS_AT_COMMIT - * @return true if the holdability is ResultSet.CLOSE_CURSORS_AT_COMMIT - */ -//## Java 1.4 begin ## - public boolean supportsResultSetHoldability(int holdability) { - debugCodeCall("supportsResultSetHoldability", holdability); - return holdability == ResultSet.CLOSE_CURSORS_AT_COMMIT; - } -//## Java 1.4 end ## - - /** - * Gets the result set holdability. - * - * @return ResultSet.CLOSE_CURSORS_AT_COMMIT - */ - //## Java 1.4 begin ## - public int getResultSetHoldability() { - debugCodeCall("getResultSetHoldability"); - return ResultSet.CLOSE_CURSORS_AT_COMMIT; - } - //## Java 1.4 end ## - - /** - * Gets the major version of the database. - * - * @return the major version - */ - public int getDatabaseMajorVersion() { - debugCodeCall("getDatabaseMajorVersion"); - return Constants.VERSION_MAJOR; - } - - /** - * Gets the minor version of the database. - * - * @return the minor version - */ - public int getDatabaseMinorVersion() { - debugCodeCall("getDatabaseMinorVersion"); - return Constants.VERSION_MINOR; - } - - /** - * Gets the major version of the supported JDBC API. - * - * @return the major version (3) - */ - public int getJDBCMajorVersion() { - debugCodeCall("getJDBCMajorVersion"); - return 3; - } - - /** - * Gets the minor version of the supported JDBC API. - * - * @return the minor version (0) - */ - public int getJDBCMinorVersion() { - debugCodeCall("getJDBCMinorVersion"); - return 0; - } - - /** - * Gets the SQL State type. - * - * @return DatabaseMetaData.sqlStateSQL99 - */ -//## Java 1.4 begin ## - public int getSQLStateType() { - debugCodeCall("getSQLStateType"); - return DatabaseMetaData.sqlStateSQL99; - } -//## Java 1.4 end ## - - /** - * Does the database make a copy before updating. - * - * @return false - */ - public boolean locatorsUpdateCopy() { - debugCodeCall("locatorsUpdateCopy"); - return false; - } - - /** - * Does the database support statement pooling. - * - * @return false - */ - public boolean supportsStatementPooling() { - debugCodeCall("supportsStatementPooling"); - return false; - } - - // ============================================================= - - private void checkClosed() throws SQLException { - conn.checkClosed(); - } - - private String getPattern(String pattern) { - return pattern == null ? "%" : pattern; - } - - private String getSchemaPattern(String pattern) { - return pattern == null ? "%" : pattern.length() == 0 ? Constants.SCHEMA_MAIN : pattern; - } - - private String getCatalogPattern(String catalogPattern) { - // Workaround for OpenOffice: getColumns is called with "" as the catalog - return catalogPattern == null || catalogPattern.length() == 0 ? "%" : catalogPattern; - } - - /** - * Get the lifetime of a rowid. - * - * @return ROWID_UNSUPPORTED - */ -/*## Java 1.6 begin ## - public RowIdLifetime getRowIdLifetime() { - debugCodeCall("getRowIdLifetime"); - return RowIdLifetime.ROWID_UNSUPPORTED; - } -## Java 1.6 end ##*/ - - /** - * [Not supported] Gets the list of schemas. - */ -/*## Java 1.6 begin ## - public ResultSet getSchemas(String catalog, String schemaPattern) - throws SQLException { - throw unsupported("getSchemas(., .)"); - } -## Java 1.6 end ##*/ - - /** - * Returns whether the database supports calling functions using the call syntax. - * - * @return true - */ - public boolean supportsStoredFunctionsUsingCallSyntax() { - debugCodeCall("supportsStoredFunctionsUsingCallSyntax"); - return true; - } - - /** - * Returns whether an exception while auto commit is on closes all result sets. - * - * @return false - */ - public boolean autoCommitFailureClosesAllResultSets() { - debugCodeCall("autoCommitFailureClosesAllResultSets"); - return false; - } - - /** - * [Not supported] Returns the client info properties. - */ - public ResultSet getClientInfoProperties() throws SQLException { - throw unsupported("clientInfoProperties"); - } - - /** - * [Not supported] Return an object of this class if possible. - */ -/*## Java 1.6 begin ## - public T unwrap(Class iface) throws SQLException { - throw unsupported("unwrap"); - } -## Java 1.6 end ##*/ - - /** - * [Not supported] Checks if unwrap can return an object of this class. - */ -/*## Java 1.6 begin ## - public boolean isWrapperFor(Class< ? > iface) throws SQLException { - throw unsupported("isWrapperFor"); - } -## Java 1.6 end ##*/ - - /** - * [Not supported] Gets the list of function columns. - */ -/*## Java 1.6 begin ## - public ResultSet getFunctionColumns(String catalog, String schemaPattern, - String functionNamePattern, String columnNamePattern) - throws SQLException { - throw unsupported("getFunctionColumns"); - } -## Java 1.6 end ##*/ - - /** - * [Not supported] Gets the list of functions. - */ -/*## Java 1.6 begin ## - public ResultSet getFunctions(String catalog, String schemaPattern, - String functionNamePattern) throws SQLException { - throw unsupported("getFunctions"); - } -## Java 1.6 end ##*/ - - /** - * INTERNAL - */ - public String toString() { - return getTraceObjectName() + ": " + conn; - } - -} diff --git a/tools/h2/src/main/org/h2/jdbc/JdbcParameterMetaData.java b/tools/h2/src/main/org/h2/jdbc/JdbcParameterMetaData.java deleted file mode 100755 index 20f3593..0000000 --- a/tools/h2/src/main/org/h2/jdbc/JdbcParameterMetaData.java +++ /dev/null @@ -1,242 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.jdbc; - -import java.sql.ParameterMetaData; -import java.sql.SQLException; -import java.util.ArrayList; -import org.h2.command.CommandInterface; -import org.h2.expression.ParameterInterface; -import org.h2.message.DbException; -import org.h2.message.Trace; -import org.h2.message.TraceObject; -import org.h2.util.MathUtils; -import org.h2.value.DataType; -import org.h2.value.Value; - -/** - * Information about the parameters of a prepared statement. - */ -public class JdbcParameterMetaData extends TraceObject -//## Java 1.4 begin ## -implements ParameterMetaData -//## Java 1.4 end ## -{ - - private JdbcPreparedStatement prep; - private int paramCount; - private ArrayList< ? extends ParameterInterface> parameters; - - JdbcParameterMetaData(Trace trace, JdbcPreparedStatement prep, CommandInterface command, int id) { - setTrace(trace, TraceObject.PARAMETER_META_DATA, id); - this.prep = prep; - this.parameters = command.getParameters(); - this.paramCount = parameters.size(); - } - - /** - * Returns the number of parameters. - * - * @return the number - */ - public int getParameterCount() throws SQLException { - try { - debugCodeCall("getParameterCount"); - checkClosed(); - return paramCount; - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Returns the parameter mode. - * Always returns parameterModeIn. - * - * @param param the column index (1,2,...) - * @return parameterModeIn - */ -//## Java 1.4 begin ## - public int getParameterMode(int param) throws SQLException { - try { - debugCodeCall("getParameterMode", param); - getParameter(param); - return parameterModeIn; - } catch (Exception e) { - throw logAndConvert(e); - } - } -//## Java 1.4 end ## - - /** - * Returns the parameter type. - * java.sql.Types.VARCHAR is returned if the data type is not known. - * - * @param param the column index (1,2,...) - * @return the data type - */ - public int getParameterType(int param) throws SQLException { - try { - debugCodeCall("getParameterType", param); - ParameterInterface p = getParameter(param); - int type = p.getType(); - if (type == Value.UNKNOWN) { - type = Value.STRING; - } - return DataType.getDataType(type).sqlType; - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Returns the parameter precision. - * The value 0 is returned if the precision is not known. - * - * @param param the column index (1,2,...) - * @return the precision - */ - public int getPrecision(int param) throws SQLException { - try { - debugCodeCall("getPrecision", param); - ParameterInterface p = getParameter(param); - return MathUtils.convertLongToInt(p.getPrecision()); - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Returns the parameter scale. - * The value 0 is returned if the scale is not known. - * - * @param param the column index (1,2,...) - * @return the scale - */ - public int getScale(int param) throws SQLException { - try { - debugCodeCall("getScale", param); - ParameterInterface p = getParameter(param); - return p.getScale(); - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Checks if this is nullable parameter. - * Returns ResultSetMetaData.columnNullableUnknown.. - * - * @param param the column index (1,2,...) - * @return ResultSetMetaData.columnNullableUnknown - */ - public int isNullable(int param) throws SQLException { - try { - debugCodeCall("isNullable", param); - return getParameter(param).getNullable(); - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Checks if this parameter is signed. - * It always returns true. - * - * @param param the column index (1,2,...) - * @return true - */ - public boolean isSigned(int param) throws SQLException { - try { - debugCodeCall("isSigned", param); - getParameter(param); - return true; - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Returns the Java class name of the parameter. - * "java.lang.String" is returned if the type is not known. - * - * @param param the column index (1,2,...) - * @return the Java class name - */ - public String getParameterClassName(int param) throws SQLException { - try { - debugCodeCall("getParameterClassName", param); - ParameterInterface p = getParameter(param); - int type = p.getType(); - if (type == Value.UNKNOWN) { - type = Value.STRING; - } - return DataType.getTypeClassName(type); - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Returns the parameter type name. - * "VARCHAR" is returned if the type is not known. - * - * @param param the column index (1,2,...) - * @return the type name - */ - public String getParameterTypeName(int param) throws SQLException { - try { - debugCodeCall("getParameterTypeName", param); - ParameterInterface p = getParameter(param); - int type = p.getType(); - if (type == Value.UNKNOWN) { - type = Value.STRING; - } - return DataType.getDataType(type).name; - } catch (Exception e) { - throw logAndConvert(e); - } - } - - private ParameterInterface getParameter(int param) throws SQLException { - checkClosed(); - if (param < 1 || param > paramCount) { - throw DbException.getInvalidValueException("" + param, "param"); - } - return parameters.get(param - 1); - } - - private void checkClosed() throws SQLException { - prep.checkClosed(); - } - - /** - * [Not supported] Return an object of this class if possible. - */ -/*## Java 1.6 begin ## - public T unwrap(Class iface) throws SQLException { - throw unsupported("unwrap"); - } -## Java 1.6 end ##*/ - - /** - * [Not supported] Checks if unwrap can return an object of this class. - */ -/*## Java 1.6 begin ## - public boolean isWrapperFor(Class< ? > iface) throws SQLException { - throw unsupported("isWrapperFor"); - } -## Java 1.6 end ##*/ - - /** - * INTERNAL - */ - public String toString() { - return getTraceObjectName() + ": parameterCount=" + paramCount; - } - -} diff --git a/tools/h2/src/main/org/h2/jdbc/JdbcPreparedStatement.java b/tools/h2/src/main/org/h2/jdbc/JdbcPreparedStatement.java deleted file mode 100755 index 1e234a7..0000000 --- a/tools/h2/src/main/org/h2/jdbc/JdbcPreparedStatement.java +++ /dev/null @@ -1,1505 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.jdbc; - -import java.io.InputStream; -import java.io.Reader; -import java.math.BigDecimal; -import java.net.URL; -import java.sql.Array; -import java.sql.Blob; -import java.sql.Clob; -import java.sql.ParameterMetaData; -import java.sql.PreparedStatement; -import java.sql.Ref; -import java.sql.ResultSet; -import java.sql.ResultSetMetaData; -import java.sql.SQLException; -import java.sql.Statement; -import java.util.ArrayList; -import java.util.Calendar; -import org.h2.command.CommandInterface; -import org.h2.constant.ErrorCode; -import org.h2.expression.ParameterInterface; -import org.h2.message.DbException; -import org.h2.message.TraceObject; -import org.h2.result.ResultInterface; -import org.h2.util.DateTimeUtils; -import org.h2.util.IOUtils; -import org.h2.util.New; -import org.h2.value.DataType; -import org.h2.value.Value; -import org.h2.value.ValueBoolean; -import org.h2.value.ValueByte; -import org.h2.value.ValueBytes; -import org.h2.value.ValueDate; -import org.h2.value.ValueDecimal; -import org.h2.value.ValueDouble; -import org.h2.value.ValueFloat; -import org.h2.value.ValueInt; -import org.h2.value.ValueLong; -import org.h2.value.ValueNull; -import org.h2.value.ValueShort; -import org.h2.value.ValueString; -import org.h2.value.ValueTime; -import org.h2.value.ValueTimestamp; - -/*## Java 1.6 begin ## -import java.sql.RowId; -import java.sql.NClob; -import java.sql.SQLXML; -## Java 1.6 end ##*/ - -/** - * Represents a prepared statement. - */ -public class JdbcPreparedStatement extends JdbcStatement implements PreparedStatement { - - private final String sqlStatement; - private CommandInterface command; - private ArrayList batchParameters; - - JdbcPreparedStatement(JdbcConnection conn, String sql, int id, int resultSetType, - int resultSetConcurrency, boolean closeWithResultSet) { - super(conn, id, resultSetType, resultSetConcurrency, closeWithResultSet); - setTrace(session.getTrace(), TraceObject.PREPARED_STATEMENT, id); - this.sqlStatement = sql; - command = conn.prepareCommand(sql, fetchSize); - } - - /** - * Executes a query (select statement) and returns the result set. If - * another result set exists for this statement, this will be closed (even - * if this statement fails). - * - * @return the result set - * @throws SQLException if this object is closed or invalid - */ - public ResultSet executeQuery() throws SQLException { - try { - int id = getNextId(TraceObject.RESULT_SET); - if (isDebugEnabled()) { - debugCodeAssign("ResultSet", TraceObject.RESULT_SET, id, "executeQuery()"); - } - checkClosed(); - closeOldResultSet(); - ResultInterface result; - boolean scrollable = resultSetType != ResultSet.TYPE_FORWARD_ONLY; - boolean updatable = resultSetConcurrency == ResultSet.CONCUR_UPDATABLE; - synchronized (session) { - try { - setExecutingStatement(command); - result = command.executeQuery(maxRows, scrollable); - } finally { - setExecutingStatement(null); - } - } - resultSet = new JdbcResultSet(conn, this, result, id, closedByResultSet, scrollable, updatable); - return resultSet; - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Executes a statement (insert, update, delete, create, drop, commit, - * rollback) and returns the update count. If another result set exists for - * this statement, this will be closed (even if this statement fails). - * - * If the statement is a create or drop and does not throw an exception, the - * current transaction (if any) is committed after executing the statement. - * If auto commit is on, this statement will be committed. - * - * @return the update count (number of row affected by an insert, update or - * delete, or 0 if no rows or the statement was a create, drop, - * commit or rollback) - * @throws SQLException if this object is closed or invalid - */ - public int executeUpdate() throws SQLException { - try { - debugCodeCall("executeUpdate"); - checkClosedForWrite(); - try { - return executeUpdateInternal(); - } finally { - afterWriting(); - } - } catch (Exception e) { - throw logAndConvert(e); - } - } - - private int executeUpdateInternal() throws SQLException { - closeOldResultSet(); - synchronized (session) { - try { - setExecutingStatement(command); - updateCount = command.executeUpdate(); - } finally { - setExecutingStatement(null); - } - } - return updateCount; - } - - /** - * Executes an arbitrary statement. If another result set exists for this - * statement, this will be closed (even if this statement fails). If auto - * commit is on, and the statement is not a select, this statement will be - * committed. - * - * @return true if a result set is available, false if not - * @throws SQLException if this object is closed or invalid - */ - public boolean execute() throws SQLException { - try { - int id = getNextId(TraceObject.RESULT_SET); - if (isDebugEnabled()) { - debugCodeCall("execute"); - } - checkClosedForWrite(); - try { - closeOldResultSet(); - boolean returnsResultSet; - synchronized (conn.getSession()) { - try { - setExecutingStatement(command); - if (command.isQuery()) { - returnsResultSet = true; - boolean scrollable = resultSetType != ResultSet.TYPE_FORWARD_ONLY; - boolean updatable = resultSetConcurrency == ResultSet.CONCUR_UPDATABLE; - ResultInterface result = command.executeQuery(maxRows, scrollable); - resultSet = new JdbcResultSet(conn, this, result, id, closedByResultSet, scrollable, updatable); - } else { - returnsResultSet = false; - updateCount = command.executeUpdate(); - } - } finally { - setExecutingStatement(null); - } - } - return returnsResultSet; - } finally { - afterWriting(); - } - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Clears all parameters. - * - * @throws SQLException if this object is closed or invalid - */ - public void clearParameters() throws SQLException { - try { - debugCodeCall("clearParameters"); - checkClosed(); - ArrayList< ? extends ParameterInterface> parameters = command.getParameters(); - for (ParameterInterface param : parameters) { - // can only delete old temp files if they are not in the batch - param.setValue(null, batchParameters == null); - } - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Calling this method is not legal on a PreparedStatement. - * - * @throws SQLException Unsupported Feature - */ - public ResultSet executeQuery(String sql) throws SQLException { - try { - debugCodeCall("executeQuery", sql); - throw DbException.get(ErrorCode.METHOD_NOT_ALLOWED_FOR_PREPARED_STATEMENT); - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Calling this method is not legal on a PreparedStatement. - * - * @throws SQLException Unsupported Feature - */ - public void addBatch(String sql) throws SQLException { - try { - debugCodeCall("addBatch", sql); - throw DbException.get(ErrorCode.METHOD_NOT_ALLOWED_FOR_PREPARED_STATEMENT); - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Calling this method is not legal on a PreparedStatement. - * - * @throws SQLException Unsupported Feature - */ - public int executeUpdate(String sql) throws SQLException { - try { - debugCodeCall("executeUpdate", sql); - throw DbException.get(ErrorCode.METHOD_NOT_ALLOWED_FOR_PREPARED_STATEMENT); - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Calling this method is not legal on a PreparedStatement. - * - * @throws SQLException Unsupported Feature - */ - public boolean execute(String sql) throws SQLException { - try { - debugCodeCall("execute", sql); - throw DbException.get(ErrorCode.METHOD_NOT_ALLOWED_FOR_PREPARED_STATEMENT); - } catch (Exception e) { - throw logAndConvert(e); - } - } - - // ============================================================= - - /** - * Sets a parameter to null. - * - * @param parameterIndex the parameter index (1, 2, ...) - * @param sqlType the data type (Types.x) - * @throws SQLException if this object is closed - */ - public void setNull(int parameterIndex, int sqlType) throws SQLException { - try { - if (isDebugEnabled()) { - debugCode("setNull("+parameterIndex+", "+sqlType+");"); - } - setParameter(parameterIndex, ValueNull.INSTANCE); - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Sets the value of a parameter. - * - * @param parameterIndex the parameter index (1, 2, ...) - * @param x the value - * @throws SQLException if this object is closed - */ - public void setInt(int parameterIndex, int x) throws SQLException { - try { - if (isDebugEnabled()) { - debugCode("setInt("+parameterIndex+", "+x+");"); - } - setParameter(parameterIndex, ValueInt.get(x)); - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Sets the value of a parameter. - * - * @param parameterIndex the parameter index (1, 2, ...) - * @param x the value - * @throws SQLException if this object is closed - */ - public void setString(int parameterIndex, String x) throws SQLException { - try { - if (isDebugEnabled()) { - debugCode("setString("+parameterIndex+", "+quote(x)+");"); - } - Value v = x == null ? (Value) ValueNull.INSTANCE : ValueString.get(x); - setParameter(parameterIndex, v); - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Sets the value of a parameter. - * - * @param parameterIndex the parameter index (1, 2, ...) - * @param x the value - * @throws SQLException if this object is closed - */ - public void setBigDecimal(int parameterIndex, BigDecimal x) throws SQLException { - try { - if (isDebugEnabled()) { - debugCode("setBigDecimal("+parameterIndex+", " + quoteBigDecimal(x) + ");"); - } - Value v = x == null ? (Value) ValueNull.INSTANCE : ValueDecimal.get(x); - setParameter(parameterIndex, v); - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Sets the value of a parameter. - * - * @param parameterIndex the parameter index (1, 2, ...) - * @param x the value - * @throws SQLException if this object is closed - */ - public void setDate(int parameterIndex, java.sql.Date x) throws SQLException { - try { - if (isDebugEnabled()) { - debugCode("setDate("+parameterIndex+", " + quoteDate(x) + ");"); - } - Value v = x == null ? (Value) ValueNull.INSTANCE : ValueDate.get(x); - setParameter(parameterIndex, v); - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Sets the value of a parameter. - * - * @param parameterIndex the parameter index (1, 2, ...) - * @param x the value - * @throws SQLException if this object is closed - */ - public void setTime(int parameterIndex, java.sql.Time x) throws SQLException { - try { - if (isDebugEnabled()) { - debugCode("setTime("+parameterIndex+", " + quoteTime(x) + ");"); - } - Value v = x == null ? (Value) ValueNull.INSTANCE : ValueTime.get(x); - setParameter(parameterIndex, v); - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Sets the value of a parameter. - * - * @param parameterIndex the parameter index (1, 2, ...) - * @param x the value - * @throws SQLException if this object is closed - */ - public void setTimestamp(int parameterIndex, java.sql.Timestamp x) throws SQLException { - try { - if (isDebugEnabled()) { - debugCode("setTimestamp("+parameterIndex+", " + quoteTimestamp(x) + ");"); - } - Value v = x == null ? (Value) ValueNull.INSTANCE : ValueTimestamp.get(x); - setParameter(parameterIndex, v); - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Sets the value of a parameter. - * - * @param parameterIndex the parameter index (1, 2, ...) - * @param x the value - * @throws SQLException if this object is closed - */ - public void setObject(int parameterIndex, Object x) throws SQLException { - try { - if (isDebugEnabled()) { - debugCode("setObject("+parameterIndex+", x);"); - } - if (x == null) { - // throw Errors.getInvalidValueException("null", "x"); - setParameter(parameterIndex, ValueNull.INSTANCE); - } else { - setParameter(parameterIndex, DataType.convertToValue(session, x, Value.UNKNOWN)); - } - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Sets the value of a parameter. The object is converted, if required, to - * the specified data type before sending to the database. - * - * @param parameterIndex the parameter index (1, 2, ...) - * @param x the value, null is allowed - * @param targetSqlType the type as defined in java.sql.Types - * @throws SQLException if this object is closed - */ - public void setObject(int parameterIndex, Object x, int targetSqlType) throws SQLException { - try { - if (isDebugEnabled()) { - debugCode("setObject("+parameterIndex+", x, "+targetSqlType+");"); - } - int type = DataType.convertSQLTypeToValueType(targetSqlType); - if (x == null) { - setParameter(parameterIndex, ValueNull.INSTANCE); - } else { - Value v = DataType.convertToValue(conn.getSession(), x, type); - setParameter(parameterIndex, v.convertTo(type)); - } - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Sets the value of a parameter. The object is converted, if required, to - * the specified data type before sending to the database. - * - * @param parameterIndex the parameter index (1, 2, ...) - * @param x the value, null is allowed - * @param targetSqlType the type as defined in java.sql.Types - * @param scale is ignored - * @throws SQLException if this object is closed - */ - public void setObject(int parameterIndex, Object x, int targetSqlType, int scale) throws SQLException { - try { - if (isDebugEnabled()) { - debugCode("setObject("+parameterIndex+", x, "+targetSqlType+", "+scale+");"); - } - setObject(parameterIndex, x, targetSqlType); - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Sets the value of a parameter. - * - * @param parameterIndex the parameter index (1, 2, ...) - * @param x the value - * @throws SQLException if this object is closed - */ - public void setBoolean(int parameterIndex, boolean x) throws SQLException { - try { - if (isDebugEnabled()) { - debugCode("setBoolean("+parameterIndex+", "+x+");"); - } - setParameter(parameterIndex, ValueBoolean.get(x)); - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Sets the value of a parameter. - * - * @param parameterIndex the parameter index (1, 2, ...) - * @param x the value - * @throws SQLException if this object is closed - */ - public void setByte(int parameterIndex, byte x) throws SQLException { - try { - if (isDebugEnabled()) { - debugCode("setByte("+parameterIndex+", "+x+");"); - } - setParameter(parameterIndex, ValueByte.get(x)); - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Sets the value of a parameter. - * - * @param parameterIndex the parameter index (1, 2, ...) - * @param x the value - * @throws SQLException if this object is closed - */ - public void setShort(int parameterIndex, short x) throws SQLException { - try { - if (isDebugEnabled()) { - debugCode("setShort("+parameterIndex+", (short) "+x+");"); - } - setParameter(parameterIndex, ValueShort.get(x)); - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Sets the value of a parameter. - * - * @param parameterIndex the parameter index (1, 2, ...) - * @param x the value - * @throws SQLException if this object is closed - */ - public void setLong(int parameterIndex, long x) throws SQLException { - try { - if (isDebugEnabled()) { - debugCode("setLong("+parameterIndex+", "+x+"L);"); - } - setParameter(parameterIndex, ValueLong.get(x)); - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Sets the value of a parameter. - * - * @param parameterIndex the parameter index (1, 2, ...) - * @param x the value - * @throws SQLException if this object is closed - */ - public void setFloat(int parameterIndex, float x) throws SQLException { - try { - if (isDebugEnabled()) { - debugCode("setFloat("+parameterIndex+", "+x+"f);"); - } - setParameter(parameterIndex, ValueFloat.get(x)); - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Sets the value of a parameter. - * - * @param parameterIndex the parameter index (1, 2, ...) - * @param x the value - * @throws SQLException if this object is closed - */ - public void setDouble(int parameterIndex, double x) throws SQLException { - try { - if (isDebugEnabled()) { - debugCode("setDouble("+parameterIndex+", "+x+"d);"); - } - setParameter(parameterIndex, ValueDouble.get(x)); - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * [Not supported] Sets the value of a column as a reference. - */ - public void setRef(int parameterIndex, Ref x) throws SQLException { - throw unsupported("ref"); - } - - /** - * Sets the date using a specified time zone. The value will be converted to - * the local time zone. - * - * @param parameterIndex the parameter index (1, 2, ...) - * @param x the value - * @param calendar the calendar - * @throws SQLException if this object is closed - */ - public void setDate(int parameterIndex, java.sql.Date x, Calendar calendar) throws SQLException { - try { - if (isDebugEnabled()) { - debugCode("setDate("+parameterIndex+", " + quoteDate(x) + ", calendar);"); - } - if (x == null) { - setParameter(parameterIndex, ValueNull.INSTANCE); - } else { - setParameter(parameterIndex, DateTimeUtils.convertDateToUniversal(x, calendar)); - } - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Sets the time using a specified time zone. The value will be converted to - * the local time zone. - * - * @param parameterIndex the parameter index (1, 2, ...) - * @param x the value - * @param calendar the calendar - * @throws SQLException if this object is closed - */ - public void setTime(int parameterIndex, java.sql.Time x, Calendar calendar) throws SQLException { - try { - if (isDebugEnabled()) { - debugCode("setTime("+parameterIndex+", " + quoteTime(x) + ", calendar);"); - } - if (x == null) { - setParameter(parameterIndex, ValueNull.INSTANCE); - } else { - setParameter(parameterIndex, DateTimeUtils.convertTimeToUniversal(x, calendar)); - } - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Sets the timestamp using a specified time zone. The value will be - * converted to the local time zone. - * - * @param parameterIndex the parameter index (1, 2, ...) - * @param x the value - * @param calendar the calendar - * @throws SQLException if this object is closed - */ - public void setTimestamp(int parameterIndex, java.sql.Timestamp x, Calendar calendar) throws SQLException { - try { - if (isDebugEnabled()) { - debugCode("setTimestamp("+parameterIndex+", " + quoteTimestamp(x) + ", calendar);"); - } - if (x == null) { - setParameter(parameterIndex, ValueNull.INSTANCE); - } else { - setParameter(parameterIndex, DateTimeUtils.convertTimestampToUniversal(x, calendar)); - } - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * [Not supported] This feature is deprecated and not supported. - * @deprecated - */ - public void setUnicodeStream(int parameterIndex, InputStream x, int length) throws SQLException { - throw unsupported("unicodeStream"); - } - - /** - * Sets a parameter to null. - * - * @param parameterIndex the parameter index (1, 2, ...) - * @param sqlType the data type (Types.x) - * @param typeName this parameter is ignored - * @throws SQLException if this object is closed - */ - public void setNull(int parameterIndex, int sqlType, String typeName) throws SQLException { - try { - if (isDebugEnabled()) { - debugCode("setNull("+parameterIndex+", "+sqlType+", "+quote(typeName)+");"); - } - setNull(parameterIndex, sqlType); - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Sets the value of a parameter as a Blob. - * - * @param parameterIndex the parameter index (1, 2, ...) - * @param x the value - * @throws SQLException if this object is closed - */ - public void setBlob(int parameterIndex, Blob x) throws SQLException { - try { - if (isDebugEnabled()) { - debugCode("setBlob("+parameterIndex+", x);"); - } - checkClosedForWrite(); - try { - Value v; - if (x == null) { - v = ValueNull.INSTANCE; - } else { - v = conn.createBlob(x.getBinaryStream(), -1); - } - setParameter(parameterIndex, v); - } finally { - afterWriting(); - } - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Sets the value of a parameter as a Blob. - * This method does not close the stream. - * The stream may be closed after executing the statement. - * - * @param parameterIndex the parameter index (1, 2, ...) - * @param x the value - * @throws SQLException if this object is closed - */ - public void setBlob(int parameterIndex, InputStream x) throws SQLException { - try { - if (isDebugEnabled()) { - debugCode("setBlob("+parameterIndex+", x);"); - } - checkClosedForWrite(); - try { - Value v = conn.createBlob(x, -1); - setParameter(parameterIndex, v); - } finally { - afterWriting(); - } - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Sets the value of a parameter as a Clob. - * - * @param parameterIndex the parameter index (1, 2, ...) - * @param x the value - * @throws SQLException if this object is closed - */ - public void setClob(int parameterIndex, Clob x) throws SQLException { - try { - if (isDebugEnabled()) { - debugCode("setClob("+parameterIndex+", x);"); - } - checkClosedForWrite(); - try { - Value v; - if (x == null) { - v = ValueNull.INSTANCE; - } else { - v = conn.createClob(x.getCharacterStream(), -1); - } - setParameter(parameterIndex, v); - } finally { - afterWriting(); - } - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Sets the value of a parameter as a Clob. - * This method does not close the reader. - * The reader may be closed after executing the statement. - * - * @param parameterIndex the parameter index (1, 2, ...) - * @param x the value - * @throws SQLException if this object is closed - */ - public void setClob(int parameterIndex, Reader x) throws SQLException { - try { - if (isDebugEnabled()) { - debugCode("setClob("+parameterIndex+", x);"); - } - checkClosedForWrite(); - try { - Value v; - if (x == null) { - v = ValueNull.INSTANCE; - } else { - v = conn.createClob(x, -1); - } - setParameter(parameterIndex, v); - } finally { - afterWriting(); - } - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * [Not supported] Sets the value of a parameter as a Array. - */ - public void setArray(int parameterIndex, Array x) throws SQLException { - throw unsupported("setArray"); - } - - /** - * Sets the value of a parameter as a byte array. - * - * @param parameterIndex the parameter index (1, 2, ...) - * @param x the value - * @throws SQLException if this object is closed - */ - public void setBytes(int parameterIndex, byte[] x) throws SQLException { - try { - if (isDebugEnabled()) { - debugCode("setBytes("+parameterIndex+", "+quoteBytes(x)+");"); - } - Value v = x == null ? (Value) ValueNull.INSTANCE : ValueBytes.get(x); - setParameter(parameterIndex, v); - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Sets the value of a parameter as an input stream. - * This method does not close the stream. - * The stream may be closed after executing the statement. - * - * @param parameterIndex the parameter index (1, 2, ...) - * @param x the value - * @param length the number of bytes - * @throws SQLException if this object is closed - */ - public void setBinaryStream(int parameterIndex, InputStream x, long length) throws SQLException { - try { - if (isDebugEnabled()) { - debugCode("setBinaryStream("+parameterIndex+", x, "+length+"L);"); - } - checkClosedForWrite(); - try { - Value v = conn.createBlob(x, length); - setParameter(parameterIndex, v); - } finally { - afterWriting(); - } - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Sets the value of a parameter as an input stream. - * This method does not close the stream. - * The stream may be closed after executing the statement. - * - * @param parameterIndex the parameter index (1, 2, ...) - * @param x the value - * @param length the number of bytes - * @throws SQLException if this object is closed - */ - public void setBinaryStream(int parameterIndex, InputStream x, int length) throws SQLException { - setBinaryStream(parameterIndex, x, (long) length); - } - - /** - * Sets the value of a parameter as an input stream. - * This method does not close the stream. - * The stream may be closed after executing the statement. - * - * @param parameterIndex the parameter index (1, 2, ...) - * @param x the value - * @throws SQLException if this object is closed - */ - public void setBinaryStream(int parameterIndex, InputStream x) throws SQLException { - setBinaryStream(parameterIndex, x, -1); - } - - /** - * Sets the value of a parameter as an ASCII stream. - * This method does not close the stream. - * The stream may be closed after executing the statement. - * - * @param parameterIndex the parameter index (1, 2, ...) - * @param x the value - * @param length the number of bytes - * @throws SQLException if this object is closed - */ - public void setAsciiStream(int parameterIndex, InputStream x, int length) throws SQLException { - setAsciiStream(parameterIndex, x, (long) length); - } - - /** - * Sets the value of a parameter as an ASCII stream. - * This method does not close the stream. - * The stream may be closed after executing the statement. - * - * @param parameterIndex the parameter index (1, 2, ...) - * @param x the value - * @param length the number of bytes - * @throws SQLException if this object is closed - */ - public void setAsciiStream(int parameterIndex, InputStream x, long length) throws SQLException { - try { - if (isDebugEnabled()) { - debugCode("setAsciiStream("+parameterIndex+", x, "+length+"L);"); - } - checkClosedForWrite(); - try { - Value v = conn.createClob(IOUtils.getAsciiReader(x), length); - setParameter(parameterIndex, v); - } finally { - afterWriting(); - } - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Sets the value of a parameter as an ASCII stream. - * This method does not close the stream. - * The stream may be closed after executing the statement. - * - * @param parameterIndex the parameter index (1, 2, ...) - * @param x the value - * @throws SQLException if this object is closed - */ - public void setAsciiStream(int parameterIndex, InputStream x) throws SQLException { - setAsciiStream(parameterIndex, x, -1); - } - - /** - * Sets the value of a parameter as a character stream. - * This method does not close the reader. - * The reader may be closed after executing the statement. - * - * @param parameterIndex the parameter index (1, 2, ...) - * @param x the value - * @param length the number of bytes - * @throws SQLException if this object is closed - */ - public void setCharacterStream(int parameterIndex, Reader x, int length) throws SQLException { - setCharacterStream(parameterIndex, x, (long) length); - } - - /** - * Sets the value of a parameter as a character stream. - * This method does not close the reader. - * The reader may be closed after executing the statement. - * - * @param parameterIndex the parameter index (1, 2, ...) - * @param x the value - * @throws SQLException if this object is closed - */ - public void setCharacterStream(int parameterIndex, Reader x) throws SQLException { - setCharacterStream(parameterIndex, x, -1); - } - - /** - * Sets the value of a parameter as a character stream. - * This method does not close the reader. - * The reader may be closed after executing the statement. - * - * @param parameterIndex the parameter index (1, 2, ...) - * @param x the value - * @param length the number of bytes - * @throws SQLException if this object is closed - */ - public void setCharacterStream(int parameterIndex, Reader x, long length) throws SQLException { - try { - if (isDebugEnabled()) { - debugCode("setCharacterStream("+parameterIndex+", x, "+length+"L);"); - } - checkClosedForWrite(); - try { - Value v = conn.createClob(x, length); - setParameter(parameterIndex, v); - } finally { - afterWriting(); - } - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * [Not supported] - */ - public void setURL(int parameterIndex, URL x) throws SQLException { - throw unsupported("url"); - } - - /** - * Gets the result set metadata of the query returned when the statement is - * executed. If this is not a query, this method returns null. - * - * @return the meta data or null if this is not a query - * @throws SQLException if this object is closed - */ - public ResultSetMetaData getMetaData() throws SQLException { - try { - debugCodeCall("getMetaData"); - checkClosed(); - ResultInterface result = command.getMetaData(); - if (result == null) { - return null; - } - int id = getNextId(TraceObject.RESULT_SET_META_DATA); - if (isDebugEnabled()) { - debugCodeAssign("ResultSetMetaData", TraceObject.RESULT_SET_META_DATA, id, "getMetaData()"); - } - String catalog = conn.getCatalog(); - JdbcResultSetMetaData meta = new JdbcResultSetMetaData(null, this, result, catalog, session.getTrace(), id); - return meta; - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Clears the batch. - */ - public void clearBatch() throws SQLException { - try { - debugCodeCall("clearBatch"); - checkClosed(); - batchParameters = null; - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Closes this statement. - * All result sets that where created by this statement - * become invalid after calling this method. - */ - public void close() throws SQLException { - try { - super.close(); - batchParameters = null; - if (command != null) { - command.close(); - command = null; - } - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Executes the batch. - * - * @return the array of update counts - */ - public int[] executeBatch() throws SQLException { - try { - debugCodeCall("executeBatch"); - if (batchParameters == null) { - // TODO batch: check what other database do if no parameters are set - batchParameters = New.arrayList(); - } - int[] result = new int[batchParameters.size()]; - boolean error = false; - SQLException next = null; - checkClosedForWrite(); - try { - for (int i = 0; i < batchParameters.size(); i++) { - Value[] set = batchParameters.get(i); - ArrayList< ? extends ParameterInterface> parameters = command.getParameters(); - for (int j = 0; j < set.length; j++) { - Value value = set[j]; - ParameterInterface param = parameters.get(j); - param.setValue(value, false); - } - try { - result[i] = executeUpdateInternal(); - } catch (Exception re) { - SQLException e = DbException.toSQLException(re); - if (next == null) { - next = e; - } else { - e.setNextException(next); - next = e; - } - logAndConvert(e); - //## Java 1.4 begin ## - result[i] = Statement.EXECUTE_FAILED; - //## Java 1.4 end ## - error = true; - } - } - batchParameters = null; - if (error) { - JdbcBatchUpdateException e = new JdbcBatchUpdateException(next, result); - e.setNextException(next); - throw e; - } - return result; - } finally { - afterWriting(); - } - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Adds the current settings to the batch. - */ - public void addBatch() throws SQLException { - try { - debugCodeCall("addBatch"); - checkClosedForWrite(); - try { - ArrayList< ? extends ParameterInterface> parameters = command.getParameters(); - Value[] set = new Value[parameters.size()]; - for (int i = 0; i < parameters.size(); i++) { - ParameterInterface param = parameters.get(i); - Value value = param.getParamValue(); - set[i] = value; - } - if (batchParameters == null) { - batchParameters = New.arrayList(); - } - batchParameters.add(set); - } finally { - afterWriting(); - } - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Calling this method is not legal on a PreparedStatement. - * - * @throws SQLException Unsupported Feature - */ - public int executeUpdate(String sql, int autoGeneratedKeys) throws SQLException { - try { - debugCode("executeUpdate("+quote(sql)+", "+autoGeneratedKeys+");"); - throw DbException.get(ErrorCode.METHOD_NOT_ALLOWED_FOR_PREPARED_STATEMENT); - } catch (Exception e) { - throw logAndConvert(e); - } - } - - - /** - * Calling this method is not legal on a PreparedStatement. - * - * @throws SQLException Unsupported Feature - */ - public int executeUpdate(String sql, int[] columnIndexes) throws SQLException { - try { - debugCode("executeUpdate(" + quote(sql) + ", " + quoteIntArray(columnIndexes) + ");"); - throw DbException.get(ErrorCode.METHOD_NOT_ALLOWED_FOR_PREPARED_STATEMENT); - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Calling this method is not legal on a PreparedStatement. - * - * @throws SQLException Unsupported Feature - */ - public int executeUpdate(String sql, String[] columnNames) throws SQLException { - try { - debugCode("executeUpdate(" + quote(sql) + ", " + quoteArray(columnNames) + ");"); - throw DbException.get(ErrorCode.METHOD_NOT_ALLOWED_FOR_PREPARED_STATEMENT); - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Calling this method is not legal on a PreparedStatement. - * - * @throws SQLException Unsupported Feature - */ - public boolean execute(String sql, int autoGeneratedKeys) throws SQLException { - try { - debugCode("execute(" + quote(sql) + ", " + autoGeneratedKeys + ");"); - throw DbException.get(ErrorCode.METHOD_NOT_ALLOWED_FOR_PREPARED_STATEMENT); - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Calling this method is not legal on a PreparedStatement. - * - * @throws SQLException Unsupported Feature - */ - public boolean execute(String sql, int[] columnIndexes) throws SQLException { - try { - debugCode("execute(" + quote(sql) + ", " + quoteIntArray(columnIndexes) + ");"); - throw DbException.get(ErrorCode.METHOD_NOT_ALLOWED_FOR_PREPARED_STATEMENT); - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Calling this method is not legal on a PreparedStatement. - * - * @throws SQLException Unsupported Feature - */ - public boolean execute(String sql, String[] columnNames) throws SQLException { - try { - debugCode("execute(" + quote(sql) + ", " + quoteArray(columnNames) + ");"); - throw DbException.get(ErrorCode.METHOD_NOT_ALLOWED_FOR_PREPARED_STATEMENT); - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Get the parameter meta data of this prepared statement. - * - * @return the meta data - */ -//## Java 1.4 begin ## - public ParameterMetaData getParameterMetaData() throws SQLException { - try { - int id = getNextId(TraceObject.PARAMETER_META_DATA); - if (isDebugEnabled()) { - debugCodeAssign("ParameterMetaData", TraceObject.PARAMETER_META_DATA, id, "getParameterMetaData()"); - } - checkClosed(); - JdbcParameterMetaData meta = new JdbcParameterMetaData(session.getTrace(), this, command, id); - return meta; - } catch (Exception e) { - throw logAndConvert(e); - } - } -//## Java 1.4 end ## - - // ============================================================= - - private void setParameter(int parameterIndex, Value value) throws SQLException { - checkClosed(); - parameterIndex--; - ArrayList< ? extends ParameterInterface> parameters = command.getParameters(); - if (parameterIndex < 0 || parameterIndex >= parameters.size()) { - throw DbException.getInvalidValueException("" + (parameterIndex + 1), "parameterIndex"); - } - ParameterInterface param = parameters.get(parameterIndex); - // can only delete old temp files if they are not in the batch - param.setValue(value, batchParameters == null); - } - - /** - * [Not supported] Sets the value of a parameter as a row id. - */ -/*## Java 1.6 begin ## - public void setRowId(int parameterIndex, RowId x) throws SQLException { - throw unsupported("rowId"); - } -## Java 1.6 end ##*/ - - /** - * Sets the value of a parameter. - * - * @param parameterIndex the parameter index (1, 2, ...) - * @param x the value - * @throws SQLException if this object is closed - */ -/*## Java 1.6 begin ## - public void setNString(int parameterIndex, String x) throws SQLException { - try { - if (isDebugEnabled()) { - debugCode("setNString("+parameterIndex+", "+quote(x)+");"); - } - Value v = x == null ? (Value) ValueNull.INSTANCE : ValueString.get(x); - setParameter(parameterIndex, v); - } catch (Exception e) { - throw logAndConvert(e); - } - } -## Java 1.6 end ##*/ - - /** - * Sets the value of a parameter as a character stream. - * This method does not close the reader. - * The reader may be closed after executing the statement. - * - * @param parameterIndex the parameter index (1, 2, ...) - * @param x the value - * @param length the number of bytes - * @throws SQLException if this object is closed - */ -/*## Java 1.6 begin ## - public void setNCharacterStream(int parameterIndex, Reader x, long length) - throws SQLException { - try { - if (isDebugEnabled()) { - debugCode("setNCharacterStream("+ - parameterIndex+", x, "+length+"L);"); - } - checkClosedForWrite(); - try { - Value v = conn.createClob(x, length); - setParameter(parameterIndex, v); - } finally { - afterWriting(); - } - } catch (Exception e) { - throw logAndConvert(e); - } - } -## Java 1.6 end ##*/ - - /** - * Sets the value of a parameter as a character stream. - * This method does not close the reader. - * The reader may be closed after executing the statement. - * - * @param parameterIndex the parameter index (1, 2, ...) - * @param x the value - * @throws SQLException if this object is closed - */ -/*## Java 1.6 begin ## - public void setNCharacterStream(int parameterIndex, Reader x) - throws SQLException { - setNCharacterStream(parameterIndex, x, -1); - } -## Java 1.6 end ##*/ - - /** - * Sets the value of a parameter as a Clob. - * - * @param parameterIndex the parameter index (1, 2, ...) - * @param x the value - * @throws SQLException if this object is closed - */ -/*## Java 1.6 begin ## - public void setNClob(int parameterIndex, NClob x) throws SQLException { - try { - if (isDebugEnabled()) { - debugCode("setNClob("+parameterIndex+", x);"); - } - checkClosedForWrite(); - Value v; - if (x == null) { - v = ValueNull.INSTANCE; - } else { - v = conn.createClob(x.getCharacterStream(), -1); - } - setParameter(parameterIndex, v); - } catch (Exception e) { - throw logAndConvert(e); - } - } -## Java 1.6 end ##*/ - - /** - * Sets the value of a parameter as a Clob. - * This method does not close the reader. - * The reader may be closed after executing the statement. - * - * @param parameterIndex the parameter index (1, 2, ...) - * @param x the value - * @throws SQLException if this object is closed - */ -/*## Java 1.6 begin ## - public void setNClob(int parameterIndex, Reader x) throws SQLException { - try { - if (isDebugEnabled()) { - debugCode("setNClob("+parameterIndex+", x);"); - } - checkClosedForWrite(); - try { - Value v = conn.createClob(x, -1); - setParameter(parameterIndex, v); - } finally { - afterWriting(); - } - } catch (Exception e) { - throw logAndConvert(e); - } - } -## Java 1.6 end ##*/ - - /** - * Sets the value of a parameter as a Clob. - * This method does not close the reader. - * The reader may be closed after executing the statement. - * - * @param parameterIndex the parameter index (1, 2, ...) - * @param x the value - * @throws SQLException if this object is closed - */ - public void setClob(int parameterIndex, Reader x, long length) throws SQLException { - try { - if (isDebugEnabled()) { - debugCode("setClob("+parameterIndex+", x, "+length+"L);"); - } - checkClosedForWrite(); - try { - Value v = conn.createClob(x, length); - setParameter(parameterIndex, v); - } finally { - afterWriting(); - } - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Sets the value of a parameter as a Blob. - * This method does not close the stream. - * The stream may be closed after executing the statement. - * - * @param parameterIndex the parameter index (1, 2, ...) - * @param x the value - * @throws SQLException if this object is closed - */ - public void setBlob(int parameterIndex, InputStream x, long length) throws SQLException { - try { - if (isDebugEnabled()) { - debugCode("setBlob("+parameterIndex+", x, "+length+"L);"); - } - checkClosedForWrite(); - try { - Value v = conn.createBlob(x, length); - setParameter(parameterIndex, v); - } finally { - afterWriting(); - } - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Sets the value of a parameter as a Clob. - * This method does not close the reader. - * The reader may be closed after executing the statement. - * - * @param parameterIndex the parameter index (1, 2, ...) - * @param x the value - * @throws SQLException if this object is closed - */ -/*## Java 1.6 begin ## - public void setNClob(int parameterIndex, Reader x, long length) - throws SQLException { - try { - if (isDebugEnabled()) { - debugCode("setNClob("+parameterIndex+", x, "+length+"L);"); - } - checkClosedForWrite(); - try { - Value v = conn.createClob(x, length); - setParameter(parameterIndex, v); - } finally { - afterWriting(); - } - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * [Not supported] Sets the value of a parameter as a SQLXML object. - */ -/*## Java 1.6 begin ## - public void setSQLXML(int parameterIndex, SQLXML x) throws SQLException { - throw unsupported("SQLXML"); - } -## Java 1.6 end ##*/ - - /** - * INTERNAL - */ - public String toString() { - return getTraceObjectName() + ": " + command; - } - - protected boolean checkClosed(boolean write) throws SQLException { - if (super.checkClosed(write)) { - // if the session was re-connected, re-prepare the statement - ArrayList< ? extends ParameterInterface> oldParams = command.getParameters(); - command = conn.prepareCommand(sqlStatement, fetchSize); - ArrayList< ? extends ParameterInterface> newParams = command.getParameters(); - for (int i = 0; i < oldParams.size(); i++) { - ParameterInterface old = oldParams.get(i); - Value value = old.getParamValue(); - if (value != null) { - ParameterInterface n = newParams.get(i); - n.setValue(value, false); - } - } - return true; - } - return false; - } - -} diff --git a/tools/h2/src/main/org/h2/jdbc/JdbcResultSet.java b/tools/h2/src/main/org/h2/jdbc/JdbcResultSet.java deleted file mode 100755 index 2f766f4..0000000 --- a/tools/h2/src/main/org/h2/jdbc/JdbcResultSet.java +++ /dev/null @@ -1,3460 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.jdbc; - -import java.io.InputStream; -import java.io.Reader; -import java.math.BigDecimal; -import java.net.URL; -import java.sql.Array; -import java.sql.Blob; -import java.sql.Clob; -import java.sql.Date; -import java.sql.Ref; -import java.sql.ResultSet; -import java.sql.ResultSetMetaData; -import java.sql.SQLException; -import java.sql.SQLWarning; -import java.sql.Statement; -import java.sql.Time; -import java.sql.Timestamp; -import java.util.Calendar; -import java.util.HashMap; -import java.util.Map; - -/*## Java 1.6 begin ## -import java.sql.NClob; -import java.sql.RowId; -import java.sql.SQLXML; -## Java 1.6 end ##*/ - -import org.h2.constant.ErrorCode; -import org.h2.constant.SysProperties; -import org.h2.message.DbException; -import org.h2.message.TraceObject; -import org.h2.result.ResultInterface; -import org.h2.result.UpdatableRow; -import org.h2.util.DateTimeUtils; -import org.h2.util.IOUtils; -import org.h2.util.MathUtils; -import org.h2.util.New; -import org.h2.util.StringUtils; -import org.h2.value.CompareMode; -import org.h2.value.DataType; -import org.h2.value.Value; -import org.h2.value.ValueBoolean; -import org.h2.value.ValueByte; -import org.h2.value.ValueBytes; -import org.h2.value.ValueDate; -import org.h2.value.ValueDecimal; -import org.h2.value.ValueDouble; -import org.h2.value.ValueFloat; -import org.h2.value.ValueInt; -import org.h2.value.ValueLong; -import org.h2.value.ValueNull; -import org.h2.value.ValueShort; -import org.h2.value.ValueString; -import org.h2.value.ValueTime; -import org.h2.value.ValueTimestamp; - -/** - *

- * Represents a result set. - *

- *

- * Column labels are case-insensitive, quotes are not supported. The first column - * has the column index 1. - *

- *

- * Updatable result sets: - * Result sets are updatable when the result only contains columns from one - * table, and if it contains all columns of a unique index (primary key or - * other) of this table. Key columns may not contain NULL (because multiple rows - * with NULL could exist). In updatable result sets, own changes are visible, - * but not own inserts and deletes. - *

- */ -public class JdbcResultSet extends TraceObject implements ResultSet { - private final boolean closeStatement; - private final boolean scrollable; - private final boolean updatable; - private ResultInterface result; - private JdbcConnection conn; - private JdbcStatement stat; - private int columnCount; - private boolean wasNull; - private Value[] insertRow; - private Value[] updateRow; - private HashMap columnLabelMap; - private HashMap patchedRows; - - JdbcResultSet(JdbcConnection conn, JdbcStatement stat, ResultInterface result, int id, - boolean closeStatement, boolean scrollable, boolean updatable) { - setTrace(conn.getSession().getTrace(), TraceObject.RESULT_SET, id); - this.conn = conn; - this.stat = stat; - this.result = result; - columnCount = result.getVisibleColumnCount(); - this.closeStatement = closeStatement; - this.scrollable = scrollable; - this.updatable = updatable; - } - - /** - * Moves the cursor to the next row of the result set. - * - * @return true if successful, false if there are no more rows - */ - public boolean next() throws SQLException { - try { - debugCodeCall("next"); - checkClosed(); - return nextRow(); - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Gets the meta data of this result set. - * - * @return the meta data - */ - public ResultSetMetaData getMetaData() throws SQLException { - try { - int id = getNextId(TraceObject.RESULT_SET_META_DATA); - if (isDebugEnabled()) { - debugCodeAssign("ResultSetMetaData", TraceObject.RESULT_SET_META_DATA, id, "getMetaData()"); - } - checkClosed(); - String catalog = conn.getCatalog(); - JdbcResultSetMetaData meta = new JdbcResultSetMetaData(this, null, result, catalog, conn.getSession().getTrace(), id); - return meta; - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Returns whether the last column accessed was a null value. - * - * @return true if the last column accessed was a null value - */ - public boolean wasNull() throws SQLException { - try { - debugCodeCall("wasNull"); - checkClosed(); - return wasNull; - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Searches for a specific column in the result set. A case-insensitive - * search is made. - * - * @param columnLabel the column label - * @return the column index (1,2,...) - * @throws SQLException if the column is not found or if the result set is - * closed - */ - public int findColumn(String columnLabel) throws SQLException { - try { - debugCodeCall("findColumn", columnLabel); - return getColumnIndex(columnLabel); - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Closes the result set. - */ - public void close() throws SQLException { - try { - debugCodeCall("close"); - closeInternal(); - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Close the result set. This method also closes the statement if required. - */ - void closeInternal() throws SQLException { - if (result != null) { - try { - result.close(); - if (closeStatement && stat != null) { - stat.close(); - } - } finally { - columnCount = 0; - result = null; - stat = null; - conn = null; - insertRow = null; - updateRow = null; - } - } - } - - /** - * Returns the statement that created this object. - * - * @return the statement or prepared statement, or null if created by a - * DatabaseMetaData call. - */ - public Statement getStatement() throws SQLException { - try { - debugCodeCall("getStatement"); - checkClosed(); - if (closeStatement) { - // if the result set was opened by a DatabaseMetaData call - return null; - } - return stat; - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Gets the first warning reported by calls on this object. - * - * @return null - */ - public SQLWarning getWarnings() throws SQLException { - try { - debugCodeCall("getWarnings"); - checkClosed(); - return null; - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Clears all warnings. - */ - public void clearWarnings() throws SQLException { - try { - debugCodeCall("clearWarnings"); - checkClosed(); - } catch (Exception e) { - throw logAndConvert(e); - } - } - - // ============================================================= - - /** - * Returns the value of the specified column as a String. - * - * @param columnIndex (1,2,...) - * @return the value - * @throws SQLException if the column is not found or if the result set is closed - */ - public String getString(int columnIndex) throws SQLException { - try { - debugCodeCall("getString", columnIndex); - return get(columnIndex).getString(); - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Returns the value of the specified column as a String. - * - * @param columnLabel the column label - * @return the value - * @throws SQLException if the column is not found or if the result set is closed - */ - public String getString(String columnLabel) throws SQLException { - try { - debugCodeCall("getString", columnLabel); - return get(columnLabel).getString(); - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Returns the value of the specified column as an int. - * - * @param columnIndex (1,2,...) - * @return the value - * @throws SQLException if the column is not found or if the result set is closed - */ - public int getInt(int columnIndex) throws SQLException { - try { - debugCodeCall("getInt", columnIndex); - return get(columnIndex).getInt(); - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Returns the value of the specified column as an int. - * - * @param columnLabel the column label - * @return the value - * @throws SQLException if the column is not found or if the result set is closed - */ - public int getInt(String columnLabel) throws SQLException { - try { - debugCodeCall("getInt", columnLabel); - return get(columnLabel).getInt(); - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Returns the value of the specified column as a String. - * - * @param columnIndex (1,2,...) - * @return the value - * @throws SQLException if the column is not found or if the result set is closed - */ - public BigDecimal getBigDecimal(int columnIndex) throws SQLException { - try { - debugCodeCall("getBigDecimal", columnIndex); - return get(columnIndex).getBigDecimal(); - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Returns the value of the specified column as a java.sql.Date. - * - * @param columnIndex (1,2,...) - * @return the value - * @throws SQLException if the column is not found or if the result set is closed - */ - public Date getDate(int columnIndex) throws SQLException { - try { - debugCodeCall("getDate", columnIndex); - return get(columnIndex).getDate(); - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Returns the value of the specified column as a java.sql.Time. - * - * @param columnIndex (1,2,...) - * @return the value - * @throws SQLException if the column is not found or if the result set is closed - */ - public Time getTime(int columnIndex) throws SQLException { - try { - debugCodeCall("getTime", columnIndex); - return get(columnIndex).getTime(); - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Returns the value of the specified column as a java.sql.Timestamp. - * - * @param columnIndex (1,2,...) - * @return the value - * @throws SQLException if the column is not found or if the result set is closed - */ - public Timestamp getTimestamp(int columnIndex) throws SQLException { - try { - debugCodeCall("getTimestamp", columnIndex); - return get(columnIndex).getTimestamp(); - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Returns the value of the specified column as a String. - * - * @param columnLabel the column label - * @return the value - * @throws SQLException if the column is not found or if the result set is closed - */ - public BigDecimal getBigDecimal(String columnLabel) throws SQLException { - try { - debugCodeCall("getBigDecimal", columnLabel); - return get(columnLabel).getBigDecimal(); - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Returns the value of the specified column as a java.sql.Date. - * - * @param columnLabel the column label - * @return the value - * @throws SQLException if the column is not found or if the result set is closed - */ - public Date getDate(String columnLabel) throws SQLException { - try { - debugCodeCall("getDate", columnLabel); - return get(columnLabel).getDate(); - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Returns the value of the specified column as a java.sql.Time. - * - * @param columnLabel the column label - * @return the value - * @throws SQLException if the column is not found or if the result set is closed - */ - public Time getTime(String columnLabel) throws SQLException { - try { - debugCodeCall("getTime", columnLabel); - return get(columnLabel).getTime(); - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Returns the value of the specified column as a java.sql.Timestamp. - * - * @param columnLabel the column label - * @return the value - * @throws SQLException if the column is not found or if the result set is closed - */ - public Timestamp getTimestamp(String columnLabel) throws SQLException { - try { - debugCodeCall("getTimestamp", columnLabel); - return get(columnLabel).getTimestamp(); - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Returns a column value as a Java object. For BINARY data, the data is - * de-serialized into a Java Object. - * - * @param columnIndex (1,2,...) - * @return the value or null - * @throws SQLException if the column is not found or if the result set is - * closed - */ - public Object getObject(int columnIndex) throws SQLException { - try { - debugCodeCall("getObject", columnIndex); - Value v = get(columnIndex); - return conn.convertToDefaultObject(v); - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Returns a column value as a Java object. For BINARY data, the data is - * de-serialized into a Java Object. - * - * @param columnLabel the column label - * @return the value or null - * @throws SQLException if the column is not found or if the result set is - * closed - */ - public Object getObject(String columnLabel) throws SQLException { - try { - debugCodeCall("getObject", columnLabel); - Value v = get(columnLabel); - return conn.convertToDefaultObject(v); - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Returns the value of the specified column as a boolean. - * - * @param columnIndex (1,2,...) - * @return the value - * @throws SQLException if the column is not found or if the result set is - * closed - */ - public boolean getBoolean(int columnIndex) throws SQLException { - try { - debugCodeCall("getBoolean", columnIndex); - Boolean v = get(columnIndex).getBoolean(); - return v == null ? false : v.booleanValue(); - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Returns the value of the specified column as a boolean. - * - * @param columnLabel the column label - * @return the value - * @throws SQLException if the column is not found or if the result set is - * closed - */ - public boolean getBoolean(String columnLabel) throws SQLException { - try { - debugCodeCall("getBoolean", columnLabel); - Boolean v = get(columnLabel).getBoolean(); - return v == null ? false : v.booleanValue(); - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Returns the value of the specified column as a byte. - * - * @param columnIndex (1,2,...) - * @return the value - * @throws SQLException if the column is not found or if the result set is - * closed - */ - public byte getByte(int columnIndex) throws SQLException { - try { - debugCodeCall("getByte", columnIndex); - return get(columnIndex).getByte(); - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Returns the value of the specified column as a byte. - * - * @param columnLabel the column label - * @return the value - * @throws SQLException if the column is not found or if the result set is - * closed - */ - public byte getByte(String columnLabel) throws SQLException { - try { - debugCodeCall("getByte", columnLabel); - return get(columnLabel).getByte(); - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Returns the value of the specified column as a short. - * - * @param columnIndex (1,2,...) - * @return the value - * @throws SQLException if the column is not found or if the result set is - * closed - */ - public short getShort(int columnIndex) throws SQLException { - try { - debugCodeCall("getShort", columnIndex); - return get(columnIndex).getShort(); - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Returns the value of the specified column as a short. - * - * @param columnLabel the column label - * @return the value - * @throws SQLException if the column is not found or if the result set is - * closed - */ - public short getShort(String columnLabel) throws SQLException { - try { - debugCodeCall("getShort", columnLabel); - return get(columnLabel).getShort(); - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Returns the value of the specified column as a long. - * - * @param columnIndex (1,2,...) - * @return the value - * @throws SQLException if the column is not found or if the result set is - * closed - */ - public long getLong(int columnIndex) throws SQLException { - try { - debugCodeCall("getLong", columnIndex); - return get(columnIndex).getLong(); - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Returns the value of the specified column as a long. - * - * @param columnLabel the column label - * @return the value - * @throws SQLException if the column is not found or if the result set is - * closed - */ - public long getLong(String columnLabel) throws SQLException { - try { - debugCodeCall("getLong", columnLabel); - return get(columnLabel).getLong(); - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Returns the value of the specified column as a float. - * - * @param columnIndex (1,2,...) - * @return the value - * @throws SQLException if the column is not found or if the result set is - * closed - */ - public float getFloat(int columnIndex) throws SQLException { - try { - debugCodeCall("getFloat", columnIndex); - return get(columnIndex).getFloat(); - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Returns the value of the specified column as a float. - * - * @param columnLabel the column label - * @return the value - * @throws SQLException if the column is not found or if the result set is - * closed - */ - public float getFloat(String columnLabel) throws SQLException { - try { - debugCodeCall("getFloat", columnLabel); - return get(columnLabel).getFloat(); - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Returns the value of the specified column as a double. - * - * @param columnIndex (1,2,...) - * @return the value - * @throws SQLException if the column is not found or if the result set is - * closed - */ - public double getDouble(int columnIndex) throws SQLException { - try { - debugCodeCall("getDouble", columnIndex); - return get(columnIndex).getDouble(); - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Returns the value of the specified column as a double. - * - * @param columnLabel the column label - * @return the value - * @throws SQLException if the column is not found or if the result set is - * closed - */ - public double getDouble(String columnLabel) throws SQLException { - try { - debugCodeCall("getDouble", columnLabel); - return get(columnLabel).getDouble(); - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Returns the value of the specified column as a String. - * - * @deprecated - * - * @param columnLabel the column label - * @return the value - * @throws SQLException if the column is not found or if the result set is - * closed - */ - public BigDecimal getBigDecimal(String columnLabel, int scale) throws SQLException { - try { - if (isDebugEnabled()) { - debugCode("getBigDecimal(" + StringUtils.quoteJavaString(columnLabel)+", "+scale+");"); - } - if (scale < 0) { - throw DbException.getInvalidValueException("" + scale, "scale"); - } - BigDecimal bd = get(columnLabel).getBigDecimal(); - return bd == null ? null : MathUtils.setScale(bd, scale); - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Returns the value of the specified column as a String. - * - * @deprecated - * - * @param columnIndex (1,2,...) - * @return the value - * @throws SQLException if the column is not found or if the result set is - * closed - */ - public BigDecimal getBigDecimal(int columnIndex, int scale) throws SQLException { - try { - if (isDebugEnabled()) { - debugCode("getBigDecimal(" + columnIndex + ", " + scale + ");"); - } - if (scale < 0) { - throw DbException.getInvalidValueException("" + scale, "scale"); - } - BigDecimal bd = get(columnIndex).getBigDecimal(); - return bd == null ? null : MathUtils.setScale(bd, scale); - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * [Not supported] - * @deprecated - */ - public InputStream getUnicodeStream(int columnIndex) throws SQLException { - throw unsupported("unicodeStream"); - } - - /** - * [Not supported] - * @deprecated - */ - public InputStream getUnicodeStream(String columnLabel) throws SQLException { - throw unsupported("unicodeStream"); - } - - /** - * [Not supported] Gets a column as a object using the specified type - * mapping. - */ - public Object getObject(int columnIndex, Map> map) throws SQLException { - throw unsupported("map"); - } - - /** - * [Not supported] Gets a column as a object using the specified type - * mapping. - */ - public Object getObject(String columnLabel, Map> map) throws SQLException { - throw unsupported("map"); - } - - /** - * [Not supported] Gets a column as a reference. - */ - public Ref getRef(int columnIndex) throws SQLException { - throw unsupported("ref"); - } - - /** - * [Not supported] Gets a column as a reference. - */ - public Ref getRef(String columnLabel) throws SQLException { - throw unsupported("ref"); - } - - /** - * Returns the value of the specified column as a java.sql.Date using a - * specified time zone. - * - * @param columnIndex (1,2,...) - * @param calendar the calendar - * @return the value - * @throws SQLException if the column is not found or if the result set is - * closed - */ - public Date getDate(int columnIndex, Calendar calendar) throws SQLException { - try { - if (isDebugEnabled()) { - debugCode("getDate(" + columnIndex + ", calendar)"); - } - Date x = get(columnIndex).getDate(); - return DateTimeUtils.convertDateToCalendar(x, calendar); - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Returns the value of the specified column as a java.sql.Date using a - * specified time zone. - * - * @param columnLabel the column label - * @param calendar the calendar - * @return the value - * @throws SQLException if the column is not found or if the result set is - * closed - */ - public Date getDate(String columnLabel, Calendar calendar) throws SQLException { - try { - if (isDebugEnabled()) { - debugCode("getDate(" + StringUtils.quoteJavaString(columnLabel) + ", calendar)"); - } - Date x = get(columnLabel).getDate(); - return DateTimeUtils.convertDateToCalendar(x, calendar); - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Returns the value of the specified column as a java.sql.Time using a - * specified time zone. - * - * @param columnIndex (1,2,...) - * @param calendar the calendar - * @return the value - * @throws SQLException if the column is not found or if the result set is - * closed - */ - public Time getTime(int columnIndex, Calendar calendar) throws SQLException { - try { - if (isDebugEnabled()) { - debugCode("getTime(" + columnIndex + ", calendar)"); - } - Time x = get(columnIndex).getTime(); - return DateTimeUtils.convertTimeToCalendar(x, calendar); - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Returns the value of the specified column as a java.sql.Time using a - * specified time zone. - * - * @param columnLabel the column label - * @param calendar the calendar - * @return the value - * @throws SQLException if the column is not found or if the result set is - * closed - */ - public Time getTime(String columnLabel, Calendar calendar) throws SQLException { - try { - if (isDebugEnabled()) { - debugCode("getTime(" + StringUtils.quoteJavaString(columnLabel) + ", calendar)"); - } - Time x = get(columnLabel).getTime(); - return DateTimeUtils.convertTimeToCalendar(x, calendar); - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Returns the value of the specified column as a java.sql.Timestamp using a - * specified time zone. - * - * @param columnIndex (1,2,...) - * @param calendar the calendar - * @return the value - * @throws SQLException if the column is not found or if the result set is - * closed - */ - public Timestamp getTimestamp(int columnIndex, Calendar calendar) throws SQLException { - try { - if (isDebugEnabled()) { - debugCode("getTimestamp(" + columnIndex + ", calendar)"); - } - Timestamp x = get(columnIndex).getTimestamp(); - return DateTimeUtils.convertTimestampToCalendar(x, calendar); - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Returns the value of the specified column as a java.sql.Timestamp. - * - * @param columnLabel the column label - * @param calendar the calendar - * @return the value - * @throws SQLException if the column is not found or if the result set is - * closed - */ - public Timestamp getTimestamp(String columnLabel, Calendar calendar) throws SQLException { - try { - if (isDebugEnabled()) { - debugCode("getTimestamp(" + StringUtils.quoteJavaString(columnLabel) + ", calendar)"); - } - Timestamp x = get(columnLabel).getTimestamp(); - return DateTimeUtils.convertTimestampToCalendar(x, calendar); - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Returns the value of the specified column as a Blob. - * - * @param columnIndex (1,2,...) - * @return the value - * @throws SQLException if the column is not found or if the result set is - * closed - */ - public Blob getBlob(int columnIndex) throws SQLException { - try { - int id = getNextId(TraceObject.BLOB); - debugCodeAssign("Blob", TraceObject.BLOB, id, "getBlob(" + columnIndex + ")"); - Value v = get(columnIndex); - return v == ValueNull.INSTANCE ? null : new JdbcBlob(conn, v, id); - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Returns the value of the specified column as a Blob. - * - * @param columnLabel the column label - * @return the value - * @throws SQLException if the column is not found or if the result set is - * closed - */ - public Blob getBlob(String columnLabel) throws SQLException { - try { - int id = getNextId(TraceObject.BLOB); - debugCodeAssign("Blob", TraceObject.BLOB, id, "getBlob(" + quote(columnLabel) + ")"); - Value v = get(columnLabel); - return v == ValueNull.INSTANCE ? null : new JdbcBlob(conn, v, id); - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Returns the value of the specified column as a byte array. - * - * @param columnIndex (1,2,...) - * @return the value - * @throws SQLException if the column is not found or if the result set is - * closed - */ - public byte[] getBytes(int columnIndex) throws SQLException { - try { - debugCodeCall("getBytes", columnIndex); - return get(columnIndex).getBytes(); - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Returns the value of the specified column as a byte array. - * - * @param columnLabel the column label - * @return the value - * @throws SQLException if the column is not found or if the result set is - * closed - */ - public byte[] getBytes(String columnLabel) throws SQLException { - try { - debugCodeCall("getBytes", columnLabel); - return get(columnLabel).getBytes(); - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Returns the value of the specified column as input stream. - * - * @param columnIndex (1,2,...) - * @return the value - * @throws SQLException if the column is not found or if the result set is - * closed - */ - public InputStream getBinaryStream(int columnIndex) throws SQLException { - try { - debugCodeCall("getBinaryStream", columnIndex); - return get(columnIndex).getInputStream(); - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Returns the value of the specified column as input stream. - * - * @param columnLabel the column label - * @return the value - * @throws SQLException if the column is not found or if the result set is - * closed - */ - public InputStream getBinaryStream(String columnLabel) throws SQLException { - try { - debugCodeCall("getBinaryStream", columnLabel); - return get(columnLabel).getInputStream(); - } catch (Exception e) { - throw logAndConvert(e); - } - } - - - /** - * Returns the value of the specified column as a Clob. - * - * @param columnIndex (1,2,...) - * @return the value - * @throws SQLException if the column is not found or if the result set is - * closed - */ - public Clob getClob(int columnIndex) throws SQLException { - try { - int id = getNextId(TraceObject.CLOB); - debugCodeAssign("Clob", TraceObject.CLOB, id, "getClob(" + columnIndex + ")"); - Value v = get(columnIndex); - return v == ValueNull.INSTANCE ? null : new JdbcClob(conn, v, id); - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Returns the value of the specified column as a Clob. - * - * @param columnLabel the column label - * @return the value - * @throws SQLException if the column is not found or if the result set is - * closed - */ - public Clob getClob(String columnLabel) throws SQLException { - try { - int id = getNextId(TraceObject.CLOB); - debugCodeAssign("Clob", TraceObject.CLOB, id, "getClob(" + quote(columnLabel) + ")"); - Value v = get(columnLabel); - return v == ValueNull.INSTANCE ? null : new JdbcClob(conn, v, id); - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Returns the value of the specified column as an Array. - * - * @param columnIndex (1,2,...) - * @return the value - * @throws SQLException if the column is not found or if the result set is - * closed - */ - public Array getArray(int columnIndex) throws SQLException { - try { - int id = getNextId(TraceObject.ARRAY); - debugCodeAssign("Clob", TraceObject.ARRAY, id, "getArray(" + columnIndex + ")"); - Value v = get(columnIndex); - return v == ValueNull.INSTANCE ? null : new JdbcArray(conn, v, id); - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Returns the value of the specified column as an Array. - * - * @param columnLabel the column label - * @return the value - * @throws SQLException if the column is not found or if the result set is - * closed - */ - public Array getArray(String columnLabel) throws SQLException { - try { - int id = getNextId(TraceObject.ARRAY); - debugCodeAssign("Clob", TraceObject.ARRAY, id, "getArray(" + quote(columnLabel) + ")"); - Value v = get(columnLabel); - return v == ValueNull.INSTANCE ? null : new JdbcArray(conn, v, id); - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Returns the value of the specified column as input stream. - * - * @param columnIndex (1,2,...) - * @return the value - * @throws SQLException if the column is not found or if the result set is - * closed - */ - public InputStream getAsciiStream(int columnIndex) throws SQLException { - try { - debugCodeCall("getAsciiStream", columnIndex); - String s = get(columnIndex).getString(); - return s == null ? null : IOUtils.getInputStream(s); - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Returns the value of the specified column as input stream. - * - * @param columnLabel the column label - * @return the value - * @throws SQLException if the column is not found or if the result set is - * closed - */ - public InputStream getAsciiStream(String columnLabel) throws SQLException { - try { - debugCodeCall("getAsciiStream", columnLabel); - String s = get(columnLabel).getString(); - return IOUtils.getInputStream(s); - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Returns the value of the specified column as input stream. - * - * @param columnIndex (1,2,...) - * @return the value - * @throws SQLException if the column is not found or if the result set is - * closed - */ - public Reader getCharacterStream(int columnIndex) throws SQLException { - try { - debugCodeCall("getCharacterStream", columnIndex); - return get(columnIndex).getReader(); - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Returns the value of the specified column as input stream. - * - * @param columnLabel the column label - * @return the value - * @throws SQLException if the column is not found or if the result set is - * closed - */ - public Reader getCharacterStream(String columnLabel) throws SQLException { - try { - debugCodeCall("getCharacterStream", columnLabel); - return get(columnLabel).getReader(); - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * [Not supported] - */ - public URL getURL(int columnIndex) throws SQLException { - throw unsupported("url"); - } - - /** - * [Not supported] - */ - public URL getURL(String columnLabel) throws SQLException { - throw unsupported("url"); - } - - // ============================================================= - - /** - * Updates a column in the current or insert row. - * - * @param columnIndex (1,2,...) - * @throws SQLException if the result set is closed or not updatable - */ - public void updateNull(int columnIndex) throws SQLException { - try { - debugCodeCall("updateNull", columnIndex); - update(columnIndex, ValueNull.INSTANCE); - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Updates a column in the current or insert row. - * - * @param columnLabel the column label - * @throws SQLException if the result set is closed or not updatable - */ - public void updateNull(String columnLabel) throws SQLException { - try { - debugCodeCall("updateNull", columnLabel); - update(columnLabel, ValueNull.INSTANCE); - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Updates a column in the current or insert row. - * - * @param columnIndex (1,2,...) - * @param x the value - * @throws SQLException if the result set is closed or not updatable - */ - public void updateBoolean(int columnIndex, boolean x) throws SQLException { - try { - if (isDebugEnabled()) { - debugCode("updateBoolean("+columnIndex+", "+x+");"); - } - update(columnIndex, ValueBoolean.get(x)); - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Updates a column in the current or insert row. - * - * @param columnLabel the column label - * @param x the value - * @throws SQLException if result set is closed or not updatable - */ - public void updateBoolean(String columnLabel, boolean x) throws SQLException { - try { - if (isDebugEnabled()) { - debugCode("updateBoolean("+quote(columnLabel)+", "+x+");"); - } - update(columnLabel, ValueBoolean.get(x)); - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Updates a column in the current or insert row. - * - * @param columnIndex (1,2,...) - * @param x the value - * @throws SQLException if the result set is closed or not updatable - */ - public void updateByte(int columnIndex, byte x) throws SQLException { - try { - if (isDebugEnabled()) { - debugCode("updateByte("+columnIndex+", "+x+");"); - } - update(columnIndex, ValueByte.get(x)); - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Updates a column in the current or insert row. - * - * @param columnLabel the column label - * @param x the value - * @throws SQLException if the result set is closed or not updatable - */ - public void updateByte(String columnLabel, byte x) throws SQLException { - try { - if (isDebugEnabled()) { - debugCode("updateByte("+columnLabel+", "+x+");"); - } - update(columnLabel, ValueByte.get(x)); - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Updates a column in the current or insert row. - * - * @param columnIndex (1,2,...) - * @param x the value - * @throws SQLException if the result set is closed or not updatable - */ - public void updateBytes(int columnIndex, byte[] x) throws SQLException { - try { - if (isDebugEnabled()) { - debugCode("updateBytes("+columnIndex+", x);"); - } - update(columnIndex, x == null ? (Value) ValueNull.INSTANCE : ValueBytes.get(x)); - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Updates a column in the current or insert row. - * - * @param columnLabel the column label - * @param x the value - * @throws SQLException if the result set is closed or not updatable - */ - public void updateBytes(String columnLabel, byte[] x) throws SQLException { - try { - if (isDebugEnabled()) { - debugCode("updateBytes("+quote(columnLabel)+", x);"); - } - update(columnLabel, x == null ? (Value) ValueNull.INSTANCE : ValueBytes.get(x)); - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Updates a column in the current or insert row. - * - * @param columnIndex (1,2,...) - * @param x the value - * @throws SQLException if the result set is closed or not updatable - */ - public void updateShort(int columnIndex, short x) throws SQLException { - try { - if (isDebugEnabled()) { - debugCode("updateShort("+columnIndex+", (short) "+x+");"); - } - update(columnIndex, ValueShort.get(x)); - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Updates a column in the current or insert row. - * - * @param columnLabel the column label - * @param x the value - * @throws SQLException if the result set is closed or not updatable - */ - public void updateShort(String columnLabel, short x) throws SQLException { - try { - if (isDebugEnabled()) { - debugCode("updateShort("+quote(columnLabel)+", (short) "+x+");"); - } - update(columnLabel, ValueShort.get(x)); - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Updates a column in the current or insert row. - * - * @param columnIndex (1,2,...) - * @param x the value - * @throws SQLException if the result set is closed or not updatable - */ - public void updateInt(int columnIndex, int x) throws SQLException { - try { - if (isDebugEnabled()) { - debugCode("updateInt("+columnIndex+", "+x+");"); - } - update(columnIndex, ValueInt.get(x)); - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Updates a column in the current or insert row. - * - * @param columnLabel the column label - * @param x the value - * @throws SQLException if the result set is closed or not updatable - */ - public void updateInt(String columnLabel, int x) throws SQLException { - try { - if (isDebugEnabled()) { - debugCode("updateInt("+quote(columnLabel)+", "+x+");"); - } - update(columnLabel, ValueInt.get(x)); - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Updates a column in the current or insert row. - * - * @param columnIndex (1,2,...) - * @param x the value - * @throws SQLException if the result set is closed or not updatable - */ - public void updateLong(int columnIndex, long x) throws SQLException { - try { - if (isDebugEnabled()) { - debugCode("updateLong("+columnIndex+", "+x+"L);"); - } - update(columnIndex, ValueLong.get(x)); - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Updates a column in the current or insert row. - * - * @param columnLabel the column label - * @param x the value - * @throws SQLException if the result set is closed or not updatable - */ - public void updateLong(String columnLabel, long x) throws SQLException { - try { - if (isDebugEnabled()) { - debugCode("updateLong("+quote(columnLabel)+", "+x+"L);"); - } - update(columnLabel, ValueLong.get(x)); - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Updates a column in the current or insert row. - * - * @param columnIndex (1,2,...) - * @param x the value - * @throws SQLException if the result set is closed or not updatable - */ - public void updateFloat(int columnIndex, float x) throws SQLException { - try { - if (isDebugEnabled()) { - debugCode("updateFloat("+columnIndex+", "+x+"f);"); - } - update(columnIndex, ValueFloat.get(x)); - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Updates a column in the current or insert row. - * - * @param columnLabel the column label - * @param x the value - * @throws SQLException if the result set is closed or not updatable - */ - public void updateFloat(String columnLabel, float x) throws SQLException { - try { - if (isDebugEnabled()) { - debugCode("updateFloat("+quote(columnLabel)+", "+x+"f);"); - } - update(columnLabel, ValueFloat.get(x)); - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Updates a column in the current or insert row. - * - * @param columnIndex (1,2,...) - * @param x the value - * @throws SQLException if the result set is closed or not updatable - */ - public void updateDouble(int columnIndex, double x) throws SQLException { - try { - if (isDebugEnabled()) { - debugCode("updateDouble("+columnIndex+", "+x+"d);"); - } - update(columnIndex, ValueDouble.get(x)); - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Updates a column in the current or insert row. - * - * @param columnLabel the column label - * @param x the value - * @throws SQLException if the result set is closed or not updatable - */ - public void updateDouble(String columnLabel, double x) throws SQLException { - try { - if (isDebugEnabled()) { - debugCode("updateDouble("+quote(columnLabel)+", "+x+"d);"); - } - update(columnLabel, ValueDouble.get(x)); - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Updates a column in the current or insert row. - * - * @param columnIndex (1,2,...) - * @param x the value - * @throws SQLException if the result set is closed or not updatable - */ - public void updateBigDecimal(int columnIndex, BigDecimal x) throws SQLException { - try { - if (isDebugEnabled()) { - debugCode("updateBigDecimal("+columnIndex+", " + quoteBigDecimal(x) + ");"); - } - update(columnIndex, x == null ? (Value) ValueNull.INSTANCE : ValueDecimal.get(x)); - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Updates a column in the current or insert row. - * - * @param columnLabel the column label - * @param x the value - * @throws SQLException if the result set is closed or not updatable - */ - public void updateBigDecimal(String columnLabel, BigDecimal x) throws SQLException { - try { - if (isDebugEnabled()) { - debugCode("updateBigDecimal("+quote(columnLabel)+", " + quoteBigDecimal(x) + ");"); - } - update(columnLabel, x == null ? (Value) ValueNull.INSTANCE : ValueDecimal.get(x)); - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Updates a column in the current or insert row. - * - * @param columnIndex (1,2,...) - * @param x the value - * @throws SQLException if the result set is closed or not updatable - */ - public void updateString(int columnIndex, String x) throws SQLException { - try { - if (isDebugEnabled()) { - debugCode("updateString("+columnIndex+", "+quote(x)+");"); - } - update(columnIndex, x == null ? (Value) ValueNull.INSTANCE : ValueString.get(x)); - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Updates a column in the current or insert row. - * - * @param columnLabel the column label - * @param x the value - * @throws SQLException if the result set is closed or not updatable - */ - public void updateString(String columnLabel, String x) throws SQLException { - try { - if (isDebugEnabled()) { - debugCode("updateString("+quote(columnLabel)+", "+quote(x)+");"); - } - update(columnLabel, x == null ? (Value) ValueNull.INSTANCE : ValueString.get(x)); - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Updates a column in the current or insert row. - * - * @param columnIndex (1,2,...) - * @param x the value - * @throws SQLException if the result set is closed or not updatable - */ - public void updateDate(int columnIndex, Date x) throws SQLException { - try { - if (isDebugEnabled()) { - debugCode("updateDate("+columnIndex+", x);"); - } - update(columnIndex, x == null ? (Value) ValueNull.INSTANCE : ValueDate.get(x)); - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Updates a column in the current or insert row. - * - * @param columnLabel the column label - * @param x the value - * @throws SQLException if the result set is closed or not updatable - */ - public void updateDate(String columnLabel, Date x) throws SQLException { - try { - if (isDebugEnabled()) { - debugCode("updateDate("+quote(columnLabel)+", x);"); - } - update(columnLabel, x == null ? (Value) ValueNull.INSTANCE : ValueDate.get(x)); - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Updates a column in the current or insert row. - * - * @param columnIndex (1,2,...) - * @param x the value - * @throws SQLException if the result set is closed or not updatable - */ - public void updateTime(int columnIndex, Time x) throws SQLException { - try { - if (isDebugEnabled()) { - debugCode("updateTime("+columnIndex+", x);"); - } - update(columnIndex, x == null ? (Value) ValueNull.INSTANCE : ValueTime.get(x)); - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Updates a column in the current or insert row. - * - * @param columnLabel the column label - * @param x the value - * @throws SQLException if the result set is closed or not updatable - */ - public void updateTime(String columnLabel, Time x) throws SQLException { - try { - if (isDebugEnabled()) { - debugCode("updateTime("+quote(columnLabel)+", x);"); - } - update(columnLabel, x == null ? (Value) ValueNull.INSTANCE : ValueTime.get(x)); - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Updates a column in the current or insert row. - * - * @param columnIndex (1,2,...) - * @param x the value - * @throws SQLException if the result set is closed or not updatable - */ - public void updateTimestamp(int columnIndex, Timestamp x) throws SQLException { - try { - if (isDebugEnabled()) { - debugCode("updateTimestamp("+columnIndex+", x);"); - } - update(columnIndex, x == null ? (Value) ValueNull.INSTANCE : ValueTimestamp.get(x)); - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Updates a column in the current or insert row. - * - * @param columnLabel the column label - * @param x the value - * @throws SQLException if the result set is closed or not updatable - */ - public void updateTimestamp(String columnLabel, Timestamp x) throws SQLException { - try { - if (isDebugEnabled()) { - debugCode("updateTimestamp("+quote(columnLabel)+", x);"); - } - update(columnLabel, x == null ? (Value) ValueNull.INSTANCE : ValueTimestamp.get(x)); - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Updates a column in the current or insert row. - * - * @param columnIndex (1,2,...) - * @param x the value - * @param length the number of characters - * @throws SQLException if the result set is closed or not updatable - */ - public void updateAsciiStream(int columnIndex, InputStream x, int length) throws SQLException { - updateAsciiStream(columnIndex, x, (long) length); - } - - /** - * Updates a column in the current or insert row. - * - * @param columnIndex (1,2,...) - * @param x the value - * @throws SQLException if the result set is closed or not updatable - */ - public void updateAsciiStream(int columnIndex, InputStream x) throws SQLException { - updateAsciiStream(columnIndex, x, -1); - } - - /** - * Updates a column in the current or insert row. - * - * @param columnIndex (1,2,...) - * @param x the value - * @param length the number of characters - * @throws SQLException if the result set is closed or not updatable - */ - public void updateAsciiStream(int columnIndex, InputStream x, long length) throws SQLException { - try { - if (isDebugEnabled()) { - debugCode("updateAsciiStream("+columnIndex+", x, "+length+"L);"); - } - checkClosed(); - Value v = conn.createClob(IOUtils.getAsciiReader(x), length); - update(columnIndex, v); - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Updates a column in the current or insert row. - * - * @param columnLabel the column label - * @param x the value - * @param length the number of characters - * @throws SQLException if the result set is closed or not updatable - */ - public void updateAsciiStream(String columnLabel, InputStream x, int length) throws SQLException { - updateAsciiStream(columnLabel, x, (long) length); - } - - /** - * Updates a column in the current or insert row. - * - * @param columnLabel the column label - * @param x the value - * @throws SQLException if the result set is closed - */ - public void updateAsciiStream(String columnLabel, InputStream x) throws SQLException { - updateAsciiStream(columnLabel, x, -1); - } - - /** - * Updates a column in the current or insert row. - * - * @param columnLabel the column label - * @param x the value - * @param length the number of characters - * @throws SQLException if the result set is closed or not updatable - */ - public void updateAsciiStream(String columnLabel, InputStream x, long length) throws SQLException { - try { - if (isDebugEnabled()) { - debugCode("updateAsciiStream("+quote(columnLabel)+", x, "+length+"L);"); - } - checkClosed(); - Value v = conn.createClob(IOUtils.getAsciiReader(x), length); - update(columnLabel, v); - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Updates a column in the current or insert row. - * - * @param columnIndex (1,2,...) - * @param x the value - * @param length the number of characters - * @throws SQLException if the result set is closed or not updatable - */ - public void updateBinaryStream(int columnIndex, InputStream x, int length) throws SQLException { - updateBinaryStream(columnIndex, x, (long) length); - } - - /** - * Updates a column in the current or insert row. - * - * @param columnIndex (1,2,...) - * @param x the value - * @throws SQLException if the result set is closed or not updatable - */ - public void updateBinaryStream(int columnIndex, InputStream x) throws SQLException { - updateBinaryStream(columnIndex, x, -1); - } - - /** - * Updates a column in the current or insert row. - * - * @param columnIndex (1,2,...) - * @param x the value - * @param length the number of characters - * @throws SQLException if the result set is closed or not updatable - */ - public void updateBinaryStream(int columnIndex, InputStream x, long length) throws SQLException { - try { - if (isDebugEnabled()) { - debugCode("updateBinaryStream("+columnIndex+", x, "+length+"L);"); - } - checkClosed(); - Value v = conn.createBlob(x, length); - update(columnIndex, v); - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Updates a column in the current or insert row. - * - * @param columnLabel the column label - * @param x the value - * @throws SQLException if the result set is closed or not updatable - */ - public void updateBinaryStream(String columnLabel, InputStream x) throws SQLException { - updateBinaryStream(columnLabel, x, -1); - } - - /** - * Updates a column in the current or insert row. - * - * @param columnLabel the column label - * @param x the value - * @param length the number of characters - * @throws SQLException if the result set is closed or not updatable - */ - public void updateBinaryStream(String columnLabel, InputStream x, int length) throws SQLException { - updateBinaryStream(columnLabel, x, (long) length); - } - - /** - * Updates a column in the current or insert row. - * - * @param columnLabel the column label - * @param x the value - * @param length the number of characters - * @throws SQLException if the result set is closed or not updatable - */ - public void updateBinaryStream(String columnLabel, InputStream x, long length) throws SQLException { - try { - if (isDebugEnabled()) { - debugCode("updateBinaryStream("+quote(columnLabel)+", x, "+length+"L);"); - } - checkClosed(); - Value v = conn.createBlob(x, length); - update(columnLabel, v); - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Updates a column in the current or insert row. - * - * @param columnIndex (1,2,...) - * @param x the value - * @param length the number of characters - * @throws SQLException if the result set is closed or not updatable - */ - public void updateCharacterStream(int columnIndex, Reader x, long length) throws SQLException { - try { - if (isDebugEnabled()) { - debugCode("updateCharacterStream("+columnIndex+", x, "+length+"L);"); - } - checkClosed(); - Value v = conn.createClob(x, length); - update(columnIndex, v); - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Updates a column in the current or insert row. - * - * @param columnIndex (1,2,...) - * @param x the value - * @param length the number of characters - * @throws SQLException if the result set is closed or not updatable - */ - public void updateCharacterStream(int columnIndex, Reader x, int length) throws SQLException { - updateCharacterStream(columnIndex, x, (long) length); - } - - /** - * Updates a column in the current or insert row. - * - * @param columnIndex (1,2,...) - * @param x the value - * @throws SQLException if the result set is closed or not updatable - */ - public void updateCharacterStream(int columnIndex, Reader x) throws SQLException { - updateCharacterStream(columnIndex, x, -1); - } - - /** - * Updates a column in the current or insert row. - * - * @param columnLabel the column label - * @param x the value - * @param length the number of characters - * @throws SQLException if the result set is closed or not updatable - */ - public void updateCharacterStream(String columnLabel, Reader x, int length) throws SQLException { - updateCharacterStream(columnLabel, x, (long) length); - } - - /** - * Updates a column in the current or insert row. - * - * @param columnLabel the column label - * @param x the value - * @throws SQLException if the result set is closed or not updatable - */ - public void updateCharacterStream(String columnLabel, Reader x) throws SQLException { - updateCharacterStream(columnLabel, x, -1); - } - - /** - * Updates a column in the current or insert row. - * - * @param columnLabel the column label - * @param x the value - * @param length the number of characters - * @throws SQLException if the result set is closed or not updatable - */ - public void updateCharacterStream(String columnLabel, Reader x, long length) throws SQLException { - try { - if (isDebugEnabled()) { - debugCode("updateCharacterStream("+quote(columnLabel)+", x, "+length+"L);"); - } - checkClosed(); - Value v = conn.createClob(x, length); - update(columnLabel, v); - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Updates a column in the current or insert row. - * - * @param columnIndex (1,2,...) - * @param x the value - * @param scale is ignored - * @throws SQLException if the result set is closed or not updatable - */ - public void updateObject(int columnIndex, Object x, int scale) throws SQLException { - try { - if (isDebugEnabled()) { - debugCode("updateObject("+columnIndex+", x, "+scale+");"); - } - update(columnIndex, convertToUnknownValue(x)); - } catch (Exception e) { - throw logAndConvert(e); - } - } - - - - /** - * Updates a column in the current or insert row. - * - * @param columnLabel the column label - * @param x the value - * @param scale is ignored - * @throws SQLException if the result set is closed or not updatable - */ - public void updateObject(String columnLabel, Object x, int scale) throws SQLException { - try { - if (isDebugEnabled()) { - debugCode("updateObject("+quote(columnLabel)+", x, "+scale+");"); - } - update(columnLabel, convertToUnknownValue(x)); - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Updates a column in the current or insert row. - * - * @param columnIndex (1,2,...) - * @param x the value - * @throws SQLException if the result set is closed or not updatable - */ - public void updateObject(int columnIndex, Object x) throws SQLException { - try { - if (isDebugEnabled()) { - debugCode("updateObject("+columnIndex+", x);"); - } - update(columnIndex, convertToUnknownValue(x)); - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Updates a column in the current or insert row. - * - * @param columnLabel the column label - * @param x the value - * @throws SQLException if the result set is closed or not updatable - */ - public void updateObject(String columnLabel, Object x) throws SQLException { - try { - if (isDebugEnabled()) { - debugCode("updateObject("+quote(columnLabel)+", x);"); - } - update(columnLabel, convertToUnknownValue(x)); - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * [Not supported] - */ - public void updateRef(int columnIndex, Ref x) throws SQLException { - throw unsupported("ref"); - } - - /** - * [Not supported] - */ - public void updateRef(String columnLabel, Ref x) throws SQLException { - throw unsupported("ref"); - } - - /** - * Updates a column in the current or insert row. - * - * @param columnIndex (1,2,...) - * @param x the value - * @throws SQLException if the result set is closed or not updatable - */ - public void updateBlob(int columnIndex, InputStream x) throws SQLException { - updateBlob(columnIndex, x, -1); - } - - /** - * Updates a column in the current or insert row. - * - * @param columnIndex (1,2,...) - * @param x the value - * @param length the length - * @throws SQLException if the result set is closed or not updatable - */ - public void updateBlob(int columnIndex, InputStream x, long length) throws SQLException { - try { - if (isDebugEnabled()) { - debugCode("updateBlob("+columnIndex+", x, " + length + "L);"); - } - checkClosed(); - Value v = conn.createBlob(x, length); - update(columnIndex, v); - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Updates a column in the current or insert row. - * - * @param columnIndex (1,2,...) - * @param x the value - * @throws SQLException if the result set is closed or not updatable - */ - public void updateBlob(int columnIndex, Blob x) throws SQLException { - try { - if (isDebugEnabled()) { - debugCode("updateBlob("+columnIndex+", x);"); - } - checkClosed(); - Value v; - if (x == null) { - v = ValueNull.INSTANCE; - } else { - v = conn.createBlob(x.getBinaryStream(), -1); - } - update(columnIndex, v); - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Updates a column in the current or insert row. - * - * @param columnLabel the column label - * @param x the value - * @throws SQLException if the result set is closed or not updatable - */ - public void updateBlob(String columnLabel, Blob x) throws SQLException { - try { - if (isDebugEnabled()) { - debugCode("updateBlob("+quote(columnLabel)+", x);"); - } - checkClosed(); - Value v; - if (x == null) { - v = ValueNull.INSTANCE; - } else { - v = conn.createBlob(x.getBinaryStream(), -1); - } - update(columnLabel, v); - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Updates a column in the current or insert row. - * - * @param columnLabel the column label - * @param x the value - * @throws SQLException if the result set is closed or not updatable - */ - public void updateBlob(String columnLabel, InputStream x) throws SQLException { - updateBlob(columnLabel, x, -1); - } - - /** - * Updates a column in the current or insert row. - * - * @param columnLabel the column label - * @param x the value - * @param length the length - * @throws SQLException if the result set is closed or not updatable - */ - public void updateBlob(String columnLabel, InputStream x, long length) throws SQLException { - try { - if (isDebugEnabled()) { - debugCode("updateBlob("+quote(columnLabel)+", x, " + length + "L);"); - } - checkClosed(); - Value v = conn.createBlob(x, -1); - update(columnLabel, v); - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Updates a column in the current or insert row. - * - * @param columnIndex (1,2,...) - * @param x the value - * @throws SQLException if the result set is closed or not updatable - */ - public void updateClob(int columnIndex, Clob x) throws SQLException { - try { - if (isDebugEnabled()) { - debugCode("updateClob("+columnIndex+", x);"); - } - checkClosed(); - Value v; - if (x == null) { - v = ValueNull.INSTANCE; - } else { - v = conn.createClob(x.getCharacterStream(), -1); - } - update(columnIndex, v); - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Updates a column in the current or insert row. - * - * @param columnIndex (1,2,...) - * @param x the value - * @throws SQLException if the result set is closed or not updatable - */ - public void updateClob(int columnIndex, Reader x) throws SQLException { - updateClob(columnIndex, x, -1); - } - - /** - * Updates a column in the current or insert row. - * - * @param columnIndex (1,2,...) - * @param x the value - * @param length the length - * @throws SQLException if the result set is closed or not updatable - */ - public void updateClob(int columnIndex, Reader x, long length) throws SQLException { - try { - if (isDebugEnabled()) { - debugCode("updateClob("+columnIndex+", x, " + length + "L);"); - } - checkClosed(); - Value v = conn.createClob(x, length); - update(columnIndex, v); - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Updates a column in the current or insert row. - * - * @param columnLabel the column label - * @param x the value - * @throws SQLException if the result set is closed or not updatable - */ - public void updateClob(String columnLabel, Clob x) throws SQLException { - try { - if (isDebugEnabled()) { - debugCode("updateClob("+quote(columnLabel)+", x);"); - } - checkClosed(); - Value v; - if (x == null) { - v = ValueNull.INSTANCE; - } else { - v = conn.createClob(x.getCharacterStream(), -1); - } - update(columnLabel, v); - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Updates a column in the current or insert row. - * - * @param columnLabel the column label - * @param x the value - * @throws SQLException if the result set is closed or not updatable - */ - public void updateClob(String columnLabel, Reader x) throws SQLException { - updateClob(columnLabel, x, -1); - } - - /** - * Updates a column in the current or insert row. - * - * @param columnLabel the column label - * @param x the value - * @param length the length - * @throws SQLException if the result set is closed or not updatable - */ - public void updateClob(String columnLabel, Reader x, long length) throws SQLException { - try { - if (isDebugEnabled()) { - debugCode("updateClob("+quote(columnLabel)+", x, " + length + "L);"); - } - checkClosed(); - Value v = conn.createClob(x, length); - update(columnLabel, v); - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * [Not supported] - */ - public void updateArray(int columnIndex, Array x) throws SQLException { - throw unsupported("setArray"); - } - - /** - * [Not supported] - */ - public void updateArray(String columnLabel, Array x) throws SQLException { - throw unsupported("setArray"); - } - - /** - * [Not supported] Gets the cursor name if it was defined. This feature is - * superseded by updateX methods. This method throws a SQLException because - * cursor names are not supported. - */ - public String getCursorName() throws SQLException { - throw unsupported("cursorName"); - } - - /** - * Gets the current row number. The first row is row 1, the second 2 and so - * on. This method returns 0 before the first and after the last row. - * - * @return the row number - */ - public int getRow() throws SQLException { - try { - debugCodeCall("getRow"); - checkClosed(); - int rowId = result.getRowId(); - if (rowId >= result.getRowCount()) { - return 0; - } - return rowId + 1; - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Gets the result set concurrency. Result sets are only updatable if the - * statement was created with updatable concurrency, and if the result set - * contains all columns of the primary key or of a unique index of a table. - * - * @return ResultSet.CONCUR_UPDATABLE if the result set is updatable, or - * ResultSet.CONCUR_READ_ONLY otherwise - */ - public int getConcurrency() throws SQLException { - try { - debugCodeCall("getConcurrency"); - checkClosed(); - if (!updatable) { - return ResultSet.CONCUR_READ_ONLY; - } - UpdatableRow row = new UpdatableRow(conn, result); - return row.isUpdatable() ? ResultSet.CONCUR_UPDATABLE : ResultSet.CONCUR_READ_ONLY; - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Gets the fetch direction. - * - * @return the direction: FETCH_FORWARD - */ - public int getFetchDirection() throws SQLException { - try { - debugCodeCall("getFetchDirection"); - checkClosed(); - return ResultSet.FETCH_FORWARD; - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Gets the number of rows suggested to read in one step. - * - * @return the current fetch size - */ - public int getFetchSize() throws SQLException { - try { - debugCodeCall("getFetchSize"); - checkClosed(); - return result.getFetchSize(); - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Sets the number of rows suggested to read in one step. This value cannot - * be higher than the maximum rows (setMaxRows) set by the statement or - * prepared statement, otherwise an exception is throws. Setting the value - * to 0 will set the default value. The default value can be changed using - * the system property h2.serverResultSetFetchSize. - * - * @param rows the number of rows - */ - public void setFetchSize(int rows) throws SQLException { - try { - debugCodeCall("setFetchSize", rows); - checkClosed(); - - if (rows < 0) { - throw DbException.getInvalidValueException("" + rows, "rows"); - } else if (rows > 0) { - if (stat != null) { - int maxRows = stat.getMaxRows(); - if (maxRows > 0 && rows > maxRows) { - throw DbException.getInvalidValueException("" + rows, "rows"); - } - } - } else { - rows = SysProperties.SERVER_RESULT_SET_FETCH_SIZE; - } - result.setFetchSize(rows); - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * [Not supported] - * Sets (changes) the fetch direction for this result set. This method - * should only be called for scrollable result sets, otherwise it will throw - * an exception (no matter what direction is used). - * - * @param direction the new fetch direction - * @throws SQLException Unsupported Feature if the method is called for a - * forward-only result set - */ - public void setFetchDirection(int direction) throws SQLException { - throw unsupported("setFetchDirection"); - } - - /** - * Get the result set type. - * - * @return the result set type (TYPE_FORWARD_ONLY, TYPE_SCROLL_INSENSITIVE - * or TYPE_SCROLL_SENSITIVE) - * @throws SQLException if the column is not found or if the result set is - * closed - */ - public int getType() throws SQLException { - try { - debugCodeCall("getType"); - checkClosed(); - return stat == null ? ResultSet.TYPE_FORWARD_ONLY : stat.resultSetType; - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Checks if the current position is before the first row, that means next() - * was not called yet, and there is at least one row. - * - * @return if there are results and the current position is before the first row - * @throws SQLException if the result set is closed - */ - public boolean isBeforeFirst() throws SQLException { - try { - debugCodeCall("isBeforeFirst"); - checkClosed(); - int row = result.getRowId(); - int count = result.getRowCount(); - return count > 0 && row < 0; - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Checks if the current position is after the last row, that means next() - * was called and returned false, and there was at least one row. - * - * @return if there are results and the current position is after the last row - * @throws SQLException if the result set is closed - */ - public boolean isAfterLast() throws SQLException { - try { - debugCodeCall("isAfterLast"); - checkClosed(); - int row = result.getRowId(); - int count = result.getRowCount(); - return count > 0 && row >= count; - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Checks if the current position is row 1, that means next() was called - * once and returned true. - * - * @return if the current position is the first row - * @throws SQLException if the result set is closed - */ - public boolean isFirst() throws SQLException { - try { - debugCodeCall("isFirst"); - checkClosed(); - int row = result.getRowId(); - return row == 0 && row < result.getRowCount(); - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Checks if the current position is the last row, that means next() was - * called and did not yet returned false, but will in the next call. - * - * @return if the current position is the last row - * @throws SQLException if the result set is closed - */ - public boolean isLast() throws SQLException { - try { - debugCodeCall("isLast"); - checkClosed(); - int row = result.getRowId(); - return row >= 0 && row == result.getRowCount() - 1; - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Moves the current position to before the first row, that means resets the - * result set. - * - * @throws SQLException if the result set is closed - */ - public void beforeFirst() throws SQLException { - try { - debugCodeCall("beforeFirst"); - checkClosed(); - if (result.getRowId() >= 0) { - resetResult(); - } - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Moves the current position to after the last row, that means after the end. - * - * @throws SQLException if the result set is closed - */ - public void afterLast() throws SQLException { - try { - debugCodeCall("afterLast"); - checkClosed(); - while (nextRow()) { - // nothing - } - } catch (Exception e) { - throw logAndConvert(e); - } -} - - /** - * Moves the current position to the first row. This is the same as calling - * beforeFirst() followed by next(). - * - * @return true if there is a row available, false if not - * @throws SQLException if the result set is closed - */ - public boolean first() throws SQLException { - try { - debugCodeCall("first"); - checkClosed(); - if (result.getRowId() < 0) { - return nextRow(); - } - resetResult(); - return nextRow(); - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Moves the current position to the last row. - * - * @return true if there is a row available, false if not - * @throws SQLException if the result set is closed - */ - public boolean last() throws SQLException { - try { - debugCodeCall("last"); - checkClosed(); - return absolute(-1); - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Moves the current position to a specific row. - * - * @param rowNumber the row number. 0 is not allowed, 1 means the first row, - * 2 the second. -1 means the last row, -2 the row before the - * last row. If the value is too large, the position is moved - * after the last row, if if the value is too small it is moved - * before the first row. - * @return true if there is a row available, false if not - * @throws SQLException if the result set is closed - */ - public boolean absolute(int rowNumber) throws SQLException { - try { - debugCodeCall("absolute", rowNumber); - checkClosed(); - if (rowNumber < 0) { - rowNumber = result.getRowCount() + rowNumber + 1; - } else if (rowNumber > result.getRowCount() + 1) { - rowNumber = result.getRowCount() + 1; - } - if (rowNumber <= result.getRowId()) { - resetResult(); - } - while (result.getRowId() + 1 < rowNumber) { - nextRow(); - } - int row = result.getRowId(); - return row >= 0 && row < result.getRowCount(); - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Moves the current position to a specific row relative to the current row. - * - * @param rowCount 0 means don't do anything, 1 is the next row, -1 the - * previous. If the value is too large, the position is moved - * after the last row, if if the value is too small it is moved - * before the first row. - * @return true if there is a row available, false if not - * @throws SQLException if the result set is closed - */ - public boolean relative(int rowCount) throws SQLException { - try { - debugCodeCall("relative", rowCount); - checkClosed(); - int row = result.getRowId() + 1 + rowCount; - if (row < 0) { - row = 0; - } else if (row > result.getRowCount()) { - row = result.getRowCount() + 1; - } - return absolute(row); - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Moves the cursor to the last row, or row before first row if the current - * position is the first row. - * - * @return true if there is a row available, false if not - * @throws SQLException if the result set is closed - */ - public boolean previous() throws SQLException { - try { - debugCodeCall("previous"); - checkClosed(); - return relative(-1); - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Moves the current position to the insert row. The current row is remembered. - * - * @throws SQLException if the result set is closed or is not updatable - */ - public void moveToInsertRow() throws SQLException { - try { - debugCodeCall("moveToInsertRow"); - checkUpdatable(); - insertRow = new Value[columnCount]; - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Moves the current position to the current row. - * - * @throws SQLException if the result set is closed or is not updatable - */ - public void moveToCurrentRow() throws SQLException { - try { - debugCodeCall("moveToCurrentRow"); - checkUpdatable(); - insertRow = null; - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Detects if the row was updated (by somebody else or the caller). - * - * @return false because this driver does not detect this - */ - public boolean rowUpdated() throws SQLException { - try { - debugCodeCall("rowUpdated"); - return false; - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Detects if the row was inserted. - * - * @return false because this driver does not detect this - */ - public boolean rowInserted() throws SQLException { - try { - debugCodeCall("rowInserted"); - return false; - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Detects if the row was deleted (by somebody else or the caller). - * - * @return false because this driver does not detect this - */ - public boolean rowDeleted() throws SQLException { - try { - debugCodeCall("rowDeleted"); - return false; - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Inserts the current row. The current position must be the insert row. - * - * @throws SQLException if the result set is closed or if not on the insert - * row, or if the result set it not updatable - */ - public void insertRow() throws SQLException { - try { - debugCodeCall("insertRow"); - checkUpdatable(); - if (insertRow == null) { - throw DbException.get(ErrorCode.NOT_ON_UPDATABLE_ROW); - } - getUpdatableRow().insertRow(insertRow); - insertRow = null; - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Updates the current row. - * - * @throws SQLException if the result set is closed, if the current row is - * the insert row or if not on a valid row, or if the result set - * it not updatable - */ - public void updateRow() throws SQLException { - try { - debugCodeCall("updateRow"); - checkUpdatable(); - if (insertRow != null) { - throw DbException.get(ErrorCode.NOT_ON_UPDATABLE_ROW); - } - checkOnValidRow(); - if (updateRow != null) { - UpdatableRow row = getUpdatableRow(); - Value[] current = new Value[columnCount]; - for (int i = 0; i < updateRow.length; i++) { - current[i] = get(i + 1); - } - row.updateRow(current, updateRow); - for (int i = 0; i < updateRow.length; i++) { - if (updateRow[i] == null) { - updateRow[i] = current[i]; - } - } - Value[] patch = row.readRow(updateRow); - patchCurrentRow(patch); - updateRow = null; - } - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Deletes the current row. - * - * @throws SQLException if the result set is closed, if the current row is - * the insert row or if not on a valid row, or if the result set - * it not updatable - */ - public void deleteRow() throws SQLException { - try { - debugCodeCall("deleteRow"); - checkUpdatable(); - if (insertRow != null) { - throw DbException.get(ErrorCode.NOT_ON_UPDATABLE_ROW); - } - checkOnValidRow(); - getUpdatableRow().deleteRow(result.currentRow()); - updateRow = null; - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Re-reads the current row from the database. - * - * @throws SQLException if the result set is closed or if the current row is - * the insert row or if the row has been deleted or if not on a - * valid row - */ - public void refreshRow() throws SQLException { - try { - debugCodeCall("refreshRow"); - checkClosed(); - if (insertRow != null) { - throw DbException.get(ErrorCode.NO_DATA_AVAILABLE); - } - checkOnValidRow(); - patchCurrentRow(getUpdatableRow().readRow(result.currentRow())); - updateRow = null; - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Cancels updating a row. - * - * @throws SQLException if the result set is closed or if the current row is - * the insert row - */ - public void cancelRowUpdates() throws SQLException { - try { - debugCodeCall("cancelRowUpdates"); - checkClosed(); - if (insertRow != null) { - throw DbException.get(ErrorCode.NO_DATA_AVAILABLE); - } - updateRow = null; - } catch (Exception e) { - throw logAndConvert(e); - } - } - - // ============================================================= - - private UpdatableRow getUpdatableRow() throws SQLException { - UpdatableRow row = new UpdatableRow(conn, result); - if (!row.isUpdatable()) { - throw DbException.get(ErrorCode.RESULT_SET_NOT_UPDATABLE); - } - return row; - } - - private int getColumnIndex(String columnLabel) throws SQLException { - checkClosed(); - if (columnLabel == null) { - throw DbException.getInvalidValueException("columnLabel", null); - } - if (columnCount >= SysProperties.MIN_COLUMN_NAME_MAP) { - if (columnLabelMap == null) { - HashMap map = New.hashMap(columnCount); - // first column names - for (int i = 0; i < columnCount; i++) { - String colName = result.getColumnName(i); - if (colName != null) { - colName = StringUtils.toUpperEnglish(colName); - map.put(colName, i); - String tabName = result.getTableName(i); - if (tabName != null) { - colName = StringUtils.toUpperEnglish(tabName) + "." + colName; - map.put(colName, i); - } - } - } - // column labels have higher priority - // column names with the same name are replaced - for (int i = 0; i < columnCount; i++) { - String c = StringUtils.toUpperEnglish(result.getAlias(i)); - map.put(c, i); - } - // assign at the end so concurrent access is supported - columnLabelMap = map; - } - Integer index = columnLabelMap.get(StringUtils.toUpperEnglish(columnLabel)); - if (index == null) { - throw DbException.get(ErrorCode.COLUMN_NOT_FOUND_1, columnLabel); - } - return index.intValue() + 1; - } - for (int i = 0; i < columnCount; i++) { - if (columnLabel.equalsIgnoreCase(result.getAlias(i))) { - return i + 1; - } - } - int idx = columnLabel.indexOf('.'); - if (idx > 0) { - String table = columnLabel.substring(0, idx); - String col = columnLabel.substring(idx+1); - for (int i = 0; i < columnCount; i++) { - if (table.equalsIgnoreCase(result.getTableName(i)) && col.equalsIgnoreCase(result.getColumnName(i))) { - return i + 1; - } - } - } else { - for (int i = 0; i < columnCount; i++) { - if (columnLabel.equalsIgnoreCase(result.getColumnName(i))) { - return i + 1; - } - } - } - throw DbException.get(ErrorCode.COLUMN_NOT_FOUND_1, columnLabel); - } - - private void checkColumnIndex(int columnIndex) throws SQLException { - checkClosed(); - if (columnIndex < 1 || columnIndex > columnCount) { - throw DbException.getInvalidValueException("" + columnIndex, "columnIndex"); - } - } - - /** - * Check if this result set is closed. - * - * @throws SQLException if it is closed - */ - void checkClosed() throws SQLException { - if (result == null) { - throw DbException.get(ErrorCode.OBJECT_CLOSED); - } - if (stat != null) { - stat.checkClosed(); - } - if (conn != null) { - conn.checkClosed(); - } - } - - private void checkOnValidRow() { - if (result.getRowId() < 0 || result.getRowId() >= result.getRowCount()) { - throw DbException.get(ErrorCode.NO_DATA_AVAILABLE); - } - } - - private Value get(int columnIndex) throws SQLException { - checkColumnIndex(columnIndex); - checkOnValidRow(); - Value[] list; - if (patchedRows == null) { - list = result.currentRow(); - } else { - list = patchedRows.get(result.getRowId()); - if (list == null) { - list = result.currentRow(); - } - } - Value value = list[columnIndex - 1]; - wasNull = value == ValueNull.INSTANCE; - return value; - } - - private Value get(String columnLabel) throws SQLException { - int columnIndex = getColumnIndex(columnLabel); - return get(columnIndex); - } - - private void update(String columnLabel, Value v) throws SQLException { - int columnIndex = getColumnIndex(columnLabel); - update(columnIndex, v); - } - - private void update(int columnIndex, Value v) throws SQLException { - checkUpdatable(); - checkColumnIndex(columnIndex); - if (insertRow != null) { - insertRow[columnIndex - 1] = v; - } else { - if (updateRow == null) { - updateRow = new Value[columnCount]; - } - updateRow[columnIndex - 1] = v; - } - } - - private boolean nextRow() { - boolean next = result.next(); - if (!next && !scrollable) { - result.close(); - } - return next; - } - - private void resetResult() { - if (!scrollable) { - throw DbException.get(ErrorCode.RESULT_SET_NOT_SCROLLABLE); - } - result.reset(); - } - - /** - * [Not supported] Returns the value of the specified column as a row id. - * - * @param columnIndex (1,2,...) - */ -/*## Java 1.6 begin ## - public RowId getRowId(int columnIndex) throws SQLException { - throw unsupported("rowId"); - } -## Java 1.6 end ##*/ - - /** - * [Not supported] Returns the value of the specified column as a row id. - * - * @param columnLabel the column label - */ -/*## Java 1.6 begin ## - public RowId getRowId(String columnLabel) throws SQLException { - throw unsupported("rowId"); - } -## Java 1.6 end ##*/ - - /** - * [Not supported] Updates a column in the current or insert row. - * - * @param columnIndex (1,2,...) - * @param x the value - */ -/*## Java 1.6 begin ## - public void updateRowId(int columnIndex, RowId x) throws SQLException { - throw unsupported("rowId"); - } -## Java 1.6 end ##*/ - - /** - * [Not supported] Updates a column in the current or insert row. - * - * @param columnLabel the column label - * @param x the value - */ -/*## Java 1.6 begin ## - public void updateRowId(String columnLabel, RowId x) throws SQLException { - throw unsupported("rowId"); - } -## Java 1.6 end ##*/ - - /** - * Returns the current result set holdability. - * - * @return the holdability - * @throws SQLException if the connection is closed - */ - public int getHoldability() throws SQLException { - try { - debugCodeCall("getHoldability"); - checkClosed(); - return conn.getHoldability(); - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Returns whether this result set is closed. - * - * @return true if the result set is closed - */ - public boolean isClosed() throws SQLException { - try { - debugCodeCall("isClosed"); - return result == null; - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Updates a column in the current or insert row. - * - * @param columnIndex (1,2,...) - * @param x the value - * @throws SQLException if the result set is closed or not updatable - */ -/*## Java 1.6 begin ## - public void updateNString(int columnIndex, String x) throws SQLException { - try { - if (isDebugEnabled()) { - debugCode("updateNString("+columnIndex+", "+quote(x)+");"); - } - update(columnIndex, x == null ? (Value) - ValueNull.INSTANCE : ValueString.get(x)); - } catch (Exception e) { - throw logAndConvert(e); - } - } -## Java 1.6 end ##*/ - - /** - * Updates a column in the current or insert row. - * - * @param columnLabel the column label - * @param x the value - * @throws SQLException if the result set is closed or not updatable - */ -/*## Java 1.6 begin ## - public void updateNString(String columnLabel, String x) throws SQLException { - try { - if (isDebugEnabled()) { - debugCode("updateNString("+quote(columnLabel)+", "+quote(x)+");"); - } - update(columnLabel, x == null ? (Value) ValueNull.INSTANCE : - ValueString.get(x)); - } catch (Exception e) { - throw logAndConvert(e); - } - } -## Java 1.6 end ##*/ - - /** - * [Not supported] - */ -/*## Java 1.6 begin ## - public void updateNClob(int columnIndex, NClob x) throws SQLException { - throw unsupported("NClob"); - } -## Java 1.6 end ##*/ - - /** - * [Not supported] - */ -/*## Java 1.6 begin ## - public void updateNClob(int columnIndex, Reader x) throws SQLException { - throw unsupported("NClob"); - } -## Java 1.6 end ##*/ - - /** - * [Not supported] - */ -/*## Java 1.6 begin ## - public void updateNClob(int columnIndex, Reader x, long length) - throws SQLException { - throw unsupported("NClob"); - } -## Java 1.6 end ##*/ - - /** - * [Not supported] - */ -/*## Java 1.6 begin ## - public void updateNClob(String columnLabel, Reader x) - throws SQLException { - throw unsupported("NClob"); - } -## Java 1.6 end ##*/ - - /** - * [Not supported] - */ -/*## Java 1.6 begin ## - public void updateNClob(String columnLabel, Reader x, long length) - throws SQLException { - throw unsupported("NClob"); - } -## Java 1.6 end ##*/ - - /** - * [Not supported] - */ -/*## Java 1.6 begin ## - public void updateNClob(String columnLabel, NClob x) throws SQLException { - throw unsupported("NClob"); - } -## Java 1.6 end ##*/ - - - /** - * Returns the value of the specified column as a Clob. - * - * @param columnIndex (1,2,...) - * @return the value - * @throws SQLException if the column is not found or if the result set is closed - */ -/*## Java 1.6 begin ## - public NClob getNClob(int columnIndex) throws SQLException { - try { - int id = getNextId(TraceObject.CLOB); - debugCodeAssign("NClob", TraceObject.CLOB, id, "getNClob(" + columnIndex + ")"); - Value v = get(columnIndex); - return v == ValueNull.INSTANCE ? null : new JdbcClob(conn, v, id); - } catch (Exception e) { - throw logAndConvert(e); - } - } -## Java 1.6 end ##*/ - - /** - * Returns the value of the specified column as a Clob. - * - * @param columnLabel the column label - * @return the value - * @throws SQLException if the column is not found or if the result set is closed - */ -/*## Java 1.6 begin ## - public NClob getNClob(String columnLabel) throws SQLException { - try { - int id = getNextId(TraceObject.CLOB); - debugCodeAssign("NClob", TraceObject.CLOB, id, "getNClob(" + columnLabel + ")"); - Value v = get(columnLabel); - return v == ValueNull.INSTANCE ? null : new JdbcClob(conn, v, id); - } catch (Exception e) { - throw logAndConvert(e); - } - } -## Java 1.6 end ##*/ - - /** - * [Not supported] Returns the value of the specified column as a SQLXML object. - */ -/*## Java 1.6 begin ## - public SQLXML getSQLXML(int columnIndex) throws SQLException { - throw unsupported("SQLXML"); - } -## Java 1.6 end ##*/ - - /** - * [Not supported] Returns the value of the specified column as a SQLXML object. - */ -/*## Java 1.6 begin ## - public SQLXML getSQLXML(String columnLabel) throws SQLException { - throw unsupported("SQLXML"); - } -## Java 1.6 end ##*/ - - /** - * [Not supported] Updates a column in the current or insert row. - */ -/*## Java 1.6 begin ## - public void updateSQLXML(int columnIndex, SQLXML xmlObject) - throws SQLException { - throw unsupported("SQLXML"); - } -## Java 1.6 end ##*/ - - /** - * [Not supported] Updates a column in the current or insert row. - */ -/*## Java 1.6 begin ## - public void updateSQLXML(String columnLabel, SQLXML xmlObject) - throws SQLException { - throw unsupported("SQLXML"); - } -## Java 1.6 end ##*/ - - /** - * Returns the value of the specified column as a String. - * - * @param columnIndex (1,2,...) - * @return the value - * @throws SQLException if the column is not found or if the result set is - * closed - */ -/*## Java 1.6 begin ## - public String getNString(int columnIndex) throws SQLException { - try { - debugCodeCall("getNString", columnIndex); - return get(columnIndex).getString(); - } catch (Exception e) { - throw logAndConvert(e); - } - } -## Java 1.6 end ##*/ - - /** - * Returns the value of the specified column as a String. - * - * @param columnLabel the column label - * @return the value - * @throws SQLException if the column is not found or if the result set is - * closed - */ -/*## Java 1.6 begin ## - public String getNString(String columnLabel) throws SQLException { - try { - debugCodeCall("getNString", columnLabel); - return get(columnLabel).getString(); - } catch (Exception e) { - throw logAndConvert(e); - } - } -## Java 1.6 end ##*/ - - /** - * Returns the value of the specified column as input stream. - * - * @param columnIndex (1,2,...) - * @return the value - * @throws SQLException if the column is not found or if the result set is - * closed - */ -/*## Java 1.6 begin ## - public Reader getNCharacterStream(int columnIndex) throws SQLException { - try { - debugCodeCall("getNCharacterStream", columnIndex); - return get(columnIndex).getReader(); - } catch (Exception e) { - throw logAndConvert(e); - } - } -## Java 1.6 end ##*/ - - /** - * Returns the value of the specified column as input stream. - * - * @param columnLabel the column label - * @return the value - * @throws SQLException if the column is not found or if the result set is - * closed - */ -/*## Java 1.6 begin ## - public Reader getNCharacterStream(String columnLabel) throws SQLException { - try { - debugCodeCall("getNCharacterStream", columnLabel); - return get(columnLabel).getReader(); - } catch (Exception e) { - throw logAndConvert(e); - } - } -## Java 1.6 end ##*/ - - /** - * Updates a column in the current or insert row. - * - * @param columnIndex (1,2,...) - * @param x the value - * @throws SQLException if the result set is closed or not updatable - */ -/*## Java 1.6 begin ## - public void updateNCharacterStream(int columnIndex, Reader x) - throws SQLException { - updateNCharacterStream(columnIndex, x, -1); - } -## Java 1.6 end ##*/ - - /** - * Updates a column in the current or insert row. - * - * @param columnIndex (1,2,...) - * @param x the value - * @param length the number of characters - * @throws SQLException if the result set is closed or not updatable - */ -/*## Java 1.6 begin ## - public void updateNCharacterStream(int columnIndex, Reader x, long length) - throws SQLException { - try { - if (isDebugEnabled()) { - debugCode("updateNCharacterStream("+columnIndex+", x, "+length+"L);"); - } - checkClosed(); - Value v = conn.createClob(x, length); - update(columnIndex, v); - } catch (Exception e) { - throw logAndConvert(e); - } - } -## Java 1.6 end ##*/ - - /** - * Updates a column in the current or insert row. - * - * @param columnLabel the column label - * @param x the value - * @throws SQLException if the result set is closed or not updatable - */ -/*## Java 1.6 begin ## - public void updateNCharacterStream(String columnLabel, Reader x) - throws SQLException { - updateNCharacterStream(columnLabel, x, -1); - } -## Java 1.6 end ##*/ - - /** - * Updates a column in the current or insert row. - * - * @param columnLabel the column label - * @param x the value - * @param length the number of characters - * @throws SQLException if the result set is closed or not updatable - */ -/*## Java 1.6 begin ## - public void updateNCharacterStream(String columnLabel, Reader x, long length) - throws SQLException { - try { - if (isDebugEnabled()) { - debugCode("updateNCharacterStream("+quote(columnLabel)+", x, "+length+"L);"); - } - checkClosed(); - Value v = conn.createClob(x, length); - update(columnLabel, v); - } catch (Exception e) { - throw logAndConvert(e); - } - } -## Java 1.6 end ##*/ - - /** - * [Not supported] Return an object of this class if possible. - */ -/*## Java 1.6 begin ## - public T unwrap(Class iface) throws SQLException { - throw unsupported("unwrap"); - } -## Java 1.6 end ##*/ - - /** - * [Not supported] Checks if unwrap can return an object of this class. - */ -/*## Java 1.6 begin ## - public boolean isWrapperFor(Class< ? > iface) throws SQLException { - throw unsupported("isWrapperFor"); - } -## Java 1.6 end ##*/ - - /** - * INTERNAL - */ - public String toString() { - return getTraceObjectName() + ": " + result; - } - - private void patchCurrentRow(Value[] row) { - boolean changed = false; - Value[] current = result.currentRow(); - CompareMode mode = conn.getCompareMode(); - for (int i = 0; i < row.length; i++) { - if (row[i].compareTo(current[i], mode) != 0) { - changed = true; - break; - } - } - if (patchedRows == null) { - patchedRows = New.hashMap(); - } - Integer rowId = result.getRowId(); - if (!changed) { - patchedRows.remove(rowId); - } else { - patchedRows.put(rowId, row); - } - } - - private Value convertToUnknownValue(Object x) throws SQLException { - checkClosed(); - return DataType.convertToValue(conn.getSession(), x, Value.UNKNOWN); - } - - private void checkUpdatable() throws SQLException { - checkClosed(); - if (!updatable) { - throw DbException.get(ErrorCode.RESULT_SET_READONLY); - } - } - -} diff --git a/tools/h2/src/main/org/h2/jdbc/JdbcResultSetMetaData.java b/tools/h2/src/main/org/h2/jdbc/JdbcResultSetMetaData.java deleted file mode 100755 index 66167a6..0000000 --- a/tools/h2/src/main/org/h2/jdbc/JdbcResultSetMetaData.java +++ /dev/null @@ -1,457 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.jdbc; - -import java.sql.ResultSetMetaData; -import java.sql.SQLException; - -import org.h2.message.DbException; -import org.h2.message.Trace; -import org.h2.message.TraceObject; -import org.h2.result.ResultInterface; -import org.h2.util.MathUtils; -import org.h2.value.DataType; - -/** - * Represents the meta data for a ResultSet. - */ -public class JdbcResultSetMetaData extends TraceObject implements ResultSetMetaData { - - private final String catalog; - private final JdbcResultSet rs; - private final JdbcPreparedStatement prep; - private final ResultInterface result; - private final int columnCount; - - JdbcResultSetMetaData(JdbcResultSet rs, JdbcPreparedStatement prep, ResultInterface result, - String catalog, Trace trace, int id) { - setTrace(trace, TraceObject.RESULT_SET_META_DATA, id); - this.catalog = catalog; - this.rs = rs; - this.prep = prep; - this.result = result; - this.columnCount = result.getVisibleColumnCount(); - } - - /** - * Returns the number of columns. - * - * @return the number of columns - * @throws SQLException if the result set is closed or invalid - */ - public int getColumnCount() throws SQLException { - try { - debugCodeCall("getColumnCount"); - checkClosed(); - return columnCount; - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Returns the column label. - * - * @param column the column index (1,2,...) - * @return the column label - * @throws SQLException if the result set is closed or invalid - */ - public String getColumnLabel(int column) throws SQLException { - try { - debugCodeCall("getColumnLabel", column); - checkColumnIndex(column); - return result.getAlias(--column); - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Returns the column name. - * - * @param column the column index (1,2,...) - * @return the column name - * @throws SQLException if the result set is closed or invalid - */ - public String getColumnName(int column) throws SQLException { - try { - debugCodeCall("getColumnName", column); - checkColumnIndex(column); - return result.getColumnName(--column); - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Returns the data type of a column. - * See also java.sql.Type. - * - * @param column the column index (1,2,...) - * @return the data type - * @throws SQLException if the result set is closed or invalid - */ - public int getColumnType(int column) throws SQLException { - try { - debugCodeCall("getColumnType", column); - checkColumnIndex(column); - int type = result.getColumnType(--column); - return DataType.convertTypeToSQLType(type); - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Returns the data type name of a column. - * - * @param column the column index (1,2,...) - * @return the data type name - * @throws SQLException if the result set is closed or invalid - */ - public String getColumnTypeName(int column) throws SQLException { - try { - debugCodeCall("getColumnTypeName", column); - checkColumnIndex(column); - int type = result.getColumnType(--column); - return DataType.getDataType(type).name; - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Returns the schema name. - * - * @param column the column index (1,2,...) - * @return the schema name - * @throws SQLException if the result set is closed or invalid - */ - public String getSchemaName(int column) throws SQLException { - try { - debugCodeCall("getSchemaName", column); - checkColumnIndex(column); - return result.getSchemaName(--column); - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Returns the table name. - * - * @param column the column index (1,2,...) - * @return the table name - * @throws SQLException if the result set is closed or invalid - */ - public String getTableName(int column) throws SQLException { - try { - debugCodeCall("getTableName", column); - checkColumnIndex(column); - return result.getTableName(--column); - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Returns the catalog name. - * - * @param column the column index (1,2,...) - * @return the catalog name - * @throws SQLException if the result set is closed or invalid - */ - public String getCatalogName(int column) throws SQLException { - try { - debugCodeCall("getCatalogName", column); - checkColumnIndex(column); - return catalog; - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Checks if this an autoincrement column. - * It always returns false. - * - * @param column the column index (1,2,...) - * @return false - * @throws SQLException if the result set is closed or invalid - */ - public boolean isAutoIncrement(int column) throws SQLException { - try { - debugCodeCall("isAutoIncrement", column); - checkColumnIndex(column); - return result.isAutoIncrement(--column); - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Checks if this column is case sensitive. - * It always returns true. - * - * @param column the column index (1,2,...) - * @return true - * @throws SQLException if the result set is closed or invalid - */ - public boolean isCaseSensitive(int column) throws SQLException { - try { - debugCodeCall("isCaseSensitive", column); - checkColumnIndex(column); - return true; - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Checks if this column is searchable. - * It always returns true. - * - * @param column the column index (1,2,...) - * @return true - * @throws SQLException if the result set is closed or invalid - */ - public boolean isSearchable(int column) throws SQLException { - try { - debugCodeCall("isSearchable", column); - checkColumnIndex(column); - return true; - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Checks if this is a currency column. - * It always returns false. - * - * @param column the column index (1,2,...) - * @return false - * @throws SQLException if the result set is closed or invalid - */ - public boolean isCurrency(int column) throws SQLException { - try { - debugCodeCall("isCurrency", column); - checkColumnIndex(column); - return false; - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Checks if this is nullable column. Returns - * ResultSetMetaData.columnNullableUnknown if this is not a column of a - * table. Otherwise, it returns ResultSetMetaData.columnNoNulls if the - * column is not nullable, and ResultSetMetaData.columnNullable if it is - * nullable. - * - * @param column the column index (1,2,...) - * @return ResultSetMetaData.column* - * @throws SQLException if the result set is closed or invalid - */ - public int isNullable(int column) throws SQLException { - try { - debugCodeCall("isNullable", column); - checkColumnIndex(column); - return result.getNullable(--column); - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Checks if this column is signed. - * It always returns true. - * - * @param column the column index (1,2,...) - * @return true - * @throws SQLException if the result set is closed or invalid - */ - public boolean isSigned(int column) throws SQLException { - try { - debugCodeCall("isSigned", column); - checkColumnIndex(column); - return true; - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Checks if this column is read only. - * It always returns false. - * - * @param column the column index (1,2,...) - * @return false - * @throws SQLException if the result set is closed or invalid - */ - public boolean isReadOnly(int column) throws SQLException { - try { - debugCodeCall("isReadOnly", column); - checkColumnIndex(column); - return false; - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Checks whether it is possible for a write on this column to succeed. - * It always returns true. - * - * @param column the column index (1,2,...) - * @return true - * @throws SQLException if the result set is closed or invalid - */ - public boolean isWritable(int column) throws SQLException { - try { - debugCodeCall("isWritable", column); - checkColumnIndex(column); - return true; - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Checks whether a write on this column will definitely succeed. - * It always returns false. - * - * @param column the column index (1,2,...) - * @return false - * @throws SQLException if the result set is closed or invalid - */ - public boolean isDefinitelyWritable(int column) throws SQLException { - try { - debugCodeCall("isDefinitelyWritable", column); - checkColumnIndex(column); - return false; - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Gets the Java class name of the object that will be returned - * if ResultSet.getObject is called. - * - * @param column the column index (1,2,...) - * @return the Java class name - * @throws SQLException if the result set is closed or invalid - */ - public String getColumnClassName(int column) throws SQLException { - try { - debugCodeCall("getColumnClassName", column); - checkColumnIndex(column); - int type = result.getColumnType(--column); - return DataType.getTypeClassName(type); - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Gets the precision for this column. - * This method always returns 0. - * - * @param column the column index (1,2,...) - * @return the precision - * @throws SQLException if the result set is closed or invalid - */ - public int getPrecision(int column) throws SQLException { - try { - debugCodeCall("getPrecision", column); - checkColumnIndex(column); - long prec = result.getColumnPrecision(--column); - return MathUtils.convertLongToInt(prec); - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Gets the scale for this column. - * This method always returns 0. - * - * @param column the column index (1,2,...) - * @return the scale - * @throws SQLException if the result set is closed or invalid - */ - public int getScale(int column) throws SQLException { - try { - debugCodeCall("getScale", column); - checkColumnIndex(column); - return result.getColumnScale(--column); - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Gets the maximum display size for this column. - * - * @param column the column index (1,2,...) - * @return the display size - * @throws SQLException if the result set is closed or invalid - */ - public int getColumnDisplaySize(int column) throws SQLException { - try { - debugCodeCall("getColumnDisplaySize", column); - checkColumnIndex(column); - return result.getDisplaySize(--column); - } catch (Exception e) { - throw logAndConvert(e); - } - } - - private void checkClosed() throws SQLException { - if (rs != null) { - rs.checkClosed(); - } - if (prep != null) { - prep.checkClosed(); - } - } - - private void checkColumnIndex(int columnIndex) throws SQLException { - checkClosed(); - if (columnIndex < 1 || columnIndex > columnCount) { - throw DbException.getInvalidValueException("" + columnIndex, "columnIndex"); - } - } - - /** - * [Not supported] Return an object of this class if possible. - */ -/*## Java 1.6 begin ## - public T unwrap(Class iface) throws SQLException { - throw unsupported("unwrap"); - } -## Java 1.6 end ##*/ - - /** - * [Not supported] Checks if unwrap can return an object of this class. - */ -/*## Java 1.6 begin ## - public boolean isWrapperFor(Class< ? > iface) throws SQLException { - throw unsupported("isWrapperFor"); - } -## Java 1.6 end ##*/ - - /** - * INTERNAL - */ - public String toString() { - return getTraceObjectName() + ": columns=" + columnCount; - } - -} diff --git a/tools/h2/src/main/org/h2/jdbc/JdbcSQLException.java b/tools/h2/src/main/org/h2/jdbc/JdbcSQLException.java deleted file mode 100755 index 260ac7b..0000000 --- a/tools/h2/src/main/org/h2/jdbc/JdbcSQLException.java +++ /dev/null @@ -1,185 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.jdbc; - -import java.io.PrintStream; -import java.io.PrintWriter; -import java.sql.SQLException; - -import org.h2.engine.Constants; - -/** - * Represents a database exception. - */ -public class JdbcSQLException extends SQLException { - - /** - * If the SQL statement contains this text, then it is never added to the - * SQL exception. Hiding the SQL statement may be important if it contains a - * passwords, such as a CREATE LINKED TABLE statement. - */ - public static final String HIDE_SQL = "--hide--"; - - private static final long serialVersionUID = 1L; - private final String originalMessage; - private final Throwable cause; - private final String stackTrace; - private String message; - private String sql; - - /** - * Creates a SQLException. - * - * @param message the reason - * @param sql the SQL statement - * @param state the SQL state - * @param errorCode the error code - * @param cause the exception that was the reason for this exception - * @param stackTrace the stack trace - */ - public JdbcSQLException(String message, String sql, String state, int errorCode, Throwable cause, String stackTrace) { - super(message, state, errorCode); - this.originalMessage = message; - setSQL(sql); - this.cause = cause; - this.stackTrace = stackTrace; - buildMessage(); -//## Java 1.4 begin ## - initCause(cause); -//## Java 1.4 end ## - } - - /** - * Get the detail error message. - * - * @return the message - */ - public String getMessage() { - return message; - } - - /** - * INTERNAL - */ - public String getOriginalMessage() { - return originalMessage; - } - - /** - * Prints the stack trace to the standard error stream. - */ - public void printStackTrace() { - // The default implementation already does that, - // but we do it again to avoid problems. - // If it is not implemented, somebody might implement it - // later on which would be a problem if done in the wrong way. - printStackTrace(System.err); - } - - /** - * Prints the stack trace to the specified print writer. - * - * @param s the print writer - */ - public void printStackTrace(PrintWriter s) { - if (s != null) { - super.printStackTrace(s); - /*## Java 1.3 only begin ## - if (cause != null) { - cause.printStackTrace(s); - } - ## Java 1.3 only end ##*/ - // getNextException().printStackTrace(s) would be very very slow - // if many exceptions are joined - SQLException next = getNextException(); - for (int i = 0; i < 100 && next != null; i++) { - s.println(next.toString()); - next = next.getNextException(); - } - if (next != null) { - s.println("(truncated)"); - } - } - } - - /** - * Prints the stack trace to the specified print stream. - * - * @param s the print stream - */ - public void printStackTrace(PrintStream s) { - if (s != null) { - super.printStackTrace(s); - /*## Java 1.3 only begin ## - if (cause != null) { - cause.printStackTrace(s); - } - ## Java 1.3 only end ##*/ - // getNextException().printStackTrace(s) would be very very slow - // if many exceptions are joined - SQLException next = getNextException(); - for (int i = 0; i < 100 && next != null; i++) { - s.println(next.toString()); - next = next.getNextException(); - } - if (next != null) { - s.println("(truncated)"); - } - } - } - - /** - * INTERNAL - */ - public Throwable getOriginalCause() { - return cause; - } - - /** - * Returns the SQL statement. - * SQL statements that contain '--hide--' are not listed. - * - * @return the SQL statement - */ - public String getSQL() { - return sql; - } - - /** - * INTERNAL - */ - public void setSQL(String sql) { - if (sql != null && sql.indexOf(HIDE_SQL) >= 0) { - sql = "-"; - } - this.sql = sql; - buildMessage(); - } - - private void buildMessage() { - StringBuilder buff = new StringBuilder(originalMessage == null ? "- " : originalMessage); - if (sql != null) { - buff.append("; SQL statement:\n").append(sql); - } - buff.append(" [").append(getErrorCode()).append('-').append(Constants.BUILD_ID).append(']'); - message = buff.toString(); - } - - /** - * Returns the class name, the message, and in the server mode, the stack - * trace of the server - * - * @return the string representation - */ - public String toString() { - if (stackTrace == null) { - return super.toString(); - } - return stackTrace; - } - -} diff --git a/tools/h2/src/main/org/h2/jdbc/JdbcSavepoint.java b/tools/h2/src/main/org/h2/jdbc/JdbcSavepoint.java deleted file mode 100755 index b6b9138..0000000 --- a/tools/h2/src/main/org/h2/jdbc/JdbcSavepoint.java +++ /dev/null @@ -1,123 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.jdbc; - -import java.sql.SQLException; -//## Java 1.4 begin ## -import java.sql.Savepoint; -//## Java 1.4 end ## - -import org.h2.constant.ErrorCode; -import org.h2.message.DbException; -import org.h2.message.Trace; -import org.h2.message.TraceObject; -import org.h2.util.StringUtils; - -/** - * A savepoint is a point inside a transaction to where a transaction can be - * rolled back. The tasks that where done before the savepoint are not rolled - * back in this case. - */ -public class JdbcSavepoint extends TraceObject -//## Java 1.4 begin ## -implements Savepoint -//## Java 1.4 end ## -{ - - private static final String SYSTEM_SAVEPOINT_PREFIX = "SYSTEM_SAVEPOINT_"; - - private int savepointId; - private String name; - private JdbcConnection conn; - - JdbcSavepoint(JdbcConnection conn, int savepointId, String name, Trace trace, int id) { - setTrace(trace, TraceObject.SAVEPOINT, id); - this.conn = conn; - this.savepointId = savepointId; - this.name = name; - } - - /** - * Release this savepoint. This method only set the connection to null and - * does not execute a statement. - */ - void release() { - this.conn = null; - } - - /** - * Get the savepoint name for this name or id. - * If the name is null, the id is used. - * - * @param name the name (may be null) - * @param id the id - * @return the savepoint name - */ - static String getName(String name, int id) { - if (name != null) { - return StringUtils.quoteJavaString(name); - } - return SYSTEM_SAVEPOINT_PREFIX + id; - } - - /** - * Roll back to this savepoint. - */ - void rollback() { - checkValid(); - conn.prepareCommand("ROLLBACK TO SAVEPOINT " + getName(name, savepointId), Integer.MAX_VALUE).executeUpdate(); - } - - private void checkValid() { - if (conn == null) { - throw DbException.get(ErrorCode.SAVEPOINT_IS_INVALID_1, getName(name, savepointId)); - } - } - - /** - * Get the generated id of this savepoint. - * @return the id - */ - public int getSavepointId() throws SQLException { - try { - debugCodeCall("getSavepointId"); - checkValid(); - if (name != null) { - throw DbException.get(ErrorCode.SAVEPOINT_IS_NAMED); - } - return savepointId; - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Get the name of this savepoint. - * @return the name - */ - public String getSavepointName() throws SQLException { - try { - debugCodeCall("getSavepointName"); - checkValid(); - if (name == null) { - throw DbException.get(ErrorCode.SAVEPOINT_IS_UNNAMED); - } - return name; - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * INTERNAL - */ - public String toString() { - return getTraceObjectName() + ": id=" + savepointId + " name=" + name; - } - - -} diff --git a/tools/h2/src/main/org/h2/jdbc/JdbcStatement.java b/tools/h2/src/main/org/h2/jdbc/JdbcStatement.java deleted file mode 100755 index bbed453..0000000 --- a/tools/h2/src/main/org/h2/jdbc/JdbcStatement.java +++ /dev/null @@ -1,994 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.jdbc; - -import java.sql.BatchUpdateException; -import java.sql.Connection; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.sql.SQLWarning; -import java.sql.Statement; -import java.util.ArrayList; -import org.h2.command.CommandInterface; -import org.h2.constant.ErrorCode; -import org.h2.constant.SysProperties; -import org.h2.engine.SessionInterface; -import org.h2.message.DbException; -import org.h2.message.TraceObject; -import org.h2.result.ResultInterface; -import org.h2.util.New; - -/** - * Represents a statement. - */ -public class JdbcStatement extends TraceObject implements Statement { - - protected JdbcConnection conn; - protected SessionInterface session; - protected JdbcResultSet resultSet; - protected int maxRows; - protected int fetchSize = SysProperties.SERVER_RESULT_SET_FETCH_SIZE; - protected int updateCount; - protected final int resultSetType; - protected final int resultSetConcurrency; - protected boolean closedByResultSet; - private CommandInterface executingCommand; - private ArrayList batchCommands; - private boolean escapeProcessing = true; - - JdbcStatement(JdbcConnection conn, int id, int resultSetType, int resultSetConcurrency, boolean closeWithResultSet) { - this.conn = conn; - this.session = conn.getSession(); - setTrace(session.getTrace(), TraceObject.STATEMENT, id); - this.resultSetType = resultSetType; - this.resultSetConcurrency = resultSetConcurrency; - this.closedByResultSet = closeWithResultSet; - } - - /** - * Executes a query (select statement) and returns the result set. - * If another result set exists for this statement, this will be closed - * (even if this statement fails). - * - * @param sql the SQL statement to execute - * @return the result set - */ - public ResultSet executeQuery(String sql) throws SQLException { - try { - int id = getNextId(TraceObject.RESULT_SET); - if (isDebugEnabled()) { - debugCodeAssign("ResultSet", TraceObject.RESULT_SET, id, "executeQuery(" + quote(sql) + ")"); - } - checkClosed(); - closeOldResultSet(); - sql = conn.translateSQL(sql, escapeProcessing); - synchronized (session) { - CommandInterface command = conn.prepareCommand(sql, fetchSize); - ResultInterface result; - boolean scrollable = resultSetType != ResultSet.TYPE_FORWARD_ONLY; - boolean updatable = resultSetConcurrency == ResultSet.CONCUR_UPDATABLE; - setExecutingStatement(command); - try { - result = command.executeQuery(maxRows, scrollable); - } finally { - setExecutingStatement(null); - } - command.close(); - resultSet = new JdbcResultSet(conn, this, result, id, closedByResultSet, scrollable, updatable); - } - return resultSet; - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Executes a statement (insert, update, delete, create, drop) - * and returns the update count. - * If another result set exists for this statement, this will be closed - * (even if this statement fails). - * - * If the statement is a create or drop and does not throw an exception, - * the current transaction (if any) is committed after executing the statement. - * If auto commit is on, this statement will be committed. - * - * @param sql the SQL statement - * @return the update count (number of row affected by an insert, - * update or delete, or 0 if no rows or the statement was a - * create, drop, commit or rollback) - * @throws SQLException if a database error occurred or a - * select statement was executed - */ - public int executeUpdate(String sql) throws SQLException { - try { - debugCodeCall("executeUpdate", sql); - return executeUpdateInternal(sql); - } catch (Exception e) { - throw logAndConvert(e); - } - } - - private int executeUpdateInternal(String sql) throws SQLException { - checkClosedForWrite(); - try { - closeOldResultSet(); - sql = conn.translateSQL(sql, escapeProcessing); - CommandInterface command = conn.prepareCommand(sql, fetchSize); - synchronized (session) { - setExecutingStatement(command); - try { - updateCount = command.executeUpdate(); - } finally { - setExecutingStatement(null); - } - } - command.close(); - return updateCount; - } finally { - afterWriting(); - } - } - - /** - * Executes an arbitrary statement. If another result set exists for this - * statement, this will be closed (even if this statement fails). - * - * If the statement is a create or drop and does not throw an exception, the - * current transaction (if any) is committed after executing the statement. - * If auto commit is on, and the statement is not a select, this statement - * will be committed. - * - * @param sql the SQL statement to execute - * @return true if a result set is available, false if not - */ - public boolean execute(String sql) throws SQLException { - try { - debugCodeCall("execute", sql); - return executeInternal(sql); - } catch (Exception e) { - throw logAndConvert(e); - } - } - - private boolean executeInternal(String sql) throws SQLException { - int id = getNextId(TraceObject.RESULT_SET); - checkClosedForWrite(); - try { - closeOldResultSet(); - sql = conn.translateSQL(sql, escapeProcessing); - CommandInterface command = conn.prepareCommand(sql, fetchSize); - boolean returnsResultSet; - synchronized (session) { - setExecutingStatement(command); - try { - if (command.isQuery()) { - returnsResultSet = true; - boolean scrollable = resultSetType != ResultSet.TYPE_FORWARD_ONLY; - boolean updatable = resultSetConcurrency == ResultSet.CONCUR_UPDATABLE; - ResultInterface result = command.executeQuery(maxRows, scrollable); - resultSet = new JdbcResultSet(conn, this, result, id, closedByResultSet, scrollable, updatable); - } else { - returnsResultSet = false; - updateCount = command.executeUpdate(); - } - } finally { - setExecutingStatement(null); - } - } - command.close(); - return returnsResultSet; - } finally { - afterWriting(); - } - } - - /** - * Returns the last result set produces by this statement. - * - * @return the result set - */ - public ResultSet getResultSet() throws SQLException { - try { - checkClosed(); - if (resultSet != null) { - int id = resultSet.getTraceId(); - debugCodeAssign("ResultSet", TraceObject.RESULT_SET, id, "getResultSet()"); - } else { - debugCodeCall("getResultSet"); - } - return resultSet; - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Returns the last update count of this statement. - * - * @return the update count (number of row affected by an insert, - * update or delete, or 0 if no rows or the statement was a - * create, drop, commit or rollback; -1 if the statement was a select). - * @throws SQLException if this object is closed or invalid - */ - public int getUpdateCount() throws SQLException { - try { - debugCodeCall("getUpdateCount"); - checkClosed(); - return updateCount; - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Closes this statement. - * All result sets that where created by this statement - * become invalid after calling this method. - */ - public void close() throws SQLException { - try { - debugCodeCall("close"); - closeOldResultSet(); - if (conn != null) { - conn = null; - } - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Returns the connection that created this object. - * - * @return the connection - */ - public Connection getConnection() { - debugCodeCall("getConnection"); - return conn; - } - - /** - * Gets the first warning reported by calls on this object. - * This driver does not support warnings, and will always return null. - * - * @return null - */ - public SQLWarning getWarnings() throws SQLException { - try { - debugCodeCall("getWarnings"); - checkClosed(); - return null; - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Clears all warnings. As this driver does not support warnings, - * this call is ignored. - */ - public void clearWarnings() throws SQLException { - try { - debugCodeCall("clearWarnings"); - checkClosed(); - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Moves to the next result set - however there is always only one result - * set. This call also closes the current result set (if there is one). - * Returns true if there is a next result set (that means - it always - * returns false). - * - * @return false - * @throws SQLException if this object is closed. - */ - public boolean getMoreResults() throws SQLException { - try { - debugCodeCall("getMoreResults"); - checkClosed(); - closeOldResultSet(); - return false; - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Sets the name of the cursor. This call is ignored. - * - * @param name ignored - * @throws SQLException if this object is closed - */ - public void setCursorName(String name) throws SQLException { - try { - debugCodeCall("setCursorName", name); - checkClosed(); - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Sets the fetch direction. - * This call is ignored by this driver. - * - * @param direction ignored - * @throws SQLException if this object is closed - */ - public void setFetchDirection(int direction) throws SQLException { - try { - debugCodeCall("setFetchDirection", direction); - checkClosed(); - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Gets the fetch direction. - * - * @return FETCH_FORWARD - * @throws SQLException if this object is closed - */ - public int getFetchDirection() throws SQLException { - try { - debugCodeCall("getFetchDirection"); - checkClosed(); - return ResultSet.FETCH_FORWARD; - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Gets the maximum number of rows for a ResultSet. - * - * @return the number of rows where 0 means no limit - * @throws SQLException if this object is closed - */ - public int getMaxRows() throws SQLException { - try { - debugCodeCall("getMaxRows"); - checkClosed(); - return maxRows; - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Gets the maximum number of rows for a ResultSet. - * - * @param maxRows the number of rows where 0 means no limit - * @throws SQLException if this object is closed - */ - public void setMaxRows(int maxRows) throws SQLException { - try { - debugCodeCall("setMaxRows", maxRows); - checkClosed(); - if (maxRows < 0) { - throw DbException.getInvalidValueException("" + maxRows, "maxRows"); - } - this.maxRows = maxRows; - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Sets the number of rows suggested to read in one step. - * This value cannot be higher than the maximum rows (setMaxRows) - * set by the statement or prepared statement, otherwise an exception - * is throws. Setting the value to 0 will set the default value. - * The default value can be changed using the system property - * h2.serverResultSetFetchSize. - * - * @param rows the number of rows - * @throws SQLException if this object is closed - */ - public void setFetchSize(int rows) throws SQLException { - try { - debugCodeCall("setFetchSize", rows); - checkClosed(); - if (rows < 0 || (rows > 0 && maxRows > 0 && rows > maxRows)) { - throw DbException.getInvalidValueException("" + rows, "rows"); - } - if (rows == 0) { - rows = SysProperties.SERVER_RESULT_SET_FETCH_SIZE; - } - fetchSize = rows; - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Gets the number of rows suggested to read in one step. - * - * @return the current fetch size - * @throws SQLException if this object is closed - */ - public int getFetchSize() throws SQLException { - try { - debugCodeCall("getFetchSize"); - checkClosed(); - return fetchSize; - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Gets the result set concurrency created by this object. - * - * @return the concurrency - */ - public int getResultSetConcurrency() throws SQLException { - try { - debugCodeCall("getResultSetConcurrency"); - checkClosed(); - return resultSetConcurrency; - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Gets the result set type. - * - * @return the type - * @throws SQLException if this object is closed - */ - public int getResultSetType() throws SQLException { - try { - debugCodeCall("getResultSetType"); - checkClosed(); - return resultSetType; - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Gets the maximum number of bytes for a result set column. - * - * @return always 0 for no limit - * @throws SQLException if this object is closed - */ - public int getMaxFieldSize() throws SQLException { - try { - debugCodeCall("getMaxFieldSize"); - checkClosed(); - return 0; - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Sets the maximum number of bytes for a result set column. - * This method does currently do nothing for this driver. - * - * @param max the maximum size - ignored - * @throws SQLException if this object is closed - */ - public void setMaxFieldSize(int max) throws SQLException { - try { - debugCodeCall("setMaxFieldSize", max); - checkClosed(); - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Enables or disables processing or JDBC escape syntax. - * See also Connection.nativeSQL. - * - * @param enable - true (default) or false (no conversion is attempted) - * @throws SQLException if this object is closed - */ - public void setEscapeProcessing(boolean enable) throws SQLException { - try { - if (isDebugEnabled()) { - debugCode("setEscapeProcessing("+enable+");"); - } - checkClosed(); - escapeProcessing = enable; - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Cancels a currently running statement. - * This method must be called from within another - * thread than the execute method. - * - * @throws SQLException if this object is closed - */ - public void cancel() throws SQLException { - try { - debugCodeCall("cancel"); - checkClosed(); - // executingCommand can be reset by another thread - CommandInterface c = executingCommand; - try { - if (c != null) { - c.cancel(); - } - } finally { - setExecutingStatement(null); - } - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Gets the current query timeout in seconds. - * This method will return 0 if no query timeout is set. - * The result is rounded to the next second. - * - * @return the timeout in seconds - * @throws SQLException if this object is closed - */ - public int getQueryTimeout() throws SQLException { - try { - debugCodeCall("getQueryTimeout"); - checkClosed(); - return conn.getQueryTimeout(); - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Sets the current query timeout in seconds. Calling this method will - * commit an open transaction, even if the value is the same as before. - * Changing the value will affect all statements of this connection. This - * method does not commit a transaction, and rolling back a transaction does - * not affect this setting. - * - * @param seconds the timeout in seconds - 0 means no timeout, values - * smaller 0 will throw an exception - * @throws SQLException if this object is closed - */ - public void setQueryTimeout(int seconds) throws SQLException { - try { - debugCodeCall("setQueryTimeout", seconds); - checkClosed(); - if (seconds < 0) { - throw DbException.getInvalidValueException("" + seconds, "seconds"); - } - conn.setQueryTimeout(seconds); - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Adds a statement to the batch. - * - * @param sql the SQL statement - */ - public void addBatch(String sql) throws SQLException { - try { - debugCodeCall("addBatch", sql); - checkClosed(); - sql = conn.translateSQL(sql, escapeProcessing); - if (batchCommands == null) { - batchCommands = New.arrayList(); - } - batchCommands.add(sql); - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Clears the batch. - */ - public void clearBatch() throws SQLException { - try { - debugCodeCall("clearBatch"); - checkClosed(); - batchCommands = null; - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Executes the batch. - * - * @return the array of update counts - */ - public int[] executeBatch() throws SQLException { - try { - debugCodeCall("executeBatch"); - checkClosedForWrite(); - try { - if (batchCommands == null) { - // TODO batch: check what other database do if no commands are set - batchCommands = New.arrayList(); - } - int[] result = new int[batchCommands.size()]; - boolean error = false; - for (int i = 0; i < batchCommands.size(); i++) { - String sql = batchCommands.get(i); - try { - result[i] = executeUpdateInternal(sql); - } catch (Exception e) { - logAndConvert(e); - //## Java 1.4 begin ## - result[i] = Statement.EXECUTE_FAILED; - //## Java 1.4 end ## - error = true; - } - } - batchCommands = null; - if (error) { - throw new BatchUpdateException(result); - } - return result; - } finally { - afterWriting(); - } - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Return a result set that contains the last generated autoincrement key - * for this connection. - * - * @return the result set with one row and one column containing the key - * @throws SQLException if this object is closed - */ - public ResultSet getGeneratedKeys() throws SQLException { - try { - int id = getNextId(TraceObject.RESULT_SET); - if (isDebugEnabled()) { - debugCodeAssign("ResultSet", TraceObject.RESULT_SET, id, "getGeneratedKeys()"); - } - checkClosed(); - return conn.getGeneratedKeys(this, id); - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Move to the next result set. - * This method always returns false. - * - * @param current Statement.CLOSE_CURRENT_RESULT, - * Statement.KEEP_CURRENT_RESULT, - * or Statement.CLOSE_ALL_RESULTS - * @return false - */ - public boolean getMoreResults(int current) throws SQLException { - try { - debugCodeCall("getMoreResults", current); - switch (current) { - case Statement.CLOSE_CURRENT_RESULT: - case Statement.CLOSE_ALL_RESULTS: - if (resultSet != null) { - resultSet.close(); - } - break; - case Statement.KEEP_CURRENT_RESULT: - // nothing to do - break; - default: - throw DbException.getInvalidValueException("" + current, "current"); - } - return false; - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Executes a statement and returns the update count. - * This method just calls executeUpdate(String sql). - * - * @param sql the SQL statement - * @return the update count (number of row affected by an insert, - * update or delete, or 0 if no rows or the statement was a - * create, drop, commit or rollback) - * @throws SQLException if a database error occurred or a - * select statement was executed - */ - public int executeUpdate(String sql, int autoGeneratedKeys) throws SQLException { - try { - if (isDebugEnabled()) { - debugCode("executeUpdate("+quote(sql)+", "+autoGeneratedKeys+");"); - } - return executeUpdateInternal(sql); - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Executes a statement and returns the update count. - * This method just calls executeUpdate(String sql). - * - * @param sql the SQL statement - * @return the update count (number of row affected by an insert, - * update or delete, or 0 if no rows or the statement was a - * create, drop, commit or rollback) - * @throws SQLException if a database error occurred or a - * select statement was executed - */ - public int executeUpdate(String sql, int[] columnIndexes) throws SQLException { - try { - if (isDebugEnabled()) { - debugCode("executeUpdate("+quote(sql)+", "+quoteIntArray(columnIndexes)+");"); - } - return executeUpdateInternal(sql); - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Executes a statement and returns the update count. - * This method just calls executeUpdate(String sql). - * - * @param sql the SQL statement - * @return the update count (number of row affected by an insert, - * update or delete, or 0 if no rows or the statement was a - * create, drop, commit or rollback) - * @throws SQLException if a database error occurred or a - * select statement was executed - */ - public int executeUpdate(String sql, String[] columnNames) throws SQLException { - try { - if (isDebugEnabled()) { - debugCode("executeUpdate("+quote(sql)+", "+quoteArray(columnNames)+");"); - } - return executeUpdateInternal(sql); - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Executes a statement and returns the update count. - * This method just calls execute(String sql). - * - * @param sql the SQL statement - * @return the update count (number of row affected by an insert, - * update or delete, or 0 if no rows or the statement was a - * create, drop, commit or rollback) - * @throws SQLException if a database error occurred or a - * select statement was executed - */ - public boolean execute(String sql, int autoGeneratedKeys) throws SQLException { - try { - if (isDebugEnabled()) { - debugCode("execute("+quote(sql)+", "+autoGeneratedKeys+");"); - } - return executeInternal(sql); - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Executes a statement and returns the update count. - * This method just calls execute(String sql). - * - * @param sql the SQL statement - * @return the update count (number of row affected by an insert, - * update or delete, or 0 if no rows or the statement was a - * create, drop, commit or rollback) - * @throws SQLException if a database error occurred or a - * select statement was executed - */ - public boolean execute(String sql, int[] columnIndexes) throws SQLException { - try { - if (isDebugEnabled()) { - debugCode("execute("+quote(sql)+", "+quoteIntArray(columnIndexes)+");"); - } - return executeInternal(sql); - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Executes a statement and returns the update count. - * This method just calls execute(String sql). - * - * @param sql the SQL statement - * @return the update count (number of row affected by an insert, - * update or delete, or 0 if no rows or the statement was a - * create, drop, commit or rollback) - * @throws SQLException if a database error occurred or a - * select statement was executed - */ - public boolean execute(String sql, String[] columnNames) throws SQLException { - try { - if (isDebugEnabled()) { - debugCode("execute("+quote(sql)+", "+quoteArray(columnNames)+");"); - } - return executeInternal(sql); - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * Gets the result set holdability. - * - * @return the holdability - */ -//## Java 1.4 begin ## - public int getResultSetHoldability() throws SQLException { - try { - debugCodeCall("getResultSetHoldability"); - checkClosed(); - return ResultSet.HOLD_CURSORS_OVER_COMMIT; - } catch (Exception e) { - throw logAndConvert(e); - } - } -//## Java 1.4 end ## - - // ============================================================= - - /** - * Check if this connection is closed. - * The next operation is a read request. - * - * @return true if the session was re-connected - * @throws SQLException if the connection or session is closed - */ - boolean checkClosed() throws SQLException { - return checkClosed(false); - } - - /** - * Check if this connection is closed. - * The next operation may be a write request. - * - * @return true if the session was re-connected - * @throws SQLException if the connection or session is closed - */ - boolean checkClosedForWrite() throws SQLException { - return checkClosed(true); - } - - /** - * INTERNAL. - * Check if the statement is closed. - * - * @param write if the next operation is possibly writing - * @return true if a reconnect was required - * @throws SQLException if it is closed - */ - protected boolean checkClosed(boolean write) throws SQLException { - if (conn == null) { - throw DbException.get(ErrorCode.OBJECT_CLOSED); - } - conn.checkClosed(write); - SessionInterface s = conn.getSession(); - if (s != session) { - session = s; - setTrace(session.getTrace()); - return true; - } - return false; - } - - /** - * Called after each write operation. - */ - void afterWriting() { - if (conn != null) { - conn.afterWriting(); - } - } - - /** - * INTERNAL. - * Close and old result set if there is still one open. - */ - protected void closeOldResultSet() throws SQLException { - try { - if (!closedByResultSet) { - if (resultSet != null) { - resultSet.closeInternal(); - } - } - } finally { - resultSet = null; - updateCount = -1; - } - } - - /** - * INTERNAL. - * Set the statement that is currently running. - * - * @param c the command - */ - protected void setExecutingStatement(CommandInterface c) { - conn.setExecutingStatement(c == null ? null : this); - executingCommand = c; - } - - /** - * Returns whether this statement is closed. - * - * @return true if the statement is closed - */ - public boolean isClosed() throws SQLException { - try { - debugCodeCall("isClosed"); - return conn == null; - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * [Not supported] Return an object of this class if possible. - */ -/*## Java 1.6 begin ## - public T unwrap(Class iface) throws SQLException { - throw unsupported("unwrap"); - } -## Java 1.6 end ##*/ - - /** - * [Not supported] Checks if unwrap can return an object of this class. - */ -/*## Java 1.6 begin ## - public boolean isWrapperFor(Class< ? > iface) throws SQLException { - throw unsupported("isWrapperFor"); - } -## Java 1.6 end ##*/ - - /** - * Returns whether this object is poolable. - * @return false - */ - public boolean isPoolable() { - debugCodeCall("isPoolable"); - return false; - } - - /** - * Requests that this object should be pooled or not. - * This call is ignored. - * - * @param poolable the requested value - */ - public void setPoolable(boolean poolable) { - if (isDebugEnabled()) { - debugCode("setPoolable("+poolable+");"); - } - } - - /** - * INTERNAL - */ - public String toString() { - return getTraceObjectName(); - } - -} - diff --git a/tools/h2/src/main/org/h2/jdbc/package.html b/tools/h2/src/main/org/h2/jdbc/package.html deleted file mode 100755 index 124923d..0000000 --- a/tools/h2/src/main/org/h2/jdbc/package.html +++ /dev/null @@ -1,15 +0,0 @@ - - - - -Javadoc package documentation -

- -Implementation of the JDBC API (package java.sql). - -

\ No newline at end of file diff --git a/tools/h2/src/main/org/h2/jdbcx/JdbcConnectionPool.java b/tools/h2/src/main/org/h2/jdbcx/JdbcConnectionPool.java deleted file mode 100755 index 6810c32..0000000 --- a/tools/h2/src/main/org/h2/jdbcx/JdbcConnectionPool.java +++ /dev/null @@ -1,362 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: Christian d'Heureuse, www.source-code.biz - * - * This class is dual-licensed LGPL and under the H2 License. - * - * This module is free software: you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation, either - * version 3 of the License, or (at your option) any later version. - * See http://www.gnu.org/licenses/lgpl.html - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied - * warranty of MERCHANTABILITY or FITNESS FOR A - * PARTICULAR PURPOSE. See the GNU Lesser General Public - * License for more details. - */ -package org.h2.jdbcx; - -import java.io.PrintWriter; -import java.sql.Connection; -import java.sql.SQLException; -import java.util.Stack; - -import javax.sql.ConnectionEvent; -import javax.sql.ConnectionEventListener; -import javax.sql.ConnectionPoolDataSource; -import javax.sql.DataSource; -import javax.sql.PooledConnection; - -/*## Java 1.6 begin ## -import org.h2.message.DbException; -## Java 1.6 end ##*/ - -/** - * A simple standalone JDBC connection pool. - * It is based on the - * - * MiniConnectionPoolManager written by Christian d'Heureuse (Java 1.5) - * . It is used as follows: - *
- * import java.sql.*;
- * import org.h2.jdbcx.JdbcConnectionPool;
- * public class Test {
- *     public static void main(String... args) throws Exception {
- *         JdbcConnectionPool cp = JdbcConnectionPool.create(
- *             "jdbc:h2:~/test", "sa", "sa");
- *         for (String sql : args) {
- *             Connection conn = cp.getConnection();
- *             conn.createStatement().execute(sql);
- *             conn.close();
- *         }
- *         cp.dispose();
- *     }
- * }
- * 
- * - * @author Christian d'Heureuse - * (www.source-code.biz) - * @author Thomas Mueller (ported to Java 1.4, some changes) - */ -public class JdbcConnectionPool implements DataSource, ConnectionEventListener { - - private static final int DEFAULT_TIMEOUT = 30; - - private final ConnectionPoolDataSource dataSource; - private final Stack recycledConnections = new Stack(); - private PrintWriter logWriter; - private int maxConnections = 10; - private int timeout = DEFAULT_TIMEOUT; - private int activeConnections; - private boolean isDisposed; - - private JdbcConnectionPool(ConnectionPoolDataSource dataSource) { - this.dataSource = dataSource; - try { - logWriter = dataSource.getLogWriter(); - } catch (Exception e) { - // ignore - } - } - - /** - * Constructs a new connection pool. - * - * @param dataSource the data source to create connections - * @return the connection pool - */ - public static JdbcConnectionPool create(ConnectionPoolDataSource dataSource) { - return new JdbcConnectionPool(dataSource); - } - - /** - * Constructs a new connection pool for H2 databases. - * - * @param url the database URL of the H2 connection - * @param user the user name - * @param password the password - * @return the connection pool - */ - public static JdbcConnectionPool create(String url, String user, String password) { - JdbcDataSource ds = new JdbcDataSource(); - ds.setURL(url); - ds.setUser(user); - ds.setPassword(password); - return new JdbcConnectionPool(ds); - } - - /** - * Sets the maximum number of connections to use from now on. - * The default value is 10 connections. - * - * @param max the maximum number of connections - */ - public synchronized void setMaxConnections(int max) { - if (max < 1) { - throw new IllegalArgumentException("Invalid maxConnections value: " + max); - } - this.maxConnections = max; - // notify waiting threads if the value was increased - notifyAll(); - } - - /** - * Gets the maximum number of connections to use. - * - * @return the max the maximum number of connections - */ - public synchronized int getMaxConnections() { - return maxConnections; - } - - /** - * Gets the maximum time in seconds to wait for a free connection. - * - * @return the timeout in seconds - */ - public synchronized int getLoginTimeout() { - return timeout; - } - - /** - * Sets the maximum time in seconds to wait for a free connection. - * The default timeout is 5 minutes. Calling this method with the - * value 0 will set the timeout to the default value. - * - * @param seconds the timeout, 0 meaning the default - */ - public synchronized void setLoginTimeout(int seconds) { - if (seconds == 0) { - seconds = DEFAULT_TIMEOUT; - } - this.timeout = seconds; - } - - /** - * Closes all unused pooled connections. - */ - public synchronized void dispose() throws SQLException { - if (isDisposed) { - return; - } - isDisposed = true; - SQLException e = null; - while (!recycledConnections.isEmpty()) { - PooledConnection pc = recycledConnections.pop(); - try { - pc.close(); - } catch (SQLException e2) { - if (e == null) { - e = e2; - } - } - } - if (e != null) { - throw e; - } - } - - /** - * Retrieves a connection from the connection pool. If - * maxConnections connections are already in use, the method - * waits until a connection becomes available or timeout - * seconds elapsed. When the application is finished using the connection, - * it must close it in order to return it to the pool. - * If no connection becomes available within the given timeout, an exception - * with SQL state 08001 and vendor code 8001 is thrown. - * - * @return a new Connection object. - * @throws SQLException when a new connection could not be established, - * or a timeout occurred - */ - public Connection getConnection() throws SQLException { - for (int i = 0;; i++) { - synchronized (this) { - if (activeConnections < maxConnections) { - return getConnectionNow(); - } - if (i >= timeout) { - throw new SQLException("Login timeout", "08001", 8001); - } - try { - wait(1000); - } catch (InterruptedException e) { - // ignore - } - } - } - } - - private Connection getConnectionNow() throws SQLException { - if (isDisposed) { - throw new IllegalStateException("Connection pool has been disposed."); - } - PooledConnection pc; - if (!recycledConnections.empty()) { - pc = recycledConnections.pop(); - } else { - pc = dataSource.getPooledConnection(); - } - Connection conn = pc.getConnection(); - activeConnections++; - pc.addConnectionEventListener(this); - return conn; - } - - /** - * This method usually puts the connection back into the pool. There are - * some exceptions: if the pool is disposed, the connection is disposed as - * well. If the pool is full, the connection is closed. - * - * @param pc the pooled connection - */ - synchronized void recycleConnection(PooledConnection pc) { - if (isDisposed) { - disposeConnection(pc); - return; - } - if (activeConnections <= 0) { - throw new AssertionError(); - } - activeConnections--; - if (activeConnections < maxConnections) { - recycledConnections.push(pc); - } else { - closeConnection(pc); - } - notifyAll(); - } - - private void closeConnection(PooledConnection pc) { - try { - pc.close(); - } catch (SQLException e) { - log("Error while closing database connection: " + e.toString()); - } - } - - /** - * Close the connection, and don't add it back to the pool. - * - * @param pc the pooled connection - */ - synchronized void disposeConnection(PooledConnection pc) { - if (activeConnections <= 0) { - throw new AssertionError(); - } - activeConnections--; - notifyAll(); - closeConnection(pc); - } - - private void log(String msg) { - String s = getClass().getName() + ": " + msg; - try { - if (logWriter == null) { - System.err.println(s); - } else { - logWriter.println(s); - } - } catch (Exception e) { - // ignore - } - } - - /** - * INTERNAL - */ - public void connectionClosed(ConnectionEvent event) { - PooledConnection pc = (PooledConnection) event.getSource(); - pc.removeConnectionEventListener(this); - recycleConnection(pc); - } - - /** - * INTERNAL - */ - public void connectionErrorOccurred(ConnectionEvent event) { - PooledConnection pc = (PooledConnection) event.getSource(); - pc.removeConnectionEventListener(this); - disposeConnection(pc); - } - - /** - * Returns the number of active (open) connections of this pool. This is the - * number of Connection objects that have been issued by - * getConnection() for which Connection.close() has - * not yet been called. - * - * @return the number of active connections. - */ - public synchronized int getActiveConnections() { - return activeConnections; - } - - /** - * INTERNAL - */ - public Connection getConnection(String username, String password) { - throw new UnsupportedOperationException(); - } - - /** - * INTERNAL - */ - public PrintWriter getLogWriter() { - return logWriter; - } - - /** - * INTERNAL - */ - public void setLogWriter(PrintWriter logWriter) { - this.logWriter = logWriter; - } - - /** - * [Not supported] Return an object of this class if possible. - * - * @param iface the class - */ -/*## Java 1.6 begin ## - public T unwrap(Class iface) throws SQLException { - throw DbException.getUnsupportedException("unwrap"); - } -## Java 1.6 end ##*/ - - /** - * [Not supported] Checks if unwrap can return an object of this class. - * - * @param iface the class - */ -/*## Java 1.6 begin ## - public boolean isWrapperFor(Class< ? > iface) throws SQLException { - throw DbException.getUnsupportedException("isWrapperFor"); - } -## Java 1.6 end ##*/ - -} diff --git a/tools/h2/src/main/org/h2/jdbcx/JdbcDataSource.java b/tools/h2/src/main/org/h2/jdbcx/JdbcDataSource.java deleted file mode 100755 index 2dad7a9..0000000 --- a/tools/h2/src/main/org/h2/jdbcx/JdbcDataSource.java +++ /dev/null @@ -1,390 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.jdbcx; - -import java.io.IOException; -import java.io.ObjectInputStream; -import java.io.PrintWriter; -import java.io.Serializable; -import java.sql.Connection; -import java.sql.SQLException; -import java.util.Properties; -import javax.naming.Reference; -import javax.naming.Referenceable; -import javax.naming.StringRefAddr; -import javax.sql.ConnectionPoolDataSource; -import javax.sql.DataSource; -import javax.sql.PooledConnection; -import javax.sql.XAConnection; -import javax.sql.XADataSource; -import org.h2.jdbc.JdbcConnection; -import org.h2.message.TraceObject; -import org.h2.util.StringUtils; - -/** - * A data source for H2 database connections. It is a factory for XAConnection - * and Connection objects. This class is usually registered in a JNDI naming - * service. To create a data source object and register it with a JNDI service, - * use the following code: - * - *
- * import org.h2.jdbcx.JdbcDataSource;
- * import javax.naming.Context;
- * import javax.naming.InitialContext;
- * JdbcDataSource ds = new JdbcDataSource();
- * ds.setURL("jdbc:h2:˜/test");
- * ds.setUser("sa");
- * ds.setPassword("sa");
- * Context ctx = new InitialContext();
- * ctx.bind("jdbc/dsName", ds);
- * 
- * - * To use a data source that is already registered, use the following code: - * - *
- * import java.sql.Connection;
- * import javax.sql.DataSource;
- * import javax.naming.Context;
- * import javax.naming.InitialContext;
- * Context ctx = new InitialContext();
- * DataSource ds = (DataSource) ctx.lookup("jdbc/dsName");
- * Connection conn = ds.getConnection();
- * 
- * - * In this example the user name and password are serialized as - * well; this may be a security problem in some cases. - */ -public class JdbcDataSource extends TraceObject -//## Java 1.4 begin ## -implements XADataSource, DataSource, ConnectionPoolDataSource, Serializable, Referenceable -//## Java 1.4 end ## -{ - - private static final long serialVersionUID = 1288136338451857771L; - - private transient JdbcDataSourceFactory factory; - private transient PrintWriter logWriter; - private int loginTimeout; - private String userName = ""; - private char[] passwordChars = { }; - private String url = ""; - private String description; - - static { - org.h2.Driver.load(); - } - - /** - * The public constructor. - */ - public JdbcDataSource() { - initFactory(); - int id = getNextId(TraceObject.DATA_SOURCE); - setTrace(factory.getTrace(), TraceObject.DATA_SOURCE, id); - } - - /** - * Called when de-serializing the object. - * - * @param in the input stream - */ - private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException { - initFactory(); - in.defaultReadObject(); - } - - private void initFactory() { - factory = new JdbcDataSourceFactory(); - } - - /** - * Get the login timeout in seconds, 0 meaning no timeout. - * - * @return the timeout in seconds - */ - public int getLoginTimeout() { - debugCodeCall("getLoginTimeout"); - return loginTimeout; - } - - /** - * Set the login timeout in seconds, 0 meaning no timeout. - * The default value is 0. - * This value is ignored by this database. - * - * @param timeout the timeout in seconds - */ - public void setLoginTimeout(int timeout) { - debugCodeCall("setLoginTimeout", timeout); - this.loginTimeout = timeout; - } - - /** - * Get the current log writer for this object. - * - * @return the log writer - */ - public PrintWriter getLogWriter() { - debugCodeCall("getLogWriter"); - return logWriter; - } - - /** - * Set the current log writer for this object. - * This value is ignored by this database. - * - * @param out the log writer - */ - public void setLogWriter(PrintWriter out) { - debugCodeCall("setLogWriter(out)"); - logWriter = out; - } - - /** - * Open a new connection using the current URL, user name and password. - * - * @return the connection - */ - public Connection getConnection() throws SQLException { - debugCodeCall("getConnection"); - return getJdbcConnection(userName, StringUtils.cloneCharArray(passwordChars)); - } - - /** - * Open a new connection using the current URL and the specified user name - * and password. - * - * @param user the user name - * @param password the password - * @return the connection - */ - public Connection getConnection(String user, String password) throws SQLException { - if (isDebugEnabled()) { - debugCode("getConnection("+quote(user)+", \"\");"); - } - return getJdbcConnection(user, convertToCharArray(password)); - } - - private JdbcConnection getJdbcConnection(String user, char[] password) throws SQLException { - if (isDebugEnabled()) { - debugCode("getJdbcConnection("+quote(user)+", new char[0]);"); - } - Properties info = new Properties(); - info.setProperty("user", user); - info.put("password", password); - return new JdbcConnection(url, info); - } - - /** - * Get the current URL. - * - * @return the URL - */ - public String getURL() { - debugCodeCall("getURL"); - return url; - } - - /** - * Set the current URL. - * - * @param url the new URL - */ - public void setURL(String url) { - debugCodeCall("setURL", url); - this.url = url; - } - - /** - * Set the current password. - * - * @param password the new password. - */ - public void setPassword(String password) { - debugCodeCall("setPassword", ""); - this.passwordChars = convertToCharArray(password); - } - - /** - * Set the current password in the form of a char array. - * - * @param password the new password in the form of a char array. - */ - public void setPasswordChars(char[] password) { - if (isDebugEnabled()) { - debugCode("setPasswordChars(new char[0]);"); - } - this.passwordChars = password; - } - - private char[] convertToCharArray(String s) { - return s == null ? null : s.toCharArray(); - } - - private String convertToString(char[] a) { - return a == null ? null : new String(a); - } - - /** - * Get the current password. - * - * @return the password - */ - public String getPassword() { - debugCodeCall("getPassword"); - return convertToString(passwordChars); - } - - /** - * Get the current user name. - * - * @return the user name - */ - public String getUser() { - debugCodeCall("getUser"); - return userName; - } - - /** - * Set the current user name. - * - * @param user the new user name - */ - public void setUser(String user) { - debugCodeCall("setUser", user); - this.userName = user; - } - - /** - * Get the current description. - * - * @return the description - */ - public String getDescription() { - debugCodeCall("getDescription"); - return description; - } - - /** - * Set the description. - * - * @param description the new description - */ - public void setDescription(String description) { - debugCodeCall("getDescription", description); - this.description = description; - } - - /** - * Get a new reference for this object, using the current settings. - * - * @return the new reference - */ -//## Java 1.4 begin ## - public Reference getReference() { - debugCodeCall("getReference"); - String factoryClassName = JdbcDataSourceFactory.class.getName(); - Reference ref = new Reference(getClass().getName(), factoryClassName, null); - ref.add(new StringRefAddr("url", url)); - ref.add(new StringRefAddr("user", userName)); - ref.add(new StringRefAddr("password", convertToString(passwordChars))); - ref.add(new StringRefAddr("loginTimeout", String.valueOf(loginTimeout))); - ref.add(new StringRefAddr("description", description)); - return ref; - } -//## Java 1.4 end ## - - /** - * Open a new XA connection using the current URL, user name and password. - * - * @return the connection - */ -//## Java 1.4 begin ## - public XAConnection getXAConnection() throws SQLException { - debugCodeCall("getXAConnection"); - int id = getNextId(XA_DATA_SOURCE); - return new JdbcXAConnection(factory, id, url, userName, passwordChars); - } -//## Java 1.4 end ## - - /** - * Open a new XA connection using the current URL and the specified user - * name and password. - * - * @param user the user name - * @param password the password - * @return the connection - */ -//## Java 1.4 begin ## - public XAConnection getXAConnection(String user, String password) throws SQLException { - if (isDebugEnabled()) { - debugCode("getXAConnection("+quote(user)+", \"\");"); - } - int id = getNextId(XA_DATA_SOURCE); - return new JdbcXAConnection(factory, id, url, user, convertToCharArray(password)); - } -//## Java 1.4 end ## - - /** - * Open a new pooled connection using the current URL, user name and password. - * - * @return the connection - */ -//## Java 1.4 begin ## - public PooledConnection getPooledConnection() throws SQLException { - debugCodeCall("getPooledConnection"); - return getXAConnection(); - } -//## Java 1.4 end ## - - /** - * Open a new pooled connection using the current URL and the specified user - * name and password. - * - * @param user the user name - * @param password the password - * @return the connection - */ -//## Java 1.4 begin ## - public PooledConnection getPooledConnection(String user, String password) throws SQLException { - if (isDebugEnabled()) { - debugCode("getPooledConnection("+quote(user)+", \"\");"); - } - return getXAConnection(user, password); - } -//## Java 1.4 end ## - - /** - * [Not supported] Return an object of this class if possible. - * - * @param iface the class - */ -/*## Java 1.6 begin ## - public T unwrap(Class iface) throws SQLException { - throw unsupported("unwrap"); - } -## Java 1.6 end ##*/ - - /** - * [Not supported] Checks if unwrap can return an object of this class. - * - * @param iface the class - */ -/*## Java 1.6 begin ## - public boolean isWrapperFor(Class< ? > iface) throws SQLException { - throw unsupported("isWrapperFor"); - } -## Java 1.6 end ##*/ - - /** - * INTERNAL - */ - public String toString() { - return getTraceObjectName() + ": url=" + url + " user=" + userName; - } - -} diff --git a/tools/h2/src/main/org/h2/jdbcx/JdbcDataSourceFactory.java b/tools/h2/src/main/org/h2/jdbcx/JdbcDataSourceFactory.java deleted file mode 100755 index b8f46b8..0000000 --- a/tools/h2/src/main/org/h2/jdbcx/JdbcDataSourceFactory.java +++ /dev/null @@ -1,95 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.jdbcx; - -import java.util.Hashtable; - -//## Java 1.4 begin ## -import javax.naming.Context; -import javax.naming.Name; -import javax.naming.Reference; -import javax.naming.spi.ObjectFactory; -//## Java 1.4 end ## - -import org.h2.constant.SysProperties; -import org.h2.engine.Constants; -import org.h2.message.Trace; -import org.h2.message.TraceSystem; - -/** - * This class is used to create new DataSource objects. - * An application should not use this class directly. - */ -public class JdbcDataSourceFactory -//## Java 1.4 begin ## -implements ObjectFactory -//## Java 1.4 end ## -{ - - private static TraceSystem cachedTraceSystem; - private Trace trace; - - static { - org.h2.Driver.load(); - } - - /** - * The public constructor to create new factory objects. - */ - public JdbcDataSourceFactory() { - trace = getTraceSystem().getTrace("JDBCX"); - } - - /** - * Creates a new object using the specified location or reference - * information. - * - * @param obj the reference (this factory only supports objects of type - * javax.naming.Reference) - * @param name unused - * @param nameCtx unused - * @param environment unused - * @return the new JdbcDataSource, or null if the reference class name is - * not JdbcDataSource. - */ -//## Java 1.4 begin ## - public synchronized Object getObjectInstance(Object obj, Name name, Context nameCtx, Hashtable< ? , ? > environment) { - if (trace.isDebugEnabled()) { - trace.debug("getObjectInstance obj=" + obj + " name=" + name + " nameCtx=" + nameCtx + " environment=" + environment); - } - if (obj instanceof Reference) { - Reference ref = (Reference) obj; - if (ref.getClassName().equals(JdbcDataSource.class.getName())) { - JdbcDataSource dataSource = new JdbcDataSource(); - dataSource.setURL((String) ref.get("url").getContent()); - dataSource.setUser((String) ref.get("user").getContent()); - dataSource.setPassword((String) ref.get("password").getContent()); - dataSource.setDescription((String) ref.get("description").getContent()); - String s = (String) ref.get("loginTimeout").getContent(); - dataSource.setLoginTimeout(Integer.parseInt(s)); - return dataSource; - } - } - return null; - } -//## Java 1.4 end ## - - private TraceSystem getTraceSystem() { - synchronized (JdbcDataSourceFactory.class) { - if (cachedTraceSystem == null) { - cachedTraceSystem = new TraceSystem(SysProperties.CLIENT_TRACE_DIRECTORY + "h2datasource" + Constants.SUFFIX_TRACE_FILE); - cachedTraceSystem.setLevelFile(SysProperties.DATASOURCE_TRACE_LEVEL); - } - return cachedTraceSystem; - } - } - - Trace getTrace() { - return trace; - } - -} diff --git a/tools/h2/src/main/org/h2/jdbcx/JdbcXAConnection.java b/tools/h2/src/main/org/h2/jdbcx/JdbcXAConnection.java deleted file mode 100755 index 32de7db..0000000 --- a/tools/h2/src/main/org/h2/jdbcx/JdbcXAConnection.java +++ /dev/null @@ -1,540 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.jdbcx; - -//## Java 1.4 begin ## -import java.sql.Connection; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.sql.Statement; -import java.util.ArrayList; -import java.util.Properties; -import javax.sql.ConnectionEvent; -import javax.sql.ConnectionEventListener; -import javax.sql.XAConnection; -import javax.transaction.xa.XAException; -import javax.transaction.xa.XAResource; -import javax.transaction.xa.Xid; -import org.h2.constant.ErrorCode; -import org.h2.constant.SysProperties; -import org.h2.jdbc.JdbcConnection; -import org.h2.util.Utils; -import org.h2.util.JdbcUtils; -import org.h2.util.New; -import org.h2.util.StringUtils; -//## Java 1.4 end ## - -import org.h2.message.DbException; -import org.h2.message.Trace; -import org.h2.message.TraceObject; - -/*## Java 1.6 begin ## -import javax.sql.StatementEventListener; -## Java 1.6 end ##*/ - -/** - * This class provides support for distributed transactions. - * An application developer usually does not use this interface. - * It is used by the transaction manager internally. - */ -public class JdbcXAConnection extends TraceObject -//## Java 1.4 begin ## -implements XAConnection, XAResource -//## Java 1.4 end ## -{ - -//## Java 1.4 begin ## - private static int nextTransactionId; - - private JdbcDataSourceFactory factory; - private String url, user; - - // This connection is kept open as long as the XAConnection is alive - private JdbcConnection physicalConn; - - // This connection is replaced whenever getConnection is called - private volatile PooledJdbcConnection handleConn; - private ArrayList listeners = New.arrayList(); - private Xid currentTransaction; - private int currentTransactionId; - - static { - org.h2.Driver.load(); - } - - JdbcXAConnection(JdbcDataSourceFactory factory, int id, String url, String user, char[] password) throws SQLException { - this.factory = factory; - setTrace(factory.getTrace(), TraceObject.XA_DATA_SOURCE, id); - this.url = url; - this.user = user; - Properties info = new Properties(); - info.setProperty("user", user); - info.put("password", StringUtils.cloneCharArray(password)); - physicalConn = new JdbcConnection(url, info); - } -//## Java 1.4 end ## - - /** - * Get the XAResource object. - * - * @return itself - */ -//## Java 1.4 begin ## - public XAResource getXAResource() { - debugCodeCall("getXAResource"); - return this; - } -//## Java 1.4 end ## - - /** - * Close the physical connection. - * This method is usually called by the connection pool. - * - * @throws SQLException - */ -//## Java 1.4 begin ## - public void close() throws SQLException { - debugCodeCall("close"); - PooledJdbcConnection lastHandle = handleConn; - if (lastHandle != null) { - listeners.clear(); - lastHandle.close(); - } - if (physicalConn != null) { - try { - physicalConn.close(); - } finally { - physicalConn = null; - } - } - } -//## Java 1.4 end ## - - /** - * Get a connection that is a handle to the physical connection. This method - * is usually called by the connection pool. This method closes the last - * connection handle if one exists. - * - * @return the connection - */ -//## Java 1.4 begin ## - public Connection getConnection() throws SQLException { - debugCodeCall("getConnection"); - PooledJdbcConnection lastHandle = handleConn; - if (lastHandle != null) { - lastHandle.close(); - } - handleConn = new PooledJdbcConnection(physicalConn); - return handleConn; - } -//## Java 1.4 end ## - - /** - * Register a new listener for the connection. - * - * @param listener the event listener - */ -//## Java 1.4 begin ## - public void addConnectionEventListener(ConnectionEventListener listener) { - debugCode("addConnectionEventListener(listener);"); - listeners.add(listener); - } -//## Java 1.4 end ## - - /** - * Remove the event listener. - * - * @param listener the event listener - */ -//## Java 1.4 begin ## - public void removeConnectionEventListener(ConnectionEventListener listener) { - debugCode("removeConnectionEventListener(listener);"); - listeners.remove(listener); - } -//## Java 1.4 end ## - - /** - * INTERNAL - */ -//## Java 1.4 begin ## - void closedHandle() { - debugCode("closedHandle();"); - for (ConnectionEventListener listener : New.arrayList(listeners)) { - ConnectionEvent event = new ConnectionEvent(this); - listener.connectionClosed(event); - } - handleConn = null; - } -//## Java 1.4 end ## - - /** - * Get the transaction timeout. - * - * @return 0 - */ -//## Java 1.4 begin ## - public int getTransactionTimeout() { - debugCodeCall("getTransactionTimeout"); - return 0; - } -//## Java 1.4 end ## - - /** - * Set the transaction timeout. - * - * @param seconds ignored - * @return false - */ -//## Java 1.4 begin ## - public boolean setTransactionTimeout(int seconds) { - debugCodeCall("setTransactionTimeout", seconds); - return false; - } -//## Java 1.4 end ## - - /** - * Checks if this is the same XAResource. - * - * @param xares the other object - * @return true if this is the same object - */ -//## Java 1.4 begin ## - public boolean isSameRM(XAResource xares) { - debugCode("isSameRM(xares);"); - return xares == this; - } -//## Java 1.4 end ## - - /** - * Get the list of prepared transaction branches. - * This method is called by the transaction manager during recovery. - * - * @param flag TMSTARTRSCAN, TMENDRSCAN, or TMNOFLAGS. If no other flags are set, - * TMNOFLAGS must be used. - * @return zero or more Xid objects - * @throws XAException - */ -//## Java 1.4 begin ## - public Xid[] recover(int flag) throws XAException { - debugCodeCall("recover", quoteFlags(flag)); - checkOpen(); - Statement stat = null; - try { - stat = physicalConn.createStatement(); - ResultSet rs = stat.executeQuery("SELECT * FROM INFORMATION_SCHEMA.IN_DOUBT ORDER BY TRANSACTION"); - ArrayList list = New.arrayList(); - while (rs.next()) { - String tid = rs.getString("TRANSACTION"); - int id = getNextId(XID); - Xid xid = new JdbcXid(factory, id, tid); - list.add(xid); - } - rs.close(); - Xid[] result = new Xid[list.size()]; - list.toArray(result); - return result; - } catch (SQLException e) { - XAException xa = new XAException(XAException.XAER_RMERR); - xa.initCause(e); - throw xa; - } finally { - JdbcUtils.closeSilently(stat); - } - } -//## Java 1.4 end ## - - /** - * Prepare a transaction. - * - * @param xid the transaction id - * @return XA_OK - * @throws XAException - */ -//## Java 1.4 begin ## - public int prepare(Xid xid) throws XAException { - if (isDebugEnabled()) { - debugCode("prepare("+quoteXid(xid)+");"); - } - checkOpen(); - if (!currentTransaction.equals(xid)) { - throw new XAException(XAException.XAER_INVAL); - } - Statement stat = null; - try { - stat = physicalConn.createStatement(); - currentTransactionId = nextTransactionId++; - stat.execute("PREPARE COMMIT TX_" + currentTransactionId); - } catch (SQLException e) { - throw convertException(e); - } finally { - JdbcUtils.closeSilently(stat); - } - return XA_OK; - } -//## Java 1.4 end ## - - /** - * Forget a transaction. - * This method does not have an effect for this database. - * - * @param xid the transaction id - */ -//## Java 1.4 begin ## - public void forget(Xid xid) { - if (isDebugEnabled()) { - debugCode("forget("+quoteXid(xid)+");"); - } - } -//## Java 1.4 end ## - - /** - * Roll back a transaction. - * - * @param xid the transaction id - * @throws XAException - */ -//## Java 1.4 begin ## - public void rollback(Xid xid) throws XAException { - if (isDebugEnabled()) { - debugCode("rollback("+quoteXid(xid)+");"); - } - try { - physicalConn.rollback(); - } catch (SQLException e) { - throw convertException(e); - } - currentTransaction = null; - } -//## Java 1.4 end ## - - /** - * End a transaction. - * - * @param xid the transaction id - * @param flags TMSUCCESS, TMFAIL, or TMSUSPEND - * @throws XAException - */ -//## Java 1.4 begin ## - public void end(Xid xid, int flags) throws XAException { - if (isDebugEnabled()) { - debugCode("end("+quoteXid(xid)+", "+quoteFlags(flags)+");"); - } - // TODO transaction end: implement this method - if (flags == TMSUSPEND) { - return; - } - if (!currentTransaction.equals(xid)) { - throw new XAException(XAException.XAER_OUTSIDE); - } - } -//## Java 1.4 end ## - - /** - * Start or continue to work on a transaction. - * - * @param xid the transaction id - * @param flags TMNOFLAGS, TMJOIN, or TMRESUME - * @throws XAException - */ -//## Java 1.4 begin ## - public void start(Xid xid, int flags) throws XAException { - if (isDebugEnabled()) { - debugCode("start("+quoteXid(xid)+", "+quoteFlags(flags)+");"); - } - if (flags == TMRESUME) { - return; - } - if (flags == TMJOIN) { - if (currentTransaction != null && !currentTransaction.equals(xid)) { - throw new XAException(XAException.XAER_RMERR); - } - } else if (currentTransaction != null) { - throw new XAException(XAException.XAER_NOTA); - } - try { - physicalConn.setAutoCommit(false); - } catch (SQLException e) { - throw convertException(e); - } - currentTransaction = xid; - } -//## Java 1.4 end ## - - /** - * Commit a transaction. - * - * @param xid the transaction id - * @param onePhase use a one-phase protocol if true - * @throws XAException - */ -//## Java 1.4 begin ## - public void commit(Xid xid, boolean onePhase) throws XAException { - if (isDebugEnabled()) { - debugCode("commit("+quoteXid(xid)+", "+onePhase+");"); - } - Statement stat = null; - try { - if (onePhase) { - physicalConn.commit(); - } else { - stat = physicalConn.createStatement(); - stat.execute("COMMIT TRANSACTION TX_" + currentTransactionId); - } - } catch (SQLException e) { - throw convertException(e); - } finally { - JdbcUtils.closeSilently(stat); - } - currentTransaction = null; - } -//## Java 1.4 end ## - - /** - * [Not supported] Add a statement event listener. - * - * @param listener the new statement event listener - */ -/*## Java 1.6 begin ## - public void addStatementEventListener(StatementEventListener listener) { - throw new UnsupportedOperationException(); - } -## Java 1.6 end ##*/ - - /** - * [Not supported] Remove a statement event listener. - * - * @param listener the statement event listener - */ -/*## Java 1.6 begin ## - public void removeStatementEventListener(StatementEventListener listener) { - throw new UnsupportedOperationException(); - } -## Java 1.6 end ##*/ - - /** - * INTERNAL - */ -//## Java 1.4 begin ## - public String toString() { - return getTraceObjectName() + ": url=" + url + " user=" + user; - } - - private XAException convertException(SQLException e) { - XAException xa = new XAException(e.getMessage()); - xa.initCause(e); - return xa; - } - - private String quoteXid(Xid xid) { - StringBuilder buff = new StringBuilder(); - buff.append("\"f:"). - append(xid.getFormatId()). - append(",bq:"). - append(Utils.convertBytesToString(xid.getBranchQualifier())). - append(",gx:"). - append(Utils.convertBytesToString(xid.getGlobalTransactionId())). - append(",c:"). - append(xid.getClass().getName()). - append("\""); - return buff.toString(); - } - - private String quoteFlags(int flags) { - StringBuilder buff = new StringBuilder(); - if ((flags & XAResource.TMENDRSCAN) != 0) { - buff.append("|XAResource.TMENDRSCAN"); - } - if ((flags & XAResource.TMFAIL) != 0) { - buff.append("|XAResource.TMFAIL"); - } - if ((flags & XAResource.TMJOIN) != 0) { - buff.append("|XAResource.TMJOIN"); - } - if ((flags & XAResource.TMONEPHASE) != 0) { - buff.append("|XAResource.TMONEPHASE"); - } - if ((flags & XAResource.TMRESUME) != 0) { - buff.append("|XAResource.TMRESUME"); - } - if ((flags & XAResource.TMSTARTRSCAN) != 0) { - buff.append("|XAResource.TMSTARTRSCAN"); - } - if ((flags & XAResource.TMSUCCESS) != 0) { - buff.append("|XAResource.TMSUCCESS"); - } - if ((flags & XAResource.TMSUSPEND) != 0) { - buff.append("|XAResource.TMSUSPEND"); - } - if ((flags & XAResource.XA_RDONLY) != 0) { - buff.append("|XAResource.XA_RDONLY"); - } - if (buff.length() == 0) { - buff.append("|XAResource.TMNOFLAGS"); - } - return buff.toString().substring(1); - } - - private void checkOpen() throws XAException { - if (physicalConn == null) { - throw new XAException(XAException.XAER_RMERR); - } - } -//## Java 1.4 end ## - - /** - * A pooled connection. - */ - class PooledJdbcConnection extends JdbcConnection { - - private boolean isClosed; - - public PooledJdbcConnection(JdbcConnection conn) { - super(conn); - openStackTrace = new Exception("Stack Trace"); - } - - public synchronized void close() throws SQLException { - if (!isClosed) { - rollback(); - setAutoCommit(true); - closedHandle(); - isClosed = true; - } - } - - public synchronized boolean isClosed() throws SQLException { - return isClosed || super.isClosed(); - } - - protected synchronized void checkClosed(boolean write) throws SQLException { - if (isClosed) { - throw DbException.get(ErrorCode.OBJECT_CLOSED); - } - super.checkClosed(write); - } - - protected void finalize() { - // don't call super.finalize because - // this should print its own stack trace, - // and would close the connection - if (!SysProperties.runFinalize) { - return; - } - Trace trace = getTrace(); - try { - if (!isClosed()) { - trace.error("Pooled connection not closed", openStackTrace); - JdbcXAConnection.this.close(); - } - } catch (SQLException e) { - trace.debug("finalize", e); - } - } - - } - -} diff --git a/tools/h2/src/main/org/h2/jdbcx/JdbcXid.java b/tools/h2/src/main/org/h2/jdbcx/JdbcXid.java deleted file mode 100755 index d05d557..0000000 --- a/tools/h2/src/main/org/h2/jdbcx/JdbcXid.java +++ /dev/null @@ -1,98 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.jdbcx; - -import java.util.StringTokenizer; -import javax.transaction.xa.Xid; -import org.h2.constant.ErrorCode; -import org.h2.message.DbException; -import org.h2.message.TraceObject; -import org.h2.util.Utils; - -/** - * An object of this class represents a transaction id. - */ -public class JdbcXid extends TraceObject -//## Java 1.4 begin ## -implements Xid -//## Java 1.4 end ## -{ - - private static final String PREFIX = "XID"; - - private int formatId; - private byte[] branchQualifier; - private byte[] globalTransactionId; - - JdbcXid(JdbcDataSourceFactory factory, int id, String tid) { - setTrace(factory.getTrace(), TraceObject.XID, id); - try { - StringTokenizer tokenizer = new StringTokenizer(tid, "_"); - String prefix = tokenizer.nextToken(); - if (!PREFIX.equals(prefix)) { - throw DbException.get(ErrorCode.WRONG_XID_FORMAT_1, tid); - } - formatId = Integer.parseInt(tokenizer.nextToken()); - branchQualifier = Utils.convertStringToBytes(tokenizer.nextToken()); - globalTransactionId = Utils.convertStringToBytes(tokenizer.nextToken()); - } catch (RuntimeException e) { - throw DbException.get(ErrorCode.WRONG_XID_FORMAT_1, tid); - } - } - - /** - * INTERNAL - */ - public String getAsString() { - StringBuilder buff = new StringBuilder(PREFIX); - buff.append('_'). - append(formatId). - append('_'). - append(Utils.convertBytesToString(branchQualifier)). - append('_'). - append(Utils.convertBytesToString(globalTransactionId)); - return buff.toString(); - } - - /** - * Get the format id. - * - * @return the format id - */ - public int getFormatId() { - debugCodeCall("getFormatId"); - return formatId; - } - - /** - * The transaction branch identifier. - * - * @return the identifier - */ - public byte[] getBranchQualifier() { - debugCodeCall("getBranchQualifier"); - return branchQualifier; - } - - /** - * The global transaction identifier. - * - * @return the transaction id - */ - public byte[] getGlobalTransactionId() { - debugCodeCall("getGlobalTransactionId"); - return globalTransactionId; - } - - /** - * INTERNAL - */ - public String toString() { - return getTraceObjectName() + ": " + getAsString(); - } - -} diff --git a/tools/h2/src/main/org/h2/jdbcx/package.html b/tools/h2/src/main/org/h2/jdbcx/package.html deleted file mode 100755 index f4be3f7..0000000 --- a/tools/h2/src/main/org/h2/jdbcx/package.html +++ /dev/null @@ -1,15 +0,0 @@ - - - - -Javadoc package documentation -

- -Implementation of the extended JDBC API (package javax.sql). - -

\ No newline at end of file diff --git a/tools/h2/src/main/org/h2/message/DbException.java b/tools/h2/src/main/org/h2/message/DbException.java deleted file mode 100755 index 1040826..0000000 --- a/tools/h2/src/main/org/h2/message/DbException.java +++ /dev/null @@ -1,350 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.message; - -import java.io.ByteArrayInputStream; -import java.io.IOException; -import java.lang.reflect.InvocationTargetException; -import java.sql.SQLException; -import java.text.MessageFormat; -import java.util.Locale; -import java.util.Properties; -import java.util.Map.Entry; -import org.h2.constant.ErrorCode; -import org.h2.jdbc.JdbcSQLException; -import org.h2.util.SortedProperties; -import org.h2.util.StringUtils; -import org.h2.util.Utils; - -/** - * This exception wraps a checked exception. - * It is used in methods where checked exceptions are not supported, - * for example in a Comparator. - */ -public class DbException extends RuntimeException { - - private static final long serialVersionUID = 1L; - - private static final Properties MESSAGES = new Properties(); - - static { - try { - byte[] messages = Utils.getResource("/org/h2/res/_messages_en.prop"); - if (messages != null) { - MESSAGES.load(new ByteArrayInputStream(messages)); - } - String language = Locale.getDefault().getLanguage(); - if (!"en".equals(language)) { - byte[] translations = Utils.getResource("/org/h2/res/_messages_" + language + ".prop"); - // message: translated message + english - // (otherwise certain applications don't work) - if (translations != null) { - Properties p = SortedProperties.fromLines(new String(translations, "UTF-8")); - for (Entry e : p.entrySet()) { - String key = (String) e.getKey(); - String translation = (String) e.getValue(); - if (translation != null && !translation.startsWith("#")) { - String original = MESSAGES.getProperty(key); - String message = translation + "\n" + original; - MESSAGES.put(key, message); - } - } - } - } - } catch (IOException e) { - TraceSystem.traceThrowable(e); - } - } - - private DbException(SQLException e) { - super(e.getMessage(), e); - } - - private static String translate(String key, String... params) { - String message = null; - if (MESSAGES != null) { - // Tomcat sets final static fields to null sometimes - message = MESSAGES.getProperty(key); - } - if (message == null) { - message = "(Message " + key + " not found)"; - } - if (params != null) { - for (int i = 0; i < params.length; i++) { - String s = params[i]; - if (s != null && s.length() > 0) { - params[i] = StringUtils.quoteIdentifier(s); - } - } - message = MessageFormat.format(message, (Object[]) params); - } - return message; - } - - /** - * Get the SQLException object. - * - * @return the exception - */ - public SQLException getSQLException() { - return (SQLException) getCause(); - } - - /** - * Get the error code. - * - * @return the error code - */ - public int getErrorCode() { - return getSQLException().getErrorCode(); - } - - /** - * Set the SQL statement of the given exception. - * This method may create a new object. - * - * @param sql the SQL statement - * @return the exception - */ - public DbException addSQL(String sql) { - SQLException e = getSQLException(); - if (e instanceof JdbcSQLException) { - JdbcSQLException j = (JdbcSQLException) e; - if (j.getSQL() == null) { - j.setSQL(sql); - } - return this; - } - e = new JdbcSQLException(e.getMessage(), sql, e.getSQLState(), e.getErrorCode(), e, null); - return new DbException(e); - } - - /** - * Create a database exception for a specific error code. - * - * @param errorCode the error code - * @return the exception - */ - public static DbException get(int errorCode) { - return get(errorCode, (String) null); - } - - /** - * Create a database exception for a specific error code. - * - * @param errorCode the error code - * @param p1 the first parameter of the message - * @return the exception - */ - public static DbException get(int errorCode, String p1) { - return get(errorCode, new String[] { p1 }); - } - - /** - * Create a database exception for a specific error code. - * - * @param errorCode the error code - * @param cause the cause of the exception - * @param params the list of parameters of the message - * @return the exception - */ - public static DbException get(int errorCode, Throwable cause, String... params) { - return new DbException(getJdbcSQLException(errorCode, cause, params)); - } - - /** - * Create a database exception for a specific error code. - * - * @param errorCode the error code - * @param params the list of parameters of the message - * @return the exception - */ - public static DbException get(int errorCode, String... params) { - return new DbException(getJdbcSQLException(errorCode, null, params)); - } - - /** - * Create a syntax error exception. - * - * @param sql the SQL statement - * @param index the position of the error in the SQL statement - * @return the exception - */ - public static DbException getSyntaxError(String sql, int index) { - sql = StringUtils.addAsterisk(sql, index); - return get(ErrorCode.SYNTAX_ERROR_1, sql); - } - - /** - * Create a syntax error exception. - * - * @param sql the SQL statement - * @param index the position of the error in the SQL statement - * @param expected the expected keyword at the given position - * @return the exception - */ - public static DbException getSyntaxError(String sql, int index, String expected) { - sql = StringUtils.addAsterisk(sql, index); - return get(ErrorCode.SYNTAX_ERROR_2, sql, expected); - } - - /** - * Gets a SQL exception meaning this feature is not supported. - * - * @param message what exactly is not supported - * @return the exception - */ - public static DbException getUnsupportedException(String message) { - return get(ErrorCode.FEATURE_NOT_SUPPORTED_1, message); - } - - /** - * Gets a SQL exception meaning this value is invalid. - * - * @param value the value passed - * @param param the name of the parameter - * @return the IllegalArgumentException object - */ - public static DbException getInvalidValueException(String value, String param) { - return get(ErrorCode.INVALID_VALUE_2, value, param); - } - - /** - * Throw an internal error. This method seems to return an exception object, - * so that it can be used instead of 'return', but in fact it always throws - * the exception. - * - * @param s the message - * @return the RuntimeException object - * @throws RuntimeException the exception - */ - public static RuntimeException throwInternalError(String s) { - RuntimeException e = new RuntimeException(s); - TraceSystem.traceThrowable(e); - throw e; - } - - /** - * Throw an internal error. This method seems to return an exception object, - * so that it can be used instead of 'return', but in fact it always throws - * the exception. - * - * @return the RuntimeException object - */ - public static RuntimeException throwInternalError() { - return throwInternalError("Unexpected code path"); - } - - /** - * Convert an exception to a SQL exception using the default mapping. - * - * @param e the root cause - * @return the SQL exception object - */ - public static SQLException toSQLException(Exception e) { - if (e instanceof SQLException) { - return (SQLException) e; - } - return convert(e).getSQLException(); - } - - /** - * Convert a throwable to an SQL exception using the default mapping. All - * errors except the following are re-thrown: StackOverflowError, - * LinkageError. - * - * @param e the root cause - * @return the exception object - */ - public static DbException convert(Throwable e) { - if (e instanceof DbException) { - return (DbException) e; - } else if (e instanceof SQLException) { - return new DbException((SQLException) e); - } else if (e instanceof InvocationTargetException) { - return convertInvocation((InvocationTargetException) e, null); - } else if (e instanceof IOException) { - return get(ErrorCode.IO_EXCEPTION_1, e, e.toString()); - } else if (e instanceof OutOfMemoryError) { - return get(ErrorCode.OUT_OF_MEMORY, e); - } else if (e instanceof StackOverflowError || e instanceof LinkageError) { - return get(ErrorCode.GENERAL_ERROR_1, e, e.toString()); - } else if (e instanceof Error) { - throw (Error) e; - } - return get(ErrorCode.GENERAL_ERROR_1, e, e.toString()); - } - - /** - * Convert an InvocationTarget exception to a database exception. - * - * @param te the root cause - * @param message the added message or null - * @return the database exception object - */ - public static DbException convertInvocation(InvocationTargetException te, String message) { - Throwable t = te.getTargetException(); - if (t instanceof SQLException || t instanceof DbException) { - return convert(t); - } - message = message == null ? t.getMessage() : message + ": " + t.getMessage(); - return get(ErrorCode.EXCEPTION_IN_FUNCTION_1, t, message); - } - - /** - * Convert an IO exception to a database exception. - * - * @param e the root cause - * @param message the message or null - * @return the database exception object - */ - public static DbException convertIOException(IOException e, String message) { - if (message == null) { - Throwable t = e.getCause(); - if (t != null && t instanceof DbException) { - return (DbException) t; - } - return get(ErrorCode.IO_EXCEPTION_1, e, e.toString()); - } - return get(ErrorCode.IO_EXCEPTION_2, e, e.toString(), message); - } - - /** - * Gets the SQL exception object for a specific error code. - * - * @param errorCode the error code - * @param cause the cause of the exception - * @param params the list of parameters of the message - * @return the SQLException object - */ - private static JdbcSQLException getJdbcSQLException(int errorCode, Throwable cause, String... params) { - String sqlstate = ErrorCode.getState(errorCode); - String message = translate(sqlstate, params); - return new JdbcSQLException(message, null, sqlstate, errorCode, cause, null); - } - - /** - * Convert an exception to an IO exception. - * - * @param e the root cause - * @return the IO exception - */ - public static IOException convertToIOException(Throwable e) { - if (e instanceof JdbcSQLException) { - JdbcSQLException e2 = (JdbcSQLException) e; - if (e2.getOriginalCause() != null) { - e = e2.getOriginalCause(); - } - } - IOException io = new IOException(e.toString()); - //## Java 1.4 begin ## - io.initCause(e); - //## Java 1.4 end ## - return io; - } - -} diff --git a/tools/h2/src/main/org/h2/message/Trace.java b/tools/h2/src/main/org/h2/message/Trace.java deleted file mode 100755 index d455c70..0000000 --- a/tools/h2/src/main/org/h2/message/Trace.java +++ /dev/null @@ -1,272 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.message; - -import org.h2.constant.SysProperties; -import org.h2.util.StringUtils; - -/** - * This class represents a trace module. - */ -public class Trace { - - /** - * The trace module name for commands. - */ - public static final String COMMAND = "command"; - - /** - * The trace module name for constraints. - */ - public static final String CONSTRAINT = "constraint"; - - /** - * The trace module name for databases. - */ - public static final String DATABASE = "database"; - - /** - * The trace module name for functions. - */ - public static final String FUNCTION = "function"; - - /** - * The trace module name for file locks. - */ - public static final String FILE_LOCK = "fileLock"; - - /** - * The trace module name for indexes. - */ - public static final String INDEX = "index"; - - /** - * The trace module name for the JDBC API. - */ - public static final String JDBC = "jdbc"; - - /** - * The trace module name for locks. - */ - public static final String LOCK = "lock"; - - /** - * The trace module name for the transaction log. - */ - public static final String LOG = "log"; - - /** - * The trace module name for schemas. - */ - public static final String SCHEMA = "schema"; - - /** - * The trace module name for sessions. - */ - public static final String SESSION = "session"; - - /** - * The trace module name for sequences. - */ - public static final String SEQUENCE = "sequence"; - - /** - * The trace module name for settings. - */ - public static final String SETTING = "setting"; - - /** - * The trace module name for tables. - */ - public static final String TABLE = "table"; - - /** - * The trace module name for triggers. - */ - public static final String TRIGGER = "trigger"; - - /** - * The trace module name for users. - */ - public static final String USER = "user"; - - /** - * The trace module name for the page store. - */ - public static final String PAGE_STORE = "pageStore"; - - private TraceWriter traceWriter; - private String module; - private String lineSeparator; - private int traceLevel = TraceSystem.PARENT; - - Trace(TraceWriter traceWriter, String module) { - this.traceWriter = traceWriter; - this.module = module; - this.lineSeparator = SysProperties.LINE_SEPARATOR; - } - - /** - * Set the trace level of this component. This setting overrides the parent - * trace level. - * - * @param level the new level - */ - public void setLevel(int level) { - this.traceLevel = level; - } - - private boolean isEnabled(int level) { - if (this.traceLevel == TraceSystem.PARENT) { - return traceWriter.isEnabled(level); - } - return level <= this.traceLevel; - } - - /** - * Check if the trace level is equal or higher than INFO. - * - * @return true if it is - */ - public boolean isInfoEnabled() { - return isEnabled(TraceSystem.INFO); - } - - /** - * Check if the trace level is equal or higher than DEBUG. - * - * @return true if it is - */ - public boolean isDebugEnabled() { - return isEnabled(TraceSystem.DEBUG); - } - - /** - * Write a message with trace level ERROR to the trace system. - * - * @param s the message - * @param t the exception - */ - public void error(String s, Throwable t) { - if (isEnabled(TraceSystem.ERROR)) { - traceWriter.write(TraceSystem.ERROR, module, s, t); - } - } - - /** - * Write a message with trace level INFO to the trace system. - * - * @param s the message - */ - public void info(String s) { - if (isEnabled(TraceSystem.INFO)) { - traceWriter.write(TraceSystem.INFO, module, s, null); - } - } - - /** - * Write a message with trace level INFO to the trace system. - * - * @param s the message - * @param t the exception - */ - void info(String s, Throwable t) { - if (isEnabled(TraceSystem.INFO)) { - traceWriter.write(TraceSystem.INFO, module, s, t); - } - } - - /** - * Write a SQL statement with trace level INFO to the trace system. - * - * @param sql the SQL statement - * @param params the parameters used, in the for {1:...} - * @param count the update count - * @param time the time it took to run the statement in ms - */ - public void infoSQL(String sql, String params, int count, long time) { - if (!isEnabled(TraceSystem.INFO)) { - return; - } - StringBuilder buff = new StringBuilder(sql.length() + params.length() + 20); - buff.append(lineSeparator).append("/*SQL"); - boolean space = false; - if (params.length() > 0) { - // This looks like a bug, but it is intentional: - // If there are no parameters, the SQL statement is - // the rest of the line. If there are parameters, they - // are appended at the end of the line. Knowing the size - // of the statement simplifies separating the SQL statement - // from the parameters (no need to parse). - space = true; - buff.append(" l:").append(sql.length()); - } - if (count > 0) { - space = true; - buff.append(" #:").append(count); - } - if (time > 0) { - space = true; - buff.append(" t:").append(time); - } - if (!space) { - buff.append(' '); - } - buff.append("*/"). - append(StringUtils.javaEncode(sql)). - append(StringUtils.javaEncode(params)). - append(';'); - sql = buff.toString(); - traceWriter.write(TraceSystem.INFO, module, sql, null); - } - - /** - * Write a message with trace level DEBUG to the trace system. - * - * @param s the message - */ - public void debug(String s) { - if (isEnabled(TraceSystem.DEBUG)) { - traceWriter.write(TraceSystem.DEBUG, module, s, null); - } - } - - /** - * Write a message with trace level DEBUG to the trace system. - * - * @param s the message - * @param t the exception - */ - public void debug(String s, Throwable t) { - if (isEnabled(TraceSystem.DEBUG)) { - traceWriter.write(TraceSystem.DEBUG, module, s, t); - } - } - - /** - * Write Java source code with trace level INFO to the trace system. - * - * @param java the source code - */ - public void infoCode(String java) { - if (isEnabled(TraceSystem.INFO)) { - traceWriter.write(TraceSystem.INFO, module, lineSeparator + "/**/" + java, null); - } - } - - /** - * Write Java source code with trace level DEBUG to the trace system. - * - * @param java the source code - */ - void debugCode(String java) { - if (isEnabled(TraceSystem.DEBUG)) { - traceWriter.write(TraceSystem.DEBUG, module, lineSeparator + "/**/" + java, null); - } - } - -} diff --git a/tools/h2/src/main/org/h2/message/TraceObject.java b/tools/h2/src/main/org/h2/message/TraceObject.java deleted file mode 100755 index c87b8f7..0000000 --- a/tools/h2/src/main/org/h2/message/TraceObject.java +++ /dev/null @@ -1,458 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.message; - -import java.io.PrintWriter; -import java.io.Writer; -import java.math.BigDecimal; -import java.sql.SQLException; -import java.util.ArrayList; -import java.util.Map; -import org.h2.constant.SysProperties; -import org.h2.expression.ParameterInterface; -import org.h2.util.Utils; -import org.h2.util.IOUtils; -import org.h2.util.StatementBuilder; -import org.h2.util.StringUtils; - -/** - * The base class for objects that can print trace information about themselves. - */ -public class TraceObject { - - /** - * The trace type id for callable statements. - */ - protected static final int CALLABLE_STATEMENT = 0; - - /** - * The trace type id for connections. - */ - protected static final int CONNECTION = 1; - - /** - * The trace type id for database meta data objects. - */ - protected static final int DATABASE_META_DATA = 2; - - /** - * The trace type id for prepared statements. - */ - protected static final int PREPARED_STATEMENT = 3; - - /** - * The trace type id for result sets. - */ - protected static final int RESULT_SET = 4; - - /** - * The trace type id for result set meta data objects. - */ - protected static final int RESULT_SET_META_DATA = 5; - - /** - * The trace type id for savepoint objects. - */ - protected static final int SAVEPOINT = 6; - - /** - * The trace type id for sql exceptions. - */ - protected static final int SQL_EXCEPTION = 7; - - /** - * The trace type id for statements. - */ - protected static final int STATEMENT = 8; - - /** - * The trace type id for blobs. - */ - protected static final int BLOB = 9; - - /** - * The trace type id for clobs. - */ - protected static final int CLOB = 10; - - /** - * The trace type id for parameter meta data objects. - */ - protected static final int PARAMETER_META_DATA = 11; - - /** - * The trace type id for data sources. - */ - protected static final int DATA_SOURCE = 12; - - /** - * The trace type id for XA data sources. - */ - protected static final int XA_DATA_SOURCE = 13; - - /** - * The trace type id for transaction ids. - */ - protected static final int XID = 14; - - /** - * The trace type id for array objects. - */ - protected static final int ARRAY = 15; - - private static final int LAST = ARRAY + 1; - private static final int[] ID = new int[LAST]; - private static final String[] PREFIX = { - "call", "conn", "dbMeta", "prep", "rs", "rsMeta", "sp", "ex", "stat", "blob", "clob", "pMeta", - "ds", "xads", "xid", "ar" - }; - - private Trace trace; - private int traceType; - private int id; - - /** - * Set the options to use when writing trace message. - * - * @param trace the trace object - * @param type the trace object type - * @param id the trace object id - */ - protected void setTrace(Trace trace, int type, int id) { - this.trace = trace; - this.traceType = type; - this.id = id; - } - - /** - * Update the trace object. - * - * @param trace the trace object - */ - protected void setTrace(Trace trace) { - this.trace = trace; - } - - /** - * Get the trace object. - * - * @return the trace object - */ - protected Trace getTrace() { - return trace; - } - - /** - * INTERNAL - */ - public int getTraceId() { - return id; - } - - /** - * INTERNAL - */ - public String getTraceObjectName() { - return PREFIX[traceType] + id; - } - - /** - * Get the next trace object id for this object type. - * - * @param type the object type - * @return the new trace object id - */ - protected int getNextId(int type) { - return ID[type]++; - } - - /** - * Check if the debug trace level is enabled. - * - * @return true if it is - */ - protected boolean isDebugEnabled() { - return trace.isDebugEnabled(); - } - - /** - * Check if info trace level is enabled. - * - * @return true if it is - */ - protected boolean isInfoEnabled() { - return trace.isInfoEnabled(); - } - - /** - * Write trace information as an assignment in the form - * className prefixId = objectName.value. - * - * @param className the class name of the result - * @param newType the prefix type - * @param newId the trace object id of the created object - * @param value the value to assign this new object to - */ - protected void debugCodeAssign(String className, int newType, int newId, String value) { - if (trace.isDebugEnabled()) { - trace.debugCode(className + " " + PREFIX[newType] + newId + " = " + getTraceObjectName() + "." + value + ";"); - } - } - - /** - * Write trace information as a method call in the form - * objectName.methodName(). - * - * @param methodName the method name - */ - protected void debugCodeCall(String methodName) { - if (trace.isDebugEnabled()) { - trace.debugCode(getTraceObjectName() + "." + methodName + "();"); - } - } - - /** - * Write trace information as a method call in the form - * objectName.methodName(param) where the parameter is formatted as a long - * value. - * - * @param methodName the method name - * @param param one single long parameter - */ - protected void debugCodeCall(String methodName, long param) { - if (trace.isDebugEnabled()) { - trace.debugCode(getTraceObjectName() + "." + methodName + "(" + param + ");"); - } - } - - /** - * Write trace information as a method call in the form - * objectName.methodName(param) where the parameter is formatted as a Java - * string. - * - * @param methodName the method name - * @param param one single string parameter - */ - protected void debugCodeCall(String methodName, String param) { - if (trace.isDebugEnabled()) { - trace.debugCode(getTraceObjectName() + "." + methodName + "(" + quote(param) + ");"); - } - } - - /** - * Write trace information in the form objectName.text. - * - * @param text the trace text - */ - protected void debugCode(String text) { - if (trace.isDebugEnabled()) { - trace.debugCode(getTraceObjectName() + "." + text); - } - } - - /** - * Format a string as a Java string literal. - * - * @param s the string to convert - * @return the Java string literal - */ - protected String quote(String s) { - return StringUtils.quoteJavaString(s); - } - - /** - * Format a time to the Java source code that represents this object. - * - * @param x the time to convert - * @return the Java source code - */ - protected String quoteTime(java.sql.Time x) { - if (x == null) { - return "null"; - } - return "Time.valueOf(\"" + x.toString() + "\")"; - } - - /** - * Format a timestamp to the Java source code that represents this object. - * - * @param x the timestamp to convert - * @return the Java source code - */ - protected String quoteTimestamp(java.sql.Timestamp x) { - if (x == null) { - return "null"; - } - return "Timestamp.valueOf(\"" + x.toString() + "\")"; - } - - /** - * Format a date to the Java source code that represents this object. - * - * @param x the date to convert - * @return the Java source code - */ - protected String quoteDate(java.sql.Date x) { - if (x == null) { - return "null"; - } - return "Date.valueOf(\"" + x.toString() + "\")"; - } - - /** - * Format a big decimal to the Java source code that represents this object. - * - * @param x the big decimal to convert - * @return the Java source code - */ - protected String quoteBigDecimal(BigDecimal x) { - if (x == null) { - return "null"; - } - return "new BigDecimal(\"" + x.toString() + "\")"; - } - - /** - * Format a byte array to the Java source code that represents this object. - * - * @param x the byte array to convert - * @return the Java source code - */ - protected String quoteBytes(byte[] x) { - if (x == null) { - return "null"; - } - return "org.h2.util.Utils.convertStringToBytes(\"" + Utils.convertBytesToString(x) + "\")"; - } - - /** - * Format a string array to the Java source code that represents this - * object. - * - * @param s the string array to convert - * @return the Java source code - */ - protected String quoteArray(String[] s) { - return StringUtils.quoteJavaStringArray(s); - } - - /** - * Format an int array to the Java source code that represents this object. - * - * @param s the int array to convert - * @return the Java source code - */ - protected String quoteIntArray(int[] s) { - return StringUtils.quoteJavaIntArray(s); - } - - /** - * Format a map to the Java source code that represents this object. - * - * @param map the map to convert - * @return the Java source code - */ - protected String quoteMap(Map> map) { - if (map == null) { - return "null"; - } - if (map.size() == 0) { - return "new Map()"; - } - StringBuilder buff = new StringBuilder("new Map() /* "); - try { - for (Map.Entry> entry : map.entrySet()) { - String key = entry.getKey(); - Class< ? > clazz = entry.getValue(); - buff.append(key).append(':').append(clazz.getName()); - } - } catch (Exception e) { - buff.append(e.toString()).append(": ").append(map.toString()); - } - buff.append("*/"); - return buff.toString(); - } - - /** - * Log an exception and convert it to a SQL exception if required. - * - * @param ex the exception - * @return the SQL exception object - */ - protected SQLException logAndConvert(Exception ex) { - SQLException e = DbException.toSQLException(ex); - if (SysProperties.LOG_ALL_ERRORS) { - synchronized (TraceObject.class) { - // e.printStackTrace(); - try { - Writer writer = IOUtils.getWriter(IOUtils.openFileOutputStream(SysProperties.LOG_ALL_ERRORS_FILE, true)); - PrintWriter p = new PrintWriter(writer); - e.printStackTrace(p); - p.close(); - writer.close(); - } catch (Exception e2) { - e2.printStackTrace(); - } - } - } - if (trace == null) { - TraceSystem.traceThrowable(e); - } else { - int errorCode = e.getErrorCode(); - if (errorCode >= 23000 && errorCode < 24000) { - trace.info("SQLException", e); - } else { - trace.error("SQLException", e); - } - } - return e; - } - - /** - * Get and throw a SQL exception meaning this feature is not supported. - * - * @param message the message - * @return never returns normally - * @throws SQLException the exception - */ - protected SQLException unsupported(String message) throws SQLException { - try { - throw DbException.getUnsupportedException(message); - } catch (Exception e) { - throw logAndConvert(e); - } - } - - /** - * INTERNAL - */ - public static String toString(String sql, ArrayList< ? extends ParameterInterface> params) { - StatementBuilder buff = new StatementBuilder(sql); - if (params != null && params.size() > 0) { - buff.append(" {"); - int i = 0; - for (ParameterInterface p : params) { - i++; - try { - buff.appendExceptFirst(", "); - buff.append(i).append(": "); - if (p == null || p.getParamValue() == null) { - buff.append('-'); - } else { - buff.append(p.getParamValue().getSQL()); - } - } catch (Exception e) { - buff.append("/* ").append(i).append(": ").append(e.toString()).append("*/ "); - } - } - buff.append("};"); - } - return buff.toString(); - - } - -} diff --git a/tools/h2/src/main/org/h2/message/TraceSystem.java b/tools/h2/src/main/org/h2/message/TraceSystem.java deleted file mode 100755 index 40651ae..0000000 --- a/tools/h2/src/main/org/h2/message/TraceSystem.java +++ /dev/null @@ -1,330 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.message; - -import java.io.IOException; -import java.io.PrintWriter; -import java.io.Writer; -import java.sql.DriverManager; -import java.text.SimpleDateFormat; -import java.util.Date; -import org.h2.constant.ErrorCode; -import org.h2.constant.SysProperties; -import org.h2.engine.Constants; -import org.h2.jdbc.JdbcSQLException; -import org.h2.util.IOUtils; -import org.h2.util.SmallLRUCache; - -/** - * The trace mechanism is the logging facility of this database. There is - * usually one trace system per database. It is called 'trace' because the term - * 'log' is already used in the database domain and means 'transaction log'. It - * is possible to write after close was called, but that means for each write - * the file will be opened and closed again (which is slower). - */ -public class TraceSystem implements TraceWriter { - - /** - * The parent trace level should be used. - */ - public static final int PARENT = -1; - - /** - * This trace level means nothing should be written. - */ - public static final int OFF = 0; - - /** - * This trace level means only errors should be written. - */ - public static final int ERROR = 1; - - /** - * This trace level means errors and informational messages should be - * written. - */ - public static final int INFO = 2; - - /** - * This trace level means all type of messages should be written. - */ - public static final int DEBUG = 3; - - /** - * This trace level means all type of messages should be written, but - * instead of using the trace file the messages should be written to SLF4J. - */ - public static final int ADAPTER = 4; - - /** - * The default level for system out trace messages. - */ - public static final int DEFAULT_TRACE_LEVEL_SYSTEM_OUT = OFF; - - /** - * The default level for file trace messages. - */ - public static final int DEFAULT_TRACE_LEVEL_FILE = ERROR; - - /** - * The default maximum trace file size. It is currently 64 MB. Additionally, - * there could be a .old file of the same size. - */ - private static final int DEFAULT_MAX_FILE_SIZE = 64 * 1024 * 1024; - - private static final int CHECK_SIZE_EACH_WRITES = 128; - - private int levelSystemOut = DEFAULT_TRACE_LEVEL_SYSTEM_OUT; - private int levelFile = DEFAULT_TRACE_LEVEL_FILE; - private int levelMax; - private int maxFileSize = DEFAULT_MAX_FILE_SIZE; - private String fileName; - private SmallLRUCache traces; - private SimpleDateFormat dateFormat; - private Writer fileWriter; - private PrintWriter printWriter; - private int checkSize; - private boolean closed; - private boolean writingErrorLogged; - private TraceWriter writer = this; - - /** - * Create a new trace system object. - * - * @param fileName the file name - */ - public TraceSystem(String fileName) { - this.fileName = fileName; - updateLevel(); - traces = SmallLRUCache.newInstance(100); - } - - private void updateLevel() { - levelMax = Math.max(levelSystemOut, levelFile); - } - - /** - * Write the exception to the driver manager log writer if configured. - * - * @param e the exception - */ - public static void traceThrowable(Throwable e) { - PrintWriter writer = DriverManager.getLogWriter(); - if (writer != null) { - e.printStackTrace(writer); - } - } - - /** - * Get or create a trace object for this module. - * - * @param module the module name - * @return the trace object - */ - public synchronized Trace getTrace(String module) { - Trace t = traces.get(module); - if (t == null) { - t = new Trace(writer, module); - traces.put(module, t); - } - return t; - } - - public boolean isEnabled(int level) { - return level <= this.levelMax; - } - - /** - * Set the trace file name. - * - * @param name the file name - */ - public void setFileName(String name) { - this.fileName = name; - } - - /** - * Set the maximum trace file size in bytes. - * - * @param max the maximum size - */ - public void setMaxFileSize(int max) { - this.maxFileSize = max; - } - - /** - * Set the trace level to use for System.out - * - * @param level the new level - */ - public void setLevelSystemOut(int level) { - levelSystemOut = level; - updateLevel(); - } - - /** - * Set the file trace level. - * - * @param level the new level - */ - public void setLevelFile(int level) { - if (level == ADAPTER) { - String adapterClass = "org.h2.message.TraceWriterAdapter"; - try { - writer = (TraceWriter) Class.forName(adapterClass).newInstance(); - } catch (Throwable e) { - e = DbException.get(ErrorCode.CLASS_NOT_FOUND_1, e, adapterClass); - write(ERROR, Trace.DATABASE, adapterClass, e); - return; - } - String name = fileName; - if (name != null) { - if (name.endsWith(Constants.SUFFIX_TRACE_FILE)) { - name = name.substring(0, name.length() - Constants.SUFFIX_TRACE_FILE.length()); - } - int idx = Math.max(name.lastIndexOf('/'), name.lastIndexOf('\\')); - if (idx >= 0) { - name = name.substring(idx + 1); - } - writer.setName(name); - } - } - levelFile = level; - updateLevel(); - } - - private synchronized String format(String module, String s) { - if (dateFormat == null) { - dateFormat = new SimpleDateFormat("MM-dd HH:mm:ss "); - } - return dateFormat.format(new Date()) + module + ": " + s; - } - - public void write(int level, String module, String s, Throwable t) { - if (level <= levelSystemOut || level > this.levelMax) { - // level <= levelSystemOut: the system out level is set higher - // level > this.level: the level for this module is set higher - System.out.println(format(module, s)); - if (t != null && levelSystemOut == DEBUG) { - t.printStackTrace(); - } - } - if (fileName != null) { - if (level <= levelFile) { - writeFile(format(module, s), t); - } - } - } - - private synchronized void writeFile(String s, Throwable t) { - try { - if (checkSize++ >= CHECK_SIZE_EACH_WRITES) { - checkSize = 0; - closeWriter(); - if (maxFileSize > 0 && IOUtils.length(fileName) > maxFileSize) { - String old = fileName + ".old"; - if (IOUtils.exists(old)) { - IOUtils.delete(old); - } - IOUtils.rename(fileName, old); - } - } - if (!openWriter()) { - return; - } - printWriter.println(s); - if (t != null) { - if (levelFile == ERROR && t instanceof JdbcSQLException) { - JdbcSQLException se = (JdbcSQLException) t; - int code = se.getErrorCode(); - if (ErrorCode.isCommon(code)) { - printWriter.println(t.toString()); - } else { - t.printStackTrace(printWriter); - } - } else { - t.printStackTrace(printWriter); - } - } - printWriter.flush(); - if (closed) { - closeWriter(); - } - } catch (Exception e) { - logWritingError(e); - } - } - - private void logWritingError(Exception e) { - if (writingErrorLogged) { - return; - } - writingErrorLogged = true; - Exception se = DbException.get(ErrorCode.TRACE_FILE_ERROR_2, e, fileName, e.toString()); - // print this error only once - fileName = null; - System.out.println(se); - se.printStackTrace(); - } - - private boolean openWriter() { - if (printWriter == null) { - try { - IOUtils.createDirs(fileName); - if (IOUtils.exists(fileName) && IOUtils.isReadOnly(fileName)) { - // read only database: don't log error if the trace file - // can't be opened - return false; - } - fileWriter = IOUtils.getWriter(IOUtils.openFileOutputStream(fileName, true)); - printWriter = new PrintWriter(fileWriter, true); - } catch (Exception e) { - logWritingError(e); - return false; - } - } - return true; - } - - private synchronized void closeWriter() { - if (printWriter != null) { - printWriter.flush(); - printWriter.close(); - printWriter = null; - } - if (fileWriter != null) { - try { - fileWriter.close(); - } catch (IOException e) { - // ignore - } - fileWriter = null; - } - } - - /** - * Close the writers, and the files if required. It is still possible to - * write after closing, however after each write the file is closed again - * (slowing down tracing). - */ - public void close() { - closeWriter(); - closed = true; - } - - protected void finalize() { - if (!SysProperties.runFinalize) { - return; - } - close(); - } - - public void setName(String name) { - // nothing to do (the file name is already set) - } - -} diff --git a/tools/h2/src/main/org/h2/message/TraceWriter.java b/tools/h2/src/main/org/h2/message/TraceWriter.java deleted file mode 100755 index 54de461..0000000 --- a/tools/h2/src/main/org/h2/message/TraceWriter.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.message; - -/** - * The backend of the trace system must implement this interface. Two - * implementations are supported: the (default) native trace writer - * implementation that can write to a file and to system out, and an adapter - * that uses SLF4J (Simple Logging Facade for Java). - */ -interface TraceWriter { - - /** - * Set the name of the database or trace object. - * - * @param name the new name - */ - void setName(String name); - - /** - * Write a message. - * - * @param level the trace level - * @param module the name of the module - * @param s the message - * @param t the exception (may be null) - */ - void write(int level, String module, String s, Throwable t); - - /** - * Check the given trace / log level is enabled. - * - * @param level the level - * @return true if the level is enabled - */ - boolean isEnabled(int level); - -} diff --git a/tools/h2/src/main/org/h2/message/TraceWriterAdapter.java b/tools/h2/src/main/org/h2/message/TraceWriterAdapter.java deleted file mode 100755 index 5c21a15..0000000 --- a/tools/h2/src/main/org/h2/message/TraceWriterAdapter.java +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.message; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * This adapter sends log output to SLF4J. SLF4J supports multiple - * implementations such as Logback, Log4j, Jakarta Commons Logging (JCL), JDK - * 1.4 logging, x4juli, and Simple Log. To use SLF4J, you need to add the - * required jar files to the classpath, and set the trace level to 4 when opening - * a database: - * - *
- * jdbc:h2:˜/test;TRACE_LEVEL_FILE=4
- * 
- * - * The logger name is 'h2database'. - */ -public class TraceWriterAdapter implements TraceWriter { - - private String name; - private Logger logger = LoggerFactory.getLogger("h2database"); - - public void setName(String name) { - this.name = name; - } - - public boolean isEnabled(int level) { - switch (level) { - case TraceSystem.DEBUG: - return logger.isDebugEnabled(); - case TraceSystem.INFO: - return logger.isInfoEnabled(); - case TraceSystem.ERROR: - return logger.isErrorEnabled(); - default: - return false; - } - } - - public void write(int level, String module, String s, Throwable t) { - if (isEnabled(level)) { - if (name != null) { - s = name + ":" + module + " " + s; - } else { - s = module + " " + s; - } - switch (level) { - case TraceSystem.DEBUG: - logger.debug(s, t); - break; - case TraceSystem.INFO: - logger.info(s, t); - break; - case TraceSystem.ERROR: - logger.error(s, t); - break; - default: - } - } - } - -} diff --git a/tools/h2/src/main/org/h2/message/package.html b/tools/h2/src/main/org/h2/message/package.html deleted file mode 100755 index 14db8ca..0000000 --- a/tools/h2/src/main/org/h2/message/package.html +++ /dev/null @@ -1,15 +0,0 @@ - - - - -Javadoc package documentation -

- -Trace (logging facility) and error message tool. - -

\ No newline at end of file diff --git a/tools/h2/src/main/org/h2/package.html b/tools/h2/src/main/org/h2/package.html deleted file mode 100755 index 5d55f7e..0000000 --- a/tools/h2/src/main/org/h2/package.html +++ /dev/null @@ -1,15 +0,0 @@ - - - - -Javadoc package documentation -

- -Implementation of the JDBC driver. - -

\ No newline at end of file diff --git a/tools/h2/src/main/org/h2/res/_messages_de.prop b/tools/h2/src/main/org/h2/res/_messages_de.prop deleted file mode 100755 index 11880b5..0000000 --- a/tools/h2/src/main/org/h2/res/_messages_de.prop +++ /dev/null @@ -1,168 +0,0 @@ -.translator=Thomas Mueller -02000=Keine Daten verfügbar -07001=Ungültige Anzahl Parameter für {0}, erwartet: {1} -08000=Fehler beim Öffnen der Datenbank: {0} -08004=Falscher Benutzer Name oder Passwort -21S02=Anzahl der Felder stimmt nicht überein -22003=Zahlenwert ausserhalb des Bereichs -22012=Division durch 0: {0} -22025=Fehler in LIKE ESCAPE: {0} -23000=Bedingung verletzt: {0} -23001=Eindeutiger Index oder Primarschlüssel verletzt: {0} -23002=Referentielle Integrität verletzt: {0} -23003=Referentielle Integrität verletzt: {0} -40001=Eine Verklemmung (Deadlock) ist aufgetreten. Die aktuelle Transaktion wurde rlückgängig gemacht. Details: {0} -42000=Syntax Fehler in SQL Befehl {0} -42001=Syntax Fehler in SQL Befehl {0}; erwartet {1} -42S01=Tabelle {0} besteht bereits -42S02=Tabelle {0} nicht gefunden -42S11=Index {0} besteht bereits -42S12=Index {0} nicht gefunden -42S21=Doppelter Feldname {0} -42S22=Feld {0} nicht gefunden -42S32=Einstellung {0} nicht gefunden -90000=Funktion {0} muss Zeilen zurückgeben -90001=Methode nicht zulässig für eine Abfrage. Erlaubt sind execute oder executeQuery, nicht jedoch executeUpdate -90002=Methode nur zulässig for eine Abfrage. Erlaubt sind execute oder executeUpdate, nicht jedoch executeQuery -90003=Hexadezimal Zahl mit einer ungeraden Anzahl Zeichen: {0} -90004=Hexadezimal Zahl enthält unerlaubtes Zeichen: {0} -90005=Wert zu gross / lang für Feld {0}: {1} -90006=NULL nicht zulässig für Feld {0} -90007=Das Objekt wurde bereits geschlossen -90008=Unerlaubter Wert {0} für Parameter {1} -90009=Kann Datum {0} nicht umwandeln, Grund: {1} -90010=Kann Zeit {0} nicht umwandeln, Grund: {1} -90011=Kann Zeitstempel {0} nicht umwandeln, Grund: {1} -90012=Parameter {0} wurde nicht gesetzt -90013=Datenbank {0} nicht gefunden -90014=Fehler beim Parsen von {0} -90015=SUM oder AVG auf falschem Datentyp für {0} -90016=Feld {0} muss in der GROUP BY Liste sein -90017=Versuche, einen zweiten Primärschlüssel zu definieren -90018=Die Datenbank-Verbindung wurde nicht explizit geschlossen (jetzt in der Müllabfuhr) -90019=Kann aktuellen Benutzer nicht löschen -90020=Datenbank wird wahrscheinlich bereits benutzt: {0}. Mögliche Lösungen: alle Verbindungen schliessen; Server Modus verwenden -90021=Datenumwandlungsfehler beim Umwandeln von {0} -90022=Funktion {0} nicht gefunden -90023=Feld {0} darf nicht NULL nicht erlauben -90024=Fehler beim Umbenennen der Datei {0} nach {1} -90025=Kann Datei {0} nicht löschen -90026=Serialisierung fehlgeschlagen, Grund: {0} -90027=De-Serialisierung fehlgeschlagen, Grund: {1} -90028=Eingabe/Ausgabe Fehler: {0} -90029=Im Moment nicht auf einer veränderbaren Zeile -90030=Datei fehlerhaft beim Lesen des Datensatzes: {0}. Mögliche Lösung: Recovery Werkzeug verwenden -90031=Eingabe/Ausgabe: {0}; {1} -90032=Benutzer {0} nicht gefunden -90033=Benutzer {0} besteht bereits -90034=Log Datei Fehler: {0}, Grund: {1} -90035=Sequenz {0} besteht bereits -90036=Sequenz {0} nicht gefunden -90037=View {0} nicht gefunden -90038=View {0} besteht bereits -90039=Der Wert ist zu gross / lang für die Genauigkeit {0} -90040=Für diese Operation werden Administrator-Rechte benötigt -90041=Trigger {0} besteht bereits -90042=Trigger {0} nicht gefunden -90043=Fehler beim Erzeugen des Triggers {0}, Klasse {1}, Grund: {1}; siehe Ursache für Details -90044=Fehler beim Ausführen des Triggers {0}, Klasse {1}, Grund: {1}; siehe Ursache für Details -90045=Bedingung {0} besteht bereits -90046=URL Format Fehler; erwartet {0}, erhalten {1} -90047=Falsche Version, Treiber Version ist {0}, Server Version ist {1} -90048=Datenbank Datei Version wird nicht unterstützt oder ungültiger Dateikopf in Datei {0} -90049=Verschlüsselungsfehler in Datei {0} -90050=Falsches Passwort Format, benötigt wird: Datei-Passwort Benutzer-Passwort -90051=Befehl wurde abgebrochen oder das Session-Timeout ist abgelaufen -90052=Unterabfrage gibt mehr als eine Feld zurück -90053=Skalar-Unterabfrage enthält mehr als eine Zeile -90054=Ungültige Verwendung der Aggregat Funktion {0} -90055=Chiffre nicht unterstützt: {0} -90056=Kein Vorgabewert für Feld {0} -90057=Bedingung {0} nicht gefunden -90058=Innerhalb eines Triggers sind Commit und Rollback ist nicht erlaubt -90059=Mehrdeutiger Feldname {0} -90060=Ungültige Datei-Sperr-Methode {0} -90061=Fehler beim Öffnen von Port {0} (Port wird ev. bereits verwendet), Grund: {1} -90062=Fehler beim Erzeugen der Datei {0} -90063=Savepoint ist ungültig: {0} -90064=Savepoint hat keinen Namen -90065=Savepoint hat einen Namen -90066=Doppeltes Merkmahl {0} -90067=Verbindung ist unterbrochen: {0} -90068=Sortier-Ausdruck {0} muss in diesem Fall im Resultat vorkommen -90069=Rolle {0} besteht bereits -90070=Rolle {0} nicht gefunden -90071=Benutzer or Rolle {0} nicht gefunden -90072=Rollen und Rechte können nicht gemischt werden -90073=Java Methoden müssen eine unterschiedliche Anzahl Parameter aufweisen: {0} und {1} -90074=Rolle {0} bereits zugewiesen -90075=Feld ist Teil eines Indexes {0} -90076=Funktions-Alias {0} besteht bereits -90077=Funktions-Alias {0} nicht gefunden -90078=Schema {0} besteht bereits -90079=Schema {0} nicht gefunden -90080=Schema Namen müssen übereinstimmen -90081=Feld {0} enthält NULL Werte -90082=Sequenz {0} gehört zu einer Tabelle -90083=Feld wird referenziert durch {0} -90084=Kann das letzte Feld nicht löschen {0} -90085=Index {0} gehört zu einer Bedingung -90086=Klasse {0} nicht gefunden -90087=Methode {0} nicht gefunden -90088=Unbekannter Modus {0} -90089=Textvergleich-Modus kann nicht geändert werden wenn eine Daten-Tabelle existiert : {0} -90090=Schema {0} kann nicht gelöscht werden -90091=Rolle {0} kann nicht gelöscht werden -90092=Diese Java-Version wird nicht unterstützt (Java 1.4 oder neuer wird benötigt) -90093=Clustering Fehler - Datenbank läuft bereits im autonomen Modus -90094=Clustering Fehler - Datenbank läuft bereits im Cluster Modus, Serverliste: {0} -90095=Textformat Fehler: {0} -90096=Nicht genug Rechte für Objekt {0} -90097=Die Datenbank ist schreibgeschützt -90098=Die Datenbank ist bereits geschlossen -90099=Fehler beim Setzen des Datenbank Ereignis Empfängers {0}, Grund: {1} -90100=Kein Festplatten Speicherplatz verfügbar -90101=Falsches XID Format: {0} -90102=Datenkompressions-Option nicht unterstützt: {0} -90103=Datenkompressions-Algorithmus nicht unterstützt: {0} -90104=Datenkompressions Fehler -90105=Fehler beim Aufruf eine benutzerdefinierten Funktion: {0} -90106=Kann {0} nicht zurücksetzen per TRUNCATE -90107=Kann {0} nicht löschen weil {1} davon abhängt -90108=Nicht genug Hauptspeicher. -90109=View {0} ist ungültig: {1} -90110={0} ausserhalb des Bereichts -90111=Fehler beim Zugriff auf eine verknüpfte Tabelle mit SQL Befehl {0}, Grund: {1} -90112=Zeile nicht gefunden beim Löschen von Index {0} -90113=Datenbank-Verbindungs Option {0} nicht unterstützt -90114=Konstante {0} besteht bereits -90115=Konstante {0} nicht gefunden -90116=Literal dieser Art nicht zugelassen -90117=Verbindungen von anderen Rechnern sind nicht freigegeben, siehe -tcpAllowOthers -90118=Kann Tabelle nicht löschen {0} -90119=Benutzer-Datentyp {0} besteht bereits -90120=Benutzer-Datentyp {0} nicht gefunden -90121=Die Datenbank wurde bereits geschlossen (um das automatische Schliessen beim Stopp der VM zu deaktivieren, die Datenbank URL mit ";DB_CLOSE_ON_EXIT=FALSE" ergänzen) -90122=Funktion nicht unterstützt für Tabelle {0} wenn Views auf die Tabelle vorhanden sind: {1} -90123=Kann nicht indizierte und nicht indizierte Parameter mischen -90124=Datei nicht gefunden: {0} -90125=Ungültig Klasse, erwartet {0} erhalten {1} -90126=Datenbank ist nicht persistent -90127=Die Resultat-Zeilen können nicht verändert werden. Die Abfrage muss alle Felder eines eindeutigen Schlüssels enthalten, und nur eine Tabelle enthalten. -90128=Kann nicht an den Anfang der Resultat-Zeilen springen. Mögliche Lösung: conn.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ..). -90129=Transaktion {0} nicht gefunden -90130=Diese Methode ist nicht erlaubt für ein PreparedStatement; benützen Sie ein Statement. -90131=Gleichzeitige Änderung in Tabelle {0}: eine andere Transaktion hat den gleichen Datensatz geändert oder gelöscht -90132=Aggregat-Funktion {0} nicht gefunden -90133=Kann das Setting {0} nicht ändern wenn die Datenbank bereits geöffnet ist -90134=Der Zugriff auf die Klasse {0} ist nicht erlaubt -90135=Die Datenbank befindet sich im Exclusiv Modus; es können keine zusätzlichen Verbindungen geöffnet werden -90136=Diese Outer Join Bedingung wird nicht unterstützt: {0} -90137=Werte können nur einer Variablen zugewiesen werden, nicht an: {0} -90138=Ungültiger Datenbank Name: {0} -90139=Die (public static) Java Funktion wurde nicht gefunden: {0} -90140=Die Resultat-Zeilen können nicht verändert werden. Mögliche Lösung: conn.createStatement(.., ResultSet.CONCUR_UPDATABLE). -HY000=Allgemeiner Fehler: {0} -HY004=Unbekannter Datentyp: {0} -HYC00=Dieses Feature wird nicht unterstützt: {0} -HYT00=Zeitüberschreitung beim Versuch die Tabelle {0} zu sperren diff --git a/tools/h2/src/main/org/h2/res/_messages_en.prop b/tools/h2/src/main/org/h2/res/_messages_en.prop deleted file mode 100755 index 18fb37e..0000000 --- a/tools/h2/src/main/org/h2/res/_messages_en.prop +++ /dev/null @@ -1,168 +0,0 @@ -.translator=Thomas Mueller -02000=No data is available -07001=Invalid parameter count for {0}, expected count: {1} -08000=Error opening database: {0} -08004=Wrong user name or password -21S02=Column count does not match -22003=Numeric value out of range -22012=Division by zero: {0} -22025=Error in LIKE ESCAPE: {0} -23000=Check constraint violation: {0} -23001=Unique index or primary key violation: {0} -23002=Referential integrity constraint violation: {0} -23003=Referential integrity constraint violation: {0} -40001=Deadlock detected. The current transaction was rolled back. Details: {0} -42000=Syntax error in SQL statement {0} -42001=Syntax error in SQL statement {0}; expected {1} -42S01=Table {0} already exists -42S02=Table {0} not found -42S11=Index {0} already exists -42S12=Index {0} not found -42S21=Duplicate column name {0} -42S22=Column {0} not found -42S32=Setting {0} not found -90000=Function {0} must return a result set -90001=Method is not allowed for a query. Use execute or executeQuery instead of executeUpdate -90002=Method is only allowed for a query. Use execute or executeUpdate instead of executeQuery -90003=Hexadecimal string with odd number of characters: {0} -90004=Hexadecimal string contains non-hex character: {0} -90005=Value too long for column {0}: {1} -90006=NULL not allowed for column {0} -90007=The object is already closed -90008=Invalid value {0} for parameter {1} -90009=Cannot parse date constant {0}, cause: {1} -90010=Cannot parse time constant {0}, cause: {1} -90011=Cannot parse timestamp constant {0}, cause: {1} -90012=Parameter {0} is not set -90013=Database {0} not found -90014=Error parsing {0} -90015=SUM or AVG on wrong data type for {0} -90016=Column {0} must be in the GROUP BY list -90017=Attempt to define a second primary key -90018=The connection was not closed by the application and is garbage collected -90019=Cannot drop the current user -90020=Database may be already in use: {0}. Possible solutions: close all other connection(s); use the server mode -90021=Data conversion error converting {0} -90022=Function {0} not found -90023=Column {0} must not be nullable -90024=Error while renaming file {0} to {1} -90025=Cannot delete file {0} -90026=Serialization failed, cause: {0} -90027=Deserialization failed, cause: {0} -90028=IO Exception: {0} -90029=Currently not on an updatable row -90030=File corrupted while reading record: {0}. Possible solution: use the recovery tool -90031=IO Exception: {0}; {1} -90032=User {0} not found -90033=User {0} already exists -90034=Log file error: {0}, cause: {1} -90035=Sequence {0} already exists -90036=Sequence {0} not found -90037=View {0} not found -90038=View {0} already exists -90039=The value is too large for the precision {0} -90040=Admin rights are required for this operation -90041=Trigger {0} already exists -90042=Trigger {0} not found -90043=Error creating or initializing trigger {0} object, class {1}, cause: {2}; see root cause for details -90044=Error executing trigger {0}, class {1}, cause : {2}; see root cause for details -90045=Constraint {0} already exists -90046=URL format error; must be {0} but is {1} -90047=Version mismatch, driver version is {0} but server version is {1} -90048=Unsupported database file version or invalid file header in file {0} -90049=Encryption error in file {0} -90050=Wrong password format, must be: file password user password -90051=Statement was canceled or the session timed out -90052=Subquery is not a single column query -90053=Scalar subquery contains more than one row -90054=Invalid use of aggregate function {0} -90055=Unsupported cipher {0} -90056=No default value is set for column {0} -90057=Constraint {0} not found -90058=Commit or rollback is not allowed within a trigger -90059=Ambiguous column name {0} -90060=Unsupported file lock method {0} -90061=Exception opening port {0} (port may be in use), cause: {1} -90062=Error while creating file {0} -90063=Savepoint is invalid: {0} -90064=Savepoint is unnamed -90065=Savepoint is named -90066=Duplicate property {0} -90067=Connection is broken: {0} -90068=Order by expression {0} must be in the result list in this case -90069=Role {0} already exists -90070=Role {0} not found -90071=User or role {0} not found -90072=Roles and rights cannot be mixed -90073=Matching Java methods must have different parameter counts: {0} and {1} -90074=Role {0} already granted -90075=Column is part of the index {0} -90076=Function alias {0} already exists -90077=Function alias {0} not found -90078=Schema {0} already exists -90079=Schema {0} not found -90080=Schema name must match -90081=Column {0} contains null values -90082=Sequence {0} belongs to a table -90083=Column may be referenced by {0} -90084=Cannot drop last column {0} -90085=Index {0} belongs to a constraint -90086=Class {0} not found -90087=Method {0} not found -90088=Unknown mode {0} -90089=Collation cannot be changed because there is a data table: {0} -90090=Schema {0} cannot be dropped -90091=Role {0} cannot be dropped -90092=This Java version is not supported (Java 1.4 is required) -90093=Clustering error - database currently runs in standalone mode -90094=Clustering error - database currently runs in cluster mode, server list: {0} -90095=String format error: {0} -90096=Not enough rights for object {0} -90097=The database is read only -90098=The database has been closed -90099=Error setting database event listener {0}, cause: {1} -90100=No disk space available -90101=Wrong XID format: {0} -90102=Unsupported compression options: {0} -90103=Unsupported compression algorithm: {0} -90104=Compression error -90105=Exception calling user-defined function: {0} -90106=Cannot truncate {0} -90107=Cannot drop {0} because {1} depends on it -90108=Out of memory. -90109=View {0} is invalid: {1} -90110={0} out of range -90111=Error accessing linked table with SQL statement {0}, cause: {1} -90112=Row not found when trying to delete from index {0} -90113=Unsupported connection setting {0} -90114=Constant {0} already exists -90115=Constant {0} not found -90116=Literals of this kind are not allowed -90117=Remote connections to this server are not allowed, see -tcpAllowOthers -90118=Cannot drop table {0} -90119=User data type {0} already exists -90120=User data type {0} not found -90121=Database is already closed (to disable automatic closing at VM shutdown, add ";DB_CLOSE_ON_EXIT=FALSE" to the db URL) -90122=Operation not supported for table {0} when there are views on the table: {1} -90123=Cannot mix indexed and non-indexed parameters -90124=File not found: {0} -90125=Invalid class, expected {0} but got {1} -90126=Database is not persistent -90127=The result set is not updatable. The query must select all columns from a unique key. Only one table may be selected. -90128=The result set is not scrollable and can not be reset. You may need to use conn.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ..). -90129=Transaction {0} not found -90130=This method is not allowed for a prepared statement; use a regular statement instead. -90131=Concurrent update in table {0}: another transaction has updated or deleted the same row -90132=Aggregate {0} not found -90133=Cannot change the setting {0} when the database is already open -90134=Access to the class {0} is denied -90135=The database is open in exclusive mode; can not open additional connections -90136=Unsupported outer join condition: {0} -90137=Can only assign to a variable, not to: {0} -90138=Invalid database name: {0} -90139=The public static Java method was not found: {0} -90140=The result set is readonly. You may need to use conn.createStatement(.., ResultSet.CONCUR_UPDATABLE). -HY000=General error: {0} -HY004=Unknown data type: {0} -HYC00=Feature not supported: {0} -HYT00=Timeout trying to lock table {0} diff --git a/tools/h2/src/main/org/h2/res/_messages_es.prop b/tools/h2/src/main/org/h2/res/_messages_es.prop deleted file mode 100755 index 9b6eee7..0000000 --- a/tools/h2/src/main/org/h2/res/_messages_es.prop +++ /dev/null @@ -1,168 +0,0 @@ -.translator=Dario V. Fassi -02000=No hay datos disponibles. -07001=Cantidad de parametros invalidos para {0}, cantidad esperada: {1} -08000=Error abriendo la base de datos: {0} -08004=Nombre de usuario ó password incorrecto -21S02=La cantidad de columnas no coincide -22003=Valor numerico fuera de rango -22012=División por cero: {0} -22025=Error en LIKE ESCAPE: {0} -23000=Violación de Check constraint: {0} -23001=Violación de indice de Unicidad ó Clave primaria: {0} -23002=Violación de una restricción de Integridad Referencial: {0} -23003=Violación de una restricción de Integridad Referencial: {0} -40001=Deadlock - Punto muerto detectado. La transacción actual fue retrotraída (rollback). Detalles: {0} -42000=Error de Sintaxis en sentencia SQL {0} -42001=Error de Sintaxis en sentencia SQL {0}; se esperaba {1} -42S01=Tabla {0} ya existe -42S02=Tabla {0} no encontrada -42S11=Indice {0} ya existe -42S12=Indice {0} no encontrado -42S21=Nombre de columna Duplicada {0} -42S22=Columna {0} no encontrada -42S32=Setting {0} no encontrado -90000=Función {0} debe devolver un set de resultados (ResultSet) -90001=Metodo no permitido en un query. Use execute ó executeQuery en lugar de executeUpdate -90002=Metodo permitido unicamente en un query. Use execute ó executeUpdate en lugar de executeQuery -90003=Cadena Hexadecimal con cantidad impar de caracteres: {0} -90004=Cadena Hexadecimal contiene caracteres invalidos: {0} -90005=Valor demasiado largo para la columna {0}: {1} -90006=La columna {0} no permite valores nulos (NULL) -90007=El objeto ya está cerrado -90008=Valor Invalido {0} para el parametro {1} -90009=Imposible interpretar la constante de fecha {0}, causa: {1} -90010=Imposible interpretar la constante de hora {0}, causa: {1} -90011=Imposible interpretar la constante de fecha y hora timestamp {0}, causa: {1} -90012=Parametro {0} no está fijado -90013=Database {0} no encontrada -90014=Error interpretando {0} -90015=SUM ó AVG sobre un tipo de datos invalidado para {0} -90016=La columna {0} debe estar incluida en la lista de GROUP BY -90017=Intento de definir una segunda clave primaria -90018=La conexión no fue cerrada por la aplicación y esta siendo limpiada (garbage collected) -90019=Imposible eliminar el usuario actual -90020=La base de datos puede que ya esté siendo utilizada: {0}. Soluciones Posibles: cierre todas las otras conexiones; use el modo server -90021=Conversión de datos fallida, convirtiendo {0} -90022=Función {0} no encontrada -90023=Columna {0} no puede ser nullable -90024=Error mientras se renombraba el archivo {0} a {1} -90025=No se pudo borrar el archivo {0} -90026=Serialización fallida, causa: {0} -90027=Deserialización fallida, causa: {0} -90028=IO Exception: {0} -90029=La fila actual no es actualizable -90030=Archivo corrupto mientras se leía el registro: {0}. Solución Posible: use la herramienta de recuperación (recovery tool) -90031=IO Exception: {0}; {1} -90032=Usuario {0} no encontrado -90033=Usuario {0} ya existe -90034=Log archivo error: {0}, causa: {1} -90035=Sequence {0} ya existe -90036=Sequence {0} no encontrado -90037=View {0} no encontrado -90038=View {0} ya existe -90039=El valor es demasiado largo para la precisión {0} -90040=Derechos de Admin son requeridos para esta operación -90041=Trigger {0} ya existe -90042=Trigger {0} no encontrado -90043=Error creando ó inicializando trigger {0} objeto, clase {1}, causa: {2}; vea la causa raiz para mas detalle -90044=Error ejecutando trigger {0}, clase {1}, causa : {2}; vea la causa raiz para mas detalle -90045=Constraint {0} ya existe -90046=Error de formato en URL; debe ser {0} pero es {1} -90047=Discordancia de Versión, la versión del driver es {0} y la del server es {1} -90048=Versión del archivo de base de datos no soportada ó encabezado de archivo invalido en archivo {0} -90049=Error de Encriptación en archivo {0} -90050=Formato de password erroneo, debe ser: archivo password Usuario password -90051=Ls sentencia fue cancelado ó la sesión expiró por tiempo vencido -90052=El Subquery no es un query escalar (debe devolver una sola columna) -90053=El Subquery escalar contiene mas de una fila -90054=Uso Invalido de la función de columna agregada {0} -90055=Cipher No soportado {0} -90056=No se fijado un valor por defecto para la columna {0} -90057=Constraint {0} no encontrado -90058=Commit ó rollback no permitido dentro de un trigger -90059=Nombre de columna ambigua {0} -90060=Metodo de lockeo de archivo no soportado {0} -90061=Exception abriendo puerto {0} (el puerto puede estar en uso), causa: {1} -90062=Error creando archivo {0} -90063=Savepoint invalido: {0} -90064=Savepoint sin nombre -90065=Savepoint con nombre -90066=Propiedad Duplicada {0} -90067=Conexión rota: {0} -90068=Expresión Order by {0} debe estar en la lista de campos a devolver en este caso -90069=Role {0} ya existe -90070=Role {0} no encontrado -90071=Usuario ó role {0} no encontrado -90072=Roles y derechos no pueden ser mezclados -90073=Los metodos Java de Matching deben tener diferente cantidad de parametros: {0} y {1} -90074=Role {0} ya otorgado -90075=La columna es parte del indice {0} -90076=Función alias {0} ya existe -90077=Función alias {0} no encontrada -90078=Schema {0} ya existe -90079=Schema {0} no encontrado -90080=El nombre del Schema debe concordar -90081=Columna {0} contiene valores nulos -90082=Sequence {0} pertenece a una tabla -90083=La columna puede estar referenciada por {0} -90084=Imposible eliminar la ultima columna {0} -90085=Index {0} pertenece a un constraint -90086=Class {0} no encontrada -90087=Method {0} no encontrado -90088=Modo desconocido {0} -90089=Collation no puede ser cambiado debido a que existe una tabla de datos: {0} -90090=Schema {0} no puede ser eliminado -90091=Role {0} no puede ser eliminado -90092=Esta versión de Java no esta suportada (Java 1.4 es requerida) -90093=Clustering error - la base de datos se esta corriendo en modo standalone -90094=Clustering error - la base de datos esta corriendo en modo CLUSTER, lista de servidores: {0} -90095=String con error de formato: {0} -90096=No tiene los derechos necesarios para el objeto {0} -90097=La base de datos es de solo lectura (read only) -90098=La base de datos ha sido cerrada -90099=Error setting database event listener {0}, causa: {1} -90100=No hay suficiente espacio disponible en disco -90101=Formato erroneo de XID : {0} -90102=Opciones de compresión No soportadas: {0} -90103=Algoritmo de compresión No soportado: {0} -90104=Error de Compresión -90105=Exception llamando a una función definida por el usuario: {0} -90106=Imposible truncar {0} -90107=Imposible eliminar {0} debido a que {1} depende de él. -90108=Memoria Insuficiente - Out of memory. Tamaño: {0} -90109=La Vista {0} es invalida: {1} -90110={0} fuera de rango -90111=Error accediendo Linked Table con sentencia SQL {0}, causa: {1} -90112=Fila no encontrada mientras se intentaba borrar del indice {0} -90113=Parametro de conexión No soportado {0} -90114=Constante {0} ya existe -90115=Constante {0} no encontrado -90116=Literales de este tipo no estan permitidos -90117=Este server no permite Conexiones Remotas, vea -tcpAllowOthers -90118=Imposible eliminar tabla {0} -90119=Tipo de dato de usuario {0} ya existe -90120=Tipo de dato de usuario {0} no encontrado -90121=La base de datos ya esta cerrada (para des-habilitar el cerrado automatico durante el shutdown de la VM, agregue ";DB_CLOSE_ON_EXIT=FALSE" a la URL de conexión) -90122=Operación no soportada para la tabla {0} cuando existen vistas sobre la tabla: {1} -90123=No se puede mezclar parametros indexados y no-indexados -90124=Archivo no encontrado: {0} -90125=Clase Invalida, se esperaba {0} pero se obtuvo {1} -90126=La base de datos no es persistente -90127=El conjunto de resultados NO es actualizable. El query debe seleccionar todas la columnas desde una clave de unicidad. Solo una tabla puede ser seleccionada. -90128=El conjunto de resultados NO es scrollable y no puede ser reseteada. You may need to use conn.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ..). -90129=Transacción {0} no encontrada -90130=Este metodo no esta permitido para una sentencia preparada; en su lugar use una sentencia regular. -90131=Actualización concurrente sobre la tabla {0}: otra transacción ha actualizado ó borrado la misma fila -90132=Aggregate {0} no encontrado -90133=No puede cambiar el setting {0} cuando la base de datos esta abierta -90134=Acceso denegado a la clase {0} -90135=La base de datos esta abierta en modo EXCLUSIVO; no puede abrir conexiones adicionales -90136=Condición No soportada en Outer join : {0} -90137=Solo puede asignarse a una variable, no a: {0} -90138=Nombre de base de datos Invalido: {0} -90139=El metodo Java (publico y estatico) : {0} no fue encontrado -90140=#The result set is readonly. You may need to use conn.createStatement(.., ResultSet.CONCUR_UPDATABLE). -HY000=Error General : {0} -HY004=Tipo de dato desconocido : {0} -HYC00=Caracteristica no soportada: {0} -HYT00=Tiempo vencido intentando trabar (lock) la tabla {0} diff --git a/tools/h2/src/main/org/h2/res/_messages_ja.prop b/tools/h2/src/main/org/h2/res/_messages_ja.prop deleted file mode 100755 index 4fe54d6..0000000 --- a/tools/h2/src/main/org/h2/res/_messages_ja.prop +++ /dev/null @@ -1,168 +0,0 @@ -.translator=IKEMOTO, Masahiro -02000=有効なデータがありません -07001={0} は無効なパラメータ番号です, 期待される番号: {1} -08000=データベースオープンエラー: {0} -08004=ユーザ名またはパスワードが不正です -21S02=列番号が一致しません -22003=範囲外の数値です -22012=ゼロで除算しました: {0} -22025=LIKE ESCAPE にエラーがあります: {0} -23000=制約違反を確認してください: {0} -23001=ユニークインデックス、またはプライマリキー違反: {0} -23002=参照整合性制約違反: {0} -23003=参照整合性制約違反: {0} -40001=デッドロックが検出されました。現在のトランザクションはロールバックされました。詳細: {0} -42000=SQLステートメントに文法エラーがあります {0} -42001=SQLステートメントに文法エラーがあります {0}; 期待されるステートメント {1} -42S01=テーブル {0} はすでに存在します -42S02=テーブル {0} が見つかりません -42S11=インデックス {0} はすでに存在します -42S12=インデックス {0} が見つかりません -42S21=列名 {0} が重複しています -42S22=列 {0} が見つかりません -42S32=設定 {0} が見つかりません -90000=関数 {0} はリザルトセットを返さなければなりません -90001=メソッドはクエリをサポートしていません。executeUpdateのかわりに、excute、またはexecuteQueryを使用してください -90002=メソッドはクエリしかサポートしていません。executeQueryのかわりに、excecute、またはexecuteUpdateを使用してください -90003=文字数が奇数の16進文字列です: {0} -90004=16進文字列に不正な文字が含まれています: {0} -90005=列 {0} の値が長過ぎます: {1} -90006=列 {0} にはnull値が許されていません -90007=オブジェクトはすでに閉じられています -90008=パラメータ {1} に対する値 {0} が不正です -90009=日付定数 {0} を解析できません -90010=時間定数 {0} を解析できません -90011=タイムスタンプ定数 {0} を解析できません -90012=パラメータ {0} がセットされていません -90013=データベース {0} が見つかりません -90014=解析エラー {0} -90015=SUM、AVGを不正なデータ型 {0} に使用しました -90016=列 {0} はリストによりグループ化されなければなりません -90017=複数のプライマリキーを定義しようとしました -90018=アプリケーションにより閉じられていない接続がガベージコレクトされました -90019=使用中のユーザをドロップすることはできません -90020=データベースが使用中です: {0}. 可能な解決策: 他の接続を全て閉じる; サーバモードを使う -90021=データ変換中にエラーが発生しました {0} -90022=関数 {0} が見つかりません -90023=列 {0} にはnull値を許すべきてはありません -90024=ファイル名を {0} から {1} に変更中にエラーが発生しました -90025=ファイル {0} を削除できません -90026=直列化に失敗しました -90027=直列化復元に失敗しました -90028=入出力例外: {0} -90029=現在行は更新不可です -90030=レコード {0} を読み込み中にファイルの破損を検出しました。可能な解決策: リカバリツールを使用してください -90031=入出力例外: {0}; {1} -90032=ユーザ {0} が見つかりません -90033=ユーザ {0} はすでに存在します -90034=ログファイルエラー: {0} -90035=シーケンス {0} はすでに存在します -90036=シーケンス {0} が見つかりません -90037=ビュー {0} が見つかりません -90038=ビュー {0} はすでに存在します -90039=精度 {0} に対して値が大きすぎます -90040=この操作には管理権限が必要です -90041=トリガ {0} はすでに存在します -90042=トリガ {0} が見つかりません -90043=トリガ {0} オブジェクト, クラス {1} を生成中にエラーが発生しました -90044=トリガ {0} オブジェクト, クラス {1} を実行中にエラーが発生しました -90045=制約 {0} はすでに存在します -90046=URLフォーマットエラー; {1} ではなく {0} でなければなりません -90047=バージョンが一致しません。ドライババージョンは {0} ですが、サーババージョンは {1} です -90048=ファイル {0} は、未サポートのバージョンか、不正なファイルヘッダを持つデータベースファイルです -90049=ファイル {0} の暗号化エラーです -90050=不正なパスワードフォーマットです。正しくは: ファイルパスワード <空白> ユーザパスワード -90051=ステートメントがキャンセルされたか、セッションがタイムアウトしました -90052=サブクエリが単一列のクエリではありません -90053=数値サブクエリが複数の行を含んでいます -90054=集約関数 {0} の不正な使用 -90055={0} は未サポートの暗号です -90056=列 {0} にデフォルト値が設定されていません -90057=制約 {0} が見つかりません -90058=トリガ内でのコミット、ロールバックは許されていません -90059=列名 {0} があいまいです -90060={0} は未サポートのファイルロック方式です -90061=ポート {0} をオープン中に例外が発生しました (ポートが使用中の可能性があります) -90062=ファイル {0} を作成中にエラーが発生しました -90063=セーブポイントが不正です: {0} -90064=セーブポイントの名前を削除しました -90065=セーブポイントに名前を設定しました -90066=プロパティ {0} が重複しています -90067=接続が壊れています: {0} -90068=order by 対象の式 {0} は、結果リストに含まれる必要があります -90069=ロール {0} はすでに存在します -90070=ロール {0} が見つかりません -90071=ユーザ、またはロール {0} が見つかりません -90072=ロールと権限は混在できません -90073=適合するJavaメソッドは異なるパラメータ数である必要があります: {0}, {1} -90074=ロール {0} はすでに許可されています -90075=列はインデックス {0} の一部です -90076=関数の別名 {0} はすでに存在します -90077=関数の別名 {0} が見つかりません -90078=スキーマ {0} はすでに存在します -90079=スキーマ {0} が見つかりません -90080=スキーマ名が一致しません -90081=列 {0} がnull値を含んでいます -90082=シーケンス {0} はテーブルに属します -90083=列は {0} に参照されている可能性があります -90084=最後の列 {0} をドロップすることはできません -90085=インデックス {0} は制約に属しています -90086=クラス {0} が見つかりません -90087=メソッド {0} が見つかりません -90088={0} は不明なモードです -90089=データテーブル {0} があるため、照合順序の変更はできません -90090=スキーマ {0} はドロップできません -90091=ロール {0} はドロップできません -90092=このJavaバージョンはサポートされていません (Java 1.4が必要です) -90093=クラスタリングエラー - データベースはスタンドアロンモードで動作しています -90094=クラスタリングエラー - データベースはクラスターモードで動作しています, サーバリスト: {0} -90095=文字列フォーマットエラー: {0} -90096=オブジェクト {0} に対する十分な権限がありません -90097=データベースは読み込み専用です -90098=データベースはすでに閉じられています -90099=データベースイベントリスナの設定エラー {0} -90100=ディスクの空き領域がありません -90101=不正なXIDフォーマット: {0} -90102=未サポートの圧縮オプション: {0} -90103=未サポートの圧縮アルゴリズム: {0} -90104=圧縮エラー -90105=ユーザ定義関数を実行中に例外が発生しました: {0} -90106={0} を空にできません -90107={1} が依存しているため、{0} をドロップすることはできません -90108=メモリが不足しています -90109=ビュー {0} は無効です: {1} -90110={0} は範囲外です -90111=SQLステートメント {0} による結合テーブルアクセスエラー -90112=インデックス {0} から削除を試みましたが、行が見つかりません -90113=未サポートの接続設定 {0} -90114=定数 {0} はすでに存在します -90115=定数 {0} が見つかりません -90116=この種類のリテラルは許されていません -90117=このサーバへのリモート接続は許されていません, -tcpAllowOthersを参照 -90118=テーブル {0} はドロップできません -90119=ユーザデータ型 {0} はすでに存在します -90120=ユーザデータ型 {0} が見つかりません -90121=データベースはすでに閉じられています (VM終了時の自動データベースクローズを無効にするためには、db URLに ";DB_CLOSE_ON_EXIT=FALSE" を追加してください) -90122=ビューが存在するテーブル {0} に対する操作はサポートされていません: {1} -90123=インデックスの付いたパラメータと付いていないパラメータを混在させることはできません -90124=ファイルが見つかりません: {0} -90125=無効なクラス, {0} が期待されているにもかかわらず {1} を取得しました -90126=データベースは永続的ではありません -90127=リザルトセットが更新可能ではありません。クエリは単一のテーブルから、ユニークキーを全てselectしなければなりません -90128=リザルトセットがスクロール、リセット可能ではありません。conn.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ..) を使う必要があるかもしれません -90129=トランザクション {0} が見つかりません -90130=プリペアドステートメントにこのメソッドは許されていません; かわりに通常のステートメントを使用してください -90131=テーブル {0} に並行して更新が行われました: 別のトランザクションが、同じ行に更新か削除を行いました -90132=集約 {0} が見つかりません -90133=データベースオープン中には、設定 {0} を変更できません -90134=クラス {0} へのアクセスが拒否されました -90135=データベースは排他モードでオープンされています; 接続を追加することはできません -90136=未サポートの外部結合条件: {0} -90137=割り当ては変数にのみ可能です。{0} にはできません -90138=不正なデータベース名: {0} -90139=public staticであるJavaメソッドが見つかりません: {0} -90140=リザルトセットは読み込み専用です。conn.createStatement(.., ResultSet.CONCUR_UPDATABLE) を使う必要があるかもしれません -HY000=一般エラー: {0} -HY004=不明なデータ型: {0} -HYC00=機能はサポートされていません: {0} -HYT00=テーブル {0} のロック試行がタイムアウトしました diff --git a/tools/h2/src/main/org/h2/res/_messages_pl.prop b/tools/h2/src/main/org/h2/res/_messages_pl.prop deleted file mode 100755 index 2691190..0000000 --- a/tools/h2/src/main/org/h2/res/_messages_pl.prop +++ /dev/null @@ -1,168 +0,0 @@ -.translator=Tomek -02000=Dane nie sa dostepne -07001=Niewlasciwa liczba parametrow, oczekiwano ilosci: {0} -08000=Blad otwarcia bazy danych: {0} -08004=Nieprawidlowy uzytkownik/haslo -21S02=Niezgodna ilosc kolumn -22003=Wartosc numeryczna poza zakresem -22012=Dzielenie przez zero: {0} -22025=Blad w LIKE ESCAPE: {0} -23000=Naruszenie ograniczenia Check: {0} -23001=Naruszenie ograniczenia Klucza Glownego lub Indeksu Unikalnego: {0} -23002=#Referential integrity constraint violation: {0} -23003=#Referential integrity constraint violation: {0} -40001=#Deadlock detected. The current transaction was rolled back. Details: {0} -42000=Blad skladniowy w wyrazeniu SQL {0} -42001=Blad skladniowy w wyrazeniu SQL {0}; oczekiwano {1} -42S01=Tablela {0} juz istnieje -42S02=Tablela {0} nie istnieje -42S11=Indeks {0} juz istnieje -42S12=Indeks {0} nie istnieje -42S21=Zduplikowana nazwa kolumny {0} -42S22=Kolumna {0} nie istnieje -42S32=Ustawienie {0} nie istnieje -90000=Funkcja {0} musi zwrocic dane -90001=Metoda nie jest dozwolona w kwerendzie -90002=Metoda jest dozwolona tylko w kwerendzie -90003=Hexadecimal string with odd number of characters: {0} -90004=Hexadecimal string contains non hex character: {0} -90005=Wartosc za dluga dla kolumny {0}: {1} -90006=Pole nie moze byc puste {0} -90007=Objekt jest zamkniety -90008=Nieprawidlowa wartosc {0} parametru {1} -90009=#Cannot parse date constant {0}, cause: {1} -90010=#Cannot parse time constant {0}, cause: {1} -90011=#Cannot parse timestamp constant {0}, cause: {1} -90012=Parametr o numerze {0} nie jest ustalony -90013=Baza danych {0} nie znaleziona -90014=Blad parsowania {0} -90015=Agregacja SUM lub AVG wywolana na zlym typie danych {0} -90016=Kolumna {0} musi byc na liscie grupowania -90017=Proba zdefiniowania drugiego klucza glownego -90018=Polaczenie zostalo zamkniete przez aplikacje i zostalo usuniete przez kolektor nieuzytkow -90019=Nie mozna skasowac aktualnego uzytkownika -90020=Baza danych moze byc juz otwarta: {0} -90021=Blad konwersji danych {0} -90022=Funkcja {0} nie istnieje -90023=Kolumna Column {0} nie moze zawierac wartosci pustej -90024=Blad w zmianie nazwy pliku {0} na {1} -90025=Nie mozna skasowac pliku {0} -90026=#Serialization failed, cause: {0} -90027=#Deserialization failed, cause: {0} -90028=Blad wejscia/wyjscia: {0} -90029=Aktualny rekord nie pozwala na aktualizacje -90030=Uszkodzenie pliku podczas wczytywania rekordu: {0} -90031=Polaczenie nie zostalo zamkniete -90032=Uzytkownik {0} nie istnieje -90033=Uzytkownik {0} juz istnieje -90034=#Log file error: {0}, cause: {1} -90035=Sekwencja {0} juz istnieje -90036=Sekwencja {0} nie istnieje -90037=Widok {0} nie istnieje -90038=Widok {0} juz istnieje -90039=Wartosc jest za duza dla precyzji {0} -90040=Uprawnienia administratora sa wymagane do wykonania tej operacji -90041=Wyzwalacz {0} juz istnieje -90042=Wyzwalacz {0} nie istnieje -90043=#Error creating or initializing trigger {0} object, class {1}, cause: {2}; see root cause for details -90044=#Error executing trigger {0}, class {1}, cause : {2}; see root cause for details -90045=Ograniczenie {0} juz istnieje -90046=Bledny format URL; powinno byc {0} a jest {1} -90047=Niezgodna wersja sterownika, aktualna werjsa to {0} a wersja serwera to {1} -90048=Nieprawidlowa wersja pliku bazy danych lub nieprawidlowy naglowek pliku {0} -90049=Blad szyfowania pliku {0} -90050=Zly format hasla, powinno byc: plik haslo uzytkownik haslo -90051=Statement was canceled or the session timed out -90052=Podzapytanie nie jest zapytaniem opartym o jedna kolumne -90053=Scalar subquery contains more than one row -90054=Nieprawidlowe uzycie funkcji agregujacej {0} -90055=Unsupported cipher {0} -90056=Brak domyslnej wartosci dla kolumny {0} -90057=Ograniczenie {0} nie istnieje -90058=#Commit or rollback is not allowed within a trigger -90059=Niejednoznaczna nazwa kolumny {0} -90060=Niewspierana metoda blokowania pliku {0} -90061=#Exception opening port {0} (port may be in use), cause: {1} -90062=Blad tworzenia pliku {0} -90063=Zakladka jest nieprawidlowa: {0} -90064=Zakladka jest bez nazwy -90065=Zakladka jest nazwana -90066=Zduplikowana wlasciwosc {0} -90067=Polaczenie uszkodzone: {0} -90068=Wyrazenie sortowania {0} musi byc na liscie wyboru w tym przypadku -90069=Rola {0} juz istnieje -90070=Rola {0} nie istnieje -90071=Uzytkownik lub Rola User {0} nie istnieje -90072=Role i prawa nie moga byc mieszane -90073=#Matching Java methods must have different parameter counts: {0} and {1} -90074=Rola {0} juz przyznana -90075=Kolumna jest czescia indeksu {0} -90076=Alias funkcji {0} juz istnieje -90077=Alias funkcji {0} nie istnieje -90078=Schemat{0} juz istnieje -90079=Schemat {0} nie istnieje -90080=Nazwa schematu musi pasowac -90081=Kolumna {0} zawiera wartosci puste -90082=Sekwencja {0} nalezy do tabeli -90083=Do kolumny mozna odwoloac sie przez referencje {0} -90084=Nie mozna skasowac ostatniej kolumny {0} -90085=Indeks {0} nalezy do ograniczenia -90086=Klasa {0} nie istnieje -90087=Metoda {0} nie istnieje -90088=Nieznany stan {0} -90089=Metoda porownywania jezykowego nie moze byc zmieniona z powodu istnienia danych w tabeli {0} -90090=Schemat {0} nie moze zostac skasowany -90091=Rola {0} nie moze zostac skasowana -90092=Obecna wersja Javy nie jest wspierana (Java 1.4 lub nowsza jest wymagana) -90093=Clustering error - database currently runs in standalone mode -90094=Clustering error - database currently runs in cluster mode, server list: {0} -90095=Blad ciagu formatowania: {0} -90096=Brak wystarczajacych praw do obiektu {0} -90097=Baza danych jest w trybie tylko do odczytu -90098=Baza danych zostala zamknieta -90099=#Error setting database event listener {0}, cause: {1} -90100=Brak miejsca na dysku -90101=Zly format XID: {0} -90102=Nie wspierana opcja kompresji: {0} -90103=Nie wspierany algorytm kompresji: {0} -90104=Blad kompresji -90105=Wyjatek wywoluje funkcje uzytkownika: {0} -90106=Nie mozna obciac {0} -90107=Nie mozna skasowac {0} poniewaz zalezy od {1} -90108=#Out of memory. -90109=Widok {0} jest nieprawidlowy -90110={0} poza zakresem -90111=#Error accessing linked table with SQL statement {0}, cause: {1} -90112=Rekord nie znaleziony przy probie kasowania z indeksu {0} -90113=Ni ewspierana opcja polaczenia {0} -90114=Stala {0} juz istnieje -90115=Stala {0} nie istnieje -90116=Literal tego typu nie jest dozwolony -90117=Zdalne polaczeania do tego serwera nie sa dozwolone, zobacz -tcpAllowOthers -90118=Nie mozna skasowac tabeli {0} -90119=Typ danych uzytkownika {0} juz istnieje -90120=Typ danych uzytkownika {0} nie istnieje -90121=#Database is already closed (to disable automatic closing at VM shutdown, add ";DB_CLOSE_ON_EXIT=FALSE" to the db URL) -90122=Operacja nie jest dozwolona dla tabeli {0} gdy istnieja widoki oparte na tabeli: {1} -90123=Nie mozna mieszac parametrow indeksowych z nieindeksowymi -90124=Plik nie istnieje: {0} -90125=Nieprawidlowa klasa, oczekiwano {0} a jest {1} -90126=Baza danych nie jest trwala -90127=#The result set is not updatable. The query must select all columns from a unique key. Only one table may be selected. -90128=#The result set is not scrollable and can not be reset. You may need to use conn.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ..). -90129=#Transaction {0} not found -90130=#This method is not allowed for a prepared statement; use a regular statement instead. -90131=#Concurrent update in table {0}: another transaction has updated or deleted the same row -90132=#Aggregate {0} not found -90133=#Cannot change the setting {0} when the database is already open -90134=#Access to the class {0} is denied -90135=#The database is open in exclusive mode; can not open additional connections -90136=#Unsupported outer join condition: {0} -90137=#Can only assign to a variable, not to: {0} -90138=#Invalid database name: {0} -90139=#The public static Java method was not found: {0} -90140=#The result set is readonly. You may need to use conn.createStatement(.., ResultSet.CONCUR_UPDATABLE). -HY000=Blad ogolny: {0} -HY004=Nieznany typ danyche: {0} -HYC00=Cecha nie jest wspierana: {0} -HYT00=Czas oczekiwania na blokade tabeli {0} sie skonczyl diff --git a/tools/h2/src/main/org/h2/res/_messages_pt_br.prop b/tools/h2/src/main/org/h2/res/_messages_pt_br.prop deleted file mode 100755 index dc92f77..0000000 --- a/tools/h2/src/main/org/h2/res/_messages_pt_br.prop +++ /dev/null @@ -1,168 +0,0 @@ -.translator=Eduardo Fonseca Velasques -02000=Não há dados disponíveis -07001=Quantidade de parâmetros errados para {0}, experado: {1} -08000=Erro ao abrir a base de dados: {0} -08004=Autenticaçao inválida, verifique o usuário ou a senha -21S02=A quantidade de colunas não corresponde -22003=Valor númerico não esta dentro do limite -22012=Divisão por zero: {0} -22025=Erro em LIKE ESCAPE: {0} -23000=Violação da restrição: {0} -23001=Violação de índice único ou de chave primária: {0} -23002=Violação da integridade de restrição: {0} -23003=Violação da integridade de restrição: {0} -40001=#Deadlock detected. The current transaction was rolled back. Details: {0} -42000=Erro de sintax na declaração SQL {0} -42001=Erro de sintax na declaração SQL {0}; esperado {1} -42S01=Tabela {0} já existe -42S02=Tabela {0} não foi encontrada -42S11=índice {0} já existe -42S12=índice {0} não foi encontrado -42S21=Nome duplicado da coluna {0} -42S22=Coluna {0} não foi encontrada -42S32=Definição {0} não foi encontrada -90000=Função {0} deve retornar algum resultado -90001=O método não esta hábilitado para consulta. Use o execute ou o executeQuery em vez de executeUpdate -90002=O método é apenas para consulta. Use o execute ou o executeUpdate em vez de executeQuery -90003=Sequência Hexadecimal com número ímpar de caracteres: {0} -90004=Sequência Hexadecimal contêm caracteres inválidos: {0} -90005=Valor muito longo para a coluna {0}: {1} -90006=NULL não é permitido para a coluna {0} -90007=O objeto está fechado -90008=Valor inválido {0} para o parâmetro {1} -90009=Não é possível converter {0} para date, causa: {1} -90010=Não é possível converter {0} para time, causa: {1} -90011=Não é possível converter {0} para timestamp, causa: {1} -90012=Parâmetro {0} não esta definido -90013=Base de dados {0} não encontrada -90014=Erro na conversão {0} -90015=SUM ou AVG com tipo de dados errado para {0} -90016=Coluna {0} também deve estar no GROUP BY -90017=Tentativa para definir uma segunda chave primária -90018=A conecção foi fechada pela aplicação e retirada da memória -90019=Não pode remover o usuário corrente -90020=A base de dados talvez esteja em uso: {0}. Solução possível: fechar todas as outras conecções; use o modo servidor -90021=Erro na conversão de dado, convertendo {0} -90022=Função {0} não encontrada -90023=Coluna {0} não deve permitir valor nulo -90024=Erro ao renomear arquivo {0} para {1} -90025=Não pode apagar o arquivo {0} -90026=Serialização falhada, causa: {0} -90027=Deserialização falhada, causa: {0} -90028=Exceção de IO: {0} -90029=No momento não é possível fazer alterações nas linhas -90030=Arquivo corrompido durante a leitura: {0}. Possível solução: use o recovery tool -90031=Exceção de IO: {0}; {1} -90032=Usuário {0} não foi encontrado -90033=Usuário {0} já existe -90034=Erro no arquivo de Log: {0}, causa: {1} -90035=Sequência {0} já existe -90036=Sequência {0} não foi encontrada -90037=Vista {0} não foi encontrada -90038=Vista {0} já existe -90039=O valor é muito alto para a precisão {0} -90040=Direitos de permisões do Admin são necessários para está operação -90041=Trigger {0} já existe -90042=Trigger {0} não foi encontrada -90043=Erro na criação ou inicialização da trigger no objeto {0}, classe {1}, causa: {2}; para maior detalhe veja a raiz da causa -90044=Erro executando trigger {0}, classe {1}, causa : {2}; para maior detalhe veja a raiz da causa -90045=Restrição {0} já existe -90046=Erro no formato da URL; deve ser {0} mas está {1} -90047=Versões incompatíveis, versão do driver é {0} mas a versão do servidor é {1} -90048=Versão do arquivo de base de dados não é suportado, ou o cabeçalho do arquivo é inválido, no arquivo {0} -90049=Erro de encriptação no arquivo {0} -90050=Erro no formato da senha, deveria ser: arquivo de senha senha do usuário -90051=#Statement was canceled or the session timed out -90052=A Subquery não é de coluna única -90053=A Subquery contém mais de uma linha -90054=Uso inválido da função {0} agregada -90055=Cipher {0} não é suportado -90056=Nenhum valor pré-definido foi especificado para a coluna {0} -90057=Restrição {0} não foi encontrada -90058=#Commit or rollback is not allowed within a trigger -90059=Nome da coluna {0} é ambíguo. -90060=Não suporta o método do arquivo de bloqueio {0} -90061=Exceção ao abrir no porto {0} (provavelmente está em uso), causa: {1} -90062=Erro na criação do arquivo {0} -90063=Savepoint é inválido: {0} -90064=Savepoint não está nomeado -90065=Savepoint está nomeado -90066=Propriedade {0} duplicada -90067=A conecção está quebrada: {0} -90068=Expressão order by {0} deve estar na lista neste caso -90069=Regra {0} já existe -90070=Regra {0} não foi encontrada -90071=Usuário ou regra {0} não foram encontrados -90072=Regras e permissões não podem ser combinados -90073=#Matching Java methods must have different parameter counts: {0} and {1} -90074=Regra {0} já foi concedida -90075=A coluna faz parte do índice {0} -90076=Nome alternativo da função {0} já existe -90077=Nome alternativo da função {0} não foi encontrado -90078=Esquema {0} já existe -90079=Esquema {0} não foi encontrado -90080=Nome do esquema deve ser válido -90081=Coluna {0} restringe valores nulos -90082=Sequência {0} pertence a uma tabela -90083=A coluna pode ser referênciada por {0} -90084=Não pode apagar a última coluna {0} -90085=índice {0} pertence a uma restrição -90086=Classe {0} não foi encontrada -90087=Método {0} não foi encontrado -90088=Modo {0} desconhecido -90089=A coleção não pode ser alterada, porque existe uma tabela de dados: {0} -90090=Esquema {0} não pode ser apagado -90091=Regra {0} não pode ser apagada -90092=Esta versão do Java não é suportada (Java 1.4 é requerido no mínimo) -90093=Erro de clusterização - base de dados rodando no modo standalone no momento -90094=Erro de clusterização - base de dados rodando no modo cluster, lista do servidor: {0} -90095=Erro no formato da string: {0} -90096=Permissões insuficientes para o objeto {0} -90097=Base de dados é somente leitura -90098=Base de dados foi fechada -90099=Erro na definição do evento listener {0} da base de dados, causa: {1} -90100=Não há espaço em disco suficiente -90101=Formato XID incorreto: {0} -90102=Não é suportado as opções de compressão: {0} -90103=Não é suportado o algorítimo de compressão: {0} -90104=Erro na compressão -90105=Exceção na chamada da função definida pelo usuário: {0} -90106=Não pode fazer o truncate {0} -90107=Não pode apagar {0} por que depende de {1} -90108=#Out of memory. -90109=Vista {0} é inválida: {1} -90110={0} out of range -90111=Erro ao acessar a tabela lincada com a instrução SQL {0}, causa: {1} -90112=A linha não foi encontrada ao tentar eliminar apartir do índice {0} -90113=Não suporta a definição de conecção {0} -90114=Constante {0} já existe -90115=Constante {0} não foi encontrada -90116=Literais deste tipo não são permitidas -90117=Conecções remotas para este servidor não estão habilitadas, veja -tcpAllowOthers -90118=Não pode apagar a tabela {0} -90119=Tipo de dados do usuário {0} já existe -90120=Tipo de dados do usuário {0} não foram encontrados -90121=Base de dados já está fechada (para desabilitar o fechamento automático quando a VM terminar, addicione ";DB_CLOSE_ON_EXIT=FALSE" na url da base de dados) -90122=Operação não suportada para a tabela {0} quando existe alguma vista sobre a tabela: {1} -90123=Não pode combinar parâmetros de índices com não índices -90124=Arquivo não encontrado: {0} -90125=Classe inválida, experada {0} mas está {1} -90126=Base de dados não é persistente -90127=O resultado definido não é atualizável. A consulta deve selecionar todas as colunas de chave primária. Somente uma tabela pode ser selecionada. -90128=O resultado não é navegável e não pode ser resetado. Você pode usar conn.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ..). -90129=Transação {0} não encontrada -90130=Este método não é permitido para um statement preparado; Utilize um statement instanciado. -90131=Atualização concorrente na tabela {0}: outra transação atualizou ou deletou a mesma linha -90132=Agregação {0} não encontrada -90133=#Cannot change the setting {0} when the database is already open -90134=#Access to the class {0} is denied -90135=#The database is open in exclusive mode; can not open additional connections -90136=#Unsupported outer join condition: {0} -90137=#Can only assign to a variable, not to: {0} -90138=#Invalid database name: {0} -90139=#The public static Java method was not found: {0} -90140=#The result set is readonly. You may need to use conn.createStatement(.., ResultSet.CONCUR_UPDATABLE). -HY000=Erro geral: {0} -HY004=Tipo de dados desconhecido: {0} -HYC00=Recurso não suportado: {0} -HYT00=Timeout ao tentar bloquear a tabela {0} diff --git a/tools/h2/src/main/org/h2/res/_messages_ru.prop b/tools/h2/src/main/org/h2/res/_messages_ru.prop deleted file mode 100755 index 9486c21..0000000 --- a/tools/h2/src/main/org/h2/res/_messages_ru.prop +++ /dev/null @@ -1,168 +0,0 @@ -.translator=Sergi Vladykin -02000=Нет данных -07001=Неверное количество параметров для функции {0}, ожидаемое количество: {1} -08000=Ошибка при открытии базы данных: {0} -08004=Неверное имя пользователя или пароль -21S02=Неверное количество столбцов -22003=Численное значение вне допустимого диапазона -22012=Деление на ноль: {0} -22025=Ошибка в LIKE ESCAPE: {0} -23000=Нарушение ограничения: {0} -23001=Нарушение уникального индекса или первичного ключа: {0} -23002=Нарушение ссылочной целостности: {0} -23003=Нарушение ссылочной целостности: {0} -40001=Обнаружена взаимная блокировка потоков. Текущая транзакция была откачена. Детали: {0} -42000=Синтаксическая ошибка в выражении SQL {0} -42001=Синтаксическая ошибка в выражении SQL {0}; ожидалось {1} -42S01=Таблица {0} уже существует -42S02=Таблица {0} не найдена -42S11=Индекс {0} уже существует -42S12=Индекс {0} не найден -42S21=Повтор имени столбца {0} -42S22=Столбец {0} не найден -42S32=Настройка {0} не найдена -90000=Функция {0} должна возвращать набор записей -90001=Метод не разрешен для запросов. Используйте execute или executeQuery вместо executeUpdate -90002=Метод разрешен только для запросов. Используйте execute или executeUpdate вместо executeQuery -90003=Шестнадцатиричная строка содержит нечетное количество символов: {0} -90004=Шестнадцатиричная строка содержит нешестнадцатиричные символы: {0} -90005=Значение слишком длинное для поля {0}: {1} -90006=Значение NULL не разрешено для поля {0} -90007=Объект уже закрыт -90008=Недопустимое значение {0} для параметра {1} -90009=Невозможно преобразование строки {0} в тип date, причина: {1} -90010=Невозможно преобразование строки {0} в тип time, причина: {1} -90011=Невозможно преобразование строки {0} в тип timestamp, причина: {1} -90012=Параметр {0} не установлен -90013=База данных {0} не найдена -90014=Ошибка при разборе {0} -90015=SUM или AVG на недопустимом типе данных {0} -90016=Столбец {0} должен быть в предложении GROUP BY -90017=Попытка создания второго первичного ключа -90018=Незакрытое приложением соединение уничтожено сборщиком мусора -90019=Невозможно удалить текущего пользователя -90020=База данных уже используется: {0}. Возможные решения: закрыть все другие соединения; использовать режим сервера -90021=Ошибка преобразования данных при конвертации {0} -90022=Функция {0} не найдена -90023=Поле {0} не должно поддерживать значение NULL -90024=Ошибка при переименовании файла {0} в {1} -90025=Невозможно удалить файл {0} -90026=Ошибка сериализации, причина: {0} -90027=Ошибка десериализации, причина: {0} -90028=Ошибка ввода/вывода: {0} -90029=Запись не является обновляемой -90030=Файл поврежден при чтении строки: {0}. Возможные решения: используйте утилиту восстановления (recovery tool) -90031=Ошибка ввода/вывода: {0}; {1} -90032=Пользователь {0} не найден -90033=Пользователь {0} уже существует -90034=Ошибка записи в файл трассировки: {0}, причина: {1} -90035=Последовательность {0} уже существует -90036=Последовательность {0} не найдена -90037=Представление {0} не найдено -90038=Представление {0} уже существует -90039=Значение слишком большое для точности {0} -90040=Для выполнения данной операции необходимы права администратора -90041=Триггер {0} уже существует -90042=Триггер {0} не найден -90043=Ошибка при создании или инициализации триггера {0}, класс {1}, причина: {2}; для изучения подробностей смотрите корневую причину -90044=Ошибка при выполнении триггера {0}, класс {1}, причина : {2}; для изучения подробностей смотрите корневую причину -90045=Ограничение {0} уже существует -90046=Ошибка формата URL; должно быть {0}, на текущий момент {1} -90047=Несовпадение версий: версия драйвера {0}, версия сервера {1} -90048=Неподдерживаемая версия файлов базы данных или некорректный заголовок в файле {0} -90049=Ошибка шифрования в файле {0} -90050=Некорректный формат пароля, должен быть: пароль файла <пробел> пароль пользователя -90051=Запрос был отменен или закончилось время ожидания сессии -90052=Подзапрос выбирает более одного столбца -90053=Подзапрос выбирает более одной строки -90054=Некорректное использование агрегирующей функции {0} -90055=Метод шифрования {0} не поддерживается -90056=Для поля {0} не установлено значение по умолчанию -90057=Ограничение {0} не найдено -90058=Commit или rollback внутри триггера не допускается -90059=Неоднозначное имя столбца {0} -90060=Метод блокировки файлов {0} не поддерживается -90061=Ошибка при открытии порта {0} (порт может уже использоваться), причина: {1} -90062=Ошибка при создании файла {0} -90063=Savepoint не существует: {0} -90064=Savepoint не имеет имени -90065=Savepoint является именованным -90066=Повтор свойства соединения {0} -90067=Соединение разорвано: {0} -90068=Столбцы предложения ORDER BY {0} в данном случае должны содержаться в выбираемом списке -90069=Роль {0} уже существует -90070=Роль {0} не найдена -90071=Пользователь или роль {0} не найдены -90072=Недопустимо одновременно управлять правами и ролями пользователя -90073=Соответствующие методы Java должны иметь различное количество аргументов: {0} и {1} -90074=Роль {0} уже выдана -90075=Поле является частью индекса {0} -90076=Псевдоним функции {0} уже существует -90077=Псевдоним функции {0} не найден -90078=Схема {0} уже существует -90079=Схема {0} не найдена -90080=Схема должна совпадать с текущей -90081=Таблица содержит записи со значением NULL в поле {0} -90082=Последовательность {0} относится к таблице -90083=На поле может ссылаться {0} -90084=Невозможно удалить последнее поле {0} -90085=Индекс {0} относится к ограничению -90086=Класс {0} не найден -90087=Метод {0} не найден -90088=Неизвестный режим {0} -90089=Невозможно изменить collation, пока есть данные в таблицах: {0} -90090=Схема {0} не может быть удалена -90091=Роль {0} не может быть удалена -90092=Данная версия Java не поддерживается (минимальная поддерживаемая версия Java 1.4) -90093=Ошибка кластеризации - база данных работает в одиночном режиме -90094=Ошибка кластеризации - база данных работает в кластерном режиме, список серверов: {0} -90095=Ошибка формата строкового литерала: {0} -90096=Недостаточно прав на объект {0} -90097=База данных доступна только на чтение -90098=База данных уже закрыта -90099=Ошибка при установке слушателя событий базы данных {0}, причина: {1} -90100=Недостаточно места на диске -90101=Некорректный XID формат: {0} -90102=Неподдерживаемые опции сжатия: {0} -90103=Неподдерживаемый алгоритм сжатия: {0} -90104=Ошибка сжатия -90105=Ошибка при вызове пользовательской функции: {0} -90106=Невозможно очистить {0} -90107=Невозможно удалить {0}, пока существует зависимый объект {1} -90108=Ошибка нехватки памяти -90109=Представление {0} содержит ошибки: {1} -90110={0} вне допустимого диапазона -90111=Ошибка при обращении к линкованной таблице SQL запросом {0}, причина: {1} -90112=Запись не найдена при удалении из индекса {0} -90113=Неподдерживаемая опция соединения {0} -90114=Константа {0} уже существует -90115=Константа {0} не найдена -90116=Вычисление литералов запрещено -90117=Удаленные соединения к данному серверу запрещены, см. -tcpAllowOthers -90118=Невозможно удалить таблицу {0} -90119=Объект с именем {0} уже существует -90120=Домен {0} не найден -90121=База данных уже закрыта (чтобы отключить автоматическое закрытие базы данных при останове JVM, добавьте ";DB_CLOSE_ON_EXIT=FALSE" в URL) -90122=Операция для таблицы {0} не поддерживается, пока существуют представления: {1} -90123=Одновременное использование индексированных и неиндексированных параметров в запросе не поддерживается -90124=Файл не найден: {0} -90125=Недопустимый класс, ожидался {0}, но получен {1} -90126=База данных не является персистентной -90127=Набор записей не является обновляемым. Запрос должен выбирать все поля уникального ключа. Только одна таблица может быть выбрана. -90128=Набор записей не является прокручиваемым. Возможно необходимо использовать conn.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ..). -90129=Транзакция {0} не найдена -90130=Данный метод не разрешен для PreparedStatement; используйте Statement. -90131=Конкурентное изменение таблицы {0}: другая транзакция обновила или удалила ту же строку -90132=Агрегирующая функция {0} не найдена -90133=Невозможно изменить опцию {0}, когда база данных уже открыта -90134=Доступ к классу {0} запрещен -90135=База данных открыта в эксклюзивном режиме, открыть дополнительные соединения невозможно -90136=Данное условие не поддерживается в OUTER JOIN : {0} -90137=Присваивать значения возможно только переменным, но не: {0} -90138=Недопустимое имя базы данных: {0} -90139=public static Java метод не найден: {0} -90140=Набор записей не является обновляемым. Возможно необходимо использовать conn.createStatement(.., ResultSet.CONCUR_UPDATABLE). -HY000=Внутренняя ошибка: {0} -HY004=Неизвестный тип данных: {0} -HYC00=Данная функция не поддерживается: {0} -HYT00=Время ожидания блокировки таблицы {0} истекло diff --git a/tools/h2/src/main/org/h2/res/_messages_sk.prop b/tools/h2/src/main/org/h2/res/_messages_sk.prop deleted file mode 100755 index f5be139..0000000 --- a/tools/h2/src/main/org/h2/res/_messages_sk.prop +++ /dev/null @@ -1,168 +0,0 @@ -.translator=Ľubomír Grajciar -02000=Žiadné dáta nie sú dostupné -07001=Nesprávny počet parametrov pre {0}, očakávaný počet: {1} -08000=Chyba otvorenia databázy: {0} -08004=Nesprávne používateľské meno alebo heslo -21S02=Počet stĺpcov sa nezhoduje -22003=Číselná hodnota mimo rozsah -22012=Delenie nulou: {0} -22025=Chyba v LIKE ESCAPE: {0} -23000=Skontrolujte porušenie obmedzenia (constraint): {0} -23001=Porušenie jedinečnosti (unique) indexu alebo primárneho kľúča: {0} -23002=Porušenie obmedzenia (constraint) referenčnej integrity: {0} -23003=Porušenie obmedzenia (constraint) referenčnej integrity: {0} -40001=Mŕtvy bod (deadlock) detegovaný. Aktuálna transakcia bude odvolaná (rolled back). Podrobnosti: {0} -42000=Syntaktická chyba v SQL príkaze {0} -42001=Syntaktická chyba v SQL príkaze {0}; očakávané {1} -42S01=Tabuľka {0} už existuje -42S02=Tabuľka {0} nenájdená -42S11=Index {0} už existuje -42S12=Index {0} nenájdený -42S21=Duplicitné meno stĺpca {0} -42S22=Stĺpec {0} nenájdený -42S32=Nastavenie {0} nenájdené -90000=Funkcia {0} musí vracať výsledok (result set) -90001=Metóda nie je povolená pre dopyt (query). Použite execute alebo executeQuery namiesto executeUpdate -90002=Metóda je povolená iba pre dopyt (query). Použite execute alebo executeUpdate namiesto executeQuery -90003=Hexadecimálny reťazec s nepárnym počtom znakov: {0} -90004=Hexadecimálny reťazec obsahuje nepovolené znaky pre šestnáskovú sústavu: {0} -90005=Hodnota je príliš dlhá pre stĺpec {0}: {1} -90006=NULL nie je povolený pre stĺpec {0} -90007=Objekt už je zatvorený -90008=Nesprávna hodnota {0} parametra {1} -90009=Nemožem rozobrať dátumovú (date) konštantu {0}, dôvod: {1} -90010=Nemožem rozobrať časovú (time) konštantu {0}, dôvod: {1} -90011=Nemožem rozobrať časovú pečiatku (timestamp) {0}, dôvod: {1} -90012=Parameter {0} nie je nastavený -90013=Databáza {0} nenájdená -90014=Chyba rozobrania (parse) {0} -90015=SUM alebo AVG na nesprávnom dátovom type {0} -90016=Stĺpec {0} musí byť uvedený v GROUP BY zozname -90017=Pokus o definíciu druhého primárneho kľúča -90018=Spojenie neuzatvorené aplikáciou bolo zrušené -90019=Nemôžem zmazať aktuálneho používateľa -90020=Databáza sa už asi používa: {0}. Možné riešenia: zatvorte všetky dalšie spojenia; použite serverový mód -90021=Chyba konverzie dát pre {0} -90022=Funkcia {0} nenájdená -90023=Stĺpec {0} nesmie umožniť vložiť NULL -90024=Chyba pri premenovaní súboru {0} na {1} -90025=Nemôžem zmazať súbor {0} -90026=Serializácia neúspešná, dôvod: {0} -90027=Deserializácia neúspešná, dôvod: {0} -90028=IO výnimka: {0} -90029=Momentálne nie ste na riadku umožňujúcom úpravu (update) -90030=Poškodenie súboru pri čítaní záznamu: {0}. Možné riešenie: použiť nástroj na opravu databázy -90031=IO výnimka: {0}; {1} -90032=Používateľ {0} nenájdený -90033=Používateľ {0} už existuje -90034=Chyba Log súboru: {0}, dôvod: {1} -90035=Sekvencia {0} už existuje -90036=Sekvencia {0} nenájdená -90037=Pohľad (view) {0} nenájdený -90038=Pohľad (view) {0} už existuje -90039=Hodnota je príliš veľka pre presnosť {0} -90040=Administrátorské práva sú potrebné pre túto operáciu -90041=Spúštač (trigger) {0} už existuje -90042=Spúšťač (trigger) {0} nenájdený -90043=Chyba vytvorenia alebo spustenia spúšťača (trigger) {0} objekt, trieda {1}, dôvod: {2}; pre podrobnosti pozrite prvotný (root) dôvod -90044=Chyba vykonania spúšťača (trigger) {0}, trieda {1}, dôvod : {2}; pre podrobnosti pozrite prvotný (root) dôvod -90045=Obmedzenie (constraint) {0} už existuje -90046=Chyba formátu URL; musí byť {0}, ale je {1} -90047=Nezhoda verzií, verzia ovládača je {0}, ale verzia servera je {1} -90048=Nepodporovaná verzia databázového súboru alebo chybná hlavička súuboru {0} -90049=Chyba šifrovania súboru {0} -90050=Nesprávny formát hesiel, musí byť: súborové heslo používateľské heslo -90051=Príkaz bol zrušený alebo vypršal časový limit sedenia -90052=Vnorený dopyt (subquery) nie je dopyt na jeden stĺpec -90053=Skalárny vnorený dopyt (scalar subquery) obsahuje viac ako jeden riadok -90054=Nesprávne použitie agregačnej funkcie {0} -90055=Nepodporovaný typ šifry {0} -90056=Nie je nastavená vychodzia hodnota stĺpca {0} -90057=Obmedzenie (constraint) {0} nenájdený -90058=Commit alebo Rollback nie je povolené použiť v spúšťači (trigger) -90059=Nejednoznačné meno stĺpca {0} -90060=Nepodporovaná metóda zamknutia súboru {0} -90061=Vznikla výnimka pri otváraní portu {0} (port sa asi už používa), dôvod: {1} -90062=Chyba vytvorenia súboru {0} -90063=Bod návratu (savepoint) je nesprávny: {0} -90064=Bod návratu (savepoint) nie je pomenovaný -90065=Bod návratu (savepoint) je pomenovaný -90066=Duplicitná vlastnosť (property) {0} -90067=Spojenie je prerušené: {0} -90068=Order by expression {0} must be in the result list in this case -90069=Rola {0} už existuje -90070=Rola {0} nenájdená -90071=Používateľ alebo rola {0} nenajdená -90072=Role a práva sa nemôžu miešať -90073=Zhodné Java metódy musia mať rozdielny počet parametrov: {0} a {1} -90074=Rola {0} už je udelená (granted) -90075=Stĺpec je časťou indexu {0} -90076=Alias funkcie {0} už existuje -90077=Alias funkcie {0} nenájdený -90078=Schéma {0} už existuje -90079=Schéma {0} nenájdená -90080=Meno schémy sa musí zhodovať -90081=Stĺpec {0} obsahuje NULL hodnoty -90082=Sekvencia {0} patrí tabuľke -90083=Na stĺpec asi odkazuje {0} -90084=Nemôžem zmazať posledný stĺpec {0} -90085=Index {0} patrí obmedzeniu (constraint) -90086=Trieda {0} nenájdená -90087=Metóda {0} nenájdená -90088=Neznámy mód {0} -90089=Kolácia (collation) nemôže byť zmenená pretože tu je dátová tabuľka: {0} -90090=Schéma {0} nemôže byť zmazaná -90091=Rola {0} nemôže byť zmazaná -90092=Táto verzia Javy nie je podporovaná (Min. Java 1.4 je požadovaná) -90093=Chyba klustra - databáza je teraz v nezáviaslom (standalone) móde -90094=Chyba klustra - databáza je teraz v kluster móde, zoznam serverov: {0} -90095=Chyba formátu reťazca: {0} -90096=Nedostatočné práva na objekt {0} -90097=Databáza je iba na čítanie -90098=Databáza bola zatvorená -90099=Chyba nastavenia poslucháča udalostí (event listener) {0} pre databázu, dôvod: {1} -90100=Málo miesta na disku -90101=Nesprávny XID formát: {0} -90102=Nepodporované prepínače kompresie: {0} -90103=Nepodporovaný algoritmus kompresie: {0} -90104=Chyba kompresie -90105=Výnimka pri volaní používatelsky definovanej funkcie -90106=Nemožem skrátiť {0} -90107=Nemôžem zmazať {0} lebo {1} zavisí na {0} -90108=Nedostatok pamäte. -90109=Pohľad (view) {0} je nesprávny: {1} -90110={0} mimo rozsah -90111=Chyba prístupu k linkovanej tabuľke SQL príkazom {0}, dôvod: {1} -90112=Riadok nenájdený pri pokuse o vymazanie cez index {0} -90113=Nepodporované nastavenie spojenia {0} -90114=Konštanta {0} už existuje -90115=Konštanta {0} nenájdená -90116=Písmená (literals) tohto druhu nie sú povolené -90117=Vzdialené pripojenia na tento server nie sú povolené, pozrite -tcpAllowOthers -90118=Nemôžem zmazať tabuľku {0} -90119=Používateľský dátový typ {0} už existuje -90120=Používateľský dátový typ {0} nenájdený -90121=Databáza už je zatvorená (na zamedzenie automatického zatvárania pri ukončení VM, pridajte ";DB_CLOSE_ON_EXIT=FALSE" do DB URL) -90122=Operácia pre tabuľku {0} nie je podporovaná, kedže existujú na tabuľku pohľady (views): {1} -90123=Nemožno miešať indexované a neindexované parametre -90124=Súbor nenájdený: {0} -90125=Nesprávna trieda {1}, očakávana je {0} -90126=Databáza nie je trvalá (persistent) -90127=Výsledok (result set) nie je upraviteľný. Dopyt musí vybrať všetky stĺpce zahrnuté v jedinečnom (unique) kĺúči. Iba jedna tabuľka môže byť vybraná. -90128=Výsledok (result set) nie je rolovateľný (scrollable) a nemôže byť resetnutý. Je potrebné použiť conn.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ..). -90129=Transakcia {0} nenájdená -90130=Táto metóda nie je povolená pre pripravený prikaz (prepared statement); použite namiesto neho normálny prikaz (regular statement). -90131=Viacnásobná úprava v tabuľke {0}: iná transakcia upravila alebo zmazala rovnaký riadok -90132=Agregácia {0} nenájdená -90133=Nemôžem zmeniť nastavenie {0} keď už je databáza otvorená -90134=Prístup k triede {0} odoprený -90135=Databáza je otvorená vo výhradnom (exclusive) móde; nemôžem na ňu otvoriť ďalšie pripojenia -90136=Nepodporovaná "outer join" podmienka: {0} -90137=Môžete priradiť len do premennej, nie do: {0} -90138=Nesprávne meno databázy: {0} -90139=Verejná statická Java metóda nebola nájdená: {0} -90140=Výsledok (result set) je iba na čítanie. Je potrebné použiť conn.createStatement(.., ResultSet.CONCUR_UPDATABLE). -HY000=Všeobecná chyba: {0} -HY004=Neznámy dátový typ: {0} -HYC00=Vlastnosť nie je podporovaná: {0} -HYT00=Vypršal časový limit na zamknutie tabuľky {0} diff --git a/tools/h2/src/main/org/h2/res/h2-22.png b/tools/h2/src/main/org/h2/res/h2-22.png deleted file mode 100755 index 95ba9c7..0000000 Binary files a/tools/h2/src/main/org/h2/res/h2-22.png and /dev/null differ diff --git a/tools/h2/src/main/org/h2/res/h2-24.png b/tools/h2/src/main/org/h2/res/h2-24.png deleted file mode 100755 index 04b5d2b..0000000 Binary files a/tools/h2/src/main/org/h2/res/h2-24.png and /dev/null differ diff --git a/tools/h2/src/main/org/h2/res/h2.png b/tools/h2/src/main/org/h2/res/h2.png deleted file mode 100755 index d5340e5..0000000 Binary files a/tools/h2/src/main/org/h2/res/h2.png and /dev/null differ diff --git a/tools/h2/src/main/org/h2/res/help.csv b/tools/h2/src/main/org/h2/res/help.csv deleted file mode 100755 index 28cd27d..0000000 --- a/tools/h2/src/main/org/h2/res/help.csv +++ /dev/null @@ -1,1336 +0,0 @@ -# Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, -# Version 1.0, and under the Eclipse Public License, Version 1.0 -# (http://h2database.com/html/license.html). -# Initial Developer: H2 Group) -"SECTION","TOPIC","SYNTAX","TEXT" -"Commands (DML)","SELECT"," -SELECT [ TOP term ] [ DISTINCT | ALL ] selectExpression [,...] -FROM tableExpression [,...] [ WHERE expression ] -[ GROUP BY expression [,...] ] [ HAVING expression ] -[ { UNION [ ALL ] | MINUS | EXCEPT | INTERSECT } select ] [ ORDER BY order [,...] ] -[ LIMIT expression [ OFFSET expression ] [ SAMPLE_SIZE rowCountInt ] ] -[ FOR UPDATE ] -"," -Selects data from a table or multiple tables." -"Commands (DML)","INSERT"," -INSERT INTO tableName [ ( columnName [,...] ) ] -{ VALUES { ( { DEFAULT | expression } [,...] ) } [,...] | select } -"," -Inserts a new row / new rows into a table." -"Commands (DML)","UPDATE"," -UPDATE tableName [ [ AS ] newTableAlias ] SET { columnName= { DEFAULT | expression } } [,...] -[ WHERE expression ] -"," -Updates data in a table." -"Commands (DML)","DELETE"," -DELETE FROM tableName [ WHERE expression ] -"," -Deletes rows form a table." -"Commands (DML)","BACKUP"," -BACKUP TO fileNameString -"," -Backs up the database files to a ." -"Commands (DML)","CALL"," -CALL expression -"," -Calculates a simple expression." -"Commands (DML)","EXPLAIN"," -EXPLAIN { [ PLAN FOR ] | ANALYZE } { select | insert | update | delete } -"," -Shows the execution plan for a statement." -"Commands (DML)","MERGE"," -MERGE INTO tableName [ ( columnName [,...] ) ] -[ KEY ( columnName [,...] ) ] -{ VALUES { ( { DEFAULT | expression } [,...] ) } [,...] | select } -"," -Updates existing rows, and insert rows that don't exist." -"Commands (DML)","RUNSCRIPT"," -RUNSCRIPT FROM fileNameString [ COMPRESSION { DEFLATE | LZF | ZIP | GZIP } ] -[ CIPHER cipher PASSWORD string ] [ CHARSET charsetString ] -"," -Runs a SQL script from a file." -"Commands (DML)","SCRIPT"," -SCRIPT [ SIMPLE ] [ NODATA ] [ NOPASSWORDS ] [ NOSETTINGS ] -[ DROP ] [ BLOCKSIZE blockSizeInt ] -[ TO fileNameString [ COMPRESSION { DEFLATE | LZF | ZIP | GZIP } ] - [ CIPHER cipher PASSWORD string ] ] -"," -Creates a SQL script from the database." -"Commands (DML)","SHOW"," -SHOW { SCHEMAS | TABLES [ FROM schemaName ] | - COLUMNS FROM tableName [ FROM schemaName ] } -"," -Lists the schemas, tables, or the columns of a table." -"Commands (DDL)","ALTER INDEX RENAME"," -ALTER INDEX indexName RENAME TO newIndexName -"," -Renames an index." -"Commands (DDL)","ALTER SEQUENCE"," -ALTER SEQUENCE sequenceName [ RESTART WITH long ] [ INCREMENT BY long ] -"," -Changes the next value and the increment of a sequence." -"Commands (DDL)","ALTER TABLE ADD"," -ALTER TABLE tableName ADD name dataType [ DEFAULT expression ] -[ [ NOT ] NULL ] [ AUTO_INCREMENT | IDENTITY ] [ BEFORE columnName ] -"," -Adds a new column to a table." -"Commands (DDL)","ALTER TABLE ADD CONSTRAINT"," -ALTER TABLE tableName ADD constraint [ CHECK | NOCHECK ] -"," -Adds a constraint to a table." -"Commands (DDL)","ALTER TABLE ALTER"," -ALTER TABLE tableName ALTER COLUMN columnName -{ { dataType [ DEFAULT expression ] [ [ NOT ] NULL ] [ AUTO_INCREMENT | IDENTITY ] } - | { RENAME TO name } - | { RESTART WITH long } - | { SELECTIVITY int } - | { SET DEFAULT expression } - | { SET NULL } - | { SET NOT NULL } } -"," -Changes the data type of a column, rename a column, -change the identity value, or change the selectivity." -"Commands (DDL)","ALTER TABLE DROP COLUMN"," -ALTER TABLE tableName DROP COLUMN columnName -"," -Removes a column from a table." -"Commands (DDL)","ALTER TABLE DROP CONSTRAINT"," -ALTER TABLE tableName DROP { CONSTRAINT [ IF EXISTS ] constraintName | PRIMARY KEY } -"," -Removes a constraint or a primary key from a table." -"Commands (DDL)","ALTER TABLE SET"," -ALTER TABLE tableName SET REFERENTIAL_INTEGRITY - { FALSE | TRUE [ CHECK | NOCHECK ] } -"," -Disables or enables referential integrity checking for a table." -"Commands (DDL)","ALTER TABLE RENAME"," -ALTER TABLE tableName RENAME TO newName -"," -Renames a table." -"Commands (DDL)","ALTER USER ADMIN"," -ALTER USER userName ADMIN { TRUE | FALSE } -"," -Switches the admin flag of a user on or off." -"Commands (DDL)","ALTER USER RENAME"," -ALTER USER userName RENAME TO newUserName -"," -Renames a user." -"Commands (DDL)","ALTER USER SET PASSWORD"," -ALTER USER userName SET { PASSWORD string | SALT bytes HASH bytes } -"," -Changes the password of a user." -"Commands (DDL)","ALTER VIEW"," -ALTER VIEW viewName RECOMPILE -"," -Recompiles a view after the underlying tables have been changed or created." -"Commands (DDL)","ANALYZE"," -ANALYZE [ SAMPLE_SIZE rowCountInt ] -"," -Updates the selectivity statistics of all tables." -"Commands (DDL)","COMMENT"," -COMMENT ON -{ { COLUMN [ schemaName. ] tableName.columnName } - | { { TABLE | VIEW | CONSTANT | CONSTRAINT | ALIAS | INDEX | ROLE - | SCHEMA | SEQUENCE | TRIGGER | USER | DOMAIN } [ schemaName. ] objectName } } -IS expression -"," -Sets the comment of a database object." -"Commands (DDL)","CREATE AGGREGATE"," -CREATE AGGREGATE [ IF NOT EXISTS ] newAggregateName FOR className -"," -Creates a new user-defined aggregate function." -"Commands (DDL)","CREATE ALIAS"," -CREATE ALIAS [ IF NOT EXISTS ] newFunctionAliasName [ DETERMINISTIC ] -{ FOR classAndMethodName | AS sourceCodeString } -"," -Creates a new function alias." -"Commands (DDL)","CREATE CONSTANT"," -CREATE CONSTANT [ IF NOT EXISTS ] newConstantName VALUE expression -"," -Creates a new constant." -"Commands (DDL)","CREATE DOMAIN"," -CREATE DOMAIN [ IF NOT EXISTS ] newDomainName AS dataType -[ DEFAULT expression ] [ [ NOT ] NULL ] [ SELECTIVITY selectivity ] -[ CHECK condition ] -"," -Creates a new data type (domain)." -"Commands (DDL)","CREATE INDEX"," -CREATE { [ UNIQUE ] [ HASH ] INDEX [ IF NOT EXISTS ] newIndexName - | PRIMARY KEY [ HASH ] } -ON tableName ( indexColumn [,...] ) -"," -Creates a new index." -"Commands (DDL)","CREATE LINKED TABLE"," -CREATE [ [ GLOBAL | LOCAL ] TEMPORARY ] LINKED TABLE [ IF NOT EXISTS ] -name ( driverString, urlString, userString, passwordString, -[ originalSchemaString, ] originalTableString ) [ EMIT UPDATES | READONLY ] -"," -Creates a table link to an external table." -"Commands (DDL)","CREATE ROLE"," -CREATE ROLE [ IF NOT EXISTS ] newRoleName -"," -Creates a new role." -"Commands (DDL)","CREATE SCHEMA"," -CREATE SCHEMA [ IF NOT EXISTS ] name [ AUTHORIZATION ownerUserName ] -"," -Creates a new schema." -"Commands (DDL)","CREATE SEQUENCE"," -CREATE SEQUENCE [ IF NOT EXISTS ] newSequenceName [ START WITH long ] -[ INCREMENT BY long ] [ CACHE long ] -"," -Creates a new sequence." -"Commands (DDL)","CREATE TABLE"," -CREATE [ CACHED | MEMORY ] [ TEMP | [ GLOBAL | LOCAL ] TEMPORARY ] -TABLE [ IF NOT EXISTS ] name -{ { ( { columnDefinition | constraint } [,...] ) [ AS select ] } - | { AS select } } -[ ENGINE tableEngineName ] [ NOT PERSISTENT ] -"," -Creates a new table." -"Commands (DDL)","CREATE TRIGGER"," -CREATE TRIGGER [ IF NOT EXISTS ] newTriggerName { BEFORE | AFTER | INSTEAD OF } -{ INSERT | UPDATE | DELETE | SELECT | ROLLBACK } [,...] ON tableName [ FOR EACH ROW ] -[ QUEUE int ] [ NOWAIT ] CALL triggeredClassName -"," -Creates a new trigger." -"Commands (DDL)","CREATE USER"," -CREATE USER [ IF NOT EXISTS ] newUserName -{ PASSWORD string | SALT bytes HASH bytes } [ ADMIN ] -"," -Creates a new user." -"Commands (DDL)","CREATE VIEW"," -CREATE [ FORCE ] VIEW [ IF NOT EXISTS ] newViewName -[ ( columnName [,...] ) ] AS select -"," -Creates a new view." -"Commands (DDL)","DROP AGGREGATE"," -DROP AGGREGATE [ IF EXISTS ] aggregateName -"," -Drops an existing user-defined aggregate function." -"Commands (DDL)","DROP ALIAS"," -DROP ALIAS [ IF EXISTS ] existingFunctionAliasName -"," -Drops an existing function alias." -"Commands (DDL)","DROP ALL OBJECTS"," -DROP ALL OBJECTS [ DELETE FILES ] -"," -Drops all existing views, tables, sequences, schemas, function aliases, roles, -user-defined aggregate functions, domains, and users (except the current user)." -"Commands (DDL)","DROP CONSTANT"," -DROP CONSTANT [ IF EXISTS ] constantName -"," -Drops a constant." -"Commands (DDL)","DROP DOMAIN"," -DROP DOMAIN [ IF EXISTS ] domainName -"," -Drops a data type (domain)." -"Commands (DDL)","DROP INDEX"," -DROP INDEX [ IF EXISTS ] indexName -"," -Drops an index." -"Commands (DDL)","DROP ROLE"," -DROP ROLE [ IF EXISTS ] roleName -"," -Drops a role." -"Commands (DDL)","DROP SCHEMA"," -DROP SCHEMA [ IF EXISTS ] schemaName -"," -Drops a schema." -"Commands (DDL)","DROP SEQUENCE"," -DROP SEQUENCE [ IF EXISTS ] sequenceName -"," -Drops a sequence." -"Commands (DDL)","DROP TABLE"," -DROP TABLE [ IF EXISTS ] tableName [,...] -"," -Drops an existing table, or a list of existing tables." -"Commands (DDL)","DROP TRIGGER"," -DROP TRIGGER [ IF EXISTS ] triggerName -"," -Drops an existing trigger." -"Commands (DDL)","DROP USER"," -DROP USER [ IF EXISTS ] userName -"," -Drops a user." -"Commands (DDL)","DROP VIEW"," -DROP VIEW [ IF EXISTS ] viewName -"," -Drops a view." -"Commands (DDL)","TRUNCATE TABLE"," -TRUNCATE TABLE tableName -"," -Removes all rows from a table." -"Commands (Other)","CHECKPOINT"," -CHECKPOINT -"," -Flushes the data to disk and switches to a new transaction log if possible." -"Commands (Other)","CHECKPOINT SYNC"," -CHECKPOINT SYNC -"," -Flushes the data to disk and and forces all system buffers be written -to the underlying device." -"Commands (Other)","COMMIT"," -COMMIT [ WORK ] -"," -Commits a transaction." -"Commands (Other)","COMMIT TRANSACTION"," -COMMIT TRANSACTION transactionName -"," -Sets the resolution of an in-doubt transaction to 'commit'." -"Commands (Other)","GRANT RIGHT"," -GRANT { SELECT | INSERT | UPDATE | DELETE | ALL } [,...] ON -tableName [,...] TO { PUBLIC | userName | roleName } -"," -Grants rights for a table to a user or role." -"Commands (Other)","GRANT ROLE"," -GRANT roleName TO { PUBLIC | userName | roleName } -"," -Grants a role to a user or role." -"Commands (Other)","HELP"," -HELP [ anything [...] ] -"," -Displays the help pages of SQL commands or keywords." -"Commands (Other)","PREPARE COMMIT"," -PREPARE COMMIT newTransactionName -"," -Prepares committing a transaction." -"Commands (Other)","REVOKE RIGHT"," -REVOKE { SELECT | INSERT | UPDATE | DELETE | ALL } [,...] ON -tableName [,...] FROM { PUBLIC | userName | roleName } -"," -Removes rights for a table from a user or role." -"Commands (Other)","REVOKE ROLE"," -REVOKE roleName FROM { PUBLIC | userName | roleName } -"," -Removes a role from a user or role." -"Commands (Other)","ROLLBACK"," -ROLLBACK [ TO SAVEPOINT savepointName ] -"," -Rolls back a transaction." -"Commands (Other)","ROLLBACK TRANSACTION"," -ROLLBACK TRANSACTION transactionName -"," -Sets the resolution of an in-doubt transaction to 'rollback'." -"Commands (Other)","SAVEPOINT"," -SAVEPOINT savepointName -"," -Create a new savepoint." -"Commands (Other)","SET @"," -SET @variableName [ = ] expression -"," -Updates a user-defined variable." -"Commands (Other)","SET ALLOW_LITERALS"," -SET ALLOW_LITERALS { NONE | ALL | NUMBERS } -"," -This setting can help solve the SQL injection problem." -"Commands (Other)","SET AUTOCOMMIT"," -SET AUTOCOMMIT { TRUE | ON | FALSE | OFF } -"," -Switches auto commit on or off." -"Commands (Other)","SET CACHE_SIZE"," -SET CACHE_SIZE int -"," -Sets the size of the cache in KB (each KB being 1024 bytes) for the current database." -"Commands (Other)","SET CLUSTER"," -SET CLUSTER serverListString -"," -This command should not be used directly by an application, the statement is -executed automatically by the system." -"Commands (Other)","SET COLLATION"," -SET [ DATABASE ] COLLATION -{ OFF | collationName [ STRENGTH { PRIMARY | SECONDARY | TERTIARY | IDENTICAL } ] } -"," -Sets the collation used for comparing strings." -"Commands (Other)","SET COMPRESS_LOB"," -SET COMPRESS_LOB { NO | LZF | DEFLATE } -"," -Sets the compression algorithm for BLOB and CLOB data." -"Commands (Other)","SET DATABASE_EVENT_LISTENER"," -SET DATABASE_EVENT_LISTENER classNameString -"," -Sets the event listener class." -"Commands (Other)","SET DB_CLOSE_DELAY"," -SET DB_CLOSE_DELAY int -"," -Sets the delay for closing a database if all connections are closed." -"Commands (Other)","SET DEFAULT_LOCK_TIMEOUT"," -SET DEFAULT LOCK_TIMEOUT int -"," -Sets the default lock timeout (in milliseconds) in this database that is used -for the new sessions." -"Commands (Other)","SET DEFAULT_TABLE_TYPE"," -SET DEFAULT_TABLE_TYPE { MEMORY | CACHED } -"," -Sets the default table storage type that is used when creating new tables." -"Commands (Other)","SET EXCLUSIVE"," -SET EXCLUSIVE { 0 | 1 | 2 } -"," -Switched the database to exclusive mode (1, 2) and back to normal mode (0)." -"Commands (Other)","SET IGNORECASE"," -SET IGNORECASE { TRUE | FALSE } -"," -If IGNORECASE is enabled, text columns in newly created tables will be -case-insensitive." -"Commands (Other)","SET LOCK_MODE"," -SET LOCK_MODE int -"," -Sets the lock mode." -"Commands (Other)","SET LOCK_TIMEOUT"," -SET LOCK_TIMEOUT int -"," -Sets the lock timeout (in milliseconds) for the current session." -"Commands (Other)","SET MAX_LENGTH_INPLACE_LOB"," -SET MAX_LENGTH_INPLACE_LOB int -"," -Sets the maximum size of an in-place LOB object." -"Commands (Other)","SET MAX_LOG_SIZE"," -SET MAX_LOG_SIZE int -"," -Sets the maximum size of the transaction log, in megabytes." -"Commands (Other)","SET MAX_MEMORY_ROWS"," -SET MAX_MEMORY_ROWS int -"," -The maximum number of rows in a result set that are kept in-memory." -"Commands (Other)","SET MAX_MEMORY_UNDO"," -SET MAX_MEMORY_UNDO int -"," -The maximum number of undo records per a session that are kept in-memory." -"Commands (Other)","SET MAX_OPERATION_MEMORY"," -SET MAX_OPERATION_MEMORY int -"," -Sets the maximum memory used for large operations (delete and insert), in bytes." -"Commands (Other)","SET MODE"," -SET MODE { REGULAR | DB2 | DERBY | HSQLDB | MSSQLSERVER | MYSQL | ORACLE | POSTGRESQL } -"," -Changes to another database compatibility mode." -"Commands (Other)","SET MULTI_THREADED"," -SET MULTI_THREADED { 0 | 1 } -"," -Enabled (1) or disabled (0) multi-threading inside the database engine." -"Commands (Other)","SET OPTIMIZE_REUSE_RESULTS"," -SET OPTIMIZE_REUSE_RESULTS { 0 | 1 } -"," -Enabled (1) or disabled (0) the result reuse optimization." -"Commands (Other)","SET PASSWORD"," -SET PASSWORD string -"," -Changes the password of the current user." -"Commands (Other)","SET QUERY_TIMEOUT"," -SET QUERY_TIMEOUT int -"," -Set the query timeout of the current session to the given value." -"Commands (Other)","SET REFERENTIAL_INTEGRITY"," -SET REFERENTIAL_INTEGRITY { TRUE | FALSE } -"," -Disabled or enables referential integrity checking for the whole database." -"Commands (Other)","SET SALT HASH"," -SET SALT bytes HASH bytes -"," -Sets the password salt and hash for the current user." -"Commands (Other)","SET SCHEMA"," -SET SCHEMA schemaName -"," -Changes the default schema of the current connection." -"Commands (Other)","SET SCHEMA_SEARCH_PATH"," -SET SCHEMA_SEARCH_PATH schemaName [,...] -"," -Changes the schema search path of the current connection." -"Commands (Other)","SET THROTTLE"," -SET THROTTLE int -"," -Sets the throttle for the current connection." -"Commands (Other)","SET TRACE_LEVEL"," -SET { TRACE_LEVEL_FILE | TRACE_LEVEL_SYSTEM_OUT } int -"," -Sets the trace level for file the file or system out stream." -"Commands (Other)","SET TRACE_MAX_FILE_SIZE"," -SET TRACE_MAX_FILE_SIZE int -"," -Sets the maximum trace file size." -"Commands (Other)","SET UNDO_LOG"," -SET UNDO_LOG int -"," -Enables (1) or disables (0) the per session undo log." -"Commands (Other)","SET WRITE_DELAY"," -SET WRITE_DELAY int -"," -Set the maximum delay between a commit and flushing the log, in milliseconds." -"Commands (Other)","SHUTDOWN"," -SHUTDOWN [ IMMEDIATELY | COMPACT ] -"," -This statement closes all open connections to the database and closes the -database." -"Other Grammar","Alias"," -name -"," -An alias is a name that is only valid in the context of the statement." -"Other Grammar","And Condition"," -condition [ { AND condition } [...] ] -"," -Value or condition." -"Other Grammar","Array"," -( expression [,...] ) -"," -An array of values." -"Other Grammar","Boolean"," -TRUE | FALSE -"," -A boolean value." -"Other Grammar","Bytes"," -X'hex' -"," -A binary value." -"Other Grammar","Case"," -CASE expression { WHEN expression THEN expression } [...] -[ ELSE expression ] END -"," -Returns the first expression where the value is equal to the test expression." -"Other Grammar","Case When"," -CASE { WHEN expression THEN expression} [...] -[ ELSE expression ] END -"," -Returns the first expression where the condition is true." -"Other Grammar","Cipher"," -{ AES | XTEA } -"," -Two algorithms are supported, AES (AES-128) and XTEA (using 32 rounds)." -"Other Grammar","Column Definition"," -columnName dataType { DEFAULT expression | AS computedColumnExpression } [ [ NOT ] NULL ] -[ { AUTO_INCREMENT | IDENTITY } [ ( startInt [, incrementInt ] ) ] ] -[ SELECTIVITY selectivity ] [ PRIMARY KEY [ HASH ] | UNIQUE ] -"," -Default expressions are used if no explicit value was used when adding a row." -"Other Grammar","Comments"," --- anythingUntilEndOfLine | // anythingUntilEndOfLine | /* anythingUntilEndComment */ -"," -Comments can be used anywhere in a command and are ignored by the database." -"Other Grammar","Compare"," -<> | <= | >= | = | < | > | != -"," -Comparison operator." -"Other Grammar","Condition"," -operand [ conditionRightHandSide ] | NOT condition | EXISTS ( select ) -"," -Boolean value or condition." -"Other Grammar","Condition Right Hand Side"," -compare { { { ALL | ANY | SOME } ( select ) } | operand } - | IS [ NOT ] NULL - | BETWEEN operand AND operand - | IN ( { select | expression [,...] } ) - | [ NOT ] LIKE operand [ ESCAPE string ] - | [ NOT ] REGEXP operand -"," -The right hand side of a condition." -"Other Grammar","Constraint"," -[ constraintNameDefinition ] { - CHECK expression | UNIQUE ( columnName [,...] ) - | referentialConstraint } - | PRIMARY KEY [ HASH ] ( columnName [,...] ) -"," -Defines a constraint." -"Other Grammar","Constraint Name Definition"," -CONSTRAINT [ IF NOT EXISTS ] newConstraintName -"," -Defines a constraint name." -"Other Grammar","Csv Options"," -charsetString [, fieldSepString [, fieldDelimString [, escString [, nullString]]]]] -"," -Optional parameters for CSVREAD and CSVWRITE." -"Other Grammar","Data Type"," -intType | booleanType | tinyintType | smallintType | bigintType | identityType - | decimalType | doubleType | realType | dateType | timeType | timestampType - | binaryType | otherType | varcharType | varcharIgnorecaseType | charType - | blobType | clobType | uuidType | arrayType -"," -A data type definition." -"Other Grammar","Date"," -DATE 'yyyy-MM-dd' -"," -A date literal." -"Other Grammar","Decimal"," -[ + | - ] number [ . number ] -"," -Number with fixed precision and scale." -"Other Grammar","Digit"," -0-9 -"," -A digit." -"Other Grammar","Dollar Quoted String"," -$$anythingExceptTwoDollarSigns$$ -"," -A string starts and ends with two dollar signs." -"Other Grammar","Double"," -[ + | - ] { { number [ . number ] } | { . number } } [ E [ + | - ] expNumber [...] ] ] -"," -The limitations are the same as for the Java data type Double." -"Other Grammar","Expression"," -andCondition [ { OR andCondition } [...] ] -"," -Value or condition." -"Other Grammar","Factor"," -term [ { { * | / } term } [...] ] -"," -A value or a numeric factor." -"Other Grammar","Hex"," -{ { digit | a-f | A-F } { digit | a-f | A-F } } [...] -"," -The hexadecimal representation of a number or of bytes." -"Other Grammar","Hex Number"," -[ + | - ] 0x hex -"," -A number written in hexadecimal notation." -"Other Grammar","Index Column"," -columnName [ ASC | DESC ] [ NULLS { FIRST | LAST } ] -"," -Indexes this column in ascending or descending order." -"Other Grammar","Int"," -[ + | - ] number -"," -The maximum integer number is 2147483647, the minimum is -2147483648." -"Other Grammar","Long"," -[ + | - ] number -"," -Long numbers are between -9223372036854775808 and 9223372036854775807." -"Other Grammar","Name"," -{ { A-Z|_ } [ { A-Z|_|0-9 } [...] ] } | quotedName -"," -Names are not case sensitive." -"Other Grammar","Null"," -NULL -"," -NULL is a value without data type and means 'unknown value'." -"Other Grammar","Number"," -digit [...] -"," -The maximum length of the number depends on the data type used." -"Other Grammar","Operand"," -summand [ { || summand } [...] ] -"," -A value or a concatenation of values." -"Other Grammar","Order"," -{ int | expression } [ ASC | DESC ] [ NULLS { FIRST | LAST } ] -"," -Sorts the result by the given column number, or by an expression." -"Other Grammar","Quoted Name"," -""anythingExceptDoubleQuote"" -"," -Quoted names are case sensitive, and can contain spaces." -"Other Grammar","Referential Constraint"," -FOREIGN KEY ( columnName [,...] ) -REFERENCES [ refTableName ] [ ( refColumnName [,...] ) ] -[ ON DELETE { CASCADE | RESTRICT | NO ACTION | SET { DEFAULT | NULL } } ] -[ ON UPDATE { CASCADE | SET { DEFAULT | NULL } } ] -"," -Defines a referential constraint." -"Other Grammar","Select Expression"," -* | expression [ [ AS ] columnAlias ] | tableAlias.* -"," -An expression in a SELECT statement." -"Other Grammar","String"," -'anythingExceptSingleQuote' -"," -A string starts and ends with a single quote." -"Other Grammar","Summand"," -factor [ { { + | - } factor } [...] ] -"," -A value or a numeric sum." -"Other Grammar","Table Expression"," -{ [ schemaName. ] tableName | ( select ) } [ [ AS ] newTableAlias ] -[ { { LEFT | RIGHT } [ OUTER ] | [ INNER ] | CROSS | NATURAL } - JOIN tableExpression [ ON expression ] ] -"," -Joins a table." -"Other Grammar","Term"," -value - | columnName - | ?[ int ] - | NEXT VALUE FOR sequenceName - | function - | { - | + } term - | ( expression ) - | select - | case - | caseWhen - | tableAlias.columnName -"," -A value." -"Other Grammar","Time"," -TIME 'hh:mm:ss' -"," -A time literal." -"Other Grammar","Timestamp"," -TIMESTAMP 'yyyy-MM-dd hh:mm:ss[.nnnnnnnnn]' -"," -A timestamp literal." -"Other Grammar","Value"," -string | dollarQuotedString | hexNumber | int | long | decimal | double - | date | time | timestamp | boolean | bytes | array | null -"," -A value of any data type, or null." -"Data Types","INT Type"," -INT | INTEGER | MEDIUMINT | INT4 | SIGNED -"," -Possible values: -2147483648 to 2147483647." -"Data Types","BOOLEAN Type"," -BOOLEAN | BIT | BOOL -"," -Possible values: TRUE and FALSE." -"Data Types","TINYINT Type"," -TINYINT -"," -Possible values are: -128 to 127." -"Data Types","SMALLINT Type"," -SMALLINT | INT2 | YEAR -"," -Possible values: -32768 to 32767." -"Data Types","BIGINT Type"," -BIGINT | INT8 -"," -Possible values: -9223372036854775808 to 9223372036854775807." -"Data Types","IDENTITY Type"," -IDENTITY -"," -Auto-Increment value." -"Data Types","DECIMAL Type"," -{ DECIMAL | NUMBER | DEC | NUMERIC } ( precisionInt [ , scaleInt ] ) -"," -Data type with fixed precision and scale." -"Data Types","DOUBLE Type"," -{ DOUBLE [ PRECISION ] | FLOAT | FLOAT4 | FLOAT8 } -"," -Floating point number." -"Data Types","REAL Type"," -REAL -"," -Single precision floating point number." -"Data Types","TIME Type"," -TIME -"," -The format is hh:mm:ss." -"Data Types","DATE Type"," -DATE -"," -The format is yyyy-MM-dd." -"Data Types","TIMESTAMP Type"," -{ TIMESTAMP | DATETIME | SMALLDATETIME } -"," -The format is yyyy-MM-dd hh:mm:ss[." -"Data Types","BINARY Type"," -{ BINARY | VARBINARY | LONGVARBINARY | RAW | BYTEA } [ ( precisionInt ) ] -"," -Represents a byte array." -"Data Types","OTHER Type"," -OTHER -"," -This type allows storing serialized Java objects." -"Data Types","VARCHAR Type"," -{ VARCHAR | LONGVARCHAR | VARCHAR2 | NVARCHAR - | NVARCHAR2 | VARCHAR_CASESENSITIVE} [ ( precisionInt ) ] -"," -Unicode String." -"Data Types","VARCHAR_IGNORECASE Type"," -VARCHAR_IGNORECASE [ ( precisionInt ) ] -"," -Same as VARCHAR, but not case sensitive when comparing." -"Data Types","CHAR Type"," -{ CHAR | CHARACTER | NCHAR } [ ( precisionInt ) ] -"," -This type is supported for compatibility with other databases and older -applications." -"Data Types","BLOB Type"," -{ BLOB | TINYBLOB | MEDIUMBLOB | LONGBLOB | IMAGE | OID } [ ( precisionInt ) ] -"," -Like BINARY, but intended for very large values such as files or images." -"Data Types","CLOB Type"," -{ CLOB | TINYTEXT | TEXT | MEDIUMTEXT | LONGTEXT | NTEXT | NCLOB } [ ( precisionInt ) ] -"," -CLOB is like VARCHAR, but intended for very large values." -"Data Types","UUID Type"," -UUID -"," -Universally unique identifier." -"Data Types","ARRAY Type"," -ARRAY -"," -An array of values." -"Functions (Aggregate)","AVG"," -AVG ( [ DISTINCT ] { int | long | decimal | double } ) -"," -The average (mean) value." -"Functions (Aggregate)","BOOL_AND"," -BOOL_AND(boolean) -"," -Returns true if all expressions are true." -"Functions (Aggregate)","BOOL_OR"," -BOOL_OR(boolean) -"," -Returns true if any expression is true." -"Functions (Aggregate)","COUNT"," -COUNT( { * | { [ DISTINCT ] expression } } ) -"," -The count of all row, or of the non-null values." -"Functions (Aggregate)","GROUP_CONCAT"," -GROUP_CONCAT ( [ DISTINCT ] string -[ ORDER BY { expression [ ASC | DESC ] } [,...] ] -[ SEPARATOR expression ] ) -"," -Concatenates strings with a separator." -"Functions (Aggregate)","MAX"," -MAX(value) -"," -The highest value." -"Functions (Aggregate)","MIN"," -MIN(value) -"," -The lowest value." -"Functions (Aggregate)","SUM"," -SUM( [ DISTINCT ] { int | long | decimal | double } ) -"," -The sum of all values." -"Functions (Aggregate)","SELECTIVITY"," -SELECTIVITY(value) -"," -Estimates the selectivity (0-100) of a value." -"Functions (Aggregate)","STDDEV_POP"," -STDDEV_POP( [ DISTINCT ] double ) -"," -The population standard deviation." -"Functions (Aggregate)","STDDEV_SAMP"," -STDDEV_SAMP( [ DISTINCT ] double ) -"," -The sample standard deviation." -"Functions (Aggregate)","VAR_POP"," -VAR_POP( [ DISTINCT ] double ) -"," -The population variance (square of the population standard deviation)." -"Functions (Aggregate)","VAR_SAMP"," -VAR_SAMP( [ DISTINCT ] double ) -"," -The sample variance (square of the sample standard deviation)." -"Functions (Numeric)","ABS"," -ABS ( { int | long | decimal | double } ) -"," -See also Java Math." -"Functions (Numeric)","ACOS"," -ACOS(double) -"," -See also Java Math." -"Functions (Numeric)","ASIN"," -ASIN(double) -"," -See also Java Math." -"Functions (Numeric)","ATAN"," -ATAN(double) -"," -See also Java Math." -"Functions (Numeric)","COS"," -COS(double) -"," -See also Java Math." -"Functions (Numeric)","COT"," -COT(double) -"," -See also Java Math." -"Functions (Numeric)","SIN"," -SIN(double) -"," -See also Java Math." -"Functions (Numeric)","TAN"," -TAN(double) -"," -See also Java Math." -"Functions (Numeric)","ATAN2"," -ATAN2(double, double) -"," -See also Java Math." -"Functions (Numeric)","BITAND"," -BITAND(long, long) -"," -The bitwise AND operation." -"Functions (Numeric)","BITOR"," -BITOR(long, long) -"," -The bitwise OR operation." -"Functions (Numeric)","BITXOR"," -BITXOR(long, long) -"," -The bitwise XOR operation." -"Functions (Numeric)","MOD"," -MOD(long, long) -"," -The modulo operation." -"Functions (Numeric)","CEILING"," -CEILING(double) -"," -See also Java Math." -"Functions (Numeric)","DEGREES"," -DEGREES(double) -"," -See also Java Math." -"Functions (Numeric)","EXP"," -EXP(double) -"," -See also Java Math." -"Functions (Numeric)","FLOOR"," -FLOOR(double) -"," -See also Java Math." -"Functions (Numeric)","LOG"," -LOG(double) -"," -See also Java Math." -"Functions (Numeric)","LOG10"," -LOG10(double) -"," -See also Java Math." -"Functions (Numeric)","RADIANS"," -RADIANS(double) -"," -See also Java Math." -"Functions (Numeric)","SQRT"," -SQRT(double) -"," -See also Java Math." -"Functions (Numeric)","PI"," -PI() -"," -See also Java Math." -"Functions (Numeric)","POWER"," -POWER(double, double) -"," -See also Java Math." -"Functions (Numeric)","RAND"," -RAND( [ int ] ) -"," -Calling the function without parameter returns the next a pseudo random number." -"Functions (Numeric)","RANDOM_UUID"," -RANDOM_UUID() -"," -Returns a new UUID with 122 pseudo random bits." -"Functions (Numeric)","ROUND"," -ROUND(double, digitsInt) -"," -Rounds to a number of digits." -"Functions (Numeric)","ROUNDMAGIC"," -ROUNDMAGIC(double) -"," -This function rounds numbers in a good way, but it is slow." -"Functions (Numeric)","SECURE_RAND"," -SECURE_RAND(int) -"," -Generates a number of cryptographically secure random numbers." -"Functions (Numeric)","SIGN"," -SIGN ( { int | long | decimal | double } ) -"," -Returns -1 if the value is smaller 0, 0 if zero, and otherwise 1." -"Functions (Numeric)","ENCRYPT"," -ENCRYPT(algorithmString, keyBytes, dataBytes) -"," -Encrypts data using a key." -"Functions (Numeric)","DECRYPT"," -DECRYPT(algorithmString, keyBytes, dataBytes) -"," -Decrypts data using a key." -"Functions (Numeric)","HASH"," -HASH(algorithmString, dataBytes, iterationInt) -"," -Calculate the hash value using an algorithm, and repeat this process for a number of iterations." -"Functions (Numeric)","TRUNCATE"," -TRUNCATE(double, digitsInt) -"," -Truncates to a number of digits (to the next value closer to 0)." -"Functions (Numeric)","COMPRESS"," -COMPRESS(dataBytes [, algorithmString]) -"," -Compresses the data using the specified compression algorithm." -"Functions (Numeric)","EXPAND"," -EXPAND(bytes) -"," -Expands data that was compressed using the COMPRESS function." -"Functions (Numeric)","ZERO"," -ZERO() -"," -Returns the value 0." -"Functions (String)","ASCII"," -ASCII(string) -"," -Returns the ASCII value of the first character in the string." -"Functions (String)","BIT_LENGTH"," -BIT_LENGTH(string) -"," -Returns the number of bits in a string." -"Functions (String)","LENGTH"," -{ LENGTH | CHAR_LENGTH | CHARACTER_LENGTH } ( string ) -"," -Returns the number of characters in a string." -"Functions (String)","OCTET_LENGTH"," -OCTET_LENGTH(string) -"," -Returns the number of bytes in a string." -"Functions (String)","CHAR"," -{ CHAR | CHR } ( int ) -"," -Returns the character that represents the ASCII value." -"Functions (String)","CONCAT"," -CONCAT(string, string [,...]) -"," -Combines strings." -"Functions (String)","DIFFERENCE"," -DIFFERENCE(string, string) -"," -Returns the difference between the sounds of two strings." -"Functions (String)","HEXTORAW"," -HEXTORAW(string) -"," -Converts a hex representation of a string to a string." -"Functions (String)","RAWTOHEX"," -RAWTOHEX(string) -"," -Converts a string to the hex representation." -"Functions (String)","INSTR"," -INSTR(string, searchString, [, startInt]) -"," -Returns the location of a search string in a string (s)." -"Functions (String)","INSERT Function"," -INSERT(originalString, startInt, lengthInt, addString) -"," -Inserts a additional string into the original string at a specified start position." -"Functions (String)","LOWER"," -{ LOWER | LCASE } ( string ) -"," -Converts a string to lowercase." -"Functions (String)","UPPER"," -{ UPPER | UCASE } ( string ) -"," -Converts a string to uppercase." -"Functions (String)","LEFT"," -LEFT(string, int) -"," -Returns the leftmost number of characters." -"Functions (String)","RIGHT"," -RIGHT(string, int) -"," -Returns the rightmost number of characters." -"Functions (String)","LOCATE"," -LOCATE(searchString, string [, startInt]) -"," -Returns the location of a search string in a string." -"Functions (String)","POSITION"," -POSITION(searchString, string) -"," -Returns the location of a search string in a string." -"Functions (String)","LPAD"," -LPAD(string, int[, paddingString]) -"," -Left pad the string to the specified length." -"Functions (String)","RPAD"," -RPAD(string, int[, paddingString]) -"," -Right pad the string to the specified length." -"Functions (String)","LTRIM"," -LTRIM(string) -"," -Removes all leading spaces from a string." -"Functions (String)","RTRIM"," -RTRIM(string) -"," -Removes all trailing spaces from a string." -"Functions (String)","TRIM"," -TRIM ( [ { LEADING | TRAILING | BOTH } [ string ] FROM ] string ) -"," -Removes all leading spaces, trailing spaces, or spaces at both ends, from a string." -"Functions (String)","REGEXP_REPLACE"," -REGEXP_REPLACE(inputString, regexString, replacementString) -"," -Replaces each substring that matches a regular expression." -"Functions (String)","REPEAT"," -REPEAT(string, int) -"," -Returns a string repeated some number of times." -"Functions (String)","REPLACE"," -REPLACE(string, searchString [, replacementString]) -"," -Replaces all occurrences of a search string in a text with another string." -"Functions (String)","SOUNDEX"," -SOUNDEX(string) -"," -Returns a four character code representing the sound of a string." -"Functions (String)","SPACE"," -SPACE(int) -"," -Returns a string consisting of a number of spaces." -"Functions (String)","STRINGDECODE"," -STRINGDECODE(string) -"," -Converts a encoded string using the Java string literal encoding format." -"Functions (String)","STRINGENCODE"," -STRINGENCODE(string) -"," -Encodes special characters in a string using the Java string literal encoding format." -"Functions (String)","STRINGTOUTF8"," -STRINGTOUTF8(string) -"," -Encodes a string to a byte array using the UTF8 encoding format." -"Functions (String)","SUBSTRING"," -{ SUBSTRING | SUBSTR } ( string, startInt [, lengthInt ] ) -"," -Returns a substring of a string starting at a position." -"Functions (String)","UTF8TOSTRING"," -UTF8TOSTRING(bytes) -"," -Decodes a byte array in the UTF8 format to a string." -"Functions (String)","XMLATTR"," -XMLATTR(nameString, valueString) -"," -Creates an XML attribute element of the form name=""value""." -"Functions (String)","XMLNODE"," -XMLNODE(elementString [, attributesString [, contentString]]) -"," -Create an XML node element." -"Functions (String)","XMLCOMMENT"," -XMLCOMMENT(commentString) -"," -Creates an XML comment." -"Functions (String)","XMLCDATA"," -XMLCDATA(valueString) -"," -Creates an XML CDATA element." -"Functions (String)","XMLSTARTDOC"," -XMLSTARTDOC() -"," -The string '] The target file name (default\: backup.zip)\n[-dir ] The source directory (default\: .)\n[-db ] Source database; not required if there is only one\n[-quiet] Do not print progress information -org.h2.tools.ChangeFileEncryption=Allows changing the database file encryption password or algorithm.\nThis tool can not be used to change a password of a user.\n The database must be closed before using this tool. -org.h2.tools.ChangeFileEncryption.main=Options are case sensitive. Supported options are\:\n[-help] or [-?] Print the list of options\n[-cipher type] The encryption type (AES or XTEA)\n[-dir ] The database directory (default\: .)\n[-db ] Database name (all databases if not set)\n[-decrypt ] The decryption password (if not set\: not yet encrypted)\n[-encrypt ] The encryption password (if not set\: do not encrypt)\n[-quiet] Do not print progress information -org.h2.tools.Console=Starts the H2 Console (web-) server, as well as the TCP and PG server. -org.h2.tools.Console.main=When running without options, -tcp, -web, -browser and -pg are started.\nOptions are case sensitive. Supported options are\:\n[-help] or [-?] Print the list of options\n[-web] Start the web server with the H2 Console\n[-tool] Start the icon or window that allows to start a browser\n[-browser] Start a browser connecting to the web server\n[-tcp] Start the TCP server\n[-pg] Start the PG server\nFor each Server, additional options are available;\n for details, see the Server tool.\nIf a service can not be started, the program\n terminates with an exit code of 1. -org.h2.tools.ConvertTraceFile=Converts a .trace.db file to a SQL script and Java source code.\nSQL statement statistics are listed as well. -org.h2.tools.ConvertTraceFile.main=Options are case sensitive. Supported options are\:\n[-help] or [-?] Print the list of options\n[-traceFile ] The trace file name (default\: test.trace.db)\n[-script ] The script file name (default\: test.sql)\n[-javaClass ] The Java directory and class file name (default\: Test) -org.h2.tools.CreateCluster=Creates a cluster from a standalone database.\nCopies a database to another location if required. -org.h2.tools.CreateCluster.main=Options are case sensitive. Supported options are\:\n[-help] or [-?] Print the list of options\n[-urlSource ""] The database URL of the source database (jdbc\:h2\:...)\n[-urlTarget ""] The database URL of the target database (jdbc\:h2\:...)\n[-user ] The user name (default\: sa)\n[-password ] The password\n[-serverList ] The comma separated list of host names or IP addresses -org.h2.tools.DeleteDbFiles=Deletes all files belonging to a database.\nThe database must be closed before calling this tool. -org.h2.tools.DeleteDbFiles.main=Options are case sensitive. Supported options are\:\n[-help] or [-?] Print the list of options\n[-dir ] The directory (default\: .)\n[-db ] The database name\n[-quiet] Do not print progress information -org.h2.tools.Recover=Helps recovering a corrupted database. -org.h2.tools.Recover.main=Options are case sensitive. Supported options are\:\n[-help] or [-?] Print the list of options\n[-dir ] The directory (default\: .)\n[-db ] The database name (all databases if not set)\n[-trace] Print additional trace information\nEncrypted databases need to be decrypted first. -org.h2.tools.Restore=Restores a H2 database by extracting the database files from a .zip file. -org.h2.tools.Restore.main=Options are case sensitive. Supported options are\:\n[-help] or [-?] Print the list of options\n[-file ] The source file name (default\: backup.zip)\n[-dir ] The target directory (default\: .)\n[-db ] The target database name (as stored if not set)\n[-quiet] Do not print progress information -org.h2.tools.RunScript=Runs a SQL script against a database. -org.h2.tools.RunScript.main=Options are case sensitive. Supported options are\:\n[-help] or [-?] Print the list of options\n[-url ""] The database URL (jdbc\:...)\n[-user ] The user name (default\: sa)\n[-password ] The password\n[-script ] The script file to run (default\: backup.sql)\n[-driver ] The JDBC driver class to use (not required in most cases)\n[-showResults] Show the statements and the results of queries\n[-checkResults] Check if the query results match the expected results\n[-continueOnError] Continue even if the script contains errors\n[-options ...] RUNSCRIPT options (embedded H2; -*Results not supported) -org.h2.tools.Script=Creates a SQL script file by extracting the schema and data of a database. -org.h2.tools.Script.main=Options are case sensitive. Supported options are\:\n[-help] or [-?] Print the list of options\n[-url ""] The database URL (jdbc\:...)\n[-user ] The user name (default\: sa)\n[-password ] The password\n[-script ] The target script file name (default\: backup.sql)\n[-options ...] A list of options (only for embedded H2, see RUNSCRIPT)\n[-quiet] Do not print progress information -org.h2.tools.Server=Starts the H2 Console (web-) server, TCP, and PG server. -org.h2.tools.Server.main=When running without options, -tcp, -web, -browser and -pg are started.\nOptions are case sensitive. Supported options are\:\n[-help] or [-?] Print the list of options\n[-web] Start the web server with the H2 Console\n[-webAllowOthers] Allow other computers to connect - see below\n[-webDaemon] Use a daemon thread\n[-webPort ] The port (default\: 8082)\n[-webSSL] Use encrypted (HTTPS) connections\n[-browser] Start a browser connecting to the web server\n[-tcp] Start the TCP server\n[-tcpAllowOthers] Allow other computers to connect - see below\n[-tcpDaemon] Use a daemon thread\n[-tcpPort ] The port (default\: 9092)\n[-tcpSSL] Use encrypted (SSL) connections\n[-tcpPassword ] The password for shutting down a TCP server\n[-tcpShutdown ""] Stop the TCP server; example\: tcp\://localhost\n[-tcpShutdownForce] Do not wait until all connections are closed\n[-pg] Start the PG server\n[-pgAllowOthers] Allow other computers to connect - see below\n[-pgDaemon] Use a daemon thread\n[-pgPort ] The port (default\: 5435)\n[-baseDir ] The base directory for H2 databases (all servers)\n[-ifExists] Only existing databases may be opened (all servers)\n[-trace] Print additional trace information (all servers)\nThe options -xAllowOthers are potentially risky.\nFor details, see Advanced Topics / Protection against Remote Access. -org.h2.tools.Shell=Interactive command line tool to access a database using JDBC. -org.h2.tools.Shell.main=Options are case sensitive. Supported options are\:\n[-help] or [-?] Print the list of options\n[-url ""] The database URL (jdbc\:h2\:...)\n[-user ] The user name\n[-password ] The password\n[-driver ] The JDBC driver class to use (not required in most cases)\n[-sql ""] Execute the SQL statements and exit\nIf special characters don't work as expected, you may need to use\n -Dfile.encoding\=UTF-8 (Mac OS X) or CP850 (Windows). diff --git a/tools/h2/src/main/org/h2/result/LocalResult.java b/tools/h2/src/main/org/h2/result/LocalResult.java deleted file mode 100755 index 97d0d74..0000000 --- a/tools/h2/src/main/org/h2/result/LocalResult.java +++ /dev/null @@ -1,463 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.result; - -import java.sql.ResultSet; -import java.sql.ResultSetMetaData; -import java.sql.SQLException; -import java.util.ArrayList; -import org.h2.constant.SysProperties; -import org.h2.engine.Database; -import org.h2.engine.Session; -import org.h2.expression.Expression; -import org.h2.expression.ExpressionColumn; -import org.h2.message.DbException; -import org.h2.table.Column; -import org.h2.util.New; -import org.h2.util.ValueHashMap; -import org.h2.value.DataType; -import org.h2.value.Value; -import org.h2.value.ValueArray; - -/** - * A local result set contains all row data of a result set. - * This is the object generated by engine, - * and it is also used directly by the ResultSet class in the embedded mode. - * If the result does not fit in memory, it is written to a temporary file. - */ -public class LocalResult implements ResultInterface { - - private int maxMemoryRows; - private Session session; - private int visibleColumnCount; - private Expression[] expressions; - private int rowId, rowCount; - private ArrayList rows; - private SortOrder sort; - private ValueHashMap distinctRows; - private Value[] currentRow; - private int offset, limit; - private ResultExternal disk; - private int diskOffset; - private boolean distinct; - private boolean closed; - - /** - * Construct a local result object. - */ - public LocalResult() { - // nothing to do - } - - /** - * Construct a local result object. - * - * @param session the session - * @param expressions the expression array - * @param visibleColumnCount the number of visible columns - */ - public LocalResult(Session session, Expression[] expressions, int visibleColumnCount) { - this.session = session; - if (session == null) { - this.maxMemoryRows = Integer.MAX_VALUE; - } else { - this.maxMemoryRows = session.getDatabase().getMaxMemoryRows(); - } - rows = New.arrayList(); - this.visibleColumnCount = visibleColumnCount; - rowId = -1; - this.expressions = expressions; - } - - /** - * Construct a local result set by reading all data from a regular result set. - * - * @param session the session - * @param rs the result set - * @param maxrows the maximum number of rows to read (0 for no limit) - * @return the local result set - */ - public static LocalResult read(Session session, ResultSet rs, int maxrows) { - try { - Expression[] cols = getExpressionColumns(session, rs); - int columnCount = cols.length; - LocalResult result = new LocalResult(session, cols, columnCount); - for (int i = 0; (maxrows == 0 || i < maxrows) && rs.next(); i++) { - Value[] list = new Value[columnCount]; - for (int j = 0; j < columnCount; j++) { - int type = result.getColumnType(j); - list[j] = DataType.readValue(session, rs, j + 1, type); - } - result.addRow(list); - } - result.done(); - return result; - } catch (SQLException e) { - throw DbException.convert(e); - } - } - - private static Expression[] getExpressionColumns(Session session, ResultSet rs) throws SQLException { - ResultSetMetaData meta = rs.getMetaData(); - int columnCount = meta.getColumnCount(); - Expression[] expressions = new Expression[columnCount]; - Database db = session == null ? null : session.getDatabase(); - for (int i = 0; i < columnCount; i++) { - String name = meta.getColumnLabel(i + 1); - int type = DataType.convertSQLTypeToValueType(meta.getColumnType(i + 1)); - int precision = meta.getPrecision(i + 1); - int scale = meta.getScale(i + 1); - int displaySize = meta.getColumnDisplaySize(i + 1); - Column col = new Column(name, type, precision, scale, displaySize); - Expression expr = new ExpressionColumn(db, col); - expressions[i] = expr; - } - return expressions; - } - - /** - * Create a shallow copy of the result set. The data and a temporary table - * (if there is any) is not copied. - * - * @param targetSession the session of the copy - * @return the copy - */ - public LocalResult createShallowCopy(Session targetSession) { - if (disk == null && (rows == null || rows.size() < rowCount)) { - return null; - } - LocalResult copy = new LocalResult(); - copy.maxMemoryRows = this.maxMemoryRows; - copy.session = targetSession; - copy.visibleColumnCount = this.visibleColumnCount; - copy.expressions = this.expressions; - copy.rowId = -1; - copy.rowCount = this.rowCount; - copy.rows = this.rows; - copy.sort = this.sort; - copy.distinctRows = this.distinctRows; - copy.distinct = distinct; - copy.currentRow = null; - copy.offset = 0; - copy.limit = 0; - copy.disk = this.disk; - copy.diskOffset = this.diskOffset; - return copy; - } - - /** - * Set the sort order. - * - * @param sort the sort order - */ - public void setSortOrder(SortOrder sort) { - this.sort = sort; - } - - /** - * Remove duplicate rows. - */ - public void setDistinct() { - distinct = true; - distinctRows = ValueHashMap.newInstance(); - } - - /** - * Remove the row from the result set if it exists. - * - * @param values the row - */ - public void removeDistinct(Value[] values) { - if (!distinct) { - DbException.throwInternalError(); - } - if (distinctRows != null) { - ValueArray array = ValueArray.get(values); - distinctRows.remove(array); - rowCount = distinctRows.size(); - } else { - rowCount = disk.removeRow(values); - } - } - - /** - * Check if this result set contains the given row. - * - * @param values the row - * @return true if the row exists - */ - public boolean containsDistinct(Value[] values) { - if (!distinct) { - DbException.throwInternalError(); - } - if (distinctRows != null) { - ValueArray array = ValueArray.get(values); - return distinctRows.get(array) != null; - } - return disk.contains(values); - } - - public void reset() { - rowId = -1; - if (disk != null) { - disk.reset(); - if (diskOffset > 0) { - for (int i = 0; i < diskOffset; i++) { - disk.next(); - } - } - } - } - - public Value[] currentRow() { - return currentRow; - } - - public boolean next() { - if (rowId < rowCount) { - rowId++; - if (rowId < rowCount) { - if (disk != null) { - currentRow = disk.next(); - } else { - currentRow = rows.get(rowId); - } - return true; - } - currentRow = null; - } - return false; - } - - public int getRowId() { - return rowId; - } - - /** - * Add a row to this object. - * - * @param values the row to add - */ - public void addRow(Value[] values) { - if (distinct) { - if (distinctRows != null) { - ValueArray array = ValueArray.get(values); - distinctRows.put(array, values); - rowCount = distinctRows.size(); - if (rowCount > SysProperties.MAX_MEMORY_ROWS_DISTINCT && session.getDatabase().isPersistent()) { - disk = new ResultTempTable(session, sort); - disk.addRows(distinctRows.values()); - distinctRows = null; - } - } else { - rowCount = disk.addRow(values); - } - return; - } - rows.add(values); - rowCount++; - if (rows.size() > maxMemoryRows && session.getDatabase().isPersistent()) { - if (disk == null) { - disk = new ResultDiskBuffer(session, sort, values.length); - } - addRowsToDisk(); - } - } - - private void addRowsToDisk() { - disk.addRows(rows); - rows.clear(); - } - - public int getVisibleColumnCount() { - return visibleColumnCount; - } - - /** - * This method is called after all rows have been added. - */ - public void done() { - if (distinct) { - if (distinctRows != null) { - rows = distinctRows.values(); - distinctRows = null; - } else { - if (disk != null && sort != null) { - // external sort - ResultExternal temp = disk; - disk = null; - temp.reset(); - rows = New.arrayList(); - // TODO use offset directly if possible - while (true) { - Value[] list = temp.next(); - if (list == null) { - break; - } - if (disk == null) { - disk = new ResultDiskBuffer(session, sort, list.length); - } - rows.add(list); - if (rows.size() > maxMemoryRows) { - disk.addRows(rows); - rows.clear(); - } - } - temp.close(); - // the remaining data in rows is written in the following lines - } - } - } - if (disk != null) { - addRowsToDisk(); - disk.done(); - } else { - if (sort != null) { - sort.sort(rows); - } - } - applyOffset(); - applyLimit(); - reset(); - } - - public int getRowCount() { - return rowCount; - } - - /** - * Set the number of rows that this result will return at the maximum. - * - * @param limit the limit - */ - public void setLimit(int limit) { - this.limit = limit; - } - - private void applyLimit() { - if (limit <= 0) { - return; - } - if (disk == null) { - if (rows.size() > limit) { - rows = New.arrayList(rows.subList(0, limit)); - rowCount = limit; - } - } else { - if (limit < rowCount) { - rowCount = limit; - } - } - } - - public boolean needToClose() { - return disk != null; - } - - public void close() { - if (disk != null) { - disk.close(); - disk = null; - closed = true; - } - } - - public String getAlias(int i) { - return expressions[i].getAlias(); - } - - public String getTableName(int i) { - return expressions[i].getTableName(); - } - - public String getSchemaName(int i) { - return expressions[i].getSchemaName(); - } - - public int getDisplaySize(int i) { - return expressions[i].getDisplaySize(); - } - - public String getColumnName(int i) { - return expressions[i].getColumnName(); - } - - public int getColumnType(int i) { - return expressions[i].getType(); - } - - public long getColumnPrecision(int i) { - return expressions[i].getPrecision(); - } - - public int getNullable(int i) { - return expressions[i].getNullable(); - } - - public boolean isAutoIncrement(int i) { - return expressions[i].isAutoIncrement(); - } - - public int getColumnScale(int i) { - return expressions[i].getScale(); - } - - /** - * Set the offset of the first row to return. - * - * @param offset the offset - */ - public void setOffset(int offset) { - this.offset = offset; - } - - private void applyOffset() { - if (offset <= 0) { - return; - } - if (disk == null) { - if (offset >= rows.size()) { - rows.clear(); - rowCount = 0; - } else { - // avoid copying the whole array for each row - int remove = Math.min(offset, rows.size()); - rows = New.arrayList(rows.subList(remove, rows.size())); - rowCount -= remove; - } - } else { - if (offset >= rowCount) { - rowCount = 0; - } else { - diskOffset = offset; - rowCount -= offset; - } - } - } - - public String toString() { - return "columns: " + visibleColumnCount + " rows: " + rowCount + " pos: " + rowId; - } - - /** - * Check if this result set is closed. - * - * @return true if it is - */ - public boolean isClosed() { - return closed; - } - - public int getFetchSize() { - return 0; - } - - public void setFetchSize(int fetchSize) { - // ignore - } - -} diff --git a/tools/h2/src/main/org/h2/result/ResultColumn.java b/tools/h2/src/main/org/h2/result/ResultColumn.java deleted file mode 100755 index 46cdf50..0000000 --- a/tools/h2/src/main/org/h2/result/ResultColumn.java +++ /dev/null @@ -1,106 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.result; - -import java.io.IOException; - -import org.h2.value.Transfer; - -/** - * A result set column of a remote result. - */ -public class ResultColumn { - - /** - * The column alias. - */ - String alias; - - /** - * The schema name or null. - */ - String schemaName; - - /** - * The table name or null. - */ - String tableName; - - /** - * The column name or null. - */ - String columnName; - - /** - * The value type of this column. - */ - int columnType; - - /** - * The precision. - */ - long precision; - - /** - * The scale. - */ - int scale; - - /** - * The expected display size. - */ - int displaySize; - - /** - * True if this is an autoincrement column. - */ - boolean autoIncrement; - - /** - * True if this column is nullable. - */ - int nullable; - - /** - * Read an object from the given transfer object. - * - * @param in the object from where to read the data - */ - ResultColumn(Transfer in) throws IOException { - alias = in.readString(); - schemaName = in.readString(); - tableName = in.readString(); - columnName = in.readString(); - columnType = in.readInt(); - precision = in.readLong(); - scale = in.readInt(); - displaySize = in.readInt(); - autoIncrement = in.readBoolean(); - nullable = in.readInt(); - } - - /** - * Write a result column to the given output. - * - * @param out the object to where to write the data - * @param result the result - * @param i the column index - */ - public static void writeColumn(Transfer out, ResultInterface result, int i) throws IOException { - out.writeString(result.getAlias(i)); - out.writeString(result.getSchemaName(i)); - out.writeString(result.getTableName(i)); - out.writeString(result.getColumnName(i)); - out.writeInt(result.getColumnType(i)); - out.writeLong(result.getColumnPrecision(i)); - out.writeInt(result.getColumnScale(i)); - out.writeInt(result.getDisplaySize(i)); - out.writeBoolean(result.isAutoIncrement(i)); - out.writeInt(result.getNullable(i)); - } - -} diff --git a/tools/h2/src/main/org/h2/result/ResultDiskBuffer.java b/tools/h2/src/main/org/h2/result/ResultDiskBuffer.java deleted file mode 100755 index 36299b2..0000000 --- a/tools/h2/src/main/org/h2/result/ResultDiskBuffer.java +++ /dev/null @@ -1,233 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.result; - -import java.io.ByteArrayOutputStream; -import java.util.ArrayList; -import org.h2.constant.SysProperties; -import org.h2.engine.Constants; -import org.h2.engine.Database; -import org.h2.engine.Session; -import org.h2.message.DbException; -import org.h2.store.Data; -import org.h2.store.FileStore; -import org.h2.util.New; -import org.h2.value.Value; - -/** - * This class implements the disk buffer for the LocalResult class. - */ -class ResultDiskBuffer implements ResultExternal { - - private static final int READ_AHEAD = 128; - - private Data rowBuff; - private FileStore file; - private ArrayList tapes; - private ResultDiskTape mainTape; - private SortOrder sort; - private int columnCount; - - /** - * Represents a virtual disk tape for the merge sort algorithm. - * Each virtual disk tape is a region of the temp file. - */ - static class ResultDiskTape { - - /** - * The start position of this tape in the file. - */ - long start; - - /** - * The end position of this tape in the file. - */ - long end; - - /** - * The current read position. - */ - long pos; - - /** - * A list of rows in the buffer. - */ - ArrayList buffer = New.arrayList(); - } - - ResultDiskBuffer(Session session, SortOrder sort, int columnCount) { - this.sort = sort; - this.columnCount = columnCount; - Database db = session.getDatabase(); - rowBuff = Data.create(db, SysProperties.PAGE_SIZE); - String fileName = session.getDatabase().createTempFile(); - file = session.getDatabase().openFile(fileName, "rw", false); - file.setCheckedWriting(false); - file.seek(FileStore.HEADER_LENGTH); - if (sort != null) { - tapes = New.arrayList(); - } else { - mainTape = new ResultDiskTape(); - mainTape.pos = FileStore.HEADER_LENGTH; - } - } - - public void addRows(ArrayList rows) { - if (sort != null) { - sort.sort(rows); - } - Data buff = rowBuff; - long start = file.getFilePointer(); - ByteArrayOutputStream buffer = new ByteArrayOutputStream(); - int bufferLen = 0; - int maxBufferSize = SysProperties.LARGE_RESULT_BUFFER_SIZE; - for (Value[] row : rows) { - buff.reset(); - buff.writeInt(0); - for (int j = 0; j < columnCount; j++) { - Value v = row[j]; - buff.checkCapacity(buff.getValueLen(v)); - buff.writeValue(v); - } - buff.fillAligned(); - int len = buff.length(); - buff.setInt(0, len); - if (maxBufferSize > 0) { - buffer.write(buff.getBytes(), 0, len); - bufferLen += len; - if (bufferLen > maxBufferSize) { - byte[] data = buffer.toByteArray(); - buffer.reset(); - file.write(data, 0, data.length); - bufferLen = 0; - } - } else { - file.write(buff.getBytes(), 0, len); - } - } - if (bufferLen > 0) { - byte[] data = buffer.toByteArray(); - file.write(data, 0, data.length); - } - if (sort != null) { - ResultDiskTape tape = new ResultDiskTape(); - tape.start = start; - tape.end = file.getFilePointer(); - tapes.add(tape); - } else { - mainTape.end = file.getFilePointer(); - } - } - - public void done() { - file.seek(FileStore.HEADER_LENGTH); - file.autoDelete(); - } - - public void reset() { - if (sort != null) { - for (ResultDiskTape tape : tapes) { - tape.pos = tape.start; - tape.buffer = New.arrayList(); - } - } else { - mainTape.pos = FileStore.HEADER_LENGTH; - mainTape.buffer = New.arrayList(); - } - } - - private void readRow(ResultDiskTape tape) { - int min = Constants.FILE_BLOCK_SIZE; - Data buff = rowBuff; - buff.reset(); - file.readFully(buff.getBytes(), 0, min); - int len = buff.readInt(); - buff.checkCapacity(len); - if (len - min > 0) { - file.readFully(buff.getBytes(), min, len - min); - } - tape.pos += len; - Value[] row = new Value[columnCount]; - for (int k = 0; k < columnCount; k++) { - row[k] = buff.readValue(); - } - tape.buffer.add(row); - } - - public Value[] next() { - return sort != null ? nextSorted() : nextUnsorted(); - } - - private Value[] nextUnsorted() { - file.seek(mainTape.pos); - if (mainTape.buffer.size() == 0) { - for (int j = 0; mainTape.pos < mainTape.end && j < READ_AHEAD; j++) { - readRow(mainTape); - } - } - Value[] row = mainTape.buffer.get(0); - mainTape.buffer.remove(0); - return row; - } - - private Value[] nextSorted() { - int next = -1; - for (int i = 0; i < tapes.size(); i++) { - ResultDiskTape tape = tapes.get(i); - if (tape.buffer.size() == 0 && tape.pos < tape.end) { - file.seek(tape.pos); - for (int j = 0; tape.pos < tape.end && j < READ_AHEAD; j++) { - readRow(tape); - } - } - if (tape.buffer.size() > 0) { - if (next == -1) { - next = i; - } else if (compareTapes(tape, tapes.get(next)) < 0) { - next = i; - } - } - } - ResultDiskTape t = tapes.get(next); - Value[] row = t.buffer.get(0); - t.buffer.remove(0); - return row; - } - - private int compareTapes(ResultDiskTape a, ResultDiskTape b) { - Value[] va = a.buffer.get(0); - Value[] vb = b.buffer.get(0); - return sort.compare(va, vb); - } - - protected void finalize() { - if (!SysProperties.runFinalize) { - return; - } - close(); - } - - public void close() { - if (file != null) { - file.closeAndDeleteSilently(); - file = null; - } - } - - public int removeRow(Value[] values) { - throw DbException.throwInternalError(); - } - - public boolean contains(Value[] values) { - throw DbException.throwInternalError(); - } - - public int addRow(Value[] values) { - throw DbException.throwInternalError(); - } - -} diff --git a/tools/h2/src/main/org/h2/result/ResultExternal.java b/tools/h2/src/main/org/h2/result/ResultExternal.java deleted file mode 100755 index 8ee2e54..0000000 --- a/tools/h2/src/main/org/h2/result/ResultExternal.java +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.result; - -import java.util.ArrayList; -import org.h2.value.Value; - -/** - * This interface is used to extend the LocalResult class, if data does not fit - * in memory. - */ -public interface ResultExternal { - - /** - * Reset the current position of this object. - */ - void reset(); - - /** - * Get the next row from the result. - * - * @return the next row or null - */ - Value[] next(); - - /** - * Add a number of rows to the result. - * - * @param rows the list of rows to add - */ - void addRows(ArrayList rows); - - /** - * This method is called after all rows have been added. - */ - void done(); - - /** - * Close this object and delete the temporary file. - */ - void close(); - - /** - * Remove the row with the given values from this object if such a row - * exists. - * - * @param values the row - * @return the new row count - */ - int removeRow(Value[] values); - - /** - * Check if the given row exists in this object. - * - * @param values the row - * @return true if it exists - */ - boolean contains(Value[] values); - - /** - * Add a row to this object. - * - * @param values the row to add - * @return the new number of rows in this object - */ - int addRow(Value[] values); - -} diff --git a/tools/h2/src/main/org/h2/result/ResultInterface.java b/tools/h2/src/main/org/h2/result/ResultInterface.java deleted file mode 100755 index 7b20416..0000000 --- a/tools/h2/src/main/org/h2/result/ResultInterface.java +++ /dev/null @@ -1,167 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.result; - -import org.h2.value.Value; - -/** - * The result interface is used by the LocalResult and ResultRemote class. - * A result may contain rows, or just an update count. - */ -public interface ResultInterface { - - /** - * Go to the beginning of the result, that means - * before the first row. - */ - void reset(); - - /** - * Get the current row. - * - * @return the row - */ - Value[] currentRow(); - - /** - * Go to the next row. - * - * @return true if a row exists - */ - boolean next(); - - /** - * Get the current row id, starting with 0. - * -1 is returned when next() was not called yet. - * - * @return the row id - */ - int getRowId(); - - /** - * Get the number of visible columns. - * More columns may exist internally for sorting or grouping. - * - * @return the number of columns - */ - int getVisibleColumnCount(); - - /** - * Get the number of rows in this object. - * - * @return the number of rows - */ - int getRowCount(); - - /** - * Check if this result set should be closed, for example because it is - * buffered using a temporary file. - * - * @return true if close should be called. - */ - boolean needToClose(); - - /** - * Close the result and delete any temporary files - */ - void close(); - - /** - * Get the column alias name for the column. - * - * @param i the column number (starting with 0) - * @return the alias name - */ - String getAlias(int i); - - /** - * Get the schema name for the column, if one exists. - * - * @param i the column number (starting with 0) - * @return the schema name or null - */ - String getSchemaName(int i); - - /** - * Get the table name for the column, if one exists. - * - * @param i the column number (starting with 0) - * @return the table name or null - */ - String getTableName(int i); - - /** - * Get the column name. - * - * @param i the column number (starting with 0) - * @return the column name - */ - String getColumnName(int i); - - /** - * Get the column data type. - * - * @param i the column number (starting with 0) - * @return the column data type - */ - int getColumnType(int i); - - /** - * Get the precision for this column. - * - * @param i the column number (starting with 0) - * @return the precision - */ - long getColumnPrecision(int i); - - /** - * Get the scale for this column. - * - * @param i the column number (starting with 0) - * @return the scale - */ - int getColumnScale(int i); - - /** - * Get the display size for this column. - * - * @param i the column number (starting with 0) - * @return the display size - */ - int getDisplaySize(int i); - - /** - * Check if this is an auto-increment column. - * - * @param i the column number (starting with 0) - * @return true for auto-increment columns - */ - boolean isAutoIncrement(int i); - - /** - * Check if this column is nullable. - * - * @param i the column number (starting with 0) - * @return Column.NULLABLE_* - */ - int getNullable(int i); - - /** - * Set the fetch size for this result set. - * - * @param fetchSize the new fetch size - */ - void setFetchSize(int fetchSize); - - /** - * Get the current fetch size for this result set. - * - * @return the fetch size - */ - int getFetchSize(); - -} diff --git a/tools/h2/src/main/org/h2/result/ResultRemote.java b/tools/h2/src/main/org/h2/result/ResultRemote.java deleted file mode 100755 index 9b408f9..0000000 --- a/tools/h2/src/main/org/h2/result/ResultRemote.java +++ /dev/null @@ -1,252 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.result; - -import java.io.IOException; -import java.util.ArrayList; -import org.h2.constant.SysProperties; -import org.h2.engine.SessionRemote; -import org.h2.message.DbException; -import org.h2.message.Trace; -import org.h2.util.New; -import org.h2.value.Transfer; -import org.h2.value.Value; - -/** - * The client side part of a result set that is kept on the server. - * In many cases, the complete data is kept on the client side, - * but for large results only a subset is in-memory. - */ -public class ResultRemote implements ResultInterface { - - private int fetchSize; - private SessionRemote session; - private Transfer transfer; - private int id; - private ResultColumn[] columns; - private Value[] currentRow; - private int rowId, rowCount, rowOffset; - private ArrayList result; - private ArrayList lobValues; - private final Trace trace; - - public ResultRemote(SessionRemote session, Transfer transfer, int id, int columnCount, int fetchSize) - throws IOException { - this.session = session; - trace = session.getTrace(); - this.transfer = transfer; - this.id = id; - this.columns = new ResultColumn[columnCount]; - rowCount = transfer.readInt(); - for (int i = 0; i < columnCount; i++) { - columns[i] = new ResultColumn(transfer); - } - rowId = -1; - result = New.arrayList(); - this.fetchSize = fetchSize; - fetchRows(false); - } - - public String getAlias(int i) { - return columns[i].alias; - } - - public String getSchemaName(int i) { - return columns[i].schemaName; - } - - public String getTableName(int i) { - return columns[i].tableName; - } - - public String getColumnName(int i) { - return columns[i].columnName; - } - - public int getColumnType(int i) { - return columns[i].columnType; - } - - public long getColumnPrecision(int i) { - return columns[i].precision; - } - - public int getColumnScale(int i) { - return columns[i].scale; - } - - public int getDisplaySize(int i) { - return columns[i].displaySize; - } - - public boolean isAutoIncrement(int i) { - return columns[i].autoIncrement; - } - - public int getNullable(int i) { - return columns[i].nullable; - } - - public void reset() { - rowId = -1; - currentRow = null; - if (session == null) { - return; - } - synchronized (session) { - session.checkClosed(); - try { - session.traceOperation("RESULT_RESET", id); - transfer.writeInt(SessionRemote.RESULT_RESET).writeInt(id).flush(); - } catch (IOException e) { - throw DbException.convertIOException(e, null); - } - } - } - - public Value[] currentRow() { - return currentRow; - } - - public boolean next() { - if (rowId < rowCount) { - rowId++; - remapIfOld(); - if (rowId < rowCount) { - if (rowId - rowOffset >= result.size()) { - fetchRows(true); - } - currentRow = result.get(rowId - rowOffset); - return true; - } - currentRow = null; - } - return false; - } - - public int getRowId() { - return rowId; - } - - public int getVisibleColumnCount() { - return columns.length; - } - - public int getRowCount() { - return rowCount; - } - - private void sendClose() { - if (session == null) { - return; - } - // TODO result sets: no reset possible for larger remote result sets - try { - synchronized (session) { - session.traceOperation("RESULT_CLOSE", id); - transfer.writeInt(SessionRemote.RESULT_CLOSE).writeInt(id); - } - } catch (IOException e) { - trace.error("close", e); - } finally { - transfer = null; - session = null; - } - } - - public void close() { - if (lobValues != null) { - for (Value v : lobValues) { - try { - v.close(); - } catch (DbException e) { - trace.error("delete lob " + v.getTraceSQL(), e); - } - } - lobValues = null; - } - result = null; - sendClose(); - } - - private void remapIfOld() { - if (session == null) { - return; - } - try { - if (id <= session.getCurrentId() - SysProperties.SERVER_CACHED_OBJECTS / 2) { - // object is too old - we need to map it to a new id - int newId = session.getNextId(); - session.traceOperation("CHANGE_ID", id); - transfer.writeInt(SessionRemote.CHANGE_ID).writeInt(id).writeInt(newId); - id = newId; - // TODO remote result set: very old result sets may be - // already removed on the server (theoretically) - how to - // solve this? - } - } catch (IOException e) { - throw DbException.convertIOException(e, null); - } - } - - private void fetchRows(boolean sendFetch) { - synchronized (session) { - session.checkClosed(); - try { - rowOffset += result.size(); - result.clear(); - int fetch = Math.min(fetchSize, rowCount - rowOffset); - if (sendFetch) { - session.traceOperation("RESULT_FETCH_ROWS", id); - transfer.writeInt(SessionRemote.RESULT_FETCH_ROWS).writeInt(id).writeInt(fetch); - session.done(transfer); - } - for (int r = 0; r < fetch; r++) { - boolean row = transfer.readBoolean(); - if (!row) { - break; - } - int len = columns.length; - Value[] values = new Value[len]; - for (int i = 0; i < len; i++) { - Value v = transfer.readValue(); - values[i] = v; - if (v.isFileBased()) { - if (lobValues == null) { - lobValues = New.arrayList(); - } - lobValues.add(v); - } - } - result.add(values); - } - if (rowOffset + result.size() >= rowCount) { - sendClose(); - } - } catch (IOException e) { - throw DbException.convertIOException(e, null); - } - } - } - - public String toString() { - return "columns: " + columns.length + " rows: " + rowCount + " pos: " + rowId; - } - - public int getFetchSize() { - return fetchSize; - } - - public void setFetchSize(int fetchSize) { - this.fetchSize = fetchSize; - } - - public boolean needToClose() { - return true; - } - -} diff --git a/tools/h2/src/main/org/h2/result/ResultTempTable.java b/tools/h2/src/main/org/h2/result/ResultTempTable.java deleted file mode 100755 index db5ce84..0000000 --- a/tools/h2/src/main/org/h2/result/ResultTempTable.java +++ /dev/null @@ -1,163 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.result; - -import java.util.ArrayList; -import org.h2.command.ddl.CreateTableData; -import org.h2.engine.Constants; -import org.h2.engine.Database; -import org.h2.engine.Session; -import org.h2.index.Cursor; -import org.h2.index.Index; -import org.h2.index.IndexType; -import org.h2.index.PageBtreeIndex; -import org.h2.schema.Schema; -import org.h2.table.Column; -import org.h2.table.IndexColumn; -import org.h2.table.RegularTable; -import org.h2.value.Value; -import org.h2.value.ValueArray; - -/** - * This class implements the temp table buffer for the LocalResult class. - */ -public class ResultTempTable implements ResultExternal { - - private static final String COLUMN_NAME = "DATA"; - private Session session; - private RegularTable table; - private SortOrder sort; - private Index index; - private Cursor resultCursor; - - public ResultTempTable(Session session, SortOrder sort) { - this.session = session; - this.sort = sort; - Schema schema = session.getDatabase().getSchema(Constants.SCHEMA_MAIN); - Column column = new Column(COLUMN_NAME, Value.ARRAY); - column.setNullable(false); - CreateTableData data = new CreateTableData(); - data.columns.add(column); - data.id = session.getDatabase().allocateObjectId(); - data.tableName = "TEMP_RESULT_SET_" + data.id; - data.temporary = true; - data.persistIndexes = false; - data.persistData = true; - data.create = true; - data.session = session; - table = (RegularTable) schema.createTable(data); - int indexId = session.getDatabase().allocateObjectId(); - IndexColumn indexColumn = new IndexColumn(); - indexColumn.column = column; - indexColumn.columnName = COLUMN_NAME; - IndexType indexType; - indexType = IndexType.createPrimaryKey(true, false); - IndexColumn[] indexCols = { indexColumn }; - index = new PageBtreeIndex(table, indexId, data.tableName, indexCols, indexType, true, session); - index.setTemporary(true); - table.getIndexes().add(index); - } - - public int removeRow(Value[] values) { - Row row = convertToRow(values); - Cursor cursor = find(row); - if (cursor != null) { - row = cursor.get(); - table.removeRow(session, row); - } - return (int) table.getRowCount(session); - } - - public boolean contains(Value[] values) { - return find(convertToRow(values)) != null; - } - - public int addRow(Value[] values) { - Row row = convertToRow(values); - Cursor cursor = find(row); - if (cursor == null) { - table.addRow(session, row); - } - return (int) table.getRowCount(session); - } - - public void addRows(ArrayList rows) { - if (sort != null) { - sort.sort(rows); - } - for (Value[] values : rows) { - addRow(values); - } - } - - public void close() { - if (table == null) { - return; - } - try { - table.truncate(session); - Database database = session.getDatabase(); - synchronized (database) { - Session sysSession = database.getSystemSession(); - if (!database.isSysTableLocked()) { - // this session may not lock the sys table (except if it already has locked it) - // because it must be committed immediately - // otherwise other threads can not access the sys table. - // if the table is not removed now, it will be when the database - // is opened the next time - // (the table is truncated, so this is just one record) - synchronized (sysSession) { - index.removeChildrenAndResources(sysSession); - table.removeChildrenAndResources(sysSession); - // the transaction must be committed immediately - sysSession.commit(false); - } - } - } - } finally { - table = null; - } - } - - public void done() { - // nothing to do - } - - public Value[] next() { - if (!resultCursor.next()) { - return null; - } - Row row = resultCursor.get(); - ValueArray data = (ValueArray) row.getValue(0); - return data.getList(); - } - - public void reset() { - resultCursor = index.find(session, null, null); - } - - private Row convertToRow(Value[] values) { - ValueArray data = ValueArray.get(values); - return new Row(new Value[]{data}, data.getMemory()); - } - - private Cursor find(Row row) { - Cursor cursor = index.find(session, row, row); - Value a = row.getValue(0); - while (cursor.next()) { - SearchRow found; - found = cursor.getSearchRow(); - Value b = found.getValue(0); - if (session.getDatabase().areEqual(a, b)) { - return cursor; - } - } - return null; - } - -} - diff --git a/tools/h2/src/main/org/h2/result/Row.java b/tools/h2/src/main/org/h2/result/Row.java deleted file mode 100755 index 41e9cdb..0000000 --- a/tools/h2/src/main/org/h2/result/Row.java +++ /dev/null @@ -1,139 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.result; - -import org.h2.store.Data; -import org.h2.util.StatementBuilder; -import org.h2.value.Value; - -/** - * Represents a row in a table. - */ -public class Row implements SearchRow { - - public static final int MEMORY_CALCULATE = -1; - private long key; - private final Value[] data; - private final int memory; - private int version; - private boolean deleted; - private int sessionId; - - public Row(Value[] data, int memory) { - this.data = data; - if (memory != MEMORY_CALCULATE) { - this.memory = 16 + memory * 4; - } else { - this.memory = MEMORY_CALCULATE; - } - } - - public void setKeyAndVersion(SearchRow row) { - setKey(row.getKey()); - setVersion(row.getVersion()); - } - - public int getVersion() { - return version; - } - - public void setVersion(int version) { - this.version = version; - } - - public long getKey() { - return key; - } - - public void setKey(long key) { - this.key = key; - } - - public Value getValue(int i) { - return data[i]; - } - - /** - * Get the number of bytes required for the data. - * - * @param dummy the template buffer - * @return the number of bytes - */ - public int getByteCount(Data dummy) { - int size = 0; - for (Value v : data) { - size += dummy.getValueLen(v); - } - return size; - } - - public void setValue(int i, Value v) { - data[i] = v; - } - - public boolean isEmpty() { - return data == null; - } - - public int getColumnCount() { - return data.length; - } - - public int getMemorySize() { - if (memory != MEMORY_CALCULATE) { - return memory; - } - int m = 8; - for (int i = 0; data != null && i < data.length; i++) { - m += data[i].getMemory(); - } - return m; - } - - public String toString() { - StatementBuilder buff = new StatementBuilder("( /* key:"); - buff.append(getKey()); - if (version != 0) { - buff.append(" v:" + version); - } - if (isDeleted()) { - buff.append(" deleted"); - } - buff.append(" */ "); - if (data != null) { - for (Value v : data) { - buff.appendExceptFirst(", "); - buff.append(v == null ? "null" : v.getTraceSQL()); - } - } - return buff.append(')').toString(); - } - - public void setDeleted(boolean deleted) { - this.deleted = deleted; - } - - public void setSessionId(int sessionId) { - this.sessionId = sessionId; - } - - public int getSessionId() { - return sessionId; - } - - /** - * This record has been committed. The session id is reset. - */ - public void commit() { - this.sessionId = 0; - } - - public boolean isDeleted() { - return deleted; - } - -} diff --git a/tools/h2/src/main/org/h2/result/RowList.java b/tools/h2/src/main/org/h2/result/RowList.java deleted file mode 100755 index 34ee4cd..0000000 --- a/tools/h2/src/main/org/h2/result/RowList.java +++ /dev/null @@ -1,263 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.result; - -import java.util.ArrayList; -import org.h2.constant.SysProperties; -import org.h2.engine.Constants; -import org.h2.engine.Database; -import org.h2.engine.Session; -import org.h2.store.Data; -import org.h2.store.FileStore; -import org.h2.util.New; -import org.h2.value.Value; - -/** - * A list of rows. If the list grows too large, it is buffered to disk - * automatically. - */ -public class RowList { - - private final Session session; - private final ArrayList list = New.arrayList(); - private int size; - private int index, listIndex; - private FileStore file; - private Data rowBuff; - private ArrayList lobs; - private int memory, maxMemory; - private boolean written; - private boolean readUncached; - - /** - * Construct a new row list for this session. - * - * @param session the session - */ - public RowList(Session session) { - this.session = session; - if (SysProperties.DEFAULT_MAX_OPERATION_MEMORY > 0 && session.getDatabase().isPersistent()) { - maxMemory = session.getDatabase().getMaxOperationMemory(); - } - } - - private void writeRow(Data buff, Row r) { - buff.checkCapacity(1 + Data.LENGTH_INT * 8); - buff.writeByte((byte) 1); - buff.writeInt(r.getMemorySize()); - buff.writeInt(r.getColumnCount()); - buff.writeLong(r.getKey()); - buff.writeInt(r.getVersion()); - buff.writeInt(r.isDeleted() ? 1 : 0); - buff.writeInt(r.getSessionId()); - for (int i = 0; i < r.getColumnCount(); i++) { - Value v = r.getValue(i); - buff.checkCapacity(1); - if (v == null) { - buff.writeByte((byte) 0); - } else { - buff.writeByte((byte) 1); - if (v.getType() == Value.CLOB || v.getType() == Value.BLOB) { - // need to keep a reference to temporary lobs, - // otherwise the temp file is deleted - if (v.getSmall() == null && v.getTableId() == 0) { - if (lobs == null) { - lobs = New.arrayList(); - } - // need to create a copy, otherwise, - // if stored multiple times, it may be renamed - // and then not found - v = v.copyToTemp(); - lobs.add(v); - } - } - buff.checkCapacity(buff.getValueLen(v)); - buff.writeValue(v); - } - } - } - - private void writeAllRows() { - if (file == null) { - Database db = session.getDatabase(); - String fileName = db.createTempFile(); - file = db.openFile(fileName, "rw", false); - file.seek(FileStore.HEADER_LENGTH); - rowBuff = Data.create(db, SysProperties.PAGE_SIZE); - file.seek(FileStore.HEADER_LENGTH); - } - Data buff = rowBuff; - initBuffer(buff); - for (int i = 0; i < list.size(); i++) { - if (i > 0 && buff.length() > Constants.IO_BUFFER_SIZE) { - flushBuffer(buff); - initBuffer(buff); - } - Row r = list.get(i); - writeRow(buff, r); - } - flushBuffer(buff); - file.autoDelete(); - list.clear(); - memory = 0; - } - - private void initBuffer(Data buff) { - buff.reset(); - buff.writeInt(0); - } - - private void flushBuffer(Data buff) { - buff.checkCapacity(1); - buff.writeByte((byte) 0); - buff.fillAligned(); - buff.setInt(0, buff.length() / Constants.FILE_BLOCK_SIZE); - file.write(buff.getBytes(), 0, buff.length()); - } - - /** - * Add a row to the list. - * - * @param r the row to add - */ - public void add(Row r) { - list.add(r); - memory += r.getMemorySize(); - if (maxMemory > 0 && memory > maxMemory) { - writeAllRows(); - } - size++; - } - - /** - * Remove all rows from the list. - */ - public void reset() { - index = 0; - if (file != null) { - listIndex = 0; - if (!written) { - writeAllRows(); - written = true; - } - list.clear(); - file.seek(FileStore.HEADER_LENGTH); - } - } - - /** - * Check if there are more rows in this list. - * - * @return true it there are more rows - */ - public boolean hasNext() { - return index < size; - } - - private Row readRow(Data buff) { - if (buff.readByte() == 0) { - return null; - } - int mem = buff.readInt(); - int columnCount = buff.readInt(); - long key = buff.readLong(); - int version = buff.readInt(); - if (readUncached) { - key = 0; - } - boolean deleted = buff.readInt() == 1; - int sessionId = buff.readInt(); - Value[] values = new Value[columnCount]; - for (int i = 0; i < columnCount; i++) { - Value v; - if (buff.readByte() == 0) { - v = null; - } else { - v = buff.readValue(); - if (v.isLinked()) { - // the table id is 0 if it was linked when writing - // a temporary entry - if (v.getTableId() == 0) { - session.unlinkAtCommit(v); - } - } - } - values[i] = v; - } - Row row = new Row(values, mem); - row.setKey(key); - row.setVersion(version); - row.setDeleted(deleted); - row.setSessionId(sessionId); - return row; - } - - /** - * Get the next row from the list. - * - * @return the next row - */ - public Row next() { - Row r; - if (file == null) { - r = list.get(index++); - } else { - if (listIndex >= list.size()) { - list.clear(); - listIndex = 0; - Data buff = rowBuff; - buff.reset(); - int min = Constants.FILE_BLOCK_SIZE; - file.readFully(buff.getBytes(), 0, min); - int len = buff.readInt() * Constants.FILE_BLOCK_SIZE; - buff.checkCapacity(len); - if (len - min > 0) { - file.readFully(buff.getBytes(), min, len - min); - } - for (int i = 0;; i++) { - r = readRow(buff); - if (r == null) { - break; - } - list.add(r); - } - } - index++; - r = list.get(listIndex++); - } - return r; - } - - /** - * Get the number of rows in this list. - * - * @return the number of rows - */ - public int size() { - return size; - } - - /** - * Do not use the cache. - */ - public void invalidateCache() { - readUncached = true; - } - - /** - * Close the result list and delete the temporary file. - */ - public void close() { - if (file != null) { - file.autoDelete(); - file.closeAndDeleteSilently(); - file = null; - rowBuff = null; - } - } - -} diff --git a/tools/h2/src/main/org/h2/result/SearchRow.java b/tools/h2/src/main/org/h2/result/SearchRow.java deleted file mode 100755 index fdcc4d2..0000000 --- a/tools/h2/src/main/org/h2/result/SearchRow.java +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.result; - -import org.h2.value.Value; - -/** - * The interface for rows stored in a table, and for partial rows stored in the - * index. - */ -public interface SearchRow { - - /** - * Get the column count. - * - * @return the column count - */ - int getColumnCount(); - - /** - * Get the value for the column - * - * @param index the column number (starting with 0) - * @return the value - */ - Value getValue(int index); - - /** - * Set the value for given column - * - * @param index the column number (starting with 0) - * @param v the new value - */ - void setValue(int index, Value v); - - /** - * Set the position and version to match another row. - * - * @param old the other row. - */ - void setKeyAndVersion(SearchRow old); - - /** - * Get the version of the row. - * - * @return the version - */ - int getVersion(); - - /** - * Set the unique key of the row. - * - * @param key the key - */ - void setKey(long key); - - /** - * Get the unique key of the row. - * - * @return the key - */ - long getKey(); - -} diff --git a/tools/h2/src/main/org/h2/result/SimpleRow.java b/tools/h2/src/main/org/h2/result/SimpleRow.java deleted file mode 100755 index b526d2d..0000000 --- a/tools/h2/src/main/org/h2/result/SimpleRow.java +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.result; - -import org.h2.util.StatementBuilder; -import org.h2.value.Value; - -/** - * Represents a simple row without state. - */ -public class SimpleRow implements SearchRow { - - private long key; - private int version; - private Value[] data; - - public SimpleRow(Value[] data) { - this.data = data; - } - - public int getColumnCount() { - return data.length; - } - - public long getKey() { - return key; - } - - public void setKey(long key) { - this.key = key; - } - - public void setKeyAndVersion(SearchRow row) { - key = row.getKey(); - version = row.getVersion(); - } - - public int getVersion() { - return version; - } - - public void setValue(int i, Value v) { - data[i] = v; - } - - public Value getValue(int i) { - return data[i]; - } - - public String toString() { - StatementBuilder buff = new StatementBuilder("( /* key:"); - buff.append(getKey()); - if (version != 0) { - buff.append(" v:" + version); - } - buff.append(" */ "); - for (Value v : data) { - buff.appendExceptFirst(", "); - buff.append(v == null ? "null" : v.getTraceSQL()); - } - return buff.append(')').toString(); - } - -} diff --git a/tools/h2/src/main/org/h2/result/SimpleRowValue.java b/tools/h2/src/main/org/h2/result/SimpleRowValue.java deleted file mode 100755 index b36051d..0000000 --- a/tools/h2/src/main/org/h2/result/SimpleRowValue.java +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.result; - -import org.h2.value.Value; - -/** - * A simple row that contains data for only one column. - */ -public class SimpleRowValue implements SearchRow { - - private long key; - private int version; - private int index; - private int virtualColumnCount; - private Value data; - - public SimpleRowValue(int columnCount) { - this.virtualColumnCount = columnCount; - } - - public void setKeyAndVersion(SearchRow row) { - key = row.getKey(); - version = row.getVersion(); - } - - public int getVersion() { - return version; - } - - public int getColumnCount() { - return virtualColumnCount; - } - - public long getKey() { - return key; - } - - public void setKey(long key) { - this.key = key; - } - - public Value getValue(int idx) { - return idx == index ? data : null; - } - - public void setValue(int idx, Value v) { - index = idx; - data = v; - } - - public String toString() { - return "( /* " + key + " */ " + (data == null ? "null" : data.getTraceSQL()) + " )"; - } - -} diff --git a/tools/h2/src/main/org/h2/result/SortOrder.java b/tools/h2/src/main/org/h2/result/SortOrder.java deleted file mode 100755 index 96bdf0c..0000000 --- a/tools/h2/src/main/org/h2/result/SortOrder.java +++ /dev/null @@ -1,176 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.result; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.Comparator; -import org.h2.constant.SysProperties; -import org.h2.engine.Database; -import org.h2.expression.Expression; -import org.h2.util.StatementBuilder; -import org.h2.util.StringUtils; -import org.h2.value.Value; -import org.h2.value.ValueNull; - -/** - * A sort order represents an ORDER BY clause in a query. - */ -public class SortOrder implements Comparator { - - /** - * This bit mask means the values should be sorted in ascending order. - */ - public static final int ASCENDING = 0; - - /** - * This bit mask means the values should be sorted in descending order. - */ - public static final int DESCENDING = 1; - - /** - * This bit mask means NULLs should be sorted before other data, no matter - * if ascending or descending order is used. - */ - public static final int NULLS_FIRST = 2; - - /** - * This bit mask means NULLs should be sorted after other data, no matter - * if ascending or descending order is used. - */ - public static final int NULLS_LAST = 4; - - /** - * The default sort order for NULL. - */ - private static final int DEFAULT_NULL_SORT = SysProperties.SORT_NULLS_HIGH ? 1 : -1; - - private final Database database; - private final int[] indexes; - private final int[] sortTypes; - - /** - * Construct a new sort order object. - * - * @param database the database - * @param index the column index list - * @param sortType the sort order bit masks - */ - public SortOrder(Database database, int[] index, int[] sortType) { - this.database = database; - this.indexes = index; - this.sortTypes = sortType; - } - - /** - * Create the SQL snippet that describes this sort order. - * This is the SQL snippet that usually appears after the ORDER BY clause. - * - * @param list the expression list - * @param visible the number of columns in the select list - * @return the SQL snippet - */ - public String getSQL(Expression[] list, int visible) { - StatementBuilder buff = new StatementBuilder(); - int i = 0; - for (int idx : indexes) { - buff.appendExceptFirst(", "); - if (idx < visible) { - buff.append(idx + 1); - } else { - buff.append('=').append(StringUtils.unEnclose(list[idx].getSQL())); - } - int type = sortTypes[i++]; - if ((type & DESCENDING) != 0) { - buff.append(" DESC"); - } - if ((type & NULLS_FIRST) != 0) { - buff.append(" NULLS FIRST"); - } else if ((type & NULLS_LAST) != 0) { - buff.append(" NULLS LAST"); - } - } - return buff.toString(); - } - - /** - * Compare two expressions where one of them is NULL. - * - * @param aNull whether the first expression is null - * @param bNull whether the second expression is null - * @param sortType the sort bit mask to use - * @return the result of the comparison (-1 meaning the first expression - * should appear before the second, 0 if they are equal) - */ - public static int compareNull(boolean aNull, boolean bNull, int sortType) { - if ((sortType & NULLS_FIRST) != 0) { - return aNull ? -1 : 1; - } else if ((sortType & NULLS_LAST) != 0) { - return aNull ? 1 : -1; - } else { - // see also JdbcDatabaseMetaData.nullsAreSorted* - int comp = aNull ? DEFAULT_NULL_SORT : -DEFAULT_NULL_SORT; - return (sortType & DESCENDING) == 0 ? comp : -comp; - } - } - - /** - * Compare two expression lists. - * - * @param a the first expression list - * @param b the second expression list - * @return the result of the comparison - */ - public int compare(Value[] a, Value[] b) { - for (int i = 0; i < indexes.length; i++) { - int idx = indexes[i]; - int type = sortTypes[i]; - Value ao = a[idx]; - Value bo = b[idx]; - boolean aNull = ao == ValueNull.INSTANCE, bNull = bo == ValueNull.INSTANCE; - if (aNull || bNull) { - if (aNull == bNull) { - continue; - } - return compareNull(aNull, bNull, type); - } - int comp = database.compare(ao, bo); - if (comp != 0) { - return (type & DESCENDING) == 0 ? comp : -comp; - } - } - return 0; - } - - /** - * Sort a list of rows. - * - * @param rows the list of rows - */ - public void sort(ArrayList rows) { - Collections.sort(rows, this); - } - - /** - * Get the column index list. - * - * @return the list - */ - public int[] getIndexes() { - return indexes; - } - - /** - * Get the sort order bit masks. - * - * @return the list - */ - public int[] getSortTypes() { - return sortTypes; - } - -} diff --git a/tools/h2/src/main/org/h2/result/UpdatableRow.java b/tools/h2/src/main/org/h2/result/UpdatableRow.java deleted file mode 100755 index 4ca8eb3..0000000 --- a/tools/h2/src/main/org/h2/result/UpdatableRow.java +++ /dev/null @@ -1,281 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.result; - -import java.sql.DatabaseMetaData; -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.util.ArrayList; -import org.h2.constant.ErrorCode; -import org.h2.jdbc.JdbcConnection; -import org.h2.message.DbException; -import org.h2.util.JdbcUtils; -import org.h2.util.New; -import org.h2.util.StatementBuilder; -import org.h2.util.StringUtils; -import org.h2.value.DataType; -import org.h2.value.Value; -import org.h2.value.ValueNull; - -/** - * This class is used for updatable result sets. - * An updatable row provides functions to update the current row in a result set. - */ -public class UpdatableRow { - - private final JdbcConnection conn; - private final DatabaseMetaData meta; - private final ResultInterface result; - private final int columnCount; - private String schemaName; - private String tableName; - private ArrayList key; - private boolean isUpdatable; - - /** - * Construct a new object that is linked to the result set. The constructor - * reads the database meta data to find out if the result set is updatable. - * - * @param conn the database connection - * @param result the result - */ - public UpdatableRow(JdbcConnection conn, ResultInterface result) throws SQLException { - this.conn = conn; - this.meta = conn.getMetaData(); - this.result = result; - columnCount = result.getVisibleColumnCount(); - for (int i = 0; i < columnCount; i++) { - String t = result.getTableName(i); - String s = result.getSchemaName(i); - if (t == null || s == null) { - return; - } - if (tableName == null) { - tableName = t; - } else if (!tableName.equals(t)) { - return; - } - if (schemaName == null) { - schemaName = s; - } else if (!schemaName.equals(s)) { - return; - } - } - ResultSet rs = meta.getTables(null, - JdbcUtils.escapeMetaDataPattern(schemaName), - JdbcUtils.escapeMetaDataPattern(tableName), - new String[] { "TABLE" }); - if (!rs.next()) { - return; - } - if (rs.getString("SQL") == null) { - // system table - return; - } - key = New.arrayList(); - rs = meta.getPrimaryKeys(null, - JdbcUtils.escapeMetaDataPattern(schemaName), - tableName); - while (rs.next()) { - key.add(rs.getString("COLUMN_NAME")); - } - if (key.size() == 0) { - rs = meta.getIndexInfo(null, - JdbcUtils.escapeMetaDataPattern(schemaName), - tableName, true, true); - while (rs.next()) { - key.add(rs.getString("COLUMN_NAME")); - } - } - isUpdatable = key.size() > 0; - } - - /** - * Check if this result set is updatable. - * - * @return true if it is - */ - public boolean isUpdatable() { - return isUpdatable; - } - - private int getColumnIndex(String columnName) { - for (int i = 0; i < columnCount; i++) { - String col = result.getColumnName(i); - if (col.equals(columnName)) { - return i; - } - } - throw DbException.get(ErrorCode.COLUMN_NOT_FOUND_1, columnName); - } - - private void appendColumnList(StatementBuilder buff, boolean set) { - buff.resetCount(); - for (int i = 0; i < columnCount; i++) { - buff.appendExceptFirst(","); - String col = result.getColumnName(i); - buff.append(StringUtils.quoteIdentifier(col)); - if (set) { - buff.append("=? "); - } - } - } - - private void appendKeyCondition(StatementBuilder buff) { - buff.append(" WHERE "); - buff.resetCount(); - for (String k : key) { - buff.appendExceptFirst(" AND "); - buff.append(StringUtils.quoteIdentifier(k)).append("=?"); - } - } - - private void setKey(PreparedStatement prep, int start, Value[] current) throws SQLException { - for (int i = 0; i < key.size(); i++) { - String col = key.get(i); - int idx = getColumnIndex(col); - Value v = current[idx]; - if (v == null || v == ValueNull.INSTANCE) { - // rows with a unique key containing NULL are not supported, - // as multiple such rows could exist - throw DbException.get(ErrorCode.NO_DATA_AVAILABLE); - } - v.set(prep, start + i); - } - } - -// public boolean isRowDeleted(Value[] row) throws SQLException { -// StringBuilder buff = new StringBuilder(); -// buff.append("SELECT COUNT(*) FROM "). -// append(StringUtils.quoteIdentifier(tableName)); -// appendKeyCondition(buff); -// PreparedStatement prep = conn.prepareStatement(buff.toString()); -// setKey(prep, 1, row); -// ResultSet rs = prep.executeQuery(); -// rs.next(); -// return rs.getInt(1) == 0; -// } - - private void appendTableName(StatementBuilder buff) { - if (schemaName != null && schemaName.length() > 0) { - buff.append(StringUtils.quoteIdentifier(schemaName)).append('.'); - } - buff.append(StringUtils.quoteIdentifier(tableName)); - } - - /** - * Re-reads a row from the database and updates the values in the array. - * - * @param row the values that contain the key - * @return the row - */ - public Value[] readRow(Value[] row) throws SQLException { - StatementBuilder buff = new StatementBuilder("SELECT "); - appendColumnList(buff, false); - buff.append(" FROM "); - appendTableName(buff); - appendKeyCondition(buff); - PreparedStatement prep = conn.prepareStatement(buff.toString()); - setKey(prep, 1, row); - ResultSet rs = prep.executeQuery(); - if (!rs.next()) { - throw DbException.get(ErrorCode.NO_DATA_AVAILABLE); - } - Value[] newRow = new Value[columnCount]; - for (int i = 0; i < columnCount; i++) { - int type = result.getColumnType(i); - newRow[i] = DataType.readValue(conn.getSession(), rs, i + 1, type); - } - return newRow; - } - - /** - * Delete the given row in the database. - * - * @param current the row - * @throws SQLException if this row has already been deleted - */ - public void deleteRow(Value[] current) throws SQLException { - StatementBuilder buff = new StatementBuilder("DELETE FROM "); - appendTableName(buff); - appendKeyCondition(buff); - PreparedStatement prep = conn.prepareStatement(buff.toString()); - setKey(prep, 1, current); - int count = prep.executeUpdate(); - if (count != 1) { - // the row has already been deleted - throw DbException.get(ErrorCode.NO_DATA_AVAILABLE); - } - } - - /** - * Update a row in the database. - * - * @param current the old row - * @param updateRow the new row - * @throws SQLException if the row has been deleted - */ - public void updateRow(Value[] current, Value[] updateRow) throws SQLException { - StatementBuilder buff = new StatementBuilder("UPDATE "); - appendTableName(buff); - buff.append(" SET "); - appendColumnList(buff, true); - // TODO updatable result set: we could add all current values to the - // where clause - // - like this optimistic ('no') locking is possible - appendKeyCondition(buff); - PreparedStatement prep = conn.prepareStatement(buff.toString()); - int j = 1; - for (int i = 0; i < columnCount; i++) { - Value v = updateRow[i]; - if (v == null) { - v = current[i]; - } - v.set(prep, j++); - } - setKey(prep, j, current); - int count = prep.executeUpdate(); - if (count != 1) { - // the row has been deleted - throw DbException.get(ErrorCode.NO_DATA_AVAILABLE); - } - } - - /** - * Insert a new row into the database. - * - * @param row the new row - * @throws SQLException if the row could not be inserted - */ - public void insertRow(Value[] row) throws SQLException { - StatementBuilder buff = new StatementBuilder("INSERT INTO "); - appendTableName(buff); - buff.append('('); - appendColumnList(buff, false); - buff.append(")VALUES("); - buff.resetCount(); - for (int i = 0; i < columnCount; i++) { - buff.appendExceptFirst(","); - buff.append('?'); - } - buff.append(')'); - PreparedStatement prep = conn.prepareStatement(buff.toString()); - for (int i = 0; i < columnCount; i++) { - Value v = row[i]; - if (v == null) { - v = ValueNull.INSTANCE; - } - v.set(prep, i + 1); - } - int count = prep.executeUpdate(); - if (count != 1) { - throw DbException.get(ErrorCode.NO_DATA_AVAILABLE); - } - } - -} diff --git a/tools/h2/src/main/org/h2/result/package.html b/tools/h2/src/main/org/h2/result/package.html deleted file mode 100755 index 75af029..0000000 --- a/tools/h2/src/main/org/h2/result/package.html +++ /dev/null @@ -1,15 +0,0 @@ - - - - -Javadoc package documentation -

- -Implementation of row and internal result sets. - -

\ No newline at end of file diff --git a/tools/h2/src/main/org/h2/schema/Constant.java b/tools/h2/src/main/org/h2/schema/Constant.java deleted file mode 100755 index ae674a4..0000000 --- a/tools/h2/src/main/org/h2/schema/Constant.java +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.schema; - -import org.h2.engine.DbObject; -import org.h2.engine.Session; -import org.h2.expression.ValueExpression; -import org.h2.message.DbException; -import org.h2.message.Trace; -import org.h2.table.Table; -import org.h2.value.Value; - -/** - * A user-defined constant as created by the SQL statement - * CREATE CONSTANT - */ -public class Constant extends SchemaObjectBase { - - private Value value; - private ValueExpression expression; - - public Constant(Schema schema, int id, String name) { - initSchemaObjectBase(schema, id, name, Trace.SCHEMA); - } - - public String getCreateSQLForCopy(Table table, String quotedName) { - throw DbException.throwInternalError(); - } - - public String getDropSQL() { - return null; - } - - public String getCreateSQL() { - return "CREATE CONSTANT " + getSQL() + " VALUE " + value.getSQL(); - } - - public int getType() { - return DbObject.CONSTANT; - } - - public void removeChildrenAndResources(Session session) { - database.removeMeta(session, getId()); - invalidate(); - } - - public void checkRename() { - // ok - } - - public void setValue(Value value) { - this.value = value; - expression = ValueExpression.get(value); - } - - public ValueExpression getValue() { - return expression; - } - -} diff --git a/tools/h2/src/main/org/h2/schema/Schema.java b/tools/h2/src/main/org/h2/schema/Schema.java deleted file mode 100755 index 0324e07..0000000 --- a/tools/h2/src/main/org/h2/schema/Schema.java +++ /dev/null @@ -1,558 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.schema; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.HashSet; -import org.h2.api.TableEngine; -import org.h2.command.ddl.CreateTableData; -import org.h2.constant.ErrorCode; -import org.h2.constant.SysProperties; -import org.h2.constraint.Constraint; -import org.h2.engine.Database; -import org.h2.engine.DbObject; -import org.h2.engine.DbObjectBase; -import org.h2.engine.FunctionAlias; -import org.h2.engine.Session; -import org.h2.engine.User; -import org.h2.index.Index; -import org.h2.message.DbException; -import org.h2.message.Trace; -import org.h2.table.Table; -import org.h2.table.RegularTable; -import org.h2.table.TableLink; -import org.h2.util.New; -import org.h2.util.Utils; - -/** - * A schema as created by the SQL statement - * CREATE SCHEMA - */ -public class Schema extends DbObjectBase { - - private User owner; - private boolean system; - - private HashMap tablesAndViews = New.hashMap(); - private HashMap indexes = New.hashMap(); - private HashMap sequences = New.hashMap(); - private HashMap triggers = New.hashMap(); - private HashMap constraints = New.hashMap(); - private HashMap constants = New.hashMap(); - private HashMap functions = New.hashMap(); - - /** - * The set of returned unique names that are not yet stored. It is used to - * avoid returning the same unique name twice when multiple threads - * concurrently create objects. - */ - private HashSet temporaryUniqueNames = New.hashSet(); - - /** - * Create a new schema object. - * - * @param database the database - * @param id the object id - * @param schemaName the schema name - * @param owner the owner of the schema - * @param system if this is a system schema (such a schema can not be - * dropped) - */ - public Schema(Database database, int id, String schemaName, User owner, boolean system) { - initDbObjectBase(database, id, schemaName, Trace.SCHEMA); - this.owner = owner; - this.system = system; - } - - /** - * Check if this schema can be dropped. System schemas can not be dropped. - * - * @return true if it can be dropped - */ - public boolean canDrop() { - return !system; - } - - public String getCreateSQLForCopy(Table table, String quotedName) { - throw DbException.throwInternalError(); - } - - public String getDropSQL() { - return null; - } - - public String getCreateSQL() { - if (system) { - return null; - } - return "CREATE SCHEMA IF NOT EXISTS " + - getSQL() + " AUTHORIZATION " + owner.getSQL(); - } - - public int getType() { - return DbObject.SCHEMA; - } - - public void removeChildrenAndResources(Session session) { - while (triggers != null && triggers.size() > 0) { - TriggerObject obj = (TriggerObject) triggers.values().toArray()[0]; - database.removeSchemaObject(session, obj); - } - while (constraints != null && constraints.size() > 0) { - Constraint obj = (Constraint) constraints.values().toArray()[0]; - database.removeSchemaObject(session, obj); - } - while (tablesAndViews != null && tablesAndViews.size() > 0) { - Table obj = (Table) tablesAndViews.values().toArray()[0]; - database.removeSchemaObject(session, obj); - } - while (indexes != null && indexes.size() > 0) { - Index obj = (Index) indexes.values().toArray()[0]; - database.removeSchemaObject(session, obj); - } - while (sequences != null && sequences.size() > 0) { - Sequence obj = (Sequence) sequences.values().toArray()[0]; - database.removeSchemaObject(session, obj); - } - while (constants != null && constants.size() > 0) { - Constant obj = (Constant) constants.values().toArray()[0]; - database.removeSchemaObject(session, obj); - } - while (functions != null && functions.size() > 0) { - FunctionAlias obj = (FunctionAlias) functions.values().toArray()[0]; - database.removeSchemaObject(session, obj); - } - database.removeMeta(session, getId()); - owner = null; - invalidate(); - } - - public void checkRename() { - // ok - } - - /** - * Get the owner of this schema. - * - * @return the owner - */ - public User getOwner() { - return owner; - } - - @SuppressWarnings("unchecked") - private HashMap getMap(int type) { - HashMap result; - switch (type) { - case DbObject.TABLE_OR_VIEW: - result = tablesAndViews; - break; - case DbObject.SEQUENCE: - result = sequences; - break; - case DbObject.INDEX: - result = indexes; - break; - case DbObject.TRIGGER: - result = triggers; - break; - case DbObject.CONSTRAINT: - result = constraints; - break; - case DbObject.CONSTANT: - result = constants; - break; - case DbObject.FUNCTION_ALIAS: - result = functions; - break; - default: - throw DbException.throwInternalError("type=" + type); - } - return (HashMap) result; - } - - /** - * Add an object to this schema. - * This method must not be called within CreateSchemaObject; - * use Database.addSchemaObject() instead - * - * @param obj the object to add - */ - public void add(SchemaObject obj) { - if (SysProperties.CHECK && obj.getSchema() != this) { - DbException.throwInternalError("wrong schema"); - } - String name = obj.getName(); - HashMap map = getMap(obj.getType()); - if (SysProperties.CHECK && map.get(name) != null) { - DbException.throwInternalError("object already exists: " + name); - } - map.put(name, obj); - freeUniqueName(name); - } - - /** - * Rename an object. - * - * @param obj the object to rename - * @param newName the new name - */ - public void rename(SchemaObject obj, String newName) { - int type = obj.getType(); - HashMap map = getMap(type); - if (SysProperties.CHECK) { - if (!map.containsKey(obj.getName())) { - DbException.throwInternalError("not found: " + obj.getName()); - } - if (obj.getName().equals(newName) || map.containsKey(newName)) { - DbException.throwInternalError("object already exists: " + newName); - } - } - obj.checkRename(); - map.remove(obj.getName()); - freeUniqueName(obj.getName()); - obj.rename(newName); - map.put(newName, obj); - freeUniqueName(newName); - } - - /** - * Try to find a table or view with this name. This method returns null if - * no object with this name exists. Local temporary tables are also - * returned. - * - * @param session the session - * @param name the object name - * @return the object or null - */ - public Table findTableOrView(Session session, String name) { - Table table = tablesAndViews.get(name); - if (table == null && session != null) { - table = session.findLocalTempTable(name); - } - return table; - } - - /** - * Try to find an index with this name. This method returns null if - * no object with this name exists. - * - * @param session the session - * @param name the object name - * @return the object or null - */ - public Index findIndex(Session session, String name) { - Index index = indexes.get(name); - if (index == null) { - index = session.findLocalTempTableIndex(name); - } - return index; - } - - /** - * Try to find a trigger with this name. This method returns null if - * no object with this name exists. - * - * @param name the object name - * @return the object or null - */ - public TriggerObject findTrigger(String name) { - return triggers.get(name); - } - - /** - * Try to find a sequence with this name. This method returns null if - * no object with this name exists. - * - * @param sequenceName the object name - * @return the object or null - */ - public Sequence findSequence(String sequenceName) { - return sequences.get(sequenceName); - } - - /** - * Try to find a constraint with this name. This method returns null if no - * object with this name exists. - * - * @param session the session - * @param name the object name - * @return the object or null - */ - public Constraint findConstraint(Session session, String name) { - Constraint constraint = constraints.get(name); - if (constraint == null) { - constraint = session.findLocalTempTableConstraint(name); - } - return constraint; - } - - /** - * Try to find a user defined constant with this name. This method returns - * null if no object with this name exists. - * - * @param constantName the object name - * @return the object or null - */ - public Constant findConstant(String constantName) { - return constants.get(constantName); - } - - /** - * Try to find a user defined function with this name. This method returns - * null if no object with this name exists. - * - * @param functionAlias the object name - * @return the object or null - */ - public FunctionAlias findFunction(String functionAlias) { - return functions.get(functionAlias); - } - - /** - * Release a unique object name. - * - * @param name the object name - */ - public void freeUniqueName(String name) { - if (name != null) { - synchronized (temporaryUniqueNames) { - temporaryUniqueNames.remove(name); - } - } - } - - private String getUniqueName(DbObject obj, HashMap map, String prefix) { - String hash = Integer.toHexString(obj.getName().hashCode()).toUpperCase(); - String name = null; - synchronized (temporaryUniqueNames) { - for (int i = 1; i < hash.length(); i++) { - name = prefix + hash.substring(0, i); - if (!map.containsKey(name) && !temporaryUniqueNames.contains(name)) { - break; - } - name = null; - } - if (name == null) { - prefix = prefix + hash + "_"; - for (int i = 0;; i++) { - name = prefix + i; - if (!map.containsKey(name) && !temporaryUniqueNames.contains(name)) { - break; - } - } - } - temporaryUniqueNames.add(name); - } - return name; - } - - /** - * Create a unique constraint name. - * - * @param session the session - * @param table the constraint table - * @return the unique name - */ - public String getUniqueConstraintName(Session session, Table table) { - HashMap tableConstraints; - if (table.isTemporary() && !table.isGlobalTemporary()) { - tableConstraints = session.getLocalTempTableConstraints(); - } else { - tableConstraints = constraints; - } - return getUniqueName(table, tableConstraints, "CONSTRAINT_"); - } - - /** - * Create a unique index name. - * - * @param session the session - * @param table the indexed table - * @param prefix the index name prefix - * @return the unique name - */ - public String getUniqueIndexName(Session session, Table table, String prefix) { - HashMap tableIndexes; - if (table.isTemporary() && !table.isGlobalTemporary()) { - tableIndexes = session.getLocalTempTableIndexes(); - } else { - tableIndexes = indexes; - } - return getUniqueName(table, tableIndexes, prefix); - } - - /** - * Get the table or view with the given name. - * Local temporary tables are also returned. - * - * @param session the session - * @param name the table or view name - * @return the table or view - * @throws SQLException if no such object exists - */ - public Table getTableOrView(Session session, String name) { - Table table = tablesAndViews.get(name); - if (table == null && session != null) { - table = session.findLocalTempTable(name); - } - if (table == null) { - throw DbException.get(ErrorCode.TABLE_OR_VIEW_NOT_FOUND_1, name); - } - return table; - } - - /** - * Get the index with the given name. - * - * @param name the index name - * @return the index - * @throws SQLException if no such object exists - */ - public Index getIndex(String name) { - Index index = indexes.get(name); - if (index == null) { - throw DbException.get(ErrorCode.INDEX_NOT_FOUND_1, name); - } - return index; - } - - /** - * Get the constraint with the given name. - * - * @param name the constraint name - * @return the constraint - * @throws SQLException if no such object exists - */ - public Constraint getConstraint(String name) { - Constraint constraint = constraints.get(name); - if (constraint == null) { - throw DbException.get(ErrorCode.CONSTRAINT_NOT_FOUND_1, name); - } - return constraint; - } - - /** - * Get the user defined constant with the given name. - * - * @param constantName the constant name - * @return the constant - * @throws SQLException if no such object exists - */ - public Constant getConstant(String constantName) { - Constant constant = constants.get(constantName); - if (constant == null) { - throw DbException.get(ErrorCode.CONSTANT_NOT_FOUND_1, constantName); - } - return constant; - } - - /** - * Get the sequence with the given name. - * - * @param sequenceName the sequence name - * @return the sequence - * @throws SQLException if no such object exists - */ - public Sequence getSequence(String sequenceName) { - Sequence sequence = sequences.get(sequenceName); - if (sequence == null) { - throw DbException.get(ErrorCode.SEQUENCE_NOT_FOUND_1, sequenceName); - } - return sequence; - } - - /** - * Get all objects of the given type. - * - * @param type the object type - * @return a (possible empty) list of all objects - */ - public ArrayList getAll(int type) { - HashMap map = getMap(type); - return New.arrayList(map.values()); - } - - /** - * Get all tables and views. - * - * @return a (possible empty) list of all objects - */ - public ArrayList
getAllTablesAndViews() { - return New.arrayList(tablesAndViews.values()); - } - - /** - * Get all functions. - * - * @return a (possible empty) list of all objects - */ - public ArrayList getAllFunctionAliases() { - return New.arrayList(functions.values()); - } - - /** - * Remove an object from this schema. - * - * @param obj the object to remove - */ - public void remove(SchemaObject obj) { - String objName = obj.getName(); - HashMap map = getMap(obj.getType()); - if (SysProperties.CHECK && !map.containsKey(objName)) { - DbException.throwInternalError("not found: " + objName); - } - map.remove(objName); - freeUniqueName(objName); - } - - /** - * Add a table to the schema. - * - * @param data the create table information - * @return the created {@link Table} object - */ - public Table createTable(CreateTableData data) { - synchronized (database) { - data.schema = this; - if (data.tableEngine != null) { - TableEngine engine; - try { - engine = (TableEngine) Utils.loadUserClass(data.tableEngine).newInstance(); - } catch (Exception e) { - throw DbException.convert(e); - } - return engine.createTable(data); - } - return new RegularTable(data); - } - } - - /** - * Add a linked table to the schema. - * - * @param id the object id - * @param tableName the table name of the alias - * @param driver the driver class name - * @param url the database URL - * @param user the user name - * @param password the password - * @param originalSchema the schema name of the target table - * @param originalTable the table name of the target table - * @param emitUpdates if updates should be emitted instead of delete/insert - * @param force create the object even if the database can not be accessed - * @return the {@link TableLink} object - */ - public TableLink createTableLink(int id, String tableName, String driver, String url, String user, String password, - String originalSchema, String originalTable, boolean emitUpdates, boolean force) { - synchronized (database) { - return new TableLink(this, id, tableName, driver, url, user, password, originalSchema, originalTable, emitUpdates, force); - } - } - -} diff --git a/tools/h2/src/main/org/h2/schema/SchemaObject.java b/tools/h2/src/main/org/h2/schema/SchemaObject.java deleted file mode 100755 index a062c91..0000000 --- a/tools/h2/src/main/org/h2/schema/SchemaObject.java +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.schema; - -import org.h2.engine.DbObject; - -/** - * Any database object that is stored in a schema. - */ -public interface SchemaObject extends DbObject { - - /** - * Get the schema in which this object is defined - * - * @return the schema - */ - Schema getSchema(); - - /** - * Check whether this is a hidden object that doesn't appear in the meta - * data and in the script, and is not dropped on DROP ALL OBJECTS. - * - * @return true if it is hidden - */ - boolean isHidden(); - -} diff --git a/tools/h2/src/main/org/h2/schema/SchemaObjectBase.java b/tools/h2/src/main/org/h2/schema/SchemaObjectBase.java deleted file mode 100755 index 59ec00f..0000000 --- a/tools/h2/src/main/org/h2/schema/SchemaObjectBase.java +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.schema; - -import org.h2.engine.DbObjectBase; - -/** - * The base class for classes implementing SchemaObject. - */ -public abstract class SchemaObjectBase extends DbObjectBase implements SchemaObject { - - private Schema schema; - - /** - * Initialize some attributes of this object. - * - * @param newSchema the schema - * @param id the object id - * @param name the name - * @param traceModule the trace module name - */ - protected void initSchemaObjectBase(Schema newSchema, int id, String name, String traceModule) { - initDbObjectBase(newSchema.getDatabase(), id, name, traceModule); - this.schema = newSchema; - } - - public Schema getSchema() { - return schema; - } - - public String getSQL() { - return schema.getSQL() + "." + super.getSQL(); - } - - public boolean isHidden() { - return false; - } - -} diff --git a/tools/h2/src/main/org/h2/schema/Sequence.java b/tools/h2/src/main/org/h2/schema/Sequence.java deleted file mode 100755 index 4fcd33e..0000000 --- a/tools/h2/src/main/org/h2/schema/Sequence.java +++ /dev/null @@ -1,176 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.schema; - -import org.h2.constant.ErrorCode; -import org.h2.engine.DbObject; -import org.h2.engine.Session; -import org.h2.message.DbException; -import org.h2.message.Trace; -import org.h2.table.Table; - -/** - *A sequence is created using the statement - * CREATE SEQUENCE - */ -public class Sequence extends SchemaObjectBase { - - /** - * The default cache size for sequences. - */ - public static final int DEFAULT_CACHE_SIZE = 32; - - private long value = 1; - private long valueWithMargin; - private long increment = 1; - private long cacheSize = DEFAULT_CACHE_SIZE; - private boolean belongsToTable; - - public Sequence(Schema schema, int id, String name, boolean belongsToTable) { - initSchemaObjectBase(schema, id, name, Trace.SEQUENCE); - this.belongsToTable = belongsToTable; - } - - public synchronized void setStartValue(long value) { - this.value = value; - this.valueWithMargin = value; - } - - public boolean getBelongsToTable() { - return belongsToTable; - } - - public long getIncrement() { - return increment; - } - - public void setIncrement(long inc) { - if (inc == 0) { - throw DbException.get(ErrorCode.INVALID_VALUE_2, "0", "INCREMENT"); - } - this.increment = inc; - } - - public String getDropSQL() { - if (getBelongsToTable()) { - return null; - } - return "DROP SEQUENCE IF EXISTS " + getSQL(); - } - - public String getCreateSQLForCopy(Table table, String quotedName) { - throw DbException.throwInternalError(); - } - - public synchronized String getCreateSQL() { - StringBuilder buff = new StringBuilder("CREATE SEQUENCE "); - buff.append(getSQL()).append(" START WITH ").append(value); - if (increment != 1) { - buff.append(" INCREMENT BY ").append(increment); - } - if (cacheSize != DEFAULT_CACHE_SIZE) { - buff.append(" CACHE ").append(cacheSize); - } - if (belongsToTable) { - buff.append(" BELONGS_TO_TABLE"); - } - return buff.toString(); - } - - /** - * Get the next value for this sequence. - * - * @param session the session - * @return the next value - */ - public synchronized long getNext(Session session) { - if ((increment > 0 && value >= valueWithMargin) || (increment < 0 && value <= valueWithMargin)) { - valueWithMargin += increment * cacheSize; - flush(session); - } - long v = value; - value += increment; - return v; - } - - /** - * Flush the current value to disk. - */ - public void flushWithoutMargin() { - if (valueWithMargin != value) { - valueWithMargin = value; - flush(null); - } - } - - /** - * Flush the current value, including the margin, to disk. - * - * @param session the session - */ - public synchronized void flush(Session session) { - Session sysSession = database.getSystemSession(); - if (session == null || !database.isSysTableLocked()) { - // this session may not lock the sys table (except if it already has locked it) - // because it must be committed immediately - // otherwise other threads can not access the sys table. - session = sysSession; - } - synchronized (session) { - // just for this case, use the value with the margin for the script - long realValue = value; - try { - value = valueWithMargin; - database.update(session, this); - } finally { - value = realValue; - } - if (session == sysSession) { - // if the system session is used, - // the transaction must be committed immediately - sysSession.commit(false); - } - } - } - - /** - * Flush the current value to disk and close this object. - */ - public void close() { - flushWithoutMargin(); - } - - public int getType() { - return DbObject.SEQUENCE; - } - - public void removeChildrenAndResources(Session session) { - database.removeMeta(session, getId()); - invalidate(); - } - - public void checkRename() { - // nothing to do - } - - public synchronized long getCurrentValue() { - return value - increment; - } - - public void setBelongsToTable(boolean b) { - this.belongsToTable = b; - } - - public void setCacheSize(long cacheSize) { - this.cacheSize = cacheSize; - } - - public long getCacheSize() { - return cacheSize; - } - -} diff --git a/tools/h2/src/main/org/h2/schema/TriggerObject.java b/tools/h2/src/main/org/h2/schema/TriggerObject.java deleted file mode 100755 index d3c6749..0000000 --- a/tools/h2/src/main/org/h2/schema/TriggerObject.java +++ /dev/null @@ -1,386 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.schema; - -import java.sql.Connection; -import java.sql.SQLException; -import org.h2.api.Trigger; -import org.h2.command.Parser; -import org.h2.constant.ErrorCode; -import org.h2.engine.DbObject; -import org.h2.engine.Session; -import org.h2.message.DbException; -import org.h2.message.Trace; -import org.h2.result.Row; -import org.h2.table.Table; -import org.h2.util.Utils; -import org.h2.util.StatementBuilder; -import org.h2.value.DataType; -import org.h2.value.Value; - -/** - *A trigger is created using the statement - * CREATE TRIGGER - */ -public class TriggerObject extends SchemaObjectBase { - - /** - * The default queue size. - */ - public static final int DEFAULT_QUEUE_SIZE = 1024; - - private boolean insteadOf; - private boolean before; - private int typeMask; - private boolean rowBased; - private boolean onRollback; - // TODO trigger: support queue and noWait = false as well - private int queueSize = DEFAULT_QUEUE_SIZE; - private boolean noWait; - private Table table; - private String triggerClassName; - private Trigger triggerCallback; - - public TriggerObject(Schema schema, int id, String name, Table table) { - initSchemaObjectBase(schema, id, name, Trace.TRIGGER); - this.table = table; - setTemporary(table.isTemporary()); - } - - public void setBefore(boolean before) { - this.before = before; - } - - public void setInsteadOf(boolean insteadOf) { - this.insteadOf = insteadOf; - } - - private synchronized void load(Session session) { - if (triggerCallback != null) { - return; - } - try { - Connection c2 = session.createConnection(false); - Object obj = Utils.loadUserClass(triggerClassName).newInstance(); - triggerCallback = (Trigger) obj; - triggerCallback.init(c2, getSchema().getName(), getName(), table.getName(), before, typeMask); - } catch (Throwable e) { - // try again later - triggerCallback = null; - throw DbException.get(ErrorCode.ERROR_CREATING_TRIGGER_OBJECT_3, e, getName(), - triggerClassName, e.toString()); - } - } - - /** - * Set the trigger class name and load the class if possible. - * - * @param session the session - * @param triggerClassName the name of the trigger class - * @param force whether exceptions (due to missing class or access rights) - * should be ignored - */ - public void setTriggerClassName(Session session, String triggerClassName, boolean force) { - this.triggerClassName = triggerClassName; - try { - load(session); - } catch (DbException e) { - if (!force) { - throw e; - } - } - } - - /** - * Call the trigger class if required. This method does nothing if the - * trigger is not defined for the given action. This method is called before - * or after any rows have been processed, once for each statement. - * - * @param session the session - * @param type the trigger type - * @param beforeAction if this method is called before applying the changes - */ - public void fire(Session session, int type, boolean beforeAction) { - if (rowBased || before != beforeAction || (typeMask & type) == 0) { - return; - } - load(session); - Connection c2 = session.createConnection(false); - boolean old = false; - if (type != Trigger.SELECT) { - old = session.setCommitOrRollbackDisabled(true); - } - Value identity = session.getScopeIdentity(); - try { - triggerCallback.fire(c2, null, null); - } catch (Throwable e) { - throw DbException.get(ErrorCode.ERROR_EXECUTING_TRIGGER_3, e, getName(), - triggerClassName, e.toString()); - } finally { - session.setScopeIdentity(identity); - if (type != Trigger.SELECT) { - session.setCommitOrRollbackDisabled(old); - } - } - } - - private Object[] convertToObjectList(Row row) { - if (row == null) { - return null; - } - int len = row.getColumnCount(); - Object[] list = new Object[len]; - for (int i = 0; i < len; i++) { - list[i] = row.getValue(i).getObject(); - } - return list; - } - - /** - * Call the fire method of the user-defined trigger class if required. This - * method does nothing if the trigger is not defined for the given action. - * This method is called before or after a row is processed, possibly many - * times for each statement. - * - * @param session the session - * @param oldRow the old row - * @param newRow the new row - * @param beforeAction true if this method is called before the operation is - * applied - * @param rollback when the operation occurred within a rollback - * @return true if no further action is required (for 'instead of' triggers) - */ - public boolean fireRow(Session session, Row oldRow, Row newRow, boolean beforeAction, boolean rollback) { - if (!rowBased || before != beforeAction) { - return false; - } - if (rollback && !onRollback) { - return false; - } - load(session); - Object[] oldList; - Object[] newList; - boolean fire = false; - if ((typeMask & Trigger.INSERT) != 0) { - if (oldRow == null && newRow != null) { - fire = true; - } - } - if ((typeMask & Trigger.UPDATE) != 0) { - if (oldRow != null && newRow != null) { - fire = true; - } - } - if ((typeMask & Trigger.DELETE) != 0) { - if (oldRow != null && newRow == null) { - fire = true; - } - } - if (!fire) { - return false; - } - oldList = convertToObjectList(oldRow); - newList = convertToObjectList(newRow); - Object[] newListBackup; - if (before && newList != null) { - newListBackup = new Object[newList.length]; - for (int i = 0; i < newList.length; i++) { - newListBackup[i] = newList[i]; - } - } else { - newListBackup = null; - } - Connection c2 = session.createConnection(false); - boolean old = session.getAutoCommit(); - boolean oldDisabled = session.setCommitOrRollbackDisabled(true); - Value identity = session.getScopeIdentity(); - try { - session.setAutoCommit(false); - triggerCallback.fire(c2, oldList, newList); - if (newListBackup != null) { - for (int i = 0; i < newList.length; i++) { - Object o = newList[i]; - if (o != newListBackup[i]) { - Value v = DataType.convertToValue(session, o, Value.UNKNOWN); - newRow.setValue(i, v); - } - } - } - } catch (Exception e) { - if (onRollback) { - // ignore - } else { - throw DbException.convert(e); - } - } finally { - session.setScopeIdentity(identity); - session.setCommitOrRollbackDisabled(oldDisabled); - session.setAutoCommit(old); - } - return insteadOf; - } - - /** - * Set the trigger type. - * - * @param typeMask the type - */ - public void setTypeMask(int typeMask) { - this.typeMask = typeMask; - } - - public void setRowBased(boolean rowBased) { - this.rowBased = rowBased; - } - - public void setQueueSize(int size) { - this.queueSize = size; - } - - public int getQueueSize() { - return queueSize; - } - - public void setNoWait(boolean noWait) { - this.noWait = noWait; - } - - public boolean isNoWait() { - return noWait; - } - - public void setOnRollback(boolean onRollback) { - this.onRollback = onRollback; - } - - public String getDropSQL() { - return null; - } - - public String getCreateSQLForCopy(Table targetTable, String quotedName) { - StringBuilder buff = new StringBuilder("CREATE FORCE TRIGGER "); - buff.append(quotedName); - if (insteadOf) { - buff.append(" INSTEAD OF "); - } else if (before) { - buff.append(" BEFORE "); - } else { - buff.append(" AFTER "); - } - buff.append(getTypeNameList()); - buff.append(" ON ").append(targetTable.getSQL()); - if (rowBased) { - buff.append(" FOR EACH ROW"); - } - if (noWait) { - buff.append(" NOWAIT"); - } else { - buff.append(" QUEUE ").append(queueSize); - } - buff.append(" CALL ").append(Parser.quoteIdentifier(triggerClassName)); - return buff.toString(); - } - - public String getTypeNameList() { - StatementBuilder buff = new StatementBuilder(); - if ((typeMask & Trigger.INSERT) != 0) { - buff.appendExceptFirst(", "); - buff.append("INSERT"); - } - if ((typeMask & Trigger.UPDATE) != 0) { - buff.appendExceptFirst(", "); - buff.append("UPDATE"); - } - if ((typeMask & Trigger.DELETE) != 0) { - buff.appendExceptFirst(", "); - buff.append("DELETE"); - } - if ((typeMask & Trigger.SELECT) != 0) { - buff.appendExceptFirst(", "); - buff.append("SELECT"); - } - if (onRollback) { - buff.appendExceptFirst(", "); - buff.append("ROLLBACK"); - } - return buff.toString(); - } - - public String getCreateSQL() { - return getCreateSQLForCopy(table, getSQL()); - } - - public int getType() { - return DbObject.TRIGGER; - } - - public void removeChildrenAndResources(Session session) { - table.removeTrigger(this); - database.removeMeta(session, getId()); - if (triggerCallback != null) { - try { - triggerCallback.remove(); - } catch (SQLException e) { - throw DbException.convert(e); - } - } - table = null; - triggerClassName = null; - triggerCallback = null; - invalidate(); - } - - public void checkRename() { - // nothing to do - } - - /** - * Get the table of this trigger. - * - * @return the table - */ - public Table getTable() { - return table; - } - - /** - * Check if this is a before trigger. - * - * @return true if it is - */ - public boolean isBefore() { - return before; - } - - /** - * Get the trigger class name. - * - * @return the class name - */ - public String getTriggerClassName() { - return triggerClassName; - } - - /** - * Close the trigger. - */ - public void close() throws SQLException { - if (triggerCallback != null) { - triggerCallback.close(); - } - } - - /** - * Check whether this is a select trigger. - * - * @return true if it is - */ - public boolean isSelectTrigger() { - return (typeMask & Trigger.SELECT) != 0; - } - -} diff --git a/tools/h2/src/main/org/h2/schema/package.html b/tools/h2/src/main/org/h2/schema/package.html deleted file mode 100755 index 6d0764c..0000000 --- a/tools/h2/src/main/org/h2/schema/package.html +++ /dev/null @@ -1,15 +0,0 @@ - - - - -Javadoc package documentation -

- -Schema implementation and objects that are stored in a schema (for example, sequences and constants). - -

\ No newline at end of file diff --git a/tools/h2/src/main/org/h2/security/AES.java b/tools/h2/src/main/org/h2/security/AES.java deleted file mode 100755 index 4fd44d4..0000000 --- a/tools/h2/src/main/org/h2/security/AES.java +++ /dev/null @@ -1,250 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.security; - -import org.h2.constant.SysProperties; -import org.h2.message.DbException; - -/** - * An implementation of the AES block cipher algorithm, - * also known as Rijndael. Only AES-128 is supported by this class. - */ -public class AES implements BlockCipher { - - private static final int[] RCON = new int[10]; - private static final int[] FS = new int[256]; - private static final int[] FT0 = new int[256]; - private static final int[] FT1 = new int[256]; - private static final int[] FT2 = new int[256]; - private static final int[] FT3 = new int[256]; - private static final int[] RS = new int[256]; - private static final int[] RT0 = new int[256]; - private static final int[] RT1 = new int[256]; - private static final int[] RT2 = new int[256]; - private static final int[] RT3 = new int[256]; - private int[] encKey = new int[44]; - private int[] decKey = new int[44]; - - AES() { - // do nothing - } - - private static int rot8(int x) { - return (x >>> 8) | (x << 24); - } - - private static int xtime(int x) { - return ((x << 1) ^ (((x & 0x80) != 0) ? 0x1b : 0)) & 255; - } - - private static int mul(int[] pow, int[] log, int x, int y) { - return (x != 0 && y != 0) ? pow[(log[x] + log[y]) % 255] : 0; - } - - static { - int[] pow = new int[256]; - int[] log = new int[256]; - for (int i = 0, x = 1; i < 256; i++, x ^= xtime(x)) { - pow[i] = x; - log[x] = i; - } - for (int i = 0, x = 1; i < 10; i++, x = xtime(x)) { - RCON[i] = x << 24; - } - FS[0x00] = 0x63; - RS[0x63] = 0x00; - for (int i = 1; i < 256; i++) { - int x = pow[255 - log[i]], y = x; - y = ((y << 1) | (y >> 7)) & 255; - x ^= y; - y = ((y << 1) | (y >> 7)) & 255; - x ^= y; - y = ((y << 1) | (y >> 7)) & 255; - x ^= y; - y = ((y << 1) | (y >> 7)) & 255; - x ^= y ^ 0x63; - FS[i] = x & 255; - RS[x] = i & 255; - } - for (int i = 0; i < 256; i++) { - int x = FS[i], y = xtime(x); - FT0[i] = (x ^ y) ^ (x << 8) ^ (x << 16) ^ (y << 24); - FT1[i] = rot8(FT0[i]); - FT2[i] = rot8(FT1[i]); - FT3[i] = rot8(FT2[i]); - y = RS[i]; - RT0[i] = mul(pow, log, 0x0b, y) ^ (mul(pow, log, 0x0d, y) << 8) - ^ (mul(pow, log, 0x09, y) << 16) ^ (mul(pow, log, 0x0e, y) << 24); - RT1[i] = rot8(RT0[i]); - RT2[i] = rot8(RT1[i]); - RT3[i] = rot8(RT2[i]); - } - } - - private int getDec(int t) { - return RT0[FS[(t >> 24) & 255]] ^ RT1[FS[(t >> 16) & 255]] ^ RT2[FS[(t >> 8) & 255]] ^ RT3[FS[t & 255]]; - } - - public void setKey(byte[] key) { - for (int i = 0, j = 0; i < 4; i++) { - encKey[i] = decKey[i] = ((key[j++] & 255) << 24) | ((key[j++] & 255) << 16) | ((key[j++] & 255) << 8) - | (key[j++] & 255); - } - int e = 0; - for (int i = 0; i < 10; i++, e += 4) { - encKey[e + 4] = encKey[e] ^ RCON[i] ^ (FS[(encKey[e + 3] >> 16) & 255] << 24) - ^ (FS[(encKey[e + 3] >> 8) & 255] << 16) ^ (FS[(encKey[e + 3]) & 255] << 8) ^ FS[(encKey[e + 3] >> 24) & 255]; - encKey[e + 5] = encKey[e + 1] ^ encKey[e + 4]; - encKey[e + 6] = encKey[e + 2] ^ encKey[e + 5]; - encKey[e + 7] = encKey[e + 3] ^ encKey[e + 6]; - } - int d = 0; - decKey[d++] = encKey[e++]; - decKey[d++] = encKey[e++]; - decKey[d++] = encKey[e++]; - decKey[d++] = encKey[e++]; - for (int i = 1; i < 10; i++) { - e -= 8; - decKey[d++] = getDec(encKey[e++]); - decKey[d++] = getDec(encKey[e++]); - decKey[d++] = getDec(encKey[e++]); - decKey[d++] = getDec(encKey[e++]); - } - e -= 8; - decKey[d++] = encKey[e++]; - decKey[d++] = encKey[e++]; - decKey[d++] = encKey[e++]; - decKey[d] = encKey[e]; - } - - public void encrypt(byte[] bytes, int off, int len) { - if (SysProperties.CHECK && (len % ALIGN != 0)) { - DbException.throwInternalError("unaligned len " + len); - } - for (int i = off; i < off + len; i += 16) { - encryptBlock(bytes, bytes, i); - } - } - - public void decrypt(byte[] bytes, int off, int len) { - if (SysProperties.CHECK && (len % ALIGN != 0)) { - DbException.throwInternalError("unaligned len " + len); - } - for (int i = off; i < off + len; i += 16) { - decryptBlock(bytes, bytes, i); - } - } - - private void encryptBlock(byte[] in, byte[] out, int off) { - int[] k = encKey; - int x0 = ((in[off] << 24) | ((in[off+1] & 255) << 16) | ((in[off+2] & 255) << 8) | (in[off+3] & 255)) ^ k[0]; - int x1 = ((in[off+4] << 24) | ((in[off+5] & 255) << 16) | ((in[off+6] & 255) << 8) | (in[off+7] & 255)) ^ k[1]; - int x2 = ((in[off+8] << 24) | ((in[off+9] & 255) << 16) | ((in[off+10] & 255) << 8) | (in[off+11] & 255)) ^ k[2]; - int x3 = ((in[off+12] << 24) | ((in[off+13] & 255) << 16) | ((in[off+14] & 255) << 8) | (in[off+15] & 255)) ^ k[3]; - int y0 = FT0[(x0 >> 24) & 255] ^ FT1[(x1 >> 16) & 255] ^ FT2[(x2 >> 8) & 255] ^ FT3[x3 & 255] ^ k[4]; - int y1 = FT0[(x1 >> 24) & 255] ^ FT1[(x2 >> 16) & 255] ^ FT2[(x3 >> 8) & 255] ^ FT3[x0 & 255] ^ k[5]; - int y2 = FT0[(x2 >> 24) & 255] ^ FT1[(x3 >> 16) & 255] ^ FT2[(x0 >> 8) & 255] ^ FT3[x1 & 255] ^ k[6]; - int y3 = FT0[(x3 >> 24) & 255] ^ FT1[(x0 >> 16) & 255] ^ FT2[(x1 >> 8) & 255] ^ FT3[x2 & 255] ^ k[7]; - x0 = FT0[(y0 >> 24) & 255] ^ FT1[(y1 >> 16) & 255] ^ FT2[(y2 >> 8) & 255] ^ FT3[y3 & 255] ^ k[8]; - x1 = FT0[(y1 >> 24) & 255] ^ FT1[(y2 >> 16) & 255] ^ FT2[(y3 >> 8) & 255] ^ FT3[y0 & 255] ^ k[9]; - x2 = FT0[(y2 >> 24) & 255] ^ FT1[(y3 >> 16) & 255] ^ FT2[(y0 >> 8) & 255] ^ FT3[y1 & 255] ^ k[10]; - x3 = FT0[(y3 >> 24) & 255] ^ FT1[(y0 >> 16) & 255] ^ FT2[(y1 >> 8) & 255] ^ FT3[y2 & 255] ^ k[11]; - y0 = FT0[(x0 >> 24) & 255] ^ FT1[(x1 >> 16) & 255] ^ FT2[(x2 >> 8) & 255] ^ FT3[x3 & 255] ^ k[12]; - y1 = FT0[(x1 >> 24) & 255] ^ FT1[(x2 >> 16) & 255] ^ FT2[(x3 >> 8) & 255] ^ FT3[x0 & 255] ^ k[13]; - y2 = FT0[(x2 >> 24) & 255] ^ FT1[(x3 >> 16) & 255] ^ FT2[(x0 >> 8) & 255] ^ FT3[x1 & 255] ^ k[14]; - y3 = FT0[(x3 >> 24) & 255] ^ FT1[(x0 >> 16) & 255] ^ FT2[(x1 >> 8) & 255] ^ FT3[x2 & 255] ^ k[15]; - x0 = FT0[(y0 >> 24) & 255] ^ FT1[(y1 >> 16) & 255] ^ FT2[(y2 >> 8) & 255] ^ FT3[y3 & 255] ^ k[16]; - x1 = FT0[(y1 >> 24) & 255] ^ FT1[(y2 >> 16) & 255] ^ FT2[(y3 >> 8) & 255] ^ FT3[y0 & 255] ^ k[17]; - x2 = FT0[(y2 >> 24) & 255] ^ FT1[(y3 >> 16) & 255] ^ FT2[(y0 >> 8) & 255] ^ FT3[y1 & 255] ^ k[18]; - x3 = FT0[(y3 >> 24) & 255] ^ FT1[(y0 >> 16) & 255] ^ FT2[(y1 >> 8) & 255] ^ FT3[y2 & 255] ^ k[19]; - y0 = FT0[(x0 >> 24) & 255] ^ FT1[(x1 >> 16) & 255] ^ FT2[(x2 >> 8) & 255] ^ FT3[x3 & 255] ^ k[20]; - y1 = FT0[(x1 >> 24) & 255] ^ FT1[(x2 >> 16) & 255] ^ FT2[(x3 >> 8) & 255] ^ FT3[x0 & 255] ^ k[21]; - y2 = FT0[(x2 >> 24) & 255] ^ FT1[(x3 >> 16) & 255] ^ FT2[(x0 >> 8) & 255] ^ FT3[x1 & 255] ^ k[22]; - y3 = FT0[(x3 >> 24) & 255] ^ FT1[(x0 >> 16) & 255] ^ FT2[(x1 >> 8) & 255] ^ FT3[x2 & 255] ^ k[23]; - x0 = FT0[(y0 >> 24) & 255] ^ FT1[(y1 >> 16) & 255] ^ FT2[(y2 >> 8) & 255] ^ FT3[y3 & 255] ^ k[24]; - x1 = FT0[(y1 >> 24) & 255] ^ FT1[(y2 >> 16) & 255] ^ FT2[(y3 >> 8) & 255] ^ FT3[y0 & 255] ^ k[25]; - x2 = FT0[(y2 >> 24) & 255] ^ FT1[(y3 >> 16) & 255] ^ FT2[(y0 >> 8) & 255] ^ FT3[y1 & 255] ^ k[26]; - x3 = FT0[(y3 >> 24) & 255] ^ FT1[(y0 >> 16) & 255] ^ FT2[(y1 >> 8) & 255] ^ FT3[y2 & 255] ^ k[27]; - y0 = FT0[(x0 >> 24) & 255] ^ FT1[(x1 >> 16) & 255] ^ FT2[(x2 >> 8) & 255] ^ FT3[x3 & 255] ^ k[28]; - y1 = FT0[(x1 >> 24) & 255] ^ FT1[(x2 >> 16) & 255] ^ FT2[(x3 >> 8) & 255] ^ FT3[x0 & 255] ^ k[29]; - y2 = FT0[(x2 >> 24) & 255] ^ FT1[(x3 >> 16) & 255] ^ FT2[(x0 >> 8) & 255] ^ FT3[x1 & 255] ^ k[30]; - y3 = FT0[(x3 >> 24) & 255] ^ FT1[(x0 >> 16) & 255] ^ FT2[(x1 >> 8) & 255] ^ FT3[x2 & 255] ^ k[31]; - x0 = FT0[(y0 >> 24) & 255] ^ FT1[(y1 >> 16) & 255] ^ FT2[(y2 >> 8) & 255] ^ FT3[y3 & 255] ^ k[32]; - x1 = FT0[(y1 >> 24) & 255] ^ FT1[(y2 >> 16) & 255] ^ FT2[(y3 >> 8) & 255] ^ FT3[y0 & 255] ^ k[33]; - x2 = FT0[(y2 >> 24) & 255] ^ FT1[(y3 >> 16) & 255] ^ FT2[(y0 >> 8) & 255] ^ FT3[y1 & 255] ^ k[34]; - x3 = FT0[(y3 >> 24) & 255] ^ FT1[(y0 >> 16) & 255] ^ FT2[(y1 >> 8) & 255] ^ FT3[y2 & 255] ^ k[35]; - y0 = FT0[(x0 >> 24) & 255] ^ FT1[(x1 >> 16) & 255] ^ FT2[(x2 >> 8) & 255] ^ FT3[x3 & 255] ^ k[36]; - y1 = FT0[(x1 >> 24) & 255] ^ FT1[(x2 >> 16) & 255] ^ FT2[(x3 >> 8) & 255] ^ FT3[x0 & 255] ^ k[37]; - y2 = FT0[(x2 >> 24) & 255] ^ FT1[(x3 >> 16) & 255] ^ FT2[(x0 >> 8) & 255] ^ FT3[x1 & 255] ^ k[38]; - y3 = FT0[(x3 >> 24) & 255] ^ FT1[(x0 >> 16) & 255] ^ FT2[(x1 >> 8) & 255] ^ FT3[x2 & 255] ^ k[39]; - x0 = ((FS[(y0 >> 24) & 255] << 24) | (FS[(y1 >> 16) & 255] << 16) | (FS[(y2 >> 8) & 255] << 8) | FS[y3 & 255]) ^ k[40]; - x1 = ((FS[(y1 >> 24) & 255] << 24) | (FS[(y2 >> 16) & 255] << 16) | (FS[(y3 >> 8) & 255] << 8) | FS[y0 & 255]) ^ k[41]; - x2 = ((FS[(y2 >> 24) & 255] << 24) | (FS[(y3 >> 16) & 255] << 16) | (FS[(y0 >> 8) & 255] << 8) | FS[y1 & 255]) ^ k[42]; - x3 = ((FS[(y3 >> 24) & 255] << 24) | (FS[(y0 >> 16) & 255] << 16) | (FS[(y1 >> 8) & 255] << 8) | FS[y2 & 255]) ^ k[43]; - out[off] = (byte) (x0 >> 24); out[off+1] = (byte) (x0 >> 16); out[off+2] = (byte) (x0 >> 8); out[off+3] = (byte) x0; - out[off+4] = (byte) (x1 >> 24); out[off+5] = (byte) (x1 >> 16); out[off+6] = (byte) (x1 >> 8); out[off+7] = (byte) x1; - out[off+8] = (byte) (x2 >> 24); out[off+9] = (byte) (x2 >> 16); out[off+10] = (byte) (x2 >> 8); out[off+11] = (byte) x2; - out[off+12] = (byte) (x3 >> 24); out[off+13] = (byte) (x3 >> 16); out[off+14] = (byte) (x3 >> 8); out[off+15] = (byte) x3; - } - - private void decryptBlock(byte[] in, byte[] out, int off) { - int[] k = decKey; - int x0 = ((in[off] << 24) | ((in[off+1] & 255) << 16) | ((in[off+2] & 255) << 8) | (in[off+3] & 255)) ^ k[0]; - int x1 = ((in[off+4] << 24) | ((in[off+5] & 255) << 16) | ((in[off+6] & 255) << 8) | (in[off+7] & 255)) ^ k[1]; - int x2 = ((in[off+8] << 24) | ((in[off+9] & 255) << 16) | ((in[off+10] & 255) << 8) | (in[off+11] & 255)) ^ k[2]; - int x3 = ((in[off+12] << 24) | ((in[off+13] & 255) << 16) | ((in[off+14] & 255) << 8) | (in[off+15] & 255)) ^ k[3]; - int y0 = RT0[(x0 >> 24) & 255] ^ RT1[(x3 >> 16) & 255] ^ RT2[(x2 >> 8) & 255] ^ RT3[x1 & 255] ^ k[4]; - int y1 = RT0[(x1 >> 24) & 255] ^ RT1[(x0 >> 16) & 255] ^ RT2[(x3 >> 8) & 255] ^ RT3[x2 & 255] ^ k[5]; - int y2 = RT0[(x2 >> 24) & 255] ^ RT1[(x1 >> 16) & 255] ^ RT2[(x0 >> 8) & 255] ^ RT3[x3 & 255] ^ k[6]; - int y3 = RT0[(x3 >> 24) & 255] ^ RT1[(x2 >> 16) & 255] ^ RT2[(x1 >> 8) & 255] ^ RT3[x0 & 255] ^ k[7]; - x0 = RT0[(y0 >> 24) & 255] ^ RT1[(y3 >> 16) & 255] ^ RT2[(y2 >> 8) & 255] ^ RT3[y1 & 255] ^ k[8]; - x1 = RT0[(y1 >> 24) & 255] ^ RT1[(y0 >> 16) & 255] ^ RT2[(y3 >> 8) & 255] ^ RT3[y2 & 255] ^ k[9]; - x2 = RT0[(y2 >> 24) & 255] ^ RT1[(y1 >> 16) & 255] ^ RT2[(y0 >> 8) & 255] ^ RT3[y3 & 255] ^ k[10]; - x3 = RT0[(y3 >> 24) & 255] ^ RT1[(y2 >> 16) & 255] ^ RT2[(y1 >> 8) & 255] ^ RT3[y0 & 255] ^ k[11]; - y0 = RT0[(x0 >> 24) & 255] ^ RT1[(x3 >> 16) & 255] ^ RT2[(x2 >> 8) & 255] ^ RT3[x1 & 255] ^ k[12]; - y1 = RT0[(x1 >> 24) & 255] ^ RT1[(x0 >> 16) & 255] ^ RT2[(x3 >> 8) & 255] ^ RT3[x2 & 255] ^ k[13]; - y2 = RT0[(x2 >> 24) & 255] ^ RT1[(x1 >> 16) & 255] ^ RT2[(x0 >> 8) & 255] ^ RT3[x3 & 255] ^ k[14]; - y3 = RT0[(x3 >> 24) & 255] ^ RT1[(x2 >> 16) & 255] ^ RT2[(x1 >> 8) & 255] ^ RT3[x0 & 255] ^ k[15]; - x0 = RT0[(y0 >> 24) & 255] ^ RT1[(y3 >> 16) & 255] ^ RT2[(y2 >> 8) & 255] ^ RT3[y1 & 255] ^ k[16]; - x1 = RT0[(y1 >> 24) & 255] ^ RT1[(y0 >> 16) & 255] ^ RT2[(y3 >> 8) & 255] ^ RT3[y2 & 255] ^ k[17]; - x2 = RT0[(y2 >> 24) & 255] ^ RT1[(y1 >> 16) & 255] ^ RT2[(y0 >> 8) & 255] ^ RT3[y3 & 255] ^ k[18]; - x3 = RT0[(y3 >> 24) & 255] ^ RT1[(y2 >> 16) & 255] ^ RT2[(y1 >> 8) & 255] ^ RT3[y0 & 255] ^ k[19]; - y0 = RT0[(x0 >> 24) & 255] ^ RT1[(x3 >> 16) & 255] ^ RT2[(x2 >> 8) & 255] ^ RT3[x1 & 255] ^ k[20]; - y1 = RT0[(x1 >> 24) & 255] ^ RT1[(x0 >> 16) & 255] ^ RT2[(x3 >> 8) & 255] ^ RT3[x2 & 255] ^ k[21]; - y2 = RT0[(x2 >> 24) & 255] ^ RT1[(x1 >> 16) & 255] ^ RT2[(x0 >> 8) & 255] ^ RT3[x3 & 255] ^ k[22]; - y3 = RT0[(x3 >> 24) & 255] ^ RT1[(x2 >> 16) & 255] ^ RT2[(x1 >> 8) & 255] ^ RT3[x0 & 255] ^ k[23]; - x0 = RT0[(y0 >> 24) & 255] ^ RT1[(y3 >> 16) & 255] ^ RT2[(y2 >> 8) & 255] ^ RT3[y1 & 255] ^ k[24]; - x1 = RT0[(y1 >> 24) & 255] ^ RT1[(y0 >> 16) & 255] ^ RT2[(y3 >> 8) & 255] ^ RT3[y2 & 255] ^ k[25]; - x2 = RT0[(y2 >> 24) & 255] ^ RT1[(y1 >> 16) & 255] ^ RT2[(y0 >> 8) & 255] ^ RT3[y3 & 255] ^ k[26]; - x3 = RT0[(y3 >> 24) & 255] ^ RT1[(y2 >> 16) & 255] ^ RT2[(y1 >> 8) & 255] ^ RT3[y0 & 255] ^ k[27]; - y0 = RT0[(x0 >> 24) & 255] ^ RT1[(x3 >> 16) & 255] ^ RT2[(x2 >> 8) & 255] ^ RT3[x1 & 255] ^ k[28]; - y1 = RT0[(x1 >> 24) & 255] ^ RT1[(x0 >> 16) & 255] ^ RT2[(x3 >> 8) & 255] ^ RT3[x2 & 255] ^ k[29]; - y2 = RT0[(x2 >> 24) & 255] ^ RT1[(x1 >> 16) & 255] ^ RT2[(x0 >> 8) & 255] ^ RT3[x3 & 255] ^ k[30]; - y3 = RT0[(x3 >> 24) & 255] ^ RT1[(x2 >> 16) & 255] ^ RT2[(x1 >> 8) & 255] ^ RT3[x0 & 255] ^ k[31]; - x0 = RT0[(y0 >> 24) & 255] ^ RT1[(y3 >> 16) & 255] ^ RT2[(y2 >> 8) & 255] ^ RT3[y1 & 255] ^ k[32]; - x1 = RT0[(y1 >> 24) & 255] ^ RT1[(y0 >> 16) & 255] ^ RT2[(y3 >> 8) & 255] ^ RT3[y2 & 255] ^ k[33]; - x2 = RT0[(y2 >> 24) & 255] ^ RT1[(y1 >> 16) & 255] ^ RT2[(y0 >> 8) & 255] ^ RT3[y3 & 255] ^ k[34]; - x3 = RT0[(y3 >> 24) & 255] ^ RT1[(y2 >> 16) & 255] ^ RT2[(y1 >> 8) & 255] ^ RT3[y0 & 255] ^ k[35]; - y0 = RT0[(x0 >> 24) & 255] ^ RT1[(x3 >> 16) & 255] ^ RT2[(x2 >> 8) & 255] ^ RT3[x1 & 255] ^ k[36]; - y1 = RT0[(x1 >> 24) & 255] ^ RT1[(x0 >> 16) & 255] ^ RT2[(x3 >> 8) & 255] ^ RT3[x2 & 255] ^ k[37]; - y2 = RT0[(x2 >> 24) & 255] ^ RT1[(x1 >> 16) & 255] ^ RT2[(x0 >> 8) & 255] ^ RT3[x3 & 255] ^ k[38]; - y3 = RT0[(x3 >> 24) & 255] ^ RT1[(x2 >> 16) & 255] ^ RT2[(x1 >> 8) & 255] ^ RT3[x0 & 255] ^ k[39]; - x0 = ((RS[(y0 >> 24) & 255] << 24) | (RS[(y3 >> 16) & 255] << 16) | (RS[(y2 >> 8) & 255] << 8) | RS[y1 & 255]) ^ k[40]; - x1 = ((RS[(y1 >> 24) & 255] << 24) | (RS[(y0 >> 16) & 255] << 16) | (RS[(y3 >> 8) & 255] << 8) | RS[y2 & 255]) ^ k[41]; - x2 = ((RS[(y2 >> 24) & 255] << 24) | (RS[(y1 >> 16) & 255] << 16) | (RS[(y0 >> 8) & 255] << 8) | RS[y3 & 255]) ^ k[42]; - x3 = ((RS[(y3 >> 24) & 255] << 24) | (RS[(y2 >> 16) & 255] << 16) | (RS[(y1 >> 8) & 255] << 8) | RS[y0 & 255]) ^ k[43]; - out[off] = (byte) (x0 >> 24); out[off+1] = (byte) (x0 >> 16); out[off+2] = (byte) (x0 >> 8); out[off+3] = (byte) x0; - out[off+4] = (byte) (x1 >> 24); out[off+5] = (byte) (x1 >> 16); out[off+6] = (byte) (x1 >> 8); out[off+7] = (byte) x1; - out[off+8] = (byte) (x2 >> 24); out[off+9] = (byte) (x2 >> 16); out[off+10] = (byte) (x2 >> 8); out[off+11] = (byte) x2; - out[off+12] = (byte) (x3 >> 24); out[off+13] = (byte) (x3 >> 16); out[off+14] = (byte) (x3 >> 8); out[off+15] = (byte) x3; - } - - public int getKeyLength() { - return 4 * 4; - } - -} diff --git a/tools/h2/src/main/org/h2/security/BlockCipher.java b/tools/h2/src/main/org/h2/security/BlockCipher.java deleted file mode 100755 index 7d4af72..0000000 --- a/tools/h2/src/main/org/h2/security/BlockCipher.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.security; - -/** - * A block cipher is a data encryption algorithm that operates on blocks. - */ -public interface BlockCipher { - - /** - * Blocks sizes are always multiples of this number. - */ - int ALIGN = 16; - - /** - * Set the encryption key used for encrypting and decrypting. - * The key needs to be 16 bytes long. - * - * @param key the key - */ - void setKey(byte[] key); - - /** - * Encrypt a number of bytes. This is done in-place, that - * means the bytes are overwritten. - * - * @param bytes the byte array - * @param off the start index - * @param len the number of bytes to encrypt - */ - void encrypt(byte[] bytes, int off, int len); - - /** - * Decrypt a number of bytes. This is done in-place, that - * means the bytes are overwritten. - * - * @param bytes the byte array - * @param off the start index - * @param len the number of bytes to decrypt - */ - void decrypt(byte[] bytes, int off, int len); - - /** - * Get the length of the key in bytes. - * - * @return the length of the key - */ - int getKeyLength(); -} diff --git a/tools/h2/src/main/org/h2/security/CipherFactory.java b/tools/h2/src/main/org/h2/security/CipherFactory.java deleted file mode 100755 index 4bde090..0000000 --- a/tools/h2/src/main/org/h2/security/CipherFactory.java +++ /dev/null @@ -1,225 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.security; - -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.net.InetAddress; -import java.net.InetSocketAddress; -import java.net.ServerSocket; -import java.net.Socket; -import java.security.KeyFactory; -import java.security.KeyStore; -import java.security.PrivateKey; -import java.security.cert.Certificate; -import java.security.cert.CertificateFactory; -import java.security.spec.PKCS8EncodedKeySpec; -import java.util.Properties; -import javax.net.ServerSocketFactory; -import javax.net.ssl.SSLServerSocket; -import javax.net.ssl.SSLServerSocketFactory; -import javax.net.ssl.SSLSocket; -import javax.net.ssl.SSLSocketFactory; -import org.h2.constant.ErrorCode; -import org.h2.constant.SysProperties; -import org.h2.message.DbException; -import org.h2.util.IOUtils; -import org.h2.util.Utils; - -/** - * A factory to create new block cipher objects. - */ -public class CipherFactory { - - /** - * The default password to use for the .h2.keystore file - */ - public static final String KEYSTORE_PASSWORD = "h2pass"; - private static final String KEYSTORE = ".h2.keystore"; - private static final String KEYSTORE_KEY = "javax.net.ssl.keyStore"; - private static final String KEYSTORE_PASSWORD_KEY = "javax.net.ssl.keyStorePassword"; - private static final String ANONYMOUS_CIPHER_SUITE = "SSL_DH_anon_WITH_RC4_128_MD5"; - - private CipherFactory() { - // utility class - } - - /** - * Get a new block cipher object for the given algorithm. - * - * @param algorithm the algorithm - * @return a new cipher object - */ - public static BlockCipher getBlockCipher(String algorithm) { - if ("XTEA".equalsIgnoreCase(algorithm)) { - return new XTEA(); - } else if ("AES".equalsIgnoreCase(algorithm)) { - return new AES(); - } - throw DbException.get(ErrorCode.UNSUPPORTED_CIPHER, algorithm); - } - - /** - * Get a new cryptographic hash object for the given algorithm. - * - * @param algorithm the algorithm - * @return a new hash object - */ - public static SHA256 getHash(String algorithm) { - if ("SHA256".equalsIgnoreCase(algorithm)) { - return new SHA256(); - } - throw DbException.getInvalidValueException(algorithm, "algorithm"); - } - - /** - * Create a secure client socket that is connected to the given address and port. - * - * @param address the address to connect to - * @param port the port - * @return the socket - */ - public static Socket createSocket(InetAddress address, int port) throws IOException { - Socket socket = null; -//## Java 1.4 begin ## - setKeystore(); - SSLSocketFactory f = (SSLSocketFactory) SSLSocketFactory.getDefault(); - SSLSocket secureSocket = (SSLSocket) f.createSocket(); - secureSocket.connect(new InetSocketAddress(address, port), - SysProperties.SOCKET_CONNECT_TIMEOUT); - if (SysProperties.ENABLE_ANONYMOUS_SSL) { - String[] list = secureSocket.getEnabledCipherSuites(); - list = addAnonymous(list); - secureSocket.setEnabledCipherSuites(list); - } - socket = secureSocket; -//## Java 1.4 end ## - return socket; - } - -/** - * Create a secure server socket. If a bind address is specified, the socket - * is only bound to this address. - * - * @param port the port to listen on - * @param bindAddress the address to bind to, or null to bind to all - * addresses - * @return the server socket - */ - public static ServerSocket createServerSocket(int port, InetAddress bindAddress) throws IOException { - ServerSocket socket = null; -//## Java 1.4 begin ## - setKeystore(); - ServerSocketFactory f = SSLServerSocketFactory.getDefault(); - SSLServerSocket secureSocket; - if (bindAddress == null) { - secureSocket = (SSLServerSocket) f.createServerSocket(port); - } else { - secureSocket = (SSLServerSocket) f.createServerSocket(port, 0, bindAddress); - } - if (SysProperties.ENABLE_ANONYMOUS_SSL) { - String[] list = secureSocket.getEnabledCipherSuites(); - list = addAnonymous(list); - secureSocket.setEnabledCipherSuites(list); - } - socket = secureSocket; -//## Java 1.4 end ## - return socket; - } - -//## Java 1.4 begin ## - private static byte[] getKeyStoreBytes(KeyStore store, String password) throws IOException { - ByteArrayOutputStream bout = new ByteArrayOutputStream(); - try { - store.store(bout, password.toCharArray()); - } catch (Exception e) { - throw DbException.convertToIOException(e); - } - return bout.toByteArray(); - } -//## Java 1.4 end ## - -/** - * Get the keystore object using the given password. - * - * @param password the keystore password - * @return the keystore - */ -//## Java 1.4 begin ## - public static KeyStore getKeyStore(String password) throws IOException { - try { - // The following source code can be re-generated - // if you have a keystore file. - // This code is (hopefully) more Java version independent - // than using keystores directly. See also: - // http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4887561 - // (1.4.2 cannot read keystore written with 1.4.1) - // --- generated code start --- - - KeyStore store = KeyStore.getInstance(KeyStore.getDefaultType()); - - store.load(null, password.toCharArray()); - KeyFactory keyFactory = KeyFactory.getInstance("RSA"); - store.load(null, password.toCharArray()); - PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec( - Utils.convertStringToBytes("30820277020100300d06092a864886f70d0101010500048202613082025d02010002818100dc0a13c602b7141110eade2f051b54777b060d0f74e6a110f9cce81159f271ebc88d8e8aa1f743b505fc2e7dfe38d33b8d3f64d1b363d1af4d877833897954cbaec2fa384c22a415498cf306bb07ac09b76b001cd68bf77ea0a628f5101959cf2993a9c23dbee79b19305977f8715ae78d023471194cc900b231eecb0aaea98d02030100010281810099aa4ff4d0a09a5af0bd953cb10c4d08c3d98df565664ac5582e494314d5c3c92dddedd5d316a32a206be4ec084616fe57be15e27cad111aa3c21fa79e32258c6ca8430afc69eddd52d3b751b37da6b6860910b94653192c0db1d02abcfd6ce14c01f238eec7c20bd3bb750940004bacba2880349a9494d10e139ecb2355d101024100ffdc3defd9c05a2d377ef6019fa62b3fbd5b0020a04cc8533bca730e1f6fcf5dfceea1b044fbe17d9eababfbc7d955edad6bc60f9be826ad2c22ba77d19a9f65024100dc28d43fdbbc93852cc3567093157702bc16f156f709fb7db0d9eec028f41fd0edcd17224c866e66be1744141fb724a10fd741c8a96afdd9141b36d67fff6309024077b1cddbde0f69604bdcfe33263fb36ddf24aa3b9922327915b890f8a36648295d0139ecdf68c245652c4489c6257b58744fbdd961834a4cab201801a3b1e52d024100b17142e8991d1b350a0802624759d48ae2b8071a158ff91fabeb6a8f7c328e762143dc726b8529f42b1fab6220d1c676fdc27ba5d44e847c72c52064afd351a902407c6e23fe35bcfcd1a662aa82a2aa725fcece311644d5b6e3894853fd4ce9fe78218c957b1ff03fc9e5ef8ffeb6bd58235f6a215c97d354fdace7e781e4a63e8b")); - PrivateKey privateKey = keyFactory.generatePrivate(keySpec); - Certificate[] certs = { CertificateFactory - .getInstance("X.509") - .generateCertificate( - new ByteArrayInputStream( - Utils.convertStringToBytes("3082018b3081f502044295ce6b300d06092a864886f70d0101040500300d310b3009060355040313024832301e170d3035303532363133323630335a170d3337303933303036353734375a300d310b300906035504031302483230819f300d06092a864886f70d010101050003818d0030818902818100dc0a13c602b7141110eade2f051b54777b060d0f74e6a110f9cce81159f271ebc88d8e8aa1f743b505fc2e7dfe38d33b8d3f64d1b363d1af4d877833897954cbaec2fa384c22a415498cf306bb07ac09b76b001cd68bf77ea0a628f5101959cf2993a9c23dbee79b19305977f8715ae78d023471194cc900b231eecb0aaea98d0203010001300d06092a864886f70d01010405000381810083f4401a279453701bef9a7681a5b8b24f153f7d18c7c892133d97bd5f13736be7505290a445a7d5ceb75522403e5097515cd966ded6351ff60d5193de34cd36e5cb04d380398e66286f99923fd92296645fd4ada45844d194dfd815e6cd57f385c117be982809028bba1116c85740b3d27a55b1a0948bf291ddba44bed337b9"))), }; - store.setKeyEntry("h2", privateKey, password.toCharArray(), certs); - // --- generated code end --- - return store; - } catch (Exception e) { - throw DbException.convertToIOException(e); - } - } - - private static void setKeystore() throws IOException { - Properties p = System.getProperties(); - if (p.getProperty(KEYSTORE_KEY) == null) { - String fileName = IOUtils.getFileInUserHome(KEYSTORE); - byte[] data = getKeyStoreBytes(getKeyStore(KEYSTORE_PASSWORD), KEYSTORE_PASSWORD); - boolean needWrite = true; - if (IOUtils.exists(fileName) && IOUtils.length(fileName) == data.length) { - // don't need to overwrite the file if it did not change - InputStream fin = IOUtils.openFileInputStream(fileName); - byte[] now = IOUtils.readBytesAndClose(fin, 0); - if (now != null && Utils.compareNotNull(data, now) == 0) { - needWrite = false; - } - } - if (needWrite) { - try { - OutputStream out = IOUtils.openFileOutputStream(fileName, false); - out.write(data); - out.close(); - } catch (Exception e) { - throw DbException.convertToIOException(e); - } - } - String absolutePath = IOUtils.getAbsolutePath(fileName); - System.setProperty(KEYSTORE_KEY, absolutePath); - } - if (p.getProperty(KEYSTORE_PASSWORD_KEY) == null) { - System.setProperty(KEYSTORE_PASSWORD_KEY, KEYSTORE_PASSWORD); - } - } - - private static String[] addAnonymous(String[] list) { - String[] newList = new String[list.length + 1]; - System.arraycopy(list, 0, newList, 1, list.length); - newList[0] = ANONYMOUS_CIPHER_SUITE; - return newList; - } - -} diff --git a/tools/h2/src/main/org/h2/security/SHA256.java b/tools/h2/src/main/org/h2/security/SHA256.java deleted file mode 100755 index 7857dfc..0000000 --- a/tools/h2/src/main/org/h2/security/SHA256.java +++ /dev/null @@ -1,172 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.security; - -import java.util.Arrays; - -/** - * This class implements the cryptographic hash function SHA-256. - */ -public class SHA256 { - - /** - * The first 32 bits of the fractional parts of the cube roots of the first - * sixty-four prime numbers. - */ - private static final int[] K = { 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, - 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5, 0xd807aa98, - 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, - 0x9bdc06a7, 0xc19bf174, 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, - 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, - 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, - 0xd5a79147, 0x06ca6351, 0x14292967, 0x27b70a85, 0x2e1b2138, - 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, - 0x92722c85, 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, - 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070, 0x19a4c116, - 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, - 0x5b9cca4f, 0x682e6ff3, 0x748f82ee, 0x78a5636f, 0x84c87814, - 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2 }; - - /** - * Calculate the hash code by using the given salt. The salt is appended - * after the data before the hash code is calculated. After generating the - * hash code, the data and all internal buffers are filled with zeros to avoid - * keeping insecure data in memory longer than required (and possibly - * swapped to disk). - * - * @param data the data to hash - * @param salt the salt to use - * @return the hash code - */ - public byte[] getHashWithSalt(byte[] data, byte[] salt) { - byte[] buff = new byte[data.length + salt.length]; - System.arraycopy(data, 0, buff, 0, data.length); - System.arraycopy(salt, 0, buff, data.length, salt.length); - return getHash(buff, true); - } - - /** - * Calculate the hash of a password by prepending the user name and a '@' - * character. Both the user name and the password are encoded to a byte - * array using UTF-16. After generating the hash code, the password array - * and all internal buffers are filled with zeros to avoid keeping the plain text - * password in memory longer than required (and possibly swapped to disk). - * - * @param userName the user name - * @param password the password - * @return the hash code - */ - public byte[] getKeyPasswordHash(String userName, char[] password) { - String user = userName + "@"; - byte[] buff = new byte[2 * (user.length() + password.length)]; - int n = 0; - for (int i = 0; i < user.length(); i++) { - char c = user.charAt(i); - buff[n++] = (byte) (c >> 8); - buff[n++] = (byte) c; - } - for (int i = 0; i < password.length; i++) { - char c = password[i]; - buff[n++] = (byte) (c >> 8); - buff[n++] = (byte) c; - } - Arrays.fill(password, (char) 0); - return getHash(buff, true); - } - - /** - * Calculate the hash code for the given data. - * - * @param data the data to hash - * @param nullData if the data should be filled with zeros after calculating - * the hash code - * @return the hash code - */ - public byte[] getHash(byte[] data, boolean nullData) { - int byteLen = data.length; - int intLen = ((byteLen + 9 + 63) / 64) * 16; - byte[] bytes = new byte[intLen * 4]; - System.arraycopy(data, 0, bytes, 0, byteLen); - if (nullData) { - Arrays.fill(data, (byte) 0); - } - bytes[byteLen] = (byte) 0x80; - int[] buff = new int[intLen]; - for (int i = 0, j = 0; j < intLen; i += 4, j++) { - buff[j] = readInt(bytes, i); - } - buff[intLen - 2] = byteLen >>> 29; - buff[intLen - 1] = byteLen << 3; - int[] w = new int[64]; - int[] hh = { 0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, - 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19 }; - for (int block = 0; block < intLen; block += 16) { - for (int i = 0; i < 16; i++) { - w[i] = buff[block + i]; - } - for (int i = 16; i < 64; i++) { - int x = w[i - 2]; - int theta1 = rot(x, 17) ^ rot(x, 19) ^ (x >>> 10); - x = w[i - 15]; - int theta0 = rot(x, 7) ^ rot(x, 18) ^ (x >>> 3); - w[i] = theta1 + w[i - 7] + theta0 + w[i - 16]; - } - - int a = hh[0], b = hh[1], c = hh[2], d = hh[3]; - int e = hh[4], f = hh[5], g = hh[6], h = hh[7]; - - for (int i = 0; i < 64; i++) { - int t1 = h + (rot(e, 6) ^ rot(e, 11) ^ rot(e, 25)) - + ((e & f) ^ ((~e) & g)) + K[i] + w[i]; - int t2 = (rot(a, 2) ^ rot(a, 13) ^ rot(a, 22)) - + ((a & b) ^ (a & c) ^ (b & c)); - h = g; - g = f; - f = e; - e = d + t1; - d = c; - c = b; - b = a; - a = t1 + t2; - } - hh[0] += a; - hh[1] += b; - hh[2] += c; - hh[3] += d; - hh[4] += e; - hh[5] += f; - hh[6] += g; - hh[7] += h; - } - byte[] result = new byte[32]; - for (int i = 0; i < 8; i++) { - writeInt(result, i * 4, hh[i]); - } - Arrays.fill(w, 0); - Arrays.fill(buff, 0); - Arrays.fill(hh, 0); - Arrays.fill(bytes, (byte) 0); - return result; - } - - private int rot(int i, int count) { - return (i << (32 - count)) | (i >>> count); - } - - private int readInt(byte[] b, int i) { - return ((b[i] & 0xff) << 24) + ((b[i + 1] & 0xff) << 16) - + ((b[i + 2] & 0xff) << 8) + (b[i + 3] & 0xff); - } - - private void writeInt(byte[] b, int i, int value) { - b[i] = (byte) (value >> 24); - b[i + 1] = (byte) (value >> 16); - b[i + 2] = (byte) (value >> 8); - b[i + 3] = (byte) value; - } - -} diff --git a/tools/h2/src/main/org/h2/security/SecureFileStore.java b/tools/h2/src/main/org/h2/security/SecureFileStore.java deleted file mode 100755 index ee7f535..0000000 --- a/tools/h2/src/main/org/h2/security/SecureFileStore.java +++ /dev/null @@ -1,129 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.security; - -import org.h2.engine.Constants; -import org.h2.store.DataHandler; -import org.h2.store.FileStore; -import org.h2.util.MathUtils; - -/** - * A file store that encrypts all data before writing, - * and decrypts all data after reading. - */ -public class SecureFileStore extends FileStore { - - private byte[] key; - private BlockCipher cipher; - private BlockCipher cipherForInitVector; - private byte[] buffer = new byte[4]; - private long pos; - private byte[] bufferForInitVector; - private int keyIterations; - - public SecureFileStore(DataHandler handler, String name, String mode, String cipher, byte[] key, int keyIterations) { - super(handler, name, mode); - this.key = key; - this.cipher = CipherFactory.getBlockCipher(cipher); - this.cipherForInitVector = CipherFactory.getBlockCipher(cipher); - this.keyIterations = keyIterations; - bufferForInitVector = new byte[Constants.FILE_BLOCK_SIZE]; - } - - protected byte[] generateSalt() { - return MathUtils.secureRandomBytes(Constants.FILE_BLOCK_SIZE); - } - - protected void initKey(byte[] salt) { - SHA256 sha = new SHA256(); - key = sha.getHashWithSalt(key, salt); - for (int i = 0; i < keyIterations; i++) { - key = sha.getHash(key, true); - } - cipher.setKey(key); - key = sha.getHash(key, true); - cipherForInitVector.setKey(key); - } - - protected void writeDirect(byte[] b, int off, int len) { - super.write(b, off, len); - pos += len; - } - - public void write(byte[] b, int off, int len) { - if (buffer.length < b.length) { - buffer = new byte[len]; - } - System.arraycopy(b, off, buffer, 0, len); - xorInitVector(buffer, 0, len, pos); - cipher.encrypt(buffer, 0, len); - super.write(buffer, 0, len); - pos += len; - } - - protected void readFullyDirect(byte[] b, int off, int len) { - super.readFully(b, off, len); - pos += len; - } - - public void readFully(byte[] b, int off, int len) { - super.readFully(b, off, len); - cipher.decrypt(b, off, len); - xorInitVector(b, off, len, pos); - pos += len; - } - - public void seek(long x) { - this.pos = x; - super.seek(x); - } - - public void setLength(long newLength) { - long oldPos = pos; - long length = length(); - if (newLength > length) { - seek(length); - byte[] empty = EMPTY; - while (true) { - int p = (int) Math.min(newLength - length, EMPTY.length); - if (p <= 0) { - break; - } - write(empty, 0, p); - length += p; - } - seek(oldPos); - } else { - super.setLength(newLength); - } - } - - private void xorInitVector(byte[] b, int off, int len, long p) { - byte[] iv = bufferForInitVector; - while (len > 0) { - for (int i = 0; i < Constants.FILE_BLOCK_SIZE; i += 8) { - long block = (p + i) >>> 3; - iv[i] = (byte) (block >> 56); - iv[i + 1] = (byte) (block >> 48); - iv[i + 2] = (byte) (block >> 40); - iv[i + 3] = (byte) (block >> 32); - iv[i + 4] = (byte) (block >> 24); - iv[i + 5] = (byte) (block >> 16); - iv[i + 6] = (byte) (block >> 8); - iv[i + 7] = (byte) block; - } - cipherForInitVector.encrypt(iv, 0, Constants.FILE_BLOCK_SIZE); - for (int i = 0; i < Constants.FILE_BLOCK_SIZE; i++) { - b[off + i] ^= iv[i]; - } - p += Constants.FILE_BLOCK_SIZE; - off += Constants.FILE_BLOCK_SIZE; - len -= Constants.FILE_BLOCK_SIZE; - } - } - -} diff --git a/tools/h2/src/main/org/h2/security/XTEA.java b/tools/h2/src/main/org/h2/security/XTEA.java deleted file mode 100755 index dd12bac..0000000 --- a/tools/h2/src/main/org/h2/security/XTEA.java +++ /dev/null @@ -1,112 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.security; - -import org.h2.constant.SysProperties; -import org.h2.message.DbException; - -/** - * An implementation of the XTEA block cipher algorithm. - * This implementation uses 32 rounds. - */ -public class XTEA implements BlockCipher { - - // best attack reported as of 2004 is 26 rounds [wikipedia] - private static final int DELTA = 0x9E3779B9; - private int k0, k1, k2, k3, k4, k5, k6, k7, k8, k9, k10, k11, k12, k13, k14, k15; - private int k16, k17, k18, k19, k20, k21, k22, k23, k24, k25, k26, k27, k28, k29, k30, k31; - - XTEA() { - // do nothing - } - - public void setKey(byte[] b) { - int[] key = new int[4]; - for (int i = 0; i < 16;) { - key[i / 4] = (b[i++] << 24) + ((b[i++] & 255) << 16) + ((b[i++] & 255) << 8) + (b[i++] & 255); - } - int[] r = new int[32]; - for (int i = 0, sum = 0; i < 32;) { - r[i++] = sum + key[sum & 3]; - sum += DELTA; - r[i++] = sum + key[ (sum >>> 11) & 3]; - } - k0 = r[0]; k1 = r[1]; k2 = r[2]; k3 = r[3]; k4 = r[4]; k5 = r[5]; k6 = r[6]; k7 = r[7]; - k8 = r[8]; k9 = r[9]; k10 = r[10]; k11 = r[11]; k12 = r[12]; k13 = r[13]; k14 = r[14]; k15 = r[15]; - k16 = r[16]; k17 = r[17]; k18 = r[18]; k19 = r[19]; k20 = r[20]; k21 = r[21]; k22 = r[22]; k23 = r[23]; - k24 = r[24]; k25 = r[25]; k26 = r[26]; k27 = r[27]; k28 = r[28]; k29 = r[29]; k30 = r[30]; k31 = r[31]; - } - - public void encrypt(byte[] bytes, int off, int len) { - if (SysProperties.CHECK && (len % ALIGN != 0)) { - DbException.throwInternalError("unaligned len " + len); - } - for (int i = off; i < off + len; i += 8) { - encryptBlock(bytes, bytes, i); - } - } - - public void decrypt(byte[] bytes, int off, int len) { - if (SysProperties.CHECK && (len % ALIGN != 0)) { - DbException.throwInternalError("unaligned len " + len); - } - for (int i = off; i < off + len; i += 8) { - decryptBlock(bytes, bytes, i); - } - } - - private void encryptBlock(byte[] in, byte[] out, int off) { - int y = (in[off] << 24) | ((in[off+1] & 255) << 16) | ((in[off+2] & 255) << 8) | (in[off+3] & 255); - int z = (in[off+4] << 24) | ((in[off+5] & 255) << 16) | ((in[off+6] & 255) << 8) | (in[off+7] & 255); - y += (((z << 4) ^ (z >>> 5)) + z) ^ k0; z += (((y >>> 5) ^ (y << 4)) + y) ^ k1; - y += (((z << 4) ^ (z >>> 5)) + z) ^ k2; z += (((y >>> 5) ^ (y << 4)) + y) ^ k3; - y += (((z << 4) ^ (z >>> 5)) + z) ^ k4; z += (((y >>> 5) ^ (y << 4)) + y) ^ k5; - y += (((z << 4) ^ (z >>> 5)) + z) ^ k6; z += (((y >>> 5) ^ (y << 4)) + y) ^ k7; - y += (((z << 4) ^ (z >>> 5)) + z) ^ k8; z += (((y >>> 5) ^ (y << 4)) + y) ^ k9; - y += (((z << 4) ^ (z >>> 5)) + z) ^ k10; z += (((y >>> 5) ^ (y << 4)) + y) ^ k11; - y += (((z << 4) ^ (z >>> 5)) + z) ^ k12; z += (((y >>> 5) ^ (y << 4)) + y) ^ k13; - y += (((z << 4) ^ (z >>> 5)) + z) ^ k14; z += (((y >>> 5) ^ (y << 4)) + y) ^ k15; - y += (((z << 4) ^ (z >>> 5)) + z) ^ k16; z += (((y >>> 5) ^ (y << 4)) + y) ^ k17; - y += (((z << 4) ^ (z >>> 5)) + z) ^ k18; z += (((y >>> 5) ^ (y << 4)) + y) ^ k19; - y += (((z << 4) ^ (z >>> 5)) + z) ^ k20; z += (((y >>> 5) ^ (y << 4)) + y) ^ k21; - y += (((z << 4) ^ (z >>> 5)) + z) ^ k22; z += (((y >>> 5) ^ (y << 4)) + y) ^ k23; - y += (((z << 4) ^ (z >>> 5)) + z) ^ k24; z += (((y >>> 5) ^ (y << 4)) + y) ^ k25; - y += (((z << 4) ^ (z >>> 5)) + z) ^ k26; z += (((y >>> 5) ^ (y << 4)) + y) ^ k27; - y += (((z << 4) ^ (z >>> 5)) + z) ^ k28; z += (((y >>> 5) ^ (y << 4)) + y) ^ k29; - y += (((z << 4) ^ (z >>> 5)) + z) ^ k30; z += (((y >>> 5) ^ (y << 4)) + y) ^ k31; - out[off] = (byte) (y >> 24); out[off+1] = (byte) (y >> 16); out[off+2] = (byte) (y >> 8); out[off+3] = (byte) y; - out[off+4] = (byte) (z >> 24); out[off+5] = (byte) (z >> 16); out[off+6] = (byte) (z >> 8); out[off+7] = (byte) z; - } - - private void decryptBlock(byte[] in, byte[] out, int off) { - int y = (in[off] << 24) | ((in[off+1] & 255) << 16) | ((in[off+2] & 255) << 8) | (in[off+3] & 255); - int z = (in[off+4] << 24) | ((in[off+5] & 255) << 16) | ((in[off+6] & 255) << 8) | (in[off+7] & 255); - z -= (((y >>> 5) ^ (y << 4)) + y) ^ k31; y -= (((z << 4) ^ (z >>> 5)) + z) ^ k30; - z -= (((y >>> 5) ^ (y << 4)) + y) ^ k29; y -= (((z << 4) ^ (z >>> 5)) + z) ^ k28; - z -= (((y >>> 5) ^ (y << 4)) + y) ^ k27; y -= (((z << 4) ^ (z >>> 5)) + z) ^ k26; - z -= (((y >>> 5) ^ (y << 4)) + y) ^ k25; y -= (((z << 4) ^ (z >>> 5)) + z) ^ k24; - z -= (((y >>> 5) ^ (y << 4)) + y) ^ k23; y -= (((z << 4) ^ (z >>> 5)) + z) ^ k22; - z -= (((y >>> 5) ^ (y << 4)) + y) ^ k21; y -= (((z << 4) ^ (z >>> 5)) + z) ^ k20; - z -= (((y >>> 5) ^ (y << 4)) + y) ^ k19; y -= (((z << 4) ^ (z >>> 5)) + z) ^ k18; - z -= (((y >>> 5) ^ (y << 4)) + y) ^ k17; y -= (((z << 4) ^ (z >>> 5)) + z) ^ k16; - z -= (((y >>> 5) ^ (y << 4)) + y) ^ k15; y -= (((z << 4) ^ (z >>> 5)) + z) ^ k14; - z -= (((y >>> 5) ^ (y << 4)) + y) ^ k13; y -= (((z << 4) ^ (z >>> 5)) + z) ^ k12; - z -= (((y >>> 5) ^ (y << 4)) + y) ^ k11; y -= (((z << 4) ^ (z >>> 5)) + z) ^ k10; - z -= (((y >>> 5) ^ (y << 4)) + y) ^ k9; y -= (((z << 4) ^ (z >>> 5)) + z) ^ k8; - z -= (((y >>> 5) ^ (y << 4)) + y) ^ k7; y -= (((z << 4) ^ (z >>> 5)) + z) ^ k6; - z -= (((y >>> 5) ^ (y << 4)) + y) ^ k5; y -= (((z << 4) ^ (z >>> 5)) + z) ^ k4; - z -= (((y >>> 5) ^ (y << 4)) + y) ^ k3; y -= (((z << 4) ^ (z >>> 5)) + z) ^ k2; - z -= (((y >>> 5) ^ (y << 4)) + y) ^ k1; y -= (((z << 4) ^ (z >>> 5)) + z) ^ k0; - out[off] = (byte) (y >> 24); out[off+1] = (byte) (y >> 16); out[off+2] = (byte) (y >> 8); out[off+3] = (byte) y; - out[off+4] = (byte) (z >> 24); out[off+5] = (byte) (z >> 16); out[off+6] = (byte) (z >> 8); out[off+7] = (byte) z; - } - - public int getKeyLength() { - return 16; - } - -} diff --git a/tools/h2/src/main/org/h2/security/package.html b/tools/h2/src/main/org/h2/security/package.html deleted file mode 100755 index 3d990c9..0000000 --- a/tools/h2/src/main/org/h2/security/package.html +++ /dev/null @@ -1,15 +0,0 @@ - - - - -Javadoc package documentation -

- -Security classes, such as encryption and cryptographically secure hash algorithms. - -

\ No newline at end of file diff --git a/tools/h2/src/main/org/h2/server/Service.java b/tools/h2/src/main/org/h2/server/Service.java deleted file mode 100755 index 2ef448d..0000000 --- a/tools/h2/src/main/org/h2/server/Service.java +++ /dev/null @@ -1,93 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.server; - -import java.sql.SQLException; - -/** - * Classes implementing this interface usually provide a - * TCP/IP listener such as an FTP server. - * The can be started and stopped, and may or may not - * allow remote connections. - */ -public interface Service { - - /** - * Initialize the service from command line options. - * - * @param args the command line options - */ - void init(String... args) throws Exception; - - /** - * Get the URL of this service in a human readable form - * - * @return the url - */ - String getURL(); - - /** - * Start the service. This usually means create the server socket. - * This method must not block. - */ - void start() throws SQLException; - - /** - * Listen for incoming connections. - * This method blocks. - */ - void listen(); - - /** - * Stop the service. - */ - void stop(); - - /** - * Check if the service is running. - * - * @param traceError if errors should be written - * @return if the server is running - */ - boolean isRunning(boolean traceError); - - /** - * Check if remote connections are allowed. - * - * @return true if remote connections are allowed - */ - boolean getAllowOthers(); - - /** - * Get the human readable name of the service. - * - * @return the name - */ - String getName(); - - /** - * Get the human readable short name of the service. - * - * @return the type - */ - String getType(); - - /** - * Gets the port this service is listening on. - * - * @return the port - */ - int getPort(); - - /** - * Check if a daemon thread should be used. - * - * @return true if a daemon thread should be used - */ - boolean isDaemon(); - -} diff --git a/tools/h2/src/main/org/h2/server/ShutdownHandler.java b/tools/h2/src/main/org/h2/server/ShutdownHandler.java deleted file mode 100755 index 46d5141..0000000 --- a/tools/h2/src/main/org/h2/server/ShutdownHandler.java +++ /dev/null @@ -1,18 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.server; - -/** - * A shutdown handler is a listener for shutdown events. - */ -public interface ShutdownHandler { - - /** - * Tell the listener to shut down. - */ - void shutdown(); -} diff --git a/tools/h2/src/main/org/h2/server/TcpServer.java b/tools/h2/src/main/org/h2/server/TcpServer.java deleted file mode 100755 index 0adba4f..0000000 --- a/tools/h2/src/main/org/h2/server/TcpServer.java +++ /dev/null @@ -1,476 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.server; - -import java.io.IOException; -import java.net.ServerSocket; -import java.net.Socket; -import java.net.UnknownHostException; -import java.sql.Connection; -import java.sql.DriverManager; -import java.sql.PreparedStatement; -import java.sql.SQLException; -import java.sql.Statement; -import java.util.Collections; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Map; -import java.util.Properties; -import java.util.Set; -import org.h2.Driver; -import org.h2.constant.ErrorCode; -import org.h2.engine.Constants; -import org.h2.message.DbException; -import org.h2.message.TraceSystem; -import org.h2.util.JdbcUtils; -import org.h2.util.NetUtils; -import org.h2.util.New; - -/** - * The TCP server implements the native H2 database server protocol. - * It supports multiple client connections to multiple databases - * (many to many). The same database may be opened by multiple clients. - * Also supported is the mixed mode: opening databases in embedded mode, - * and at the same time start a TCP server to allow clients to connect to - * the same database over the network. - */ -public class TcpServer implements Service { - - private static final int SHUTDOWN_NORMAL = 0; - private static final int SHUTDOWN_FORCE = 1; - - /** - * The name of the in-memory management database used by the TCP server - * to keep the active sessions. - */ - private static final String MANAGEMENT_DB_PREFIX = "management_db_"; - - private static final Map SERVERS = Collections.synchronizedMap(new HashMap()); - - private int port; - private boolean trace; - private boolean ssl; - private boolean stop; - private ServerSocket serverSocket; - private Set running = Collections.synchronizedSet(new HashSet()); - private String baseDir; - private boolean allowOthers; - private boolean isDaemon; - private boolean ifExists; - private Connection managementDb; - private PreparedStatement managementDbAdd; - private PreparedStatement managementDbRemove; - private String managementPassword = ""; - private Thread listenerThread; - private int nextThreadId; - private String key, keyDatabase; - - /** - * Get the database name of the management database. - * The management database contains a table with active sessions (SESSIONS). - * - * @param port the TCP server port - * @return the database name (usually starting with mem:) - */ - public static String getManagementDbName(int port) { - return "mem:" + MANAGEMENT_DB_PREFIX + port; - } - - private void initManagementDb() throws SQLException { - Properties prop = new Properties(); - prop.setProperty("user", "sa"); - prop.setProperty("password", managementPassword); - // avoid using the driver manager - Connection conn = Driver.load().connect("jdbc:h2:" + getManagementDbName(port), prop); - managementDb = conn; - Statement stat = null; - try { - stat = conn.createStatement(); - stat.execute("CREATE ALIAS IF NOT EXISTS STOP_SERVER FOR \"" + TcpServer.class.getName() + ".stopServer\""); - stat.execute("CREATE TABLE IF NOT EXISTS SESSIONS(ID INT PRIMARY KEY, URL VARCHAR, USER VARCHAR, CONNECTED TIMESTAMP)"); - managementDbAdd = conn.prepareStatement("INSERT INTO SESSIONS VALUES(?, ?, ?, NOW())"); - managementDbRemove = conn.prepareStatement("DELETE FROM SESSIONS WHERE ID=?"); - } finally { - JdbcUtils.closeSilently(stat); - } - SERVERS.put(port, this); - } - - /** - * Add a connection to the management database. - * - * @param id the connection id - * @param url the database URL - * @param user the user name - */ - synchronized void addConnection(int id, String url, String user) { - try { - managementDbAdd.setInt(1, id); - managementDbAdd.setString(2, url); - managementDbAdd.setString(3, user); - managementDbAdd.execute(); - } catch (SQLException e) { - TraceSystem.traceThrowable(e); - } - } - - /** - * Remove a connection from the management database. - * - * @param id the connection id - */ - synchronized void removeConnection(int id) { - try { - managementDbRemove.setInt(1, id); - managementDbRemove.execute(); - } catch (SQLException e) { - TraceSystem.traceThrowable(e); - } - } - - private synchronized void stopManagementDb() { - if (managementDb != null) { - try { - managementDb.close(); - } catch (SQLException e) { - TraceSystem.traceThrowable(e); - } - managementDb = null; - } - } - - public void init(String... args) { - port = Constants.DEFAULT_TCP_PORT; - for (int i = 0; args != null && i < args.length; i++) { - String a = args[i]; - if ("-trace".equals(a)) { - trace = true; - } else if ("-tcpSSL".equals(a)) { - ssl = true; - } else if ("-tcpPort".equals(a)) { - port = Integer.decode(args[++i]); - } else if ("-tcpPassword".equals(a)) { - managementPassword = args[++i]; - } else if ("-baseDir".equals(a)) { - baseDir = args[++i]; - } else if ("-key".equals(a)) { - key = args[++i]; - keyDatabase = args[++i]; - } else if ("-tcpAllowOthers".equals(a)) { - allowOthers = true; - } else if ("-tcpDaemon".equals(a)) { - isDaemon = true; - } else if ("-ifExists".equals(a)) { - ifExists = true; - } - } - org.h2.Driver.load(); - } - - public String getURL() { - return (ssl ? "ssl" : "tcp") + "://" + NetUtils.getLocalAddress() + ":" + port; - } - - public int getPort() { - return port; - } - - /** - * Check if this socket may connect to this server. Remote connections are - * not allowed if the flag allowOthers is set. - * - * @param socket the socket - * @return true if this client may connect - */ - boolean allow(Socket socket) { - if (allowOthers) { - return true; - } - try { - return NetUtils.isLocalAddress(socket); - } catch (UnknownHostException e) { - traceError(e); - return false; - } - } - - public synchronized void start() throws SQLException { - stop = false; - serverSocket = NetUtils.createServerSocket(port, ssl); - port = serverSocket.getLocalPort(); - initManagementDb(); - } - - public void listen() { - listenerThread = Thread.currentThread(); - String threadName = listenerThread.getName(); - try { - while (!stop) { - Socket s = serverSocket.accept(); - TcpServerThread c = new TcpServerThread(s, this, nextThreadId++); - running.add(c); - Thread thread = new Thread(c); - thread.setDaemon(isDaemon); - thread.setName(threadName + " thread"); - c.setThread(thread); - thread.start(); - } - serverSocket = NetUtils.closeSilently(serverSocket); - } catch (Exception e) { - if (!stop) { - TraceSystem.traceThrowable(e); - } - } - stopManagementDb(); - } - - public synchronized boolean isRunning(boolean traceError) { - if (serverSocket == null) { - return false; - } - try { - Socket s = NetUtils.createLoopbackSocket(port, ssl); - s.close(); - return true; - } catch (Exception e) { - if (traceError) { - traceError(e); - } - return false; - } - } - - public void stop() { - // TODO server: share code between web and tcp servers - // need to remove the server first, otherwise the connection is broken - // while the server is still registered in this map - SERVERS.remove(port); - if (!stop) { - stopManagementDb(); - stop = true; - if (serverSocket != null) { - try { - serverSocket.close(); - } catch (IOException e) { - TraceSystem.traceThrowable(e); - } catch (NullPointerException e) { - // ignore - } - serverSocket = null; - } - if (listenerThread != null) { - try { - listenerThread.join(1000); - } catch (InterruptedException e) { - TraceSystem.traceThrowable(e); - } - } - } - // TODO server: using a boolean 'now' argument? a timeout? - for (TcpServerThread c : New.arrayList(running)) { - if (c != null) { - c.close(); - try { - c.getThread().join(100); - } catch (Exception e) { - TraceSystem.traceThrowable(e); - } - } - } - } - - /** - * Stop a running server. This method is called via reflection from the - * STOP_SERVER function. - * - * @param port the port where the server runs, or 0 for all running servers - * @param password the password (or null) - * @param shutdownMode the shutdown mode, SHUTDOWN_NORMAL or SHUTDOWN_FORCE. - */ - public static void stopServer(int port, String password, int shutdownMode) { - if (port == 0) { - for (int p : SERVERS.keySet().toArray(new Integer[0])) { - if (p != 0) { - stopServer(p, password, shutdownMode); - } - } - return; - } - TcpServer server = SERVERS.get(port); - if (server == null) { - return; - } - if (!server.managementPassword.equals(password)) { - return; - } - if (shutdownMode == SHUTDOWN_NORMAL) { - server.stopManagementDb(); - server.stop = true; - try { - Socket s = NetUtils.createLoopbackSocket(port, false); - s.close(); - } catch (Exception e) { - // try to connect - so that accept returns - } - } else if (shutdownMode == SHUTDOWN_FORCE) { - server.stop(); - } - } - - /** - * Remove a thread from the list. - * - * @param t the thread to remove - */ - void remove(TcpServerThread t) { - running.remove(t); - } - - /** - * Get the configured base directory. - * - * @return the base directory - */ - String getBaseDir() { - return baseDir; - } - - /** - * Print a message if the trace flag is enabled. - * - * @param s the message - */ - void trace(String s) { - if (trace) { - System.out.println(s); - } - } - /** - * Print a stack trace if the trace flag is enabled. - * - * @param e the exception - */ - void traceError(Throwable e) { - if (trace) { - e.printStackTrace(); - } - } - - public boolean getAllowOthers() { - return allowOthers; - } - - public String getType() { - return "TCP"; - } - - public String getName() { - return "H2 TCP Server"; - } - - boolean getIfExists() { - return ifExists; - } - - /** - * Stop the TCP server with the given URL. - * - * @param url the database URL - * @param password the password - * @param force if the server should be stopped immediately - * @param all whether all TCP servers that are running in the JVM should be - * stopped - */ - public static synchronized void shutdown(String url, String password, boolean force, boolean all) throws SQLException { - try { - int port = Constants.DEFAULT_TCP_PORT; - int idx = url.indexOf(':', "jdbc:h2:".length()); - if (idx >= 0) { - String p = url.substring(idx + 1); - idx = p.indexOf('/'); - if (idx >= 0) { - p = p.substring(0, idx); - } - port = Integer.decode(p); - } - String db = getManagementDbName(port); - try { - org.h2.Driver.load(); - } catch (Throwable e) { - throw DbException.convert(e); - } - for (int i = 0; i < 2; i++) { - Connection conn = null; - PreparedStatement prep = null; - try { - conn = DriverManager.getConnection("jdbc:h2:" + url + "/" + db, "sa", password); - prep = conn.prepareStatement("CALL STOP_SERVER(?, ?, ?)"); - prep.setInt(1, all ? 0 : port); - prep.setString(2, password); - prep.setInt(3, force ? SHUTDOWN_FORCE : SHUTDOWN_NORMAL); - try { - prep.execute(); - } catch (SQLException e) { - if (force) { - // ignore - } else { - throw e; - } - } - break; - } catch (SQLException e) { - if (i == 1) { - throw e; - } - } finally { - JdbcUtils.closeSilently(prep); - JdbcUtils.closeSilently(conn); - } - } - } catch (Exception e) { - throw DbException.toSQLException(e); - } - } - - /** - * Cancel a running statement. - * - * @param sessionId the session id - * @param statementId the statement id - */ - void cancelStatement(String sessionId, int statementId) throws SQLException { - for (TcpServerThread c : New.arrayList(running)) { - if (c != null) { - c.cancelStatement(sessionId, statementId); - } - } - } - - /** - * If no key is set, return the original database name. If a key is set, - * check if the key matches. If yes, return the correct database name. If - * not, throw an exception. - * - * @param db the key to test (or database name if no key is used) - * @return the database name - * @throws SQLException if a key is set but doesn't match - */ - public String checkKeyAndGetDatabaseName(String db) throws SQLException { - if (key == null) { - return db; - } - if (key.equals(db)) { - return keyDatabase; - } - throw DbException.get(ErrorCode.WRONG_USER_OR_PASSWORD); - } - - public boolean isDaemon() { - return isDaemon; - } - -} diff --git a/tools/h2/src/main/org/h2/server/TcpServerThread.java b/tools/h2/src/main/org/h2/server/TcpServerThread.java deleted file mode 100755 index 3748a7a..0000000 --- a/tools/h2/src/main/org/h2/server/TcpServerThread.java +++ /dev/null @@ -1,403 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.server; - -import java.io.IOException; -import java.io.PrintWriter; -import java.io.StringWriter; -import java.net.Socket; -import java.sql.SQLException; -import java.util.ArrayList; -import org.h2.command.Command; -import org.h2.constant.ErrorCode; -import org.h2.constant.SysProperties; -import org.h2.engine.ConnectionInfo; -import org.h2.engine.Constants; -import org.h2.engine.Engine; -import org.h2.engine.Session; -import org.h2.engine.SessionRemote; -import org.h2.expression.Parameter; -import org.h2.expression.ParameterInterface; -import org.h2.expression.ParameterRemote; -import org.h2.jdbc.JdbcSQLException; -import org.h2.message.DbException; -import org.h2.result.ResultColumn; -import org.h2.result.ResultInterface; -import org.h2.util.SmallMap; -import org.h2.util.StringUtils; -import org.h2.value.Transfer; -import org.h2.value.Value; - -/** - * One server thread is opened per client connection. - */ -public class TcpServerThread implements Runnable { - private TcpServer server; - private Session session; - private boolean stop; - private Thread thread; - private Transfer transfer; - private Command commit; - private SmallMap cache = new SmallMap(SysProperties.SERVER_CACHED_OBJECTS); - private int threadId; - private int clientVersion; - private String sessionId; - - TcpServerThread(Socket socket, TcpServer server, int id) { - this.server = server; - this.threadId = id; - transfer = new Transfer(null); - transfer.setSocket(socket); - } - - private void trace(String s) { - server.trace(this + " " + s); - } - - public void run() { - try { - transfer.init(); - trace("Connect"); - // TODO server: should support a list of allowed databases - // and a list of allowed clients - try { - if (!server.allow(transfer.getSocket())) { - throw DbException.get(ErrorCode.REMOTE_CONNECTION_NOT_ALLOWED); - } - clientVersion = transfer.readInt(); - if (clientVersion < Constants.TCP_PROTOCOL_VERSION) { - throw DbException.get(ErrorCode.DRIVER_VERSION_ERROR_2, "" + clientVersion, "" + Constants.TCP_PROTOCOL_VERSION); - } - // max version (currently not used) - transfer.readInt(); - String db = transfer.readString(); - String originalURL = transfer.readString(); - if (db == null && originalURL == null) { - String targetSessionId = transfer.readString(); - int command = transfer.readInt(); - stop = true; - if (command == SessionRemote.SESSION_CANCEL_STATEMENT) { - // cancel a running statement - int statementId = transfer.readInt(); - server.cancelStatement(targetSessionId, statementId); - } else if (command == SessionRemote.SESSION_CHECK_KEY) { - // check if this is the correct server - db = server.checkKeyAndGetDatabaseName(targetSessionId); - if (!targetSessionId.equals(db)) { - transfer.writeInt(SessionRemote.STATUS_OK); - } else { - transfer.writeInt(SessionRemote.STATUS_ERROR); - } - } - } - String baseDir = server.getBaseDir(); - if (baseDir == null) { - baseDir = SysProperties.getBaseDir(); - } - db = server.checkKeyAndGetDatabaseName(db); - ConnectionInfo ci = new ConnectionInfo(db); - if (baseDir != null) { - ci.setBaseDir(baseDir); - } - if (server.getIfExists()) { - ci.setProperty("IFEXISTS", "TRUE"); - } - ci.setOriginalURL(originalURL); - ci.setUserName(transfer.readString()); - ci.setUserPasswordHash(transfer.readBytes()); - ci.setFilePasswordHash(transfer.readBytes()); - int len = transfer.readInt(); - for (int i = 0; i < len; i++) { - ci.setProperty(transfer.readString(), transfer.readString()); - } - Engine engine = Engine.getInstance(); - session = engine.getSession(ci); - transfer.setSession(session); - transfer.writeInt(SessionRemote.STATUS_OK); - if (clientVersion >= Constants.TCP_PROTOCOL_VERSION) { - // version 6: reply what version to use - transfer.writeInt(Constants.TCP_PROTOCOL_VERSION); - } - transfer.flush(); - server.addConnection(threadId, originalURL, ci.getUserName()); - trace("Connected"); - } catch (Throwable e) { - sendError(e); - stop = true; - } - while (!stop) { - try { - process(); - } catch (Throwable e) { - sendError(e); - } - } - trace("Disconnect"); - } catch (Throwable e) { - server.traceError(e); - } finally { - close(); - } - } - - private void closeSession() { - if (session != null) { - try { - Command rollback = session.prepareLocal("ROLLBACK"); - rollback.executeUpdate(); - } catch (Exception e) { - server.traceError(e); - } - try { - session.close(); - server.removeConnection(threadId); - } catch (Exception e) { - server.traceError(e); - } finally { - session = null; - } - } - } - - /** - * Close a connection. - */ - void close() { - try { - stop = true; - closeSession(); - transfer.close(); - trace("Close"); - } catch (Exception e) { - server.traceError(e); - } - server.remove(this); - } - - private void sendError(Throwable t) { - try { - SQLException e = DbException.convert(t).getSQLException(); - StringWriter writer = new StringWriter(); - e.printStackTrace(new PrintWriter(writer)); - String trace = writer.toString(); - String message; - String sql; - if (e instanceof JdbcSQLException) { - JdbcSQLException j = (JdbcSQLException) e; - message = j.getOriginalMessage(); - sql = j.getSQL(); - } else { - message = e.getMessage(); - sql = null; - } - transfer.writeInt(SessionRemote.STATUS_ERROR).writeString(e.getSQLState()).writeString(message) - .writeString(sql).writeInt(e.getErrorCode()).writeString(trace).flush(); - } catch (IOException e2) { - server.traceError(e2); - // if writing the error does not work, close the connection - stop = true; - } - } - - private void setParameters(Command command) throws IOException { - int len = transfer.readInt(); - ArrayList< ? extends ParameterInterface> params = command.getParameters(); - for (int i = 0; i < len; i++) { - Parameter p = (Parameter) params.get(i); - p.setValue(transfer.readValue()); - } - } - - private void process() throws IOException, SQLException { - int operation = transfer.readInt(); - switch (operation) { - case SessionRemote.SESSION_PREPARE_READ_PARAMS: - case SessionRemote.SESSION_PREPARE: { - int id = transfer.readInt(); - String sql = transfer.readString(); - int old = session.getModificationId(); - Command command = session.prepareLocal(sql); - boolean readonly = command.isReadOnly(); - cache.addObject(id, command); - boolean isQuery = command.isQuery(); - ArrayList< ? extends ParameterInterface> params = command.getParameters(); - transfer.writeInt(getState(old)).writeBoolean(isQuery).writeBoolean(readonly) - .writeInt(params.size()); - if (operation == SessionRemote.SESSION_PREPARE_READ_PARAMS) { - for (ParameterInterface p : params) { - ParameterRemote.writeMetaData(transfer, p); - } - } - transfer.flush(); - break; - } - case SessionRemote.SESSION_CLOSE: { - closeSession(); - transfer.writeInt(SessionRemote.STATUS_OK).flush(); - close(); - break; - } - case SessionRemote.COMMAND_COMMIT: { - if (commit == null) { - commit = session.prepareLocal("COMMIT"); - } - int old = session.getModificationId(); - commit.executeUpdate(); - transfer.writeInt(getState(old)).flush(); - break; - } - case SessionRemote.COMMAND_GET_META_DATA: { - int id = transfer.readInt(); - int objectId = transfer.readInt(); - Command command = (Command) cache.getObject(id, false); - ResultInterface result = command.getMetaData(); - cache.addObject(objectId, result); - int columnCount = result.getVisibleColumnCount(); - transfer.writeInt(SessionRemote.STATUS_OK).writeInt(columnCount).writeInt(0); - for (int i = 0; i < columnCount; i++) { - ResultColumn.writeColumn(transfer, result, i); - } - transfer.flush(); - break; - } - case SessionRemote.COMMAND_EXECUTE_QUERY: { - int id = transfer.readInt(); - int objectId = transfer.readInt(); - int maxRows = transfer.readInt(); - int fetchSize = transfer.readInt(); - Command command = (Command) cache.getObject(id, false); - setParameters(command); - int old = session.getModificationId(); - ResultInterface result = command.executeQuery(maxRows, false); - cache.addObject(objectId, result); - int columnCount = result.getVisibleColumnCount(); - int state = getState(old); - transfer.writeInt(state).writeInt(columnCount); - int rowCount = result.getRowCount(); - transfer.writeInt(rowCount); - for (int i = 0; i < columnCount; i++) { - ResultColumn.writeColumn(transfer, result, i); - } - int fetch = Math.min(rowCount, fetchSize); - for (int i = 0; i < fetch; i++) { - sendRow(result); - } - transfer.flush(); - break; - } - case SessionRemote.COMMAND_EXECUTE_UPDATE: { - int id = transfer.readInt(); - Command command = (Command) cache.getObject(id, false); - setParameters(command); - int old = session.getModificationId(); - int updateCount = command.executeUpdate(); - int status; - if (session.isClosed()) { - status = SessionRemote.STATUS_CLOSED; - } else { - status = getState(old); - } - transfer.writeInt(status).writeInt(updateCount).writeBoolean(session.getAutoCommit()); - transfer.flush(); - break; - } - case SessionRemote.COMMAND_CLOSE: { - int id = transfer.readInt(); - Command command = (Command) cache.getObject(id, true); - if (command != null) { - command.close(); - cache.freeObject(id); - } - break; - } - case SessionRemote.RESULT_FETCH_ROWS: { - int id = transfer.readInt(); - int count = transfer.readInt(); - ResultInterface result = (ResultInterface) cache.getObject(id, false); - transfer.writeInt(SessionRemote.STATUS_OK); - for (int i = 0; i < count; i++) { - sendRow(result); - } - transfer.flush(); - break; - } - case SessionRemote.RESULT_RESET: { - int id = transfer.readInt(); - ResultInterface result = (ResultInterface) cache.getObject(id, false); - result.reset(); - break; - } - case SessionRemote.RESULT_CLOSE: { - int id = transfer.readInt(); - ResultInterface result = (ResultInterface) cache.getObject(id, true); - if (result != null) { - result.close(); - cache.freeObject(id); - } - break; - } - case SessionRemote.CHANGE_ID: { - int oldId = transfer.readInt(); - int newId = transfer.readInt(); - Object obj = cache.getObject(oldId, false); - cache.freeObject(oldId); - cache.addObject(newId, obj); - break; - } - case SessionRemote.SESSION_SET_ID: { - sessionId = transfer.readString(); - transfer.writeInt(SessionRemote.STATUS_OK).flush(); - break; - } - default: - trace("Unknown operation: " + operation); - closeSession(); - close(); - } - } - - private int getState(int oldModificationId) { - if (session.getModificationId() == oldModificationId) { - return SessionRemote.STATUS_OK; - } - return SessionRemote.STATUS_OK_STATE_CHANGED; - } - - private void sendRow(ResultInterface result) throws IOException { - if (result.next()) { - transfer.writeBoolean(true); - Value[] v = result.currentRow(); - for (int i = 0; i < result.getVisibleColumnCount(); i++) { - transfer.writeValue(v[i]); - } - } else { - transfer.writeBoolean(false); - } - } - - void setThread(Thread thread) { - this.thread = thread; - } - - Thread getThread() { - return thread; - } - - /** - * Cancel a running statement. - * - * @param targetSessionId the session id - * @param statementId the statement to cancel - */ - void cancelStatement(String targetSessionId, int statementId) throws SQLException { - if (StringUtils.equals(targetSessionId, this.sessionId)) { - Command cmd = (Command) cache.getObject(statementId, false); - cmd.cancel(); - } - } - -} diff --git a/tools/h2/src/main/org/h2/server/package.html b/tools/h2/src/main/org/h2/server/package.html deleted file mode 100755 index e9f8090..0000000 --- a/tools/h2/src/main/org/h2/server/package.html +++ /dev/null @@ -1,15 +0,0 @@ - - - - -Javadoc package documentation -

- -A small FTP server. - -

\ No newline at end of file diff --git a/tools/h2/src/main/org/h2/server/pg/PgServer.java b/tools/h2/src/main/org/h2/server/pg/PgServer.java deleted file mode 100755 index 7bbca5b..0000000 --- a/tools/h2/src/main/org/h2/server/pg/PgServer.java +++ /dev/null @@ -1,461 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.server.pg; - -import java.io.IOException; -import java.net.ServerSocket; -import java.net.Socket; -import java.net.UnknownHostException; -import java.sql.Connection; -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.sql.Timestamp; -import java.sql.Types; -import java.util.Collections; -import java.util.HashSet; -import java.util.Set; -import org.h2.engine.Constants; -import org.h2.server.Service; -import org.h2.util.NetUtils; -import org.h2.util.New; - -/** - * This class implements a subset of the PostgreSQL protocol as described here: - * http://developer.postgresql.org/pgdocs/postgres/protocol.html - * The PostgreSQL catalog is described here: - * http://www.postgresql.org/docs/7.4/static/catalogs.html - * - * @author Thomas Mueller - * @author Sergi Vladykin 2009-07-03 (convertType) - */ -public class PgServer implements Service { - - /** - * The default port to use for the PG server. - * This value is also in the documentation and in the Server javadoc. - */ - public static final int DEFAULT_PORT = 5435; - - /** - * The VARCHAR type. - */ - public static final int PG_TYPE_VARCHAR = 1043; - - private static final int PG_TYPE_BOOL = 16; - private static final int PG_TYPE_BYTEA = 17; - private static final int PG_TYPE_BPCHAR = 1042; - private static final int PG_TYPE_INT8 = 20; - private static final int PG_TYPE_INT2 = 21; - private static final int PG_TYPE_INT4 = 23; - private static final int PG_TYPE_TEXT = 25; - private static final int PG_TYPE_OID = 26; - private static final int PG_TYPE_FLOAT4 = 700; - private static final int PG_TYPE_FLOAT8 = 701; - private static final int PG_TYPE_UNKNOWN = 705; - private static final int PG_TYPE_TEXTARRAY = 1009; - private static final int PG_TYPE_DATE = 1082; - private static final int PG_TYPE_TIME = 1083; - private static final int PG_TYPE_TIMESTAMP_NO_TMZONE = 1114; - private static final int PG_TYPE_NUMERIC = 1700; - - private HashSet typeSet = New.hashSet(); - - private int port = PgServer.DEFAULT_PORT; - private boolean stop; - private boolean trace; - private ServerSocket serverSocket; - private Set running = Collections.synchronizedSet(new HashSet()); - private String baseDir; - private boolean allowOthers; - private boolean isDaemon; - private boolean ifExists; - - public void init(String... args) { - port = DEFAULT_PORT; - for (int i = 0; args != null && i < args.length; i++) { - String a = args[i]; - if ("-trace".equals(a)) { - trace = true; - } else if ("-pgPort".equals(a)) { - port = Integer.decode(args[++i]); - } else if ("-baseDir".equals(a)) { - baseDir = args[++i]; - } else if ("-pgAllowOthers".equals(a)) { - allowOthers = true; - } else if ("-pgDaemon".equals(a)) { - isDaemon = true; - } else if ("-ifExists".equals(a)) { - ifExists = true; - } - } - org.h2.Driver.load(); - // int testing; - // trace = true; - } - - boolean getTrace() { - return trace; - } - - /** - * Print a message if the trace flag is enabled. - * - * @param s the message - */ - void trace(String s) { - if (trace) { - System.out.println(s); - } - } - - /** - * Remove a thread from the list. - * - * @param t the thread to remove - */ - synchronized void remove(PgServerThread t) { - running.remove(t); - } - - /** - * Print the stack trace if the trace flag is enabled. - * - * @param e the exception - */ - void traceError(Exception e) { - if (trace) { - e.printStackTrace(); - } - } - - public String getURL() { - return "pg://" + NetUtils.getLocalAddress() + ":" + port; - } - - public int getPort() { - return port; - } - - private boolean allow(Socket socket) { - if (allowOthers) { - return true; - } - try { - return NetUtils.isLocalAddress(socket); - } catch (UnknownHostException e) { - traceError(e); - return false; - } - } - - public void start() { - serverSocket = NetUtils.createServerSocket(port, false); - } - - public void listen() { - String threadName = Thread.currentThread().getName(); - try { - while (!stop) { - Socket s = serverSocket.accept(); - if (!allow(s)) { - trace("Connection not allowed"); - s.close(); - } else { - PgServerThread c = new PgServerThread(s, this); - running.add(c); - c.setProcessId(running.size()); - Thread thread = new Thread(c); - thread.setDaemon(isDaemon); - thread.setName(threadName+" thread"); - c.setThread(thread); - thread.start(); - } - } - } catch (Exception e) { - if (!stop) { - e.printStackTrace(); - } - } - } - - public void stop() { - // TODO server: combine with tcp server - if (!stop) { - stop = true; - if (serverSocket != null) { - try { - serverSocket.close(); - } catch (IOException e) { - // TODO log exception - e.printStackTrace(); - } - serverSocket = null; - } - } - // TODO server: using a boolean 'now' argument? a timeout? - for (PgServerThread c : New.arrayList(running)) { - c.close(); - try { - Thread t = c.getThread(); - if (t != null) { - t.join(100); - } - } catch (Exception e) { - // TODO log exception - e.printStackTrace(); - } - } - } - - public boolean isRunning(boolean traceError) { - if (serverSocket == null) { - return false; - } - try { - Socket s = NetUtils.createLoopbackSocket(serverSocket.getLocalPort(), false); - s.close(); - return true; - } catch (Exception e) { - if (traceError) { - traceError(e); - } - return false; - } - } - - String getBaseDir() { - return baseDir; - } - - public boolean getAllowOthers() { - return allowOthers; - } - - public String getType() { - return "PG"; - } - - public String getName() { - return "H2 PG Server"; - } - - boolean getIfExists() { - return ifExists; - } - - /** - * The Java implementation of the PostgreSQL function pg_get_indexdef. The - * method is used to get CREATE INDEX command for an index, or the column - * definition of one column in the index. - * - * @param conn the connection - * @param indexId the index id - * @param ordinalPosition the ordinal position (null if the SQL statement - * should be returned) - * @param pretty this flag is ignored - * @return the SQL statement or the column name - */ - public static String getIndexColumn(Connection conn, int indexId, Integer ordinalPosition, Boolean pretty) - throws SQLException { - if (ordinalPosition == null || ordinalPosition.intValue() == 0) { - PreparedStatement prep = conn.prepareStatement("select sql from information_schema.indexes where id=?"); - prep.setInt(1, indexId); - ResultSet rs = prep.executeQuery(); - if (rs.next()) { - return rs.getString(1); - } - return null; - } - PreparedStatement prep = conn.prepareStatement("select column_name from information_schema.indexes where id=? and ordinal_position=?"); - prep.setInt(1, indexId); - prep.setInt(2, ordinalPosition.intValue()); - ResultSet rs = prep.executeQuery(); - if (rs.next()) { - return rs.getString(1); - } - return null; - } - - /** - * Get the name of the current schema. - * This method is called by the database. - * - * @param conn the connection - * @return the schema name - */ - public static String getCurrentSchema(Connection conn) throws SQLException { - ResultSet rs = conn.createStatement().executeQuery("call schema()"); - rs.next(); - return rs.getString(1); - } - - /** - * Get the name of this encoding code. - * This method is called by the database. - * - * @param code the encoding code - * @return the encoding name - */ - public static String getEncodingName(int code) { - switch (code) { - case 0: - return "SQL_ASCII"; - case 6: - return "UTF8"; - case 8: - return "LATIN1"; - default: - return code < 40 ? "UTF8" : ""; - } - } - - /** - * Get the version. This method must return PostgreSQL to keep some clients - * happy. This method is called by the database. - * - * @return the server name and version - */ - public static String getVersion() { - return "PostgreSQL 8.1.4 server protocol using H2 " + Constants.getFullVersion(); - } - - /** - * Get the current system time. - * This method is called by the database. - * - * @return the current system time - */ - public static Timestamp getStartTime() { - return new Timestamp(System.currentTimeMillis()); - } - - /** - * Get the user name for this id. - * This method is called by the database. - * - * @param conn the connection - * @param id the user id - * @return the user name - */ - public static String getUserById(Connection conn, int id) throws SQLException { - PreparedStatement prep = conn.prepareStatement("SELECT NAME FROM INFORMATION_SCHEMA.USERS WHERE ID=?"); - prep.setInt(1, id); - ResultSet rs = prep.executeQuery(); - if (rs.next()) { - return rs.getString(1); - } - return null; - } - - /** - * Check if the this session has the given database privilege. - * This method is called by the database. - * - * @param id the session id - * @param privilege the privilege to check - * @return true - */ - public static boolean hasDatabasePrivilege(int id, String privilege) { - return true; - } - - /** - * Check if the current session has access to this table. - * This method is called by the database. - * - * @param table the table name - * @param privilege the privilege to check - * @return true - */ - public static boolean hasTablePrivilege(String table, String privilege) { - return true; - } - - /** - * Get the current transaction id. - * This method is called by the database. - * - * @param table the table name - * @param id the id - * @return 1 - */ - public static int getCurrentTid(String table, String id) { - return 1; - } - - /** - * Convert the SQL type to a PostgreSQL type - * - * @param type the SQL type - * @return the PostgreSQL type - */ - public static int convertType(final int type) { - switch (type) { - case Types.BOOLEAN: - return PG_TYPE_BOOL; - case Types.VARCHAR: - return PG_TYPE_VARCHAR; - case Types.CLOB: - return PG_TYPE_TEXT; - case Types.CHAR: - return PG_TYPE_BPCHAR; - case Types.SMALLINT: - return PG_TYPE_INT2; - case Types.INTEGER: - return PG_TYPE_INT4; - case Types.BIGINT: - return PG_TYPE_INT8; - case Types.DECIMAL: - return PG_TYPE_NUMERIC; - case Types.REAL: - return PG_TYPE_FLOAT4; - case Types.DOUBLE: - return PG_TYPE_FLOAT8; - case Types.TIME: - return PG_TYPE_TIME; - case Types.DATE: - return PG_TYPE_DATE; - case Types.TIMESTAMP: - return PG_TYPE_TIMESTAMP_NO_TMZONE; - case Types.VARBINARY: - return PG_TYPE_BYTEA; - case Types.BLOB: - return PG_TYPE_OID; - case Types.ARRAY: - return PG_TYPE_TEXTARRAY; - default: - return PG_TYPE_UNKNOWN; - } - } - - /** - * Get the type hash set. - * - * @return the type set - */ - HashSet getTypeSet() { - return typeSet; - } - - /** - * Check whether a data type is supported. - * A warning is logged if not. - * - * @param type the type - */ - void checkType(int type) { - if (!typeSet.contains(type)) { - trace("Unsupported type: " + type); - } - } - - public boolean isDaemon() { - return isDaemon; - } - -} diff --git a/tools/h2/src/main/org/h2/server/pg/PgServerThread.java b/tools/h2/src/main/org/h2/server/pg/PgServerThread.java deleted file mode 100755 index b88ff00..0000000 --- a/tools/h2/src/main/org/h2/server/pg/PgServerThread.java +++ /dev/null @@ -1,805 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.server.pg; - -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.DataInputStream; -import java.io.DataOutputStream; -import java.io.EOFException; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.io.OutputStream; -import java.io.Reader; -import java.io.StringReader; -import java.net.Socket; -import java.sql.Connection; -import java.sql.ParameterMetaData; -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.ResultSetMetaData; -import java.sql.SQLException; -import java.sql.Statement; -import java.util.HashMap; -import java.util.HashSet; -import org.h2.constant.SysProperties; -import org.h2.engine.ConnectionInfo; -import org.h2.jdbc.JdbcConnection; -import org.h2.message.DbException; -import org.h2.util.Utils; -import org.h2.util.IOUtils; -import org.h2.util.JdbcUtils; -import org.h2.util.New; -import org.h2.util.ScriptReader; - -/** - * One server thread is opened for each client. - */ -public class PgServerThread implements Runnable { - private PgServer server; - private Socket socket; - private Connection conn; - private boolean stop; - private DataInputStream dataInRaw; - private DataInputStream dataIn; - private OutputStream out; - private int messageType; - private ByteArrayOutputStream outBuffer; - private DataOutputStream dataOut; - private Thread thread; - private boolean initDone; - private String userName; - private String databaseName; - private int processId; - private String clientEncoding = SysProperties.PG_DEFAULT_CLIENT_ENCODING; - private String dateStyle = "ISO"; - private HashMap prepared = New.hashMap(); - private HashMap portals = New.hashMap(); - - PgServerThread(Socket socket, PgServer server) { - this.server = server; - this.socket = socket; - } - - public void run() { - try { - server.trace("Connect"); - InputStream ins = socket.getInputStream(); - out = socket.getOutputStream(); - dataInRaw = new DataInputStream(ins); - while (!stop) { - process(); - out.flush(); - } - } catch (EOFException e) { - // more or less normal disconnect - } catch (Exception e) { - server.traceError(e); - } finally { - server.trace("Disconnect"); - close(); - } - } - - private String readString() throws IOException { - ByteArrayOutputStream buff = new ByteArrayOutputStream(); - while (true) { - int x = dataIn.read(); - if (x <= 0) { - break; - } - buff.write(x); - } - return new String(buff.toByteArray(), getEncoding()); - } - - private int readInt() throws IOException { - return dataIn.readInt(); - } - - private int readShort() throws IOException { - return dataIn.readShort(); - } - - private byte readByte() throws IOException { - return dataIn.readByte(); - } - - private void readFully(byte[] buff) throws IOException { - dataIn.readFully(buff); - } - - private void process() throws IOException { - int x; - if (initDone) { - x = dataInRaw.read(); - if (x < 0) { - stop = true; - return; - } - } else { - x = 0; - } - int len = dataInRaw.readInt(); - len -= 4; - byte[] data = Utils.newBytes(len); - dataInRaw.readFully(data, 0, len); - dataIn = new DataInputStream(new ByteArrayInputStream(data, 0, len)); - switch (x) { - case 0: - server.trace("Init"); - int version = readInt(); - if (version == 80877102) { - server.trace("CancelRequest (not supported)"); - server.trace(" pid: " + readInt()); - server.trace(" key: " + readInt()); - } else if (version == 80877103) { - server.trace("SSLRequest"); - out.write('N'); - } else { - server.trace("StartupMessage"); - server.trace(" version " + version + " (" + (version >> 16) + "." + (version & 0xff) + ")"); - while (true) { - String param = readString(); - if (param.length() == 0) { - break; - } - String value = readString(); - if ("user".equals(param)) { - this.userName = value; - } else if ("database".equals(param)) { - this.databaseName = value; - } else if ("client_encoding".equals(param)) { - clientEncoding = value; - } else if ("DateStyle".equals(param)) { - dateStyle = value; - } - server.trace(" param " + param + "=" + value); - } - sendAuthenticationCleartextPassword(); - initDone = true; - } - break; - case 'p': { - server.trace("PasswordMessage"); - String password = readString(); - try { - ConnectionInfo ci = new ConnectionInfo(databaseName); - String baseDir = server.getBaseDir(); - if (baseDir == null) { - baseDir = SysProperties.getBaseDir(); - } - if (baseDir != null) { - ci.setBaseDir(baseDir); - } - if (server.getIfExists()) { - ci.setProperty("IFEXISTS", "TRUE"); - } - ci.setProperty("MODE", "PostgreSQL"); - ci.setOriginalURL("jdbc:h2:" + databaseName + ";MODE=PostgreSQL"); - ci.setUserName(userName); - ci.setProperty("PASSWORD", password); - ci.convertPasswords(); - conn = new JdbcConnection(ci, false); - // can not do this because when called inside - // DriverManager.getConnection, a deadlock occurs - // conn = DriverManager.getConnection(url, userName, password); - initDb(); - sendAuthenticationOk(); - } catch (Exception e) { - e.printStackTrace(); - stop = true; - } - break; - } - case 'P': { - server.trace("Parse"); - Prepared p = new Prepared(); - p.name = readString(); - p.sql = getSQL(readString()); - int count = readShort(); - p.paramType = new int[count]; - for (int i = 0; i < count; i++) { - int type = readInt(); - server.checkType(type); - p.paramType[i] = type; - } - try { - p.prep = conn.prepareStatement(p.sql); - prepared.put(p.name, p); - sendParseComplete(); - } catch (Exception e) { - sendErrorResponse(e); - } - break; - } - case 'B': { - server.trace("Bind"); - Portal portal = new Portal(); - portal.name = readString(); - String prepName = readString(); - Prepared prep = prepared.get(prepName); - if (prep == null) { - sendErrorResponse("Portal not found"); - break; - } - portal.sql = prep.sql; - portal.prep = prep.prep; - portals.put(portal.name, portal); - int formatCodeCount = readShort(); - int[] formatCodes = new int[formatCodeCount]; - for (int i = 0; i < formatCodeCount; i++) { - formatCodes[i] = readShort(); - } - int paramCount = readShort(); - for (int i = 0; i < paramCount; i++) { - int paramLen = readInt(); - byte[] d2 = Utils.newBytes(paramLen); - readFully(d2); - try { - setParameter(portal.prep, i, d2, formatCodes); - } catch (Exception e) { - sendErrorResponse(e); - } - } - int resultCodeCount = readShort(); - portal.resultColumnFormat = new int[resultCodeCount]; - for (int i = 0; i < resultCodeCount; i++) { - portal.resultColumnFormat[i] = readShort(); - } - sendBindComplete(); - break; - } - case 'D': { - char type = (char) readByte(); - String name = readString(); - server.trace("Describe"); - if (type == 'S') { - Prepared p = prepared.get(name); - if (p == null) { - sendErrorResponse("Prepared not found: " + name); - } else { - sendParameterDescription(p); - } - } else if (type == 'P') { - Portal p = portals.get(name); - if (p == null) { - sendErrorResponse("Portal not found: " + name); - } else { - PreparedStatement prep = p.prep; - try { - ResultSetMetaData meta = prep.getMetaData(); - sendRowDescription(meta); - } catch (Exception e) { - sendErrorResponse(e); - } - } - } else { - server.trace("expected S or P, got " + type); - sendErrorResponse("expected S or P"); - } - break; - } - case 'E': { - String name = readString(); - server.trace("Execute"); - Portal p = portals.get(name); - if (p == null) { - sendErrorResponse("Portal not found: " + name); - break; - } - int maxRows = readShort(); - PreparedStatement prep = p.prep; - server.trace(p.sql); - try { - prep.setMaxRows(maxRows); - boolean result = prep.execute(); - if (result) { - try { - ResultSet rs = prep.getResultSet(); - ResultSetMetaData meta = rs.getMetaData(); - sendRowDescription(meta); - while (rs.next()) { - sendDataRow(rs); - } - sendCommandComplete(p.sql, 0); - } catch (Exception e) { - sendErrorResponse(e); - } - } else { - sendCommandComplete(p.sql, prep.getUpdateCount()); - } - } catch (Exception e) { - sendErrorResponse(e); - } - break; - } - case 'S': { - server.trace("Sync"); - sendReadyForQuery(); - break; - } - case 'Q': { - server.trace("Query"); - String query = readString(); - ScriptReader reader = new ScriptReader(new StringReader(query)); - while (true) { - Statement stat = null; - try { - String s = reader.readStatement(); - if (s == null) { - break; - } - s = getSQL(s); - stat = conn.createStatement(); - boolean result = stat.execute(s); - if (result) { - ResultSet rs = stat.getResultSet(); - ResultSetMetaData meta = rs.getMetaData(); - sendRowDescription(meta); - while (rs.next()) { - sendDataRow(rs); - } - sendCommandComplete(s, 0); - } else { - sendCommandComplete(s, stat.getUpdateCount()); - } - } catch (SQLException e) { - sendErrorResponse(e); - } finally { - JdbcUtils.closeSilently(stat); - } - } - sendReadyForQuery(); - break; - } - case 'X': { - server.trace("Terminate"); - close(); - break; - } - default: - server.trace("Unsupported: " + x + " (" + (char) x + ")"); - break; - } - } - - private String getSQL(String s) { - String lower = s.toLowerCase(); - if (lower.startsWith("show max_identifier_length")) { - s = "CALL 63"; - } else if (lower.startsWith("set client_encoding to")) { - s = "set DATESTYLE ISO"; - } - // s = StringUtils.replaceAll(s, "i.indkey[ia.attnum-1]", "0"); - if (server.getTrace()) { - server.trace(s + ";"); - } - return s; - } - - private void sendCommandComplete(String sql, int updateCount) throws IOException { - startMessage('C'); - sql = sql.trim().toUpperCase(); - // TODO remove remarks at the beginning - String tag; - if (sql.startsWith("INSERT")) { - tag = "INSERT 0 " + updateCount; - } else if (sql.startsWith("DELETE")) { - tag = "DELETE " + updateCount; - } else if (sql.startsWith("UPDATE")) { - tag = "UPDATE " + updateCount; - } else if (sql.startsWith("SELECT") || sql.startsWith("CALL")) { - tag = "SELECT"; - } else if (sql.startsWith("BEGIN")) { - tag = "BEGIN"; - } else { - server.trace("Check command tag: " + sql); - tag = "UPDATE " + updateCount; - } - writeString(tag); - sendMessage(); - } - - private void sendDataRow(ResultSet rs) throws IOException { - try { - int columns = rs.getMetaData().getColumnCount(); - String[] values = new String[columns]; - for (int i = 0; i < columns; i++) { - values[i] = rs.getString(i + 1); - } - startMessage('D'); - writeShort(columns); - for (String s : values) { - if (s == null) { - writeInt(-1); - } else { - // TODO write Binary data - byte[] d2 = s.getBytes(getEncoding()); - writeInt(d2.length); - write(d2); - } - } - sendMessage(); - } catch (Exception e) { - sendErrorResponse(e); - } - } - - private String getEncoding() { - if ("UNICODE".equals(clientEncoding)) { - return "UTF-8"; - } - return clientEncoding; - } - - private void setParameter(PreparedStatement prep, int i, byte[] d2, int[] formatCodes) throws SQLException { - boolean text = (i >= formatCodes.length) || (formatCodes[i] == 0); - String s; - try { - if (text) { - s = new String(d2, getEncoding()); - } else { - server.trace("Binary format not supported"); - s = new String(d2, getEncoding()); - } - } catch (Exception e) { - server.traceError(e); - s = null; - } - // if(server.getLog()) { - // server.log(" " + i + ": " + s); - // } - prep.setString(i + 1, s); - } - - private void sendErrorResponse(Exception re) throws IOException { - SQLException e = DbException.toSQLException(re); - server.traceError(e); - startMessage('E'); - write('S'); - writeString("ERROR"); - write('C'); - writeString(e.getSQLState()); - write('M'); - writeString(e.getMessage()); - write('D'); - writeString(e.toString()); - write(0); - sendMessage(); - } - - private void sendParameterDescription(Prepared p) throws IOException { - try { - PreparedStatement prep = p.prep; - ParameterMetaData meta = prep.getParameterMetaData(); - int count = meta.getParameterCount(); - startMessage('t'); - writeShort(count); - for (int i = 0; i < count; i++) { - int type; - if (p.paramType != null && p.paramType[i] != 0) { - type = p.paramType[i]; - } else { - type = PgServer.PG_TYPE_VARCHAR; - } - server.checkType(type); - writeInt(type); - } - sendMessage(); - } catch (Exception e) { - sendErrorResponse(e); - } - } - - private void sendNoData() throws IOException { - startMessage('n'); - sendMessage(); - } - - private void sendRowDescription(ResultSetMetaData meta) throws IOException { - try { - if (meta == null) { - sendNoData(); - } else { - int columns = meta.getColumnCount(); - int[] types = new int[columns]; - int[] precision = new int[columns]; - String[] names = new String[columns]; - for (int i = 0; i < columns; i++) { - names[i] = meta.getColumnName(i + 1); - int type = meta.getColumnType(i + 1); - type = PgServer.convertType(type); - precision[i] = meta.getColumnDisplaySize(i + 1); - server.checkType(type); - types[i] = type; - } - startMessage('T'); - writeShort(columns); - for (int i = 0; i < columns; i++) { - writeString(names[i].toLowerCase()); - // object ID - writeInt(0); - // attribute number of the column - writeShort(0); - // data type - writeInt(types[i]); - // pg_type.typlen - writeShort(getTypeSize(types[i], precision[i])); - // pg_attribute.atttypmod - writeInt(-1); - // text - writeShort(0); - } - sendMessage(); - } - } catch (Exception e) { - sendErrorResponse(e); - } - } - - private int getTypeSize(int pgType, int precision) { - switch (pgType) { - case PgServer.PG_TYPE_VARCHAR: - return Math.max(255, precision + 10); - default: - return precision + 4; - } - } - - private void sendErrorResponse(String message) throws IOException { - server.trace("Exception: " + message); - startMessage('E'); - write('S'); - writeString("ERROR"); - write('C'); - // PROTOCOL VIOLATION - writeString("08P01"); - write('M'); - writeString(message); - sendMessage(); - } - - private void sendParseComplete() throws IOException { - startMessage('1'); - sendMessage(); - } - - private void sendBindComplete() throws IOException { - startMessage('2'); - sendMessage(); - } - - private void initDb() throws SQLException { - Statement stat = null; - ResultSet rs = null; - Reader r = null; - try { - synchronized (server) { - // better would be: set the database to exclusive mode - rs = conn.getMetaData().getTables(null, "PG_CATALOG", "PG_VERSION", null); - boolean tableFound = rs.next(); - stat = conn.createStatement(); - if (!tableFound) { - try { - r = new InputStreamReader(new ByteArrayInputStream(Utils - .getResource("/org/h2/server/pg/pg_catalog.sql"))); - } catch (IOException e) { - throw DbException.convertIOException(e, "Can not read pg_catalog resource"); - } - ScriptReader reader = new ScriptReader(r); - while (true) { - String sql = reader.readStatement(); - if (sql == null) { - break; - } - stat.execute(sql); - } - reader.close(); - } - } - - rs = stat.executeQuery("SELECT VERSION FROM PG_CATALOG.PG_VERSION"); - if (!rs.next() || rs.getInt(1) != 1) { - throw DbException.throwInternalError("Invalid PG_VERSION"); - } - stat.execute("set search_path = PUBLIC, pg_catalog"); - - HashSet typeSet = server.getTypeSet(); - if (typeSet.size() == 0) { - rs = stat.executeQuery("SELECT OID FROM PG_CATALOG.PG_TYPE"); - while (rs.next()) { - typeSet.add(rs.getInt(1)); - } - } - } finally { - JdbcUtils.closeSilently(stat); - JdbcUtils.closeSilently(rs); - IOUtils.closeSilently(r); - } - } - - /** - * Close this connection. - */ - void close() { - try { - stop = true; - JdbcUtils.closeSilently(conn); - if (socket != null) { - socket.close(); - } - server.trace("Close"); - } catch (Exception e) { - server.traceError(e); - } - conn = null; - socket = null; - server.remove(this); - } - - private void sendAuthenticationCleartextPassword() throws IOException { - startMessage('R'); - writeInt(3); - sendMessage(); - } - - private void sendAuthenticationOk() throws IOException { - startMessage('R'); - writeInt(0); - sendMessage(); - sendParameterStatus("client_encoding", clientEncoding); - sendParameterStatus("DateStyle", dateStyle); - sendParameterStatus("integer_datetimes", "off"); - sendParameterStatus("is_superuser", "off"); - sendParameterStatus("server_encoding", "SQL_ASCII"); - sendParameterStatus("server_version", "8.1.4"); - sendParameterStatus("session_authorization", userName); - sendParameterStatus("standard_conforming_strings", "off"); - // TODO PostgreSQL TimeZone - sendParameterStatus("TimeZone", "CET"); - sendBackendKeyData(); - sendReadyForQuery(); - } - - private void sendReadyForQuery() throws IOException { - startMessage('Z'); - char c; - try { - if (conn.getAutoCommit()) { - // idle - c = 'I'; - } else { - // in a transaction block - c = 'T'; - } - } catch (SQLException e) { - // failed transaction block - c = 'E'; - } - write((byte) c); - sendMessage(); - } - - private void sendBackendKeyData() throws IOException { - startMessage('K'); - writeInt(processId); - writeInt(processId); - sendMessage(); - } - - private void writeString(String s) throws IOException { - write(s.getBytes(getEncoding())); - write(0); - } - - private void writeInt(int i) throws IOException { - dataOut.writeInt(i); - } - - private void writeShort(int i) throws IOException { - dataOut.writeShort(i); - } - - private void write(byte[] data) throws IOException { - dataOut.write(data); - } - - private void write(int b) throws IOException { - dataOut.write(b); - } - - private void startMessage(int newMessageType) { - this.messageType = newMessageType; - outBuffer = new ByteArrayOutputStream(); - dataOut = new DataOutputStream(outBuffer); - } - - private void sendMessage() throws IOException { - dataOut.flush(); - byte[] buff = outBuffer.toByteArray(); - int len = buff.length; - dataOut = new DataOutputStream(out); - dataOut.write(messageType); - dataOut.writeInt(len + 4); - dataOut.write(buff); - dataOut.flush(); - } - - private void sendParameterStatus(String param, String value) throws IOException { - startMessage('S'); - writeString(param); - writeString(value); - sendMessage(); - } - - void setThread(Thread thread) { - this.thread = thread; - } - - Thread getThread() { - return thread; - } - - void setProcessId(int id) { - this.processId = id; - } - - /** - * Represents a PostgreSQL Prepared object. - */ - static class Prepared { - - /** - * The object name. - */ - String name; - - /** - * The SQL statement. - */ - String sql; - - /** - * The prepared statement. - */ - PreparedStatement prep; - - /** - * The list of parameter types (if set). - */ - int[] paramType; - } - - /** - * Represents a PostgreSQL Portal object. - */ - static class Portal { - - /** - * The portal name. - */ - String name; - - /** - * The SQL statement. - */ - String sql; - - /** - * The format used in the result set columns (if set). - */ - int[] resultColumnFormat; - - /** - * The prepared statement. - */ - PreparedStatement prep; - } - -} diff --git a/tools/h2/src/main/org/h2/server/pg/package.html b/tools/h2/src/main/org/h2/server/pg/package.html deleted file mode 100755 index eace3d7..0000000 --- a/tools/h2/src/main/org/h2/server/pg/package.html +++ /dev/null @@ -1,15 +0,0 @@ - - - - -Javadoc package documentation -

- -PostgreSQL server implementation of this database. - -

\ No newline at end of file diff --git a/tools/h2/src/main/org/h2/server/pg/pg_catalog.sql b/tools/h2/src/main/org/h2/server/pg/pg_catalog.sql deleted file mode 100755 index 7fc80b0..0000000 --- a/tools/h2/src/main/org/h2/server/pg/pg_catalog.sql +++ /dev/null @@ -1,298 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -; -drop schema if exists pg_catalog; -create schema pg_catalog; - -drop alias if exists pg_convertType; -create alias pg_convertType deterministic for "org.h2.server.pg.PgServer.convertType"; - -create table pg_catalog.pg_version as select 1 as version; - -create view pg_catalog.pg_roles -- (oid, rolname, rolcreaterole, rolcreatedb) -as -select - id oid, - cast(name as varchar_ignorecase) rolname, - case when admin then 't' else 'f' end as rolcreaterole, - case when admin then 't' else 'f' end as rolcreatedb -from information_schema.users; - -create view pg_catalog.pg_namespace -- (oid, nspname) -as -select - id oid, - cast(schema_name as varchar_ignorecase) nspname -from information_schema.schemata; - -create table pg_catalog.pg_type( - oid int primary key, - typname varchar_ignorecase, - typnamespace int, - typlen int, - typtype varchar, - typbasetype int, - typtypmod int); - -insert into pg_catalog.pg_type -select - pg_convertType(data_type) oid, - cast(type_name as varchar_ignorecase) typname, - (select oid from pg_catalog.pg_namespace where nspname = 'pg_catalog') typnamespace, - -1 typlen, - 'c' typtype, - 0 typbasetype, - -1 typtypmod -from information_schema.type_info -where pos = 0 - and pg_convertType(data_type) <> 705; -- not unknown - -merge into pg_catalog.pg_type values( - 19, - 'name', - (select oid from pg_catalog.pg_namespace where nspname = 'pg_catalog'), - -1, - 'c', - 0, - -1 -); -merge into pg_catalog.pg_type values( - 0, - 'null', - (select oid from pg_catalog.pg_namespace where nspname = 'pg_catalog'), - -1, - 'c', - 0, - -1 -); - -create view pg_catalog.pg_class -- (oid, relname, relnamespace, relkind, relam, reltuples, relpages, relhasrules, relhasoids) -as -select - id oid, - cast(table_name as varchar_ignorecase) relname, - (select id from information_schema.schemata where schema_name = table_schema) relnamespace, - case table_type when 'TABLE' then 'r' else 'v' end relkind, - 0 relam, - cast(0 as float) reltuples, - 0 relpages, - false relhasrules, - false relhasoids -from information_schema.tables -union all -select - id oid, - cast(index_name as varchar_ignorecase) relname, - (select id from information_schema.schemata where schema_name = table_schema) relnamespace, - 'i' relkind, - 0 relam, - cast(0 as float) reltuples, - 0 relpages, - false relhasrules, - false relhasoids -from information_schema.indexes; - -create table pg_catalog.pg_proc( - oid int, - proname varchar_ignorecase, - prorettype int, - pronamespace int -); - -create table pg_catalog.pg_trigger( - oid int, - tgconstrrelid int, - tgfoid int, - tgargs int, - tgnargs int, - tgdeferrable boolean, - tginitdeferred boolean, - tgconstrname varchar_ignorecase, - tgrelid int -); - -create view pg_catalog.pg_attrdef -- (oid, adsrc, adrelid, adnum) -as -select - id oid, - 0 adsrc, - 0 adrelid, - 0 adnum -from information_schema.tables where 1=0; - -create view pg_catalog.pg_attribute -- (oid, attrelid, attname, atttypid, attlen, attnum, atttypmod, attnotnull, attisdropped, atthasdef) -as -select - t.id*10000 + c.ordinal_position oid, - t.id attrelid, - c.column_name attname, - pg_convertType(data_type) atttypid, - -1 attlen, - c.ordinal_position attnum, - -1 atttypmod, - false attnotnull, - false attisdropped, - false atthasdef -from information_schema.tables t, information_schema.columns c -where t.table_name = c.table_name -and t.table_schema = c.table_schema -union all -select - 1000000 + t.id*10000 + c.ordinal_position oid, - i.id attrelid, - c.column_name attname, - pg_convertType(data_type) atttypid, - -1 attlen, - c.ordinal_position attnum, - -1 atttypmod, - false attnotnull, - false attisdropped, - false atthasdef -from information_schema.tables t, information_schema.indexes i, information_schema.columns c -where t.table_name = i.table_name -and t.table_schema = i.table_schema -and t.table_name = c.table_name -and t.table_schema = c.table_schema; - -create view pg_catalog.pg_index -- (oid, indexrelid, indrelid, indisclustered, indisunique, indisprimary, indexprs, indkey) -as -select - i.id oid, - i.id indexrelid, - t.id indrelid, - false indisclustered, - not non_unique indisunique, - primary_key indisprimary, - cast('' as varchar_ignorecase) indexprs, - cast(0 as array) indkey -from information_schema.indexes i, information_schema.tables t -where i.table_schema = t.table_schema -and i.table_name = t.table_name -and i.ordinal_position = 1; - -drop alias if exists pg_get_indexdef; -create alias pg_get_indexdef for "org.h2.server.pg.PgServer.getIndexColumn"; - -drop alias if exists version; -create alias version for "org.h2.server.pg.PgServer.getVersion"; - -drop alias if exists current_schema; -create alias current_schema for "org.h2.server.pg.PgServer.getCurrentSchema"; - -drop alias if exists pg_encoding_to_char; -create alias pg_encoding_to_char for "org.h2.server.pg.PgServer.getEncodingName"; - -drop alias if exists pg_postmaster_start_time; -create alias pg_postmaster_start_time for "org.h2.server.pg.PgServer.getStartTime"; - -drop alias if exists pg_get_userbyid; -create alias pg_get_userbyid for "org.h2.server.pg.PgServer.getUserById"; - -drop alias if exists has_database_privilege; -create alias has_database_privilege for "org.h2.server.pg.PgServer.hasDatabasePrivilege"; - -drop alias if exists has_table_privilege; -create alias has_table_privilege for "org.h2.server.pg.PgServer.hasTablePrivilege"; - -drop alias if exists currtid2; -create alias currtid2 for "org.h2.server.pg.PgServer.getCurrentTid"; - -create table pg_catalog.pg_database( - oid int, - datname varchar_ignorecase, - encoding int, - datlastsysoid int, - datallowconn boolean, - datconfig array, -- text[] - datacl array, -- aclitem[] - datdba int, - dattablespace int -); - -insert into pg_catalog.pg_database values( - 0, -- oid - 'postgres', -- datname - 6, -- encoding, UTF8 - 100000, -- datlastsysoid - true, -- datallowconn - null, -- datconfig - null, -- datacl - select min(id) from information_schema.users where admin=true, -- datdba - 0 -- dattablespace -); - -create table pg_catalog.pg_tablespace( - oid int, - spcname varchar_ignorecase, - spclocation varchar_ignorecase, - spcowner int, - spcacl array -- aclitem[] -); - -insert into pg_catalog.pg_tablespace values( - 0, - 'main', -- spcname - '?', -- spclocation - 0, -- spcowner, - null -- spcacl -); - -create table pg_catalog.pg_settings( - oid int, - name varchar_ignorecase, - setting varchar_ignorecase -); - -insert into pg_catalog.pg_settings values -(0, 'autovacuum', 'on'), -(1, 'stats_start_collector', 'on'), -(2, 'stats_row_level', 'on'); - -create view pg_catalog.pg_user -- oid, usename, usecreatedb, usesuper -as -select - id oid, - cast(name as varchar_ignorecase) usename, - true usecreatedb, - true usesuper -from information_schema.users; - -create table pg_catalog.pg_authid( - oid int, - rolname varchar_ignorecase, - rolsuper boolean, - rolinherit boolean, - rolcreaterole boolean, - rolcreatedb boolean, - rolcatupdate boolean, - rolcanlogin boolean, - rolconnlimit boolean, - rolpassword boolean, - rolvaliduntil timestamp, -- timestamptz - rolconfig array -- text[] -); - -create table pg_catalog.pg_am(oid int, amname varchar_ignorecase); -insert into pg_catalog.pg_am values(0, 'btree'); -insert into pg_catalog.pg_am values(1, 'hash'); - -create table pg_catalog.pg_description -- (objoid, objsubid, classoid, description) -as -select - oid objoid, - 0 objsubid, - -1 classoid, - cast(datname as varchar_ignorecase) description -from pg_catalog.pg_database; - -create table pg_catalog.pg_group -- oid, groname -as -select - 0 oid, - cast('' as varchar_ignorecase) groname -from pg_catalog.pg_database where 1=0; - diff --git a/tools/h2/src/main/org/h2/server/web/ConnectionInfo.java b/tools/h2/src/main/org/h2/server/web/ConnectionInfo.java deleted file mode 100755 index 460f442..0000000 --- a/tools/h2/src/main/org/h2/server/web/ConnectionInfo.java +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.server.web; - -import org.h2.util.MathUtils; -import org.h2.util.StringUtils; - -/** - * The connection info object is a wrapper for database connection information - * such as the database URL, user name and password. - * This class is used by the H2 Console. - */ -public class ConnectionInfo implements Comparable { - /** - * The driver class name. - */ - public String driver; - - /** - * The database URL. - */ - public String url; - - /** - * The user name. - */ - public String user; - - /** - * The connection display name. - */ - String name; - - /** - * The last time this connection was used. - */ - int lastAccess; - - ConnectionInfo() { - // nothing to do - } - - public ConnectionInfo(String data) { - String[] array = StringUtils.arraySplit(data, '|', false); - name = get(array, 0); - driver = get(array, 1); - url = get(array, 2); - user = get(array, 3); - } - - private String get(String[] array, int i) { - return array != null && array.length > i ? array[i] : ""; - } - - String getString() { - return StringUtils.arrayCombine(new String[] { name, driver, url, user }, '|'); - } - - public int compareTo(ConnectionInfo o) { - return -MathUtils.compareInt(lastAccess, o.lastAccess); - } - -} diff --git a/tools/h2/src/main/org/h2/server/web/DbColumn.java b/tools/h2/src/main/org/h2/server/web/DbColumn.java deleted file mode 100755 index 3c1c1ce..0000000 --- a/tools/h2/src/main/org/h2/server/web/DbColumn.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.server.web; - -import java.sql.DatabaseMetaData; -import java.sql.ResultSet; -import java.sql.SQLException; - -/** - * Keeps the meta data information of a column. - * This class is used by the H2 Console. - */ -class DbColumn { - - /** - * The column name. - */ - String name; - - /** - * The data type name (including precision and the NOT NULL flag if - * applicable). - */ - String dataType; - - DbColumn(ResultSet rs) throws SQLException { - name = rs.getString("COLUMN_NAME"); - String type = rs.getString("TYPE_NAME"); - int size = rs.getInt(DbContents.findColumn(rs, "COLUMN_SIZE", 7)); - if (size > 0) { - type += "(" + size; - int prec = rs.getInt(DbContents.findColumn(rs, "DECIMAL_DIGITS", 9)); - if (prec > 0) { - type += ", " + prec; - } - type += ")"; - } - if (rs.getInt("NULLABLE") == DatabaseMetaData.columnNoNulls) { - type += " NOT NULL"; - } - dataType = type; - } -} diff --git a/tools/h2/src/main/org/h2/server/web/DbContents.java b/tools/h2/src/main/org/h2/server/web/DbContents.java deleted file mode 100755 index 2ef90d6..0000000 --- a/tools/h2/src/main/org/h2/server/web/DbContents.java +++ /dev/null @@ -1,258 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.server.web; - -import java.sql.DatabaseMetaData; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.sql.Statement; -import java.util.ArrayList; - -import org.h2.command.Parser; -import org.h2.util.New; -import org.h2.util.StringUtils; - -/** - * Keeps meta data information about a database. - * This class is used by the H2 Console. - */ -public class DbContents { - - /** - * The list of schemas. - */ - DbSchema[] schemas; - - /** - * The default schema. - */ - DbSchema defaultSchema; - - /** - * True if this is an Oracle database. - */ - boolean isOracle; - - /** - * True if this is a H2 database. - */ - boolean isH2; - - /** - * True if this is a H2 database in MySQL mode. - */ - boolean isH2ModeMySQL; - - /** - * True if this is a PostgreSQL database. - */ - boolean isPostgreSQL; - - /** - * True if this is a MySQL database. - */ - boolean isMySQL; - - /** - * True if this is an Apache Derby database. - */ - boolean isDerby; - - /** - * True if this is a Firebird database. - */ - boolean isFirebird; - - /** - * True if this is an SQLite database. - */ - boolean isSQLite; - - /** - * True if the unquoted names are stored as upper case. - * False for MySQL and PostgreSQL. - */ - boolean storedUpperCaseIdentifiers; - - /** - * Get the column index of a column in a result set. If the column is not - * found, the default column index is returned. - * This is a workaround for a JDBC-ODBC bridge problem. - * - * @param rs the result set - * @param columnName the column name - * @param defaultColumnIndex the default column index - * @return the column index - */ - static int findColumn(ResultSet rs, String columnName, int defaultColumnIndex) { - try { - return rs.findColumn(columnName); - } catch (SQLException e) { - return defaultColumnIndex; - } - } - - /** - * Read the contents of this database from the database meta data. - * - * @param meta the database meta data - */ - void readContents(DatabaseMetaData meta) throws SQLException { - String prod = StringUtils.toLowerEnglish(meta.getDatabaseProductName()); - isSQLite = prod.indexOf("sqlite") >= 0; - String url = meta.getURL(); - if (url != null) { - isH2 = url.startsWith("jdbc:h2:"); - if (isH2) { - Statement stat = meta.getConnection().createStatement(); - ResultSet rs = stat.executeQuery( - "SELECT UPPER(VALUE) FROM INFORMATION_SCHEMA.SETTINGS WHERE NAME='MODE'"); - rs.next(); - if ("MYSQL".equals(rs.getString(1))) { - isH2ModeMySQL = true; - } - rs.close(); - stat.close(); - } - isOracle = url.startsWith("jdbc:oracle:"); - isPostgreSQL = url.startsWith("jdbc:postgresql:"); - // isHSQLDB = url.startsWith("jdbc:hsqldb:"); - isMySQL = url.startsWith("jdbc:mysql:"); - isDerby = url.startsWith("jdbc:derby:"); - isFirebird = url.startsWith("jdbc:firebirdsql:"); - } - storedUpperCaseIdentifiers = meta.storesUpperCaseIdentifiers(); - String defaultSchemaName = getDefaultSchemaName(meta); - String[] schemaNames = getSchemaNames(meta); - schemas = new DbSchema[schemaNames.length]; - for (int i = 0; i < schemaNames.length; i++) { - String schemaName = schemaNames[i]; - boolean isDefault = defaultSchemaName == null || defaultSchemaName.equals(schemaName); - DbSchema schema = new DbSchema(this, schemaName, isDefault); - if (schema.isDefault) { - defaultSchema = schema; - } - schemas[i] = schema; - String[] tableTypes = { "TABLE", "SYSTEM TABLE", "VIEW", "SYSTEM VIEW", - "TABLE LINK", "SYNONYM" }; - schema.readTables(meta, tableTypes); - } - if (defaultSchema == null) { - String best = null; - for (DbSchema schema : schemas) { - if ("dbo".equals(schema.name)) { - // MS SQL Server - defaultSchema = schema; - break; - } - if (defaultSchema == null || best == null || schema.name.length() < best.length()) { - best = schema.name; - defaultSchema = schema; - } - } - } - } - - private String[] getSchemaNames(DatabaseMetaData meta) throws SQLException { - if (isMySQL) { - return new String[] { "" }; - } else if (isFirebird) { - return new String[] { null }; - } - ResultSet rs = meta.getSchemas(); - ArrayList schemaList = New.arrayList(); - while (rs.next()) { - String schema = rs.getString(findColumn(rs, "TABLE_SCHEM", 1)); - if (isOracle) { - for (String ignore : new String[] { - "CTXSYS", "DIP", "DBSNMP", "DMSYS", "EXFSYS", "MDDATA", "MDSYS", - "MGMT_VIEW", "OLAPSYS", "ORDSYS", "ORDPLUGINS", "OUTLN", "SI_INFORMTN_SCHEMA", "SYS", "SYSMAN", - "SYSTEM", "TSMSYS", "WMSYS", "XDB" - }) { - if (ignore.equals(schema)) { - schema = null; - break; - } - } - } - if (schema == null) { - continue; - } - schemaList.add(schema); - } - rs.close(); - String[] list = new String[schemaList.size()]; - schemaList.toArray(list); - return list; - } - - private String getDefaultSchemaName(DatabaseMetaData meta) { - String defaultSchemaName = ""; - try { - if (isOracle) { - return meta.getUserName(); - } else if (isPostgreSQL) { - return "public"; - } else if (isMySQL) { - return ""; - } else if (isDerby) { - return StringUtils.toUpperEnglish(meta.getUserName()); - } else if (isFirebird) { - return null; - } - ResultSet rs = meta.getSchemas(); - int index = rs.findColumn("IS_DEFAULT"); - while (rs.next()) { - if (rs.getBoolean(index)) { - defaultSchemaName = rs.getString("TABLE_SCHEM"); - } - } - } catch (SQLException e) { - // IS_DEFAULT not found - } - return defaultSchemaName; - } - - /** - * Add double quotes around an identifier if required. - * For the H2 database, all identifiers are quoted. - * - * @param identifier the identifier - * @return the quoted identifier - */ - String quoteIdentifier(String identifier) { - if (identifier == null) { - return null; - } - if (isH2 && !isH2ModeMySQL) { - return Parser.quoteIdentifier(identifier); - } - return StringUtils.toUpperEnglish(identifier); - } - - /** - * Check whether an identifier from the database meta data needs to be - * quoted. This depends on how the database stores the identifiers ("test" - * doesn't need to be quoted if the database stores identifiers lowercase) - * - * @param identifier the identifier - * @return true if the identifier needs to be quoted - */ - boolean needsQuotes(String identifier) { - if (storedUpperCaseIdentifiers) { - if (identifier.equals(identifier.toUpperCase())) { - return false; - } - } else { - if (identifier.equals(identifier.toLowerCase())) { - return false; - } - } - return true; - } - -} diff --git a/tools/h2/src/main/org/h2/server/web/DbContextRule.java b/tools/h2/src/main/org/h2/server/web/DbContextRule.java deleted file mode 100755 index 7162468..0000000 --- a/tools/h2/src/main/org/h2/server/web/DbContextRule.java +++ /dev/null @@ -1,480 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.server.web; - -import java.util.HashMap; -import java.util.HashSet; -import java.util.Map; -import org.h2.bnf.BnfVisitor; -import org.h2.bnf.Rule; -import org.h2.bnf.RuleHead; -import org.h2.bnf.Sentence; -import org.h2.command.Parser; -import org.h2.message.DbException; -import org.h2.util.New; -import org.h2.util.StringUtils; - -/** - * A BNF terminal rule that is linked to the database context information. - * This class is used by the H2 Console, to support auto-complete. - */ -public class DbContextRule implements Rule { - - static final int COLUMN = 0, TABLE = 1, TABLE_ALIAS = 2; - static final int NEW_TABLE_ALIAS = 3; - static final int COLUMN_ALIAS = 4, SCHEMA = 5; - private static final boolean SUGGEST_TABLE_ALIAS = false; - - private DbContents contents; - private int type; - - DbContextRule(DbContents contents, int type) { - this.contents = contents; - this.type = type; - } - - public String toString() { - switch (type) { - case SCHEMA: - return "schema"; - case TABLE: - return "table"; - case NEW_TABLE_ALIAS: - return "nt"; - case TABLE_ALIAS: - return "t"; - case COLUMN_ALIAS: - return "c"; - case COLUMN: - return "column"; - default: - return "?"; - } - } - - public String name() { - return null; - } - - public void setLinks(HashMap ruleMap) { - // nothing to do - } - - public void addNextTokenList(Sentence sentence) { - switch (type) { - case SCHEMA: - addSchema(sentence); - break; - case TABLE: - addTable(sentence); - break; - case NEW_TABLE_ALIAS: - addNewTableAlias(sentence); - break; - case TABLE_ALIAS: - addTableAlias(sentence); - break; - case COLUMN_ALIAS: -// addColumnAlias(query, sentence); -// break; - case COLUMN: - addColumn(sentence); - break; - default: - } - } - - private void addTableAlias(Sentence sentence) { - String query = sentence.getQuery(); - String q = StringUtils.toUpperEnglish(query.trim()); - HashMap map = sentence.getAliases(); - HashSet set = New.hashSet(); - if (map != null) { - for (Map.Entry entry : map.entrySet()) { - String alias = entry.getKey(); - DbTableOrView table = entry.getValue(); - set.add(StringUtils.toUpperEnglish(table.name)); - if (q.length() == 0 || alias.startsWith(q)) { - if (q.length() < alias.length()) { - sentence.add(alias + ".", alias.substring(q.length()) + ".", Sentence.CONTEXT); - } - } - } - } - HashSet tables = sentence.getTables(); - if (tables != null) { - for (DbTableOrView table : tables) { - String tableName = StringUtils.toUpperEnglish(table.name); - //DbTableOrView[] tables = contents.defaultSchema.tables; - //for(int i=0; i 3) { - return; - } - String lastTableName = StringUtils.toUpperEnglish(sentence.getLastTable().name); - if (lastTableName == null) { - return; - } - HashMap map = sentence.getAliases(); - String shortName = lastTableName.substring(0, 1); - if (map != null && map.containsKey(shortName)) { - int result = 0; - for (int i = 1;; i++) { - if (!map.containsKey(shortName + i)) { - result = i; - break; - } - } - shortName += result; - } - String q = StringUtils.toUpperEnglish(query.trim()); - if (q.length() == 0 || StringUtils.toUpperEnglish(shortName).startsWith(q)) { - if (q.length() < shortName.length()) { - sentence.add(shortName, shortName.substring(q.length()), Sentence.CONTEXT); - } - } - } - } - -// private boolean startWithIgnoreCase(String a, String b) { -// if(a.length() < b.length()) { -// return false; -// } -// for(int i=0; i set = null; - HashMap aliases = sentence.getAliases(); - if (tableName == null && sentence.getTables() != null) { - set = sentence.getTables(); - } - DbTableOrView table = null; - if (tableName != null && aliases != null && aliases.get(tableName) != null) { - table = aliases.get(tableName); - tableName = StringUtils.toUpperEnglish(table.name); - } - if (tableName == null) { - if (set == null && aliases == null) { - return; - } - if ((set != null && set.size() > 1) || (aliases != null && aliases.size() > 1)) { - return; - } - } - if (table == null) { - for (DbTableOrView tab : contents.defaultSchema.tables) { - String t = StringUtils.toUpperEnglish(tab.name); - if (tableName != null && !tableName.equals(t)) { - continue; - } - if (set != null && !set.contains(tab)) { - continue; - } - table = tab; - break; - } - } - if (table != null && table.columns != null) { - for (DbColumn column : table.columns) { - String columnName = column.name; - if (!StringUtils.toUpperEnglish(columnName).startsWith(columnPattern)) { - continue; - } - if (columnPattern.length() < columnName.length()) { - String sub = columnName.substring(columnPattern.length()); - if (sub.equals(columnName) && contents.needsQuotes(columnName)) { - columnName = StringUtils.quoteIdentifier(columnName); - sub = columnName; - } - sentence.add(columnName, sub, Sentence.CONTEXT); - } - } - } - } - - public boolean matchRemove(Sentence sentence) { - if (sentence.getQuery().length() == 0) { - return false; - } - String s; - switch (type) { - case SCHEMA: - s = matchSchema(sentence); - break; - case TABLE: - s = matchTable(sentence); - break; - case NEW_TABLE_ALIAS: - s = matchTableAlias(sentence, true); - break; - case TABLE_ALIAS: - s = matchTableAlias(sentence, false); - break; - case COLUMN_ALIAS: - s = matchColumnAlias(sentence); - break; - case COLUMN: - s = matchColumn(sentence); - break; - default: - throw DbException.throwInternalError("type=" + type); - } - if (s == null) { - return false; - } - sentence.setQuery(s); - return true; - } - - private String matchSchema(Sentence sentence) { - String query = sentence.getQuery(); - String up = sentence.getQueryUpper(); - DbSchema[] schemas = contents.schemas; - String best = null; - DbSchema bestSchema = null; - for (DbSchema schema: schemas) { - String schemaName = StringUtils.toUpperEnglish(schema.name); - if (up.startsWith(schemaName)) { - if (best == null || schemaName.length() > best.length()) { - best = schemaName; - bestSchema = schema; - } - } - } - sentence.setLastMatchedSchema(bestSchema); - if (best == null) { - return null; - } - query = query.substring(best.length()); - // while(query.length()>0 && Character.isWhitespace(query.charAt(0))) { - // query = query.substring(1); - // } - return query; - } - - private String matchTable(Sentence sentence) { - String query = sentence.getQuery(); - String up = sentence.getQueryUpper(); - DbSchema schema = sentence.getLastMatchedSchema(); - if (schema == null) { - schema = contents.defaultSchema; - } - DbTableOrView[] tables = schema.tables; - String best = null; - DbTableOrView bestTable = null; - for (DbTableOrView table : tables) { - String tableName = StringUtils.toUpperEnglish(table.name); - if (up.startsWith(tableName)) { - if (best == null || tableName.length() > best.length()) { - best = tableName; - bestTable = table; - } - } - } - if (best == null) { - return null; - } - sentence.addTable(bestTable); - query = query.substring(best.length()); - // while(query.length()>0 && Character.isWhitespace(query.charAt(0))) { - // query = query.substring(1); - // } - return query; - } - - private String matchColumnAlias(Sentence sentence) { - String query = sentence.getQuery(); - String up = sentence.getQueryUpper(); - int i = 0; - if (query.indexOf(' ') < 0) { - return null; - } - for (; i < up.length(); i++) { - char ch = up.charAt(i); - if (ch != '_' && !Character.isLetterOrDigit(ch)) { - break; - } - } - if (i == 0) { - return null; - } - String alias = up.substring(0, i); - if (Parser.isKeyword(alias, true)) { - return null; - } - return query.substring(alias.length()); - } - - private String matchTableAlias(Sentence sentence, boolean add) { - String query = sentence.getQuery(); - String up = sentence.getQueryUpper(); - int i = 0; - if (query.indexOf(' ') < 0) { - return null; - } - for (; i < up.length(); i++) { - char ch = up.charAt(i); - if (ch != '_' && !Character.isLetterOrDigit(ch)) { - break; - } - } - if (i == 0) { - return null; - } - String alias = up.substring(0, i); - if (Parser.isKeyword(alias, true)) { - return null; - } - if (add) { - sentence.addAlias(alias, sentence.getLastTable()); - } - HashMap map = sentence.getAliases(); - if ((map != null && map.containsKey(alias)) || (sentence.getLastTable() == null)) { - if (add && query.length() == alias.length()) { - return query; - } - query = query.substring(alias.length()); - return query; - } - HashSet tables = sentence.getTables(); - if (tables != null) { - String best = null; - for (DbTableOrView table : tables) { - String tableName = StringUtils.toUpperEnglish(table.name); - //DbTableOrView[] tables = contents.defaultSchema.tables; - //for(int i=0; i best.length())) { - sentence.setLastMatchedTable(table); - best = tableName; - } - } - if (best != null) { - query = query.substring(best.length()); - return query; - } - } - return null; - } - - private String matchColumn(Sentence sentence) { - String query = sentence.getQuery(); - String up = sentence.getQueryUpper(); - HashSet set = sentence.getTables(); - String best = null; - DbTableOrView last = sentence.getLastMatchedTable(); - if (last != null && last.columns != null) { - for (DbColumn column : last.columns) { - String name = StringUtils.toUpperEnglish(column.name); - if (up.startsWith(name)) { - String b = query.substring(name.length()); - if (best == null || b.length() < best.length()) { - best = b; - } - } - } - } - for (DbTableOrView table : contents.defaultSchema.tables) { - if (table != last && set != null && !set.contains(table)) { - continue; - } - if (table == null || table.columns == null) { - continue; - } - for (DbColumn column : table.columns) { - String name = StringUtils.toUpperEnglish(column.name); - if (up.startsWith(name)) { - String b = query.substring(name.length()); - if (best == null || b.length() < best.length()) { - best = b; - } - } - } - } - return best; - } - - public void accept(BnfVisitor visitor) { - // nothing to do - } - -} diff --git a/tools/h2/src/main/org/h2/server/web/DbSchema.java b/tools/h2/src/main/org/h2/server/web/DbSchema.java deleted file mode 100755 index 1e6d145..0000000 --- a/tools/h2/src/main/org/h2/server/web/DbSchema.java +++ /dev/null @@ -1,103 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.server.web; - -import java.sql.DatabaseMetaData; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.util.ArrayList; -import org.h2.util.New; - -/** - * Contains meta data information about a database schema. - * This class is used by the H2 Console. - */ -public class DbSchema { - - /** - * Up to this many tables, the column type and indexes are listed. - */ - static final int MAX_TABLES_LIST_INDEXES = 100; - - /** - * Up to this many tables, the column names are listed. - */ - static final int MAX_TABLES_LIST_COLUMNS = 500; - - /** - * The database content container. - */ - final DbContents contents; - - /** - * The schema name. - */ - final String name; - - /** - * True if this is the default schema for this database. - */ - final boolean isDefault; - - /** - * True if this is a system schema (for example the INFORMATION_SCHEMA). - */ - final boolean isSystem; - - /** - * The quoted schema name. - */ - final String quotedName; - - /** - * The table list. - */ - DbTableOrView[] tables; - - DbSchema(DbContents contents, String name, boolean isDefault) { - this.contents = contents; - this.name = name; - this.quotedName = contents.quoteIdentifier(name); - this.isDefault = isDefault; - if (name.toUpperCase().startsWith("INFO")) { - isSystem = true; - } else if (contents.isPostgreSQL && name.toUpperCase().startsWith("PG_")) { - isSystem = true; - } else if (contents.isDerby && name.startsWith("SYS")) { - isSystem = true; - } else { - isSystem = false; - } - } - - /** - * Read all tables for this schema from the database meta data. - * - * @param meta the database meta data - * @param tableTypes the table types to read - */ - void readTables(DatabaseMetaData meta, String[] tableTypes) throws SQLException { - ResultSet rs = meta.getTables(null, name, null, tableTypes); - ArrayList list = New.arrayList(); - while (rs.next()) { - DbTableOrView table = new DbTableOrView(this, rs); - if (contents.isOracle && table.name.indexOf('$') > 0) { - continue; - } - list.add(table); - } - rs.close(); - tables = new DbTableOrView[list.size()]; - list.toArray(tables); - if (tables.length < MAX_TABLES_LIST_COLUMNS) { - for (DbTableOrView tab : tables) { - tab.readColumns(meta); - } - } - } - -} diff --git a/tools/h2/src/main/org/h2/server/web/DbStarter.java b/tools/h2/src/main/org/h2/server/web/DbStarter.java deleted file mode 100755 index 5196bc2..0000000 --- a/tools/h2/src/main/org/h2/server/web/DbStarter.java +++ /dev/null @@ -1,88 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.server.web; - -import java.sql.Connection; -import java.sql.DriverManager; - -import javax.servlet.ServletContext; -import javax.servlet.ServletContextEvent; -import javax.servlet.ServletContextListener; - -import org.h2.tools.Server; -import org.h2.util.StringUtils; - -/** - * This class can be used to start the H2 TCP server (or other H2 servers, for - * example the PG server) inside a web application container such as Tomcat or - * Jetty. It can also open a database connection. - */ -public class DbStarter implements ServletContextListener { - - private Connection conn; - private Server server; - - public void contextInitialized(ServletContextEvent servletContextEvent) { - try { - org.h2.Driver.load(); - - // This will get the setting from a context-param in web.xml if defined: - ServletContext servletContext = servletContextEvent.getServletContext(); - String url = getParameter(servletContext, "db.url", "jdbc:h2:~/test"); - String user = getParameter(servletContext, "db.user", "sa"); - String password = getParameter(servletContext, "db.password", "sa"); - - conn = DriverManager.getConnection(url, user, password); - servletContext.setAttribute("connection", conn); - - // Start the server if configured to do so - String serverParams = getParameter(servletContext, "db.tcpServer", null); - if (serverParams != null) { - String[] params = StringUtils.arraySplit(serverParams, ' ', true); - server = Server.createTcpServer(params); - server.start(); - } - // To access the database in server mode, use the database URL: - // jdbc:h2:tcp://localhost/~/test - - } catch (Exception e) { - e.printStackTrace(); - } - } - - private String getParameter(ServletContext servletContext, String key, String defaultValue) { - String value = servletContext.getInitParameter(key); - return value == null ? defaultValue : value; - } - - /** - * Get the connection. - * - * @return the connection - */ - public Connection getConnection() { - return conn; - } - - public void contextDestroyed(ServletContextEvent servletContextEvent) { - try { - conn.createStatement().execute("SHUTDOWN"); - } catch (Exception e) { - e.printStackTrace(); - } - try { - conn.close(); - } catch (Exception e) { - e.printStackTrace(); - } - if (server != null) { - server.stop(); - server = null; - } - } - -} diff --git a/tools/h2/src/main/org/h2/server/web/DbTableOrView.java b/tools/h2/src/main/org/h2/server/web/DbTableOrView.java deleted file mode 100755 index 0d2b65f..0000000 --- a/tools/h2/src/main/org/h2/server/web/DbTableOrView.java +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.server.web; - -import java.sql.DatabaseMetaData; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.util.ArrayList; -import org.h2.util.New; - -/** - * Contains meta data information about a table or a view. - * This class is used by the H2 Console. - */ -public class DbTableOrView { - - /** - * The schema this table belongs to. - */ - DbSchema schema; - - /** - * The table name. - */ - String name; - - /** - * The quoted table name. - */ - String quotedName; - - /** - * True if this represents a view. - */ - boolean isView; - - /** - * The column list. - */ - DbColumn[] columns; - - DbTableOrView(DbSchema schema, ResultSet rs) throws SQLException { - this.schema = schema; - name = rs.getString("TABLE_NAME"); - String type = rs.getString("TABLE_TYPE"); - isView = "VIEW".equals(type); - quotedName = schema.contents.quoteIdentifier(name); - } - - /** - * Read the column for this table from the database meta data. - * - * @param meta the database meta data - */ - void readColumns(DatabaseMetaData meta) throws SQLException { - ResultSet rs = meta.getColumns(null, schema.name, name, null); - ArrayList list = New.arrayList(); - while (rs.next()) { - DbColumn column = new DbColumn(rs); - list.add(column); - } - rs.close(); - columns = new DbColumn[list.size()]; - list.toArray(columns); - } - -} diff --git a/tools/h2/src/main/org/h2/server/web/PageParser.java b/tools/h2/src/main/org/h2/server/web/PageParser.java deleted file mode 100755 index b10b6fc..0000000 --- a/tools/h2/src/main/org/h2/server/web/PageParser.java +++ /dev/null @@ -1,341 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.server.web; - -import java.text.ParseException; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import org.h2.util.New; - -/** - * A page parser can parse an HTML page and replace the tags there. - * This class is used by the H2 Console. - */ -public class PageParser { - private String page; - private int pos; - private Map settings; - private int len; - private StringBuilder result; - - private PageParser(String page, Map settings, int pos) { - this.page = page; - this.pos = pos; - this.len = page.length(); - this.settings = settings; - result = new StringBuilder(len); - } - - /** - * Replace the tags in the HTML page with the given settings. - * - * @param page the HTML page - * @param settings the settings - * @return the converted page - */ - public static String parse(String page, Map settings) { - PageParser block = new PageParser(page, settings, 0); - return block.replaceTags(); - } - - private void setError(int i) { - String s = page.substring(0, i) + "####BUG####" + page.substring(i); - s = PageParser.escapeHtml(s); - result = new StringBuilder(); - result.append(s); - } - - private String parseBlockUntil(String end) throws ParseException { - PageParser block = new PageParser(page, settings, pos); - block.parseAll(); - if (!block.readIf(end)) { - throw new ParseException(page, block.pos); - } - pos = block.pos; - return block.result.toString(); - } - - private String replaceTags() { - try { - parseAll(); - if (pos != len) { - setError(pos); - } - } catch (ParseException e) { - setError(pos); - } - return result.toString(); - } - - @SuppressWarnings("unchecked") - private void parseAll() throws ParseException { - StringBuilder buff = result; - String p = page; - int i = pos; - for (; i < len; i++) { - char c = p.charAt(i); - switch (c) { - case '<': { - if (p.charAt(i + 3) == ':' && p.charAt(i + 1) == '/') { - // end tag - pos = i; - return; - } else if (p.charAt(i + 2) == ':') { - pos = i; - if (readIf(""); - int start = pos; - List list = (List) get(items); - if (list == null) { - result.append("?items?"); - list = New.arrayList(); - } - if (list.size() == 0) { - parseBlockUntil(""); - } - for (Object o : list) { - settings.put(var, o); - pos = start; - String block = parseBlockUntil(""); - result.append(block); - } - } else if (readIf(""); - String block = parseBlockUntil(""); - pos--; - if (value.equals(val)) { - result.append(block); - } - } else { - setError(i); - return; - } - i = pos; - } else { - buff.append(c); - } - break; - } - case '$': - if (p.length() > i + 1 && p.charAt(i + 1) == '{') { - i += 2; - int j = p.indexOf('}', i); - if (j < 0) { - setError(i); - return; - } - String item = p.substring(i, j).trim(); - i = j; - String s = (String) get(item); - replaceTags(s); - } else { - buff.append(c); - } - break; - default: - buff.append(c); - break; - } - } - pos = i; - } - - @SuppressWarnings("unchecked") - private Object get(String item) { - int dot = item.indexOf('.'); - if (dot >= 0) { - String sub = item.substring(dot + 1); - item = item.substring(0, dot); - HashMap map = (HashMap) settings.get(item); - if (map == null) { - return "?" + item + "?"; - } - return map.get(sub); - } - return settings.get(item); - } - - private void replaceTags(String s) { - if (s != null) { - result.append(PageParser.parse(s, settings)); - } - } - - private String readParam(String name) throws ParseException { - read(name); - read("="); - read("\""); - int start = pos; - while (page.charAt(pos) != '"') { - pos++; - } - int end = pos; - read("\""); - String s = page.substring(start, end); - return PageParser.parse(s, settings); - } - - private void skipSpaces() { - while (page.charAt(pos) == ' ') { - pos++; - } - } - - private void read(String s) throws ParseException { - if (!readIf(s)) { - throw new ParseException(s, pos); - } - } - - private boolean readIf(String s) { - skipSpaces(); - if (page.regionMatches(pos, s, 0, s.length())) { - pos += s.length(); - skipSpaces(); - return true; - } - return false; - } - - /** - * Convert data to HTML, but don't convert newlines and multiple spaces. - * - * @param s the data - * @return the escaped html text - */ - static String escapeHtmlData(String s) { - return escapeHtml(s, false); - } - - /** - * Convert data to HTML, including newlines and multiple spaces. - * - * @param s the data - * @return the escaped html text - */ - public static String escapeHtml(String s) { - return escapeHtml(s, true); - } - - private static String escapeHtml(String s, boolean convertBreakAndSpace) { - if (s == null) { - return null; - } - if (convertBreakAndSpace) { - if (s.length() == 0) { - return " "; - } - } - StringBuilder buff = new StringBuilder(s.length()); - boolean convertSpace = true; - for (int i = 0; i < s.length(); i++) { - char c = s.charAt(i); - if (c == ' ') { - if (convertSpace && convertBreakAndSpace) { - buff.append(" "); - } else { - buff.append(' '); - convertSpace = true; - } - continue; - } - convertSpace = false; - switch (c) { - case '$': - // so that ${ } in the text is interpreted correctly - buff.append("$"); - break; - case '<': - buff.append("<"); - break; - case '>': - buff.append(">"); - break; - case '&': - buff.append("&"); - break; - case '"': - buff.append("""); - break; - case '\'': - buff.append("'"); - break; - case '\n': - if (convertBreakAndSpace) { - buff.append("
"); - convertSpace = true; - } else { - buff.append(c); - } - break; - default: - if (c >= 128) { - buff.append("&#").append((int) c).append(';'); - } else { - buff.append(c); - } - break; - } - } - return buff.toString(); - } - - /** - * Escape text as a the javascript string. - * - * @param s the text - * @return the javascript string - */ - static String escapeJavaScript(String s) { - if (s == null) { - return null; - } - if (s.length() == 0) { - return ""; - } - StringBuilder buff = new StringBuilder(s.length()); - for (int i = 0; i < s.length(); i++) { - char c = s.charAt(i); - switch (c) { - case '"': - buff.append("\\\""); - break; - case '\'': - buff.append("\\'"); - break; - case '\\': - buff.append("\\\\"); - break; - case '\n': - buff.append("\\n"); - break; - case '\r': - buff.append("\\r"); - break; - case '\t': - buff.append("\\t"); - break; - default: - buff.append(c); - break; - } - } - return buff.toString(); - } -} diff --git a/tools/h2/src/main/org/h2/server/web/WebApp.java b/tools/h2/src/main/org/h2/server/web/WebApp.java deleted file mode 100755 index a32511b..0000000 --- a/tools/h2/src/main/org/h2/server/web/WebApp.java +++ /dev/null @@ -1,1749 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.server.web; - -import java.io.ByteArrayOutputStream; -import java.io.PrintStream; -import java.io.PrintWriter; -import java.io.StringReader; -import java.io.StringWriter; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; -import java.math.BigDecimal; -import java.sql.Connection; -import java.sql.DatabaseMetaData; -import java.sql.ParameterMetaData; -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.ResultSetMetaData; -import java.sql.SQLException; -import java.sql.Statement; -import java.sql.Types; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.Comparator; -import java.util.HashMap; -import java.util.Iterator; -import java.util.Locale; -import java.util.Map; -import java.util.Properties; -import java.util.Random; -import org.h2.bnf.Bnf; -import org.h2.constant.ErrorCode; -import org.h2.constant.SysProperties; -import org.h2.engine.Constants; -import org.h2.jdbc.JdbcSQLException; -import org.h2.message.DbException; -import org.h2.tools.Backup; -import org.h2.tools.ChangeFileEncryption; -import org.h2.tools.ConvertTraceFile; -import org.h2.tools.CreateCluster; -import org.h2.tools.DeleteDbFiles; -import org.h2.tools.Recover; -import org.h2.tools.Restore; -import org.h2.tools.RunScript; -import org.h2.tools.Script; -import org.h2.tools.SimpleResultSet; -import org.h2.util.JdbcUtils; -import org.h2.util.New; -import org.h2.util.Profiler; -import org.h2.util.ScriptReader; -import org.h2.util.SortedProperties; -import org.h2.util.StatementBuilder; -import org.h2.util.StringUtils; -import org.h2.util.Tool; -import org.h2.util.Utils; - -/** - * For each connection to a session, an object of this class is created. - * This class is used by the H2 Console. - */ -public class WebApp { - - /** - * The web server. - */ - protected WebServer server; - - /** - * The session. - */ - protected WebSession session; - - /** - * The session attributes - */ - protected Properties attributes; - - /** - * The mime type of the current response. - */ - protected String mimeType; - - /** - * Whether the response can be cached. - */ - protected boolean cache; - - /** - * Whether to close the connection. - */ - protected boolean stop; - - /** - * The language in the HTTP header. - */ - protected String headerLanguage; - - private Profiler profiler; - - WebApp(WebServer server) { - this.server = server; - } - - /** - * Set the web session and attributes. - * - * @param session the session - * @param attributes the attributes - */ - void setSession(WebSession session, Properties attributes) { - this.session = session; - this.attributes = attributes; - } - - /** - * Process an HTTP request. - * - * @param file the file that was requested - * @param the host address - * @return the name of the file to return to the client - */ - String processRequest(String file, String hostAddr) { - int index = file.lastIndexOf('.'); - String suffix; - if (index >= 0) { - suffix = file.substring(index + 1); - } else { - suffix = ""; - } - if ("ico".equals(suffix)) { - mimeType = "image/x-icon"; - cache = true; - } else if ("gif".equals(suffix)) { - mimeType = "image/gif"; - cache = true; - } else if ("css".equals(suffix)) { - cache = true; - mimeType = "text/css"; - } else if ("html".equals(suffix) || "do".equals(suffix) || "jsp".equals(suffix)) { - cache = false; - mimeType = "text/html"; - if (session == null) { - session = server.createNewSession(hostAddr); - if (!"notAllowed.jsp".equals(file)) { - file = "index.do"; - } - } - } else if ("js".equals(suffix)) { - cache = true; - mimeType = "text/javascript"; - } else { - cache = false; - mimeType = "text/html"; - file = "error.jsp"; - trace("Unknown mime type, file " + file); - } - trace("mimeType=" + mimeType); - trace(file); - if (file.endsWith(".do")) { - file = process(file); - } - return file; - } - - private String getComboBox(String[] elements, String selected) { - StringBuilder buff = new StringBuilder(); - for (String value : elements) { - buff.append(""); - } - return buff.toString(); - } - - private String getComboBox(String[][] elements, String selected) { - StringBuilder buff = new StringBuilder(); - for (String[] n : elements) { - buff.append(""); - } - return buff.toString(); - } - - private String process(String file) { - trace("process " + file); - while (file.endsWith(".do")) { - if ("login.do".equals(file)) { - file = login(); - } else if ("index.do".equals(file)) { - file = index(); - } else if ("logout.do".equals(file)) { - file = logout(); - } else if ("settingRemove.do".equals(file)) { - file = settingRemove(); - } else if ("settingSave.do".equals(file)) { - file = settingSave(); - } else if ("test.do".equals(file)) { - file = test(); - } else if ("query.do".equals(file)) { - file = query(); - } else if ("tables.do".equals(file)) { - file = tables(); - } else if ("editResult.do".equals(file)) { - file = editResult(); - } else if ("getHistory.do".equals(file)) { - file = getHistory(); - } else if ("admin.do".equals(file)) { - file = admin(); - } else if ("adminSave.do".equals(file)) { - file = adminSave(); - } else if ("adminStartTranslate.do".equals(file)) { - file = adminStartTranslate(); - } else if ("adminShutdown.do".equals(file)) { - file = adminShutdown(); - } else if ("autoCompleteList.do".equals(file)) { - file = autoCompleteList(); - } else if ("tools.do".equals(file)) { - file = tools(); - } else { - file = "error.jsp"; - } - } - trace("return " + file); - return file; - } - - private String autoCompleteList() { - String query = (String) attributes.get("query"); - boolean lowercase = false; - if (query.trim().length() > 0 && Character.isLowerCase(query.trim().charAt(0))) { - lowercase = true; - } - try { - String sql = query; - if (sql.endsWith(";")) { - sql += " "; - } - ScriptReader reader = new ScriptReader(new StringReader(sql)); - reader.setSkipRemarks(true); - String lastSql = ""; - while (true) { - String n = reader.readStatement(); - if (n == null) { - break; - } - lastSql = n; - } - String result = ""; - if (reader.isInsideRemark()) { - if (reader.isBlockRemark()) { - result = "1#(End Remark)# */\n" + result; - } else { - result = "1#(Newline)#\n" + result; - } - } else { - sql = lastSql; - while (sql.length() > 0 && sql.charAt(0) <= ' ') { - sql = sql.substring(1); - } - if (sql.trim().length() > 0 && Character.isLowerCase(sql.trim().charAt(0))) { - lowercase = true; - } - Bnf bnf = session.getBnf(); - if (bnf == null) { - return "autoCompleteList.jsp"; - } - HashMap map = bnf.getNextTokenList(sql); - String space = ""; - if (sql.length() > 0) { - char last = sql.charAt(sql.length() - 1); - if (!Character.isWhitespace(last) && (last != '.' && last >= ' ' && last != '\'' && last != '"')) { - space = " "; - } - } - ArrayList list = New.arrayList(map.size()); - for (Map.Entry entry : map.entrySet()) { - String key = entry.getKey(); - String value = entry.getValue(); - String type = "" + key.charAt(0); - key = key.substring(2); - if (Character.isLetter(key.charAt(0)) && lowercase) { - key = StringUtils.toLowerEnglish(key); - value = StringUtils.toLowerEnglish(value); - } - if (key.equals(value) && !".".equals(value)) { - value = space + value; - } - key = StringUtils.urlEncode(key); - key = StringUtils.replaceAll(key, "+", " "); - value = StringUtils.urlEncode(value); - value = StringUtils.replaceAll(value, "+", " "); - list.add(type + "#" + key + "#" + value); - } - Collections.sort(list); - if (query.endsWith("\n") || query.trim().endsWith(";")) { - list.add(0, "1#(Newline)#\n"); - } - StatementBuilder buff = new StatementBuilder(); - for (String s : list) { - buff.appendExceptFirst("|"); - buff.append(s); - } - result = buff.toString(); - } - session.put("autoCompleteList", result); - } catch (Throwable e) { - server.traceError(e); - } - return "autoCompleteList.jsp"; - } - - private String admin() { - session.put("port", "" + server.getPort()); - session.put("allowOthers", "" + server.getAllowOthers()); - session.put("ssl", String.valueOf(server.getSSL())); - session.put("sessions", server.getSessions()); - return "admin.jsp"; - } - - private String adminSave() { - try { - Properties prop = new SortedProperties(); - int port = Integer.decode((String) attributes.get("port")); - prop.setProperty("webPort", String.valueOf(port)); - server.setPort(port); - boolean allowOthers = Boolean.valueOf((String) attributes.get("allowOthers")).booleanValue(); - prop.setProperty("webAllowOthers", String.valueOf(allowOthers)); - server.setAllowOthers(allowOthers); - boolean ssl = Boolean.valueOf((String) attributes.get("ssl")).booleanValue(); - prop.setProperty("webSSL", String.valueOf(ssl)); - server.setSSL(ssl); - server.saveSettings(prop); - } catch (Exception e) { - trace(e.toString()); - } - return admin(); - } - - private String tools() { - try { - String toolName = (String) attributes.get("tool"); - session.put("tool", toolName); - String args = (String) attributes.get("args"); - String[] argList = StringUtils.arraySplit(args, ',', false); - Tool tool = null; - if ("Backup".equals(toolName)) { - tool = new Backup(); - } else if ("Restore".equals(toolName)) { - tool = new Restore(); - } else if ("Recover".equals(toolName)) { - tool = new Recover(); - } else if ("DeleteDbFiles".equals(toolName)) { - tool = new DeleteDbFiles(); - } else if ("ChangeFileEncryption".equals(toolName)) { - tool = new ChangeFileEncryption(); - } else if ("Script".equals(toolName)) { - tool = new Script(); - } else if ("RunScript".equals(toolName)) { - tool = new RunScript(); - } else if ("ConvertTraceFile".equals(toolName)) { - tool = new ConvertTraceFile(); - } else if ("CreateCluster".equals(toolName)) { - tool = new CreateCluster(); - } else { - throw DbException.throwInternalError(toolName); - } - ByteArrayOutputStream outBuff = new ByteArrayOutputStream(); - PrintStream out = new PrintStream(outBuff, false, "UTF-8"); - tool.setOut(out); - try { - tool.runTool(argList); - out.flush(); - String o = new String(outBuff.toByteArray(), "UTF-8"); - String result = PageParser.escapeHtml(o); - session.put("toolResult", result); - } catch (Exception e) { - session.put("toolResult", getStackTrace(0, e, true)); - } - } catch (Exception e) { - server.traceError(e); - } - return "tools.jsp"; - } - - @SuppressWarnings("unchecked") - private String adminStartTranslate() { - Map p = (Map) session.map.get("text"); - String file = server.startTranslate(p); - session.put("translationFile", file); - return "helpTranslate.jsp"; - } - - /** - * Stop the application and the server. - * - * @return the page to display - */ - protected String adminShutdown() { - server.shutdown(); - return "admin.jsp"; - } - - private String index() { - String[][] languageArray = server.getLanguageArray(); - String language = (String) attributes.get("language"); - Locale locale = session.locale; - if (language != null) { - if (locale == null || !StringUtils.toLowerEnglish(locale.getLanguage()).equals(language)) { - locale = new Locale(language, ""); - server.readTranslations(session, locale.getLanguage()); - session.put("language", language); - session.locale = locale; - } - } else { - language = (String) session.get("language"); - } - if (language == null) { - // if the language is not yet known - // use the last header - language = headerLanguage; - } - session.put("languageCombo", getComboBox(languageArray, language)); - String[] settingNames = server.getSettingNames(); - String setting = attributes.getProperty("setting"); - if (setting == null && settingNames.length > 0) { - setting = settingNames[0]; - } - String combobox = getComboBox(settingNames, setting); - session.put("settingsList", combobox); - ConnectionInfo info = server.getSetting(setting); - if (info == null) { - info = new ConnectionInfo(); - } - session.put("setting", PageParser.escapeHtmlData(setting)); - session.put("name", PageParser.escapeHtmlData(setting)); - session.put("driver", PageParser.escapeHtmlData(info.driver)); - session.put("url", PageParser.escapeHtmlData(info.url)); - session.put("user", PageParser.escapeHtmlData(info.user)); - return "index.jsp"; - } - - private String getHistory() { - int id = Integer.parseInt(attributes.getProperty("id")); - String sql = session.getCommand(id); - session.put("query", PageParser.escapeHtmlData(sql)); - return "query.jsp"; - } - - private int addColumns(boolean mainSchema, DbTableOrView table, StringBuilder buff, int treeIndex, boolean showColumnTypes, - StringBuilder columnsBuffer) { - DbColumn[] columns = table.columns; - for (int i = 0; columns != null && i < columns.length; i++) { - DbColumn column = columns[i]; - if (columnsBuffer.length() > 0) { - columnsBuffer.append(' '); - } - columnsBuffer.append(column.name); - String col = StringUtils.urlEncode(PageParser.escapeJavaScript(column.name)); - String level = mainSchema ? ", 1, 1" : ", 2, 2"; - buff.append("setNode(" + treeIndex + level + ", 'column', '" + PageParser.escapeJavaScript(column.name) - + "', 'javascript:ins(\\'" + col + "\\')');\n"); - treeIndex++; - if (mainSchema && showColumnTypes) { - buff.append("setNode(" + treeIndex + ", 2, 2, 'type', '" + PageParser.escapeJavaScript(column.dataType) - + "', null);\n"); - treeIndex++; - } - } - return treeIndex; - } - - /** - * This class represents index information for the GUI. - */ - static class IndexInfo { - - /** - * The index name. - */ - String name; - - /** - * The index type name. - */ - String type; - - /** - * The indexed columns. - */ - String columns; - } - - private int addIndexes(boolean mainSchema, DatabaseMetaData meta, String table, String schema, StringBuilder buff, int treeIndex) - throws SQLException { - ResultSet rs = meta.getIndexInfo(null, schema, table, false, true); - HashMap indexMap = New.hashMap(); - while (rs.next()) { - String name = rs.getString("INDEX_NAME"); - IndexInfo info = indexMap.get(name); - if (info == null) { - int t = rs.getInt("TYPE"); - String type; - if (t == DatabaseMetaData.tableIndexClustered) { - type = ""; - } else if (t == DatabaseMetaData.tableIndexHashed) { - type = " (${text.tree.hashed})"; - } else if (t == DatabaseMetaData.tableIndexOther) { - type = ""; - } else { - type = null; - } - if (name != null && type != null) { - info = new IndexInfo(); - info.name = name; - type = (rs.getBoolean("NON_UNIQUE") ? "${text.tree.nonUnique}" : "${text.tree.unique}") + type; - info.type = type; - info.columns = rs.getString("COLUMN_NAME"); - indexMap.put(name, info); - } - } else { - info.columns += ", " + rs.getString("COLUMN_NAME"); - } - } - rs.close(); - if (indexMap.size() > 0) { - String level = mainSchema ? ", 1, 1" : ", 2, 1"; - String levelIndex = mainSchema ? ", 2, 1" : ", 3, 1"; - String levelColumnType = mainSchema ? ", 3, 2" : ", 4, 2"; - buff.append("setNode(" + treeIndex + level + ", 'index_az', '${text.tree.indexes}', null);\n"); - treeIndex++; - for (IndexInfo info : indexMap.values()) { - buff.append("setNode(" + treeIndex + levelIndex + ", 'index', '" + PageParser.escapeJavaScript(info.name) - + "', null);\n"); - treeIndex++; - buff.append("setNode(" + treeIndex + levelColumnType + ", 'type', '" + info.type + "', null);\n"); - treeIndex++; - buff.append("setNode(" + treeIndex + levelColumnType + ", 'type', '" + PageParser.escapeJavaScript(info.columns) - + "', null);\n"); - treeIndex++; - } - } - return treeIndex; - } - - private int addTablesAndViews(DbSchema schema, boolean mainSchema, StringBuilder buff, int treeIndex) - throws SQLException { - if (schema == null) { - return treeIndex; - } - Connection conn = session.getConnection(); - DatabaseMetaData meta = session.getMetaData(); - int level = mainSchema ? 0 : 1; - boolean showColumns = mainSchema || !schema.isSystem; - String indentation = ", " + level + ", " + (showColumns ? "1" : "2") + ", "; - String indentNode = ", " + (level + 1) + ", 2, "; - DbTableOrView[] tables = schema.tables; - if (tables == null) { - return treeIndex; - } - boolean isOracle = schema.contents.isOracle; - boolean notManyTables = tables.length < DbSchema.MAX_TABLES_LIST_INDEXES; - for (DbTableOrView table : tables) { - if (table.isView) { - continue; - } - int tableId = treeIndex; - String tab = table.quotedName; - if (!mainSchema) { - tab = schema.quotedName + "." + tab; - } - tab = StringUtils.urlEncode(PageParser.escapeJavaScript(tab)); - buff.append("setNode(" + treeIndex + indentation + " 'table', '" + PageParser.escapeJavaScript(table.name) - + "', 'javascript:ins(\\'" + tab + "\\',true)');\n"); - treeIndex++; - if (mainSchema || showColumns) { - StringBuilder columnsBuffer = new StringBuilder(); - treeIndex = addColumns(mainSchema, table, buff, treeIndex, notManyTables, columnsBuffer); - if (!isOracle && notManyTables) { - treeIndex = addIndexes(mainSchema, meta, table.name, schema.name, buff, treeIndex); - } - buff.append("addTable('" + PageParser.escapeJavaScript(table.name) + "', '" - + PageParser.escapeJavaScript(columnsBuffer.toString()) + "', " + tableId + ");\n"); - } - } - tables = schema.tables; - for (DbTableOrView view : tables) { - if (!view.isView) { - continue; - } - int tableId = treeIndex; - String tab = view.quotedName; - if (!mainSchema) { - tab = view.schema.quotedName + "." + tab; - } - tab = StringUtils.urlEncode(PageParser.escapeJavaScript(tab)); - buff.append("setNode(" + treeIndex + indentation + " 'view', '" + PageParser.escapeJavaScript(view.name) - + "', 'javascript:ins(\\'" + tab + "\\',true)');\n"); - treeIndex++; - if (mainSchema) { - StringBuilder columnsBuffer = new StringBuilder(); - treeIndex = addColumns(mainSchema, view, buff, treeIndex, notManyTables, columnsBuffer); - if (schema.contents.isH2) { - PreparedStatement prep = null; - try { - prep = conn.prepareStatement("SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME=?"); - prep.setString(1, view.name); - ResultSet rs = prep.executeQuery(); - if (rs.next()) { - String sql = rs.getString("SQL"); - buff.append("setNode(" + treeIndex + indentNode + " 'type', '" - + PageParser.escapeJavaScript(sql) + "', null);\n"); - treeIndex++; - } - rs.close(); - } finally { - JdbcUtils.closeSilently(prep); - } - } - buff.append("addTable('" + PageParser.escapeJavaScript(view.name) + "', '" - + PageParser.escapeJavaScript(columnsBuffer.toString()) + "', " + tableId + ");\n"); - } - } - return treeIndex; - } - - private String tables() { - DbContents contents = session.getContents(); - boolean isH2 = false; - try { - contents.readContents(session.getMetaData()); - session.loadBnf(); - Connection conn = session.getConnection(); - DatabaseMetaData meta = session.getMetaData(); - isH2 = contents.isH2; - - StringBuilder buff = new StringBuilder(); - buff.append("setNode(0, 0, 0, 'database', '" + PageParser.escapeJavaScript((String) session.get("url")) - + "', null);\n"); - int treeIndex = 1; - - DbSchema defaultSchema = contents.defaultSchema; - treeIndex = addTablesAndViews(defaultSchema, true, buff, treeIndex); - DbSchema[] schemas = contents.schemas; - for (DbSchema schema : schemas) { - if (schema == defaultSchema || schema == null) { - continue; - } - buff.append("setNode(" + treeIndex + ", 0, 1, 'folder', '" + PageParser.escapeJavaScript(schema.name) - + "', null);\n"); - treeIndex++; - treeIndex = addTablesAndViews(schema, false, buff, treeIndex); - } - if (isH2) { - Statement stat = null; - try { - stat = conn.createStatement(); - ResultSet rs = stat - .executeQuery("SELECT * FROM INFORMATION_SCHEMA.SEQUENCES ORDER BY SEQUENCE_NAME"); - for (int i = 0; rs.next(); i++) { - if (i == 0) { - buff.append("setNode(" + treeIndex - + ", 0, 1, 'sequences', '${text.tree.sequences}', null);\n"); - treeIndex++; - } - String name = rs.getString("SEQUENCE_NAME"); - String current = rs.getString("CURRENT_VALUE"); - String increment = rs.getString("INCREMENT"); - buff.append("setNode(" + treeIndex + ", 1, 1, 'sequence', '" - + PageParser.escapeJavaScript(name) + "', null);\n"); - treeIndex++; - buff.append("setNode(" + treeIndex + ", 2, 2, 'type', '${text.tree.current}: " - + PageParser.escapeJavaScript(current) + "', null);\n"); - treeIndex++; - if (!"1".equals(increment)) { - buff.append("setNode(" + treeIndex + ", 2, 2, 'type', '${text.tree.increment}: " - + PageParser.escapeJavaScript(increment) + "', null);\n"); - treeIndex++; - } - } - rs.close(); - rs = stat.executeQuery("SELECT * FROM INFORMATION_SCHEMA.USERS ORDER BY NAME"); - for (int i = 0; rs.next(); i++) { - if (i == 0) { - buff.append("setNode(" + treeIndex + ", 0, 1, 'users', '${text.tree.users}', null);\n"); - treeIndex++; - } - String name = rs.getString("NAME"); - String admin = rs.getString("ADMIN"); - buff.append("setNode(" + treeIndex + ", 1, 1, 'user', '" + PageParser.escapeJavaScript(name) - + "', null);\n"); - treeIndex++; - if (admin.equalsIgnoreCase("TRUE")) { - buff.append("setNode(" + treeIndex + ", 2, 2, 'type', '${text.tree.admin}', null);\n"); - treeIndex++; - } - } - rs.close(); - } finally { - JdbcUtils.closeSilently(stat); - } - } - String version = meta.getDatabaseProductName() + " " + meta.getDatabaseProductVersion(); - buff.append("setNode(" + treeIndex + ", 0, 0, 'info', '" + PageParser.escapeJavaScript(version) - + "', null);\n"); - buff.append("refreshQueryTables();"); - session.put("tree", buff.toString()); - } catch (Exception e) { - session.put("tree", ""); - session.put("error", getStackTrace(0, e, isH2)); - } - return "tables.jsp"; - } - - private String getStackTrace(int id, Throwable e, boolean isH2) { - try { - StringWriter writer = new StringWriter(); - e.printStackTrace(new PrintWriter(writer)); - String stackTrace = writer.toString(); - stackTrace = PageParser.escapeHtml(stackTrace); - if (isH2) { - stackTrace = linkToSource(stackTrace); - } - stackTrace = StringUtils.replaceAll(stackTrace, "\t", "    "); - String message = PageParser.escapeHtml(e.getMessage()); - String error = "" + message + ""; - if (e instanceof SQLException) { - SQLException se = (SQLException) e; - error += " " + se.getSQLState() + "/" + se.getErrorCode(); - if (isH2) { - int code = se.getErrorCode(); - error += " (${text.a.help})"; - } - } - error += "
" + stackTrace + "
"; - error = formatAsError(error); - return error; - } catch (OutOfMemoryError e2) { - server.traceError(e); - return e.toString(); - } - } - - private String linkToSource(String s) { - try { - StringBuilder result = new StringBuilder(s.length()); - int idx = s.indexOf("
"); - result.append(s.substring(0, idx)); - while (true) { - int start = s.indexOf("org.h2.", idx); - if (start < 0) { - result.append(s.substring(idx)); - break; - } - result.append(s.substring(idx, start)); - int end = s.indexOf(')', start); - if (end < 0) { - result.append(s.substring(idx)); - break; - } - String element = s.substring(start, end); - int open = element.lastIndexOf('('); - int dotMethod = element.lastIndexOf('.', open - 1); - int dotClass = element.lastIndexOf('.', dotMethod - 1); - String packageName = element.substring(0, dotClass); - int colon = element.lastIndexOf(':'); - String file = element.substring(open + 1, colon); - String lineNumber = element.substring(colon + 1, element.length()); - String fullFileName = packageName.replace('.', '/') + "/" + file; - result.append(""); - result.append(element); - result.append(""); - idx = end; - } - return result.toString(); - } catch (Throwable t) { - return s; - } - } - - private String formatAsError(String s) { - return "
" + s + "
"; - } - - private String test() { - String driver = attributes.getProperty("driver", ""); - String url = attributes.getProperty("url", ""); - String user = attributes.getProperty("user", ""); - String password = attributes.getProperty("password", ""); - session.put("driver", driver); - session.put("url", url); - session.put("user", user); - boolean isH2 = url.startsWith("jdbc:h2:"); - try { - long start = System.currentTimeMillis(); - String profOpen = "", profClose = ""; - Profiler prof = new Profiler(); - prof.startCollecting(); - Connection conn; - try { - conn = server.getConnection(driver, url, user, password); - } finally { - prof.stopCollecting(); - profOpen = prof.getTop(3); - } - prof = new Profiler(); - prof.startCollecting(); - try { - JdbcUtils.closeSilently(conn); - } finally { - prof.stopCollecting(); - profClose = prof.getTop(3); - } - long time = System.currentTimeMillis() - start; - String success; - if (time > 1000) { - success = "" + - "${text.login.testSuccessful}" + - "
" + - PageParser.escapeHtml(profOpen) + - "
" + - PageParser.escapeHtml(profClose) + - "
"; - } else { - success = "${text.login.testSuccessful}"; - } - session.put("error", success); - // session.put("error", "${text.login.testSuccessful}"); - return "login.jsp"; - } catch (Exception e) { - session.put("error", getLoginError(e, isH2)); - return "login.jsp"; - } - } - - /** - * Get the formatted login error message. - * - * @param e the exception - * @param isH2 if the current database is a H2 database - * @return the formatted error message - */ - String getLoginError(Exception e, boolean isH2) { - if (e instanceof JdbcSQLException && ((JdbcSQLException) e).getErrorCode() == ErrorCode.CLASS_NOT_FOUND_1) { - return "${text.login.driverNotFound}
" + getStackTrace(0, e, isH2); - } - return getStackTrace(0, e, isH2); - } - - private String login() { - String driver = attributes.getProperty("driver", ""); - String url = attributes.getProperty("url", ""); - String user = attributes.getProperty("user", ""); - String password = attributes.getProperty("password", ""); - session.put("autoCommit", "checked"); - session.put("autoComplete", "1"); - session.put("maxrows", "1000"); - if (loginAsync(driver, url, user, password)) { - return ""; - } - boolean isH2 = url.startsWith("jdbc:h2:"); - try { - Connection conn = server.getConnection(driver, url, user, password); - session.setConnection(conn); - session.put("url", url); - session.put("user", user); - session.remove("error"); - settingSave(); - return "frame.jsp"; - } catch (Exception e) { - session.put("error", getLoginError(e, isH2)); - return "login.jsp"; - } - } - - /** - * Login in a separate thread if possible. - * - * @param driver the driver class - * @param url the database URL - * @param user the user name - * @param password the password - * @return false if asynchronous login is not possible - */ - protected boolean loginAsync(String driver, String url, String user, String password) { - return false; - } - - private String logout() { - try { - Connection conn = session.getConnection(); - session.setConnection(null); - session.remove("conn"); - session.remove("result"); - session.remove("tables"); - session.remove("user"); - session.remove("tool"); - if (conn != null) { - if (session.getShutdownServerOnDisconnect()) { - server.shutdown(); - } else { - conn.close(); - } - } - } catch (Exception e) { - trace(e.toString()); - } - return "index.do"; - } - - private String query() { - String sql = attributes.getProperty("sql").trim(); - try { - ScriptReader r = new ScriptReader(new StringReader(sql)); - final ArrayList list = New.arrayList(); - while (true) { - String s = r.readStatement(); - if (s == null) { - break; - } - list.add(s); - } - final Connection conn = session.getConnection(); - if (SysProperties.CONSOLE_STREAM && server.getAllowChunked()) { - String page = StringUtils.utf8Decode(server.getFile("result.jsp")); - int idx = page.indexOf("${result}"); - // the first element of the list is the header, the last the footer - list.add(0, page.substring(0, idx)); - list.add(page.substring(idx + "${result}".length())); - session.put("chunks", new Iterator() { - private int i; - public boolean hasNext() { - return i < list.size(); - } - public String next() { - String s = list.get(i++); - if (i == 1 || i == list.size()) { - return s; - } - StringBuilder b = new StringBuilder(); - query(conn, s, i - 1, list.size() - 2, b); - return b.toString(); - } - public void remove() { - throw new UnsupportedOperationException(); - } - }); - return "result.jsp"; - } - String result; - StringBuilder buff = new StringBuilder(); - for (int i = 0; i < list.size(); i++) { - String s = list.get(i); - query(conn, s, i, list.size(), buff); - } - result = buff.toString(); - session.put("result", result); - } catch (Throwable e) { - session.put("result", getStackTrace(0, e, session.getContents().isH2)); - } - return "result.jsp"; - } - - /** - * Execute a query and append the result to the buffer. - * - * @param conn the connection - * @param s the statement - * @param i the index - * @param size the number of statements - * @param buff the target buffer - */ - protected void query(Connection conn, String s, int i, int size, StringBuilder buff) { - if (!(s.startsWith("@") && s.endsWith("."))) { - buff.append(PageParser.escapeHtml(s + ";")).append("
"); - } - boolean forceEdit = s.startsWith("@edit"); - buff.append(getResult(conn, i + 1, s, size == 1, forceEdit)).append("
"); - } - - private String editResult() { - ResultSet rs = session.result; - int row = Integer.parseInt(attributes.getProperty("row")); - int op = Integer.parseInt(attributes.getProperty("op")); - String result = "", error = ""; - try { - if (op == 1) { - boolean insert = row < 0; - if (insert) { - rs.moveToInsertRow(); - } else { - rs.absolute(row); - } - for (int i = 0; i < rs.getMetaData().getColumnCount(); i++) { - String x = attributes.getProperty("r" + row + "c" + (i + 1)); - unescapeData(x, rs, i + 1); - } - if (insert) { - rs.insertRow(); - } else { - rs.updateRow(); - } - } else if (op == 2) { - rs.absolute(row); - rs.deleteRow(); - } else if (op == 3) { - // cancel - } - } catch (Throwable e) { - result = "
" + getStackTrace(0, e, session.getContents().isH2); - error = formatAsError(e.getMessage()); - } - String sql = "@edit " + (String) session.get("resultSetSQL"); - Connection conn = session.getConnection(); - result = error + getResult(conn, -1, sql, true, true) + result; - session.put("result", result); - return "result.jsp"; - } - - private ResultSet getMetaResultSet(Connection conn, String sql) throws SQLException { - DatabaseMetaData meta = conn.getMetaData(); - if (isBuiltIn(sql, "@best_row_identifier")) { - String[] p = split(sql); - int scale = p[4] == null ? 0 : Integer.parseInt(p[4]); - boolean nullable = p[5] == null ? false : Boolean.valueOf(p[5]).booleanValue(); - return meta.getBestRowIdentifier(p[1], p[2], p[3], scale, nullable); - } else if (isBuiltIn(sql, "@catalogs")) { - return meta.getCatalogs(); - } else if (isBuiltIn(sql, "@columns")) { - String[] p = split(sql); - return meta.getColumns(p[1], p[2], p[3], p[4]); - } else if (isBuiltIn(sql, "@column_privileges")) { - String[] p = split(sql); - return meta.getColumnPrivileges(p[1], p[2], p[3], p[4]); - } else if (isBuiltIn(sql, "@cross_references")) { - String[] p = split(sql); - return meta.getCrossReference(p[1], p[2], p[3], p[4], p[5], p[6]); - } else if (isBuiltIn(sql, "@exported_keys")) { - String[] p = split(sql); - return meta.getExportedKeys(p[1], p[2], p[3]); - } else if (isBuiltIn(sql, "@imported_keys")) { - String[] p = split(sql); - return meta.getImportedKeys(p[1], p[2], p[3]); - } else if (isBuiltIn(sql, "@index_info")) { - String[] p = split(sql); - boolean unique = p[4] == null ? false : Boolean.valueOf(p[4]).booleanValue(); - boolean approx = p[5] == null ? false : Boolean.valueOf(p[5]).booleanValue(); - return meta.getIndexInfo(p[1], p[2], p[3], unique, approx); - } else if (isBuiltIn(sql, "@primary_keys")) { - String[] p = split(sql); - return meta.getPrimaryKeys(p[1], p[2], p[3]); - } else if (isBuiltIn(sql, "@procedures")) { - String[] p = split(sql); - return meta.getProcedures(p[1], p[2], p[3]); - } else if (isBuiltIn(sql, "@procedure_columns")) { - String[] p = split(sql); - return meta.getProcedureColumns(p[1], p[2], p[3], p[4]); - } else if (isBuiltIn(sql, "@schemas")) { - return meta.getSchemas(); - } else if (isBuiltIn(sql, "@tables")) { - String[] p = split(sql); - String[] types = p[4] == null ? null : StringUtils.arraySplit(p[4], ',', false); - return meta.getTables(p[1], p[2], p[3], types); - } else if (isBuiltIn(sql, "@table_privileges")) { - String[] p = split(sql); - return meta.getTablePrivileges(p[1], p[2], p[3]); - } else if (isBuiltIn(sql, "@table_types")) { - return meta.getTableTypes(); - } else if (isBuiltIn(sql, "@type_info")) { - return meta.getTypeInfo(); - } else if (isBuiltIn(sql, "@udts")) { - String[] p = split(sql); - int[] types; - if (p[4] == null) { - types = null; - } else { - String[] t = StringUtils.arraySplit(p[4], ',', false); - types = new int[t.length]; - for (int i = 0; i < t.length; i++) { - types[i] = Integer.parseInt(t[i]); - } - } - return meta.getUDTs(p[1], p[2], p[3], types); - } else if (isBuiltIn(sql, "@version_columns")) { - String[] p = split(sql); - return meta.getVersionColumns(p[1], p[2], p[3]); - } else if (isBuiltIn(sql, "@memory")) { - SimpleResultSet rs = new SimpleResultSet(); - rs.addColumn("Type", Types.VARCHAR, 0, 0); - rs.addColumn("KB", Types.VARCHAR, 0, 0); - rs.addRow("Used Memory", "" + Utils.getMemoryUsed()); - rs.addRow("Free Memory", "" + Utils.getMemoryFree()); - return rs; - } else if (isBuiltIn(sql, "@info")) { - SimpleResultSet rs = new SimpleResultSet(); - rs.addColumn("KEY", Types.VARCHAR, 0, 0); - rs.addColumn("VALUE", Types.VARCHAR, 0, 0); - rs.addRow("conn.getCatalog", conn.getCatalog()); - rs.addRow("conn.getAutoCommit", "" + conn.getAutoCommit()); - rs.addRow("conn.getTransactionIsolation", "" + conn.getTransactionIsolation()); - rs.addRow("conn.getWarnings", "" + conn.getWarnings()); - String map; - try { - map = "" + conn.getTypeMap(); - } catch (SQLException e) { - map = e.toString(); - } - rs.addRow("conn.getTypeMap", "" + map); - rs.addRow("conn.isReadOnly", "" + conn.isReadOnly()); -//## Java 1.4 begin ## - rs.addRow("conn.getHoldability", "" + conn.getHoldability()); -//## Java 1.4 end ## - addDatabaseMetaData(rs, meta); - return rs; -//## Java 1.4 begin ## - } else if (isBuiltIn(sql, "@attributes")) { - String[] p = split(sql); - return meta.getAttributes(p[1], p[2], p[3], p[4]); - } else if (isBuiltIn(sql, "@super_tables")) { - String[] p = split(sql); - return meta.getSuperTables(p[1], p[2], p[3]); - } else if (isBuiltIn(sql, "@super_types")) { - String[] p = split(sql); - return meta.getSuperTypes(p[1], p[2], p[3]); -//## Java 1.4 end ## - } else if (isBuiltIn(sql, "@prof_stop")) { - if (profiler != null) { - profiler.stopCollecting(); - SimpleResultSet rs = new SimpleResultSet(); - rs.addColumn("Top Stack Trace(s)", Types.VARCHAR, 0, 0); - rs.addRow(profiler.getTop(3)); - profiler = null; - return rs; - } - } - return null; - } - - private void addDatabaseMetaData(SimpleResultSet rs, DatabaseMetaData meta) { - Method[] methods = DatabaseMetaData.class.getDeclaredMethods(); - Arrays.sort(methods, new Comparator() { - public int compare(Method o1, Method o2) { - return o1.toString().compareTo(o2.toString()); - } - }); - for (Method m : methods) { - if (m.getParameterTypes().length == 0) { - try { - Object o = m.invoke(meta); - rs.addRow("meta." + m.getName(), "" + o); - } catch (InvocationTargetException e) { - rs.addRow("meta." + m.getName(), e.getTargetException().toString()); - } catch (Exception e) { - rs.addRow("meta." + m.getName(), e.toString()); - } - } - } - } - - private String[] split(String s) { - String[] list = new String[10]; - String[] t = StringUtils.arraySplit(s, ' ', true); - System.arraycopy(t, 0, list, 0, t.length); - for (int i = 0; i < list.length; i++) { - if ("null".equals(list[i])) { - list[i] = null; - } - } - return list; - } - - private int getMaxrows() { - String r = (String) session.get("maxrows"); - int maxrows = r == null ? 0 : Integer.parseInt(r); - return maxrows; - } - - private String getResult(Connection conn, int id, String sql, boolean allowEdit, boolean forceEdit) { - try { - sql = sql.trim(); - StringBuilder buff = new StringBuilder(); - String sqlUpper = StringUtils.toUpperEnglish(sql); - if (sqlUpper.indexOf("CREATE") >= 0 || sqlUpper.indexOf("DROP") >= 0 || sqlUpper.indexOf("ALTER") >= 0 - || sqlUpper.indexOf("RUNSCRIPT") >= 0) { - String sessionId = attributes.getProperty("jsessionid"); - buff.append(""); - } - Statement stat; - DbContents contents = session.getContents(); - if (forceEdit || (allowEdit && contents.isH2)) { - stat = conn.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_UPDATABLE); - } else { - stat = conn.createStatement(); - } - ResultSet rs; - long time = System.currentTimeMillis(); - boolean metadata = false; - boolean generatedKeys = false; - boolean edit = false; - boolean list = false; - if (isBuiltIn(sql, "@autocommit_true")) { - conn.setAutoCommit(true); - return "${text.result.autoCommitOn}"; - } else if (isBuiltIn(sql, "@autocommit_false")) { - conn.setAutoCommit(false); - return "${text.result.autoCommitOff}"; - } else if (isBuiltIn(sql, "@cancel")) { - stat = session.executingStatement; - if (stat != null) { - stat.cancel(); - buff.append("${text.result.statementWasCanceled}"); - } else { - buff.append("${text.result.noRunningStatement}"); - } - return buff.toString(); - } else if (isBuiltIn(sql, "@edit")) { - edit = true; - sql = sql.substring("@edit".length()).trim(); - session.put("resultSetSQL", sql); - } else if (isBuiltIn(sql, "@generated")) { - generatedKeys = true; - sql = sql.substring("@generated".length()).trim(); - } else if (isBuiltIn(sql, "@history")) { - buff.append(getHistoryString()); - return buff.toString(); - } else if (isBuiltIn(sql, "@list")) { - list = true; - sql = sql.substring("@list".length()).trim(); - } else if (isBuiltIn(sql, "@loop")) { - sql = sql.substring("@loop".length()).trim(); - int idx = sql.indexOf(' '); - int count = Integer.decode(sql.substring(0, idx)); - sql = sql.substring(idx).trim(); - return executeLoop(conn, count, sql); - } else if (isBuiltIn(sql, "@maxrows")) { - int maxrows = (int) Double.parseDouble(sql.substring("@maxrows".length()).trim()); - session.put("maxrows", "" + maxrows); - return "${text.result.maxrowsSet}"; - } else if (isBuiltIn(sql, "@meta")) { - metadata = true; - sql = sql.substring("@meta".length()).trim(); - } else if (isBuiltIn(sql, "@parameter_meta")) { - sql = sql.substring("@parameter_meta".length()).trim(); - PreparedStatement prep = conn.prepareStatement(sql); - buff.append(getParameterResultSet(prep.getParameterMetaData())); - return buff.toString(); - } else if (isBuiltIn(sql, "@prof_start")) { - if (profiler != null) { - profiler.stopCollecting(); - } - profiler = new Profiler(); - profiler.startCollecting(); - return "Ok"; - } else if (isBuiltIn(sql, "@transaction_isolation")) { - String s = sql.substring("@transaction_isolation".length()).trim(); - if (s.length() > 0) { - int level = Integer.parseInt(s); - conn.setTransactionIsolation(level); - } - buff.append("Transaction Isolation: " + conn.getTransactionIsolation() + "
"); - buff.append(Connection.TRANSACTION_READ_UNCOMMITTED + ": read_uncommitted
"); - buff.append(Connection.TRANSACTION_READ_COMMITTED + ": read_committed
"); - buff.append(Connection.TRANSACTION_REPEATABLE_READ + ": repeatable_read
"); - buff.append(Connection.TRANSACTION_SERIALIZABLE + ": serializable"); - } - if (sql.startsWith("@")) { - rs = getMetaResultSet(conn, sql); - if (rs == null) { - buff.append("?: " + sql); - return buff.toString(); - } - } else { - int maxrows = getMaxrows(); - stat.setMaxRows(maxrows); - session.executingStatement = stat; - boolean isResultSet = stat.execute(sql); - session.addCommand(sql); - if (generatedKeys) { - rs = null; -//## Java 1.4 begin ## - rs = stat.getGeneratedKeys(); -//## Java 1.4 end ## - } else { - if (!isResultSet) { - buff.append("${text.result.updateCount}: " + stat.getUpdateCount()); - time = System.currentTimeMillis() - time; - buff.append("
(").append(time).append(" ms)"); - stat.close(); - return buff.toString(); - } - rs = stat.getResultSet(); - } - } - time = System.currentTimeMillis() - time; - buff.append(getResultSet(sql, rs, metadata, list, edit, time, allowEdit)); - // SQLWarning warning = stat.getWarnings(); - // if(warning != null) { - // buff.append("
Warning:
"). - // append(getStackTrace(id, warning)); - // } - if (!edit) { - stat.close(); - } - return buff.toString(); - } catch (Throwable e) { - // throwable: including OutOfMemoryError and so on - return getStackTrace(id, e, session.getContents().isH2); - } finally { - session.executingStatement = null; - } - } - - private boolean isBuiltIn(String sql, String builtIn) { - return StringUtils.startsWithIgnoreCase(sql, builtIn); - } - - private String executeLoop(Connection conn, int count, String sql) throws SQLException { - ArrayList params = New.arrayList(); - int idx = 0; - while (!stop) { - idx = sql.indexOf('?', idx); - if (idx < 0) { - break; - } - if (isBuiltIn(sql.substring(idx), "?/*rnd*/")) { - params.add(1); - sql = sql.substring(0, idx) + "?" + sql.substring(idx + "/*rnd*/".length() + 1); - } else { - params.add(0); - } - idx++; - } - int rows = 0; - boolean prepared; - Random random = new Random(1); - long time = System.currentTimeMillis(); - if (isBuiltIn(sql, "@statement")) { - sql = sql.substring("@statement".length()).trim(); - prepared = false; - Statement stat = conn.createStatement(); - for (int i = 0; !stop && i < count; i++) { - String s = sql; - for (Integer type : params) { - idx = s.indexOf('?'); - if (type.intValue() == 1) { - s = s.substring(0, idx) + random.nextInt(count) + s.substring(idx + 1); - } else { - s = s.substring(0, idx) + i + s.substring(idx + 1); - } - } - if (stat.execute(s)) { - ResultSet rs = stat.getResultSet(); - while (!stop && rs.next()) { - rows++; - // maybe get the data as well - } - rs.close(); - } - } - } else { - prepared = true; - PreparedStatement prep = conn.prepareStatement(sql); - for (int i = 0; !stop && i < count; i++) { - for (int j = 0; j < params.size(); j++) { - Integer type = params.get(j); - if (type.intValue() == 1) { - prep.setInt(j + 1, random.nextInt(count)); - } else { - prep.setInt(j + 1, i); - } - } - if (session.getContents().isSQLite) { - // SQLite currently throws an exception on prep.execute() - prep.executeUpdate(); - } else { - if (prep.execute()) { - ResultSet rs = prep.getResultSet(); - while (!stop && rs.next()) { - rows++; - // maybe get the data as well - } - rs.close(); - } - } - } - } - time = System.currentTimeMillis() - time; - StatementBuilder buff = new StatementBuilder(); - buff.append(time).append(" ms: ").append(count).append(" * "); - if (prepared) { - buff.append("(Prepared) "); - } else { - buff.append("(Statement) "); - } - buff.append('('); - for (int p : params) { - buff.appendExceptFirst(", "); - buff.append(p == 0 ? "i" : "rnd"); - } - return buff.append(") ").append(sql).toString(); - } - - private String getHistoryString() { - StringBuilder buff = new StringBuilder(); - ArrayList history = session.getCommands(); - buff.append("
"); - for (int i = history.size() - 1; i >= 0; i--) { - String sql = history.get(i); - buff.append(""); - } - buff.append("
Command
"). - append("\"${text.resultEdit.edit}\""). - append(""). - append(PageParser.escapeHtml(sql)). - append("
"); - return buff.toString(); - } - - private String getParameterResultSet(ParameterMetaData meta) throws SQLException { - StringBuilder buff = new StringBuilder(); - if (meta == null) { - return "No parameter meta data"; - } - buff.append(""). - append(""). - append(""); - for (int i = 0; i < meta.getParameterCount(); i++) { - buff.append(""); - } - buff.append("
classNamemodetypetypeNameprecisionscale
"). - append(meta.getParameterClassName(i + 1)). - append(""). - append(meta.getParameterMode(i + 1)). - append(""). - append(meta.getParameterType(i + 1)). - append(""). - append(meta.getParameterTypeName(i + 1)). - append(""). - append(meta.getPrecision(i + 1)). - append(""). - append(meta.getScale(i + 1)). - append("
"); - return buff.toString(); - } - - private String getResultSet(String sql, ResultSet rs, boolean metadata, boolean list, boolean edit, long time, - boolean allowEdit) throws SQLException { - int maxrows = getMaxrows(); - time = System.currentTimeMillis() - time; - StringBuilder buff = new StringBuilder(); - if (edit) { - buff.append("
" + - "" + - "" + - ""); - } else { - buff.append("
"); - } - ResultSetMetaData meta = rs.getMetaData(); - int columns = meta.getColumnCount(); - int rows = 0; - if (metadata) { - buff.append("" + - "" + - "" + - "" + - ""); - for (int i = 1; i <= columns; i++) { - buff.append(""). - append(""). - append(""). - append(""). - append(""). - append(""). - append(""). - append(""). - append(""). - append(""). - append(""). - append(""). - append(""). - append(""). - append(""). - append(""). - append(""). - append(""). - append(""). - append(""). - append(""). - append(""). - append(""); - } - } else if (list) { - buff.append(""); - while (rs.next()) { - if (maxrows > 0 && rows >= maxrows) { - break; - } - rows++; - buff.append(""); - for (int i = 0; i < columns; i++) { - buff.append(""); - } - } - } else { - buff.append(""); - if (edit) { - buff.append(""); - } - for (int i = 0; i < columns; i++) { - buff.append(""); - } - buff.append(""); - while (rs.next()) { - if (maxrows > 0 && rows >= maxrows) { - break; - } - rows++; - buff.append(""); - if (edit) { - buff.append(""); - } - for (int i = 0; i < columns; i++) { - buff.append(""); - } - buff.append(""); - } - } - boolean isUpdatable = false; - try { - isUpdatable = rs.getConcurrency() == ResultSet.CONCUR_UPDATABLE - && rs.getType() != ResultSet.TYPE_FORWARD_ONLY; - } catch (NullPointerException e) { - // ignore - // workaround for a JDBC-ODBC bridge problem - } - if (edit) { - ResultSet old = session.result; - if (old != null) { - old.close(); - } - session.result = rs; - } else { - rs.close(); - } - if (edit) { - buff.append(""); - for (int i = 0; i < columns; i++) { - buff.append(""); - } - buff.append(""); - } - buff.append("
ilabelcatschemtabcoltypetypeNameclassprecscalesizeautoInccasecurrencynullrosearchsigwdefW
").append(i).append("").append(PageParser.escapeHtml(meta.getColumnLabel(i))).append("").append(PageParser.escapeHtml(meta.getCatalogName(i))).append("").append(PageParser.escapeHtml(meta.getSchemaName(i))).append("").append(PageParser.escapeHtml(meta.getTableName(i))).append("").append(PageParser.escapeHtml(meta.getColumnName(i))).append("").append(meta.getColumnType(i)).append("").append(PageParser.escapeHtml(meta.getColumnTypeName(i))).append("").append(PageParser.escapeHtml(meta.getColumnClassName(i))).append("").append(meta.getPrecision(i)).append("").append(meta.getScale(i)).append("").append(meta.getColumnDisplaySize(i)).append("").append(meta.isAutoIncrement(i)).append("").append(meta.isCaseSensitive(i)).append("").append(meta.isCurrency(i)).append("").append(meta.isNullable(i)).append("").append(meta.isReadOnly(i)).append("").append(meta.isSearchable(i)).append("").append(meta.isSigned(i)).append("").append(meta.isWritable(i)).append("").append(meta.isDefinitelyWritable(i)).append("
ColumnData
Row #"). - append(rows).append("
"). - append(PageParser.escapeHtml(meta.getColumnLabel(i + 1))). - append(""). - append(escapeData(rs, i + 1)). - append("
Action"). - append(PageParser.escapeHtml(meta.getColumnLabel(i + 1))). - append("
"). - append("\"${text.resultEdit.edit}\""). - append("\"${text.resultEdit.delete}\""). - append(""). - append(escapeData(rs, i + 1)). - append("
"). - append("\"${text.resultEdit.add}\""). - append("
"); - if (edit) { - buff.append("
"); - } - if (rows == 0) { - buff.append("(${text.result.noRows}"); - } else if (rows == 1) { - buff.append("(${text.result.1row}"); - } else { - buff.append('(').append(rows).append(" ${text.result.rows}"); - } - buff.append(", "); - time = System.currentTimeMillis() - time; - buff.append(time).append(" ms)"); - if (!edit && isUpdatable && allowEdit) { - buff.append("

" + - "" + - "
"); - } - return buff.toString(); - } - - /** - * Save the current connection settings to the properties file. - * - * @return the file to open afterwards - */ - String settingSave() { - ConnectionInfo info = new ConnectionInfo(); - info.name = attributes.getProperty("name", ""); - info.driver = attributes.getProperty("driver", ""); - info.url = attributes.getProperty("url", ""); - info.user = attributes.getProperty("user", ""); - server.updateSetting(info); - attributes.put("setting", info.name); - server.saveSettings(null); - return "index.do"; - } - - private String escapeData(ResultSet rs, int columnIndex) throws SQLException { - String d = rs.getString(columnIndex); - if (d == null) { - return "null"; - } else if (d.length() > SysProperties.WEB_MAX_VALUE_LENGTH) { - String s; - if (isBinary(rs.getMetaData().getColumnType(columnIndex))) { - s = PageParser.escapeHtml(d.substring(0, 6)) + "... (" + (d.length() / 2) + " ${text.result.bytes})"; - } else { - s = PageParser.escapeHtml(d.substring(0, 100)) + "... (" + d.length() + " ${text.result.characters})"; - } - return "
=+
" + s; - } else if (d.equals("null") || d.startsWith("= ") || d.startsWith("=+")) { - return "
=
" + PageParser.escapeHtml(d); - } - return PageParser.escapeHtml(d); - } - - private boolean isBinary(int sqlType) { - switch (sqlType) { - case Types.BINARY: - case Types.BLOB: - case Types.JAVA_OBJECT: - case Types.LONGVARBINARY: - case Types.OTHER: - case Types.VARBINARY: - return true; - } - return false; - } - - private void unescapeData(String x, ResultSet rs, int columnIndex) throws SQLException { - if (x.equals("null")) { - rs.updateNull(columnIndex); - return; - } else if (x.startsWith("=+")) { - // don't update - return; - } else if (x.startsWith("= ")) { - x = x.substring(2); - } - ResultSetMetaData meta = rs.getMetaData(); - int type = meta.getColumnType(columnIndex); - if (session.getContents().isH2) { - rs.updateString(columnIndex, x); - return; - } - switch (type) { - case Types.BIGINT: - rs.updateLong(columnIndex, Long.decode(x)); - break; - case Types.DECIMAL: - rs.updateBigDecimal(columnIndex, new BigDecimal(x)); - break; - case Types.DOUBLE: - case Types.FLOAT: - rs.updateDouble(columnIndex, Double.parseDouble(x)); - break; - case Types.REAL: - rs.updateFloat(columnIndex, Float.parseFloat(x)); - break; - case Types.INTEGER: - rs.updateInt(columnIndex, Integer.decode(x)); - break; - case Types.TINYINT: - rs.updateShort(columnIndex, Short.decode(x)); - break; - default: - rs.updateString(columnIndex, x); - } - } - - private String settingRemove() { - String setting = attributes.getProperty("name", ""); - server.removeSetting(setting); - ArrayList settings = server.getSettings(); - if (settings.size() > 0) { - attributes.put("setting", settings.get(0)); - } - server.saveSettings(null); - return "index.do"; - } - - /** - * Get the current mime type. - * - * @return the mime type - */ - String getMimeType() { - return mimeType; - } - - boolean getCache() { - return cache; - } - - WebSession getSession() { - return session; - } - - private void trace(String s) { - server.trace(s); - } - -} diff --git a/tools/h2/src/main/org/h2/server/web/WebServer.java b/tools/h2/src/main/org/h2/server/web/WebServer.java deleted file mode 100755 index c174518..0000000 --- a/tools/h2/src/main/org/h2/server/web/WebServer.java +++ /dev/null @@ -1,713 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.server.web; - -import java.io.File; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.net.ServerSocket; -import java.net.Socket; -import java.sql.Connection; -import java.sql.SQLException; -import java.text.SimpleDateFormat; -import java.util.ArrayList; -import java.util.Collections; -import java.util.Date; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Locale; -import java.util.Map; -import java.util.Properties; -import java.util.Set; -import java.util.TimeZone; -import java.util.Map.Entry; -import org.h2.constant.SysProperties; -import org.h2.engine.Constants; -import org.h2.message.TraceSystem; -import org.h2.server.Service; -import org.h2.server.ShutdownHandler; -import org.h2.util.Utils; -import org.h2.util.IOUtils; -import org.h2.util.JdbcUtils; -import org.h2.util.MathUtils; -import org.h2.util.NetUtils; -import org.h2.util.New; -import org.h2.util.SortedProperties; - -/** - * The web server is a simple standalone HTTP server that implements the H2 - * Console application. It is not optimized for performance. - */ -public class WebServer implements Service { - - private static final String DEFAULT_LANGUAGE = "en"; - - private static final String[][] LANGUAGES = { - { "de", "Deutsch" }, - { "en", "English" }, - { "es", "Espa\u00f1ol" }, - { "fr", "Fran\u00e7ais" }, - { "hu", "Magyar"}, - { "in", "Indonesia"}, - { "it", "Italiano"}, - { "ja", "\u65e5\u672c\u8a9e"}, - { "nl", "Nederlands"}, - { "pl", "Polski"}, - { "pt_BR", "Portugu\u00eas (Brasil)"}, - { "pt_PT", "Portugu\u00eas (Europeu)"}, - { "ru", "\u0440\u0443\u0441\u0441\u043a\u0438\u0439"}, - { "sk", "Slovensky"}, - { "tr", "T\u00fcrk\u00e7e"}, - { "uk", "\u0423\u043A\u0440\u0430\u0457\u043D\u0441\u044C\u043A\u0430"}, - { "zh_CN", "\u4e2d\u6587 (\u7b80\u4f53)"}, - { "zh_TW", "\u4e2d\u6587 (\u7e41\u9ad4)"}, - }; - - private static final String[] GENERIC = { - "Generic JNDI Data Source|javax.naming.InitialContext|java:comp/env/jdbc/Test|sa", - "Generic Firebird Server|org.firebirdsql.jdbc.FBDriver|jdbc:firebirdsql:localhost:c:/temp/firebird/test|sysdba", - "Generic OneDollarDB|in.co.daffodil.db.jdbc.DaffodilDBDriver|jdbc:daffodilDB_embedded:school;path=C:/temp;create=true|sa", - "Generic SQLite|org.sqlite.JDBC|jdbc:sqlite:test|sa", - "Generic DB2|COM.ibm.db2.jdbc.net.DB2Driver|jdbc:db2://localhost/test|" , - "Generic Oracle|oracle.jdbc.driver.OracleDriver|jdbc:oracle:thin:@localhost:1521:test|scott" , - "Generic MS SQL Server 2000|com.microsoft.jdbc.sqlserver.SQLServerDriver|jdbc:microsoft:sqlserver://localhost:1433;DatabaseName=sqlexpress|sa", - "Generic MS SQL Server 2005|com.microsoft.sqlserver.jdbc.SQLServerDriver|jdbc:sqlserver://localhost;DatabaseName=test|sa", - "Generic PostgreSQL|org.postgresql.Driver|jdbc:postgresql:test|" , - "Generic MySQL|com.mysql.jdbc.Driver|jdbc:mysql://localhost:3306/test|" , - "Generic HSQLDB|org.hsqldb.jdbcDriver|jdbc:hsqldb:test;hsqldb.default_table_type=cached|sa" , - "Generic Derby (Server)|org.apache.derby.jdbc.ClientDriver|jdbc:derby://localhost:1527/test;create=true|sa", - "Generic Derby (Embedded)|org.apache.derby.jdbc.EmbeddedDriver|jdbc:derby:test;create=true|sa", - "Generic H2 (Server)|org.h2.Driver|jdbc:h2:tcp://localhost/~/test|sa", - // this will be listed on top for new installations - "Generic H2 (Embedded)|org.h2.Driver|jdbc:h2:~/test|sa", - }; - - private static int ticker; - - /** - * The session timeout is 30 min. - */ - private static final long SESSION_TIMEOUT = 30 * 60 * 1000; - -// static { -// String[] list = Locale.getISOLanguages(); -// for (int i = 0; i < list.length; i++) { -// System.out.print(list[i] + " "); -// } -// String lang = new java.util.Locale("hu"). -// getDisplayLanguage(new java.util.Locale("hu")); -// java.util.Locale.CHINESE.getDisplayLanguage(java.util.Locale.CHINESE); -// for (int i = 0; i < lang.length(); i++) { -// System.out.println(Integer.toHexString(lang.charAt(i)) + " "); -// } -// } - - // private URLClassLoader urlClassLoader; - private int port; - private boolean allowOthers; - private boolean isDaemon; - private Set running = Collections.synchronizedSet(new HashSet()); - private boolean ssl; - private HashMap connInfoMap = New.hashMap(); - - private long lastTimeoutCheck; - private HashMap sessions = New.hashMap(); - private HashSet languages = New.hashSet(); - private String startDateTime; - private ServerSocket serverSocket; - private String url; - private ShutdownHandler shutdownHandler; - private Thread listenerThread; - private boolean ifExists; - private boolean trace; - private TranslateThread translateThread; - - private boolean allowChunked = true; - - /** - * Read the given file from the file system or from the resources. - * - * @param file the file name - * @return the data - */ - byte[] getFile(String file) throws IOException { - trace("getFile <" + file + ">"); - byte[] data = Utils.getResource("/org/h2/server/web/res/" + file); - if (data == null) { - trace(" null"); - } else { - trace(" size=" + data.length); - } - return data; - } - - /** - * Remove this web thread from the set of running threads. - * - * @param t the thread to remove - */ - synchronized void remove(WebThread t) { - running.remove(t); - } - - private String generateSessionId() { - byte[] buff = MathUtils.secureRandomBytes(16); - return Utils.convertBytesToString(buff); - } - - /** - * Get the web session object for the given session id. - * - * @param sessionId the session id - * @return the web session or null - */ - WebSession getSession(String sessionId) { - long now = System.currentTimeMillis(); - if (lastTimeoutCheck + SESSION_TIMEOUT < now) { - for (String id : New.arrayList(sessions.keySet())) { - WebSession session = sessions.get(id); - Long last = (Long) session.get("lastAccess"); - if (last != null && last.longValue() + SESSION_TIMEOUT < now) { - trace("timeout for " + id); - sessions.remove(id); - } - } - lastTimeoutCheck = now; - } - WebSession session = sessions.get(sessionId); - if (session != null) { - session.lastAccess = System.currentTimeMillis(); - } - return session; - } - - /** - * Create a new web session id and object. - * - * @param hostAddr the host address - * @return the web session object - */ - WebSession createNewSession(String hostAddr) { - String newId; - do { - newId = generateSessionId(); - } while(sessions.get(newId) != null); - WebSession session = new WebSession(this); - session.put("sessionId", newId); - session.put("ip", hostAddr); - session.put("language", DEFAULT_LANGUAGE); - sessions.put(newId, session); - // always read the english translation, - // so that untranslated text appears at least in english - readTranslations(session, DEFAULT_LANGUAGE); - return getSession(newId); - } - - String getStartDateTime() { - if (startDateTime == null) { - SimpleDateFormat format = new SimpleDateFormat("EEE, d MMM yyyy HH:mm:ss z", new Locale("en", "")); - format.setTimeZone(TimeZone.getTimeZone("GMT")); - startDateTime = format.format(new Date()); - } - return startDateTime; - } - - public void init(String... args) { - // TODO web: support using a different properties file - Properties prop = loadProperties(); - port = SortedProperties.getIntProperty(prop, "webPort", Constants.DEFAULT_HTTP_PORT); - ssl = SortedProperties.getBooleanProperty(prop, "webSSL", false); - allowOthers = SortedProperties.getBooleanProperty(prop, "webAllowOthers", false); - for (int i = 0; args != null && i < args.length; i++) { - String a = args[i]; - if ("-webPort".equals(a)) { - port = Integer.decode(args[++i]); - } else if ("-webSSL".equals(a)) { - ssl = true; - } else if ("-webAllowOthers".equals(a)) { - allowOthers = true; - } else if ("-webDaemon".equals(a)) { - isDaemon = true; - } else if ("-baseDir".equals(a)) { - String baseDir = args[++i]; - SysProperties.setBaseDir(baseDir); - } else if ("-ifExists".equals(a)) { - ifExists = true; - } else if ("-trace".equals(a)) { - trace = true; - } - } -// if(driverList != null) { -// try { -// String[] drivers = -// StringUtils.arraySplit(driverList, ',', false); -// URL[] urls = new URL[drivers.length]; -// for(int i=0; i entry : text.entrySet()) { - String value = (String) entry.getValue(); - if (value.startsWith("#")) { - entry.setValue(value.substring(1)); - } - } - } catch (IOException e) { - TraceSystem.traceThrowable(e); - } - session.put("text", new HashMap(text)); - } - - String[][] getLanguageArray() { - return LANGUAGES; - } - - ArrayList> getSessions() { - ArrayList> list = New.arrayList(); - for (WebSession s : sessions.values()) { - list.add(s.getInfo()); - } - return list; - } - - public String getType() { - return "Web"; - } - - public String getName() { - return "H2 Console Server"; - } - - void setAllowOthers(boolean b) { - allowOthers = b; - } - - public boolean getAllowOthers() { - return allowOthers; - } - - void setSSL(boolean b) { - ssl = b; - } - - void setPort(int port) { - this.port = port; - } - - boolean getSSL() { - return ssl; - } - - public int getPort() { - return port; - } - - /** - * Get the connection information for this setting. - * - * @param name the setting name - * @return the connection information - */ - ConnectionInfo getSetting(String name) { - return connInfoMap.get(name); - } - - /** - * Update a connection information setting. - * - * @param info the connection information - */ - void updateSetting(ConnectionInfo info) { - connInfoMap.put(info.name, info); - info.lastAccess = ticker++; - } - - /** - * Remove a connection information setting from the list - * - * @param name the setting to remove - */ - void removeSetting(String name) { - connInfoMap.remove(name); - } - - private String getPropertiesFileName() { - // store the properties in the user directory - return IOUtils.getFileInUserHome(Constants.SERVER_PROPERTIES_FILE); - } - - private Properties loadProperties() { - String fileName = getPropertiesFileName(); - try { - return SortedProperties.loadProperties(fileName); - } catch (Exception e) { - TraceSystem.traceThrowable(e); - return new Properties(); - } - } - - /** - * Get the list of connection information setting names. - * - * @return the connection info names - */ - String[] getSettingNames() { - ArrayList list = getSettings(); - String[] names = new String[list.size()]; - for (int i = 0; i < list.size(); i++) { - names[i] = list.get(i).name; - } - return names; - } - - /** - * Get the list of connection info objects. - * - * @return the list - */ - synchronized ArrayList getSettings() { - ArrayList settings = New.arrayList(); - if (connInfoMap.size() == 0) { - Properties prop = loadProperties(); - if (prop.size() == 0) { - for (String gen : GENERIC) { - ConnectionInfo info = new ConnectionInfo(gen); - settings.add(info); - updateSetting(info); - } - } else { - for (int i = 0;; i++) { - String data = prop.getProperty(String.valueOf(i)); - if (data == null) { - break; - } - ConnectionInfo info = new ConnectionInfo(data); - settings.add(info); - updateSetting(info); - } - } - } else { - settings.addAll(connInfoMap.values()); - } - Collections.sort(settings); - return settings; - } - - /** - * Save the settings to the properties file. - * - * @param prop null or the properties webPort, webAllowOthers, and webSSL - */ - synchronized void saveSettings(Properties prop) { - try { - if (prop == null) { - Properties old = loadProperties(); - prop = new SortedProperties(); - prop.setProperty("webPort", "" + SortedProperties.getIntProperty(old, "webPort", port)); - prop.setProperty("webAllowOthers", "" + SortedProperties.getBooleanProperty(old, "webAllowOthers", ssl)); - prop.setProperty("webSSL", "" + SortedProperties.getBooleanProperty(old, "webSSL", allowOthers)); - } - ArrayList settings = getSettings(); - int len = settings.size(); - for (int i = 0; i < len; i++) { - ConnectionInfo info = settings.get(i); - if (info != null) { - prop.setProperty(String.valueOf(len - i - 1), info.getString()); - } - } - OutputStream out = IOUtils.openFileOutputStream(getPropertiesFileName(), false); - prop.store(out, "H2 Server Properties"); - out.close(); - } catch (Exception e) { - TraceSystem.traceThrowable(e); - } - } - - /** - * Open a database connection. - * - * @param driver the driver class name - * @param databaseUrl the database URL - * @param user the user name - * @param password the password - * @return the database connection - */ - Connection getConnection(String driver, String databaseUrl, String user, String password) throws SQLException { - driver = driver.trim(); - databaseUrl = databaseUrl.trim(); - org.h2.Driver.load(); - Properties p = new Properties(); - p.setProperty("user", user.trim()); - // do not trim the password, otherwise an - // encrypted H2 database with empty user password doesn't work - p.setProperty("password", password); - if (databaseUrl.startsWith("jdbc:h2:")) { - if (ifExists) { - databaseUrl += ";IFEXISTS=TRUE"; - } - // PostgreSQL would throw a NullPointerException - // if it is loaded before the H2 driver - // because it can't deal with non-String objects in the connection Properties - return org.h2.Driver.load().connect(databaseUrl, p); - } -// try { -// Driver dr = (Driver) urlClassLoader. -// loadClass(driver).newInstance(); -// return dr.connect(url, p); -// } catch(ClassNotFoundException e2) { -// throw e2; -// } - return JdbcUtils.getConnection(driver, databaseUrl, p); - } - - /** - * Shut down the web server. - */ - void shutdown() { - if (shutdownHandler != null) { - shutdownHandler.shutdown(); - } - } - - public void setShutdownHandler(ShutdownHandler shutdownHandler) { - this.shutdownHandler = shutdownHandler; - } - - /** - * Create a session with a given connection. - * - * @param conn the connection - * @return the URL of the web site to access this connection - */ - public String addSession(Connection conn) throws SQLException { - WebSession session = createNewSession("local"); - session.setShutdownServerOnDisconnect(); - session.setConnection(conn); - session.put("url", conn.getMetaData().getURL()); - String s = (String) session.get("sessionId"); - return url + "/frame.jsp?jsessionid=" + s; - } - - /** - * The translate thread reads and writes the file translation.properties - * once a second. - */ - private class TranslateThread extends Thread { - - private final File file = new File("translation.properties"); - private final Map translation; - private volatile boolean stopNow; - - TranslateThread(Map translation) { - this.translation = translation; - } - - public String getFileName() { - return file.getAbsolutePath(); - } - - public void stopNow() { - this.stopNow = true; - try { - join(); - } catch (InterruptedException e) { - // ignore - } - } - - public void run() { - while (!stopNow) { - try { - SortedProperties sp = new SortedProperties(); - if (file.exists()) { - InputStream in = IOUtils.openFileInputStream(file.getName()); - sp.load(in); - translation.putAll(sp); - } else { - OutputStream out = IOUtils.openFileOutputStream(file.getName(), false); - sp.putAll(translation); - sp.store(out, "Translation"); - } - Thread.sleep(1000); - } catch (Exception e) { - traceError(e); - } - } - } - - } - - /** - * Start the translation thread that reads the file once a second. - * - * @param translation the translation map - * @return the name of the file to translate - */ - String startTranslate(Map translation) { - if (translateThread != null) { - translateThread.stopNow(); - } - translateThread = new TranslateThread(translation); - translateThread.setDaemon(true); - translateThread.start(); - return translateThread.getFileName(); - } - - public boolean isDaemon() { - return isDaemon; - } - - void setAllowChunked(boolean allowChunked) { - this.allowChunked = allowChunked; - } - - boolean getAllowChunked() { - return allowChunked; - } - -} diff --git a/tools/h2/src/main/org/h2/server/web/WebServlet.java b/tools/h2/src/main/org/h2/server/web/WebServlet.java deleted file mode 100755 index 0547de9..0000000 --- a/tools/h2/src/main/org/h2/server/web/WebServlet.java +++ /dev/null @@ -1,155 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.server.web; - -import java.io.IOException; -import java.net.InetAddress; -import java.net.UnknownHostException; -import java.util.ArrayList; -import java.util.Enumeration; -import java.util.Properties; -import javax.servlet.ServletConfig; -import javax.servlet.ServletOutputStream; -import javax.servlet.http.HttpServlet; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import org.h2.util.New; -import org.h2.util.StringUtils; - -/** - * This servlet lets the H2 Console be used in a standard servlet container - * such as Tomcat or Jetty. - */ -public class WebServlet extends HttpServlet { - - private static final long serialVersionUID = 1L; - private transient WebServer server; - - public void init() { - ServletConfig config = getServletConfig(); - Enumeration< ? > en = config.getInitParameterNames(); - ArrayList list = New.arrayList(); - while (en.hasMoreElements()) { - String name = en.nextElement().toString(); - String value = config.getInitParameter(name); - if (!name.startsWith("-")) { - name = "-" + name; - } - list.add(name); - if (value.length() > 0) { - list.add(value); - } - } - String[] args = new String[list.size()]; - list.toArray(args); - server = new WebServer(); - server.setAllowChunked(false); - server.init(args); - } - - public void destroy() { - server.stop(); - } - - private boolean allow(HttpServletRequest req) { - if (server.getAllowOthers()) { - return true; - } - String addr = req.getRemoteAddr(); - try { - InetAddress address = InetAddress.getByName(addr); - return address.isLoopbackAddress(); - } catch (UnknownHostException e) { - return false; - } catch (NoClassDefFoundError e) { - // Google App Engine does not allow java.net.InetAddress - return false; - } - } - - private String getAllowedFile(HttpServletRequest req, String requestedFile) { - if (!allow(req)) { - return "notAllowed.jsp"; - } - if (requestedFile.length() == 0) { - return "index.do"; - } - return requestedFile; - } - - protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException { - req.setCharacterEncoding("utf-8"); - String file = req.getPathInfo(); - if (file == null) { - resp.sendRedirect(req.getRequestURI() + "/"); - return; - } else if (file.startsWith("/")) { - file = file.substring(1); - } - file = getAllowedFile(req, file); - byte[] bytes = null; - Properties attributes = new Properties(); - Enumeration< ? > en = req.getAttributeNames(); - while (en.hasMoreElements()) { - String name = en.nextElement().toString(); - String value = req.getAttribute(name).toString(); - attributes.put(name, value); - } - en = req.getParameterNames(); - while (en.hasMoreElements()) { - String name = en.nextElement().toString(); - String value = req.getParameter(name); - attributes.put(name, value); - } - WebSession session = null; - String sessionId = attributes.getProperty("jsessionid"); - if (sessionId != null) { - session = server.getSession(sessionId); - } - WebApp app = new WebApp(server); - app.setSession(session, attributes); - String ifModifiedSince = req.getHeader("if-modified-since"); - - String hostAddr = req.getRemoteAddr(); - file = app.processRequest(file, hostAddr); - session = app.getSession(); - - String mimeType = app.getMimeType(); - boolean cache = app.getCache(); - - if (cache && server.getStartDateTime().equals(ifModifiedSince)) { - resp.setStatus(HttpServletResponse.SC_NOT_MODIFIED); - return; - } - bytes = server.getFile(file); - if (bytes == null) { - resp.sendError(HttpServletResponse.SC_NOT_FOUND); - bytes = StringUtils.utf8Encode("File not found: " + file); - } else { - if (session != null && file.endsWith(".jsp")) { - String page = StringUtils.utf8Decode(bytes); - page = PageParser.parse(page, session.map); - bytes = StringUtils.utf8Encode(page); - } - resp.setContentType(mimeType); - if (!cache) { - resp.setHeader("Cache-Control", "no-cache"); - } else { - resp.setHeader("Cache-Control", "max-age=10"); - resp.setHeader("Last-Modified", server.getStartDateTime()); - } - } - if (bytes != null) { - ServletOutputStream out = resp.getOutputStream(); - out.write(bytes); - } - } - - protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws IOException { - doGet(req, resp); - } -} diff --git a/tools/h2/src/main/org/h2/server/web/WebSession.java b/tools/h2/src/main/org/h2/server/web/WebSession.java deleted file mode 100755 index 44f5bd9..0000000 --- a/tools/h2/src/main/org/h2/server/web/WebSession.java +++ /dev/null @@ -1,260 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.server.web; - -import java.sql.Connection; -import java.sql.DatabaseMetaData; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.sql.Statement; -import java.sql.Timestamp; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.Locale; - -import org.h2.bnf.Bnf; -import org.h2.message.TraceSystem; -import org.h2.util.New; - -/** - * The web session keeps all data of a user session. - * This class is used by the H2 Console. - */ -class WebSession { - - private static final int MAX_HISTORY = 1000; - - /** - * The last time this client sent a request. - */ - long lastAccess; - - /** - * The session attribute map. - */ - HashMap map = New.hashMap(); - - /** - * The current locale. - */ - Locale locale; - - /** - * The currently executing statement. - */ - Statement executingStatement; - - /** - * The current updatable result set. - */ - ResultSet result; - - private WebServer server; - - private ArrayList commandHistory = New.arrayList(); - - private Connection conn; - private DatabaseMetaData meta; - private DbContents contents = new DbContents(); - private DbContextRule columnRule; - private DbContextRule newAliasRule; - private DbContextRule schemaRule; - private DbContextRule tableRule; - private DbContextRule aliasRule; - private DbContextRule columnAliasRule; - private Bnf bnf; - private boolean shutdownServerOnDisconnect; - - WebSession(WebServer server) { - this.server = server; - } - - /** - * Put an attribute value in the map. - * - * @param key the key - * @param value the new value - */ - void put(String key, Object value) { - map.put(key, value); - } - - /** - * Get the value for the given key. - * - * @param key the key - * @return the value - */ - Object get(String key) { - if ("sessions".equals(key)) { - return server.getSessions(); - } - return map.get(key); - } - - /** - * Remove a session attribute from the map. - * - * @param key the key - */ - void remove(String key) { - map.remove(key); - } - - /** - * Get the BNF object. - * - * @return the BNF object - */ - Bnf getBnf() { - return bnf; - } - - /** - * Load the SQL grammar BNF. - */ - void loadBnf() { - try { - Bnf newBnf = Bnf.getInstance(null); - columnRule = new DbContextRule(contents, DbContextRule.COLUMN); - newAliasRule = new DbContextRule(contents, DbContextRule.NEW_TABLE_ALIAS); - aliasRule = new DbContextRule(contents, DbContextRule.TABLE_ALIAS); - tableRule = new DbContextRule(contents, DbContextRule.TABLE); - schemaRule = new DbContextRule(contents, DbContextRule.SCHEMA); - columnAliasRule = new DbContextRule(contents, DbContextRule.COLUMN_ALIAS); - newBnf.updateTopic("column_name", columnRule); - newBnf.updateTopic("new_table_alias", newAliasRule); - newBnf.updateTopic("table_alias", aliasRule); - newBnf.updateTopic("column_alias", columnAliasRule); - newBnf.updateTopic("table_name", tableRule); - newBnf.updateTopic("schema_name", schemaRule); - newBnf.linkStatements(); - bnf = newBnf; - } catch (Exception e) { - // ok we don't have the bnf - server.traceError(e); - } - } - - /** - * Get the SQL statement from history. - * - * @param id the history id - * @return the SQL statement - */ - String getCommand(int id) { - return commandHistory.get(id); - } - - /** - * Add a SQL statement to the history. - * - * @param sql the SQL statement - */ - void addCommand(String sql) { - if (sql == null) { - return; - } - sql = sql.trim(); - if (sql.length() == 0) { - return; - } - if (commandHistory.size() > MAX_HISTORY) { - commandHistory.remove(0); - } - int idx = commandHistory.indexOf(sql); - if (idx >= 0) { - commandHistory.remove(idx); - } - commandHistory.add(sql); - } - - /** - * Get the list of SQL statements in the history. - * - * @return the commands - */ - ArrayList getCommands() { - return commandHistory; - } - - /** - * Update session meta data information and get the information in a map. - * - * @return a map containing the session meta data - */ - HashMap getInfo() { - HashMap m = New.hashMap(); - m.putAll(map); - m.put("lastAccess", new Timestamp(lastAccess).toString()); - try { - m.put("url", conn == null ? "not connected" : conn.getMetaData().getURL()); - m.put("user", conn == null ? "-" : conn.getMetaData().getUserName()); - m.put("lastQuery", commandHistory.size() == 0 ? "" : commandHistory.get(0)); - m.put("executing", executingStatement == null ? "no" : "yes"); - } catch (SQLException e) { - TraceSystem.traceThrowable(e); - } - return m; - } - - void setConnection(Connection conn) throws SQLException { - this.conn = conn; - if (conn == null) { - meta = null; - } else { - meta = conn.getMetaData(); - } - contents = new DbContents(); - } - - DatabaseMetaData getMetaData() { - return meta; - } - - Connection getConnection() { - return conn; - } - - DbContents getContents() { - return contents; - } - - /** - * Shutdown the server when disconnecting. - */ - void setShutdownServerOnDisconnect() { - this.shutdownServerOnDisconnect = true; - } - - boolean getShutdownServerOnDisconnect() { - return shutdownServerOnDisconnect; - } - - /** - * Close the connection and stop the statement if one is currently - * executing. - */ - void close() { - if (executingStatement != null) { - try { - executingStatement.cancel(); - } catch (Exception e) { - // ignore - } - } - if (conn != null) { - try { - conn.close(); - } catch (Exception e) { - // ignore - } - } - - } - -} diff --git a/tools/h2/src/main/org/h2/server/web/WebThread.java b/tools/h2/src/main/org/h2/server/web/WebThread.java deleted file mode 100755 index 7050a3e..0000000 --- a/tools/h2/src/main/org/h2/server/web/WebThread.java +++ /dev/null @@ -1,326 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.server.web; - -import java.io.BufferedInputStream; -import java.io.BufferedOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.net.Socket; -import java.net.UnknownHostException; -import java.util.Iterator; -import java.util.Locale; -import java.util.Properties; -import java.util.StringTokenizer; -import org.h2.constant.SysProperties; -import org.h2.message.TraceSystem; -import org.h2.util.Utils; -import org.h2.util.IOUtils; -import org.h2.util.NetUtils; -import org.h2.util.StringUtils; - -/** - * For each connection to a session, an object of this class is created. - * This class is used by the H2 Console. - */ -class WebThread extends WebApp implements Runnable { - - protected OutputStream output; - protected Socket socket; - private Thread thread; - private InputStream input; - private String ifModifiedSince; - - WebThread(Socket socket, WebServer server) { - super(server); - this.socket = socket; - thread = new Thread(this, "H2 Console thread"); - } - - /** - * Start the thread. - */ - void start() { - thread.start(); - } - - /** - * Wait until the thread is stopped. - * - * @param millis the maximum number of milliseconds to wait - */ - void join(int millis) throws InterruptedException { - thread.join(millis); - } - - /** - * Close the connection now. - */ - void stopNow() { - this.stop = true; - try { - socket.close(); - } catch (IOException e) { - // ignore - } - } - - private String getAllowedFile(String requestedFile) { - if (!allow()) { - return "notAllowed.jsp"; - } - if (requestedFile.length() == 0) { - return "index.do"; - } - return requestedFile; - } - - public void run() { - try { - input = new BufferedInputStream(socket.getInputStream()); - output = new BufferedOutputStream(socket.getOutputStream()); - while (!stop) { - if (!process()) { - break; - } - } - } catch (IOException e) { - TraceSystem.traceThrowable(e); - } - IOUtils.closeSilently(output); - IOUtils.closeSilently(input); - try { - socket.close(); - } catch (IOException e) { - // ignore - } finally { - server.remove(this); - } - } - - @SuppressWarnings("unchecked") - private boolean process() throws IOException { - boolean keepAlive = false; - String head = readHeaderLine(); - if (head.startsWith("GET ") || head.startsWith("POST ")) { - int begin = head.indexOf('/'), end = head.lastIndexOf(' '); - String file; - if (begin < 0 || end < begin) { - file = ""; - } else { - file = head.substring(begin + 1, end).trim(); - } - trace(head + ": " + file); - file = getAllowedFile(file); - attributes = new Properties(); - int paramIndex = file.indexOf("?"); - session = null; - if (paramIndex >= 0) { - String attrib = file.substring(paramIndex + 1); - parseAttributes(attrib); - String sessionId = attributes.getProperty("jsessionid"); - file = file.substring(0, paramIndex); - session = server.getSession(sessionId); - } - keepAlive = parseHeader(); - String hostAddr = socket.getInetAddress().getHostAddress(); - file = processRequest(file, hostAddr); - if (file.length() == 0) { - // asynchronous request - return true; - } - String message; - byte[] bytes; - if (cache && ifModifiedSince != null && ifModifiedSince.equals(server.getStartDateTime())) { - bytes = null; - message = "HTTP/1.1 304 Not Modified\r\n"; - } else { - bytes = server.getFile(file); - if (bytes == null) { - message = "HTTP/1.0 404 Not Found\r\n"; - bytes = StringUtils.utf8Encode("File not found: " + file); - } else { - if (session != null && file.endsWith(".jsp")) { - String page = StringUtils.utf8Decode(bytes); - if (SysProperties.CONSOLE_STREAM) { - Iterator it = (Iterator) session.map.remove("chunks"); - if (it != null) { - message = "HTTP/1.1 200 OK\r\n"; - message += "Content-Type: " + mimeType + "\r\n"; - message += "Cache-Control: no-cache\r\n"; - message += "Transfer-Encoding: chunked\r\n"; - message += "\r\n"; - trace(message); - output.write(message.getBytes()); - while (it.hasNext()) { - String s = it.next(); - s = PageParser.parse(s, session.map); - if (bytes.length == 0) { - continue; - } - bytes = StringUtils.utf8Encode(s); - output.write(Integer.toHexString(bytes.length).getBytes()); - output.write("\r\n".getBytes()); - output.write(bytes); - output.write("\r\n".getBytes()); - output.flush(); - } - output.write("0\r\n\r\n".getBytes()); - output.flush(); - return keepAlive; - } - } - page = PageParser.parse(page, session.map); - bytes = StringUtils.utf8Encode(page); - } - message = "HTTP/1.1 200 OK\r\n"; - message += "Content-Type: " + mimeType + "\r\n"; - if (!cache) { - message += "Cache-Control: no-cache\r\n"; - } else { - message += "Cache-Control: max-age=10\r\n"; - message += "Last-Modified: " + server.getStartDateTime() + "\r\n"; - } - message += "Content-Length: " + bytes.length + "\r\n"; - } - } - message += "\r\n"; - trace(message); - output.write(message.getBytes()); - if (bytes != null) { - output.write(bytes); - } - output.flush(); - } - return keepAlive; - } - - private String readHeaderLine() throws IOException { - StringBuilder buff = new StringBuilder(); - while (true) { - int i = input.read(); - if (i == -1) { - throw new IOException("Unexpected EOF"); - } else if (i == '\r' && input.read() == '\n' || i == '\n') { - return buff.length() > 0 ? buff.toString() : null; - } else { - buff.append((char) i); - } - } - } - - private void parseAttributes(String s) { - trace("data=" + s); - while (s != null) { - int idx = s.indexOf('='); - if (idx >= 0) { - String property = s.substring(0, idx); - s = s.substring(idx + 1); - idx = s.indexOf('&'); - String value; - if (idx >= 0) { - value = s.substring(0, idx); - s = s.substring(idx + 1); - } else { - value = s; - } - String attr = StringUtils.urlDecode(value); - attributes.put(property, attr); - } else { - break; - } - } - trace(attributes.toString()); - } - - private boolean parseHeader() throws IOException { - boolean keepAlive = false; - trace("parseHeader"); - int len = 0; - ifModifiedSince = null; - while (true) { - String line = readHeaderLine(); - if (line == null) { - break; - } - trace(" " + line); - String lower = StringUtils.toLowerEnglish(line); - if (lower.startsWith("if-modified-since")) { - ifModifiedSince = line.substring(line.indexOf(':') + 1).trim(); - } else if (lower.startsWith("connection")) { - String conn = line.substring(line.indexOf(':') + 1).trim(); - if ("keep-alive".equals(conn)) { - keepAlive = true; - } - } else if (lower.startsWith("content-length")) { - len = Integer.parseInt(line.substring(line.indexOf(':') + 1).trim()); - trace("len=" + len); - } else if (lower.startsWith("accept-language")) { - Locale locale = session == null ? null : session.locale; - if (locale == null) { - String languages = line.substring(line.indexOf(':') + 1).trim(); - StringTokenizer tokenizer = new StringTokenizer(languages, ",;"); - while (tokenizer.hasMoreTokens()) { - String token = tokenizer.nextToken(); - if (!token.startsWith("q=")) { - if (server.supportsLanguage(token)) { - int dash = token.indexOf('-'); - if (dash >= 0) { - String language = token.substring(0, dash); - String country = token.substring(dash + 1); - locale = new Locale(language, country); - } else { - locale = new Locale(token, ""); - } - headerLanguage = locale.getLanguage(); - if (session != null) { - session.locale = locale; - session.put("language", headerLanguage); - server.readTranslations(session, headerLanguage); - } - break; - } - } - } - } - } else if (line.trim().length() == 0) { - break; - } - } - if (session != null && len > 0) { - byte[] bytes = Utils.newBytes(len); - for (int pos = 0; pos < len;) { - pos += input.read(bytes, pos, len - pos); - } - String s = new String(bytes); - parseAttributes(s); - } - return keepAlive; - } - - protected String adminShutdown() { - stopNow(); - return super.adminShutdown(); - } - - private boolean allow() { - if (server.getAllowOthers()) { - return true; - } - try { - return NetUtils.isLocalAddress(socket); - } catch (UnknownHostException e) { - server.traceError(e); - return false; - } - } - - private void trace(String s) { - server.trace(s); - } -} diff --git a/tools/h2/src/main/org/h2/server/web/package.html b/tools/h2/src/main/org/h2/server/web/package.html deleted file mode 100755 index 1f206f5..0000000 --- a/tools/h2/src/main/org/h2/server/web/package.html +++ /dev/null @@ -1,15 +0,0 @@ - - - - -Javadoc package documentation -

- -The H2 Console tool. - -

\ No newline at end of file diff --git a/tools/h2/src/main/org/h2/server/web/res/_text_de.prop b/tools/h2/src/main/org/h2/server/web/res/_text_de.prop deleted file mode 100755 index d131dcf..0000000 --- a/tools/h2/src/main/org/h2/server/web/res/_text_de.prop +++ /dev/null @@ -1,149 +0,0 @@ -.translator=Thomas Mueller -a.help=Hilfe -a.language=Deutsch -a.lynxNotSupported=Dieser Browser unterstützt keine Frames. Frames (und Javascript) werden benötigt. -a.password=Passwort -a.remoteConnectionsDisabled=Verbindungen von anderen Rechnern sind nicht freigegeben ('webAllowOthers'). -a.title=H2 Console -a.tools=Tools -a.user=Benutzername -admin.executing=Aktiv -admin.ip=IP -admin.lastAccess=Letzter Zugriff -admin.lastQuery=Letzter Befehl -admin.url=URL -adminAllow=Zugelassene Verbindungen -adminConnection=Verbindungs-Sicherheit -adminHttp=Unverschlüsselte HTTP Verbindungen -adminHttps=Verschlüsselte HTTPS Verbindungen -adminLocal=Nur lokale Verbindungen erlauben -adminLogin=Administration Login -adminLoginCancel=Abbrechen -adminLoginOk=OK -adminLogout=Beenden -adminOthers=Verbindungen von anderen Computern erlauben -adminPort=Port -adminPortWeb=Web-Server Port -adminRestart=Änderungen werden nach einem Neustart des Servers aktiv. -adminSave=Speichern -adminSessions=Aktive Verbindungen -adminShutdown=Shutdown -adminTitle=H2 Console Optionen -adminTranslateHelp=Die H2 Console übersetzen oder die Übersetzung verbessern. -adminTranslateStart=Übersetzen -helpAction=Aktion -helpAddAnotherRow=Fügt einen weiteren Datensatz hinzu -helpAddDrivers=Datenbank Treiber hinzufügen -helpAddDriversText=Es ist möglich zusätzliche Datenbank-Treiber zu laden, indem die Pfade der Treiber-Dateien in den Umgebungsvariablen H2DRIVERS oder CLASSPATH eingetragen werden. Beispiel (Windows): Um den Datenbank-Treiber mit dem Jar-File C:/Programs/hsqldb/lib/hsqldb.jar hinzuzufügen, setzen Sie den die Umgebungvariable H2DRIVERS auf C:/Programs/hsqldb/lib/hsqldb.jar. -helpAddRow=Fügt einen Datensatz hinzu -helpCommandHistory=Zeigt die Befehls-Chronik -helpCreateTable=Erzeugt eine neue Tabelle -helpDeleteRow=Entfernt einen Datensatz -helpDisconnect=Trennt die Verbindung zur Datenbank -helpDisplayThis=Zeigt diese Hilfe Seite -helpDropTable=Löscht die Tabelle falls es sie gibt -helpExecuteCurrent=Führt den aktuellen SQL Befehl aus -helpIcon=Schaltfläche -helpImportantCommands=Wichtige Befehle -helpOperations=Operationen -helpQuery=Fragt die Tabelle ab -helpSampleSQL=Beispiel SQL Skript -helpStatements=SQL Befehle -helpUpdate=Ändert Daten in einer Zeile -helpWithColumnsIdName=mit zwei Spalten -login.connect=Verbinden -login.driverClass=Datenbank-Treiber Klasse -login.driverNotFound=Datenbank-Treiber nicht gefunden
Für Informationen zum Hinzufügen von Treibern siehe Hilfe -login.goAdmin=Optionen -login.jdbcUrl=JDBC URL -login.language=Sprache -login.login=Login -login.remove=Entfernen -login.save=Speichern -login.savedSetting=Gespeicherte Einstellung -login.settingName=Einstellungs-Name -login.testConnection=Verbindung testen -login.testSuccessful=Test erfolgreich -login.welcome=H2 Console -result.1row=1 Datensatz -result.autoCommitOff=Auto-Commit ist jetzt ausgeschaltet -result.autoCommitOn=Auto-Commit ist jetzt eingeschaltet -result.bytes=Bytes -result.characters=Characters -result.maxrowsSet=Maximale Anzahl Zeilen ist jetzt gesetzt -result.noRows=keine Datensätze -result.noRunningStatement=Im Moment wird kein Befehl ausgeführt -result.rows=Datensätze -result.statementWasCanceled=Der Befehl wurde abgebrochen -result.updateCount=Änderungen -resultEdit.add=Hinzufügen -resultEdit.cancel=Abbrechen -resultEdit.delete=Löschen -resultEdit.edit=Bearbeiten -resultEdit.editResult=Bearbeiten -resultEdit.save=Speichern -toolbar.all=Alle -toolbar.autoCommit=Auto-Commit -toolbar.autoComplete=Auto-Complete -toolbar.autoComplete.full=Alles -toolbar.autoComplete.normal=Normal -toolbar.autoComplete.off=Aus -toolbar.cancelStatement=Laufenden Befehl abbrechen -toolbar.clear=Leeren -toolbar.commit=Commit (Abschliessen/Speichern) -toolbar.disconnect=Verbindung trennen -toolbar.history=Befehls-Chronik -toolbar.maxRows=Maximale Anzahl Zeilen -toolbar.refresh=Aktualisieren -toolbar.rollback=Rollback (Rückgängig) -toolbar.run=Ausführen (Strg+Enter) -toolbar.sqlStatement=SQL Befehl -tools.backup=Backup -tools.backup.help=Erzeugt eine Sichheitskopie eine Datenbank. -tools.changeFileEncryption=ChangeFileEncryption -tools.changeFileEncryption.help=Erlaubt, Datei Verschlüsselungs-Passwort und -Algorithmus einer Datenbank zu ändern. -tools.cipher=Verschlüsselung (AES oder XTEA) -tools.commandLine=Kommandozeile -tools.convertTraceFile=ConvertTraceFile -tools.convertTraceFile.help=Konvertiert eine .trace.db Datei in eine Java Applikation und ein SQL Script. -tools.createCluster=CreateCluster -tools.createCluster.help=Generiert ein Cluster aus einer autonomen Datenbank. -tools.databaseName=Datenbankname -tools.decryptionPassword=Entschlüsselungs-Passwort -tools.deleteDbFiles=DeleteDbFiles -tools.deleteDbFiles.help=Löscht alle Dateien die zu einer Datenbank gehören. -tools.directory=Verzeichnis -tools.encryptionPassword=Verschlüsselungs-Passwort -tools.javaDirectoryClassName=Java Verzeichnis- und Klassen-Name -tools.recover=Recover -tools.recover.help=Hilft bei der Reparatur eine beschädigten Datenbank. -tools.restore=Restore -tools.restore.help=Stellt eine Datenbank aus einem Backup her. -tools.result=Ergebnis -tools.run=Start -tools.runScript=RunScript -tools.runScript.help=Führt ein SQL Script aus. -tools.script=Script -tools.script.help=Generiert eine SQL Script einer Datenbank für Backup- und Migrationszwecke. -tools.scriptFileName=Script Dateiname -tools.serverList=Server List -tools.sourceDatabaseName=Quell-Datenbankname -tools.sourceDatabaseURL=Quell-Datenbank URL -tools.sourceDirectory=Quell-Verzeichnis -tools.sourceFileName=Quell-Dateiname -tools.sourceScriptFileName=Dateiname des Scripts (Quelle) -tools.targetDatabaseName=Ziel-Datenbankname -tools.targetDatabaseURL=Ziel-Datenbank URL -tools.targetDirectory=Ziel-Verzeichnis -tools.targetFileName=Ziel-Dateiname -tools.targetScriptFileName=Dateiname des Scripts (Ziel) -tools.traceFileName=Name der Trace Datei -tree.admin=Administrator -tree.current=Aktueller Wert -tree.hashed=Hash-basiert -tree.increment=Inkrement -tree.indexes=Indexe -tree.nonUnique=nicht eindeutig -tree.sequences=Sequenzen -tree.unique=eindeutig -tree.users=Benutzer diff --git a/tools/h2/src/main/org/h2/server/web/res/_text_en.prop b/tools/h2/src/main/org/h2/server/web/res/_text_en.prop deleted file mode 100755 index 79d0a33..0000000 --- a/tools/h2/src/main/org/h2/server/web/res/_text_en.prop +++ /dev/null @@ -1,149 +0,0 @@ -.translator=Thomas Mueller -a.help=Help -a.language=English -a.lynxNotSupported=Sorry, Lynx not supported yet -a.password=Password -a.remoteConnectionsDisabled=Sorry, remote connections ('webAllowOthers') are disabled on this server. -a.title=H2 Console -a.tools=Tools -a.user=User Name -admin.executing=Executing -admin.ip=IP -admin.lastAccess=Last Access -admin.lastQuery=Last Query -admin.url=URL -adminAllow=Allowed clients -adminConnection=Connection security -adminHttp=Use unencrypted HTTP connections -adminHttps=Use encrypted SSL (HTTPS) connections -adminLocal=Only allow local connections -adminLogin=Administration Login -adminLoginCancel=Cancel -adminLoginOk=OK -adminLogout=Logout -adminOthers=Allow connections from other computers -adminPort=Port number -adminPortWeb=Web server port number -adminRestart=Changes take effect after restarting the server. -adminSave=Save -adminSessions=Active Sessions -adminShutdown=Shutdown -adminTitle=H2 Console Preferences -adminTranslateHelp=Translate or improve the translation of the H2 Console. -adminTranslateStart=Translate -helpAction=Action -helpAddAnotherRow=Add another row -helpAddDrivers=Adding Database Drivers -helpAddDriversText=Additional database drivers can be registered by adding the Jar file location of the driver to the 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. -helpAddRow=Add a new row -helpCommandHistory=Shows the Command History -helpCreateTable=Create a new table -helpDeleteRow=Remove a row -helpDisconnect=Disconnects from the database -helpDisplayThis=Displays this Help Page -helpDropTable=Delete the table if it exists -helpExecuteCurrent=Executes the current SQL statement -helpIcon=Icon -helpImportantCommands=Important Commands -helpOperations=Operations -helpQuery=Query the table -helpSampleSQL=Sample SQL Script -helpStatements=SQL statements -helpUpdate=Change data in a row -helpWithColumnsIdName=with ID and NAME columns -login.connect=Connect -login.driverClass=Driver Class -login.driverNotFound=Database driver not found
See in the Help for how to add drivers -login.goAdmin=Preferences -login.jdbcUrl=JDBC URL -login.language=Language -login.login=Login -login.remove=Remove -login.save=Save -login.savedSetting=Saved Settings -login.settingName=Setting Name -login.testConnection=Test Connection -login.testSuccessful=Test successful -login.welcome=H2 Console -result.1row=1 row -result.autoCommitOff=Auto commit is now OFF -result.autoCommitOn=Auto commit is now ON -result.bytes=bytes -result.characters=characters -result.maxrowsSet=Max rowcount is set -result.noRows=no rows -result.noRunningStatement=There is currently no running statement -result.rows=rows -result.statementWasCanceled=The statement was canceled -result.updateCount=Update count -resultEdit.add=Add -resultEdit.cancel=Cancel -resultEdit.delete=Delete -resultEdit.edit=Edit -resultEdit.editResult=Edit -resultEdit.save=Save -toolbar.all=All -toolbar.autoCommit=Auto commit -toolbar.autoComplete=Auto complete -toolbar.autoComplete.full=Full -toolbar.autoComplete.normal=Normal -toolbar.autoComplete.off=Off -toolbar.cancelStatement=Cancel the current statement -toolbar.clear=Clear -toolbar.commit=Commit -toolbar.disconnect=Disconnect -toolbar.history=Command history -toolbar.maxRows=Max rows -toolbar.refresh=Refresh -toolbar.rollback=Rollback -toolbar.run=Run (Ctrl+Enter) -toolbar.sqlStatement=SQL statement -tools.backup=Backup -tools.backup.help=Creates a backup of a database. -tools.changeFileEncryption=ChangeFileEncryption -tools.changeFileEncryption.help=Allows changing the database file encryption password and algorithm. -tools.cipher=Cipher (AES or XTEA) -tools.commandLine=Command line -tools.convertTraceFile=ConvertTraceFile -tools.convertTraceFile.help=Converts a .trace.db file to a Java application and SQL script. -tools.createCluster=CreateCluster -tools.createCluster.help=Creates a cluster from a standalone database. -tools.databaseName=Database name -tools.decryptionPassword=Decryption password -tools.deleteDbFiles=DeleteDbFiles -tools.deleteDbFiles.help=Deletes all files belonging to a database. -tools.directory=Directory -tools.encryptionPassword=Encryption password -tools.javaDirectoryClassName=Java directory and class name -tools.recover=Recover -tools.recover.help=Helps recovering a corrupted database. -tools.restore=Restore -tools.restore.help=Restores a database backup. -tools.result=Result -tools.run=Run -tools.runScript=RunScript -tools.runScript.help=Runs a SQL script. -tools.script=Script -tools.script.help=Allows to convert a database to a SQL script for backup or migration. -tools.scriptFileName=Script file name -tools.serverList=Server list -tools.sourceDatabaseName=Source database name -tools.sourceDatabaseURL=Source database URL -tools.sourceDirectory=Source directory -tools.sourceFileName=Source file name -tools.sourceScriptFileName=Source script file name -tools.targetDatabaseName=Target database name -tools.targetDatabaseURL=Target database URL -tools.targetDirectory=Target directory -tools.targetFileName=Target file name -tools.targetScriptFileName=Target script file name -tools.traceFileName=Trace file name -tree.admin=Admin -tree.current=Current value -tree.hashed=Hashed -tree.increment=Increment -tree.indexes=Indexes -tree.nonUnique=Non unique -tree.sequences=Sequences -tree.unique=Unique -tree.users=Users diff --git a/tools/h2/src/main/org/h2/server/web/res/_text_es.prop b/tools/h2/src/main/org/h2/server/web/res/_text_es.prop deleted file mode 100755 index 81893d1..0000000 --- a/tools/h2/src/main/org/h2/server/web/res/_text_es.prop +++ /dev/null @@ -1,149 +0,0 @@ -.translator=Miguel Angel -a.help=Ayuda -a.language=Español -a.lynxNotSupported=Lo sentimos, Lynx no está soportado todavía -a.password=Contraseña -a.remoteConnectionsDisabled=Conexiones remotas desactivadas -a.title=H2 Console -a.tools=#Tools -a.user=Nombre de usuario -admin.executing=Ejecutando -admin.ip=IP -admin.lastAccess=Último acceso -admin.lastQuery=Última consulta -admin.url=URL -adminAllow=Clientes permitidos -adminConnection=Conexión segura -adminHttp=Usar conexiones HTTP desencriptadas -adminHttps=Usar conexiones HTTPS (SSL) encriptadas -adminLocal=Permitir únicamente conexiones locales -adminLogin=Registrar administración -adminLoginCancel=Cancelar -adminLoginOk=Aceptar -adminLogout=Desconectar -adminOthers=Permitir conexiones desde otros ordenadores -adminPort=Puerto -adminPortWeb=Puerto del servidor Web -adminRestart=Los cambios tendrán efecto al reiniciar el servidor. -adminSave=Guardar -adminSessions=Sesiones activas -adminShutdown=Parar servidor -adminTitle=Preferencias de H2 Consola -adminTranslateHelp=#Translate or improve the translation of the H2 Console. -adminTranslateStart=#Translate -helpAction=Action -helpAddAnotherRow=Añadir otra fila -helpAddDrivers=Añadiendo drivers de base de datos -helpAddDriversText=Se pueden registrar otros drivers añadiendo el archivo Jar del driver a la variable de entorno H2DRIVERS o CLASSPATH. Por ejemplo (Windows): Para añadir la librería del driver de base de datos C:/Programs/hsqldb/lib/hsqldb.jar, hay que establecer la variable de entorno H2DRIVERS a C:/Programs/hsqldb/lib/hsqldb.jar. -helpAddRow=Añadir una fila nueva -helpCommandHistory=Ver histórico de comandos -helpCreateTable=Crear una tabla nueva -helpDeleteRow=Borrar una fila -helpDisconnect=Desconectar de la base de datos. -helpDisplayThis=Visualizar esta página de ayuda. -helpDropTable=Borrar la tabla si existe -helpExecuteCurrent=Ejecuta la actual sentencia SQL -helpIcon=Icon -helpImportantCommands=Comandos importantes -helpOperations=Operaciones -helpQuery=Consulta la tabla -helpSampleSQL=Ejemplo SQL Script -helpStatements=Sentencias SQL -helpUpdate=Modificar datos en una fila -helpWithColumnsIdName=con las columnas ID y NAME -login.connect=Conectar -login.driverClass=Controlador -login.driverNotFound=Controlador no encontrado -login.goAdmin=Preferencias -login.jdbcUrl=URL JDBC -login.language=Idioma -login.login=Registrar -login.remove=Eliminar -login.save=Guardar -login.savedSetting=Configuraciones guardadas -login.settingName=Nombre de la configuración -login.testConnection=Probar la conexión -login.testSuccessful=Prueba correcta -login.welcome=H2 Consola -result.1row=1 fila -result.autoCommitOff=El auto commit no está activo -result.autoCommitOn=El auto commit está activo -result.bytes=#bytes -result.characters=#characters -result.maxrowsSet=Número máximo de filas modificado -result.noRows=No se han recuperado filas -result.noRunningStatement=No hay una instrucción ejecutándose -result.rows=filas -result.statementWasCanceled=La instrucción fue cancelada -result.updateCount=Modificaciones -resultEdit.add=Añadir -resultEdit.cancel=Cancelar -resultEdit.delete=Eliminar -resultEdit.edit=Editar -resultEdit.editResult=Editar -resultEdit.save=Guardar -toolbar.all=Todos -toolbar.autoCommit=Auto commit -toolbar.autoComplete=Auto completado -toolbar.autoComplete.full=Completo -toolbar.autoComplete.normal=Normal -toolbar.autoComplete.off=Desactivado -toolbar.cancelStatement=Cancelar la instrucción actual -toolbar.clear=Eliminar -toolbar.commit=Commit -toolbar.disconnect=Desconectar -toolbar.history=Histórico comandos -toolbar.maxRows=Número máximo de filas -toolbar.refresh=Actualizar -toolbar.rollback=Rollback -toolbar.run=Ejecutar (Ctrl+Enter) -toolbar.sqlStatement=Instrucción SQL -tools.backup=#Backup -tools.backup.help=#Creates a backup of a database. -tools.changeFileEncryption=#ChangeFileEncryption -tools.changeFileEncryption.help=#Allows changing the database file encryption password and algorithm. -tools.cipher=#Cipher (AES or XTEA) -tools.commandLine=#Command line -tools.convertTraceFile=#ConvertTraceFile -tools.convertTraceFile.help=#Converts a .trace.db file to a Java application and SQL script. -tools.createCluster=#CreateCluster -tools.createCluster.help=#Creates a cluster from a standalone database. -tools.databaseName=#Database name -tools.decryptionPassword=#Decryption password -tools.deleteDbFiles=#DeleteDbFiles -tools.deleteDbFiles.help=#Deletes all files belonging to a database. -tools.directory=#Directory -tools.encryptionPassword=#Encryption password -tools.javaDirectoryClassName=#Java directory and class name -tools.recover=#Recover -tools.recover.help=#Helps recovering a corrupted database. -tools.restore=#Restore -tools.restore.help=#Restores a database backup. -tools.result=#Result -tools.run=#Run -tools.runScript=#RunScript -tools.runScript.help=#Runs a SQL script. -tools.script=#Script -tools.script.help=#Allows to convert a database to a SQL script for backup or migration. -tools.scriptFileName=#Script file name -tools.serverList=#Server list -tools.sourceDatabaseName=#Source database name -tools.sourceDatabaseURL=#Source database URL -tools.sourceDirectory=#Source directory -tools.sourceFileName=#Source file name -tools.sourceScriptFileName=#Source script file name -tools.targetDatabaseName=#Target database name -tools.targetDatabaseURL=#Target database URL -tools.targetDirectory=#Target directory -tools.targetFileName=#Target file name -tools.targetScriptFileName=#Target script file name -tools.traceFileName=#Trace file name -tree.admin=Administrador -tree.current=Valor actual -tree.hashed=Hash -tree.increment=Incremento -tree.indexes=Índices -tree.nonUnique=No único -tree.sequences=Secuencias -tree.unique=Único -tree.users=Usuarios diff --git a/tools/h2/src/main/org/h2/server/web/res/_text_fr.prop b/tools/h2/src/main/org/h2/server/web/res/_text_fr.prop deleted file mode 100755 index 63ea8db..0000000 --- a/tools/h2/src/main/org/h2/server/web/res/_text_fr.prop +++ /dev/null @@ -1,149 +0,0 @@ -.translator=Olivier Parent -a.help=Aide -a.language=Français -a.lynxNotSupported=Désolé, Lynx n'est pas encore supporté -a.password=Mot de passe -a.remoteConnectionsDisabled=Désolé, la gestion des connexions provenant de machines distantes est désactivée sur ce serveur ('webAllowOthers'). -a.title=Console H2 -a.tools=Outils -a.user=Nom d'utilisateur -admin.executing=Exécution en cours -admin.ip=Adresse IP -admin.lastAccess=Dernier accès -admin.lastQuery=Dernière requête -admin.url=URL -adminAllow=Clients autorisés -adminConnection=Sécurité des connexions -adminHttp=Utiliser des connexions HTTP non sécurisées -adminHttps=Utiliser des connexions sécurisées -adminLocal=Autoriser uniquement les connexions locales -adminLogin=Login administrateur -adminLoginCancel=Annuler -adminLoginOk=OK -adminLogout=Déconnexion -adminOthers=Autoriser les connexions d'ordinateurs distants -adminPort=Numéro de port -adminPortWeb=Numéro de port du serveur Web -adminRestart=Modifications effectuées après redémarrage du serveur. -adminSave=Enregistrer -adminSessions=Sessions actives -adminShutdown=Arrêt -adminTitle=Console H2 de paramétrage des options -adminTranslateHelp=#Translate or improve the translation of the H2 Console. -adminTranslateStart=#Translate -helpAction=Action -helpAddAnotherRow=Ajouter un autre enregistrement -helpAddDrivers=Ajouter des pilotes de base de données -helpAddDriversText=Des pilotes additionels peuvent être configurés en déclarant l'emplacement du fichier Jar contenant ces pilotes dans les variables d'environnement H2DRIVERS ou CLASSPATH. Exemple (Windows): Pour ajouter la bibliothèque C:/Programs/hsqldb/lib/hsqldb.jar, définir la valeur de la variable d'environnement H2DRIVERS en C:/Programs/hsqldb/lib/hsqldb.jar. -helpAddRow=Ajouter un nouvel enregistrement -helpCommandHistory=Affiche l'historique des commandes -helpCreateTable=Créer une nouvelle table -helpDeleteRow=Effacer un enregistrement -helpDisconnect=Déconnexion de la base de données -helpDisplayThis=Affiche cette page d'aide -helpDropTable=Effacer une table si elle existe -helpExecuteCurrent=Exécute la commande courante -helpIcon=Icone -helpImportantCommands=Commandes principales -helpOperations=Opérations -helpQuery=Requêter une table -helpSampleSQL=Exemple de script SQL -helpStatements=Instructions SQL -helpUpdate=Modifier un enregistrement -helpWithColumnsIdName=avec les colonnes ID et NAME -login.connect=Connecter -login.driverClass=Pilote JDBC -login.driverNotFound=Pilote non trouvé.
Veuillez consulter dans l'aide la procédure d'ajout de pilotes. -login.goAdmin=Options -login.jdbcUrl=URL JDBC -login.language=Langue -login.login=Connexion -login.remove=Supprimer -login.save=Enregistrer -login.savedSetting=Configuration enregistrée -login.settingName=Nom de configuration -login.testConnection=Test de connexion -login.testSuccessful=Succès -login.welcome=Console H2 -result.1row=1 enregistrement -result.autoCommitOff=Validation automatique non activée -result.autoCommitOn=Validation automatique activée -result.bytes=#bytes -result.characters=#characters -result.maxrowsSet=Nombre max d'enregistrements défini -result.noRows=Aucun enregistrement -result.noRunningStatement=Pas d'instruction en cours -result.rows=enregistrements -result.statementWasCanceled=L'instruction a été annulée -result.updateCount=Nombre de modifications -resultEdit.add=Ajouter -resultEdit.cancel=Annuler -resultEdit.delete=Supprimer -resultEdit.edit=Editer -resultEdit.editResult=Editer -resultEdit.save=Enregistrer -toolbar.all=Tous -toolbar.autoCommit=Validation automatique (auto commit) -toolbar.autoComplete=Complètement automatique -toolbar.autoComplete.full=Exhaustif -toolbar.autoComplete.normal=Normal -toolbar.autoComplete.off=Désactivé -toolbar.cancelStatement=Annuler l'instruction en cours -toolbar.clear=Effacer -toolbar.commit=Valider -toolbar.disconnect=Déconnecter -toolbar.history=Historique des instructions -toolbar.maxRows=Max lignes -toolbar.refresh=Rafraîchir -toolbar.rollback=Revenir en arrière -toolbar.run=Exécuter (Ctrl+Enter) -toolbar.sqlStatement=Instruction SQL -tools.backup=Sauvegarde -tools.backup.help=Crée une sauvegarde de base de données. -tools.changeFileEncryption=Modifier le chiffrement -tools.changeFileEncryption.help=Permet la modification du mot de passe et de l'algorithme de chiffrement des fichiers de base de données. -tools.cipher=Chiffrement (AES ou XTEA) -tools.commandLine=Ligne de commande -tools.convertTraceFile=Convertir le fichier trace -tools.convertTraceFile.help=Convertit un fichier .trace.db en une application Java ou un script SQL. -tools.createCluster=Créer une grappe de serveurs -tools.createCluster.help=Crée une grappe de serveurs depuis une base de données autonome. -tools.databaseName=Nom de la base de données -tools.decryptionPassword=Mot de passe de déchiffrement -tools.deleteDbFiles=Supprimer les fichiers -tools.deleteDbFiles.help=Supprime tous les fichiers appartenant à une base de données -tools.directory=Répertoire -tools.encryptionPassword=Mot de passe de chiffrement -tools.javaDirectoryClassName=Répertoire Java et nom de classe -tools.recover=Réparation -tools.recover.help=Aide la réparation d'une base de données corrompue -tools.restore=Restauration -tools.restore.help=Restaure une sauvegarde de base de données. -tools.result=Résultat -tools.run=Exécuter -tools.runScript=Exécuter le script -tools.runScript.help=Exécute un script SQL. -tools.script=Script -tools.script.help=Convertit une base de données en script SQL pour une sauvegarde ou une migration. -tools.scriptFileName=Nom du fichier de script -tools.serverList=Liste des serveurs -tools.sourceDatabaseName=Base de données source -tools.sourceDatabaseURL=URL base de données source -tools.sourceDirectory=Répertoire source -tools.sourceFileName=Nom de fichier source -tools.sourceScriptFileName=Nom du fichier script source -tools.targetDatabaseName=Base de données cible -tools.targetDatabaseURL=URL base de données cible -tools.targetDirectory=Répertoire cible -tools.targetFileName=Nom de fichier cible -tools.targetScriptFileName=Nom de fichier script cible -tools.traceFileName=Nom du fichier de trace -tree.admin=Administrateur -tree.current=Valeur actuelle -tree.hashed=Haché (hashed) -tree.increment=Incrément -tree.indexes=Index -tree.nonUnique=Non unique -tree.sequences=Séquences -tree.unique=Unique -tree.users=Utilisateurs diff --git a/tools/h2/src/main/org/h2/server/web/res/_text_hu.prop b/tools/h2/src/main/org/h2/server/web/res/_text_hu.prop deleted file mode 100755 index 5fdc042..0000000 --- a/tools/h2/src/main/org/h2/server/web/res/_text_hu.prop +++ /dev/null @@ -1,149 +0,0 @@ -.translator=Andras Hideg -a.help=Súgó -a.language=Magyar -a.lynxNotSupported=A Lynx böngésző egyelőre nem támogatott -a.password=Jelszó -a.remoteConnectionsDisabled=Ezen a kiszolgálón távoli kapcsolatok ('webAllowOthers') nem engedélyezettek. -a.title=H2 konzol -a.tools=#Tools -a.user=Felhasználónév -admin.executing=Utasítás végrehajtása -admin.ip=IP -admin.lastAccess=Legutóbbi hozzáférés -admin.lastQuery=Legutóbbi lekérdezés -admin.url=URL -adminAllow=Engedélyezett ügyfelek -adminConnection=Kapcsolatbiztonság -adminHttp=Titkosítatlan HTTP kapcsolatok használata -adminHttps=Titkosított SSL (HTTPS) kapcsolatok használata -adminLocal=Csak helyi kapcsolatok engedélyezése -adminLogin=Adminisztrációs bejelentkezés -adminLoginCancel=Mégse -adminLoginOk=OK -adminLogout=Kilépés -adminOthers=Más számítógépekről kezdeményezett kapcsolatok engedélyezése -adminPort=#Port number -adminPortWeb=Webkiszolgáló portszáma -adminRestart=A változtatások a kiszolgáló újraindítása után lépnek érvénybe -adminSave=Mentés -adminSessions=Aktív munkamenetek -adminShutdown=Leállítás -adminTitle=H2 Konzol tulajdonságai -adminTranslateHelp=#Translate or improve the translation of the H2 Console. -adminTranslateStart=#Translate -helpAction=Parancs -helpAddAnotherRow=Rekord hozzáadása -helpAddDrivers=Adatbázis-illesztőprogramok hozzáadása -helpAddDriversText=További adatbázis-illesztőprogramok regisztrálásakor a H2DRIVERS vagy CLASSPATH környezeti változókhoz kell adni a .jar illesztőprogram-fájlok elérési útvonalait. Például (Windows esetén) a C:/Programs/hsqldb/lib/hsqldb.jar illesztőprogram regisztrálásához a H2DRIVERS környezeti változónak az alábbi értékét kell megadni: C:/Programs/hsqldb/lib/hsqldb.jar -helpAddRow=Rekord hozzáadása -helpCommandHistory=Korábbi utasítások megjelenítése -helpCreateTable=Új tábla létrehozása -helpDeleteRow=rekord törlése -helpDisconnect=Kapcsolat megszakítása az adatbázissal -helpDisplayThis=Súgó megjelenítése -helpDropTable=Tábla törlése, ha az létezik -helpExecuteCurrent=Aktuális SQL utasítás végrehajtása -helpIcon=Ikon -helpImportantCommands=Fontos utasítások -helpOperations=Műveletek -helpQuery=Tábla lekérdezése -helpSampleSQL=Minta SQL szkript -helpStatements=SQL utasítások -helpUpdate=Adatok módosítása egy rekordon belül -helpWithColumnsIdName=ID és NAME oszlopokkal -login.connect=Csatlakozás -login.driverClass=Illesztőprogram osztály -login.driverNotFound=Adatbázis-illesztőprogram nem található
Illesztőprogramok hozzáadásáról a Súgó ad felvilágosítást. -login.goAdmin=Tulajdonságok -login.jdbcUrl=JDBC URL -login.language=Nyelv -login.login=Belépés -login.remove=Eltávolítás -login.save=Mentés -login.savedSetting=Mentett beállítások -login.settingName=Beállítás neve -login.testConnection=Kapcsolat tesztelése -login.testSuccessful=Kapcsolat tesztelése sikeres volt -login.welcome=H2 konzol -result.1row=1 rekord -result.autoCommitOff=Automatikus jóváhagyás kikapcsolva -result.autoCommitOn=Automatikus jóváhagyás bekapcsolva -result.bytes=#bytes -result.characters=#characters -result.maxrowsSet=Rekordok maximális száma beállítva -result.noRows=nincs rekord -result.noRunningStatement=Utasítás jelenleg nincs folyamatban -result.rows=rekordok -result.statementWasCanceled=Az utasítás végrehajtása megszakadt -result.updateCount=Frissítés -resultEdit.add=Hozzáadás -resultEdit.cancel=Mégse -resultEdit.delete=Törlés -resultEdit.edit=Szerkesztés -resultEdit.editResult=Szerkesztés -resultEdit.save=Mentés -toolbar.all=Mind -toolbar.autoCommit=Automatikus jóváhagyás -toolbar.autoComplete=Automatikus kiegészítés -toolbar.autoComplete.full=Teljes -toolbar.autoComplete.normal=Normál -toolbar.autoComplete.off=Kikapcsolva -toolbar.cancelStatement=Aktuális utasítás végrehajtásának megszakítása -toolbar.clear=Törlés -toolbar.commit=Jóváhagyás -toolbar.disconnect=Kapcsolat bontása -toolbar.history=Korábbi utasítások -toolbar.maxRows=Rekordok maximális száma -toolbar.refresh=Frissítés -toolbar.rollback=Visszagörgetés -toolbar.run=Végrehajtás (Ctrl+Enter) -toolbar.sqlStatement=SQL utasítás -tools.backup=#Backup -tools.backup.help=#Creates a backup of a database. -tools.changeFileEncryption=#ChangeFileEncryption -tools.changeFileEncryption.help=#Allows changing the database file encryption password and algorithm. -tools.cipher=#Cipher (AES or XTEA) -tools.commandLine=#Command line -tools.convertTraceFile=#ConvertTraceFile -tools.convertTraceFile.help=#Converts a .trace.db file to a Java application and SQL script. -tools.createCluster=#CreateCluster -tools.createCluster.help=#Creates a cluster from a standalone database. -tools.databaseName=#Database name -tools.decryptionPassword=#Decryption password -tools.deleteDbFiles=#DeleteDbFiles -tools.deleteDbFiles.help=#Deletes all files belonging to a database. -tools.directory=#Directory -tools.encryptionPassword=#Encryption password -tools.javaDirectoryClassName=#Java directory and class name -tools.recover=#Recover -tools.recover.help=#Helps recovering a corrupted database. -tools.restore=#Restore -tools.restore.help=#Restores a database backup. -tools.result=#Result -tools.run=#Run -tools.runScript=#RunScript -tools.runScript.help=#Runs a SQL script. -tools.script=#Script -tools.script.help=#Allows to convert a database to a SQL script for backup or migration. -tools.scriptFileName=#Script file name -tools.serverList=#Server list -tools.sourceDatabaseName=#Source database name -tools.sourceDatabaseURL=#Source database URL -tools.sourceDirectory=#Source directory -tools.sourceFileName=#Source file name -tools.sourceScriptFileName=#Source script file name -tools.targetDatabaseName=#Target database name -tools.targetDatabaseURL=#Target database URL -tools.targetDirectory=#Target directory -tools.targetFileName=#Target file name -tools.targetScriptFileName=#Target script file name -tools.traceFileName=#Trace file name -tree.admin=Adminisztrátor -tree.current=Aktuális érték -tree.hashed=Hash-értékkel ellátott -tree.increment=Inkrementált -tree.indexes=Indexek -tree.nonUnique=Nem egyedi -tree.sequences=Szekvencia -tree.unique=Egyedi -tree.users=Felhasználók diff --git a/tools/h2/src/main/org/h2/server/web/res/_text_in.prop b/tools/h2/src/main/org/h2/server/web/res/_text_in.prop deleted file mode 100755 index 3e0d385..0000000 --- a/tools/h2/src/main/org/h2/server/web/res/_text_in.prop +++ /dev/null @@ -1,149 +0,0 @@ -.translator=Joko Yuliantoro -a.help=Bantuan -a.language=Indonesia -a.lynxNotSupported=Maaf, Lynx belum didukung. Gunakan browser yang mendukung Javascript (dan Frame). -a.password=Kata kunci -a.remoteConnectionsDisabled=Maaf, fungsi koneksi jarak jauh ('webAllowOthers') dimatikan pada server ini. -a.title=Konsol H2 -a.tools=#Tools -a.user=Nama pengguna -admin.executing=Sedang eksekusi -admin.ip=IP -admin.lastAccess=Akses Terakhir -admin.lastQuery=Kueri Terakhir -admin.url=URL -adminAllow=Klien terijin -adminConnection=Keamanan koneksi -adminHttp=Gunakan koneksi HTTP tidak terenkripsi -adminHttps=Gunakan koneksi SSL terenkripsi (HTTPS) -adminLocal=Hanya ijinkan koneksi lokal -adminLogin=Login Pengelola -adminLoginCancel=Batal -adminLoginOk=OK -adminLogout=Keluar -adminOthers=Ijinkan koneksi dari komputer lain -adminPort=Nomor port -adminPortWeb=Nomor port web server -adminRestart=Perubahan akan efektif setelah server di-restart. -adminSave=Simpan -adminSessions=Sesi aktif -adminShutdown=Matikan -adminTitle=Pilihan di Konsol H2 -adminTranslateHelp=#Translate or improve the translation of the H2 Console. -adminTranslateStart=#Translate -helpAction=Aksi -helpAddAnotherRow=Menambah sebuah baris -helpAddDrivers=Menambah pengendali basis data -helpAddDriversText=Pengendali basis data tambahan dapat didaftarkan dengan cara menambah lokasi file Jar dari si pengendali ke variabel lingkungan H2DRIVERS atau CLASSPATH. Contoh (Windows): Untuk menambah librari pengendali basis data C:/Programs/hsqldb/lib/hsqldb.jar, atur variabel lingkungan H2DRIVERS menjadi C:/Programs/hsqldb/lib/hsqldb.jar. -helpAddRow=Tambah sebuah baris baru -helpCommandHistory=Tampilkan sejarah perintah -helpCreateTable=Ciptakan sebuah tabel -helpDeleteRow=Buang sebuah baris -helpDisconnect=Putuskan koneksi dari basis data -helpDisplayThis=Tampilkan laman bantuan ini -helpDropTable=Hapus tabel jika sudah ada -helpExecuteCurrent=Jalankan pernyataan SQL terkini -helpIcon=Ikon -helpImportantCommands=Perintah penting -helpOperations=Operasi -helpQuery=Kueri ke tabel -helpSampleSQL=Contoh skrip SQL -helpStatements=Pernyataan SQL -helpUpdate=Rubah data dalam sebuah baris -helpWithColumnsIdName=dengan kolom ID dan NAME -login.connect=Hubungkan -login.driverClass=Kelas Pengendali -login.driverNotFound=Pengendali basis data tidak ditemukan
Pelajari bagian Bantuan untuk mengetahui bagaimana cara menambah pengendali basis data -login.goAdmin=Pilihan -login.jdbcUrl=JDBC URL -login.language=Bahasa -login.login=Login -login.remove=Buang -login.save=Simpan -login.savedSetting=Pengaturan tersimpan -login.settingName=Nama pengaturan -login.testConnection=Tes koneksi -login.testSuccessful=Tes berhasil -login.welcome=Konsol H2 -result.1row=1 baris -result.autoCommitOff=Autocommit sekarang OFF -result.autoCommitOn=Autocommit sekarang ON -result.bytes=#bytes -result.characters=#characters -result.maxrowsSet=Hitungan baris maksimum terpasang -result.noRows=Tidak ada hasil -result.noRunningStatement=Saat ini tidak ada pernyataan yang beroperasi -result.rows=baris -result.statementWasCanceled=Pernyataan tersebut dibatalkan -result.updateCount=Perbarui Hitungan -resultEdit.add=Tambah -resultEdit.cancel=Batal -resultEdit.delete=Hapus -resultEdit.edit=Ubah -resultEdit.editResult=Ubah -resultEdit.save=Simpan -toolbar.all=Semua -toolbar.autoCommit=Autocommit -toolbar.autoComplete=Auto-Complete -toolbar.autoComplete.full=Full -toolbar.autoComplete.normal=Normal -toolbar.autoComplete.off=Off -toolbar.cancelStatement=Batalkan pernyataan terkini -toolbar.clear=Bersihkan -toolbar.commit=Laksanakan -toolbar.disconnect=Putuskan koneksi -toolbar.history=Sejarah perintah -toolbar.maxRows=Baris maksimum -toolbar.refresh=Segarkan -toolbar.rollback=Gulung mundur -toolbar.run=Jalankan (Ctrl+Enter) -toolbar.sqlStatement=Pernyataan SQL -tools.backup=#Backup -tools.backup.help=#Creates a backup of a database. -tools.changeFileEncryption=#ChangeFileEncryption -tools.changeFileEncryption.help=#Allows changing the database file encryption password and algorithm. -tools.cipher=#Cipher (AES or XTEA) -tools.commandLine=#Command line -tools.convertTraceFile=#ConvertTraceFile -tools.convertTraceFile.help=#Converts a .trace.db file to a Java application and SQL script. -tools.createCluster=#CreateCluster -tools.createCluster.help=#Creates a cluster from a standalone database. -tools.databaseName=#Database name -tools.decryptionPassword=#Decryption password -tools.deleteDbFiles=#DeleteDbFiles -tools.deleteDbFiles.help=#Deletes all files belonging to a database. -tools.directory=#Directory -tools.encryptionPassword=#Encryption password -tools.javaDirectoryClassName=#Java directory and class name -tools.recover=#Recover -tools.recover.help=#Helps recovering a corrupted database. -tools.restore=#Restore -tools.restore.help=#Restores a database backup. -tools.result=#Result -tools.run=#Run -tools.runScript=#RunScript -tools.runScript.help=#Runs a SQL script. -tools.script=#Script -tools.script.help=#Allows to convert a database to a SQL script for backup or migration. -tools.scriptFileName=#Script file name -tools.serverList=#Server list -tools.sourceDatabaseName=#Source database name -tools.sourceDatabaseURL=#Source database URL -tools.sourceDirectory=#Source directory -tools.sourceFileName=#Source file name -tools.sourceScriptFileName=#Source script file name -tools.targetDatabaseName=#Target database name -tools.targetDatabaseURL=#Target database URL -tools.targetDirectory=#Target directory -tools.targetFileName=#Target file name -tools.targetScriptFileName=#Target script file name -tools.traceFileName=#Trace file name -tree.admin=Admin -tree.current=Nilai terkini -tree.hashed=Hashed -tree.increment=Penambahan -tree.indexes=Indeks -tree.nonUnique=Tidak-Unik -tree.sequences=Urut-urutan -tree.unique=Unik -tree.users=Para pengguna diff --git a/tools/h2/src/main/org/h2/server/web/res/_text_it.prop b/tools/h2/src/main/org/h2/server/web/res/_text_it.prop deleted file mode 100755 index 8912ef3..0000000 --- a/tools/h2/src/main/org/h2/server/web/res/_text_it.prop +++ /dev/null @@ -1,149 +0,0 @@ -.translator=PierPaolo Ucchino -a.help=Aiuto -a.language=Italiano -a.lynxNotSupported=Spiacente, Lynx non è al momento supportato -a.password=Password -a.remoteConnectionsDisabled=Spiacente, le connessioni remote ('webAllowOthers') sono disabilitate su questo server. -a.title=H2 Pannello di controllo -a.tools=Accessori -a.user=Nome utente -admin.executing=Esecuzione in corso -admin.ip=IP -admin.lastAccess=Ultimo accesso -admin.lastQuery=Ultima query -admin.url=URL -adminAllow=Client abilitati -adminConnection=Sicurezza della connessione -adminHttp=Usa connessioni HTTP non criptate -adminHttps=Usa connessioni criptate con SSL (HTTPS) -adminLocal=Abilita solo connessioni locali -adminLogin=Accesso amministratore -adminLoginCancel=Annulla -adminLoginOk=OK -adminLogout=Disconnessione -adminOthers=Abilita connessioni da altri computers -adminPort=Numero di porta -adminPortWeb=Numero di porta del server Web -adminRestart=Le modifiche saranno effettive dopo il riavvio del server. -adminSave=Salva -adminSessions=Connessioni attive -adminShutdown=Shutdown -adminTitle=Pannello di controllo preferenze H2 -adminTranslateHelp=Traduci o modifica la traduzione della console di H2. -adminTranslateStart=Traduci -helpAction=Azione -helpAddAnotherRow=Aggiunge un'altra riga -helpAddDrivers=Aggiunta di altri driver per l'accesso al database -helpAddDriversText=I drivers per il database possono essere inseriti aggiungendo la posizione del file Jar del driver stesso alle variabili di ambiente H2DRIVERS o CLASSPATH. Esempio (Windows): Per aggiungere alla libreria il drivers per il database C:/Programs/hsqldb/lib/hsqldb.jar, basta modificare la variabile di ambiente H2DRIVERS in C:/Programs/hsqldb/lib/hsqldb.jar. -helpAddRow=Aggiunge una nuova riga -helpCommandHistory=Mostra l'elenco dei comandi eseguiti -helpCreateTable=Crea una nuova tabella -helpDeleteRow=Rimuove una riga -helpDisconnect=Disconnette dal database -helpDisplayThis=Mostra questa pagina di aiuto -helpDropTable=Cancella la tabella se esiste -helpExecuteCurrent=Esegue il corrente comando SQL -helpIcon=Icona -helpImportantCommands=Comandi importanti -helpOperations=Operazioni -helpQuery=Seleziona tutto dalla tabella -helpSampleSQL=Programma SQL di esempio -helpStatements=Comandi SQL -helpUpdate=Cambia dei dati in una riga -helpWithColumnsIdName=tramite ID e NOME colonne -login.connect=Connetti -login.driverClass=Classe driver -login.driverNotFound=Il driver del database non è stato trovato
Guardare in Aiuto su come aggiungere dei drivers -login.goAdmin=Preferenze -login.jdbcUrl=JDBC URL -login.language=Lingua -login.login=Accesso -login.remove=Rimuovi -login.save=Salva -login.savedSetting=Configurazioni salvate -login.settingName=Nome configurazione -login.testConnection=Prova la connessione -login.testSuccessful=Connessione riuscita -login.welcome=Pannello di controllo H2 -result.1row=1 riga -result.autoCommitOff=Auto inserimento adesso e' disattivo -result.autoCommitOn=Auto inserimento adesso e' attivo -result.bytes=#bytes -result.characters=#characters -result.maxrowsSet=Il numero massimo di righe e' stato impostato -result.noRows=nessuna riga -result.noRunningStatement=C'e' un comando in corso di esecuzione -result.rows=righe -result.statementWasCanceled=Il comando e' stato annullato -result.updateCount=Aggiorna il risultato -resultEdit.add=Aggiungi -resultEdit.cancel=Annulla -resultEdit.delete=Cancella -resultEdit.edit=Modifica -resultEdit.editResult=Modifica -resultEdit.save=Salva -toolbar.all=Tutto -toolbar.autoCommit=Auto inserimento -toolbar.autoComplete=Auto completamento -toolbar.autoComplete.full=Pieno -toolbar.autoComplete.normal=Normale -toolbar.autoComplete.off=Disattivo -toolbar.cancelStatement=Annulla il seguente comando -toolbar.clear=Annulla -toolbar.commit=Esegui comando -toolbar.disconnect=Disconnetti -toolbar.history=Comandi eseguiti -toolbar.maxRows=Massimo numero righe -toolbar.refresh=Aggiorna -toolbar.rollback=Annulla comando -toolbar.run=Esegui (Ctrl+Invio) -toolbar.sqlStatement=Comando SQL -tools.backup=Backup -tools.backup.help=Crea un backup del database. -tools.changeFileEncryption=Cambia cifratura del file -tools.changeFileEncryption.help=Permette il cambiamento della password e dell'algoritmo di cifratura del database. -tools.cipher=Cifratura (AES or XTEA) -tools.commandLine=Linea di comando -tools.convertTraceFile=Converti il file di tracciamento -tools.convertTraceFile.help=Converte un file .trace.db in una applicazione java e uno script SQL. -tools.createCluster=Crea un cluster -tools.createCluster.help=Crea un cluster da un database standalone. -tools.databaseName=Nome del database -tools.decryptionPassword=Password per la decifratura -tools.deleteDbFiles=Cancella files del database -tools.deleteDbFiles.help=Cancella tutti i files appartenenti a un database. -tools.directory=Directory -tools.encryptionPassword=Password di cifratura -tools.javaDirectoryClassName=Directory java e nome della classe -tools.recover=Recupera -tools.recover.help=Aiuta a recuperare un database corrotto. -tools.restore=Ripristina -tools.restore.help=Ripristina un backup di un database. -tools.result=Risultato -tools.run=Esegui -tools.runScript=Esegui script -tools.runScript.help=Esegui script SQL. -tools.script=Script -tools.script.help=Permette la conversione di un database in uno script SQL per un backup o una migrazione. -tools.scriptFileName=Nome del file di script -tools.serverList=Lista dei servers -tools.sourceDatabaseName=Nome del database sorgente -tools.sourceDatabaseURL=URL del database sorgente -tools.sourceDirectory=Directory sorgente -tools.sourceFileName=Nome del file sorgente -tools.sourceScriptFileName=Nome del file script sorgente -tools.targetDatabaseName=Nome del database destinazione -tools.targetDatabaseURL=URL del database destinazione -tools.targetDirectory=Directory destinazione -tools.targetFileName=Nome del file destinazione -tools.targetScriptFileName=Nome del file di script destinazione -tools.traceFileName=Nome del file di traccia -tree.admin=Amministratore -tree.current=Valore corrente -tree.hashed=Valore hash -tree.increment=Incremento -tree.indexes=Indici -tree.nonUnique=Non unico -tree.sequences=Sequenze -tree.unique=Unico -tree.users=Utenti diff --git a/tools/h2/src/main/org/h2/server/web/res/_text_ja.prop b/tools/h2/src/main/org/h2/server/web/res/_text_ja.prop deleted file mode 100755 index 0b2eece..0000000 --- a/tools/h2/src/main/org/h2/server/web/res/_text_ja.prop +++ /dev/null @@ -1,149 +0,0 @@ -.translator=IKEMOTO, Masahiro -a.help=ヘルプ -a.language=日本語 -a.lynxNotSupported=Lynxにはまだ対応していません -a.password=パスワード -a.remoteConnectionsDisabled=このサーバでは、リモート接続('webAllowOthers')が有効になっていません。 -a.title=H2コンソール -a.tools=ツール -a.user=ユーザ名 -admin.executing=実行中 -admin.ip=IP -admin.lastAccess=最終アクセス -admin.lastQuery=最終問い合せ -admin.url=URL -adminAllow=クライアント接続許可 -adminConnection=接続セキュリティ -adminHttp=暗号化されない HTTP 接続を使用 -adminHttps=暗号化された SSL (HTTPS) 接続を使用 -adminLocal=ローカル接続のみ許可 -adminLogin=管理者ログイン -adminLoginCancel=キャンセル -adminLoginOk=OK -adminLogout=ログアウト -adminOthers=他のコンピュータからの接続を許可 -adminPort=ポート番号 -adminPortWeb=Webサーバポート番号 -adminRestart=変更はサーバの再起動後に有効になります。 -adminSave=保存 -adminSessions=アクティブセッション -adminShutdown=シャットダウン -adminTitle=H2コンソール設定 -adminTranslateHelp=H2コンソールの日本語訳を更新します。 -adminTranslateStart=翻訳 -helpAction=アクション -helpAddAnotherRow=別の行を追加 -helpAddDrivers=データベースドライバの追加 -helpAddDriversText=追加ドライバは、Jarファイルの場所を環境変数 H2DRIVERS、または CLASSPATH に追加することで登録できます。例 (Windows): データベースドライバライブラリ C:/Programs/hsqldb/lib/hsqldb.jar を追加するには、環境変数 H2DRIVERS に、C:/Programs/hsqldb/lib/hsqldb.jar を設定します。 -helpAddRow=新しい行を追加 -helpCommandHistory=コマンド履歴を表示 -helpCreateTable=ID、および NAME 列を持つ -helpDeleteRow=行を削除 -helpDisconnect=データベース接続を切断 -helpDisplayThis=このページを表示 -helpDropTable=存在するならテーブルを削除 -helpExecuteCurrent=現在のSQLステートメントを実行 -helpIcon=アイコン -helpImportantCommands=重要なコマンド -helpOperations=オペレーション -helpQuery=テーブル問い合わせ -helpSampleSQL=SQLステートメントのサンプル -helpStatements=SQLステートメント -helpUpdate=行データの変更 -helpWithColumnsIdName=新しいテーブルを作成 -login.connect=接続 -login.driverClass=ドライバクラス -login.driverNotFound=データベースドライバが見付かりません
ヘルプでドライバの追加方法を確認してください -login.goAdmin=設定 -login.jdbcUrl=JDBC URL -login.language=言語 -login.login=ログイン -login.remove=削除 -login.save=保存 -login.savedSetting=保存済設定 -login.settingName=設定名 -login.testConnection=接続テスト -login.testSuccessful=テストは成功しました -login.welcome=H2コンソール -result.1row=1 行 -result.autoCommitOff=オートコミットが無効になりました -result.autoCommitOn=オートコミットが有効になりました -result.bytes=バイト -result.characters=文字 -result.maxrowsSet=最大行数が設定されました -result.noRows=該当行無し -result.noRunningStatement=現在実行中のステートメントはありません -result.rows=行 -result.statementWasCanceled=ステートメントがキャンセルされました -result.updateCount=更新数 -resultEdit.add=追加 -resultEdit.cancel=キャンセル -resultEdit.delete=削除 -resultEdit.edit=編集 -resultEdit.editResult=編集 -resultEdit.save=保存 -toolbar.all=全て -toolbar.autoCommit=オートコミット -toolbar.autoComplete=オートコンプリート -toolbar.autoComplete.full=フル -toolbar.autoComplete.normal=ノーマル -toolbar.autoComplete.off=オフ -toolbar.cancelStatement=現在のステートメントをキャンセル -toolbar.clear=クリア -toolbar.commit=コミット -toolbar.disconnect=切断 -toolbar.history=コマンド履歴 -toolbar.maxRows=最大行数 -toolbar.refresh=リフレッシュ -toolbar.rollback=ロールバック -toolbar.run=実行 (Ctrl+Enter) -toolbar.sqlStatement=SQLステートメント -tools.backup=バックアップ -tools.backup.help=データベースのバックアップを作成します。 -tools.changeFileEncryption=ファイル暗号化設定の変更 -tools.changeFileEncryption.help=データベースファイルの暗号化方式とパスワードを変更します。 -tools.cipher=暗号化方式 (AES or XTEA) -tools.commandLine=コマンドライン -tools.convertTraceFile=トレースファイルの変換 -tools.convertTraceFile.help=.trace.dbファイルを、JavaアプリケーションとSQLスクリプトに変換します。 -tools.createCluster=クラスタ作成 -tools.createCluster.help=スタンドアロンデータベースからクラスタを作成します。 -tools.databaseName=データベース名 -tools.decryptionPassword=復号化パスワード -tools.deleteDbFiles=データベースファイルの削除 -tools.deleteDbFiles.help=データベースに関連する全てのファイルを削除します。 -tools.directory=ディレクトリ -tools.encryptionPassword=暗号化パスワード -tools.javaDirectoryClassName=Javaディレクトリとクラス名 -tools.recover=修復 -tools.recover.help=破損したデータベースの修復を支援します。 -tools.restore=リストア -tools.restore.help=データベースをバックアップからリストアします。 -tools.result=結果 -tools.run=実行 -tools.runScript=スクリプトの実行 -tools.runScript.help=SQLスクリプトを実行します。 -tools.script=スクリプト -tools.script.help=バックアップ、または移動のために、データベースをSQLスクリプトに変換します。 -tools.scriptFileName=スクリプトファイル名 -tools.serverList=サーバリスト -tools.sourceDatabaseName=ソースデータベース名 -tools.sourceDatabaseURL=ソースデータベースURL -tools.sourceDirectory=ソースディレクトリ -tools.sourceFileName=ソースファイル名 -tools.sourceScriptFileName=ソーススクリプトファイル名 -tools.targetDatabaseName=ターゲットデータベース名 -tools.targetDatabaseURL=ターゲットデータベースURL -tools.targetDirectory=ターゲットディレクトリ -tools.targetFileName=ターゲットファイル名 -tools.targetScriptFileName=ターゲットスクリプトファイル名 -tools.traceFileName=トレースファイル名 -tree.admin=管理者 -tree.current=現在値 -tree.hashed=ハッシュ -tree.increment=インクリメント -tree.indexes=インデックス -tree.nonUnique=Non-Unique -tree.sequences=シーケンス -tree.unique=Unique -tree.users=ユーザ diff --git a/tools/h2/src/main/org/h2/server/web/res/_text_nl.prop b/tools/h2/src/main/org/h2/server/web/res/_text_nl.prop deleted file mode 100755 index 4d816b5..0000000 --- a/tools/h2/src/main/org/h2/server/web/res/_text_nl.prop +++ /dev/null @@ -1,149 +0,0 @@ -.translator=Remco Schoen -a.help=Help -a.language=Nederlands -a.lynxNotSupported=Sorry, Lynx wordt nog niet ondersteund -a.password=Wachtwoord -a.remoteConnectionsDisabled=Sorry, externe verbindingen ('webAllowOthers') zijn niet toegelaten voor deze server. -a.title=H2 Console -a.tools=#Tools -a.user=Gebruikersnaam -admin.executing=Uitvoeren -admin.ip=IP -admin.lastAccess=Laatste toegang -admin.lastQuery=Laatste query -admin.url=URL -adminAllow=Toegestane clients -adminConnection=Beveiliging verbinding -adminHttp=Gebruik onversleutelde HTTP verbindingen -adminHttps=Gebruik versleutelde SSL (HTTPS) verbindingen -adminLocal=Sta alleen lokale verbindingen toe -adminLogin=Inloggen instellingen -adminLoginCancel=Annuleren -adminLoginOk=OK -adminLogout=Uitloggen -adminOthers=Sta verbindingen vanaf andere computers toe -adminPort=Poortnummer -adminPortWeb=Webserver poortnummer -adminRestart=Wijzigingen worden doorgevoerd na herstarten server -adminSave=Opslaan -adminSessions=Actieve sessies -adminShutdown=Server stoppen -adminTitle=H2 Console instellingen -adminTranslateHelp=#Translate or improve the translation of the H2 Console. -adminTranslateStart=#Translate -helpAction=Gebeurtenis -helpAddAnotherRow=Voeg nogmaals een nieuwe regel toe -helpAddDrivers=Toevoegen drivers voor een database -helpAddDriversText=Extra drivers voor een database kunnen worden geregistreerd door het toevoegen van het Jar-bestand van de driver aan de omgevingsvariabelen H2DRIVERS of CLASSPATH. Voorbeeld (Windows): om de driver bibliotheek C:/Programs/hsqldb/lib/hsqldb.jar toe te voegen, moet de omgevingsvariabele H2DRIVERS op C:/Programs/hsqldb/lib/hsqldb.jar gezet worden. -helpAddRow=Voeg een nieuwe regel toe -helpCommandHistory=Toont de geschiedenis van commando's -helpCreateTable=Maak een nieuwe table aan -helpDeleteRow=Verwijder een regel -helpDisconnect=Verbreekt de verbinding met de database -helpDisplayThis=Toont deze helppagina -helpDropTable=Verwijdert de tabel als deze bestaat -helpExecuteCurrent=Voert het huidige SQL-statement uit -helpIcon=Icoon -helpImportantCommands=Belangrijke commando's -helpOperations=Acties -helpQuery=Vraag gegevens op uit de tabel -helpSampleSQL=Voorbeeld SQL-script -helpStatements=SQL-statements -helpUpdate=Verander de gegevens in een rij -helpWithColumnsIdName=met de kolommen ID en NAME -login.connect=Verbind -login.driverClass=Driver klasse -login.driverNotFound=Driver voor database niet gevonden
Kijk in de help hoe je drivers kunt toevoegen -login.goAdmin=Instellingen -login.jdbcUrl=JDBC URL -login.language=Taal -login.login=Inloggen -login.remove=Verwijderen -login.save=Opslaan -login.savedSetting=Opgeslagen instellingen -login.settingName=Instellingsnaam -login.testConnection=Test verbinding -login.testSuccessful=Test succesvol -login.welcome=H2 Console -result.1row=1 rij -result.autoCommitOff=Auto commit is nu UIT -result.autoCommitOn=Auto commit is nu AAN -result.bytes=#bytes -result.characters=#characters -result.maxrowsSet=Het maximum aantal rijen is ingesteld -result.noRows=geen rijen -result.noRunningStatement=Er wordt momenteel geen statement uitgevoerd -result.rows=rijen -result.statementWasCanceled=Het statement is geannuleerd -result.updateCount=Aantal wijzigingen -resultEdit.add=Toevoegen -resultEdit.cancel=Annuleren -resultEdit.delete=Verwijderen -resultEdit.edit=Wijzigen -resultEdit.editResult=Wijzigen -resultEdit.save=Opslaan -toolbar.all=Alle -toolbar.autoCommit=Auto commit -toolbar.autoComplete=Auto aanvullen -toolbar.autoComplete.full=Volledig -toolbar.autoComplete.normal=Normaal -toolbar.autoComplete.off=Uit -toolbar.cancelStatement=Annuleer het huidige statement -toolbar.clear=Wissen -toolbar.commit=Commit -toolbar.disconnect=Verbinding verbreken -toolbar.history=Geschiedenis commando's -toolbar.maxRows=Max rijen -toolbar.refresh=Verversen -toolbar.rollback=Rollback -toolbar.run=Uitvoeren (Ctrl+Enter) -toolbar.sqlStatement=SQL statement -tools.backup=#Backup -tools.backup.help=#Creates a backup of a database. -tools.changeFileEncryption=#ChangeFileEncryption -tools.changeFileEncryption.help=#Allows changing the database file encryption password and algorithm. -tools.cipher=#Cipher (AES or XTEA) -tools.commandLine=#Command line -tools.convertTraceFile=#ConvertTraceFile -tools.convertTraceFile.help=#Converts a .trace.db file to a Java application and SQL script. -tools.createCluster=#CreateCluster -tools.createCluster.help=#Creates a cluster from a standalone database. -tools.databaseName=#Database name -tools.decryptionPassword=#Decryption password -tools.deleteDbFiles=#DeleteDbFiles -tools.deleteDbFiles.help=#Deletes all files belonging to a database. -tools.directory=#Directory -tools.encryptionPassword=#Encryption password -tools.javaDirectoryClassName=#Java directory and class name -tools.recover=#Recover -tools.recover.help=#Helps recovering a corrupted database. -tools.restore=#Restore -tools.restore.help=#Restores a database backup. -tools.result=#Result -tools.run=#Run -tools.runScript=#RunScript -tools.runScript.help=#Runs a SQL script. -tools.script=#Script -tools.script.help=#Allows to convert a database to a SQL script for backup or migration. -tools.scriptFileName=#Script file name -tools.serverList=#Server list -tools.sourceDatabaseName=#Source database name -tools.sourceDatabaseURL=#Source database URL -tools.sourceDirectory=#Source directory -tools.sourceFileName=#Source file name -tools.sourceScriptFileName=#Source script file name -tools.targetDatabaseName=#Target database name -tools.targetDatabaseURL=#Target database URL -tools.targetDirectory=#Target directory -tools.targetFileName=#Target file name -tools.targetScriptFileName=#Target script file name -tools.traceFileName=#Trace file name -tree.admin=Beheerder -tree.current=Huidige waarde -tree.hashed=Hashed -tree.increment=Ophogen -tree.indexes=Indices -tree.nonUnique=Niet uniek -tree.sequences=Sequenties -tree.unique=Uniek -tree.users=Gebruikers diff --git a/tools/h2/src/main/org/h2/server/web/res/_text_pl.prop b/tools/h2/src/main/org/h2/server/web/res/_text_pl.prop deleted file mode 100755 index 576c86b..0000000 --- a/tools/h2/src/main/org/h2/server/web/res/_text_pl.prop +++ /dev/null @@ -1,149 +0,0 @@ -.translator=Tomek -a.help=Pomoc -a.language=Polski -a.lynxNotSupported=Przeglądarka Lynx nie jest wpierana jeszcze -a.password=Hasło -a.remoteConnectionsDisabled=Połączenia zdalne ('webAllowOthers') są wyłączone na tym serwerze. -a.title=Konsola H2 -a.tools=Narzędzia -a.user=Użytkownik -admin.executing=Wykonywanie -admin.ip=IP -admin.lastAccess=Ostatnie logowanie -admin.lastQuery=Ostatnie zapytanie -admin.url=URL -adminAllow=Zaufani klienci -adminConnection=Bezpieczeństwo połączeń -adminHttp=Używaj szyfrowanych połączeń HTTP -adminHttps=Używaj szyfrowanych połączeń SSL (HTTPS) -adminLocal=Tylko lokalne połączenia -adminLogin=Logowanie administracyjne -adminLoginCancel=Anuluj -adminLoginOk=OK -adminLogout=Wyloguj -adminOthers=Pozwalaj na połączenia zdalne -adminPort=Numer portu -adminPortWeb=Numer portu serwera Web -adminRestart=Zmiany będą widoczne po zrestartowaniu serwera. -adminSave=Zapisz -adminSessions=Aktywne sesje -adminShutdown=Wyłącz -adminTitle=Ustawienia konsoli H2 -adminTranslateHelp=Przetłumacz lub popraw tłumaczenie konsoli H2. -adminTranslateStart=Tłumacz -helpAction=Akcja -helpAddAnotherRow=Dodaj kolejny rekord -helpAddDrivers=Dodatkowe sterowniki baz danych -helpAddDriversText=Dodatkowe sterowniki bazy danych mogą być rejestrowane przez dodanie plików Jar do zmiennych środowiskowych H2DRIVERS lub CLASSPATH. Przykładowo (Windows): Aby dodać sterownik z pliku C:/Programs/hsqldb/lib/hsqldb.jar, ustaw zmienną środowiskową H2DRIVERS na C:/Programs/hsqldb/lib/hsqldb.jar. -helpAddRow=Dodaj nowy rekord -helpCommandHistory=Pokazuje historię komend -helpCreateTable=Tworzy nową tabele -helpDeleteRow=Usuń rekord -helpDisconnect=Wyloguj się z bazy danych -helpDisplayThis=Wyświetla tą strone pomocy -helpDropTable=Skasuj tabele jeżeli istnieje -helpExecuteCurrent=Wykonuje bierzące zapytanie SQL -helpIcon=Ikona -helpImportantCommands=Ważne komendy -helpOperations=Operacje -helpQuery=Wykonaj zapytanie wybierajace -helpSampleSQL=Prosty skrypt SQL -helpStatements=Wyrażenia SQL -helpUpdate=Zmień dane w rekordzie -helpWithColumnsIdName=z kolumnami ID i NAME -login.connect=Połącz -login.driverClass=Klasa sterownika -login.driverNotFound=Sterownik nie istnieje
Zobacz w dokumentacji opis dodawania sterowników -login.goAdmin=Opcje -login.jdbcUrl=JDBC URL -login.language=Język -login.login=Użytkownik -login.remove=Usuń -login.save=Zapisz -login.savedSetting=Zapisz opcje -login.settingName=Nazwa opcji -login.testConnection=Testuj połaczenie -login.testSuccessful=Test zakończony sukcesem -login.welcome=Konsola H2 -result.1row=1 rekord -result.autoCommitOff=Automatyczne zatwierdzanie jest teraz WYŁĄCZONE -result.autoCommitOn=Automatyczne zatwierdzanie jest teraz WŁACZONE -result.bytes=#bytes -result.characters=#characters -result.maxrowsSet=Maksymalna ilość rekordów -result.noRows=brak danych -result.noRunningStatement=Obecnie nie jest wykonywane żedne zapytanie -result.rows=rekordy -result.statementWasCanceled=Zapytanie zostało anulowane -result.updateCount=Ilość aktualizacji -resultEdit.add=Dodaj -resultEdit.cancel=Anuluj -resultEdit.delete=Skasuj -resultEdit.edit=Edytuj -resultEdit.editResult=Edytuj -resultEdit.save=Zapisz -toolbar.all=Wszystko -toolbar.autoCommit=Automatyczne zatwierdzanie -toolbar.autoComplete=Automatyczne uzupełnianie -toolbar.autoComplete.full=Pełny -toolbar.autoComplete.normal=Normalny -toolbar.autoComplete.off=Wyłączony -toolbar.cancelStatement=Anuluj bierzące zapytanie -toolbar.clear=Wyczyść -toolbar.commit=Zatwierdź -toolbar.disconnect=Rozłącz -toolbar.history=Historia komend -toolbar.maxRows=Maksymalna ilość rekordów -toolbar.refresh=Odśwież -toolbar.rollback=Cofnij zmiany -toolbar.run=Wykonaj (Ctrl+Enter) -toolbar.sqlStatement=Zapytanie SQL -tools.backup=Backup -tools.backup.help=Twozy kopie bezpieczenstwa bazy danych. -tools.changeFileEncryption=Zmien kodowanie pliku -tools.changeFileEncryption.help=Zezwalaj a zmiane hasła i algorytmu szyforowania. -tools.cipher=Cipher (AES lub XTEA) -tools.commandLine=Linia komend -tools.convertTraceFile=Konwertuj plik śladu -tools.convertTraceFile.help=Konwertuje plik .trace.db na aplikacje Java i skrypt SQL. -tools.createCluster=Utwórz Klaster -tools.createCluster.help=Tworzy klaster z samodzielnej bazy danych. -tools.databaseName=Naza bazy danych -tools.decryptionPassword=Hasło deszyfrowania -tools.deleteDbFiles=Skasuj pliki bazy danych -tools.deleteDbFiles.help=Skasuj wszystkie pliki bazy danych. -tools.directory=Katalog -tools.encryptionPassword=hasło szyfrowania -tools.javaDirectoryClassName=Katalog Javy i nazwa klasy -tools.recover=Odzyskaj -tools.recover.help=Pomaga odzyskać dane z uszkodzonej bazy. -tools.restore=Przywroć -tools.restore.help=Przywraca baze z archiwum. -tools.result=Wynik -tools.run=Uruchom -tools.runScript=Wykonaj Skrypt -tools.runScript.help=Uruchamia skrytp SQL. -tools.script=Skrypt -tools.script.help=Pozwala na konwersje bazy danych do skryptu SQL dla potrzeb kopi bezpieczenstwa lub migracji bazy. -tools.scriptFileName=Nazwa pliku skryptu -tools.serverList=Lista serwerów -tools.sourceDatabaseName=Nazwa źrodłowej bazy danych -tools.sourceDatabaseURL=URL źrodłowej bazy danych -tools.sourceDirectory=Źrodłowy katalog -tools.sourceFileName=Nazwa pliku źrodłowego -tools.sourceScriptFileName=Nazwa pliku źrodłowego skryptu -tools.targetDatabaseName=Nazwa docelowej bazy danych -tools.targetDatabaseURL=URL docelowej bazy danych -tools.targetDirectory=Docelowy katalog -tools.targetFileName=Nazwa pliku docelowego -tools.targetScriptFileName=Nazwa pliku docelowego skryptu -tools.traceFileName=Nazwa pliku śladu -tree.admin=Administrator -tree.current=Bierząca wartość -tree.hashed=Haszowany -tree.increment=Zwiekszenie -tree.indexes=Indeksy -tree.nonUnique=Nieunikalny -tree.sequences=Sekwencje -tree.unique=Unikalny -tree.users=Użytkownicy diff --git a/tools/h2/src/main/org/h2/server/web/res/_text_pt_br.prop b/tools/h2/src/main/org/h2/server/web/res/_text_pt_br.prop deleted file mode 100755 index 23d7a15..0000000 --- a/tools/h2/src/main/org/h2/server/web/res/_text_pt_br.prop +++ /dev/null @@ -1,149 +0,0 @@ -.translator=Eduardo Fonseca Velasques -a.help=Ajuda -a.language=Português (Brasil) -a.lynxNotSupported=Lynx não é suportado -a.password=Senha -a.remoteConnectionsDisabled=Conexões remotas ('webAllowOthers') estão desativadas neste servidor. -a.title=H2 Terminal -a.tools=#Tools -a.user=Usuário -admin.executing=Executando -admin.ip=IP -admin.lastAccess=Último Acesso -admin.lastQuery=Última Query -admin.url=URL -adminAllow=Clientes com acesso -adminConnection=Nível de segurança da conexão -adminHttp=Usar conexão do tipo HTTP não segura (os dados não são encriptados) -adminHttps=Usar conexão do tipo HTTPS segura por SSL (os dados são encriptados) -adminLocal=Permitir apenas conexões do computador local -adminLogin=Entrar como administrador -adminLoginCancel=Cancelar -adminLoginOk=Confirmar -adminLogout=Sair -adminOthers=Permitir conexões de outros computadores na rede -adminPort=Número da porta -adminPortWeb=Número da porta do servidor -adminRestart=As alterações serão aplicadas depois de reiniciar o servidor. -adminSave=Salvar -adminSessions=Sessões ativas -adminShutdown=Terminar -adminTitle=Configuração do H2 Terminal -adminTranslateHelp=#Translate or improve the translation of the H2 Console. -adminTranslateStart=#Translate -helpAction=Ação -helpAddAnotherRow=Adicionar outra linha -helpAddDrivers=Adicionar drivers de Base de Dados -helpAddDriversText=É possível registrar outros drivers, adicionando o arquivo JAR respectivo na variável de ambiente H2DRIVERS ou CLASSPATH. Exemplo (Windows): Para adicionar o driver que está em C:/Programs/hsqldb/lib/hsqldb.jar altere o valor da variável de ambiente H2DRIVERS para C:/Programs/hsqldb/lib/hsqldb.jar. -helpAddRow=Adicionar uma linha nova -helpCommandHistory=Mostrar o histórico de comandos -helpCreateTable=Criar uma tabela nova -helpDeleteRow=Apagar uma linha -helpDisconnect=Fechar conexão à Base de Dados -helpDisplayThis=Mostrar está página de ajuda -helpDropTable=Apagar a tabela, caso ela exista -helpExecuteCurrent=Executar o comando SQL corrente -helpIcon=Símbolo -helpImportantCommands=Comandos importantes -helpOperations=Operações= -helpQuery=Pesquisar uma tabela -helpSampleSQL=Scripts de exemplo -helpStatements=Comandos SQL -helpUpdate=Alterar os dados de uma linha -helpWithColumnsIdName=com as colunas ID e NAME -login.connect=Conectar -login.driverClass=Classe com o driver -login.driverNotFound=O driver não foi encontrado
Ver na seção de ajuda, como adicionar drivers -login.goAdmin=Preferências -login.jdbcUrl=JDBC URL -login.language=Língua -login.login=Login -login.remove=Remover -login.save=Gravar -login.savedSetting=Configuração ativa -login.settingName=Nome da configuração -login.testConnection=Testar conexão -login.testSuccessful=Teste bem sucedido -login.welcome=Consola H2 -result.1row=Uma linha -result.autoCommitOff=Auto commit agora está desligado -result.autoCommitOn=Auto commit agora está ligado -result.bytes=#bytes -result.characters=#characters -result.maxrowsSet=Número máximo de linhas foi alterado -result.noRows=sem linhas -result.noRunningStatement=Actualmente não existe nenhum comando em execução -result.rows=linhas -result.statementWasCanceled=O comando foi cancelado -result.updateCount=Número de registros alterados -resultEdit.add=Adicionar -resultEdit.cancel=Cancelar -resultEdit.delete=Apagar -resultEdit.edit=Alterar -resultEdit.editResult=Alterar -resultEdit.save=Salvar -toolbar.all=Todas -toolbar.autoCommit=Auto commit -toolbar.autoComplete=Auto complete -toolbar.autoComplete.full=Total -toolbar.autoComplete.normal=Normal -toolbar.autoComplete.off=Desligado -toolbar.cancelStatement=Cancelar o comando que está em execução -toolbar.clear=Limpar -toolbar.commit=Commit -toolbar.disconnect=Desligar -toolbar.history=Histórico de comandos executados -toolbar.maxRows=Número máximo de linhas -toolbar.refresh=Atualizar -toolbar.rollback=Rollback -toolbar.run=Executar comando (Ctrl+Enter) -toolbar.sqlStatement=Comando SQL -tools.backup=#Backup -tools.backup.help=#Creates a backup of a database. -tools.changeFileEncryption=#ChangeFileEncryption -tools.changeFileEncryption.help=#Allows changing the database file encryption password and algorithm. -tools.cipher=#Cipher (AES or XTEA) -tools.commandLine=#Command line -tools.convertTraceFile=#ConvertTraceFile -tools.convertTraceFile.help=#Converts a .trace.db file to a Java application and SQL script. -tools.createCluster=#CreateCluster -tools.createCluster.help=#Creates a cluster from a standalone database. -tools.databaseName=#Database name -tools.decryptionPassword=#Decryption password -tools.deleteDbFiles=#DeleteDbFiles -tools.deleteDbFiles.help=#Deletes all files belonging to a database. -tools.directory=#Directory -tools.encryptionPassword=#Encryption password -tools.javaDirectoryClassName=#Java directory and class name -tools.recover=#Recover -tools.recover.help=#Helps recovering a corrupted database. -tools.restore=#Restore -tools.restore.help=#Restores a database backup. -tools.result=#Result -tools.run=#Run -tools.runScript=#RunScript -tools.runScript.help=#Runs a SQL script. -tools.script=#Script -tools.script.help=#Allows to convert a database to a SQL script for backup or migration. -tools.scriptFileName=#Script file name -tools.serverList=#Server list -tools.sourceDatabaseName=#Source database name -tools.sourceDatabaseURL=#Source database URL -tools.sourceDirectory=#Source directory -tools.sourceFileName=#Source file name -tools.sourceScriptFileName=#Source script file name -tools.targetDatabaseName=#Target database name -tools.targetDatabaseURL=#Target database URL -tools.targetDirectory=#Target directory -tools.targetFileName=#Target file name -tools.targetScriptFileName=#Target script file name -tools.traceFileName=#Trace file name -tree.admin=Administrador -tree.current=Valor corrente -tree.hashed=Hashed -tree.increment=Incrementar -tree.indexes=Índices -tree.nonUnique=Não único -tree.sequences=Sequências -tree.unique=Único -tree.users=Usuários diff --git a/tools/h2/src/main/org/h2/server/web/res/_text_pt_pt.prop b/tools/h2/src/main/org/h2/server/web/res/_text_pt_pt.prop deleted file mode 100755 index 89310d2..0000000 --- a/tools/h2/src/main/org/h2/server/web/res/_text_pt_pt.prop +++ /dev/null @@ -1,149 +0,0 @@ -.translator=Antonio Casqueiro -a.help=Ajuda -a.language=Português (Europeu) -a.lynxNotSupported=Lynx ainda não é suportado -a.password=Senha -a.remoteConnectionsDisabled=Conexões remotas ('webAllowOthers') encontram-se desactivadas neste servidor. -a.title=H2 Consola -a.tools=#Tools -a.user=Nome Utilizador -admin.executing=A executar -admin.ip=IP -admin.lastAccess=Último Acesso -admin.lastQuery=Última Query -admin.url=URL -adminAllow=Clientes com acesso -adminConnection=Nível de segurança da conexão -adminHttp=Usar conexões HTTP não seguras (os dados não são cifrados) -adminHttps=Usar conexões SSL (HTTPS) seguras (os dados são cifrados) -adminLocal=Apenas permitir conexões a partir do computador local -adminLogin=Entrar como administrador -adminLoginCancel=Cancelar -adminLoginOk=Confirmar -adminLogout=Sair -adminOthers=Permitir conexões a partir de outro computador na rede -adminPort=Número do porto -adminPortWeb=Número do porto do servidor -adminRestart=As alterações apenas serão aplicadas após reiniciar o servidor. -adminSave=Gravar -adminSessions=Sessões activas -adminShutdown=Encerrar -adminTitle=Preferencias da Consola H2 -adminTranslateHelp=#Translate or improve the translation of the H2 Console. -adminTranslateStart=#Translate -helpAction=Acção -helpAddAnotherRow=Adicionar outra linha -helpAddDrivers=Adicionar drivers de Base de Dados -helpAddDriversText=É possível registar outros drivers, adicionando o ficheiro JAR respectivo, à variável de ambiente H2DRIVERS ou CLASSPATH. Exemplo (Windows): Para adicionar o driver que se encontra em C:/Programs/hsqldb/lib/hsqldb.jar, alterar o valor da variável de ambiente H2DRIVERS para C:/Programs/hsqldb/lib/hsqldb.jar. -helpAddRow=Adicionar uma linha nova -helpCommandHistory=Mostrar o histórico de comandos -helpCreateTable=Criar uma tabela nova -helpDeleteRow=Apagar uma linha -helpDisconnect=Fechar conexão à Base de Dados -helpDisplayThis=Mostrar esta página de ajuda -helpDropTable=Apagar a tabela, caso ela exista -helpExecuteCurrent=Executar o comando SQL corrente -helpIcon=Simbolo -helpImportantCommands=Comandos importantes -helpOperations=Operações= -helpQuery=Pesquisar uma tabela -helpSampleSQL=Scripts de exemplo -helpStatements=Comandos SQL -helpUpdate=Modificar os dados de uma linha -helpWithColumnsIdName=com as colunas ID e NAME -login.connect=Estabelecer conexão -login.driverClass=Classe com o driver -login.driverNotFound=O driver não foi encontrado
Ver na secção de ajuda, como adicionar drivers -login.goAdmin=Preferencias -login.jdbcUrl=JDBC URL -login.language=Lingua -login.login=Login -login.remove=Remover -login.save=Gravar -login.savedSetting=Configuração activa -login.settingName=Nome da configuração -login.testConnection=Testar conexão -login.testSuccessful=Teste bem sucedido -login.welcome=Consola H2 -result.1row=1 linha -result.autoCommitOff=O auto commit passou a estar desligado -result.autoCommitOn=O auto commit passou a estar ligado -result.bytes=#bytes -result.characters=#characters -result.maxrowsSet=O número máximo de linhas foi alterado -result.noRows=sem linhas -result.noRunningStatement=Actualmente não existe nenhum comando em execução -result.rows=linhas -result.statementWasCanceled=O comando foi cancelado -result.updateCount=Número de registos actualizados -resultEdit.add=Adicionar -resultEdit.cancel=Cancelar -resultEdit.delete=Apagar -resultEdit.edit=Alterar -resultEdit.editResult=Alterar -resultEdit.save=Gravar -toolbar.all=Todas -toolbar.autoCommit=Auto commit -toolbar.autoComplete=Auto complete -toolbar.autoComplete.full=Total -toolbar.autoComplete.normal=Normal -toolbar.autoComplete.off=Desligado -toolbar.cancelStatement=Cancelar o comando que se encontra em execução -toolbar.clear=Limpar -toolbar.commit=Commit -toolbar.disconnect=Desligar -toolbar.history=Histórico de comandos executados -toolbar.maxRows=Número máximo de linhas -toolbar.refresh=Actualizar -toolbar.rollback=Rollback -toolbar.run=Executar comando (Ctrl+Enter) -toolbar.sqlStatement=Comando SQL -tools.backup=#Backup -tools.backup.help=#Creates a backup of a database. -tools.changeFileEncryption=#ChangeFileEncryption -tools.changeFileEncryption.help=#Allows changing the database file encryption password and algorithm. -tools.cipher=#Cipher (AES or XTEA) -tools.commandLine=#Command line -tools.convertTraceFile=#ConvertTraceFile -tools.convertTraceFile.help=#Converts a .trace.db file to a Java application and SQL script. -tools.createCluster=#CreateCluster -tools.createCluster.help=#Creates a cluster from a standalone database. -tools.databaseName=#Database name -tools.decryptionPassword=#Decryption password -tools.deleteDbFiles=#DeleteDbFiles -tools.deleteDbFiles.help=#Deletes all files belonging to a database. -tools.directory=#Directory -tools.encryptionPassword=#Encryption password -tools.javaDirectoryClassName=#Java directory and class name -tools.recover=#Recover -tools.recover.help=#Helps recovering a corrupted database. -tools.restore=#Restore -tools.restore.help=#Restores a database backup. -tools.result=#Result -tools.run=#Run -tools.runScript=#RunScript -tools.runScript.help=#Runs a SQL script. -tools.script=#Script -tools.script.help=#Allows to convert a database to a SQL script for backup or migration. -tools.scriptFileName=#Script file name -tools.serverList=#Server list -tools.sourceDatabaseName=#Source database name -tools.sourceDatabaseURL=#Source database URL -tools.sourceDirectory=#Source directory -tools.sourceFileName=#Source file name -tools.sourceScriptFileName=#Source script file name -tools.targetDatabaseName=#Target database name -tools.targetDatabaseURL=#Target database URL -tools.targetDirectory=#Target directory -tools.targetFileName=#Target file name -tools.targetScriptFileName=#Target script file name -tools.traceFileName=#Trace file name -tree.admin=Administrador -tree.current=Valor corrente -tree.hashed=Hashed -tree.increment=Incrementar -tree.indexes=Índices -tree.nonUnique=Não único -tree.sequences=Sequências -tree.unique=Único -tree.users=Utilizadoreses diff --git a/tools/h2/src/main/org/h2/server/web/res/_text_ru.prop b/tools/h2/src/main/org/h2/server/web/res/_text_ru.prop deleted file mode 100755 index 43cded8..0000000 --- a/tools/h2/src/main/org/h2/server/web/res/_text_ru.prop +++ /dev/null @@ -1,149 +0,0 @@ -.translator=Vlad Alexahin -a.help=Помощь -a.language=Русский -a.lynxNotSupported=Извините, Lynx пока что не поддерживается -a.password=Пароль -a.remoteConnectionsDisabled=Извините, удаленные подключения ('webAllowOthers') запрещены на этом сервере. -a.title=H2 Console -a.tools=#Tools -a.user=Пользователь Имя -admin.executing=Выполняется -admin.ip=IP -admin.lastAccess=Последний Вход -admin.lastQuery=Последний Запрос -admin.url=URL -adminAllow=Разрешенные клиенты -adminConnection=Безопасность подключения -adminHttp=Используйте незашифрованые HTTP-соединения -adminHttps=Используйте SSL (HTTPS) соединения -adminLocal=Разрешены только локальные подключения -adminLogin=Администратор Логин -adminLoginCancel=Отменить -adminLoginOk=OK -adminLogout=Logout -adminOthers=Разрешить удаленные подключения -adminPort=Номер порта -adminPortWeb=Порт web-сервера -adminRestart=Изменения вступят в силу после перезагрузки сервера. -adminSave=Сохранить -adminSessions=Активные сессии -adminShutdown=Выключить -adminTitle=H2 Console Preferences -adminTranslateHelp=#Translate or improve the translation of the H2 Console. -adminTranslateStart=#Translate -helpAction=Действие -helpAddAnotherRow=Добавить строку -helpAddDrivers=Дабавляем драйвер базы данных -helpAddDriversText=Дополнительные драйверы базы данных могут быть зарегестрированы добавлением соответствующих Jar-файлов в переменную среды H2DRIVERS или в CLASSPATH. Пример (Windows): Чтобы добаить библиотеку драйвера базы данных C:/Programs/hsqldb/lib/hsqldb.jar, установите в переменную среды H2DRIVERS значение C:/Programs/hsqldb/lib/hsqldb.jar. -helpAddRow=Добавить новую строку -helpCommandHistory=Показывает историю выполенных команд -helpCreateTable=Создать новую таблицу -helpDeleteRow=Удалить строку -helpDisconnect=Отключиться от базы данных -helpDisplayThis=Показывает это окно помощи -helpDropTable=Удаляет таблицу, если она уже существует -helpExecuteCurrent=Выполнить текущий SQL-запрос -helpIcon=Иконка -helpImportantCommands=Важные команды -helpOperations=Операции -helpQuery=Запрос к таблице -helpSampleSQL=Примеры SQL-скриптов -helpStatements=SQL-запрос -helpUpdate=Изменить данные в строке -helpWithColumnsIdName=с колонками ID и NAME -login.connect=Соединиться -login.driverClass=Класс драйвера -login.driverNotFound=Драйвер базы данных не найден
Посмотрите в Помощи, как добавить драйвер базы данных -login.goAdmin=Preferences -login.jdbcUrl=JDBC URL -login.language=Язык -login.login=Логин -login.remove=Удалить -login.save=Сохранить -login.savedSetting=Сохранить настройки -login.settingName=Имя настройки -login.testConnection=Тестовое соединение -login.testSuccessful=Тест прошел успешно -login.welcome=H2 Console -result.1row=1 строка -result.autoCommitOff=Авто-выполнение сейчас ВЫКЛЮЧЕНО -result.autoCommitOn=Авто-выполнение сейчас ВКЛЮЧЕНО -result.bytes=#bytes -result.characters=#characters -result.maxrowsSet=Установлено максимальное количество строк -result.noRows=нет строк -result.noRunningStatement=Сейчас нету выполняемых запросов -result.rows=строки -result.statementWasCanceled=Запрос был отменен -result.updateCount=Обновить количество -resultEdit.add=Добавить -resultEdit.cancel=Отменить -resultEdit.delete=Удалить -resultEdit.edit=Править -resultEdit.editResult=Править -resultEdit.save=Сохранить -toolbar.all=Все -toolbar.autoCommit=Авто-выполнение -toolbar.autoComplete=Авто-завершение -toolbar.autoComplete.full=Все -toolbar.autoComplete.normal=Нормальные -toolbar.autoComplete.off=Выключено -toolbar.cancelStatement=Отменить текущий запрос -toolbar.clear=Очистить -toolbar.commit=Выполнить -toolbar.disconnect=Отсоедениться -toolbar.history=История команд -toolbar.maxRows=Максимальное количество строк -toolbar.refresh=Обновить -toolbar.rollback=Вернуть назад -toolbar.run=Выполнить (Ctrl+Enter) -toolbar.sqlStatement=SQL-запрос -tools.backup=#Backup -tools.backup.help=#Creates a backup of a database. -tools.changeFileEncryption=#ChangeFileEncryption -tools.changeFileEncryption.help=#Allows changing the database file encryption password and algorithm. -tools.cipher=#Cipher (AES or XTEA) -tools.commandLine=#Command line -tools.convertTraceFile=#ConvertTraceFile -tools.convertTraceFile.help=#Converts a .trace.db file to a Java application and SQL script. -tools.createCluster=#CreateCluster -tools.createCluster.help=#Creates a cluster from a standalone database. -tools.databaseName=#Database name -tools.decryptionPassword=#Decryption password -tools.deleteDbFiles=#DeleteDbFiles -tools.deleteDbFiles.help=#Deletes all files belonging to a database. -tools.directory=#Directory -tools.encryptionPassword=#Encryption password -tools.javaDirectoryClassName=#Java directory and class name -tools.recover=#Recover -tools.recover.help=#Helps recovering a corrupted database. -tools.restore=#Restore -tools.restore.help=#Restores a database backup. -tools.result=#Result -tools.run=#Run -tools.runScript=#RunScript -tools.runScript.help=#Runs a SQL script. -tools.script=#Script -tools.script.help=#Allows to convert a database to a SQL script for backup or migration. -tools.scriptFileName=#Script file name -tools.serverList=#Server list -tools.sourceDatabaseName=#Source database name -tools.sourceDatabaseURL=#Source database URL -tools.sourceDirectory=#Source directory -tools.sourceFileName=#Source file name -tools.sourceScriptFileName=#Source script file name -tools.targetDatabaseName=#Target database name -tools.targetDatabaseURL=#Target database URL -tools.targetDirectory=#Target directory -tools.targetFileName=#Target file name -tools.targetScriptFileName=#Target script file name -tools.traceFileName=#Trace file name -tree.admin=Администратор -tree.current=Текущее значение -tree.hashed=Hashed -tree.increment=Увеличить -tree.indexes=Индексы -tree.nonUnique=Неуникальное -tree.sequences=Последовательность -tree.unique=Уникальное -tree.users=Пользователи diff --git a/tools/h2/src/main/org/h2/server/web/res/_text_sk.prop b/tools/h2/src/main/org/h2/server/web/res/_text_sk.prop deleted file mode 100755 index 6e962ac..0000000 --- a/tools/h2/src/main/org/h2/server/web/res/_text_sk.prop +++ /dev/null @@ -1,149 +0,0 @@ -.translator=Ľubomír Grajciar -a.help=Pomocník -a.language=Slovensky -a.lynxNotSupported=Prepáčte, Lynx zatiaľ nie je podporovaný -a.password=Heslo -a.remoteConnectionsDisabled=Prepáčte, vzdialené pripojenia ('webAllowOthers') sú pre tento server zakázané. -a.title=H2 konzola -a.tools=Nástroje -a.user=Meno používateľa -admin.executing=Vykonávanie -admin.ip=IP -admin.lastAccess=Posledný prístup -admin.lastQuery=Posledný príkaz -admin.url=URL -adminAllow=Povolenia klientov -adminConnection=Bezpečnosť pripojenia -adminHttp=Použiť nešifrované HTTP pripojenia -adminHttps=Použiť šifrované SSL (HTTPS) pripojenia -adminLocal=Povoliť iba lokálne pripojenia -adminLogin=Prihlásenie Správcu -adminLoginCancel=Zrušiť -adminLoginOk=OK -adminLogout=Odhlásiť -adminOthers=Povoliť pripojenia z iných počítačov -adminPort=Číslo portu -adminPortWeb=Číslo portu Web servera -adminRestart=Zmeny sa vykonajú po reštarte servera -adminSave=Uložiť -adminSessions=Aktívne pripojenia -adminShutdown=Ukončiť H2 server -adminTitle=Nastavenia H2 konzoly -adminTranslateHelp=Preložiť alebo zlepšiť preklad H2 konzoly. -adminTranslateStart=Preložiť -helpAction=Akcia -helpAddAnotherRow=Pridať ďalší riadok -helpAddDrivers=Pridanie databázových ovládačov -helpAddDriversText=Ďalšie databázové ovládače môžu byť zaregistrované pridaním mena jar súboru ovládača aj s cestou do premennej prostredia H2DRIVERS alebo CLASSPATH. Napríklad (Windows): na pridanie knižnice databázového ovládača C:/Programs/hsqldb/lib/hsqldb.jar, nastavte premennú prostredia H2DRIVERS na C:/Programs/hsqldb/lib/hsqldb.jar. -helpAddRow=Pridať nový riadok -helpCommandHistory=Ukáž históriu príkazov -helpCreateTable=Vytvoriť novú tabuľku -helpDeleteRow=Odstrániť riadok -helpDisconnect=Odpojiť sa od databázy -helpDisplayThis=Zobraziť túto stránku pomocníka -helpDropTable=Zmazať tabuľku pokiaľ existuje -helpExecuteCurrent=Vykonať aktuálny SQL príkaz -helpIcon=Ikona -helpImportantCommands=Dôležité príkazy -helpOperations=Operácie -helpQuery=Vypýtať dáta z tabuľky -helpSampleSQL=Príklad SQL skriptu -helpStatements=SQL príkazy -helpUpdate=Zmeniť dáta v riadku -helpWithColumnsIdName=so stĺpcami ID a NAME -login.connect=Pripojiť -login.driverClass=Trieda ovládača -login.driverNotFound=Databázový ovládač nebol nájdený
Použite pomocníka na zistenie, ako pridať databázový ovládač -login.goAdmin=Nastavenia -login.jdbcUrl=JDBC URL -login.language=Jazyk -login.login=Prihlásenie -login.remove=Odstrániť -login.save=Uložiť -login.savedSetting=Uložené nastavenia -login.settingName=Meno nastavenia -login.testConnection=Test pripojenia -login.testSuccessful=Test úspešný -login.welcome=H2 konzola -result.1row=1 riadok -result.autoCommitOff=Automatický commit je teraz VYPNUTÝ -result.autoCommitOn=Automatický commit je teraz ZAPNUTÝ -result.bytes=bajtov -result.characters=znakov -result.maxrowsSet=Maximalny počet riadkov v skupine -result.noRows=žiadne riadky -result.noRunningStatement=Momentálne sa nevykonáva žiadny príkaz -result.rows=riadky/ov -result.statementWasCanceled=Príkaz bol zrušený -result.updateCount=Počet aktualizácii -resultEdit.add=Pridať -resultEdit.cancel=Zrušiť -resultEdit.delete=Zmazať -resultEdit.edit=Upraviť -resultEdit.editResult=Upraviť -resultEdit.save=Uložiť -toolbar.all=Všetko -toolbar.autoCommit=Auto commit -toolbar.autoComplete=Auto dokončovanie -toolbar.autoComplete.full=Plné -toolbar.autoComplete.normal=Normálne -toolbar.autoComplete.off=Vypnuté -toolbar.cancelStatement=Zrušiť aktuálny príkaz -toolbar.clear=Vyčistiť -toolbar.commit=Commit (schváliť) -toolbar.disconnect=Odpojiť -toolbar.history=História príkazov -toolbar.maxRows=Max. riadkov -toolbar.refresh=Obnoviť -toolbar.rollback=Rollback (odvolať) -toolbar.run=Spustiť (Ctrl+Enter) -toolbar.sqlStatement=SQL príkaz -tools.backup=Zálohovať -tools.backup.help=Vytvorenie zálohy databázy -tools.changeFileEncryption=ZmeniťŠifrovanieSúboru -tools.changeFileEncryption.help=Umožní zmeniť heslo a algoritmus šifrovania databázového súboru. -tools.cipher=Šifra (AES alebo XTEA) -tools.commandLine=Príkazový riadok -tools.convertTraceFile=PrekonvertovaťTraceSúbor -tools.convertTraceFile.help=Prekonvertuje .trace.db súbor na Java program a SQL skript. -tools.createCluster=VytvoriťKluster -tools.createCluster.help=Vytvoriť kluster zo samostatnej databázy. -tools.databaseName=Meno databázy -tools.decryptionPassword=Heslo na dešifrovanie -tools.deleteDbFiles=ZmazaťDbSúbory -tools.deleteDbFiles.help=Vymaže všetky súbory databázy -tools.directory=Priečinok -tools.encryptionPassword=Heslo na šifrovanie -tools.javaDirectoryClassName=Java priečinok a meno triedy -tools.recover=Opraviť -tools.recover.help=Umožní opraviť poškodenú databázu. -tools.restore=Obnoviť -tools.restore.help=Obnoviť databázu zo zálohy. -tools.result=Výsledok -tools.run=Spustiť -tools.runScript=SpustiťSkript -tools.runScript.help=Spustí SQL skript. -tools.script=Skript -tools.script.help=Umožní vytvoriť z databázy SQL skript na zálohu alebo prenesenie databázy. -tools.scriptFileName=Meno súboru skriptu -tools.serverList=Zoznam serverov -tools.sourceDatabaseName=Meno zdrojovej databázy -tools.sourceDatabaseURL=URL zdrojovej databázy -tools.sourceDirectory=Zdrojový priečinok -tools.sourceFileName=Meno zdrojového súboru -tools.sourceScriptFileName=Meno súboru zdrojového skriptu -tools.targetDatabaseName=Meno cieľovej databázy -tools.targetDatabaseURL=URL cieľovej databázy -tools.targetDirectory=Cieľový priečinok -tools.targetFileName=Meno cieľového súboru -tools.targetScriptFileName=Meno súboru cieľového skriptu -tools.traceFileName=Meno trace súboru -tree.admin=Admin -tree.current=Aktuálna hodnota -tree.hashed=Hashed (s kontrolným súčtom) -tree.increment=Inkrement -tree.indexes=Indexy -tree.nonUnique=Non unique (nie je jedinečný) -tree.sequences=Sekvencie -tree.unique=Unique (jedinečný) -tree.users=Používatelia diff --git a/tools/h2/src/main/org/h2/server/web/res/_text_tr.prop b/tools/h2/src/main/org/h2/server/web/res/_text_tr.prop deleted file mode 100755 index dc2035d..0000000 --- a/tools/h2/src/main/org/h2/server/web/res/_text_tr.prop +++ /dev/null @@ -1,149 +0,0 @@ -.translator=Rıdvan Ağar -a.help=Yardım -a.language=Türkçe -a.lynxNotSupported=Web tarayıcınız HTML Frames'i desteklemiyor. Frames (ve Javascript) desteği gerekli. -a.password=Şifre -a.remoteConnectionsDisabled=Başka bilgisayarlardan, veri tabanına bağlanma izni henüz ayarlanmamış ('webAllowOthers'). -a.title=H2 Konsolu -a.tools=Araçlar -a.user=Kullanıcı adı -admin.executing=Aktif -admin.ip=IP -admin.lastAccess=Son bağlantı -admin.lastQuery=Son komut -admin.url=URL -adminAllow=İzin verilen bağlantılar -adminConnection=Bağlantı güvenliği -adminHttp=Şifrelenmemiş HTTP bağlantıları -adminHttps=Şifrelenmiş HTTP bağlantıları -adminLocal=Sadece yerel bağlantılara izin ver -adminLogin=Yönetim girişi -adminLoginCancel=İptal et -adminLoginOk=Tamam -adminLogout=Bitir -adminOthers=Başka bilgisayarlardan, veri tabanına bağlanma izni ver -adminPort=Port -adminPortWeb=Web-Server Port -adminRestart=Değişiklikler veri tabanı hizmetçisinin yeniden başlatılmasıyla etkinlik kazanacak. -adminSave=Kaydet -adminSessions=Aktif bağlantılar -adminShutdown=Kapat -adminTitle=H2 Konsol ayarları -adminTranslateHelp=H2 Kullanıcı arayüzünü (H2 Konsol) dilinize çevirin yada çeviriyi düzeltin. -adminTranslateStart=Çeviri -helpAction=Aksiyon -helpAddAnotherRow=Yeni bir satır ekle -helpAddDrivers=Veritabanı sürücüsü ekle -helpAddDriversText=Yeni veri tabanı sürücüleri eklemek için, sürücü dosyalarının yerini H2DRIVERS yada CLASSPATH çevre değişkenlerine ekleyebilirsiniz. Örnek (Windows): Sürücü dosyası C:/Programs/hsqldb/lib/hsqldb.jar ise H2DRIVERS değişkenini C:/Programs/hsqldb/lib/hsqldb.jar olarak girin. -helpAddRow=Veri tabanına yeni bir satır ekler -helpCommandHistory=Komut tarihçesini gösterir -helpCreateTable=Veri tabanına yeni bir tabela ekler -helpDeleteRow=Tabeladan satırı siler -helpDisconnect=Veri tabanı bağlantısını keser -helpDisplayThis=Bu yardım sayfasını gösterir -helpDropTable=Var ise, istenen tabelayı siler -helpExecuteCurrent=Girilen SQL komutunu icra eder -helpIcon=Şalter -helpImportantCommands=Önemli komutlar -helpOperations=İşlemler -helpQuery=Tabela içeriğini gösterir -helpSampleSQL=Örnek SQL -helpStatements=SQL komutları -helpUpdate=Bir tabeladaki belli bir satır içeriğini değiştirir -helpWithColumnsIdName=Colon isimleriyle birlikte -login.connect=Bağlan -login.driverClass=Veri tabanı sürücü sınıfı -login.driverNotFound=İstenilen veri tabanı sürücüsü bulunamadı
Sürücü ekleme konusunda bilgi için Yardım'a başvurunuz -login.goAdmin=Seçenekler -login.jdbcUrl=JDBC URL -login.language=Dil -login.login=Giriş -login.remove=Sil -login.save=Kaydet -login.savedSetting=Kayıtlı ayarlar -login.settingName=Ayar adı -login.testConnection=Bağlantıyı test et -login.testSuccessful=Test başarılı -login.welcome=H2 Konsolu -result.1row=1 dizi -result.autoCommitOff=Auto-Commit kapatıldı -result.autoCommitOn=Auto-Commit açıldı -result.bytes=#bytes -result.characters=#characters -result.maxrowsSet=Maximum dizi sayısı ayarı yapıldı -result.noRows=Hiç bir bilgi yok -result.noRunningStatement=Şu an bir komut icra ediliyor -result.rows=Dizi -result.statementWasCanceled=Komut iptal edildi -result.updateCount=Güncelleşterilen dizi sayısı -resultEdit.add=Ekle -resultEdit.cancel=İptal -resultEdit.delete=Sil -resultEdit.edit=Değiştir -resultEdit.editResult=Değiştir -resultEdit.save=Kaydet -toolbar.all=Hepsi -toolbar.autoCommit=Auto-Commit -toolbar.autoComplete=Auto-Complete -toolbar.autoComplete.full=Hepsi -toolbar.autoComplete.normal=Normal -toolbar.autoComplete.off=Kapalı -toolbar.cancelStatement=Yürütülen işlemi iptal et -toolbar.clear=Temizle -toolbar.commit=Degişiklikleri kaydet -toolbar.disconnect=Bağlantıyı kes -toolbar.history=Verilmiş olan komutlar -toolbar.maxRows=Maximum dizi sayısı -toolbar.refresh=Güncelleştir -toolbar.rollback=Değişiklikleri geri al -toolbar.run=İşlemi yürüt -toolbar.sqlStatement=SQL komutu -tools.backup=Yedekle -tools.backup.help=Bir veritabanının yedeklemesini yapar. -tools.changeFileEncryption=DosyaKodla -tools.changeFileEncryption.help=Veritabanının dosya kodlama şifresi ve türünü belirler. -tools.cipher=Şifreleme türü (AES yada XTEA) -tools.commandLine=Komut -tools.convertTraceFile=TraceDosyasiDönüştür -tools.convertTraceFile.help=Verilen bir trace.db dosyasını Java uygulamasına ve SQL-Betiğe çevirir. -tools.createCluster=KümeYarat -tools.createCluster.help=Bağımsız bir veritabanından bir küme (Cluster) yaratır. -tools.databaseName=Veritabanının adı -tools.decryptionPassword=Kod çözme şifresi -tools.deleteDbFiles=VeritabanıDosyalarınıSil -tools.deleteDbFiles.help=Bir veritabanına ait bütün dosyaları siler. -tools.directory=Dizelge -tools.encryptionPassword=Kodlama şifresi -tools.javaDirectoryClassName=Java dizelge ve sınıf adı -tools.recover=Kurtar -tools.recover.help=Bozuk bir veritabanının kurtarılmasına yardımcı olur. -tools.restore=YenidenY???#252kle -tools.restore.help=Bir veritabanının yedeklemesini yeniden yükler. -tools.result=Sonuç -tools.run=İşlemi yürüt -tools.runScript=BetikÇalıştır -tools.runScript.help=Bir betik dosyası çalıştırır. -tools.script=Betik -tools.script.help=Bir veritabanının yedekleme yada taşıma amaçlı SQL-Betiğe çevrilmesini sağlar -tools.scriptFileName=Betik dosya adı -tools.serverList=Hizmetçi listesi -tools.sourceDatabaseName=Kaynak veritabanının adı -tools.sourceDatabaseURL=Kaynak veritabanının URL'u -tools.sourceDirectory=Kaynak dizelge -tools.sourceFileName=Kaynak dosya adı -tools.sourceScriptFileName=Kaynak betik dosya adı -tools.targetDatabaseName=Hedef veritabanının adı -tools.targetDatabaseURL=Hedef veritabanının URL'u -tools.targetDirectory=Hedef dizelge -tools.targetFileName=Hedef dosya adı -tools.targetScriptFileName=Hedef betik dosya adı -tools.traceFileName=Trace dosya adı -tree.admin=Yönetici -tree.current=Güncel değer -tree.hashed=Hash tabanlı -tree.increment=Artır -tree.indexes=Indexler -tree.nonUnique=eşsiz değil -tree.sequences=Dizinler -tree.unique=Eşsiz -tree.users=Kullanıcı diff --git a/tools/h2/src/main/org/h2/server/web/res/_text_uk.prop b/tools/h2/src/main/org/h2/server/web/res/_text_uk.prop deleted file mode 100755 index 84f818b..0000000 --- a/tools/h2/src/main/org/h2/server/web/res/_text_uk.prop +++ /dev/null @@ -1,149 +0,0 @@ -.translator=Igor Dobrovolskyi -a.help=Допомога -a.language=Українська -a.lynxNotSupported=Вибачте, але Lynx не підтримується -a.password=Пароль -a.remoteConnectionsDisabled=Вибачте, віддалені підключення ('webAllowOthers') на цьому сервері заборонені. -a.title=Консоль H2 -a.tools=#Tools -a.user=Iм'я користувача -admin.executing=Виконується -admin.ip=IP -admin.lastAccess=Останній доступ -admin.lastQuery=Останній запит -admin.url=URL -adminAllow=Дозволені клієнти -adminConnection=Безпека під'єднання -adminHttp=Використовуйте незашифровані HTTP під'єднання -adminHttps=Використовуйте зашифровані SSL (HTTPS) під'єднання -adminLocal=Дозволено лише локальні під'єднання -adminLogin=Адміністративний логін -adminLoginCancel=Відмінити -adminLoginOk=OK -adminLogout=Завершення сеансу -adminOthers=Дозволити під'єднання з інших копм'ютерів -adminPort=Номер порта -adminPortWeb=Номер порта веб сервера -adminRestart=Зміни вступлять в силу після перезавантаження сервера. -adminSave=Зберегти -adminSessions=Активні сесії -adminShutdown=Виключити -adminTitle=Настройки консолі H2 -adminTranslateHelp=#Translate or improve the translation of the H2 Console. -adminTranslateStart=#Translate -helpAction=Дія -helpAddAnotherRow=Додати новий рядок -helpAddDrivers=Додати драйвер бази даних -helpAddDriversText=Нові драйвери баз даних можуть бути зареєстровані додаванням шляху до Jar-файлу з драйвером до змінної оточення H2DRIVERS або CLASSPATH. Наприклад (Windows): Щоб додати драйвер бази даних C:/Programs/hsqldb/lib/hsqldb.jar, встановіть змінну оточення H2DRIVERS рівною C:/Programs/hsqldb/lib/hsqldb.jar. -helpAddRow=Додати новий рядок -helpCommandHistory=Показує історію команд -helpCreateTable=Створити нову таблицю -helpDeleteRow=Видалити рядок -helpDisconnect=Від'єднує від бази даних -helpDisplayThis=Показує цю сторінку допомоги -helpDropTable=Видалити таблицю, якщо вона існує -helpExecuteCurrent=Виконує поточний SQL запит -helpIcon=Iконка -helpImportantCommands=Важливі команди -helpOperations=Операції -helpQuery=Запит до таблиці -helpSampleSQL=Приклад SQL запиту -helpStatements=SQL запити -helpUpdate=Змінити дані в рядку -helpWithColumnsIdName=з колонками ID і NAME -login.connect=Під'єднатись -login.driverClass=Driver Class -login.driverNotFound=Дравер бази даних не знайдено
Подивіться в допомозі як додати нові драйвери -login.goAdmin=Настройки -login.jdbcUrl=JDBC URL -login.language=Мова -login.login=Логін -login.remove=Видалити -login.save=Зберегти -login.savedSetting=Збережені налаштування -login.settingName=Iм'я налаштування -login.testConnection=Тестове під'єднання -login.testSuccessful=Тест пройдено успішно -login.welcome=Консоль H2 -result.1row=1 рядок -result.autoCommitOff=Автозбереження виключене -result.autoCommitOn=Автозбереження включене -result.bytes=#bytes -result.characters=#characters -result.maxrowsSet=Встановлено максимальну кількість рядків -result.noRows=немає рядків -result.noRunningStatement=В даний момент не виконується жоден запит -result.rows=рядків -result.statementWasCanceled=Запит було відмінено -result.updateCount=Кількість змінених -resultEdit.add=Додати -resultEdit.cancel=Відмінити -resultEdit.delete=Видалити -resultEdit.edit=Редагувати -resultEdit.editResult=Редагувати -resultEdit.save=Зберегти -toolbar.all=Всі -toolbar.autoCommit=Автозбереження -toolbar.autoComplete=Авто доповнення -toolbar.autoComplete.full=Повне -toolbar.autoComplete.normal=Нормальне -toolbar.autoComplete.off=Виключене -toolbar.cancelStatement=Відмінити поточний запит -toolbar.clear=Очистити -toolbar.commit=Підтвердити зміни -toolbar.disconnect=Від'єднатись -toolbar.history=Iсторія команд -toolbar.maxRows=Максимальна кількість рядків -toolbar.refresh=Оновити -toolbar.rollback=Вернути назад -toolbar.run=Виконати (Ctrl+Enter) -toolbar.sqlStatement=SQL запит -tools.backup=#Backup -tools.backup.help=#Creates a backup of a database. -tools.changeFileEncryption=#ChangeFileEncryption -tools.changeFileEncryption.help=#Allows changing the database file encryption password and algorithm. -tools.cipher=#Cipher (AES or XTEA) -tools.commandLine=#Command line -tools.convertTraceFile=#ConvertTraceFile -tools.convertTraceFile.help=#Converts a .trace.db file to a Java application and SQL script. -tools.createCluster=#CreateCluster -tools.createCluster.help=#Creates a cluster from a standalone database. -tools.databaseName=#Database name -tools.decryptionPassword=#Decryption password -tools.deleteDbFiles=#DeleteDbFiles -tools.deleteDbFiles.help=#Deletes all files belonging to a database. -tools.directory=#Directory -tools.encryptionPassword=#Encryption password -tools.javaDirectoryClassName=#Java directory and class name -tools.recover=#Recover -tools.recover.help=#Helps recovering a corrupted database. -tools.restore=#Restore -tools.restore.help=#Restores a database backup. -tools.result=#Result -tools.run=#Run -tools.runScript=#RunScript -tools.runScript.help=#Runs a SQL script. -tools.script=#Script -tools.script.help=#Allows to convert a database to a SQL script for backup or migration. -tools.scriptFileName=#Script file name -tools.serverList=#Server list -tools.sourceDatabaseName=#Source database name -tools.sourceDatabaseURL=#Source database URL -tools.sourceDirectory=#Source directory -tools.sourceFileName=#Source file name -tools.sourceScriptFileName=#Source script file name -tools.targetDatabaseName=#Target database name -tools.targetDatabaseURL=#Target database URL -tools.targetDirectory=#Target directory -tools.targetFileName=#Target file name -tools.targetScriptFileName=#Target script file name -tools.traceFileName=#Trace file name -tree.admin=Адмін -tree.current=Поточне значення -tree.hashed=Хешований -tree.increment=Збільшити -tree.indexes=Iндекси -tree.nonUnique=Неунікальне -tree.sequences=Послідовності -tree.unique=Унікальне -tree.users=Користувачі diff --git a/tools/h2/src/main/org/h2/server/web/res/_text_zh_cn.prop b/tools/h2/src/main/org/h2/server/web/res/_text_zh_cn.prop deleted file mode 100755 index 0b196e4..0000000 --- a/tools/h2/src/main/org/h2/server/web/res/_text_zh_cn.prop +++ /dev/null @@ -1,149 +0,0 @@ -.translator=junheng.song (sjh21 (at) hot mail (dot) com); Created by JInto - www.guh-software.de - Mon Apr 10 2006 -a.help=帮助 -a.language=中文 (简体) -a.lynxNotSupported=抱歉, 目前还不支持Lynx -a.password=密码 -a.remoteConnectionsDisabled=抱歉, 服务器上的远程计算机连接被禁用. -a.title=H2 控制台 -a.tools=#Tools -a.user=用户名 -admin.executing=执行 -admin.ip=IP地址 -admin.lastAccess=最后访问 -admin.lastQuery=最后查询 -admin.url=URL -adminAllow=允许连接的客户端 -adminConnection=连接安全 -adminHttp=使用非加密的 HTTP 连接 -adminHttps=使用加密的 SSL (HTTPS) 连接 -adminLocal=只允许本地连接 -adminLogin=管理员登录 -adminLoginCancel=取消 -adminLoginOk=确认 -adminLogout=注销 -adminOthers=允许来自其他远程计算机的连接 -adminPort=端口号 -adminPortWeb=Web server 端口号 -adminRestart=重启服务器后修改配置将生效. -adminSave=保存 -adminSessions=活动的会话 -adminShutdown=关闭 -adminTitle=H2 控制台配置 -adminTranslateHelp=#Translate or improve the translation of the H2 Console. -adminTranslateStart=#Translate -helpAction=活动 -helpAddAnotherRow=增加另一行 -helpAddDrivers=增加数据库驱动 -helpAddDriversText=可以通过添加系统环境变量H2DRIVERS 或者 CLASSPATH 来增加数据库驱动注册。例如(Windows):要增加数据库驱动C:/Programs/hsqldb/lib/hsqldb.jar,可以增加系统环境变量H2DRIVERS并设置到C:/Programs/hsqldb/lib/hsqldb.jar。 -helpAddRow=增加新的一行 -helpCommandHistory=显示历史SQL命令 -helpCreateTable=创建一个新表 -helpDeleteRow=删除一行 -helpDisconnect=断开数据库连接 -helpDisplayThis=显示帮助页 -helpDropTable=如果表存在删除它 -helpExecuteCurrent=执行当前SQL语句 -helpIcon=图标 -helpImportantCommands=重要的命令 -helpOperations=操作 -helpQuery=查询表 -helpSampleSQL=样例SQL脚本 -helpStatements=SQL 语句 -helpUpdate=改变一行数据 -helpWithColumnsIdName=用ID和NAME列 -login.connect=连接 -login.driverClass=驱动类 -login.driverNotFound=数据库驱动没有发现
请参考帮助去添加数据库驱动 -login.goAdmin=配置 -login.jdbcUrl=JDBC URL -login.language=语言 -login.login=登录 -login.remove=删除 -login.save=保存 -login.savedSetting=保存的连接设置 -login.settingName=连接设置名称 -login.testConnection=测试连接 -login.testSuccessful=测试成功 -login.welcome=H2 控制台 -result.1row=1 行 -result.autoCommitOff=自动提交现在为关闭 -result.autoCommitOn=自动提交现在为打开 -result.bytes=#bytes -result.characters=#characters -result.maxrowsSet=最大返回行数被设置 -result.noRows=无返回行 -result.noRunningStatement=当前没有正在执行的SQL语句 -result.rows=行 -result.statementWasCanceled=SQL 语句被取消 -result.updateCount=更新行数 -resultEdit.add=增加 -resultEdit.cancel=取消 -resultEdit.delete=删除 -resultEdit.edit=编辑 -resultEdit.editResult=编辑结果集 -resultEdit.save=保存 -toolbar.all=全部 -toolbar.autoCommit=自动提交 -toolbar.autoComplete=#Auto complete -toolbar.autoComplete.full=#Full -toolbar.autoComplete.normal=#Normal -toolbar.autoComplete.off=#Off -toolbar.cancelStatement=取消当前的执行语句 -toolbar.clear=清除 -toolbar.commit=提交 -toolbar.disconnect=断开连接 -toolbar.history=历史SQL命令 -toolbar.maxRows=最大行数 -toolbar.refresh=刷新 -toolbar.rollback=回滚 -toolbar.run=执行 (Ctrl+Enter) -toolbar.sqlStatement=SQL 语句 -tools.backup=#Backup -tools.backup.help=#Creates a backup of a database. -tools.changeFileEncryption=#ChangeFileEncryption -tools.changeFileEncryption.help=#Allows changing the database file encryption password and algorithm. -tools.cipher=#Cipher (AES or XTEA) -tools.commandLine=#Command line -tools.convertTraceFile=#ConvertTraceFile -tools.convertTraceFile.help=#Converts a .trace.db file to a Java application and SQL script. -tools.createCluster=#CreateCluster -tools.createCluster.help=#Creates a cluster from a standalone database. -tools.databaseName=#Database name -tools.decryptionPassword=#Decryption password -tools.deleteDbFiles=#DeleteDbFiles -tools.deleteDbFiles.help=#Deletes all files belonging to a database. -tools.directory=#Directory -tools.encryptionPassword=#Encryption password -tools.javaDirectoryClassName=#Java directory and class name -tools.recover=#Recover -tools.recover.help=#Helps recovering a corrupted database. -tools.restore=#Restore -tools.restore.help=#Restores a database backup. -tools.result=#Result -tools.run=#Run -tools.runScript=#RunScript -tools.runScript.help=#Runs a SQL script. -tools.script=#Script -tools.script.help=#Allows to convert a database to a SQL script for backup or migration. -tools.scriptFileName=#Script file name -tools.serverList=#Server list -tools.sourceDatabaseName=#Source database name -tools.sourceDatabaseURL=#Source database URL -tools.sourceDirectory=#Source directory -tools.sourceFileName=#Source file name -tools.sourceScriptFileName=#Source script file name -tools.targetDatabaseName=#Target database name -tools.targetDatabaseURL=#Target database URL -tools.targetDirectory=#Target directory -tools.targetFileName=#Target file name -tools.targetScriptFileName=#Target script file name -tools.traceFileName=#Trace file name -tree.admin=管理 -tree.current=当前值 -tree.hashed=杂乱的 -tree.increment=增加 -tree.indexes=索引 -tree.nonUnique=不唯一 -tree.sequences=序列 -tree.unique=唯一 -tree.users=用户 diff --git a/tools/h2/src/main/org/h2/server/web/res/_text_zh_tw.prop b/tools/h2/src/main/org/h2/server/web/res/_text_zh_tw.prop deleted file mode 100755 index 5f0072c..0000000 --- a/tools/h2/src/main/org/h2/server/web/res/_text_zh_tw.prop +++ /dev/null @@ -1,149 +0,0 @@ -.translator=derek chao (Dept of Geog., CCU, Taiwan), 2008.04.20 -a.help=輔助說明 -a.language=中文 (繁體) -a.lynxNotSupported=抱歉, 目前還不支援Lynx瀏覽器 -a.password=密碼 -a.remoteConnectionsDisabled=抱歉, 本伺服器禁用遠端連接 ('webAllowOthers'). -a.title=H2 控制台 -a.tools=#Tools -a.user=使用者名稱 -admin.executing=執行 -admin.ip=IP位址 -admin.lastAccess=上次存取 -admin.lastQuery=上次查詢 -admin.url=URL -adminAllow=允許連接的客戶端 -adminConnection=連接之安全性 -adminHttp=使用非加密的 HTTP 連接 -adminHttps=使用加密的 SSL (HTTPS) 連接 -adminLocal=只允許本地連接 -adminLogin=管理員登入 -adminLoginCancel=取消 -adminLoginOk=確定 -adminLogout=登出 -adminOthers=允許來自其他電腦的連接 -adminPort=通訊埠 -adminPortWeb=Web 伺服器的通訊埠 -adminRestart=伺服器重新啟動後修改才會生效. -adminSave=儲存 -adminSessions=作用中的進程 (Active Sessions) -adminShutdown=關閉 -adminTitle=H2 控制台個人喜好設定 -adminTranslateHelp=#Translate or improve the translation of the H2 Console. -adminTranslateStart=#Translate -helpAction=動作 -helpAddAnotherRow=增加另一資料列 (row) -helpAddDrivers=增加資料庫驅動程式 -helpAddDriversText=可以透過添加系統環境變量H2DRIVERS 或 CLASSPATH 指向Jar檔案的位置,來註冊資料庫的驅動程式。例如(在Windows系統內):添加系統環境變數H2DRIVERS並指向C:/Programs/hsqldb/lib/hsqldb.jar,即可將C:/Programs/hsqldb/lib/hsqldb.jar資料庫驅動程式庫加入。 -helpAddRow=增加新的資料列 (row) -helpCommandHistory=顯示命令史 -helpCreateTable=創建新資料表 -helpDeleteRow=刪除資料列 (row) -helpDisconnect=中斷資料庫連接 -helpDisplayThis=顯示輔助說明頁 -helpDropTable=刪除存在的資料表 -helpExecuteCurrent=執行目前的SQL述句 -helpIcon=圖示 -helpImportantCommands=重要命令 -helpOperations=操作 -helpQuery=資料表查詢 -helpSampleSQL=範例SQL腳本 -helpStatements=SQL述句 -helpUpdate=變更資料列 (row) 中的資料 -helpWithColumnsIdName=用ID和NAME欄位 -login.connect=連接 -login.driverClass=驅動程式類別 (Driver Class) -login.driverNotFound=沒有找到資料庫驅動程式
請參考輔助說明來添加驅動程式 -login.goAdmin=個人喜好設定 -login.jdbcUrl=JDBC URL -login.language=語言 -login.login=登入 -login.remove=刪除 -login.save=儲存 -login.savedSetting=儲存的設定值 -login.settingName=設定的名稱 -login.testConnection=測試連接 -login.testSuccessful=測試成功 -login.welcome=H2 控制台 -result.1row=1列資料列 (row) -result.autoCommitOff=自動提交現在為關閉狀態 -result.autoCommitOn=自動提交現在為開啟狀態 -result.bytes=#bytes -result.characters=#characters -result.maxrowsSet=最大資料列 (rowcount) 設定完成 -result.noRows=無資料列 (rows) -result.noRunningStatement=目前沒有正在執行的SQL述句 -result.rows=資料列 (rows) -result.statementWasCanceled=SQL述句已取消 -result.updateCount=更新計數 -resultEdit.add=增加 -resultEdit.cancel=取消 -resultEdit.delete=刪除 -resultEdit.edit=編輯 -resultEdit.editResult=編輯 -resultEdit.save=儲存 -toolbar.all=全部 -toolbar.autoCommit=自動提交 -toolbar.autoComplete=自動完成 (complete) -toolbar.autoComplete.full=完整 -toolbar.autoComplete.normal=標準 -toolbar.autoComplete.off=關閉 -toolbar.cancelStatement=取消目前的SQL述句 -toolbar.clear=清除 -toolbar.commit=提交 -toolbar.disconnect=中斷連接 -toolbar.history=命令史 -toolbar.maxRows=最大資料列 (rows) -toolbar.refresh=更新 -toolbar.rollback=退返 (rollback) -toolbar.run=執行 (Ctrl+Enter) -toolbar.sqlStatement=SQL 述句 -tools.backup=備份 -tools.backup.help=建立資料庫的備份 -tools.changeFileEncryption=#ChangeFileEncryption -tools.changeFileEncryption.help=#Allows changing the database file encryption password and algorithm. -tools.cipher=加密 (AES 或 XTEA) -tools.commandLine=命令列 -tools.convertTraceFile=轉換Trace檔案 -tools.convertTraceFile.help=將.trace.db檔案轉換成Java應用程式與SQL腳本 (script). -tools.createCluster=建立叢集 (Cluster) -tools.createCluster.help=自獨立的資料庫建立叢集 (Cluster) -tools.databaseName=資料庫名稱 -tools.decryptionPassword=明文密碼 -tools.deleteDbFiles=刪除資料庫檔案 -tools.deleteDbFiles.help=刪除某一資料庫的所有相關檔案 -tools.directory=目錄 -tools.encryptionPassword=密文密碼 -tools.javaDirectoryClassName=Java目錄 (directory) 與類別 (class) 名稱 -tools.recover=修復 -tools.recover.help=協助修復損壞的資料庫 -tools.restore=回存 -tools.restore.help=回存資料庫的備份 -tools.result=結果 -tools.run=執行 -tools.runScript=執行腳本 (Script) -tools.runScript.help=執行SQL腳本 (script) -tools.script=腳本 (Script) -tools.script.help=允許自資料庫轉換出為備份或搬遷用的SQL腳本(script) -tools.scriptFileName=腳本 (Script) 檔案名稱 -tools.serverList=伺服器清單 -tools.sourceDatabaseName=來源 (source) 資料庫名稱 -tools.sourceDatabaseURL=來源 (source) 資料庫URL -tools.sourceDirectory=來源目錄 (source directory) -tools.sourceFileName=來源 (source) 檔案名稱 -tools.sourceScriptFileName=來源腳本 (script) 檔案名稱 -tools.targetDatabaseName=目的 (target) 資料庫名稱 -tools.targetDatabaseURL=目的 (target) 資料庫URL -tools.targetDirectory=目的目錄 (target directory) -tools.targetFileName=目的 (target) 檔案名稱 -tools.targetScriptFileName=目的腳本 (script) 檔案名稱 -tools.traceFileName=Trace 檔案名稱 -tree.admin=管理 -tree.current=目前的數值 -tree.hashed=使用雜湊法 (hashed) -tree.increment=遞增 -tree.indexes=索引 -tree.nonUnique=非唯一 -tree.sequences=序列 -tree.unique=唯一 -tree.users=使用者 diff --git a/tools/h2/src/main/org/h2/server/web/res/admin.jsp b/tools/h2/src/main/org/h2/server/web/res/admin.jsp deleted file mode 100755 index e3e9dd2..0000000 --- a/tools/h2/src/main/org/h2/server/web/res/admin.jsp +++ /dev/null @@ -1,135 +0,0 @@ - - - - - ${text.a.title} - - - - - - -

- ${text.adminTitle} -

-

- ${text.adminLogout} -

-
-
-

- ${text.adminAllow} -

-

- - - - - - - ${text.adminLocal}
- - - - - - - - ${text.adminOthers}
-

-

- ${text.adminConnection} -

-

- - - - - - - ${text.adminHttp}
- - - - - - - - ${text.adminHttps}
-

-

- ${text.adminPort} -

-

- ${text.adminPortWeb}: -

-
-

- -

-

- ${text.adminRestart} -

-
-
-

-

- -
-

-

- ${text.adminTranslateHelp} -

-
-

- ${text.adminSessions} -

- - - - - - - - - - - - - - - - - - - -
${text.admin.ip}${text.admin.url}${text.a.user}${text.admin.executing}${text.admin.lastAccess}${text.admin.lastQuery}
- ${item.ip} - - ${item.url} - - ${item.user} - - ${item.executing} - - ${item.lastAccess} - - ${item.lastQuery} -
-
-
- -
- \ No newline at end of file diff --git a/tools/h2/src/main/org/h2/server/web/res/adminLogin.jsp b/tools/h2/src/main/org/h2/server/web/res/adminLogin.jsp deleted file mode 100755 index 13e9255..0000000 --- a/tools/h2/src/main/org/h2/server/web/res/adminLogin.jsp +++ /dev/null @@ -1,55 +0,0 @@ - - - - - ${text.a.title} - - - - - - -
- - - - - - - - - - - - - - - -
-

${error}

-
- - - \ No newline at end of file diff --git a/tools/h2/src/main/org/h2/server/web/res/autoCompleteList.jsp b/tools/h2/src/main/org/h2/server/web/res/autoCompleteList.jsp deleted file mode 100755 index 8d68480..0000000 --- a/tools/h2/src/main/org/h2/server/web/res/autoCompleteList.jsp +++ /dev/null @@ -1 +0,0 @@ -${autoCompleteList} \ No newline at end of file diff --git a/tools/h2/src/main/org/h2/server/web/res/background.gif b/tools/h2/src/main/org/h2/server/web/res/background.gif deleted file mode 100755 index f8832e6..0000000 Binary files a/tools/h2/src/main/org/h2/server/web/res/background.gif and /dev/null differ diff --git a/tools/h2/src/main/org/h2/server/web/res/error.jsp b/tools/h2/src/main/org/h2/server/web/res/error.jsp deleted file mode 100755 index 4be869d..0000000 --- a/tools/h2/src/main/org/h2/server/web/res/error.jsp +++ /dev/null @@ -1,18 +0,0 @@ - - - - - ${text.a.title} - - - -

- ${error} -

- \ No newline at end of file diff --git a/tools/h2/src/main/org/h2/server/web/res/favicon.ico b/tools/h2/src/main/org/h2/server/web/res/favicon.ico deleted file mode 100755 index 6e0f78a..0000000 Binary files a/tools/h2/src/main/org/h2/server/web/res/favicon.ico and /dev/null differ diff --git a/tools/h2/src/main/org/h2/server/web/res/frame.jsp b/tools/h2/src/main/org/h2/server/web/res/frame.jsp deleted file mode 100755 index 228fded..0000000 --- a/tools/h2/src/main/org/h2/server/web/res/frame.jsp +++ /dev/null @@ -1,30 +0,0 @@ - - - - - - ${text.a.title} - - - - - - - - - - - - - -<body> - ${text.a.lynxNotSupported} -</body> - - diff --git a/tools/h2/src/main/org/h2/server/web/res/header.jsp b/tools/h2/src/main/org/h2/server/web/res/header.jsp deleted file mode 100755 index 5b7d8d8..0000000 --- a/tools/h2/src/main/org/h2/server/web/res/header.jsp +++ /dev/null @@ -1,94 +0,0 @@ - - - - - - ${text.a.title} - - - -
-
${text.toolbar.disconnect}${text.toolbar.refresh}${text.toolbar.autoCommit} ${text.toolbar.rollback}${text.toolbar.commit} ${text.toolbar.maxRows}:  ${text.toolbar.run}${text.toolbar.cancelStatement}${text.toolbar.history}${text.toolbar.autoComplete} ${text.a.help}
-
- - - diff --git a/tools/h2/src/main/org/h2/server/web/res/help.jsp b/tools/h2/src/main/org/h2/server/web/res/help.jsp deleted file mode 100755 index 34586fc..0000000 --- a/tools/h2/src/main/org/h2/server/web/res/help.jsp +++ /dev/null @@ -1,92 +0,0 @@ - - - - - - ${text.a.title} - - - - - - -
- -

${text.helpImportantCommands}

- - - - - - - - - - - - - - - - - -
${text.a.help} - ${text.helpDisplayThis} -
${text.toolbar.history} - ${text.helpCommandHistory} -
${text.toolbar.run} - ${text.helpExecuteCurrent} -
${text.toolbar.disconnect} - ${text.helpDisconnect} -
- -

${text.helpSampleSQL}

- - - -
- ${text.helpDropTable}
- ${text.helpCreateTable}
-   ${text.helpWithColumnsIdName}
- ${text.helpAddRow}
- ${text.helpAddAnotherRow}
- ${text.helpQuery}
- ${text.helpUpdate}
- ${text.helpDeleteRow} -
- DROP TABLE IF EXISTS TEST;
- CREATE TABLE TEST(ID INT PRIMARY KEY,
-    NAME VARCHAR(255));
- INSERT INTO TEST VALUES(1, 'Hello');
- INSERT INTO TEST VALUES(2, 'World');
- SELECT * FROM TEST ORDER BY ID;
- UPDATE TEST SET NAME='Hi' WHERE ID=1;
- DELETE FROM TEST WHERE ID=2; -
- ${text.a.help} - - HELP ... -
- -

${text.helpAddDrivers}

-

-${text.helpAddDriversText} -

- -
- -
- - diff --git a/tools/h2/src/main/org/h2/server/web/res/helpTranslate.jsp b/tools/h2/src/main/org/h2/server/web/res/helpTranslate.jsp deleted file mode 100755 index 3d64ac6..0000000 --- a/tools/h2/src/main/org/h2/server/web/res/helpTranslate.jsp +++ /dev/null @@ -1,45 +0,0 @@ - - - - - - ${text.a.title} - - - - -
- -

Translate

-

-You can now translate the file ${translationFile} with your favorite editor. -

-

-To view the changes in context, save the file and refresh the browser. -The H2 Console reads the file every second. -

-

-When done, please send the file to the H2 support. -Please send the file as an attachment (to avoid line breaks). -

-

-To translate from scratch: -

-
  • Stop the H2 Console -
  • Rename or delete the translation file -
  • Start the H2 Console -
  • Select the source language of your choice -
  • Go to 'Preferences' and click 'Translation' -
- -${text.adminLogout} - -
- - \ No newline at end of file diff --git a/tools/h2/src/main/org/h2/server/web/res/ico_add.gif b/tools/h2/src/main/org/h2/server/web/res/ico_add.gif deleted file mode 100755 index 252d7eb..0000000 Binary files a/tools/h2/src/main/org/h2/server/web/res/ico_add.gif and /dev/null differ diff --git a/tools/h2/src/main/org/h2/server/web/res/ico_ok.gif b/tools/h2/src/main/org/h2/server/web/res/ico_ok.gif deleted file mode 100755 index 9e80aaf..0000000 Binary files a/tools/h2/src/main/org/h2/server/web/res/ico_ok.gif and /dev/null differ diff --git a/tools/h2/src/main/org/h2/server/web/res/ico_remove.gif b/tools/h2/src/main/org/h2/server/web/res/ico_remove.gif deleted file mode 100755 index 64b4384..0000000 Binary files a/tools/h2/src/main/org/h2/server/web/res/ico_remove.gif and /dev/null differ diff --git a/tools/h2/src/main/org/h2/server/web/res/ico_search.gif b/tools/h2/src/main/org/h2/server/web/res/ico_search.gif deleted file mode 100755 index a4548c5..0000000 Binary files a/tools/h2/src/main/org/h2/server/web/res/ico_search.gif and /dev/null differ diff --git a/tools/h2/src/main/org/h2/server/web/res/ico_undo.gif b/tools/h2/src/main/org/h2/server/web/res/ico_undo.gif deleted file mode 100755 index d77f94f..0000000 Binary files a/tools/h2/src/main/org/h2/server/web/res/ico_undo.gif and /dev/null differ diff --git a/tools/h2/src/main/org/h2/server/web/res/ico_write.gif b/tools/h2/src/main/org/h2/server/web/res/ico_write.gif deleted file mode 100755 index feb8e94..0000000 Binary files a/tools/h2/src/main/org/h2/server/web/res/ico_write.gif and /dev/null differ diff --git a/tools/h2/src/main/org/h2/server/web/res/icon_commit.gif b/tools/h2/src/main/org/h2/server/web/res/icon_commit.gif deleted file mode 100755 index ac8e3ee..0000000 Binary files a/tools/h2/src/main/org/h2/server/web/res/icon_commit.gif and /dev/null differ diff --git a/tools/h2/src/main/org/h2/server/web/res/icon_disconnect.gif b/tools/h2/src/main/org/h2/server/web/res/icon_disconnect.gif deleted file mode 100755 index 2ece8d8..0000000 Binary files a/tools/h2/src/main/org/h2/server/web/res/icon_disconnect.gif and /dev/null differ diff --git a/tools/h2/src/main/org/h2/server/web/res/icon_help.gif b/tools/h2/src/main/org/h2/server/web/res/icon_help.gif deleted file mode 100755 index a5dfad0..0000000 Binary files a/tools/h2/src/main/org/h2/server/web/res/icon_help.gif and /dev/null differ diff --git a/tools/h2/src/main/org/h2/server/web/res/icon_history.gif b/tools/h2/src/main/org/h2/server/web/res/icon_history.gif deleted file mode 100755 index 745fdf2..0000000 Binary files a/tools/h2/src/main/org/h2/server/web/res/icon_history.gif and /dev/null differ diff --git a/tools/h2/src/main/org/h2/server/web/res/icon_line.gif b/tools/h2/src/main/org/h2/server/web/res/icon_line.gif deleted file mode 100755 index 98c2c38..0000000 Binary files a/tools/h2/src/main/org/h2/server/web/res/icon_line.gif and /dev/null differ diff --git a/tools/h2/src/main/org/h2/server/web/res/icon_refresh.gif b/tools/h2/src/main/org/h2/server/web/res/icon_refresh.gif deleted file mode 100755 index 2fdec08..0000000 Binary files a/tools/h2/src/main/org/h2/server/web/res/icon_refresh.gif and /dev/null differ diff --git a/tools/h2/src/main/org/h2/server/web/res/icon_rollback.gif b/tools/h2/src/main/org/h2/server/web/res/icon_rollback.gif deleted file mode 100755 index bcc2a4c..0000000 Binary files a/tools/h2/src/main/org/h2/server/web/res/icon_rollback.gif and /dev/null differ diff --git a/tools/h2/src/main/org/h2/server/web/res/icon_run.gif b/tools/h2/src/main/org/h2/server/web/res/icon_run.gif deleted file mode 100755 index 4c6a6bf..0000000 Binary files a/tools/h2/src/main/org/h2/server/web/res/icon_run.gif and /dev/null differ diff --git a/tools/h2/src/main/org/h2/server/web/res/icon_stop.gif b/tools/h2/src/main/org/h2/server/web/res/icon_stop.gif deleted file mode 100755 index ae44bf3..0000000 Binary files a/tools/h2/src/main/org/h2/server/web/res/icon_stop.gif and /dev/null differ diff --git a/tools/h2/src/main/org/h2/server/web/res/index.jsp b/tools/h2/src/main/org/h2/server/web/res/index.jsp deleted file mode 100755 index 6558e14..0000000 --- a/tools/h2/src/main/org/h2/server/web/res/index.jsp +++ /dev/null @@ -1,26 +0,0 @@ - - - - - ${text.a.title} - - - - - -

Welcome to H2

-

No Javascript

-If you are not automatically redirected to the login page, then -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. - - diff --git a/tools/h2/src/main/org/h2/server/web/res/login.jsp b/tools/h2/src/main/org/h2/server/web/res/login.jsp deleted file mode 100755 index bbbcd41..0000000 --- a/tools/h2/src/main/org/h2/server/web/res/login.jsp +++ /dev/null @@ -1,135 +0,0 @@ - - - - - ${text.login.title} - - - - -
-

-    ${text.login.goAdmin} - -    ${text.a.tools} -    ${text.a.help} -

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -

${error}

-
- \ No newline at end of file diff --git a/tools/h2/src/main/org/h2/server/web/res/notAllowed.jsp b/tools/h2/src/main/org/h2/server/web/res/notAllowed.jsp deleted file mode 100755 index 18de6d7..0000000 --- a/tools/h2/src/main/org/h2/server/web/res/notAllowed.jsp +++ /dev/null @@ -1,18 +0,0 @@ - - - - - ${text.a.title} - - -

${text.a.title}

-

- ${text.a.remoteConnectionsDisabled} -

- \ No newline at end of file diff --git a/tools/h2/src/main/org/h2/server/web/res/query.jsp b/tools/h2/src/main/org/h2/server/web/res/query.jsp deleted file mode 100755 index a9a9ec9..0000000 --- a/tools/h2/src/main/org/h2/server/web/res/query.jsp +++ /dev/null @@ -1,466 +0,0 @@ - - - - - - ${text.a.title} - - - - -
- - - ${text.toolbar.sqlStatement}: -
- -
- -
- - \ No newline at end of file diff --git a/tools/h2/src/main/org/h2/server/web/res/result.jsp b/tools/h2/src/main/org/h2/server/web/res/result.jsp deleted file mode 100755 index 97c9077..0000000 --- a/tools/h2/src/main/org/h2/server/web/res/result.jsp +++ /dev/null @@ -1,24 +0,0 @@ - - - - - - ${text.a.title} - - - - - -
-${result} -
- -
- - diff --git a/tools/h2/src/main/org/h2/server/web/res/sort_down.gif b/tools/h2/src/main/org/h2/server/web/res/sort_down.gif deleted file mode 100755 index 124c234..0000000 Binary files a/tools/h2/src/main/org/h2/server/web/res/sort_down.gif and /dev/null differ diff --git a/tools/h2/src/main/org/h2/server/web/res/sort_up.gif b/tools/h2/src/main/org/h2/server/web/res/sort_up.gif deleted file mode 100755 index e75c561..0000000 Binary files a/tools/h2/src/main/org/h2/server/web/res/sort_up.gif and /dev/null differ diff --git a/tools/h2/src/main/org/h2/server/web/res/stylesheet.css b/tools/h2/src/main/org/h2/server/web/res/stylesheet.css deleted file mode 100755 index 81ec34c..0000000 --- a/tools/h2/src/main/org/h2/server/web/res/stylesheet.css +++ /dev/null @@ -1,310 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ - -td, input, select, textarea, body, code, pre { - font: 9pt/130% Tahoma, Arial, Helvetica, sans-serif; -} - -h1, h2, h3, h4, h5 { - font: 9pt Tahoma, Arial, Helvetica, sans-serif; - font-weight: bold; -} - -a { - text-decoration: none; - color: #0000ff; -} - -a:hover { - text-decoration: underline; -} - -body { - margin: 4px; -} - -code { - background-color: #ece9d8; - padding: 0px 2px; -} - -h1 { - background-color: #0000bb; - padding: 2px 4px 2px 4px; - color: #fff; - font-size: 15pt; - line-height: normal; -} - -h2 { - font-size: 13pt; -} - -h3 { - font-size: 10pt; -} - -li { - margin-top: 6px; -} - -ol { - list-style-type: upper-roman; - list-style-position: outside; -} - -table { - background-color: #ffffff; - border-collapse: collapse; - border: 1px solid #aca899; -} - -td { - background-color: #ffffff; - font-size: 9pt; - padding: 2px; - text-align: left; - vertical-align:top; - border: 1px solid #aca899; -} - -textarea { - width: 100%; - overflow: auto; -} - -th { - font-size: 9pt; - font-weight: normal; - text-align: left; - background-color: #ece9d8; - padding: 2px; - border: 1px solid #aca899; -} - -ul { - list-style-type: disc; - list-style-position: outside; - padding-left: 20px; -} - -.result { - background-color: #f4f0e0; - margin: 10px; -} - -.toolbar { - background-color: #ece9d8; -} - -table.toolbar { - border-collapse: collapse; - border: 0px; - padding: 0px 0px; -} - -th.toolbar { - border: 0px; -} - -tr.toolbar { - border: 0px; -} - -td.toolbar { - vertical-align: middle; - border: 0px; - padding: 0px 0px; -} - -table.nav { - border: 0px; -} - -tr.nav { - border: 0px; -} - -td.nav { - border: 0px; -} - -table.login { - background-color: #ece9d8; - border:1px solid #aca899; -} - -tr.login { - border: 0px; -} - -th.login { - color: #ffffff; - font-size: 10pt; - text-align: left; - border: 0px; - background-color: #ece9d8; - padding: 5px 10px; - background-image: url(background.gif); -} - -td.login { - background-color: #ece9d8; - font-size: 9pt; - padding: 5px 10px; - text-align: left; - border: 0px; -} - -.iconLine { - border-width:0px; - border-style:solid; -} - -.icon { - border-top-color:#ece9d8; - border-left-color:#ece9d8; - border-right-color:#ece9d8; - border-bottom-color:#ece9d8; - border-width:1px; - border-style:solid; -} - -.icon_hover { - border-top-color:#ffffff; - border-left-color:#ffffff; - border-right-color:#aca899; - border-bottom-color:#aca899; - border-width:1px; - border-style:solid; -} - -table.empty { - background-color: #ffffff; - border: 0px; -} - -td.empty { - background-color: #ffffff; - border: 0px; - font-size: 9pt; - padding: 5px 10px; - text-align: left; -} - -.error { - color: #ff0000; -} - -p.error { - color: #ff0000; -} - -input.button { - padding: 1px; -} - -.tree { - border: 0px; - vertical-align: middle; - white-space: nowrap; -} - -.tree img { - height: 18px; - width: 18px; - border: 0px; - vertical-align: middle; -} - -.tree a { - border: 0px; - text-decoration: none; - vertical-align: middle; - white-space: nowrap; - color: #000000; -} - -.tree a:hover { - color: #345373; -} - -table.content { - width: 100%; - height: 100%; - border: 0px; -} - -tr.content { - border:0px; - border-left:1px solid #aca899; -} - -td.content { - border:0px; - border-left:1px solid #aca899; -} - -.contentDiv { - margin:10px; -} - -tr.contentResult { - border:0px; - border-top:1px solid #aca899; - border-left:1px solid #aca899; -} - -td.contentResult { - border:0px; - border-top:1px solid #aca899; - border-left:1px solid #aca899; -} - -table.autoComp { - background-color: #e0ecff; - border: 1px solid #7f9db9; - cursor: pointer; - position: absolute; - top: 1px; - left: 1px; - z-index:0; - padding: 0px; - margin: 0px; - border-spacing:2px; -} - -td.autoComp0 { - border-spacing: 0px; - padding: 1px 8px; - background-color: #cce0ff; - border: 0px; -} - -td.autoComp1 { - border-spacing: 0px; - padding: 1px 8px; - background-color: #e7f0ff; - border: 0px; -} - -td.autoComp2 { - border-spacing: 0px; - padding: 1px 8px; - background-color: #ffffff; - border: 0px; -} - -td.autoCompHide { - padding: 2px; - display: none; -} - -table.tool, table.tool tr, table.tool tr td { - padding: 0px; - border: 0px; -} diff --git a/tools/h2/src/main/org/h2/server/web/res/table.js b/tools/h2/src/main/org/h2/server/web/res/table.js deleted file mode 100755 index c3abfe4..0000000 --- a/tools/h2/src/main/org/h2/server/web/res/table.js +++ /dev/null @@ -1,197 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ - -addEvent(window, "load", initSort); - -function addEvent(elm, evType, fn, useCapture) { - // addEvent and removeEvent - // cross-browser event handling for IE5+, NS6 and Mozilla - // By Scott Andrew - if (elm.addEventListener){ - elm.addEventListener(evType, fn, useCapture); - return true; - } else if (elm.attachEvent){ - var r = elm.attachEvent("on"+evType, fn); - return r; - } else { - alert("Handler could not be added"); - } -} - -function initSort() { - if(document.getElementById('editing') != undefined) { - // don't allow sorting while editing - return; - } - var tables = document.getElementsByTagName("table"); - for (var i=0; i 0) { - var header = table.rows[0]; - for(var j=0;j  
'; - } - } - } -} - -function editRow(row, session, write, undo) { - var table = document.getElementById('editTable'); - var y = row < 0 ? table.rows.length - 1 : row; - var i; - for(i=1; i'; - var undo = ''+undo+''; - cell.innerHTML = edit + undo; - } else { - cell.innerHTML = ''; - } - } - var cells = table.rows[y].cells; - for(i=1; i'; - } -} - -function editCancel(row) { - var editing = document.getElementById('editing'); - editing.row.value = row; - editing.op.value='3'; - editing.submit(); -} - -function editOk(row) { - var editing = document.getElementById('editing'); - editing.row.value = row; - editing.op.value='1'; - editing.submit(); -} - -function editKeyDown(row, object, event) { - var key=event.keyCode? event.keyCode : event.charCode; - if(key == 46 && event.ctrlKey) { - // ctrl + delete - object.value = 'null'; - return false; - } else if(key == 13) { - editOk(row); - return false; - } else if(key == 27) { - editCancel(row); - return false; - } -} - -function getInnerText(el) { - if (typeof el == "string") return el; - if (typeof el == "undefined") { return el }; - if (el.innerText) { - // not needed but it is faster - return el.innerText; - } - var str = ""; - var cs = el.childNodes; - var l = cs.length; - for (var i = 0; i < l; i++) { - switch (cs[i].nodeType) { - case 1: //ELEMENT_NODE - str += getInnerText(cs[i]); - break; - case 3: //TEXT_NODE - str += cs[i].nodeValue; - break; - } - } - return str; -} - -function resortTable(link) { - // get the span - var span; - for (var ci=0;ci - - - - - ${text.a.title} - - - - - - - -
- -
- -

- ${error} -

- - - diff --git a/tools/h2/src/main/org/h2/server/web/res/tools.jsp b/tools/h2/src/main/org/h2/server/web/res/tools.jsp deleted file mode 100755 index fc9f9bb..0000000 --- a/tools/h2/src/main/org/h2/server/web/res/tools.jsp +++ /dev/null @@ -1,242 +0,0 @@ - - - - - ${text.a.tools} - - - - -
- -

${text.a.tools}

-

-${text.adminLogout} -

-
-

-${text.tools.backup}   -${text.tools.restore}   -${text.tools.recover}   -${text.tools.deleteDbFiles}   -${text.tools.changeFileEncryption} -

-${text.tools.script}   -${text.tools.runScript}   -${text.tools.convertTraceFile}   -${text.tools.createCluster} -

-
- - - - - - - - - - - - - - -
- - - diff --git a/tools/h2/src/main/org/h2/server/web/res/tree.js b/tools/h2/src/main/org/h2/server/web/res/tree.js deleted file mode 100755 index 5d73bbb..0000000 --- a/tools/h2/src/main/org/h2/server/web/res/tree.js +++ /dev/null @@ -1,125 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ - -var nodeList = new Array(); -var icons = new Array(); -var tables = new Array(); -var tablesByName = new Object(); - -function Table(name, columns, i) { - this.name = name; - this.columns = columns; - this.id = i; -} - -function addTable(name, columns, i) { - var t = new Table(name, columns, i); - tables[tables.length] = t; - tablesByName[name] = t; -} - -function ins(s, isTable) { - if(top.h2query) { - if(top.h2query.insertText) { - top.h2query.insertText(s, isTable); - } - } -} - -function refreshQueryTables() { - if(top.frames['h2query']) { - if(top.frames['h2query'].refreshTables) { - top.frames['h2query'].refreshTables(); - } - } -} - -function goToTable(s) { - var t = tablesByName[s]; - if(t) { - hitOpen(t.id); - return true; - } - return false; -} - -function loadIcons() { - icons[0] = new Image(); - icons[0].src = "tree_minus.gif"; - icons[1] = new Image(); - icons[1].src = "tree_plus.gif"; -} - -function Node(level, type, icon, text, link) { - this.level = level; - this.type = type; - this.icon = icon; - this.text = text; - this.link = link; -} - -function setNode(id, level, type, icon, text, link) { - nodeList[id] = new Node(level, type, icon, text, link); -} - -function writeDiv(i, level, dist) { - if(dist>0) { - document.write("
"); - } else { - while(dist++<0) { - document.write("
"); - } - } -} - -function writeTree() { - loadIcons(); - var last=nodeList[0]; - for (var i=0; i0) { - document.write(""); - } - if (node.type==1) { - if( i < nodeList.length-1 && nodeList[i+1].level > node.level) { - document.write(""); - } else { - document.write(""); - } - } - document.write(" "); - if(node.link==null) { - document.write(node.text); - } else { - document.write(""+node.text+""); - } - document.write("
"); - } - writeDiv(0, 0, -last.type); -} - -function hit(i) { - var theDiv = document.getElementById("div"+i); - var theJoin = document.getElementById("join"+i); - if (theDiv.style.display == 'none') { - theJoin.src = icons[0].src; - theDiv.style.display = ''; - } else { - theJoin.src = icons[1].src; - theDiv.style.display = 'none'; - } -} - -function hitOpen(i) { - var theDiv = document.getElementById("div"+i); - var theJoin = document.getElementById("join"+i); - theJoin.src = icons[0].src; - theDiv.style.display = ''; -} \ No newline at end of file diff --git a/tools/h2/src/main/org/h2/server/web/res/tree_column.gif b/tools/h2/src/main/org/h2/server/web/res/tree_column.gif deleted file mode 100755 index e6aeb35..0000000 Binary files a/tools/h2/src/main/org/h2/server/web/res/tree_column.gif and /dev/null differ diff --git a/tools/h2/src/main/org/h2/server/web/res/tree_database.gif b/tools/h2/src/main/org/h2/server/web/res/tree_database.gif deleted file mode 100755 index c0cb0da..0000000 Binary files a/tools/h2/src/main/org/h2/server/web/res/tree_database.gif and /dev/null differ diff --git a/tools/h2/src/main/org/h2/server/web/res/tree_empty.gif b/tools/h2/src/main/org/h2/server/web/res/tree_empty.gif deleted file mode 100755 index b5cf523..0000000 Binary files a/tools/h2/src/main/org/h2/server/web/res/tree_empty.gif and /dev/null differ diff --git a/tools/h2/src/main/org/h2/server/web/res/tree_folder.gif b/tools/h2/src/main/org/h2/server/web/res/tree_folder.gif deleted file mode 100755 index eb12976..0000000 Binary files a/tools/h2/src/main/org/h2/server/web/res/tree_folder.gif and /dev/null differ diff --git a/tools/h2/src/main/org/h2/server/web/res/tree_index.gif b/tools/h2/src/main/org/h2/server/web/res/tree_index.gif deleted file mode 100755 index a841511..0000000 Binary files a/tools/h2/src/main/org/h2/server/web/res/tree_index.gif and /dev/null differ diff --git a/tools/h2/src/main/org/h2/server/web/res/tree_index_az.gif b/tools/h2/src/main/org/h2/server/web/res/tree_index_az.gif deleted file mode 100755 index e956755..0000000 Binary files a/tools/h2/src/main/org/h2/server/web/res/tree_index_az.gif and /dev/null differ diff --git a/tools/h2/src/main/org/h2/server/web/res/tree_info.gif b/tools/h2/src/main/org/h2/server/web/res/tree_info.gif deleted file mode 100755 index a9a38f4..0000000 Binary files a/tools/h2/src/main/org/h2/server/web/res/tree_info.gif and /dev/null differ diff --git a/tools/h2/src/main/org/h2/server/web/res/tree_line.gif b/tools/h2/src/main/org/h2/server/web/res/tree_line.gif deleted file mode 100755 index 1a259ee..0000000 Binary files a/tools/h2/src/main/org/h2/server/web/res/tree_line.gif and /dev/null differ diff --git a/tools/h2/src/main/org/h2/server/web/res/tree_minus.gif b/tools/h2/src/main/org/h2/server/web/res/tree_minus.gif deleted file mode 100755 index 2592ac2..0000000 Binary files a/tools/h2/src/main/org/h2/server/web/res/tree_minus.gif and /dev/null differ diff --git a/tools/h2/src/main/org/h2/server/web/res/tree_page.gif b/tools/h2/src/main/org/h2/server/web/res/tree_page.gif deleted file mode 100755 index 42d7318..0000000 Binary files a/tools/h2/src/main/org/h2/server/web/res/tree_page.gif and /dev/null differ diff --git a/tools/h2/src/main/org/h2/server/web/res/tree_plus.gif b/tools/h2/src/main/org/h2/server/web/res/tree_plus.gif deleted file mode 100755 index f258ce2..0000000 Binary files a/tools/h2/src/main/org/h2/server/web/res/tree_plus.gif and /dev/null differ diff --git a/tools/h2/src/main/org/h2/server/web/res/tree_sequence.gif b/tools/h2/src/main/org/h2/server/web/res/tree_sequence.gif deleted file mode 100755 index 60820a9..0000000 Binary files a/tools/h2/src/main/org/h2/server/web/res/tree_sequence.gif and /dev/null differ diff --git a/tools/h2/src/main/org/h2/server/web/res/tree_sequences.gif b/tools/h2/src/main/org/h2/server/web/res/tree_sequences.gif deleted file mode 100755 index e72a596..0000000 Binary files a/tools/h2/src/main/org/h2/server/web/res/tree_sequences.gif and /dev/null differ diff --git a/tools/h2/src/main/org/h2/server/web/res/tree_table.gif b/tools/h2/src/main/org/h2/server/web/res/tree_table.gif deleted file mode 100755 index e64a80d..0000000 Binary files a/tools/h2/src/main/org/h2/server/web/res/tree_table.gif and /dev/null differ diff --git a/tools/h2/src/main/org/h2/server/web/res/tree_type.gif b/tools/h2/src/main/org/h2/server/web/res/tree_type.gif deleted file mode 100755 index 313fc00..0000000 Binary files a/tools/h2/src/main/org/h2/server/web/res/tree_type.gif and /dev/null differ diff --git a/tools/h2/src/main/org/h2/server/web/res/tree_types.gif b/tools/h2/src/main/org/h2/server/web/res/tree_types.gif deleted file mode 100755 index 8e55d90..0000000 Binary files a/tools/h2/src/main/org/h2/server/web/res/tree_types.gif and /dev/null differ diff --git a/tools/h2/src/main/org/h2/server/web/res/tree_user.gif b/tools/h2/src/main/org/h2/server/web/res/tree_user.gif deleted file mode 100755 index 72160a8..0000000 Binary files a/tools/h2/src/main/org/h2/server/web/res/tree_user.gif and /dev/null differ diff --git a/tools/h2/src/main/org/h2/server/web/res/tree_users.gif b/tools/h2/src/main/org/h2/server/web/res/tree_users.gif deleted file mode 100755 index 3c3d84f..0000000 Binary files a/tools/h2/src/main/org/h2/server/web/res/tree_users.gif and /dev/null differ diff --git a/tools/h2/src/main/org/h2/server/web/res/tree_view.gif b/tools/h2/src/main/org/h2/server/web/res/tree_view.gif deleted file mode 100755 index 0ef4493..0000000 Binary files a/tools/h2/src/main/org/h2/server/web/res/tree_view.gif and /dev/null differ diff --git a/tools/h2/src/main/org/h2/store/Data.java b/tools/h2/src/main/org/h2/store/Data.java deleted file mode 100755 index c90f074..0000000 --- a/tools/h2/src/main/org/h2/store/Data.java +++ /dev/null @@ -1,1135 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - * - * The variable size number format code is a port from SQLite, - * but stored in reverse order (least significant bits in the first byte). - */ -package org.h2.store; -import java.math.BigDecimal; -import java.math.BigInteger; -import java.sql.Date; -import java.sql.Time; -import java.sql.Timestamp; -import org.h2.constant.ErrorCode; -import org.h2.constant.SysProperties; -import org.h2.engine.Constants; -import org.h2.message.DbException; -import org.h2.util.DateTimeUtils; -import org.h2.util.MathUtils; -import org.h2.util.Utils; -import org.h2.value.Value; -import org.h2.value.ValueArray; -import org.h2.value.ValueBoolean; -import org.h2.value.ValueByte; -import org.h2.value.ValueBytes; -import org.h2.value.ValueDate; -import org.h2.value.ValueDecimal; -import org.h2.value.ValueDouble; -import org.h2.value.ValueFloat; -import org.h2.value.ValueInt; -import org.h2.value.ValueJavaObject; -import org.h2.value.ValueLob; -import org.h2.value.ValueLobDb; -import org.h2.value.ValueLong; -import org.h2.value.ValueNull; -import org.h2.value.ValueShort; -import org.h2.value.ValueString; -import org.h2.value.ValueStringFixed; -import org.h2.value.ValueStringIgnoreCase; -import org.h2.value.ValueTime; -import org.h2.value.ValueTimestamp; -import org.h2.value.ValueUuid; - -/** - * This class represents a byte buffer that contains persistent data of a page. - */ -public class Data { - - /** - * The length of an integer value. - */ - public static final int LENGTH_INT = 4; - - private static final boolean TEST = false; - private static final int TEST_OFFSET = 0; - - /** - * The length of a long value. - */ - private static final int LENGTH_LONG = 8; - - private static final int INT_0_15 = 32; - private static final int LONG_0_7 = 48; - private static final int DECIMAL_0_1 = 56; - private static final int DECIMAL_SMALL_0 = 58; - private static final int DECIMAL_SMALL = 59; - private static final int DOUBLE_0_1 = 60; - private static final int FLOAT_0_1 = 62; - private static final int BOOLEAN_FALSE = 64; - private static final int BOOLEAN_TRUE = 65; - private static final int INT_NEG = 66; - private static final int LONG_NEG = 67; - private static final int STRING_0_31 = 68; - private static final int BYTES_0_31 = 100; - - private static final long MILLIS_PER_MINUTE = 1000 * 60; - - /** - * The data itself. - */ - protected byte[] data; - - /** - * The current write or read position. - */ - private int pos; - - /** - * The data handler responsible for lob objects. - */ - private final DataHandler handler; - - protected Data(DataHandler handler, byte[] data) { - this.handler = handler; - this.data = data; - } - - /** - * Update an integer at the given position. - * The current position is not change. - * - * @param pos the position - * @param x the value - */ - public void setInt(int pos, int x) { - byte[] buff = data; - buff[pos] = (byte) (x >> 24); - buff[pos + 1] = (byte) (x >> 16); - buff[pos + 2] = (byte) (x >> 8); - buff[pos + 3] = (byte) x; - } - - /** - * Write an integer at the current position. - * The current position is incremented. - * - * @param x the value - */ - public void writeInt(int x) { - byte[] buff = data; - buff[pos] = (byte) (x >> 24); - buff[pos + 1] = (byte) (x >> 16); - buff[pos + 2] = (byte) (x >> 8); - buff[pos + 3] = (byte) x; - pos += 4; - } - - /** - * Read an integer at the current position. - * The current position is incremented. - * - * @return the value - */ - public int readInt() { - byte[] buff = data; - int x = (buff[pos] << 24) + ((buff[pos+1] & 0xff) << 16) + ((buff[pos+2] & 0xff) << 8) + (buff[pos+3] & 0xff); - pos += 4; - return x; - } - - /** - * Get the length of a String. This includes the bytes required to encode - * the length. - * - * @param s the string - * @return the number of bytes required - */ - public static int getStringLen(String s) { - int len = s.length(); - return getStringWithoutLengthLen(s, len) + getVarIntLen(len); - } - - /** - * Calculate the length of String, excluding the bytes required to encode - * the length. - *

- * For performance reasons the internal representation of a String is - * similar to UTF-8, but not exactly UTF-8. - * - * @param s the string - * @param len the length of the string - * @return the number of bytes required - */ - public static int getStringWithoutLengthLen(String s, int len) { - int plus = 0; - for (int i = 0; i < len; i++) { - char c = s.charAt(i); - if (c >= 0x800) { - plus += 2; - } else if (c >= 0x80) { - plus++; - } - } - return len + plus; - } - - /** - * Read a String value. - * The current position is incremented. - * - * @return the value - */ - public String readString() { - int len = readVarInt(); - return readString(len); - } - - /** - * Read a String from the byte array. - *

- * For performance reasons the internal representation of a String is - * similar to UTF-8, but not exactly UTF-8. - * - * @param len - * @return the String - */ - private String readString(int len) { - byte[] buff = data; - int p = pos; - char[] chars = new char[len]; - for (int i = 0; i < len; i++) { - int x = buff[p++] & 0xff; - if (x < 0x80) { - chars[i] = (char) x; - } else if (x >= 0xe0) { - chars[i] = (char) (((x & 0xf) << 12) + ((buff[p++] & 0x3f) << 6) + (buff[p++] & 0x3f)); - } else { - chars[i] = (char) (((x & 0x1f) << 6) + (buff[p++] & 0x3f)); - } - } - pos = p; - return new String(chars); - } - - /** - * Write a String. - * The current position is incremented. - * - * @param s the value - */ - public void writeString(String s) { - int len = s.length(); - writeVarInt(len); - writeStringWithoutLength(s, len); - } - - /** - * Write a String. - *

- * For performance reasons the internal representation of a String is - * similar to UTF-8, but not exactly UTF-8. - * - * @param s the string - * @param len the number of characters to write - */ - private void writeStringWithoutLength(String s, int len) { - int p = pos; - byte[] buff = data; - for (int i = 0; i < len; i++) { - int c = s.charAt(i); - if (c < 0x80) { - buff[p++] = (byte) c; - } else if (c >= 0x800) { - buff[p++] = (byte) (0xe0 | (c >> 12)); - buff[p++] = (byte) (((c >> 6) & 0x3f)); - buff[p++] = (byte) (c & 0x3f); - } else { - buff[p++] = (byte) (0xc0 | (c >> 6)); - buff[p++] = (byte) (c & 0x3f); - } - } - pos = p; - } - - /** - * Increase the size to the given length. - * The current position is set to the given value. - * - * @param len the new length - */ - public void fill(int len) { - pos = len; - if (data.length < len) { - checkCapacity(len - data.length); - } - } - - /** - * Create a new buffer for the given handler. The - * handler will decide what type of buffer is created. - * - * @param handler the data handler - * @param capacity the initial capacity of the buffer - * @return the buffer - */ - public static Data create(DataHandler handler, int capacity) { - return new Data(handler, new byte[capacity]); - } - - /** - * Create a new buffer using the given data for the given handler. The - * handler will decide what type of buffer is created. - * - * @param handler the data handler - * @param buff the data - * @return the buffer - */ - public static Data create(DataHandler handler, byte[] buff) { - return new Data(handler, buff); - } - - /** - * Get the current write position of this buffer, which is the current - * length. - * - * @return the length - */ - public int length() { - return pos; - } - - /** - * Get the byte array used for this page. - * - * @return the byte array - */ - public byte[] getBytes() { - return data; - } - - /** - * Set the position to 0. - */ - public void reset() { - pos = 0; - } - - /** - * Append a number of bytes to this buffer. - * - * @param buff the data - * @param off the offset in the data - * @param len the length in bytes - */ - public void write(byte[] buff, int off, int len) { - System.arraycopy(buff, off, data, pos, len); - pos += len; - } - - /** - * Append a number of bytes to this buffer. - * - * @param buff the data - */ - public void write(byte[] buff) { - write(buff, 0, buff.length); - } - - /** - * Copy a number of bytes to the given buffer from the current position. The - * current position is incremented accordingly. - * - * @param buff the output buffer - * @param off the offset in the output buffer - * @param len the number of bytes to copy - */ - public void read(byte[] buff, int off, int len) { - System.arraycopy(data, pos, buff, off, len); - pos += len; - } - - /** - * Copy a number of bytes to the given buffer from the current position. The - * current position is incremented accordingly. - * - * @param buff the output buffer - */ - public void read(byte[] buff) { - read(buff, 0, buff.length); - } - - /** - * Append one single byte. - * - * @param x the value - */ - public void writeByte(byte x) { - data[pos++] = x; - } - - /** - * Read one single byte. - * - * @return the value - */ - public byte readByte() { - return data[pos++]; - } - - /** - * Read a long value. This method reads two int values and combines them. - * - * @return the long value - */ - public long readLong() { - return ((long) (readInt()) << 32) + (readInt() & 0xffffffffL); - } - - /** - * Append a long value. This method writes two int values. - * - * @param x the value - */ - public void writeLong(long x) { - writeInt((int) (x >>> 32)); - writeInt((int) x); - } - - /** - * Append a value. - * - * @param v the value - */ - public void writeValue(Value v) { - int start = pos; - if (TEST) { - pos += TEST_OFFSET; - } - if (v == ValueNull.INSTANCE) { - data[pos++] = 0; - return; - } - int type = v.getType(); - switch (type) { - case Value.BOOLEAN: - writeByte((byte) (v.getBoolean().booleanValue() ? BOOLEAN_TRUE : BOOLEAN_FALSE)); - break; - case Value.BYTE: - writeByte((byte) type); - writeByte(v.getByte()); - break; - case Value.SHORT: - writeByte((byte) type); - writeShortInt(v.getShort()); - break; - case Value.INT: { - int x = v.getInt(); - if (x < 0) { - writeByte((byte) INT_NEG); - writeVarInt(-x); - } else if (x < 16) { - writeByte((byte) (INT_0_15 + x)); - } else { - writeByte((byte) type); - writeVarInt(x); - } - break; - } - case Value.LONG: { - long x = v.getLong(); - if (x < 0) { - writeByte((byte) LONG_NEG); - writeVarLong(-x); - } else if (x < 8) { - writeByte((byte) (LONG_0_7 + x)); - } else { - writeByte((byte) type); - writeVarLong(x); - } - break; - } - case Value.DECIMAL: { - BigDecimal x = v.getBigDecimal(); - if (BigDecimal.ZERO.equals(x)) { - writeByte((byte) DECIMAL_0_1); - } else if (BigDecimal.ONE.equals(x)) { - writeByte((byte) (DECIMAL_0_1 + 1)); - } else { - int scale = x.scale(); - BigInteger b = x.unscaledValue(); - int bits = b.bitLength(); - if (bits <= 63) { - if (scale == 0) { - writeByte((byte) DECIMAL_SMALL_0); - writeVarLong(b.longValue()); - } else { - writeByte((byte) DECIMAL_SMALL); - writeVarInt(scale); - writeVarLong(b.longValue()); - } - } else { - writeByte((byte) type); - writeVarInt(scale); - byte[] bytes = b.toByteArray(); - writeVarInt(bytes.length); - write(bytes, 0, bytes.length); - } - } - break; - } - case Value.TIME: - writeByte((byte) type); - writeVarLong(DateTimeUtils.getTimeLocal(v.getTimeNoCopy())); - break; - case Value.DATE: { - writeByte((byte) type); - long x = DateTimeUtils.getTimeLocal(v.getDateNoCopy()); - writeVarLong(x / MILLIS_PER_MINUTE); - break; - } - case Value.TIMESTAMP: { - writeByte((byte) type); - Timestamp ts = v.getTimestampNoCopy(); - writeVarLong(DateTimeUtils.getTimeLocal(ts)); - writeVarInt(ts.getNanos()); - break; - } - case Value.JAVA_OBJECT: { - writeByte((byte) type); - byte[] b = v.getBytesNoCopy(); - writeVarInt(b.length); - write(b, 0, b.length); - break; - } - case Value.BYTES: { - byte[] b = v.getBytesNoCopy(); - int len = b.length; - if (len < 32) { - writeByte((byte) (BYTES_0_31 + len)); - write(b, 0, b.length); - } else { - writeByte((byte) type); - writeVarInt(b.length); - write(b, 0, b.length); - } - break; - } - case Value.UUID: { - writeByte((byte) type); - ValueUuid uuid = (ValueUuid) v; - writeLong(uuid.getHigh()); - writeLong(uuid.getLow()); - break; - } - case Value.STRING: { - String s = v.getString(); - int len = s.length(); - if (len < 32) { - writeByte((byte) (STRING_0_31 + len)); - writeStringWithoutLength(s, len); - } else { - writeByte((byte) type); - writeString(s); - } - break; - } - case Value.STRING_IGNORECASE: - case Value.STRING_FIXED: - writeByte((byte) type); - writeString(v.getString()); - break; - case Value.DOUBLE: { - double x = v.getDouble(); - if (x == 0.0 || x == 1.0) { - writeByte((byte) (DOUBLE_0_1 + x)); - } else { - writeByte((byte) type); - writeVarLong(MathUtils.reverseLong(Double.doubleToLongBits(x))); - } - break; - } - case Value.FLOAT: { - float x = v.getFloat(); - if (x == 0.0f || x == 1.0f) { - writeByte((byte) (FLOAT_0_1 + x)); - } else { - writeByte((byte) type); - writeVarInt(MathUtils.reverseInt(Float.floatToIntBits(v.getFloat()))); - } - break; - } - case Value.BLOB: - case Value.CLOB: { - writeByte((byte) type); - if (v instanceof ValueLob) { - ValueLob lob = (ValueLob) v; - lob.convertToFileIfRequired(handler); - byte[] small = lob.getSmall(); - if (small == null) { - int t = -1; - if (!lob.isLinked()) { - t = -2; - } - writeVarInt(t); - writeVarInt(lob.getTableId()); - writeVarInt(lob.getObjectId()); - writeVarLong(lob.getPrecision()); - writeByte((byte) (lob.useCompression() ? 1 : 0)); - if (t == -2) { - writeString(lob.getFileName()); - } - } else { - writeVarInt(small.length); - write(small, 0, small.length); - } - } else { - ValueLobDb lob = (ValueLobDb) v; - byte[] small = lob.getSmall(); - if (small == null) { - writeVarInt(-3); - writeVarInt(lob.getTableId()); - writeVarLong(lob.getLobId()); - writeVarLong(lob.getPrecision()); - } else { - writeVarInt(small.length); - write(small, 0, small.length); - } - } - break; - } - case Value.ARRAY: { - writeByte((byte) type); - Value[] list = ((ValueArray) v).getList(); - writeVarInt(list.length); - for (Value x : list) { - writeValue(x); - } - break; - } - default: - DbException.throwInternalError("type=" + v.getType()); - } - if (SysProperties.CHECK2) { - if (pos - start != getValueLen(v, handler)) { - throw DbException - .throwInternalError("value size error: got " + (pos - start) + " expected " + getValueLen(v, handler)); - } - } - } - - /** - * Read a value. - * - * @return the value - */ - public Value readValue() { - if (TEST) { - pos += TEST_OFFSET; - } - int type = data[pos++] & 255; - switch (type) { - case Value.NULL: - return ValueNull.INSTANCE; - case BOOLEAN_TRUE: - return ValueBoolean.get(true); - case BOOLEAN_FALSE: - return ValueBoolean.get(false); - case INT_NEG: - return ValueInt.get(-readVarInt()); - case Value.INT: - return ValueInt.get(readVarInt()); - case LONG_NEG: - return ValueLong.get(-readVarLong()); - case Value.LONG: - return ValueLong.get(readVarLong()); - case Value.BYTE: - return ValueByte.get(readByte()); - case Value.SHORT: - return ValueShort.get(readShortInt()); - case DECIMAL_0_1: - return (ValueDecimal) ValueDecimal.ZERO; - case DECIMAL_0_1 + 1: - return (ValueDecimal) ValueDecimal.ONE; - case DECIMAL_SMALL_0: - return ValueDecimal.get(BigDecimal.valueOf(readVarLong())); - case DECIMAL_SMALL: { - int scale = readVarInt(); - return ValueDecimal.get(BigDecimal.valueOf(readVarLong(), scale)); - } - case Value.DECIMAL: { - int scale = readVarInt(); - int len = readVarInt(); - byte[] buff = Utils.newBytes(len); - read(buff, 0, len); - BigInteger b = new BigInteger(buff); - return ValueDecimal.get(new BigDecimal(b, scale)); - } - case Value.DATE: { - long x = readVarLong() * MILLIS_PER_MINUTE; - return ValueDate.getNoCopy(new Date(DateTimeUtils.getTimeGMT(x))); - } - case Value.TIME: - // need to normalize the year, month and day - return ValueTime.get(new Time(DateTimeUtils.getTimeGMT(readVarLong()))); - case Value.TIMESTAMP: { - Timestamp ts = new Timestamp(DateTimeUtils.getTimeGMT(readVarLong())); - ts.setNanos(readVarInt()); - return ValueTimestamp.getNoCopy(ts); - } - case Value.BYTES: { - int len = readVarInt(); - byte[] b = Utils.newBytes(len); - read(b, 0, len); - return ValueBytes.getNoCopy(b); - } - case Value.JAVA_OBJECT: { - int len = readVarInt(); - byte[] b = Utils.newBytes(len); - read(b, 0, len); - return ValueJavaObject.getNoCopy(b); - } - case Value.UUID: - return ValueUuid.get(readLong(), readLong()); - case Value.STRING: - return ValueString.get(readString()); - case Value.STRING_IGNORECASE: - return ValueStringIgnoreCase.get(readString()); - case Value.STRING_FIXED: - return ValueStringFixed.get(readString()); - case FLOAT_0_1: - return ValueFloat.get(0); - case FLOAT_0_1 + 1: - return ValueFloat.get(1); - case DOUBLE_0_1: - return ValueDouble.get(0); - case DOUBLE_0_1 + 1: - return ValueDouble.get(1); - case Value.DOUBLE: - return ValueDouble.get(Double.longBitsToDouble(MathUtils.reverseLong(readVarLong()))); - case Value.FLOAT: - return ValueFloat.get(Float.intBitsToFloat(MathUtils.reverseInt(readVarInt()))); - case Value.BLOB: - case Value.CLOB: { - int smallLen = readVarInt(); - if (smallLen >= 0) { - byte[] small = Utils.newBytes(smallLen); - read(small, 0, smallLen); - return LobStorage.createSmallLob(type, small); - } else if (smallLen == -3) { - int tableId = readVarInt(); - long lobId = readVarLong(); - long precision = readVarLong(); - LobStorage lobStorage = handler.getLobStorage(); - ValueLobDb lob = ValueLobDb.create(type, lobStorage, null, tableId, lobId, precision); - return lob; - } else { - int tableId = readVarInt(); - int objectId = readVarInt(); - long precision = 0; - boolean compression = false; - // -1: regular - // -2: regular, but not linked (in this case: including file name) - if (smallLen == -1 || smallLen == -2) { - precision = readVarLong(); - compression = readByte() == 1; - } - ValueLob lob = ValueLob.open(type, handler, tableId, objectId, precision, compression); - if (smallLen == -2) { - lob.setFileName(readString(), false); - } - return lob; - } - } - case Value.ARRAY: { - int len = readVarInt(); - Value[] list = new Value[len]; - for (int i = 0; i < len; i++) { - list[i] = readValue(); - } - return ValueArray.get(list); - } - default: - if (type >= INT_0_15 && type < INT_0_15 + 16) { - return ValueInt.get(type - INT_0_15); - } else if (type >= LONG_0_7 && type < LONG_0_7 + 8) { - return ValueLong.get(type - LONG_0_7); - } else if (type >= BYTES_0_31 && type < BYTES_0_31 + 32) { - int len = type - BYTES_0_31; - byte[] b = Utils.newBytes(len); - read(b, 0, len); - return ValueBytes.getNoCopy(b); - } else if (type >= STRING_0_31 && type < STRING_0_31 + 32) { - return ValueString.get(readString(type - STRING_0_31)); - } - throw DbException.get(ErrorCode.FILE_CORRUPTED_1, "type: " + type); - } - } - - /** - * Calculate the number of bytes required to encode the given value. - * - * @param v the value - * @return the number of bytes required to store this value - */ - public int getValueLen(Value v) { - return getValueLen(v, handler); - } - - /** - * Calculate the number of bytes required to encode the given value. - * - * @param v the value - * @param handler the data handler for lobs - * @return the number of bytes required to store this value - */ - public static int getValueLen(Value v, DataHandler handler) { - return getValueLen2(v, handler) + TEST_OFFSET; - } - - private static int getValueLen2(Value v, DataHandler handler) { - if (v == ValueNull.INSTANCE) { - return 1; - } - switch (v.getType()) { - case Value.BOOLEAN: - return 1; - case Value.BYTE: - return 2; - case Value.SHORT: - return 3; - case Value.INT: { - int x = v.getInt(); - if (x < 0) { - return 1 + getVarIntLen(-x); - } else if (x < 16) { - return 1; - } else { - return 1 + getVarIntLen(x); - } - } - case Value.LONG: { - long x = v.getLong(); - if (x < 0) { - return 1 + getVarLongLen(-x); - } else if (x < 8) { - return 1; - } else { - return 1 + getVarLongLen(x); - } - } - case Value.DOUBLE: { - double x = v.getDouble(); - if (x == 0.0 || x == 1.0) { - return 1; - } - return 1 + getVarLongLen(MathUtils.reverseLong(Double.doubleToLongBits(x))); - } - case Value.FLOAT: { - float x = v.getFloat(); - if (x == 0.0f || x == 1.0f) { - return 1; - } - return 1 + getVarIntLen(MathUtils.reverseInt(Float.floatToIntBits(v.getFloat()))); - } - case Value.STRING: { - String s = v.getString(); - int len = s.length(); - if (len < 32) { - return 1 + getStringWithoutLengthLen(s, len); - } - return 1 + getStringLen(s); - } - case Value.STRING_IGNORECASE: - case Value.STRING_FIXED: - return 1 + getStringLen(v.getString()); - case Value.DECIMAL: { - BigDecimal x = v.getBigDecimal(); - if (BigDecimal.ZERO.equals(x)) { - return 1; - } else if (BigDecimal.ONE.equals(x)) { - return 1; - } - int scale = x.scale(); - BigInteger b = x.unscaledValue(); - int bits = b.bitLength(); - if (bits <= 63) { - if (scale == 0) { - return 1 + getVarLongLen(b.longValue()); - } - return 1 + getVarIntLen(scale) + getVarLongLen(b.longValue()); - } - byte[] bytes = b.toByteArray(); - return 1 + getVarIntLen(scale) + getVarIntLen(bytes.length) + bytes.length; - } - case Value.TIME: - return 1 + getVarLongLen(DateTimeUtils.getTimeLocal(v.getTimeNoCopy())); - case Value.DATE: { - long x = DateTimeUtils.getTimeLocal(v.getDateNoCopy()); - return 1 + getVarLongLen(x / MILLIS_PER_MINUTE); - } - case Value.TIMESTAMP: { - Timestamp ts = v.getTimestampNoCopy(); - return 1 + getVarLongLen(DateTimeUtils.getTimeLocal(ts)) + getVarIntLen(ts.getNanos()); - } - case Value.JAVA_OBJECT: { - byte[] b = v.getBytesNoCopy(); - return 1 + getVarIntLen(b.length) + b.length; - } - case Value.BYTES: { - byte[] b = v.getBytesNoCopy(); - int len = b.length; - if (len < 32) { - return 1 + b.length; - } - return 1 + getVarIntLen(b.length) + b.length; - } - case Value.UUID: - return 1 + LENGTH_LONG + LENGTH_LONG; - case Value.BLOB: - case Value.CLOB: { - int len = 1; - if (v instanceof ValueLob) { - ValueLob lob = (ValueLob) v; - lob.convertToFileIfRequired(handler); - byte[] small = lob.getSmall(); - if (small == null) { - int t = -1; - if (!lob.isLinked()) { - t = -2; - } - len += getVarIntLen(t); - len += getVarIntLen(lob.getTableId()); - len += getVarIntLen(lob.getObjectId()); - len += getVarLongLen(lob.getPrecision()); - len += 1; - if (t == -2) { - len += getStringLen(lob.getFileName()); - } - } else { - len += getVarIntLen(small.length); - len += small.length; - } - } else { - ValueLobDb lob = (ValueLobDb) v; - byte[] small = lob.getSmall(); - if (small == null) { - len += getVarIntLen(-3); - len += getVarIntLen(lob.getTableId()); - len += getVarLongLen(lob.getLobId()); - len += getVarLongLen(lob.getPrecision()); - } else { - len += getVarIntLen(small.length); - len += small.length; - } - } - return len; - } - case Value.ARRAY: { - Value[] list = ((ValueArray) v).getList(); - int len = 1 + getVarIntLen(list.length); - for (Value x : list) { - len += getValueLen(x, handler); - } - return len; - } - default: - throw DbException.throwInternalError("type=" + v.getType()); - } - } - - /** - * Set the current read / write position. - * - * @param pos the new position - */ - public void setPos(int pos) { - this.pos = pos; - } - - /** - * Write a short integer at the current position. - * The current position is incremented. - * - * @param x the value - */ - public void writeShortInt(int x) { - byte[] buff = data; - buff[pos++] = (byte) (x >> 8); - buff[pos++] = (byte) x; - } - - /** - * Read an short integer at the current position. - * The current position is incremented. - * - * @return the value - */ - public short readShortInt() { - byte[] buff = data; - return (short) (((buff[pos++] & 0xff) << 8) + (buff[pos++] & 0xff)); - } - - /** - * Shrink the array to this size. - * - * @param size the new size - */ - public void truncate(int size) { - if (pos > size) { - byte[] buff = new byte[size]; - System.arraycopy(data, 0, buff, 0, size); - this.pos = size; - data = buff; - } - } - - /** - * The number of bytes required for a variable size int. - * - * @param x the value - * @return the len - */ - public static int getVarIntLen(int x) { - if ((x & (-1 << 7)) == 0) { - return 1; - } else if ((x & (-1 << 14)) == 0) { - return 2; - } else if ((x & (-1 << 21)) == 0) { - return 3; - } else if ((x & (-1 << 28)) == 0) { - return 4; - } - return 5; - } - - /** - * Write a variable size int. - * - * @param x the value - */ - public void writeVarInt(int x) { - while ((x & ~0x7f) != 0) { - data[pos++] = (byte) (0x80 | (x & 0x7f)); - x >>>= 7; - } - data[pos++] = (byte) x; - } - - /** - * Read a variable size int. - * - * @return the value - */ - public int readVarInt() { - int b = data[pos]; - if (b >= 0) { - pos++; - return b; - } - int x = b & 0x7f; - b = data[pos + 1]; - if (b >= 0) { - pos += 2; - return x | (b << 7); - } - x |= (b & 0x7f) << 7; - b = data[pos + 2]; - if (b >= 0) { - pos += 3; - return x | (b << 14); - } - x |= (b & 0x7f) << 14; - b = data[pos + 3]; - if (b >= 0) { - pos += 4; - return x | b << 21; - } - x |= ((b & 0x7f) << 21) | (data[pos + 4] << 28); - pos += 5; - return x; - } - - /** - * The number of bytes required for a variable size long. - * - * @param x the value - * @return the len - */ - public static int getVarLongLen(long x) { - int i = 1; - while (true) { - x >>>= 7; - if (x == 0) { - return i; - } - i++; - } - } - - /** - * Write a variable size long. - * - * @param x the value - */ - public void writeVarLong(long x) { - while ((x & ~0x7f) != 0) { - data[pos++] = (byte) ((x & 0x7f) | 0x80); - x >>>= 7; - } - data[pos++] = (byte) x; - } - - /** - * Read a variable size long. - * - * @return the value - */ - public long readVarLong() { - long x = data[pos++]; - if (x >= 0) { - return x; - } - x &= 0x7f; - for (int s = 7;; s += 7) { - long b = data[pos++]; - x |= (b & 0x7f) << s; - if (b >= 0) { - return x; - } - } - } - - /** - * Check if there is still enough capacity in the buffer. - * This method extends the buffer if required. - * - * @param plus the number of additional bytes required - */ - public void checkCapacity(int plus) { - if (pos + plus >= data.length) { - // a separate method to simplify inlining - expand(plus); - } - } - - private void expand(int plus) { - byte[] d = Utils.newBytes((data.length + plus) * 2); - // must copy everything, because pos could be 0 and data may be - // still required - System.arraycopy(data, 0, d, 0, data.length); - data = d; - } - - /** - * Fill up the buffer with empty space and an (initially empty) checksum - * until the size is a multiple of Constants.FILE_BLOCK_SIZE. - */ - public void fillAligned() { - // 0..6 > 8, 7..14 > 16, 15..22 > 24, ... - fill(MathUtils.roundUpInt(pos + 2, Constants.FILE_BLOCK_SIZE)); - } - -} diff --git a/tools/h2/src/main/org/h2/store/DataHandler.java b/tools/h2/src/main/org/h2/store/DataHandler.java deleted file mode 100755 index 1b2915d..0000000 --- a/tools/h2/src/main/org/h2/store/DataHandler.java +++ /dev/null @@ -1,109 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.store; - -import java.sql.Connection; -import org.h2.util.SmallLRUCache; -import org.h2.util.TempFileDeleter; - -/** - * A data handler contains a number of callback methods. - * The most important implementing class is a database. - */ -public interface DataHandler { - - /** - * Get the database path. - * - * @return the database path - */ - String getDatabasePath(); - - /** - * Open a file at the given location. - * - * @param name the file name - * @param mode the mode - * @param mustExist whether the file must already exist - * @return the file - */ - FileStore openFile(String name, String mode, boolean mustExist); - - /** - * Check if the simulated power failure occurred. - * This call will decrement the countdown. - * - * @throws SQLException if the simulated power failure occurred - */ - void checkPowerOff(); - - /** - * Check if writing is allowed. - * - * @throws SQLException if it is not allowed - */ - void checkWritingAllowed(); - - /** - * Free up disk space if possible. - * This method is called if more space is needed. - * - * @throws SQLException if no more space could be freed - */ - void freeUpDiskSpace(); - - /** - * Get the maximum length of a in-place large object - * - * @return the maximum size - */ - int getMaxLengthInplaceLob(); - - /** - * Get the compression algorithm used for large objects. - * - * @param type the data type (CLOB or BLOB) - * @return the compression algorithm, or null - */ - String getLobCompressionAlgorithm(int type); - - /** - * Get the temp file deleter mechanism. - * - * @return the temp file deleter - */ - TempFileDeleter getTempFileDeleter(); - - /** - * Get the synchronization object for lob operations. - * - * @return the synchronization object - */ - Object getLobSyncObject(); - - /** - * Get the lob file list cache if it is used. - * - * @return the cache or null - */ - SmallLRUCache getLobFileListCache(); - - /** - * Get the lob storage mechanism to use. - * - * @return the lob storage mechanism - */ - LobStorage getLobStorage(); - - /** - * Get a database connection to be used for LOB access. - * - * @return the connection or null - */ - Connection getLobConnection(); - -} diff --git a/tools/h2/src/main/org/h2/store/DataReader.java b/tools/h2/src/main/org/h2/store/DataReader.java deleted file mode 100755 index 47e1b0f..0000000 --- a/tools/h2/src/main/org/h2/store/DataReader.java +++ /dev/null @@ -1,151 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.store; - -import java.io.EOFException; -import java.io.IOException; -import java.io.InputStream; -import org.h2.util.IOUtils; - -/** - * This class is backed by an input stream and supports reading values and - * variable size data. - */ -public class DataReader { - - private static final EOFException EOF = new EOFException(); - private InputStream in; - - /** - * Create a new data reader. - * - * @param in the input stream - */ - public DataReader(InputStream in) { - this.in = in; - } - - /** - * Read a byte. - * - * @return the byte - */ - public byte read() throws IOException { - int x = in.read(); - if (x < 0) { - throw EOF; - } - return (byte) x; - } - - /** - * Read a variable size integer. - * - * @return the value - */ - public int readVarInt() throws IOException { - int b = read(); - if (b >= 0) { - return b; - } - int x = b & 0x7f; - b = read(); - if (b >= 0) { - return x | (b << 7); - } - x |= (b & 0x7f) << 7; - b = read(); - if (b >= 0) { - return x | (b << 14); - } - x |= (b & 0x7f) << 14; - b = read(); - if (b >= 0) { - return x | b << 21; - } - return x | ((b & 0x7f) << 21) | (read() << 28); - } - - /** - * Read a variable size long. - * - * @return the value - */ - public long readVarLong() throws IOException { - long x = read(); - if (x >= 0) { - return x; - } - x &= 0x7f; - for (int s = 7;; s += 7) { - long b = read(); - x |= (b & 0x7f) << s; - if (b >= 0) { - return x; - } - } - } - - /** - * Read an integer. - * - * @return the value - */ - // public int readInt() throws IOException { - // return (read() << 24) + ((read() & 0xff) << 16) + - // ((read() & 0xff) << 8) + (read() & 0xff); - //} - - /** - * Read a long. - * - * @return the value - */ - // public long readLong() throws IOException { - // return ((long) (readInt()) << 32) + (readInt() & 0xffffffffL); - // } - - /** - * Read a number of bytes. - * - * @param buff the target buffer - * @param offset the offset within the target buffer - * @param len the number of bytes to read - */ - public void readFully(byte[] buff, int offset, int len) throws IOException { - int got = IOUtils.readFully(in, buff, offset, len); - if (got < len) { - throw EOF; - } - } - - /** - * Read a string from the stream. - * - * @return the string - */ - public String readString() throws IOException { - int len = readVarInt(); - return readString(len); - } - - private String readString(int len) throws IOException { - char[] chars = new char[len]; - for (int i = 0; i < len; i++) { - int x = read() & 0xff; - if (x < 0x80) { - chars[i] = (char) x; - } else if (x >= 0xe0) { - chars[i] = (char) (((x & 0xf) << 12) + ((read() & 0x3f) << 6) + (read() & 0x3f)); - } else { - chars[i] = (char) (((x & 0x1f) << 6) + (read() & 0x3f)); - } - } - return new String(chars); - } - -} diff --git a/tools/h2/src/main/org/h2/store/FileLister.java b/tools/h2/src/main/org/h2/store/FileLister.java deleted file mode 100755 index 9b4c0d4..0000000 --- a/tools/h2/src/main/org/h2/store/FileLister.java +++ /dev/null @@ -1,113 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.store; - -import java.sql.SQLException; -import java.util.ArrayList; -import org.h2.constant.ErrorCode; -import org.h2.engine.Constants; -import org.h2.message.DbException; -import org.h2.message.TraceSystem; -import org.h2.util.IOUtils; -import org.h2.util.New; - -/** - * Utility class to list the files of a database. - */ -public class FileLister { - - private FileLister() { - // utility class - } - - /** - * Extract the name of the database from a given file name. - * Only files ending with .data.db are considered, all others return null. - * - * @param fileName the file name (without directory) - * @return the database name or null - */ - public static String getDatabaseNameFromFileName(String fileName) { - if (fileName.endsWith(Constants.SUFFIX_PAGE_FILE)) { - return fileName.substring(0, fileName.length() - Constants.SUFFIX_PAGE_FILE.length()); - } - return null; - } - - /** - * Try to lock the database, and then unlock it. If this worked, the - * .lock.db file will be removed. - * - * @param files the database files to check - * @param message the text to include in the error message - * @throws SQLException if it failed - */ - public static void tryUnlockDatabase(ArrayList files, String message) throws SQLException { - for (String fileName : files) { - if (fileName.endsWith(Constants.SUFFIX_LOCK_FILE)) { - FileLock lock = new FileLock(new TraceSystem(null), fileName, Constants.LOCK_SLEEP); - try { - lock.lock(FileLock.LOCK_FILE); - lock.unlock(); - } catch (DbException e) { - throw DbException.get( - ErrorCode.CANNOT_CHANGE_SETTING_WHEN_OPEN_1, message).getSQLException(); - } - } - } - } - - /** - * Get the list of database files. - * - * @param dir the directory (null for the current directory) - * @param db the database name (null for all databases) - * @param all if true, files such as the lock, trace, and lob - * files are included. If false, only data, index, log, - * and lob files are returned - * @return the list of files - */ - public static ArrayList getDatabaseFiles(String dir, String db, boolean all) { - if (dir == null || dir.equals("")) { - dir = "."; - } - dir = IOUtils.normalize(dir); - ArrayList files = New.arrayList(); - String start = db == null ? null : IOUtils.normalize(dir + "/" + db); - String[] list = IOUtils.listFiles(dir); - for (int i = 0; list != null && i < list.length; i++) { - String f = list[i]; - boolean ok = false; - if (f.endsWith(Constants.SUFFIX_LOBS_DIRECTORY)) { - if (start == null || IOUtils.fileStartsWith(f, start + ".")) { - files.addAll(getDatabaseFiles(f, null, all)); - ok = true; - } - } else if (f.endsWith(Constants.SUFFIX_LOB_FILE)) { - ok = true; - } else if (f.endsWith(Constants.SUFFIX_PAGE_FILE)) { - ok = true; - } else if (all) { - if (f.endsWith(Constants.SUFFIX_LOCK_FILE)) { - ok = true; - } else if (f.endsWith(Constants.SUFFIX_TEMP_FILE)) { - ok = true; - } else if (f.endsWith(Constants.SUFFIX_TRACE_FILE)) { - ok = true; - } - } - if (ok) { - if (db == null || IOUtils.fileStartsWith(f, start + ".")) { - String fileName = f; - files.add(fileName); - } - } - } - return files; - } - -} diff --git a/tools/h2/src/main/org/h2/store/FileLock.java b/tools/h2/src/main/org/h2/store/FileLock.java deleted file mode 100755 index 7ca259f..0000000 --- a/tools/h2/src/main/org/h2/store/FileLock.java +++ /dev/null @@ -1,508 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.store; - -import java.io.IOException; -import java.io.OutputStream; -import java.net.BindException; -import java.net.ConnectException; -import java.net.InetAddress; -import java.net.ServerSocket; -import java.net.Socket; -import java.net.UnknownHostException; -import java.util.Properties; -import org.h2.constant.ErrorCode; -import org.h2.engine.Constants; -import org.h2.engine.SessionRemote; -import org.h2.message.DbException; -import org.h2.message.Trace; -import org.h2.message.TraceSystem; -import org.h2.store.fs.FileSystem; -import org.h2.util.Utils; -import org.h2.util.MathUtils; -import org.h2.util.NetUtils; -import org.h2.util.SortedProperties; -import org.h2.value.Transfer; - -/** - * The file lock is used to lock a database so that only one process can write - * to it. It uses a cooperative locking protocol. Usually a .lock.db file is - * used, but locking by creating a socket is supported as well. - */ -public class FileLock implements Runnable { - - /** - * This locking method means no locking is used at all. - */ - public static final int LOCK_NO = 0; - - /** - * This locking method means the cooperative file locking protocol should be - * used. - */ - public static final int LOCK_FILE = 1; - - /** - * This locking method means a socket is created on the given machine. - */ - public static final int LOCK_SOCKET = 2; - - /** - * This locking method means multiple writers are allowed, and they - * synchronize themselves. - */ - public static final int LOCK_SERIALIZED = 3; - - private static final String MAGIC = "FileLock"; - private static final String FILE = "file", SOCKET = "socket", SERIALIZED = "serialized"; - private static final int RANDOM_BYTES = 16; - private static final int SLEEP_GAP = 25; - private static final int TIME_GRANULARITY = 2000; - - /** - * The lock file name. - */ - private volatile String fileName; - - /** - * The server socket (only used when using the SOCKET mode). - */ - private volatile ServerSocket serverSocket; - - /** - * The file system. - */ - private FileSystem fs; - - /** - * The number of milliseconds to sleep after checking a file. - */ - private int sleep; - - /** - * The trace object. - */ - private Trace trace; - - /** - * The last time the lock file was written. - */ - private long lastWrite; - - private String method, ipAddress; - private Properties properties; - private boolean locked; - private String uniqueId; - private Thread watchdog; - - /** - * Create a new file locking object. - * - * @param traceSystem the trace system to use - * @param fileName the file name - * @param sleep the number of milliseconds to sleep - */ - public FileLock(TraceSystem traceSystem, String fileName, int sleep) { - this.trace = traceSystem.getTrace(Trace.FILE_LOCK); - this.fileName = fileName; - this.sleep = sleep; - } - - /** - * Lock the file if possible. A file may only be locked once. - * - * @param fileLockMethod the file locking method to use - * @throws SQLException if locking was not successful - */ - public synchronized void lock(int fileLockMethod) { - this.fs = FileSystem.getInstance(fileName); - checkServer(); - if (locked) { - DbException.throwInternalError("already locked"); - } - switch (fileLockMethod) { - case LOCK_FILE: - lockFile(); - break; - case LOCK_SOCKET: - lockSocket(); - break; - case LOCK_SERIALIZED: - lockSerialized(); - break; - } - locked = true; - } - - /** - * Unlock the file. The watchdog thread is stopped. This method does nothing - * if the file is already unlocked. - */ - public synchronized void unlock() { - if (!locked) { - return; - } - try { - if (fileName != null) { - if (load().equals(properties)) { - fs.delete(fileName); - } - } - if (serverSocket != null) { - serverSocket.close(); - } - } catch (Exception e) { - trace.debug("unlock", e); - } finally { - fileName = null; - serverSocket = null; - locked = false; - } - try { - if (watchdog != null) { - watchdog.interrupt(); - } - } catch (Exception e) { - trace.debug("unlock", e); - } - } - - /** - * Add or change a setting to the properties. This call does not save the - * file. - * - * @param key the key - * @param value the value - */ - public void setProperty(String key, String value) { - if (value == null) { - properties.remove(key); - } else { - properties.put(key, value); - } - } - - /** - * Save the lock file. - * - * @return the saved properties - */ - public Properties save() { - try { - OutputStream out = fs.openFileOutputStream(fileName, false); - try { - properties.store(out, MAGIC); - } finally { - out.close(); - } - lastWrite = fs.getLastModified(fileName); - if (trace.isDebugEnabled()) { - trace.debug("save " + properties); - } - return properties; - } catch (IOException e) { - throw getExceptionFatal("Could not save properties " + fileName, e); - } - } - - private void checkServer() { - Properties prop = load(); - String server = prop.getProperty("server"); - if (server == null) { - return; - } - boolean running = false; - String id = prop.getProperty("id"); - try { - Socket socket = NetUtils.createSocket(server, Constants.DEFAULT_TCP_PORT, false); - Transfer transfer = new Transfer(null); - transfer.setSocket(socket); - transfer.init(); - transfer.writeInt(Constants.TCP_PROTOCOL_VERSION); - transfer.writeInt(Constants.TCP_PROTOCOL_VERSION); - transfer.writeString(null); - transfer.writeString(null); - transfer.writeString(id); - transfer.writeInt(SessionRemote.SESSION_CHECK_KEY); - transfer.flush(); - int state = transfer.readInt(); - if (state == SessionRemote.STATUS_OK) { - running = true; - } - transfer.close(); - socket.close(); - } catch (IOException e) { - return; - } - if (running) { - DbException e = DbException.get(ErrorCode.DATABASE_ALREADY_OPEN_1, "Server is running"); - throw e.addSQL(server + "/" + id); - } - } - - /** - * Load the properties file. - * - * @return the properties - */ - public Properties load() { - try { - Properties p2 = SortedProperties.loadProperties(fileName); - if (trace.isDebugEnabled()) { - trace.debug("load " + p2); - } - return p2; - } catch (IOException e) { - throw getExceptionFatal("Could not load properties " + fileName, e); - } - } - - private void waitUntilOld() { - for (int i = 0; i < 2 * TIME_GRANULARITY / SLEEP_GAP; i++) { - long last = fs.getLastModified(fileName); - long dist = System.currentTimeMillis() - last; - if (dist < -TIME_GRANULARITY) { - // lock file modified in the future - - // wait for a bit longer than usual - try { - Thread.sleep(2 * sleep); - } catch (Exception e) { - trace.debug("sleep", e); - } - return; - } else if (dist > TIME_GRANULARITY) { - return; - } - try { - Thread.sleep(SLEEP_GAP); - } catch (Exception e) { - trace.debug("sleep", e); - } - } - throw getExceptionFatal("Lock file recently modified", null); - } - - private void setUniqueId() { - byte[] bytes = MathUtils.secureRandomBytes(RANDOM_BYTES); - String random = Utils.convertBytesToString(bytes); - uniqueId = Long.toHexString(System.currentTimeMillis()) + random; - properties.setProperty("id", uniqueId); - } - - private void lockSerialized() { - method = SERIALIZED; - fs.createDirs(fileName); - if (fs.createNewFile(fileName)) { - properties = new SortedProperties(); - properties.setProperty("method", String.valueOf(method)); - setUniqueId(); - save(); - } else { - while (true) { - try { - properties = load(); - } catch (DbException e) { - // ignore - } - return; - } - } - } - - private void lockFile() { - method = FILE; - properties = new SortedProperties(); - properties.setProperty("method", String.valueOf(method)); - setUniqueId(); - fs.createDirs(fileName); - if (!fs.createNewFile(fileName)) { - waitUntilOld(); - String m2 = load().getProperty("method", FILE); - if (!m2.equals(FILE)) { - throw getExceptionFatal("Unsupported lock method " + m2, null); - } - save(); - sleep(2 * sleep); - if (!load().equals(properties)) { - throw getExceptionAlreadyInUse("Locked by another process"); - } - fs.delete(fileName); - if (!fs.createNewFile(fileName)) { - throw getExceptionFatal("Another process was faster", null); - } - } - save(); - sleep(SLEEP_GAP); - if (!load().equals(properties)) { - fileName = null; - throw getExceptionFatal("Concurrent update", null); - } - watchdog = new Thread(this); - watchdog.setName("H2 File Lock Watchdog " + fileName); - watchdog.setDaemon(true); - watchdog.setPriority(Thread.MAX_PRIORITY - 1); - watchdog.start(); - } - - private void lockSocket() { - method = SOCKET; - properties = new SortedProperties(); - properties.setProperty("method", String.valueOf(method)); - setUniqueId(); - // if this returns 127.0.0.1, - // the computer is probably not networked - ipAddress = NetUtils.getLocalAddress(); - fs.createDirs(fileName); - if (!fs.createNewFile(fileName)) { - waitUntilOld(); - long read = fs.getLastModified(fileName); - Properties p2 = load(); - String m2 = p2.getProperty("method", SOCKET); - if (m2.equals(FILE)) { - lockFile(); - return; - } else if (!m2.equals(SOCKET)) { - throw getExceptionFatal("Unsupported lock method " + m2, null); - } - String ip = p2.getProperty("ipAddress", ipAddress); - if (!ipAddress.equals(ip)) { - throw getExceptionAlreadyInUse("Locked by another computer: " + ip); - } - String port = p2.getProperty("port", "0"); - int portId = Integer.parseInt(port); - InetAddress address; - try { - address = InetAddress.getByName(ip); - } catch (UnknownHostException e) { - throw getExceptionFatal("Unknown host " + ip, e); - } - for (int i = 0; i < 3; i++) { - try { - Socket s = new Socket(address, portId); - s.close(); - throw getExceptionAlreadyInUse("Locked by another process"); - } catch (BindException e) { - throw getExceptionFatal("Bind Exception", null); - } catch (ConnectException e) { - trace.debug("Socket not connected to port " + port, e); - } catch (IOException e) { - throw getExceptionFatal("IOException", null); - } - } - if (read != fs.getLastModified(fileName)) { - throw getExceptionFatal("Concurrent update", null); - } - fs.delete(fileName); - if (!fs.createNewFile(fileName)) { - throw getExceptionFatal("Another process was faster", null); - } - } - try { - // 0 to use any free port - serverSocket = NetUtils.createServerSocket(0, false); - int port = serverSocket.getLocalPort(); - properties.setProperty("ipAddress", ipAddress); - properties.setProperty("port", String.valueOf(port)); - } catch (Exception e) { - trace.debug("lock", e); - serverSocket = null; - lockFile(); - return; - } - save(); - watchdog = new Thread(this); - watchdog.setDaemon(true); - watchdog.setName("H2 File Lock Watchdog (Socket) " + fileName); - watchdog.start(); - } - - private void sleep(int time) { - try { - Thread.sleep(time); - } catch (InterruptedException e) { - throw getExceptionFatal("Sleep interrupted", e); - } - } - - private DbException getExceptionFatal(String reason, Throwable t) { - return DbException.get(ErrorCode.ERROR_OPENING_DATABASE_1, t, reason); - } - - private DbException getExceptionAlreadyInUse(String reason) { - DbException e = DbException.get(ErrorCode.DATABASE_ALREADY_OPEN_1, reason); - if (fileName != null) { - try { - Properties prop = load(); - String serverId = prop.getProperty("server") + "/" + prop.getProperty("id"); - e = e.addSQL(serverId); - } catch (DbException e2) { - // ignore - } - } - return e; - } - - /** - * Get the file locking method type given a method name. - * - * @param method the method name - * @return the method type - * @throws SQLException if the method name is unknown - */ - public static int getFileLockMethod(String method) { - if (method == null || method.equalsIgnoreCase("FILE")) { - return FileLock.LOCK_FILE; - } else if (method.equalsIgnoreCase("NO")) { - return FileLock.LOCK_NO; - } else if (method.equalsIgnoreCase("SOCKET")) { - return FileLock.LOCK_SOCKET; - } else if (method.equalsIgnoreCase("SERIALIZED")) { - return FileLock.LOCK_SERIALIZED; - } else { - throw DbException.get(ErrorCode.UNSUPPORTED_LOCK_METHOD_1, method); - } - } - - public String getUniqueId() { - return uniqueId; - } - - public void run() { - try { - while (fileName != null) { - // trace.debug("watchdog check"); - try { - if (!fs.exists(fileName) || fs.getLastModified(fileName) != lastWrite) { - save(); - } - Thread.sleep(sleep); - } catch (OutOfMemoryError e) { - // ignore - } catch (InterruptedException e) { - // ignore - } catch (NullPointerException e) { - // ignore - } catch (Exception e) { - trace.debug("watchdog", e); - } - } - while (serverSocket != null) { - try { - trace.debug("watchdog accept"); - Socket s = serverSocket.accept(); - s.close(); - } catch (Exception e) { - trace.debug("watchdog", e); - } - } - } catch (Exception e) { - trace.debug("watchdog", e); - } - trace.debug("watchdog end"); - } - -} diff --git a/tools/h2/src/main/org/h2/store/FileStore.java b/tools/h2/src/main/org/h2/store/FileStore.java deleted file mode 100755 index 17346e1..0000000 --- a/tools/h2/src/main/org/h2/store/FileStore.java +++ /dev/null @@ -1,509 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.store; - -import java.io.IOException; -import java.lang.ref.Reference; -import org.h2.constant.ErrorCode; -import org.h2.constant.SysProperties; -import org.h2.engine.Constants; -import org.h2.message.DbException; -import org.h2.security.SecureFileStore; -import org.h2.store.fs.FileObject; -import org.h2.store.fs.FileSystem; -import org.h2.util.TempFileDeleter; -import org.h2.util.Utils; - -/** - * This class is an abstraction of a random access file. - * Each file contains a magic header, and reading / writing is done in blocks. - * See also {@link SecureFileStore} - */ -public class FileStore { - - /** - * The size of the file header in bytes. - */ - public static final int HEADER_LENGTH = 3 * Constants.FILE_BLOCK_SIZE; - - /** - * An empty buffer to speed up extending the file (it seems that writing 0 - * bytes is faster then calling setLength). - */ - protected static final byte[] EMPTY = new byte[16 * 1024]; - - /** - * The magic file header. - */ - private static final String HEADER = "-- H2 0.5/B -- ".substring(0, Constants.FILE_BLOCK_SIZE - 1) + "\n"; - - /** - * The file name. - */ - protected String name; - - /** - * The callback object is responsible to check access rights, and free up - * disk space if required. - */ - protected DataHandler handler; - - private FileObject file; - private long filePos; - private long fileLength; - private Reference< ? > autoDeleteReference; - private boolean checkedWriting = true; - private boolean synchronousMode; - private String mode; - private TempFileDeleter tempFileDeleter; - private boolean textMode; - - /** - * Create a new file using the given settings. - * - * @param handler the callback object - * @param name the file name - * @param mode the access mode ("r", "rw", "rws", "rwd") - */ - protected FileStore(DataHandler handler, String name, String mode) { - FileSystem fs = FileSystem.getInstance(name); - this.handler = handler; - this.name = name; - this.mode = mode; - if (handler != null) { - tempFileDeleter = handler.getTempFileDeleter(); - } - try { - fs.createDirs(name); - if (fs.exists(name) && !fs.canWrite(name)) { - mode = "r"; - this.mode = mode; - } - file = fs.openFileObject(name, mode); - if (mode.length() > 2) { - synchronousMode = true; - } - fileLength = file.length(); - } catch (IOException e) { - throw DbException.convertIOException(e, "name: " + name + " mode: " + mode); - } - } - - /** - * Open a non encrypted file store with the given settings. - * - * @param handler the data handler - * @param name the file name - * @param mode the access mode (r, rw, rws, rwd) - * @return the created object - */ - public static FileStore open(DataHandler handler, String name, String mode) { - return open(handler, name, mode, null, null, 0); - } - - /** - * Open an encrypted file store with the given settings. - * - * @param handler the data handler - * @param name the file name - * @param mode the access mode (r, rw, rws, rwd) - * @param cipher the name of the cipher algorithm - * @param key the encryption key - * @return the created object - */ - public static FileStore open(DataHandler handler, String name, String mode, String cipher, byte[] key) { - return open(handler, name, mode, cipher, key, Constants.ENCRYPTION_KEY_HASH_ITERATIONS); - } - - /** - * Open an encrypted file store with the given settings. - * - * @param handler the data handler - * @param name the file name - * @param mode the access mode (r, rw, rws, rwd) - * @param cipher the name of the cipher algorithm - * @param key the encryption key - * @param keyIterations the number of iterations the key should be hashed - * @return the created object - */ - public static FileStore open(DataHandler handler, String name, String mode, String cipher, - byte[] key, int keyIterations) { - FileStore store; - if (cipher == null) { - store = new FileStore(handler, name, mode); - } else { - store = new SecureFileStore(handler, name, mode, cipher, key, keyIterations); - } - return store; - } - - /** - * Generate the random salt bytes if required. - * - * @return the random salt or the magic - */ - protected byte[] generateSalt() { - return HEADER.getBytes(); - } - - /** - * Initialize the key using the given salt. - * - * @param salt the salt - */ - protected void initKey(byte[] salt) { - // do nothing - } - - public void setCheckedWriting(boolean value) { - this.checkedWriting = value; - } - - private void checkWritingAllowed() { - if (handler != null && checkedWriting) { - handler.checkWritingAllowed(); - } - } - - private void checkPowerOff() { - if (handler != null) { - handler.checkPowerOff(); - } - } - - /** - * Initialize the file. This method will write or check the file header if - * required. - */ - public void init() { - int len = Constants.FILE_BLOCK_SIZE; - byte[] salt; - byte[] magic = HEADER.getBytes(); - if (length() < HEADER_LENGTH) { - // write unencrypted - checkedWriting = false; - writeDirect(magic, 0, len); - salt = generateSalt(); - writeDirect(salt, 0, len); - initKey(salt); - // write (maybe) encrypted - write(magic, 0, len); - checkedWriting = true; - } else { - // read unencrypted - seek(0); - byte[] buff = new byte[len]; - readFullyDirect(buff, 0, len); - if (Utils.compareNotNull(buff, magic) != 0) { - throw DbException.get(ErrorCode.FILE_VERSION_ERROR_1, name); - } - salt = new byte[len]; - readFullyDirect(salt, 0, len); - initKey(salt); - // read (maybe) encrypted - readFully(buff, 0, Constants.FILE_BLOCK_SIZE); - if (textMode) { - buff[10] = 'B'; - } - if (Utils.compareNotNull(buff, magic) != 0) { - throw DbException.get(ErrorCode.FILE_ENCRYPTION_ERROR_1, name); - } - } - } - - /** - * Close the file. - */ - public void close() { - if (file != null) { - try { - trace("close", name, file); - file.close(); - } catch (IOException e) { - throw DbException.convertIOException(e, name); - } finally { - file = null; - } - } - } - - /** - * Close the file without throwing any exceptions. Exceptions are simply - * ignored. - */ - public void closeSilently() { - try { - close(); - } catch (Exception e) { - // ignore - } - } - - /** - * Close the file (ignoring exceptions) and delete the file. - */ - public void closeAndDeleteSilently() { - if (file != null) { - closeSilently(); - tempFileDeleter.deleteFile(autoDeleteReference, name); - name = null; - } - } - - /** - * Read a number of bytes without decrypting. - * - * @param b the target buffer - * @param off the offset - * @param len the number of bytes to read - */ - protected void readFullyDirect(byte[] b, int off, int len) { - readFully(b, off, len); - } - - /** - * Read a number of bytes. - * - * @param b the target buffer - * @param off the offset - * @param len the number of bytes to read - */ - public void readFully(byte[] b, int off, int len) { - if (SysProperties.CHECK && (len < 0 || len % Constants.FILE_BLOCK_SIZE != 0)) { - DbException.throwInternalError("unaligned read " + name + " len " + len); - } - checkPowerOff(); - try { - file.readFully(b, off, len); - } catch (IOException e) { - throw DbException.convertIOException(e, name); - } - filePos += len; - } - - /** - * Go to the specified file location. - * - * @param pos the location - */ - public void seek(long pos) { - if (SysProperties.CHECK && pos % Constants.FILE_BLOCK_SIZE != 0) { - DbException.throwInternalError("unaligned seek " + name + " pos " + pos); - } - try { - if (pos != filePos) { - file.seek(pos); - filePos = pos; - } - } catch (IOException e) { - throw DbException.convertIOException(e, name); - } - } - - /** - * Write a number of bytes without encrypting. - * - * @param b the source buffer - * @param off the offset - * @param len the number of bytes to write - */ - protected void writeDirect(byte[] b, int off, int len) { - write(b, off, len); - } - - /** - * Write a number of bytes. - * - * @param b the source buffer - * @param off the offset - * @param len the number of bytes to write - */ - public void write(byte[] b, int off, int len) { - if (SysProperties.CHECK && (len < 0 || len % Constants.FILE_BLOCK_SIZE != 0)) { - DbException.throwInternalError("unaligned write " + name + " len " + len); - } - checkWritingAllowed(); - checkPowerOff(); - try { - file.write(b, off, len); - } catch (IOException e) { - if (freeUpDiskSpace()) { - try { - file.write(b, off, len); - } catch (IOException e2) { - throw DbException.convertIOException(e2, name); - } - } else { - throw DbException.convertIOException(e, name); - } - } - filePos += len; - fileLength = Math.max(filePos, fileLength); - } - - private boolean freeUpDiskSpace() { - if (handler == null) { - return false; - } - handler.freeUpDiskSpace(); - return true; - } - - private void extendByWriting(long newLength) throws IOException { - long pos = filePos; - file.seek(fileLength); - byte[] empty = EMPTY; - while (true) { - int p = (int) Math.min(newLength - fileLength, EMPTY.length); - if (p <= 0) { - break; - } - file.write(empty, 0, p); - fileLength += p; - } - file.seek(pos); - } - - /** - * Set the length of the file. This will expand or shrink the file. - * - * @param newLength the new file size - */ - public void setLength(long newLength) { - if (SysProperties.CHECK && newLength % Constants.FILE_BLOCK_SIZE != 0) { - DbException.throwInternalError("unaligned setLength " + name + " pos " + newLength); - } - checkPowerOff(); - checkWritingAllowed(); - try { - if (synchronousMode && newLength > fileLength) { - extendByWriting(newLength); - } else { - file.setFileLength(newLength); - } - fileLength = newLength; - } catch (IOException e) { - if (newLength > fileLength && freeUpDiskSpace()) { - try { - file.setFileLength(newLength); - } catch (IOException e2) { - throw DbException.convertIOException(e2, name); - } - } else { - throw DbException.convertIOException(e, name); - } - } - } - - /** - * Get the file size in bytes. - * - * @return the file size - */ - public long length() { - try { - long len = fileLength; - if (SysProperties.CHECK2) { - len = file.length(); - if (len != fileLength) { - DbException.throwInternalError("file " + name + " length " + len + " expected " + fileLength); - } - } - if (SysProperties.CHECK2 && len % Constants.FILE_BLOCK_SIZE != 0) { - long newLength = len + Constants.FILE_BLOCK_SIZE - (len % Constants.FILE_BLOCK_SIZE); - file.setFileLength(newLength); - fileLength = newLength; - DbException.throwInternalError("unaligned file length " + name + " len " + len); - } - return len; - } catch (IOException e) { - throw DbException.convertIOException(e, name); - } - } - - /** - * Get the current location of the file pointer. - * - * @return the location - */ - public long getFilePointer() { - if (SysProperties.CHECK2) { - try { - if (file.getFilePointer() != filePos) { - DbException.throwInternalError(); - } - } catch (IOException e) { - throw DbException.convertIOException(e, name); - } - } - return filePos; - } - - /** - * Call fsync. Depending on the operating system and hardware, this may or - * may not in fact write the changes. - */ - public void sync() { - try { - file.sync(); - } catch (IOException e) { - throw DbException.convertIOException(e, name); - } - } - - /** - * Automatically delete the file once it is no longer in use. - */ - public void autoDelete() { - if (autoDeleteReference == null) { - autoDeleteReference = tempFileDeleter.addFile(name, this); - } - } - - /** - * No longer automatically delete the file once it is no longer in use. - */ - public void stopAutoDelete() { - tempFileDeleter.stopAutoDelete(autoDeleteReference, name); - autoDeleteReference = null; - } - - /** - * Close the file. The file may later be re-opened using openFile. - */ - public void closeFile() throws IOException { - file.close(); - file = null; - } - - /** - * Re-open the file. The file pointer will be reset to the previous - * location. - */ - public void openFile() throws IOException { - if (file == null) { - file = FileSystem.getInstance(name).openFileObject(name, mode); - file.seek(filePos); - } - } - - private static void trace(String method, String fileName, Object o) { - if (SysProperties.TRACE_IO) { - System.out.println("FileStore." + method + " " + fileName + " " + o); - } - } - - /** - * Check if the file store is in text mode. - * - * @return true if it is - */ - public boolean isTextMode() { - return textMode; - } - -} diff --git a/tools/h2/src/main/org/h2/store/FileStoreInputStream.java b/tools/h2/src/main/org/h2/store/FileStoreInputStream.java deleted file mode 100755 index 309f2cf..0000000 --- a/tools/h2/src/main/org/h2/store/FileStoreInputStream.java +++ /dev/null @@ -1,166 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.store; - -import java.io.IOException; -import java.io.InputStream; -import org.h2.constant.SysProperties; -import org.h2.engine.Constants; -import org.h2.message.DbException; -import org.h2.tools.CompressTool; -import org.h2.util.Utils; - -/** - * An input stream that is backed by a file store. - */ -public class FileStoreInputStream extends InputStream { - - private FileStore store; - private Data page; - private int remainingInBuffer; - private CompressTool compress; - private boolean endOfFile; - private boolean alwaysClose; - - public FileStoreInputStream(FileStore store, DataHandler handler, boolean compression, boolean alwaysClose) { - this.store = store; - this.alwaysClose = alwaysClose; - if (compression) { - compress = CompressTool.getInstance(); - } - page = Data.create(handler, Constants.FILE_BLOCK_SIZE); - try { - if (store.length() <= FileStore.HEADER_LENGTH) { - close(); - } else { - fillBuffer(); - } - } catch (IOException e) { - throw DbException.convertIOException(e, store.name); - } - } - - public int available() { - return remainingInBuffer <= 0 ? 0 : remainingInBuffer; - } - - public int read(byte[] buff) throws IOException { - return read(buff, 0, buff.length); - } - - public int read(byte[] b, int off, int len) throws IOException { - if (len == 0) { - return 0; - } - int read = 0; - while (len > 0) { - int r = readBlock(b, off, len); - if (r < 0) { - break; - } - read += r; - off += r; - len -= r; - } - return read == 0 ? -1 : read; - } - - private int readBlock(byte[] buff, int off, int len) throws IOException { - fillBuffer(); - if (endOfFile) { - return -1; - } - int l = Math.min(remainingInBuffer, len); - page.read(buff, off, l); - remainingInBuffer -= l; - return l; - } - - private void fillBuffer() throws IOException { - if (remainingInBuffer > 0 || endOfFile) { - return; - } - page.reset(); - store.openFile(); - if (store.length() == store.getFilePointer()) { - close(); - return; - } - store.readFully(page.getBytes(), 0, Constants.FILE_BLOCK_SIZE); - page.reset(); - remainingInBuffer = readInt(); - if (remainingInBuffer < 0) { - close(); - return; - } - page.checkCapacity(remainingInBuffer); - // get the length to read - if (compress != null) { - page.checkCapacity(Data.LENGTH_INT); - readInt(); - } - page.setPos(page.length() + remainingInBuffer); - page.fillAligned(); - int len = page.length() - Constants.FILE_BLOCK_SIZE; - page.reset(); - readInt(); - store.readFully(page.getBytes(), Constants.FILE_BLOCK_SIZE, len); - page.reset(); - readInt(); - if (compress != null) { - int uncompressed = readInt(); - byte[] buff = Utils.newBytes(remainingInBuffer); - page.read(buff, 0, remainingInBuffer); - page.reset(); - page.checkCapacity(uncompressed); - compress.expand(buff, page.getBytes(), 0); - remainingInBuffer = uncompressed; - } - if (alwaysClose) { - store.closeFile(); - } - } - - public void close() { - if (store != null) { - try { - store.close(); - endOfFile = true; - } finally { - store = null; - } - } - } - - protected void finalize() { - if (!SysProperties.runFinalize) { - return; - } - close(); - } - - public int read() throws IOException { - fillBuffer(); - if (endOfFile) { - return -1; - } - int i = page.readByte() & 0xff; - remainingInBuffer--; - return i; - } - - private int readInt() { - if (store.isTextMode()) { - byte[] buff = new byte[8]; - page.read(buff, 0, 8); - String s = new String(buff); - return Integer.parseInt(s, 16); - } - return page.readInt(); - } - -} diff --git a/tools/h2/src/main/org/h2/store/FileStoreOutputStream.java b/tools/h2/src/main/org/h2/store/FileStoreOutputStream.java deleted file mode 100755 index 30706a5..0000000 --- a/tools/h2/src/main/org/h2/store/FileStoreOutputStream.java +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.store; - -import java.io.OutputStream; -import org.h2.engine.Constants; -import org.h2.tools.CompressTool; - -/** - * An output stream that is backed by a file store. - */ -public class FileStoreOutputStream extends OutputStream { - private FileStore store; - private Data page; - private String compressionAlgorithm; - private CompressTool compress; - private byte[] buffer = { 0 }; - - public FileStoreOutputStream(FileStore store, DataHandler handler, String compressionAlgorithm) { - this.store = store; - if (compressionAlgorithm != null) { - compress = CompressTool.getInstance(); - this.compressionAlgorithm = compressionAlgorithm; - } - page = Data.create(handler, Constants.FILE_BLOCK_SIZE); - } - - public void write(int b) { - buffer[0] = (byte) b; - write(buffer); - } - - public void write(byte[] buff) { - write(buff, 0, buff.length); - } - - public void write(byte[] buff, int off, int len) { - if (len > 0) { - page.reset(); - if (compress != null) { - if (off != 0 || len != buff.length) { - byte[] b2 = new byte[len]; - System.arraycopy(buff, off, b2, 0, len); - buff = b2; - off = 0; - } - int uncompressed = len; - buff = compress.compress(buff, compressionAlgorithm); - len = buff.length; - page.checkCapacity(2 * Data.LENGTH_INT + len); - page.writeInt(len); - page.writeInt(uncompressed); - page.write(buff, off, len); - } else { - page.checkCapacity(Data.LENGTH_INT + len); - page.writeInt(len); - page.write(buff, off, len); - } - page.fillAligned(); - store.write(page.getBytes(), 0, page.length()); - } - } - - public void close() { - if (store != null) { - try { - store.close(); - } finally { - store = null; - } - } - } - -} diff --git a/tools/h2/src/main/org/h2/store/InDoubtTransaction.java b/tools/h2/src/main/org/h2/store/InDoubtTransaction.java deleted file mode 100755 index 2826783..0000000 --- a/tools/h2/src/main/org/h2/store/InDoubtTransaction.java +++ /dev/null @@ -1,103 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.store; - -import org.h2.message.DbException; - -/** - * Represents an in-doubt transaction (a transaction in the prepare phase). - */ -public class InDoubtTransaction { - - /** - * The transaction state meaning this transaction is not committed yet, but - * also not rolled back (in-doubt). - */ - public static final int IN_DOUBT = 0; - - /** - * The transaction state meaning this transaction is committed. - */ - public static final int COMMIT = 1; - - /** - * The transaction state meaning this transaction is rolled back. - */ - public static final int ROLLBACK = 2; - - // TODO 2-phase-commit: document sql statements and metadata table - - private final PageStore store; - private final int sessionId; - private final int pos; - private final String transaction; - private int state; - - /** - * Create a new in-doubt transaction info object. - * - * @param store the page store - * @param sessionId the session id - * @param pos the position - * @param transaction the transaction name - */ - public InDoubtTransaction(PageStore store, int sessionId, int pos, String transaction) { - this.store = store; - this.sessionId = sessionId; - this.pos = pos; - this.transaction = transaction; - this.state = IN_DOUBT; - } - - /** - * Change the state of this transaction. - * This will also update the transaction log. - * - * @param state the new state - */ - public void setState(int state) { - switch(state) { - case COMMIT: - store.setInDoubtTransactionState(sessionId, pos, true); - break; - case ROLLBACK: - store.setInDoubtTransactionState(sessionId, pos, false); - break; - default: - DbException.throwInternalError("state="+state); - } - this.state = state; - } - - /** - * Get the state of this transaction as a text. - * - * @return the transaction state text - */ - public String getState() { - switch(state) { - case IN_DOUBT: - return "IN_DOUBT"; - case COMMIT: - return "COMMIT"; - case ROLLBACK: - return "ROLLBACK"; - default: - throw DbException.throwInternalError("state="+state); - } - } - - /** - * Get the name of the transaction. - * - * @return the transaction name - */ - public String getTransaction() { - return transaction; - } - -} diff --git a/tools/h2/src/main/org/h2/store/LobStorage.java b/tools/h2/src/main/org/h2/store/LobStorage.java deleted file mode 100755 index bafe7e6..0000000 --- a/tools/h2/src/main/org/h2/store/LobStorage.java +++ /dev/null @@ -1,578 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.store; - -import java.io.IOException; -import java.io.InputStream; -import java.io.Reader; -import java.sql.Connection; -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.sql.Statement; -import java.util.Arrays; -import java.util.HashMap; -import org.h2.constant.ErrorCode; -import org.h2.constant.SysProperties; -import org.h2.engine.Constants; -import org.h2.message.DbException; -import org.h2.tools.CompressTool; -import org.h2.util.IOUtils; -import org.h2.util.New; -import org.h2.util.StringUtils; -import org.h2.util.Utils; -import org.h2.value.Value; -import org.h2.value.ValueLob; -import org.h2.value.ValueLobDb; - -/** - * This class stores LOB objects in the database. - */ -public class LobStorage { - - /** - * The table id for session variables (LOBs not assigned to a table). - */ - public static final int TABLE_ID_SESSION_VARIABLE = -1; - - /** - * The table id for temporary objects (not assigned to any object). - */ - public static final int TABLE_TEMP = -2; - - - private static final String LOBS = "INFORMATION_SCHEMA.LOBS"; - private static final String LOB_MAP = "INFORMATION_SCHEMA.LOB_MAP"; - private static final String LOB_DATA = "INFORMATION_SCHEMA.LOB_DATA"; - - private static final int BLOCK_LENGTH = 20000; - private static final boolean HASH = true; - private static final long UNIQUE = 0xffff; - private Connection conn; - private HashMap prepared = New.hashMap(); - private long nextBlock; - private CompressTool compress = CompressTool.getInstance(); - - private final DataHandler handler; - private boolean init; - - public LobStorage(DataHandler handler) { - this.handler = handler; - } - - /** - * Initialize the lob storage. - */ - public void init() { - if (init) { - return; - } - conn = handler.getLobConnection(); - init = true; - if (conn == null) { - return; - } - try { - Statement stat = conn.createStatement(); - // stat.execute("SET UNDO_LOG 0"); - // stat.execute("SET REDO_LOG_BINARY 0"); - stat.execute("CREATE TABLE IF NOT EXISTS " + LOBS + "(ID BIGINT PRIMARY KEY, BYTE_COUNT BIGINT, TABLE INT) HIDDEN"); - stat.execute("CREATE TABLE IF NOT EXISTS " + LOB_MAP + "(LOB BIGINT, SEQ INT, BLOCK BIGINT, PRIMARY KEY(LOB, SEQ)) HIDDEN"); - stat.execute("CREATE INDEX IF NOT EXISTS INFORMATION_SCHEMA.INDEX_LOB_MAP_DATA_LOB ON " + LOB_MAP + "(BLOCK, LOB)"); - stat.execute("CREATE TABLE IF NOT EXISTS " + LOB_DATA + "(BLOCK BIGINT PRIMARY KEY, COMPRESSED INT, DATA BINARY) HIDDEN"); - ResultSet rs; - rs = stat.executeQuery("SELECT MAX(BLOCK) FROM " + LOB_DATA); - rs.next(); - nextBlock = rs.getLong(1) + 1; - if (HASH) { - nextBlock = Math.max(UNIQUE + 1, nextBlock); - } - } catch (SQLException e) { - throw DbException.convert(e); - } - } - - private long getNextLobId() throws SQLException { - PreparedStatement prep = prepare("SELECT MAX(ID) FROM " + LOBS); - ResultSet rs = prep.executeQuery(); - rs.next(); - return rs.getLong(1) + 1; - } - - /** - * Remove all LOBs for this table. - * - * @param tableId the table id - */ - public void removeAllForTable(int tableId) { - if (SysProperties.LOB_IN_DATABASE) { - init(); - try { - PreparedStatement prep = prepare("SELECT ID FROM " + LOBS + " WHERE TABLE = ?"); - prep.setInt(1, tableId); - ResultSet rs = prep.executeQuery(); - while (rs.next()) { - deleteLob(rs.getLong(1)); - } - } catch (SQLException e) { - throw DbException.convert(e); - } - if (tableId == TABLE_ID_SESSION_VARIABLE) { - removeAllForTable(TABLE_TEMP); - } - // remove both lobs in the database as well as in the file system - // (compatibility) - } - ValueLob.removeAllForTable(handler, tableId); - } - - /** - * Create a LOB object that fits in memory. - * - * @param type the value type - * @param small the byte array - * @return the LOB - */ - public static Value createSmallLob(int type, byte[] small) { - if (SysProperties.LOB_IN_DATABASE) { - int precision; - if (type == Value.CLOB) { - precision = StringUtils.utf8Decode(small).length(); - } else { - precision = small.length; - } - return ValueLobDb.createSmallLob(type, small, precision); - } - return ValueLob.createSmallLob(type, small); - } - - /** - * An input stream that reads from a LOB. - */ - public static class LobInputStream extends InputStream { - - private final Connection conn; - private PreparedStatement prepSelect; - private byte[] buffer; - private int pos; - private long remainingBytes; - private long lob; - private int seq; - private CompressTool compress; - - public LobInputStream(Connection conn, long lob) throws IOException { - this.conn = conn; - try { - this.lob = lob; - PreparedStatement prep = conn.prepareStatement( - "SELECT BYTE_COUNT FROM " + LOBS + " WHERE ID = ?"); - prep.setLong(1, lob); - ResultSet rs = prep.executeQuery(); - if (!rs.next()) { - throw DbException.get(ErrorCode.IO_EXCEPTION_1, "Missing lob: "+ lob).getSQLException(); - } - remainingBytes = rs.getLong(1); - rs.close(); - } catch (SQLException e) { - throw DbException.convertToIOException(e); - } - } - - public int read() throws IOException { - fillBuffer(); - if (remainingBytes <= 0) { - return -1; - } - remainingBytes--; - return buffer[pos++] & 255; - } - - public int read(byte[] buff) throws IOException { - return readFully(buff, 0, buff.length); - } - - public int read(byte[] buff, int off, int length) throws IOException { - return readFully(buff, off, length); - } - - private int readFully(byte[] buff, int off, int length) throws IOException { - if (length == 0) { - return 0; - } - int read = 0; - while (length > 0) { - fillBuffer(); - if (remainingBytes <= 0) { - break; - } - int len = (int) Math.min(length, remainingBytes); - len = Math.min(len, buffer.length - pos); - System.arraycopy(buffer, pos, buff, off, len); - pos += len; - read += len; - remainingBytes -= len; - off += len; - length -= len; - } - return read == 0 ? -1 : read; - } - - private void fillBuffer() throws IOException { - if (buffer != null && pos < buffer.length) { - return; - } - if (remainingBytes <= 0) { - return; - } - try { - if (prepSelect == null) { - prepSelect = conn.prepareStatement( - "SELECT COMPRESSED, DATA FROM " + LOB_MAP + " M " + - "INNER JOIN " + LOB_DATA + " D ON M.BLOCK = D.BLOCK " + - "WHERE M.LOB = ? AND M.SEQ = ?"); - } - prepSelect.setLong(1, lob); - prepSelect.setInt(2, seq); - ResultSet rs = prepSelect.executeQuery(); - if (!rs.next()) { - throw DbException.get(ErrorCode.IO_EXCEPTION_1, "Missing lob entry: "+ lob + "/" + seq).getSQLException(); - } - seq++; - int compressed = rs.getInt(1); - buffer = rs.getBytes(2); - if (compressed != 0) { - if (compress == null) { - compress = CompressTool.getInstance(); - } - buffer = compress.expand(buffer); - } - pos = 0; - } catch (SQLException e) { - throw DbException.convertToIOException(e); - } - } - - } - - private synchronized PreparedStatement prepare(String sql) throws SQLException { - PreparedStatement prep = prepared.get(sql); - if (prep == null) { - prep = conn.prepareStatement(sql); - prepared.put(sql, prep); - } - return prep; - } - - private void deleteLob(long lob) throws SQLException { - PreparedStatement prep; - prep = prepare( - "DELETE FROM " + LOB_MAP + " " + - "WHERE LOB = ?"); - prep.setLong(1, lob); - prep.execute(); - prep = prepare( - "DELETE FROM " + LOB_DATA + " D " + - "WHERE BLOCK IN(SELECT M.BLOCK FROM " + LOB_MAP + " M WHERE LOB = ?) " + - "AND NOT EXISTS(SELECT 1 FROM " + LOB_MAP + " M " + - "WHERE M.BLOCK = D.BLOCK AND M.LOB <> ?)"); - prep.setLong(1, lob); - prep.setLong(2, lob); - prep.execute(); - prep = prepare( - "DELETE FROM " + LOBS + " " + - "WHERE ID = ?"); - prep.setLong(1, lob); - prep.execute(); - } - - /** - * Get the input stream for the given lob. - * - * @param lobId the lob id - * @return the stream - */ - public InputStream getInputStream(long lobId) throws IOException { - init(); - return new LobInputStream(conn, lobId); - } - - private ValueLobDb addLob(InputStream in, long maxLength, int type) { - byte[] buff = new byte[BLOCK_LENGTH]; - if (maxLength < 0) { - maxLength = Long.MAX_VALUE; - } - long length = 0; - long lobId; - int maxLengthInPlaceLob = handler.getMaxLengthInplaceLob(); - String compressAlgorithm = handler.getLobCompressionAlgorithm(type); - try { - lobId = getNextLobId(); - try { - for (int seq = 0; maxLength > 0; seq++) { - int len = (int) Math.min(BLOCK_LENGTH, maxLength); - len = IOUtils.readFully(in, buff, 0, len); - if (len <= 0) { - break; - } - length += len; - maxLength -= len; - byte[] b; - if (len != buff.length) { - b = new byte[len]; - System.arraycopy(buff, 0, b, 0, len); - } else { - b = buff; - } - if (seq == 0 && b.length < BLOCK_LENGTH && b.length <= maxLengthInPlaceLob) { - // CLOB: the precision will be fixed later - ValueLobDb v = ValueLobDb.createSmallLob(type, b, b.length); - return v; - } - storeBlock(lobId, seq, b, compressAlgorithm); - } - return registerLob(type, lobId, TABLE_TEMP, length); - } catch (IOException e) { - deleteLob(lobId); - throw DbException.convertIOException(e, "adding blob"); - } - } catch (SQLException e) { - throw DbException.convert(e); - } - } - - private ValueLobDb registerLob(int type, long lobId, int tableId, long byteCount) { - try { - PreparedStatement prep = prepare( - "INSERT INTO " + LOBS + "(ID, BYTE_COUNT, TABLE) VALUES(?, ?, ?)"); - prep.setLong(1, lobId); - prep.setLong(2, byteCount); - prep.setInt(3, tableId); - prep.execute(); - ValueLobDb v = ValueLobDb.create(type, this, null, tableId, lobId, byteCount); - return v; - } catch (SQLException e) { - throw DbException.convert(e); - } - } - - /** - * Copy a lob. - * - * @param type the type - * @param oldLobId the old lob id - * @param tableId the new table id - * @param length the length - * @return the new lob - */ - public ValueLobDb copyLob(int type, long oldLobId, int tableId, long length) { - try { - long lobId = getNextLobId(); - PreparedStatement prep = prepare( - "INSERT INTO " + LOB_MAP + "(LOB, SEQ, BLOCK) " + - "SELECT ?, SEQ, BLOCK FROM " + LOB_MAP + " WHERE LOB = ?"); - prep.setLong(1, lobId); - prep.setLong(2, oldLobId); - prep.executeUpdate(); - prep = prepare( - "INSERT INTO " + LOBS + "(ID, BYTE_COUNT, TABLE) " + - "SELECT ?, BYTE_COUNT, ? FROM " + LOBS + " WHERE ID = ?"); - prep.setLong(1, lobId); - prep.setLong(2, tableId); - prep.setLong(3, oldLobId); - prep.executeUpdate(); - ValueLobDb v = ValueLobDb.create(type, this, null, tableId, lobId, length); - return v; - } catch (SQLException e) { - throw DbException.convert(e); - } - } - - /** - * Store a block in the LOB storage. - * - * @param lobId the lob id - * @param seq the sequence number - * @param b the data - * @param compressAlgorithm the compression algorithm (may be null) - */ - synchronized void storeBlock(long lobId, int seq, byte[] b, String compressAlgorithm) throws SQLException { - long block; - boolean blockExists = false; - if (compressAlgorithm != null) { - b = compress.compress(b, compressAlgorithm); - } - if (HASH) { - block = Arrays.hashCode(b) & UNIQUE; - PreparedStatement prep = prepare( - "SELECT COMPRESSED, DATA FROM " + LOB_DATA + - " WHERE BLOCK = ?"); - prep.setLong(1, block); - ResultSet rs = prep.executeQuery(); - if (rs.next()) { - boolean compressed = rs.getInt(1) != 0; - byte[] compare = rs.getBytes(2); - if (Arrays.equals(b, compare) && compressed == (compressAlgorithm != null)) { - blockExists = true; - } else { - block = nextBlock++; - } - } - } else { - block = nextBlock++; - } - if (!blockExists) { - PreparedStatement prep = prepare( - "INSERT INTO " + LOB_DATA + "(BLOCK, COMPRESSED, DATA) VALUES(?, ?, ?)"); - prep.setLong(1, block); - prep.setInt(2, compressAlgorithm == null ? 0 : 1); - prep.setBytes(3, b); - prep.execute(); - } - PreparedStatement prep = prepare( - "INSERT INTO " + LOB_MAP + "(LOB, SEQ, BLOCK) VALUES(?, ?, ?)"); - prep.setLong(1, lobId); - prep.setInt(2, seq); - prep.setLong(3, block); - prep.execute(); - } - - /** - * An input stream that reads the data from a reader. - */ - static class CountingReaderInputStream extends InputStream { - - private final Reader reader; - private long length; - private long remaining; - private int pos; - private char[] charBuffer = new char[Constants.IO_BUFFER_SIZE]; - private byte[] buffer; - - CountingReaderInputStream(Reader reader, long maxLength) { - this.reader = reader; - this.remaining = maxLength; - buffer = Utils.EMPTY_BYTES; - } - - public int read(byte[] buff, int offset, int len) throws IOException { - if (buffer == null) { - return -1; - } - if (pos >= buffer.length) { - fillBuffer(); - if (buffer == null) { - return -1; - } - } - len = Math.min(len, buffer.length - pos); - System.arraycopy(buffer, pos, buff, offset, len); - pos += len; - return len; - } - - public int read() throws IOException { - if (buffer == null) { - return -1; - } - if (pos >= buffer.length) { - fillBuffer(); - if (buffer == null) { - return -1; - } - } - return buffer[pos++]; - } - - private void fillBuffer() throws IOException { - int len = (int) Math.min(charBuffer.length, remaining); - if (len > 0) { - len = reader.read(charBuffer, 0, len); - } else { - len = -1; - } - if (len < 0) { - buffer = null; - } else { - buffer = StringUtils.utf8Encode(new String(charBuffer, 0, len)); - length += len; - remaining -= len; - } - pos = 0; - } - - public long getLength() { - return length; - } - - public void close() throws IOException { - reader.close(); - } - - } - - /** - * Create a BLOB object. - * - * @param in the input stream - * @param maxLength the maximum length (-1 if not known) - * @return the LOB - */ - public Value createBlob(InputStream in, long maxLength) { - if (SysProperties.LOB_IN_DATABASE) { - init(); - if (conn == null) { - return ValueLobDb.createTempBlob(in, maxLength, handler); - } - return addLob(in, maxLength, Value.BLOB); - } - return ValueLob.createBlob(in, maxLength, handler); - } - - /** - * Create a CLOB object. - * - * @param reader the reader - * @param maxLength the maximum length (-1 if not known) - * @return the LOB - */ - public Value createClob(Reader reader, long maxLength) { - if (SysProperties.LOB_IN_DATABASE) { - init(); - if (conn == null) { - return ValueLobDb.createTempClob(reader, maxLength, handler); - } - long max = maxLength == -1 ? Long.MAX_VALUE : maxLength; - CountingReaderInputStream in = new CountingReaderInputStream(reader, max); - ValueLobDb lob = addLob(in, Long.MAX_VALUE, Value.CLOB); - lob.setPrecision(in.getLength()); - return lob; - } - return ValueLob.createClob(reader, maxLength, handler); - } - - /** - * Set the table reference of this lob. - * - * @param lobId the lob - * @param table the table - */ - public void setTable(long lobId, int table) { - try { - PreparedStatement prep = prepare("UPDATE " + LOBS + " SET TABLE = ? WHERE ID = ?"); - prep.setInt(1, table); - prep.setLong(2, lobId); - int updateCount = prep.executeUpdate(); - if (updateCount != 1) { - // can be zero when recovering - // throw DbException.throwInternalError("count: " + updateCount); - } - } catch (SQLException e) { - throw DbException.convert(e); - } - } - -} diff --git a/tools/h2/src/main/org/h2/store/Page.java b/tools/h2/src/main/org/h2/store/Page.java deleted file mode 100755 index 77e6d2a..0000000 --- a/tools/h2/src/main/org/h2/store/Page.java +++ /dev/null @@ -1,91 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.store; - -import org.h2.engine.Session; -import org.h2.util.CacheObject; - - -/** - * A page. Format: - *

  • 0-3: parent page id (0 for root) - *
  • 4-4: page type - *
  • page-type specific data - *
- */ -public abstract class Page extends CacheObject { - - /** - * This is the last page of a chain. - */ - public static final int FLAG_LAST = 16; - - /** - * An empty page. - */ - public static final int TYPE_EMPTY = 0; - - /** - * A data leaf page (without overflow: + FLAG_LAST). - */ - public static final int TYPE_DATA_LEAF = 1; - - /** - * A data node page (never has overflow pages). - */ - public static final int TYPE_DATA_NODE = 2; - - /** - * A data overflow page (the last page: + FLAG_LAST). - */ - public static final int TYPE_DATA_OVERFLOW = 3; - - /** - * A b-tree leaf page (without overflow: + FLAG_LAST). - */ - public static final int TYPE_BTREE_LEAF = 4; - - /** - * A b-tree node page (never has overflow pages). - */ - public static final int TYPE_BTREE_NODE = 5; - - /** - * A page containing a list of free pages (the last page: + FLAG_LAST). - */ - public static final int TYPE_FREE_LIST = 6; - - /** - * A stream trunk page. - */ - public static final int TYPE_STREAM_TRUNK = 7; - - /** - * A stream data page. - */ - public static final int TYPE_STREAM_DATA = 8; - - /** - * When this page was changed the last time. - */ - protected int changeCount; - - /** - * Copy the data to a new location, change the parent to point to the new - * location, and free up the current page. - * - * @param session the session - * @param newPos the new position - */ - public abstract void moveTo(Session session, int newPos); - - /** - * Write the page. - */ - public abstract void write(); - -} diff --git a/tools/h2/src/main/org/h2/store/PageFreeList.java b/tools/h2/src/main/org/h2/store/PageFreeList.java deleted file mode 100755 index 88d6af4..0000000 --- a/tools/h2/src/main/org/h2/store/PageFreeList.java +++ /dev/null @@ -1,225 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, Version - * 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). Initial Developer: H2 Group - */ -package org.h2.store; - -import java.util.BitSet; -import org.h2.engine.Session; - -/** - * The list of free pages of a page store. The format of a free list trunk page - * is: - *
    - *
  • page type: byte (0)
  • - *
  • checksum: short (1-2)
  • - *
  • data (3-)
  • - *
- */ -public class PageFreeList extends Page { - - private static final int DATA_START = 3; - - private final PageStore store; - private final BitSet used = new BitSet(); - private final int pageCount; - private boolean full; - private Data data; - - private PageFreeList(PageStore store, int pageId) { - setPos(pageId); - this.store = store; - pageCount = (store.getPageSize() - DATA_START) * 8; - used.set(0); - } - - /** - * Read a free-list page. - * - * @param store the page store - * @param data the data - * @param pageId the page id - * @return the page - */ - static PageFreeList read(PageStore store, Data data, int pageId) { - PageFreeList p = new PageFreeList(store, pageId); - p.data = data; - p.read(); - return p; - } - - /** - * Create a new free-list page. - * - * @param store the page store - * @param pageId the page id - * @return the page - */ - static PageFreeList create(PageStore store, int pageId) { - return new PageFreeList(store, pageId); - } - - /** - * Allocate a page from the free list. - * - * @param exclude the exclude list or null - * @param first the first page to look for - * @return the page, or -1 if all pages are used - */ - int allocate(BitSet exclude, int first) { - if (full) { - return -1; - } - // TODO cache last result - int start = Math.max(0, first - getPos()); - while (true) { - int free = used.nextClearBit(start); - if (free >= pageCount) { - if (start == 0) { - full = true; - } - return -1; - } - if (exclude != null && exclude.get(free + getPos())) { - start = exclude.nextClearBit(free + getPos()) - getPos(); - if (start >= pageCount) { - return -1; - } - } else { - // set the bit first, because logUndo can - // allocate other pages, and we must not - // return the same page twice - used.set(free); - store.logUndo(this, data); - store.update(this); - return free + getPos(); - } - } - } - - int getFirstFree() { - if (full) { - return -1; - } - int free = used.nextClearBit(0); - if (free >= pageCount) { - return -1; - } - return free + getPos(); - } - - int getLastUsed() { - int last = used.length() - 1; - return last <= 0 ? -1 : last + getPos(); - } - - /** - * Mark a page as used. - * - * @param pageId the page id - * @return the page id, or -1 - */ - int allocate(int pageId) { - int idx = pageId - getPos(); - if (idx >= 0 && !used.get(idx)) { - // set the bit first, because logUndo can - // allocate other pages, and we must not - // return the same page twice - used.set(idx); - store.logUndo(this, data); - store.update(this); - } - return pageId; - } - - /** - * Add a page to the free list. - * - * @param pageId the page id to add - */ - void free(int pageId) { - full = false; - store.logUndo(this, data); - used.clear(pageId - getPos()); - store.update(this); - } - - /** - * Read the page from the disk. - */ - private void read() { - data.reset(); - data.readByte(); - data.readShortInt(); - for (int i = 0; i < pageCount; i += 8) { - int x = data.readByte() & 255; - for (int j = 0; j < 8; j++) { - if ((x & (1 << j)) != 0) { - used.set(i + j); - } - } - } - full = false; - } - - public void write() { - data = store.createData(); - data.writeByte((byte) Page.TYPE_FREE_LIST); - data.writeShortInt(0); - for (int i = 0; i < pageCount; i += 8) { - int x = 0; - for (int j = 0; j < 8; j++) { - if (used.get(i + j)) { - x += 1 << j; - } - } - data.writeByte((byte) x); - } - store.writePage(getPos(), data); - } - - /** - * Get the number of pages that can fit in a free list. - * - * @param pageSize the page size - * @return the number of pages - */ - public static int getPagesAddressed(int pageSize) { - return (pageSize - DATA_START) * 8; - } - - /** - * Get the estimated memory size. - * - * @return number of double words (4 bytes) - */ - public int getMemorySize() { - return store.getPageSize() >> 2; - } - - /** - * Check if a page is already in use. - * - * @param pageId the page to check - * @return true if it is in use - */ - boolean isUsed(int pageId) { - return used.get(pageId - getPos()); - } - - public void moveTo(Session session, int newPos) { - // the old data does not need to be copied, as free-list pages - // at the end of the file are not required - store.free(getPos(), false); - } - - public String toString() { - return "page [" + getPos() + "] freeList" + (full ? "full" : ""); - } - - public boolean canRemove() { - return false; - } - -} diff --git a/tools/h2/src/main/org/h2/store/PageInputStream.java b/tools/h2/src/main/org/h2/store/PageInputStream.java deleted file mode 100755 index 6081c00..0000000 --- a/tools/h2/src/main/org/h2/store/PageInputStream.java +++ /dev/null @@ -1,167 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.store; - -import java.io.EOFException; -import java.io.IOException; -import java.io.InputStream; -import java.util.BitSet; -import org.h2.message.DbException; -import org.h2.message.Trace; - -/** - * An input stream that reads from a page store. - */ -public class PageInputStream extends InputStream { - - private PageStore store; - private final Trace trace; - private int firstTrunkPage; - private PageStreamTrunk.Iterator trunkIterator; - private int dataPage; - private PageStreamTrunk trunk; - private int trunkIndex; - private PageStreamData data; - private int dataPos; - private boolean endOfFile; - private int remaining; - private byte[] buffer = { 0 }; - private int logKey; - - PageInputStream(PageStore store, int logKey, int firstTrunkPage, int dataPage) { - this.store = store; - this.trace = store.getTrace(); - // minus one because we increment before comparing - this.logKey = logKey - 1; - this.firstTrunkPage = firstTrunkPage; - trunkIterator = new PageStreamTrunk.Iterator(store, firstTrunkPage); - this.dataPage = dataPage; - } - - public int read() throws IOException { - int len = read(buffer); - return len < 0 ? -1 : (buffer[0] & 255); - } - - public int read(byte[] b) throws IOException { - return read(b, 0, b.length); - } - - public int read(byte[] b, int off, int len) throws IOException { - if (len == 0) { - return 0; - } - int read = 0; - while (len > 0) { - int r = readBlock(b, off, len); - if (r < 0) { - break; - } - read += r; - off += r; - len -= r; - } - return read == 0 ? -1 : read; - } - - private int readBlock(byte[] buff, int off, int len) throws IOException { - try { - fillBuffer(); - if (endOfFile) { - return -1; - } - int l = Math.min(remaining, len); - data.read(dataPos, buff, off, l); - remaining -= l; - dataPos += l; - return l; - } catch (DbException e) { - throw new EOFException(); - } - } - - private void fillBuffer() { - if (remaining > 0 || endOfFile) { - return; - } - int next; - while (true) { - if (trunk == null) { - trunk = trunkIterator.next(); - trunkIndex = 0; - logKey++; - if (trunk == null || trunk.getLogKey() != logKey) { - endOfFile = true; - return; - } - } - if (trunk != null) { - next = trunk.getPageData(trunkIndex++); - if (next == -1) { - trunk = null; - } else if (dataPage == -1 || dataPage == next) { - break; - } - } - } - if (trace.isDebugEnabled()) { - trace.debug("pageIn.readPage " + next); - } - dataPage = -1; - data = null; - Page p = store.getPage(next); - if (p instanceof PageStreamData) { - data = (PageStreamData) p; - } - if (data == null || data.getLogKey() != logKey) { - endOfFile = true; - return; - } - dataPos = data.getReadStart(); - remaining = store.getPageSize() - dataPos; - } - - /** - * Set all pages as 'allocated' in the page store. - * - * @return the bit set - */ - BitSet allocateAllPages() { - BitSet pages = new BitSet(); - int key = logKey; - PageStreamTrunk.Iterator it = new PageStreamTrunk.Iterator(store, firstTrunkPage); - while (true) { - PageStreamTrunk t = it.next(); - key++; - if (it.canDelete()) { - store.allocatePage(it.getCurrentPageId()); - } - if (t == null || t.getLogKey() != key) { - break; - } - pages.set(t.getPos()); - for (int i = 0;; i++) { - int n = t.getPageData(i); - if (n == -1) { - break; - } - pages.set(n); - store.allocatePage(n); - } - } - return pages; - } - - int getDataPage() { - return data.getPos(); - } - - public void close() { - // nothing to do - } - -} diff --git a/tools/h2/src/main/org/h2/store/PageLog.java b/tools/h2/src/main/org/h2/store/PageLog.java deleted file mode 100755 index 8f3e696..0000000 --- a/tools/h2/src/main/org/h2/store/PageLog.java +++ /dev/null @@ -1,822 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.store; - -import java.io.IOException; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.BitSet; -import java.util.HashMap; -import org.h2.compress.CompressLZF; -import org.h2.constant.ErrorCode; -import org.h2.constant.SysProperties; -import org.h2.engine.Session; -import org.h2.message.DbException; -import org.h2.message.Trace; -import org.h2.result.Row; -import org.h2.util.IntArray; -import org.h2.util.IntIntHashMap; -import org.h2.util.New; -import org.h2.value.Value; -import org.h2.value.ValueNull; - -/** - * Transaction log mechanism. The stream contains a list of records. The data - * format for a record is: - *
    - *
  • type (0: no-op, 1: undo, 2: commit, ...)
  • - *
  • data
  • - *
- * The transaction log is split into sections. - * A checkpoint starts a new section. - */ -public class PageLog { - - /** - * No operation. - */ - public static final int NOOP = 0; - - /** - * An undo log entry. Format: page id: varInt, size, page. Size 0 means - * uncompressed, size 1 means empty page, otherwise the size is the number - * of compressed bytes. - */ - public static final int UNDO = 1; - - /** - * A commit entry of a session. - * Format: session id: varInt. - */ - public static final int COMMIT = 2; - - /** - * A prepare commit entry for a session. - * Format: session id: varInt, transaction name: string. - */ - public static final int PREPARE_COMMIT = 3; - - /** - * Roll back a prepared transaction. - * Format: session id: varInt. - */ - public static final int ROLLBACK = 4; - - /** - * Add a record to a table. - * Format: session id: varInt, table id: varInt, row. - */ - public static final int ADD = 5; - - /** - * Remove a record from a table. - * Format: session id: varInt, table id: varInt, row. - */ - public static final int REMOVE = 6; - - /** - * Truncate a table. - * Format: session id: varInt, table id: varInt. - */ - public static final int TRUNCATE = 7; - - /** - * Perform a checkpoint. The log section id is incremented. - * Format: - - */ - public static final int CHECKPOINT = 8; - - /** - * Free a log page. - * Format: count: varInt, page ids: varInt - */ - public static final int FREE_LOG = 9; - - /** - * The recovery stage to undo changes (re-apply the backup). - */ - static final int RECOVERY_STAGE_UNDO = 0; - - /** - * The recovery stage to allocate pages used by the transaction log. - */ - static final int RECOVERY_STAGE_ALLOCATE = 1; - - /** - * The recovery stage to redo operations. - */ - static final int RECOVERY_STAGE_REDO = 2; - - private static final boolean COMPRESS_UNDO = true; - - private final PageStore store; - private Trace trace; - - private Data writeBuffer; - private PageInputStream pageIn; - private PageOutputStream pageOut; - private int firstTrunkPage; - private int firstDataPage; - private Data dataBuffer; - private int logKey; - private int logSectionId, logPos; - private int firstSectionId; - - private CompressLZF compress; - private byte[] compressBuffer; - - /** - * If the bit is set, the given page was written to the current log section. - * The undo entry of these pages doesn't need to be written again. - */ - private BitSet undo = new BitSet(); - - /** - * The undo entry of those pages was written in any log section. - * These pages may not be used in the transaction log. - */ - private BitSet undoAll = new BitSet(); - - /** - * The map of section ids (key) and data page where the section starts (value). - */ - private IntIntHashMap logSectionPageMap = new IntIntHashMap(); - - /** - * The session state map. - * Only used during recovery. - */ - private HashMap sessionStates = New.hashMap(); - - /** - * The map of pages used by the transaction log. - * Only used during recovery. - */ - private BitSet usedLogPages; - - PageLog(PageStore store) { - this.store = store; - dataBuffer = store.createData(); - trace = store.getTrace(); - compress = new CompressLZF(); - compressBuffer = new byte[store.getPageSize() * 2]; - } - - /** - * Open the log for writing. For an existing database, the recovery - * must be run first. - * - * @param newFirstTrunkPage the first trunk page - * @param atEnd whether only pages at the end of the file should be used - */ - void openForWriting(int newFirstTrunkPage, boolean atEnd) { - trace.debug("log openForWriting firstPage:" + newFirstTrunkPage); - this.firstTrunkPage = newFirstTrunkPage; - logKey++; - pageOut = new PageOutputStream(store, newFirstTrunkPage, undoAll, logKey, atEnd); - pageOut.reserve(1); - // pageBuffer = new BufferedOutputStream(pageOut, 8 * 1024); - store.setLogFirstPage(logKey, newFirstTrunkPage, pageOut.getCurrentDataPageId()); - writeBuffer = store.createData(); - } - - /** - * Free up all pages allocated by the log. - */ - void free() { - if (pageOut != null) { - pageOut.freeReserved(); - } - PageStreamTrunk.Iterator it = new PageStreamTrunk.Iterator(store, firstTrunkPage); - while (firstTrunkPage != 0 && firstTrunkPage < store.getPageCount()) { - PageStreamTrunk t = it.next(); - if (t == null) { - if (it.canDelete()) { - store.free(firstTrunkPage, false); - } - break; - } - t.free(); - firstTrunkPage = t.getNextTrunk(); - } - } - - /** - * Open the log for reading. - * - * @param newLogKey the first expected log key - * @param newFirstTrunkPage the first trunk page - * @param newFirstDataPage the index of the first data page - */ - void openForReading(int newLogKey, int newFirstTrunkPage, int newFirstDataPage) { - this.logKey = newLogKey; - this.firstTrunkPage = newFirstTrunkPage; - this.firstDataPage = newFirstDataPage; - } - - /** - * Run one recovery stage. There are three recovery stages: 0: only the undo - * steps are run (restoring the state before the last checkpoint). 1: the - * pages that are used by the transaction log are allocated. 2: the - * committed operations are re-applied. - * - * @param stage the recovery stage - */ - void recover(int stage) { - if (trace.isDebugEnabled()) { - trace.debug("log recover stage:" + stage); - } - if (stage == RECOVERY_STAGE_ALLOCATE) { - PageInputStream in = new PageInputStream(store, logKey, firstTrunkPage, firstDataPage); - usedLogPages = in.allocateAllPages(); - in.close(); - return; - } - pageIn = new PageInputStream(store, logKey, firstTrunkPage, firstDataPage); - DataReader in = new DataReader(pageIn); - int logId = 0; - Data data = store.createData(); - try { - int pos = 0; - while (true) { - int x = in.read(); - if (x < 0) { - break; - } - pos++; - if (x == UNDO) { - int pageId = in.readVarInt(); - int size = in.readVarInt(); - if (size == 0) { - in.readFully(data.getBytes(), 0, store.getPageSize()); - } else if (size == 1) { - // empty - Arrays.fill(data.getBytes(), 0, store.getPageSize(), (byte) 0); - } else { - in.readFully(compressBuffer, 0, size); - compress.expand(compressBuffer, 0, size, data.getBytes(), 0, store.getPageSize()); - } - if (stage == RECOVERY_STAGE_UNDO) { - if (!undo.get(pageId)) { - if (trace.isDebugEnabled()) { - trace.debug("log undo " + pageId); - } - store.writePage(pageId, data); - undo.set(pageId); - undoAll.set(pageId); - } else { - if (trace.isDebugEnabled()) { - trace.debug("log undo skip " + pageId); - } - } - } - } else if (x == ADD) { - int sessionId = in.readVarInt(); - int tableId = in.readVarInt(); - Row row = readRow(in, data); - if (stage == RECOVERY_STAGE_UNDO) { - store.allocateIfIndexRoot(pos, tableId, row); - } else if (stage == RECOVERY_STAGE_REDO) { - if (isSessionCommitted(sessionId, logId, pos)) { - if (trace.isDebugEnabled()) { - trace.debug("log redo + table:" + tableId + " s:" + sessionId + " " + row); - } - store.redo(pos, tableId, row, true); - } else { - if (trace.isDebugEnabled()) { - trace.debug("log ignore s:" + sessionId + " + table:" + tableId + " " + row); - } - } - } - } else if (x == REMOVE) { - int sessionId = in.readVarInt(); - int tableId = in.readVarInt(); - long key = in.readVarLong(); - if (stage == RECOVERY_STAGE_REDO) { - if (isSessionCommitted(sessionId, logId, pos)) { - if (trace.isDebugEnabled()) { - trace.debug("log redo - table:" + tableId + " key:" + key); - } - store.redoDelete(pos, tableId, key); - } else { - if (trace.isDebugEnabled()) { - trace.debug("log ignore s:" + sessionId + " - table:" + tableId + " key:" + key); - } - } - } - } else if (x == TRUNCATE) { - int sessionId = in.readVarInt(); - int tableId = in.readVarInt(); - if (stage == RECOVERY_STAGE_REDO) { - if (isSessionCommitted(sessionId, logId, pos)) { - if (trace.isDebugEnabled()) { - trace.debug("log redo truncate table:" + tableId); - } - store.redoTruncate(tableId); - } else { - if (trace.isDebugEnabled()) { - trace.debug("log ignore s:" + sessionId + " truncate table:" + tableId); - } - } - } - } else if (x == PREPARE_COMMIT) { - int sessionId = in.readVarInt(); - String transaction = in.readString(); - if (trace.isDebugEnabled()) { - trace.debug("log prepare commit " + sessionId + " " + transaction + " pos:" + pos); - } - if (stage == RECOVERY_STAGE_UNDO) { - int page = pageIn.getDataPage(); - setPrepareCommit(sessionId, page, transaction); - } - } else if (x == ROLLBACK) { - int sessionId = in.readVarInt(); - if (trace.isDebugEnabled()) { - trace.debug("log rollback " + sessionId + " pos:" + pos); - } - // ignore - this entry is just informational - } else if (x == COMMIT) { - int sessionId = in.readVarInt(); - if (trace.isDebugEnabled()) { - trace.debug("log commit " + sessionId + " pos:" + pos); - } - if (stage == RECOVERY_STAGE_UNDO) { - setLastCommitForSession(sessionId, logId, pos); - } - } else if (x == NOOP) { - // nothing to do - } else if (x == CHECKPOINT) { - logId++; - } else if (x == FREE_LOG) { - int count = in.readVarInt(); - for (int i = 0; i < count; i++) { - int pageId = in.readVarInt(); - if (stage == RECOVERY_STAGE_REDO) { - if (!usedLogPages.get(pageId)) { - store.free(pageId, false); - } - } - } - } else { - if (trace.isDebugEnabled()) { - trace.debug("log end"); - break; - } - } - } - } catch (DbException e) { - if (e.getErrorCode() == ErrorCode.FILE_CORRUPTED_1) { - trace.debug("log recovery stopped: " + e.toString()); - } else { - throw e; - } - } catch (IOException e) { - trace.debug("log recovery stopped: " + e.toString()); - } - undo = new BitSet(); - if (stage == RECOVERY_STAGE_REDO) { - usedLogPages = null; - } - } - - /** - * This method is called when a 'prepare commit' log entry is read when - * opening the database. - * - * @param sessionId the session id - * @param the data page with the prepare entry - * @param transaction the transaction name, or null to rollback - */ - private void setPrepareCommit(int sessionId, int pageId, String transaction) { - SessionState state = getOrAddSessionState(sessionId); - InDoubtTransaction doubt; - if (transaction == null) { - doubt = null; - } else { - doubt = new InDoubtTransaction(store, sessionId, pageId, transaction); - } - state.inDoubtTransaction = doubt; - } - - /** - * Read a row from an input stream. - * - * @param in the input stream - * @param data a temporary buffer - * @return the row - */ - public static Row readRow(DataReader in, Data data) throws IOException { - long key = in.readVarLong(); - int len = in.readVarInt(); - data.reset(); - data.checkCapacity(len); - in.readFully(data.getBytes(), 0, len); - int columnCount = data.readVarInt(); - Value[] values = new Value[columnCount]; - for (int i = 0; i < columnCount; i++) { - values[i] = data.readValue(); - } - Row row = new Row(values, Row.MEMORY_CALCULATE); - row.setKey(key); - return row; - } - - /** - * Check if the undo entry was already written for the given page. - * - * @param pageId the page - * @return true if it was written - */ - boolean getUndo(int pageId) { - return undo.get(pageId); - } - - /** - * Add an undo entry to the log. The page data is only written once until - * the next checkpoint. - * - * @param pageId the page id - * @param page the old page data - */ - void addUndo(int pageId, Data page) { - if (undo.get(pageId)) { - return; - } - if (trace.isDebugEnabled()) { - trace.debug("log undo " + pageId); - } - if (SysProperties.CHECK && page == null) { - DbException.throwInternalError("Undo entry not written"); - } - undo.set(pageId); - undoAll.set(pageId); - Data buffer = getBuffer(); - buffer.writeByte((byte) UNDO); - buffer.writeVarInt(pageId); - if (page.getBytes()[0] == 0) { - buffer.writeVarInt(1); - } else { - int pageSize = store.getPageSize(); - if (COMPRESS_UNDO) { - int size = compress.compress(page.getBytes(), pageSize, compressBuffer, 0); - if (size < pageSize) { - buffer.writeVarInt(size); - buffer.checkCapacity(size); - buffer.write(compressBuffer, 0, size); - } else { - buffer.writeVarInt(0); - buffer.checkCapacity(pageSize); - buffer.write(page.getBytes(), 0, pageSize); - } - } else { - buffer.writeVarInt(0); - buffer.checkCapacity(pageSize); - buffer.write(page.getBytes(), 0, pageSize); - } - } - write(buffer); - } - - private void freeLogPages(IntArray pages) { - if (trace.isDebugEnabled()) { - trace.debug("log frees " + pages.get(0) + ".." + pages.get(pages.size() - 1)); - } - Data buffer = getBuffer(); - buffer.writeByte((byte) FREE_LOG); - buffer.writeVarInt(pages.size()); - for (int i = 0; i < pages.size(); i++) { - buffer.writeVarInt(pages.get(i)); - } - write(buffer); - } - - private void write(Data data) { - pageOut.write(data.getBytes(), 0, data.length()); - data.reset(); - } - - /** - * Mark a transaction as committed. - * - * @param session the session - */ - void commit(int sessionId) { - if (trace.isDebugEnabled()) { - trace.debug("log commit s:" + sessionId); - } - if (store.getDatabase().getPageStore() == null) { - // database already closed - return; - } - Data buffer = getBuffer(); - buffer.writeByte((byte) COMMIT); - buffer.writeVarInt(sessionId); - write(buffer); - if (store.getDatabase().getFlushOnEachCommit()) { - flush(); - } - } - - /** - * Prepare a transaction. - * - * @param session the session - * @param transaction the name of the transaction - */ - void prepareCommit(Session session, String transaction) { - if (trace.isDebugEnabled()) { - trace.debug("log prepare commit s:" + session.getId() + " " + transaction); - } - if (store.getDatabase().getPageStore() == null) { - // database already closed - return; - } - // store it on a separate log page - int pageSize = store.getPageSize(); - pageOut.flush(); - pageOut.fillPage(); - Data buffer = getBuffer(); - buffer.writeByte((byte) PREPARE_COMMIT); - buffer.writeVarInt(session.getId()); - buffer.writeString(transaction); - if (buffer.length() >= PageStreamData.getCapacity(pageSize)) { - throw DbException.getInvalidValueException(transaction, "transaction name (too long)"); - } - write(buffer); - // store it on a separate log page - flushOut(); - pageOut.fillPage(); - if (store.getDatabase().getFlushOnEachCommit()) { - flush(); - } - } - - /** - * A record is added to a table, or removed from a table. - * - * @param session the session - * @param tableId the table id - * @param row the row to add - * @param add true if the row is added, false if it is removed - */ - void logAddOrRemoveRow(Session session, int tableId, Row row, boolean add) { - if (trace.isDebugEnabled()) { - trace.debug("log " + (add?"+":"-") + " s:" + session.getId() + " table:" + tableId + - " row:" + row); - } - session.addLogPos(logSectionId, logPos); - logPos++; - Data data = dataBuffer; - data.reset(); - int columns = row.getColumnCount(); - data.writeVarInt(columns); - data.checkCapacity(row.getByteCount(data)); - if (session.isRedoLogBinaryEnabled()) { - for (int i = 0; i < columns; i++) { - data.writeValue(row.getValue(i)); - } - } else { - for (int i = 0; i < columns; i++) { - Value v = row.getValue(i); - if (v.getType() == Value.BYTES) { - data.writeValue(ValueNull.INSTANCE); - } else { - data.writeValue(v); - } - } - } - Data buffer = getBuffer(); - buffer.writeByte((byte) (add ? ADD : REMOVE)); - buffer.writeVarInt(session.getId()); - buffer.writeVarInt(tableId); - buffer.writeVarLong(row.getKey()); - if (add) { - buffer.writeVarInt(data.length()); - buffer.checkCapacity(data.length()); - buffer.write(data.getBytes(), 0, data.length()); - } - write(buffer); - } - - /** - * A table is truncated. - * - * @param session the session - * @param tableId the table id - */ - void logTruncate(Session session, int tableId) { - if (trace.isDebugEnabled()) { - trace.debug("log truncate s:" + session.getId() + " table:" + tableId); - } - session.addLogPos(logSectionId, logPos); - logPos++; - Data buffer = getBuffer(); - buffer.writeByte((byte) TRUNCATE); - buffer.writeVarInt(session.getId()); - buffer.writeVarInt(tableId); - write(buffer); - } - - /** - * Flush the transaction log. - */ - void flush() { - if (pageOut != null) { - flushOut(); - } - } - - /** - * Switch to a new log section. - */ - void checkpoint() { - Data buffer = getBuffer(); - buffer.writeByte((byte) CHECKPOINT); - write(buffer); - undo = new BitSet(); - logSectionId++; - logPos = 0; - pageOut.flush(); - pageOut.fillPage(); - int currentDataPage = pageOut.getCurrentDataPageId(); - logSectionPageMap.put(logSectionId, currentDataPage); - } - - int getLogSectionId() { - return logSectionId; - } - - long getLogPos() { - return logPos; - } - - /** - * Remove all pages until the given log (excluding). - * - * @param firstUncommittedSection the first log section to keep - */ - void removeUntil(int firstUncommittedSection) { - if (firstUncommittedSection == 0) { - return; - } - int firstDataPageToKeep = logSectionPageMap.get(firstUncommittedSection); - firstTrunkPage = removeUntil(firstTrunkPage, firstDataPageToKeep); - store.setLogFirstPage(logKey, firstTrunkPage, firstDataPageToKeep); - while (firstSectionId < firstUncommittedSection) { - if (firstSectionId > 0) { - // there is no entry for log 0 - logSectionPageMap.remove(firstSectionId); - } - firstSectionId++; - } - } - - /** - * Remove all pages until the given data page. - * - * @param trunkPage the first trunk page - * @param firstDataPageToKeep the first data page to keep - * @return the trunk page of the data page to keep - */ - private int removeUntil(int trunkPage, int firstDataPageToKeep) { - trace.debug("log.removeUntil " + trunkPage + " " + firstDataPageToKeep); - while (true) { - Page p = store.getPage(trunkPage); - PageStreamTrunk t = (PageStreamTrunk) p; - logKey = t.getLogKey(); - if (t.contains(firstDataPageToKeep)) { - return t.getPos(); - } - trunkPage = t.getNextTrunk(); - IntArray list = new IntArray(); - list.add(t.getPos()); - for (int i = 0;; i++) { - int next = t.getPageData(i); - if (next == -1) { - break; - } - list.add(next); - } - freeLogPages(list); - pageOut.free(t); - } - } - - /** - * Close without further writing. - */ - void close() { - trace.debug("log close"); - if (pageOut != null) { - pageOut.close(); - pageOut = null; - } - writeBuffer = null; - } - - /** - * Check if the session committed after than the given position. - * - * @param sessionId the session id - * @param logId the log id - * @param pos the position in the log - * @return true if it is committed - */ - private boolean isSessionCommitted(int sessionId, int logId, int pos) { - SessionState state = sessionStates.get(sessionId); - if (state == null) { - return false; - } - return state.isCommitted(logId, pos); - } - - /** - * Set the last commit record for a session. - * - * @param sessionId the session id - * @param logId the log id - * @param pos the position in the log - */ - private void setLastCommitForSession(int sessionId, int logId, int pos) { - SessionState state = getOrAddSessionState(sessionId); - state.lastCommitLog = logId; - state.lastCommitPos = pos; - state.inDoubtTransaction = null; - } - - /** - * Get the session state for this session. A new object is created if there - * is no session state yet. - * - * @param sessionId the session id - * @return the session state object - */ - private SessionState getOrAddSessionState(int sessionId) { - Integer key = sessionId; - SessionState state = sessionStates.get(key); - if (state == null) { - state = new SessionState(); - sessionStates.put(key, state); - state.sessionId = sessionId; - } - return state; - } - - long getSize() { - return pageOut == null ? 0 : pageOut.getSize(); - } - - ArrayList getInDoubtTransactions() { - ArrayList list = New.arrayList(); - for (SessionState state : sessionStates.values()) { - InDoubtTransaction in = state.inDoubtTransaction; - if (in != null) { - list.add(in); - } - } - return list; - } - - /** - * Set the state of an in-doubt transaction. - * - * @param sessionId the session - * @param pageId the page where the commit was prepared - * @param commit whether the transaction should be committed - */ - void setInDoubtTransactionState(int sessionId, int pageId, boolean commit) { - PageStreamData d = (PageStreamData) store.getPage(pageId); - d.initWrite(); - Data buff = store.createData(); - buff.writeByte((byte) (commit ? COMMIT : ROLLBACK)); - buff.writeVarInt(sessionId); - byte[] bytes = buff.getBytes(); - d.write(bytes, 0, bytes.length); - bytes = new byte[d.getRemaining()]; - d.write(bytes, 0, bytes.length); - d.write(); - } - - /** - * Called after the recovery has been completed. - */ - void recoverEnd() { - sessionStates = New.hashMap(); - } - - private void flushOut() { - pageOut.flush(); - } - - private Data getBuffer() { - if (writeBuffer.length() == 0) { - return writeBuffer; - } - return store.createData(); - } - -} diff --git a/tools/h2/src/main/org/h2/store/PageOutputStream.java b/tools/h2/src/main/org/h2/store/PageOutputStream.java deleted file mode 100755 index ac2a453..0000000 --- a/tools/h2/src/main/org/h2/store/PageOutputStream.java +++ /dev/null @@ -1,212 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.store; - -import java.util.BitSet; -import org.h2.message.DbException; -import org.h2.message.Trace; -import org.h2.util.IntArray; - -/** - * An output stream that writes into a page store. - */ -public class PageOutputStream { - - private PageStore store; - private final Trace trace; - private int trunkPageId; - private final BitSet exclude; - - private int trunkNext; - private IntArray reservedPages = new IntArray(); - private PageStreamTrunk trunk; - private int trunkIndex; - private PageStreamData data; - private int reserved; - private int remaining; - private boolean needFlush; - private boolean writing; - private int pageCount; - private boolean atEnd; - private int logKey; - - /** - * Create a new page output stream. - * - * @param store the page store - * @param trunkPage the first trunk page (already allocated) - * @param exclude the pages not to use - * @param logKey the log key of the first trunk page - * @param atEnd whether only pages at the end of the file should be used - */ - public PageOutputStream(PageStore store, int trunkPage, BitSet exclude, int logKey, boolean atEnd) { - this.trace = store.getTrace(); - this.store = store; - this.trunkPageId = trunkPage; - this.exclude = exclude; - // minus one, because we increment before creating a trunk page - this.logKey = logKey - 1; - this.atEnd = atEnd; - } - - /** - * Allocate the required pages so that no pages need to be allocated while - * writing. - * - * @param minBuffer the number of bytes to allocate - */ - void reserve(int minBuffer) { - if (reserved < minBuffer) { - int pageSize = store.getPageSize(); - int capacityPerPage = PageStreamData.getCapacity(pageSize); - int pages = PageStreamTrunk.getPagesAddressed(pageSize); - int pagesToAllocate = 0, totalCapacity = 0; - do { - // allocate x data pages plus one trunk page - pagesToAllocate += pages + 1; - totalCapacity += pages * capacityPerPage; - } while (totalCapacity < minBuffer); - int firstPageToUse = atEnd ? trunkPageId : 0; - store.allocatePages(reservedPages, pagesToAllocate, exclude, firstPageToUse); - reserved += totalCapacity; - if (data == null) { - initNextData(); - } - } - } - - private void initNextData() { - int nextData = trunk == null ? -1 : trunk.getPageData(trunkIndex++); - if (nextData == -1) { - int parent = trunkPageId; - if (trunkNext != 0) { - trunkPageId = trunkNext; - } - int len = PageStreamTrunk.getPagesAddressed(store.getPageSize()); - int[] pageIds = new int[len]; - for (int i = 0; i < len; i++) { - pageIds[i] = reservedPages.get(i); - } - trunkNext = reservedPages.get(len); - logKey++; - trunk = PageStreamTrunk.create(store, parent, trunkPageId, trunkNext, logKey, pageIds); - trunkIndex = 0; - pageCount++; - trunk.write(); - reservedPages.removeRange(0, len + 1); - nextData = trunk.getPageData(trunkIndex++); - } - data = PageStreamData.create(store, nextData, trunk.getPos(), logKey); - pageCount++; - data.initWrite(); - } - - /** - * Write the data. - * - * @param b the buffer - * @param off the offset - * @param len the length - */ - public void write(byte[] b, int off, int len) { - if (len <= 0) { - return; - } - if (writing) { - DbException.throwInternalError("writing while still writing"); - } - try { - reserve(len); - writing = true; - while (len > 0) { - int l = data.write(b, off, len); - if (l < len) { - storePage(); - initNextData(); - } - reserved -= l; - off += l; - len -= l; - } - needFlush = true; - remaining -= len; - } finally { - writing = false; - } - } - - private void storePage() { - if (trace.isDebugEnabled()) { - trace.debug("pageOut.storePage " + data); - } - data.write(); - } - - /** - * Write all data. - */ - public void flush() { - if (needFlush) { - storePage(); - needFlush = false; - } - } - - /** - * Close the stream. - */ - public void close() { - store = null; - } - - int getCurrentDataPageId() { - return data.getPos(); - } - - /** - * Fill the data page with zeros and write it. - * This is required for a checkpoint. - */ - void fillPage() { - if (trace.isDebugEnabled()) { - trace.debug("pageOut.storePage fill " + data.getPos()); - } - reserve(data.getRemaining() + 1); - reserved -= data.getRemaining(); - data.write(); - initNextData(); - } - - long getSize() { - return pageCount * store.getPageSize(); - } - - /** - * Remove a trunk page from the stream. - * - * @param t the trunk page - */ - void free(PageStreamTrunk t) { - pageCount -= t.free(); - } - - /** - * Free up all reserved pages. - */ - void freeReserved() { - if (reservedPages.size() > 0) { - int[] array = new int[reservedPages.size()]; - reservedPages.toArray(array); - reservedPages = new IntArray(); - reserved = 0; - for (int p : array) { - store.free(p); - } - } - } - -} diff --git a/tools/h2/src/main/org/h2/store/PageStore.java b/tools/h2/src/main/org/h2/store/PageStore.java deleted file mode 100755 index 5d7f5ca..0000000 --- a/tools/h2/src/main/org/h2/store/PageStore.java +++ /dev/null @@ -1,1655 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.store; - -import java.io.IOException; -import java.io.OutputStream; -import java.util.ArrayList; -import java.util.BitSet; -import java.util.Collections; -import java.util.HashMap; -import java.util.zip.CRC32; -import org.h2.command.ddl.CreateTableData; -import org.h2.constant.ErrorCode; -import org.h2.constant.SysProperties; -import org.h2.engine.Constants; -import org.h2.engine.Database; -import org.h2.engine.Session; -import org.h2.index.Cursor; -import org.h2.index.Index; -import org.h2.index.IndexType; -import org.h2.index.MultiVersionIndex; -import org.h2.index.PageBtreeIndex; -import org.h2.index.PageBtreeLeaf; -import org.h2.index.PageBtreeNode; -import org.h2.index.PageDataIndex; -import org.h2.index.PageDataLeaf; -import org.h2.index.PageDataNode; -import org.h2.index.PageDataOverflow; -import org.h2.index.PageDelegateIndex; -import org.h2.index.PageIndex; -import org.h2.message.DbException; -import org.h2.message.Trace; -import org.h2.result.Row; -import org.h2.result.SearchRow; -import org.h2.schema.Schema; -import org.h2.table.Column; -import org.h2.table.IndexColumn; -import org.h2.table.RegularTable; -import org.h2.table.Table; -import org.h2.util.Cache; -import org.h2.util.CacheLRU; -import org.h2.util.CacheObject; -import org.h2.util.CacheWriter; -import org.h2.util.IOUtils; -import org.h2.util.IntArray; -import org.h2.util.IntIntHashMap; -import org.h2.util.New; -import org.h2.util.StatementBuilder; -import org.h2.util.StringUtils; -import org.h2.value.CompareMode; -import org.h2.value.Value; -import org.h2.value.ValueInt; -import org.h2.value.ValueString; - -/** - * This class represents a file that is organized as a number of pages. Page 0 - * contains a static file header, and pages 1 and 2 both contain the variable - * file header (page 2 is a copy of page 1 and is only read if the checksum of - * page 1 is invalid). The format of page 0 is: - *
    - *
  • 0-47: file header (3 time "-- H2 0.5/B -- \n")
  • - *
  • 48-51: page size in bytes (512 - 32768, must be a power of 2)
  • - *
  • 52: write version (read-only if larger than 1)
  • - *
  • 53: read version (opening fails if larger than 1)
  • - *
- * The format of page 1 and 2 is: - *
    - *
  • CRC32 of the remaining data: int (0-3)
  • - *
  • write counter (incremented on each write): long (4-11)
  • - *
  • log trunk key: int (12-15)
  • - *
  • log trunk page (0 for none): int (16-19)
  • - *
  • log data page (0 for none): int (20-23)
  • - *
- * Page 3 contains the first free list page. - * Page 4 contains the meta table root page. - */ -public class PageStore implements CacheWriter { - - // TODO test running out of disk space (using a special file system) - // TODO test with recovery being the default method - // TODO test reservedPages does not grow unbound - - // TODO utf-x: test if it's faster - // TODO corrupt pages should be freed once in a while - // TODO node row counts are incorrect (not splitting row counts) - // TODO after opening the database, delay writing until required - // TODO optimization: try to avoid allocating a byte array per page - // TODO optimization: check if calling Data.getValueLen slows things down - // TODO order pages so that searching for a key only seeks forward - // TODO optimization: update: only log the key and changed values - // TODO index creation: use less space (ordered, split at insertion point) - // TODO detect circles in linked lists - // (input stream, free list, extend pages...) - // at runtime and recovery - // synchronized correctly (on the index?) - // TODO remove trace or use isDebugEnabled - // TODO recover tool: support syntax to delete a row with a key - // TODO don't store default values (store a special value) - // TODO split files (1 GB max size) - // TODO add a setting (that can be changed at runtime) to call fsync - // and delay on each commit - // TODO check for file size (exception if not exact size expected) - // TODO online backup using bsdiff - - // TODO when removing DiskFile: - // remove CacheObject.blockCount - // remove Record.getMemorySize - // simplify InDoubtTransaction - // remove parameter in Record.write(DataPage buff) - // remove Record.getByteCount - // remove Database.objectIds - // remove TableData.checkRowCount - // remove Row.setPos - // remove database URL option RECOVER=1 option - // remove old database URL options and documentation - - /** - * The smallest possible page size. - */ - public static final int PAGE_SIZE_MIN = 64; - - /** - * The biggest possible page size. - */ - public static final int PAGE_SIZE_MAX = 32768; - - private static final int PAGE_ID_FREE_LIST_ROOT = 3; - private static final int PAGE_ID_META_ROOT = 4; - - private static final int MIN_PAGE_COUNT = 6; - - private static final int INCREMENT_PAGES = 128; - - private static final int READ_VERSION = 3; - private static final int WRITE_VERSION = 3; - - private static final int META_TYPE_DATA_INDEX = 0; - private static final int META_TYPE_BTREE_INDEX = 1; - private static final int META_TABLE_ID = -1; - - private static final SearchRow[] EMPTY_SEARCH_ROW = { }; - - private Database database; - private final Trace trace; - private String fileName; - private FileStore file; - private String accessMode; - private int pageSize = SysProperties.PAGE_SIZE; - private int pageSizeShift; - private long writeCountBase, writeCount, readCount; - private int logKey, logFirstTrunkPage, logFirstDataPage; - - private Cache cache; - - private int freeListPagesPerList; - - private boolean recoveryRunning; - - /** - * The file size in bytes. - */ - private long fileLength; - - /** - * Number of pages (including free pages). - */ - private int pageCount; - - private PageLog log; - - private Schema metaSchema; - private RegularTable metaTable; - private PageDataIndex metaIndex; - private IntIntHashMap metaRootPageId = new IntIntHashMap(); - private HashMap metaObjects = New.hashMap(); - private HashMap tempObjects; - - /** - * The map of reserved pages, to ensure index head pages - * are not used for regular data during recovery. The key is the page id, - * and the value the latest transaction position where this page is used. - */ - private HashMap reservedPages; - private boolean isNew; - private long maxLogSize = Constants.DEFAULT_MAX_LOG_SIZE; - private Session systemSession; - private BitSet freed = new BitSet(); - - private ArrayList freeLists = New.arrayList(); - - /** - * The change count is something like a "micro-transaction-id". - * It is used to ensure that changed pages are not written to the file - * before the the current operation is not finished. This is only a problem - * when using a very small cache size. The value starts at 1 so that - * pages with change count 0 can be evicted from the cache. - */ - private int changeCount = 1; - - private Data emptyPage; - - private long logSizeBase; - - /** - * Create a new page store object. - * - * @param database the database - * @param fileName the file name - * @param accessMode the access mode - * @param cacheSizeDefault the default cache size - */ - public PageStore(Database database, String fileName, String accessMode, int cacheSizeDefault) { - this.fileName = fileName; - this.accessMode = accessMode; - this.database = database; - trace = database.getTrace(Trace.PAGE_STORE); - // if (!fileName.endsWith("reopen.h2.db")) - // trace.setLevel(TraceSystem.DEBUG); - String cacheType = database.getCacheType(); - this.cache = CacheLRU.getCache(this, cacheType, cacheSizeDefault); - systemSession = new Session(database, null, 0); - } - - /** - * Copy the next page to the output stream. - * - * @param pageId the page to copy - * @param out the output stream - * @return the new position, or -1 if there is no more data to copy - */ - public int copyDirect(int pageId, OutputStream out) throws IOException { - synchronized (database) { - byte[] buffer = new byte[pageSize]; - if (pageId >= pageCount) { - return -1; - } - file.seek((long) pageId << pageSizeShift); - file.readFullyDirect(buffer, 0, pageSize); - readCount++; - out.write(buffer, 0, pageSize); - return pageId + 1; - } - } - - /** - * Open the file and read the header. - */ - public void open() { - try { - metaRootPageId.put(META_TABLE_ID, PAGE_ID_META_ROOT); - if (IOUtils.exists(fileName)) { - long length = IOUtils.length(fileName); - if (length < MIN_PAGE_COUNT * PAGE_SIZE_MIN) { - if (database.isReadOnly()) { - throw DbException.get(ErrorCode.FILE_CORRUPTED_1, fileName + " length: " + length); - } - // the database was not fully created - openNew(); - } else { - openExisting(); - } - } else { - openNew(); - } - } catch (DbException e) { - close(); - throw e; - } - } - - private void openNew() { - setPageSize(pageSize); - freeListPagesPerList = PageFreeList.getPagesAddressed(pageSize); - file = database.openFile(fileName, accessMode, false); - recoveryRunning = true; - writeStaticHeader(); - writeVariableHeader(); - log = new PageLog(this); - increaseFileSize(MIN_PAGE_COUNT); - openMetaIndex(); - logFirstTrunkPage = allocatePage(); - log.openForWriting(logFirstTrunkPage, false); - isNew = true; - recoveryRunning = false; - increaseFileSize(INCREMENT_PAGES); - } - - private void openExisting() { - file = database.openFile(fileName, accessMode, true); - readStaticHeader(); - freeListPagesPerList = PageFreeList.getPagesAddressed(pageSize); - fileLength = file.length(); - pageCount = (int) (fileLength / pageSize); - if (pageCount < MIN_PAGE_COUNT) { - if (database.isReadOnly()) { - throw DbException.get(ErrorCode.FILE_CORRUPTED_1, fileName + " pageCount: " + pageCount); - } - file.close(); - IOUtils.delete(fileName); - openNew(); - return; - } - readVariableHeader(); - log = new PageLog(this); - log.openForReading(logKey, logFirstTrunkPage, logFirstDataPage); - recover(); - if (!database.isReadOnly()) { - recoveryRunning = true; - log.free(); - logFirstTrunkPage = allocatePage(); - log.openForWriting(logFirstTrunkPage, false); - recoveryRunning = false; - checkpoint(); - removeOldTempIndexes(); - } - } - - private void removeOldTempIndexes() { - if (tempObjects != null) { - metaObjects.putAll(tempObjects); - for (PageIndex index: tempObjects.values()) { - if (index.getTable().isTemporary()) { - index.truncate(systemSession); - index.remove(systemSession); - } - } - systemSession.commit(true); - tempObjects = null; - } - metaObjects.clear(); - metaObjects.put(-1, metaIndex); - } - - private void writeIndexRowCounts() { - for (PageIndex index: metaObjects.values()) { - index.writeRowCount(); - } - } - - private void writeBack() { - ArrayList list = cache.getAllChanged(); - Collections.sort(list); - for (CacheObject rec : list) { - writeBack(rec); - } - } - - /** - * Flush all pending changes to disk, and switch the new transaction log. - */ - public void checkpoint() { - trace.debug("checkpoint"); - if (log == null || database.isReadOnly()) { - // the file was never fully opened - return; - } - synchronized (database) { - database.checkPowerOff(); - writeIndexRowCounts(); - - log.checkpoint(); - writeBack(); - - int firstUncommittedSection = getFirstUncommittedSection(); - - log.removeUntil(firstUncommittedSection); - - // write back the free list - writeBack(); - - // ensure the free list is backed up again - log.checkpoint(); - - - byte[] empty = new byte[pageSize]; - for (int i = PAGE_ID_FREE_LIST_ROOT; i < pageCount; i++) { - if (isUsed(i)) { - freed.clear(i); - } else if (!freed.get(i)) { - if (trace.isDebugEnabled()) { - trace.debug("free " + i); - } - freed.set(i); - file.seek((long) i << pageSizeShift); - file.write(empty, 0, pageSize); - writeCount++; - } - } - } - } - - /** - * Shrink the file so there are no empty pages at the end. - * - * @param fully if the database should be fully compressed - */ - public void compact(boolean fully) { - if (!SysProperties.PAGE_STORE_TRIM) { - return; - } - // find the last used page - int lastUsed = -1; - for (int i = getFreeListId(pageCount); i >= 0; i--) { - lastUsed = getFreeList(i).getLastUsed(); - if (lastUsed != -1) { - break; - } - } - // open a new log at the very end - // (to be truncated later) - writeBack(); - recoveryRunning = true; - try { - log.free(); - logFirstTrunkPage = lastUsed + 1; - allocatePage(logFirstTrunkPage); - log.openForWriting(logFirstTrunkPage, true); - - // ensure the free list is backed up again - log.checkpoint(); - - } finally { - recoveryRunning = false; - } - long start = System.currentTimeMillis(); - int maxCompactTime = SysProperties.MAX_COMPACT_TIME; - int maxMove = SysProperties.MAX_COMPACT_COUNT; - if (fully) { - maxCompactTime = Integer.MAX_VALUE; - maxMove = Integer.MAX_VALUE; - } - for (int x = lastUsed, j = 0; x > MIN_PAGE_COUNT && j < maxMove; x--, j++) { - compact(x); - long now = System.currentTimeMillis(); - if (now > start + maxCompactTime) { - break; - } - } - - // TODO can most likely be simplified - checkpoint(); - log.checkpoint(); - writeIndexRowCounts(); - log.checkpoint(); - writeBack(); - commit(systemSession); - writeBack(); - log.checkpoint(); - - // truncate the log - recoveryRunning = true; - try { - log.free(); - setLogFirstPage(0, 0, 0); - } finally { - recoveryRunning = false; - } - writeBack(); - for (int i = getFreeListId(pageCount); i >= 0; i--) { - lastUsed = getFreeList(i).getLastUsed(); - if (lastUsed != -1) { - break; - } - } - int newPageCount = lastUsed + 1; - if (newPageCount < pageCount) { - freed.set(newPageCount, pageCount, false); - } - pageCount = newPageCount; - // the easiest way to remove superfluous entries - freeLists.clear(); - trace.debug("pageCount:" + pageCount); - long newLength = (long) pageCount << pageSizeShift; - if (file.length() != newLength) { - file.setLength(newLength); - writeCount++; - } - } - - private void compact(int full) { - int free = -1; - for (int i = 0; i < pageCount; i++) { - free = getFreeList(i).getFirstFree(); - if (free != -1) { - break; - } - } - if (free == -1 || free >= full) { - return; - } - Page f = (Page) cache.get(free); - if (f != null) { - DbException.throwInternalError("not free: " + f); - } - if (isUsed(full)) { - Page p = getPage(full); - if (p != null) { - trace.debug("move " + p.getPos() + " to " + free); - try { - p.moveTo(systemSession, free); - } finally { - changeCount++; - } - } else { - freePage(full); - } - } - } - - /** - * Read a page from the store. - * - * @param pageId the page id - * @return the page - */ - public Page getPage(int pageId) { - synchronized (database) { - Page p = (Page) cache.find(pageId); - if (p != null) { - return p; - } - } - Data data = createData(); - readPage(pageId, data); - int type = data.readByte(); - if (type == Page.TYPE_EMPTY) { - return null; - } - data.readShortInt(); - data.readInt(); - if (!checksumTest(data.getBytes(), pageId, pageSize)) { - throw DbException.get(ErrorCode.FILE_CORRUPTED_1, "wrong checksum"); - } - Page p; - switch (type & ~Page.FLAG_LAST) { - case Page.TYPE_FREE_LIST: - p = PageFreeList.read(this, data, pageId); - break; - case Page.TYPE_DATA_LEAF: { - int indexId = data.readVarInt(); - PageDataIndex index = (PageDataIndex) metaObjects.get(indexId); - if (index == null) { - throw DbException.get(ErrorCode.FILE_CORRUPTED_1, "index not found " + indexId); - } - p = PageDataLeaf.read(index, data, pageId); - break; - } - case Page.TYPE_DATA_NODE: { - int indexId = data.readVarInt(); - PageDataIndex index = (PageDataIndex) metaObjects.get(indexId); - if (index == null) { - throw DbException.get(ErrorCode.FILE_CORRUPTED_1, "index not found " + indexId); - } - p = PageDataNode.read(index, data, pageId); - break; - } - case Page.TYPE_DATA_OVERFLOW: { - p = PageDataOverflow.read(this, data, pageId); - break; - } - case Page.TYPE_BTREE_LEAF: { - int indexId = data.readVarInt(); - PageBtreeIndex index = (PageBtreeIndex) metaObjects.get(indexId); - if (index == null) { - throw DbException.get(ErrorCode.FILE_CORRUPTED_1, "index not found " + indexId); - } - p = PageBtreeLeaf.read(index, data, pageId); - break; - } - case Page.TYPE_BTREE_NODE: { - int indexId = data.readVarInt(); - PageBtreeIndex index = (PageBtreeIndex) metaObjects.get(indexId); - if (index == null) { - throw DbException.get(ErrorCode.FILE_CORRUPTED_1, "index not found " + indexId); - } - p = PageBtreeNode.read(index, data, pageId); - break; - } - case Page.TYPE_STREAM_TRUNK: - p = PageStreamTrunk.read(this, data, pageId); - break; - case Page.TYPE_STREAM_DATA: - p = PageStreamData.read(this, data, pageId); - break; - default: - throw DbException.get(ErrorCode.FILE_CORRUPTED_1, "page=" + pageId + " type=" + type); - } - cache.put(p); - return p; - } - - private int getFirstUncommittedSection() { - trace.debug("getFirstUncommittedSection"); - Session[] sessions = database.getSessions(true); - int firstUncommittedSection = log.getLogSectionId(); - for (int i = 0; i < sessions.length; i++) { - Session session = sessions[i]; - int firstUncommitted = session.getFirstUncommittedLog(); - if (firstUncommitted != Session.LOG_WRITTEN) { - if (firstUncommitted < firstUncommittedSection) { - firstUncommittedSection = firstUncommitted; - } - } - } - return firstUncommittedSection; - } - - private void readStaticHeader() { - file.seek(FileStore.HEADER_LENGTH); - Data page = Data.create(database, new byte[PAGE_SIZE_MIN - FileStore.HEADER_LENGTH]); - file.readFully(page.getBytes(), 0, PAGE_SIZE_MIN - FileStore.HEADER_LENGTH); - readCount++; - setPageSize(page.readInt()); - int writeVersion = page.readByte(); - int readVersion = page.readByte(); - if (readVersion > READ_VERSION) { - throw DbException.get(ErrorCode.FILE_VERSION_ERROR_1, fileName); - } - if (writeVersion > WRITE_VERSION) { - close(); - database.setReadOnly(true); - accessMode = "r"; - file = database.openFile(fileName, accessMode, true); - } - } - - private void readVariableHeader() { - Data page = createData(); - for (int i = 1;; i++) { - if (i == 3) { - throw DbException.get(ErrorCode.FILE_CORRUPTED_1, fileName); - } - page.reset(); - readPage(i, page); - CRC32 crc = new CRC32(); - crc.update(page.getBytes(), 4, pageSize - 4); - int expected = (int) crc.getValue(); - int got = page.readInt(); - if (expected == got) { - writeCountBase = page.readLong(); - logKey = page.readInt(); - logFirstTrunkPage = page.readInt(); - logFirstDataPage = page.readInt(); - break; - } - } - } - - /** - * Set the page size. The size must be a power of two. This method must be - * called before opening. - * - * @param size the page size - */ - public void setPageSize(int size) { - if (size < PAGE_SIZE_MIN || size > PAGE_SIZE_MAX) { - throw DbException.get(ErrorCode.FILE_CORRUPTED_1, fileName + " pageSize: " + size); - } - boolean good = false; - int shift = 0; - for (int i = 1; i <= size;) { - if (size == i) { - good = true; - break; - } - shift++; - i += i; - } - if (!good) { - throw DbException.get(ErrorCode.FILE_CORRUPTED_1, fileName); - } - pageSize = size; - emptyPage = createData(); - pageSizeShift = shift; - } - - private void writeStaticHeader() { - Data page = Data.create(database, new byte[pageSize - FileStore.HEADER_LENGTH]); - page.writeInt(pageSize); - page.writeByte((byte) WRITE_VERSION); - page.writeByte((byte) READ_VERSION); - file.seek(FileStore.HEADER_LENGTH); - file.write(page.getBytes(), 0, pageSize - FileStore.HEADER_LENGTH); - writeCount++; - } - - /** - * Set the trunk page and data page id of the log. - * - * @param logKey the log key of the trunk page - * @param trunkPageId the trunk page id - * @param dataPageId the data page id - */ - void setLogFirstPage(int logKey, int trunkPageId, int dataPageId) { - if (trace.isDebugEnabled()) { - trace.debug("setLogFirstPage key: " + logKey + " trunk: " + trunkPageId + " data: " + dataPageId); - } - this.logKey = logKey; - this.logFirstTrunkPage = trunkPageId; - this.logFirstDataPage = dataPageId; - writeVariableHeader(); - } - - private void writeVariableHeader() { - trace.debug("writeVariableHeader"); - file.sync(); - Data page = createData(); - page.writeInt(0); - page.writeLong(getWriteCountTotal()); - page.writeInt(logKey); - page.writeInt(logFirstTrunkPage); - page.writeInt(logFirstDataPage); - CRC32 crc = new CRC32(); - crc.update(page.getBytes(), 4, pageSize - 4); - page.setInt(0, (int) crc.getValue()); - file.seek(pageSize); - file.write(page.getBytes(), 0, pageSize); - file.seek(pageSize + pageSize); - file.write(page.getBytes(), 0, pageSize); - // don't increment the write counter, because it was just written - } - - /** - * Close the file without further writing. - */ - public void close() { - trace.debug("close"); - if (log != null) { - log.close(); - log = null; - } - if (file != null) { - try { - file.close(); - } finally { - file = null; - } - } - } - - public void flushLog() { - if (file != null) { - synchronized (database) { - log.flush(); - } - } - } - - /** - * Flush the transaction log and sync the file. - */ - public void sync() { - if (file != null) { - synchronized (database) { - log.flush(); - file.sync(); - } - } - } - - public Trace getTrace() { - return trace; - } - - public void writeBack(CacheObject obj) { - synchronized (database) { - Page record = (Page) obj; - if (trace.isDebugEnabled()) { - trace.debug("writeBack " + record); - } - record.write(); - record.setChanged(false); - } - } - - /** - * Write an undo log entry if required. - * - * @param page the page - * @param old the old data (if known) or null - */ - public void logUndo(Page page, Data old) { - synchronized (database) { - if (trace.isDebugEnabled()) { - // if (!record.isChanged()) { - // trace.debug("logUndo " + record.toString()); - // } - } - checkOpen(); - database.checkWritingAllowed(); - if (!recoveryRunning) { - int pos = page.getPos(); - if (!log.getUndo(pos)) { - if (old == null) { - old = readPage(pos); - } - log.addUndo(pos, old); - } - } - } - } - - /** - * Update a page. - * - * @param page the page - */ - public void update(Page page) { - synchronized (database) { - if (trace.isDebugEnabled()) { - if (!page.isChanged()) { - trace.debug("updateRecord " + page.toString()); - } - } - checkOpen(); - database.checkWritingAllowed(); - page.setChanged(true); - int pos = page.getPos(); - if (SysProperties.CHECK && !recoveryRunning) { - // ensure the undo entry is already written - log.addUndo(pos, null); - } - allocatePage(pos); - cache.update(pos, page); - } - } - - private int getFreeListId(int pageId) { - return (pageId - PAGE_ID_FREE_LIST_ROOT) / freeListPagesPerList; - } - - private PageFreeList getFreeListForPage(int pageId) { - return getFreeList(getFreeListId(pageId)); - } - - private PageFreeList getFreeList(int i) { - PageFreeList list = null; - if (i < freeLists.size()) { - list = freeLists.get(i); - if (list != null) { - return list; - } - } - int p = PAGE_ID_FREE_LIST_ROOT + i * freeListPagesPerList; - while (p >= pageCount) { - increaseFileSize(INCREMENT_PAGES); - } - if (p < pageCount) { - list = (PageFreeList) getPage(p); - } - if (list == null) { - list = PageFreeList.create(this, p); - cache.put(list); - } - while (freeLists.size() <= i) { - freeLists.add(null); - } - freeLists.set(i, list); - return list; - } - - private void freePage(int pageId) { - PageFreeList list = getFreeListForPage(pageId); - list.free(pageId); - } - - /** - * Set the bit of an already allocated page. - * - * @param pageId the page to allocate - */ - void allocatePage(int pageId) { - PageFreeList list = getFreeListForPage(pageId); - list.allocate(pageId); - } - - private boolean isUsed(int pageId) { - return getFreeListForPage(pageId).isUsed(pageId); - } - - /** - * Allocate a number of pages. - * - * @param list the list where to add the allocated pages - * @param pagesToAllocate the number of pages to allocate - * @param exclude the exclude list - * @param after all allocated pages are higher than this page - */ - void allocatePages(IntArray list, int pagesToAllocate, BitSet exclude, int after) { - for (int i = 0; i < pagesToAllocate; i++) { - int page = allocatePage(exclude, after); - after = page; - list.add(page); - } - } - - /** - * Allocate a page. - * - * @return the page id - */ - public int allocatePage() { - int pos = allocatePage(null, 0); - if (!recoveryRunning) { - log.addUndo(pos, emptyPage); - } - return pos; - } - - private int allocatePage(BitSet exclude, int first) { - int page; - synchronized (database) { - // TODO could remember the first possible free list page - for (int i = 0;; i++) { - PageFreeList list = getFreeList(i); - page = list.allocate(exclude, first); - if (page >= 0) { - break; - } - } - if (page >= pageCount) { - increaseFileSize(INCREMENT_PAGES); - } - if (trace.isDebugEnabled()) { - // trace.debug("allocatePage " + pos); - } - return page; - } - } - - private void increaseFileSize(int increment) { - for (int i = pageCount; i < pageCount + increment; i++) { - freed.set(i); - } - pageCount += increment; - long newLength = (long) pageCount << pageSizeShift; - file.setLength(newLength); - writeCount++; - fileLength = newLength; - } - - /** - * Add a page to the free list. The undo log entry must have been written. - * - * @param pageId the page id - */ - public void free(int pageId) { - free(pageId, true); - } - - /** - * Add a page to the free list. - * - * @param pageId the page id - * @param undo if the undo record must have been written - */ - void free(int pageId, boolean undo) { - if (trace.isDebugEnabled()) { - // trace.debug("freePage " + pageId); - } - synchronized (database) { - cache.remove(pageId); - if (SysProperties.CHECK && !recoveryRunning && undo) { - // ensure the undo entry is already written - log.addUndo(pageId, null); - } - freePage(pageId); - if (recoveryRunning) { - writePage(pageId, createData()); - } - } - } - - /** - * Create a data object. - * - * @return the data page. - */ - public Data createData() { - return Data.create(database, new byte[pageSize]); - } - - /** - * Read a page. - * - * @param pos the page id - * @return the page - */ - public Data readPage(int pos) { - Data page = createData(); - readPage(pos, page); - return page; - } - - /** - * Read a page. - * - * @param pos the page id - * @param page the page - */ - void readPage(int pos, Data page) { - synchronized (database) { - if (pos < 0 || pos >= pageCount) { - throw DbException.get(ErrorCode.FILE_CORRUPTED_1, pos + " of " + pageCount); - } - file.seek((long) pos << pageSizeShift); - file.readFully(page.getBytes(), 0, pageSize); - readCount++; - } - } - - /** - * Get the page size. - * - * @return the page size - */ - public int getPageSize() { - return pageSize; - } - - /** - * Get the number of pages (including free pages). - * - * @return the page count - */ - public int getPageCount() { - return pageCount; - } - - /** - * Write a page. - * - * @param pageId the page id - * @param data the data - */ - public void writePage(int pageId, Data data) { - if (pageId <= 0) { - DbException.throwInternalError("write to page " + pageId); - } - byte[] bytes = data.getBytes(); - if (SysProperties.CHECK) { - boolean shouldBeFreeList = (pageId - PAGE_ID_FREE_LIST_ROOT) % freeListPagesPerList == 0; - boolean isFreeList = bytes[0] == Page.TYPE_FREE_LIST; - if (bytes[0] != 0 && shouldBeFreeList != isFreeList) { - throw DbException.throwInternalError(); - } - } - checksumSet(bytes, pageId); - synchronized (database) { - file.seek((long) pageId << pageSizeShift); - file.write(bytes, 0, pageSize); - writeCount++; - } - } - - /** - * Remove a page from the cache. - * - * @param pageId the page id - */ - public void removeRecord(int pageId) { - synchronized (database) { - cache.remove(pageId); - } - } - - Database getDatabase() { - return database; - } - - /** - * Run recovery. - */ - private void recover() { - trace.debug("log recover"); - recoveryRunning = true; - log.recover(PageLog.RECOVERY_STAGE_UNDO); - if (reservedPages != null) { - for (int r : reservedPages.keySet()) { - if (trace.isDebugEnabled()) { - trace.debug("reserve " + r); - } - allocatePage(r); - } - } - log.recover(PageLog.RECOVERY_STAGE_ALLOCATE); - openMetaIndex(); - readMetaData(); - log.recover(PageLog.RECOVERY_STAGE_REDO); - boolean setReadOnly = false; - if (!database.isReadOnly()) { - if (log.getInDoubtTransactions().size() == 0) { - log.recoverEnd(); - int firstUncommittedSection = getFirstUncommittedSection(); - log.removeUntil(firstUncommittedSection); - } else { - setReadOnly = true; - } - } - PageDataIndex systemTable = (PageDataIndex) metaObjects.get(0); - isNew = systemTable == null; - for (PageIndex index : metaObjects.values()) { - if (index.getTable().isTemporary()) { - // temporary indexes are removed after opening - if (tempObjects == null) { - tempObjects = New.hashMap(); - } - tempObjects.put(index.getId(), index); - } else { - index.close(systemSession); - } - } - - allocatePage(PAGE_ID_META_ROOT); - writeIndexRowCounts(); - recoveryRunning = false; - reservedPages = null; - - writeBack(); - // clear the cache because it contains pages with closed indexes - cache.clear(); - freeLists.clear(); - - metaObjects.clear(); - metaObjects.put(-1, metaIndex); - - if (setReadOnly) { - database.setReadOnly(true); - } - trace.debug("log recover done"); - } - - /** - * A record is added to a table, or removed from a table. - * - * @param session the session - * @param tableId the table id - * @param row the row to add - * @param add true if the row is added, false if it is removed - */ - public void logAddOrRemoveRow(Session session, int tableId, Row row, boolean add) { - synchronized (database) { - if (!recoveryRunning) { - log.logAddOrRemoveRow(session, tableId, row, add); - } - } - } - - /** - * Mark a committed transaction. - * - * @param session the session - */ - public void commit(Session session) { - synchronized (database) { - checkOpen(); - log.commit(session.getId()); - if (log.getSize() - logSizeBase > maxLogSize) { - checkpoint(); - logSizeBase = log.getSize(); - } - } - } - - /** - * Prepare a transaction. - * - * @param session the session - * @param transaction the name of the transaction - */ - public void prepareCommit(Session session, String transaction) { - synchronized (database) { - log.prepareCommit(session, transaction); - } - } - - /** - * Check whether this is a new database. - * - * @return true if it is - */ - public boolean isNew() { - return isNew; - } - - /** - * Reserve the page if this is a index root page entry. - * - * @param logPos the redo log position - * @param tableId the table id - * @param row the row - */ - void allocateIfIndexRoot(int logPos, int tableId, Row row) { - if (tableId == META_TABLE_ID) { - int rootPageId = row.getValue(3).getInt(); - if (reservedPages == null) { - reservedPages = New.hashMap(); - } - reservedPages.put(rootPageId, logPos); - } - } - - /** - * Redo a delete in a table. - * - * @param logPos the redo log position - * @param tableId the object id of the table - * @param key the key of the row to delete - */ - void redoDelete(int logPos, int tableId, long key) { - Index index = metaObjects.get(tableId); - PageDataIndex scan = (PageDataIndex) index; - Row row = scan.getRow(key); - redo(logPos, tableId, row, false); - } - - /** - * Redo a change in a table. - * - * @param logPos the redo log position - * @param tableId the object id of the table - * @param row the row - * @param add true if the record is added, false if deleted - */ - void redo(int logPos, int tableId, Row row, boolean add) { - if (tableId == META_TABLE_ID) { - if (add) { - addMeta(row, systemSession, true); - } else { - removeMeta(logPos, row); - } - } - Index index = metaObjects.get(tableId); - if (index == null) { - throw DbException.throwInternalError("Table not found: " + tableId + " " + row + " " + add); - } - Table table = index.getTable(); - if (add) { - table.addRow(systemSession, row); - } else { - table.removeRow(systemSession, row); - } - } - - /** - * Redo a truncate. - * - * @param tableId the object id of the table - */ - void redoTruncate(int tableId) { - Index index = metaObjects.get(tableId); - Table table = index.getTable(); - table.truncate(systemSession); - } - - private void openMetaIndex() { - CreateTableData data = new CreateTableData(); - ArrayList cols = data.columns; - cols.add(new Column("ID", Value.INT)); - cols.add(new Column("TYPE", Value.INT)); - cols.add(new Column("PARENT", Value.INT)); - cols.add(new Column("HEAD", Value.INT)); - cols.add(new Column("OPTIONS", Value.STRING)); - cols.add(new Column("COLUMNS", Value.STRING)); - metaSchema = new Schema(database, 0, "", null, true); - data.schema = metaSchema; - data.tableName = "PAGE_INDEX"; - data.id = META_TABLE_ID; - data.temporary = false; - data.persistData = true; - data.persistIndexes = true; - data.create = false; - data.session = systemSession; - metaTable = new RegularTable(data); - metaIndex = (PageDataIndex) metaTable.getScanIndex( - systemSession); - metaObjects.clear(); - metaObjects.put(-1, metaIndex); - } - - private void readMetaData() { - Cursor cursor = metaIndex.find(systemSession, null, null); - // first, create all tables - while (cursor.next()) { - Row row = cursor.get(); - int type = row.getValue(1).getInt(); - if (type == META_TYPE_DATA_INDEX) { - addMeta(row, systemSession, false); - } - } - // now create all secondary indexes - // otherwise the table might not be created yet - cursor = metaIndex.find(systemSession, null, null); - while (cursor.next()) { - Row row = cursor.get(); - int type = row.getValue(1).getInt(); - if (type != META_TYPE_DATA_INDEX) { - addMeta(row, systemSession, false); - } - } - } - - private void removeMeta(int logPos, Row row) { - int id = row.getValue(0).getInt(); - PageIndex index = metaObjects.get(id); - int rootPageId = index.getRootPageId(); - index.getTable().removeIndex(index); - if (index instanceof PageBtreeIndex || index instanceof PageDelegateIndex) { - if (index.isTemporary()) { - systemSession.removeLocalTempTableIndex(index); - } else { - index.getSchema().remove(index); - } - } - index.remove(systemSession); - metaObjects.remove(id); - if (reservedPages != null && reservedPages.containsKey(rootPageId)) { - // re-allocate the page if it is used later on again - int latestPos = reservedPages.get(rootPageId); - if (latestPos > logPos) { - allocatePage(rootPageId); - } - } - } - - private void addMeta(Row row, Session session, boolean redo) { - int id = row.getValue(0).getInt(); - int type = row.getValue(1).getInt(); - int parent = row.getValue(2).getInt(); - int rootPageId = row.getValue(3).getInt(); - String options = row.getValue(4).getString(); - String columnList = row.getValue(5).getString(); - String[] columns = StringUtils.arraySplit(columnList, ',', false); - String[] ops = StringUtils.arraySplit(options, ',', false); - Index meta; - if (trace.isDebugEnabled()) { - trace.debug("addMeta id=" + id + " type=" + type + " root=" + rootPageId + " parent=" + parent + " columns=" + columnList); - } - if (redo && rootPageId != 0) { - // ensure the page is empty, but not used by regular data - writePage(rootPageId, createData()); - allocatePage(rootPageId); - } - metaRootPageId.put(id, rootPageId); - if (type == META_TYPE_DATA_INDEX) { - CreateTableData data = new CreateTableData(); - for (int i = 0; i < columns.length; i++) { - Column col = new Column("C" + i, Value.INT); - data.columns.add(col); - } - data.schema = metaSchema; - data.tableName = "T" + id; - data.id = id; - data.temporary = ops[2].equals("temp"); - data.persistData = true; - data.persistIndexes = true; - data.create = false; - data.session = session; - RegularTable table = new RegularTable(data); - CompareMode mode = CompareMode.getInstance(ops[0], Integer.parseInt(ops[1])); - table.setCompareMode(mode); - meta = table.getScanIndex(session); - } else { - Index p = metaObjects.get(parent); - if (p == null) { - throw DbException.get(ErrorCode.FILE_CORRUPTED_1, "Table not found:" + parent + " for " + row + " meta:" + metaObjects); - } - RegularTable table = (RegularTable) p.getTable(); - Column[] tableCols = table.getColumns(); - IndexColumn[] cols = new IndexColumn[columns.length]; - for (int i = 0; i < columns.length; i++) { - String c = columns[i]; - IndexColumn ic = new IndexColumn(); - int idx = c.indexOf('/'); - if (idx >= 0) { - String s = c.substring(idx + 1); - ic.sortType = Integer.parseInt(s); - c = c.substring(0, idx); - } - Column column = tableCols[Integer.parseInt(c)]; - ic.column = column; - cols[i] = ic; - } - IndexType indexType; - if (ops[3].equals("d")) { - indexType = IndexType.createPrimaryKey(true, false); - Column[] tableColumns = table.getColumns(); - for (int i = 0; i < cols.length; i++) { - tableColumns[cols[i].column.getColumnId()].setNullable(false); - } - } else { - indexType = IndexType.createNonUnique(true); - } - meta = table.addIndex(session, "I" + id, id, cols, indexType, false, null); - } - PageIndex index; - if (meta instanceof MultiVersionIndex) { - index = (PageIndex) ((MultiVersionIndex) meta).getBaseIndex(); - } else { - index = (PageIndex) meta; - } - metaObjects.put(id, index); - } - - /** - * Add an index to the in-memory index map. - * - * @param index the index - */ - public void addIndex(PageIndex index) { - metaObjects.put(index.getId(), index); - } - - /** - * Add the meta data of an index. - * - * @param index the index to add - * @param session the session - */ - public void addMeta(PageIndex index, Session session) { - int type = index instanceof PageDataIndex ? META_TYPE_DATA_INDEX : META_TYPE_BTREE_INDEX; - IndexColumn[] columns = index.getIndexColumns(); - StatementBuilder buff = new StatementBuilder(); - for (IndexColumn col : columns) { - buff.appendExceptFirst(","); - int id = col.column.getColumnId(); - buff.append(id); - int sortType = col.sortType; - if (sortType != 0) { - buff.append('/'); - buff.append(sortType); - } - } - String columnList = buff.toString(); - Table table = index.getTable(); - CompareMode mode = table.getCompareMode(); - String options = mode.getName()+ "," + mode.getStrength() + ","; - if (table.isTemporary()) { - options += "temp"; - } - options += ","; - if (index instanceof PageDelegateIndex) { - options += "d"; - } - Row row = metaTable.getTemplateRow(); - row.setValue(0, ValueInt.get(index.getId())); - row.setValue(1, ValueInt.get(type)); - row.setValue(2, ValueInt.get(table.getId())); - row.setValue(3, ValueInt.get(index.getRootPageId())); - row.setValue(4, ValueString.get(options)); - row.setValue(5, ValueString.get(columnList)); - row.setKey(index.getId() + 1); - metaIndex.add(session, row); - } - - /** - * Remove the meta data of an index. - * - * @param index the index to remove - * @param session the session - */ - public void removeMeta(Index index, Session session) { - if (!recoveryRunning) { - removeMetaIndex(index, session); - metaObjects.remove(index.getId()); - } - } - - private void removeMetaIndex(Index index, Session session) { - int key = index.getId() + 1; - Row row = metaIndex.getRow(session, key); - if (row.getKey() != key) { - throw DbException.get(ErrorCode.FILE_CORRUPTED_1, "key: " + key + " index: " + index + " table: " + index.getTable() + " row: " + row); - } - metaIndex.remove(session, row); - } - - /** - * Set the maximum transaction log size in megabytes. - * - * @param maxSize the new maximum log size - */ - public void setMaxLogSize(long maxSize) { - this.maxLogSize = maxSize; - } - - /** - * Commit or rollback a prepared transaction after opening a database with - * in-doubt transactions. - * - * @param sessionId the session id - * @param pageId the page where the transaction was prepared - * @param commit if the transaction should be committed - */ - public void setInDoubtTransactionState(int sessionId, int pageId, boolean commit) { - boolean old = database.isReadOnly(); - try { - database.setReadOnly(false); - log.setInDoubtTransactionState(sessionId, pageId, commit); - } finally { - database.setReadOnly(old); - } - } - - /** - * Get the list of in-doubt transaction. - * - * @return the list - */ - public ArrayList getInDoubtTransactions() { - return log.getInDoubtTransactions(); - } - - /** - * Check whether the recovery process is currently running. - * - * @return true if it is - */ - public boolean isRecoveryRunning() { - return this.recoveryRunning; - } - - private void checkOpen() { - if (file == null) { - throw DbException.get(ErrorCode.DATABASE_IS_CLOSED); - } - } - - /** - * Create an array of SearchRow with the given size. - * - * @param entryCount the number of elements - * @return the array - */ - public static SearchRow[] newSearchRows(int entryCount) { - if (entryCount == 0) { - return EMPTY_SEARCH_ROW; - } - return new SearchRow[entryCount]; - } - - /** - * Get the file write count since the database was created. - * - * @return the write count - */ - public long getWriteCountTotal() { - return writeCount + writeCountBase; - } - - /** - * Get the file write count since the database was opened. - * - * @return the write count - */ - public long getWriteCount() { - return writeCount; - } - - /** - * Get the file read count since the database was opened. - * - * @return the read count - */ - public long getReadCount() { - return readCount; - } - - /** - * A table is truncated. - * - * @param session the session - * @param tableId the table id - */ - public void logTruncate(Session session, int tableId) { - synchronized (database) { - if (!recoveryRunning) { - log.logTruncate(session, tableId); - } - } - } - - /** - * Get the root page of an index. - * - * @param indexId the index id - * @return the root page - */ - public int getRootPageId(int indexId) { - return metaRootPageId.get(indexId); - } - - public Cache getCache() { - return cache; - } - - private void checksumSet(byte[] d, int pageId) { - int ps = pageSize; - int type = d[0]; - if (type == Page.TYPE_EMPTY) { - return; - } - int s1 = 255 + (type & 255), s2 = 255 + s1; - s2 += s1 += d[6] & 255; - s2 += s1 += d[(ps >> 1) - 1] & 255; - s2 += s1 += d[ps >> 1] & 255; - s2 += s1 += d[ps - 2] & 255; - s2 += s1 += d[ps - 1] & 255; - d[1] = (byte) (((s1 & 255) + (s1 >> 8)) ^ pageId); - d[2] = (byte) (((s2 & 255) + (s2 >> 8)) ^ (pageId >> 8)); - } - - /** - * Check if the stored checksum is correct - * @param d the data - * @param pageId the page id - * @param pageSize the page size - * @return true if it is correct - */ - public static boolean checksumTest(byte[] d, int pageId, int pageSize) { - int ps = pageSize; - int s1 = 255 + (d[0] & 255), s2 = 255 + s1; - s2 += s1 += d[6] & 255; - s2 += s1 += d[(ps >> 1) - 1] & 255; - s2 += s1 += d[ps >> 1] & 255; - s2 += s1 += d[ps - 2] & 255; - s2 += s1 += d[ps - 1] & 255; - if (d[1] != (byte) (((s1 & 255) + (s1 >> 8)) ^ pageId) - || d[2] != (byte) (((s2 & 255) + (s2 >> 8)) ^ (pageId >> 8))) { - return false; - } - return true; - } - - /** - * Increment the change count. To be done after the operation has finished. - */ - public void incrementChangeCount() { - changeCount++; - } - - /** - * Get the current change count. The first value is 1 - * - * @return the change count - */ - public int getChangeCount() { - return changeCount; - } - -} diff --git a/tools/h2/src/main/org/h2/store/PageStreamData.java b/tools/h2/src/main/org/h2/store/PageStreamData.java deleted file mode 100755 index 73d9f26..0000000 --- a/tools/h2/src/main/org/h2/store/PageStreamData.java +++ /dev/null @@ -1,168 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.store; - -import org.h2.engine.Session; - -/** - * A data page of a stream. The format is: - *
    - *
  • page type: byte (0)
  • - *
  • checksum: short (1-2)
  • - *
  • the trunk page id: int (3-6)
  • - *
  • log key: int (7-10)
  • - *
  • data (11-)
  • - *
- */ -public class PageStreamData extends Page { - - private static final int DATA_START = 11; - - private final PageStore store; - private int trunk; - private int logKey; - private Data data; - private int remaining; - - private PageStreamData(PageStore store, int pageId, int trunk, int logKey) { - setPos(pageId); - this.store = store; - this.trunk = trunk; - this.logKey = logKey; - } - - /** - * Read a stream data page. - * - * @param store the page store - * @param data the data - * @param pageId the page id - * @return the page - */ - static PageStreamData read(PageStore store, Data data, int pageId) { - PageStreamData p = new PageStreamData(store, pageId, 0, 0); - p.data = data; - p.read(); - return p; - } - - /** - * Create a new stream trunk page. - * - * @param store the page store - * @param pageId the page id - * @param trunk the trunk page - * @param logKey the log key - * @return the page - */ - static PageStreamData create(PageStore store, int pageId, int trunk, int logKey) { - return new PageStreamData(store, pageId, trunk, logKey); - } - - /** - * Read the page from the disk. - */ - private void read() { - data.reset(); - data.readByte(); - data.readShortInt(); - trunk = data.readInt(); - logKey = data.readInt(); - } - - /** - * Write the header data. - */ - void initWrite() { - data = store.createData(); - data.writeByte((byte) Page.TYPE_STREAM_DATA); - data.writeShortInt(0); - data.writeInt(trunk); - data.writeInt(logKey); - remaining = store.getPageSize() - data.length(); - } - - /** - * Write the data to the buffer. - * - * @param buff the source data - * @param off the offset in the source buffer - * @param len the number of bytes to write - * @return the number of bytes written - */ - int write(byte[] buff, int offset, int len) { - int max = Math.min(remaining, len); - data.write(buff, offset, max); - remaining -= max; - return max; - } - - public void write() { - store.writePage(getPos(), data); - } - - /** - * Get the number of bytes that fit in a page. - * - * @param pageSize the page size - * @return the number of bytes - */ - static int getCapacity(int pageSize) { - return pageSize - DATA_START; - } - - /** - * Read the next bytes from the buffer. - * - * @param startPos the position in the data page - * @param buff the target buffer - * @param off the offset in the target buffer - * @param len the number of bytes to read - */ - void read(int startPos, byte[] buff, int off, int len) { - System.arraycopy(data.getBytes(), startPos, buff, off, len); - } - - /** - * Get the number of remaining data bytes of this page. - * - * @return the remaining byte count - */ - int getRemaining() { - return remaining; - } - - /** - * Get the estimated memory size. - * - * @return number of double words (4 bytes) - */ - public int getMemorySize() { - return store.getPageSize() >> 2; - } - - public void moveTo(Session session, int newPos) { - // not required - } - - int getLogKey() { - return logKey; - } - - public String toString() { - return "[" + getPos() + "] stream data key:" + logKey + " pos:" + data.length() + " remaining:" + remaining; - } - - public boolean canRemove() { - return true; - } - - public int getReadStart() { - return DATA_START; - } - -} \ No newline at end of file diff --git a/tools/h2/src/main/org/h2/store/PageStreamTrunk.java b/tools/h2/src/main/org/h2/store/PageStreamTrunk.java deleted file mode 100755 index 38fdd44..0000000 --- a/tools/h2/src/main/org/h2/store/PageStreamTrunk.java +++ /dev/null @@ -1,279 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.store; - -import org.h2.constant.ErrorCode; -import org.h2.engine.Session; -import org.h2.message.DbException; - -/** - * A trunk page of a stream. It contains the page numbers of the stream, and the - * page number of the next trunk. The format is: - *
    - *
  • page type: byte (0)
  • - *
  • checksum: short (1-2)
  • - *
  • previous trunk page, or 0 if none: int (3-6)
  • - *
  • log key: int (7-10)
  • - *
  • next trunk page: int (11-14)
  • - *
  • number of pages: short (15-16)
  • - *
  • page ids (17-)
  • - *
- */ -public class PageStreamTrunk extends Page { - - private static final int DATA_START = 17; - - /** - * The previous stream trunk. - */ - int parent; - - /** - * The next stream trunk. - */ - int nextTrunk; - - private final PageStore store; - private int logKey; - private int[] pageIds; - private int pageCount; - private Data data; - - private PageStreamTrunk(PageStore store, int parent, int pageId, int next, int logKey, int[] pageIds) { - setPos(pageId); - this.parent = parent; - this.store = store; - this.nextTrunk = next; - this.logKey = logKey; - this.pageCount = pageIds.length; - this.pageIds = pageIds; - } - - private PageStreamTrunk(PageStore store, Data data, int pageId) { - setPos(pageId); - this.data = data; - this.store = store; - } - - /** - * Read a stream trunk page. - * - * @param store the page store - * @param data the data - * @param pageId the page id - * @return the page - */ - static PageStreamTrunk read(PageStore store, Data data, int pageId) { - PageStreamTrunk p = new PageStreamTrunk(store, data, pageId); - p.read(); - return p; - } - - /** - * Create a new stream trunk page. - * - * @param store the page store - * @param parent the parent page - * @param pageId the page id - * @param next the next trunk page - * @param logKey the log key - * @param pageIds the stream data page ids - * @return the page - */ - static PageStreamTrunk create(PageStore store, int parent, int pageId, int next, int logKey, int[] pageIds) { - return new PageStreamTrunk(store, parent, pageId, next, logKey, pageIds); - } - - /** - * Read the page from the disk. - */ - private void read() { - data.reset(); - data.readByte(); - data.readShortInt(); - parent = data.readInt(); - logKey = data.readInt(); - nextTrunk = data.readInt(); - pageCount = data.readShortInt(); - pageIds = new int[pageCount]; - for (int i = 0; i < pageCount; i++) { - pageIds[i] = data.readInt(); - } - } - - /** - * Get the data page id at the given position. - * - * @param index the index (0, 1, ...) - * @return the value, or -1 if the index is too large - */ - int getPageData(int index) { - if (index >= pageIds.length) { - return -1; - } - return pageIds[index++]; - } - - public void write() { - data = store.createData(); - data.writeByte((byte) Page.TYPE_STREAM_TRUNK); - data.writeShortInt(0); - data.writeInt(parent); - data.writeInt(logKey); - data.writeInt(nextTrunk); - data.writeShortInt(pageCount); - for (int i = 0; i < pageCount; i++) { - data.writeInt(pageIds[i]); - } - store.writePage(getPos(), data); - } - - /** - * Get the number of pages that can be addressed in a stream trunk page. - * - * @param pageSize the page size - * @return the number of pages - */ - static int getPagesAddressed(int pageSize) { - return (pageSize - DATA_START) / 4; - } - - /** - * Check if the given data page is in this trunk page. - * - * @param dataPageId the page id - * @return true if it is - */ - boolean contains(int dataPageId) { - for (int i = 0; i < pageCount; i++) { - if (pageIds[i] == dataPageId) { - return true; - } - } - return false; - } - - /** - * Free this page and all data pages. - * - * @return the number of pages freed - */ - int free() { - store.free(getPos(), false); - int freed = 1; - for (int i = 0; i < pageCount; i++) { - int page = pageIds[i]; - store.free(page, false); - freed++; - } - return freed; - } - - /** - * Get the estimated memory size. - * - * @return number of double words (4 bytes) - */ - public int getMemorySize() { - return store.getPageSize() >> 2; - } - - public void moveTo(Session session, int newPos) { - // not required - } - - int getLogKey() { - return logKey; - } - - public int getNextTrunk() { - return nextTrunk; - } - - /** - * An iterator over page stream trunk pages. - */ - static class Iterator { - - private PageStore store; - private int first; - private int next; - private int previous; - private boolean canDelete; - private int current; - - Iterator(PageStore store, int first) { - this.store = store; - this.next = first; - } - - int getCurrentPageId() { - return current; - } - - /** - * Get the next trunk page or null if no next trunk page. - * - * @return the next trunk page or null - */ - PageStreamTrunk next() { - canDelete = false; - if (first == 0) { - first = next; - } else if (first == next) { - return null; - } - if (next == 0 || next >= store.getPageCount()) { - return null; - } - Page p; - current = next; - try { - p = store.getPage(next); - } catch (DbException e) { - if (e.getErrorCode() == ErrorCode.FILE_CORRUPTED_1) { - // wrong checksum means end of stream - return null; - } - throw e; - } - if (p == null || p instanceof PageStreamTrunk || p instanceof PageStreamData) { - canDelete = true; - } - if (!(p instanceof PageStreamTrunk)) { - return null; - } - PageStreamTrunk t = (PageStreamTrunk) p; - if (previous > 0 && t.parent != previous) { - return null; - } - previous = next; - next = t.nextTrunk; - return t; - } - - /** - * Check if the current page can be deleted. It can if it's empty, a - * stream trunk, or a stream data page. - * - * @return true if it can be deleted - */ - boolean canDelete() { - return canDelete; - } - - } - - public boolean canRemove() { - return true; - } - - public String toString() { - return "page[" + getPos() + "] stream trunk key:" + logKey + " next:" + nextTrunk; - } - -} diff --git a/tools/h2/src/main/org/h2/store/SessionState.java b/tools/h2/src/main/org/h2/store/SessionState.java deleted file mode 100755 index f5729ba..0000000 --- a/tools/h2/src/main/org/h2/store/SessionState.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.store; - - -/** - * The session state contains information about when was the last commit of a - * session. It is only used during recovery. - */ -class SessionState { - - /** - * The session id - */ - public int sessionId; - - /** - * The last log id where a commit for this session is found. - */ - public int lastCommitLog; - - /** - * The position where a commit for this session is found. - */ - public int lastCommitPos; - - /** - * The in-doubt transaction if there is one. - */ - public InDoubtTransaction inDoubtTransaction; - - /** - * Check if this session state is already committed at this point. - * - * @param logId the log id - * @param pos the position in the log - * @return true if it is committed - */ - public boolean isCommitted(int logId, int pos) { - if (logId != lastCommitLog) { - return lastCommitLog > logId; - } - return lastCommitPos >= pos; - } - - public String toString() { - return "sessionId:" + sessionId + " log:" + lastCommitLog + " pos:" + lastCommitPos + " inDoubt:" + inDoubtTransaction; - } -} diff --git a/tools/h2/src/main/org/h2/store/WriterThread.java b/tools/h2/src/main/org/h2/store/WriterThread.java deleted file mode 100755 index e3da91f..0000000 --- a/tools/h2/src/main/org/h2/store/WriterThread.java +++ /dev/null @@ -1,125 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.store; - -import java.lang.ref.WeakReference; -import java.security.AccessControlException; -import org.h2.constant.SysProperties; -import org.h2.engine.Database; -import org.h2.message.Trace; -import org.h2.message.TraceSystem; - -/** - * The writer thread is responsible to flush the transaction transaction log - * from time to time. - */ -public class WriterThread implements Runnable { - - /** - * The reference to the database. - * - * Thread objects are not garbage collected - * until they returned from the run() method - * (even if they where never started) - * so if the connection was not closed, - * the database object cannot get reclaimed - * by the garbage collector if we use a hard reference. - */ - private volatile WeakReference databaseRef; - - private int writeDelay; - private Thread thread; - private volatile boolean stop; - - private WriterThread(Database database, int writeDelay) { - this.databaseRef = new WeakReference(database); - this.writeDelay = writeDelay; - } - - /** - * Change the write delay - * - * @param writeDelay the new write delay - */ - public void setWriteDelay(int writeDelay) { - this.writeDelay = writeDelay; - } - - /** - * Create and start a new writer thread for the given database. If the - * thread can't be created, this method returns null. - * - * @param database the database - * @param writeDelay the delay - * @return the writer thread object or null - */ - public static WriterThread create(Database database, int writeDelay) { - try { - WriterThread writer = new WriterThread(database, writeDelay); - writer.thread = new Thread(writer); - writer.thread.setName("H2 Log Writer " + database.getShortName()); - writer.thread.setDaemon(true); - return writer; - } catch (AccessControlException e) { - // // Google App Engine does not allow threads - return null; - } - } - - public void run() { - while (!stop) { - Database database = databaseRef.get(); - if (database == null) { - break; - } - int wait = writeDelay; - try { - if (database.isFileLockSerialized()) { - wait = SysProperties.MIN_WRITE_DELAY; - database.checkpointIfRequired(); - } else { - database.flush(); - } - } catch (Exception e) { - TraceSystem traceSystem = database.getTraceSystem(); - if (traceSystem != null) { - traceSystem.getTrace(Trace.LOG).error("flush", e); - } - } - - // TODO log writer: could also flush the dirty cache when there is - // low activity - if (wait < SysProperties.MIN_WRITE_DELAY) { - // wait 0 mean wait forever, which is not what we want - wait = SysProperties.MIN_WRITE_DELAY; - } - try { - Thread.sleep(wait); - } catch (InterruptedException e) { - // ignore - } - } - databaseRef = null; - } - - /** - * Stop the thread. This method is called when closing the database. - */ - public void stopThread() { - stop = true; - } - - /** - * Start the thread. This method is called after opening the database - * (to avoid deadlocks) - */ - public void startThread() { - thread.start(); - this.thread = null; - } - -} diff --git a/tools/h2/src/main/org/h2/store/fs/FileObject.java b/tools/h2/src/main/org/h2/store/fs/FileObject.java deleted file mode 100755 index e8d82d5..0000000 --- a/tools/h2/src/main/org/h2/store/fs/FileObject.java +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.store.fs; - -import java.io.IOException; - -/** - * This interface represents a random access file. - */ -public interface FileObject { - - /** - * Get the length of the file. - * - * @return the length - */ - long length() throws IOException; - - /** - * Close the file. - */ - void close() throws IOException; - - /** - * Read from the file. - * @param b the byte array - * @param off the offset - * @param len the number of bytes - */ - void readFully(byte[] b, int off, int len) throws IOException; - - /** - * Go to the specified position in the file. - * - * @param pos the new position - */ - void seek(long pos) throws IOException; - - /** - * Write to the file. - * - * @param b the byte array - * @param off the offset - * @param len the number of bytes - */ - void write(byte[] b, int off, int len) throws IOException; - - /** - * Get the file pointer. - * - * @return the current file pointer - */ - long getFilePointer() throws IOException; - - /** - * Force changes to the physical location. - */ - void sync() throws IOException; - - /** - * Change the length of the file. - * - * @param newLength the new length - */ - void setFileLength(long newLength) throws IOException; - - /** - * Get the full qualified name of this file. - * - * @return the name - */ - String getName(); - -} diff --git a/tools/h2/src/main/org/h2/store/fs/FileObjectDisk.java b/tools/h2/src/main/org/h2/store/fs/FileObjectDisk.java deleted file mode 100755 index b5f52b7..0000000 --- a/tools/h2/src/main/org/h2/store/fs/FileObjectDisk.java +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.store.fs; - -import java.io.FileNotFoundException; -import java.io.IOException; -import java.io.RandomAccessFile; -import org.h2.constant.SysProperties; -import org.h2.util.IOUtils; - -/** - * This class is extends a java.io.RandomAccessFile. - */ -public class FileObjectDisk extends RandomAccessFile implements FileObject { - - private final String name; - - FileObjectDisk(String fileName, String mode) throws FileNotFoundException { - super(fileName, mode); - this.name = fileName; - } - - public void sync() throws IOException { - String m = SysProperties.SYNC_METHOD; - if ("".equals(m)) { - // do nothing - } else if ("sync".equals(m)) { - getFD().sync(); - } else if ("force".equals(m)) { - getChannel().force(true); - } else if ("forceFalse".equals(m)) { - getChannel().force(false); - } else { - getFD().sync(); - } - } - - public void setFileLength(long newLength) throws IOException { - IOUtils.setLength(this, newLength); - } - - public String getName() { - return name; - } - -} diff --git a/tools/h2/src/main/org/h2/store/fs/FileObjectDiskChannel.java b/tools/h2/src/main/org/h2/store/fs/FileObjectDiskChannel.java deleted file mode 100755 index 8e389c8..0000000 --- a/tools/h2/src/main/org/h2/store/fs/FileObjectDiskChannel.java +++ /dev/null @@ -1,89 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: Jan Kotek - */ -package org.h2.store.fs; - -import java.io.FileNotFoundException; -import java.io.IOException; -import java.io.RandomAccessFile; -import java.nio.ByteBuffer; -import java.nio.channels.FileChannel; - -/** - * File which uses NIO FileChannel. - */ -public class FileObjectDiskChannel implements FileObject { - - private final String name; - private FileChannel channel; - - FileObjectDiskChannel(String fileName, String mode) throws FileNotFoundException { - this.name = fileName; - RandomAccessFile file = new RandomAccessFile(fileName, mode); - channel = file.getChannel(); - } - - public void close() throws IOException { - channel.close(); - } - - public long getFilePointer() throws IOException { - return channel.position(); - } - - public String getName() { - return name; - } - - public long length() throws IOException { - return channel.size(); - } - - public void readFully(byte[] b, int off, int len) throws IOException { - if (len == 0) { - return; - } - // reading the size can reduce the performance - // if (channel.size() <= off + len) { - // throw new java.io.EOFException(); - // } - ByteBuffer buf = ByteBuffer.wrap(b); - buf.position(off); - buf.limit(off + len); - channel.read(buf); - } - - public void seek(long pos) throws IOException { - channel.position(pos); - } - - public void setFileLength(long newLength) throws IOException { - if (newLength <= channel.size()) { - long oldPos = channel.position(); - channel.truncate(newLength); - if (oldPos > newLength) { - oldPos = newLength; - } - channel.position(oldPos); - } else { - // extend by writing to the new location - ByteBuffer b = ByteBuffer.allocate(1); - channel.write(b, newLength - 1); - } - } - - public void sync() throws IOException { - channel.force(true); - } - - public void write(byte[] b, int off, int len) throws IOException { - ByteBuffer buf = ByteBuffer.wrap(b); - buf.position(off); - buf.limit(off + len); - channel.write(buf); - } - -} diff --git a/tools/h2/src/main/org/h2/store/fs/FileObjectDiskMapped.java b/tools/h2/src/main/org/h2/store/fs/FileObjectDiskMapped.java deleted file mode 100755 index 777abde..0000000 --- a/tools/h2/src/main/org/h2/store/fs/FileObjectDiskMapped.java +++ /dev/null @@ -1,147 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: Jan Kotek - */ -package org.h2.store.fs; - -import java.io.IOException; -import java.io.RandomAccessFile; -import java.lang.ref.WeakReference; -import java.lang.reflect.Method; -import java.nio.MappedByteBuffer; -import java.nio.channels.FileChannel.MapMode; -import org.h2.constant.SysProperties; -import org.h2.util.IOUtils; - -/** - * FileObject which is using NIO MappedByteBuffer mapped to memory from file. - */ -public class FileObjectDiskMapped implements FileObject { - - // TODO support files over 2 GB by using multiple buffers - private static final long GC_TIMEOUT_MS = 10000; - private final String name; - private final MapMode mode; - private RandomAccessFile file; - private MappedByteBuffer mapped; - - FileObjectDiskMapped(String fileName, String mode) throws IOException { - if ("r".equals(mode)) { - this.mode = MapMode.READ_ONLY; - } else { - this.mode = MapMode.READ_WRITE; - } - this.name = fileName; - file = new RandomAccessFile(fileName, mode); - reMap(); - } - - private void unMap() throws IOException { - if (mapped != null) { - // first write all data - mapped.force(); - - // need to dispose old direct buffer, see bug - // http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4724038 - - boolean useSystemGc; - if (SysProperties.NIO_CLEANER_HACK) { - try { - useSystemGc = false; - Method cleanerMethod = mapped.getClass().getMethod("cleaner"); - cleanerMethod.setAccessible(true); - Object cleaner = cleanerMethod.invoke(mapped); - Method clearMethod = cleaner.getClass().getMethod("clear"); - clearMethod.invoke(cleaner); - } catch (Throwable e) { - useSystemGc = true; - } - } else { - useSystemGc = true; - } - if (useSystemGc) { - WeakReference bufferWeakRef = new WeakReference(mapped); - mapped = null; - long start = System.currentTimeMillis(); - while (bufferWeakRef.get() != null) { - if (System.currentTimeMillis() - start > GC_TIMEOUT_MS) { - throw new IOException("Timeout (" + GC_TIMEOUT_MS - + " ms) reached while trying to GC mapped buffer"); - } - System.gc(); - Thread.yield(); - } - } - } - } - - /** - * Re-map byte buffer into memory, called when file size has changed or file - * was created. - */ - private void reMap() throws IOException { - if (file.length() > Integer.MAX_VALUE) { - throw new IOException("File over 2GB is not supported yet"); - } - int oldPos = 0; - if (mapped != null) { - oldPos = mapped.position(); - mapped.force(); - unMap(); - } - - // maps new MappedByteBuffer, old one is disposed during GC - mapped = file.getChannel().map(mode, 0, file.length()); - if (SysProperties.NIO_LOAD_MAPPED) { - mapped.load(); - } - mapped.position(oldPos); - } - - public void close() throws IOException { - unMap(); - file.close(); - file = null; - } - - public long getFilePointer() { - return mapped.position(); - } - - public String getName() { - return name; - } - - public long length() throws IOException { - return file.length(); - } - - public void readFully(byte[] b, int off, int len) { - mapped.get(b, off, len); - } - - public void seek(long pos) { - mapped.position((int) pos); - } - - public void setFileLength(long newLength) throws IOException { - IOUtils.setLength(file, newLength); - reMap(); - } - - public void sync() throws IOException { - file.getFD().sync(); - mapped.force(); - } - - public void write(byte[] b, int off, int len) throws IOException { - // check if need to expand file - if (mapped.capacity() < mapped.position() + len) { - setFileLength(mapped.position() + len); - } - mapped.put(b, off, len); - } - -} diff --git a/tools/h2/src/main/org/h2/store/fs/FileObjectInputStream.java b/tools/h2/src/main/org/h2/store/fs/FileObjectInputStream.java deleted file mode 100755 index a824137..0000000 --- a/tools/h2/src/main/org/h2/store/fs/FileObjectInputStream.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.store.fs; - -import java.io.IOException; -import java.io.InputStream; - -/** - * Allows to read from a file object like an input stream. - */ -public class FileObjectInputStream extends InputStream { - - private FileObject file; - private byte[] buffer = { 0 }; - - /** - * Create a new file object input stream from the file object. - * - * @param file the file object - */ - public FileObjectInputStream(FileObject file) { - this.file = file; - } - - public int read() throws IOException { - if (file.getFilePointer() >= file.length()) { - return -1; - } - file.readFully(buffer, 0, 1); - return buffer[0] & 0xff; - } - - public int read(byte[] b) throws IOException { - return read(b, 0, b.length); - } - - public int read(byte[] b, int off, int len) throws IOException { - if (file.getFilePointer() + len < file.length()) { - file.readFully(b, off, len); - return len; - } - return super.read(b, off, len); - } - - public void close() throws IOException { - file.close(); - } - -} diff --git a/tools/h2/src/main/org/h2/store/fs/FileObjectMemory.java b/tools/h2/src/main/org/h2/store/fs/FileObjectMemory.java deleted file mode 100755 index e9f1762..0000000 --- a/tools/h2/src/main/org/h2/store/fs/FileObjectMemory.java +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.store.fs; - -import java.io.IOException; - -/** - * This class represents an in-memory file. - */ -public class FileObjectMemory implements FileObject { - - private final FileObjectMemoryData data; - private long pos; - - FileObjectMemory(FileObjectMemoryData data) { - this.data = data; - } - - public long length() { - return data.length(); - } - - public void setFileLength(long newLength) throws IOException { - data.touch(); - if (newLength < length()) { - pos = Math.min(pos, newLength); - } - data.setFileLength(newLength); - } - - public void seek(long newPos) { - this.pos = (int) newPos; - } - - public void write(byte[] b, int off, int len) throws IOException { - data.touch(); - pos = data.readWrite(pos, b, off, len, true); - } - - public void readFully(byte[] b, int off, int len) throws IOException { - pos = data.readWrite(pos, b, off, len, false); - } - - public long getFilePointer() { - return pos; - } - - public void close() { - pos = 0; - } - - public void sync() { - // do nothing - } - - public void setName(String name) { - data.setName(name); - } - - public String getName() { - return data.getName(); - } - - public long getLastModified() { - return data.getLastModified(); - } - -} diff --git a/tools/h2/src/main/org/h2/store/fs/FileObjectMemoryData.java b/tools/h2/src/main/org/h2/store/fs/FileObjectMemoryData.java deleted file mode 100755 index e846a96..0000000 --- a/tools/h2/src/main/org/h2/store/fs/FileObjectMemoryData.java +++ /dev/null @@ -1,298 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.store.fs; - -import java.io.EOFException; -import java.io.IOException; -import java.util.LinkedHashMap; -import java.util.Map; -import org.h2.compress.CompressLZF; -import org.h2.util.MathUtils; - -/** - * This class contains the data of an in-memory random access file. - * Data compression using the LZF algorithm is supported as well. - */ -class FileObjectMemoryData { - - private static final int CACHE_SIZE = 8; - private static final int BLOCK_SIZE_SHIFT = 10; - private static final int BLOCK_SIZE = 1 << BLOCK_SIZE_SHIFT; - private static final int BLOCK_SIZE_MASK = BLOCK_SIZE - 1; - private static final CompressLZF LZF = new CompressLZF(); - private static final byte[] BUFFER = new byte[BLOCK_SIZE * 2]; - private static final byte[] COMPRESSED_EMPTY_BLOCK; - -//## Java 1.4 begin ## - private static final Cache COMPRESS_LATER = new Cache(CACHE_SIZE); -//## Java 1.4 end ## - - private String name; - private final boolean compress; - private long length; - private byte[][] data; - private long lastModified; - private boolean isReadOnly; - - static { - byte[] n = new byte[BLOCK_SIZE]; - int len = LZF.compress(n, BLOCK_SIZE, BUFFER, 0); - COMPRESSED_EMPTY_BLOCK = new byte[len]; - System.arraycopy(BUFFER, 0, COMPRESSED_EMPTY_BLOCK, 0, len); - } - - /** - * This small cache compresses the data if an element leaves the cache. - */ -//## Java 1.4 begin ## - static class Cache extends LinkedHashMap { - - private static final long serialVersionUID = 1L; - private int size; - - Cache(int size) { - super(size, (float) 0.75, true); - this.size = size; - } - - protected boolean removeEldestEntry(Map.Entry eldest) { - if (size() < size) { - return false; - } - CompressItem c = (CompressItem) eldest.getKey(); - compress(c.data, c.page); - return true; - } - } - - /** - * Represents a compressed item. - */ - static class CompressItem { - - /** - * The file data. - */ - byte[][] data; - - /** - * The page to compress. - */ - int page; - - public int hashCode() { - return page; - } - - public boolean equals(Object o) { - if (o instanceof CompressItem) { - CompressItem c = (CompressItem) o; - return c.data == data && c.page == page; - } - return false; - } - } -//## Java 1.4 end ## - - FileObjectMemoryData(String name, boolean compress) { - this.name = name; - this.compress = compress; - data = new byte[0][]; - lastModified = System.currentTimeMillis(); - } - - private static void compressLater(byte[][] data, int page) { -//## Java 1.4 begin ## - CompressItem c = new CompressItem(); - c.data = data; - c.page = page; - synchronized (LZF) { - COMPRESS_LATER.put(c, c); - } -//## Java 1.4 end ## - } - - private static void expand(byte[][] data, int page) { - byte[] d = data[page]; - if (d.length == BLOCK_SIZE) { - return; - } - byte[] out = new byte[BLOCK_SIZE]; - if (d != COMPRESSED_EMPTY_BLOCK) { - synchronized (LZF) { - LZF.expand(d, 0, d.length, out, 0, BLOCK_SIZE); - } - } - data[page] = out; - } - - /** - * Compress the data in a byte array. - * - * @param data the page array - * @param page which page to compress - */ - static void compress(byte[][] data, int page) { - byte[] d = data[page]; - synchronized (LZF) { - int len = LZF.compress(d, BLOCK_SIZE, BUFFER, 0); - if (len <= BLOCK_SIZE) { - d = new byte[len]; - System.arraycopy(BUFFER, 0, d, 0, len); - data[page] = d; - } - } - } - - /** - * Update the last modified time. - */ - void touch() throws IOException { - if (isReadOnly) { - throw new IOException("Read only"); - } - lastModified = System.currentTimeMillis(); - } - - /** - * Get the file length. - * - * @return the length - */ - long length() { - return length; - } - - /** - * Change the file length. - * - * @param newLength the new length - */ - void setFileLength(long newLength) { - if (newLength < length) { - changeLength(newLength); - long end = MathUtils.roundUpLong(newLength, BLOCK_SIZE); - if (end != newLength) { - int lastPage = (int) (newLength >>> BLOCK_SIZE_SHIFT); - expand(data, lastPage); - byte[] d = data[lastPage]; - for (int i = (int) (newLength & BLOCK_SIZE_MASK); i < BLOCK_SIZE; i++) { - d[i] = 0; - } - if (compress) { - compressLater(data, lastPage); - } - } - } else { - changeLength(newLength); - } - } - - private void changeLength(long len) { - length = len; - len = MathUtils.roundUpLong(len, BLOCK_SIZE); - int blocks = (int) (len >>> BLOCK_SIZE_SHIFT); - if (blocks != data.length) { - byte[][] n = new byte[blocks][]; - System.arraycopy(data, 0, n, 0, Math.min(data.length, n.length)); - for (int i = data.length; i < blocks; i++) { - n[i] = COMPRESSED_EMPTY_BLOCK; - } - data = n; - } - } - - /** - * Read or write. - * - * @param pos the position - * @param b the byte array - * @param off the offset within the byte array - * @param len the number of bytes - * @param write true for writing - * @return the new position - */ - long readWrite(long pos, byte[] b, int off, int len, boolean write) throws IOException { - long end = pos + len; - if (end > length) { - if (write) { - changeLength(end); - } else { - if (len == 0) { - return pos; - } - throw new EOFException("File: " + name); - } - } - while (len > 0) { - int l = (int) Math.min(len, BLOCK_SIZE - (pos & BLOCK_SIZE_MASK)); - int page = (int) (pos >>> BLOCK_SIZE_SHIFT); - expand(data, page); - byte[] block = data[page]; - int blockOffset = (int) (pos & BLOCK_SIZE_MASK); - if (write) { - System.arraycopy(b, off, block, blockOffset, l); - } else { - System.arraycopy(block, blockOffset, b, off, l); - } - if (compress) { - compressLater(data, page); - } - off += l; - pos += l; - len -= l; - } - return pos; - } - - /** - * Set the file name. - * - * @param name the name - */ - void setName(String name) { - this.name = name; - } - - /** - * Get the file name - * - * @return the name - */ - String getName() { - return name; - } - - /** - * Get the last modified time. - * - * @return the time - */ - long getLastModified() { - return lastModified; - } - - /** - * Check whether writing is allowed. - * - * @return true if it is - */ - boolean canWrite() { - return !isReadOnly; - } - - /** - * Set the read-only flag. - * - * @return true - */ - boolean setReadOnly() { - isReadOnly = true; - return true; - } - -} diff --git a/tools/h2/src/main/org/h2/store/fs/FileObjectOutputStream.java b/tools/h2/src/main/org/h2/store/fs/FileObjectOutputStream.java deleted file mode 100755 index 92b70ba..0000000 --- a/tools/h2/src/main/org/h2/store/fs/FileObjectOutputStream.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.store.fs; - -import java.io.IOException; -import java.io.OutputStream; - -/** - * Allows to write to a file object like an output stream. - */ -public class FileObjectOutputStream extends OutputStream { - - private FileObject file; - private byte[] buffer = { 0 }; - - /** - * Create a new file object output stream from the file object. - * - * @param file the file object - * @param append true for append mode, false for truncate and overwrite - */ - public FileObjectOutputStream(FileObject file, boolean append) throws IOException { - this.file = file; - if (append) { - file.seek(file.length()); - } else { - file.seek(0); - file.setFileLength(0); - } - } - - public void write(int b) throws IOException { - buffer[0] = (byte) b; - file.write(buffer, 0, 1); - } - - public void write(byte[] b) throws IOException { - file.write(b, 0, b.length); - } - - public void write(byte[] b, int off, int len) throws IOException { - file.write(b, off, len); - } - - public void close() throws IOException { - file.close(); - } - -} diff --git a/tools/h2/src/main/org/h2/store/fs/FileObjectSplit.java b/tools/h2/src/main/org/h2/store/fs/FileObjectSplit.java deleted file mode 100755 index 3a20f6c..0000000 --- a/tools/h2/src/main/org/h2/store/fs/FileObjectSplit.java +++ /dev/null @@ -1,155 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.store.fs; - -import java.io.IOException; -import org.h2.message.DbException; -import org.h2.util.IOUtils; - -/** - * A file that may be split into multiple smaller files. - */ -public class FileObjectSplit implements FileObject { - - private final String name; - private final String mode; - private final long maxLength; - private FileObject[] list; - private long filePointer; - private long length; - - FileObjectSplit(String name, String mode, FileObject[] list, long length, long maxLength) { - this.name = name; - this.mode = mode; - this.list = list; - this.length = length; - this.maxLength = maxLength; - } - - public void close() throws IOException { - for (FileObject f : list) { - f.close(); - } - } - - public long getFilePointer() { - return filePointer; - } - - public long length() { - return length; - } - - private int read(byte[] b, int off, int len) throws IOException { - long offset = filePointer % maxLength; - int l = (int) Math.min(len, maxLength - offset); - FileObject fo = getFileObject(); - fo.seek(offset); - fo.readFully(b, off, l); - filePointer += l; - return l; - } - - public void readFully(byte[] b, int off, int len) throws IOException { - while (true) { - int l = read(b, off, len); - len -= l; - if (len <= 0) { - return; - } - off += l; - } - } - - public void seek(long pos) { - filePointer = pos; - } - - private FileObject getFileObject() throws IOException { - int id = (int) (filePointer / maxLength); - while (id >= list.length) { - int i = list.length; - FileObject[] newList = new FileObject[i + 1]; - System.arraycopy(list, 0, newList, 0, i); - String fileName = FileSystemSplit.getFileName(name, i); - newList[i] = FileSystem.getInstance(fileName).openFileObject(fileName, mode); - list = newList; - } - return list[id]; - } - - public void setFileLength(long newLength) throws IOException { - filePointer = Math.min(filePointer, newLength); - int newFileCount = 1 + (int) (newLength / maxLength); - if (newFileCount == list.length) { - long size = newLength - maxLength * (newFileCount - 1); - list[list.length - 1].setFileLength(size); - } else { - FileObject[] newList = new FileObject[newFileCount]; - int max = Math.max(newFileCount, list.length); - long remaining = newLength; - for (int i = 0; i < max; i++) { - long size = Math.min(remaining, maxLength); - remaining -= size; - if (i >= newFileCount) { - list[i].close(); - try { - IOUtils.delete(list[i].getName()); - } catch (DbException e) { - throw DbException.convertToIOException(e); - } - } else if (i >= list.length) { - String fileName = FileSystemSplit.getFileName(name, i); - FileObject o = FileSystem.getInstance(fileName).openFileObject(fileName, mode); - o.setFileLength(size); - newList[i] = o; - } else { - FileObject o = list[i]; - if (o.length() != size) { - o.setFileLength(size); - } - newList[i] = list[i]; - } - } - list = newList; - } - this.length = newLength; - } - - public void sync() throws IOException { - for (FileObject f : list) { - f.sync(); - } - } - - public void write(byte[] b, int off, int len) throws IOException { - while (true) { - int l = writePart(b, off, len); - len -= l; - if (len <= 0) { - return; - } - off += l; - } - } - - private int writePart(byte[] b, int off, int len) throws IOException { - long offset = filePointer % maxLength; - int l = (int) Math.min(len, maxLength - offset); - FileObject fo = getFileObject(); - fo.seek(offset); - fo.write(b, off, l); - filePointer += l; - length = Math.max(length, filePointer); - return l; - } - - public String getName() { - return name; - } - -} diff --git a/tools/h2/src/main/org/h2/store/fs/FileObjectZip.java b/tools/h2/src/main/org/h2/store/fs/FileObjectZip.java deleted file mode 100755 index 29822a0..0000000 --- a/tools/h2/src/main/org/h2/store/fs/FileObjectZip.java +++ /dev/null @@ -1,110 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.store.fs; - -import java.io.EOFException; -import java.io.IOException; -import java.io.InputStream; -import java.util.zip.ZipEntry; -import java.util.zip.ZipFile; - -import org.h2.util.IOUtils; - -/** - * The file is read from a stream. When reading from start to end, the same - * input stream is re-used, however when reading from end to start, a new input - * stream is opened for each request. - */ -public class FileObjectZip implements FileObject { - - private static final byte[] SKIP_BUFFER = new byte[1024]; - - private ZipFile file; - private ZipEntry entry; - private long pos; - private InputStream in; - private long inPos; - private long length; - private boolean skipUsingRead; - - FileObjectZip(ZipFile file, ZipEntry entry) { - this.file = file; - this.entry = entry; - length = entry.getSize(); - } - - public void close() { - // nothing to do - } - - public long getFilePointer() { - return pos; - } - - public long length() { - return length; - } - - public void readFully(byte[] b, int off, int len) throws IOException { - if (inPos > pos) { - if (in != null) { - in.close(); - } - in = null; - } - if (in == null) { - in = file.getInputStream(entry); - inPos = 0; - } - if (inPos < pos) { - long skip = pos - inPos; - if (!skipUsingRead) { - try { - IOUtils.skipFully(in, skip); - } catch (NullPointerException e) { - // workaround for Google Android - skipUsingRead = true; - } - } - if (skipUsingRead) { - while (skip > 0) { - int s = (int) Math.min(SKIP_BUFFER.length, skip); - s = in.read(SKIP_BUFFER, 0, s); - skip -= s; - } - } - inPos = pos; - } - int l = IOUtils.readFully(in, b, off, len); - if (l != len) { - throw new EOFException(); - } - pos += len; - inPos += len; - } - - public void seek(long newPos) { - this.pos = newPos; - } - - public void setFileLength(long newLength) throws IOException { - throw new IOException("File is read-only"); - } - - public void sync() { - // nothing to do - } - - public void write(byte[] b, int off, int len) throws IOException { - throw new IOException("File is read-only"); - } - - public String getName() { - return file.getName(); - } - -} diff --git a/tools/h2/src/main/org/h2/store/fs/FileSystem.java b/tools/h2/src/main/org/h2/store/fs/FileSystem.java deleted file mode 100755 index e5f7e2c..0000000 --- a/tools/h2/src/main/org/h2/store/fs/FileSystem.java +++ /dev/null @@ -1,340 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.store.fs; - -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.util.ArrayList; -import org.h2.util.MathUtils; -import org.h2.util.New; -import org.h2.util.Utils; - -/** - * The file system is a storage abstraction. - */ -public abstract class FileSystem { - - /** - * The prefix for temporary files. See also TestClearReferences. - */ - private static String tempRandom; - private static long tempSequence; - - private static boolean defaultServicesRegistered; - - private static final ArrayList SERVICES = New.arrayList(); - - /** - * Get the file system object. - * - * @param fileName the file name or prefix - * @return the file system - */ - public static FileSystem getInstance(String fileName) { - if (fileName.indexOf(':') >= 0) { - if (FileSystemMemory.getInstance().accepts(fileName)) { - return FileSystemMemory.getInstance(); - } - registerDefaultServices(); - for (FileSystem fs : SERVICES) { - if (fs.accepts(fileName)) { - return fs; - } - } - } - return FileSystemDisk.getInstance(); - } - - private static synchronized void registerDefaultServices() { - if (!defaultServicesRegistered) { - defaultServicesRegistered = true; - for (String c : new String[] { - "org.h2.store.fs.FileSystemZip", - "org.h2.store.fs.FileSystemSplit", - "org.h2.store.fs.FileSystemDiskNio", - "org.h2.store.fs.FileSystemDiskNioMapped" - }) { - try { - Class.forName(c); - } catch (Exception e) { - // ignore - the files may be excluded in purpose - } - } - } - } - - /** - * Register a file system. - * - * @param service the file system - */ - public static synchronized void register(FileSystem service) { - registerDefaultServices(); - SERVICES.add(service); - } - - /** - * Unregister a file system. - * - * @param service the file system - */ - public static synchronized void unregister(FileSystem service) { - SERVICES.remove(service); - } - - /** - * Check if the file system is responsible for this file name. - * - * @param fileName the file name - * @return true if it is - */ - protected abstract boolean accepts(String fileName); - - /** - * Get the length of a file. - * - * @param fileName the file name - * @return the length in bytes - */ - public abstract long length(String fileName); - - /** - * Rename a file if this is allowed. - * - * @param oldName the old fully qualified file name - * @param newName the new fully qualified file name - */ - public abstract void rename(String oldName, String newName); - - /** - * Create a new file. - * - * @param fileName the file name - * @return true if creating was successful - */ - public abstract boolean createNewFile(String fileName); - - /** - * Checks if a file exists. - * - * @param fileName the file name - * @return true if it exists - */ - public abstract boolean exists(String fileName); - - /** - * Delete a file. - * - * @param fileName the file name - */ - public abstract void delete(String fileName); - - /** - * Try to delete a file. - * - * @param fileName the file name - * @return true if it could be deleted - */ - public abstract boolean tryDelete(String fileName); - - /** - * List the files in the given directory. - * - * @param directory the directory - * @return the list of fully qualified file names - */ - public abstract String[] listFiles(String directory); - - /** - * Delete a directory or file and all subdirectories and files. - * - * @param directory the directory - * @param tryOnly whether errors should be ignored - */ - public abstract void deleteRecursive(String directory, boolean tryOnly); - - /** - * Check if a file is read-only. - * - * @param fileName the file name - * @return if it is read only - */ - public abstract boolean isReadOnly(String fileName); - - /** - * Normalize a file name. - * - * @param fileName the file name - * @return the normalized file name - */ - public abstract String normalize(String fileName); - - /** - * Get the parent directory of a file or directory. - * - * @param fileName the file or directory name - * @return the parent directory name - */ - public abstract String getParent(String fileName); - - /** - * Check if it is a file or a directory. - * - * @param fileName the file or directory name - * @return true if it is a directory - */ - public abstract boolean isDirectory(String fileName); - - /** - * Check if the file name includes a path. - * - * @param fileName the file name - * @return if the file name is absolute - */ - public abstract boolean isAbsolute(String fileName); - - /** - * Get the absolute file name. - * - * @param fileName the file name - * @return the absolute file name - */ - public abstract String getAbsolutePath(String fileName); - - /** - * Get the last modified date of a file - * - * @param fileName the file name - * @return the last modified date - */ - public abstract long getLastModified(String fileName); - - /** - * Check if the file is writable. - * - * @param fileName the file name - * @return if the file is writable - */ - public abstract boolean canWrite(String fileName); - - /** - * Copy a file from one directory to another, or to another file. - * - * @param original the original file name - * @param copy the file name of the copy - */ - public abstract void copy(String original, String copy); - - /** - * Create all required directories. - * - * @param directoryName the directory name - */ - public void mkdirs(String directoryName) { - createDirs(directoryName + "/x"); - } - - /** - * Create all required directories that are required for this file. - * - * @param fileName the file name (not directory name) - */ - public abstract void createDirs(String fileName); - - /** - * Get the file name (without directory part). - * - * @param name the directory and file name - * @return just the file name - */ - public abstract String getFileName(String name); - - /** - * Check if a file starts with a given prefix. - * - * @param fileName the complete file name - * @param prefix the prefix - * @return true if it starts with the prefix - */ - public abstract boolean fileStartsWith(String fileName, String prefix); - - /** - * Create an output stream to write into the file. - * - * @param fileName the file name - * @param append if true, the file will grow, if false, the file will be - * truncated first - * @return the output stream - */ - public abstract OutputStream openFileOutputStream(String fileName, boolean append); - - /** - * Open a random access file object. - * - * @param fileName the file name - * @param mode the access mode. Supported are r, rw, rws, rwd - * @return the file object - */ - public abstract FileObject openFileObject(String fileName, String mode) throws IOException; - - /** - * Create an input stream to read from the file. - * - * @param fileName the file name - * @return the input stream - */ - public abstract InputStream openFileInputStream(String fileName) throws IOException; - - /** - * Disable the ability to write. - * - * @param fileName the file name - * @return true if the call was successful - */ - public abstract boolean setReadOnly(String fileName); - - /** - * Get the next temporary file name part (the part in the middle). - * - * @param newRandom if the random part of the filename should change - * @return the file name part - */ - protected synchronized String getNextTempFileNamePart(boolean newRandom) { - if (newRandom || tempRandom == null) { - byte[] prefix = new byte[8]; - MathUtils.randomBytes(prefix); - tempRandom = Utils.convertBytesToString(prefix) + "."; - } - return tempRandom + tempSequence++; - } - - /** - * Create a new temporary file. - * - * @param prefix the prefix of the file name (including directory name if - * required) - * @param suffix the suffix - * @param deleteOnExit if the file should be deleted when the virtual - * machine exists - * @param inTempDir if the file should be stored in the temporary directory - * @return the name of the created file - */ - public String createTempFile(String prefix, String suffix, boolean deleteOnExit, boolean inTempDir) throws IOException { - while (true) { - String n = prefix + getNextTempFileNamePart(false) + suffix; - if (exists(n)) { - // in theory, the random number could collide - getNextTempFileNamePart(true); - } - // creates the file (not thread safe) - openFileObject(n, "rw").close(); - return n; - } - } - -} diff --git a/tools/h2/src/main/org/h2/store/fs/FileSystemDisk.java b/tools/h2/src/main/org/h2/store/fs/FileSystemDisk.java deleted file mode 100755 index ed0138b..0000000 --- a/tools/h2/src/main/org/h2/store/fs/FileSystemDisk.java +++ /dev/null @@ -1,458 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.store.fs; - -import java.io.File; -import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.io.RandomAccessFile; -import java.net.URL; - -import org.h2.constant.ErrorCode; -import org.h2.constant.SysProperties; -import org.h2.engine.Constants; -import org.h2.message.DbException; -import org.h2.util.IOUtils; -import org.h2.util.StringUtils; - -/** - * This file system stores files on disk. - * This is the most common file system. - */ -public class FileSystemDisk extends FileSystem { - - private static final FileSystemDisk INSTANCE = new FileSystemDisk(); - // TODO detection of 'case in sensitive filesystem' - // could maybe implemented using some other means - private static final boolean IS_FILE_SYSTEM_CASE_INSENSITIVE = File.separatorChar == '\\'; - - protected FileSystemDisk() { - // nothing to do - } - - public static FileSystemDisk getInstance() { - return INSTANCE; - } - - public long length(String fileName) { - fileName = translateFileName(fileName); - return new File(fileName).length(); - } - - /** - * Translate the file name to the native format. - * This will expand the home directory (~). - * - * @param fileName the file name - * @return the native file name - */ - protected String translateFileName(String fileName) { - return expandUserHomeDirectory(fileName); - } - - /** - * Expand '~' to the user home directory. It is only be expanded if the ~ - * stands alone, or is followed by / or \. - * - * @param fileName the file name - * @return the native file name - */ - public static String expandUserHomeDirectory(String fileName) { - if (fileName == null) { - return null; - } - if (fileName.startsWith("~") && (fileName.length() == 1 || fileName.startsWith("~/") || fileName.startsWith("~\\"))) { - String userDir = SysProperties.USER_HOME; - fileName = userDir + fileName.substring(1); - } - return fileName; - } - - public void rename(String oldName, String newName) { - oldName = translateFileName(oldName); - newName = translateFileName(newName); - File oldFile = new File(oldName); - File newFile = new File(newName); - if (oldFile.getAbsolutePath().equals(newFile.getAbsolutePath())) { - DbException.throwInternalError("rename file old=new"); - } - if (!oldFile.exists()) { - throw DbException.get(ErrorCode.FILE_RENAME_FAILED_2, - oldName + " (not found)", - newName); - } - if (newFile.exists()) { - throw DbException.get(ErrorCode.FILE_RENAME_FAILED_2, - new String[] { oldName, newName + " (exists)" }); - } - for (int i = 0; i < SysProperties.MAX_FILE_RETRY; i++) { - trace("rename", oldName + " >" + newName, null); - boolean ok = oldFile.renameTo(newFile); - if (ok) { - return; - } - wait(i); - } - throw DbException.get(ErrorCode.FILE_RENAME_FAILED_2, new String[]{oldName, newName}); - } - - /** - * Print a trace message if tracing is enabled. - * - * @param method the method - * @param fileName the file name - * @param o the object - */ - protected void trace(String method, String fileName, Object o) { - if (SysProperties.TRACE_IO) { - System.out.println("FileSystem." + method + " " + fileName + " " + o); - } - } - - private static void wait(int i) { - if (i > 8) { - System.gc(); - } - try { - // sleep at most 256 ms - long sleep = Math.min(256, i * i); - Thread.sleep(sleep); - } catch (InterruptedException e) { - // ignore - } - } - - public boolean createNewFile(String fileName) { - fileName = translateFileName(fileName); - File file = new File(fileName); - for (int i = 0; i < SysProperties.MAX_FILE_RETRY; i++) { - try { - return file.createNewFile(); - } catch (IOException e) { - // 'access denied' is really a concurrent access problem - wait(i); - } - } - return false; - } - - public boolean exists(String fileName) { - fileName = translateFileName(fileName); - return new File(fileName).exists(); - } - - public void delete(String fileName) { - fileName = translateFileName(fileName); - File file = new File(fileName); - if (file.exists()) { - for (int i = 0; i < SysProperties.MAX_FILE_RETRY; i++) { - trace("delete", fileName, null); - boolean ok = file.delete(); - if (ok) { - return; - } - wait(i); - } - throw DbException.get(ErrorCode.FILE_DELETE_FAILED_1, fileName); - } - } - - public boolean tryDelete(String fileName) { - fileName = translateFileName(fileName); - trace("tryDelete", fileName, null); - return new File(fileName).delete(); - } - - public String createTempFile(String name, String suffix, boolean deleteOnExit, boolean inTempDir) - throws IOException { - name = translateFileName(name); - name += "."; - String prefix = new File(name).getName(); - File dir; - if (inTempDir) { - dir = null; - } else { - dir = new File(name).getAbsoluteFile().getParentFile(); - IOUtils.mkdirs(dir); - } - File f; - while (true) { - f = new File(dir, prefix + getNextTempFileNamePart(false) + suffix); - if (f.exists()) { - // in theory, the random number could collide - getNextTempFileNamePart(true); - } else { - break; - } - } - if (deleteOnExit) { - try { - f.deleteOnExit(); - } catch (Throwable e) { - // sometimes this throws a NullPointerException - // at java.io.DeleteOnExitHook.add(DeleteOnExitHook.java:33) - // we can ignore it - } - } - return f.getCanonicalPath(); - } - - public String[] listFiles(String path) { - path = translateFileName(path); - File f = new File(path); - try { - String[] list = f.list(); - if (list == null) { - return new String[0]; - } - String base = f.getCanonicalPath(); - if (!base.endsWith(File.separator)) { - base += File.separator; - } - for (int i = 0; i < list.length; i++) { - list[i] = base + list[i]; - } - return list; - } catch (IOException e) { - throw DbException.convertIOException(e, path); - } - } - - public void deleteRecursive(String fileName, boolean tryOnly) { - fileName = translateFileName(fileName); - if (IOUtils.isDirectory(fileName)) { - String[] list = listFiles(fileName); - for (int i = 0; list != null && i < list.length; i++) { - deleteRecursive(list[i], tryOnly); - } - } - if (tryOnly) { - tryDelete(fileName); - } else { - delete(fileName); - } - } - - public boolean isReadOnly(String fileName) { - fileName = translateFileName(fileName); - File f = new File(fileName); - return f.exists() && !canWriteInternal(f); - } - - public boolean setReadOnly(String fileName) { - fileName = translateFileName(fileName); - File f = new File(fileName); - return f.setReadOnly(); - } - - public String normalize(String fileName) { - fileName = translateFileName(fileName); - File f = new File(fileName); - try { - return f.getCanonicalPath(); - } catch (IOException e) { - throw DbException.convertIOException(e, fileName); - } - } - - public String getParent(String fileName) { - fileName = translateFileName(fileName); - return new File(fileName).getParent(); - } - - public boolean isDirectory(String fileName) { - fileName = translateFileName(fileName); - return new File(fileName).isDirectory(); - } - - public boolean isAbsolute(String fileName) { - fileName = translateFileName(fileName); - File file = new File(fileName); - return file.isAbsolute(); - } - - public String getAbsolutePath(String fileName) { - fileName = translateFileName(fileName); - File parent = new File(fileName).getAbsoluteFile(); - return parent.getAbsolutePath(); - } - - public long getLastModified(String fileName) { - fileName = translateFileName(fileName); - return new File(fileName).lastModified(); - } - - public boolean canWrite(String fileName) { - fileName = translateFileName(fileName); - return canWriteInternal(new File(fileName)); - } - - private boolean canWriteInternal(File file) { - try { - if (!file.canWrite()) { - return false; - } - } catch (Exception e) { - // workaround for GAE which throws a - // java.security.AccessControlException - return false; - } - // File.canWrite() does not respect windows user permissions, - // so we must try to open it using the mode "rw". - // See also http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4420020 - RandomAccessFile r = null; - try { - r = new RandomAccessFile(file, "rw"); - return true; - } catch (FileNotFoundException e) { - return false; - } finally { - if (r != null) { - try { - r.close(); - } catch (IOException e) { - // ignore - } - } - } - } - - public void copy(String original, String copy) { - original = translateFileName(original); - copy = translateFileName(copy); - OutputStream out = null; - InputStream in = null; - try { - out = IOUtils.openFileOutputStream(copy, false); - in = IOUtils.openFileInputStream(original); - byte[] buffer = new byte[Constants.IO_BUFFER_SIZE]; - while (true) { - int len = in.read(buffer); - if (len < 0) { - break; - } - out.write(buffer, 0, len); - } - out.close(); - } catch (IOException e) { - throw DbException.convertIOException(e, "original: " + original + " copy: " + copy); - } finally { - IOUtils.closeSilently(in); - IOUtils.closeSilently(out); - } - } - - public void createDirs(String fileName) { - fileName = translateFileName(fileName); - File f = new File(fileName); - if (!f.exists()) { - String parent = f.getParent(); - if (parent == null) { - return; - } - File dir = new File(parent); - for (int i = 0; i < SysProperties.MAX_FILE_RETRY; i++) { - if ((dir.exists() && dir.isDirectory()) || dir.mkdirs()) { - return; - } - wait(i); - } - throw DbException.get(ErrorCode.FILE_CREATION_FAILED_1, parent); - } - } - - public String getFileName(String name) { - name = translateFileName(name); - return new File(name).getName(); - } - - public boolean fileStartsWith(String fileName, String prefix) { - fileName = translateFileName(fileName); - if (IS_FILE_SYSTEM_CASE_INSENSITIVE) { - fileName = StringUtils.toUpperEnglish(fileName); - prefix = StringUtils.toUpperEnglish(prefix); - } - return fileName.startsWith(prefix); - } - - public OutputStream openFileOutputStream(String fileName, boolean append) { - fileName = translateFileName(fileName); - try { - File file = new File(fileName); - createDirs(file.getAbsolutePath()); - FileOutputStream out = new FileOutputStream(fileName, append); - trace("openFileOutputStream", fileName, out); - return out; - } catch (IOException e) { - freeMemoryAndFinalize(); - try { - return new FileOutputStream(fileName); - } catch (IOException e2) { - throw DbException.convertIOException(e, fileName); - } - } - } - - public InputStream openFileInputStream(String fileName) throws IOException { - if (fileName.indexOf(':') > 1) { - // if the : is in position 1, a windows file access is assumed: C:.. or D: - // otherwise an URL is assumed - URL url = new URL(fileName); - InputStream in = url.openStream(); - return in; - } - fileName = translateFileName(fileName); - FileInputStream in = new FileInputStream(fileName); - trace("openFileInputStream", fileName, in); - return in; - } - - /** - * Call the garbage collection and run finalization. This close all files that - * were not closed, and are no longer referenced. - */ - protected void freeMemoryAndFinalize() { - trace("freeMemoryAndFinalize", null, null); - Runtime rt = Runtime.getRuntime(); - long mem = rt.freeMemory(); - for (int i = 0; i < 16; i++) { - rt.gc(); - long now = rt.freeMemory(); - rt.runFinalization(); - if (now == mem) { - break; - } - mem = now; - } - } - - public FileObject openFileObject(String fileName, String mode) throws IOException { - fileName = translateFileName(fileName); - FileObjectDisk f; - try { - f = new FileObjectDisk(fileName, mode); - trace("openRandomAccessFile", fileName, f); - } catch (IOException e) { - freeMemoryAndFinalize(); - try { - f = new FileObjectDisk(fileName, mode); - } catch (IOException e2) { - throw e; - } - } - return f; - } - - protected boolean accepts(String fileName) { - return true; - } - -} diff --git a/tools/h2/src/main/org/h2/store/fs/FileSystemDiskNio.java b/tools/h2/src/main/org/h2/store/fs/FileSystemDiskNio.java deleted file mode 100755 index 0ad17cc..0000000 --- a/tools/h2/src/main/org/h2/store/fs/FileSystemDiskNio.java +++ /dev/null @@ -1,103 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: Jan Kotek - */ -package org.h2.store.fs; - -import java.io.IOException; -import java.io.InputStream; - -/** - * This file system stores files on disk and uses java.nio to access the files. - * This class uses FileChannel. - */ -public class FileSystemDiskNio extends FileSystemDisk { - - private static final String PREFIX = "nio:"; - - static { - FileSystem.register(new FileSystemDiskNio()); - } - - public String createTempFile(String name, String suffix, boolean deleteOnExit, boolean inTempDir) - throws IOException { - String file = super.createTempFile(name, suffix, deleteOnExit, inTempDir); - return getPrefix() + file; - } - - protected String translateFileName(String fileName) { - if (fileName.startsWith(getPrefix())) { - fileName = fileName.substring(getPrefix().length()); - } - return super.translateFileName(fileName); - } - - public InputStream openFileInputStream(String fileName) throws IOException { - return super.openFileInputStream(translateFileName(fileName)); - } - - public String normalize(String fileName) { - return getPrefix() + super.normalize(fileName); - } - - public String[] listFiles(String path) { - String[] list = super.listFiles(path); - for (int i = 0; list != null && i < list.length; i++) { - list[i] = getPrefix() + list[i]; - } - return list; - } - - public String getParent(String fileName) { - return getPrefix() + super.getParent(fileName); - } - - public String getAbsolutePath(String fileName) { - return getPrefix() + super.getAbsolutePath(fileName); - } - - public FileObject openFileObject(String fileName, String mode) throws IOException { - fileName = translateFileName(fileName); - FileObject f; - try { - f = open(fileName, mode); - trace("openRandomAccessFile", fileName, f); - } catch (IOException e) { - freeMemoryAndFinalize(); - try { - f = open(fileName, mode); - } catch (IOException e2) { - throw e; - } - } - return f; - } - - /** - * Get the prefix for this file system. - * - * @return the prefix - */ - protected String getPrefix() { - return PREFIX; - } - - /** - * Try to open a file with this name and mode. - * - * @param fileName the file name - * @param mode the open mode - * @return the file object - * @throws IOException if opening fails - */ - protected FileObject open(String fileName, String mode) throws IOException { - return new FileObjectDiskChannel(fileName, mode); - } - - protected boolean accepts(String fileName) { - return fileName.startsWith(getPrefix()); - } - -} diff --git a/tools/h2/src/main/org/h2/store/fs/FileSystemDiskNioMapped.java b/tools/h2/src/main/org/h2/store/fs/FileSystemDiskNioMapped.java deleted file mode 100755 index 5cddc31..0000000 --- a/tools/h2/src/main/org/h2/store/fs/FileSystemDiskNioMapped.java +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: Jan Kotek - */ -package org.h2.store.fs; - -import java.io.IOException; - -/** - * This file system stores files on disk and uses java.nio to access the files. - * This class used memory mapped files. - */ -public class FileSystemDiskNioMapped extends FileSystemDiskNio { - - private static final String PREFIX = "nioMapped:"; - - static { - FileSystem.register(new FileSystemDiskNioMapped()); - } - - protected String getPrefix() { - return PREFIX; - } - - protected FileObject open(String fileName, String mode) throws IOException { - return new FileObjectDiskMapped(fileName, mode); - } - -} diff --git a/tools/h2/src/main/org/h2/store/fs/FileSystemMemory.java b/tools/h2/src/main/org/h2/store/fs/FileSystemMemory.java deleted file mode 100755 index 807a62d..0000000 --- a/tools/h2/src/main/org/h2/store/fs/FileSystemMemory.java +++ /dev/null @@ -1,234 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.store.fs; - -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.util.ArrayList; -import java.util.Iterator; -import java.util.TreeMap; -import org.h2.message.DbException; -import org.h2.util.IOUtils; -import org.h2.util.New; - -/** - * This file system keeps files fully in memory. - * There is an option to compress file blocks to safe memory. - */ -public class FileSystemMemory extends FileSystem { - - /** - * The prefix used for an in-memory file system. - */ - public static final String PREFIX = "memFS:"; - - /** - * The prefix used for a compressed in-memory file system. - */ - public static final String PREFIX_LZF = "memLZF:"; - - private static final FileSystemMemory INSTANCE = new FileSystemMemory(); - private static final TreeMap MEMORY_FILES = new TreeMap(); - - private FileSystemMemory() { - // don't allow construction - } - - public static FileSystemMemory getInstance() { - return INSTANCE; - } - - public long length(String fileName) { - return getMemoryFile(fileName).length(); - } - - public void rename(String oldName, String newName) { - oldName = normalize(oldName); - newName = normalize(newName); - synchronized (MEMORY_FILES) { - FileObjectMemoryData f = getMemoryFile(oldName); - f.setName(newName); - MEMORY_FILES.remove(oldName); - MEMORY_FILES.put(newName, f); - } - } - - public boolean createNewFile(String fileName) { - synchronized (MEMORY_FILES) { - if (exists(fileName)) { - return false; - } - getMemoryFile(fileName); - } - return true; - } - - public boolean exists(String fileName) { - fileName = normalize(fileName); - synchronized (MEMORY_FILES) { - return MEMORY_FILES.get(fileName) != null; - } - } - - public void delete(String fileName) { - fileName = normalize(fileName); - synchronized (MEMORY_FILES) { - MEMORY_FILES.remove(fileName); - } - } - - public boolean tryDelete(String fileName) { - delete(fileName); - return true; - } - - public String[] listFiles(String path) { - ArrayList list = New.arrayList(); - synchronized (MEMORY_FILES) { - for (String name : MEMORY_FILES.tailMap(path).keySet()) { - if (name.startsWith(path)) { - list.add(name); - } else { - break; - } - } - String[] array = new String[list.size()]; - list.toArray(array); - return array; - } - } - - public void deleteRecursive(String fileName, boolean tryOnly) { - fileName = normalize(fileName); - synchronized (MEMORY_FILES) { - Iterator it = MEMORY_FILES.tailMap(fileName).keySet().iterator(); - while (it.hasNext()) { - String name = it.next(); - if (name.startsWith(fileName)) { - it.remove(); - } else { - break; - } - } - } - } - - public boolean isReadOnly(String fileName) { - return !getMemoryFile(fileName).canWrite(); - } - - public boolean setReadOnly(String fileName) { - return getMemoryFile(fileName).setReadOnly(); - } - - public String normalize(String fileName) { - fileName = fileName.replace('\\', '/'); - int idx = fileName.indexOf(":/"); - if (idx > 0) { - fileName = fileName.substring(0, idx + 1) + fileName.substring(idx + 2); - } - return fileName; - } - - public String getParent(String fileName) { - fileName = normalize(fileName); - int idx = fileName.lastIndexOf('/'); - if (idx < 0) { - idx = fileName.indexOf(':') + 1; - } - return fileName.substring(0, idx); - } - - public boolean isDirectory(String fileName) { - // TODO in memory file system currently - // does not really support directories - return false; - } - - public boolean isAbsolute(String fileName) { - // TODO relative files are not supported - return true; - } - - public String getAbsolutePath(String fileName) { - // TODO relative files are not supported - return normalize(fileName); - } - - public long getLastModified(String fileName) { - return getMemoryFile(fileName).getLastModified(); - } - - public boolean canWrite(String fileName) { - return true; - } - - public void copy(String original, String copy) { - try { - OutputStream out = openFileOutputStream(copy, false); - InputStream in = openFileInputStream(original); - IOUtils.copyAndClose(in, out); - } catch (IOException e) { - throw DbException.convertIOException(e, "Can not copy " + original + " to " + copy); - } - } - - public void createDirs(String fileName) { - // TODO directories are not really supported - } - - public String getFileName(String name) { - int idx = Math.max(name.indexOf(':'), name.lastIndexOf('/')); - return idx < 0 ? name : name.substring(idx + 1); - } - - public boolean fileStartsWith(String fileName, String prefix) { - fileName = normalize(fileName); - prefix = normalize(prefix); - return fileName.startsWith(prefix); - } - - public OutputStream openFileOutputStream(String fileName, boolean append) { - try { - FileObjectMemoryData obj = getMemoryFile(fileName); - FileObjectMemory m = new FileObjectMemory(obj); - return new FileObjectOutputStream(m, append); - } catch (IOException e) { - throw DbException.convertIOException(e, fileName); - } - } - - public InputStream openFileInputStream(String fileName) { - FileObjectMemoryData obj = getMemoryFile(fileName); - FileObjectMemory m = new FileObjectMemory(obj); - return new FileObjectInputStream(m); - } - - public FileObject openFileObject(String fileName, String mode) { - FileObjectMemoryData obj = getMemoryFile(fileName); - return new FileObjectMemory(obj); - } - - private FileObjectMemoryData getMemoryFile(String fileName) { - fileName = normalize(fileName); - synchronized (MEMORY_FILES) { - FileObjectMemoryData m = MEMORY_FILES.get(fileName); - if (m == null) { - boolean compress = fileName.startsWith(PREFIX_LZF); - m = new FileObjectMemoryData(fileName, compress); - MEMORY_FILES.put(fileName, m); - } - return m; - } - } - - protected boolean accepts(String fileName) { - return fileName.startsWith(PREFIX) || fileName.startsWith(PREFIX_LZF); - } - -} diff --git a/tools/h2/src/main/org/h2/store/fs/FileSystemSplit.java b/tools/h2/src/main/org/h2/store/fs/FileSystemSplit.java deleted file mode 100755 index dc622f6..0000000 --- a/tools/h2/src/main/org/h2/store/fs/FileSystemSplit.java +++ /dev/null @@ -1,328 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.store.fs; - -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.io.SequenceInputStream; -import java.util.ArrayList; - -import org.h2.constant.SysProperties; -import org.h2.message.DbException; -import org.h2.util.New; - -/** - * A file system that may split files into multiple smaller files. - * (required for a FAT32 because it only support files up to 2 GB). - */ -public class FileSystemSplit extends FileSystem { - - private static final String PREFIX = "split:"; - - private static final String PART_SUFFIX = ".part"; - private long defaultMaxSize = 1L << SysProperties.SPLIT_FILE_SIZE_SHIFT; - - static { - FileSystem.register(new FileSystemSplit()); - } - - public boolean canWrite(String fileName) { - fileName = translateFileName(fileName); - return getFileSystem(fileName).canWrite(fileName); - } - - public boolean setReadOnly(String fileName) { - fileName = translateFileName(fileName); - boolean result = false; - for (int i = 0;; i++) { - String f = getFileName(fileName, i); - if (getFileSystem(f).exists(f)) { - result = getFileSystem(f).setReadOnly(f); - } else { - break; - } - } - return result; - } - - public void copy(String original, String copy) { - original = translateFileName(original); - copy = translateFileName(copy); - getFileSystem(original).copy(original, copy); - for (int i = 1;; i++) { - String o = getFileName(original, i); - if (getFileSystem(o).exists(o)) { - String c = getFileName(copy, i); - getFileSystem(o).copy(o, c); - } else { - break; - } - } - } - - public void createDirs(String fileName) { - fileName = translateFileName(fileName); - getFileSystem(fileName).createDirs(fileName); - } - - public boolean createNewFile(String fileName) { - fileName = translateFileName(fileName); - return getFileSystem(fileName).createNewFile(fileName); - } - - public String createTempFile(String prefix, String suffix, boolean deleteOnExit, boolean inTempDir) - throws IOException { - prefix = translateFileName(prefix); - return PREFIX + getFileSystem(prefix).createTempFile(prefix, suffix, deleteOnExit, inTempDir); - } - - public void delete(String fileName) { - fileName = translateFileName(fileName); - for (int i = 0;; i++) { - String f = getFileName(fileName, i); - if (getFileSystem(fileName).exists(f)) { - getFileSystem(fileName).delete(f); - } else { - break; - } - } - } - - public void deleteRecursive(String directory, boolean tryOnly) { - directory = translateFileName(directory); - getFileSystem(directory).deleteRecursive(directory, tryOnly); - } - - public boolean exists(String fileName) { - fileName = translateFileName(fileName); - return getFileSystem(fileName).exists(fileName); - } - - public boolean fileStartsWith(String fileName, String prefix) { - fileName = translateFileName(fileName); - prefix = translateFileName(prefix); - return getFileSystem(fileName).fileStartsWith(fileName, prefix); - } - - public String getAbsolutePath(String fileName) { - fileName = translateFileName(fileName); - return PREFIX + getFileSystem(fileName).getAbsolutePath(fileName); - } - - public String getFileName(String name) { - name = translateFileName(name); - return getFileSystem(name).getFileName(name); - } - - public long getLastModified(String fileName) { - fileName = translateFileName(fileName); - long lastModified = 0; - for (int i = 0;; i++) { - String f = getFileName(fileName, i); - if (getFileSystem(fileName).exists(f)) { - long l = getFileSystem(fileName).getLastModified(fileName); - lastModified = Math.max(lastModified, l); - } else { - break; - } - } - return lastModified; - } - - public String getParent(String fileName) { - fileName = translateFileName(fileName); - return PREFIX + getFileSystem(fileName).getParent(fileName); - } - - public boolean isAbsolute(String fileName) { - fileName = translateFileName(fileName); - return getFileSystem(fileName).isAbsolute(fileName); - } - - public boolean isDirectory(String fileName) { - fileName = translateFileName(fileName); - return getFileSystem(fileName).isDirectory(fileName); - } - - public boolean isReadOnly(String fileName) { - fileName = translateFileName(fileName); - return getFileSystem(fileName).isReadOnly(fileName); - } - - public long length(String fileName) { - fileName = translateFileName(fileName); - long length = 0; - for (int i = 0;; i++) { - String f = getFileName(fileName, i); - if (getFileSystem(fileName).exists(f)) { - length += getFileSystem(fileName).length(f); - } else { - break; - } - } - return length; - } - - public String[] listFiles(String directory) { - directory = translateFileName(directory); - String[] array = getFileSystem(directory).listFiles(directory); - ArrayList list = New.arrayList(); - for (int i = 0; i < array.length; i++) { - String f = array[i]; - if (f.endsWith(PART_SUFFIX)) { - continue; - } - array[i] = f = PREFIX + f; - list.add(f); - } - if (list.size() != array.length) { - array = new String[list.size()]; - list.toArray(array); - } - return array; - } - - public String normalize(String fileName) { - fileName = translateFileName(fileName); - return PREFIX + getFileSystem(fileName).normalize(fileName); - } - - public InputStream openFileInputStream(String fileName) throws IOException { - fileName = translateFileName(fileName); - InputStream input = getFileSystem(fileName).openFileInputStream(fileName); - for (int i = 1;; i++) { - String f = getFileName(fileName, i); - if (getFileSystem(f).exists(f)) { - InputStream i2 = getFileSystem(f).openFileInputStream(f); - input = new SequenceInputStream(input, i2); - } else { - break; - } - } - return input; - } - - public FileObject openFileObject(String fileName, String mode) throws IOException { - fileName = translateFileName(fileName); - ArrayList list = New.arrayList(); - FileObject o = getFileSystem(fileName).openFileObject(fileName, mode); - list.add(o); - for (int i = 1;; i++) { - String f = getFileName(fileName, i); - if (getFileSystem(fileName).exists(f)) { - o = getFileSystem(f).openFileObject(f, mode); - list.add(o); - } else { - break; - } - } - FileObject[] array = new FileObject[list.size()]; - list.toArray(array); - long maxLength = array[0].length(); - long length = maxLength; - if (array.length == 1) { - if (maxLength < defaultMaxSize) { - maxLength = defaultMaxSize; - } - } else { - for (int i = 1; i < array.length - 1; i++) { - o = array[i]; - long l = o.length(); - length += l; - if (l != maxLength) { - throw new IOException("Expected file length: " + maxLength + " got: " + l + " for " + o.getName()); - } - } - o = array[array.length - 1]; - long l = o.length(); - length += l; - if (l > maxLength) { - throw new IOException("Expected file length: " + maxLength + " got: " + l + " for " + o.getName()); - } - } - FileObjectSplit fo = new FileObjectSplit(fileName, mode, array, length, maxLength); - return fo; - } - - public OutputStream openFileOutputStream(String fileName, boolean append) { - fileName = translateFileName(fileName); - // TODO the output stream is not split - return getFileSystem(fileName).openFileOutputStream(fileName, append); - } - - public void rename(String oldName, String newName) { - oldName = translateFileName(oldName); - newName = translateFileName(newName); - for (int i = 0;; i++) { - String o = getFileName(oldName, i); - if (getFileSystem(o).exists(o)) { - String n = getFileName(newName, i); - getFileSystem(n).rename(o, n); - } else { - break; - } - } - } - - public boolean tryDelete(String fileName) { - fileName = translateFileName(fileName); - for (int i = 0;; i++) { - String f = getFileName(fileName, i); - if (getFileSystem(fileName).exists(f)) { - boolean ok = getFileSystem(fileName).tryDelete(f); - if (!ok) { - return false; - } - } else { - break; - } - } - return true; - } - - private String translateFileName(String fileName) { - if (!fileName.startsWith(PREFIX)) { - DbException.throwInternalError(fileName + " doesn't start with " + PREFIX); - } - fileName = fileName.substring(PREFIX.length()); - if (fileName.length() > 0 && Character.isDigit(fileName.charAt(0))) { - int idx = fileName.indexOf(':'); - String size = fileName.substring(0, idx); - try { - defaultMaxSize = 1L << Integer.decode(size).intValue(); - fileName = fileName.substring(idx + 1); - } catch (NumberFormatException e) { - // ignore - } - } - return fileName; - } - - /** - * Get the file name of a part file. - * - * @param fileName the file name - * @param id the part id - * @return the file name including the part id - */ - static String getFileName(String fileName, int id) { - if (id > 0) { - fileName += "." + id + PART_SUFFIX; - } - return fileName; - } - - private FileSystem getFileSystem(String fileName) { - return FileSystem.getInstance(fileName); - } - - protected boolean accepts(String fileName) { - return fileName.startsWith(PREFIX); - } - -} diff --git a/tools/h2/src/main/org/h2/store/fs/FileSystemZip.java b/tools/h2/src/main/org/h2/store/fs/FileSystemZip.java deleted file mode 100755 index 27355b1..0000000 --- a/tools/h2/src/main/org/h2/store/fs/FileSystemZip.java +++ /dev/null @@ -1,256 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.store.fs; - -import java.io.FileNotFoundException; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.util.ArrayList; -import java.util.Enumeration; -import java.util.zip.ZipEntry; -import java.util.zip.ZipFile; -import org.h2.message.DbException; -import org.h2.util.New; - -/** - * This is a read-only file system that allows - * to access databases stored in a .zip or .jar file. - */ -public class FileSystemZip extends FileSystem { - - private static final String PREFIX = "zip:"; - - static { - FileSystem.register(new FileSystemZip()); - } - - public boolean canWrite(String fileName) { - return false; - } - - public void copy(String original, String copy) { - throw DbException.getUnsupportedException("write"); - } - - public void createDirs(String fileName) { - // ignore - } - - public boolean createNewFile(String fileName) { - throw DbException.getUnsupportedException("write"); - } - - public String createTempFile(String prefix, String suffix, boolean deleteOnExit, boolean inTempDir) throws IOException { - if (!inTempDir) { - throw new IOException("File system is read-only"); - } - return FileSystemDisk.getInstance().createTempFile(prefix, suffix, deleteOnExit, true); - } - - public void delete(String fileName) { - throw DbException.getUnsupportedException("write"); - } - - public void deleteRecursive(String fileName, boolean tryOnly) { - throw DbException.getUnsupportedException("write"); - } - - public boolean exists(String fileName) { - try { - String entryName = getEntryName(fileName); - if (entryName.length() == 0) { - return true; - } - ZipFile file = openZipFile(fileName); - return file.getEntry(entryName) != null; - } catch (IOException e) { - return false; - } - } - - public boolean fileStartsWith(String fileName, String prefix) { - return fileName.startsWith(prefix); - } - - public String getAbsolutePath(String fileName) { - return fileName; - } - - public String getFileName(String name) { - name = getEntryName(name); - if (name.endsWith("/")) { - name = name.substring(0, name.length() - 1); - } - int idx = name.lastIndexOf('/'); - if (idx >= 0) { - name = name.substring(idx + 1); - } - return name; - } - - public long getLastModified(String fileName) { - return 0; - } - - public String getParent(String fileName) { - int idx = fileName.lastIndexOf('/'); - if (idx > 0) { - fileName = fileName.substring(0, idx); - } - return fileName; - } - - public boolean isAbsolute(String fileName) { - return true; - } - - public boolean isDirectory(String fileName) { - try { - String entryName = getEntryName(fileName); - if (entryName.length() == 0) { - return true; - } - ZipFile file = openZipFile(fileName); - Enumeration< ? extends ZipEntry> en = file.entries(); - while (en.hasMoreElements()) { - ZipEntry entry = en.nextElement(); - String n = entry.getName(); - if (n.equals(entryName)) { - return entry.isDirectory(); - } else if (n.startsWith(entryName)) { - if (n.length() == entryName.length() + 1) { - if (n.equals(entryName + "/")) { - return true; - } - } - } - } - return false; - } catch (IOException e) { - return false; - } - } - - public boolean isReadOnly(String fileName) { - return true; - } - - public boolean setReadOnly(String fileName) { - return true; - } - - public long length(String fileName) { - try { - ZipFile file = openZipFile(fileName); - ZipEntry entry = file.getEntry(getEntryName(fileName)); - return entry == null ? 0 : entry.getSize(); - } catch (IOException e) { - return 0; - } - } - - public String[] listFiles(String path) { - try { - if (path.indexOf('!') < 0) { - path += "!"; - } - if (!path.endsWith("/")) { - path += "/"; - } - ZipFile file = openZipFile(path); - String dirName = getEntryName(path); - String prefix = path.substring(0, path.length() - dirName.length()); - Enumeration< ? extends ZipEntry> en = file.entries(); - ArrayList list = New.arrayList(); - while (en.hasMoreElements()) { - ZipEntry entry = en.nextElement(); - String name = entry.getName(); - if (!name.startsWith(dirName)) { - continue; - } - if (name.length() <= dirName.length()) { - continue; - } - int idx = name.indexOf('/', dirName.length()); - if (idx < 0 || idx >= name.length() - 1) { - list.add(prefix + name); - } - } - String[] result = new String[list.size()]; - list.toArray(result); - return result; - } catch (IOException e) { - throw DbException.convertIOException(e, "listFiles " + path); - } - } - - public String normalize(String fileName) { - return fileName; - } - - public InputStream openFileInputStream(String fileName) throws IOException { - FileObject file = openFileObject(fileName, "r"); - return new FileObjectInputStream(file); - } - - public FileObject openFileObject(String fileName, String mode) throws IOException { - ZipFile file = openZipFile(translateFileName(fileName)); - ZipEntry entry = file.getEntry(getEntryName(fileName)); - if (entry == null) { - throw new FileNotFoundException(fileName); - } - return new FileObjectZip(file, entry); - } - - public OutputStream openFileOutputStream(String fileName, boolean append) { - throw DbException.getUnsupportedException("write"); - } - - public void rename(String oldName, String newName) { - throw DbException.getUnsupportedException("write"); - } - - public boolean tryDelete(String fileName) { - return false; - } - - private String translateFileName(String fileName) { - if (fileName.startsWith(PREFIX)) { - fileName = fileName.substring(PREFIX.length()); - } - int idx = fileName.indexOf('!'); - if (idx >= 0) { - fileName = fileName.substring(0, idx); - } - return FileSystemDisk.expandUserHomeDirectory(fileName); - } - - private String getEntryName(String fileName) { - int idx = fileName.indexOf('!'); - if (idx <= 0) { - fileName = ""; - } else { - fileName = fileName.substring(idx + 1); - } - fileName = fileName.replace('\\', '/'); - if (fileName.startsWith("/")) { - fileName = fileName.substring(1); - } - return fileName; - } - - private ZipFile openZipFile(String fileName) throws IOException { - fileName = translateFileName(fileName); - return new ZipFile(fileName); - } - - protected boolean accepts(String fileName) { - return fileName.startsWith(PREFIX); - } - -} diff --git a/tools/h2/src/main/org/h2/store/fs/package.html b/tools/h2/src/main/org/h2/store/fs/package.html deleted file mode 100755 index d87256c..0000000 --- a/tools/h2/src/main/org/h2/store/fs/package.html +++ /dev/null @@ -1,15 +0,0 @@ - - - - -Javadoc package documentation -

- -A file system abstraction. - -

\ No newline at end of file diff --git a/tools/h2/src/main/org/h2/store/package.html b/tools/h2/src/main/org/h2/store/package.html deleted file mode 100755 index d8f2a1c..0000000 --- a/tools/h2/src/main/org/h2/store/package.html +++ /dev/null @@ -1,15 +0,0 @@ - - - - -Javadoc package documentation -

- -Storage abstractions, such as a file with a cache, or a class to convert values to a byte array and vice versa. - -

\ No newline at end of file diff --git a/tools/h2/src/main/org/h2/table/Column.java b/tools/h2/src/main/org/h2/table/Column.java deleted file mode 100755 index 4fb344b..0000000 --- a/tools/h2/src/main/org/h2/table/Column.java +++ /dev/null @@ -1,650 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.table; - -import java.sql.ResultSetMetaData; -import java.sql.Time; -import java.sql.Timestamp; -import org.h2.command.Parser; -import org.h2.constant.ErrorCode; -import org.h2.engine.Constants; -import org.h2.engine.Mode; -import org.h2.engine.Session; -import org.h2.expression.ConditionAndOr; -import org.h2.expression.Expression; -import org.h2.expression.ExpressionVisitor; -import org.h2.expression.SequenceValue; -import org.h2.expression.ValueExpression; -import org.h2.message.DbException; -import org.h2.result.Row; -import org.h2.schema.Schema; -import org.h2.schema.Sequence; -import org.h2.util.MathUtils; -import org.h2.util.StringUtils; -import org.h2.value.DataType; -import org.h2.value.Value; -import org.h2.value.ValueInt; -import org.h2.value.ValueLong; -import org.h2.value.ValueNull; -import org.h2.value.ValueString; -import org.h2.value.ValueTime; -import org.h2.value.ValueTimestamp; -import org.h2.value.ValueUuid; - -/** - * This class represents a column in a table. - */ -public class Column { - - /** - * This column is not nullable. - */ - public static final int NOT_NULLABLE = ResultSetMetaData.columnNoNulls; - - /** - * This column is nullable. - */ - public static final int NULLABLE = ResultSetMetaData.columnNullable; - - /** - * It is not know whether this column is nullable. - */ - public static final int NULLABLE_UNKNOWN = ResultSetMetaData.columnNullableUnknown; - - private final int type; - private final long precision; - private final int scale; - private final int displaySize; - private Table table; - private String name; - private int columnId; - private boolean nullable = true; - private Expression defaultExpression; - private Expression checkConstraint; - private String checkConstraintSQL; - private String originalSQL; - private boolean autoIncrement; - private long start; - private long increment; - private boolean convertNullToDefault; - private Sequence sequence; - private boolean isComputed; - private TableFilter computeTableFilter; - private int selectivity; - private SingleColumnResolver resolver; - private String comment; - private boolean primaryKey; - - public Column(String name, int type) { - this(name, type, -1, -1, -1); - } - - public Column(String name, int type, long precision, int scale, int displaySize) { - this.name = name; - this.type = type; - if (precision == -1 && scale == -1 && displaySize == -1) { - DataType dt = DataType.getDataType(type); - precision = dt.defaultPrecision; - scale = dt.defaultScale; - displaySize = dt.defaultDisplaySize; - } - this.precision = precision; - this.scale = scale; - this.displaySize = displaySize; - } - - public boolean equals(Object o) { - if (o == this) { - return true; - } else if (!(o instanceof Column)) { - return false; - } - Column other = (Column) o; - if (table == null || other.table == null || name == null || other.name == null) { - return false; - } - return table == other.table && name.equals(other.name); - } - - public int hashCode() { - if (table == null || name == null) { - return 0; - } - return table.getId() ^ name.hashCode(); - } - - public Column getClone() { - Column newColumn = new Column(name, type, precision, scale, displaySize); - // table is not set - // columnId is not set - newColumn.nullable = nullable; - newColumn.defaultExpression = defaultExpression; - newColumn.originalSQL = originalSQL; - // autoIncrement, start, increment is not set - newColumn.convertNullToDefault = convertNullToDefault; - newColumn.sequence = sequence; - newColumn.comment = comment; - newColumn.computeTableFilter = computeTableFilter; - newColumn.isComputed = isComputed; - newColumn.selectivity = selectivity; - newColumn.primaryKey = primaryKey; - return newColumn; - } - - /** - * Convert a value to this column's type. - * - * @param v the value - * @return the value - */ - public Value convert(Value v) { - try { - return v.convertTo(type); - } catch (DbException e) { - if (e.getErrorCode() == ErrorCode.DATA_CONVERSION_ERROR_1) { - throw DbException.get(ErrorCode.DATA_CONVERSION_ERROR_1, v.getSQL() + " (" + getCreateSQL() + ")"); - } - throw e; - } - } - - boolean getComputed() { - return isComputed; - } - - /** - * Compute the value of this computed column. - * - * @param session the session - * @param row the row - * @return the value - */ - Value computeValue(Session session, Row row) { - synchronized (this) { - computeTableFilter.setSession(session); - computeTableFilter.set(row); - return defaultExpression.getValue(session); - } - } - - /** - * Set the default value in the form of a computed expression of other - * columns. - * - * @param expression the computed expression - */ - public void setComputedExpression(Expression expression) { - this.isComputed = true; - this.defaultExpression = expression; - } - - /** - * Set the table and column id. - * - * @param table the table - * @param columnId the column index - */ - public void setTable(Table table, int columnId) { - this.table = table; - this.columnId = columnId; - } - - public Table getTable() { - return table; - } - - /** - * Set the default expression. - * - * @param session the session - * @param defaultExpression the default expression - */ - public void setDefaultExpression(Session session, Expression defaultExpression) { - // also to test that no column names are used - if (defaultExpression != null) { - defaultExpression = defaultExpression.optimize(session); - if (defaultExpression.isConstant()) { - defaultExpression = ValueExpression.get(defaultExpression.getValue(session)); - } - } - this.defaultExpression = defaultExpression; - } - - public int getColumnId() { - return columnId; - } - - public String getSQL() { - return Parser.quoteIdentifier(name); - } - - public String getName() { - return name; - } - - public int getType() { - return type; - } - - public long getPrecision() { - return precision; - } - - public int getDisplaySize() { - return displaySize; - } - - public int getScale() { - return scale; - } - - public void setNullable(boolean b) { - nullable = b; - } - - /** - * Validate the value, convert it if required, and update the sequence value - * if required. If the value is null, the default value (NULL if no default - * is set) is returned. Check constraints are validated as well. - * - * @param session the session - * @param value the value or null - * @return the new or converted value - */ - public Value validateConvertUpdateSequence(Session session, Value value) { - if (value == null) { - if (defaultExpression == null) { - value = ValueNull.INSTANCE; - } else { - synchronized (this) { - value = defaultExpression.getValue(session).convertTo(type); - } - if (primaryKey) { - session.setLastIdentity(value); - } - } - } - Mode mode = session.getDatabase().getMode(); - if (value == ValueNull.INSTANCE) { - if (convertNullToDefault) { - synchronized (this) { - value = defaultExpression.getValue(session).convertTo(type); - } - } - if (value == ValueNull.INSTANCE && !nullable) { - if (mode.convertInsertNullToZero) { - DataType dt = DataType.getDataType(type); - if (dt.decimal) { - value = ValueInt.get(0).convertTo(type); - } else if (dt.type == Value.TIMESTAMP) { - value = ValueTimestamp.getNoCopy(new Timestamp(System.currentTimeMillis())); - } else if (dt.type == Value.TIME) { - // need to normalize - value = ValueTime.get(Time.valueOf("0:0:0")); - } else if (dt.type == Value.DATE) { - value = ValueTimestamp.getNoCopy(new Timestamp(System.currentTimeMillis())).convertTo(dt.type); - } else { - value = ValueString.get("").convertTo(type); - } - } else { - throw DbException.get(ErrorCode.NULL_NOT_ALLOWED, name); - } - } - } - if (checkConstraint != null) { - resolver.setValue(value); - Value v; - synchronized (this) { - v = checkConstraint.getValue(session); - } - // Both TRUE and NULL are ok - if (Boolean.FALSE.equals(v.getBoolean())) { - throw DbException.get(ErrorCode.CHECK_CONSTRAINT_VIOLATED_1, checkConstraint.getSQL()); - } - } - value = value.convertScale(mode.convertOnlyToSmallerScale, scale); - if (precision > 0) { - if (!value.checkPrecision(precision)) { - String s = value.getTraceSQL(); - if (s.length() > 127) { - s = s.substring(0, 128) + "..."; - } - throw DbException.get(ErrorCode.VALUE_TOO_LONG_2, - getCreateSQL(), s + " (" + value.getPrecision() + ")"); - } - } - updateSequenceIfRequired(session, value); - return value; - } - - private void updateSequenceIfRequired(Session session, Value value) { - if (sequence != null) { - long current = sequence.getCurrentValue(); - long inc = sequence.getIncrement(); - long now = value.getLong(); - boolean update = false; - if (inc > 0 && now > current) { - update = true; - } else if (inc < 0 && now < current) { - update = true; - } - if (update) { - sequence.setStartValue(now + inc); - session.setLastIdentity(ValueLong.get(now)); - sequence.flush(session); - } - } - } - - /** - * Convert the auto-increment flag to a sequence that is linked with this - * table. - * - * @param session the session - * @param schema the schema where the sequence should be generated - * @param id the object id - * @param temporary true if the sequence is temporary and does not need to - * be stored - */ - public void convertAutoIncrementToSequence(Session session, Schema schema, int id, boolean temporary) { - if (!autoIncrement) { - DbException.throwInternalError(); - } - if ("IDENTITY".equals(originalSQL)) { - originalSQL = "BIGINT"; - } - String sequenceName; - for (int i = 0;; i++) { - ValueUuid uuid = ValueUuid.getNewRandom(); - String s = uuid.getString(); - s = s.replace('-', '_').toUpperCase(); - sequenceName = "SYSTEM_SEQUENCE_" + s; - if (schema.findSequence(sequenceName) == null) { - break; - } - } - Sequence seq = new Sequence(schema, id, sequenceName, true); - seq.setStartValue(start); - seq.setIncrement(increment); - if (!temporary) { - session.getDatabase().addSchemaObject(session, seq); - } - setAutoIncrement(false, 0, 0); - SequenceValue seqValue = new SequenceValue(seq); - setDefaultExpression(session, seqValue); - setSequence(seq); - } - - /** - * Prepare all expressions of this column. - * - * @param session the session - */ - public void prepareExpression(Session session) { - if (defaultExpression != null) { - computeTableFilter = new TableFilter(session, table, null, false, null); - defaultExpression.mapColumns(computeTableFilter, 0); - defaultExpression = defaultExpression.optimize(session); - } - } - - public String getCreateSQL() { - StringBuilder buff = new StringBuilder(); - if (name != null) { - buff.append(Parser.quoteIdentifier(name)).append(' '); - } - if (originalSQL != null) { - buff.append(originalSQL); - } else { - buff.append(DataType.getDataType(type).name); - switch (type) { - case Value.DECIMAL: - buff.append('(').append(precision).append(", ").append(scale).append(')'); - break; - case Value.BYTES: - case Value.STRING: - case Value.STRING_IGNORECASE: - case Value.STRING_FIXED: - if (precision < Integer.MAX_VALUE) { - buff.append('(').append(precision).append(')'); - } - break; - default: - } - } - if (defaultExpression != null) { - String sql = defaultExpression.getSQL(); - if (sql != null) { - if (isComputed) { - buff.append(" AS ").append(sql); - } else if (defaultExpression != null) { - buff.append(" DEFAULT ").append(sql); - } - } - } - if (!nullable) { - buff.append(" NOT NULL"); - } - if (convertNullToDefault) { - buff.append(" NULL_TO_DEFAULT"); - } - if (sequence != null) { - buff.append(" SEQUENCE ").append(sequence.getSQL()); - } - if (selectivity != 0) { - buff.append(" SELECTIVITY ").append(selectivity); - } - if (checkConstraint != null) { - buff.append(" CHECK ").append(checkConstraintSQL); - } - if (comment != null) { - buff.append(" COMMENT ").append(StringUtils.quoteStringSQL(comment)); - } - return buff.toString(); - } - - public boolean isNullable() { - return nullable; - } - - public void setOriginalSQL(String original) { - originalSQL = original; - } - - public String getOriginalSQL() { - return originalSQL; - } - - public Expression getDefaultExpression() { - return defaultExpression; - } - - public boolean isAutoIncrement() { - return autoIncrement; - } - - /** - * Set the autoincrement flag and related properties of this column. - * - * @param autoInc the new autoincrement flag - * @param start the sequence start value - * @param increment the sequence increment - */ - public void setAutoIncrement(boolean autoInc, long start, long increment) { - this.autoIncrement = autoInc; - this.start = start; - this.increment = increment; - this.nullable = false; - if (autoInc) { - convertNullToDefault = true; - } - } - - public void setConvertNullToDefault(boolean convert) { - this.convertNullToDefault = convert; - } - - /** - * Rename the column. This method will only set the column name to the new - * value. - * - * @param newName the new column name - */ - public void rename(String newName) { - this.name = newName; - } - - public void setSequence(Sequence sequence) { - this.sequence = sequence; - } - - public Sequence getSequence() { - return sequence; - } - - /** - * Get the selectivity of the column. Selectivity 100 means values are - * unique, 10 means every distinct value appears 10 times on average. - * - * @return the selectivity - */ - public int getSelectivity() { - return selectivity == 0 ? Constants.SELECTIVITY_DEFAULT : selectivity; - } - - /** - * Set the new selectivity of a column. - * - * @param selectivity the new value - */ - public void setSelectivity(int selectivity) { - selectivity = selectivity < 0 ? 0 : (selectivity > 100 ? 100 : selectivity); - this.selectivity = selectivity; - } - - /** - * Add a check constraint expression to this column. An existing check - * constraint constraint is added using AND. - * - * @param session the session - * @param expr the (additional) constraint - */ - public void addCheckConstraint(Session session, Expression expr) { - resolver = new SingleColumnResolver(this); - synchronized (this) { - String oldName = name; - if (name == null) { - name = "VALUE"; - } - expr.mapColumns(resolver, 0); - name = oldName; - } - expr = expr.optimize(session); - resolver.setValue(ValueNull.INSTANCE); - // check if the column is mapped - synchronized (this) { - expr.getValue(session); - } - if (checkConstraint == null) { - checkConstraint = expr; - } else { - checkConstraint = new ConditionAndOr(ConditionAndOr.AND, checkConstraint, expr); - } - checkConstraintSQL = getCheckConstraintSQL(session, name); - } - - /** - * Get the check constraint expression for this column if set. - * - * @param session the session - * @param asColumnName the column name to use - * @return the constraint expression - */ - public Expression getCheckConstraint(Session session, String asColumnName) { - if (checkConstraint == null) { - return null; - } - Parser parser = new Parser(session); - String sql; - synchronized (this) { - String oldName = name; - name = asColumnName; - sql = checkConstraint.getSQL(); - name = oldName; - } - Expression expr = parser.parseExpression(sql); - return expr; - } - - String getDefaultSQL() { - return defaultExpression == null ? null : defaultExpression.getSQL(); - } - - int getPrecisionAsInt() { - return MathUtils.convertLongToInt(precision); - } - - DataType getDataType() { - return DataType.getDataType(type); - } - - /** - * Get the check constraint SQL snippet. - * - * @param session the session - * @param asColumnName the column name to use - * @return the SQL snippet - */ - String getCheckConstraintSQL(Session session, String asColumnName) { - Expression constraint = getCheckConstraint(session, asColumnName); - return constraint == null ? "" : constraint.getSQL(); - } - - public void setComment(String comment) { - this.comment = comment; - } - - public String getComment() { - return comment; - } - - public void setPrimaryKey(boolean primaryKey) { - this.primaryKey = primaryKey; - } - - /** - * Visit the default expression, the check constraint, and the sequence (if - * any). - * - * @param visitor the visitor - * @return true if every visited expression returned true, or if there are - * no expressions - */ - boolean isEverything(ExpressionVisitor visitor) { - if (visitor.getType() == ExpressionVisitor.GET_DEPENDENCIES) { - if (sequence != null) { - visitor.getDependencies().add(sequence); - } - } - if (defaultExpression != null && !defaultExpression.isEverything(visitor)) { - return false; - } - if (checkConstraint != null && !checkConstraint.isEverything(visitor)) { - return false; - } - return true; - } - - public boolean isPrimaryKey() { - return primaryKey; - } - - public String toString() { - return name; - } - -} diff --git a/tools/h2/src/main/org/h2/table/ColumnResolver.java b/tools/h2/src/main/org/h2/table/ColumnResolver.java deleted file mode 100755 index aad6280..0000000 --- a/tools/h2/src/main/org/h2/table/ColumnResolver.java +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.table; - -import org.h2.command.dml.Select; -import org.h2.expression.Expression; -import org.h2.expression.ExpressionColumn; -import org.h2.value.Value; - -/** - * A column resolver is list of column (for example, a table) that can map a - * column name to an actual column. - */ -public interface ColumnResolver { - - /** - * Get the table alias. - * - * @return the table alias - */ - String getTableAlias(); - - /** - * Get the column list. - * - * @return the column list - */ - Column[] getColumns(); - - /** - * Get the list of system columns, if any. - * - * @return the system columns - */ - Column[] getSystemColumns(); - - /** - * Get the schema name. - * - * @return the schema name - */ - String getSchemaName(); - - /** - * Get the value for the given column. - * - * @param column the column - * @return the value - */ - Value getValue(Column column); - - /** - * Get the table filter. - * - * @return the table filter - */ - TableFilter getTableFilter(); - - /** - * Get the select statement. - * - * @return the select statement - */ - Select getSelect(); - - /** - * Get the expression that represents this column. - * - * @param expressionColumn the expression column - * @param column the column - * @return the optimized expression - */ - Expression optimize(ExpressionColumn expressionColumn, Column column); - -} diff --git a/tools/h2/src/main/org/h2/table/FunctionTable.java b/tools/h2/src/main/org/h2/table/FunctionTable.java deleted file mode 100755 index 52f6bc0..0000000 --- a/tools/h2/src/main/org/h2/table/FunctionTable.java +++ /dev/null @@ -1,206 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.table; - -import java.sql.ResultSet; -import java.sql.ResultSetMetaData; -import java.sql.SQLException; -import java.util.ArrayList; -import org.h2.constant.ErrorCode; -import org.h2.engine.Session; -import org.h2.expression.Expression; -import org.h2.expression.FunctionCall; -import org.h2.expression.TableFunction; -import org.h2.index.FunctionIndex; -import org.h2.index.Index; -import org.h2.index.IndexType; -import org.h2.message.DbException; -import org.h2.result.LocalResult; -import org.h2.result.Row; -import org.h2.schema.Schema; -import org.h2.value.DataType; -import org.h2.value.Value; -import org.h2.value.ValueNull; -import org.h2.value.ValueResultSet; - -/** - * A table backed by a system or user-defined function that returns a result set. - */ -public class FunctionTable extends Table { - - private final FunctionCall function; - private final long rowCount; - private Expression functionExpr; - private LocalResult cachedResult; - private Value cachedValue; - - public FunctionTable(Schema schema, Session session, Expression functionExpr, FunctionCall function) { - super(schema, 0, function.getName(), false, true); - this.functionExpr = functionExpr; - this.function = function; - if (function instanceof TableFunction) { - rowCount = ((TableFunction) function).getRowCount(); - } else { - rowCount = Long.MAX_VALUE; - } - function.optimize(session); - int type = function.getType(); - if (type != Value.RESULT_SET) { - throw DbException.get(ErrorCode.FUNCTION_MUST_RETURN_RESULT_SET_1, function.getName()); - } - int params = function.getParameterCount(); - Expression[] columnListArgs = new Expression[params]; - Expression[] args = function.getArgs(); - for (int i = 0; i < params; i++) { - args[i] = args[i].optimize(session); - columnListArgs[i] = args[i]; - } - ValueResultSet template = function.getValueForColumnList(session, columnListArgs); - if (template == null) { - throw DbException.get(ErrorCode.FUNCTION_MUST_RETURN_RESULT_SET_1, function.getName()); - } - ResultSet rs = template.getResultSet(); - try { - ResultSetMetaData meta = rs.getMetaData(); - int columnCount = meta.getColumnCount(); - Column[] cols = new Column[columnCount]; - for (int i = 0; i < columnCount; i++) { - cols[i] = new Column(meta.getColumnName(i + 1), DataType.convertSQLTypeToValueType(meta - .getColumnType(i + 1)), meta.getPrecision(i + 1), meta.getScale(i + 1), meta.getColumnDisplaySize(i + 1)); - } - setColumns(cols); - } catch (SQLException e) { - throw DbException.convert(e); - } - } - - public void lock(Session session, boolean exclusive, boolean force) { - // nothing to do - } - - public void close(Session session) { - // nothing to do - } - - public void unlock(Session s) { - // nothing to do - } - - public boolean isLockedExclusively() { - return false; - } - - public Index addIndex(Session session, String indexName, int indexId, IndexColumn[] cols, IndexType indexType, - boolean create, String indexComment) { - throw DbException.getUnsupportedException("ALIAS"); - } - - public void removeRow(Session session, Row row) { - throw DbException.getUnsupportedException("ALIAS"); - } - - public void truncate(Session session) { - throw DbException.getUnsupportedException("ALIAS"); - } - - public boolean canDrop() { - throw DbException.throwInternalError(); - } - - public void addRow(Session session, Row row) { - throw DbException.getUnsupportedException("ALIAS"); - } - - public void checkSupportAlter() { - throw DbException.getUnsupportedException("ALIAS"); - } - - public String getTableType() { - return null; - } - - public Index getScanIndex(Session session) { - return new FunctionIndex(this, IndexColumn.wrap(columns)); - } - - public ArrayList getIndexes() { - return null; - } - - public boolean canGetRowCount() { - return rowCount != Long.MAX_VALUE; - } - - public long getRowCount(Session session) { - return rowCount; - } - - public String getCreateSQL() { - return null; - } - - public String getDropSQL() { - return null; - } - - public void checkRename() { - throw DbException.getUnsupportedException("ALIAS"); - } - - /** - * Read the result set from the function. - * - * @param session the session - * @return the result set - */ - public LocalResult getResult(Session session) { - functionExpr = functionExpr.optimize(session); - Value v = functionExpr.getValue(session); - if (cachedResult != null && cachedValue == v) { - cachedResult.reset(); - return cachedResult; - } - if (v == ValueNull.INSTANCE) { - return new LocalResult(); - } - ValueResultSet value = (ValueResultSet) v; - ResultSet rs = value.getResultSet(); - LocalResult result = LocalResult.read(session, rs, 0); - if (function.isDeterministic()) { - cachedResult = result; - cachedValue = v; - } - return result; - } - - public long getMaxDataModificationId() { - // TODO optimization: table-as-a-function currently doesn't know the - // last modified date - return Long.MAX_VALUE; - } - - public Index getUniqueIndex() { - return null; - } - - public String getSQL() { - return function.getSQL(); - } - - public long getRowCountApproximation() { - return rowCount; - } - - public boolean isDeterministic() { - return function.isDeterministic(); - } - - public boolean canReference() { - return false; - } - -} diff --git a/tools/h2/src/main/org/h2/table/IndexColumn.java b/tools/h2/src/main/org/h2/table/IndexColumn.java deleted file mode 100755 index 20edaa6..0000000 --- a/tools/h2/src/main/org/h2/table/IndexColumn.java +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.table; - -import org.h2.result.SortOrder; - -/** - * This represents a column item of an index. This is required because some - * indexes support descending sorted columns. - */ -public class IndexColumn { - - /** - * The column name. - */ - public String columnName; - - /** - * The column, or null if not set. - */ - public Column column; - - /** - * The sort type. Ascending (the default) and descending are supported; - * nulls can be sorted first or last. - */ - public int sortType = SortOrder.ASCENDING; - - /** - * Get the SQL snippet for this index column. - * - * @return the SQL snippet - */ - public String getSQL() { - StringBuilder buff = new StringBuilder(column.getSQL()); - if ((sortType & SortOrder.DESCENDING) != 0) { - buff.append(" DESC"); - } - if ((sortType & SortOrder.NULLS_FIRST) != 0) { - buff.append(" NULLS FIRST"); - } else if ((sortType & SortOrder.NULLS_LAST) != 0) { - buff.append(" NULLS LAST"); - } - return buff.toString(); - } - - /** - * Create an array of index columns from a list of columns. The default sort - * type is used. - * - * @param columns the column list - * @return the index column array - */ - public static IndexColumn[] wrap(Column[] columns) { - IndexColumn[] list = new IndexColumn[columns.length]; - for (int i = 0; i < list.length; i++) { - list[i] = new IndexColumn(); - list[i].column = columns[i]; - } - return list; - } - - /** - * Map the columns using the column names and the specified table. - * - * @param indexColumns the column list with column names set - * @param table the table from where to map the column names to columns - */ - public static void mapColumns(IndexColumn[] indexColumns, Table table) { - for (IndexColumn col : indexColumns) { - col.column = table.getColumn(col.columnName); - } - } -} diff --git a/tools/h2/src/main/org/h2/table/LinkSchema.java b/tools/h2/src/main/org/h2/table/LinkSchema.java deleted file mode 100755 index b202247..0000000 --- a/tools/h2/src/main/org/h2/table/LinkSchema.java +++ /dev/null @@ -1,89 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.table; - -import java.sql.Connection; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.sql.Statement; -import java.sql.Types; - -import org.h2.message.DbException; -import org.h2.tools.SimpleResultSet; -import org.h2.util.JdbcUtils; -import org.h2.util.StringUtils; - -/** - * A utility class to create table links for a whole schema. - */ -public class LinkSchema { - - private LinkSchema() { - // utility class - } - - /** - * Link all tables of a schema to the database. - * - * @param conn the connection to the database where the links are to be created - * @param targetSchema the schema name where the objects should be created - * @param driver the driver class name of the linked database - * @param url the database URL of the linked database - * @param user the user name - * @param password the password - * @param sourceSchema the schema where the existing tables are - * @return a result set with the created tables - */ - public static ResultSet linkSchema(Connection conn, String targetSchema, String driver, String url, String user, - String password, String sourceSchema) { - Connection c2 = null; - Statement stat = null; - ResultSet rs = null; - SimpleResultSet result = new SimpleResultSet(); - result.addColumn("TABLE_NAME", Types.VARCHAR, Integer.MAX_VALUE, 0); - try { - c2 = JdbcUtils.getConnection(driver, url, user, password); - stat = conn.createStatement(); - stat.execute("CREATE SCHEMA IF NOT EXISTS " + StringUtils.quoteIdentifier(targetSchema)); - rs = c2.getMetaData().getTables(null, sourceSchema, null, null); - while (rs.next()) { - String table = rs.getString("TABLE_NAME"); - StringBuilder buff = new StringBuilder(); - buff.append("DROP TABLE IF EXISTS "). - append(StringUtils.quoteIdentifier(targetSchema)). - append('.'). - append(StringUtils.quoteIdentifier(table)); - stat.execute(buff.toString()); - buff = new StringBuilder(); - buff.append("CREATE LINKED TABLE "). - append(StringUtils.quoteIdentifier(targetSchema)). - append('.'). - append(StringUtils.quoteIdentifier(table)). - append('('). - append(StringUtils.quoteStringSQL(driver)). - append(", "). - append(StringUtils.quoteStringSQL(url)). - append(", "). - append(StringUtils.quoteStringSQL(user)). - append(", "). - append(StringUtils.quoteStringSQL(password)). - append(", "). - append(StringUtils.quoteStringSQL(table)). - append(')'); - stat.execute(buff.toString()); - result.addRow(table); - } - } catch (SQLException e) { - throw DbException.convert(e); - } finally { - JdbcUtils.closeSilently(rs); - JdbcUtils.closeSilently(c2); - JdbcUtils.closeSilently(stat); - } - return result; - } -} diff --git a/tools/h2/src/main/org/h2/table/MetaTable.java b/tools/h2/src/main/org/h2/table/MetaTable.java deleted file mode 100755 index f993667..0000000 --- a/tools/h2/src/main/org/h2/table/MetaTable.java +++ /dev/null @@ -1,1779 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.table; - -import java.io.ByteArrayInputStream; -import java.io.InputStreamReader; -import java.io.Reader; -import java.sql.DatabaseMetaData; -import java.sql.ResultSet; -import java.sql.Timestamp; -import java.text.Collator; -import java.util.ArrayList; -import java.util.Locale; -import org.h2.command.Command; -import org.h2.constant.SysProperties; -import org.h2.constraint.Constraint; -import org.h2.constraint.ConstraintCheck; -import org.h2.constraint.ConstraintReferential; -import org.h2.constraint.ConstraintUnique; -import org.h2.engine.Constants; -import org.h2.engine.Database; -import org.h2.engine.DbObject; -import org.h2.engine.FunctionAlias; -import org.h2.engine.Right; -import org.h2.engine.Role; -import org.h2.engine.Session; -import org.h2.engine.Setting; -import org.h2.engine.User; -import org.h2.engine.UserAggregate; -import org.h2.engine.UserDataType; -import org.h2.expression.ValueExpression; -import org.h2.index.Index; -import org.h2.index.IndexType; -import org.h2.index.MetaIndex; -import org.h2.index.MultiVersionIndex; -import org.h2.message.DbException; -import org.h2.result.Row; -import org.h2.result.SearchRow; -import org.h2.result.SortOrder; -import org.h2.schema.Constant; -import org.h2.schema.Schema; -import org.h2.schema.SchemaObject; -import org.h2.schema.Sequence; -import org.h2.schema.TriggerObject; -import org.h2.store.InDoubtTransaction; -import org.h2.store.PageStore; -import org.h2.tools.Csv; -import org.h2.util.MathUtils; -import org.h2.util.New; -import org.h2.util.StatementBuilder; -import org.h2.util.StringUtils; -import org.h2.util.Utils; -import org.h2.value.CompareMode; -import org.h2.value.DataType; -import org.h2.value.Value; -import org.h2.value.ValueNull; -import org.h2.value.ValueString; - -/** - * This class is responsible to build the database meta data pseudo tables. - */ -public class MetaTable extends Table { - - /** - * The approximate number of rows of a meta table. - */ - public static final long ROW_COUNT_APPROXIMATION = 1000; - - private static final String CHARACTER_SET_NAME = "Unicode"; - - private static final int TABLES = 0; - private static final int COLUMNS = 1; - private static final int INDEXES = 2; - private static final int TABLE_TYPES = 3; - private static final int TYPE_INFO = 4; - private static final int CATALOGS = 5; - private static final int SETTINGS = 6; - private static final int HELP = 7; - private static final int SEQUENCES = 8; - private static final int USERS = 9; - private static final int ROLES = 10; - private static final int RIGHTS = 11; - private static final int FUNCTION_ALIASES = 12; - private static final int SCHEMATA = 13; - private static final int TABLE_PRIVILEGES = 14; - private static final int COLUMN_PRIVILEGES = 15; - private static final int COLLATIONS = 16; - private static final int VIEWS = 17; - private static final int IN_DOUBT = 18; - private static final int CROSS_REFERENCES = 19; - private static final int CONSTRAINTS = 20; - private static final int FUNCTION_COLUMNS = 21; - private static final int CONSTANTS = 22; - private static final int DOMAINS = 23; - private static final int TRIGGERS = 24; - private static final int SESSIONS = 25; - private static final int LOCKS = 26; - private static final int SESSION_STATE = 27; - private static final int META_TABLE_TYPE_COUNT = SESSION_STATE + 1; - - private final int type; - private final int indexColumn; - private MetaIndex metaIndex; - - /** - * Create a new metadata table. - * - * @param schema the schema - * @param id the object id - * @param type the meta table type - */ - public MetaTable(Schema schema, int id, int type) { - // tableName will be set later - super(schema, id, null, true, true); - this.type = type; - Column[] cols; - String indexColumnName = null; - switch(type) { - case TABLES: - setObjectName("TABLES"); - cols = createColumns( - "TABLE_CATALOG", - "TABLE_SCHEMA", - "TABLE_NAME", - "TABLE_TYPE", - // extensions - "STORAGE_TYPE", - "SQL", - "REMARKS", - "LAST_MODIFICATION BIGINT", - "ID INT", - "TYPE_NAME", - "TABLE_CLASS" - ); - indexColumnName = "TABLE_NAME"; - break; - case COLUMNS: - setObjectName("COLUMNS"); - cols = createColumns( - "TABLE_CATALOG", - "TABLE_SCHEMA", - "TABLE_NAME", - "COLUMN_NAME", - "ORDINAL_POSITION INT", - "COLUMN_DEFAULT", - "IS_NULLABLE", - "DATA_TYPE INT", - "CHARACTER_MAXIMUM_LENGTH INT", - "CHARACTER_OCTET_LENGTH INT", - "NUMERIC_PRECISION INT", - "NUMERIC_PRECISION_RADIX INT", - "NUMERIC_SCALE INT", - "CHARACTER_SET_NAME", - "COLLATION_NAME", - // extensions - "TYPE_NAME", - "NULLABLE INT", - "IS_COMPUTED BIT", - "SELECTIVITY INT", - "CHECK_CONSTRAINT", - "SEQUENCE_NAME", - "REMARKS", - "SOURCE_DATA_TYPE SMALLINT" - ); - indexColumnName = "TABLE_NAME"; - break; - case INDEXES: - setObjectName("INDEXES"); - cols = createColumns( - "TABLE_CATALOG", - "TABLE_SCHEMA", - "TABLE_NAME", - "NON_UNIQUE BIT", - "INDEX_NAME", - "ORDINAL_POSITION SMALLINT", - "COLUMN_NAME", - "CARDINALITY INT", - "PRIMARY_KEY BIT", - "INDEX_TYPE_NAME", - "IS_GENERATED BIT", - "INDEX_TYPE SMALLINT", - "ASC_OR_DESC", - "PAGES INT", - "FILTER_CONDITION", - "REMARKS", - "SQL", - "ID INT", - "SORT_TYPE INT", - "CONSTRAINT_NAME", - "INDEX_CLASS" - ); - indexColumnName = "TABLE_NAME"; - break; - case TABLE_TYPES: - setObjectName("TABLE_TYPES"); - cols = createColumns("TYPE"); - break; - case TYPE_INFO: - setObjectName("TYPE_INFO"); - cols = createColumns( - "TYPE_NAME", - "DATA_TYPE INT", - "PRECISION INT", - "PREFIX", - "SUFFIX", - "PARAMS", - "AUTO_INCREMENT BIT", - "MINIMUM_SCALE SMALLINT", - "MAXIMUM_SCALE SMALLINT", - "RADIX INT", - "POS INT", - "CASE_SENSITIVE BIT", - "NULLABLE SMALLINT", - "SEARCHABLE SMALLINT" - ); - break; - case CATALOGS: - setObjectName("CATALOGS"); - cols = createColumns("CATALOG_NAME"); - break; - case SETTINGS: - setObjectName("SETTINGS"); - cols = createColumns("NAME", "VALUE"); - break; - case HELP: - setObjectName("HELP"); - cols = createColumns( - "ID INT", - "SECTION", - "TOPIC", - "SYNTAX", - "TEXT" - ); - break; - case SEQUENCES: - setObjectName("SEQUENCES"); - cols = createColumns( - "SEQUENCE_CATALOG", - "SEQUENCE_SCHEMA", - "SEQUENCE_NAME", - "CURRENT_VALUE BIGINT", - "INCREMENT BIGINT", - "IS_GENERATED BIT", - "REMARKS", - "CACHE BIGINT", - "ID INT" - ); - break; - case USERS: - setObjectName("USERS"); - cols = createColumns( - "NAME", - "ADMIN", - "REMARKS", - "ID INT" - ); - break; - case ROLES: - setObjectName("ROLES"); - cols = createColumns( - "NAME", - "REMARKS", - "ID INT" - ); - break; - case RIGHTS: - setObjectName("RIGHTS"); - cols = createColumns( - "GRANTEE", - "GRANTEETYPE", - "GRANTEDROLE", - "RIGHTS", - "TABLE_SCHEMA", - "TABLE_NAME", - "ID INT" - ); - indexColumnName = "TABLE_NAME"; - break; - case FUNCTION_ALIASES: - setObjectName("FUNCTION_ALIASES"); - cols = createColumns( - "ALIAS_CATALOG", - "ALIAS_SCHEMA", - "ALIAS_NAME", - "JAVA_CLASS", - "JAVA_METHOD", - "DATA_TYPE INT", - "COLUMN_COUNT INT", - "RETURNS_RESULT SMALLINT", - "REMARKS", - "ID INT", - "SOURCE" - ); - break; - case FUNCTION_COLUMNS: - setObjectName("FUNCTION_COLUMNS"); - cols = createColumns( - "ALIAS_CATALOG", - "ALIAS_SCHEMA", - "ALIAS_NAME", - "JAVA_CLASS", - "JAVA_METHOD", - "COLUMN_COUNT INT", - "POS INT", - "COLUMN_NAME", - "DATA_TYPE INT", - "TYPE_NAME", - "PRECISION INT", - "SCALE SMALLINT", - "RADIX SMALLINT", - "NULLABLE SMALLINT", - "COLUMN_TYPE SMALLINT", - "REMARKS", - "COLUMN_DEFAULT" - ); - break; - case SCHEMATA: - setObjectName("SCHEMATA"); - cols = createColumns( - "CATALOG_NAME", - "SCHEMA_NAME", - "SCHEMA_OWNER", - "DEFAULT_CHARACTER_SET_NAME", - "DEFAULT_COLLATION_NAME", - "IS_DEFAULT BIT", - "REMARKS", - "ID INT" - ); - break; - case TABLE_PRIVILEGES: - setObjectName("TABLE_PRIVILEGES"); - cols = createColumns( - "GRANTOR", - "GRANTEE", - "TABLE_CATALOG", - "TABLE_SCHEMA", - "TABLE_NAME", - "PRIVILEGE_TYPE", - "IS_GRANTABLE" - ); - indexColumnName = "TABLE_NAME"; - break; - case COLUMN_PRIVILEGES: - setObjectName("COLUMN_PRIVILEGES"); - cols = createColumns( - "GRANTOR", - "GRANTEE", - "TABLE_CATALOG", - "TABLE_SCHEMA", - "TABLE_NAME", - "COLUMN_NAME", - "PRIVILEGE_TYPE", - "IS_GRANTABLE" - ); - indexColumnName = "TABLE_NAME"; - break; - case COLLATIONS: - setObjectName("COLLATIONS"); - cols = createColumns( - "NAME", - "KEY" - ); - break; - case VIEWS: - setObjectName("VIEWS"); - cols = createColumns( - "TABLE_CATALOG", - "TABLE_SCHEMA", - "TABLE_NAME", - "VIEW_DEFINITION", - "CHECK_OPTION", - "IS_UPDATABLE", - "STATUS", - "REMARKS", - "ID INT" - ); - indexColumnName = "TABLE_NAME"; - break; - case IN_DOUBT: - setObjectName("IN_DOUBT"); - cols = createColumns( - "TRANSACTION", - "STATE" - ); - break; - case CROSS_REFERENCES: - setObjectName("CROSS_REFERENCES"); - cols = createColumns( - "PKTABLE_CATALOG", - "PKTABLE_SCHEMA", - "PKTABLE_NAME", - "PKCOLUMN_NAME", - "FKTABLE_CATALOG", - "FKTABLE_SCHEMA", - "FKTABLE_NAME", - "FKCOLUMN_NAME", - "ORDINAL_POSITION SMALLINT", - "UPDATE_RULE SMALLINT", - "DELETE_RULE SMALLINT", - "FK_NAME", - "PK_NAME", - "DEFERRABILITY SMALLINT" - ); - indexColumnName = "PKTABLE_NAME"; - break; - case CONSTRAINTS: - setObjectName("CONSTRAINTS"); - cols = createColumns( - "CONSTRAINT_CATALOG", - "CONSTRAINT_SCHEMA", - "CONSTRAINT_NAME", - "CONSTRAINT_TYPE", - "TABLE_CATALOG", - "TABLE_SCHEMA", - "TABLE_NAME", - "UNIQUE_INDEX_NAME", - "CHECK_EXPRESSION", - "COLUMN_LIST", - "REMARKS", - "SQL", - "ID INT" - ); - indexColumnName = "TABLE_NAME"; - break; - case CONSTANTS: - setObjectName("CONSTANTS"); - cols = createColumns( - "CONSTANT_CATALOG", - "CONSTANT_SCHEMA", - "CONSTANT_NAME", - "DATA_TYPE INT", - "REMARKS", - "SQL", - "ID INT" - ); - break; - case DOMAINS: - setObjectName("DOMAINS"); - cols = createColumns( - "DOMAIN_CATALOG", - "DOMAIN_SCHEMA", - "DOMAIN_NAME", - "COLUMN_DEFAULT", - "IS_NULLABLE", - "DATA_TYPE INT", - "PRECISION INT", - "SCALE INT", - "TYPE_NAME", - "SELECTIVITY INT", - "CHECK_CONSTRAINT", - "REMARKS", - "SQL", - "ID INT" - ); - break; - case TRIGGERS: - setObjectName("TRIGGERS"); - cols = createColumns( - "TRIGGER_CATALOG", - "TRIGGER_SCHEMA", - "TRIGGER_NAME", - "TRIGGER_TYPE", - "TABLE_CATALOG", - "TABLE_SCHEMA", - "TABLE_NAME", - "BEFORE BIT", - "JAVA_CLASS", - "QUEUE_SIZE INT", - "NO_WAIT BIT", - "REMARKS", - "SQL", - "ID INT" - ); - break; - case SESSIONS: { - setObjectName("SESSIONS"); - cols = createColumns( - "ID INT", - "USER_NAME", - "SESSION_START", - "STATEMENT", - "STATEMENT_START" - ); - break; - } - case LOCKS: { - setObjectName("LOCKS"); - cols = createColumns( - "TABLE_SCHEMA", - "TABLE_NAME", - "SESSION_ID INT", - "LOCK_TYPE" - ); - break; - } - case SESSION_STATE: { - setObjectName("SESSION_STATE"); - cols = createColumns( - "KEY", - "SQL" - ); - break; - } - default: - throw DbException.throwInternalError("type="+type); - } - setColumns(cols); - - if (indexColumnName == null) { - indexColumn = -1; - } else { - indexColumn = getColumn(indexColumnName).getColumnId(); - IndexColumn[] indexCols = IndexColumn.wrap(new Column[] { cols[indexColumn] }); - metaIndex = new MetaIndex(this, indexCols, false); - } - } - - private Column[] createColumns(String... names) { - Column[] cols = new Column[names.length]; - for (int i = 0; i < names.length; i++) { - String nameType = names[i]; - int idx = nameType.indexOf(' '); - int dataType; - String name; - if (idx < 0) { - dataType = Value.STRING; - name = nameType; - } else { - dataType = DataType.getTypeByName(nameType.substring(idx + 1)).type; - name = nameType.substring(0, idx); - } - cols[i] = new Column(name, dataType); - } - return cols; - } - - public String getDropSQL() { - return null; - } - - public String getCreateSQL() { - return null; - } - - public Index addIndex(Session session, String indexName, int indexId, IndexColumn[] cols, IndexType indexType, - boolean create, String indexComment) { - throw DbException.getUnsupportedException("META"); - } - - public void lock(Session session, boolean exclusive, boolean force) { - // nothing to do - } - - public boolean isLockedExclusively() { - return false; - } - - private String identifier(String s) { - if (database.getMode().lowerCaseIdentifiers) { - s = s == null ? null : StringUtils.toLowerEnglish(s); - } - return s; - } - - private ArrayList getAllTables(Session session) { - ArrayList
tables = database.getAllTablesAndViews(true); - ArrayList
tempTables = session.getLocalTempTables(); - tables.addAll(tempTables); - return tables; - } - - private boolean checkIndex(Session session, String value, Value indexFrom, Value indexTo) { - if (value == null || (indexFrom == null && indexTo == null)) { - return true; - } - Database db = session.getDatabase(); - Value v = ValueString.get(value); - if (indexFrom != null && db.compare(v, indexFrom) < 0) { - return false; - } - if (indexTo != null && db.compare(v, indexTo) > 0) { - return false; - } - return true; - } - - private String replaceNullWithEmpty(String s) { - return s == null ? "" : s; - } - - /** - * Generate the data for the given metadata table using the given first and - * last row filters. - * - * @param session the session - * @param first the first row to return - * @param last the last row to return - * @return the generated rows - */ - public ArrayList generateRows(Session session, SearchRow first, SearchRow last) { - Value indexFrom = null, indexTo = null; - - if (indexColumn >= 0) { - if (first != null) { - indexFrom = first.getValue(indexColumn); - } - if (last != null) { - indexTo = last.getValue(indexColumn); - } - } - - ArrayList rows = New.arrayList(); - String catalog = identifier(database.getShortName()); - switch (type) { - case TABLES: { - for (Table table : getAllTables(session)) { - String tableName = identifier(table.getName()); - if (!checkIndex(session, tableName, indexFrom, indexTo)) { - continue; - } - if (table.isHidden()) { - continue; - } - String storageType; - if (table.isTemporary()) { - if (table.isGlobalTemporary()) { - storageType = "GLOBAL TEMPORARY"; - } else { - storageType = "LOCAL TEMPORARY"; - } - } else { - storageType = table.isPersistIndexes() ? "CACHED" : "MEMORY"; - } - add(rows, - // TABLE_CATALOG - catalog, - // TABLE_SCHEMA - identifier(table.getSchema().getName()), - // TABLE_NAME - tableName, - // TABLE_TYPE - table.getTableType(), - // STORAGE_TYPE - storageType, - // SQL - table.getCreateSQL(), - // REMARKS - replaceNullWithEmpty(table.getComment()), - // LAST_MODIFICATION - "" + table.getMaxDataModificationId(), - // ID - "" + table.getId(), - // TYPE_NAME - null, - // TABLE_CLASS - table.getClass().getName() - ); - } - break; - } - case COLUMNS: { - for (Table table : getAllTables(session)) { - String tableName = identifier(table.getName()); - if (!checkIndex(session, tableName, indexFrom, indexTo)) { - continue; - } - if (table.isHidden()) { - continue; - } - Column[] cols = table.getColumns(); - String collation = database.getCompareMode().getName(); - for (int j = 0; j < cols.length; j++) { - Column c = cols[j]; - Sequence sequence = c.getSequence(); - add(rows, - // TABLE_CATALOG - catalog, - // TABLE_SCHEMA - identifier(table.getSchema().getName()), - // TABLE_NAME - tableName, - // COLUMN_NAME - identifier(c.getName()), - // ORDINAL_POSITION - String.valueOf(j + 1), - // COLUMN_DEFAULT - c.getDefaultSQL(), - // IS_NULLABLE - c.isNullable() ? "YES" : "NO", - // DATA_TYPE - "" + DataType.convertTypeToSQLType(c.getType()), - // CHARACTER_MAXIMUM_LENGTH - "" + c.getPrecisionAsInt(), - // CHARACTER_OCTET_LENGTH - "" + c.getPrecisionAsInt(), - // NUMERIC_PRECISION - "" + c.getPrecisionAsInt(), - // NUMERIC_PRECISION_RADIX - "10", - // NUMERIC_SCALE - "" + c.getScale(), - // CHARACTER_SET_NAME - CHARACTER_SET_NAME, - // COLLATION_NAME - collation, - // TYPE_NAME - identifier(DataType.getDataType(c.getType()).name), - // NULLABLE - "" + (c.isNullable() ? DatabaseMetaData.columnNullable : DatabaseMetaData.columnNoNulls) , - // IS_COMPUTED - "" + (c.getComputed() ? "TRUE" : "FALSE"), - // SELECTIVITY - "" + (c.getSelectivity()), - // CHECK_CONSTRAINT - c.getCheckConstraintSQL(session, c.getName()), - // SEQUENCE_NAME - sequence == null ? null : sequence.getName(), - // REMARKS - replaceNullWithEmpty(c.getComment()), - // SOURCE_DATA_TYPE - null - ); - } - } - break; - } - case INDEXES: { - for (Table table : getAllTables(session)) { - String tableName = identifier(table.getName()); - if (!checkIndex(session, tableName, indexFrom, indexTo)) { - continue; - } - if (table.isHidden()) { - continue; - } - ArrayList indexes = table.getIndexes(); - ArrayList constraints = table.getConstraints(); - for (int j = 0; indexes != null && j < indexes.size(); j++) { - Index index = indexes.get(j); - if (index.getCreateSQL() == null) { - continue; - } - String constraintName = null; - for (int k = 0; constraints != null && k < constraints.size(); k++) { - Constraint constraint = constraints.get(k); - if (constraint.usesIndex(index)) { - if (index.getIndexType().isPrimaryKey()) { - if (constraint.getConstraintType().equals(Constraint.PRIMARY_KEY)) { - constraintName = constraint.getName(); - } - } else { - constraintName = constraint.getName(); - } - } - } - IndexColumn[] cols = index.getIndexColumns(); - String indexClass; - if (index instanceof MultiVersionIndex) { - indexClass = ((MultiVersionIndex) index).getBaseIndex().getClass().getName(); - } else { - indexClass = index.getClass().getName(); - } - for (int k = 0; k < cols.length; k++) { - IndexColumn idxCol = cols[k]; - Column column = idxCol.column; - add(rows, - // TABLE_CATALOG - catalog, - // TABLE_SCHEMA - identifier(table.getSchema().getName()), - // TABLE_NAME - tableName, - // NON_UNIQUE - index.getIndexType().isUnique() ? "FALSE" : "TRUE", - // INDEX_NAME - identifier(index.getName()), - // ORDINAL_POSITION - "" + (k+1), - // COLUMN_NAME - identifier(column.getName()), - // CARDINALITY - "0", - // PRIMARY_KEY - index.getIndexType().isPrimaryKey() ? "TRUE" : "FALSE", - // INDEX_TYPE_NAME - index.getIndexType().getSQL(), - // IS_GENERATED - index.getIndexType().getBelongsToConstraint() ? "TRUE" : "FALSE", - // INDEX_TYPE - "" + DatabaseMetaData.tableIndexOther, - // ASC_OR_DESC - (idxCol.sortType & SortOrder.DESCENDING) != 0 ? "D" : "A", - // PAGES - "0", - // FILTER_CONDITION - "", - // REMARKS - replaceNullWithEmpty(index.getComment()), - // SQL - index.getCreateSQL(), - // ID - "" + index.getId(), - // SORT_TYPE - "" + idxCol.sortType, - // CONSTRAINT_NAME - constraintName, - // INDEX_CLASS - indexClass - ); - } - } - } - break; - } - case TABLE_TYPES: { - add(rows, Table.TABLE); - add(rows, Table.TABLE_LINK); - add(rows, Table.SYSTEM_TABLE); - add(rows, Table.VIEW); - break; - } - case CATALOGS: { - add(rows, catalog); - break; - } - case SETTINGS: { - for (Setting s : database.getAllSettings()) { - String value = s.getStringValue(); - if (value == null) { - value = "" + s.getIntValue(); - } - add(rows, - identifier(s.getName()), - value - ); - } - add(rows, "info.BUILD_ID", "" + Constants.BUILD_ID); - add(rows, "info.VERSION_MAJOR", "" + Constants.VERSION_MAJOR); - add(rows, "info.VERSION_MINOR", "" + Constants.VERSION_MINOR); - add(rows, "info.VERSION", "" + Constants.getFullVersion()); - if (session.getUser().isAdmin()) { - String[] settings = { - "java.runtime.version", - "java.vm.name", "java.vendor", - "os.name", "os.arch", "os.version", "sun.os.patch.level", - "file.separator", "path.separator", "line.separator", - "user.country", "user.language", "user.variant", "file.encoding" - }; - for (String s : settings) { - add(rows, "property." + s, SysProperties.getStringSetting(s, "")); - } - } - add(rows, "EXCLUSIVE", database.getExclusiveSession() == null ? "FALSE" : "TRUE"); - add(rows, "MODE", database.getMode().getName()); - add(rows, "MULTI_THREADED", database.isMultiThreaded() ? "1" : "0"); - add(rows, "MVCC", database.isMultiVersion() ? "TRUE" : "FALSE"); - add(rows, "QUERY_TIMEOUT", "" + session.getQueryTimeout()); - // the setting for the current database - add(rows, "h2.allowBigDecimalExtensions", "" + SysProperties.ALLOW_BIG_DECIMAL_EXTENSIONS); - add(rows, "h2.baseDir", "" + SysProperties.getBaseDir()); - add(rows, "h2.check", "" + SysProperties.CHECK); - add(rows, "h2.check2", "" + SysProperties.CHECK2); - add(rows, "h2.clientTraceDirectory", SysProperties.CLIENT_TRACE_DIRECTORY); - add(rows, SysProperties.H2_COLLATOR_CACHE_SIZE, "" + SysProperties.getCollatorCacheSize()); - add(rows, "h2.defaultMaxMemoryUndo", "" + SysProperties.DEFAULT_MAX_MEMORY_UNDO); - add(rows, "h2.lobFilesPerDirectory", "" + SysProperties.LOB_FILES_PER_DIRECTORY); - add(rows, "h2.logAllErrors", "" + SysProperties.LOG_ALL_ERRORS); - add(rows, "h2.logAllErrorsFile", "" + SysProperties.LOG_ALL_ERRORS_FILE); - add(rows, "h2.maxFileRetry", "" + SysProperties.MAX_FILE_RETRY); - add(rows, SysProperties.H2_MAX_QUERY_TIMEOUT, "" + SysProperties.getMaxQueryTimeout()); - add(rows, "h2.lobCloseBetweenReads", "" + SysProperties.lobCloseBetweenReads); - add(rows, "h2.objectCache", "" + SysProperties.OBJECT_CACHE); - add(rows, "h2.objectCacheSize", "" + SysProperties.OBJECT_CACHE_SIZE); - add(rows, "h2.objectCacheMaxPerElementSize", "" + SysProperties.OBJECT_CACHE_MAX_PER_ELEMENT_SIZE); - add(rows, "h2.optimizeInList", "" + SysProperties.OPTIMIZE_IN_LIST); - add(rows, "h2.optimizeSubqueryCache", "" + SysProperties.OPTIMIZE_SUBQUERY_CACHE); - add(rows, "h2.recompileAlways", "" + SysProperties.RECOMPILE_ALWAYS); - add(rows, "h2.redoBufferSize", "" + SysProperties.REDO_BUFFER_SIZE); - add(rows, "h2.runFinalize", "" + SysProperties.runFinalize); - add(rows, "h2.scriptDirectory", SysProperties.getScriptDirectory()); - add(rows, "h2.serverCachedObjects", "" + SysProperties.SERVER_CACHED_OBJECTS); - add(rows, "h2.serverResultSetFetchSize", "" + SysProperties.SERVER_RESULT_SET_FETCH_SIZE); - add(rows, "h2.sortNullsHigh", "" + SysProperties.SORT_NULLS_HIGH); - if (database.isPersistent()) { - PageStore store = database.getPageStore(); - add(rows, "info.FILE_WRITE_TOTAL", "" + store.getWriteCountTotal()); - add(rows, "info.FILE_WRITE", "" + store.getWriteCount()); - add(rows, "info.FILE_READ", "" + store.getReadCount()); - add(rows, "info.CACHE_MAX_SIZE", "" + store.getCache().getMaxSize()); - add(rows, "info.CACHE_SIZE", "" + store.getCache().getSize()); - } - break; - } - case TYPE_INFO: { - for (DataType t : DataType.getTypes()) { - if (t.hidden || t.sqlType == Value.NULL) { - continue; - } - add(rows, - // TYPE_NAME - t.name, - // DATA_TYPE - String.valueOf(t.sqlType), - // PRECISION - String.valueOf(MathUtils.convertLongToInt(t.maxPrecision)), - // PREFIX - t.prefix, - // SUFFIX - t.suffix, - // PARAMS - t.params, - // AUTO_INCREMENT - String.valueOf(t.autoIncrement), - // MINIMUM_SCALE - String.valueOf(t.minScale), - // MAXIMUM_SCALE - String.valueOf(t.maxScale), - // RADIX - t.decimal ? "10" : null, - // POS - String.valueOf(t.sqlTypePos), - // CASE_SENSITIVE - String.valueOf(t.caseSensitive), - // NULLABLE - "" + DatabaseMetaData.typeNullable, - // SEARCHABLE - "" + DatabaseMetaData.typeSearchable - ); - } - break; - } - case HELP: { - String resource = "/org/h2/res/help.csv"; - try { - byte[] data = Utils.getResource(resource); - Reader reader = new InputStreamReader(new ByteArrayInputStream(data)); - ResultSet rs = Csv.getInstance().read(reader, null); - for (int i = 0; rs.next(); i++) { - add(rows, - // ID - String.valueOf(i), - // SECTION - rs.getString(1).trim(), - // TOPIC - rs.getString(2).trim(), - // SYNTAX - rs.getString(3).trim(), - // TEXT - rs.getString(4).trim() - ); - } - } catch (Exception e) { - throw DbException.convert(e); - } - break; - } - case SEQUENCES: { - for (SchemaObject obj : database.getAllSchemaObjects(DbObject.SEQUENCE)) { - Sequence s = (Sequence) obj; - add(rows, - // SEQUENCE_CATALOG - catalog, - // SEQUENCE_SCHEMA - identifier(s.getSchema().getName()), - // SEQUENCE_NAME - identifier(s.getName()), - // CURRENT_VALUE - String.valueOf(s.getCurrentValue()), - // INCREMENT - String.valueOf(s.getIncrement()), - // IS_GENERATED - s.getBelongsToTable() ? "TRUE" : "FALSE", - // REMARKS - replaceNullWithEmpty(s.getComment()), - // CACHE - String.valueOf(s.getCacheSize()), - // ID - "" + s.getId() - ); - } - break; - } - case USERS: { - for (User u : database.getAllUsers()) { - add(rows, - // NAME - identifier(u.getName()), - // ADMIN - String.valueOf(u.isAdmin()), - // REMARKS - replaceNullWithEmpty(u.getComment()), - // ID - "" + u.getId() - ); - } - break; - } - case ROLES: { - for (Role r : database.getAllRoles()) { - add(rows, - // NAME - identifier(r.getName()), - // REMARKS - replaceNullWithEmpty(r.getComment()), - // ID - "" + r.getId() - ); - } - break; - } - case RIGHTS: { - for (Right r : database.getAllRights()) { - Role role = r.getGrantedRole(); - DbObject grantee = r.getGrantee(); - String rightType = grantee.getType() == DbObject.USER ? "USER" : "ROLE"; - if (role == null) { - Table granted = r.getGrantedTable(); - String tableName = identifier(granted.getName()); - if (!checkIndex(session, tableName, indexFrom, indexTo)) { - continue; - } - add(rows, - // GRANTEE - identifier(grantee.getName()), - // GRANTEETYPE - rightType, - // GRANTEDROLE - "", - // RIGHTS - r.getRights(), - // TABLE_SCHEMA - identifier(granted.getSchema().getName()), - // TABLE_NAME - identifier(granted.getName()), - // ID - "" + r.getId() - ); - } else { - add(rows, - // GRANTEE - identifier(grantee.getName()), - // GRANTEETYPE - rightType, - // GRANTEDROLE - identifier(role.getName()), - // RIGHTS - "", - // TABLE_SCHEMA - "", - // TABLE_NAME - "", - // ID - "" + r.getId() - ); - } - } - break; - } - case FUNCTION_ALIASES: { - for (SchemaObject aliasAsSchemaObject : database.getAllSchemaObjects(DbObject.FUNCTION_ALIAS)) { - FunctionAlias alias = (FunctionAlias) aliasAsSchemaObject; - for (FunctionAlias.JavaMethod method : alias.getJavaMethods()) { - int returnsResult = method.getDataType() == Value.NULL ? DatabaseMetaData.procedureNoResult - : DatabaseMetaData.procedureReturnsResult; - add(rows, - // ALIAS_CATALOG - catalog, - // ALIAS_SCHEMA - alias.getSchema().getName(), - // ALIAS_NAME - identifier(alias.getName()), - // JAVA_CLASS - alias.getJavaClassName(), - // JAVA_METHOD - alias.getJavaMethodName(), - // DATA_TYPE - "" + DataType.convertTypeToSQLType(method.getDataType()), - // COLUMN_COUNT INT - "" + method.getColumnClasses().length, - // RETURNS_RESULT SMALLINT - "" + returnsResult, - // REMARKS - replaceNullWithEmpty(alias.getComment()), - // ID - "" + alias.getId(), - // SOURCE - alias.getSource() - ); - } - } - for (UserAggregate agg : database.getAllAggregates()) { - int returnsResult = DatabaseMetaData.procedureReturnsResult; - add(rows, - // ALIAS_CATALOG - catalog, - // ALIAS_SCHEMA - Constants.SCHEMA_MAIN, - // ALIAS_NAME - identifier(agg.getName()), - // JAVA_CLASS - agg.getJavaClassName(), - // JAVA_METHOD - "", - // DATA_TYPE - "" + DataType.convertTypeToSQLType(Value.NULL), - // COLUMN_COUNT INT - "1", - // RETURNS_RESULT SMALLINT - "" + returnsResult, - // REMARKS - replaceNullWithEmpty(agg.getComment()), - // ID - "" + agg.getId() - ); - } - break; - } - case FUNCTION_COLUMNS: { - for (SchemaObject aliasAsSchemaObject : database.getAllSchemaObjects(DbObject.FUNCTION_ALIAS)) { - FunctionAlias alias = (FunctionAlias) aliasAsSchemaObject; - for (FunctionAlias.JavaMethod method : alias.getJavaMethods()) { - Class< ? >[] columnList = method.getColumnClasses(); - for (int k = 0; k < columnList.length; k++) { - Class< ? > clazz = columnList[k]; - int dataType = DataType.getTypeFromClass(clazz); - DataType dt = DataType.getDataType(dataType); - int nullable = clazz.isPrimitive() ? DatabaseMetaData.columnNoNulls - : DatabaseMetaData.columnNullable; - add(rows, - // ALIAS_CATALOG - catalog, - // ALIAS_SCHEMA - alias.getSchema().getName(), - // ALIAS_NAME - identifier(alias.getName()), - // JAVA_CLASS - alias.getJavaClassName(), - // JAVA_METHOD - alias.getJavaMethodName(), - // COLUMN_COUNT - "" + method.getParameterCount(), - // POS INT - "" + k, - // COLUMN_NAME - "P" + (k+1), - // DATA_TYPE - "" + DataType.convertTypeToSQLType(dt.type), - // TYPE_NAME - dt.name, - // PRECISION - "" + dt.defaultPrecision, - // SCALE - "" + dt.defaultScale, - // RADIX - "10", - // NULLABLE SMALLINT - "" + nullable, - // COLUMN_TYPE - "" + DatabaseMetaData.procedureColumnIn, - // REMARKS - "", - // COLUMN_DEFAULT - null - ); - } - } - } - break; - } - case SCHEMATA: { - String collation = database.getCompareMode().getName(); - for (Schema schema : database.getAllSchemas()) { - add(rows, - // CATALOG_NAME - catalog, - // SCHEMA_NAME - identifier(schema.getName()), - // SCHEMA_OWNER - identifier(schema.getOwner().getName()), - // DEFAULT_CHARACTER_SET_NAME - CHARACTER_SET_NAME, - // DEFAULT_COLLATION_NAME - collation, - // IS_DEFAULT - Constants.SCHEMA_MAIN.equals(schema.getName()) ? "TRUE" : "FALSE", - // REMARKS - replaceNullWithEmpty(schema.getComment()), - // ID - "" + schema.getId() - ); - } - break; - } - case TABLE_PRIVILEGES: { - for (Right r : database.getAllRights()) { - Table table = r.getGrantedTable(); - if (table == null || table.isHidden()) { - continue; - } - String tableName = identifier(table.getName()); - if (!checkIndex(session, tableName, indexFrom, indexTo)) { - continue; - } - addPrivileges(rows, r.getGrantee(), catalog, table, null, r.getRightMask()); - } - break; - } - case COLUMN_PRIVILEGES: { - for (Right r : database.getAllRights()) { - Table table = r.getGrantedTable(); - if (table == null || table.isHidden()) { - continue; - } - String tableName = identifier(table.getName()); - if (!checkIndex(session, tableName, indexFrom, indexTo)) { - continue; - } - DbObject grantee = r.getGrantee(); - int mask = r.getRightMask(); - for (Column column : table.getColumns()) { - addPrivileges(rows, grantee, catalog, table, column.getName(), mask); - } - } - break; - } - case COLLATIONS: { - for (Locale l : Collator.getAvailableLocales()) { - add(rows, - // NAME - CompareMode.getName(l), - // KEY - l.toString() - ); - } - break; - } - case VIEWS: { - for (Table table : getAllTables(session)) { - if (!table.getTableType().equals(Table.VIEW)) { - continue; - } - String tableName = identifier(table.getName()); - if (!checkIndex(session, tableName, indexFrom, indexTo)) { - continue; - } - TableView view = (TableView) table; - add(rows, - // TABLE_CATALOG - catalog, - // TABLE_SCHEMA - identifier(table.getSchema().getName()), - // TABLE_NAME - tableName, - // VIEW_DEFINITION - table.getCreateSQL(), - // CHECK_OPTION - "NONE", - // IS_UPDATABLE - "NO", - // STATUS - view.isInvalid() ? "INVALID" : "VALID", - // REMARKS - replaceNullWithEmpty(view.getComment()), - // ID - "" + view.getId() - ); - } - break; - } - case IN_DOUBT: { - ArrayList prepared = database.getInDoubtTransactions(); - if (prepared != null) { - for (InDoubtTransaction prep : prepared) { - add(rows, - // TRANSACTION - prep.getTransaction(), - // STATE - prep.getState() - ); - } - } - break; - } - case CROSS_REFERENCES: { - for (SchemaObject obj : database.getAllSchemaObjects(DbObject.CONSTRAINT)) { - Constraint constraint = (Constraint) obj; - if (!(constraint.getConstraintType().equals(Constraint.REFERENTIAL))) { - continue; - } - ConstraintReferential ref = (ConstraintReferential) constraint; - IndexColumn[] cols = ref.getColumns(); - IndexColumn[] refCols = ref.getRefColumns(); - Table tab = ref.getTable(); - Table refTab = ref.getRefTable(); - String tableName = identifier(refTab.getName()); - if (!checkIndex(session, tableName, indexFrom, indexTo)) { - continue; - } - int update = getRefAction(ref.getUpdateAction()); - int delete = getRefAction(ref.getDeleteAction()); - for (int j = 0; j < cols.length; j++) { - add(rows, - // PKTABLE_CATALOG - catalog, - // PKTABLE_SCHEMA - identifier(refTab.getSchema().getName()), - // PKTABLE_NAME - identifier(refTab.getName()), - // PKCOLUMN_NAME - identifier(refCols[j].column.getName()), - // FKTABLE_CATALOG - catalog, - // FKTABLE_SCHEMA - identifier(tab.getSchema().getName()), - // FKTABLE_NAME - identifier(tab.getName()), - // FKCOLUMN_NAME - identifier(cols[j].column.getName()), - // ORDINAL_POSITION - String.valueOf(j + 1), - // UPDATE_RULE SMALLINT - String.valueOf(update), - // DELETE_RULE SMALLINT - String.valueOf(delete), - // FK_NAME - identifier(ref.getName()), - // PK_NAME - null, - // DEFERRABILITY - "" + DatabaseMetaData.importedKeyNotDeferrable - ); - } - } - break; - } - case CONSTRAINTS: { - for (SchemaObject obj : database.getAllSchemaObjects(DbObject.CONSTRAINT)) { - Constraint constraint = (Constraint) obj; - String constraintType = constraint.getConstraintType(); - String checkExpression = null; - IndexColumn[] indexColumns = null; - Table table = constraint.getTable(); - if (table.isHidden()) { - continue; - } - Index index = constraint.getUniqueIndex(); - String uniqueIndexName = null; - if (index != null) { - uniqueIndexName = index.getName(); - } - String tableName = identifier(table.getName()); - if (!checkIndex(session, tableName, indexFrom, indexTo)) { - continue; - } - if (constraintType.equals(Constraint.CHECK)) { - checkExpression = ((ConstraintCheck) constraint).getExpression().getSQL(); - } else if (constraintType.equals(Constraint.UNIQUE) || constraintType.equals(Constraint.PRIMARY_KEY)) { - indexColumns = ((ConstraintUnique) constraint).getColumns(); - } else if (constraintType.equals(Constraint.REFERENTIAL)) { - indexColumns = ((ConstraintReferential) constraint).getColumns(); - } - String columnList = null; - if (indexColumns != null) { - StatementBuilder buff = new StatementBuilder(); - for (IndexColumn col : indexColumns) { - buff.appendExceptFirst(","); - buff.append(col.column.getName()); - } - columnList = buff.toString(); - } - add(rows, - // CONSTRAINT_CATALOG - catalog, - // CONSTRAINT_SCHEMA - identifier(constraint.getSchema().getName()), - // CONSTRAINT_NAME - identifier(constraint.getName()), - // CONSTRAINT_TYPE - constraintType, - // TABLE_CATALOG - catalog, - // TABLE_SCHEMA - identifier(table.getSchema().getName()), - // TABLE_NAME - tableName, - // UNIQUE_INDEX_NAME - uniqueIndexName, - // CHECK_EXPRESSION - checkExpression, - // COLUMN_LIST - columnList, - // REMARKS - replaceNullWithEmpty(constraint.getComment()), - // SQL - constraint.getCreateSQL(), - // ID - "" + constraint.getId() - ); - } - break; - } - case CONSTANTS: { - for (SchemaObject obj : database.getAllSchemaObjects(DbObject.CONSTANT)) { - Constant constant = (Constant) obj; - ValueExpression expr = constant.getValue(); - add(rows, - // CONSTANT_CATALOG - catalog, - // CONSTANT_SCHEMA - identifier(constant.getSchema().getName()), - // CONSTANT_NAME - identifier(constant.getName()), - // CONSTANT_TYPE - "" + DataType.convertTypeToSQLType(expr.getType()), - // REMARKS - replaceNullWithEmpty(constant.getComment()), - // SQL - expr.getSQL(), - // ID - "" + constant.getId() - ); - } - break; - } - case DOMAINS: { - for (UserDataType dt : database.getAllUserDataTypes()) { - Column col = dt.getColumn(); - add(rows, - // DOMAIN_CATALOG - catalog, - // DOMAIN_SCHEMA - Constants.SCHEMA_MAIN, - // DOMAIN_NAME - identifier(dt.getName()), - // COLUMN_DEFAULT - col.getDefaultSQL(), - // IS_NULLABLE - col.isNullable() ? "YES" : "NO", - // DATA_TYPE - "" + col.getDataType().sqlType, - // PRECISION INT - "" + col.getPrecisionAsInt(), - // SCALE INT - "" + col.getScale(), - // TYPE_NAME - col.getDataType().name, - // SELECTIVITY INT - "" + col.getSelectivity(), - // CHECK_CONSTRAINT - "" + col.getCheckConstraintSQL(session, "VALUE"), - // REMARKS - replaceNullWithEmpty(dt.getComment()), - // SQL - "" + dt.getCreateSQL(), - // ID - "" + dt.getId() - ); - } - break; - } - case TRIGGERS: { - for (SchemaObject obj : database.getAllSchemaObjects(DbObject.TRIGGER)) { - TriggerObject trigger = (TriggerObject) obj; - Table table = trigger.getTable(); - add(rows, - // TRIGGER_CATALOG - catalog, - // TRIGGER_SCHEMA - identifier(trigger.getSchema().getName()), - // TRIGGER_NAME - identifier(trigger.getName()), - // TRIGGER_TYPE - trigger.getTypeNameList(), - // TABLE_CATALOG - catalog, - // TABLE_SCHEMA - identifier(table.getSchema().getName()), - // TABLE_NAME - identifier(table.getName()), - // BEFORE BIT - "" + trigger.isBefore(), - // JAVA_CLASS - trigger.getTriggerClassName(), - // QUEUE_SIZE INT - "" + trigger.getQueueSize(), - // NO_WAIT BIT - "" + trigger.isNoWait(), - // REMARKS - replaceNullWithEmpty(trigger.getComment()), - // SQL - trigger.getCreateSQL(), - // ID - "" + trigger.getId() - ); - } - break; - } - case SESSIONS: { - boolean admin = session.getUser().isAdmin(); - for (Session s : database.getSessions(false)) { - if (admin || s == session) { - Command command = s.getCurrentCommand(); - add(rows, - // ID - "" + s.getId(), - // USER_NAME - s.getUser().getName(), - // SESSION_START - new Timestamp(s.getSessionStart()).toString(), - // STATEMENT - command == null ? null : command.toString(), - // STATEMENT_START - new Timestamp(s.getCurrentCommandStart()).toString() - ); - } - } - break; - } - case LOCKS: { - boolean admin = session.getUser().isAdmin(); - for (Session s : database.getSessions(false)) { - if (admin || s == session) { - for (Table table : s.getLocks()) { - add(rows, - // TABLE_SCHEMA - table.getSchema().getName(), - // TABLE_NAME - table.getName(), - // SESSION_ID - "" + s.getId(), - // LOCK_TYPE - table.isLockedExclusivelyBy(s) ? "WRITE" : "READ" - ); - } - } - } - break; - } - case SESSION_STATE: { - for (String name : session.getVariableNames()) { - Value v = session.getVariable(name); - add(rows, - // KEY - "@" + name, - // SQL - "SET @" + name + " " + v.getSQL() - ); - } - for (Table table : session.getLocalTempTables()) { - add(rows, - // KEY - "TABLE " + table.getName(), - // SQL - table.getCreateSQL() - ); - } - String[] path = session.getSchemaSearchPath(); - if (path != null && path.length > 0) { - StatementBuilder buff = new StatementBuilder("SET SCHEMA_SEARCH_PATH "); - for (String p : path) { - buff.appendExceptFirst(", "); - buff.append(StringUtils.quoteIdentifier(p)); - } - add(rows, - // KEY - "SCHEMA_SEARCH_PATH", - // SQL - buff.toString() - ); - } - String schema = session.getCurrentSchemaName(); - if (schema != null) { - add(rows, - // KEY - "SCHEMA", - // SQL - "SET SCHEMA " + StringUtils.quoteIdentifier(schema) - ); - } - break; - } - default: - DbException.throwInternalError("type="+type); - } - return rows; - } - - private int getRefAction(int action) { - switch(action) { - case ConstraintReferential.CASCADE: - return DatabaseMetaData.importedKeyCascade; - case ConstraintReferential.RESTRICT: - return DatabaseMetaData.importedKeyRestrict; - case ConstraintReferential.SET_DEFAULT: - return DatabaseMetaData.importedKeySetDefault; - case ConstraintReferential.SET_NULL: - return DatabaseMetaData.importedKeySetNull; - default: - throw DbException.throwInternalError("action="+action); - } - } - - public void removeRow(Session session, Row row) { - throw DbException.getUnsupportedException("META"); - } - - public void addRow(Session session, Row row) { - throw DbException.getUnsupportedException("META"); - } - - public void removeChildrenAndResources(Session session) { - throw DbException.getUnsupportedException("META"); - } - - public void close(Session session) { - // nothing to do - } - - public void unlock(Session s) { - // nothing to do - } - - private void addPrivileges(ArrayList rows, DbObject grantee, String catalog, Table table, String column, - int rightMask) { - if ((rightMask & Right.SELECT) != 0) { - addPrivilege(rows, grantee, catalog, table, column, "SELECT"); - } - if ((rightMask & Right.INSERT) != 0) { - addPrivilege(rows, grantee, catalog, table, column, "INSERT"); - } - if ((rightMask & Right.UPDATE) != 0) { - addPrivilege(rows, grantee, catalog, table, column, "UPDATE"); - } - if ((rightMask & Right.DELETE) != 0) { - addPrivilege(rows, grantee, catalog, table, column, "DELETE"); - } - } - - private void addPrivilege(ArrayList rows, DbObject grantee, String catalog, Table table, String column, - String right) { - String isGrantable = "NO"; - if (grantee.getType() == DbObject.USER) { - User user = (User) grantee; - if (user.isAdmin()) { - // the right is grantable if the grantee is an admin - isGrantable = "YES"; - } - } - if (column == null) { - add(rows, - // GRANTOR - null, - // GRANTEE - identifier(grantee.getName()), - // TABLE_CATALOG - catalog, - // TABLE_SCHEMA - identifier(table.getSchema().getName()), - // TABLE_NAME - identifier(table.getName()), - // PRIVILEGE_TYPE - right, - // IS_GRANTABLE - isGrantable - ); - } else { - add(rows, - // GRANTOR - null, - // GRANTEE - identifier(grantee.getName()), - // TABLE_CATALOG - catalog, - // TABLE_SCHEMA - identifier(table.getSchema().getName()), - // TABLE_NAME - identifier(table.getName()), - // COLUMN_NAME - identifier(column), - // PRIVILEGE_TYPE - right, - // IS_GRANTABLE - isGrantable - ); - } - } - - private void add(ArrayList rows, String... strings) { - Value[] values = new Value[strings.length]; - for (int i = 0; i < strings.length; i++) { - String s = strings[i]; - Value v = (s == null) ? (Value) ValueNull.INSTANCE : ValueString.get(s); - Column col = columns[i]; - v = col.convert(v); - values[i] = v; - } - Row row = new Row(values, 1); - row.setKey(rows.size()); - rows.add(row); - } - - public void checkRename() { - throw DbException.getUnsupportedException("META"); - } - - public void checkSupportAlter() { - throw DbException.getUnsupportedException("META"); - } - - public void truncate(Session session) { - throw DbException.getUnsupportedException("META"); - } - - public long getRowCount(Session session) { - throw DbException.throwInternalError(); - } - - public boolean canGetRowCount() { - return false; - } - - public boolean canDrop() { - return false; - } - - public String getTableType() { - return Table.SYSTEM_TABLE; - } - - public Index getScanIndex(Session session) { - return new MetaIndex(this, IndexColumn.wrap(columns), true); - } - - public ArrayList getIndexes() { - ArrayList list = New.arrayList(); - if (metaIndex == null) { - return list; - } - list.add(new MetaIndex(this, IndexColumn.wrap(columns), true)); - // TODO re-use the index - list.add(metaIndex); - return list; - } - - public long getMaxDataModificationId() { - return database.getModificationDataId(); - } - - public Index getUniqueIndex() { - return null; - } - - /** - * Get the number of meta table types. Supported meta table - * types are 0 .. this value - 1. - * - * @return the number of meta table types - */ - public static int getMetaTableTypeCount() { - return META_TABLE_TYPE_COUNT; - } - - public long getRowCountApproximation() { - return ROW_COUNT_APPROXIMATION; - } - - public boolean isDeterministic() { - return true; - } - - public boolean canReference() { - return false; - } - -} diff --git a/tools/h2/src/main/org/h2/table/Plan.java b/tools/h2/src/main/org/h2/table/Plan.java deleted file mode 100755 index bff3e2c..0000000 --- a/tools/h2/src/main/org/h2/table/Plan.java +++ /dev/null @@ -1,133 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.table; - -import java.util.ArrayList; -import java.util.HashMap; -import org.h2.engine.Session; -import org.h2.expression.Expression; -import org.h2.expression.ExpressionVisitor; -import org.h2.util.New; - -/** - * A possible query execution plan. The time required to execute a query depends - * on the order the tables are accessed. - */ -public class Plan { - private final TableFilter[] filters; - private final HashMap planItems = New.hashMap(); - private final Expression[] allConditions; - private final TableFilter[] allFilters; - - /** - * Create a query plan with the given order. - * - * @param filters the tables of the query - * @param count the number of table items - * @param condition the condition in the WHERE clause - */ - public Plan(TableFilter[] filters, int count, Expression condition) { - this.filters = new TableFilter[count]; - System.arraycopy(filters, 0, this.filters, 0, count); - ArrayList allCond = New.arrayList(); - ArrayList all = New.arrayList(); - if (condition != null) { - allCond.add(condition); - } - for (int i = 0; i < count; i++) { - TableFilter f = filters[i]; - do { - all.add(f); - if (f.getJoinCondition() != null) { - allCond.add(f.getJoinCondition()); - } - f = f.getJoin(); - } while(f != null); - } - allConditions = new Expression[allCond.size()]; - allCond.toArray(allConditions); - allFilters = new TableFilter[all.size()]; - all.toArray(allFilters); - } - - /** - * Get the plan item for the given table. - * - * @param filter the table - * @return the plan item - */ - public PlanItem getItem(TableFilter filter) { - return planItems.get(filter); - } - - /** - * The the list of tables. - * - * @return the list of tables - */ - public TableFilter[] getFilters() { - return filters; - } - - /** - * Remove all index conditions that can not be used. - */ - public void removeUnusableIndexConditions() { - for (int i = 0; i < allFilters.length; i++) { - TableFilter f = allFilters[i]; - setEvaluatable(f, true); - if (i < allFilters.length - 1) { - // the last table doesn't need the optimization, - // otherwise the expression is calculated twice unnecessarily - // (not that bad but not optimal) - f.optimizeFullCondition(false); - } - f.removeUnusableIndexConditions(); - } - for (TableFilter f : allFilters) { - setEvaluatable(f, false); - } - } - - /** - * Calculate the cost of this query plan. - * - * @param session the session - * @return the cost - */ - public double calculateCost(Session session) { - double cost = 1; - boolean invalidPlan = false; - int level = 1; - for (TableFilter tableFilter : allFilters) { - PlanItem item = tableFilter.getBestPlanItem(session, level++); - planItems.put(tableFilter, item); - cost += cost * item.cost; - setEvaluatable(tableFilter, true); - Expression on = tableFilter.getJoinCondition(); - if (on != null) { - if (!on.isEverything(ExpressionVisitor.EVALUATABLE)) { - invalidPlan = true; - break; - } - } - } - if (invalidPlan) { - cost = Double.POSITIVE_INFINITY; - } - for (TableFilter f : allFilters) { - setEvaluatable(f, false); - } - return cost; - } - - private void setEvaluatable(TableFilter filter, boolean b) { - for (Expression e : allConditions) { - e.setEvaluatable(filter, b); - } - } -} diff --git a/tools/h2/src/main/org/h2/table/PlanItem.java b/tools/h2/src/main/org/h2/table/PlanItem.java deleted file mode 100755 index 43dd3c1..0000000 --- a/tools/h2/src/main/org/h2/table/PlanItem.java +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.table; - -import org.h2.index.Index; - -/** - * The plan item describes the index to be used, and the estimated cost when - * using it. - */ -public class PlanItem { - - /** - * The cost. - */ - double cost; - - private Index index; - private PlanItem joinPlan; - - void setIndex(Index index) { - this.index = index; - } - - public Index getIndex() { - return index; - } - - PlanItem getJoinPlan() { - return joinPlan; - } - - void setJoinPlan(PlanItem joinPlan) { - this.joinPlan = joinPlan; - } - -} diff --git a/tools/h2/src/main/org/h2/table/RangeTable.java b/tools/h2/src/main/org/h2/table/RangeTable.java deleted file mode 100755 index cc4530b..0000000 --- a/tools/h2/src/main/org/h2/table/RangeTable.java +++ /dev/null @@ -1,175 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.table; - -import java.util.ArrayList; -import org.h2.engine.Session; -import org.h2.expression.Expression; -import org.h2.index.Index; -import org.h2.index.IndexType; -import org.h2.index.RangeIndex; -import org.h2.message.DbException; -import org.h2.result.Row; -import org.h2.schema.Schema; -import org.h2.value.Value; - -/** - * The table SYSTEM_RANGE is a virtual table that generates incrementing numbers - * with a given start end end point. - */ -public class RangeTable extends Table { - - /** - * The name of the range table. - */ - public static final String NAME = "SYSTEM_RANGE"; - - private Expression min, max; - private boolean optimized; - - /** - * Create a new range with the given start and end expressions. - * - * @param schema the schema (always the main schema) - * @param min the start expression - * @param max the end expression - */ - public RangeTable(Schema schema, Expression min, Expression max) { - super(schema, 0, NAME, true, true); - Column[] cols = { new Column("X", Value.LONG) }; - this.min = min; - this.max = max; - setColumns(cols); - } - - public String getDropSQL() { - return null; - } - - public String getCreateSQL() { - return null; - } - - public String getSQL() { - return NAME + "(" + min.getSQL() + ", " + max.getSQL() + ")"; - } - - public void lock(Session session, boolean exclusive, boolean force) { - // nothing to do - } - - public void close(Session session) { - // nothing to do - } - - public void unlock(Session s) { - // nothing to do - } - - public boolean isLockedExclusively() { - return false; - } - - public Index addIndex(Session session, String indexName, int indexId, IndexColumn[] cols, IndexType indexType, boolean create, String indexComment) { - throw DbException.getUnsupportedException("SYSTEM_RANGE"); - } - - public void removeRow(Session session, Row row) { - throw DbException.getUnsupportedException("SYSTEM_RANGE"); - } - - public void addRow(Session session, Row row) { - throw DbException.getUnsupportedException("SYSTEM_RANGE"); - } - - public void checkSupportAlter() { - throw DbException.getUnsupportedException("SYSTEM_RANGE"); - } - - public void checkRename() { - throw DbException.getUnsupportedException("SYSTEM_RANGE"); - } - - public boolean canGetRowCount() { - return true; - } - - public boolean canDrop() { - return false; - } - - public long getRowCount(Session session) { - return Math.max(0, getMax(session) - getMin(session) + 1); - } - - public String getTableType() { - throw DbException.throwInternalError(); - } - - public Index getScanIndex(Session session) { - return new RangeIndex(this, IndexColumn.wrap(columns)); - } - - /** - * Calculate and get the start value of this range. - * - * @param session the session - * @return the start value - */ - public long getMin(Session session) { - optimize(session); - return min.getValue(session).getLong(); - } - - /** - * Calculate and get the end value of this range. - * - * @param session the session - * @return the end value - */ - public long getMax(Session session) { - optimize(session); - return max.getValue(session).getLong(); - } - - private void optimize(Session s) { - if (!optimized) { - min = min.optimize(s); - max = max.optimize(s); - optimized = true; - } - } - - public ArrayList getIndexes() { - return null; - } - - public void truncate(Session session) { - throw DbException.getUnsupportedException("SYSTEM_RANGE"); - } - - public long getMaxDataModificationId() { - return 0; - } - - public Index getUniqueIndex() { - return null; - } - - public long getRowCountApproximation() { - return 100; - } - - public boolean isDeterministic() { - return true; - } - - public boolean canReference() { - return false; - } - -} diff --git a/tools/h2/src/main/org/h2/table/RegularTable.java b/tools/h2/src/main/org/h2/table/RegularTable.java deleted file mode 100755 index a0399f9..0000000 --- a/tools/h2/src/main/org/h2/table/RegularTable.java +++ /dev/null @@ -1,690 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.table; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.Comparator; -import java.util.HashSet; -import java.util.Set; -import org.h2.api.DatabaseEventListener; -import org.h2.command.ddl.Analyze; -import org.h2.command.ddl.CreateTableData; -import org.h2.constant.ErrorCode; -import org.h2.constant.SysProperties; -import org.h2.constraint.Constraint; -import org.h2.constraint.ConstraintReferential; -import org.h2.engine.Constants; -import org.h2.engine.DbObject; -import org.h2.engine.Session; -import org.h2.index.Cursor; -import org.h2.index.HashIndex; -import org.h2.index.Index; -import org.h2.index.IndexType; -import org.h2.index.MultiVersionIndex; -import org.h2.index.NonUniqueHashIndex; -import org.h2.index.PageBtreeIndex; -import org.h2.index.PageDataIndex; -import org.h2.index.PageDelegateIndex; -import org.h2.index.ScanIndex; -import org.h2.index.TreeIndex; -import org.h2.message.DbException; -import org.h2.message.Trace; -import org.h2.result.Row; -import org.h2.result.SortOrder; -import org.h2.schema.SchemaObject; -import org.h2.util.MathUtils; -import org.h2.util.New; -import org.h2.value.CompareMode; -import org.h2.value.DataType; -import org.h2.value.Value; - -/** - * Most tables are an instance of this class. For this table, the data is stored - * in the database. The actual data is not kept here, instead it is kept in the - * indexes. There is at least one index, the scan index. - */ -public class RegularTable extends TableBase { - private Index scanIndex; - private long rowCount; - private volatile Session lockExclusive; - private HashSet lockShared = New.hashSet(); - private Trace traceLock; - private final ArrayList indexes = New.arrayList(); - private long lastModificationId; - private boolean containsLargeObject; - private PageDataIndex mainIndex; - private int changesSinceAnalyze; - private int nextAnalyze = SysProperties.ANALYZE_AUTO; - - /** - * True if one thread ever was waiting to lock this table. This is to avoid - * calling notifyAll if no session was ever waiting to lock this table. If - * set, the flag stays. In theory, it could be reset, however not sure when. - */ - private boolean waitForLock; - - public RegularTable(CreateTableData data) { - super(data); - this.isHidden = data.isHidden; - if (data.persistData && database.isPersistent()) { - mainIndex = new PageDataIndex(this, data.id, IndexColumn.wrap(getColumns()), IndexType.createScan(data.persistData), data.create, data.session); - scanIndex = mainIndex; - } else { - scanIndex = new ScanIndex(this, data.id, IndexColumn.wrap(getColumns()), IndexType.createScan(data.persistData)); - } - indexes.add(scanIndex); - for (Column col : getColumns()) { - if (DataType.isLargeObject(col.getType())) { - containsLargeObject = true; - memoryPerRow = Row.MEMORY_CALCULATE; - } - } - traceLock = database.getTrace(Trace.LOCK); - } - - public void close(Session session) { - for (Index index : indexes) { - index.close(session); - } - } - - /** - * Read the given row. - * - * @param session the session - * @param key unique key - * @return the row - */ - public Row getRow(Session session, long key) { - return scanIndex.getRow(session, key); - } - - public void addRow(Session session, Row row) { - int i = 0; - lastModificationId = database.getNextModificationDataId(); - if (database.isMultiVersion()) { - row.setSessionId(session.getId()); - } - try { - for (; i < indexes.size(); i++) { - Index index = indexes.get(i); - index.add(session, row); - checkRowCount(session, index, 1); - } - rowCount++; - } catch (Throwable e) { - try { - while (--i >= 0) { - Index index = indexes.get(i); - index.remove(session, row); - checkRowCount(session, index, 0); - } - } catch (DbException e2) { - // this could happen, for example on failure in the storage - // but if that is not the case it means there is something wrong - // with the database - trace.error("Could not undo operation", e); - throw e2; - } - throw DbException.convert(e); - } - analyzeIfRequired(session); - } - - private void checkRowCount(Session session, Index index, int offset) { - if (SysProperties.CHECK && !database.isMultiVersion()) { - if (!(index instanceof PageDelegateIndex)) { - long rc = index.getRowCount(session); - if (rc != rowCount + offset) { - DbException.throwInternalError("rowCount expected " + (rowCount + offset) + " got " + rc + " " + getName() + "." + index.getName()); - } - } - } - } - - public Index getScanIndex(Session session) { - return indexes.get(0); - } - - public Index getUniqueIndex() { - for (Index idx : indexes) { - if (idx.getIndexType().isUnique()) { - return idx; - } - } - return null; - } - - public ArrayList getIndexes() { - return indexes; - } - - public Index addIndex(Session session, String indexName, int indexId, IndexColumn[] cols, IndexType indexType, - boolean create, String indexComment) { - if (indexType.isPrimaryKey()) { - for (IndexColumn c : cols) { - Column column = c.column; - if (column.isNullable()) { - throw DbException.get(ErrorCode.COLUMN_MUST_NOT_BE_NULLABLE_1, column.getName()); - } - column.setPrimaryKey(true); - } - } - Index index; - if (isPersistIndexes() && indexType.isPersistent()) { - int mainIndexColumn; - if (database.isStarting() && database.getPageStore().getRootPageId(indexId) != 0) { - mainIndexColumn = -1; - } else if (!database.isStarting() && mainIndex.getRowCount(session) != 0) { - mainIndexColumn = -1; - } else { - mainIndexColumn = getMainIndexColumn(indexType, cols); - } - if (mainIndexColumn != -1) { - mainIndex.setMainIndexColumn(mainIndexColumn); - index = new PageDelegateIndex(this, indexId, indexName, indexType, mainIndex, create, session); - } else { - index = new PageBtreeIndex(this, indexId, indexName, cols, indexType, create, session); - } - } else { - if (indexType.isHash() && cols.length <= 1) { - if (indexType.isUnique()) { - index = new HashIndex(this, indexId, indexName, cols, indexType); - } else { - index = new NonUniqueHashIndex(this, indexId, indexName, cols, indexType); - } - } else { - index = new TreeIndex(this, indexId, indexName, cols, indexType); - } - } - if (database.isMultiVersion()) { - index = new MultiVersionIndex(index, this); - } - if (index.needRebuild() && rowCount > 0) { - try { - Index scan = getScanIndex(session); - long remaining = scan.getRowCount(session); - long total = remaining; - Cursor cursor = scan.find(session, null, null); - long i = 0; - int bufferSize = Constants.DEFAULT_MAX_MEMORY_ROWS; - ArrayList buffer = New.arrayList(bufferSize); - String n = getName() + ":" + index.getName(); - int t = MathUtils.convertLongToInt(total); - while (cursor.next()) { - database.setProgress(DatabaseEventListener.STATE_CREATE_INDEX, n, - MathUtils.convertLongToInt(i++), t); - Row row = cursor.get(); - buffer.add(row); - if (buffer.size() >= bufferSize) { - addRowsToIndex(session, buffer, index); - } - remaining--; - } - addRowsToIndex(session, buffer, index); - if (SysProperties.CHECK && remaining != 0) { - DbException.throwInternalError("rowcount remaining=" + remaining + " " + getName()); - } - } catch (DbException e) { - getSchema().freeUniqueName(indexName); - try { - index.remove(session); - } catch (DbException e2) { - // this could happen, for example on failure in the storage - // but if that is not the case it means - // there is something wrong with the database - trace.error("Could not remove index", e); - throw e2; - } - throw e; - } - } - boolean temporary = isTemporary(); - index.setTemporary(temporary); - if (index.getCreateSQL() != null) { - index.setComment(indexComment); - if (temporary && !isGlobalTemporary()) { - session.addLocalTempTableIndex(index); - } else { - database.addSchemaObject(session, index); - } - } - indexes.add(index); - setModified(); - return index; - } - - private int getMainIndexColumn(IndexType indexType, IndexColumn[] cols) { - if (mainIndex.getMainIndexColumn() != -1) { - return -1; - } - if (!indexType.isPrimaryKey() || cols.length != 1) { - return -1; - } - IndexColumn first = cols[0]; - if (first.sortType != SortOrder.ASCENDING) { - return -1; - } - switch(first.column.getType()) { - case Value.BYTE: - case Value.SHORT: - case Value.INT: - case Value.LONG: - break; - default: - return -1; - } - return first.column.getColumnId(); - } - - public boolean canGetRowCount() { - return true; - } - - private void addRowsToIndex(Session session, ArrayList list, Index index) { - final Index idx = index; - Collections.sort(list, new Comparator() { - public int compare(Row r1, Row r2) { - return idx.compareRows(r1, r2); - } - }); - for (Row row : list) { - index.add(session, row); - } - list.clear(); - } - - public boolean canDrop() { - return true; - } - - public long getRowCount(Session session) { - if (database.isMultiVersion()) { - return getScanIndex(session).getRowCount(session); - } - return rowCount; - } - - public void removeRow(Session session, Row row) { - if (database.isMultiVersion()) { - if (row.isDeleted()) { - throw DbException.get(ErrorCode.CONCURRENT_UPDATE_1, getName()); - } - int old = row.getSessionId(); - int newId = session.getId(); - if (old == 0) { - row.setSessionId(newId); - } else if (old != newId) { - throw DbException.get(ErrorCode.CONCURRENT_UPDATE_1, getName()); - } - } - lastModificationId = database.getNextModificationDataId(); - int i = indexes.size() - 1; - try { - for (; i >= 0; i--) { - Index index = indexes.get(i); - index.remove(session, row); - checkRowCount(session, index, -1); - } - rowCount--; - } catch (Throwable e) { - try { - while (++i < indexes.size()) { - Index index = indexes.get(i); - index.add(session, row); - checkRowCount(session, index, 0); - } - } catch (DbException e2) { - // this could happen, for example on failure in the storage - // but if that is not the case it means there is something wrong - // with the database - trace.error("Could not undo operation", e); - throw e2; - } - throw DbException.convert(e); - } - analyzeIfRequired(session); - } - - public void truncate(Session session) { - lastModificationId = database.getNextModificationDataId(); - for (int i = indexes.size() - 1; i >= 0; i--) { - Index index = indexes.get(i); - index.truncate(session); - } - rowCount = 0; - changesSinceAnalyze = 0; - } - - private void analyzeIfRequired(Session session) { - if (nextAnalyze == 0 || nextAnalyze > changesSinceAnalyze++) { - return; - } - changesSinceAnalyze = 0; - int n = 2 * nextAnalyze; - if (n > 0) { - nextAnalyze = n; - } - int rows = SysProperties.ANALYZE_SAMPLE; - Analyze.analyzeTable(session, this, rows, false); - } - - public boolean isLockedExclusivelyBy(Session session) { - return lockExclusive == session; - } - - public void lock(Session session, boolean exclusive, boolean force) { - int lockMode = database.getLockMode(); - if (lockMode == Constants.LOCK_MODE_OFF) { - return; - } - if (!force && database.isMultiVersion()) { - // MVCC: update, delete, and insert use a shared lock. - // Select doesn't lock except when using FOR UPDATE and - // the system property h2.selectForUpdateMvcc - // is not enabled - if (exclusive) { - exclusive = false; - } else { - if (lockExclusive == null) { - return; - } - } - } - if (lockExclusive == session) { - return; - } - synchronized (database) { - try { - doLock(session, lockMode, exclusive); - } finally { - session.setWaitForLock(null); - } - } - } - - private void doLock(Session session, int lockMode, boolean exclusive) { - traceLock(session, exclusive, "requesting for"); - long max = System.currentTimeMillis() + session.getLockTimeout(); - boolean checkDeadlock = false; - while (true) { - if (lockExclusive == session) { - return; - } - if (exclusive) { - if (lockExclusive == null) { - if (lockShared.isEmpty()) { - traceLock(session, exclusive, "added for"); - session.addLock(this); - lockExclusive = session; - return; - } else if (lockShared.size() == 1 && lockShared.contains(session)) { - traceLock(session, exclusive, "add (upgraded) for "); - lockExclusive = session; - return; - } - } - } else { - if (lockExclusive == null) { - if (lockMode == Constants.LOCK_MODE_READ_COMMITTED) { - if (!database.isMultiThreaded() && !database.isMultiVersion()) { - // READ_COMMITTED: a read lock is acquired, - // but released immediately after the operation - // is complete. - // When allowing only one thread, no lock is - // required. - // Row level locks work like read committed. - return; - } - } - if (!lockShared.contains(session)) { - traceLock(session, exclusive, "ok"); - session.addLock(this); - lockShared.add(session); - } - return; - } - } - session.setWaitForLock(this); - if (checkDeadlock) { - ArrayList sessions = checkDeadlock(session, null, null); - if (sessions != null) { - throw DbException.get(ErrorCode.DEADLOCK_1, getDeadlockDetails(sessions)); - } - } else { - // check for deadlocks from now on - checkDeadlock = true; - } - long now = System.currentTimeMillis(); - if (now >= max) { - traceLock(session, exclusive, "timeout after " + session.getLockTimeout()); - throw DbException.get(ErrorCode.LOCK_TIMEOUT_1, getName()); - } - try { - traceLock(session, exclusive, "waiting for"); - if (database.getLockMode() == Constants.LOCK_MODE_TABLE_GC) { - for (int i = 0; i < 20; i++) { - long free = Runtime.getRuntime().freeMemory(); - System.gc(); - long free2 = Runtime.getRuntime().freeMemory(); - if (free == free2) { - break; - } - } - } - // don't wait too long so that deadlocks are detected early - long sleep = Math.min(Constants.DEADLOCK_CHECK, max - now); - if (sleep == 0) { - sleep = 1; - } - waitForLock = true; - database.wait(sleep); - } catch (InterruptedException e) { - // ignore - } - } - } - - private String getDeadlockDetails(ArrayList sessions) { - StringBuilder buff = new StringBuilder(); - for (Session s : sessions) { - Table lock = s.getWaitForLock(); - buff.append("\nSession "). - append(s.toString()). - append(" is waiting to lock "). - append(lock.toString()). - append(" while locking "); - int i = 0; - for (Table t : s.getLocks()) { - if (i++ > 0) { - buff.append(", "); - } - buff.append(t.toString()); - if (t instanceof RegularTable) { - if (((RegularTable) t).lockExclusive == s) { - buff.append(" (exclusive)"); - } else { - buff.append(" (shared)"); - } - } - } - buff.append('.'); - } - return buff.toString(); - } - - public ArrayList checkDeadlock(Session session, Session clash, Set visited) { - // only one deadlock check at any given time - synchronized (RegularTable.class) { - if (clash == null) { - // verification is started - clash = session; - visited = New.hashSet(); - } else if (clash == session) { - // we found a circle where this session is involved - return New.arrayList(); - } else if (visited.contains(session)) { - // we have already checked this session. - // there is a circle, but the sessions in the circle need to - // find it out themselves - return null; - } - visited.add(session); - ArrayList error = null; - for (Session s : lockShared) { - if (s == session) { - // it doesn't matter if we have locked the object already - continue; - } - Table t = s.getWaitForLock(); - if (t != null) { - error = t.checkDeadlock(s, clash, visited); - if (error != null) { - error.add(session); - break; - } - } - } - if (error == null && lockExclusive != null) { - Table t = lockExclusive.getWaitForLock(); - if (t != null) { - error = t.checkDeadlock(lockExclusive, clash, visited); - if (error != null) { - error.add(session); - } - } - } - return error; - } - } - - private void traceLock(Session session, boolean exclusive, String s) { - if (traceLock.isDebugEnabled()) { - traceLock.debug(session.getId() + " " + (exclusive ? "exclusive write lock" : "shared read lock") + " " + s + " " + getName()); - } - } - - public boolean isLockedExclusively() { - return lockExclusive != null; - } - - public void unlock(Session s) { - if (database != null) { - traceLock(s, lockExclusive == s, "unlock"); - if (lockExclusive == s) { - lockExclusive = null; - } - if (lockShared.size() > 0) { - lockShared.remove(s); - } - // TODO lock: maybe we need we fifo-queue to make sure nobody - // starves. check what other databases do - synchronized (database) { - if (database.getSessionCount() > 1 && waitForLock) { - database.notifyAll(); - } - } - } - } - - /** - * Create a row from the values. - * - * @param data the value list - * @return the row - */ - public Row createRow(Value[] data) { - return new Row(data, memoryPerRow); - } - - /** - * Set the row count of this table. - * - * @param count the row count - */ - public void setRowCount(long count) { - this.rowCount = count; - } - - public void removeChildrenAndResources(Session session) { - super.removeChildrenAndResources(session); - // go backwards because database.removeIndex will call table.removeIndex - while (indexes.size() > 1) { - Index index = indexes.get(1); - if (index.getName() != null) { - database.removeSchemaObject(session, index); - } - } - if (SysProperties.CHECK) { - for (SchemaObject obj : database.getAllSchemaObjects(DbObject.INDEX)) { - Index index = (Index) obj; - if (index.getTable() == this) { - DbException.throwInternalError("index not dropped: " + index.getName()); - } - } - } - scanIndex.remove(session); - database.removeMeta(session, getId()); - scanIndex = null; - lockExclusive = null; - lockShared = null; - invalidate(); - } - - public String toString() { - return getSQL(); - } - - public void checkRename() { - // ok - } - - public void checkSupportAlter() { - // ok - } - - public boolean canTruncate() { - ArrayList constraints = getConstraints(); - for (int i = 0; constraints != null && i < constraints.size(); i++) { - Constraint c = constraints.get(i); - if (!(c.getConstraintType().equals(Constraint.REFERENTIAL))) { - continue; - } - ConstraintReferential ref = (ConstraintReferential) c; - if (ref.getRefTable() == this) { - return false; - } - } - return true; - } - - public String getTableType() { - return Table.TABLE; - } - - public long getMaxDataModificationId() { - return lastModificationId; - } - - public boolean getContainsLargeObject() { - return containsLargeObject; - } - - public long getRowCountApproximation() { - return scanIndex.getRowCountApproximation(); - } - - public void setCompareMode(CompareMode compareMode) { - this.compareMode = compareMode; - } - - public boolean isDeterministic() { - return true; - } - -} diff --git a/tools/h2/src/main/org/h2/table/SingleColumnResolver.java b/tools/h2/src/main/org/h2/table/SingleColumnResolver.java deleted file mode 100755 index 8ab565a..0000000 --- a/tools/h2/src/main/org/h2/table/SingleColumnResolver.java +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.table; - -import org.h2.command.dml.Select; -import org.h2.expression.Expression; -import org.h2.expression.ExpressionColumn; -import org.h2.value.Value; - -/** - * The single column resolver is like a table with exactly one row. - * It is used to parse a simple one-column check constraint. - */ -public class SingleColumnResolver implements ColumnResolver { - - private final Column column; - private Value value; - - SingleColumnResolver(Column column) { - this.column = column; - } - - public String getTableAlias() { - return null; - } - - void setValue(Value value) { - this.value = value; - } - - public Value getValue(Column col) { - return value; - } - - public Column[] getColumns() { - return new Column[] { column }; - } - - public String getSchemaName() { - return null; - } - - public TableFilter getTableFilter() { - return null; - } - - public Select getSelect() { - return null; - } - - public Column[] getSystemColumns() { - return null; - } - - public Expression optimize(ExpressionColumn expressionColumn, Column col) { - return expressionColumn; - } - -} diff --git a/tools/h2/src/main/org/h2/table/Table.java b/tools/h2/src/main/org/h2/table/Table.java deleted file mode 100755 index 3b76f7e..0000000 --- a/tools/h2/src/main/org/h2/table/Table.java +++ /dev/null @@ -1,1004 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.table; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Set; -import org.h2.command.Prepared; -import org.h2.constant.ErrorCode; -import org.h2.constraint.Constraint; -import org.h2.engine.Constants; -import org.h2.engine.DbObject; -import org.h2.engine.Right; -import org.h2.engine.Session; -import org.h2.engine.UndoLogRecord; -import org.h2.expression.Expression; -import org.h2.expression.ExpressionVisitor; -import org.h2.index.Index; -import org.h2.index.IndexType; -import org.h2.message.DbException; -import org.h2.message.Trace; -import org.h2.result.Row; -import org.h2.result.RowList; -import org.h2.result.SearchRow; -import org.h2.result.SimpleRow; -import org.h2.result.SimpleRowValue; -import org.h2.schema.Schema; -import org.h2.schema.SchemaObjectBase; -import org.h2.schema.Sequence; -import org.h2.schema.TriggerObject; -import org.h2.util.New; -import org.h2.value.CompareMode; -import org.h2.value.DataType; -import org.h2.value.Value; -import org.h2.value.ValueNull; - -/** - * This is the base class for most tables. - * A table contains a list of columns and a list of rows. - */ -public abstract class Table extends SchemaObjectBase { - - /** - * The table type that means this table is a regular persistent table. - */ - public static final int TYPE_CACHED = 0; - - /** - * The table type that means this table is a regular persistent table. - */ - public static final int TYPE_MEMORY = 1; - - /** - * The table type name for linked tables. - */ - public static final String TABLE_LINK = "TABLE LINK"; - - /** - * The table type name for system tables. - */ - public static final String SYSTEM_TABLE = "SYSTEM TABLE"; - - /** - * The table type name for regular data tables. - */ - public static final String TABLE = "TABLE"; - - /** - * The table type name for views. - */ - public static final String VIEW = "VIEW"; - - /** - * The table type name for external table engines. - */ - public static final String EXTERNAL_TABLE_ENGINE = "EXTERNAL"; - - /** - * The columns of this table. - */ - protected Column[] columns; - - /** - * The amount of memory required for a row if all values would be very small. - */ - protected int memoryPerRow; - - /** - * The compare mode used for this table. - */ - protected CompareMode compareMode; - - /** - * Protected tables are not listed in the meta data and are excluded when - * using the SCRIPT command. - */ - protected boolean isHidden; - - private final HashMap columnMap = New.hashMap(); - private boolean persistIndexes; - private boolean persistData; - private ArrayList triggers; - private ArrayList constraints; - private ArrayList sequences; - private ArrayList views; - private boolean checkForeignKeyConstraints = true; - private boolean onCommitDrop, onCommitTruncate; - private Row nullRow; - - public Table(Schema schema, int id, String name, boolean persistIndexes, boolean persistData) { - initSchemaObjectBase(schema, id, name, Trace.TABLE); - this.persistIndexes = persistIndexes; - this.persistData = persistData; - compareMode = schema.getDatabase().getCompareMode(); - } - - public void rename(String newName) { - super.rename(newName); - for (int i = 0; constraints != null && i < constraints.size(); i++) { - Constraint constraint = constraints.get(i); - constraint.rebuild(); - } - } - - /** - * Lock the table for the given session. - * This method waits until the lock is granted. - * - * @param session the session - * @param exclusive true for write locks, false for read locks - * @param force lock even in the MVCC mode - * @throws SQLException if a lock timeout occurred - */ - public abstract void lock(Session session, boolean exclusive, boolean force); - - /** - * Close the table object and flush changes. - * - * @param session the session - */ - public abstract void close(Session session); - - /** - * Release the lock for this session. - * - * @param s the session - */ - public abstract void unlock(Session s); - - /** - * Create an index for this table - * - * @param session the session - * @param indexName the name of the index - * @param indexId the id - * @param cols the index columns - * @param indexType the index type - * @param create whether this is a new index - * @param indexComment the comment - * @return the index - */ - public abstract Index addIndex(Session session, String indexName, int indexId, IndexColumn[] cols, IndexType indexType, - boolean create, String indexComment); - - /** - * Remove a row from the table and all indexes. - * - * @param session the session - * @param row the row - */ - public abstract void removeRow(Session session, Row row); - - /** - * Remove all rows from the table and indexes. - * - * @param session the session - */ - public abstract void truncate(Session session); - - /** - * Add a row to the table and all indexes. - * - * @param session the session - * @param row the row - * @throws SQLException if a constraint was violated - */ - public abstract void addRow(Session session, Row row); - - /** - * Check if this table supports ALTER TABLE. - * - * @throws SQLException if it is not supported - */ - public abstract void checkSupportAlter(); - - /** - * Get the table type name - * - * @return the table type name - */ - public abstract String getTableType(); - - /** - * Get the scan index to iterate through all rows. - * - * @param session the session - * @return the index - */ - public abstract Index getScanIndex(Session session); - - /** - * Get any unique index for this table if one exists. - * - * @return a unique index - */ - public abstract Index getUniqueIndex(); - - /** - * Get all indexes for this table. - * - * @return the list of indexes - */ - public abstract ArrayList getIndexes(); - - /** - * Check if this table is locked exclusively. - * - * @return true if it is. - */ - public abstract boolean isLockedExclusively(); - - /** - * Get the last data modification id. - * - * @return the modification id - */ - public abstract long getMaxDataModificationId(); - - /** - * Check if the table is deterministic. - * - * @return true if it is - */ - public abstract boolean isDeterministic(); - - /** - * Check if the row count can be retrieved quickly. - * - * @return true if it can - */ - public abstract boolean canGetRowCount(); - - /** - * Check if this table can be referenced. - * - * @return true if it can - */ - public boolean canReference() { - return true; - } - - /** - * Check if this table can be dropped. - * - * @return true if it can - */ - public abstract boolean canDrop(); - - /** - * Get the row count for this table. - * - * @param session the session - * @return the row count - */ - public abstract long getRowCount(Session session); - - /** - * Get the approximated row count for this table. - * - * @return the approximated row count - */ - public abstract long getRowCountApproximation(); - - public String getCreateSQLForCopy(Table table, String quotedName) { - throw DbException.throwInternalError(); - } - - /** - * Add all objects that this table depends on to the hash set. - * - * @param dependencies the current set of dependencies - */ - public void addDependencies(HashSet dependencies) { - if (sequences != null) { - for (Sequence s : sequences) { - dependencies.add(s); - } - } - ExpressionVisitor visitor = ExpressionVisitor.get(ExpressionVisitor.GET_DEPENDENCIES); - visitor.setDependencies(dependencies); - for (Column col : columns) { - col.isEverything(visitor); - } - } - - public ArrayList getChildren() { - ArrayList children = New.arrayList(); - ArrayList indexes = getIndexes(); - if (indexes != null) { - children.addAll(indexes); - } - if (constraints != null) { - children.addAll(constraints); - } - if (triggers != null) { - children.addAll(triggers); - } - if (sequences != null) { - children.addAll(sequences); - } - if (views != null) { - children.addAll(views); - } - ArrayList rights = database.getAllRights(); - for (Right right : rights) { - if (right.getGrantedTable() == this) { - children.add(right); - } - } - return children; - } - - protected void setColumns(Column[] columns) { - this.columns = columns; - if (columnMap.size() > 0) { - columnMap.clear(); - } - // a row needs memory even if there are no columns - int memory = 1; - for (int i = 0; i < columns.length; i++) { - Column col = columns[i]; - int dataType = col.getType(); - if (dataType == Value.UNKNOWN) { - throw DbException.get(ErrorCode.UNKNOWN_DATA_TYPE_1, col.getSQL()); - } - memory += DataType.getDataType(dataType).memory; - col.setTable(this, i); - String columnName = col.getName(); - if (columnMap.get(columnName) != null) { - throw DbException.get(ErrorCode.DUPLICATE_COLUMN_NAME_1, columnName); - } - columnMap.put(columnName, col); - } - memoryPerRow = memory; - } - - /** - * Rename a column of this table. - * - * @param column the column to rename - * @param newName the new column name - */ - public void renameColumn(Column column, String newName) { - for (Column c : columns) { - if (c == column) { - continue; - } - if (c.getName().equals(newName)) { - throw DbException.get(ErrorCode.DUPLICATE_COLUMN_NAME_1, newName); - } - } - columnMap.remove(column.getName()); - column.rename(newName); - columnMap.put(newName, column); - } - - /** - * Check if the table is exclusively locked by this session. - * - * @param session the session - * @return true if it is - */ - public boolean isLockedExclusivelyBy(Session session) { - return false; - } - - /** - * Update a list of rows in this table. - * - * @param prepared the prepared statement - * @param session the session - * @param rows a list of row pairs of the form old row, new row, old row, - * new row,... - */ - public void updateRows(Prepared prepared, Session session, RowList rows) { - // remove the old rows - int rowScanCount = 0; - for (rows.reset(); rows.hasNext();) { - if ((++rowScanCount & 127) == 0) { - prepared.checkCanceled(); - } - Row o = rows.next(); - rows.next(); - removeRow(session, o); - session.log(this, UndoLogRecord.DELETE, o); - } - // add the new rows - for (rows.reset(); rows.hasNext();) { - if ((++rowScanCount & 127) == 0) { - prepared.checkCanceled(); - } - rows.next(); - Row n = rows.next(); - addRow(session, n); - session.log(this, UndoLogRecord.INSERT, n); - } - } - - public void removeChildrenAndResources(Session session) { - while (views != null && views.size() > 0) { - TableView view = views.get(0); - views.remove(0); - database.removeSchemaObject(session, view); - } - while (triggers != null && triggers.size() > 0) { - TriggerObject trigger = triggers.get(0); - triggers.remove(0); - database.removeSchemaObject(session, trigger); - } - while (constraints != null && constraints.size() > 0) { - Constraint constraint = constraints.get(0); - constraints.remove(0); - database.removeSchemaObject(session, constraint); - } - for (Right right : database.getAllRights()) { - if (right.getGrantedTable() == this) { - database.removeDatabaseObject(session, right); - } - } - database.removeMeta(session, getId()); - // must delete sequences later (in case there is a power failure - // before removing the table object) - while (sequences != null && sequences.size() > 0) { - Sequence sequence = sequences.get(0); - sequences.remove(0); - if (!isTemporary()) { - // only remove if no other table depends on this sequence - // this is possible when calling ALTER TABLE ALTER COLUMN - if (database.getDependentTable(sequence, this) == null) { - database.removeSchemaObject(session, sequence); - } - } - } - } - - /** - * Check that this column is not referenced by a referential constraint or - * multi-column index. - * - * @param col the column - * @throws SQLException if the column is referenced - */ - public void checkColumnIsNotReferenced(Column col) { - for (int i = 0; constraints != null && i < constraints.size(); i++) { - Constraint constraint = constraints.get(i); - if (constraint.containsColumn(col)) { - throw DbException.get(ErrorCode.COLUMN_MAY_BE_REFERENCED_1, constraint.getSQL()); - } - } - ArrayList indexes = getIndexes(); - for (int i = 0; indexes != null && i < indexes.size(); i++) { - Index index = indexes.get(i); - if (index.getColumns().length == 1) { - continue; - } - if (index.getCreateSQL() == null) { - continue; - } - if (index.getColumnIndex(col) >= 0) { - throw DbException.get(ErrorCode.COLUMN_MAY_BE_REFERENCED_1, index.getSQL()); - } - } - } - - public Row getTemplateRow() { - return new Row(new Value[columns.length], memoryPerRow); - } - - /** - * Get a new simple row object. - * - * @param singleColumn if only one value need to be stored - * @return the simple row object - */ - public SearchRow getTemplateSimpleRow(boolean singleColumn) { - if (singleColumn) { - return new SimpleRowValue(columns.length); - } - return new SimpleRow(new Value[columns.length]); - } - - Row getNullRow() { - synchronized (this) { - if (nullRow == null) { - nullRow = new Row(new Value[columns.length], 1); - for (int i = 0; i < columns.length; i++) { - nullRow.setValue(i, ValueNull.INSTANCE); - } - } - return nullRow; - } - } - - public Column[] getColumns() { - return columns; - } - - public int getType() { - return DbObject.TABLE_OR_VIEW; - } - - /** - * Get the column at the given index. - * - * @param index the column index (0, 1,...) - * @return the column - */ - public Column getColumn(int index) { - return columns[index]; - } - - /** - * Get the column with the given name. - * - * @param columnName the column name - * @return the column - * @throws SQLException if the column was not found - */ - public Column getColumn(String columnName) { - Column column = columnMap.get(columnName); - if (column == null) { - throw DbException.get(ErrorCode.COLUMN_NOT_FOUND_1, columnName); - } - return column; - } - - /** - * Get the best plan for the given search mask. - * - * @param session the session - * @param masks null means 'always false' - * @return the plan item - */ - public PlanItem getBestPlanItem(Session session, int[] masks) { - PlanItem item = new PlanItem(); - item.setIndex(getScanIndex(session)); - item.cost = item.getIndex().getCost(session, null); - ArrayList indexes = getIndexes(); - for (int i = 1; indexes != null && masks != null && i < indexes.size(); i++) { - Index index = indexes.get(i); - double cost = index.getCost(session, masks); - if (cost < item.cost) { - item.cost = cost; - item.setIndex(index); - } - } - return item; - } - - /** - * Get the primary key index if there is one, or null if there is none. - * - * @return the primary key index or null - */ - public Index findPrimaryKey() { - ArrayList indexes = getIndexes(); - for (int i = 0; indexes != null && i < indexes.size(); i++) { - Index idx = indexes.get(i); - if (idx.getIndexType().isPrimaryKey()) { - return idx; - } - } - return null; - } - - public Index getPrimaryKey() { - Index index = findPrimaryKey(); - if (index != null) { - return index; - } - throw DbException.get(ErrorCode.INDEX_NOT_FOUND_1, Constants.PREFIX_PRIMARY_KEY); - } - - /** - * Validate all values in this row, convert the values if required, and - * update the sequence values if required. This call will also set the - * default values if required and set the computed column if there are any. - * - * @param session the session - * @param row the row - */ - public void validateConvertUpdateSequence(Session session, Row row) { - for (int i = 0; i < columns.length; i++) { - Value value = row.getValue(i); - Column column = columns[i]; - Value v2; - if (column.getComputed()) { - // force updating the value - value = null; - v2 = column.computeValue(session, row); - } - v2 = column.validateConvertUpdateSequence(session, value); - if (v2 != value) { - row.setValue(i, v2); - } - } - } - - private void remove(ArrayList< ? extends DbObject> list, DbObject obj) { - if (list != null) { - int i = list.indexOf(obj); - if (i >= 0) { - list.remove(i); - } - } - } - - /** - * Remove the given index from the list. - * - * @param index the index to remove - */ - public void removeIndex(Index index) { - ArrayList indexes = getIndexes(); - if (indexes != null) { - remove(indexes, index); - if (index.getIndexType().isPrimaryKey()) { - for (Column col : index.getColumns()) { - col.setPrimaryKey(false); - } - } - } - } - - /** - * Remove the given view from the list. - * - * @param view the view to remove - */ - void removeView(TableView view) { - remove(views, view); - } - - /** - * Remove the given constraint from the list. - * - * @param constraint the constraint to remove - */ - public void removeConstraint(Constraint constraint) { - remove(constraints, constraint); - } - - /** - * Remove a sequence from the table. Sequences are used as identity columns. - * - * @param session the session - * @param sequence the sequence to remove - */ - public void removeSequence(Session session, Sequence sequence) { - remove(sequences, sequence); - } - - /** - * Remove the given trigger from the list. - * - * @param trigger the trigger to remove - */ - public void removeTrigger(TriggerObject trigger) { - remove(triggers, trigger); - } - - /** - * Add a view to this table. - * - * @param view the view to add - */ - public void addView(TableView view) { - views = add(views, view); - } - - /** - * Add a constraint to the table. - * - * @param constraint the constraint to add - */ - public void addConstraint(Constraint constraint) { - if (constraints == null || constraints.indexOf(constraint) < 0) { - constraints = add(constraints, constraint); - } - } - - public ArrayList getConstraints() { - return constraints; - } - - /** - * Add a sequence to this table. - * - * @param sequence the sequence to add - */ - public void addSequence(Sequence sequence) { - sequences = add(sequences, sequence); - } - - /** - * Add a trigger to this table. - * - * @param trigger the trigger to add - */ - public void addTrigger(TriggerObject trigger) { - triggers = add(triggers, trigger); - } - - private ArrayList add(ArrayList list, T obj) { - if (list == null) { - list = New.arrayList(); - } - // self constraints are two entries in the list - list.add(obj); - return list; - } - - /** - * Fire the triggers for this table. - * - * @param session the session - * @param type the trigger type - * @param beforeAction whether 'before' triggers should be called - */ - public void fire(Session session, int type, boolean beforeAction) { - if (triggers != null) { - for (TriggerObject trigger : triggers) { - trigger.fire(session, type, beforeAction); - } - } - } - - /** - * Check whether this table has a select trigger. - * - * @return true if it has - */ - public boolean hasSelectTrigger() { - if (triggers != null) { - for (TriggerObject trigger : triggers) { - if (trigger.isSelectTrigger()) { - return true; - } - } - } - return false; - } - - /** - * Check if row based triggers or constraints are defined. - * In this case the fire after and before row methods need to be called. - * - * @return if there are any triggers or rows defined - */ - public boolean fireRow() { - return (constraints != null && constraints.size() > 0) || (triggers != null && triggers.size() > 0); - } - - /** - * Fire all triggers that need to be called before a row is updated. - * - * @param session the session - * @param oldRow the old data or null for an insert - * @param newRow the new data or null for a delete - * @return true if no further action is required (for 'instead of' triggers) - */ - public boolean fireBeforeRow(Session session, Row oldRow, Row newRow) { - boolean done = fireRow(session, oldRow, newRow, true, false); - fireConstraints(session, oldRow, newRow, true); - return done; - } - - private void fireConstraints(Session session, Row oldRow, Row newRow, boolean before) { - if (constraints != null) { - for (Constraint constraint : constraints) { - if (constraint.isBefore() == before) { - constraint.checkRow(session, this, oldRow, newRow); - } - } - } - } - - /** - * Fire all triggers that need to be called after a row is updated. - * - * @param session the session - * @param oldRow the old data or null for an insert - * @param newRow the new data or null for a delete - * @param rollback when the operation occurred within a rollback - */ - public void fireAfterRow(Session session, Row oldRow, Row newRow, boolean rollback) { - fireRow(session, oldRow, newRow, false, rollback); - if (!rollback) { - fireConstraints(session, oldRow, newRow, false); - } - } - - private boolean fireRow(Session session, Row oldRow, Row newRow, boolean beforeAction, boolean rollback) { - if (triggers != null) { - for (TriggerObject trigger : triggers) { - boolean done = trigger.fireRow(session, oldRow, newRow, beforeAction, rollback); - if (done) { - return true; - } - } - } - return false; - } - - public boolean isGlobalTemporary() { - return false; - } - - /** - * Check if this table can be truncated. - * - * @return true if it can - */ - public boolean canTruncate() { - return false; - } - - /** - * Enable or disable foreign key constraint checking for this table. - * - * @param session the session - * @param enabled true if checking should be enabled - * @param checkExisting true if existing rows must be checked during this call - */ - public void setCheckForeignKeyConstraints(Session session, boolean enabled, boolean checkExisting) - { - if (enabled && checkExisting) { - for (int i = 0; constraints != null && i < constraints.size(); i++) { - Constraint c = constraints.get(i); - c.checkExistingData(session); - } - } - checkForeignKeyConstraints = enabled; - } - - public boolean getCheckForeignKeyConstraints() { - return checkForeignKeyConstraints; - } - - /** - * Get the index that has the given column as the first element. - * This method returns null if no matching index is found. - * - * @param column the column - * @param first if the min value should be returned - * @return the index or null - */ - public Index getIndexForColumn(Column column, boolean first) { - ArrayList indexes = getIndexes(); - for (int i = 1; indexes != null && i < indexes.size(); i++) { - Index index = indexes.get(i); - if (index.canGetFirstOrLast()) { - int idx = index.getColumnIndex(column); - if (idx == 0) { - return index; - } - } - } - return null; - } - - public boolean getOnCommitDrop() { - return onCommitDrop; - } - - public void setOnCommitDrop(boolean onCommitDrop) { - this.onCommitDrop = onCommitDrop; - } - - public boolean getOnCommitTruncate() { - return onCommitTruncate; - } - - public void setOnCommitTruncate(boolean onCommitTruncate) { - this.onCommitTruncate = onCommitTruncate; - } - - /** - * If the index is still required by a constraint, transfer the ownership to - * it. Otherwise, the index is removed. - * - * @param session the session - * @param index the index that is no longer required - */ - public void removeIndexOrTransferOwnership(Session session, Index index) { - boolean stillNeeded = false; - for (int i = 0; constraints != null && i < constraints.size(); i++) { - Constraint cons = constraints.get(i); - if (cons.usesIndex(index)) { - cons.setIndexOwner(index); - database.update(session, cons); - stillNeeded = true; - } - } - if (!stillNeeded) { - database.removeSchemaObject(session, index); - } - } - - /** - * Check if a deadlock occurred. This method is called recursively. There is - * a circle if the session to be tested has already being visited. If this - * session is part of the circle (if it is the clash session), the method - * must return an empty object array. Once a deadlock has been detected, the - * methods must add the session to the list. If this session is not part of - * the circle, or if no deadlock is detected, this method returns null. - * - * @param session the session to be tested for - * @param clash set with sessions already visited, and null when starting - * verification - * @param visited set with sessions already visited, and null when starting - * verification - * @return an object array with the sessions involved in the deadlock, or - * null - */ - public ArrayList checkDeadlock(Session session, Session clash, Set visited) { - return null; - } - - public boolean isPersistIndexes() { - return persistIndexes; - } - - public boolean isPersistData() { - return persistData; - } - - /** - * Compare two values with the current comparison mode. The values may be of - * different type. - * - * @param a the first value - * @param b the second value - * @return 0 if both values are equal, -1 if the first value is smaller, and - * 1 otherwise - */ - public int compareTypeSave(Value a, Value b) { - int dataType = Value.getHigherOrder(a.getType(), b.getType()); - a = a.convertTo(dataType); - b = b.convertTo(dataType); - return a.compareTypeSave(b, compareMode); - } - - public CompareMode getCompareMode() { - return compareMode; - } - - /** - * Tests if the table can be written. Usually, this depends on the - * database.checkWritingAllowed method, but some tables (eg. TableLink) - * overwrite this default behaviour. - */ - public void checkWritingAllowed() { - database.checkWritingAllowed(); - } - - /** - * Get or generate a default value for the given column. - * - * @param session the session - * @param column the column - * @return the value - */ - public Value getDefaultValue(Session session, Column column) { - Expression defaultExpr = column.getDefaultExpression(); - Value v; - if (defaultExpr == null) { - v = column.validateConvertUpdateSequence(session, null); - } else { - v = defaultExpr.getValue(session); - } - return column.convert(v); - } - - public boolean isHidden() { - return isHidden; - } - -} diff --git a/tools/h2/src/main/org/h2/table/TableBase.java b/tools/h2/src/main/org/h2/table/TableBase.java deleted file mode 100755 index 63dfa34..0000000 --- a/tools/h2/src/main/org/h2/table/TableBase.java +++ /dev/null @@ -1,88 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.table; - -import org.h2.command.ddl.CreateTableData; -import org.h2.util.StatementBuilder; -import org.h2.util.StringUtils; - -/** - * The base class of a regular table, or a user defined table. - * - * @author Thomas Mueller - * @author Sergi Vladykin - */ -public abstract class TableBase extends Table { - - /** - * The table engine used (null for regular tables). - */ - protected final String tableEngine; - - private final boolean globalTemporary; - - public TableBase(CreateTableData data) { - super(data.schema, data.id, data.tableName, data.persistIndexes, data.persistData); - this.tableEngine = data.tableEngine; - this.globalTemporary = data.globalTemporary; - setTemporary(data.temporary); - Column[] cols = new Column[data.columns.size()]; - data.columns.toArray(cols); - setColumns(cols); - } - - public String getDropSQL() { - return "DROP TABLE IF EXISTS " + getSQL(); - } - - public String getCreateSQL() { - StatementBuilder buff = new StatementBuilder("CREATE "); - if (isTemporary()) { - if (isGlobalTemporary()) { - buff.append("GLOBAL "); - } else { - buff.append("LOCAL "); - } - buff.append("TEMPORARY "); - } else if (isPersistIndexes()) { - buff.append("CACHED "); - } else { - buff.append("MEMORY "); - } - buff.append("TABLE "); - if (isHidden) { - buff.append("IF NOT EXISTS "); - } - buff.append(getSQL()); - if (comment != null) { - buff.append(" COMMENT ").append(StringUtils.quoteStringSQL(comment)); - } - buff.append("(\n "); - for (Column column : columns) { - buff.appendExceptFirst(",\n "); - buff.append(column.getCreateSQL()); - } - buff.append("\n)"); - if (tableEngine != null) { - buff.append("\nENGINE \""); - buff.append(tableEngine); - buff.append("\""); - } - if (!isPersistIndexes() && !isPersistData()) { - buff.append("\nNOT PERSISTENT"); - } - if (isHidden) { - buff.append("\nHIDDEN"); - } - return buff.toString(); - } - - public boolean isGlobalTemporary() { - return globalTemporary; - } - -} diff --git a/tools/h2/src/main/org/h2/table/TableFilter.java b/tools/h2/src/main/org/h2/table/TableFilter.java deleted file mode 100755 index 6a94a01..0000000 --- a/tools/h2/src/main/org/h2/table/TableFilter.java +++ /dev/null @@ -1,747 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.table; - -import java.util.ArrayList; -import org.h2.command.Parser; -import org.h2.command.dml.Select; -import org.h2.constant.SysProperties; -import org.h2.engine.Right; -import org.h2.engine.Session; -import org.h2.expression.Comparison; -import org.h2.expression.ConditionAndOr; -import org.h2.expression.Expression; -import org.h2.expression.ExpressionColumn; -import org.h2.index.Index; -import org.h2.index.IndexCondition; -import org.h2.index.IndexCursor; -import org.h2.message.DbException; -import org.h2.result.Row; -import org.h2.result.SearchRow; -import org.h2.util.New; -import org.h2.util.StatementBuilder; -import org.h2.util.StringUtils; -import org.h2.value.Value; - -/** - * A table filter represents a table that is used in a query. There is one such - * object whenever a table (or view) is used in a query. For example the - * following query has 2 table filters: SELECT * FROM TEST T1, TEST T2. - */ -public class TableFilter implements ColumnResolver { - private static final int BEFORE_FIRST = 0, FOUND = 1, AFTER_LAST = 2, NULL_ROW = 3; - private final Table table; - private final Select select; - private String alias; - private Session session; - private Index index; - private int scanCount; - - /** - * Indicates that this filter is used in the plan. - */ - private boolean used; - - /** - * The filter used to walk through the index. - */ - private final IndexCursor cursor; - - /** - * The index conditions used for direct index lookup (start or end). - */ - private final ArrayList indexConditions = New.arrayList(); - - /** - * Additional conditions that can't be used for index lookup, but for row - * filter for this table (ID=ID, NAME LIKE '%X%') - */ - private Expression filterCondition; - - /** - * The complete join condition. - */ - private Expression joinCondition; - - private SearchRow currentSearchRow; - private Row current; - private int state; - private TableFilter join; - private boolean outerJoin; - private ArrayList naturalJoinColumns; - private boolean foundOne; - private Expression fullCondition; - private final int hashCode; - - /** - * Create a new table filter object. - * - * @param session the session - * @param table the table from where to read data - * @param alias the alias name - * @param rightsChecked true if rights are already checked - * @param select the select statement - */ - public TableFilter(Session session, Table table, String alias, boolean rightsChecked, Select select) { - this.session = session; - this.table = table; - this.alias = alias; - this.select = select; - this.cursor = new IndexCursor(); - if (!rightsChecked) { - session.getUser().checkRight(table, Right.SELECT); - } - hashCode = session.nextObjectId(); - } - - public Select getSelect() { - return select; - } - - public Table getTable() { - return table; - } - - /** - * Lock the table. This will also lock joined tables. - * - * @param s the session - * @param exclusive true if an exclusive lock is required - * @param force lock even in the MVCC mode - */ - public void lock(Session s, boolean exclusive, boolean force) { - table.lock(s, exclusive, force); - if (join != null) { - join.lock(s, exclusive, force); - } - } - - /** - * Get the best plan item (index, cost) to use use for the current join - * order. - * - * @param s the session - * @param level 1 for the first table in a join, 2 for the second, and so on - * @return the best plan item - */ - public PlanItem getBestPlanItem(Session s, int level) { - PlanItem item; - if (indexConditions.size() == 0) { - item = new PlanItem(); - item.setIndex(table.getScanIndex(s)); - item.cost = item.getIndex().getCost(s, null); - } else { - int len = table.getColumns().length; - int[] masks = new int[len]; - for (IndexCondition condition : indexConditions) { - if (condition.isEvaluatable()) { - if (condition.isAlwaysFalse()) { - masks = null; - break; - } - int id = condition.getColumn().getColumnId(); - masks[id] |= condition.getMask(indexConditions); - } - } - item = table.getBestPlanItem(s, masks); - // the more index conditions, the earlier the table - // to ensure joins without indexes are evaluated: - // x (x.a=10); y (x.b=y.b) - see issue 113 - item.cost -= item.cost * indexConditions.size() / 100 / level; - } - if (join != null) { - setEvaluatable(join); - item.setJoinPlan(join.getBestPlanItem(s, level)); - // TODO optimizer: calculate cost of a join: should use separate - // expected row number and lookup cost - item.cost += item.cost * item.getJoinPlan().cost; - } - return item; - } - - private void setEvaluatable(TableFilter join) { - // this table filter is now evaluatable - in all sub-joins - do { - Expression e = join.getJoinCondition(); - if (e != null) { - e.setEvaluatable(this, true); - } - join = join.getJoin(); - } while (join != null); - } - - /** - * Set what plan item (index, cost) to use use. - * - * @param item the plan item - */ - public void setPlanItem(PlanItem item) { - setIndex(item.getIndex()); - if (join != null) { - if (item.getJoinPlan() != null) { - join.setPlanItem(item.getJoinPlan()); - } - } - } - - /** - * Prepare reading rows. This method will remove all index conditions that - * can not be used, and optimize the conditions. - */ - public void prepare() { - // forget all unused index conditions - for (int i = 0; i < indexConditions.size(); i++) { - IndexCondition condition = indexConditions.get(i); - if (!condition.isAlwaysFalse()) { - Column col = condition.getColumn(); - if (index.getColumnIndex(col) < 0) { - indexConditions.remove(i); - i--; - } - } - } - if (join != null) { - if (SysProperties.CHECK && join == this) { - DbException.throwInternalError("self join"); - } - join.prepare(); - } - if (filterCondition != null) { - filterCondition = filterCondition.optimize(session); - } - if (joinCondition != null) { - joinCondition = joinCondition.optimize(session); - } - } - - /** - * Start the query. This will reset the scan counts. - * - * @param s the session - */ - public void startQuery(Session s) { - this.session = s; - scanCount = 0; - if (join != null) { - join.startQuery(s); - } - } - - /** - * Reset to the current position. - */ - public void reset() { - if (join != null) { - join.reset(); - } - state = BEFORE_FIRST; - foundOne = false; - } - - /** - * Check if there are more rows to read. - * - * @return true if there are - */ - public boolean next() { - if (state == AFTER_LAST) { - return false; - } else if (state == BEFORE_FIRST) { - cursor.find(session, indexConditions); - if (!cursor.isAlwaysFalse()) { - if (join != null) { - join.reset(); - } - } - } else { - // state == FOUND || LAST_ROW - // the last row was ok - try next row of the join - if (join != null && join.next()) { - return true; - } - } - while (true) { - // go to the next row - if (state == NULL_ROW) { - break; - } - if (cursor.isAlwaysFalse()) { - state = AFTER_LAST; - } else { - if ((++scanCount & 4095) == 0) { - checkTimeout(); - } - if (cursor.next()) { - currentSearchRow = cursor.getSearchRow(); - current = null; - state = FOUND; - } else { - state = AFTER_LAST; - } - } - // if no more rows found, try the null row (for outer joins only) - if (state == AFTER_LAST) { - if (outerJoin && !foundOne) { - state = NULL_ROW; - current = table.getNullRow(); - currentSearchRow = current; - } else { - break; - } - } - if (!isOk(filterCondition)) { - continue; - } - boolean joinConditionOk = isOk(joinCondition); - if (state == FOUND) { - if (joinConditionOk) { - foundOne = true; - } else { - continue; - } - } - if (join != null) { - join.reset(); - if (!join.next()) { - continue; - } - } - // check if it's ok - if (state == NULL_ROW || joinConditionOk) { - return true; - } - } - state = AFTER_LAST; - return false; - } - - private void checkTimeout() { - session.checkCanceled(); - // System.out.println(this.alias+ " " + table.getName() + ": " + - // scanCount); - } - - private boolean isOk(Expression condition) { - if (condition == null) { - return true; - } - return Boolean.TRUE.equals(condition.getBooleanValue(session)); - } - - /** - * Get the current row. - * - * @return the current row, or null - */ - public Row get() { - if (current == null && currentSearchRow != null) { - current = cursor.get(); - } - return current; - } - - /** - * Set the current row. - * - * @param current the current row - */ - public void set(Row current) { - // this is currently only used so that check constraints work - to set - // the current (new) row - this.current = current; - this.currentSearchRow = current; - } - - /** - * Get the table alias name. If no alias is specified, the table name is - * returned. - * - * @return the alias name - */ - public String getTableAlias() { - if (alias != null) { - return alias; - } - return table.getName(); - } - - /** - * Add an index condition. - * - * @param condition the index condition - */ - public void addIndexCondition(IndexCondition condition) { - indexConditions.add(condition); - } - - /** - * Add a filter condition. - * - * @param condition the condition - * @param isJoin if this is in fact a join condition - */ - public void addFilterCondition(Expression condition, boolean isJoin) { - if (isJoin) { - if (joinCondition == null) { - joinCondition = condition; - } else { - joinCondition = new ConditionAndOr(ConditionAndOr.AND, joinCondition, condition); - } - } else { - if (filterCondition == null) { - filterCondition = condition; - } else { - filterCondition = new ConditionAndOr(ConditionAndOr.AND, filterCondition, condition); - } - } - } - - /** - * Add a joined table. - * - * @param filter the joined table filter - * @param outer if this is an outer join - * @param on the join condition - */ - public void addJoin(TableFilter filter, boolean outer, Expression on) { - if (on != null) { - on.mapColumns(this, 0); - } - if (join == null) { - this.join = filter; - filter.outerJoin = outer; - if (outer) { - // convert all inner joins on the right hand side to outer joins - TableFilter f = filter.join; - while (f != null) { - f.outerJoin = true; - f = f.join; - } - } - if (on != null) { - filter.mapAndAddFilter(on); - } - } else { - join.addJoin(filter, outer, on); - } - } - - /** - * Map the columns and add the join condition. - * - * @param on the condition - */ - public void mapAndAddFilter(Expression on) { - on.mapColumns(this, 0); - addFilterCondition(on, true); - on.createIndexConditions(session, this); - if (join != null) { - join.mapAndAddFilter(on); - } - } - - public TableFilter getJoin() { - return join; - } - - /** - * Check if this is an outer joined table. - * - * @return true if it is - */ - public boolean isJoinOuter() { - return outerJoin; - } - - /** - * Get the query execution plan text to use for this table filter. - * - * @param isJoin if this is a joined table - * @return the SQL statement snippet - */ - public String getPlanSQL(boolean isJoin) { - StringBuilder buff = new StringBuilder(); - if (isJoin) { - if (outerJoin) { - buff.append("LEFT OUTER JOIN "); - } else { - buff.append("INNER JOIN "); - } - } - buff.append(table.getSQL()); - if (alias != null) { - buff.append(' ').append(Parser.quoteIdentifier(alias)); - } - if (index != null) { - buff.append(" /* "); - StatementBuilder planBuff = new StatementBuilder(); - planBuff.append(index.getPlanSQL()); - if (indexConditions.size() > 0) { - planBuff.append(": "); - for (IndexCondition condition : indexConditions) { - planBuff.appendExceptFirst(" AND "); - planBuff.append(condition.getSQL()); - } - } - String plan = StringUtils.quoteRemarkSQL(planBuff.toString()); - buff.append(plan).append(" */"); - } - if (isJoin) { - buff.append(" ON "); - if (joinCondition == null) { - // need to have a ON expression, otherwise the nesting is - // unclear - buff.append("1=1"); - } else { - buff.append(StringUtils.unEnclose(joinCondition.getSQL())); - } - } - if (filterCondition != null) { - buff.append(" /* WHERE "); - String condition = StringUtils.unEnclose(filterCondition.getSQL()); - condition = StringUtils.quoteRemarkSQL(condition); - buff.append(condition).append(" */"); - } - if (scanCount > 0) { - buff.append(" /* scanCount: ").append(scanCount).append(" */"); - } - return buff.toString(); - } - - /** - * Remove all index conditions that are not used by the current index. - */ - void removeUnusableIndexConditions() { - for (int i = 0; i < indexConditions.size(); i++) { - IndexCondition cond = indexConditions.get(i); - if (!cond.isEvaluatable()) { - indexConditions.remove(i--); - } - } - } - - public Index getIndex() { - return index; - } - - public void setIndex(Index index) { - this.index = index; - cursor.setIndex(index); - } - - public void setUsed(boolean used) { - this.used = used; - } - - public boolean isUsed() { - return used; - } - - /** - * Set the session of this table filter. - * - * @param session the new session - */ - void setSession(Session session) { - this.session = session; - } - - /** - * Remove the joined table - */ - public void removeJoin() { - this.join = null; - } - - public Expression getJoinCondition() { - return joinCondition; - } - - /** - * Remove the join condition. - */ - public void removeJoinCondition() { - this.joinCondition = null; - } - - public Expression getFilterCondition() { - return filterCondition; - } - - /** - * Remove the filter condition. - */ - public void removeFilterCondition() { - this.filterCondition = null; - } - - public void setFullCondition(Expression condition) { - this.fullCondition = condition; - if (join != null) { - join.setFullCondition(condition); - } - } - - /** - * Optimize the full condition. This will add the full condition to the - * filter condition. - * - * @param fromOuterJoin if this method was called from an outer joined table - */ - void optimizeFullCondition(boolean fromOuterJoin) { - if (fullCondition != null) { - fullCondition.addFilterConditions(this, fromOuterJoin || outerJoin); - if (join != null) { - join.optimizeFullCondition(fromOuterJoin || outerJoin); - } - } - } - - /** - * Update the filter and join conditions of this and all joined tables with - * the information that the given table filter can now return rows or not. - * - * @param filter the table filter - * @param b the new flag - */ - public void setEvaluatable(TableFilter filter, boolean b) { - if (filterCondition != null) { - filterCondition.setEvaluatable(filter, b); - } - if (joinCondition != null) { - joinCondition.setEvaluatable(filter, b); - } - if (join != null) { - join.setEvaluatable(filter, b); - } - } - - public String getSchemaName() { - return table.getSchema().getName(); - } - - public Column[] getColumns() { - return table.getColumns(); - } - - /** - * Get the system columns that this table understands. This is used for - * compatibility with other databases. The columns are only returned if the - * current mode supports system columns. - * - * @return the system columns - */ - public Column[] getSystemColumns() { - if (!session.getDatabase().getMode().systemColumns) { - return null; - } - Column[] sys = new Column[3]; - sys[0] = new Column("oid", Value.INT); - sys[0].setTable(table, 0); - sys[1] = new Column("ctid", Value.STRING); - sys[1].setTable(table, 0); - sys[2] = new Column("CTID", Value.STRING); - sys[2].setTable(table, 0); - return sys; - } - - public Value getValue(Column column) { - if (currentSearchRow == null) { - return null; - } - int columnId = column.getColumnId(); - if (current == null) { - Value v = currentSearchRow.getValue(columnId); - if (v != null) { - return v; - } - current = cursor.get(); - } - return current.getValue(columnId); - } - - public TableFilter getTableFilter() { - return this; - } - - public void setAlias(String alias) { - this.alias = alias; - } - - public Expression optimize(ExpressionColumn expressionColumn, Column column) { - return expressionColumn; - } - - public String toString() { - return alias != null ? alias : table.toString(); - } - - /** - * Add a column to the natural join key column list. - * - * @param c the column to add - */ - public void addNaturalJoinColumn(Column c) { - if (naturalJoinColumns == null) { - naturalJoinColumns = New.arrayList(); - } - naturalJoinColumns.add(c); - } - - /** - * Check if the given column is a natural join column. - * - * @param c the column to check - * @return true if this is a joined natural join column - */ - public boolean isNaturalJoinColumn(Column c) { - return naturalJoinColumns != null && naturalJoinColumns.indexOf(c) >= 0; - } - - public int hashCode() { - return hashCode; - } - - /** - * Are there any index conditions that involve IN(...). - * - * @return whether there are IN(...) comparisons - */ - public boolean hasInComparisons() { - for (IndexCondition cond : indexConditions) { - int compareType = cond.getCompareType(); - if (compareType == Comparison.IN_QUERY || compareType == Comparison.IN_LIST) { - return true; - } - } - return false; - } - - /** - * Add the current row to the array, if there is a current row. - * - * @param rows the rows to lock - */ - public void lockRow(ArrayList rows) { - if (state == FOUND) { - rows.add(get()); - } - } - - /** - * Lock the given rows. - * - * @param forUpdateRows the rows to lock - */ - public void lockRows(ArrayList forUpdateRows) { - for (Row row : forUpdateRows) { - table.removeRow(session, row); - table.addRow(session, row); - } - } - -} diff --git a/tools/h2/src/main/org/h2/table/TableLink.java b/tools/h2/src/main/org/h2/table/TableLink.java deleted file mode 100755 index f261cce..0000000 --- a/tools/h2/src/main/org/h2/table/TableLink.java +++ /dev/null @@ -1,590 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.table; - -import java.sql.DatabaseMetaData; -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.ResultSetMetaData; -import java.sql.SQLException; -import java.sql.Statement; -import java.sql.Types; -import java.util.ArrayList; -import java.util.HashMap; -import org.h2.command.Prepared; -import org.h2.constant.ErrorCode; -import org.h2.engine.Session; -import org.h2.engine.UndoLogRecord; -import org.h2.index.Index; -import org.h2.index.IndexType; -import org.h2.index.LinkedIndex; -import org.h2.jdbc.JdbcSQLException; -import org.h2.message.DbException; -import org.h2.result.Row; -import org.h2.result.RowList; -import org.h2.schema.Schema; -import org.h2.util.JdbcUtils; -import org.h2.util.MathUtils; -import org.h2.util.New; -import org.h2.util.StringUtils; -import org.h2.value.DataType; -import org.h2.value.Value; -import org.h2.value.ValueDate; -import org.h2.value.ValueTime; -import org.h2.value.ValueTimestamp; - -/** - * A linked table contains connection information for a table accessible by JDBC. - * The table may be stored in a different database. - */ -public class TableLink extends Table { - - private static final long ROW_COUNT_APPROXIMATION = 100000; - - private String driver, url, user, password, originalSchema, originalTable, qualifiedTableName; - private TableLinkConnection conn; - private HashMap preparedMap = New.hashMap(); - private final ArrayList indexes = New.arrayList(); - private final boolean emitUpdates; - private LinkedIndex linkedIndex; - private DbException connectException; - private boolean storesLowerCase; - private boolean storesMixedCase; - private boolean supportsMixedCaseIdentifiers; - private boolean globalTemporary; - private boolean readOnly; - - public TableLink(Schema schema, int id, String name, String driver, String url, String user, String password, - String originalSchema, String originalTable, boolean emitUpdates, boolean force) { - super(schema, id, name, false, true); - this.driver = driver; - this.url = url; - this.user = user; - this.password = password; - this.originalSchema = originalSchema; - this.originalTable = originalTable; - this.emitUpdates = emitUpdates; - try { - connect(); - } catch (DbException e) { - connectException = e; - if (!force) { - throw e; - } - Column[] cols = { }; - setColumns(cols); - linkedIndex = new LinkedIndex(this, id, IndexColumn.wrap(cols), IndexType.createNonUnique(false)); - indexes.add(linkedIndex); - } - } - - private void connect() { - conn = database.getLinkConnection(driver, url, user, password); - synchronized (conn) { - try { - readMetaData(); - } catch (Exception e) { - // could be SQLException or RuntimeException - conn.close(); - conn = null; - throw DbException.convert(e); - } - } - } - - private void readMetaData() throws SQLException { - DatabaseMetaData meta = conn.getConnection().getMetaData(); - storesLowerCase = meta.storesLowerCaseIdentifiers(); - storesMixedCase = meta.storesMixedCaseIdentifiers(); - supportsMixedCaseIdentifiers = meta.supportsMixedCaseIdentifiers(); - ResultSet rs = meta.getTables(null, originalSchema, originalTable, null); - if (rs.next() && rs.next()) { - throw DbException.get(ErrorCode.SCHEMA_NAME_MUST_MATCH, originalTable); - } - rs.close(); - rs = meta.getColumns(null, originalSchema, originalTable, null); - int i = 0; - ArrayList columnList = New.arrayList(); - HashMap columnMap = New.hashMap(); - String catalog = null, schema = null; - while (rs.next()) { - String thisCatalog = rs.getString("TABLE_CAT"); - if (catalog == null) { - catalog = thisCatalog; - } - String thisSchema = rs.getString("TABLE_SCHEM"); - if (schema == null) { - schema = thisSchema; - } - if (!StringUtils.equals(catalog, thisCatalog) || !StringUtils.equals(schema, thisSchema)) { - // if the table exists in multiple schemas or tables, - // use the alternative solution - columnMap.clear(); - columnList.clear(); - break; - } - String n = rs.getString("COLUMN_NAME"); - n = convertColumnName(n); - int sqlType = rs.getInt("DATA_TYPE"); - long precision = rs.getInt("COLUMN_SIZE"); - precision = convertPrecision(sqlType, precision); - int scale = rs.getInt("DECIMAL_DIGITS"); - int displaySize = MathUtils.convertLongToInt(precision); - int type = DataType.convertSQLTypeToValueType(sqlType); - Column col = new Column(n, type, precision, scale, displaySize); - col.setTable(this, i++); - columnList.add(col); - columnMap.put(n, col); - } - rs.close(); - if (originalTable.indexOf('.') < 0 && !StringUtils.isNullOrEmpty(schema)) { - qualifiedTableName = schema + "." + originalTable; - } else { - qualifiedTableName = originalTable; - } - // check if the table is accessible - Statement stat = null; - try { - stat = conn.getConnection().createStatement(); - rs = stat.executeQuery("SELECT * FROM " + qualifiedTableName + " T WHERE 1=0"); - if (columnList.size() == 0) { - // alternative solution - ResultSetMetaData rsMeta = rs.getMetaData(); - for (i = 0; i < rsMeta.getColumnCount();) { - String n = rsMeta.getColumnName(i + 1); - n = convertColumnName(n); - int sqlType = rsMeta.getColumnType(i + 1); - long precision = rsMeta.getPrecision(i + 1); - precision = convertPrecision(sqlType, precision); - int scale = rsMeta.getScale(i + 1); - int displaySize = rsMeta.getColumnDisplaySize(i + 1); - int type = DataType.convertSQLTypeToValueType(sqlType); - Column col = new Column(n, type, precision, scale, displaySize); - col.setTable(this, i++); - columnList.add(col); - columnMap.put(n, col); - } - } - rs.close(); - } catch (Exception e) { - throw DbException.get(ErrorCode.TABLE_OR_VIEW_NOT_FOUND_1, e, - originalTable + "(" + e.toString() + ")"); - } finally { - JdbcUtils.closeSilently(stat); - } - Column[] cols = new Column[columnList.size()]; - columnList.toArray(cols); - setColumns(cols); - int id = getId(); - linkedIndex = new LinkedIndex(this, id, IndexColumn.wrap(cols), IndexType.createNonUnique(false)); - indexes.add(linkedIndex); - try { - rs = meta.getPrimaryKeys(null, originalSchema, originalTable); - } catch (Exception e) { - // Some ODBC bridge drivers don't support it: - // some combinations of "DataDirect SequeLink(R) for JDBC" - // http://www.datadirect.com/index.ssp - rs = null; - } - String pkName = ""; - ArrayList list; - if (rs != null && rs.next()) { - // the problem is, the rows are not sorted by KEY_SEQ - list = New.arrayList(); - do { - int idx = rs.getInt("KEY_SEQ"); - if (pkName == null) { - pkName = rs.getString("PK_NAME"); - } - while (list.size() < idx) { - list.add(null); - } - String col = rs.getString("COLUMN_NAME"); - col = convertColumnName(col); - Column column = columnMap.get(col); - if (idx == 0) { - // workaround for a bug in the SQLite JDBC driver - list.add(column); - } else { - list.set(idx - 1, column); - } - } while (rs.next()); - addIndex(list, IndexType.createPrimaryKey(false, false)); - rs.close(); - } - try { - rs = meta.getIndexInfo(null, originalSchema, originalTable, false, true); - } catch (Exception e) { - // Oracle throws an exception if the table is not found or is a - // SYNONYM - rs = null; - } - String indexName = null; - list = New.arrayList(); - IndexType indexType = null; - if (rs != null) { - while (rs.next()) { - if (rs.getShort("TYPE") == DatabaseMetaData.tableIndexStatistic) { - // ignore index statistics - continue; - } - String newIndex = rs.getString("INDEX_NAME"); - if (pkName.equals(newIndex)) { - continue; - } - if (indexName != null && !indexName.equals(newIndex)) { - addIndex(list, indexType); - indexName = null; - } - if (indexName == null) { - indexName = newIndex; - list.clear(); - } - boolean unique = !rs.getBoolean("NON_UNIQUE"); - indexType = unique ? IndexType.createUnique(false, false) : IndexType.createNonUnique(false); - String col = rs.getString("COLUMN_NAME"); - col = convertColumnName(col); - Column column = columnMap.get(col); - list.add(column); - } - rs.close(); - } - if (indexName != null) { - addIndex(list, indexType); - } - } - - private long convertPrecision(int sqlType, long precision) { - // workaround for an Oracle problem - // the precision reported by Oracle is 7 for a date column - switch (sqlType) { - case Types.DATE: - precision = Math.max(ValueDate.PRECISION, precision); - break; - case Types.TIMESTAMP: - precision = Math.max(ValueTimestamp.PRECISION, precision); - break; - case Types.TIME: - precision = Math.max(ValueTime.PRECISION, precision); - break; - } - return precision; - } - - private String convertColumnName(String columnName) { - if ((storesMixedCase || storesLowerCase) && columnName.equals(StringUtils.toLowerEnglish(columnName))) { - columnName = StringUtils.toUpperEnglish(columnName); - } else if (storesMixedCase && !supportsMixedCaseIdentifiers) { - // TeraData - columnName = StringUtils.toUpperEnglish(columnName); - } - return columnName; - } - - private void addIndex(ArrayList list, IndexType indexType) { - Column[] cols = new Column[list.size()]; - list.toArray(cols); - Index index = new LinkedIndex(this, 0, IndexColumn.wrap(cols), indexType); - indexes.add(index); - } - - public String getDropSQL() { - return "DROP TABLE IF EXISTS " + getSQL(); - } - - public String getCreateSQL() { - StringBuilder buff = new StringBuilder("CREATE FORCE "); - if (isTemporary()) { - if (globalTemporary) { - buff.append("GLOBAL "); - } else { - buff.append("LOCAL "); - } - buff.append("TEMPORARY "); - } - buff.append("LINKED TABLE ").append(getSQL()); - if (comment != null) { - buff.append(" COMMENT ").append(StringUtils.quoteStringSQL(comment)); - } - buff.append('('). - append(StringUtils.quoteStringSQL(driver)). - append(", "). - append(StringUtils.quoteStringSQL(url)). - append(", "). - append(StringUtils.quoteStringSQL(user)). - append(", "). - append(StringUtils.quoteStringSQL(password)). - append(", "). - append(StringUtils.quoteStringSQL(originalTable)). - append(')'); - if (emitUpdates) { - buff.append(" EMIT UPDATES"); - } - if (readOnly) { - buff.append(" READONLY"); - } - buff.append(" /*" + JdbcSQLException.HIDE_SQL + "*/"); - return buff.toString(); - } - - public Index addIndex(Session session, String indexName, int indexId, IndexColumn[] cols, IndexType indexType, - boolean create, String indexComment) { - throw DbException.getUnsupportedException("LINK"); - } - - public void lock(Session session, boolean exclusive, boolean force) { - // nothing to do - } - - public boolean isLockedExclusively() { - return false; - } - - public Index getScanIndex(Session session) { - return linkedIndex; - } - - private void checkReadOnly() { - if (readOnly) { - throw DbException.get(ErrorCode.DATABASE_IS_READ_ONLY); - } - } - - public void removeRow(Session session, Row row) { - checkReadOnly(); - getScanIndex(session).remove(session, row); - } - - public void addRow(Session session, Row row) { - checkReadOnly(); - getScanIndex(session).add(session, row); - } - - public void close(Session session) { - if (conn != null) { - try { - conn.close(); - } finally { - conn = null; - } - } - } - - public synchronized long getRowCount(Session session) { - String sql = "SELECT COUNT(*) FROM " + qualifiedTableName; - try { - PreparedStatement prep = getPreparedStatement(sql, false); - ResultSet rs = prep.executeQuery(); - rs.next(); - long count = rs.getLong(1); - rs.close(); - return count; - } catch (Exception e) { - throw wrapException(sql, e); - } - } - - /** - * Wrap a SQL exception that occurred while accessing a linked table. - * - * @param sql the SQL statement - * @param ex the exception from the remote database - * @return the wrapped exception - */ - public DbException wrapException(String sql, Exception ex) { - SQLException e = DbException.toSQLException(ex); - return DbException.get(ErrorCode.ERROR_ACCESSING_LINKED_TABLE_2, e, sql, e.toString()); - } - - public String getQualifiedTable() { - return qualifiedTableName; - } - - /** - * Get a prepared statement object for the given statement. Prepared - * statements are kept in a hash map to avoid re-creating them. - * - * @param sql the SQL statement - * @param exclusive if the prepared statement must be removed from the map - * until reusePreparedStatement is called (only required for queries) - * @return the prepared statement - */ - public PreparedStatement getPreparedStatement(String sql, boolean exclusive) { - if (trace.isDebugEnabled()) { - trace.debug(getName() + ":\n" + sql); - } - try { - if (conn == null) { - throw connectException; - } - PreparedStatement prep = preparedMap.get(sql); - if (prep == null) { - prep = conn.getConnection().prepareStatement(sql); - preparedMap.put(sql, prep); - } - if (exclusive) { - preparedMap.remove(sql); - } - return prep; - } catch (SQLException e) { - throw DbException.convert(e); - } - } - - public void unlock(Session s) { - // nothing to do - } - - public void checkRename() { - // ok - } - - public void checkSupportAlter() { - throw DbException.getUnsupportedException("LINK"); - } - - public void truncate(Session session) { - throw DbException.getUnsupportedException("LINK"); - } - - public boolean canGetRowCount() { - return true; - } - - public boolean canDrop() { - return true; - } - - public String getTableType() { - return Table.TABLE_LINK; - } - - public void removeChildrenAndResources(Session session) { - super.removeChildrenAndResources(session); - close(session); - database.removeMeta(session, getId()); - driver = null; - url = user = password = originalTable = null; - preparedMap = null; - invalidate(); - } - - public boolean isOracle() { - return url.startsWith("jdbc:oracle:"); - } - - public ArrayList getIndexes() { - return indexes; - } - - public long getMaxDataModificationId() { - // data may have been modified externally - return Long.MAX_VALUE; - } - - public Index getUniqueIndex() { - for (Index idx : indexes) { - if (idx.getIndexType().isUnique()) { - return idx; - } - } - return null; - } - - public void updateRows(Prepared prepared, Session session, RowList rows) { - boolean deleteInsert; - checkReadOnly(); - if (emitUpdates) { - for (rows.reset(); rows.hasNext();) { - prepared.checkCanceled(); - Row oldRow = rows.next(); - Row newRow = rows.next(); - linkedIndex.update(oldRow, newRow); - session.log(this, UndoLogRecord.DELETE, oldRow); - session.log(this, UndoLogRecord.INSERT, newRow); - } - deleteInsert = false; - } else { - deleteInsert = true; - } - if (deleteInsert) { - super.updateRows(prepared, session, rows); - } - } - - public void setGlobalTemporary(boolean globalTemporary) { - this.globalTemporary = globalTemporary; - } - - public void setReadOnly(boolean readOnly) { - this.readOnly = readOnly; - } - - public TableLinkConnection getConnection() { - return conn; - } - - public long getRowCountApproximation() { - return ROW_COUNT_APPROXIMATION; - } - - /** - * Add this prepared statement to the list of cached statements. - * - * @param prep the prepared statement - * @param sql the SQL statement - */ - public void reusePreparedStatement(PreparedStatement prep, String sql) { - preparedMap.put(sql, prep); - } - - public boolean isDeterministic() { - return false; - } - - /** - * Linked tables don't know if they are readonly. This overwrites - * the default handling. - */ - public void checkWritingAllowed() { - // only the target database can verify this - } - - /** - * Convert the values if required. Default values are not set (kept as - * null). - * - * @param session the session - * @param row the row - */ - public void validateConvertUpdateSequence(Session session, Row row) { - for (int i = 0; i < columns.length; i++) { - Value value = row.getValue(i); - if (value != null) { - // null means use the default value - Column column = columns[i]; - Value v2 = column.validateConvertUpdateSequence(session, value); - if (v2 != value) { - row.setValue(i, v2); - } - } - } - } - - /** - * Get or generate a default value for the given column. Default values are - * not set (kept as null). - * - * @param session the session - * @param column the column - * @return the value - */ - public Value getDefaultValue(Session session, Column column) { - return null; - } - -} diff --git a/tools/h2/src/main/org/h2/table/TableLinkConnection.java b/tools/h2/src/main/org/h2/table/TableLinkConnection.java deleted file mode 100755 index c67a864..0000000 --- a/tools/h2/src/main/org/h2/table/TableLinkConnection.java +++ /dev/null @@ -1,139 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.table; - -import java.sql.Connection; -import java.sql.SQLException; -import java.util.HashMap; - -import org.h2.constant.SysProperties; -import org.h2.message.DbException; -import org.h2.util.Utils; -import org.h2.util.JdbcUtils; -import org.h2.util.StringUtils; - -/** - * A connection for a linked table. The same connection may be used for multiple - * tables, that means a connection may be shared. - */ -public class TableLinkConnection { - - /** - * The map where the link is kept. - */ - private HashMap map; - - /** - * The connection information. - */ - private final String driver, url, user, password; - - /** - * The database connection. - */ - private Connection conn; - - /** - * How many times the connection is used. - */ - private int useCounter; - - private TableLinkConnection(HashMap map, String driver, String url, String user, String password) { - this.map = map; - this.driver = driver; - this.url = url; - this.user = user; - this.password = password; - } - - /** - * Open a new connection. - * - * @param map the map where the connection should be stored - * (if shared connections are enabled). - * @param driver the JDBC driver class name - * @param url the database URL - * @param user the user name - * @param password the password - * @return a connection - */ - public static TableLinkConnection open(HashMap map, String driver, String url, String user, String password) { - TableLinkConnection t = new TableLinkConnection(map, driver, url, user, password); - if (!SysProperties.SHARE_LINKED_CONNECTIONS) { - t.open(); - return t; - } - synchronized (map) { - TableLinkConnection result; - result = map.get(t); - if (result == null) { - synchronized (t) { - t.open(); - } - // put the connection in the map after is has been opened, - // so we know it works - map.put(t, t); - result = t; - } - synchronized (result) { - result.useCounter++; - } - return result; - } - } - - private void open() { - try { - conn = JdbcUtils.getConnection(driver, url, user, password); - } catch (SQLException e) { - throw DbException.convert(e); - } - } - - public int hashCode() { - return Utils.hashCode(driver) - ^ Utils.hashCode(url) - ^ Utils.hashCode(user) - ^ Utils.hashCode(password); - } - - public boolean equals(Object o) { - if (o instanceof TableLinkConnection) { - TableLinkConnection other = (TableLinkConnection) o; - return StringUtils.equals(driver, other.driver) - && StringUtils.equals(url, other.url) - && StringUtils.equals(user, other.user) - && StringUtils.equals(password, other.password); - } - return false; - } - - /** - * Get the connection. - * This method and methods on the statement must be - * synchronized on this object. - * - * @return the connection - */ - Connection getConnection() { - return conn; - } - - /** - * Closes the connection if this is the last link to it. - */ - synchronized void close() { - if (--useCounter <= 0) { - JdbcUtils.closeSilently(conn); - conn = null; - synchronized (map) { - map.remove(this); - } - } - } - -} diff --git a/tools/h2/src/main/org/h2/table/TableView.java b/tools/h2/src/main/org/h2/table/TableView.java deleted file mode 100755 index a38abde..0000000 --- a/tools/h2/src/main/org/h2/table/TableView.java +++ /dev/null @@ -1,371 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.table; - -import java.util.ArrayList; -import org.h2.command.Prepared; -import org.h2.command.dml.Query; -import org.h2.constant.ErrorCode; -import org.h2.engine.Constants; -import org.h2.engine.Session; -import org.h2.engine.User; -import org.h2.expression.Expression; -import org.h2.expression.ExpressionVisitor; -import org.h2.expression.Parameter; -import org.h2.index.Index; -import org.h2.index.IndexType; -import org.h2.index.ViewIndex; -import org.h2.message.DbException; -import org.h2.result.Row; -import org.h2.schema.Schema; -import org.h2.util.IntArray; -import org.h2.util.New; -import org.h2.util.SmallLRUCache; -import org.h2.util.StatementBuilder; -import org.h2.util.StringUtils; -import org.h2.util.Utils; -import org.h2.value.Value; - -/** - * A view is a virtual table that is defined by a query. - */ -public class TableView extends Table { - - private static final long ROW_COUNT_APPROXIMATION = 100; - - private String querySQL; - private ArrayList
tables; - private final String[] columnNames; - private Query viewQuery; - private ViewIndex index; - private boolean recursive; - private DbException createException; - private SmallLRUCache indexCache = SmallLRUCache.newInstance(Constants.VIEW_INDEX_CACHE_SIZE); - private long lastModificationCheck; - private long maxDataModificationId; - private User owner; - private Query topQuery; - - public TableView(Schema schema, int id, String name, String querySQL, ArrayList params, String[] columnNames, - Session session, boolean recursive) { - super(schema, id, name, false, true); - this.querySQL = querySQL; - this.columnNames = columnNames; - this.recursive = recursive; - index = new ViewIndex(this, querySQL, params, recursive); - initColumnsAndTables(session); - } - - /** - * Re-compile the query, updating the SQL statement. - * - * @param session the session - * @return the query - */ - public Query recompileQuery(Session session) { - Prepared p = session.prepare(querySQL); - if (!(p instanceof Query)) { - throw DbException.getSyntaxError(querySQL, 0); - } - Query query = (Query) p; - querySQL = query.getPlanSQL(); - return query; - } - - private void initColumnsAndTables(Session session) { - Column[] cols; - removeViewFromTables(); - try { - Query query = recompileQuery(session); - tables = New.arrayList(query.getTables()); - ArrayList expressions = query.getExpressions(); - ArrayList list = New.arrayList(); - for (int i = 0; i < query.getColumnCount(); i++) { - Expression expr = expressions.get(i); - String name = null; - if (columnNames != null && columnNames.length > i) { - name = columnNames[i]; - } - if (name == null) { - name = expr.getAlias(); - } - int type = expr.getType(); - long precision = expr.getPrecision(); - int scale = expr.getScale(); - int displaySize = expr.getDisplaySize(); - Column col = new Column(name, type, precision, scale, displaySize); - col.setTable(this, i); - list.add(col); - } - cols = new Column[list.size()]; - list.toArray(cols); - createException = null; - viewQuery = query; - } catch (DbException e) { - createException = e; - // if it can't be compiled, then it's a 'zero column table' - // this avoids problems when creating the view when opening the - // database - tables = New.arrayList(); - cols = new Column[0]; - if (recursive && columnNames != null) { - cols = new Column[columnNames.length]; - for (int i = 0; i < columnNames.length; i++) { - cols[i] = new Column(columnNames[i], Value.STRING); - } - index.setRecursive(true); - recursive = true; - createException = null; - } - - } - setColumns(cols); - if (getId() != 0) { - addViewToTables(); - } - } - - /** - * Check if this view is currently invalid. - * - * @return true if it is - */ - public boolean isInvalid() { - return createException != null; - } - - public PlanItem getBestPlanItem(Session session, int[] masks) { - PlanItem item = new PlanItem(); - item.cost = index.getCost(session, masks); - IntArray masksArray = new IntArray(masks == null ? Utils.EMPTY_INT_ARRAY : masks); - ViewIndex i2 = indexCache.get(masksArray); - if (i2 == null || i2.getSession() != session) { - i2 = new ViewIndex(this, index, session, masks); - indexCache.put(masksArray, i2); - } - item.setIndex(i2); - return item; - } - - public String getDropSQL() { - return "DROP VIEW IF EXISTS " + getSQL(); - } - - public String getCreateSQL() { - StatementBuilder buff = new StatementBuilder("CREATE FORCE VIEW "); - buff.append(getSQL()); - if (comment != null) { - buff.append(" COMMENT ").append(StringUtils.quoteStringSQL(comment)); - } - if (columns.length > 0) { - buff.append('('); - for (Column c : columns) { - buff.appendExceptFirst(", "); - buff.append(c.getSQL()); - } - buff.append(')'); - } else if (columnNames != null) { - buff.append('('); - for (String n : columnNames) { - buff.appendExceptFirst(", "); - buff.append(n); - } - buff.append(')'); - } - return buff.append(" AS\n").append(querySQL).toString(); - } - - public void checkRename() { - // ok - } - - public void lock(Session session, boolean exclusive, boolean force) { - // exclusive lock means: the view will be dropped - } - - public void close(Session session) { - // nothing to do - } - - public void unlock(Session s) { - // nothing to do - } - - public boolean isLockedExclusively() { - return false; - } - - public Index addIndex(Session session, String indexName, int indexId, IndexColumn[] cols, IndexType indexType, - boolean create, String indexComment) { - throw DbException.getUnsupportedException("VIEW"); - } - - public void removeRow(Session session, Row row) { - throw DbException.getUnsupportedException("VIEW"); - } - - public void addRow(Session session, Row row) { - throw DbException.getUnsupportedException("VIEW"); - } - - public void checkSupportAlter() { - throw DbException.getUnsupportedException("VIEW"); - } - - public void truncate(Session session) { - throw DbException.getUnsupportedException("VIEW"); - } - - public long getRowCount(Session session) { - throw DbException.throwInternalError(); - } - - public boolean canGetRowCount() { - // TODO view: could get the row count, but not that easy - return false; - } - - public boolean canDrop() { - return true; - } - - public String getTableType() { - return Table.VIEW; - } - - public void removeChildrenAndResources(Session session) { - removeViewFromTables(); - super.removeChildrenAndResources(session); - database.removeMeta(session, getId()); - querySQL = null; - index = null; - invalidate(); - } - - public String getSQL() { - if (isTemporary()) { - return "(" + querySQL + ")"; - } - return super.getSQL(); - } - - public String getQuery() { - return querySQL; - } - - public Index getScanIndex(Session session) { - if (createException != null) { - String msg = createException.getMessage(); - throw DbException.get(ErrorCode.VIEW_IS_INVALID_2, createException, getSQL(), msg); - } - PlanItem item = getBestPlanItem(session, null); - return item.getIndex(); - } - - public ArrayList getIndexes() { - return null; - } - - /** - * Re-compile the view query. - * - * @param session the session - */ - public void recompile(Session session) { - for (Table t : tables) { - t.removeView(this); - } - tables.clear(); - initColumnsAndTables(session); - } - - public long getMaxDataModificationId() { - if (createException != null) { - return Long.MAX_VALUE; - } - if (viewQuery == null) { - return Long.MAX_VALUE; - } - // if nothing was modified in the database since the last check, and the - // last is known, then we don't need to check again - // this speeds up nested views - long dbMod = database.getModificationDataId(); - if (dbMod > lastModificationCheck && maxDataModificationId <= dbMod) { - maxDataModificationId = viewQuery.getMaxDataModificationId(); - lastModificationCheck = dbMod; - } - return maxDataModificationId; - } - - public Index getUniqueIndex() { - return null; - } - - private void removeViewFromTables() { - if (tables != null) { - for (Table t : tables) { - t.removeView(this); - } - tables.clear(); - } - } - - private void addViewToTables() { - for (Table t : tables) { - t.addView(this); - } - } - - private void setOwner(User owner) { - this.owner = owner; - } - - public User getOwner() { - return owner; - } - - /** - * Create a temporary view out of the given query. - * - * @param session the session - * @param owner the owner of the query - * @param name the view name - * @param query the query - * @param topQuery the top level query - * @return the view table - */ - public static TableView createTempView(Session session, User owner, String name, Query query, Query topQuery) { - Schema mainSchema = session.getDatabase().getSchema(Constants.SCHEMA_MAIN); - String querySQL = query.getPlanSQL(); - TableView v = new TableView(mainSchema, 0, name, querySQL, query.getParameters(), null, session, - false); - v.setTopQuery(topQuery); - if (v.createException != null) { - throw v.createException; - } - v.setOwner(owner); - v.setTemporary(true); - return v; - } - - private void setTopQuery(Query topQuery) { - this.topQuery = topQuery; - } - - public long getRowCountApproximation() { - return ROW_COUNT_APPROXIMATION; - } - - public int getParameterOffset() { - return topQuery == null ? 0 : topQuery.getParameters().size(); - } - - public boolean isDeterministic() { - return viewQuery.isEverything(ExpressionVisitor.DETERMINISTIC); - } - -} diff --git a/tools/h2/src/main/org/h2/table/package.html b/tools/h2/src/main/org/h2/table/package.html deleted file mode 100755 index 34d4a36..0000000 --- a/tools/h2/src/main/org/h2/table/package.html +++ /dev/null @@ -1,15 +0,0 @@ - - - - -Javadoc package documentation -

- -Classes related to a table and table meta data. - -

\ No newline at end of file diff --git a/tools/h2/src/main/org/h2/tools/Backup.java b/tools/h2/src/main/org/h2/tools/Backup.java deleted file mode 100755 index f80040a..0000000 --- a/tools/h2/src/main/org/h2/tools/Backup.java +++ /dev/null @@ -1,168 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.tools; - -import java.io.FileNotFoundException; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.sql.SQLException; -import java.util.ArrayList; -import java.util.zip.ZipEntry; -import java.util.zip.ZipOutputStream; -import org.h2.command.dml.BackupCommand; -import org.h2.engine.Constants; -import org.h2.message.DbException; -import org.h2.store.FileLister; -import org.h2.util.IOUtils; -import org.h2.util.Tool; - -/** - * Creates a backup of a database. - *
- * This tool copies all database files. The database must be closed before using - * this tool. To create a backup while the database is in use, run the BACKUP - * SQL statement. In an emergency, for example if the application is not - * responding, creating a backup using the Backup tool is possible by using the - * quiet mode. However, if the database is changed while the backup is running - * in quiet mode, the backup could be corrupt. - * - * @h2.resource - */ -public class Backup extends Tool { - - /** - * Options are case sensitive. Supported options are: - *
- * - * - * - * - * - * - * - * - * - * - *
[-help] or [-?]Print the list of options
[-file <filename>]The target file name (default: backup.zip)
[-dir <dir>]The source directory (default: .)
[-db <database>]Source database; not required if there is only one
[-quiet]Do not print progress information
- * @h2.resource - * - * @param args the command line arguments - */ - public static void main(String... args) throws SQLException { - new Backup().runTool(args); - } - - public void runTool(String... args) throws SQLException { - String zipFileName = "backup.zip"; - String dir = "."; - String db = null; - boolean quiet = false; - for (int i = 0; args != null && i < args.length; i++) { - String arg = args[i]; - if (arg.equals("-dir")) { - dir = args[++i]; - } else if (arg.equals("-db")) { - db = args[++i]; - } else if (arg.equals("-quiet")) { - quiet = true; - } else if (arg.equals("-file")) { - zipFileName = args[++i]; - } else if (arg.equals("-help") || arg.equals("-?")) { - showUsage(); - return; - } else { - throwUnsupportedOption(arg); - } - } - try { - process(zipFileName, dir, db, quiet); - } catch (Exception e) { - throw DbException.toSQLException(e); - } - } - - /** - * Backs up database files. - * - * @param zipFileName the name of the target backup file (including path) - * @param directory the source directory name - * @param db the source database name (null if there is only one database) - * @param quiet don't print progress information - * @throws SQLException - */ - public static void execute(String zipFileName, String directory, String db, boolean quiet) throws SQLException { - try { - new Backup().process(zipFileName, directory, db, quiet); - } catch (Exception e) { - throw DbException.toSQLException(e); - } - } - - private void process(String zipFileName, String directory, String db, boolean quiet) throws SQLException { - ArrayList list = FileLister.getDatabaseFiles(directory, db, true); - if (!quiet) { - FileLister.tryUnlockDatabase(list, "backup"); - } - if (list.size() == 0) { - if (!quiet) { - printNoDatabaseFilesFound(directory, db); - } - return; - } - zipFileName = IOUtils.normalize(zipFileName); - if (IOUtils.exists(zipFileName)) { - IOUtils.delete(zipFileName); - } - OutputStream fileOut = null; - try { - fileOut = IOUtils.openFileOutputStream(zipFileName, false); - ZipOutputStream zipOut = new ZipOutputStream(fileOut); - String base = ""; - for (String fileName : list) { - if (fileName.endsWith(Constants.SUFFIX_PAGE_FILE)) { - base = IOUtils.getParent(fileName); - break; - } - } - for (String fileName : list) { - String f = IOUtils.getAbsolutePath(fileName); - if (!f.startsWith(base)) { - DbException.throwInternalError(f + " does not start with " + base); - } - if (IOUtils.isDirectory(fileName)) { - continue; - } - f = f.substring(base.length()); - f = BackupCommand.correctFileName(f); - ZipEntry entry = new ZipEntry(f); - zipOut.putNextEntry(entry); - InputStream in = null; - try { - in = IOUtils.openFileInputStream(fileName); - IOUtils.copyAndCloseInput(in, zipOut); - } catch (FileNotFoundException e) { - // the file could have been deleted in the meantime - // ignore this (in this case an empty file is created) - } finally { - IOUtils.closeSilently(in); - } - zipOut.closeEntry(); - if (!quiet) { - out.println("Processed: " + fileName); - } - } - zipOut.closeEntry(); - zipOut.close(); - } catch (IOException e) { - throw DbException.convertIOException(e, zipFileName); - } finally { - IOUtils.closeSilently(fileOut); - } - } - -} diff --git a/tools/h2/src/main/org/h2/tools/ChangeFileEncryption.java b/tools/h2/src/main/org/h2/tools/ChangeFileEncryption.java deleted file mode 100755 index 4a85396..0000000 --- a/tools/h2/src/main/org/h2/tools/ChangeFileEncryption.java +++ /dev/null @@ -1,219 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.tools; - -import java.sql.SQLException; -import java.util.ArrayList; -import org.h2.message.DbException; -import org.h2.security.SHA256; -import org.h2.store.FileLister; -import org.h2.store.FileStore; -import org.h2.util.IOUtils; -import org.h2.util.Tool; - -/** - * Allows changing the database file encryption password or algorithm. - *
- * This tool can not be used to change a password of a user. - * The database must be closed before using this tool. - * @h2.resource - */ -public class ChangeFileEncryption extends Tool { - - private String directory; - private String cipherType; - private byte[] decrypt; - private byte[] encrypt; - - /** - * Options are case sensitive. Supported options are: - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - *
[-help] or [-?]Print the list of options
[-cipher type]The encryption type (AES or XTEA)
[-dir <dir>]The database directory (default: .)
[-db <database>]Database name (all databases if not set)
[-decrypt <pwd>]The decryption password (if not set: not yet encrypted)
[-encrypt <pwd>]The encryption password (if not set: do not encrypt)
[-quiet]Do not print progress information
- * @h2.resource - * - * @param args the command line arguments - */ - public static void main(String... args) throws SQLException { - new ChangeFileEncryption().runTool(args); - } - - public void runTool(String... args) throws SQLException { - String dir = "."; - String cipher = null; - char[] decryptPassword = null; - char[] encryptPassword = null; - String db = null; - boolean quiet = false; - for (int i = 0; args != null && i < args.length; i++) { - String arg = args[i]; - if (arg.equals("-dir")) { - dir = args[++i]; - } else if (arg.equals("-cipher")) { - cipher = args[++i]; - } else if (arg.equals("-db")) { - db = args[++i]; - } else if (arg.equals("-decrypt")) { - decryptPassword = args[++i].toCharArray(); - } else if (arg.equals("-encrypt")) { - encryptPassword = args[++i].toCharArray(); - } else if (arg.equals("-quiet")) { - quiet = true; - } else if (arg.equals("-help") || arg.equals("-?")) { - showUsage(); - return; - } else { - throwUnsupportedOption(arg); - } - } - if ((encryptPassword == null && decryptPassword == null) || cipher == null) { - showUsage(); - throw new SQLException("Encryption or decryption password not set, or cipher not set"); - } - try { - process(dir, db, cipher, decryptPassword, encryptPassword, quiet); - } catch (Exception e) { - throw DbException.toSQLException(e); - } - } - - /** - * Get the file encryption key for a given password. - * The password must be supplied as char arrays and is cleaned in this method. - * - * @param password the password as a char array - * @return the encryption key - */ - private static byte[] getFileEncryptionKey(char[] password) { - if (password == null) { - return null; - } - SHA256 sha = new SHA256(); - return sha.getKeyPasswordHash("file", password); - } - - /** - * Changes the password for a database. - * The passwords must be supplied as char arrays and are cleaned in this method. - * The database must be closed before calling this method. - * - * @param dir the directory (. for the current directory) - * @param db the database name (null for all databases) - * @param cipher the cipher (AES, XTEA) - * @param decryptPassword the decryption password as a char array - * @param encryptPassword the encryption password as a char array - * @param quiet don't print progress information - * @throws SQLException - */ - public static void execute(String dir, String db, String cipher, char[] decryptPassword, char[] encryptPassword, boolean quiet) throws SQLException { - try { - new ChangeFileEncryption().process(dir, db, cipher, decryptPassword, encryptPassword, quiet); - } catch (Exception e) { - throw DbException.toSQLException(e); - } - } - - private void process(String dir, String db, String cipher, char[] decryptPassword, char[] encryptPassword, boolean quiet) throws SQLException { - ChangeFileEncryption change = new ChangeFileEncryption(); - if (encryptPassword != null) { - for (char c : encryptPassword) { - if (c == ' ') { - throw new SQLException("The file password may not contain spaces"); - } - } - } - change.out = out; - change.directory = dir; - change.cipherType = cipher; - change.decrypt = getFileEncryptionKey(decryptPassword); - change.encrypt = getFileEncryptionKey(encryptPassword); - - ArrayList files = FileLister.getDatabaseFiles(dir, db, true); - FileLister.tryUnlockDatabase(files, "encryption"); - files = FileLister.getDatabaseFiles(dir, db, false); - if (files.size() == 0 && !quiet) { - printNoDatabaseFilesFound(dir, db); - } - // first, test only if the file can be renamed - // (to find errors with locked files early) - for (String fileName : files) { - String temp = dir + "/temp.db"; - IOUtils.delete(temp); - IOUtils.rename(fileName, temp); - IOUtils.rename(temp, fileName); - } - // if this worked, the operation will (hopefully) be successful - // TODO changeFileEncryption: this is a workaround! - // make the operation atomic (all files or none) - for (String fileName : files) { - // Don't process a lob directory, just the files in the directory. - if (!IOUtils.isDirectory(fileName)) { - change.process(fileName); - } - } - } - - private void process(String fileName) { - FileStore in; - if (decrypt == null) { - in = FileStore.open(null, fileName, "r"); - } else { - in = FileStore.open(null, fileName, "r", cipherType, decrypt); - } - in.init(); - copy(fileName, in, encrypt); - } - - private void copy(String fileName, FileStore in, byte[] key) { - if (IOUtils.isDirectory(fileName)) { - return; - } - String temp = directory + "/temp.db"; - IOUtils.delete(temp); - FileStore fileOut; - if (key == null) { - fileOut = FileStore.open(null, temp, "rw"); - } else { - fileOut = FileStore.open(null, temp, "rw", cipherType, key); - } - fileOut.init(); - byte[] buffer = new byte[4 * 1024]; - long remaining = in.length() - FileStore.HEADER_LENGTH; - long total = remaining; - in.seek(FileStore.HEADER_LENGTH); - fileOut.seek(FileStore.HEADER_LENGTH); - long time = System.currentTimeMillis(); - while (remaining > 0) { - if (System.currentTimeMillis() - time > 1000) { - out.println(fileName + ": " + (100 - 100 * remaining / total) + "%"); - time = System.currentTimeMillis(); - } - int len = (int) Math.min(buffer.length, remaining); - in.readFully(buffer, 0, len); - fileOut.write(buffer, 0, len); - remaining -= len; - } - in.close(); - fileOut.close(); - IOUtils.delete(fileName); - IOUtils.rename(temp, fileName); - } - -} diff --git a/tools/h2/src/main/org/h2/tools/CompressTool.java b/tools/h2/src/main/org/h2/tools/CompressTool.java deleted file mode 100755 index ae84009..0000000 --- a/tools/h2/src/main/org/h2/tools/CompressTool.java +++ /dev/null @@ -1,312 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.tools; - -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.util.zip.DeflaterOutputStream; -import java.util.zip.GZIPInputStream; -import java.util.zip.GZIPOutputStream; -import java.util.zip.InflaterInputStream; -import java.util.zip.ZipEntry; -import java.util.zip.ZipInputStream; -import java.util.zip.ZipOutputStream; - -import org.h2.compress.CompressDeflate; -import org.h2.compress.CompressLZF; -import org.h2.compress.CompressNo; -import org.h2.compress.Compressor; -import org.h2.compress.LZFInputStream; -import org.h2.compress.LZFOutputStream; -import org.h2.constant.ErrorCode; -import org.h2.engine.Constants; -import org.h2.message.DbException; -import org.h2.util.Utils; -import org.h2.util.StringUtils; - -/** - * A tool to losslessly compress data, and expand the compressed data again. - */ -public class CompressTool { - - private static final int MAX_BUFFER_SIZE = 3 * Constants.IO_BUFFER_SIZE_COMPRESS; - private byte[] cachedBuffer; - - private CompressTool() { - // don't allow construction - } - - private byte[] getBuffer(int min) { - if (min > MAX_BUFFER_SIZE) { - return Utils.newBytes(min); - } - if (cachedBuffer == null || cachedBuffer.length < min) { - cachedBuffer = Utils.newBytes(min); - } - return cachedBuffer; - } - - /** - * Get a new instance. Each instance uses a separate buffer, so multiple - * instances can be used concurrently. However each instance alone is not - * multithreading safe. - * - * @return a new instance - */ - public static CompressTool getInstance() { - return new CompressTool(); - } - - /** - * Compressed the data using the specified algorithm. If no algorithm is - * supplied, LZF is used - * - * @param in the byte array with the original data - * @param algorithm the algorithm (LZF, DEFLATE) - * @return the compressed data - * @throws SQLException if a error occurs - */ - public byte[] compress(byte[] in, String algorithm) { - int len = in.length; - if (in.length < 5) { - algorithm = "NO"; - } - Compressor compress = getCompressor(algorithm); - byte[] buff = getBuffer((len < 100 ? len + 100 : len) * 2); - int newLen = compress(in, in.length, compress, buff); - byte[] out = Utils.newBytes(newLen); - System.arraycopy(buff, 0, out, 0, newLen); - return out; - } - - /** - * INTERNAL - */ - public int compress(byte[] in, int len, Compressor compress, byte[] out) { - int newLen = 0; - out[0] = (byte) compress.getAlgorithm(); - int start = 1 + writeInt(out, 1, len); - newLen = compress.compress(in, len, out, start); - if (newLen > len + start || newLen <= 0) { - out[0] = Compressor.NO; - System.arraycopy(in, 0, out, start, len); - newLen = len + start; - } - return newLen; - } - - /** - * Expands the compressed data. - * - * @param in the byte array with the compressed data - * @return the uncompressed data - * @throws SQLException if a error occurs - */ - public byte[] expand(byte[] in) { - int algorithm = in[0]; - Compressor compress = getCompressor(algorithm); - try { - int len = readInt(in, 1); - int start = 1 + getLength(len); - byte[] buff = Utils.newBytes(len); - compress.expand(in, start, in.length - start, buff, 0, len); - return buff; - } catch (Exception e) { - throw DbException.get(ErrorCode.COMPRESSION_ERROR, e); - } - } - - /** - * INTERNAL - */ - public void expand(byte[] in, byte[] out, int outPos) { - int algorithm = in[0]; - Compressor compress = getCompressor(algorithm); - try { - int len = readInt(in, 1); - int start = 1 + getLength(len); - compress.expand(in, start, in.length - start, out, outPos, len); - } catch (Exception e) { - throw DbException.get(ErrorCode.COMPRESSION_ERROR, e); - } - } - - private int readInt(byte[] buff, int pos) { - int x = buff[pos++] & 0xff; - if (x < 0x80) { - return x; - } - if (x < 0xc0) { - return ((x & 0x3f) << 8) + (buff[pos] & 0xff); - } - if (x < 0xe0) { - return ((x & 0x1f) << 16) + ((buff[pos++] & 0xff) << 8) + (buff[pos] & 0xff); - } - if (x < 0xf0) { - return ((x & 0xf) << 24) + ((buff[pos++] & 0xff) << 16) + ((buff[pos++] & 0xff) << 8) - + (buff[pos] & 0xff); - } - return ((buff[pos++] & 0xff) << 24) + ((buff[pos++] & 0xff) << 16) + ((buff[pos++] & 0xff) << 8) - + (buff[pos] & 0xff); - } - - private int writeInt(byte[] buff, int pos, int x) { - if (x < 0) { - buff[pos++] = (byte) 0xf0; - buff[pos++] = (byte) (x >> 24); - buff[pos++] = (byte) (x >> 16); - buff[pos++] = (byte) (x >> 8); - buff[pos] = (byte) x; - return 5; - } else if (x < 0x80) { - buff[pos] = (byte) x; - return 1; - } else if (x < 0x4000) { - buff[pos++] = (byte) (0x80 | (x >> 8)); - buff[pos] = (byte) x; - return 2; - } else if (x < 0x200000) { - buff[pos++] = (byte) (0xc0 | (x >> 16)); - buff[pos++] = (byte) (x >> 8); - buff[pos] = (byte) x; - return 3; - } else if (x < 0x10000000) { - buff[pos++] = (byte) (0xe0 | (x >> 24)); - buff[pos++] = (byte) (x >> 16); - buff[pos++] = (byte) (x >> 8); - buff[pos] = (byte) x; - return 4; - } else { - buff[pos++] = (byte) 0xf0; - buff[pos++] = (byte) (x >> 24); - buff[pos++] = (byte) (x >> 16); - buff[pos++] = (byte) (x >> 8); - buff[pos] = (byte) x; - return 5; - } - } - - private int getLength(int x) { - if (x < 0) { - return 5; - } else if (x < 0x80) { - return 1; - } else if (x < 0x4000) { - return 2; - } else if (x < 0x200000) { - return 3; - } else if (x < 0x10000000) { - return 4; - } else { - return 5; - } - } - - private Compressor getCompressor(String algorithm) { - if (algorithm == null) { - algorithm = "LZF"; - } - int idx = algorithm.indexOf(' '); - String options = null; - if (idx > 0) { - options = algorithm.substring(idx + 1); - algorithm = algorithm.substring(0, idx); - } - int a = getCompressAlgorithm(algorithm); - Compressor compress = getCompressor(a); - compress.setOptions(options); - return compress; - } - - /** - * INTERNAL - */ - public int getCompressAlgorithm(String algorithm) { - algorithm = StringUtils.toUpperEnglish(algorithm); - if ("NO".equals(algorithm)) { - return Compressor.NO; - } else if ("LZF".equals(algorithm)) { - return Compressor.LZF; - } else if ("DEFLATE".equals(algorithm)) { - return Compressor.DEFLATE; - } else { - throw DbException.get(ErrorCode.UNSUPPORTED_COMPRESSION_ALGORITHM_1, algorithm); - } - } - - private Compressor getCompressor(int algorithm) { - switch (algorithm) { - case Compressor.NO: - return new CompressNo(); - case Compressor.LZF: - return new CompressLZF(); - case Compressor.DEFLATE: - return new CompressDeflate(); - default: - throw DbException.get(ErrorCode.UNSUPPORTED_COMPRESSION_ALGORITHM_1, "" + algorithm); - } - } - - /** - * INTERNAL - */ - public static OutputStream wrapOutputStream(OutputStream out, String compressionAlgorithm, String entryName) { - try { - if ("GZIP".equals(compressionAlgorithm)) { - out = new GZIPOutputStream(out); - } else if ("ZIP".equals(compressionAlgorithm)) { - ZipOutputStream z = new ZipOutputStream(out); - z.putNextEntry(new ZipEntry(entryName)); - out = z; - } else if ("DEFLATE".equals(compressionAlgorithm)) { - out = new DeflaterOutputStream(out); - } else if ("LZF".equals(compressionAlgorithm)) { - out = new LZFOutputStream(out); - } else if (compressionAlgorithm != null) { - throw DbException.get(ErrorCode.UNSUPPORTED_COMPRESSION_ALGORITHM_1, compressionAlgorithm); - } - return out; - } catch (IOException e) { - throw DbException.convertIOException(e, null); - } - } - - /** - * INTERNAL - */ - public static InputStream wrapInputStream(InputStream in, String compressionAlgorithm, String entryName) { - try { - if ("GZIP".equals(compressionAlgorithm)) { - in = new GZIPInputStream(in); - } else if ("ZIP".equals(compressionAlgorithm)) { - ZipInputStream z = new ZipInputStream(in); - while (true) { - ZipEntry entry = z.getNextEntry(); - if (entry == null) { - return null; - } - if (entryName.equals(entry.getName())) { - break; - } - } - in = z; - } else if ("DEFLATE".equals(compressionAlgorithm)) { - in = new InflaterInputStream(in); - } else if ("LZF".equals(compressionAlgorithm)) { - in = new LZFInputStream(in); - } else if (compressionAlgorithm != null) { - throw DbException.get(ErrorCode.UNSUPPORTED_COMPRESSION_ALGORITHM_1, compressionAlgorithm); - } - return in; - } catch (IOException e) { - throw DbException.convertIOException(e, null); - } - } - -} - diff --git a/tools/h2/src/main/org/h2/tools/Console.java b/tools/h2/src/main/org/h2/tools/Console.java deleted file mode 100755 index e78df5c..0000000 --- a/tools/h2/src/main/org/h2/tools/Console.java +++ /dev/null @@ -1,552 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.tools; - -//## AWT begin ## -import java.awt.Button; -import java.awt.Dimension; -import java.awt.Font; -import java.awt.Frame; -import java.awt.GraphicsEnvironment; -import java.awt.GridBagConstraints; -import java.awt.GridBagLayout; -import java.awt.Image; -import java.awt.Insets; -import java.awt.Label; -import java.awt.MenuItem; -import java.awt.Panel; -import java.awt.PopupMenu; -import java.awt.SystemColor; -import java.awt.TextField; -import java.awt.Toolkit; -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; -import java.awt.event.MouseEvent; -import java.awt.event.MouseListener; -import java.awt.event.WindowEvent; -import java.awt.event.WindowListener; -import java.io.IOException; -import java.sql.SQLException; -import org.h2.constant.SysProperties; -import org.h2.server.ShutdownHandler; -import org.h2.util.Tool; -import org.h2.util.Utils; - -/** - * Starts the H2 Console (web-) server, as well as the TCP and PG server. - * @h2.resource - * - * @author Thomas Mueller, Ridvan Agar - */ -public class Console extends Tool implements -//## AWT begin ## -ActionListener, MouseListener, WindowListener, -//## AWT end ## -ShutdownHandler { - -//## AWT begin ## - private Frame frame; - private boolean trayIcon; - private Font font; - private Button startBrowser; - private TextField urlText; -//## AWT end ## - private Server web, tcp, pg; - private boolean isWindows; - - /** - * When running without options, -tcp, -web, -browser and -pg are started. - *
- * Options are case sensitive. Supported options are: - * - * - * - * - * - * - * - * - * - * - * - * - * - *
[-help] or [-?]Print the list of options
[-web]Start the web server with the H2 Console
[-tool]Start the icon or window that allows to start a browser
[-browser]Start a browser connecting to the web server
[-tcp]Start the TCP server
[-pg]Start the PG server
- * For each Server, additional options are available; - * for details, see the Server tool.
- * If a service can not be started, the program - * terminates with an exit code of 1. - * @h2.resource - * - * @param args the command line arguments - */ - public static void main(String... args) throws SQLException { - new Console().runTool(args); - } - - /** - * This tool starts the H2 Console (web-) server, as well as the TCP and PG - * server. For JDK 1.6, a system tray icon is created, for platforms that - * support it. Otherwise, a small window opens. - * - * @param args the command line arguments - */ - public void runTool(String... args) throws SQLException { - isWindows = SysProperties.getStringSetting("os.name", "").startsWith("Windows"); - boolean tcpStart = false, pgStart = false, webStart = false, toolStart = false; - boolean browserStart = false; - boolean startDefaultServers = true; - - for (int i = 0; args != null && i < args.length; i++) { - String arg = args[i]; - if (arg == null) { - continue; - } else if ("-?".equals(arg) || "-help".equals(arg)) { - showUsage(); - return; - } else if ("-web".equals(arg)) { - startDefaultServers = false; - webStart = true; - } else if ("-tool".equals(arg)) { - startDefaultServers = false; - webStart = true; - toolStart = true; - } else if ("-browser".equals(arg)) { - startDefaultServers = false; - webStart = true; - browserStart = true; - } else if ("-tcp".equals(arg)) { - startDefaultServers = false; - tcpStart = true; - } else if ("-pg".equals(arg)) { - startDefaultServers = false; - pgStart = true; - } - } - if (startDefaultServers) { - webStart = true; - toolStart = true; - browserStart = true; - tcpStart = true; - pgStart = true; - } - SQLException startException = null; - boolean webRunning = false; - if (webStart) { - try { - web = Server.createWebServer(args); - web.setShutdownHandler(this); - web.start(); - webRunning = true; - } catch (SQLException e) { - printProblem(e, web); - startException = e; - } - } - -//## AWT begin ## - if (toolStart && webRunning && !GraphicsEnvironment.isHeadless()) { - loadFont(); - try { - if (!createTrayIcon()) { - showWindow(); - } - } catch (Exception e) { - e.printStackTrace(); - } - } -//## AWT end ## - - // start browser in any case (even if the server is already running) - // because some people don't look at the output, - // but are wondering why nothing happens - if (browserStart) { - Server.openBrowser(web.getURL()); - } - - if (tcpStart) { - try { - tcp = Server.createTcpServer(args); - tcp.start(); - } catch (SQLException e) { - printProblem(e, tcp); - if (startException == null) { - startException = e; - } - } - } - if (pgStart) { - try { - pg = Server.createPgServer(args); - pg.start(); - } catch (SQLException e) { - printProblem(e, pg); - if (startException == null) { - startException = e; - } - } - } - if (startException != null) { - throw startException; - } - } - - private void printProblem(Exception e, Server server) { - if (server == null) { - e.printStackTrace(); - } else { - out.println(server.getStatus()); - out.println("Root cause: " + e.getMessage()); - } - } - - private Image loadImage(String name) { - try { - byte[] imageData = Utils.getResource(name); - if (imageData == null) { - return null; - } - return Toolkit.getDefaultToolkit().createImage(imageData); - } catch (IOException e) { - e.printStackTrace(); - return null; - } - } - - /** - * INTERNAL - */ - public void shutdown() { - stopAll(); - } - - /** - * Stop all servers that were started using the console. - */ - void stopAll() { - if (web != null && web.isRunning(false)) { - web.stop(); - web = null; - } - if (tcp != null && tcp.isRunning(false)) { - tcp.stop(); - tcp = null; - } - if (pg != null && pg.isRunning(false)) { - pg.stop(); - pg = null; - } -//## AWT begin ## - if (frame != null) { - frame.dispose(); - frame = null; - } -//## AWT end ## - System.exit(0); - } - -//## AWT begin ## - private void loadFont() { - if (isWindows) { - font = new Font("Dialog", Font.PLAIN, 11); - } else { - font = new Font("Dialog", Font.PLAIN, 12); - } - } - - private boolean createTrayIcon() { - try { - // SystemTray.isSupported(); - Boolean supported = (Boolean) Class.forName("java.awt.SystemTray"). - getMethod("isSupported"). - invoke(null); - if (!supported) { - return false; - } - PopupMenu menuConsole = new PopupMenu(); - MenuItem itemConsole = new MenuItem("H2 Console"); - itemConsole.setActionCommand("console"); - itemConsole.addActionListener(this); - itemConsole.setFont(font); - menuConsole.add(itemConsole); - MenuItem itemStatus = new MenuItem("Status"); - itemStatus.setActionCommand("status"); - itemStatus.addActionListener(this); - itemStatus.setFont(font); - menuConsole.add(itemStatus); - MenuItem itemExit = new MenuItem("Exit"); - itemExit.setFont(font); - itemExit.setActionCommand("exit"); - itemExit.addActionListener(this); - menuConsole.add(itemExit); - - // SystemTray tray = SystemTray.getSystemTray(); - Object tray = Class.forName("java.awt.SystemTray"). - getMethod("getSystemTray"). - invoke(null); - - // Dimension d = tray.getTrayIconSize(); - Dimension d = (Dimension) Class.forName("java.awt.SystemTray"). - getMethod("getTrayIconSize"). - invoke(tray); - String iconFile; - if (d.width >= 24 && d.height >= 24) { - iconFile = "/org/h2/res/h2-24.png"; - } else if (d.width >= 22 && d.height >= 22) { - iconFile = "/org/h2/res/h2-22.png"; - } else { - iconFile = "/org/h2/res/h2.png"; - } - Image icon = loadImage(iconFile); - // TrayIcon icon = new TrayIcon(image, "H2 Database Engine", menuConsole); - Object ti = Class.forName("java.awt.TrayIcon"). - getConstructor(Image.class, String.class, PopupMenu.class). - newInstance(icon, "H2 Database Engine", menuConsole); - - // trayIcon.addMouseListener(this); - ti.getClass(). - getMethod("addMouseListener", MouseListener.class). - invoke(ti, this); - - // tray.add(icon); - tray.getClass(). - getMethod("add", Class.forName("java.awt.TrayIcon")). - invoke(tray, ti); - - this.trayIcon = true; - - return true; - } catch (Exception e) { - return false; - } - } - - private void showWindow() { - if (frame != null) { - return; - } - frame = new Frame("H2 Console"); - frame.addWindowListener(this); - Image image = loadImage("/org/h2/res/h2.png"); - if (image != null) { - frame.setIconImage(image); - } - frame.setResizable(false); - frame.setBackground(SystemColor.control); - - GridBagLayout layout = new GridBagLayout(); - frame.setLayout(layout); - - // the main panel keeps everything together - Panel mainPanel = new Panel(layout); - - GridBagConstraints constraintsPanel = new GridBagConstraints(); - constraintsPanel.gridx = 0; - constraintsPanel.weightx = 1.0D; - constraintsPanel.weighty = 1.0D; - constraintsPanel.fill = GridBagConstraints.BOTH; - constraintsPanel.insets = new Insets(0, 10, 0, 10); - constraintsPanel.gridy = 0; - - GridBagConstraints constraintsButton = new GridBagConstraints(); - constraintsButton.gridx = 0; - constraintsButton.gridwidth = 2; - constraintsButton.insets = new Insets(10, 0, 0, 0); - constraintsButton.gridy = 1; - constraintsButton.anchor = GridBagConstraints.EAST; - - GridBagConstraints constraintsTextField = new GridBagConstraints(); - constraintsTextField.fill = GridBagConstraints.HORIZONTAL; - constraintsTextField.gridy = 0; - constraintsTextField.weightx = 1.0; - constraintsTextField.insets = new Insets(0, 5, 0, 0); - constraintsTextField.gridx = 1; - - GridBagConstraints constraintsLabel = new GridBagConstraints(); - constraintsLabel.gridx = 0; - constraintsLabel.gridy = 0; - - Label label = new Label("H2 Console URL:", Label.LEFT); - label.setFont(font); - mainPanel.add(label, constraintsLabel); - - urlText = new TextField(); - urlText.setEditable(false); - urlText.setFont(font); - urlText.setText(web.getURL()); - if (isWindows) { - urlText.setFocusable(false); - } - mainPanel.add(urlText, constraintsTextField); - - startBrowser = new Button("Start Browser"); - startBrowser.setFocusable(false); - startBrowser.setActionCommand("console"); - startBrowser.addActionListener(this); - startBrowser.setFont(font); - mainPanel.add(startBrowser, constraintsButton); - frame.add(mainPanel, constraintsPanel); - - int width = 300, height = 120; - frame.setSize(width, height); - Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize(); - frame.setLocation((screenSize.width - width) / 2, (screenSize.height - height) / 2); - try { - frame.setVisible(true); - } catch (Throwable t) { - // ignore - // some systems don't support this method, for example IKVM - // however it still works - } - } - - private void startBrowser() { - if (web != null) { - String url = web.getURL(); - if (urlText != null) { - urlText.setText(url); - } - Server.openBrowser(url); - } - } -//## AWT end ## - - /** - * INTERNAL - */ -//## AWT begin ## - public void actionPerformed(ActionEvent e) { - String command = e.getActionCommand(); - if ("exit".equals(command)) { - stopAll(); - } else if ("console".equals(command)) { - startBrowser(); - } else if ("status".equals(command)) { - showWindow(); - } else if (startBrowser == e.getSource()) { - // for some reason, IKVM ignores setActionCommand - startBrowser(); - } - } -//## AWT end ## - - /** - * INTERNAL - */ -//## AWT begin ## - public void mouseClicked(MouseEvent e) { - if (e.getButton() == MouseEvent.BUTTON1) { - startBrowser(); - } - } -//## AWT end ## - - /** - * INTERNAL - */ -//## AWT begin ## - public void mouseEntered(MouseEvent e) { - // nothing to do - } -//## AWT end ## - - /** - * INTERNAL - */ -//## AWT begin ## - public void mouseExited(MouseEvent e) { - // nothing to do - } -//## AWT end ## - - /** - * INTERNAL - */ -//## AWT begin ## - public void mousePressed(MouseEvent e) { - // nothing to do - } -//## AWT end ## - - /** - * INTERNAL - */ -//## AWT begin ## - public void mouseReleased(MouseEvent e) { - // nothing to do - } -//## AWT end ## - - /** - * INTERNAL - */ -//## AWT begin ## - public void windowClosing(WindowEvent e) { - if (trayIcon) { - frame.dispose(); - frame = null; - } else { - stopAll(); - } - } -//## AWT end ## - - /** - * INTERNAL - */ -//## AWT begin ## - public void windowActivated(WindowEvent e) { - // nothing to do - } -//## AWT end ## - - /** - * INTERNAL - */ -//## AWT begin ## - public void windowClosed(WindowEvent e) { - // nothing to do - } -//## AWT end ## - - /** - * INTERNAL - */ -//## AWT begin ## - public void windowDeactivated(WindowEvent e) { - // nothing to do - } -//## AWT end ## - - /** - * INTERNAL - */ -//## AWT begin ## - public void windowDeiconified(WindowEvent e) { - // nothing to do - } -//## AWT end ## - - /** - * INTERNAL - */ -//## AWT begin ## - public void windowIconified(WindowEvent e) { - // nothing to do - } -//## AWT end ## - - /** - * INTERNAL - */ -//## AWT begin ## - public void windowOpened(WindowEvent e) { - // nothing to do - } -//## AWT end ## - -} diff --git a/tools/h2/src/main/org/h2/tools/ConvertTraceFile.java b/tools/h2/src/main/org/h2/tools/ConvertTraceFile.java deleted file mode 100755 index 439a914..0000000 --- a/tools/h2/src/main/org/h2/tools/ConvertTraceFile.java +++ /dev/null @@ -1,223 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.tools; -import java.io.IOException; -import java.io.LineNumberReader; -import java.io.PrintWriter; -import java.sql.SQLException; -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashMap; -import java.util.StringTokenizer; - -import org.h2.message.DbException; -import org.h2.util.IOUtils; -import org.h2.util.MathUtils; -import org.h2.util.New; -import org.h2.util.StringUtils; -import org.h2.util.Tool; - -/** - * Converts a .trace.db file to a SQL script and Java source code. - *
- * SQL statement statistics are listed as well. - * @h2.resource - */ -public class ConvertTraceFile extends Tool { - - private HashMap stats = New.hashMap(); - private long timeTotal; - - /** - * This class holds statistics about a SQL statement. - */ - static class Stat implements Comparable { - String sql; - int executeCount; - long time; - long resultCount; - - public int compareTo(Stat other) { - if (other == this) { - return 0; - } - int c = MathUtils.compareLong(other.time, time); - if (c == 0) { - c = MathUtils.compareInt(other.executeCount, executeCount); - if (c == 0) { - c = sql.compareTo(other.sql); - } - } - return c; - } - } - - /** - * Options are case sensitive. Supported options are: - * - * - * - * - * - * - * - * - * - *
[-help] or [-?]Print the list of options
[-traceFile <file>]The trace file name (default: test.trace.db)
[-script <file>]The script file name (default: test.sql)
[-javaClass <file>]The Java directory and class file name (default: Test)
- * @h2.resource - * - * @param args the command line arguments - */ - public static void main(String... args) throws SQLException { - new ConvertTraceFile().runTool(args); - } - - public void runTool(String... args) throws SQLException { - String traceFile = "test.trace.db"; - String javaClass = "Test"; - String script = "test.sql"; - for (int i = 0; args != null && i < args.length; i++) { - String arg = args[i]; - if (arg.equals("-traceFile")) { - traceFile = args[++i]; - } else if (arg.equals("-javaClass")) { - javaClass = args[++i]; - } else if (arg.equals("-script")) { - script = args[++i]; - } else if (arg.equals("-help") || arg.equals("-?")) { - showUsage(); - return; - } else { - throwUnsupportedOption(arg); - } - } - try { - convertFile(traceFile, javaClass, script); - } catch (IOException e) { - throw DbException.convertIOException(e, traceFile); - } - } - - /** - * Converts a trace file to a Java class file and a script file. - * - * @param traceFileName - * @param javaClassName - * @throws IOException - */ - private void convertFile(String traceFileName, String javaClassName, String script) throws IOException { - LineNumberReader reader = new LineNumberReader(IOUtils.getReader(IOUtils.openFileInputStream(traceFileName))); - PrintWriter javaWriter = new PrintWriter(IOUtils.getWriter(IOUtils.openFileOutputStream(javaClassName + ".java", false))); - PrintWriter scriptWriter = new PrintWriter(IOUtils.getWriter(IOUtils.openFileOutputStream(script, false))); - javaWriter.println("import java.io.*;"); - javaWriter.println("import java.sql.*;"); - javaWriter.println("import java.math.*;"); - javaWriter.println("import java.util.Calendar;"); - String cn = javaClassName.replace('\\', '/'); - int idx = cn.lastIndexOf('/'); - if (idx > 0) { - cn = cn.substring(idx + 1); - } - javaWriter.println("public class " + cn + " {"); - javaWriter.println(" public static void main(String... args) throws Exception {"); - javaWriter.println(" Class.forName(\"org.h2.Driver\");"); - while (true) { - String line = reader.readLine(); - if (line == null) { - break; - } - if (line.startsWith("/**/")) { - line = " " + line.substring(4); - javaWriter.println(line); - } else if (line.startsWith("/*SQL")) { - int end = line.indexOf("*/"); - String sql = line.substring(end + "*/".length()); - sql = StringUtils.javaDecode(sql); - line = line.substring("/*SQL".length(), end); - if (line.length() > 0) { - String statement = sql; - int count = 0; - int time = 0; - line = line.trim(); - if (line.length() > 0) { - StringTokenizer tk = new StringTokenizer(line, " :"); - while (tk.hasMoreElements()) { - String token = tk.nextToken(); - if ("l".equals(token)) { - int len = Integer.parseInt(tk.nextToken()); - statement = sql.substring(0, len) + ";"; - } else if ("#".equals(token)) { - count = Integer.parseInt(tk.nextToken()); - } else if ("t".equals(token)) { - time = Integer.parseInt(tk.nextToken()); - } - } - } - addToStats(statement, count, time); - } - scriptWriter.println(sql); - } - } - javaWriter.println(" }"); - javaWriter.println("}"); - reader.close(); - javaWriter.close(); - if (stats.size() > 0) { - scriptWriter.println("-----------------------------------------"); - scriptWriter.println("-- SQL Statement Statistics"); - scriptWriter.println("-- time: total time in milliseconds (accumulated)"); - scriptWriter.println("-- count: how many times the statement ran"); - scriptWriter.println("-- result: total update count or row count"); - scriptWriter.println("-----------------------------------------"); - scriptWriter.println("-- self accu time count result sql"); - int accumTime = 0; - ArrayList list = New.arrayList(stats.values()); - Collections.sort(list); - if (timeTotal == 0) { - timeTotal = 1; - } - for (Stat stat : list) { - accumTime += stat.time; - StringBuilder buff = new StringBuilder(100); - buff.append("-- "). - append(padNumberLeft(100 * stat.time / timeTotal, 3)). - append("% "). - append(padNumberLeft(100 * accumTime / timeTotal, 3)). - append('%'). - append(padNumberLeft(stat.time, 8)). - append(padNumberLeft(stat.executeCount, 8)). - append(padNumberLeft(stat.resultCount, 8)). - append(' '). - append(removeNewlines(stat.sql)); - scriptWriter.println(buff.toString()); - } - } - scriptWriter.close(); - } - - private String removeNewlines(String s) { - return s == null ? s : s.replace('\r', ' ').replace('\n', ' '); - } - - private String padNumberLeft(long number, int digits) { - return StringUtils.pad(String.valueOf(number), digits, " ", false); - } - - private void addToStats(String sql, int resultCount, int time) { - Stat stat = stats.get(sql); - if (stat == null) { - stat = new Stat(); - stat.sql = sql; - stats.put(sql, stat); - } - stat.executeCount++; - stat.resultCount += resultCount; - stat.time += time; - timeTotal += time; - } - -} diff --git a/tools/h2/src/main/org/h2/tools/CreateCluster.java b/tools/h2/src/main/org/h2/tools/CreateCluster.java deleted file mode 100755 index 71b8fdb..0000000 --- a/tools/h2/src/main/org/h2/tools/CreateCluster.java +++ /dev/null @@ -1,169 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.tools; - -import java.io.OutputStream; -import java.sql.Connection; -import java.sql.DriverManager; -import java.sql.SQLException; -import java.sql.Statement; -import org.h2.util.IOUtils; -import org.h2.util.JdbcUtils; -import org.h2.util.Tool; - -/** - * Creates a cluster from a standalone database. - *
- * Copies a database to another location if required. - * @h2.resource - */ -public class CreateCluster extends Tool { - - /** - * Options are case sensitive. Supported options are: - * - * - * - * - * - * - * - * - * - * - * - * - * - *
[-help] or [-?]Print the list of options
[-urlSource "<url>"]The database URL of the source database (jdbc:h2:...)
[-urlTarget "<url>"]The database URL of the target database (jdbc:h2:...)
[-user <user>]The user name (default: sa)
[-password <pwd>]The password
[-serverList <list>]The comma separated list of host names or IP addresses
- * @h2.resource - * - * @param args the command line arguments - */ - public static void main(String... args) throws SQLException { - new CreateCluster().runTool(args); - } - - public void runTool(String... args) throws SQLException { - String urlSource = null; - String urlTarget = null; - String user = "sa"; - String password = ""; - String serverList = null; - for (int i = 0; args != null && i < args.length; i++) { - String arg = args[i]; - if (arg.equals("-urlSource")) { - urlSource = args[++i]; - } else if (arg.equals("-urlTarget")) { - urlTarget = args[++i]; - } else if (arg.equals("-user")) { - user = args[++i]; - } else if (arg.equals("-password")) { - password = args[++i]; - } else if (arg.equals("-serverList")) { - serverList = args[++i]; - } else if (arg.equals("-help") || arg.equals("-?")) { - showUsage(); - return; - } else { - throwUnsupportedOption(arg); - } - } - if (urlSource == null || urlTarget == null || serverList == null) { - showUsage(); - throw new SQLException("Source URL, target URL, or server list not set"); - } - process(urlSource, urlTarget, user, password, serverList); - } - - /** - * Creates a cluster. - * - * @param urlSource the database URL of the original database - * @param urlTarget the database URL of the copy - * @param user the user name - * @param password the password - * @param serverList the server list - * @throws SQLException - */ - public void execute(String urlSource, String urlTarget, String user, String password, String serverList) throws SQLException { - new CreateCluster().process(urlSource, urlTarget, user, password, serverList); - } - - private void process(String urlSource, String urlTarget, String user, String password, String serverList) throws SQLException { - Connection connSource = null, connTarget = null; - Statement statSource = null, statTarget = null; - String scriptFile = "backup.sql"; - try { - org.h2.Driver.load(); - - // verify that the database doesn't exist - boolean exists; - try { - connTarget = DriverManager.getConnection(urlTarget + ";IFEXISTS=TRUE", user, password); - connTarget.close(); - exists = true; - } catch (SQLException e) { - // database does not exists - ok - exists = false; - } - if (exists) { - throw new SQLException("Target database must not yet exist. Please delete it first"); - } - - // use cluster='' so connecting is possible - // even if the cluster is enabled - connSource = DriverManager.getConnection(urlSource + ";CLUSTER=''", user, password); - statSource = connSource.createStatement(); - - // enable the exclusive mode and close other connections, - // so that data can't change while restoring the second database - statSource.execute("SET EXCLUSIVE 2"); - - try { - - // backup - Script script = new Script(); - script.setOut(out); - OutputStream scriptOut = null; - try { - scriptOut = IOUtils.openFileOutputStream(scriptFile, false); - script.process(connSource, scriptOut); - } finally { - IOUtils.closeSilently(scriptOut); - } - - // delete the target database and then restore - connTarget = DriverManager.getConnection(urlTarget + ";CLUSTER=''", user, password); - statTarget = connTarget.createStatement(); - statTarget.execute("DROP ALL OBJECTS DELETE FILES"); - connTarget.close(); - - RunScript runScript = new RunScript(); - runScript.setOut(out); - runScript.process(urlTarget, user, password, scriptFile, null, false); - - connTarget = DriverManager.getConnection(urlTarget, user, password); - statTarget = connTarget.createStatement(); - - // set the cluster to the serverList on both databases - statSource.executeUpdate("SET CLUSTER '" + serverList + "'"); - statTarget.executeUpdate("SET CLUSTER '" + serverList + "'"); - } finally { - - // switch back to the regular mode - statSource.execute("SET EXCLUSIVE FALSE"); - } - } finally { - IOUtils.delete(scriptFile); - JdbcUtils.closeSilently(statSource); - JdbcUtils.closeSilently(statTarget); - JdbcUtils.closeSilently(connSource); - JdbcUtils.closeSilently(connTarget); - } - } - -} diff --git a/tools/h2/src/main/org/h2/tools/Csv.java b/tools/h2/src/main/org/h2/tools/Csv.java deleted file mode 100755 index 3b5e174..0000000 --- a/tools/h2/src/main/org/h2/tools/Csv.java +++ /dev/null @@ -1,728 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.tools; - -import java.io.BufferedInputStream; -import java.io.BufferedOutputStream; -import java.io.BufferedReader; -import java.io.BufferedWriter; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.io.OutputStream; -import java.io.OutputStreamWriter; -import java.io.Reader; -import java.io.Writer; -import java.sql.Connection; -import java.sql.ResultSet; -import java.sql.ResultSetMetaData; -import java.sql.SQLException; -import java.sql.Statement; -import java.sql.Types; -import java.util.ArrayList; - -import org.h2.constant.ErrorCode; -import org.h2.constant.SysProperties; -import org.h2.engine.Constants; -import org.h2.message.DbException; -import org.h2.util.IOUtils; -import org.h2.util.JdbcUtils; -import org.h2.util.New; - -/** - * A facility to read from and write to CSV (comma separated values) files. When - * reading, the BOM (the byte-order-mark) character 0xfeff at the beginning of - * the file is ignored. - * - * @author Thomas Mueller, Sylvain Cuaz - */ -public class Csv implements SimpleRowSource { - - private String streamCharset = SysProperties.FILE_ENCODING; - private String[] columnNames; - private char fieldSeparatorRead = ','; - private char commentLineStart = '#'; - private String fieldSeparatorWrite = ","; - private String rowSeparatorWrite; - private char fieldDelimiter = '\"'; - private char escapeCharacter = '\"'; - private String lineSeparator = SysProperties.LINE_SEPARATOR; - private String nullString = ""; - private String fileName; - private Reader input; - private char[] inputBuffer; - private int inputBufferPos; - private int inputBufferStart = -1; - private int inputBufferEnd; - private Writer output; - private boolean endOfLine, endOfFile; - - private Csv() { - // don't allow construction - } - - /** - * Get a new object of this class. - * - * @return the new instance - */ - public static Csv getInstance() { - return new Csv(); - } - - private int writeResultSet(ResultSet rs) throws SQLException { - try { - ResultSetMetaData meta = rs.getMetaData(); - int rows = 0; - int columnCount = meta.getColumnCount(); - String[] row = new String[columnCount]; - for (int i = 0; i < columnCount; i++) { - row[i] = meta.getColumnLabel(i + 1); - } - writeRow(row); - while (rs.next()) { - for (int i = 0; i < columnCount; i++) { - row[i] = rs.getString(i + 1); - } - writeRow(row); - rows++; - } - output.close(); - return rows; - } catch (IOException e) { - throw DbException.convertIOException(e, null); - } finally { - close(); - JdbcUtils.closeSilently(rs); - } - } - - /** - * Writes the result set to a file in the CSV format. - * - * @param writer the writer - * @param rs the result set - * @return the number of rows written - * @throws SQLException - */ - public int write(Writer writer, ResultSet rs) throws SQLException { - this.output = writer; - return writeResultSet(rs); - } - - /** - * Writes the result set to a file in the CSV format. The result set is read - * using the following loop: - * - *
-     * while (rs.next()) {
-     *     writeRow(row);
-     * }
-     * 
- * - * @param outputFileName the name of the csv file - * @param rs the result set - the result set must be positioned before the - * first row. - * @param charset the charset or null to use the system default charset - * (see system property file.encoding) - * @return the number of rows written - * @throws SQLException - */ - public int write(String outputFileName, ResultSet rs, String charset) throws SQLException { - init(outputFileName, charset); - try { - initWrite(); - return writeResultSet(rs); - } catch (IOException e) { - throw convertException("IOException writing " + outputFileName, e); - } - } - - /** - * Writes the result set of a query to a file in the CSV format. - * - * @param conn the connection - * @param outputFileName the file name - * @param sql the query - * @param charset the charset or null to use the system default charset - * (see system property file.encoding) - * @return the number of rows written - * @throws SQLException - */ - public int write(Connection conn, String outputFileName, String sql, String charset) throws SQLException { - Statement stat = conn.createStatement(); - ResultSet rs = stat.executeQuery(sql); - int rows = write(outputFileName, rs, charset); - stat.close(); - return rows; - } - - /** - * Reads from the CSV file and returns a result set. The rows in the result - * set are created on demand, that means the file is kept open until all - * rows are read or the result set is closed. - *
- * If the columns are read from the CSV file, then the following rules are - * used: columns names that start with a letter or '_', and only - * contain letters, '_', and digits, are considered case insensitive - * and are converted to uppercase. Other column names are considered - * case sensitive (that means they need to be quoted when accessed). - * - * @param inputFileName the file name - * @param colNames or null if the column names should be read from the CSV - * file - * @param charset the charset or null to use the system default charset - * (see system property file.encoding) - * @return the result set - * @throws SQLException - */ - public ResultSet read(String inputFileName, String[] colNames, String charset) throws SQLException { - init(inputFileName, charset); - try { - return readResultSet(colNames); - } catch (IOException e) { - throw convertException("IOException reading " + inputFileName, e); - } - } - - /** - * Reads CSV data from a reader and returns a result set. The rows in the - * result set are created on demand, that means the reader is kept open - * until all rows are read or the result set is closed. - * - * @param reader the reader - * @param colNames or null if the column names should be read from the CSV file - * @return the result set - * @throws SQLException, IOException - */ - public ResultSet read(Reader reader, String[] colNames) throws IOException { - init(null, null); - this.input = reader; - return readResultSet(colNames); - } - - private ResultSet readResultSet(String[] colNames) throws IOException { - this.columnNames = colNames; - initRead(); - SimpleResultSet result = new SimpleResultSet(this); - makeColumnNamesUnique(); - for (String columnName : columnNames) { - result.addColumn(columnName, Types.VARCHAR, Integer.MAX_VALUE, 0); - } - return result; - } - - private void makeColumnNamesUnique() { - for (int i = 0; i < columnNames.length; i++) { - String x = columnNames[i]; - if (x == null || x.length() == 0) { - x = "C" + (i + 1); - } - for (int j = 0; j < i; j++) { - String y = columnNames[j]; - if (x.equals(y)) { - x += "1"; - j = -1; - } - } - columnNames[i] = x; - } - } - - private void init(String newFileName, String charset) { - this.fileName = newFileName; - if (charset != null) { - this.streamCharset = charset; - } - } - - private void initWrite() throws IOException { - if (output == null) { - try { - OutputStream out = IOUtils.openFileOutputStream(fileName, false); - out = new BufferedOutputStream(out, Constants.IO_BUFFER_SIZE); - output = new BufferedWriter(new OutputStreamWriter(out, streamCharset)); - } catch (Exception e) { - close(); - throw DbException.convertToIOException(e); - } - } - } - - private void writeRow(String[] values) throws IOException { - for (int i = 0; i < values.length; i++) { - if (i > 0) { - if (fieldSeparatorWrite != null) { - output.write(fieldSeparatorWrite); - } - } - String s = values[i]; - if (s != null) { - if (escapeCharacter != 0) { - if (fieldDelimiter != 0) { - output.write(fieldDelimiter); - } - output.write(escape(s)); - if (fieldDelimiter != 0) { - output.write(fieldDelimiter); - } - } else { - output.write(s); - } - } else if (nullString != null && nullString.length() > 0) { - output.write(nullString); - } - } - if (rowSeparatorWrite != null) { - output.write(rowSeparatorWrite); - } - output.write(lineSeparator); - } - - private String escape(String data) { - if (data.indexOf(fieldDelimiter) < 0) { - if (escapeCharacter == fieldDelimiter || data.indexOf(escapeCharacter) < 0) { - return data; - } - } - StringBuilder buff = new StringBuilder(data.length()); - for (int i = 0; i < data.length(); i++) { - char ch = data.charAt(i); - if (ch == fieldDelimiter || ch == escapeCharacter) { - buff.append(escapeCharacter); - } - buff.append(ch); - } - return buff.toString(); - } - - private void initRead() throws IOException { - if (input == null) { - try { - InputStream in = IOUtils.openFileInputStream(fileName); - in = new BufferedInputStream(in, Constants.IO_BUFFER_SIZE); - input = new InputStreamReader(in, streamCharset); - } catch (IOException e) { - close(); - throw e; - } - } - if (!input.markSupported()) { - input = new BufferedReader(input); - } - input.mark(1); - int bom = input.read(); - if (bom != 0xfeff) { - // Microsoft Excel compatibility - // ignore pseudo-BOM - input.reset(); - } - inputBuffer = new char[Constants.IO_BUFFER_SIZE * 2]; - if (columnNames == null) { - readHeader(); - } - } - - private void readHeader() throws IOException { - ArrayList list = New.arrayList(); - while (true) { - String v = readValue(); - if (v == null) { - if (endOfLine) { - if (endOfFile || list.size() > 0) { - break; - } - } else { - v = "COLUMN" + list.size(); - list.add(v); - } - } else { - if (v.length() == 0) { - v = "COLUMN" + list.size(); - } else if (isSimpleColumnName(v)) { - v = v.toUpperCase(); - } - list.add(v); - if (endOfLine) { - break; - } - } - } - columnNames = new String[list.size()]; - list.toArray(columnNames); - } - - private boolean isSimpleColumnName(String columnName) { - for (int i = 0; i < columnName.length(); i++) { - char ch = columnName.charAt(i); - if (i == 0) { - if (ch != '_' && !Character.isLetter(ch)) { - return false; - } - } else { - if (ch != '_' && !Character.isLetterOrDigit(ch)) { - return false; - } - } - } - if (columnName.length() == 0) { - return false; - } - return true; - } - - private void pushBack() { - inputBufferPos--; - } - - private int readChar() throws IOException { - if (inputBufferPos >= inputBufferEnd) { - return readBuffer(); - } - return inputBuffer[inputBufferPos++]; - } - - private int readBuffer() throws IOException { - if (endOfFile) { - return -1; - } - int keep; - if (inputBufferStart >= 0) { - keep = inputBufferPos - inputBufferStart; - if (keep > 0) { - char[] src = inputBuffer; - if (keep + Constants.IO_BUFFER_SIZE > src.length) { - inputBuffer = new char[src.length * 2]; - } - System.arraycopy(src, inputBufferStart, inputBuffer, 0, keep); - } - inputBufferStart = 0; - } else { - keep = 0; - } - inputBufferPos = keep; - int len = input.read(inputBuffer, keep, Constants.IO_BUFFER_SIZE); - if (len == -1) { - // ensure bufferPos > bufferEnd - // even after pushBack - inputBufferEnd = -1024; - endOfFile = true; - // ensure the right number of characters are read - // in case the input buffer is still used - inputBufferPos++; - return -1; - } - inputBufferEnd = keep + len; - return inputBuffer[inputBufferPos++]; - } - - private String readValue() throws IOException { - endOfLine = false; - inputBufferStart = inputBufferPos; - while (true) { - int ch = readChar(); - if (ch == fieldDelimiter) { - // delimited value - boolean containsEscape = false; - inputBufferStart = inputBufferPos; - int sep; - while (true) { - ch = readChar(); - if (ch == fieldDelimiter) { - ch = readChar(); - if (ch != fieldDelimiter) { - sep = 2; - break; - } - containsEscape = true; - } else if (ch == escapeCharacter) { - ch = readChar(); - if (ch < 0) { - sep = 1; - break; - } - containsEscape = true; - } else if (ch < 0) { - sep = 1; - break; - } - } - String s = new String(inputBuffer, inputBufferStart, inputBufferPos - inputBufferStart - sep); - if (containsEscape) { - s = unEscape(s); - } - inputBufferStart = -1; - while (true) { - if (ch == fieldSeparatorRead) { - break; - } else if (ch == '\n' || ch < 0 || ch == '\r') { - endOfLine = true; - break; - } else if (ch == ' ' || ch == '\t') { - // ignore - } else { - pushBack(); - break; - } - ch = readChar(); - } - return s; - } else if (ch == '\n' || ch < 0 || ch == '\r') { - endOfLine = true; - return null; - } else if (ch == fieldSeparatorRead) { - // null - return null; - } else if (ch <= ' ') { - // ignore spaces - continue; - } else if (ch == commentLineStart) { - // comment until end of line - inputBufferStart = -1; - while (true) { - ch = readChar(); - if (ch == '\n' || ch < 0 || ch == '\r') { - break; - } - } - endOfLine = true; - return null; - } else { - // un-delimited value - while (true) { - ch = readChar(); - if (ch == fieldSeparatorRead) { - break; - } else if (ch == '\n' || ch < 0 || ch == '\r') { - endOfLine = true; - break; - } - } - String s = new String(inputBuffer, inputBufferStart, inputBufferPos - inputBufferStart - 1); - inputBufferStart = -1; - // check un-delimited value for nullString - return readNull(s.trim()); - } - } - } - - private String readNull(String s) { - return s.equals(nullString) ? null : s; - } - - private String unEscape(String s) { - StringBuilder buff = new StringBuilder(s.length()); - int start = 0; - char[] chars = null; - while (true) { - int idx = s.indexOf(escapeCharacter, start); - if (idx < 0) { - idx = s.indexOf(fieldDelimiter, start); - if (idx < 0) { - break; - } - } - if (chars == null) { - chars = s.toCharArray(); - } - buff.append(chars, start, idx - start); - if (idx == s.length() - 1) { - start = s.length(); - break; - } - buff.append(chars[idx + 1]); - start = idx + 2; - } - buff.append(s.substring(start)); - return buff.toString(); - } - - /** - * INTERNAL - */ - public Object[] readRow() throws SQLException { - if (input == null) { - return null; - } - String[] row = new String[columnNames.length]; - try { - int i = 0; - while (true) { - String v = readValue(); - if (v == null) { - if (endOfLine) { - if (i == 0) { - if (endOfFile) { - return null; - } - // empty line - continue; - } - break; - } - } - if (i < row.length) { - row[i++] = v; - } - if (endOfLine) { - break; - } - } - } catch (IOException e) { - throw convertException("IOException reading from " + fileName, e); - } - return row; - } - - private SQLException convertException(String message, Exception e) { - return DbException.get(ErrorCode.IO_EXCEPTION_1, e, message).getSQLException(); -// SQLException s = new SQLException(message, "CSV"); -// //## Java 1.4 begin ## -// s.initCause(e); -// //## Java 1.4 end ## -// return s; - } - - /** - * INTERNAL - */ - public void close() { - IOUtils.closeSilently(input); - input = null; - IOUtils.closeSilently(output); - output = null; - } - - /** - * INTERNAL - */ - public void reset() throws SQLException { - throw new SQLException("Method is not supported", "CSV"); - } - - /** - * Override the field separator for writing. The default is ",". - * - * @param fieldSeparatorWrite the field separator - */ - public void setFieldSeparatorWrite(String fieldSeparatorWrite) { - this.fieldSeparatorWrite = fieldSeparatorWrite; - } - - /** - * Get the current field separator for writing. - * - * @return the field separator - */ - public String getFieldSeparatorWrite() { - return fieldSeparatorWrite; - } - - /** - * Override the field separator for reading. The default is ','. - * - * @param fieldSeparatorRead the field separator - */ - public void setFieldSeparatorRead(char fieldSeparatorRead) { - this.fieldSeparatorRead = fieldSeparatorRead; - } - - /** - * Get the current field separator for reading. - * - * @return the field separator - */ - public char getFieldSeparatorRead() { - return fieldSeparatorRead; - } - - /** - * Get the current row separator for writing. - * - * @return the row separator - */ - public String getRowSeparatorWrite() { - return rowSeparatorWrite; - } - - /** - * Override the end-of-row marker for writing. The default is null. After - * writing the end-of-row marker, a line feed is written (\n or \r\n - * depending on the system settings). - * - * @param rowSeparatorWrite the row separator - */ - public void setRowSeparatorWrite(String rowSeparatorWrite) { - this.rowSeparatorWrite = rowSeparatorWrite; - } - - /** - * Set the field delimiter. The default is " (a double quote). - * The value 0 means no field delimiter is used. - * - * @param fieldDelimiter the field delimiter - */ - public void setFieldDelimiter(char fieldDelimiter) { - this.fieldDelimiter = fieldDelimiter; - } - - /** - * Get the current field delimiter. - * - * @return the field delimiter - */ - public char getFieldDelimiter() { - return fieldDelimiter; - } - - /** - * Set the escape character (used to escape the field delimiter). The - * default is " (a double quote). The value 0 means no escape character is used. - * - * @param escapeCharacter the escape character - */ - public void setEscapeCharacter(char escapeCharacter) { - this.escapeCharacter = escapeCharacter; - } - - /** - * Get the current escape character. - * - * @return the escape character - */ - public char getEscapeCharacter() { - return escapeCharacter; - } - - /** - * Set the line separator. - * - * @param lineSeparator the line separator - */ - public void setLineSeparator(String lineSeparator) { - this.lineSeparator = lineSeparator; - } - - /** - * Set the value that represents NULL. - * - * @param nullString the null - */ - public void setNullString(String nullString) { - this.nullString = nullString; - } - - /** - * Get the current null string. - * - * @return the null string. - */ - public String getNullString() { - return nullString; - } - -} diff --git a/tools/h2/src/main/org/h2/tools/DeleteDbFiles.java b/tools/h2/src/main/org/h2/tools/DeleteDbFiles.java deleted file mode 100755 index fe50f4a..0000000 --- a/tools/h2/src/main/org/h2/tools/DeleteDbFiles.java +++ /dev/null @@ -1,112 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.tools; - -import java.sql.SQLException; -import java.util.ArrayList; - -import org.h2.engine.Constants; -import org.h2.store.FileLister; -import org.h2.util.IOUtils; -import org.h2.util.Tool; - -/** - * Deletes all files belonging to a database. - *
- * The database must be closed before calling this tool. - * @h2.resource - */ -public class DeleteDbFiles extends Tool { - - /** - * Options are case sensitive. Supported options are: - * - * - * - * - * - * - * - * - * - *
[-help] or [-?]Print the list of options
[-dir <dir>]The directory (default: .)
[-db <database>]The database name
[-quiet]Do not print progress information
- * @h2.resource - * - * @param args the command line arguments - */ - public static void main(String... args) throws SQLException { - new DeleteDbFiles().runTool(args); - } - - public void runTool(String... args) throws SQLException { - String dir = "."; - String db = null; - boolean quiet = false; - for (int i = 0; args != null && i < args.length; i++) { - String arg = args[i]; - if (arg.equals("-dir")) { - dir = args[++i]; - } else if (arg.equals("-db")) { - db = args[++i]; - } else if (arg.equals("-quiet")) { - quiet = true; - } else if (arg.equals("-help") || arg.equals("-?")) { - showUsage(); - return; - } else { - throwUnsupportedOption(arg); - } - } - process(dir, db, quiet); - } - - /** - * Deletes the database files. - * - * @param dir the directory - * @param db the database name (null for all databases) - * @param quiet don't print progress information - * @throws SQLException - */ - public static void execute(String dir, String db, boolean quiet) throws SQLException { - new DeleteDbFiles().process(dir, db, quiet); - } - - /** - * Deletes the database files. - * - * @param dir the directory - * @param db the database name (null for all databases) - * @param quiet don't print progress information - * @throws SQLException - */ - private void process(String dir, String db, boolean quiet) throws SQLException { - DeleteDbFiles delete = new DeleteDbFiles(); - ArrayList files = FileLister.getDatabaseFiles(dir, db, true); - if (files.size() == 0 && !quiet) { - printNoDatabaseFilesFound(dir, db); - } - for (String fileName : files) { - delete.process(fileName, quiet); - if (!quiet) { - out.println("Processed: " + fileName); - } - } - } - - private void process(String fileName, boolean quiet) { - if (IOUtils.isDirectory(fileName)) { - // only delete empty directories - IOUtils.tryDelete(fileName); - } else if (quiet || fileName.endsWith(Constants.SUFFIX_TEMP_FILE) || fileName.endsWith(Constants.SUFFIX_TRACE_FILE)) { - IOUtils.tryDelete(fileName); - } else { - IOUtils.delete(fileName); - } - } - -} diff --git a/tools/h2/src/main/org/h2/tools/MultiDimension.java b/tools/h2/src/main/org/h2/tools/MultiDimension.java deleted file mode 100755 index 67e5c09..0000000 --- a/tools/h2/src/main/org/h2/tools/MultiDimension.java +++ /dev/null @@ -1,288 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.tools; - -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.util.ArrayList; -import java.util.Collections; -import java.util.Comparator; -import org.h2.util.New; -import org.h2.util.StringUtils; - -/** - * A tool to help an application execute multi-dimensional range queries. - * The algorithm used is database independent, the only requirement - * is that the engine supports a range index (for example b-tree). - */ -public class MultiDimension implements Comparator { - - private static final MultiDimension INSTANCE = new MultiDimension(); - - private MultiDimension() { - // don't allow construction - } - - /** - * Get the singleton. - * - * @return the singleton - */ - public static MultiDimension getInstance() { - return INSTANCE; - } - - /** - * Convert the multi-dimensional value into a one-dimensional (scalar) value. - * This is done by interleaving the bits of the values. - * Each values must be bigger or equal to 0. The maximum value - * is dependent on the number of dimensions. For two keys, it is 32 bit, - * for 3: 21 bit, 4: 16 bit, 5: 12 bit, 6: 10 bit, 7: 9 bit, 8: 8 bit. - * - * @param values the multi-dimensional value - * @return the scalar value - */ - public long interleave(int[] values) { - int dimensions = values.length; - int bitsPerValue = 64 / dimensions; - // for 2 keys: 0x800000; 3: 0x - long max = 1L << bitsPerValue; - long x = 0; - for (int i = 0; i < dimensions; i++) { - long k = values[i]; - if (k < 0 || k > max) { - throw new IllegalArgumentException("value out of range; value=" + values[i] + " min=0 max=" + max); - } - for (int b = 0; b < bitsPerValue; b++) { - x |= (k & (1L << b)) << (i + (dimensions - 1) * b); - } - } - if (dimensions == 2) { - long xx = getMorton2(values[0], values[1]); - if (xx != x) { - throw new IllegalArgumentException("test"); - } - } - return x; - } - - /** - * Gets one of the original multi-dimensional values from a scalar value. - * - * @param scalar the scalar value - * @param dimensions the number of dimensions - * @param dim the dimension of the returned value (starting from 0) - * @return the value - */ - public int deinterleave(long scalar, int dimensions, int dim) { - int bitsPerValue = 64 / dimensions; - int value = 0; - for (int i = 0; i < bitsPerValue; i++) { - value |= (scalar >> (dim + (dimensions - 1) * i)) & (1L << i); - } - return value; - } - - -// public static int get(long z, int d) { -// int n = 0; -// for (int i = 0; i < 31; i++) { -// n |= (z & (1 << (i + i + d))) >> (i + d); -// } -// return n; -// } - - /** - * Generates an optimized multi-dimensional range query. - * The query contains parameters. It can only be used with the H2 database. - * - * @param table the table name - * @param columns the list of columns - * @param scalarColumn the column name of the computed scalar column - * @return the query - */ - public String generatePreparedQuery(String table, String scalarColumn, String[] columns) { - StringBuilder buff = new StringBuilder("SELECT D.* FROM "); - buff.append(StringUtils.quoteIdentifier(table)). - append(" D, TABLE(_FROM_ BIGINT=?, _TO_ BIGINT=?) WHERE "). - append(StringUtils.quoteIdentifier(scalarColumn)). - append(" BETWEEN _FROM_ AND _TO_"); - for (String col : columns) { - buff.append(" AND ").append(StringUtils.quoteIdentifier(col)).append("+1 BETWEEN ?+1 AND ?+1"); - } - return buff.toString(); - } - - /** - * Executes a prepared query that was generated using generatePreparedQuery. - * - * @param prep the prepared statement - * @param min the lower values - * @param max the upper values - * @return the result set - */ - public ResultSet getResult(PreparedStatement prep, int[] min, int[] max) throws SQLException { - long[][] ranges = getMortonRanges(min, max); - int len = ranges.length; - Long[] from = new Long[len]; - Long[] to = new Long[len]; - for (int i = 0; i < len; i++) { - from[i] = Long.valueOf(ranges[i][0]); - to[i] = Long.valueOf(ranges[i][1]); - } - prep.setObject(1, from); - prep.setObject(2, to); - len = min.length; - for (int i = 0, idx = 3; i < len; i++) { - prep.setInt(idx++, min[i]); - prep.setInt(idx++, max[i]); - } - return prep.executeQuery(); - } - - /** - * Gets a list of ranges to be searched for a multi-dimensional range query - * where min <= value <= max. In most cases, the ranges will be larger - * than required in order to combine smaller ranges into one. Usually, about - * double as much points will be included in the resulting range. - * - * @param min the minimum value - * @param max the maximum value - * @return the list of ranges - */ - private long[][] getMortonRanges(int[] min, int[] max) { - int len = min.length; - if (max.length != len) { - throw new IllegalArgumentException("dimensions mismatch"); - } - for (int i = 0; i < len; i++) { - if (min[i] > max[i]) { - int temp = min[i]; - min[i] = max[i]; - max[i] = temp; - } - } - int total = getSize(min, max, len); - ArrayList list = New.arrayList(); - addMortonRanges(list, min, max, len, 0); - optimize(list, total); - long[][] ranges = new long[list.size()][2]; - list.toArray(ranges); - return ranges; - } - - private long getMorton2(int x, int y) { - long z = 0; - for (int i = 0; i < 32; i++) { - z |= (x & (1L << i)) << i; - z |= (y & (1L << i)) << (i + 1); - } - return z; - } - - private int getSize(int[] min, int[] max, int len) { - int size = 1; - for (int i = 0; i < len; i++) { - int diff = max[i] - min[i]; - size *= diff + 1; - } - return size; - } - - private void optimize(ArrayList list, int total) { - Collections.sort(list, this); - for (int minGap = 10;; minGap += minGap / 2) { - for (int i = 0; i < list.size() - 1; i++) { - long[] current = list.get(i); - long[] next = list.get(i + 1); - if (current[1] + minGap >= next[0]) { - current[1] = next[1]; - list.remove(i + 1); - i--; - } - } - int searched = 0; - for (long[] range : list) { - searched += range[1] - range[0] + 1; - } - if (searched > 2 * total || list.size() < 3 /* || minGap > total */) { - break; - } - } - } - - public int compare(long[] a, long[] b) { - return a[0] > b[0] ? 1 : -1; - } - - private void addMortonRanges(ArrayList list, int[] min, int[] max, int len, int level) { - if (level > 100) { - throw new IllegalArgumentException("Stop"); - } - int largest = 0, largestDiff = 0; - long size = 1; - for (int i = 0; i < len; i++) { - int diff = max[i] - min[i]; - if (diff < 0) { - throw new IllegalArgumentException("Stop"); - } - size *= diff + 1; - if (size < 0) { - throw new IllegalArgumentException("Stop"); - } - if (diff > largestDiff) { - largestDiff = diff; - largest = i; - } - } - long low = interleave(min), high = interleave(max); - if (high < low) { - throw new IllegalArgumentException("Stop"); - } - long range = high - low + 1; - if (range == size) { - long[] item = { low, high }; - list.add(item); - } else { - int middle = findMiddle(min[largest], max[largest]); - int temp = max[largest]; - max[largest] = middle; - addMortonRanges(list, min, max, len, level + 1); - max[largest] = temp; - temp = min[largest]; - min[largest] = middle + 1; - addMortonRanges(list, min, max, len, level + 1); - min[largest] = temp; - } - } - - private int roundUp(int x, int blockSizePowerOf2) { - return (x + blockSizePowerOf2 - 1) & (-blockSizePowerOf2); - } - - private int findMiddle(int a, int b) { - int diff = b - a - 1; - if (diff == 0) { - return a; - } - if (diff == 1) { - return a + 1; - } - int scale = 0; - while ((1 << scale) < diff) { - scale++; - } - scale--; - int m = roundUp(a + 2, 1 << scale) - 1; - if (m <= a || m >= b) { - throw new IllegalArgumentException("stop"); - } - return m; - } - -} diff --git a/tools/h2/src/main/org/h2/tools/Recover.java b/tools/h2/src/main/org/h2/tools/Recover.java deleted file mode 100755 index b2c0acb..0000000 --- a/tools/h2/src/main/org/h2/tools/Recover.java +++ /dev/null @@ -1,1321 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.tools; - -import java.io.BufferedInputStream; -import java.io.BufferedReader; -import java.io.EOFException; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.io.OutputStream; -import java.io.PrintWriter; -import java.io.Reader; -import java.sql.Connection; -import java.sql.SQLException; -import java.util.ArrayList; -import java.util.BitSet; -import java.util.Collections; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Map; -import java.util.zip.CRC32; -import org.h2.compress.CompressLZF; -import org.h2.constant.SysProperties; -import org.h2.engine.Constants; -import org.h2.engine.DbObject; -import org.h2.engine.MetaRecord; -import org.h2.jdbc.JdbcConnection; -import org.h2.message.DbException; -import org.h2.result.Row; -import org.h2.result.SimpleRow; -import org.h2.security.SHA256; -import org.h2.store.Data; -import org.h2.store.DataHandler; -import org.h2.store.DataReader; -import org.h2.store.FileLister; -import org.h2.store.FileStore; -import org.h2.store.FileStoreInputStream; -import org.h2.store.LobStorage; -import org.h2.store.Page; -import org.h2.store.PageFreeList; -import org.h2.store.PageLog; -import org.h2.store.PageStore; -import org.h2.util.IOUtils; -import org.h2.util.IntArray; -import org.h2.util.MathUtils; -import org.h2.util.New; -import org.h2.util.SmallLRUCache; -import org.h2.util.StatementBuilder; -import org.h2.util.TempFileDeleter; -import org.h2.util.Tool; -import org.h2.util.Utils; -import org.h2.value.Value; -import org.h2.value.ValueLob; -import org.h2.value.ValueLobDb; -import org.h2.value.ValueLong; - -/** - * Helps recovering a corrupted database. - * @h2.resource - */ -public class Recover extends Tool implements DataHandler { - - private String databaseName; - private int block; - private int storageId; - private String storageName; - private int recordLength; - private int valueId; - private boolean trace; - private ArrayList schema; - private HashSet objectIdSet; - private HashMap tableMap; - private HashMap columnTypeMap; - private boolean remove; - - private int pageSize; - private FileStore store; - private int[] parents; - - private Stats stat; - - /** - * Statistic data - */ - class Stats { - - /** - * The empty space in bytes in a data leaf pages. - */ - long pageDataEmpty; - - /** - * The number of bytes used for data. - */ - int pageDataRows; - - /** - * The number of bytes used for the page headers. - */ - int pageDataHead; - - /** - * The count per page type. - */ - int[] pageTypeCount = new int[Page.TYPE_STREAM_DATA + 2]; - - /** - * The number of free pages. - */ - int free; - } - - /** - * Options are case sensitive. Supported options are: - * - * - * - * - * - * - * - * - * - *
[-help] or [-?]Print the list of options
[-dir <dir>]The directory (default: .)
[-db <database>]The database name (all databases if not set)
[-trace]Print additional trace information
- * Encrypted databases need to be decrypted first. - * @h2.resource - * - * @param args the command line arguments - */ - public static void main(String... args) throws SQLException { - new Recover().runTool(args); - } - - /** - * Dumps the contents of a database file to a human readable text file. This - * text file can be used to recover most of the data. This tool does not - * open the database and can be used even if the database files are - * corrupted. A database can get corrupted if there is a bug in the database - * engine or file system software, or if an application writes into the - * database file that doesn't understand the the file format, or if there is - * a hardware problem. - * - * @param args the command line arguments - */ - public void runTool(String... args) throws SQLException { - String dir = "."; - String db = null; - for (int i = 0; args != null && i < args.length; i++) { - String arg = args[i]; - if ("-dir".equals(arg)) { - dir = args[++i]; - } else if ("-db".equals(arg)) { - db = args[++i]; - } else if ("-removePassword".equals(arg)) { - remove = true; - } else if ("-trace".equals(arg)) { - trace = true; - } else if (arg.equals("-help") || arg.equals("-?")) { - showUsage(); - return; - } else { - throwUnsupportedOption(arg); - } - } - process(dir, db); - } - - /** - * INTERNAL - */ - public static Reader readClob(String fileName) throws IOException { - return new BufferedReader(new InputStreamReader(readBlob(fileName), "UTF-8")); - } - - /** - * INTERNAL - */ - public static InputStream readBlob(String fileName) throws IOException { - return new BufferedInputStream(IOUtils.openFileInputStream(fileName)); - } - - /** - * INTERNAL - */ - public static Value.ValueBlob readBlobDb(Connection conn, long lobId, long precision) { - DataHandler h = ((JdbcConnection) conn).getSession().getDataHandler(); - LobStorage lobStorage = h.getLobStorage(); - return ValueLobDb.create(Value.BLOB, lobStorage, null, LobStorage.TABLE_TEMP, lobId, precision); - } - - /** - * INTERNAL - */ - public static Value.ValueClob readClobDb(Connection conn, long lobId, long precision) { - DataHandler h = ((JdbcConnection) conn).getSession().getDataHandler(); - LobStorage lobStorage = h.getLobStorage(); - return ValueLobDb.create(Value.CLOB, lobStorage, null, LobStorage.TABLE_TEMP, lobId, precision); - } - - private void trace(String message) { - if (trace) { - out.println(message); - } - } - - private void traceError(String message, Throwable t) { - out.println(message + ": " + t.toString()); - if (trace) { - t.printStackTrace(out); - } - } - - /** - * Dumps the contents of a database to a SQL script file. - * - * @param dir the directory - * @param db the database name (null for all databases) - */ - public static void execute(String dir, String db) throws SQLException { - try { - new Recover().process(dir, db); - } catch (DbException e) { - throw DbException.toSQLException(e); - } - } - - private void process(String dir, String db) { - ArrayList list = FileLister.getDatabaseFiles(dir, db, true); - if (list.size() == 0) { - printNoDatabaseFilesFound(dir, db); - } - for (String fileName : list) { - if (fileName.endsWith(Constants.SUFFIX_PAGE_FILE)) { - dumpPageStore(fileName); - } else if (fileName.endsWith(Constants.SUFFIX_LOB_FILE)) { - dumpLob(fileName, true); - dumpLob(fileName, false); - } - } - } - - private PrintWriter getWriter(String fileName, String suffix) { - fileName = fileName.substring(0, fileName.length() - 3); - String outputFile = fileName + suffix; - trace("Created file: " + outputFile); - return new PrintWriter(IOUtils.getWriter(IOUtils.openFileOutputStream(outputFile, false))); - } - - private void writeDataError(PrintWriter writer, String error, byte[] data) { - writer.println("-- ERROR: " + error + " block: " + block + " storageId: " - + storageId + " recordLength: " + recordLength + " valueId: " + valueId); - StringBuilder sb = new StringBuilder(); - for (int i = 0; i < data.length; i++) { - int x = data[i] & 0xff; - if (x >= ' ' && x < 128) { - sb.append((char) x); - } else { - sb.append('?'); - } - } - writer.println("-- dump: " + sb.toString()); - sb = new StringBuilder(); - for (int i = 0; i < data.length; i++) { - int x = data[i] & 0xff; - sb.append(' '); - if (x < 16) { - sb.append('0'); - } - sb.append(Integer.toHexString(x)); - } - writer.println("-- dump: " + sb.toString()); - } - - private void dumpLob(String fileName, boolean lobCompression) { - OutputStream fileOut = null; - FileStore fileStore = null; - int size = 0; - String n = fileName + (lobCompression ? ".comp" : "") + ".txt"; - InputStream in = null; - try { - fileOut = IOUtils.openFileOutputStream(n, false); - fileStore = FileStore.open(null, fileName, "r"); - fileStore.init(); - in = new BufferedInputStream(new FileStoreInputStream(fileStore, this, lobCompression, false)); - byte[] buffer = new byte[Constants.IO_BUFFER_SIZE]; - while (true) { - int l = in.read(buffer); - if (l < 0) { - break; - } - fileOut.write(buffer, 0, l); - size += l; - } - fileOut.close(); - } catch (Throwable e) { - // this is usually not a problem, because we try both compressed and - // uncompressed - } finally { - IOUtils.closeSilently(fileOut); - IOUtils.closeSilently(in); - closeSilently(fileStore); - } - if (size == 0) { - try { - IOUtils.delete(n); - } catch (Exception e) { - traceError(n, e); - } - } - } - - private String getSQL(String column, Value v) { - if (v instanceof ValueLob) { - ValueLob lob = (ValueLob) v; - byte[] small = lob.getSmall(); - if (small == null) { - String file = lob.getFileName(); - if (lob.getType() == Value.BLOB) { - return "READ_BLOB('" + file + ".txt')"; - } - return "READ_CLOB('" + file + ".txt')"; - } - } else if (v instanceof ValueLobDb) { - ValueLobDb lob = (ValueLobDb) v; - byte[] small = lob.getSmall(); - if (small == null) { - int type = lob.getType(); - long id = lob.getLobId(); - long precision = lob.getPrecision(); - String m; - String columnType; - if (type == Value.BLOB) { - columnType = "BLOB"; - m = "READ_BLOB_DB"; - } else { - columnType = "CLOB"; - m = "READ_CLOB_DB"; - } - columnTypeMap.put(column, columnType); - return m + "(" + id + ", " + precision + ")"; - } - } - return v.getSQL(); - } - - private void setDatabaseName(String name) { - databaseName = name; - } - - private void dumpPageStore(String fileName) { - setDatabaseName(fileName.substring(0, fileName.length() - Constants.SUFFIX_PAGE_FILE.length())); - PrintWriter writer = null; - stat = new Stats(); - try { - writer = getWriter(fileName, ".sql"); - writer.println("CREATE ALIAS IF NOT EXISTS READ_BLOB FOR \"" + this.getClass().getName() + ".readBlob\";"); - writer.println("CREATE ALIAS IF NOT EXISTS READ_CLOB FOR \"" + this.getClass().getName() + ".readClob\";"); - writer.println("CREATE ALIAS IF NOT EXISTS READ_BLOB_DB FOR \"" + this.getClass().getName() + ".readBlobDb\";"); - writer.println("CREATE ALIAS IF NOT EXISTS READ_CLOB_DB FOR \"" + this.getClass().getName() + ".readClobDb\";"); - resetSchema(); - store = FileStore.open(null, fileName, remove ? "rw" : "r"); - long length = store.length(); - try { - store.init(); - } catch (Exception e) { - writeError(writer, e); - } - Data s = Data.create(this, 128); - store.seek(0); - store.readFully(s.getBytes(), 0, 128); - s.setPos(48); - pageSize = s.readInt(); - int writeVersion = s.readByte(); - int readVersion = s.readByte(); - writer.println("-- pageSize: " + pageSize + - " writeVersion: " + writeVersion + - " readVersion: " + readVersion); - if (pageSize < PageStore.PAGE_SIZE_MIN || pageSize > PageStore.PAGE_SIZE_MAX) { - pageSize = SysProperties.PAGE_SIZE; - writer.println("-- ERROR: page size; using " + pageSize); - } - int pageCount = (int) (length / pageSize); - parents = new int[pageCount]; - s = Data.create(this, pageSize); - for (int i = 3; i < pageCount; i++) { - s.reset(); - store.seek(i * pageSize); - store.readFully(s.getBytes(), 0, 32); - s.readByte(); - s.readShortInt(); - parents[i] = s.readInt(); - } - int logKey = 0, logFirstTrunkPage = 0, logFirstDataPage = 0; - s = Data.create(this, pageSize); - for (int i = 1;; i++) { - if (i == 3) { - break; - } - s.reset(); - store.seek(i * pageSize); - store.readFully(s.getBytes(), 0, pageSize); - CRC32 crc = new CRC32(); - crc.update(s.getBytes(), 4, pageSize - 4); - int expected = (int) crc.getValue(); - int got = s.readInt(); - long writeCounter = s.readLong(); - int key = s.readInt(); - int firstTrunkPage = s.readInt(); - int firstDataPage = s.readInt(); - if (expected == got) { - logKey = key; - logFirstTrunkPage = firstTrunkPage; - logFirstDataPage = firstDataPage; - } - writer.println("-- head " + i + - ": writeCounter: " + writeCounter + - " log key: " + key + " trunk: " + firstTrunkPage + "/" + firstDataPage + - " crc expected " + expected + - " got " + got + " (" + (expected == got ? "ok" : "different") + ")"); - } - writer.println("-- firstTrunkPage: " + logFirstTrunkPage + - " firstDataPage: " + logFirstDataPage); - - PrintWriter devNull = new PrintWriter(new OutputStream() { - public void write(int b) { - // ignore - } - }); - dumpPageStore(devNull, pageCount); - stat = new Stats(); - schema.clear(); - objectIdSet = New.hashSet(); - dumpPageStore(writer, pageCount); - writeSchema(writer); - try { - dumpPageLogStream(writer, logKey, logFirstTrunkPage, logFirstDataPage); - } catch (EOFException e) { - // ignore - } - writer.println("---- Statistics ----------"); - writer.println("-- page count: " + pageCount + " free: " + stat.free); - writer.println("-- page data head: " + stat.pageDataHead + " empty: " + stat.pageDataEmpty + " rows: " + stat.pageDataRows); - for (int i = 0; i < stat.pageTypeCount.length; i++) { - int count = stat.pageTypeCount[i]; - if (count > 0) { - writer.println("-- page count type: " + i + " " + (100 * count / pageCount) + "% count: " + count); - } - } - - writer.close(); - } catch (Throwable e) { - writeError(writer, e); - } finally { - IOUtils.closeSilently(writer); - closeSilently(store); - } - } - - private void dumpPageStore(PrintWriter writer, int pageCount) { - Data s = Data.create(this, pageSize); - for (int page = 3; page < pageCount; page++) { - s = Data.create(this, pageSize); - store.seek(page * pageSize); - store.readFully(s.getBytes(), 0, pageSize); - int type = s.readByte(); - switch (type) { - case Page.TYPE_EMPTY: - stat.pageTypeCount[type]++; - continue; - } - boolean last = (type & Page.FLAG_LAST) != 0; - type &= ~Page.FLAG_LAST; - if (!PageStore.checksumTest(s.getBytes(), page, pageSize)) { - writer.println("-- ERROR: page " + page + " checksum mismatch type: " + type); - } - s.readShortInt(); - switch (type) { - // type 1 - case Page.TYPE_DATA_LEAF: { - stat.pageTypeCount[type]++; - int parentPageId = s.readInt(); - setStorage(s.readVarInt()); - int columnCount = s.readVarInt(); - int entries = s.readShortInt(); - writer.println("-- page " + page + ": data leaf " + (last ? "(last)" : "") + " parent: " + parentPageId + - " table: " + storageId + " entries: " + entries + " columns: " + columnCount); - dumpPageDataLeaf(writer, s, last, page, columnCount, entries); - break; - } - // type 2 - case Page.TYPE_DATA_NODE: { - stat.pageTypeCount[type]++; - int parentPageId = s.readInt(); - setStorage(s.readVarInt()); - int rowCount = s.readInt(); - int entries = s.readShortInt(); - writer.println("-- page " + page + ": data node " + (last ? "(last)" : "") + " parent: " + parentPageId + - " entries: " + entries + " rowCount: " + rowCount); - dumpPageDataNode(writer, s, page, entries); - break; - } - // type 3 - case Page.TYPE_DATA_OVERFLOW: - stat.pageTypeCount[type]++; - writer.println("-- page " + page + ": data overflow " + (last ? "(last)" : "")); - break; - // type 4 - case Page.TYPE_BTREE_LEAF: { - stat.pageTypeCount[type]++; - int parentPageId = s.readInt(); - setStorage(s.readVarInt()); - int entries = s.readShortInt(); - writer.println("-- page " + page + ": b-tree leaf " + (last ? "(last)" : "") + " parent: " + parentPageId + - " index: " + storageId + " entries: " + entries); - if (trace) { - dumpPageBtreeLeaf(writer, s, entries, !last); - } - break; - } - // type 5 - case Page.TYPE_BTREE_NODE: - stat.pageTypeCount[type]++; - int parentPageId = s.readInt(); - setStorage(s.readVarInt()); - writer.println("-- page " + page + ": b-tree node" + (last ? "(last)" : "") + " parent: " + parentPageId + - " index: " + storageId); - dumpPageBtreeNode(writer, s, page, !last); - break; - // type 6 - case Page.TYPE_FREE_LIST: - stat.pageTypeCount[type]++; - writer.println("-- page " + page + ": free list " + (last ? "(last)" : "")); - stat.free += dumpPageFreeList(writer, s, page, pageCount); - break; - // type 7 - case Page.TYPE_STREAM_TRUNK: - stat.pageTypeCount[type]++; - writer.println("-- page " + page + ": log trunk"); - break; - // type 8 - case Page.TYPE_STREAM_DATA: - stat.pageTypeCount[type]++; - writer.println("-- page " + page + ": log data"); - break; - default: - writer.println("-- ERROR page " + page + " unknown type " + type); - break; - } - } - } - - private void dumpPageLogStream(PrintWriter writer, int logKey, int logFirstTrunkPage, int logFirstDataPage) throws IOException { - Data s = Data.create(this, pageSize); - DataReader in = new DataReader( - new PageInputStream(writer, this, store, logKey, logFirstTrunkPage, logFirstDataPage, pageSize) - ); - writer.println("---- Transaction log ----------"); - CompressLZF compress = new CompressLZF(); - while (true) { - int x = in.read(); - if (x < 0) { - break; - } - if (x == PageLog.NOOP) { - // ignore - } else if (x == PageLog.UNDO) { - int pageId = in.readVarInt(); - int size = in.readVarInt(); - byte[] data = new byte[pageSize]; - if (size == 0) { - in.readFully(data, 0, pageSize); - } else if (size == 1) { - // empty - } else { - byte[] compressBuffer = new byte[size]; - in.readFully(compressBuffer, 0, size); - compress.expand(compressBuffer, 0, size, data, 0, pageSize); - } - String typeName = ""; - int type = data[0]; - boolean last = (type & Page.FLAG_LAST) != 0; - type &= ~Page.FLAG_LAST; - switch (type) { - case Page.TYPE_EMPTY: - typeName = "empty"; - break; - case Page.TYPE_DATA_LEAF: - typeName = "data leaf " + (last ? "(last)" : ""); - break; - case Page.TYPE_DATA_NODE: - typeName = "data node " + (last ? "(last)" : ""); - break; - case Page.TYPE_DATA_OVERFLOW: - typeName = "data overflow " + (last ? "(last)" : ""); - break; - case Page.TYPE_BTREE_LEAF: - typeName = "b-tree leaf " + (last ? "(last)" : ""); - break; - case Page.TYPE_BTREE_NODE: - typeName = "b-tree node " + (last ? "(last)" : ""); - break; - case Page.TYPE_FREE_LIST: - typeName = "free list " + (last ? "(last)" : ""); - break; - case Page.TYPE_STREAM_TRUNK: - typeName = "log trunk"; - break; - case Page.TYPE_STREAM_DATA: - typeName = "log data"; - break; - default: - typeName = "ERROR: unknown type " + type; - break; - } - writer.println("-- undo page " + pageId + " " + typeName); - } else if (x == PageLog.ADD) { - int sessionId = in.readVarInt(); - setStorage(in.readVarInt()); - Row row = PageLog.readRow(in, s); - writer.println("-- session " + sessionId + - " table " + storageId + - " add " + row.toString()); - } else if (x == PageLog.REMOVE) { - int sessionId = in.readVarInt(); - setStorage(in.readVarInt()); - long key = in.readVarLong(); - writer.println("-- session " + sessionId + - " table " + storageId + - " remove " + key); - } else if (x == PageLog.TRUNCATE) { - int sessionId = in.readVarInt(); - setStorage(in.readVarInt()); - writer.println("-- session " + sessionId + - " table " + storageId + - " truncate"); - } else if (x == PageLog.COMMIT) { - int sessionId = in.readVarInt(); - writer.println("-- commit " + sessionId); - } else if (x == PageLog.ROLLBACK) { - int sessionId = in.readVarInt(); - writer.println("-- rollback " + sessionId); - } else if (x == PageLog.PREPARE_COMMIT) { - int sessionId = in.readVarInt(); - String transaction = in.readString(); - writer.println("-- prepare commit " + sessionId + " " + transaction); - } else if (x == PageLog.NOOP) { - // nothing to do - } else if (x == PageLog.CHECKPOINT) { - writer.println("-- checkpoint"); - } else if (x == PageLog.FREE_LOG) { - int size = in.readVarInt(); - StringBuilder buff = new StringBuilder("-- free"); - for (int i = 0; i < size; i++) { - buff.append(' ').append(in.readVarInt()); - } - writer.println(buff); - } else { - writer.println("-- ERROR: unknown operation " + x); - break; - } - } - } - - private String setStorage(int storageId) { - this.storageId = storageId; - this.storageName = "O_" + String.valueOf(storageId).replace('-', 'M'); - return storageName; - } - - /** - * An input stream that reads the data from a page store. - */ - static class PageInputStream extends InputStream { - - private final PrintWriter writer; - private final FileStore store; - private final Data page; - private final int pageSize; - private int trunkPage; - private int dataPage; - private IntArray dataPages = new IntArray(); - private boolean endOfFile; - private int remaining; - private int logKey; - - public PageInputStream(PrintWriter writer, DataHandler handler, - FileStore store, int logKey, int firstTrunkPage, int firstDataPage, int pageSize) { - this.writer = writer; - this.store = store; - this.pageSize = pageSize; - this.logKey = logKey - 1; - this.trunkPage = firstTrunkPage; - this.dataPage = firstDataPage; - page = Data.create(handler, pageSize); - } - - public int read() { - byte[] b = { 0 }; - int len = read(b); - return len < 0 ? -1 : (b[0] & 255); - } - - public int read(byte[] b) { - return read(b, 0, b.length); - } - - public int read(byte[] b, int off, int len) { - if (len == 0) { - return 0; - } - int read = 0; - while (len > 0) { - int r = readBlock(b, off, len); - if (r < 0) { - break; - } - read += r; - off += r; - len -= r; - } - return read == 0 ? -1 : read; - } - - private int readBlock(byte[] buff, int off, int len) { - fillBuffer(); - if (endOfFile) { - return -1; - } - int l = Math.min(remaining, len); - page.read(buff, off, l); - remaining -= l; - return l; - } - - private void fillBuffer() { - if (remaining > 0 || endOfFile) { - return; - } - while (dataPages.size() == 0) { - if (trunkPage == 0) { - endOfFile = true; - return; - } - store.seek((long) trunkPage * pageSize); - store.readFully(page.getBytes(), 0, pageSize); - page.reset(); - if (!PageStore.checksumTest(page.getBytes(), trunkPage, pageSize)) { - writer.println("-- ERROR: checksum mismatch page: " +trunkPage); - endOfFile = true; - return; - } - int t = page.readByte(); - page.readShortInt(); - if (t != Page.TYPE_STREAM_TRUNK) { - writer.println("-- eof page: " + trunkPage + " type: " + t + " expected type: " + Page.TYPE_STREAM_TRUNK); - endOfFile = true; - return; - } - page.readInt(); - int key = page.readInt(); - logKey++; - if (key != logKey) { - writer.println("-- eof page: " + trunkPage + " type: " + t + " expected key: " + logKey + " got: " + key); - } - trunkPage = page.readInt(); - int pageCount = page.readShortInt(); - for (int i = 0; i < pageCount; i++) { - int d = page.readInt(); - if (dataPage != 0) { - if (d == dataPage) { - dataPage = 0; - } else { - // ignore the pages before the starting page - continue; - } - } - dataPages.add(d); - } - } - if (dataPages.size() > 0) { - page.reset(); - int nextPage = dataPages.get(0); - dataPages.remove(0); - store.seek((long) nextPage * pageSize); - store.readFully(page.getBytes(), 0, pageSize); - page.reset(); - int t = page.readByte(); - if (t != 0 && !PageStore.checksumTest(page.getBytes(), nextPage, pageSize)) { - writer.println("-- ERROR: checksum mismatch page: " +nextPage); - endOfFile = true; - return; - } - page.readShortInt(); - int p = page.readInt(); - int k = page.readInt(); - if (t != Page.TYPE_STREAM_DATA) { - writer.println("-- eof page: " +nextPage+ " type: " + t + " parent: " + p + - " expected type: " + Page.TYPE_STREAM_DATA); - endOfFile = true; - return; - } else if (k != logKey) { - writer.println("-- eof page: " +nextPage+ " type: " + t + " parent: " + p + - " expected key: " + logKey + " got: " + k); - endOfFile = true; - return; - } - remaining = pageSize - page.length(); - } - } - } - - private void dumpPageBtreeNode(PrintWriter writer, Data s, int pageId, boolean positionOnly) { - int rowCount = s.readInt(); - int entryCount = s.readShortInt(); - int[] children = new int[entryCount + 1]; - int[] offsets = new int[entryCount]; - children[entryCount] = s.readInt(); - checkParent(writer, pageId, children, entryCount); - int empty = Integer.MAX_VALUE; - for (int i = 0; i < entryCount; i++) { - children[i] = s.readInt(); - checkParent(writer, pageId, children, i); - int off = s.readShortInt(); - empty = Math.min(off, empty); - offsets[i] = off; - } - empty = empty - s.length(); - if (!trace) { - return; - } - writer.println("-- empty: " + empty); - for (int i = 0; i < entryCount; i++) { - int off = offsets[i]; - s.setPos(off); - long key = s.readVarLong(); - Value data; - if (positionOnly) { - data = ValueLong.get(key); - } else { - try { - data = s.readValue(); - } catch (Throwable e) { - writeDataError(writer, "exception " + e, s.getBytes()); - continue; - } - } - writer.println("-- [" + i + "] child: " + children[i] + " key: " + key + " data: " + data); - } - writer.println("-- [" + entryCount + "] child: " + children[entryCount] + " rowCount: " + rowCount); - } - - private int dumpPageFreeList(PrintWriter writer, Data s, long pageId, long pageCount) { - int pagesAddressed = PageFreeList.getPagesAddressed(pageSize); - BitSet used = new BitSet(); - for (int i = 0; i < pagesAddressed; i += 8) { - int x = s.readByte() & 255; - for (int j = 0; j < 8; j++) { - if ((x & (1 << j)) != 0) { - used.set(i + j); - } - } - } - int free = 0; - for (long i = 0, j = pageId; i < pagesAddressed && j < pageCount; i++, j++) { - if (i == 0 || j % 100 == 0) { - if (i > 0) { - writer.println(); - } - writer.print("-- " + j + " "); - } else if (j % 20 == 0) { - writer.print(" - "); - } else if (j % 10 == 0) { - writer.print(' '); - } - writer.print(used.get((int) i) ? '1' : '0'); - if (!used.get((int) i)) { - free++; - } - } - writer.println(); - return free; - } - - private void dumpPageBtreeLeaf(PrintWriter writer, Data s, int entryCount, boolean positionOnly) { - int[] offsets = new int[entryCount]; - int empty = Integer.MAX_VALUE; - for (int i = 0; i < entryCount; i++) { - int off = s.readShortInt(); - empty = Math.min(off, empty); - offsets[i] = off; - } - empty = empty - s.length(); - writer.println("-- empty: " + empty); - for (int i = 0; i < entryCount; i++) { - int off = offsets[i]; - s.setPos(off); - long key = s.readVarLong(); - Value data; - if (positionOnly) { - data = ValueLong.get(key); - } else { - try { - data = s.readValue(); - } catch (Throwable e) { - writeDataError(writer, "exception " + e, s.getBytes()); - continue; - } - } - writer.println("-- [" + i + "] key: " + key + " data: " + data); - } - } - - private void checkParent(PrintWriter writer, long pageId, int[] children, int index) { - int child = children[index]; - if (child < 0 || child >= parents.length) { - writer.println("-- ERROR [" + pageId + "] child[" + index + "]: " + child + " >= page count: " + parents.length); - } else if (parents[child] != pageId) { - writer.println("-- ERROR [" + pageId + "] child[" + index + "]: " + child + " parent: " + parents[child]); - } - } - - private void dumpPageDataNode(PrintWriter writer, Data s, long pageId, int entryCount) { - int[] children = new int[entryCount + 1]; - long[] keys = new long[entryCount]; - children[entryCount] = s.readInt(); - checkParent(writer, pageId, children, entryCount); - for (int i = 0; i < entryCount; i++) { - children[i] = s.readInt(); - checkParent(writer, pageId, children, i); - keys[i] = s.readVarLong(); - } - if (!trace) { - return; - } - for (int i = 0; i < entryCount; i++) { - writer.println("-- [" + i + "] child: " + children[i] + " key: " + keys[i]); - } - writer.println("-- [" + entryCount + "] child: " + children[entryCount]); - } - - private void dumpPageDataLeaf(PrintWriter writer, Data s, boolean last, long pageId, int columnCount, int entryCount) { - long[] keys = new long[entryCount]; - int[] offsets = new int[entryCount]; - long next = 0; - if (!last) { - next = s.readInt(); - writer.println("-- next: " + next); - } - int empty = pageSize; - for (int i = 0; i < entryCount; i++) { - keys[i] = s.readVarLong(); - int off = s.readShortInt(); - empty = Math.min(off, empty); - offsets[i] = off; - } - stat.pageDataRows += pageSize - empty; - empty = empty - s.length(); - stat.pageDataHead += s.length(); - stat.pageDataEmpty += empty; - if (trace) { - writer.println("-- empty: " + empty); - } - if (!last) { - Data s2 = Data.create(this, pageSize); - s.setPos(pageSize); - long parent = pageId; - while (true) { - checkParent(writer, parent, new int[]{(int) next}, 0); - parent = next; - store.seek(pageSize * next); - store.readFully(s2.getBytes(), 0, pageSize); - s2.reset(); - int type = s2.readByte(); - s2.readShortInt(); - s2.readInt(); - if (type == (Page.TYPE_DATA_OVERFLOW | Page.FLAG_LAST)) { - int size = s2.readShortInt(); - writer.println("-- chain: " + next + " type: " + type + " size: " + size); - s.checkCapacity(size); - s.write(s2.getBytes(), s2.length(), size); - break; - } else if (type == Page.TYPE_DATA_OVERFLOW) { - next = s2.readInt(); - if (next == 0) { - writeDataError(writer, "next:0", s2.getBytes()); - break; - } - int size = pageSize - s2.length(); - writer.println("-- chain: " + next + " type: " + type + " size: " + size + " next: " + next); - s.checkCapacity(size); - s.write(s2.getBytes(), s2.length(), size); - } else { - writeDataError(writer, "type: " + type, s2.getBytes()); - break; - } - } - } - for (int i = 0; i < entryCount; i++) { - long key = keys[i]; - int off = offsets[i]; - if (trace) { - writer.println("-- [" + i + "] storage: " + storageId + " key: " + key + " off: " + off); - } - s.setPos(off); - Value[] data = createRecord(writer, s, columnCount); - if (data != null) { - createTemporaryTable(writer); - writeRow(writer, s, data); - if (remove && storageId == 0) { - String sql = data[3].getString(); - if (sql.startsWith("CREATE USER ")) { - int saltIndex = Utils.indexOf(s.getBytes(), "SALT ".getBytes(), off); - if (saltIndex >= 0) { - String userName = sql.substring("CREATE USER ".length(), sql.indexOf("SALT ") - 1); - if (userName.startsWith("\"")) { - // TODO doesn't work for all cases ("" inside user name) - userName = userName.substring(1, userName.length() - 1); - } - SHA256 sha = new SHA256(); - byte[] userPasswordHash = sha.getKeyPasswordHash(userName, "".toCharArray()); - byte[] salt = MathUtils.secureRandomBytes(Constants.SALT_LEN); - byte[] passwordHash = sha.getHashWithSalt(userPasswordHash, salt); - StringBuilder buff = new StringBuilder(); - buff.append("SALT '"). - append(Utils.convertBytesToString(salt)). - append("' HASH '"). - append(Utils.convertBytesToString(passwordHash)). - append('\''); - byte[] replacement = buff.toString().getBytes(); - System.arraycopy(replacement, 0, s.getBytes(), saltIndex, replacement.length); - store.seek(pageSize * pageId); - store.write(s.getBytes(), 0, pageSize); - if (trace) { - out.println("User: " + userName); - } - remove = false; - } - } - } - } - } - } - - private Value[] createRecord(PrintWriter writer, Data s, int columnCount) { - recordLength = columnCount; - if (columnCount <= 0) { - writeDataError(writer, "columnCount<0", s.getBytes()); - return null; - } - Value[] data; - try { - data = new Value[columnCount]; - } catch (OutOfMemoryError e) { - writeDataError(writer, "out of memory", s.getBytes()); - return null; - } - return data; - } - - private void writeRow(PrintWriter writer, Data s, Value[] data) { - StringBuilder sb = new StringBuilder(); - sb.append("INSERT INTO " + storageName + " VALUES("); - for (valueId = 0; valueId < recordLength; valueId++) { - try { - Value v = s.readValue(); - data[valueId] = v; - if (valueId > 0) { - sb.append(", "); - } - String columnName = storageName + "." + valueId; - sb.append(getSQL(columnName, v)); - } catch (Exception e) { - writeDataError(writer, "exception " + e, s.getBytes()); - continue; - } catch (OutOfMemoryError e) { - writeDataError(writer, "out of memory", s.getBytes()); - continue; - } - } - sb.append(");"); - writer.println(sb.toString()); - if (storageId == 0) { - try { - SimpleRow r = new SimpleRow(data); - MetaRecord meta = new MetaRecord(r); - schema.add(meta); - if (meta.getObjectType() == DbObject.TABLE_OR_VIEW) { - String sql = data[3].getString(); - String name = extractTableOrViewName(sql); - tableMap.put(meta.getId(), name); - } - } catch (Throwable t) { - writeError(writer, t); - } - } - } - - private void resetSchema() { - schema = New.arrayList(); - objectIdSet = New.hashSet(); - tableMap = New.hashMap(); - columnTypeMap = New.hashMap(); - } - - private void writeSchema(PrintWriter writer) { - writer.println("---- Schema ----------"); - Collections.sort(schema); - for (MetaRecord m : schema) { - String sql = m.getSQL(); - // create, but not referential integrity constraints and so on - if (sql.startsWith("CREATE ")) { - writer.println(sql + ";"); - } - } - // first, copy the lob storage (if there is any) - // must occur before copying data, - // otherwise the lob storage may be overwritten - boolean deleteLobs = false; - for (Map.Entry entry : tableMap.entrySet()) { - Integer objectId = entry.getKey(); - String name = entry.getValue(); - if (objectIdSet.contains(objectId)) { - if (name.startsWith("INFORMATION_SCHEMA.LOB")) { - setStorage(objectId); - writer.println("DELETE FROM " + name + ";"); - writer.println("INSERT INTO " + name + " SELECT * FROM " + storageName + ";"); - if (name.startsWith("INFORMATION_SCHEMA.LOBS")) { - writer.println("UPDATE " + name + " SET TABLE = " + LobStorage.TABLE_TEMP + ";"); - deleteLobs = true; - } - } - } - } - for (Map.Entry entry : tableMap.entrySet()) { - Integer objectId = entry.getKey(); - String name = entry.getValue(); - if (objectIdSet.contains(objectId)) { - setStorage(objectId); - if (name.startsWith("INFORMATION_SCHEMA.LOB")) { - continue; - } - writer.println("INSERT INTO " + name + " SELECT * FROM " + storageName + ";"); - } - } - for (Integer objectId : objectIdSet) { - setStorage(objectId); - writer.println("DROP TABLE " + storageName + ";"); - } - writer.println("DROP ALIAS READ_BLOB;"); - writer.println("DROP ALIAS READ_CLOB;"); - writer.println("DROP ALIAS READ_BLOB_DB;"); - writer.println("DROP ALIAS READ_CLOB_DB;"); - if (deleteLobs) { - writer.println("DELETE FROM INFORMATION_SCHEMA.LOBS WHERE TABLE = " + LobStorage.TABLE_TEMP + ";"); - } - for (MetaRecord m : schema) { - String sql = m.getSQL(); - // everything except create - if (!sql.startsWith("CREATE ")) { - writer.println(sql + ";"); - } - } - } - - private void createTemporaryTable(PrintWriter writer) { - if (!objectIdSet.contains(storageId)) { - objectIdSet.add(storageId); - StatementBuilder buff = new StatementBuilder("CREATE TABLE "); - buff.append(storageName).append('('); - for (int i = 0; i < recordLength; i++) { - buff.appendExceptFirst(", "); - buff.append('C').append(i).append(' '); - String columnType = columnTypeMap.get(storageName + "." + i); - if (columnType == null) { - buff.append("VARCHAR"); - } else { - buff.append(columnType); - } - } - writer.println(buff.append(");").toString()); - writer.flush(); - } - } - - private String extractTableOrViewName(String sql) { - int indexTable = sql.indexOf(" TABLE "); - int indexView = sql.indexOf(" VIEW "); - if (indexTable > 0 && indexView > 0) { - if (indexTable < indexView) { - indexView = -1; - } else { - indexTable = -1; - } - } - if (indexView > 0) { - sql = sql.substring(indexView + " VIEW ".length()); - } else if (indexTable > 0) { - sql = sql.substring(indexTable + " TABLE ".length()); - } else { - return "UNKNOWN"; - } - if (sql.startsWith("IF NOT EXISTS ")) { - sql = sql.substring("IF NOT EXISTS ".length()); - } - boolean ignore = false; - for (int i = 0; i < sql.length(); i++) { - char ch = sql.charAt(i); - if (ch == '\"') { - ignore = !ignore; - } else if (!ignore && (ch <= ' ' || ch == '(')) { - sql = sql.substring(0, i); - return sql; - } - } - return "UNKNOWN"; - } - - - private void closeSilently(FileStore fileStore) { - if (fileStore != null) { - fileStore.closeSilently(); - } - } - - private void writeError(PrintWriter writer, Throwable e) { - if (writer != null) { - writer.println("// error: " + e); - } - traceError("Error", e); - } - - /** - * INTERNAL - */ - public String getDatabasePath() { - return databaseName; - } - - /** - * INTERNAL - */ - public FileStore openFile(String name, String mode, boolean mustExist) { - return FileStore.open(this, name, "rw"); - } - - /** - * INTERNAL - */ - public void checkPowerOff() { - // nothing to do - } - - /** - * INTERNAL - */ - public void checkWritingAllowed() { - // nothing to do - } - - /** - * INTERNAL - */ - public void freeUpDiskSpace() { - // nothing to do - } - - /** - * INTERNAL - */ - public int getMaxLengthInplaceLob() { - throw DbException.throwInternalError(); - } - - /** - * INTERNAL - */ - public String getLobCompressionAlgorithm(int type) { - return null; - } - - /** - * INTERNAL - */ - public Object getLobSyncObject() { - return this; - } - - /** - * INTERNAL - */ - public SmallLRUCache getLobFileListCache() { - return null; - } - - /** - * INTERNAL - */ - public TempFileDeleter getTempFileDeleter() { - return TempFileDeleter.getInstance(); - } - - /** - * INTERNAL - */ - public LobStorage getLobStorage() { - return null; - } - - /** - * INTERNAL - */ - public Connection getLobConnection() { - return null; - } - -} diff --git a/tools/h2/src/main/org/h2/tools/Restore.java b/tools/h2/src/main/org/h2/tools/Restore.java deleted file mode 100755 index bb4f679..0000000 --- a/tools/h2/src/main/org/h2/tools/Restore.java +++ /dev/null @@ -1,196 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.tools; - -import java.io.File; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.sql.SQLException; -import java.util.zip.ZipEntry; -import java.util.zip.ZipInputStream; - -import org.h2.message.DbException; -import org.h2.store.FileLister; -import org.h2.util.IOUtils; -import org.h2.util.Tool; - -/** - * Restores a H2 database by extracting the database files from a .zip file. - * @h2.resource - */ -public class Restore extends Tool { - - /** - * Options are case sensitive. Supported options are: - * - * - * - * - * - * - * - * - * - * - * - *
[-help] or [-?]Print the list of options
[-file <filename>]The source file name (default: backup.zip)
[-dir <dir>]The target directory (default: .)
[-db <database>]The target database name (as stored if not set)
[-quiet]Do not print progress information
- * @h2.resource - * - * @param args the command line arguments - */ - public static void main(String... args) throws SQLException { - new Restore().runTool(args); - } - - public void runTool(String... args) throws SQLException { - String zipFileName = "backup.zip"; - String dir = "."; - String db = null; - for (int i = 0; args != null && i < args.length; i++) { - String arg = args[i]; - if (arg.equals("-dir")) { - dir = args[++i]; - } else if (arg.equals("-file")) { - zipFileName = args[++i]; - } else if (arg.equals("-db")) { - db = args[++i]; - } else if (arg.equals("-quiet")) { - // ignore - } else if (arg.equals("-help") || arg.equals("-?")) { - showUsage(); - return; - } else { - throwUnsupportedOption(arg); - } - } - process(zipFileName, dir, db); - } - - private static String getOriginalDbName(String fileName, String db) throws IOException { - InputStream in = null; - try { - in = IOUtils.openFileInputStream(fileName); - ZipInputStream zipIn = new ZipInputStream(in); - String originalDbName = null; - boolean multiple = false; - while (true) { - ZipEntry entry = zipIn.getNextEntry(); - if (entry == null) { - break; - } - String entryName = entry.getName(); - zipIn.closeEntry(); - String name = FileLister.getDatabaseNameFromFileName(entryName); - if (name != null) { - if (db.equals(name)) { - originalDbName = name; - // we found the correct database - break; - } else if (originalDbName == null) { - originalDbName = name; - // we found a database, but maybe another one - } else { - // we have found multiple databases, but not the correct - // one - multiple = true; - } - } - } - zipIn.close(); - if (multiple && !db.equals(originalDbName)) { - throw new IOException("Multiple databases found, but not " + db); - } - return originalDbName; - } finally { - IOUtils.closeSilently(in); - } - } - - /** - * Restores database files. - * - * @param zipFileName the name of the backup file - * @param directory the directory name - * @param db the database name (null for all databases) - * @param quiet don't print progress information - * @throws SQLException - */ - public static void execute(String zipFileName, String directory, String db, boolean quiet) throws SQLException { - new Restore().process(zipFileName, directory, db); - } - - /** - * Restores database files. - * - * @param zipFileName the name of the backup file - * @param directory the directory name - * @param db the database name (null for all databases) - * @param quiet don't print progress information - * @throws SQLException - */ - private void process(String zipFileName, String directory, String db) throws SQLException { - InputStream in = null; - try { - if (!IOUtils.exists(zipFileName)) { - throw new IOException("File not found: " + zipFileName); - } - String originalDbName = null; - int originalDbLen = 0; - if (db != null) { - originalDbName = getOriginalDbName(zipFileName, db); - if (originalDbName == null) { - throw new IOException("No database named " + db + " found"); - } - if (originalDbName.startsWith(File.separator)) { - originalDbName = originalDbName.substring(1); - } - originalDbLen = originalDbName.length(); - } - in = IOUtils.openFileInputStream(zipFileName); - ZipInputStream zipIn = new ZipInputStream(in); - while (true) { - ZipEntry entry = zipIn.getNextEntry(); - if (entry == null) { - break; - } - String fileName = entry.getName(); - // restoring windows backups on linux and vice versa - fileName = fileName.replace('\\', File.separatorChar); - fileName = fileName.replace('/', File.separatorChar); - if (fileName.startsWith(File.separator)) { - fileName = fileName.substring(1); - } - boolean copy = false; - if (db == null) { - copy = true; - } else if (fileName.startsWith(originalDbName + ".")) { - fileName = db + fileName.substring(originalDbLen); - copy = true; - } - if (copy) { - OutputStream o = null; - try { - o = IOUtils.openFileOutputStream(directory + File.separator + fileName, false); - IOUtils.copy(zipIn, o); - o.close(); - } finally { - IOUtils.closeSilently(o); - } - } - zipIn.closeEntry(); - } - zipIn.closeEntry(); - zipIn.close(); - } catch (IOException e) { - throw DbException.convertIOException(e, zipFileName); - } finally { - IOUtils.closeSilently(in); - } - } - -} diff --git a/tools/h2/src/main/org/h2/tools/RunScript.java b/tools/h2/src/main/org/h2/tools/RunScript.java deleted file mode 100755 index fa70d2e..0000000 --- a/tools/h2/src/main/org/h2/tools/RunScript.java +++ /dev/null @@ -1,319 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.tools; - -import java.io.BufferedInputStream; -import java.io.File; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.io.Reader; -import java.sql.Connection; -import java.sql.DriverManager; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.sql.Statement; -import org.h2.engine.Constants; -import org.h2.message.DbException; -import org.h2.util.Utils; -import org.h2.util.IOUtils; -import org.h2.util.JdbcUtils; -import org.h2.util.ScriptReader; -import org.h2.util.StringUtils; -import org.h2.util.Tool; - -/** - * Runs a SQL script against a database. - * @h2.resource - */ -public class RunScript extends Tool { - - private boolean showResults; - private boolean checkResults; - - /** - * Options are case sensitive. Supported options are: - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - *
[-help] or [-?]Print the list of options
[-url "<url>"]The database URL (jdbc:...)
[-user <user>]The user name (default: sa)
[-password <pwd>]The password
[-script <file>]The script file to run (default: backup.sql)
[-driver <class>]The JDBC driver class to use (not required in most cases)
[-showResults]Show the statements and the results of queries
[-checkResults]Check if the query results match the expected results
[-continueOnError]Continue even if the script contains errors
[-options ...]RUNSCRIPT options (embedded H2; -*Results not supported)
- * @h2.resource - * - * @param args the command line arguments - */ - public static void main(String... args) throws SQLException { - new RunScript().runTool(args); - } - - /** - * Executes the contents of a SQL script file against a database. - * This tool is usually used to create a database from script. - * It can also be used to analyze performance problems by running - * the tool using Java profiler settings such as: - *
-     * java -Xrunhprof:cpu=samples,depth=16 ...
-     * 
- * To include local files when using remote databases, use the special - * syntax: - *
-     * @INCLUDE fileName
-     * 
- * This syntax is only supported by this tool. Embedded RUNSCRIPT SQL - * statements will be executed by the database. - * - * @param args the command line arguments - */ - public void runTool(String... args) throws SQLException { - String url = null; - String user = "sa"; - String password = ""; - String script = "backup.sql"; - String options = null; - boolean continueOnError = false; - boolean showTime = false; - for (int i = 0; args != null && i < args.length; i++) { - String arg = args[i]; - if (arg.equals("-url")) { - url = args[++i]; - } else if (arg.equals("-user")) { - user = args[++i]; - } else if (arg.equals("-password")) { - password = args[++i]; - } else if (arg.equals("-continueOnError")) { - continueOnError = true; - } else if (arg.equals("-checkResults")) { - checkResults = true; - } else if (arg.equals("-showResults")) { - showResults = true; - } else if (arg.equals("-script")) { - script = args[++i]; - } else if (arg.equals("-time")) { - showTime = true; - } else if (arg.equals("-driver")) { - String driver = args[++i]; - Utils.loadUserClass(driver); - } else if (arg.equals("-options")) { - StringBuilder buff = new StringBuilder(); - i++; - for (; i < args.length; i++) { - buff.append(' ').append(args[i]); - } - options = buff.toString(); - } else if (arg.equals("-help") || arg.equals("-?")) { - showUsage(); - return; - } else { - throwUnsupportedOption(arg); - } - } - if (url == null) { - showUsage(); - throw new SQLException("URL not set"); - } - long time = System.currentTimeMillis(); - if (options != null) { - processRunscript(url, user, password, script, options); - } else { - process(url, user, password, script, null, continueOnError); - } - if (showTime) { - time = System.currentTimeMillis() - time; - out.println("Done in " + time + " ms"); - } - } - - /** - * Executes the SQL commands in a script file against a database. - * - * @param conn the connection to a database - * @param reader the reader - * @return the last result set - */ - public static ResultSet execute(Connection conn, Reader reader) throws SQLException { - return new RunScript().process(conn, reader); - } - - private ResultSet process(Connection conn, Reader reader) throws SQLException { - Statement stat = conn.createStatement(); - ResultSet rs = null; - ScriptReader r = new ScriptReader(reader); - while (true) { - String sql = r.readStatement(); - if (sql == null) { - break; - } - boolean resultSet = stat.execute(sql); - if (resultSet) { - if (rs != null) { - rs.close(); - rs = null; - } - rs = stat.getResultSet(); - } - } - return rs; - } - - private void process(Connection conn, String fileName, boolean continueOnError, String charsetName) throws SQLException, IOException { - InputStream in = IOUtils.openFileInputStream(fileName); - String path = IOUtils.getParent(fileName); - try { - in = new BufferedInputStream(in, Constants.IO_BUFFER_SIZE); - Reader reader = new InputStreamReader(in, charsetName); - process(conn, continueOnError, path, reader, charsetName); - } finally { - IOUtils.closeSilently(in); - } - } - - private void process(Connection conn, boolean continueOnError, String path, Reader reader, String charsetName) throws SQLException, IOException { - Statement stat = conn.createStatement(); - ScriptReader r = new ScriptReader(reader); - while (true) { - String sql = r.readStatement(); - if (sql == null) { - break; - } - String trim = sql.trim(); - if (trim.startsWith("@") && StringUtils.toUpperEnglish(trim).startsWith("@INCLUDE")) { - sql = trim; - sql = sql.substring("@INCLUDE".length()).trim(); - if (!IOUtils.isAbsolute(sql)) { - sql = path + File.separator + sql; - } - process(conn, sql, continueOnError, charsetName); - } else { - try { - if (trim.length() > 0) { - if (showResults && !trim.startsWith("-->")) { - out.print(sql + ";"); - } - if (showResults || checkResults) { - boolean query = stat.execute(sql); - if (query) { - ResultSet rs = stat.getResultSet(); - int columns = rs.getMetaData().getColumnCount(); - StringBuilder buff = new StringBuilder(); - while (rs.next()) { - buff.append("\n-->"); - for (int i = 0; i < columns; i++) { - String s = rs.getString(i + 1); - if (s != null) { - s = StringUtils.replaceAll(s, "\r\n", "\n"); - s = StringUtils.replaceAll(s, "\n", "\n--> "); - s = StringUtils.replaceAll(s, "\r", "\r--> "); - } - buff.append(' ').append(s); - } - } - buff.append("\n;"); - String result = buff.toString(); - if (showResults) { - out.print(result); - } - if (checkResults) { - String expected = r.readStatement() + ";"; - expected = StringUtils.replaceAll(expected, "\r\n", "\n"); - expected = StringUtils.replaceAll(expected, "\r", "\n"); - if (!expected.equals(result)) { - expected = StringUtils.replaceAll(expected, " ", "+"); - result = StringUtils.replaceAll(result, " ", "+"); - throw new SQLException("Unexpected output for:\n" + sql.trim() + "\nGot:\n" + result + "\nExpected:\n" + expected); - } - } - - } - } else { - stat.execute(sql); - } - } - } catch (Exception e) { - if (continueOnError) { - e.printStackTrace(out); - } else { - throw DbException.toSQLException(e); - } - } - } - } - } - - private static void processRunscript(String url, String user, String password, String fileName, String options) throws SQLException { - Connection conn = null; - Statement stat = null; - try { - org.h2.Driver.load(); - conn = DriverManager.getConnection(url, user, password); - stat = conn.createStatement(); - String sql = "RUNSCRIPT FROM '" + fileName + "' " + options; - stat.execute(sql); - } finally { - JdbcUtils.closeSilently(stat); - JdbcUtils.closeSilently(conn); - } - } - - /** - * Executes the SQL commands in a script file against a database. - * - * @param url the database URL - * @param user the user name - * @param password the password - * @param fileName the script file - * @param charsetName the character set name or null for UTF-8 - * @param continueOnError if execution should be continued if an error occurs - */ - public static void execute(String url, String user, String password, String fileName, String charsetName, boolean continueOnError) throws SQLException { - new RunScript().process(url, user, password, fileName, charsetName, continueOnError); - } - - /** - * Executes the SQL commands in a script file against a database. - * - * @param url the database URL - * @param user the user name - * @param password the password - * @param fileName the script file - * @param charsetName the character set name or null for UTF-8 - * @param continueOnError if execution should be continued if an error occurs - */ - void process(String url, String user, String password, String fileName, String charsetName, boolean continueOnError) throws SQLException { - try { - org.h2.Driver.load(); - Connection conn = DriverManager.getConnection(url, user, password); - if (charsetName == null) { - charsetName = Constants.UTF8; - } - try { - process(conn, fileName, continueOnError, charsetName); - } finally { - conn.close(); - } - } catch (IOException e) { - throw DbException.convertIOException(e, fileName); - } - } - -} diff --git a/tools/h2/src/main/org/h2/tools/Script.java b/tools/h2/src/main/org/h2/tools/Script.java deleted file mode 100755 index 9eb7d38..0000000 --- a/tools/h2/src/main/org/h2/tools/Script.java +++ /dev/null @@ -1,203 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.tools; - -import java.io.OutputStream; -import java.io.PrintWriter; -import java.sql.Connection; -import java.sql.DriverManager; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.sql.Statement; -import org.h2.util.IOUtils; -import org.h2.util.JdbcUtils; -import org.h2.util.StringUtils; -import org.h2.util.Tool; - -/** - * Creates a SQL script file by extracting the schema and data of a database. - * @h2.resource - */ -public class Script extends Tool { - - /** - * Options are case sensitive. Supported options are: - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - *
[-help] or [-?]Print the list of options
[-url "<url>"]The database URL (jdbc:...)
[-user <user>]The user name (default: sa)
[-password <pwd>]The password
[-script <file>]The target script file name (default: backup.sql)
[-options ...]A list of options (only for embedded H2, see RUNSCRIPT)
[-quiet]Do not print progress information
- * @h2.resource - * - * @param args the command line arguments - */ - public static void main(String... args) throws SQLException { - new Script().runTool(args); - } - - public void runTool(String... args) throws SQLException { - String url = null; - String user = "sa"; - String password = ""; - String file = "backup.sql"; - String options1 = null, options2 = null; - for (int i = 0; args != null && i < args.length; i++) { - String arg = args[i]; - if (arg.equals("-url")) { - url = args[++i]; - } else if (arg.equals("-user")) { - user = args[++i]; - } else if (arg.equals("-password")) { - password = args[++i]; - } else if (arg.equals("-script")) { - file = args[++i]; - } else if (arg.equals("-options")) { - StringBuilder buff1 = new StringBuilder(); - StringBuilder buff2 = new StringBuilder(); - i++; - for (; i < args.length; i++) { - String a = args[i]; - String upper = StringUtils.toUpperEnglish(a); - if (upper.startsWith("NO") || "DROP".equals(upper)) { - buff1.append(' '); - buff1.append(args[i]); - } else { - buff2.append(' '); - buff2.append(args[i]); - } - } - options1 = buff1.toString(); - options2 = buff2.toString(); - } else if (arg.equals("-help") || arg.equals("-?")) { - showUsage(); - return; - } else { - throwUnsupportedOption(arg); - } - } - if (url == null) { - showUsage(); - throw new SQLException("URL not set"); - } - if (options1 != null) { - processScript(url, user, password, file, options1, options2); - } else { - process(url, user, password, file); - } - } - - private void processScript(String url, String user, String password, String fileName, String options1, String options2) throws SQLException { - Connection conn = null; - Statement stat = null; - try { - org.h2.Driver.load(); - conn = DriverManager.getConnection(url, user, password); - stat = conn.createStatement(); - String sql = "SCRIPT " + options1 + " TO '" + fileName + "' " + options2; - stat.execute(sql); - } finally { - JdbcUtils.closeSilently(stat); - JdbcUtils.closeSilently(conn); - } - } - - /** - * Backs up a database to a SQL script file. - * - * @param url the database URL - * @param user the user name - * @param password the password - * @param fileName the script file - */ - public static void execute(String url, String user, String password, String fileName) throws SQLException { - new Script().process(url, user, password, fileName); - } - - /** - * Backs up a database to a stream. The stream is not closed. - * - * @param url the database URL - * @param user the user name - * @param password the password - * @param out the output stream - */ - public static void execute(String url, String user, String password, OutputStream out) throws SQLException { - new Script().process(url, user, password, out); - } - - /** - * Backs up a database to a SQL script file. - * - * @param url the database URL - * @param user the user name - * @param password the password - * @param fileName the script file - */ - void process(String url, String user, String password, String fileName) throws SQLException { - OutputStream o = null; - try { - o = IOUtils.openFileOutputStream(fileName, false); - process(url, user, password, o); - } finally { - IOUtils.closeSilently(o); - } - } - - /** - * Backs up a database to a stream. The stream is not closed. - * - * @param url the database URL - * @param user the user name - * @param password the password - * @param o the output stream - */ - void process(String url, String user, String password, OutputStream o) throws SQLException { - Connection conn = null; - try { - org.h2.Driver.load(); - conn = DriverManager.getConnection(url, user, password); - process(conn, o); - } finally { - JdbcUtils.closeSilently(conn); - } - } - - /** - * Backs up a database to a stream. The stream is not closed. - * The connection is not closed. - * - * @param conn the connection - * @param o the output stream - */ - void process(Connection conn, OutputStream o) throws SQLException { - Statement stat = null; - try { - stat = conn.createStatement(); - PrintWriter writer = new PrintWriter(IOUtils.getWriter(o)); - ResultSet rs = stat.executeQuery("SCRIPT"); - while (rs.next()) { - String s = rs.getString(1); - writer.println(s); - } - writer.flush(); - } finally { - JdbcUtils.closeSilently(stat); - } - } - -} diff --git a/tools/h2/src/main/org/h2/tools/Server.java b/tools/h2/src/main/org/h2/tools/Server.java deleted file mode 100755 index 2ceb42b..0000000 --- a/tools/h2/src/main/org/h2/tools/Server.java +++ /dev/null @@ -1,559 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.tools; - -import java.io.IOException; -import java.net.URI; -import java.sql.Connection; -import java.sql.SQLException; -import org.h2.constant.ErrorCode; -import org.h2.constant.SysProperties; -import org.h2.message.DbException; -import org.h2.message.TraceSystem; -import org.h2.server.Service; -import org.h2.server.ShutdownHandler; -import org.h2.server.TcpServer; -import org.h2.server.pg.PgServer; -import org.h2.server.web.WebServer; -import org.h2.util.StringUtils; -import org.h2.util.Tool; - -/** - * Starts the H2 Console (web-) server, TCP, and PG server. - * @h2.resource - */ -public class Server extends Tool implements Runnable, ShutdownHandler { - - private Service service; - private Server web, tcp, pg; - private ShutdownHandler shutdownHandler; - - public Server() { - // nothing to do - } - - /** - * Create a new server for the given service. - * - * @param service the service - * @param args the command line arguments - */ - public Server(Service service, String... args) throws SQLException { - this.service = service; - try { - service.init(args); - } catch (Exception e) { - throw DbException.toSQLException(e); - } - } - - /** - * When running without options, -tcp, -web, -browser and -pg are started. - *
- * Options are case sensitive. Supported options are: - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - *
[-help] or [-?]Print the list of options
[-web]Start the web server with the H2 Console
[-webAllowOthers]Allow other computers to connect - see below
[-webDaemon]Use a daemon thread
[-webPort <port>]The port (default: 8082)
[-webSSL]Use encrypted (HTTPS) connections
[-browser]Start a browser connecting to the web server
[-tcp]Start the TCP server
[-tcpAllowOthers]Allow other computers to connect - see below
[-tcpDaemon]Use a daemon thread
[-tcpPort <port>]The port (default: 9092)
[-tcpSSL]Use encrypted (SSL) connections
[-tcpPassword <pwd>]The password for shutting down a TCP server
[-tcpShutdown "<url>"]Stop the TCP server; example: tcp://localhost
[-tcpShutdownForce]Do not wait until all connections are closed
[-pg]Start the PG server
[-pgAllowOthers]Allow other computers to connect - see below
[-pgDaemon]Use a daemon thread
[-pgPort <port>]The port (default: 5435)
[-baseDir <dir>]The base directory for H2 databases (all servers)
[-ifExists]Only existing databases may be opened (all servers)
[-trace]Print additional trace information (all servers)
- * The options -xAllowOthers are potentially risky. - *
- * For details, see Advanced Topics / Protection against Remote Access. - * @h2.resource - * - * @param args the command line arguments - */ - public static void main(String... args) throws SQLException { - new Server().runTool(args); - } - - public void runTool(String... args) throws SQLException { - boolean tcpStart = false, pgStart = false, webStart = false; - boolean browserStart = false; - boolean tcpShutdown = false, tcpShutdownForce = false; - String tcpPassword = ""; - String tcpShutdownServer = ""; - boolean startDefaultServers = true; - for (int i = 0; args != null && i < args.length; i++) { - String arg = args[i]; - if (arg == null) { - continue; - } else if ("-?".equals(arg) || "-help".equals(arg)) { - showUsage(); - return; - } else if (arg.startsWith("-web")) { - if ("-web".equals(arg)) { - startDefaultServers = false; - webStart = true; - } else if ("-webAllowOthers".equals(arg)) { - // no parameters - } else if ("-webDaemon".equals(arg)) { - // no parameters - } else if ("-webSSL".equals(arg)) { - // no parameters - } else if ("-webPort".equals(arg)) { - i++; - } else if ("-webScript".equals(arg)) { - i++; - } else { - throwUnsupportedOption(arg); - } - } else if ("-browser".equals(arg)) { - startDefaultServers = false; - browserStart = true; - } else if (arg.startsWith("-tcp")) { - if ("-tcp".equals(arg)) { - startDefaultServers = false; - tcpStart = true; - } else if ("-tcpAllowOthers".equals(arg)) { - // no parameters - } else if ("-tcpDaemon".equals(arg)) { - // no parameters - } else if ("-tcpSSL".equals(arg)) { - // no parameters - } else if ("-tcpPort".equals(arg)) { - i++; - } else if ("-tcpPassword".equals(arg)) { - tcpPassword = args[++i]; - } else if ("-tcpShutdown".equals(arg)) { - startDefaultServers = false; - tcpShutdown = true; - tcpShutdownServer = args[++i]; - } else if ("-tcpShutdownForce".equals(arg)) { - tcpShutdownForce = true; - } else { - throwUnsupportedOption(arg); - } - } else if (arg.startsWith("-pg")) { - if ("-pg".equals(arg)) { - startDefaultServers = false; - pgStart = true; - } else if ("-pgAllowOthers".equals(arg)) { - // no parameters - } else if ("-pgDaemon".equals(arg)) { - // no parameters - } else if ("-pgPort".equals(arg)) { - i++; - } else { - throwUnsupportedOption(arg); - } - } else if ("-trace".equals(arg)) { - // no parameters - } else if ("-ifExists".equals(arg)) { - // no parameters - } else if ("-baseDir".equals(arg)) { - i++; - } else { - throwUnsupportedOption(arg); - } - } - if (startDefaultServers) { - tcpStart = true; - pgStart = true; - webStart = true; - browserStart = true; - } - // TODO server: maybe use one single properties file? - if (tcpShutdown) { - out.println("Shutting down TCP Server at " + tcpShutdownServer); - shutdownTcpServer(tcpShutdownServer, tcpPassword, tcpShutdownForce, false); - } - if (webStart) { - web = createWebServer(args); - web.setShutdownHandler(this); - SQLException result = null; - try { - web.start(); - } catch (Exception e) { - result = DbException.toSQLException(e); - } - out.println(web.getStatus()); - // start browser in any case (even if the server is already running) - // because some people don't look at the output, - // but are wondering why nothing happens - if (browserStart) { - Server.openBrowser(web.getURL()); - } - if (result != null) { - throw result; - } - } - if (tcpStart) { - tcp = createTcpServer(args); - tcp.start(); - out.println(tcp.getStatus()); - } - if (pgStart) { - pg = createPgServer(args); - pg.start(); - out.println(pg.getStatus()); - } - } - - /** - * Shutdown one or all TCP server. If force is set to false, the server will not - * allow new connections, but not kill existing connections, instead it will - * stop if the last connection is closed. If force is set to true, existing - * connections are killed. After calling the method with force=false, it is - * not possible to call it again with force=true because new connections are - * not allowed. Example: - * - *
-     * Server.shutdownTcpServer(
-     *     "tcp://localhost:9094", password, true, false);
-     * 
- * - * @param url example: tcp://localhost:9094 - * @param password the password to use ("" for no password) - * @param force the shutdown (don't wait) - * @param all whether all TCP servers that are running in the JVM - * should be stopped - */ - public static void shutdownTcpServer(String url, String password, boolean force, boolean all) throws SQLException { - TcpServer.shutdown(url, password, force, all); - } - - /** - * Get the status of this server. - * - * @return the status - */ - public String getStatus() { - StringBuilder buff = new StringBuilder(); - if (isRunning(false)) { - buff.append(service.getType()). - append(" server running on "). - append(service.getURL()). - append(" ("); - if (service.getAllowOthers()) { - buff.append("others can connect"); - } else { - buff.append("only local connections"); - } - buff.append(')'); - } else { - buff.append("The "). - append(service.getType()). - append(" server could not be started. Possible cause: another server is already running on "). - append(service.getURL()); - } - return buff.toString(); - } - - /** - * Create a new web server, but does not start it yet. Example: - * - *
-     * Server server = Server.createWebServer(
-     *     new String[] { "-trace" }).start();
-     * 
- * - * @param args the argument list - * @return the server - */ - public static Server createWebServer(String... args) throws SQLException { - WebServer service = new WebServer(); - Server server = new Server(service, args); - service.setShutdownHandler(server); - return server; - } - - /** - * Create a new TCP server, but does not start it yet. Example: - * - *
-     * Server server = Server.createTcpServer(
-     *     new String[] { "-tcpAllowOthers" }).start();
-     * 
- * - * @param args the argument list - * @return the server - */ - public static Server createTcpServer(String... args) throws SQLException { - return new Server(new TcpServer(), args); - } - - /** - * Create a new PG server, but does not start it yet. - * Example: - *
-     * Server server =
-     *     Server.createPgServer("-pgAllowOthers").start();
-     * 
- * - * @param args the argument list - * @return the server - */ - public static Server createPgServer(String... args) throws SQLException { - return new Server(new PgServer(), args); - } - - /** - * Tries to start the server. - * @return the server if successful - * @throws SQLException if the server could not be started - */ - public Server start() throws SQLException { - try { - service.start(); - Thread t = new Thread(this); - t.setDaemon(service.isDaemon()); - String name = service.getName() + " (" + service.getURL() + ")"; - t.setName(name); - t.start(); - for (int i = 1; i < 64; i += i) { - wait(i); - if (isRunning(false)) { - return this; - } - } - if (isRunning(true)) { - return this; - } - throw DbException.get(ErrorCode.EXCEPTION_OPENING_PORT_2, name, "timeout"); - } catch (DbException e) { - throw DbException.toSQLException(e); - } - } - - private static void wait(int i) { - try { - // sleep at most 4096 ms - long sleep = (long) i * (long) i; - Thread.sleep(sleep); - } catch (InterruptedException e) { - // ignore - } - } - - private void stopAll() { - if (web != null && web.isRunning(false)) { - web.stop(); - web = null; - } - if (tcp != null && tcp.isRunning(false)) { - tcp.stop(); - tcp = null; - } - if (pg != null && pg.isRunning(false)) { - pg.stop(); - pg = null; - } - } - - /** - * Checks if the server is running. - * - * @param traceError if errors should be written - * @return if the server is running - */ - public boolean isRunning(boolean traceError) { - return service.isRunning(traceError); - } - - /** - * Stops the server. - */ - public void stop() { - service.stop(); - } - - /** - * Gets the URL of this server. - * - * @return the url - */ - public String getURL() { - return service.getURL(); - } - - /** - * Gets the port this server is listening on. - * - * @return the port - */ - public int getPort() { - return service.getPort(); - } - - /** - * INTERNAL - */ - public void run() { - try { - service.listen(); - } catch (Exception e) { - TraceSystem.traceThrowable(e); - } - } - - /** - * INTERNAL - */ - public void setShutdownHandler(ShutdownHandler shutdownHandler) { - this.shutdownHandler = shutdownHandler; - } - - /** - * INTERNAL - */ - public void shutdown() { - if (shutdownHandler != null) { - shutdownHandler.shutdown(); - } else { - stopAll(); - } - } - - /** - * Get the service attached to this server. - * - * @return the service - */ - public Service getService() { - return service; - } - - /** - * Open a new browser tab or window with the given URL. - * - * @param url the URL to open - */ - public static void openBrowser(String url) { - String osName = SysProperties.getStringSetting("os.name", "linux").toLowerCase(); - Runtime rt = Runtime.getRuntime(); - try { - String browser = SysProperties.BROWSER; - if (browser != null) { - if (browser.indexOf("%url") >= 0) { - String[] args = StringUtils.arraySplit(browser, ',', false); - for (int i = 0; i < args.length; i++) { - args[i] = StringUtils.replaceAll(args[i], "%url", url); - } - rt.exec(args); - } else if (osName.indexOf("windows") >= 0) { - rt.exec(new String[] { "cmd.exe", "/C", browser, url }); - } else { - rt.exec(new String[] { browser, url }); - } - return; - } - try { - Class< ? > desktopClass = Class.forName("java.awt.Desktop"); - // Desktop.isDesktopSupported() - Boolean supported = (Boolean) desktopClass. - getMethod("isDesktopSupported"). - invoke(null, new Object[0]); - URI uri = new URI(url); - if (supported) { - // Desktop.getDesktop(); - Object desktop = desktopClass.getMethod("getDesktop"). - invoke(null, new Object[0]); - // desktop.browse(uri); - desktopClass.getMethod("browse", URI.class). - invoke(desktop, uri); - return; - } - } catch (Exception e) { - // ignore - } - if (osName.indexOf("windows") >= 0) { - rt.exec(new String[] { "rundll32", "url.dll,FileProtocolHandler", url }); - } else if (osName.indexOf("mac") >= 0) { - // Mac OS: to open a page with Safari, use "open -a Safari" - Runtime.getRuntime().exec(new String[] { "open", url }); - } else { - String[] browsers = { "firefox", "mozilla-firefox", "mozilla", "konqueror", "netscape", "opera" }; - boolean ok = false; - for (String b : browsers) { - try { - rt.exec(new String[] { b, url }); - ok = true; - break; - } catch (Exception e) { - // ignore and try the next - } - } - if (!ok) { - // No success in detection. - System.out.println("Please open a browser and go to " + url); - } - } - } catch (IOException e) { - System.out.println("Failed to start a browser to open the URL " + url); - e.printStackTrace(); - } - } - - /** - * Start a web server and a browser that uses the given connection. The - * current transaction is preserved. This is specially useful to manually - * inspect the database when debugging. This method return as soon as the - * user has disconnected. - * - * @param conn the database connection (the database must be open) - */ - public static void startWebServer(Connection conn) throws SQLException { - WebServer webServer = new WebServer(); - Server web = new Server(webServer, new String[] { "-webPort", "0" }); - web.start(); - Server server = new Server(); - server.web = web; - webServer.setShutdownHandler(server); - String url = webServer.addSession(conn); - Server.openBrowser(url); - while (!webServer.isStopped()) { - try { - Thread.sleep(1000); - } catch (InterruptedException e) { - // ignore - } - } - } - -} diff --git a/tools/h2/src/main/org/h2/tools/Shell.java b/tools/h2/src/main/org/h2/tools/Shell.java deleted file mode 100755 index 69e2e54..0000000 --- a/tools/h2/src/main/org/h2/tools/Shell.java +++ /dev/null @@ -1,598 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.tools; - -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.io.PrintStream; -import java.io.StringReader; -import java.lang.reflect.Method; -import java.sql.Connection; -import java.sql.DriverManager; -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.ResultSetMetaData; -import java.sql.SQLException; -import java.sql.Statement; -import java.util.ArrayList; -import java.util.Properties; -import org.h2.engine.Constants; -import org.h2.server.web.ConnectionInfo; -import org.h2.util.ScriptReader; -import org.h2.util.Utils; -import org.h2.util.IOUtils; -import org.h2.util.JdbcUtils; -import org.h2.util.New; -import org.h2.util.SortedProperties; -import org.h2.util.Tool; - -/** - * Interactive command line tool to access a database using JDBC. - * @h2.resource - */ -public class Shell extends Tool implements Runnable { - - private static final int HISTORY_COUNT = 20; - - private PrintStream err = System.err; - private InputStream in = System.in; - private BufferedReader reader; - private Connection conn; - private Statement stat; - private boolean listMode; - private int maxColumnSize = 100; - // Windows: '\u00b3'; - private char boxVertical = '|'; - private ArrayList history = New.arrayList(); - private boolean stopHide; - - /** - * Options are case sensitive. Supported options are: - * - * - * - * - * - * - * - * - * - * - * - * - * - *
[-help] or [-?]Print the list of options
[-url "<url>"]The database URL (jdbc:h2:...)
[-user <user>]The user name
[-password <pwd>]The password
[-driver <class>]The JDBC driver class to use (not required in most cases)
[-sql "<statements>"]Execute the SQL statements and exit
- * If special characters don't work as expected, you may need to use - * -Dfile.encoding=UTF-8 (Mac OS X) or CP850 (Windows). - * @h2.resource - * - * @param args the command line arguments - */ - public static void main(String... args) throws SQLException { - new Shell().runTool(args); - } - - /** - * Sets the standard error stream. - * - * @param err the new standard error stream - */ - public void setErr(PrintStream err) { - this.err = err; - } - - /** - * Redirects the standard input. By default, System.in is used. - * - * @param in the input stream to use - */ - public void setIn(InputStream in) { - this.in = in; - } - - /** - * Redirects the standard input. By default, System.in is used. - * - * @param reader the input stream reader to use - */ - public void setInReader(BufferedReader reader) { - this.reader = reader; - } - - /** - * Run the shell tool with the given command line settings. - * - * @param args the command line settings - */ - public void runTool(String... args) throws SQLException { - String url = null; - String user = ""; - String password = ""; - String sql = null; - for (int i = 0; args != null && i < args.length; i++) { - String arg = args[i]; - if (arg.equals("-url")) { - url = args[++i]; - } else if (arg.equals("-user")) { - user = args[++i]; - } else if (arg.equals("-password")) { - password = args[++i]; - } else if (arg.equals("-driver")) { - String driver = args[++i]; - Utils.loadUserClass(driver); - } else if (arg.equals("-sql")) { - sql = args[++i]; - } else if (arg.equals("-help") || arg.equals("-?")) { - showUsage(); - return; - } else { - throwUnsupportedOption(arg); - } - } - if (url != null) { - org.h2.Driver.load(); - conn = DriverManager.getConnection(url, user, password); - stat = conn.createStatement(); - } - if (sql == null) { - promptLoop(); - } else { - ScriptReader r = new ScriptReader(new StringReader(sql)); - while (true) { - String s = r.readStatement(); - if (s == null) { - break; - } - execute(s); - } - } - } - - private void showHelp() { - println("Commands are case insensitive; SQL statements end with ';'"); - println("help or ? Display this help"); - println("list Toggle result list / stack trace mode"); - println("maxwidth Set maximum column width (default is 100)"); - println("show List all tables"); - println("describe Describe a table"); - println("history Show the last 20 statements"); - println("quit or exit Close the connection and exit"); - println(""); - } - - private void promptLoop() { - println(""); - println("Welcome to H2 Shell " + Constants.getFullVersion()); - println("Exit with Ctrl+C"); - if (conn != null) { - showHelp(); - } - String statement = null; - if (reader == null) { - reader = new BufferedReader(new InputStreamReader(in)); - } - while (true) { - try { - if (conn == null) { - connect(); - showHelp(); - } - if (statement == null) { - print("sql> "); - } else { - print("...> "); - } - String line = readLine(); - if (line == null) { - break; - } - String trimmed = line.trim(); - if (trimmed.length() == 0) { - continue; - } - boolean end = trimmed.endsWith(";"); - if (end) { - line = line.substring(0, line.lastIndexOf(';')); - trimmed = trimmed.substring(0, trimmed.length() - 1); - } - String upper = trimmed.toUpperCase(); - if ("EXIT".equals(upper) || "QUIT".equals(upper)) { - break; - } else if ("HELP".equals(upper) || "?".equals(upper)) { - showHelp(); - } else if ("LIST".equals(upper)) { - listMode = !listMode; - println("Result list mode is now " + (listMode ? "on" : "off")); - } else if ("HISTORY".equals(upper)) { - for (int i = 0; i < history.size(); i++) { - String s = history.get(i); - s = s.replace('\n', ' ').replace('\r', ' '); - println("#" + (1 + i) + ": " + s); - } - if (history.size() > 0) { - println("To re-run a statement, type the number and press and enter"); - } else { - println("No history"); - } - } else if (upper.startsWith("DESCRIBE")) { - String tableName = upper.substring("DESCRIBE".length()).trim(); - if (tableName.length() == 0) { - println("Usage: describe [.]"); - } else { - String schemaName = null; - int dot = tableName.indexOf('.'); - if (dot >= 0) { - schemaName = tableName.substring(0, dot); - tableName = tableName.substring(dot + 1); - } - PreparedStatement prep = null; - ResultSet rs = null; - try { - String sql = "SELECT CAST(COLUMN_NAME AS VARCHAR(32)) AS \"Column Name\", " + - "CAST(TYPE_NAME AS VARCHAR(14)) AS \"Type\", " + - "NUMERIC_PRECISION AS \"Precision\", " + - "CAST(IS_NULLABLE AS VARCHAR(8)) AS \"Nullable\", " + - "CAST(COLUMN_DEFAULT AS VARCHAR(20)) AS \"Default\" " + - "FROM INFORMATION_SCHEMA.COLUMNS " + - "WHERE UPPER(TABLE_NAME)=?"; - if (schemaName != null) { - sql += " AND UPPER(TABLE_SCHEMA)=?"; - } - sql += " ORDER BY ORDINAL_POSITION"; - prep = conn.prepareStatement(sql); - prep.setString(1, tableName.toUpperCase()); - if (schemaName != null) { - prep.setString(2, schemaName.toUpperCase()); - } - rs = prep.executeQuery(); - printResult(rs, false); - } catch (SQLException e) { - println("Exception: " + e.toString()); - e.printStackTrace(err); - } finally { - JdbcUtils.closeSilently(rs); - JdbcUtils.closeSilently(prep); - } - } - } else if (upper.startsWith("SHOW")) { - ResultSet rs = null; - try { - rs = stat.executeQuery( - "SELECT CAST(TABLE_SCHEMA AS VARCHAR(32)) AS \"Schema\", TABLE_NAME AS \"Table Name\" " + - "FROM INFORMATION_SCHEMA.TABLES ORDER BY TABLE_SCHEMA, TABLE_NAME"); - printResult(rs, false); - } catch (SQLException e) { - println("Exception: " + e.toString()); - e.printStackTrace(err); - } finally { - JdbcUtils.closeSilently(rs); - } - } else if (upper.startsWith("MAXWIDTH")) { - upper = upper.substring("MAXWIDTH".length()).trim(); - try { - maxColumnSize = Integer.parseInt(upper); - } catch (NumberFormatException e) { - println("Usage: maxwidth "); - } - println("Maximum column width is now " + maxColumnSize); - } else { - boolean addToHistory = true; - if (statement == null) { - if (isNumber(line)) { - int pos = Integer.parseInt(line); - if (pos == 0 || pos > history.size()) { - println("Not found"); - } else { - statement = history.get(pos - 1); - addToHistory = false; - println(statement); - end = true; - } - } else { - statement = line; - } - } else { - statement += "\n" + line; - } - if (end) { - if (addToHistory) { - history.add(0, statement); - if (history.size() > HISTORY_COUNT) { - history.remove(HISTORY_COUNT); - } - } - execute(statement); - statement = null; - } - } - } catch (SQLException e) { - println("SQL Exception: " + e.getMessage()); - statement = null; - } catch (IOException e) { - println(e.getMessage()); - break; - } catch (Exception e) { - println("Exception: " + e.toString()); - e.printStackTrace(err); - break; - } - } - if (conn != null) { - try { - conn.close(); - println("Connection closed"); - } catch (SQLException e) { - println("SQL Exception: " + e.getMessage()); - e.printStackTrace(err); - } - } - } - - private boolean isNumber(String s) { - if (s.length() == 0) { - return false; - } - for (char c : s.toCharArray()) { - if (!Character.isDigit(c)) { - return false; - } - } - return true; - } - - private void connect() throws IOException, SQLException { - String propertiesFileName = IOUtils.getFileInUserHome(Constants.SERVER_PROPERTIES_FILE); - String url = "jdbc:h2:~/test"; - String user = "sa"; - String driver = null; - try { - Properties prop = SortedProperties.loadProperties(propertiesFileName); - String data = null; - boolean found = false; - for (int i = 0;; i++) { - String d = prop.getProperty(String.valueOf(i)); - if (d == null) { - break; - } - found = true; - data = d; - } - if (found) { - ConnectionInfo info = new ConnectionInfo(data); - url = info.url; - user = info.user; - driver = info.driver; - } - } catch (IOException e) { - // ignore - } - println("[Enter] " + url); - print("URL "); - url = readLine(url); - if (driver == null) { - driver = JdbcUtils.getDriver(url); - } - if (driver != null) { - println("[Enter] " + driver); - } - print("Driver "); - driver = readLine(driver); - println("[Enter] " + user); - print("User "); - user = readLine(user); - println("[Enter] Hide"); - print("Password "); - String password = readLine(); - if (password.length() == 0) { - password = readPassword(); - } - conn = JdbcUtils.getConnection(driver, url, user, password); - stat = conn.createStatement(); - println("Connected"); - } - - /** - * Print the string without newline, and flush. - * - * @param s the string to print - */ - protected void print(String s) { - out.print(s); - out.flush(); - } - - private void println(String s) { - out.println(s); - out.flush(); - } - - private String readPassword() throws IOException { - try { - Method getConsole = System.class.getMethod("console"); - Object console = getConsole.invoke(null); - Method readPassword = console.getClass().getMethod("readPassword"); - print("Password "); - char[] password = (char[]) readPassword.invoke(console); - return password == null ? null : new String(password); - } catch (Exception e) { - // ignore, use the default solution - } - Thread passwordHider = new Thread(this); - stopHide = false; - passwordHider.start(); - print("Password > "); - String p = readLine(); - stopHide = true; - try { - passwordHider.join(); - } catch (InterruptedException e) { - // ignore - } - print("\b\b"); - return p; - } - - /** - * INTERNAL. - * Hides the password by repeatedly printing - * backspace, backspace, >, <. - */ - public void run() { - while (!stopHide) { - print("\b\b><"); - try { - Thread.sleep(10); - } catch (InterruptedException e) { - // ignore - } - } - } - - - private String readLine(String defaultValue) throws IOException { - String s = readLine(); - return s.length() == 0 ? defaultValue : s; - } - - private String readLine() throws IOException { - String line = reader.readLine(); - if (line == null) { - throw new IOException("Aborted"); - } - return line; - } - - private void execute(String sql) { - long time = System.currentTimeMillis(); - boolean result; - try { - result = stat.execute(sql); - } catch (SQLException e) { - println("Error: " + e.toString()); - if (listMode) { - e.printStackTrace(err); - } - return; - } - ResultSet rs = null; - try { - if (result) { - rs = stat.getResultSet(); - int rowCount = printResult(rs, listMode); - time = System.currentTimeMillis() - time; - println("(" + rowCount + (rowCount == 1 ? " row, " : " rows, ") + time + " ms)"); - } else { - int updateCount = stat.getUpdateCount(); - time = System.currentTimeMillis() - time; - println("(Update count: " + updateCount + ", " + time + " ms)"); - } - } catch (SQLException e) { - println("Error: " + e.toString()); - e.printStackTrace(err); - } finally { - JdbcUtils.closeSilently(rs); - } - } - - private int printResult(ResultSet rs, boolean asList) throws SQLException { - ResultSetMetaData meta = rs.getMetaData(); - int longest = 0; - int len = meta.getColumnCount(); - String[] columns = new String[len]; - int[] columnSizes = new int[len]; - int total = 0; - for (int i = 0; i < len; i++) { - String s = meta.getColumnLabel(i + 1); - int l = s.length(); - if (!asList) { - l = Math.max(l, meta.getColumnDisplaySize(i + 1)); - l = Math.min(maxColumnSize, l); - } - if (s.length() > l) { - s = s.substring(0, l); - } - columns[i] = s; - columnSizes[i] = l; - longest = Math.max(longest, l); - total += l; - } - StringBuilder buff = new StringBuilder(); - if (!asList) { - for (int i = 0; i < len; i++) { - if (i > 0) { - buff.append(boxVertical); - } - String s = columns[i]; - buff.append(s); - if (i < len - 1) { - for (int j = s.length(); j < columnSizes[i]; j++) { - buff.append(' '); - } - } - } - println(buff.toString()); - } - boolean truncated = false; - int rowCount = 0; - while (rs.next()) { - rowCount++; - buff.setLength(0); - if (asList) { - if (rowCount > 1) { - println(""); - } - for (int i = 0; i < len; i++) { - if (i > 0) { - buff.append('\n'); - } - String label = columns[i]; - buff.append(label); - for (int j = label.length(); j < longest; j++) { - buff.append(' '); - } - buff.append(": ").append(rs.getString(i + 1)); - } - } else { - for (int i = 0; i < len; i++) { - if (i > 0) { - buff.append(boxVertical); - } - String s = rs.getString(i + 1); - if (s == null) { - s = "null"; - } - int m = columnSizes[i]; - // only truncate if more than once column - if (len > 1 && !asList && s.length() > m) { - s = s.substring(0, m); - truncated = true; - } - buff.append(s); - if (i < len - 1) { - for (int j = s.length(); j < m; j++) { - buff.append(' '); - } - } - } - } - println(buff.toString()); - } - if (rowCount == 0 && asList) { - for (String label : columns) { - buff.append(label).append('\n'); - } - println(buff.toString()); - } - if (truncated) { - println("(data is partially truncated)"); - } - return rowCount; - } - -} diff --git a/tools/h2/src/main/org/h2/tools/SimpleResultSet.java b/tools/h2/src/main/org/h2/tools/SimpleResultSet.java deleted file mode 100755 index 4afe6f7..0000000 --- a/tools/h2/src/main/org/h2/tools/SimpleResultSet.java +++ /dev/null @@ -1,2121 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.tools; - -import java.io.InputStream; -import java.io.Reader; -import java.math.BigDecimal; -import java.net.URL; -import java.sql.Array; -import java.sql.Blob; -import java.sql.Clob; -import java.sql.Date; -import java.sql.Ref; -import java.sql.ResultSet; -import java.sql.ResultSetMetaData; -import java.sql.SQLException; -import java.sql.SQLWarning; -import java.sql.Statement; -import java.sql.Time; -import java.sql.Timestamp; -import java.sql.Types; -import java.util.ArrayList; -import java.util.Calendar; -import java.util.Map; -import org.h2.constant.ErrorCode; -import org.h2.message.DbException; -import org.h2.util.New; - -/*## Java 1.6 begin ## -import java.sql.NClob; -import java.sql.RowId; -import java.sql.SQLXML; -## Java 1.6 end ##*/ - -/** - * This class is a simple result set and meta data implementation. - * It can be used in Java functions that return a result set. - * Only the most basic methods are implemented, the others throw an exception. - * This implementation is standalone, and only relies on standard classes. - * It can be extended easily if required. - * - * An application can create a result set using the following code: - * - *
- * SimpleResultSet rs = new SimpleResultSet();
- * rs.addColumn("ID", Types.INTEGER, 10, 0);
- * rs.addColumn("NAME", Types.VARCHAR, 255, 0);
- * rs.addRow(0, "Hello" });
- * rs.addRow(1, "World" });
- * 
- * - */ -public class SimpleResultSet implements ResultSet, ResultSetMetaData { - - private ArrayList rows; - private Object[] currentRow; - private int rowId = -1; - private boolean wasNull; - private SimpleRowSource source; - private ArrayList columns = New.arrayList(); - - /** - * This class holds the data of a result column. - */ - static class Column { - - /** - * The column label. - */ - String name; - - /** - * The SQL type. - */ - int sqlType; - - /** - * The precision. - */ - int precision; - - /** - * The scale. - */ - int scale; - } - - /** - * A simple array implementation, - * backed by an object array - */ - public static class SimpleArray implements Array { - - private Object[] value; - - SimpleArray(Object[] value) { - this.value = value; - } - - /** - * Get the object array. - * - * @return the object array - */ - public Object getArray() { - return value; - } - - /** - * INTERNAL - */ - public Object getArray(Map> map) throws SQLException { - throw getUnsupportedException(); - } - - /** - * INTERNAL - */ - public Object getArray(long index, int count) throws SQLException { - throw getUnsupportedException(); - } - - /** - * INTERNAL - */ - public Object getArray(long index, int count, Map> map) throws SQLException { - throw getUnsupportedException(); - } - - /** - * Get the base type of this array. - * - * @return Types.NULL - */ - public int getBaseType() { - return Types.NULL; - } - - /** - * Get the base type name of this array. - * - * @return "NULL" - */ - public String getBaseTypeName() { - return "NULL"; - } - - /** - * INTERNAL - */ - public ResultSet getResultSet() throws SQLException { - throw getUnsupportedException(); - } - - /** - * INTERNAL - */ - public ResultSet getResultSet(Map> map) throws SQLException { - throw getUnsupportedException(); - } - - /** - * INTERNAL - */ - public ResultSet getResultSet(long index, int count) throws SQLException { - throw getUnsupportedException(); - } - - /** - * INTERNAL - */ - public ResultSet getResultSet(long index, int count, Map> map) throws SQLException { - throw getUnsupportedException(); - } - - /** - * INTERNAL - */ - public void free() { - // nothing to do - } - - } - - /** - * This constructor is used if the result set is later populated with addRow. - */ - public SimpleResultSet() { - rows = New.arrayList(); - } - - /** - * This constructor is used if the result set should retrieve the rows using - * the specified row source object. - * - * @param source the row source - */ - public SimpleResultSet(SimpleRowSource source) { - this.source = source; - } - - /** - * Adds a column to the result set. - * All columns must be added before adding rows. - * - * @param name null is replaced with C1, C2,... - * @param sqlType the value returned in getColumnType(..) (ignored internally) - * @param precision the precision - * @param scale the scale - */ - public void addColumn(String name, int sqlType, int precision, int scale) { - if (rows != null && rows.size() > 0) { - throw new IllegalStateException("Cannot add a column after adding rows"); - } - if (name == null) { - name = "C" + (columns.size() + 1); - } - Column column = new Column(); - column.name = name; - column.sqlType = sqlType; - column.precision = precision; - column.scale = scale; - columns.add(column); - } - - /** - * Add a new row to the result set. - * Do not use this method when using a RowSource. - * - * @param row the row as an array of objects - */ - public void addRow(Object... row) { - if (rows == null) { - throw new IllegalStateException("Cannot add a row when using RowSource"); - } - rows.add(row); - } - - /** - * Returns ResultSet.CONCUR_READ_ONLY. - * - * @return CONCUR_READ_ONLY - */ - public int getConcurrency() { - return ResultSet.CONCUR_READ_ONLY; - } - - /** - * Returns ResultSet.FETCH_FORWARD. - * - * @return FETCH_FORWARD - */ - public int getFetchDirection() { - return ResultSet.FETCH_FORWARD; - } - - /** - * Returns 0. - * - * @return 0 - */ - public int getFetchSize() { - return 0; - } - - /** - * Returns the row number (1, 2,...) or 0 for no row. - * - * @return 0 - */ - public int getRow() { - return rowId + 1; - } - - /** - * Returns ResultSet.TYPE_FORWARD_ONLY. - * - * @return TYPE_FORWARD_ONLY - */ - public int getType() { - return ResultSet.TYPE_FORWARD_ONLY; - } - - /** - * Closes the result set and releases the resources. - */ - public void close() { - currentRow = null; - rows = null; - columns = null; - rowId = -1; - if (source != null) { - source.close(); - source = null; - } - } - - /** - * Moves the cursor to the next row of the result set. - * - * @return true if successful, false if there are no more rows - */ - public boolean next() throws SQLException { - if (source != null) { - rowId++; - currentRow = source.readRow(); - if (currentRow != null) { - return true; - } - } else if (rows != null && rowId < rows.size()) { - rowId++; - if (rowId < rows.size()) { - currentRow = rows.get(rowId); - return true; - } - } - close(); - return false; - } - - /** - * Moves the current position to before the first row, that means resets the - * result set. - */ - public void beforeFirst() throws SQLException { - rowId = -1; - if (source != null) { - source.reset(); - } - } - - /** - * Returns whether the last column accessed was null. - * - * @return true if the last column accessed was null - */ - public boolean wasNull() { - return wasNull; - } - - /** - * Returns the value as a byte. - * - * @param columnIndex (1,2,...) - * @return the value - */ - public byte getByte(int columnIndex) throws SQLException { - Object o = get(columnIndex); - if (o != null && !(o instanceof Number)) { - o = Byte.decode(o.toString()); - } - return o == null ? 0 : ((Number) o).byteValue(); - } - - /** - * Returns the value as an double. - * - * @param columnIndex (1,2,...) - * @return the value - */ - public double getDouble(int columnIndex) throws SQLException { - Object o = get(columnIndex); - if (o != null && !(o instanceof Number)) { - return Double.parseDouble(o.toString()); - } - return o == null ? 0 : ((Number) o).doubleValue(); - } - - /** - * Returns the value as a float. - * - * @param columnIndex (1,2,...) - * @return the value - */ - public float getFloat(int columnIndex) throws SQLException { - Object o = get(columnIndex); - if (o != null && !(o instanceof Number)) { - return Float.parseFloat(o.toString()); - } - return o == null ? 0 : ((Number) o).floatValue(); - } - - /** - * Returns the value as an int. - * - * @param columnIndex (1,2,...) - * @return the value - */ - public int getInt(int columnIndex) throws SQLException { - Object o = get(columnIndex); - if (o != null && !(o instanceof Number)) { - o = Integer.decode(o.toString()); - } - return o == null ? 0 : ((Number) o).intValue(); - } - - /** - * Returns the value as a long. - * - * @param columnIndex (1,2,...) - * @return the value - */ - public long getLong(int columnIndex) throws SQLException { - Object o = get(columnIndex); - if (o != null && !(o instanceof Number)) { - o = Long.decode(o.toString()); - } - return o == null ? 0 : ((Number) o).longValue(); - } - - /** - * Returns the value as a short. - * - * @param columnIndex (1,2,...) - * @return the value - */ - public short getShort(int columnIndex) throws SQLException { - Object o = get(columnIndex); - if (o != null && !(o instanceof Number)) { - o = Short.decode(o.toString()); - } - return o == null ? 0 : ((Number) o).shortValue(); - } - - /** - * Returns the value as a boolean. - * - * @param columnIndex (1,2,...) - * @return the value - */ - public boolean getBoolean(int columnIndex) throws SQLException { - Object o = get(columnIndex); - if (o != null && !(o instanceof Boolean)) { - o = Boolean.valueOf(o.toString()); - } - return o == null ? false : ((Boolean) o).booleanValue(); - } - - /** - * Returns the value as a byte array. - * - * @param columnIndex (1,2,...) - * @return the value - */ - public byte[] getBytes(int columnIndex) throws SQLException { - return (byte[]) get(columnIndex); - } - - /** - * Returns the value as an Object. - * - * @param columnIndex (1,2,...) - * @return the value - */ - public Object getObject(int columnIndex) throws SQLException { - return get(columnIndex); - } - - /** - * Returns the value as a String. - * - * @param columnIndex (1,2,...) - * @return the value - */ - public String getString(int columnIndex) throws SQLException { - Object o = get(columnIndex); - return o == null ? null : o.toString(); - } - - /** - * Returns the value as a byte. - * - * @param columnLabel the column label - * @return the value - */ - public byte getByte(String columnLabel) throws SQLException { - return getByte(findColumn(columnLabel)); - } - - /** - * Returns the value as a double. - * - * @param columnLabel the column label - * @return the value - */ - public double getDouble(String columnLabel) throws SQLException { - return getDouble(findColumn(columnLabel)); - } - - /** - * Returns the value as a float. - * - * @param columnLabel the column label - * @return the value - */ - public float getFloat(String columnLabel) throws SQLException { - return getFloat(findColumn(columnLabel)); - } - - /** - * Searches for a specific column in the result set. A case-insensitive - * search is made. - * - * @param columnLabel the column label - * @return the column index (1,2,...) - * @throws SQLException if the column is not found or if the result set is - * closed - */ - public int findColumn(String columnLabel) throws SQLException { - for (int i = 0; columnLabel != null && columns != null && i < columns.size(); i++) { - if (columnLabel.equalsIgnoreCase(getColumn(i).name)) { - return i + 1; - } - } - throw DbException.get(ErrorCode.COLUMN_NOT_FOUND_1, columnLabel).getSQLException(); - } - - /** - * Returns the value as an int. - * - * @param columnLabel the column label - * @return the value - */ - public int getInt(String columnLabel) throws SQLException { - return getInt(findColumn(columnLabel)); - } - - /** - * Returns the value as a long. - * - * @param columnLabel the column label - * @return the value - */ - public long getLong(String columnLabel) throws SQLException { - return getLong(findColumn(columnLabel)); - } - - /** - * Returns the value as a short. - * - * @param columnLabel the column label - * @return the value - */ - public short getShort(String columnLabel) throws SQLException { - return getShort(findColumn(columnLabel)); - } - - /** - * Returns the value as a boolean. - * - * @param columnLabel the column label - * @return the value - */ - public boolean getBoolean(String columnLabel) throws SQLException { - return getBoolean(findColumn(columnLabel)); - } - - /** - * Returns the value as a byte array. - * - * @param columnLabel the column label - * @return the value - */ - public byte[] getBytes(String columnLabel) throws SQLException { - return getBytes(findColumn(columnLabel)); - } - - /** - * Returns the value as a java.math.BigDecimal. - * - * @param columnIndex (1,2,...) - * @return the value - */ - public BigDecimal getBigDecimal(int columnIndex) throws SQLException { - Object o = get(columnIndex); - if (o != null && !(o instanceof BigDecimal)) { - o = new BigDecimal(o.toString()); - } - return (BigDecimal) o; - } - - /** - * Returns the value as an java.sql.Date. - * - * @param columnIndex (1,2,...) - * @return the value - */ - public Date getDate(int columnIndex) throws SQLException { - return (Date) get(columnIndex); - } - - /** - * Returns a reference to itself. - * - * @return this - */ - public ResultSetMetaData getMetaData() { - return this; - } - - /** - * Returns null. - * - * @return null - */ - public SQLWarning getWarnings() { - return null; - } - - /** - * Returns null. - * - * @return null - */ - public Statement getStatement() { - return null; - } - - /** - * Returns the value as an java.sql.Time. - * - * @param columnIndex (1,2,...) - * @return the value - */ - public Time getTime(int columnIndex) throws SQLException { - return (Time) get(columnIndex); - } - - /** - * Returns the value as an java.sql.Timestamp. - * - * @param columnIndex (1,2,...) - * @return the value - */ - public Timestamp getTimestamp(int columnIndex) throws SQLException { - return (Timestamp) get(columnIndex); - } - - /** - * Returns the value as a java.sql.Array. - * - * @param columnIndex (1,2,...) - * @return the value - */ - public Array getArray(int columnIndex) throws SQLException { - return new SimpleArray((Object[]) get(columnIndex)); - } - - /** - * Returns the value as an Object. - * - * @param columnLabel the column label - * @return the value - */ - public Object getObject(String columnLabel) throws SQLException { - return getObject(findColumn(columnLabel)); - } - - /** - * Returns the value as a String. - * - * @param columnLabel the column label - * @return the value - */ - public String getString(String columnLabel) throws SQLException { - return getString(findColumn(columnLabel)); - } - - /** - * Returns the value as a java.math.BigDecimal. - * - * @param columnLabel the column label - * @return the value - */ - public BigDecimal getBigDecimal(String columnLabel) throws SQLException { - return getBigDecimal(findColumn(columnLabel)); - } - - /** - * Returns the value as a java.sql.Date. - * - * @param columnLabel the column label - * @return the value - */ - public Date getDate(String columnLabel) throws SQLException { - return getDate(findColumn(columnLabel)); - } - - /** - * Returns the value as a java.sql.Time. - * - * @param columnLabel the column label - * @return the value - */ - public Time getTime(String columnLabel) throws SQLException { - return getTime(findColumn(columnLabel)); - } - - /** - * Returns the value as a java.sql.Timestamp. - * - * @param columnLabel the column label - * @return the value - */ - public Timestamp getTimestamp(String columnLabel) throws SQLException { - return getTimestamp(findColumn(columnLabel)); - } - - /** - * Returns the value as a java.sql.Array. - * - * @param columnLabel the column label - * @return the value - */ - public Array getArray(String columnLabel) throws SQLException { - return getArray(findColumn(columnLabel)); - } - - - // ---- result set meta data --------------------------------------------- - - /** - * Returns the column count. - * - * @return the column count - */ - public int getColumnCount() { - return columns.size(); - } - - /** - * Returns 15. - * - * @param columnIndex (1,2,...) - * @return 15 - */ - public int getColumnDisplaySize(int columnIndex) { - return 15; - } - - /** - * Returns the SQL type. - * - * @param columnIndex (1,2,...) - * @return the SQL type - */ - public int getColumnType(int columnIndex) throws SQLException { - return getColumn(columnIndex - 1).sqlType; - } - - /** - * Returns the precision. - * - * @param columnIndex (1,2,...) - * @return the precision - */ - public int getPrecision(int columnIndex) throws SQLException { - return getColumn(columnIndex - 1).precision; - } - - /** - * Returns the scale. - * - * @param columnIndex (1,2,...) - * @return the scale - */ - public int getScale(int columnIndex) throws SQLException { - return getColumn(columnIndex - 1).scale; - } - - /** - * Returns ResultSetMetaData.columnNullableUnknown. - * - * @param columnIndex (1,2,...) - * @return columnNullableUnknown - */ - public int isNullable(int columnIndex) { - return ResultSetMetaData.columnNullableUnknown; - } - - /** - * Returns false. - * - * @param columnIndex (1,2,...) - * @return false - */ - public boolean isAutoIncrement(int columnIndex) { - return false; - } - - /** - * Returns true. - * - * @param columnIndex (1,2,...) - * @return true - */ - public boolean isCaseSensitive(int columnIndex) { - return true; - } - - /** - * Returns false. - * - * @param columnIndex (1,2,...) - * @return false - */ - public boolean isCurrency(int columnIndex) { - return false; - } - - /** - * Returns false. - * - * @param columnIndex (1,2,...) - * @return false - */ - public boolean isDefinitelyWritable(int columnIndex) { - return false; - } - - /** - * Returns true. - * - * @param columnIndex (1,2,...) - * @return true - */ - public boolean isReadOnly(int columnIndex) { - return true; - } - - /** - * Returns true. - * - * @param columnIndex (1,2,...) - * @return true - */ - public boolean isSearchable(int columnIndex) { - return true; - } - - /** - * Returns true. - * - * @param columnIndex (1,2,...) - * @return true - */ - public boolean isSigned(int columnIndex) { - return true; - } - - /** - * Returns false. - * - * @param columnIndex (1,2,...) - * @return false - */ - public boolean isWritable(int columnIndex) { - return false; - } - - /** - * Returns null. - * - * @param columnIndex (1,2,...) - * @return null - */ - public String getCatalogName(int columnIndex) { - return null; - } - - /** - * Returns null. - * - * @param columnIndex (1,2,...) - * @return null - */ - public String getColumnClassName(int columnIndex) { - return null; - } - - /** - * Returns the column label. - * - * @param columnIndex (1,2,...) - * @return the column label - */ - public String getColumnLabel(int columnIndex) throws SQLException { - return getColumn(columnIndex - 1).name; - } - - /** - * Returns the column name. - * - * @param columnIndex (1,2,...) - * @return the column name - */ - public String getColumnName(int columnIndex) throws SQLException { - return getColumnLabel(columnIndex); - } - - /** - * Returns null. - * - * @param columnIndex (1,2,...) - * @return null - */ - public String getColumnTypeName(int columnIndex) { - return null; - } - - /** - * Returns null. - * - * @param columnIndex (1,2,...) - * @return null - */ - public String getSchemaName(int columnIndex) { - return null; - } - - /** - * Returns null. - * - * @param columnIndex (1,2,...) - * @return null - */ - public String getTableName(int columnIndex) { - return null; - } - - // ---- unsupported / result set --------------------------------------------- - - /** - * INTERNAL - */ - public void clearWarnings() { - // nothing to do - } - - /** - * INTERNAL - */ - public void afterLast() throws SQLException { - throw getUnsupportedException(); - } - - /** - * INTERNAL - */ - public void cancelRowUpdates() throws SQLException { - throw getUnsupportedException(); - } - - /** - * INTERNAL - */ - public void updateNull(String columnLabel) throws SQLException { - throw getUnsupportedException(); - } - - /** - * INTERNAL - */ - public void deleteRow() throws SQLException { - throw getUnsupportedException(); - } - - /** - * INTERNAL - */ - public void insertRow() throws SQLException { - throw getUnsupportedException(); - } - - /** - * INTERNAL - */ - public void moveToCurrentRow() throws SQLException { - throw getUnsupportedException(); - } - - /** - * INTERNAL - */ - public void moveToInsertRow() throws SQLException { - throw getUnsupportedException(); - } - - /** - * INTERNAL - */ - public void refreshRow() throws SQLException { - throw getUnsupportedException(); - } - - /** - * INTERNAL - */ - public void updateRow() throws SQLException { - throw getUnsupportedException(); - } - - /** - * INTERNAL - */ - public boolean first() throws SQLException { - throw getUnsupportedException(); - } - - /** - * INTERNAL - */ - public boolean isAfterLast() throws SQLException { - throw getUnsupportedException(); - } - - /** - * INTERNAL - */ - public boolean isBeforeFirst() throws SQLException { - throw getUnsupportedException(); - } - - /** - * INTERNAL - */ - public boolean isFirst() throws SQLException { - throw getUnsupportedException(); - } - - /** - * INTERNAL - */ - public boolean isLast() throws SQLException { - throw getUnsupportedException(); - } - - /** - * INTERNAL - */ - public boolean last() throws SQLException { - throw getUnsupportedException(); - } - - /** - * INTERNAL - */ - public boolean previous() throws SQLException { - throw getUnsupportedException(); - } - - /** - * INTERNAL - */ - public boolean rowDeleted() throws SQLException { - throw getUnsupportedException(); - } - - /** - * INTERNAL - */ - public boolean rowInserted() throws SQLException { - throw getUnsupportedException(); - } - - /** - * INTERNAL - */ - public boolean rowUpdated() throws SQLException { - throw getUnsupportedException(); - } - - /** - * INTERNAL - */ - public void setFetchDirection(int direction) throws SQLException { - throw getUnsupportedException(); - } - - /** - * INTERNAL - */ - public void setFetchSize(int rows) throws SQLException { - throw getUnsupportedException(); - } - - /** - * INTERNAL - */ - public void updateNull(int columnIndex) throws SQLException { - throw getUnsupportedException(); - } - - /** - * INTERNAL - */ - public boolean absolute(int row) throws SQLException { - throw getUnsupportedException(); - } - - /** - * INTERNAL - */ - public boolean relative(int offset) throws SQLException { - throw getUnsupportedException(); - } - - /** - * INTERNAL - */ - public void updateByte(int columnIndex, byte x) throws SQLException { - throw getUnsupportedException(); - } - - /** - * INTERNAL - */ - public void updateDouble(int columnIndex, double x) throws SQLException { - throw getUnsupportedException(); - } - - /** - * INTERNAL - */ - public void updateFloat(int columnIndex, float x) throws SQLException { - throw getUnsupportedException(); - } - - /** - * INTERNAL - */ - public void updateInt(int columnIndex, int x) throws SQLException { - throw getUnsupportedException(); - } - - /** - * INTERNAL - */ - public void updateLong(int columnIndex, long x) throws SQLException { - throw getUnsupportedException(); - } - - /** - * INTERNAL - */ - public void updateShort(int columnIndex, short x) throws SQLException { - throw getUnsupportedException(); - } - - /** - * INTERNAL - */ - public void updateBoolean(int columnIndex, boolean x) throws SQLException { - throw getUnsupportedException(); - } - - /** - * INTERNAL - */ - public void updateBytes(int columnIndex, byte[] x) throws SQLException { - throw getUnsupportedException(); - } - - /** - * INTERNAL - */ - public InputStream getAsciiStream(int columnIndex) { - return null; - } - - /** - * INTERNAL - */ - public InputStream getBinaryStream(int columnIndex) { - return null; - } - - /** - * @deprecated INTERNAL - */ - public InputStream getUnicodeStream(int columnIndex) { - return null; - } - - /** - * INTERNAL - */ - public void updateAsciiStream(int columnIndex, InputStream x, int length) throws SQLException { - throw getUnsupportedException(); - } - - /** - * INTERNAL - */ - public void updateBinaryStream(int columnIndex, InputStream x, int length) throws SQLException { - throw getUnsupportedException(); - } - - /** - * INTERNAL - */ - public Reader getCharacterStream(int columnIndex) throws SQLException { - throw getUnsupportedException(); - } - - /** - * INTERNAL - */ - public void updateCharacterStream(int columnIndex, Reader x, int length) throws SQLException { - throw getUnsupportedException(); - } - - /** - * INTERNAL - */ - public void updateObject(int columnIndex, Object x) throws SQLException { - throw getUnsupportedException(); - } - - /** - * INTERNAL - */ - public void updateObject(int columnIndex, Object x, int scale) throws SQLException { - throw getUnsupportedException(); - } - - /** - * INTERNAL - */ - public String getCursorName() throws SQLException { - throw getUnsupportedException(); - } - - /** - * INTERNAL - */ - public void updateString(int columnIndex, String x) throws SQLException { - throw getUnsupportedException(); - } - - /** - * INTERNAL - */ - public void updateByte(String columnLabel, byte x) throws SQLException { - throw getUnsupportedException(); - } - - /** - * INTERNAL - */ - public void updateDouble(String columnLabel, double x) throws SQLException { - throw getUnsupportedException(); - } - - /** - * INTERNAL - */ - public void updateFloat(String columnLabel, float x) throws SQLException { - throw getUnsupportedException(); - } - - /** - * INTERNAL - */ - public void updateInt(String columnLabel, int x) throws SQLException { - throw getUnsupportedException(); - } - - /** - * INTERNAL - */ - public void updateLong(String columnLabel, long x) throws SQLException { - throw getUnsupportedException(); - } - - /** - * INTERNAL - */ - public void updateShort(String columnLabel, short x) throws SQLException { - throw getUnsupportedException(); - } - - /** - * INTERNAL - */ - public void updateBoolean(String columnLabel, boolean x) throws SQLException { - throw getUnsupportedException(); - } - - /** - * INTERNAL - */ - public void updateBytes(String columnLabel, byte[] x) throws SQLException { - throw getUnsupportedException(); - } - - /** - * @deprecated INTERNAL - */ - public BigDecimal getBigDecimal(int columnIndex, int scale) throws SQLException { - throw getUnsupportedException(); - } - - /** - * INTERNAL - */ - public void updateBigDecimal(int columnIndex, BigDecimal x) throws SQLException { - throw getUnsupportedException(); - } - - /** - * INTERNAL - */ - public URL getURL(int columnIndex) throws SQLException { - throw getUnsupportedException(); - } - - /** - * INTERNAL - */ - public void updateArray(int columnIndex, Array x) throws SQLException { - throw getUnsupportedException(); - } - - /** - * INTERNAL - */ - public Blob getBlob(int i) throws SQLException { - throw getUnsupportedException(); - } - - /** - * INTERNAL - */ - public void updateBlob(int columnIndex, Blob x) throws SQLException { - throw getUnsupportedException(); - } - - /** - * INTERNAL - */ - public Clob getClob(int i) throws SQLException { - throw getUnsupportedException(); - } - - /** - * INTERNAL - */ - public void updateClob(int columnIndex, Clob x) throws SQLException { - throw getUnsupportedException(); - } - - /** - * INTERNAL - */ - public void updateDate(int columnIndex, Date x) throws SQLException { - throw getUnsupportedException(); - } - - /** - * INTERNAL - */ - public Ref getRef(int i) throws SQLException { - throw getUnsupportedException(); - } - - /** - * INTERNAL - */ - public void updateRef(int columnIndex, Ref x) throws SQLException { - throw getUnsupportedException(); - } - - /** - * INTERNAL - */ - public void updateTime(int columnIndex, Time x) throws SQLException { - throw getUnsupportedException(); - } - - /** - * INTERNAL - */ - public void updateTimestamp(int columnIndex, Timestamp x) throws SQLException { - throw getUnsupportedException(); - } - - /** - * INTERNAL - */ - public InputStream getAsciiStream(String columnLabel) throws SQLException { - throw getUnsupportedException(); - } - - /** - * INTERNAL - */ - public InputStream getBinaryStream(String columnLabel) throws SQLException { - throw getUnsupportedException(); - } - - /** - * @deprecated INTERNAL - */ - public InputStream getUnicodeStream(String columnLabel) throws SQLException { - throw getUnsupportedException(); - } - - /** - * INTERNAL - */ - public void updateAsciiStream(String columnLabel, InputStream x, int length) throws SQLException { - throw getUnsupportedException(); - } - - /** - * INTERNAL - */ - public void updateBinaryStream(String columnLabel, InputStream x, int length) throws SQLException { - throw getUnsupportedException(); - } - - /** - * INTERNAL - */ - public Reader getCharacterStream(String columnLabel) throws SQLException { - throw getUnsupportedException(); - } - - /** - * INTERNAL - */ - public void updateCharacterStream(String columnLabel, Reader reader, int length) throws SQLException { - throw getUnsupportedException(); - } - - /** - * INTERNAL - */ - public void updateObject(String columnLabel, Object x) throws SQLException { - throw getUnsupportedException(); - } - - /** - * INTERNAL - */ - public void updateObject(String columnLabel, Object x, int scale) throws SQLException { - throw getUnsupportedException(); - } - - /** - * INTERNAL - */ - public Object getObject(int i, Map> map) throws SQLException { - throw getUnsupportedException(); - } - - /** - * INTERNAL - */ - public void updateString(String columnLabel, String x) throws SQLException { - throw getUnsupportedException(); - } - - /** - * @deprecated INTERNAL - */ - public BigDecimal getBigDecimal(String columnLabel, int scale) throws SQLException { - throw getUnsupportedException(); - } - - /** - * INTERNAL - */ - public void updateBigDecimal(String columnLabel, BigDecimal x) throws SQLException { - throw getUnsupportedException(); - } - - /** - * INTERNAL - */ - public URL getURL(String columnLabel) throws SQLException { - throw getUnsupportedException(); - } - - /** - * INTERNAL - */ - public void updateArray(String columnLabel, Array x) throws SQLException { - throw getUnsupportedException(); - } - - /** - * INTERNAL - */ - public Blob getBlob(String colName) throws SQLException { - throw getUnsupportedException(); - } - - /** - * INTERNAL - */ - public void updateBlob(String columnLabel, Blob x) throws SQLException { - throw getUnsupportedException(); - } - - /** - * INTERNAL - */ - public Clob getClob(String colName) throws SQLException { - throw getUnsupportedException(); - } - - /** - * INTERNAL - */ - public void updateClob(String columnLabel, Clob x) throws SQLException { - throw getUnsupportedException(); - } - - /** - * INTERNAL - */ - public void updateDate(String columnLabel, Date x) throws SQLException { - throw getUnsupportedException(); - } - - /** - * INTERNAL - */ - public Date getDate(int columnIndex, Calendar cal) throws SQLException { - throw getUnsupportedException(); - } - - /** - * INTERNAL - */ - public Ref getRef(String colName) throws SQLException { - throw getUnsupportedException(); - } - - /** - * INTERNAL - */ - public void updateRef(String columnLabel, Ref x) throws SQLException { - throw getUnsupportedException(); - } - - /** - * INTERNAL - */ - public void updateTime(String columnLabel, Time x) throws SQLException { - throw getUnsupportedException(); - } - - /** - * INTERNAL - */ - public Time getTime(int columnIndex, Calendar cal) throws SQLException { - throw getUnsupportedException(); - } - - /** - * INTERNAL - */ - public void updateTimestamp(String columnLabel, Timestamp x) throws SQLException { - throw getUnsupportedException(); - } - - /** - * INTERNAL - */ - public Timestamp getTimestamp(int columnIndex, Calendar cal) throws SQLException { - throw getUnsupportedException(); - } - - /** - * INTERNAL - */ - public Object getObject(String colName, Map> map) throws SQLException { - throw getUnsupportedException(); - } - - /** - * INTERNAL - */ - public Date getDate(String columnLabel, Calendar cal) throws SQLException { - throw getUnsupportedException(); - } - - /** - * INTERNAL - */ - public Time getTime(String columnLabel, Calendar cal) throws SQLException { - throw getUnsupportedException(); - } - - /** - * INTERNAL - */ - public Timestamp getTimestamp(String columnLabel, Calendar cal) throws SQLException { - throw getUnsupportedException(); - } - - // --- private ----------------------------- - - /** - * INTERNAL - */ - static SQLException getUnsupportedException() { - return DbException.get(ErrorCode.FEATURE_NOT_SUPPORTED_1).getSQLException(); - } - - private void checkColumnIndex(int columnIndex) throws SQLException { - if (columnIndex < 0 || columnIndex >= columns.size()) { - throw DbException.getInvalidValueException("" + columnIndex, "columnIndex").getSQLException(); - } - } - - private Object get(int columnIndex) throws SQLException { - if (currentRow == null) { - throw DbException.get(ErrorCode.NO_DATA_AVAILABLE).getSQLException(); - } - columnIndex--; - checkColumnIndex(columnIndex); - Object o = columnIndex < currentRow.length ? currentRow[columnIndex] : null; - wasNull = o == null; - return o; - } - - private Column getColumn(int i) throws SQLException { - checkColumnIndex(i); - return columns.get(i); - } - - /** - * INTERNAL - */ -/*## Java 1.6 begin ## - public RowId getRowId(int columnIndex) throws SQLException { - throw getUnsupportedException(); - } -## Java 1.6 end ##*/ - - /** - * INTERNAL - */ -/*## Java 1.6 begin ## - public RowId getRowId(String columnLabel) throws SQLException { - throw getUnsupportedException(); - } -## Java 1.6 end ##*/ - - /** - * INTERNAL - */ -/*## Java 1.6 begin ## - public void updateRowId(int columnIndex, RowId x) throws SQLException { - throw getUnsupportedException(); - } -## Java 1.6 end ##*/ - - /** - * INTERNAL - */ -/*## Java 1.6 begin ## - public void updateRowId(String columnLabel, RowId x) throws SQLException { - throw getUnsupportedException(); - } -## Java 1.6 end ##*/ - - /** - * Returns the current result set holdability. - * - * @return the holdability - */ -//## Java 1.4 begin ## - public int getHoldability() { - return ResultSet.HOLD_CURSORS_OVER_COMMIT; - } -//## Java 1.4 end ## - - /** - * Returns whether this result set has been closed. - * - * @return true if the result set was closed - */ - public boolean isClosed() { - return rows == null; - } - - /** - * INTERNAL - */ -/*## Java 1.6 begin ## - public void updateNString(int columnIndex, String nString) - throws SQLException { - throw getUnsupportedException(); - } -## Java 1.6 end ##*/ - - /** - * INTERNAL - */ -/*## Java 1.6 begin ## - public void updateNString(String columnLabel, String nString) - throws SQLException { - throw getUnsupportedException(); - } -## Java 1.6 end ##*/ - - /** - * INTERNAL - */ -/*## Java 1.6 begin ## - public void updateNClob(int columnIndex, NClob nClob) - throws SQLException { - throw getUnsupportedException(); - } -## Java 1.6 end ##*/ - - /** - * INTERNAL - */ -/*## Java 1.6 begin ## - public void updateNClob(String columnLabel, NClob nClob) - throws SQLException { - throw getUnsupportedException(); - } -## Java 1.6 end ##*/ - - /** - * INTERNAL - */ -/*## Java 1.6 begin ## - public NClob getNClob(int columnIndex) throws SQLException { - throw getUnsupportedException(); - } -## Java 1.6 end ##*/ - - /** - * INTERNAL - */ -/*## Java 1.6 begin ## - public NClob getNClob(String columnLabel) throws SQLException { - throw getUnsupportedException(); - } -## Java 1.6 end ##*/ - - /** - * INTERNAL - */ -/*## Java 1.6 begin ## - public SQLXML getSQLXML(int columnIndex) throws SQLException { - throw getUnsupportedException(); - } -## Java 1.6 end ##*/ - - /** - * INTERNAL - */ -/*## Java 1.6 begin ## - public SQLXML getSQLXML(String columnLabel) throws SQLException { - throw getUnsupportedException(); - } -## Java 1.6 end ##*/ - - /** - * INTERNAL - */ -/*## Java 1.6 begin ## - public void updateSQLXML(int columnIndex, SQLXML xmlObject) - throws SQLException { - throw getUnsupportedException(); - } -## Java 1.6 end ##*/ - - /** - * INTERNAL - */ -/*## Java 1.6 begin ## - public void updateSQLXML(String columnLabel, SQLXML xmlObject) - throws SQLException { - throw getUnsupportedException(); - } -## Java 1.6 end ##*/ - - /** - * INTERNAL - */ -/*## Java 1.6 begin ## - public String getNString(int columnIndex) throws SQLException { - return getString(columnIndex); - } -## Java 1.6 end ##*/ - - /** - * INTERNAL - */ -/*## Java 1.6 begin ## - public String getNString(String columnLabel) throws SQLException { - return getString(columnLabel); - } -## Java 1.6 end ##*/ - - /** - * INTERNAL - */ -/*## Java 1.6 begin ## - public Reader getNCharacterStream(int columnIndex) throws SQLException { - throw getUnsupportedException(); - } -## Java 1.6 end ##*/ - - /** - * INTERNAL - */ -/*## Java 1.6 begin ## - public Reader getNCharacterStream(String columnLabel) - throws SQLException { - throw getUnsupportedException(); - } -## Java 1.6 end ##*/ - - /** - * INTERNAL - */ -/*## Java 1.6 begin ## - public T unwrap(Class iface) throws SQLException { - throw getUnsupportedException(); - } -## Java 1.6 end ##*/ - - /** - * INTERNAL - */ -/*## Java 1.6 begin ## - public boolean isWrapperFor(Class< ? > iface) throws SQLException { - throw getUnsupportedException(); - } -## Java 1.6 end ##*/ - - /** - * INTERNAL - */ -/*## Java 1.6 begin ## - public void updateAsciiStream(int columnIndex, InputStream x) - throws SQLException { - throw getUnsupportedException(); - } -## Java 1.6 end ##*/ - - /** - * INTERNAL - */ -/*## Java 1.6 begin ## - public void updateAsciiStream(String columnLabel, InputStream x) - throws SQLException { - throw getUnsupportedException(); - } -## Java 1.6 end ##*/ - - /** - * INTERNAL - */ -/*## Java 1.6 begin ## - public void updateAsciiStream(int columnIndex, InputStream x, long length) - throws SQLException { - throw getUnsupportedException(); - } -## Java 1.6 end ##*/ - - /** - * INTERNAL - */ -/*## Java 1.6 begin ## - public void updateAsciiStream(String columnLabel, InputStream x, long length) - throws SQLException { - throw getUnsupportedException(); - } -## Java 1.6 end ##*/ - - /** - * INTERNAL - */ -/*## Java 1.6 begin ## - public void updateBinaryStream(int columnLabel, InputStream x) - throws SQLException { - throw getUnsupportedException(); - } -## Java 1.6 end ##*/ - - /** - * INTERNAL - */ -/*## Java 1.6 begin ## - public void updateBinaryStream(String columnLabel, InputStream x) - throws SQLException { - throw getUnsupportedException(); - } -## Java 1.6 end ##*/ - - /** - * INTERNAL - */ -/*## Java 1.6 begin ## - public void updateBinaryStream(int columnIndex, InputStream x, long length) - throws SQLException { - throw getUnsupportedException(); - } -## Java 1.6 end ##*/ - - /** - * INTERNAL - */ -/*## Java 1.6 begin ## - public void updateBinaryStream(String columnLabel, InputStream x, long length) - throws SQLException { - throw getUnsupportedException(); - } -## Java 1.6 end ##*/ - - /** - * INTERNAL - */ -/*## Java 1.6 begin ## - public void updateBlob(int columnIndex, InputStream x) throws SQLException { - throw getUnsupportedException(); - } -## Java 1.6 end ##*/ - - /** - * INTERNAL - */ -/*## Java 1.6 begin ## - public void updateBlob(String columnLabel, InputStream x) throws SQLException { - throw getUnsupportedException(); - } -## Java 1.6 end ##*/ - - /** - * INTERNAL - */ -/*## Java 1.6 begin ## - public void updateBlob(int columnIndex, InputStream x, long length) - throws SQLException { - throw getUnsupportedException(); - } -## Java 1.6 end ##*/ - - /** - * INTERNAL - */ -/*## Java 1.6 begin ## - public void updateBlob(String columnLabel, InputStream x, long length) - throws SQLException { - throw getUnsupportedException(); - } -## Java 1.6 end ##*/ - - /** - * INTERNAL - */ -/*## Java 1.6 begin ## - public void updateCharacterStream(int columnIndex, Reader x) - throws SQLException { - throw getUnsupportedException(); - } -## Java 1.6 end ##*/ - - /** - * INTERNAL - */ -/*## Java 1.6 begin ## - public void updateCharacterStream(String columnLabel, Reader x) - throws SQLException { - throw getUnsupportedException(); - } -## Java 1.6 end ##*/ - - /** - * INTERNAL - */ -/*## Java 1.6 begin ## - public void updateCharacterStream(int columnIndex, Reader x, long length) - throws SQLException { - throw getUnsupportedException(); - } -## Java 1.6 end ##*/ - - /** - * INTERNAL - */ -/*## Java 1.6 begin ## - public void updateCharacterStream(String columnLabel, Reader x, long length) - throws SQLException { - throw getUnsupportedException(); - } -## Java 1.6 end ##*/ - - /** - * INTERNAL - */ -/*## Java 1.6 begin ## - public void updateClob(int columnIndex, Reader x) throws SQLException { - throw getUnsupportedException(); - } -## Java 1.6 end ##*/ - - /** - * INTERNAL - */ -/*## Java 1.6 begin ## - public void updateClob(String columnLabel, Reader x) throws SQLException { - throw getUnsupportedException(); - } -## Java 1.6 end ##*/ - - /** - * INTERNAL - */ -/*## Java 1.6 begin ## - public void updateClob(int columnIndex, Reader x, long length) - throws SQLException { - throw getUnsupportedException(); - } -## Java 1.6 end ##*/ - - /** - * INTERNAL - */ -/*## Java 1.6 begin ## - public void updateClob(String columnLabel, Reader x, long length) - throws SQLException { - throw getUnsupportedException(); - } -## Java 1.6 end ##*/ - - /** - * INTERNAL - */ -/*## Java 1.6 begin ## - public void updateNCharacterStream(int columnIndex, Reader x) - throws SQLException { - throw getUnsupportedException(); - } -## Java 1.6 end ##*/ - - /** - * INTERNAL - */ -/*## Java 1.6 begin ## - public void updateNCharacterStream(String columnLabel, Reader x) - throws SQLException { - throw getUnsupportedException(); - } -## Java 1.6 end ##*/ - - /** - * INTERNAL - */ -/*## Java 1.6 begin ## - public void updateNCharacterStream(int columnIndex, Reader x, long length) - throws SQLException { - throw getUnsupportedException(); - } -## Java 1.6 end ##*/ - - /** - * INTERNAL - */ -/*## Java 1.6 begin ## - public void updateNCharacterStream(String columnLabel, Reader x, long length) - throws SQLException { - throw getUnsupportedException(); - } -## Java 1.6 end ##*/ - - /** - * INTERNAL - */ -/*## Java 1.6 begin ## - public void updateNClob(int columnIndex, Reader x) throws SQLException { - throw getUnsupportedException(); - } -## Java 1.6 end ##*/ - - /** - * INTERNAL - */ -/*## Java 1.6 begin ## - public void updateNClob(String columnLabel, Reader x) throws SQLException { - throw getUnsupportedException(); - } -## Java 1.6 end ##*/ - - /** - * INTERNAL - */ -/*## Java 1.6 begin ## - public void updateNClob(int columnIndex, Reader x, long length) - throws SQLException { - throw getUnsupportedException(); - } -## Java 1.6 end ##*/ - - /** - * INTERNAL - */ -/*## Java 1.6 begin ## - public void updateNClob(String columnLabel, Reader x, long length) - throws SQLException { - throw getUnsupportedException(); - } -## Java 1.6 end ##*/ - -} diff --git a/tools/h2/src/main/org/h2/tools/SimpleRowSource.java b/tools/h2/src/main/org/h2/tools/SimpleRowSource.java deleted file mode 100755 index 05b25b3..0000000 --- a/tools/h2/src/main/org/h2/tools/SimpleRowSource.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.tools; - -import java.sql.SQLException; - -/** - * This interface is for classes that create rows on demand. - * It is used together with SimpleResultSet to create a dynamic result set. - */ -public interface SimpleRowSource { - - /** - * Get the next row. Must return null if no more rows are available. - * - * @return the row or null - * @throws SQLException - */ - Object[] readRow() throws SQLException; - - /** - * Close the row source. - */ - void close(); - - /** - * Reset the position (before the first row). - * - * @throws SQLException if this operation is not supported - */ - void reset() throws SQLException; -} diff --git a/tools/h2/src/main/org/h2/tools/TriggerAdapter.java b/tools/h2/src/main/org/h2/tools/TriggerAdapter.java deleted file mode 100755 index 44c0193..0000000 --- a/tools/h2/src/main/org/h2/tools/TriggerAdapter.java +++ /dev/null @@ -1,156 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.tools; - -import java.sql.Connection; -import java.sql.ResultSet; -import java.sql.SQLException; -import org.h2.api.Trigger; - -/** - * An adapter for the trigger interface that allows to use the ResultSet - * interface instead of a row array. - */ -public abstract class TriggerAdapter implements Trigger { - - private SimpleResultSet oldResultSet, newResultSet; - private TriggerRowSource oldSource, newSource; - - /** - * This method is called by the database engine once when initializing the - * trigger. It is called when the trigger is created, as well as when the - * database is opened. The default implementation initialized the result - * sets. - * - * @param conn a connection to the database - * @param schemaName the name of the schema - * @param triggerName the name of the trigger used in the CREATE TRIGGER - * statement - * @param tableName the name of the table - * @param before whether the fire method is called before or after the - * operation is performed - * @param type the operation type: INSERT, UPDATE, or DELETE - */ - public void init(Connection conn, String schemaName, - String triggerName, String tableName, - boolean before, int type) throws SQLException { - ResultSet rs = conn.getMetaData().getColumns( - null, schemaName, tableName, null); - oldSource = new TriggerRowSource(); - newSource = new TriggerRowSource(); - oldResultSet = new SimpleResultSet(oldSource); - newResultSet = new SimpleResultSet(newSource); - while (rs.next()) { - String column = rs.getString("COLUMN_NAME"); - int dataType = rs.getInt("DATA_TYPE"); - int precision = rs.getInt("COLUMN_SIZE"); - int scale = rs.getInt("DECIMAL_DIGITS"); - oldResultSet.addColumn(column, dataType, precision, scale); - newResultSet.addColumn(column, dataType, precision, scale); - } - } - - /** - * A row source that allows to set the next row. - */ - static class TriggerRowSource implements SimpleRowSource { - - private Object[] row; - - void setRow(Object[] row) { - this.row = row; - } - - public Object[] readRow() { - return row; - } - - public void close() { - // ignore - } - - public void reset() { - // ignore - } - - } - - /** - * This method is called for each triggered action. The method is called - * immediately when the operation occurred (before it is committed). A - * transaction rollback will also rollback the operations that were done - * within the trigger, if the operations occurred within the same database. - * If the trigger changes state outside the database, a rollback trigger - * should be used. - *

- * The row arrays contain all columns of the table, in the same order - * as defined in the table. - *

- *

- * The default implementation calls the fire method with the ResultSet - * parameters. - *

- * - * @param conn a connection to the database - * @param oldRow the old row, or null if no old row is available (for - * INSERT) - * @param newRow the new row, or null if no new row is available (for - * DELETE) - * @throws SQLException if the operation must be undone - */ - public void fire(Connection conn, Object[] oldRow, - Object[] newRow) throws SQLException { - fire(conn, wrap(oldResultSet, oldSource, oldRow), wrap(newResultSet, newSource, newRow)); - } - - /** - * This method is called for each triggered action by the default - * fire(Connection conn, Object[] oldRow, Object[] newRow) method. - * ResultSet.next does not need to be called (and calling it has no effect; - * it will always return true). - * - * @param conn a connection to the database - * @param oldRow the old row, or null if no old row is available (for - * INSERT) - * @param newRow the new row, or null if no new row is available (for - * DELETE) - * @throws SQLException if the operation must be undone - */ - public abstract void fire(Connection conn, ResultSet oldRow, ResultSet newRow) throws SQLException; - - private SimpleResultSet wrap(SimpleResultSet rs, TriggerRowSource source, Object[] row) throws SQLException { - if (row == null) { - return null; - } - source.setRow(row); - rs.next(); - return rs; - } - - /** - * This method is called when the database is closed. - * If the method throws an exception, it will be logged, but - * closing the database will continue. - * The default implementation does nothing. - * - * @throws SQLException - */ - public void remove() throws SQLException { - // do nothing by default - } - - /** - * This method is called when the trigger is dropped. - * The default implementation does nothing. - * - * @throws SQLException - */ - public void close() throws SQLException { - // do nothing by default - } - -} diff --git a/tools/h2/src/main/org/h2/tools/package.html b/tools/h2/src/main/org/h2/tools/package.html deleted file mode 100755 index 9b521c9..0000000 --- a/tools/h2/src/main/org/h2/tools/package.html +++ /dev/null @@ -1,15 +0,0 @@ - - - - -Javadoc package documentation -

- -Various tools. Most tools are command line driven, but not all (for example the CSV tool). - -

\ No newline at end of file diff --git a/tools/h2/src/main/org/h2/util/AutoCloseInputStream.java b/tools/h2/src/main/org/h2/util/AutoCloseInputStream.java deleted file mode 100755 index df84473..0000000 --- a/tools/h2/src/main/org/h2/util/AutoCloseInputStream.java +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.util; - -import java.io.IOException; -import java.io.InputStream; - -/** - * This input stream wrapper closes the base input stream when fully read. - */ -public class AutoCloseInputStream extends InputStream { - - private final InputStream in; - private boolean closed; - - /** - * Create a new input stream. - * - * @param in the input stream - */ - public AutoCloseInputStream(InputStream in) { - this.in = in; - } - - private int autoClose(int x) throws IOException { - if (x < 0) { - close(); - } - return x; - } - - public void close() throws IOException { - if (!closed) { - in.close(); - closed = true; - } - } - - public int read(byte[] b, int off, int len) throws IOException { - return closed ? -1 : autoClose(in.read(b, off, len)); - } - - public int read(byte[] b) throws IOException { - return closed ? -1 : autoClose(in.read(b)); - } - - public int read() throws IOException { - return closed ? -1 : autoClose(in.read()); - } - -} diff --git a/tools/h2/src/main/org/h2/util/Cache.java b/tools/h2/src/main/org/h2/util/Cache.java deleted file mode 100755 index db06da9..0000000 --- a/tools/h2/src/main/org/h2/util/Cache.java +++ /dev/null @@ -1,92 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.util; - -import java.util.ArrayList; - -/** - * The cache keeps frequently used objects in the main memory. - */ -public interface Cache { - - /** - * Get all objects in the cache that have been changed. - * - * @return the list of objects - */ - ArrayList getAllChanged(); - - /** - * Clear the cache. - */ - void clear(); - - /** - * Get an element in the cache if it is available. - * This will move the item to the front of the list. - * - * @param pos the unique key of the element - * @return the element or null - */ - CacheObject get(int pos); - - /** - * Add an element to the cache. Other items may fall out of the cache - * because of this. It is not allowed to add the same record twice. - * - * @param r the object - */ - void put(CacheObject r); - - /** - * Update an element in the cache. - * This will move the item to the front of the list. - * - * @param pos the unique key of the element - * @param record the element - * @return the element - */ - CacheObject update(int pos, CacheObject record); - - /** - * Remove an object from the cache. - * - * @param pos the unique key of the element - */ - void remove(int pos); - - /** - * Get an element from the cache if it is available. - * This will not move the item to the front of the list. - * - * @param pos the unique key of the element - * @return the element or null - */ - CacheObject find(int pos); - - /** - * Set the maximum memory to be used by this cache. - * - * @param size the maximum size in KB - */ - void setMaxSize(int size); - - /** - * Get the maximum size in KB. - * - * @return the maximum size in KB - */ - int getMaxSize(); - - /** - * Get the used size in KB. - * - * @return the current size in KB - */ - int getSize(); - -} diff --git a/tools/h2/src/main/org/h2/util/CacheHead.java b/tools/h2/src/main/org/h2/util/CacheHead.java deleted file mode 100755 index 97a0f72..0000000 --- a/tools/h2/src/main/org/h2/util/CacheHead.java +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.util; - -/** - * The head element of the linked list. - */ -public class CacheHead extends CacheObject { - - public boolean canRemove() { - return false; - } - - public int getMemorySize() { - return 0; - } - -} diff --git a/tools/h2/src/main/org/h2/util/CacheLRU.java b/tools/h2/src/main/org/h2/util/CacheLRU.java deleted file mode 100755 index ed23f0c..0000000 --- a/tools/h2/src/main/org/h2/util/CacheLRU.java +++ /dev/null @@ -1,388 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.util; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.Map; -import org.h2.constant.SysProperties; -import org.h2.engine.Constants; -import org.h2.message.DbException; - -/** - * A cache implementation based on the last recently used (LRU) algorithm. - */ -public class CacheLRU implements Cache { - - static final String TYPE_NAME = "LRU"; - - private final CacheWriter writer; - private final CacheObject head = new CacheHead(); - private final int mask; - private CacheObject[] values; - private int recordCount; - - /** - * The number of cache buckets. - */ - private final int len; - - /** - * The maximum memory, in words (4 bytes each). - */ - private int maxSize; - - /** - * The current memory used in this cache, in words (4 bytes each). - */ - private int sizeMemory; - - private CacheLRU(CacheWriter writer, int maxKb) { - this.maxSize = maxKb * 1024 / 4; - this.writer = writer; - this.len = MathUtils.nextPowerOf2(maxSize / 64); - this.mask = len - 1; - MathUtils.checkPowerOf2(len); - clear(); - } - - /** - * Create a cache of the given type and size. - * - * @param writer the cache writer - * @param cacheType the cache type - * @param cacheSize the size - * @return the cache object - */ - public static Cache getCache(CacheWriter writer, String cacheType, int cacheSize) { - Map secondLevel = null; - if (cacheType.startsWith("SOFT_")) { - secondLevel = new SoftHashMap(); - cacheType = cacheType.substring("SOFT_".length()); - } - Cache cache; - if (CacheLRU.TYPE_NAME.equals(cacheType)) { - cache = new CacheLRU(writer, cacheSize); - } else { - throw DbException.getInvalidValueException(cacheType, "CACHE_TYPE"); - } - if (secondLevel != null) { - cache = new CacheSecondLevel(cache, secondLevel); - } - return cache; - } - - public void clear() { - head.cacheNext = head.cachePrevious = head; - // first set to null - avoiding out of memory - values = null; - values = new CacheObject[len]; - recordCount = 0; - sizeMemory = 0; - } - - public void put(CacheObject rec) { - if (SysProperties.CHECK) { - int pos = rec.getPos(); - CacheObject old = find(pos); - if (old != null) { - DbException.throwInternalError("try to add a record twice pos:" + pos); - } - } - int index = rec.getPos() & mask; - rec.cacheChained = values[index]; - values[index] = rec; - recordCount++; - sizeMemory += rec.getMemorySize(); - addToFront(rec); - removeOldIfRequired(); - } - - public CacheObject update(int pos, CacheObject rec) { - CacheObject old = find(pos); - if (old == null) { - put(rec); - } else { - if (SysProperties.CHECK) { - if (old != rec) { - DbException.throwInternalError("old!=record pos:" + pos + " old:" + old + " new:" + rec); - } - } - removeFromLinkedList(rec); - addToFront(rec); - } - return old; - } - - private void removeOldIfRequired() { - // a small method, to allow inlining - if (sizeMemory >= maxSize) { - removeOld(); - } - } - - private void removeOld() { - int i = 0; - ArrayList changed = New.arrayList(); - int mem = sizeMemory; - int rc = recordCount; - boolean flushed = false; - CacheObject next = head.cacheNext; - while (mem * 4 > maxSize * 3 && rc > Constants.CACHE_MIN_RECORDS) { - CacheObject check = next; - next = check.cacheNext; - i++; - if (i >= recordCount) { - if (!flushed) { - writer.flushLog(); - flushed = true; - i = 0; - } else { - // can't remove any record, because the records can not be removed - // hopefully this does not happen frequently, but it can happen - writer.getTrace().info("Cannot remove records, cache size too small? records:" + recordCount + " memory:" + sizeMemory); - break; - } - } - if (SysProperties.CHECK && check == head) { - DbException.throwInternalError("try to remove head"); - } - // we are not allowed to remove it if the log is not yet written - // (because we need to log before writing the data) - // also, can't write it if the record is pinned - if (!check.canRemove()) { - removeFromLinkedList(check); - addToFront(check); - continue; - } - rc--; - mem -= check.getMemorySize(); - if (check.isChanged()) { - changed.add(check); - } else { - remove(check.getPos()); - } - } - if (changed.size() > 0) { - Collections.sort(changed); - int max = maxSize; - try { - // temporary disable size checking, - // to avoid stack overflow - maxSize = Integer.MAX_VALUE; - for (i = 0; i < changed.size(); i++) { - CacheObject rec = changed.get(i); - writer.writeBack(rec); - } - } finally { - maxSize = max; - } - for (i = 0; i < changed.size(); i++) { - CacheObject rec = changed.get(i); - remove(rec.getPos()); - if (SysProperties.CHECK) { - if (rec.cacheNext != null) { - throw DbException.throwInternalError(); - } - } - } - } - } - - private void addToFront(CacheObject rec) { - if (SysProperties.CHECK && rec == head) { - DbException.throwInternalError("try to move head"); - } - rec.cacheNext = head; - rec.cachePrevious = head.cachePrevious; - rec.cachePrevious.cacheNext = rec; - head.cachePrevious = rec; - } - - private void removeFromLinkedList(CacheObject rec) { - if (SysProperties.CHECK && rec == head) { - DbException.throwInternalError("try to remove head"); - } - rec.cachePrevious.cacheNext = rec.cacheNext; - rec.cacheNext.cachePrevious = rec.cachePrevious; - // TODO cache: mystery: why is this required? needs more memory if we - // don't do this - rec.cacheNext = null; - rec.cachePrevious = null; - } - - public void remove(int pos) { - int index = pos & mask; - CacheObject rec = values[index]; - if (rec == null) { - return; - } - if (rec.getPos() == pos) { - values[index] = rec.cacheChained; - } else { - CacheObject last; - do { - last = rec; - rec = rec.cacheChained; - if (rec == null) { - return; - } - } while (rec.getPos() != pos); - last.cacheChained = rec.cacheChained; - } - recordCount--; - sizeMemory -= rec.getMemorySize(); - removeFromLinkedList(rec); - if (SysProperties.CHECK) { - rec.cacheChained = null; - CacheObject o = find(pos); - if (o != null) { - DbException.throwInternalError("not removed: " + o); - } - } - } - - public CacheObject find(int pos) { - CacheObject rec = values[pos & mask]; - while (rec != null && rec.getPos() != pos) { - rec = rec.cacheChained; - } - return rec; - } - - public CacheObject get(int pos) { - CacheObject rec = find(pos); - if (rec != null) { - removeFromLinkedList(rec); - addToFront(rec); - } - return rec; - } - -// private void testConsistency() { -// int s = size; -// HashSet set = new HashSet(); -// for(int i=0; i { - - /** - * The previous element in the LRU linked list. If the previous element is - * the head, then this element is the most recently used object. - */ - public CacheObject cachePrevious; - - /** - * The next element in the LRU linked list. If the next element is the head, - * then this element is the least recently used object. - */ - public CacheObject cacheNext; - - /** - * The next element in the hash chain. - */ - public CacheObject cacheChained; - - private int pos; - private boolean changed; - - /** - * Check if the object can be removed from the cache. - * For example pinned objects can not be removed. - * - * @return true if it can be removed - */ - public abstract boolean canRemove(); - - /** - * Get the estimated memory size. - * - * @return number of double words (4 bytes) - */ - public abstract int getMemorySize(); - - public void setPos(int pos) { - if (SysProperties.CHECK && (cachePrevious != null || cacheNext != null || cacheChained != null)) { - DbException.throwInternalError("setPos too late"); - } - this.pos = pos; - } - - public int getPos() { - return pos; - } - - /** - * Check if this cache object has been changed and thus needs to be written - * back to the storage. - * - * @return if it has been changed - */ - public boolean isChanged() { - return changed; - } - - public void setChanged(boolean b) { - changed = b; - } - - public int compareTo(CacheObject other) { - return MathUtils.compareInt(getPos(), other.getPos()); - } - -} diff --git a/tools/h2/src/main/org/h2/util/CacheSecondLevel.java b/tools/h2/src/main/org/h2/util/CacheSecondLevel.java deleted file mode 100755 index e7f60c2..0000000 --- a/tools/h2/src/main/org/h2/util/CacheSecondLevel.java +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: Jan Kotek - */ -package org.h2.util; - -import java.util.ArrayList; -import java.util.Map; - -/** - * Cache which wraps another cache (proxy pattern) and adds caching using map. - * This is useful for WeakReference, SoftReference or hard reference cache. - */ -class CacheSecondLevel implements Cache { - - private final Cache baseCache; - private final Map map; - - CacheSecondLevel(Cache cache, Map map) { - this.baseCache = cache; - this.map = map; - } - - public void clear() { - map.clear(); - baseCache.clear(); - } - - public CacheObject find(int pos) { - CacheObject ret = baseCache.find(pos); - if (ret == null) { - ret = map.get(pos); - } - return ret; - } - - public CacheObject get(int pos) { - CacheObject ret = baseCache.get(pos); - if (ret == null) { - ret = map.get(pos); - } - return ret; - } - - public ArrayList getAllChanged() { - return baseCache.getAllChanged(); - } - - public int getMaxSize() { - return baseCache.getMaxSize(); - } - - public int getSize() { - return baseCache.getSize(); - } - - public void put(CacheObject r) { - baseCache.put(r); - map.put(r.getPos(), r); - } - - public void remove(int pos) { - baseCache.remove(pos); - map.remove(pos); - } - - public void setMaxSize(int size) { - baseCache.setMaxSize(size); - } - - public CacheObject update(int pos, CacheObject record) { - CacheObject oldRec = baseCache.update(pos, record); - map.put(pos, record); - return oldRec; - } - -} diff --git a/tools/h2/src/main/org/h2/util/CacheWriter.java b/tools/h2/src/main/org/h2/util/CacheWriter.java deleted file mode 100755 index 1e61bea..0000000 --- a/tools/h2/src/main/org/h2/util/CacheWriter.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.util; - -import org.h2.message.Trace; - -/** - * The cache writer is called by the cache to persist changed data that needs to - * be removed from the cache. - */ -public interface CacheWriter { - - /** - * Persist a record. - * - * @param entry the cache entry - */ - void writeBack(CacheObject entry); - - /** - * Flush the transaction log, so that entries can be removed from the cache. - * This is only required if the cache is full and contains data that is not - * yet written to the log. It is required to write the log entries to the - * log first, because the log is 'write ahead'. - */ - void flushLog(); - - /** - * Get the trace writer. - * - * @return the trace writer - */ - Trace getTrace(); - -} diff --git a/tools/h2/src/main/org/h2/util/DateTimeUtils.java b/tools/h2/src/main/org/h2/util/DateTimeUtils.java deleted file mode 100755 index 6edfb34..0000000 --- a/tools/h2/src/main/org/h2/util/DateTimeUtils.java +++ /dev/null @@ -1,559 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - * Iso8601: - * Initial Developer: Robert Rathsack (firstName dot lastName at gmx dot de) - */ -package org.h2.util; - -import java.sql.Date; -import java.sql.Time; -import java.sql.Timestamp; -import java.text.SimpleDateFormat; -import java.util.Calendar; -import java.util.GregorianCalendar; -import java.util.Locale; -import java.util.TimeZone; -import org.h2.constant.ErrorCode; -import org.h2.message.DbException; -import org.h2.value.Value; -import org.h2.value.ValueDate; -import org.h2.value.ValueTime; -import org.h2.value.ValueTimestamp; - -/** - * This utility class contains time conversion functions. - */ -public class DateTimeUtils { - - private static final int DEFAULT_YEAR = 1970; - private static final int DEFAULT_MONTH = 1; - private static final int DEFAULT_DAY = 1; - private static final int DEFAULT_HOUR = 0; - - private static Calendar cachedCalendar = Calendar.getInstance(); - - private DateTimeUtils() { - // utility class - } - - /** - * Reset the calendar, for example after changing the default timezone. - */ - public static void resetCalendar() { - cachedCalendar = null; - } - - private static Calendar getCalendar() { - if (cachedCalendar == null) { - cachedCalendar = Calendar.getInstance(); - } - return cachedCalendar; - } - - /** - * Convert the timestamp to the specified time zone. - * - * @param x the timestamp - * @param calendar the calendar - * @return the timestamp using the correct time zone - */ - public static Timestamp convertTimestampToCalendar(Timestamp x, Calendar calendar) { - if (x != null) { - Timestamp y = new Timestamp(getLocalTime(x, calendar)); - // fix the nano seconds - y.setNanos(x.getNanos()); - x = y; - } - return x; - } - - /** - * Clone a time object and reset the day to 1970-01-01. - * - * @param value the time value - * @return the time value without the date component - */ - public static Time cloneAndNormalizeTime(Time value) { - Calendar cal = getCalendar(); - long time; - synchronized (cal) { - cal.setTime(value); - // month is 0 based - cal.set(DEFAULT_YEAR, DEFAULT_MONTH - 1, DEFAULT_DAY); - time = cal.getTime().getTime(); - } - return new Time(time); - } - - /** - * Clone a date object and reset the hour, minutes, seconds, and - * milliseconds to zero. - * - * @param value the date value - * @return the date value at midnight - */ - public static Date cloneAndNormalizeDate(Date value) { - Calendar cal = getCalendar(); - long time; - synchronized (cal) { - cal.setTime(value); - // if we don't enable lenient processing, dates between - // 1916-06-03 and 1920-03-21, - // 1940-06-15, 1947-03-16, and - // 1966-05-22 to 1979-05-27 don't work - // (central european timezone CET) - cal.setLenient(true); - cal.set(Calendar.MILLISECOND, 0); - cal.set(Calendar.SECOND, 0); - cal.set(Calendar.MINUTE, 0); - cal.set(Calendar.HOUR_OF_DAY, DEFAULT_HOUR); - time = cal.getTime().getTime(); - } - return new Date(time); - } - - /** - * Convert the date from the specified time zone to UTC. - * - * @param x the date - * @param source the calendar - * @return the date in UTC - */ - public static Value convertDateToUniversal(Date x, Calendar source) { - return ValueDate.get(new Date(getUniversalTime(source, x))); - } - - /** - * Convert the time from the specified time zone to UTC. - * - * @param x the time - * @param source the calendar - * @return the time in UTC - */ - public static Value convertTimeToUniversal(Time x, Calendar source) { - return ValueTime.get(new Time(getUniversalTime(source, x))); - } - - /** - * Convert the timestamp from the specified time zone to UTC. - * - * @param x the time - * @param source the calendar - * @return the timestamp in UTC - */ - public static Value convertTimestampToUniversal(Timestamp x, Calendar source) { - Timestamp y = new Timestamp(getUniversalTime(source, x)); - // fix the nano seconds - y.setNanos(x.getNanos()); - return ValueTimestamp.getNoCopy(y); - } - - /** - * Convert the date value to UTC using the given calendar. - * - * @param source the source calendar - * @param x the date - * @return the UTC number of milliseconds. - */ - private static long getUniversalTime(Calendar source, java.util.Date x) { - if (source == null) { - throw DbException.getInvalidValueException("calendar", null); - } - source = (Calendar) source.clone(); - Calendar universal = getCalendar(); - synchronized (universal) { - source.setTime(x); - convertTime(source, universal); - return universal.getTime().getTime(); - } - } - - private static long getLocalTime(java.util.Date x, Calendar target) { - if (target == null) { - throw DbException.getInvalidValueException("calendar", null); - } - target = (Calendar) target.clone(); - Calendar local = Calendar.getInstance(); - synchronized (local) { - local.setTime(x); - convertTime(local, target); - } - return target.getTime().getTime(); - } - - private static void convertTime(Calendar from, Calendar to) { - to.set(Calendar.YEAR, from.get(Calendar.YEAR)); - to.set(Calendar.MONTH, from.get(Calendar.MONTH)); - to.set(Calendar.DAY_OF_MONTH, from.get(Calendar.DAY_OF_MONTH)); - to.set(Calendar.HOUR_OF_DAY, from.get(Calendar.HOUR_OF_DAY)); - to.set(Calendar.MINUTE, from.get(Calendar.MINUTE)); - to.set(Calendar.SECOND, from.get(Calendar.SECOND)); - to.set(Calendar.MILLISECOND, from.get(Calendar.MILLISECOND)); - } - - /** - * Convert the date to the specified time zone. - * - * @param x the date - * @param calendar the calendar - * @return the date using the correct time zone - */ - public static Date convertDateToCalendar(Date x, Calendar calendar) { - return x == null ? null : new Date(getLocalTime(x, calendar)); - } - - /** - * Convert the time to the specified time zone. - * - * @param x the time - * @param calendar the calendar - * @return the time using the correct time zone - */ - public static Time convertTimeToCalendar(Time x, Calendar calendar) { - return x == null ? null : new Time(getLocalTime(x, calendar)); - } - - /** - * Parse a date, time or timestamp value. This method supports the format - * +/-year-month-day hour:minute:seconds.fractional and an optional timezone - * part. - * - * @param original the original string - * @param type the value type (Value.TIME, TIMESTAMP, or DATE) - * @param errorCode the error code to use if an error occurs - * @return the date object - */ - public static java.util.Date parseDateTime(String original, int type, int errorCode) { - String s = original; - if (s == null) { - return null; - } - try { - int timeStart = 0; - TimeZone tz = null; - if (type == Value.TIME) { - timeStart = 0; - } else { - timeStart = s.indexOf(' ') + 1; - if (timeStart <= 0) { - // ISO 8601 compatibility - timeStart = s.indexOf('T') + 1; - } - } - - int year = DEFAULT_YEAR, month = DEFAULT_MONTH, day = DEFAULT_DAY; - if (type != Value.TIME) { - if (s.startsWith("+")) { - // +year - s = s.substring(1); - } - // start at position 1 to support -year - int s1 = s.indexOf('-', 1); - int s2 = s.indexOf('-', s1 + 1); - if (s1 <= 0 || s2 <= s1) { - throw DbException.get(errorCode, s, "format yyyy-mm-dd"); - } - year = Integer.parseInt(s.substring(0, s1)); - month = Integer.parseInt(s.substring(s1 + 1, s2)); - int end = timeStart == 0 ? s.length() : timeStart - 1; - day = Integer.parseInt(s.substring(s2 + 1, end)); - } - int hour = DEFAULT_HOUR, minute = 0, second = 0, nano = 0; - int s1 = s.indexOf(':', timeStart); - if (type == Value.TIME || (type == Value.TIMESTAMP && s1 >= 0)) { - int s2 = s.indexOf(':', s1 + 1); - int s3 = s.indexOf('.', s2 + 1); - if (s1 <= 0 || s2 <= s1) { - throw DbException.get(errorCode, s, "format hh:mm:ss"); - } - - if (s.endsWith("Z")) { - s = s.substring(0, s.length() - 1); - tz = TimeZone.getTimeZone("UTC"); - } else { - int timeZoneStart = s.indexOf('+', s2 + 1); - if (timeZoneStart < 0) { - timeZoneStart = s.indexOf('-', s2 + 1); - } - if (timeZoneStart >= 0) { - String tzName = "GMT" + s.substring(timeZoneStart); - tz = TimeZone.getTimeZone(tzName); - if (!tz.getID().startsWith(tzName)) { - throw DbException.get(errorCode, new String[] { s, tz.getID() + " <>" + tzName }); - } - s = s.substring(0, timeZoneStart).trim(); - } - } - - hour = Integer.parseInt(s.substring(timeStart, s1)); - minute = Integer.parseInt(s.substring(s1 + 1, s2)); - if (s3 < 0) { - second = Integer.parseInt(s.substring(s2 + 1)); - } else { - second = Integer.parseInt(s.substring(s2 + 1, s3)); - String n = (s + "000000000").substring(s3 + 1, s3 + 10); - nano = Integer.parseInt(n); - } - } - long time; - try { - time = getTime(false, tz, year, month, day, hour, minute, second, type != Value.TIMESTAMP, nano); - } catch (IllegalArgumentException e) { - // special case: if the time simply doesn't exist because of - // daylight saving time changes, use the lenient version - String message = e.toString(); - if (message.indexOf("HOUR_OF_DAY") > 0) { - if (hour < 0 || hour > 23) { - throw e; - } - time = getTime(true, tz, year, month, day, hour, minute, second, type != Value.TIMESTAMP, nano); - } else if (message.indexOf("DAY_OF_MONTH") > 0) { - int maxDay; - if (month == 2) { - maxDay = new GregorianCalendar().isLeapYear(year) ? 29 : 28; - } else { - maxDay = 30 + ((month + (month > 7 ? 1 : 0)) & 1); - } - if (day < 1 || day > maxDay) { - throw e; - } - // DAY_OF_MONTH is thrown for years > 2037 - // using the timezone Brasilia and others, - // for example for 2042-10-12 00:00:00. - hour += 6; - time = getTime(true, tz, year, month, day, hour, minute, second, type != Value.TIMESTAMP, nano); - } else { - throw e; - } - } - switch (type) { - case Value.DATE: - return new java.sql.Date(time); - case Value.TIME: - return new java.sql.Time(time); - case Value.TIMESTAMP: { - Timestamp ts = new Timestamp(time); - ts.setNanos(nano); - return ts; - } - default: - throw DbException.throwInternalError("type:" + type); - } - } catch (IllegalArgumentException e) { - throw DbException.get(errorCode, e, original, e.toString()); - } - } - - private static long getTime(boolean lenient, TimeZone tz, int year, int month, int day, int hour, int minute, int second, boolean setMillis, int nano) { - Calendar c; - if (tz == null) { - c = getCalendar(); - } else { - c = Calendar.getInstance(tz); - } - synchronized (c) { - c.setLenient(lenient); - if (year <= 0) { - c.set(Calendar.ERA, GregorianCalendar.BC); - c.set(Calendar.YEAR, 1 - year); - } else { - c.set(Calendar.ERA, GregorianCalendar.AD); - c.set(Calendar.YEAR, year); - } - // january is 0 - c.set(Calendar.MONTH, month - 1); - c.set(Calendar.DAY_OF_MONTH, day); - c.set(Calendar.HOUR_OF_DAY, hour); - c.set(Calendar.MINUTE, minute); - c.set(Calendar.SECOND, second); - if (setMillis) { - c.set(Calendar.MILLISECOND, nano / 1000000); - } - return c.getTime().getTime(); - } - } - - /** - * Get the specified field of a date, however with years normalized to - * positive or negative, and month starting with 1. - * - * @param d the date - * @param field the field type - * @return the value - */ - public static int getDatePart(java.util.Date d, int field) { - Calendar c = getCalendar(); - int value; - synchronized (c) { - c.setTime(d); - value = c.get(field); - } - if (field == Calendar.MONTH) { - value++; - } else if (field == Calendar.YEAR) { - if (c.get(Calendar.ERA) == GregorianCalendar.BC) { - value = 1 - value; - } - } - return value; - } - - /** - * Get the number of milliseconds since 1970-01-01 in the local timezone. - * - * @param d the date - * @return the milliseconds - */ - public static long getTimeLocal(java.util.Date d) { - Calendar c = getCalendar(); - synchronized (c) { - c.setTime(d); - return c.getTime().getTime() + c.get(Calendar.ZONE_OFFSET); - } - } - - /** - * Convert the number of milliseconds since 1970-01-01 in the local timezone - * to GMT. - * - * @param millis the number of milliseconds in the local timezone - * @return the number of milliseconds in GMT - */ - public static long getTimeGMT(long millis) { - Date d = new Date(millis); - Calendar c = getCalendar(); - synchronized (c) { - c.setTime(d); - return c.getTime().getTime() - c.get(Calendar.ZONE_OFFSET); - } - } - - /** - * Return the day of week according to the ISO 8601 specification. Week - * starts at Monday. See also http://en.wikipedia.org/wiki/ISO_8601 - * - * @author Robert Rathsack - * - * @param date the date object which day of week should be calculated - * @return the day of the week, Monday as 1 to Sunday as 7 - */ - public static int getIsoDayOfWeek(java.util.Date date) { - Calendar cal = Calendar.getInstance(); - cal.setTimeInMillis(date.getTime()); - int val = cal.get(Calendar.DAY_OF_WEEK) - 1; - return val == 0 ? 7 : val; - } - - /** - * Returns the week of the year according to the ISO 8601 specification. The - * spec defines the first week of the year as the week which contains at - * least 4 days of the new year. The week starts at Monday. Therefore - * December 29th - 31th could belong to the next year and January 1st - 3th - * could belong to the previous year. If January 1st is on Thursday (or - * earlier) it belongs to the first week, otherwise to the last week of the - * previous year. Hence January 4th always belongs to the first week while - * the December 28th always belongs to the last week. - * - * @author Robert Rathsack - * - * @param date the date object which week of year should be calculated - * @return the week of the year - */ - public static int getIsoWeek(java.util.Date date) { - Calendar c = Calendar.getInstance(); - c.setTimeInMillis(date.getTime()); - c.setFirstDayOfWeek(Calendar.MONDAY); - c.setMinimalDaysInFirstWeek(4); - return c.get(Calendar.WEEK_OF_YEAR); - } - - /** - * Returns the year according to the ISO week definition. - * - * @author Robert Rathsack - * - * @param date the date object which year should be calculated - * @return the year - */ - public static int getIsoYear(java.util.Date date) { - Calendar cal = Calendar.getInstance(); - cal.setTimeInMillis(date.getTime()); - cal.setFirstDayOfWeek(Calendar.MONDAY); - cal.setMinimalDaysInFirstWeek(4); - int year = cal.get(Calendar.YEAR); - int month = cal.get(Calendar.MONTH); - int week = cal.get(Calendar.WEEK_OF_YEAR); - if (month == 0 && week > 51) { - year--; - } else if (month == 11 && week == 1) { - year++; - } - return year; - } - - /** - * Formats a date using a format string. - * - * @param date the date to format - * @param format the format string - * @param locale the locale - * @param timeZone the timezone - * @return the formatted date - */ - public static String formatDateTime(java.util.Date date, String format, String locale, String timeZone) { - SimpleDateFormat dateFormat = getDateFormat(format, locale, timeZone); - synchronized (dateFormat) { - return dateFormat.format(date); - } - } - - /** - * Parses a date using a format string. - * - * @param date the date to parse - * @param format the parsing format - * @param locale the locale - * @param timeZone the timeZone - * @return the parsed date - */ - public static java.util.Date parseDateTime(String date, String format, String locale, String timeZone) { - SimpleDateFormat dateFormat = getDateFormat(format, locale, timeZone); - try { - synchronized (dateFormat) { - return dateFormat.parse(date); - } - } catch (Exception e) { - // ParseException - throw DbException.get(ErrorCode.PARSE_ERROR_1, e, date); - } - } - - private static SimpleDateFormat getDateFormat(String format, String locale, String timeZone) { - try { - // currently, a new instance is create for each call - // however, could cache the last few instances - SimpleDateFormat df; - if (locale == null) { - df = new SimpleDateFormat(format); - } else { - //## Java 1.4 begin ## - Locale l = new Locale(locale); - //## Java 1.4 end ## - /*## Java 1.3 only begin ## - Locale l = new Locale(locale, ""); - ## Java 1.3 only end ##*/ - df = new SimpleDateFormat(format, l); - } - if (timeZone != null) { - df.setTimeZone(TimeZone.getTimeZone(timeZone)); - } - return df; - } catch (Exception e) { - throw DbException.get(ErrorCode.PARSE_ERROR_1, e, format + "/" + locale + "/" + timeZone); - } - } - -} diff --git a/tools/h2/src/main/org/h2/util/DbDriverActivator.java b/tools/h2/src/main/org/h2/util/DbDriverActivator.java deleted file mode 100755 index deae624..0000000 --- a/tools/h2/src/main/org/h2/util/DbDriverActivator.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.util; - -import org.osgi.framework.BundleActivator; -import org.osgi.framework.BundleContext; - -/** - * The driver activator loads the H2 driver when starting the bundle. - * The driver is unloaded when stopping the bundle. - */ -public class DbDriverActivator implements BundleActivator { - - /** - * Start the bundle. This will load and register the database driver. - * - * @param bundleContext the bundle context - */ - public void start(BundleContext bundleContext) { - org.h2.Driver.load(); - } - - /** - * Stop the bundle. This will deregister the database driver. - * - * @param bundleContext the bundle context - */ - public void stop(BundleContext bundleContext) { - org.h2.Driver.unload(); - } - -} diff --git a/tools/h2/src/main/org/h2/util/ExactUTF8InputStreamReader.java b/tools/h2/src/main/org/h2/util/ExactUTF8InputStreamReader.java deleted file mode 100755 index 80deefa..0000000 --- a/tools/h2/src/main/org/h2/util/ExactUTF8InputStreamReader.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.util; - -import java.io.IOException; -import java.io.InputStream; -import java.io.Reader; - -/** - * The regular InputStreamReader may read some more bytes than required. - * If this is a problem, use this class. - */ -public class ExactUTF8InputStreamReader extends Reader { - - private InputStream in; - - public ExactUTF8InputStreamReader(InputStream in) { - this.in = in; - } - - public void close() { - // nothing to do - } - - public int read(char[] chars, int off, int len) throws IOException { - for (int i = 0; i < len; i++, off++) { - int x = in.read(); - if (x < 0) { - return i == 0 ? -1 : i; - } - x = x & 0xff; - if (x < 0x80) { - chars[off] = (char) x; - } else if (x >= 0xe0) { - chars[off] = (char) (((x & 0xf) << 12) + ((in.read() & 0x3f) << 6) + (in.read() & 0x3f)); - } else { - chars[off] = (char) (((x & 0x1f) << 6) + (in.read() & 0x3f)); - } - } - return len; - } - -} diff --git a/tools/h2/src/main/org/h2/util/HashBase.java b/tools/h2/src/main/org/h2/util/HashBase.java deleted file mode 100755 index 1f9ccc1..0000000 --- a/tools/h2/src/main/org/h2/util/HashBase.java +++ /dev/null @@ -1,120 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.util; - - -/** - * The base for other hash classes. - */ -public abstract class HashBase { - - private static final int MAX_LOAD = 90; - - /** - * The bit mask to get the index from the hash code. - */ - protected int mask; - - /** - * The number of slots in the table. - */ - protected int len; - - /** - * The number of occupied slots, excluding the zero key (if any). - */ - protected int size; - - /** - * The number of deleted slots. - */ - protected int deletedCount; - - /** - * The level. The number of slots is 2 ^ level. - */ - protected int level; - - /** - * Whether the zero key is used. - */ - protected boolean zeroKey; - - private int maxSize, minSize, maxDeleted; - - public HashBase() { - reset(2); - } - - /** - * Increase the size of the underlying table and re-distribute the elements. - * - * @param newLevel the new level - */ - protected abstract void rehash(int newLevel); - - /** - * Get the size of the map. - * - * @return the size - */ - public int size() { - return size + (zeroKey ? 1 : 0); - } - - /** - * Check the size before adding an entry. This method resizes the map if - * required. - */ - void checkSizePut() { - if (deletedCount > size) { - rehash(level); - } - if (size + deletedCount >= maxSize) { - rehash(level + 1); - } - } - - /** - * Check the size before removing an entry. This method resizes the map if - * required. - */ - protected void checkSizeRemove() { - if (size < minSize && level > 0) { - rehash(level - 1); - } else if (deletedCount > maxDeleted) { - rehash(level); - } - } - - /** - * Clear the map and reset the level to the specified value. - * - * @param newLevel the new level - */ - protected void reset(int newLevel) { - minSize = size * 3 / 4; - size = 0; - level = newLevel; - len = 2 << level; - mask = len - 1; - maxSize = (int) (len * MAX_LOAD / 100L); - deletedCount = 0; - maxDeleted = 20 + len / 2; - } - - /** - * Calculate the index for this hash code. - * - * @param hash the hash code - * @return the index - */ - protected int getIndex(int hash) { - return hash & mask; - } - -} diff --git a/tools/h2/src/main/org/h2/util/IOUtils.java b/tools/h2/src/main/org/h2/util/IOUtils.java deleted file mode 100755 index 04cde3e..0000000 --- a/tools/h2/src/main/org/h2/util/IOUtils.java +++ /dev/null @@ -1,715 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.util; - -import java.io.BufferedReader; -import java.io.BufferedWriter; -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.EOFException; -import java.io.File; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.io.OutputStream; -import java.io.OutputStreamWriter; -import java.io.RandomAccessFile; -import java.io.Reader; -import java.io.StringReader; -import java.io.StringWriter; -import java.io.Writer; -import org.h2.constant.SysProperties; -import org.h2.engine.Constants; -import org.h2.message.DbException; -import org.h2.store.fs.FileSystem; - -/** - * This utility class contains input/output functions. - */ -public class IOUtils { - - private static final int BUFFER_BLOCK_SIZE = 4 * 1024; - - private IOUtils() { - // utility class - } - - /** - * Close an output stream without throwing an exception. - * - * @param out the output stream or null - */ - public static void closeSilently(OutputStream out) { - if (out != null) { - try { - trace("closeSilently", null, out); - out.close(); - } catch (IOException e) { - // ignore - } - } - } - - /** - * Skip a number of bytes in an input stream. - * - * @param in the input stream - * @param skip the number of bytes to skip - * @throws EOFException if the end of file has been reached before all bytes - * could be skipped - * @throws IOException if an IO exception occurred while skipping - */ - public static void skipFully(InputStream in, long skip) throws IOException { - while (skip > 0) { - long skipped = in.skip(skip); - if (skipped <= 0) { - throw new EOFException(); - } - skip -= skipped; - } - } - - /** - * Skip a number of characters in a reader. - * - * @param reader the reader - * @param skip the number of characters to skip - * @throws EOFException if the end of file has been reached before all - * characters could be skipped - * @throws IOException if an IO exception occurred while skipping - */ - public static void skipFully(Reader reader, long skip) throws IOException { - while (skip > 0) { - long skipped = reader.skip(skip); - if (skipped <= 0) { - throw new EOFException(); - } - skip -= skipped; - } - } - - /** - * Copy all data from the input stream to the output stream and close both - * streams. Exceptions while closing are ignored. - * - * @param in the input stream - * @param out the output stream - * @return the number of bytes copied - */ - public static long copyAndClose(InputStream in, OutputStream out) throws IOException { - try { - long len = copyAndCloseInput(in, out); - out.close(); - return len; - } finally { - closeSilently(out); - } - } - - /** - * Copy all data from the input stream to the output stream and close the - * input stream. Exceptions while closing are ignored. - * - * @param in the input stream - * @param out the output stream - * @return the number of bytes copied - */ - public static long copyAndCloseInput(InputStream in, OutputStream out) throws IOException { - try { - return copy(in, out); - } finally { - closeSilently(in); - } - } - - /** - * Copy all data from the input stream to the output stream. Both streams - * are kept open. - * - * @param in the input stream - * @param out the output stream - * @return the number of bytes copied - */ - public static long copy(InputStream in, OutputStream out) throws IOException { - long written = 0; - byte[] buffer = new byte[4 * 1024]; - while (true) { - int len = in.read(buffer); - if (len < 0) { - break; - } - out.write(buffer, 0, len); - written += len; - } - return written; - } - - /** - * Copy all data from the reader to the writer and close the reader. - * Exceptions while closing are ignored. - * - * @param in the reader - * @param out the writer - * @return the number of characters copied - */ - public static long copyAndCloseInput(Reader in, Writer out) throws IOException { - long written = 0; - try { - char[] buffer = new char[4 * 1024]; - while (true) { - int len = in.read(buffer); - if (len < 0) { - break; - } - out.write(buffer, 0, len); - written += len; - } - } finally { - in.close(); - } - return written; - } - - /** - * Close an input stream without throwing an exception. - * - * @param in the input stream or null - */ - public static void closeSilently(InputStream in) { - if (in != null) { - try { - trace("closeSilently", null, in); - in.close(); - } catch (IOException e) { - // ignore - } - } - } - - /** - * Close a reader without throwing an exception. - * - * @param reader the reader or null - */ - public static void closeSilently(Reader reader) { - if (reader != null) { - try { - reader.close(); - } catch (IOException e) { - // ignore - } - } - } - - /** - * Close a writer without throwing an exception. - * - * @param writer the writer or null - */ - public static void closeSilently(Writer writer) { - if (writer != null) { - try { - writer.flush(); - writer.close(); - } catch (IOException e) { - // ignore - } - } - } - - /** - * Read a number of bytes from an input stream and close the stream. - * - * @param in the input stream - * @param length the maximum number of bytes to read, or -1 to read until - * the end of file - * @return the bytes read - */ - public static byte[] readBytesAndClose(InputStream in, int length) throws IOException { - try { - if (length <= 0) { - length = Integer.MAX_VALUE; - } - int block = Math.min(BUFFER_BLOCK_SIZE, length); - ByteArrayOutputStream out = new ByteArrayOutputStream(block); - byte[] buff = new byte[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; - } - return out.toByteArray(); - } finally { - in.close(); - } - } - - /** - * Read a number of characters from a reader and close it. - * - * @param in the reader - * @param length the maximum number of characters to read, or -1 to read - * until the end of file - * @return the string read - */ - public static String readStringAndClose(Reader in, int length) throws IOException { - try { - if (length <= 0) { - length = Integer.MAX_VALUE; - } - int block = Math.min(BUFFER_BLOCK_SIZE, 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; - } - return out.toString(); - } finally { - in.close(); - } - } - - /** - * Try to read the given number of bytes to the buffer. This method reads - * until the maximum number of bytes have been read or until the end of - * file. - * - * @param in the input stream - * @param buffer the output buffer - * @param off the offset in the buffer - * @param max the number of bytes to read at most - * @return the number of bytes read, 0 meaning EOF - */ - public static int readFully(InputStream in, byte[] buffer, int off, int max) throws IOException { - int len = Math.min(max, buffer.length); - int result = 0; - while (len > 0) { - int l = in.read(buffer, off, len); - if (l < 0) { - break; - } - result += l; - off += l; - len -= l; - } - return result; - } - - /** - * Try to read the given number of characters to the buffer. This method - * reads until the maximum number of characters have been read or until the - * end of file. - * - * @param in the reader - * @param buffer the output buffer - * @param max the number of characters to read at most - * @return the number of characters read - */ - public static int readFully(Reader in, char[] buffer, int max) throws IOException { - int off = 0, len = Math.min(max, buffer.length); - if (len == 0) { - return 0; - } - while (true) { - int l = len - off; - if (l <= 0) { - break; - } - l = in.read(buffer, off, l); - if (l < 0) { - break; - } - off += l; - } - return off <= 0 ? -1 : off; - } - - /** - * Create a reader to read from an input stream using the UTF-8 format. If - * the input stream is null, this method returns null. - * - * @param in the input stream or null - * @return the reader - */ - public static Reader getReader(InputStream in) { - try { - // InputStreamReader may read some more bytes - return in == null ? null : new BufferedReader(new InputStreamReader(in, Constants.UTF8)); - } catch (Exception e) { - // UnsupportedEncodingException - throw DbException.convert(e); - } - } - - /** - * Create a buffered writer to write to an output stream using the UTF-8 - * format. If the output stream is null, this method returns null. - * - * @param out the output stream or null - * @return the writer - */ - public static Writer getWriter(OutputStream out) { - try { - return out == null ? null : new BufferedWriter(new OutputStreamWriter(out, Constants.UTF8)); - } catch (Exception e) { - // UnsupportedEncodingException - throw DbException.convert(e); - } - } - - /** - * Create an input stream to read from a string. The string is converted to - * a byte array using UTF-8 encoding. - * If the string is null, this method returns null. - * - * @param s the string - * @return the input stream - */ - public static InputStream getInputStream(String s) { - if (s == null) { - return null; - } - return new ByteArrayInputStream(StringUtils.utf8Encode(s)); - } - - /** - * Create a reader to read from a string. - * If the string is null, this method returns null. - * - * @param s the string or null - * @return the reader - */ - public static Reader getReader(String s) { - return s == null ? null : new StringReader(s); - } - - /** - * Wrap an input stream in a reader. The bytes are converted to characters - * using the US-ASCII character set. - * - * @param in the input stream - * @return the reader - */ - public static Reader getAsciiReader(InputStream in) { - try { - return in == null ? null : new InputStreamReader(in, "US-ASCII"); - } catch (Exception e) { - // UnsupportedEncodingException - throw DbException.convert(e); - } - } - - /** - * Create the directory and all parent directories if required. - * - * @param directory the directory - * @throws IOException - */ - public static void mkdirs(File directory) throws IOException { - // loop, to deal with race conditions (if another thread creates or - // deletes the same directory at the same time). - for (int i = 0; i < 5; i++) { - if (directory.exists()) { - if (directory.isDirectory()) { - return; - } - throw new IOException("Could not create directory, because a file with the same name already exists: " + directory.getAbsolutePath()); - } - if (directory.mkdirs()) { - return; - } - } - throw new IOException("Could not create directory: " + directory.getAbsolutePath()); - } - - /** - * Change the length of the file. - * - * @param file the random access file - * @param newLength the new length - */ - public static void setLength(RandomAccessFile file, long newLength) throws IOException { - try { - trace("setLength", null, file); - file.setLength(newLength); - } catch (IOException e) { - long length = file.length(); - if (newLength < length) { - throw e; - } - long pos = file.getFilePointer(); - file.seek(length); - long remaining = newLength - length; - int maxSize = 1024 * 1024; - int block = (int) Math.min(remaining, maxSize); - byte[] buffer = new byte[block]; - while (remaining > 0) { - int write = (int) Math.min(remaining, maxSize); - file.write(buffer, 0, write); - remaining -= write; - } - file.seek(pos); - } - } - - /** - * Get the absolute file path of a file in the user home directory. - * - * @param fileName the file name - * @return the absolute path - */ - public static String getFileInUserHome(String fileName) { - String userDir = SysProperties.USER_HOME; - if (userDir == null) { - return fileName; - } - File file = new File(userDir, fileName); - return file.getAbsolutePath(); - } - - /** - * Get the file name (without directory part). - * - * @param name the directory and file name - * @return just the file name - */ - public static String getFileName(String name) { - return FileSystem.getInstance(name).getFileName(name); - } - - /** - * Normalize a file name. - * - * @param fileName the file name - * @return the normalized file name - */ - public static String normalize(String fileName) { - return FileSystem.getInstance(fileName).normalize(fileName); - } - - /** - * Try to delete a file. - * - * @param fileName the file name - * @return true if it worked - */ - public static boolean tryDelete(String fileName) { - return FileSystem.getInstance(fileName).tryDelete(fileName); - } - - /** - * Check if a file is read-only. - * - * @param fileName the file name - * @return if it is read only - */ - public static boolean isReadOnly(String fileName) { - return FileSystem.getInstance(fileName).isReadOnly(fileName); - } - - /** - * Checks if a file exists. - * - * @param fileName the file name - * @return true if it exists - */ - public static boolean exists(String fileName) { - return FileSystem.getInstance(fileName).exists(fileName); - } - - /** - * Get the length of a file. - * - * @param fileName the file name - * @return the length in bytes - */ - public static long length(String fileName) { - return FileSystem.getInstance(fileName).length(fileName); - } - - /** - * Create a new temporary file. - * - * @param prefix the prefix of the file name (including directory name if - * required) - * @param suffix the suffix - * @param deleteOnExit if the file should be deleted when the virtual - * machine exists - * @param inTempDir if the file should be stored in the temporary directory - * @return the name of the created file - */ - public static String createTempFile(String prefix, String suffix, boolean deleteOnExit, boolean inTempDir) - throws IOException { - return FileSystem.getInstance(prefix).createTempFile(prefix, suffix, deleteOnExit, inTempDir); - } - - /** - * Get the parent directory of a file or directory. - * - * @param fileName the file or directory name - * @return the parent directory name - */ - public static String getParent(String fileName) { - return FileSystem.getInstance(fileName).getParent(fileName); - } - - /** - * List the files in the given directory. - * - * @param path the directory - * @return the list of fully qualified file names - */ - public static String[] listFiles(String path) { - return FileSystem.getInstance(path).listFiles(path); - } - - /** - * Check if it is a file or a directory. - * - * @param fileName the file or directory name - * @return true if it is a directory - */ - public static boolean isDirectory(String fileName) { - return FileSystem.getInstance(fileName).isDirectory(fileName); - } - - /** - * Check if the file name includes a path. - * - * @param fileName the file name - * @return if the file name is absolute - */ - public static boolean isAbsolute(String fileName) { - return FileSystem.getInstance(fileName).isAbsolute(fileName); - } - - /** - * Get the absolute file name. - * - * @param fileName the file name - * @return the absolute file name - */ - public static String getAbsolutePath(String fileName) { - return FileSystem.getInstance(fileName).getAbsolutePath(fileName); - } - - /** - * Check if a file starts with a given prefix. - * - * @param fileName the complete file name - * @param prefix the prefix - * @return true if it starts with the prefix - */ - public static boolean fileStartsWith(String fileName, String prefix) { - return FileSystem.getInstance(fileName).fileStartsWith(fileName, prefix); - } - - /** - * Create an input stream to read from the file. - * - * @param fileName the file name - * @return the input stream - */ - public static InputStream openFileInputStream(String fileName) throws IOException { - return FileSystem.getInstance(fileName).openFileInputStream(fileName); - } - - /** - * Create an output stream to write into the file. - * - * @param fileName the file name - * @param append if true, the file will grow, if false, the file will be - * truncated first - * @return the output stream - */ - public static OutputStream openFileOutputStream(String fileName, boolean append) { - return FileSystem.getInstance(fileName).openFileOutputStream(fileName, append); - } - - /** - * Rename a file if this is allowed. - * - * @param oldName the old fully qualified file name - * @param newName the new fully qualified file name - */ - public static void rename(String oldName, String newName) { - FileSystem.getInstance(oldName).rename(oldName, newName); - } - - /** - * Create all required directories that are required for this file. - * - * @param fileName the file name (not directory name) - */ - public static void createDirs(String fileName) { - FileSystem.getInstance(fileName).createDirs(fileName); - } - - /** - * Delete a file. - * - * @param fileName the file name - */ - public static void delete(String fileName) { - FileSystem.getInstance(fileName).delete(fileName); - } - - /** - * Get the last modified date of a file. - * - * @param fileName the file name - * @return the last modified date - */ - public static long getLastModified(String fileName) { - return FileSystem.getInstance(fileName).getLastModified(fileName); - } - - /** - * Trace input or output operations if enabled. - * - * @param method the method from where this method was called - * @param fileName the file name - * @param o the object to append to the message - */ - static void trace(String method, String fileName, Object o) { - if (SysProperties.TRACE_IO) { - System.out.println("IOUtils." + method + " " + fileName + " " + o); - } - } - - /** - * Checks if a file is below a given directory - * - * @param file the file to check - * @param dir the directory the file must be in - * @return true if the file is within the directory - */ - public static boolean isInDir(File file, File dir) { - try { - String canonicalFileName = file.getCanonicalPath(); - String canonicalDirName = dir.getCanonicalPath(); - if (canonicalFileName.equals(canonicalDirName)) { - // the file is the directory: not allowed (file "../test" in dir "test") - return false; - } - return canonicalFileName.startsWith(canonicalDirName); - } catch (IOException e) { - return false; - } - } - -} diff --git a/tools/h2/src/main/org/h2/util/IntArray.java b/tools/h2/src/main/org/h2/util/IntArray.java deleted file mode 100755 index 234ad12..0000000 --- a/tools/h2/src/main/org/h2/util/IntArray.java +++ /dev/null @@ -1,161 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.util; - -import org.h2.constant.SysProperties; - -/** - * An array with integer element. - */ -public class IntArray { - - private int[] data; - private int size; - private int hash; - - /** - * Create an int array with the default initial capacity. - */ - public IntArray() { - this(10); - } - - /** - * Create an int array with specified initial capacity. - * - * @param capacity the initial capacity - */ - public IntArray(int capacity) { - data = new int[capacity]; - } - - /** - * Create an int array with the given values and size. - * - * @param data the int array - */ - public IntArray(int[] data) { - this.data = data; - size = data.length; - } - - /** - * Append a value. - * - * @param value the value to append - */ - public void add(int value) { - checkCapacity(); - data[size++] = value; - } - - /** - * Get the value at the given index. - * - * @param index the index - * @return the value - */ - public int get(int index) { - if (SysProperties.CHECK && index >= size) { - throw new ArrayIndexOutOfBoundsException("i=" + index + " size=" + size); - } - return data[index]; - } - - /** - * Remove the value at the given index. - * - * @param index the index - */ - public void remove(int index) { - if (SysProperties.CHECK && index >= size) { - throw new ArrayIndexOutOfBoundsException("i=" + index + " size=" + size); - } - System.arraycopy(data, index + 1, data, index, size - index - 1); - size--; - } - - private void checkCapacity() { - if (size >= data.length) { - int[] d = new int[Math.max(4, data.length * 2)]; - System.arraycopy(data, 0, d, 0, data.length); - data = d; - } - } - - public boolean equals(Object obj) { - if (!(obj instanceof IntArray)) { - return false; - } - IntArray other = (IntArray) obj; - if (hashCode() != other.hashCode() || size != other.size) { - return false; - } - for (int i = 0; i < size; i++) { - if (data[i] != other.data[i]) { - return false; - } - } - return true; - } - - public int hashCode() { - if (hash != 0) { - return hash; - } - int h = size + 1; - for (int i = 0; i < size; i++) { - h = h * 31 + data[i]; - } - hash = h; - return h; - } - - /** - * Get the size of the list. - * - * @return the size - */ - public int size() { - return size; - } - - /** - * Convert this list to an array. The target array must be big enough. - * - * @param array the target array - */ - public void toArray(int[] array) { - System.arraycopy(data, 0, array, 0, size); - } - - public String toString() { - StatementBuilder buff = new StatementBuilder("{"); - for (int i = 0; i < size; i++) { - buff.appendExceptFirst(", "); - buff.append(data[i]); - } - return buff.append('}').toString(); - } - - /** - * Remove a number of elements. - * - * @param fromIndex the index of the first item to remove - * @param toIndex upper bound (exclusive) - */ - public void removeRange(int fromIndex, int toIndex) { - if (SysProperties.CHECK) { - if (fromIndex > toIndex || toIndex > size) { - throw new ArrayIndexOutOfBoundsException("from=" + fromIndex + " to=" + toIndex + " size=" + size); - } - } - System.arraycopy(data, toIndex, data, fromIndex, size - toIndex); - size -= toIndex - fromIndex; - } - -} diff --git a/tools/h2/src/main/org/h2/util/IntIntHashMap.java b/tools/h2/src/main/org/h2/util/IntIntHashMap.java deleted file mode 100755 index 2784dc1..0000000 --- a/tools/h2/src/main/org/h2/util/IntIntHashMap.java +++ /dev/null @@ -1,159 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.util; - -import org.h2.message.DbException; - -/** - * A hash map with int key and int values. There is a restriction: the - * value -1 (NOT_FOUND) cannot be stored in the map. 0 can be stored. - * An empty record has key=0 and value=0. - * A deleted record has key=0 and value=DELETED - */ -public class IntIntHashMap extends HashBase { - - /** - * The value indicating that the entry has not been found. - */ - public static final int NOT_FOUND = -1; - - private static final int DELETED = 1; - private int[] keys; - private int[] values; - private int zeroValue; - - protected void reset(int newLevel) { - super.reset(newLevel); - keys = new int[len]; - values = new int[len]; - } - - /** - * Store the given key-value pair. The value is overwritten or added. - * - * @param key the key - * @param value the value (-1 is not supported) - */ - public void put(int key, int value) { - if (key == 0) { - zeroKey = true; - zeroValue = value; - } - try { - checkSizePut(); - } catch (Exception e) { - // in fact, it is never thrown - // TODO hash: maybe optimize it - } - int index = getIndex(key); - int plus = 1; - int deleted = -1; - do { - int k = keys[index]; - if (k == 0) { - if (values[index] != DELETED) { - // found an empty record - if (deleted >= 0) { - index = deleted; - deletedCount--; - } - size++; - keys[index] = key; - values[index] = value; - return; - } - // found a deleted record - if (deleted < 0) { - deleted = index; - } - } else if (k == key) { - // update existing - values[index] = value; - return; - } - index = (index + plus++) & mask; - } while(plus <= len); - // no space - DbException.throwInternalError("hashmap is full"); - } - - /** - * Remove the key-value pair with the given key. - * - * @param key the key - */ - public void remove(int key) { - if (key == 0) { - zeroKey = false; - return; - } - try { - checkSizeRemove(); - } catch (Exception e) { - // in fact, it is never thrown - // TODO hash: maybe optimize it - } - int index = getIndex(key); - int plus = 1; - do { - int k = keys[index]; - if (k == key) { - // found the record - keys[index] = 0; - values[index] = DELETED; - deletedCount++; - size--; - return; - } else if (k == 0 && values[index] == 0) { - // found an empty record - return; - } - index = (index + plus++) & mask; - } while(plus <= len); - // not found - } - - protected void rehash(int newLevel) { - int[] oldKeys = keys; - int[] oldValues = values; - reset(newLevel); - for (int i = 0; i < oldKeys.length; i++) { - int k = oldKeys[i]; - if (k != 0) { - put(k, oldValues[i]); - } - } - } - - /** - * Get the value for the given key. This method returns NOT_FOUND if the - * entry has not been found. - * - * @param key the key - * @return the value or NOT_FOUND - */ - public int get(int key) { - if (key == 0) { - return zeroKey ? zeroValue : NOT_FOUND; - } - int index = getIndex(key); - int plus = 1; - do { - int k = keys[index]; - if (k == 0 && values[index] == 0) { - // found an empty record - return NOT_FOUND; - } else if (k == key) { - // found it - return values[index]; - } - index = (index + plus++) & mask; - } while(plus <= len); - return NOT_FOUND; - } - -} diff --git a/tools/h2/src/main/org/h2/util/JdbcUtils.java b/tools/h2/src/main/org/h2/util/JdbcUtils.java deleted file mode 100755 index 08f3a0b..0000000 --- a/tools/h2/src/main/org/h2/util/JdbcUtils.java +++ /dev/null @@ -1,223 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.util; - -import java.sql.Connection; -import java.sql.DriverManager; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.sql.Statement; -import java.util.Properties; -import javax.naming.Context; -import javax.sql.DataSource; -import javax.sql.XAConnection; -import org.h2.message.DbException; - -/** - * This is a utility class with JDBC helper functions. - */ -public class JdbcUtils { - - private static final String[] DRIVERS = { - "h2:", "org.h2.Driver", - "Cache:", "com.intersys.jdbc.CacheDriver", - "daffodilDB://", "in.co.daffodil.db.rmi.RmiDaffodilDBDriver", - "daffodil", "in.co.daffodil.db.jdbc.DaffodilDBDriver", - "db2:", "COM.ibm.db2.jdbc.net.DB2Driver", - "derby:net:", "org.apache.derby.jdbc.ClientDriver", - "derby://", "org.apache.derby.jdbc.ClientDriver", - "derby:", "org.apache.derby.jdbc.EmbeddedDriver", - "FrontBase:", "com.frontbase.jdbc.FBJDriver", - "firebirdsql:", "org.firebirdsql.jdbc.FBDriver", - "hsqldb:", "org.hsqldb.jdbcDriver", - "informix-sqli:", "com.informix.jdbc.IfxDriver", - "jtds:", "net.sourceforge.jtds.jdbc.Driver", - "microsoft:", "com.microsoft.jdbc.sqlserver.SQLServerDriver", - "mimer:", "com.mimer.jdbc.Driver", - "mysql:", "com.mysql.jdbc.Driver", - "odbc:", "sun.jdbc.odbc.JdbcOdbcDriver", - "oracle:", "oracle.jdbc.driver.OracleDriver", - "pervasive:", "com.pervasive.jdbc.v2.Driver", - "pointbase:micro:", "com.pointbase.me.jdbc.jdbcDriver", - "pointbase:", "com.pointbase.jdbc.jdbcUniversalDriver", - "postgresql:", "org.postgresql.Driver", - "sybase:", "com.sybase.jdbc3.jdbc.SybDriver", - "sqlserver:", "com.microsoft.sqlserver.jdbc.SQLServerDriver", - "teradata:", "com.ncr.teradata.TeraDriver", - }; - - private JdbcUtils() { - // utility class - } - - /** - * Close a statement without throwing an exception. - * - * @param stat the statement or null - */ - public static void closeSilently(Statement stat) { - if (stat != null) { - try { - stat.close(); - } catch (SQLException e) { - // ignore - } - } - } - - /** - * Close a connection without throwing an exception. - * - * @param conn the connection or null - */ - public static void closeSilently(Connection conn) { - if (conn != null) { - try { - conn.close(); - } catch (SQLException e) { - // ignore - } - } - } - - /** - * Close a result set without throwing an exception. - * - * @param rs the result set or null - */ - public static void closeSilently(ResultSet rs) { - if (rs != null) { - try { - rs.close(); - } catch (SQLException e) { - // ignore - } - } - } - - /** - * Close an XA connection set without throwing an exception. - * - * @param conn the XA connection or null - */ -//## Java 1.4 begin ## - public static void closeSilently(XAConnection conn) { - if (conn != null) { - try { - conn.close(); - } catch (SQLException e) { - // ignore - } - } - } -//## Java 1.4 end ## - - /** - * Open a new database connection with the given settings. - * - * @param driver the driver class name - * @param url the database URL - * @param user the user name - * @param password the password - * @return the database connection - */ - public static Connection getConnection(String driver, String url, String user, String password) throws SQLException { - Properties prop = new Properties(); - if (user != null) { - prop.setProperty("user", user); - } - if (password != null) { - prop.setProperty("password", password); - } - return getConnection(driver, url, prop); - } - - /** - * Escape table or schema patterns used for DatabaseMetaData functions. - * - * @param pattern the pattern - * @return the escaped pattern - */ - public static String escapeMetaDataPattern(String pattern) { - if (pattern == null || pattern.length() == 0) { - return pattern; - } - return StringUtils.replaceAll(pattern, "\\", "\\\\"); - } - - /** - * Open a new database connection with the given settings. - * - * @param driver the driver class name - * @param url the database URL - * @param prop the properties containing at least the user name and password - * @return the database connection - */ - public static Connection getConnection(String driver, String url, Properties prop) throws SQLException { - if (StringUtils.isNullOrEmpty(driver)) { - JdbcUtils.load(url); - } else { - Class< ? > d = Utils.loadUserClass(driver); - if (java.sql.Driver.class.isAssignableFrom(d)) { - return DriverManager.getConnection(url, prop); - //## Java 1.4 begin ## - } else if (javax.naming.Context.class.isAssignableFrom(d)) { - // JNDI context - try { - Context context = (Context) d.newInstance(); - DataSource ds = (DataSource) context.lookup(url); - String user = prop.getProperty("user"); - String password = prop.getProperty("password"); - if (StringUtils.isNullOrEmpty(user) && StringUtils.isNullOrEmpty(password)) { - return ds.getConnection(); - } - return ds.getConnection(user, password); - } catch (Exception e) { - throw DbException.toSQLException(e); - } - //## Java 1.4 end ## - } else { - // Don't know, but maybe it loaded a JDBC Driver - return DriverManager.getConnection(url, prop); - } - } - return DriverManager.getConnection(url, prop); - } - - /** - * Get the driver class name for the given URL, or null if the URL is - * unknown. - * - * @param url the database URL - * @return the driver class name - */ - public static String getDriver(String url) { - if (url.startsWith("jdbc:")) { - url = url.substring("jdbc:".length()); - for (int i = 0; i < DRIVERS.length; i += 2) { - String prefix = DRIVERS[i]; - if (url.startsWith(prefix)) { - return DRIVERS[i + 1]; - } - } - } - return null; - } - - /** - * Load the driver class for the given URL, if the database URL is known. - * - * @param url the database URL - */ - public static void load(String url) { - String driver = getDriver(url); - if (driver != null) { - Utils.loadUserClass(driver); - } - } - -} diff --git a/tools/h2/src/main/org/h2/util/MathUtils.java b/tools/h2/src/main/org/h2/util/MathUtils.java deleted file mode 100755 index af6a761..0000000 --- a/tools/h2/src/main/org/h2/util/MathUtils.java +++ /dev/null @@ -1,415 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.util; - -import java.io.ByteArrayOutputStream; -import java.io.DataOutputStream; -import java.io.IOException; -import java.lang.reflect.Method; -import java.math.BigDecimal; -import java.security.SecureRandom; -import java.util.Random; -import org.h2.message.DbException; - -/** - * This is a utility class with mathematical helper functions. - */ -public class MathUtils { - - /** - * The secure random object. - */ - static SecureRandom cachedSecureRandom; - - /** - * True if the secure random object is seeded. - */ - static volatile boolean seeded; - - private static boolean usePrecisionWorkaround; - - private static final Random RANDOM = new Random(); - - /** - * The maximum scale of a BigDecimal value. - */ - private static final int BIG_DECIMAL_SCALE_MAX = 100000; - - - private MathUtils() { - // utility class - } - - private static synchronized SecureRandom getSecureRandom() { - if (cachedSecureRandom != null) { - return cachedSecureRandom; - } - // Workaround for SecureRandom problem as described in - // http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6202721 - // Can not do that in a static initializer block, because - // threads are not started until after the initializer block exits - try { - cachedSecureRandom = SecureRandom.getInstance("SHA1PRNG"); - // On some systems, secureRandom.generateSeed() is very slow. - // In this case it is initialized using our own seed implementation - // and afterwards (in the thread) using the regular algorithm. - Runnable runnable = new Runnable() { - public void run() { - try { - SecureRandom sr = SecureRandom.getInstance("SHA1PRNG"); - byte[] seed = sr.generateSeed(20); - synchronized (cachedSecureRandom) { - cachedSecureRandom.setSeed(seed); - seeded = true; - } - } catch (Exception e) { - // NoSuchAlgorithmException - warn("SecureRandom", e); - } - } - }; - - try { - Thread t = new Thread(runnable); - // let the process terminate even if generating the seed is really slow - t.setDaemon(true); - t.start(); - Thread.yield(); - try { - // normally, generateSeed takes less than 200 ms - t.join(400); - } catch (InterruptedException e) { - warn("InterruptedException", e); - } - if (!seeded) { - byte[] seed = generateAlternativeSeed(); - // this never reduces randomness - synchronized (cachedSecureRandom) { - cachedSecureRandom.setSeed(seed); - } - } - } catch (SecurityException e) { - // workaround for the Google App Engine: don't use a thread - runnable.run(); - generateAlternativeSeed(); - } - - } catch (Exception e) { - // NoSuchAlgorithmException - warn("SecureRandom", e); - cachedSecureRandom = new SecureRandom(); - } - return cachedSecureRandom; - } - - private static byte[] generateAlternativeSeed() { - try { - ByteArrayOutputStream bout = new ByteArrayOutputStream(); - DataOutputStream out = new DataOutputStream(bout); - - // milliseconds - out.writeLong(System.currentTimeMillis()); - - // nanoseconds if available - try { - Method m = System.class.getMethod("nanoTime"); - if (m != null) { - Object o = m.invoke(null); - out.writeUTF(o.toString()); - } - } catch (Exception e) { - // nanoTime not found, this is ok (only exists for JDK 1.5 and higher) - } - - // memory - out.writeInt(new Object().hashCode()); - Runtime runtime = Runtime.getRuntime(); - out.writeLong(runtime.freeMemory()); - out.writeLong(runtime.maxMemory()); - out.writeLong(runtime.totalMemory()); - - // environment - try { - out.writeUTF(System.getProperties().toString()); - } catch (Exception e) { - warn("generateAlternativeSeed", e); - } - - // host name and ip addresses (if any) - try { - // workaround for the Google App Engine: don't use InetAddress - Class< ? > inetAddressClass = Class.forName("java.net.InetAddress"); - Object localHost = inetAddressClass.getMethod("getLocalHost").invoke(null); - String hostName = inetAddressClass.getMethod("getHostName").invoke(localHost).toString(); - out.writeUTF(hostName); - Object[] list = (Object[]) inetAddressClass.getMethod("getAllByName", String.class).invoke(null, hostName); - Method getAddress = inetAddressClass.getMethod("getAddress"); - for (Object o : list) { - out.write((byte[]) getAddress.invoke(o)); - } - } catch (Throwable e) { - // on some system, InetAddress is not supported - // on some system, InetAddress.getLocalHost() doesn't work - // for some reason (incorrect configuration) - } - - // timing (a second thread is already running usually) - for (int j = 0; j < 16; j++) { - int i = 0; - long end = System.currentTimeMillis(); - while (end == System.currentTimeMillis()) { - i++; - } - out.writeInt(i); - } - - out.close(); - return bout.toByteArray(); - } catch (IOException e) { - warn("generateAlternativeSeed", e); - return new byte[1]; - } - } - - /** - * Print a message to system output if there was a problem initializing the - * random number generator. - * - * @param s the message to print - * @param t the stack trace - */ - static void warn(String s, Throwable t) { - // not a fatal problem, but maybe reduced security - System.out.println("RandomUtils warning: " + s); - if (t != null) { - t.printStackTrace(); - } - } - - /** - * Round the value up to the next block size. The block size must be a power - * of two. As an example, using the block size of 8, the following rounding - * operations are done: 0 stays 0; values 1..8 results in 8, 9..16 results - * in 16, and so on. - * - * @param x the value to be rounded - * @param blockSizePowerOf2 the block size - * @return the rounded value - */ - public static int roundUpInt(int x, int blockSizePowerOf2) { - return (x + blockSizePowerOf2 - 1) & (-blockSizePowerOf2); - } - - /** - * Round the value up to the next block size. The block size must be a power - * of two. As an example, using the block size of 8, the following rounding - * operations are done: 0 stays 0; values 1..8 results in 8, 9..16 results - * in 16, and so on. - * - * @param x the value to be rounded - * @param blockSizePowerOf2 the block size - * @return the rounded value - */ - public static long roundUpLong(long x, long blockSizePowerOf2) { - return (x + blockSizePowerOf2 - 1) & (-blockSizePowerOf2); - } - - /** - * Check if a value is a power of two. - * - * @param len the value to check - * @throws RuntimeException if it is not a power of two - */ - public static void checkPowerOf2(int len) { - if ((len & (len - 1)) != 0 && len > 0) { - DbException.throwInternalError("not a power of 2: " + len); - } - } - - /** - * Get the value that is equal or higher than this value, and that is a - * power of two. - * - * @param x the original value - * @return the next power of two value - */ - public static int nextPowerOf2(int x) { - long i = 1; - while (i < x && i < (Integer.MAX_VALUE / 2)) { - i += i; - } - return (int) i; - } - - /** - * Set the scale of a BigDecimal value. - * - * @param bd the BigDecimal value - * @param scale the new scale - * @return the scaled value - */ - public static BigDecimal setScale(BigDecimal bd, int scale) { - if (scale > BIG_DECIMAL_SCALE_MAX) { - throw DbException.getInvalidValueException("" + scale, "scale"); - } else if (scale < -BIG_DECIMAL_SCALE_MAX) { - throw DbException.getInvalidValueException("" + scale, "scale"); - } - return bd.setScale(scale, BigDecimal.ROUND_HALF_UP); - } - - /** - * Convert a long value to an int value. Values larger than the biggest int - * value is converted to the biggest int value, and values smaller than the - * smallest int value are converted to the smallest int value. - * - * @param l the value to convert - * @return the converted int value - */ - public static int convertLongToInt(long l) { - if (l <= Integer.MIN_VALUE) { - return Integer.MIN_VALUE; - } else if (l >= Integer.MAX_VALUE) { - return Integer.MAX_VALUE; - } else { - return (int) l; - } - } - - /** - * Reverse the bits in a 32 bit integer. This code is also available in Java - * 5 using Integer.reverse, however not available yet in Retrotranslator. - * The code was taken from http://www.hackersdelight.org - reverse.c - * - * @param x the original value - * @return the value with reversed bits - */ - public static int reverseInt(int x) { - x = (x & 0x55555555) << 1 | (x >>> 1) & 0x55555555; - x = (x & 0x33333333) << 2 | (x >>> 2) & 0x33333333; - x = (x & 0x0f0f0f0f) << 4 | (x >>> 4) & 0x0f0f0f0f; - x = (x << 24) | ((x & 0xff00) << 8) | ((x >>> 8) & 0xff00) | (x >>> 24); - return x; - } - - /** - * Reverse the bits in a 64 bit long. This code is also available in Java 5 - * using Long.reverse, however not available yet in Retrotranslator. - * - * @param x the original value - * @return the value with reversed bits - */ - public static long reverseLong(long x) { - return (reverseInt((int) (x >>> 32L)) & 0xffffffffL) ^ (((long) reverseInt((int) x)) << 32L); - } - - /** - * Compatibility for BigDecimal.precision() which is not available in Java 1.4. - * - * @param x the value - * @return the precision - */ - public static int precision(BigDecimal x) { - if (!usePrecisionWorkaround) { - try { - return x.precision(); - } catch (Exception e) { - // NoSuchMethodError - usePrecisionWorkaround = true; - } - } - return x.unscaledValue().abs().toString().length(); - } - - /** - * Compare two values. Returns -1 if the first value is smaller, 1 if bigger, - * and 0 if equal. - * - * @param a the first value - * @param b the second value - * @return the result - */ - public static int compareInt(int a, int b) { - return a == b ? 0 : a < b ? -1 : 1; - } - - /** - * Compare two values. Returns -1 if the first value is smaller, 1 if bigger, - * and 0 if equal. - * - * @param a the first value - * @param b the second value - * @return the result - */ - public static int compareLong(long a, long b) { - return a == b ? 0 : a < b ? -1 : 1; - } - - /** - * Get a cryptographically secure pseudo random long value. - * - * @return the random long value - */ - public static long secureRandomLong() { - SecureRandom sr = getSecureRandom(); - synchronized (sr) { - return sr.nextLong(); - } - } - - /** - * Get a number of pseudo random bytes. - * - * @param bytes the target array - */ - public static void randomBytes(byte[] bytes) { - RANDOM.nextBytes(bytes); - } - - /** - * Get a number of cryptographically secure pseudo random bytes. - * - * @param len the number of bytes - * @return the random bytes - */ - public static byte[] secureRandomBytes(int len) { - if (len <= 0) { - len = 1; - } - byte[] buff = new byte[len]; - SecureRandom sr = getSecureRandom(); - synchronized (sr) { - sr.nextBytes(buff); - } - return buff; - } - - /** - * Get a pseudo random int value between 0 (including and the given value - * (excluding). The value is not cryptographically secure. - * - * @param lowerThan the value returned will be lower than this value - * @return the random long value - */ - public static int randomInt(int lowerThan) { - return RANDOM.nextInt(lowerThan); - } - - /** - * Get a cryptographically secure pseudo random int value between 0 - * (including and the given value (excluding). - * - * @param lowerThan the value returned will be lower than this value - * @return the random long value - */ - public static int secureRandomInt(int lowerThan) { - SecureRandom sr = getSecureRandom(); - synchronized (sr) { - return sr.nextInt(lowerThan); - } - } - -} diff --git a/tools/h2/src/main/org/h2/util/NetUtils.java b/tools/h2/src/main/org/h2/util/NetUtils.java deleted file mode 100755 index 3c483f9..0000000 --- a/tools/h2/src/main/org/h2/util/NetUtils.java +++ /dev/null @@ -1,262 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.util; - -import java.io.IOException; -import java.net.BindException; -import java.net.Inet6Address; -import java.net.InetAddress; -import java.net.InetSocketAddress; -import java.net.ServerSocket; -import java.net.Socket; -import java.net.UnknownHostException; -import org.h2.constant.ErrorCode; -import org.h2.constant.SysProperties; -import org.h2.message.DbException; -import org.h2.security.CipherFactory; - -/** - * This utility class contains socket helper functions. - */ -public class NetUtils { - - private static final int CACHE_MILLIS = 1000; - private static InetAddress cachedBindAddress; - private static String cachedLocalAddress; - private static long cachedLocalAddressTime; - - private NetUtils() { - // utility class - } - - /** - * Create a loopback socket (a socket that is connected to localhost) on - * this port. - * - * @param port the port - * @param ssl if SSL should be used - * @return the socket - */ - public static Socket createLoopbackSocket(int port, boolean ssl) throws IOException { - InetAddress address = getBindAddress(); - if (address == null) { - address = InetAddress.getLocalHost(); - } - return createSocket(getHostAddress(address), port, ssl); - } - - /** - * Get the host address. This method adds '[' and ']' if required for - * Inet6Address that contain a ':'. - * - * @param address the address - * @return the host address - */ - private static String getHostAddress(InetAddress address) { - String host = address.getHostAddress(); - if (address instanceof Inet6Address) { - if (host.indexOf(':') >= 0 && !host.startsWith("[")) { - host = "[" + host + "]"; - } - } - return host; - } - - /** - * Create a client socket that is connected to the given address and port. - * - * @param server to connect to (including an optional port) - * @param defaultPort the default port (if not specified in the server - * address) - * @param ssl if SSL should be used - * @return the socket - */ - public static Socket createSocket(String server, int defaultPort, boolean ssl) throws IOException { - int port = defaultPort; - // IPv6: RFC 2732 format is '[a:b:c:d:e:f:g:h]' or - // '[a:b:c:d:e:f:g:h]:port' - // RFC 2396 format is 'a.b.c.d' or 'a.b.c.d:port' or 'hostname' or - // 'hostname:port' - int startIndex = server.startsWith("[") ? server.indexOf(']') : 0; - int idx = server.indexOf(':', startIndex); - if (idx >= 0) { - port = Integer.decode(server.substring(idx + 1)); - server = server.substring(0, idx); - } - InetAddress address = InetAddress.getByName(server); - return createSocket(address, port, ssl); - } - - /** - * Create a client socket that is connected to the given address and port. - * - * @param address the address to connect to - * @param port the port - * @param ssl if SSL should be used - * @return the socket - */ - public static Socket createSocket(InetAddress address, int port, boolean ssl) throws IOException { - for (int i = 0;; i++) { - try { - if (ssl) { - return CipherFactory.createSocket(address, port); - } - Socket socket = new Socket(); - socket.connect(new InetSocketAddress(address, port), - SysProperties.SOCKET_CONNECT_TIMEOUT); - return socket; - } catch (IOException e) { - if (i >= SysProperties.SOCKET_CONNECT_RETRY) { - throw e; - } - // wait a bit and retry - try { - // sleep at most 256 ms - long sleep = Math.min(256, i * i); - Thread.sleep(sleep); - } catch (InterruptedException e2) { - // ignore - } - } - } - } - - /** - * Create a server socket. The system property h2.bindAddress is used if - * set. - * - * @param port the port to listen on - * @param ssl if SSL should be used - * @return the server socket - */ - public static ServerSocket createServerSocket(int port, boolean ssl) { - try { - return createServerSocketTry(port, ssl); - } catch (Exception e) { - // try again - return createServerSocketTry(port, ssl); - } - } - - /** - * Get the bind address if the system property h2.bindAddress is set, or - * null if not. - * - * @return the bind address - */ - private static InetAddress getBindAddress() throws UnknownHostException { - String host = SysProperties.BIND_ADDRESS; - if (host == null || host.length() == 0) { - return null; - } - synchronized (NetUtils.class) { - if (cachedBindAddress == null) { - cachedBindAddress = InetAddress.getByName(host); - } - } - return cachedBindAddress; - } - - private static ServerSocket createServerSocketTry(int port, boolean ssl) { - try { - InetAddress bindAddress = getBindAddress(); - if (ssl) { - return CipherFactory.createServerSocket(port, bindAddress); - } - if (bindAddress == null) { - return new ServerSocket(port); - } - return new ServerSocket(port, 0, bindAddress); - } catch (BindException be) { - throw DbException.get(ErrorCode.EXCEPTION_OPENING_PORT_2, - be, "" + port, be.toString()); - } catch (IOException e) { - throw DbException.convertIOException(e, "port: " + port + " ssl: " + ssl); - } - } - - /** - * Check if a socket is connected to a local address. - * - * @param socket the socket - * @return true if it is - */ - public static boolean isLocalAddress(Socket socket) throws UnknownHostException { - InetAddress test = socket.getInetAddress(); - //## Java 1.4 begin ## - if (test.isLoopbackAddress()) { - return true; - } - //## Java 1.4 end ## - InetAddress localhost = InetAddress.getLocalHost(); - // localhost.getCanonicalHostName() is very very slow - String host = localhost.getHostAddress(); - for (InetAddress addr : InetAddress.getAllByName(host)) { - if (test.equals(addr)) { - return true; - } - } - return false; - } - - /** - * Close a server socket and ignore any exceptions. - * - * @param socket the socket - * @return null - */ - public static ServerSocket closeSilently(ServerSocket socket) { - if (socket != null) { - try { - socket.close(); - } catch (IOException e) { - // ignore - } - } - return null; - } - - /** - * Get the local host address as a string. - * For performance, the result is cached for one second. - * - * @return the local host address - */ - public static synchronized String getLocalAddress() { - long now = System.currentTimeMillis(); - if (cachedLocalAddress != null) { - if (cachedLocalAddressTime + CACHE_MILLIS > now) { - return cachedLocalAddress; - } - } - InetAddress bind = null; - boolean useLocalhost = false; - try { - bind = getBindAddress(); - if (bind == null) { - useLocalhost = true; - } - } catch (UnknownHostException e) { - // ignore - } - if (useLocalhost) { - try { - bind = InetAddress.getLocalHost(); - } catch (UnknownHostException e) { - throw DbException.convert(e); - } - } - String address = bind == null ? "localhost" : getHostAddress(bind); - if (address.equals("127.0.0.1")) { - address = "localhost"; - } - cachedLocalAddress = address; - cachedLocalAddressTime = now; - return address; - } - -} diff --git a/tools/h2/src/main/org/h2/util/New.java b/tools/h2/src/main/org/h2/util/New.java deleted file mode 100755 index 229a133..0000000 --- a/tools/h2/src/main/org/h2/util/New.java +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.util; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.HashMap; -import java.util.HashSet; - -/** - * This class contains static methods to construct commonly used generic objects - * such as ArrayList. - */ -public class New { - - /** - * Create a new ArrayList. - * - * @param the type - * @return the object - */ - public static ArrayList arrayList() { - return new ArrayList(); - } - - /** - * Create a new HashMap. - * - * @param the key type - * @param the value type - * @return the object - */ - public static HashMap hashMap() { - return new HashMap(); - } - - /** - * Create a new HashMap. - * - * @param the key type - * @param the value type - * @param initialCapacity the initial capacity - * @return the object - */ - public static HashMap hashMap(int initialCapacity) { - return new HashMap(initialCapacity); - } - - /** - * Create a new HashSet. - * - * @param the type - * @return the object - */ - public static HashSet hashSet() { - return new HashSet(); - } - - /** - * Create a new ArrayList. - * - * @param the type - * @param c the collection - * @return the object - */ - public static ArrayList arrayList(Collection c) { - return new ArrayList(c); - } - - /** - * Create a new ArrayList. - * - * @param the type - * @param initialCapacity the initial capacity - * @return the object - */ - public static ArrayList arrayList(int initialCapacity) { - return new ArrayList(initialCapacity); - } - -} diff --git a/tools/h2/src/main/org/h2/util/Permutations.java b/tools/h2/src/main/org/h2/util/Permutations.java deleted file mode 100755 index d5e29a6..0000000 --- a/tools/h2/src/main/org/h2/util/Permutations.java +++ /dev/null @@ -1,159 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.util; - -import org.h2.message.DbException; - -/** - * A class to iterate over all permutations of an array. - * The algorithm is from Applied Combinatorics, by Alan Tucker as implemented in - * http://www.koders.com/java/fidD3445CD11B1DC687F6B8911075E7F01E23171553.aspx - * - * @param the element type - */ -public class Permutations { - - private T[] in; - private T[] out; - private int n, m; - private int[] index; - private boolean hasNext = true; - - private Permutations(T[] in, T[] out, int m) { - this.n = in.length; - this.m = m; - if (n < m || m < 0) { - DbException.throwInternalError("n < m or m < 0"); - } - this.in = in; - this.out = out; - index = new int[n]; - for (int i = 0; i < n; i++) { - index[i] = i; - } - - // The elements from m to n are always kept ascending right to left. - // This keeps the dip in the interesting region. - reverseAfter(m - 1); - } - - /** - * Create a new permutations object. - * - * @param the type - * @param in the source array - * @param out the target array - * @return the generated permutations object - */ - public static Permutations create(T[] in, T[] out) { - return new Permutations(in, out, in.length); - } - - /** - * Create a new permutations object. - * - * @param the type - * @param in the source array - * @param out the target array - * @param m the number of output elements to generate - * @return the generated permutations object - */ - public static Permutations create(T[] in, T[] out, int m) { - return new Permutations(in, out, m); - } - - /** - * Move the index forward a notch. The algorithm first finds the rightmost - * index that is less than its neighbor to the right. This is the dip point. - * The algorithm next finds the least element to the right of the dip that - * is greater than the dip. That element is switched with the dip. Finally, - * the list of elements to the right of the dip is reversed. - * For example, in a permutation of 5 items, the index may be {1, 2, 4, 3, - * 0}. The dip is 2 the rightmost element less than its neighbor on its - * right. The least element to the right of 2 that is greater than 2 is 3. - * These elements are swapped, yielding {1, 3, 4, 2, 0}, and the list right - * of the dip point is reversed, yielding {1, 3, 0, 2, 4}. - */ - private void moveIndex() { - // find the index of the first element that dips - int i = rightmostDip(); - if (i < 0) { - hasNext = false; - return; - } - - // find the least greater element to the right of the dip - int leastToRightIndex = i + 1; - for (int j = i + 2; j < n; j++) { - if (index[j] < index[leastToRightIndex] && index[j] > index[i]) { - leastToRightIndex = j; - } - } - - // switch dip element with least greater element to its right - int t = index[i]; - index[i] = index[leastToRightIndex]; - index[leastToRightIndex] = t; - - if (m - 1 > i) { - // reverse the elements to the right of the dip - reverseAfter(i); - - // reverse the elements to the right of m - 1 - reverseAfter(m - 1); - } - } - - /** - * Get the index of the first element from the right that is less - * than its neighbor on the right. - * - * @return the index or -1 if non is found - */ - private int rightmostDip() { - for (int i = n - 2; i >= 0; i--) { - if (index[i] < index[i + 1]) { - return i; - } - } - return -1; - } - - /** - * Reverse the elements to the right of the specified index. - * - * @param i the index - */ - private void reverseAfter(int i) { - int start = i + 1; - int end = n - 1; - while (start < end) { - int t = index[start]; - index[start] = index[end]; - index[end] = t; - start++; - end--; - } - } - - /** - * Go to the next lineup, and if available, fill the target array. - * - * @return if a new lineup is available - */ - public boolean next() { - if (!hasNext) { - return false; - } - for (int i = 0; i < m; i++) { - out[i] = in[index[i]]; - } - moveIndex(); - return true; - } - -} diff --git a/tools/h2/src/main/org/h2/util/Profiler.java b/tools/h2/src/main/org/h2/util/Profiler.java deleted file mode 100755 index 9d83065..0000000 --- a/tools/h2/src/main/org/h2/util/Profiler.java +++ /dev/null @@ -1,191 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.util; - -import java.util.HashMap; -import java.util.Iterator; -import java.util.Map; -import org.h2.engine.Constants; - -/** - * A simple CPU profiling tool similar to java -Xrunhprof. - */ -public class Profiler implements Runnable { - private static final int MAX_ELEMENTS = 1000; - - public int interval = 50; - public int depth = 16; - - private String[] ignoreLines = StringUtils.arraySplit("", ',', true); - private String[] ignoreThreads = StringUtils.arraySplit( - "java.lang.Thread.dumpThreads," + - "java.net.PlainSocketImpl.socketAccept," + - "java.net.SocketInputStream.socketRead0," + - "java.net.SocketOutputStream.socketWrite0," + - "java.lang.UNIXProcess.waitForProcessExit," + - "java.lang.Object.wait," + - "java.lang.Thread.sleep," + - "sun.awt.windows.WToolkit.eventLoop," - , ',', true); - private volatile boolean stop; - private HashMap counts = new HashMap(); - private int minCount = 1; - private int total; - private Thread thread; - private long time; - - /** - * Start collecting profiling data. - */ - public void startCollecting() { - thread = new Thread(this); - thread.setName("Profiler"); - thread.setDaemon(true); - thread.start(); - } - - /** - * Stop collecting. - */ - public void stopCollecting() { - stop = true; - if (thread != null) { - try { - thread.join(); - } catch (InterruptedException e) { - // ignore - } - thread = null; - } - } - - public void run() { - time = System.currentTimeMillis(); - while (!stop) { - try { - tick(); - } catch (Throwable t) { - break; - } - } - time = System.currentTimeMillis() - time; - } - - private void tick() { - if (interval > 0) { - try { - Thread.sleep(interval); - } catch (Exception e) { - // ignore - } - } - Map map = Thread.getAllStackTraces(); - for (Map.Entry entry : map.entrySet()) { - Thread t = entry.getKey(); - if (t.getState() != Thread.State.RUNNABLE) { - continue; - } - StackTraceElement[] dump = entry.getValue(); - if (dump.length == 0) { - continue; - } - boolean ignoreThis = false; - for (String ig : ignoreThreads) { - if (ig.length() > 0 && dump[0].toString().startsWith(ig)) { - ignoreThis = true; - break; - } - } - if (ignoreThis) { - continue; - } - StringBuilder buff = new StringBuilder(); - // simple recursive calls are ignored - String last = null; - for (int j = 0, i = 0; i < dump.length && j < depth; i++) { - String el = dump[i].toString(); - ignoreThis = false; - for (String ig : ignoreLines) { - if (ig.length() > 0 && el.startsWith(ig)) { - ignoreThis = true; - break; - } - } - if (!ignoreThis && !el.equals(last)) { - last = el; - buff.append("at ").append(el).append('\n'); - j++; - } - } - if (buff.length() > 0) { - increment(buff.toString()); - } - } - } - - private void increment(String trace) { - total++; - Integer oldCount = counts.get(trace); - if (oldCount == null) { - counts.put(trace, 1); - } else { - counts.put(trace, oldCount + 1); - } - if (counts.size() > MAX_ELEMENTS) { - for (Iterator> ei = counts.entrySet().iterator(); ei.hasNext();) { - Map.Entry e = ei.next(); - if (e.getValue() <= minCount) { - ei.remove(); - } - } - if (counts.size() > MAX_ELEMENTS) { - minCount++; - } - } - } - - /** - * Get the top stack traces. - * - * @param count the maximum number of stack traces - * @return the stack traces. - */ - public String getTop(int count) { - stopCollecting(); - StringBuilder buff = new StringBuilder(); - buff.append("Profiler: top ").append(count).append(" stack trace(s) of ").append(time). - append(" ms [build-").append(Constants.BUILD_ID).append("]:\n"); - if (counts.size() == 0) { - buff.append("(none)"); - } - for (int x = 0, min = 0;;) { - int highest = 0; - Map.Entry best = null; - for (Map.Entry el : counts.entrySet()) { - if (el.getValue() > highest) { - best = el; - highest = el.getValue(); - } - } - if (best == null) { - break; - } - counts.remove(best.getKey()); - if (++x >= count) { - if (best.getValue() < min) { - break; - } - min = best.getValue(); - } - buff.append(best.getValue()).append('/').append(total). - append('\n').append(best.getKey()); - } - buff.append('.'); - return buff.toString(); - } - -} diff --git a/tools/h2/src/main/org/h2/util/ScriptReader.java b/tools/h2/src/main/org/h2/util/ScriptReader.java deleted file mode 100755 index 394036e..0000000 --- a/tools/h2/src/main/org/h2/util/ScriptReader.java +++ /dev/null @@ -1,282 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.util; - -import java.io.IOException; -import java.io.Reader; -import java.util.Arrays; -import org.h2.engine.Constants; -import org.h2.message.DbException; - -/** - * This class can split SQL scripts to single SQL statements. - * Each SQL statement ends with the character ';', however it is ignored - * in comments and quotes. - */ -public class ScriptReader { - private Reader reader; - private char[] buffer; - private int bufferPos; - private int bufferStart = -1; - private int bufferEnd; - private boolean endOfFile; - private boolean insideRemark; - private boolean blockRemark; - private boolean skipRemarks; - private int remarkStart; - - /** - * Create a new SQL script reader from the given reader - * - * @param reader the reader - */ - public ScriptReader(Reader reader) { - this.reader = reader; - buffer = new char[Constants.IO_BUFFER_SIZE * 2]; - } - - /** - * Close the underlying reader. - */ - public void close() { - try { - reader.close(); - } catch (IOException e) { - throw DbException.convertIOException(e, null); - } - } - - /** - * Read a statement from the reader. This method returns null if the end has - * been reached. - * - * @return the SQL statement or null - */ - public String readStatement() { - if (endOfFile) { - return null; - } - try { - return readStatementLoop(); - } catch (IOException e) { - throw DbException.convertIOException(e, null); - } - } - - private String readStatementLoop() throws IOException { - bufferStart = bufferPos; - int c = read(); - while (true) { - if (c < 0) { - endOfFile = true; - if (bufferPos - 1 == bufferStart) { - return null; - } - break; - } else if (c == ';') { - break; - } - switch (c) { - case '$': { - c = read(); - if (c == '$' && (bufferPos - bufferStart < 3 || buffer[bufferPos - 3] <= ' ')) { - // dollar quoted string - while (true) { - c = read(); - if (c < 0) { - break; - } - if (c == '$') { - c = read(); - if (c < 0) { - break; - } - if (c == '$') { - break; - } - } - } - c = read(); - } - break; - } - case '\'': - while (true) { - c = read(); - if (c < 0) { - break; - } - if (c == '\'') { - break; - } - } - c = read(); - break; - case '"': - while (true) { - c = read(); - if (c < 0) { - break; - } - if (c == '\"') { - break; - } - } - c = read(); - break; - case '/': { - c = read(); - if (c == '*') { - // block comment - startRemark(false); - while (true) { - c = read(); - if (c < 0) { - break; - } - if (c == '*') { - c = read(); - if (c < 0) { - clearRemark(); - break; - } - if (c == '/') { - endRemark(); - break; - } - } - } - c = read(); - } else if (c == '/') { - // single line comment - startRemark(false); - while (true) { - c = read(); - if (c < 0) { - clearRemark(); - break; - } - if (c == '\r' || c == '\n') { - endRemark(); - break; - } - } - c = read(); - } - break; - } - case '-': { - c = read(); - if (c == '-') { - // single line comment - startRemark(false); - while (true) { - c = read(); - if (c < 0) { - clearRemark(); - break; - } - if (c == '\r' || c == '\n') { - endRemark(); - break; - } - } - c = read(); - } - break; - } - default: { - c = read(); - } - } - } - return new String(buffer, bufferStart, bufferPos - 1 - bufferStart); - } - - private void startRemark(boolean block) { - blockRemark = block; - remarkStart = bufferPos - 2; - insideRemark = true; - } - - private void endRemark() { - clearRemark(); - insideRemark = false; - } - - private void clearRemark() { - if (skipRemarks) { - Arrays.fill(buffer, remarkStart, bufferPos, ' '); - } - } - - private int read() throws IOException { - if (bufferPos >= bufferEnd) { - return readBuffer(); - } - return buffer[bufferPos++]; - } - - private int readBuffer() throws IOException { - if (endOfFile) { - return -1; - } - int keep = bufferPos - bufferStart; - if (keep > 0) { - char[] src = buffer; - if (keep + Constants.IO_BUFFER_SIZE > src.length) { - buffer = new char[src.length * 2]; - } - System.arraycopy(src, bufferStart, buffer, 0, keep); - } - remarkStart -= bufferStart; - bufferStart = 0; - bufferPos = keep; - int len = reader.read(buffer, keep, Constants.IO_BUFFER_SIZE); - if (len == -1) { - // ensure bufferPos > bufferEnd - bufferEnd = -1024; - endOfFile = true; - // ensure the right number of characters are read - // in case the input buffer is still used - bufferPos++; - return -1; - } - bufferEnd = keep + len; - return buffer[bufferPos++]; - } - - /** - * Check if this is the last statement, and if the single line or block - * comment is not finished yet. - * - * @return true if the current position is inside a remark - */ - public boolean isInsideRemark() { - return insideRemark; - } - - /** - * If currently inside a remark, this method tells if it is a block comment - * (true) or single line comment (false) - * - * @return true if inside a block comment - */ - public boolean isBlockRemark() { - return blockRemark; - } - - /** - * If comments should be skipped completely by this reader. - * - * @param skipRemarks true if comments should be skipped - */ - public void setSkipRemarks(boolean skipRemarks) { - this.skipRemarks = skipRemarks; - } - -} diff --git a/tools/h2/src/main/org/h2/util/SmallLRUCache.java b/tools/h2/src/main/org/h2/util/SmallLRUCache.java deleted file mode 100755 index 04b15d5..0000000 --- a/tools/h2/src/main/org/h2/util/SmallLRUCache.java +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.util; - -//## Java 1.4 begin ## -import java.util.LinkedHashMap; -//## Java 1.4 end ## -/*## Java 1.3 only begin ## -import java.util.HashMap; -## Java 1.3 only end ##*/ -import java.util.Map; - -/** - * This class implements a small LRU object cache. - * - * @param the key - * @param the value - */ -public class SmallLRUCache -//## Java 1.4 begin ## -extends LinkedHashMap -//## Java 1.4 end ## -/*## Java 1.3 only begin ## -extends HashMap -## Java 1.3 only end ##*/ -{ - - private static final long serialVersionUID = 1L; - private int size; - - private SmallLRUCache(int size) { - super(size, (float) 0.75, true); - this.size = size; - } - - /** - * Create a new object with all elements of the given collection. - * - * @param the key type - * @param the value type - * @param size the number of elements - * @return the object - */ - public static SmallLRUCache newInstance(int size) { - return new SmallLRUCache(size); - } - -//## Java 1.4 begin ## - protected boolean removeEldestEntry(Map.Entry eldest) { - return size() > size; - } -//## Java 1.4 end ## -} diff --git a/tools/h2/src/main/org/h2/util/SmallMap.java b/tools/h2/src/main/org/h2/util/SmallMap.java deleted file mode 100755 index 7c1d6ad..0000000 --- a/tools/h2/src/main/org/h2/util/SmallMap.java +++ /dev/null @@ -1,96 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.util; - -import java.sql.SQLException; -import java.util.HashMap; -import java.util.Iterator; - -import org.h2.constant.ErrorCode; -import org.h2.message.DbException; - -/** - * A simple hash table with an optimization for the last recently used object. - */ -public class SmallMap { - - private HashMap map = New.hashMap(); - private Object cache; - private int cacheId; - private int lastId; - private int maxElements; - - /** - * Create a map with the given maximum number of entries. - * - * @param maxElements the maximum number of entries - */ - public SmallMap(int maxElements) { - this.maxElements = maxElements; - } - - /** - * Add an object to the map. If the size of the map is larger than twice the - * maximum size, objects with a low id are removed. - * - * @param id the object id - * @param o the object - * @return the id - */ - public int addObject(int id, Object o) { - if (map.size() > maxElements * 2) { - Iterator it = map.keySet().iterator(); - while (it.hasNext()) { - Integer k = it.next(); - if (k.intValue() + maxElements < lastId) { - it.remove(); - } - } - } - if (id > lastId) { - lastId = id; - } - map.put(id, o); - cacheId = id; - cache = o; - return id; - } - - /** - * Remove an object from the map. - * - * @param id the id of the object to remove - */ - public void freeObject(int id) { - if (cacheId == id) { - cacheId = -1; - cache = null; - } - map.remove(id); - } - - /** - * Get an object from the map if it is stored. - * - * @param id the id of the object - * @param ifAvailable only return it if available, otherwise return null - * @return the object or null - * @throws SQLException if isAvailable is false and the object has not been - * found - */ - public Object getObject(int id, boolean ifAvailable) throws SQLException { - if (id == cacheId) { - return cache; - } - Object obj = map.get(id); - if (obj == null && !ifAvailable) { - throw DbException.get(ErrorCode.OBJECT_CLOSED); - } - return obj; - } - -} diff --git a/tools/h2/src/main/org/h2/util/SoftHashMap.java b/tools/h2/src/main/org/h2/util/SoftHashMap.java deleted file mode 100755 index 4ccfdad..0000000 --- a/tools/h2/src/main/org/h2/util/SoftHashMap.java +++ /dev/null @@ -1,102 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.util; - -import java.lang.ref.Reference; -import java.lang.ref.ReferenceQueue; -import java.lang.ref.SoftReference; -import java.util.AbstractMap; -import java.util.Map; -import java.util.Set; - -/** - * Map which stores items using SoftReference. Items can be garbage collected - * and removed. It is not a general purpose cache, as it doesn't implement some - * methods, and others not according to the map definition, to improve speed. - * - * @param the key type - * @param the value type - */ -public class SoftHashMap extends AbstractMap { - - private Map> map; - private ReferenceQueue queue = new ReferenceQueue(); - - public SoftHashMap() { - map = New.hashMap(); - } - - @SuppressWarnings("unchecked") - private void processQueue() { - while (true) { - Reference< ? extends V> o = queue.poll(); - if (o == null) { - return; - } - SoftValue k = (SoftValue) o; - Object key = k.key; - map.remove(key); - } - } - - public V get(Object key) { - processQueue(); - SoftReference o = map.get(key); - if (o == null) { - return null; - } - return o.get(); - } - - /** - * Store the object. The return value of this method is null or a SoftReference. - * - * @param key the key - * @param value the value - * @return null or the old object. - */ - public V put(K key, V value) { - processQueue(); - SoftValue old = map.put(key, new SoftValue(value, queue, key)); - return old == null ? null : old.get(); - } - - /** - * Remove an object. - * - * @param key the key - * @return null or the old object - */ - public V remove(Object key) { - processQueue(); - SoftReference ref = map.remove(key); - return ref == null ? null : ref.get(); - } - - public void clear() { - processQueue(); - map.clear(); - } - - public Set> entrySet() { - throw new UnsupportedOperationException(); - } - - /** - * A soft reference that has a hard reference to the key. - */ - private static class SoftValue extends SoftReference { - final Object key; - - public SoftValue(T ref, ReferenceQueue q, Object key) { - super(ref, q); - this.key = key; - } - - } - -} diff --git a/tools/h2/src/main/org/h2/util/SortedProperties.java b/tools/h2/src/main/org/h2/util/SortedProperties.java deleted file mode 100755 index 5099c8b..0000000 --- a/tools/h2/src/main/org/h2/util/SortedProperties.java +++ /dev/null @@ -1,163 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.util; - -import java.io.BufferedWriter; -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.io.LineNumberReader; -import java.io.OutputStreamWriter; -import java.io.PrintWriter; -import java.io.Writer; -import java.util.Collections; -import java.util.Enumeration; -import java.util.Properties; -import java.util.TreeMap; -import java.util.Vector; -import java.util.Map.Entry; -import org.h2.message.DbException; -import org.h2.message.TraceSystem; - -/** - * Sorted properties file. - * This implementation requires that store() internally calls keys(). - */ -public class SortedProperties extends Properties { - - private static final long serialVersionUID = 1L; - - public synchronized Enumeration keys() { - Vector v = new Vector(); - for (Object o : keySet()) { - v.add(o.toString()); - } - Collections.sort(v); - return new Vector(v).elements(); - } - - /** - * Get a boolean property value from a properties object. - * - * @param prop the properties object - * @param key the key - * @param def the default value - * @return the value if set, or the default value if not - */ - public static boolean getBooleanProperty(Properties prop, String key, boolean def) { - String value = prop.getProperty(key, "" + def); - try { - return Boolean.valueOf(value).booleanValue(); - } catch (Exception e) { - TraceSystem.traceThrowable(e); - return def; - } - } - - /** - * Get an int property value from a properties object. - * - * @param prop the properties object - * @param key the key - * @param def the default value - * @return the value if set, or the default value if not - */ - public static int getIntProperty(Properties prop, String key, int def) { - String value = prop.getProperty(key, "" + def); - try { - return Integer.decode(value); - } catch (Exception e) { - TraceSystem.traceThrowable(e); - return def; - } - } - - /** - * Load a properties object from a file. - * - * @param fileName the name of the properties file - * @return the properties object - */ - public static synchronized SortedProperties loadProperties(String fileName) throws IOException { - SortedProperties prop = new SortedProperties(); - if (IOUtils.exists(fileName)) { - InputStream in = null; - try { - in = IOUtils.openFileInputStream(fileName); - prop.load(in); - } finally { - if (in != null) { - in.close(); - } - } - } - return prop; - } - - /** - * Store a properties file. The header and the date is not written. - * - * @param fileName the target file name - */ - public synchronized void store(String fileName) throws IOException { - ByteArrayOutputStream out = new ByteArrayOutputStream(); - store(out, null); - ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray()); - InputStreamReader reader = new InputStreamReader(in, "ISO8859-1"); - LineNumberReader r = new LineNumberReader(reader); - Writer w; - try { - w = new OutputStreamWriter(IOUtils.openFileOutputStream(fileName, false)); - } catch (Exception e) { - throw DbException.convertToIOException(e); - } - PrintWriter writer = new PrintWriter(new BufferedWriter(w)); - while (true) { - String line = r.readLine(); - if (line == null) { - break; - } - if (!line.startsWith("#")) { - writer.print(line + "\n"); - } - } - writer.close(); - } - - /** - * Convert the map to a list of line in the form key=value. - * - * @return the lines - */ - public synchronized String toLines() { - StringBuilder buff = new StringBuilder(); - for (Entry e : new TreeMap(this).entrySet()) { - buff.append(e.getKey()).append('=').append(e.getValue()).append('\n'); - } - return buff.toString(); - } - - /** - * Convert a String to a map. - * - * @param s the string - * @return the map - */ - public static SortedProperties fromLines(String s) { - SortedProperties p = new SortedProperties(); - for (String line : StringUtils.arraySplit(s, '\n', true)) { - int idx = line.indexOf('='); - if (idx > 0) { - p.put(line.substring(0, idx), line.substring(idx + 1)); - } - } - return p; - } - -} diff --git a/tools/h2/src/main/org/h2/util/SourceCompiler.java b/tools/h2/src/main/org/h2/util/SourceCompiler.java deleted file mode 100755 index 6e8fe5d..0000000 --- a/tools/h2/src/main/org/h2/util/SourceCompiler.java +++ /dev/null @@ -1,259 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.util; - -import java.io.ByteArrayOutputStream; -import java.io.DataInputStream; -import java.io.File; -import java.io.FileInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.io.PrintStream; -import java.io.PrintWriter; -import java.lang.reflect.Method; -import java.lang.reflect.Modifier; -import java.util.HashMap; -import org.h2.constant.ErrorCode; -import org.h2.message.DbException; - -/** - * This class allows to convert source code to a class. It uses one class loader - * per class. - */ -public class SourceCompiler { - - private static final Class< ? > JAVAC_SUN; - - /** - * The class name to source code map. - */ - HashMap sources = New.hashMap(); - - /** - * The class name to byte code map. - */ - HashMap> compiled = New.hashMap(); - - private String compileDir = System.getProperty("java.io.tmpdir"); - - static { - Class< ? > clazz; - try { - clazz = Class.forName("com.sun.tools.javac.Main"); - } catch (Exception e) { - clazz = null; - } - JAVAC_SUN = clazz; - } - - /** - * Set the source code for the specified class. - * This will reset all compiled classes. - * - * @param className the class name - * @param source the source code - */ - public void setSource(String className, String source) { - sources.put(className, source); - compiled.clear(); - } - - /** - * Get the class object for the given name. - * - * @param packageAndClassName the class name - * @return the class - */ - private Class< ? > getClass(String packageAndClassName) throws ClassNotFoundException { - - Class< ? > compiledClass = compiled.get(packageAndClassName); - if (compiledClass != null) { - return compiledClass; - } - - ClassLoader classLoader = new ClassLoader(getClass().getClassLoader()) { - public Class< ? > findClass(String name) throws ClassNotFoundException { - Class< ? > classInstance = compiled.get(name); - if (classInstance == null) { - String source = sources.get(name); - String packageName = null; - int idx = name.lastIndexOf('.'); - String className; - if (idx >= 0) { - packageName = name.substring(0, idx); - className = name.substring(idx + 1); - } else { - className = name; - } - byte[] data = javacCompile(packageName, className, source); - if (data == null) { - classInstance = findSystemClass(name); - } else { - classInstance = defineClass(name, data, 0, data.length); - compiled.put(name, classInstance); - } - } - return classInstance; - } - }; - return classLoader.loadClass(packageAndClassName); - } - - /** - * Get the first public static method of the given class. - * - * @param className the class name - * @return the method name - */ - public Method getMethod(String className) throws ClassNotFoundException { - Class< ? > clazz = getClass(className); - Method[] methods = clazz.getDeclaredMethods(); - for (Method m : methods) { - int modifiers = m.getModifiers(); - if (Modifier.isPublic(modifiers)) { - if (Modifier.isStatic(modifiers)) { - return m; - } - } - } - return null; - } - - /** - * Compile the given class. This method tries to use the class - * "com.sun.tools.javac.Main" if available. If not, it tries to run "javac" - * in a separate process. - * - * @param packageName the package name - * @param className the class name - * @param source the source code - * @return the class file - */ - byte[] javacCompile(String packageName, String className, String source) { - File dir = new File(compileDir); - if (packageName != null) { - dir = new File(dir, packageName.replace('.', '/')); - try { - IOUtils.mkdirs(dir); - } catch (IOException e) { - throw DbException.convertIOException(e, compileDir); - } - } - File javaFile = new File(dir, className + ".java"); - File classFile = new File(dir, className + ".class"); - try { - OutputStream f = IOUtils.openFileOutputStream(javaFile.getAbsolutePath(), false); - PrintWriter out = new PrintWriter(IOUtils.getWriter(f)); - classFile.delete(); - int endImport = source.indexOf("@CODE"); - String importCode = "import java.util.*;\n" + - "import java.math.*;\n" + - "import java.sql.*;\n"; - if (endImport >= 0) { - importCode = source.substring(0, endImport); - source = source.substring("@CODE".length() + endImport); - } - if (packageName != null) { - out.println("package " + packageName + ";"); - } - out.println(importCode); - out.println("public class "+ className +" {\n" + - " public static " + - source + "\n" + - "}\n"); - out.close(); - if (JAVAC_SUN != null) { - javacSun(javaFile); - } else { - javacProcess(javaFile); - } - byte[] data = new byte[(int) classFile.length()]; - DataInputStream in = new DataInputStream(new FileInputStream(classFile)); - in.readFully(data); - in.close(); - return data; - } catch (Exception e) { - throw DbException.convert(e); - } finally { - javaFile.delete(); - classFile.delete(); - } - } - - private void javacProcess(File javaFile) { - exec("javac", - "-sourcepath", compileDir, - "-d", compileDir, - "-encoding", "UTF-8", - javaFile.getAbsolutePath()); - } - - private int exec(String... args) { - ByteArrayOutputStream buff = new ByteArrayOutputStream(); - try { - Process p = Runtime.getRuntime().exec(args); - copyInThread(p.getInputStream(), buff); - copyInThread(p.getErrorStream(), buff); - p.waitFor(); - throwSyntaxError(buff); - return p.exitValue(); - } catch (Exception e) { - throw DbException.convert(e); - } - } - - private void throwSyntaxError(ByteArrayOutputStream out) { - String err = StringUtils.utf8Decode(out.toByteArray()); - if (err.length() > 0) { - err = StringUtils.replaceAll(err, compileDir, ""); - throw DbException.get(ErrorCode.SYNTAX_ERROR_1, err); - } - } - - private void copyInThread(final InputStream in, final OutputStream out) { - new Thread() { - public void run() { - try { - while (true) { - int x = in.read(); - if (x < 0) { - return; - } - if (out != null) { - out.write(x); - } - } - } catch (Exception e) { - throw DbException.convert(e); - } - } - } .start(); - } - - private void javacSun(File javaFile) { - PrintStream old = System.err; - ByteArrayOutputStream buff = new ByteArrayOutputStream(); - PrintStream temp = new PrintStream(buff); - try { - System.setErr(temp); - Method compile = JAVAC_SUN.getMethod("compile", String[].class); - Object javac = JAVAC_SUN.newInstance(); - compile.invoke(javac, (Object) new String[] { - "-sourcepath", compileDir, - "-d", compileDir, - "-encoding", "UTF-8", - javaFile.getAbsolutePath() }); - throwSyntaxError(buff); - } catch (Exception e) { - throw DbException.convert(e); - } finally { - System.setErr(old); - } - } - -} diff --git a/tools/h2/src/main/org/h2/util/StatementBuilder.java b/tools/h2/src/main/org/h2/util/StatementBuilder.java deleted file mode 100755 index 65d279d..0000000 --- a/tools/h2/src/main/org/h2/util/StatementBuilder.java +++ /dev/null @@ -1,130 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.util; - -/** - * A utility class to build a statement. In addition to the methods supported by - * StringBuilder, it allows to add a text only in the second iteration. This - * simplified constructs such as: - *
- * StringBuilder buff = new StringBuilder();
- * for (int i = 0; i < args.length; i++) {
- *     if (i > 0) {
- *         buff.append(", ");
- *     }
- *     buff.append(args[i]);
- * }
- * 
- * to - *
- * StatementBuilder buff = new StatementBuilder();
- * for (String s : args) {
- *     buff.appendExceptFirst(", ");
- *     buff.append(a);
- * }
- *
- */ -public class StatementBuilder { - - private final StringBuilder builder = new StringBuilder(); - private int index; - - /** - * Create a new builder. - */ - public StatementBuilder() { - // nothing to do - } - - /** - * Create a new builder. - * - * @param string the initial string - */ - public StatementBuilder(String string) { - builder.append(string); - } - - /** - * Append a text. - * - * @param s the text to append - * @return itself - */ - public StatementBuilder append(String s) { - builder.append(s); - return this; - } - - /** - * Append a character. - * - * @param c the character to append - * @return itself - */ - public StatementBuilder append(char c) { - builder.append(c); - return this; - } - - /** - * Append a number. - * - * @param x the number to append - * @return itself - */ - public StatementBuilder append(long x) { - builder.append(x); - return this; - } - - /** - * Reset the loop counter. - * - * @return itself - */ - public StatementBuilder resetCount() { - index = 0; - return this; - } - - /** - * Append a text, but only if appendExceptFirst was never called. - * - * @param s the text to append - */ - public void appendOnlyFirst(String s) { - if (index == 0) { - builder.append(s); - } - } - - /** - * Append a text, except when this method is called the first time. - * - * @param s the text to append - */ - public void appendExceptFirst(String s) { - if (index++ > 0) { - builder.append(s); - } - } - - public String toString() { - return builder.toString(); - } - - /** - * Get the length. - * - * @return the length - */ - public int length() { - return builder.length(); - } - -} diff --git a/tools/h2/src/main/org/h2/util/StringUtils.java b/tools/h2/src/main/org/h2/util/StringUtils.java deleted file mode 100755 index 64b194f..0000000 --- a/tools/h2/src/main/org/h2/util/StringUtils.java +++ /dev/null @@ -1,935 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.util; - -import java.lang.ref.SoftReference; -import java.net.URLEncoder; -import java.util.ArrayList; -import java.util.Locale; -import org.h2.constant.ErrorCode; -import org.h2.constant.SysProperties; -import org.h2.engine.Constants; -import org.h2.message.DbException; - -/** - * A few String utility functions. - */ -public class StringUtils { - - private static SoftReference softCache = new SoftReference(null); - - private StringUtils() { - // utility class - } - - private static String[] getCache() { - String[] cache; - // softCache can be null due to a Tomcat problem - // a workaround is disable the system property org.apache. - // catalina.loader.WebappClassLoader.ENABLE_CLEAR_REFERENCES - if (softCache != null) { - cache = softCache.get(); - if (cache != null) { - return cache; - } - } - try { - cache = new String[SysProperties.OBJECT_CACHE_SIZE]; - } catch (OutOfMemoryError e) { - return null; - } - softCache = new SoftReference(cache); - return cache; - } - - /** - * Check if two strings are equal. Here, null is equal to null. - * - * @param a the first value - * @param b the second value - * @return true if both are null or both are equal - */ - public static boolean equals(String a, String b) { - if (a == null) { - return b == null; - } - return a.equals(b); - } - - /** - * Convert a string to uppercase using the English locale. - * - * @param s the test to convert - * @return the uppercase text - */ - public static String toUpperEnglish(String s) { - return s.toUpperCase(Locale.ENGLISH); - } - - /** - * Convert a string to lowercase using the English locale. - * - * @param s the text to convert - * @return the lowercase text - */ - public static String toLowerEnglish(String s) { - return s.toLowerCase(Locale.ENGLISH); - } - - /** - * Check is a string starts with another string, ignoring the case. - * - * @param s the string to check (must be longer than start) - * @param start the prefix of s - * @return true if start is a prefix of s - */ - public static boolean startsWithIgnoreCase(String s, String start) { - if (s.length() < start.length()) { - return false; - } - return s.substring(0, start.length()).equalsIgnoreCase(start); - } - - - /** - * Convert a string to a SQL literal. Null is converted to NULL. The text is - * enclosed in single quotes. If there are any special characters, the method - * STRINGDECODE is used. - * - * @param s the text to convert. - * @return the SQL literal - */ - public static String quoteStringSQL(String s) { - if (s == null) { - return "NULL"; - } - StringBuilder buff = new StringBuilder(s.length() + 2); - buff.append('\''); - for (int i = 0; i < s.length(); i++) { - char c = s.charAt(i); - if (c == '\'') { - buff.append(c); - } else if (c < ' ' || c > 127) { - // need to start from the beginning because maybe there was a \ - // that was not quoted - return "STRINGDECODE(" + quoteStringSQL(javaEncode(s)) + ")"; - } - buff.append(c); - } - buff.append('\''); - return buff.toString(); - } - - /** - * Convert a string to a Java literal using the correct escape sequences. - * The literal is not enclosed in double quotes. The result can be used in - * properties files or in Java source code. - * - * @param s the text to convert - * @return the Java representation - */ - public static String javaEncode(String s) { - StringBuilder buff = new StringBuilder(s.length()); - for (int i = 0; i < s.length(); i++) { - char c = s.charAt(i); - switch (c) { -// case '\b': -// // BS backspace -// // not supported in properties files -// buff.append("\\b"); -// break; - case '\t': - // HT horizontal tab - buff.append("\\t"); - break; - case '\n': - // LF linefeed - buff.append("\\n"); - break; - case '\f': - // FF form feed - buff.append("\\f"); - break; - case '\r': - // CR carriage return - buff.append("\\r"); - break; - case '"': - // double quote - buff.append("\\\""); - break; - case '\\': - // backslash - buff.append("\\\\"); - break; - default: - int ch = c & 0xffff; - if (ch >= ' ' && (ch < 0x80)) { - buff.append(c); - // not supported in properties files - // } else if(ch < 0xff) { - // buff.append("\\"); - // // make sure it's three characters (0x200 is octal 1000) - // buff.append(Integer.toOctalString(0x200 | ch).substring(1)); - } else { - buff.append("\\u"); - // make sure it's four characters - buff.append(Integer.toHexString(0x10000 | ch).substring(1)); - } - } - } - return buff.toString(); - } - - /** - * Add an asterisk ('[*]') at the given position. This format is used to - * show where parsing failed in a statement. - * - * @param s the text - * @param index the position - * @return the text with asterisk - */ - public static String addAsterisk(String s, int index) { - if (s != null && index < s.length()) { - s = s.substring(0, index) + "[*]" + s.substring(index); - } - return s; - } - - private static DbException getFormatException(String s, int i) { - return DbException.get(ErrorCode.STRING_FORMAT_ERROR_1, addAsterisk(s, i)); - } - - /** - * Decode a text that is encoded as a Java string literal. The Java - * properties file format and Java source code format is supported. - * - * @param s the encoded string - * @return the string - */ - public static String javaDecode(String s) { - StringBuilder buff = new StringBuilder(s.length()); - for (int i = 0; i < s.length(); i++) { - char c = s.charAt(i); - if (c == '"') { - break; - } else if (c == '\\') { - if (i >= s.length()) { - throw getFormatException(s, s.length() - 1); - } - c = s.charAt(++i); - switch (c) { - case 't': - buff.append('\t'); - break; - case 'r': - buff.append('\r'); - break; - case 'n': - buff.append('\n'); - break; - case 'b': - buff.append('\b'); - break; - case 'f': - buff.append('\f'); - break; - case '#': - // for properties files - buff.append('#'); - break; - case '=': - // for properties files - buff.append('='); - break; - case ':': - // for properties files - buff.append(':'); - break; - case '"': - buff.append('"'); - break; - case '\\': - buff.append('\\'); - break; - case 'u': { - try { - c = (char) (Integer.parseInt(s.substring(i + 1, i + 5), 16)); - } catch (NumberFormatException e) { - throw getFormatException(s, i); - } - i += 4; - buff.append(c); - break; - } - default: - if (c >= '0' && c <= '9') { - try { - c = (char) (Integer.parseInt(s.substring(i, i + 3), 8)); - } catch (NumberFormatException e) { - throw getFormatException(s, i); - } - i += 2; - buff.append(c); - } else { - throw getFormatException(s, i); - } - } - } else { - buff.append(c); - } - } - return buff.toString(); - } - - /** - * Convert a string to the Java literal and enclose it with double quotes. - * Null will result in "null" (without double quotes). - * - * @param s the text to convert - * @return the Java representation - */ - public static String quoteJavaString(String s) { - if (s == null) { - return "null"; - } - return "\"" + javaEncode(s) + "\""; - } - - /** - * Convert the text to UTF-8 format. For the Unicode characters - * 0xd800-0xdfff only one byte is returned. - * - * @param s the text - * @return the UTF-8 representation - */ - public static byte[] utf8Encode(String s) { - try { - return s.getBytes(Constants.UTF8); - } catch (Exception e) { - // UnsupportedEncodingException - throw DbException.convert(e); - } - } - - /** - * Convert a UTF-8 representation of a text to the text. - * - * @param utf8 the UTF-8 representation - * @return the text - */ - public static String utf8Decode(byte[] utf8) { - try { - return new String(utf8, Constants.UTF8); - } catch (Exception e) { - // UnsupportedEncodingException - throw DbException.convert(e); - } - } - - /** - * Convert a UTF-8 representation of a text to the text using the given - * offset and length. - * - * @param bytes the UTF-8 representation - * @param offset the offset in the bytes array - * @param length the number of bytes - * @return the text - */ - private static String utf8Decode(byte[] bytes, int offset, int length) { - try { - return new String(bytes, offset, length, Constants.UTF8); - } catch (Exception e) { - // UnsupportedEncodingException - throw DbException.convert(e); - } - } - - /** - * Convert a string array to the Java source code that represents this - * array. Null will be converted to 'null'. - * - * @param array the string array - * @return the Java source code (including new String[]{}) - */ - public static String quoteJavaStringArray(String[] array) { - if (array == null) { - return "null"; - } - StatementBuilder buff = new StatementBuilder("new String[]{"); - for (String a : array) { - buff.appendExceptFirst(", "); - buff.append(quoteJavaString(a)); - } - return buff.append('}').toString(); - } - - /** - * Convert an int array to the Java source code that represents this array. - * Null will be converted to 'null'. - * - * @param array the int array - * @return the Java source code (including new int[]{}) - */ - public static String quoteJavaIntArray(int[] array) { - if (array == null) { - return "null"; - } - StatementBuilder buff = new StatementBuilder("new int[]{"); - for (int a : array) { - buff.appendExceptFirst(", "); - buff.append(a); - } - return buff.append('}').toString(); - } - - /** - * Enclose a string with '(' and ')' if this is not yet done. - * - * @param s the string - * @return the enclosed string - */ - public static String enclose(String s) { - if (s.startsWith("(")) { - return s; - } - return "(" + s + ")"; - } - - /** - * Remove enclosing '(' and ')' if this text is enclosed. - * - * @param s the potentially enclosed string - * @return the string - */ - public static String unEnclose(String s) { - if (s.startsWith("(") && s.endsWith(")")) { - return s.substring(1, s.length() - 1); - } - return s; - } - - /** - * Encode the string as an URL. - * - * @param s the string to encode - * @return the encoded string - */ - public static String urlEncode(String s) { -//## Java 1.4 begin ## - try { - return URLEncoder.encode(s, "UTF-8"); - } catch (Exception e) { - // UnsupportedEncodingException - throw DbException.convert(e); - } -//## Java 1.4 end ## -/*## Java 1.3 only begin ## -/* - return URLEncoder.encode(s); -*/ -//## Java 1.4 end ## -// byte[] utf = utf8Encode(s); -// StringBuilder buff = new StringBuilder(utf.length); -// for(int i=0; i 127 || ch < ' ')) { - throw new IllegalArgumentException("unexpected char " + (int) ch + " decoding " + encoded); - } - buff[j++] = (byte) ch; - } - } - String s = utf8Decode(buff, 0, j); - return s; - } - - /** - * Split a string into an array of strings using the given separator. A null - * string will result in a null array, and an empty string in a zero element - * array. - * - * @param s the string to split - * @param separatorChar the separator character - * @param trim whether each element should be trimmed - * @return the array list - */ - public static String[] arraySplit(String s, char separatorChar, boolean trim) { - if (s == null) { - return null; - } - if (s.length() == 0) { - return new String[0]; - } - ArrayList list = New.arrayList(); - StringBuilder buff = new StringBuilder(s.length()); - for (int i = 0; i < s.length(); i++) { - char c = s.charAt(i); - if (c == separatorChar) { - String e = buff.toString(); - list.add(trim ? e.trim() : e); - buff.setLength(0); - } else if (c == '\\' && i < s.length() - 1) { - buff.append(s.charAt(++i)); - } else { - buff.append(c); - } - } - String e = buff.toString(); - list.add(trim ? e.trim() : e); - String[] array = new String[list.size()]; - list.toArray(array); - return array; - } - - /** - * Combine an array of strings to one array using the given separator - * character. A backslash and the separator character and escaped using a - * backslash. - * - * @param list the string array - * @param separatorChar the separator character - * @return the combined string - */ - public static String arrayCombine(String[] list, char separatorChar) { - StatementBuilder buff = new StatementBuilder(); - for (String s : list) { - buff.appendExceptFirst(String.valueOf(separatorChar)); - if (s == null) { - s = ""; - } - for (int j = 0; j < s.length(); j++) { - char c = s.charAt(j); - if (c == '\\' || c == separatorChar) { - buff.append('\\'); - } - buff.append(c); - } - } - return buff.toString(); - } - - /** - * Creates an XML attribute of the form name="value". - * A single space is prepended to the name, - * so that multiple attributes can be concatenated. - * @param name the attribute name - * @param value the attribute value - * @return the attribute - */ - public static String xmlAttr(String name, String value) { - return " " + name + "=\"" + xmlText(value) + "\""; - } - - /** - * Create an XML node with optional attributes and content. - * The data is indented with 4 spaces if it contains a newline character. - * - * @param name the element name - * @param attributes the attributes (may be null) - * @param content the content (may be null) - * @return the node - */ - public static String xmlNode(String name, String attributes, String content) { - String start = attributes == null ? name : name + attributes; - if (content == null) { - return "<" + start + "/>\n"; - } - if (content.indexOf('\n') >= 0) { - content = "\n" + indent(content); - } - return "<" + start + ">" + content + "\n"; - } - - /** - * Indents a string with 4 spaces. - * @param s the string - * @return the indented string - */ - private static String indent(String s) { - return indent(s, 4); - } - - /** - * Indents a string with spaces. - * @param s the string - * @param spaces the number of spaces - * @return the indented string - */ - private static String indent(String s, int spaces) { - StringBuilder buff = new StringBuilder(s.length() + spaces); - for (int i = 0; i < s.length();) { - for (int j = 0; j < spaces; j++) { - buff.append(' '); - } - int n = s.indexOf('\n', i); - n = n < 0 ? s.length() : n + 1; - buff.append(s.substring(i, n)); - i = n; - } - if (!s.endsWith("\n")) { - buff.append('\n'); - } - return buff.toString(); - } - - /** - * Escapes a comment. - * If the data contains '--', it is converted to '- -'. - * The data is indented with 4 spaces if it contains a newline character. - * - * @param data the comment text - * @return - */ - public static String xmlComment(String data) { - int idx = 0; - while (true) { - idx = data.indexOf("--", idx); - if (idx < 0) { - break; - } - data = data.substring(0, idx + 1) + " " + data.substring(idx + 1); - } - // must have a space at the beginning and at the end, - // otherwise the data must not contain '-' as the first/last character - if (data.indexOf('\n') >= 0) { - return "\n"; - } - return "\n"; - } - - /** - * Converts the data to a CDATA element. - * If the data contains ']]>', it is escaped as a text element. - * - * @param data the text data - * @return - */ - public static String xmlCData(String data) { - if (data.indexOf("]]>") >= 0) { - return xmlText(data); - } - boolean newline = data.endsWith("\n"); - data = ""; - return newline ? data + "\n" : data; - } - - /** - * Returns - * @return - */ - public static String xmlStartDoc() { - return "\n"; - } - - /** - * Escapes an XML text element. - * - * @param text the text data - * @return the escaped text - */ - public static String xmlText(String text) { - StringBuilder buff = new StringBuilder(text.length()); - for (int i = 0; i < text.length(); i++) { - char ch = text.charAt(i); - switch (ch) { - case '<': - buff.append("<"); - break; - case '>': - buff.append(">"); - break; - case '&': - buff.append("&"); - break; - case '\'': - buff.append("'"); - break; - case '\"': - buff.append("""); - break; - case '\r': - case '\n': - case '\t': - buff.append(ch); - break; - default: - if (ch < ' ' || ch > 127) { - buff.append("&#x"). - append(Integer.toHexString(ch)). - append(';'); - } else { - buff.append(ch); - } - } - } - return buff.toString(); - } - - /** - * Replace all occurrences of the before string with the after string. - * - * @param s the string - * @param before the old text - * @param after the new text - * @return the string with the before string replaced - */ - public static String replaceAll(String s, String before, String after) { - StringBuilder buff = new StringBuilder(s.length()); - int index = 0; - while (true) { - int next = s.indexOf(before, index); - if (next < 0) { - buff.append(s.substring(index)); - break; - } - buff.append(s.substring(index, next)).append(after); - index = next + before.length(); - } - return buff.toString(); - } - - /** - * Enclose a string with double quotes. A double quote inside the string is - * escaped using a double quote. - * - * @param s the text - * @return the double quoted text - */ - public static String quoteIdentifier(String s) { - StringBuilder buff = new StringBuilder(s.length() + 2); - buff.append('\"'); - for (int i = 0; i < s.length(); i++) { - char c = s.charAt(i); - if (c == '"') { - buff.append(c); - } - buff.append(c); - } - return buff.append('\"').toString(); - } - - /** - * Check if a String is null or empty (the length is null). - * - * @param s the string to check - * @return true if it is null or empty - */ - public static boolean isNullOrEmpty(String s) { - return s == null || s.length() == 0; - } - - /** - * In a string, replace block comment marks with /++ .. ++/. - * - * @param sql the string - * @return the resulting string - */ - public static String quoteRemarkSQL(String sql) { - while (true) { - int idx = sql.indexOf("*/"); - if (idx < 0) { - break; - } - sql = sql.substring(0, idx) + "++/" + sql.substring(idx + 2); - } - while (true) { - int idx = sql.indexOf("/*"); - if (idx < 0) { - break; - } - sql = sql.substring(0, idx) + "/++" + sql.substring(idx + 2); - } - return sql; - } - - /** - * Pad a string. This method is used for the SQL function RPAD and LPAD. - * - * @param string the original string - * @param n the target length - * @param padding the padding string - * @param right true if the padding should be appended at the end - * @return the padded string - */ - public static String pad(String string, int n, String padding, boolean right) { - if (n < 0) { - n = 0; - } - if (n < string.length()) { - return string.substring(0, n); - } else if (n == string.length()) { - return string; - } - char paddingChar; - if (padding == null || padding.length() == 0) { - paddingChar = ' '; - } else { - paddingChar = padding.charAt(0); - } - StringBuilder buff = new StringBuilder(n); - n -= string.length(); - if (right) { - buff.append(string); - } - for (int i = 0; i < n; i++) { - buff.append(paddingChar); - } - if (!right) { - buff.append(string); - } - return buff.toString(); - } - - /** - * Create a new char array and copy all the data. If the size of the byte - * array is zero, the same array is returned. - * - * @param chars the char array (may be null) - * @return a new char array - */ - public static char[] cloneCharArray(char[] chars) { - if (chars == null) { - return null; - } - int len = chars.length; - if (len == 0) { - return chars; - } - char[] copy = new char[len]; - System.arraycopy(chars, 0, copy, 0, len); - return copy; - } - - /** - * Trim a character from a string. - * - * @param s the string - * @param leading if leading characters should be removed - * @param trailing if trailing characters should be removed - * @param sp what to remove (only the first character is used) - * or null for a space - * @return the trimmed string - */ - public static String trim(String s, boolean leading, boolean trailing, String sp) { - char space = (sp == null || sp.length() < 1) ? ' ' : sp.charAt(0); - if (leading) { - int len = s.length(), i = 0; - while (i < len && s.charAt(i) == space) { - i++; - } - s = (i == 0) ? s : s.substring(i); - } - if (trailing) { - int endIndex = s.length() - 1; - int i = endIndex; - while (i >= 0 && s.charAt(i) == space) { - i--; - } - s = i == endIndex ? s : s.substring(0, i + 1); - } - return s; - } - - /** - * Get the string from the cache if possible. If the string has not been - * found, it is added to the cache. If there is such a string in the cache, - * that one is returned. - * - * @param s the original string - * @return a string with the same content, if possible from the cache - */ - public static String cache(String s) { - if (!SysProperties.OBJECT_CACHE) { - return s; - } - if (s == null) { - return s; - } else if (s.length() == 0) { - return ""; - } - int hash = s.hashCode(); - String[] cache = getCache(); - if (cache != null) { - int index = hash & (SysProperties.OBJECT_CACHE_SIZE - 1); - String cached = cache[index]; - if (cached != null) { - if (s.equals(cached)) { - return cached; - } - } - cache[index] = s; - } - return s; - } - - /** - * Get a string from the cache, and if no such string has been found, create - * a new one with only this content. This solves out of memory problems if - * the string is a substring of another, large string. In Java, strings are - * shared, which could lead to memory problems. This avoid such problems. - * - * @param s the string - * @return a string that is guaranteed not be a substring of a large string - */ - public static String fromCacheOrNew(String s) { - if (!SysProperties.OBJECT_CACHE) { - return s; - } - if (s == null) { - return s; - } else if (s.length() == 0) { - return ""; - } - int hash = s.hashCode(); - String[] cache = getCache(); - int index = hash & (SysProperties.OBJECT_CACHE_SIZE - 1); - if (cache == null) { - return s; - } - String cached = cache[index]; - if (cached != null) { - if (s.equals(cached)) { - return cached; - } - } - // create a new object that is not shared - // (to avoid out of memory if it is a substring of a big String) - // NOPMD - s = new String(s); - cache[index] = s; - return s; - } - - /** - * Clear the cache. This method is used for testing. - */ - public static void clearCache() { - softCache = new SoftReference(null); - } - -} diff --git a/tools/h2/src/main/org/h2/util/TempFileDeleter.java b/tools/h2/src/main/org/h2/util/TempFileDeleter.java deleted file mode 100755 index e9f68f3..0000000 --- a/tools/h2/src/main/org/h2/util/TempFileDeleter.java +++ /dev/null @@ -1,116 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.util; - -import java.lang.ref.PhantomReference; -import java.lang.ref.Reference; -import java.lang.ref.ReferenceQueue; -import java.util.HashMap; - -import org.h2.constant.SysProperties; -import org.h2.message.DbException; - -/** - * This class deletes temporary files when they are not used any longer. - */ -public class TempFileDeleter { - - private final ReferenceQueue queue = new ReferenceQueue(); - private final HashMap, String> refMap = New.hashMap(); - - private TempFileDeleter() { - // utility class - } - - public static TempFileDeleter getInstance() { - return new TempFileDeleter(); - } - - /** - * Add a file to the list of temp files to delete. The file is deleted once - * the file object is garbage collected. - * - * @param fileName the file name - * @param file the object to monitor - * @return the reference that can be used to stop deleting the file - */ - public synchronized Reference< ? > addFile(String fileName, Object file) { - IOUtils.trace("TempFileDeleter.addFile", fileName, file); - PhantomReference< ? > ref = new PhantomReference(file, queue); - refMap.put(ref, fileName); - deleteUnused(); - return ref; - } - - /** - * Delete the given file now. This will remove the reference from the list. - * - * @param ref the reference as returned by addFile - * @param fileName the file name - */ - public synchronized void deleteFile(Reference< ? > ref, String fileName) { - if (ref != null) { - String f2 = refMap.remove(ref); - if (f2 != null) { - if (SysProperties.CHECK && fileName != null && !f2.equals(fileName)) { - DbException.throwInternalError("f2:" + f2 + " f:" + fileName); - } - fileName = f2; - } - } - if (fileName != null && IOUtils.exists(fileName)) { - try { - IOUtils.trace("TempFileDeleter.deleteFile", fileName, null); - IOUtils.tryDelete(fileName); - } catch (Exception e) { - // TODO log such errors? - } - } - } - - /** - * Delete all registered temp files. - */ - public void deleteAll() { - for (String tempFile : refMap.values()) { - deleteFile(null, tempFile); - } - deleteUnused(); - } - - /** - * Delete all unused files now. - */ - public void deleteUnused() { - while (queue != null) { - Reference< ? extends Object> ref = queue.poll(); - if (ref == null) { - break; - } - deleteFile(ref, null); - } - } - - /** - * This method is called if a file should no longer be deleted if the object - * is garbage collected. - * - * @param ref the reference as returned by addFile - * @param fileName the file name - */ - public void stopAutoDelete(Reference< ? > ref, String fileName) { - IOUtils.trace("TempFileDeleter.stopAutoDelete", fileName, ref); - if (ref != null) { - String f2 = refMap.remove(ref); - if (SysProperties.CHECK && (f2 == null || !f2.equals(fileName))) { - DbException.throwInternalError("f2:" + f2 + " " + (f2 == null ? "" : f2) + " f:" + fileName); - } - } - deleteUnused(); - } - -} diff --git a/tools/h2/src/main/org/h2/util/Tool.java b/tools/h2/src/main/org/h2/util/Tool.java deleted file mode 100755 index 1c8a7e1..0000000 --- a/tools/h2/src/main/org/h2/util/Tool.java +++ /dev/null @@ -1,96 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.util; - -import java.io.ByteArrayInputStream; -import java.io.IOException; -import java.io.PrintStream; -import java.sql.SQLException; -import java.util.Properties; - -/** - * Command line tools implement the tool interface so that they can be used in - * the H2 Console. - */ -public abstract class Tool { - - /** - * The output stream where this tool writes to. - */ - protected PrintStream out = System.out; - - private Properties resources; - - /** - * Sets the standard output stream. - * - * @param out the new standard output stream - */ - public void setOut(PrintStream out) { - this.out = out; - } - - /** - * Run the tool with the given output stream and arguments. - * - * @param args the argument list - */ - public abstract void runTool(String... args) throws SQLException; - - /** - * Throw a SQLException saying this command line option is not supported. - * - * @param option the unsupported option - * @return this method never returns normally - */ - protected SQLException throwUnsupportedOption(String option) throws SQLException { - showUsage(); - throw new SQLException("Unsupported option: " + option); - } - - /** - * Print to the output stream that no database files have been found. - * - * @param dir the directory or null - * @param db the database name or null - */ - protected void printNoDatabaseFilesFound(String dir, String db) { - StringBuilder buff = new StringBuilder("No database files have been found"); - if (dir != null) { - buff.append(" in directory ").append(dir); - } - if (db != null) { - buff.append(" for the database ").append(db); - } - out.println(buff.toString()); - } - - /** - * Print the usage of the tool. This method reads the description from the - * resource file. - */ - protected void showUsage() { - if (resources == null) { - resources = new Properties(); - String resourceName = "/org/h2/res/javadoc.properties"; - try { - byte[] buff = Utils.getResource(resourceName); - if (buff != null) { - resources.load(new ByteArrayInputStream(buff)); - } - } catch (IOException e) { - out.println("Cannot load " + resourceName); - } - } - String className = getClass().getName(); - out.println(resources.get(className)); - out.println("Usage: java "+getClass().getName() + " "); - out.println(resources.get(className + ".main")); - out.println("See also http://h2database.com/javadoc/" + className.replace('.', '/') + ".html"); - } - -} diff --git a/tools/h2/src/main/org/h2/util/Utils.java b/tools/h2/src/main/org/h2/util/Utils.java deleted file mode 100755 index b28f605..0000000 --- a/tools/h2/src/main/org/h2/util/Utils.java +++ /dev/null @@ -1,546 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.util; - -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.ObjectInputStream; -import java.io.ObjectOutputStream; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.HashSet; -import java.util.zip.ZipEntry; -import java.util.zip.ZipInputStream; -import org.h2.constant.ErrorCode; -import org.h2.constant.SysProperties; -import org.h2.message.DbException; - -/** - * This utility class contains miscellaneous functions. - */ -public class Utils { - - /** - * An 0-size byte array. - */ - public static final byte[] EMPTY_BYTES = {}; - - /** - * An 0-size int array. - */ - public static final int[] EMPTY_INT_ARRAY = {}; - - /** - * An 0-size long array. - */ - private static final long[] EMPTY_LONG_ARRAY = {}; - - private static final int GC_DELAY = 50; - private static final int MAX_GC = 8; - private static final char[] HEX = "0123456789abcdef".toCharArray(); - - private static long lastGC; - - private static final boolean ALLOW_ALL_CLASSES; - private static final HashSet ALLOWED_CLASS_NAMES = New.hashSet(); - private static final String[] ALLOWED_CLASS_NAME_PREFIXES; - - private static final HashMap RESOURCES = New.hashMap(); - - static { - String s = SysProperties.ALLOWED_CLASSES; - ArrayList prefixes = New.arrayList(); - boolean allowAll = false; - for (String p : StringUtils.arraySplit(s, ',', true)) { - if (p.equals("*")) { - allowAll = true; - } else if (p.endsWith("*")) { - prefixes.add(p.substring(0, p.length() - 1)); - } else { - ALLOWED_CLASS_NAMES.add(p); - } - } - ALLOW_ALL_CLASSES = allowAll; - ALLOWED_CLASS_NAME_PREFIXES = new String[prefixes.size()]; - prefixes.toArray(ALLOWED_CLASS_NAME_PREFIXES); - } - - private Utils() { - // utility class - } - - private static int readInt(byte[] buff, int pos) { - return (buff[pos++] << 24) + ((buff[pos++] & 0xff) << 16) + ((buff[pos++] & 0xff) << 8) + (buff[pos] & 0xff); - } - - /** - * Read a long value from the byte array at the given position. The most - * significant byte is read first. - * - * @param buff the byte array - * @param pos the position - * @return the value - */ - public static long readLong(byte[] buff, int pos) { - return ((long) (readInt(buff, pos)) << 32) + (readInt(buff, pos + 4) & 0xffffffffL); - } - - /** - * Write a long value to the byte array. - * - * @param buff the byte array - * @param pos the position - * @param x the value - */ - public static void writeLong(byte[] buff, int pos, long x) { - for (int i = 0; i < 8; i++) { - buff[pos + i] = (byte) ((x >> (8 * (8 - i))) & 255); - } - } - - /** - * Calculate the index of the first occurrence of the pattern in the byte - * array, starting with the given index. This methods returns -1 if the - * pattern has not been found, and the start position if the pattern is - * empty. - * - * @param bytes the byte array - * @param pattern the pattern - * @param start the start index from where to search - * @return the index - */ - public static int indexOf(byte[] bytes, byte[] pattern, int start) { - if (pattern.length == 0) { - return start; - } - if (start > bytes.length) { - return -1; - } - int last = bytes.length - pattern.length + 1; - next: for (; start < last; start++) { - for (int i = 0; i < pattern.length; i++) { - if (bytes[start + i] != pattern[i]) { - continue next; - } - } - return start; - } - return -1; - } - - /** - * Convert a hex encoded string to a byte array. - * - * @param s the hex encoded string - * @return the byte array - */ - public static byte[] convertStringToBytes(String s) { - int len = s.length(); - if (len % 2 != 0) { - throw DbException.get(ErrorCode.HEX_STRING_ODD_1, s); - } - len /= 2; - byte[] buff = new byte[len]; - for (int i = 0; i < len; i++) { - buff[i] = (byte) ((getHexDigit(s, i + i) << 4) | getHexDigit(s, i + i + 1)); - } - return buff; - } - - private static int getHexDigit(String s, int i) { - char c = s.charAt(i); - if (c >= '0' && c <= '9') { - return c - '0'; - } else if (c >= 'a' && c <= 'f') { - return c - 'a' + 0xa; - } else if (c >= 'A' && c <= 'F') { - return c - 'A' + 0xa; - } else { - throw DbException.get(ErrorCode.HEX_STRING_WRONG_1, s); - } - } - - /** - * Calculate the hash code of the given byte array. - * - * @param value the byte array - * @return the hash code - */ - public static int getByteArrayHash(byte[] value) { - int len = value.length; - int h = len; - if (len < 50) { - for (int i = 0; i < len; i++) { - h = 31 * h + value[i]; - } - } else { - int step = len / 16; - for (int i = 0; i < 4; i++) { - h = 31 * h + value[i]; - h = 31 * h + value[--len]; - } - for (int i = 4 + step; i < len; i += step) { - h = 31 * h + value[i]; - } - } - return h; - } - - /** - * Convert a byte array to a hex encoded string. - * - * @param value the byte array - * @return the hex encoded string - */ - public static String convertBytesToString(byte[] value) { - return convertBytesToString(value, value.length); - } - - /** - * Convert a byte array to a hex encoded string. - * - * @param value the byte array - * @param len the number of bytes to encode - * @return the hex encoded string - */ - public static String convertBytesToString(byte[] value, int len) { - char[] buff = new char[len + len]; - char[] hex = HEX; - for (int i = 0; i < len; i++) { - int c = value[i] & 0xff; - buff[i + i] = hex[c >> 4]; - buff[i + i + 1] = hex[c & 0xf]; - } - return new String(buff); - } - - /** - * Compare two byte arrays. This method will always loop over all bytes and - * doesn't use conditional operations in the loop to make sure an attacker - * can not use a timing attack when trying out passwords. - * - * @param test the first array - * @param good the second array - * @return true if both byte arrays contain the same bytes - */ - public static boolean compareSecure(byte[] test, byte[] good) { - if ((test == null) || (good == null)) { - return (test == null) && (good == null); - } - if (test.length != good.length) { - return false; - } - if (test.length == 0) { - return true; - } - // don't use conditional operations inside the loop - int bits = 0; - for (int i = 0; i < good.length; i++) { - // this will never reset any bits - bits |= test[i] ^ good[i]; - } - return bits == 0; - } - - /** - * Compare the contents of two byte arrays. If the content or length of the - * first array is smaller than the second array, -1 is returned. If the - * content or length of the second array is smaller than the first array, 1 - * is returned. If the contents and lengths are the same, 0 is returned. - * - * @param data1 the first byte array (must not be null) - * @param data2 the second byte array (must not be null) - * @return the result of the comparison (-1, 1 or 0) - */ - public static int compareNotNull(byte[] data1, byte[] data2) { - int len = Math.min(data1.length, data2.length); - for (int i = 0; i < len; i++) { - byte b = data1[i]; - byte b2 = data2[i]; - if (b != b2) { - return b > b2 ? 1 : -1; - } - } - return Integer.signum(data1.length - data2.length); - } - - /** - * Copy the contents of the source array to the target array. If the size if - * the target array is too small, a larger array is created. - * - * @param source the source array - * @param target the target array - * @return the target array or a new one if the target array was too small - */ - public static byte[] copy(byte[] source, byte[] target) { - int len = source.length; - if (len > target.length) { - target = new byte[len]; - } - System.arraycopy(source, 0, target, 0, len); - return target; - } - - /** - * Create a new byte array and copy all the data. If the size of the byte - * array is zero, the same array is returned. - * - * @param b the byte array (may not be null) - * @return a new byte array - */ - public static byte[] cloneByteArray(byte[] b) { - if (b == null) { - return null; - } - int len = b.length; - if (len == 0) { - return b; - } - byte[] copy = new byte[len]; - System.arraycopy(b, 0, copy, 0, len); - return copy; - } - - /** - * Serialize the object to a byte array. - * - * @param obj the object to serialize - * @return the byte array - */ - public static byte[] serialize(Object obj) { - try { - ByteArrayOutputStream out = new ByteArrayOutputStream(); - ObjectOutputStream os = new ObjectOutputStream(out); - os.writeObject(obj); - return out.toByteArray(); - } catch (Throwable e) { - throw DbException.get(ErrorCode.SERIALIZATION_FAILED_1, e, e.toString()); - } - } - - /** - * De-serialize the byte array to an object. - * - * @param data the byte array - * @return the object - * @throws SQLException - */ - public static Object deserialize(byte[] data) { - try { - ByteArrayInputStream in = new ByteArrayInputStream(data); - ObjectInputStream is = new ObjectInputStream(in); - Object obj = is.readObject(); - return obj; - } catch (Throwable e) { - throw DbException.get(ErrorCode.DESERIALIZATION_FAILED_1, e, e.toString()); - } - } - - /** - * Calculate the hash code of the given object. The object may be null. - * - * @param o the object - * @return the hash code, or 0 if the object is null - */ - public static int hashCode(Object o) { - return o == null ? 0 : o.hashCode(); - } - - /** - * Get the used memory in KB. - * This method possibly calls System.gc(). - * - * @return the used memory - */ - public static int getMemoryUsed() { - collectGarbage(); - Runtime rt = Runtime.getRuntime(); - long mem = rt.totalMemory() - rt.freeMemory(); - return (int) (mem >> 10); - } - - /** - * Get the free memory in KB. - * This method possibly calls System.gc(). - * - * @return the free memory - */ - public static int getMemoryFree() { - collectGarbage(); - Runtime rt = Runtime.getRuntime(); - long mem = rt.freeMemory(); - return (int) (mem >> 10); - } - - /** - * Get the maximum memory in KB. - * - * @return the maximum memory - */ - public static long getMemoryMax() { - long max = Runtime.getRuntime().maxMemory(); - return max / 1024; - } - - private static synchronized void collectGarbage() { - Runtime runtime = Runtime.getRuntime(); - long total = runtime.totalMemory(); - long time = System.currentTimeMillis(); - if (lastGC + GC_DELAY < time) { - for (int i = 0; i < MAX_GC; i++) { - runtime.gc(); - long now = runtime.totalMemory(); - if (now == total) { - lastGC = System.currentTimeMillis(); - break; - } - total = now; - } - } - } - - /** - * Create an array of bytes with the given size. If this is not possible - * because not enough memory is available, an OutOfMemoryError with the - * requested size in the message is thrown. - * - * @param len the number of bytes requested - * @return the byte array - * @throws OutOfMemoryError - */ - public static byte[] newBytes(int len) { - try { - if (len == 0) { - return EMPTY_BYTES; - } - return new byte[len]; - } catch (OutOfMemoryError e) { - Error e2 = new OutOfMemoryError("Requested memory: " + len); - e2.initCause(e); - throw e2; - } - } - - /** - * Create an int array with the given size. - * - * @param len the number of bytes requested - * @return the int array - */ - public static int[] newIntArray(int len) { - if (len == 0) { - return EMPTY_INT_ARRAY; - } - return new int[len]; - } - - /** - * Create a long array with the given size. - * - * @param len the number of bytes requested - * @return the int array - */ - public static long[] newLongArray(int len) { - if (len == 0) { - return EMPTY_LONG_ARRAY; - } - return new long[len]; - } - - /** - * Load a class, but check if it is allowed to load this class first. To - * perform access rights checking, the system property h2.allowedClasses - * needs to be set to a list of class file name prefixes. - * - * @param className the name of the class - * @return the class object - */ - public static Class< ? > loadUserClass(String className) { - if (!ALLOW_ALL_CLASSES && !ALLOWED_CLASS_NAMES.contains(className)) { - boolean allowed = false; - for (String s : ALLOWED_CLASS_NAME_PREFIXES) { - if (className.startsWith(s)) { - allowed = true; - } - } - if (!allowed) { - throw DbException.get(ErrorCode.ACCESS_DENIED_TO_CLASS_1, className); - } - } - try { - return Class.forName(className); - } catch (ClassNotFoundException e) { - try { - return Class.forName(className, true, Thread.currentThread().getContextClassLoader()); - } catch (Exception e2) { - throw DbException.get(ErrorCode.CLASS_NOT_FOUND_1, e, className); - } - } catch (NoClassDefFoundError e) { - throw DbException.get(ErrorCode.CLASS_NOT_FOUND_1, e, className); - } catch (Error e) { - // UnsupportedClassVersionError - throw DbException.get(ErrorCode.GENERAL_ERROR_1, e, className); - } - } - - /** - * Get a resource from the resource map. - * - * @param name the name of the resource - * @return the resource data - */ - public static byte[] getResource(String name) throws IOException { - byte[] data; - if (RESOURCES.size() == 0) { - // TODO web: security (check what happens with files like 'lpt1.txt' on windows) - InputStream in = Utils.class.getResourceAsStream(name); - if (in == null) { - data = null; - } else { - data = IOUtils.readBytesAndClose(in, 0); - } - } else { - data = RESOURCES.get(name); - } - return data == null ? EMPTY_BYTES : data; - } - - static { - loadResourcesFromZip(); - } - - private static void loadResourcesFromZip() { - InputStream in = Utils.class.getResourceAsStream("data.zip"); - if (in == null) { - return; - } - ZipInputStream zipIn = new ZipInputStream(in); - try { - while (true) { - ZipEntry entry = zipIn.getNextEntry(); - if (entry == null) { - break; - } - String entryName = entry.getName(); - if (!entryName.startsWith("/")) { - entryName = "/" + entryName; - } - ByteArrayOutputStream out = new ByteArrayOutputStream(); - IOUtils.copy(zipIn, out); - zipIn.closeEntry(); - RESOURCES.put(entryName, out.toByteArray()); - } - zipIn.close(); - } catch (IOException e) { - // if this happens we have a real problem - e.printStackTrace(); - } - } - -} diff --git a/tools/h2/src/main/org/h2/util/ValueHashMap.java b/tools/h2/src/main/org/h2/util/ValueHashMap.java deleted file mode 100755 index 6d3bf17..0000000 --- a/tools/h2/src/main/org/h2/util/ValueHashMap.java +++ /dev/null @@ -1,181 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.util; - -import java.util.ArrayList; -import org.h2.message.DbException; -import org.h2.value.Value; -import org.h2.value.ValueNull; - -/** - * This hash map supports keys of type Value. - * - * @param the value type - */ -public class ValueHashMap extends HashBase { - - private Value[] keys; - private V[] values; - - /** - * Create a new value hash map. - * - * @return the object - */ - public static ValueHashMap newInstance() { - return new ValueHashMap(); - } - - @SuppressWarnings("unchecked") - protected void reset(int newLevel) { - super.reset(newLevel); - keys = new Value[len]; - values = (V[]) new Object[len]; - } - - protected void rehash(int newLevel) { - Value[] oldKeys = keys; - V[] oldValues = values; - reset(newLevel); - for (int i = 0; i < oldKeys.length; i++) { - Value k = oldKeys[i]; - if (k != null && k != ValueNull.DELETED) { - put(k, oldValues[i]); - } - } - } - - private int getIndex(Value key) { - return key.hashCode() & mask; - } - - /** - * Add or update a key value pair. - * - * @param key the key - * @param value the new value - */ - public void put(Value key, V value) { - checkSizePut(); - int index = getIndex(key); - int plus = 1; - int deleted = -1; - do { - Value k = keys[index]; - if (k == null) { - // found an empty record - if (deleted >= 0) { - index = deleted; - deletedCount--; - } - size++; - keys[index] = key; - values[index] = value; - return; - } else if (k == ValueNull.DELETED) { - // found a deleted record - if (deleted < 0) { - deleted = index; - } - } else if (k.equals(key)) { - // update existing - values[index] = value; - return; - } - index = (index + plus++) & mask; - } while (plus <= len); - // no space - DbException.throwInternalError("hashmap is full"); - } - - /** - * Remove a key value pair. - * - * @param key the key - */ - public void remove(Value key) { - checkSizeRemove(); - int index = getIndex(key); - int plus = 1; - do { - Value k = keys[index]; - if (k == null) { - // found an empty record - return; - } else if (k == ValueNull.DELETED) { - // found a deleted record - } else if (k.equals(key)) { - // found the record - keys[index] = ValueNull.DELETED; - values[index] = null; - deletedCount++; - size--; - return; - } - index = (index + plus++) & mask; - } while(plus <= len); - // not found - } - - /** - * Get the value for this key. This method returns null if the key was not - * found. - * - * @param key the key - * @return the value for the given key - */ - public V get(Value key) { - int index = getIndex(key); - int plus = 1; - do { - Value k = keys[index]; - if (k == null) { - // found an empty record - return null; - } else if (k == ValueNull.DELETED) { - // found a deleted record - } else if (k.equals(key)) { - // found it - return values[index]; - } - index = (index + plus++) & mask; - } while (plus <= len); - return null; - } - - /** - * Get the list of keys. - * - * @return all keys - */ - public ArrayList keys() { - ArrayList list = New.arrayList(size); - for (Value k : keys) { - if (k != null && k != ValueNull.DELETED) { - list.add(k); - } - } - return list; - } - - /** - * Get the list of values. - * - * @return all values - */ - public ArrayList values() { - ArrayList list = New.arrayList(size); - for (int i = 0; i < keys.length; i++) { - Value k = keys[i]; - if (k != null && k != ValueNull.DELETED) { - list.add(values[i]); - } - } - return list; - } - -} diff --git a/tools/h2/src/main/org/h2/util/package.html b/tools/h2/src/main/org/h2/util/package.html deleted file mode 100755 index c0bd4fe..0000000 --- a/tools/h2/src/main/org/h2/util/package.html +++ /dev/null @@ -1,15 +0,0 @@ - - - - -Javadoc package documentation -

- -Internal utility classes. - -

\ No newline at end of file diff --git a/tools/h2/src/main/org/h2/value/CompareMode.java b/tools/h2/src/main/org/h2/value/CompareMode.java deleted file mode 100755 index c81c579..0000000 --- a/tools/h2/src/main/org/h2/value/CompareMode.java +++ /dev/null @@ -1,206 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.value; - -import java.text.CollationKey; -import java.text.Collator; -import java.util.Locale; - -import org.h2.constant.SysProperties; -import org.h2.util.SmallLRUCache; -import org.h2.util.StringUtils; - -/** - * Instances of this class can compare strings. - * Case sensitive and case insensitive comparison is supported, - * and comparison using a collator. - */ -public class CompareMode { - - /** - * This constant means there is no collator set, - * and the default string comparison is to be used. - */ - public static final String OFF = "OFF"; - - private static CompareMode lastUsed; - - private final String name; - private final int strength; - private final Collator collator; - private final SmallLRUCache collationKeys; - - private CompareMode(String name, int strength) { - this.name = name; - this.strength = strength; - this.collator = CompareMode.getCollator(name); - int cacheSize = 0; - if (collator != null) { - this.collator.setStrength(strength); - cacheSize = SysProperties.getCollatorCacheSize(); - } - if (cacheSize != 0) { - collationKeys = SmallLRUCache.newInstance(cacheSize); - } else { - collationKeys = null; - } - } - - /** - * Create a new compare mode with the given collator and strength. If - * required, a new CompareMode is created, or if possible the last one is - * returned. A cache is used to speed up comparison when using a collator; - * CollationKey objects are cached. - * - * @param name the collation name or null - * @param strength the collation strength - * @return the compare mode - */ - public static synchronized CompareMode getInstance(String name, int strength) { - if (lastUsed != null) { - if (StringUtils.equals(lastUsed.name, name)) { - if (lastUsed.strength == strength) { - return lastUsed; - } - } - } - lastUsed = new CompareMode(name, strength); - return lastUsed; - } - - /** - * Compare two characters in a string. - * - * @param a the first string - * @param ai the character index in the first string - * @param b the second string - * @param bi the character index in the second string - * @param ignoreCase true if a case-insensitive comparison should be made - * @return true if the characters are equals - */ - public boolean equalsChars(String a, int ai, String b, int bi, boolean ignoreCase) { - if (collator != null) { - return compareString(a.substring(ai, ai + 1), b.substring(bi, bi + 1), ignoreCase) == 0; - } - char ca = a.charAt(ai); - char cb = b.charAt(bi); - if (ignoreCase) { - ca = Character.toUpperCase(ca); - cb = Character.toUpperCase(cb); - } - return ca == cb; - } - - /** - * Compare two strings. - * - * @param a the first string - * @param b the second string - * @param ignoreCase true if a case-insensitive comparison should be made - * @return -1 if the first string is 'smaller', 1 if the second string is - * smaller, and 0 if they are equal - */ - public int compareString(String a, String b, boolean ignoreCase) { - if (collator == null) { - if (ignoreCase) { - return a.compareToIgnoreCase(b); - } - return a.compareTo(b); - } - if (ignoreCase) { - // this is locale sensitive - a = a.toUpperCase(); - b = b.toUpperCase(); - } - int comp; - if (collationKeys != null) { - CollationKey aKey = getKey(a); - CollationKey bKey = getKey(b); - comp = aKey.compareTo(bKey); - } else { - comp = collator.compare(a, b); - } - return comp; - } - - private CollationKey getKey(String a) { - synchronized (collationKeys) { - CollationKey key = collationKeys.get(a); - if (key == null) { - key = collator.getCollationKey(a); - collationKeys.put(a, key); - } - return key; - } - } - - /** - * Get the collation name. - * - * @param l the locale - * @return the name of the collation - */ - public static String getName(Locale l) { - Locale english = Locale.ENGLISH; - String name = l.getDisplayLanguage(english) + ' ' + l.getDisplayCountry(english) + ' ' + l.getVariant(); - name = StringUtils.toUpperEnglish(name.trim().replace(' ', '_')); - return name; - } - - private static boolean compareLocaleNames(Locale locale, String name) { - return name.equalsIgnoreCase(locale.toString()) || name.equalsIgnoreCase(getName(locale)); - } - - /** - * Get the collator object for the given language name or language / country - * combination. - * - * @param name the language name - * @return the collator - */ - public static Collator getCollator(String name) { - if (name == null || name.equals(OFF)) { - return null; - } - Collator result = null; - if (name.length() == 2) { - Locale locale = new Locale(name.toLowerCase(), ""); - if (compareLocaleNames(locale, name)) { - result = Collator.getInstance(locale); - } - } else if (name.length() == 5) { - // LL_CC (language_country) - int idx = name.indexOf('_'); - if (idx >= 0) { - String language = name.substring(0, idx).toLowerCase(); - String country = name.substring(idx + 1); - Locale locale = new Locale(language, country); - if (compareLocaleNames(locale, name)) { - result = Collator.getInstance(locale); - } - } - } - if (result == null) { - for (Locale locale : Collator.getAvailableLocales()) { - if (compareLocaleNames(locale, name)) { - result = Collator.getInstance(locale); - break; - } - } - } - return result; - } - - public String getName() { - return name == null ? OFF : name; - } - - public int getStrength() { - return strength; - } - -} diff --git a/tools/h2/src/main/org/h2/value/DataType.java b/tools/h2/src/main/org/h2/value/DataType.java deleted file mode 100755 index 58cba86..0000000 --- a/tools/h2/src/main/org/h2/value/DataType.java +++ /dev/null @@ -1,1036 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.value; - -import java.io.BufferedReader; -import java.io.InputStream; -import java.io.Reader; -import java.math.BigDecimal; -import java.sql.Array; -import java.sql.Blob; -import java.sql.Clob; -import java.sql.Date; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.sql.Time; -import java.sql.Timestamp; -import java.sql.Types; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.UUID; - -import org.h2.constant.ErrorCode; -import org.h2.constant.SysProperties; -import org.h2.engine.SessionInterface; -import org.h2.jdbc.JdbcBlob; -import org.h2.jdbc.JdbcClob; -import org.h2.jdbc.JdbcConnection; -import org.h2.message.DbException; -import org.h2.store.LobStorage; -import org.h2.util.Utils; -import org.h2.util.New; -import org.h2.util.StringUtils; - -/** - * This class contains meta data information about data types, - * and can convert between Java objects and Values. - */ -public class DataType { - - /** - * This constant is used for JDK 1.3 compatibility - * and equal to java.sql.Types.BOOLEAN - */ - public static final int TYPE_BOOLEAN = 16; - - /** - * This constant is used for JDK 1.3 compatibility - * and equal to java.sql.Types.DATALINK - */ - public static final int TYPE_DATALINK = 70; - - /** - * This constant is used for JDK 1.5 compatibility - * and equal to java.sql.Types.LONGNVARCHAR - */ - public static final int TYPE_LONGNVARCHAR = -16; - - /** - * This constant is used for JDK 1.5 compatibility - * and equal to java.sql.Types.NCHAR - */ - public static final int TYPE_NCHAR = -15; - - /** - * This constant is used for JDK 1.5 compatibility - * and equal to java.sql.Types.NVARCHAR - */ - public static final int TYPE_NVARCHAR = -9; - - /** - * This constant is used for JDK 1.5 compatibility - * and equal to java.sql.Types.NCLOB - */ - public static final int TYPE_NCLOB = 2011; - - /** - * The list of types. An ArrayList so that Tomcat doesn't set it to null - * when clearing references. - */ - private static final ArrayList TYPES = New.arrayList(); - private static final HashMap TYPES_BY_NAME = New.hashMap(); - private static final ArrayList TYPES_BY_VALUE_TYPE = New.arrayList(); - - /** - * The value type of this data type. - */ - public int type; - - /** - * The data type name. - */ - public String name; - - /** - * The SQL type. - */ - public int sqlType; - - /** - * The Java class name. - */ - public String jdbc; - - /** - * How closely the data type maps to the corresponding JDBC SQL type (low is - * best). - */ - public int sqlTypePos; - - /** - * The maximum supported precision. - */ - public long maxPrecision; - - /** - * The lowest possible scale. - */ - public int minScale; - - /** - * The highest possible scale. - */ - public int maxScale; - - /** - * If this is a numeric type. - */ - public boolean decimal; - - /** - * The prefix required for the SQL literal representation. - */ - public String prefix; - - /** - * The suffix required for the SQL literal representation. - */ - public String suffix; - - /** - * The list of parameters used in the column definition. - */ - public String params; - - /** - * If this is an autoincrement type. - */ - public boolean autoIncrement; - - /** - * If this data type is an autoincrement type. - */ - public boolean caseSensitive; - - /** - * If the precision parameter is supported. - */ - public boolean supportsPrecision; - - /** - * If the scale parameter is supported. - */ - public boolean supportsScale; - - /** - * The default precision. - */ - public long defaultPrecision; - - /** - * The default scale. - */ - public int defaultScale; - - /** - * The default display size. - */ - public int defaultDisplaySize; - - /** - * If this data type should not be listed in the database meta data. - */ - public boolean hidden; - - /** - * The number of bytes required for an object. - */ - public int memory; - - static { - for (int i = 0; i < Value.TYPE_COUNT; i++) { - TYPES_BY_VALUE_TYPE.add(null); - } - add(Value.NULL, Types.NULL, "Null", - new DataType(), - new String[]{"NULL"}, - 1 - ); - add(Value.STRING, Types.VARCHAR, "String", - createString(true), - new String[]{"VARCHAR", "VARCHAR2", "NVARCHAR", "NVARCHAR2", "VARCHAR_CASESENSITIVE", "CHARACTER VARYING", "TID"}, - 4 - ); - add(Value.STRING, Types.LONGVARCHAR, "String", - createString(true), - new String[]{"LONGVARCHAR", "LONGNVARCHAR"}, - 4 - ); - add(Value.STRING_FIXED, Types.CHAR, "String", - createString(true), - new String[]{"CHAR", "CHARACTER", "NCHAR"}, - 4 - ); - add(Value.STRING_IGNORECASE, Types.VARCHAR, "String", - createString(false), - new String[]{"VARCHAR_IGNORECASE"}, - 4 - ); - add(Value.BOOLEAN, DataType.TYPE_BOOLEAN, "Boolean", - createDecimal(ValueBoolean.PRECISION, ValueBoolean.PRECISION, 0, ValueBoolean.DISPLAY_SIZE, false, false), - new String[]{"BOOLEAN", "BIT", "BOOL"}, - 1 - ); - add(Value.BYTE, Types.TINYINT, "Byte", - createDecimal(ValueByte.PRECISION, ValueByte.PRECISION, 0, ValueByte.DISPLAY_SIZE, false, false), - new String[]{"TINYINT"}, - 1 - ); - add(Value.SHORT, Types.SMALLINT, "Short", - createDecimal(ValueShort.PRECISION, ValueShort.PRECISION, 0, ValueShort.DISPLAY_SIZE, false, false), - new String[]{"SMALLINT", "YEAR", "INT2"}, - 5 - ); - add(Value.INT, Types.INTEGER, "Int", - createDecimal(ValueInt.PRECISION, ValueInt.PRECISION, 0, ValueInt.DISPLAY_SIZE, false, false), - new String[]{"INTEGER", "INT", "MEDIUMINT", "INT4", "SIGNED"}, - 5 - ); - add(Value.LONG, Types.BIGINT, "Long", - createDecimal(ValueLong.PRECISION, ValueLong.PRECISION, 0, ValueLong.DISPLAY_SIZE, false, false), - new String[]{"BIGINT", "INT8", "LONG"}, - 5 - ); - add(Value.LONG, Types.BIGINT, "Long", - createDecimal(ValueLong.PRECISION, ValueLong.PRECISION, 0, ValueLong.DISPLAY_SIZE, false, true), - new String[]{"IDENTITY", "SERIAL"}, - 5 - ); - add(Value.DECIMAL, Types.DECIMAL, "BigDecimal", - createDecimal(Integer.MAX_VALUE, ValueDecimal.DEFAULT_PRECISION, ValueDecimal.DEFAULT_SCALE, ValueDecimal.DEFAULT_DISPLAY_SIZE, true, false), - new String[]{"DECIMAL", "DEC"}, - 17 - ); - add(Value.DECIMAL, Types.NUMERIC, "BigDecimal", - createDecimal(Integer.MAX_VALUE, ValueDecimal.DEFAULT_PRECISION, ValueDecimal.DEFAULT_SCALE, ValueDecimal.DEFAULT_DISPLAY_SIZE, true, false), - new String[]{"NUMERIC", "NUMBER"}, - 17 - ); - add(Value.FLOAT, Types.REAL, "Float", - createDecimal(ValueFloat.PRECISION, ValueFloat.PRECISION, 0, ValueFloat.DISPLAY_SIZE, false, false), - new String[] {"REAL", "FLOAT4"}, - 5 - ); - add(Value.DOUBLE, Types.DOUBLE, "Double", - createDecimal(ValueDouble.PRECISION, ValueDouble.PRECISION, 0, ValueDouble.DISPLAY_SIZE, false, false), - new String[] { "DOUBLE", "DOUBLE PRECISION" }, - 4 - ); - add(Value.DOUBLE, Types.FLOAT, "Double", - createDecimal(ValueDouble.PRECISION, ValueDouble.PRECISION, 0, ValueDouble.DISPLAY_SIZE, false, false), - new String[] {"FLOAT", "FLOAT8" }, - 4 - ); - add(Value.TIME, Types.TIME, "Time", - createDate(ValueTime.PRECISION, "TIME", 0, ValueTime.DISPLAY_SIZE), - new String[]{"TIME"}, - 10 - ); - add(Value.DATE, Types.DATE, "Date", - createDate(ValueDate.PRECISION, "DATE", 0, ValueDate.DISPLAY_SIZE), - new String[]{"DATE"}, - 10 - ); - add(Value.TIMESTAMP, Types.TIMESTAMP, "Timestamp", - createDate(ValueTimestamp.PRECISION, "TIMESTAMP", ValueTimestamp.DEFAULT_SCALE, ValueTimestamp.DISPLAY_SIZE), - new String[]{"TIMESTAMP", "DATETIME", "SMALLDATETIME"}, - 12 - ); - add(Value.BYTES, Types.VARBINARY, "Bytes", - createString(false), - new String[]{"VARBINARY"}, - 8 - ); - add(Value.BYTES, Types.BINARY, "Bytes", - createString(false), - new String[]{"BINARY", "RAW", "BYTEA", "LONG RAW"}, - 8 - ); - add(Value.BYTES, Types.LONGVARBINARY, "Bytes", - createString(false), - new String[]{"LONGVARBINARY"}, - 8 - ); - add(Value.UUID, Types.BINARY, "Bytes", - createString(false), - new String[]{"UUID"}, - 8 - ); - add(Value.JAVA_OBJECT, Types.OTHER, "Object", - createString(false), - new String[]{"OTHER", "OBJECT", "JAVA_OBJECT"}, - 8 - ); - add(Value.BLOB, Types.BLOB, "Blob", - createLob(), - new String[]{"BLOB", "TINYBLOB", "MEDIUMBLOB", "LONGBLOB", "IMAGE", "OID"}, - 10 - ); - add(Value.CLOB, Types.CLOB, "Clob", - createLob(), - new String[]{"CLOB", "TINYTEXT", "TEXT", "MEDIUMTEXT", "LONGTEXT", "NTEXT", "NCLOB"}, - 10 - ); - DataType dataType = new DataType(); - dataType.prefix = "("; - dataType.suffix = "')"; - add(Value.ARRAY, Types.ARRAY, "Array", - dataType, - new String[]{"ARRAY"}, - 10 - ); - dataType = new DataType(); - add(Value.RESULT_SET, 0, "ResultSet", - dataType, - new String[]{"RESULT_SET"}, - 20 - ); - for (int i = 0; i < TYPES_BY_VALUE_TYPE.size(); i++) { - DataType dt = TYPES_BY_VALUE_TYPE.get(i); - if (dt == null) { - DbException.throwInternalError("unmapped type " + i); - } - Value.getOrder(i); - } - } - - private static void add(int type, int sqlType, String jdbc, DataType dataType, String[] names, int memory) { - for (int i = 0; i < names.length; i++) { - DataType dt = new DataType(); - dt.type = type; - dt.sqlType = sqlType; - dt.jdbc = jdbc; - dt.name = names[i]; - dt.autoIncrement = dataType.autoIncrement; - dt.decimal = dataType.decimal; - dt.maxPrecision = dataType.maxPrecision; - dt.maxScale = dataType.maxScale; - dt.minScale = dataType.minScale; - dt.params = dataType.params; - dt.prefix = dataType.prefix; - dt.suffix = dataType.suffix; - dt.supportsPrecision = dataType.supportsPrecision; - dt.supportsScale = dataType.supportsScale; - dt.defaultPrecision = dataType.defaultPrecision; - dt.defaultScale = dataType.defaultScale; - dt.defaultDisplaySize = dataType.defaultDisplaySize; - dt.caseSensitive = dataType.caseSensitive; - dt.hidden = i > 0; - dt.memory = memory; - for (DataType t2 : TYPES) { - if (t2.sqlType == dt.sqlType) { - dt.sqlTypePos++; - } - } - TYPES_BY_NAME.put(dt.name, dt); - if (TYPES_BY_VALUE_TYPE.get(type) == null) { - TYPES_BY_VALUE_TYPE.set(type, dt); - } - TYPES.add(dt); - } - } - - private static DataType createDecimal(int maxPrecision, int defaultPrecision, int defaultScale, int defaultDisplaySize, boolean needsPrecisionAndScale, boolean autoInc) { - DataType dataType = new DataType(); - dataType.maxPrecision = maxPrecision; - dataType.defaultPrecision = defaultPrecision; - dataType.defaultScale = defaultScale; - dataType.defaultDisplaySize = defaultDisplaySize; - if (needsPrecisionAndScale) { - dataType.params = "PRECISION,SCALE"; - dataType.supportsPrecision = true; - dataType.supportsScale = true; - } - dataType.decimal = true; - dataType.autoIncrement = autoInc; - return dataType; - } - - private static DataType createDate(int precision, String prefix, int scale, int displaySize) { - DataType dataType = new DataType(); - dataType.prefix = prefix + " '"; - dataType.suffix = "'"; - dataType.maxPrecision = precision; - dataType.supportsScale = scale != 0; - dataType.maxScale = scale; - dataType.defaultPrecision = precision; - dataType.defaultScale = scale; - dataType.defaultDisplaySize = displaySize; - return dataType; - } - - private static DataType createString(boolean caseSensitive) { - DataType dataType = new DataType(); - dataType.prefix = "'"; - dataType.suffix = "'"; - dataType.params = "LENGTH"; - dataType.caseSensitive = caseSensitive; - dataType.supportsPrecision = true; - dataType.maxPrecision = Integer.MAX_VALUE; - dataType.defaultPrecision = Integer.MAX_VALUE; - dataType.defaultDisplaySize = Integer.MAX_VALUE; - return dataType; - } - - private static DataType createLob() { - DataType t = createString(true); - t.maxPrecision = Long.MAX_VALUE; - t.defaultPrecision = Long.MAX_VALUE; - return t; - } - - /** - * Get the list of data types. - * - * @return the list - */ - public static ArrayList getTypes() { - return TYPES; - } - - /** - * Read a value from the given result set. - * - * @param session the session - * @param rs the result set - * @param columnIndex the column index (1 based) - * @param type the data type - * @return the value - */ - public static Value readValue(SessionInterface session, ResultSet rs, int columnIndex, int type) { - try { - Value v; - switch(type) { - case Value.NULL: { - return ValueNull.INSTANCE; - } - case Value.BYTES: { - byte[] buff = rs.getBytes(columnIndex); - v = buff == null ? (Value) ValueNull.INSTANCE : ValueBytes.getNoCopy(buff); - break; - } - case Value.UUID: { - byte[] buff = rs.getBytes(columnIndex); - v = buff == null ? (Value) ValueNull.INSTANCE : ValueUuid.get(buff); - break; - } - case Value.BOOLEAN: { - boolean value = rs.getBoolean(columnIndex); - v = rs.wasNull() ? (Value) ValueNull.INSTANCE : ValueBoolean.get(value); - break; - } - case Value.BYTE: { - byte value = rs.getByte(columnIndex); - v = rs.wasNull() ? (Value) ValueNull.INSTANCE : ValueByte.get(value); - break; - } - case Value.DATE: { - Date value = rs.getDate(columnIndex); - v = value == null ? (Value) ValueNull.INSTANCE : ValueDate.get(value); - break; - } - case Value.TIME: { - Time value = rs.getTime(columnIndex); - v = value == null ? (Value) ValueNull.INSTANCE : ValueTime.get(value); - break; - } - case Value.TIMESTAMP: { - Timestamp value = rs.getTimestamp(columnIndex); - v = value == null ? (Value) ValueNull.INSTANCE : ValueTimestamp.get(value); - break; - } - case Value.DECIMAL: { - BigDecimal value = rs.getBigDecimal(columnIndex); - v = value == null ? (Value) ValueNull.INSTANCE : ValueDecimal.get(value); - break; - } - case Value.DOUBLE: { - double value = rs.getDouble(columnIndex); - v = rs.wasNull() ? (Value) ValueNull.INSTANCE : ValueDouble.get(value); - break; - } - case Value.FLOAT: { - float value = rs.getFloat(columnIndex); - v = rs.wasNull() ? (Value) ValueNull.INSTANCE : ValueFloat.get(value); - break; - } - case Value.INT: { - int value = rs.getInt(columnIndex); - v = rs.wasNull() ? (Value) ValueNull.INSTANCE : ValueInt.get(value); - break; - } - case Value.LONG: { - long value = rs.getLong(columnIndex); - v = rs.wasNull() ? (Value) ValueNull.INSTANCE : ValueLong.get(value); - break; - } - case Value.SHORT: { - short value = rs.getShort(columnIndex); - v = rs.wasNull() ? (Value) ValueNull.INSTANCE : ValueShort.get(value); - break; - } - case Value.STRING_IGNORECASE: { - String s = rs.getString(columnIndex); - v = (s == null) ? (Value) ValueNull.INSTANCE : ValueStringIgnoreCase.get(s); - break; - } - case Value.STRING_FIXED: { - String s = rs.getString(columnIndex); - v = (s == null) ? (Value) ValueNull.INSTANCE : ValueStringFixed.get(s); - break; - } - case Value.STRING: { - String s = rs.getString(columnIndex); - v = (s == null) ? (Value) ValueNull.INSTANCE : ValueString.get(s); - break; - } - case Value.CLOB: { - if (session == null) { - v = LobStorage.createSmallLob(Value.CLOB, StringUtils.utf8Encode(rs.getString(columnIndex))); - } else { - Reader in = rs.getCharacterStream(columnIndex); - if (in == null) { - v = ValueNull.INSTANCE; - } else { - v = session.getDataHandler().getLobStorage().createClob(new BufferedReader(in), -1); - } - } - break; - } - case Value.BLOB: { - if (session == null) { - v = LobStorage.createSmallLob(Value.BLOB, rs.getBytes(columnIndex)); - } else { - InputStream in = rs.getBinaryStream(columnIndex); - v = (in == null) ? (Value) ValueNull.INSTANCE : session.getDataHandler().getLobStorage().createBlob(in, -1); - } - break; - } - case Value.JAVA_OBJECT: { - byte[] buff = rs.getBytes(columnIndex); - v = buff == null ? (Value) ValueNull.INSTANCE : ValueJavaObject.getNoCopy(buff); - break; - } - case Value.ARRAY: { - Array array = rs.getArray(columnIndex); - if (array == null) { - return ValueNull.INSTANCE; - } - Object[] list = (Object[]) array.getArray(); - if (list == null) { - return ValueNull.INSTANCE; - } - Value[] values = new Value[list.length]; - for (int i = 0; i < list.length; i++) { - values[i] = DataType.convertToValue(session, list[i], Value.NULL); - } - v = ValueArray.get(values); - break; - } - default: - throw DbException.throwInternalError("type="+type); - } - return v; - } catch (SQLException e) { - throw DbException.convert(e); - } - } - - /** - * Get the name of the Java class for the given value type. - * - * @param type the value type - * @return the class name - */ - public static String getTypeClassName(int type) { - switch(type) { - case Value.BOOLEAN: - // "java.lang.Boolean"; - return Boolean.class.getName(); - case Value.BYTE: - // "java.lang.Byte"; - return Byte.class.getName(); - case Value.SHORT: - // "java.lang.Short"; - return Short.class.getName(); - case Value.INT: - // "java.lang.Integer"; - return Integer.class.getName(); - case Value.LONG: - // "java.lang.Long"; - return Long.class.getName(); - case Value.DECIMAL: - // "java.math.BigDecimal"; - return BigDecimal.class.getName(); - case Value.TIME: - // "java.sql.Time"; - return Time.class.getName(); - case Value.DATE: - // "java.sql.Date"; - return Date.class.getName(); - case Value.TIMESTAMP: - // "java.sql.Timestamp"; - return Timestamp.class.getName(); - case Value.BYTES: - case Value.UUID: - // "[B", not "byte[]"; - return byte[].class.getName(); - case Value.STRING: - case Value.STRING_IGNORECASE: - case Value.STRING_FIXED: - // "java.lang.String"; - return String.class.getName(); - case Value.BLOB: - if (SysProperties.RETURN_LOB_OBJECTS) { - // "java.sql.Blob"; - return java.sql.Blob.class.getName(); - } - // "java.io.InputStream"; - return java.io.InputStream.class.getName(); - case Value.CLOB: - if (SysProperties.RETURN_LOB_OBJECTS) { - // "java.sql.Clob"; - return java.sql.Clob.class.getName(); - } - // "java.io.Reader"; - return java.io.Reader.class.getName(); - case Value.DOUBLE: - // "java.lang.Double"; - return Double.class.getName(); - case Value.FLOAT: - // "java.lang.Float"; - return Float.class.getName(); - case Value.NULL: - return null; - case Value.JAVA_OBJECT: - // "java.lang.Object"; - return Object.class.getName(); - case Value.UNKNOWN: - // anything - return Object.class.getName(); - case Value.ARRAY: - return Array.class.getName(); - case Value.RESULT_SET: - return ResultSet.class.getName(); - default: - throw DbException.throwInternalError("type="+type); - } - } - - /** - * Get the data type object for the given value type. - * - * @param type the value type - * @return the data type object - */ - public static DataType getDataType(int type) { - DataType dt = TYPES_BY_VALUE_TYPE.get(type); - if (dt == null) { - dt = TYPES_BY_VALUE_TYPE.get(Value.NULL); - } - return dt; - } - - /** - * Convert a value type to a SQL type. - * - * @param type the value type - * @return the SQL type - */ - public static int convertTypeToSQLType(int type) { - return getDataType(type).sqlType; - } - - /** - * Convert a SQL type to a value type. - * - * @param sqlType the SQL type - * @return the value type - */ - public static int convertSQLTypeToValueType(int sqlType) { - switch(sqlType) { - case Types.CHAR: - case DataType.TYPE_NCHAR: - return Value.STRING_FIXED; - case Types.VARCHAR: - case Types.LONGVARCHAR: - case DataType.TYPE_NVARCHAR: - case DataType.TYPE_LONGNVARCHAR: - return Value.STRING; - case Types.NUMERIC: - case Types.DECIMAL: - return Value.DECIMAL; - case Types.BIT: - case DataType.TYPE_BOOLEAN: - return Value.BOOLEAN; - case Types.INTEGER: - return Value.INT; - case Types.SMALLINT: - return Value.SHORT; - case Types.TINYINT: - return Value.BYTE; - case Types.BIGINT: - return Value.LONG; - case Types.REAL: - return Value.FLOAT; - case Types.DOUBLE: - case Types.FLOAT: - return Value.DOUBLE; - case Types.BINARY: - case Types.VARBINARY: - case Types.LONGVARBINARY: - return Value.BYTES; - case Types.OTHER: - case Types.JAVA_OBJECT: - return Value.JAVA_OBJECT; - case Types.DATE: - return Value.DATE; - case Types.TIME: - return Value.TIME; - case Types.TIMESTAMP: - return Value.TIMESTAMP; - case Types.BLOB: - return Value.BLOB; - case Types.CLOB: - case DataType.TYPE_NCLOB: - return Value.CLOB; - case Types.NULL: - return Value.NULL; - case Types.ARRAY: - return Value.ARRAY; - default: - throw DbException.get(ErrorCode.UNKNOWN_DATA_TYPE_1, "" + sqlType); - } - } - - /** - * Get the value type for the given Java class. - * - * @param x the Java class - * @return the value type - */ - public static int getTypeFromClass(Class < ? > x) { - // TODO refactor: too many if/else in functions, can reduce! - if (x == null) { - return Value.NULL; - } - if (ResultSet.class.isAssignableFrom(x)) { - return Value.RESULT_SET; - } else if (Value.ValueBlob.class.isAssignableFrom(x)) { - return Value.BLOB; - } else if (Value.ValueClob.class.isAssignableFrom(x)) { - return Value.CLOB; - } else if (String.class.isAssignableFrom(x)) { - return Value.STRING; - } else if (BigDecimal.class.isAssignableFrom(x)) { - return Value.DECIMAL; - } else if (Boolean.class.isAssignableFrom(x) || boolean.class.isAssignableFrom(x)) { - return Value.BOOLEAN; - } else if (Byte.class.isAssignableFrom(x) || byte.class.isAssignableFrom(x)) { - return Value.BYTE; - } else if (Short.class.isAssignableFrom(x) || short.class.isAssignableFrom(x)) { - return Value.SHORT; - } else if (Integer.class.isAssignableFrom(x) || int.class.isAssignableFrom(x)) { - return Value.INT; - } else if (Character.class.isAssignableFrom(x) || char.class.isAssignableFrom(x)) { - throw DbException.get(ErrorCode.DATA_CONVERSION_ERROR_1, "char (not supported)"); - } else if (Long.class.isAssignableFrom(x) || long.class.isAssignableFrom(x)) { - return Value.LONG; - } else if (Float.class.isAssignableFrom(x) || float.class.isAssignableFrom(x)) { - return Value.FLOAT; - } else if (Double.class.isAssignableFrom(x) || double.class.isAssignableFrom(x)) { - return Value.DOUBLE; - } else if (byte[].class.isAssignableFrom(x)) { - return Value.BYTES; - } else if (Date.class.isAssignableFrom(x)) { - return Value.DATE; - } else if (Time.class.isAssignableFrom(x)) { - return Value.TIME; - } else if (Timestamp.class.isAssignableFrom(x)) { - return Value.TIMESTAMP; - } else if (java.util.Date.class.isAssignableFrom(x)) { - return Value.TIMESTAMP; - } else if (java.io.Reader.class.isAssignableFrom(x)) { - return Value.CLOB; - } else if (java.sql.Clob.class.isAssignableFrom(x)) { - return Value.CLOB; - } else if (java.io.InputStream.class.isAssignableFrom(x)) { - return Value.BLOB; - } else if (java.sql.Blob.class.isAssignableFrom(x)) { - return Value.BLOB; - } else if (UUID.class.isAssignableFrom(x)) { - return Value.UUID; - } else if (Object[].class.isAssignableFrom(x)) { - return Value.ARRAY; - } else if (Void.TYPE == x) { - return Value.NULL; - } else { - return Value.JAVA_OBJECT; - } - } - - /** - * Convert a Java object to a value. - * - * @param session the session - * @param x the value - * @param type the value type - * @return the value - */ - public static Value convertToValue(SessionInterface session, Object x, int type) { - if (x == null) { - return ValueNull.INSTANCE; - } - if (type == Value.JAVA_OBJECT) { - return ValueJavaObject.getNoCopy(Utils.serialize(x)); - } - if (x instanceof String) { - return ValueString.get((String) x); - } else if (x instanceof Value) { - return (Value) x; - } else if (x instanceof Long) { - return ValueLong.get(((Long) x).longValue()); - } else if (x instanceof Integer) { - return ValueInt.get(((Integer) x).intValue()); - } else if (x instanceof BigDecimal) { - return ValueDecimal.get((BigDecimal) x); - } else if (x instanceof Boolean) { - return ValueBoolean.get(((Boolean) x).booleanValue()); - } else if (x instanceof Byte) { - return ValueByte.get(((Byte) x).byteValue()); - } else if (x instanceof Short) { - return ValueShort.get(((Short) x).shortValue()); - } else if (x instanceof Float) { - return ValueFloat.get(((Float) x).floatValue()); - } else if (x instanceof Double) { - return ValueDouble.get(((Double) x).doubleValue()); - } else if (x instanceof byte[]) { - return ValueBytes.get((byte[]) x); - } else if (x instanceof Date) { - return ValueDate.get((Date) x); - } else if (x instanceof Time) { - return ValueTime.get((Time) x); - } else if (x instanceof Timestamp) { - return ValueTimestamp.get((Timestamp) x); - } else if (x instanceof java.util.Date) { - return ValueTimestamp.get(new Timestamp(((java.util.Date) x).getTime())); - } else if (x instanceof java.io.Reader) { - Reader r = new BufferedReader((java.io.Reader) x); - return session.getDataHandler().getLobStorage().createClob(r, -1); - } else if (x instanceof java.sql.Clob) { - try { - Reader r = new BufferedReader(((java.sql.Clob) x).getCharacterStream()); - return session.getDataHandler().getLobStorage().createClob(r, -1); - } catch (SQLException e) { - throw DbException.convert(e); - } - } else if (x instanceof java.io.InputStream) { - return session.getDataHandler().getLobStorage().createBlob((java.io.InputStream) x, -1); - } else if (x instanceof java.sql.Blob) { - try { - return session.getDataHandler().getLobStorage().createBlob(((java.sql.Blob) x).getBinaryStream(), -1); - } catch (SQLException e) { - throw DbException.convert(e); - } - } else if (x instanceof ResultSet) { - return ValueResultSet.get((ResultSet) x); - } else if (x instanceof UUID) { - UUID u = (UUID) x; - return ValueUuid.get(u.getMostSignificantBits(), u.getLeastSignificantBits()); - } else if (x instanceof Object[]) { - // (a.getClass().isArray()); - // (a.getClass().getComponentType().isPrimitive()); - Object[] o = (Object[]) x; - int len = o.length; - Value[] v = new Value[len]; - for (int i = 0; i < len; i++) { - v[i] = convertToValue(session, o[i], type); - } - return ValueArray.get(v); - } else if (x instanceof Character) { - return ValueStringFixed.get(((Character) x).toString()); - } else { - return ValueJavaObject.getNoCopy(Utils.serialize(x)); - } - } - - /** - * Get a data type object from a type name. - * - * @param s the type name - * @return the data type object - */ - public static DataType getTypeByName(String s) { - return TYPES_BY_NAME.get(s); - } - - /** - * Check if the given value type is a large object (BLOB or CLOB). - * - * @param type the value type - * @return true if the value type is a lob type - */ - public static boolean isLargeObject(int type) { - if (type == Value.BLOB || type == Value.CLOB) { - return true; - } - return false; - } - - /** - * Check if the given value type is a String (VARCHAR,...). - * - * @param type the value type - * @return true if the value type is a String type - */ - public static boolean isStringType(int type) { - if (type == Value.STRING || type == Value.STRING_FIXED || type == Value.STRING_IGNORECASE) { - return true; - } - return false; - } - - /** - * Check if the given value type supports the add operation. - * - * @param type the value type - * @return true if add is supported - */ - public static boolean supportsAdd(int type) { - switch (type) { - case Value.BYTE: - case Value.DECIMAL: - case Value.DOUBLE: - case Value.FLOAT: - case Value.INT: - case Value.LONG: - case Value.SHORT: - return true; - default: - return false; - } - } - - /** - * Get the data type that will not overflow when calling 'add' 2 billion times. - * - * @param type the value type - * @return the data type that supports adding - */ - public static int getAddProofType(int type) { - switch (type) { - case Value.BYTE: - return Value.LONG; - case Value.FLOAT: - return Value.DOUBLE; - case Value.INT: - return Value.LONG; - case Value.LONG: - return Value.DECIMAL; - case Value.SHORT: - return Value.LONG; - default: - return type; - } - } - - /** - * Get the default value in the form of a Java object for the given Java class. - * - * @param clazz the Java class - * @return the default object - */ - public static Object getDefaultForPrimitiveType(Class< ? > clazz) { - if (clazz == Boolean.TYPE) { - return Boolean.FALSE; - } else if (clazz == Byte.TYPE) { - return Byte.valueOf((byte) 0); - } else if (clazz == Character.TYPE) { - return Character.valueOf((char) 0); - } else if (clazz == Short.TYPE) { - return Short.valueOf((short) 0); - } else if (clazz == Integer.TYPE) { - return Integer.valueOf(0); - } else if (clazz == Long.TYPE) { - return Long.valueOf(0); - } else if (clazz == Float.TYPE) { - return Float.valueOf(0); - } else if (clazz == Double.TYPE) { - return Double.valueOf(0); - } - throw DbException.throwInternalError("primitive=" + clazz.toString()); - } - - /** - * Convert a value to the specified class. - * - * @param session the session - * @param conn the database connection - * @param v the value - * @param paramClass the target class - * @return the converted object - */ - public static Object convertTo(SessionInterface session, JdbcConnection conn, Value v, Class< ? > paramClass) { - if (paramClass == Blob.class) { - return new JdbcBlob(conn, v, 0); - } else if (paramClass == Clob.class) { - return new JdbcClob(conn, v, 0); - } - throw DbException.getUnsupportedException(paramClass.getName()); - } - -} diff --git a/tools/h2/src/main/org/h2/value/Transfer.java b/tools/h2/src/main/org/h2/value/Transfer.java deleted file mode 100755 index 445446d..0000000 --- a/tools/h2/src/main/org/h2/value/Transfer.java +++ /dev/null @@ -1,575 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.value; - -import java.io.BufferedInputStream; -import java.io.BufferedOutputStream; -import java.io.BufferedWriter; -import java.io.DataInputStream; -import java.io.DataOutputStream; -import java.io.IOException; -import java.io.OutputStreamWriter; -import java.io.Reader; -import java.io.Writer; -import java.math.BigDecimal; -import java.net.InetAddress; -import java.net.Socket; -import java.sql.Date; -import java.sql.ResultSet; -import java.sql.ResultSetMetaData; -import java.sql.SQLException; -import java.sql.Time; -import java.sql.Timestamp; -import org.h2.constant.ErrorCode; -import org.h2.engine.Constants; -import org.h2.engine.SessionInterface; -import org.h2.message.DbException; -import org.h2.message.TraceSystem; -import org.h2.tools.SimpleResultSet; -import org.h2.util.ExactUTF8InputStreamReader; -import org.h2.util.IOUtils; -import org.h2.util.NetUtils; -import org.h2.util.StringUtils; -import org.h2.util.Utils; - -/** - * The transfer class is used to send and receive Value objects. - * It is used on both the client side, and on the server side. - */ -public class Transfer { - - private static final int BUFFER_SIZE = 16 * 1024; - private static final int LOB_MAGIC = 0x1234; - - private Socket socket; - private DataInputStream in; - private DataOutputStream out; - private SessionInterface session; - private boolean ssl; - - /** - * Create a new transfer object for the specified session. - * - * @param session the session - */ - public Transfer(SessionInterface session) { - this.session = session; - } - - /** - * Set the socket this object uses. - * - * @param s the socket - */ - public void setSocket(Socket s) { - socket = s; - } - - /** - * Initialize the transfer object. This method will try to open an input and - * output stream. - */ - public void init() throws IOException { - in = new DataInputStream(new BufferedInputStream(socket.getInputStream(), Transfer.BUFFER_SIZE)); - out = new DataOutputStream(new BufferedOutputStream(socket.getOutputStream(), Transfer.BUFFER_SIZE)); - } - - /** - * Write pending changes. - */ - public void flush() throws IOException { - out.flush(); - } - - /** - * Write a boolean. - * - * @param x the value - * @return itself - */ - public Transfer writeBoolean(boolean x) throws IOException { - out.writeByte((byte) (x ? 1 : 0)); - return this; - } - - /** - * Read a boolean. - * - * @return the value - */ - public boolean readBoolean() throws IOException { - return in.readByte() == 1; - } - - /** - * Write a byte. - * - * @param x the value - * @return itself - */ - private Transfer writeByte(byte x) throws IOException { - out.writeByte(x); - return this; - } - - /** - * Read a byte. - * - * @return the value - */ - private byte readByte() throws IOException { - return in.readByte(); - } - - /** - * Write an int. - * - * @param x the value - * @return itself - */ - public Transfer writeInt(int x) throws IOException { - out.writeInt(x); - return this; - } - - /** - * Read an int. - * - * @return the value - */ - public int readInt() throws IOException { - return in.readInt(); - } - - /** - * Write a long. - * - * @param x the value - * @return itself - */ - public Transfer writeLong(long x) throws IOException { - out.writeLong(x); - return this; - } - - /** - * Read a long. - * - * @return the value - */ - public long readLong() throws IOException { - return in.readLong(); - } - - /** - * Write a double. - * - * @param x the value - * @return itself - */ - private Transfer writeDouble(double i) throws IOException { - out.writeDouble(i); - return this; - } - - /** - * Write a float. - * - * @param x the value - * @return itself - */ - private Transfer writeFloat(float i) throws IOException { - out.writeFloat(i); - return this; - } - - /** - * Read a double. - * - * @return the value - */ - private double readDouble() throws IOException { - return in.readDouble(); - } - - /** - * Read a float. - * - * @return the value - */ - private float readFloat() throws IOException { - return in.readFloat(); - } - - /** - * Write a string. The maximum string length is Integer.MAX_VALUE. - * - * @param s the value - * @return itself - */ - public Transfer writeString(String s) throws IOException { - if (s == null) { - out.writeInt(-1); - } else { - int len = s.length(); - out.writeInt(len); - for (int i = 0; i < len; i++) { - out.writeChar(s.charAt(i)); - } - } - return this; - } - - /** - * Read a string. - * - * @return the value - */ - public String readString() throws IOException { - int len = in.readInt(); - if (len == -1) { - return null; - } - // TODO optimize: StringBuilder is synchronized, maybe use a char array - // (but that means more memory) - StringBuilder buff = new StringBuilder(len); - for (int i = 0; i < len; i++) { - buff.append(in.readChar()); - } - String s = buff.toString(); - s = StringUtils.cache(s); - return s; - } - - /** - * Write a byte array. - * - * @param data the value - * @return itself - */ - public Transfer writeBytes(byte[] data) throws IOException { - if (data == null) { - writeInt(-1); - } else { - writeInt(data.length); - out.write(data); - } - return this; - } - - /** - * Read a byte array. - * - * @return the value - */ - public byte[] readBytes() throws IOException { - int len = readInt(); - if (len == -1) { - return null; - } - byte[] b = Utils.newBytes(len); - in.readFully(b); - return b; - } - - /** - * Close the transfer object and the socket. - */ - public void close() { - if (socket != null) { - try { - out.flush(); - if (socket != null) { - socket.close(); - } - } catch (IOException e) { - TraceSystem.traceThrowable(e); - } finally { - socket = null; - } - } - } - - /** - * Write a value. - * - * @param v the value - */ - public void writeValue(Value v) throws IOException { - int type = v.getType(); - writeInt(type); - switch (type) { - case Value.NULL: - break; - case Value.BYTES: - case Value.JAVA_OBJECT: - writeBytes(v.getBytesNoCopy()); - break; - case Value.UUID: { - ValueUuid uuid = (ValueUuid) v; - writeLong(uuid.getHigh()); - writeLong(uuid.getLow()); - break; - } - case Value.BOOLEAN: - writeBoolean(v.getBoolean().booleanValue()); - break; - case Value.BYTE: - writeByte(v.getByte()); - break; - case Value.TIME: - writeLong(v.getTimeNoCopy().getTime()); - break; - case Value.DATE: - writeLong(v.getDateNoCopy().getTime()); - break; - case Value.TIMESTAMP: { - Timestamp ts = v.getTimestampNoCopy(); - writeLong(ts.getTime()); - writeInt(ts.getNanos()); - break; - } - case Value.DECIMAL: - writeString(v.getString()); - break; - case Value.DOUBLE: - writeDouble(v.getDouble()); - break; - case Value.FLOAT: - writeFloat(v.getFloat()); - break; - case Value.INT: - writeInt(v.getInt()); - break; - case Value.LONG: - writeLong(v.getLong()); - break; - case Value.SHORT: - writeInt(v.getShort()); - break; - case Value.STRING: - case Value.STRING_IGNORECASE: - case Value.STRING_FIXED: - writeString(v.getString()); - break; - case Value.BLOB: { - long length = v.getPrecision(); - if (length < 0) { - throw DbException.get(ErrorCode.CONNECTION_BROKEN_1, "length=" + length); - } - writeLong(length); - long written = IOUtils.copyAndCloseInput(v.getInputStream(), out); - if (written != length) { - throw DbException.get(ErrorCode.CONNECTION_BROKEN_1, "length:" + length + " written:" + written); - } - writeInt(LOB_MAGIC); - break; - } - case Value.CLOB: { - long length = v.getPrecision(); - if (length < 0) { - throw DbException.get(ErrorCode.CONNECTION_BROKEN_1, "length=" + length); - } - writeLong(length); - Reader reader = v.getReader(); - // below, writer.flush needs to be called to ensure the buffer is written - // but, this will also flush the output stream, and this slows things down - // so construct an output stream that will ignore this chained flush call - java.io.OutputStream out2 = new java.io.FilterOutputStream(out) { - public void flush() { - // do nothing - } - }; - Writer writer = new BufferedWriter(new OutputStreamWriter(out2, Constants.UTF8)); - long written = IOUtils.copyAndCloseInput(reader, writer); - if (written != length) { - throw DbException.get(ErrorCode.CONNECTION_BROKEN_1, "length:" + length + " written:" + written); - } - writer.flush(); - writeInt(LOB_MAGIC); - break; - } - case Value.ARRAY: { - Value[] list = ((ValueArray) v).getList(); - writeInt(list.length); - for (Value value : list) { - writeValue(value); - } - break; - } - case Value.RESULT_SET: { - try { - ResultSet rs = ((ValueResultSet) v).getResultSet(); - rs.beforeFirst(); - ResultSetMetaData meta = rs.getMetaData(); - int columnCount = meta.getColumnCount(); - writeInt(columnCount); - for (int i = 0; i < columnCount; i++) { - writeString(meta.getColumnName(i + 1)); - writeInt(meta.getColumnType(i + 1)); - writeInt(meta.getPrecision(i + 1)); - writeInt(meta.getScale(i + 1)); - } - while (rs.next()) { - writeBoolean(true); - for (int i = 0; i < columnCount; i++) { - int t = DataType.convertSQLTypeToValueType(meta.getColumnType(i + 1)); - Value val = DataType.readValue(session, rs, i + 1, t); - writeValue(val); - } - } - writeBoolean(false); - rs.beforeFirst(); - } catch (SQLException e) { - throw DbException.convertToIOException(e); - } - break; - } - default: - throw DbException.get(ErrorCode.CONNECTION_BROKEN_1, "type=" + type); - } - } - - /** - * Read a value. - * - * @return the value - */ - public Value readValue() throws IOException { - int type = readInt(); - switch(type) { - case Value.NULL: - return ValueNull.INSTANCE; - case Value.BYTES: - return ValueBytes.getNoCopy(readBytes()); - case Value.UUID: - return ValueUuid.get(readLong(), readLong()); - case Value.JAVA_OBJECT: - return ValueJavaObject.getNoCopy(readBytes()); - case Value.BOOLEAN: - return ValueBoolean.get(readBoolean()); - case Value.BYTE: - return ValueByte.get(readByte()); - case Value.DATE: - return ValueDate.getNoCopy(new Date(readLong())); - case Value.TIME: - return ValueTime.getNoCopy(new Time(readLong())); - case Value.TIMESTAMP: { - Timestamp ts = new Timestamp(readLong()); - ts.setNanos(readInt()); - return ValueTimestamp.getNoCopy(ts); - } - case Value.DECIMAL: - return ValueDecimal.get(new BigDecimal(readString())); - case Value.DOUBLE: - return ValueDouble.get(readDouble()); - case Value.FLOAT: - return ValueFloat.get(readFloat()); - case Value.INT: - return ValueInt.get(readInt()); - case Value.LONG: - return ValueLong.get(readLong()); - case Value.SHORT: - return ValueShort.get((short) readInt()); - case Value.STRING: - return ValueString.get(readString()); - case Value.STRING_IGNORECASE: - return ValueStringIgnoreCase.get(readString()); - case Value.STRING_FIXED: - return ValueStringFixed.get(readString()); - case Value.BLOB: { - long length = readLong(); - Value v = session.getDataHandler().getLobStorage().createBlob(in, length); - int magic = readInt(); - if (magic != LOB_MAGIC) { - throw DbException.get(ErrorCode.CONNECTION_BROKEN_1, "magic=" + magic); - } - return v; - } - case Value.CLOB: { - long length = readLong(); - Value v = session.getDataHandler().getLobStorage().createClob(new ExactUTF8InputStreamReader(in), length); - int magic = readInt(); - if (magic != LOB_MAGIC) { - throw DbException.get(ErrorCode.CONNECTION_BROKEN_1, "magic=" + magic); - } - return v; - } - case Value.ARRAY: { - int len = readInt(); - Value[] list = new Value[len]; - for (int i = 0; i < len; i++) { - list[i] = readValue(); - } - return ValueArray.get(list); - } - case Value.RESULT_SET: { - SimpleResultSet rs = new SimpleResultSet(); - int columns = readInt(); - for (int i = 0; i < columns; i++) { - rs.addColumn(readString(), readInt(), readInt(), readInt()); - } - while (true) { - if (!readBoolean()) { - break; - } - Object[] o = new Object[columns]; - for (int i = 0; i < columns; i++) { - o[i] = readValue().getObject(); - } - rs.addRow(o); - } - return ValueResultSet.get(rs); - } - default: - throw DbException.get(ErrorCode.CONNECTION_BROKEN_1, "type=" + type); - } - } - - /** - * Get the socket. - * - * @return the socket - */ - public Socket getSocket() { - return socket; - } - - /** - * Set the session. - * - * @param session the session - */ - public void setSession(SessionInterface session) { - this.session = session; - } - - /** - * Enable or disable SSL. - * - * @param ssl the new value - */ - public void setSSL(boolean ssl) { - this.ssl = ssl; - } - - /** - * Open a new new connection to the same address and port as this one. - * - * @return the new transfer object - */ - public Transfer openNewConnection() throws IOException { - InetAddress address = socket.getInetAddress(); - int port = socket.getPort(); - Socket s2 = NetUtils.createSocket(address, port, ssl); - Transfer trans = new Transfer(null); - trans.setSocket(s2); - trans.setSSL(ssl); - return trans; - } - -} diff --git a/tools/h2/src/main/org/h2/value/Value.java b/tools/h2/src/main/org/h2/value/Value.java deleted file mode 100755 index 23ed318..0000000 --- a/tools/h2/src/main/org/h2/value/Value.java +++ /dev/null @@ -1,1024 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.value; - -import java.io.ByteArrayInputStream; -import java.io.InputStream; -import java.io.Reader; -import java.lang.ref.SoftReference; -import java.math.BigDecimal; -import java.sql.Date; -import java.sql.PreparedStatement; -import java.sql.SQLException; -import java.sql.Time; -import java.sql.Timestamp; -import java.sql.Types; -import org.h2.constant.ErrorCode; -import org.h2.constant.SysProperties; -import org.h2.message.DbException; -import org.h2.store.DataHandler; -import org.h2.store.LobStorage; -import org.h2.tools.SimpleResultSet; -import org.h2.util.IOUtils; -import org.h2.util.StringUtils; -import org.h2.util.Utils; - -/** - * This is the base class for all value classes. - * It provides conversion and comparison methods. - */ -public abstract class Value { - - /** - * The data type is unknown at this time. - */ - public static final int UNKNOWN = -1; - - /** - * The value type for NULL. - */ - public static final int NULL = 0; - - /** - * The value type for BOOLEAN values. - */ - public static final int BOOLEAN = 1; - - /** - * The value type for BYTE values. - */ - public static final int BYTE = 2; - - /** - * The value type for SHORT values. - */ - public static final int SHORT = 3; - - /** - * The value type for INT values. - */ - public static final int INT = 4; - - /** - * The value type for LONG values. - */ - public static final int LONG = 5; - - /** - * The value type for DECIMAL values. - */ - public static final int DECIMAL = 6; - - /** - * The value type for DOUBLE values. - */ - public static final int DOUBLE = 7; - - /** - * The value type for FLOAT values. - */ - public static final int FLOAT = 8; - - /** - * The value type for INT values. - */ - public static final int TIME = 9; - - /** - * The value type for DATE values. - */ - public static final int DATE = 10; - - /** - * The value type for TIMESTAMP values. - */ - public static final int TIMESTAMP = 11; - - /** - * The value type for BYTES values. - */ - public static final int BYTES = 12; - - /** - * The value type for STRING values. - */ - public static final int STRING = 13; - - /** - * The value type for case insensitive STRING values. - */ - public static final int STRING_IGNORECASE = 14; - - /** - * The value type for BLOB values. - */ - public static final int BLOB = 15; - - /** - * The value type for CLOB values. - */ - public static final int CLOB = 16; - - /** - * The value type for ARRAY values. - */ - public static final int ARRAY = 17; - - /** - * The value type for RESULT_SET values. - */ - public static final int RESULT_SET = 18; - /** - * The value type for JAVA_OBJECT values. - */ - public static final int JAVA_OBJECT = 19; - - /** - * The value type for UUID values. - */ - public static final int UUID = 20; - - /** - * The value type for string values with a fixed size. - */ - public static final int STRING_FIXED = 21; - - /** - * The number of value types. - */ - public static final int TYPE_COUNT = STRING_FIXED + 1; - - private static SoftReference softCache = new SoftReference(null); - private static final BigDecimal MAX_LONG_DECIMAL = BigDecimal.valueOf(Long.MAX_VALUE); - private static final BigDecimal MIN_LONG_DECIMAL = BigDecimal.valueOf(Long.MIN_VALUE); - - /** - * Get the SQL expression for this value. - * - * @return the SQL expression - */ - public abstract String getSQL(); - - /** - * Get the value type. - * - * @return the type - */ - public abstract int getType(); - - /** - * Get the precision. - * - * @return the precision - */ - public abstract long getPrecision(); - - /** - * Get the display size in characters. - * - * @return the display size - */ - public abstract int getDisplaySize(); - - /** - * Get the memory used by this object. - * - * @return the memory used in bytes - */ - public int getMemory() { - return DataType.getDataType(getType()).memory * 4; - } - - /** - * Get the value as a string. - * - * @return the string - */ - public abstract String getString(); - - /** - * Get the value as an object. - * - * @return the object - */ - public abstract Object getObject(); - - /** - * Set the value as a parameter in a prepared statement. - * - * @param prep the prepared statement - * @param parameterIndex the parameter index - */ - public abstract void set(PreparedStatement prep, int parameterIndex) throws SQLException; - - /** - * Compare the value with another value of the same type. - * - * @param v the other value - * @param mode the compare mode - * @return 0 if both values are equal, -1 if the other value is smaller, and - * 1 otherwise - */ - protected abstract int compareSecure(Value v, CompareMode mode); - - public abstract int hashCode(); - - /** - * Check if the two values have the same hash code. No data conversion is - * made; this method returns false if the other object is not of the same - * class. For some values, compareTo may return 0 even if equals return - * false. Example: ValueDecimal 0.0 and 0.00. - * - * @param other the other value - * @return true if they are equal - */ - public abstract boolean equals(Object other); - - /** - * Get the order of this value type. - * - * @param type the value type - * @return the order number - */ - static int getOrder(int type) { - switch(type) { - case UNKNOWN: - return 1; - case NULL: - return 2; - case STRING: - return 10; - case CLOB: - return 11; - case STRING_FIXED: - return 12; - case STRING_IGNORECASE: - return 13; - case BOOLEAN: - return 20; - case BYTE: - return 21; - case SHORT: - return 22; - case INT: - return 23; - case LONG: - return 24; - case DECIMAL: - return 25; - case FLOAT: - return 26; - case DOUBLE: - return 27; - case TIME: - return 30; - case DATE: - return 31; - case TIMESTAMP: - return 32; - case BYTES: - return 40; - case BLOB: - return 41; - case UUID: - return 42; - case JAVA_OBJECT: - return 43; - case ARRAY: - return 50; - case RESULT_SET: - return 51; - default: - throw DbException.throwInternalError("type:"+type); - } - } - - /** - * Get the higher value order type of two value types. If values need to be - * converted to match the other operands value type, the value with the - * lower order is converted to the value with the higher order. - * - * @param t1 the first value type - * @param t2 the second value type - * @return the higher value type of the two - */ - public static int getHigherOrder(int t1, int t2) { - if (t1 == t2) { - if (t1 == Value.UNKNOWN) { - throw DbException.get(ErrorCode.UNKNOWN_DATA_TYPE_1, "?, ?"); - } - return t1; - } - int o1 = getOrder(t1); - int o2 = getOrder(t2); - return o1 > o2 ? t1 : t2; - } - - /** - * Check if a value is in the cache that is equal to this value. If yes, - * this value should be used to save memory. If the value is not in the - * cache yet, it is added. - * - * @param v the value to look for - * @return the value in the cache or the value passed - */ - static Value cache(Value v) { - if (SysProperties.OBJECT_CACHE) { - int hash = v.hashCode(); - if (softCache == null) { - softCache = new SoftReference(null); - } - Value[] cache = softCache.get(); - if (cache == null) { - cache = new Value[SysProperties.OBJECT_CACHE_SIZE]; - softCache = new SoftReference(cache); - } - int index = hash & (SysProperties.OBJECT_CACHE_SIZE - 1); - Value cached = cache[index]; - if (cached != null) { - if (cached.getType() == v.getType() && v.equals(cached)) { - // cacheHit++; - return cached; - } - } - // cacheMiss++; - // cache[cacheCleaner] = null; - // cacheCleaner = (cacheCleaner + 1) & (Constants.OBJECT_CACHE_SIZE - 1); - cache[index] = v; - } - return v; - } - - public Boolean getBoolean() { - return ((ValueBoolean) convertTo(Value.BOOLEAN)).getBoolean(); - } - - public Date getDate() { - return ((ValueDate) convertTo(Value.DATE)).getDate(); - } - - public Date getDateNoCopy() { - return ((ValueDate) convertTo(Value.DATE)).getDateNoCopy(); - } - - public Time getTime() { - return ((ValueTime) convertTo(Value.TIME)).getTime(); - } - - public Time getTimeNoCopy() { - return ((ValueTime) convertTo(Value.TIME)).getTimeNoCopy(); - } - - public Timestamp getTimestamp() { - return ((ValueTimestamp) convertTo(Value.TIMESTAMP)).getTimestamp(); - } - - public Timestamp getTimestampNoCopy() { - return ((ValueTimestamp) convertTo(Value.TIMESTAMP)).getTimestampNoCopy(); - } - - public byte[] getBytes() { - return ((ValueBytes) convertTo(Value.BYTES)).getBytes(); - } - - public byte[] getBytesNoCopy() { - return ((ValueBytes) convertTo(Value.BYTES)).getBytesNoCopy(); - } - - public byte getByte() { - return ((ValueByte) convertTo(Value.BYTE)).getByte(); - } - - public short getShort() { - return ((ValueShort) convertTo(Value.SHORT)).getShort(); - } - - public BigDecimal getBigDecimal() { - return ((ValueDecimal) convertTo(Value.DECIMAL)).getBigDecimal(); - } - - public double getDouble() { - return ((ValueDouble) convertTo(Value.DOUBLE)).getDouble(); - } - - public float getFloat() { - return ((ValueFloat) convertTo(Value.FLOAT)).getFloat(); - } - - public int getInt() { - return ((ValueInt) convertTo(Value.INT)).getInt(); - } - - public long getLong() { - return ((ValueLong) convertTo(Value.LONG)).getLong(); - } - - public InputStream getInputStream() { - return new ByteArrayInputStream(getBytesNoCopy()); - } - - public Reader getReader() { - return IOUtils.getReader(getString()); - } - - /** - * Add a value and return the result. - * - * @param v the value to add - * @return the result - */ - public Value add(Value v) { - throw throwUnsupportedExceptionForType("+"); - } - - public int getSignum() { - throw throwUnsupportedExceptionForType("SIGNUM"); - } - - /** - * Return -value if this value support arithmetic operations. - * - * @return the negative - */ - public Value negate() { - throw throwUnsupportedExceptionForType("NEG"); - } - - /** - * Subtract a value and return the result. - * - * @param v the value to subtract - * @return the result - */ - public Value subtract(Value v) { - throw throwUnsupportedExceptionForType("-"); - } - - /** - * Divide by a value and return the result. - * - * @param v the value to divide by - * @return the result - */ - public Value divide(Value v) { - throw throwUnsupportedExceptionForType("/"); - } - - /** - * Multiply with a value and return the result. - * - * @param v the value to multiply with - * @return the result - */ - public Value multiply(Value v) { - throw throwUnsupportedExceptionForType("*"); - } - - /** - * Compare a value to the specified type. - * - * @param type the value type - * @return the value - */ - public Value convertTo(int type) { - // converting NULL done in ValueNull - // converting BLOB to CLOB and vice versa is done in ValueLob - if (getType() == type) { - return this; - } - // decimal conversion - switch (type) { - case BOOLEAN: { - switch (getType()) { - case BYTE: - case SHORT: - case INT: - case LONG: - case DECIMAL: - case DOUBLE: - case FLOAT: - return ValueBoolean.get(getSignum() != 0); - case TIME: - case DATE: - case TIMESTAMP: - case BYTES: - case JAVA_OBJECT: - case UUID: - throw DbException.get(ErrorCode.DATA_CONVERSION_ERROR_1, getString()); - } - break; - } - case BYTE: { - switch (getType()) { - case BOOLEAN: - return ValueByte.get(getBoolean().booleanValue() ? (byte) 1 : (byte) 0); - case SHORT: - return ValueByte.get(convertToByte(getShort())); - case INT: - return ValueByte.get(convertToByte(getInt())); - case LONG: - return ValueByte.get(convertToByte(getLong())); - case DECIMAL: - return ValueByte.get(convertToByte(convertToLong(getBigDecimal()))); - case DOUBLE: - return ValueByte.get(convertToByte(convertToLong(getDouble()))); - case FLOAT: - return ValueByte.get(convertToByte(convertToLong(getFloat()))); - } - break; - } - case SHORT: { - switch (getType()) { - case BOOLEAN: - return ValueShort.get(getBoolean().booleanValue() ? (short) 1 : (short) 0); - case BYTE: - return ValueShort.get(getByte()); - case INT: - return ValueShort.get(convertToShort(getInt())); - case LONG: - return ValueShort.get(convertToShort(getLong())); - case DECIMAL: - return ValueShort.get(convertToShort(convertToLong(getBigDecimal()))); - case DOUBLE: - return ValueShort.get(convertToShort(convertToLong(getDouble()))); - case FLOAT: - return ValueShort.get(convertToShort(convertToLong(getFloat()))); - } - break; - } - case INT: { - switch (getType()) { - case BOOLEAN: - return ValueInt.get(getBoolean().booleanValue() ? 1 : 0); - case BYTE: - return ValueInt.get(getByte()); - case SHORT: - return ValueInt.get(getShort()); - case LONG: - return ValueInt.get(convertToInt(getLong())); - case DECIMAL: - return ValueInt.get(convertToInt(convertToLong(getBigDecimal()))); - case DOUBLE: - return ValueInt.get(convertToInt(convertToLong(getDouble()))); - case FLOAT: - return ValueInt.get(convertToInt(convertToLong(getFloat()))); - } - break; - } - case LONG: { - switch (getType()) { - case BOOLEAN: - return ValueLong.get(getBoolean().booleanValue() ? 1 : 0); - case BYTE: - return ValueLong.get(getByte()); - case SHORT: - return ValueLong.get(getShort()); - case INT: - return ValueLong.get(getInt()); - case DECIMAL: - return ValueLong.get(convertToLong(getBigDecimal())); - case DOUBLE: - return ValueLong.get(convertToLong(getDouble())); - case FLOAT: - return ValueLong.get(convertToLong(getFloat())); - } - break; - } - case DECIMAL: { - // convert to string is required for JDK 1.4 - switch (getType()) { - case BOOLEAN: - return ValueDecimal.get(BigDecimal.valueOf(getBoolean().booleanValue() ? 1 : 0)); - case BYTE: - return ValueDecimal.get(BigDecimal.valueOf(getByte())); - case SHORT: - return ValueDecimal.get(BigDecimal.valueOf(getShort())); - case INT: - return ValueDecimal.get(BigDecimal.valueOf(getInt())); - case LONG: - return ValueDecimal.get(BigDecimal.valueOf(getLong())); - case DOUBLE: { - double d = getDouble(); - if (Double.isInfinite(d) || Double.isNaN(d)) { - throw DbException.get(ErrorCode.DATA_CONVERSION_ERROR_1, "" + d); - } - return ValueDecimal.get(BigDecimal.valueOf(d)); - } - case FLOAT: { - float f = getFloat(); - if (Float.isInfinite(f) || Float.isNaN(f)) { - throw DbException.get(ErrorCode.DATA_CONVERSION_ERROR_1, "" + f); - } - return ValueDecimal.get(new BigDecimal(Float.toString(f))); - } - } - break; - } - case DOUBLE: { - switch (getType()) { - case BOOLEAN: - return ValueDouble.get(getBoolean().booleanValue() ? 1 : 0); - case BYTE: - return ValueDouble.get(getByte()); - case SHORT: - return ValueDouble.get(getShort()); - case INT: - return ValueDouble.get(getInt()); - case LONG: - return ValueDouble.get(getLong()); - case DECIMAL: - return ValueDouble.get(getBigDecimal().doubleValue()); - case FLOAT: - return ValueDouble.get(getFloat()); - } - break; - } - case FLOAT: { - switch (getType()) { - case BOOLEAN: - return ValueFloat.get(getBoolean().booleanValue() ? 1 : 0); - case BYTE: - return ValueFloat.get(getByte()); - case SHORT: - return ValueFloat.get(getShort()); - case INT: - return ValueFloat.get(getInt()); - case LONG: - return ValueFloat.get(getLong()); - case DECIMAL: - return ValueFloat.get(getBigDecimal().floatValue()); - case DOUBLE: - return ValueFloat.get((float) getDouble()); - } - break; - } - case DATE: { - switch (getType()) { - case TIME: - return ValueDate.get(new Date(getTimeNoCopy().getTime())); - case TIMESTAMP: - return ValueDate.get(new Date(getTimestampNoCopy().getTime())); - } - break; - } - case TIME: { - switch (getType()) { - case DATE: - // need to normalize the year, month and day - return ValueTime.get(new Time(getDateNoCopy().getTime())); - case TIMESTAMP: - // need to normalize the year, month and day - return ValueTime.get(new Time(getTimestampNoCopy().getTime())); - } - break; - } - case TIMESTAMP: { - switch (getType()) { - case TIME: - return ValueTimestamp.getNoCopy(new Timestamp(getTimeNoCopy().getTime())); - case DATE: - return ValueTimestamp.getNoCopy(new Timestamp(getDateNoCopy().getTime())); - } - break; - } - case BYTES: { - switch(getType()) { - case JAVA_OBJECT: - case BLOB: - return ValueBytes.getNoCopy(getBytesNoCopy()); - case UUID: - return ValueBytes.getNoCopy(getBytes()); - } - break; - } - case JAVA_OBJECT: { - switch(getType()) { - case BYTES: - case BLOB: - return ValueJavaObject.getNoCopy(getBytesNoCopy()); - } - break; - } - case BLOB: { - switch(getType()) { - case BYTES: - - return LobStorage.createSmallLob(Value.BLOB, getBytesNoCopy()); - } - break; - } - case UUID: { - switch(getType()) { - case BYTES: - return ValueUuid.get(getBytesNoCopy()); - } - } - } - // conversion by parsing the string value - String s = getString(); - try { - switch (type) { - case NULL: - return ValueNull.INSTANCE; - case BOOLEAN: { - if (s.equalsIgnoreCase("true") || s.equalsIgnoreCase("t") || s.equalsIgnoreCase("yes") || s.equalsIgnoreCase("y")) { - return ValueBoolean.get(true); - } else if (s.equalsIgnoreCase("false") || s.equalsIgnoreCase("f") || s.equalsIgnoreCase("no") || s.equalsIgnoreCase("n")) { - return ValueBoolean.get(false); - } else { - // convert to a number, and if it is not 0 then it is true - return ValueBoolean.get(new BigDecimal(s).signum() != 0); - } - } - case BYTE: - return ValueByte.get(Byte.decode(s.trim())); - case SHORT: - return ValueShort.get(Short.decode(s.trim())); - case INT: - return ValueInt.get(Integer.decode(s.trim())); - case LONG: - return ValueLong.get(Long.decode(s.trim())); - case DECIMAL: - return ValueDecimal.get(new BigDecimal(s.trim())); - case TIME: - return ValueTime.getNoCopy(ValueTime.parseTime(s.trim())); - case DATE: - return ValueDate.getNoCopy(ValueDate.parseDate(s.trim())); - case TIMESTAMP: - return ValueTimestamp.getNoCopy(ValueTimestamp.parseTimestamp(s.trim())); - case BYTES: - return ValueBytes.getNoCopy(Utils.convertStringToBytes(s.trim())); - case JAVA_OBJECT: - return ValueJavaObject.getNoCopy(Utils.convertStringToBytes(s.trim())); - case STRING: - return ValueString.get(s); - case STRING_IGNORECASE: - return ValueStringIgnoreCase.get(s); - case STRING_FIXED: - return ValueStringFixed.get(s); - case DOUBLE: - return ValueDouble.get(Double.parseDouble(s.trim())); - case FLOAT: - return ValueFloat.get(Float.parseFloat(s.trim())); - case CLOB: - return LobStorage.createSmallLob(CLOB, StringUtils.utf8Encode(s)); - case BLOB: - return LobStorage.createSmallLob(BLOB, Utils.convertStringToBytes(s.trim())); - case ARRAY: - return ValueArray.get(new Value[]{ValueString.get(s)}); - case RESULT_SET: { - SimpleResultSet rs = new SimpleResultSet(); - rs.addColumn("X", Types.VARCHAR, s.length(), 0); - rs.addRow(s); - return ValueResultSet.get(rs); - } - case UUID: - return ValueUuid.get(s); - default: - throw DbException.throwInternalError("type=" + type); - } - } catch (NumberFormatException e) { - throw DbException.get(ErrorCode.DATA_CONVERSION_ERROR_1, e, s); - } - } - - /** - * Compare this value against another value given that the values are of the - * same data type. - * - * @param v the other value - * @param mode the compare mode - * @return 0 if both values are equal, -1 if the other value is smaller, and - * 1 otherwise - */ - public final int compareTypeSave(Value v, CompareMode mode) { - if (this == ValueNull.INSTANCE) { - return v == ValueNull.INSTANCE ? 0 : -1; - } else if (v == ValueNull.INSTANCE) { - return 1; - } - return compareSecure(v, mode); - } - - /** - * Compare this value against another value using the specified compare - * mode. - * - * @param v the other value - * @param mode the compare mode - * @return 0 if both values are equal, -1 if the other value is smaller, and - * 1 otherwise - */ - public final int compareTo(Value v, CompareMode mode) { - if (this == v) { - return 0; - } - if (this == ValueNull.INSTANCE) { - return v == ValueNull.INSTANCE ? 0 : -1; - } else if (v == ValueNull.INSTANCE) { - return 1; - } - if (getType() == v.getType()) { - return compareSecure(v, mode); - } - int t2 = Value.getHigherOrder(getType(), v.getType()); - return convertTo(t2).compareSecure(v.convertTo(t2), mode); - } - - public int getScale() { - return 0; - } - - /** - * Convert the scale. - * - * @param onlyToSmallerScale if the scale should not reduced - * @param targetScale the requested scale - * @return the value - * @throws SQLException - */ - public Value convertScale(boolean onlyToSmallerScale, int targetScale) { - return this; - } - - /** - * Convert the precision to the requested value. - * - * @param precision the new precision - * @return the new value - * @throws SQLException - */ - public Value convertPrecision(long precision) { - return this; - } - - private byte convertToByte(long x) { - if (x > Byte.MAX_VALUE || x < Byte.MIN_VALUE) { - throw DbException.get(ErrorCode.NUMERIC_VALUE_OUT_OF_RANGE); - } - return (byte) x; - } - - private short convertToShort(long x) { - if (x > Short.MAX_VALUE || x < Short.MIN_VALUE) { - throw DbException.get(ErrorCode.NUMERIC_VALUE_OUT_OF_RANGE); - } - return (short) x; - } - - private int convertToInt(long x) { - if (x > Integer.MAX_VALUE || x < Integer.MIN_VALUE) { - throw DbException.get(ErrorCode.NUMERIC_VALUE_OUT_OF_RANGE); - } - return (int) x; - } - - private long convertToLong(double x) { - if (x > Long.MAX_VALUE || x < Long.MIN_VALUE) { - // TODO document that +Infinity, -Infinity throw an exception and NaN returns 0 - throw DbException.get(ErrorCode.NUMERIC_VALUE_OUT_OF_RANGE); - } - return Math.round(x); - } - - private long convertToLong(BigDecimal x) { - if (x.compareTo(MAX_LONG_DECIMAL) > 0 || x.compareTo(Value.MIN_LONG_DECIMAL) < 0) { - throw DbException.get(ErrorCode.NUMERIC_VALUE_OUT_OF_RANGE); - } - return x.setScale(0, BigDecimal.ROUND_HALF_UP).longValue(); - } - - /** - * Link a large value to a given table. For values that are kept fully in - * memory this method has no effect. - * - * @param handler the data handler - * @param tableId the table to link to - * @return the new value or itself - * @throws SQLException - */ - public Value link(DataHandler handler, int tableId) { - return this; - } - - /** - * Check if this value is linked to a specific table. For values that are - * kept fully in memory, this method returns false. - * - * @return true if it is - */ - public boolean isLinked() { - return false; - } - - /** - * Mark any underlying resource as 'not linked to any table'. For values - * that are kept fully in memory this method has no effect. - * - * @throws SQLException - */ - public void unlink() { - // nothing to do - } - - /** - * Check if this value is stored in it's own file. For values that are - * kept fully in memory, this method returns false. - * - * @return true if it is - */ - public boolean isFileBased() { - return false; - } - - /** - * Close the underlying resource, if any. For values that are kept fully in - * memory this method has no effect. - * - * @throws SQLException - */ - public void close() { - // nothing to do - } - - /** - * Check if the precision is smaller or equal than the given precision. - * - * @param precision the maximum precision - * @return true if the precision of this value is smaller or equal to the - * given precision - */ - public boolean checkPrecision(long precision) { - return getPrecision() <= precision; - } - - /** - * Get a medium size SQL expression for debugging or tracing. If the precision is - * too large, only a subset of the value is returned. - * - * @return the SQL expression - */ - public String getTraceSQL() { - return getSQL(); - } - - public String toString() { - return getTraceSQL(); - } - - /** - * Throw the exception that the feature is not support for the given data type. - * - * @return never returns normally - * @throws the exception - */ - protected DbException throwUnsupportedExceptionForType(String op) { - throw DbException.getUnsupportedException(DataType.getDataType(getType()).name + " " + op); - } - - /** - * Get the table (only for LOB object). - * - * @return the table id - */ - public int getTableId() { - return 0; - } - - /** - * Get the byte array. - * - * @return the byte array - */ - public byte[] getSmall() { - return null; - } - - /** - * Copy this value to a temporary file if necessary. - * - * @return the new value - */ - public Value copyToTemp() { - return this; - } - - /** - * A "binary large object". - */ - public interface ValueClob { - // this is a marker interface - } - - /** - * A "character large object". - */ - public interface ValueBlob { - // this is a marker interface - } - -} diff --git a/tools/h2/src/main/org/h2/value/ValueArray.java b/tools/h2/src/main/org/h2/value/ValueArray.java deleted file mode 100755 index 4ecab9a..0000000 --- a/tools/h2/src/main/org/h2/value/ValueArray.java +++ /dev/null @@ -1,152 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.value; - -import java.sql.PreparedStatement; -import org.h2.util.MathUtils; -import org.h2.util.StatementBuilder; - -/** - * Implementation of the ARRAY data type. - */ -public class ValueArray extends Value { - private final Value[] values; - private int hash; - - private ValueArray(Value[] list) { - this.values = list; - } - - /** - * Get or create a array value for the given value array. - * Do not clone the data. - * - * @param list the value array - * @return the value - */ - public static ValueArray get(Value[] list) { - return new ValueArray(list); - } - - public int hashCode() { - if (hash != 0) { - return hash; - } - int h = 1; - for (Value v : values) { - h = h * 31 + v.hashCode(); - } - hash = h; - return h; - } - - public Value[] getList() { - return values; - } - - public int getType() { - return Value.ARRAY; - } - - public long getPrecision() { - return 0; - } - - public String getString() { - StatementBuilder buff = new StatementBuilder("("); - for (Value v : values) { - buff.appendExceptFirst(", "); - buff.append(v.getString()); - } - return buff.append(')').toString(); - } - - protected int compareSecure(Value o, CompareMode mode) { - ValueArray v = (ValueArray) o; - if (values == v.values) { - return 0; - } - int l = values.length; - int ol = v.values.length; - int len = Math.min(l, ol); - for (int i = 0; i < len; i++) { - Value v1 = values[i]; - Value v2 = v.values[i]; - int comp = v1.compareTo(v2, mode); - if (comp != 0) { - return comp; - } - } - return l > ol ? 1 : l == ol ? 0 : -1; - } - - public Object getObject() { - Object[] list = new Object[values.length]; - for (int i = 0; i < values.length; i++) { - list[i] = values[i].getObject(); - } - return list; - } - - public void set(PreparedStatement prep, int parameterIndex) { - throw throwUnsupportedExceptionForType("PreparedStatement.set"); - } - - public String getSQL() { - StatementBuilder buff = new StatementBuilder("("); - for (Value v : values) { - buff.appendExceptFirst(", "); - buff.append(v.getSQL()); - } - return buff.append(')').toString(); - } - - public String getTraceSQL() { - StatementBuilder buff = new StatementBuilder("("); - for (Value v : values) { - buff.appendExceptFirst(", "); - buff.append(v.getTraceSQL()); - } - return buff.append(')').toString(); - } - - public int getDisplaySize() { - long size = 0; - for (Value v : values) { - size += v.getDisplaySize(); - } - return MathUtils.convertLongToInt(size); - } - - public boolean equals(Object other) { - if (!(other instanceof ValueArray)) { - return false; - } - ValueArray v = (ValueArray) other; - if (values == v.values) { - return true; - } - if (values.length != v.values.length) { - return false; - } - for (int i = 0; i < values.length; i++) { - if (!values[i].equals(v.values[i])) { - return false; - } - } - return true; - } - - public int getMemory() { - int memory = 0; - for (Value v : values) { - memory += v.getMemory(); - } - return memory; - } - -} diff --git a/tools/h2/src/main/org/h2/value/ValueBoolean.java b/tools/h2/src/main/org/h2/value/ValueBoolean.java deleted file mode 100755 index c9b9234..0000000 --- a/tools/h2/src/main/org/h2/value/ValueBoolean.java +++ /dev/null @@ -1,101 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.value; - -import java.sql.PreparedStatement; -import java.sql.SQLException; - -/** - * Implementation of the BOOLEAN data type. - */ -public class ValueBoolean extends Value { - - /** - * The precision in digits. - */ - public static final int PRECISION = 1; - - /** - * The maximum display size of a boolean. - * Example: FALSE - */ - public static final int DISPLAY_SIZE = 5; - - /** - * Of type Object so that Tomcat doesn't set it to null. - */ - private static final Object TRUE = new ValueBoolean(true); - private static final Object FALSE = new ValueBoolean(false); - - private final Boolean value; - - private ValueBoolean(boolean value) { - this.value = Boolean.valueOf(value); - } - - public int getType() { - return Value.BOOLEAN; - } - - public String getSQL() { - return getString(); - } - - public String getString() { - return value.booleanValue() ? "TRUE" : "FALSE"; - } - - public Value negate() { - return (ValueBoolean) (value.booleanValue() ? FALSE : TRUE); - } - - public Boolean getBoolean() { - return value; - } - - protected int compareSecure(Value o, CompareMode mode) { - boolean v2 = ((ValueBoolean) o).value.booleanValue(); - boolean v = value.booleanValue(); - return (v == v2) ? 0 : (v ? 1 : -1); - } - - public long getPrecision() { - return PRECISION; - } - - public int hashCode() { - return value.booleanValue() ? 1 : 0; - } - - public Object getObject() { - return value; - } - - public void set(PreparedStatement prep, int parameterIndex) throws SQLException { - prep.setBoolean(parameterIndex, value.booleanValue()); - } - - /** - * Get the boolean value for the given boolean. - * - * @param b the boolean - * @return the value - */ - public static ValueBoolean get(boolean b) { - return (ValueBoolean) (b ? TRUE : FALSE); - } - - public int getDisplaySize() { - return DISPLAY_SIZE; - } - - public boolean equals(Object other) { - // there are only ever two instances, so the instance must match - return this == other; - } - -} diff --git a/tools/h2/src/main/org/h2/value/ValueByte.java b/tools/h2/src/main/org/h2/value/ValueByte.java deleted file mode 100755 index a87be6d..0000000 --- a/tools/h2/src/main/org/h2/value/ValueByte.java +++ /dev/null @@ -1,130 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.value; - -import java.sql.PreparedStatement; -import java.sql.SQLException; -import org.h2.constant.ErrorCode; -import org.h2.message.DbException; -import org.h2.util.MathUtils; - -/** - * Implementation of the BYTE data type. - */ -public class ValueByte extends Value { - - /** - * The precision in digits. - */ - static final int PRECISION = 3; - - /** - * The display size for a byte. - * Example: -127 - */ - static final int DISPLAY_SIZE = 4; - - private final byte value; - - private ValueByte(byte value) { - this.value = value; - } - - public Value add(Value v) { - ValueByte other = (ValueByte) v; - return checkRange(value + other.value); - } - - private ValueByte checkRange(int x) { - if (x < Byte.MIN_VALUE || x > Byte.MAX_VALUE) { - throw DbException.get(ErrorCode.OVERFLOW_FOR_TYPE_1, DataType.getDataType(Value.BYTE).name); - } - return ValueByte.get((byte) x); - } - - public int getSignum() { - return Integer.signum(value); - } - - public Value negate() { - return checkRange(-(int) value); - } - - public Value subtract(Value v) { - ValueByte other = (ValueByte) v; - return checkRange(value - other.value); - } - - public Value multiply(Value v) { - ValueByte other = (ValueByte) v; - return checkRange(value * other.value); - } - - public Value divide(Value v) { - ValueByte other = (ValueByte) v; - if (other.value == 0) { - throw DbException.get(ErrorCode.DIVISION_BY_ZERO_1, getSQL()); - } - return ValueByte.get((byte) (value / other.value)); - } - - public String getSQL() { - return getString(); - } - - public int getType() { - return Value.BYTE; - } - - public byte getByte() { - return value; - } - - protected int compareSecure(Value o, CompareMode mode) { - ValueByte v = (ValueByte) o; - return MathUtils.compareInt(value, v.value); - } - - public String getString() { - return String.valueOf(value); - } - - public long getPrecision() { - return PRECISION; - } - - public int hashCode() { - return value; - } - - public Object getObject() { - return Byte.valueOf(value); - } - - public void set(PreparedStatement prep, int parameterIndex) throws SQLException { - prep.setByte(parameterIndex, value); - } - - /** - * Get or create byte value for the given byte. - * - * @param i the byte - * @return the value - */ - public static ValueByte get(byte i) { - return (ValueByte) Value.cache(new ValueByte(i)); - } - - public int getDisplaySize() { - return DISPLAY_SIZE; - } - - public boolean equals(Object other) { - return other instanceof ValueByte && value == ((ValueByte) other).value; - } - -} diff --git a/tools/h2/src/main/org/h2/value/ValueBytes.java b/tools/h2/src/main/org/h2/value/ValueBytes.java deleted file mode 100755 index dd7ecff..0000000 --- a/tools/h2/src/main/org/h2/value/ValueBytes.java +++ /dev/null @@ -1,119 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.value; - -import java.sql.PreparedStatement; -import java.sql.SQLException; -import org.h2.constant.SysProperties; -import org.h2.util.MathUtils; -import org.h2.util.Utils; - -/** - * Implementation of the BINARY data type. - * It is also the base class for ValueJavaObject. - */ -public class ValueBytes extends Value { - - private static final ValueBytes EMPTY = new ValueBytes(Utils.EMPTY_BYTES); - - private final byte[] value; - private int hash; - - protected ValueBytes(byte[] v) { - this.value = v; - } - - /** - * Get or create a bytes value for the given byte array. - * Clone the data. - * - * @param b the byte array - * @return the value - */ - public static ValueBytes get(byte[] b) { - if (b.length == 0) { - return EMPTY; - } - b = Utils.cloneByteArray(b); - return getNoCopy(b); - } - - /** - * Get or create a bytes value for the given byte array. - * Do not clone the date. - * - * @param b the byte array - * @return the value - */ - public static ValueBytes getNoCopy(byte[] b) { - if (b.length == 0) { - return EMPTY; - } - ValueBytes obj = new ValueBytes(b); - if (b.length > SysProperties.OBJECT_CACHE_MAX_PER_ELEMENT_SIZE) { - return obj; - } - return (ValueBytes) Value.cache(obj); - } - - public int getType() { - return Value.BYTES; - } - - public String getSQL() { - return "X'" + getString() + "'"; - } - - public byte[] getBytesNoCopy() { - return value; - } - - public byte[] getBytes() { - return Utils.cloneByteArray(value); - } - - protected int compareSecure(Value v, CompareMode mode) { - byte[] v2 = ((ValueBytes) v).value; - return Utils.compareNotNull(value, v2); - } - - public String getString() { - return Utils.convertBytesToString(value); - } - - public long getPrecision() { - return value.length; - } - - public int hashCode() { - if (hash == 0) { - hash = Utils.getByteArrayHash(value); - } - return hash; - } - - public Object getObject() { - return getBytes(); - } - - public void set(PreparedStatement prep, int parameterIndex) throws SQLException { - prep.setBytes(parameterIndex, value); - } - - public int getDisplaySize() { - return MathUtils.convertLongToInt(value.length * 2L); - } - - public int getMemory() { - return value.length + 4; - } - - public boolean equals(Object other) { - return other instanceof ValueBytes && Utils.compareNotNull(value, ((ValueBytes) other).value) == 0; - } - -} diff --git a/tools/h2/src/main/org/h2/value/ValueDate.java b/tools/h2/src/main/org/h2/value/ValueDate.java deleted file mode 100755 index beeed45..0000000 --- a/tools/h2/src/main/org/h2/value/ValueDate.java +++ /dev/null @@ -1,132 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.value; - -import java.sql.Date; -import java.sql.PreparedStatement; -import java.sql.SQLException; -import java.util.Calendar; -import org.h2.constant.ErrorCode; -import org.h2.util.DateTimeUtils; - -/** - * Implementation of the DATE data type. - */ -public class ValueDate extends Value { - - /** - * The precision in digits. - */ - public static final int PRECISION = 8; - - /** - * The display size of the textual representation of a date. - * Example: 2000-01-02 - */ - static final int DISPLAY_SIZE = 10; - - private final Date value; - - private ValueDate(Date value) { - this.value = value; - } - - /** - * Parse a string to a java.sql.Date object. - * - * @param s the string to parse - * @return the date - */ - public static Date parseDate(String s) { - return (Date) DateTimeUtils.parseDateTime(s, Value.DATE, ErrorCode.DATE_CONSTANT_2); - } - - public Date getDate() { - // this class is mutable - must copy the object - return (Date) value.clone(); - } - - public Date getDateNoCopy() { - return value; - } - - public String getSQL() { - return "DATE '" + getString() + "'"; - } - - public int getType() { - return Value.DATE; - } - - protected int compareSecure(Value o, CompareMode mode) { - ValueDate v = (ValueDate) o; - return Integer.signum(value.compareTo(v.value)); - } - - public String getString() { - String s = value.toString(); - long time = value.getTime(); - // special case: java.sql.Date doesn't format - // years below year 1 (BC) and years above 9999 correctly - if (time < ValueTimestamp.YEAR_ONE || time > ValueTimestamp.YEAR_9999) { - int year = DateTimeUtils.getDatePart(value, Calendar.YEAR); - if (year < 1 || year > 9999) { - s = year + s.substring(s.indexOf('-')); - } - } - return s; - } - - public long getPrecision() { - return PRECISION; - } - - public int hashCode() { - return value.hashCode(); - } - - public Object getObject() { - // this class is mutable - must copy the object - return getDate(); - } - - public void set(PreparedStatement prep, int parameterIndex) throws SQLException { - prep.setDate(parameterIndex, value); - } - - /** - * Get or create a date value for the given date. - * Clone the date. - * - * @param date the date - * @return the value - */ - public static ValueDate get(Date date) { - date = DateTimeUtils.cloneAndNormalizeDate(date); - return getNoCopy(date); - } - - /** - * Get or create a date value for the given date. - * Do not clone the date. - * - * @param date the date - * @return the value - */ - public static ValueDate getNoCopy(Date date) { - return (ValueDate) Value.cache(new ValueDate(date)); - } - - public int getDisplaySize() { - return DISPLAY_SIZE; - } - - public boolean equals(Object other) { - return other instanceof ValueDate && value.equals(((ValueDate) other).value); - } - -} diff --git a/tools/h2/src/main/org/h2/value/ValueDecimal.java b/tools/h2/src/main/org/h2/value/ValueDecimal.java deleted file mode 100755 index e89cbc5..0000000 --- a/tools/h2/src/main/org/h2/value/ValueDecimal.java +++ /dev/null @@ -1,217 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.value; - -import java.math.BigDecimal; -import java.sql.PreparedStatement; -import java.sql.SQLException; - -import org.h2.constant.ErrorCode; -import org.h2.constant.SysProperties; -import org.h2.message.DbException; -import org.h2.util.MathUtils; - -/** - * Implementation of the DECIMAL data type. - */ -public class ValueDecimal extends Value { - - /** - * The value 'zero'. - */ - public static final Object ZERO = new ValueDecimal(BigDecimal.ZERO); - - /** - * The value 'one'. - */ - public static final Object ONE = new ValueDecimal(BigDecimal.ONE); - - /** - * The default precision for a decimal value. - */ - static final int DEFAULT_PRECISION = 65535; - - /** - * The default scale for a decimal value. - */ - static final int DEFAULT_SCALE = 32767; - - /** - * The default display size for a decimal value. - */ - static final int DEFAULT_DISPLAY_SIZE = 65535; - - private static final int DIVIDE_SCALE_ADD = 25; - - private final BigDecimal value; - private String valueString; - private int precision; - - private ValueDecimal(BigDecimal value) { - if (value == null) { - throw new IllegalArgumentException(); - } else if (!SysProperties.ALLOW_BIG_DECIMAL_EXTENSIONS && !value.getClass().equals(BigDecimal.class)) { - throw DbException.get(ErrorCode.INVALID_CLASS_2, - BigDecimal.class.getName(), value.getClass().getName()); - } - this.value = value; - } - - public Value add(Value v) { - ValueDecimal dec = (ValueDecimal) v; - return ValueDecimal.get(value.add(dec.value)); - } - - public Value subtract(Value v) { - ValueDecimal dec = (ValueDecimal) v; - return ValueDecimal.get(value.subtract(dec.value)); - } - - public Value negate() { - return ValueDecimal.get(value.negate()); - } - - public Value multiply(Value v) { - ValueDecimal dec = (ValueDecimal) v; - return ValueDecimal.get(value.multiply(dec.value)); - } - - public Value divide(Value v) { - ValueDecimal dec = (ValueDecimal) v; - if (dec.value.signum() == 0) { - throw DbException.get(ErrorCode.DIVISION_BY_ZERO_1, getSQL()); - } - BigDecimal bd = value.divide(dec.value, value.scale() + DIVIDE_SCALE_ADD, BigDecimal.ROUND_HALF_DOWN); - if (bd.signum() == 0) { - bd = BigDecimal.ZERO; - } else if (bd.scale() > 0) { - if (!bd.unscaledValue().testBit(0)) { - String s = bd.toString(); - int i = s.length() - 1; - while (i >= 0 && s.charAt(i) == '0') { - i--; - } - if (i < s.length() - 1) { - s = s.substring(0, i + 1); - bd = new BigDecimal(s); - } - } - } - return ValueDecimal.get(bd); - } - - public String getSQL() { - return getString(); - } - - public int getType() { - return Value.DECIMAL; - } - - protected int compareSecure(Value o, CompareMode mode) { - ValueDecimal v = (ValueDecimal) o; - return value.compareTo(v.value); - } - - public int getSignum() { - return value.signum(); - } - - public BigDecimal getBigDecimal() { - return value; - } - - public String getString() { - if (valueString == null) { - valueString = value.toString(); - } - return valueString; - } - - public long getPrecision() { - if (precision == 0) { - precision = MathUtils.precision(value); - } - return precision; - } - - public boolean checkPrecision(long prec) { - if (prec == DEFAULT_PRECISION) { - return true; - } - return getPrecision() <= prec; - } - - public int getScale() { - return value.scale(); - } - - public int hashCode() { - return value.hashCode(); - } - - public Object getObject() { - return value; - } - - public void set(PreparedStatement prep, int parameterIndex) throws SQLException { - prep.setBigDecimal(parameterIndex, value); - } - - public Value convertScale(boolean onlyToSmallerScale, int targetScale) { - if (value.scale() == targetScale) { - return this; - } - if (onlyToSmallerScale || targetScale >= DEFAULT_SCALE) { - if (value.scale() < targetScale) { - return this; - } - } - BigDecimal bd = MathUtils.setScale(value, targetScale); - return ValueDecimal.get(bd); - } - - public Value convertPrecision(long newPrecision) { - if (getPrecision() <= newPrecision) { - return this; - } - throw DbException.get(ErrorCode.VALUE_TOO_LARGE_FOR_PRECISION_1, "" + newPrecision); - } - - /** - * Get or create big decimal value for the given big decimal. - * - * @param dec the bit decimal - * @return the value - */ - public static ValueDecimal get(BigDecimal dec) { - if (BigDecimal.ZERO.equals(dec)) { - return (ValueDecimal) ZERO; - } else if (BigDecimal.ONE.equals(dec)) { - return (ValueDecimal) ONE; - } - return (ValueDecimal) Value.cache(new ValueDecimal(dec)); - } - - public int getDisplaySize() { - // add 2 characters for '-' and '.' - return MathUtils.convertLongToInt(getPrecision() + 2); - } - - public boolean equals(Object other) { - // Two BigDecimal objects are considered equal only if they are equal in - // value and scale (thus 2.0 is not equal to 2.00 when using equals; - // however -0.0 and 0.0 are). Can not use compareTo because 2.0 and 2.00 - // have different hash codes - return other instanceof ValueDecimal && value.equals(((ValueDecimal) other).value); - } - - public int getMemory() { - return MathUtils.precision(value) * 3 + 120; - } - -} diff --git a/tools/h2/src/main/org/h2/value/ValueDouble.java b/tools/h2/src/main/org/h2/value/ValueDouble.java deleted file mode 100755 index 137152b..0000000 --- a/tools/h2/src/main/org/h2/value/ValueDouble.java +++ /dev/null @@ -1,150 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.value; - -import java.sql.PreparedStatement; -import java.sql.SQLException; -import org.h2.constant.ErrorCode; -import org.h2.message.DbException; - -/** - * Implementation of the DOUBLE data type. - */ -public class ValueDouble extends Value { - - /** - * The precision in digits. - */ - public static final int PRECISION = 17; - - /** - * The maximum display size of a double. - * Example: -3.3333333333333334E-100 - */ - public static final int DISPLAY_SIZE = 24; - - private static final double DOUBLE_ZERO = 0.0; - private static final double DOUBLE_ONE = 1.0; - private static final ValueDouble ZERO = new ValueDouble(DOUBLE_ZERO); - private static final ValueDouble ONE = new ValueDouble(DOUBLE_ONE); - private static final ValueDouble NAN = new ValueDouble(Double.NaN); - - private final double value; - - private ValueDouble(double value) { - this.value = value; - } - - public Value add(Value v) { - ValueDouble v2 = (ValueDouble) v; - return ValueDouble.get(value + v2.value); - } - - public Value subtract(Value v) { - ValueDouble v2 = (ValueDouble) v; - return ValueDouble.get(value - v2.value); - } - - public Value negate() { - return ValueDouble.get(-value); - } - - public Value multiply(Value v) { - ValueDouble v2 = (ValueDouble) v; - return ValueDouble.get(value * v2.value); - } - - public Value divide(Value v) { - ValueDouble v2 = (ValueDouble) v; - if (v2.value == 0.0) { - throw DbException.get(ErrorCode.DIVISION_BY_ZERO_1, getSQL()); - } - return ValueDouble.get(value / v2.value); - } - - public String getSQL() { - if (value == Double.POSITIVE_INFINITY) { - return "POWER(0, -1)"; - } else if (value == Double.NEGATIVE_INFINITY) { - return "(-POWER(0, -1))"; - } else if (Double.isNaN(value)) { - return "SQRT(-1)"; - } - return getString(); - } - - public int getType() { - return Value.DOUBLE; - } - - protected int compareSecure(Value o, CompareMode mode) { - ValueDouble v = (ValueDouble) o; - return Double.compare(value, v.value); - } - - public int getSignum() { - return value == 0 ? 0 : (value < 0 ? -1 : 1); - } - - public double getDouble() { - return value; - } - - public String getString() { - return String.valueOf(value); - } - - public long getPrecision() { - return PRECISION; - } - - public int getScale() { - return 0; - } - - public int hashCode() { - long hash = Double.doubleToLongBits(value); - return (int) (hash ^ (hash >> 32)); - } - - public Object getObject() { - return Double.valueOf(value); - } - - public void set(PreparedStatement prep, int parameterIndex) throws SQLException { - prep.setDouble(parameterIndex, value); - } - - /** - * Get or create double value for the given double. - * - * @param d the double - * @return the value - */ - public static ValueDouble get(double d) { - if (DOUBLE_ZERO == d) { - return ZERO; - } else if (DOUBLE_ONE == d) { - return ONE; - } else if (Double.isNaN(d)) { - return NAN; - } - return (ValueDouble) Value.cache(new ValueDouble(d)); - } - - public int getDisplaySize() { - return DISPLAY_SIZE; - } - - public boolean equals(Object other) { - if (!(other instanceof ValueDouble)) { - return false; - } - return compareSecure((ValueDouble) other, null) == 0; - } - -} diff --git a/tools/h2/src/main/org/h2/value/ValueFloat.java b/tools/h2/src/main/org/h2/value/ValueFloat.java deleted file mode 100755 index c71b9b7..0000000 --- a/tools/h2/src/main/org/h2/value/ValueFloat.java +++ /dev/null @@ -1,148 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.value; - -import java.sql.PreparedStatement; -import java.sql.SQLException; -import org.h2.constant.ErrorCode; -import org.h2.message.DbException; - -/** - * Implementation of the REAL data type. - */ -public class ValueFloat extends Value { - - /** - * The precision in digits. - */ - static final int PRECISION = 7; - - /** - * The maximum display size of a float. - * Example: -1.12345676E-20 - */ - static final int DISPLAY_SIZE = 15; - - private static final float FLOAT_ZERO = 0.0F; - private static final float FLOAT_ONE = 1.0F; - private static final ValueFloat ZERO = new ValueFloat(FLOAT_ZERO); - private static final ValueFloat ONE = new ValueFloat(FLOAT_ONE); - - private final float value; - - private ValueFloat(float value) { - this.value = value; - } - - public Value add(Value v) { - ValueFloat v2 = (ValueFloat) v; - return ValueFloat.get(value + v2.value); - } - - public Value subtract(Value v) { - ValueFloat v2 = (ValueFloat) v; - return ValueFloat.get(value - v2.value); - } - - public Value negate() { - return ValueFloat.get(-value); - } - - public Value multiply(Value v) { - ValueFloat v2 = (ValueFloat) v; - return ValueFloat.get(value * v2.value); - } - - public Value divide(Value v) { - ValueFloat v2 = (ValueFloat) v; - if (v2.value == 0.0) { - throw DbException.get(ErrorCode.DIVISION_BY_ZERO_1, getSQL()); - } - return ValueFloat.get(value / v2.value); - } - - public String getSQL() { - if (value == Float.POSITIVE_INFINITY) { - return "POWER(0, -1)"; - } else if (value == Float.NEGATIVE_INFINITY) { - return "(-POWER(0, -1))"; - } else if (Double.isNaN(value)) { - // NaN - return "SQRT(-1)"; - } - return getString(); - } - - public int getType() { - return Value.FLOAT; - } - - protected int compareSecure(Value o, CompareMode mode) { - ValueFloat v = (ValueFloat) o; - return Float.compare(value, v.value); - } - - public int getSignum() { - return value == 0 ? 0 : (value < 0 ? -1 : 1); - } - - public float getFloat() { - return value; - } - - public String getString() { - return String.valueOf(value); - } - - public long getPrecision() { - return PRECISION; - } - - public int getScale() { - return 0; - } - - public int hashCode() { - long hash = Float.floatToIntBits(value); - return (int) (hash ^ (hash >> 32)); - } - - public Object getObject() { - return Float.valueOf(value); - } - - public void set(PreparedStatement prep, int parameterIndex) throws SQLException { - prep.setFloat(parameterIndex, value); - } - - /** - * Get or create float value for the given float. - * - * @param d the float - * @return the value - */ - public static ValueFloat get(float d) { - if (FLOAT_ZERO == d) { - return ZERO; - } else if (FLOAT_ONE == d) { - return ONE; - } - return (ValueFloat) Value.cache(new ValueFloat(d)); - } - - public int getDisplaySize() { - return DISPLAY_SIZE; - } - - public boolean equals(Object other) { - if (!(other instanceof ValueFloat)) { - return false; - } - return compareSecure((ValueFloat) other, null) == 0; - } - -} diff --git a/tools/h2/src/main/org/h2/value/ValueInt.java b/tools/h2/src/main/org/h2/value/ValueInt.java deleted file mode 100755 index 041f788..0000000 --- a/tools/h2/src/main/org/h2/value/ValueInt.java +++ /dev/null @@ -1,154 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.value; - -import java.sql.PreparedStatement; -import java.sql.SQLException; -import org.h2.constant.ErrorCode; -import org.h2.message.DbException; -import org.h2.util.MathUtils; - -/** - * Implementation of the INT data type. - */ -public class ValueInt extends Value { - - /** - * The precision in digits. - */ - public static final int PRECISION = 10; - - /** - * The maximum display size of an int. - * Example: -2147483648 - */ - public static final int DISPLAY_SIZE = 11; - - private static final int STATIC_SIZE = 128; - // must be a power of 2 - private static final int DYNAMIC_SIZE = 256; - private static final ValueInt[] STATIC_CACHE = new ValueInt[STATIC_SIZE]; - private static final ValueInt[] DYNAMIC_CACHE = new ValueInt[DYNAMIC_SIZE]; - - private final int value; - - static { - for (int i = 0; i < STATIC_SIZE; i++) { - STATIC_CACHE[i] = new ValueInt(i); - } - } - - private ValueInt(int value) { - this.value = value; - } - - /** - * Get or create an int value for the given int. - * - * @param i the int - * @return the value - */ - public static ValueInt get(int i) { - if (i >= 0 && i < STATIC_SIZE) { - return STATIC_CACHE[i]; - } - ValueInt v = DYNAMIC_CACHE[i & (DYNAMIC_SIZE - 1)]; - if (v == null || v.value != i) { - v = new ValueInt(i); - DYNAMIC_CACHE[i & (DYNAMIC_SIZE - 1)] = v; - } - return v; - } - - public Value add(Value v) { - ValueInt other = (ValueInt) v; - return checkRange((long) value + (long) other.value); - } - - private ValueInt checkRange(long x) { - if (x < Integer.MIN_VALUE || x > Integer.MAX_VALUE) { - throw DbException.get(ErrorCode.OVERFLOW_FOR_TYPE_1, DataType.getDataType(Value.INT).name); - } - return ValueInt.get((int) x); - } - - public int getSignum() { - return Integer.signum(value); - } - - public Value negate() { - return checkRange(-(long) value); - } - - public Value subtract(Value v) { - ValueInt other = (ValueInt) v; - return checkRange((long) value - (long) other.value); - } - - public Value multiply(Value v) { - ValueInt other = (ValueInt) v; - return checkRange((long) value * (long) other.value); - } - - public Value divide(Value v) { - ValueInt other = (ValueInt) v; - if (other.value == 0) { - throw DbException.get(ErrorCode.DIVISION_BY_ZERO_1, getSQL()); - } - return ValueInt.get(value / other.value); - } - - public String getSQL() { - return getString(); - } - - public int getType() { - return Value.INT; - } - - public int getInt() { - return value; - } - - public long getLong() { - return value; - } - - protected int compareSecure(Value o, CompareMode mode) { - ValueInt v = (ValueInt) o; - return MathUtils.compareInt(value, v.value); - } - - public String getString() { - return String.valueOf(value); - } - - public long getPrecision() { - return PRECISION; - } - - public int hashCode() { - return value; - } - - public Object getObject() { - return value; - } - - public void set(PreparedStatement prep, int parameterIndex) throws SQLException { - prep.setInt(parameterIndex, value); - } - - public int getDisplaySize() { - return DISPLAY_SIZE; - } - - public boolean equals(Object other) { - return other instanceof ValueInt && value == ((ValueInt) other).value; - } - -} diff --git a/tools/h2/src/main/org/h2/value/ValueJavaObject.java b/tools/h2/src/main/org/h2/value/ValueJavaObject.java deleted file mode 100755 index fe2f23f..0000000 --- a/tools/h2/src/main/org/h2/value/ValueJavaObject.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.value; - -import java.sql.PreparedStatement; -import java.sql.SQLException; -import java.sql.Types; - -import org.h2.constant.SysProperties; -import org.h2.util.Utils; - -/** - * Implementation of the OBJECT data type. - */ -public class ValueJavaObject extends ValueBytes { - - private static final ValueJavaObject EMPTY = new ValueJavaObject(Utils.EMPTY_BYTES); - - protected ValueJavaObject(byte[] v) { - super(v); - } - - /** - * Get or create a java object value for the given byte array. - * Do not clone the data. - * - * @param b the byte array - * @return the value - */ - public static ValueJavaObject getNoCopy(byte[] b) { - if (b.length == 0) { - return EMPTY; - } - ValueJavaObject obj = new ValueJavaObject(b); - if (b.length > SysProperties.OBJECT_CACHE_MAX_PER_ELEMENT_SIZE) { - return obj; - } - return (ValueJavaObject) Value.cache(obj); - } - - public int getType() { - return Value.JAVA_OBJECT; - } - - public void set(PreparedStatement prep, int parameterIndex) throws SQLException { - Object obj = Utils.deserialize(getBytesNoCopy()); - prep.setObject(parameterIndex, obj, Types.JAVA_OBJECT); - } - -} diff --git a/tools/h2/src/main/org/h2/value/ValueLob.java b/tools/h2/src/main/org/h2/value/ValueLob.java deleted file mode 100755 index 9a3d535..0000000 --- a/tools/h2/src/main/org/h2/value/ValueLob.java +++ /dev/null @@ -1,784 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.value; - -import java.io.BufferedInputStream; -import java.io.ByteArrayInputStream; -import java.io.File; -import java.io.IOException; -import java.io.InputStream; -import java.io.Reader; -import java.sql.PreparedStatement; -import java.sql.SQLException; -import org.h2.constant.SysProperties; -import org.h2.engine.Constants; -import org.h2.message.DbException; -import org.h2.store.DataHandler; -import org.h2.store.FileStore; -import org.h2.store.FileStoreInputStream; -import org.h2.store.FileStoreOutputStream; -import org.h2.store.fs.FileSystem; -import org.h2.util.IOUtils; -import org.h2.util.MathUtils; -import org.h2.util.SmallLRUCache; -import org.h2.util.StringUtils; -import org.h2.util.Utils; - -/** - * Implementation of the BLOB and CLOB data types. Small objects are kept in - * memory and stored in the record. - * - * Large objects are stored in their own files. When large objects are set in a - * prepared statement, they are first stored as 'temporary' files. Later, when - * they are used in a record, and when the record is stored, the lob files are - * linked: the file is renamed using the file format (tableId).(objectId). There - * is one exception: large variables are stored in the file (-1).(objectId). - * - * When lobs are deleted, they are first renamed to a temp file, and if the - * delete operation is committed the file is deleted. - * - * Data compression is supported. - */ -public class ValueLob extends Value { - - /** - * This counter is used to calculate the next directory to store lobs. It is - * better than using a random number because less directories are created. - */ - private static int dirCounter; - - private final int type; - private long precision; - private DataHandler handler; - private int tableId; - private int objectId; - private String fileName; - private boolean linked; - private byte[] small; - private int hash; - private boolean compression; - private FileStore tempFile; - - private ValueLob(int type, DataHandler handler, String fileName, int tableId, int objectId, boolean linked, - long precision, boolean compression) { - this.type = type; - this.handler = handler; - this.fileName = fileName; - this.tableId = tableId; - this.objectId = objectId; - this.linked = linked; - this.precision = precision; - this.compression = compression; - } - - private ValueLob(int type, byte[] small) { - this.type = type; - this.small = small; - if (small != null) { - if (type == Value.BLOB) { - this.precision = small.length; - } else { - this.precision = getString().length(); - } - } - } - - private static ValueLob copy(ValueLob lob) { - ValueLob copy = new ValueLob(lob.type, lob.handler, lob.fileName, lob.tableId, lob.objectId, lob.linked, lob.precision, lob.compression); - copy.small = lob.small; - copy.hash = lob.hash; - return copy; - } - - /** - * Create a small lob using the given byte array. - * - * @param type the type (Value.BLOB or CLOB) - * @param small the byte array - * @return the lob value - */ - public static ValueLob createSmallLob(int type, byte[] small) { - return new ValueLob(type, small); - } - - private static String getFileName(DataHandler handler, int tableId, int objectId) { - if (SysProperties.CHECK && tableId == 0 && objectId == 0) { - DbException.throwInternalError("0 LOB"); - } - String table = tableId < 0 ? ".temp" : ".t" + tableId; - return getFileNamePrefix(handler.getDatabasePath(), objectId) + table + Constants.SUFFIX_LOB_FILE; - } - - /** - * Create a LOB value with the given parameters. - * - * @param type the data type - * @param handler the file handler - * @param tableId the table object id - * @param objectId the object id - * @param precision the precision (length in elements) - * @param compression if compression is used - * @return the value object - */ - public static ValueLob open(int type, DataHandler handler, int tableId, int objectId, long precision, boolean compression) { - String fileName = getFileName(handler, tableId, objectId); - return new ValueLob(type, handler, fileName, tableId, objectId, true, precision, compression); - } - - /** - * Create a CLOB value from a stream. - * - * @param in the reader - * @param length the number of characters to read, or -1 for no limit - * @param handler the data handler - * @return the lob value - */ - public static ValueLob createClob(Reader in, long length, DataHandler handler) { - try { - boolean compress = handler.getLobCompressionAlgorithm(Value.CLOB) != null; - long remaining = Long.MAX_VALUE; - if (length >= 0 && length < remaining) { - remaining = length; - } - int len = getBufferSize(handler, compress, remaining); - char[] buff; - if (len >= Integer.MAX_VALUE) { - String data = IOUtils.readStringAndClose(in, -1); - buff = data.toCharArray(); - len = buff.length; - } else { - buff = new char[len]; - len = IOUtils.readFully(in, buff, len); - len = len < 0 ? 0 : len; - } - if (len <= handler.getMaxLengthInplaceLob()) { - byte[] small = StringUtils.utf8Encode(new String(buff, 0, len)); - return ValueLob.createSmallLob(Value.CLOB, small); - } - ValueLob lob = new ValueLob(Value.CLOB, null); - lob.createFromReader(buff, len, in, remaining, handler); - return lob; - } catch (IOException e) { - throw DbException.convertIOException(e, null); - } - } - - private static int getBufferSize(DataHandler handler, boolean compress, long remaining) { - if (remaining < 0 || remaining > Integer.MAX_VALUE) { - remaining = Integer.MAX_VALUE; - } - long inplace = handler.getMaxLengthInplaceLob(); - if (inplace >= Integer.MAX_VALUE) { - inplace = remaining; - } - long m = compress ? Constants.IO_BUFFER_SIZE_COMPRESS : Constants.IO_BUFFER_SIZE; - if (m < remaining && m <= inplace) { - m = Math.min(remaining, inplace + 1); - // the buffer size must be bigger than the inplace lob, otherwise we can't - // know if it must be stored in-place or not - m = MathUtils.roundUpLong(m, Constants.IO_BUFFER_SIZE); - } - m = Math.min(remaining, m); - m = MathUtils.convertLongToInt(m); - if (m < 0) { - m = Integer.MAX_VALUE; - } - return (int) m; - } - - private void createFromReader(char[] buff, int len, Reader in, long remaining, DataHandler h) { - try { - FileStoreOutputStream out = initLarge(h); - boolean compress = h.getLobCompressionAlgorithm(Value.CLOB) != null; - try { - while (true) { - precision += len; - byte[] b = StringUtils.utf8Encode(new String(buff, 0, len)); - out.write(b, 0, b.length); - remaining -= len; - if (remaining <= 0) { - break; - } - len = getBufferSize(h, compress, remaining); - len = IOUtils.readFully(in, buff, len); - if (len <= 0) { - break; - } - } - } finally { - out.close(); - } - } catch (IOException e) { - throw DbException.convertIOException(e, null); - } - } - - private static String getFileNamePrefix(String path, int objectId) { - String name; - int f = objectId % SysProperties.LOB_FILES_PER_DIRECTORY; - if (f > 0) { - name = File.separator + objectId; - } else { - name = ""; - } - objectId /= SysProperties.LOB_FILES_PER_DIRECTORY; - while (objectId > 0) { - f = objectId % SysProperties.LOB_FILES_PER_DIRECTORY; - name = File.separator + f + Constants.SUFFIX_LOBS_DIRECTORY + name; - objectId /= SysProperties.LOB_FILES_PER_DIRECTORY; - } - name = IOUtils.normalize(path + Constants.SUFFIX_LOBS_DIRECTORY + name); - return name; - } - - private int getNewObjectId(DataHandler h) { - String path = h.getDatabasePath(); - int newId = 0; - int lobsPerDir = SysProperties.LOB_FILES_PER_DIRECTORY; - while (true) { - String dir = getFileNamePrefix(path, newId); - String[] list = getFileList(h, dir); - int fileCount = 0; - boolean[] used = new boolean[lobsPerDir]; - for (String name : list) { - if (name.endsWith(Constants.SUFFIX_DB_FILE)) { - name = IOUtils.getFileName(name); - String n = name.substring(0, name.indexOf('.')); - int id; - try { - id = Integer.parseInt(n); - } catch (NumberFormatException e) { - id = -1; - } - if (id > 0) { - fileCount++; - used[id % lobsPerDir] = true; - } - } - } - int fileId = -1; - if (fileCount < lobsPerDir) { - for (int i = 1; i < lobsPerDir; i++) { - if (!used[i]) { - fileId = i; - break; - } - } - } - if (fileId > 0) { - newId += fileId; - invalidateFileList(h, dir); - break; - } - if (newId > Integer.MAX_VALUE / lobsPerDir) { - // this directory path is full: start from zero - newId = 0; - dirCounter = MathUtils.randomInt(lobsPerDir - 1) * lobsPerDir; - } else { - // calculate the directory - // start with 1 (otherwise we don't know the number of directories) - // it doesn't really matter what directory is used, it might as well be random - // (but that would generate more directories): - // int dirId = RandomUtils.nextInt(lobsPerDir - 1) + 1; - int dirId = (dirCounter++ / (lobsPerDir - 1)) + 1; - newId = newId * lobsPerDir; - newId += dirId * lobsPerDir; - } - } - return newId; - } - - /** - * Reset the directory counter as if the process was stopped. This method is - * for debugging only (to simulate stopping a process). - */ - public static void resetDirCounter() { - dirCounter = 0; - } - - private void invalidateFileList(DataHandler h, String dir) { - SmallLRUCache cache = h.getLobFileListCache(); - if (cache != null) { - synchronized (cache) { - cache.remove(dir); - } - } - } - - private String[] getFileList(DataHandler h, String dir) { - SmallLRUCache cache = h.getLobFileListCache(); - String[] list; - if (cache == null) { - list = IOUtils.listFiles(dir); - } else { - synchronized (cache) { - list = cache.get(dir); - if (list == null) { - list = IOUtils.listFiles(dir); - cache.put(dir, list); - } - } - } - return list; - } - - /** - * Create a BLOB value from a stream. - * - * @param in the input stream - * @param length the number of characters to read, or -1 for no limit - * @param handler the data handler - * @return the lob value - */ - public static ValueLob createBlob(InputStream in, long length, DataHandler handler) { - try { - long remaining = Long.MAX_VALUE; - boolean compress = handler.getLobCompressionAlgorithm(Value.BLOB) != null; - if (length >= 0 && length < remaining) { - remaining = length; - } - int len = getBufferSize(handler, compress, remaining); - byte[] buff; - if (len >= Integer.MAX_VALUE) { - buff = IOUtils.readBytesAndClose(in, -1); - len = buff.length; - } else { - buff = Utils.newBytes(len); - len = IOUtils.readFully(in, buff, 0, len); - } - if (len <= handler.getMaxLengthInplaceLob()) { - byte[] small = Utils.newBytes(len); - System.arraycopy(buff, 0, small, 0, len); - return ValueLob.createSmallLob(Value.BLOB, small); - } - ValueLob lob = new ValueLob(Value.BLOB, null); - lob.createFromStream(buff, len, in, remaining, handler); - return lob; - } catch (IOException e) { - throw DbException.convertIOException(e, null); - } - } - - private FileStoreOutputStream initLarge(DataHandler h) { - this.handler = h; - this.tableId = 0; - this.linked = false; - this.precision = 0; - this.small = null; - this.hash = 0; - String compressionAlgorithm = h.getLobCompressionAlgorithm(type); - this.compression = compressionAlgorithm != null; - synchronized (h) { - objectId = getNewObjectId(h); - fileName = getFileNamePrefix(h.getDatabasePath(), objectId) + Constants.SUFFIX_TEMP_FILE; - tempFile = h.openFile(fileName, "rw", false); - tempFile.autoDelete(); - } - FileStoreOutputStream out = new FileStoreOutputStream(tempFile, h, compressionAlgorithm); - return out; - } - - private void createFromStream(byte[] buff, int len, InputStream in, long remaining, DataHandler h) { - try { - FileStoreOutputStream out = initLarge(h); - boolean compress = h.getLobCompressionAlgorithm(Value.BLOB) != null; - try { - while (true) { - precision += len; - out.write(buff, 0, len); - remaining -= len; - if (remaining <= 0) { - break; - } - len = getBufferSize(h, compress, remaining); - len = IOUtils.readFully(in, buff, 0, len); - if (len <= 0) { - break; - } - } - } finally { - out.close(); - } - } catch (IOException e) { - throw DbException.convertIOException(e, null); - } - } - - /** - * Convert a lob to another data type. The data is fully read in memory - * except when converting to BLOB or CLOB. - * - * @param t the new type - * @return the converted value - */ - public Value convertTo(int t) { - if (t == type) { - return this; - } else if (t == Value.CLOB) { - ValueLob copy = ValueLob.createClob(getReader(), -1, handler); - return copy; - } else if (t == Value.BLOB) { - ValueLob copy = ValueLob.createBlob(getInputStream(), -1, handler); - return copy; - } - return super.convertTo(t); - } - - public boolean isLinked() { - return linked; - } - - /** - * Get the current file name where the lob is saved. - * - * @return the file name or null - */ - public String getFileName() { - return fileName; - } - - public void close() { - if (fileName != null) { - if (tempFile != null) { - tempFile.stopAutoDelete(); - } - deleteFile(handler, fileName); - } - } - - public void unlink() { - if (linked && fileName != null) { - String temp; - // synchronize on the database, to avoid concurrent temp file - // creation / deletion / backup - synchronized (handler) { - temp = getFileName(handler, -1, objectId); - deleteFile(handler, temp); - renameFile(handler, fileName, temp); - tempFile = FileStore.open(handler, temp, "rw"); - tempFile.autoDelete(); - tempFile.closeSilently(); - fileName = temp; - linked = false; - } - } - } - - public Value link(DataHandler h, int tabId) { - if (fileName == null) { - this.tableId = tabId; - return this; - } - if (linked) { - ValueLob copy = ValueLob.copy(this); - copy.objectId = getNewObjectId(h); - copy.tableId = tabId; - String live = getFileName(h, copy.tableId, copy.objectId); - copyFileTo(h, fileName, live); - copy.fileName = live; - copy.linked = true; - return copy; - } - if (!linked) { - this.tableId = tabId; - String live = getFileName(h, tableId, objectId); - if (tempFile != null) { - tempFile.stopAutoDelete(); - tempFile = null; - } - renameFile(h, fileName, live); - fileName = live; - linked = true; - } - return this; - } - - /** - * Get the current table id of this lob. - * - * @return the table id - */ - public int getTableId() { - return tableId; - } - - /** - * Get the current object id of this lob. - * - * @return the object id - */ - public int getObjectId() { - return objectId; - } - - public int getType() { - return type; - } - - public long getPrecision() { - return precision; - } - - public String getString() { - int len = precision > Integer.MAX_VALUE || precision == 0 ? Integer.MAX_VALUE : (int) precision; - try { - if (type == Value.CLOB) { - if (small != null) { - return StringUtils.utf8Decode(small); - } - return IOUtils.readStringAndClose(getReader(), len); - } - byte[] buff; - if (small != null) { - buff = small; - } else { - buff = IOUtils.readBytesAndClose(getInputStream(), len); - } - return Utils.convertBytesToString(buff); - } catch (IOException e) { - throw DbException.convertIOException(e, fileName); - } - } - - public byte[] getBytes() { - if (type == CLOB) { - // convert hex to string - return super.getBytes(); - } - byte[] data = getBytesNoCopy(); - return Utils.cloneByteArray(data); - } - - public byte[] getBytesNoCopy() { - if (type == CLOB) { - // convert hex to string - return super.getBytesNoCopy(); - } - if (small != null) { - return small; - } - try { - return IOUtils.readBytesAndClose(getInputStream(), Integer.MAX_VALUE); - } catch (IOException e) { - throw DbException.convertIOException(e, fileName); - } - } - - public int hashCode() { - if (hash == 0) { - if (precision > 4096) { - // TODO: should calculate the hash code when saving, and store - // it in the database file - return (int) (precision ^ (precision >>> 32)); - } - if (type == CLOB) { - hash = getString().hashCode(); - } else { - hash = Utils.getByteArrayHash(getBytes()); - } - } - return hash; - } - - protected int compareSecure(Value v, CompareMode mode) { - if (type == Value.CLOB) { - return Integer.signum(getString().compareTo(v.getString())); - } - byte[] v2 = v.getBytesNoCopy(); - return Utils.compareNotNull(getBytes(), v2); - } - - public Object getObject() { - if (type == Value.CLOB) { - return getReader(); - } - return getInputStream(); - } - - public Reader getReader() { - return IOUtils.getReader(getInputStream()); - } - - public InputStream getInputStream() { - if (fileName == null) { - return new ByteArrayInputStream(small); - } - FileStore store = handler.openFile(fileName, "r", true); - boolean alwaysClose = SysProperties.lobCloseBetweenReads; - return new BufferedInputStream(new FileStoreInputStream(store, handler, compression, alwaysClose), - Constants.IO_BUFFER_SIZE); - } - - public void set(PreparedStatement prep, int parameterIndex) throws SQLException { - long p = getPrecision(); - if (p > Integer.MAX_VALUE || p <= 0) { - p = -1; - } - if (type == Value.BLOB) { - prep.setBinaryStream(parameterIndex, getInputStream(), (int) p); - } else { - prep.setCharacterStream(parameterIndex, getReader(), (int) p); - } - } - - public String getSQL() { - String s; - if (type == Value.CLOB) { - s = getString(); - return StringUtils.quoteStringSQL(s); - } - byte[] buff = getBytes(); - s = Utils.convertBytesToString(buff); - return "X'" + s + "'"; - } - - public String getTraceSQL() { - if (small != null && getPrecision() <= SysProperties.MAX_TRACE_DATA_LENGTH) { - return getSQL(); - } - StringBuilder buff = new StringBuilder(); - if (type == Value.CLOB) { - buff.append("SPACE(").append(getPrecision()); - } else { - buff.append("CAST(REPEAT('00', ").append(getPrecision()).append(") AS BINARY"); - } - buff.append(" /* ").append(fileName).append(" */)"); - return buff.toString(); - } - - /** - * Get the data if this a small lob value. - * - * @return the data - */ - public byte[] getSmall() { - return small; - } - - public int getDisplaySize() { - return MathUtils.convertLongToInt(getPrecision()); - } - - public boolean equals(Object other) { - return other instanceof ValueLob && compareSecure((Value) other, null) == 0; - } - - /** - * Store the lob data to a file if the size of the buffer it larger than the - * maximum size for an in-place lob. - * - * @param h the data handler - */ - public void convertToFileIfRequired(DataHandler h) { - if (small != null && small.length > h.getMaxLengthInplaceLob()) { - boolean compress = h.getLobCompressionAlgorithm(type) != null; - int len = getBufferSize(h, compress, Long.MAX_VALUE); - int tabId = tableId; - if (type == Value.BLOB) { - createFromStream(Utils.newBytes(len), 0, getInputStream(), Long.MAX_VALUE, h); - } else { - createFromReader(new char[len], 0, getReader(), Long.MAX_VALUE, h); - } - Value v2 = link(h, tabId); - if (SysProperties.CHECK && v2 != this) { - DbException.throwInternalError(); - } - } - } - - /** - * Remove all lobs for a given table id. - * - * @param handler the data handler - * @param tableId the table id - */ - public static void removeAllForTable(DataHandler handler, int tableId) { - String dir = getFileNamePrefix(handler.getDatabasePath(), 0); - removeAllForTable(handler, dir, tableId); - } - - private static void removeAllForTable(DataHandler handler, String dir, int tableId) { - for (String name : IOUtils.listFiles(dir)) { - if (IOUtils.isDirectory(name)) { - removeAllForTable(handler, name, tableId); - } else { - if (name.endsWith(".t" + tableId + Constants.SUFFIX_LOB_FILE)) { - deleteFile(handler, name); - } - } - } - } - - /** - * Check if this lob value is compressed. - * - * @return true if it is - */ - public boolean useCompression() { - return compression; - } - - public boolean isFileBased() { - return fileName != null; - } - - private static synchronized void deleteFile(DataHandler handler, String fileName) { - // synchronize on the database, to avoid concurrent temp file creation / - // deletion / backup - synchronized (handler.getLobSyncObject()) { - IOUtils.delete(fileName); - } - } - - private static synchronized void renameFile(DataHandler handler, String oldName, String newName) - { - synchronized (handler.getLobSyncObject()) { - IOUtils.rename(oldName, newName); - } - } - - private void copyFileTo(DataHandler h, String sourceFileName, String targetFileName) { - synchronized (h.getLobSyncObject()) { - FileSystem.getInstance(sourceFileName).copy(sourceFileName, targetFileName); - } - } - - /** - * Set the file name of this lob value. - * - * @param fileName the file name - * @param linked if the lob is linked - */ - public void setFileName(String fileName, boolean linked) { - this.fileName = fileName; - this.linked = linked; - } - - public int getMemory() { - if (small != null) { - return small.length + 64; - } - return 128; - } - - /** - * Create an independent copy of this temporary value. - * The file will not be deleted automatically. - * - * @return the value - */ - public ValueLob copyToTemp() { - ValueLob lob; - if (type == CLOB) { - lob = ValueLob.createClob(getReader(), precision, handler); - } else { - lob = ValueLob.createBlob(getInputStream(), precision, handler); - } - return lob; - } - -} diff --git a/tools/h2/src/main/org/h2/value/ValueLobDb.java b/tools/h2/src/main/org/h2/value/ValueLobDb.java deleted file mode 100755 index e5cdbcd..0000000 --- a/tools/h2/src/main/org/h2/value/ValueLobDb.java +++ /dev/null @@ -1,534 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.value; - -import java.io.BufferedInputStream; -import java.io.ByteArrayInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.Reader; -import java.sql.PreparedStatement; -import java.sql.SQLException; -import org.h2.constant.SysProperties; -import org.h2.engine.Constants; -import org.h2.message.DbException; -import org.h2.store.DataHandler; -import org.h2.store.FileStore; -import org.h2.store.FileStoreInputStream; -import org.h2.store.FileStoreOutputStream; -import org.h2.store.LobStorage; -import org.h2.util.IOUtils; -import org.h2.util.MathUtils; -import org.h2.util.StringUtils; -import org.h2.util.Utils; - -/** - * An alternate LOB implementation. - */ -public class ValueLobDb extends Value implements Value.ValueClob, Value.ValueBlob { - - private final int type; - private long precision; - private int tableId; - private int hash; - - private LobStorage lobStorage; - private long lobId; - - private byte[] small; - - private DataHandler handler; - private FileStore tempFile; - private String fileName; - - private ValueLobDb(int type, LobStorage lobStorage, String fileName, int tableId, long lobId, long precision) { - this.type = type; - this.lobStorage = lobStorage; - this.fileName = fileName; - this.tableId = tableId; - this.lobId = lobId; - this.precision = precision; - } - - private ValueLobDb(int type, byte[] small, long precision) { - this.type = type; - this.small = small; - this.precision = precision; - } - - /** - * Create a LOB value. - * - * @param type the type - * @param lobStorage the storage - * @param fileName the file name (may be null) - * @param tableId the table id - * @param id the lob id - * @param precision the precision (number of bytes / characters) - * @return the value - */ - public static ValueLobDb create(int type, LobStorage lobStorage, String fileName, int tableId, long id, long precision) { - return new ValueLobDb(type, lobStorage, fileName, tableId, id, precision); - } - - /** - * Create a small lob using the given byte array. - * - * @param type the type (Value.BLOB or CLOB) - * @param small the byte array - * @param precision the precision - * @return the lob value - */ - public static ValueLobDb createSmallLob(int type, byte[] small, long precision) { - return new ValueLobDb(type, small, precision); - } - - /** - * Convert a lob to another data type. The data is fully read in memory - * except when converting to BLOB or CLOB. - * - * @param t the new type - * @return the converted value - */ - public Value convertTo(int t) { - if (t == type) { - return this; - } else if (t == Value.CLOB) { - if (lobStorage != null) { - Value copy = lobStorage.createClob(getReader(), -1); - return copy; - } - } else if (t == Value.BLOB) { - if (lobStorage != null) { - Value copy = lobStorage.createBlob(getInputStream(), -1); - return copy; - } - } - return super.convertTo(t); - } - - public boolean isLinked() { - return tableId != LobStorage.TABLE_ID_SESSION_VARIABLE; - } - - public void close() { - if (fileName != null) { - if (tempFile != null) { - tempFile.stopAutoDelete(); - } - deleteFile(handler, fileName); - } - } - - private static synchronized void deleteFile(DataHandler handler, String fileName) { - // synchronize on the database, to avoid concurrent temp file creation / - // deletion / backup - synchronized (handler.getLobSyncObject()) { - IOUtils.delete(fileName); - } - } - - public void unlink() { - if (small == null && tableId != LobStorage.TABLE_ID_SESSION_VARIABLE) { - lobStorage.setTable(lobId, LobStorage.TABLE_ID_SESSION_VARIABLE); - tableId = LobStorage.TABLE_ID_SESSION_VARIABLE; - } - } - - public Value link(DataHandler h, int tabId) { - if (small == null) { - if (tabId != tableId) { - if (tableId != LobStorage.TABLE_TEMP) { - return lobStorage.copyLob(type, lobId, tabId, getPrecision()); - } - lobStorage.setTable(lobId, tabId); - this.tableId = tabId; - } - } else if (small.length > h.getMaxLengthInplaceLob()) { - LobStorage s = h.getLobStorage(); - Value v; - if (type == Value.BLOB) { - v = s.createBlob(getInputStream(), getPrecision()); - } else { - v = s.createClob(getReader(), getPrecision()); - } - return v.link(h, tabId); - } - return this; - } - - /** - * Get the current table id of this lob. - * - * @return the table id - */ - public int getTableId() { - return tableId; - } - - public int getType() { - return type; - } - - public long getPrecision() { - return precision; - } - - public String getString() { - int len = precision > Integer.MAX_VALUE || precision == 0 ? Integer.MAX_VALUE : (int) precision; - try { - if (type == Value.CLOB) { - if (small != null) { - return StringUtils.utf8Decode(small); - } - return IOUtils.readStringAndClose(getReader(), len); - } - byte[] buff; - if (small != null) { - buff = small; - } else { - buff = IOUtils.readBytesAndClose(getInputStream(), len); - } - return Utils.convertBytesToString(buff); - } catch (IOException e) { - throw DbException.convertIOException(e, toString()); - } - } - - public byte[] getBytes() { - if (type == CLOB) { - // convert hex to string - return super.getBytes(); - } - byte[] data = getBytesNoCopy(); - return Utils.cloneByteArray(data); - } - - public byte[] getBytesNoCopy() { - if (type == CLOB) { - // convert hex to string - return super.getBytesNoCopy(); - } - if (small != null) { - return small; - } - try { - return IOUtils.readBytesAndClose(getInputStream(), Integer.MAX_VALUE); - } catch (IOException e) { - throw DbException.convertIOException(e, toString()); - } - } - - public int hashCode() { - if (hash == 0) { - if (precision > 4096) { - // TODO: should calculate the hash code when saving, and store - // it in the database file - return (int) (precision ^ (precision >>> 32)); - } - if (type == CLOB) { - hash = getString().hashCode(); - } else { - hash = Utils.getByteArrayHash(getBytes()); - } - } - return hash; - } - - protected int compareSecure(Value v, CompareMode mode) { - if (type == Value.CLOB) { - return Integer.signum(getString().compareTo(v.getString())); - } - byte[] v2 = v.getBytesNoCopy(); - return Utils.compareNotNull(getBytes(), v2); - } - - public Object getObject() { - if (type == Value.CLOB) { - return getReader(); - } - return getInputStream(); - } - - public Reader getReader() { - return IOUtils.getReader(getInputStream()); - } - - public InputStream getInputStream() { - if (small != null) { - return new ByteArrayInputStream(small); - } else if (fileName != null) { - FileStore store = handler.openFile(fileName, "r", true); - boolean alwaysClose = SysProperties.lobCloseBetweenReads; - return new BufferedInputStream(new FileStoreInputStream(store, handler, false, alwaysClose), - Constants.IO_BUFFER_SIZE); - } - try { - return lobStorage.getInputStream(lobId); - } catch (IOException e) { - throw DbException.convertIOException(e, toString()); - } - } - - public void set(PreparedStatement prep, int parameterIndex) throws SQLException { - long p = getPrecision(); - if (p > Integer.MAX_VALUE || p <= 0) { - p = -1; - } - if (type == Value.BLOB) { - prep.setBinaryStream(parameterIndex, getInputStream(), (int) p); - } else { - prep.setCharacterStream(parameterIndex, getReader(), (int) p); - } - } - - public String getSQL() { - String s; - if (type == Value.CLOB) { - s = getString(); - return StringUtils.quoteStringSQL(s); - } - byte[] buff = getBytes(); - s = Utils.convertBytesToString(buff); - return "X'" + s + "'"; - } - - public String getTraceSQL() { - if (small != null && getPrecision() <= SysProperties.MAX_TRACE_DATA_LENGTH) { - return getSQL(); - } - StringBuilder buff = new StringBuilder(); - if (type == Value.CLOB) { - buff.append("SPACE(").append(getPrecision()); - } else { - buff.append("CAST(REPEAT('00', ").append(getPrecision()).append(") AS BINARY"); - } - buff.append(" /* table: ").append(tableId).append(" id: ").append(lobId).append(" */)"); - return buff.toString(); - } - - /** - * Get the data if this a small lob value. - * - * @return the data - */ - public byte[] getSmall() { - return small; - } - - public int getDisplaySize() { - return MathUtils.convertLongToInt(getPrecision()); - } - - public boolean equals(Object other) { - return other instanceof ValueLob && compareSecure((Value) other, null) == 0; - } - - public boolean isFileBased() { - return small == null; - } - - public int getMemory() { - if (small != null) { - return small.length + 64; - } - return 128; - } - - /** - * Create an independent copy of this temporary value. - * The file will not be deleted automatically. - * - * @return the value - */ - public ValueLobDb copyToTemp() { - return this; - } - - public long getLobId() { - return lobId; - } - - public void setPrecision(long precision) { - this.precision = precision; - } - - public String toString() { - return "lob: " + fileName + " table: " + tableId + " id: " + lobId; - } - - /** - * Create a temporary CLOB value from a stream. - * - * @param in the reader - * @param length the number of characters to read, or -1 for no limit - * @param handler the data handler - * @return the lob value - */ - public static ValueLobDb createTempClob(Reader in, long length, DataHandler handler) { - try { - boolean compress = handler.getLobCompressionAlgorithm(Value.CLOB) != null; - long remaining = Long.MAX_VALUE; - if (length >= 0 && length < remaining) { - remaining = length; - } - int len = getBufferSize(handler, compress, remaining); - char[] buff; - if (len >= Integer.MAX_VALUE) { - String data = IOUtils.readStringAndClose(in, -1); - buff = data.toCharArray(); - len = buff.length; - } else { - buff = new char[len]; - len = IOUtils.readFully(in, buff, len); - len = len < 0 ? 0 : len; - } - if (len <= handler.getMaxLengthInplaceLob()) { - byte[] small = StringUtils.utf8Encode(new String(buff, 0, len)); - return ValueLobDb.createSmallLob(Value.CLOB, small, len); - } - ValueLobDb lob = new ValueLobDb(Value.CLOB, null, 0); - lob.createTempFromReader(buff, len, in, remaining, handler); - return lob; - } catch (IOException e) { - throw DbException.convertIOException(e, null); - } - } - - /** - * Create a temporary BLOB value from a stream. - * - * @param in the input stream - * @param length the number of characters to read, or -1 for no limit - * @param handler the data handler - * @return the lob value - */ - public static ValueLobDb createTempBlob(InputStream in, long length, DataHandler handler) { - try { - long remaining = Long.MAX_VALUE; - boolean compress = handler.getLobCompressionAlgorithm(Value.BLOB) != null; - if (length >= 0 && length < remaining) { - remaining = length; - } - int len = getBufferSize(handler, compress, remaining); - byte[] buff; - if (len >= Integer.MAX_VALUE) { - buff = IOUtils.readBytesAndClose(in, -1); - len = buff.length; - } else { - buff = Utils.newBytes(len); - len = IOUtils.readFully(in, buff, 0, len); - } - if (len <= handler.getMaxLengthInplaceLob()) { - byte[] small = Utils.newBytes(len); - System.arraycopy(buff, 0, small, 0, len); - return ValueLobDb.createSmallLob(Value.BLOB, small, small.length); - } - ValueLobDb lob = new ValueLobDb(Value.BLOB, null, 0); - lob.createTempFromStream(buff, len, in, remaining, handler); - return lob; - } catch (IOException e) { - throw DbException.convertIOException(e, null); - } - } - - private void createTempFromReader(char[] buff, int len, Reader in, long remaining, DataHandler h) { - try { - FileStoreOutputStream out = initTemp(h); - try { - while (true) { - precision += len; - byte[] b = StringUtils.utf8Encode(new String(buff, 0, len)); - out.write(b, 0, b.length); - remaining -= len; - if (remaining <= 0) { - break; - } - len = getBufferSize(h, false, remaining); - len = IOUtils.readFully(in, buff, len); - if (len <= 0) { - break; - } - } - } finally { - out.close(); - } - } catch (IOException e) { - throw DbException.convertIOException(e, null); - } - } - - private void createTempFromStream(byte[] buff, int len, InputStream in, long remaining, DataHandler h) { - try { - FileStoreOutputStream out = initTemp(h); - boolean compress = h.getLobCompressionAlgorithm(Value.BLOB) != null; - try { - while (true) { - precision += len; - out.write(buff, 0, len); - remaining -= len; - if (remaining <= 0) { - break; - } - len = getBufferSize(h, compress, remaining); - len = IOUtils.readFully(in, buff, 0, len); - if (len <= 0) { - break; - } - } - } finally { - out.close(); - } - } catch (IOException e) { - throw DbException.convertIOException(e, null); - } - } - - private FileStoreOutputStream initTemp(DataHandler h) { - this.precision = 0; - this.handler = h; - this.lobStorage = h.getLobStorage(); - this.small = null; - try { - String path = h.getDatabasePath(); - if (path.length() == 0) { - path = SysProperties.PREFIX_TEMP_FILE; - } - fileName = IOUtils.createTempFile(path, Constants.SUFFIX_TEMP_FILE, true, true); - } catch (IOException e) { - throw DbException.convertIOException(e, null); - } - tempFile = h.openFile(fileName, "rw", false); - tempFile.autoDelete(); - FileStoreOutputStream out = new FileStoreOutputStream(tempFile, null, null); - return out; - } - - private static int getBufferSize(DataHandler handler, boolean compress, long remaining) { - if (remaining < 0 || remaining > Integer.MAX_VALUE) { - remaining = Integer.MAX_VALUE; - } - long inplace = handler.getMaxLengthInplaceLob(); - if (inplace >= Integer.MAX_VALUE) { - inplace = remaining; - } - long m = compress ? Constants.IO_BUFFER_SIZE_COMPRESS : Constants.IO_BUFFER_SIZE; - if (m < remaining && m <= inplace) { - m = Math.min(remaining, inplace + 1); - // the buffer size must be bigger than the inplace lob, otherwise we can't - // know if it must be stored in-place or not - m = MathUtils.roundUpLong(m, Constants.IO_BUFFER_SIZE); - } - m = Math.min(remaining, m); - m = MathUtils.convertLongToInt(m); - if (m < 0) { - m = Integer.MAX_VALUE; - } - return (int) m; - } - -} diff --git a/tools/h2/src/main/org/h2/value/ValueLong.java b/tools/h2/src/main/org/h2/value/ValueLong.java deleted file mode 100755 index 4401ae4..0000000 --- a/tools/h2/src/main/org/h2/value/ValueLong.java +++ /dev/null @@ -1,198 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.value; - -import java.math.BigDecimal; -import java.math.BigInteger; -import java.sql.PreparedStatement; -import java.sql.SQLException; -import org.h2.constant.ErrorCode; -import org.h2.message.DbException; -import org.h2.util.MathUtils; - -/** - * Implementation of the BIGINT data type. - */ -public class ValueLong extends Value { - - /** - * The largest Long value, as a BigInteger. - */ - public static final BigInteger MAX = BigInteger.valueOf(Long.MAX_VALUE); - - /** - * The smallest Long value, as a BigDecimal. - */ - public static final BigDecimal MIN_BD = BigDecimal.valueOf(Long.MIN_VALUE); - - /** - * The precision in digits. - */ - public static final int PRECISION = 19; - - /** - * The maximum display size of a long. - * Example: 9223372036854775808 - */ - public static final int DISPLAY_SIZE = 20; - - private static final BigInteger MIN = BigInteger.valueOf(Long.MIN_VALUE); - private static final int STATIC_SIZE = 100; - private static final ValueLong[] STATIC_CACHE; - - private final long value; - - static { - STATIC_CACHE = new ValueLong[STATIC_SIZE]; - for (int i = 0; i < STATIC_SIZE; i++) { - STATIC_CACHE[i] = new ValueLong(i); - } - } - - private ValueLong(long value) { - this.value = value; - } - - public Value add(Value v) { - ValueLong other = (ValueLong) v; - long result = value + other.value; - int sv = Long.signum(value); - int so = Long.signum(other.value); - int sr = Long.signum(result); - // if the operands have different signs overflow can not occur - // if the operands have the same sign, - // and the result has a different sign, then it is an overflow - // it can not be an overflow when one of the operands is 0 - if (sv != so || sr == so || sv == 0 || so == 0) { - return ValueLong.get(result); - } - throw getOverflow(); - } - - public int getSignum() { - return Long.signum(value); - } - - public Value negate() { - if (value == Long.MIN_VALUE) { - throw getOverflow(); - } - return ValueLong.get(-value); - } - - private DbException getOverflow() { - return DbException.get(ErrorCode.OVERFLOW_FOR_TYPE_1, DataType.getDataType(Value.LONG).name); - } - - public Value subtract(Value v) { - ValueLong other = (ValueLong) v; - int sv = Long.signum(value); - int so = Long.signum(other.value); - // if the operands have the same sign, then overflow can not occur - // if the second operand is 0, then overflow can not occur - if (sv == so || so == 0) { - return ValueLong.get(value - other.value); - } - // now, if the other value is Long.MIN_VALUE, it must be an overflow - // x - Long.MIN_VALUE overflows for x>=0 - return add(other.negate()); - } - - private boolean isInteger(long a) { - return a >= Integer.MIN_VALUE && a <= Integer.MAX_VALUE; - } - - public Value multiply(Value v) { - ValueLong other = (ValueLong) v; - long result = value * other.value; - if (value == 0 || value == 1 || other.value == 0 || other.value == 1) { - return ValueLong.get(result); - } - if (isInteger(value) && isInteger(other.value)) { - return ValueLong.get(result); - } - // just checking one case is not enough: Long.MIN_VALUE * -1 - // probably this is correct but I'm not sure - // if(result / value == other.value && result / other.value == value) { - // return ValueLong.get(result); - //} - BigInteger bv = BigInteger.valueOf(value); - BigInteger bo = BigInteger.valueOf(other.value); - BigInteger br = bv.multiply(bo); - if (br.compareTo(MIN) < 0 || br.compareTo(MAX) > 0) { - throw getOverflow(); - } - return ValueLong.get(br.longValue()); - } - - public Value divide(Value v) { - ValueLong other = (ValueLong) v; - if (other.value == 0) { - throw DbException.get(ErrorCode.DIVISION_BY_ZERO_1, getSQL()); - } - return ValueLong.get(value / other.value); - } - - public String getSQL() { - return getString(); - } - - public int getType() { - return Value.LONG; - } - - public long getLong() { - return value; - } - - protected int compareSecure(Value o, CompareMode mode) { - ValueLong v = (ValueLong) o; - return MathUtils.compareLong(value, v.value); - } - - public String getString() { - return String.valueOf(value); - } - - public long getPrecision() { - return PRECISION; - } - - public int hashCode() { - return (int) (value ^ (value >> 32)); - } - - public Object getObject() { - return value; - } - - public void set(PreparedStatement prep, int parameterIndex) throws SQLException { - prep.setLong(parameterIndex, value); - } - - /** - * Get or create a long value for the given long. - * - * @param i the long - * @return the value - */ - public static ValueLong get(long i) { - if (i >= 0 && i < STATIC_SIZE) { - return STATIC_CACHE[(int) i]; - } - return (ValueLong) Value.cache(new ValueLong(i)); - } - - public int getDisplaySize() { - return DISPLAY_SIZE; - } - - public boolean equals(Object other) { - return other instanceof ValueLong && value == ((ValueLong) other).value; - } - -} diff --git a/tools/h2/src/main/org/h2/value/ValueNull.java b/tools/h2/src/main/org/h2/value/ValueNull.java deleted file mode 100755 index cc21a85..0000000 --- a/tools/h2/src/main/org/h2/value/ValueNull.java +++ /dev/null @@ -1,150 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.value; - -import java.io.InputStream; -import java.io.Reader; -import java.math.BigDecimal; -import java.sql.Date; -import java.sql.PreparedStatement; -import java.sql.SQLException; -import java.sql.Time; -import java.sql.Timestamp; - -import org.h2.message.DbException; - -/** - * Implementation of NULL. NULL is not a regular data type. - */ -public class ValueNull extends Value { - - /** - * The main NULL instance. - */ - public static final ValueNull INSTANCE = new ValueNull(); - - /** - * This special instance is used as a marker for deleted entries in a map. - * It should not be used anywhere else. - */ - public static final ValueNull DELETED = new ValueNull(); - - /** - * The precision of NULL. - */ - private static final int PRECISION = 1; - - /** - * The display size of the textual representation of NULL. - */ - private static final int DISPLAY_SIZE = 4; - - private ValueNull() { - // don't allow construction - } - - public String getSQL() { - return "NULL"; - } - - public int getType() { - return Value.NULL; - } - - public String getString() { - return null; - } - - public Boolean getBoolean() { - return null; - } - - public Date getDate() { - return null; - } - - public Time getTime() { - return null; - } - - public Timestamp getTimestamp() { - return null; - } - - public byte[] getBytes() { - return null; - } - - public byte getByte() { - return 0; - } - - public short getShort() { - return 0; - } - - public BigDecimal getBigDecimal() { - return null; - } - - public double getDouble() { - return 0.0; - } - - public float getFloat() { - return 0.0F; - } - - public int getInt() { - return 0; - } - - public long getLong() { - return 0; - } - - public InputStream getInputStream() { - return null; - } - - public Reader getReader() { - return null; - } - - public Value convertTo(int type) { - return this; - } - - protected int compareSecure(Value v, CompareMode mode) { - throw DbException.throwInternalError("compare null"); - } - - public long getPrecision() { - return PRECISION; - } - - public int hashCode() { - return 0; - } - - public Object getObject() { - return null; - } - - public void set(PreparedStatement prep, int parameterIndex) throws SQLException { - prep.setNull(parameterIndex, DataType.convertTypeToSQLType(Value.NULL)); - } - - public int getDisplaySize() { - return DISPLAY_SIZE; - } - - public boolean equals(Object other) { - return other == this; - } - -} diff --git a/tools/h2/src/main/org/h2/value/ValueResultSet.java b/tools/h2/src/main/org/h2/value/ValueResultSet.java deleted file mode 100755 index 34b70a2..0000000 --- a/tools/h2/src/main/org/h2/value/ValueResultSet.java +++ /dev/null @@ -1,144 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.value; - -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.ResultSetMetaData; -import java.sql.SQLException; - -import org.h2.message.DbException; -import org.h2.tools.SimpleResultSet; -import org.h2.util.StatementBuilder; - -/** - * Implementation of the RESULT_SET data type. - */ -public class ValueResultSet extends Value { - - private final ResultSet result; - - private ValueResultSet(ResultSet rs) { - this.result = rs; - } - - /** - * Create a result set value for the given result set. - * The result set will be wrapped. - * - * @param rs the result set - * @return the value - */ - public static ValueResultSet get(ResultSet rs) { - ValueResultSet val = new ValueResultSet(rs); - return val; - } - - /** - * Create a result set value for the given result set. The result set will - * be fully read in memory. The original result set is not closed. - * - * @param rs the result set - * @param maxrows the maximum number of rows to read (0 to just read the - * meta data) - * @return the value - */ - public static ValueResultSet getCopy(ResultSet rs, int maxrows) { - try { - ResultSetMetaData meta = rs.getMetaData(); - int columnCount = meta.getColumnCount(); - SimpleResultSet simple = new SimpleResultSet(); - ValueResultSet val = new ValueResultSet(simple); - for (int i = 0; i < columnCount; i++) { - String name = meta.getColumnLabel(i + 1); - int sqlType = meta.getColumnType(i + 1); - int precision = meta.getPrecision(i + 1); - int scale = meta.getScale(i + 1); - simple.addColumn(name, sqlType, precision, scale); - } - for (int i = 0; i < maxrows && rs.next(); i++) { - Object[] list = new Object[columnCount]; - for (int j = 0; j < columnCount; j++) { - list[j] = rs.getObject(j + 1); - } - simple.addRow(list); - } - return val; - } catch (SQLException e) { - throw DbException.convert(e); - } - } - - public int getType() { - return Value.RESULT_SET; - } - - public long getPrecision() { - return 0; - } - - public int getDisplaySize() { - // it doesn't make sense to calculate it - return Integer.MAX_VALUE; - } - - public String getString() { - try { - StatementBuilder buff = new StatementBuilder("("); - result.beforeFirst(); - ResultSetMetaData meta = result.getMetaData(); - int columnCount = meta.getColumnCount(); - for (int i = 0; result.next(); i++) { - if (i > 0) { - buff.append(", "); - } - buff.append('('); - buff.resetCount(); - for (int j = 0; j < columnCount; j++) { - buff.appendExceptFirst(", "); - int t = DataType.convertSQLTypeToValueType(meta.getColumnType(j + 1)); - Value v = DataType.readValue(null, result, j+1, t); - buff.append(v.getString()); - } - buff.append(')'); - } - result.beforeFirst(); - return buff.append(')').toString(); - } catch (SQLException e) { - throw DbException.convert(e); - } - } - - protected int compareSecure(Value v, CompareMode mode) { - throw throwUnsupportedExceptionForType("<=>"); - } - - public boolean equals(Object other) { - return other == this; - } - - public int hashCode() { - return 0; - } - - public Object getObject() { - return result; - } - - public ResultSet getResultSet() { - return result; - } - - public void set(PreparedStatement prep, int parameterIndex) { - throw throwUnsupportedExceptionForType("PreparedStatement.set"); - } - - public String getSQL() { - return ""; - } - -} diff --git a/tools/h2/src/main/org/h2/value/ValueShort.java b/tools/h2/src/main/org/h2/value/ValueShort.java deleted file mode 100755 index e6d31f3..0000000 --- a/tools/h2/src/main/org/h2/value/ValueShort.java +++ /dev/null @@ -1,130 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.value; - -import java.sql.PreparedStatement; -import java.sql.SQLException; -import org.h2.constant.ErrorCode; -import org.h2.message.DbException; -import org.h2.util.MathUtils; - -/** - * Implementation of the SMALLINT data type. - */ -public class ValueShort extends Value { - - /** - * The precision in digits. - */ - static final int PRECISION = 5; - - /** - * The maximum display size of a short. - * Example: -32768 - */ - static final int DISPLAY_SIZE = 6; - - private final short value; - - private ValueShort(short value) { - this.value = value; - } - - public Value add(Value v) { - ValueShort other = (ValueShort) v; - return checkRange(value + other.value); - } - - private ValueShort checkRange(int x) { - if (x < Short.MIN_VALUE || x > Short.MAX_VALUE) { - throw DbException.get(ErrorCode.OVERFLOW_FOR_TYPE_1, DataType.getDataType(Value.SHORT).name); - } - return ValueShort.get((short) x); - } - - public int getSignum() { - return Integer.signum(value); - } - - public Value negate() { - return checkRange(-(int) value); - } - - public Value subtract(Value v) { - ValueShort other = (ValueShort) v; - return checkRange(value - other.value); - } - - public Value multiply(Value v) { - ValueShort other = (ValueShort) v; - return checkRange(value * other.value); - } - - public Value divide(Value v) { - ValueShort other = (ValueShort) v; - if (other.value == 0) { - throw DbException.get(ErrorCode.DIVISION_BY_ZERO_1, getSQL()); - } - return ValueShort.get((short) (value / other.value)); - } - - public String getSQL() { - return getString(); - } - - public int getType() { - return Value.SHORT; - } - - public short getShort() { - return value; - } - - protected int compareSecure(Value o, CompareMode mode) { - ValueShort v = (ValueShort) o; - return MathUtils.compareInt(value, v.value); - } - - public String getString() { - return String.valueOf(value); - } - - public long getPrecision() { - return PRECISION; - } - - public int hashCode() { - return value; - } - - public Object getObject() { - return Short.valueOf(value); - } - - public void set(PreparedStatement prep, int parameterIndex) throws SQLException { - prep.setShort(parameterIndex, value); - } - - /** - * Get or create a short value for the given short. - * - * @param i the short - * @return the value - */ - public static ValueShort get(short i) { - return (ValueShort) Value.cache(new ValueShort(i)); - } - - public int getDisplaySize() { - return DISPLAY_SIZE; - } - - public boolean equals(Object other) { - return other instanceof ValueShort && value == ((ValueShort) other).value; - } - -} diff --git a/tools/h2/src/main/org/h2/value/ValueString.java b/tools/h2/src/main/org/h2/value/ValueString.java deleted file mode 100755 index 412695d..0000000 --- a/tools/h2/src/main/org/h2/value/ValueString.java +++ /dev/null @@ -1,143 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.value; - -import java.sql.PreparedStatement; -import java.sql.SQLException; -import org.h2.constant.SysProperties; -import org.h2.util.MathUtils; -import org.h2.util.StringUtils; - -/** - * Implementation of the VARCHAR data type. - * It is also the base class for other ValueString* classes. - */ -public class ValueString extends Value { - - private static final ValueString EMPTY = new ValueString(""); - - /** - * The string data. - */ - protected final String value; - - protected ValueString(String value) { - this.value = value; - } - - public String getSQL() { - return StringUtils.quoteStringSQL(value); - } - - public boolean equals(Object other) { - return other instanceof ValueString && value.equals(((ValueString) other).value); - } - - protected int compareSecure(Value o, CompareMode mode) { - // compatibility: the other object could be another type - ValueString v = (ValueString) o; - return mode.compareString(value, v.value, false); - } - - public String getString() { - return value; - } - - public long getPrecision() { - return value.length(); - } - - public Object getObject() { - return value; - } - - public void set(PreparedStatement prep, int parameterIndex) throws SQLException { - prep.setString(parameterIndex, value); - } - - public int getDisplaySize() { - return value.length(); - } - - public int getMemory() { - return value.length() * 2 + 30; - } - - public Value convertPrecision(long precision) { - if (precision == 0 || value.length() <= precision) { - return this; - } - int p = MathUtils.convertLongToInt(precision); - return getNew(value.substring(0, p)); - } - - public int hashCode() { - // TODO hash performance: could build a quicker hash - // by hashing the size and a few characters - return value.hashCode(); - - // proposed code: -// private int hash = 0; -// -// public int hashCode() { -// int h = hash; -// if (h == 0) { -// String s = value; -// int l = s.length(); -// if (l > 0) { -// if (l < 16) -// h = s.hashCode(); -// else { -// h = l; -// for (int i = 1; i <= l; i <<= 1) -// h = 31 * -// (31 * h + s.charAt(i - 1)) + -// s.charAt(l - i); -// } -// hash = h; -// } -// } -// return h; -// } - - } - - public int getType() { - return Value.STRING; - } - - /** - * Get or create a string value for the given string. - * - * @param s the string - * @return the value - */ - public static ValueString get(String s) { - if (s.length() == 0) { - return EMPTY; - } - ValueString obj = new ValueString(StringUtils.cache(s)); - if (s.length() > SysProperties.OBJECT_CACHE_MAX_PER_ELEMENT_SIZE) { - return obj; - } - return (ValueString) Value.cache(obj); - // this saves memory, but is really slow - // return new ValueString(s.intern()); - } - - /** - * Create a new String value of the current class. - * This method is meant to be overridden by subclasses. - * - * @param s the string - * @return the value - */ - protected Value getNew(String s) { - return ValueString.get(s); - } - -} diff --git a/tools/h2/src/main/org/h2/value/ValueStringFixed.java b/tools/h2/src/main/org/h2/value/ValueStringFixed.java deleted file mode 100755 index 52e093b..0000000 --- a/tools/h2/src/main/org/h2/value/ValueStringFixed.java +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.value; - -import org.h2.constant.SysProperties; -import org.h2.util.StringUtils; - -/** - * Implementation of the CHAR data type. - */ -public class ValueStringFixed extends ValueString { - - private static final ValueStringFixed EMPTY = new ValueStringFixed(""); - - protected ValueStringFixed(String value) { - super(value); - } - - private static String trimRight(String s) { - int endIndex = s.length() - 1; - int i = endIndex; - while (i >= 0 && s.charAt(i) == ' ') { - i--; - } - s = i == endIndex ? s : s.substring(0, i + 1); - return s; - } - - public int getType() { - return Value.STRING_FIXED; - } - - /** - * Get or create a fixed length string value for the given string. - * Spaces at the end of the string will be removed. - * - * @param s the string - * @return the value - */ - public static ValueStringFixed get(String s) { - s = trimRight(s); - if (s.length() == 0) { - return EMPTY; - } - ValueStringFixed obj = new ValueStringFixed(StringUtils.cache(s)); - if (s.length() > SysProperties.OBJECT_CACHE_MAX_PER_ELEMENT_SIZE) { - return obj; - } - return (ValueStringFixed) Value.cache(obj); - } - - protected Value getNew(String s) { - return ValueString.get(s); - } - -} diff --git a/tools/h2/src/main/org/h2/value/ValueStringIgnoreCase.java b/tools/h2/src/main/org/h2/value/ValueStringIgnoreCase.java deleted file mode 100755 index e392eea..0000000 --- a/tools/h2/src/main/org/h2/value/ValueStringIgnoreCase.java +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.value; - -import org.h2.constant.SysProperties; -import org.h2.util.StringUtils; - -/** - * Implementation of the VARCHAR_IGNORECASE data type. - */ -public class ValueStringIgnoreCase extends ValueString { - - private static final ValueStringIgnoreCase EMPTY = new ValueStringIgnoreCase(""); - private int hash; - - protected ValueStringIgnoreCase(String value) { - super(value); - } - - public int getType() { - return Value.STRING_IGNORECASE; - } - - protected int compareSecure(Value o, CompareMode mode) { - ValueStringIgnoreCase v = (ValueStringIgnoreCase) o; - return mode.compareString(value, v.value, true); - } - - public boolean equals(Object other) { - return other instanceof ValueString && value.equalsIgnoreCase(((ValueString) other).value); - } - - public int hashCode() { - if (hash == 0) { - // this is locale sensitive - hash = value.toUpperCase().hashCode(); - } - return hash; - } - - public String getSQL() { - return "CAST(" + StringUtils.quoteStringSQL(value) + " AS VARCHAR_IGNORECASE)"; - } - - /** - * Get or create a case insensitive string value for the given string. - * The value will have the same case as the passed string. - * - * @param s the string - * @return the value - */ - public static ValueStringIgnoreCase get(String s) { - if (s.length() == 0) { - return EMPTY; - } - ValueStringIgnoreCase obj = new ValueStringIgnoreCase(StringUtils.cache(s)); - if (s.length() > SysProperties.OBJECT_CACHE_MAX_PER_ELEMENT_SIZE) { - return obj; - } - ValueStringIgnoreCase cache = (ValueStringIgnoreCase) Value.cache(obj); - // the cached object could have the wrong case - // (it would still be 'equal', but we don't like to store it) - if (cache.value.equals(s)) { - return cache; - } - return obj; - } - - protected Value getNew(String s) { - return ValueString.get(s); - } - -} diff --git a/tools/h2/src/main/org/h2/value/ValueTime.java b/tools/h2/src/main/org/h2/value/ValueTime.java deleted file mode 100755 index 98a9686..0000000 --- a/tools/h2/src/main/org/h2/value/ValueTime.java +++ /dev/null @@ -1,120 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.value; - -import java.sql.PreparedStatement; -import java.sql.SQLException; -import java.sql.Time; -import org.h2.constant.ErrorCode; -import org.h2.util.DateTimeUtils; - -/** - * Implementation of the TIME data type. - */ -public class ValueTime extends Value { - - /** - * The precision in digits. - */ - public static final int PRECISION = 6; - - /** - * The display size of the textual representation of a time. - * Example: 10:00:00 - */ - static final int DISPLAY_SIZE = 8; - - private final Time value; - - private ValueTime(Time value) { - this.value = value; - } - - /** - * Parse a string to a java.sql.Time object. - * - * @param s the string to parse - * @return the time - */ - public static Time parseTime(String s) { - return (Time) DateTimeUtils.parseDateTime(s, Value.TIME, ErrorCode.TIME_CONSTANT_2); - } - - public Time getTime() { - // this class is mutable - must copy the object - return (Time) value.clone(); - } - - public Time getTimeNoCopy() { - return value; - } - - public String getSQL() { - return "TIME '" + getString() + "'"; - } - - public int getType() { - return Value.TIME; - } - - protected int compareSecure(Value o, CompareMode mode) { - ValueTime v = (ValueTime) o; - return Integer.signum(value.compareTo(v.value)); - } - - public String getString() { - return value.toString(); - } - - public long getPrecision() { - return PRECISION; - } - - public int hashCode() { - return value.hashCode(); - } - - public Object getObject() { - return getTime(); - } - - public void set(PreparedStatement prep, int parameterIndex) throws SQLException { - prep.setTime(parameterIndex, value); - } - - /** - * Get or create a time value for the given time. - * Clone the time. - * - * @param time the time - * @return the value - */ - public static ValueTime get(Time time) { - time = DateTimeUtils.cloneAndNormalizeTime(time); - return getNoCopy(time); - } - - /** - * Get or create a time value for the given time. - * Do not clone the time. - * - * @param time the time - * @return the value - */ - public static ValueTime getNoCopy(Time time) { - return (ValueTime) Value.cache(new ValueTime(time)); - } - - public int getDisplaySize() { - return DISPLAY_SIZE; - } - - public boolean equals(Object other) { - return other instanceof ValueTime && value.equals(((ValueTime) other).value); - } - -} diff --git a/tools/h2/src/main/org/h2/value/ValueTimestamp.java b/tools/h2/src/main/org/h2/value/ValueTimestamp.java deleted file mode 100755 index f6638d8..0000000 --- a/tools/h2/src/main/org/h2/value/ValueTimestamp.java +++ /dev/null @@ -1,183 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.value; - -import java.math.BigDecimal; -import java.sql.PreparedStatement; -import java.sql.SQLException; -import java.sql.Timestamp; -import java.util.Calendar; - -import org.h2.constant.ErrorCode; -import org.h2.message.DbException; -import org.h2.util.DateTimeUtils; -import org.h2.util.MathUtils; - -/** - * Implementation of the TIMESTAMP data type. - */ -public class ValueTimestamp extends Value { - - /** - * The precision in digits. - */ - public static final int PRECISION = 23; - - /** - * The display size of the textual representation of a timestamp. - * Example: 2001-01-01 23:59:59.000 - */ - static final int DISPLAY_SIZE = 23; - - /** - * The default scale for timestamps. - */ - static final int DEFAULT_SCALE = 10; - - /** - * This is used to find out if a date is possibly BC. Because of time zone - * issues (the date is time zone specific), the second day is used. That - * means the value is not exact, but it does not need to be. - */ - static final long YEAR_ONE = java.sql.Date.valueOf("0001-01-02").getTime(); - - /** - * This is used to find out if the year is possibly larger than 9999. - * Because of time zone issues (the date is time zone specific), it's a few - * days before the last day. That means the value is not exact, but it does - * not need to be. - */ - static final long YEAR_9999 = java.sql.Date.valueOf("9999-12-20").getTime(); - - private final Timestamp value; - - private ValueTimestamp(Timestamp value) { - this.value = value; - } - - public Timestamp getTimestamp() { - return (Timestamp) value.clone(); - } - - public Timestamp getTimestampNoCopy() { - return value; - } - - public String getSQL() { - return "TIMESTAMP '" + getString() + "'"; - } - - /** - * Parse a string to a java.sql.Timestamp object. - * - * @param s the string to parse - * @return the timestamp - */ - public static Timestamp parseTimestamp(String s) { - return (Timestamp) DateTimeUtils.parseDateTime(s, Value.TIMESTAMP, ErrorCode.TIMESTAMP_CONSTANT_2); - } - - public int getType() { - return Value.TIMESTAMP; - } - - protected int compareSecure(Value o, CompareMode mode) { - ValueTimestamp v = (ValueTimestamp) o; - return Integer.signum(value.compareTo(v.value)); - } - - public String getString() { - String s = value.toString(); - long time = value.getTime(); - // special case: java.sql.Timestamp doesn't format - // years below year 1 (BC) correctly - if (time < YEAR_ONE) { - int year = DateTimeUtils.getDatePart(value, Calendar.YEAR); - if (year < 1) { - s = year + s.substring(s.indexOf('-')); - } - } - return s; - } - - public long getPrecision() { - return PRECISION; - } - - public int getScale() { - return DEFAULT_SCALE; - } - - public int hashCode() { - return value.hashCode(); - } - - public Object getObject() { - // this class is mutable - must copy the object - return getTimestamp(); - } - - public void set(PreparedStatement prep, int parameterIndex) throws SQLException { - prep.setTimestamp(parameterIndex, value); - } - - /** - * Get or create a timestamp value for the given timestamp. - * Clone the timestamp. - * - * @param timestamp the timestamp - * @return the value - */ - public static ValueTimestamp get(Timestamp timestamp) { - timestamp = (Timestamp) timestamp.clone(); - return getNoCopy(timestamp); - } - - /** - * Get or create a timestamp value for the given timestamp. - * Do not clone the timestamp. - * - * @param timestamp the timestamp - * @return the value - */ - public static ValueTimestamp getNoCopy(Timestamp timestamp) { - return (ValueTimestamp) Value.cache(new ValueTimestamp(timestamp)); - } - - public Value convertScale(boolean onlyToSmallerScale, int targetScale) { - if (targetScale < 0 || targetScale > DEFAULT_SCALE) { - // TODO convertScale for Timestamps: may throw an exception? - throw DbException.getInvalidValueException("" + targetScale, "scale"); - } - int nanos = value.getNanos(); - BigDecimal bd = BigDecimal.valueOf(nanos); - bd = bd.movePointLeft(9); - bd = MathUtils.setScale(bd, targetScale); - bd = bd.movePointRight(9); - int n2 = bd.intValue(); - if (n2 == nanos) { - return this; - } - long t = value.getTime(); - while (n2 >= 1000000000) { - t += 1000; - n2 -= 1000000000; - } - Timestamp t2 = new Timestamp(t); - t2.setNanos(n2); - return ValueTimestamp.getNoCopy(t2); - } - - public int getDisplaySize() { - return DISPLAY_SIZE; - } - - public boolean equals(Object other) { - return other instanceof ValueTimestamp && value.equals(((ValueTimestamp) other).value); - } - -} diff --git a/tools/h2/src/main/org/h2/value/ValueUuid.java b/tools/h2/src/main/org/h2/value/ValueUuid.java deleted file mode 100755 index 57dced5..0000000 --- a/tools/h2/src/main/org/h2/value/ValueUuid.java +++ /dev/null @@ -1,201 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.value; - -import java.sql.PreparedStatement; -import java.sql.SQLException; -import java.util.UUID; - -import org.h2.util.Utils; -import org.h2.util.MathUtils; -import org.h2.util.StringUtils; - -/** - * Implementation of the UUID data type. - */ -public class ValueUuid extends Value { - - /** - * The precision of this value in number of bytes. - */ - private static final int PRECISION = 16; - - /** - * The display size of the textual representation of a UUID. - * Example: cd38d882-7ada-4589-b5fb-7da0ca559d9a - */ - private static final int DISPLAY_SIZE = 36; - - private final long high, low; - - private ValueUuid(long high, long low) { - this.high = high; - this.low = low; - } - - public int hashCode() { - return (int) ((high >>> 32) ^ high ^ (low >>> 32) ^ low); - } - - /** - * Create a new UUID using the pseudo random number generator. - * - * @return the new UUID - */ - public static ValueUuid getNewRandom() { - long high = MathUtils.secureRandomLong(); - long low = MathUtils.secureRandomLong(); - // version 4 (random) - high = (high & (~0xf000L)) | 0x4000L; - // variant (Leach-Salz) - low = (low & 0x3fffffffffffffffL) | 0x8000000000000000L; - return new ValueUuid(high, low); - } - - /** - * Get or create a UUID for the given 32 bytes. - * - * @param binary the byte array (must be at least 32 bytes long) - * @return the UUID - */ - public static ValueUuid get(byte[] binary) { - if (binary.length < 32) { - return get(Utils.convertBytesToString(binary)); - } - long high = Utils.readLong(binary, 0); - long low = Utils.readLong(binary, 16); - return (ValueUuid) Value.cache(new ValueUuid(high, low)); - } - - /** - * Get or create a UUID for the given high and low order values. - * - * @param high the most significant bits - * @param low the least significant bits - * @return the UUID - */ - public static ValueUuid get(long high, long low) { - return (ValueUuid) Value.cache(new ValueUuid(high, low)); - } - - /** - * Get or create a UUID for the given text representation. - * - * @param s the text representation of the UUID - * @return the UUID - */ - public static ValueUuid get(String s) { - long low = 0, high = 0; - for (int i = 0, j = 0; i < s.length(); i++) { - char c = s.charAt(i); - if (c >= '0' && c <= '9') { - low = (low << 4) | (c - '0'); - } else if (c >= 'a' && c <= 'f') { - low = (low << 4) | (c - 'a' + 0xa); - } else if (c == '-') { - continue; - } else if (c >= 'A' && c <= 'F') { - low = (low << 4) | (c - 'A' + 0xa); - } else { - continue; - } - if (j++ == 15) { - high = low; - low = 0; - } - } - return (ValueUuid) Value.cache(new ValueUuid(high, low)); - } - - public String getSQL() { - return StringUtils.quoteStringSQL(getString()); - } - - public int getType() { - return Value.UUID; - } - - public long getPrecision() { - return PRECISION; - } - - private void appendHex(StringBuilder buff, long x, int bytes) { - for (int i = bytes * 8 - 4; i >= 0; i -= 8) { - buff.append(Integer.toHexString((int) (x >> i) & 0xf)). - append(Integer.toHexString((int) (x >> (i - 4)) & 0xf)); - } - } - - public String getString() { - StringBuilder buff = new StringBuilder(36); - appendHex(buff, high >> 32, 4); - buff.append('-'); - appendHex(buff, high >> 16, 2); - buff.append('-'); - appendHex(buff, high, 2); - buff.append('-'); - appendHex(buff, low >> 48, 2); - buff.append('-'); - appendHex(buff, low, 6); - return buff.toString(); - } - - protected int compareSecure(Value o, CompareMode mode) { - if (o == this) { - return 0; - } - ValueUuid v = (ValueUuid) o; - if (high == v.high) { - return MathUtils.compareLong(low, v.low); - } - return high > v.high ? 1 : -1; - } - - public boolean equals(Object other) { - return other instanceof ValueUuid && compareSecure((Value) other, null) == 0; - } - - public Object getObject() { - return new UUID(high, low); - } - - public byte[] getBytes() { - byte[] buff = new byte[16]; - for (int i = 0; i < 8; i++) { - buff[i] = (byte) ((high >> (8 * (7 - i))) & 255); - buff[8 + i] = (byte) ((low >> (8 * (7 - i))) & 255); - } - return buff; - } - - public void set(PreparedStatement prep, int parameterIndex) throws SQLException { - prep.setBytes(parameterIndex, getBytes()); - } - - /** - * Get the most significant 64 bits of this UUID. - * - * @return the high order bits - */ - public long getHigh() { - return high; - } - - /** - * Get the least significant 64 bits of this UUID. - * - * @return the low order bits - */ - public long getLow() { - return low; - } - - public int getDisplaySize() { - return DISPLAY_SIZE; - } - -} diff --git a/tools/h2/src/main/org/h2/value/package.html b/tools/h2/src/main/org/h2/value/package.html deleted file mode 100755 index 3ba57b9..0000000 --- a/tools/h2/src/main/org/h2/value/package.html +++ /dev/null @@ -1,15 +0,0 @@ - - - - -Javadoc package documentation -

- -Data type and value implementations. - -

\ No newline at end of file diff --git a/tools/h2/src/test/org/h2/samples/Compact.java b/tools/h2/src/test/org/h2/samples/Compact.java deleted file mode 100755 index 36ab6bc..0000000 --- a/tools/h2/src/test/org/h2/samples/Compact.java +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.samples; - -import java.sql.Connection; -import java.sql.DriverManager; -import java.sql.SQLException; -import java.sql.Statement; - -import org.h2.tools.Script; -import org.h2.tools.DeleteDbFiles; -import org.h2.tools.RunScript; -import org.h2.util.IOUtils; - -/** - * This sample application shows how to compact the database files. - * This is done by creating a SQL script, and then re-creating the database - * using this script. - */ -public class Compact { - - /** - * This method is called when executing this sample application from the - * command line. - * - * @param args the command line parameters - */ - public static void main(String... args) throws Exception { - DeleteDbFiles.execute("data", "test", true); - Class.forName("org.h2.Driver"); - Connection conn = DriverManager.getConnection("jdbc:h2:data/test", "sa", ""); - Statement stat = conn.createStatement(); - stat.execute("CREATE TABLE TEST(ID INT PRIMARY KEY, NAME VARCHAR)"); - stat.execute("INSERT INTO TEST VALUES(1, 'Hello'), (2, 'World');"); - conn.close(); - System.out.println("Compacting..."); - compact("data", "test", "sa", ""); - System.out.println("Done."); - } - - /** - * Utility method to compact a database. - * - * @param dir the directory - * @param dbName the database name - * @param user the user name - * @param password the password - */ - 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); - DeleteDbFiles.execute(dir, dbName, true); - RunScript.execute(url, user, password, file, null, false); - IOUtils.delete(file); - } -} diff --git a/tools/h2/src/test/org/h2/samples/CsvSample.java b/tools/h2/src/test/org/h2/samples/CsvSample.java deleted file mode 100755 index 7154cd8..0000000 --- a/tools/h2/src/test/org/h2/samples/CsvSample.java +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.samples; - -import java.sql.ResultSet; -import java.sql.ResultSetMetaData; -import java.sql.SQLException; -import java.sql.Types; - -import org.h2.tools.Csv; -import org.h2.tools.SimpleResultSet; -import org.h2.util.IOUtils; - -/** - * This sample application shows how to use the CSV tool - * to write CSV (comma separated values) files, and - * how to use the tool to read such files. - * See also the section CSV (Comma Separated Values) Support in the Tutorial. - */ -public class CsvSample { - - /** - * This method is called when executing this sample application from the - * command line. - * - * @param args the command line parameters - */ - public static void main(String... args) throws SQLException { - CsvSample.write(); - CsvSample.read(); - IOUtils.delete("data/test.csv"); - } - - /** - * Write a CSV file. - */ - static void write() throws SQLException { - SimpleResultSet rs = new SimpleResultSet(); - rs.addColumn("NAME", Types.VARCHAR, 255, 0); - rs.addColumn("EMAIL", Types.VARCHAR, 255, 0); - rs.addColumn("PHONE", Types.VARCHAR, 255, 0); - rs.addRow("Bob Meier", "bob.meier@abcde.abc", "+41123456789"); - rs.addRow("John Jones", "john.jones@abcde.abc", "+41976543210"); - Csv.getInstance().write("data/test.csv", rs, null); - } - - /** - * Read a CSV file. - */ - static void read() throws SQLException { - ResultSet rs = Csv.getInstance().read("data/test.csv", null, null); - ResultSetMetaData meta = rs.getMetaData(); - while (rs.next()) { - for (int i = 0; i < meta.getColumnCount(); i++) { - System.out.println(meta.getColumnLabel(i + 1) + ": " + rs.getString(i + 1)); - } - System.out.println(); - } - rs.close(); - } -} diff --git a/tools/h2/src/test/org/h2/samples/FileFunctions.java b/tools/h2/src/test/org/h2/samples/FileFunctions.java deleted file mode 100755 index 3c62eea..0000000 --- a/tools/h2/src/test/org/h2/samples/FileFunctions.java +++ /dev/null @@ -1,87 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.samples; - -import java.io.IOException; -import java.io.RandomAccessFile; -import java.sql.Connection; -import java.sql.DriverManager; -import java.sql.ResultSet; -import java.sql.Statement; - -/** - * This sample application shows how to create a user defined function - * to read a file from the file system. - */ -public class FileFunctions { - - /** - * This method is called when executing this sample application from the - * command line. - * - * @param args the command line parameters - */ - public static void main(String... args) throws Exception { - Class.forName("org.h2.Driver"); - Connection conn = DriverManager.getConnection("jdbc:h2:mem:", "sa", ""); - Statement stat = conn.createStatement(); - stat.execute("CREATE ALIAS READ_TEXT_FILE FOR \"org.h2.samples.FileFunctions.readTextFile\" "); - stat.execute("CREATE ALIAS READ_TEXT_FILE_WITH_ENCODING FOR \"org.h2.samples.FileFunctions.readTextFileWithEncoding\" "); - stat.execute("CREATE ALIAS READ_FILE FOR \"org.h2.samples.FileFunctions.readFile\" "); - ResultSet rs = stat.executeQuery("CALL READ_FILE('test.txt')"); - rs.next(); - byte[] data = rs.getBytes(1); - System.out.println("length: " + data.length); - rs = stat.executeQuery("CALL READ_TEXT_FILE('test.txt')"); - rs.next(); - String text = rs.getString(1); - System.out.println("text: " + text); - conn.close(); - } - - /** - * Read a String from a file. The default encoding for this platform is used. - * - * @param fileName the file name - * @return the text - */ - public static String readTextFile(String fileName) throws IOException { - byte[] buff = readFile(fileName); - String s = new String(buff); - return s; - } - - /** - * Read a String from a file using the specified encoding. - * - * @param fileName the file name - * @param encoding the encoding - * @return the text - */ - public static String readTextFileWithEncoding(String fileName, String encoding) throws IOException { - byte[] buff = readFile(fileName); - String s = new String(buff, encoding); - return s; - } - - /** - * Read a file into a byte array. - * - * @param fileName the file name - * @return the byte array - */ - public static byte[] readFile(String fileName) throws IOException { - RandomAccessFile file = new RandomAccessFile(fileName, "r"); - try { - byte[] buff = new byte[(int) file.length()]; - file.readFully(buff); - return buff; - } finally { - file.close(); - } - } -} diff --git a/tools/h2/src/test/org/h2/samples/Function.java b/tools/h2/src/test/org/h2/samples/Function.java deleted file mode 100755 index e659536..0000000 --- a/tools/h2/src/test/org/h2/samples/Function.java +++ /dev/null @@ -1,134 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.samples; - -import java.math.BigInteger; -import java.sql.Connection; -import java.sql.DriverManager; -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.sql.Statement; -import java.sql.Types; -import org.h2.tools.SimpleResultSet; - -/** - * This sample application shows how to define and use - * custom (user defined) functions in this database. - */ -public class Function { - - /** - * This method is called when executing this sample application from the - * command line. - * - * @param args the command line parameters - */ - public static void main(String... args) throws Exception { - Class.forName("org.h2.Driver"); - Connection conn = DriverManager.getConnection("jdbc:h2:mem:", "sa", ""); - Statement stat = conn.createStatement(); - - // Using a custom Java function - stat.execute("CREATE ALIAS IS_PRIME FOR \"org.h2.samples.Function.isPrime\" "); - ResultSet rs; - rs = stat.executeQuery("SELECT IS_PRIME(X), X FROM SYSTEM_RANGE(1, 20) ORDER BY X"); - while (rs.next()) { - boolean isPrime = rs.getBoolean(1); - if (isPrime) { - int x = rs.getInt(2); - System.out.println(x + " is prime"); - } - } - - // Calling the built-in 'table' function - stat.execute("CREATE TABLE TEST(ID INT) AS " + - "SELECT X FROM SYSTEM_RANGE(1, 100)"); - PreparedStatement prep; - prep = conn.prepareStatement("SELECT * FROM TABLE(X INT=?, O INT=?) J " + - "INNER JOIN TEST T ON J.X=T.ID ORDER BY J.O"); - prep.setObject(1, - new Integer[] { new Integer(30), new Integer(20) }); - prep.setObject(2, - new Integer[] { new Integer(1), new Integer(2) }); - 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(); - } - - /** - * Check if a value is a prime number. - * - * @param value the value - * @return true if it is a prime number - */ - public static boolean isPrime(int value) { - return new BigInteger(String.valueOf(value)).isProbablePrime(100); - } - - /** - * Execute a query. - * - * @param conn the connection - * @param sql the SQL statement - * @return the result set - */ - public static ResultSet query(Connection conn, String sql) throws SQLException { - return conn.createStatement().executeQuery(sql); - } - - /** - * Creates a simple result set with one row. - * - * @return the result set - */ - public static ResultSet simpleResultSet() { - SimpleResultSet rs = new SimpleResultSet(); - rs.addColumn("ID", Types.INTEGER, 10, 0); - rs.addColumn("NAME", Types.VARCHAR, 255, 0); - rs.addRow(0, "Hello"); - 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(x, y); - } - } - return rs; - } - -} diff --git a/tools/h2/src/test/org/h2/samples/FunctionMultiReturn.java b/tools/h2/src/test/org/h2/samples/FunctionMultiReturn.java deleted file mode 100755 index e094840..0000000 --- a/tools/h2/src/test/org/h2/samples/FunctionMultiReturn.java +++ /dev/null @@ -1,148 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.samples; - -import java.sql.Connection; -import java.sql.DriverManager; -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.sql.Statement; -import java.sql.Types; - -import org.h2.tools.SimpleResultSet; - -/** - * User defined functions can return a result set, - * and can therefore be used like a table. - * This sample application uses such a function to convert - * polar to cartesian coordinates. - */ -public class FunctionMultiReturn { - - /** - * This method is called when executing this sample application from the - * command line. - * - * @param args the command line parameters - */ - public static void main(String... args) throws Exception { - Class.forName("org.h2.Driver"); - Connection conn = DriverManager.getConnection("jdbc:h2:mem:", "sa", ""); - Statement stat = conn.createStatement(); - stat.execute("CREATE ALIAS P2C FOR \"org.h2.samples.FunctionMultiReturn.polar2Cartesian\" "); - PreparedStatement prep = conn.prepareStatement("SELECT X, Y FROM P2C(?, ?)"); - prep.setDouble(1, 5.0); - prep.setDouble(2, 0.5); - ResultSet rs = prep.executeQuery(); - while (rs.next()) { - double x = rs.getDouble(1); - double y = rs.getDouble(2); - System.out.println("result: (x=" + x + ", y="+y+")"); - } - - stat.execute("CREATE TABLE TEST(ID IDENTITY, R DOUBLE, A DOUBLE)"); - stat.execute("INSERT INTO TEST(R, A) VALUES(5.0, 0.5), (10.0, 0.6)"); - stat.execute("CREATE ALIAS P2C_SET FOR \"org.h2.samples.FunctionMultiReturn.polar2CartesianSet\" "); - rs = conn.createStatement().executeQuery("SELECT * FROM P2C_SET('SELECT * FROM TEST')"); - while (rs.next()) { - double r = rs.getDouble("R"); - double a = rs.getDouble("A"); - double x = rs.getDouble("X"); - double y = rs.getDouble("Y"); - System.out.println("(r="+r+" a="+a+") : (x=" + x + ", y="+y+")"); - } - - stat.execute("CREATE ALIAS P2C_A FOR \"org.h2.samples.FunctionMultiReturn.polar2CartesianArray\" "); - rs = conn.createStatement().executeQuery("SELECT R, A, P2C_A(R, A) FROM TEST"); - while (rs.next()) { - double r = rs.getDouble(1); - double a = rs.getDouble(2); - Object o = rs.getObject(3); - Object[] xy = (Object[]) o; - double x = ((Double) xy[0]).doubleValue(); - double y = ((Double) xy[1]).doubleValue(); - System.out.println("(r=" + r + " a=" + a + ") : (x=" + x + ", y=" + y + ")"); - } - - rs = conn.createStatement().executeQuery("SELECT R, A, ARRAY_GET(E, 1), ARRAY_GET(E, 2) FROM (SELECT R, A, P2C_A(R, A) E FROM TEST)"); - while (rs.next()) { - double r = rs.getDouble(1); - double a = rs.getDouble(2); - double x = rs.getDouble(3); - double y = rs.getDouble(4); - System.out.println("(r="+r+" a="+a+") : (x=" + x + ", y="+y+")"); - } - - conn.close(); - } - - /** - * Convert polar coordinates to cartesian coordinates. The function may be - * called twice, once to retrieve the result columns (with null parameters), - * and the second time to return the data. - * - * @param r the distance from the point 0/0 - * @param alpha the angle - * @return a result set with two columns: x and y - */ - public static ResultSet polar2Cartesian(Double r, Double alpha) { - SimpleResultSet rs = new SimpleResultSet(); - rs.addColumn("X", Types.DOUBLE, 0, 0); - rs.addColumn("Y", Types.DOUBLE, 0, 0); - if (r != null && alpha != null) { - double x = r.doubleValue() * Math.cos(alpha.doubleValue()); - double y = r.doubleValue() * Math.sin(alpha.doubleValue()); - rs.addRow(x, y); - } - return rs; - } - - /** - * Convert polar coordinates to cartesian coordinates. The function may be - * called twice, once to retrieve the result columns (with null parameters), - * and the second time to return the data. - * - * @param r the distance from the point 0/0 - * @param alpha the angle - * @return an array two values: x and y - */ - public static Object[] polar2CartesianArray(Double r, Double alpha) { - double x = r.doubleValue() * Math.cos(alpha.doubleValue()); - double y = r.doubleValue() * Math.sin(alpha.doubleValue()); - return new Object[]{new Double(x), new Double(y)}; - } - - /** - * Convert a set of polar coordinates to cartesian coordinates. The function - * may be called twice, once to retrieve the result columns (with null - * parameters), and the second time to return the data. - * - * @param conn the connection - * @param query the query - * @return a result set with the coordinates - */ - public static ResultSet polar2CartesianSet(Connection conn, String query) throws SQLException { - SimpleResultSet result = new SimpleResultSet(); - result.addColumn("R", Types.DOUBLE, 0, 0); - result.addColumn("A", Types.DOUBLE, 0, 0); - result.addColumn("X", Types.DOUBLE, 0, 0); - result.addColumn("Y", Types.DOUBLE, 0, 0); - if (query != null) { - ResultSet rs = conn.createStatement().executeQuery(query); - while (rs.next()) { - double r = rs.getDouble("R"); - double alpha = rs.getDouble("A"); - double x = r * Math.cos(alpha); - double y = r * Math.sin(alpha); - result.addRow(r, alpha, x, y); - } - } - return result; - } - -} diff --git a/tools/h2/src/test/org/h2/samples/HelloWorld.java b/tools/h2/src/test/org/h2/samples/HelloWorld.java deleted file mode 100755 index 0a3c309..0000000 --- a/tools/h2/src/test/org/h2/samples/HelloWorld.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, Version - * 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). Initial Developer: H2 Group - */ -package org.h2.samples; - -import java.sql.Connection; -import java.sql.DriverManager; -import java.sql.ResultSet; -import java.sql.Statement; -import org.h2.tools.DeleteDbFiles; - -/** - * A very simple class that shows how to load the driver, create a database, - * create a table, and insert some data. - */ -public class HelloWorld { - - /** - * Called when ran from command line. - * - * @param args ignored - */ - public static void main(String... args) throws Exception { - // delete the database named 'test' in the user home directory - DeleteDbFiles.execute("~", "test", true); - - Class.forName("org.h2.Driver"); - Connection conn = DriverManager.getConnection("jdbc:h2:~/test"); - Statement stat = conn.createStatement(); - - // this line would initialize the database - // from the SQL script file 'init.sql' - // stat.execute("runscript from 'init.sql'"); - - stat.execute("create table test(id int primary key, name varchar(255))"); - stat.execute("insert into test values(1, 'Hello')"); - ResultSet rs; - rs = stat.executeQuery("select * from test"); - while (rs.next()) { - System.out.println(rs.getString("name")); - } - conn.close(); - } - -} diff --git a/tools/h2/src/test/org/h2/samples/InitDatabaseFromJar.java b/tools/h2/src/test/org/h2/samples/InitDatabaseFromJar.java deleted file mode 100755 index 55262c1..0000000 --- a/tools/h2/src/test/org/h2/samples/InitDatabaseFromJar.java +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.samples; - -import java.io.InputStream; -import java.io.InputStreamReader; -import java.sql.Connection; -import java.sql.DriverManager; -import java.sql.ResultSet; -import java.sql.Statement; - -import org.h2.tools.RunScript; - -/** - * In this example a database is initialized from compressed script in a jar - * file. - */ -public class InitDatabaseFromJar { - - /** - * This method is called when executing this sample application from the - * command line. - * - * @param args the command line parameters - */ - public static void main(String... args) throws Exception { - new InitDatabaseFromJar().createScript(); - new InitDatabaseFromJar().initDb(); - } - - /** - * Create a script from a new database. - */ - private void createScript() throws Exception { - Class.forName("org.h2.Driver"); - Connection conn = DriverManager.getConnection("jdbc:h2:mem:test"); - Statement stat = conn.createStatement(); - stat.execute("CREATE TABLE TEST(NAME VARCHAR)"); - stat.execute("INSERT INTO TEST VALUES('Hello World')"); - stat.execute("SCRIPT TO 'script.sql'"); - conn.close(); - } - - /** - * Initialize a database from a SQL script file. - */ - void initDb() throws Exception { - Class.forName("org.h2.Driver"); - Connection conn = DriverManager.getConnection("jdbc:h2:mem:test"); - InputStream in = getClass().getResourceAsStream("script.sql"); - if (in == null) { - System.out.println("Please add the file script.sql to the classpath, package " - + getClass().getPackage().getName()); - } else { - RunScript.execute(conn, new InputStreamReader(in)); - ResultSet rs = conn.createStatement().executeQuery("SELECT * FROM TEST"); - while (rs.next()) { - System.out.println(rs.getString(1)); - } - conn.close(); - } - } -} diff --git a/tools/h2/src/test/org/h2/samples/MixedMode.java b/tools/h2/src/test/org/h2/samples/MixedMode.java deleted file mode 100755 index 838e79b..0000000 --- a/tools/h2/src/test/org/h2/samples/MixedMode.java +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.samples; - -import java.sql.Connection; -import java.sql.DriverManager; -import java.sql.SQLException; -import java.sql.Statement; -import org.h2.tools.Server; - -/** - * This sample program opens the same database once in embedded mode, - * and once in the server mode. The embedded mode is faster, but only - * the server mode supports remote connections. - */ -public class MixedMode { - - /** - * This method is called when executing this sample application from the - * command line. - * - * @param args the command line parameters - */ - public static void main(String... args) throws Exception { - - // start the server, allows to access the database remotely - Server server = Server.createTcpServer("-tcpPort", "9081"); - server.start(); - System.out.println("You can access the database remotely now, using the URL:"); - System.out.println("jdbc:h2:tcp://localhost:9081/~/test (user: sa, password: sa)"); - - // now use the database in your application in embedded mode - Class.forName("org.h2.Driver"); - Connection conn = DriverManager.getConnection("jdbc:h2:~/test", "sa", "sa"); - - // some simple 'business usage' - Statement stat = conn.createStatement(); - stat.execute("DROP TABLE TIMER IF EXISTS"); - stat.execute("CREATE TABLE TIMER(ID INT PRIMARY KEY, TIME VARCHAR)"); - System.out.println("Execute this a few times: SELECT TIME FROM TIMER"); - System.out.println("To stop this application (and the server), run: DROP TABLE TIMER"); - try { - while (true) { - // runs forever, except if you drop the table remotely - stat.execute("MERGE INTO TIMER VALUES(1, NOW())"); - Thread.sleep(1000); - } - } catch (SQLException e) { - System.out.println("Error: " + e.toString()); - } - conn.close(); - - // stop the server - server.stop(); - } -} diff --git a/tools/h2/src/test/org/h2/samples/Newsfeed.java b/tools/h2/src/test/org/h2/samples/Newsfeed.java deleted file mode 100755 index 277e0fe..0000000 --- a/tools/h2/src/test/org/h2/samples/Newsfeed.java +++ /dev/null @@ -1,83 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.samples; - -import java.io.File; -import java.io.FileOutputStream; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.io.OutputStreamWriter; -import java.io.Writer; -import java.sql.Connection; -import java.sql.DriverManager; -import java.sql.ResultSet; - -import org.h2.tools.RunScript; -import org.h2.util.StringUtils; - -/** - * The newsfeed application uses XML functions to create an RSS and Atom feed - * from a simple SQL script. A textual representation of the data is created as - * well. - */ -public class Newsfeed { - - /** - * This method is called when executing this sample application from the - * command line. - * - * @param args the command line parameters - */ - public static void main(String... args) throws Exception { - String targetDir = args.length == 0 ? "." : args[0]; - Class.forName("org.h2.Driver"); - Connection conn = DriverManager.getConnection("jdbc:h2:mem:", "sa", ""); - InputStream in = Newsfeed.class.getResourceAsStream("newsfeed.sql"); - ResultSet rs = RunScript.execute(conn, new InputStreamReader(in, "ISO-8859-1")); - in.close(); - while (rs.next()) { - String file = rs.getString("FILE"); - String content = rs.getString("CONTENT"); - if (file.endsWith(".txt")) { - content = convertHtml2Text(content); - } - new File(targetDir).mkdirs(); - FileOutputStream out = new FileOutputStream(targetDir + "/" + file); - Writer writer = new OutputStreamWriter(out, "UTF-8"); - writer.write(content); - writer.close(); - out.close(); - } - conn.close(); - } - - /** - * Convert HTML text to plain text. - * - * @param html the html text - * @return the plain text - */ - private static String convertHtml2Text(String html) { - String s = html; - s = StringUtils.replaceAll(s, "", ""); - s = StringUtils.replaceAll(s, "", ""); - s = StringUtils.replaceAll(s, "
    ", ""); - s = StringUtils.replaceAll(s, "
", ""); - s = StringUtils.replaceAll(s, "
  • ", "- "); - s = StringUtils.replaceAll(s, "
  • ", ""); - s = StringUtils.replaceAll(s, "", " ) "); - s = StringUtils.replaceAll(s, "", ""); - s = StringUtils.replaceAll(s, "
    ", ""); - s = StringUtils.replaceAll(s, "
    ", ""); - s = StringUtils.replaceAll(s, "
    ", ""); - if (s.indexOf('<') >= 0 || s.indexOf('>') >= 0) { - throw new RuntimeException("Unsupported HTML Tag: < or > in " + s); - } - return s; - } -} diff --git a/tools/h2/src/test/org/h2/samples/SQLInjection.java b/tools/h2/src/test/org/h2/samples/SQLInjection.java deleted file mode 100755 index b4ed057..0000000 --- a/tools/h2/src/test/org/h2/samples/SQLInjection.java +++ /dev/null @@ -1,419 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.samples; - -import java.io.BufferedReader; -import java.io.InputStreamReader; -import java.sql.Connection; -import java.sql.DriverManager; -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.sql.Statement; - -/** - * SQL Injection is a common security vulnerability for applications that use - * database. It is one of the most common security vulnerabilities for web - * applications today. This sample application shows how SQL injection works, - * and how to protect the application from it. - */ -public class SQLInjection { - - private Connection conn; - private Statement stat; - - /** - * This method is called when executing this sample application from the - * command line. - * - * @param args the command line parameters - */ - public static void main(String... args) throws Exception { - new SQLInjection().run("org.h2.Driver", - "jdbc:h2:test", "sa", "sa"); -// new SQLInjection().run("org.postgresql.Driver", -// "jdbc:postgresql:jpox2", "sa", "sa"); -// new SQLInjection().run("com.mysql.jdbc.Driver", -// "jdbc:mysql://localhost/test", "sa", "sa"); -// new SQLInjection().run("org.hsqldb.jdbcDriver", -// "jdbc:hsqldb:test", "sa", ""); -// new SQLInjection().run( -// "org.apache.derby.jdbc.EmbeddedDriver", -// "jdbc:derby:test3;create=true", "sa", "sa"); - } - - /** - * Run the test against the specified database. - * - * @param driver the JDBC driver name - * @param url the database URL - * @param user the user name - * @param password the password - */ - void run(String driver, String url, String user, String password) throws Exception { - Class.forName(driver); - conn = DriverManager.getConnection(url, user, password); - stat = conn.createStatement(); - try { - stat.execute("DROP TABLE USERS"); - } catch (SQLException e) { - // ignore - } - stat.execute("CREATE TABLE USERS(ID INT PRIMARY KEY, " + - "NAME VARCHAR(255), PASSWORD VARCHAR(255))"); - stat.execute("INSERT INTO USERS VALUES(1, 'admin', 'super')"); - stat.execute("INSERT INTO USERS VALUES(2, 'guest', '123456')"); - stat.execute("INSERT INTO USERS VALUES(3, 'test', 'abc')"); - - loginByNameInsecure(); - - if (url.startsWith("jdbc:h2:")) { - loginStoredProcedureInsecure(); - limitRowAccess(); - } - - loginByNameSecure(); - - if (url.startsWith("jdbc:h2:")) { - stat.execute("SET ALLOW_LITERALS NONE"); - stat.execute("SET ALLOW_LITERALS NUMBERS"); - stat.execute("SET ALLOW_LITERALS ALL"); - } - - loginByIdInsecure(); - loginByIdSecure(); - - try { - stat.execute("DROP TABLE ITEMS"); - } catch (SQLException e) { - // ignore - } - - stat.execute("CREATE TABLE ITEMS(ID INT PRIMARY KEY, " + - "NAME VARCHAR(255), ACTIVE INT)"); - stat.execute("INSERT INTO ITEMS VALUES(0, 'XBox', 0)"); - stat.execute("INSERT INTO ITEMS VALUES(1, 'XBox 360', 1)"); - stat.execute("INSERT INTO ITEMS VALUES(2, 'PlayStation 1', 0)"); - stat.execute("INSERT INTO ITEMS VALUES(3, 'PlayStation 2', 1)"); - stat.execute("INSERT INTO ITEMS VALUES(4, 'PlayStation 3', 1)"); - - listActiveItems(); - - if (url.startsWith("jdbc:h2:")) { - stat.execute("DROP CONSTANT IF EXISTS TYPE_INACTIVE"); - stat.execute("DROP CONSTANT IF EXISTS TYPE_ACTIVE"); - stat.execute("CREATE CONSTANT TYPE_INACTIVE VALUE 0"); - stat.execute("CREATE CONSTANT TYPE_ACTIVE VALUE 1"); - listActiveItemsUsingConstants(); - } - - listItemsSortedInsecure(); - listItemsSortedSecure(); - - if (url.startsWith("jdbc:h2:")) { - listItemsSortedSecureParam(); - storePasswordHashWithSalt(); - } - - conn.close(); - } - - /** - * Simulate a login using an insecure method. - */ - void loginByNameInsecure() throws Exception { - System.out.println("Insecure Systems Inc. - login"); - String name = input("Name?"); - String password = input("Password?"); - ResultSet rs = stat.executeQuery("SELECT * FROM USERS WHERE " + - "NAME='" + name + "' AND PASSWORD='" + password + "'"); - if (rs.next()) { - System.out.println("Welcome!"); - } else { - System.out.println("Access denied!"); - } - } - - /** - * Utility method to get a user record given the user name and password. - * This method is secure. - * - * @param conn the database connection - * @param userName the user name - * @param password the password - * @return a result set with the user record if the password matches - */ - public static ResultSet getUser(Connection conn, String userName, String password) throws Exception { - PreparedStatement prep = conn.prepareStatement( - "SELECT * FROM USERS WHERE NAME=? AND PASSWORD=?"); - prep.setString(1, userName); - prep.setString(2, password); - return prep.executeQuery(); - } - - /** - * Utility method to change a password of a user. - * This method is secure, except that the old password is not checked. - * - * @param conn the database connection - * @param userName the user name - * @param password the password - * @return the new password - */ - public static String changePassword(Connection conn, String userName, String password) throws Exception { - PreparedStatement prep = conn.prepareStatement( - "UPDATE USERS SET PASSWORD=? WHERE NAME=?"); - prep.setString(1, password); - prep.setString(2, userName); - prep.executeUpdate(); - return password; - } - - /** - * Simulate a login using an insecure method. - * A stored procedure is used here. - */ - void loginStoredProcedureInsecure() throws Exception { - System.out.println("Insecure Systems Inc. - login using a stored procedure"); - stat.execute("CREATE ALIAS IF NOT EXISTS " + - "GET_USER FOR \"org.h2.samples.SQLInjection.getUser\""); - stat.execute("CREATE ALIAS IF NOT EXISTS " + - "CHANGE_PASSWORD FOR \"org.h2.samples.SQLInjection.changePassword\""); - String name = input("Name?"); - String password = input("Password?"); - ResultSet rs = stat.executeQuery( - "CALL GET_USER('" + name + "', '" + password + "')"); - if (rs.next()) { - System.out.println("Welcome!"); - } else { - System.out.println("Access denied!"); - } - } - - /** - * Simulate a login using a secure method. - */ - void loginByNameSecure() throws Exception { - System.out.println("Secure Systems Inc. - login using placeholders"); - String name = input("Name?"); - String password = input("Password?"); - PreparedStatement prep = conn.prepareStatement( - "SELECT * FROM USERS WHERE " + - "NAME=? AND PASSWORD=?"); - prep.setString(1, name); - prep.setString(2, password); - ResultSet rs = prep.executeQuery(); - if (rs.next()) { - System.out.println("Welcome!"); - } else { - System.out.println("Access denied!"); - } - } - - /** - * Sample code to limit access only to specific rows. - */ - void limitRowAccess() throws Exception { - System.out.println("Secure Systems Inc. - limit row access"); - stat.execute("DROP TABLE IF EXISTS SESSION_USER"); - stat.execute("CREATE TABLE SESSION_USER(ID INT, USER INT)"); - stat.execute("DROP VIEW IF EXISTS MY_USER"); - stat.execute("CREATE VIEW MY_USER AS " + - "SELECT U.* FROM SESSION_USER S, USERS U " + - "WHERE S.ID=SESSION_ID() AND S.USER=U.ID"); - stat.execute("INSERT INTO SESSION_USER VALUES(SESSION_ID(), 1)"); - ResultSet rs = stat.executeQuery("SELECT ID, NAME FROM MY_USER"); - while (rs.next()) { - System.out.println(rs.getString(1) + ": " + rs.getString(2)); - } - } - - /** - * Simulate a login using an insecure method. - */ - void loginByIdInsecure() throws Exception { - System.out.println("Half Secure Systems Inc. - login by id"); - String id = input("User ID?"); - String password = input("Password?"); - try { - PreparedStatement prep = conn.prepareStatement( - "SELECT * FROM USERS WHERE " + - "ID=" + id + " AND PASSWORD=?"); - prep.setString(1, password); - ResultSet rs = prep.executeQuery(); - if (rs.next()) { - System.out.println("Welcome!"); - } else { - System.out.println("Access denied!"); - } - } catch (SQLException e) { - System.out.println(e); - } - } - - /** - * Simulate a login using a secure method. - */ - void loginByIdSecure() throws Exception { - System.out.println("Secure Systems Inc. - login by id"); - String id = input("User ID?"); - String password = input("Password?"); - try { - PreparedStatement prep = conn.prepareStatement( - "SELECT * FROM USERS WHERE " + - "ID=? AND PASSWORD=?"); - prep.setInt(1, Integer.parseInt(id)); - prep.setString(2, password); - ResultSet rs = prep.executeQuery(); - if (rs.next()) { - System.out.println("Welcome!"); - } else { - System.out.println("Access denied!"); - } - } catch (Exception e) { - System.out.println(e); - } - } - - /** - * List active items. - * The method uses the hard coded value '1', and therefore the database - * can not verify if the SQL statement was constructed with user - * input or not. - */ - void listActiveItems() throws Exception { - System.out.println("Half Secure Systems Inc. - list active items"); - ResultSet rs = stat.executeQuery( - "SELECT NAME FROM ITEMS WHERE ACTIVE=1"); - while (rs.next()) { - System.out.println("Name: " + rs.getString(1)); - } - } - - /** - * List active items. - * The method uses a constant, and therefore the database - * knows it does not contain user input. - */ - void listActiveItemsUsingConstants() throws Exception { - System.out.println("Secure Systems Inc. - list active items"); - ResultSet rs = stat.executeQuery( - "SELECT NAME FROM ITEMS WHERE ACTIVE=TYPE_ACTIVE"); - while (rs.next()) { - System.out.println("Name: " + rs.getString(1)); - } - } - - /** - * List items using a specified sort order. - * The method is not secure as user input is used to construct the - * SQL statement. - */ - void listItemsSortedInsecure() throws Exception { - System.out.println("Insecure Systems Inc. - list items"); - String order = input("order (id, name)?"); - try { - ResultSet rs = stat.executeQuery( - "SELECT ID, NAME FROM ITEMS ORDER BY " + order); - while (rs.next()) { - System.out.println(rs.getString(1) + ": " + rs.getString(2)); - } - } catch (SQLException e) { - System.out.println(e); - } - } - - /** - * List items using a specified sort order. - * The method is secure as the user input is validated before use. - * However the database has no chance to verify this. - */ - void listItemsSortedSecure() throws Exception { - System.out.println("Secure Systems Inc. - list items"); - String order = input("order (id, name)?"); - if (!order.matches("[a-zA-Z0-9_]*")) { - order = "id"; - } - try { - ResultSet rs = stat.executeQuery( - "SELECT ID, NAME FROM ITEMS ORDER BY " + order); - while (rs.next()) { - System.out.println(rs.getString(1) + ": " + rs.getString(2)); - } - } catch (SQLException e) { - System.out.println(e); - } - } - - /** - * List items using a specified sort order. - * The method is secure as a parameterized statement is used. - */ - void listItemsSortedSecureParam() throws Exception { - System.out.println("Secure Systems Inc. - list items"); - String order = input("order (1, 2, -1, -2)?"); - PreparedStatement prep = conn.prepareStatement( - "SELECT ID, NAME FROM ITEMS ORDER BY ?"); - try { - prep.setInt(1, Integer.parseInt(order)); - ResultSet rs = prep.executeQuery(); - while (rs.next()) { - System.out.println(rs.getString(1) + ": " + rs.getString(2)); - } - } catch (Exception e) { - System.out.println(e); - } - } - - /** - * This method creates a one way hash from the password - * (using a random salt), and stores this information instead of the - * password. - */ - void storePasswordHashWithSalt() throws Exception { - System.out.println("Very Secure Systems Inc. - login"); - stat.execute("DROP TABLE IF EXISTS USERS2"); - stat.execute("CREATE TABLE USERS2(ID INT PRIMARY KEY, " + - "NAME VARCHAR, SALT BINARY, HASH BINARY)"); - stat.execute("INSERT INTO USERS2 VALUES" + - "(1, 'admin', SECURE_RAND(16), NULL)"); - stat.execute("DROP CONSTANT IF EXISTS HASH_ITERATIONS"); - stat.execute("DROP CONSTANT IF EXISTS HASH_ALGORITHM"); - stat.execute("CREATE CONSTANT HASH_ITERATIONS VALUE 100"); - stat.execute("CREATE CONSTANT HASH_ALGORITHM VALUE 'SHA256'"); - stat.execute("UPDATE USERS2 SET " + - "HASH=HASH(HASH_ALGORITHM, STRINGTOUTF8('abc' || SALT), HASH_ITERATIONS) " + - "WHERE ID=1"); - String user = input("user?"); - String password = input("password?"); - stat.execute("SET ALLOW_LITERALS NONE"); - PreparedStatement prep = conn.prepareStatement( - "SELECT * FROM USERS2 WHERE NAME=? AND " + - "HASH=HASH(HASH_ALGORITHM, STRINGTOUTF8(? || SALT), HASH_ITERATIONS)"); - prep.setString(1, user); - prep.setString(2, password); - ResultSet rs = prep.executeQuery(); - while (rs.next()) { - System.out.println("name: " + rs.getString("NAME")); - System.out.println("salt: " + rs.getString("SALT")); - System.out.println("hash: " + rs.getString("HASH")); - } - stat.execute("SET ALLOW_LITERALS ALL"); - } - - /** - * Utility method to get user input from the command line. - * - * @param prompt the prompt - * @return the user input - */ - String input(String prompt) throws Exception { - System.out.print(prompt); - return new BufferedReader(new InputStreamReader(System.in)).readLine(); - } - -} diff --git a/tools/h2/src/test/org/h2/samples/SecurePassword.java b/tools/h2/src/test/org/h2/samples/SecurePassword.java deleted file mode 100755 index 1ee2866..0000000 --- a/tools/h2/src/test/org/h2/samples/SecurePassword.java +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.samples; - -import java.sql.Connection; -import java.sql.DriverManager; -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.Statement; -import java.util.Properties; - -/** - * This example shows how to secure passwords - * (both database passwords, and account passwords). - */ -public class SecurePassword { - - /** - * This method is called when executing this sample application from the - * command line. - * - * @param args the command line parameters - */ - public static void main(String... args) throws Exception { - - Class.forName("org.h2.Driver"); - String url = "jdbc:h2:data/simple"; - String user = "sam"; - char[] password = {'t', 'i', 'a', 'E', 'T', 'r', 'p'}; - - // This is the normal, but 'unsafe' way to connect: - // the password may reside in the main memory for an undefined time, - // or even written to disk (swap file): - // Connection conn = - // DriverManager.getConnection(url, user, new String(password)); - - // This is the most safe way to connect: the password is overwritten after use - Properties prop = new Properties(); - prop.setProperty("user", user); - prop.put("password", password); - Connection conn = DriverManager.getConnection(url, prop); - - // For security reasons, account passwords should not be stored directly - // in a database. Instead, only the hash should be stored. Also, - // PreparedStatements must be used to avoid SQL injection: - Statement stat = conn.createStatement(); - stat.execute( - "drop table account if exists"); - stat.execute( - "create table account(name varchar primary key, salt binary default secure_rand(16), hash binary)"); - PreparedStatement prep; - prep = conn.prepareStatement("insert into account(name) values(?)"); - prep.setString(1, "Joe"); - prep.execute(); - prep = conn.prepareStatement( - "update account set hash=hash('SHA256', stringtoutf8(salt||?), 10) where name=?"); - prep.setString(1, "secret"); - prep.setString(2, "Joe"); - prep.execute(); - prep = conn.prepareStatement( - "select * from account where name=? and hash=hash('SHA256', stringtoutf8(salt||?), 10)"); - prep.setString(1, "Joe"); - prep.setString(2, "secret"); - ResultSet rs = prep.executeQuery(); - while (rs.next()) { - System.out.println(rs.getString("name")); - } - conn.close(); - } - -} diff --git a/tools/h2/src/test/org/h2/samples/ShowProgress.java b/tools/h2/src/test/org/h2/samples/ShowProgress.java deleted file mode 100755 index 7d4cd81..0000000 --- a/tools/h2/src/test/org/h2/samples/ShowProgress.java +++ /dev/null @@ -1,163 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.samples; - -import java.sql.Connection; -import java.sql.DriverManager; -import java.sql.PreparedStatement; -import java.sql.SQLException; -import java.sql.Statement; - -import org.h2.api.DatabaseEventListener; -import org.h2.jdbc.JdbcConnection; - -/** - * This example application implements a database event listener. - * This is useful to display progress information while opening a large database, - * or to log database exceptions. - */ -public class ShowProgress implements DatabaseEventListener { - - private long last, start; - - /** - * Create a new instance of this class, and start the timer. - */ - public ShowProgress() { - start = last = System.currentTimeMillis(); - } - - /** - * This method is called when executing this sample application from the - * command line. - * - * @param args the command line parameters - */ - public static void main(String... args) throws Exception { - new ShowProgress().test(); - } - - /** - * Run the progress test. - */ - void test() throws Exception { - Class.forName("org.h2.Driver"); - Connection conn = DriverManager.getConnection("jdbc:h2:test", "sa", ""); - Statement stat = conn.createStatement(); - stat.execute("DROP TABLE IF EXISTS TEST"); - stat.execute("CREATE TABLE TEST(ID INT PRIMARY KEY, NAME VARCHAR)"); - PreparedStatement prep = conn.prepareStatement("INSERT INTO TEST VALUES(?, 'Test' || SPACE(100))"); - long time; - time = System.currentTimeMillis(); - int len = 1000; - for (int i = 0; i < len; i++) { - long now = System.currentTimeMillis(); - if (now > time + 1000) { - time = now; - System.out.println("Inserting " + (100L * i / len) + "%"); - } - prep.setInt(1, i); - prep.execute(); - } - boolean abnormalTermination = true; - if (abnormalTermination) { - ((JdbcConnection) conn).setPowerOffCount(1); - try { - stat.execute("INSERT INTO TEST VALUES(-1, 'Test' || SPACE(100))"); - } catch (SQLException e) { - // ignore - } - } else { - conn.close(); - } - - System.out.println("Open connection..."); - time = System.currentTimeMillis(); - conn = DriverManager.getConnection("jdbc:h2:test;DATABASE_EVENT_LISTENER='" + getClass().getName() + "'", "sa", ""); - time = System.currentTimeMillis() - time; - System.out.println("Done after " + time + " ms"); - conn.close(); - - } - - /** - * This method is called by the database if disk space is low. - */ - public void diskSpaceIsLow() { - System.out.println("diskSpaceIsLow"); - } - - /** - * This method is called if an exception occurs in the database. - * - * @param e the exception - * @param sql the SQL statement - */ - public void exceptionThrown(SQLException e, String sql) { - System.out.println("Error executing " + sql); - e.printStackTrace(); - } - - /** - * This method is called when opening the database to notify about the progress. - * - * @param state the current state - * @param name the object name (depends on the state) - * @param current the current progress - * @param max the 100% mark - */ - public void setProgress(int state, String name, int current, int max) { - long time = System.currentTimeMillis(); - if (time < last + 5000) { - return; - } - last = time; - String stateName = "?"; - switch (state) { - case STATE_SCAN_FILE: - stateName = "Scan " + name; - break; - case STATE_CREATE_INDEX: - stateName = "Create Index " + name; - break; - case STATE_RECOVER: - stateName = "Recover"; - break; - } - try { - Thread.sleep(1); - } catch (InterruptedException e) { - // ignore - } - System.out.println("State: " + stateName + " " + (100 * current / max) + "% (" + current + " of " + max + ") " - + (time - start) + " ms"); - } - - /** - * This method is called when the database is closed. - */ - public void closingDatabase() { - System.out.println("Closing the database"); - } - - /** - * This method is called just after creating the instance. - * - * @param url the database URL - */ - public void init(String url) { - System.out.println("Initializing the event listener for database " + url); - } - - /** - * This method is called when the database is open. - */ - public void opened() { - // do nothing - } - -} diff --git a/tools/h2/src/test/org/h2/samples/ShutdownServer.java b/tools/h2/src/test/org/h2/samples/ShutdownServer.java deleted file mode 100755 index 7730257..0000000 --- a/tools/h2/src/test/org/h2/samples/ShutdownServer.java +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.samples; - -/** - * This very simple sample application stops a H2 TCP server - * if it is running. - */ -public class ShutdownServer { - - /** - * This method is called when executing this sample application from the - * command line. - * - * @param args the command line parameters - */ - public static void main(String... args) throws Exception { - org.h2.tools.Server.shutdownTcpServer("tcp://localhost:9094", "", false, false); - } -} diff --git a/tools/h2/src/test/org/h2/samples/TriggerPassData.java b/tools/h2/src/test/org/h2/samples/TriggerPassData.java deleted file mode 100755 index 36248ce..0000000 --- a/tools/h2/src/test/org/h2/samples/TriggerPassData.java +++ /dev/null @@ -1,91 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.samples; - -import java.sql.Connection; -import java.sql.DriverManager; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.sql.Statement; -import java.util.Collections; -import java.util.HashMap; -import java.util.Map; -import org.h2.api.Trigger; - -/** - * This sample application shows how to pass data to a trigger. Trigger data can - * be persisted by storing it in the database. - */ -public class TriggerPassData implements Trigger { - - private static final Map TRIGGERS = - Collections.synchronizedMap(new HashMap()); - private String triggerData; - - /** - * This method is called when executing this sample application from the - * command line. - * - * @param args the command line parameters - */ - public static void main(String... args) throws Exception { - Class.forName("org.h2.Driver"); - Connection conn = DriverManager.getConnection( - "jdbc:h2:mem:test", "sa", ""); - Statement stat = conn.createStatement(); - stat.execute("CREATE TABLE TEST(ID INT)"); - stat.execute("CREATE ALIAS TRIGGER_SET FOR \"" + - TriggerPassData.class.getName() + - ".setTriggerData\""); - stat.execute("CREATE TRIGGER T1 " + - "BEFORE INSERT ON TEST " + - "FOR EACH ROW CALL \"" + - TriggerPassData.class.getName() + "\""); - stat.execute("CALL TRIGGER_SET('T1', 'Hello')"); - stat.execute("INSERT INTO TEST VALUES(1)"); - stat.execute("CALL TRIGGER_SET('T1', 'World')"); - stat.execute("INSERT INTO TEST VALUES(2)"); - conn.close(); - } - - public void init(Connection conn, String schemaName, - String triggerName, String tableName, boolean before, - int type) throws SQLException { - TRIGGERS.put(getPrefix(conn) + triggerName, this); - } - - public void fire(Connection conn, Object[] old, Object[] row) { - System.out.println(triggerData + ": " + row[0]); - } - - public void close() { - // ignore - } - - public void remove() { - // ignore - } - - /** - * Call this method to change a specific trigger. - * - * @param conn the connection - * @param trigger the trigger name - * @param data the data - */ - public static void setTriggerData(Connection conn, String trigger, String data) throws SQLException { - TRIGGERS.get(getPrefix(conn) + trigger).triggerData = data; - } - - private static String getPrefix(Connection conn) throws SQLException { - Statement stat = conn.createStatement(); - ResultSet rs = stat.executeQuery("call ifnull(database_path() || '_', '') || database() || '_'"); - rs.next(); - return rs.getString(1); - } - -} diff --git a/tools/h2/src/test/org/h2/samples/TriggerSample.java b/tools/h2/src/test/org/h2/samples/TriggerSample.java deleted file mode 100755 index 736e9ed..0000000 --- a/tools/h2/src/test/org/h2/samples/TriggerSample.java +++ /dev/null @@ -1,109 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.samples; - -import java.math.BigDecimal; -import java.sql.Connection; -import java.sql.DriverManager; -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.sql.Statement; - -import org.h2.api.Trigger; - -/** - * This sample application shows how to use database triggers. - */ -public class TriggerSample { - - /** - * This method is called when executing this sample application from the - * command line. - * - * @param args the command line parameters - */ - public static void main(String... args) throws Exception { - Class.forName("org.h2.Driver"); - Connection conn = DriverManager.getConnection("jdbc:h2:mem:", "sa", ""); - Statement stat = conn.createStatement(); - stat.execute("CREATE TABLE INVOICE(ID INT PRIMARY KEY, AMOUNT DECIMAL)"); - stat.execute("CREATE TABLE INVOICE_SUM(AMOUNT DECIMAL)"); - stat.execute("INSERT INTO INVOICE_SUM VALUES(0.0)"); - stat.execute("CREATE TRIGGER INV_INS AFTER INSERT ON INVOICE FOR EACH ROW CALL \"org.h2.samples.TriggerSample$MyTrigger\" "); - stat.execute("CREATE TRIGGER INV_UPD AFTER UPDATE ON INVOICE FOR EACH ROW CALL \"org.h2.samples.TriggerSample$MyTrigger\" "); - stat.execute("CREATE TRIGGER INV_DEL AFTER DELETE ON INVOICE FOR EACH ROW CALL \"org.h2.samples.TriggerSample$MyTrigger\" "); - - stat.execute("INSERT INTO INVOICE VALUES(1, 10.0)"); - stat.execute("INSERT INTO INVOICE VALUES(2, 19.95)"); - stat.execute("UPDATE INVOICE SET AMOUNT=20.0 WHERE ID=2"); - stat.execute("DELETE FROM INVOICE WHERE ID=1"); - - ResultSet rs; - rs = stat.executeQuery("SELECT AMOUNT FROM INVOICE_SUM"); - rs.next(); - System.out.println("The sum is " + rs.getBigDecimal(1)); - conn.close(); - } - - /** - * This class is a simple trigger implementation. - */ - public static class MyTrigger implements Trigger { - - /** - * Initializes the trigger. - * - * @param conn a connection to the database - * @param schemaName the name of the schema - * @param triggerName the name of the trigger used in the CREATE TRIGGER - * statement - * @param tableName the name of the table - * @param before whether the fire method is called before or after the - * operation is performed - * @param type the operation type: INSERT, UPDATE, or DELETE - */ - public void init(Connection conn, String schemaName, String triggerName, String tableName, boolean before, int type) { - // Initializing trigger - } - - /** - * This method is called for each triggered action. - * - * @param conn a connection to the database - * @param oldRow the old row, or null if no old row is available (for INSERT) - * @param newRow the new row, or null if no new row is available (for DELETE) - * @throws SQLException if the operation must be undone - */ - public void fire(Connection conn, - Object[] oldRow, Object[] newRow) - throws SQLException { - BigDecimal diff = null; - if (newRow != null) { - diff = (BigDecimal) newRow[1]; - } - if (oldRow != null) { - BigDecimal m = (BigDecimal) oldRow[1]; - diff = diff == null ? m.negate() : diff.subtract(m); - } - PreparedStatement prep = conn.prepareStatement( - "UPDATE INVOICE_SUM SET AMOUNT=AMOUNT+?"); - prep.setBigDecimal(1, diff); - prep.execute(); - } - - public void close() { - // ignore - } - - public void remove() { - // ignore - } - - } - -} diff --git a/tools/h2/src/test/org/h2/samples/fullTextSearch.sql b/tools/h2/src/test/org/h2/samples/fullTextSearch.sql deleted file mode 100755 index 581e922..0000000 --- a/tools/h2/src/test/org/h2/samples/fullTextSearch.sql +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ - -// Example using the 'native' fulltext search implementation -CREATE ALIAS IF NOT EXISTS FT_INIT FOR "org.h2.fulltext.FullText.init"; -CALL FT_INIT(); -DROP TABLE IF EXISTS TEST; -CREATE TABLE TEST(ID INT PRIMARY KEY, NAME VARCHAR); -INSERT INTO TEST VALUES(1, 'Hello World'); -CALL FT_CREATE_INDEX('PUBLIC', 'TEST', NULL); -SELECT * FROM FT_SEARCH('Hello', 0, 0); -SELECT * FROM FT_SEARCH('Hallo', 0, 0); -INSERT INTO TEST VALUES(2, 'Hallo Welt'); -SELECT * FROM FT_SEARCH('Hello', 0, 0); -SELECT * FROM FT_SEARCH('Hallo', 0, 0); -CALL FT_REINDEX(); -SELECT * FROM FT_SEARCH('Hello', 0, 0); -SELECT * FROM FT_SEARCH('Hallo', 0, 0); -INSERT INTO TEST VALUES(3, 'Hello World'); -INSERT INTO TEST VALUES(4, 'Hello World'); -INSERT INTO TEST VALUES(5, 'Hello World'); -SELECT * FROM FT_SEARCH('World', 0, 0); -SELECT * FROM FT_SEARCH('World', 1, 0); -SELECT * FROM FT_SEARCH('World', 0, 2); -SELECT * FROM FT_SEARCH('World', 2, 1); -SELECT * FROM FT_SEARCH('1', 0, 0); -CALL FT_DROP_INDEX('PUBLIC', 'TEST'); -SELECT * FROM FT_SEARCH('World', 2, 1); -CALL FT_DROP_ALL(); - -// Example using the 'Lucene' fulltext search implementation -CREATE ALIAS IF NOT EXISTS FTL_INIT FOR "org.h2.fulltext.FullTextLucene.init"; -CALL FTL_INIT(); -DROP TABLE IF EXISTS TEST; -CREATE TABLE TEST(ID INT PRIMARY KEY, NAME VARCHAR); -INSERT INTO TEST VALUES(1, 'Hello World'); -CALL FTL_CREATE_INDEX('PUBLIC', 'TEST', NULL); -SELECT * FROM FTL_SEARCH('Hello', 0, 0); -SELECT * FROM FTL_SEARCH('Hallo', 0, 0); -INSERT INTO TEST VALUES(2, 'Hallo Welt'); -SELECT * FROM FTL_SEARCH('Hello', 0, 0); -SELECT * FROM FTL_SEARCH('Hallo', 0, 0); -CALL FTL_REINDEX(); -SELECT * FROM FTL_SEARCH('Hello', 0, 0); -SELECT * FROM FTL_SEARCH('Hallo', 0, 0); -INSERT INTO TEST VALUES(3, 'Hello World'); -INSERT INTO TEST VALUES(4, 'Hello World'); -INSERT INTO TEST VALUES(5, 'Hello World'); -SELECT * FROM FTL_SEARCH('World', 0, 0); -SELECT * FROM FTL_SEARCH('World', 1, 0); -SELECT * FROM FTL_SEARCH('World', 0, 2); -SELECT * FROM FTL_SEARCH('World', 2, 1); -SELECT * FROM FTL_SEARCH('1', 0, 0); -CALL FTL_DROP_ALL(); -SELECT * FROM FTL_SEARCH('World', 2, 1); -CALL FTL_DROP_ALL(); diff --git a/tools/h2/src/test/org/h2/samples/newsfeed.sql b/tools/h2/src/test/org/h2/samples/newsfeed.sql deleted file mode 100755 index 3ce4eb0..0000000 --- a/tools/h2/src/test/org/h2/samples/newsfeed.sql +++ /dev/null @@ -1,132 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ - -CREATE TABLE VERSION(ID INT PRIMARY KEY, VERSION VARCHAR, CREATED VARCHAR); -INSERT INTO VERSION VALUES -(87, '1.2.137', '2010-06-06'), -(86, '1.2.136', '2010-05-24'), -(85, '1.2.135', '2010-05-08'), -(84, '1.2.134', '2010-04-23'), -(83, '1.2.133', '2010-04-10'), -(82, '1.2.132', '2010-03-21'), -(81, '1.2.131', '2010-03-05'), -(80, '1.2.130', '2010-02-26'), -(79, '1.2.129', '2010-02-19'), -(78, '1.2.128', '2010-01-30'), -(77, '1.2.127', '2010-01-15'), -(76, '1.2.126', '2009-12-18'), -(75, '1.2.125', '2009-12-06'), -(74, '1.2.124', '2009-11-20'), -; - -CREATE TABLE CHANNEL(TITLE VARCHAR, LINK VARCHAR, DESC VARCHAR, - LANGUAGE VARCHAR, PUB TIMESTAMP, LAST TIMESTAMP, AUTHOR VARCHAR); - -INSERT INTO CHANNEL VALUES('H2 Database Engine' , - 'http://www.h2database.com/', 'H2 Database Engine', 'en-us', NOW(), NOW(), 'Thomas Mueller'); - -CREATE VIEW ITEM AS -SELECT ID, 'New version available: ' || VERSION || ' (' || CREATED || ')' TITLE, -CAST((CREATED || ' 12:00:00') AS TIMESTAMP) ISSUED, -$$A new version of H2 is available for -download. -(You may have to click 'Refresh'). -
    -For details, see the -change log. -
    -For future plans, see the -roadmap. -$$ AS DESC FROM VERSION; - -SELECT 'newsfeed-rss.xml' FILE, - XMLSTARTDOC() || - XMLNODE('rss', XMLATTR('version', '2.0'), - XMLNODE('channel', NULL, - XMLNODE('title', NULL, C.TITLE) || - XMLNODE('link', NULL, C.LINK) || - XMLNODE('description', NULL, C.DESC) || - XMLNODE('language', NULL, C.LANGUAGE) || - XMLNODE('pubDate', NULL, FORMATDATETIME(C.PUB, 'EEE, d MMM yyyy HH:mm:ss z', 'en', 'GMT')) || - XMLNODE('lastBuildDate', NULL, FORMATDATETIME(C.LAST, 'EEE, d MMM yyyy HH:mm:ss z', 'en', 'GMT')) || - GROUP_CONCAT( - XMLNODE('item', NULL, - XMLNODE('title', NULL, I.TITLE) || - XMLNODE('link', NULL, C.LINK) || - XMLNODE('description', NULL, XMLCDATA(I.TITLE)) - ) - ORDER BY I.ID DESC SEPARATOR '') - ) - ) CONTENT -FROM CHANNEL C, ITEM I -UNION -SELECT 'newsfeed-atom.xml' FILE, - XMLSTARTDOC() || - XMLNODE('feed', XMLATTR('xmlns', 'http://www.w3.org/2005/Atom') || XMLATTR('xml:lang', C.LANGUAGE), - XMLNODE('title', XMLATTR('type', 'text'), C.TITLE) || - XMLNODE('id', NULL, XMLTEXT(C.LINK)) || - XMLNODE('author', NULL, XMLNODE('name', NULL, C.AUTHOR)) || - XMLNODE('link', XMLATTR('rel', 'self') || XMLATTR('href', 'http://www.h2database.com/html/newsfeed-atom.xml'), NULL) || - XMLNODE('updated', NULL, FORMATDATETIME(C.LAST, 'yyyy-MM-dd''T''HH:mm:ss''Z''', 'en', 'GMT')) || - GROUP_CONCAT( - XMLNODE('entry', NULL, - XMLNODE('title', XMLATTR('type', 'text'), I.TITLE) || - XMLNODE('link', XMLATTR('rel', 'alternate') || XMLATTR('type', 'text/html') || XMLATTR('href', C.LINK), NULL) || - XMLNODE('id', NULL, XMLTEXT(C.LINK || '/' || I.ID)) || - XMLNODE('updated', NULL, FORMATDATETIME(I.ISSUED, 'yyyy-MM-dd''T''HH:mm:ss''Z''', 'en', 'GMT')) || - XMLNODE('content', XMLATTR('type', 'html'), XMLCDATA(I.DESC)) - ) - ORDER BY I.ID DESC SEPARATOR '') - ) CONTENT -FROM CHANNEL C, ITEM I -UNION -SELECT 'newsletter.txt' FILE, I.DESC CONTENT FROM ITEM I WHERE I.ID = (SELECT MAX(ID) FROM ITEM) -UNION -SELECT 'doap-h2.rdf' FILE, - XMLSTARTDOC() || -$$ - - H2 Database Engine - - Java - - - - - - - H2 Database Engine - - H2 is a relational database management system written in Java. - It can be embedded in Java applications or run in the client-server mode. - The disk footprint is about 1 MB. The main programming APIs are SQL and JDBC, - however the database also supports using the PostgreSQL ODBC driver by acting like a PostgreSQL server. - It is possible to create both in-memory tables, as well as disk-based tables. - Tables can be persistent or temporary. Index types are hash table and tree for in-memory tables, - and b-tree for disk-based tables. - All data manipulation operations are transactional. (from Wikipedia) - - - - - - - - -$$ || - GROUP_CONCAT( - XMLNODE('release', NULL, - XMLNODE('Version', NULL, - XMLNODE('name', NULL, 'H2 ' || V.VERSION) || - XMLNODE('created', NULL, V.CREATED) || - XMLNODE('revision', NULL, V.VERSION) - ) - ) - ORDER BY V.ID DESC SEPARATOR '') || -' -' CONTENT -FROM VERSION V diff --git a/tools/h2/src/test/org/h2/samples/optimizations.sql b/tools/h2/src/test/org/h2/samples/optimizations.sql deleted file mode 100755 index 1d94f67..0000000 --- a/tools/h2/src/test/org/h2/samples/optimizations.sql +++ /dev/null @@ -1,244 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ - -------------------------------------------------------------------------------- --- Optimize Count Star -------------------------------------------------------------------------------- --- This code snippet shows how to quickly get the the number of rows in a table. - --- Initialize the data -CREATE TABLE TEST(ID INT PRIMARY KEY); -INSERT INTO TEST SELECT X FROM SYSTEM_RANGE(1, 1000); - --- Query the count -SELECT COUNT(*) FROM TEST; ---> 1000 -; - --- Display the query plan - 'direct lookup' means the index is used -EXPLAIN SELECT COUNT(*) FROM TEST; ---> SELECT COUNT(*) ---> FROM PUBLIC.TEST /* PUBLIC.TEST.tableScan */ ---> /* direct lookup */ -; - -DROP TABLE TEST; - -------------------------------------------------------------------------------- --- Optimize Distinct -------------------------------------------------------------------------------- --- This code snippet shows how to quickly get all distinct values --- of a column for the whole table. - --- Initialize the data -CREATE TABLE TEST(ID INT PRIMARY KEY, TYPE INT); -CALL RAND(0); ---> 0.730967787376657 -; -INSERT INTO TEST SELECT X, MOD(X, 10) FROM SYSTEM_RANGE(1, 1000); - --- Create an index on the column TYPE -CREATE INDEX IDX_TEST_TYPE ON TEST(TYPE); - --- Calculate the selectivity - otherwise it will not be optimized -ANALYZE; - --- Query the distinct values -SELECT DISTINCT TYPE FROM TEST ORDER BY TYPE LIMIT 3; ---> 0 ---> 1 ---> 2 -; - --- Display the query plan - 'index sorted' means the index is used to order -EXPLAIN SELECT DISTINCT TYPE FROM TEST ORDER BY TYPE LIMIT 3; ---> SELECT DISTINCT TYPE ---> FROM PUBLIC.TEST /* PUBLIC.IDX_TEST_TYPE */ ---> ORDER BY 1 ---> LIMIT 3 ---> /* distinct */ ---> /* index sorted */ -; - -DROP TABLE TEST; - -------------------------------------------------------------------------------- --- Optimize Min Max -------------------------------------------------------------------------------- --- This code snippet shows how to quickly get the smallest and largest value --- of a column for each group. - --- Initialize the data -CREATE TABLE TEST(ID INT PRIMARY KEY, VALUE DECIMAL(100, 2)); -CALL RAND(0); ---> 0.730967787376657 -; -INSERT INTO TEST SELECT X, RAND()*100 FROM SYSTEM_RANGE(1, 1000); - --- Create an index on the column VALUE -CREATE INDEX IDX_TEST_VALUE ON TEST(VALUE); - --- Query the largest and smallest value - this is optimized -SELECT MIN(VALUE), MAX(VALUE) FROM TEST; ---> 0.01 99.89 -; - --- Display the query plan - 'direct lookup' means it's optimized -EXPLAIN SELECT MIN(VALUE), MAX(VALUE) FROM TEST; ---> SELECT MIN(VALUE), MAX(VALUE) ---> FROM PUBLIC.TEST /* PUBLIC.TEST.tableScan */ ---> /* direct lookup */ -; - -DROP TABLE TEST; - -------------------------------------------------------------------------------- --- Optimize Grouped Min Max -------------------------------------------------------------------------------- --- This code snippet shows how to quickly get the smallest and largest value --- of a column for each group. - --- Initialize the data -CREATE TABLE TEST(ID INT PRIMARY KEY, TYPE INT, VALUE DECIMAL(100, 2)); -CALL RAND(0); ---> 0.730967787376657 -; -INSERT INTO TEST SELECT X, MOD(X, 5), RAND()*100 FROM SYSTEM_RANGE(1, 1000); - --- Create an index on the columns TYPE and VALUE -CREATE INDEX IDX_TEST_TYPE_VALUE ON TEST(TYPE, VALUE); - --- Analyze to optimize the DISTINCT part of the query query -ANALYZE; - --- Query the largest and smallest value - this is optimized -SELECT TYPE, (SELECT VALUE FROM TEST T2 WHERE T.TYPE = T2.TYPE -ORDER BY TYPE, VALUE LIMIT 1) MIN -FROM (SELECT DISTINCT TYPE FROM TEST) T ORDER BY TYPE; ---> 0 0.42 ---> 1 0.14 ---> 2 0.01 ---> 3 0.40 ---> 4 0.44 -; - --- Display the query plan -EXPLAIN SELECT TYPE, (SELECT VALUE FROM TEST T2 WHERE T.TYPE = T2.TYPE -ORDER BY TYPE, VALUE LIMIT 1) MIN -FROM (SELECT DISTINCT TYPE FROM TEST) T ORDER BY TYPE; ---> SELECT TYPE, (SELECT VALUE ---> FROM PUBLIC.TEST T2 /* PUBLIC.IDX_TEST_TYPE_VALUE: TYPE = T.TYPE */ ---> WHERE T.TYPE = T2.TYPE ---> ORDER BY =TYPE, 1 ---> LIMIT 1 ---> /* index sorted */) AS MIN ---> FROM (SELECT DISTINCT TYPE ---> FROM PUBLIC.TEST /* PUBLIC.IDX_TEST_TYPE_VALUE */ ---> /* distinct */) T /* SELECT DISTINCT TYPE ---> FROM PUBLIC.TEST /++ PUBLIC.IDX_TEST_TYPE_VALUE ++/ ---> /++ distinct ++/ */ ---> ORDER BY 1 -; - -DROP TABLE TEST; - -------------------------------------------------------------------------------- --- Optimize Top N -- -------------------------------------------------------------------------------- --- This code snippet shows how to quickly get the smallest and largest N --- values of a column for the whole table. - --- Initialize the data -CREATE TABLE TEST(ID INT PRIMARY KEY, TYPE INT, VALUE DECIMAL(100, 2)); -CALL RAND(0); ---> 0.730967787376657 -; -INSERT INTO TEST SELECT X, MOD(X, 100), RAND()*100 FROM SYSTEM_RANGE(1, 1000); - --- Create an index on the column VALUE -CREATE INDEX IDX_TEST_VALUE ON TEST(VALUE); - --- Query the smallest 10 values -SELECT VALUE FROM TEST ORDER BY VALUE LIMIT 3; ---> 0.01 ---> 0.14 ---> 0.16 -; - --- Display the query plan - 'index sorted' means the index is used -EXPLAIN SELECT VALUE FROM TEST ORDER BY VALUE LIMIT 10; ---> SELECT VALUE ---> FROM PUBLIC.TEST /* PUBLIC.IDX_TEST_VALUE */ ---> ORDER BY 1 ---> LIMIT 10 ---> /* index sorted */ -; - --- To optimize getting the largest values, a new descending index is required -CREATE INDEX IDX_TEST_VALUE_D ON TEST(VALUE DESC); - --- Query the largest 10 values -SELECT VALUE FROM TEST ORDER BY VALUE DESC LIMIT 3; ---> 99.89 ---> 99.73 ---> 99.68 -; - --- Display the query plan - 'index sorted' means the index is used -EXPLAIN SELECT VALUE FROM TEST ORDER BY VALUE DESC LIMIT 10; ---> SELECT VALUE ---> FROM PUBLIC.TEST /* PUBLIC.IDX_TEST_VALUE_D */ ---> ORDER BY 1 DESC ---> LIMIT 10 ---> /* index sorted */ -; - -DROP TABLE TEST; - -------------------------------------------------------------------------------- --- Optimize IN(..) -------------------------------------------------------------------------------- --- This code snippet shows how IN(...) uses an index (unlike .. OR ..). - --- Initialize the data -CREATE TABLE TEST(ID INT PRIMARY KEY); -INSERT INTO TEST SELECT X FROM SYSTEM_RANGE(1, 1000); - --- Query the count -SELECT * FROM TEST WHERE ID IN(1, 1000); ---> 1 ---> 1000 -; - --- Display the query plan -EXPLAIN SELECT * FROM TEST WHERE ID IN(1, 1000); ---> SELECT TEST.ID ---> FROM PUBLIC.TEST /* PUBLIC.PRIMARY_KEY_2: ID IN(1, 1000) */ ---> WHERE ID IN(1, 1000) -; - -DROP TABLE TEST; - -------------------------------------------------------------------------------- --- Optimize Multiple IN(..) -------------------------------------------------------------------------------- --- This code snippet shows how multiple IN(...) conditions use an index. - --- Initialize the data -CREATE TABLE TEST(ID INT PRIMARY KEY, DATA INT); -CREATE INDEX TEST_DATA ON TEST(DATA); - -INSERT INTO TEST SELECT X, MOD(X, 10) FROM SYSTEM_RANGE(1, 1000); - --- Display the query plan -EXPLAIN SELECT * FROM TEST WHERE ID IN (10, 20) AND DATA IN (1, 2); ---> SELECT TEST.ID, TEST.DATA ---> FROM PUBLIC.TEST /* PUBLIC.PRIMARY_KEY_2: ID IN(10, 20) */ ---> WHERE (ID IN(10, 20)) AND (DATA IN(1, 2)) -; - -DROP TABLE TEST; diff --git a/tools/h2/src/test/org/h2/samples/package.html b/tools/h2/src/test/org/h2/samples/package.html deleted file mode 100755 index 2fd75f6..0000000 --- a/tools/h2/src/test/org/h2/samples/package.html +++ /dev/null @@ -1,15 +0,0 @@ - - - - -Javadoc package documentation -

    - -Standalone sample applications. - -

    \ No newline at end of file diff --git a/tools/h2/src/test/org/h2/test/TestAll.java b/tools/h2/src/test/org/h2/test/TestAll.java deleted file mode 100755 index 9431d29..0000000 --- a/tools/h2/src/test/org/h2/test/TestAll.java +++ /dev/null @@ -1,727 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.test; - -import java.sql.SQLException; -import java.util.Properties; -import org.h2.Driver; -import org.h2.engine.Constants; -import org.h2.store.fs.FileSystemDisk; -import org.h2.test.bench.TestPerformance; -import org.h2.test.db.TestAlter; -import org.h2.test.db.TestAutoRecompile; -import org.h2.test.db.TestBackup; -import org.h2.test.db.TestBigDb; -import org.h2.test.db.TestBigResult; -import org.h2.test.db.TestCases; -import org.h2.test.db.TestCheckpoint; -import org.h2.test.db.TestCluster; -import org.h2.test.db.TestCompatibility; -import org.h2.test.db.TestCsv; -import org.h2.test.db.TestDeadlock; -import org.h2.test.db.TestEncryptedDb; -import org.h2.test.db.TestExclusive; -import org.h2.test.db.TestFullText; -import org.h2.test.db.TestFunctionOverload; -import org.h2.test.db.TestFunctions; -import org.h2.test.db.TestIndex; -import org.h2.test.db.TestLargeBlob; -import org.h2.test.db.TestLinkedTable; -import org.h2.test.db.TestListener; -import org.h2.test.db.TestLob; -import org.h2.test.db.TestMemoryUsage; -import org.h2.test.db.TestMultiConn; -import org.h2.test.db.TestMultiDimension; -import org.h2.test.db.TestMultiThread; -import org.h2.test.db.TestMultiThreadedKernel; -import org.h2.test.db.TestOpenClose; -import org.h2.test.db.TestOptimizations; -import org.h2.test.db.TestOutOfMemory; -import org.h2.test.db.TestPowerOff; -import org.h2.test.db.TestReadOnly; -import org.h2.test.db.TestRights; -import org.h2.test.db.TestRunscript; -import org.h2.test.db.TestSQLInjection; -import org.h2.test.db.TestScript; -import org.h2.test.db.TestScriptSimple; -import org.h2.test.db.TestSequence; -import org.h2.test.db.TestSessionsLocks; -import org.h2.test.db.TestSpaceReuse; -import org.h2.test.db.TestSpeed; -import org.h2.test.db.TestTableEngines; -import org.h2.test.db.TestTempTables; -import org.h2.test.db.TestTransaction; -import org.h2.test.db.TestTriggersConstraints; -import org.h2.test.db.TestTwoPhaseCommit; -import org.h2.test.db.TestView; -import org.h2.test.db.TestViewAlterTable; -import org.h2.test.jaqu.AliasMapTest; -import org.h2.test.jaqu.SamplesTest; -import org.h2.test.jaqu.UpdateTest; -import org.h2.test.jdbc.TestBatchUpdates; -import org.h2.test.jdbc.TestCallableStatement; -import org.h2.test.jdbc.TestCancel; -import org.h2.test.jdbc.TestDatabaseEventListener; -import org.h2.test.jdbc.TestDriver; -import org.h2.test.jdbc.TestManyJdbcObjects; -import org.h2.test.jdbc.TestMetaData; -import org.h2.test.jdbc.TestNativeSQL; -import org.h2.test.jdbc.TestPreparedStatement; -import org.h2.test.jdbc.TestResultSet; -import org.h2.test.jdbc.TestStatement; -import org.h2.test.jdbc.TestTransactionIsolation; -import org.h2.test.jdbc.TestUpdatableResultSet; -import org.h2.test.jdbc.TestZloty; -import org.h2.test.jdbcx.TestConnectionPool; -import org.h2.test.jdbcx.TestDataSource; -import org.h2.test.jdbcx.TestXA; -import org.h2.test.jdbcx.TestXASimple; -import org.h2.test.mvcc.TestMvcc1; -import org.h2.test.mvcc.TestMvcc2; -import org.h2.test.mvcc.TestMvcc3; -import org.h2.test.mvcc.TestMvccMultiThreaded; -import org.h2.test.rowlock.TestRowLocks; -import org.h2.test.server.TestAutoServer; -import org.h2.test.server.TestNestedLoop; -import org.h2.test.server.TestWeb; -import org.h2.test.server.TestInit; -import org.h2.test.synth.TestBtreeIndex; -import org.h2.test.synth.TestCrashAPI; -import org.h2.test.synth.TestFuzzOptimizations; -import org.h2.test.synth.TestHaltApp; -import org.h2.test.synth.TestJoin; -import org.h2.test.synth.TestKill; -import org.h2.test.synth.TestKillRestart; -import org.h2.test.synth.TestKillRestartMulti; -import org.h2.test.synth.TestMultiThreaded; -import org.h2.test.synth.TestRandomSQL; -import org.h2.test.synth.TestTimer; -import org.h2.test.synth.sql.TestSynth; -import org.h2.test.synth.thread.TestMulti; -import org.h2.test.unit.TestAutoReconnect; -import org.h2.test.unit.TestCache; -import org.h2.test.unit.TestClearReferences; -import org.h2.test.unit.TestCompress; -import org.h2.test.unit.TestDataPage; -import org.h2.test.unit.TestDate; -import org.h2.test.unit.TestDateIso8601; -import org.h2.test.unit.TestExit; -import org.h2.test.unit.TestFile; -import org.h2.test.unit.TestFileLock; -import org.h2.test.unit.TestFileLockSerialized; -import org.h2.test.unit.TestFileSystem; -import org.h2.test.unit.TestFtp; -import org.h2.test.unit.TestIntArray; -import org.h2.test.unit.TestIntIntHashMap; -import org.h2.test.unit.TestMathUtils; -import org.h2.test.unit.TestNetUtils; -import org.h2.test.unit.TestOldVersion; -import org.h2.test.unit.TestOverflow; -import org.h2.test.unit.TestPageStore; -import org.h2.test.unit.TestPageStoreCoverage; -import org.h2.test.unit.TestPattern; -import org.h2.test.unit.TestPgServer; -import org.h2.test.unit.TestReader; -import org.h2.test.unit.TestRecovery; -import org.h2.test.unit.TestReopen; -import org.h2.test.unit.TestSampleApps; -import org.h2.test.unit.TestScriptReader; -import org.h2.test.unit.TestSecurity; -import org.h2.test.unit.TestShell; -import org.h2.test.unit.TestStreams; -import org.h2.test.unit.TestStringCache; -import org.h2.test.unit.TestStringUtils; -import org.h2.test.unit.TestTools; -import org.h2.test.unit.TestValue; -import org.h2.test.unit.TestValueHashMap; -import org.h2.test.unit.TestValueMemory; -import org.h2.test.utils.OutputCatcher; -import org.h2.test.utils.RecordingFileSystem; -import org.h2.test.utils.SelfDestructor; -import org.h2.test.db.TestConnectionInfo; -import org.h2.tools.DeleteDbFiles; -import org.h2.tools.Server; -import org.h2.util.Profiler; -import org.h2.util.Utils; -import org.h2.util.StringUtils; - -/** - * The main test application. JUnit is not used because loops are easier to - * write in regular java applications (most tests are ran multiple times using - * different settings). - */ -public class TestAll { - -/* - -Random test: - -java15 -cd h2database/h2/bin -del *.db -start cmd /k "java -cp .;%H2DRIVERS% org.h2.test.TestAll join >testJoin.txt" -start cmd /k "java -cp . org.h2.test.TestAll synth >testSynth.txt" -start cmd /k "java -cp . org.h2.test.TestAll all >testAll.txt" -start cmd /k "java -cp . org.h2.test.TestAll random >testRandom.txt" -start cmd /k "java -cp . org.h2.test.TestAll btree >testBtree.txt" -start cmd /k "java -cp . org.h2.test.TestAll halt >testHalt.txt" -java -cp . org.h2.test.TestAll crash >testCrash.txt - -java org.h2.test.TestAll timer - -*/ - - /** - * If the test should run with many rows. - */ - public boolean big; - - /** - * If remote database connections should be used. - */ - public boolean networked; - - /** - * If in-memory databases should be used. - */ - public boolean memory; - - /** - * If code coverage is enabled. - */ - public boolean codeCoverage; - - /** - * If the multi version concurrency control mode should be used. - */ - public boolean mvcc; - - /** - * The cipher to use (null for unencrypted). - */ - public String cipher; - - /** - * If only JDK 1.4 methods should be tested. - */ - public boolean jdk14 = true; - - /** - * The file trace level value to use. - */ - public int traceLevelFile; - - /** - * If test trace information should be written (for debugging only). - */ - public boolean traceTest; - - /** - * If testing on Google App Engine. - */ - public boolean googleAppEngine; - - /** - * If a small cache and a low number for MAX_MEMORY_ROWS should be used. - */ - public boolean diskResult; - - /** - * Test using the recording file system. - */ - public boolean record; - - /** - * If the transaction log should be kept small (that is, the log should be - * switched early). - */ - boolean smallLog; - - /** - * If SSL should be used for remote connections. - */ - boolean ssl; - - /** - * If MAX_MEMORY_UNDO=3 should be used. - */ - boolean diskUndo; - - /** - * If TRACE_LEVEL_SYSTEM_OUT should be set to 2 (for debugging only). - */ - boolean traceSystemOut; - - /** - * If the tests should run forever. - */ - boolean endless; - - /** - * The THROTTLE value to use. - */ - int throttle; - - /** - * If the test should stop when the first error occurs. - */ - boolean stopOnError; - - /** - * The cache type. - */ - String cacheType; - - private Server server; - - /** - * Run all tests. - * - * @param args the command line arguments - */ - public static void main(String... args) throws Exception { - OutputCatcher catcher = OutputCatcher.start(); - run(args); - catcher.stop(); - catcher.writeTo("Test Output", "docs/html/testOutput.html"); - } - - private static void run(String... args) throws Exception { - SelfDestructor.startCountdown(6 * 60); - long time = System.currentTimeMillis(); - TestAll test = new TestAll(); - test.printSystem(); - System.setProperty("h2.maxMemoryRowsDistinct", "128"); - System.setProperty("h2.check2", "true"); - - int initialTest; - // System.setProperty("h2.largeTransactions", "true"); - // System.setProperty("h2.lobInDatabase", "true"); - // System.setProperty("h2.analyzeAuto", "100"); - - int speedup; - // System.setProperty("h2.syncMethod", ""); - -/* - -recovery tests with small freeList pages, page size 64 - -reopen org.h2.test.unit.TestPageStore --Xmx1500m -D reopenOffset=3 -D reopenShift=1 - -power failure test -power failure test: MULTI_THREADED=TRUE -power failure test: larger binaries and additional index. -power failure test with randomly generating / dropping indexes and tables. - -drop table test; -create table test(id identity, name varchar(100) default space(100)); -@LOOP 10 insert into test select null, null from system_range(1, 100000); -delete from test; - -documentation: review package and class level javadocs -documentation: rolling review at jaqu.html - -------------- - -remove old TODO, move to roadmap - -kill a test: -kill -9 `jps -l | grep "org.h2.test." | cut -d " " -f 1` - -*/ - if (args.length > 0) { - if ("reopen".equals(args[0])) { - System.setProperty("h2.delayWrongPasswordMin", "0"); - System.setProperty("h2.check2", "false"); - System.setProperty("h2.lobInDatabase", "true"); - System.setProperty("h2.analyzeAuto", "100"); - // System.setProperty("h2.pageSize", "64"); - RecordingFileSystem.register(); - test.record = true; - TestReopen reopen = new TestReopen(); - RecordingFileSystem.setRecorder(reopen); - test.runTests(); - } else if ("crash".equals(args[0])) { - test.endless = true; - new TestCrashAPI().runTest(test); - } else if ("synth".equals(args[0])) { - new TestSynth().runTest(test); - } else if ("kill".equals(args[0])) { - new TestKill().runTest(test); - } else if ("random".equals(args[0])) { - test.endless = true; - new TestRandomSQL().runTest(test); - } else if ("join".equals(args[0])) { - new TestJoin().runTest(test); - test.endless = true; - } else if ("btree".equals(args[0])) { - new TestBtreeIndex().runTest(test); - } else if ("all".equals(args[0])) { - test.testEverything(); - } else if ("codeCoverage".equals(args[0])) { - test.codeCoverage = true; - test.runTests(); - } else if ("multiThread".equals(args[0])) { - new TestMulti().runTest(test); - } else if ("halt".equals(args[0])) { - new TestHaltApp().runTest(test); - } else if ("timer".equals(args[0])) { - new TestTimer().runTest(test); - } - } else { - test.runTests(); - Profiler prof = new Profiler(); - prof.depth = 4; - prof.interval = 1; - prof.startCollecting(); - TestPerformance.main("-init", "-db", "1"); - prof.stopCollecting(); - System.out.println(prof.getTop(3)); -// Recover.execute("data", null); -// RunScript.execute("jdbc:h2:data/test2", -// "sa1", "sa1", "data/test.h2.sql", null, false); -// Recover.execute("data", null); - } - System.out.println(TestBase.formatTime(System.currentTimeMillis() - time) + " total"); - } - - /** - * Run all tests in all possible combinations. - */ - private void testEverything() throws SQLException { - for (int c = 0; c < 3; c++) { - if (c == 0) { - cipher = null; - } else if (c == 1) { - cipher = "XTEA"; - } else { - cipher = "AES"; - } - for (int a = 0; a < 64; a++) { - smallLog = (a & 1) != 0; - big = (a & 2) != 0; - networked = (a & 4) != 0; - memory = (a & 8) != 0; - ssl = (a & 16) != 0; - diskResult = (a & 32) != 0; - for (int trace = 0; trace < 3; trace++) { - traceLevelFile = trace; - test(); - } - } - } - } - - /** - * Run the tests with a number of different settings. - */ - private void runTests() throws SQLException { - jdk14 = true; - smallLog = big = networked = memory = ssl = false; - diskResult = traceSystemOut = diskUndo = false; - mvcc = traceTest = stopOnError = false; - traceLevelFile = throttle = 0; - cipher = null; - test(); - testUnit(); - - networked = true; - memory = true; - test(); - - memory = false; - networked = false; - diskUndo = true; - diskResult = true; - traceLevelFile = 3; - throttle = 1; - cacheType = "SOFT_LRU"; - cipher = "XTEA"; - test(); - - diskUndo = false; - diskResult = false; - traceLevelFile = 1; - throttle = 0; - cacheType = null; - cipher = null; - test(); - - traceLevelFile = 2; - big = true; - smallLog = true; - networked = true; - ssl = true; - test(); - - smallLog = false; - networked = false; - ssl = false; - traceLevelFile = 0; - test(); - - big = false; - cipher = "AES"; - test(); - - mvcc = true; - cipher = null; - test(); - - memory = true; - test(); - } - - /** - * Run all tests with the current settings. - */ - private void test() throws SQLException { - System.out.println(); - System.out.println("Test " + toString() + " (" + Utils.getMemoryUsed() + " KB used)"); - beforeTest(); - - // db - new TestScriptSimple().runTest(this); - new TestScript().runTest(this); - new TestAlter().runTest(this); - new TestAutoRecompile().runTest(this); - new TestBackup().runTest(this); - new TestBigDb().runTest(this); - new TestBigResult().runTest(this); - new TestCases().runTest(this); - new TestCheckpoint().runTest(this); - new TestCluster().runTest(this); - new TestConnectionInfo().runTest(this); - new TestCompatibility().runTest(this); - new TestCsv().runTest(this); - new TestDeadlock().runTest(this); - new TestEncryptedDb().runTest(this); - new TestExclusive().runTest(this); - new TestFullText().runTest(this); - new TestFunctionOverload().runTest(this); - new TestFunctions().runTest(this); - new TestInit().runTest(this); - new TestIndex().runTest(this); - new TestLargeBlob().runTest(this); - new TestLinkedTable().runTest(this); - new TestListener().runTest(this); - new TestLob().runTest(this); - new TestMemoryUsage().runTest(this); - new TestMultiConn().runTest(this); - new TestMultiDimension().runTest(this); - new TestMultiThread().runTest(this); - new TestMultiThreadedKernel().runTest(this); - new TestOpenClose().runTest(this); - new TestOptimizations().runTest(this); - new TestOutOfMemory().runTest(this); - new TestPowerOff().runTest(this); - new TestReadOnly().runTest(this); - new TestRights().runTest(this); - new TestRunscript().runTest(this); - new TestSQLInjection().runTest(this); - new TestSessionsLocks().runTest(this); - new TestSequence().runTest(this); - new TestSpaceReuse().runTest(this); - new TestSpeed().runTest(this); - new TestTableEngines().runTest(this); - new TestTempTables().runTest(this); - new TestTransaction().runTest(this); - new TestTriggersConstraints().runTest(this); - new TestTwoPhaseCommit().runTest(this); - new TestView().runTest(this); - new TestViewAlterTable().runTest(this); - - // jaqu - new AliasMapTest().runTest(this); - new SamplesTest().runTest(this); - new UpdateTest().runTest(this); - - // jdbc - new TestBatchUpdates().runTest(this); - new TestCallableStatement().runTest(this); - new TestCancel().runTest(this); - new TestDatabaseEventListener().runTest(this); - new TestDriver().runTest(this); - new TestManyJdbcObjects().runTest(this); - new TestMetaData().runTest(this); - new TestNativeSQL().runTest(this); - new TestPreparedStatement().runTest(this); - new TestResultSet().runTest(this); - new TestStatement().runTest(this); - new TestTransactionIsolation().runTest(this); - new TestUpdatableResultSet().runTest(this); - new TestZloty().runTest(this); - - // jdbcx - new TestConnectionPool().runTest(this); - new TestDataSource().runTest(this); - new TestXA().runTest(this); - new TestXASimple().runTest(this); - - // server - new TestAutoServer().runTest(this); - new TestNestedLoop().runTest(this); - new TestWeb().runTest(this); - - // mvcc & row level locking - new TestMvcc1().runTest(this); - new TestMvcc2().runTest(this); - new TestMvcc3().runTest(this); - new TestMvccMultiThreaded().runTest(this); - new TestRowLocks().runTest(this); - - // synth - new TestBtreeIndex().runTest(this); - new TestCrashAPI().runTest(this); - new TestFuzzOptimizations().runTest(this); - new TestRandomSQL().runTest(this); - new TestKillRestart().runTest(this); - new TestKillRestartMulti().runTest(this); - new TestMultiThreaded().runTest(this); - - afterTest(); - } - - private void testUnit() { - new TestAutoReconnect().runTest(this); - new TestCache().runTest(this); - new TestClearReferences().runTest(this); - new TestCompress().runTest(this); - new TestDataPage().runTest(this); - new TestDate().runTest(this); - new TestDateIso8601().runTest(this); - new TestExit().runTest(this); - new TestFile().runTest(this); - new TestFileLock().runTest(this); - new TestFileLockSerialized().runTest(this); - new TestFtp().runTest(this); - new TestFileSystem().runTest(this); - new TestIntArray().runTest(this); - new TestIntIntHashMap().runTest(this); - new TestMathUtils().runTest(this); - new TestOldVersion().runTest(this); - new TestNetUtils().runTest(this); - new TestMultiThreadedKernel().runTest(this); - new TestOverflow().runTest(this); - new TestPageStore().runTest(this); - new TestPageStoreCoverage().runTest(this); - new TestPattern().runTest(this); - new TestPgServer().runTest(this); - new TestReader().runTest(this); - new TestRecovery().runTest(this); - new TestSampleApps().runTest(this); - new TestScriptReader().runTest(this); - runTest("org.h2.test.unit.TestServlet"); - new TestSecurity().runTest(this); - new TestShell().runTest(this); - new TestStreams().runTest(this); - new TestStringCache().runTest(this); - new TestStringUtils().runTest(this); - new TestTools().runTest(this); - new TestValue().runTest(this); - new TestValueHashMap().runTest(this); - new TestValueMemory().runTest(this); - } - - private void runTest(String className) { - try { - Class< ? > clazz = Class.forName(className); - TestBase test = (TestBase) clazz.newInstance(); - test.runTest(this); - } catch (Exception e) { - // ignore - TestBase.printlnWithTime(0, className + " class not found"); - } catch (NoClassDefFoundError e) { - // ignore - TestBase.printlnWithTime(0, className + " class not found"); - } - } - - /** - * This method is called before a complete set of tests is run. It deletes - * old database files in the test directory and trace files. It also starts - * a TCP server if the test uses remote connections. - */ - void beforeTest() throws SQLException { - Driver.load(); - FileSystemDisk.getInstance().deleteRecursive(TestBase.BASE_TEST_DIR, true); - DeleteDbFiles.execute(TestBase.BASE_TEST_DIR, null, true); - FileSystemDisk.getInstance().deleteRecursive("trace.db", false); - if (networked) { - String[] args = ssl ? new String[] { "-tcpSSL", "true", "-tcpPort", "9192" } : new String[] { "-tcpPort", - "9192" }; - server = Server.createTcpServer(args); - try { - server.start(); - } catch (SQLException e) { - System.out.println("FAIL: can not start server (may already be running)"); - server = null; - } - } - } - - private void afterTest() { - FileSystemDisk.getInstance().deleteRecursive("trace.db", true); - if (networked && server != null) { - server.stop(); - } - FileSystemDisk.getInstance().deleteRecursive(TestBase.BASE_TEST_DIR, true); - } - - private void printSystem() { - Properties prop = System.getProperties(); - System.out.println("H2 " + Constants.getFullVersion() + " @ " + new java.sql.Timestamp(System.currentTimeMillis()).toString()); - System.out.println("Java " + - prop.getProperty("java.runtime.version") + ", " + - prop.getProperty("java.vm.name")+", " + - prop.getProperty("java.vendor")); - System.out.println( - prop.getProperty("os.name") + ", " + - prop.getProperty("os.arch")+", "+ - prop.getProperty("os.version")+", "+ - prop.getProperty("sun.os.patch.level")+", "+ - prop.getProperty("file.separator")+" "+ - prop.getProperty("path.separator")+" "+ - StringUtils.javaEncode(prop.getProperty("line.separator")) + " " + - prop.getProperty("user.country") + " " + - prop.getProperty("user.language") + " " + - prop.getProperty("user.variant")+" "+ - prop.getProperty("file.encoding")); - } - - public String toString() { - StringBuilder buff = new StringBuilder(); - appendIf(buff, big, "big"); - appendIf(buff, networked, "net"); - appendIf(buff, memory, "memory"); - appendIf(buff, codeCoverage, "codeCoverage"); - appendIf(buff, mvcc, "mvcc"); - appendIf(buff, cipher != null, cipher); - appendIf(buff, cacheType != null, cacheType); - appendIf(buff, jdk14, "jdk14"); - appendIf(buff, smallLog, "smallLog"); - appendIf(buff, ssl, "ssl"); - appendIf(buff, diskUndo, "diskUndo"); - appendIf(buff, diskResult, "diskResult"); - appendIf(buff, traceSystemOut, "traceSystemOut"); - appendIf(buff, endless, "endless"); - appendIf(buff, traceLevelFile > 0, "traceLevelFile"); - appendIf(buff, throttle > 0, "throttle:" + throttle); - appendIf(buff, traceTest, "traceTest"); - appendIf(buff, stopOnError, "stopOnError"); - return buff.toString(); - } - - private void appendIf(StringBuilder buff, boolean flag, String text) { - if (flag) { - buff.append(text); - buff.append(' '); - } - } - -} diff --git a/tools/h2/src/test/org/h2/test/TestBase.java b/tools/h2/src/test/org/h2/test/TestBase.java deleted file mode 100755 index d4c3ee7..0000000 --- a/tools/h2/src/test/org/h2/test/TestBase.java +++ /dev/null @@ -1,1229 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.test; - -import java.io.File; -import java.io.FileWriter; -import java.io.IOException; -import java.io.InputStream; -import java.io.PrintWriter; -import java.io.Reader; -import java.sql.Connection; -import java.sql.DriverManager; -import java.sql.ResultSet; -import java.sql.ResultSetMetaData; -import java.sql.SQLException; -import java.sql.Statement; -import java.sql.Types; -import java.text.SimpleDateFormat; -import java.util.ArrayList; -import java.util.LinkedList; -import org.h2.constant.SysProperties; -import org.h2.jdbc.JdbcConnection; -import org.h2.message.TraceSystem; -import org.h2.store.FileLock; -import org.h2.store.fs.FileSystem; -import org.h2.test.utils.RecordingFileSystem; -import org.h2.tools.DeleteDbFiles; - -/** - * The base class for all tests. - */ -public abstract class TestBase { - - /** - * The base directory. - */ - public static final String BASE_TEST_DIR = "data"; - - /** - * The temporary directory. - */ - protected static final String TEMP_DIR = "data/temp"; - - /** - * An id used to create unique file names. - */ - protected static int uniqueId; - - /** - * The base directory to write test databases. - */ - private static String baseDir = getTestDir(""); - - /** - * The last time something was printed. - */ - private static long lastPrint; - - /** - * The test configuration. - */ - public TestAll config; - - /** - * The time when the test was started. - */ - protected long start; - - private LinkedList memory = new LinkedList(); - - /** - * Get the test directory for this test. - * - * @param name the directory name suffix - * @return the test directory - */ - public static String getTestDir(String name) { - return BASE_TEST_DIR + "/test" + name; - } - - /** - * Start the TCP server if enabled in the configuration. - */ - protected void startServerIfRequired() throws SQLException { - config.beforeTest(); - } - - /** - * Initialize the test configuration using the default settings. - * - * @return itself - */ - public TestBase init() throws Exception { - return init(new TestAll()); - } - - /** - * Initialize the test configuration. - * - * @param conf the configuration - * @return itself - */ - public TestBase init(TestAll conf) throws Exception { - baseDir = getTestDir(""); - System.setProperty("java.io.tmpdir", TEMP_DIR); - this.config = conf; - return this; - } - - /** - * Run a test case using the given seed value. - * - * @param seed the random seed value - */ - public void testCase(int seed) throws Exception { - // do nothing - } - - /** - * This method is initializes the test, runs the test by calling the test() - * method, and prints status information. It also catches exceptions so that - * the tests can continue. - * - * @param conf the test configuration - */ - public void runTest(TestAll conf) { - try { - init(conf); - start = System.currentTimeMillis(); - test(); - println(""); - } catch (Throwable e) { - println("FAIL " + e.toString()); - logError("FAIL " + e.toString(), e); - if (config.stopOnError) { - throw new AssertionError("ERROR"); - } - if (e instanceof OutOfMemoryError) { - throw (OutOfMemoryError) e; - } - } finally { - try { - FileSystem.getInstance("memFS:").deleteRecursive("memFS:", false); - FileSystem.getInstance("memLZF:").deleteRecursive("memLZF:", false); - } catch (RuntimeException e) { - e.printStackTrace(); - } - } - } - - /** - * Open a database connection in admin mode. The default user name and - * password is used. - * - * @param name the database name - * @return the connection - */ - public Connection getConnection(String name) throws SQLException { - return getConnectionInternal(getURL(name, true), getUser(), getPassword()); - } - - /** - * Open a database connection. - * - * @param name the database name - * @param user the user name to use - * @param password the password to use - * @return the connection - */ - protected Connection getConnection(String name, String user, String password) throws SQLException { - return getConnectionInternal(getURL(name, false), user, password); - } - - /** - * Get the password to use to login for the given user password. The file - * password is added if required. - * - * @param userPassword the password of this user - * @return the login password - */ - protected String getPassword(String userPassword) { - return config == null || config.cipher == null ? userPassword : "filePassword " + userPassword; - } - - /** - * Get the login password. This is usually the user password. If file - * encryption is used it is combined with the file password. - * - * @return the login password - */ - protected String getPassword() { - return getPassword("123"); - } - - /** - * Get the base directory for tests. - * If a special file system is used, the prefix is prepended. - * - * @return the directory, possibly including file system prefix - */ - protected String getBaseDir() { - if (config != null && config.record) { - return RecordingFileSystem.PREFIX + "memFS:" + baseDir; - } - return baseDir; - } - - /** - * Get the database URL for the given database name using the current - * configuration options. - * - * @param name the database name - * @param admin true if the current user is an admin - * @return the database URL - */ - protected String getURL(String name, boolean admin) { - String url; - if (name.startsWith("jdbc:")) { - return name; - } - if (config.memory) { - name = "mem:" + name; - } else { - int idx = name.indexOf(':'); - if (idx < 0 || idx > 10) { - // index > 10 if in options - name = getBaseDir() + "/" + name; - } - } - if (config.networked) { - if (config.ssl) { - url = "ssl://localhost:9192/" + name; - } else { - url = "tcp://localhost:9192/" + name; - } - } else if (config.googleAppEngine) { - url = "gae://" + name + ";FILE_LOCK=NO;AUTO_SERVER=FALSE;DB_CLOSE_ON_EXIT=FALSE"; - } else { - url = name; - } - if (!config.memory) { - if (config.smallLog && admin) { - url += ";MAX_LOG_SIZE=1"; - } - } - if (config.traceSystemOut) { - url += ";TRACE_LEVEL_SYSTEM_OUT=2"; - } - if (config.traceLevelFile > 0 && admin) { - if (url.indexOf("TRACE_LEVEL_FILE=") < 0) { - url += ";TRACE_LEVEL_FILE=" + config.traceLevelFile; - } - if (url.indexOf("TRACE_MAX_FILE_SIZE") < 0) { - url += ";TRACE_MAX_FILE_SIZE=8"; - } - } - if (config.throttle > 0) { - url += ";THROTTLE=" + config.throttle; - } - if (url.indexOf("LOCK_TIMEOUT=") < 0) { - url += ";LOCK_TIMEOUT=50"; - } - if (config.diskUndo && admin) { - url += ";MAX_MEMORY_UNDO=3"; - } - if (config.big && admin) { - // force operations to disk - url += ";MAX_OPERATION_MEMORY=1"; - } - if (config.mvcc && url.indexOf("MVCC=") < 0) { - url += ";MVCC=TRUE"; - } - if (config.cacheType != null && admin && url.indexOf("CACHE_TYPE=") < 0) { - url += ";CACHE_TYPE=" + config.cacheType; - } - if (config.diskResult && admin) { - url += ";MAX_MEMORY_ROWS=100;CACHE_SIZE=0"; - } - if (config.cipher != null) { - url += ";CIPHER=" + config.cipher; - } - return "jdbc:h2:" + url; - } - - private Connection getConnectionInternal(String url, String user, String password) throws SQLException { - org.h2.Driver.load(); - // url += ";DEFAULT_TABLE_TYPE=1"; - // Class.forName("org.hsqldb.jdbcDriver"); - // return DriverManager.getConnection("jdbc:hsqldb:" + name, "sa", ""); - return DriverManager.getConnection(url, user, password); - } - - /** - * Get the small or the big value depending on the configuration. - * - * @param small the value to return if the current test mode is 'small' - * @param big the value to return if the current test mode is 'big' - * @return small or big, depending on the configuration - */ - protected int getSize(int small, int big) { - return config.endless ? Integer.MAX_VALUE : config.big ? big : small; - } - - protected String getUser() { - return "sa"; - } - - /** - * Write a message to system out if trace is enabled. - * - * @param x the value to write - */ - protected void trace(int x) { - trace("" + x); - } - - /** - * Write a message to system out if trace is enabled. - * - * @param s the message to write - */ - public void trace(String s) { - if (config.traceTest) { - lastPrint = 0; - println(s); - } - } - - /** - * Print how much memory is currently used. - */ - protected void traceMemory() { - if (config.traceTest) { - trace("mem=" + getMemoryUsed()); - } - } - - /** - * Print the currently used memory, the message and the given time in - * milliseconds. - * - * @param s the message - * @param time the time in millis - */ - public void printTimeMemory(String s, long time) { - if (config.big) { - println(getMemoryUsed() + " MB: " + s + " ms: " + time); - } - } - - /** - * Get the number of megabytes heap memory in use. - * - * @return the used megabytes - */ - public static int getMemoryUsed() { - Runtime rt = Runtime.getRuntime(); - long memory = Long.MAX_VALUE; - for (int i = 0; i < 8; i++) { - rt.gc(); - long memNow = rt.totalMemory() - rt.freeMemory(); - if (memNow >= memory) { - break; - } - memory = memNow; - } - int mb = (int) (memory / 1024 / 1024); - return mb; - } - - /** - * Called if the test reached a point that was not expected. - * - * @throws AssertionError always throws an AssertionError - */ - protected void fail() { - fail("Unexpected success"); - } - - /** - * Called if the test reached a point that was not expected. - * - * @param string the error message - * @throws AssertionError always throws an AssertionError - */ - protected void fail(String string) { - lastPrint = 0; - println(string); - throw new AssertionError(string); - } - - /** - * Log an error message. - * - * @param s the message - * @param e the exception - */ - public static void logError(String s, Throwable e) { - if (e == null) { - e = new Exception(s); - } - System.out.flush(); - System.err.println("ERROR: " + s + " " + e.toString() + " ------------------------------"); - e.printStackTrace(); - try { - TraceSystem ts = new TraceSystem(null); - FileLock lock = new FileLock(ts, "error.lock", 1000); - lock.lock(FileLock.LOCK_FILE); - FileWriter fw = new FileWriter("error.txt", true); - PrintWriter pw = new PrintWriter(fw); - e.printStackTrace(pw); - pw.close(); - fw.close(); - lock.unlock(); - } catch (Throwable t) { - t.printStackTrace(); - } - System.err.flush(); - } - - /** - * Print a message to system out. - * - * @param s the message - */ - public void println(String s) { - long now = System.currentTimeMillis(); - if (now > lastPrint + 1000) { - lastPrint = now; - long time = now - start; - printlnWithTime(time, getClass().getName() + " " + s); - } - } - - /** - * Print a message, prepended with the specified time in milliseconds. - * - * @param millis the time in milliseconds - * @param s the message - */ - static void printlnWithTime(long millis, String s) { - System.out.println(formatTime(millis) + " " + s); - } - - /** - * Print the current time and a message to system out. - * - * @param s the message - */ - protected void printTime(String s) { - SimpleDateFormat dateFormat = new SimpleDateFormat("HH:mm:ss"); - println(dateFormat.format(new java.util.Date()) + " " + s); - } - - /** - * Format the time in the format hh:mm:ss.1234 where 1234 is milliseconds. - * - * @param millis the time in milliseconds - * @return the formatted time - */ - static String formatTime(long millis) { - String s = new java.sql.Time(java.sql.Time.valueOf("0:0:0").getTime() + millis).toString() - + "." + ("" + (1000 + (millis % 1000))).substring(1); - if (s.startsWith("00:")) { - s = s.substring(3); - } - return s; - } - - /** - * Delete all database files for this database. - * - * @param name the database name - */ - protected void deleteDb(String name) throws SQLException { - deleteDb(getBaseDir(), name); - } - - /** - * Delete all database files for a database. - * - * @param dir the directory where the database files are located - * @param name the database name - */ - protected void deleteDb(String dir, String name) throws SQLException { - DeleteDbFiles.execute(dir, name, true); - // ArrayList list; - // list = FileLister.getDatabaseFiles(baseDir, name, true); - // if (list.size() > 0) { - // System.out.println("Not deleted: " + list); - // } - } - - /** - * This method will be called by the test framework. - * - * @throws Exception if an exception in the test occurs - */ - public abstract void test() throws Exception; - - /** - * Check if two values are equal, and if not throw an exception. - * - * @param message the message to print in case of error - * @param expected the expected value - * @param actual the actual value - * @throws AssertionError if the values are not equal - */ - public void assertEquals(String message, int expected, int actual) { - if (expected != actual) { - fail("Expected: " + expected + " actual: " + actual + " message: " + message); - } - } - - /** - * Check if two values are equal, and if not throw an exception. - * - * @param expected the expected value - * @param actual the actual value - * @throws AssertionError if the values are not equal - */ - public void assertEquals(int expected, int actual) { - if (expected != actual) { - fail("Expected: " + expected + " actual: " + actual); - } - } - - /** - * Check if two values are equal, and if not throw an exception. - * - * @param expected the expected value - * @param actual the actual value - * @throws AssertionError if the values are not equal - */ - public void assertEquals(byte[] expected, byte[] actual) { - assertEquals(expected.length, actual.length); - for (int i = 0; i < expected.length; i++) { - if (expected[i] != actual[i]) { - fail("[" + i + "]: expected: " + (int) expected[i] + " actual: " + (int) actual[i]); - } - } - } - - /** - * Check if two readers are equal, and if not throw an exception. - * - * @param expected the expected value - * @param actual the actual value - * @throws AssertionError if the values are not equal - */ - protected void assertEqualReaders(Reader expected, Reader actual, int len) throws IOException { - for (int i = 0; len < 0 || i < len; i++) { - int ce = expected.read(); - int ca = actual.read(); - assertEquals(ce, ca); - if (ce == -1) { - break; - } - } - expected.close(); - actual.close(); - } - - /** - * Check if two streams are equal, and if not throw an exception. - * - * @param expected the expected value - * @param actual the actual value - * @throws AssertionError if the values are not equal - */ - protected void assertEqualStreams(InputStream expected, InputStream actual, int len) throws IOException { - // this doesn't actually read anything - just tests reading 0 bytes - actual.read(new byte[0]); - expected.read(new byte[0]); - actual.read(new byte[10], 3, 0); - expected.read(new byte[10], 0, 0); - - for (int i = 0; len < 0 || i < len; i++) { - int ca = actual.read(); - actual.read(new byte[0]); - int ce = expected.read(); - assertEquals(ce, ca); - if (ca == -1) { - break; - } - } - actual.read(new byte[10], 3, 0); - expected.read(new byte[10], 0, 0); - actual.read(new byte[0]); - expected.read(new byte[0]); - actual.close(); - expected.close(); - } - - /** - * Check if two values are equal, and if not throw an exception. - * - * @param message the message to use if the check fails - * @param expected the expected value - * @param actual the actual value - * @throws AssertionError if the values are not equal - */ - protected void assertEquals(String message, String expected, String actual) { - if (expected == null && actual == null) { - return; - } else if (expected == null || actual == null) { - fail("Expected: " + expected + " Actual: " + actual + " " + message); - } - if (!expected.equals(actual)) { - for (int i = 0; i < expected.length(); i++) { - String s = expected.substring(0, i); - if (!actual.startsWith(s)) { - expected = expected.substring(0, i) + "<*>" + expected.substring(i); - break; - } - } - int al = expected.length(); - int bl = actual.length(); - if (al > 4000) { - expected = expected.substring(0, 4000); - } - if (bl > 4000) { - actual = actual.substring(0, 4000); - } - fail("Expected: " + expected + " (" + al + ") actual: " + actual + " (" + bl + ") " + message); - } - } - - /** - * Check if two values are equal, and if not throw an exception. - * - * @param expected the expected value - * @param actual the actual value - * @throws AssertionError if the values are not equal - */ - protected void assertEquals(String expected, String actual) { - assertEquals("", expected, actual); - } - - /** - * Check if two result sets are equal, and if not throw an exception. - * - * @param message the message to use if the check fails - * @param rs0 the first result set - * @param rs1 the second result set - * @throws AssertionError if the values are not equal - */ - protected void assertEquals(String message, ResultSet rs0, ResultSet rs1) throws SQLException { - ResultSetMetaData meta = rs0.getMetaData(); - int columns = meta.getColumnCount(); - assertEquals(columns, rs1.getMetaData().getColumnCount()); - while (rs0.next()) { - assertTrue(message, rs1.next()); - for (int i = 0; i < columns; i++) { - assertEquals(message, rs0.getString(i + 1), rs1.getString(i + 1)); - } - } - assertFalse(message, rs0.next()); - assertFalse(message, rs1.next()); - } - - /** - * Check if the first value is larger or equal than the second value, and if - * not throw an exception. - * - * @param a the first value - * @param b the second value (must be smaller than the first value) - * @throws AssertionError if the first value is smaller - */ - protected void assertSmaller(long a, long b) { - if (a >= b) { - fail("a: " + a + " is not smaller than b: " + b); - } - } - - /** - * Check that a result contains the given substring. - * - * @param result the result value - * @param contains the term that should appear in the result - * @throws AssertionError if the term was not found - */ - protected void assertContains(String result, String contains) { - if (result.indexOf(contains) < 0) { - fail(result + " does not contain: " + contains); - } - } - - /** - * Check that a text starts with the expected characters.. - * - * @param text the text - * @param expectedStart the expected prefix - * @throws AssertionError if the text does not start with the expected characters - */ - protected void assertStartsWith(String text, String expectedStart) { - if (!text.startsWith(expectedStart)) { - fail(text + " does not start with: " + expectedStart); - } - } - - /** - * Check if two values are equal, and if not throw an exception. - * - * @param expected the expected value - * @param actual the actual value - * @throws AssertionError if the values are not equal - */ - protected void assertEquals(long expected, long actual) { - if (expected != actual) { - fail("Expected: " + expected + " actual: " + actual); - } - } - - /** - * Check if two values are equal, and if not throw an exception. - * - * @param expected the expected value - * @param actual the actual value - * @throws AssertionError if the values are not equal - */ - protected void assertEquals(double expected, double actual) { - if (expected != actual) { - if (Double.isNaN(expected) && Double.isNaN(actual)) { - // if both a NaN, then there is no error - } else { - fail("Expected: " + expected + " actual: " + actual); - } - } - } - - /** - * Check if two values are equal, and if not throw an exception. - * - * @param expected the expected value - * @param actual the actual value - * @throws AssertionError if the values are not equal - */ - protected void assertEquals(float expected, float actual) { - if (expected != actual) { - if (Float.isNaN(expected) && Float.isNaN(actual)) { - // if both a NaN, then there is no error - } else { - fail("Expected: " + expected + " actual: " + actual); - } - } - } - - /** - * Check if two values are equal, and if not throw an exception. - * - * @param expected the expected value - * @param actual the actual value - * @throws AssertionError if the values are not equal - */ - protected void assertEquals(boolean expected, boolean actual) { - if (expected != actual) { - fail("Boolean expected: " + expected + " actual: " + actual); - } - } - - /** - * Check that the passed boolean is true. - * - * @param condition the condition - * @throws AssertionError if the condition is false - */ - public void assertTrue(boolean condition) { - assertTrue("Expected: true got: false", condition); - } - - /** - * Check that the passed boolean is true. - * - * @param message the message to print if the condition is false - * @param condition the condition - * @throws AssertionError if the condition is false - */ - protected void assertTrue(String message, boolean condition) { - if (!condition) { - fail(message); - } - } - - /** - * Check that the passed boolean is false. - * - * @param value the condition - * @throws AssertionError if the condition is true - */ - protected void assertFalse(boolean value) { - assertFalse("Expected: false got: true", value); - } - - /** - * Check that the passed boolean is false. - * - * @param message the message to print if the condition is false - * @param value the condition - * @throws AssertionError if the condition is true - */ - protected void assertFalse(String message, boolean value) { - if (value) { - fail(message); - } - } - - /** - * Check that the result set row count matches. - * - * @param expected the number of expected rows - * @param rs the result set - * @throws AssertionError if a different number of rows have been found - */ - protected void assertResultRowCount(int expected, ResultSet rs) throws SQLException { - int i = 0; - while (rs.next()) { - i++; - } - assertEquals(expected, i); - } - - /** - * Check that the result set of a query is exactly this value. - * - * @param stat the statement - * @param sql the SQL statement to execute - * @param expected the expected result value - * @throws AssertionError if a different result value was returned - */ - protected void assertSingleValue(Statement stat, String sql, int expected) throws SQLException { - ResultSet rs = stat.executeQuery(sql); - assertTrue(rs.next()); - assertEquals(expected, rs.getInt(1)); - assertFalse(rs.next()); - } - - /** - * Check that the result set of a query is exactly this value. - * - * @param expected the expected result value - * @param stat the statement - * @param sql the SQL statement to execute - * @throws AssertionError if a different result value was returned - */ - protected void assertResult(String expected, Statement stat, String sql) throws SQLException { - ResultSet rs = stat.executeQuery(sql); - if (rs.next()) { - String actual = rs.getString(1); - assertEquals(expected, actual); - } else { - assertEquals(null, expected); - } - } - - /** - * Check if the result set meta data is correct. - * - * @param rs the result set - * @param columnCount the expected column count - * @param labels the expected column labels - * @param datatypes the expected data types - * @param precision the expected precisions - * @param scale the expected scales - */ - protected void assertResultSetMeta(ResultSet rs, int columnCount, String[] labels, int[] datatypes, int[] precision, - int[] scale) throws SQLException { - ResultSetMetaData meta = rs.getMetaData(); - int cc = meta.getColumnCount(); - if (cc != columnCount) { - fail("result set contains " + cc + " columns not " + columnCount); - } - for (int i = 0; i < columnCount; i++) { - if (labels != null) { - String l = meta.getColumnLabel(i + 1); - if (!labels[i].equals(l)) { - fail("column label " + i + " is " + l + " not " + labels[i]); - } - } - if (datatypes != null) { - int t = meta.getColumnType(i + 1); - if (datatypes[i] != t) { - fail("column datatype " + i + " is " + t + " not " + datatypes[i] + " (prec=" - + meta.getPrecision(i + 1) + " scale=" + meta.getScale(i + 1) + ")"); - } - String typeName = meta.getColumnTypeName(i + 1); - String className = meta.getColumnClassName(i + 1); - switch (t) { - case Types.INTEGER: - assertEquals("INTEGER", typeName); - assertEquals("java.lang.Integer", className); - break; - case Types.VARCHAR: - assertEquals("VARCHAR", typeName); - assertEquals("java.lang.String", className); - break; - case Types.SMALLINT: - assertEquals("SMALLINT", typeName); - assertEquals("java.lang.Short", className); - break; - case Types.TIMESTAMP: - assertEquals("TIMESTAMP", typeName); - assertEquals("java.sql.Timestamp", className); - break; - case Types.DECIMAL: - assertEquals("DECIMAL", typeName); - assertEquals("java.math.BigDecimal", className); - break; - default: - } - } - if (precision != null) { - int p = meta.getPrecision(i + 1); - if (precision[i] != p) { - fail("column precision " + i + " is " + p + " not " + precision[i]); - } - } - if (scale != null) { - int s = meta.getScale(i + 1); - if (scale[i] != s) { - fail("column scale " + i + " is " + s + " not " + scale[i]); - } - } - - } - } - - /** - * Check if a result set contains the expected data. - * The sort order is significant - * - * @param rs the result set - * @param data the expected data - * @throws AssertionError if there is a mismatch - */ - protected void assertResultSetOrdered(ResultSet rs, String[][] data) throws SQLException { - assertResultSet(true, rs, data); - } - - /** - * Check if a result set contains the expected data. - * The sort order is not significant - * - * @param rs the result set - * @param data the expected data - * @throws AssertionError if there is a mismatch - */ -// void assertResultSetUnordered(ResultSet rs, String[][] data) { -// assertResultSet(false, rs, data); -// } - - /** - * Check if a result set contains the expected data. - * - * @param ordered if the sort order is significant - * @param rs the result set - * @param data the expected data - * @throws AssertionError if there is a mismatch - */ - private void assertResultSet(boolean ordered, ResultSet rs, String[][] data) throws SQLException { - int len = rs.getMetaData().getColumnCount(); - int rows = data.length; - if (rows == 0) { - // special case: no rows - if (rs.next()) { - fail("testResultSet expected rowCount:" + rows + " got:0"); - } - } - int len2 = data[0].length; - if (len < len2) { - fail("testResultSet expected columnCount:" + len2 + " got:" + len); - } - for (int i = 0; i < rows; i++) { - if (!rs.next()) { - fail("testResultSet expected rowCount:" + rows + " got:" + i); - } - String[] row = getData(rs, len); - if (ordered) { - String[] good = data[i]; - if (!testRow(good, row, good.length)) { - fail("testResultSet row not equal, got:\n" + formatRow(row) + "\n" + formatRow(good)); - } - } else { - boolean found = false; - for (int j = 0; j < rows; j++) { - String[] good = data[i]; - if (testRow(good, row, good.length)) { - found = true; - break; - } - } - if (!found) { - fail("testResultSet no match for row:" + formatRow(row)); - } - } - } - if (rs.next()) { - String[] row = getData(rs, len); - fail("testResultSet expected rowcount:" + rows + " got:>=" + (rows + 1) + " data:" + formatRow(row)); - } - } - - private boolean testRow(String[] a, String[] b, int len) { - for (int i = 0; i < len; i++) { - String sa = a[i]; - String sb = b[i]; - if (sa == null || sb == null) { - if (sa != sb) { - return false; - } - } else { - if (!sa.equals(sb)) { - return false; - } - } - } - return true; - } - - private String[] getData(ResultSet rs, int len) throws SQLException { - String[] data = new String[len]; - for (int i = 0; i < len; i++) { - data[i] = rs.getString(i + 1); - // just check if it works - rs.getObject(i + 1); - } - return data; - } - - private String formatRow(String[] row) { - String sb = ""; - for (String r : row) { - sb += "{" + r + "}"; - } - return "{" + sb + "}"; - } - - /** - * Simulate a database crash. This method will also close the database - * files, but the files are in a state as the power was switched off. It - * doesn't throw an exception. - * - * @param conn the database connection - */ - protected void crash(Connection conn) { - ((JdbcConnection) conn).setPowerOffCount(1); - try { - conn.createStatement().execute("SET WRITE_DELAY 0"); - conn.createStatement().execute("CREATE TABLE TEST_A(ID INT)"); - fail("should be crashed already"); - } catch (SQLException e) { - // expected - } - try { - conn.close(); - } catch (SQLException e) { - // ignore - } - } - - /** - * Read a string from the reader. This method reads until end of file. - * - * @param reader the reader - * @return the string read - */ - protected String readString(Reader reader) { - if (reader == null) { - return null; - } - StringBuilder buffer = new StringBuilder(); - try { - while (true) { - int c = reader.read(); - if (c == -1) { - break; - } - buffer.append((char) c); - } - return buffer.toString(); - } catch (Exception e) { - assertTrue(false); - return null; - } - } - - /** - * Check that a given exception is not an unexpected 'general error' - * exception. - * - * @param e the error - */ - protected void assertKnownException(SQLException e) { - assertKnownException("", e); - } - - /** - * Check that a given exception is not an unexpected 'general error' - * exception. - * - * @param message the message - * @param e the exception - */ - protected void assertKnownException(String message, SQLException e) { - if (e != null && e.getSQLState().startsWith("HY000")) { - TestBase.logError("Unexpected General error " + message, e); - } - } - - /** - * Check if two values are equal, and if not throw an exception. - * - * @param expected the expected value - * @param actual the actual value - * @throws AssertionError if the values are not equal - */ - protected void assertEquals(Integer expected, Integer actual) { - if (expected == null || actual == null) { - assertTrue(expected == actual); - } else { - assertEquals(expected.intValue(), actual.intValue()); - } - } - - /** - * Check if two databases contain the same met data. - * - * @param stat1 the connection to the first database - * @param stat2 the connection to the second database - * @throws AssertionError if the databases don't match - */ - protected void assertEqualDatabases(Statement stat1, Statement stat2) throws SQLException { - if (SysProperties.ANALYZE_AUTO > 0) { - stat1.execute("analyze"); - stat2.execute("analyze"); - } - ResultSet rs1 = stat1.executeQuery("SCRIPT NOPASSWORDS"); - ResultSet rs2 = stat2.executeQuery("SCRIPT NOPASSWORDS"); - ArrayList list1 = new ArrayList(); - ArrayList list2 = new ArrayList(); - while (rs1.next()) { - String s1 = rs1.getString(1); - if (!rs2.next()) { - fail("expected: " + s1); - } - String s2 = rs2.getString(1); - if (!s1.equals(s2)) { - list1.add(s1); - list2.add(s2); - } - } - for (String s : list1) { - if (!list2.remove(s)) { - fail("only found in first: " + s); - } - } - assertEquals(0, list2.size()); - assertFalse(rs2.next()); - } - - /** - * Create a new object of the calling class. - * - * @return the new test - */ - public static TestBase createCaller() { - return createCaller(new Exception().getStackTrace()[1].getClassName()); - } - - /** - * Create a new object of the given class. - * - * @param className the class name - * @return the new test - */ - public static TestBase createCaller(String className) { - org.h2.Driver.load(); - try { - return (TestBase) Class.forName(className).newInstance(); - } catch (Exception e) { - throw new RuntimeException("Can not create object " + className, e); - } - } - - /** - * Get the classpath list used to execute java -cp ... - * - * @return the classpath list - */ - protected String getClassPath() { - return "bin" + File.pathSeparator + "temp" + File.pathSeparator + "."; - } - - /** - * Use up almost all memory. - * - * @param remainingKB the number of kilobytes that are not referenced - */ - protected void eatMemory(int remainingKB) { - byte[] reserve = new byte[remainingKB * 1024]; - // first, eat memory in 16 KB blocks, then eat in 16 byte blocks - for (int size = 16 * 1024; size > 0; size /= 1024) { - while (true) { - try { - byte[] block = new byte[16 * 1024]; - memory.add(block); - } catch (OutOfMemoryError e) { - break; - } - } - } - // silly code - makes sure there are no warnings - reserve[0] = reserve[1]; - // actually it is anyway garbage collected - reserve = null; - } - - /** - * Remove the hard reference to the memory. - */ - protected void freeMemory() { - memory.clear(); - } - -} diff --git a/tools/h2/src/test/org/h2/test/bench/Bench.java b/tools/h2/src/test/org/h2/test/bench/Bench.java deleted file mode 100755 index 9f4d307..0000000 --- a/tools/h2/src/test/org/h2/test/bench/Bench.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.test.bench; - -import java.sql.SQLException; - -/** - * The interface for benchmark tests. - */ -public interface Bench { - - /** - * Initialize the database. This includes creating tables and inserting data. - * - * @param db the database object - * @param size the amount of data - */ - void init(Database db, int size) throws SQLException; - - /** - * Run the test. - */ - void runTest() throws Exception; - - /** - * Get the name of the test. - * - * @return the test name - */ - String getName(); - -} diff --git a/tools/h2/src/test/org/h2/test/bench/BenchA.java b/tools/h2/src/test/org/h2/test/bench/BenchA.java deleted file mode 100755 index 818159c..0000000 --- a/tools/h2/src/test/org/h2/test/bench/BenchA.java +++ /dev/null @@ -1,181 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.test.bench; - -import java.math.BigDecimal; -import java.sql.PreparedStatement; -import java.sql.SQLException; -import java.util.Random; - -/** - * This test is similar to the TPC-A test of the Transaction Processing Council - * (TPC). However, only one connection and one thread is used. - *

    - * See also: http://www.tpc.org/tpca/spec/tpca_current.pdf - */ -public class BenchA implements Bench { - - private static final String FILLER = "abcdefghijklmnopqrstuvwxyz"; - private static final int DELTA = 10000; - - private Database database; - - private int branches; - private int tellers; - private int accounts; - private int transactions; - - public void init(Database db, int size) throws SQLException { - this.database = db; - transactions = size * 30; - - int scale = 1; - accounts = size * 50; - tellers = Math.max(accounts / 10, 1); - branches = Math.max(tellers / 10, 1); - - db.start(this, "Init"); - - db.openConnection(); - - db.dropTable("BRANCHES"); - db.dropTable("TELLERS"); - db.dropTable("ACCOUNTS"); - db.dropTable("HISTORY"); - - String[] create = { "CREATE TABLE BRANCHES(BID INT NOT NULL PRIMARY KEY, BBALANCE DECIMAL(15,2), FILLER VARCHAR(88))", - "CREATE TABLE TELLERS(TID INT NOT NULL PRIMARY KEY, BID INT, TBALANCE DECIMAL(15,2), FILLER VARCHAR(84))", - "CREATE TABLE ACCOUNTS(AID INT NOT NULL PRIMARY KEY, BID INT, ABALANCE DECIMAL(15,2), FILLER VARCHAR(84))", - "CREATE TABLE HISTORY(TID INT, BID INT, AID INT, DELTA DECIMAL(15,2), HTIME DATETIME, FILLER VARCHAR(40))" }; - - for (String sql : create) { - db.update(sql); - } - - PreparedStatement prep; - db.setAutoCommit(false); - int commitEvery = 1000; - prep = db.prepare("INSERT INTO BRANCHES(BID,BBALANCE,FILLER) VALUES(?,10000.00,'" + FILLER + "')"); - for (int i = 0; i < branches * scale; i++) { - prep.setInt(1, i); - db.update(prep, "insertBranches"); - if (i % commitEvery == 0) { - db.commit(); - } - } - db.commit(); - prep = db.prepare("INSERT INTO TELLERS(TID,BID,TBALANCE,FILLER) VALUES(?,?,10000.00,'" + FILLER + "')"); - for (int i = 0; i < tellers * scale; i++) { - prep.setInt(1, i); - prep.setInt(2, i / tellers); - db.update(prep, "insertTellers"); - if (i % commitEvery == 0) { - db.commit(); - } - } - db.commit(); - int len = accounts * scale; - prep = db.prepare("INSERT INTO ACCOUNTS(AID,BID,ABALANCE,FILLER) VALUES(?,?,10000.00,'" + FILLER + "')"); - for (int i = 0; i < len; i++) { - prep.setInt(1, i); - prep.setInt(2, i / accounts); - db.update(prep, "insertAccounts"); - if (i % commitEvery == 0) { - db.commit(); - } - } - db.commit(); - db.closeConnection(); - db.end(); - -// db.start(this, "Open/Close"); -// db.openConnection(); -// db.closeConnection(); -// db.end(); - } - - public void runTest() throws SQLException { - - database.start(this, "Transactions"); - database.openConnection(); - processTransactions(); - database.closeConnection(); - database.end(); - - database.openConnection(); - processTransactions(); - database.logMemory(this, "Memory Usage"); - database.closeConnection(); - - } - - private void processTransactions() throws SQLException { - Random random = database.getRandom(); - int branch = random.nextInt(branches); - int teller = random.nextInt(tellers); - - PreparedStatement updateAccount = database.prepare("UPDATE ACCOUNTS SET ABALANCE=ABALANCE+? WHERE AID=?"); - PreparedStatement selectBalance = database.prepare("SELECT ABALANCE FROM ACCOUNTS WHERE AID=?"); - PreparedStatement updateTeller = database.prepare("UPDATE TELLERS SET TBALANCE=TBALANCE+? WHERE TID=?"); - PreparedStatement updateBranch = database.prepare("UPDATE BRANCHES SET BBALANCE=BBALANCE+? WHERE BID=?"); - PreparedStatement insertHistory = database.prepare("INSERT INTO HISTORY(AID,TID,BID,DELTA,HTIME,FILLER) VALUES(?,?,?,?,?,?)"); - int accountsPerBranch = accounts / branches; - database.setAutoCommit(false); - - for (int i = 0; i < transactions; i++) { - int account; - if (random.nextInt(100) < 85) { - account = random.nextInt(accountsPerBranch) + branch * accountsPerBranch; - } else { - account = random.nextInt(accounts); - } - int max = BenchA.DELTA; - // delta: -max .. +max - - BigDecimal delta = BigDecimal.valueOf(random.nextInt(max * 2) - max); - long current = System.currentTimeMillis(); - - updateAccount.setBigDecimal(1, delta); - updateAccount.setInt(2, account); - database.update(updateAccount, "updateAccount"); - - updateTeller.setBigDecimal(1, delta); - updateTeller.setInt(2, teller); - database.update(updateTeller, "updateTeller"); - - updateBranch.setBigDecimal(1, delta); - updateBranch.setInt(2, branch); - database.update(updateBranch, "updateBranch"); - - selectBalance.setInt(1, account); - database.queryReadResult(selectBalance); - - insertHistory.setInt(1, account); - insertHistory.setInt(2, teller); - insertHistory.setInt(3, branch); - insertHistory.setBigDecimal(4, delta); - // TODO convert: should be able to convert date to timestamp - // (by using 0 for remaining fields) - // insertHistory.setDate(5, new java.sql.Date(current)); - insertHistory.setTimestamp(5, new java.sql.Timestamp(current)); - insertHistory.setString(6, BenchA.FILLER); - database.update(insertHistory, "insertHistory"); - - database.commit(); - } - updateAccount.close(); - selectBalance.close(); - updateTeller.close(); - updateBranch.close(); - insertHistory.close(); - } - - public String getName() { - return "BenchA"; - } - -} diff --git a/tools/h2/src/test/org/h2/test/bench/BenchB.java b/tools/h2/src/test/org/h2/test/bench/BenchB.java deleted file mode 100755 index 3710b44..0000000 --- a/tools/h2/src/test/org/h2/test/bench/BenchB.java +++ /dev/null @@ -1,212 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.test.bench; - -import java.sql.Connection; -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.util.Random; - -/** - * This test is similar to the TPC-B test of the Transaction Processing Council - * (TPC). Multiple threads are used (one thread per connection). Referential - * integrity is not implemented. - *

    - * See also http://www.tpc.org/tpcb - */ -public class BenchB implements Bench, Runnable { - - // master data - private Database database; - private int scale = 1; - private int branches = 1; - private int tellers = 10; - private int accounts = 100000; - private int clients = 10; - private int transactionPerClient; - - // client data - private BenchB master; - private Connection conn; - private PreparedStatement updateAccount; - private PreparedStatement selectAccount; - private PreparedStatement updateTeller; - private PreparedStatement updateBranch; - private PreparedStatement insertHistory; - private Random random; - - public BenchB() { - // nothing to do - } - - private BenchB(BenchB master, int seed) throws SQLException { - this.master = master; - random = new Random(seed); - conn = master.database.openNewConnection(); - conn.setAutoCommit(false); - updateAccount = conn.prepareStatement( - "UPDATE ACCOUNTS SET ABALANCE=ABALANCE+? WHERE AID=?"); - selectAccount = conn.prepareStatement( - "SELECT ABALANCE FROM ACCOUNTS WHERE AID=?"); - updateTeller = conn.prepareStatement( - "UPDATE TELLERS SET TBALANCE=TBALANCE+? WHERE TID=?"); - updateBranch = conn.prepareStatement( - "UPDATE BRANCHES SET BBALANCE=BBALANCE+? WHERE BID=?"); - insertHistory = conn.prepareStatement( - "INSERT INTO HISTORY(TID, BID, AID, DELTA) VALUES(?, ?, ?, ?)"); - } - - public void init(Database db, int size) throws SQLException { - this.database = db; - this.transactionPerClient = size; - - db.start(this, "Init"); - db.openConnection(); - db.dropTable("BRANCHES"); - db.dropTable("TELLERS"); - db.dropTable("ACCOUNTS"); - db.dropTable("HISTORY"); - String[] create = { "CREATE TABLE BRANCHES(BID INT NOT NULL PRIMARY KEY, BBALANCE INT, FILLER VARCHAR(88))", - "CREATE TABLE TELLERS(TID INT NOT NULL PRIMARY KEY, BID INT, TBALANCE INT, FILLER VARCHAR(84))", - "CREATE TABLE ACCOUNTS(AID INT NOT NULL PRIMARY KEY, BID INT, ABALANCE INT, FILLER VARCHAR(84))", - "CREATE TABLE HISTORY(TID INT, BID INT, AID INT, DELTA INT, TIME DATETIME, FILLER VARCHAR(22))" }; - for (String sql : create) { - db.update(sql); - } - PreparedStatement prep; - db.setAutoCommit(false); - int commitEvery = 1000; - prep = db.prepare( - "INSERT INTO BRANCHES(BID, BBALANCE) VALUES(?, 0)"); - for (int i = 0; i < branches * scale; i++) { - prep.setInt(1, i); - db.update(prep, "insertBranches"); - if (i % commitEvery == 0) { - db.commit(); - } - } - db.commit(); - prep = db.prepare( - "INSERT INTO TELLERS(TID, BID, TBALANCE) VALUES(?, ?, 0)"); - for (int i = 0; i < tellers * scale; i++) { - prep.setInt(1, i); - prep.setInt(2, i / tellers); - db.update(prep, "insertTellers"); - if (i % commitEvery == 0) { - db.commit(); - } - } - db.commit(); - int len = accounts * scale; - prep = db.prepare( - "INSERT INTO ACCOUNTS(AID, BID, ABALANCE) VALUES(?, ?, 0)"); - for (int i = 0; i < len; i++) { - prep.setInt(1, i); - prep.setInt(2, i / accounts); - db.update(prep, "insertAccounts"); - if (i % commitEvery == 0) { - db.commit(); - } - } - db.commit(); - db.closeConnection(); - db.end(); -// db.start(this, "Open/Close"); -// db.openConnection(); -// db.closeConnection(); -// db.end(); - } - - public void run() { - int accountsPerBranch = accounts / branches; - for (int i = 0; i < master.transactionPerClient; i++) { - int branch = random.nextInt(master.branches); - int teller = random.nextInt(master.tellers); - int account; - if (random.nextInt(100) < 85) { - account = random.nextInt(accountsPerBranch) + branch * accountsPerBranch; - } else { - account = random.nextInt(accounts); - } - int delta = random.nextInt(1000); - doOne(branch, teller, account, delta); - } - try { - conn.close(); - } catch (SQLException e) { - // ignore - } - } - - private void doOne(int branch, int teller, int account, int delta) { - try { - // UPDATE ACCOUNTS SET ABALANCE=ABALANCE+? WHERE AID=? - updateAccount.setInt(1, delta); - updateAccount.setInt(2, account); - updateAccount.executeUpdate(); - - // SELECT ABALANCE FROM ACCOUNTS WHERE AID=? - selectAccount.setInt(1, account); - ResultSet rs = selectAccount.executeQuery(); - while (rs.next()) { - rs.getInt(1); - } - - // UPDATE TELLERS SET TBALANCE=TABLANCE+? WHERE TID=? - updateTeller.setInt(1, delta); - updateTeller.setInt(2, teller); - updateTeller.executeUpdate(); - - // UPDATE BRANCHES SET BBALANCE=BBALANCE+? WHERE BID=? - updateBranch.setInt(1, delta); - updateBranch.setInt(2, branch); - updateBranch.executeUpdate(); - - // INSERT INTO HISTORY(TID, BID, AID, DELTA) VALUES(?, ?, ?, ?) - insertHistory.setInt(1, teller); - insertHistory.setInt(2, branch); - insertHistory.setInt(3, account); - insertHistory.setInt(4, delta); - insertHistory.executeUpdate(); - conn.commit(); - } catch (SQLException e) { - e.printStackTrace(); - } - } - - - public void runTest() throws Exception { - Database db = database; - db.start(this, "Transactions"); - db.openConnection(); - processTransactions(); - db.closeConnection(); - db.end(); - db.openConnection(); - processTransactions(); - db.logMemory(this, "Memory Usage"); - db.closeConnection(); - } - - private void processTransactions() throws Exception { - Thread[] threads = new Thread[clients]; - for (int i = 0; i < clients; i++) { - threads[i] = new Thread(new BenchB(this, i)); - } - for (Thread t : threads) { - t.start(); - } - for (Thread t : threads) { - t.join(); - } - } - - public String getName() { - return "BenchB"; - } -} diff --git a/tools/h2/src/test/org/h2/test/bench/BenchC.java b/tools/h2/src/test/org/h2/test/bench/BenchC.java deleted file mode 100755 index 2ee3aed..0000000 --- a/tools/h2/src/test/org/h2/test/bench/BenchC.java +++ /dev/null @@ -1,566 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.test.bench; - -import java.math.BigDecimal; -import java.sql.PreparedStatement; -import java.sql.SQLException; -import java.sql.Timestamp; -import java.sql.Types; - -/** - * This test is similar to the TPC-C test of the Transaction Processing Council - * (TPC). Only one connection and one thread is used. Referential integrity is - * not implemented. - *

    - * See also http://www.tpc.org - */ -public class BenchC implements Bench { - - private static final String[] TABLES = { "WAREHOUSE", "DISTRICT", "CUSTOMER", "HISTORY", "ORDERS", - "NEW_ORDER", "ITEM", "STOCK", "ORDER_LINE", "RESULTS" }; - private static final String[] CREATE_SQL = { - "CREATE TABLE WAREHOUSE(\n" + - " W_ID INT NOT NULL PRIMARY KEY,\n" + - " W_NAME VARCHAR(10),\n" + - " W_STREET_1 VARCHAR(20),\n" + - " W_STREET_2 VARCHAR(20),\n" + - " W_CITY VARCHAR(20),\n" + - " W_STATE CHAR(2),\n" + - " W_ZIP CHAR(9),\n" + - " W_TAX DECIMAL(4, 4),\n" + - " W_YTD DECIMAL(12, 2))", - "CREATE TABLE DISTRICT(\n" + - " D_ID INT NOT NULL,\n" + - " D_W_ID INT NOT NULL,\n" + - " D_NAME VARCHAR(10),\n" + - " D_STREET_1 VARCHAR(20),\n" + - " D_STREET_2 VARCHAR(20),\n" + - " D_CITY VARCHAR(20),\n" + - " D_STATE CHAR(2),\n" + - " D_ZIP CHAR(9),\n" + - " D_TAX DECIMAL(4, 4),\n" + - " D_YTD DECIMAL(12, 2),\n" + - " D_NEXT_O_ID INT,\n" + - " PRIMARY KEY (D_ID, D_W_ID))", - // + " FOREIGN KEY (D_W_ID)\n" - // + " REFERENCES WAREHOUSE(W_ID))", - "CREATE TABLE CUSTOMER(\n" + - " C_ID INT NOT NULL,\n" + - " C_D_ID INT NOT NULL,\n" + - " C_W_ID INT NOT NULL,\n" + - " C_FIRST VARCHAR(16),\n" + - " C_MIDDLE CHAR(2),\n" + - " C_LAST VARCHAR(16),\n" + - " C_STREET_1 VARCHAR(20),\n" + - " C_STREET_2 VARCHAR(20),\n" + - " C_CITY VARCHAR(20),\n" + - " C_STATE CHAR(2),\n" + - " C_ZIP CHAR(9),\n" + - " C_PHONE CHAR(16),\n" + - " C_SINCE TIMESTAMP,\n" + - " C_CREDIT CHAR(2),\n" + - " C_CREDIT_LIM DECIMAL(12, 2),\n" + - " C_DISCOUNT DECIMAL(4, 4),\n" + - " C_BALANCE DECIMAL(12, 2),\n" + - " C_YTD_PAYMENT DECIMAL(12, 2),\n" + - " C_PAYMENT_CNT DECIMAL(4),\n" + - " C_DELIVERY_CNT DECIMAL(4),\n" + - " C_DATA VARCHAR(500),\n" + - " PRIMARY KEY (C_W_ID, C_D_ID, C_ID))", - // + " FOREIGN KEY (C_W_ID, C_D_ID)\n" - // + " REFERENCES DISTRICT(D_W_ID, D_ID))", - "CREATE INDEX CUSTOMER_NAME ON CUSTOMER(C_LAST, C_D_ID, C_W_ID)", - "CREATE TABLE HISTORY(\n" + - " H_C_ID INT,\n" + - " H_C_D_ID INT,\n" + - " H_C_W_ID INT,\n" + - " H_D_ID INT,\n" + - " H_W_ID INT,\n" + - " H_DATE TIMESTAMP,\n" + - " H_AMOUNT DECIMAL(6, 2),\n" + - " H_DATA VARCHAR(24))", - // + " FOREIGN KEY(H_C_W_ID, H_C_D_ID, H_C_ID)\n" - // + " REFERENCES CUSTOMER(C_W_ID, C_D_ID, C_ID),\n" - // + " FOREIGN KEY(H_W_ID, H_D_ID)\n" - // + " REFERENCES DISTRICT(D_W_ID, D_ID))", - "CREATE TABLE ORDERS(\n" + - " O_ID INT NOT NULL,\n" + - " O_D_ID INT NOT NULL,\n" + - " O_W_ID INT NOT NULL,\n" + - " O_C_ID INT,\n" + - " O_ENTRY_D TIMESTAMP,\n" + - " O_CARRIER_ID INT,\n" + - " O_OL_CNT INT,\n" + - " O_ALL_LOCAL DECIMAL(1),\n" + - " PRIMARY KEY(O_W_ID, O_D_ID, O_ID))", - // + " FOREIGN KEY(O_W_ID, O_D_ID, O_C_ID)\n" - // + " REFERENCES CUSTOMER(C_W_ID, C_D_ID, C_ID))", - "CREATE INDEX ORDERS_OID ON ORDERS(O_ID)", - "CREATE TABLE NEW_ORDER(\n" + - " NO_O_ID INT NOT NULL,\n" + - " NO_D_ID INT NOT NULL,\n" + - " NO_W_ID INT NOT NULL,\n" + - " PRIMARY KEY(NO_W_ID, NO_D_ID, NO_O_ID))", - // + " FOREIGN KEY(NO_W_ID, NO_D_ID, NO_O_ID)\n" - // + " REFERENCES ORDER(O_W_ID, O_D_ID, O_ID))", - "CREATE TABLE ITEM(\n" + - " I_ID INT NOT NULL,\n" + - " I_IM_ID INT,\n" + - " I_NAME VARCHAR(24),\n" + - " I_PRICE DECIMAL(5, 2),\n" + - " I_DATA VARCHAR(50),\n" + - " PRIMARY KEY(I_ID))", - "CREATE TABLE STOCK(\n" + - " S_I_ID INT NOT NULL,\n" + - " S_W_ID INT NOT NULL,\n" + - " S_QUANTITY DECIMAL(4),\n" + - " S_DIST_01 CHAR(24),\n" + - " S_DIST_02 CHAR(24),\n" + - " S_DIST_03 CHAR(24),\n" + - " S_DIST_04 CHAR(24),\n" + - " S_DIST_05 CHAR(24),\n" + - " S_DIST_06 CHAR(24),\n" + - " S_DIST_07 CHAR(24),\n" + - " S_DIST_08 CHAR(24),\n" + - " S_DIST_09 CHAR(24),\n" + - " S_DIST_10 CHAR(24),\n" + - " S_YTD DECIMAL(8),\n" + - " S_ORDER_CNT DECIMAL(4),\n" + - " S_REMOTE_CNT DECIMAL(4),\n" + - " S_DATA VARCHAR(50),\n" + - " PRIMARY KEY(S_W_ID, S_I_ID))", - // + " FOREIGN KEY(S_W_ID)\n" - // + " REFERENCES WAREHOUSE(W_ID),\n" - // + " FOREIGN KEY(S_I_ID)\n" + " REFERENCES ITEM(I_ID))", - "CREATE TABLE ORDER_LINE(\n" + - " OL_O_ID INT NOT NULL,\n" + - " OL_D_ID INT NOT NULL,\n" + - " OL_W_ID INT NOT NULL,\n" + - " OL_NUMBER INT NOT NULL,\n" + - " OL_I_ID INT,\n" + - " OL_SUPPLY_W_ID INT,\n" + - " OL_DELIVERY_D TIMESTAMP,\n" + - " OL_QUANTITY DECIMAL(2),\n" + - " OL_AMOUNT DECIMAL(6, 2),\n" + - " OL_DIST_INFO CHAR(24),\n" + - " PRIMARY KEY (OL_W_ID, OL_D_ID, OL_O_ID, OL_NUMBER))", - // + " FOREIGN KEY(OL_W_ID, OL_D_ID, OL_O_ID)\n" - // + " REFERENCES ORDER(O_W_ID, O_D_ID, O_ID),\n" - // + " FOREIGN KEY(OL_SUPPLY_W_ID, OL_I_ID)\n" - // + " REFERENCES STOCK(S_W_ID, S_I_ID))", - "CREATE TABLE RESULTS(\n" + - " ID INT NOT NULL PRIMARY KEY,\n" + - " TERMINAL INT,\n" + - " OPERATION INT,\n" + - " RESPONSE_TIME INT,\n" + - " PROCESSING_TIME INT,\n" + - " KEYING_TIME INT,\n" + - " THINK_TIME INT,\n" + - " SUCCESSFUL INT,\n" + - " NOW TIMESTAMP)" }; - - int warehouses = 1; - int items = 10000; - int districtsPerWarehouse = 10; - int customersPerDistrict = 300; - - private Database database; - - private int ordersPerDistrict = 300; - - private BenchCRandom random; - private String action; - - private int commitEvery = 1000; - - - public void init(Database db, int size) throws SQLException { - this.database = db; - - random = new BenchCRandom(); - - items = size * 10; - warehouses = 1; - districtsPerWarehouse = Math.max(1, size / 100); - customersPerDistrict = Math.max(1, size / 100); - ordersPerDistrict = Math.max(1, size / 1000); - - db.start(this, "Init"); - db.openConnection(); - load(); - db.commit(); - db.closeConnection(); - db.end(); - - // db.start(this, "Open/Close"); - // db.openConnection(); - // db.closeConnection(); - // db.end(); - - } - - private void load() throws SQLException { - for (String sql : TABLES) { - database.dropTable(sql); - } - for (String sql : CREATE_SQL) { - database.update(sql); - } - database.setAutoCommit(false); - loadItem(); - loadWarehouse(); - loadCustomer(); - loadOrder(); - database.commit(); - trace("Load done"); - } - - private void trace(String s) { - action = s; - } - - private void trace(int i, int max) { - database.trace(action, i, max); - } - - private void loadItem() throws SQLException { - trace("Loading item table"); - boolean[] original = random.getBoolean(items, items / 10); - PreparedStatement prep = database.prepare( - "INSERT INTO ITEM(I_ID, I_IM_ID, I_NAME, I_PRICE, I_DATA) " + - "VALUES(?, ?, ?, ?, ?)"); - for (int id = 1; id <= items; id++) { - String name = random.getString(14, 24); - BigDecimal price = random.getBigDecimal(random.getInt(100, 10000), 2); - String data = random.getString(26, 50); - if (original[id - 1]) { - data = random.replace(data, "original"); - } - prep.setInt(1, id); - prep.setInt(2, random.getInt(1, 10000)); - prep.setString(3, name); - prep.setBigDecimal(4, price); - prep.setString(5, data); - database.update(prep, "insertItem"); - trace(id, items); - if (id % commitEvery == 0) { - database.commit(); - } - } - } - - private void loadWarehouse() throws SQLException { - trace("Loading warehouse table"); - PreparedStatement prep = database.prepare( - "INSERT INTO WAREHOUSE(W_ID, W_NAME, W_STREET_1, " + - "W_STREET_2, W_CITY, W_STATE, W_ZIP, W_TAX, W_YTD) " + - "VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?)"); - for (int id = 1; id <= warehouses; id++) { - String name = random.getString(6, 10); - String[] address = random.getAddress(); - String street1 = address[0]; - String street2 = address[1]; - String city = address[2]; - String state = address[3]; - String zip = address[4]; - BigDecimal tax = random.getBigDecimal(random.getInt(0, 2000), 4); - BigDecimal ytd = new BigDecimal("300000.00"); - prep.setInt(1, id); - prep.setString(2, name); - prep.setString(3, street1); - prep.setString(4, street2); - prep.setString(5, city); - prep.setString(6, state); - prep.setString(7, zip); - prep.setBigDecimal(8, tax); - prep.setBigDecimal(9, ytd); - database.update(prep, "insertWarehouse"); - loadStock(id); - loadDistrict(id); - if (id % commitEvery == 0) { - database.commit(); - } - } - } - - private void loadCustomer() throws SQLException { - trace("Load customer table"); - int max = warehouses * districtsPerWarehouse; - int i = 0; - for (int id = 1; id <= warehouses; id++) { - for (int districtId = 1; districtId <= districtsPerWarehouse; districtId++) { - loadCustomerSub(districtId, id); - trace(i++, max); - if (i % commitEvery == 0) { - database.commit(); - } - } - } - } - - private void loadCustomerSub(int dId, int wId) throws SQLException { - Timestamp timestamp = new Timestamp(System.currentTimeMillis()); - PreparedStatement prepCustomer = database.prepare( - "INSERT INTO CUSTOMER(C_ID, C_D_ID, C_W_ID, " + - "C_FIRST, C_MIDDLE, C_LAST, " + - "C_STREET_1, C_STREET_2, C_CITY, C_STATE, C_ZIP, " + - "C_PHONE, C_SINCE, C_CREDIT, " + - "C_CREDIT_LIM, C_DISCOUNT, C_BALANCE, C_DATA, " + - "C_YTD_PAYMENT, C_PAYMENT_CNT, C_DELIVERY_CNT) " + - "VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"); - PreparedStatement prepHistory = database.prepare( - "INSERT INTO HISTORY(H_C_ID, H_C_D_ID, H_C_W_ID, " + - "H_W_ID, H_D_ID, H_DATE, H_AMOUNT, H_DATA) " + - "VALUES (?, ?, ?, ?, ?, ?, ?, ?)"); - for (int cId = 1; cId <= customersPerDistrict; cId++) { - String first = random.getString(8, 16); - String middle = "OE"; - String last; - if (cId < 1000) { - last = random.getLastname(cId); - } else { - last = random.getLastname(random.getNonUniform(255, 0, 999)); - } - String[] address = random.getAddress(); - String street1 = address[0]; - String street2 = address[1]; - String city = address[2]; - String state = address[3]; - String zip = address[4]; - String phone = random.getNumberString(16, 16); - String credit; - if (random.getInt(0, 1) == 0) { - credit = "GC"; - } else { - credit = "BC"; - } - BigDecimal discount = random.getBigDecimal(random.getInt(0, 5000), 4); - BigDecimal balance = new BigDecimal("-10.00"); - BigDecimal creditLim = new BigDecimal("50000.00"); - String data = random.getString(300, 500); - BigDecimal ytdPayment = new BigDecimal("10.00"); - int paymentCnt = 1; - int deliveryCnt = 1; - prepCustomer.setInt(1, cId); - prepCustomer.setInt(2, dId); - prepCustomer.setInt(3, wId); - prepCustomer.setString(4, first); - prepCustomer.setString(5, middle); - prepCustomer.setString(6, last); - prepCustomer.setString(7, street1); - prepCustomer.setString(8, street2); - prepCustomer.setString(9, city); - prepCustomer.setString(10, state); - prepCustomer.setString(11, zip); - prepCustomer.setString(12, phone); - prepCustomer.setTimestamp(13, timestamp); - prepCustomer.setString(14, credit); - prepCustomer.setBigDecimal(15, creditLim); - prepCustomer.setBigDecimal(16, discount); - prepCustomer.setBigDecimal(17, balance); - prepCustomer.setString(18, data); - prepCustomer.setBigDecimal(19, ytdPayment); - prepCustomer.setInt(20, paymentCnt); - prepCustomer.setInt(21, deliveryCnt); - database.update(prepCustomer, "insertCustomer"); - BigDecimal amount = new BigDecimal("10.00"); - String hData = random.getString(12, 24); - prepHistory.setInt(1, cId); - prepHistory.setInt(2, dId); - prepHistory.setInt(3, wId); - prepHistory.setInt(4, wId); - prepHistory.setInt(5, dId); - prepHistory.setTimestamp(6, timestamp); - prepHistory.setBigDecimal(7, amount); - prepHistory.setString(8, hData); - database.update(prepHistory, "insertHistory"); - } - } - - private void loadOrder() throws SQLException { - trace("Loading order table"); - int max = warehouses * districtsPerWarehouse; - int i = 0; - for (int wId = 1; wId <= warehouses; wId++) { - for (int dId = 1; dId <= districtsPerWarehouse; dId++) { - loadOrderSub(dId, wId); - trace(i++, max); - } - } - } - - private void loadOrderSub(int dId, int wId) throws SQLException { - Timestamp timestamp = new Timestamp(System.currentTimeMillis()); - int[] orderid = random.getPermutation(ordersPerDistrict); - PreparedStatement prepOrder = database.prepare( - "INSERT INTO ORDERS(O_ID, O_C_ID, O_D_ID, O_W_ID, " + - "O_ENTRY_D, O_CARRIER_ID, O_OL_CNT, O_ALL_LOCAL) " + - "VALUES(?, ?, ?, ?, ?, ?, ?, 1)"); - PreparedStatement prepNewOrder = database.prepare( - "INSERT INTO NEW_ORDER (NO_O_ID, NO_D_ID, NO_W_ID) " + - "VALUES (?, ?, ?)"); - PreparedStatement prepLine = database.prepare( - "INSERT INTO ORDER_LINE(" + - "OL_O_ID, OL_D_ID, OL_W_ID, OL_NUMBER, " + - "OL_I_ID, OL_SUPPLY_W_ID, OL_QUANTITY, OL_AMOUNT, " + - "OL_DIST_INFO, OL_DELIVERY_D)" + - "VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, NULL)"); - for (int oId = 1, i = 0; oId <= ordersPerDistrict; oId++) { - int cId = orderid[oId - 1]; - int carrierId = random.getInt(1, 10); - int olCnt = random.getInt(5, 15); - prepOrder.setInt(1, oId); - prepOrder.setInt(2, cId); - prepOrder.setInt(3, dId); - prepOrder.setInt(4, wId); - prepOrder.setTimestamp(5, timestamp); - prepOrder.setInt(7, olCnt); - if (oId <= 2100) { - prepOrder.setInt(6, carrierId); - } else { - // the last 900 orders have not been delivered - prepOrder.setNull(6, Types.INTEGER); - prepNewOrder.setInt(1, oId); - prepNewOrder.setInt(2, dId); - prepNewOrder.setInt(3, wId); - database.update(prepNewOrder, "newNewOrder"); - } - database.update(prepOrder, "insertOrder"); - for (int ol = 1; ol <= olCnt; ol++) { - int id = random.getInt(1, items); - int supplyId = wId; - int quantity = 5; - String distInfo = random.getString(24); - BigDecimal amount; - if (oId < 2101) { - amount = random.getBigDecimal(0, 2); - } else { - amount = random.getBigDecimal(random.getInt(0, 1000000), 2); - } - prepLine.setInt(1, oId); - prepLine.setInt(2, dId); - prepLine.setInt(3, wId); - prepLine.setInt(4, ol); - prepLine.setInt(5, id); - prepLine.setInt(6, supplyId); - prepLine.setInt(7, quantity); - prepLine.setBigDecimal(8, amount); - prepLine.setString(9, distInfo); - database.update(prepLine, "insertOrderLine"); - if (i++ % commitEvery == 0) { - database.commit(); - } - } - } - } - - private void loadStock(int wId) throws SQLException { - trace("Loading stock table (warehouse " + wId + ")"); - boolean[] original = random.getBoolean(items, items / 10); - PreparedStatement prep = database.prepare( - "INSERT INTO STOCK(S_I_ID, S_W_ID, S_QUANTITY, " + - "S_DIST_01, S_DIST_02, S_DIST_03, S_DIST_04, S_DIST_05, " + - "S_DIST_06, S_DIST_07, S_DIST_08, S_DIST_09, S_DIST_10, " + - "S_DATA, S_YTD, S_ORDER_CNT, S_REMOTE_CNT) " + - "VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"); - for (int id = 1; id <= items; id++) { - int quantity = random.getInt(10, 100); - String dist01 = random.getString(24); - String dist02 = random.getString(24); - String dist03 = random.getString(24); - String dist04 = random.getString(24); - String dist05 = random.getString(24); - String dist06 = random.getString(24); - String dist07 = random.getString(24); - String dist08 = random.getString(24); - String dist09 = random.getString(24); - String dist10 = random.getString(24); - String data = random.getString(26, 50); - if (original[id - 1]) { - data = random.replace(data, "original"); - } - prep.setInt(1, id); - prep.setInt(2, wId); - prep.setInt(3, quantity); - prep.setString(4, dist01); - prep.setString(5, dist02); - prep.setString(6, dist03); - prep.setString(7, dist04); - prep.setString(8, dist05); - prep.setString(9, dist06); - prep.setString(10, dist07); - prep.setString(11, dist08); - prep.setString(12, dist09); - prep.setString(13, dist10); - prep.setString(14, data); - prep.setInt(15, 0); - prep.setInt(16, 0); - prep.setInt(17, 0); - database.update(prep, "insertStock"); - if (id % commitEvery == 0) { - database.commit(); - } - trace(id, items); - } - } - - private void loadDistrict(int wId) throws SQLException { - BigDecimal ytd = new BigDecimal("300000.00"); - int nextId = 3001; - PreparedStatement prep = database.prepare( - "INSERT INTO DISTRICT(D_ID, D_W_ID, D_NAME, " + - "D_STREET_1, D_STREET_2, D_CITY, D_STATE, D_ZIP, " + - "D_TAX, D_YTD, D_NEXT_O_ID) " + - "VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"); - for (int dId = 1; dId <= districtsPerWarehouse; dId++) { - String name = random.getString(6, 10); - String[] address = random.getAddress(); - String street1 = address[0]; - String street2 = address[1]; - String city = address[2]; - String state = address[3]; - String zip = address[4]; - BigDecimal tax = random.getBigDecimal(random.getInt(0, 2000), 4); - prep.setInt(1, dId); - prep.setInt(2, wId); - prep.setString(3, name); - prep.setString(4, street1); - prep.setString(5, street2); - prep.setString(6, city); - prep.setString(7, state); - prep.setString(8, zip); - prep.setBigDecimal(9, tax); - prep.setBigDecimal(10, ytd); - prep.setInt(11, nextId); - database.update(prep, "insertDistrict"); - trace(dId, districtsPerWarehouse); - } - } - - public void runTest() throws SQLException { - database.start(this, "Transactions"); - database.openConnection(); - for (int i = 0; i < 70; i++) { - BenchCThread process = new BenchCThread(database, this, random, i); - process.process(); - } - database.closeConnection(); - database.end(); - - database.openConnection(); - BenchCThread process = new BenchCThread(database, this, random, 0); - process.process(); - database.logMemory(this, "Memory Usage"); - database.closeConnection(); - } - - public String getName() { - return "BenchC"; - } - -} diff --git a/tools/h2/src/test/org/h2/test/bench/BenchCRandom.java b/tools/h2/src/test/org/h2/test/bench/BenchCRandom.java deleted file mode 100755 index 325c9bf..0000000 --- a/tools/h2/src/test/org/h2/test/bench/BenchCRandom.java +++ /dev/null @@ -1,180 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.test.bench; - -import java.math.BigDecimal; -import java.math.BigInteger; -import java.util.Random; - -/** - * The random data generator used for BenchC. - */ -public class BenchCRandom { - - private Random random = new Random(10); - - /** - * Get a non-uniform random integer value between min and max. - * - * @param a the bit mask - * @param min the minimum value - * @param max the maximum value - * @return the random value - */ - int getNonUniform(int a, int min, int max) { - int c = 0; - return (((getInt(0, a) | getInt(min, max)) + c) % (max - min + 1)) - + min; - } - - /** - * Get a random integer value between min and max. - * - * @param min the minimum value - * @param max the maximum value - * @return the random value - */ - int getInt(int min, int max) { - return max <= min ? min : (random.nextInt(max - min) + min); - } - - /** - * Generate a boolean array with this many items set to true (randomly - * distributed). - * - * @param length the size of the array - * @param trueCount the number of true elements - * @return the boolean array - */ - boolean[] getBoolean(int length, int trueCount) { - boolean[] data = new boolean[length]; - for (int i = 0, pos; i < trueCount; i++) { - do { - pos = getInt(0, length); - } while (data[pos]); - data[pos] = true; - } - return data; - } - - /** - * Replace a random part of the string with another text. - * - * @param text the original text - * @param replacement the replacement - * @return the patched string - */ - String replace(String text, String replacement) { - int pos = getInt(0, text.length() - replacement.length()); - StringBuilder buffer = new StringBuilder(text); - buffer.replace(pos, pos + 7, replacement); - return buffer.toString(); - } - - /** - * Get a random number string. - * - * @param min the minimum value - * @param max the maximum value - * @return the number string - */ - String getNumberString(int min, int max) { - int len = getInt(min, max); - char[] buff = new char[len]; - for (int i = 0; i < len; i++) { - buff[i] = (char) getInt('0', '9'); - } - return new String(buff); - } - - /** - * Get random address data. - * - * @return the address - */ - String[] getAddress() { - String str1 = getString(10, 20); - String str2 = getString(10, 20); - String city = getString(10, 20); - String state = getString(2); - String zip = getNumberString(9, 9); - return new String[] { str1, str2, city, state, zip }; - } - - /** - * Get a random string. - * - * @param min the minimum size - * @param max the maximum size - * @return the string - */ - String getString(int min, int max) { - return getString(getInt(min, max)); - } - - /** - * Get a random string. - * - * @param len the size - * @return the string - */ - String getString(int len) { - char[] buff = new char[len]; - for (int i = 0; i < len; i++) { - buff[i] = (char) getInt('A', 'Z'); - } - return new String(buff); - } - - /** - * Generate a random permutation if the values 0 .. length. - * - * @param length the number of elements - * @return the random permutation - */ - int[] getPermutation(int length) { - int[] data = new int[length]; - for (int i = 0; i < length; i++) { - data[i] = i; - } - for (int i = 0; i < length; i++) { - int j = getInt(0, length); - int temp = data[i]; - data[i] = data[j]; - data[j] = temp; - } - return data; - } - - /** - * Create a big decimal value. - * - * @param value the value - * @param scale the scale - * @return the big decimal object - */ - BigDecimal getBigDecimal(int value, int scale) { - return new BigDecimal(new BigInteger(String.valueOf(value)), scale); - } - - /** - * Generate a last name composed of three elements - * - * @param i the last name index - * @return the name - */ - String getLastname(int i) { - String[] n = { "BAR", "OUGHT", "ABLE", "PRI", "PRES", "ESE", "ANTI", - "CALLY", "ATION", "EING" }; - StringBuilder buff = new StringBuilder(); - buff.append(n[i / 100]); - buff.append(n[(i / 10) % 10]); - buff.append(n[i % 10]); - return buff.toString(); - } - -} diff --git a/tools/h2/src/test/org/h2/test/bench/BenchCThread.java b/tools/h2/src/test/org/h2/test/bench/BenchCThread.java deleted file mode 100755 index 692e9f6..0000000 --- a/tools/h2/src/test/org/h2/test/bench/BenchCThread.java +++ /dev/null @@ -1,725 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.test.bench; - -import java.math.BigDecimal; -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.sql.Timestamp; -import java.util.HashMap; - -/** - * This class implements the functionality of one thread of BenchC. - */ -public class BenchCThread { - - private static final int OP_NEW_ORDER = 0, OP_PAYMENT = 1, - OP_ORDER_STATUS = 2, OP_DELIVERY = 3, - OP_STOCK_LEVEL = 4; - private static final BigDecimal ONE = new BigDecimal("1"); - - private Database db; - private int warehouseId; - private int terminalId; - private HashMap prepared = new HashMap(); - private BenchCRandom random; - private BenchC bench; - - BenchCThread(Database db, BenchC bench, BenchCRandom random, int terminal) - throws SQLException { - this.db = db; - this.bench = bench; - this.terminalId = terminal; - db.setAutoCommit(false); - this.random = random; - warehouseId = random.getInt(1, bench.warehouses); - } - - /** - * Process the list of operations (a 'deck') in random order. - */ - void process() throws SQLException { - int[] deck = { OP_NEW_ORDER, OP_NEW_ORDER, OP_NEW_ORDER, - OP_NEW_ORDER, OP_NEW_ORDER, OP_NEW_ORDER, OP_NEW_ORDER, - OP_NEW_ORDER, OP_NEW_ORDER, OP_NEW_ORDER, OP_PAYMENT, - OP_PAYMENT, OP_PAYMENT, OP_PAYMENT, OP_PAYMENT, OP_PAYMENT, - OP_PAYMENT, OP_PAYMENT, OP_PAYMENT, OP_PAYMENT, - OP_ORDER_STATUS, OP_DELIVERY, OP_STOCK_LEVEL }; - int len = deck.length; - for (int i = 0; i < len; i++) { - int temp = deck[i]; - int j = random.getInt(0, len); - deck[i] = deck[j]; - deck[j] = temp; - } - for (int op : deck) { - switch (op) { - case OP_NEW_ORDER: - processNewOrder(); - break; - case OP_PAYMENT: - processPayment(); - break; - case OP_ORDER_STATUS: - processOrderStatus(); - break; - case OP_DELIVERY: - processDelivery(); - break; - case OP_STOCK_LEVEL: - processStockLevel(); - break; - default: - throw new AssertionError("op=" + op); - } - } - } - - private void processNewOrder() throws SQLException { - int dId = random.getInt(1, bench.districtsPerWarehouse); - int cId = random.getNonUniform(1023, 1, bench.customersPerDistrict); - int olCnt = random.getInt(5, 15); - boolean rollback = random.getInt(1, 100) == 1; - int[] supplyId = new int[olCnt]; - int[] itemId = new int[olCnt]; - int[] quantity = new int[olCnt]; - int allLocal = 1; - for (int i = 0; i < olCnt; i++) { - int w; - if (bench.warehouses > 1 && random.getInt(1, 100) == 1) { - do { - w = random.getInt(1, bench.warehouses); - } while (w != warehouseId); - allLocal = 0; - } else { - w = warehouseId; - } - supplyId[i] = w; - int item; - if (rollback && i == olCnt - 1) { - // unused order number - item = -1; - } else { - item = random.getNonUniform(8191, 1, bench.items); - } - itemId[i] = item; - quantity[i] = random.getInt(1, 10); - } - char[] bg = new char[olCnt]; - int[] stock = new int[olCnt]; - BigDecimal[] amt = new BigDecimal[olCnt]; - Timestamp datetime = new Timestamp(System.currentTimeMillis()); - PreparedStatement prep; - ResultSet rs; - - prep = prepare("UPDATE DISTRICT SET D_NEXT_O_ID=D_NEXT_O_ID+1 " - + "WHERE D_ID=? AND D_W_ID=?"); - prep.setInt(1, dId); - prep.setInt(2, warehouseId); - db.update(prep, "updateDistrict"); - prep = prepare("SELECT D_NEXT_O_ID, D_TAX FROM DISTRICT " - + "WHERE D_ID=? AND D_W_ID=?"); - prep.setInt(1, dId); - prep.setInt(2, warehouseId); - rs = db.query(prep); - rs.next(); - int oId = rs.getInt(1) - 1; - BigDecimal tax = rs.getBigDecimal(2); - rs.close(); - prep = prepare("SELECT C_DISCOUNT, C_LAST, C_CREDIT, W_TAX " - + "FROM CUSTOMER, WAREHOUSE " - + "WHERE C_ID=? AND W_ID=? AND C_W_ID=W_ID AND C_D_ID=?"); - prep.setInt(1, cId); - prep.setInt(2, warehouseId); - prep.setInt(3, dId); - rs = db.query(prep); - rs.next(); - BigDecimal discount = rs.getBigDecimal(1); - // c_last - rs.getString(2); - // c_credit - rs.getString(3); - BigDecimal wTax = rs.getBigDecimal(4); - rs.close(); - BigDecimal total = new BigDecimal("0"); - for (int number = 1; number <= olCnt; number++) { - int olId = itemId[number - 1]; - int olSupplyId = supplyId[number - 1]; - int olQuantity = quantity[number - 1]; - prep = prepare("SELECT I_PRICE, I_NAME, I_DATA " - + "FROM ITEM WHERE I_ID=?"); - prep.setInt(1, olId); - rs = db.query(prep); - if (!rs.next()) { - if (rollback) { - // item not found - correct behavior - db.rollback(); - return; - } - throw new SQLException("item not found: " + olId + " " - + olSupplyId); - } - BigDecimal price = rs.getBigDecimal(1); - // i_name - rs.getString(2); - String data = rs.getString(3); - rs.close(); - prep = prepare("SELECT S_QUANTITY, S_DATA, " - + "S_DIST_01, S_DIST_02, S_DIST_03, S_DIST_04, S_DIST_05, " - + "S_DIST_06, S_DIST_07, S_DIST_08, S_DIST_09, S_DIST_10 " - + "FROM STOCK WHERE S_I_ID=? AND S_W_ID=?"); - prep.setInt(1, olId); - prep.setInt(2, olSupplyId); - rs = db.query(prep); - if (!rs.next()) { - if (rollback) { - // item not found - correct behavior - db.rollback(); - return; - } - throw new SQLException("item not found: " + olId + " " - + olSupplyId); - } - int sQuantity = rs.getInt(1); - String sData = rs.getString(2); - String[] dist = new String[10]; - for (int i = 0; i < 10; i++) { - dist[i] = rs.getString(3 + i); - } - rs.close(); - String distInfo = dist[dId - 1]; - stock[number - 1] = sQuantity; - if ((data.indexOf("original") != -1) - && (sData.indexOf("original") != -1)) { - bg[number - 1] = 'B'; - } else { - bg[number - 1] = 'G'; - } - if (sQuantity > olQuantity) { - sQuantity = sQuantity - olQuantity; - } else { - sQuantity = sQuantity - olQuantity + 91; - } - prep = prepare("UPDATE STOCK SET S_QUANTITY=? " - + "WHERE S_W_ID=? AND S_I_ID=?"); - prep.setInt(1, sQuantity); - prep.setInt(2, olSupplyId); - prep.setInt(3, olId); - db.update(prep, "updateStock"); - BigDecimal olAmount = new BigDecimal(olQuantity).multiply( - price).multiply(ONE.add(wTax).add(tax)).multiply( - ONE.subtract(discount)); - olAmount = olAmount.setScale(2, BigDecimal.ROUND_HALF_UP); - amt[number - 1] = olAmount; - total = total.add(olAmount); - prep = prepare("INSERT INTO ORDER_LINE (OL_O_ID, OL_D_ID, OL_W_ID, OL_NUMBER, " - + "OL_I_ID, OL_SUPPLY_W_ID, " - + "OL_QUANTITY, OL_AMOUNT, OL_DIST_INFO) " - + "VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)"); - prep.setInt(1, oId); - prep.setInt(2, dId); - prep.setInt(3, warehouseId); - prep.setInt(4, number); - prep.setInt(5, olId); - prep.setInt(6, olSupplyId); - prep.setInt(7, olQuantity); - prep.setBigDecimal(8, olAmount); - prep.setString(9, distInfo); - db.update(prep, "insertOrderLine"); - } - prep = prepare("INSERT INTO ORDERS (O_ID, O_D_ID, O_W_ID, O_C_ID, " - + "O_ENTRY_D, O_OL_CNT, O_ALL_LOCAL) " - + "VALUES (?, ?, ?, ?, ?, ?, ?)"); - prep.setInt(1, oId); - prep.setInt(2, dId); - prep.setInt(3, warehouseId); - prep.setInt(4, cId); - prep.setTimestamp(5, datetime); - prep.setInt(6, olCnt); - prep.setInt(7, allLocal); - db.update(prep, "insertOrders"); - prep = prepare("INSERT INTO NEW_ORDER (NO_O_ID, NO_D_ID, NO_W_ID) " - + "VALUES (?, ?, ?)"); - prep.setInt(1, oId); - prep.setInt(2, dId); - prep.setInt(3, warehouseId); - db.update(prep, "insertNewOrder"); - db.commit(); - } - - private void processPayment() throws SQLException { - int dId = random.getInt(1, bench.districtsPerWarehouse); - int wId, cdId; - if (bench.warehouses > 1 && random.getInt(1, 100) <= 15) { - do { - wId = random.getInt(1, bench.warehouses); - } while (wId != warehouseId); - cdId = random.getInt(1, bench.districtsPerWarehouse); - } else { - wId = warehouseId; - cdId = dId; - } - boolean byName; - String last; - int cId = 1; - if (random.getInt(1, 100) <= 60) { - byName = true; - last = random.getLastname(random.getNonUniform(255, 0, 999)); - } else { - byName = false; - last = ""; - cId = random.getNonUniform(1023, 1, bench.customersPerDistrict); - } - BigDecimal amount = random.getBigDecimal(random.getInt(100, 500000), - 2); - Timestamp datetime = new Timestamp(System.currentTimeMillis()); - PreparedStatement prep; - ResultSet rs; - - prep = prepare("UPDATE DISTRICT SET D_YTD = D_YTD+? " - + "WHERE D_ID=? AND D_W_ID=?"); - prep.setBigDecimal(1, amount); - prep.setInt(2, dId); - prep.setInt(3, warehouseId); - db.update(prep, "updateDistrict"); - prep = prepare("UPDATE WAREHOUSE SET W_YTD=W_YTD+? WHERE W_ID=?"); - prep.setBigDecimal(1, amount); - prep.setInt(2, warehouseId); - db.update(prep, "updateWarehouse"); - prep = prepare("SELECT W_STREET_1, W_STREET_2, W_CITY, W_STATE, W_ZIP, W_NAME " - + "FROM WAREHOUSE WHERE W_ID=?"); - prep.setInt(1, warehouseId); - rs = db.query(prep); - rs.next(); - // w_street_1 - rs.getString(1); - // w_street_2 - rs.getString(2); - // w_city - rs.getString(3); - // w_state - rs.getString(4); - // w_zip - rs.getString(5); - String wName = rs.getString(6); - rs.close(); - prep = prepare("SELECT D_STREET_1, D_STREET_2, D_CITY, D_STATE, D_ZIP, D_NAME " - + "FROM DISTRICT WHERE D_ID=? AND D_W_ID=?"); - prep.setInt(1, dId); - prep.setInt(2, warehouseId); - rs = db.query(prep); - rs.next(); - // d_street_1 - rs.getString(1); - // d_street_2 - rs.getString(2); - // d_city - rs.getString(3); - // d_state - rs.getString(4); - // d_zip - rs.getString(5); - String dName = rs.getString(6); - rs.close(); - BigDecimal balance; - String credit; - if (byName) { - prep = prepare("SELECT COUNT(C_ID) FROM CUSTOMER " - + "WHERE C_LAST=? AND C_D_ID=? AND C_W_ID=?"); - prep.setString(1, last); - prep.setInt(2, cdId); - prep.setInt(3, wId); - rs = db.query(prep); - rs.next(); - int namecnt = rs.getInt(1); - rs.close(); - if (namecnt == 0) { - // TODO TPC-C: check if this can happen - db.rollback(); - return; - } - prep = prepare("SELECT C_FIRST, C_MIDDLE, C_ID, " - + "C_STREET_1, C_STREET_2, C_CITY, C_STATE, C_ZIP, " - + "C_PHONE, C_CREDIT, C_CREDIT_LIM, " - + "C_DISCOUNT, C_BALANCE, C_SINCE FROM CUSTOMER " - + "WHERE C_LAST=? AND C_D_ID=? AND C_W_ID=? " - + "ORDER BY C_FIRST"); - prep.setString(1, last); - prep.setInt(2, cdId); - prep.setInt(3, wId); - rs = db.query(prep); - // locate midpoint customer - if (namecnt % 2 != 0) { - namecnt++; - } - for (int n = 0; n < namecnt / 2; n++) { - rs.next(); - } - // c_first - rs.getString(1); - // c_middle - rs.getString(2); - cId = rs.getInt(3); - // c_street_1 - rs.getString(4); - // c_street_2 - rs.getString(5); - // c_city - rs.getString(6); - // c_state - rs.getString(7); - // c_zip - rs.getString(8); - // c_phone - rs.getString(9); - credit = rs.getString(10); - // c_credit_lim - rs.getString(11); - // c_discount - rs.getBigDecimal(12); - balance = rs.getBigDecimal(13); - // c_since - rs.getTimestamp(14); - rs.close(); - } else { - prep = prepare("SELECT C_FIRST, C_MIDDLE, C_LAST, " - + "C_STREET_1, C_STREET_2, C_CITY, C_STATE, C_ZIP, " - + "C_PHONE, C_CREDIT, C_CREDIT_LIM, " - + "C_DISCOUNT, C_BALANCE, C_SINCE FROM CUSTOMER " - + "WHERE C_ID=? AND C_D_ID=? AND C_W_ID=?"); - prep.setInt(1, cId); - prep.setInt(2, cdId); - prep.setInt(3, wId); - rs = db.query(prep); - rs.next(); - // c_first - rs.getString(1); - // c_middle - rs.getString(2); - // c_last - rs.getString(3); - // c_street_1 - rs.getString(4); - // c_street_2 - rs.getString(5); - // c_city - rs.getString(6); - // c_state - rs.getString(7); - // c_zip - rs.getString(8); - // c_phone - rs.getString(9); - credit = rs.getString(10); - // c_credit_lim - rs.getString(11); - // c_discount - rs.getBigDecimal(12); - balance = rs.getBigDecimal(13); - // c_since - rs.getTimestamp(14); - rs.close(); - } - balance = balance.add(amount); - if (credit.equals("BC")) { - prep = prepare("SELECT C_DATA INTO FROM CUSTOMER " - + "WHERE C_ID=? AND C_D_ID=? AND C_W_ID=?"); - prep.setInt(1, cId); - prep.setInt(2, cdId); - prep.setInt(3, wId); - rs = db.query(prep); - rs.next(); - String cData = rs.getString(1); - rs.close(); - String cNewData = "| " + cId + " " + cdId + " " + wId - + " " + dId + " " + warehouseId + " " + amount + " " - + cData; - if (cNewData.length() > 500) { - cNewData = cNewData.substring(0, 500); - } - prep = prepare("UPDATE CUSTOMER SET C_BALANCE=?, C_DATA=? " - + "WHERE C_ID=? AND C_D_ID=? AND C_W_ID=?"); - prep.setBigDecimal(1, balance); - prep.setString(2, cNewData); - prep.setInt(3, cId); - prep.setInt(4, cdId); - prep.setInt(5, wId); - db.update(prep, "updateCustomer"); - } else { - prep = prepare("UPDATE CUSTOMER SET C_BALANCE=? " - + "WHERE C_ID=? AND C_D_ID=? AND C_W_ID=?"); - prep.setBigDecimal(1, balance); - prep.setInt(2, cId); - prep.setInt(3, cdId); - prep.setInt(4, wId); - db.update(prep, "updateCustomer"); - } - // MySQL bug? -// String h_data = w_name + " " + d_name; - String hData = wName + " " + dName; - prep = prepare("INSERT INTO HISTORY (H_C_D_ID, H_C_W_ID, H_C_ID, H_D_ID, " - + "H_W_ID, H_DATE, H_AMOUNT, H_DATA) " - + "VALUES (?, ?, ?, ?, ?, ?, ?, ?)"); - prep.setInt(1, cdId); - prep.setInt(2, wId); - prep.setInt(3, cId); - prep.setInt(4, dId); - prep.setInt(5, warehouseId); - prep.setTimestamp(6, datetime); - prep.setBigDecimal(7, amount); - prep.setString(8, hData); - db.update(prep, "insertHistory"); - db.commit(); - } - - private void processOrderStatus() throws SQLException { - int dId = random.getInt(1, bench.districtsPerWarehouse); - boolean byName; - String last = null; - int cId = -1; - if (random.getInt(1, 100) <= 60) { - byName = true; - last = random.getLastname(random.getNonUniform(255, 0, 999)); - } else { - byName = false; - cId = random.getNonUniform(1023, 1, bench.customersPerDistrict); - } - PreparedStatement prep; - ResultSet rs; - - prep = prepare("UPDATE DISTRICT SET D_NEXT_O_ID=-1 WHERE D_ID=-1"); - db.update(prep, "updateDistrict"); - if (byName) { - prep = prepare("SELECT COUNT(C_ID) FROM CUSTOMER " - + "WHERE C_LAST=? AND C_D_ID=? AND C_W_ID=?"); - prep.setString(1, last); - prep.setInt(2, dId); - prep.setInt(3, warehouseId); - rs = db.query(prep); - rs.next(); - int namecnt = rs.getInt(1); - rs.close(); - if (namecnt == 0) { - // TODO TPC-C: check if this can happen - db.rollback(); - return; - } - prep = prepare("SELECT C_BALANCE, C_FIRST, C_MIDDLE, C_ID " - + "FROM CUSTOMER " - + "WHERE C_LAST=? AND C_D_ID=? AND C_W_ID=? " - + "ORDER BY C_FIRST"); - prep.setString(1, last); - prep.setInt(2, dId); - prep.setInt(3, warehouseId); - rs = db.query(prep); - if (namecnt % 2 != 0) { - namecnt++; - } - for (int n = 0; n < namecnt / 2; n++) { - rs.next(); - } - // c_balance - rs.getBigDecimal(1); - // c_first - rs.getString(2); - // c_middle - rs.getString(3); - rs.close(); - } else { - prep = prepare("SELECT C_BALANCE, C_FIRST, C_MIDDLE, C_LAST " - + "FROM CUSTOMER " - + "WHERE C_ID=? AND C_D_ID=? AND C_W_ID=?"); - prep.setInt(1, cId); - prep.setInt(2, dId); - prep.setInt(3, warehouseId); - rs = db.query(prep); - rs.next(); - // c_balance - rs.getBigDecimal(1); - // c_first - rs.getString(2); - // c_middle - rs.getString(3); - // c_last - rs.getString(4); - rs.close(); - } - prep = prepare("SELECT MAX(O_ID) " - + "FROM ORDERS WHERE O_C_ID=? AND O_D_ID=? AND O_W_ID=?"); - prep.setInt(1, cId); - prep.setInt(2, dId); - prep.setInt(3, warehouseId); - rs = db.query(prep); - int oId = -1; - if (rs.next()) { - oId = rs.getInt(1); - if (rs.wasNull()) { - oId = -1; - } - } - rs.close(); - if (oId != -1) { - prep = prepare("SELECT O_ID, O_CARRIER_ID, O_ENTRY_D " - + "FROM ORDERS WHERE O_ID=?"); - prep.setInt(1, oId); - rs = db.query(prep); - rs.next(); - oId = rs.getInt(1); - // o_carrier_id - rs.getInt(2); - // o_entry_d - rs.getTimestamp(3); - rs.close(); - prep = prepare("SELECT OL_I_ID, OL_SUPPLY_W_ID, OL_QUANTITY, " - + "OL_AMOUNT, OL_DELIVERY_D FROM ORDER_LINE " - + "WHERE OL_O_ID=? AND OL_D_ID=? AND OL_W_ID=?"); - prep.setInt(1, oId); - prep.setInt(2, dId); - prep.setInt(3, warehouseId); - rs = db.query(prep); - while (rs.next()) { - // o_i_id - rs.getInt(1); - // ol_supply_w_id - rs.getInt(2); - // ol_quantity - rs.getInt(3); - // ol_amount - rs.getBigDecimal(4); - // ol_delivery_d - rs.getTimestamp(5); - } - rs.close(); - } - db.commit(); - } - - private void processDelivery() throws SQLException { - int carrierId = random.getInt(1, 10); - Timestamp datetime = new Timestamp(System.currentTimeMillis()); - PreparedStatement prep; - ResultSet rs; - - prep = prepare("UPDATE DISTRICT SET D_NEXT_O_ID=-1 WHERE D_ID=-1"); - db.update(prep, "updateDistrict"); - for (int dId = 1; dId <= bench.districtsPerWarehouse; dId++) { - prep = prepare("SELECT MIN(NO_O_ID) FROM NEW_ORDER " - + "WHERE NO_D_ID=? AND NO_W_ID=?"); - prep.setInt(1, dId); - prep.setInt(2, warehouseId); - rs = db.query(prep); - int noId = -1; - if (rs.next()) { - noId = rs.getInt(1); - if (rs.wasNull()) { - noId = -1; - } - } - rs.close(); - if (noId != -1) { - prep = prepare("DELETE FROM NEW_ORDER " - + "WHERE NO_O_ID=? AND NO_D_ID=? AND NO_W_ID=?"); - prep.setInt(1, noId); - prep.setInt(2, dId); - prep.setInt(3, warehouseId); - db.update(prep, "deleteNewOrder"); - prep = prepare("SELECT O_C_ID FROM ORDERS " - + "WHERE O_ID=? AND O_D_ID=? AND O_W_ID=?"); - prep.setInt(1, noId); - prep.setInt(2, dId); - prep.setInt(3, warehouseId); - rs = db.query(prep); - rs.next(); - // o_c_id - rs.getInt(1); - rs.close(); - prep = prepare("UPDATE ORDERS SET O_CARRIER_ID=? " - + "WHERE O_ID=? AND O_D_ID=? AND O_W_ID=?"); - prep.setInt(1, carrierId); - prep.setInt(2, noId); - prep.setInt(3, dId); - prep.setInt(4, warehouseId); - db.update(prep, "updateOrders"); - prep = prepare("UPDATE ORDER_LINE SET OL_DELIVERY_D=? " - + "WHERE OL_O_ID=? AND OL_D_ID=? AND OL_W_ID=?"); - prep.setTimestamp(1, datetime); - prep.setInt(2, noId); - prep.setInt(3, dId); - prep.setInt(4, warehouseId); - db.update(prep, "updateOrderLine"); - prep = prepare("SELECT SUM(OL_AMOUNT) FROM ORDER_LINE " - + "WHERE OL_O_ID=? AND OL_D_ID=? AND OL_W_ID=?"); - prep.setInt(1, noId); - prep.setInt(2, dId); - prep.setInt(3, warehouseId); - rs = db.query(prep); - rs.next(); - BigDecimal amount = rs.getBigDecimal(1); - rs.close(); - prep = prepare("UPDATE CUSTOMER SET C_BALANCE=C_BALANCE+? " - + "WHERE C_ID=? AND C_D_ID=? AND C_W_ID=?"); - prep.setBigDecimal(1, amount); - prep.setInt(2, noId); - prep.setInt(3, dId); - prep.setInt(4, warehouseId); - db.update(prep, "updateCustomer"); - } - } - db.commit(); - } - - private void processStockLevel() throws SQLException { - int dId = (terminalId % bench.districtsPerWarehouse) + 1; - int threshold = random.getInt(10, 20); - PreparedStatement prep; - ResultSet rs; - - prep = prepare("UPDATE DISTRICT SET D_NEXT_O_ID=-1 WHERE D_ID=-1"); - db.update(prep, "updateDistrict"); - - prep = prepare("SELECT D_NEXT_O_ID FROM DISTRICT " - + "WHERE D_ID=? AND D_W_ID=?"); - prep.setInt(1, dId); - prep.setInt(2, warehouseId); - rs = db.query(prep); - rs.next(); - int oId = rs.getInt(1); - rs.close(); - prep = prepare("SELECT COUNT(DISTINCT S_I_ID) " - + "FROM ORDER_LINE, STOCK WHERE " - + "OL_W_ID=? AND " - + "OL_D_ID=? AND " - + "OL_O_ID=?-20 AND " - + "S_W_ID=? AND " - + "S_I_ID=OL_I_ID AND " - + "S_QUANTITY replace = new ArrayList(); - private String currentAction; - private long startTime; - private Connection conn; - private Statement stat; - private boolean trace = true; - private long lastTrace; - private Random random = new Random(1); - private ArrayList results = new ArrayList(); - private int totalTime; - private int executedStatements; - - private Server serverH2; - private Object serverDerby; - private boolean serverHSQLDB; - - /** - * Get the database name. - * - * @return the database name - */ - String getName() { - return name; - } - - /** - * Get the total measured time. - * - * @return the time - */ - int getTotalTime() { - return totalTime; - } - - /** - * Get the result array. - * - * @return the result array - */ - ArrayList getResults() { - return results; - } - - /** - * Get the random number generator. - * - * @return the generator - */ - Random getRandom() { - return random; - } - - /** - * Start the server if the this is a remote connection. - */ - void startServer() throws Exception { - if (url.startsWith("jdbc:h2:tcp:")) { - serverH2 = Server.createTcpServer().start(); - Thread.sleep(100); - } else if (url.startsWith("jdbc:derby://")) { - serverDerby = Class.forName("org.apache.derby.drda.NetworkServerControl").newInstance(); - Method m = serverDerby.getClass().getMethod("start", PrintWriter.class); - m.invoke(serverDerby, new Object[] { null }); - // serverDerby = new NetworkServerControl(); - // serverDerby.start(null); - Thread.sleep(100); - } else if (url.startsWith("jdbc:hsqldb:hsql:")) { - if (!serverHSQLDB) { - Class< ? > c; - try { - c = Class.forName("org.hsqldb.server.Server"); - } catch (Exception e) { - c = Class.forName("org.hsqldb.Server"); - } - Method m = c.getMethod("main", String[].class); - m.invoke(null, new Object[] { new String[] { "-database.0", - "data/mydb;hsqldb.default_table_type=cached", "-dbname.0", "xdb" } }); - // org.hsqldb.Server.main(new String[]{"-database.0", "mydb", - // "-dbname.0", "xdb"}); - serverHSQLDB = true; - Thread.sleep(100); - } - } - } - - /** - * Stop the server if this is a remote connection. - */ - void stopServer() throws Exception { - if (serverH2 != null) { - serverH2.stop(); - serverH2 = null; - } - if (serverDerby != null) { - Method m = serverDerby.getClass().getMethod("shutdown"); - // cast for JDK 1.5 - m.invoke(serverDerby, (Object[]) null); - // serverDerby.shutdown(); - serverDerby = null; - } else if (serverHSQLDB) { - // can not shut down (shutdown calls System.exit) - // openConnection(); - // update("SHUTDOWN"); - // closeConnection(); - // serverHSQLDB = false; - } - } - - /** - * Parse a database configuration and create a database object from it. - * - * @param test the test application - * @param id the database id - * @param dbString the configuration string - * @return a new database object with the given settings - */ - static Database parse(TestPerformance test, int id, String dbString) { - try { - StringTokenizer tokenizer = new StringTokenizer(dbString, ","); - Database db = new Database(); - db.id = id; - db.test = test; - db.name = tokenizer.nextToken().trim(); - String driver = tokenizer.nextToken().trim(); - Class.forName(driver); - db.url = tokenizer.nextToken().trim(); - db.user = tokenizer.nextToken().trim(); - db.password = ""; - if (tokenizer.hasMoreTokens()) { - db.password = tokenizer.nextToken().trim(); - } - return db; - } catch (Exception e) { - System.out.println("Cannot load database " + dbString + " :" + e.toString()); - return null; - } - } - - /** - * Get the database connection. The connection must be opened first. - * - * @return the connection - */ - Connection getConnection() { - return conn; - } - - /** - * Open a new database connection. This connection must be closed - * by calling conn.close(). - * - * @return the opened connection - */ - Connection openNewConnection() throws SQLException { - Connection newConn = DriverManager.getConnection(url, user, password); - if (url.startsWith("jdbc:derby:")) { - // Derby: use higher cache size - Statement s = null; - try { - s = newConn.createStatement(); - // stat.execute("CALL - // SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.storage.pageCacheSize', - // '64')"); - // stat.execute("CALL - // SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.storage.pageSize', - // '8192')"); - } finally { - JdbcUtils.closeSilently(s); - } - } else if (url.startsWith("jdbc:hsqldb:")) { - // HSQLDB: use a WRITE_DELAY of 1 second - Statement s = null; - try { - s = newConn.createStatement(); - s.execute("SET WRITE_DELAY 1"); - } finally { - JdbcUtils.closeSilently(s); - } - } - return newConn; - } - - /** - * Open the database connection. - */ - void openConnection() throws SQLException { - conn = openNewConnection(); - stat = conn.createStatement(); - } - - /** - * Close the database connection. - */ - void closeConnection() throws SQLException { - // if(!serverHSQLDB && url.startsWith("jdbc:hsqldb:")) { - // stat.execute("SHUTDOWN"); - // } - conn.close(); - stat = null; - conn = null; - } - - /** - * Initialize the SQL statement translation of this database. - * - * @param prop the properties with the translations to use - */ - void setTranslations(Properties prop) { - String databaseType = url.substring("jdbc:".length()); - databaseType = databaseType.substring(0, databaseType.indexOf(':')); - for (Object k : prop.keySet()) { - String key = (String) k; - if (key.startsWith(databaseType + ".")) { - String pattern = key.substring(databaseType.length() + 1); - pattern = StringUtils.replaceAll(pattern, "_", " "); - pattern = StringUtils.toUpperEnglish(pattern); - String replacement = prop.getProperty(key); - replace.add(new String[]{pattern, replacement}); - } - } - } - - /** - * Prepare a SQL statement. - * - * @param sql the SQL statement - * @return the prepared statement - */ - PreparedStatement prepare(String sql) throws SQLException { - sql = getSQL(sql); - return conn.prepareStatement(sql); - } - - private String getSQL(String sql) { - for (String[] pair : replace) { - String pattern = pair[0]; - String replacement = pair[1]; - sql = StringUtils.replaceAll(sql, pattern, replacement); - } - return sql; - } - - /** - * Start the benchmark. - * - * @param bench the benchmark - * @param action the action - */ - void start(Bench bench, String action) { - this.currentAction = bench.getName() + ": " + action; - this.startTime = System.currentTimeMillis(); - } - - /** - * This method is called when the test run ends. This will stop collecting - * data. - */ - void end() { - long time = System.currentTimeMillis() - startTime; - log(currentAction, "ms", (int) time); - if (test.collect) { - totalTime += time; - } - } - - /** - * Drop a table. Errors are ignored. - * - * @param table the table name - */ - void dropTable(String table) { - try { - update("DROP TABLE " + table); - } catch (Exception e) { - // ignore - table may not exist - } - } - - /** - * Execute an SQL statement. - * - * @param prep the prepared statement - * @param traceMessage the trace message - */ - void update(PreparedStatement prep, String traceMessage) throws SQLException { - test.trace(traceMessage); - prep.executeUpdate(); - if (test.collect) { - executedStatements++; - } - } - - /** - * Execute an SQL statement. - * - * @param sql the SQL statement - */ - void update(String sql) throws SQLException { - sql = getSQL(sql); - if (sql.trim().length() > 0) { - if (test.collect) { - executedStatements++; - } - stat.execute(sql); - } else { - System.out.println("?"); - } - } - - /** - * Enable or disable auto-commit. - * - * @param b false to disable - */ - void setAutoCommit(boolean b) throws SQLException { - conn.setAutoCommit(b); - } - - /** - * Commit a transaction. - */ - void commit() throws SQLException { - conn.commit(); - } - - /** - * Roll a transaction back. - */ - void rollback() throws SQLException { - conn.rollback(); - } - - /** - * Print trace information if trace is enabled. - * - * @param action the action - * @param i the current value - * @param max the maximum value - */ - void trace(String action, int i, int max) { - if (trace) { - long time = System.currentTimeMillis(); - if (i == 0 || lastTrace == 0) { - lastTrace = time; - } else if (time > lastTrace + 1000) { - System.out.println(action + ": " + ((100 * i / max) + "%")); - lastTrace = time; - } - } - } - - /** - * If data collection is enabled, add the currently used memory size to the - * log. - * - * @param bench the benchmark - * @param action the action - */ - void logMemory(Bench bench, String action) { - log(bench.getName() + ": " + action, "MB", TestBase.getMemoryUsed()); - } - - /** - * If data collection is enabled, add this information to the log. - * - * @param action the action - * @param scale the scale - * @param value the value - */ - void log(String action, String scale, int value) { - if (test.collect) { - results.add(new Object[] { action, scale, new Integer(value) }); - } - } - - /** - * Execute a query. - * - * @param prep the prepared statement - * @return the result set - */ - ResultSet query(PreparedStatement prep) throws SQLException { - // long time = System.currentTimeMillis(); - ResultSet rs = prep.executeQuery(); - // time = System.currentTimeMillis() - time; - // if(time > 100) { - // System.out.println("time="+time); - // } - if (test.collect) { - executedStatements++; - } - return rs; - } - - /** - * Execute a query and read all rows. - * - * @param prep the prepared statement - */ - void queryReadResult(PreparedStatement prep) throws SQLException { - ResultSet rs = prep.executeQuery(); - ResultSetMetaData meta = rs.getMetaData(); - int columnCount = meta.getColumnCount(); - while (rs.next()) { - for (int i = 0; i < columnCount; i++) { - rs.getString(i + 1); - } - } - } - - /** - * Get the number of executed statements. - * - * @return the number of statements - */ - int getExecutedStatements() { - return executedStatements; - } - - /** - * Get the database id. - * - * @return the id - */ - int getId() { - return id; - } - -} diff --git a/tools/h2/src/test/org/h2/test/bench/TestPerformance.java b/tools/h2/src/test/org/h2/test/bench/TestPerformance.java deleted file mode 100755 index fa0357e..0000000 --- a/tools/h2/src/test/org/h2/test/bench/TestPerformance.java +++ /dev/null @@ -1,263 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.test.bench; - -import java.io.FileWriter; -import java.io.InputStream; -import java.io.PrintWriter; -import java.sql.Connection; -import java.sql.DatabaseMetaData; -import java.sql.DriverManager; -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.sql.Statement; -import java.util.ArrayList; -import java.util.Properties; - -import org.h2.store.fs.FileSystem; -import org.h2.test.TestBase; -import org.h2.util.IOUtils; -import org.h2.util.JdbcUtils; - -/** - * The main controller class of the benchmark application. - * To run the benchmark, call the main method of this class. - */ -public class TestPerformance { - - /** - * Whether data should be collected. - */ - boolean collect; - - /** - * The flag used to enable or disable trace messages. - */ - boolean trace; - - /** - * This method is called when executing this sample application. - * - * @param args the command line parameters - */ - public static void main(String... args) throws Exception { - new TestPerformance().test(args); - } - - private Connection getResultConnection() throws SQLException { - org.h2.Driver.load(); - return DriverManager.getConnection("jdbc:h2:data/results"); - } - - private void openResults() throws SQLException { - Connection conn = null; - Statement stat = null; - try { - conn = getResultConnection(); - stat = conn.createStatement(); - stat.execute("CREATE TABLE IF NOT EXISTS RESULTS(TESTID INT, TEST VARCHAR, " - + "UNIT VARCHAR, DBID INT, DB VARCHAR, RESULT VARCHAR)"); - } finally { - JdbcUtils.closeSilently(stat); - JdbcUtils.closeSilently(conn); - } - } - - private void test(String... args) throws Exception { - int dbId = -1; - boolean exit = false; - String out = "benchmark.html"; - for (int i = 0; i < args.length; i++) { - String arg = args[i]; - if ("-db".equals(arg)) { - dbId = Integer.parseInt(args[++i]); - } else if ("-init".equals(arg)) { - FileSystem.getInstance("data").deleteRecursive("data", true); - } else if ("-out".equals(arg)) { - out = args[++i]; - } else if ("-trace".equals(arg)) { - trace = true; - } else if ("-exit".equals(arg)) { - exit = true; - } - } - Properties prop = new Properties(); - InputStream in = getClass().getResourceAsStream("test.properties"); - prop.load(in); - in.close(); - int size = Integer.parseInt(prop.getProperty("size")); - ArrayList dbs = new ArrayList(); - for (int i = 0; i < 100; i++) { - if (dbId != -1 && i != dbId) { - continue; - } - String dbString = prop.getProperty("db" + i); - if (dbString != null) { - Database db = Database.parse(this, i, dbString); - if (db != null) { - db.setTranslations(prop); - dbs.add(db); - } - } - } - ArrayList tests = new ArrayList(); - for (int i = 0; i < 100; i++) { - String testString = prop.getProperty("test" + i); - if (testString != null) { - Bench bench = (Bench) Class.forName(testString).newInstance(); - tests.add(bench); - } - } - testAll(dbs, tests, size); - collect = false; - if (dbs.size() == 0) { - return; - } - ArrayList results = dbs.get(0).getResults(); - Connection conn = null; - PreparedStatement prep = null; - Statement stat = null; - PrintWriter writer = null; - try { - openResults(); - conn = getResultConnection(); - stat = conn.createStatement(); - prep = conn - .prepareStatement("INSERT INTO RESULTS(TESTID, TEST, UNIT, DBID, DB, RESULT) VALUES(?, ?, ?, ?, ?, ?)"); - for (int i = 0; i < results.size(); i++) { - Object[] res = results.get(i); - prep.setInt(1, i); - prep.setString(2, res[0].toString()); - prep.setString(3, res[1].toString()); - for (Database db : dbs) { - prep.setInt(4, db.getId()); - prep.setString(5, db.getName()); - Object[] v = db.getResults().get(i); - prep.setString(6, v[2].toString()); - prep.execute(); - } - } - - writer = new PrintWriter(new FileWriter(out)); - ResultSet rs = stat.executeQuery( - "CALL '

    ' " - +"|| SELECT GROUP_CONCAT('' ORDER BY DBID SEPARATOR '') FROM " - +"(SELECT DISTINCT DBID, DB FROM RESULTS)" - +"|| '' || CHAR(10) " - +"|| SELECT GROUP_CONCAT('' || ( " - +"SELECT GROUP_CONCAT('' ORDER BY DBID SEPARATOR '') FROM RESULTS R2 WHERE " - +"R2.TESTID = R1.TESTID) || '' ORDER BY TESTID SEPARATOR CHAR(10)) FROM " - +"(SELECT DISTINCT TESTID, TEST, UNIT FROM RESULTS) R1" - +"|| '
    Test CaseUnit' || DB || '
    ' || TEST || '' || UNIT || '' || RESULT || '
    '" - ); - rs.next(); - String result = rs.getString(1); - writer.println(result); - } finally { - JdbcUtils.closeSilently(prep); - JdbcUtils.closeSilently(stat); - JdbcUtils.closeSilently(conn); - IOUtils.closeSilently(writer); - } - -// ResultSet rsDbs = conn.createStatement().executeQuery( -// "SELECT DB RESULTS GROUP BY DBID, DB ORDER BY DBID"); -// while(rsDbs.next()) { -// writer.println("" + rsDbs.getString(1) + ""); -// } -// ResultSet rs = conn.createStatement().executeQuery( -// "SELECT TEST, UNIT FROM RESULTS " + -// "GROUP BY TESTID, TEST, UNIT ORDER BY TESTID"); -// while(rs.next()) { -// writer.println("" + rs.getString(1) + ""); -// writer.println("" + rs.getString(2) + ""); -// ResultSet rsRes = conn.createStatement().executeQuery( -// "SELECT RESULT FROM RESULTS WHERE TESTID=? ORDER BY DBID"); -// -// -// } - -// PrintWriter writer = -// new PrintWriter(new FileWriter("benchmark.html")); -// writer.println(""); -// for(int j=0; j" + db.getName() + ""); -// } -// writer.println(""); -// for(int i=0; i"); -// writer.println(""); -// for(int j=0; j" + v[2] + ""); -// } -// writer.println(""); -// } -// writer.println("
    Test CaseUnit
    " + res[0] + "" + res[1] + "
    "); - - if (exit) { - System.exit(0); - } - } - - private void testAll(ArrayList dbs, ArrayList tests, int size) throws Exception { - for (int i = 0; i < dbs.size(); i++) { - if (i > 0) { - Thread.sleep(1000); - } - // calls garbage collection - TestBase.getMemoryUsed(); - Database db = dbs.get(i); - System.out.println("Testing the performance of " + db.getName()); - db.startServer(); - Connection conn = db.openNewConnection(); - DatabaseMetaData meta = conn.getMetaData(); - System.out.println(" " + meta.getDatabaseProductName() + " " + meta.getDatabaseProductVersion()); - runDatabase(db, tests, 1); - runDatabase(db, tests, 1); - collect = true; - runDatabase(db, tests, size); - conn.close(); - db.log("Executed statements", "#", db.getExecutedStatements()); - db.log("Total time", "ms", db.getTotalTime()); - int statPerSec = db.getExecutedStatements() * 1000 / db.getTotalTime(); - db.log("Statements per second", "#", statPerSec); - System.out.println("Statements per second: " + statPerSec); - collect = false; - db.stopServer(); - } - } - - private void runDatabase(Database db, ArrayList tests, int size) throws Exception { - for (Bench bench : tests) { - runTest(db, bench, size); - } - } - - private void runTest(Database db, Bench bench, int size) throws Exception { - bench.init(db, size); - bench.runTest(); - } - - /** - * Print a message to system out if trace is enabled. - * - * @param s the message - */ - void trace(String s) { - if (trace) { - System.out.println(s); - } - } - -} diff --git a/tools/h2/src/test/org/h2/test/bench/package.html b/tools/h2/src/test/org/h2/test/bench/package.html deleted file mode 100755 index 9292723..0000000 --- a/tools/h2/src/test/org/h2/test/bench/package.html +++ /dev/null @@ -1,15 +0,0 @@ - - - - -Javadoc package documentation -

    - -The implementation of the benchmark application. - -

    \ No newline at end of file diff --git a/tools/h2/src/test/org/h2/test/bench/test.properties b/tools/h2/src/test/org/h2/test/bench/test.properties deleted file mode 100755 index 90d14ff..0000000 --- a/tools/h2/src/test/org/h2/test/bench/test.properties +++ /dev/null @@ -1,36 +0,0 @@ -db1 = H2, org.h2.Driver, jdbc:h2:data/test;LOCK_TIMEOUT=10000;LOCK_MODE=3, sa, sa - -#xdb2 = H2 (nio), org.h2.Driver, jdbc:h2:nio:data/test;LOCK_TIMEOUT=10000;LOCK_MODE=3, sa, sa -#xdb3 = H2 (nioMapped), org.h2.Driver, jdbc:h2:nioMapped:data/test;LOCK_TIMEOUT=10000;LOCK_MODE=3, sa, sa -#xdb2 = H2 (MVCC), org.h2.Driver, jdbc:h2:data/test_mvcc;MVCC=TRUE, sa, sa -#xdb2 = H2 (XTEA), org.h2.Driver, jdbc:h2:data/test_xtea;LOCK_TIMEOUT=10000;LOCK_MODE=3;CIPHER=XTEA, sa, sa 123 -#xdb3 = H2 (AES), org.h2.Driver, jdbc:h2:data/test_aes;LOCK_TIMEOUT=10000;LOCK_MODE=3;CIPHER=AES, sa, sa 123 -#xdb4 = H2, org.h2.Driver, jdbc:h2:data/test;LOCK_TIMEOUT=10000;LOCK_MODE=3;write_mode_log=rws;write_delay=0, sa, sa -#xdb5 = H2_PG, org.postgresql.Driver, jdbc:postgresql://localhost:5435/h2test, sa, sa - -db2 = HSQLDB, org.hsqldb.jdbcDriver, jdbc:hsqldb:data/test;hsqldb.default_table_type=cached;sql.enforce_size=true, sa -db3 = Derby, org.apache.derby.jdbc.EmbeddedDriver, jdbc:derby:data/derby;create=true, sa, sa - -db4 = H2, org.h2.Driver, jdbc:h2:tcp://localhost/data/testServer;LOCK_TIMEOUT=10000;LOCK_MODE=3, sa, sa -db5 = HSQLDB, org.hsqldb.jdbcDriver, jdbc:hsqldb:hsql://localhost/xdb, sa -db6 = Derby, org.apache.derby.jdbc.ClientDriver, jdbc:derby://localhost/data/derbyServer;create=true, sa, sa -db7 = PostgreSQL, org.postgresql.Driver, jdbc:postgresql:test, sa, sa -db8 = MySQL, com.mysql.jdbc.Driver, jdbc:mysql://localhost/test?jdbcCompliantTruncation=false, sa, sa - -#db2 = MSSQLServer, com.microsoft.jdbc.sqlserver.SQLServerDriver, jdbc:microsoft:sqlserver://127.0.0.1:1433;DatabaseName=test, test, test -#db2 = Oracle, oracle.jdbc.driver.OracleDriver, jdbc:oracle:thin:@localhost:1521:XE, client, client -#db2 = Firebird, org.firebirdsql.jdbc.FBDriver, jdbc:firebirdsql:localhost:c:/temp/firebird/test, sysdba, masterkey -#db2 = DB2, COM.ibm.db2.jdbc.net.DB2Driver, jdbc:db2://localhost/test, test, test -#db2 = OneDollarDB, in.co.daffodil.db.jdbc.DaffodilDBDriver, jdbc:daffodilDB_embedded:school;path=C:/temp;create=true, sa - -firebirdsql.datetime = TIMESTAMP -postgresql.datetime = TIMESTAMP -derby.datetime = TIMESTAMP -oracle.datetime = TIMESTAMP - -test1 = org.h2.test.bench.BenchSimple -test2 = org.h2.test.bench.BenchA -test3 = org.h2.test.bench.BenchB -test4 = org.h2.test.bench.BenchC - -size = 400 diff --git a/tools/h2/src/test/org/h2/test/coverage/Coverage.java b/tools/h2/src/test/org/h2/test/coverage/Coverage.java deleted file mode 100755 index 876b91c..0000000 --- a/tools/h2/src/test/org/h2/test/coverage/Coverage.java +++ /dev/null @@ -1,519 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.test.coverage; - -import java.io.BufferedReader; -import java.io.BufferedWriter; -import java.io.File; -import java.io.FileReader; -import java.io.FileWriter; -import java.io.IOException; -import java.io.Reader; -import java.io.Writer; -import java.util.ArrayList; -import org.h2.util.New; - -/** - * Tool to instrument java files with profiler calls. The tool can be used for - * profiling an application and for coverage testing. This class is not used at - * runtime of the tested application. - */ -public class Coverage { - private static final String IMPORT = "import " + Coverage.class.getPackage().getName() + ".Profile"; - private ArrayList files = New.arrayList(); - private ArrayList exclude = New.arrayList(); - private Tokenizer tokenizer; - private Writer writer; - private Writer data; - private String token = ""; - private String add = ""; - private String file; - private int index; - private int indent; - private int line; - private String last; - private String word, function; - private boolean perClass; - private boolean perFunction = true; - - private void printUsage() { - System.out.println("Usage:\n" + "- copy all your source files to another directory\n" - + " (be careful, they will be modified - don't take originals!)\n" + "- java " + getClass().getName() - + " \n" + " this will modified the source code and create 'profile.txt'\n" - + "- compile the modified source files\n" + "- run your main application\n" - + "- after the application exits, a file 'notCovered.txt' is created,\n" - + " which contains the class names, function names and line numbers\n" - + " of code that has not been covered\n\n" + "Options:\n" + "-r recurse all subdirectories\n" - + "-e exclude files\n" + "-c coverage on a per-class basis\n" - + "-f coverage on a per-function basis\n" + " directory name (. for current directory)"); - } - - /** - * This method is called when executing this application. - * - * @param args the command line parameters - */ - public static void main(String... args) { - new Coverage().run(args); - } - - private void run(String... args) { - if (args.length == 0 || args[0].equals("-?")) { - printUsage(); - return; - } - Coverage c = new Coverage(); - int recurse = 1; - for (int i = 0; i < args.length; i++) { - String s = args[i]; - if (s.equals("-r")) { - // maximum recurse is 100 subdirectories, that should be enough - recurse = 100; - } else if (s.equals("-c")) { - c.perClass = true; - } else if (s.equals("-f")) { - c.perFunction = true; - } else if (s.equals("-e")) { - c.addExclude(args[++i]); - } else { - c.addDir(s, recurse); - } - } - try { - c.data = new BufferedWriter(new FileWriter("profile.txt")); - c.processAll(); - c.data.close(); - } catch (Exception e) { - e.printStackTrace(); - } - } - - private void addExclude(String fileName) { - exclude.add(fileName); - } - - private boolean isExcluded(String s) { - for (String e : exclude) { - if (s.startsWith(e)) { - return true; - } - } - return false; - } - - private void addDir(String path, int recurse) { - File f = new File(path); - if (f.isFile() && path.endsWith(".java")) { - if (!isExcluded(path)) { - files.add(path); - } - } else if (f.isDirectory() && recurse > 0) { - for (String name : f.list()) { - addDir(path + "/" + name, recurse - 1); - } - } - } - - private void processAll() { - int len = files.size(); - long time = System.currentTimeMillis(); - for (int i = 0; i < len; i++) { - long t2 = System.currentTimeMillis(); - if (t2 - time > 1000 || i >= len - 1) { - System.out.println((i + 1) + " of " + len + " " + (100 * i / len) + "%"); - time = t2; - } - String fileName = files.get(i); - processFile(fileName); - } - } - - private void processFile(String name) { - file = name; - int i; - i = file.lastIndexOf('.'); - if (i != -1) { - file = file.substring(0, i); - } - while (true) { - i = file.indexOf('/'); - if (i < 0) { - i = file.indexOf('\\'); - } - if (i < 0) { - break; - } - file = file.substring(0, i) + "." + file.substring(i + 1); - } - if (name.endsWith("Coverage.java") || name.endsWith("Tokenizer.java") || name.endsWith("Profile.java")) { - return; - } - File f = new File(name); - File fileNew = new File(name + ".new"); - try { - writer = new BufferedWriter(new FileWriter(fileNew)); - Reader r = new BufferedReader(new FileReader(f)); - tokenizer = new Tokenizer(r); - indent = 0; - try { - process(); - } catch (Exception e) { - r.close(); - writer.close(); - e.printStackTrace(); - printError(e.getMessage()); - throw e; - } - r.close(); - writer.close(); - File backup = new File(name + ".bak"); - backup.delete(); - f.renameTo(backup); - File copy = new File(name); - fileNew.renameTo(copy); - if (perClass) { - nextDebug(); - } - } catch (Exception e) { - e.printStackTrace(); - printError(e.getMessage()); - } - } - - private void read() throws IOException { - last = token; - String write = token; - token = null; - tokenizer.initToken(); - int i = tokenizer.nextToken(); - if (i != Tokenizer.TYPE_EOF) { - token = tokenizer.getString(); - if (token == null) { - token = "" + ((char) i); - } else if (i == '\'') { - // mToken="'"+getEscape(mToken)+"'"; - token = tokenizer.getToken(); - } else if (i == '\"') { - // mToken="\""+getEscape(mToken)+"\""; - token = tokenizer.getToken(); - } else { - if (write == null) { - write = ""; - } else { - write = write + " "; - } - } - } - if (write == null - || (!write.equals("else ") && !write.equals("else") && !write.equals("super ") - && !write.equals("super") && !write.equals("this ") && !write.equals("this") - && !write.equals("} ") && !write.equals("}"))) { - if (add != null && !add.equals("")) { - writeLine(); - write(add); - if (!perClass) { - nextDebug(); - } - } - } - add = ""; - if (write != null) { - write(write); - } - } - - private void readThis(String s) throws IOException { - if (!token.equals(s)) { - throw new IOException("Expected: " + s + " got:" + token); - } - read(); - } - - private void process() throws IOException { - boolean imp = false; - read(); - do { - while (true) { - if (token == null || token.equals("{")) { - break; - } else if (token.equals(";")) { - if (!imp) { - write(";" + IMPORT); - imp = true; - } - } - read(); - } - processClass(); - } while (token != null); - } - - private void processInit() throws IOException { - do { - if (token.equals("{")) { - read(); - processInit(); - } else if (token.equals("}")) { - read(); - return; - } else { - read(); - } - } while (true); - } - - private void processClass() throws IOException { - int type = 0; - while (true) { - if (token == null) { - break; - } else if (token.equals("class")) { - read(); - type = 1; - } else if (token.equals("=")) { - read(); - type = 2; - } else if (token.equals("static")) { - word = "static"; - read(); - type = 3; - } else if (token.equals("(")) { - word = last + "("; - read(); - if (!token.equals(")")) { - word = word + token; - } - type = 3; - } else if (token.equals(",")) { - read(); - word = word + "," + token; - } else if (token.equals(")")) { - word = word + ")"; - read(); - } else if (token.equals(";")) { - read(); - type = 0; - } else if (token.equals("{")) { - read(); - if (type == 1) { - processClass(); - } else if (type == 2) { - processInit(); - } else if (type == 3) { - writeLine(); - setLine(); - processFunction(); - writeLine(); - } - } else if (token.equals("}")) { - read(); - break; - } else { - read(); - } - } - } - - private void processBracket() throws IOException { - do { - if (token.equals("(")) { - read(); - processBracket(); - } else if (token.equals(")")) { - read(); - return; - } else { - read(); - } - } while (true); - } - - private void processFunction() throws IOException { - function = word; - writeLine(); - do { - processStatement(); - } while (!token.equals("}")); - read(); - writeLine(); - } - - private void processBlockOrStatement() throws IOException { - if (!token.equals("{")) { - write("{ //++"); - writeLine(); - setLine(); - processStatement(); - write("} //++"); - writeLine(); - } else { - read(); - setLine(); - processFunction(); - } - } - - private void processStatement() throws IOException { - while (true) { - if (token.equals("while") || token.equals("for") || token.equals("synchronized")) { - read(); - readThis("("); - processBracket(); - indent++; - processBlockOrStatement(); - indent--; - return; - } else if (token.equals("if")) { - read(); - readThis("("); - processBracket(); - indent++; - processBlockOrStatement(); - indent--; - if (token.equals("else")) { - read(); - indent++; - processBlockOrStatement(); - indent--; - } - return; - } else if (token.equals("try")) { - read(); - indent++; - processBlockOrStatement(); - indent--; - while (true) { - if (token.equals("catch")) { - read(); - readThis("("); - processBracket(); - indent++; - processBlockOrStatement(); - indent--; - } else if (token.equals("finally")) { - read(); - indent++; - processBlockOrStatement(); - indent--; - } else { - break; - } - } - return; - } else if (token.equals("{")) { - if (last.equals(")")) { - // process anonymous inner classes (this is a hack) - read(); - processClass(); - return; - } else if (last.equals("]")) { - // process object array initialization (another hack) - while (!token.equals("}")) { - read(); - } - read(); - return; - } - indent++; - processBlockOrStatement(); - indent--; - return; - } else if (token.equals("do")) { - read(); - indent++; - processBlockOrStatement(); - readThis("while"); - readThis("("); - processBracket(); - readThis(";"); - setLine(); - indent--; - return; - } else if (token.equals("case")) { - add = ""; - read(); - while (!token.equals(":")) { - read(); - } - read(); - setLine(); - } else if (token.equals("default")) { - add = ""; - read(); - readThis(":"); - setLine(); - } else if (token.equals("switch")) { - read(); - readThis("("); - processBracket(); - indent++; - processBlockOrStatement(); - indent--; - return; - } else if (token.equals("class")) { - read(); - processClass(); - return; - } else if (token.equals("(")) { - read(); - processBracket(); - } else if (token.equals("=")) { - read(); - if (token.equals("{")) { - read(); - processInit(); - } - } else if (token.equals(";")) { - read(); - setLine(); - return; - } else if (token.equals("}")) { - return; - } else { - read(); - } - } - } - - private void setLine() { - add += "Profile.visit(" + index + ");"; - line = tokenizer.getLine(); - } - - private void nextDebug() throws IOException { - if (perFunction) { - int i = function.indexOf("("); - String func = i < 0 ? function : function.substring(0, i); - String fileLine = file + "." + func + "("; - i = file.lastIndexOf('.'); - String className = i < 0 ? file : file.substring(i + 1); - fileLine += className + ".java:" + line + ")"; - data.write(fileLine + " " + last + "\r\n"); - } else { - data.write(file + " " + line + "\r\n"); - } - index++; - } - - private void writeLine() throws IOException { - write("\r\n"); - for (int i = 0; i < indent; i++) { - writer.write(' '); - } - } - - private void write(String s) throws IOException { - writer.write(s); - // System.out.print(s); - } - - private void printError(String error) { - System.out.println(""); - System.out.println("File:" + file); - System.out.println("ERROR: " + error); - } -} diff --git a/tools/h2/src/test/org/h2/test/coverage/Profile.java b/tools/h2/src/test/org/h2/test/coverage/Profile.java deleted file mode 100755 index 6f4afe9..0000000 --- a/tools/h2/src/test/org/h2/test/coverage/Profile.java +++ /dev/null @@ -1,257 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.test.coverage; - -import java.io.BufferedWriter; -import java.io.FileReader; -import java.io.FileWriter; -import java.io.IOException; -import java.io.LineNumberReader; -import java.io.Reader; -import java.io.Writer; - -/** - * The class used at runtime to measure the code usage and performance. - */ -public class Profile extends Thread { - private static final boolean LIST_UNVISITED = false; - private static final boolean TRACE = false; - private static final Profile MAIN = new Profile(); - private static int top = 15; - private int[] count; - private int[] time; - private boolean stop; - private int maxIndex; - private int lastIndex; - private long lastTime; - private BufferedWriter trace; - - private Profile() { - FileReader reader = null; - try { - reader = new FileReader("profile.txt"); - LineNumberReader r = new LineNumberReader(reader); - while (r.readLine() != null) { - // nothing - just count lines - } - maxIndex = r.getLineNumber(); - count = new int[maxIndex]; - time = new int[maxIndex]; - lastTime = System.currentTimeMillis(); - Runtime.getRuntime().addShutdownHook(this); - } catch (Exception e) { - e.printStackTrace(); - System.exit(1); - } finally { - closeSilently(reader); - } - } - - static { - try { - String s = System.getProperty("profile.top"); - if (s != null) { - top = Integer.parseInt(s); - } - } catch (Throwable e) { - // ignore SecurityExceptions - } - } - - /** - * This method is called by an instrumented application whenever a line of - * code is executed. - * - * @param i the line number that is executed - */ - public static void visit(int i) { - MAIN.addVisit(i); - } - - public void run() { - list(); - } - - /** - * Start collecting data. - */ - public static void startCollecting() { - MAIN.stop = false; - MAIN.lastTime = System.currentTimeMillis(); - } - - /** - * Stop collecting data. - */ - public static void stopCollecting() { - MAIN.stop = true; - } - - /** - * List all captured data. - */ - public static void list() { - if (MAIN.lastIndex == 0) { - // don't list anything if no statistics collected - return; - } - try { - MAIN.listUnvisited(); - MAIN.listTop("MOST CALLED", MAIN.count, top); - MAIN.listTop("MOST TIME USED", MAIN.time, top); - } catch (Exception e) { - e.printStackTrace(); - } - } - - private void closeSilently(Reader reader) { - if (reader != null) { - try { - reader.close(); - } catch (IOException e) { - // ignore - } - } - } - - private void closeSilently(Writer writer) { - if (writer != null) { - try { - writer.close(); - } catch (IOException e) { - // ignore - } - } - } - - private void addVisit(int i) { - if (stop) { - return; - } - long now = System.currentTimeMillis(); - if (TRACE) { - if (trace != null) { - int duration = (int) (now - lastTime); - try { - trace.write(i + "\t" + duration + "\r\n"); - } catch (Exception e) { - e.printStackTrace(); - System.exit(1); - } - } - } - count[i]++; - time[lastIndex] += (int) (now - lastTime); - lastTime = now; - lastIndex = i; - } - - private void listUnvisited() throws IOException { - printLine('='); - print("NOT COVERED"); - printLine('-'); - FileReader reader = null; - FileWriter fileWriter = null; - try { - reader = new FileReader("profile.txt"); - LineNumberReader r = new LineNumberReader(reader); - fileWriter = new FileWriter("notCovered.txt"); - BufferedWriter writer = new BufferedWriter(fileWriter); - int unvisited = 0; - int unvisitedThrow = 0; - for (int i = 0; i < maxIndex; i++) { - String line = r.readLine(); - if (count[i] == 0) { - if (!line.endsWith("throw")) { - writer.write(line + "\r\n"); - if (LIST_UNVISITED) { - print(line + "\r\n"); - } - unvisited++; - } else { - unvisitedThrow++; - } - } - } - int percent = 100 * unvisited / maxIndex; - print("Not covered: " + percent + " % " + " (" + unvisited + " of " + maxIndex + "; throw=" - + unvisitedThrow + ")"); - } finally { - closeSilently(fileWriter); - closeSilently(reader); - } - } - - private void listTop(String title, int[] list, int max) throws IOException { - printLine('-'); - int total = 0; - int totalLines = 0; - for (int j = 0; j < maxIndex; j++) { - int l = list[j]; - if (l > 0) { - total += list[j]; - totalLines++; - } - } - if (max == 0) { - max = totalLines; - } - print(title); - print("Total: " + total); - printLine('-'); - String[] text = new String[max]; - int[] index = new int[max]; - for (int i = 0; i < max; i++) { - int big = list[0]; - int bigIndex = 0; - for (int j = 1; j < maxIndex; j++) { - int l = list[j]; - if (l > big) { - big = l; - bigIndex = j; - } - } - list[bigIndex] = -(big + 1); - index[i] = bigIndex; - } - FileReader reader = null; - try { - reader = new FileReader("profile.txt"); - LineNumberReader r = new LineNumberReader(reader); - for (int i = 0; i < maxIndex; i++) { - String line = r.readLine(); - int k = list[i]; - if (k < 0) { - k = -(k + 1); - list[i] = k; - for (int j = 0; j < max; j++) { - if (index[j] == i) { - int percent = 100 * k / total; - text[j] = k + " " + percent + "%: " + line; - } - } - } - } - for (int i = 0; i < max; i++) { - print(text[i]); - } - } finally { - closeSilently(reader); - } - } - - private void print(String s) { - System.out.println(s); - } - - private void printLine(char c) { - for (int i = 0; i < 60; i++) { - System.out.print(c); - } - print(""); - } -} diff --git a/tools/h2/src/test/org/h2/test/coverage/Tokenizer.java b/tools/h2/src/test/org/h2/test/coverage/Tokenizer.java deleted file mode 100755 index 6a236ef..0000000 --- a/tools/h2/src/test/org/h2/test/coverage/Tokenizer.java +++ /dev/null @@ -1,281 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.test.coverage; - -import java.io.EOFException; -import java.io.IOException; -import java.io.Reader; - -/** - * Helper class for the java file parser. - */ -public class Tokenizer { - - /** - * This token type means no more tokens are available. - */ - static final int TYPE_EOF = -1; - - private static final int TYPE_WORD = -2; - private static final int TYPE_NOTHING = -3; - private static final byte WHITESPACE = 1; - private static final byte ALPHA = 4; - private static final byte QUOTE = 8; - - private StringBuilder buffer; - - private Reader reader; - - private char[] chars = new char[20]; - private int peekChar; - private int line = 1; - - private byte[] charTypes = new byte[256]; - - private int type = TYPE_NOTHING; - private String value; - - private Tokenizer() { - wordChars('a', 'z'); - wordChars('A', 'Z'); - wordChars('0', '9'); - wordChars('.', '.'); - wordChars('+', '+'); - wordChars('-', '-'); - wordChars('_', '_'); - wordChars(128 + 32, 255); - whitespaceChars(0, ' '); - charTypes['"'] = QUOTE; - charTypes['\''] = QUOTE; - } - - Tokenizer(Reader r) { - this(); - reader = r; - } - - String getString() { - return value; - } - - private void wordChars(int low, int hi) { - while (low <= hi) { - charTypes[low++] |= ALPHA; - } - } - - private void whitespaceChars(int low, int hi) { - while (low <= hi) { - charTypes[low++] = WHITESPACE; - } - } - - private int read() throws IOException { - int i = reader.read(); - if (i != -1) { - append(i); - } - return i; - } - - /** - * Initialize the tokenizer. - */ - void initToken() { - buffer = new StringBuilder(); - } - - String getToken() { - buffer.setLength(buffer.length() - 1); - return buffer.toString(); - } - - private void append(int i) { - buffer.append((char) i); - } - - /** - * Read the next token and get the token type. - * - * @return the token type - */ - int nextToken() throws IOException { - byte[] ct = charTypes; - int c; - value = null; - - if (type == TYPE_NOTHING) { - c = read(); - if (c >= 0) { - type = c; - } - } else { - c = peekChar; - if (c < 0) { - try { - c = read(); - if (c >= 0) { - type = c; - } - } catch (EOFException e) { - c = -1; - } - } - } - - if (c < 0) { - return type = TYPE_EOF; - } - int charType = c < 256 ? ct[c] : ALPHA; - while ((charType & WHITESPACE) != 0) { - if (c == '\r') { - line++; - c = read(); - if (c == '\n') { - c = read(); - } - } else { - if (c == '\n') { - line++; - } - c = read(); - } - if (c < 0) { - return type = TYPE_EOF; - } - charType = c < 256 ? ct[c] : ALPHA; - } - if ((charType & ALPHA) != 0) { - initToken(); - append(c); - int i = 0; - do { - if (i >= chars.length) { - char[] nb = new char[chars.length * 2]; - System.arraycopy(chars, 0, nb, 0, chars.length); - chars = nb; - } - chars[i++] = (char) c; - c = read(); - charType = c < 0 ? WHITESPACE : c < 256 ? ct[c] : ALPHA; - } while ((charType & ALPHA) != 0); - peekChar = c; - value = String.copyValueOf(chars, 0, i); - return type = TYPE_WORD; - } - if ((charType & QUOTE) != 0) { - initToken(); - append(c); - type = c; - int i = 0; - // \octal needs a lookahead - peekChar = read(); - while (peekChar >= 0 && peekChar != type && peekChar != '\n' - && peekChar != '\r') { - if (peekChar == '\\') { - c = read(); - // to allow \377, but not \477 - int first = c; - if (c >= '0' && c <= '7') { - c = c - '0'; - int c2 = read(); - if ('0' <= c2 && c2 <= '7') { - c = (c << 3) + (c2 - '0'); - c2 = read(); - if ('0' <= c2 && c2 <= '7' && first <= '3') { - c = (c << 3) + (c2 - '0'); - peekChar = read(); - } else { - peekChar = c2; - } - } else { - peekChar = c2; - } - } else { - switch (c) { - case 'b': - c = '\b'; - break; - case 'f': - c = '\f'; - break; - case 'n': - c = '\n'; - break; - case 'r': - c = '\r'; - break; - case 't': - c = '\t'; - break; - default: - } - peekChar = read(); - } - } else { - c = peekChar; - peekChar = read(); - } - - if (i >= chars.length) { - char[] nb = new char[chars.length * 2]; - System.arraycopy(chars, 0, nb, 0, chars.length); - chars = nb; - } - chars[i++] = (char) c; - } - if (peekChar == type) { - // keep \n or \r intact in peekChar - peekChar = read(); - } - value = String.copyValueOf(chars, 0, i); - return type; - } - if (c == '/') { - c = read(); - if (c == '*') { - int prevChar = 0; - while ((c = read()) != '/' || prevChar != '*') { - if (c == '\r') { - line++; - c = read(); - if (c == '\n') { - c = read(); - } - } else { - if (c == '\n') { - line++; - c = read(); - } - } - if (c < 0) { - return type = TYPE_EOF; - } - prevChar = c; - } - peekChar = read(); - return nextToken(); - } else if (c == '/') { - while ((c = read()) != '\n' && c != '\r' && c >= 0) { - // nothing - } - peekChar = c; - return nextToken(); - } else { - peekChar = c; - return type = '/'; - } - } - peekChar = read(); - return type = c; - } - - int getLine() { - return line; - } -} - diff --git a/tools/h2/src/test/org/h2/test/coverage/package.html b/tools/h2/src/test/org/h2/test/coverage/package.html deleted file mode 100755 index 24266d3..0000000 --- a/tools/h2/src/test/org/h2/test/coverage/package.html +++ /dev/null @@ -1,15 +0,0 @@ - - - - -Javadoc package documentation -

    - -A standalone code coverage tool. - -

    \ No newline at end of file diff --git a/tools/h2/src/test/org/h2/test/db/Db.java b/tools/h2/src/test/org/h2/test/db/Db.java deleted file mode 100755 index 67dc785..0000000 --- a/tools/h2/src/test/org/h2/test/db/Db.java +++ /dev/null @@ -1,273 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.test.db; - -import java.io.InputStream; -import java.sql.Connection; -import java.sql.DriverManager; -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.ResultSetMetaData; -import java.sql.SQLException; -import java.sql.Statement; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import org.h2.util.JdbcUtils; - -/** - * A simple wrapper around the JDBC API. - * Currently used for testing. - * Features: - *
      - *
    • No checked exceptions - *
    • Easy to use, fluent API - *
    - */ -public class Db { - - private Connection conn; - private Statement stat; - private HashMap prepared = new HashMap(); - - /** - * Create a database object using the given connection. - * - * @param conn the database connection - */ - public Db(Connection conn) { - try { - this.conn = conn; - stat = conn.createStatement(); - } catch (SQLException e) { - throw convert(e); - } - } - - /** - * Open the database connection. For most databases, it is not required to - * load the driver before calling this method. - * - * @param url the database URL - * @param user the user name - * @param password the password - * @return the database - */ - public static Db open(String url, String user, String password) { - try { - JdbcUtils.load(url); - return new Db(DriverManager.getConnection(url, user, password)); - } catch (SQLException e) { - throw convert(e); - } - } - - /** - * Prepare a SQL statement. - * - * @param sql the SQL statement - * @return the prepared statement - */ - public Prepared prepare(String sql) { - try { - PreparedStatement prep = prepared.get(sql); - if (prep == null) { - prep = conn.prepareStatement(sql); - prepared.put(sql, prep); - } - return new Prepared(conn.prepareStatement(sql)); - } catch (SQLException e) { - throw convert(e); - } - } - - /** - * Execute a SQL statement. - * - * @param sql the SQL statement - */ - public void execute(String sql) { - try { - stat.execute(sql); - } catch (SQLException e) { - throw convert(e); - } - } - - /** - * Read a result set. - * - * @param rs the result set - * @return a list of maps - */ - static List> query(ResultSet rs) throws SQLException { - List> list = new ArrayList>(); - ResultSetMetaData meta = rs.getMetaData(); - int columnCount = meta.getColumnCount(); - while (rs.next()) { - HashMap map = new HashMap(); - for (int i = 0; i < columnCount; i++) { - map.put(meta.getColumnLabel(i+1), rs.getObject(i+1)); - } - list.add(map); - } - return list; - } - - /** - * Execute a SQL statement. - * - * @param sql the SQL statement - * @return a list of maps - */ - public List> query(String sql) { - try { - return query(stat.executeQuery(sql)); - } catch (SQLException e) { - throw convert(e); - } - } - - /** - * Close the database connection. - */ - public void close() { - try { - conn.close(); - } catch (SQLException e) { - throw convert(e); - } - } - - /** - * This class represents a prepared statement. - */ - public static class Prepared { - private PreparedStatement prep; - private int index; - - Prepared(PreparedStatement prep) { - this.prep = prep; - } - - /** - * Set the value of the current parameter. - * - * @param x the value - * @return itself - */ - public Prepared set(int x) { - try { - prep.setInt(++index, x); - return this; - } catch (SQLException e) { - throw convert(e); - } - } - - /** - * Set the value of the current parameter. - * - * @param x the value - * @return itself - */ - public Prepared set(String x) { - try { - prep.setString(++index, x); - return this; - } catch (SQLException e) { - throw convert(e); - } - } - - /** - * Set the value of the current parameter. - * - * @param x the value - * @return itself - */ - public Prepared set(byte[] x) { - try { - prep.setBytes(++index, x); - return this; - } catch (SQLException e) { - throw convert(e); - } - } - - /** - * Set the value of the current parameter. - * - * @param x the value - * @return itself - */ - public Prepared set(InputStream x) { - try { - prep.setBinaryStream(++index, x, -1); - return this; - } catch (SQLException e) { - throw convert(e); - } - } - - /** - * Execute the prepared statement. - */ - public void execute() { - try { - prep.execute(); - } catch (SQLException e) { - throw convert(e); - } - } - - /** - * Execute the prepared query. - * - * @return the result list - */ - public List> query() { - try { - return Db.query(prep.executeQuery()); - } catch (SQLException e) { - throw convert(e); - } - } - } - - /** - * Convert a checked exception to a runtime exception. - * - * @param e the checked exception - * @return the runtime exception - */ - static RuntimeException convert(Exception e) { - return new RuntimeException(e.toString(), e); - } - - public void setAutoCommit(boolean autoCommit) { - try { - conn.setAutoCommit(autoCommit); - } catch (SQLException e) { - throw convert(e); - } - } - - /** - * Commit a pending transaction. - */ - public void commit() { - try { - conn.commit(); - } catch (SQLException e) { - throw convert(e); - } - } - -} diff --git a/tools/h2/src/test/org/h2/test/db/Task.java b/tools/h2/src/test/org/h2/test/db/Task.java deleted file mode 100755 index b2c9e39..0000000 --- a/tools/h2/src/test/org/h2/test/db/Task.java +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.test.db; - -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStreamReader; -import org.h2.test.utils.SelfDestructor; - -/** - * A task that can be run as a separate process. - */ -public abstract class Task { - - /** - * Run the class. This method is called by the task framework, and should - * not be called directly from the application. - * - * @param args the command line arguments - */ - public static void main(String... args) { - SelfDestructor.startCountdown(60); - Task task; - try { - String className = args[0]; - task = (Task) Class.forName(className).newInstance(); - System.out.println("running"); - } catch (Throwable t) { - System.out.println("init error: " + t); - t.printStackTrace(); - return; - } - try { - String[] taskArgs = new String[args.length - 1]; - System.arraycopy(args, 0, taskArgs, 0, args.length - 1); - task.run(taskArgs); - } catch (Throwable t) { - System.out.println("error: " + t); - t.printStackTrace(); - } - } - - /** - * Run the task. - * - * @param args the command line arguments - */ - abstract void run(String... args) throws Exception; - - /** - * Receive a message from the process over the standard output. - * - * @return the message - */ - protected String receive() { - try { - return new BufferedReader(new InputStreamReader(System.in)).readLine(); - } catch (IOException e) { - throw new RuntimeException("Error reading from input", e); - } - } - - /** - * Send a message to the process over the standard input. - * - * @param message the message - */ - protected void send(String message) { - System.out.println(message); - System.out.flush(); - } - -} diff --git a/tools/h2/src/test/org/h2/test/db/TaskProcess.java b/tools/h2/src/test/org/h2/test/db/TaskProcess.java deleted file mode 100755 index 696f7eb..0000000 --- a/tools/h2/src/test/org/h2/test/db/TaskProcess.java +++ /dev/null @@ -1,142 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.test.db; - -import java.io.BufferedReader; -import java.io.BufferedWriter; -import java.io.File; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.io.OutputStream; -import java.io.OutputStreamWriter; -import java.util.ArrayList; -import java.util.Arrays; -import org.h2.test.utils.SelfDestructor; -import org.h2.util.StringUtils; - -/** - * A task that is run as an external process. This class communicates over - * standard input / output with the process. The standard error stream of the - * process is directly send to the standard error stream of this process. - */ -public class TaskProcess { - private final Task taskDef; - private Process process; - private BufferedReader reader; - private BufferedWriter writer; - - /** - * Construct a new task process. The process is not started yet. - * - * @param taskDef the task - */ - public TaskProcess(Task taskDef) { - this.taskDef = taskDef; - } - - /** - * Start the task with the given arguments. - * - * @param args the arguments, or null - */ - public void start(String... args) { - try { - String selfDestruct = SelfDestructor.getPropertyString(60); - ArrayList list = new ArrayList(); - list.add("java"); - list.add(selfDestruct); - list.add("-cp"); - list.add("bin" + File.pathSeparator + "."); - list.add(Task.class.getName()); - list.add(taskDef.getClass().getName()); - if (args != null && args.length > 0) { - list.addAll(Arrays.asList(args)); - } - String[] procDef = new String[list.size()]; - list.toArray(procDef); - traceOperation("start: " + StringUtils.arrayCombine(procDef, ' ')); - process = Runtime.getRuntime().exec(procDef); - copyInThread(process.getErrorStream(), System.err); - reader = new BufferedReader(new InputStreamReader(process.getInputStream())); - writer = new BufferedWriter(new OutputStreamWriter(process.getOutputStream())); - String line = reader.readLine(); - if (line == null) { - throw new RuntimeException("No reply from process, command: " + StringUtils.arrayCombine(procDef, ' ')); - } else if (line.startsWith("running")) { - traceOperation("got reply: " + line); - } else if (line.startsWith("init error")) { - throw new RuntimeException(line); - } - } catch (Throwable t) { - throw new RuntimeException("Error starting task", t); - } - } - - private void copyInThread(final InputStream in, final OutputStream out) { - new Thread() { - public void run() { - try { - while (true) { - int x = in.read(); - if (x < 0) { - return; - } - if (out != null) { - out.write(x); - } - } - } catch (Exception e) { - throw new RuntimeException(e); - } - } - } .start(); - } - - /** - * Receive a message from the process over the standard output. - * - * @return the message - */ - public String receive() { - try { - return reader.readLine(); - } catch (IOException e) { - throw new RuntimeException("Error reading", e); - } - } - - /** - * Send a message to the process over the standard input. - * - * @param message the message - */ - public void send(String message) { - try { - writer.write(message + "\n"); - writer.flush(); - } catch (IOException e) { - throw new RuntimeException("Error writing " + message, e); - } - } - - /** - * Kill the process if it still runs. - */ - public void destroy() { - process.destroy(); - } - - /** - * Trace the operation. Tracing is disabled by default. - * - * @param s the string to print - */ - private void traceOperation(String s) { - // ignore - } -} diff --git a/tools/h2/src/test/org/h2/test/db/TestAlter.java b/tools/h2/src/test/org/h2/test/db/TestAlter.java deleted file mode 100755 index 6eb63ae..0000000 --- a/tools/h2/src/test/org/h2/test/db/TestAlter.java +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.test.db; - -import java.sql.Connection; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.sql.Statement; - -import org.h2.constant.ErrorCode; -import org.h2.test.TestBase; - -/** - * Test ALTER statements. - */ -public class TestAlter extends TestBase { - - private Connection conn; - private Statement stat; - - /** - * Run just this test. - * - * @param a ignored - */ - public static void main(String... a) throws Exception { - TestBase.createCaller().init().test(); - } - - public void test() throws Exception { - deleteDb("alter"); - conn = getConnection("alter"); - stat = conn.createStatement(); - testAlterTableAlterColumn(); - testAlterTableDropIdentityColumn(); - conn.close(); - deleteDb("alter"); - } - - private void testAlterTableDropIdentityColumn() throws SQLException { - stat.execute("create table test(id int auto_increment, name varchar)"); - stat.execute("alter table test drop column id"); - ResultSet rs = stat.executeQuery("select * from INFORMATION_SCHEMA.SEQUENCES"); - assertFalse(rs.next()); - stat.execute("drop table test"); - - stat.execute("create table test(id int auto_increment, name varchar)"); - stat.execute("alter table test drop column name"); - rs = stat.executeQuery("select * from INFORMATION_SCHEMA.SEQUENCES"); - assertTrue(rs.next()); - stat.execute("drop table test"); - } - - private void testAlterTableAlterColumn() throws SQLException { - stat.execute("create table t(x varchar) as select 'x'"); - try { - stat.execute("alter table t alter column x int"); - } catch (SQLException e) { - assertEquals(ErrorCode.DATA_CONVERSION_ERROR_1, e.getErrorCode()); - } - stat.execute("drop table t"); - stat.execute("create table t(id identity, x varchar) as select null, 'x'"); - try { - stat.execute("alter table t alter column x int"); - } catch (SQLException e) { - assertEquals(ErrorCode.DATA_CONVERSION_ERROR_1, e.getErrorCode()); - } - stat.execute("drop table t"); - } - -} diff --git a/tools/h2/src/test/org/h2/test/db/TestAutoRecompile.java b/tools/h2/src/test/org/h2/test/db/TestAutoRecompile.java deleted file mode 100755 index 26d331f..0000000 --- a/tools/h2/src/test/org/h2/test/db/TestAutoRecompile.java +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.test.db; - -import java.sql.Connection; -import java.sql.PreparedStatement; -import java.sql.SQLException; -import java.sql.Statement; - -import org.h2.test.TestBase; - -/** - * Tests if prepared statements are re-compiled when required. - */ -public class TestAutoRecompile extends TestBase { - - /** - * Run just this test. - * - * @param a ignored - */ - public static void main(String... a) throws Exception { - TestBase.createCaller().init().test(); - } - - public void test() throws SQLException { - deleteDb("autoRecompile"); - Connection conn = getConnection("autoRecompile"); - Statement stat = conn.createStatement(); - stat.execute("CREATE TABLE TEST(ID INT PRIMARY KEY)"); - PreparedStatement prep = conn.prepareStatement("SELECT * FROM TEST"); - assertEquals(1, prep.executeQuery().getMetaData().getColumnCount()); - stat.execute("ALTER TABLE TEST ADD COLUMN NAME VARCHAR(255)"); - assertEquals(2, prep.executeQuery().getMetaData().getColumnCount()); - stat.execute("DROP TABLE TEST"); - stat.execute("CREATE TABLE TEST(ID INT PRIMARY KEY, X INT, Y INT)"); - assertEquals(3, prep.executeQuery().getMetaData().getColumnCount()); - // TODO test auto-recompile with insert..select, views and so on - - prep = conn.prepareStatement("INSERT INTO TEST VALUES(1, 2, 3)"); - stat.execute("ALTER TABLE TEST ADD COLUMN Z INT"); - try { - prep.execute(); - fail(); - } catch (SQLException e) { - assertKnownException(e); - } - try { - prep.execute(); - fail(); - } catch (SQLException e) { - assertKnownException(e); - } - conn.close(); - deleteDb("autoRecompile"); - } - -} diff --git a/tools/h2/src/test/org/h2/test/db/TestBackup.java b/tools/h2/src/test/org/h2/test/db/TestBackup.java deleted file mode 100755 index b9ec7e6..0000000 --- a/tools/h2/src/test/org/h2/test/db/TestBackup.java +++ /dev/null @@ -1,96 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.test.db; - -import java.sql.Connection; -import java.sql.SQLException; -import java.sql.Statement; - -import org.h2.test.TestBase; -import org.h2.tools.Backup; -import org.h2.tools.Restore; -import org.h2.util.IOUtils; - -/** - * Test for the BACKUP SQL statement. - */ -public class TestBackup extends TestBase { - - /** - * Run just this test. - * - * @param a ignored - */ - public static void main(String... a) throws Exception { - TestBase.createCaller().init().test(); - } - - public void test() throws SQLException { - if (config.memory) { - return; - } - testBackupRestoreLobStatement(); - testBackupRestoreLob(); - testBackup(); - deleteDb("backup"); - IOUtils.delete(getBaseDir() + "/backup.zip"); - } - - private void testBackupRestoreLob() throws SQLException { - deleteDb("backup"); - Connection conn = getConnection("backup"); - conn.createStatement().execute("create table test(x clob) as select space(10000)"); - conn.close(); - Backup.execute(getBaseDir() + "/backup.zip", getBaseDir(), "backup", true); - deleteDb("backup"); - Restore.execute(getBaseDir() + "/backup.zip", getBaseDir(), "backup", true); - } - - private void testBackupRestoreLobStatement() throws SQLException { - deleteDb("backup"); - Connection conn = getConnection("backup"); - conn.createStatement().execute("create table test(x clob) as select space(10000)"); - conn.createStatement().execute("backup to '" +getBaseDir() + "/backup.zip"+"'"); - conn.close(); - deleteDb("backup"); - Restore.execute(getBaseDir() + "/backup.zip", getBaseDir(), "backup", true); - } - - private void testBackup() throws SQLException { - deleteDb("backup"); - deleteDb("restored"); - Connection conn1, conn2, conn3; - Statement stat1, stat2, stat3; - conn1 = getConnection("backup"); - stat1 = conn1.createStatement(); - stat1.execute("create table test(id int primary key, name varchar(255))"); - stat1.execute("insert into test values(1, 'first'), (2, 'second')"); - stat1.execute("create table testlob(id int primary key, b blob, c clob)"); - stat1.execute("insert into testlob values(1, space(10000), repeat('00', 10000))"); - conn2 = getConnection("backup"); - stat2 = conn2.createStatement(); - stat2.execute("insert into test values(3, 'third')"); - conn2.setAutoCommit(false); - stat2.execute("insert into test values(4, 'fourth (uncommitted)')"); - stat2.execute("insert into testlob values(2, ' ', '00')"); - - stat1.execute("backup to '" + getBaseDir() + "/backup.zip'"); - conn2.rollback(); - assertEqualDatabases(stat1, stat2); - - Restore.execute(getBaseDir() + "/backup.zip", getBaseDir(), "restored", true); - conn3 = getConnection("restored"); - stat3 = conn3.createStatement(); - assertEqualDatabases(stat1, stat3); - - conn1.close(); - conn2.close(); - conn3.close(); - deleteDb("restored"); - } - -} diff --git a/tools/h2/src/test/org/h2/test/db/TestBigDb.java b/tools/h2/src/test/org/h2/test/db/TestBigDb.java deleted file mode 100755 index 0af6a53..0000000 --- a/tools/h2/src/test/org/h2/test/db/TestBigDb.java +++ /dev/null @@ -1,144 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.test.db; - -import java.sql.Connection; -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.sql.Statement; - -import org.h2.test.TestBase; -import org.h2.util.Utils; - -/** - * Test for big databases. - */ -public class TestBigDb extends TestBase { - - /** - * Run just this test. - * - * @param a ignored - */ - public static void main(String... a) throws Exception { - TestBase.createCaller().init().test(); - } - - public void test() throws SQLException { - if (config.memory) { - return; - } - if (config.networked && config.big) { - return; - } - testLargeTable(); - testInsert(); - testLeftSummary(); - deleteDb("bigDb"); - } - - private void testLargeTable() throws SQLException { - deleteDb("bigDb"); - Connection conn = getConnection("bigDb"); - Statement stat = conn.createStatement(); - stat.execute("CREATE CACHED TABLE TEST(" + "M_CODE CHAR(1) DEFAULT CAST(RAND()*9 AS INT)," - + "PRD_CODE CHAR(20) DEFAULT SECURE_RAND(10)," + "ORG_CODE_SUPPLIER CHAR(13) DEFAULT SECURE_RAND(6)," - + "PRD_CODE_1 CHAR(14) DEFAULT SECURE_RAND(7)," + "PRD_CODE_2 CHAR(20) DEFAULT SECURE_RAND(10)," - + "ORG_CODE CHAR(13) DEFAULT SECURE_RAND(6)," + "SUBSTITUTED_BY CHAR(20) DEFAULT SECURE_RAND(10)," - + "SUBSTITUTED_BY_2 CHAR(14) DEFAULT SECURE_RAND(7)," - + "SUBSTITUTION_FOR CHAR(20) DEFAULT SECURE_RAND(10)," - + "SUBSTITUTION_FOR_2 CHAR(14) DEFAULT SECURE_RAND(7)," + "TEST CHAR(2) DEFAULT SECURE_RAND(1)," - + "TEST_2 CHAR(2) DEFAULT SECURE_RAND(1)," + "TEST_3 DECIMAL(7,2) DEFAULT RAND()," - + "PRIMARY_UNIT_CODE CHAR(3) DEFAULT SECURE_RAND(1)," - + "RATE_PRICE_ORDER_UNIT DECIMAL(9,3) DEFAULT RAND()," - + "ORDER_UNIT_CODE CHAR(3) DEFAULT SECURE_RAND(1)," + "ORDER_QTY_MIN DECIMAL(6,1) DEFAULT RAND()," - + "ORDER_QTY_LOT_SIZE DECIMAL(6,1) DEFAULT RAND()," - + "ORDER_UNIT_CODE_2 CHAR(3) DEFAULT SECURE_RAND(1)," + "PRICE_GROUP CHAR(20) DEFAULT SECURE_RAND(10)," - + "LEAD_TIME INTEGER DEFAULT RAND()," + "LEAD_TIME_UNIT_CODE CHAR(3) DEFAULT SECURE_RAND(1)," - + "PRD_GROUP CHAR(10) DEFAULT SECURE_RAND(5)," + "WEIGHT_GROSS DECIMAL(7,3) DEFAULT RAND()," - + "WEIGHT_UNIT_CODE CHAR(3) DEFAULT SECURE_RAND(1)," + "PACK_UNIT_CODE CHAR(3) DEFAULT SECURE_RAND(1)," - + "PACK_LENGTH DECIMAL(7,3) DEFAULT RAND()," + "PACK_WIDTH DECIMAL(7,3) DEFAULT RAND()," - + "PACK_HEIGHT DECIMAL(7,3) DEFAULT RAND()," + "SIZE_UNIT_CODE CHAR(3) DEFAULT SECURE_RAND(1)," - + "STATUS_CODE CHAR(3) DEFAULT SECURE_RAND(1)," + "INTRA_STAT_CODE CHAR(12) DEFAULT SECURE_RAND(6)," - + "PRD_TITLE CHAR(50) DEFAULT SECURE_RAND(25)," + "VALID_FROM DATE DEFAULT NOW()," - + "MOD_DATUM DATE DEFAULT NOW())"); - int len = getSize(10, 50000); - try { - PreparedStatement prep = conn.prepareStatement("INSERT INTO TEST(PRD_CODE) VALUES('abc' || ?)"); - long time = System.currentTimeMillis(); - for (int i = 0; i < len; i++) { - if ((i % 1000) == 0) { - long t = System.currentTimeMillis(); - if (t - time > 1000) { - time = t; - int free = Utils.getMemoryFree(); - println("i: " + i + " free: " + free + " used: " + Utils.getMemoryUsed()); - } - } - prep.setInt(1, i); - prep.execute(); - } - stat.execute("CREATE INDEX IDX_TEST_PRD_CODE ON TEST(PRD_CODE)"); - ResultSet rs = stat.executeQuery("SELECT * FROM TEST"); - int columns = rs.getMetaData().getColumnCount(); - while (rs.next()) { - for (int i = 0; i < columns; i++) { - rs.getString(i + 1); - } - } - } catch (OutOfMemoryError e) { - TestBase.logError("memory", e); - conn.close(); - throw e; - } - conn.close(); - } - - private void testLeftSummary() throws SQLException { - deleteDb("bigDb"); - Connection conn = getConnection("bigDb"); - Statement stat = conn.createStatement(); - stat.execute("CREATE TABLE TEST(ID INT, NEG INT AS -ID, NAME VARCHAR, PRIMARY KEY(ID, NAME))"); - stat.execute("CREATE INDEX IDX_NEG ON TEST(NEG, NAME)"); - PreparedStatement prep = conn.prepareStatement("INSERT INTO TEST(ID, NAME) VALUES(?, '1234567890')"); - int len = getSize(10, 1000); - int block = getSize(3, 10); - int left, x = 0; - for (int i = 0; i < len; i++) { - left = x + block / 2; - for (int j = 0; j < block; j++) { - prep.setInt(1, x++); - prep.execute(); - } - stat.execute("DELETE FROM TEST WHERE ID>" + left); - ResultSet rs = stat.executeQuery("SELECT COUNT(*) FROM TEST"); - rs.next(); - int count = rs.getInt(1); - trace("count: " + count); - } - conn.close(); - } - - private void testInsert() throws SQLException { - deleteDb("bigDb"); - Connection conn = getConnection("bigDb"); - Statement stat = conn.createStatement(); - stat.execute("CREATE TABLE TEST(ID IDENTITY, NAME VARCHAR)"); - PreparedStatement prep = conn.prepareStatement("INSERT INTO TEST(NAME) VALUES('Hello World')"); - int len = getSize(1000, 10000); - for (int i = 0; i < len; i++) { - if (i % 1000 == 0) { - println("rows: " + i); - Thread.yield(); - } - prep.execute(); - } - conn.close(); - } - -} diff --git a/tools/h2/src/test/org/h2/test/db/TestBigResult.java b/tools/h2/src/test/org/h2/test/db/TestBigResult.java deleted file mode 100755 index a9b296f..0000000 --- a/tools/h2/src/test/org/h2/test/db/TestBigResult.java +++ /dev/null @@ -1,200 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.test.db; - -import java.sql.Connection; -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.sql.Statement; -import java.util.ArrayList; - -import org.h2.store.FileLister; -import org.h2.test.TestBase; - -/** - * Test for big result sets. - */ -public class TestBigResult extends TestBase { - - /** - * Run just this test. - * - * @param a ignored - */ - public static void main(String... a) throws Exception { - TestBase.createCaller().init().test(); - } - - public void test() throws SQLException { - if (config.memory) { - return; - } - testLargeSubquery(); - testLargeUpdateDelete(); - testCloseConnectionDelete(); - testOrderGroup(); - testLimitBufferedResult(); - deleteDb("bigResult"); - } - - private void testLargeSubquery() throws SQLException { - deleteDb("bigResult"); - Connection conn = getConnection("bigResult"); - Statement stat = conn.createStatement(); - int len = getSize(1000, 4000); - stat.execute("SET MAX_MEMORY_ROWS " + (len / 10)); - stat.execute("CREATE TABLE RECOVERY(TRANSACTION_ID INT, SQL_STMT VARCHAR)"); - stat.execute("INSERT INTO RECOVERY " + - "SELECT X, CASE MOD(X, 2) WHEN 0 THEN 'commit' ELSE 'begin' END " + - "FROM SYSTEM_RANGE(1, "+len+")"); - ResultSet rs = stat.executeQuery("SELECT * FROM RECOVERY WHERE SQL_STMT LIKE 'begin%' AND " + - "TRANSACTION_ID NOT IN(SELECT TRANSACTION_ID FROM RECOVERY " + - "WHERE SQL_STMT='commit' OR SQL_STMT='rollback')"); - int count = 0, last = 1; - while (rs.next()) { - assertEquals(last, rs.getInt(1)); - last += 2; - count++; - } - assertEquals(len / 2, count); - conn.close(); - } - - private void testLargeUpdateDelete() throws SQLException { - deleteDb("bigResult"); - Connection conn = getConnection("bigResult"); - Statement stat = conn.createStatement(); - int len = getSize(10000, 100000); - stat.execute("SET MAX_OPERATION_MEMORY 4096"); - stat.execute("CREATE TABLE TEST AS SELECT * FROM SYSTEM_RANGE(1, " + len + ")"); - stat.execute("UPDATE TEST SET X=X+1"); - stat.execute("DELETE FROM TEST"); - conn.close(); - } - - private void testCloseConnectionDelete() throws SQLException { - deleteDb("bigResult"); - Connection conn = getConnection("bigResult"); - Statement stat = conn.createStatement(); - stat.execute("SET MAX_MEMORY_ROWS 2"); - ResultSet rs = stat.executeQuery("SELECT * FROM SYSTEM_RANGE(1, 100)"); - while (rs.next()) { - // ignore - } - // rs.close(); - conn.close(); - deleteDb("bigResult"); - ArrayList files = FileLister.getDatabaseFiles(getBaseDir(), "bigResult", true); - if (files.size() > 0) { - fail("file not deleted: " + files.get(0)); - } - } - - private void testLimitBufferedResult() throws SQLException { - deleteDb("bigResult"); - Connection conn = getConnection("bigResult"); - Statement stat = conn.createStatement(); - stat.execute("DROP TABLE IF EXISTS TEST"); - stat.execute("CREATE TABLE TEST(ID INT)"); - for (int i = 0; i < 200; i++) { - stat.execute("INSERT INTO TEST(ID) VALUES(" + i + ")"); - } - stat.execute("SET MAX_MEMORY_ROWS 100"); - ResultSet rs; - rs = stat.executeQuery("select id from test order by id limit 10 offset 85"); - for (int i = 85; rs.next(); i++) { - assertEquals(i, rs.getInt(1)); - } - rs = stat.executeQuery("select id from test order by id limit 10 offset 95"); - for (int i = 95; rs.next(); i++) { - assertEquals(i, rs.getInt(1)); - } - rs = stat.executeQuery("select id from test order by id limit 10 offset 105"); - for (int i = 105; rs.next(); i++) { - assertEquals(i, rs.getInt(1)); - } - conn.close(); - } - - private void testOrderGroup() throws SQLException { - deleteDb("bigResult"); - Connection conn = getConnection("bigResult"); - Statement stat = conn.createStatement(); - stat.execute("DROP TABLE IF EXISTS TEST"); - stat.execute("CREATE TABLE TEST(" + - "ID INT PRIMARY KEY, " + - "Name VARCHAR(255), " + - "FirstName VARCHAR(255), " + - "Points INT," + - "LicenseID INT)"); - int len = getSize(10, 5000); - PreparedStatement prep = conn.prepareStatement("INSERT INTO TEST VALUES(?, ?, ?, ?, ?)"); - for (int i = 0; i < len; i++) { - prep.setInt(1, i); - prep.setString(2, "Name " + i); - prep.setString(3, "First Name " + i); - prep.setInt(4, i * 10); - prep.setInt(5, i * i); - prep.execute(); - } - conn.close(); - conn = getConnection("bigResult"); - stat = conn.createStatement(); - stat.setMaxRows(len + 1); - ResultSet rs = stat.executeQuery("SELECT * FROM TEST ORDER BY ID"); - for (int i = 0; i < len; i++) { - rs.next(); - assertEquals(i, rs.getInt(1)); - assertEquals("Name " + i, rs.getString(2)); - assertEquals("First Name " + i, rs.getString(3)); - assertEquals(i * 10, rs.getInt(4)); - assertEquals(i * i, rs.getInt(5)); - } - - stat.setMaxRows(len + 1); - rs = stat.executeQuery("SELECT * FROM TEST WHERE ID >= 1000 ORDER BY ID"); - for (int i = 1000; i < len; i++) { - rs.next(); - assertEquals(i, rs.getInt(1)); - assertEquals("Name " + i, rs.getString(2)); - assertEquals("First Name " + i, rs.getString(3)); - assertEquals(i * 10, rs.getInt(4)); - assertEquals(i * i, rs.getInt(5)); - } - - stat.execute("SET MAX_MEMORY_ROWS 2"); - rs = stat.executeQuery("SELECT Name, SUM(ID) FROM TEST GROUP BY NAME"); - while (rs.next()) { - rs.getString(1); - rs.getInt(2); - } - - conn.setAutoCommit(false); - stat.setMaxRows(0); - stat.execute("SET MAX_MEMORY_ROWS 0"); - stat.execute("CREATE TABLE DATA(ID INT, NAME VARCHAR_IGNORECASE(255))"); - prep = conn.prepareStatement("INSERT INTO DATA VALUES(?, ?)"); - for (int i = 0; i < len; i++) { - prep.setInt(1, i); - prep.setString(2, "" + i / 200); - prep.execute(); - } - Statement s2 = conn.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_UPDATABLE); - rs = s2.executeQuery("SELECT NAME FROM DATA"); - rs.last(); - conn.setAutoCommit(true); - - rs = s2.executeQuery("SELECT NAME FROM DATA ORDER BY ID"); - while (rs.next()) { - // do nothing - } - - conn.close(); - } - -} diff --git a/tools/h2/src/test/org/h2/test/db/TestCases.java b/tools/h2/src/test/org/h2/test/db/TestCases.java deleted file mode 100755 index f6eb8c6..0000000 --- a/tools/h2/src/test/org/h2/test/db/TestCases.java +++ /dev/null @@ -1,1067 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.test.db; - -import java.io.File; -import java.io.StringReader; -import java.sql.Connection; -import java.sql.Date; -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.sql.Statement; -import java.sql.Time; -import java.sql.Timestamp; -import java.util.Random; -import org.h2.constant.ErrorCode; -import org.h2.test.TestBase; -import org.h2.util.IOUtils; - -/** - * Various test cases. - */ -public class TestCases extends TestBase { - - /** - * Run just this test. - * - * @param a ignored - */ - public static void main(String... a) throws Exception { - TestBase.createCaller().init().test(); - } - - public void test() throws Exception { - testPreparedSubquery2(); - testPreparedSubquery(); - testCompareDoubleWithIntColumn(); - testDeleteIndexOutOfBounds(); - testOrderByWithSubselect(); - testInsertDeleteRollback(); - testLargeRollback(); - testConstraintAlterTable(); - testJoinWithView(); - testLobDecrypt(); - testInvalidDatabaseName(); - testReuseSpace(); - testDeleteGroup(); - testDisconnect(); - testExecuteTrace(); - if (config.memory) { - return; - } - testDeleteAndDropTableWithLobs(true); - testDeleteAndDropTableWithLobs(false); - testEmptyBtreeIndex(); - testReservedKeywordReconnect(); - testSpecialSQL(); - testUpperCaseLowerCaseDatabase(); - testManualCommitSet(); - testSchemaIdentityReconnect(); - testAlterTableReconnect(); - testPersistentSettings(); - testInsertSelectUnion(); - testViewReconnect(); - testDefaultQueryReconnect(); - testBigString(); - testRenameReconnect(); - testAllSizes(); - testCreateDrop(); - testPolePos(); - testQuick(); - testMutableObjects(); - testSelectForUpdate(); - testDoubleRecovery(); - testConstraintReconnect(); - testCollation(); - deleteDb("cases"); - } - - private void testPreparedSubquery2() throws SQLException { - deleteDb("cases"); - Connection conn = getConnection("cases"); - Statement stat = conn.createStatement(); - stat.execute("create table test(id int primary key, name varchar(255))"); - stat.execute("insert into test values(1, 'Hello')"); - stat.execute("insert into test values(2, 'World')"); - - PreparedStatement ps = conn.prepareStatement("select name from test where id in (select id from test where name = ?)"); - ps.setString(1, "Hello"); - ResultSet rs = ps.executeQuery(); - if (rs.next()) { - if (!rs.getString("name").equals("Hello")) { - fail("'" + rs.getString("name") + "' must be 'Hello'"); - } - } else { - fail("Must have a result!"); - } - rs.close(); - - ps.setString(1, "World"); - rs = ps.executeQuery(); - if (rs.next()) { - if (!rs.getString("name").equals("World")) { - fail("'" + rs.getString("name") + "' must be 'World'"); - } - } else { - fail("Must have a result!"); - } - rs.close(); - conn.close(); - } - - private void testPreparedSubquery() throws SQLException { - deleteDb("cases"); - Connection conn = getConnection("cases"); - Statement stat = conn.createStatement(); - stat.execute("create table test(id int)"); - stat.execute("insert into test values(1)"); - String sql = "select ?, ?, (select count(*) from test inner join " + - "(select id from test where 0=?) as t2 on t2.id=test.id) from test"; - ResultSet rs; - rs = stat.executeQuery(sql.replace('?', '0')); - rs.next(); - assertEquals(1, rs.getInt(3)); - PreparedStatement prep = conn.prepareStatement(sql); - prep.setInt(1, 0); - prep.setInt(2, 0); - prep.setInt(3, 0); - rs = prep.executeQuery(); - rs.next(); - assertEquals(1, rs.getInt(3)); - conn.close(); - } - - private void testCompareDoubleWithIntColumn() throws SQLException { - deleteDb("cases"); - Connection conn = getConnection("cases"); - Statement stat = conn.createStatement(); - testCompareDoubleWithIntColumn(stat, false, 0.1, false); - testCompareDoubleWithIntColumn(stat, false, 0.1, true); - testCompareDoubleWithIntColumn(stat, false, 0.9, false); - testCompareDoubleWithIntColumn(stat, false, 0.9, true); - testCompareDoubleWithIntColumn(stat, true, 0.1, false); - testCompareDoubleWithIntColumn(stat, true, 0.1, true); - testCompareDoubleWithIntColumn(stat, true, 0.9, false); - testCompareDoubleWithIntColumn(stat, true, 0.9, true); - conn.close(); - } - - private void testCompareDoubleWithIntColumn(Statement stat, boolean pk, double x, boolean prepared) throws SQLException { - if (pk) { - stat.execute("create table test(id int primary key)"); - } else { - stat.execute("create table test(id int)"); - } - stat.execute("insert into test values(1)"); - ResultSet rs; - if (prepared) { - PreparedStatement prep = stat.getConnection().prepareStatement("select * from test where id > ?"); - prep.setDouble(1, x); - rs = prep.executeQuery(); - } else { - rs = stat.executeQuery("select * from test where id > " + x); - } - assertTrue(rs.next()); - stat.execute("drop table test"); - } - - private void testDeleteIndexOutOfBounds() throws SQLException { - if (config.memory || !config.big) { - return; - } - deleteDb("cases"); - Connection conn = getConnection("cases"); - Statement stat = conn.createStatement(); - stat.execute("CREATE TABLE IF NOT EXISTS test (rowid INTEGER PRIMARY KEY AUTO_INCREMENT, txt VARCHAR(64000));"); - PreparedStatement prep = conn.prepareStatement("insert into test (txt) values(space(?))"); - for (int i = 0; i < 3000; i++) { - prep.setInt(1, i * 3); - prep.execute(); - } - stat.execute("DELETE FROM test;"); - conn.close(); - } - - private void testInsertDeleteRollback() throws SQLException { - deleteDb("cases"); - Connection conn = getConnection("cases"); - Statement stat = conn.createStatement(); - stat.execute("set cache_size 1"); - stat.execute("SET MAX_MEMORY_ROWS " + Integer.MAX_VALUE); - stat.execute("SET MAX_MEMORY_UNDO " + Integer.MAX_VALUE); - stat.execute("SET MAX_OPERATION_MEMORY " + Integer.MAX_VALUE); - stat.execute("create table test(id identity)"); - conn.setAutoCommit(false); - stat.execute("insert into test select x from system_range(1, 11)"); - stat.execute("delete from test"); - conn.rollback(); - conn.close(); - } - - private void testLargeRollback() throws SQLException { - Connection conn; - Statement stat; - - deleteDb("cases"); - conn = getConnection("cases"); - stat = conn.createStatement(); - stat.execute("set max_operation_memory 1"); - stat.execute("create table test(id int)"); - stat.execute("insert into test values(1), (2)"); - stat.execute("create index idx on test(id)"); - conn.setAutoCommit(false); - stat.execute("update test set id = id where id=2"); - stat.execute("update test set id = id"); - conn.rollback(); - conn.close(); - - deleteDb("cases"); - conn = getConnection("cases"); - conn.createStatement().execute("set MAX_MEMORY_UNDO 1"); - conn.createStatement().execute("create table test(id number primary key)"); - conn.createStatement().execute("insert into test(id) select x from system_range(1, 2)"); - Connection conn2 = getConnection("cases"); - conn2.setAutoCommit(false); - assertEquals(2, conn2.createStatement().executeUpdate("delete from test")); - conn2.close(); - conn.close(); - - deleteDb("cases"); - conn = getConnection("cases"); - conn.createStatement().execute("set MAX_MEMORY_UNDO 8"); - conn.createStatement().execute("create table test(id number primary key)"); - conn.setAutoCommit(false); - conn.createStatement().execute("insert into test select x from system_range(1, 10)"); - conn.createStatement().execute("delete from test"); - conn.rollback(); - conn.close(); - } - - private void testConstraintAlterTable() throws SQLException { - deleteDb("cases"); - Connection conn = getConnection("cases"); - Statement stat = conn.createStatement(); - stat.execute("create table parent (pid int)"); - stat.execute("create table child (cid int primary key, pid int)"); - stat.execute("alter table child add foreign key (pid) references parent(pid)"); - stat.execute("alter table child add column c2 int"); - stat.execute("alter table parent add column p2 varchar"); - conn.close(); - } - - private void testEmptyBtreeIndex() throws SQLException { - deleteDb("cases"); - Connection conn; - conn = getConnection("cases"); - conn.createStatement().execute("CREATE TABLE test(id int PRIMARY KEY);"); - conn.createStatement().execute("INSERT INTO test SELECT X FROM SYSTEM_RANGE(1, 77)"); - conn.createStatement().execute("DELETE from test"); - conn.close(); - conn = getConnection("cases"); - conn.createStatement().execute("INSERT INTO test (id) VALUES (1)"); - conn.close(); - conn = getConnection("cases"); - conn.createStatement().execute("DELETE from test"); - conn.createStatement().execute("drop table test"); - conn.close(); - } - - private void testJoinWithView() throws SQLException { - deleteDb("cases"); - Connection conn = getConnection("cases"); - conn.createStatement().execute( - "create table t(i identity, n varchar) as select 1, 'x'"); - PreparedStatement prep = conn.prepareStatement( - "select 1 from dual " + - "inner join(select n from t where i=?) a on a.n='x' " + - "inner join(select n from t where i=?) b on b.n='x'"); - prep.setInt(1, 1); - prep.setInt(2, 1); - prep.execute(); - conn.close(); - } - - private void testLobDecrypt() throws SQLException { - Connection conn = getConnection("cases"); - String key = "key"; - String value = "Hello World"; - PreparedStatement prep = conn.prepareStatement("CALL ENCRYPT('AES', RAWTOHEX(?), STRINGTOUTF8(?))"); - prep.setCharacterStream(1, new StringReader(key), -1); - prep.setCharacterStream(2, new StringReader(value), -1); - ResultSet rs = prep.executeQuery(); - rs.next(); - String encrypted = rs.getString(1); - PreparedStatement prep2 = conn - .prepareStatement("CALL TRIM(CHAR(0) FROM UTF8TOSTRING(DECRYPT('AES', RAWTOHEX(?), ?)))"); - prep2.setCharacterStream(1, new StringReader(key), -1); - prep2.setCharacterStream(2, new StringReader(encrypted), -1); - ResultSet rs2 = prep2.executeQuery(); - rs2.first(); - String decrypted = rs2.getString(1); - prep2.close(); - assertEquals(value, decrypted); - conn.close(); - } - - private void testReservedKeywordReconnect() throws SQLException { - if (config.memory) { - return; - } - deleteDb("cases"); - Connection conn = getConnection("cases"); - Statement stat = conn.createStatement(); - stat.execute("create table \"UNIQUE\"(\"UNIQUE\" int)"); - conn.close(); - conn = getConnection("cases"); - stat = conn.createStatement(); - stat.execute("select \"UNIQUE\" from \"UNIQUE\""); - stat.execute("drop table \"UNIQUE\""); - conn.close(); - } - - private void testInvalidDatabaseName() { - if (config.memory) { - return; - } - try { - getConnection("cases/"); - fail(); - } catch (SQLException e) { - assertEquals(ErrorCode.INVALID_DATABASE_NAME_1, e.getErrorCode()); - } - } - - private void testReuseSpace() throws SQLException { - deleteDb("cases"); - Connection conn = getConnection("cases"); - Statement stat = conn.createStatement(); - int tableCount = getSize(2, 5); - for (int i = 0; i < tableCount; i++) { - stat.execute("create table t" + i + "(data varchar)"); - } - Random random = new Random(1); - int len = getSize(50, 500); - for (int i = 0; i < len; i++) { - String table = "t" + random.nextInt(tableCount); - String sql; - if (random.nextBoolean()) { - sql = "insert into " + table + " values(space(100000))"; - } else { - sql = "delete from " + table; - } - stat.execute(sql); - stat.execute("script to '" + getBaseDir() + "/test.sql'"); - } - conn.close(); - IOUtils.delete(getBaseDir() + "/test.sql"); - } - - private void testDeleteGroup() throws SQLException { - deleteDb("cases"); - Connection conn = getConnection("cases"); - Statement stat = conn.createStatement(); - stat.execute("set max_memory_rows 2"); - stat.execute("create table test(id int primary key, x int)"); - stat.execute("insert into test values(0, 0), (1, 1), (2, 2)"); - stat.execute("delete from test where id not in (select min(x) from test group by id)"); - conn.close(); - } - - private void testSpecialSQL() throws SQLException { - deleteDb("cases"); - Connection conn = getConnection("cases"); - Statement stat = conn.createStatement(); - try { - stat.execute("create table address(id identity, name varchar check? instr(value, '@') > 1)"); - } catch (SQLException e) { - assertKnownException(e); - } - stat.execute("SET AUTOCOMMIT OFF; \n//create sequence if not exists object_id;\n"); - stat.execute("SET AUTOCOMMIT OFF;\n//create sequence if not exists object_id;\n"); - stat.execute("SET AUTOCOMMIT OFF; //create sequence if not exists object_id;"); - stat.execute("SET AUTOCOMMIT OFF;//create sequence if not exists object_id;"); - stat.execute("SET AUTOCOMMIT OFF \n//create sequence if not exists object_id;"); - stat.execute("SET AUTOCOMMIT OFF\n//create sequence if not exists object_id;"); - stat.execute("SET AUTOCOMMIT OFF //create sequence if not exists object_id;"); - stat.execute("SET AUTOCOMMIT OFF//create sequence if not exists object_id;"); - stat.execute("SET AUTOCOMMIT OFF; \n///create sequence if not exists object_id;"); - stat.execute("SET AUTOCOMMIT OFF;\n///create sequence if not exists object_id;"); - stat.execute("SET AUTOCOMMIT OFF; ///create sequence if not exists object_id;"); - stat.execute("SET AUTOCOMMIT OFF;///create sequence if not exists object_id;"); - stat.execute("SET AUTOCOMMIT OFF \n///create sequence if not exists object_id;"); - stat.execute("SET AUTOCOMMIT OFF\n///create sequence if not exists object_id;"); - stat.execute("SET AUTOCOMMIT OFF ///create sequence if not exists object_id;"); - stat.execute("SET AUTOCOMMIT OFF///create sequence if not exists object_id;"); - conn.close(); - } - - private void testUpperCaseLowerCaseDatabase() throws SQLException { - if (File.separatorChar != '\\' || config.googleAppEngine) { - return; - } - deleteDb("cases"); - deleteDb("CaSeS"); - Connection conn, conn2; - ResultSet rs; - conn = getConnection("cases"); - Statement stat = conn.createStatement(); - stat.execute("CHECKPOINT"); - stat.execute("CREATE TABLE TEST(ID INT)"); - stat.execute("INSERT INTO TEST VALUES(1)"); - stat.execute("CHECKPOINT"); - - conn2 = getConnection("CaSeS"); - rs = conn.createStatement().executeQuery("SELECT * FROM TEST"); - assertTrue(rs.next()); - conn2.close(); - - conn.close(); - - conn = getConnection("cases"); - rs = conn.createStatement().executeQuery("SELECT * FROM TEST"); - assertTrue(rs.next()); - conn.close(); - - conn = getConnection("CaSeS"); - rs = conn.createStatement().executeQuery("SELECT * FROM TEST"); - assertTrue(rs.next()); - conn.close(); - - deleteDb("cases"); - deleteDb("CaSeS"); - - } - - private void testManualCommitSet() throws SQLException { - deleteDb("cases"); - Connection conn = getConnection("cases"); - Connection conn2 = getConnection("cases"); - conn.setAutoCommit(false); - conn2.setAutoCommit(false); - conn.createStatement().execute("SET MODE REGULAR"); - conn2.createStatement().execute("SET MODE REGULAR"); - conn.close(); - conn2.close(); - } - - private void testSchemaIdentityReconnect() throws SQLException { - deleteDb("cases"); - Connection conn = getConnection("cases"); - Statement stat = conn.createStatement(); - stat.execute("create schema s authorization sa"); - stat.execute("create table s.test(id identity)"); - conn.close(); - conn = getConnection("cases"); - ResultSet rs = conn.createStatement().executeQuery("SELECT * FROM S.TEST"); - while (rs.next()) { - // ignore - } - conn.close(); - } - - private void testDisconnect() throws Exception { - if (config.networked || config.codeCoverage) { - return; - } - deleteDb("cases"); - Connection conn = getConnection("cases"); - final Statement stat = conn.createStatement(); - stat.execute("CREATE TABLE TEST(ID IDENTITY)"); - for (int i = 0; i < 1000; i++) { - stat.execute("INSERT INTO TEST() VALUES()"); - } - final SQLException[] stopped = { null }; - Thread t = new Thread(new Runnable() { - public void run() { - try { - long time = System.currentTimeMillis(); - ResultSet rs = stat - .executeQuery("SELECT MAX(T.ID) FROM TEST T, TEST, TEST, TEST, TEST, TEST, TEST, TEST, TEST, TEST, TEST"); - rs.next(); - time = System.currentTimeMillis() - time; - TestBase.logError("query was too quick; result: " + rs.getInt(1) + " time:" + time, null); - } catch (SQLException e) { - stopped[0] = e; - // ok - } - } - }); - t.start(); - Thread.sleep(300); - long time = System.currentTimeMillis(); - conn.close(); - t.join(5000); - if (stopped[0] == null) { - fail("query still running"); - } else { - assertKnownException(stopped[0]); - } - time = System.currentTimeMillis() - time; - if (time > 5000) { - fail("closing took " + time); - } - deleteDb("cases"); - } - - private void testExecuteTrace() throws SQLException { - deleteDb("cases"); - Connection conn = getConnection("cases"); - Statement stat = conn.createStatement(); - ResultSet rs = stat.executeQuery("SELECT ? FROM DUAL {1: 'Hello'}"); - rs.next(); - assertEquals("Hello", rs.getString(1)); - assertFalse(rs.next()); - - rs = stat.executeQuery("SELECT ? FROM DUAL UNION ALL SELECT ? FROM DUAL {1: 'Hello', 2:'World' }"); - rs.next(); - assertEquals("Hello", rs.getString(1)); - rs.next(); - assertEquals("World", rs.getString(1)); - assertFalse(rs.next()); - - conn.close(); - } - - private void testAlterTableReconnect() throws SQLException { - deleteDb("cases"); - Connection conn = getConnection("cases"); - Statement stat = conn.createStatement(); - stat.execute("create table test(id identity);"); - stat.execute("insert into test values(1);"); - try { - stat.execute("alter table test add column name varchar not null;"); - fail(); - } catch (SQLException e) { - assertKnownException(e); - } - conn.close(); - conn = getConnection("cases"); - ResultSet rs = conn.createStatement().executeQuery("SELECT * FROM TEST"); - rs.next(); - assertEquals("1", rs.getString(1)); - assertFalse(rs.next()); - stat = conn.createStatement(); - stat.execute("drop table test"); - stat.execute("create table test(id identity)"); - stat.execute("insert into test values(1)"); - stat.execute("alter table test alter column id set default 'x'"); - conn.close(); - conn = getConnection("cases"); - stat = conn.createStatement(); - rs = conn.createStatement().executeQuery("SELECT * FROM TEST"); - rs.next(); - assertEquals("1", rs.getString(1)); - assertFalse(rs.next()); - stat.execute("drop table test"); - stat.execute("create table test(id identity)"); - stat.execute("insert into test values(1)"); - try { - stat.execute("alter table test alter column id date"); - fail(); - } catch (SQLException e) { - assertKnownException(e); - } - conn.close(); - conn = getConnection("cases"); - rs = conn.createStatement().executeQuery("SELECT * FROM TEST"); - rs.next(); - assertEquals("1", rs.getString(1)); - assertFalse(rs.next()); - conn.close(); - } - - private void testCollation() throws SQLException { - deleteDb("cases"); - Connection conn = getConnection("cases"); - Statement stat = conn.createStatement(); - stat.execute("SET COLLATION ENGLISH STRENGTH PRIMARY"); - stat.execute("CREATE TABLE TEST(ID INT PRIMARY KEY, NAME VARCHAR(255))"); - stat.execute("INSERT INTO TEST VALUES(1, 'Hello'), (2, 'World'), (3, 'WORLD'), (4, 'HELLO')"); - stat.execute("create index idxname on test(name)"); - ResultSet rs; - rs = stat.executeQuery("select name from test order by name"); - rs.next(); - assertEquals("Hello", rs.getString(1)); - rs.next(); - assertEquals("HELLO", rs.getString(1)); - rs.next(); - assertEquals("World", rs.getString(1)); - rs.next(); - assertEquals("WORLD", rs.getString(1)); - rs = stat.executeQuery("select name from test where name like 'He%'"); - rs.next(); - assertEquals("Hello", rs.getString(1)); - rs.next(); - assertEquals("HELLO", rs.getString(1)); - conn.close(); - } - - private void testPersistentSettings() throws SQLException { - deleteDb("cases"); - Connection conn = getConnection("cases"); - Statement stat = conn.createStatement(); - stat.execute("SET COLLATION de_DE"); - stat.execute("CREATE TABLE TEST(ID INT PRIMARY KEY, NAME VARCHAR)"); - stat.execute("CREATE INDEX IDXNAME ON TEST(NAME)"); - // \u00f6 = oe - stat.execute("INSERT INTO TEST VALUES(1, 'B\u00f6hlen'), (2, 'Bach'), (3, 'Bucher')"); - conn.close(); - conn = getConnection("cases"); - ResultSet rs = conn.createStatement().executeQuery("SELECT NAME FROM TEST ORDER BY NAME"); - rs.next(); - assertEquals("Bach", rs.getString(1)); - rs.next(); - assertEquals("B\u00f6hlen", rs.getString(1)); - rs.next(); - assertEquals("Bucher", rs.getString(1)); - conn.close(); - } - - private void testInsertSelectUnion() throws SQLException { - deleteDb("cases"); - Connection conn = getConnection("cases"); - Statement stat = conn.createStatement(); - stat.execute("CREATE TABLE TEST(ORDER_ID INT PRIMARY KEY, ORDER_DATE DATETIME, USER_ID INT ," - + "DESCRIPTION VARCHAR, STATE VARCHAR, TRACKING_ID VARCHAR)"); - Timestamp orderDate = Timestamp.valueOf("2005-05-21 17:46:00"); - String sql = "insert into TEST (ORDER_ID,ORDER_DATE,USER_ID,DESCRIPTION,STATE,TRACKING_ID) " - + "select cast(? as int),cast(? as date),cast(? as int),cast(? as varchar),cast(? as varchar),cast(? as varchar) union all select ?,?,?,?,?,?"; - PreparedStatement ps = conn.prepareStatement(sql); - ps.setInt(1, 5555); - ps.setTimestamp(2, orderDate); - ps.setInt(3, 2222); - ps.setString(4, "test desc"); - ps.setString(5, "test_state"); - ps.setString(6, "testid"); - ps.setInt(7, 5556); - ps.setTimestamp(8, orderDate); - ps.setInt(9, 2222); - ps.setString(10, "test desc"); - ps.setString(11, "test_state"); - ps.setString(12, "testid"); - assertEquals(2, ps.executeUpdate()); - ps.close(); - conn.close(); - } - - private void testViewReconnect() throws SQLException { - trace("testViewReconnect"); - deleteDb("cases"); - Connection conn = getConnection("cases"); - Statement stat = conn.createStatement(); - stat.execute("create table test(id int)"); - stat.execute("create view abc as select * from test"); - stat.execute("drop table test"); - conn.close(); - conn = getConnection("cases"); - stat = conn.createStatement(); - try { - stat.execute("select * from abc"); - fail(); - } catch (SQLException e) { - assertKnownException(e); - } - conn.close(); - } - - private void testDefaultQueryReconnect() throws SQLException { - trace("testDefaultQueryReconnect"); - deleteDb("cases"); - Connection conn = getConnection("cases"); - Statement stat = conn.createStatement(); - stat.execute("create table parent(id int)"); - stat.execute("insert into parent values(1)"); - stat.execute("create table test(id int default (select max(id) from parent), name varchar)"); - - conn.close(); - conn = getConnection("cases"); - stat = conn.createStatement(); - conn.setAutoCommit(false); - stat.execute("insert into parent values(2)"); - stat.execute("insert into test(name) values('test')"); - ResultSet rs = stat.executeQuery("select * from test"); - rs.next(); - assertEquals(2, rs.getInt(1)); - assertFalse(rs.next()); - conn.close(); - } - - private void testBigString() throws SQLException { - trace("testBigString"); - deleteDb("cases"); - Connection conn = getConnection("cases"); - Statement stat = conn.createStatement(); - stat.execute("DROP TABLE IF EXISTS TEST"); - stat.execute("CREATE TABLE TEST(ID INT, TEXT VARCHAR, TEXT_C CLOB)"); - PreparedStatement prep = conn.prepareStatement("INSERT INTO TEST VALUES(?, ?, ?)"); - int len = getSize(1000, 66000); - char[] buff = new char[len]; - - // The UCS code values 0xd800-0xdfff (UTF-16 surrogates) - // as well as 0xfffe and 0xffff (UCS non-characters) - // should not appear in conforming UTF-8 streams. - // (String.getBytes("UTF-8") only returns 1 byte for 0xd800-0xdfff) - - Random random = new Random(); - random.setSeed(1); - for (int i = 0; i < len; i++) { - char c; - do { - c = (char) random.nextInt(); - } while (c >= 0xd800 && c <= 0xdfff); - buff[i] = c; - } - String big = new String(buff); - prep.setInt(1, 1); - prep.setString(2, big); - prep.setString(3, big); - prep.execute(); - prep.setInt(1, 2); - prep.setCharacterStream(2, new StringReader(big), 0); - prep.setCharacterStream(3, new StringReader(big), 0); - prep.execute(); - ResultSet rs = stat.executeQuery("SELECT * FROM TEST ORDER BY ID"); - rs.next(); - assertEquals(1, rs.getInt(1)); - assertEquals(big, rs.getString(2)); - assertEquals(big, readString(rs.getCharacterStream(2))); - assertEquals(big, rs.getString(3)); - assertEquals(big, readString(rs.getCharacterStream(3))); - rs.next(); - assertEquals(2, rs.getInt(1)); - assertEquals(big, rs.getString(2)); - assertEquals(big, readString(rs.getCharacterStream(2))); - assertEquals(big, rs.getString(3)); - assertEquals(big, readString(rs.getCharacterStream(3))); - rs.next(); - assertFalse(rs.next()); - conn.close(); - } - - private void testConstraintReconnect() throws SQLException { - trace("testConstraintReconnect"); - deleteDb("cases"); - Connection conn = getConnection("cases"); - Statement stat = conn.createStatement(); - stat.execute("drop table if exists parent"); - stat.execute("drop table if exists child"); - stat.execute("create table parent(id int)"); - stat.execute("create table child(c_id int, p_id int, foreign key(p_id) references parent(id))"); - stat.execute("insert into parent values(1), (2)"); - stat.execute("insert into child values(1, 1)"); - stat.execute("insert into child values(2, 2)"); - stat.execute("insert into child values(3, 2)"); - stat.execute("delete from child"); - conn.close(); - conn = getConnection("cases"); - conn.close(); - } - - private void testDoubleRecovery() throws SQLException { - if (config.networked || config.googleAppEngine) { - return; - } - trace("testDoubleRecovery"); - deleteDb("cases"); - Connection conn = getConnection("cases"); - Statement stat = conn.createStatement(); - stat.execute("SET WRITE_DELAY 0"); - stat.execute("DROP TABLE IF EXISTS TEST"); - stat.execute("CREATE TABLE TEST(ID INT PRIMARY KEY, NAME VARCHAR(255))"); - stat.execute("INSERT INTO TEST VALUES(1, 'Hello')"); - conn.setAutoCommit(false); - stat.execute("INSERT INTO TEST VALUES(2, 'World')"); - crash(conn); - - conn = getConnection("cases"); - stat = conn.createStatement(); - stat.execute("SET WRITE_DELAY 0"); - stat.execute("INSERT INTO TEST VALUES(3, 'Break')"); - crash(conn); - - conn = getConnection("cases"); - stat = conn.createStatement(); - ResultSet rs = stat.executeQuery("SELECT * FROM TEST ORDER BY ID"); - rs.next(); - assertEquals(1, rs.getInt(1)); - assertEquals("Hello", rs.getString(2)); - rs.next(); - assertEquals(3, rs.getInt(1)); - assertEquals("Break", rs.getString(2)); - conn.close(); - } - - private void testRenameReconnect() throws SQLException { - trace("testRenameReconnect"); - deleteDb("cases"); - Connection conn = getConnection("cases"); - conn.createStatement().execute("CREATE TABLE TEST_SEQ(ID INT IDENTITY, NAME VARCHAR(255))"); - conn.createStatement().execute("CREATE TABLE TEST(ID INT PRIMARY KEY)"); - conn.createStatement().execute("ALTER TABLE TEST RENAME TO TEST2"); - conn.createStatement().execute("CREATE TABLE TEST_B(ID INT PRIMARY KEY, NAME VARCHAR, UNIQUE(NAME))"); - conn.close(); - conn = getConnection("cases"); - conn.createStatement().execute("INSERT INTO TEST_SEQ(NAME) VALUES('Hi')"); - ResultSet rs = conn.createStatement().executeQuery("CALL IDENTITY()"); - rs.next(); - assertEquals(1, rs.getInt(1)); - conn.createStatement().execute("SELECT * FROM TEST2"); - conn.createStatement().execute("SELECT * FROM TEST_B"); - conn.createStatement().execute("ALTER TABLE TEST_B RENAME TO TEST_B2"); - conn.close(); - conn = getConnection("cases"); - conn.createStatement().execute("SELECT * FROM TEST_B2"); - conn.createStatement().execute("INSERT INTO TEST_SEQ(NAME) VALUES('World')"); - rs = conn.createStatement().executeQuery("CALL IDENTITY()"); - rs.next(); - assertEquals(2, rs.getInt(1)); - conn.close(); - } - - private void testAllSizes() throws SQLException { - trace("testAllSizes"); - deleteDb("cases"); - Connection conn = getConnection("cases"); - Statement stat = conn.createStatement(); - stat.execute("CREATE TABLE TEST(A INT, B INT, C INT, DATA VARCHAR)"); - int increment = getSize(100, 1); - for (int i = 1; i < 500; i += increment) { - StringBuilder buff = new StringBuilder(); - buff.append("CREATE TABLE TEST"); - for (int j = 0; j < i; j++) { - buff.append('a'); - } - buff.append("(ID INT)"); - String sql = buff.toString(); - stat.execute(sql); - stat.execute("INSERT INTO TEST VALUES(" + i + ", 0, 0, '" + sql + "')"); - } - conn.close(); - conn = getConnection("cases"); - stat = conn.createStatement(); - ResultSet rs = stat.executeQuery("SELECT * FROM TEST"); - while (rs.next()) { - int id = rs.getInt(1); - String s = rs.getString("DATA"); - if (!s.endsWith(")")) { - fail("id=" + id); - } - } - conn.close(); - } - - private void testSelectForUpdate() throws SQLException { - trace("testSelectForUpdate"); - deleteDb("cases"); - Connection conn1 = getConnection("cases"); - Statement stat1 = conn1.createStatement(); - stat1.execute("CREATE TABLE TEST(ID INT)"); - stat1.execute("INSERT INTO TEST VALUES(1)"); - conn1.setAutoCommit(false); - stat1.execute("SELECT * FROM TEST FOR UPDATE"); - Connection conn2 = getConnection("cases"); - Statement stat2 = conn2.createStatement(); - try { - stat2.execute("UPDATE TEST SET ID=2"); - fail(); - } catch (SQLException e) { - assertKnownException(e); - } - conn1.commit(); - stat2.execute("UPDATE TEST SET ID=2"); - conn1.close(); - conn2.close(); - } - - private void testMutableObjects() throws SQLException { - trace("testMutableObjects"); - deleteDb("cases"); - Connection conn = getConnection("cases"); - Statement stat = conn.createStatement(); - stat.execute("CREATE TABLE TEST(ID INT, D DATE, T TIME, TS TIMESTAMP)"); - stat.execute("INSERT INTO TEST VALUES(1, '2001-01-01', '20:00:00', '2002-02-02 22:22:22.2')"); - stat.execute("INSERT INTO TEST VALUES(1, '2001-01-01', '20:00:00', '2002-02-02 22:22:22.2')"); - ResultSet rs = stat.executeQuery("SELECT * FROM TEST"); - rs.next(); - Date d1 = rs.getDate("D"); - Time t1 = rs.getTime("T"); - Timestamp ts1 = rs.getTimestamp("TS"); - rs.next(); - Date d2 = rs.getDate("D"); - Time t2 = rs.getTime("T"); - Timestamp ts2 = rs.getTimestamp("TS"); - assertTrue(ts1 != ts2); - assertTrue(d1 != d2); - assertTrue(t1 != t2); - assertTrue(t2 != rs.getObject("T")); - assertTrue(d2 != rs.getObject("D")); - assertTrue(ts2 != rs.getObject("TS")); - assertFalse(rs.next()); - conn.close(); - } - - private void testCreateDrop() throws SQLException { - trace("testCreateDrop"); - deleteDb("cases"); - Connection conn = getConnection("cases"); - Statement stat = conn.createStatement(); - stat.execute("create table employee(id int, firstName VARCHAR(50), salary decimal(10, 2), " - + "superior_id int, CONSTRAINT PK_employee PRIMARY KEY (id), " - + "CONSTRAINT FK_superior FOREIGN KEY (superior_id) REFERENCES employee(ID))"); - stat.execute("DROP TABLE employee"); - conn.close(); - conn = getConnection("cases"); - conn.close(); - } - - private void testPolePos() throws SQLException { - trace("testPolePos"); - // poleposition-0.20 - - Connection c0 = getConnection("cases"); - c0.createStatement().executeUpdate("SET AUTOCOMMIT FALSE"); - c0.createStatement().executeUpdate( - "create table australia (ID INTEGER NOT NULL, " + - "Name VARCHAR(100), firstName VARCHAR(100), " + - "Points INTEGER, LicenseID INTEGER, PRIMARY KEY(ID))"); - c0.createStatement().executeUpdate("COMMIT"); - c0.close(); - - c0 = getConnection("cases"); - c0.createStatement().executeUpdate("SET AUTOCOMMIT FALSE"); - PreparedStatement p15 = c0.prepareStatement("insert into australia" - + "(id, Name, firstName, Points, LicenseID) values (?, ?, ?, ?, ?)"); - int len = getSize(1, 1000); - for (int i = 0; i < len; i++) { - p15.setInt(1, i); - p15.setString(2, "Pilot_" + i); - p15.setString(3, "Herkules"); - p15.setInt(4, i); - p15.setInt(5, i); - p15.executeUpdate(); - } - c0.createStatement().executeUpdate("COMMIT"); - c0.close(); - - // c0=getConnection("cases"); - // c0.createStatement().executeUpdate("SET AUTOCOMMIT FALSE"); - // c0.createStatement().executeQuery("select * from australia"); - // c0.createStatement().executeQuery("select * from australia"); - // c0.close(); - - // c0=getConnection("cases"); - // c0.createStatement().executeUpdate("SET AUTOCOMMIT FALSE"); - // c0.createStatement().executeUpdate("COMMIT"); - // c0.createStatement().executeUpdate("delete from australia"); - // c0.createStatement().executeUpdate("COMMIT"); - // c0.close(); - - c0 = getConnection("cases"); - c0.createStatement().executeUpdate("SET AUTOCOMMIT FALSE"); - c0.createStatement().executeUpdate("drop table australia"); - c0.createStatement().executeUpdate( - "create table australia (ID INTEGER NOT NULL, Name VARCHAR(100), " - + "firstName VARCHAR(100), Points INTEGER, LicenseID INTEGER, PRIMARY KEY(ID))"); - c0.createStatement().executeUpdate("COMMIT"); - c0.close(); - - c0 = getConnection("cases"); - c0.createStatement().executeUpdate("SET AUTOCOMMIT FALSE"); - PreparedStatement p65 = c0.prepareStatement("insert into australia" - + "(id, Name, FirstName, Points, LicenseID) values (?, ?, ?, ?, ?)"); - len = getSize(1, 1000); - for (int i = 0; i < len; i++) { - p65.setInt(1, i); - p65.setString(2, "Pilot_" + i); - p65.setString(3, "Herkules"); - p65.setInt(4, i); - p65.setInt(5, i); - p65.executeUpdate(); - } - c0.createStatement().executeUpdate("COMMIT"); - c0.createStatement().executeUpdate("COMMIT"); - c0.createStatement().executeUpdate("COMMIT"); - c0.close(); - - c0 = getConnection("cases"); - c0.close(); - } - - private void testQuick() throws SQLException { - trace("testQuick"); - deleteDb("cases"); - - Connection c0 = getConnection("cases"); - c0.createStatement().executeUpdate("create table test (ID int PRIMARY KEY)"); - c0.createStatement().executeUpdate("insert into test values(1)"); - c0.createStatement().executeUpdate("drop table test"); - c0.createStatement().executeUpdate("create table test (ID int PRIMARY KEY)"); - c0.close(); - - c0 = getConnection("cases"); - c0.createStatement().executeUpdate("insert into test values(1)"); - c0.close(); - - c0 = getConnection("cases"); - c0.close(); - } - - private void testOrderByWithSubselect() throws SQLException { - deleteDb("cases"); - - Connection conn = getConnection("cases"); - Statement stat = conn.createStatement(); - stat.execute("create table master(id number primary key, name varchar2(30));"); - stat.execute("create table detail(id number references master(id), location varchar2(30));"); - - stat.execute("Insert into master values(1,'a'), (2,'b'), (3,'c');"); - stat.execute("Insert into detail values(1,'a'), (2,'b'), (3,'c');"); - - ResultSet rs = stat.executeQuery( - "select master.id, master.name " + - "from master " + - "where master.id in (select detail.id from detail) " + - "order by master.id"); - assertTrue(rs.next()); - assertEquals(1, rs.getInt(1)); - assertTrue(rs.next()); - assertEquals(2, rs.getInt(1)); - assertTrue(rs.next()); - assertEquals(3, rs.getInt(1)); - - conn.close(); - } - - private void testDeleteAndDropTableWithLobs(boolean useDrop) throws SQLException { - deleteDb("cases"); - Connection conn = getConnection("cases"); - Statement stat = conn.createStatement(); - stat.execute("CREATE TABLE TEST(id int, content BLOB)"); - stat.execute("set MAX_LENGTH_INPLACE_LOB 1"); - - PreparedStatement prepared = conn.prepareStatement("INSERT INTO TEST VALUES(?, ?)"); - byte[] blobContent = "BLOB_CONTENT".getBytes(); - prepared.setInt(1, 1); - prepared.setBytes(2, blobContent); - prepared.execute(); - - if (useDrop) { - stat.execute("DROP TABLE TEST"); - } else { - stat.execute("DELETE FROM TEST"); - } - - conn.close(); - - String[] list = IOUtils.listFiles(getBaseDir() + "/cases.lobs.db"); - if (list != null && list.length > 0) { - fail("Lob file was not deleted"); - } - } - -} \ No newline at end of file diff --git a/tools/h2/src/test/org/h2/test/db/TestCheckpoint.java b/tools/h2/src/test/org/h2/test/db/TestCheckpoint.java deleted file mode 100755 index aaeb28d..0000000 --- a/tools/h2/src/test/org/h2/test/db/TestCheckpoint.java +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.test.db; - -import java.sql.Connection; -import java.sql.SQLException; -import java.sql.Statement; - -import org.h2.test.TestBase; - -/** - * Tests the CHECKPOINT SQL statement. - */ -public class TestCheckpoint extends TestBase { - - /** - * Run just this test. - * - * @param a ignored - */ - public static void main(String... a) throws Exception { - TestBase.createCaller().init().test(); - } - - public void test() throws SQLException { - // TODO test checkpoint with rollback, not only just run the command - deleteDb("checkpoint"); - Connection c0 = getConnection("checkpoint"); - Statement s0 = c0.createStatement(); - Connection c1 = getConnection("checkpoint"); - Statement s1 = c1.createStatement(); - s1.execute("CREATE TABLE TEST(ID INT PRIMARY KEY, NAME VARCHAR(255))"); - s1.execute("INSERT INTO TEST VALUES(1, 'Hello')"); - s0.execute("CHECKPOINT"); - - s1.execute("INSERT INTO TEST VALUES(2, 'World')"); - c1.setAutoCommit(false); - s1.execute("INSERT INTO TEST VALUES(3, 'Maybe')"); - s0.execute("CHECKPOINT"); - - s1.execute("INSERT INTO TEST VALUES(4, 'Or not')"); - s0.execute("CHECKPOINT"); - - s1.execute("INSERT INTO TEST VALUES(5, 'ok yes')"); - s1.execute("COMMIT"); - s0.execute("CHECKPOINT"); - - c0.close(); - c1.close(); - deleteDb("checkpoint"); - } - -} diff --git a/tools/h2/src/test/org/h2/test/db/TestCluster.java b/tools/h2/src/test/org/h2/test/db/TestCluster.java deleted file mode 100755 index a7c10ac..0000000 --- a/tools/h2/src/test/org/h2/test/db/TestCluster.java +++ /dev/null @@ -1,244 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.test.db; - -import java.sql.Connection; -import java.sql.DriverManager; -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.sql.Statement; - -import org.h2.test.TestBase; -import org.h2.tools.CreateCluster; -import org.h2.tools.DeleteDbFiles; -import org.h2.tools.Server; -import org.h2.util.IOUtils; -import org.h2.util.JdbcUtils; - -/** - * Test for the cluster feature. - */ -public class TestCluster extends TestBase { - - /** - * Run just this test. - * - * @param a ignored - */ - public static void main(String... a) throws Exception { - TestBase.createCaller().init().test(); - } - - public void test() throws Exception { - testCreateClusterAtRuntime(); - testStartStopCluster(); - } - - private void testCreateClusterAtRuntime() throws SQLException { - if (config.memory || config.networked || config.cipher != null) { - return; - } - int port1 = 9191, port2 = 9192; - String serverList = "localhost:" + port1 + ",localhost:" + port2; - deleteFiles(); - - org.h2.Driver.load(); - String user = getUser(), password = getPassword(); - Connection conn; - Statement stat; - String url1 = "jdbc:h2:tcp://localhost:" + port1 + "/test"; - String url2 = "jdbc:h2:tcp://localhost:" + port2 + "/test"; - String urlCluster = "jdbc:h2:tcp://" + serverList + "/test"; - int len = 10; - - // initialize the database - Server n1 = org.h2.tools.Server.createTcpServer("-tcpPort", "" + port1, "-baseDir", getBaseDir() + "/node1").start(); - conn = DriverManager.getConnection(url1, user, password); - stat = conn.createStatement(); - stat.execute("create table test(id int primary key, name varchar) as " + - "select x, 'Data' || x from system_range(0, " + (len - 1) + ")"); - stat.execute("create user test password 'test'"); - stat.execute("grant all on test to test"); - - // start the second server - Server n2 = org.h2.tools.Server.createTcpServer("-tcpPort", "" + port2 , "-baseDir", getBaseDir() + "/node2").start(); - - // copy the database and initialize the cluster - CreateCluster.main("-urlSource", url1, "-urlTarget", url2, "-user", user, "-password", password, "-serverList", - serverList); - - // check the original connection is closed - try { - stat.execute("select * from test"); - fail(); - } catch (SQLException e) { - // expected - JdbcUtils.closeSilently(conn); - } - - // test the cluster connection - Connection connApp = DriverManager.getConnection(urlCluster + ";AUTO_RECONNECT=TRUE", user, password); - check(connApp, len, "'" + serverList + "'"); - - // delete the rows, but don't commit - connApp.setAutoCommit(false); - connApp.createStatement().execute("delete from test"); - - // stop server 2, and test if only one server is available - n2.stop(); - - // rollback the transaction - connApp.createStatement().executeQuery("select count(*) from test"); - connApp.rollback(); - check(connApp, len, "''"); - connApp.setAutoCommit(true); - - // re-create the cluster - n2 = org.h2.tools.Server.createTcpServer("-tcpPort", "" + port2, "-baseDir", getBaseDir() + "/node2").start(); - CreateCluster.main("-urlSource", url1, "-urlTarget", url2, "-user", user, "-password", password, "-serverList", - serverList); - - // test the cluster connection - check(connApp, len, "'" + serverList + "'"); - - // test a non-admin user - String user2 = "test", password2 = getPassword("test"); - connApp = DriverManager.getConnection(urlCluster, user2, password2); - check(connApp, len, "'" + serverList + "'"); - - n1.stop(); - n2.stop(); - deleteFiles(); - } - - private void testStartStopCluster() throws SQLException { - if (config.memory || config.networked || config.cipher != null) { - return; - } - int port1 = 9193, port2 = 9194; - String serverList = "localhost:" + port1 + ",localhost:" + port2; - deleteFiles(); - - // initialize the database - Connection conn; - org.h2.Driver.load(); - - String urlNode1 = getURL("node1/test", true); - String urlNode2 = getURL("node2/test", true); - String user = getUser(), password = getPassword(); - conn = DriverManager.getConnection(urlNode1, user, password); - Statement stat; - stat = conn.createStatement(); - stat.execute("DROP TABLE IF EXISTS TEST"); - stat.execute("CREATE TABLE TEST(ID INT PRIMARY KEY, NAME VARCHAR(255))"); - PreparedStatement prep = conn.prepareStatement("INSERT INTO TEST VALUES(?, ?)"); - int len = getSize(10, 1000); - for (int i = 0; i < len; i++) { - prep.setInt(1, i); - prep.setString(2, "Data" + i); - prep.executeUpdate(); - } - check(conn, len, "''"); - conn.close(); - - // copy the database and initialize the cluster - CreateCluster.main("-urlSource", urlNode1, "-urlTarget", - urlNode2, "-user", user, "-password", password, "-serverList", - serverList); - - // start both servers - Server n1 = org.h2.tools.Server.createTcpServer("-tcpPort", "" + port1, "-baseDir", getBaseDir() + "/node1").start(); - Server n2 = org.h2.tools.Server.createTcpServer("-tcpPort", "" + port2, "-baseDir", getBaseDir() + "/node2").start(); - - // try to connect in standalone mode - should fail - try { - conn = DriverManager.getConnection("jdbc:h2:tcp://localhost:"+port1+"/test", user, password); - fail("should not be able to connect in standalone mode"); - } catch (SQLException e) { - assertKnownException(e); - } - try { - DriverManager.getConnection("jdbc:h2:tcp://localhost:"+port2+"/test", user, password); - fail("should not be able to connect in standalone mode"); - } catch (SQLException e) { - assertKnownException(e); - } - - // test a cluster connection - conn = DriverManager.getConnection("jdbc:h2:tcp://" + serverList + "/test", user, password); - check(conn, len, "'"+serverList+"'"); - conn.close(); - - // stop server 2, and test if only one server is available - n2.stop(); - conn = DriverManager.getConnection("jdbc:h2:tcp://" + serverList + "/test", user, password); - check(conn, len, "''"); - conn.close(); - - // disable the cluster - conn = DriverManager.getConnection("jdbc:h2:tcp://localhost:"+port1+"/test;CLUSTER=''", user, password); - conn.close(); - n1.stop(); - - // re-create the cluster - DeleteDbFiles.main("-dir", getBaseDir() + "/node2", "-quiet"); - CreateCluster.main("-urlSource", urlNode1, "-urlTarget", - urlNode2, "-user", user, "-password", password, "-serverList", - serverList); - n1 = org.h2.tools.Server.createTcpServer("-tcpPort", "" + port1, "-baseDir", getBaseDir() + "/node1").start(); - n2 = org.h2.tools.Server.createTcpServer("-tcpPort", "" + port2, "-baseDir", getBaseDir() + "/node2").start(); - - conn = DriverManager.getConnection("jdbc:h2:tcp://" + serverList + "/test", user, password); - stat = conn.createStatement(); - stat.execute("CREATE TABLE BOTH(ID INT)"); - - n1.stop(); - - stat.execute("CREATE TABLE A(ID INT)"); - conn.close(); - n2.stop(); - - n1 = org.h2.tools.Server.createTcpServer("-tcpPort", "" + port1, "-baseDir", getBaseDir() + "/node1").start(); - conn = DriverManager.getConnection("jdbc:h2:tcp://localhost:"+port1+"/test;CLUSTER=''", user, password); - check(conn, len, "''"); - conn.close(); - n1.stop(); - - n2 = org.h2.tools.Server.createTcpServer("-tcpPort", "" + port2, "-baseDir", getBaseDir() + "/node2").start(); - conn = DriverManager.getConnection("jdbc:h2:tcp://localhost:" + port2 + "/test;CLUSTER=''", user, password); - check(conn, len, "''"); - conn.createStatement().execute("SELECT * FROM A"); - conn.close(); - n2.stop(); - deleteFiles(); - } - - private void deleteFiles() throws SQLException { - DeleteDbFiles.main("-dir", getBaseDir() + "/node1", "-quiet"); - DeleteDbFiles.main("-dir", getBaseDir() + "/node2", "-quiet"); - IOUtils.delete(getBaseDir() + "/node1"); - IOUtils.delete(getBaseDir() + "/node2"); - } - - private void check(Connection conn, int len, String expectedCluster) throws SQLException { - PreparedStatement prep = conn.prepareStatement("SELECT * FROM TEST WHERE ID=?"); - for (int i = 0; i < len; i++) { - prep.setInt(1, i); - ResultSet rs = prep.executeQuery(); - rs.next(); - assertEquals("Data" + i, rs.getString(2)); - assertFalse(rs.next()); - } - ResultSet rs = conn.createStatement().executeQuery( - "SELECT VALUE FROM INFORMATION_SCHEMA.SETTINGS WHERE NAME='CLUSTER'"); - rs.next(); - String cluster = rs.getString(1); - assertEquals(expectedCluster, cluster); - } - -} diff --git a/tools/h2/src/test/org/h2/test/db/TestCompatibility.java b/tools/h2/src/test/org/h2/test/db/TestCompatibility.java deleted file mode 100755 index ff607da..0000000 --- a/tools/h2/src/test/org/h2/test/db/TestCompatibility.java +++ /dev/null @@ -1,211 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.test.db; - -import java.sql.Connection; -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.ResultSetMetaData; -import java.sql.SQLException; -import java.sql.Statement; -import org.h2.test.TestBase; - -/** - * Tests the compatibility with other databases. - */ -public class TestCompatibility extends TestBase { - - private Connection conn; - - /** - * Run just this test. - * - * @param a ignored - */ - public static void main(String... a) throws Exception { - TestBase.createCaller().init().test(); - } - - public void test() throws SQLException { - deleteDb("compatibility"); - - conn = getConnection("compatibility"); - testDomain(); - testColumnAlias(); - testUniqueIndexSingleNull(); - testUniqueIndexOracle(); - testHsqlDb(); - testMySQL(); - testPlusSignAsConcatOperator(); - - conn.close(); - deleteDb("compatibility"); - } - - private void testDomain() throws SQLException { - if (config.memory) { - return; - } - Statement stat = conn.createStatement(); - stat.execute("create table test(id int primary key) as select 1"); - try { - stat.execute("create domain int as varchar"); - fail(); - } catch (SQLException e) { - assertKnownException(e); - } - conn.close(); - conn = getConnection("compatibility"); - stat = conn.createStatement(); - stat.execute("insert into test values(2)"); - stat.execute("drop table test"); - } - - private void testColumnAlias() throws SQLException { - Statement stat = conn.createStatement(); - String[] modes = { "PostgreSQL", "MySQL", "HSQLDB", "MSSQLServer", "Derby", "Oracle", "Regular" }; - String columnAlias; - columnAlias = "MySQL,Regular"; - stat.execute("CREATE TABLE TEST(ID INT)"); - for (String mode : modes) { - stat.execute("SET MODE " + mode); - ResultSet rs = stat.executeQuery("SELECT ID I FROM TEST"); - ResultSetMetaData meta = rs.getMetaData(); - String columnName = meta.getColumnName(1); - String tableName = meta.getTableName(1); - if ("ID".equals(columnName) && "TEST".equals(tableName)) { - assertTrue(mode + " mode should not support columnAlias", columnAlias.indexOf(mode) >= 0); - } else if ("I".equals(columnName) && tableName == null) { - assertTrue(mode + " mode should support columnAlias", columnAlias.indexOf(mode) < 0); - } else { - fail(); - } - } - stat.execute("DROP TABLE TEST"); - } - - private void testUniqueIndexSingleNull() throws SQLException { - Statement stat = conn.createStatement(); - String[] modes = { "PostgreSQL", "MySQL", "HSQLDB", "MSSQLServer", "Derby", "Oracle", "Regular" }; - String multiNull = "PostgreSQL,MySQL,Oracle,Regular"; - for (String mode : modes) { - stat.execute("SET MODE " + mode); - stat.execute("CREATE TABLE TEST(ID INT)"); - stat.execute("CREATE UNIQUE INDEX IDX_ID_U ON TEST(ID)"); - try { - stat.execute("INSERT INTO TEST VALUES(1), (2), (NULL), (NULL)"); - assertTrue(mode + " mode should not support multiple NULL", multiNull.indexOf(mode) >= 0); - } catch (SQLException e) { - assertTrue(mode + " mode should support multiple NULL", multiNull.indexOf(mode) < 0); - } - stat.execute("DROP TABLE TEST"); - } - } - - private void testUniqueIndexOracle() throws SQLException { - Statement stat = conn.createStatement(); - stat.execute("SET MODE ORACLE"); - stat.execute("create table t2(c1 int, c2 int)"); - stat.execute("create unique index i2 on t2(c1, c2)"); - stat.execute("insert into t2 values (null, 1)"); - try { - stat.execute("insert into t2 values (null, 1)"); - fail(); - } catch (SQLException e) { - assertKnownException(e); - } - stat.execute("insert into t2 values (null, null)"); - stat.execute("insert into t2 values (null, null)"); - stat.execute("insert into t2 values (1, null)"); - try { - stat.execute("insert into t2 values (1, null)"); - fail(); - } catch (SQLException e) { - assertKnownException(e); - } - stat.execute("DROP TABLE T2"); - } - - private void testHsqlDb() throws SQLException { - Statement stat = conn.createStatement(); - stat.execute("DROP TABLE TEST IF EXISTS; CREATE TABLE TEST(ID INT PRIMARY KEY); "); - stat.execute("CALL CURRENT_TIME"); - stat.execute("CALL CURRENT_TIMESTAMP"); - stat.execute("CALL CURRENT_DATE"); - stat.execute("CALL SYSDATE"); - stat.execute("CALL TODAY"); - - stat.execute("DROP TABLE TEST IF EXISTS"); - stat.execute("CREATE TABLE TEST(ID INT)"); - stat.execute("INSERT INTO TEST VALUES(1)"); - PreparedStatement prep = conn.prepareStatement("SELECT LIMIT ? 1 ID FROM TEST"); - prep.setInt(1, 2); - prep.executeQuery(); - stat.execute("DROP TABLE TEST IF EXISTS"); - - } - - private void testMySQL() throws SQLException { - Statement stat = conn.createStatement(); - stat.execute("SELECT 1"); - stat.execute("DROP TABLE IF EXISTS TEST"); - stat.execute("CREATE TABLE TEST(ID INT, NAME VARCHAR)"); - stat.execute("INSERT INTO TEST VALUES(1, 'Hello'), (2, 'World')"); - org.h2.mode.FunctionsMySQL.register(conn); - assertResult("1196418619", stat, "SELECT UNIX_TIMESTAMP('2007-11-30 10:30:19Z')"); - assertResult("1196418619", stat, "SELECT UNIX_TIMESTAMP(FROM_UNIXTIME(1196418619))"); - assertResult("2007 November", stat, "SELECT FROM_UNIXTIME(1196300000, '%Y %M')"); - assertResult("2003-12-31", stat, "SELECT DATE('2003-12-31 11:02:03')"); - - } - - private void testPlusSignAsConcatOperator() throws SQLException { - Statement stat = conn.createStatement(); - stat.execute("SET MODE MSSQLServer"); - stat.execute("DROP TABLE IF EXISTS TEST"); - stat.execute("CREATE TABLE TEST(NAME VARCHAR(50), SURNAME VARCHAR(50))"); - stat.execute("INSERT INTO TEST VALUES('John', 'Doe')"); - stat.execute("INSERT INTO TEST VALUES('Jack', 'Sullivan')"); - - assertResult("abcd123", stat, "SELECT 'abc' + 'd123'"); - - assertResult("Doe, John", stat, - "SELECT surname + ', ' + name FROM test WHERE SUBSTRING(NAME,1,1)+SUBSTRING(SURNAME,1,1) = 'JD'"); - - stat.execute("ALTER TABLE TEST ADD COLUMN full_name VARCHAR(100)"); - stat.execute("UPDATE TEST SET full_name = name + ', ' + surname"); - assertResult("John, Doe", stat, "SELECT full_name FROM TEST where name='John'"); - - PreparedStatement prep = conn.prepareStatement("INSERT INTO TEST VALUES(?, ?, ? + ', ' + ?)"); - int ca = 1; - prep.setString(ca++, "Paul"); - prep.setString(ca++, "Frank"); - prep.setString(ca++, "Paul"); - prep.setString(ca++, "Frank"); - prep.executeUpdate(); - prep.close(); - - assertResult("Paul, Frank", stat, "SELECT full_name FROM test WHERE name = 'Paul'"); - - prep = conn.prepareStatement("SELECT ? + ?"); - int cb = 1; - prep.setString(cb++, "abcd123"); - prep.setString(cb++, "d123"); - prep.executeQuery(); - prep.close(); - - prep = conn.prepareStatement("SELECT full_name FROM test WHERE (SUBSTRING(name, 1, 1) + SUBSTRING(surname, 2, 3)) = ?"); - prep.setString(1, "Joe"); - ResultSet res = prep.executeQuery(); - assertTrue("Result cannot be empty", res.next()); - assertEquals("John, Doe", res.getString(1)); - res.close(); - prep.close(); - - } - -} diff --git a/tools/h2/src/test/org/h2/test/db/TestConnectionInfo.java b/tools/h2/src/test/org/h2/test/db/TestConnectionInfo.java deleted file mode 100755 index 57d0a4e..0000000 --- a/tools/h2/src/test/org/h2/test/db/TestConnectionInfo.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.test.db; - -import org.h2.test.TestBase; -import org.h2.engine.ConnectionInfo; - -import java.util.Properties; - -/** - * Test the ConnectionInfo class. - * - * @author Kerry Sainsbury - */ -public class TestConnectionInfo extends TestBase { - - /** - * Run just this test. - * - * @param a ignored - */ - public static void main(String[] a) throws Exception { - TestBase.createCaller().init().test(); - } - - public void test() throws Exception { - Properties info = new Properties(); - ConnectionInfo connectionInfo = new ConnectionInfo( - "jdbc:h2:mem:testdb" + - ";LOG=2" + - ";ACCESS_MODE_DATA=rws" + - ";INIT=CREATE this...\\;INSERT that..." + - ";IFEXISTS=TRUE", - info); - - assertEquals("jdbc:h2:mem:testdb", connectionInfo.getURL()); - - assertEquals("2", connectionInfo.getProperty("LOG", "")); - assertEquals("rws", connectionInfo.getProperty("ACCESS_MODE_DATA", "")); - assertEquals("CREATE this...;INSERT that...", connectionInfo.getProperty("INIT", "")); - assertEquals("TRUE", connectionInfo.getProperty("IFEXISTS", "")); - assertEquals("undefined", connectionInfo.getProperty("CACHE_TYPE", "undefined")); - } - -} diff --git a/tools/h2/src/test/org/h2/test/db/TestCsv.java b/tools/h2/src/test/org/h2/test/db/TestCsv.java deleted file mode 100755 index 45188b0..0000000 --- a/tools/h2/src/test/org/h2/test/db/TestCsv.java +++ /dev/null @@ -1,388 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.test.db; - -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.File; -import java.io.InputStreamReader; -import java.io.Reader; -import java.io.StringReader; -import java.sql.Connection; -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.ResultSetMetaData; -import java.sql.SQLException; -import java.sql.Statement; -import java.util.ArrayList; -import java.util.Random; -import org.h2.store.fs.FileObject; -import org.h2.store.fs.FileSystem; -import org.h2.test.TestBase; -import org.h2.tools.Csv; -import org.h2.util.IOUtils; -import org.h2.util.New; -import org.h2.util.StringUtils; -import org.h2.util.Utils; - -/** - * CSVREAD and CSVWRITE tests. - * - * @author Thomas Mueller - * @author Sylvain Cuaz (testNull) - * - */ -public class TestCsv extends TestBase { - - /** - * Run just this test. - * - * @param a ignored - */ - public static void main(String... a) throws Exception { - TestBase test = TestBase.createCaller().init(); - test.config.traceTest = true; - test.test(); - } - - public void test() throws Exception { - testPseudoBom(); - testWriteRead(); - testColumnNames(); - testSpaceSeparated(); - testNull(); - testRandomData(); - testEmptyFieldDelimiter(); - testFieldDelimiter(); - testAsTable(); - testRead(); - testPipe(); - deleteDb("csv"); - } - - private void testPseudoBom() throws Exception { - ByteArrayOutputStream out = new ByteArrayOutputStream(); - // UTF-8 "BOM" / marker - out.write(Utils.convertStringToBytes("ef" + "bb" + "bf")); - out.write("\"ID\", \"NAME\"\n1, Hello".getBytes("UTF-8")); - byte[] buff = out.toByteArray(); - Reader r = new InputStreamReader(new ByteArrayInputStream(buff), "UTF-8"); - ResultSet rs = Csv.getInstance().read(r, null); - assertEquals("ID", rs.getMetaData().getColumnLabel(1)); - assertEquals("NAME", rs.getMetaData().getColumnLabel(2)); - assertTrue(rs.next()); - assertEquals(1, rs.getInt(1)); - assertEquals("Hello", rs.getString(2)); - assertFalse(rs.next()); - } - - private void testColumnNames() throws Exception { - ResultSet rs; - rs = Csv.getInstance().read(new StringReader("Id,First Name,2x,_x2\n1,2,3"), null); - assertEquals("ID", rs.getMetaData().getColumnName(1)); - assertEquals("First Name", rs.getMetaData().getColumnName(2)); - assertEquals("2x", rs.getMetaData().getColumnName(3)); - assertEquals("_X2", rs.getMetaData().getColumnName(4)); - } - - private void testSpaceSeparated() throws SQLException { - deleteDb("csv"); - File f = new File(getBaseDir() + "/testSpace.csv"); - IOUtils.delete(f.getAbsolutePath()); - - Connection conn = getConnection("csv"); - Statement stat = conn.createStatement(); - stat.execute("create temporary table test (a int, b int, c int)"); - stat.execute("insert into test values(1,2,3)"); - stat.execute("insert into test values(4,null,5)"); - stat.execute("call csvwrite('"+getBaseDir()+"/test.tsv','select * from test',null,' ')"); - ResultSet rs1 = stat.executeQuery("select * from test"); - assertResultSetOrdered(rs1, new String[][]{new String[]{"1", "2", "3"}, new String[]{"4", null, "5"}}); - ResultSet rs2 = stat.executeQuery("select * from csvread('"+getBaseDir()+"/test.tsv',null,null,' ')"); - assertResultSetOrdered(rs2, new String[][]{new String[]{"1", "2", "3"}, new String[]{"4", null, "5"}}); - conn.close(); - IOUtils.delete(f.getAbsolutePath()); - IOUtils.delete(getBaseDir() + "/test.tsv"); - } - - /** - * Test custom NULL string. - */ - private void testNull() throws Exception { - deleteDb("csv"); - - String fileName = getBaseDir() + "/testNull.csv"; - FileSystem fs = FileSystem.getInstance(fileName); - fs.delete(fileName); - - FileObject file = fs.openFileObject(fileName, "rw"); - String csvContent = "\"A\",\"B\",\"C\",\"D\"\n\\N,\"\",\"\\N\","; - byte[] b = csvContent.getBytes("UTF-8"); - file.write(b, 0, b.length); - file.close(); - Csv csv = Csv.getInstance(); - csv.setNullString("\\N"); - ResultSet rs = csv.read(file.getName(), null, "UTF8"); - ResultSetMetaData meta = rs.getMetaData(); - assertEquals(4, meta.getColumnCount()); - assertEquals("A", meta.getColumnLabel(1)); - assertEquals("B", meta.getColumnLabel(2)); - assertEquals("C", meta.getColumnLabel(3)); - assertEquals("D", meta.getColumnLabel(4)); - assertTrue(rs.next()); - assertEquals(null, rs.getString(1)); - assertEquals("", rs.getString(2)); - // null is never quoted - assertEquals("\\N", rs.getString(3)); - // an empty string is always parsed as null - assertEquals(null, rs.getString(4)); - assertFalse(rs.next()); - - Connection conn = getConnection("csv"); - Statement stat = conn.createStatement(); - stat.execute("call csvwrite('" + file.getName() + "', 'select NULL as a, '''' as b, ''\\N'' as c, NULL as d', 'UTF8', ',', '\"', NULL, '\\N', '\n')"); - InputStreamReader reader = new InputStreamReader(fs.openFileInputStream(fileName)); - // on read, an empty string is treated like null, - // but on write a null is always written with the nullString - String data = IOUtils.readStringAndClose(reader, -1); - assertEquals(csvContent + "\\N", data.trim()); - conn.close(); - - fs.delete(fileName); - } - - private void testRandomData() throws SQLException { - deleteDb("csv"); - Connection conn = getConnection("csv"); - Statement stat = conn.createStatement(); - stat.execute("drop table if exists test"); - stat.execute("create table test(a varchar, b varchar)"); - int len = getSize(1000, 10000); - PreparedStatement prep = conn.prepareStatement("insert into test values(?, ?)"); - ArrayList list = New.arrayList(); - Random random = new Random(1); - for (int i = 0; i < len; i++) { - String a = randomData(random), b = randomData(random); - prep.setString(1, a); - prep.setString(2, b); - list.add(new String[]{a, b}); - prep.execute(); - } - stat.execute("CALL CSVWRITE('" + getBaseDir() + "/test.csv', 'SELECT * FROM test', 'UTF-8', '|', '#')"); - Csv csv = Csv.getInstance(); - csv.setFieldSeparatorRead('|'); - csv.setFieldDelimiter('#'); - ResultSet rs = csv.read(getBaseDir() + "/test.csv", null, "UTF-8"); - for (int i = 0; i < len; i++) { - assertTrue(rs.next()); - String[] pair = list.get(i); - assertEquals(pair[0], rs.getString(1)); - assertEquals(pair[1], rs.getString(2)); - } - assertFalse(rs.next()); - conn.close(); - IOUtils.delete(getBaseDir() + "/test.csv"); - } - - private String randomData(Random random) { - if (random.nextInt(10) == 1) { - return null; - } - int len = random.nextInt(5); - StringBuilder buff = new StringBuilder(); - String chars = "\\\'\",\r\n\t ;.-123456|#"; - for (int i = 0; i < len; i++) { - buff.append(chars.charAt(random.nextInt(chars.length()))); - } - return buff.toString(); - } - - private void testEmptyFieldDelimiter() throws Exception { - String fileName = getBaseDir() + "/test.csv"; - IOUtils.delete(fileName); - Connection conn = getConnection("csv"); - Statement stat = conn.createStatement(); - stat.execute("call csvwrite('"+fileName+"', 'select 1 id, ''Hello'' name', null, '|', '', null, null, chr(10))"); - InputStreamReader reader = new InputStreamReader(IOUtils.openFileInputStream(fileName)); - String text = IOUtils.readStringAndClose(reader, -1).trim(); - text = StringUtils.replaceAll(text, "\n", " "); - assertEquals("ID|NAME 1|Hello", text); - ResultSet rs = stat.executeQuery("select * from csvread('" + fileName + "', null, null, '|', '')"); - ResultSetMetaData meta = rs.getMetaData(); - assertEquals(2, meta.getColumnCount()); - assertEquals("ID", meta.getColumnLabel(1)); - assertEquals("NAME", meta.getColumnLabel(2)); - assertTrue(rs.next()); - assertEquals("1", rs.getString(1)); - assertEquals("Hello", rs.getString(2)); - assertFalse(rs.next()); - conn.close(); - IOUtils.delete(fileName); - } - - private void testFieldDelimiter() throws Exception { - String fileName = getBaseDir() + "/test.csv"; - String fileName2 = getBaseDir() + "/test2.csv"; - FileSystem fs = FileSystem.getInstance(fileName); - fs.delete(fileName); - FileObject file = fs.openFileObject(fileName, "rw"); - byte[] b = "'A'; 'B'\n\'It\\'s nice\'; '\nHello\\*\n'".getBytes(); - file.write(b, 0, b.length); - file.close(); - Connection conn = getConnection("csv"); - Statement stat = conn.createStatement(); - ResultSet rs = stat.executeQuery("select * from csvread('" + fileName + "', null, null, ';', '''', '\\')"); - ResultSetMetaData meta = rs.getMetaData(); - assertEquals(2, meta.getColumnCount()); - assertEquals("A", meta.getColumnLabel(1)); - assertEquals("B", meta.getColumnLabel(2)); - assertTrue(rs.next()); - assertEquals("It's nice", rs.getString(1)); - assertEquals("\nHello*\n", rs.getString(2)); - assertFalse(rs.next()); - stat.execute("call csvwrite('" + fileName2 + "', 'select * from csvread(''" + fileName + "'', null, null, '';'', '''''''', ''\\'')', null, '+', '*', '#')"); - rs = stat.executeQuery("select * from csvread('" + fileName2 + "', null, null, '+', '*', '#')"); - meta = rs.getMetaData(); - assertEquals(2, meta.getColumnCount()); - assertEquals("A", meta.getColumnLabel(1)); - assertEquals("B", meta.getColumnLabel(2)); - assertTrue(rs.next()); - assertEquals("It's nice", rs.getString(1)); - assertEquals("\nHello*\n", rs.getString(2)); - assertFalse(rs.next()); - conn.close(); - fs.delete(fileName); - fs.delete(fileName2); - } - - private void testPipe() throws SQLException { - deleteDb("csv"); - Connection conn = getConnection("csv"); - Statement stat = conn.createStatement(); - stat.execute("call csvwrite('" + getBaseDir() + "/test.csv', 'select 1 id, ''Hello'' name', 'utf-8', '|')"); - ResultSet rs = stat.executeQuery("select * from csvread('" + getBaseDir() + "/test.csv', null, 'utf-8', '|')"); - assertTrue(rs.next()); - assertEquals(1, rs.getInt(1)); - assertEquals("Hello", rs.getString(2)); - assertFalse(rs.next()); - new File(getBaseDir() + "/test.csv").delete(); - - // PreparedStatement prep = conn.prepareStatement("select * from - // csvread(?, null, ?, ?)"); - // prep.setString(1, BASE_DIR+"/test.csv"); - // prep.setString(2, "utf-8"); - // prep.setString(3, "|"); - // rs = prep.executeQuery(); - - conn.close(); - IOUtils.delete(getBaseDir() + "/test.csv"); - } - - private void testAsTable() throws SQLException { - deleteDb("csv"); - Connection conn = getConnection("csv"); - Statement stat = conn.createStatement(); - stat.execute("call csvwrite('" + getBaseDir() + "/test.csv', 'select 1 id, ''Hello'' name')"); - ResultSet rs = stat.executeQuery("select name from csvread('" + getBaseDir() + "/test.csv')"); - assertTrue(rs.next()); - assertEquals("Hello", rs.getString(1)); - assertFalse(rs.next()); - rs = stat.executeQuery("call csvread('" + getBaseDir() + "/test.csv')"); - assertTrue(rs.next()); - assertEquals(1, rs.getInt(1)); - assertEquals("Hello", rs.getString(2)); - assertFalse(rs.next()); - new File(getBaseDir() + "/test.csv").delete(); - conn.close(); - } - - private void testRead() throws Exception { - String fileName = getBaseDir() + "/test.csv"; - FileSystem fs = FileSystem.getInstance(fileName); - fs.delete(fileName); - FileObject file = fs.openFileObject(fileName, "rw"); - byte[] b = "a,b,c,d\n201,-2,0,18\n, \"abc\"\"\" ,,\"\"\n 1 ,2 , 3, 4 \n5, 6, 7, 8".getBytes(); - file.write(b, 0, b.length); - file.close(); - ResultSet rs = Csv.getInstance().read(fileName, null, "UTF8"); - ResultSetMetaData meta = rs.getMetaData(); - assertEquals(4, meta.getColumnCount()); - assertEquals("A", meta.getColumnLabel(1)); - assertEquals("B", meta.getColumnLabel(2)); - assertEquals("C", meta.getColumnLabel(3)); - assertEquals("D", meta.getColumnLabel(4)); - assertTrue(rs.next()); - assertEquals("201", rs.getString(1)); - assertEquals("-2", rs.getString(2)); - assertEquals("0", rs.getString(3)); - assertEquals("18", rs.getString(4)); - assertTrue(rs.next()); - assertEquals(null, rs.getString(1)); - assertEquals("abc\"", rs.getString(2)); - assertEquals(null, rs.getString(3)); - assertEquals("", rs.getString(4)); - assertTrue(rs.next()); - assertEquals("1", rs.getString(1)); - assertEquals("2", rs.getString(2)); - assertEquals("3", rs.getString(3)); - assertEquals("4", rs.getString(4)); - assertTrue(rs.next()); - assertEquals("5", rs.getString(1)); - assertEquals("6", rs.getString(2)); - assertEquals("7", rs.getString(3)); - assertEquals("8", rs.getString(4)); - assertFalse(rs.next()); - - // a,b,c,d - // 201,-2,0,18 - // 201,2,0,18 - // 201,2,0,18 - // 201,2,0,18 - // 201,2,0,18 - // 201,2,0,18 - fs.delete(fileName); - } - - private void testWriteRead() throws SQLException { - deleteDb("csv"); - Connection conn = getConnection("csv"); - Statement stat = conn.createStatement(); - stat.execute("CREATE TABLE TEST(ID IDENTITY, NAME VARCHAR)"); - // int len = 100000; - int len = 100; - for (int i = 0; i < len; i++) { - stat.execute("INSERT INTO TEST(NAME) VALUES('Ruebezahl')"); - } - long time; - time = System.currentTimeMillis(); - Csv.getInstance().write(conn, getBaseDir() + "/testRW.csv", "SELECT X ID, 'Ruebezahl' NAME FROM SYSTEM_RANGE(1, " + len + ")", "UTF8"); - trace("write: " + (System.currentTimeMillis() - time)); - ResultSet rs; - time = System.currentTimeMillis(); - for (int i = 0; i < 30; i++) { - rs = Csv.getInstance().read(getBaseDir() + "/testRW.csv", null, "UTF8"); - while (rs.next()) { - // ignore - } - } - trace("read: " + (System.currentTimeMillis() - time)); - rs = Csv.getInstance().read(getBaseDir() + "/testRW.csv", null, "UTF8"); - // stat.execute("CREATE ALIAS CSVREAD FOR \"org.h2.tools.Csv.read\""); - ResultSetMetaData meta = rs.getMetaData(); - assertEquals(2, meta.getColumnCount()); - for (int i = 0; i < len; i++) { - rs.next(); - assertEquals("" + (i + 1), rs.getString("ID")); - assertEquals("Ruebezahl", rs.getString("NAME")); - } - assertFalse(rs.next()); - rs.close(); - conn.close(); - IOUtils.delete(getBaseDir() + "/testRW.csv"); - } - -} diff --git a/tools/h2/src/test/org/h2/test/db/TestDeadlock.java b/tools/h2/src/test/org/h2/test/db/TestDeadlock.java deleted file mode 100755 index ed01497..0000000 --- a/tools/h2/src/test/org/h2/test/db/TestDeadlock.java +++ /dev/null @@ -1,312 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.test.db; - -import java.sql.Connection; -import java.sql.SQLException; - -import org.h2.constant.ErrorCode; -import org.h2.test.TestBase; - -/** - * Test the deadlock detection mechanism. - */ -public class TestDeadlock extends TestBase { - - /** - * The first connection. - */ - Connection c1; - - /** - * The second connection. - */ - Connection c2; - - /** - * The third connection. - */ - Connection c3; - private volatile SQLException lastException; - - /** - * Run just this test. - * - * @param a ignored - */ - public static void main(String... a) throws Exception { - TestBase.createCaller().init().test(); - } - - public void test() throws Exception { - deleteDb("deadlock"); - testDiningPhilosophers(); - testLockUpgrade(); - testThreePhilosophers(); - testNoDeadlock(); - testThreeSome(); - deleteDb("deadlock"); - } - - private void initTest() throws SQLException { - c1 = getConnection("deadlock"); - c2 = getConnection("deadlock"); - c3 = getConnection("deadlock"); - c1.createStatement().execute("SET LOCK_TIMEOUT 1000"); - c2.createStatement().execute("SET LOCK_TIMEOUT 1000"); - c3.createStatement().execute("SET LOCK_TIMEOUT 1000"); - c1.setAutoCommit(false); - c2.setAutoCommit(false); - c3.setAutoCommit(false); - lastException = null; - } - - private void end() throws SQLException { - c1.close(); - c2.close(); - c3.close(); - } - - /** - * This class wraps exception handling to simplify creating small threads - * that execute a statement. - */ - abstract class DoIt extends Thread { - - /** - * The operation to execute. - */ - abstract void execute() throws SQLException; - - public void run() { - try { - execute(); - } catch (SQLException e) { - catchDeadlock(e); - } - } - } - - /** - * Add the exception to the list of exceptions. - * - * @param e the exception - */ - void catchDeadlock(SQLException e) { - if (lastException != null) { - lastException.setNextException(e); - } else { - lastException = e; - } - } - - private void testNoDeadlock() throws Exception { - initTest(); - c1.createStatement().execute("CREATE TABLE TEST_A(ID INT PRIMARY KEY)"); - c1.createStatement().execute("CREATE TABLE TEST_B(ID INT PRIMARY KEY)"); - c1.createStatement().execute("CREATE TABLE TEST_C(ID INT PRIMARY KEY)"); - c1.commit(); - c1.createStatement().execute("INSERT INTO TEST_A VALUES(1)"); - c2.createStatement().execute("INSERT INTO TEST_B VALUES(1)"); - c3.createStatement().execute("INSERT INTO TEST_C VALUES(1)"); - DoIt t2 = new DoIt() { - public void execute() throws SQLException { - c1.createStatement().execute("DELETE FROM TEST_B"); - c1.commit(); - } - }; - t2.start(); - DoIt t3 = new DoIt() { - public void execute() throws SQLException { - c2.createStatement().execute("DELETE FROM TEST_C"); - c2.commit(); - } - }; - t3.start(); - Thread.sleep(500); - try { - c3.createStatement().execute("DELETE FROM TEST_C"); - c3.commit(); - } catch (SQLException e) { - catchDeadlock(e); - } - t2.join(); - t3.join(); - if (lastException != null) { - throw lastException; - } - c1.commit(); - c2.commit(); - c3.commit(); - c1.createStatement().execute("DROP TABLE TEST_A, TEST_B, TEST_C"); - end(); - - } - - private void testThreePhilosophers() throws Exception { - if (config.mvcc) { - return; - } - initTest(); - c1.createStatement().execute("CREATE TABLE TEST_A(ID INT PRIMARY KEY)"); - c1.createStatement().execute("CREATE TABLE TEST_B(ID INT PRIMARY KEY)"); - c1.createStatement().execute("CREATE TABLE TEST_C(ID INT PRIMARY KEY)"); - c1.commit(); - c1.createStatement().execute("INSERT INTO TEST_A VALUES(1)"); - c2.createStatement().execute("INSERT INTO TEST_B VALUES(1)"); - c3.createStatement().execute("INSERT INTO TEST_C VALUES(1)"); - DoIt t2 = new DoIt() { - public void execute() throws SQLException { - c1.createStatement().execute("DELETE FROM TEST_B"); - c1.commit(); - } - }; - t2.start(); - DoIt t3 = new DoIt() { - public void execute() throws SQLException { - c2.createStatement().execute("DELETE FROM TEST_C"); - c2.commit(); - } - }; - t3.start(); - try { - c3.createStatement().execute("DELETE FROM TEST_A"); - c3.commit(); - } catch (SQLException e) { - catchDeadlock(e); - } - t2.join(); - t3.join(); - checkDeadlock(); - c1.commit(); - c2.commit(); - c3.commit(); - c1.createStatement().execute("DROP TABLE TEST_A, TEST_B, TEST_C"); - end(); - } - - // test case for issue # 61 - // http://code.google.com/p/h2database/issues/detail?id=61) - private void testThreeSome() throws Exception { - if (config.mvcc) { - return; - } - initTest(); - c1.createStatement().execute("CREATE TABLE TEST_A(ID INT PRIMARY KEY)"); - c1.createStatement().execute("CREATE TABLE TEST_B(ID INT PRIMARY KEY)"); - c1.createStatement().execute("CREATE TABLE TEST_C(ID INT PRIMARY KEY)"); - c1.commit(); - c1.createStatement().execute("INSERT INTO TEST_A VALUES(1)"); - c1.createStatement().execute("INSERT INTO TEST_B VALUES(1)"); - c2.createStatement().execute("INSERT INTO TEST_C VALUES(1)"); - DoIt t2 = new DoIt() { - public void execute() throws SQLException { - c3.createStatement().execute("INSERT INTO TEST_B VALUES(2)"); - c3.commit(); - } - }; - t2.start(); - DoIt t3 = new DoIt() { - public void execute() throws SQLException { - c2.createStatement().execute("INSERT INTO TEST_A VALUES(2)"); - c2.commit(); - } - }; - t3.start(); - try { - c1.createStatement().execute("INSERT INTO TEST_C VALUES(2)"); - c1.commit(); - } catch (SQLException e) { - catchDeadlock(e); - c1.rollback(); - } - t2.join(); - t3.join(); - checkDeadlock(); - c1.commit(); - c2.commit(); - c3.commit(); - c1.createStatement().execute("DROP TABLE TEST_A, TEST_B, TEST_C"); - end(); - } - - private void testLockUpgrade() throws Exception { - if (config.mvcc) { - return; - } - initTest(); - c1.createStatement().execute("CREATE TABLE TEST(ID INT PRIMARY KEY)"); - c1.createStatement().execute("INSERT INTO TEST VALUES(1)"); - c1.commit(); - c1.setTransactionIsolation(Connection.TRANSACTION_SERIALIZABLE); - c2.setTransactionIsolation(Connection.TRANSACTION_SERIALIZABLE); - c1.createStatement().executeQuery("SELECT * FROM TEST"); - c2.createStatement().executeQuery("SELECT * FROM TEST"); - Thread t1 = new DoIt() { - public void execute() throws SQLException { - c1.createStatement().execute("DELETE FROM TEST"); - c1.commit(); - } - }; - t1.start(); - try { - c2.createStatement().execute("DELETE FROM TEST"); - c2.commit(); - } catch (SQLException e) { - catchDeadlock(e); - } - t1.join(); - checkDeadlock(); - c1.commit(); - c2.commit(); - c1.createStatement().execute("DROP TABLE TEST"); - end(); - } - - private void testDiningPhilosophers() throws Exception { - if (config.mvcc) { - return; - } - initTest(); - c1.createStatement().execute("CREATE TABLE T1(ID INT)"); - c1.createStatement().execute("CREATE TABLE T2(ID INT)"); - c1.createStatement().execute("INSERT INTO T1 VALUES(1)"); - c2.createStatement().execute("INSERT INTO T2 VALUES(1)"); - DoIt t1 = new DoIt() { - public void execute() throws SQLException { - c1.createStatement().execute("INSERT INTO T2 VALUES(2)"); - c1.commit(); - } - }; - t1.start(); - try { - c2.createStatement().execute("INSERT INTO T1 VALUES(2)"); - } catch (SQLException e) { - catchDeadlock(e); - } - t1.join(); - checkDeadlock(); - c1.commit(); - c2.commit(); - c1.createStatement().execute("DROP TABLE T1, T2"); - end(); - } - - private void checkDeadlock() throws SQLException { - assertTrue(lastException != null); - assertKnownException(lastException); - assertEquals(ErrorCode.DEADLOCK_1, lastException.getErrorCode()); - SQLException e2 = lastException.getNextException(); - if (e2 != null) { - // we have two exception, but there should only be one - SQLException e3 = new SQLException("Expected one exception, got multiple"); - e3.initCause(e2); - throw e3; - } - } - -} diff --git a/tools/h2/src/test/org/h2/test/db/TestEncryptedDb.java b/tools/h2/src/test/org/h2/test/db/TestEncryptedDb.java deleted file mode 100755 index bcccbdf..0000000 --- a/tools/h2/src/test/org/h2/test/db/TestEncryptedDb.java +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.test.db; - -import java.sql.Connection; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.sql.Statement; - -import org.h2.test.TestBase; - -/** - * Test using an encrypted database. - */ -public class TestEncryptedDb extends TestBase { - - /** - * Run just this test. - * - * @param a ignored - */ - public static void main(String... a) throws Exception { - TestBase.createCaller().init().test(); - } - - public void test() throws SQLException { - if (config.memory || config.cipher != null) { - return; - } - deleteDb("encrypted"); - Connection conn = getConnection("encrypted;CIPHER=AES", "sa", "123 123"); - Statement stat = conn.createStatement(); - stat.execute("CREATE TABLE TEST(ID INT)"); - stat.execute("CHECKPOINT"); - stat.execute("SET WRITE_DELAY 0"); - stat.execute("INSERT INTO TEST VALUES(1)"); - stat.execute("SHUTDOWN IMMEDIATELY"); - try { - conn.close(); - } catch (SQLException e) { - assertKnownException(e); - } - - try { - getConnection("encrypted;CIPHER=AES", "sa", "1234 1234"); - fail(); - } catch (SQLException e) { - assertKnownException(e); - } - - conn = getConnection("encrypted;CIPHER=AES", "sa", "123 123"); - stat = conn.createStatement(); - ResultSet rs = stat.executeQuery("SELECT * FROM TEST"); - assertTrue(rs.next()); - assertEquals(1, rs.getInt(1)); - assertFalse(rs.next()); - - conn.close(); - deleteDb("encrypted"); - } - -} diff --git a/tools/h2/src/test/org/h2/test/db/TestExclusive.java b/tools/h2/src/test/org/h2/test/db/TestExclusive.java deleted file mode 100755 index a55e631..0000000 --- a/tools/h2/src/test/org/h2/test/db/TestExclusive.java +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.test.db; - -import java.sql.Connection; -import java.sql.SQLException; -import java.sql.Statement; - -import org.h2.test.TestBase; - -/** - * Test for the exclusive mode. - */ -public class TestExclusive extends TestBase { - - /** - * Run just this test. - * - * @param a ignored - */ - public static void main(String... a) throws Exception { - TestBase.createCaller().init().test(); - } - - public void test() throws Exception { - deleteDb("exclusive"); - Connection conn = getConnection("exclusive"); - Statement stat = conn.createStatement(); - stat.execute("set exclusive true"); - try { - Connection conn2 = getConnection("exclusive"); - conn2.close(); - fail(); - } catch (SQLException e) { - assertKnownException(e); - } - - stat.execute("set exclusive false"); - Connection conn2 = getConnection("exclusive"); - final Statement stat2 = conn2.createStatement(); - stat.execute("set exclusive true"); - final int[] state = { 0 }; - Thread t = new Thread() { - public void run() { - try { - stat2.execute("select * from dual"); - if (state[0] != 1) { - new Error("unexpected state: " + state[0]).printStackTrace(); - } - state[0] = 2; - } catch (Exception e) { - e.printStackTrace(); - } - } - }; - t.start(); - state[0] = 1; - stat.execute("set exclusive false"); - for (int i = 0; i < 20; i++) { - Thread.sleep(100); - if (state[0] == 2) { - break; - } - } - assertEquals(2, state[0]); - stat.execute("set exclusive true"); - conn.close(); - - // check that exclusive mode is off when disconnected - stat2.execute("select * from dual"); - conn2.close(); - deleteDb("exclusive"); - } - -} diff --git a/tools/h2/src/test/org/h2/test/db/TestFullText.java b/tools/h2/src/test/org/h2/test/db/TestFullText.java deleted file mode 100755 index 4491556..0000000 --- a/tools/h2/src/test/org/h2/test/db/TestFullText.java +++ /dev/null @@ -1,384 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.test.db; - -import java.io.Reader; -import java.sql.Connection; -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.sql.Statement; -import java.util.Random; -import java.util.StringTokenizer; -import org.h2.fulltext.FullText; -import org.h2.store.fs.FileSystem; -import org.h2.test.TestBase; - -/** - * Fulltext search tests. - */ -public class TestFullText extends TestBase { - - /** - * Run just this test. - * - * @param a ignored - */ - public static void main(String... a) throws Exception { - TestBase.createCaller().init().test(); - } - - public void test() throws Exception { - testTransaction(false); - testCreateDrop(); - if (config.memory) { - return; - } - testMultiThreaded(); - testStreamLob(); - test(false, "VARCHAR"); - test(false, "CLOB"); - testPerformance(false); - testReopen(false); - String luceneFullTextClassName = "org.h2.fulltext.FullTextLucene"; - try { - Class.forName(luceneFullTextClassName); - testTransaction(true); - test(true, "VARCHAR"); - test(true, "CLOB"); - testPerformance(true); - testReopen(true); - } catch (ClassNotFoundException e) { - println("Class not found, not tested: " + luceneFullTextClassName); - // ok - } catch (NoClassDefFoundError e) { - println("Class not found, not tested: " + luceneFullTextClassName); - // ok - } - FullText.closeAll(); - deleteDb("fullText"); - deleteDb("fullTextReopen"); - } - - private void testTransaction(boolean lucene) throws SQLException { - if (config.memory) { - return; - } - String prefix = lucene ? "FTL" : "FT"; - deleteDb("fullTextTransaction"); - FileSystem.getInstance(getBaseDir()).deleteRecursive(getBaseDir() + "/fullTextTransaction", false); - Connection conn = getConnection("fullTextTransaction"); - Statement stat = conn.createStatement(); - String className = lucene ? "FullTextLucene" : "FullText"; - stat.execute("CREATE ALIAS IF NOT EXISTS " + prefix + "_INIT FOR \"org.h2.fulltext." + className + ".init\""); - stat.execute("CALL " + prefix + "_INIT()"); - stat.execute("CREATE TABLE TEST(ID INT PRIMARY KEY, NAME VARCHAR)"); - stat.execute("INSERT INTO TEST VALUES(1, 'Hello World')"); - stat.execute("CALL " + prefix + "_CREATE_INDEX('PUBLIC', 'TEST', NULL)"); - stat.execute("UPDATE TEST SET NAME=NULL WHERE ID=1"); - stat.execute("UPDATE TEST SET NAME='Hello World' WHERE ID=1"); - conn.setAutoCommit(false); - stat.execute("insert into test values(2, 'Hello Moon!')"); - conn.rollback(); - conn.close(); - conn = getConnection("fullTextTransaction"); - stat = conn.createStatement(); - ResultSet rs = stat.executeQuery("SELECT * FROM " + prefix + "_SEARCH('Hello', 0, 0)"); - assertTrue(rs.next()); - rs = stat.executeQuery("SELECT * FROM " + prefix + "_SEARCH('Moon', 0, 0)"); - assertFalse(rs.next()); - FullText.dropAll(conn); - conn.close(); - deleteDb("fullTextTransaction"); - FileSystem.getInstance(getBaseDir()).deleteRecursive(getBaseDir() + "/fullTextTransaction", false); - } - - private void testMultiThreaded() throws Exception { - deleteDb("fullText"); - final boolean[] stop = { false }; - final Exception[] exception = { null }; - int len = 2; - Thread[] threads = new Thread[len]; - for (int i = 0; i < len; i++) { - // final Connection conn = - // getConnection("fullText;MULTI_THREADED=1;LOCK_TIMEOUT=10000"); - final Connection conn = getConnection("fullText"); - Statement stat = conn.createStatement(); - stat.execute("CREATE ALIAS IF NOT EXISTS FT_INIT FOR \"org.h2.fulltext.FullText.init\""); - stat.execute("CALL FT_INIT()"); - stat.execute("CREATE ALIAS IF NOT EXISTS FT_INIT FOR \"org.h2.fulltext.FullText.init\""); - stat.execute("CALL FT_INIT()"); - final String tableName = "TEST" + i; - stat.execute("CREATE TABLE " + tableName + "(ID INT PRIMARY KEY, DATA VARCHAR)"); - FullText.createIndex(conn, "PUBLIC", tableName, null); - threads[i] = new Thread() { - public void run() { - try { - PreparedStatement prep = conn.prepareStatement("INSERT INTO " + tableName + " VALUES(?, ?)"); - Random random = new Random(); - int x = 0; - while (!stop[0]) { - StringBuilder buff = new StringBuilder(); - for (int j = 0; j < 1000; j++) { - buff.append(" " + random.nextInt(10000)); - buff.append(" x" + j); - } - prep.setInt(1, x); - prep.setString(2, buff.toString()); - prep.execute(); - x++; - } - conn.close(); - } catch (SQLException e) { - exception[0] = e; - } - } - }; - } - for (Thread t : threads) { - t.start(); - } - Thread.sleep(1000); - stop[0] = true; - for (Thread t : threads) { - t.join(); - } - if (exception[0] != null) { - throw exception[0]; - } - - } - - private void testStreamLob() throws SQLException { - deleteDb("fullText"); - Connection conn = getConnection("fullText"); - Statement stat = conn.createStatement(); - stat.execute("CREATE ALIAS IF NOT EXISTS FT_INIT FOR \"org.h2.fulltext.FullText.init\""); - stat.execute("CREATE TABLE TEST(ID INT PRIMARY KEY, DATA CLOB)"); - FullText.createIndex(conn, "PUBLIC", "TEST", null); - conn.setAutoCommit(false); - stat.execute("insert into test values(1, 'Hello Moon!')"); - conn.rollback(); - conn.setAutoCommit(true); - stat.execute("insert into test values(0, 'Hello World!')"); - PreparedStatement prep = conn.prepareStatement("insert into test values(1, ?)"); - final int length = 1024 * 1024; - prep.setCharacterStream(1, new Reader() { - int remaining = length; - public void close() { - // ignore - } - public int read(char[] buff, int off, int len) { - if (remaining >= len) { - remaining -= len; - return len; - } - remaining = -1; - return -1; - } - }, length); - prep.execute(); - ResultSet rs = stat.executeQuery("SELECT * FROM FT_SEARCH('World', 0, 0)"); - assertTrue(rs.next()); - rs = stat.executeQuery("SELECT * FROM FT_SEARCH('Moon', 0, 0)"); - assertFalse(rs.next()); - FullText.dropAll(conn); - conn.close(); - deleteDb("fullText"); - } - - private void testCreateDrop() throws SQLException { - deleteDb("fullText"); - FileSystem.getInstance(getBaseDir()).deleteRecursive(getBaseDir() + "/fullText", false); - Connection conn = getConnection("fullText"); - Statement stat = conn.createStatement(); - stat.execute("CREATE ALIAS IF NOT EXISTS FT_INIT FOR \"org.h2.fulltext.FullText.init\""); - stat.execute("CREATE TABLE TEST(ID INT PRIMARY KEY, NAME VARCHAR)"); - for (int i = 0; i < 10; i++) { - FullText.createIndex(conn, "PUBLIC", "TEST", null); - FullText.dropIndex(conn, "PUBLIC", "TEST"); - } - conn.close(); - deleteDb("fullText"); - FileSystem.getInstance(getBaseDir()).deleteRecursive(getBaseDir() + "/fullText", false); - } - - private void testReopen(boolean lucene) throws SQLException { - String prefix = lucene ? "FTL" : "FT"; - deleteDb("fullTextReopen"); - FileSystem.getInstance(getBaseDir()).deleteRecursive(getBaseDir() + "/fullTextReopen", false); - Connection conn = getConnection("fullTextReopen"); - Statement stat = conn.createStatement(); - String className = lucene ? "FullTextLucene" : "FullText"; - stat.execute("CREATE ALIAS IF NOT EXISTS " + prefix + "_INIT FOR \"org.h2.fulltext." + className + ".init\""); - stat.execute("CALL " + prefix + "_INIT()"); - stat.execute("CREATE TABLE TEST(ID INT PRIMARY KEY, NAME VARCHAR)"); - stat.execute("INSERT INTO TEST VALUES(1, 'Hello World')"); - stat.execute("CALL " + prefix + "_CREATE_INDEX('PUBLIC', 'TEST', NULL)"); - stat.execute("UPDATE TEST SET NAME=NULL WHERE ID=1"); - stat.execute("UPDATE TEST SET NAME='Hello World' WHERE ID=1"); - conn.close(); - - conn = getConnection("fullTextReopen"); - stat = conn.createStatement(); - ResultSet rs = stat.executeQuery("SELECT * FROM " + prefix + "_SEARCH('Hello', 0, 0)"); - assertTrue(rs.next()); - stat.executeQuery("SELECT * FROM " + prefix + "_SEARCH(NULL, 0, 0)"); - stat.execute("INSERT INTO TEST VALUES(2, NULL)"); - conn.close(); - - FullText.closeAll(); - conn = getConnection("fullTextReopen"); - stat = conn.createStatement(); - stat.execute("INSERT INTO TEST VALUES(3, 'Hello')"); - conn.close(); - FileSystem.getInstance(getBaseDir()).deleteRecursive(getBaseDir() + "/fullTextReopen", false); - } - - private void testPerformance(boolean lucene) throws SQLException { - deleteDb("fullText"); - FileSystem.getInstance(getBaseDir()).deleteRecursive(getBaseDir() + "/fullText", false); - Connection conn = getConnection("fullText"); - String prefix = lucene ? "FTL" : "FT"; - Statement stat = conn.createStatement(); - String className = lucene ? "FullTextLucene" : "FullText"; - stat.execute("CREATE ALIAS IF NOT EXISTS " + prefix + "_INIT FOR \"org.h2.fulltext." + className + ".init\""); - stat.execute("CALL " + prefix + "_INIT()"); - stat.execute("DROP TABLE IF EXISTS TEST"); - stat.execute("CREATE TABLE TEST AS SELECT * FROM INFORMATION_SCHEMA.HELP"); - stat.execute("ALTER TABLE TEST ALTER COLUMN ID INT NOT NULL"); - stat.execute("CREATE PRIMARY KEY ON TEST(ID)"); - long time = System.currentTimeMillis(); - stat.execute("CALL " + prefix + "_CREATE_INDEX('PUBLIC', 'TEST', NULL)"); - println("create " + prefix + ": " + (System.currentTimeMillis() - time)); - PreparedStatement prep = conn.prepareStatement("SELECT * FROM " + prefix + "_SEARCH(?, 0, 0)"); - time = System.currentTimeMillis(); - ResultSet rs = stat.executeQuery("SELECT TEXT FROM TEST"); - int count = 0; - while (rs.next()) { - String text = rs.getString(1); - StringTokenizer tokenizer = new StringTokenizer(text, " ()[].,;:-+*/!?=<>{}#@'\"~$_%&|"); - while (tokenizer.hasMoreTokens()) { - String word = tokenizer.nextToken(); - if (word.length() < 10) { - continue; - } - prep.setString(1, word); - ResultSet rs2 = prep.executeQuery(); - while (rs2.next()) { - rs2.getString(1); - count++; - } - } - } - println("search " + prefix + ": " + (System.currentTimeMillis() - time) + " count: " + count); - stat.execute("CALL " + prefix + "_DROP_ALL()"); - conn.close(); - } - - private void test(boolean lucene, String dataType) throws SQLException { - if (lucene && getBaseDir().indexOf(':') > 0) { - return; - } - deleteDb("fullText"); - Connection conn = getConnection("fullText"); - String prefix = lucene ? "FTL_" : "FT_"; - Statement stat = conn.createStatement(); - String className = lucene ? "FullTextLucene" : "FullText"; - stat.execute("CREATE ALIAS IF NOT EXISTS " + prefix + "INIT FOR \"org.h2.fulltext." + className + ".init\""); - stat.execute("CALL " + prefix + "INIT()"); - stat.execute("DROP TABLE IF EXISTS TEST"); - stat.execute("CREATE TABLE TEST(ID INT PRIMARY KEY, NAME " + dataType + ")"); - stat.execute("INSERT INTO TEST VALUES(1, 'Hello World')"); - stat.execute("CALL " + prefix + "CREATE_INDEX('PUBLIC', 'TEST', NULL)"); - ResultSet rs; - rs = stat.executeQuery("SELECT * FROM " + prefix + "SEARCH('Hello', 0, 0)"); - rs.next(); - assertEquals("\"PUBLIC\".\"TEST\" WHERE \"ID\"=1", rs.getString(1)); - assertFalse(rs.next()); - rs = stat.executeQuery("SELECT * FROM " + prefix + "SEARCH('Hallo', 0, 0)"); - assertFalse(rs.next()); - stat.execute("INSERT INTO TEST VALUES(2, 'Hallo Welt')"); - rs = stat.executeQuery("SELECT * FROM " + prefix + "SEARCH('Hello', 0, 0)"); - rs.next(); - assertEquals("\"PUBLIC\".\"TEST\" WHERE \"ID\"=1", rs.getString(1)); - assertFalse(rs.next()); - rs = stat.executeQuery("SELECT * FROM " + prefix + "SEARCH('Hallo', 0, 0)"); - rs.next(); - assertEquals("\"PUBLIC\".\"TEST\" WHERE \"ID\"=2", rs.getString(1)); - assertFalse(rs.next()); - - stat.execute("CALL " + prefix + "REINDEX()"); - rs = stat.executeQuery("SELECT * FROM " + prefix + "SEARCH('Hello', 0, 0)"); - rs.next(); - assertEquals("\"PUBLIC\".\"TEST\" WHERE \"ID\"=1", rs.getString(1)); - assertFalse(rs.next()); - rs = stat.executeQuery("SELECT * FROM " + prefix + "SEARCH('Hallo', 0, 0)"); - rs.next(); - assertEquals("\"PUBLIC\".\"TEST\" WHERE \"ID\"=2", rs.getString(1)); - assertFalse(rs.next()); - - stat.execute("INSERT INTO TEST VALUES(3, 'Hello World')"); - stat.execute("INSERT INTO TEST VALUES(4, 'Hello World')"); - stat.execute("INSERT INTO TEST VALUES(5, 'Hello World')"); - - rs = stat.executeQuery("SELECT * FROM " + prefix + "SEARCH('World', 0, 0) ORDER BY QUERY"); - rs.next(); - assertEquals("\"PUBLIC\".\"TEST\" WHERE \"ID\"=1", rs.getString(1)); - rs.next(); - assertEquals("\"PUBLIC\".\"TEST\" WHERE \"ID\"=3", rs.getString(1)); - rs.next(); - assertEquals("\"PUBLIC\".\"TEST\" WHERE \"ID\"=4", rs.getString(1)); - rs.next(); - assertEquals("\"PUBLIC\".\"TEST\" WHERE \"ID\"=5", rs.getString(1)); - assertFalse(rs.next()); - - rs = stat.executeQuery("SELECT * FROM " + prefix + "SEARCH('World', 1, 0)"); - rs.next(); - assertTrue(rs.getString(1).startsWith("\"PUBLIC\".\"TEST\" WHERE \"ID\"=")); - assertFalse(rs.next()); - - rs = stat.executeQuery("SELECT * FROM " + prefix + "SEARCH('World', 0, 2) ORDER BY QUERY"); - rs.next(); - assertTrue(rs.getString(1).startsWith("\"PUBLIC\".\"TEST\" WHERE \"ID\"=")); - rs.next(); - assertTrue(rs.getString(1).startsWith("\"PUBLIC\".\"TEST\" WHERE \"ID\"=")); - assertFalse(rs.next()); - - rs = stat.executeQuery("SELECT * FROM " + prefix + "SEARCH('World', 2, 1) ORDER BY QUERY"); - rs.next(); - assertTrue(rs.getString(1).startsWith("\"PUBLIC\".\"TEST\" WHERE \"ID\"=")); - rs.next(); - assertTrue(rs.getString(1).startsWith("\"PUBLIC\".\"TEST\" WHERE \"ID\"=")); - assertFalse(rs.next()); - - rs = stat.executeQuery("SELECT * FROM " + prefix + "SEARCH('1', 0, 0)"); - rs.next(); - assertEquals("\"PUBLIC\".\"TEST\" WHERE \"ID\"=1", rs.getString(1)); - assertFalse(rs.next()); - - if (lucene) { - rs = stat.executeQuery("SELECT * FROM " + prefix + "SEARCH('NAME:Hallo', 0, 0)"); - rs.next(); - assertEquals("\"PUBLIC\".\"TEST\" WHERE \"ID\"=2", rs.getString(1)); - assertFalse(rs.next()); - } - - conn.close(); - - conn = getConnection("fullText"); - stat = conn.createStatement(); - rs = stat.executeQuery("SELECT * FROM " + prefix + "SEARCH('World', 0, 0)"); - - stat.execute("CALL " + prefix + "DROP_ALL()"); - stat.executeQuery("SELECT * FROM " + prefix + "SEARCH('World', 2, 1)"); - stat.execute("CALL " + prefix + "DROP_ALL()"); - - conn.close(); - - } -} diff --git a/tools/h2/src/test/org/h2/test/db/TestFunctionOverload.java b/tools/h2/src/test/org/h2/test/db/TestFunctionOverload.java deleted file mode 100755 index 76e624b..0000000 --- a/tools/h2/src/test/org/h2/test/db/TestFunctionOverload.java +++ /dev/null @@ -1,208 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.test.db; - -import java.sql.Connection; -import java.sql.DatabaseMetaData; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.sql.Statement; - -import org.h2.test.TestBase; - -/** - * Tests for overloaded user defined functions. - * - * @author Gary Tong - */ -public class TestFunctionOverload extends TestBase { - - private static final String ME = TestFunctionOverload.class.getName(); - private Connection conn; - private DatabaseMetaData meta; - - /** - * Run just this test. - * - * @param a ignored - */ - public static void main(String... a) throws Exception { - TestBase.createCaller().init().test(); - } - - public void test() throws SQLException { - deleteDb("functionOverload"); - conn = getConnection("functionOverload"); - meta = conn.getMetaData(); - testControl(); - testOverload(); - testOverloadNamedArgs(); - testOverloadWithConnection(); - testOverloadError(); - conn.close(); - deleteDb("functionOverload"); - } - - private void testOverloadError() throws SQLException { - Statement stat = conn.createStatement(); - try { - stat.execute("create alias overloadError for \"" + ME + ".overloadError\""); - fail(); - } catch (SQLException e) { - assertKnownException(e); - } - } - - private void testControl() throws SQLException { - Statement stat = conn.createStatement(); - stat.execute("create alias overload0 for \"" + ME + ".overload0\""); - ResultSet rs = stat.executeQuery("select overload0() from dual"); - assertTrue(rs.next()); - assertEquals("0 args", 0, rs.getInt(1)); - assertFalse(rs.next()); - rs = meta.getProcedures(null, null, "OVERLOAD0"); - rs.next(); - assertFalse(rs.next()); - } - - private void testOverload() throws SQLException { - Statement stat = conn.createStatement(); - stat.execute("create alias overload1or2 for \"" + ME + ".overload1or2\""); - ResultSet rs = stat.executeQuery("select overload1or2(1) from dual"); - rs.next(); - assertEquals("1 arg", 1, rs.getInt(1)); - assertFalse(rs.next()); - rs = stat.executeQuery("select overload1or2(1, 2) from dual"); - rs.next(); - assertEquals("2 args", 3, rs.getInt(1)); - assertFalse(rs.next()); - rs = meta.getProcedures(null, null, "OVERLOAD1OR2"); - rs.next(); - assertEquals(1, rs.getInt("NUM_INPUT_PARAMS")); - rs.next(); - assertEquals(2, rs.getInt("NUM_INPUT_PARAMS")); - assertFalse(rs.next()); - } - - private void testOverloadNamedArgs() throws SQLException { - Statement stat = conn.createStatement(); - - stat.execute("create alias overload1or2Named for \"" + ME + ".overload1or2(int)\""); - - ResultSet rs = stat.executeQuery("select overload1or2Named(1) from dual"); - assertTrue("First Row", rs.next()); - assertEquals("1 arg", 1, rs.getInt(1)); - assertFalse("Second Row", rs.next()); - rs.close(); - - try { - rs = stat.executeQuery("select overload1or2Named(1, 2) from dual"); - rs.close(); - fail(); - } catch (SQLException e) { - assertKnownException(e); - } - - stat.close(); - } - - private void testOverloadWithConnection() throws SQLException { - Statement stat = conn.createStatement(); - - stat.execute("create alias overload1or2WithConn for \"" + ME + ".overload1or2WithConn\""); - - ResultSet rs = stat.executeQuery("select overload1or2WithConn(1) from dual"); - rs.next(); - assertEquals("1 arg", 1, rs.getInt(1)); - assertFalse(rs.next()); - rs.close(); - - rs = stat.executeQuery("select overload1or2WithConn(1, 2) from dual"); - rs.next(); - assertEquals("2 args", 3, rs.getInt(1)); - assertFalse(rs.next()); - rs.close(); - - stat.close(); - } - - /** - * This method is called via reflection from the database. - * - * @return 0 - */ - public static int overload0() { - return 0; - } - - /** - * This method is called via reflection from the database. - * - * @param one the value - * @return the value - */ - public static int overload1or2(int one) { - return one; - } - - /** - * This method is called via reflection from the database. - * - * @param one the first value - * @param two the second value - * @return the sum of both - */ - public static int overload1or2(int one, int two) { - return one + two; - } - - /** - * This method is called via reflection from the database. - * - * @param conn the connection - * @param one the value - * @return the value - */ - public static int overload1or2WithConn(Connection conn, int one) throws SQLException { - conn.createStatement().executeQuery("select 1 from dual"); - return one; - } - - /** - * This method is called via reflection from the database. - * - * @param one the first value - * @param two the second value - * @return the sum of both - */ - public static int overload1or2WithConn(int one, int two) { - return one + two; - } - - /** - * This method is called via reflection from the database. - * - * @param one the first value - * @param two the second value - * @return the sum of both - */ - public static int overloadError(int one, int two) { - return one + two; - } - - /** - * This method is called via reflection from the database. - * - * @param one the first value - * @param two the second value - * @return the sum of both - */ - public static int overloadError(double one, double two) { - return (int) (one + two); - } - -} diff --git a/tools/h2/src/test/org/h2/test/db/TestFunctions.java b/tools/h2/src/test/org/h2/test/db/TestFunctions.java deleted file mode 100755 index c05bcc9..0000000 --- a/tools/h2/src/test/org/h2/test/db/TestFunctions.java +++ /dev/null @@ -1,809 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.test.db; - -import java.io.BufferedInputStream; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.io.OutputStream; -import java.math.BigDecimal; -import java.sql.Blob; -import java.sql.Connection; -import java.sql.DatabaseMetaData; -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.sql.Statement; -import java.sql.Types; -import java.util.ArrayList; -import java.util.Properties; -import java.util.UUID; - -import org.h2.api.AggregateFunction; -import org.h2.store.fs.FileSystem; -import org.h2.test.TestBase; -import org.h2.tools.SimpleResultSet; -import org.h2.util.IOUtils; -import org.h2.util.New; - -/** - * Tests for user defined functions and aggregates. - */ -public class TestFunctions extends TestBase implements AggregateFunction { - - static int count; - - /** - * Run just this test. - * - * @param a ignored - */ - public static void main(String... a) throws Exception { - TestBase.createCaller().init().test(); - } - - public void test() throws Exception { - deleteDb("functions"); - testGreatest(); - testSource(); - testDynamicArgumentAndReturn(); - testUUID(); - testWhiteSpacesInParameters(); - testSchemaSearchPath(); - testDeterministic(); - testTransactionId(); - testPrecision(); - testVarArgs(); - testAggregate(); - testFunctions(); - testFileRead(); - deleteDb("functions"); - FileSystem.getInstance(TEMP_DIR).deleteRecursive(TEMP_DIR, true); - } - - private void testGreatest() throws SQLException { - Connection conn = getConnection("functions"); - Statement stat = conn.createStatement(); - - String createSQL = "CREATE TABLE testGreatest (id BIGINT);"; - stat.execute(createSQL); - stat.execute("insert into testGreatest values (1)"); - - String query = "SELECT GREATEST(id, " + ((long) Integer.MAX_VALUE) + ") FROM testGreatest"; - ResultSet rs = stat.executeQuery(query); - rs.next(); - Object o = rs.getObject(1); - assertEquals(Long.class.getName(), o.getClass().getName()); - - String query2 = "SELECT GREATEST(id, " + ((long) Integer.MAX_VALUE + 1) + ") FROM testGreatest"; - ResultSet rs2 = stat.executeQuery(query2); - rs2.next(); - Object o2 = rs2.getObject(1); - assertEquals(Long.class.getName(), o2.getClass().getName()); - - conn.close(); - } - - private void testSource() throws SQLException { - Connection conn = getConnection("functions"); - Statement stat = conn.createStatement(); - ResultSet rs; - stat.execute("create force alias sayHi as 'String test(String name) {\n" + - "return \"Hello \" + name;\n}'"); - rs = stat.executeQuery("SELECT ALIAS_NAME FROM INFORMATION_SCHEMA.FUNCTION_ALIASES"); - rs.next(); - assertEquals("SAY" + "HI", rs.getString(1)); - rs = stat.executeQuery("call sayHi('Joe')"); - rs.next(); - assertEquals("Hello Joe", rs.getString(1)); - if (!config.memory) { - conn.close(); - conn = getConnection("functions"); - stat = conn.createStatement(); - rs = stat.executeQuery("call sayHi('Joe')"); - rs.next(); - assertEquals("Hello Joe", rs.getString(1)); - } - stat.execute("drop alias sayHi"); - conn.close(); - } - - private void testDynamicArgumentAndReturn() throws SQLException { - Connection conn = getConnection("functions"); - Statement stat = conn.createStatement(); - ResultSet rs; - stat.execute("create alias dynamic deterministic for \"" + getClass().getName() + ".dynamic\""); - setCount(0); - rs = stat.executeQuery("call dynamic(('a', 1))[0]"); - rs.next(); - String a = rs.getString(1); - assertEquals("a1", a); - stat.execute("drop alias dynamic"); - conn.close(); - } - - private void testUUID() throws SQLException { - Connection conn = getConnection("functions"); - Statement stat = conn.createStatement(); - ResultSet rs; - - stat.execute("create alias xorUUID for \""+getClass().getName()+".xorUUID\""); - setCount(0); - rs = stat.executeQuery("call xorUUID(random_uuid(), random_uuid())"); - rs.next(); - Object o = rs.getObject(1); - assertEquals(UUID.class.toString(), o.getClass().toString()); - stat.execute("drop alias xorUUID"); - - conn.close(); - } - - private void testDeterministic() throws SQLException { - Connection conn = getConnection("functions"); - Statement stat = conn.createStatement(); - ResultSet rs; - - stat.execute("create alias getCount for \""+getClass().getName()+".getCount\""); - setCount(0); - rs = stat.executeQuery("select getCount() from system_range(1, 2)"); - rs.next(); - assertEquals(0, rs.getInt(1)); - rs.next(); - assertEquals(1, rs.getInt(1)); - stat.execute("drop alias getCount"); - - stat.execute("create alias getCount deterministic for \""+getClass().getName()+".getCount\""); - setCount(0); - rs = stat.executeQuery("select getCount() from system_range(1, 2)"); - rs.next(); - assertEquals(0, rs.getInt(1)); - rs.next(); - assertEquals(0, rs.getInt(1)); - stat.execute("drop alias getCount"); - rs = stat.executeQuery("SELECT * FROM INFORMATION_SCHEMA.FUNCTION_ALIASES WHERE UPPER(ALIAS_NAME) = 'GET' || 'COUNT'"); - assertFalse(rs.next()); - stat.execute("create alias reverse deterministic for \""+getClass().getName()+".reverse\""); - rs = stat.executeQuery("select reverse(x) from system_range(700, 700)"); - rs.next(); - assertEquals("007", rs.getString(1)); - stat.execute("drop alias reverse"); - - conn.close(); - } - - private void testTransactionId() throws SQLException { - if (config.memory) { - return; - } - Connection conn = getConnection("functions"); - Statement stat = conn.createStatement(); - stat.execute("create table test(id int)"); - ResultSet rs; - rs = stat.executeQuery("call transaction_id()"); - rs.next(); - assertTrue(rs.getString(1) == null && rs.wasNull()); - stat.execute("insert into test values(1)"); - rs = stat.executeQuery("call transaction_id()"); - rs.next(); - assertTrue(rs.getString(1) == null && rs.wasNull()); - conn.setAutoCommit(false); - stat.execute("delete from test"); - rs = stat.executeQuery("call transaction_id()"); - rs.next(); - assertTrue(rs.getString(1) != null); - stat.execute("drop table test"); - conn.close(); - } - - private void testPrecision() throws SQLException { - Connection conn = getConnection("functions"); - Statement stat = conn.createStatement(); - stat.execute("create alias no_op for \""+getClass().getName()+".noOp\""); - PreparedStatement prep = conn.prepareStatement("select * from dual where no_op(1.6)=?"); - prep.setBigDecimal(1, new BigDecimal("1.6")); - ResultSet rs = prep.executeQuery(); - assertTrue(rs.next()); - - stat.execute("create aggregate agg_sum for \""+getClass().getName()+"\""); - rs = stat.executeQuery("select agg_sum(1), sum(1.6) from dual"); - rs.next(); - assertEquals(1, rs.getMetaData().getScale(2)); - assertEquals(32767, rs.getMetaData().getScale(1)); - conn.close(); - } - - private void testVarArgs() throws SQLException { -//## Java 1.5 begin ## - Connection conn = getConnection("functions"); - Statement stat = conn.createStatement(); - stat.execute("CREATE ALIAS mean FOR \"" + - getClass().getName() + ".mean\""); - ResultSet rs = stat.executeQuery( - "select mean(), mean(10), mean(10, 20), mean(10, 20, 30)"); - rs.next(); - assertEquals(1.0, rs.getDouble(1)); - assertEquals(10.0, rs.getDouble(2)); - assertEquals(15.0, rs.getDouble(3)); - assertEquals(20.0, rs.getDouble(4)); - - stat.execute("CREATE ALIAS mean2 FOR \"" + - getClass().getName() + ".mean2\""); - rs = stat.executeQuery( - "select mean2(), mean2(10), mean2(10, 20)"); - rs.next(); - assertEquals(Double.NaN, rs.getDouble(1)); - assertEquals(10.0, rs.getDouble(2)); - assertEquals(15.0, rs.getDouble(3)); - - stat.execute("CREATE ALIAS printMean FOR \"" + - getClass().getName() + ".printMean\""); - rs = stat.executeQuery( - "select printMean('A'), printMean('A', 10), " + - "printMean('BB', 10, 20), printMean ('CCC', 10, 20, 30)"); - rs.next(); - assertEquals("A: 0", rs.getString(1)); - assertEquals("A: 10", rs.getString(2)); - assertEquals("BB: 15", rs.getString(3)); - assertEquals("CCC: 20", rs.getString(4)); - conn.close(); -//## Java 1.5 end ## - } - - private void testFileRead() throws Exception { - Connection conn = getConnection("functions"); - Statement stat = conn.createStatement(); - String fileName = getBaseDir() + "/test.txt"; - Properties prop = System.getProperties(); - OutputStream out = IOUtils.openFileOutputStream(fileName, false); - prop.store(out, ""); - out.close(); - ResultSet rs = stat.executeQuery("SELECT LENGTH(FILE_READ('" + fileName + "')) LEN"); - rs.next(); - assertEquals(IOUtils.length(fileName), rs.getInt(1)); - rs = stat.executeQuery("SELECT FILE_READ('" + fileName + "') PROP"); - rs.next(); - Properties p2 = new Properties(); - p2.load(rs.getBinaryStream(1)); - assertEquals(prop.size(), p2.size()); - rs = stat.executeQuery("SELECT FILE_READ('" + fileName + "', NULL) PROP"); - rs.next(); - String ps = rs.getString(1); - InputStreamReader r = new InputStreamReader(IOUtils.openFileInputStream(fileName)); - String ps2 = IOUtils.readStringAndClose(r, -1); - assertEquals(ps, ps2); - conn.close(); - IOUtils.delete(fileName); - } - - /** - * This median implementation keeps all objects in memory. - */ - public static class MedianString implements AggregateFunction { - - private ArrayList list = New.arrayList(); - - public void add(Object value) { - list.add(value.toString()); - } - - public Object getResult() { - return list.get(list.size() / 2); - } - - public int getType(int[] inputType) { - return Types.VARCHAR; - } - - public void init(Connection conn) { - // nothing to do - } - - } - - private void testAggregate() throws SQLException { - deleteDb("functions"); - Connection conn = getConnection("functions"); - Statement stat = conn.createStatement(); - stat.execute("CREATE AGGREGATE MEDIAN FOR \"" + MedianString.class.getName() + "\""); - stat.execute("CREATE AGGREGATE IF NOT EXISTS MEDIAN FOR \"" + MedianString.class.getName() + "\""); - ResultSet rs = stat.executeQuery("SELECT MEDIAN(X) FROM SYSTEM_RANGE(1, 9)"); - rs.next(); - assertEquals("5", rs.getString(1)); - conn.close(); - - if (config.memory) { - return; - } - - conn = getConnection("functions"); - stat = conn.createStatement(); - stat.executeQuery("SELECT MEDIAN(X) FROM SYSTEM_RANGE(1, 9)"); - DatabaseMetaData meta = conn.getMetaData(); - rs = meta.getProcedures(null, null, "MEDIAN"); - assertTrue(rs.next()); - assertFalse(rs.next()); - rs = stat.executeQuery("SCRIPT"); - boolean found = false; - while (rs.next()) { - String sql = rs.getString(1); - if (sql.indexOf("MEDIAN") >= 0) { - found = true; - } - } - assertTrue(found); - stat.execute("DROP AGGREGATE MEDIAN"); - stat.execute("DROP AGGREGATE IF EXISTS MEDIAN"); - conn.close(); - } - - private void testFunctions() throws SQLException { - deleteDb("functions"); - Connection conn = getConnection("functions"); - Statement stat = conn.createStatement(); - assertCallResult(null, stat, "abs(null)"); - assertCallResult("1", stat, "abs(1)"); - assertCallResult("1", stat, "abs(1)"); - - stat.execute("CREATE TABLE TEST(ID INT PRIMARY KEY, NAME VARCHAR)"); - stat.execute("CREATE ALIAS ADD_ROW FOR \"" + getClass().getName() + ".addRow\""); - ResultSet rs; - rs = stat.executeQuery("CALL ADD_ROW(1, 'Hello')"); - rs.next(); - assertEquals(1, rs.getInt(1)); - rs = stat.executeQuery("SELECT * FROM TEST"); - rs.next(); - assertEquals(1, rs.getInt(1)); - assertEquals("Hello", rs.getString(2)); - assertFalse(rs.next()); - - rs = stat.executeQuery("CALL ADD_ROW(2, 'World')"); - - stat.execute("CREATE ALIAS SELECT_F FOR \"" + getClass().getName() + ".select\""); - rs = stat.executeQuery("CALL SELECT_F('SELECT * FROM TEST ORDER BY ID')"); - assertEquals(2, rs.getMetaData().getColumnCount()); - rs.next(); - assertEquals(1, rs.getInt(1)); - assertEquals("Hello", rs.getString(2)); - rs.next(); - assertEquals(2, rs.getInt(1)); - assertEquals("World", rs.getString(2)); - assertFalse(rs.next()); - - rs = stat.executeQuery("SELECT NAME FROM SELECT_F('SELECT * FROM TEST ORDER BY NAME') ORDER BY NAME DESC"); - assertEquals(1, rs.getMetaData().getColumnCount()); - rs.next(); - assertEquals("World", rs.getString(1)); - rs.next(); - assertEquals("Hello", rs.getString(1)); - assertFalse(rs.next()); - - rs = stat.executeQuery("SELECT SELECT_F('SELECT * FROM TEST WHERE ID=' || ID) FROM TEST ORDER BY ID"); - assertEquals(1, rs.getMetaData().getColumnCount()); - rs.next(); - assertEquals("((1, Hello))", rs.getString(1)); - rs.next(); - assertEquals("((2, World))", rs.getString(1)); - assertFalse(rs.next()); - - rs = stat.executeQuery("SELECT SELECT_F('SELECT * FROM TEST ORDER BY ID') FROM DUAL"); - assertEquals(1, rs.getMetaData().getColumnCount()); - rs.next(); - assertEquals("((1, Hello), (2, World))", rs.getString(1)); - assertFalse(rs.next()); - - try { - stat.executeQuery("CALL SELECT_F('ERROR')"); - fail(); - } catch (SQLException e) { - assertEquals("42001", e.getSQLState()); - } - - stat.execute("CREATE ALIAS SIMPLE FOR \"" + getClass().getName() + ".simpleResultSet\""); - rs = stat.executeQuery("CALL SIMPLE(2, 1,1,1,1,1,1,1)"); - assertEquals(2, rs.getMetaData().getColumnCount()); - rs.next(); - assertEquals(0, rs.getInt(1)); - assertEquals("Hello", rs.getString(2)); - rs.next(); - assertEquals(1, rs.getInt(1)); - assertEquals("World", rs.getString(2)); - assertFalse(rs.next()); - - rs = stat.executeQuery("SELECT * FROM SIMPLE(1, 1,1,1,1,1,1,1)"); - assertEquals(2, rs.getMetaData().getColumnCount()); - rs.next(); - assertEquals(0, rs.getInt(1)); - assertEquals("Hello", rs.getString(2)); - assertFalse(rs.next()); - - stat.execute("CREATE ALIAS ARRAY FOR \"" + getClass().getName() + ".getArray\""); - rs = stat.executeQuery("CALL ARRAY()"); - assertEquals(2, rs.getMetaData().getColumnCount()); - rs.next(); - assertEquals(0, rs.getInt(1)); - assertEquals("Hello", rs.getString(2)); - assertFalse(rs.next()); - - stat.execute("CREATE ALIAS ROOT FOR \"" + getClass().getName() + ".root\""); - rs = stat.executeQuery("CALL ROOT(9)"); - rs.next(); - assertEquals(3, rs.getInt(1)); - assertFalse(rs.next()); - - stat.execute("CREATE ALIAS MAX_ID FOR \"" + getClass().getName() + ".selectMaxId\""); - rs = stat.executeQuery("CALL MAX_ID()"); - rs.next(); - assertEquals(2, rs.getInt(1)); - assertFalse(rs.next()); - - rs = stat.executeQuery("SELECT * FROM MAX_ID()"); - rs.next(); - assertEquals(2, rs.getInt(1)); - assertFalse(rs.next()); - - rs = stat.executeQuery("CALL CASE WHEN -9 < 0 THEN 0 ELSE ROOT(-9) END"); - rs.next(); - assertEquals(0, rs.getInt(1)); - assertFalse(rs.next()); - - stat.execute("CREATE ALIAS blob2stream FOR \"" + getClass().getName() + ".blob2stream\""); - stat.execute("CREATE ALIAS stream2stream FOR \"" + getClass().getName() + ".stream2stream\""); - stat.execute("CREATE TABLE TEST_BLOB(ID INT PRIMARY KEY, VALUE BLOB)"); - stat.execute("INSERT INTO TEST_BLOB VALUES(0, null)"); - stat.execute("INSERT INTO TEST_BLOB VALUES(1, 'edd1f011edd1f011edd1f011')"); - rs = stat.executeQuery("SELECT blob2stream(VALUE) FROM TEST_BLOB"); - while (rs.next()) { - // ignore - } - rs.close(); - rs = stat.executeQuery("SELECT stream2stream(VALUE) FROM TEST_BLOB"); - while (rs.next()) { - // ignore - } - - stat.execute("CREATE ALIAS NULL_RESULT FOR \"" + getClass().getName() + ".nullResultSet\""); - rs = stat.executeQuery("CALL NULL_RESULT()"); - assertEquals(1, rs.getMetaData().getColumnCount()); - rs.next(); - assertEquals(null, rs.getString(1)); - assertFalse(rs.next()); - - conn.close(); - } - - private void testWhiteSpacesInParameters() throws SQLException { - deleteDb("functions"); - Connection conn = getConnection("functions"); - Statement stat = conn.createStatement(); - // with white space - stat.execute("CREATE ALIAS PARSE_INT2 FOR \"java.lang.Integer.parseInt(java.lang.String, int)\""); - ResultSet rs; - rs = stat.executeQuery("CALL PARSE_INT2('473', 10)"); - rs.next(); - assertEquals(473, rs.getInt(1)); - stat.execute("DROP ALIAS PARSE_INT2"); - // without white space - stat.execute("CREATE ALIAS PARSE_INT2 FOR \"java.lang.Integer.parseInt(java.lang.String,int)\""); - stat.execute("DROP ALIAS PARSE_INT2"); - conn.close(); - } - - private void testSchemaSearchPath() throws SQLException { - deleteDb("functions"); - Connection conn = getConnection("functions"); - Statement stat = conn.createStatement(); - ResultSet rs; - stat.execute("CREATE SCHEMA TEST"); - stat.execute("SET SCHEMA TEST"); - stat.execute("CREATE ALIAS PARSE_INT2 FOR \"java.lang.Integer.parseInt(java.lang.String, int)\";"); - rs = stat.executeQuery("SELECT ALIAS_NAME FROM INFORMATION_SCHEMA.FUNCTION_ALIASES WHERE ALIAS_SCHEMA ='TEST'"); - rs.next(); - assertEquals("PARSE_INT2", rs.getString(1)); - stat.execute("DROP ALIAS PARSE_INT2"); - - stat.execute("SET SCHEMA PUBLIC"); - stat.execute("CREATE ALIAS TEST.PARSE_INT2 FOR \"java.lang.Integer.parseInt(java.lang.String, int)\";"); - stat.execute("SET SCHEMA_SEARCH_PATH PUBLIC, TEST"); - - rs = stat.executeQuery("CALL PARSE_INT2('-FF', 16)"); - rs.next(); - assertEquals(-255, rs.getInt(1)); - rs = stat.executeQuery("SELECT ALIAS_NAME FROM INFORMATION_SCHEMA.FUNCTION_ALIASES WHERE ALIAS_SCHEMA ='TEST'"); - rs.next(); - assertEquals("PARSE_INT2", rs.getString(1)); - rs = stat.executeQuery("CALL TEST.PARSE_INT2('-2147483648', 10)"); - rs.next(); - assertEquals(-2147483648, rs.getInt(1)); - rs = stat.executeQuery("CALL FUNCTIONS.TEST.PARSE_INT2('-2147483648', 10)"); - rs.next(); - assertEquals(-2147483648, rs.getInt(1)); - conn.close(); - } - - private void assertCallResult(String expected, Statement stat, String sql) throws SQLException { - ResultSet rs = stat.executeQuery("CALL " + sql); - rs.next(); - String s = rs.getString(1); - assertEquals(expected, s); - } - - /** - * This method is called via reflection from the database. - * - * @param value the blob - * @return the input stream - */ - public static BufferedInputStream blob2stream(Blob value) throws SQLException { - if (value == null) { - return null; - } - BufferedInputStream bufferedInStream = new BufferedInputStream(value.getBinaryStream()); - return bufferedInStream; - } - - /** - * This method is called via reflection from the database. - * - * @param value the input stream - * @return the buffered input stream - */ - public static BufferedInputStream stream2stream(InputStream value) { - if (value == null) { - return null; - } - BufferedInputStream bufferedInStream = new BufferedInputStream(value); - return bufferedInStream; - } - - /** - * This method is called via reflection from the database. - * - * @param conn the connection - * @param id the test id - * @param name the text - * @return the count - */ - public static int addRow(Connection conn, int id, String name) throws SQLException { - conn.createStatement().execute("INSERT INTO TEST VALUES(" + id + ", '" + name + "')"); - ResultSet rs = conn.createStatement().executeQuery("SELECT COUNT(*) FROM TEST"); - rs.next(); - int result = rs.getInt(1); - rs.close(); - return result; - } - - /** - * This method is called via reflection from the database. - * - * @param conn the connection - * @param sql the SQL statement - * @return the result set - */ - public static ResultSet select(Connection conn, String sql) throws SQLException { - Statement stat = conn.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY); - return stat.executeQuery(sql); - } - - /** - * This method is called via reflection from the database. - * - * @param conn the connection - * @return the result set - */ - public static ResultSet selectMaxId(Connection conn) throws SQLException { - return conn.createStatement().executeQuery("SELECT MAX(ID) FROM TEST"); - } - - /** - * This method is called via reflection from the database. - * - * @return the test array - */ - public static Object[] getArray() { - return new Object[] { new Integer(0), "Hello" }; - } - - /** - * This method is called via reflection from the database. - * - * @param conn the connection - * @return the result set - */ - public static ResultSet nullResultSet(Connection conn) throws SQLException { - PreparedStatement statement = conn.prepareStatement("select null from system_range(1,1)"); - return statement.executeQuery(); - } - - /** - * Test method to create a simple result set. - * - * @param rowCount the number of rows - * @param ip an int - * @param bp a boolean - * @param fp a float - * @param dp a double - * @param lp a long - * @param byParam a byte - * @param sp a short - * @return a result set - */ - public static ResultSet simpleResultSet(Integer rowCount, int ip, boolean bp, float fp, double dp, long lp, - byte byParam, short sp) { - SimpleResultSet rs = new SimpleResultSet(); - rs.addColumn("ID", Types.INTEGER, 10, 0); - rs.addColumn("NAME", Types.VARCHAR, 255, 0); - if (rowCount == null) { - if (ip != 0 || bp || fp != 0.0 || dp != 0.0 || sp != 0 || lp != 0 || byParam != 0) { - throw new AssertionError("params not 0/false"); - } - } - if (rowCount != null) { - if (ip != 1 || !bp || fp != 1.0 || dp != 1.0 || sp != 1 || lp != 1 || byParam != 1) { - throw new AssertionError("params not 1/true"); - } - if (rowCount.intValue() >= 1) { - rs.addRow(0, "Hello"); - } - if (rowCount.intValue() >= 2) { - rs.addRow(1, "World"); - } - } - return rs; - } - - /** - * This method is called via reflection from the database. - * - * @param value the value - * @return the square root - */ - public static int root(int value) { - if (value < 0) { - TestBase.logError("function called but should not", null); - } - return (int) Math.sqrt(value); - } - - /** - * This method is called via reflection from the database. - * - * @return 1 - */ - public static double mean() { - return 1; - } - - /** - * This method is called via reflection from the database. - * - * @param dec the value - * @return the value - */ - public static BigDecimal noOp(BigDecimal dec) { - return dec; - } - - /** - * This method is called via reflection from the database. - * - * @return the count - */ - public static int getCount() { - return count++; - } - - private static void setCount(int newCount) { - count = newCount; - } - - /** - * This method is called via reflection from the database. - * - * @param s the string - * @return the string, reversed - */ - public static String reverse(String s) { - return new StringBuilder(s).reverse().toString(); - } - - /** - * This method is called via reflection from the database. - * - * @param values the values - * @return the mean value - */ -//## Java 1.5 begin ## - public static double mean(double... values) { - double sum = 0; - for (double x : values) { - sum += x; - } - return sum / values.length; - } -//## Java 1.5 end ## - - /** - * This method is called via reflection from the database. - * - * @param conn the connection - * @param values the values - * @return the mean value - */ -//## Java 1.5 begin ## - public static double mean2(Connection conn, double... values) { - conn.getClass(); - double sum = 0; - for (double x : values) { - sum += x; - } - return sum / values.length; - } -//## Java 1.5 end ## - - /** - * This method is called via reflection from the database. - * - * @param prefix the print prefix - * @param values the values - * @return the text - */ -//## Java 1.5 begin ## - public static String printMean(String prefix, double... values) { - double sum = 0; - for (double x : values) { - sum += x; - } - return prefix + ": " + (int) (sum / values.length); - } -//## Java 1.5 end ## - - /** - * This method is called via reflection from the database. - * - * @param a the first UUID - * @param b the second UUID - * @return a xor b - */ - public static UUID xorUUID(UUID a, UUID b) { - return new UUID(a.getMostSignificantBits() ^ b.getMostSignificantBits(), - a.getLeastSignificantBits() ^ b.getLeastSignificantBits()); - } - - /** - * This method is called via reflection from the database. - * - * @param args the argument list - * @return an array of one element - */ - public static Object[] dynamic(Object[] args) { - StringBuilder buff = new StringBuilder(); - for (Object a : args) { - buff.append(a); - } - return new Object[] { buff.toString() }; - } - - public void add(Object value) { - // ignore - } - - public Object getResult() { - return new BigDecimal("1.6"); - } - - public int getType(int[] inputTypes) { - if (inputTypes.length != 1 || inputTypes[0] != Types.INTEGER) { - throw new RuntimeException("unexpected data type"); - } - return Types.DECIMAL; - } - - public void init(Connection conn) { - // ignore - } - -} diff --git a/tools/h2/src/test/org/h2/test/db/TestIndex.java b/tools/h2/src/test/org/h2/test/db/TestIndex.java deleted file mode 100755 index b916fba..0000000 --- a/tools/h2/src/test/org/h2/test/db/TestIndex.java +++ /dev/null @@ -1,473 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.test.db; - -import java.sql.Connection; -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.sql.Statement; -import java.util.HashMap; -import java.util.Random; - -import org.h2.result.SortOrder; -import org.h2.test.TestBase; -import org.h2.util.New; - -/** - * Index tests. - */ -public class TestIndex extends TestBase { - - private Connection conn; - private Statement stat; - private Random random = new Random(); - - /** - * Run just this test. - * - * @param a ignored - */ - public static void main(String... a) throws Exception { - TestBase.createCaller().init().test(); - } - - public void test() throws SQLException { - deleteDb("index"); - testNonUniqueHashIndex(); - testRenamePrimaryKey(); - testRandomized(); - testDescIndex(); - testHashIndex(); - - if (config.networked && config.big) { - return; - } - - random.setSeed(100); - - deleteDb("index"); - testWideIndex(147); - testWideIndex(313); - testWideIndex(979); - testWideIndex(1200); - testWideIndex(2400); - if (config.big) { - Random r = new Random(); - for (int j = 0; j < 10; j++) { - int i = r.nextInt(3000); - if ((i % 100) == 0) { - println("width: " + i); - } - testWideIndex(i); - } - } - - testLike(); - reconnect(); - testConstraint(); - testLargeIndex(); - testMultiColumnIndex(); - // long time; - // time = System.currentTimeMillis(); - testHashIndex(true, false); - - testHashIndex(false, false); - // System.out.println("b-tree="+(System.currentTimeMillis()-time)); - // time = System.currentTimeMillis(); - testHashIndex(true, true); - testHashIndex(false, true); - // System.out.println("hash="+(System.currentTimeMillis()-time)); - - testMultiColumnHashIndex(); - - conn.close(); - deleteDb("index"); - } - - private void testNonUniqueHashIndex() throws SQLException { - reconnect(); - stat.execute("create memory table test(id bigint, data bigint)"); - stat.execute("create hash index on test(id)"); - Random rand = new Random(1); - PreparedStatement prepInsert = conn.prepareStatement("insert into test values(?, ?)"); - PreparedStatement prepDelete = conn.prepareStatement("delete from test where id=?"); - PreparedStatement prepSelect = conn.prepareStatement("select count(*) from test where id=?"); - HashMap map = New.hashMap(); - for (int i = 0; i < 1000; i++) { - long key = rand.nextInt(10) * 1000000000L; - Integer r = map.get(key); - int result = r == null ? 0 : (int) r; - if (rand.nextBoolean()) { - prepSelect.setLong(1, key); - ResultSet rs = prepSelect.executeQuery(); - rs.next(); - assertEquals(result, rs.getInt(1)); - } else { - if (rand.nextBoolean()) { - prepInsert.setLong(1, key); - prepInsert.setInt(2, rand.nextInt()); - prepInsert.execute(); - map.put(key, result + 1); - } else { - prepDelete.setLong(1, key); - prepDelete.execute(); - map.put(key, 0); - } - } - } - stat.execute("drop table test"); - conn.close(); - } - - private void testRenamePrimaryKey() throws SQLException { - if (config.memory) { - return; - } - reconnect(); - stat.execute("create table test(id int not null)"); - stat.execute("alter table test add constraint x primary key(id)"); - ResultSet rs; - rs = conn.getMetaData().getIndexInfo(null, null, "TEST", true, false); - rs.next(); - String old = rs.getString("INDEX_NAME"); - stat.execute("alter index " + old + " rename to y"); - rs = conn.getMetaData().getIndexInfo(null, null, "TEST", true, false); - rs.next(); - assertEquals("Y", rs.getString("INDEX_NAME")); - reconnect(); - rs = conn.getMetaData().getIndexInfo(null, null, "TEST", true, false); - rs.next(); - assertEquals("Y", rs.getString("INDEX_NAME")); - stat.execute("drop table test"); - } - - private void testRandomized() throws SQLException { - boolean reopen = !config.memory; - Random rand = new Random(1); - reconnect(); - stat.execute("drop all objects"); - stat.execute("CREATE TABLE TEST(ID identity)"); - int len = getSize(100, 1000); - for (int i = 0; i < len; i++) { - switch (rand.nextInt(4)) { - case 0: - if (rand.nextInt(10) == 0) { - if (reopen) { - trace("reconnect"); - reconnect(); - } - } - break; - case 1: - trace("insert"); - stat.execute("insert into test(id) values(null)"); - break; - case 2: - trace("delete"); - stat.execute("delete from test"); - break; - case 3: - trace("insert 1-100"); - stat.execute("insert into test select null from system_range(1, 100)"); - break; - } - } - stat.execute("drop table test"); - } - - private void testHashIndex() throws SQLException { - reconnect(); - stat.execute("create table testA(id int primary key, name varchar)"); - stat.execute("create table testB(id int primary key hash, name varchar)"); - int len = getSize(300, 3000); - stat.execute("insert into testA select x, 'Hello' from system_range(1, " + len + ")"); - stat.execute("insert into testB select x, 'Hello' from system_range(1, " + len + ")"); - Random rand = new Random(1); - for (int i = 0; i < len; i++) { - int x = rand.nextInt(len); - String sql = ""; - switch(rand.nextInt(3)) { - case 0: - sql = "delete from testA where id = " + x; - break; - case 1: - sql = "update testA set name = " + rand.nextInt(100) + " where id = " + x; - break; - case 2: - sql = "select name from testA where id = " + x; - break; - default: - } - boolean result = stat.execute(sql); - if (result) { - ResultSet rs = stat.getResultSet(); - String s1 = rs.next() ? rs.getString(1) : null; - rs = stat.executeQuery(sql.replace('A', 'B')); - String s2 = rs.next() ? rs.getString(1) : null; - assertEquals(s1, s2); - } else { - int count1 = stat.getUpdateCount(); - int count2 = stat.executeUpdate(sql.replace('A', 'B')); - assertEquals(count1, count2); - } - } - stat.execute("drop table testA, testB"); - conn.close(); - } - - private void reconnect() throws SQLException { - if (conn != null) { - conn.close(); - conn = null; - } - conn = getConnection("index"); - stat = conn.createStatement(); - } - - private void testDescIndex() throws SQLException { - if (config.memory) { - return; - } - ResultSet rs; - reconnect(); - stat.execute("CREATE TABLE TEST(ID INT)"); - stat.execute("CREATE INDEX IDX_ND ON TEST(ID DESC)"); - rs = conn.getMetaData().getIndexInfo(null, null, "TEST", false, false); - rs.next(); - assertEquals("D", rs.getString("ASC_OR_DESC")); - assertEquals(SortOrder.DESCENDING, rs.getInt("SORT_TYPE")); - stat.execute("INSERT INTO TEST SELECT X FROM SYSTEM_RANGE(1, 30)"); - rs = stat.executeQuery("SELECT COUNT(*) FROM TEST WHERE ID BETWEEN 10 AND 20"); - rs.next(); - assertEquals(11, rs.getInt(1)); - reconnect(); - rs = conn.getMetaData().getIndexInfo(null, null, "TEST", false, false); - rs.next(); - assertEquals("D", rs.getString("ASC_OR_DESC")); - assertEquals(SortOrder.DESCENDING, rs.getInt("SORT_TYPE")); - rs = stat.executeQuery("SELECT COUNT(*) FROM TEST WHERE ID BETWEEN 10 AND 20"); - rs.next(); - assertEquals(11, rs.getInt(1)); - stat.execute("DROP TABLE TEST"); - - stat.execute("create table test(x int, y int)"); - stat.execute("insert into test values(1, 1), (1, 2)"); - stat.execute("create index test_x_y on test (x desc, y desc)"); - rs = stat.executeQuery("select * from test where x=1 and y<2"); - assertTrue(rs.next()); - - conn.close(); - } - - private String getRandomString(int len) { - StringBuilder buff = new StringBuilder(); - for (int i = 0; i < len; i++) { - buff.append((char) ('a' + random.nextInt(26))); - } - return buff.toString(); - } - - private void testWideIndex(int length) throws SQLException { - reconnect(); - stat.execute("drop all objects"); - stat.execute("CREATE TABLE TEST(ID INT, NAME VARCHAR)"); - stat.execute("CREATE INDEX IDXNAME ON TEST(NAME)"); - for (int i = 0; i < 100; i++) { - stat.execute("INSERT INTO TEST VALUES(" + i + ", SPACE(" + length + ") || " + i + " )"); - } - ResultSet rs = stat.executeQuery("SELECT * FROM TEST ORDER BY NAME"); - while (rs.next()) { - int id = rs.getInt("ID"); - String name = rs.getString("NAME"); - assertEquals("" + id, name.trim()); - } - if (!config.memory) { - reconnect(); - rs = stat.executeQuery("SELECT * FROM TEST ORDER BY NAME"); - while (rs.next()) { - int id = rs.getInt("ID"); - String name = rs.getString("NAME"); - assertEquals("" + id, name.trim()); - } - } - stat.execute("drop all objects"); - } - - private void testLike() throws SQLException { - reconnect(); - stat.execute("CREATE TABLE ABC(ID INT, NAME VARCHAR)"); - stat.execute("INSERT INTO ABC VALUES(1, 'Hello')"); - PreparedStatement prep = conn.prepareStatement("SELECT * FROM ABC WHERE NAME LIKE CAST(? AS VARCHAR)"); - prep.setString(1, "Hi%"); - prep.execute(); - stat.execute("DROP TABLE ABC"); - } - - private void testConstraint() throws SQLException { - if (config.memory) { - return; - } - stat.execute("CREATE TABLE PARENT(ID INT PRIMARY KEY)"); - stat.execute("CREATE TABLE CHILD(ID INT PRIMARY KEY, PID INT, FOREIGN KEY(PID) REFERENCES PARENT(ID))"); - reconnect(); - stat.execute("DROP TABLE PARENT"); - stat.execute("DROP TABLE CHILD"); - } - - private void testLargeIndex() throws SQLException { - random.setSeed(10); - for (int i = 1; i < 100; i += getSize(1000, 7)) { - stat.execute("DROP TABLE IF EXISTS TEST"); - stat.execute("CREATE TABLE TEST(NAME VARCHAR(" + i + "))"); - stat.execute("CREATE INDEX IDXNAME ON TEST(NAME)"); - PreparedStatement prep = conn.prepareStatement("INSERT INTO TEST VALUES(?)"); - for (int j = 0; j < getSize(2, 5); j++) { - prep.setString(1, getRandomString(i)); - prep.execute(); - } - if (!config.memory) { - conn.close(); - conn = getConnection("index"); - stat = conn.createStatement(); - } - ResultSet rs = stat.executeQuery("SELECT COUNT(*) FROM TEST WHERE NAME > 'mdd'"); - rs.next(); - int count = rs.getInt(1); - trace(i + " count=" + count); - } - - stat.execute("DROP TABLE IF EXISTS TEST"); - } - - private void testHashIndex(boolean primaryKey, boolean hash) throws SQLException { - if (config.memory) { - return; - } - - reconnect(); - - stat.execute("DROP TABLE IF EXISTS TEST"); - if (primaryKey) { - stat.execute("CREATE TABLE TEST(A INT PRIMARY KEY " + (hash ? "HASH" : "") + ", B INT)"); - } else { - stat.execute("CREATE TABLE TEST(A INT, B INT)"); - stat.execute("CREATE UNIQUE " + (hash ? "HASH" : "") + " INDEX ON TEST(A)"); - } - PreparedStatement prep; - prep = conn.prepareStatement("INSERT INTO TEST VALUES(?, ?)"); - int len = getSize(5, 1000); - for (int a = 0; a < len; a++) { - prep.setInt(1, a); - prep.setInt(2, a); - prep.execute(); - assertEquals(1, getValue("SELECT COUNT(*) FROM TEST WHERE A=" + a)); - assertEquals(0, getValue("SELECT COUNT(*) FROM TEST WHERE A=-1-" + a)); - } - - reconnect(); - - prep = conn.prepareStatement("DELETE FROM TEST WHERE A=?"); - for (int a = 0; a < len; a++) { - if (getValue("SELECT COUNT(*) FROM TEST WHERE A=" + a) != 1) { - assertEquals(1, getValue("SELECT COUNT(*) FROM TEST WHERE A=" + a)); - } - prep.setInt(1, a); - assertEquals(1, prep.executeUpdate()); - } - assertEquals(0, getValue("SELECT COUNT(*) FROM TEST")); - } - - private void testMultiColumnIndex() throws SQLException { - stat.execute("DROP TABLE IF EXISTS TEST"); - stat.execute("CREATE TABLE TEST(A INT, B INT)"); - PreparedStatement prep; - prep = conn.prepareStatement("INSERT INTO TEST VALUES(?, ?)"); - int len = getSize(3, 260); - for (int a = 0; a < len; a++) { - prep.setInt(1, a); - prep.setInt(2, a); - prep.execute(); - } - stat.execute("INSERT INTO TEST SELECT A, B FROM TEST"); - stat.execute("CREATE INDEX ON TEST(A, B)"); - prep = conn.prepareStatement("DELETE FROM TEST WHERE A=?"); - for (int a = 0; a < len; a++) { - log("SELECT * FROM TEST"); - assertEquals(2, getValue("SELECT COUNT(*) FROM TEST WHERE A=" + (len - a - 1))); - assertEquals((len - a) * 2, getValue("SELECT COUNT(*) FROM TEST")); - prep.setInt(1, len - a - 1); - prep.execute(); - } - assertEquals(0, getValue("SELECT COUNT(*) FROM TEST")); - } - - private void testMultiColumnHashIndex() throws SQLException { - if (config.memory) { - return; - } - - stat.execute("DROP TABLE IF EXISTS TEST"); - stat.execute("CREATE TABLE TEST(A INT, B INT, DATA VARCHAR(255))"); - stat.execute("CREATE UNIQUE HASH INDEX IDX_AB ON TEST(A, B)"); - PreparedStatement prep; - prep = conn.prepareStatement("INSERT INTO TEST VALUES(?, ?, ?)"); - // speed is quadratic (len*len) - int len = getSize(2, 14); - for (int a = 0; a < len; a++) { - for (int b = 0; b < len; b += 2) { - prep.setInt(1, a); - prep.setInt(2, b); - prep.setString(3, "i(" + a + "," + b + ")"); - prep.execute(); - } - } - - reconnect(); - - prep = conn.prepareStatement("UPDATE TEST SET DATA=DATA||? WHERE A=? AND B=?"); - for (int a = 0; a < len; a++) { - for (int b = 0; b < len; b += 2) { - prep.setString(1, "u(" + a + "," + b + ")"); - prep.setInt(2, a); - prep.setInt(3, b); - prep.execute(); - } - } - - reconnect(); - - ResultSet rs = stat.executeQuery("SELECT * FROM TEST WHERE DATA <> 'i('||a||','||b||')u('||a||','||b||')'"); - assertFalse(rs.next()); - assertEquals(len * (len / 2), getValue("SELECT COUNT(*) FROM TEST")); - stat.execute("DROP TABLE TEST"); - } - - private int getValue(String sql) throws SQLException { - ResultSet rs = stat.executeQuery(sql); - rs.next(); - return rs.getInt(1); - } - - private void log(String sql) throws SQLException { - trace(sql); - ResultSet rs = stat.executeQuery(sql); - int cols = rs.getMetaData().getColumnCount(); - while (rs.next()) { - StringBuilder buff = new StringBuilder(); - for (int i = 0; i < cols; i++) { - if (i > 0) { - buff.append(", "); - } - buff.append("[" + i + "]=" + rs.getString(i + 1)); - } - trace(buff.toString()); - } - trace("---done---"); - } - -} diff --git a/tools/h2/src/test/org/h2/test/db/TestLargeBlob.java b/tools/h2/src/test/org/h2/test/db/TestLargeBlob.java deleted file mode 100755 index c457dd7..0000000 --- a/tools/h2/src/test/org/h2/test/db/TestLargeBlob.java +++ /dev/null @@ -1,84 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.test.db; - -import java.io.InputStream; -import java.sql.Connection; -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.Statement; -import org.h2.test.TestBase; - -/** - * Test a BLOB larger than Integer.MAX_VALUE - */ -public class TestLargeBlob extends TestBase { - - /** - * Run just this test. - * - * @param a ignored - */ - public static void main(String... a) throws Exception { - TestBase.createCaller().init().test(); - } - - public void test() throws Exception { - if (!config.big || config.memory || config.mvcc || config.networked) { - return; - } - - deleteDb("largeBlob"); - String url = getURL("largeBlob;TRACE_LEVEL_FILE=0", true); - Connection conn = getConnection(url); - final long testLength = Integer.MAX_VALUE + 110L; - Statement stat = conn.createStatement(); - stat.execute("set COMPRESS_LOB LZF"); - stat.execute("create table test(x blob)"); - PreparedStatement prep = conn.prepareStatement( - "insert into test values(?)"); - prep.setBinaryStream(1, new InputStream() { - long remaining = testLength; - int p; - byte[] oneByte = { 0 }; - public void close() { - // ignore - } - public int read(byte[] buff, int off, int len) { - len = (int) Math.min(remaining, len); - remaining -= len; - if (p++ % 5000 == 0) { - println("" + remaining); - } - return len == 0 ? -1 : len; - } - public int read() { - return read(oneByte, 0, 1) < 0 ? -1 : oneByte[0]; - } - }, -1); - prep.executeUpdate(); - ResultSet rs = stat.executeQuery( - "select length(x) from test"); - rs.next(); - assertEquals(testLength, rs.getLong(1)); - rs = stat.executeQuery("select x from test"); - rs.next(); - InputStream in = rs.getBinaryStream(1); - byte[] buff = new byte[4 * 1024]; - long length = 0; - while (true) { - int len = in.read(buff); - if (len < 0) { - break; - } - length += len; - } - assertEquals(testLength, length); - conn.close(); - } - -} diff --git a/tools/h2/src/test/org/h2/test/db/TestLinkedTable.java b/tools/h2/src/test/org/h2/test/db/TestLinkedTable.java deleted file mode 100755 index c87dfec..0000000 --- a/tools/h2/src/test/org/h2/test/db/TestLinkedTable.java +++ /dev/null @@ -1,635 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.test.db; - -import java.io.File; -import java.math.BigDecimal; -import java.sql.Connection; -import java.sql.DriverManager; -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.ResultSetMetaData; -import java.sql.SQLException; -import java.sql.Statement; -import java.sql.Timestamp; -import org.h2.constant.SysProperties; -import org.h2.test.TestBase; - -/** - * Tests the linked table feature (CREATE LINKED TABLE). - */ -public class TestLinkedTable extends TestBase { - - /** - * Run just this test. - * - * @param a ignored - */ - public static void main(String... a) throws Exception { - TestBase.createCaller().init().test(); - } - - public void test() throws SQLException { - testDefaultValues(); - testHiddenSQL(); - // testLinkAutoAdd(); - testNestedQueriesToSameTable(); - testSharedConnection(); - testMultipleSchemas(); - testReadOnlyLinkedTable(); - testLinkOtherSchema(); - testLinkDrop(); - testLinkSchema(); - testLinkEmitUpdates(); - testLinkTable(); - testLinkTwoTables(); - testCachingResults(); - testLinkedTableInReadOnlyDb(); - - deleteDb("linkedTable"); - } - - private void testDefaultValues() throws SQLException { - if (config.memory) { - return; - } - deleteDb("linkedTable"); - Connection connMain = DriverManager.getConnection("jdbc:h2:mem:linkedTable"); - Statement statMain = connMain.createStatement(); - statMain.execute("create table test(id identity, name varchar default 'test')"); - - Connection conn = getConnection("linkedTable"); - Statement stat = conn.createStatement(); - stat.execute("create linked table test1('', 'jdbc:h2:mem:linkedTable', '', '', 'TEST') emit updates"); - stat.execute("create linked table test2('', 'jdbc:h2:mem:linkedTable', '', '', 'TEST')"); - stat.execute("insert into test1 values(default, default)"); - stat.execute("insert into test2 values(default, default)"); - stat.execute("merge into test2 values(3, default)"); - stat.execute("update test1 set name=default where id=1"); - stat.execute("update test2 set name=default where id=2"); - - ResultSet rs = statMain.executeQuery("select * from test order by id"); - rs.next(); - assertEquals(1, rs.getInt(1)); - assertEquals("test", rs.getString(2)); - rs.next(); - assertEquals(2, rs.getInt(1)); - assertEquals("test", rs.getString(2)); - rs.next(); - assertEquals(3, rs.getInt(1)); - assertEquals("test", rs.getString(2)); - assertFalse(rs.next()); - - stat.execute("delete from test1 where id=1"); - stat.execute("delete from test2 where id=2"); - stat.execute("delete from test2 where id=3"); - conn.close(); - rs = statMain.executeQuery("select * from test order by id"); - assertFalse(rs.next()); - - connMain.close(); - } - - private void testHiddenSQL() throws SQLException { - if (config.memory || !SysProperties.SHARE_LINKED_CONNECTIONS) { - return; - } - org.h2.Driver.load(); - deleteDb("linkedTable"); - Connection conn = getConnection("linkedTable"); - try { - conn.createStatement().execute( - "create linked table test(null, 'jdbc:h2:mem:', 'sa', 'pwd', 'DUAL2')"); - fail(); - } catch (SQLException e) { - assertTrue(e.toString().indexOf("pwd") >= 0); - } - try { - conn.createStatement().execute( - "create linked table test(null, 'jdbc:h2:mem:', 'sa', 'pwd', 'DUAL2') --hide--"); - fail(); - } catch (SQLException e) { - assertTrue(e.toString().indexOf("pwd") < 0); - } - conn.close(); - } - - // this is not a bug, it is the documented behavior -// private void testLinkAutoAdd() throws SQLException { -// Class.forName("org.h2.Driver"); -// Connection ca = -// DriverManager.getConnection("jdbc:h2:mem:one", "sa", "sa"); -// Connection cb = -// DriverManager.getConnection("jdbc:h2:mem:two", "sa", "sa"); -// Statement sa = ca.createStatement(); -// Statement sb = cb.createStatement(); -// sa.execute("CREATE TABLE ONE (X NUMBER)"); -// sb.execute( -// "CALL LINK_SCHEMA('GOOD', '', " + -// "'jdbc:h2:mem:one', 'sa', 'sa', 'PUBLIC'); "); -// sb.executeQuery("SELECT * FROM GOOD.ONE"); -// sa.execute("CREATE TABLE TWO (X NUMBER)"); -// sb.executeQuery("SELECT * FROM GOOD.TWO"); // FAILED -// ca.close(); -// cb.close(); -// } - - private void testNestedQueriesToSameTable() throws SQLException { - if (config.memory || !SysProperties.SHARE_LINKED_CONNECTIONS) { - return; - } - org.h2.Driver.load(); - deleteDb("linkedTable"); - String url = getURL("linkedTable", true); - String user = getUser(); - String password = getPassword(); - Connection ca = getConnection(url, user, password); - Statement sa = ca.createStatement(); - sa.execute("CREATE TABLE TEST(ID INT) AS SELECT 1"); - ca.close(); - Connection cb = DriverManager.getConnection("jdbc:h2:mem:two", "sa", "sa"); - Statement sb = cb.createStatement(); - sb.execute("CREATE LINKED TABLE T1(NULL, '" + url + "', '"+user+"', '"+password+"', 'TEST')"); - sb.executeQuery("SELECT * FROM DUAL A LEFT OUTER JOIN T1 A ON A.ID=1 LEFT OUTER JOIN T1 B ON B.ID=1"); - sb.execute("DROP ALL OBJECTS"); - cb.close(); - } - - private void testSharedConnection() throws SQLException { - if (config.memory || !SysProperties.SHARE_LINKED_CONNECTIONS) { - return; - } - org.h2.Driver.load(); - deleteDb("linkedTable"); - String url = getURL("linkedTable", true); - String user = getUser(); - String password = getPassword(); - Connection ca = getConnection(url, user, password); - Statement sa = ca.createStatement(); - sa.execute("CREATE TABLE TEST(ID INT)"); - ca.close(); - Connection cb = DriverManager.getConnection("jdbc:h2:mem:two", "sa", "sa"); - Statement sb = cb.createStatement(); - sb.execute("CREATE LINKED TABLE T1(NULL, '" + url + ";OPEN_NEW=TRUE', '"+user+"', '"+password+"', 'TEST')"); - sb.execute("CREATE LINKED TABLE T2(NULL, '" + url + ";OPEN_NEW=TRUE', '"+user+"', '"+password+"', 'TEST')"); - sb.execute("DROP ALL OBJECTS"); - cb.close(); - } - - private void testMultipleSchemas() throws SQLException { - org.h2.Driver.load(); - Connection ca = DriverManager.getConnection("jdbc:h2:mem:one", "sa", "sa"); - Connection cb = DriverManager.getConnection("jdbc:h2:mem:two", "sa", "sa"); - Statement sa = ca.createStatement(); - Statement sb = cb.createStatement(); - sa.execute("CREATE TABLE TEST(ID INT)"); - sa.execute("CREATE SCHEMA P"); - sa.execute("CREATE TABLE P.TEST(X INT)"); - sa.execute("INSERT INTO TEST VALUES(1)"); - sa.execute("INSERT INTO P.TEST VALUES(2)"); - try { - sb.execute("CREATE LINKED TABLE T(NULL, 'jdbc:h2:mem:one', 'sa', 'sa', 'TEST')"); - fail(); - } catch (SQLException e) { - assertKnownException(e); - } - sb.execute("CREATE LINKED TABLE T(NULL, 'jdbc:h2:mem:one', 'sa', 'sa', 'PUBLIC', 'TEST')"); - sb.execute("CREATE LINKED TABLE T2(NULL, 'jdbc:h2:mem:one', 'sa', 'sa', 'P', 'TEST')"); - assertSingleValue(sb, "SELECT * FROM T", 1); - assertSingleValue(sb, "SELECT * FROM T2", 2); - sa.execute("DROP ALL OBJECTS"); - sb.execute("DROP ALL OBJECTS"); - try { - assertSingleValue(sa, "SELECT * FROM TEST", 0); - fail(); - } catch (SQLException e) { - assertKnownException(e); - } - ca.close(); - cb.close(); - } - - private void testReadOnlyLinkedTable() throws SQLException { - org.h2.Driver.load(); - Connection ca = DriverManager.getConnection("jdbc:h2:mem:one", "sa", "sa"); - Connection cb = DriverManager.getConnection("jdbc:h2:mem:two", "sa", "sa"); - Statement sa = ca.createStatement(); - Statement sb = cb.createStatement(); - sa.execute("CREATE TABLE TEST(ID INT)"); - sa.execute("INSERT INTO TEST VALUES(1)"); - String[] suffix = {"", "READONLY", "EMIT UPDATES"}; - for (int i = 0; i < suffix.length; i++) { - String sql = "CREATE LINKED TABLE T(NULL, 'jdbc:h2:mem:one', 'sa', 'sa', 'TEST')" + suffix[i]; - sb.execute(sql); - sb.executeQuery("SELECT * FROM T"); - String[] update = {"DELETE FROM T", "INSERT INTO T VALUES(2)", "UPDATE T SET ID = 3"}; - for (String u : update) { - try { - sb.execute(u); - if (i == 1) { - fail(); - } - } catch (SQLException e) { - if (i == 1) { - assertKnownException(e); - } else { - throw e; - } - } - } - sb.execute("DROP TABLE T"); - } - ca.close(); - cb.close(); - } - - private void testLinkOtherSchema() throws SQLException { - org.h2.Driver.load(); - Connection ca = DriverManager.getConnection("jdbc:h2:mem:one", "sa", "sa"); - Connection cb = DriverManager.getConnection("jdbc:h2:mem:two", "sa", "sa"); - Statement sa = ca.createStatement(); - Statement sb = cb.createStatement(); - sa.execute("CREATE TABLE GOOD (X NUMBER)"); - sa.execute("CREATE SCHEMA S"); - sa.execute("CREATE TABLE S.BAD (X NUMBER)"); - sb.execute("CALL LINK_SCHEMA('G', '', 'jdbc:h2:mem:one', 'sa', 'sa', 'PUBLIC'); "); - sb.execute("CALL LINK_SCHEMA('B', '', 'jdbc:h2:mem:one', 'sa', 'sa', 'S'); "); - // OK - sb.executeQuery("SELECT * FROM G.GOOD"); - // FAILED - sb.executeQuery("SELECT * FROM B.BAD"); - ca.close(); - cb.close(); - } - - private void testLinkTwoTables() throws SQLException { - org.h2.Driver.load(); - Connection conn = DriverManager.getConnection("jdbc:h2:mem:one", "sa", "sa"); - Statement stat = conn.createStatement(); - stat.execute("CREATE SCHEMA Y"); - stat.execute("CREATE TABLE A( C INT)"); - stat.execute("INSERT INTO A VALUES(1)"); - stat.execute("CREATE TABLE Y.A (C INT)"); - stat.execute("INSERT INTO Y.A VALUES(2)"); - Connection conn2 = DriverManager.getConnection("jdbc:h2:mem:two"); - Statement stat2 = conn2.createStatement(); - stat2.execute("CREATE LINKED TABLE one('org.h2.Driver', 'jdbc:h2:mem:one', 'sa', 'sa', 'Y.A');"); - stat2.execute("CREATE LINKED TABLE two('org.h2.Driver', 'jdbc:h2:mem:one', 'sa', 'sa', 'PUBLIC.A');"); - ResultSet rs = stat2.executeQuery("SELECT * FROM one"); - rs.next(); - assertEquals(2, rs.getInt(1)); - rs = stat2.executeQuery("SELECT * FROM two"); - rs.next(); - assertEquals(1, rs.getInt(1)); - conn.close(); - conn2.close(); - } - - private void testLinkDrop() throws SQLException { - org.h2.Driver.load(); - Connection connA = DriverManager.getConnection("jdbc:h2:mem:a"); - Statement statA = connA.createStatement(); - statA.execute("CREATE TABLE TEST(ID INT)"); - Connection connB = DriverManager.getConnection("jdbc:h2:mem:b"); - Statement statB = connB.createStatement(); - statB.execute("CREATE LINKED TABLE TEST_LINK('', 'jdbc:h2:mem:a', '', '', 'TEST')"); - connA.close(); - // the connection should be closed now - // (and the table should disappear because the last connection was - // closed) - statB.execute("DROP TABLE TEST_LINK"); - connA = DriverManager.getConnection("jdbc:h2:mem:a"); - statA = connA.createStatement(); - // table should not exist now - statA.execute("CREATE TABLE TEST(ID INT)"); - connA.close(); - connB.close(); - } - - private void testLinkEmitUpdates() throws SQLException { - if (config.memory || config.networked) { - return; - } - - deleteDb("linked1"); - deleteDb("linked2"); - org.h2.Driver.load(); - - String url1 = getURL("linked1", true); - String url2 = getURL("linked2", true); - - Connection conn = DriverManager.getConnection(url1, "sa1", "abc abc"); - Statement stat = conn.createStatement(); - stat.execute("CREATE TABLE TEST(ID INT PRIMARY KEY, NAME VARCHAR)"); - - Connection conn2 = DriverManager.getConnection(url2, "sa2", "def def"); - Statement stat2 = conn2.createStatement(); - String link = "CREATE LINKED TABLE TEST_LINK_U('', '" + url1 - + "', 'sa1', 'abc abc', 'TEST') EMIT UPDATES"; - stat2.execute(link); - link = "CREATE LINKED TABLE TEST_LINK_DI('', '" + url1 + "', 'sa1', 'abc abc', 'TEST')"; - stat2.execute(link); - stat2.executeUpdate("INSERT INTO TEST_LINK_U VALUES(1, 'Hello')"); - stat2.executeUpdate("INSERT INTO TEST_LINK_DI VALUES(2, 'World')"); - try { - stat2.executeUpdate("UPDATE TEST_LINK_U SET ID=ID+1"); - fail(); - } catch (SQLException e) { - assertKnownException(e); - } - stat2.executeUpdate("UPDATE TEST_LINK_DI SET ID=ID+1"); - stat2.executeUpdate("UPDATE TEST_LINK_U SET NAME=NAME || ID"); - ResultSet rs; - - rs = stat2.executeQuery("SELECT * FROM TEST_LINK_DI ORDER BY ID"); - rs.next(); - assertEquals(2, rs.getInt(1)); - assertEquals("Hello2", rs.getString(2)); - rs.next(); - assertEquals(3, rs.getInt(1)); - assertEquals("World3", rs.getString(2)); - assertFalse(rs.next()); - - rs = stat2.executeQuery("SELECT * FROM TEST_LINK_U ORDER BY ID"); - rs.next(); - assertEquals(2, rs.getInt(1)); - assertEquals("Hello2", rs.getString(2)); - rs.next(); - assertEquals(3, rs.getInt(1)); - assertEquals("World3", rs.getString(2)); - assertFalse(rs.next()); - - rs = stat.executeQuery("SELECT * FROM TEST ORDER BY ID"); - rs.next(); - assertEquals(2, rs.getInt(1)); - assertEquals("Hello2", rs.getString(2)); - rs.next(); - assertEquals(3, rs.getInt(1)); - assertEquals("World3", rs.getString(2)); - assertFalse(rs.next()); - - conn.close(); - conn2.close(); - } - - private void testLinkSchema() throws SQLException { - if (config.memory || config.networked) { - return; - } - - deleteDb("linked1"); - deleteDb("linked2"); - org.h2.Driver.load(); - String url1 = getURL("linked1", true); - String url2 = getURL("linked2", true); - - Connection conn = DriverManager.getConnection(url1, "sa1", "abc abc"); - Statement stat = conn.createStatement(); - stat.execute("CREATE TABLE TEST1(ID INT PRIMARY KEY)"); - - Connection conn2 = DriverManager.getConnection(url2, "sa2", "def def"); - Statement stat2 = conn2.createStatement(); - String link = "CALL LINK_SCHEMA('LINKED', '', '" + url1 + "', 'sa1', 'abc abc', 'PUBLIC')"; - stat2.execute(link); - stat2.executeQuery("SELECT * FROM LINKED.TEST1"); - - stat.execute("CREATE TABLE TEST2(ID INT PRIMARY KEY)"); - stat2.execute(link); - stat2.executeQuery("SELECT * FROM LINKED.TEST1"); - stat2.executeQuery("SELECT * FROM LINKED.TEST2"); - - conn.close(); - conn2.close(); - } - - private void testLinkTable() throws SQLException { - if (config.memory || config.networked) { - return; - } - - deleteDb("linked1"); - deleteDb("linked2"); - org.h2.Driver.load(); - - String url1 = getURL("linked1", true); - String url2 = getURL("linked2", true); - - Connection conn = DriverManager.getConnection(url1, "sa1", "abc abc"); - Statement stat = conn.createStatement(); - stat.execute("CREATE TEMP TABLE TEST_TEMP(ID INT PRIMARY KEY)"); - stat.execute("CREATE TABLE TEST(ID INT PRIMARY KEY, NAME VARCHAR(200), XT TINYINT, XD DECIMAL(10,2), XTS TIMESTAMP, XBY BINARY(255), XBO BIT, XSM SMALLINT, XBI BIGINT, XBL BLOB, XDA DATE, XTI TIME, XCL CLOB, XDO DOUBLE)"); - stat.execute("CREATE INDEX IDXNAME ON TEST(NAME)"); - stat.execute("INSERT INTO TEST VALUES(0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL)"); - stat.execute("INSERT INTO TEST VALUES(1, 'Hello', -1, 10.30, '2001-02-03 11:22:33.4455', X'FF0102', TRUE, 3000, 1234567890123456789, X'1122AA', DATE '0002-01-01', TIME '00:00:00', 'J\u00fcrg', 2.25)"); - testRow(stat, "TEST"); - stat.execute("INSERT INTO TEST VALUES(2, 'World', 30, 100.05, '2005-12-31 12:34:56.789', X'FFEECC33', FALSE, 1, -1234567890123456789, X'4455FF', DATE '9999-12-31', TIME '23:59:59', 'George', -2.5)"); - testRow(stat, "TEST"); - stat.execute("SELECT * FROM TEST_TEMP"); - conn.close(); - - conn = DriverManager.getConnection(url1, "sa1", "abc abc"); - stat = conn.createStatement(); - testRow(stat, "TEST"); - try { - stat.execute("SELECT * FROM TEST_TEMP"); - fail("temp table must not be persistent"); - } catch (SQLException e) { - assertKnownException(e); - } - conn.close(); - - conn = DriverManager.getConnection(url2, "sa2", "def def"); - stat = conn.createStatement(); - stat.execute("CREATE LINKED TABLE IF NOT EXISTS LINK_TEST('org.h2.Driver', '" + url1 - + "', 'sa1', 'abc abc', 'TEST')"); - stat.execute("CREATE LINKED TABLE IF NOT EXISTS LINK_TEST('org.h2.Driver', '" + url1 - + "', 'sa1', 'abc abc', 'TEST')"); - testRow(stat, "LINK_TEST"); - ResultSet rs = stat.executeQuery("SELECT * FROM LINK_TEST"); - ResultSetMetaData meta = rs.getMetaData(); - assertEquals(10, meta.getPrecision(1)); - assertEquals(200, meta.getPrecision(2)); - - conn.close(); - conn = DriverManager.getConnection(url2, "sa2", "def def"); - stat = conn.createStatement(); - - stat.execute("INSERT INTO LINK_TEST VALUES(3, 'Link Test', 30, 100.05, '2005-12-31 12:34:56.789', X'FFEECC33', FALSE, 1, -1234567890123456789, X'4455FF', DATE '9999-12-31', TIME '23:59:59', 'George', -2.5)"); - - rs = stat.executeQuery("SELECT COUNT(*) FROM LINK_TEST"); - rs.next(); - assertEquals(4, rs.getInt(1)); - - rs = stat.executeQuery("SELECT COUNT(*) FROM LINK_TEST WHERE NAME='Link Test'"); - rs.next(); - assertEquals(1, rs.getInt(1)); - - int uc = stat.executeUpdate("DELETE FROM LINK_TEST WHERE ID=3"); - assertEquals(1, uc); - - rs = stat.executeQuery("SELECT COUNT(*) FROM LINK_TEST"); - rs.next(); - assertEquals(3, rs.getInt(1)); - - rs = stat.executeQuery("SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME='LINK_TEST'"); - rs.next(); - assertEquals("TABLE LINK", rs.getString("TABLE_TYPE")); - - rs.next(); - rs = stat.executeQuery("SELECT * FROM LINK_TEST WHERE ID=0"); - rs.next(); - assertTrue(rs.getString("NAME") == null && rs.wasNull()); - assertTrue(rs.getString("XT") == null && rs.wasNull()); - assertTrue(rs.getInt("ID") == 0 && !rs.wasNull()); - assertTrue(rs.getBigDecimal("XD") == null && rs.wasNull()); - assertTrue(rs.getTimestamp("XTS") == null && rs.wasNull()); - assertTrue(rs.getBytes("XBY") == null && rs.wasNull()); - assertTrue(!rs.getBoolean("XBO") && rs.wasNull()); - assertTrue(rs.getShort("XSM") == 0 && rs.wasNull()); - assertTrue(rs.getLong("XBI") == 0 && rs.wasNull()); - assertTrue(rs.getString("XBL") == null && rs.wasNull()); - assertTrue(rs.getString("XDA") == null && rs.wasNull()); - assertTrue(rs.getString("XTI") == null && rs.wasNull()); - assertTrue(rs.getString("XCL") == null && rs.wasNull()); - assertTrue(rs.getString("XDO") == null && rs.wasNull()); - assertFalse(rs.next()); - - stat.execute("DROP TABLE LINK_TEST"); - - stat.execute("CREATE LINKED TABLE LINK_TEST('org.h2.Driver', '" + url1 - + "', 'sa1', 'abc abc', '(SELECT COUNT(*) FROM TEST)')"); - rs = stat.executeQuery("SELECT * FROM LINK_TEST"); - rs.next(); - assertEquals(3, rs.getInt(1)); - assertFalse(rs.next()); - - conn.close(); - - deleteDb("linked1"); - deleteDb("linked2"); - } - - private void testRow(Statement stat, String name) throws SQLException { - ResultSet rs = stat.executeQuery("SELECT * FROM " + name + " WHERE ID=1"); - rs.next(); - assertEquals("Hello", rs.getString("NAME")); - assertEquals(-1, rs.getByte("XT")); - BigDecimal bd = rs.getBigDecimal("XD"); - assertTrue(bd.equals(new BigDecimal("10.30"))); - Timestamp ts = rs.getTimestamp("XTS"); - String s = ts.toString(); - assertEquals("2001-02-03 11:22:33.4455", s); - assertTrue(ts.equals(Timestamp.valueOf("2001-02-03 11:22:33.4455"))); - assertEquals(new byte[] { (byte) 255, (byte) 1, (byte) 2 }, rs.getBytes("XBY")); - assertTrue(rs.getBoolean("XBO")); - assertEquals(3000, rs.getShort("XSM")); - assertEquals(1234567890123456789L, rs.getLong("XBI")); - assertEquals("1122aa", rs.getString("XBL")); - assertEquals("0002-01-01", rs.getString("XDA")); - assertEquals("00:00:00", rs.getString("XTI")); - assertEquals("J\u00fcrg", rs.getString("XCL")); - assertEquals("2.25", rs.getString("XDO")); - } - - private void testCachingResults() throws SQLException { - org.h2.Driver.load(); - Connection ca = DriverManager.getConnection("jdbc:h2:mem:one", "sa", "sa"); - Connection cb = DriverManager.getConnection("jdbc:h2:mem:two", "sa", "sa"); - - Statement sa = ca.createStatement(); - Statement sb = cb.createStatement(); - sa.execute("CREATE TABLE TEST(ID VARCHAR)"); - sa.execute("INSERT INTO TEST (ID) VALUES('abc')"); - sb.execute("CREATE LOCAL TEMPORARY LINKED TABLE T(NULL, 'jdbc:h2:mem:one', 'sa', 'sa', 'TEST')"); - - PreparedStatement paData = ca.prepareStatement("select id from TEST where id = ?"); - PreparedStatement pbData = cb.prepareStatement("select id from T where id = ?"); - PreparedStatement paCount = ca.prepareStatement("select count(*) from TEST"); - PreparedStatement pbCount = cb.prepareStatement("select count(*) from T"); - - // Direct query => Result 1 - testCachingResultsCheckResult(paData, 1, "abc"); - testCachingResultsCheckResult(paCount, 1); - - // Via linked table => Result 1 - testCachingResultsCheckResult(pbData, 1, "abc"); - testCachingResultsCheckResult(pbCount, 1); - - sa.execute("INSERT INTO TEST (ID) VALUES('abc')"); - - // Direct query => Result 2 - testCachingResultsCheckResult(paData, 2, "abc"); - testCachingResultsCheckResult(paCount, 2); - - // Via linked table => Result must be 2 - testCachingResultsCheckResult(pbData, 2, "abc"); - testCachingResultsCheckResult(pbCount, 2); - - ca.close(); - cb.close(); - } - - private void testCachingResultsCheckResult(PreparedStatement ps, int expected) throws SQLException { - ResultSet rs = ps.executeQuery(); - rs.next(); - assertEquals(expected, rs.getInt(1)); - } - - private void testCachingResultsCheckResult(PreparedStatement ps, int expected, String value) throws SQLException { - ps.setString(1, value); - ResultSet rs = ps.executeQuery(); - int counter = 0; - while (rs.next()) { - counter++; - String result = rs.getString(1); - assertEquals(result, value); - } - assertEquals(expected, counter); - } - - private void testLinkedTableInReadOnlyDb() throws SQLException { - if (config.memory || config.networked || config.googleAppEngine) { - return; - } - - deleteDb("testLinkedTableInReadOnlyDb"); - org.h2.Driver.load(); - - Connection memConn = DriverManager.getConnection("jdbc:h2:mem:one", "sa", "sa"); - Statement memStat = memConn.createStatement(); - memStat.execute("CREATE TABLE TEST(ID VARCHAR)"); - - String url1 = getURL("testLinkedTableInReadOnlyDb", true); - Connection conn = DriverManager.getConnection(url1, "sa1", "abc abc"); - Statement stat = conn.createStatement(); - stat.execute("CREATE TABLE TEST(ID INT PRIMARY KEY)"); - conn.close(); - - File[] files = new File(getBaseDir()).listFiles(); - for (File file : files) { - if ((file.getName().startsWith("testLinkedTableInReadOnlyDb")) && (!file.getName().endsWith(".trace.db"))) { - boolean isReadOnly = file.setReadOnly(); - if (!isReadOnly) { - fail("File " + file.getAbsolutePath() + " is not read only. Can't test it."); - } - } - } - - // Now it's read only - conn = DriverManager.getConnection(url1, "sa1", "abc abc"); - stat = conn.createStatement(); - stat.execute("CREATE LOCAL TEMPORARY LINKED TABLE T(NULL, 'jdbc:h2:mem:one', 'sa', 'sa', 'TEST')"); - // This is valid because it's a linked table - stat.execute("INSERT INTO T VALUES('abc')"); - - conn.close(); - memConn.close(); - - deleteDb("testLinkedTableInReadOnlyDb"); - } - -} diff --git a/tools/h2/src/test/org/h2/test/db/TestListener.java b/tools/h2/src/test/org/h2/test/db/TestListener.java deleted file mode 100755 index cb0e185..0000000 --- a/tools/h2/src/test/org/h2/test/db/TestListener.java +++ /dev/null @@ -1,140 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.test.db; - -import java.sql.Connection; -import java.sql.DriverManager; -import java.sql.PreparedStatement; -import java.sql.SQLException; -import java.sql.Statement; - -import org.h2.api.DatabaseEventListener; -import org.h2.test.TestBase; -import org.h2.util.JdbcUtils; - -/** - * Tests the DatabaseEventListener. - */ -public class TestListener extends TestBase implements DatabaseEventListener { - - private long last; - private int lastState = -1; - private String databaseUrl; - - public TestListener() { - start = last = System.currentTimeMillis(); - } - - /** - * Run just this test. - * - * @param a ignored - */ - public static void main(String... a) throws Exception { - TestBase.createCaller().init().test(); - } - - public void test() throws SQLException { - if (config.networked || config.cipher != null) { - return; - } - deleteDb("listener"); - Connection conn; - conn = getConnection("listener"); - Statement stat = conn.createStatement(); - stat.execute("CREATE TABLE TEST(ID INT PRIMARY KEY, NAME VARCHAR)"); - PreparedStatement prep = conn.prepareStatement("INSERT INTO TEST VALUES(?, 'Test' || SPACE(100))"); - int len = getSize(100, 100000); - for (int i = 0; i < len; i++) { - prep.setInt(1, i); - prep.execute(); - } - crash(conn); - - conn = getConnection("listener;database_event_listener='" + getClass().getName() + "'"); - conn.close(); - deleteDb("listener"); - } - - public void diskSpaceIsLow() { - printTime("diskSpaceIsLow"); - } - - public void exceptionThrown(SQLException e, String sql) { - TestBase.logError("exceptionThrown sql=" + sql, e); - } - - public void setProgress(int state, String name, int current, int max) { - long time = System.currentTimeMillis(); - if (state == lastState && time < last + 1000) { - return; - } - if (name.length() > 30) { - name = "..." + name.substring(name.length() - 30); - } - last = time; - lastState = state; - String stateName; - switch (state) { - case STATE_SCAN_FILE: - stateName = "Scan " + name; - break; - case STATE_CREATE_INDEX: - stateName = "Create Index " + name; - break; - case STATE_RECOVER: - stateName = "Recover"; - break; - default: - TestBase.logError("unknown state: " + state, null); - stateName = "? " + name; - } - try { - Thread.sleep(1); - } catch (InterruptedException e) { - // ignore - } - printTime("state: " + stateName + " " + (100 * current / max) + " " + (time - start)); - } - - public void closingDatabase() { - if (databaseUrl.toUpperCase().indexOf("CIPHER") >= 0) { - return; - } - Connection conn = null; - try { - conn = DriverManager.getConnection(databaseUrl, getUser(), getPassword()); - conn.createStatement().execute("DROP TABLE TEST2"); - conn.close(); - } catch (SQLException e) { - e.printStackTrace(); - } finally { - JdbcUtils.closeSilently(conn); - } - } - - public void init(String url) { - this.databaseUrl = url; - } - - public void opened() { - if (databaseUrl.toUpperCase().indexOf("CIPHER") >= 0) { - return; - } - Connection conn = null; - try { - conn = DriverManager.getConnection(databaseUrl, getUser(), getPassword()); - conn.createStatement().execute("CREATE TABLE IF NOT EXISTS TEST2(ID INT)"); - conn.close(); - } catch (SQLException e) { - e.printStackTrace(); - } finally { - JdbcUtils.closeSilently(conn); - } - } - -} diff --git a/tools/h2/src/test/org/h2/test/db/TestLob.java b/tools/h2/src/test/org/h2/test/db/TestLob.java deleted file mode 100755 index bf21b92..0000000 --- a/tools/h2/src/test/org/h2/test/db/TestLob.java +++ /dev/null @@ -1,920 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.test.db; - -import java.io.ByteArrayInputStream; -import java.io.CharArrayReader; -import java.io.File; -import java.io.InputStream; -import java.io.Reader; -import java.io.StringReader; -import java.sql.Blob; -import java.sql.Clob; -import java.sql.Connection; -import java.sql.DatabaseMetaData; -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.sql.Savepoint; -import java.sql.Statement; -import java.util.ArrayList; -import java.util.Random; -import org.h2.constant.SysProperties; -import org.h2.store.FileLister; -import org.h2.store.fs.FileSystem; -import org.h2.test.TestBase; -import org.h2.tools.DeleteDbFiles; -import org.h2.util.Utils; -import org.h2.util.IOUtils; -import org.h2.util.StringUtils; -import org.h2.value.ValueLob; - -/** - * Tests LOB and CLOB data types. - */ -public class TestLob extends TestBase { - - /** - * Run just this test. - * - * @param a ignored - */ - public static void main(String... a) throws Exception { - TestBase.createCaller().init().test(); - } - - public void test() throws Exception { - testTempFilesDeleted(); - testAddLobRestart(); - testLobServerMemory(); - if (config.memory) { - return; - } - testLobUpdateMany(); - testLobDeleteTemp(); - testLobDelete(); - testLobVariable(); - testLobDrop(); - testLobNoClose(); - testLobTransactions(10); - testLobTransactions(10000); - testLobRollbackStop(); - testLobCopy(); - testLobHibernate(); - testLobCopy(false); - testLobCopy(true); - testLobCompression(false); - testLobCompression(true); - testManyLobs(); - testClob(); - testUpdateLob(); - testLobReconnect(); - testLob(false); - testLob(true); - testJavaObject(); - deleteDb("lob"); - FileSystem.getInstance(TEMP_DIR).deleteRecursive(TEMP_DIR, true); - } - - private void testTempFilesDeleted() throws Exception { - String[] list; - FileSystem.getInstance(TEMP_DIR).deleteRecursive(TEMP_DIR, true); - IOUtils.mkdirs(new File(TEMP_DIR)); - list = IOUtils.listFiles(TEMP_DIR); - if (list.length > 0) { - fail("Unexpected temp file: " + list[0]); - } - deleteDb("lob"); - Connection conn = getConnection("lob"); - Statement stat; - stat = conn.createStatement(); - stat.execute("create table test(id int primary key, name text)"); - stat.execute("insert into test values(1, space(100000))"); - ResultSet rs; - rs = stat.executeQuery("select * from test"); - rs.next(); - rs.getCharacterStream("name").close(); - rs.close(); - conn.close(); - list = IOUtils.listFiles(TEMP_DIR); - if (list.length > 0) { - fail("Unexpected temp file: " + list[0]); - } - } - - private void testAddLobRestart() throws SQLException { - DeleteDbFiles.execute("memFS:", "lob", true); - Connection conn = org.h2.Driver.load().connect("jdbc:h2:memFS:lob", null); - Statement stat = conn.createStatement(); - stat.execute("create table test(d blob)"); - stat.execute("set MAX_LENGTH_INPLACE_LOB 1"); - PreparedStatement prep = conn.prepareCall("insert into test values('0000')"); - // long start = System.currentTimeMillis(); - for (int i = 0; i < 2000; i++) { - // if (i % 1000 == 0) { - // long now = System.currentTimeMillis(); - // System.out.println(i + " " + (now - start)); - // start = now; - // } - prep.execute(); - ValueLob.resetDirCounter(); - } - conn.close(); - DeleteDbFiles.execute("memFS:", "lob", true); - } - - private void testLobUpdateMany() throws SQLException { - deleteDb("lob"); - Connection conn = getConnection("lob"); - Statement stat = conn.createStatement(); - stat.execute("create table post(id int primary key, text clob) as select x, space(96) from system_range(1, 329)"); - PreparedStatement prep = conn.prepareStatement("update post set text = ?"); - prep.setCharacterStream(1, new StringReader(new String(new char[1025])), -1); - prep.executeUpdate(); - conn.close(); - } - - private void testLobDeleteTemp() throws SQLException { - if (SysProperties.LOB_IN_DATABASE) { - return; - } - deleteDb("lob"); - Connection conn = getConnection("lob"); - Statement stat = conn.createStatement(); - stat.execute("create table test(data clob) as select space(100000) from dual"); - assertEquals(1, IOUtils.listFiles(getBaseDir() + "/lob.lobs.db").length); - stat.execute("delete from test"); - conn.close(); - assertEquals(0, IOUtils.listFiles(getBaseDir() + "/lob.lobs.db").length); - } - - private void testLobServerMemory() throws SQLException { - deleteDb("lob"); - Connection conn = getConnection("lob"); - Statement stat = conn.createStatement(); - stat.execute("CREATE TABLE TEST(ID INT, DATA CLOB)"); - PreparedStatement prep = conn.prepareStatement("INSERT INTO TEST VALUES(1, ?)"); - StringReader reader = new StringReader(new String(new char[100000])); - prep.setCharacterStream(1, reader, -1); - prep.execute(); - conn.close(); - } - - private void testLobDelete() throws SQLException { - if (config.memory || SysProperties.LOB_IN_DATABASE) { - return; - } - deleteDb("lob"); - Connection conn = reconnect(null); - Statement stat = conn.createStatement(); - stat.execute("CREATE TABLE TEST(ID INT, DATA CLOB)"); - stat.execute("INSERT INTO TEST SELECT X, SPACE(10000) FROM SYSTEM_RANGE(1, 10)"); - ArrayList list = FileLister.getDatabaseFiles(getBaseDir(), "lob", true); - stat.execute("UPDATE TEST SET DATA = SPACE(5000)"); - collectAndWait(); - stat.execute("CHECKPOINT"); - ArrayList list2 = FileLister.getDatabaseFiles(getBaseDir(), "lob", true); - if (list2.size() >= list.size() + 5) { - fail("Expected not many more files, got " + list2.size() + " was " + list.size()); - } - stat.execute("DELETE FROM TEST"); - collectAndWait(); - stat.execute("CHECKPOINT"); - ArrayList list3 = FileLister.getDatabaseFiles(getBaseDir(), "lob", true); - if (list3.size() >= list.size()) { - fail("Expected less files, got " + list2.size() + " was " + list.size()); - } - conn.close(); - } - - private void collectAndWait() { - for (int i = 0; i < 3; i++) { - System.gc(); - } - try { - Thread.sleep(50); - } catch (InterruptedException e) { - // ignore - } - } - - private void testLobVariable() throws SQLException { - deleteDb("lob"); - Connection conn = reconnect(null); - Statement stat = conn.createStatement(); - stat.execute("CREATE TABLE TEST(ID INT, DATA CLOB)"); - stat.execute("INSERT INTO TEST VALUES(1, SPACE(100000))"); - stat.execute("SET @TOTAL = SELECT DATA FROM TEST WHERE ID=1"); - stat.execute("DROP TABLE TEST"); - stat.execute("CALL @TOTAL LIKE '%X'"); - stat.execute("CREATE TABLE TEST(ID INT, DATA CLOB)"); - stat.execute("INSERT INTO TEST VALUES(1, @TOTAL)"); - stat.execute("INSERT INTO TEST VALUES(2, @TOTAL)"); - stat.execute("DROP TABLE TEST"); - stat.execute("CALL @TOTAL LIKE '%X'"); - conn.close(); - } - - private void testLobDrop() throws SQLException { - if (config.networked) { - return; - } - deleteDb("lob"); - Connection conn = reconnect(null); - Statement stat = conn.createStatement(); - for (int i = 0; i < 500; i++) { - stat.execute("CREATE TABLE T" + i + "(ID INT, C CLOB)"); - } - stat.execute("CREATE TABLE TEST(ID INT, C CLOB)"); - stat.execute("INSERT INTO TEST VALUES(1, SPACE(10000))"); - for (int i = 0; i < 500; i++) { - stat.execute("DROP TABLE T" + i); - } - ResultSet rs = stat.executeQuery("SELECT * FROM TEST"); - while (rs.next()) { - rs.getString("C"); - } - conn.close(); - } - - private void testLobNoClose() throws Exception { - if (config.networked) { - return; - } - deleteDb("lob"); - Connection conn = reconnect(null); - conn.createStatement().execute("CREATE TABLE TEST(ID IDENTITY, DATA CLOB)"); - conn.createStatement().execute("INSERT INTO TEST VALUES(1, SPACE(10000))"); - ResultSet rs = conn.createStatement().executeQuery("SELECT DATA FROM TEST"); - rs.next(); - SysProperties.lobCloseBetweenReads = true; - Reader in = rs.getCharacterStream(1); - in.read(); - conn.createStatement().execute("DELETE FROM TEST"); - SysProperties.lobCloseBetweenReads = false; - conn.createStatement().execute("INSERT INTO TEST VALUES(1, SPACE(10000))"); - rs = conn.createStatement().executeQuery("SELECT DATA FROM TEST"); - rs.next(); - in = rs.getCharacterStream(1); - in.read(); - conn.setAutoCommit(false); - try { - conn.createStatement().execute("DELETE FROM TEST"); - conn.commit(); - // DELETE does not fail in Linux, but in Windows - // error("Error expected"); - // but reading afterwards should fail - int len = 0; - while (true) { - int x = in.read(); - if (x < 0) { - break; - } - len++; - } - in.close(); - if (len > 0) { - // in Linux, it seems it is still possible to read in files - // even if they are deleted - if (System.getProperty("os.name").indexOf("Windows") > 0) { - fail("Error expected; len=" + len); - } - } - } catch (SQLException e) { - assertKnownException(e); - } - conn.rollback(); - conn.close(); - } - - private void testLobTransactions(int spaceLen) throws SQLException { - deleteDb("lob"); - Connection conn = reconnect(null); - conn.createStatement().execute("CREATE TABLE TEST(ID IDENTITY, DATA CLOB, DATA2 VARCHAR)"); - conn.setAutoCommit(false); - Random random = new Random(0); - int rows = 0; - Savepoint sp = null; - int len = getSize(100, 400); - for (int i = 0; i < len; i++) { - switch (random.nextInt(10)) { - case 0: - trace("insert"); - conn.createStatement().execute( - "INSERT INTO TEST(DATA, DATA2) VALUES('" + i + "' || SPACE(" + spaceLen + "), '" + i + "')"); - rows++; - break; - case 1: - if (rows > 0) { - trace("delete"); - conn.createStatement().execute("DELETE FROM TEST WHERE ID=" + random.nextInt(rows)); - } - break; - case 2: - if (rows > 0) { - trace("update"); - conn.createStatement().execute( - "UPDATE TEST SET DATA='x' || DATA, DATA2='x' || DATA2 WHERE ID=" + random.nextInt(rows)); - } - break; - case 3: - if (rows > 0) { - trace("commit"); - conn.commit(); - sp = null; - } - break; - case 4: - if (rows > 0) { - trace("rollback"); - conn.rollback(); - sp = null; - } - break; - case 5: - trace("savepoint"); - sp = conn.setSavepoint(); - break; - case 6: - if (sp != null) { - trace("rollback to savepoint"); - conn.rollback(sp); - } - break; - case 7: - if (rows > 0) { - trace("checkpoint"); - conn.createStatement().execute("CHECKPOINT"); - trace("shutdown immediately"); - conn.createStatement().execute("SHUTDOWN IMMEDIATELY"); - trace("shutdown done"); - conn = reconnect(conn); - conn.setAutoCommit(false); - sp = null; - } - break; - default: - } - ResultSet rs = conn.createStatement().executeQuery("SELECT * FROM TEST"); - while (rs.next()) { - String d1 = rs.getString("DATA").trim(); - String d2 = rs.getString("DATA2").trim(); - assertEquals(d1, d2); - } - - } - conn.close(); - } - - private void testLobRollbackStop() throws SQLException { - deleteDb("lob"); - Connection conn = reconnect(null); - conn.createStatement().execute("CREATE TABLE TEST(ID INT PRIMARY KEY, DATA CLOB)"); - conn.createStatement().execute("INSERT INTO TEST VALUES(1, SPACE(10000))"); - conn.setAutoCommit(false); - conn.createStatement().execute("DELETE FROM TEST"); - conn.createStatement().execute("CHECKPOINT"); - conn.createStatement().execute("SHUTDOWN IMMEDIATELY"); - conn = reconnect(conn); - ResultSet rs = conn.createStatement().executeQuery("SELECT * FROM TEST"); - assertTrue(rs.next()); - rs.getInt(1); - assertEquals(10000, rs.getString(2).length()); - conn.close(); - } - - private void testLobCopy() throws SQLException { - deleteDb("lob"); - Connection conn = reconnect(null); - Statement stat = conn.createStatement(); - stat.execute("create table test(id int, data clob)"); - stat.execute("insert into test values(1, space(1000));"); - stat.execute("insert into test values(2, space(10000));"); - stat.execute("create table test2(id int, data clob);"); - stat.execute("insert into test2 select * from test;"); - stat.execute("drop table test;"); - stat.execute("select * from test2;"); - stat.execute("update test2 set id=id;"); - stat.execute("select * from test2;"); - conn.close(); - } - - private void testLobHibernate() throws Exception { - deleteDb("lob"); - Connection conn0 = reconnect(null); - - conn0.getAutoCommit(); - conn0.setAutoCommit(false); - DatabaseMetaData dbMeta0 = conn0.getMetaData(); - dbMeta0.getDatabaseProductName(); - dbMeta0.getDatabaseMajorVersion(); - dbMeta0.getDatabaseProductVersion(); - dbMeta0.getDriverName(); - dbMeta0.getDriverVersion(); - dbMeta0.supportsResultSetType(1004); - dbMeta0.supportsBatchUpdates(); - dbMeta0.dataDefinitionCausesTransactionCommit(); - dbMeta0.dataDefinitionIgnoredInTransactions(); - dbMeta0.supportsGetGeneratedKeys(); - conn0.getAutoCommit(); - conn0.getAutoCommit(); - conn0.commit(); - conn0.setAutoCommit(true); - Statement stat0 = conn0.createStatement(); - stat0.executeUpdate("drop table CLOB_ENTITY if exists"); - stat0.getWarnings(); - stat0.executeUpdate("create table CLOB_ENTITY (ID bigint not null, DATA clob, CLOB_DATA clob, primary key (ID))"); - stat0.getWarnings(); - stat0.close(); - conn0.getWarnings(); - conn0.clearWarnings(); - conn0.setAutoCommit(false); - conn0.getAutoCommit(); - conn0.getAutoCommit(); - PreparedStatement prep0 = conn0.prepareStatement("select max(ID) from CLOB_ENTITY"); - ResultSet rs0 = prep0.executeQuery(); - rs0.next(); - rs0.getLong(1); - rs0.wasNull(); - rs0.close(); - prep0.close(); - conn0.getAutoCommit(); - PreparedStatement prep1 = conn0 - .prepareStatement("insert into CLOB_ENTITY (DATA, CLOB_DATA, ID) values (?, ?, ?)"); - prep1.setNull(1, 2005); - StringBuilder buff = new StringBuilder(10000); - for (int i = 0; i < 10000; i++) { - buff.append((char) ('0' + (i % 10))); - } - Reader x = new StringReader(buff.toString()); - prep1.setCharacterStream(2, x, 10000); - prep1.setLong(3, 1); - prep1.addBatch(); - prep1.executeBatch(); - prep1.close(); - conn0.getAutoCommit(); - conn0.getAutoCommit(); - conn0.commit(); - conn0.isClosed(); - conn0.getWarnings(); - conn0.clearWarnings(); - conn0.getAutoCommit(); - conn0.getAutoCommit(); - PreparedStatement prep2 = conn0 - .prepareStatement("select c_.ID as ID0_0_, c_.DATA as S_, c_.CLOB_DATA as CLOB3_0_0_ from CLOB_ENTITY c_ where c_.ID=?"); - prep2.setLong(1, 1); - ResultSet rs1 = prep2.executeQuery(); - rs1.next(); - rs1.getCharacterStream("S_"); - Clob clob0 = rs1.getClob("CLOB3_0_0_"); - rs1.wasNull(); - rs1.next(); - rs1.close(); - prep2.getMaxRows(); - prep2.getQueryTimeout(); - prep2.close(); - conn0.getAutoCommit(); - Reader r = clob0.getCharacterStream(); - for (int i = 0; i < 10000; i++) { - int ch = r.read(); - if (ch != ('0' + (i % 10))) { - fail("expected " + (char) ('0' + (i % 10)) + " got: " + ch + " (" + (char) ch + ")"); - } - } - int ch = r.read(); - if (ch != -1) { - fail("expected -1 got: " + ch); - } - conn0.close(); - } - - private void testLobCopy(boolean compress) throws SQLException { - deleteDb("lob"); - Connection conn; - conn = reconnect(null); - Statement stat = conn.createStatement(); - if (compress) { - stat.execute("SET COMPRESS_LOB LZF"); - } else { - stat.execute("SET COMPRESS_LOB NO"); - } - conn = reconnect(conn); - stat = conn.createStatement(); - ResultSet rs; - rs = stat.executeQuery("select value from information_schema.settings where NAME='COMPRESS_LOB'"); - rs.next(); - assertEquals(compress ? "LZF" : "NO", rs.getString(1)); - assertFalse(rs.next()); - stat.execute("create table test(text clob)"); - stat.execute("create table test2(text clob)"); - StringBuilder buff = new StringBuilder(); - for (int i = 0; i < 1000; i++) { - buff.append(' '); - } - String spaces = buff.toString(); - stat.execute("insert into test values('" + spaces + "')"); - stat.execute("insert into test2 select * from test"); - rs = stat.executeQuery("select * from test2"); - rs.next(); - assertEquals(spaces, rs.getString(1)); - stat.execute("drop table test"); - rs = stat.executeQuery("select * from test2"); - rs.next(); - assertEquals(spaces, rs.getString(1)); - stat.execute("alter table test2 add column id int before text"); - rs = stat.executeQuery("select * from test2"); - rs.next(); - assertEquals(spaces, rs.getString("text")); - conn.close(); - } - - private void testLobCompression(boolean compress) throws Exception { - deleteDb("lob"); - Connection conn; - conn = reconnect(null); - if (compress) { - conn.createStatement().execute("SET COMPRESS_LOB LZF"); - } else { - conn.createStatement().execute("SET COMPRESS_LOB NO"); - } - conn.createStatement().execute("CREATE TABLE TEST(ID INT PRIMARY KEY, C CLOB)"); - PreparedStatement prep = conn.prepareStatement("INSERT INTO TEST VALUES(?, ?)"); - long time = System.currentTimeMillis(); - int len = getSize(10, 40); - if (config.networked && config.big) { - len = 5; - } - StringBuilder buff = new StringBuilder(); - for (int i = 0; i < 1000; i++) { - buff.append(StringUtils.xmlNode("content", null, "This is a test " + i)); - } - String xml = buff.toString(); - for (int i = 0; i < len; i++) { - prep.setInt(1, i); - prep.setString(2, xml + i); - prep.execute(); - } - for (int i = 0; i < len; i++) { - ResultSet rs = conn.createStatement().executeQuery("SELECT * FROM TEST"); - while (rs.next()) { - if (i == 0) { - assertEquals(xml + rs.getInt(1), rs.getString(2)); - } else { - Reader r = rs.getCharacterStream(2); - String result = IOUtils.readStringAndClose(r, -1); - assertEquals(xml + rs.getInt(1), result); - } - } - } - time = System.currentTimeMillis() - time; - trace("time: " + time + " compress: " + compress); - conn.close(); - if (!config.memory && SysProperties.LOB_IN_DATABASE) { - long length = new File(getBaseDir() + "/lob.h2.db").length(); - trace("len: " + length + " compress: " + compress); - } - } - - private void testManyLobs() throws Exception { - deleteDb("lob"); - Connection conn; - conn = reconnect(null); - conn.createStatement().execute("CREATE TABLE TEST(ID INT PRIMARY KEY, B BLOB, C CLOB)"); - int len = getSize(10, 2000); - if (config.networked) { - len = 100; - } - - int first = 1, increment = 19; - - PreparedStatement prep = conn.prepareStatement("INSERT INTO TEST(ID, B, C) VALUES(?, ?, ?)"); - for (int i = first; i < len; i += increment) { - int l = i; - prep.setInt(1, i); - prep.setBinaryStream(2, getRandomStream(l, i), -1); - prep.setCharacterStream(3, getRandomReader(l, i), -1); - prep.execute(); - } - - conn = reconnect(conn); - ResultSet rs = conn.createStatement().executeQuery("SELECT * FROM TEST ORDER BY ID"); - while (rs.next()) { - int i = rs.getInt("ID"); - Blob b = rs.getBlob("B"); - Clob c = rs.getClob("C"); - int l = i; - assertEquals(l, b.length()); - assertEquals(l, c.length()); - assertEqualStreams(getRandomStream(l, i), b.getBinaryStream(), -1); - assertEqualReaders(getRandomReader(l, i), c.getCharacterStream(), -1); - } - - prep = conn.prepareStatement("UPDATE TEST SET B=?, C=? WHERE ID=?"); - for (int i = first; i < len; i += increment) { - int l = i; - prep.setBinaryStream(1, getRandomStream(l, -i), -1); - prep.setCharacterStream(2, getRandomReader(l, -i), -1); - prep.setInt(3, i); - prep.execute(); - } - - conn = reconnect(conn); - rs = conn.createStatement().executeQuery("SELECT * FROM TEST ORDER BY ID"); - while (rs.next()) { - int i = rs.getInt("ID"); - Blob b = rs.getBlob("B"); - Clob c = rs.getClob("C"); - int l = i; - assertEquals(l, b.length()); - assertEquals(l, c.length()); - assertEqualStreams(getRandomStream(l, -i), b.getBinaryStream(), -1); - assertEqualReaders(getRandomReader(l, -i), c.getCharacterStream(), -1); - } - - conn.close(); - } - - private void testClob() throws Exception { - deleteDb("lob"); - Connection conn; - conn = reconnect(null); - conn.createStatement().execute("CREATE TABLE TEST(ID IDENTITY, C CLOB)"); - PreparedStatement prep = conn.prepareStatement("INSERT INTO TEST(C) VALUES(?)"); - prep.setCharacterStream(1, new CharArrayReader("Bohlen".toCharArray()), "Bohlen".length()); - prep.execute(); - prep.setCharacterStream(1, new CharArrayReader("B\u00f6hlen".toCharArray()), "B\u00f6hlen".length()); - prep.execute(); - prep.setCharacterStream(1, getRandomReader(501, 1), -1); - prep.execute(); - prep.setCharacterStream(1, getRandomReader(1501, 2), 401); - prep.execute(); - conn = reconnect(conn); - ResultSet rs = conn.createStatement().executeQuery("SELECT * FROM TEST ORDER BY ID"); - rs.next(); - assertEquals("Bohlen", rs.getString("C")); - assertEqualReaders(new CharArrayReader("Bohlen".toCharArray()), rs.getCharacterStream("C"), -1); - rs.next(); - assertEqualReaders(new CharArrayReader("B\u00f6hlen".toCharArray()), rs.getCharacterStream("C"), -1); - rs.next(); - assertEqualReaders(getRandomReader(501, 1), rs.getCharacterStream("C"), -1); - Clob clob = rs.getClob("C"); - assertEqualReaders(getRandomReader(501, 1), clob.getCharacterStream(), -1); - assertEquals(501, clob.length()); - rs.next(); - assertEqualReaders(getRandomReader(401, 2), rs.getCharacterStream("C"), -1); - assertEqualReaders(getRandomReader(1500, 2), rs.getCharacterStream("C"), 401); - clob = rs.getClob("C"); - assertEqualReaders(getRandomReader(1501, 2), clob.getCharacterStream(), 401); - assertEqualReaders(getRandomReader(401, 2), clob.getCharacterStream(), 401); - assertEquals(401, clob.length()); - assertFalse(rs.next()); - conn.close(); - } - - private Connection reconnect(Connection conn) throws SQLException { - long time = System.currentTimeMillis(); - if (conn != null) { - try { - conn.close(); - } catch (SQLException e) { - // ignore - } - } - conn = getConnection("lob"); - trace("re-connect=" + (System.currentTimeMillis() - time)); - return conn; - } - - private void testUpdateLob() throws SQLException { - deleteDb("lob"); - Connection conn; - conn = reconnect(null); - - PreparedStatement prep = conn - .prepareStatement("CREATE TABLE IF NOT EXISTS p( id int primary key, rawbyte BLOB ); "); - prep.execute(); - prep.close(); - - prep = conn.prepareStatement("INSERT INTO p(id) VALUES(?);"); - for (int i = 0; i < 10; i++) { - prep.setInt(1, i); - prep.execute(); - } - prep.close(); - - prep = conn.prepareStatement("UPDATE p set rawbyte=? WHERE id=?"); - for (int i = 0; i < 8; i++) { - prep.setBinaryStream(1, getRandomStream(10000, i), 0); - prep.setInt(2, i); - prep.execute(); - } - prep.close(); - conn.commit(); - - conn = reconnect(conn); - - conn.setAutoCommit(true); - prep = conn.prepareStatement("UPDATE p set rawbyte=? WHERE id=?"); - for (int i = 8; i < 10; i++) { - prep.setBinaryStream(1, getRandomStream(10000, i), 0); - prep.setInt(2, i); - prep.execute(); - } - prep.close(); - - prep = conn.prepareStatement("SELECT * from p"); - ResultSet rs = prep.executeQuery(); - while (rs.next()) { - for (int i = 1; i <= rs.getMetaData().getColumnCount(); i++) { - rs.getMetaData().getColumnName(i); - rs.getString(i); - } - } - conn.close(); - } - - private void testLobReconnect() throws Exception { - deleteDb("lob"); - Connection conn = reconnect(null); - Statement stat = conn.createStatement(); - stat.execute("CREATE TABLE TEST(ID INT PRIMARY KEY, TEXT CLOB)"); - PreparedStatement prep; - prep = conn.prepareStatement("INSERT INTO TEST VALUES(1, ?)"); - String s = new String(getRandomChars(10000, 1)); - byte[] data = s.getBytes("UTF-8"); - prep.setBinaryStream(1, new ByteArrayInputStream(data), 0); - prep.execute(); - - conn = reconnect(conn); - stat = conn.createStatement(); - ResultSet rs = stat.executeQuery("SELECT * FROM TEST WHERE ID=1"); - rs.next(); - assertEqualStreams(rs.getBinaryStream("TEXT"), new ByteArrayInputStream(data), -1); - - prep = conn.prepareStatement("UPDATE TEST SET TEXT = ?"); - prep.setBinaryStream(1, new ByteArrayInputStream(data), 0); - prep.execute(); - - conn = reconnect(conn); - stat = conn.createStatement(); - rs = stat.executeQuery("SELECT * FROM TEST WHERE ID=1"); - rs.next(); - assertEqualStreams(rs.getBinaryStream("TEXT"), new ByteArrayInputStream(data), -1); - - stat.execute("DROP TABLE IF EXISTS TEST"); - conn.close(); - } - - private void testLob(boolean clob) throws Exception { - deleteDb("lob"); - Connection conn = reconnect(null); - conn = reconnect(conn); - Statement stat = conn.createStatement(); - stat.execute("DROP TABLE IF EXISTS TEST"); - PreparedStatement prep; - ResultSet rs; - long time; - stat.execute("CREATE TABLE TEST(ID INT PRIMARY KEY, VALUE " + (clob ? "CLOB" : "BLOB") + ")"); - - int len = getSize(1, 1000); - if (config.networked && config.big) { - len = 100; - } - - time = System.currentTimeMillis(); - prep = conn.prepareStatement("INSERT INTO TEST VALUES(?, ?)"); - for (int i = 0; i < len; i += i + i + 1) { - prep.setInt(1, i); - int size = i * i; - if (clob) { - prep.setCharacterStream(2, getRandomReader(size, i), 0); - } else { - prep.setBinaryStream(2, getRandomStream(size, i), 0); - } - prep.execute(); - } - trace("insert=" + (System.currentTimeMillis() - time)); - traceMemory(); - conn = reconnect(conn); - - time = System.currentTimeMillis(); - prep = conn.prepareStatement("SELECT ID, VALUE FROM TEST"); - rs = prep.executeQuery(); - while (rs.next()) { - int id = rs.getInt("ID"); - int size = id * id; - if (clob) { - Reader rt = rs.getCharacterStream(2); - assertEqualReaders(getRandomReader(size, id), rt, -1); - Object obj = rs.getObject(2); - if (obj instanceof Clob) { - obj = ((Clob) obj).getCharacterStream(); - } - assertEqualReaders(getRandomReader(size, id), (Reader) obj, -1); - } else { - InputStream in = rs.getBinaryStream(2); - assertEqualStreams(getRandomStream(size, id), in, -1); - Object obj = rs.getObject(2); - if (obj instanceof Blob) { - obj = ((Blob) obj).getBinaryStream(); - } - assertEqualStreams(getRandomStream(size, id), (InputStream) obj, -1); - } - } - trace("select=" + (System.currentTimeMillis() - time)); - traceMemory(); - - conn = reconnect(conn); - - time = System.currentTimeMillis(); - prep = conn.prepareStatement("DELETE FROM TEST WHERE ID=?"); - for (int i = 0; i < len; i++) { - prep.setInt(1, i); - prep.executeUpdate(); - } - trace("delete=" + (System.currentTimeMillis() - time)); - traceMemory(); - conn = reconnect(conn); - - conn.setAutoCommit(false); - prep = conn.prepareStatement("INSERT INTO TEST VALUES(1, ?)"); - if (clob) { - prep.setCharacterStream(1, getRandomReader(0, 0), 0); - } else { - prep.setBinaryStream(1, getRandomStream(0, 0), 0); - } - prep.execute(); - conn.rollback(); - prep.execute(); - conn.commit(); - - conn.createStatement().execute("DELETE FROM TEST WHERE ID=1"); - conn.rollback(); - conn.createStatement().execute("DELETE FROM TEST WHERE ID=1"); - conn.commit(); - - conn.createStatement().execute("DROP TABLE TEST"); - conn.close(); - } - - private void testJavaObject() throws SQLException { - deleteDb("lob"); - Connection conn = getConnection("lob"); - Statement stat = conn.createStatement(); - stat.execute("CREATE TABLE TEST(ID INT PRIMARY KEY, DATA OTHER)"); - PreparedStatement prep = conn.prepareStatement("INSERT INTO TEST VALUES(1, ?)"); - prep.setObject(1, new TestLobObject("abc")); - prep.execute(); - ResultSet rs = conn.createStatement().executeQuery("SELECT * FROM TEST"); - rs.next(); - Object oa = rs.getObject(2); - TestLobObject a = (TestLobObject) oa; - Object ob = rs.getObject("DATA"); - TestLobObject b = (TestLobObject) ob; - assertEquals("abc", a.data); - assertEquals("abc", b.data); - assertFalse(rs.next()); - - conn.createStatement().execute("drop table test"); - stat.execute("create table test(value other)"); - prep = conn.prepareStatement("insert into test values(?)"); - prep.setObject(1, Utils.serialize("")); - prep.execute(); - rs = stat.executeQuery("select value from test"); - while (rs.next()) { - assertEquals("", (String) rs.getObject("value")); - } - conn.close(); - } - - private Reader getRandomReader(int len, int seed) { - return new CharArrayReader(getRandomChars(len, seed)); - } - - private char[] getRandomChars(int len, int seed) { - Random random = new Random(seed); - char[] buff = new char[len]; - for (int i = 0; i < len; i++) { - char ch; - do { - ch = (char) random.nextInt(Character.MAX_VALUE); - // UTF8: String.getBytes("UTF-8") only returns 1 byte for - // 0xd800-0xdfff - } while (ch >= 0xd800 && ch <= 0xdfff); - buff[i] = ch; - } - return buff; - } - - private InputStream getRandomStream(int len, int seed) { - Random random = new Random(seed); - byte[] buff = new byte[len]; - random.nextBytes(buff); - return new ByteArrayInputStream(buff); - } - -} diff --git a/tools/h2/src/test/org/h2/test/db/TestLobObject.java b/tools/h2/src/test/org/h2/test/db/TestLobObject.java deleted file mode 100755 index 7f65015..0000000 --- a/tools/h2/src/test/org/h2/test/db/TestLobObject.java +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.test.db; - -import java.io.Serializable; - -/** - * A utility class for TestLob. - */ -class TestLobObject implements Serializable { - - private static final long serialVersionUID = 1L; - String data; - - TestLobObject(String data) { - this.data = data; - } -} diff --git a/tools/h2/src/test/org/h2/test/db/TestMemoryUsage.java b/tools/h2/src/test/org/h2/test/db/TestMemoryUsage.java deleted file mode 100755 index 4a3f84e..0000000 --- a/tools/h2/src/test/org/h2/test/db/TestMemoryUsage.java +++ /dev/null @@ -1,250 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.test.db; - -import java.sql.Connection; -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.sql.Statement; -import java.util.Random; - -import org.h2.test.TestBase; -import org.h2.util.Utils; - -/** - * Tests the memory usage of the cache. - */ -public class TestMemoryUsage extends TestBase { - - private Connection conn; - - /** - * Run just this test. - * - * @param a ignored - */ - public static void main(String... a) throws Exception { - TestBase.createCaller().init().test(); - } - - public void test() throws SQLException { - if (getBaseDir().indexOf(':') >= 0) { - // can't test in-memory databases - return; - } - testCreateDropLoop(); - testCreateIndex(); - testClob(); - testReconnectOften(); - deleteDb("memoryUsage"); - reconnect(); - insertUpdateSelectDelete(); - reconnect(); - insertUpdateSelectDelete(); - conn.close(); - deleteDb("memoryUsage"); - } - - private void testCreateDropLoop() throws SQLException { - deleteDb("memoryUsage"); - conn = getConnection("memoryUsage"); - Statement stat = conn.createStatement(); - for (int i = 0; i < 100; i++) { - stat.execute("CREATE TABLE TEST(ID INT)"); - stat.execute("DROP TABLE TEST"); - } - int used = Utils.getMemoryUsed(); - for (int i = 0; i < 1000; i++) { - stat.execute("CREATE TABLE TEST(ID INT PRIMARY KEY)"); - stat.execute("DROP TABLE TEST"); - } - int usedNow = Utils.getMemoryUsed(); - if (usedNow > used * 1.3) { - assertEquals(used, usedNow); - } - conn.close(); - } - - - private void reconnect() throws SQLException { - if (conn != null) { - conn.close(); - } - // Class.forName("org.hsqldb.jdbcDriver"); - // conn = DriverManager.getConnection("jdbc:hsqldb:test", "sa", ""); - conn = getConnection("memoryUsage"); - } - - private void testClob() throws SQLException { - if (config.memory || !config.big) { - return; - } - deleteDb("memoryUsage"); - conn = getConnection("memoryUsage"); - Statement stat = conn.createStatement(); - stat.execute("SET MAX_LENGTH_INPLACE_LOB 32768"); - stat.execute("SET CACHE_SIZE 8000"); - stat.execute("CREATE TABLE TEST(ID IDENTITY, DATA CLOB)"); - freeSoftReferences(); - try { - int base = Utils.getMemoryUsed(); - for (int i = 0; i < 4; i++) { - stat.execute("INSERT INTO TEST(DATA) SELECT SPACE(32000) FROM SYSTEM_RANGE(1, 200)"); - freeSoftReferences(); - int used = Utils.getMemoryUsed(); - if ((used - base) > 16000) { - fail("Used: " + (used - base)); - } - } - } finally { - conn.close(); - freeMemory(); - } - } - - /** - * Eat memory so that all soft references are garbage collected. - */ - void freeSoftReferences() { - try { - eatMemory(1); - } catch (OutOfMemoryError e) { - // ignore - } - System.gc(); - System.gc(); - freeMemory(); - } - - private void testCreateIndex() throws SQLException { - if (config.memory) { - return; - } - deleteDb("memoryUsage"); - conn = getConnection("memoryUsage"); - Statement stat = conn.createStatement(); - stat.execute("create table test(id int, name varchar(255))"); - PreparedStatement prep = conn.prepareStatement("insert into test values(?, space(200))"); - int len = getSize(10000, 100000); - for (int i = 0; i < len; i++) { - if (i % 1000 == 0) { - // trace("[" + i + "/" + len + "] KB: " + MemoryUtils.getMemoryUsed()); - } - prep.setInt(1, i); - prep.executeUpdate(); - } - int base = Utils.getMemoryUsed(); - stat.execute("create index idx_test_id on test(id)"); - System.gc(); - System.gc(); - int used = Utils.getMemoryUsed(); - if ((used - base) > getSize(7500, 12000)) { - fail("Used: " + (used - base)); - } - stat.execute("drop table test"); - conn.close(); - } - - private void testReconnectOften() throws SQLException { - deleteDb("memoryUsage"); - Connection conn1 = getConnection("memoryUsage"); - int len = getSize(1, 2000); - printTimeMemory("start", 0); - long time = System.currentTimeMillis(); - for (int i = 0; i < len; i++) { - Connection conn2 = getConnection("memoryUsage"); - conn2.close(); - if (i % 10000 == 0) { - printTimeMemory("connect", System.currentTimeMillis() - time); - } - } - printTimeMemory("connect", System.currentTimeMillis() - time); - conn1.close(); - } - - private void insertUpdateSelectDelete() throws SQLException { - Statement stat = conn.createStatement(); - long time; - int len = getSize(1, 2000); - - // insert - time = System.currentTimeMillis(); - stat.execute("DROP TABLE IF EXISTS TEST"); - trace("drop=" + (System.currentTimeMillis() - time)); - stat.execute("CREATE CACHED TABLE TEST(ID INT PRIMARY KEY, NAME VARCHAR(255))"); - PreparedStatement prep = conn.prepareStatement("INSERT INTO TEST VALUES(?, 'Hello World')"); - printTimeMemory("start", 0); - time = System.currentTimeMillis(); - for (int i = 0; i < len; i++) { - prep.setInt(1, i); - prep.execute(); - if (i % 50000 == 0) { - trace(" " + (100 * i / len) + "%"); - } - } - printTimeMemory("insert", System.currentTimeMillis() - time); - - // update - time = System.currentTimeMillis(); - prep = conn.prepareStatement("UPDATE TEST SET NAME='Hallo Welt' || ID WHERE ID = ?"); - for (int i = 0; i < len; i++) { - prep.setInt(1, i); - prep.execute(); - if (i % 50000 == 0) { - trace(" " + (100 * i / len) + "%"); - } - } - printTimeMemory("update", System.currentTimeMillis() - time); - - // select - time = System.currentTimeMillis(); - prep = conn.prepareStatement("SELECT * FROM TEST WHERE ID = ?"); - for (int i = 0; i < len; i++) { - prep.setInt(1, i); - ResultSet rs = prep.executeQuery(); - rs.next(); - if (rs.next()) { - fail("one row expected, got more"); - } - if (i % 50000 == 0) { - trace(" " + (100 * i / len) + "%"); - } - } - printTimeMemory("select", System.currentTimeMillis() - time); - - // select randomized - Random random = new Random(1); - time = System.currentTimeMillis(); - prep = conn.prepareStatement("SELECT * FROM TEST WHERE ID = ?"); - for (int i = 0; i < len; i++) { - prep.setInt(1, random.nextInt(len)); - ResultSet rs = prep.executeQuery(); - rs.next(); - if (rs.next()) { - fail("one row expected, got more"); - } - if (i % 50000 == 0) { - trace(" " + (100 * i / len) + "%"); - } - } - printTimeMemory("select randomized", System.currentTimeMillis() - time); - - // delete - time = System.currentTimeMillis(); - prep = conn.prepareStatement("DELETE FROM TEST WHERE ID = ?"); - for (int i = 0; i < len; i++) { - prep.setInt(1, random.nextInt(len)); - prep.executeUpdate(); - if (i % 50000 == 0) { - trace(" " + (100 * i / len) + "%"); - } - } - printTimeMemory("delete", System.currentTimeMillis() - time); - } - -} diff --git a/tools/h2/src/test/org/h2/test/db/TestMultiConn.java b/tools/h2/src/test/org/h2/test/db/TestMultiConn.java deleted file mode 100755 index a64ba74..0000000 --- a/tools/h2/src/test/org/h2/test/db/TestMultiConn.java +++ /dev/null @@ -1,230 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.test.db; - -import java.sql.Connection; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.sql.Statement; - -import org.h2.api.DatabaseEventListener; -import org.h2.test.TestBase; - -/** - * Multi-connection tests. - */ -public class TestMultiConn extends TestBase implements DatabaseEventListener { - - private static int wait; - - /** - * Run just this test. - * - * @param a ignored - */ - public static void main(String... a) throws Exception { - TestBase.createCaller().init().test(); - } - - public void test() throws Exception { - testConcurrentShutdownQuery(); - testCommitRollback(); - testConcurrentOpen(); - testThreeThreads(); - deleteDb("multiConn"); - } - - private void testConcurrentShutdownQuery() throws Exception { - Connection conn1 = getConnection("multiConn"); - Connection conn2 = getConnection("multiConn"); - final Statement stat1 = conn1.createStatement(); - stat1.execute("CREATE ALIAS SLEEP FOR \"java.lang.Thread.sleep(long)\""); - final Statement stat2 = conn2.createStatement(); - stat1.execute("SET THROTTLE 100"); - new Thread() { - public void run() { - try { - stat2.executeQuery("CALL SLEEP(100)"); - try { - Thread.sleep(10); - } catch (Exception e) { - // ignore - } - stat2.executeQuery("CALL SLEEP(100)"); - } catch (SQLException e) { - // ignore - } - } - } .start(); - Thread.sleep(50); - stat1.execute("SHUTDOWN"); - conn1.close(); - try { - conn2.close(); - } catch (SQLException e) { - // ignore - } - } - - private void testThreeThreads() throws Exception { - deleteDb("multiConn"); - final Connection conn1 = getConnection("multiConn"); - final Connection conn2 = getConnection("multiConn"); - final Connection conn3 = getConnection("multiConn"); - conn1.setAutoCommit(false); - conn2.setAutoCommit(false); - conn3.setAutoCommit(false); - final Statement s1 = conn1.createStatement(); - final Statement s2 = conn2.createStatement(); - final Statement s3 = conn3.createStatement(); - s1.execute("CREATE TABLE TEST1(ID INT)"); - s2.execute("CREATE TABLE TEST2(ID INT)"); - s3.execute("CREATE TABLE TEST3(ID INT)"); - s1.execute("INSERT INTO TEST1 VALUES(1)"); - s2.execute("INSERT INTO TEST2 VALUES(2)"); - s3.execute("INSERT INTO TEST3 VALUES(3)"); - s1.execute("SET LOCK_TIMEOUT 1000"); - s2.execute("SET LOCK_TIMEOUT 1000"); - s3.execute("SET LOCK_TIMEOUT 1000"); - Thread t1 = new Thread(new Runnable() { - public void run() { - try { - s3.execute("INSERT INTO TEST2 VALUES(4)"); - conn3.commit(); - } catch (SQLException e) { - TestBase.logError("insert", e); - } - } - }); - t1.start(); - Thread.sleep(20); - Thread t2 = new Thread(new Runnable() { - public void run() { - try { - s2.execute("INSERT INTO TEST1 VALUES(5)"); - conn2.commit(); - } catch (SQLException e) { - TestBase.logError("insert", e); - } - } - }); - t2.start(); - Thread.sleep(20); - conn1.commit(); - t2.join(1000); - t1.join(1000); - ResultSet rs = s1.executeQuery("SELECT * FROM TEST1 ORDER BY ID"); - rs.next(); - assertEquals(1, rs.getInt(1)); - rs.next(); - assertEquals(5, rs.getInt(1)); - assertFalse(rs.next()); - conn1.close(); - conn2.close(); - conn3.close(); - } - - private void testConcurrentOpen() throws Exception { - if (config.memory || config.googleAppEngine) { - return; - } - deleteDb("multiConn"); - Connection conn = getConnection("multiConn"); - conn.createStatement().execute("CREATE TABLE TEST(ID INT PRIMARY KEY, NAME VARCHAR)"); - conn.createStatement().execute("INSERT INTO TEST VALUES(0, 'Hello'), (1, 'World')"); - conn.createStatement().execute("SHUTDOWN"); - conn.close(); - final String listener = getClass().getName(); - Runnable r = new Runnable() { - public void run() { - try { - Connection c1 = getConnection("multiConn;DATABASE_EVENT_LISTENER='" + listener - + "';file_lock=socket"); - c1.close(); - } catch (Exception e) { - TestBase.logError("connect", e); - } - } - }; - Thread thread = new Thread(r); - thread.start(); - Thread.sleep(10); - Connection c2 = getConnection("multiConn;file_lock=socket"); - c2.close(); - thread.join(); - } - - public void diskSpaceIsLow() { - // do nothing - } - - public void exceptionThrown(SQLException e, String sql) { - // do nothing - } - - public void setProgress(int state, String name, int x, int max) { - if (wait > 0) { - try { - Thread.sleep(wait); - } catch (InterruptedException e) { - TestBase.logError("sleep", e); - } - } - } - - public void closingDatabase() { - // do nothing - } - - private void testCommitRollback() throws SQLException { - deleteDb("multiConn"); - Connection c1 = getConnection("multiConn"); - Connection c2 = getConnection("multiConn"); - c1.setAutoCommit(false); - c2.setAutoCommit(false); - Statement s1 = c1.createStatement(); - s1.execute("DROP TABLE IF EXISTS MULTI_A"); - s1.execute("CREATE TABLE MULTI_A(ID INT, NAME VARCHAR(255))"); - s1.execute("INSERT INTO MULTI_A VALUES(0, '0-insert-A')"); - Statement s2 = c2.createStatement(); - s1.execute("DROP TABLE IF EXISTS MULTI_B"); - s1.execute("CREATE TABLE MULTI_B(ID INT, NAME VARCHAR(255))"); - s2.execute("INSERT INTO MULTI_B VALUES(0, '1-insert-B')"); - c1.commit(); - c2.rollback(); - s1.execute("INSERT INTO MULTI_A VALUES(1, '0-insert-C')"); - s2.execute("INSERT INTO MULTI_B VALUES(1, '1-insert-D')"); - c1.rollback(); - c2.commit(); - c1.close(); - c2.close(); - - if (!config.memory) { - Connection conn = getConnection("multiConn"); - ResultSet rs; - rs = conn.createStatement().executeQuery("SELECT * FROM MULTI_A ORDER BY ID"); - rs.next(); - assertEquals("0-insert-A", rs.getString("NAME")); - assertFalse(rs.next()); - rs = conn.createStatement().executeQuery("SELECT * FROM MULTI_B ORDER BY ID"); - rs.next(); - assertEquals("1-insert-D", rs.getString("NAME")); - assertFalse(rs.next()); - conn.close(); - } - - } - - public void init(String url) { - // do nothing - } - - public void opened() { - // do nothing - } - -} diff --git a/tools/h2/src/test/org/h2/test/db/TestMultiDimension.java b/tools/h2/src/test/org/h2/test/db/TestMultiDimension.java deleted file mode 100755 index 95bc9ef..0000000 --- a/tools/h2/src/test/org/h2/test/db/TestMultiDimension.java +++ /dev/null @@ -1,131 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.test.db; - -import java.sql.Connection; -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.sql.Statement; -import java.util.Random; - -import org.h2.test.TestBase; -import org.h2.tools.MultiDimension; - -/** - * Tests the multi-dimension index tool. - */ -public class TestMultiDimension extends TestBase { - - /** - * Run just this test. - * - * @param a ignored - */ - public static void main(String... a) throws Exception { - TestBase.createCaller().init().test(); - } - - public void test() throws SQLException { - Random rand = new Random(10); - for (int i = 0; i < 1000; i++) { - int x = rand.nextInt(1000), y = rand.nextInt(1000), z = rand.nextInt(1000); - MultiDimension tool = MultiDimension.getInstance(); - long xyz = tool.interleave(new int[] { x, y, z }); - assertEquals(x, tool.deinterleave(xyz, 3, 0)); - assertEquals(y, tool.deinterleave(xyz, 3, 1)); - assertEquals(z, tool.deinterleave(xyz, 3, 2)); - } - - deleteDb("multiDimension"); - Connection conn; - conn = getConnection("multiDimension"); - Statement stat = conn.createStatement(); - stat.execute("CREATE ALIAS MAP FOR \"" + getClass().getName() + ".interleave\""); - stat.execute("CREATE TABLE TEST(X INT NOT NULL, Y INT NOT NULL, Z INT NOT NULL, " + - "XYZ BIGINT AS MAP(X, Y, Z), DATA VARCHAR)"); - stat.execute("CREATE INDEX IDX_X ON TEST(X, Y, Z)"); - stat.execute("CREATE INDEX IDX_XYZ ON TEST(XYZ)"); - PreparedStatement prep = conn.prepareStatement( - "INSERT INTO TEST(X, Y, Z, DATA) VALUES(?, ?, ?, ?)"); - // a reasonable max value to see the performance difference is 60; the - // higher the bigger the difference - int max = getSize(10, 20); - long time = System.currentTimeMillis(); - for (int x = 0; x < max; x++) { - for (int y = 0; y < max; y++) { - for (int z = 0; z < max; z++) { - long t2 = System.currentTimeMillis(); - if (t2 - time > 1000) { - int percent = (int) (100.0 * ((double) x * x * x) / ((double) max * max * max)); - trace(percent + "%"); - time = t2; - try { - Thread.sleep(10); - } catch (Exception e) { - // ignore - } - } - prep.setInt(1, x); - prep.setInt(2, y); - prep.setInt(3, z); - prep.setString(4, "Test data"); - prep.execute(); - } - } - } - stat.execute("ANALYZE SAMPLE_SIZE 10000"); - PreparedStatement prepRegular = conn.prepareStatement( - "SELECT * FROM TEST WHERE X BETWEEN ? AND ? " + - "AND Y BETWEEN ? AND ? AND Z BETWEEN ? AND ? ORDER BY X, Y, Z"); - MultiDimension multi = MultiDimension.getInstance(); - String sql = multi.generatePreparedQuery("TEST", "XYZ", new String[] { "X", "Y", "Z" }); - sql += " ORDER BY X, Y, Z"; - PreparedStatement prepMulti = conn.prepareStatement(sql); - long timeMulti = 0, timeRegular = 0; - int timeMax = getSize(100, 2000); - for (int i = 0; timeMulti < timeMax; i++) { - int size = rand.nextInt(max / 10); - int minX = rand.nextInt(max - size); - int minY = rand.nextInt(max - size); - int minZ = rand.nextInt(max - size); - int maxX = minX + size, maxY = minY + size, maxZ = minZ + size; - time = System.currentTimeMillis(); - ResultSet rs1 = multi.getResult(prepMulti, new int[] { minX, minY, minZ }, new int[] { maxX, maxY, maxZ }); - timeMulti += System.currentTimeMillis() - time; - time = System.currentTimeMillis(); - prepRegular.setInt(1, minX); - prepRegular.setInt(2, maxX); - prepRegular.setInt(3, minY); - prepRegular.setInt(4, maxY); - prepRegular.setInt(5, minZ); - prepRegular.setInt(6, maxZ); - ResultSet rs2 = prepRegular.executeQuery(); - timeRegular += System.currentTimeMillis() - time; - while (rs1.next()) { - assertTrue(rs2.next()); - assertEquals(rs1.getInt(1), rs2.getInt(1)); - assertEquals(rs1.getInt(2), rs2.getInt(2)); - } - assertFalse(rs2.next()); - } - conn.close(); - deleteDb("multiDimension"); - } - - /** - * This method is called via reflection from the database. - * - * @param x the x value - * @param y the y value - * @param z the z value - * @return the bit-interleaved value - */ - public static long interleave(int x, int y, int z) { - return MultiDimension.getInstance().interleave(new int[] { x, y, z }); - } -} diff --git a/tools/h2/src/test/org/h2/test/db/TestMultiThread.java b/tools/h2/src/test/org/h2/test/db/TestMultiThread.java deleted file mode 100755 index 95cc4eb..0000000 --- a/tools/h2/src/test/org/h2/test/db/TestMultiThread.java +++ /dev/null @@ -1,142 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.test.db; - -import java.sql.Connection; -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.sql.Statement; -import java.util.Random; -import org.h2.test.TestAll; -import org.h2.test.TestBase; - -/** - * Multi-threaded tests. - */ -public class TestMultiThread extends TestBase implements Runnable { - - private boolean stop; - private TestMultiThread parent; - private Random random; - private Connection threadConn; - private Statement threadStat; - - public TestMultiThread() { - // nothing to do - } - - private TestMultiThread(TestAll config, TestMultiThread parent) throws SQLException { - this.config = config; - this.parent = parent; - random = new Random(); - threadConn = getConnection(); - threadStat = threadConn.createStatement(); - } - - /** - * Run just this test. - * - * @param a ignored - */ - public static void main(String... a) throws Exception { - TestBase.createCaller().init().test(); - } - - public void test() throws Exception { - testConcurrentAnalyze(); - testConcurrentInsertUpdateSelect(); - } - - private void testConcurrentAnalyze() throws Exception { - if (config.mvcc) { - return; - } - deleteDb("concurrentAnalyze"); - final String url = getURL("concurrentAnalyze;MULTI_THREADED=1", true); - Connection conn = getConnection(url); - Statement stat = conn.createStatement(); - stat.execute("create table test(id bigint primary key) as select x from system_range(1, 1000)"); - final Exception[] ex = new Exception[1]; - Thread t = new Thread() { - public void run() { - try { - Connection conn2; - conn2 = getConnection(url); - for (int i = 0; i < 1000; i++) { - conn2.createStatement().execute("analyze"); - } - conn2.close(); - } catch (Exception e) { - ex[0] = e; - } - } - }; - t.start(); - Thread.yield(); - for (int i = 0; i < 1000; i++) { - conn.createStatement().execute("analyze"); - } - t.join(); - if (ex[0] != null) { - throw ex[0]; - } - stat.execute("drop table test"); - conn.close(); - deleteDb("concurrentAnalyze"); - } - - private void testConcurrentInsertUpdateSelect() throws Exception { - threadConn = getConnection(); - threadStat = threadConn.createStatement(); - threadStat.execute("CREATE TABLE TEST(ID IDENTITY, NAME VARCHAR)"); - int len = getSize(10, 200); - Thread[] threads = new Thread[len]; - for (int i = 0; i < len; i++) { - threads[i] = new Thread(new TestMultiThread(config, this)); - } - for (int i = 0; i < len; i++) { - threads[i].start(); - } - int sleep = getSize(400, 10000); - Thread.sleep(sleep); - this.stop = true; - for (int i = 0; i < len; i++) { - threads[i].join(); - } - ResultSet rs = threadStat.executeQuery("SELECT COUNT(*) FROM TEST"); - rs.next(); - trace("max id=" + rs.getInt(1)); - threadConn.close(); - } - - private Connection getConnection() throws SQLException { - return getConnection("jdbc:h2:mem:multiThread"); - } - - public void run() { - try { - while (!parent.stop) { - threadStat.execute("SELECT COUNT(*) FROM TEST"); - threadStat.execute("INSERT INTO TEST VALUES(NULL, 'Hi')"); - PreparedStatement prep = threadConn.prepareStatement("UPDATE TEST SET NAME='Hello' WHERE ID=?"); - prep.setInt(1, random.nextInt(10000)); - prep.execute(); - prep = threadConn.prepareStatement("SELECT * FROM TEST WHERE ID=?"); - prep.setInt(1, random.nextInt(10000)); - ResultSet rs = prep.executeQuery(); - while (rs.next()) { - rs.getString("NAME"); - } - } - threadConn.close(); - } catch (Exception e) { - logError("multi", e); - } - } - -} diff --git a/tools/h2/src/test/org/h2/test/db/TestMultiThreadedKernel.java b/tools/h2/src/test/org/h2/test/db/TestMultiThreadedKernel.java deleted file mode 100755 index 4a84a9c..0000000 --- a/tools/h2/src/test/org/h2/test/db/TestMultiThreadedKernel.java +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.test.db; - -import java.sql.Connection; -import java.sql.DriverManager; -import java.sql.Statement; -import org.h2.test.TestBase; -import org.h2.util.JdbcUtils; - -/** - * A multi-threaded test case. - */ -public class TestMultiThreadedKernel extends TestBase { - - /** - * Stop the current thread. - */ - volatile boolean stop; - - /** - * The exception that occurred in the thread. - */ - Exception exception; - - /** - * Run just this test. - * - * @param a ignored - */ - public static void main(String... a) throws Exception { - TestBase.createCaller().init().test(); - } - - public void test() throws Exception { - if (config.mvcc) { - return; - } - deleteDb("multiThreadedKernel"); - final String url = getURL("multiThreadedKernel;DB_CLOSE_DELAY=-1;MULTI_THREADED=1", true); - final String user = getUser(), password = getPassword(); - int len = 3; - Thread[] threads = new Thread[len]; - for (int i = 0; i < len; i++) { - threads[i] = new Thread(new Runnable() { - public void run() { - Connection conn = null; - try { - for (int j = 0; j < 100 && !stop; j++) { - conn = DriverManager.getConnection(url, user, password); - Statement stat = conn.createStatement(); - stat.execute("create local temporary table temp(id identity)"); - stat.execute("insert into temp values(1)"); - conn.close(); - } - } catch (Exception e) { - exception = e; - } finally { - JdbcUtils.closeSilently(conn); - } - } - }); - } - for (int i = 0; i < len; i++) { - threads[i].start(); - } - Thread.sleep(1000); - stop = true; - for (int i = 0; i < len; i++) { - threads[i].join(); - } - Connection conn = DriverManager.getConnection(url, user, password); - conn.createStatement().execute("shutdown"); - conn.close(); - if (exception != null) { - throw exception; - } - deleteDb("multiThreadedKernel"); - } - -} diff --git a/tools/h2/src/test/org/h2/test/db/TestOpenClose.java b/tools/h2/src/test/org/h2/test/db/TestOpenClose.java deleted file mode 100755 index 1c4d595..0000000 --- a/tools/h2/src/test/org/h2/test/db/TestOpenClose.java +++ /dev/null @@ -1,222 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.test.db; - -import java.sql.Connection; -import java.sql.DriverManager; -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.sql.Statement; - -import org.h2.api.DatabaseEventListener; -import org.h2.test.TestBase; -import org.h2.tools.Restore; -import org.h2.util.IOUtils; - -/** - * Tests opening and closing a database. - */ -public class TestOpenClose extends TestBase implements DatabaseEventListener { - - private int nextId = 10; - - /** - * Run just this test. - * - * @param a ignored - */ - public static void main(String... a) throws Exception { - TestBase.createCaller().init().test(); - } - - public void test() throws Exception { - testCloseDelay(); - testBackup(); - testCase(); - testReconnectFast(); - deleteDb("openClose"); - } - - private void testCloseDelay() throws Exception { - deleteDb("openClose"); - String url = getURL("openClose;DB_CLOSE_DELAY=1", true); - String user = getUser(), password = getPassword(); - Connection conn = DriverManager.getConnection(url, user, password); - conn.close(); - Thread.sleep(950); - long time = System.currentTimeMillis(); - for (int i = 0; System.currentTimeMillis() - time < 100; i++) { - conn = DriverManager.getConnection(url, user, password); - conn.close(); - } - conn = DriverManager.getConnection(url, user, password); - conn.createStatement().execute("SHUTDOWN"); - conn.close(); - } - - private void testBackup() throws SQLException { - if (config.memory) { - return; - } - deleteDb("openClose"); - String url = getURL("openClose", true); - org.h2.Driver.load(); - Connection conn = DriverManager.getConnection(url, "sa", "abc def"); - Statement stat = conn.createStatement(); - stat.execute("CREATE TABLE TEST(C CLOB)"); - stat.execute("INSERT INTO TEST VALUES(SPACE(10000))"); - stat.execute("BACKUP TO '" + getBaseDir() + "/test.zip'"); - conn.close(); - deleteDb("openClose"); - Restore.execute(getBaseDir() + "/test.zip", getBaseDir(), null, true); - conn = DriverManager.getConnection(url, "sa", "abc def"); - stat = conn.createStatement(); - ResultSet rs = stat.executeQuery("SELECT * FROM TEST"); - rs.next(); - assertEquals(10000, rs.getString(1).length()); - assertFalse(rs.next()); - conn.close(); - IOUtils.delete(getBaseDir() + "/test.zip"); - } - - private void testReconnectFast() throws SQLException { - if (config.memory) { - return; - } - - deleteDb("openClose"); - String user = getUser(), password = getPassword(); - String url = getURL("openClose;DATABASE_EVENT_LISTENER='" + TestOpenClose.class.getName() - + "'", true); - Connection conn = DriverManager.getConnection(url, user, password); - Statement stat = conn.createStatement(); - try { - stat.execute("CREATE TABLE TEST(ID IDENTITY, NAME VARCHAR)"); - stat.execute("SET MAX_MEMORY_UNDO 100000"); - stat.execute("CREATE INDEX IDXNAME ON TEST(NAME)"); - stat.execute("INSERT INTO TEST SELECT X, X || ' Data' FROM SYSTEM_RANGE(1, 1000)"); - } catch (SQLException e) { - // ok - } - stat.close(); - conn.close(); - conn = DriverManager.getConnection(url, user, password); - stat = conn.createStatement(); - ResultSet rs = stat.executeQuery("SELECT * FROM DUAL"); - if (rs.next()) { - rs.getString(1); - } - rs.close(); - stat.close(); - conn.close(); - conn = DriverManager.getConnection(url, user, password); - stat = conn.createStatement(); - // stat.execute("SET DB_CLOSE_DELAY 0"); - stat.executeUpdate("SHUTDOWN"); - stat.close(); - conn.close(); - } - - private void testCase() throws Exception { - if (config.memory) { - return; - } - - org.h2.Driver.load(); - deleteDb("openClose"); - final String url = getURL("openClose;FILE_LOCK=NO", true); - final String user = getUser(), password = getPassword(); - Connection conn = DriverManager.getConnection(url, user, password); - conn.createStatement().execute("drop table employee if exists"); - conn.createStatement().execute("create table employee(id int primary key, name varchar, salary int)"); - conn.close(); - // previously using getSize(200, 1000); - // but for Ubuntu, the default ulimit is 1024, - // which breaks the test - int len = getSize(10, 50); - Thread[] threads = new Thread[len]; - for (int i = 0; i < len; i++) { - threads[i] = new Thread() { - public void run() { - try { - Connection c = DriverManager.getConnection(url, user, password); - PreparedStatement prep = c.prepareStatement("insert into employee values(?, ?, 0)"); - int id = getNextId(); - prep.setInt(1, id); - prep.setString(2, "employee " + id); - prep.execute(); - c.close(); - } catch (Throwable e) { - TestBase.logError("insert", e); - } - } - }; - threads[i].start(); - } - // for(int i=0; i 0) { - throw new AssertionError("unexpected: " + stateName); - } - break; - case STATE_CREATE_INDEX: - stateName = "Create Index " + name + " " + current + "/" + max; - if (!"SYS:SYS_ID".equals(name)) { - throw new AssertionError("unexpected: " + stateName); - } - break; - case STATE_RECOVER: - stateName = "Recover " + current + "/" + max; - break; - default: - stateName = "?"; - } - // System.out.println(": " + stateName); - } - - public void closingDatabase() { - // nothing to do - } - - public void init(String url) { - // nothing to do - } - - public void opened() { - // nothing to do - } - -} diff --git a/tools/h2/src/test/org/h2/test/db/TestOptimizations.java b/tools/h2/src/test/org/h2/test/db/TestOptimizations.java deleted file mode 100755 index b4e7db1..0000000 --- a/tools/h2/src/test/org/h2/test/db/TestOptimizations.java +++ /dev/null @@ -1,607 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.test.db; - -import java.sql.Connection; -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.sql.Statement; -import java.sql.Types; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.Random; -import java.util.TreeSet; -import org.h2.constant.SysProperties; -import org.h2.test.TestBase; -import org.h2.tools.SimpleResultSet; -import org.h2.util.New; - -/** - * Test various optimizations (query cache, optimization for MIN(..), and - * MAX(..)). - */ -public class TestOptimizations extends TestBase { - - /** - * Run just this test. - * - * @param a ignored - */ - public static void main(String... a) throws Exception { - TestBase.createCaller().init().test(); - } - - public void test() throws Exception { - testSortIndex(); - testAutoAnalyze(); - testInAndBetween(); - testNestedIn(); - testNestedInSelectAndLike(); - testNestedInSelect(); - testInSelectJoin(); - testMinMaxNullOptimization(); - if (config.networked) { - return; - } - testOptimizeInJoinSelect(); - testOptimizeInJoin(); - testMultiColumnRangeQuery(); - testDistinctOptimization(); - testQueryCacheTimestamp(); - testQueryCacheSpeed(); - testQueryCache(true); - testQueryCache(false); - testIn(); - testMinMaxCountOptimization(true); - testMinMaxCountOptimization(false); - deleteDb("optimizations"); - } - - private void testSortIndex() throws SQLException { - Connection conn = getConnection("optimizations"); - Statement stat = conn.createStatement(); - stat.execute("drop table test if exists"); - stat.execute("create table test(id int)"); - stat.execute("create index idx_id_desc on test(id desc)"); - stat.execute("create index idx_id_asc on test(id)"); - ResultSet rs; - - rs = stat.executeQuery("explain select * from test where id > 10 order by id"); - rs.next(); - assertTrue(rs.getString(1).indexOf("IDX_ID_ASC") >= 0); - - rs = stat.executeQuery("explain select * from test where id < 10 order by id desc"); - rs.next(); - assertTrue(rs.getString(1).indexOf("IDX_ID_DESC") >= 0); - - rs.next(); - stat.execute("drop table test"); - conn.close(); - } - - private void testAutoAnalyze() throws SQLException { - int auto = SysProperties.ANALYZE_AUTO; - if (auto == 0) { - return; - } - deleteDb("optimizations"); - Connection conn = getConnection("optimizations"); - Statement stat = conn.createStatement(); - stat.execute("create table test(id int)"); - stat.execute("create user onlyInsert password ''"); - stat.execute("grant insert on test to onlyInsert"); - Connection conn2 = getConnection("optimizations", "onlyInsert", getPassword("")); - Statement stat2 = conn2.createStatement(); - stat2.execute("insert into test select x from system_range(1, " + (auto + 10) + ")"); - conn.close(); - conn2.close(); - } - - private void testInAndBetween() throws SQLException { - deleteDb("optimizations"); - Connection conn = getConnection("optimizations"); - Statement stat = conn.createStatement(); - ResultSet rs; - stat.execute("create table test(id int, name varchar)"); - stat.execute("create index idx_name on test(id, name)"); - stat.execute("insert into test values(1, 'Hello'), (2, 'World')"); - rs = stat.executeQuery("select * from test where id between 1 and 3 and name in ('World')"); - assertTrue(rs.next()); - rs = stat.executeQuery("select * from test where id between 1 and 3 and name in (select 'World')"); - assertTrue(rs.next()); - stat.execute("drop table test"); - conn.close(); - } - - private void testNestedIn() throws SQLException { - deleteDb("optimizations"); - Connection conn = getConnection("optimizations"); - Statement stat = conn.createStatement(); - ResultSet rs; - - stat.execute("create table accounts(id integer primary key, status varchar(255), tag varchar(255))"); - stat.execute("insert into accounts values (31, 'X', 'A')"); - stat.execute("create table parent(id int)"); - stat.execute("insert into parent values(31)"); - stat.execute("create view test_view as select a.status, a.tag from accounts a, parent t where a.id = t.id"); - rs = stat.executeQuery("select * from test_view where status='X' and tag in ('A','B')"); - assertTrue(rs.next()); - rs = stat.executeQuery("select * from (select a.status, a.tag from accounts a, parent t where a.id = t.id) x where status='X' and tag in ('A','B')"); - assertTrue(rs.next()); - - stat.execute("create table test(id int primary key, name varchar(255))"); - stat.execute("create unique index idx_name on test(name, id)"); - stat.execute("insert into test values(1, 'Hello'), (2, 'World')"); - rs = stat.executeQuery("select * from (select * from test) where id=1 and name in('Hello', 'World')"); - assertTrue(rs.next()); - stat.execute("drop table test"); - - conn.close(); - } - - private void testNestedInSelect() throws SQLException { - deleteDb("optimizations"); - Connection conn = getConnection("optimizations"); - Statement stat = conn.createStatement(); - ResultSet rs; - - stat.execute("create table test(id int primary key, name varchar) as select 1, 'Hello'"); - stat.execute("select * from (select * from test) where id=1 and name in('Hello', 'World')"); - - stat.execute("drop table test"); - - stat.execute("create table test(id int, name varchar) as select 1, 'Hello'"); - stat.execute("create index idx2 on test(id, name)"); - rs = stat.executeQuery("select count(*) from test where id=1 and name in('Hello', 'x')"); - rs.next(); - assertEquals(1, rs.getInt(1)); - - conn.close(); - } - - private void testNestedInSelectAndLike() throws SQLException { - deleteDb("optimizations"); - Connection conn = getConnection("optimizations"); - Statement stat = conn.createStatement(); - - stat.execute("create table test(id int primary key)"); - stat.execute("insert into test values(2)"); - ResultSet rs = stat.executeQuery("select * from test where id in(1, 2)"); - assertTrue(rs.next()); - assertEquals(2, rs.getInt(1)); - assertFalse(rs.next()); - stat.execute("create table test2(id int primary key hash)"); - stat.execute("insert into test2 values(2)"); - rs = stat.executeQuery("select * from test where id in(1, 2)"); - assertTrue(rs.next()); - assertEquals(2, rs.getInt(1)); - assertFalse(rs.next()); - - PreparedStatement prep; - prep = conn.prepareStatement("SELECT * FROM DUAL A WHERE A.X IN (SELECT B.X FROM DUAL B WHERE B.X LIKE ?)"); - prep.setString(1, "1"); - prep.execute(); - prep = conn.prepareStatement("SELECT * FROM DUAL A WHERE A.X IN (SELECT B.X FROM DUAL B WHERE B.X IN (?, ?))"); - prep.setInt(1, 1); - prep.setInt(2, 1); - prep.executeQuery(); - conn.close(); - } - - private void testInSelectJoin() throws SQLException { - deleteDb("optimizations"); - Connection conn = getConnection("optimizations"); - Statement stat = conn.createStatement(); - stat.execute("create table test(a int, b int, c int, d int) " + - "as select 1, 1, 1, 1 from dual;"); - ResultSet rs; - PreparedStatement prep; - prep = conn.prepareStatement("SELECT 2 FROM TEST A " - + "INNER JOIN (SELECT DISTINCT B.C AS X FROM TEST B " - + "WHERE B.D = ?2) V ON 1=1 WHERE (A = ?1) AND (B = V.X)"); - prep.setInt(1, 1); - prep.setInt(2, 1); - rs = prep.executeQuery(); - assertTrue(rs.next()); - assertFalse(rs.next()); - - prep = conn.prepareStatement( - "select 2 from test a where a=? and b in(" + - "select b.c from test b where b.d=?)"); - prep.setInt(1, 1); - prep.setInt(2, 1); - rs = prep.executeQuery(); - assertTrue(rs.next()); - assertFalse(rs.next()); - conn.close(); - } - - - private void testOptimizeInJoinSelect() throws SQLException { - deleteDb("optimizations"); - Connection conn = getConnection("optimizations"); - Statement stat = conn.createStatement(); - stat.execute("create table item(id int primary key)"); - stat.execute("insert into item values(1)"); - stat.execute("create alias opt for \"" + - getClass().getName() + - ".optimizeInJoinSelect\""); - PreparedStatement prep = conn.prepareStatement( - "select * from item where id in (select x from opt())"); - ResultSet rs = prep.executeQuery(); - assertTrue(rs.next()); - assertEquals(1, rs.getInt(1)); - assertFalse(rs.next()); - conn.close(); - } - - /** - * This method is called via reflection from the database. - * - * @return a result set - */ - public static ResultSet optimizeInJoinSelect() { - SimpleResultSet rs = new SimpleResultSet(); - rs.addColumn("X", Types.INTEGER, 0, 0); - rs.addRow(1); - return rs; - } - - private void testOptimizeInJoin() throws SQLException { - deleteDb("optimizations"); - Connection conn = getConnection("optimizations"); - Statement stat = conn.createStatement(); - - stat.execute("create table test(id int primary key)"); - stat.execute("insert into test select x from system_range(1, 1000)"); - ResultSet rs = stat.executeQuery("explain select * from test where id in (400, 300)"); - rs.next(); - String plan = rs.getString(1); - if (plan.indexOf("/* PUBLIC.PRIMARY_KEY_") < 0) { - fail("Expected using the primary key, got: " + plan); - } - conn.close(); - } - - private void testMinMaxNullOptimization() throws SQLException { - deleteDb("optimizations"); - Connection conn = getConnection("optimizations"); - Statement stat = conn.createStatement(); - Random random = new Random(1); - int len = getSize(50, 500); - for (int i = 0; i < len; i++) { - stat.execute("drop table if exists test"); - stat.execute("create table test(x int)"); - if (random.nextBoolean()) { - int count = random.nextBoolean() ? 1 : 1 + random.nextInt(len); - if (count > 0) { - stat.execute("insert into test select null from system_range(1, " + count + ")"); - } - } - int maxExpected = -1; - int minExpected = -1; - if (random.nextInt(10) != 1) { - minExpected = 1; - maxExpected = 1 + random.nextInt(len); - stat.execute("insert into test select x from system_range(1, " + maxExpected + ")"); - } - String sql = "create index idx on test(x"; - if (random.nextBoolean()) { - sql += " desc"; - } - if (random.nextBoolean()) { - if (random.nextBoolean()) { - sql += " nulls first"; - } else { - sql += " nulls last"; - } - } - sql += ")"; - stat.execute(sql); - ResultSet rs = stat.executeQuery("explain select min(x), max(x) from test"); - rs.next(); - if (!config.mvcc) { - String plan = rs.getString(1); - assertTrue(plan.indexOf("direct") > 0); - } - rs = stat.executeQuery("select min(x), max(x) from test"); - rs.next(); - int min = rs.getInt(1); - if (rs.wasNull()) { - min = -1; - } - int max = rs.getInt(2); - if (rs.wasNull()) { - max = -1; - } - assertEquals(minExpected, min); - assertEquals(maxExpected, max); - } - conn.close(); - } - - private void testMultiColumnRangeQuery() throws SQLException { - deleteDb("optimizations"); - Connection conn = getConnection("optimizations"); - Statement stat = conn.createStatement(); - stat.execute("CREATE TABLE Logs(id INT PRIMARY KEY, type INT)"); - stat.execute("CREATE unique INDEX type_index ON Logs(type, id)"); - stat.execute("INSERT INTO Logs SELECT X, MOD(X, 3) FROM SYSTEM_RANGE(1, 1000)"); - stat.execute("ANALYZE SAMPLE_SIZE 0"); - ResultSet rs; - rs = stat.executeQuery("EXPLAIN SELECT id FROM Logs WHERE id < 100 and type=2 AND id<100"); - rs.next(); - String plan = rs.getString(1); - assertTrue(plan.indexOf("TYPE_INDEX") > 0); - conn.close(); - } - - private void testDistinctOptimization() throws SQLException { - deleteDb("optimizations"); - Connection conn = getConnection("optimizations"); - Statement stat = conn.createStatement(); - stat.execute("CREATE TABLE TEST(ID INT PRIMARY KEY, NAME VARCHAR, TYPE INT)"); - stat.execute("CREATE INDEX IDX_TEST_TYPE ON TEST(TYPE)"); - Random random = new Random(1); - int len = getSize(10000, 100000); - int[] groupCount = new int[10]; - PreparedStatement prep = conn.prepareStatement("INSERT INTO TEST VALUES(?, ?, ?)"); - for (int i = 0; i < len; i++) { - prep.setInt(1, i); - prep.setString(2, "Hello World"); - int type = random.nextInt(10); - groupCount[type]++; - prep.setInt(3, type); - prep.execute(); - } - ResultSet rs; - rs = stat.executeQuery("SELECT TYPE, COUNT(*) FROM TEST GROUP BY TYPE ORDER BY TYPE"); - for (int i = 0; rs.next(); i++) { - assertEquals(i, rs.getInt(1)); - assertEquals(groupCount[i], rs.getInt(2)); - } - assertFalse(rs.next()); - rs = stat.executeQuery("SELECT DISTINCT TYPE FROM TEST ORDER BY TYPE"); - for (int i = 0; rs.next(); i++) { - assertEquals(i, rs.getInt(1)); - } - assertFalse(rs.next()); - stat.execute("ANALYZE"); - rs = stat.executeQuery("SELECT DISTINCT TYPE FROM TEST ORDER BY TYPE"); - for (int i = 0; i < 10; i++) { - assertTrue(rs.next()); - assertEquals(i, rs.getInt(1)); - } - assertFalse(rs.next()); - rs = stat.executeQuery("SELECT DISTINCT TYPE FROM TEST ORDER BY TYPE LIMIT 5 OFFSET 2"); - for (int i = 2; i < 7; i++) { - assertTrue(rs.next()); - assertEquals(i, rs.getInt(1)); - } - assertFalse(rs.next()); - rs = stat.executeQuery("SELECT DISTINCT TYPE FROM TEST ORDER BY TYPE LIMIT 0 OFFSET 0 SAMPLE_SIZE 3"); - // must have at least one row - assertTrue(rs.next()); - for (int i = 0; i < 3; i++) { - rs.getInt(1); - if (i > 0 && !rs.next()) { - break; - } - } - assertFalse(rs.next()); - conn.close(); - } - - private void testQueryCacheTimestamp() throws Exception { - deleteDb("optimizations"); - Connection conn = getConnection("optimizations"); - PreparedStatement prep = conn.prepareStatement("SELECT CURRENT_TIMESTAMP()"); - ResultSet rs = prep.executeQuery(); - rs.next(); - String a = rs.getString(1); - Thread.sleep(50); - rs = prep.executeQuery(); - rs.next(); - String b = rs.getString(1); - assertFalse(a.equals(b)); - conn.close(); - } - - private void testQueryCacheSpeed() throws SQLException { - deleteDb("optimizations"); - Connection conn = getConnection("optimizations"); - Statement stat = conn.createStatement(); - testQuerySpeed(stat, - "select sum(a.n), sum(b.x) from system_range(1, 100) b, (select sum(x) n from system_range(1, 4000)) a"); - conn.close(); - } - - private void testQuerySpeed(Statement stat, String sql) throws SQLException { - stat.execute("set OPTIMIZE_REUSE_RESULTS 0"); - stat.execute(sql); - long time = System.currentTimeMillis(); - stat.execute(sql); - time = System.currentTimeMillis() - time; - stat.execute("set OPTIMIZE_REUSE_RESULTS 1"); - stat.execute(sql); - long time2 = System.currentTimeMillis(); - stat.execute(sql); - time2 = System.currentTimeMillis() - time2; - if (time2 > time * 2) { - fail("not optimized: " + time + " optimized: " + time2 + " sql:" + sql); - } - } - - private void testQueryCache(boolean optimize) throws SQLException { - deleteDb("optimizations"); - Connection conn = getConnection("optimizations"); - Statement stat = conn.createStatement(); - if (optimize) { - stat.execute("set OPTIMIZE_REUSE_RESULTS 1"); - } else { - stat.execute("set OPTIMIZE_REUSE_RESULTS 0"); - } - stat.execute("create table test(id int)"); - stat.execute("create table test2(id int)"); - stat.execute("insert into test values(1), (1), (2)"); - stat.execute("insert into test2 values(1)"); - PreparedStatement prep = conn.prepareStatement("select * from test where id = (select id from test2)"); - ResultSet rs1 = prep.executeQuery(); - rs1.next(); - assertEquals(1, rs1.getInt(1)); - rs1.next(); - assertEquals(1, rs1.getInt(1)); - assertFalse(rs1.next()); - - stat.execute("update test2 set id = 2"); - ResultSet rs2 = prep.executeQuery(); - rs2.next(); - assertEquals(2, rs2.getInt(1)); - - conn.close(); - } - - private void testMinMaxCountOptimization(boolean memory) throws SQLException { - deleteDb("optimizations"); - Connection conn = getConnection("optimizations"); - Statement stat = conn.createStatement(); - stat.execute("create " + (memory ? "memory" : "") + " table test(id int primary key, value int)"); - stat.execute("create index idx_value_id on test(value, id);"); - int len = getSize(1000, 10000); - HashMap map = New.hashMap(); - TreeSet set = new TreeSet(); - Random random = new Random(1); - for (int i = 0; i < len; i++) { - if (i == len / 2) { - if (!config.memory) { - conn.close(); - conn = getConnection("optimizations"); - stat = conn.createStatement(); - } - } - switch (random.nextInt(10)) { - case 0: - case 1: - case 2: - case 3: - case 4: - case 5: - if (random.nextInt(1000) == 1) { - stat.execute("insert into test values(" + i + ", null)"); - map.put(new Integer(i), null); - } else { - int value = random.nextInt(); - stat.execute("insert into test values(" + i + ", " + value + ")"); - map.put(new Integer(i), new Integer(value)); - set.add(new Integer(value)); - } - break; - case 6: - case 7: - case 8: { - if (map.size() > 0) { - for (int j = random.nextInt(i), k = 0; k < 10; k++, j++) { - if (map.containsKey(j)) { - Integer x = map.remove(j); - if (x != null) { - set.remove(x); - } - stat.execute("delete from test where id=" + j); - } - } - } - break; - } - case 9: { - ArrayList list = New.arrayList(map.values()); - int count = list.size(); - Integer min = null, max = null; - if (count > 0) { - min = set.first(); - max = set.last(); - } - ResultSet rs = stat.executeQuery("select min(value), max(value), count(*) from test"); - rs.next(); - Integer minDb = (Integer) rs.getObject(1); - Integer maxDb = (Integer) rs.getObject(2); - int countDb = rs.getInt(3); - assertEquals(minDb, min); - assertEquals(maxDb, max); - assertEquals(countDb, count); - break; - } - default: - } - } - conn.close(); - } - - private void testIn() throws SQLException { - deleteDb("optimizations"); - Connection conn = getConnection("optimizations"); - Statement stat = conn.createStatement(); - PreparedStatement prep; - ResultSet rs; - - assertFalse(stat.executeQuery("select * from dual where x in()").next()); - assertFalse(stat.executeQuery("select * from dual where null in(1)").next()); - assertFalse(stat.executeQuery("select * from dual where null in(null)").next()); - assertFalse(stat.executeQuery("select * from dual where null in(null, 1)").next()); - - assertFalse(stat.executeQuery("select * from dual where 1+x in(3, 4)").next()); - assertFalse(stat.executeQuery("select * from dual d1, dual d2 where d1.x in(3, 4)").next()); - - stat.execute("create table test(id int primary key, name varchar)"); - stat.execute("insert into test values(1, 'Hello')"); - stat.execute("insert into test values(2, 'World')"); - - prep = conn.prepareStatement("select * from test t1 where t1.id in(?)"); - prep.setInt(1, 1); - rs = prep.executeQuery(); - rs.next(); - assertEquals(1, rs.getInt(1)); - assertEquals("Hello", rs.getString(2)); - assertFalse(rs.next()); - - prep = conn.prepareStatement("select * from test t1 where t1.id in(?, ?) order by id"); - prep.setInt(1, 1); - prep.setInt(2, 2); - rs = prep.executeQuery(); - rs.next(); - assertEquals(1, rs.getInt(1)); - assertEquals("Hello", rs.getString(2)); - rs.next(); - assertEquals(2, rs.getInt(1)); - assertEquals("World", rs.getString(2)); - assertFalse(rs.next()); - - prep = conn.prepareStatement("select * from test t1 where t1.id " - + "in(select t2.id from test t2 where t2.id=?)"); - prep.setInt(1, 2); - rs = prep.executeQuery(); - rs.next(); - assertEquals(2, rs.getInt(1)); - assertEquals("World", rs.getString(2)); - assertFalse(rs.next()); - - prep = conn.prepareStatement("select * from test t1 where t1.id " - + "in(select t2.id from test t2 where t2.id=? and t1.id<>t2.id)"); - prep.setInt(1, 2); - rs = prep.executeQuery(); - assertFalse(rs.next()); - - prep = conn.prepareStatement("select * from test t1 where t1.id " - + "in(select t2.id from test t2 where t2.id in(cast(?+10 as varchar)))"); - prep.setInt(1, 2); - rs = prep.executeQuery(); - assertFalse(rs.next()); - - conn.close(); - } - -} diff --git a/tools/h2/src/test/org/h2/test/db/TestOutOfMemory.java b/tools/h2/src/test/org/h2/test/db/TestOutOfMemory.java deleted file mode 100755 index c3b946a..0000000 --- a/tools/h2/src/test/org/h2/test/db/TestOutOfMemory.java +++ /dev/null @@ -1,80 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.test.db; - -import java.sql.Connection; -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.sql.Statement; -import org.h2.constant.ErrorCode; -import org.h2.test.TestBase; - -/** - * Tests out of memory situations. The database must not get corrupted, and - * transactions must stay atomic. - */ -public class TestOutOfMemory extends TestBase { - - /** - * Run just this test. - * - * @param a ignored - */ - public static void main(String... a) throws Exception { - TestBase.createCaller().init().test(); - } - - public void test() throws SQLException { - if (config.memory || config.mvcc) { - return; - } - for (int i = 0; i < 5; i++) { - System.gc(); - } - deleteDb("outOfMemory"); - Connection conn = getConnection("outOfMemory"); - Statement stat = conn.createStatement(); - stat.execute("drop all objects"); - stat.execute("create table stuff (id int, text varchar as space(100) || id)"); - stat.execute("insert into stuff(id) select x from system_range(1, 3000)"); - PreparedStatement prep = conn.prepareStatement("update stuff set text = text || ' upd'"); - prep.execute(); - stat.execute("checkpoint"); - eatMemory(80); - try { - try { - prep.execute(); - fail(); - } catch (SQLException e) { - assertEquals(ErrorCode.OUT_OF_MEMORY, e.getErrorCode()); - try { - conn.close(); - fail(); - } catch (SQLException e2) { - assertEquals(ErrorCode.DATABASE_IS_CLOSED, e2.getErrorCode()); - } - } - freeMemory(); - conn = null; - conn = getConnection("outOfMemory"); - stat = conn.createStatement(); - ResultSet rs = stat.executeQuery("select count(*) from stuff"); - rs.next(); - assertEquals(3000, rs.getInt(1)); - } finally { - try { - conn.close(); - } catch (SQLException e) { - // out of memory will close the database - assertKnownException(e); - } - } - deleteDb("outOfMemory"); - } - -} diff --git a/tools/h2/src/test/org/h2/test/db/TestPowerOff.java b/tools/h2/src/test/org/h2/test/db/TestPowerOff.java deleted file mode 100755 index 82cf0c6..0000000 --- a/tools/h2/src/test/org/h2/test/db/TestPowerOff.java +++ /dev/null @@ -1,311 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.test.db; - -import java.sql.Connection; -import java.sql.DatabaseMetaData; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.sql.Statement; -import java.util.Random; -import org.h2.constant.ErrorCode; -import org.h2.constant.SysProperties; -import org.h2.engine.Database; -import org.h2.jdbc.JdbcConnection; -import org.h2.test.TestBase; -import org.h2.util.JdbcUtils; - -/** - * Tests simulated power off conditions. - */ -public class TestPowerOff extends TestBase { - - private String dbName = "powerOff"; - private String dir, url; - - private int maxPowerOffCount; - - /** - * Run just this test. - * - * @param a ignored - */ - public static void main(String... a) throws Exception { - TestBase.createCaller().init().test(); - } - - public void test() throws SQLException { - if (config.memory) { - return; - } - if (config.big || config.googleAppEngine) { - dir = getBaseDir(); - url = dbName; - } else { - dir = "memFS:"; - url = "memFS:/" + dbName; - } - url += ";FILE_LOCK=NO;TRACE_LEVEL_FILE=0"; - testSummaryCrash(); - testCrash(); - testShutdown(); - testMemoryTables(); - testPersistentTables(); - deleteDb(dir, dbName); - } - - private void testSummaryCrash() throws SQLException { - if (config.networked) { - return; - } - deleteDb(dir, dbName); - Connection conn = getConnection(url); - Statement stat = conn.createStatement(); - for (int i = 0; i < 10; i++) { - stat.execute("CREATE TABLE TEST" + i + "(ID INT PRIMARY KEY, NAME VARCHAR)"); - for (int j = 0; j < 10; j++) { - stat.execute("INSERT INTO TEST" + i + " VALUES(" + j + ", 'Hello')"); - } - } - for (int i = 0; i < 10; i += 2) { - stat.execute("DROP TABLE TEST" + i); - } - stat.execute("SET WRITE_DELAY 0"); - stat.execute("CHECKPOINT"); - for (int j = 0; j < 10; j++) { - stat.execute("INSERT INTO TEST1 VALUES(" + (10 + j) + ", 'World')"); - } - stat.execute("SHUTDOWN IMMEDIATELY"); - JdbcUtils.closeSilently(conn); - conn = getConnection(url); - stat = conn.createStatement(); - for (int i = 1; i < 10; i += 2) { - ResultSet rs = stat.executeQuery("SELECT * FROM TEST" + i + " ORDER BY ID"); - for (int j = 0; j < 10; j++) { - rs.next(); - assertEquals(j, rs.getInt(1)); - assertEquals("Hello", rs.getString(2)); - } - if (i == 1) { - for (int j = 0; j < 10; j++) { - rs.next(); - assertEquals(j + 10, rs.getInt(1)); - assertEquals("World", rs.getString(2)); - } - } - assertFalse(rs.next()); - } - conn.close(); - } - - private void testCrash() throws SQLException { - if (config.networked) { - return; - } - deleteDb(dir, dbName); - Random random = new Random(1); - SysProperties.runFinalize = false; - int repeat = getSize(1, 20); - for (int i = 0; i < repeat; i++) { - Connection conn = getConnection(url); - conn.close(); - conn = getConnection(url); - Statement stat = conn.createStatement(); - stat.execute("SET WRITE_DELAY 0"); - ((JdbcConnection) conn).setPowerOffCount(random.nextInt(100)); - try { - stat.execute("DROP TABLE IF EXISTS TEST"); - stat.execute("CREATE TABLE TEST(ID INT PRIMARY KEY, NAME VARCHAR(255))"); - conn.setAutoCommit(false); - int len = getSize(3, 100); - for (int j = 0; j < len; j++) { - stat.execute("INSERT INTO TEST VALUES(" + j + ", 'Hello')"); - if (random.nextInt(5) == 0) { - conn.commit(); - } - if (random.nextInt(10) == 0) { - stat.execute("DROP TABLE IF EXISTS TEST"); - stat.execute("CREATE TABLE TEST(ID INT PRIMARY KEY, NAME VARCHAR(255))"); - } - } - stat.execute("DROP TABLE IF EXISTS TEST"); - conn.close(); - } catch (SQLException e) { - if (!e.getSQLState().equals("90098")) { - TestBase.logError("power", e); - } - } - } - } - - private void testShutdown() throws SQLException { - deleteDb(dir, dbName); - Connection conn = getConnection(url); - Statement stat = conn.createStatement(); - stat.execute("CREATE TABLE TEST(ID INT PRIMARY KEY, NAME VARCHAR(255))"); - stat.execute("INSERT INTO TEST VALUES(1, 'Hello')"); - stat.execute("SHUTDOWN"); - conn.close(); - - conn = getConnection(url); - stat = conn.createStatement(); - ResultSet rs = stat.executeQuery("SELECT * FROM TEST"); - assertTrue(rs.next()); - assertFalse(rs.next()); - conn.close(); - } - - private void testMemoryTables() throws SQLException { - if (config.networked) { - return; - } - deleteDb(dir, dbName); - - Connection conn = getConnection(url); - Statement stat = conn.createStatement(); - stat.execute("CREATE MEMORY TABLE TEST(ID INT PRIMARY KEY, NAME VARCHAR(255))"); - stat.execute("INSERT INTO TEST VALUES(1, 'Hello')"); - stat.execute("CHECKPOINT"); - ((JdbcConnection) conn).setPowerOffCount(1); - try { - stat.execute("INSERT INTO TEST VALUES(2, 'Hello')"); - stat.execute("INSERT INTO TEST VALUES(3, 'Hello')"); - stat.execute("CHECKPOINT"); - fail(); - } catch (SQLException e) { - assertKnownException(e); - } - - ((JdbcConnection) conn).setPowerOffCount(0); - try { - conn.close(); - } catch (SQLException e) { - // ignore - } - conn = getConnection(url); - stat = conn.createStatement(); - ResultSet rs = stat.executeQuery("SELECT COUNT(*) FROM TEST"); - rs.next(); - assertEquals(1, rs.getInt(1)); - conn.close(); - } - - private void testPersistentTables() throws SQLException { - if (config.networked) { - return; - } - if (config.cipher != null) { - // this would take too long (setLength uses - // individual writes, many thousand operations) - return; - } - deleteDb(dir, dbName); - - // ((JdbcConnection)conn).setPowerOffCount(Integer.MAX_VALUE); - testRun(true); - int max = maxPowerOffCount; - trace("max=" + max); - runTest(0, max, true); - recoverAndCheckConsistency(); - runTest(0, max, false); - recoverAndCheckConsistency(); - } - - private void runTest(int min, int max, boolean withConsistencyCheck) throws SQLException { - for (int i = min; i < max; i++) { - deleteDb(dir, dbName); - Database.setInitialPowerOffCount(i); - int expect = testRun(false); - if (withConsistencyCheck) { - int got = recoverAndCheckConsistency(); - trace("test " + i + " of " + max + " expect=" + expect + " got=" + got); - } else { - trace("test " + i + " of " + max + " expect=" + expect); - } - } - Database.setInitialPowerOffCount(0); - } - - private int testRun(boolean init) throws SQLException { - if (init) { - Database.setInitialPowerOffCount(Integer.MAX_VALUE); - } - int state = 0; - try { - Connection conn = getConnection(url); - Statement stat = conn.createStatement(); - stat.execute("SET WRITE_DELAY 0"); - stat.execute("CREATE TABLE IF NOT EXISTS TEST(ID INT PRIMARY KEY, NAME VARCHAR(255))"); - state = 1; - conn.setAutoCommit(false); - stat.execute("INSERT INTO TEST VALUES(1, 'Hello')"); - stat.execute("INSERT INTO TEST VALUES(2, 'World')"); - conn.commit(); - state = 2; - stat.execute("UPDATE TEST SET NAME='Hallo' WHERE ID=1"); - stat.execute("UPDATE TEST SET NAME='Welt' WHERE ID=2"); - conn.commit(); - state = 3; - stat.execute("DELETE FROM TEST WHERE ID=1"); - stat.execute("DELETE FROM TEST WHERE ID=2"); - conn.commit(); - state = 1; - stat.execute("DROP TABLE TEST"); - state = 0; - if (init) { - maxPowerOffCount = Integer.MAX_VALUE - ((JdbcConnection) conn).getPowerOffCount(); - } - conn.close(); - } catch (SQLException e) { - if (e.getSQLState().equals("" + ErrorCode.DATABASE_IS_CLOSED)) { - // this is ok - } else { - throw e; - } - } - return state; - } - - private int recoverAndCheckConsistency() throws SQLException { - int state; - Database.setInitialPowerOffCount(0); - Connection conn = getConnection(url); - if (((JdbcConnection) conn).getPowerOffCount() != 0) { - fail("power off count is not 0"); - } - Statement stat = conn.createStatement(); - DatabaseMetaData meta = conn.getMetaData(); - ResultSet rs = meta.getTables(null, null, "TEST", null); - if (!rs.next()) { - state = 0; - } else { - // table does not exist - rs = stat.executeQuery("SELECT * FROM TEST ORDER BY ID"); - if (!rs.next()) { - state = 1; - } else { - assertEquals(1, rs.getInt(1)); - String name1 = rs.getString(2); - assertTrue(rs.next()); - assertEquals(2, rs.getInt(1)); - String name2 = rs.getString(2); - assertFalse(rs.next()); - if ("Hello".equals(name1)) { - assertEquals("World", name2); - state = 2; - } else { - assertEquals("Hallo", name1); - assertEquals("Welt", name2); - state = 3; - } - } - } - conn.close(); - return state; - } - -} diff --git a/tools/h2/src/test/org/h2/test/db/TestReadOnly.java b/tools/h2/src/test/org/h2/test/db/TestReadOnly.java deleted file mode 100755 index 2bf0a77..0000000 --- a/tools/h2/src/test/org/h2/test/db/TestReadOnly.java +++ /dev/null @@ -1,154 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.test.db; - -import java.io.File; -import java.io.RandomAccessFile; -import java.sql.Connection; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.sql.Statement; -import java.util.ArrayList; -import org.h2.constant.ErrorCode; -import org.h2.store.FileLister; -import org.h2.store.fs.FileSystem; -import org.h2.test.TestBase; - -/** - * Test for the read-only database feature. - */ -public class TestReadOnly extends TestBase { - - /** - * Run just this test. - * - * @param a ignored - */ - public static void main(String... a) throws Exception { - TestBase.createCaller().init().test(); - } - - public void test() throws Exception { - if (config.memory) { - return; - } - testReadOnlyConnect(); - testReadOnlyDbCreate(); - if (!config.googleAppEngine) { - testReadOnlyFiles(true); - } - testReadOnlyFiles(false); - deleteDb("readonly"); - } - - private void testReadOnlyDbCreate() throws SQLException { - deleteDb("readonly"); - Connection conn = getConnection("readonly"); - conn.close(); - conn = getConnection("readonly;ACCESS_MODE_DATA=r"); - Statement stat = conn.createStatement(); - try { - stat.execute("CREATE TABLE TEST(ID INT)"); - fail(); - } catch (SQLException e) { - assertKnownException(e); - } - try { - stat.execute("SELECT * FROM TEST"); - fail(); - } catch (SQLException e) { - assertKnownException(e); - } - stat.execute("create local temporary linked table test(null, 'jdbc:h2:mem:test3', 'sa', 'sa', 'INFORMATION_SCHEMA.TABLES')"); - ResultSet rs = stat.executeQuery("select * from test"); - assertTrue(rs.next()); - conn.close(); - } - - private void testReadOnlyFiles(boolean setReadOnly) throws Exception { - new File(System.getProperty("java.io.tmpdir")).mkdirs(); - File f = File.createTempFile("test", "temp"); - assertTrue(f.canWrite()); - f.setReadOnly(); - assertTrue(!f.canWrite()); - f.delete(); - - f = File.createTempFile("test", "temp"); - RandomAccessFile r = new RandomAccessFile(f, "rw"); - r.write(1); - f.setReadOnly(); - r.close(); - assertTrue(!f.canWrite()); - f.delete(); - - deleteDb("readonly"); - Connection conn = getConnection("readonly"); - Statement stat = conn.createStatement(); - stat.execute("CREATE TABLE TEST(ID INT PRIMARY KEY, NAME VARCHAR)"); - stat.execute("INSERT INTO TEST VALUES(1, 'Hello')"); - stat.execute("INSERT INTO TEST VALUES(2, 'World')"); - assertTrue(!conn.isReadOnly()); - conn.close(); - - if (setReadOnly) { - setReadOnly(); - conn = getConnection("readonly"); - } else { - conn = getConnection("readonly;ACCESS_MODE_DATA=r"); - } - assertTrue(conn.isReadOnly()); - stat = conn.createStatement(); - stat.execute("SELECT * FROM TEST"); - try { - stat.execute("DELETE FROM TEST"); - fail("read only delete"); - } catch (SQLException e) { - assertKnownException(e); - } - conn.close(); - - if (setReadOnly) { - conn = getConnection("readonly;DB_CLOSE_DELAY=1"); - } else { - conn = getConnection("readonly;DB_CLOSE_DELAY=1;ACCESS_MODE_DATA=r"); - } - stat = conn.createStatement(); - stat.execute("SELECT * FROM TEST"); - try { - stat.execute("DELETE FROM TEST"); - fail("read only delete"); - } catch (SQLException e) { - assertKnownException(e); - } - stat.execute("SET DB_CLOSE_DELAY=0"); - conn.close(); - } - - private void setReadOnly() { - FileSystem fs = FileSystem.getInstance(getBaseDir()); - ArrayList list = FileLister.getDatabaseFiles(getBaseDir(), "readonly", true); - for (String fileName : list) { - fs.setReadOnly(fileName); - } - } - - private void testReadOnlyConnect() throws SQLException { - deleteDb("readonly"); - Connection conn = getConnection("readonly;OPEN_NEW=TRUE"); - Statement stat = conn.createStatement(); - stat.execute("create table test(id identity)"); - stat.execute("insert into test select x from system_range(1, 11)"); - try { - getConnection("readonly;ACCESS_MODE_DATA=r;OPEN_NEW=TRUE"); - } catch (SQLException e) { - assertEquals(ErrorCode.DATABASE_ALREADY_OPEN_1, e.getErrorCode()); - } - conn.close(); - deleteDb("readonly"); - } - -} diff --git a/tools/h2/src/test/org/h2/test/db/TestRights.java b/tools/h2/src/test/org/h2/test/db/TestRights.java deleted file mode 100755 index 90add92..0000000 --- a/tools/h2/src/test/org/h2/test/db/TestRights.java +++ /dev/null @@ -1,343 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.test.db; - -import java.sql.Connection; -import java.sql.DatabaseMetaData; -import java.sql.ResultSet; -import java.sql.ResultSetMetaData; -import java.sql.SQLException; -import java.sql.Statement; - -import org.h2.constant.ErrorCode; -import org.h2.test.TestBase; -import org.h2.util.IOUtils; - -/** - * Access rights tests. - */ -public class TestRights extends TestBase { - - private Statement stat; - - /** - * Run just this test. - * - * @param a ignored - */ - public static void main(String... a) throws Exception { - TestBase.createCaller().init().test(); - } - - public void test() throws SQLException { - testDropOwnUser(); - testGetTables(); - testDropTempTables(); - // testLowerCaseUser(); - testSchemaRenameUser(); - testAccessRights(); - deleteDb("rights"); - } - - private void testDropOwnUser() throws SQLException { - deleteDb("rights"); - String user = getUser().toUpperCase(); - Connection conn = getConnection("rights"); - stat = conn.createStatement(); - try { - stat.execute("DROP USER " + user); - fail(); - } catch (SQLException e) { - assertEquals(ErrorCode.CANNOT_DROP_CURRENT_USER, e.getErrorCode()); - } - stat.execute("CREATE USER TEST PASSWORD 'TEST' ADMIN"); - stat.execute("DROP USER " + user); - conn.close(); - if (!config.memory) { - try { - getConnection("rights"); - fail(); - } catch (SQLException e) { - assertKnownException(e); - } - } - } - -// public void testLowerCaseUser() throws SQLException { - // Documentation: for compatibility, - // only unquoted or uppercase user names are allowed. -// deleteDb("rights"); -// Connection conn = getConnection("rights"); -// stat = conn.createStatement(); -// stat.execute("CREATE USER \"TEST1\" PASSWORD 'abc'"); -// stat.execute("CREATE USER \"Test2\" PASSWORD 'abc'"); -// conn.close(); -// conn = getConnection("rights", "TEST1", "abc"); -// conn.close(); -// conn = getConnection("rights", "Test2", "abc"); -// conn.close(); -// } - - private void testGetTables() throws SQLException { - deleteDb("rights"); - Connection conn = getConnection("rights"); - stat = conn.createStatement(); - - stat.execute("CREATE USER IF NOT EXISTS TEST PASSWORD 'TEST'"); - stat.execute("CREATE TABLE TEST(ID INT)"); - stat.execute("GRANT ALL ON TEST TO TEST"); - Connection conn2 = getConnection("rights", "TEST", getPassword("TEST")); - DatabaseMetaData meta = conn2.getMetaData(); - meta.getTables(null, null, "%", new String[]{"TABLE", "VIEW", "SEQUENCE"}); - conn2.close(); - conn.close(); - } - - private void testDropTempTables() throws SQLException { - deleteDb("rights"); - Connection conn = getConnection("rights"); - stat = conn.createStatement(); - stat.execute("CREATE USER IF NOT EXISTS READER PASSWORD 'READER'"); - stat.execute("CREATE TABLE TEST(ID INT)"); - Connection conn2 = getConnection("rights", "READER", getPassword("READER")); - Statement stat2 = conn2.createStatement(); - try { - stat2.execute("SELECT * FROM TEST"); - fail(); - } catch (SQLException e) { - assertKnownException(e); - } - stat2.execute("CREATE LOCAL TEMPORARY TABLE IF NOT EXISTS MY_TEST(ID INT)"); - stat2.execute("INSERT INTO MY_TEST VALUES(1)"); - stat2.execute("SELECT * FROM MY_TEST"); - stat2.execute("DROP TABLE MY_TEST"); - conn2.close(); - conn.close(); - } - - private void testSchemaRenameUser() throws SQLException { - if (config.memory) { - return; - } - deleteDb("rights"); - Connection conn = getConnection("rights"); - stat = conn.createStatement(); - stat.execute("create user test password '' admin"); - stat.execute("create schema b authorization test"); - stat.execute("create table b.test(id int)"); - stat.execute("alter user test rename to test1"); - conn.close(); - conn = getConnection("rights"); - stat = conn.createStatement(); - stat.execute("select * from b.test"); - try { - stat.execute("alter user test1 admin false"); - fail(); - } catch (SQLException e) { - assertKnownException(e); - } - try { - stat.execute("drop user test1"); - fail(); - } catch (SQLException e) { - assertKnownException(e); - } - stat.execute("drop schema b"); - stat.execute("alter user test1 admin false"); - stat.execute("drop user test1"); - conn.close(); - } - - private void testAccessRights() throws SQLException { - if (config.memory) { - return; - } - - deleteDb("rights"); - Connection conn = getConnection("rights"); - stat = conn.createStatement(); - // default table type - testTableType(conn, "MEMORY"); - testTableType(conn, "CACHED"); - - // rights on tables and views - executeSuccess("CREATE USER PASS_READER PASSWORD 'abc'"); - executeSuccess("CREATE TABLE TEST(ID INT PRIMARY KEY, NAME VARCHAR)"); - executeSuccess("CREATE TABLE PASS(ID INT PRIMARY KEY, NAME VARCHAR, PASSWORD VARCHAR)"); - executeSuccess("CREATE VIEW PASS_NAME AS SELECT ID, NAME FROM PASS"); - executeSuccess("GRANT SELECT ON PASS_NAME TO PASS_READER"); - executeSuccess("GRANT SELECT, INSERT, UPDATE ON TEST TO PASS_READER"); - conn.close(); - - conn = getConnection("rights", "PASS_READER", getPassword("abc")); - stat = conn.createStatement(); - executeSuccess("SELECT * FROM PASS_NAME"); - executeSuccess("SELECT * FROM (SELECT * FROM PASS_NAME)"); - executeSuccess("SELECT (SELECT NAME FROM PASS_NAME) P FROM PASS_NAME"); - executeError("SELECT (SELECT PASSWORD FROM PASS) P FROM PASS_NAME"); - executeError("SELECT * FROM PASS"); - executeError("INSERT INTO TEST SELECT 1, PASSWORD FROM PASS"); - executeError("INSERT INTO TEST VALUES(SELECT PASSWORD FROM PASS)"); - executeError("UPDATE TEST SET NAME=(SELECT PASSWORD FROM PASS)"); - executeError("DELETE FROM TEST WHERE NAME=(SELECT PASSWORD FROM PASS)"); - executeError("SELECT * FROM (SELECT * FROM PASS)"); - executeError("CREATE VIEW X AS SELECT * FROM PASS_READER"); - conn.close(); - - conn = getConnection("rights"); - stat = conn.createStatement(); - - executeSuccess("DROP TABLE TEST"); - executeSuccess("CREATE USER TEST PASSWORD 'abc'"); - executeSuccess("ALTER USER TEST ADMIN TRUE"); - executeSuccess("CREATE TABLE TEST(ID INT)"); - executeSuccess("CREATE SCHEMA SCHEMA_A AUTHORIZATION SA"); - executeSuccess("CREATE TABLE SCHEMA_A.TABLE_B(ID INT)"); - executeSuccess("GRANT ALL ON SCHEMA_A.TABLE_B TO TEST"); - executeSuccess("CREATE TABLE HIDDEN(ID INT)"); - executeSuccess("CREATE TABLE PUB_TABLE(ID INT)"); - executeSuccess("CREATE TABLE ROLE_TABLE(ID INT)"); - executeSuccess("CREATE ROLE TEST_ROLE"); - executeSuccess("GRANT SELECT ON ROLE_TABLE TO TEST_ROLE"); - executeSuccess("GRANT UPDATE ON ROLE_TABLE TO TEST_ROLE"); - executeSuccess("REVOKE UPDATE ON ROLE_TABLE FROM TEST_ROLE"); - executeError("REVOKE SELECT, SUB1 ON ROLE_TABLE FROM TEST_ROLE"); - executeSuccess("GRANT TEST_ROLE TO TEST"); - executeSuccess("GRANT SELECT ON PUB_TABLE TO PUBLIC"); - executeSuccess("GRANT SELECT ON TEST TO TEST"); - executeSuccess("CREATE ROLE SUB1"); - executeSuccess("CREATE ROLE SUB2"); - executeSuccess("CREATE TABLE SUB_TABLE(ID INT)"); - executeSuccess("GRANT ALL ON SUB_TABLE TO SUB2"); - executeSuccess("REVOKE UPDATE, DELETE ON SUB_TABLE FROM SUB2"); - executeSuccess("GRANT SUB2 TO SUB1"); - executeSuccess("GRANT SUB1 TO TEST"); - - executeSuccess("ALTER USER TEST SET PASSWORD 'def'"); - executeSuccess("CREATE USER TEST2 PASSWORD 'def' ADMIN"); - executeSuccess("ALTER USER TEST ADMIN FALSE"); - executeSuccess("SCRIPT TO '" + getBaseDir() + "/rights.sql' CIPHER XTEA PASSWORD 'test'"); - conn.close(); - - try { - conn = getConnection("rights", "Test", getPassword("abc")); - fail("mixed case user name"); - } catch (SQLException e) { - assertKnownException(e); - } - try { - conn = getConnection("rights", "TEST", getPassword("abc")); - fail("wrong password"); - } catch (SQLException e) { - assertKnownException(e); - } - try { - getConnection("rights", "TEST", getPassword("")); - fail("wrong password"); - } catch (SQLException e) { - assertKnownException(e); - } - conn = getConnection("rights", "TEST", getPassword("def")); - stat = conn.createStatement(); - - executeError("SET DEFAULT_TABLE_TYPE MEMORY"); - - executeSuccess("SELECT * FROM TEST"); - executeSuccess("SELECT * FROM SYSTEM_RANGE(1,2)"); - executeSuccess("SELECT * FROM SCHEMA_A.TABLE_B"); - executeSuccess("SELECT * FROM PUB_TABLE"); - executeSuccess("SELECT * FROM ROLE_TABLE"); - executeError("UPDATE ROLE_TABLE SET ID=0"); - executeError("DELETE FROM ROLE_TABLE"); - executeError("SELECT * FROM HIDDEN"); - executeError("UPDATE TEST SET ID=0"); - executeError("CALL SELECT MIN(PASSWORD) FROM PASS"); - executeSuccess("SELECT * FROM SUB_TABLE"); - executeSuccess("INSERT INTO SUB_TABLE VALUES(1)"); - executeError("DELETE FROM SUB_TABLE"); - executeError("UPDATE FROM SUB_TABLE"); - - executeError("CREATE USER TEST3 PASSWORD 'def'"); - executeError("ALTER USER TEST2 ADMIN FALSE"); - executeError("ALTER USER TEST2 SET PASSWORD 'ghi'"); - executeError("ALTER USER TEST2 RENAME TO TEST_X"); - executeError("ALTER USER TEST RENAME TO TEST_X"); - executeSuccess("ALTER USER TEST SET PASSWORD 'ghi'"); - executeError("DROP USER TEST2"); - - conn.close(); - conn = getConnection("rights"); - stat = conn.createStatement(); - executeSuccess("DROP ROLE SUB1"); - executeSuccess("DROP TABLE ROLE_TABLE"); - executeSuccess("DROP USER TEST"); - - conn.close(); - conn = getConnection("rights"); - stat = conn.createStatement(); - - executeSuccess("DROP TABLE IF EXISTS TEST"); - executeSuccess("CREATE TABLE TEST(ID INT PRIMARY KEY, NAME VARCHAR(255))"); - executeSuccess("CREATE USER GUEST PASSWORD 'abc'"); - executeSuccess("GRANT SELECT ON TEST TO GUEST"); - executeSuccess("ALTER USER GUEST RENAME TO GAST"); - conn.close(); - conn = getConnection("rights"); - conn.close(); - IOUtils.delete(getBaseDir() + "/rights.sql"); - } - - private void testTableType(Connection conn, String type) throws SQLException { - executeSuccess("SET DEFAULT_TABLE_TYPE " + type); - executeSuccess("CREATE TABLE TEST(ID INT)"); - ResultSet rs = conn.createStatement().executeQuery( - "SELECT STORAGE_TYPE FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME='TEST'"); - rs.next(); - assertEquals(type, rs.getString(1)); - executeSuccess("DROP TABLE TEST"); - } - - private void executeError(String sql) { - try { - stat.execute(sql); - fail("not admin"); - } catch (SQLException e) { - assertKnownException(e); - } - } - - private void executeSuccess(String sql) throws SQLException { - if (stat.execute(sql)) { - ResultSet rs = stat.getResultSet(); - - // this will check if the result set is updatable - rs.getConcurrency(); - - ResultSetMetaData meta = rs.getMetaData(); - int columnCount = meta.getColumnCount(); - for (int i = 0; i < columnCount; i++) { - meta.getCatalogName(i + 1); - meta.getColumnClassName(i + 1); - meta.getColumnDisplaySize(i + 1); - meta.getColumnLabel(i + 1); - meta.getColumnName(i + 1); - meta.getColumnType(i + 1); - meta.getColumnTypeName(i + 1); - meta.getPrecision(i + 1); - meta.getScale(i + 1); - meta.getSchemaName(i + 1); - meta.getTableName(i + 1); - } - while (rs.next()) { - for (int i = 0; i < columnCount; i++) { - rs.getObject(i + 1); - } - } - } - } - -} diff --git a/tools/h2/src/test/org/h2/test/db/TestRunscript.java b/tools/h2/src/test/org/h2/test/db/TestRunscript.java deleted file mode 100755 index 1bcdc4f..0000000 --- a/tools/h2/src/test/org/h2/test/db/TestRunscript.java +++ /dev/null @@ -1,151 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.test.db; - -import java.sql.Connection; -import java.sql.SQLException; -import java.sql.Statement; - -import org.h2.api.Trigger; -import org.h2.test.TestBase; -import org.h2.util.IOUtils; - -/** - * Tests the RUNSCRIPT SQL statement. - */ -public class TestRunscript extends TestBase implements Trigger { - - /** - * Run just this test. - * - * @param a ignored - */ - public static void main(String... a) throws Exception { - TestBase.createCaller().init().test(); - } - - public void test() throws SQLException { - testClobPrimaryKey(); - test(false); - test(true); - deleteDb("runscript"); - } - - /** - * This method is called via reflection from the database. - * - * @param a the value - * @return the absolute value - */ - public static int test(int a) { - return Math.abs(a); - } - - private void testClobPrimaryKey() throws SQLException { - deleteDb("runscript"); - Connection conn; - Statement stat; - conn = getConnection("runscript"); - stat = conn.createStatement(); - stat.execute("create table test(id int not null, data clob) as select 1, space(4100)"); - // the primary key for SYSTEM_LOB_STREAM used to be named like this - stat.execute("create primary key primary_key_e on test(id)"); - stat.execute("script to '" + getBaseDir() + "/backup.sql'"); - conn.close(); - deleteDb("runscript"); - conn = getConnection("runscript"); - stat = conn.createStatement(); - stat.execute("runscript from '" + getBaseDir() + "/backup.sql'"); - conn.close(); - deleteDb("runscriptRestore"); - IOUtils.delete(getBaseDir() + "/backup.sql"); - } - - private void test(boolean password) throws SQLException { - deleteDb("runscript"); - Connection conn1, conn2; - Statement stat1, stat2; - conn1 = getConnection("runscript"); - stat1 = conn1.createStatement(); - stat1.execute("create table test (id identity, name varchar(12))"); - stat1.execute("insert into test (name) values ('first'), ('second')"); - stat1.execute("create sequence testSeq start with 100 increment by 10"); - stat1.execute("create alias myTest for \"" + getClass().getName() + ".test\""); - stat1.execute("create trigger myTrigger before insert on test nowait call \"" + getClass().getName() + "\""); - stat1.execute("create view testView as select * from test where 1=0 union all select * from test where 0=1"); - stat1.execute("create user testAdmin salt '00' hash '01' admin"); - stat1.execute("create schema testSchema authorization testAdmin"); - stat1.execute("create table testSchema.parent(id int primary key, name varchar)"); - stat1.execute("create index idxname on testSchema.parent(name)"); - stat1 - .execute("create table testSchema.child(id int primary key, parentId int, name varchar, foreign key(parentId) references parent(id))"); - stat1.execute("create user testUser salt '02' hash '03'"); - stat1.execute("create role testRole"); - stat1.execute("grant all on testSchema.child to testUser"); - stat1.execute("grant select, insert on testSchema.parent to testRole"); - stat1.execute("grant testRole to testUser"); - - String sql = "script to '" + getBaseDir() + "/backup.2.sql'"; - if (password) { - sql += " CIPHER AES PASSWORD 't1e2s3t4'"; - } - stat1.execute(sql); - - deleteDb("runscriptRestore"); - conn2 = getConnection("runscriptRestore"); - stat2 = conn2.createStatement(); - sql = "runscript from '" + getBaseDir() + "/backup.2.sql'"; - if (password) { - sql += " CIPHER AES PASSWORD 'wrongPassword'"; - } - if (password) { - try { - stat2.execute(sql); - fail(); - } catch (SQLException e) { - assertKnownException(e); - } - } - sql = "runscript from '" + getBaseDir() + "/backup.2.sql'"; - if (password) { - sql += " CIPHER AES PASSWORD 't1e2s3t4'"; - } - stat2.execute(sql); - stat2.execute("script to '" + getBaseDir() + "/backup.3.sql'"); - - assertEqualDatabases(stat1, stat2); - - conn1.close(); - conn2.close(); - deleteDb("runscriptRestore"); - IOUtils.delete(getBaseDir() + "/backup.2.sql"); - IOUtils.delete(getBaseDir() + "/backup.3.sql"); - - } - - public void init(Connection conn, String schemaName, String triggerName, String tableName, boolean before, int type) { - if (!before) { - throw new InternalError("before:" + before); - } - if (type != INSERT) { - throw new InternalError("type:" + type); - } - } - - public void fire(Connection conn, Object[] oldRow, Object[] newRow) { - // nothing to do - } - - public void close() { - // ignore - } - - public void remove() { - // ignore - } - -} diff --git a/tools/h2/src/test/org/h2/test/db/TestSQLInjection.java b/tools/h2/src/test/org/h2/test/db/TestSQLInjection.java deleted file mode 100755 index b80f77d..0000000 --- a/tools/h2/src/test/org/h2/test/db/TestSQLInjection.java +++ /dev/null @@ -1,122 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.test.db; - -import java.sql.Connection; -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.sql.Statement; - -import org.h2.test.TestBase; - -/** - * Tests the ALLOW_LITERALS feature (protection against SQL injection). - */ -public class TestSQLInjection extends TestBase { - - private Connection conn; - private Statement stat; - - /** - * Run just this test. - * - * @param a ignored - */ - public static void main(String... a) throws Exception { - TestBase.createCaller().init().test(); - } - - public void test() throws SQLException { - deleteDb("sqlInjection"); - reconnect("sqlInjection"); - stat.execute("DROP TABLE IF EXISTS USERS"); - stat.execute("CREATE TABLE USERS(NAME VARCHAR PRIMARY KEY, PASSWORD VARCHAR, TYPE VARCHAR)"); - stat.execute("CREATE SCHEMA CONST"); - stat.execute("CREATE CONSTANT CONST.ACTIVE VALUE 'Active'"); - stat.execute("INSERT INTO USERS VALUES('James', '123456', CONST.ACTIVE)"); - assertTrue(checkPasswordInsecure("123456")); - assertFalse(checkPasswordInsecure("abcdef")); - assertTrue(checkPasswordInsecure("' OR ''='")); - assertTrue(checkPasswordSecure("123456")); - assertFalse(checkPasswordSecure("abcdef")); - assertFalse(checkPasswordSecure("' OR ''='")); - stat.execute("CALL 123"); - stat.execute("CALL 'Hello'"); - stat.execute("CALL $$Hello World$$"); - stat.execute("SET ALLOW_LITERALS NUMBERS"); - stat.execute("CALL 123"); - try { - stat.execute("CALL 'Hello'"); - fail(); - } catch (SQLException e) { - assertKnownException(e); - } - try { - stat.execute("CALL $$Hello World$$"); - fail(); - } catch (SQLException e) { - assertKnownException(e); - } - - stat.execute("SET ALLOW_LITERALS NONE"); - - try { - assertTrue(checkPasswordInsecure("123456")); - fail(); - } catch (SQLException e) { - assertKnownException(e); - } - assertTrue(checkPasswordSecure("123456")); - assertFalse(checkPasswordSecure("' OR ''='")); - conn.close(); - - if (config.memory) { - return; - } - - reconnect("sqlInjection"); - - try { - assertTrue(checkPasswordInsecure("123456")); - fail("Should fail now"); - } catch (SQLException e) { - assertKnownException(e); - } - assertTrue(checkPasswordSecure("123456")); - assertFalse(checkPasswordSecure("' OR ''='")); - conn.close(); - deleteDb("sqlInjection"); - } - - private boolean checkPasswordInsecure(String pwd) throws SQLException { - String sql = "SELECT * FROM USERS WHERE PASSWORD='" + pwd + "'"; - ResultSet rs = conn.createStatement().executeQuery(sql); - return rs.next(); - } - - private boolean checkPasswordSecure(String pwd) throws SQLException { - String sql = "SELECT * FROM USERS WHERE PASSWORD=?"; - PreparedStatement prep = conn.prepareStatement(sql); - prep.setString(1, pwd); - ResultSet rs = prep.executeQuery(); - return rs.next(); - } - - private void reconnect(String name) throws SQLException { - if (!config.memory) { - if (conn != null) { - conn.close(); - conn = null; - } - } - if (conn == null) { - conn = getConnection(name); - stat = conn.createStatement(); - } - } -} diff --git a/tools/h2/src/test/org/h2/test/db/TestScript.java b/tools/h2/src/test/org/h2/test/db/TestScript.java deleted file mode 100755 index 84f2510..0000000 --- a/tools/h2/src/test/org/h2/test/db/TestScript.java +++ /dev/null @@ -1,380 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.test.db; - -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.io.LineNumberReader; -import java.io.PrintStream; -import java.sql.Connection; -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.ResultSetMetaData; -import java.sql.SQLException; -import java.sql.Statement; -import java.util.ArrayList; -import org.h2.engine.Constants; -import org.h2.test.TestAll; -import org.h2.test.TestBase; -import org.h2.util.New; -import org.h2.util.StringUtils; - -/** - * This test runs a SQL script file and compares the output with the expected - * output. - */ -public class TestScript extends TestBase { - - private boolean failFast; - - private boolean alwaysReconnect; - private Connection conn; - private Statement stat; - private LineNumberReader in; - private int line; - private PrintStream out; - private ArrayList result = New.arrayList(); - private String putBack; - private StringBuilder errors; - private ArrayList statements; - private String fileName = "org/h2/test/test-" + - Constants.VERSION_MAJOR + "." + Constants.VERSION_MINOR + ".txt"; - - /** - * Run just this test. - * - * @param a ignored - */ - public static void main(String... a) throws Exception { - TestBase.createCaller().init().test(); - } - - /** - * Get all SQL statements of this file. - * - * @param conf the configuration - * @return the list of statements - */ - public ArrayList getAllStatements(TestAll conf) throws Exception { - config = conf; - statements = New.arrayList(); - test(); - return statements; - } - - public void test() throws Exception { - if (config.networked && config.big) { - return; - } - alwaysReconnect = false; - if (!config.memory) { - if (config.big) { - alwaysReconnect = true; - } - } - testScript(); - deleteDb("script"); - } - - private void testScript() throws Exception { - deleteDb("script"); - String outFile = "test.out.txt"; - String inFile = fileName; - conn = getConnection("script"); - stat = conn.createStatement(); - out = new PrintStream(new FileOutputStream(outFile)); - errors = new StringBuilder(); - testFile(inFile); - conn.close(); - out.close(); - if (errors.length() > 0) { - throw new Exception("errors:\n" + errors.toString()); - } - // new File(outFile).delete(); - } - - private String readLine() throws IOException { - if (putBack != null) { - String s = putBack; - putBack = null; - return s; - } - while (true) { - String s = in.readLine(); - if (s == null) { - return s; - } - s = s.trim(); - if (s.length() > 0) { - return s; - } - } - } - - private void testFile(String inFile) throws Exception { - InputStream is = getClass().getClassLoader().getResourceAsStream(inFile); - in = new LineNumberReader(new InputStreamReader(is, "Cp1252")); - StringBuilder buff = new StringBuilder(); - while (true) { - String sql = readLine(); - if (sql == null) { - break; - } - if (sql.startsWith("--")) { - write(sql); - } else if (sql.startsWith(">")) { - // do nothing - } else if (sql.endsWith(";")) { - write(sql); - buff.append(sql.substring(0, sql.length() - 1)); - sql = buff.toString(); - buff = new StringBuilder(); - process(sql); - } else { - write(sql); - buff.append(sql); - buff.append('\n'); - } - } - } - - private boolean containsTempTables() throws SQLException { - ResultSet rs = conn.getMetaData().getTables(null, null, null, new String[] { "TABLE" }); - while (rs.next()) { - String sql = rs.getString("SQL"); - if (sql != null) { - if (sql.indexOf("TEMPORARY") >= 0) { - return true; - } - } - } - return false; - } - - private void process(String sql) throws Exception { - if (alwaysReconnect) { - if (!containsTempTables()) { - boolean autocommit = conn.getAutoCommit(); - if (autocommit) { - conn.close(); - conn = getConnection("script"); - conn.setAutoCommit(autocommit); - stat = conn.createStatement(); - } - } - } - if (statements != null) { - statements.add(sql); - } - if (sql.indexOf('?') == -1) { - processStatement(sql); - } else { - String param = readLine(); - write(param); - if (!param.equals("{")) { - throw new AssertionError("expected '{', got " + param + " in " + sql); - } - try { - PreparedStatement prep = conn.prepareStatement(sql); - int count = 0; - while (true) { - param = readLine(); - write(param); - if (param.startsWith("}")) { - break; - } - count += processPrepared(sql, prep, param); - } - writeResult(sql, "update count: " + count, null); - } catch (SQLException e) { - writeException(sql, e); - } - } - write(""); - } - - private void setParameter(PreparedStatement prep, int i, String param) throws SQLException { - if (param.equalsIgnoreCase("null")) { - param = null; - } - prep.setString(i, param); - } - - private int processPrepared(String sql, PreparedStatement prep, String param) throws Exception { - try { - StringBuilder buff = new StringBuilder(); - int index = 0; - for (int i = 0; i < param.length(); i++) { - char c = param.charAt(i); - if (c == ',') { - setParameter(prep, ++index, buff.toString()); - buff = new StringBuilder(); - } else if (c == '"') { - while (true) { - c = param.charAt(++i); - if (c == '"') { - break; - } - buff.append(c); - } - } else if (c > ' ') { - buff.append(c); - } - } - if (buff.length() > 0) { - setParameter(prep, ++index, buff.toString()); - } - if (prep.execute()) { - writeResultSet(sql, prep.getResultSet()); - return 0; - } - return prep.getUpdateCount(); - } catch (SQLException e) { - writeException(sql, e); - return 0; - } - } - - private int processStatement(String sql) throws Exception { - try { - if (stat.execute(sql)) { - writeResultSet(sql, stat.getResultSet()); - } else { - int count = stat.getUpdateCount(); - writeResult(sql, count < 1 ? "ok" : "update count: " + count, null); - } - } catch (SQLException e) { - writeException(sql, e); - } - return 0; - } - - private String formatString(String s) { - if (s == null) { - return "null"; - } - return s.replace('\n', ' '); - } - - private void writeResultSet(String sql, ResultSet rs) throws Exception { - boolean ordered = StringUtils.toLowerEnglish(sql).indexOf("order by") >= 0; - ResultSetMetaData meta = rs.getMetaData(); - int len = meta.getColumnCount(); - int[] max = new int[len]; - String[] head = new String[len]; - for (int i = 0; i < len; i++) { - String label = formatString(meta.getColumnLabel(i + 1)); - max[i] = label.length(); - head[i] = label; - } - result.clear(); - while (rs.next()) { - String[] row = new String[len]; - for (int i = 0; i < len; i++) { - String data = formatString(rs.getString(i + 1)); - if (max[i] < data.length()) { - max[i] = data.length(); - } - row[i] = data; - } - result.add(row); - } - rs.close(); - writeResult(sql, format(head, max), null); - writeResult(sql, format(null, max), null); - String[] array = new String[result.size()]; - for (int i = 0; i < result.size(); i++) { - array[i] = format(result.get(i), max); - } - if (!ordered) { - sort(array); - } - int i = 0; - for (; i < array.length; i++) { - writeResult(sql, array[i], null); - } - writeResult(sql, (ordered ? "rows (ordered): " : "rows: ") + i, null); - } - - private String format(String[] row, int[] max) { - int length = max.length; - StringBuilder buff = new StringBuilder(); - for (int i = 0; i < length; i++) { - if (i > 0) { - buff.append(' '); - } - if (row == null) { - for (int j = 0; j < max[i]; j++) { - buff.append('-'); - } - } else { - int len = row[i].length(); - buff.append(row[i]); - if (i < length - 1) { - for (int j = len; j < max[i]; j++) { - buff.append(' '); - } - } - } - } - return buff.toString(); - } - - private void writeException(String sql, SQLException e) throws Exception { - writeResult(sql, "exception", e); - } - - private void writeResult(String sql, String s, SQLException e) throws Exception { - assertKnownException(e); - s = ("> " + s).trim(); - String compare = readLine(); - if (compare != null && compare.startsWith(">")) { - if (!compare.equals(s)) { - if (alwaysReconnect && sql.toUpperCase().startsWith("EXPLAIN")) { - return; - } - errors.append("line: "); - errors.append(line); - errors.append("\n" + "exp: "); - errors.append(compare); - errors.append("\n" + "got: "); - errors.append(s); - errors.append("\n"); - if (e != null) { - TestBase.logError("script", e); - } - if (failFast) { - TestBase.logError(errors.toString(), null); - conn.close(); - System.exit(1); - } - } - } else { - putBack = compare; - } - write(s); - - } - - private void write(String s) { - line++; - out.println(s); - } - - private void sort(String[] a) { - for (int i = 1, j, len = a.length; i < len; i++) { - String t = a[i]; - for (j = i - 1; j >= 0 && t.compareTo(a[j]) < 0; j--) { - a[j + 1] = a[j]; - } - a[j + 1] = t; - } - } - -} diff --git a/tools/h2/src/test/org/h2/test/db/TestScriptSimple.java b/tools/h2/src/test/org/h2/test/db/TestScriptSimple.java deleted file mode 100755 index f0fb133..0000000 --- a/tools/h2/src/test/org/h2/test/db/TestScriptSimple.java +++ /dev/null @@ -1,84 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.test.db; - -import java.io.InputStream; -import java.io.InputStreamReader; -import java.io.LineNumberReader; -import java.sql.Connection; -import java.sql.ResultSet; -import java.sql.SQLException; - -import org.h2.test.TestBase; -import org.h2.util.ScriptReader; - -/** - * This test runs a simple SQL script file and compares the output with the - * expected output. - */ -public class TestScriptSimple extends TestBase { - - private Connection conn; - - /** - * Run just this test. - * - * @param a ignored - */ - public static void main(String... a) throws Exception { - TestBase.createCaller().init().test(); - } - - public void test() throws Exception { - if (config.memory || config.big || config.networked) { - return; - } - deleteDb("scriptSimple"); - reconnect(); - String inFile = "org/h2/test/testSimple.in.txt"; - InputStream is = getClass().getClassLoader().getResourceAsStream(inFile); - LineNumberReader lineReader = new LineNumberReader(new InputStreamReader(is, "Cp1252")); - ScriptReader reader = new ScriptReader(lineReader); - while (true) { - String sql = reader.readStatement(); - if (sql == null) { - break; - } - sql = sql.trim(); - try { - if ("@reconnect".equals(sql.toLowerCase())) { - reconnect(); - } else if (sql.length() == 0) { - // ignore - } else if (sql.toLowerCase().startsWith("select")) { - ResultSet rs = conn.createStatement().executeQuery(sql); - while (rs.next()) { - String expected = reader.readStatement().trim(); - String got = "> " + rs.getString(1); - assertEquals(expected, got); - } - } else { - conn.createStatement().execute(sql); - } - } catch (SQLException e) { - System.out.println(sql); - throw e; - } - } - is.close(); - conn.close(); - deleteDb("scriptSimple"); - } - - private void reconnect() throws SQLException { - if (conn != null) { - conn.close(); - } - conn = getConnection("scriptSimple"); - } - -} diff --git a/tools/h2/src/test/org/h2/test/db/TestSequence.java b/tools/h2/src/test/org/h2/test/db/TestSequence.java deleted file mode 100755 index 2b20141..0000000 --- a/tools/h2/src/test/org/h2/test/db/TestSequence.java +++ /dev/null @@ -1,134 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.test.db; - -import java.sql.Connection; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.sql.Statement; - -import org.h2.test.TestBase; - -/** - * Tests the sequence feature of this database. - */ -public class TestSequence extends TestBase { - - /** - * Run just this test. - * - * @param a ignored - */ - public static void main(String... a) throws Exception { - TestBase.createCaller().init().test(); - } - - public void test() throws SQLException { - testSchemaSearchPath(); - testAlterSequenceColumn(); - testAlterSequence(); - testCache(); - testTwo(); - deleteDb("sequence"); - } - - private void testSchemaSearchPath() throws SQLException { - deleteDb("sequence"); - Connection conn = getConnection("sequence"); - Statement stat = conn.createStatement(); - stat.execute("CREATE SCHEMA TEST"); - stat.execute("CREATE SEQUENCE TEST.TEST_SEQ"); - stat.execute("SET SCHEMA_SEARCH_PATH PUBLIC, TEST"); - stat.execute("CALL TEST_SEQ.NEXTVAL"); - stat.execute("CALL TEST_SEQ.CURRVAL"); - conn.close(); - } - - private void testAlterSequenceColumn() throws SQLException { - deleteDb("sequence"); - Connection conn = getConnection("sequence"); - Statement stat = conn.createStatement(); - stat.execute("CREATE TABLE TEST(ID INT , NAME VARCHAR(255))"); - stat.execute("INSERT INTO TEST VALUES(1, 'Hello')"); - stat.execute("ALTER TABLE TEST ALTER COLUMN ID INT IDENTITY"); - stat.execute("ALTER TABLE test ALTER COLUMN ID RESTART WITH 3"); - stat.execute("INSERT INTO TEST (name) VALUES('Other World')"); - conn.close(); - } - - private void testAlterSequence() throws SQLException { - deleteDb("sequence"); - Connection conn = getConnection("sequence"); - Statement stat = conn.createStatement(); - stat.execute("create sequence test"); - conn.setAutoCommit(false); - stat.execute("alter sequence test restart with 1"); - for (int i = 0; i < 40; i++) { - stat.execute("select nextval('test')"); - } - conn.close(); - } - - private void testCache() throws SQLException { - if (config.memory) { - return; - } - deleteDb("sequence"); - Connection conn = getConnection("sequence"); - Statement stat = conn.createStatement(); - stat.execute("create sequence test_Sequence"); - stat.execute("create sequence test_Sequence3 cache 3"); - conn.close(); - conn = getConnection("sequence"); - stat = conn.createStatement(); - stat.execute("call next value for test_Sequence"); - stat.execute("call next value for test_Sequence3"); - ResultSet rs = stat.executeQuery("select * from information_schema.sequences order by sequence_name"); - rs.next(); - assertEquals("TEST_SEQUENCE", rs.getString("SEQUENCE_NAME")); - assertEquals("32", rs.getString("CACHE")); - rs.next(); - assertEquals("TEST_SEQUENCE3", rs.getString("SEQUENCE_NAME")); - assertEquals("3", rs.getString("CACHE")); - assertFalse(rs.next()); - conn.close(); - } - - private void testTwo() throws SQLException { - deleteDb("sequence"); - Connection conn = getConnection("sequence"); - Statement stat = conn.createStatement(); - stat.execute("create sequence testSequence"); - conn.setAutoCommit(false); - - Connection conn2 = getConnection("sequence"); - Statement stat2 = conn2.createStatement(); - conn2.setAutoCommit(false); - - long last = 0; - for (int i = 0; i < 100; i++) { - long v1 = getNext(stat); - assertTrue(v1 > last); - last = v1; - for (int j = 0; j < 100; j++) { - long v2 = getNext(stat2); - assertTrue(v2 > last); - last = v2; - } - } - - conn2.close(); - conn.close(); - } - - private long getNext(Statement stat) throws SQLException { - ResultSet rs = stat.executeQuery("call next value for testSequence"); - rs.next(); - long value = rs.getLong(1); - return value; - } -} diff --git a/tools/h2/src/test/org/h2/test/db/TestSessionsLocks.java b/tools/h2/src/test/org/h2/test/db/TestSessionsLocks.java deleted file mode 100755 index c5a3a8f..0000000 --- a/tools/h2/src/test/org/h2/test/db/TestSessionsLocks.java +++ /dev/null @@ -1,135 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.test.db; - -import java.sql.Connection; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.sql.Statement; - -import org.h2.test.TestBase; - -/** - * Tests the meta data tables information_schema.locks and sessions. - */ -public class TestSessionsLocks extends TestBase { - - /** - * Run just this test. - * - * @param a ignored - */ - public static void main(String... a) throws Exception { - TestBase.createCaller().init().test(); - } - - public void test() throws Exception { - if (config.mvcc) { - return; - } - testCancelStatement(); - testLocks(); - deleteDb("sessionsLocks"); - } - - private void testLocks() throws SQLException { - deleteDb("sessionsLocks"); - Connection conn = getConnection("sessionsLocks;MULTI_THREADED=1"); - Statement stat = conn.createStatement(); - ResultSet rs; - rs = stat.executeQuery("select * from information_schema.locks order by session_id"); - assertFalse(rs.next()); - Connection conn2 = getConnection("sessionsLocks"); - Statement stat2 = conn2.createStatement(); - stat2.execute("create table test(id int primary key, name varchar)"); - conn2.setAutoCommit(false); - stat2.execute("insert into test values(1, 'Hello')"); - rs = stat.executeQuery("select * from information_schema.locks order by session_id"); - rs.next(); - assertEquals("PUBLIC", rs.getString("TABLE_SCHEMA")); - assertEquals("TEST", rs.getString("TABLE_NAME")); - rs.getString("SESSION_ID"); - if (config.mvcc) { - assertEquals("READ", rs.getString("LOCK_TYPE")); - } else { - assertEquals("WRITE", rs.getString("LOCK_TYPE")); - } - assertFalse(rs.next()); - conn2.commit(); - conn2.setTransactionIsolation(Connection.TRANSACTION_SERIALIZABLE); - stat2.execute("SELECT * FROM TEST"); - rs = stat.executeQuery("select * from information_schema.locks order by session_id"); - if (!config.mvcc) { - rs.next(); - assertEquals("PUBLIC", rs.getString("TABLE_SCHEMA")); - assertEquals("TEST", rs.getString("TABLE_NAME")); - rs.getString("SESSION_ID"); - assertEquals("READ", rs.getString("LOCK_TYPE")); - } - assertFalse(rs.next()); - conn2.commit(); - rs = stat.executeQuery("select * from information_schema.locks order by session_id"); - assertFalse(rs.next()); - conn.close(); - conn2.close(); - } - - private void testCancelStatement() throws Exception { - deleteDb("sessionsLocks"); - Connection conn = getConnection("sessionsLocks;MULTI_THREADED=1"); - Statement stat = conn.createStatement(); - ResultSet rs; - rs = stat.executeQuery("select * from information_schema.sessions order by SESSION_START, ID"); - rs.next(); - int sessionId = rs.getInt("ID"); - rs.getString("USER_NAME"); - rs.getTimestamp("SESSION_START"); - rs.getString("STATEMENT"); - rs.getTimestamp("STATEMENT_START"); - assertFalse(rs.next()); - Connection conn2 = getConnection("sessionsLocks"); - final Statement stat2 = conn2.createStatement(); - rs = stat.executeQuery("select * from information_schema.sessions order by SESSION_START, ID"); - assertTrue(rs.next()); - assertEquals(sessionId, rs.getInt("ID")); - assertTrue(rs.next()); - int otherId = rs.getInt("ID"); - assertTrue(otherId != sessionId); - assertFalse(rs.next()); - stat2.execute("set throttle 1"); - final boolean[] done = { false }; - Runnable runnable = new Runnable() { - public void run() { - try { - stat2.execute("select count(*) from system_range(1, 10000000) t1, system_range(1, 10000000) t2"); - new Error("Unexpected success").printStackTrace(); - } catch (SQLException e) { - done[0] = true; - } - } - }; - new Thread(runnable).start(); - while (true) { - Thread.sleep(100); - rs = stat.executeQuery("CALL CANCEL_SESSION(" + otherId + ")"); - rs.next(); - if (rs.getBoolean(1)) { - for (int i = 0; i < 20; i++) { - Thread.sleep(100); - if (done[0]) { - break; - } - } - assertTrue(done[0]); - break; - } - } - conn2.close(); - conn.close(); - } - -} diff --git a/tools/h2/src/test/org/h2/test/db/TestSpaceReuse.java b/tools/h2/src/test/org/h2/test/db/TestSpaceReuse.java deleted file mode 100755 index 0d00143..0000000 --- a/tools/h2/src/test/org/h2/test/db/TestSpaceReuse.java +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.test.db; - -import java.io.File; -import java.sql.Connection; -import java.sql.SQLException; -import java.sql.Statement; - -import org.h2.test.TestBase; - -/** - * Tests if disk space is reused after deleting many rows. - */ -public class TestSpaceReuse extends TestBase { - - /** - * Run just this test. - * - * @param a ignored - */ - public static void main(String... a) throws Exception { - TestBase.createCaller().init().test(); - } - - public void test() throws SQLException { - if (config.memory) { - return; - } - deleteDb("spaceReuse"); - long first = 0, now = 0; - for (int i = 0; i < 10; i++) { - Connection conn = getConnection("spaceReuse"); - Statement stat = conn.createStatement(); - stat.execute("create table if not exists t(i int)"); - stat.execute("insert into t select x from system_range(1, 500)"); - conn.close(); - conn = getConnection("spaceReuse"); - conn.createStatement().execute("delete from t"); - conn.close(); - now = new File(getBaseDir() + "/spaceReuse.data.db").length(); - if (first == 0) { - first = now; - } - } - if (now > first) { - fail("first: " + first + " now: " + now); - } - deleteDb("spaceReuse"); - } - -} diff --git a/tools/h2/src/test/org/h2/test/db/TestSpeed.java b/tools/h2/src/test/org/h2/test/db/TestSpeed.java deleted file mode 100755 index 894ea53..0000000 --- a/tools/h2/src/test/org/h2/test/db/TestSpeed.java +++ /dev/null @@ -1,397 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.test.db; - -import java.sql.Connection; -import java.sql.PreparedStatement; -import java.sql.SQLException; -import java.sql.Statement; - -import org.h2.test.TestBase; - -/** - * Various small performance tests. - */ -public class TestSpeed extends TestBase { - - /** - * Run just this test. - * - * @param a ignored - */ - public static void main(String... a) throws Exception { - TestBase.createCaller().init().test(); - } - - public void test() throws SQLException { - - deleteDb("speed"); - Connection conn; - - conn = getConnection("speed"); - - // conn = - // getConnection("speed;ASSERT=0;MAX_MEMORY_ROWS=1000000;MAX_LOG_SIZE=1000"); - - // Class.forName("org.hsqldb.jdbcDriver"); - // conn = DriverManager.getConnection("jdbc:hsqldb:speed"); - - Statement stat = conn.createStatement(); - stat.execute("DROP TABLE IF EXISTS TEST"); - stat.execute("CREATE TABLE TEST(ID INT PRIMARY KEY, NAME VARCHAR(255))"); - int len = getSize(1, 10000); - for (int i = 0; i < len; i++) { - stat.execute("SELECT ID, NAME FROM TEST ORDER BY ID"); - } - - // drop table if exists test; - // CREATE TABLE TEST(ID INT PRIMARY KEY, NAME VARCHAR(255)); - // @LOOP 100000 INSERT INTO TEST VALUES(?, 'Hello'); - // @LOOP 100000 SELECT * FROM TEST WHERE ID = ?; - - // stat.execute("CREATE TABLE TEST(ID INT PRIMARY KEY, NAME - // VARCHAR(255))"); - // for(int i=0; i<1000; i++) { - // stat.execute("INSERT INTO TEST VALUES("+i+", 'Hello')"); - // } - // stat.execute("CREATE TABLE TEST_A(ID INT PRIMARY KEY, NAME - // VARCHAR(255))"); - // stat.execute("INSERT INTO TEST_A VALUES(0, 'Hello')"); - long time = System.currentTimeMillis(); - // for(int i=1; i<8000; i*=2) { - // stat.execute("INSERT INTO TEST_A SELECT ID+"+i+", NAME FROM TEST_A"); - // - // // stat.execute("INSERT INTO TEST_A VALUES("+i+", 'Hello')"); - // } - // for(int i=0; i<4; i++) { - // ResultSet rs = stat.executeQuery("SELECT * FROM TEST_A"); - // while(rs.next()) { - // rs.getInt(1); - // rs.getString(2); - // } - // } - // System.out.println(System.currentTimeMillis()-time); - - // - // stat.execute("CREATE TABLE TEST_B(ID INT PRIMARY KEY, NAME - // VARCHAR(255))"); - // for(int i=0; i<80000; i++) { - // stat.execute("INSERT INTO TEST_B VALUES("+i+", 'Hello')"); - // } - - // conn.close(); - // System.exit(0); - // int testParser; - // java -Xrunhprof:cpu=samples,depth=8 -cp . org.h2.test.TestAll - // - // stat.execute("CREATE TABLE TEST(ID INT)"); - // stat.execute("INSERT INTO TEST VALUES(1)"); - // ResultSet rs = stat.executeQuery("SELECT ID OTHER_ID FROM TEST"); - // rs.next(); - // rs.getString("ID"); - // stat.execute("DROP TABLE TEST"); - - // long time = System.currentTimeMillis(); - - stat.execute("DROP TABLE IF EXISTS TEST"); - stat.execute("CREATE CACHED TABLE TEST(ID INT PRIMARY KEY, NAME VARCHAR(255))"); - PreparedStatement prep = conn.prepareStatement("INSERT INTO TEST VALUES(?, ?)"); - - int max = getSize(1, 10000); - for (int i = 0; i < max; i++) { - prep.setInt(1, i); - prep.setString(2, - "abchelloasdfaldsjflajdflajdslfoajlskdfkjasdfadsfasdfadsfadfsalksdjflasjflajsdlkfjaksdjflkskd" + i); - prep.execute(); - } - - // System.exit(0); - // System.out.println("END "+Value.cacheHit+" "+Value.cacheMiss); - - time = System.currentTimeMillis() - time; - trace(time + " insert"); - - // if(true) return; - - // if(config.log) { - // System.gc(); - // System.gc(); - // log("mem="+(Runtime.getRuntime().totalMemory() - - // Runtime.getRuntime().freeMemory())/1024); - // } - - // conn.close(); - - time = System.currentTimeMillis(); - - prep = conn.prepareStatement("UPDATE TEST SET NAME='Another data row which is long' WHERE ID=?"); - for (int i = 0; i < max; i++) { - prep.setInt(1, i); - prep.execute(); - - // System.out.println("updated "+i); - // stat.execute("UPDATE TEST SET NAME='Another data row which is - // long' WHERE ID="+i); - // ResultSet rs = stat.executeQuery("SELECT * FROM TEST WHERE - // ID="+i); - // if(!rs.next()) { - // throw new AssertionError("hey! i="+i); - // } - // if(rs.next()) { - // throw new AssertionError("hey! i="+i); - // } - } - // for(int i=0; i - // T2.ID"); - - // PreparedStatement prep; - // - // prep = conn - // .prepareStatement("INSERT INTO Test - // VALUES(?,'Julia','Peterson-Clancy',?)"); - - // query(stat, "SELECT * FROM TEST WHERE NAME LIKE 'Ju%'"); - - // long time = System.currentTimeMillis(); - // - // for (int i = 0; i < len; i++) { - // prep.setInt(1, i); - // prep.setInt(2, i); - // prep.execute(); - // query(stat, "SELECT * FROM TEST"); - // if(i % 2 == 0) { - // stat.executeUpdate("INSERT INTO Test - // VALUES("+i+",'Julia','Peterson-Clancy',"+i+")"); - // } else { - // stat.executeUpdate("INSERT INTO TEST - // VALUES("+i+",'Julia','Peterson-Clancy',"+i+")"); - // } - // } - - // query(stat, "SELECT ABS(-1) FROM TEST"); - - // conn.close(); - // if(true) return; - - // stat.executeUpdate("UPDATE Test SET Name='Hans' WHERE Id=1"); - // query(stat, "SELECT * FROM Test WHERE Id=1"); - // stat.executeUpdate("DELETE FROM Test WHERE Id=1"); - - // query(stat, "SELECT * FROM TEST"); - - // conn.close(); - // - // if(true) { - // return; - // } - - // query(stat, "SELECT * FROM TEST WHERE ID = 182"); - /* - * for(int i=0; i DATE '2004-12-19'"); - */ - /* - * stat.executeUpdate("CREATE TABLE TEST(ID INT PRIMARY KEY, VALUE - * BINARY(10))"); stat.executeUpdate("INSERT INTO TEST VALUES(1, X'0011')"); - * stat.executeUpdate("INSERT INTO TEST VALUES(2, X'01FFAA')"); query(stat, - * "SELECT * FROM TEST WHERE VALUE > X'0011'"); - */ - /* - * stat.executeUpdate("CREATE TABLE TEST(ID INT PRIMARY KEY, NAME - * VARCHAR(255))"); stat.executeUpdate("INSERT INTO TEST VALUES(1, - * 'Hallo')"); stat.executeUpdate("INSERT INTO TEST VALUES(2, 'World')"); - */ - /* - * stat.executeUpdate("CREATE UNIQUE INDEX TEST_NAME ON TEST(NAME)"); - * stat.executeUpdate("DROP INDEX TEST_NAME"); stat.executeUpdate("INSERT - * INTO TEST VALUES(2, 'Hallo')"); stat.executeUpdate("DELETE FROM TEST"); - * for(int i=0; i <100; i++) { stat.executeUpdate("INSERT INTO TEST - * VALUES("+i+", 'Test"+i+"')"); } - */ - /* - * query(stat, "SELECT T1.ID, T1.NAME FROM TEST T1"); query(stat, "SELECT - * T1.ID, T1.NAME, T2.ID, T2.NAME FROM TEST T1, TEST T2"); query(stat, - * "SELECT T1.ID, T1.NAME, T2.ID, T2.NAME FROM TEST T1, TEST T2 WHERE T1.ID = - * T2.ID"); - */ - /* - * query(stat, "SELECT * FROM TEST WHERE ID = 1"); - * stat.executeUpdate("DELETE FROM TEST WHERE ID = 2"); query(stat, "SELECT * - * FROM TEST WHERE ID < 10"); query(stat, "SELECT * FROM TEST WHERE ID = - * 2"); stat.executeUpdate("UPDATE TEST SET NAME = 'World' WHERE ID = 5"); - * query(stat, "SELECT * FROM TEST WHERE ID = 5"); query(stat, "SELECT * - * FROM TEST WHERE ID < 10"); - */ - // } - // private static void query(Statement stat, String sql) throws SQLException - // { - // System.out.println("--------- " + sql); - // ResultSet rs = stat.executeQuery(sql); - // ResultSetMetaData meta = rs.getMetaData(); - // while (rs.next()) { - // for (int i = 0; i < meta.getColumnCount(); i++) { - // System.out.print("[" + meta.getColumnLabel(i + 1) + "]=" - // + rs.getString(i + 1) + " "); - // } - // System.out.println(); - // } - // } -} diff --git a/tools/h2/src/test/org/h2/test/db/TestTableEngines.java b/tools/h2/src/test/org/h2/test/db/TestTableEngines.java deleted file mode 100755 index 8621b60..0000000 --- a/tools/h2/src/test/org/h2/test/db/TestTableEngines.java +++ /dev/null @@ -1,309 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.test.db; - -import java.sql.Connection; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.sql.Statement; -import java.util.ArrayList; -import org.h2.api.TableEngine; -import org.h2.command.ddl.CreateTableData; -import org.h2.engine.Session; -import org.h2.index.BaseIndex; -import org.h2.index.Cursor; -import org.h2.index.SingleRowCursor; -import org.h2.index.Index; -import org.h2.index.IndexType; -import org.h2.result.Row; -import org.h2.result.SearchRow; -import org.h2.table.IndexColumn; -import org.h2.table.TableBase; -import org.h2.table.Table; -import org.h2.test.TestBase; - -/** - * The class for external table engines mechanism testing. - * - * @author Sergi Vladykin - */ -public class TestTableEngines extends TestBase { - - /** - * Run just this test. - * - * @param a ignored - */ - public static void main(String[] a) throws Exception { - TestBase.createCaller().init().test(); - } - - public void test() throws Exception { - if (config.mvcc) { - return; - } - deleteDb("tableEngine"); - - Connection conn = getConnection("tableEngine"); - Statement stat = conn.createStatement(); - stat.execute("CREATE TABLE t1(id int, name varchar) ENGINE \"" + OneRowTableEngine.class.getName() + "\""); - - testStatements(stat); - - stat.close(); - conn.close(); - - if (!config.memory) { - conn = getConnection("tableEngine"); - stat = conn.createStatement(); - - ResultSet rs = stat.executeQuery("SELECT name FROM t1"); - assertFalse(rs.next()); - rs.close(); - - testStatements(stat); - - stat.close(); - conn.close(); - } - - deleteDb("tableEngine"); - - } - - private void testStatements(Statement stat) throws SQLException { - assertEquals(stat.executeUpdate("INSERT INTO t1 VALUES(2, 'abc')"), 1); - assertEquals(stat.executeUpdate("UPDATE t1 SET name = 'abcdef' WHERE id=2"), 1); - assertEquals(stat.executeUpdate("INSERT INTO t1 VALUES(3, 'abcdefghi')"), 1); - - assertEquals(stat.executeUpdate("DELETE FROM t1 WHERE id=2"), 0); - assertEquals(stat.executeUpdate("DELETE FROM t1 WHERE id=3"), 1); - - ResultSet rs = stat.executeQuery("SELECT name FROM t1"); - assertFalse(rs.next()); - rs.close(); - - assertEquals(stat.executeUpdate("INSERT INTO t1 VALUES(2, 'abc')"), 1); - assertEquals(stat.executeUpdate("UPDATE t1 SET name = 'abcdef' WHERE id=2"), 1); - assertEquals(stat.executeUpdate("INSERT INTO t1 VALUES(3, 'abcdefghi')"), 1); - - rs = stat.executeQuery("SELECT name FROM t1"); - assertTrue(rs.next()); - assertEquals(rs.getString(1), "abcdefghi"); - assertFalse(rs.next()); - rs.close(); - - } - - /** - * A test table factory. - */ - public static class OneRowTableEngine implements TableEngine { - - /** - * A table implementation with one row. - */ - private static class OneRowTable extends TableBase { - - /** - * A scan index for one row. - */ - private class Scan extends BaseIndex { - - Scan(Table table) { - initBaseIndex(table, table.getId(), table.getName() + "_SCAN", - IndexColumn.wrap(table.getColumns()), IndexType.createScan(false)); - } - - public long getRowCountApproximation() { - return table.getRowCountApproximation(); - } - - public long getRowCount(Session session) { - return table.getRowCount(session); - } - - @Override - public void checkRename() { - // do nothing - } - - @Override - public void truncate(Session session) { - // do nothing - } - - @Override - public void remove(Session session) { - // do nothing - } - - @Override - public void remove(Session session, Row r) { - // do nothing - } - - @Override - public boolean needRebuild() { - return false; - } - - @Override - public double getCost(Session session, int[] masks) { - return 0; - } - - @Override - public Cursor findFirstOrLast(Session session, boolean first) { - return new SingleRowCursor(row); - } - - @Override - public Cursor find(Session session, SearchRow first, SearchRow last) { - return new SingleRowCursor(row); - } - - @Override - public void close(Session session) { - // do nothing - } - - @Override - public boolean canGetFirstOrLast() { - return true; - } - - @Override - public void add(Session session, Row r) { - // do nothing - } - } - - volatile Row row; - - private final Index scanIndex; - - OneRowTable(CreateTableData data) { - super(data); - scanIndex = new Scan(this); - } - - @Override - public Index addIndex(Session session, String indexName, int indexId, IndexColumn[] cols, - IndexType indexType, boolean create, String indexComment) { - return null; - } - - @Override - public void addRow(Session session, Row r) { - this.row = r; - } - - @Override - public boolean canDrop() { - return true; - } - - @Override - public boolean canGetRowCount() { - return true; - } - - @Override - public void checkSupportAlter() { - // do nothing - } - - @Override - public void close(Session session) { - // do nothing - } - - @Override - public ArrayList getIndexes() { - return null; - } - - @Override - public long getMaxDataModificationId() { - return 0; - } - - @Override - public long getRowCount(Session session) { - return getRowCountApproximation(); - } - - @Override - public long getRowCountApproximation() { - return row == null ? 0 : 1; - } - - @Override - public Index getScanIndex(Session session) { - return scanIndex; - } - - @Override - public String getTableType() { - return EXTERNAL_TABLE_ENGINE; - } - - @Override - public Index getUniqueIndex() { - return null; - } - - @Override - public boolean isDeterministic() { - return false; - } - - @Override - public boolean isLockedExclusively() { - return false; - } - - @Override - public void lock(Session session, boolean exclusive, boolean force) { - // do nothing - } - - @Override - public void removeRow(Session session, Row r) { - this.row = null; - } - - @Override - public void truncate(Session session) { - row = null; - } - - @Override - public void unlock(Session s) { - // do nothing - } - - @Override - public void checkRename() { - // do nothing - } - - } - - /** - * Create a new OneRowTable. - * - * @param data the meta data of the table to create - * @return the new table - */ - public OneRowTable createTable(CreateTableData data) { - return new OneRowTable(data); - } - } - -} diff --git a/tools/h2/src/test/org/h2/test/db/TestTempTables.java b/tools/h2/src/test/org/h2/test/db/TestTempTables.java deleted file mode 100755 index 7ac2655..0000000 --- a/tools/h2/src/test/org/h2/test/db/TestTempTables.java +++ /dev/null @@ -1,155 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.test.db; - -import java.sql.Connection; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.sql.Statement; -import org.h2.engine.Constants; -import org.h2.test.TestBase; -import org.h2.util.IOUtils; - -/** - * Temporary table tests. - */ -public class TestTempTables extends TestBase { - - /** - * Run just this test. - * - * @param a ignored - */ - public static void main(String... a) throws Exception { - TestBase.createCaller().init().test(); - } - - public void test() throws SQLException { - deleteDb("tempTables"); - testDeleteGlobalTempTableWhenClosing(); - Connection c1 = getConnection("tempTables"); - testAlter(c1); - Connection c2 = getConnection("tempTables"); - testConstraints(c1, c2); - testTables(c1, c2); - testIndexes(c1, c2); - c1.close(); - c2.close(); - deleteDb("tempTables"); - } - - private void testDeleteGlobalTempTableWhenClosing() throws SQLException { - if (config.memory) { - return; - } - deleteDb("tempTables"); - Connection conn = getConnection("tempTables"); - Statement stat = conn.createStatement(); - stat.execute("create global temporary table test(id int, data varchar)"); - stat.execute("insert into test select x, space(1000) from system_range(1, 1000)"); - stat.execute("shutdown compact"); - try { - conn.close(); - } catch (SQLException e) { - // expected - } - String dbName = getBaseDir() + "/tempTables" + Constants.SUFFIX_PAGE_FILE; - long before = IOUtils.length(dbName); - assertTrue(before > 0); - conn = getConnection("tempTables"); - conn.close(); - long after = IOUtils.length(dbName); - assertEquals(after, before); - } - - private void testAlter(Connection conn) throws SQLException { - Statement stat; - stat = conn.createStatement(); - stat.execute("create temporary table test(id varchar)"); - stat.execute("create index idx1 on test(id)"); - stat.execute("drop index idx1"); - stat.execute("create index idx1 on test(id)"); - stat.execute("insert into test select x from system_range(1, 10)"); - try { - stat.execute("alter table test add column x int"); - fail(); - } catch (SQLException e) { - assertKnownException(e); - } - stat.execute("drop table test"); - } - - private void testConstraints(Connection conn1, Connection conn2) throws SQLException { - Statement s1 = conn1.createStatement(), s2 = conn2.createStatement(); - s1.execute("create local temporary table test(id int unique)"); - s2.execute("create local temporary table test(id int unique)"); - s1.execute("alter table test add constraint a unique(id)"); - s2.execute("alter table test add constraint a unique(id)"); - s1.execute("drop table test"); - s2.execute("drop table test"); - } - - private void testIndexes(Connection conn1, Connection conn2) throws SQLException { - conn1.createStatement().executeUpdate("create local temporary table test(id int)"); - conn1.createStatement().executeUpdate("create index idx_id on test(id)"); - conn2.createStatement().executeUpdate("create local temporary table test(id int)"); - conn2.createStatement().executeUpdate("create index idx_id on test(id)"); - conn2.createStatement().executeUpdate("drop index idx_id"); - conn2.createStatement().executeUpdate("drop table test"); - conn2.createStatement().executeUpdate("create table test(id int)"); - conn2.createStatement().executeUpdate("create index idx_id on test(id)"); - conn1.createStatement().executeUpdate("drop table test"); - conn1.createStatement().executeUpdate("drop table test"); - } - - private void testTables(Connection c1, Connection c2) throws SQLException { - Statement s1 = c1.createStatement(); - Statement s2 = c2.createStatement(); - s1.execute("CREATE LOCAL TEMPORARY TABLE LT(A INT)"); - s1.execute("CREATE GLOBAL TEMPORARY TABLE GT1(ID INT)"); - s2.execute("CREATE GLOBAL TEMPORARY TABLE GT2(ID INT)"); - s2.execute("CREATE LOCAL TEMPORARY TABLE LT(B INT)"); - s2.execute("SELECT B FROM LT"); - s1.execute("SELECT A FROM LT"); - s1.execute("SELECT * FROM GT1"); - s2.execute("SELECT * FROM GT1"); - s1.execute("SELECT * FROM GT2"); - s2.execute("SELECT * FROM GT2"); - s2.execute("DROP TABLE GT1"); - s2.execute("DROP TABLE GT2"); - s2.execute("DROP TABLE LT"); - s1.execute("DROP TABLE LT"); - - // temp tables: 'on commit' syntax is currently not documented, because - // not tested well - // and hopefully nobody is using it, as it looks like functional sugar - // (this features are here for compatibility only) - ResultSet rs; - c1.setAutoCommit(false); - s1.execute("create local temporary table test_temp(id int) on commit delete rows"); - s1.execute("insert into test_temp values(1)"); - rs = s1.executeQuery("select * from test_temp"); - assertResultRowCount(1, rs); - c1.commit(); - rs = s1.executeQuery("select * from test_temp"); - assertResultRowCount(0, rs); - s1.execute("drop table test_temp"); - - s1.execute("create local temporary table test_temp(id int) on commit drop"); - s1.execute("insert into test_temp values(1)"); - rs = s1.executeQuery("select * from test_temp"); - assertResultRowCount(1, rs); - c1.commit(); - try { - s1.executeQuery("select * from test_temp"); - fail("test_temp should have been dropped automatically"); - } catch (SQLException e) { - assertKnownException(e); - } - } - -} diff --git a/tools/h2/src/test/org/h2/test/db/TestTransaction.java b/tools/h2/src/test/org/h2/test/db/TestTransaction.java deleted file mode 100755 index 42bf6fe..0000000 --- a/tools/h2/src/test/org/h2/test/db/TestTransaction.java +++ /dev/null @@ -1,385 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.test.db; - -import java.sql.Connection; -import java.sql.DatabaseMetaData; -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.sql.Savepoint; -import java.sql.Statement; -import java.util.ArrayList; -import java.util.Random; -import org.h2.test.TestBase; -import org.h2.util.New; - -/** - * Transactional tests, including transaction isolation tests, and tests related - * to savepoints. - */ -public class TestTransaction extends TestBase { - - /** - * Run just this test. - * - * @param a ignored - */ - public static void main(String... a) throws Exception { - TestBase.createCaller().init().test(); - } - - public void test() throws SQLException { - testRollback(); - testRollback2(); - testForUpdate(); - testSetTransaction(); - testReferential(); - testSavepoint(); - testIsolation(); - deleteDb("transaction"); - } - - private void testForUpdate() throws SQLException { - deleteDb("transaction"); - Connection conn = getConnection("transaction"); - conn.setAutoCommit(false); - Statement stat = conn.createStatement(); - stat.execute("create table test(id int primary key) as select 1"); - conn.commit(); - PreparedStatement prep = conn.prepareStatement("select * from test for update"); - prep.execute(); - // releases the lock - conn.commit(); - prep.execute(); - Connection conn2 = getConnection("transaction"); - conn2.setAutoCommit(false); - try { - conn2.createStatement().execute("select * from test"); - fail(); - } catch (SQLException e) { - assertKnownException(e); - } - conn2.close(); - conn.close(); - } - - private void testRollback() throws SQLException { - deleteDb("transaction"); - Connection conn = getConnection("transaction"); - Statement stat = conn.createStatement(); - stat.execute("create table test(id int)"); - stat.execute("create index idx_id on test(id)"); - stat.execute("insert into test values(1), (1), (1)"); - if (!config.memory) { - conn.close(); - conn = getConnection("transaction"); - stat = conn.createStatement(); - } - conn.setAutoCommit(false); - stat.execute("delete from test"); - conn.rollback(); - ResultSet rs; - rs = stat.executeQuery("select * from test"); - assertResultRowCount(3, rs); - rs = stat.executeQuery("select * from test where id = 1"); - assertResultRowCount(3, rs); - conn.close(); - - conn = getConnection("transaction"); - stat = conn.createStatement(); - stat.execute("create table master(id int) as select 1"); - stat.execute("create table child1(id int references master(id) on delete cascade)"); - stat.execute("insert into child1 values(1), (1), (1)"); - stat.execute("create table child2(id int references master(id)) as select 1"); - if (!config.memory) { - conn.close(); - conn = getConnection("transaction"); - stat = conn.createStatement(); - } - stat = conn.createStatement(); - try { - stat.execute("delete from master"); - fail(); - } catch (SQLException ex) { - // ok - conn.rollback(); - } - rs = stat.executeQuery("select * from master where id=1"); - assertResultRowCount(1, rs); - rs = stat.executeQuery("select * from child1"); - assertResultRowCount(3, rs); - rs = stat.executeQuery("select * from child1 where id=1"); - assertResultRowCount(3, rs); - conn.close(); - } - - private void testRollback2() throws SQLException { - deleteDb("transaction"); - Connection conn = getConnection("transaction"); - Statement stat = conn.createStatement(); - stat.execute("create table test(id int)"); - stat.execute("create index idx_id on test(id)"); - stat.execute("insert into test values(1), (1)"); - if (!config.memory) { - conn.close(); - conn = getConnection("transaction"); - stat = conn.createStatement(); - } - conn.setAutoCommit(false); - stat.execute("delete from test"); - conn.rollback(); - ResultSet rs; - rs = stat.executeQuery("select * from test where id = 1"); - assertResultRowCount(2, rs); - conn.close(); - - conn = getConnection("transaction"); - stat = conn.createStatement(); - stat.execute("create table master(id int) as select 1"); - stat.execute("create table child1(id int references master(id) on delete cascade)"); - stat.execute("insert into child1 values(1), (1)"); - stat.execute("create table child2(id int references master(id)) as select 1"); - if (!config.memory) { - conn.close(); - conn = getConnection("transaction"); - stat = conn.createStatement(); - } - stat = conn.createStatement(); - try { - stat.execute("delete from master"); - fail(); - } catch (SQLException ex) { - // ok - } - rs = stat.executeQuery("select * from master where id=1"); - assertResultRowCount(1, rs); - rs = stat.executeQuery("select * from child1 where id=1"); - assertResultRowCount(2, rs); - conn.close(); - } - - private void testSetTransaction() throws SQLException { - deleteDb("transaction"); - Connection conn = getConnection("transaction"); - conn.setAutoCommit(false); - Statement stat = conn.createStatement(); - stat.execute("create table test(id int)"); - stat.execute("insert into test values(1)"); - stat.execute("set @x = 1"); - conn.commit(); - assertSingleValue(stat, "select id from test", 1); - assertSingleValue(stat, "call @x", 1); - - stat.execute("update test set id=2"); - stat.execute("set @x = 2"); - conn.rollback(); - assertSingleValue(stat, "select id from test", 1); - assertSingleValue(stat, "call @x", 2); - - conn.close(); - } - - private void testReferential() throws SQLException { - deleteDb("transaction"); - Connection c1 = getConnection("transaction"); - c1.setAutoCommit(false); - Statement s1 = c1.createStatement(); - s1.execute("drop table if exists a"); - s1.execute("drop table if exists b"); - s1.execute("create table a (id integer identity not null, code varchar(10) not null, primary key(id))"); - s1.execute("create table b (name varchar(100) not null, a integer, primary key(name), foreign key(a) references a(id))"); - Connection c2 = getConnection("transaction"); - c2.setAutoCommit(false); - s1.executeUpdate("insert into A(code) values('one')"); - Statement s2 = c2.createStatement(); - try { - s2.executeUpdate("insert into B values('two', 1)"); - fail(); - } catch (SQLException e) { - assertKnownException(e); - } - c2.commit(); - c1.rollback(); - c1.close(); - c2.close(); - } - - private void testSavepoint() throws SQLException { - deleteDb("transaction"); - Connection conn = getConnection("transaction"); - Statement stat = conn.createStatement(); - stat.execute("CREATE TABLE TEST0(ID IDENTITY, NAME VARCHAR)"); - stat.execute("CREATE TABLE TEST1(NAME VARCHAR, ID IDENTITY, X TIMESTAMP DEFAULT CURRENT_TIMESTAMP)"); - conn.setAutoCommit(false); - int[] count = new int[2]; - int[] countCommitted = new int[2]; - int[] countSave = new int[2]; - int len = getSize(2000, 10000); - Random random = new Random(10); - Savepoint sp = null; - for (int i = 0; i < len; i++) { - int tableId = random.nextInt(2); - String table = "TEST" + tableId; - int op = random.nextInt(6); - switch (op) { - case 0: - stat.execute("INSERT INTO " + table + "(NAME) VALUES('op" + i + "')"); - count[tableId]++; - break; - case 1: - if (count[tableId] > 0) { - stat.execute("DELETE FROM " + table + " WHERE ID=SELECT MIN(ID) FROM " + table); - count[tableId]--; - } - break; - case 2: - sp = conn.setSavepoint(); - countSave[0] = count[0]; - countSave[1] = count[1]; - break; - case 3: - if (sp != null) { - conn.rollback(sp); - count[0] = countSave[0]; - count[1] = countSave[1]; - } - break; - case 4: - conn.commit(); - sp = null; - countCommitted[0] = count[0]; - countCommitted[1] = count[1]; - break; - case 5: - conn.rollback(); - sp = null; - count[0] = countCommitted[0]; - count[1] = countCommitted[1]; - break; - default: - } - checkTableCount(stat, "TEST0", count[0]); - checkTableCount(stat, "TEST1", count[1]); - } - conn.close(); - } - - private void checkTableCount(Statement stat, String tableName, int count) throws SQLException { - ResultSet rs; - rs = stat.executeQuery("SELECT COUNT(*) FROM " + tableName); - rs.next(); - assertEquals(count, rs.getInt(1)); - } - - private void testIsolation() throws SQLException { - Connection conn = getConnection("transaction"); - trace("default TransactionIsolation=" + conn.getTransactionIsolation()); - conn.setTransactionIsolation(Connection.TRANSACTION_READ_COMMITTED); - assertTrue(conn.getTransactionIsolation() == Connection.TRANSACTION_READ_COMMITTED); - conn.setTransactionIsolation(Connection.TRANSACTION_SERIALIZABLE); - assertTrue(conn.getTransactionIsolation() == Connection.TRANSACTION_SERIALIZABLE); - Statement stat = conn.createStatement(); - assertTrue(conn.getAutoCommit()); - conn.setAutoCommit(false); - assertFalse(conn.getAutoCommit()); - conn.setAutoCommit(true); - assertTrue(conn.getAutoCommit()); - test(stat, "CREATE TABLE TEST(ID INT PRIMARY KEY)"); - conn.commit(); - test(stat, "INSERT INTO TEST VALUES(0)"); - conn.rollback(); - testValue(stat, "SELECT COUNT(*) FROM TEST", "1"); - conn.setAutoCommit(false); - test(stat, "DELETE FROM TEST"); - // testValue("SELECT COUNT(*) FROM TEST", "0"); - conn.rollback(); - testValue(stat, "SELECT COUNT(*) FROM TEST", "1"); - conn.commit(); - conn.setAutoCommit(true); - testNestedResultSets(conn); - conn.setAutoCommit(false); - testNestedResultSets(conn); - conn.close(); - } - - private void testNestedResultSets(Connection conn) throws SQLException { - Statement stat = conn.createStatement(); - test(stat, "CREATE TABLE NEST1(ID INT PRIMARY KEY,VALUE VARCHAR(255))"); - test(stat, "CREATE TABLE NEST2(ID INT PRIMARY KEY,VALUE VARCHAR(255))"); - DatabaseMetaData meta = conn.getMetaData(); - ArrayList result = New.arrayList(); - ResultSet rs1, rs2; - rs1 = meta.getTables(null, null, "NEST%", null); - while (rs1.next()) { - String table = rs1.getString("TABLE_NAME"); - rs2 = meta.getColumns(null, null, table, null); - while (rs2.next()) { - String column = rs2.getString("COLUMN_NAME"); - trace("Table: " + table + " Column: " + column); - result.add(table + "." + column); - } - } - if (result.size() != 4) { - fail("Wrong result, should be NEST1.ID, NEST1.NAME, NEST2.ID, NEST2.NAME but is " + result); - } - result = New.arrayList(); - test(stat, "INSERT INTO NEST1 VALUES(1,'A')"); - test(stat, "INSERT INTO NEST1 VALUES(2,'B')"); - test(stat, "INSERT INTO NEST2 VALUES(1,'1')"); - test(stat, "INSERT INTO NEST2 VALUES(2,'2')"); - Statement s1 = conn.createStatement(); - Statement s2 = conn.createStatement(); - rs1 = s1.executeQuery("SELECT * FROM NEST1 ORDER BY ID"); - while (rs1.next()) { - rs2 = s2.executeQuery("SELECT * FROM NEST2 ORDER BY ID"); - while (rs2.next()) { - String v1 = rs1.getString("VALUE"); - String v2 = rs2.getString("VALUE"); - result.add(v1 + "/" + v2); - } - } - if (result.size() != 4) { - fail("Wrong result, should be A/1, A/2, B/1, B/2 but is " + result); - } - result = New.arrayList(); - rs1 = s1.executeQuery("SELECT * FROM NEST1 ORDER BY ID"); - rs2 = s1.executeQuery("SELECT * FROM NEST2 ORDER BY ID"); - try { - rs1.next(); - fail("next worked on a closed result set"); - } catch (SQLException e) { - assertKnownException(e); - } - // this is already closed, so but closing again should no do any harm - rs1.close(); - while (rs2.next()) { - String v1 = rs2.getString("VALUE"); - result.add(v1); - } - if (result.size() != 2) { - fail("Wrong result, should be A, B but is " + result); - } - test(stat, "DROP TABLE NEST1"); - test(stat, "DROP TABLE NEST2"); - } - - private void testValue(Statement stat, String sql, String data) throws SQLException { - ResultSet rs = stat.executeQuery(sql); - rs.next(); - String s = rs.getString(1); - if (s == null ? (data != null) : (!s.equals(data))) { - fail("s= " + s + " should be: " + data); - } - } - - private void test(Statement stat, String sql) throws SQLException { - trace(sql); - stat.execute(sql); - } - -} diff --git a/tools/h2/src/test/org/h2/test/db/TestTriggersConstraints.java b/tools/h2/src/test/org/h2/test/db/TestTriggersConstraints.java deleted file mode 100755 index 4058339..0000000 --- a/tools/h2/src/test/org/h2/test/db/TestTriggersConstraints.java +++ /dev/null @@ -1,408 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.test.db; - -import java.sql.Connection; -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.sql.Statement; -import java.util.Arrays; -import java.util.HashSet; - -import org.h2.api.Trigger; -import org.h2.test.TestBase; -import org.h2.tools.TriggerAdapter; - -/** - * Tests for trigger and constraints. - */ -public class TestTriggersConstraints extends TestBase implements Trigger { - - private static boolean mustNotCallTrigger; - private String triggerName; - - /** - * Run just this test. - * - * @param a ignored - */ - public static void main(String... a) throws Exception { - TestBase.createCaller().init().test(); - } - - public void test() throws SQLException { - deleteDb("trigger"); - testTriggerAdapter(); - testViewTrigger(); - testTriggerBeforeSelect(); - testTriggerAlterTable(); - testTriggers(); - testConstraints(); - deleteDb("trigger"); - } - - private void testTriggerAdapter() throws SQLException { - Connection conn; - Statement stat; - conn = getConnection("trigger"); - stat = conn.createStatement(); - stat.execute("drop table if exists test"); - stat.execute("create table test(id int)"); - stat.execute("create table message(name varchar)"); - stat.execute("create trigger test_insert after insert, update, delete on test " + - "for each row call \"" + TestTriggerAdapter.class.getName() + "\""); - stat.execute("insert into test values(1)"); - stat.execute("update test set id = 2"); - stat.execute("delete from test"); - ResultSet rs; - rs = stat.executeQuery("select * from message"); - assertTrue(rs.next()); - assertEquals("+1;", rs.getString(1)); - assertTrue(rs.next()); - assertEquals("-1;+2;", rs.getString(1)); - assertTrue(rs.next()); - assertEquals("-2;", rs.getString(1)); - assertFalse(rs.next()); - stat.execute("drop table test, message"); - conn.close(); - } - - private void testViewTrigger() throws SQLException { - Connection conn; - Statement stat; - conn = getConnection("trigger"); - stat = conn.createStatement(); - stat.execute("drop table if exists test"); - stat.execute("create table test(id int)"); - stat.execute("create view test_view as select * from test"); - stat.execute("create trigger test_view_insert instead of insert on test_view for each row call \"" + TestView.class.getName() + "\""); - if (!config.memory) { - conn.close(); - conn = getConnection("trigger"); - stat = conn.createStatement(); - } - stat.execute("insert into test_view values(1)"); - ResultSet rs; - rs = stat.executeQuery("select * from test"); - assertTrue(rs.next()); - assertFalse(rs.next()); - stat.execute("drop view test_view"); - stat.execute("drop table test"); - conn.close(); - } - - /** - * A test trigger adapter implementation. - */ - public static class TestTriggerAdapter extends TriggerAdapter { - - public void fire(Connection conn, ResultSet oldRow, ResultSet newRow) throws SQLException { - StringBuilder buff = new StringBuilder(); - if (oldRow != null) { - buff.append("-").append(oldRow.getString("id")).append(';'); - } - if (newRow != null) { - buff.append("+").append(newRow.getString("id")).append(';'); - } - conn.createStatement().execute("insert into message values('" + buff.toString() + "')"); - } - - } - - /** - * A test trigger implementation. - */ - public static class TestView implements Trigger { - - PreparedStatement prepInsert; - - public void init(Connection conn, String schemaName, String triggerName, String tableName, boolean before, - int type) throws SQLException { - prepInsert = conn.prepareStatement("insert into test values(?)"); - } - - public void fire(Connection conn, Object[] oldRow, Object[] newRow) throws SQLException { - prepInsert.setInt(1, (Integer) newRow[0]); - prepInsert.execute(); - } - - public void close() { - // ignore - } - - public void remove() { - // ignore - } - - } - - private void testTriggerBeforeSelect() throws SQLException { - Connection conn; - Statement stat; - conn = getConnection("trigger"); - stat = conn.createStatement(); - stat.execute("drop table if exists meta_tables"); - stat.execute("create table meta_tables(name varchar)"); - stat.execute("create trigger meta_tables_select before select on meta_tables call \"" + TestSelect.class.getName() + "\""); - ResultSet rs; - rs = stat.executeQuery("select * from meta_tables"); - assertTrue(rs.next()); - assertFalse(rs.next()); - stat.execute("create table test(id int)"); - rs = stat.executeQuery("select * from meta_tables"); - assertTrue(rs.next()); - assertTrue(rs.next()); - assertFalse(rs.next()); - conn.close(); - if (!config.memory) { - conn = getConnection("trigger"); - stat = conn.createStatement(); - stat.execute("create table test2(id int)"); - rs = stat.executeQuery("select * from meta_tables"); - assertTrue(rs.next()); - assertTrue(rs.next()); - assertTrue(rs.next()); - assertFalse(rs.next()); - conn.close(); - } - } - - /** - * A test trigger implementation. - */ - public static class TestSelect implements Trigger { - - PreparedStatement prepMeta; - - public void init(Connection conn, String schemaName, String triggerName, String tableName, boolean before, - int type) throws SQLException { - prepMeta = conn.prepareStatement("insert into meta_tables " + - "select table_name from information_schema.tables " + - "where table_schema='PUBLIC'"); - } - - public void fire(Connection conn, Object[] oldRow, Object[] newRow) throws SQLException { - conn.createStatement().execute("delete from meta_tables"); - prepMeta.execute(); - } - - public void close() { - // ignore - } - - public void remove() { - // ignore - } - - } - - /** - * A test trigger implementation. - */ - public static class Test implements Trigger { - - public void fire(Connection conn, Object[] oldRow, Object[] newRow) throws SQLException { - conn.createStatement().execute("call seq.nextval"); - } - - public void init(Connection conn, String schemaName, String triggerName, String tableName, boolean before, - int type) { - // nothing to do - } - - public void close() { - // ignore - } - - public void remove() { - // ignore - } - - } - - private void testTriggerAlterTable() throws SQLException { - Connection conn = getConnection("trigger"); - Statement stat = conn.createStatement(); - stat.execute("DROP TABLE IF EXISTS TEST"); - stat.execute("create sequence seq"); - stat.execute("create table test(id int primary key)"); - assertSingleValue(stat, "call seq.nextval", 1); - conn.setAutoCommit(false); - stat.execute("create trigger test_upd before insert on test call \"" + Test.class.getName() + "\""); - stat.execute("insert into test values(1)"); - assertSingleValue(stat, "call seq.nextval", 3); - stat.execute("alter table test add column name varchar"); - assertSingleValue(stat, "call seq.nextval", 4); - stat.execute("drop sequence seq"); - stat.execute("drop table test"); - conn.close(); - } - - private void testConstraints() throws SQLException { - Connection conn = getConnection("trigger"); - Statement stat = conn.createStatement(); - stat.execute("DROP TABLE IF EXISTS TEST"); - stat.execute("create table test(id int primary key, parent int)"); - stat.execute("alter table test add constraint test_parent_id foreign key(parent) references test (id) on delete cascade"); - stat.execute("insert into test select x, x/2 from system_range(0, 100)"); - stat.execute("delete from test"); - assertSingleValue(stat, "select count(*) from test", 0); - stat.execute("drop table test"); - conn.close(); - } - - private void testTriggers() throws SQLException { - mustNotCallTrigger = false; - Connection conn = getConnection("trigger"); - Statement stat = conn.createStatement(); - stat.execute("DROP TABLE IF EXISTS TEST"); - stat.execute("CREATE TABLE TEST(ID INT PRIMARY KEY, NAME VARCHAR(255))"); - // CREATE TRIGGER trigger {BEFORE|AFTER} - // {INSERT|UPDATE|DELETE|ROLLBACK} ON table - // [FOR EACH ROW] [QUEUE n] [NOWAIT] CALL triggeredClass - stat.execute("CREATE TRIGGER IF NOT EXISTS INS_BEFORE BEFORE INSERT ON TEST FOR EACH ROW NOWAIT CALL \"" - + getClass().getName() + "\""); - stat.execute("CREATE TRIGGER IF NOT EXISTS INS_BEFORE BEFORE INSERT ON TEST FOR EACH ROW NOWAIT CALL \"" - + getClass().getName() + "\""); - stat.execute("CREATE TRIGGER INS_AFTER AFTER INSERT ON TEST FOR EACH ROW NOWAIT CALL \"" + getClass().getName() - + "\""); - stat.execute("CREATE TRIGGER UPD_BEFORE BEFORE UPDATE ON TEST FOR EACH ROW NOWAIT CALL \"" - + getClass().getName() + "\""); - stat.execute("CREATE TRIGGER INS_AFTER_ROLLBACK AFTER INSERT, ROLLBACK ON TEST FOR EACH ROW NOWAIT CALL \"" + getClass().getName() - + "\""); - stat.execute("INSERT INTO TEST VALUES(1, 'Hello')"); - ResultSet rs; - rs = stat.executeQuery("SCRIPT"); - checkRows(rs, new String[] { - "CREATE FORCE TRIGGER PUBLIC.INS_BEFORE BEFORE INSERT ON PUBLIC.TEST FOR EACH ROW NOWAIT CALL \"" - + getClass().getName() + "\";", - "CREATE FORCE TRIGGER PUBLIC.INS_AFTER AFTER INSERT ON PUBLIC.TEST FOR EACH ROW NOWAIT CALL \"" - + getClass().getName() + "\";", - "CREATE FORCE TRIGGER PUBLIC.UPD_BEFORE BEFORE UPDATE ON PUBLIC.TEST FOR EACH ROW NOWAIT CALL \"" - + getClass().getName() + "\";", - "CREATE FORCE TRIGGER PUBLIC.INS_AFTER_ROLLBACK AFTER INSERT, ROLLBACK ON PUBLIC.TEST FOR EACH ROW NOWAIT CALL \"" - + getClass().getName() + "\";", - }); - while (rs.next()) { - String sql = rs.getString(1); - if (sql.startsWith("CREATE TRIGGER")) { - System.out.println(sql); - } - } - - rs = stat.executeQuery("SELECT * FROM TEST"); - rs.next(); - assertEquals("Hello-updated", rs.getString(2)); - assertFalse(rs.next()); - stat.execute("UPDATE TEST SET NAME=NAME||'-upd'"); - rs = stat.executeQuery("SELECT * FROM TEST"); - rs.next(); - assertEquals("Hello-updated-upd-updated2", rs.getString(2)); - assertFalse(rs.next()); - - mustNotCallTrigger = true; - stat.execute("DROP TRIGGER IF EXISTS INS_BEFORE"); - stat.execute("DROP TRIGGER IF EXISTS INS_BEFORE"); - stat.execute("DROP TRIGGER IF EXISTS INS_AFTER_ROLLBACK"); - try { - stat.execute("DROP TRIGGER INS_BEFORE"); - fail(); - } catch (SQLException e) { - assertKnownException(e); - } - stat.execute("DROP TRIGGER INS_AFTER"); - stat.execute("DROP TRIGGER UPD_BEFORE"); - stat.execute("UPDATE TEST SET NAME=NAME||'-upd-no_trigger'"); - stat.execute("INSERT INTO TEST VALUES(100, 'Insert-no_trigger')"); - conn.close(); - - conn = getConnection("trigger"); - - mustNotCallTrigger = false; - conn.close(); - } - - private void checkRows(ResultSet rs, String[] expected) throws SQLException { - HashSet set = new HashSet(Arrays.asList(expected)); - while (rs.next()) { - set.remove(rs.getString(1)); - } - if (set.size() > 0) { - fail("set should be empty: " + set); - } - } - - public void fire(Connection conn, Object[] oldRow, Object[] newRow) { - if (mustNotCallTrigger) { - throw new AssertionError("must not be called now"); - } - if (conn == null) { - throw new AssertionError("connection is null"); - } - if (triggerName.startsWith("INS_BEFORE")) { - newRow[1] = newRow[1] + "-updated"; - } else if (triggerName.startsWith("INS_AFTER")) { - if (!newRow[1].toString().endsWith("-updated")) { - throw new AssertionError("supposed to be updated"); - } - checkCommit(conn); - } else if (triggerName.startsWith("UPD_BEFORE")) { - newRow[1] = newRow[1] + "-updated2"; - } else if (triggerName.startsWith("UPD_AFTER")) { - if (!newRow[1].toString().endsWith("-updated2")) { - throw new AssertionError("supposed to be updated2"); - } - checkCommit(conn); - } - } - - public void close() { - // ignore - } - - public void remove() { - // ignore - } - - private void checkCommit(Connection conn) { - try { - conn.commit(); - throw new AssertionError("Commit must not work here"); - } catch (SQLException e) { - try { - assertKnownException(e); - } catch (Exception e2) { - throw new AssertionError("Unexpected: " + e.toString()); - } - } - try { - conn.createStatement().execute("CREATE TABLE X(ID INT)"); - throw new AssertionError("CREATE TABLE WORKED, but implicitly commits"); - } catch (SQLException e) { - try { - assertKnownException(e); - } catch (Exception e2) { - throw new AssertionError("Unexpected: " + e.toString()); - } - } - } - - public void init(Connection conn, String schemaName, String trigger, String tableName, boolean before, int type) { - this.triggerName = trigger; - if (!"TEST".equals(tableName)) { - throw new AssertionError("supposed to be TEST"); - } - if ((trigger.endsWith("AFTER") && before) || (trigger.endsWith("BEFORE") && !before)) { - throw new AssertionError("triggerName: " + trigger + " before:" + before); - } - if ((trigger.startsWith("UPD") && type != UPDATE) || (trigger.startsWith("INS") && type != INSERT) || (trigger.startsWith("DEL") && type != DELETE)) { - throw new AssertionError("triggerName: " + trigger + " type:" + type); - } - } - -} diff --git a/tools/h2/src/test/org/h2/test/db/TestTwoPhaseCommit.java b/tools/h2/src/test/org/h2/test/db/TestTwoPhaseCommit.java deleted file mode 100755 index fceebd2..0000000 --- a/tools/h2/src/test/org/h2/test/db/TestTwoPhaseCommit.java +++ /dev/null @@ -1,117 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.test.db; - -import java.sql.Connection; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.sql.Statement; -import java.util.ArrayList; - -import org.h2.test.TestBase; -import org.h2.util.New; - -/** - * Tests for the two-phase-commit feature. - */ -public class TestTwoPhaseCommit extends TestBase { - - /** - * Run just this test. - * - * @param a ignored - */ - public static void main(String... a) throws Exception { - TestBase.createCaller().init().test(); - } - - public void test() throws SQLException { - if (config.memory || config.networked) { - return; - } - - deleteDb("twoPhaseCommit"); - - prepare(); - openWith(true); - test(true); - - prepare(); - openWith(false); - test(false); - - testLargeTransactionName(); - deleteDb("twoPhaseCommit"); - } - - private void testLargeTransactionName() throws SQLException { - Connection conn = getConnection("twoPhaseCommit"); - Statement stat = conn.createStatement(); - conn.setAutoCommit(false); - stat.execute("CREATE TABLE TEST2(ID INT)"); - String name = "tx12345678"; - try { - for (int i = 0;; i++) { - stat.execute("INSERT INTO TEST2 VALUES(1)"); - name += "x"; - stat.execute("PREPARE COMMIT " + name); - } - } catch (SQLException e) { - assertKnownException(e); - } - conn.close(); - } - - private void test(boolean rolledBack) throws SQLException { - Connection conn = getConnection("twoPhaseCommit"); - Statement stat = conn.createStatement(); - stat.execute("SET WRITE_DELAY 0"); - ResultSet rs = stat.executeQuery("SELECT * FROM TEST ORDER BY ID"); - rs.next(); - assertEquals(1, rs.getInt(1)); - assertEquals("Hello", rs.getString(2)); - if (!rolledBack) { - rs.next(); - assertEquals(2, rs.getInt(1)); - assertEquals("World", rs.getString(2)); - } - assertFalse(rs.next()); - conn.close(); - } - - private void openWith(boolean rollback) throws SQLException { - Connection conn = getConnection("twoPhaseCommit"); - Statement stat = conn.createStatement(); - ArrayList list = New.arrayList(); - ResultSet rs = stat.executeQuery("SELECT * FROM INFORMATION_SCHEMA.IN_DOUBT"); - while (rs.next()) { - list.add(rs.getString("TRANSACTION")); - } - for (String s : list) { - if (rollback) { - stat.execute("ROLLBACK TRANSACTION " + s); - } else { - stat.execute("COMMIT TRANSACTION " + s); - } - } - conn.close(); - } - - private void prepare() throws SQLException { - deleteDb("twoPhaseCommit"); - Connection conn = getConnection("twoPhaseCommit"); - Statement stat = conn.createStatement(); - stat.execute("SET WRITE_DELAY 0"); - conn.setAutoCommit(false); - stat.execute("CREATE TABLE TEST(ID INT PRIMARY KEY, NAME VARCHAR)"); - stat.execute("INSERT INTO TEST VALUES(1, 'Hello')"); - conn.commit(); - stat.execute("INSERT INTO TEST VALUES(2, 'World')"); - stat.execute("PREPARE COMMIT XID_TEST_TRANSACTION_WITH_LONG_NAME"); - crash(conn); - } -} diff --git a/tools/h2/src/test/org/h2/test/db/TestView.java b/tools/h2/src/test/org/h2/test/db/TestView.java deleted file mode 100755 index 6f660cc..0000000 --- a/tools/h2/src/test/org/h2/test/db/TestView.java +++ /dev/null @@ -1,144 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.test.db; - -import java.sql.Connection; -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.sql.Statement; -import org.h2.test.TestBase; - -/** - * Test for views. - */ -public class TestView extends TestBase { - - private static int x; - - /** - * Run just this test. - * - * @param a ignored - */ - public static void main(String... a) throws Exception { - TestBase.createCaller().init().test(); - } - - public void test() throws SQLException { - testCache(); - testCacheFunction(true); - testCacheFunction(false); - testInSelect(); - testUnionReconnect(); - testManyViews(); - deleteDb("view"); - } - - private void testCacheFunction(boolean deterministic) throws SQLException { - deleteDb("view"); - Connection conn = getConnection("view"); - Statement stat = conn.createStatement(); - stat.execute("CREATE ALIAS GET_X " + - (deterministic ? "DETERMINISTIC" : "") + - " FOR \"" + getClass().getName() + ".getX\""); - stat.execute("CREATE VIEW V AS SELECT * FROM (SELECT GET_X())"); - ResultSet rs; - x = 8; - rs = stat.executeQuery("SELECT * FROM V"); - rs.next(); - assertEquals(8, rs.getInt(1)); - x = 5; - rs = stat.executeQuery("SELECT * FROM V"); - rs.next(); - assertEquals(deterministic ? 8 : 5, rs.getInt(1)); - conn.close(); - } - - /** - * This method is called via reflection from the database. - * - * @return the static value x - */ - public static int getX() { - return x; - } - - private void testCache() throws SQLException { - deleteDb("view"); - Connection conn = getConnection("view"); - Statement stat = conn.createStatement(); - stat.execute("SET @X 8"); - stat.execute("CREATE VIEW V AS SELECT * FROM (SELECT @X)"); - ResultSet rs; - rs = stat.executeQuery("SELECT * FROM V"); - rs.next(); - assertEquals(8, rs.getInt(1)); - stat.execute("SET @X 5"); - rs = stat.executeQuery("SELECT * FROM V"); - rs.next(); - assertEquals(5, rs.getInt(1)); - conn.close(); - } - - private void testInSelect() throws SQLException { - deleteDb("view"); - Connection conn = getConnection("view"); - Statement stat = conn.createStatement(); - stat.execute("create table test(id int primary key) as select 1"); - PreparedStatement prep = conn.prepareStatement( - "select * from test t where t.id in (select t2.id from test t2 where t2.id in (?, ?))"); - prep.setInt(1, 1); - prep.setInt(2, 2); - prep.execute(); - conn.close(); - } - - private void testUnionReconnect() throws SQLException { - if (config.memory) { - return; - } - deleteDb("view"); - Connection conn = getConnection("view"); - Statement stat = conn.createStatement(); - stat.execute("create table t1(k smallint, ts timestamp(6))"); - stat.execute("create table t2(k smallint, ts timestamp(6))"); - stat.execute("create table t3(k smallint, ts timestamp(6))"); - stat.execute("create view v_max_ts as select " + - "max(ts) from (select max(ts) as ts from t1 " + - "union select max(ts) as ts from t2 " + - "union select max(ts) as ts from t3)"); - stat.execute("create view v_test as select max(ts) as ts from t1 " + - "union select max(ts) as ts from t2 " + - "union select max(ts) as ts from t3"); - conn.close(); - conn = getConnection("view"); - stat = conn.createStatement(); - stat.execute("select * from v_max_ts"); - conn.close(); - deleteDb("view"); - } - - private void testManyViews() throws SQLException { - deleteDb("view"); - Connection conn = getConnection("view"); - Statement s = conn.createStatement(); - s.execute("create table t0(id int primary key)"); - s.execute("insert into t0 values(1), (2), (3)"); - for (int i = 0; i < 30; i++) { - s.execute("create view t" + (i + 1) + " as select * from t" + i); - s.execute("select * from t" + (i + 1)); - ResultSet rs = s.executeQuery("select count(*) from t" + (i + 1) + " where id=2"); - assertTrue(rs.next()); - assertEquals(1, rs.getInt(1)); - } - conn.close(); - conn = getConnection("view"); - conn.close(); - deleteDb("view"); - } -} diff --git a/tools/h2/src/test/org/h2/test/db/TestViewAlterTable.java b/tools/h2/src/test/org/h2/test/db/TestViewAlterTable.java deleted file mode 100755 index 0ff4dc5..0000000 --- a/tools/h2/src/test/org/h2/test/db/TestViewAlterTable.java +++ /dev/null @@ -1,197 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.test.db; - -import java.sql.Connection; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.sql.Statement; -import org.h2.test.TestBase; -import org.h2.constant.ErrorCode; - -/** - * Test the impact of ALTER TABLE statements on views. - */ -public class TestViewAlterTable extends TestBase { - - private Connection conn; - private Statement stat; - - /** - * Run just this test. - * - * @param a ignored - */ - public static void main(String... a) throws Exception { - TestBase.createCaller().init().test(); - } - - public void test() throws Exception { - deleteDb("alter"); - conn = getConnection("alter"); - stat = conn.createStatement(); - - testDropColumnWithoutViews(); - testViewsAreWorking(); - testAlterTableDropColumnNotInView(); - testAlterTableDropColumnInView(); - testAlterTableAddColumnWithView(); - testAlterTableAlterColumnDataTypeWithView(); - testSelectStar(); - testJoinAndAlias(); - testSubSelect(); - testForeignKey(); - - conn.close(); - deleteDb("alter"); - } - - private void testDropColumnWithoutViews() throws SQLException { - stat.execute("create table test(a int, b int, c int)"); - stat.execute("alter table test drop column c"); - stat.execute("drop table test"); - } - - private void testViewsAreWorking() throws SQLException { - createTestData(); - checkViewRemainsValid(); - } - - private void testAlterTableDropColumnNotInView() throws SQLException { - createTestData(); - stat.execute("alter table test drop column c"); - checkViewRemainsValid(); - } - - private void testAlterTableDropColumnInView() throws SQLException { - // simple - stat.execute("create table test(id identity, name varchar) as select x, 'Hello'"); - stat.execute("create view test_view as select * from test"); - try { - stat.execute("alter table test drop name"); - fail(); - } catch (SQLException e) { - assertEquals(ErrorCode.VIEW_IS_INVALID_2, e.getErrorCode()); - } - ResultSet rs = stat.executeQuery("select * from test_view"); - assertTrue(rs.next()); - stat.execute("drop view test_view"); - stat.execute("drop table test"); - - // nested - createTestData(); - try { - stat.execute("alter table test drop column a"); - fail("Should throw exception because V1 uses column A"); - } catch (SQLException e) { - assertEquals(ErrorCode.VIEW_IS_INVALID_2, e.getErrorCode()); - } - stat.execute("drop table test"); - } - - private void testAlterTableAddColumnWithView() throws SQLException { - createTestData(); - stat.execute("alter table test add column d int"); - checkViewRemainsValid(); - } - - private void testAlterTableAlterColumnDataTypeWithView() throws SQLException { - createTestData(); - stat.execute("alter table test alter b char(1)"); - checkViewRemainsValid(); - } - - private void testSelectStar() throws SQLException { - createTestData(); - stat.execute("create view v4 as select * from test"); - stat.execute("alter table test add d int default 6"); - try { - stat.executeQuery("select d from v4"); - // H2 doesn't remember v4 as 'select * from test', - // it instead remembers each individual column that was in 'test' when the - // view was originally created. This is consistent with PostgreSQL. - } catch (SQLException e) { - assertEquals(ErrorCode.COLUMN_NOT_FOUND_1, e.getErrorCode()); - } - checkViewRemainsValid(); - } - - private void testJoinAndAlias() throws SQLException { - createTestData(); - stat.execute("create view v4 as select v1.a dog, v3.a cat from v1 join v3 on v1.b = v3.a"); - // should make no difference - stat.execute("alter table test add d int default 6"); - ResultSet rs = stat.executeQuery("select cat, dog from v4"); - assertTrue(rs.next()); - assertEquals(1, rs.getInt(1)); - assertEquals(2, rs.getInt(2)); - assertFalse(rs.next()); - checkViewRemainsValid(); - } - - private void testSubSelect() throws SQLException { - createTestData(); - stat.execute("create view v4 as select * from v3 where a in (select b from v2)"); - // should make no difference - stat.execute("alter table test add d int default 6"); - ResultSet rs = stat.executeQuery("select a from v4"); - assertTrue(rs.next()); - assertEquals(1, rs.getInt(1)); - assertFalse(rs.next()); - checkViewRemainsValid(); - } - - private void testForeignKey() throws SQLException { - createTestData(); - stat.execute("create table test2(z int, a int, primary key(z), foreign key (a) references TEST(a))"); - stat.execute("insert into test2(z, a) values (99, 1)"); - // should make no difference - stat.execute("alter table test add d int default 6"); - ResultSet rs = stat.executeQuery("select z from test2"); - assertTrue(rs.next()); - assertEquals(99, rs.getInt(1)); - assertFalse(rs.next()); - stat.execute("drop table test2"); - checkViewRemainsValid(); - } - - private void createTestData() throws SQLException { - stat.execute("create table test(a int, b int, c int)"); - stat.execute("insert into test(a, b, c) values (1, 2, 3)"); - stat.execute("create view v1 as select a as b, b as a from test"); - // child of v1 - stat.execute("create view v2 as select * from v1"); - // sibling of v1 - stat.execute("create view v3 as select a from test"); - } - - private void checkViewRemainsValid() throws SQLException { - ResultSet rs = stat.executeQuery("select b from v1"); - assertTrue(rs.next()); - assertEquals(1, rs.getInt(1)); - assertFalse(rs.next()); - - rs = stat.executeQuery("select b from v2"); - assertTrue(rs.next()); - assertEquals(1, rs.getInt(1)); - assertFalse(rs.next()); - - rs = stat.executeQuery("select b from test"); - assertTrue(rs.next()); - assertEquals(2, rs.getInt(1)); - assertFalse(rs.next()); - - stat.execute("drop table test"); - - ResultSet d = conn.getMetaData().getTables(null, null, null, null); - while (d.next()) { - if (!d.getString(2).equals("INFORMATION_SCHEMA")) { - fail("Should have no tables left in the database, not: " + d.getString(2) + "." + d.getString(3)); - } - } - } -} diff --git a/tools/h2/src/test/org/h2/test/db/package.html b/tools/h2/src/test/org/h2/test/db/package.html deleted file mode 100755 index 3d67da4..0000000 --- a/tools/h2/src/test/org/h2/test/db/package.html +++ /dev/null @@ -1,15 +0,0 @@ - - - - -Javadoc package documentation -

    - -Database tests. Most tests are on the SQL level. - -

    \ No newline at end of file diff --git a/tools/h2/src/test/org/h2/test/jaqu/AliasMapTest.java b/tools/h2/src/test/org/h2/test/jaqu/AliasMapTest.java deleted file mode 100755 index 8fc2545..0000000 --- a/tools/h2/src/test/org/h2/test/jaqu/AliasMapTest.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.test.jaqu; - -import java.util.List; -import org.h2.jaqu.Db; -import org.h2.test.TestBase; - -/** - * Tests that columns (p.unitsInStock) are not compared by value with the value - * (9), but by reference (using an identity hash map). - * See http://code.google.com/p/h2database/issues/detail?id=119 - * - * @author d moebius at scoop slash gmbh dot de - */ -public class AliasMapTest extends TestBase { - - /** - * This method is called when executing this application from the command - * line. - * - * @param args the command line parameters - */ - public static void main(String... args) throws Exception { - new AliasMapTest().test(); - } - - public void test() throws Exception { - Db db = Db.open("jdbc:h2:mem:", "sa", "sa"); - db.insertAll(Product.getList()); - - Product p = new Product(); - List products = db - .from(p) - .where(p.unitsInStock).is(9) - .orderBy(p.productId).select(); - - assertEquals("[]", products.toString()); - - db.close(); - } -} - diff --git a/tools/h2/src/test/org/h2/test/jaqu/ComplexObject.java b/tools/h2/src/test/org/h2/test/jaqu/ComplexObject.java deleted file mode 100755 index d47b23e..0000000 --- a/tools/h2/src/test/org/h2/test/jaqu/ComplexObject.java +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.test.jaqu; - -//## Java 1.5 begin ## -import static org.h2.jaqu.Define.*; - -import java.math.BigDecimal; -import java.util.Arrays; -import java.util.Date; -import java.util.List; -import java.sql.Time; -import java.sql.Timestamp; -import org.h2.jaqu.Table; -//## Java 1.5 end ## - -/** - * A table containing all possible data types. - */ -//## Java 1.5 begin ## -public class ComplexObject implements Table { - public Integer id; - public Long amount; - public String name; - public BigDecimal value; - public Date birthday; - public Time time; - public Timestamp created; - - static ComplexObject build(Integer id, boolean isNull) { - ComplexObject obj = new ComplexObject(); - obj.id = id; - obj.amount = isNull ? null : Long.valueOf(1); - obj.name = isNull ? null : "hello"; - obj.value = isNull ? null : new BigDecimal("1"); - obj.birthday = isNull ? null : java.sql.Date.valueOf("2001-01-01"); - obj.time = isNull ? null : Time.valueOf("10:20:30"); - obj.created = isNull ? null : Timestamp.valueOf("2002-02-02 02:02:02"); - return obj; - } - - public void define() { - primaryKey(id); - } - - public static List getList() { - return Arrays.asList(new ComplexObject[] { build(0, true), build(1, false) }); - } - -} -//## Java 1.5 end ## diff --git a/tools/h2/src/test/org/h2/test/jaqu/Customer.java b/tools/h2/src/test/org/h2/test/jaqu/Customer.java deleted file mode 100755 index 69d0906..0000000 --- a/tools/h2/src/test/org/h2/test/jaqu/Customer.java +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.test.jaqu; - -//## Java 1.5 begin ## -import java.util.Arrays; -import java.util.List; -//## Java 1.5 end ## - -/** - * A table containing customer data. - */ -public class Customer { - - public String customerId; - public String region; - - public Customer() { - // public constructor - } - - public Customer(String customerId, String region) { - this.customerId = customerId; - this.region = region; - } - - public String toString() { - return customerId; - } - -//## Java 1.5 begin ## - public static List getList() { - Customer[] list = { - new Customer("ALFKI", "WA"), - new Customer("ANATR", "WA"), - new Customer("ANTON", "CA") }; - return Arrays.asList(list); - } -//## Java 1.5 end ## -} diff --git a/tools/h2/src/test/org/h2/test/jaqu/Order.java b/tools/h2/src/test/org/h2/test/jaqu/Order.java deleted file mode 100755 index 348b54b..0000000 --- a/tools/h2/src/test/org/h2/test/jaqu/Order.java +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.test.jaqu; - -//## Java 1.5 begin ## -import static org.h2.jaqu.Define.*; - -import java.math.BigDecimal; -import java.util.Arrays; -import java.util.Date; -import java.util.List; - -import org.h2.jaqu.Table; -//## Java 1.5 end ## - -/** - * A table containing order data. - */ -//## Java 1.5 begin ## - -public class Order implements Table { - public String customerId; - public Integer orderId; - public Date orderDate; - public BigDecimal total; - - public Order(String customerId, Integer orderId, - String total, String orderDate) { - this.customerId = customerId; - this.orderId = orderId; - this.total = new BigDecimal(total); - this.orderDate = java.sql.Date.valueOf(orderDate); - } - - public Order() { - // public constructor - } - - public void define() { - tableName("Orders"); - primaryKey(customerId, orderId); - } - - public static List getList() { - Order[] list = { - new Order("ALFKI", 10702, "330.00", "2007-01-02"), - new Order("ALFKI", 10952, "471.20", "2007-02-03"), - new Order("ANATR", 10308, "88.80", "2007-01-03"), - new Order("ANATR", 10625, "479.75", "2007-03-03"), - new Order("ANATR", 10759, "320.00", "2007-04-01"), - new Order("ANTON", 10365, "403.20", "2007-02-13"), - new Order("ANTON", 10682, "375.50", "2007-03-13"), - new Order("ANTON", 10355, "480.00", "2007-04-11") }; - return Arrays.asList(list); - } - -} -//## Java 1.5 end ## diff --git a/tools/h2/src/test/org/h2/test/jaqu/Product.java b/tools/h2/src/test/org/h2/test/jaqu/Product.java deleted file mode 100755 index f53c81d..0000000 --- a/tools/h2/src/test/org/h2/test/jaqu/Product.java +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.test.jaqu; - -//## Java 1.5 begin ## -import java.util.Arrays; -import java.util.List; - -import org.h2.jaqu.Table; - -import static org.h2.jaqu.Define.*; -//## Java 1.5 end ## - -/** - * A table containing product data. - */ -//## Java 1.5 begin ## -public class Product implements Table { - - public Integer productId; - public String productName; - public String category; - public Double unitPrice; - public Integer unitsInStock; - - public Product() { - // public constructor - } - - private Product(int productId, String productName, - String category, double unitPrice, int unitsInStock) { - this.productId = productId; - this.productName = productName; - this.category = category; - this.unitPrice = unitPrice; - this.unitsInStock = unitsInStock; - } - - public void define() { - tableName("Product"); - primaryKey(productId); - maxLength(category, 255); - index(productName, category); - } - - private static Product create(int productId, String productName, - String category, double unitPrice, int unitsInStock) { - return new Product(productId, productName, category, - unitPrice, unitsInStock); - } - - public static List getList() { - Product[] list = { - create(1, "Chai", "Beverages", 18, 39), - create(2, "Chang", "Beverages", 19.0, 17), - create(3, "Aniseed Syrup", "Condiments", 10.0, 13), - create(4, "Chef Anton's Cajun Seasoning", "Condiments", 22.0, 53), - create(5, "Chef Anton's Gumbo Mix", "Condiments", 21.3500, 0), - create(6, "Grandma's Boysenberry Spread", "Condiments", 25.0, 120), - create(7, "Uncle Bob's Organic Dried Pears", "Produce", 30.0, 15), - create(8, "Northwoods Cranberry Sauce", "Condiments", 40.0, 6), - create(9, "Mishi Kobe Niku", "Meat/Poultry", 97.0, 29), - create(10, "Ikura", "Seafood", 31.0, 31), - }; - - return Arrays.asList(list); - } - - public String toString() { - return productName + ": " + unitsInStock; - } - -} -//## Java 1.5 end ## diff --git a/tools/h2/src/test/org/h2/test/jaqu/SamplesTest.java b/tools/h2/src/test/org/h2/test/jaqu/SamplesTest.java deleted file mode 100755 index b6dccc4..0000000 --- a/tools/h2/src/test/org/h2/test/jaqu/SamplesTest.java +++ /dev/null @@ -1,419 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.test.jaqu; - -import static org.h2.jaqu.Function.count; -import static org.h2.jaqu.Function.isNull; -import static org.h2.jaqu.Function.length; -import static org.h2.jaqu.Function.*; -import java.math.BigDecimal; -import java.util.List; -import org.h2.jaqu.Db; -import org.h2.jaqu.Filter; -import org.h2.test.TestBase; - -/** - * This is the implementation of the 101 LINQ Samples as described in - * http://msdn2.microsoft.com/en-us/vcsharp/aa336760.aspx - */ -public class SamplesTest extends TestBase { - - /** - * This object represents a database (actually a connection to the database). - */ -//## Java 1.5 begin ## - Db db; -//## Java 1.5 end ## - - /** - * This method is called when executing this application from the command - * line. - * - * @param args the command line parameters - */ - public static void main(String... args) { - new SamplesTest().test(); - } - - public void test() { -//## Java 1.5 begin ## - db = Db.open("jdbc:h2:mem:", "sa", "sa"); - db.insertAll(Product.getList()); - db.insertAll(Customer.getList()); - db.insertAll(Order.getList()); - db.insertAll(ComplexObject.getList()); - // TODO support getters/setters - // TODO support all relevant data types (byte[], ...) - // TODO nested AND/OR, >, <, ... - // TODO NOT - // TODO +, -, *, /, ||, nested operations - // TODO LIKE ESCAPE... - // TODO UPDATE: FROM ... UPDATE? - // TODO SELECT UNION - // TODO DatabaseAdapter - testComplexObject(); - testComplexObject2(); - testOrAndNot(); - testDelete(); - testIsNull(); - testLike(); - testMinMax(); - testSum(); - testLength(); - testCount(); - testGroup(); - testSelectManyCompoundFrom2(); - testWhereSimple4(); - testSelectSimple2(); - testAnonymousTypes3(); - testWhereSimple2(); - testWhereSimple3(); - testReverseColumns(); - db.close(); -//## Java 1.5 end ## - } - - /** - * A simple test table. The columns are in a different order than in the - * database. - */ - public static class TestReverse { - public String name; - public Integer id; - } - -//## Java 1.5 begin ## - private void testReverseColumns() { - db.executeUpdate("create table TestReverse(id int, name varchar, additional varchar)"); - TestReverse t = new TestReverse(); - t.id = 10; - t.name = "Hello"; - db.insert(t); - TestReverse check = db.from(new TestReverse()).selectFirst(); - assertEquals(t.name, check.name); - assertEquals(t.id, check.id); - } -//## Java 1.5 end ## - - -//## Java 1.5 begin ## - private void testWhereSimple2() { - -// var soldOutProducts = -// from p in products -// where p.UnitsInStock == 0 -// select p; - - Product p = new Product(); - List soldOutProducts = - db.from(p). - where(p.unitsInStock).is(0). - orderBy(p.productId).select(); - - assertEquals("[Chef Anton's Gumbo Mix: 0]", soldOutProducts.toString()); - } - - private void testWhereSimple3() { - -// var expensiveInStockProducts = -// from p in products -// where p.UnitsInStock > 0 -// && p.UnitPrice > 3.00M -// select p; - - Product p = new Product(); - List expensiveInStockProducts = - db.from(p). - where(p.unitsInStock).bigger(0). - and(p.unitPrice).bigger(30.0). - orderBy(p.productId).select(); - - assertEquals("[Northwoods Cranberry Sauce: 6, Mishi Kobe Niku: 29, Ikura: 31]", - expensiveInStockProducts.toString()); - } - - private void testWhereSimple4() { - -// var waCustomers = -// from c in customers -// where c.Region == "WA" -// select c; - - Customer c = new Customer(); - List waCustomers = - db.from(c). - where(c.region).is("WA"). - select(); - - assertEquals("[ALFKI, ANATR]", waCustomers.toString()); - } - - private void testSelectSimple2() { - -// var productNames = -// from p in products -// select p.ProductName; - - Product p = new Product(); - List productNames = - db.from(p). - orderBy(p.productId).select(p.productName); - - List products = Product.getList(); - for (int i = 0; i < products.size(); i++) { - assertEquals(products.get(i).productName, productNames.get(i)); - } - } -//## Java 1.5 end ## - - /** - * A result set class containing the product name and price. - */ - public static class ProductPrice { - public String productName; - public String category; - public Double price; - } - -//## Java 1.5 begin ## - private void testAnonymousTypes3() { - -// var productInfos = -// from p in products -// select new { -// p.ProductName, -// p.Category, -// Price = p.UnitPrice -// }; - - final Product p = new Product(); - List productInfos = - db.from(p).orderBy(p.productId). - select(new ProductPrice() { { - productName = p.productName; - category = p.category; - price = p.unitPrice; - }}); - - List products = Product.getList(); - assertEquals(products.size(), productInfos.size()); - for (int i = 0; i < products.size(); i++) { - ProductPrice pr = productInfos.get(i); - Product p2 = products.get(i); - assertEquals(p2.productName, pr.productName); - assertEquals(p2.category, pr.category); - assertEquals(p2.unitPrice, pr.price); - } - } -//## Java 1.5 end ## - - /** - * A result set class containing customer data and the order total. - */ - public static class CustOrder { - public String customerId; - public Integer orderId; - public BigDecimal total; - public String toString() { - return customerId + ":" + orderId + ":" + total; - } - } - -//## Java 1.5 begin ## - private void testSelectManyCompoundFrom2() { - -// var orders = -// from c in customers, -// o in c.Orders -// where o.Total < 500.00M -// select new { -// c.CustomerID, -// o.OrderID, -// o.Total -// }; - - final Customer c = new Customer(); - final Order o = new Order(); - List orders = - db.from(c). - innerJoin(o).on(c.customerId).is(o.customerId). - where(o.total).smaller(new BigDecimal("100.00")). - orderBy(1). - select(new CustOrder() { { - customerId = c.customerId; - orderId = o.orderId; - total = o.total; - }}); - - assertEquals("[ANATR:10308:88.80]", orders.toString()); - } - - private void testIsNull() { - Product p = new Product(); - String sql = db.from(p).whereTrue(isNull(p.productName)).getSQL(); - assertEquals("SELECT * FROM Product WHERE (productName IS NULL)", sql); - } - - private void testDelete() { - Product p = new Product(); - int deleted = db.from(p).where(p.productName).like("A%").delete(); - assertEquals(1, deleted); - deleted = db.from(p).delete(); - assertEquals(9, deleted); - db.insertAll(Product.getList()); - } - - private void testOrAndNot() { - Product p = new Product(); - String sql = db.from(p).whereTrue(not(isNull(p.productName))).getSQL(); - assertEquals("SELECT * FROM Product WHERE (NOT productName IS NULL)", sql); - sql = db.from(p).whereTrue(not(isNull(p.productName))).getSQL(); - assertEquals("SELECT * FROM Product WHERE (NOT productName IS NULL)", sql); - sql = db.from(p).whereTrue(db.test(p.productId).is(1)).getSQL(); - assertEquals("SELECT * FROM Product WHERE ((productId = ?))", sql); - } - - private void testLength() { - Product p = new Product(); - List lengths = - db.from(p). - where(length(p.productName)).smaller(10). - orderBy(1). - selectDistinct(length(p.productName)); - assertEquals("[4, 5]", lengths.toString()); - } - - private void testSum() { - Product p = new Product(); - Long sum = db.from(p).selectFirst(sum(p.unitsInStock)); - assertEquals(323, sum.intValue()); - Double sumPrice = db.from(p).selectFirst(sum(p.unitPrice)); - assertEquals(313.35, sumPrice.doubleValue()); - } - - private void testMinMax() { - Product p = new Product(); - Integer min = db.from(p).selectFirst(min(p.unitsInStock)); - assertEquals(0, min.intValue()); - String minName = db.from(p).selectFirst(min(p.productName)); - assertEquals("Aniseed Syrup", minName); - Double max = db.from(p).selectFirst(max(p.unitPrice)); - assertEquals(97.0, max.doubleValue()); - } - - private void testLike() { - Product p = new Product(); - List aList = db.from(p). - where(p.productName).like("Cha%"). - orderBy(p.productName).select(); - assertEquals("[Chai: 39, Chang: 17]", aList.toString()); - } - - private void testCount() { - long count = db.from(new Product()).selectCount(); - assertEquals(10, count); - } - - private void testComplexObject() { - ComplexObject co = new ComplexObject(); - String sql = db.from(co). - where(co.id).is(1). - and(co.amount).is(1L). - and(co.birthday).smaller(new java.util.Date()). - and(co.created).smaller(java.sql.Timestamp.valueOf("2005-05-05 05:05:05")). - and(co.name).is("hello"). - and(co.time).smaller(java.sql.Time.valueOf("23:23:23")). - and(co.value).is(new BigDecimal("1")).getSQL(); - assertEquals("SELECT * FROM ComplexObject " + - "WHERE id = ? " + - "AND amount = ? " + - "AND birthday < ? " + - "AND created < ? " + - "AND name = ? " + - "AND time < ? " + - "AND value = ?", sql); - - long count = db.from(co). - where(co.id).is(1). - and(co.amount).is(1L). - and(co.birthday).smaller(new java.util.Date()). - and(co.created).smaller(java.sql.Timestamp.valueOf("2005-05-05 05:05:05")). - and(co.name).is("hello"). - and(co.time).smaller(java.sql.Time.valueOf("23:23:23")). - and(co.value).is(new BigDecimal("1")). - selectCount(); - assertEquals(1, count); - } - - private void testComplexObject2() { - testComplexObject2(1, "hello"); - } - - private void testComplexObject2(final int x, final String name) { - final ComplexObject co = new ComplexObject(); - - String sql = db.from(co). - where(new Filter() { public boolean where() { - return co.id == x - && co.name.equals(name) - && co.name.equals("hello"); - } }).getSQL(); - assertEquals("SELECT * FROM ComplexObject " + - "WHERE id=? " + - "AND ?=name " + - "AND 'hello'=name", sql); - - long count = db.from(co). - where(new Filter() { public boolean where() { - return co.id == x - && co.name.equals(name) - && co.name.equals("hello"); - } }).selectCount(); - - assertEquals(1, count); - } -//## Java 1.5 end ## - - /** - * A result set class containing product groups. - */ - public static class ProductGroup { - public String category; - public Long productCount; - public String toString() { - return category + ":" + productCount; - } - } - -//## Java 1.5 begin ## - private void testGroup() { - -// var orderGroups = -// from p in products -// group p by p.Category into g -// select new { -// Category = g.Key, -// Products = g -// }; - - final Product p = new Product(); - List list = - db.from(p). - groupBy(p.category). - orderBy(1). - select(new ProductGroup() { { - category = p.category; - productCount = count(); - }}); - - assertEquals("[Beverages:2, Condiments:5, " + - "Meat/Poultry:1, Produce:1, Seafood:1]", - list.toString()); - } - -//## Java 1.5 end ## -} diff --git a/tools/h2/src/test/org/h2/test/jaqu/UpdateTest.java b/tools/h2/src/test/org/h2/test/jaqu/UpdateTest.java deleted file mode 100755 index 19937c7..0000000 --- a/tools/h2/src/test/org/h2/test/jaqu/UpdateTest.java +++ /dev/null @@ -1,115 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.test.jaqu; - -import org.h2.jaqu.Db; -import org.h2.test.TestBase; - -import static java.sql.Date.valueOf; - -/** - * Tests the Db.update() function. - * - * @author dmoebius at scoop slash gmbh dot de - */ -public class UpdateTest extends TestBase { - - Db db; - - /** - * This method is called when executing this application from the command - * line. - * - * @param args the command line parameters - */ - public static void main(String... args) throws Exception { - new UpdateTest().test(); - } - - public void test() throws Exception { - db = Db.open("jdbc:h2:mem:", "sa", "sa"); - db.insertAll(Product.getList()); - db.insertAll(Customer.getList()); - db.insertAll(Order.getList()); - - testSimpleUpdate(); - testSimpleUpdateWithCombinedPrimaryKey(); - testSimpleMerge(); - testSimpleMergeWithCombinedPrimaryKey(); - - db.close(); - } - - private void testSimpleUpdate() { - Product p = new Product(); - Product pChang = db.from(p).where(p.productName).is("Chang").selectFirst(); - // update unitPrice from 19.0 to 19.5 - pChang.unitPrice = 19.5; - // update unitsInStock from 17 to 16 - pChang.unitsInStock = 16; - db.update(pChang); - - Product p2 = new Product(); - Product pChang2 = db.from(p2).where(p2.productName).is("Chang").selectFirst(); - assertEquals(19.5, pChang2.unitPrice); - assertEquals(new Integer(16), pChang2.unitsInStock); - - // undo update - pChang.unitPrice = 19.0; - pChang.unitsInStock = 17; - db.update(pChang); - } - - private void testSimpleUpdateWithCombinedPrimaryKey() { - Order o = new Order(); - Order ourOrder = db.from(o).where(o.orderDate).is(valueOf("2007-01-02")).selectFirst(); - ourOrder.orderDate = valueOf("2007-01-03"); - db.update(ourOrder); - - Order ourUpdatedOrder = db.from(o).where(o.orderDate).is(valueOf("2007-01-03")).selectFirst(); - assertTrue("updated order not found", ourUpdatedOrder != null); - - // undo update - ourOrder.orderDate = valueOf("2007-01-02"); - db.update(ourOrder); - } - - private void testSimpleMerge() { - Product p = new Product(); - Product pChang = db.from(p).where(p.productName).is("Chang").selectFirst(); - // update unitPrice from 19.0 to 19.5 - pChang.unitPrice = 19.5; - // update unitsInStock from 17 to 16 - pChang.unitsInStock = 16; - db.merge(pChang); - - Product p2 = new Product(); - Product pChang2 = db.from(p2).where(p2.productName).is("Chang").selectFirst(); - assertEquals(19.5, pChang2.unitPrice); - assertEquals(new Integer(16), pChang2.unitsInStock); - - // undo update - pChang.unitPrice = 19.0; - pChang.unitsInStock = 17; - db.merge(pChang); - } - - private void testSimpleMergeWithCombinedPrimaryKey() { - Order o = new Order(); - Order ourOrder = db.from(o).where(o.orderDate).is(valueOf("2007-01-02")).selectFirst(); - ourOrder.orderDate = valueOf("2007-01-03"); - db.merge(ourOrder); - - Order ourUpdatedOrder = db.from(o).where(o.orderDate).is(valueOf("2007-01-03")).selectFirst(); - assertTrue("updated order not found", ourUpdatedOrder != null); - - // undo update - ourOrder.orderDate = valueOf("2007-01-02"); - db.merge(ourOrder); - } - -} diff --git a/tools/h2/src/test/org/h2/test/jaqu/package.html b/tools/h2/src/test/org/h2/test/jaqu/package.html deleted file mode 100755 index be732e5..0000000 --- a/tools/h2/src/test/org/h2/test/jaqu/package.html +++ /dev/null @@ -1,15 +0,0 @@ - - - - -Javadoc package documentation -

    - -JaQu (Java Query) test cases. - -

    \ No newline at end of file diff --git a/tools/h2/src/test/org/h2/test/jdbc/TestBatchUpdates.java b/tools/h2/src/test/org/h2/test/jdbc/TestBatchUpdates.java deleted file mode 100755 index d19c424..0000000 --- a/tools/h2/src/test/org/h2/test/jdbc/TestBatchUpdates.java +++ /dev/null @@ -1,530 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.test.jdbc; - -import java.io.ByteArrayOutputStream; -import java.io.PrintStream; -import java.sql.BatchUpdateException; -import java.sql.CallableStatement; -import java.sql.Connection; -import java.sql.DatabaseMetaData; -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.sql.Statement; - -import org.h2.test.TestBase; - -/** - * Test for batch updates. - */ -public class TestBatchUpdates extends TestBase { - - private static final String COFFEE_UPDATE = "UPDATE TEST SET PRICE=PRICE*20 WHERE TYPE_ID=?"; - private static final String COFFEE_SELECT = "SELECT PRICE FROM TEST WHERE KEY_ID=?"; - // private static final String COFFEE_QUERY = - // "SELECT C_NAME,PRICE FROM TEST WHERE TYPE_ID=?"; - // private static final String COFFEE_DELETE = - // "DELETE FROM TEST WHERE KEY_ID=?"; - private static final String COFFEE_INSERT1 = "INSERT INTO TEST VALUES(9,'COFFEE-9',9.0,5)"; - private static final String COFFEE_DELETE1 = "DELETE FROM TEST WHERE KEY_ID=9"; - private static final String COFFEE_UPDATE1 = "UPDATE TEST SET PRICE=PRICE*20 WHERE TYPE_ID=1"; - private static final String COFFEE_SELECT1 = "SELECT PRICE FROM TEST WHERE KEY_ID>4"; - private static final String COFFEE_UPDATE_SET = "UPDATE TEST SET KEY_ID=?, C_NAME=? WHERE C_NAME=?"; - private static final String COFFEE_SELECT_CONTINUED = "SELECT COUNT(*) FROM TEST WHERE C_NAME='Continue-1'"; - - private int coffeeSize = 10; - private int coffeeType = 11; - private Connection conn; - private Statement stat; - private PreparedStatement prep; - - /** - * Run just this test. - * - * @param a ignored - */ - public static void main(String... a) throws Exception { - TestBase.createCaller().init().test(); - } - - public void test() throws SQLException { - testExecuteCall(); - testException(); - testCoffee(); - deleteDb("batchUpdates"); - } - - private void testExecuteCall() throws SQLException { - deleteDb("batchUpdates"); - conn = getConnection("batchUpdates"); - stat = conn.createStatement(); - stat.execute("CREATE ALIAS updatePrices FOR \"" + getClass().getName() + ".updatePrices\""); - CallableStatement call = conn.prepareCall("{call updatePrices(?, ?)}"); - call.setString(1, "Hello"); - call.setFloat(2, 1.4f); - call.addBatch(); - call.setString(1, "World"); - call.setFloat(2, 3.2f); - call.addBatch(); - int[] updateCounts = call.executeBatch(); - int total = 0; - for (int t : updateCounts) { - total += t; - } - assertEquals(4, total); - conn.close(); - } - - /** - * This method is called by the database. - * - * @param message the message (currently not used) - * @param f the float - * @return the float converted to an int - */ - public static int updatePrices(String message, double f) { - return (int) f; - } - - private void testException() throws SQLException { - deleteDb("batchUpdates"); - conn = getConnection("batchUpdates"); - stat = conn.createStatement(); - stat.execute("create table test(id int primary key)"); - prep = conn.prepareStatement("insert into test values(?)"); - for (int i = 0; i < 700; i++) { - prep.setString(1, "x"); - prep.addBatch(); - } - try { - prep.executeBatch(); - } catch (BatchUpdateException e) { - PrintStream temp = System.err; - try { - ByteArrayOutputStream buff = new ByteArrayOutputStream(); - PrintStream p = new PrintStream(buff); - System.setErr(p); - e.printStackTrace(); - } finally { - System.setErr(temp); - } - } - conn.close(); - } - - private void testCoffee() throws SQLException { - deleteDb("batchUpdates"); - conn = getConnection("batchUpdates"); - stat = conn.createStatement(); - DatabaseMetaData meta = conn.getMetaData(); - if (!meta.supportsBatchUpdates()) { - fail("does not support BatchUpdates"); - } - stat.executeUpdate("CREATE TABLE TEST(KEY_ID INT PRIMARY KEY," - + "C_NAME VARCHAR(255),PRICE DECIMAL(20,2),TYPE_ID INT)"); - String newName = null; - float newPrice = 0; - int newType = 0; - prep = conn.prepareStatement("INSERT INTO TEST VALUES(?,?,?,?)"); - int newKey = 1; - for (int i = 1; i <= coffeeType && newKey <= coffeeSize; i++) { - for (int j = 1; j <= i && newKey <= coffeeSize; j++) { - newName = "COFFEE-" + newKey; - newPrice = newKey + (float) .00; - newType = i; - prep.setInt(1, newKey); - prep.setString(2, newName); - prep.setFloat(3, newPrice); - prep.setInt(4, newType); - prep.execute(); - newKey = newKey + 1; - } - } - trace("Inserted the Rows "); - testAddBatch01(); - testAddBatch02(); - testClearBatch01(); - testClearBatch02(); - testExecuteBatch01(); - testExecuteBatch02(); - testExecuteBatch03(); - testExecuteBatch04(); - testExecuteBatch05(); - testExecuteBatch06(); - testExecuteBatch07(); - testContinueBatch01(); - - conn.close(); - } - - private void testAddBatch01() throws SQLException { - trace("testAddBatch01"); - int i = 0; - int[] retValue = { 0, 0, 0 }; - String s = COFFEE_UPDATE; - trace("Prepared Statement String:" + s); - prep = conn.prepareStatement(s); - prep.setInt(1, 2); - prep.addBatch(); - prep.setInt(1, 3); - prep.addBatch(); - prep.setInt(1, 4); - prep.addBatch(); - int[] updateCount = prep.executeBatch(); - int updateCountLen = updateCount.length; - - // PreparedStatement p; - // p = conn.prepareStatement(COFFEE_UPDATE); - // p.setInt(1,2); - // System.out.println("upc="+p.executeUpdate()); - // p.setInt(1,3); - // System.out.println("upc="+p.executeUpdate()); - // p.setInt(1,4); - // System.out.println("upc="+p.executeUpdate()); - - trace("updateCount length:" + updateCountLen); - if (updateCountLen != 3) { - fail("updateCount: " + updateCountLen); - } else { - trace("addBatch add the SQL statements to Batch "); - } - String query1 = "SELECT COUNT(*) FROM TEST WHERE TYPE_ID=2"; - String query2 = "SELECT COUNT(*) FROM TEST WHERE TYPE_ID=3"; - String query3 = "SELECT COUNT(*) FROM TEST WHERE TYPE_ID=4"; - ResultSet rs = stat.executeQuery(query1); - rs.next(); - retValue[i++] = rs.getInt(1); - rs = stat.executeQuery(query2); - rs.next(); - retValue[i++] = rs.getInt(1); - rs = stat.executeQuery(query3); - rs.next(); - retValue[i++] = rs.getInt(1); - for (int j = 0; j < updateCount.length; j++) { - trace("UpdateCount:" + updateCount[j]); - assertEquals(updateCount[j], retValue[j]); - } - } - - private void testAddBatch02() throws SQLException { - trace("testAddBatch02"); - int i = 0; - int[] retValue = { 0, 0, 0 }; - int updCountLength = 0; - String sUpdCoffee = COFFEE_UPDATE1; - String sDelCoffee = COFFEE_DELETE1; - String sInsCoffee = COFFEE_INSERT1; - stat.addBatch(sUpdCoffee); - stat.addBatch(sDelCoffee); - stat.addBatch(sInsCoffee); - int[] updateCount = stat.executeBatch(); - updCountLength = updateCount.length; - trace("updateCount Length:" + updCountLength); - if (updCountLength != 3) { - fail("addBatch " + updCountLength); - } else { - trace("addBatch add the SQL statements to Batch "); - } - String query1 = "SELECT COUNT(*) FROM TEST WHERE TYPE_ID=1"; - ResultSet rs = stat.executeQuery(query1); - rs.next(); - retValue[i++] = rs.getInt(1); - // 1 as delete Statement will delete only one row - retValue[i++] = 1; - // 1 as insert Statement will insert only one row - retValue[i++] = 1; - trace("ReturnValue count : " + retValue.length); - for (int j = 0; j < updateCount.length; j++) { - trace("Update Count:" + updateCount[j]); - trace("Returned Value : " + retValue[j]); - if (updateCount[j] != retValue[j]) { - fail("j=" + j + " right:" + retValue[j]); - } - } - } - - private void testClearBatch01() throws SQLException { - trace("testClearBatch01"); - String sPrepStmt = COFFEE_UPDATE; - trace("Prepared Statement String:" + sPrepStmt); - prep = conn.prepareStatement(sPrepStmt); - prep.setInt(1, 2); - prep.addBatch(); - prep.setInt(1, 3); - prep.addBatch(); - prep.setInt(1, 4); - prep.addBatch(); - prep.clearBatch(); - int[] updateCount = prep.executeBatch(); - int updCountLength = updateCount.length; - if (updCountLength == 0) { - trace("clearBatch Method clears the current Batch "); - } else { - fail("clearBatch " + updCountLength); - } - } - - private void testClearBatch02() throws SQLException { - trace("testClearBatch02"); - int updCountLength = 0; - String sUpdCoffee = COFFEE_UPDATE1; - String sInsCoffee = COFFEE_INSERT1; - String sDelCoffee = COFFEE_DELETE1; - stat.addBatch(sUpdCoffee); - stat.addBatch(sDelCoffee); - stat.addBatch(sInsCoffee); - stat.clearBatch(); - int[] updateCount = stat.executeBatch(); - updCountLength = updateCount.length; - trace("updateCount Length:" + updCountLength); - if (updCountLength == 0) { - trace("clearBatch Method clears the current Batch "); - } else { - fail("clearBatch"); - } - } - - private void testExecuteBatch01() throws SQLException { - trace("testExecuteBatch01"); - int i = 0; - int[] retValue = { 0, 0, 0 }; - int updCountLength = 0; - String sPrepStmt = COFFEE_UPDATE; - trace("Prepared Statement String:" + sPrepStmt); - // get the PreparedStatement object - prep = conn.prepareStatement(sPrepStmt); - prep.setInt(1, 1); - prep.addBatch(); - prep.setInt(1, 2); - prep.addBatch(); - prep.setInt(1, 3); - prep.addBatch(); - int[] updateCount = prep.executeBatch(); - updCountLength = updateCount.length; - trace("Successfully Updated"); - trace("updateCount Length:" + updCountLength); - if (updCountLength != 3) { - fail("executeBatch"); - } else { - trace("executeBatch executes the Batch of SQL statements"); - } - // 1 is the number that is set First for Type Id in Prepared Statement - String query1 = "SELECT COUNT(*) FROM TEST WHERE TYPE_ID=1"; - // 2 is the number that is set second for Type id in Prepared Statement - String query2 = "SELECT COUNT(*) FROM TEST WHERE TYPE_ID=2"; - // 3 is the number that is set Third for Type id in Prepared Statement - String query3 = "SELECT COUNT(*) FROM TEST WHERE TYPE_ID=3"; - ResultSet rs = stat.executeQuery(query1); - rs.next(); - retValue[i++] = rs.getInt(1); - rs = stat.executeQuery(query2); - rs.next(); - retValue[i++] = rs.getInt(1); - rs = stat.executeQuery(query3); - rs.next(); - retValue[i++] = rs.getInt(1); - trace("retValue length : " + retValue.length); - for (int j = 0; j < updateCount.length; j++) { - trace("UpdateCount Value:" + updateCount[j]); - trace("RetValue : " + retValue[j]); - if (updateCount[j] != retValue[j]) { - fail("j=" + j + " right:" + retValue[j]); - } - } - } - - private void testExecuteBatch02() throws SQLException { - trace("testExecuteBatch02"); - String sPrepStmt = COFFEE_UPDATE; - trace("Prepared Statement String:" + sPrepStmt); - prep = conn.prepareStatement(sPrepStmt); - prep.setInt(1, 1); - prep.setInt(1, 2); - prep.setInt(1, 3); - int[] updateCount = prep.executeBatch(); - int updCountLength = updateCount.length; - trace("UpdateCount Length : " + updCountLength); - if (updCountLength == 0) { - trace("executeBatch does not execute Empty Batch"); - } else { - fail("executeBatch"); - } - } - - private void testExecuteBatch03() throws SQLException { - trace("testExecuteBatch03"); - boolean batchExceptionFlag = false; - String sPrepStmt = COFFEE_SELECT; - trace("Prepared Statement String :" + sPrepStmt); - prep = conn.prepareStatement(sPrepStmt); - prep.setInt(1, 1); - prep.addBatch(); - try { - int[] updateCount = prep.executeBatch(); - trace("Update Count" + updateCount.length); - } catch (BatchUpdateException b) { - batchExceptionFlag = true; - } - if (batchExceptionFlag) { - trace("select not allowed; correct"); - } else { - fail("executeBatch select"); - } - } - - private void testExecuteBatch04() throws SQLException { - trace("testExecuteBatch04"); - int i = 0; - int[] retValue = { 0, 0, 0 }; - int updCountLength = 0; - String sUpdCoffee = COFFEE_UPDATE1; - String sInsCoffee = COFFEE_INSERT1; - String sDelCoffee = COFFEE_DELETE1; - stat.addBatch(sUpdCoffee); - stat.addBatch(sDelCoffee); - stat.addBatch(sInsCoffee); - int[] updateCount = stat.executeBatch(); - updCountLength = updateCount.length; - trace("Successfully Updated"); - trace("updateCount Length:" + updCountLength); - if (updCountLength != 3) { - fail("executeBatch"); - } else { - trace("executeBatch executes the Batch of SQL statements"); - } - String query1 = "SELECT COUNT(*) FROM TEST WHERE TYPE_ID=1"; - ResultSet rs = stat.executeQuery(query1); - rs.next(); - retValue[i++] = rs.getInt(1); - // 1 as Delete Statement will delete only one row - retValue[i++] = 1; - // 1 as Insert Statement will insert only one row - retValue[i++] = 1; - for (int j = 0; j < updateCount.length; j++) { - trace("Update Count : " + updateCount[j]); - if (updateCount[j] != retValue[j]) { - fail("j=" + j + " right:" + retValue[j]); - } - } - } - - private void testExecuteBatch05() throws SQLException { - trace("testExecuteBatch05"); - int updCountLength = 0; - int[] updateCount = stat.executeBatch(); - updCountLength = updateCount.length; - trace("updateCount Length:" + updCountLength); - if (updCountLength == 0) { - trace("executeBatch Method does not execute the Empty Batch "); - } else { - fail("executeBatch 0!=" + updCountLength); - } - } - - private void testExecuteBatch06() throws SQLException { - trace("testExecuteBatch06"); - boolean batchExceptionFlag = false; - // Insert a row which is already Present - String sInsCoffee = COFFEE_INSERT1; - String sDelCoffee = COFFEE_DELETE1; - stat.addBatch(sInsCoffee); - stat.addBatch(sInsCoffee); - stat.addBatch(sDelCoffee); - try { - stat.executeBatch(); - } catch (BatchUpdateException b) { - batchExceptionFlag = true; - for (int uc : b.getUpdateCounts()) { - trace("Update counts:" + uc); - } - } - if (batchExceptionFlag) { - trace("executeBatch insert duplicate; correct"); - } else { - fail("executeBatch"); - } - } - - private void testExecuteBatch07() throws SQLException { - trace("testExecuteBatch07"); - boolean batchExceptionFlag = false; - String selectCoffee = COFFEE_SELECT1; - trace("selectCoffee = " + selectCoffee); - Statement stmt = conn.createStatement(); - stmt.addBatch(selectCoffee); - try { - int[] updateCount = stmt.executeBatch(); - trace("updateCount Length : " + updateCount.length); - } catch (BatchUpdateException be) { - batchExceptionFlag = true; - } - if (batchExceptionFlag) { - trace("executeBatch select"); - } else { - fail("executeBatch"); - } - } - - private void testContinueBatch01() throws SQLException { - trace("testContinueBatch01"); - int[] batchUpdates = { 0, 0, 0 }; - int buCountLen = 0; - try { - String sPrepStmt = COFFEE_UPDATE_SET; - trace("Prepared Statement String:" + sPrepStmt); - prep = conn.prepareStatement(sPrepStmt); - // Now add a legal update to the batch - prep.setInt(1, 1); - prep.setString(2, "Continue-1"); - prep.setString(3, "COFFEE-1"); - prep.addBatch(); - // Now add an illegal update to the batch by - // forcing a unique constraint violation - // Try changing the key_id of row 3 to 1. - prep.setInt(1, 1); - prep.setString(2, "Invalid"); - prep.setString(3, "COFFEE-3"); - prep.addBatch(); - // Now add a second legal update to the batch - // which will be processed ONLY if the driver supports - // continued batch processing according to 6.2.2.3 - // of the J2EE platform spec. - prep.setInt(1, 2); - prep.setString(2, "Continue-2"); - prep.setString(3, "COFFEE-2"); - prep.addBatch(); - // The executeBatch() method will result in a - // BatchUpdateException - prep.executeBatch(); - } catch (BatchUpdateException b) { - trace("expected BatchUpdateException"); - batchUpdates = b.getUpdateCounts(); - buCountLen = batchUpdates.length; - } - if (buCountLen == 1) { - trace("no continued updates - OK"); - return; - } else if (buCountLen == 3) { - trace("Driver supports continued updates."); - // Check to see if the third row from the batch was added - String query = COFFEE_SELECT_CONTINUED; - trace("Query is: " + query); - ResultSet rs = stat.executeQuery(query); - rs.next(); - int count = rs.getInt(1); - rs.close(); - stat.close(); - trace("Count val is: " + count); - // Make sure that we have the correct error code for - // the failed update. - if (!(batchUpdates[1] == -3 && count == 1)) { - fail("insert failed"); - } - } - } -} diff --git a/tools/h2/src/test/org/h2/test/jdbc/TestCallableStatement.java b/tools/h2/src/test/org/h2/test/jdbc/TestCallableStatement.java deleted file mode 100755 index 30a1805..0000000 --- a/tools/h2/src/test/org/h2/test/jdbc/TestCallableStatement.java +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.test.jdbc; - -import java.sql.CallableStatement; -import java.sql.Connection; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.sql.Statement; - -import org.h2.test.TestBase; - -/** - * Tests for the CallableStatement class. - */ -public class TestCallableStatement extends TestBase { - - /** - * Run just this test. - * - * @param a ignored - */ - public static void main(String... a) throws Exception { - TestBase.createCaller().init().test(); - } - - public void test() throws SQLException { - deleteDb("callableStatement"); - Connection conn = getConnection("callableStatement"); - testPrepare(conn); - conn.close(); - deleteDb("callableStatement"); - } - - private void testPrepare(Connection conn) throws SQLException { - Statement stat = conn.createStatement(); - CallableStatement call; - ResultSet rs; - stat.execute("CREATE TABLE TEST(ID INT, NAME VARCHAR)"); - call = conn.prepareCall("INSERT INTO TEST VALUES(?, ?)"); - call.setInt(1, 1); - call.setString(2, "Hello"); - call.execute(); - call = conn.prepareCall("SELECT * FROM TEST", ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY); - rs = call.executeQuery(); - rs.next(); - assertEquals(1, rs.getInt(1)); - assertEquals("Hello", rs.getString(2)); - assertFalse(rs.next()); - call = conn.prepareCall("SELECT * FROM TEST", ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY, ResultSet.HOLD_CURSORS_OVER_COMMIT); - rs = call.executeQuery(); - rs.next(); - assertEquals(1, rs.getInt(1)); - assertEquals("Hello", rs.getString(2)); - assertFalse(rs.next()); - } - -} diff --git a/tools/h2/src/test/org/h2/test/jdbc/TestCancel.java b/tools/h2/src/test/org/h2/test/jdbc/TestCancel.java deleted file mode 100755 index 138c20d..0000000 --- a/tools/h2/src/test/org/h2/test/jdbc/TestCancel.java +++ /dev/null @@ -1,222 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.test.jdbc; - -import java.sql.Connection; -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.sql.Savepoint; -import java.sql.Statement; - -import org.h2.constant.ErrorCode; -import org.h2.constant.SysProperties; -import org.h2.test.TestBase; - -/** - * Tests Statement.cancel - */ -public class TestCancel extends TestBase { - - private static int lastVisited; - - /** - * Run just this test. - * - * @param a ignored - */ - public static void main(String... a) throws Exception { - TestBase.createCaller().init().test(); - } - - /** - * This thread cancels a statement after some time. - */ - static class CancelThread extends Thread { - private Statement cancel; - private int wait; - private volatile boolean stop; - - CancelThread(Statement cancel, int wait) { - this.cancel = cancel; - this.wait = wait; - } - - /** - * Stop the test now. - */ - public void stopNow() { - this.stop = true; - } - - public void run() { - while (!stop) { - try { - Thread.sleep(wait); - cancel.cancel(); - Thread.yield(); - } catch (SQLException e) { - // ignore errors on closed statements - } catch (Exception e) { - TestBase.logError("sleep", e); - } - } - } - } - - public void test() throws Exception { - testQueryTimeoutInTransaction(); - testReset(); - testMaxQueryTimeout(); - testQueryTimeout(); - testJdbcQueryTimeout(); - testCancelStatement(); - deleteDb("cancel"); - } - - private void testReset() throws SQLException { - deleteDb("cancel"); - Connection conn = getConnection("cancel"); - Statement stat = conn.createStatement(); - stat.execute("set query_timeout 1"); - try { - stat.execute("select count(*) from system_range(1, 1000000), system_range(1, 1000000)"); - fail(); - } catch (SQLException e) { - assertKnownException(e); - } - stat.execute("set query_timeout 0"); - stat.execute("select count(*) from system_range(1, 1000), system_range(1, 1000)"); - conn.close(); - } - - private void testQueryTimeoutInTransaction() throws SQLException { - deleteDb("cancel"); - Connection conn = getConnection("cancel"); - Statement stat = conn.createStatement(); - stat.execute("CREATE TABLE TEST(ID INT)"); - conn.setAutoCommit(false); - stat.execute("INSERT INTO TEST VALUES(1)"); - Savepoint sp = conn.setSavepoint(); - stat.execute("INSERT INTO TEST VALUES(2)"); - stat.setQueryTimeout(1); - conn.rollback(sp); - conn.commit(); - conn.close(); - } - - private void testJdbcQueryTimeout() throws SQLException { - deleteDb("cancel"); - Connection conn = getConnection("cancel"); - Statement stat = conn.createStatement(); - assertEquals(0, stat.getQueryTimeout()); - stat.setQueryTimeout(1); - assertEquals(1, stat.getQueryTimeout()); - Statement s2 = conn.createStatement(); - assertEquals(1, s2.getQueryTimeout()); - ResultSet rs = s2.executeQuery("SELECT VALUE FROM INFORMATION_SCHEMA.SETTINGS WHERE NAME = 'QUERY_TIMEOUT'"); - rs.next(); - assertEquals(1000, rs.getInt(1)); - try { - stat.executeQuery("SELECT MAX(RAND()) FROM SYSTEM_RANGE(1, 100000000)"); - fail(); - } catch (SQLException e) { - assertEquals(ErrorCode.STATEMENT_WAS_CANCELED, e.getErrorCode()); - } - stat.setQueryTimeout(0); - stat.execute("SET QUERY_TIMEOUT 1100"); - assertEquals(2, stat.getQueryTimeout()); - conn.close(); - } - - private void testQueryTimeout() throws SQLException { - deleteDb("cancel"); - Connection conn = getConnection("cancel"); - Statement stat = conn.createStatement(); - stat.execute("SET QUERY_TIMEOUT 10"); - try { - stat.executeQuery("SELECT MAX(RAND()) FROM SYSTEM_RANGE(1, 100000000)"); - fail(); - } catch (SQLException e) { - assertEquals(ErrorCode.STATEMENT_WAS_CANCELED, e.getErrorCode()); - } - conn.close(); - } - - private void testMaxQueryTimeout() throws SQLException { - deleteDb("cancel"); - int oldMax = SysProperties.getMaxQueryTimeout(); - try { - System.setProperty(SysProperties.H2_MAX_QUERY_TIMEOUT, "" + 10); - Connection conn = getConnection("cancel"); - Statement stat = conn.createStatement(); - try { - stat.executeQuery("SELECT MAX(RAND()) FROM SYSTEM_RANGE(1, 100000000)"); - fail(); - } catch (SQLException e) { - assertEquals(ErrorCode.STATEMENT_WAS_CANCELED, e.getErrorCode()); - } - conn.close(); - } finally { - System.setProperty("h2.maxQueryTimeout", "" + oldMax); - } - } - - /** - * This method is called via reflection from the database. - * - * @param x the value - * @return the value - */ - public static int visit(int x) { - lastVisited = x; - return x; - } - - private void testCancelStatement() throws Exception { - deleteDb("cancel"); - Connection conn = getConnection("cancel"); - Statement stat = conn.createStatement(); - stat.execute("DROP TABLE IF EXISTS TEST"); - stat.execute("CREATE ALIAS VISIT FOR \"" + getClass().getName() + ".visit\""); - stat.execute("CREATE MEMORY TABLE TEST(ID INT PRIMARY KEY, NAME VARCHAR(255))"); - PreparedStatement prep = conn.prepareStatement("INSERT INTO TEST VALUES(?, ?)"); - trace("insert"); - int len = getSize(10, 1000); - for (int i = 0; i < len; i++) { - prep.setInt(1, i); - // prep.setString(2, "Test Value "+i); - prep.setString(2, "hi"); - prep.execute(); - } - trace("inserted"); - // TODO test insert.. select - for (int i = 1;;) { - Statement query = conn.createStatement(); - CancelThread cancel = new CancelThread(query, i); - visit(0); - cancel.start(); - Thread.yield(); - try { - query.executeQuery( - "SELECT VISIT(ID), (SELECT SUM(X) FROM SYSTEM_RANGE(1, 10000) WHERE X<>ID) FROM TEST ORDER BY ID"); - } catch (SQLException e) { - assertKnownException(e); - // ignore canceled statements - } - cancel.stopNow(); - cancel.join(); - if (lastVisited == 0) { - i += 10; - } else { - break; - } - } - conn.close(); - } - -} diff --git a/tools/h2/src/test/org/h2/test/jdbc/TestDatabaseEventListener.java b/tools/h2/src/test/org/h2/test/jdbc/TestDatabaseEventListener.java deleted file mode 100755 index 1483cef..0000000 --- a/tools/h2/src/test/org/h2/test/jdbc/TestDatabaseEventListener.java +++ /dev/null @@ -1,245 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.test.jdbc; - -import java.sql.Connection; -import java.sql.DriverManager; -import java.sql.SQLException; -import java.sql.Statement; -import java.util.Properties; - -import org.h2.api.DatabaseEventListener; -import org.h2.test.TestBase; - -/** - * Tests the DatabaseEventListener interface. - */ -public class TestDatabaseEventListener extends TestBase implements DatabaseEventListener { - - private static boolean calledOpened, calledClosingDatabase, calledScan, calledCreateIndex; - - /** - * Run just this test. - * - * @param a ignored - */ - public static void main(String... a) throws Exception { - TestBase.createCaller().init().test(); - } - - public void test() throws SQLException { - testInit(); - testIndexRebuiltOnce(); - testIndexNotRebuilt(); - testCalled(); - testCloseLog0(false); - testCloseLog0(true); - deleteDb("databaseEventListener"); - } - - /** - * Initialize the database after opening. - */ - public static class Init implements DatabaseEventListener { - - private String databaseUrl; - - public void init(String url) { - databaseUrl = url; - } - - public void opened() { - try { - Connection conn = DriverManager.getConnection(databaseUrl, "sa", "sa"); - Statement stat = conn.createStatement(); - stat.execute("create table if not exists test(id int)"); - conn.close(); - } catch (SQLException e) { - throw new RuntimeException(e); - } - } - - public void closingDatabase() { - // nothing to do - } - - public void diskSpaceIsLow() { - // nothing to do - } - - public void exceptionThrown(SQLException e, String sql) { - // nothing to do - } - - public void setProgress(int state, String name, int x, int max) { - // nothing to do - } - - } - - private void testInit() throws SQLException { - if (config.networked || config.cipher != null || config.memory) { - return; - } - deleteDb("databaseEventListener"); - String url = getURL("databaseEventListener", true); - url += ";DATABASE_EVENT_LISTENER='"+ Init.class.getName() + "'"; - Connection conn = DriverManager.getConnection(url, "sa", "sa"); - Statement stat = conn.createStatement(); - stat.execute("select * from test"); - conn.close(); - } - - private void testIndexRebuiltOnce() throws SQLException { - if (config.memory) { - return; - } - deleteDb("databaseEventListener"); - String url = getURL("databaseEventListener", true); - String user = getUser(), password = getPassword(); - Properties p = new Properties(); - p.setProperty("user", user); - p.setProperty("password", password); - Connection conn; - Statement stat; - conn = DriverManager.getConnection(url, p); - stat = conn.createStatement(); - // the old.id index head is at position 0 - stat.execute("create table old(id identity) as select 1"); - // the test.id index head is at position 1 - stat.execute("create table test(id identity) as select 1"); - conn.close(); - conn = DriverManager.getConnection(url, p); - stat = conn.createStatement(); - // free up space at position 0 - stat.execute("drop table old"); - stat.execute("insert into test values(2)"); - stat.execute("checkpoint sync"); - stat.execute("shutdown immediately"); - try { - conn.close(); - } catch (SQLException e) { - assertKnownException(e); - } - // now the index should be re-built - conn = DriverManager.getConnection(url, p); - conn.close(); - calledCreateIndex = false; - p.put("DATABASE_EVENT_LISTENER", getClass().getName()); - conn = org.h2.Driver.load().connect(url, p); - conn.close(); - assertTrue(!calledCreateIndex); - } - - private void testIndexNotRebuilt() throws SQLException { - if (config.memory) { - return; - } - deleteDb("databaseEventListener"); - String url = getURL("databaseEventListener", true); - String user = getUser(), password = getPassword(); - Properties p = new Properties(); - p.setProperty("user", user); - p.setProperty("password", password); - Connection conn = DriverManager.getConnection(url, p); - Statement stat = conn.createStatement(); - // the old.id index head is at position 0 - stat.execute("create table old(id identity) as select 1"); - // the test.id index head is at position 1 - stat.execute("create table test(id identity) as select 1"); - conn.close(); - conn = DriverManager.getConnection(url, p); - stat = conn.createStatement(); - // free up space at position 0 - stat.execute("drop table old"); - // truncate, relocating to position 0 - stat.execute("truncate table test"); - stat.execute("insert into test select 1"); - conn.close(); - calledCreateIndex = false; - p.put("DATABASE_EVENT_LISTENER", getClass().getName()); - conn = org.h2.Driver.load().connect(url, p); - conn.close(); - assertTrue(!calledCreateIndex); - } - - private void testCloseLog0(boolean shutdown) throws SQLException { - if (config.memory) { - return; - } - deleteDb("databaseEventListener"); - String url = getURL("databaseEventListener", true); - String user = getUser(), password = getPassword(); - Properties p = new Properties(); - p.setProperty("user", user); - p.setProperty("password", password); - Connection conn = DriverManager.getConnection(url, p); - Statement stat = conn.createStatement(); - stat.execute("create table test(id int primary key, name varchar)"); - stat.execute("insert into test select x, space(1000) from system_range(1,1000)"); - if (shutdown) { - stat.execute("shutdown"); - } - conn.close(); - - calledOpened = false; - calledScan = false; - p.put("DATABASE_EVENT_LISTENER", getClass().getName()); - conn = org.h2.Driver.load().connect(url, p); - conn.close(); - if (calledOpened) { - assertTrue(!calledScan); - } - } - - private void testCalled() throws SQLException { - Properties p = new Properties(); - p.setProperty("user", "sa"); - p.setProperty("password", "sa"); - calledOpened = false; - calledClosingDatabase = false; - p.put("DATABASE_EVENT_LISTENER", getClass().getName()); - org.h2.Driver.load(); - String url = "jdbc:h2:mem:databaseEventListener"; - Connection conn = org.h2.Driver.load().connect(url, p); - conn.close(); - assertTrue(calledOpened); - assertTrue(calledClosingDatabase); - } - - public void closingDatabase() { - calledClosingDatabase = true; - } - - public void diskSpaceIsLow() { - // nothing to do - } - - public void exceptionThrown(SQLException e, String sql) { - // nothing to do - } - - public void init(String url) { - // nothing to do - } - - public void opened() { - calledOpened = true; - } - - public void setProgress(int state, String name, int x, int max) { - if (state == DatabaseEventListener.STATE_SCAN_FILE) { - calledScan = true; - } - if (state == DatabaseEventListener.STATE_CREATE_INDEX) { - if (!name.startsWith("SYS:")) { - calledCreateIndex = true; - } - } - } - -} diff --git a/tools/h2/src/test/org/h2/test/jdbc/TestDriver.java b/tools/h2/src/test/org/h2/test/jdbc/TestDriver.java deleted file mode 100755 index bca5d48..0000000 --- a/tools/h2/src/test/org/h2/test/jdbc/TestDriver.java +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.test.jdbc; - -import java.sql.DriverManager; -import java.sql.SQLException; - -import org.h2.Driver; -import org.h2.test.TestBase; - -/** - * Tests the database driver. - */ -public class TestDriver extends TestBase { - - /** - * Run just this test. - * - * @param a ignored - */ - public static void main(String... a) throws Exception { - TestBase.createCaller().init().test(); - } - - public void test() throws Exception { - Driver instance = Driver.load(); - assertTrue(DriverManager.getDriver("jdbc:h2:~/test") == instance); - Driver.unload(); - try { - java.sql.Driver d = DriverManager.getDriver("jdbc:h2:~/test"); - fail(d.toString()); - } catch (SQLException e) { - // ignore - } - Driver.load(); - assertTrue(DriverManager.getDriver("jdbc:h2:~/test") == instance); - } - -} diff --git a/tools/h2/src/test/org/h2/test/jdbc/TestManyJdbcObjects.java b/tools/h2/src/test/org/h2/test/jdbc/TestManyJdbcObjects.java deleted file mode 100755 index afe1ea9..0000000 --- a/tools/h2/src/test/org/h2/test/jdbc/TestManyJdbcObjects.java +++ /dev/null @@ -1,121 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.test.jdbc; - -import java.sql.Connection; -import java.sql.DatabaseMetaData; -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.sql.Statement; - -import org.h2.constant.SysProperties; -import org.h2.test.TestBase; - -/** - * Tests the server by creating many JDBC objects (result sets and so on). - */ -public class TestManyJdbcObjects extends TestBase { - - /** - * Run just this test. - * - * @param a ignored - */ - public static void main(String... a) throws Exception { - TestBase.createCaller().init().test(); - } - - public void test() throws SQLException { - testNestedResultSets(); - testManyConnections(); - testOneConnectionPrepare(); - deleteDb("manyObjects"); - } - - private void testNestedResultSets() throws SQLException { - if (!config.networked) { - return; - } - deleteDb("manyObjects"); - Connection conn = getConnection("manyObjects"); - DatabaseMetaData meta = conn.getMetaData(); - ResultSet rsTables = meta.getColumns(null, null, null, null); - while (rsTables.next()) { - meta.getExportedKeys(null, null, null); - meta.getImportedKeys(null, null, null); - } - conn.close(); - } - - private void testManyConnections() throws SQLException { - if (!config.networked || config.memory) { - return; - } - // SERVER_CACHED_OBJECTS = 1000: connections = 20 (1250) - // SERVER_CACHED_OBJECTS = 500: connections = 40 - // SERVER_CACHED_OBJECTS = 50: connections = 120 - deleteDb("manyObjects"); - SysProperties.runFinalize = false; - int connCount = getSize(4, 40); - Connection[] conn = new Connection[connCount]; - for (int i = 0; i < connCount; i++) { - conn[i] = getConnection("manyObjects"); - } - int len = getSize(50, 500); - for (int j = 0; j < len; j++) { - if ((j % 10) == 0) { - trace("j=" + j); - } - for (int i = 0; i < connCount; i++) { - conn[i].getMetaData().getSchemas().close(); - } - } - for (int i = 0; i < connCount; i++) { - conn[i].close(); - } - SysProperties.runFinalize = true; - } - - private void testOneConnectionPrepare() throws SQLException { - deleteDb("manyObjects"); - SysProperties.runFinalize = false; - Connection conn = getConnection("manyObjects"); - PreparedStatement prep; - Statement stat; - int size = getSize(10, 1000); - for (int i = 0; i < size; i++) { - conn.getMetaData(); - } - for (int i = 0; i < size; i++) { - conn.createStatement(); - } - stat = conn.createStatement(); - stat.execute("CREATE TABLE TEST(ID INT PRIMARY KEY, NAME VARCHAR)"); - stat.execute("INSERT INTO TEST VALUES(1, 'Hello')"); - for (int i = 0; i < size; i++) { - stat.executeQuery("SELECT * FROM TEST WHERE 1=0"); - } - for (int i = 0; i < size; i++) { - stat.executeQuery("SELECT * FROM TEST"); - } - for (int i = 0; i < size; i++) { - conn.prepareStatement("SELECT * FROM TEST"); - } - prep = conn.prepareStatement("SELECT * FROM TEST WHERE 1=0"); - for (int i = 0; i < size; i++) { - prep.executeQuery(); - } - prep = conn.prepareStatement("SELECT * FROM TEST"); - for (int i = 0; i < size; i++) { - prep.executeQuery(); - } - SysProperties.runFinalize = true; - conn.close(); - } - -} diff --git a/tools/h2/src/test/org/h2/test/jdbc/TestMetaData.java b/tools/h2/src/test/org/h2/test/jdbc/TestMetaData.java deleted file mode 100755 index 2674465..0000000 --- a/tools/h2/src/test/org/h2/test/jdbc/TestMetaData.java +++ /dev/null @@ -1,874 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.test.jdbc; - -import java.sql.Connection; -import java.sql.DatabaseMetaData; -import java.sql.Driver; -import java.sql.ResultSet; -import java.sql.ResultSetMetaData; -import java.sql.SQLException; -import java.sql.Statement; -import java.sql.Types; - -import org.h2.constant.SysProperties; -import org.h2.engine.Constants; -import org.h2.test.TestBase; -import org.h2.value.DataType; - -/** - * Test for the DatabaseMetaData implementation. - */ -public class TestMetaData extends TestBase { - - private Connection conn; - private DatabaseMetaData meta; - private Statement stat; - private String catalog = "METADATA"; - - /** - * Run just this test. - * - * @param a ignored - */ - public static void main(String... a) throws Exception { - TestBase.createCaller().init().test(); - } - - public void test() throws SQLException { - deleteDb("metaData"); - - testTempTable(); - - conn = getConnection("metaData"); - - testColumnLobMeta(); - testColumnMetaData(); - testColumnPrecision(); - testColumnDefault(); - testCrossReferences(); - testProcedureColumns(); - - stat = conn.createStatement(); - meta = conn.getMetaData(); - testStatic(); - // TODO test remaining meta data - - stat.execute("CREATE TABLE TEST(ID INT PRIMARY KEY, NAME VARCHAR(255))"); - stat.execute("CREATE INDEX IDXNAME ON TEST(NAME)"); - - ResultSet rs; - - rs = meta.getCatalogs(); - rs.next(); - assertEquals(catalog, rs.getString(1)); - assertFalse(rs.next()); - - rs = meta.getSchemas(); - rs.next(); - assertEquals("INFORMATION_SCHEMA", rs.getString("TABLE_SCHEM")); - rs.next(); - assertEquals("PUBLIC", rs.getString("TABLE_SCHEM")); - assertFalse(rs.next()); - - rs = meta.getTableTypes(); - rs.next(); - assertEquals("SYSTEM TABLE", rs.getString("TABLE_TYPE")); - rs.next(); - assertEquals("TABLE", rs.getString("TABLE_TYPE")); - rs.next(); - assertEquals("TABLE LINK", rs.getString("TABLE_TYPE")); - rs.next(); - assertEquals("VIEW", rs.getString("TABLE_TYPE")); - assertFalse(rs.next()); - - rs = meta.getTables(null, Constants.SCHEMA_MAIN, null, new String[] { "TABLE" }); - assertTrue(rs.getStatement() == null); - rs.next(); - assertEquals("TEST", rs.getString("TABLE_NAME")); - assertFalse(rs.next()); - - rs = meta.getTables(null, "INFORMATION_SCHEMA", null, new String[] { "TABLE", "SYSTEM TABLE" }); - rs.next(); - assertEquals("CATALOGS", rs.getString("TABLE_NAME")); - rs.next(); - assertEquals("COLLATIONS", rs.getString("TABLE_NAME")); - rs.next(); - assertEquals("COLUMNS", rs.getString("TABLE_NAME")); - rs.next(); - assertEquals("COLUMN_PRIVILEGES", rs.getString("TABLE_NAME")); - rs.next(); - assertEquals("CONSTANTS", rs.getString("TABLE_NAME")); - rs.next(); - assertEquals("CONSTRAINTS", rs.getString("TABLE_NAME")); - rs.next(); - assertEquals("CROSS_REFERENCES", rs.getString("TABLE_NAME")); - rs.next(); - assertEquals("DOMAINS", rs.getString("TABLE_NAME")); - rs.next(); - assertEquals("FUNCTION_ALIASES", rs.getString("TABLE_NAME")); - rs.next(); - assertEquals("FUNCTION_COLUMNS", rs.getString("TABLE_NAME")); - rs.next(); - assertEquals("HELP", rs.getString("TABLE_NAME")); - rs.next(); - assertEquals("INDEXES", rs.getString("TABLE_NAME")); - rs.next(); - assertEquals("IN_DOUBT", rs.getString("TABLE_NAME")); - rs.next(); - assertEquals("LOCKS", rs.getString("TABLE_NAME")); - rs.next(); - assertEquals("RIGHTS", rs.getString("TABLE_NAME")); - rs.next(); - assertEquals("ROLES", rs.getString("TABLE_NAME")); - rs.next(); - assertEquals("SCHEMATA", rs.getString("TABLE_NAME")); - rs.next(); - assertEquals("SEQUENCES", rs.getString("TABLE_NAME")); - rs.next(); - assertEquals("SESSIONS", rs.getString("TABLE_NAME")); - rs.next(); - assertEquals("SESSION_STATE", rs.getString("TABLE_NAME")); - rs.next(); - assertEquals("SETTINGS", rs.getString("TABLE_NAME")); - rs.next(); - assertEquals("TABLES", rs.getString("TABLE_NAME")); - rs.next(); - assertEquals("TABLE_PRIVILEGES", rs.getString("TABLE_NAME")); - rs.next(); - assertEquals("TABLE_TYPES", rs.getString("TABLE_NAME")); - rs.next(); - assertEquals("TRIGGERS", rs.getString("TABLE_NAME")); - rs.next(); - assertEquals("TYPE_INFO", rs.getString("TABLE_NAME")); - rs.next(); - assertEquals("USERS", rs.getString("TABLE_NAME")); - rs.next(); - assertEquals("VIEWS", rs.getString("TABLE_NAME")); - assertFalse(rs.next()); - - rs = meta.getColumns(null, null, "TEST", null); - rs.next(); - assertEquals("ID", rs.getString("COLUMN_NAME")); - rs.next(); - assertEquals("NAME", rs.getString("COLUMN_NAME")); - assertFalse(rs.next()); - - rs = meta.getPrimaryKeys(null, null, "TEST"); - rs.next(); - assertEquals("ID", rs.getString("COLUMN_NAME")); - assertFalse(rs.next()); - - rs = meta.getBestRowIdentifier(null, null, "TEST", DatabaseMetaData.bestRowSession, false); - rs.next(); - assertEquals("ID", rs.getString("COLUMN_NAME")); - assertFalse(rs.next()); - - rs = meta.getIndexInfo(null, null, "TEST", false, false); - rs.next(); - String index = rs.getString("INDEX_NAME"); - assertTrue(index.startsWith("PRIMARY_KEY")); - assertEquals("ID", rs.getString("COLUMN_NAME")); - rs.next(); - assertEquals("IDXNAME", rs.getString("INDEX_NAME")); - assertEquals("NAME", rs.getString("COLUMN_NAME")); - assertFalse(rs.next()); - - rs = meta.getIndexInfo(null, null, "TEST", true, false); - rs.next(); - index = rs.getString("INDEX_NAME"); - assertTrue(index.startsWith("PRIMARY_KEY")); - assertEquals("ID", rs.getString("COLUMN_NAME")); - assertFalse(rs.next()); - - rs = meta.getVersionColumns(null, null, "TEST"); - assertFalse(rs.next()); - - stat.execute("DROP TABLE TEST"); - - rs = stat.executeQuery("SELECT * FROM INFORMATION_SCHEMA.SETTINGS"); - while (rs.next()) { - String name = rs.getString("NAME"); - String value = rs.getString("VALUE"); - trace(name + "=" + value); - } - - testMore(); - - // meta.getTablePrivileges() - - // meta.getAttributes() - // meta.getColumnPrivileges() - // meta.getSuperTables() - // meta.getSuperTypes() - // meta.getTypeInfo() - // meta.getUDTs() - - conn.close(); - - deleteDb("metaData"); - - } - - private void testColumnLobMeta() throws SQLException { - stat = conn.createStatement(); - stat.executeUpdate("CREATE TABLE t (blob BLOB, clob CLOB)"); - stat.execute("INSERT INTO t VALUES('', '')"); - ResultSet rs = stat.executeQuery("SELECT blob,clob FROM t"); - ResultSetMetaData rsMeta = rs.getMetaData(); - if (SysProperties.RETURN_LOB_OBJECTS) { - assertEquals("java.sql.Blob", rsMeta.getColumnClassName(1)); - assertEquals("java.sql.Clob", rsMeta.getColumnClassName(2)); - } else { - assertEquals("java.io.InputStream", rsMeta.getColumnClassName(1)); - assertEquals("java.io.Reader", rsMeta.getColumnClassName(2)); - } - rs.next(); - if (SysProperties.RETURN_LOB_OBJECTS) { - assertTrue(rs.getObject(1) instanceof java.sql.Blob); - assertTrue(rs.getObject(2) instanceof java.sql.Clob); - } else { - assertEquals("java.io.ByteArrayInputStream", rs.getObject(1).getClass().getName()); - assertEquals("java.io.BufferedReader", rs.getObject(2).getClass().getName()); - } - stat.executeUpdate("DROP TABLE t"); - } - - private void testColumnMetaData() throws SQLException { - String sql = "select substring('Hello',0,1)"; - ResultSet rs = conn.prepareStatement(sql).executeQuery(); - rs.next(); - int type = rs.getMetaData().getColumnType(1); - assertEquals(Types.VARCHAR, type); - rs = conn.createStatement().executeQuery("SELECT COUNT(*) C FROM DUAL"); - assertEquals("C", rs.getMetaData().getColumnName(1)); - - stat = conn.createStatement(); - stat.execute("create table a(x array)"); - stat.execute("insert into a values((1, 2))"); - rs = stat.executeQuery("SELECT x[1] FROM a"); - ResultSetMetaData rsMeta = rs.getMetaData(); - assertEquals(Types.VARCHAR, rsMeta.getColumnType(1)); - rs.next(); - // assertEquals(String.class.getName(), rs.getObject(1).getClass().getName()); - stat.execute("drop table a"); - } - - private void testColumnPrecision() throws SQLException { - stat = conn.createStatement(); - stat.execute("CREATE TABLE ONE(X NUMBER(12,2), Y FLOAT)"); - stat.execute("CREATE TABLE TWO AS SELECT * FROM ONE"); - ResultSet rs; - ResultSetMetaData rsMeta; - rs = stat.executeQuery("SELECT * FROM ONE"); - rsMeta = rs.getMetaData(); - assertEquals(12, rsMeta.getPrecision(1)); - assertEquals(17, rsMeta.getPrecision(2)); - assertEquals(Types.DECIMAL, rsMeta.getColumnType(1)); - assertEquals(Types.DOUBLE, rsMeta.getColumnType(2)); - rs = stat.executeQuery("SELECT * FROM TWO"); - rsMeta = rs.getMetaData(); - assertEquals(12, rsMeta.getPrecision(1)); - assertEquals(17, rsMeta.getPrecision(2)); - assertEquals(Types.DECIMAL, rsMeta.getColumnType(1)); - assertEquals(Types.DOUBLE, rsMeta.getColumnType(2)); - stat.execute("DROP TABLE ONE, TWO"); - } - - private void testColumnDefault() throws SQLException { - meta = conn.getMetaData(); - ResultSet rs; - stat = conn.createStatement(); - stat.execute("CREATE TABLE TEST(A INT, B INT DEFAULT NULL)"); - rs = meta.getColumns(null, null, "TEST", null); - rs.next(); - assertEquals("A", rs.getString("COLUMN_NAME")); - assertEquals(null, rs.getString("COLUMN_DEF")); - rs.next(); - assertEquals("B", rs.getString("COLUMN_NAME")); - assertEquals("NULL", rs.getString("COLUMN_DEF")); - assertFalse(rs.next()); - stat.execute("DROP TABLE TEST"); - } - - private void testProcedureColumns() throws SQLException { - meta = conn.getMetaData(); - ResultSet rs; - stat = conn.createStatement(); - stat.execute("CREATE ALIAS PROP FOR \"java.lang.System.getProperty(java.lang.String)\""); - stat.execute("CREATE ALIAS EXIT FOR \"java.lang.System.exit\""); - rs = meta.getProcedures(null, null, "EX%"); - assertResultSetMeta(rs, 9, new String[] { "PROCEDURE_CAT", "PROCEDURE_SCHEM", "PROCEDURE_NAME", - "NUM_INPUT_PARAMS", "NUM_OUTPUT_PARAMS", "NUM_RESULT_SETS", "REMARKS", "PROCEDURE_TYPE", - "SPECIFIC_NAME" - }, new int[] { - Types.VARCHAR, Types.VARCHAR, Types.VARCHAR, Types.INTEGER, Types.INTEGER, Types.INTEGER, - Types.VARCHAR, Types.SMALLINT, Types.VARCHAR }, null, null); - assertResultSetOrdered(rs, new String[][] { { catalog, Constants.SCHEMA_MAIN, "EXIT", "1", "0", "0", "", - "" + DatabaseMetaData.procedureNoResult } }); - rs = meta.getProcedureColumns(null, null, null, null); - assertResultSetMeta(rs, 20, - new String[] { "PROCEDURE_CAT", "PROCEDURE_SCHEM", "PROCEDURE_NAME", "COLUMN_NAME", "COLUMN_TYPE", - "DATA_TYPE", "TYPE_NAME", "PRECISION", "LENGTH", "SCALE", "RADIX", "NULLABLE", "REMARKS", - "COLUMN_DEF", "SQL_DATA_TYPE", "SQL_DATETIME_SUB", "CHAR_OCTET_LENGTH", "ORDINAL_POSITION", - "IS_NULLABLE", "SPECIFIC_NAME" }, - new int[] { Types.VARCHAR, Types.VARCHAR, Types.VARCHAR, Types.VARCHAR, Types.SMALLINT, Types.INTEGER, - Types.VARCHAR, Types.INTEGER, Types.INTEGER, Types.SMALLINT, Types.SMALLINT, Types.SMALLINT, Types.VARCHAR, - Types.VARCHAR, Types.INTEGER, Types.INTEGER, Types.INTEGER, Types.INTEGER, Types.VARCHAR, Types.VARCHAR}, null, null); - assertResultSetOrdered(rs, new String[][] { - { catalog, Constants.SCHEMA_MAIN, "EXIT", "P1", "" + DatabaseMetaData.procedureColumnIn, - "" + Types.INTEGER, "INTEGER", "10", "10", "0", "10", "" + DatabaseMetaData.procedureNoNulls }, - { catalog, Constants.SCHEMA_MAIN, "PROP", "P1", "" + DatabaseMetaData.procedureColumnIn, - "" + Types.VARCHAR, "VARCHAR", "" + Integer.MAX_VALUE, "" + Integer.MAX_VALUE, "0", "10", - "" + DatabaseMetaData.procedureNullable }, }); - stat.execute("DROP ALIAS EXIT"); - stat.execute("DROP ALIAS PROP"); - } - - private void testCrossReferences() throws SQLException { - meta = conn.getMetaData(); - ResultSet rs; - stat = conn.createStatement(); - stat.execute("CREATE TABLE PARENT(A INT, B INT, PRIMARY KEY(A, B))"); - stat.execute("CREATE TABLE CHILD(ID INT PRIMARY KEY, PA INT, PB INT, CONSTRAINT AB FOREIGN KEY(PA, PB) REFERENCES PARENT(A, B))"); - rs = meta.getCrossReference(null, "PUBLIC", "PARENT", null, "PUBLIC", "CHILD"); - checkCrossRef(rs); - rs = meta.getImportedKeys(null, "PUBLIC", "CHILD"); - checkCrossRef(rs); - rs = meta.getExportedKeys(null, "PUBLIC", "PARENT"); - checkCrossRef(rs); - stat.execute("DROP TABLE PARENT"); - stat.execute("DROP TABLE CHILD"); - } - - private void checkCrossRef(ResultSet rs) throws SQLException { - assertResultSetMeta(rs, 14, new String[] { "PKTABLE_CAT", "PKTABLE_SCHEM", "PKTABLE_NAME", "PKCOLUMN_NAME", - "FKTABLE_CAT", "FKTABLE_SCHEM", "FKTABLE_NAME", "FKCOLUMN_NAME", "KEY_SEQ", "UPDATE_RULE", - "DELETE_RULE", "FK_NAME", "PK_NAME", "DEFERRABILITY" }, new int[] { Types.VARCHAR, Types.VARCHAR, - Types.VARCHAR, Types.VARCHAR, Types.VARCHAR, Types.VARCHAR, Types.VARCHAR, Types.VARCHAR, - Types.SMALLINT, Types.SMALLINT, Types.SMALLINT, Types.VARCHAR, Types.VARCHAR, Types.SMALLINT }, null, - null); - assertResultSetOrdered(rs, new String[][] { - { catalog, Constants.SCHEMA_MAIN, "PARENT", "A", catalog, Constants.SCHEMA_MAIN, "CHILD", "PA", "1", - "" + DatabaseMetaData.importedKeyRestrict, "" + DatabaseMetaData.importedKeyRestrict, "AB", - null, "" + DatabaseMetaData.importedKeyNotDeferrable }, - { catalog, Constants.SCHEMA_MAIN, "PARENT", "B", catalog, Constants.SCHEMA_MAIN, "CHILD", "PB", "2", - "" + DatabaseMetaData.importedKeyRestrict, "" + DatabaseMetaData.importedKeyRestrict, "AB", - null, "" + DatabaseMetaData.importedKeyNotDeferrable } }); - } - - private void testTempTable() throws SQLException { - conn = getConnection("metaData"); - stat = conn.createStatement(); - stat.execute("DROP TABLE IF EXISTS TEST_TEMP"); - stat.execute("CREATE TEMP TABLE TEST_TEMP(ID INT PRIMARY KEY, NAME VARCHAR(255))"); - stat.execute("CREATE INDEX IDX_NAME ON TEST_TEMP(NAME)"); - stat.execute("ALTER TABLE TEST_TEMP ADD FOREIGN KEY(ID) REFERENCES(ID)"); - conn.close(); - - conn = getConnection("metaData"); - stat = conn.createStatement(); - stat.execute("CREATE TEMP TABLE TEST_TEMP(ID INT PRIMARY KEY, NAME VARCHAR(255))"); - ResultSet rs = stat.executeQuery("SELECT STORAGE_TYPE FROM " - + "INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME='TEST_TEMP'"); - rs.next(); - assertEquals("GLOBAL TEMPORARY", rs.getString("STORAGE_TYPE")); - stat.execute("DROP TABLE IF EXISTS TEST_TEMP"); - conn.close(); - } - - private void testStatic() throws SQLException { - Driver dr = org.h2.Driver.load(); - - assertEquals(dr.getMajorVersion(), meta.getDriverMajorVersion()); - assertEquals(dr.getMinorVersion(), meta.getDriverMinorVersion()); - assertTrue(dr.jdbcCompliant()); - - assertEquals(0, dr.getPropertyInfo(null, null).length); - assertTrue(dr.connect("jdbc:test:false", null) == null); - - assertTrue(meta.getNumericFunctions().length() > 0); - assertTrue(meta.getStringFunctions().length() > 0); - assertTrue(meta.getSystemFunctions().length() > 0); - assertTrue(meta.getTimeDateFunctions().length() > 0); - - assertTrue(meta.allProceduresAreCallable()); - assertTrue(meta.allTablesAreSelectable()); - assertTrue(meta.dataDefinitionCausesTransactionCommit()); - assertFalse(meta.dataDefinitionIgnoredInTransactions()); - assertFalse(meta.deletesAreDetected(ResultSet.TYPE_FORWARD_ONLY)); - assertFalse(meta.deletesAreDetected(ResultSet.TYPE_SCROLL_INSENSITIVE)); - assertFalse(meta.deletesAreDetected(ResultSet.TYPE_SCROLL_SENSITIVE)); - assertFalse(meta.doesMaxRowSizeIncludeBlobs()); - assertEquals(".", meta.getCatalogSeparator()); - assertEquals("catalog", meta.getCatalogTerm()); - assertTrue(meta.getConnection() == conn); - if (config.jdk14) { - String versionStart = meta.getDatabaseMajorVersion() + "." + meta.getDatabaseMinorVersion(); - assertTrue(meta.getDatabaseProductVersion().startsWith(versionStart)); - assertEquals(meta.getDatabaseMajorVersion(), meta.getDriverMajorVersion()); - assertEquals(meta.getDatabaseMinorVersion(), meta.getDriverMinorVersion()); - assertEquals(3, meta.getJDBCMajorVersion()); - assertEquals(0, meta.getJDBCMinorVersion()); - } - assertEquals("H2", meta.getDatabaseProductName()); - assertEquals(Connection.TRANSACTION_READ_COMMITTED, meta.getDefaultTransactionIsolation()); - assertEquals("H2 JDBC Driver", meta.getDriverName()); - - String versionStart = meta.getDriverMajorVersion() + "." + meta.getDriverMinorVersion(); - assertTrue(meta.getDriverVersion().startsWith(versionStart)); - assertEquals("", meta.getExtraNameCharacters()); - assertEquals("\"", meta.getIdentifierQuoteString()); - assertEquals(0, meta.getMaxBinaryLiteralLength()); - assertEquals(0, meta.getMaxCatalogNameLength()); - assertEquals(0, meta.getMaxCharLiteralLength()); - assertEquals(0, meta.getMaxColumnNameLength()); - assertEquals(0, meta.getMaxColumnsInGroupBy()); - assertEquals(0, meta.getMaxColumnsInIndex()); - assertEquals(0, meta.getMaxColumnsInOrderBy()); - assertEquals(0, meta.getMaxColumnsInSelect()); - assertEquals(0, meta.getMaxColumnsInTable()); - assertEquals(0, meta.getMaxConnections()); - assertEquals(0, meta.getMaxCursorNameLength()); - assertEquals(0, meta.getMaxIndexLength()); - assertEquals(0, meta.getMaxProcedureNameLength()); - assertEquals(0, meta.getMaxRowSize()); - assertEquals(0, meta.getMaxSchemaNameLength()); - assertEquals(0, meta.getMaxStatementLength()); - assertEquals(0, meta.getMaxStatements()); - assertEquals(0, meta.getMaxTableNameLength()); - assertEquals(0, meta.getMaxTablesInSelect()); - assertEquals(0, meta.getMaxUserNameLength()); - assertEquals("procedure", meta.getProcedureTerm()); - if (config.jdk14) { - assertEquals(ResultSet.CLOSE_CURSORS_AT_COMMIT, meta.getResultSetHoldability()); - assertEquals(DatabaseMetaData.sqlStateSQL99, meta.getSQLStateType()); - assertFalse(meta.locatorsUpdateCopy()); - } - assertEquals("schema", meta.getSchemaTerm()); - assertEquals("\\", meta.getSearchStringEscape()); - assertEquals("LIMIT,MINUS,ROWNUM,SYSDATE,SYSTIME,SYSTIMESTAMP,TODAY", meta.getSQLKeywords()); - - assertTrue(meta.getURL().startsWith("jdbc:h2:")); - assertTrue(meta.getUserName().length() > 1); - assertFalse(meta.insertsAreDetected(ResultSet.TYPE_FORWARD_ONLY)); - assertFalse(meta.insertsAreDetected(ResultSet.TYPE_SCROLL_INSENSITIVE)); - assertFalse(meta.insertsAreDetected(ResultSet.TYPE_SCROLL_SENSITIVE)); - assertTrue(meta.isCatalogAtStart()); - assertFalse(meta.isReadOnly()); - assertTrue(meta.nullPlusNonNullIsNull()); - assertFalse(meta.nullsAreSortedAtEnd()); - assertFalse(meta.nullsAreSortedAtStart()); - assertFalse(meta.nullsAreSortedHigh()); - assertTrue(meta.nullsAreSortedLow()); - assertFalse(meta.othersDeletesAreVisible(ResultSet.TYPE_FORWARD_ONLY)); - assertFalse(meta.othersDeletesAreVisible(ResultSet.TYPE_SCROLL_INSENSITIVE)); - assertFalse(meta.othersDeletesAreVisible(ResultSet.TYPE_SCROLL_SENSITIVE)); - assertFalse(meta.othersInsertsAreVisible(ResultSet.TYPE_FORWARD_ONLY)); - assertFalse(meta.othersInsertsAreVisible(ResultSet.TYPE_SCROLL_INSENSITIVE)); - assertFalse(meta.othersInsertsAreVisible(ResultSet.TYPE_SCROLL_SENSITIVE)); - assertFalse(meta.othersUpdatesAreVisible(ResultSet.TYPE_FORWARD_ONLY)); - assertFalse(meta.othersUpdatesAreVisible(ResultSet.TYPE_SCROLL_INSENSITIVE)); - assertFalse(meta.othersUpdatesAreVisible(ResultSet.TYPE_SCROLL_SENSITIVE)); - assertFalse(meta.ownDeletesAreVisible(ResultSet.TYPE_FORWARD_ONLY)); - assertFalse(meta.ownDeletesAreVisible(ResultSet.TYPE_SCROLL_INSENSITIVE)); - assertFalse(meta.ownDeletesAreVisible(ResultSet.TYPE_SCROLL_SENSITIVE)); - assertFalse(meta.ownInsertsAreVisible(ResultSet.TYPE_FORWARD_ONLY)); - assertFalse(meta.ownInsertsAreVisible(ResultSet.TYPE_SCROLL_INSENSITIVE)); - assertFalse(meta.ownInsertsAreVisible(ResultSet.TYPE_SCROLL_SENSITIVE)); - assertTrue(meta.ownUpdatesAreVisible(ResultSet.TYPE_FORWARD_ONLY)); - assertTrue(meta.ownUpdatesAreVisible(ResultSet.TYPE_SCROLL_INSENSITIVE)); - assertTrue(meta.ownUpdatesAreVisible(ResultSet.TYPE_SCROLL_SENSITIVE)); - assertFalse(meta.storesLowerCaseIdentifiers()); - assertFalse(meta.storesLowerCaseQuotedIdentifiers()); - assertFalse(meta.storesMixedCaseIdentifiers()); - assertTrue(meta.storesMixedCaseQuotedIdentifiers()); - assertTrue(meta.storesUpperCaseIdentifiers()); - assertFalse(meta.storesUpperCaseQuotedIdentifiers()); - assertTrue(meta.supportsAlterTableWithAddColumn()); - assertTrue(meta.supportsAlterTableWithDropColumn()); - assertTrue(meta.supportsANSI92EntryLevelSQL()); - assertFalse(meta.supportsANSI92IntermediateSQL()); - assertFalse(meta.supportsANSI92FullSQL()); - assertTrue(meta.supportsBatchUpdates()); - assertTrue(meta.supportsCatalogsInDataManipulation()); - assertTrue(meta.supportsCatalogsInIndexDefinitions()); - assertTrue(meta.supportsCatalogsInPrivilegeDefinitions()); - assertFalse(meta.supportsCatalogsInProcedureCalls()); - assertTrue(meta.supportsCatalogsInTableDefinitions()); - assertTrue(meta.supportsColumnAliasing()); - assertTrue(meta.supportsConvert()); - assertTrue(meta.supportsConvert(Types.INTEGER, Types.VARCHAR)); - assertTrue(meta.supportsCoreSQLGrammar()); - assertTrue(meta.supportsCorrelatedSubqueries()); - assertFalse(meta.supportsDataDefinitionAndDataManipulationTransactions()); - assertTrue(meta.supportsDataManipulationTransactionsOnly()); - assertFalse(meta.supportsDifferentTableCorrelationNames()); - assertTrue(meta.supportsExpressionsInOrderBy()); - assertFalse(meta.supportsExtendedSQLGrammar()); - assertFalse(meta.supportsFullOuterJoins()); - if (config.jdk14) { - assertTrue(meta.supportsGetGeneratedKeys()); - assertTrue(meta.supportsMultipleOpenResults()); - assertFalse(meta.supportsNamedParameters()); - } - assertTrue(meta.supportsGroupBy()); - assertTrue(meta.supportsGroupByBeyondSelect()); - assertTrue(meta.supportsGroupByUnrelated()); - assertTrue(meta.supportsIntegrityEnhancementFacility()); - assertTrue(meta.supportsLikeEscapeClause()); - assertTrue(meta.supportsLimitedOuterJoins()); - assertTrue(meta.supportsMinimumSQLGrammar()); - assertFalse(meta.supportsMixedCaseIdentifiers()); - assertTrue(meta.supportsMixedCaseQuotedIdentifiers()); - assertFalse(meta.supportsMultipleResultSets()); - assertTrue(meta.supportsMultipleTransactions()); - assertTrue(meta.supportsNonNullableColumns()); - assertFalse(meta.supportsOpenCursorsAcrossCommit()); - assertFalse(meta.supportsOpenCursorsAcrossRollback()); - assertTrue(meta.supportsOpenStatementsAcrossCommit()); - assertTrue(meta.supportsOpenStatementsAcrossRollback()); - assertTrue(meta.supportsOrderByUnrelated()); - assertTrue(meta.supportsOuterJoins()); - assertTrue(meta.supportsPositionedDelete()); - assertTrue(meta.supportsPositionedUpdate()); - assertTrue(meta.supportsResultSetConcurrency(ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY)); - assertTrue(meta.supportsResultSetConcurrency(ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_UPDATABLE)); - assertTrue(meta.supportsResultSetConcurrency(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY)); - assertTrue(meta.supportsResultSetConcurrency(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_UPDATABLE)); - assertFalse(meta.supportsResultSetConcurrency(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_READ_ONLY)); - assertFalse(meta.supportsResultSetConcurrency(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_UPDATABLE)); - if (config.jdk14) { - assertFalse(meta.supportsResultSetHoldability(ResultSet.HOLD_CURSORS_OVER_COMMIT)); - assertTrue(meta.supportsResultSetHoldability(ResultSet.CLOSE_CURSORS_AT_COMMIT)); - assertTrue(meta.supportsSavepoints()); - assertFalse(meta.supportsStatementPooling()); - } - assertTrue(meta.supportsResultSetType(ResultSet.TYPE_FORWARD_ONLY)); - assertTrue(meta.supportsResultSetType(ResultSet.TYPE_SCROLL_INSENSITIVE)); - assertFalse(meta.supportsResultSetType(ResultSet.TYPE_SCROLL_SENSITIVE)); - assertTrue(meta.supportsSchemasInDataManipulation()); - assertTrue(meta.supportsSchemasInIndexDefinitions()); - assertTrue(meta.supportsSchemasInPrivilegeDefinitions()); - assertTrue(meta.supportsSchemasInProcedureCalls()); - assertTrue(meta.supportsSchemasInTableDefinitions()); - assertTrue(meta.supportsSelectForUpdate()); - assertFalse(meta.supportsStoredProcedures()); - assertTrue(meta.supportsSubqueriesInComparisons()); - assertTrue(meta.supportsSubqueriesInExists()); - assertTrue(meta.supportsSubqueriesInIns()); - assertTrue(meta.supportsSubqueriesInQuantifieds()); - assertTrue(meta.supportsTableCorrelationNames()); - assertTrue(meta.supportsTransactions()); - assertTrue(meta.supportsTransactionIsolationLevel(Connection.TRANSACTION_NONE)); - assertTrue(meta.supportsTransactionIsolationLevel(Connection.TRANSACTION_READ_COMMITTED)); - assertTrue(meta.supportsTransactionIsolationLevel(Connection.TRANSACTION_READ_UNCOMMITTED)); - assertTrue(meta.supportsTransactionIsolationLevel(Connection.TRANSACTION_REPEATABLE_READ)); - assertTrue(meta.supportsTransactionIsolationLevel(Connection.TRANSACTION_SERIALIZABLE)); - assertTrue(meta.supportsUnion()); - assertTrue(meta.supportsUnionAll()); - assertFalse(meta.updatesAreDetected(ResultSet.TYPE_FORWARD_ONLY)); - assertFalse(meta.updatesAreDetected(ResultSet.TYPE_SCROLL_INSENSITIVE)); - assertFalse(meta.updatesAreDetected(ResultSet.TYPE_SCROLL_SENSITIVE)); - assertFalse(meta.usesLocalFilePerTable()); - assertTrue(meta.usesLocalFiles()); - } - - private void testMore() throws SQLException { - meta = conn.getMetaData(); - stat = conn.createStatement(); - ResultSet rs; - - conn.setReadOnly(true); - conn.setReadOnly(false); - assertFalse(conn.isReadOnly()); - assertTrue(conn.isReadOnly() == meta.isReadOnly()); - - assertTrue(conn == meta.getConnection()); - - // currently, setCatalog is ignored - conn.setCatalog("XYZ"); - trace(conn.getCatalog()); - - String product = meta.getDatabaseProductName(); - trace("meta.getDatabaseProductName:" + product); - - String version = meta.getDatabaseProductVersion(); - trace("meta.getDatabaseProductVersion:" + version); - - int major = meta.getDriverMajorVersion(); - trace("meta.getDriverMajorVersion:" + major); - - int minor = meta.getDriverMinorVersion(); - trace("meta.getDriverMinorVersion:" + minor); - - String driverName = meta.getDriverName(); - trace("meta.getDriverName:" + driverName); - - String driverVersion = meta.getDriverVersion(); - trace("meta.getDriverVersion:" + driverVersion); - - meta.getSearchStringEscape(); - - String url = meta.getURL(); - trace("meta.getURL:" + url); - - String user = meta.getUserName(); - trace("meta.getUserName:" + user); - - trace("meta.nullsAreSortedHigh:" + meta.nullsAreSortedHigh()); - trace("meta.nullsAreSortedLow:" + meta.nullsAreSortedLow()); - trace("meta.nullsAreSortedAtStart:" + meta.nullsAreSortedAtStart()); - trace("meta.nullsAreSortedAtEnd:" + meta.nullsAreSortedAtEnd()); - int count = (meta.nullsAreSortedHigh() ? 1 : 0) + (meta.nullsAreSortedLow() ? 1 : 0) - + (meta.nullsAreSortedAtStart() ? 1 : 0) + (meta.nullsAreSortedAtEnd() ? 1 : 0); - assertTrue(count == 1); - - trace("meta.allProceduresAreCallable:" + meta.allProceduresAreCallable()); - assertTrue(meta.allProceduresAreCallable()); - - trace("meta.allTablesAreSelectable:" + meta.allTablesAreSelectable()); - assertTrue(meta.allTablesAreSelectable()); - - trace("getTables"); - rs = meta.getTables(null, Constants.SCHEMA_MAIN, null, new String[] { "TABLE" }); - assertResultSetMeta(rs, 11, new String[] { "TABLE_CAT", "TABLE_SCHEM", "TABLE_NAME", "TABLE_TYPE", "REMARKS", - "TYPE_CAT", "TYPE_SCHEM", "TYPE_NAME", "SELF_REFERENCING_COL_NAME", "REF_GENERATION", "SQL" }, - new int[] { Types.VARCHAR, Types.VARCHAR, Types.VARCHAR, Types.VARCHAR, Types.VARCHAR, - Types.VARCHAR, Types.VARCHAR, Types.VARCHAR, Types.VARCHAR, Types.VARCHAR, Types.VARCHAR }, null, null); - if (rs.next()) { - fail("Database is not empty after dropping all tables"); - } - stat.executeUpdate("CREATE TABLE TEST(" + "ID INT PRIMARY KEY," + "TEXT_V VARCHAR(120)," - + "DEC_V DECIMAL(12,3)," + "DATE_V DATETIME," + "BLOB_V BLOB," + "CLOB_V CLOB" + ")"); - rs = meta.getTables(null, Constants.SCHEMA_MAIN, null, new String[] { "TABLE" }); - assertResultSetOrdered(rs, new String[][] { { catalog, Constants.SCHEMA_MAIN, "TEST", "TABLE", "" } }); - trace("getColumns"); - rs = meta.getColumns(null, null, "TEST", null); - assertResultSetMeta(rs, 23, new String[] { "TABLE_CAT", "TABLE_SCHEM", "TABLE_NAME", "COLUMN_NAME", "DATA_TYPE", - "TYPE_NAME", "COLUMN_SIZE", "BUFFER_LENGTH", "DECIMAL_DIGITS", "NUM_PREC_RADIX", "NULLABLE", "REMARKS", - "COLUMN_DEF", "SQL_DATA_TYPE", "SQL_DATETIME_SUB", "CHAR_OCTET_LENGTH", "ORDINAL_POSITION", - "IS_NULLABLE", "SCOPE_CATALOG", "SCOPE_SCHEMA", "SCOPE_TABLE", "SOURCE_DATA_TYPE", "IS_AUTOINCREMENT" }, - new int[] { Types.VARCHAR, Types.VARCHAR, Types.VARCHAR, Types.VARCHAR, - Types.INTEGER, Types.VARCHAR, Types.INTEGER, Types.INTEGER, Types.INTEGER, Types.INTEGER, - Types.INTEGER, Types.VARCHAR, Types.VARCHAR, Types.INTEGER, Types.INTEGER, Types.INTEGER, Types.INTEGER, - Types.VARCHAR, Types.VARCHAR, Types.VARCHAR, Types.VARCHAR, Types.SMALLINT, Types.VARCHAR }, null, null); - assertResultSetOrdered(rs, - new String[][] { - { catalog, Constants.SCHEMA_MAIN, "TEST", "ID", "" + Types.INTEGER, "INTEGER", "10", "10", "0", - "10", "" + DatabaseMetaData.columnNoNulls, "", null, "" + Types.INTEGER, "0", "10", "1", - "NO" }, - { catalog, Constants.SCHEMA_MAIN, "TEST", "TEXT_V", "" + Types.VARCHAR, "VARCHAR", "120", - "120", "0", "10", "" + DatabaseMetaData.columnNullable, "", null, "" + Types.VARCHAR, - "0", "120", "2", "YES" }, - { catalog, Constants.SCHEMA_MAIN, "TEST", "DEC_V", "" + Types.DECIMAL, "DECIMAL", "12", "12", - "3", "10", "" + DatabaseMetaData.columnNullable, "", null, "" + Types.DECIMAL, "0", "12", - "3", "YES" }, - { catalog, Constants.SCHEMA_MAIN, "TEST", "DATE_V", "" + Types.TIMESTAMP, "TIMESTAMP", "23", - "23", "10", "10", "" + DatabaseMetaData.columnNullable, "", null, "" + Types.TIMESTAMP, - "0", "23", "4", "YES" }, - { catalog, Constants.SCHEMA_MAIN, "TEST", "BLOB_V", "" + Types.BLOB, "BLOB", - "" + Integer.MAX_VALUE, "" + Integer.MAX_VALUE, "0", "10", - "" + DatabaseMetaData.columnNullable, "", null, "" + Types.BLOB, "0", - "" + Integer.MAX_VALUE, "5", "YES" }, - { catalog, Constants.SCHEMA_MAIN, "TEST", "CLOB_V", "" + Types.CLOB, "CLOB", - "" + Integer.MAX_VALUE, "" + Integer.MAX_VALUE, "0", "10", - "" + DatabaseMetaData.columnNullable, "", null, "" + Types.CLOB, "0", - "" + Integer.MAX_VALUE, "6", "YES" } }); - /* - * rs=meta.getColumns(null,null,"TEST",null); while(rs.next()) { int - * datatype=rs.getInt(5); } - */ - trace("getIndexInfo"); - stat.executeUpdate("CREATE INDEX IDX_TEXT_DEC ON TEST(TEXT_V,DEC_V)"); - stat.executeUpdate("CREATE UNIQUE INDEX IDX_DATE ON TEST(DATE_V)"); - rs = meta.getIndexInfo(null, null, "TEST", false, false); - assertResultSetMeta(rs, 14, new String[] { "TABLE_CAT", "TABLE_SCHEM", "TABLE_NAME", "NON_UNIQUE", - "INDEX_QUALIFIER", "INDEX_NAME", "TYPE", "ORDINAL_POSITION", "COLUMN_NAME", "ASC_OR_DESC", - "CARDINALITY", "PAGES", "FILTER_CONDITION", "SORT_TYPE"}, new int[] { Types.VARCHAR, Types.VARCHAR, Types.VARCHAR, - DataType.TYPE_BOOLEAN, Types.VARCHAR, Types.VARCHAR, Types.SMALLINT, Types.SMALLINT, Types.VARCHAR, - Types.VARCHAR, Types.INTEGER, Types.INTEGER, Types.VARCHAR, Types.INTEGER}, null, null); - assertResultSetOrdered(rs, new String[][] { - { catalog, Constants.SCHEMA_MAIN, "TEST", "FALSE", catalog, "IDX_DATE", - "" + DatabaseMetaData.tableIndexOther, "1", "DATE_V", "A", "0", "0", "" }, - { catalog, Constants.SCHEMA_MAIN, "TEST", "FALSE", catalog, "PRIMARY_KEY_2", - "" + DatabaseMetaData.tableIndexOther, "1", "ID", "A", "0", "0", "" }, - { catalog, Constants.SCHEMA_MAIN, "TEST", "TRUE", catalog, "IDX_TEXT_DEC", - "" + DatabaseMetaData.tableIndexOther, "1", "TEXT_V", "A", "0", "0", "" }, - { catalog, Constants.SCHEMA_MAIN, "TEST", "TRUE", catalog, "IDX_TEXT_DEC", - "" + DatabaseMetaData.tableIndexOther, "2", "DEC_V", "A", "0", "0", "" }, }); - stat.executeUpdate("DROP INDEX IDX_TEXT_DEC"); - stat.executeUpdate("DROP INDEX IDX_DATE"); - rs = meta.getIndexInfo(null, null, "TEST", false, false); - assertResultSetMeta(rs, 14, new String[] { "TABLE_CAT", "TABLE_SCHEM", "TABLE_NAME", "NON_UNIQUE", - "INDEX_QUALIFIER", "INDEX_NAME", "TYPE", "ORDINAL_POSITION", "COLUMN_NAME", "ASC_OR_DESC", - "CARDINALITY", "PAGES", "FILTER_CONDITION", "SORT_TYPE" }, new int[] { Types.VARCHAR, Types.VARCHAR, Types.VARCHAR, - DataType.TYPE_BOOLEAN, Types.VARCHAR, Types.VARCHAR, Types.SMALLINT, Types.SMALLINT, Types.VARCHAR, - Types.VARCHAR, Types.INTEGER, Types.INTEGER, Types.VARCHAR, Types.INTEGER }, null, null); - assertResultSetOrdered(rs, new String[][] { { catalog, Constants.SCHEMA_MAIN, "TEST", "FALSE", catalog, - "PRIMARY_KEY_2", "" + DatabaseMetaData.tableIndexOther, "1", "ID", "A", "0", "0", "" } }); - trace("getPrimaryKeys"); - rs = meta.getPrimaryKeys(null, null, "TEST"); - assertResultSetMeta(rs, 6, new String[] { "TABLE_CAT", "TABLE_SCHEM", "TABLE_NAME", "COLUMN_NAME", "KEY_SEQ", - "PK_NAME" }, new int[] { Types.VARCHAR, Types.VARCHAR, Types.VARCHAR, Types.VARCHAR, Types.SMALLINT, - Types.VARCHAR }, null, null); - assertResultSetOrdered(rs, - new String[][] { { catalog, Constants.SCHEMA_MAIN, "TEST", "ID", "1", "CONSTRAINT_2" }, }); - trace("getTables - using a wildcard"); - stat.executeUpdate("CREATE TABLE T_2(B INT,A VARCHAR(6),C INT,PRIMARY KEY(C,A,B))"); - stat.executeUpdate("CREATE TABLE TX2(B INT,A VARCHAR(6),C INT,PRIMARY KEY(C,A,B))"); - rs = meta.getTables(null, null, "T_2", null); - assertResultSetOrdered(rs, new String[][] { { catalog, Constants.SCHEMA_MAIN, "TX2", "TABLE", "" }, - { catalog, Constants.SCHEMA_MAIN, "T_2", "TABLE", "" } }); - trace("getTables - using a quoted _ character"); - rs = meta.getTables(null, null, "T\\_2", null); - assertResultSetOrdered(rs, new String[][] { { catalog, Constants.SCHEMA_MAIN, "T_2", "TABLE", "" } }); - trace("getTables - using the % wildcard"); - rs = meta.getTables(null, Constants.SCHEMA_MAIN, "%", new String[] { "TABLE" }); - assertResultSetOrdered(rs, new String[][] { { catalog, Constants.SCHEMA_MAIN, "TEST", "TABLE", "" }, - { catalog, Constants.SCHEMA_MAIN, "TX2", "TABLE", "" }, - { catalog, Constants.SCHEMA_MAIN, "T_2", "TABLE", "" } }); - stat.execute("DROP TABLE TEST"); - - trace("getColumns - using wildcards"); - rs = meta.getColumns(null, null, "___", "B%"); - assertResultSetOrdered(rs, new String[][] { - { catalog, Constants.SCHEMA_MAIN, "TX2", "B", "" + Types.INTEGER, "INTEGER", "10"}, - { catalog, Constants.SCHEMA_MAIN, "T_2", "B", "" + Types.INTEGER, "INTEGER", "10"}, }); - trace("getColumns - using wildcards"); - rs = meta.getColumns(null, null, "_\\__", "%"); - assertResultSetOrdered(rs, new String[][] { - { catalog, Constants.SCHEMA_MAIN, "T_2", "B", "" + Types.INTEGER, "INTEGER", "10"}, - { catalog, Constants.SCHEMA_MAIN, "T_2", "A", "" + Types.VARCHAR, "VARCHAR", "6"}, - { catalog, Constants.SCHEMA_MAIN, "T_2", "C", "" + Types.INTEGER, "INTEGER", "10"}, }); - trace("getIndexInfo"); - stat.executeUpdate("CREATE UNIQUE INDEX A_INDEX ON TX2(B,C,A)"); - stat.executeUpdate("CREATE INDEX B_INDEX ON TX2(A,B,C)"); - rs = meta.getIndexInfo(null, null, "TX2", false, false); - assertResultSetOrdered(rs, new String[][] { - { catalog, Constants.SCHEMA_MAIN, "TX2", "FALSE", catalog, "A_INDEX", - "" + DatabaseMetaData.tableIndexOther, "1", "B", "A" }, - { catalog, Constants.SCHEMA_MAIN, "TX2", "FALSE", catalog, "A_INDEX", - "" + DatabaseMetaData.tableIndexOther, "2", "C", "A"}, - { catalog, Constants.SCHEMA_MAIN, "TX2", "FALSE", catalog, "A_INDEX", - "" + DatabaseMetaData.tableIndexOther, "3", "A", "A"}, - { catalog, Constants.SCHEMA_MAIN, "TX2", "FALSE", catalog, "PRIMARY_KEY_14", - "" + DatabaseMetaData.tableIndexOther, "1", "C", "A"}, - { catalog, Constants.SCHEMA_MAIN, "TX2", "FALSE", catalog, "PRIMARY_KEY_14", - "" + DatabaseMetaData.tableIndexOther, "2", "A", "A" }, - { catalog, Constants.SCHEMA_MAIN, "TX2", "FALSE", catalog, "PRIMARY_KEY_14", - "" + DatabaseMetaData.tableIndexOther, "3", "B", "A"}, - { catalog, Constants.SCHEMA_MAIN, "TX2", "TRUE", catalog, "B_INDEX", - "" + DatabaseMetaData.tableIndexOther, "1", "A", "A" }, - { catalog, Constants.SCHEMA_MAIN, "TX2", "TRUE", catalog, "B_INDEX", - "" + DatabaseMetaData.tableIndexOther, "2", "B", "A" }, - { catalog, Constants.SCHEMA_MAIN, "TX2", "TRUE", catalog, "B_INDEX", - "" + DatabaseMetaData.tableIndexOther, "3", "C", "A" }, }); - trace("getPrimaryKeys"); - rs = meta.getPrimaryKeys(null, null, "T_2"); - assertResultSetOrdered(rs, new String[][] { - { catalog, Constants.SCHEMA_MAIN, "T_2", "A", "2", "CONSTRAINT_1" }, - { catalog, Constants.SCHEMA_MAIN, "T_2", "B", "3", "CONSTRAINT_1" }, - { catalog, Constants.SCHEMA_MAIN, "T_2", "C", "1", "CONSTRAINT_1" }, }); - stat.executeUpdate("DROP TABLE TX2"); - stat.executeUpdate("DROP TABLE T_2"); - stat.executeUpdate("CREATE TABLE PARENT(ID INT PRIMARY KEY)"); - stat - .executeUpdate("CREATE TABLE CHILD(P_ID INT,ID INT,PRIMARY KEY(P_ID,ID),FOREIGN KEY(P_ID) REFERENCES PARENT(ID))"); - - trace("getImportedKeys"); - rs = meta.getImportedKeys(null, null, "CHILD"); - assertResultSetMeta(rs, 14, new String[] { "PKTABLE_CAT", "PKTABLE_SCHEM", "PKTABLE_NAME", "PKCOLUMN_NAME", - "FKTABLE_CAT", "FKTABLE_SCHEM", "FKTABLE_NAME", "FKCOLUMN_NAME", "KEY_SEQ", "UPDATE_RULE", - "DELETE_RULE", "FK_NAME", "PK_NAME", "DEFERRABILITY" }, new int[] { Types.VARCHAR, Types.VARCHAR, - Types.VARCHAR, Types.VARCHAR, Types.VARCHAR, Types.VARCHAR, Types.VARCHAR, Types.VARCHAR, - Types.SMALLINT, Types.SMALLINT, Types.SMALLINT, Types.VARCHAR, Types.VARCHAR, Types.SMALLINT }, null, - null); - // TODO test - // testResultSetOrdered(rs, new String[][] { { null, null, "PARENT", - // "ID", - // null, null, "CHILD", "P_ID", "1", - // "" + DatabaseMetaData.importedKeyNoAction, - // "" + DatabaseMetaData.importedKeyNoAction, "FK_1", null, - // "" + DatabaseMetaData.importedKeyNotDeferrable}}); - - trace("getExportedKeys"); - rs = meta.getExportedKeys(null, null, "PARENT"); - assertResultSetMeta(rs, 14, new String[] { "PKTABLE_CAT", "PKTABLE_SCHEM", "PKTABLE_NAME", "PKCOLUMN_NAME", - "FKTABLE_CAT", "FKTABLE_SCHEM", "FKTABLE_NAME", "FKCOLUMN_NAME", "KEY_SEQ", "UPDATE_RULE", - "DELETE_RULE", "FK_NAME", "PK_NAME", "DEFERRABILITY" }, new int[] { Types.VARCHAR, Types.VARCHAR, - Types.VARCHAR, Types.VARCHAR, Types.VARCHAR, Types.VARCHAR, Types.VARCHAR, Types.VARCHAR, - Types.SMALLINT, Types.SMALLINT, Types.SMALLINT, Types.VARCHAR, Types.VARCHAR, Types.SMALLINT }, null, - null); - // TODO test - /* - * testResultSetOrdered(rs, new String[][]{ { null,null,"PARENT","ID", - * null,null,"CHILD","P_ID", - * "1",""+DatabaseMetaData.importedKeyNoAction, - * ""+DatabaseMetaData.importedKeyNoAction, - * null,null,""+DatabaseMetaData.importedKeyNotDeferrable } } ); - */ - trace("getCrossReference"); - rs = meta.getCrossReference(null, null, "PARENT", null, null, "CHILD"); - assertResultSetMeta(rs, 14, new String[] { "PKTABLE_CAT", "PKTABLE_SCHEM", "PKTABLE_NAME", "PKCOLUMN_NAME", - "FKTABLE_CAT", "FKTABLE_SCHEM", "FKTABLE_NAME", "FKCOLUMN_NAME", "KEY_SEQ", "UPDATE_RULE", - "DELETE_RULE", "FK_NAME", "PK_NAME", "DEFERRABILITY" }, new int[] { Types.VARCHAR, Types.VARCHAR, - Types.VARCHAR, Types.VARCHAR, Types.VARCHAR, Types.VARCHAR, Types.VARCHAR, Types.VARCHAR, - Types.SMALLINT, Types.SMALLINT, Types.SMALLINT, Types.VARCHAR, Types.VARCHAR, Types.SMALLINT }, null, - null); - // TODO test - /* - * testResultSetOrdered(rs, new String[][]{ { null,null,"PARENT","ID", - * null,null,"CHILD","P_ID", - * "1",""+DatabaseMetaData.importedKeyNoAction, - * ""+DatabaseMetaData.importedKeyNoAction, - * null,null,""+DatabaseMetaData.importedKeyNotDeferrable } } ); - */ - - rs = meta.getSchemas(); - assertResultSetMeta(rs, 3, new String[] { "TABLE_SCHEM", "TABLE_CATALOG", "IS_DEFAULT" }, new int[] { - Types.VARCHAR, Types.VARCHAR, DataType.TYPE_BOOLEAN }, null, null); - assertTrue(rs.next()); - assertEquals("INFORMATION_SCHEMA", rs.getString(1)); - assertTrue(rs.next()); - assertEquals("PUBLIC", rs.getString(1)); - assertFalse(rs.next()); - - rs = meta.getCatalogs(); - assertResultSetMeta(rs, 1, new String[] { "TABLE_CAT" }, new int[] { Types.VARCHAR }, null, null); - assertResultSetOrdered(rs, new String[][] { { catalog } }); - - rs = meta.getTableTypes(); - assertResultSetMeta(rs, 1, new String[] { "TABLE_TYPE" }, new int[] { Types.VARCHAR }, null, null); - assertResultSetOrdered(rs, new String[][] { { "SYSTEM TABLE" }, { "TABLE" }, { "TABLE LINK" }, { "VIEW" } }); - - rs = meta.getTypeInfo(); - assertResultSetMeta(rs, 18, new String[] { "TYPE_NAME", "DATA_TYPE", "PRECISION", "LITERAL_PREFIX", - "LITERAL_SUFFIX", "CREATE_PARAMS", "NULLABLE", "CASE_SENSITIVE", "SEARCHABLE", "UNSIGNED_ATTRIBUTE", - "FIXED_PREC_SCALE", "AUTO_INCREMENT", "LOCAL_TYPE_NAME", "MINIMUM_SCALE", "MAXIMUM_SCALE", - "SQL_DATA_TYPE", "SQL_DATETIME_SUB", "NUM_PREC_RADIX" }, new int[] { Types.VARCHAR, Types.INTEGER, - Types.INTEGER, Types.VARCHAR, Types.VARCHAR, Types.VARCHAR, Types.SMALLINT, DataType.TYPE_BOOLEAN, - Types.SMALLINT, DataType.TYPE_BOOLEAN, DataType.TYPE_BOOLEAN, DataType.TYPE_BOOLEAN, Types.VARCHAR, - Types.SMALLINT, Types.SMALLINT, Types.INTEGER, Types.INTEGER, Types.INTEGER }, null, null); - - rs = meta.getTablePrivileges(null, null, null); - assertResultSetMeta(rs, 7, new String[] { "TABLE_CAT", "TABLE_SCHEM", "TABLE_NAME", "GRANTOR", "GRANTEE", - "PRIVILEGE", "IS_GRANTABLE" }, new int[] { Types.VARCHAR, Types.VARCHAR, Types.VARCHAR, Types.VARCHAR, - Types.VARCHAR, Types.VARCHAR, Types.VARCHAR, Types.VARCHAR }, null, null); - - rs = meta.getColumnPrivileges(null, null, "TEST", null); - assertResultSetMeta(rs, 8, new String[] { "TABLE_CAT", "TABLE_SCHEM", "TABLE_NAME", "COLUMN_NAME", "GRANTOR", - "GRANTEE", "PRIVILEGE", "IS_GRANTABLE" }, new int[] { Types.VARCHAR, Types.VARCHAR, Types.VARCHAR, - Types.VARCHAR, Types.VARCHAR, Types.VARCHAR, Types.VARCHAR, Types.VARCHAR, Types.VARCHAR }, null, null); - - assertTrue(conn.getWarnings() == null); - conn.clearWarnings(); - assertTrue(conn.getWarnings() == null); - - } - -} diff --git a/tools/h2/src/test/org/h2/test/jdbc/TestNativeSQL.java b/tools/h2/src/test/org/h2/test/jdbc/TestNativeSQL.java deleted file mode 100755 index 69d6269..0000000 --- a/tools/h2/src/test/org/h2/test/jdbc/TestNativeSQL.java +++ /dev/null @@ -1,258 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.test.jdbc; - -import java.sql.Connection; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.sql.Statement; -import java.util.Random; - -import org.h2.test.TestBase; - -/** - * Tests the Connection.nativeSQL method. - */ -public class TestNativeSQL extends TestBase { - - private static final String[] PAIRS = { - "CREATE TABLE TEST(ID INT PRIMARY KEY)", - "CREATE TABLE TEST(ID INT PRIMARY KEY)", - - "INSERT INTO TEST VALUES(1)", "INSERT INTO TEST VALUES(1)", - "SELECT '{nothing}' FROM TEST", "SELECT '{nothing}' FROM TEST", - - "SELECT '{fn ABS(1)}' FROM TEST", "SELECT '{fn ABS(1)}' FROM TEST", - - "SELECT {d '2001-01-01'} FROM TEST", "SELECT '2001-01-01' FROM TEST", - - "SELECT {t '20:00:00'} FROM TEST", "SELECT '20:00:00' FROM TEST", - - "SELECT {ts '2001-01-01 20:00:00'} FROM TEST", "SELECT '2001-01-01 20:00:00' FROM TEST", - - "SELECT {fn CONCAT('{fn x}','{oj}')} FROM TEST", "SELECT CONCAT('{fn x}','{oj}') FROM TEST", - - "SELECT * FROM {oj TEST T1 LEFT OUTER JOIN TEST T2 ON T1.ID=T2.ID}", - "SELECT * FROM TEST T1 LEFT OUTER JOIN TEST T2 ON T1.ID=T2.ID ", - - "SELECT * FROM TEST WHERE '{' LIKE '{{' {escape '{'}", - "SELECT * FROM TEST WHERE '{' LIKE '{{' escape '{' ", - - "SELECT * FROM TEST WHERE '}' LIKE '}}' {escape '}'}", - "SELECT * FROM TEST WHERE '}' LIKE '}}' escape '}' ", - - "{call TEST('}')}", " call TEST('}') ", - - "{?= call TEST('}')}", " call TEST('}') ", - - "{? = call TEST('}')}", " call TEST('}') ", - - "{{{{this is a bug}", null, }; - - private Connection conn; - - /** - * Run just this test. - * - * @param a ignored - */ - public static void main(String... a) throws Exception { - TestBase.createCaller().init().test(); - } - - public void test() throws SQLException { - deleteDb("nativeSql"); - conn = getConnection("nativeSql"); - testPairs(); - testCases(); - testRandom(); - testQuotes(); - conn.close(); - assertTrue(conn.isClosed()); - deleteDb("nativeSql"); - } - - private void testQuotes() throws SQLException { - Statement stat = conn.createStatement(); - Random random = new Random(1); - String s = "'\"$/-* \n"; - for (int i = 0; i < 200; i++) { - StringBuilder buffQuoted = new StringBuilder(); - StringBuilder buffRaw = new StringBuilder(); - if (random.nextBoolean()) { - buffQuoted.append("'"); - for (int j = 0; j < 10; j++) { - char c = s.charAt(random.nextInt(s.length())); - if (c == '\'') { - buffQuoted.append('\''); - } - buffQuoted.append(c); - buffRaw.append(c); - } - buffQuoted.append("'"); - } else { - buffQuoted.append("$$"); - for (int j = 0; j < 10; j++) { - char c = s.charAt(random.nextInt(s.length())); - buffQuoted.append(c); - buffRaw.append(c); - if (c == '$') { - buffQuoted.append(' '); - buffRaw.append(' '); - } - } - buffQuoted.append("$$"); - } - String sql = "CALL " + buffQuoted.toString(); - ResultSet rs = stat.executeQuery(sql); - rs.next(); - String raw = buffRaw.toString(); - assertEquals(raw, rs.getString(1)); - } - } - - private void testRandom() throws SQLException { - Random random = new Random(1); - for (int i = 0; i < 100; i++) { - StringBuilder buff = new StringBuilder("{oj }"); - String s = "{}\'\"-/*$ $-"; - for (int j = random.nextInt(30); j > 0; j--) { - buff.append(s.charAt(random.nextInt(s.length()))); - } - String sql = buff.toString(); - try { - conn.nativeSQL(sql); - } catch (SQLException e) { - assertKnownException(sql, e); - } - } - String smallest = null; - for (int i = 0; i < 1000; i++) { - StringBuilder buff = new StringBuilder("{oj }"); - for (int j = random.nextInt(10); j > 0; j--) { - String s; - switch(random.nextInt(7)) { - case 0: - buff.append(" $$"); - s = "{}\'\"-/* a\n"; - for (int k = random.nextInt(5); k > 0; k--) { - buff.append(s.charAt(random.nextInt(s.length()))); - } - buff.append("$$"); - break; - case 1: - buff.append("'"); - s = "{}\"-/*$ a\n"; - for (int k = random.nextInt(5); k > 0; k--) { - buff.append(s.charAt(random.nextInt(s.length()))); - } - buff.append("'"); - break; - case 2: - buff.append("\""); - s = "{}'-/*$ a\n"; - for (int k = random.nextInt(5); k > 0; k--) { - buff.append(s.charAt(random.nextInt(s.length()))); - } - buff.append("\""); - break; - case 3: - buff.append("/*"); - s = "{}'\"-/$ a\n"; - for (int k = random.nextInt(5); k > 0; k--) { - buff.append(s.charAt(random.nextInt(s.length()))); - } - buff.append("*/"); - break; - case 4: - buff.append("--"); - s = "{}'\"-/$ a"; - for (int k = random.nextInt(5); k > 0; k--) { - buff.append(s.charAt(random.nextInt(s.length()))); - } - buff.append("\n"); - break; - case 5: - buff.append("//"); - s = "{}'\"-/$ a"; - for (int k = random.nextInt(5); k > 0; k--) { - buff.append(s.charAt(random.nextInt(s.length()))); - } - buff.append("\n"); - break; - case 6: - s = " a\n"; - for (int k = random.nextInt(5); k > 0; k--) { - buff.append(s.charAt(random.nextInt(s.length()))); - } - break; - default: - } - } - String sql = buff.toString(); - try { - conn.nativeSQL(sql); - } catch (Exception e) { - if (smallest == null || sql.length() < smallest.length()) { - smallest = sql; - } - } - } - if (smallest != null) { - conn.nativeSQL(smallest); - } - } - - private void testPairs() { - for (int i = 0; i < PAIRS.length; i += 2) { - test(PAIRS[i], PAIRS[i + 1]); - } - } - - private void testCases() throws SQLException { - conn.nativeSQL("TEST"); - conn.nativeSQL("TEST--testing"); - conn.nativeSQL("TEST--testing{oj }"); - conn.nativeSQL("TEST/*{fn }*/"); - conn.nativeSQL("TEST//{fn }"); - conn.nativeSQL("TEST-TEST/TEST/*TEST*/TEST--\rTEST--{fn }"); - conn.nativeSQL("TEST-TEST//TEST"); - conn.nativeSQL("'{}' '' \"1\" \"\"\"\""); - conn.nativeSQL("{?= call HELLO{t '10'}}"); - conn.nativeSQL("TEST 'test'{OJ OUTER JOIN}'test'{oj OUTER JOIN}"); - conn.nativeSQL("{call {ts '2001-01-10'}}"); - conn.nativeSQL("call ? { 1: '}' };"); - conn.nativeSQL("TEST TEST TEST TEST TEST 'TEST' TEST \"TEST\""); - conn.nativeSQL("TEST TEST TEST 'TEST' TEST \"TEST\""); - Statement stat = conn.createStatement(); - stat.setEscapeProcessing(true); - stat.execute("CALL {d '2001-01-01'}"); - stat.setEscapeProcessing(false); - try { - stat.execute("CALL {d '2001-01-01'} // this is a test"); - fail("expected error if setEscapeProcessing=false"); - } catch (SQLException e) { - assertKnownException(e); - } - assertFalse(conn.isClosed()); - } - - private void test(String original, String expected) { - trace("original: <" + original + ">"); - trace("expected: <" + expected + ">"); - try { - String result = conn.nativeSQL(original); - trace("result: <" + result + ">"); - assertEquals(expected, result); - } catch (SQLException e) { - assertEquals(expected, null); - assertKnownException(e); - trace("got exception, good"); - } - } - -} diff --git a/tools/h2/src/test/org/h2/test/jdbc/TestPreparedStatement.java b/tools/h2/src/test/org/h2/test/jdbc/TestPreparedStatement.java deleted file mode 100755 index 11a41cb..0000000 --- a/tools/h2/src/test/org/h2/test/jdbc/TestPreparedStatement.java +++ /dev/null @@ -1,1036 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.test.jdbc; - -import java.io.ByteArrayInputStream; -import java.io.IOException; -import java.io.StringReader; -import java.math.BigDecimal; -import java.sql.Connection; -import java.sql.ParameterMetaData; -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.ResultSetMetaData; -import java.sql.SQLException; -import java.sql.Statement; -import java.sql.Timestamp; -import java.sql.Types; -import java.util.UUID; -import org.h2.api.Trigger; -import org.h2.test.TestBase; - -/** - * Tests for the PreparedStatement implementation. - */ -public class TestPreparedStatement extends TestBase { - - private static final int LOB_SIZE = 4000, LOB_SIZE_BIG = 512 * 1024; - - /** - * Run just this test. - * - * @param a ignored - */ - public static void main(String... a) throws Exception { - TestBase.createCaller().init().test(); - } - - public void test() throws Exception { - - deleteDb("preparedStatement"); - Connection conn = getConnection("preparedStatement"); - testPrepareExecute(conn); - testUUID(conn); - testScopedGeneratedKey(conn); - testLobTempFiles(conn); - testExecuteErrorTwice(conn); - testTempView(conn); - testInsertFunction(conn); - testPrepareRecompile(conn); - testMaxRowsChange(conn); - testUnknownDataType(conn); - testCancelReuse(conn); - testCoalesce(conn); - testPreparedStatementMetaData(conn); - testDate(conn); - testArray(conn); - testUUIDGeneratedKeys(conn); - testSetObject(conn); - testPreparedSubquery(conn); - testLikeIndex(conn); - testCasewhen(conn); - testSubquery(conn); - testObject(conn); - if (config.jdk14) { - testIdentity(conn); - } - testDataTypes(conn); - testBlob(conn); - testClob(conn); - testParameterMetaData(conn); - conn.close(); - deleteDb("preparedStatement"); - } - - private void testPrepareExecute(Connection conn) throws SQLException { - Statement stat = conn.createStatement(); - stat.execute("prepare test(int, int) as select ?1*?2"); - ResultSet rs = stat.executeQuery("execute test(3, 2)"); - rs.next(); - assertEquals(6, rs.getInt(1)); - stat.execute("deallocate test"); - } - - private void testLobTempFiles(Connection conn) throws SQLException { - Statement stat = conn.createStatement(); - stat.execute("CREATE TABLE TEST(ID INT PRIMARY KEY, DATA CLOB)"); - PreparedStatement prep = conn.prepareStatement("INSERT INTO TEST VALUES(?, ?)"); - for (int i = 0; i < 5; i++) { - prep.setInt(1, i); - if (i % 2 == 0) { - prep.setCharacterStream(2, new StringReader(getString(i)), -1); - } - prep.execute(); - } - ResultSet rs = stat.executeQuery("SELECT * FROM TEST ORDER BY ID"); - int check = 0; - for (int i = 0; i < 5; i++) { - assertTrue(rs.next()); - if (i % 2 == 0) { - check = i; - } - assertEquals(getString(check), rs.getString(2)); - } - assertFalse(rs.next()); - stat.execute("DELETE FROM TEST"); - for (int i = 0; i < 3; i++) { - prep.setInt(1, i); - prep.setCharacterStream(2, new StringReader(getString(i)), -1); - prep.addBatch(); - } - prep.executeBatch(); - rs = stat.executeQuery("SELECT * FROM TEST ORDER BY ID"); - for (int i = 0; i < 3; i++) { - assertTrue(rs.next()); - assertEquals(getString(i), rs.getString(2)); - } - assertFalse(rs.next()); - stat.execute("DROP TABLE TEST"); - } - - private String getString(int i) { - return new String(new char[100000]).replace('\0', (char) ('0' + i)); - } - - - private void testExecuteErrorTwice(Connection conn) throws SQLException { - PreparedStatement prep = conn.prepareStatement("CREATE TABLE BAD AS SELECT A"); - try { - prep.execute(); - fail(); - } catch (SQLException e) { - assertKnownException(e); - } - try { - prep.execute(); - fail(); - } catch (SQLException e) { - assertKnownException(e); - } - } - - - private void testTempView(Connection conn) throws SQLException { - Statement stat = conn.createStatement(); - PreparedStatement prep; - stat.execute("CREATE TABLE TEST(FIELD INT PRIMARY KEY)"); - stat.execute("INSERT INTO TEST VALUES(1)"); - stat.execute("INSERT INTO TEST VALUES(2)"); - prep = conn.prepareStatement("select FIELD FROM " - + "(select FIELD FROM (SELECT FIELD FROM TEST WHERE FIELD = ?) AS T2 " - + "WHERE T2.FIELD = ?) AS T3 WHERE T3.FIELD = ?"); - prep.setInt(1, 1); - prep.setInt(2, 1); - prep.setInt(3, 1); - ResultSet rs = prep.executeQuery(); - rs.next(); - assertEquals(1, rs.getInt(1)); - prep.setInt(1, 2); - prep.setInt(2, 2); - prep.setInt(3, 2); - rs = prep.executeQuery(); - rs.next(); - assertEquals(2, rs.getInt(1)); - stat.execute("DROP TABLE TEST"); - } - - private void testInsertFunction(Connection conn) throws SQLException { - Statement stat = conn.createStatement(); - PreparedStatement prep; - ResultSet rs; - - stat.execute("CREATE TABLE TEST(ID INT, H BINARY)"); - prep = conn.prepareStatement("INSERT INTO TEST VALUES(?, HASH('SHA256', STRINGTOUTF8(?), 5))"); - prep.setInt(1, 1); - prep.setString(2, "One"); - prep.execute(); - prep.setInt(1, 2); - prep.setString(2, "Two"); - prep.execute(); - rs = stat.executeQuery("SELECT COUNT(DISTINCT H) FROM TEST"); - rs.next(); - assertEquals(2, rs.getInt(1)); - - stat.execute("DROP TABLE TEST"); - } - - private void testPrepareRecompile(Connection conn) throws SQLException { - Statement stat = conn.createStatement(); - PreparedStatement prep; - ResultSet rs; - - prep = conn.prepareStatement("SELECT COUNT(*) FROM DUAL WHERE ? IS NULL"); - prep.setString(1, null); - prep.executeQuery(); - stat.execute("CREATE TABLE TEST(ID INT)"); - stat.execute("DROP TABLE TEST"); - prep.setString(1, null); - prep.executeQuery(); - prep.setString(1, "X"); - rs = prep.executeQuery(); - rs.next(); - assertEquals(0, rs.getInt(1)); - - stat.execute("CREATE TABLE t1 (c1 INT, c2 VARCHAR(10))"); - stat.execute("INSERT INTO t1 SELECT X, CONCAT('Test', X) FROM SYSTEM_RANGE(1, 5);"); - prep = conn.prepareStatement("SELECT c1, c2 FROM t1 WHERE c1 = ?"); - prep.setInt(1, 1); - prep.executeQuery(); - stat.execute("CREATE TABLE t2 (x int PRIMARY KEY)"); - prep.setInt(1, 2); - rs = prep.executeQuery(); - rs.next(); - assertEquals(2, rs.getInt(1)); - prep.setInt(1, 3); - rs = prep.executeQuery(); - rs.next(); - assertEquals(3, rs.getInt(1)); - stat.execute("DROP TABLE t1, t2"); - - } - - private void testMaxRowsChange(Connection conn) throws SQLException { - PreparedStatement prep = conn.prepareStatement("SELECT * FROM SYSTEM_RANGE(1, 100)"); - ResultSet rs; - for (int j = 1; j < 20; j++) { - prep.setMaxRows(j); - rs = prep.executeQuery(); - for (int i = 0; i < j; i++) { - assertTrue(rs.next()); - } - assertFalse(rs.next()); - } - } - - private void testUnknownDataType(Connection conn) throws SQLException { - try { - PreparedStatement prep = conn.prepareStatement( - "SELECT * FROM (SELECT ? FROM DUAL)"); - prep.setInt(1, 1); - prep.execute(); - fail(); - } catch (SQLException e) { - assertKnownException(e); - } - PreparedStatement prep = conn.prepareStatement("SELECT -?"); - prep.setInt(1, 1); - prep.execute(); - prep = conn.prepareStatement("SELECT ?-?"); - prep.setInt(1, 1); - prep.setInt(2, 2); - prep.execute(); - } - - private void testCancelReuse(Connection conn) throws Exception { - conn.createStatement().execute("CREATE ALIAS YIELD FOR \"java.lang.Thread.yield\""); - final PreparedStatement prep = conn.prepareStatement("SELECT YIELD() FROM SYSTEM_RANGE(1, 100000000) LIMIT ?"); - prep.setInt(1, 100000000); - Thread t = new Thread() { - public void run() { - try { - prep.execute(); - } catch (SQLException e) { - // ignore - } - } - }; - t.start(); - Thread.sleep(100); - try { - prep.cancel(); - } catch (SQLException e) { - this.assertKnownException(e); - } - prep.setInt(1, 1); - ResultSet rs = prep.executeQuery(); - assertTrue(rs.next()); - assertEquals(0, rs.getInt(1)); - assertFalse(rs.next()); - } - - private void testCoalesce(Connection conn) throws SQLException { - Statement stat = conn.createStatement(); - stat.executeUpdate("create table test(tm timestamp)"); - stat.executeUpdate("insert into test values(current_timestamp)"); - PreparedStatement prep = conn.prepareStatement("update test set tm = coalesce(?,tm)"); - prep.setTimestamp(1, new java.sql.Timestamp(System.currentTimeMillis())); - prep.executeUpdate(); - stat.executeUpdate("drop table test"); - } - - private void testPreparedStatementMetaData(Connection conn) throws SQLException { - PreparedStatement prep = conn.prepareStatement("select * from table(x int = ?, name varchar = ?)"); - ResultSetMetaData meta = prep.getMetaData(); - assertEquals(2, meta.getColumnCount()); - assertEquals("INTEGER", meta.getColumnTypeName(1)); - assertEquals("VARCHAR", meta.getColumnTypeName(2)); - prep = conn.prepareStatement("call 1"); - meta = prep.getMetaData(); - assertEquals(1, meta.getColumnCount()); - assertEquals("INTEGER", meta.getColumnTypeName(1)); - } - - private void testArray(Connection conn) throws SQLException { - PreparedStatement prep = conn.prepareStatement("select * from table(x int = ?) order by x"); - prep.setObject(1, new Object[] { new BigDecimal("1"), "2" }); - ResultSet rs = prep.executeQuery(); - rs.next(); - assertEquals("1", rs.getString(1)); - rs.next(); - assertEquals("2", rs.getString(1)); - assertFalse(rs.next()); - } - - private void testUUID(Connection conn) throws SQLException { - Statement stat = conn.createStatement(); - stat.execute("create table test_uuid(id uuid primary key)"); - UUID uuid = new UUID(-2, -1); - PreparedStatement prep = conn.prepareStatement("insert into test_uuid values(?)"); - prep.setObject(1, uuid); - prep.execute(); - ResultSet rs = stat.executeQuery("select * from test_uuid"); - rs.next(); - assertEquals("ffffffff-ffff-fffe-ffff-ffffffffffff", rs.getString(1)); - Object o = rs.getObject(1); - assertEquals("java.util.UUID", o.getClass().getName()); - stat.execute("drop table test_uuid"); - } - - private void testUUIDGeneratedKeys(Connection conn) throws SQLException { - Statement stat = conn.createStatement(); - stat.execute("CREATE TABLE TEST_UUID(id UUID DEFAULT random_UUID() PRIMARY KEY)"); - stat.execute("INSERT INTO TEST_UUID() VALUES()"); - ResultSet rs = stat.getGeneratedKeys(); - rs.next(); - byte[] data = rs.getBytes(1); - assertEquals(16, data.length); - stat.execute("DROP TABLE TEST_UUID"); - } - - /** - * A trigger that creates a sequence value. - */ - public static class SequenceTrigger implements Trigger { - - public void fire(Connection conn, Object[] oldRow, Object[] newRow) throws SQLException { - conn.setAutoCommit(false); - conn.createStatement().execute("call next value for seq"); - } - - public void init(Connection conn, String schemaName, String triggerName, String tableName, boolean before, - int type) { - // ignore - } - - public void close() { - // ignore - } - - public void remove() { - // ignore - } - - } - - private void testScopedGeneratedKey(Connection conn) throws SQLException { - Statement stat = conn.createStatement(); - Trigger t = new SequenceTrigger(); - stat.execute("create table test(id identity)"); - stat.execute("create sequence seq start with 1000"); - stat.execute("create trigger test_ins after insert on test call \"" + t.getClass().getName() + "\""); - stat.execute("insert into test values(null)"); - ResultSet rs = stat.getGeneratedKeys(); - rs.next(); - assertEquals(1, rs.getLong(1)); - stat.execute("drop sequence seq"); - stat.execute("drop table test"); - } - - private void testSetObject(Connection conn) throws SQLException { - Statement stat = conn.createStatement(); - stat.execute("CREATE TABLE TEST(C CHAR(1))"); - PreparedStatement prep = conn.prepareStatement("INSERT INTO TEST VALUES(?)"); - prep.setObject(1, 'x'); - prep.execute(); - stat.execute("DROP TABLE TEST"); - stat.execute("CREATE TABLE TEST(ID INT, DATA BINARY, JAVA OTHER)"); - prep = conn.prepareStatement("INSERT INTO TEST VALUES(?, ?, ?)"); - prep.setInt(1, 1); - prep.setObject(2, new Integer(11)); - prep.setObject(3, null); - prep.execute(); - prep.setInt(1, 2); - prep.setObject(2, new Integer(101), Types.OTHER); - prep.setObject(3, new Integer(103), Types.OTHER); - prep.execute(); - PreparedStatement p2 = conn.prepareStatement("SELECT * FROM TEST ORDER BY ID"); - ResultSet rs = p2.executeQuery(); - rs.next(); - Object o = rs.getObject(2); - assertTrue(o instanceof byte[]); - assertTrue(rs.getObject(3) == null); - rs.next(); - o = rs.getObject(2); - assertTrue(o instanceof byte[]); - o = rs.getObject(3); - assertTrue(o instanceof Integer); - assertEquals(103, ((Integer) o).intValue()); - assertFalse(rs.next()); - stat.execute("DROP TABLE TEST"); - } - - private void testDate(Connection conn) throws SQLException { - PreparedStatement prep = conn.prepareStatement("SELECT ?"); - Timestamp ts = Timestamp.valueOf("2001-02-03 04:05:06"); - prep.setObject(1, new java.util.Date(ts.getTime())); - ResultSet rs = prep.executeQuery(); - rs.next(); - Timestamp ts2 = rs.getTimestamp(1); - assertEquals(ts.toString(), ts2.toString()); - } - - private void testPreparedSubquery(Connection conn) throws SQLException { - Statement s = conn.createStatement(); - s.executeUpdate("CREATE TABLE TEST(ID IDENTITY, FLAG BIT)"); - s.executeUpdate("INSERT INTO TEST(ID, FLAG) VALUES(0, FALSE)"); - s.executeUpdate("INSERT INTO TEST(ID, FLAG) VALUES(1, FALSE)"); - PreparedStatement u = conn.prepareStatement("SELECT ID, FLAG FROM TEST ORDER BY ID"); - PreparedStatement p = conn.prepareStatement("UPDATE TEST SET FLAG=true WHERE ID=(SELECT ?)"); - p.clearParameters(); - p.setLong(1, 0); - assertEquals(1, p.executeUpdate()); - p.clearParameters(); - p.setLong(1, 1); - assertEquals(1, p.executeUpdate()); - ResultSet rs = u.executeQuery(); - assertTrue(rs.next()); - assertEquals(0, rs.getInt(1)); - assertTrue(rs.getBoolean(2)); - assertTrue(rs.next()); - assertEquals(1, rs.getInt(1)); - assertTrue(rs.getBoolean(2)); - - p = conn.prepareStatement("SELECT * FROM TEST WHERE EXISTS(SELECT * FROM TEST WHERE ID=?)"); - p.setInt(1, -1); - rs = p.executeQuery(); - assertFalse(rs.next()); - p.setInt(1, 1); - rs = p.executeQuery(); - assertTrue(rs.next()); - - s.executeUpdate("DROP TABLE IF EXISTS TEST"); - } - - private void testParameterMetaData(Connection conn) throws SQLException { - PreparedStatement prep = conn.prepareStatement("SELECT ?, ?, ? FROM DUAL"); - ParameterMetaData pm = prep.getParameterMetaData(); - assertEquals("java.lang.String", pm.getParameterClassName(1)); - assertEquals("VARCHAR", pm.getParameterTypeName(1)); - assertEquals(3, pm.getParameterCount()); - assertEquals(ParameterMetaData.parameterModeIn, pm.getParameterMode(1)); - assertEquals(Types.VARCHAR, pm.getParameterType(1)); - assertEquals(0, pm.getPrecision(1)); - assertEquals(0, pm.getScale(1)); - assertEquals(ResultSetMetaData.columnNullableUnknown, pm.isNullable(1)); - assertEquals(pm.isSigned(1), true); - try { - pm.getPrecision(0); - fail(); - } catch (SQLException e) { - assertKnownException(e); - } - try { - pm.getPrecision(4); - fail(); - } catch (SQLException e) { - assertKnownException(e); - } - prep.close(); - try { - pm.getPrecision(1); - fail(); - } catch (SQLException e) { - assertKnownException(e); - } - - Statement stat = conn.createStatement(); - stat.execute("CREATE TABLE TEST3(ID INT, NAME VARCHAR(255), DATA DECIMAL(10,2))"); - PreparedStatement prep1 = conn.prepareStatement("UPDATE TEST3 SET ID=?, NAME=?, DATA=?"); - PreparedStatement prep2 = conn.prepareStatement("INSERT INTO TEST3 VALUES(?, ?, ?)"); - checkParameter(prep1, 1, "java.lang.Integer", 4, "INTEGER", 10, 0); - checkParameter(prep1, 2, "java.lang.String", 12, "VARCHAR", 255, 0); - checkParameter(prep1, 3, "java.math.BigDecimal", 3, "DECIMAL", 10, 2); - checkParameter(prep2, 1, "java.lang.Integer", 4, "INTEGER", 10, 0); - checkParameter(prep2, 2, "java.lang.String", 12, "VARCHAR", 255, 0); - checkParameter(prep2, 3, "java.math.BigDecimal", 3, "DECIMAL", 10, 2); - PreparedStatement prep3 = conn.prepareStatement("SELECT * FROM TEST3 WHERE ID=? AND NAME LIKE ? AND ?>DATA"); - checkParameter(prep3, 1, "java.lang.Integer", 4, "INTEGER", 10, 0); - checkParameter(prep3, 2, "java.lang.String", 12, "VARCHAR", 0, 0); - checkParameter(prep3, 3, "java.math.BigDecimal", 3, "DECIMAL", 10, 2); - stat.execute("DROP TABLE TEST3"); - } - - private void checkParameter(PreparedStatement prep, int index, String className, int type, String typeName, int precision, int scale) throws SQLException { - ParameterMetaData meta = prep.getParameterMetaData(); - assertEquals(className, meta.getParameterClassName(index)); - assertEquals(type, meta.getParameterType(index)); - assertEquals(typeName, meta.getParameterTypeName(index)); - assertEquals(precision, meta.getPrecision(index)); - assertEquals(scale, meta.getScale(index)); - } - - private void testLikeIndex(Connection conn) throws SQLException { - Statement stat = conn.createStatement(); - stat.execute("CREATE TABLE TEST(ID INT PRIMARY KEY, NAME VARCHAR(255))"); - stat.execute("INSERT INTO TEST VALUES(1, 'Hello')"); - stat.execute("INSERT INTO TEST VALUES(2, 'World')"); - stat.execute("create index idxname on test(name);"); - PreparedStatement prep, prepExe; - - prep = conn.prepareStatement("EXPLAIN SELECT * FROM TEST WHERE NAME LIKE ?"); - assertEquals(1, prep.getParameterMetaData().getParameterCount()); - prepExe = conn.prepareStatement("SELECT * FROM TEST WHERE NAME LIKE ?"); - prep.setString(1, "%orld"); - prepExe.setString(1, "%orld"); - ResultSet rs = prep.executeQuery(); - rs.next(); - String plan = rs.getString(1); - assertTrue(plan.indexOf(".tableScan") >= 0); - rs = prepExe.executeQuery(); - rs.next(); - assertEquals("World", rs.getString(2)); - assertFalse(rs.next()); - - prep.setString(1, "H%"); - prepExe.setString(1, "H%"); - rs = prep.executeQuery(); - rs.next(); - String plan1 = rs.getString(1); - assertTrue(plan1.indexOf("IDXNAME") >= 0); - rs = prepExe.executeQuery(); - rs.next(); - assertEquals("Hello", rs.getString(2)); - assertFalse(rs.next()); - - stat.execute("DROP TABLE IF EXISTS TEST"); - } - - private void testCasewhen(Connection conn) throws SQLException { - Statement stat = conn.createStatement(); - stat.execute("CREATE TABLE TEST(ID INT)"); - stat.execute("INSERT INTO TEST VALUES(1),(2),(3)"); - PreparedStatement prep; - ResultSet rs; - prep = conn.prepareStatement("EXPLAIN SELECT COUNT(*) FROM TEST WHERE CASEWHEN(ID=1, ID, ID)=? GROUP BY ID"); - prep.setInt(1, 1); - rs = prep.executeQuery(); - rs.next(); - String plan = rs.getString(1); - trace(plan); - rs.close(); - prep = conn - .prepareStatement("EXPLAIN SELECT COUNT(*) FROM TEST WHERE CASE ID WHEN 1 THEN ID WHEN 2 THEN ID ELSE ID END=? GROUP BY ID"); - prep.setInt(1, 1); - rs = prep.executeQuery(); - rs.next(); - plan = rs.getString(1); - trace(plan); - - prep = conn.prepareStatement("SELECT COUNT(*) FROM TEST WHERE CASEWHEN(ID=1, ID, ID)=? GROUP BY ID"); - prep.setInt(1, 1); - rs = prep.executeQuery(); - assertTrue(rs.next()); - assertEquals(1, rs.getInt(1)); - assertFalse(rs.next()); - - prep = conn - .prepareStatement("SELECT COUNT(*) FROM TEST WHERE CASE ID WHEN 1 THEN ID WHEN 2 THEN ID ELSE ID END=? GROUP BY ID"); - prep.setInt(1, 1); - rs = prep.executeQuery(); - assertTrue(rs.next()); - assertEquals(1, rs.getInt(1)); - assertFalse(rs.next()); - - prep = conn.prepareStatement("SELECT * FROM TEST WHERE ? IS NULL"); - prep.setString(1, "Hello"); - rs = prep.executeQuery(); - assertFalse(rs.next()); - try { - conn.prepareStatement("select ? from dual union select ? from dual"); - fail(); - } catch (SQLException e) { - assertKnownException(e); - } - prep = conn.prepareStatement("select cast(? as varchar) from dual union select ? from dual"); - assertEquals(2, prep.getParameterMetaData().getParameterCount()); - prep.setString(1, "a"); - prep.setString(2, "a"); - rs = prep.executeQuery(); - rs.next(); - assertEquals("a", rs.getString(1)); - assertEquals("a", rs.getString(1)); - assertFalse(rs.next()); - - stat.execute("DROP TABLE TEST"); - } - - private void testSubquery(Connection conn) throws SQLException { - Statement stat = conn.createStatement(); - stat.execute("CREATE TABLE TEST(ID INT)"); - stat.execute("INSERT INTO TEST VALUES(1),(2),(3)"); - PreparedStatement prep = conn.prepareStatement("select x.id, ? from " - + "(select * from test where id in(?, ?)) x where x.id*2 <> ?"); - assertEquals(4, prep.getParameterMetaData().getParameterCount()); - prep.setInt(1, 0); - prep.setInt(2, 1); - prep.setInt(3, 2); - prep.setInt(4, 4); - ResultSet rs = prep.executeQuery(); - rs.next(); - assertEquals(1, rs.getInt(1)); - assertEquals(0, rs.getInt(2)); - assertFalse(rs.next()); - stat.execute("DROP TABLE TEST"); - } - - private void testDataTypes(Connection conn) throws SQLException { - conn.createStatement(ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY); - conn.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_UPDATABLE); - Statement stat = conn.createStatement(); - PreparedStatement prep; - ResultSet rs; - trace("Create tables"); - stat.execute("CREATE TABLE T_INT(ID INT PRIMARY KEY,VALUE INT)"); - stat.execute("CREATE TABLE T_VARCHAR(ID INT PRIMARY KEY,VALUE VARCHAR(255))"); - stat.execute("CREATE TABLE T_DECIMAL_0(ID INT PRIMARY KEY,VALUE DECIMAL(30,0))"); - stat.execute("CREATE TABLE T_DECIMAL_10(ID INT PRIMARY KEY,VALUE DECIMAL(20,10))"); - stat.execute("CREATE TABLE T_DATETIME(ID INT PRIMARY KEY,VALUE DATETIME)"); - prep = conn.prepareStatement("INSERT INTO T_INT VALUES(?,?)", ResultSet.TYPE_FORWARD_ONLY, - ResultSet.CONCUR_READ_ONLY); - prep.setInt(1, 1); - prep.setInt(2, 0); - prep.executeUpdate(); - prep.setInt(1, 2); - prep.setInt(2, -1); - prep.executeUpdate(); - prep.setInt(1, 3); - prep.setInt(2, 3); - prep.executeUpdate(); - prep.setInt(1, 4); - prep.setNull(2, Types.INTEGER); - prep.executeUpdate(); - prep.setInt(1, 5); - prep.setBigDecimal(2, new java.math.BigDecimal("0")); - prep.executeUpdate(); - prep.setInt(1, 6); - prep.setString(2, "-1"); - prep.executeUpdate(); - prep.setInt(1, 7); - prep.setObject(2, new Integer(3)); - prep.executeUpdate(); - prep.setObject(1, "8"); - // should throw an exception - prep.setObject(2, null); - // some databases don't allow calling setObject with null (no data type) - prep.executeUpdate(); - prep.setInt(1, 9); - prep.setObject(2, new Integer(-4), Types.VARCHAR); - prep.executeUpdate(); - prep.setInt(1, 10); - prep.setObject(2, "5", Types.INTEGER); - prep.executeUpdate(); - prep.setInt(1, 11); - prep.setObject(2, null, Types.INTEGER); - prep.executeUpdate(); - prep.setInt(1, 12); - prep.setBoolean(2, true); - prep.executeUpdate(); - prep.setInt(1, 13); - prep.setBoolean(2, false); - prep.executeUpdate(); - prep.setInt(1, 14); - prep.setByte(2, (byte) -20); - prep.executeUpdate(); - prep.setInt(1, 15); - prep.setByte(2, (byte) 100); - prep.executeUpdate(); - prep.setInt(1, 16); - prep.setShort(2, (short) 30000); - prep.executeUpdate(); - prep.setInt(1, 17); - prep.setShort(2, (short) (-30000)); - prep.executeUpdate(); - prep.setInt(1, 18); - prep.setLong(2, Integer.MAX_VALUE); - prep.executeUpdate(); - prep.setInt(1, 19); - prep.setLong(2, Integer.MIN_VALUE); - prep.executeUpdate(); - - assertTrue(stat.execute("SELECT * FROM T_INT ORDER BY ID")); - rs = stat.getResultSet(); - assertResultSetOrdered(rs, new String[][] { { "1", "0" }, { "2", "-1" }, { "3", "3" }, { "4", null }, - { "5", "0" }, { "6", "-1" }, { "7", "3" }, { "8", null }, { "9", "-4" }, { "10", "5" }, { "11", null }, - { "12", "1" }, { "13", "0" }, { "14", "-20" }, { "15", "100" }, { "16", "30000" }, { "17", "-30000" }, - { "18", "" + Integer.MAX_VALUE }, { "19", "" + Integer.MIN_VALUE }, }); - - prep = conn.prepareStatement("INSERT INTO T_DECIMAL_0 VALUES(?,?)"); - prep.setInt(1, 1); - prep.setLong(2, Long.MAX_VALUE); - prep.executeUpdate(); - prep.setInt(1, 2); - prep.setLong(2, Long.MIN_VALUE); - prep.executeUpdate(); - prep.setInt(1, 3); - prep.setFloat(2, 10); - prep.executeUpdate(); - prep.setInt(1, 4); - prep.setFloat(2, -20); - prep.executeUpdate(); - prep.setInt(1, 5); - prep.setFloat(2, 30); - prep.executeUpdate(); - prep.setInt(1, 6); - prep.setFloat(2, -40); - prep.executeUpdate(); - - rs = stat.executeQuery("SELECT VALUE FROM T_DECIMAL_0 ORDER BY ID"); - checkBigDecimal(rs, new String[] { "" + Long.MAX_VALUE, "" + Long.MIN_VALUE, "10", "-20", "30", "-40" }); - - // getMoreResults - stat.execute("CREATE TABLE TEST(ID INT)"); - stat.execute("INSERT INTO TEST VALUES(1)"); - prep = conn.prepareStatement("SELECT * FROM TEST"); - // just to check if it doesn't throw an exception - it may be null - prep.getMetaData(); - assertTrue(prep.execute()); - rs = prep.getResultSet(); - assertFalse(prep.getMoreResults()); - try { - // supposed to be closed now - rs.next(); - fail("getMoreResults didn't close this result set"); - } catch (SQLException e) { - trace("no error - getMoreResults is supposed to close the result set"); - } - assertTrue(prep.getUpdateCount() == -1); - prep = conn.prepareStatement("DELETE FROM TEST"); - prep.executeUpdate(); - assertFalse(prep.getMoreResults()); - assertTrue(prep.getUpdateCount() == -1); - } - - private void testObject(Connection conn) throws SQLException { - Statement stat = conn.createStatement(); - ResultSet rs; - stat.execute("CREATE TABLE TEST(ID INT PRIMARY KEY, NAME VARCHAR(255))"); - stat.execute("INSERT INTO TEST VALUES(1, 'Hello')"); - PreparedStatement prep = conn - .prepareStatement("SELECT ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ? FROM TEST"); - prep.setObject(1, new Boolean(true)); - prep.setObject(2, "Abc"); - prep.setObject(3, new BigDecimal("10.2")); - prep.setObject(4, new Byte((byte) 0xff)); - prep.setObject(5, new Short(Short.MAX_VALUE)); - prep.setObject(6, new Integer(Integer.MIN_VALUE)); - prep.setObject(7, new Long(Long.MAX_VALUE)); - prep.setObject(8, new Float(Float.MAX_VALUE)); - prep.setObject(9, new Double(Double.MAX_VALUE)); - prep.setObject(10, java.sql.Date.valueOf("2001-02-03")); - prep.setObject(11, java.sql.Time.valueOf("04:05:06")); - prep.setObject(12, java.sql.Timestamp.valueOf("2001-02-03 04:05:06.123456789")); - prep.setObject(13, new java.util.Date(java.sql.Date.valueOf("2001-02-03").getTime())); - prep.setObject(14, new byte[] { 10, 20, 30 }); - prep.setObject(15, new Character('a'), Types.OTHER); - prep.setObject(16, "2001-01-02", Types.DATE); - // converting to null seems strange... - prep.setObject(17, "2001-01-02", Types.NULL); - prep.setObject(18, "3.725", Types.DOUBLE); - prep.setObject(19, "23:22:21", Types.TIME); - prep.setObject(20, new java.math.BigInteger("12345"), Types.OTHER); - rs = prep.executeQuery(); - rs.next(); - assertTrue(rs.getObject(1).equals(new Boolean(true))); - assertTrue(rs.getObject(2).equals("Abc")); - assertTrue(rs.getObject(3).equals(new BigDecimal("10.2"))); - assertTrue(rs.getObject(4).equals(new Byte((byte) 0xff))); - assertTrue(rs.getObject(5).equals(new Short(Short.MAX_VALUE))); - assertTrue(rs.getObject(6).equals(new Integer(Integer.MIN_VALUE))); - assertTrue(rs.getObject(7).equals(new Long(Long.MAX_VALUE))); - assertTrue(rs.getObject(8).equals(new Float(Float.MAX_VALUE))); - assertTrue(rs.getObject(9).equals(new Double(Double.MAX_VALUE))); - assertTrue(rs.getObject(10).equals(java.sql.Date.valueOf("2001-02-03"))); - assertEquals("04:05:06", rs.getObject(11).toString()); - assertTrue(rs.getObject(11).equals(java.sql.Time.valueOf("04:05:06"))); - assertTrue(rs.getObject(12).equals(java.sql.Timestamp.valueOf("2001-02-03 04:05:06.123456789"))); - assertTrue(rs.getObject(13).equals(java.sql.Timestamp.valueOf("2001-02-03 00:00:00"))); - assertEquals(new byte[] { 10, 20, 30 }, (byte[]) rs.getObject(14)); - assertTrue(rs.getObject(15).equals(new Character('a'))); - assertTrue(rs.getObject(16).equals(java.sql.Date.valueOf("2001-01-02"))); - assertTrue(rs.getObject(17) == null && rs.wasNull()); - assertTrue(rs.getObject(18).equals(new Double(3.725))); - assertTrue(rs.getObject(19).equals(java.sql.Time.valueOf("23:22:21"))); - assertTrue(rs.getObject(20).equals(new java.math.BigInteger("12345"))); - - // } else if(x instanceof java.io.Reader) { - // return session.createLob(Value.CLOB, - // TypeConverter.getInputStream((java.io.Reader)x), 0); - // } else if(x instanceof java.io.InputStream) { - // return session.createLob(Value.BLOB, (java.io.InputStream)x, 0); - // } else { - // return ValueBytes.get(TypeConverter.serialize(x)); - - stat.execute("DROP TABLE TEST"); - - } - - private void testIdentity(Connection conn) throws SQLException { - Statement stat = conn.createStatement(); - stat.execute("CREATE SEQUENCE SEQ"); - stat.execute("CREATE TABLE TEST(ID INT)"); - PreparedStatement prep; - prep = conn.prepareStatement("INSERT INTO TEST VALUES(NEXT VALUE FOR SEQ)"); - prep.execute(); - ResultSet rs = prep.getGeneratedKeys(); - rs.next(); - assertEquals(1, rs.getInt(1)); - assertFalse(rs.next()); - prep = conn.prepareStatement("INSERT INTO TEST VALUES(NEXT VALUE FOR SEQ)", Statement.RETURN_GENERATED_KEYS); - prep.execute(); - rs = prep.getGeneratedKeys(); - rs.next(); - assertEquals(2, rs.getInt(1)); - assertFalse(rs.next()); - prep = conn.prepareStatement("INSERT INTO TEST VALUES(NEXT VALUE FOR SEQ)", new int[] { 1 }); - prep.execute(); - rs = prep.getGeneratedKeys(); - rs.next(); - assertEquals(3, rs.getInt(1)); - assertFalse(rs.next()); - prep = conn.prepareStatement("INSERT INTO TEST VALUES(NEXT VALUE FOR SEQ)", new String[] { "ID" }); - prep.execute(); - rs = prep.getGeneratedKeys(); - rs.next(); - assertEquals(4, rs.getInt(1)); - assertFalse(rs.next()); - stat.execute("DROP TABLE TEST"); - } - - private int getLength() { - return getSize(LOB_SIZE, LOB_SIZE_BIG); - } - - private void testBlob(Connection conn) throws SQLException { - trace("testBlob"); - Statement stat = conn.createStatement(); - PreparedStatement prep; - ResultSet rs; - stat.execute("CREATE TABLE T_BLOB(ID INT PRIMARY KEY,V1 BLOB,V2 BLOB)"); - trace("table created"); - prep = conn.prepareStatement("INSERT INTO T_BLOB VALUES(?,?,?)"); - - prep.setInt(1, 1); - prep.setBytes(2, null); - prep.setNull(3, Types.BINARY); - prep.executeUpdate(); - - prep.setInt(1, 2); - prep.setBinaryStream(2, null, 0); - prep.setNull(3, Types.BLOB); - prep.executeUpdate(); - - int length = getLength(); - byte[] big1 = new byte[length]; - byte[] big2 = new byte[length]; - for (int i = 0; i < big1.length; i++) { - big1[i] = (byte) ((i * 11) % 254); - big2[i] = (byte) ((i * 17) % 251); - } - - prep.setInt(1, 3); - prep.setBytes(2, big1); - prep.setBytes(3, big2); - prep.executeUpdate(); - - prep.setInt(1, 4); - ByteArrayInputStream buffer; - buffer = new ByteArrayInputStream(big2); - prep.setBinaryStream(2, buffer, big2.length); - buffer = new ByteArrayInputStream(big1); - prep.setBinaryStream(3, buffer, big1.length); - prep.executeUpdate(); - try { - buffer.close(); - trace("buffer not closed"); - } catch (IOException e) { - trace("buffer closed"); - } - - prep.setInt(1, 5); - buffer = new ByteArrayInputStream(big2); - prep.setObject(2, buffer, Types.BLOB, 0); - buffer = new ByteArrayInputStream(big1); - prep.setObject(3, buffer); - prep.executeUpdate(); - - rs = stat.executeQuery("SELECT ID, V1, V2 FROM T_BLOB ORDER BY ID"); - - rs.next(); - assertEquals(1, rs.getInt(1)); - assertTrue(rs.getBytes(2) == null && rs.wasNull()); - assertTrue(rs.getBytes(3) == null && rs.wasNull()); - - rs.next(); - assertEquals(2, rs.getInt(1)); - assertTrue(rs.getBytes(2) == null && rs.wasNull()); - assertTrue(rs.getBytes(3) == null && rs.wasNull()); - - rs.next(); - assertEquals(3, rs.getInt(1)); - assertEquals(big1, rs.getBytes(2)); - assertEquals(big2, rs.getBytes(3)); - - rs.next(); - assertEquals(4, rs.getInt(1)); - assertEquals(big2, rs.getBytes(2)); - assertEquals(big1, rs.getBytes(3)); - - rs.next(); - assertEquals(5, rs.getInt(1)); - assertEquals(big2, rs.getBytes(2)); - assertEquals(big1, rs.getBytes(3)); - - assertFalse(rs.next()); - } - - private void testClob(Connection conn) throws SQLException { - trace("testClob"); - Statement stat = conn.createStatement(); - PreparedStatement prep; - ResultSet rs; - stat.execute("CREATE TABLE T_CLOB(ID INT PRIMARY KEY,V1 CLOB,V2 CLOB)"); - StringBuilder asciiBuffer = new StringBuilder(); - int len = getLength(); - for (int i = 0; i < len; i++) { - asciiBuffer.append((char) ('a' + (i % 20))); - } - String ascii1 = asciiBuffer.toString(); - String ascii2 = "Number2 " + ascii1; - prep = conn.prepareStatement("INSERT INTO T_CLOB VALUES(?,?,?)"); - - prep.setInt(1, 1); - prep.setString(2, null); - prep.setNull(3, Types.CLOB); - prep.executeUpdate(); - - prep.clearParameters(); - prep.setInt(1, 2); - prep.setAsciiStream(2, null, 0); - prep.setCharacterStream(3, null, 0); - prep.executeUpdate(); - - prep.clearParameters(); - prep.setInt(1, 3); - prep.setCharacterStream(2, new StringReader(ascii1), ascii1.length()); - prep.setCharacterStream(3, null, 0); - prep.setAsciiStream(3, new ByteArrayInputStream(ascii2.getBytes()), ascii2.length()); - prep.executeUpdate(); - - prep.clearParameters(); - prep.setInt(1, 4); - prep.setNull(2, Types.CLOB); - prep.setString(2, ascii2); - prep.setCharacterStream(3, null, 0); - prep.setNull(3, Types.CLOB); - prep.setString(3, ascii1); - prep.executeUpdate(); - - prep.clearParameters(); - prep.setInt(1, 5); - prep.setObject(2, new StringReader(ascii1)); - prep.setObject(3, new StringReader(ascii2), Types.CLOB, 0); - prep.executeUpdate(); - - rs = stat.executeQuery("SELECT ID, V1, V2 FROM T_CLOB ORDER BY ID"); - - rs.next(); - assertEquals(1, rs.getInt(1)); - assertTrue(rs.getCharacterStream(2) == null && rs.wasNull()); - assertTrue(rs.getAsciiStream(3) == null && rs.wasNull()); - - rs.next(); - assertEquals(2, rs.getInt(1)); - assertTrue(rs.getString(2) == null && rs.wasNull()); - assertTrue(rs.getString(3) == null && rs.wasNull()); - - rs.next(); - assertEquals(3, rs.getInt(1)); - assertEquals(ascii1, rs.getString(2)); - assertEquals(ascii2, rs.getString(3)); - - rs.next(); - assertEquals(4, rs.getInt(1)); - assertEquals(ascii2, rs.getString(2)); - assertEquals(ascii1, rs.getString(3)); - - rs.next(); - assertEquals(5, rs.getInt(1)); - assertEquals(ascii1, rs.getString(2)); - assertEquals(ascii2, rs.getString(3)); - - assertFalse(rs.next()); - assertTrue(prep.getWarnings() == null); - prep.clearWarnings(); - assertTrue(prep.getWarnings() == null); - assertTrue(conn == prep.getConnection()); - } - - private void checkBigDecimal(ResultSet rs, String[] value) throws SQLException { - for (String v : value) { - assertTrue(rs.next()); - java.math.BigDecimal x = rs.getBigDecimal(1); - trace("v=" + v + " x=" + x); - if (v == null) { - assertTrue(x == null); - } else { - assertTrue(x.compareTo(new java.math.BigDecimal(v)) == 0); - } - } - assertTrue(!rs.next()); - } - -} diff --git a/tools/h2/src/test/org/h2/test/jdbc/TestResultSet.java b/tools/h2/src/test/org/h2/test/jdbc/TestResultSet.java deleted file mode 100755 index a214353..0000000 --- a/tools/h2/src/test/org/h2/test/jdbc/TestResultSet.java +++ /dev/null @@ -1,1140 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.test.jdbc; - -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.math.BigDecimal; -import java.math.BigInteger; -import java.sql.Array; -import java.sql.Connection; -import java.sql.DatabaseMetaData; -import java.sql.Date; -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.ResultSetMetaData; -import java.sql.SQLException; -import java.sql.Statement; -import java.sql.Time; -import java.sql.Timestamp; -import java.sql.Types; -import java.util.Calendar; -import java.util.Locale; -import java.util.TimeZone; - -import org.h2.constant.SysProperties; -import org.h2.test.TestBase; - -/** - * Tests for the ResultSet implementation. - */ -public class TestResultSet extends TestBase { - - private Connection conn; - private Statement stat; - - /** - * Run just this test. - * - * @param a ignored - */ - public static void main(String... a) throws Exception { - TestBase.createCaller().init().test(); - } - - public void test() throws SQLException { - deleteDb("resultSet"); - conn = getConnection("resultSet"); - - stat = conn.createStatement(); - - testBeforeFirstAfterLast(); - testParseSpecialValues(); - testSpecialLocale(); - testSubstringPrecision(); - testSubstringDataType(); - testColumnLabelColumnName(); - testAbsolute(); - testFetchSize(); - testOwnUpdates(); - testUpdatePrimaryKey(); - testFindColumn(); - testColumnLength(); - testArray(); - testLimitMaxRows(); - - trace("max rows=" + stat.getMaxRows()); - stat.setMaxRows(6); - trace("max rows after set to 6=" + stat.getMaxRows()); - assertTrue(stat.getMaxRows() == 6); - - testInt(); - testVarchar(); - testDecimal(); - testDoubleFloat(); - testDatetime(); - testDatetimeWithCalendar(); - testBlob(); - testClob(); - testAutoIncrement(); - - conn.close(); - deleteDb("resultSet"); - - } - - private void testBeforeFirstAfterLast() throws SQLException { - stat.executeUpdate("create table test(id int)"); - stat.executeUpdate("insert into test values(1)"); - // With a result - ResultSet rs = stat.executeQuery("select * from test"); - assertTrue(rs.isBeforeFirst()); - assertFalse(rs.isAfterLast()); - rs.next(); - assertFalse(rs.isBeforeFirst()); - assertFalse(rs.isAfterLast()); - rs.next(); - assertFalse(rs.isBeforeFirst()); - assertTrue(rs.isAfterLast()); - rs.close(); - // With no result - rs = stat.executeQuery("select * from test where 1 = 2"); - assertFalse(rs.isBeforeFirst()); - assertFalse(rs.isAfterLast()); - rs.next(); - assertFalse(rs.isBeforeFirst()); - assertFalse(rs.isAfterLast()); - rs.close(); - stat.execute("drop table test"); - } - - private void testParseSpecialValues() throws SQLException { - for (int i = -10; i < 10; i++) { - testParseSpecialValue("" + ((long) Integer.MIN_VALUE + i)); - testParseSpecialValue("" + ((long) Integer.MAX_VALUE + i)); - BigInteger bi = BigInteger.valueOf(i); - testParseSpecialValue(bi.add(BigInteger.valueOf(Long.MIN_VALUE)).toString()); - testParseSpecialValue(bi.add(BigInteger.valueOf(Long.MAX_VALUE)).toString()); - } - } - - private void testParseSpecialValue(String x) throws SQLException { - Object expected; - expected = new BigDecimal(x); - try { - expected = Long.decode(x); - expected = Integer.decode(x); - } catch (Exception e) { - // ignore - } - ResultSet rs = stat.executeQuery("call " + x); - rs.next(); - Object o = rs.getObject(1); - assertEquals(expected.getClass().getName(), o.getClass().getName()); - assertTrue(expected.equals(o)); - } - - private void testSpecialLocale() throws SQLException { - Locale old = Locale.getDefault(); - try { - // when using Turkish as the default locale, "i".toUpperCase() is not "I" - Locale.setDefault(new Locale("tr")); - stat.execute("create table test(I1 int, i2 int, b int, c int, d int) as select 1, 1, 1, 1, 1"); - ResultSet rs = stat.executeQuery("select * from test"); - rs.next(); - rs.getString("I1"); - rs.getString("i1"); - rs.getString("I2"); - rs.getString("i2"); - stat.execute("drop table test"); - } finally { - Locale.setDefault(old); - } - } - - private void testSubstringDataType() throws SQLException { - ResultSet rs = stat.executeQuery("select substr(x, 1, 1) from dual"); - rs.next(); - assertEquals(Types.VARCHAR, rs.getMetaData().getColumnType(1)); - } - - private void testColumnLabelColumnName() throws SQLException { - ResultSet rs = stat.executeQuery("select x as y from dual"); - rs.next(); - rs.getString("x"); - rs.getString("y"); - rs.close(); - rs = conn.getMetaData().getColumns(null, null, null, null); - ResultSetMetaData meta = rs.getMetaData(); - int columnCount = meta.getColumnCount(); - String[] columnName = new String[columnCount]; - for (int i = 1; i <= columnCount; i++) { - // columnName[i - 1] = meta.getColumnLabel(i); - columnName[i - 1] = meta.getColumnName(i); - } - while (rs.next()) { - for (int i = 0; i < columnCount; i++) { - rs.getObject(columnName[i]); - } - } - } - - private void testAbsolute() throws SQLException { - // stat.execute("SET MAX_MEMORY_ROWS 90"); - stat.execute("CREATE TABLE TEST(ID INT PRIMARY KEY)"); - // there was a problem when more than MAX_MEMORY_ROWS where in the result set - stat.execute("INSERT INTO TEST SELECT X FROM SYSTEM_RANGE(1, 200)"); - Statement s2 = conn.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY); - ResultSet rs = s2.executeQuery("SELECT * FROM TEST ORDER BY ID"); - for (int i = 100; i > 0; i--) { - rs.absolute(i); - assertEquals(i, rs.getInt(1)); - } - stat.execute("DROP TABLE TEST"); - } - - private void testFetchSize() throws SQLException { - if (!config.networked || config.memory) { - return; - } - ResultSet rs = stat.executeQuery("SELECT * FROM SYSTEM_RANGE(1, 100)"); - int a = stat.getFetchSize(); - int b = rs.getFetchSize(); - assertEquals(a, b); - rs.setFetchSize(b + 1); - b = rs.getFetchSize(); - assertEquals(a + 1, b); - } - - private void testOwnUpdates() throws SQLException { - DatabaseMetaData meta = conn.getMetaData(); - for (int i = 0; i < 3; i++) { - int type = i == 0 ? ResultSet.TYPE_FORWARD_ONLY : i == 1 ? ResultSet.TYPE_SCROLL_INSENSITIVE : ResultSet.TYPE_SCROLL_SENSITIVE; - assertTrue(meta.ownUpdatesAreVisible(type)); - assertFalse(meta.ownDeletesAreVisible(type)); - assertFalse(meta.ownInsertsAreVisible(type)); - } - stat = conn.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, - ResultSet.CONCUR_UPDATABLE); - stat.execute("CREATE TABLE TEST(ID INT PRIMARY KEY, NAME VARCHAR(255))"); - stat.execute("INSERT INTO TEST VALUES(1, 'Hello')"); - stat.execute("INSERT INTO TEST VALUES(2, 'World')"); - ResultSet rs; - rs = stat.executeQuery("SELECT ID, NAME FROM TEST ORDER BY ID"); - rs.next(); - rs.next(); - rs.updateString(2, "Hallo"); - rs.updateRow(); - assertEquals("Hallo", rs.getString(2)); - stat.execute("DROP TABLE TEST"); - } - - private void testUpdatePrimaryKey() throws SQLException { - stat = conn.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, - ResultSet.CONCUR_UPDATABLE); - stat.execute("CREATE TABLE TEST(ID INT PRIMARY KEY, NAME VARCHAR(255))"); - stat.execute("INSERT INTO TEST VALUES(1, 'Hello')"); - ResultSet rs = stat.executeQuery("SELECT * FROM TEST"); - rs.next(); - rs.updateInt(1, 2); - rs.updateRow(); - rs.updateInt(1, 3); - rs.updateRow(); - stat.execute("DROP TABLE TEST"); - } - - private void checkPrecision(int expected, String sql) throws SQLException { - ResultSetMetaData meta = stat.executeQuery(sql).getMetaData(); - assertEquals(expected, meta.getPrecision(1)); - } - - private void testSubstringPrecision() throws SQLException { - trace("testSubstringPrecision"); - stat.execute("CREATE TABLE TEST(ID INT, NAME VARCHAR(10))"); - stat.execute("INSERT INTO TEST VALUES(1, 'Hello'), (2, 'WorldPeace')"); - checkPrecision(0, "SELECT SUBSTR(NAME, 12, 4) FROM TEST"); - checkPrecision(9, "SELECT SUBSTR(NAME, 2) FROM TEST"); - checkPrecision(10, "SELECT SUBSTR(NAME, ID) FROM TEST"); - checkPrecision(4, "SELECT SUBSTR(NAME, 2, 4) FROM TEST"); - checkPrecision(3, "SELECT SUBSTR(NAME, 8, 4) FROM TEST"); - checkPrecision(4, "SELECT SUBSTR(NAME, 7, 4) FROM TEST"); - checkPrecision(8, "SELECT SUBSTR(NAME, 3, ID*0) FROM TEST"); - stat.execute("DROP TABLE TEST"); - } - - private void testFindColumn() throws SQLException { - trace("testFindColumn"); - ResultSet rs; - stat.execute("CREATE TABLE TEST(ID INT, NAME VARCHAR)"); - rs = stat.executeQuery("SELECT * FROM TEST"); - assertEquals(1, rs.findColumn("ID")); - assertEquals(2, rs.findColumn("NAME")); - assertEquals(1, rs.findColumn("id")); - assertEquals(2, rs.findColumn("name")); - assertEquals(1, rs.findColumn("Id")); - assertEquals(2, rs.findColumn("Name")); - assertEquals(1, rs.findColumn("TEST.ID")); - assertEquals(2, rs.findColumn("TEST.NAME")); - assertEquals(1, rs.findColumn("Test.Id")); - assertEquals(2, rs.findColumn("Test.Name")); - stat.execute("DROP TABLE TEST"); - - stat.execute("CREATE TABLE TEST(ID INT, NAME VARCHAR, DATA VARCHAR)"); - rs = stat.executeQuery("SELECT * FROM TEST"); - assertEquals(1, rs.findColumn("ID")); - assertEquals(2, rs.findColumn("NAME")); - assertEquals(3, rs.findColumn("DATA")); - assertEquals(1, rs.findColumn("id")); - assertEquals(2, rs.findColumn("name")); - assertEquals(3, rs.findColumn("data")); - assertEquals(1, rs.findColumn("Id")); - assertEquals(2, rs.findColumn("Name")); - assertEquals(3, rs.findColumn("Data")); - assertEquals(1, rs.findColumn("TEST.ID")); - assertEquals(2, rs.findColumn("TEST.NAME")); - assertEquals(3, rs.findColumn("TEST.DATA")); - assertEquals(1, rs.findColumn("Test.Id")); - assertEquals(2, rs.findColumn("Test.Name")); - assertEquals(3, rs.findColumn("Test.Data")); - stat.execute("DROP TABLE TEST"); - - } - - private void testColumnLength() throws SQLException { - trace("testColumnDisplayLength"); - ResultSet rs; - ResultSetMetaData meta; - - stat.execute("CREATE TABLE one (ID INT, NAME VARCHAR(255))"); - rs = stat.executeQuery("select * from one"); - meta = rs.getMetaData(); - assertEquals("ID", meta.getColumnLabel(1)); - assertEquals(11, meta.getColumnDisplaySize(1)); - assertEquals("NAME", meta.getColumnLabel(2)); - assertEquals(255, meta.getColumnDisplaySize(2)); - stat.execute("DROP TABLE one"); - - rs = stat.executeQuery("select 1, 'Hello' union select 2, 'Hello World!'"); - meta = rs.getMetaData(); - assertEquals(11, meta.getColumnDisplaySize(1)); - assertEquals(12, meta.getColumnDisplaySize(2)); - - rs = stat.executeQuery("explain select * from dual"); - meta = rs.getMetaData(); - assertEquals(Integer.MAX_VALUE, meta.getColumnDisplaySize(1)); - assertEquals(Integer.MAX_VALUE, meta.getPrecision(1)); - - rs = stat.executeQuery("script"); - meta = rs.getMetaData(); - assertEquals(Integer.MAX_VALUE, meta.getColumnDisplaySize(1)); - assertEquals(Integer.MAX_VALUE, meta.getPrecision(1)); - - rs = stat.executeQuery("select group_concat(table_name) from information_schema.tables"); - rs.next(); - meta = rs.getMetaData(); - assertEquals(Integer.MAX_VALUE, meta.getColumnDisplaySize(1)); - assertEquals(Integer.MAX_VALUE, meta.getPrecision(1)); - - } - - private void testLimitMaxRows() throws SQLException { - trace("Test LimitMaxRows"); - ResultSet rs; - stat.execute("CREATE TABLE one (C CHARACTER(10))"); - rs = stat.executeQuery("SELECT C || C FROM one;"); - ResultSetMetaData md = rs.getMetaData(); - assertEquals(20, md.getPrecision(1)); - ResultSet rs2 = stat.executeQuery("SELECT UPPER (C) FROM one;"); - ResultSetMetaData md2 = rs2.getMetaData(); - assertEquals(10, md2.getPrecision(1)); - rs = stat.executeQuery("SELECT UPPER (C), CHAR(10), CONCAT(C,C,C), HEXTORAW(C), RAWTOHEX(C) FROM one"); - ResultSetMetaData meta = rs.getMetaData(); - assertEquals(10, meta.getPrecision(1)); - assertEquals(1, meta.getPrecision(2)); - assertEquals(30, meta.getPrecision(3)); - assertEquals(3, meta.getPrecision(4)); - assertEquals(40, meta.getPrecision(5)); - stat.execute("DROP TABLE one"); - } - - private void testAutoIncrement() throws SQLException { - trace("Test AutoIncrement"); - stat.execute("DROP TABLE IF EXISTS TEST"); - ResultSet rs; - stat.execute("CREATE TABLE TEST(ID IDENTITY NOT NULL, NAME VARCHAR NULL)"); - - stat.execute("INSERT INTO TEST(NAME) VALUES('Hello')"); - rs = stat.getGeneratedKeys(); - assertTrue(rs.next()); - assertEquals(1, rs.getInt(1)); - - stat.execute("INSERT INTO TEST(NAME) VALUES('World')"); - rs = stat.getGeneratedKeys(); - assertTrue(rs.next()); - assertEquals(2, rs.getInt(1)); - - rs = stat.executeQuery("SELECT ID AS I, NAME AS N, ID+1 AS IP1 FROM TEST"); - ResultSetMetaData meta = rs.getMetaData(); - assertTrue(meta.isAutoIncrement(1)); - assertFalse(meta.isAutoIncrement(2)); - assertFalse(meta.isAutoIncrement(3)); - assertEquals(ResultSetMetaData.columnNoNulls, meta.isNullable(1)); - assertEquals(ResultSetMetaData.columnNullable, meta.isNullable(2)); - assertEquals(ResultSetMetaData.columnNullableUnknown, meta.isNullable(3)); - assertTrue(rs.next()); - assertTrue(rs.next()); - assertFalse(rs.next()); - - } - - private void testInt() throws SQLException { - trace("Test INT"); - ResultSet rs; - Object o; - - stat.execute("CREATE TABLE TEST(ID INT PRIMARY KEY,VALUE INT)"); - stat.execute("INSERT INTO TEST VALUES(1,-1)"); - stat.execute("INSERT INTO TEST VALUES(2,0)"); - stat.execute("INSERT INTO TEST VALUES(3,1)"); - stat.execute("INSERT INTO TEST VALUES(4," + Integer.MAX_VALUE + ")"); - stat.execute("INSERT INTO TEST VALUES(5," + Integer.MIN_VALUE + ")"); - stat.execute("INSERT INTO TEST VALUES(6,NULL)"); - // this should not be read - maxrows=6 - stat.execute("INSERT INTO TEST VALUES(7,NULL)"); - - // MySQL compatibility (is this required?) - // rs=stat.executeQuery("SELECT * FROM TEST T ORDER BY ID"); - // check(rs.findColumn("T.ID"), 1); - // check(rs.findColumn("T.NAME"), 2); - - rs = stat.executeQuery("SELECT *, NULL AS N FROM TEST ORDER BY ID"); - - // MySQL compatibility - assertEquals(1, rs.findColumn("TEST.ID")); - assertEquals(2, rs.findColumn("TEST.VALUE")); - - ResultSetMetaData meta = rs.getMetaData(); - assertEquals(3, meta.getColumnCount()); - assertEquals("resultSet".toUpperCase(), meta.getCatalogName(1)); - assertTrue("PUBLIC".equals(meta.getSchemaName(2))); - assertTrue("TEST".equals(meta.getTableName(1))); - assertTrue("ID".equals(meta.getColumnName(1))); - assertTrue("VALUE".equals(meta.getColumnName(2))); - assertTrue(!meta.isAutoIncrement(1)); - assertTrue(meta.isCaseSensitive(1)); - assertTrue(meta.isSearchable(1)); - assertFalse(meta.isCurrency(1)); - assertTrue(meta.getColumnDisplaySize(1) > 0); - assertTrue(meta.isSigned(1)); - assertTrue(meta.isSearchable(2)); - assertEquals(ResultSetMetaData.columnNoNulls, meta.isNullable(1)); - assertFalse(meta.isReadOnly(1)); - assertTrue(meta.isWritable(1)); - assertFalse(meta.isDefinitelyWritable(1)); - assertTrue(meta.getColumnDisplaySize(1) > 0); - assertTrue(meta.getColumnDisplaySize(2) > 0); - assertEquals(null, meta.getColumnClassName(3)); - - assertTrue(rs.getRow() == 0); - assertResultSetMeta(rs, 3, new String[] { "ID", "VALUE", "N" }, new int[] { Types.INTEGER, Types.INTEGER, - Types.NULL }, new int[] { 10, 10, 1 }, new int[] { 0, 0, 0 }); - rs.next(); - assertEquals(ResultSet.CONCUR_READ_ONLY, rs.getConcurrency()); - assertEquals(ResultSet.FETCH_FORWARD, rs.getFetchDirection()); - trace("default fetch size=" + rs.getFetchSize()); - // 0 should be an allowed value (but it's not defined what is actually - // means) - rs.setFetchSize(0); - trace("after set to 0, fetch size=" + rs.getFetchSize()); - // this should break - try { - rs.setFetchSize(-1); - fail("fetch size -1 is not allowed"); - } catch (SQLException e) { - assertKnownException(e); - trace(e.toString()); - } - trace("after try to set to -1, fetch size=" + rs.getFetchSize()); - try { - rs.setFetchSize(100); - fail("fetch size 100 is bigger than maxrows - not allowed"); - } catch (SQLException e) { - assertKnownException(e); - trace(e.toString()); - } - trace("after try set to 100, fetch size=" + rs.getFetchSize()); - rs.setFetchSize(6); - - assertTrue(rs.getRow() == 1); - assertEquals(2, rs.findColumn("VALUE")); - assertEquals(2, rs.findColumn("value")); - assertEquals(2, rs.findColumn("Value")); - assertEquals(2, rs.findColumn("Value")); - assertEquals(1, rs.findColumn("ID")); - assertEquals(1, rs.findColumn("id")); - assertEquals(1, rs.findColumn("Id")); - assertEquals(1, rs.findColumn("iD")); - assertTrue(rs.getInt(2) == -1 && !rs.wasNull()); - assertTrue(rs.getInt("VALUE") == -1 && !rs.wasNull()); - assertTrue(rs.getInt("value") == -1 && !rs.wasNull()); - assertTrue(rs.getInt("Value") == -1 && !rs.wasNull()); - assertTrue(rs.getString("Value").equals("-1") && !rs.wasNull()); - - o = rs.getObject("value"); - trace(o.getClass().getName()); - assertTrue(o instanceof Integer); - assertTrue(((Integer) o).intValue() == -1); - o = rs.getObject(2); - trace(o.getClass().getName()); - assertTrue(o instanceof Integer); - assertTrue(((Integer) o).intValue() == -1); - assertTrue(rs.getBoolean("Value")); - assertTrue(rs.getByte("Value") == (byte) -1); - assertTrue(rs.getShort("Value") == (short) -1); - assertTrue(rs.getLong("Value") == -1); - assertTrue(rs.getFloat("Value") == -1.0); - assertTrue(rs.getDouble("Value") == -1.0); - - assertTrue(rs.getString("Value").equals("-1") && !rs.wasNull()); - assertTrue(rs.getInt("ID") == 1 && !rs.wasNull()); - assertTrue(rs.getInt("id") == 1 && !rs.wasNull()); - assertTrue(rs.getInt("Id") == 1 && !rs.wasNull()); - assertTrue(rs.getInt(1) == 1 && !rs.wasNull()); - rs.next(); - assertTrue(rs.getRow() == 2); - assertTrue(rs.getInt(2) == 0 && !rs.wasNull()); - assertTrue(!rs.getBoolean(2)); - assertTrue(rs.getByte(2) == 0); - assertTrue(rs.getShort(2) == 0); - assertTrue(rs.getLong(2) == 0); - assertTrue(rs.getFloat(2) == 0.0); - assertTrue(rs.getDouble(2) == 0.0); - assertTrue(rs.getString(2).equals("0") && !rs.wasNull()); - assertTrue(rs.getInt(1) == 2 && !rs.wasNull()); - rs.next(); - assertTrue(rs.getRow() == 3); - assertTrue(rs.getInt("ID") == 3 && !rs.wasNull()); - assertTrue(rs.getInt("VALUE") == 1 && !rs.wasNull()); - rs.next(); - assertTrue(rs.getRow() == 4); - assertTrue(rs.getInt("ID") == 4 && !rs.wasNull()); - assertTrue(rs.getInt("VALUE") == Integer.MAX_VALUE && !rs.wasNull()); - rs.next(); - assertTrue(rs.getRow() == 5); - assertTrue(rs.getInt("id") == 5 && !rs.wasNull()); - assertTrue(rs.getInt("value") == Integer.MIN_VALUE && !rs.wasNull()); - assertTrue(rs.getString(1).equals("5") && !rs.wasNull()); - rs.next(); - assertTrue(rs.getRow() == 6); - assertTrue(rs.getInt("id") == 6 && !rs.wasNull()); - assertTrue(rs.getInt("value") == 0 && rs.wasNull()); - assertTrue(rs.getInt(2) == 0 && rs.wasNull()); - assertTrue(rs.getInt(1) == 6 && !rs.wasNull()); - assertTrue(rs.getString(1).equals("6") && !rs.wasNull()); - assertTrue(rs.getString(2) == null && rs.wasNull()); - o = rs.getObject(2); - assertTrue(o == null); - assertTrue(rs.wasNull()); - assertFalse(rs.next()); - assertEquals(0, rs.getRow()); - // there is one more row, but because of setMaxRows we don't get it - - stat.execute("DROP TABLE TEST"); - stat.setMaxRows(0); - } - - private void testVarchar() throws SQLException { - trace("Test VARCHAR"); - ResultSet rs; - Object o; - - stat.execute("CREATE TABLE TEST(ID INT PRIMARY KEY,VALUE VARCHAR(255))"); - stat.execute("INSERT INTO TEST VALUES(1,'')"); - stat.execute("INSERT INTO TEST VALUES(2,' ')"); - stat.execute("INSERT INTO TEST VALUES(3,' ')"); - stat.execute("INSERT INTO TEST VALUES(4,NULL)"); - stat.execute("INSERT INTO TEST VALUES(5,'Hi')"); - stat.execute("INSERT INTO TEST VALUES(6,' Hi ')"); - stat.execute("INSERT INTO TEST VALUES(7,'Joe''s')"); - stat.execute("INSERT INTO TEST VALUES(8,'{escape}')"); - stat.execute("INSERT INTO TEST VALUES(9,'\\n')"); - stat.execute("INSERT INTO TEST VALUES(10,'\\''')"); - stat.execute("INSERT INTO TEST VALUES(11,'\\%')"); - rs = stat.executeQuery("SELECT * FROM TEST ORDER BY ID"); - assertResultSetMeta(rs, 2, new String[] { "ID", "VALUE" }, new int[] { Types.INTEGER, Types.VARCHAR }, new int[] { - 10, 255 }, new int[] { 0, 0 }); - String value; - rs.next(); - value = rs.getString(2); - trace("Value: <" + value + "> (should be: <>)"); - assertTrue(value != null && value.equals("") && !rs.wasNull()); - assertTrue(rs.getInt(1) == 1 && !rs.wasNull()); - rs.next(); - value = rs.getString(2); - trace("Value: <" + value + "> (should be: < >)"); - assertTrue(rs.getString(2).equals(" ") && !rs.wasNull()); - assertTrue(rs.getInt(1) == 2 && !rs.wasNull()); - rs.next(); - value = rs.getString(2); - trace("Value: <" + value + "> (should be: < >)"); - assertTrue(rs.getString(2).equals(" ") && !rs.wasNull()); - assertTrue(rs.getInt(1) == 3 && !rs.wasNull()); - rs.next(); - value = rs.getString(2); - trace("Value: <" + value + "> (should be: )"); - assertTrue(rs.getString(2) == null && rs.wasNull()); - assertTrue(rs.getInt(1) == 4 && !rs.wasNull()); - rs.next(); - value = rs.getString(2); - trace("Value: <" + value + "> (should be: )"); - assertTrue(rs.getInt(1) == 5 && !rs.wasNull()); - assertTrue(rs.getString(2).equals("Hi") && !rs.wasNull()); - o = rs.getObject("value"); - trace(o.getClass().getName()); - assertTrue(o instanceof String); - assertTrue(o.toString().equals("Hi")); - rs.next(); - value = rs.getString(2); - trace("Value: <" + value + "> (should be: < Hi >)"); - assertTrue(rs.getInt(1) == 6 && !rs.wasNull()); - assertTrue(rs.getString(2).equals(" Hi ") && !rs.wasNull()); - rs.next(); - value = rs.getString(2); - trace("Value: <" + value + "> (should be: )"); - assertTrue(rs.getInt(1) == 7 && !rs.wasNull()); - assertTrue(rs.getString(2).equals("Joe's") && !rs.wasNull()); - rs.next(); - value = rs.getString(2); - trace("Value: <" + value + "> (should be: <{escape}>)"); - assertTrue(rs.getInt(1) == 8 && !rs.wasNull()); - assertTrue(rs.getString(2).equals("{escape}") && !rs.wasNull()); - rs.next(); - value = rs.getString(2); - trace("Value: <" + value + "> (should be: <\\n>)"); - assertTrue(rs.getInt(1) == 9 && !rs.wasNull()); - assertTrue(rs.getString(2).equals("\\n") && !rs.wasNull()); - rs.next(); - value = rs.getString(2); - trace("Value: <" + value + "> (should be: <\\'>)"); - assertTrue(rs.getInt(1) == 10 && !rs.wasNull()); - assertTrue(rs.getString(2).equals("\\'") && !rs.wasNull()); - rs.next(); - value = rs.getString(2); - trace("Value: <" + value + "> (should be: <\\%>)"); - assertTrue(rs.getInt(1) == 11 && !rs.wasNull()); - assertTrue(rs.getString(2).equals("\\%") && !rs.wasNull()); - assertTrue(!rs.next()); - stat.execute("DROP TABLE TEST"); - } - - private void testDecimal() throws SQLException { - trace("Test DECIMAL"); - ResultSet rs; - Object o; - - stat.execute("CREATE TABLE TEST(ID INT PRIMARY KEY,VALUE DECIMAL(10,2))"); - stat.execute("INSERT INTO TEST VALUES(1,-1)"); - stat.execute("INSERT INTO TEST VALUES(2,.0)"); - stat.execute("INSERT INTO TEST VALUES(3,1.)"); - stat.execute("INSERT INTO TEST VALUES(4,12345678.89)"); - stat.execute("INSERT INTO TEST VALUES(6,99999998.99)"); - stat.execute("INSERT INTO TEST VALUES(7,-99999998.99)"); - stat.execute("INSERT INTO TEST VALUES(8,NULL)"); - rs = stat.executeQuery("SELECT * FROM TEST ORDER BY ID"); - assertResultSetMeta(rs, 2, new String[] { "ID", "VALUE" }, new int[] { Types.INTEGER, Types.DECIMAL }, new int[] { - 10, 10 }, new int[] { 0, 2 }); - BigDecimal bd; - rs.next(); - assertTrue(rs.getInt(1) == 1); - assertTrue(!rs.wasNull()); - assertTrue(rs.getInt(2) == -1); - assertTrue(!rs.wasNull()); - bd = rs.getBigDecimal(2); - assertTrue(bd.compareTo(new BigDecimal("-1.00")) == 0); - assertTrue(!rs.wasNull()); - o = rs.getObject(2); - trace(o.getClass().getName()); - assertTrue(o instanceof BigDecimal); - assertTrue(((BigDecimal) o).compareTo(new BigDecimal("-1.00")) == 0); - rs.next(); - assertTrue(rs.getInt(1) == 2); - assertTrue(!rs.wasNull()); - assertTrue(rs.getInt(2) == 0); - assertTrue(!rs.wasNull()); - bd = rs.getBigDecimal(2); - assertTrue(bd.compareTo(new BigDecimal("0.00")) == 0); - assertTrue(!rs.wasNull()); - rs.next(); - checkColumnBigDecimal(rs, 2, 1, "1.00"); - rs.next(); - checkColumnBigDecimal(rs, 2, 12345679, "12345678.89"); - rs.next(); - checkColumnBigDecimal(rs, 2, 99999999, "99999998.99"); - rs.next(); - checkColumnBigDecimal(rs, 2, -99999999, "-99999998.99"); - rs.next(); - checkColumnBigDecimal(rs, 2, 0, null); - assertTrue(!rs.next()); - stat.execute("DROP TABLE TEST"); - } - - private void testDoubleFloat() throws SQLException { - trace("Test DOUBLE - FLOAT"); - ResultSet rs; - Object o; - - stat.execute("CREATE TABLE TEST(ID INT PRIMARY KEY, D DOUBLE, R REAL)"); - stat.execute("INSERT INTO TEST VALUES(1, -1, -1)"); - stat.execute("INSERT INTO TEST VALUES(2,.0, .0)"); - stat.execute("INSERT INTO TEST VALUES(3, 1., 1.)"); - stat.execute("INSERT INTO TEST VALUES(4, 12345678.89, 12345678.89)"); - stat.execute("INSERT INTO TEST VALUES(6, 99999999.99, 99999999.99)"); - stat.execute("INSERT INTO TEST VALUES(7, -99999999.99, -99999999.99)"); - stat.execute("INSERT INTO TEST VALUES(8, NULL, NULL)"); - rs = stat.executeQuery("SELECT * FROM TEST ORDER BY ID"); - assertResultSetMeta(rs, 3, new String[] { "ID", "D", "R" }, - new int[] { Types.INTEGER, Types.DOUBLE, Types.REAL }, new int[] { 10, 17, 7 }, new int[] { 0, 0, 0 }); - BigDecimal bd; - rs.next(); - assertTrue(rs.getInt(1) == 1); - assertTrue(!rs.wasNull()); - assertTrue(rs.getInt(2) == -1); - assertTrue(rs.getInt(3) == -1); - assertTrue(!rs.wasNull()); - bd = rs.getBigDecimal(2); - assertTrue(bd.compareTo(new BigDecimal("-1.00")) == 0); - assertTrue(!rs.wasNull()); - o = rs.getObject(2); - trace(o.getClass().getName()); - assertTrue(o instanceof Double); - assertTrue(((Double) o).compareTo(new Double("-1.00")) == 0); - o = rs.getObject(3); - trace(o.getClass().getName()); - assertTrue(o instanceof Float); - assertTrue(((Float) o).compareTo(new Float("-1.00")) == 0); - rs.next(); - assertTrue(rs.getInt(1) == 2); - assertTrue(!rs.wasNull()); - assertTrue(rs.getInt(2) == 0); - assertTrue(!rs.wasNull()); - assertTrue(rs.getInt(3) == 0); - assertTrue(!rs.wasNull()); - bd = rs.getBigDecimal(2); - assertTrue(bd.compareTo(new BigDecimal("0.00")) == 0); - assertTrue(!rs.wasNull()); - bd = rs.getBigDecimal(3); - assertTrue(bd.compareTo(new BigDecimal("0.00")) == 0); - assertTrue(!rs.wasNull()); - rs.next(); - assertEquals(1.0, rs.getDouble(2)); - assertEquals(1.0f, rs.getFloat(3)); - rs.next(); - assertEquals(12345678.89, rs.getDouble(2)); - assertEquals(12345678.89f, rs.getFloat(3)); - rs.next(); - assertEquals(99999999.99, rs.getDouble(2)); - assertEquals(99999999.99f, rs.getFloat(3)); - rs.next(); - assertEquals(-99999999.99, rs.getDouble(2)); - assertEquals(-99999999.99f, rs.getFloat(3)); - rs.next(); - checkColumnBigDecimal(rs, 2, 0, null); - checkColumnBigDecimal(rs, 3, 0, null); - assertTrue(!rs.next()); - stat.execute("DROP TABLE TEST"); - } - - private void testDatetime() throws SQLException { - trace("Test DATETIME"); - ResultSet rs; - Object o; - - rs = stat.executeQuery("call date '99999-12-23'"); - rs.next(); - assertEquals("99999-12-23", rs.getString(1)); - rs = stat.executeQuery("call timestamp '99999-12-23 01:02:03.000'"); - rs.next(); - assertEquals("99999-12-23 01:02:03.0", rs.getString(1)); - rs = stat.executeQuery("call date '-99999-12-23'"); - rs.next(); - assertEquals("-99999-12-23", rs.getString(1)); - rs = stat.executeQuery("call timestamp '-99999-12-23 01:02:03.000'"); - rs.next(); - assertEquals("-99999-12-23 01:02:03.0", rs.getString(1)); - - stat.execute("CREATE TABLE TEST(ID INT PRIMARY KEY,VALUE DATETIME)"); - stat.execute("INSERT INTO TEST VALUES(1,DATE '2011-11-11')"); - stat.execute("INSERT INTO TEST VALUES(2,TIMESTAMP '2002-02-02 02:02:02')"); - stat.execute("INSERT INTO TEST VALUES(3,TIMESTAMP '1800-1-1 0:0:0')"); - stat.execute("INSERT INTO TEST VALUES(4,TIMESTAMP '9999-12-31 23:59:59')"); - stat.execute("INSERT INTO TEST VALUES(5,NULL)"); - rs = stat.executeQuery("SELECT 0 ID, TIMESTAMP '9999-12-31 23:59:59' VALUE FROM TEST ORDER BY ID"); - assertResultSetMeta(rs, 2, new String[] { "ID", "VALUE" }, new int[] { Types.INTEGER, Types.TIMESTAMP }, - new int[] { 10, 23 }, new int[] { 0, 10 }); - rs = stat.executeQuery("SELECT * FROM TEST ORDER BY ID"); - assertResultSetMeta(rs, 2, new String[] { "ID", "VALUE" }, new int[] { Types.INTEGER, Types.TIMESTAMP }, - new int[] { 10, 23 }, new int[] { 0, 10 }); - rs.next(); - java.sql.Date date; - java.sql.Time time; - java.sql.Timestamp ts; - date = rs.getDate(2); - assertTrue(!rs.wasNull()); - time = rs.getTime(2); - assertTrue(!rs.wasNull()); - ts = rs.getTimestamp(2); - assertTrue(!rs.wasNull()); - trace("Date: " + date.toString() + " Time:" + time.toString() + " Timestamp:" + ts.toString()); - trace("Date ms: " + date.getTime() + " Time ms:" + time.getTime() + " Timestamp ms:" + ts.getTime()); - trace("1970 ms: " + java.sql.Timestamp.valueOf("1970-01-01 00:00:00.0").getTime()); - assertEquals(java.sql.Timestamp.valueOf("2011-11-11 00:00:00.0").getTime(), date.getTime()); - assertEquals(java.sql.Timestamp.valueOf("1970-01-01 00:00:00.0").getTime(), time.getTime()); - assertEquals(java.sql.Timestamp.valueOf("2011-11-11 00:00:00.0").getTime(), ts.getTime()); - assertTrue(date.equals(java.sql.Date.valueOf("2011-11-11"))); - assertTrue(time.equals(java.sql.Time.valueOf("00:00:00"))); - assertTrue(ts.equals(java.sql.Timestamp.valueOf("2011-11-11 00:00:00.0"))); - assertFalse(rs.wasNull()); - o = rs.getObject(2); - trace(o.getClass().getName()); - assertTrue(o instanceof java.sql.Timestamp); - assertTrue(((java.sql.Timestamp) o).equals(java.sql.Timestamp.valueOf("2011-11-11 00:00:00.0"))); - assertFalse(rs.wasNull()); - rs.next(); - - date = rs.getDate("VALUE"); - assertTrue(!rs.wasNull()); - time = rs.getTime("VALUE"); - assertTrue(!rs.wasNull()); - ts = rs.getTimestamp("VALUE"); - assertTrue(!rs.wasNull()); - trace("Date: " + date.toString() + " Time:" + time.toString() + " Timestamp:" + ts.toString()); - assertEquals("2002-02-02", date.toString()); - assertEquals("02:02:02", time.toString()); - assertEquals("2002-02-02 02:02:02.0", ts.toString()); - rs.next(); - assertEquals("1800-01-01", rs.getDate("value").toString()); - assertEquals("00:00:00", rs.getTime("value").toString()); - assertEquals("1800-01-01 00:00:00.0", rs.getTimestamp("value").toString()); - rs.next(); - assertEquals("9999-12-31", rs.getDate("Value").toString()); - assertEquals("23:59:59", rs.getTime("Value").toString()); - assertEquals("9999-12-31 23:59:59.0", rs.getTimestamp("Value").toString()); - rs.next(); - assertTrue(rs.getDate("Value") == null && rs.wasNull()); - assertTrue(rs.getTime("vALUe") == null && rs.wasNull()); - assertTrue(rs.getTimestamp(2) == null && rs.wasNull()); - assertTrue(!rs.next()); - - rs = stat - .executeQuery("SELECT DATE '2001-02-03' D, TIME '14:15:16', TIMESTAMP '2007-08-09 10:11:12.141516171' TS FROM TEST"); - rs.next(); - date = (Date) rs.getObject(1); - time = (Time) rs.getObject(2); - ts = (Timestamp) rs.getObject(3); - assertEquals("2001-02-03", date.toString()); - assertEquals("14:15:16", time.toString()); - assertEquals("2007-08-09 10:11:12.141516171", ts.toString()); - - stat.execute("DROP TABLE TEST"); - } - - private void testDatetimeWithCalendar() throws SQLException { - trace("Test DATETIME with Calendar"); - ResultSet rs; - - stat.execute("CREATE TABLE TEST(ID INT PRIMARY KEY, D DATE, T TIME, TS TIMESTAMP)"); - PreparedStatement prep = conn.prepareStatement("INSERT INTO TEST VALUES(?, ?, ?, ?)"); - Calendar regular = Calendar.getInstance(); - Calendar other = null; - // search a locale that has a _different_ raw offset - long testTime = java.sql.Date.valueOf("2001-02-03").getTime(); - for (String s : TimeZone.getAvailableIDs()) { - TimeZone zone = TimeZone.getTimeZone(s); - long rawOffsetDiff = regular.getTimeZone().getRawOffset() - zone.getRawOffset(); - // must not be the same timezone (not 0 h and not 24 h difference - // as for Pacific/Auckland and Etc/GMT+12) - if (rawOffsetDiff != 0 && rawOffsetDiff != 1000 * 60 * 60 * 24) { - if (regular.getTimeZone().getOffset(testTime) != zone.getOffset(testTime)) { - other = Calendar.getInstance(zone); - break; - } - } - } - - trace("regular offset = " + regular.getTimeZone().getRawOffset() + " other = " - + other.getTimeZone().getRawOffset()); - - prep.setInt(1, 0); - prep.setDate(2, null, regular); - prep.setTime(3, null, regular); - prep.setTimestamp(4, null, regular); - prep.execute(); - - prep.setInt(1, 1); - prep.setDate(2, null, other); - prep.setTime(3, null, other); - prep.setTimestamp(4, null, other); - prep.execute(); - - prep.setInt(1, 2); - prep.setDate(2, java.sql.Date.valueOf("2001-02-03"), regular); - prep.setTime(3, java.sql.Time.valueOf("04:05:06"), regular); - prep.setTimestamp(4, java.sql.Timestamp.valueOf("2007-08-09 10:11:12.131415"), regular); - prep.execute(); - - prep.setInt(1, 3); - prep.setDate(2, java.sql.Date.valueOf("2101-02-03"), other); - prep.setTime(3, java.sql.Time.valueOf("14:05:06"), other); - prep.setTimestamp(4, java.sql.Timestamp.valueOf("2107-08-09 10:11:12.131415"), other); - prep.execute(); - - prep.setInt(1, 4); - prep.setDate(2, java.sql.Date.valueOf("2101-02-03")); - prep.setTime(3, java.sql.Time.valueOf("14:05:06")); - prep.setTimestamp(4, java.sql.Timestamp.valueOf("2107-08-09 10:11:12.131415")); - prep.execute(); - - rs = stat.executeQuery("SELECT * FROM TEST ORDER BY ID"); - assertResultSetMeta(rs, 4, - new String[] { "ID", "D", "T", "TS" }, - new int[] { Types.INTEGER, Types.DATE, Types.TIME, Types.TIMESTAMP }, - new int[] { 10, 8, 6, 23 }, new int[] { 0, 0, 0, 10 }); - - rs.next(); - assertEquals(0, rs.getInt(1)); - assertTrue(rs.getDate(2, regular) == null && rs.wasNull()); - assertTrue(rs.getTime(3, regular) == null && rs.wasNull()); - assertTrue(rs.getTimestamp(3, regular) == null && rs.wasNull()); - - rs.next(); - assertEquals(1, rs.getInt(1)); - assertTrue(rs.getDate(2, other) == null && rs.wasNull()); - assertTrue(rs.getTime(3, other) == null && rs.wasNull()); - assertTrue(rs.getTimestamp(3, other) == null && rs.wasNull()); - - rs.next(); - assertEquals(2, rs.getInt(1)); - assertEquals("2001-02-03", rs.getDate(2, regular).toString()); - assertEquals("04:05:06", rs.getTime(3, regular).toString()); - assertFalse(rs.getTime(3, other).toString().equals("04:05:06")); - assertEquals("2007-08-09 10:11:12.131415", rs.getTimestamp(4, regular).toString()); - assertFalse(rs.getTimestamp(4, other).toString().equals("2007-08-09 10:11:12.131415")); - - rs.next(); - assertEquals(3, rs.getInt("ID")); - assertFalse(rs.getTimestamp("TS", regular).toString().equals("2107-08-09 10:11:12.131415")); - assertEquals("2107-08-09 10:11:12.131415", rs.getTimestamp("TS", other).toString()); - assertFalse(rs.getTime("T", regular).toString().equals("14:05:06")); - assertEquals("14:05:06", rs.getTime("T", other).toString()); - // checkFalse(rs.getDate(2, regular).toString(), "2101-02-03"); - // check(rs.getDate("D", other).toString(), "2101-02-03"); - - rs.next(); - assertEquals(4, rs.getInt("ID")); - assertEquals("2107-08-09 10:11:12.131415", rs.getTimestamp("TS").toString()); - assertEquals("14:05:06", rs.getTime("T").toString()); - assertEquals("2101-02-03", rs.getDate("D").toString()); - - assertFalse(rs.next()); - stat.execute("DROP TABLE TEST"); - } - - private void testBlob() throws SQLException { - trace("Test BLOB"); - ResultSet rs; - - stat.execute("CREATE TABLE TEST(ID INT PRIMARY KEY,VALUE BLOB)"); - stat.execute("INSERT INTO TEST VALUES(1,X'01010101')"); - stat.execute("INSERT INTO TEST VALUES(2,X'02020202')"); - stat.execute("INSERT INTO TEST VALUES(3,X'00')"); - stat.execute("INSERT INTO TEST VALUES(4,X'ffffff')"); - stat.execute("INSERT INTO TEST VALUES(5,X'0bcec1')"); - stat.execute("INSERT INTO TEST VALUES(6,NULL)"); - rs = stat.executeQuery("SELECT * FROM TEST ORDER BY ID"); - assertResultSetMeta(rs, 2, new String[] { "ID", "VALUE" }, new int[] { Types.INTEGER, Types.BLOB }, new int[] { - 10, Integer.MAX_VALUE }, new int[] { 0, 0 }); - rs.next(); - assertEqualsWithNull(new byte[] { (byte) 0x01, (byte) 0x01, (byte) 0x01, (byte) 0x01 }, rs.getBytes(2)); - assertTrue(!rs.wasNull()); - rs.next(); - assertEqualsWithNull(new byte[] { (byte) 0x02, (byte) 0x02, (byte) 0x02, (byte) 0x02 }, rs.getBytes("value")); - assertTrue(!rs.wasNull()); - rs.next(); - assertEqualsWithNull(new byte[] { (byte) 0x00 }, readAllBytes(rs.getBinaryStream(2))); - assertTrue(!rs.wasNull()); - rs.next(); - assertEqualsWithNull(new byte[] { (byte) 0xff, (byte) 0xff, (byte) 0xff }, readAllBytes(rs.getBinaryStream("VaLuE"))); - assertTrue(!rs.wasNull()); - rs.next(); - InputStream in = rs.getBinaryStream("value"); - byte[] b = readAllBytes(in); - assertEqualsWithNull(new byte[] { (byte) 0x0b, (byte) 0xce, (byte) 0xc1 }, b); - assertTrue(!rs.wasNull()); - rs.next(); - assertEqualsWithNull(null, readAllBytes(rs.getBinaryStream("VaLuE"))); - assertTrue(rs.wasNull()); - assertTrue(!rs.next()); - stat.execute("DROP TABLE TEST"); - } - - private void testClob() throws SQLException { - trace("Test CLOB"); - ResultSet rs; - String string; - stat = conn.createStatement(ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_UPDATABLE); - stat.execute("CREATE TABLE TEST(ID INT PRIMARY KEY,VALUE CLOB)"); - stat.execute("INSERT INTO TEST VALUES(1,'Test')"); - stat.execute("INSERT INTO TEST VALUES(2,'Hello')"); - stat.execute("INSERT INTO TEST VALUES(3,'World!')"); - stat.execute("INSERT INTO TEST VALUES(4,'Hallo')"); - stat.execute("INSERT INTO TEST VALUES(5,'Welt!')"); - stat.execute("INSERT INTO TEST VALUES(6,NULL)"); - stat.execute("INSERT INTO TEST VALUES(7,NULL)"); - rs = stat.executeQuery("SELECT * FROM TEST ORDER BY ID"); - assertResultSetMeta(rs, 2, new String[] { "ID", "VALUE" }, new int[] { Types.INTEGER, Types.CLOB }, new int[] { - 10, Integer.MAX_VALUE }, new int[] { 0, 0 }); - rs.next(); - Object obj = rs.getObject(2); - if (SysProperties.RETURN_LOB_OBJECTS) { - assertTrue(obj instanceof java.sql.Clob); - } else { - assertTrue(obj instanceof java.io.Reader); - } - string = rs.getString(2); - assertTrue(string != null && string.equals("Test")); - assertTrue(!rs.wasNull()); - rs.next(); - InputStreamReader reader = null; - try { - reader = new InputStreamReader(rs.getAsciiStream(2), "ISO-8859-1"); - } catch (Exception e) { - assertTrue(false); - } - string = readString(reader); - assertTrue(!rs.wasNull()); - trace(string); - assertTrue(string != null && string.equals("Hello")); - rs.next(); - try { - reader = new InputStreamReader(rs.getAsciiStream("value"), "ISO-8859-1"); - } catch (Exception e) { - assertTrue(false); - } - string = readString(reader); - assertTrue(!rs.wasNull()); - trace(string); - assertTrue(string != null && string.equals("World!")); - rs.next(); - string = readString(rs.getCharacterStream(2)); - assertTrue(!rs.wasNull()); - trace(string); - assertTrue(string != null && string.equals("Hallo")); - rs.next(); - string = readString(rs.getCharacterStream("value")); - assertTrue(!rs.wasNull()); - trace(string); - assertTrue(string != null && string.equals("Welt!")); - rs.next(); - assertTrue(rs.getCharacterStream(2) == null); - assertTrue(rs.wasNull()); - rs.next(); - assertTrue(rs.getAsciiStream("Value") == null); - assertTrue(rs.wasNull()); - - assertTrue(rs.getStatement() == stat); - assertTrue(rs.getWarnings() == null); - rs.clearWarnings(); - assertTrue(rs.getWarnings() == null); - assertEquals(ResultSet.FETCH_FORWARD, rs.getFetchDirection()); - assertEquals(ResultSet.CONCUR_UPDATABLE, rs.getConcurrency()); - rs.next(); - stat.execute("DROP TABLE TEST"); - } - - private void testArray() throws SQLException { - trace("Test ARRAY"); - ResultSet rs; - stat.execute("CREATE TABLE TEST(ID INT PRIMARY KEY, VALUE ARRAY)"); - PreparedStatement prep = conn.prepareStatement("INSERT INTO TEST VALUES(?, ?)"); - prep.setInt(1, 1); - prep.setObject(2, new Object[] { new Integer(1), new Integer(2) }); - prep.execute(); - prep.setInt(1, 2); - prep.setObject(2, new Object[] { new Integer(11), new Integer(12) }); - prep.execute(); - rs = stat.executeQuery("SELECT * FROM TEST ORDER BY ID"); - rs.next(); - assertEquals(1, rs.getInt(1)); - Object[] list = (Object[]) rs.getObject(2); - assertEquals(1, ((Integer) list[0]).intValue()); - assertEquals(2, ((Integer) list[1]).intValue()); - Array array = rs.getArray(2); - Object[] list2 = (Object[]) array.getArray(); - assertEquals(1, ((Integer) list2[0]).intValue()); - assertEquals(2, ((Integer) list2[1]).intValue()); - list2 = (Object[]) array.getArray(2, 1); - assertEquals(2, ((Integer) list2[0]).intValue()); - rs.next(); - assertEquals(2, rs.getInt(1)); - list = (Object[]) rs.getObject(2); - assertEquals(11, ((Integer) list[0]).intValue()); - assertEquals(12, ((Integer) list[1]).intValue()); - array = rs.getArray(2); - list2 = (Object[]) array.getArray(); - assertEquals(11, ((Integer) list2[0]).intValue()); - assertEquals(12, ((Integer) list2[1]).intValue()); - list2 = (Object[]) array.getArray(2, 1); - assertEquals(12, ((Integer) list2[0]).intValue()); - assertFalse(rs.next()); - stat.execute("DROP TABLE TEST"); - } - - private byte[] readAllBytes(InputStream in) { - if (in == null) { - return null; - } - ByteArrayOutputStream out = new ByteArrayOutputStream(); - try { - while (true) { - int b = in.read(); - if (b == -1) { - break; - } - out.write(b); - } - return out.toByteArray(); - } catch (IOException e) { - assertTrue(false); - return null; - } - } - - private void assertEqualsWithNull(byte[] expected, byte[] got) { - if (got == null || expected == null) { - assertTrue(got == expected); - } else { - assertEquals(got, expected); - } - } - - private void checkColumnBigDecimal(ResultSet rs, int column, int i, String bd) throws SQLException { - BigDecimal bd1 = rs.getBigDecimal(column); - int i1 = rs.getInt(column); - if (bd == null) { - trace("should be: null"); - assertTrue(rs.wasNull()); - } else { - trace("BigDecimal i=" + i + " bd=" + bd + " ; i1=" + i1 + " bd1=" + bd1); - assertTrue(!rs.wasNull()); - assertTrue(i1 == i); - assertTrue(bd1.compareTo(new BigDecimal(bd)) == 0); - } - } - -} diff --git a/tools/h2/src/test/org/h2/test/jdbc/TestStatement.java b/tools/h2/src/test/org/h2/test/jdbc/TestStatement.java deleted file mode 100755 index c947c5b..0000000 --- a/tools/h2/src/test/org/h2/test/jdbc/TestStatement.java +++ /dev/null @@ -1,394 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.test.jdbc; - -import java.sql.Connection; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.sql.Savepoint; -import java.sql.Statement; - -import org.h2.constant.SysProperties; -import org.h2.jdbc.JdbcStatement; -import org.h2.store.fs.FileObject; -import org.h2.store.fs.FileSystem; -import org.h2.test.TestBase; - -/** - * Tests for the Statement implementation. - */ -public class TestStatement extends TestBase { - - private Connection conn; - - /** - * Run just this test. - * - * @param a ignored - */ - public static void main(String... a) throws Exception { - TestBase.createCaller().init().test(); - } - - public void test() throws Exception { - deleteDb("statement"); - conn = getConnection("statement"); - testTraceError(); - if (config.jdk14) { - testSavepoint(); - } - testConnectionRollback(); - testStatement(); - if (config.jdk14) { - testIdentityMerge(); - testIdentity(); - } - conn.close(); - deleteDb("statement"); - } - - private void testTraceError() throws Exception { - if (config.memory || config.networked || config.traceLevelFile != 0) { - return; - } - Statement stat = conn.createStatement(); - String fileName = getBaseDir() + "/statement.trace.db"; - stat.execute("DROP TABLE TEST IF EXISTS"); - stat.execute("CREATE TABLE TEST(ID INT PRIMARY KEY)"); - stat.execute("INSERT INTO TEST VALUES(1)"); - try { - stat.execute("ERROR"); - } catch (SQLException e) { - // ignore - } - FileObject trace = FileSystem.getInstance(fileName).openFileObject(fileName, "r"); - long lengthBefore = trace.length(); - try { - stat.execute("ERROR"); - } catch (SQLException e) { - // ignore - } - long error = trace.length(); - assertSmaller(lengthBefore, error); - lengthBefore = error; - try { - stat.execute("INSERT INTO TEST VALUES(1)"); - } catch (SQLException e) { - // ignore - } - error = trace.length(); - assertEquals(lengthBefore, error); - stat.execute("DROP TABLE TEST IF EXISTS"); - } - - private void testConnectionRollback() throws SQLException { - Statement stat = conn.createStatement(); - conn.setAutoCommit(false); - stat.execute("CREATE TABLE TEST(ID INT PRIMARY KEY, NAME VARCHAR(255))"); - stat.execute("INSERT INTO TEST VALUES(1, 'Hello')"); - conn.rollback(); - ResultSet rs = stat.executeQuery("SELECT * FROM TEST"); - assertFalse(rs.next()); - stat.execute("DROP TABLE TEST"); - conn.setAutoCommit(true); - } - - private void testSavepoint() throws SQLException { - Statement stat = conn.createStatement(); - stat.execute("CREATE TABLE TEST(ID INT PRIMARY KEY, NAME VARCHAR(255))"); - conn.setAutoCommit(false); - stat.execute("INSERT INTO TEST VALUES(0, 'Hi')"); - Savepoint savepoint1 = conn.setSavepoint(); - int id1 = savepoint1.getSavepointId(); - try { - savepoint1.getSavepointName(); - fail(); - } catch (SQLException e) { - assertKnownException(e); - } - stat.execute("DELETE FROM TEST"); - conn.rollback(savepoint1); - stat.execute("UPDATE TEST SET NAME='Hello'"); - Savepoint savepoint2a = conn.setSavepoint(); - Savepoint savepoint2 = conn.setSavepoint(); - conn.releaseSavepoint(savepoint2a); - try { - savepoint2a.getSavepointId(); - fail(); - } catch (SQLException e) { - assertKnownException(e); - } - int id2 = savepoint2.getSavepointId(); - assertTrue(id1 != id2); - stat.execute("UPDATE TEST SET NAME='Hallo' WHERE NAME='Hello'"); - Savepoint savepointTest = conn.setSavepoint("Joe's"); - stat.execute("DELETE FROM TEST"); - assertEquals(savepointTest.getSavepointName(), "Joe's"); - try { - savepointTest.getSavepointId(); - fail(); - } catch (SQLException e) { - assertKnownException(e); - } - conn.rollback(savepointTest); - conn.commit(); - ResultSet rs = stat.executeQuery("SELECT NAME FROM TEST"); - rs.next(); - String name = rs.getString(1); - assertEquals(name, "Hallo"); - assertFalse(rs.next()); - try { - conn.rollback(savepoint2); - fail(); - } catch (SQLException e) { - assertKnownException(e); - } - stat.execute("DROP TABLE TEST"); - conn.setAutoCommit(true); - } - - private void testStatement() throws SQLException { - - Statement stat = conn.createStatement(); - - //## Java 1.4 begin ## - assertEquals(ResultSet.HOLD_CURSORS_OVER_COMMIT, conn.getHoldability()); - conn.setHoldability(ResultSet.CLOSE_CURSORS_AT_COMMIT); - assertEquals(ResultSet.CLOSE_CURSORS_AT_COMMIT, conn.getHoldability()); - //## Java 1.4 end ## - - // ignored - stat.setCursorName("x"); - // fixed return value - assertEquals(stat.getFetchDirection(), ResultSet.FETCH_FORWARD); - // ignored - stat.setFetchDirection(ResultSet.FETCH_REVERSE); - // ignored - stat.setMaxFieldSize(100); - - assertEquals(SysProperties.SERVER_RESULT_SET_FETCH_SIZE, stat.getFetchSize()); - stat.setFetchSize(10); - assertEquals(10, stat.getFetchSize()); - stat.setFetchSize(0); - assertEquals(SysProperties.SERVER_RESULT_SET_FETCH_SIZE, stat.getFetchSize()); - assertEquals(ResultSet.TYPE_FORWARD_ONLY, stat.getResultSetType()); - Statement stat2 = conn.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_READ_ONLY, ResultSet.HOLD_CURSORS_OVER_COMMIT); - assertEquals(ResultSet.TYPE_SCROLL_SENSITIVE, stat2.getResultSetType()); - assertEquals(ResultSet.HOLD_CURSORS_OVER_COMMIT, stat2.getResultSetHoldability()); - assertEquals(ResultSet.CONCUR_READ_ONLY, stat2.getResultSetConcurrency()); - assertEquals(0, stat.getMaxFieldSize()); - assertTrue(!((JdbcStatement) stat2).isClosed()); - stat2.close(); - assertTrue(((JdbcStatement) stat2).isClosed()); - - - ResultSet rs; - int count; - boolean result; - - stat.execute("CREATE TABLE TEST(ID INT)"); - stat.execute("SELECT * FROM TEST"); - stat.execute("DROP TABLE TEST"); - - conn.getTypeMap(); - - // this method should not throw an exception - if not supported, this - // calls are ignored - - if (config.jdk14) { - assertEquals(ResultSet.HOLD_CURSORS_OVER_COMMIT, stat.getResultSetHoldability()); - } - assertEquals(ResultSet.CONCUR_READ_ONLY, stat.getResultSetConcurrency()); - - stat.cancel(); - stat.setQueryTimeout(10); - assertTrue(stat.getQueryTimeout() == 10); - stat.setQueryTimeout(0); - assertTrue(stat.getQueryTimeout() == 0); - // this is supposed to throw an exception - try { - stat.setQueryTimeout(-1); - fail("setQueryTimeout(-1) didn't throw an exception"); - } catch (SQLException e) { - assertKnownException(e); - } - assertTrue(stat.getQueryTimeout() == 0); - trace("executeUpdate"); - count = stat.executeUpdate("CREATE TABLE TEST(ID INT PRIMARY KEY,VALUE VARCHAR(255))"); - assertEquals(0, count); - count = stat.executeUpdate("INSERT INTO TEST VALUES(1,'Hello')"); - assertEquals(1, count); - count = stat.executeUpdate("INSERT INTO TEST(VALUE,ID) VALUES('JDBC',2)"); - assertEquals(1, count); - count = stat.executeUpdate("UPDATE TEST SET VALUE='LDBC' WHERE ID=2 OR ID=1"); - assertEquals(2, count); - count = stat.executeUpdate("UPDATE TEST SET VALUE='\\LDBC\\' WHERE VALUE LIKE 'LDBC' "); - assertEquals(2, count); - count = stat.executeUpdate("UPDATE TEST SET VALUE='LDBC' WHERE VALUE LIKE '\\\\LDBC\\\\'"); - trace("count:" + count); - assertEquals(2, count); - count = stat.executeUpdate("DELETE FROM TEST WHERE ID=-1"); - assertEquals(0, count); - count = stat.executeUpdate("DELETE FROM TEST WHERE ID=2"); - assertEquals(1, count); - try { - stat.executeUpdate("SELECT * FROM TEST"); - fail("executeUpdate allowed SELECT"); - } catch (SQLException e) { - assertKnownException(e); - trace("no error - SELECT not allowed with executeUpdate"); - } - count = stat.executeUpdate("DROP TABLE TEST"); - assertTrue(count == 0); - - trace("execute"); - result = stat.execute("CREATE TABLE TEST(ID INT PRIMARY KEY,VALUE VARCHAR(255))"); - assertTrue(!result); - result = stat.execute("INSERT INTO TEST VALUES(1,'Hello')"); - assertTrue(!result); - result = stat.execute("INSERT INTO TEST(VALUE,ID) VALUES('JDBC',2)"); - assertTrue(!result); - result = stat.execute("UPDATE TEST SET VALUE='LDBC' WHERE ID=2"); - assertTrue(!result); - result = stat.execute("DELETE FROM TEST WHERE ID=3"); - assertTrue(!result); - result = stat.execute("SELECT * FROM TEST"); - assertTrue(result); - result = stat.execute("DROP TABLE TEST"); - assertTrue(!result); - - trace("executeQuery"); - try { - stat.executeQuery("CREATE TABLE TEST(ID INT PRIMARY KEY,VALUE VARCHAR(255))"); - fail("executeQuery allowed CREATE TABLE"); - } catch (SQLException e) { - assertKnownException(e); - trace("no error - CREATE not allowed with executeQuery"); - } - stat.execute("CREATE TABLE TEST(ID INT PRIMARY KEY,VALUE VARCHAR(255))"); - try { - stat.executeQuery("INSERT INTO TEST VALUES(1,'Hello')"); - fail("executeQuery allowed INSERT"); - } catch (SQLException e) { - assertKnownException(e); - trace("no error - INSERT not allowed with executeQuery"); - } - try { - stat.executeQuery("UPDATE TEST SET VALUE='LDBC' WHERE ID=2"); - fail("executeQuery allowed UPDATE"); - } catch (SQLException e) { - assertKnownException(e); - trace("no error - UPDATE not allowed with executeQuery"); - } - try { - stat.executeQuery("DELETE FROM TEST WHERE ID=3"); - fail("executeQuery allowed DELETE"); - } catch (SQLException e) { - assertKnownException(e); - trace("no error - DELETE not allowed with executeQuery"); - } - stat.executeQuery("SELECT * FROM TEST"); - try { - stat.executeQuery("DROP TABLE TEST"); - fail("executeQuery allowed DROP"); - } catch (SQLException e) { - assertKnownException(e); - trace("no error - DROP not allowed with executeQuery"); - } - // getMoreResults - rs = stat.executeQuery("SELECT * FROM TEST"); - assertFalse(stat.getMoreResults()); - try { - // supposed to be closed now - rs.next(); - fail("getMoreResults didn't close this result set"); - } catch (SQLException e) { - assertKnownException(e); - trace("no error - getMoreResults is supposed to close the result set"); - } - assertTrue(stat.getUpdateCount() == -1); - count = stat.executeUpdate("DELETE FROM TEST"); - assertFalse(stat.getMoreResults()); - assertTrue(stat.getUpdateCount() == -1); - - stat.execute("DROP TABLE TEST"); - stat.executeUpdate("DROP TABLE IF EXISTS TEST"); - - assertTrue(stat.getWarnings() == null); - stat.clearWarnings(); - assertTrue(stat.getWarnings() == null); - assertTrue(conn == stat.getConnection()); - - stat.close(); - } - - private void testIdentityMerge() throws SQLException { - Statement stat = conn.createStatement(); - stat.execute("drop table if exists test1"); - stat.execute("create table test1(id identity, x int)"); - stat.execute("drop table if exists test2"); - stat.execute("create table test2(id identity, x int)"); - stat.execute("merge into test1(x) key(x) values(5)"); - ResultSet keys; - keys = stat.getGeneratedKeys(); - keys.next(); - assertEquals(1, keys.getInt(1)); - stat.execute("insert into test2(x) values(10), (11), (12)"); - stat.execute("merge into test1(x) key(x) values(5)"); - keys = stat.getGeneratedKeys(); - keys.next(); - assertEquals(0, keys.getInt(1)); - stat.execute("merge into test1(x) key(x) values(6)"); - keys = stat.getGeneratedKeys(); - keys.next(); - assertEquals(2, keys.getInt(1)); - stat.execute("drop table test1, test2"); - } - - private void testIdentity() throws SQLException { - Statement stat = conn.createStatement(); - stat.execute("CREATE SEQUENCE SEQ"); - stat.execute("CREATE TABLE TEST(ID INT)"); - stat.execute("INSERT INTO TEST VALUES(NEXT VALUE FOR SEQ)"); - ResultSet rs = stat.getGeneratedKeys(); - rs.next(); - assertEquals(1, rs.getInt(1)); - assertFalse(rs.next()); - stat.execute("INSERT INTO TEST VALUES(NEXT VALUE FOR SEQ)", Statement.RETURN_GENERATED_KEYS); - rs = stat.getGeneratedKeys(); - rs.next(); - assertEquals(2, rs.getInt(1)); - assertFalse(rs.next()); - stat.execute("INSERT INTO TEST VALUES(NEXT VALUE FOR SEQ)", new int[] { 1 }); - rs = stat.getGeneratedKeys(); - rs.next(); - assertEquals(3, rs.getInt(1)); - assertFalse(rs.next()); - stat.execute("INSERT INTO TEST VALUES(NEXT VALUE FOR SEQ)", new String[] { "ID" }); - rs = stat.getGeneratedKeys(); - rs.next(); - assertEquals(4, rs.getInt(1)); - assertFalse(rs.next()); - stat.executeUpdate("INSERT INTO TEST VALUES(NEXT VALUE FOR SEQ)", Statement.RETURN_GENERATED_KEYS); - rs = stat.getGeneratedKeys(); - rs.next(); - assertEquals(5, rs.getInt(1)); - assertFalse(rs.next()); - stat.executeUpdate("INSERT INTO TEST VALUES(NEXT VALUE FOR SEQ)", new int[] { 1 }); - rs = stat.getGeneratedKeys(); - rs.next(); - assertEquals(6, rs.getInt(1)); - assertFalse(rs.next()); - stat.executeUpdate("INSERT INTO TEST VALUES(NEXT VALUE FOR SEQ)", new String[] { "ID" }); - rs = stat.getGeneratedKeys(); - rs.next(); - assertEquals(7, rs.getInt(1)); - assertFalse(rs.next()); - stat.execute("DROP TABLE TEST"); - } - -} diff --git a/tools/h2/src/test/org/h2/test/jdbc/TestTransactionIsolation.java b/tools/h2/src/test/org/h2/test/jdbc/TestTransactionIsolation.java deleted file mode 100755 index 82d4236..0000000 --- a/tools/h2/src/test/org/h2/test/jdbc/TestTransactionIsolation.java +++ /dev/null @@ -1,107 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.test.jdbc; - -import java.sql.Connection; -import java.sql.SQLException; - -import org.h2.test.TestBase; - -/** - * Transaction isolation level tests. - */ -public class TestTransactionIsolation extends TestBase { - - private Connection conn1, conn2; - - /** - * Run just this test. - * - * @param a ignored - */ - public static void main(String... a) throws Exception { - TestBase.createCaller().init().test(); - } - - public void test() throws SQLException { - if (config.mvcc) { - // no tests yet - } else { - testTableLevelLocking(); - } - } - - private void testTableLevelLocking() throws SQLException { - deleteDb("transactionIsolation"); - conn1 = getConnection("transactionIsolation"); - assertEquals(Connection.TRANSACTION_READ_COMMITTED, conn1.getTransactionIsolation()); - conn1.setTransactionIsolation(Connection.TRANSACTION_SERIALIZABLE); - assertEquals(Connection.TRANSACTION_SERIALIZABLE, conn1.getTransactionIsolation()); - conn1.setTransactionIsolation(Connection.TRANSACTION_READ_UNCOMMITTED); - assertEquals(Connection.TRANSACTION_READ_UNCOMMITTED, conn1.getTransactionIsolation()); - assertSingleValue(conn1.createStatement(), "CALL LOCK_MODE()", 0); - conn1.setTransactionIsolation(Connection.TRANSACTION_READ_COMMITTED); - assertSingleValue(conn1.createStatement(), "CALL LOCK_MODE()", 3); - assertEquals(Connection.TRANSACTION_READ_COMMITTED, conn1.getTransactionIsolation()); - conn1.createStatement().execute("SET LOCK_MODE 1"); - assertEquals(Connection.TRANSACTION_SERIALIZABLE, conn1.getTransactionIsolation()); - conn1.createStatement().execute("CREATE TABLE TEST(ID INT)"); - conn1.createStatement().execute("INSERT INTO TEST VALUES(1)"); - conn1.setAutoCommit(false); - - conn2 = getConnection("transactionIsolation"); - conn2.setAutoCommit(false); - - conn1.setTransactionIsolation(Connection.TRANSACTION_SERIALIZABLE); - - // serializable: just reading - assertSingleValue(conn1.createStatement(), "SELECT * FROM TEST", 1); - assertSingleValue(conn2.createStatement(), "SELECT * FROM TEST", 1); - conn1.commit(); - conn2.commit(); - - // serializable: write lock - conn1.createStatement().executeUpdate("UPDATE TEST SET ID=2"); - try { - assertSingleValue(conn2.createStatement(), "SELECT * FROM TEST", 1); - fail("Expected lock timeout"); - } catch (SQLException e) { - assertKnownException(e); - } - conn1.commit(); - conn2.commit(); - - conn1.setTransactionIsolation(Connection.TRANSACTION_READ_COMMITTED); - - // read-committed: #1 read, #2 update, #1 read again - assertSingleValue(conn1.createStatement(), "SELECT * FROM TEST", 2); - conn2.createStatement().executeUpdate("UPDATE TEST SET ID=3"); - conn2.commit(); - assertSingleValue(conn1.createStatement(), "SELECT * FROM TEST", 3); - conn1.commit(); - - // read-committed: #1 read, #2 read, #2 update, #1 delete - assertSingleValue(conn1.createStatement(), "SELECT * FROM TEST", 3); - assertSingleValue(conn2.createStatement(), "SELECT * FROM TEST", 3); - conn2.createStatement().executeUpdate("UPDATE TEST SET ID=4"); - try { - conn1.createStatement().executeUpdate("DELETE FROM TEST"); - fail("Expected lock timeout"); - } catch (SQLException e) { - assertKnownException(e); - } - conn2.commit(); - conn1.commit(); - assertSingleValue(conn1.createStatement(), "SELECT * FROM TEST", 4); - assertSingleValue(conn2.createStatement(), "SELECT * FROM TEST", 4); - - conn1.close(); - conn2.close(); - deleteDb("transactionIsolation"); - } - -} diff --git a/tools/h2/src/test/org/h2/test/jdbc/TestUpdatableResultSet.java b/tools/h2/src/test/org/h2/test/jdbc/TestUpdatableResultSet.java deleted file mode 100755 index 09e5425..0000000 --- a/tools/h2/src/test/org/h2/test/jdbc/TestUpdatableResultSet.java +++ /dev/null @@ -1,481 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.test.jdbc; - -import java.io.ByteArrayInputStream; -import java.io.StringReader; -import java.math.BigDecimal; -import java.sql.Connection; -import java.sql.Date; -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.ResultSetMetaData; -import java.sql.SQLException; -import java.sql.Statement; -import java.sql.Time; -import java.sql.Timestamp; -import java.sql.Types; - -import org.h2.constant.SysProperties; -import org.h2.test.TestBase; - -/** - * Updatable result set tests. - */ -public class TestUpdatableResultSet extends TestBase { - - /** - * Run just this test. - * - * @param a ignored - */ - public static void main(String... a) throws Exception { - TestBase.createCaller().init().test(); - } - - public void test() throws SQLException { - testUpdateLob(); - testScroll(); - testUpdateDeleteInsert(); - testUpdateDataType(); - testUpdateResetRead(); - deleteDb("updatableResultSet"); - } - - private void testUpdateLob() throws SQLException { - deleteDb("updatableResultSet"); - Connection conn = getConnection("updatableResultSet"); - Statement stat = conn.createStatement(); - stat.execute("CREATE TABLE object_index (id integer primary key, object other, number integer)"); - - PreparedStatement prep = conn.prepareStatement("INSERT INTO object_index (id,object) VALUES (1,?)"); - prep.setObject(1, "hello", Types.JAVA_OBJECT); - prep.execute(); - - ResultSet rs = stat.executeQuery("SELECT object,id,number FROM object_index WHERE id =1"); - rs.next(); - assertEquals("hello", rs.getObject(1).toString()); - stat = conn.createStatement(ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_UPDATABLE); - rs = stat.executeQuery("SELECT object,id,number FROM object_index WHERE id =1"); - rs.next(); - assertEquals("hello", rs.getObject(1).toString()); - rs.updateInt(2, 1); - rs.updateRow(); - rs.close(); - stat = conn.createStatement(); - rs = stat.executeQuery("SELECT object,id,number FROM object_index WHERE id =1"); - rs.next(); - assertEquals("hello", rs.getObject(1).toString()); - conn.close(); - } - - private void testUpdateResetRead() throws SQLException { - deleteDb("updatableResultSet"); - Connection conn = getConnection("updatableResultSet"); - Statement stat = conn.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_UPDATABLE); - stat.execute("CREATE TABLE TEST(ID INT PRIMARY KEY, NAME VARCHAR(255))"); - stat.execute("INSERT INTO TEST VALUES(1, 'Hello')"); - stat.execute("INSERT INTO TEST VALUES(2, 'World')"); - ResultSet rs = stat.executeQuery("SELECT * FROM TEST ORDER BY ID"); - rs.next(); - rs.updateInt(1, 10); - rs.updateRow(); - rs.next(); - rs.updateString(2, "Welt"); - rs.updateRow(); - rs.beforeFirst(); - rs.next(); - assertEquals(10, rs.getInt(1)); - assertEquals("Hello", rs.getString(2)); - rs.next(); - assertEquals(2, rs.getInt(1)); - assertEquals("Welt", rs.getString(2)); - conn.close(); - } - - private void testScroll() throws SQLException { - deleteDb("updatableResultSet"); - Connection conn = getConnection("updatableResultSet"); - Statement stat = conn.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY); - stat.execute("CREATE TABLE TEST(ID INT PRIMARY KEY, NAME VARCHAR)"); - stat.execute("INSERT INTO TEST VALUES(1, 'Hello'), (2, 'World'), (3, 'Test')"); - - ResultSet rs = stat.executeQuery("SELECT * FROM TEST ORDER BY ID"); - - assertTrue(rs.isBeforeFirst()); - assertFalse(rs.isAfterLast()); - assertEquals(0, rs.getRow()); - - rs.next(); - assertFalse(rs.isBeforeFirst()); - assertFalse(rs.isAfterLast()); - assertEquals(1, rs.getInt(1)); - assertEquals(1, rs.getRow()); - - rs.next(); - - try { - rs.insertRow(); - fail(); - } catch (SQLException e) { - assertKnownException(e); - } - - assertFalse(rs.isBeforeFirst()); - assertFalse(rs.isAfterLast()); - assertEquals(2, rs.getInt(1)); - assertEquals(2, rs.getRow()); - - rs.next(); - assertFalse(rs.isBeforeFirst()); - assertFalse(rs.isAfterLast()); - assertEquals(3, rs.getInt(1)); - assertEquals(3, rs.getRow()); - - assertFalse(rs.next()); - assertFalse(rs.isBeforeFirst()); - assertTrue(rs.isAfterLast()); - assertEquals(0, rs.getRow()); - - assertTrue(rs.first()); - assertEquals(1, rs.getInt(1)); - assertEquals(1, rs.getRow()); - - assertTrue(rs.last()); - assertEquals(3, rs.getInt(1)); - assertEquals(3, rs.getRow()); - - assertTrue(rs.relative(0)); - assertEquals(3, rs.getRow()); - - assertTrue(rs.relative(-1)); - assertEquals(2, rs.getRow()); - - assertTrue(rs.relative(1)); - assertEquals(3, rs.getRow()); - - assertFalse(rs.relative(100)); - assertTrue(rs.isAfterLast()); - - assertFalse(rs.absolute(0)); - assertEquals(0, rs.getRow()); - - assertTrue(rs.absolute(1)); - assertEquals(1, rs.getRow()); - - assertTrue(rs.absolute(2)); - assertEquals(2, rs.getRow()); - - assertTrue(rs.absolute(3)); - assertEquals(3, rs.getRow()); - - assertFalse(rs.absolute(4)); - assertEquals(0, rs.getRow()); - - try { - assertFalse(rs.absolute(0)); - // actually, we allow it for compatibility - // error("absolute 0 not allowed"); - } catch (SQLException e) { - assertKnownException(e); - } - - assertTrue(rs.absolute(3)); - assertEquals(3, rs.getRow()); - - assertTrue(rs.absolute(-1)); - assertEquals(3, rs.getRow()); - - assertFalse(rs.absolute(4)); - assertTrue(rs.isAfterLast()); - - assertFalse(rs.absolute(5)); - assertTrue(rs.isAfterLast()); - - assertTrue(rs.previous()); - assertEquals(3, rs.getRow()); - - assertTrue(rs.previous()); - assertEquals(2, rs.getRow()); - - conn.close(); - } - - private void testUpdateDataType() throws SQLException { - deleteDb("updatableResultSet"); - Connection conn = getConnection("updatableResultSet"); - Statement stat = conn.createStatement(ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_UPDATABLE); - stat.execute("CREATE TABLE TEST(ID INT PRIMARY KEY, NAME VARCHAR(255), " - + "DEC DECIMAL(10,2), BOO BIT, BYE TINYINT, BIN BINARY(100), " - + "D DATE, T TIME, TS TIMESTAMP, DB DOUBLE, R REAL, L BIGINT, " - + "O_I INT, SH SMALLINT, CL CLOB, BL BLOB)"); - ResultSet rs = stat.executeQuery("SELECT * FROM TEST"); - ResultSetMetaData meta = rs.getMetaData(); - assertEquals("java.lang.Integer", meta.getColumnClassName(1)); - assertEquals("java.lang.String", meta.getColumnClassName(2)); - assertEquals("java.math.BigDecimal", meta.getColumnClassName(3)); - assertEquals("java.lang.Boolean", meta.getColumnClassName(4)); - assertEquals("java.lang.Byte", meta.getColumnClassName(5)); - assertEquals("[B", meta.getColumnClassName(6)); - assertEquals("java.sql.Date", meta.getColumnClassName(7)); - assertEquals("java.sql.Time", meta.getColumnClassName(8)); - assertEquals("java.sql.Timestamp", meta.getColumnClassName(9)); - assertEquals("java.lang.Double", meta.getColumnClassName(10)); - assertEquals("java.lang.Float", meta.getColumnClassName(11)); - assertEquals("java.lang.Long", meta.getColumnClassName(12)); - assertEquals("java.lang.Integer", meta.getColumnClassName(13)); - assertEquals("java.lang.Short", meta.getColumnClassName(14)); - if (SysProperties.RETURN_LOB_OBJECTS) { - assertEquals("java.sql.Clob", meta.getColumnClassName(15)); - assertEquals("java.sql.Blob", meta.getColumnClassName(16)); - } else { - assertEquals("java.io.Reader", meta.getColumnClassName(15)); - assertEquals("java.io.InputStream", meta.getColumnClassName(16)); - } - rs.moveToInsertRow(); - rs.updateInt(1, 0); - rs.updateNull(2); - rs.updateNull("DEC"); - // 'not set' values are set to null - rs.insertRow(); - - rs.moveToInsertRow(); - rs.updateInt(1, 1); - rs.updateString(2, null); - rs.updateBigDecimal(3, null); - rs.updateBoolean(4, false); - rs.updateByte(5, (byte) 0); - rs.updateBytes(6, null); - rs.updateDate(7, null); - rs.updateTime(8, null); - rs.updateTimestamp(9, null); - rs.updateDouble(10, 0.0); - rs.updateFloat(11, (float) 0.0); - rs.updateLong(12, 0L); - rs.updateObject(13, null); - rs.updateShort(14, (short) 0); - rs.updateCharacterStream(15, new StringReader("test"), 0); - rs.updateBinaryStream(16, new ByteArrayInputStream(new byte[] { (byte) 0xff, 0x00 }), 0); - rs.insertRow(); - - rs.moveToInsertRow(); - rs.updateInt("ID", 2); - rs.updateString("NAME", "+"); - rs.updateBigDecimal("DEC", new BigDecimal("1.2")); - rs.updateBoolean("BOO", true); - rs.updateByte("BYE", (byte) 0xff); - rs.updateBytes("BIN", new byte[] { 0x00, (byte) 0xff }); - rs.updateDate("D", Date.valueOf("2005-09-21")); - rs.updateTime("T", Time.valueOf("21:46:28")); - rs.updateTimestamp("TS", Timestamp.valueOf("2005-09-21 21:47:09.567890123")); - rs.updateDouble("DB", 1.725); - rs.updateFloat("R", (float) 2.5); - rs.updateLong("L", Long.MAX_VALUE); - rs.updateObject("O_I", new Integer(10)); - rs.updateShort("SH", Short.MIN_VALUE); - // auml, ouml, uuml - rs.updateCharacterStream("CL", new StringReader("\u00ef\u00f6\u00fc"), 0); - rs.updateBinaryStream("BL", new ByteArrayInputStream(new byte[] { (byte) 0xab, 0x12 }), 0); - rs.insertRow(); - - rs = stat.executeQuery("SELECT * FROM TEST ORDER BY ID NULLS FIRST"); - rs.next(); - assertTrue(rs.getInt(1) == 0); - assertTrue(rs.getString(2) == null && rs.wasNull()); - assertTrue(rs.getBigDecimal(3) == null && rs.wasNull()); - assertTrue(!rs.getBoolean(4) && rs.wasNull()); - assertTrue(rs.getByte(5) == 0 && rs.wasNull()); - assertTrue(rs.getBytes(6) == null && rs.wasNull()); - assertTrue(rs.getDate(7) == null && rs.wasNull()); - assertTrue(rs.getTime(8) == null && rs.wasNull()); - assertTrue(rs.getTimestamp(9) == null && rs.wasNull()); - assertTrue(rs.getDouble(10) == 0.0 && rs.wasNull()); - assertTrue(rs.getFloat(11) == 0.0 && rs.wasNull()); - assertTrue(rs.getLong(12) == 0 && rs.wasNull()); - assertTrue(rs.getObject(13) == null && rs.wasNull()); - assertTrue(rs.getShort(14) == 0 && rs.wasNull()); - assertTrue(rs.getCharacterStream(15) == null && rs.wasNull()); - assertTrue(rs.getBinaryStream(16) == null && rs.wasNull()); - - rs.next(); - assertTrue(rs.getInt(1) == 1); - assertTrue(rs.getString(2) == null && rs.wasNull()); - assertTrue(rs.getBigDecimal(3) == null && rs.wasNull()); - assertTrue(!rs.getBoolean(4) && !rs.wasNull()); - assertTrue(rs.getByte(5) == 0 && !rs.wasNull()); - assertTrue(rs.getBytes(6) == null && rs.wasNull()); - assertTrue(rs.getDate(7) == null && rs.wasNull()); - assertTrue(rs.getTime(8) == null && rs.wasNull()); - assertTrue(rs.getTimestamp(9) == null && rs.wasNull()); - assertTrue(rs.getDouble(10) == 0.0 && !rs.wasNull()); - assertTrue(rs.getFloat(11) == 0.0 && !rs.wasNull()); - assertTrue(rs.getLong(12) == 0 && !rs.wasNull()); - assertTrue(rs.getObject(13) == null && rs.wasNull()); - assertTrue(rs.getShort(14) == 0 && !rs.wasNull()); - assertEquals("test", rs.getString(15)); - assertEquals(new byte[] { (byte) 0xff, 0x00 }, rs.getBytes(16)); - - rs.next(); - assertTrue(rs.getInt(1) == 2); - assertEquals("+", rs.getString(2)); - assertEquals("1.20", rs.getBigDecimal(3).toString()); - assertTrue(rs.getBoolean(4)); - assertTrue((rs.getByte(5) & 0xff) == 0xff); - assertEquals(new byte[] { 0x00, (byte) 0xff }, rs.getBytes(6)); - assertEquals("2005-09-21", rs.getDate(7).toString()); - assertEquals("21:46:28", rs.getTime(8).toString()); - assertEquals("2005-09-21 21:47:09.567890123", rs.getTimestamp(9).toString()); - assertTrue(rs.getDouble(10) == 1.725); - assertTrue(rs.getFloat(11) == (float) 2.5); - assertTrue(rs.getLong(12) == Long.MAX_VALUE); - assertEquals(10, ((Integer) rs.getObject(13)).intValue()); - assertTrue(rs.getShort(14) == Short.MIN_VALUE); - // auml ouml uuml - assertEquals("\u00ef\u00f6\u00fc", rs.getString(15)); - assertEquals(new byte[] { (byte) 0xab, 0x12 }, rs.getBytes(16)); - - assertFalse(rs.next()); - stat.execute("DROP TABLE TEST"); - conn.close(); - } - - private void testUpdateDeleteInsert() throws SQLException { - deleteDb("updatableResultSet"); - Connection c1 = getConnection("updatableResultSet"); - Connection c2 = getConnection("updatableResultSet"); - Statement stat = c1.createStatement(ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_UPDATABLE); - stat.execute("DROP TABLE IF EXISTS TEST"); - stat.execute("CREATE TABLE TEST(ID INT PRIMARY KEY, NAME VARCHAR(255))"); - int max = 8; - for (int i = 0; i < max; i++) { - stat.execute("INSERT INTO TEST VALUES(" + i + ", 'Hello" + i + "')"); - } - ResultSet rs = stat.executeQuery("SELECT * FROM TEST"); - int j = max; - while (rs.next()) { - int id = rs.getInt(1); - if (id % 2 == 0) { - Statement s2 = c2.createStatement(); - s2.execute("UPDATE TEST SET NAME = NAME || '+' WHERE ID = " + rs.getInt(1)); - if (id % 4 == 0) { - rs.refreshRow(); - } - rs.updateString(2, "Updated " + rs.getString(2)); - rs.updateRow(); - } else { - rs.deleteRow(); - } - rs.moveToInsertRow(); - rs.updateString(2, "Inserted " + j); - rs.updateInt(1, j); - j += 2; - rs.insertRow(); - } - rs = stat.executeQuery("SELECT * FROM TEST ORDER BY ID"); - while (rs.next()) { - int id = rs.getInt(1); - String name = rs.getString(2); - assertEquals(0, id % 2); - if (id >= max) { - assertEquals("Inserted " + id, rs.getString(2)); - } else { - if (id % 4 == 0) { - assertEquals("Updated Hello" + id + "+", rs.getString(2)); - } else { - assertEquals("Updated Hello" + id, rs.getString(2)); - } - } - trace("id=" + id + " name=" + name); - } - c2.close(); - c1.close(); - - // test scrollable result sets - Connection conn = getConnection("updatableResultSet"); - for (int i = 0; i < 5; i++) { - testScrollable(conn, i); - } - conn.close(); - } - - private void testScrollable(Connection conn, int rows) throws SQLException { - Statement stat = conn.createStatement(); - stat.execute("CREATE TABLE IF NOT EXISTS TEST(ID INT PRIMARY KEY, NAME VARCHAR(255))"); - stat.execute("DELETE FROM TEST"); - PreparedStatement prep = conn.prepareStatement("INSERT INTO TEST VALUES(?, ?)"); - for (int i = 0; i < rows; i++) { - prep.setInt(1, i); - prep.setString(2, "Data " + i); - prep.execute(); - } - Statement regular = conn.createStatement(); - testScrollResultSet(regular, ResultSet.TYPE_FORWARD_ONLY, rows); - Statement scroll = conn.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY); - testScrollResultSet(scroll, ResultSet.TYPE_SCROLL_INSENSITIVE, rows); - } - - private void testScrollResultSet(Statement stat, int type, int rows) throws SQLException { - boolean error = false; - if (type == ResultSet.TYPE_FORWARD_ONLY) { - error = true; - } - ResultSet rs = stat.executeQuery("SELECT * FROM TEST"); - assertEquals(type, rs.getType()); - - assertState(rs, rows > 0, false, false, false); - for (int i = 0; i < rows; i++) { - rs.next(); - assertState(rs, rows == 0, i == 0, i == rows - 1, rows == 0 || i == rows); - } - try { - rs.beforeFirst(); - assertState(rs, rows > 0, false, false, false); - } catch (SQLException e) { - if (!error) { - throw e; - } - } - try { - rs.afterLast(); - assertState(rs, false, false, false, rows > 0); - } catch (SQLException e) { - if (!error) { - throw e; - } - } - try { - boolean valid = rs.first(); - assertEquals(rows > 0, valid); - if (valid) { - assertState(rs, false, true, rows == 1, rows == 0); - } - } catch (SQLException e) { - if (!error) { - throw e; - } - } - try { - boolean valid = rs.last(); - assertEquals(rows > 0, valid); - if (valid) { - assertState(rs, false, rows == 1, true, rows == 0); - } - } catch (SQLException e) { - if (!error) { - throw e; - } - } - } - - private void assertState(ResultSet rs, boolean beforeFirst, boolean first, boolean last, boolean afterLast) throws SQLException { - assertEquals(beforeFirst, rs.isBeforeFirst()); - assertEquals(first, rs.isFirst()); - assertEquals(last, rs.isLast()); - assertEquals(afterLast, rs.isAfterLast()); - } - -} diff --git a/tools/h2/src/test/org/h2/test/jdbc/TestZloty.java b/tools/h2/src/test/org/h2/test/jdbc/TestZloty.java deleted file mode 100755 index 422bef6..0000000 --- a/tools/h2/src/test/org/h2/test/jdbc/TestZloty.java +++ /dev/null @@ -1,123 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.test.jdbc; - -import java.math.BigDecimal; -import java.sql.Connection; -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.SQLException; - -import org.h2.test.TestBase; - -/** - * Tests a custom BigDecimal implementation, as well - * as direct modification of a byte in a byte array. - */ -public class TestZloty extends TestBase { - - /** - * Run just this test. - * - * @param a ignored - */ - public static void main(String... a) throws Exception { - TestBase.createCaller().init().test(); - } - - public void test() throws SQLException { - testZloty(); - testModifyBytes(); - deleteDb("zloty"); - } - - /** - * This class overrides BigDecimal and implements some strange comparison method. - */ - private static class ZlotyBigDecimal extends BigDecimal { - - private static final long serialVersionUID = 1L; - - public ZlotyBigDecimal(String s) { - super(s); - } - - public int compareTo(BigDecimal bd) { - return -super.compareTo(bd); - } - - } - - private void testModifyBytes() throws SQLException { - deleteDb("zloty"); - Connection conn = getConnection("zloty"); - conn.createStatement().execute("CREATE TABLE TEST(ID INT, DATA BINARY)"); - PreparedStatement prep = conn.prepareStatement("INSERT INTO TEST VALUES(?, ?)"); - byte[] shared = { 0 }; - prep.setInt(1, 0); - prep.setBytes(2, shared); - prep.execute(); - shared[0] = 1; - prep.setInt(1, 1); - prep.setBytes(2, shared); - prep.execute(); - ResultSet rs = conn.createStatement().executeQuery("SELECT * FROM TEST ORDER BY ID"); - rs.next(); - assertEquals(0, rs.getInt(1)); - assertEquals(0, rs.getBytes(2)[0]); - rs.next(); - assertEquals(1, rs.getInt(1)); - assertEquals(1, rs.getBytes(2)[0]); - rs.getBytes(2)[0] = 2; - assertEquals(1, rs.getBytes(2)[0]); - assertFalse(rs.next()); - conn.close(); - } - - /** - * H2 destroyer application ;-> - * - * @author Maciej Wegorkiewicz - */ - private void testZloty() throws SQLException { - deleteDb("zloty"); - Connection conn = getConnection("zloty"); - conn.createStatement().execute("CREATE TABLE TEST(ID INT, AMOUNT DECIMAL)"); - PreparedStatement prep = conn.prepareStatement("INSERT INTO TEST VALUES(?, ?)"); - prep.setInt(1, 1); - prep.setBigDecimal(2, new BigDecimal("10.0")); - prep.execute(); - prep.setInt(1, 2); - try { - prep.setBigDecimal(2, new ZlotyBigDecimal("11.0")); - prep.execute(); - fail(); - } catch (SQLException e) { - assertKnownException(e); - } - - prep.setInt(1, 3); - try { - BigDecimal value = new BigDecimal("12.100000") { - - private static final long serialVersionUID = 1L; - - public String toString() { - return "12,100000 EURO"; - } - }; - prep.setBigDecimal(2, value); - prep.execute(); - fail(); - } catch (SQLException e) { - assertKnownException(e); - } - - conn.close(); - } - -} diff --git a/tools/h2/src/test/org/h2/test/jdbc/package.html b/tools/h2/src/test/org/h2/test/jdbc/package.html deleted file mode 100755 index f72dde7..0000000 --- a/tools/h2/src/test/org/h2/test/jdbc/package.html +++ /dev/null @@ -1,15 +0,0 @@ - - - - -Javadoc package documentation -

    - -JDBC API tests. - -

    \ No newline at end of file diff --git a/tools/h2/src/test/org/h2/test/jdbcx/TestConnectionPool.java b/tools/h2/src/test/org/h2/test/jdbcx/TestConnectionPool.java deleted file mode 100755 index eb2fdd3..0000000 --- a/tools/h2/src/test/org/h2/test/jdbcx/TestConnectionPool.java +++ /dev/null @@ -1,165 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.test.jdbcx; - -import java.io.PrintWriter; -import java.io.StringWriter; -import java.sql.Connection; -import java.sql.DriverManager; -import java.sql.SQLException; -import java.sql.Statement; - -import org.h2.jdbcx.JdbcConnectionPool; -import org.h2.jdbcx.JdbcDataSource; -import org.h2.test.TestBase; - -/** - * This class tests the JdbcConnectionPool. - */ -public class TestConnectionPool extends TestBase { - - /** - * Run just this test. - * - * @param a ignored - */ - public static void main(String... a) throws Exception { - TestBase.createCaller().init().test(); - } - - public void test() throws Exception { - deleteDb("connectionPool"); - testUncommittedTransaction(); - testPerformance(); - testKeepOpen(); - testConnect(); - testThreads(); - deleteDb("connectionPool"); - } - - private void testUncommittedTransaction() throws SQLException { - String url = getURL("connectionPool", true), user = getUser(), password = getPassword(); - JdbcConnectionPool man = JdbcConnectionPool.create(url, user, password); - - assertEquals(30, man.getLoginTimeout()); - man.setLoginTimeout(1); - assertEquals(1, man.getLoginTimeout()); - man.setLoginTimeout(0); - assertEquals(30, man.getLoginTimeout()); - assertEquals(10, man.getMaxConnections()); - - PrintWriter old = man.getLogWriter(); - PrintWriter pw = new PrintWriter(new StringWriter()); - man.setLogWriter(pw); - assertTrue(pw == man.getLogWriter()); - man.setLogWriter(old); - - Connection conn1 = man.getConnection(); - assertTrue(conn1.getAutoCommit()); - conn1.setAutoCommit(false); - conn1.close(); - assertTrue(conn1.isClosed()); - - Connection conn2 = man.getConnection(); - assertTrue(conn2.getAutoCommit()); - conn2.close(); - - man.dispose(); - } - - private void testPerformance() throws SQLException { - String url = getURL("connectionPool", true), user = getUser(), password = getPassword(); - JdbcConnectionPool man = JdbcConnectionPool.create(url, user, password); - Connection conn = man.getConnection(); - int len = 1000; - long time = System.currentTimeMillis(); - for (int i = 0; i < len; i++) { - man.getConnection().close(); - } - trace((int) (System.currentTimeMillis() - time)); - man.dispose(); - time = System.currentTimeMillis(); - for (int i = 0; i < len; i++) { - DriverManager.getConnection(url, user, password).close(); - } - trace((int) (System.currentTimeMillis() - time)); - conn.close(); - } - - private void testKeepOpen() throws Exception { - JdbcConnectionPool man = getConnectionPool(1); - Connection conn = man.getConnection(); - Statement stat = conn.createStatement(); - stat.execute("create local temporary table test(id int)"); - conn.close(); - conn = man.getConnection(); - stat = conn.createStatement(); - stat.execute("select * from test"); - conn.close(); - man.dispose(); - } - - private void testThreads() throws Exception { - final int len = getSize(4, 20); - final JdbcConnectionPool man = getConnectionPool(len - 2); - final boolean[] stop = { false }; - - /** - * This class gets and returns connections from the pool. - */ - class TestRunner implements Runnable { - public void run() { - try { - while (!stop[0]) { - Connection conn = man.getConnection(); - if (man.getActiveConnections() >= len + 1) { - throw new Exception("a: " + man.getActiveConnections() + " is not smaller than b: " + len + 1); - } - Statement stat = conn.createStatement(); - stat.execute("SELECT 1 FROM DUAL"); - conn.close(); - Thread.sleep(100); - } - } catch (Exception e) { - e.printStackTrace(); - } - } - } - Thread[] threads = new Thread[len]; - for (int i = 0; i < len; i++) { - threads[i] = new Thread(new TestRunner()); - threads[i].start(); - } - Thread.sleep(1000); - stop[0] = true; - for (int i = 0; i < len; i++) { - threads[i].join(); - } - assertEquals(0, man.getActiveConnections()); - man.dispose(); - } - - private JdbcConnectionPool getConnectionPool(int poolSize) { - JdbcDataSource ds = new JdbcDataSource(); - ds.setURL(getURL("connectionPool", true)); - ds.setUser(getUser()); - ds.setPassword(getPassword()); - JdbcConnectionPool pool = JdbcConnectionPool.create(ds); - pool.setMaxConnections(poolSize); - return pool; - } - - private void testConnect() throws SQLException { - JdbcConnectionPool man = getConnectionPool(3); - for (int i = 0; i < 100; i++) { - Connection conn = man.getConnection(); - conn.close(); - } - man.dispose(); - } - -} diff --git a/tools/h2/src/test/org/h2/test/jdbcx/TestDataSource.java b/tools/h2/src/test/org/h2/test/jdbcx/TestDataSource.java deleted file mode 100755 index 8e7e0f4..0000000 --- a/tools/h2/src/test/org/h2/test/jdbcx/TestDataSource.java +++ /dev/null @@ -1,155 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.test.jdbcx; - -import java.io.PrintWriter; -import java.io.StringWriter; -import java.sql.Connection; -import java.sql.SQLException; -import java.sql.Statement; -import javax.naming.Reference; -import javax.naming.StringRefAddr; -import javax.naming.spi.ObjectFactory; -import javax.sql.ConnectionEvent; -import javax.sql.ConnectionEventListener; -import javax.sql.XAConnection; -import javax.transaction.xa.XAResource; -import javax.transaction.xa.Xid; -import org.h2.jdbcx.JdbcDataSource; -import org.h2.jdbcx.JdbcDataSourceFactory; -import org.h2.jdbcx.JdbcXAConnection; -import org.h2.test.TestBase; - -/** - * Tests DataSource and XAConnection. - */ -public class TestDataSource extends TestBase { - - /** - * Run just this test. - * - * @param a ignored - */ - public static void main(String... a) throws Exception { - TestBase.createCaller().init().test(); - } - -// public static void main(String... args) throws SQLException { -// -// // first, need to start on the command line: -// // rmiregistry 1099 -// -// // System.setProperty(Context.INITIAL_CONTEXT_FACTORY, -// "com.sun.jndi.ldap.LdapCtxFactory"); -// System.setProperty(Context.INITIAL_CONTEXT_FACTORY, -// "com.sun.jndi.rmi.registry.RegistryContextFactory"); -// System.setProperty(Context.PROVIDER_URL, "rmi://localhost:1099"); -// -// JdbcDataSource ds = new JdbcDataSource(); -// ds.setURL("jdbc:h2:test"); -// ds.setUser("test"); -// ds.setPassword(""); -// -// Context ctx = new InitialContext(); -// ctx.bind("jdbc/test", ds); -// -// DataSource ds2 = (DataSource)ctx.lookup("jdbc/test"); -// Connection conn = ds2.getConnection(); -// conn.close(); -// } - - public void test() throws Exception { - testDataSourceFactory(); - testDataSource(); - testXAConnection(); - deleteDb("dataSource"); - } - - private void testDataSourceFactory() throws Exception { - ObjectFactory factory = new JdbcDataSourceFactory(); - assertTrue(null == factory.getObjectInstance("test", null, null, null)); - Reference ref = new Reference("java.lang.String"); - assertTrue(null == factory.getObjectInstance(ref, null, null, null)); - ref = new Reference(JdbcDataSource.class.getName()); - ref.add(new StringRefAddr("url", "jdbc:h2:mem:")); - ref.add(new StringRefAddr("user", "u")); - ref.add(new StringRefAddr("password", "p")); - ref.add(new StringRefAddr("loginTimeout", "1")); - ref.add(new StringRefAddr("description", "test")); - JdbcDataSource ds = (JdbcDataSource) factory.getObjectInstance(ref, null, null, null); - assertEquals(1, ds.getLoginTimeout()); - assertEquals("jdbc:h2:mem:", ds.getURL()); - assertEquals("u", ds.getUser()); - assertEquals("p", ds.getPassword()); - Reference ref2 = ds.getReference(); - assertEquals(ref.size(), ref2.size()); - assertEquals(ref.get("url").getContent().toString(), ref2.get("url").getContent().toString()); - assertEquals(ref.get("user").getContent().toString(), ref2.get("user").getContent().toString()); - assertEquals(ref.get("password").getContent().toString(), ref2.get("password").getContent().toString()); - assertEquals(ref.get("loginTimeout").getContent().toString(), ref2.get("loginTimeout").getContent().toString()); - assertEquals(ref.get("description").getContent().toString(), ref2.get("description").getContent().toString()); - ds.setPasswordChars("abc".toCharArray()); - assertEquals("abc", ds.getPassword()); - } - - private void testXAConnection() throws Exception { - deleteDb("dataSource"); - JdbcDataSource ds = new JdbcDataSource(); - String url = getURL("dataSource", true); - String user = getUser(); - ds.setURL(url); - ds.setUser(user); - ds.setPassword(getPassword()); - - assertEquals("ds" + ds.getTraceId() + ": url=" + url + " user=" + user, ds.toString()); - - XAConnection xaConn = ds.getXAConnection(); - - int traceId = ((JdbcXAConnection) xaConn).getTraceId(); - assertEquals("xads" + traceId + ": url=" + url + " user=" + user, xaConn.toString()); - - xaConn.addConnectionEventListener(new ConnectionEventListener() { - public void connectionClosed(ConnectionEvent event) { - // nothing to do - } - - public void connectionErrorOccurred(ConnectionEvent event) { - // nothing to do - } - }); - XAResource res = xaConn.getXAResource(); - - assertFalse(res.setTransactionTimeout(1)); - assertEquals(0, res.getTransactionTimeout()); - assertTrue(res.isSameRM(res)); - assertFalse(res.isSameRM(null)); - - Connection conn = xaConn.getConnection(); - Xid[] list = res.recover(XAResource.TMSTARTRSCAN); - assertEquals(0, list.length); - Statement stat = conn.createStatement(); - stat.execute("SELECT * FROM DUAL"); - conn.close(); - xaConn.close(); - } - - private void testDataSource() throws SQLException { - deleteDb("dataSource"); - JdbcDataSource ds = new JdbcDataSource(); - PrintWriter p = new PrintWriter(new StringWriter()); - ds.setLogWriter(p); - assertTrue(p == ds.getLogWriter()); - ds.setURL(getURL("dataSource", true)); - ds.setUser(getUser()); - ds.setPassword(getPassword()); - Connection conn = ds.getConnection(); - Statement stat = conn.createStatement(); - stat.execute("SELECT * FROM DUAL"); - conn.close(); - } - -} diff --git a/tools/h2/src/test/org/h2/test/jdbcx/TestXA.java b/tools/h2/src/test/org/h2/test/jdbcx/TestXA.java deleted file mode 100755 index 82e2028..0000000 --- a/tools/h2/src/test/org/h2/test/jdbcx/TestXA.java +++ /dev/null @@ -1,275 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: James Devenish - */ -package org.h2.test.jdbcx; - -import java.sql.Connection; -import java.sql.SQLException; -import java.sql.Statement; -import javax.sql.XAConnection; -import javax.sql.XADataSource; -import javax.transaction.xa.XAResource; -import javax.transaction.xa.Xid; - -import org.h2.jdbcx.JdbcDataSource; -import org.h2.test.TestBase; -import org.h2.util.JdbcUtils; - -/** - * Basic XA tests. - */ -public class TestXA extends TestBase { - - private static final String DB_NAME1 = "xadb1"; - private static final String DB_NAME2 = "xadb2"; - - /** - * Run just this test. - * - * @param a ignored - */ - public static void main(String... a) throws Exception { - TestBase.createCaller().init().test(); - } - - public void test() throws Exception { - testXAAutoCommit(); - deleteDb("xa"); - testXA(true); - deleteDb(DB_NAME1); - deleteDb(DB_NAME2); - testXA(false); - deleteDb("xa"); - deleteDb(DB_NAME1); - deleteDb(DB_NAME2); - } - - /** - * A simple Xid implementation. - */ - public static class MyXid implements Xid { - private byte[] branchQualifier = { 0 }; - private byte[] globalTransactionId = { 0 }; - public byte[] getBranchQualifier() { - return branchQualifier; - } - public int getFormatId() { - return 0; - } - public byte[] getGlobalTransactionId() { - return globalTransactionId; - } - } - - private void testXAAutoCommit() throws Exception { - JdbcDataSource ds = new JdbcDataSource(); - ds.setURL("jdbc:h2:mem:test"); - ds.setUser("sa"); - ds.setPassword(""); - XAConnection xa = ds.getXAConnection(); - MyXid xid = new MyXid(); - xa.getXAResource().start(xid, - XAResource.TMNOFLAGS); - Connection c = xa.getConnection(); - assertTrue(!c.getAutoCommit()); - c.close(); - xa.close(); - } - - private void testXA(boolean useOneDatabase) { - String url1 = getURL(DB_NAME1, true); - String url2 = getURL(DB_NAME2, true); - - XAConnection xaConn1 = null; - XAConnection xaConn2 = null; - Connection conn1 = null; - Connection conn2 = null; - Statement stat1 = null; - Statement stat2 = null; - try { - trace("xads1 = createXADatasource1()"); - XADataSource xaDs1 = createXADatasource(useOneDatabase, url1); - trace("xads2 = createXADatasource2()"); - XADataSource xaDs2 = createXADatasource(useOneDatabase, url2); - - trace("xacon1 = xads1.getXAConnection()"); - xaConn1 = xaDs1.getXAConnection(); - trace("xacon2 = xads2.getXAConnection()"); - xaConn2 = xaDs2.getXAConnection(); - - trace("xares1 = xacon1.getXAResource()"); - XAResource xares1 = xaConn1.getXAResource(); - trace("xares2 = xacon2.getXAResource()"); - XAResource xares2 = xaConn2.getXAResource(); - - trace("xares1.recover(XAResource.TMSTARTRSCAN)"); - Xid[] xids1 = xares1.recover(XAResource.TMSTARTRSCAN); - if ((xids1 == null) || (xids1.length == 0)) { - trace("xares1.recover(XAResource.TMSTARTRSCAN): 0"); - } else { - trace("xares1.recover(XAResource.TMSTARTRSCAN): " + xids1.length); - } - - trace("xares2.recover(XAResource.TMSTARTRSCAN)"); - Xid[] xids2 = xares2.recover(XAResource.TMSTARTRSCAN); - if ((xids2 == null) || (xids2.length == 0)) { - trace("xares2.recover(XAResource.TMSTARTRSCAN): 0"); - } else { - trace("xares2.recover(XAResource.TMSTARTRSCAN): " + xids2.length); - } - - trace("con1 = xacon1.getConnection()"); - conn1 = xaConn1.getConnection(); - trace("stmt1 = con1.createStatement()"); - stat1 = conn1.createStatement(); - - trace("con2 = xacon2.getConnection()"); - conn2 = xaConn2.getConnection(); - trace("stmt2 = con2.createStatement()"); - stat2 = conn2.createStatement(); - - if (useOneDatabase) { - trace("stmt1.executeUpdate(\"DROP TABLE xatest1\")"); - try { - stat1.executeUpdate("DROP TABLE xatest1"); - } catch (SQLException e) { - // ignore - } - trace("stmt2.executeUpdate(\"DROP TABLE xatest2\")"); - try { - stat2.executeUpdate("DROP TABLE xatest2"); - } catch (SQLException e) { - // ignore - } - } else { - trace("stmt1.executeUpdate(\"DROP TABLE xatest\")"); - try { - stat1.executeUpdate("DROP TABLE xatest"); - } catch (SQLException e) { - // ignore - } - trace("stmt2.executeUpdate(\"DROP TABLE xatest\")"); - try { - stat2.executeUpdate("DROP TABLE xatest"); - } catch (SQLException e) { - // ignore - } - } - - if (useOneDatabase) { - trace("stmt1.executeUpdate(\"CREATE TABLE xatest1 (id INT PRIMARY KEY, value INT)\")"); - stat1.executeUpdate("CREATE TABLE xatest1 (id INT PRIMARY KEY, value INT)"); - trace("stmt2.executeUpdate(\"CREATE TABLE xatest2 (id INT PRIMARY KEY, value INT)\")"); - stat2.executeUpdate("CREATE TABLE xatest2 (id INT PRIMARY KEY, value INT)"); - } else { - trace("stmt1.executeUpdate(\"CREATE TABLE xatest (id INT PRIMARY KEY, value INT)\")"); - stat1.executeUpdate("CREATE TABLE xatest (id INT PRIMARY KEY, value INT)"); - trace("stmt2.executeUpdate(\"CREATE TABLE xatest (id INT PRIMARY KEY, value INT)\")"); - stat2.executeUpdate("CREATE TABLE xatest (id INT PRIMARY KEY, value INT)"); - } - - if (useOneDatabase) { - trace("stmt1.executeUpdate(\"INSERT INTO xatest1 VALUES (1, 0)\")"); - stat1.executeUpdate("INSERT INTO xatest1 VALUES (1, 0)"); - trace("stmt2.executeUpdate(\"INSERT INTO xatest2 VALUES (2, 0)\")"); - stat2.executeUpdate("INSERT INTO xatest2 VALUES (2, 0)"); - } else { - trace("stmt1.executeUpdate(\"INSERT INTO xatest VALUES (1, 0)\")"); - stat1.executeUpdate("INSERT INTO xatest VALUES (1, 0)"); - trace("stmt2.executeUpdate(\"INSERT INTO xatest VALUES (2, 0)\")"); - stat2.executeUpdate("INSERT INTO xatest VALUES (2, 0)"); - } - - Xid xid1 = null; - Xid xid2 = null; - - if (useOneDatabase) { - xid1 = new TestXid(1); - xid2 = new TestXid(2); - } else { - xid1 = new TestXid(1); - xid2 = xid1; - } - - if (useOneDatabase) { - trace("xares1.start(xid1, XAResource.TMNOFLAGS)"); - xares1.start(xid1, XAResource.TMNOFLAGS); - trace("xares2.start(xid2, XAResource.TMJOIN)"); - xares2.start(xid2, XAResource.TMJOIN); - } else { - trace("xares1.start(xid1, XAResource.TMNOFLAGS)"); - xares1.start(xid1, XAResource.TMNOFLAGS); - trace("xares2.start(xid2, XAResource.TMNOFLAGS)"); - xares2.start(xid2, XAResource.TMNOFLAGS); - } - - if (useOneDatabase) { - trace("stmt1.executeUpdate(\"UPDATE xatest1 SET value=1 WHERE id=1\")"); - stat1.executeUpdate("UPDATE xatest1 SET value=1 WHERE id=1"); - trace("stmt2.executeUpdate(\"UPDATE xatest2 SET value=1 WHERE id=2\")"); - stat2.executeUpdate("UPDATE xatest2 SET value=1 WHERE id=2"); - } else { - trace("stmt1.executeUpdate(\"UPDATE xatest SET value=1 WHERE id=1\")"); - stat1.executeUpdate("UPDATE xatest SET value=1 WHERE id=1"); - trace("stmt2.executeUpdate(\"UPDATE xatest SET value=1 WHERE id=2\")"); - stat2.executeUpdate("UPDATE xatest SET value=1 WHERE id=2"); - } - - trace("xares1.end(xid1, XAResource.TMSUCCESS)"); - xares1.end(xid1, XAResource.TMSUCCESS); - trace("xares2.end(xid2, XAResource.TMSUCCESS)"); - xares2.end(xid2, XAResource.TMSUCCESS); - - int ret1; - int ret2; - - trace("ret1 = xares1.prepare(xid1)"); - ret1 = xares1.prepare(xid1); - trace("xares1.prepare(xid1): " + ret1); - trace("ret2 = xares2.prepare(xid2)"); - ret2 = xares2.prepare(xid2); - trace("xares2.prepare(xid2): " + ret2); - - if ((ret1 != XAResource.XA_OK) && (ret1 != XAResource.XA_RDONLY)) { - throw new IllegalStateException("xares1.prepare(xid1) must return XA_OK or XA_RDONLY"); - } - if ((ret2 != XAResource.XA_OK) && (ret2 != XAResource.XA_RDONLY)) { - throw new IllegalStateException("xares2.prepare(xid2) must return XA_OK or XA_RDONLY"); - } - - if (ret1 == XAResource.XA_OK) { - trace("xares1.commit(xid1, false)"); - xares1.commit(xid1, false); - } - if (ret2 == XAResource.XA_OK) { - trace("xares2.commit(xid2, false)"); - xares2.commit(xid2, false); - } - } catch (Exception e) { - e.printStackTrace(); - } finally { - JdbcUtils.closeSilently(stat1); - JdbcUtils.closeSilently(stat2); - JdbcUtils.closeSilently(conn1); - JdbcUtils.closeSilently(conn2); - JdbcUtils.closeSilently(xaConn1); - JdbcUtils.closeSilently(xaConn2); - } - } - - private XADataSource createXADatasource(boolean useOneDatabase, String url) { - JdbcDataSource ds = new JdbcDataSource(); - ds.setPassword(getPassword("")); - ds.setUser("sa"); - if (useOneDatabase) { - ds.setURL(getURL("xa", true)); - } else { - ds.setURL(url); - } - return ds; - } - -} diff --git a/tools/h2/src/test/org/h2/test/jdbcx/TestXASimple.java b/tools/h2/src/test/org/h2/test/jdbcx/TestXASimple.java deleted file mode 100755 index 66909ef..0000000 --- a/tools/h2/src/test/org/h2/test/jdbcx/TestXASimple.java +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.test.jdbcx; - -import java.sql.Connection; -import java.sql.SQLException; - -import javax.sql.XAConnection; - -import org.h2.jdbcx.JdbcDataSource; -import org.h2.test.TestBase; - -/** - * A simple XA test. - */ -public class TestXASimple extends TestBase { - - /** - * Run just this test. - * - * @param a ignored - */ - public static void main(String... a) throws Exception { - TestBase.createCaller().init().test(); - } - - public void test() throws SQLException { - - deleteDb("xaSimple1"); - deleteDb("xaSimple2"); - org.h2.Driver.load(); - - // InitialContext context = new InitialContext(); - // context.rebind(USER_TRANSACTION_JNDI_NAME, j.getUserTransaction()); - - JdbcDataSource ds1 = new JdbcDataSource(); - ds1.setPassword(getPassword()); - ds1.setUser("sa"); - ds1.setURL(getURL("xaSimple1", true)); - - JdbcDataSource ds2 = new JdbcDataSource(); - ds2.setPassword(getPassword()); - ds2.setUser("sa"); - ds2.setURL(getURL("xaSimple2", true)); - - // UserTransaction ut = (UserTransaction) - // context.lookup("UserTransaction"); - // ut.begin(); - - XAConnection xa1 = ds1.getXAConnection(); - Connection c1 = xa1.getConnection(); - c1.setAutoCommit(false); - XAConnection xa2 = ds2.getXAConnection(); - Connection c2 = xa2.getConnection(); - c2.setAutoCommit(false); - - c1.createStatement().executeUpdate("create table test(id int, test varchar(255))"); - c2.createStatement().executeUpdate("create table test(id int, test varchar(255))"); - - // ut.rollback(); - c1.close(); - c2.close(); - - xa1.close(); - xa2.close(); - - // j.stop(); - // System.exit(0); - deleteDb("xaSimple1"); - deleteDb("xaSimple2"); - - } -} diff --git a/tools/h2/src/test/org/h2/test/jdbcx/TestXid.java b/tools/h2/src/test/org/h2/test/jdbcx/TestXid.java deleted file mode 100755 index e96245a..0000000 --- a/tools/h2/src/test/org/h2/test/jdbcx/TestXid.java +++ /dev/null @@ -1,108 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: James Devenish - */ -package org.h2.test.jdbcx; - -import java.net.InetAddress; -import java.net.UnknownHostException; -import java.text.NumberFormat; -import javax.transaction.xa.Xid; - -/** - * A utility class for the basic XA test. - */ -public class TestXid implements Xid { - private static final NumberFormat NF; - - private static int fXidCounter; - private int fFormatId; - private byte[] fGlobalTransactionId; - private byte[] fBranchQualifier; - private int fId; - private long fCreationTime; - - static { - NumberFormat nf = NumberFormat.getIntegerInstance(); - nf.setMaximumIntegerDigits(5); - nf.setMinimumIntegerDigits(5); - nf.setGroupingUsed(false); - NF = nf; - } - - public TestXid() { - this(1); - } - - public TestXid(int branch) { - synchronized (TestXid.class) { - fXidCounter++; - fId = fXidCounter; - } - fCreationTime = System.currentTimeMillis(); - String host; - try { - InetAddress ia = InetAddress.getLocalHost(); - host = ia.getHostName(); - } catch (UnknownHostException e) { - host = "localhost"; - } - - fFormatId = 0; - fGlobalTransactionId = new byte[MAXGTRIDSIZE]; - fBranchQualifier = new byte[MAXBQUALSIZE]; - - StringBuilder sb; - byte[] ba; - - sb = new StringBuilder(); - sb.append(host); - sb.append(":"); - sb.append(fId); - sb.append(":"); - sb.append(fCreationTime); - // System.out.println("global transaction id: " + sb.toString()); - ba = sb.toString().getBytes(); - - for (int i = 0; i < MAXGTRIDSIZE; i++) { - fGlobalTransactionId[i] = (byte) ' '; - } - for (int i = 0; i < ba.length; i++) { - fGlobalTransactionId[i] = ba[i]; - } - - sb = new StringBuilder(NF.format(branch)); - // System.out.println("branch qualifier: " + sb.toString()); - ba = sb.toString().getBytes(); - for (int i = 0; i < MAXBQUALSIZE; i++) { - fBranchQualifier[i] = (byte) ' '; - } - for (int i = 0; i < ba.length; i++) { - fBranchQualifier[i] = ba[i]; - } - } - - /** - * This method is called when executing this application. - * - * @param args the command line parameters - */ - public static void main(String... args) { - new TestXid(); - } - - public int getFormatId() { - return fFormatId; - } - - public byte[] getGlobalTransactionId() { - return fGlobalTransactionId; - } - - public byte[] getBranchQualifier() { - return fBranchQualifier; - } - -} diff --git a/tools/h2/src/test/org/h2/test/jdbcx/package.html b/tools/h2/src/test/org/h2/test/jdbcx/package.html deleted file mode 100755 index 96c0aa2..0000000 --- a/tools/h2/src/test/org/h2/test/jdbcx/package.html +++ /dev/null @@ -1,15 +0,0 @@ - - - - -Javadoc package documentation -

    - -Tests related to distributed transactions. - -

    \ No newline at end of file diff --git a/tools/h2/src/test/org/h2/test/mvcc/TestMvcc1.java b/tools/h2/src/test/org/h2/test/mvcc/TestMvcc1.java deleted file mode 100755 index 2dd64dd..0000000 --- a/tools/h2/src/test/org/h2/test/mvcc/TestMvcc1.java +++ /dev/null @@ -1,407 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.test.mvcc; - -import java.sql.Connection; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.sql.Statement; -import java.util.Random; - -import org.h2.constant.ErrorCode; -import org.h2.test.TestBase; - -/** - * Basic MVCC (multi version concurrency) test cases. - */ -public class TestMvcc1 extends TestBase { - - private Connection c1, c2; - private Statement s1, s2; - - /** - * Run just this test. - * - * @param a ignored - */ - public static void main(String... a) throws Exception { - TestBase.createCaller().init().test(); - } - - public void test() throws SQLException { - testCases(); - testSetMode(); - deleteDb("mvcc1"); - } - - private void testSetMode() throws SQLException { - deleteDb("mvcc1"); - c1 = getConnection("mvcc1;MVCC=FALSE"); - Statement stat = c1.createStatement(); - ResultSet rs = stat.executeQuery("select * from information_schema.settings where name='MVCC'"); - rs.next(); - assertEquals("FALSE", rs.getString("VALUE")); - try { - stat.execute("SET MVCC TRUE"); - fail(); - } catch (SQLException e) { - assertEquals(ErrorCode.CANNOT_CHANGE_SETTING_WHEN_OPEN_1, e.getErrorCode()); - } - rs = stat.executeQuery("select * from information_schema.settings where name='MVCC'"); - rs.next(); - assertEquals("FALSE", rs.getString("VALUE")); - c1.close(); - } - - private void testCases() throws SQLException { - if (!config.mvcc) { - return; - } - // TODO Prio 1: document: exclusive table lock still used when altering - // tables, adding indexes, select ... for update; table level locks are - // checked - // TODO Prio 2: if MVCC is used, rows of transactions need to fit in - // memory - // TODO Prio 2: getFirst / getLast in MultiVersionIndex - // TODO Prio 2: snapshot isolation (currently read-committed, not - // repeatable read) - - // TODO test: one thread appends, the other - // selects new data (select * from test where id > ?) and deletes - - deleteDb("mvcc1"); - c1 = getConnection("mvcc1;MVCC=TRUE;LOCK_TIMEOUT=10"); - s1 = c1.createStatement(); - c2 = getConnection("mvcc1;MVCC=TRUE;LOCK_TIMEOUT=10"); - s2 = c2.createStatement(); - c1.setAutoCommit(false); - c2.setAutoCommit(false); - - // table rollback problem - try { - s1.execute("create table b(primary key(x))"); - fail(); - } catch (SQLException e) { - // ok - } - s1.execute("create table a(id int as 1 unique)"); - s1.execute("drop table a"); - - // update same key problem - s1.execute("CREATE TABLE TEST(ID INT, NAME VARCHAR, PRIMARY KEY(ID))"); - s1.execute("INSERT INTO TEST VALUES(1, 'Hello')"); - c1.commit(); - assertResult("Hello", s2, "SELECT NAME FROM TEST WHERE ID=1"); - s1.execute("UPDATE TEST SET NAME = 'Hallo' WHERE ID=1"); - assertResult("Hello", s2, "SELECT NAME FROM TEST WHERE ID=1"); - assertResult("Hallo", s1, "SELECT NAME FROM TEST WHERE ID=1"); - s1.execute("DROP TABLE TEST"); - c1.commit(); - c2.commit(); - - // referential integrity problem - s1.execute("create table a (id integer identity not null, code varchar(10) not null, primary key(id))"); - s1.execute("create table b (name varchar(100) not null, a integer, primary key(name), foreign key(a) references a(id))"); - s1.execute("insert into a(code) values('one')"); - try { - s2.execute("insert into b values('un B', 1)"); - fail(); - } catch (SQLException e) { - assertKnownException(e); - } - c2.commit(); - c1.rollback(); - s1.execute("drop table a, b"); - c2.commit(); - - // it should not be possible to drop a table - // when an uncommitted transaction changed something - s1.execute("create table test(id int primary key)"); - s1.execute("insert into test values(1)"); - try { - s2.execute("drop table test"); - fail(); - } catch (SQLException e) { - // lock timeout expected - assertKnownException(e); - } - c1.rollback(); - s2.execute("drop table test"); - c2.rollback(); - - // table scan problem - s1.execute("create table test(id int, name varchar)"); - s1.execute("insert into test values(1, 'A'), (2, 'B')"); - c1.commit(); - assertResult("2", s1, "select count(*) from test where name<>'C'"); - s2.execute("update test set name='B2' where id=2"); - assertResult("2", s1, "select count(*) from test where name<>'C'"); - c2.commit(); - s2.execute("drop table test"); - c2.rollback(); - - // select for update should do an exclusive lock, even with mvcc - s1.execute("create table test(id int primary key, name varchar(255))"); - s1.execute("insert into test values(1, 'y')"); - c1.commit(); - s2.execute("select * from test for update"); - try { - s1.execute("insert into test values(2, 'x')"); - fail(); - } catch (SQLException e) { - // lock timeout expected - assertKnownException(e); - } - c2.rollback(); - s1.execute("drop table test"); - c1.commit(); - c2.commit(); - - s1.execute("create table test(id int primary key, name varchar(255))"); - s2.execute("insert into test values(4, 'Hello')"); - c2.rollback(); - assertResult("0", s1, "select count(*) from test where name = 'Hello'"); - assertResult("0", s2, "select count(*) from test where name = 'Hello'"); - c1.commit(); - c2.commit(); - s1.execute("DROP TABLE TEST"); - - s1.execute("CREATE TABLE TEST(ID INT PRIMARY KEY, NAME VARCHAR(255))"); - s1.execute("INSERT INTO TEST VALUES(1, 'Test')"); - c1.commit(); - assertResult("1", s1, "select max(id) from test"); - s1.execute("INSERT INTO TEST VALUES(2, 'World')"); - c1.rollback(); - assertResult("1", s1, "select max(id) from test"); - c1.commit(); - c2.commit(); - s1.execute("DROP TABLE TEST"); - - - s1.execute("create table test as select * from table(id int=(1, 2))"); - s1.execute("update test set id=1 where id=1"); - s1.execute("select max(id) from test"); - assertResult("2", s1, "select max(id) from test"); - c1.commit(); - c2.commit(); - s1.execute("DROP TABLE TEST"); - - s1.execute("CREATE TABLE TEST(ID INT)"); - s1.execute("INSERT INTO TEST VALUES(1)"); - c1.commit(); - assertResult("1", s2, "SELECT COUNT(*) FROM TEST"); - s1.executeUpdate("DELETE FROM TEST"); - assertResult("1", s2, "SELECT COUNT(*) FROM TEST"); - assertResult("0", s1, "SELECT COUNT(*) FROM TEST"); - c1.commit(); - assertResult("0", s2, "SELECT COUNT(*) FROM TEST"); - c1.commit(); - c2.commit(); - s1.execute("DROP TABLE TEST"); - - s1.execute("CREATE TABLE TEST(ID INT)"); - s1.execute("INSERT INTO TEST VALUES(1)"); - c1.commit(); - s1.execute("DELETE FROM TEST"); - assertResult("0", s1, "SELECT COUNT(*) FROM TEST"); - c1.commit(); - assertResult("0", s1, "SELECT COUNT(*) FROM TEST"); - s1.execute("INSERT INTO TEST VALUES(1)"); - s1.execute("DELETE FROM TEST"); - c1.commit(); - assertResult("0", s1, "SELECT COUNT(*) FROM TEST"); - s1.execute("DROP TABLE TEST"); - - s1.execute("CREATE TABLE TEST(ID INT PRIMARY KEY, NAME VARCHAR)"); - s1.execute("INSERT INTO TEST VALUES(1, 'Hello'), (2, 'World')"); - assertResult("0", s2, "SELECT COUNT(*) FROM TEST"); - c1.commit(); - assertResult("2", s2, "SELECT COUNT(*) FROM TEST"); - s1.execute("INSERT INTO TEST VALUES(3, '!')"); - c1.rollback(); - assertResult("2", s2, "SELECT COUNT(*) FROM TEST"); - s1.execute("DROP TABLE TEST"); - c1.commit(); - - s1.execute("CREATE TABLE TEST(ID INT PRIMARY KEY, NAME VARCHAR)"); - s1.execute("INSERT INTO TEST VALUES(1, 'Hello')"); - s1.execute("DELETE FROM TEST"); - assertResult("0", s2, "SELECT COUNT(*) FROM TEST"); - c1.commit(); - assertResult("0", s2, "SELECT COUNT(*) FROM TEST"); - s1.execute("DROP TABLE TEST"); - c1.commit(); - - s1.execute("CREATE TABLE TEST(ID INT IDENTITY, NAME VARCHAR)"); - s1.execute("INSERT INTO TEST(NAME) VALUES('Ruebezahl')"); - assertResult("0", s2, "SELECT COUNT(*) FROM TEST"); - assertResult("1", s1, "SELECT COUNT(*) FROM TEST"); - s1.execute("DROP TABLE TEST"); - c1.commit(); - - s1.execute("CREATE TABLE TEST(ID INT IDENTITY, NAME VARCHAR)"); - s1.execute("INSERT INTO TEST(NAME) VALUES('Ruebezahl')"); - s1.execute("INSERT INTO TEST(NAME) VALUES('Ruebezahl')"); - s1.execute("DROP TABLE TEST"); - c1.commit(); - - s1.execute("CREATE TABLE TEST(ID INT PRIMARY KEY, NAME VARCHAR)"); - s1.execute("INSERT INTO TEST VALUES(1, 'Hello')"); - c1.commit(); - s1.execute("DELETE FROM TEST WHERE ID=1"); - c1.rollback(); - s1.execute("DROP TABLE TEST"); - c1.commit(); - - Random random = new Random(1); - s1.execute("CREATE TABLE TEST(ID INT IDENTITY, NAME VARCHAR)"); - Statement s; - Connection c; - for (int i = 0; i < 1000; i++) { - if (random.nextBoolean()) { - s = s1; - c = c1; - } else { - s = s2; - c = c2; - } - switch (random.nextInt(5)) { - case 0: - s.execute("INSERT INTO TEST(NAME) VALUES('Hello')"); - break; - case 1: - s.execute("UPDATE TEST SET NAME=" + i + " WHERE ID=" + random.nextInt(i)); - break; - case 2: - s.execute("DELETE FROM TEST WHERE ID=" + random.nextInt(i)); - break; - case 3: - c.commit(); - break; - case 4: - c.rollback(); - break; - default: - } - s1.execute("SELECT * FROM TEST ORDER BY ID"); - s2.execute("SELECT * FROM TEST ORDER BY ID"); - } - c2.rollback(); - s1.execute("DROP TABLE TEST"); - c1.commit(); - c2.commit(); - - random = new Random(1); - s1.execute("CREATE TABLE TEST(ID INT PRIMARY KEY, NAME VARCHAR)"); - for (int i = 0; i < 1000; i++) { - if (random.nextBoolean()) { - s = s1; - c = c1; - } else { - s = s2; - c = c2; - } - switch (random.nextInt(5)) { - case 0: - s.execute("INSERT INTO TEST VALUES(" + i + ", 'Hello')"); - break; - case 1: - try { - s.execute("UPDATE TEST SET NAME=" + i + " WHERE ID=" + random.nextInt(i)); - } catch (SQLException e) { - assertEquals(ErrorCode.CONCURRENT_UPDATE_1, e.getErrorCode()); - } - break; - case 2: - s.execute("DELETE FROM TEST WHERE ID=" + random.nextInt(i)); - break; - case 3: - c.commit(); - break; - case 4: - c.rollback(); - break; - default: - } - s1.execute("SELECT * FROM TEST ORDER BY ID"); - s2.execute("SELECT * FROM TEST ORDER BY ID"); - } - c2.rollback(); - s1.execute("DROP TABLE TEST"); - c1.commit(); - c2.commit(); - - s1.execute("CREATE TABLE TEST(ID INT, NAME VARCHAR)"); - s1.execute("INSERT INTO TEST VALUES(1, 'Hello')"); - assertResult("0", s2, "SELECT COUNT(*) FROM TEST WHERE NAME!='X'"); - assertResult("1", s1, "SELECT COUNT(*) FROM TEST WHERE NAME!='X'"); - c1.commit(); - assertResult("1", s2, "SELECT COUNT(*) FROM TEST WHERE NAME!='X'"); - assertResult("1", s2, "SELECT COUNT(*) FROM TEST WHERE NAME!='X'"); - s1.execute("DROP TABLE TEST"); - c1.commit(); - c2.commit(); - - s1.execute("CREATE TABLE TEST(ID INT PRIMARY KEY, NAME VARCHAR)"); - s1.execute("INSERT INTO TEST VALUES(1, 'Hello')"); - assertResult("0", s2, "SELECT COUNT(*) FROM TEST WHERE ID<100"); - assertResult("1", s1, "SELECT COUNT(*) FROM TEST WHERE ID<100"); - c1.commit(); - assertResult("1", s2, "SELECT COUNT(*) FROM TEST WHERE ID<100"); - assertResult("1", s2, "SELECT COUNT(*) FROM TEST WHERE ID<100"); - s1.execute("DROP TABLE TEST"); - c1.commit(); - c2.commit(); - - s1.execute("CREATE TABLE TEST(ID INT, NAME VARCHAR, PRIMARY KEY(ID, NAME))"); - s1.execute("INSERT INTO TEST VALUES(1, 'Hello')"); - c1.commit(); - assertResult("Hello", s2, "SELECT NAME FROM TEST WHERE ID=1"); - s1.execute("UPDATE TEST SET NAME = 'Hallo' WHERE ID=1"); - assertResult("Hello", s2, "SELECT NAME FROM TEST WHERE ID=1"); - assertResult("Hallo", s1, "SELECT NAME FROM TEST WHERE ID=1"); - s1.execute("DROP TABLE TEST"); - c1.commit(); - c2.commit(); - - - s1.execute("create table test(id int primary key, name varchar(255))"); - s1.execute("insert into test values(1, 'Hello'), (2, 'World')"); - c1.commit(); - try { - s1.execute("update test set id=2 where id=1"); - fail(); - } catch (SQLException e) { - assertKnownException(e); - } - ResultSet rs = s1.executeQuery("select * from test order by id"); - assertTrue(rs.next()); - assertEquals(1, rs.getInt(1)); - assertEquals("Hello", rs.getString(2)); - assertTrue(rs.next()); - assertEquals(2, rs.getInt(1)); - assertEquals("World", rs.getString(2)); - assertFalse(rs.next()); - - rs = s2.executeQuery("select * from test order by id"); - assertTrue(rs.next()); - assertEquals(1, rs.getInt(1)); - assertEquals("Hello", rs.getString(2)); - assertTrue(rs.next()); - assertEquals(2, rs.getInt(1)); - assertEquals("World", rs.getString(2)); - assertFalse(rs.next()); - s1.execute("drop table test"); - c1.commit(); - c2.commit(); - - c1.close(); - c2.close(); - - } - -} diff --git a/tools/h2/src/test/org/h2/test/mvcc/TestMvcc2.java b/tools/h2/src/test/org/h2/test/mvcc/TestMvcc2.java deleted file mode 100755 index 14b1be6..0000000 --- a/tools/h2/src/test/org/h2/test/mvcc/TestMvcc2.java +++ /dev/null @@ -1,126 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.test.mvcc; - -import java.sql.Connection; -import java.sql.SQLException; -import java.sql.Statement; -import org.h2.constant.ErrorCode; -import org.h2.constant.SysProperties; -import org.h2.test.TestBase; - -/** - * Additional MVCC (multi version concurrency) test cases. - */ -public class TestMvcc2 extends TestBase { - - private static final String DROP_TABLE = "DROP TABLE IF EXISTS EMPLOYEE"; - private static final String CREATE_TABLE = "CREATE TABLE EMPLOYEE (id BIGINT, version BIGINT, NAME VARCHAR(255))"; - private static final String INSERT = "INSERT INTO EMPLOYEE (id, version, NAME) VALUES (1, 1, 'Jones')"; - private static final String UPDATE = "UPDATE EMPLOYEE SET NAME = 'Miller' WHERE version = 1"; - - /** - * Run just this test. - * - * @param a ignored - */ - public static void main(String... a) throws Exception { - System.setProperty("h2.selectForUpdateMvcc", "true"); - TestBase test = TestBase.createCaller().init(); - test.config.mvcc = true; - test.test(); - } - - public void test() throws SQLException { - if (!config.mvcc) { - return; - } - deleteDb("mvcc2"); - testSelectForUpdate(); - testInsertUpdateRollback(); - testInsertRollback(); - deleteDb("mvcc2"); - } - - private Connection getConnection() throws SQLException { - return getConnection("mvcc2"); - } - - private void testSelectForUpdate() throws SQLException { - if (!SysProperties.SELECT_FOR_UPDATE_MVCC) { - return; - } - Connection conn = getConnection(); - Connection conn2 = getConnection(); - Statement stat = conn.createStatement(); - stat.execute("create table test(id int primary key, name varchar)"); - conn.setAutoCommit(false); - stat.execute("insert into test select x, 'Hello' from system_range(1, 10)"); - stat.execute("select * from test where id = 3 for update"); - conn.commit(); - try { - stat.execute("select sum(id) from test for update"); - fail(); - } catch (SQLException e) { - assertEquals(ErrorCode.FEATURE_NOT_SUPPORTED_1, e.getErrorCode()); - } - try { - stat.execute("select distinct id from test for update"); - fail(); - } catch (SQLException e) { - assertEquals(ErrorCode.FEATURE_NOT_SUPPORTED_1, e.getErrorCode()); - } - try { - stat.execute("select id from test group by id for update"); - fail(); - } catch (SQLException e) { - assertEquals(ErrorCode.FEATURE_NOT_SUPPORTED_1, e.getErrorCode()); - } - try { - stat.execute("select t1.id from test t1, test t2 for update"); - fail(); - } catch (SQLException e) { - assertEquals(ErrorCode.FEATURE_NOT_SUPPORTED_1, e.getErrorCode()); - } - stat.execute("select * from test where id = 3 for update"); - conn2.setAutoCommit(false); - conn2.createStatement().execute("select * from test where id = 4 for update"); - try { - conn2.createStatement().execute("select * from test where id = 3 for update"); - fail(); - } catch (SQLException e) { - assertEquals(ErrorCode.CONCURRENT_UPDATE_1, e.getErrorCode()); - } - conn.close(); - } - - private void testInsertUpdateRollback() throws SQLException { - Connection conn = getConnection(); - conn.setAutoCommit(false); - Statement stmt = conn.createStatement(); - stmt.execute(DROP_TABLE); - stmt.execute(CREATE_TABLE); - conn.commit(); - stmt.execute(INSERT); - stmt.execute(UPDATE); - conn.rollback(); - conn.close(); - } - - private void testInsertRollback() throws SQLException { - Connection conn = getConnection(); - conn.setAutoCommit(false); - Statement stmt = conn.createStatement(); - stmt.execute(DROP_TABLE); - stmt.execute(CREATE_TABLE); - conn.commit(); - stmt.execute(INSERT); - conn.rollback(); - conn.close(); - } - -} diff --git a/tools/h2/src/test/org/h2/test/mvcc/TestMvcc3.java b/tools/h2/src/test/org/h2/test/mvcc/TestMvcc3.java deleted file mode 100755 index 81a8b66..0000000 --- a/tools/h2/src/test/org/h2/test/mvcc/TestMvcc3.java +++ /dev/null @@ -1,195 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.test.mvcc; - -import java.sql.Connection; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.sql.Savepoint; -import java.sql.Statement; -import org.h2.test.TestBase; - -/** - * Additional MVCC (multi version concurrency) test cases. - */ -public class TestMvcc3 extends TestBase { - - /** - * Run just this test. - * - * @param a ignored - */ - public static void main(String... a) throws Exception { - TestBase.createCaller().init().test(); - } - - public void test() throws SQLException { - testInsertUpdateRollback(); - testCreateTableAsSelect(); - testSequence(); - testDisableAutoCommit(); - testRollback(); - deleteDb("mvcc3"); - } - - private void testInsertUpdateRollback() throws SQLException { - if (!config.mvcc) { - return; - } - - deleteDb("mvcc3"); - Connection c1 = getConnection("mvcc3"); - Statement s1 = c1.createStatement(); - Connection c2 = getConnection("mvcc3"); - Statement s2 = c2.createStatement(); - - s1.execute("create table test(id int primary key, name varchar) as select 0, 'Hello'"); - c1.setAutoCommit(false); - s1.executeUpdate("update test set name = 'World'"); - printRows("after update", s1, s2); - Savepoint sp1 = c1.setSavepoint(); - s1.executeUpdate("delete from test"); - printRows("after delete", s1, s2); - c1.rollback(sp1); - printRows("after rollback delete", s1, s2); - c1.rollback(); - printRows("after rollback all", s1, s2); - - ResultSet rs = s2.executeQuery("select * from test"); - assertTrue(rs.next()); - assertFalse(rs.next()); - c1.close(); - c2.close(); - } - - private void printRows(String s, Statement s1, Statement s2) throws SQLException { - trace(s); - ResultSet rs; - rs = s1.executeQuery("select * from test"); - while (rs.next()) { - trace("s1: " + rs.getString(2)); - } - rs = s2.executeQuery("select * from test"); - while (rs.next()) { - trace("s2: " + rs.getString(2)); - } - } - - private void testCreateTableAsSelect() throws SQLException { - if (!config.mvcc) { - return; - } - deleteDb("mvcc3"); - Connection c1 = getConnection("mvcc3"); - Statement s1 = c1.createStatement(); - s1.execute("CREATE TABLE TEST AS SELECT X ID, 'Hello' NAME FROM SYSTEM_RANGE(1, 3)"); - Connection c2 = getConnection("mvcc3"); - Statement s2 = c2.createStatement(); - ResultSet rs = s2.executeQuery("SELECT NAME FROM TEST WHERE ID=1"); - rs.next(); - assertEquals("Hello", rs.getString(1)); - c1.close(); - c2.close(); - } - - private void testRollback() throws SQLException { - if (!config.mvcc) { - return; - } - - deleteDb("mvcc3"); - Connection conn = getConnection("mvcc3"); - Statement stat = conn.createStatement(); - stat.executeUpdate("DROP TABLE IF EXISTS TEST"); - stat.executeUpdate("CREATE TABLE TEST (ID NUMBER(2) PRIMARY KEY, VAL VARCHAR(10))"); - stat.executeUpdate("INSERT INTO TEST (ID, VAL) VALUES (1, 'Value')"); - stat.executeUpdate("INSERT INTO TEST (ID, VAL) VALUES (2, 'Value')"); - if (!config.memory) { - conn.close(); - conn = getConnection("mvcc3"); - } - conn.setAutoCommit(false); - conn.setTransactionIsolation(Connection.TRANSACTION_READ_COMMITTED); - - Connection conn2 = getConnection("mvcc3"); - conn2.setAutoCommit(false); - conn2.setTransactionIsolation(Connection.TRANSACTION_READ_COMMITTED); - - conn.createStatement().executeUpdate("UPDATE TEST SET VAL='Updated' WHERE ID = 1"); - conn.rollback(); - - ResultSet rs = conn2.createStatement().executeQuery("SELECT * FROM TEST"); - assertTrue(rs.next()); - assertEquals("Value", rs.getString(2)); - assertTrue(rs.next()); - assertEquals("Value", rs.getString(2)); - assertFalse(rs.next()); - - conn.createStatement().executeUpdate("UPDATE TEST SET VAL='Updated' WHERE ID = 1"); - conn.commit(); - rs = conn2.createStatement().executeQuery("SELECT * FROM TEST ORDER BY ID"); - assertTrue(rs.next()); - assertEquals(1, rs.getInt(1)); - assertEquals("Updated", rs.getString(2)); - assertTrue(rs.next()); - assertEquals(2, rs.getInt(1)); - assertEquals("Value", rs.getString(2)); - assertFalse(rs.next()); - - conn.close(); - conn2.close(); - } - - private void testDisableAutoCommit() throws SQLException { - if (!config.mvcc) { - return; - } - deleteDb("mvcc3"); - Connection conn = getConnection("mvcc3"); - Statement stat = conn.createStatement(); - stat.execute("CREATE TABLE TEST(ID INT PRIMARY KEY)"); - stat.execute("INSERT INTO TEST VALUES(0)"); - conn.setAutoCommit(false); - stat.execute("INSERT INTO TEST VALUES(1)"); - ResultSet rs = stat.executeQuery("SELECT * FROM TEST ORDER BY ID"); - rs.next(); - assertEquals(0, rs.getInt(1)); - rs.next(); - assertEquals(1, rs.getInt(1)); - conn.close(); - } - - private void testSequence() throws SQLException { - if (config.memory) { - return; - } - - deleteDb("mvcc3"); - Connection conn; - ResultSet rs; - - conn = getConnection("mvcc3"); - conn.createStatement().execute("create sequence abc"); - conn.close(); - - conn = getConnection("mvcc3"); - rs = conn.createStatement().executeQuery("call abc.nextval"); - rs.next(); - assertEquals(1, rs.getInt(1)); - conn.close(); - - conn = getConnection("mvcc3"); - rs = conn.createStatement().executeQuery("call abc.currval"); - rs.next(); - assertEquals(1, rs.getInt(1)); - conn.close(); - } -} - - - - diff --git a/tools/h2/src/test/org/h2/test/mvcc/TestMvccMultiThreaded.java b/tools/h2/src/test/org/h2/test/mvcc/TestMvccMultiThreaded.java deleted file mode 100755 index fdc7d9a..0000000 --- a/tools/h2/src/test/org/h2/test/mvcc/TestMvccMultiThreaded.java +++ /dev/null @@ -1,130 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.test.mvcc; - -import java.sql.Connection; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.util.concurrent.CountDownLatch; - -import org.h2.test.TestBase; - -/** - * Multi-threaded MVCC (multi version concurrency) test cases. - */ -public class TestMvccMultiThreaded extends TestBase { - - /** - * Run just this test. - * - * @param a ignored - */ - public static void main(String... a) throws Exception { - TestBase.createCaller().init().test(); - } - - public void test() throws Exception { - testConcurrentMerge(); - testConcurrentUpdate(""); - // not supported currently - // testConcurrentUpdate(";MULTI_THREADED=TRUE"); - } - - private void testConcurrentMerge() throws Exception { - deleteDb("mvccMultiThreaded"); - int len = 3; - final Connection[] connList = new Connection[len]; - for (int i = 0; i < len; i++) { - Connection conn = getConnection("mvccMultiThreaded;MVCC=TRUE;LOCK_TIMEOUT=1000"); - connList[i] = conn; - } - Connection conn = connList[0]; - conn.createStatement().execute("create table test(id int primary key, name varchar)"); - final SQLException[] ex = { null }; - Thread[] threads = new Thread[len]; - final boolean[] stop = { false }; - for (int i = 0; i < len; i++) { - final Connection c = connList[i]; - c.setAutoCommit(false); - threads[i] = new Thread() { - public void run() { - while (!stop[0]) { - try { - c.createStatement().execute("merge into test values(1, 'x')"); - c.commit(); - } catch (SQLException e) { - ex[0] = e; - } - } - } - }; - threads[i].start(); - } - Thread.sleep(1000); - stop[0] = true; - for (int i = 0; i < len; i++) { - threads[i].join(); - } - if (ex[0] != null) { - throw ex[0]; - } - for (int i = 0; i < len; i++) { - connList[i].close(); - } - deleteDb("mvccMultiThreaded"); - } - - private void testConcurrentUpdate(String suffix) throws Exception { - deleteDb("mvccMultiThreaded"); - int len = 2; - final Connection[] connList = new Connection[len]; - for (int i = 0; i < len; i++) { - connList[i] = getConnection("mvccMultiThreaded;MVCC=TRUE" + suffix); - } - Connection conn = connList[0]; - conn.createStatement().execute("create table test(id int primary key, value int)"); - conn.createStatement().execute("insert into test values(0, 0)"); - final Exception[] ex = { null }; - final int count = 1000; - Thread[] threads = new Thread[len]; - - final CountDownLatch latch = new CountDownLatch(len); - - for (int i = 0; i < len; i++) { - final int x = i; - threads[i] = new Thread() { - public void run() { - for (int a = 0; a < count; a++) { - try { - connList[x].createStatement().execute("update test set value=value+1"); - latch.countDown(); - latch.await(); - } catch (Exception e) { - ex[0] = e; - break; - } - } - } - }; - threads[i].start(); - } - for (int i = 0; i < len; i++) { - threads[i].join(); - } - if (ex[0] != null) { - throw ex[0]; - } - ResultSet rs = conn.createStatement().executeQuery("select value from test"); - rs.next(); - assertEquals(count * len, rs.getInt(1)); - for (int i = 0; i < len; i++) { - connList[i].close(); - } - deleteDb("mvccMultiThreaded"); - } - -} diff --git a/tools/h2/src/test/org/h2/test/mvcc/package.html b/tools/h2/src/test/org/h2/test/mvcc/package.html deleted file mode 100755 index dd748b6..0000000 --- a/tools/h2/src/test/org/h2/test/mvcc/package.html +++ /dev/null @@ -1,15 +0,0 @@ - - - - -Javadoc package documentation -

    - -Multi version concurrency tests. - -

    \ No newline at end of file diff --git a/tools/h2/src/test/org/h2/test/otherDatabases.txt b/tools/h2/src/test/org/h2/test/otherDatabases.txt deleted file mode 100755 index 51668ae..0000000 --- a/tools/h2/src/test/org/h2/test/otherDatabases.txt +++ /dev/null @@ -1,62 +0,0 @@ -MySQL --------------------------------------------------------------------------------------------------------- -Start: -sudo mysqld_safe - -Stop: -sudo mysqladmin shutdown - -Configuration: -sudo mysql -create database test; -create user 'sa'@'localhost' identified by 'sa'; -use test; -grant all on * to 'sa'@'localhost' with grant option; - -'TRADITIONAL' is default; ANSI mode can be set using: -SET GLOBAL sql_mode='ANSI'; -SELECT @@global.sql_mode; - -Non-standard escape mechanism: -select 'Joe''s', 'Joe\'s'; - -Compare with NULL problem: -drop table test; -create table test(id int); -insert into test values(1); -insert into test values(null); --- 2 rows even in ANSI mode (correct is 1 row): -select * from test where id=id and 1=1; - - -MS SQL Server 2005 --------------------------------------------------------------------------------------------------------- -Problems when trying to select large objects (even if ResultSet.getBinaryStream is used). -The workaround responseBuffering=adaptive doesn't always seem to work -(jdbc:sqlserver://localhost:4220;DatabaseName=test;responseBuffering=adaptive) - - -PostgreSQL --------------------------------------------------------------------------------------------------------- - -Non-standard escape mechanism: -select 'Joe''s', 'Joe\'s'; - -HSQLDB --------------------------------------------------------------------------------------------------------- -To use the same default settings as H2, use: -jdbc:hsqldb:data/test;hsqldb.default_table_type=cached;sql.enforce_size=true -Also, you need to execute the following statement: -SET WRITE_DELAY 1 -No optimization for COUNT(*) - - -Derby --------------------------------------------------------------------------------------------------------- -To call getFD().sync() (which results in the OS call fsync()), -set the system property derby.storage.fileSyncTransactionLog to true true. -See -http://db.apache.org/derby/javadoc/engine/org/apache/derby/iapi/reference/Property.html#FILESYNC_TRANSACTION_LOG -Missing features: -LIMIT OFFSET is not supported. -No optimization for COUNT(*) diff --git a/tools/h2/src/test/org/h2/test/package.html b/tools/h2/src/test/org/h2/test/package.html deleted file mode 100755 index ea6fd5f..0000000 --- a/tools/h2/src/test/org/h2/test/package.html +++ /dev/null @@ -1,15 +0,0 @@ - - - - -Javadoc package documentation -

    - -High level test classes. - -

    \ No newline at end of file diff --git a/tools/h2/src/test/org/h2/test/poweroff/Listener.java b/tools/h2/src/test/org/h2/test/poweroff/Listener.java deleted file mode 100755 index 01ad66a..0000000 --- a/tools/h2/src/test/org/h2/test/poweroff/Listener.java +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.test.poweroff; - -import java.io.DataInputStream; -import java.io.IOException; -import java.net.ServerSocket; -import java.net.Socket; - -/** - * The listener application for the power off test. - * The listener runs on a computer that stays on during the whole test. - */ -public class Listener implements Runnable { - - private volatile int maxValue; - - /** - * This method is called when executing this application from the command - * line. - * - * @param args the command line parameters - */ - public static void main(String... args) throws IOException { - new Listener().test(args); - } - - private void test(String... args) throws IOException { - int port = 9099; - for (int i = 0; i < args.length; i++) { - if (args[i].equals("-port")) { - port = Integer.parseInt(args[++i]); - } - } - listen(port); - } - - public void run() { - while (true) { - try { - Thread.sleep(10000); - } catch (Exception e) { - // ignore - } - System.out.println("Max=" + maxValue); - } - } - - private void listen(int port) throws IOException { - new Thread(this).start(); - ServerSocket serverSocket = new ServerSocket(port); - System.out.println("Listening on " + serverSocket.toString()); - long time; - maxValue = 0; - while (true) { - Socket socket = serverSocket.accept(); - DataInputStream in = new DataInputStream(socket.getInputStream()); - System.out.println("Connected"); - time = System.currentTimeMillis(); - try { - while (true) { - int value = in.readInt(); - if (value < 0) { - break; - } - maxValue = Math.max(maxValue, value); - } - } catch (IOException e) { - System.out.println("Closed with Exception: " + e); - } - time = System.currentTimeMillis() - time; - int operationsPerSecond = (int) (1000 * maxValue / time); - System.out.println("Max=" + maxValue + " operations/sec=" + operationsPerSecond); - } - } - -} diff --git a/tools/h2/src/test/org/h2/test/poweroff/Test.java b/tools/h2/src/test/org/h2/test/poweroff/Test.java deleted file mode 100755 index 2e481d7..0000000 --- a/tools/h2/src/test/org/h2/test/poweroff/Test.java +++ /dev/null @@ -1,165 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.test.poweroff; - -import java.io.DataOutputStream; -import java.io.File; -import java.io.FileDescriptor; -import java.io.IOException; -import java.io.RandomAccessFile; -import java.net.Socket; -import java.sql.Connection; -import java.sql.DriverManager; -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.sql.Statement; - -import org.h2.util.IOUtils; - -/** - * This application tests the durability / non-durability of file systems and - * databases. Two computers with network connection are required to run this - * test. Before starting this application, the Listener application must be - * started on another computer. - */ -public class Test { - - private String url; - private Connection conn; - private Statement stat; - private PreparedStatement prep; - - private Test() { - // nothing to do - } - - private Test(String driver, String url, String user, String password, boolean writeDelay0) { - this.url = url; - try { - Class.forName(driver); - conn = DriverManager.getConnection(url, user, password); - stat = conn.createStatement(); - if (writeDelay0) { - stat.execute("SET WRITE_DELAY 0"); - } - System.out.println(url + " started"); - } catch (Exception e) { - System.out.println(url + ": " + e.toString()); - return; - } - try { - ResultSet rs = stat.executeQuery("SELECT MAX(ID) FROM TEST"); - rs.next(); - System.out.println(url + ": MAX(ID)=" + rs.getInt(1)); - stat.execute("DROP TABLE TEST"); - } catch (SQLException e) { - // ignore - } - try { - stat.execute("CREATE TABLE TEST(ID INT PRIMARY KEY, NAME VARCHAR(255))"); - prep = conn.prepareStatement("INSERT INTO TEST VALUES(?, ?)"); - } catch (SQLException e) { - System.out.println(url + ": " + e.toString()); - } - } - - private void insert(int id) { - try { - if (prep != null) { - prep.setInt(1, id); - prep.setString(2, "World " + id); - prep.execute(); - } - } catch (SQLException e) { - System.out.println(url + ": " + e.toString()); - } - } - - /** - * This method is called when executing this application from the command - * line. - * - * @param args the command line parameters - */ - public static void main(String... args) throws Exception { - new Test().test(args); - } - - private void test(String... args) throws Exception { - int port = 9099; - String connect = "192.168.0.3"; - boolean file = false; - for (int i = 0; i < args.length; i++) { - if (args[i].equals("-port")) { - port = Integer.parseInt(args[++i]); - } else if (args[i].equals("-connect")) { - connect = args[++i]; - } else if (args[i].equals("-file")) { - file = true; - } - } - test(connect, port, file); - } - - private void test(String connect, int port, boolean file) throws Exception { - Socket socket = new Socket(connect, port); - DataOutputStream out = new DataOutputStream(socket.getOutputStream()); - System.out.println("Connected to " + socket.toString()); - if (file) { - testFile(out); - } else { - testDatabases(out); - } - } - - private void testFile(DataOutputStream out) throws IOException { - File file = new File("test.txt"); - if (file.exists()) { - file.delete(); - } - RandomAccessFile write = new RandomAccessFile(file, "rws"); - // RandomAccessFile write = new RandomAccessFile(file, "rwd"); - int fileSize = 10 * 1024 * 1024; - IOUtils.setLength(write, fileSize); - write.seek(0); - int i = 0; - FileDescriptor fd = write.getFD(); - while (true) { - if (write.getFilePointer() >= fileSize) { - break; - } - write.writeBytes(i + "\r\n"); - fd.sync(); - out.writeInt(i); - out.flush(); - i++; - } - write.close(); - } - - private void testDatabases(DataOutputStream out) throws Exception { - Test[] dbs = { - new Test("org.h2.Driver", "jdbc:h2:test1", "sa", "", true), - new Test("org.h2.Driver", "jdbc:h2:test2", "sa", "", false), - new Test("org.hsqldb.jdbcDriver", "jdbc:hsqldb:test4", "sa", "", false), - // new Test("com.mysql.jdbc.Driver", - // "jdbc:mysql://localhost/test", "sa", ""), - new Test("org.postgresql.Driver", "jdbc:postgresql:test", "sa", "sa", false), - new Test("org.apache.derby.jdbc.EmbeddedDriver", "jdbc:derby:test;create=true", "sa", "", false), - new Test("org.h2.Driver", "jdbc:h2:test5", "sa", "", true), - new Test("org.h2.Driver", "jdbc:h2:test6", "sa", "", false), }; - for (int i = 0;; i++) { - for (Test t : dbs) { - t.insert(i); - } - out.writeInt(i); - out.flush(); - } - } - -} diff --git a/tools/h2/src/test/org/h2/test/poweroff/TestRecover.java b/tools/h2/src/test/org/h2/test/poweroff/TestRecover.java deleted file mode 100755 index 64ccab6..0000000 --- a/tools/h2/src/test/org/h2/test/poweroff/TestRecover.java +++ /dev/null @@ -1,376 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.test.poweroff; - -import java.io.File; -import java.io.FileInputStream; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.io.PrintWriter; -import java.util.Date; -import java.security.SecureRandom; -import java.sql.Connection; -import java.sql.Driver; -import java.sql.DriverManager; -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.sql.Statement; -import java.text.SimpleDateFormat; -import java.util.ArrayList; -import java.util.List; -import java.util.Random; -import java.util.zip.ZipEntry; -import java.util.zip.ZipOutputStream; - -import org.h2.util.IOUtils; -import org.h2.util.New; - -/** - * This standalone test checks if recovery of a database works after power - * failure. - */ -public class TestRecover { - - private static final int MAX_STRING_LENGTH = 10000; - private static final String NODE = System.getProperty("test.node", ""); - private static final String DIR = System.getProperty("test.dir", "/temp/db"); - - private static final String TEST_DIRECTORY = DIR + "/data" + NODE; - private static final String BACKUP_DIRECTORY = DIR + "/last"; - private static final String URL = System.getProperty("test.url", "jdbc:h2:" + TEST_DIRECTORY + "/test"); - private static final String DRIVER = System.getProperty("test.driver", "org.h2.Driver"); - - // private static final String DIR = - // System.getProperty("test.dir", "/temp/derby"); - // private static final String URL = - // System.getProperty("test.url", - // "jdbc:derby:/temp/derby/data/test;create=true"); - // private static final String DRIVER = - // System.getProperty("test.driver", - // "org.apache.derby.jdbc.EmbeddedDriver"); - - /** - * This method is called when executing this application from the command - * line. - * - * @param args the command line parameters - */ - public static void main(String... args) throws Exception { - new TestRecover().runTest(); - } - - private void runTest() throws Exception { - System.out.println("URL=" + URL); - System.out.println("backup..."); - new File(TEST_DIRECTORY).mkdirs(); - File backup = backup(TEST_DIRECTORY, BACKUP_DIRECTORY, "data", 10, NODE); - System.out.println("check consistency..."); - if (!testConsistency()) { - System.out.println("error! renaming file"); - backup.renameTo(new File(backup.getParentFile(), "error-" + backup.getName())); - } - System.out.println("deleting old run..."); - deleteRecursive(new File(TEST_DIRECTORY)); - System.out.println("testing..."); - testLoop(); - } - - private static File backup(String sourcePath, String targetPath, String basePath, int max, String node) throws IOException { - File root = new File(targetPath); - if (!root.exists()) { - root.mkdirs(); - } - while (true) { - File oldest = null; - int count = 0; - for (File f : root.listFiles()) { - String name = f.getName(); - if (f.isFile() && name.startsWith("backup") && name.endsWith(".zip")) { - count++; - if (oldest == null || f.lastModified() < oldest.lastModified()) { - oldest = f; - } - } - } - if (count < max) { - break; - } - oldest.delete(); - } - SimpleDateFormat sd = new SimpleDateFormat("yyMMdd-HHmmss"); - String date = sd.format(new Date()); - File zipFile = new File(root, "backup-" + date + "-" + node + ".zip"); - ArrayList list = New.arrayList(); - File base = new File(sourcePath); - listRecursive(list, base); - if (list.size() == 0) { - FileOutputStream out = new FileOutputStream(zipFile); - out.close(); - } else { - OutputStream out = null; - try { - out = new FileOutputStream(zipFile); - ZipOutputStream zipOut = new ZipOutputStream(out); - String baseName = base.getAbsolutePath(); - for (File f : list) { - String fileName = f.getAbsolutePath(); - String entryName = fileName; - if (fileName.startsWith(baseName)) { - entryName = entryName.substring(baseName.length()); - } - if (entryName.startsWith("\\")) { - entryName = entryName.substring(1); - } - if (!entryName.startsWith("/")) { - entryName = "/" + entryName; - } - ZipEntry entry = new ZipEntry(basePath + entryName); - zipOut.putNextEntry(entry); - InputStream in = null; - try { - in = new FileInputStream(fileName); - IOUtils.copyAndCloseInput(in, zipOut); - } finally { - IOUtils.closeSilently(in); - } - zipOut.closeEntry(); - } - zipOut.closeEntry(); - zipOut.close(); - } finally { - IOUtils.closeSilently(out); - } - } - return zipFile; - } - - private static void listRecursive(List list, File file) throws IOException { - File[] l = file.listFiles(); - for (int i = 0; l != null && i < l.length; i++) { - File f = l[i]; - if (f.isDirectory()) { - listRecursive(list, f); - } else { - list.add(f); - } - } - } - - private static void deleteRecursive(File file) throws IOException { - if (file.isDirectory()) { - for (File f : file.listFiles()) { - deleteRecursive(f); - } - } - if (file.exists() && !file.delete()) { - throw new IOException("Could not delete " + file.getAbsolutePath()); - } - } - - private void testLoop() throws Exception { - Random random = new SecureRandom(); - while (true) { - runOneTest(random.nextInt()); - } - } - - private Connection openConnection() throws Exception { - Class.forName(DRIVER); - Connection conn = DriverManager.getConnection(URL, "sa", "sa"); - Statement stat = conn.createStatement(); - try { - stat.execute("CREATE TABLE TEST(ID INT PRIMARY KEY, D INT, NAME VARCHAR("+MAX_STRING_LENGTH+"))"); - stat.execute("CREATE INDEX IDX_TEST_D ON TEST(D)"); - } catch (SQLException e) { - // ignore - } - return conn; - } - - private void closeConnection(Connection conn) { - try { - conn.close(); - } catch (SQLException e) { - // ignore - } - if (DRIVER.startsWith("org.apache.derby")) { - try { - DriverManager.getConnection("jdbc:derby:;shutdown=true"); - } catch (SQLException e) { - // ignore - } - try { - Driver driver = (Driver) Class.forName(DRIVER).newInstance(); - DriverManager.registerDriver(driver); - } catch (Exception e) { - e.printStackTrace(); - } - } - } - - private void runOneTest(int i) throws Exception { - Random random = new Random(i); - Connection conn = openConnection(); - PreparedStatement prepInsert = null; - PreparedStatement prepDelete = null; - conn.setAutoCommit(false); - for (int id = 0;; id++) { - boolean rollback = random.nextInt(10) == 1; - int len; - if (random.nextInt(10) == 1) { - len = random.nextInt(100) * 2; - } else { - len = random.nextInt(2) * 2; - } - if (rollback && random.nextBoolean()) { - // make the length odd - len++; - } - // byte[] data = new byte[len]; - // random.nextBytes(data); - int op = random.nextInt(); - if (op % 1000000 == 0) { - closeConnection(conn); - conn = openConnection(); - conn.setAutoCommit(false); - prepInsert = null; - prepDelete = null; - } -// if (random.nextBoolean()) { -// int test; -// if (random.nextBoolean()) { -// conn.createStatement().execute( -// "drop index if exists idx_2"); -// conn.createStatement().execute( -// "create table if not exists test2" + -// "(id int primary key) as select x " + -// "from system_range(1, 1000)"); -// } else { -// conn.createStatement().execute( -// "create index if not exists idx_2 " + -// "on test(d, name, id)"); -// conn.createStatement().execute( -// "drop table if exists test2"); -// } -// } - if (random.nextBoolean()) { - if (prepInsert == null) { - prepInsert = conn.prepareStatement("INSERT INTO TEST(ID, D, NAME) VALUES(?, ?, ?)"); - } - prepInsert.setInt(1, id); - prepInsert.setInt(2, random.nextInt(10000)); - StringBuilder buff = new StringBuilder(); - buff.append(len); - switch (random.nextInt(10)) { - case 0: - len = random.nextInt(MAX_STRING_LENGTH); - break; - case 1: - case 2: - case 3: - len = random.nextInt(MAX_STRING_LENGTH / 20); - break; - default: - len = 0; - } - len -= 10; - while (len > 0) { - buff.append('-'); - len--; - } - buff.append("->"); - String s = buff.toString(); - prepInsert.setString(3, s); - prepInsert.execute(); - } else { - ResultSet rs = conn.createStatement().executeQuery("SELECT COUNT(*) FROM TEST"); - rs.next(); - int count = rs.getInt(1); - rs.close(); - if (count > 1000) { - if (prepDelete == null) { - prepDelete = conn.prepareStatement("DELETE FROM TEST WHERE ROWNUM <= 4"); - } - prepDelete.execute(); - } - } - if (rollback) { - conn.rollback(); - } else { - conn.commit(); - } - } - } - - private boolean testConsistency() { - FileOutputStream out = null; - PrintWriter p = null; - try { - out = new FileOutputStream(TEST_DIRECTORY + "/result.txt"); - p = new PrintWriter(out); - p.println("Results"); - p.flush(); - } catch (Throwable t) { - t.printStackTrace(); - System.exit(0); - } - Connection conn = null; - try { - conn = openConnection(); - test(conn, ""); - test(conn, "ORDER BY D"); - closeConnection(conn); - return true; - } catch (Throwable t) { - t.printStackTrace(); - t.printStackTrace(p); - return false; - } finally { - if (conn != null) { - try { - closeConnection(conn); - } catch (Throwable t2) { - t2.printStackTrace(); - t2.printStackTrace(p); - } - } - p.flush(); - p.close(); - IOUtils.closeSilently(out); - } - } - - private void test(Connection conn, String order) throws Exception { - ResultSet rs; - rs = conn.createStatement().executeQuery("SELECT * FROM TEST " + order); - int max = 0; - int count = 0; - while (rs.next()) { - count++; - int id = rs.getInt("ID"); - String name = rs.getString("NAME"); - if (!name.endsWith(">")) { - throw new Exception("unexpected entry " + id + " value " + name); - } - int idx = name.indexOf('-'); - if (idx < 0) { - throw new Exception("unexpected entry " + id + " value " + name); - } - int value = Integer.parseInt(name.substring(0, idx)); - if (value % 2 != 0) { - throw new Exception("unexpected odd entry " + id + " value " + value); - } - max = Math.max(max, id); - } - rs.close(); - System.out.println("max row id: " + max + " rows: " + count); - } - -} diff --git a/tools/h2/src/test/org/h2/test/poweroff/TestRecoverKillLoop.java b/tools/h2/src/test/org/h2/test/poweroff/TestRecoverKillLoop.java deleted file mode 100755 index 4c24943..0000000 --- a/tools/h2/src/test/org/h2/test/poweroff/TestRecoverKillLoop.java +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.test.poweroff; - -import java.io.InputStream; -import java.util.Random; -import org.h2.store.fs.FileSystemDisk; -import org.h2.test.TestBase; -import org.h2.test.synth.OutputCatcher; - -/** - * Run the TestRecover test case in a loop. The process is killed after 10 - * seconds. - */ -public class TestRecoverKillLoop extends TestBase { - - /** - * This method is called when executing this application from the command - * line. - * - * @param args the command line parameters - */ - public static void main(String... args) throws Exception { - new TestRecoverKillLoop().runTest(Integer.MAX_VALUE); - } - - public void test() throws Exception { - runTest(3); - } - - private void runTest(int count) throws Exception { - FileSystemDisk.getInstance().deleteRecursive("data/db", false); - Random random = new Random(1); - for (int i = 0; i < count; i++) { - String[] procDef = { - "java", "-cp", getClassPath(), - "-Dtest.dir=data/db", - TestRecover.class.getName() - }; - Process p = Runtime.getRuntime().exec(procDef); - InputStream in = p.getInputStream(); - OutputCatcher catcher = new OutputCatcher(in); - catcher.start(); - while (true) { - String s = catcher.readLine(60 * 1000); - // System.out.println("> " + s); - if (s == null) { - fail("No reply from process"); - } else if (s.startsWith("testing...")) { - int sleep = random.nextInt(10000); - Thread.sleep(sleep); - printTime("killing"); - p.destroy(); - p.waitFor(); - break; - } else if (s.startsWith("error!")) { - fail("Failed: " + s); - } - } - } - } - -} diff --git a/tools/h2/src/test/org/h2/test/poweroff/TestWrite.java b/tools/h2/src/test/org/h2/test/poweroff/TestWrite.java deleted file mode 100755 index 6fbd15c..0000000 --- a/tools/h2/src/test/org/h2/test/poweroff/TestWrite.java +++ /dev/null @@ -1,127 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.test.poweroff; - -import java.io.File; -import java.io.FileDescriptor; -import java.io.RandomAccessFile; -import java.sql.Connection; -import java.sql.DriverManager; -import java.sql.PreparedStatement; -import java.sql.SQLException; -import java.sql.Statement; - -/** - * This test shows the raw file access performance using various file modes. - * It also tests databases. - */ -public class TestWrite { - - private TestWrite() { - // utility class - } - - /** - * This method is called when executing this application from the command - * line. - * - * @param args the command line parameters - */ - public static void main(String... args) throws Exception { - testFile("rw", false); - testFile("rwd", false); - testFile("rws", false); - testFile("rw", true); - testFile("rwd", true); - testFile("rws", true); - testDatabase("org.h2.Driver", "jdbc:h2:test", "sa", ""); - testDatabase("org.hsqldb.jdbcDriver", "jdbc:hsqldb:test4", "sa", ""); - testDatabase("org.apache.derby.jdbc.EmbeddedDriver", "jdbc:derby:test;create=true", "sa", ""); - testDatabase("com.mysql.jdbc.Driver", "jdbc:mysql://localhost/test", "sa", "sa"); - testDatabase("org.postgresql.Driver", "jdbc:postgresql:test", "sa", "sa"); - } - - private static void testFile(String mode, boolean flush) throws Exception { - System.out.println("Testing RandomAccessFile(.., \"" + mode + "\")..."); - if (flush) { - System.out.println(" with FileDescriptor.sync()"); - } - RandomAccessFile file = new RandomAccessFile("test.txt", mode); - file.setLength(0); - FileDescriptor fd = file.getFD(); - long start = System.currentTimeMillis(); - byte[] data = { 0 }; - file.write(data); - int i = 0; - if (flush) { - for (;; i++) { - file.seek(0); - file.write(data); - fd.sync(); - if ((i & 15) == 0) { - long time = System.currentTimeMillis() - start; - if (time > 5000) { - break; - } - } - } - } else { - for (;; i++) { - file.seek(0); - file.write(data); - if ((i & 1023) == 0) { - long time = System.currentTimeMillis() - start; - if (time > 5000) { - break; - } - } - } - } - long time = System.currentTimeMillis() - start; - System.out.println("Time: " + time); - System.out.println("Operations: " + i); - System.out.println("Operations/second: " + (i * 1000 / time)); - System.out.println(); - file.close(); - new File("test.txt").delete(); - } - - private static void testDatabase(String driver, String url, String user, String password) throws Exception { - Class.forName(driver); - Connection conn = DriverManager.getConnection(url, user, password); - System.out.println("Testing Database, URL=" + url); - Statement stat = conn.createStatement(); - try { - stat.execute("DROP TABLE TEST"); - } catch (SQLException e) { - // ignore - } - stat.execute("CREATE TABLE TEST(ID INT)"); - PreparedStatement prep = conn.prepareStatement("INSERT INTO TEST VALUES(?)"); - long start = System.currentTimeMillis(); - int i = 0; - for (;; i++) { - prep.setInt(1, i); - // autocommit is on by default, so this commits as well - prep.execute(); - if ((i & 15) == 0) { - long time = System.currentTimeMillis() - start; - if (time > 5000) { - break; - } - } - } - long time = System.currentTimeMillis() - start; - System.out.println("Time: " + time); - System.out.println("Operations: " + i); - System.out.println("Operations/second: " + (i * 1000 / time)); - System.out.println(); - stat.execute("DROP TABLE TEST"); - conn.close(); - } - -} diff --git a/tools/h2/src/test/org/h2/test/poweroff/package.html b/tools/h2/src/test/org/h2/test/poweroff/package.html deleted file mode 100755 index dd748b6..0000000 --- a/tools/h2/src/test/org/h2/test/poweroff/package.html +++ /dev/null @@ -1,15 +0,0 @@ - - - - -Javadoc package documentation -

    - -Multi version concurrency tests. - -

    \ No newline at end of file diff --git a/tools/h2/src/test/org/h2/test/rowlock/TestRowLocks.java b/tools/h2/src/test/org/h2/test/rowlock/TestRowLocks.java deleted file mode 100755 index 9398451..0000000 --- a/tools/h2/src/test/org/h2/test/rowlock/TestRowLocks.java +++ /dev/null @@ -1,111 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.test.rowlock; - -import java.sql.Connection; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.sql.Statement; - -import org.h2.test.TestBase; - -/** - * Row level locking tests. - */ -public class TestRowLocks extends TestBase { - - /** - * The statements used in this test. - */ - Statement s1, s2; - - private Connection c1, c2; - - /** - * Run just this test. - * - * @param a ignored - */ - public static void main(String... a) throws Exception { - TestBase.createCaller().init().test(); - } - - public void test() throws Exception { - testSetMode(); - testCases(); - deleteDb("rowLocks"); - } - - private void testSetMode() throws SQLException { - deleteDb("rowLocks"); - c1 = getConnection("rowLocks"); - Statement stat = c1.createStatement(); - stat.execute("SET LOCK_MODE 2"); - ResultSet rs = stat.executeQuery("call lock_mode()"); - rs.next(); - assertEquals("2", rs.getString(1)); - c1.close(); - } - - private void testCases() throws Exception { - deleteDb("rowLocks"); - c1 = getConnection("rowLocks;MVCC=TRUE"); - s1 = c1.createStatement(); - s1.execute("SET LOCK_TIMEOUT 10000"); - s1.execute("CREATE TABLE TEST AS SELECT X ID, 'Hello' NAME FROM SYSTEM_RANGE(1, 3)"); - c1.commit(); - c1.setAutoCommit(false); - s1.execute("UPDATE TEST SET NAME='Hallo' WHERE ID=1"); - - c2 = getConnection("rowLocks"); - c2.setAutoCommit(false); - s2 = c2.createStatement(); - - assertEquals("Hallo", getSingleValue(s1, "SELECT NAME FROM TEST WHERE ID=1")); - assertEquals("Hello", getSingleValue(s2, "SELECT NAME FROM TEST WHERE ID=1")); - - s2.execute("UPDATE TEST SET NAME='Hallo' WHERE ID=2"); - try { - s2.executeUpdate("UPDATE TEST SET NAME='Hi' WHERE ID=1"); - fail(); - } catch (SQLException e) { - assertKnownException(e); - } - c1.commit(); - c2.commit(); - - assertEquals("Hallo", getSingleValue(s1, "SELECT NAME FROM TEST WHERE ID=1")); - assertEquals("Hallo", getSingleValue(s2, "SELECT NAME FROM TEST WHERE ID=1")); - - s2.execute("UPDATE TEST SET NAME='H1' WHERE ID=1"); - Thread thread = new Thread() { - public void run() { - try { - s1.execute("UPDATE TEST SET NAME='H2' WHERE ID=1"); - } catch (SQLException e) { - e.printStackTrace(); - } - } - }; - thread.start(); - Thread.sleep(100); - c2.commit(); - thread.join(); - c1.commit(); - assertEquals("H2", getSingleValue(s1, "SELECT NAME FROM TEST WHERE ID=1")); - assertEquals("H2", getSingleValue(s2, "SELECT NAME FROM TEST WHERE ID=1")); - - c1.close(); - c2.close(); - } - - private String getSingleValue(Statement stat, String sql) throws SQLException { - ResultSet rs = stat.executeQuery(sql); - return rs.next() ? rs.getString(1) : null; - } - -} diff --git a/tools/h2/src/test/org/h2/test/rowlock/package.html b/tools/h2/src/test/org/h2/test/rowlock/package.html deleted file mode 100755 index 0b3275c..0000000 --- a/tools/h2/src/test/org/h2/test/rowlock/package.html +++ /dev/null @@ -1,15 +0,0 @@ - - - - -Javadoc package documentation -

    - -Row level locking tests. - -

    \ No newline at end of file diff --git a/tools/h2/src/test/org/h2/test/server/TestAutoServer.java b/tools/h2/src/test/org/h2/test/server/TestAutoServer.java deleted file mode 100755 index 4d23233..0000000 --- a/tools/h2/src/test/org/h2/test/server/TestAutoServer.java +++ /dev/null @@ -1,151 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.test.server; - -import java.sql.Connection; -import java.sql.DriverManager; -import java.sql.SQLException; -import java.sql.Statement; - -import org.h2.test.TestBase; -import org.h2.util.SortedProperties; - -/** - * Tests automatic embedded/server mode. - */ -public class TestAutoServer extends TestBase { - - /** - * The number of iterations. - */ - static final int ITERATIONS = 30; - - /** - * Run just this test. - * - * @param a ignored - */ - public static void main(String... a) throws Exception { - TestBase.createCaller().init().test(); - } - - public void test() throws Exception { - testAutoServer(); - testLinkedLocalTablesWithAutoServerReconnect(); - } - - /** - * Tests basic AUTO_SERVER functionality - * - * @throws Exception - */ - private void testAutoServer() throws Exception { - if (config.memory || config.networked) { - return; - } - deleteDb("autoServer"); - String url = getURL("autoServer;AUTO_SERVER=TRUE", true); - String user = getUser(), password = getPassword(); - Connection connServer = getConnection(url + ";OPEN_NEW=TRUE", user, password); - - int i = ITERATIONS; - for (; i > 0; i--) { - Thread.sleep(100); - SortedProperties prop = SortedProperties.loadProperties(getBaseDir() + "/autoServer.lock.db"); - String key = prop.getProperty("id"); - String server = prop.getProperty("server"); - if (server != null) { - String u2 = url.substring(url.indexOf(";")); - u2 = "jdbc:h2:tcp://" + server + "/" + key + u2; - Connection conn = DriverManager.getConnection(u2, user, password); - conn.close(); - break; - } - } - if (i <= 0) { - fail(); - } - Connection conn = getConnection(url + ";OPEN_NEW=TRUE"); - Statement stat = conn.createStatement(); - if (config.big) { - try { - stat.execute("SHUTDOWN"); - } catch (SQLException e) { - assertKnownException(e); - // the connection is closed - } - } - conn.close(); - connServer.close(); - deleteDb("autoServer"); - } - - /** - * Tests recreation of temporary linked tables on reconnect - */ - private void testLinkedLocalTablesWithAutoServerReconnect() throws SQLException { - if (config.memory || config.networked) { - return; - } - deleteDb("autoServerLinkedTable1"); - deleteDb("autoServerLinkedTable2"); - String url = getURL("autoServerLinkedTable1;AUTO_SERVER=TRUE", true); - String urlLinked = getURL("autoServerLinkedTable2", true); - String user = getUser(), password = getPassword(); - - Connection connLinked = getConnection(urlLinked, user, password); - Statement statLinked = connLinked.createStatement(); - statLinked.execute("CREATE TABLE TEST(ID VARCHAR)"); - - // Server is connection 1 - Connection connAutoServer1 = getConnection(url + ";OPEN_NEW=TRUE", user, password); - Statement statAutoServer1 = connAutoServer1.createStatement(); - statAutoServer1.execute("CREATE LOCAL TEMPORARY LINKED TABLE T('', '" + - urlLinked + "', '" + user + "', '" + password + "', 'TEST')"); - - // Connection 2 connects - Connection connAutoServer2 = getConnection(url + ";OPEN_NEW=TRUE", user, password); - Statement statAutoServer2 = connAutoServer2.createStatement(); - statAutoServer2.execute("CREATE LOCAL TEMPORARY LINKED TABLE T('', '" + - urlLinked + "', '" + user + "', '" + password + "', 'TEST')"); - - // Server 1 closes the connection => connection 2 will be the server - // => the "force create local temporary linked..." must be reissued - statAutoServer1.execute("shutdown immediately"); - try { - connAutoServer1.close(); - } catch (SQLException e) { - // ignore - } - - // Now test insert - statAutoServer2.execute("INSERT INTO T (ID) VALUES('abc')"); - statAutoServer2.execute("drop table t"); - connAutoServer2.close(); - - // this will also close the linked connection from statAutoServer1 - connLinked.createStatement().execute("shutdown immediately"); - try { - connLinked.close(); - } catch (SQLException e) { - // ignore - } - - deleteDb("autoServerLinkedTable1"); - deleteDb("autoServerLinkedTable2"); - } - - /** - * This method is called via reflection from the database. - * - * @param exitValue the exit value - */ - public static void halt(int exitValue) { - Runtime.getRuntime().halt(exitValue); - } - -} diff --git a/tools/h2/src/test/org/h2/test/server/TestInit.java b/tools/h2/src/test/org/h2/test/server/TestInit.java deleted file mode 100755 index f0e93cf..0000000 --- a/tools/h2/src/test/org/h2/test/server/TestInit.java +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.test.server; - -import java.io.OutputStreamWriter; -import java.io.PrintWriter; -import java.io.Writer; -import java.sql.Connection; -import java.sql.ResultSet; -import java.sql.Statement; -import org.h2.test.TestBase; -import org.h2.util.IOUtils; - -/** - * Tests INIT command within embedded/server mode. - */ -public class TestInit extends TestBase { - - /** - * Run just this test. - * - * @param a ignored - */ - public static void main(String[] a) throws Exception { - TestBase.createCaller().init().test(); - } - - public void test() throws Exception { - - String init1 = getBaseDir() + "/test-init-1.sql"; - String init2 = getBaseDir() + "/test-init-2.sql"; - - // Create two scripts that we will run via "INIT" - IOUtils.createDirs(init1); - - Writer w = new OutputStreamWriter(IOUtils.openFileOutputStream(init1, false)); - - PrintWriter writer = new PrintWriter(w); - writer.println("create table test(id int identity, name varchar);"); - writer.println("insert into test(name) values('cat');"); - writer.close(); - - w = new OutputStreamWriter(IOUtils.openFileOutputStream(init2, false)); - writer = new PrintWriter(w); - writer.println("insert into test(name) values('dog');"); - writer.close(); - - // Make the database connection, and run the two scripts - deleteDb("initDb"); - Connection conn = getConnection("initDb;" + - "INIT=" + - "RUNSCRIPT FROM '" + init1 + "'\\;" + - "RUNSCRIPT FROM '" + init2 + "'"); - - Statement stat = conn.createStatement(); - - // Confirm our scripts have run by loading the data they inserted - ResultSet rs = stat.executeQuery("select name from test order by name"); - - assertTrue(rs.next()); - assertEquals("cat", rs.getString(1)); - - assertTrue(rs.next()); - assertEquals("dog", rs.getString(1)); - - assertFalse(rs.next()); - - conn.close(); - deleteDb("initDb"); - - IOUtils.delete(init1); - IOUtils.delete(init2); - } - -} diff --git a/tools/h2/src/test/org/h2/test/server/TestNestedLoop.java b/tools/h2/src/test/org/h2/test/server/TestNestedLoop.java deleted file mode 100755 index fa621d6..0000000 --- a/tools/h2/src/test/org/h2/test/server/TestNestedLoop.java +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.test.server; - -import java.sql.Connection; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.sql.Statement; - -import org.h2.test.TestBase; - -/** - * Tests remote JDBC access with nested loops. - * This is not allowed in some databases. - */ -public class TestNestedLoop extends TestBase { - - /** - * Run just this test. - * - * @param a ignored - */ - public static void main(String... a) throws Exception { - TestBase.createCaller().init().test(); - } - - public void test() throws SQLException { - deleteDb("nestedLoop"); - Connection conn = getConnection("nestedLoop"); - Statement stat = conn.createStatement(); - stat.execute("create table test(id int identity, name varchar)"); - int len = getSize(1010, 10000); - for (int i = 0; i < len; i++) { - stat.execute("insert into test(name) values('Hello World')"); - } - ResultSet rs = stat.executeQuery("select id from test"); - stat.executeQuery("select id from test"); - try { - rs.next(); - fail("Result set should be closed"); - } catch (SQLException e) { - assertKnownException(e); - } - rs = stat.executeQuery("select id from test"); - stat.close(); - try { - rs.next(); - fail("Result set should be closed"); - } catch (SQLException e) { - assertKnownException(e); - } - stat = conn.createStatement(); - rs = stat.executeQuery("select id from test"); - Statement stat2 = conn.createStatement(); - while (rs.next()) { - int id = rs.getInt(1); - ResultSet rs2 = stat2.executeQuery("select * from test where id=" + id); - while (rs2.next()) { - assertEquals(id, rs2.getInt(1)); - assertEquals("Hello World", rs2.getString(2)); - } - rs2 = stat2.executeQuery("select * from test where id=" + id); - while (rs2.next()) { - assertEquals(id, rs2.getInt(1)); - assertEquals("Hello World", rs2.getString(2)); - } - } - conn.close(); - deleteDb("nestedLoop"); - } - -} diff --git a/tools/h2/src/test/org/h2/test/server/TestWeb.java b/tools/h2/src/test/org/h2/test/server/TestWeb.java deleted file mode 100755 index e708e96..0000000 --- a/tools/h2/src/test/org/h2/test/server/TestWeb.java +++ /dev/null @@ -1,122 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.test.server; - -import org.h2.test.TestBase; -import org.h2.tools.Server; - -/** - * Tests the H2 Console application. - */ -public class TestWeb extends TestBase { - - /** - * Run just this test. - * - * @param a ignored - */ - public static void main(String... a) throws Exception { - TestBase.createCaller().init().test(); - } - - public void test() throws Exception { - Server server = Server.createWebServer("-webPort", "8182"); - server.start(); - String url = server.getURL(); - WebClient client = new WebClient(); - String result = client.get(url); - client.readSessionId(result); - client.get(url, "login.jsp"); - client.get(url, "stylesheet.css"); - client.get(url, "adminSave.do"); - result = client.get(url, "index.do?language=de"); - result = client.get(url, "login.jsp"); - assertContains(result, "Einstellung"); - result = client.get(url, "index.do?language=en"); - result = client.get(url, "login.jsp"); - assertTrue(result.indexOf("Einstellung") < 0); - result = client.get(url, "test.do?driver=abc&url=jdbc:abc:mem:web&user=sa&password=sa&name=_test_"); - assertContains(result, "Exception"); - result = client.get(url, "test.do?driver=org.h2.Driver&url=jdbc:h2:mem:web&user=sa&password=sa&name=_test_"); - assertTrue(result.indexOf("Exception") < 0); - result = client.get(url, "login.do?driver=org.h2.Driver&url=jdbc:h2:mem:web&user=sa&password=sa&name=_test_"); - result = client.get(url, "header.jsp"); - result = client.get(url, "tables.do"); - result = client.get(url, "query.jsp"); - result = client.get(url, "query.do?sql=select * from test"); - result = client.get(url, "query.do?sql=drop table test if exists"); - result = client.get(url, "query.do?sql=create table test(id int primary key, name varchar);insert into test values(1, 'Hello')"); - result = client.get(url, "query.do?sql=select * from test"); - assertContains(result, "Hello"); - result = client.get(url, "query.do?sql=@META select * from test"); - assertContains(result, "typeName"); - result = client.get(url, "query.do?sql=delete from test"); - result = client.get(url, "query.do?sql=@LOOP 1000 insert into test values(?, 'Hello ' || ?/*RND*/)"); - assertContains(result, "1000 * (Prepared)"); - result = client.get(url, "query.do?sql=select * from test"); - result = client.get(url, "query.do?sql=@HISTORY"); - result = client.get(url, "getHistory.do?id=4"); - assertContains(result, "select * from test"); - result = client.get(url, "autoCompleteList.do?query=se"); - -// long time = System.currentTimeMillis(); -// for (int i=0; i<1000; i++) { -// if(System.currentTimeMillis()-time > 15000) { -// break; -// } -// result = client.get(url, "autoCompleteList.do?query=select * from "); - - assertContains(result, "select"); - assertContains(result, "set"); - result = client.get(url, "tables.do"); - assertContains(result, "TEST"); - result = client.get(url, "autoCompleteList.do?query=select * from "); - assertContains(result, "test"); - result = client.get(url, "autoCompleteList.do?query=select * from test t where t."); - assertContains(result, "id"); - result = client.get(url, "autoCompleteList.do?query=select id x from test te where t"); - assertContains(result, "te"); - - result = client.get(url, "query.do?sql=delete from test"); - result = client.get(url, "query.do?sql=@LOOP 10 @STATEMENT insert into test values(?, 'Hello')"); - result = client.get(url, "query.do?sql=select * from test"); - assertContains(result, "8"); - result = client.get(url, "query.do?sql=@EDIT select * from test"); - assertContains(result, "editRow"); - - result = client.get(url, "query.do?sql=@AUTOCOMMIT TRUE"); - result = client.get(url, "query.do?sql=@AUTOCOMMIT FALSE"); - result = client.get(url, "query.do?sql=@TRANSACTION_ISOLATION"); - result = client.get(url, "query.do?sql=@SET MAXROWS 1"); - result = client.get(url, "query.do?sql=select * from test order by id"); - result = client.get(url, "query.do?sql=@SET MAXROWS 1000"); - result = client.get(url, "query.do?sql=@TABLES"); - assertContains(result, "TEST"); - result = client.get(url, "query.do?sql=@COLUMNS null null TEST"); - assertContains(result, "ID"); - result = client.get(url, "query.do?sql=@INDEX_INFO null null TEST"); - assertContains(result, "PRIMARY"); - result = client.get(url, "query.do?sql=@CATALOG"); - assertContains(result, "PUBLIC"); - result = client.get(url, "query.do?sql=@MEMORY"); - assertContains(result, "Used"); - result = client.get(url, "query.do?sql=@UDTS"); - - result = client.get(url, "query.do?sql=@INFO"); - assertContains(result, "getCatalog"); - - result = client.get(url, "logout.do"); - result = client.get(url, "settingRemove.do?name=_test_"); - - client.get(url, "admin.do"); - // this would also stop the server - // client.get(url, "adminShutdown.do"); - - server.stop(); - } - -} diff --git a/tools/h2/src/test/org/h2/test/server/WebClient.java b/tools/h2/src/test/org/h2/test/server/WebClient.java deleted file mode 100755 index d31f57f..0000000 --- a/tools/h2/src/test/org/h2/test/server/WebClient.java +++ /dev/null @@ -1,86 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.test.server; - -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.net.HttpURLConnection; -import java.net.URL; - -import org.h2.util.IOUtils; - -/** - * A simple web browser simulator. - */ -public class WebClient { - - private String sessionId; - - /** - * Open an URL and get the HTML data. - * - * @param url the HTTP URL - * @return the HTML as a string - */ - String get(String url) throws IOException { - HttpURLConnection connection = (HttpURLConnection) new URL(url).openConnection(); - connection.setRequestMethod("GET"); - connection.setInstanceFollowRedirects(true); - connection.connect(); - int code = connection.getResponseCode(); - if (code != HttpURLConnection.HTTP_OK) { - throw new IOException("Result code: " + code); - } - InputStream in = connection.getInputStream(); - String result = IOUtils.readStringAndClose(new InputStreamReader(in), -1); - connection.disconnect(); - return result; - } - - /** - * Read the session ID from a URL. - * - * @param url the URL - */ - void readSessionId(String url) { - int idx = url.indexOf("jsessionid="); - String id = url.substring(idx + "jsessionid=".length()); - for (int i = 0; i < url.length(); i++) { - char ch = id.charAt(i); - if (!Character.isLetterOrDigit(ch)) { - id = id.substring(0, i); - break; - } - } - this.sessionId = id; - } - - /** - * Read the specified HTML page. - * - * @param url the base URL - * @param page the page to read - * @return the HTML page - */ - String get(String url, String page) throws IOException { - if (sessionId != null) { - if (page.indexOf('?') < 0) { - page += "?"; - } else { - page += "&"; - } - page += "jsessionid=" + sessionId; - } - if (!url.endsWith("/")) { - url += "/"; - } - url += page; - return get(url); - } - -} diff --git a/tools/h2/src/test/org/h2/test/server/package.html b/tools/h2/src/test/org/h2/test/server/package.html deleted file mode 100755 index 04d0f11..0000000 --- a/tools/h2/src/test/org/h2/test/server/package.html +++ /dev/null @@ -1,15 +0,0 @@ - - - - -Javadoc package documentation -

    - -This package contains server tests. - -

    \ No newline at end of file diff --git a/tools/h2/src/test/org/h2/test/synth/BnfRandom.java b/tools/h2/src/test/org/h2/test/synth/BnfRandom.java deleted file mode 100755 index 3636847..0000000 --- a/tools/h2/src/test/org/h2/test/synth/BnfRandom.java +++ /dev/null @@ -1,195 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.test.synth; - -import java.util.ArrayList; -import java.util.Random; -import org.h2.bnf.Bnf; -import org.h2.bnf.BnfVisitor; -import org.h2.bnf.Rule; -import org.h2.bnf.RuleFixed; -import org.h2.bnf.RuleHead; -import org.h2.util.New; - -/** - * A BNF visitor that generates a random SQL statement. - */ -public class BnfRandom implements BnfVisitor { - - private static final boolean SHOW_SYNTAX = false; - - private final Bnf config; - private final Random random = new Random(); - private final ArrayList statements = New.arrayList(); - - private int level; - private String sql; - - BnfRandom() throws Exception { - config = Bnf.getInstance(null); - config.linkStatements(); - - ArrayList all = config.getStatements(); - - // go backwards so we can append at the end - for (int i = all.size() - 1; i >= 0; i--) { - RuleHead r = all.get(i); - String topic = r.getTopic().toLowerCase(); - int weight = 0; - if (topic.equals("select")) { - weight = 10; - } else if (topic.equals("create table")) { - weight = 20; - } else if (topic.equals("insert")) { - weight = 5; - } else if (topic.startsWith("update")) { - weight = 3; - } else if (topic.startsWith("delete")) { - weight = 3; - } else if (topic.startsWith("drop")) { - weight = 2; - } - if (SHOW_SYNTAX) { - System.out.println(r.getTopic()); - } - for (int j = 0; j < weight; j++) { - statements.add(r); - } - } - } - - public String getRandomSQL() { - int sid = random.nextInt(statements.size()); - - RuleHead r = statements.get(sid); - level = 0; - r.getRule().accept(this); - sql = sql.trim(); - - if (sql.length() > 0) { - if (sql.indexOf("TRACE_LEVEL_") < 0 && sql.indexOf("COLLATION") < 0 - && sql.indexOf("SCRIPT ") < 0 && sql.indexOf("CSVWRITE") < 0 - && sql.indexOf("BACKUP") < 0 && sql.indexOf("DB_CLOSE_DELAY") < 0) { - if (SHOW_SYNTAX) { - System.out.println(" " + sql); - } - return sql; - } - } - return null; - } - - public void visitRuleElement(boolean keyword, String name, Rule link) { - if (keyword) { - if (name.startsWith(";")) { - sql = ""; - } else { - sql = name.length() > 1 ? " " + name + " " : name; - } - } else if (link != null) { - level++; - link.accept(this); - level--; - } else { - throw new AssertionError(name); - } - } - - public void visitRuleFixed(int type) { - sql = getRandomFixed(type); - } - - private String getRandomFixed(int type) { - Random r = random; - switch (type) { - case RuleFixed.YMD: - return (1800 + r.nextInt(200)) + "-" + (1 + r.nextInt(12)) + "-" + (1 + r.nextInt(31)); - case RuleFixed.HMS: - return (r.nextInt(24)) + "-" + (r.nextInt(60)) + "-" + (r.nextInt(60)); - case RuleFixed.NANOS: - return "" + (r.nextInt(100000) + r.nextInt(10000)); - case RuleFixed.ANY_UNTIL_EOL: - case RuleFixed.ANY_EXCEPT_SINGLE_QUOTE: - case RuleFixed.ANY_EXCEPT_DOUBLE_QUOTE: - case RuleFixed.ANY_WORD: - case RuleFixed.ANY_EXCEPT_2_DOLLAR: - case RuleFixed.ANY_UNTIL_END: { - StringBuilder buff = new StringBuilder(); - int len = r.nextBoolean() ? 1 : r.nextInt(5); - for (int i = 0; i < len; i++) { - buff.append((char) ('A' + r.nextInt('C' - 'A'))); - } - return buff.toString(); - } - case RuleFixed.HEX_START: - return "0x"; - case RuleFixed.CONCAT: - return "||"; - case RuleFixed.AZ_UNDERSCORE: - return "" + (char) ('A' + r.nextInt('C' - 'A')); - case RuleFixed.AF: - return "" + (char) ('A' + r.nextInt('F' - 'A')); - case RuleFixed.DIGIT: - return "" + (char) ('0' + r.nextInt(10)); - case RuleFixed.OPEN_BRACKET: - return "["; - case RuleFixed.CLOSE_BRACKET: - return "]"; - default: - throw new AssertionError("type="+type); - } - } - - public void visitRuleList(boolean or, ArrayList list) { - if (or) { - if (level > 10) { - if (level > 1000) { - // better than stack overflow - throw new AssertionError(); - } - list.get(0).accept(this); - return; - } - int idx = random.nextInt(list.size()); - level++; - list.get(idx).accept(this); - level--; - return; - } - StringBuilder buff = new StringBuilder(); - level++; - for (Rule r : list) { - r.accept(this); - buff.append(sql); - } - level--; - sql = buff.toString(); - } - - public void visitRuleOptional(Rule rule) { - if (level > 10 ? random.nextInt(level) == 1 : random.nextInt(4) == 1) { - level++; - rule.accept(this); - level--; - return; - } - sql = ""; - } - - public void visitRuleRepeat(boolean comma, Rule rule) { - rule.accept(this); - } - - public void setSeed(int seed) { - random.setSeed(seed); - } - - public int getStatementCount() { - return statements.size(); - } - -} diff --git a/tools/h2/src/test/org/h2/test/synth/OutputCatcher.java b/tools/h2/src/test/org/h2/test/synth/OutputCatcher.java deleted file mode 100755 index 170dc0e..0000000 --- a/tools/h2/src/test/org/h2/test/synth/OutputCatcher.java +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.test.synth; - -import java.io.IOException; -import java.io.InputStream; -import java.util.LinkedList; - -import org.h2.util.IOUtils; - -/** - * Catches the output of another process. - */ -public class OutputCatcher extends Thread { - private InputStream in; - private LinkedList list = new LinkedList(); - - public OutputCatcher(InputStream in) { - this.in = in; - } - - /** - * Read a line from the output. - * - * @param wait the maximum number of milliseconds to wait - * @return the line - */ - public String readLine(long wait) { - long start = System.currentTimeMillis(); - while (true) { - synchronized (list) { - if (list.size() > 0) { - return list.removeFirst(); - } - try { - list.wait(wait); - } catch (InterruptedException e) { - // ignore - } - long time = System.currentTimeMillis() - start; - if (time >= wait) { - return null; - } - } - } - } - - public void run() { - StringBuilder buff = new StringBuilder(); - while (true) { - try { - int x = in.read(); - if (x < 0) { - break; - } - if (x < ' ') { - if (buff.length() > 0) { - String s = buff.toString(); - buff.setLength(0); - synchronized (list) { - list.add(s); - list.notifyAll(); - } - } - } else { - buff.append((char) x); - } - } catch (IOException e) { - break; - } - } - IOUtils.closeSilently(in); - } -} diff --git a/tools/h2/src/test/org/h2/test/synth/TestBtreeIndex.java b/tools/h2/src/test/org/h2/test/synth/TestBtreeIndex.java deleted file mode 100755 index fdd65f2..0000000 --- a/tools/h2/src/test/org/h2/test/synth/TestBtreeIndex.java +++ /dev/null @@ -1,191 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.test.synth; - -import java.sql.Connection; -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.sql.Statement; -import java.util.Random; -import org.h2.test.TestBase; -import org.h2.tools.DeleteDbFiles; - -/** - * A b-tree index test. - */ -public class TestBtreeIndex extends TestBase { - - /** - * Run just this test. - * - * @param a ignored - */ - public static void main(String... a) throws Exception { - TestBase.createCaller().init().test(); - } - - public void test() throws SQLException { - Random random = new Random(); - for (int i = 0; i < getSize(1, 4); i++) { - testAddDelete(); - int seed = random.nextInt(); - testCase(seed); - } - } - - private void testAddDelete() throws SQLException { - deleteDb("index"); - Connection conn = getConnection("index"); - try { - Statement stat = conn.createStatement(); - stat.execute("CREATE TABLE TEST(ID bigint primary key)"); - int count = 1000; - stat.execute("insert into test select x from system_range(1, " + count + ")"); - if (!config.memory) { - conn.close(); - conn = getConnection("index"); - stat = conn.createStatement(); - } - for (int i = 1; i < count; i++) { - ResultSet rs = stat.executeQuery("select * from test order by id"); - for (int j = i; rs.next(); j++) { - assertEquals(j, rs.getInt(1)); - } - stat.execute("delete from test where id =" + i); - } - stat.execute("drop all objects delete files"); - } finally { - conn.close(); - } - deleteDb("index"); - } - - public void testCase(int seed) throws SQLException { - testOne(seed); - } - - private void testOne(int seed) throws SQLException { - org.h2.Driver.load(); - deleteDb("index"); - printTime("testIndex " + seed); - Random random = new Random(seed); - int distinct, prefixLength; - if (random.nextBoolean()) { - distinct = random.nextInt(8000) + 1; - prefixLength = random.nextInt(8000) + 1; - } else if (random.nextBoolean()) { - distinct = random.nextInt(16000) + 1; - prefixLength = random.nextInt(100) + 1; - } else { - distinct = random.nextInt(10) + 1; - prefixLength = random.nextInt(10) + 1; - } - boolean delete = random.nextBoolean(); - StringBuilder buff = new StringBuilder(); - for (int j = 0; j < prefixLength; j++) { - buff.append("x"); - if (buff.length() % 10 == 0) { - buff.append(buff.length()); - } - } - String prefix = buff.toString().substring(0, prefixLength); - DeleteDbFiles.execute(getBaseDir() + "/index", null, true); - Connection conn = getConnection("index"); - try { - Statement stat = conn.createStatement(); - stat.execute("CREATE TABLE a(text VARCHAR PRIMARY KEY)"); - PreparedStatement prepInsert = conn.prepareStatement("INSERT INTO a VALUES(?)"); - PreparedStatement prepDelete = conn.prepareStatement("DELETE FROM a WHERE text=?"); - PreparedStatement prepDeleteAllButOne = conn.prepareStatement("DELETE FROM a WHERE text <> ?"); - int count = 0; - for (int i = 0; i < 1000; i++) { - int y = random.nextInt(distinct); - try { - prepInsert.setString(1, prefix + y); - prepInsert.executeUpdate(); - count++; - } catch (SQLException e) { - if (e.getSQLState().equals("23001")) { - // ignore - } else { - TestBase.logError("error", e); - break; - } - } - if (delete && random.nextInt(10) == 1) { - if (random.nextInt(4) == 1) { - try { - prepDeleteAllButOne.setString(1, prefix + y); - int deleted = prepDeleteAllButOne.executeUpdate(); - if (deleted < count - 1) { - printError(seed, "deleted:" + deleted + " i:" + i); - } - count -= deleted; - } catch (SQLException e) { - TestBase.logError("error", e); - break; - } - } else { - try { - prepDelete.setString(1, prefix + y); - int deleted = prepDelete.executeUpdate(); - if (deleted > 1) { - printError(seed, "deleted:" + deleted + " i:" + i); - } - count -= deleted; - } catch (SQLException e) { - TestBase.logError("error", e); - break; - } - } - } - } - int testCount; - testCount = 0; - ResultSet rs = stat.executeQuery("SELECT text FROM a ORDER BY text"); - ResultSet rs2 = conn.createStatement().executeQuery("SELECT text FROM a ORDER BY 'x' || text"); - -//System.out.println("-----------"); -//while(rs.next()) { -// System.out.println(rs.getString(1)); -//} -//System.out.println("-----------"); -//while(rs2.next()) { -// System.out.println(rs2.getString(1)); -//} -//if (true) throw new AssertionError("stop"); -// - testCount = 0; - while (rs.next() && rs2.next()) { - if (!rs.getString(1).equals(rs2.getString(1))) { - fail("" + testCount); - } - testCount++; - } - assertFalse(rs.next()); - assertFalse(rs2.next()); - if (testCount != count) { - printError(seed, "count:" + count + " testCount:" + testCount); - } - rs = stat.executeQuery("SELECT text, count(*) FROM a GROUP BY text HAVING COUNT(*)>1"); - if (rs.next()) { - printError(seed, "testCount:" + testCount + " " + rs.getString(1)); - } - } finally { - conn.close(); - } - deleteDb("index"); - } - - private void printError(int seed, String message) { - TestBase.logError("new TestBtreeIndex().init(test).testCase(" + - seed + "); // " + message, null); - fail(message); - } - -} diff --git a/tools/h2/src/test/org/h2/test/synth/TestCrashAPI.java b/tools/h2/src/test/org/h2/test/synth/TestCrashAPI.java deleted file mode 100755 index dc9cfba..0000000 --- a/tools/h2/src/test/org/h2/test/synth/TestCrashAPI.java +++ /dev/null @@ -1,526 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.test.synth; - -import java.io.File; -import java.io.PrintWriter; -import java.io.StringWriter; -import java.lang.reflect.Array; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; -import java.sql.BatchUpdateException; -import java.sql.Blob; -import java.sql.CallableStatement; -import java.sql.Clob; -import java.sql.Connection; -import java.sql.DriverManager; -import java.sql.ParameterMetaData; -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.ResultSetMetaData; -import java.sql.SQLException; -import java.sql.Savepoint; -import java.sql.Statement; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Calendar; -import java.util.Comparator; -import java.util.HashMap; -import java.util.Map; -import org.h2.constant.ErrorCode; -import org.h2.constant.SysProperties; -import org.h2.jdbc.JdbcConnection; -import org.h2.store.FileLister; -import org.h2.test.TestAll; -import org.h2.test.TestBase; -import org.h2.test.db.TestScript; -import org.h2.test.synth.sql.RandomGen; -import org.h2.tools.Backup; -import org.h2.tools.DeleteDbFiles; -import org.h2.tools.Restore; -import org.h2.util.IOUtils; -import org.h2.util.MathUtils; -import org.h2.util.New; - -/** - * A test that calls random methods with random parameters from JDBC objects. - * This is sometimes called 'Fuzz Testing'. - */ -public class TestCrashAPI extends TestBase implements Runnable { - - private static final boolean RECOVER_ALL = false; - - private static final Class< ? >[] INTERFACES = { Connection.class, PreparedStatement.class, Statement.class, - ResultSet.class, ResultSetMetaData.class, Savepoint.class, - ParameterMetaData.class, Clob.class, Blob.class, Array.class, CallableStatement.class }; - - private static final String DIR = "synth"; - - private ArrayList objects = New.arrayList(); - private HashMap, ArrayList> classMethods = New.hashMap(); - private RandomGen random = new RandomGen(); - private ArrayList statements = New.arrayList(); - private int openCount; - private long callCount; - private volatile long maxWait = 5 * 60; - private volatile boolean stopped; - private volatile boolean running; - private Thread mainThread; - - /** - * Run just this test. - * - * @param a ignored - */ - public static void main(String... a) throws Exception { - TestBase.createCaller().init().test(); - } - - @SuppressWarnings("deprecation") - public void run() { - while (--maxWait > 0) { - try { - Thread.sleep(1000); - } catch (InterruptedException e) { - // ignore - } - } - if (maxWait == 0) { - println("stopping..."); - stopped = true; - objects.clear(); - if (running) { - mainThread.stop(new SQLException("stop")); - } - } - } - - private void recoverAll() throws SQLException { - org.h2.Driver.load(); - File[] files = new File("temp/backup").listFiles(); - Arrays.sort(files, new Comparator() { - public int compare(File o1, File o2) { - return o1.getName().compareTo(o2.getName()); - } - }); - for (File f : files) { - if (!f.getName().startsWith("db-")) { - continue; - } - DeleteDbFiles.execute("data", null, true); - try { - Restore.execute(f.getAbsolutePath(), "data", null, true); - } catch (Exception e) { - System.out.println(f.getName() + " restore error " + e); - // ignore - } - ArrayList dbFiles = FileLister.getDatabaseFiles("data", null, false); - for (String name: dbFiles) { - if (!name.endsWith(".h2.db")) { - continue; - } - name = name.substring(0, name.length() - 6); - try { - DriverManager.getConnection("jdbc:h2:data/" + name, "sa", "").close(); - System.out.println(f.getName() + " OK"); - } catch (SQLException e) { - System.out.println(f.getName() + " " + e); - } - } - } - } - - public void test() throws Exception { - if (RECOVER_ALL) { - recoverAll(); - return; - } - if (config.mvcc || config.networked) { - return; - } - int len = getSize(2, 6); - Thread t = new Thread(this); - try { - mainThread = Thread.currentThread(); - t.start(); - running = true; - for (int i = 0; i < len && !stopped; i++) { - int seed = MathUtils.randomInt(Integer.MAX_VALUE); - testCase(seed); - deleteDb(); - } - } finally { - running = false; - deleteDb(); - maxWait = -1; - t.join(); - } - } - - private void deleteDb() { - try { - deleteDb(getBaseDir() + "/" + DIR, null); - } catch (Exception e) { - // ignore - } - } - - private Connection getConnection(int seed, boolean delete) throws SQLException { - openCount++; - if (delete) { - deleteDb(); - } - // can not use FILE_LOCK=NO, otherwise something could be written into - // the database in the finalize method - - String add = ""; - -// int testing; -// if(openCount >= 32) { -// int test; -// Runtime.getRuntime().halt(0); -// System.exit(1); -// } - // System.out.println("now open " + openCount); - // add += ";TRACE_LEVEL_FILE=3"; - // config.logMode = 2; - // } - - String dbName = "crashApi" + seed; - String url = getURL(DIR + "/" + dbName, true) + add; - -// int test; -// url += ";DB_CLOSE_ON_EXIT=FALSE"; -// int test; -// url += ";TRACE_LEVEL_FILE=3"; - - Connection conn = null; - String fileName = "temp/backup/db-" + uniqueId++ + ".zip"; - Backup.execute(fileName, getBaseDir() + "/" + DIR, dbName, true); - // close databases earlier - System.gc(); - try { - conn = DriverManager.getConnection(url, "sa", getPassword("")); - // delete the backup if opening was successful - IOUtils.delete(fileName); - } catch (SQLException e) { - if (e.getErrorCode() == ErrorCode.WRONG_USER_OR_PASSWORD) { - // delete if the password changed - IOUtils.delete(fileName); - } - throw e; - } - int len = random.getInt(50); - int first = random.getInt(statements.size() - len); - int end = first + len; - Statement stat = conn.createStatement(); - stat.execute("SET LOCK_TIMEOUT 10"); - stat.execute("SET WRITE_DELAY 0"); - if (random.nextBoolean()) { - if (random.nextBoolean()) { - double g = random.nextGaussian(); - int size = (int) Math.abs(10000 * g * g); - stat.execute("SET CACHE_SIZE " + size); - } else { - stat.execute("SET CACHE_SIZE 0"); - } - } - stat.execute("SCRIPT NOPASSWORDS NOSETTINGS"); - for (int i = first; i < end && i < statements.size() && !stopped; i++) { - try { - stat.execute("SELECT * FROM TEST WHERE ID=1"); - } catch (Throwable t) { - printIfBad(seed, -i, -1, t); - } - try { - stat.execute("SELECT * FROM TEST WHERE ID=1 OR ID=1"); - } catch (Throwable t) { - printIfBad(seed, -i, -1, t); - } - - String sql = statements.get(i); - try { -// if(openCount == 32) { -// int test; -// System.out.println("stop!"); -// } - stat.execute(sql); - } catch (Throwable t) { - printIfBad(seed, -i, -1, t); - } - } - if (random.nextBoolean()) { - try { - conn.commit(); - } catch (Throwable t) { - printIfBad(seed, 0, -1, t); - } - } - return conn; - } - - private void testOne(int seed) throws SQLException { - printTime("seed: " + seed); - callCount = 0; - openCount = 0; - random = new RandomGen(); - random.setSeed(seed); - Connection c1 = getConnection(seed, true); - Connection conn = null; - for (int i = 0; i < 2000 && !stopped; i++) { - // if(i % 10 == 0) { - // for(int j=0; j in = getJdbcInterface(o); - ArrayList methods = classMethods.get(in); - Method m = methods.get(random.getInt(methods.size())); - Object o2 = callRandom(seed, i, objectId, o, m); - if (o2 != null) { - objects.add(o2); - } - } - try { - if (conn != null) { - conn.close(); - } - c1.close(); - } catch (Throwable t) { - printIfBad(seed, -101010, -1, t); - try { - deleteDb(); - } catch (Throwable t2) { - printIfBad(seed, -101010, -1, t2); - } - } - objects.clear(); - } - - private void printError(int seed, int id, Throwable t) { - StringWriter writer = new StringWriter(); - t.printStackTrace(new PrintWriter(writer)); - String s = writer.toString(); - TestBase.logError("new TestCrashAPI().init(test).testCase(" + - seed + "); // Bug " + s.hashCode() + " id=" + id + - " callCount=" + callCount + " openCount=" + openCount + - " " + t.getMessage(), t); - throw new RuntimeException(t); - } - - private Object callRandom(int seed, int id, int objectId, Object o, Method m) { - Class< ? >[] paramClasses = m.getParameterTypes(); - Object[] params = new Object[paramClasses.length]; - for (int i = 0; i < params.length; i++) { - params[i] = getRandomParam(paramClasses[i]); - } - Object result = null; - try { - callCount++; - result = m.invoke(o, params); - } catch (IllegalArgumentException e) { - TestBase.logError("error", e); - } catch (IllegalAccessException e) { - TestBase.logError("error", e); - } catch (InvocationTargetException e) { - Throwable t = e.getTargetException(); - printIfBad(seed, id, objectId, t); - } - if (result == null) { - return null; - } - Class< ? > in = getJdbcInterface(result); - if (in == null) { - return null; - } - return result; - } - - private void printIfBad(int seed, int id, int objectId, Throwable t) { - if (t instanceof BatchUpdateException) { - // do nothing - } else if (t.getClass().getName().indexOf("SQLClientInfoException") >= 0) { - // do nothing - } else if (t instanceof SQLException) { - SQLException s = (SQLException) t; - int errorCode = s.getErrorCode(); - if (errorCode == 0) { - printError(seed, id, s); - } else if (errorCode == ErrorCode.OBJECT_CLOSED) { - if (objectId >= 0) { - // TODO at least call a few more times after close - maybe - // there is still an error - objects.remove(objectId); - } - } else if (errorCode == ErrorCode.GENERAL_ERROR_1) { - // General error [HY000] - printError(seed, id, s); - } - } else { - printError(seed, id, t); - } - } - - private Object getRandomParam(Class< ? > type) { - if (type == int.class) { - return new Integer(random.getRandomInt()); - } else if (type == byte.class) { - return new Byte((byte) random.getRandomInt()); - } else if (type == short.class) { - return new Short((short) random.getRandomInt()); - } else if (type == long.class) { - return new Long(random.getRandomLong()); - } else if (type == float.class) { - return new Float(random.getRandomDouble()); - } else if (type == boolean.class) { - return new Boolean(random.nextBoolean()); - } else if (type == double.class) { - return new Double(random.getRandomDouble()); - } else if (type == String.class) { - if (random.getInt(10) == 0) { - return null; - } - int randomId = random.getInt(statements.size()); - String sql = statements.get(randomId); - if (random.getInt(10) == 0) { - sql = random.modify(sql); - } - return sql; - } else if (type == int[].class) { - // TODO test with 'shared' arrays (make sure database creates a - // copy) - return random.getIntArray(); - } else if (type == java.io.Reader.class) { - return null; - } else if (type == java.sql.Array.class) { - return null; - } else if (type == byte[].class) { - // TODO test with 'shared' arrays (make sure database creates a - // copy) - return random.getByteArray(); - } else if (type == Map.class) { - return null; - } else if (type == Object.class) { - return null; - } else if (type == java.sql.Date.class) { - return random.randomDate(); - } else if (type == java.sql.Time.class) { - return random.randomTime(); - } else if (type == java.sql.Timestamp.class) { - return random.randomTimestamp(); - } else if (type == java.io.InputStream.class) { - return null; - } else if (type == String[].class) { - return null; - } else if (type == java.sql.Clob.class) { - return null; - } else if (type == java.sql.Blob.class) { - return null; - } else if (type == Savepoint.class) { - // TODO should use generated savepoints - return null; - } else if (type == Calendar.class) { - return Calendar.getInstance(); - } else if (type == java.net.URL.class) { - return null; - } else if (type == java.math.BigDecimal.class) { - return new java.math.BigDecimal("" + random.getRandomDouble()); - } else if (type == java.sql.Ref.class) { - return null; - } - return null; - } - - private Class< ? > getJdbcInterface(Object o) { - for (Class < ? > in : o.getClass().getInterfaces()) { - if (classMethods.get(in) != null) { - return in; - } - } - return null; - } - - private void initMethods() { - for (Class< ? > inter : INTERFACES) { - classMethods.put(inter, new ArrayList()); - } - for (Class< ? > inter : INTERFACES) { - ArrayList list = classMethods.get(inter); - for (Method m : inter.getMethods()) { - list.add(m); - } - } - } - - public TestBase init(TestAll conf) throws Exception { - super.init(conf); - if (config.mvcc || config.networked) { - return this; - } - startServerIfRequired(); - TestScript script = new TestScript(); - ArrayList add = script.getAllStatements(config); - initMethods(); - org.h2.Driver.load(); - statements.addAll(add); - return this; - } - - public void testCase(int i) throws SQLException { - int old = SysProperties.getMaxQueryTimeout(); - try { - System.setProperty(SysProperties.H2_MAX_QUERY_TIMEOUT, "" + 10000); - testOne(i); - } finally { - System.setProperty(SysProperties.H2_MAX_QUERY_TIMEOUT, "" + old); - } - } - -} diff --git a/tools/h2/src/test/org/h2/test/synth/TestFuzzOptimizations.java b/tools/h2/src/test/org/h2/test/synth/TestFuzzOptimizations.java deleted file mode 100755 index 79b400b..0000000 --- a/tools/h2/src/test/org/h2/test/synth/TestFuzzOptimizations.java +++ /dev/null @@ -1,248 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.test.synth; - -import java.sql.Connection; -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; -import java.util.Random; - -import org.h2.test.TestBase; -import org.h2.test.db.Db; -import org.h2.test.db.Db.Prepared; -import org.h2.util.New; - -/** - * This test executes random SQL statements to test if optimizations are working - * correctly. - */ -public class TestFuzzOptimizations extends TestBase { - - private Connection conn; - - /** - * Run just this test. - * - * @param a ignored - */ - public static void main(String... a) throws Exception { - TestBase.createCaller().init().test(); - } - - public void test() throws Exception { - deleteDb("optimizations"); - conn = getConnection("optimizations"); - testIn(); - testGroupSorted(); - testInSelect(); - conn.close(); - deleteDb("optimizations"); - } - - /* - drop table test0; - drop table test1; - create table test0(a int, b int, c int); - create index idx_1 on test0(a); - create index idx_2 on test0(b, a); - create table test1(a int, b int, c int); - insert into test0 select x / 100, - mod(x / 10, 10), mod(x, 10) - from system_range(0, 999); - update test0 set a = null where a = 9; - update test0 set b = null where b = 9; - update test0 set c = null where c = 9; - insert into test1 select * from test0; - - select * from test0 where - b in(null, 0) and a in(2, null, null) - order by 1, 2, 3; - - select * from test1 where - b in(null, 0) and a in(2, null, null) - order by 1, 2, 3; - */ - private void testIn() throws SQLException { - Db db = new Db(conn); - db.execute("create table test0(a int, b int, c int)"); - db.execute("create index idx_1 on test0(a)"); - db.execute("create index idx_2 on test0(b, a)"); - db.execute("create table test1(a int, b int, c int)"); - db.execute("insert into test0 select x / 100, mod(x / 10, 10), mod(x, 10) from system_range(0, 999)"); - db.execute("update test0 set a = null where a = 9"); - db.execute("update test0 set b = null where b = 9"); - db.execute("update test0 set c = null where c = 9"); - db.execute("insert into test1 select * from test0"); - Random seedGenerator = new Random(); - String[] columns = new String[] { "a", "b", "c" }; - String[] values = new String[] { null, "0", "0", "1", "2", "10", "a", "?" }; - String[] compares = new String[] { "in(", "not in(", "=", "=", ">", "<", ">=", "<=", "<>", "in(select", "not in(select" }; - int size = getSize(100, 1000); - for (int i = 0; i < size; i++) { - long seed = seedGenerator.nextLong(); - println("seed: " + seed); - Random random = new Random(seed); - ArrayList params = New.arrayList(); - String condition = getRandomCondition(random, params, columns, compares, values); - // System.out.println(condition + " " + params); - PreparedStatement prep0 = conn.prepareStatement( - "select * from test0 where " + condition - + " order by 1, 2, 3"); - PreparedStatement prep1 = conn.prepareStatement( - "select * from test1 where " + condition - + " order by 1, 2, 3"); - for (int j = 0; j < params.size(); j++) { - prep0.setString(j + 1, params.get(j)); - prep1.setString(j + 1, params.get(j)); - } - ResultSet rs0 = prep0.executeQuery(); - ResultSet rs1 = prep1.executeQuery(); - assertEquals("seed: " + seed + " " + condition, rs0, rs1); - if (params.size() > 0) { - for (int j = 0; j < params.size(); j++) { - String value = values[random.nextInt(values.length - 2)]; - params.set(j, value); - prep0.setString(j + 1, value); - prep1.setString(j + 1, value); - } - assertEquals("seed: " + seed + " " + condition, rs0, rs1); - } - } - db.execute("drop table test0, test1"); - } - - private String getRandomCondition(Random random, ArrayList params, - String[] columns, String[] compares, String[] values) { - int comp = 1 + random.nextInt(4); - StringBuilder buff = new StringBuilder(); - for (int j = 0; j < comp; j++) { - if (j > 0) { - buff.append(random.nextBoolean() ? " and " : " or "); - } - String column = columns[random.nextInt(columns.length)]; - String compare = compares[random.nextInt(compares.length)]; - buff.append(column).append(' ').append(compare); - if (compare.endsWith("in(")) { - int len = 1+random.nextInt(3); - for (int k = 0; k < len; k++) { - if (k > 0) { - buff.append(", "); - } - String value = values[random.nextInt(values.length)]; - buff.append(value); - if ("?".equals(value)) { - value = values[random.nextInt(values.length - 2)]; - params.add(value); - } - } - buff.append(")"); - } else if (compare.endsWith("(select")) { - String col = columns[random.nextInt(columns.length)]; - buff.append(" ").append(col).append(" from test1 where "); - String condition = getRandomCondition(random, params, columns, compares, values); - buff.append(condition); - buff.append(")"); - } else { - String value = values[random.nextInt(values.length)]; - buff.append(value); - if ("?".equals(value)) { - value = values[random.nextInt(values.length - 2)]; - params.add(value); - } - } - } - return buff.toString(); - } - - private void testInSelect() { - Db db = new Db(conn); - db.execute("CREATE TABLE TEST(A INT, B INT)"); - db.execute("CREATE INDEX IDX ON TEST(A)"); - db.execute("INSERT INTO TEST SELECT X/4, MOD(X, 4) FROM SYSTEM_RANGE(1, 16)"); - db.execute("UPDATE TEST SET A = NULL WHERE A = 0"); - db.execute("UPDATE TEST SET B = NULL WHERE B = 0"); - Random random = new Random(); - long seed = random.nextLong(); - println("seed: " + seed); - for (int i = 0; i < 100; i++) { - String column = random.nextBoolean() ? "A" : "B"; - String value = new String[] { "NULL", "0", "A", "B" }[random.nextInt(4)]; - String compare = random.nextBoolean() ? "A" : "B"; - int x = random.nextInt(3); - String sql1 = "SELECT * FROM TEST T WHERE " + column + "+0 " + - "IN(SELECT " + value + " FROM TEST I WHERE I." + compare + "=?) ORDER BY 1, 2"; - String sql2 = "SELECT * FROM TEST T WHERE " + column + " " + - "IN(SELECT " + value + " FROM TEST I WHERE I." + compare + "=?) ORDER BY 1, 2"; - List> a = db.prepare(sql1).set(x).query(); - List> b = db.prepare(sql2).set(x).query(); - assertTrue("seed: " + seed, a.equals(b)); - } - db.execute("DROP TABLE TEST"); - } - - private void testGroupSorted() { - Db db = new Db(conn); - db.execute("CREATE TABLE TEST(A INT, B INT, C INT)"); - Random random = new Random(); - long seed = random.nextLong(); - println("seed: " + seed); - for (int i = 0; i < 100; i++) { - Prepared p = db.prepare("INSERT INTO TEST VALUES(?, ?, ?)"); - p.set(new String[] { null, "0", "1", "2" }[random.nextInt(4)]); - p.set(new String[] { null, "0", "1", "2" }[random.nextInt(4)]); - p.set(new String[] { null, "0", "1", "2" }[random.nextInt(4)]); - p.execute(); - } - int len = getSize(1000, 3000); - for (int i = 0; i < len / 10; i++) { - db.execute("CREATE TABLE TEST_INDEXED AS SELECT * FROM TEST"); - int jLen = 1 + random.nextInt(2); - for (int j = 0; j < jLen; j++) { - String x = "CREATE INDEX IDX" + j + " ON TEST_INDEXED("; - int kLen = 1 + random.nextInt(2); - for (int k = 0; k < kLen; k++) { - if (k > 0) { - x += ","; - } - x += new String[] { "A", "B", "C" }[random.nextInt(3)]; - } - db.execute(x + ")"); - } - for (int j = 0; j < 10; j++) { - String x = "SELECT "; - for (int k = 0; k < 3; k++) { - if (k > 0) { - x += ","; - } - x += new String[] { "SUM(A)", "MAX(B)", "AVG(C)", "COUNT(B)" }[random.nextInt(4)]; - x += " S" + k; - } - x += " FROM "; - String group = " GROUP BY "; - int kLen = 1 + random.nextInt(2); - for (int k = 0; k < kLen; k++) { - if (k > 0) { - group += ","; - } - group += new String[] { "A", "B", "C" }[random.nextInt(3)]; - } - group += " ORDER BY 1, 2, 3"; - List> a = db.query(x + "TEST" + group); - List> b = db.query(x + "TEST_INDEXED" + group); - assertEquals(a.toString(), b.toString()); - assertTrue(a.equals(b)); - } - db.execute("DROP TABLE TEST_INDEXED"); - } - db.execute("DROP TABLE TEST"); - } - -} diff --git a/tools/h2/src/test/org/h2/test/synth/TestHalt.java b/tools/h2/src/test/org/h2/test/synth/TestHalt.java deleted file mode 100755 index 13d0e16..0000000 --- a/tools/h2/src/test/org/h2/test/synth/TestHalt.java +++ /dev/null @@ -1,351 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.test.synth; - -import java.io.File; -import java.io.FileWriter; -import java.io.IOException; -import java.io.InputStream; -import java.io.PrintWriter; -import java.sql.Connection; -import java.sql.DriverManager; -import java.sql.SQLException; -import java.text.SimpleDateFormat; -import java.util.Date; -import java.util.Random; - -import org.h2.test.TestAll; -import org.h2.test.TestBase; -import org.h2.test.utils.SelfDestructor; -import org.h2.tools.Backup; -import org.h2.tools.DeleteDbFiles; -import org.h2.util.IOUtils; -import org.h2.util.StringUtils; - -/** - * Tests database recovery by destroying a process that writes to the database. - */ -public abstract class TestHalt extends TestBase { - - /** - * This bit flag means insert operations should be performed. - */ - protected static final int OP_INSERT = 1; - - /** - * This bit flag means delete operations should be performed. - */ - protected static final int OP_DELETE = 2; - - /** - * This bit flag means update operations should be performed. - */ - protected static final int OP_UPDATE = 4; - - /** - * This bit flag means select operations should be performed. - */ - protected static final int OP_SELECT = 8; - - /** - * This bit flag means operations should be written to the transaction log - * immediately. - */ - protected static final int FLAG_NO_DELAY = 1; - - /** - * This bit flag means the test should use LOB values. - */ - protected static final int FLAG_LOBS = 2; - - private static final String DATABASE_NAME = "halt"; - private static final String TRACE_FILE_NAME = "haltTrace.trace.db"; - - /** - * The current operations bit mask. - */ - protected int operations; - - /** - * The current flags bit mask. - */ - protected int flags; - - /** - * The current test value, for example the number of rows. - */ - protected int value; - - /** - * The database connection. - */ - protected Connection conn; - - /** - * The pseudo random number generator used for this test. - */ - protected Random random = new Random(); - - private SimpleDateFormat dateFormat = new SimpleDateFormat("MM-dd HH:mm:ss "); - private int errorId; - private int sequenceId; - - /** - * Initialize the test. - */ - abstract void controllerInit() throws SQLException; - - /** - * Check if the database is consistent after a simulated database crash. - */ - abstract void controllerCheckAfterCrash() throws SQLException; - - /** - * Wait for some time after the application has been started. - */ - abstract void controllerWaitAfterAppStart() throws Exception; - - /** - * Start the application. - */ - abstract void processAppStart() throws SQLException; - - /** - * Run the application. - */ - abstract void processAppRun() throws SQLException; - - public void test() { - for (int i = 0;; i++) { - operations = OP_INSERT | i; - flags = i >> 4; - // flags |= FLAG_NO_DELAY; // | FLAG_LOBS; - try { - controllerTest(); - } catch (Throwable t) { - System.out.println("Error: " + t); - t.printStackTrace(); - } - } - } - - Connection getConnection() throws SQLException { - org.h2.Driver.load(); - String url = "jdbc:h2:" + getBaseDir() + "/halt"; - // String url = "jdbc:h2:" + baseDir + "/halt;TRACE_LEVEL_FILE=3"; - return DriverManager.getConnection(url, "sa", "sa"); - } - - /** - * The second process starts the application and executes random operations. - */ - void processRunRandom() throws SQLException { - connect(); - try { - traceOperation("connected, operations:" + operations + " flags:" + flags + " value:" + value); - processAppStart(); - System.out.println("READY"); - System.out.println("READY"); - System.out.println("READY"); - processAppRun(); - traceOperation("done"); - } catch (Exception e) { - traceOperation("run", e); - } - disconnect(); - } - - private void connect() throws SQLException { - try { - traceOperation("connecting"); - conn = getConnection(); - } catch (SQLException e) { - traceOperation("connect", e); - e.printStackTrace(); - throw e; - } - } - - /** - * Print a trace message to the trace file. - * - * @param s the message - */ - protected void traceOperation(String s) { - traceOperation(s, null); - } - - /** - * Print a trace message to the trace file. - * - * @param s the message - * @param e the exception or null - */ - protected void traceOperation(String s, Exception e) { - FileWriter writer = null; - try { - File f = new File(getBaseDir() + "/" + TRACE_FILE_NAME); - f.getParentFile().mkdirs(); - writer = new FileWriter(f, true); - PrintWriter w = new PrintWriter(writer); - s = dateFormat.format(new Date()) + ": " + s; - w.println(s); - if (e != null) { - e.printStackTrace(w); - } - } catch (IOException e2) { - e2.printStackTrace(); - } finally { - IOUtils.closeSilently(writer); - } - } - - /** - * Run one test. The controller starts the process, waits, kills the - * process, and checks if everything is ok. - */ - void controllerTest() throws Exception { - traceOperation("delete database -----------------------------"); - DeleteDbFiles.execute(getBaseDir(), DATABASE_NAME, true); - new File(getBaseDir() + "/" + TRACE_FILE_NAME).delete(); - - connect(); - controllerInit(); - disconnect(); - for (int i = 0; i < 10; i++) { - traceOperation("backing up " + sequenceId); - Backup.execute(getBaseDir() + "/haltSeq" + sequenceId + ".zip", getBaseDir(), null, true); - sequenceId++; - // int operations = OP_INSERT; - // OP_DELETE = 1, OP_UPDATE = 2, OP_SELECT = 4; - // int flags = FLAG_NODELAY; - // FLAG_NO_DELAY = 1, FLAG_AUTO_COMMIT = 2, FLAG_SMALL_CACHE = 4; - int testValue = random.nextInt(1000); - // for Derby and HSQLDB - // String classPath = "-cp - // .;D:/data/java/hsqldb.jar;D:/data/java/derby.jar"; - String selfDestruct = SelfDestructor.getPropertyString(60); - String[] procDef = { "java", selfDestruct, - "-cp", getClassPath(), - getClass().getName(), "" + operations, "" + flags, "" + testValue}; - traceOperation("start: " + StringUtils.arrayCombine(procDef, ' ')); - Process p = Runtime.getRuntime().exec(procDef); - InputStream in = p.getInputStream(); - OutputCatcher catcher = new OutputCatcher(in); - catcher.start(); - String s = catcher.readLine(5 * 60 * 1000); - if (s == null) { - throw new IOException("No reply from process, command: " + StringUtils.arrayCombine(procDef, ' ')); - } else if (s.startsWith("READY")) { - traceOperation("got reply: " + s); - } - controllerWaitAfterAppStart(); - p.destroy(); - p.waitFor(); - try { - traceOperation("backing up " + sequenceId); - Backup.execute(getBaseDir() + "/haltSeq" + sequenceId + ".zip", getBaseDir(), null, true); - // new File(BASE_DIR + "/haltSeq" + (sequenceId-20) + - // ".zip").delete(); - connect(); - controllerCheckAfterCrash(); - } catch (Exception e) { - File zip = new File(getBaseDir() + "/haltSeq" + sequenceId + ".zip"); - File zipId = new File(getBaseDir() + "/haltSeq" + sequenceId + "-" + errorId + ".zip"); - zip.renameTo(zipId); - printTime("ERROR: " + sequenceId + " " + errorId + " " + e.toString()); - e.printStackTrace(); - errorId++; - } finally { - sequenceId++; - disconnect(); - } - } - } - - /** - * Close the database connection normally. - */ - protected void disconnect() { - try { - traceOperation("disconnect"); - conn.close(); - } catch (Exception e) { - traceOperation("disconnect", e); - } - } - -// public Connection getConnectionHSQLDB() throws SQLException { -// File lock = new File("test.lck"); -// while (lock.exists()) { -// lock.delete(); -// System.gc(); -// } -// Class.forName("org.hsqldb.jdbcDriver"); -// return DriverManager.getConnection("jdbc:hsqldb:test", "sa", ""); -// } - -// public Connection getConnectionDerby() throws SQLException { -// File lock = new File("test3/db.lck"); -// while (lock.exists()) { -// lock.delete(); -// System.gc(); -// } -// Class.forName("org.apache.derby.jdbc.EmbeddedDriver").newInstance(); -// try { -// return DriverManager.getConnection( -// "jdbc:derby:test3;create=true", "sa", "sa"); -// } catch (SQLException e) { -// Exception e2 = e; -// do { -// e.printStackTrace(); -// e = e.getNextException(); -// } while (e != null); -// throw e2; -// } -// } - -// void disconnectHSQLDB() { -// try { -// conn.createStatement().execute("SHUTDOWN"); -// } catch (Exception e) { -// // ignore -// } -// // super.disconnect(); -// } - -// void disconnectDerby() { -// // super.disconnect(); -// try { -// Class.forName("org.apache.derby.jdbc.EmbeddedDriver"); -// DriverManager.getConnection( -// "jdbc:derby:;shutdown=true", "sa", "sa"); -// } catch (Exception e) { -// // ignore -// } -// } - - /** - * Create a random string with the specified length. - * - * @param len the number of characters - * @return the random string - */ - protected String getRandomString(int len) { - StringBuilder buff = new StringBuilder(); - for (int i = 0; i < len; i++) { - buff.append('a' + random.nextInt(20)); - } - return buff.toString(); - } - - public TestBase init(TestAll conf) throws Exception { - super.init(conf); - return this; - } - -} diff --git a/tools/h2/src/test/org/h2/test/synth/TestHaltApp.java b/tools/h2/src/test/org/h2/test/synth/TestHaltApp.java deleted file mode 100755 index 7f36d11..0000000 --- a/tools/h2/src/test/org/h2/test/synth/TestHaltApp.java +++ /dev/null @@ -1,172 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.test.synth; - -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.sql.Statement; - -import org.h2.test.utils.SelfDestructor; - -/** - * The application code for the {@link TestHalt} application. - */ -public class TestHaltApp extends TestHalt { - - private int rowCount; - - /** - * This method is called when executing this application from the command - * line. - * - * @param args the command line parameters - */ - public static void main(String... args) throws Exception { - SelfDestructor.startCountdown(60); - TestHaltApp app = new TestHaltApp(); - if (args.length == 0) { - app.controllerTest(); - } else { - app.operations = Integer.parseInt(args[0]); - app.flags = Integer.parseInt(args[1]); - app.value = Integer.parseInt(args[2]); - app.processRunRandom(); - } - } - - private void execute(Statement stat, String sql) throws SQLException { - traceOperation("execute: " + sql); - stat.execute(sql); - } - - /** - * Initialize the database. - */ - protected void controllerInit() throws SQLException { - Statement stat = conn.createStatement(); - // stat.execute("CREATE TABLE TEST(ID IDENTITY, NAME VARCHAR(255))"); - for (int i = 0; i < 20; i++) { - execute(stat, "DROP TABLE IF EXISTS TEST" + i); - execute(stat, "CREATE TABLE TEST" + i + "(ID INT PRIMARY KEY, NAME VARCHAR(255))"); - } - for (int i = 0; i < 20; i += 2) { - execute(stat, "DROP TABLE TEST" + i); - } - execute(stat, "DROP TABLE IF EXISTS TEST"); - execute(stat, "CREATE TABLE TEST(ID BIGINT GENERATED BY DEFAULT AS IDENTITY, NAME VARCHAR(255), DATA CLOB)"); - } - - /** - * Wait after the application has been started. - */ - protected void controllerWaitAfterAppStart() throws Exception { - int sleep = 10 + random.nextInt(300); - if ((flags & FLAG_NO_DELAY) == 0) { - sleep += 1000; - } - Thread.sleep(sleep); - } - - /** - * This method is called after a simulated crash. The method should check if - * the data is transactionally consistent and throw an exception if not. - * - * @throws SQLException if the data is not consistent. - */ - protected void controllerCheckAfterCrash() throws SQLException { - Statement stat = conn.createStatement(); - ResultSet rs = stat.executeQuery("SELECT COUNT(*) FROM TEST"); - rs.next(); - int count = rs.getInt(1); - System.out.println("count: " + count); - if (count % 2 != 0) { - traceOperation("row count: " + count); - throw new SQLException("Unexpected odd row count: " + count); - } - } - - /** - * Initialize the application. - */ - protected void processAppStart() throws SQLException { - Statement stat = conn.createStatement(); - if ((flags & FLAG_NO_DELAY) != 0) { - execute(stat, "SET WRITE_DELAY 0"); - execute(stat, "SET MAX_LOG_SIZE 1"); - } - ResultSet rs = stat.executeQuery("SELECT COUNT(*) FROM TEST"); - rs.next(); - rowCount = rs.getInt(1); - traceOperation("rows: " + rowCount, null); - } - - /** - * Run the application code. - */ - protected void processAppRun() throws SQLException { - conn.setAutoCommit(false); - traceOperation("setAutoCommit false"); - int rows = 10000 + value; - PreparedStatement prepInsert = conn.prepareStatement("INSERT INTO TEST(NAME, DATA) VALUES('Hello World', ?)"); - PreparedStatement prepUpdate = conn - .prepareStatement("UPDATE TEST SET NAME = 'Hallo Welt', DATA = ? WHERE ID = ?"); - for (int i = 0; i < rows; i++) { - Statement stat = conn.createStatement(); - if ((operations & OP_INSERT) != 0) { - if ((flags & FLAG_LOBS) != 0) { - String s = getRandomString(random.nextInt(200)); - prepInsert.setString(1, s); - traceOperation("insert " + s); - prepInsert.execute(); - } else { - execute(stat, "INSERT INTO TEST(NAME) VALUES('Hello World')"); - } - ResultSet rs = stat.getGeneratedKeys(); - rs.next(); - int key = rs.getInt(1); - traceOperation("inserted key: " + key); - rowCount++; - } - if ((operations & OP_UPDATE) != 0) { - if ((flags & FLAG_LOBS) != 0) { - String s = getRandomString(random.nextInt(200)); - prepUpdate.setString(1, s); - int x = random.nextInt(rowCount + 1); - prepUpdate.setInt(2, x); - traceOperation("update " + s + " " + x); - prepUpdate.execute(); - } else { - int x = random.nextInt(rowCount + 1); - execute(stat, "UPDATE TEST SET VALUE = 'Hallo Welt' WHERE ID = " + x); - } - } - if ((operations & OP_DELETE) != 0) { - int x = random.nextInt(rowCount + 1); - traceOperation("deleting " + x); - int uc = stat.executeUpdate("DELETE FROM TEST WHERE ID = " + x); - traceOperation("updated: " + uc); - rowCount -= uc; - } - traceOperation("rowCount " + rowCount); - traceOperation("rows now: " + rowCount, null); - if (rowCount % 2 == 0) { - traceOperation("commit " + rowCount); - conn.commit(); - traceOperation("committed: " + rowCount, null); - } - if ((flags & FLAG_NO_DELAY) != 0) { - if (random.nextInt(10) == 0 && (rowCount % 2 == 0)) { - execute(stat, "CHECKPOINT"); - } - } - } - traceOperation("rollback"); - conn.rollback(); - } - -} diff --git a/tools/h2/src/test/org/h2/test/synth/TestJoin.java b/tools/h2/src/test/org/h2/test/synth/TestJoin.java deleted file mode 100755 index 4855983..0000000 --- a/tools/h2/src/test/org/h2/test/synth/TestJoin.java +++ /dev/null @@ -1,308 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.test.synth; - -import java.sql.Connection; -import java.sql.DriverManager; -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.ResultSetMetaData; -import java.sql.SQLException; -import java.sql.Statement; -import java.util.ArrayList; -import java.util.Collections; -import java.util.Random; - -import org.h2.test.TestBase; -import org.h2.util.New; -import org.h2.util.StringUtils; - -/** - * A test that runs random join statements against two databases and compares - * the results. - */ -public class TestJoin extends TestBase { - - private ArrayList connections = New.arrayList(); - private Random random; - private int paramCount; - private StringBuilder buff; - - /** - * Run just this test. - * - * @param a ignored - */ - public static void main(String... a) throws Exception { - TestBase.createCaller().init().test(); - } - - public void test() throws Exception { - testJoin(); - } - - private void testJoin() throws Exception { - deleteDb("join"); - String shortestFailed = null; - - Connection c1 = getConnection("join"); - connections.add(c1); - - Class.forName("org.postgresql.Driver"); - Connection c2 = DriverManager.getConnection("jdbc:postgresql:test", "sa", "sa"); - connections.add(c2); - - // Class.forName("com.mysql.jdbc.Driver"); - // Connection c2 = - // DriverManager.getConnection("jdbc:mysql://localhost/test", "sa", - // "sa"); - // connections.add(c2); - - // Class.forName("org.hsqldb.jdbcDriver"); - // Connection c2 = DriverManager.getConnection("jdbc:hsqldb:join", "sa", - // ""); - // connections.add(c2); - - /* - DROP TABLE ONE; - DROP TABLE TWO; - CREATE TABLE ONE(A INT PRIMARY KEY, B INT); - INSERT INTO ONE VALUES(0, NULL); - INSERT INTO ONE VALUES(1, 0); - INSERT INTO ONE VALUES(2, 1); - INSERT INTO ONE VALUES(3, 4); - CREATE TABLE TWO(A INT PRIMARY KEY, B INT); - INSERT INTO TWO VALUES(0, NULL); - INSERT INTO TWO VALUES(1, 0); - INSERT INTO TWO VALUES(2, 2); - INSERT INTO TWO VALUES(3, 3); - INSERT INTO TWO VALUES(4, NULL); - */ - - execute("DROP TABLE ONE", null, true); - execute("DROP TABLE TWO", null, true); - execute("CREATE TABLE ONE(A INT PRIMARY KEY, B INT)", null); - execute("INSERT INTO ONE VALUES(0, NULL)", null); - execute("INSERT INTO ONE VALUES(1, 0)", null); - execute("INSERT INTO ONE VALUES(2, 1)", null); - execute("INSERT INTO ONE VALUES(3, 4)", null); - execute("CREATE TABLE TWO(A INT PRIMARY KEY, B INT)", null); - execute("INSERT INTO TWO VALUES(0, NULL)", null); - execute("INSERT INTO TWO VALUES(1, 0)", null); - execute("INSERT INTO TWO VALUES(2, 2)", null); - execute("INSERT INTO TWO VALUES(3, 3)", null); - execute("INSERT INTO TWO VALUES(4, NULL)", null); - random = new Random(); - long startTime = System.currentTimeMillis(); - for (int i = 0;; i++) { - paramCount = 0; - buff = new StringBuilder(); - long time = System.currentTimeMillis(); - if (time - startTime > 5000) { - printTime("i:" + i); - startTime = time; - } - buff.append("SELECT "); - int tables = 1 + random.nextInt(5); - for (int j = 0; j < tables; j++) { - if (j > 0) { - buff.append(", "); - } - buff.append("T" + (char) ('0' + j) + ".A"); - } - buff.append(" FROM "); - appendRandomTable(); - buff.append(" T0 "); - for (int j = 1; j < tables; j++) { - if (random.nextBoolean()) { - buff.append("INNER"); - } else { - // if(random.nextInt(4)==1) { - // buff.append("RIGHT"); - // } else { - buff.append("LEFT"); - // } - } - buff.append(" JOIN "); - appendRandomTable(); - buff.append(" T"); - buff.append((char) ('0' + j)); - buff.append(" ON "); - appendRandomCondition(j); - } - if (random.nextBoolean()) { - buff.append("WHERE "); - appendRandomCondition(tables - 1); - } - String sql = buff.toString(); - Object[] params = new Object[paramCount]; - for (int j = 0; j < paramCount; j++) { - params[j] = random.nextInt(4) == 1 ? null : new Integer(random.nextInt(10) - 3); - } - try { - execute(sql, params); - } catch (Exception e) { - if (shortestFailed == null || shortestFailed.length() > sql.length()) { - TestBase.logError("/*SHORT*/ " + sql, null); - shortestFailed = sql; - } - } - } - // c1.close(); - // c2.close(); - } - - private void appendRandomTable() { - if (random.nextBoolean()) { - buff.append("ONE"); - } else { - buff.append("TWO"); - } - } - - private void appendRandomCondition(int j) { - if (random.nextInt(10) == 1) { - buff.append("NOT "); - appendRandomCondition(j); - } else if (random.nextInt(5) == 1) { - buff.append("("); - appendRandomCondition(j); - if (random.nextBoolean()) { - buff.append(") OR ("); - } else { - buff.append(") AND ("); - } - appendRandomCondition(j); - buff.append(")"); - } else { - if (j > 0 && random.nextBoolean()) { - buff.append("T" + (char) ('0' + j - 1) + ".A=T" + (char) ('0' + j) + ".A "); - } else { - appendRandomConditionPart(j); - } - } - } - - private void appendRandomConditionPart(int j) { - int t1 = j <= 1 ? 0 : random.nextInt(j + 1); - int t2 = j <= 1 ? 0 : random.nextInt(j + 1); - String c1 = random.nextBoolean() ? "A" : "B"; - String c2 = random.nextBoolean() ? "A" : "B"; - buff.append("T" + (char) ('0' + t1)); - buff.append("." + c1); - if (random.nextInt(4) == 1) { - if (random.nextInt(5) == 1) { - buff.append(" IS NOT NULL"); - } else { - buff.append(" IS NULL"); - } - } else { - if (random.nextInt(5) == 1) { - switch (random.nextInt(5)) { - case 0: - buff.append(">"); - break; - case 1: - buff.append("<"); - break; - case 2: - buff.append("<="); - break; - case 3: - buff.append(">="); - break; - case 4: - buff.append("<>"); - break; - default: - } - } else { - buff.append("="); - } - if (random.nextBoolean()) { - buff.append("T" + (char) ('0' + t2)); - buff.append("." + c2); - } else { - buff.append(random.nextInt(5) - 1); - } - } - buff.append(" "); - } - - private void execute(String sql, Object[] params) { - execute(sql, params, false); - } - - private void execute(String sql, Object[] params, boolean ignoreDifference) { - String first = null; - for (int i = 0; i < connections.size(); i++) { - Connection conn = connections.get(i); - String s; - try { - Statement stat; - boolean result; - if (params == null || params.length == 0) { - stat = conn.createStatement(); - result = stat.execute(sql); - } else { - PreparedStatement prep = conn.prepareStatement(sql); - stat = prep; - for (int j = 0; j < params.length; j++) { - prep.setObject(j + 1, params[j]); - } - result = prep.execute(); - } - if (result) { - ResultSet rs = stat.getResultSet(); - s = "rs: " + readResult(rs); - } else { - s = "updateCount: " + stat.getUpdateCount(); - } - } catch (SQLException e) { - s = "exception"; - } - if (i == 0) { - first = s; - } else { - if (!ignoreDifference && !s.equals(first)) { - fail("FAIL s:" + s + " first:" + first + " sql:" + sql); - } - } - } - } - - private String readResult(ResultSet rs) throws SQLException { - StringBuilder b = new StringBuilder(); - ResultSetMetaData meta = rs.getMetaData(); - int columnCount = meta.getColumnCount(); - for (int i = 0; i < columnCount; i++) { - if (i > 0) { - b.append(","); - } - b.append(StringUtils.toUpperEnglish(meta.getColumnLabel(i + 1))); - } - b.append(":\n"); - String result = b.toString(); - ArrayList list = New.arrayList(); - while (rs.next()) { - b = new StringBuilder(); - for (int i = 0; i < columnCount; i++) { - if (i > 0) { - b.append(","); - } - b.append(rs.getString(i + 1)); - } - list.add(b.toString()); - } - Collections.sort(list); - for (int i = 0; i < list.size(); i++) { - result += list.get(i) + "\n"; - } - return result; - } - -} diff --git a/tools/h2/src/test/org/h2/test/synth/TestKill.java b/tools/h2/src/test/org/h2/test/synth/TestKill.java deleted file mode 100755 index 73208fd..0000000 --- a/tools/h2/src/test/org/h2/test/synth/TestKill.java +++ /dev/null @@ -1,153 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.test.synth; - -import java.sql.Connection; -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.sql.Statement; -import java.util.Random; - -import org.h2.test.TestBase; -import org.h2.test.utils.SelfDestructor; - -/** - * A random recovery test. This test starts a process that executes random - * operations against a database, then kills this process. Afterwards recovery - * is tested. - */ -public class TestKill extends TestBase { - - private static final String DIR = TestBase.getTestDir("kill"); - - private Connection conn; - private int accounts = 10; - private Random random = new Random(1); - - /** - * Run just this test. - * - * @param a ignored - */ - public static void main(String... a) throws Exception { - TestBase.createCaller().init().test(); - } - - public void test() throws Exception { - String connect = ""; - - connect = ";MAX_LOG_SIZE=10;THROTTLE=80"; - - String url = getURL(DIR + "/kill" + connect, true); - String user = getUser(); - String password = getPassword(); - String selfDestruct = SelfDestructor.getPropertyString(60); - String[] procDef = { - "java", selfDestruct, - "-cp", getClassPath(), - "org.h2.test.synth.TestKillProcess", url, user, - password, getBaseDir(), "" + accounts }; - - for (int i = 0;; i++) { - printTime("TestKill " + i); - if (i % 10 == 0) { - trace("deleting db..."); - deleteDb("kill"); - } - conn = getConnection(url); - createTables(); - checkData(); - initData(); - conn.close(); - Process proc = Runtime.getRuntime().exec(procDef); - // while(true) { - // int ch = proc.getErrorStream().read(); - // if(ch < 0) { - // break; - // } - // System.out.print((char)ch); - // } - int runtime = random.nextInt(10000); - trace("running..."); - Thread.sleep(runtime); - trace("stopping..."); - proc.destroy(); - proc.waitFor(); - trace("stopped"); - } - } - - private void createTables() throws SQLException { - trace("createTables..."); - Statement stat = conn.createStatement(); - stat.execute("CREATE TABLE IF NOT EXISTS ACCOUNT(ID INT PRIMARY KEY, SUM INT)"); - stat - .execute("CREATE TABLE IF NOT EXISTS LOG(ID IDENTITY, ACCOUNTID INT, AMOUNT INT, FOREIGN KEY(ACCOUNTID) REFERENCES ACCOUNT(ID))"); - stat.execute("CREATE TABLE IF NOT EXISTS TEST_A(ID INT PRIMARY KEY, DATA VARCHAR)"); - stat.execute("CREATE TABLE IF NOT EXISTS TEST_B(ID INT PRIMARY KEY, DATA VARCHAR)"); - } - - private void initData() throws SQLException { - trace("initData..."); - conn.createStatement().execute("DROP TABLE LOG"); - conn.createStatement().execute("DROP TABLE ACCOUNT"); - conn.createStatement().execute("DROP TABLE TEST_A"); - conn.createStatement().execute("DROP TABLE TEST_B"); - createTables(); - PreparedStatement prep = conn.prepareStatement("INSERT INTO ACCOUNT VALUES(?, 0)"); - for (int i = 0; i < accounts; i++) { - prep.setInt(1, i); - prep.execute(); - } - PreparedStatement p1 = conn.prepareStatement("INSERT INTO TEST_A VALUES(?, '')"); - PreparedStatement p2 = conn.prepareStatement("INSERT INTO TEST_B VALUES(?, '')"); - for (int i = 0; i < accounts; i++) { - p1.setInt(1, i); - p2.setInt(1, i); - p1.execute(); - p2.execute(); - } - } - - private void checkData() throws SQLException { - trace("checkData..."); - ResultSet rs = conn.createStatement().executeQuery("SELECT * FROM ACCOUNT ORDER BY ID"); - PreparedStatement prep = conn.prepareStatement("SELECT SUM(AMOUNT) FROM LOG WHERE ACCOUNTID=?"); - while (rs.next()) { - int account = rs.getInt(1); - int sum = rs.getInt(2); - prep.setInt(1, account); - ResultSet rs2 = prep.executeQuery(); - rs2.next(); - int sumLog = rs2.getInt(1); - assertEquals(sum, sumLog); - trace("account=" + account + " sum=" + sum); - } - PreparedStatement p1 = conn.prepareStatement("SELECT * FROM TEST_A WHERE ID=?"); - PreparedStatement p2 = conn.prepareStatement("SELECT * FROM TEST_B WHERE ID=?"); - for (int i = 0; i < accounts; i++) { - p1.setInt(1, i); - p2.setInt(1, i); - ResultSet r1 = p1.executeQuery(); - ResultSet r2 = p2.executeQuery(); - boolean hasData = r1.next(); - assertEquals(r2.next(), hasData); - if (hasData) { - String d1 = r1.getString("DATA"); - String d2 = r2.getString("DATA"); - assertEquals(d1, d2); - assertFalse(r1.next()); - assertFalse(r2.next()); - trace("test: data=" + d1); - } else { - trace("test: empty"); - } - } - } - -} diff --git a/tools/h2/src/test/org/h2/test/synth/TestKillProcess.java b/tools/h2/src/test/org/h2/test/synth/TestKillProcess.java deleted file mode 100755 index a5ab153..0000000 --- a/tools/h2/src/test/org/h2/test/synth/TestKillProcess.java +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.test.synth; - -import java.sql.Connection; -import java.sql.DriverManager; -import java.sql.PreparedStatement; -import java.util.ArrayList; -import java.util.Random; -import org.h2.store.FileLister; -import org.h2.test.TestBase; -import org.h2.test.utils.SelfDestructor; - -/** - * Test application for TestKill. - */ -public class TestKillProcess { - - private TestKillProcess() { - // utility class - } - - /** - * This method is called when executing this application. - * - * @param args the command line parameters - */ - public static void main(String... args) { - SelfDestructor.startCountdown(60); - try { - Class.forName("org.h2.Driver"); - String url = args[0], user = args[1], password = args[2]; - String baseDir = args[3]; - int accounts = Integer.parseInt(args[4]); - - Random random = new Random(); - Connection conn1 = DriverManager.getConnection(url, user, password); - - PreparedStatement prep1a = conn1.prepareStatement("INSERT INTO LOG(ACCOUNTID, AMOUNT) VALUES(?, ?)"); - PreparedStatement prep1b = conn1.prepareStatement("UPDATE ACCOUNT SET SUM=SUM+? WHERE ID=?"); - conn1.setAutoCommit(false); - long time = System.currentTimeMillis(); - String d = null; - for (int i = 0;; i++) { - long t = System.currentTimeMillis(); - if (t > time + 1000) { - ArrayList list = FileLister.getDatabaseFiles(baseDir, "kill", true); - System.out.println("inserting... i:" + i + " d:" + d + " files:" + list.size()); - time = t; - } - if (i > 10000) { - // System.out.println("halt"); - // Runtime.getRuntime().halt(0); - // conn.createStatement().execute("SHUTDOWN IMMEDIATELY"); - // System.exit(0); - } - int account = random.nextInt(accounts); - int value = random.nextInt(100); - prep1a.setInt(1, account); - prep1a.setInt(2, value); - prep1a.execute(); - prep1b.setInt(1, value); - prep1b.setInt(2, account); - prep1b.execute(); - conn1.commit(); - if (random.nextInt(100) < 2) { - d = "D" + random.nextInt(1000); - account = random.nextInt(accounts); - conn1.createStatement().execute("UPDATE TEST_A SET DATA='" + d + "' WHERE ID=" + account); - conn1.createStatement().execute("UPDATE TEST_B SET DATA='" + d + "' WHERE ID=" + account); - } - } - } catch (Throwable e) { - TestBase.logError("error", e); - } - } - -} diff --git a/tools/h2/src/test/org/h2/test/synth/TestKillRestart.java b/tools/h2/src/test/org/h2/test/synth/TestKillRestart.java deleted file mode 100755 index 811190b..0000000 --- a/tools/h2/src/test/org/h2/test/synth/TestKillRestart.java +++ /dev/null @@ -1,163 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.test.synth; - -import java.io.InputStream; -import java.sql.Connection; -import java.sql.DriverManager; -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.Statement; -import java.util.Random; -import org.h2.test.TestBase; -import org.h2.test.utils.SelfDestructor; - -/** - * Standalone recovery test. A new process is started and then killed while it - * executes random statements. - */ -public class TestKillRestart extends TestBase { - - public void test() throws Exception { - if (config.networked) { - return; - } - if (getBaseDir().indexOf(':') > 0) { - return; - } - deleteDb("killRestart"); - String url = getURL("killRestart", true); - // String url = getURL( - // "killRestart;CACHE_SIZE=2048;WRITE_DELAY=0", true); - String user = getUser(), password = getPassword(); - String selfDestruct = SelfDestructor.getPropertyString(60); - String[] procDef = { "java", selfDestruct, - "-cp", getClassPath(), - getClass().getName(), "-url", url, "-user", user, - "-password", password }; - - int len = getSize(2, 15); - for (int i = 0; i < len; i++) { - Process p = Runtime.getRuntime().exec(procDef); - InputStream in = p.getInputStream(); - OutputCatcher catcher = new OutputCatcher(in); - catcher.start(); - while (true) { - String s = catcher.readLine(60 * 1000); - // System.out.println("> " + s); - if (s == null) { - fail("No reply from process"); - } else if (!s.startsWith("#")) { - // System.out.println(s); - fail("Expected: #..., got: " + s); - } else if (s.startsWith("#Running")) { - Thread.sleep(100); - printTime("killing: " + i); - p.destroy(); - p.waitFor(); - break; - } else if (s.startsWith("#Fail")) { - fail("Failed: " + s); - } - } - } - deleteDb("killRestart"); - } - - /** - * This method is called when executing this application from the command - * line. - * - * @param args the command line parameters - */ - public static void main(String... args) { - SelfDestructor.startCountdown(60); - String driver = "org.h2.Driver"; - String url = "jdbc:h2:test", user = "sa", password = "sa"; - for (int i = 0; i < args.length; i++) { - if ("-url".equals(args[i])) { - url = args[++i]; - } else if ("-driver".equals(args[i])) { - driver = args[++i]; - } else if ("-user".equals(args[i])) { - user = args[++i]; - } else if ("-password".equals(args[i])) { - password = args[++i]; - } - } - System.out.println("#Started; driver: " + driver + " url: " + url + " user: " + user + " password: " + password); - try { - Class.forName(driver); - System.out.println("#Opening..."); - Connection conn = DriverManager.getConnection(url, user, password); - Statement stat = conn.createStatement(); - stat.execute("CREATE TABLE IF NOT EXISTS TEST(ID IDENTITY, NAME VARCHAR)"); - stat.execute("CREATE TABLE IF NOT EXISTS TEST2(ID IDENTITY, NAME VARCHAR)"); - ResultSet rs = stat.executeQuery("SELECT * FROM TEST"); - while (rs.next()) { - rs.getLong("ID"); - rs.getString("NAME"); - } - rs = stat.executeQuery("SELECT * FROM TEST2"); - while (rs.next()) { - rs.getLong("ID"); - rs.getString("NAME"); - } - stat.execute("DROP ALL OBJECTS DELETE FILES"); - System.out.println("#Closing with delete..."); - conn.close(); - System.out.println("#Starting..."); - conn = DriverManager.getConnection(url, user, password); - stat = conn.createStatement(); - stat.execute("DROP ALL OBJECTS"); - stat.execute("CREATE TABLE TEST(ID IDENTITY, NAME VARCHAR)"); - stat.execute("CREATE TABLE TEST2(ID IDENTITY, NAME VARCHAR)"); - stat.execute("CREATE TABLE TEST_META(ID INT)"); - PreparedStatement prep = conn.prepareStatement("INSERT INTO TEST(NAME) VALUES(?)"); - PreparedStatement prep2 = conn.prepareStatement("INSERT INTO TEST2(NAME) VALUES(?)"); - Random r = new Random(0); -// Runnable stopper = new Runnable() { -// public void run() { -// try { -// Thread.sleep(500); -// } catch (InterruptedException e) { -// } -// System.out.println("#Halt..."); -// Runtime.getRuntime().halt(0); -// } -// }; -// new Thread(stopper).start(); - for (int i = 0; i < 2000; i++) { - if (i == 100) { - System.out.println("#Running..."); - } - if (r.nextInt(100) < 10) { - conn.createStatement().execute("ALTER TABLE TEST_META ALTER COLUMN ID INT DEFAULT 10"); - } - if (r.nextBoolean()) { - if (r.nextBoolean()) { - prep.setString(1, new String(new char[r.nextInt(30) * 10])); - prep.execute(); - } else { - prep2.setString(1, new String(new char[r.nextInt(30) * 10])); - prep2.execute(); - } - } else { - if (r.nextBoolean()) { - conn.createStatement().execute("UPDATE TEST SET NAME = NULL"); - } else { - conn.createStatement().execute("UPDATE TEST2 SET NAME = NULL"); - } - } - } - } catch (Throwable e) { - e.printStackTrace(System.out); - System.out.println("#Fail: " + e.toString()); - } - } - -} diff --git a/tools/h2/src/test/org/h2/test/synth/TestKillRestartMulti.java b/tools/h2/src/test/org/h2/test/synth/TestKillRestartMulti.java deleted file mode 100755 index 4ee74e2..0000000 --- a/tools/h2/src/test/org/h2/test/synth/TestKillRestartMulti.java +++ /dev/null @@ -1,291 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.test.synth; - -import java.io.InputStream; -import java.sql.Connection; -import java.sql.DriverManager; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.sql.Statement; -import java.util.ArrayList; -import java.util.Random; - -import org.h2.constant.ErrorCode; -import org.h2.test.TestBase; -import org.h2.test.utils.SelfDestructor; -import org.h2.tools.Backup; -import org.h2.util.IOUtils; -import org.h2.util.New; - -/** - * Standalone recovery test. A new process is started and then killed while it - * executes random statements using multiple connection. - */ -public class TestKillRestartMulti extends TestBase { - - private String driver = "org.h2.Driver"; - private String url; - private String user = "sa"; - private String password = "sa"; - private ArrayList connections = New.arrayList(); - private ArrayList tables = New.arrayList(); - private int openCount; - - public void test() throws Exception { - if (config.networked) { - return; - } - if (getBaseDir().indexOf(':') > 0) { - return; - } - deleteDb("killRestartMulti"); - url = getURL("killRestartMulti", true); - user = getUser(); - password = getPassword(); - String selfDestruct = SelfDestructor.getPropertyString(60); - String[] procDef = { "java", selfDestruct, - "-cp", getClassPath(), - getClass().getName(), "-url", url, "-user", user, - "-password", password }; - deleteDb("killRestartMulti"); - int len = getSize(3, 10); - Random random = new Random(); - for (int i = 0; i < len; i++) { - Process p = Runtime.getRuntime().exec(procDef); - InputStream in = p.getInputStream(); - OutputCatcher catcher = new OutputCatcher(in); - catcher.start(); - while (true) { - String s = catcher.readLine(5 * 60 * 1000); - // System.out.println("> " + s); - if (s == null) { - fail("No reply from process"); - } else if (!s.startsWith("#")) { - // System.out.println(s); - fail("Expected: #..., got: " + s); - } else if (s.startsWith("#Running")) { - int sleep = 10 + random.nextInt(100); - Thread.sleep(sleep); - printTime("killing: " + i); - p.destroy(); - p.waitFor(); - break; - } else if (s.startsWith("#Info")) { - // System.out.println("info: " + s); - } else if (s.startsWith("#Fail")) { - System.err.println(s); - while (true) { - String a = catcher.readLine(5 * 60 * 1000); - if (a == null || "#End".endsWith(a)) { - break; - } - System.err.println(" " + a); - } - fail("Failed: " + s); - } - } - String backup = getBaseDir() + "/killRestartMulti-" + System.currentTimeMillis() + ".zip"; - try { - Backup.execute(backup, getBaseDir(), "killRestartMulti", true); - Connection conn = null; - for (int j = 0;; j++) { - try { - conn = openConnection(); - break; - } catch (SQLException e2) { - if (e2.getErrorCode() == ErrorCode.DATABASE_ALREADY_OPEN_1 - && j < 3) { - Thread.sleep(100); - } else { - throw e2; - } - } - } - testConsistent(conn); - Statement stat = conn.createStatement(); - stat.execute("DROP ALL OBJECTS"); - conn.close(); - conn = openConnection(); - conn.close(); - IOUtils.delete(backup); - } catch (SQLException e) { - IOUtils.rename(backup, backup + ".error"); - throw e; - } - } - deleteDb("killRestartMulti"); - } - - /** - * This method is called when executing this application from the command - * line. - * - * @param args the command line parameters - */ - public static void main(String... args) { - SelfDestructor.startCountdown(60); - new TestKillRestartMulti().test(args); - } - - private void test(String... args) { - for (int i = 0; i < args.length; i++) { - if ("-url".equals(args[i])) { - url = args[++i]; - } else if ("-driver".equals(args[i])) { - driver = args[++i]; - } else if ("-user".equals(args[i])) { - user = args[++i]; - } else if ("-password".equals(args[i])) { - password = args[++i]; - } - } - System.out.println("#Started; driver: " + driver + " url: " + url + " user: " + user + " password: " + password); - try { - System.out.println("#Starting..."); - Random random = new Random(); - boolean wasRunning = false; - for (int i = 0; i < 3000; i++) { - if (i > 1000 && connections.size() > 1 && tables.size() > 1) { - System.out.println("#Running connections: " + connections.size() + " tables: " + tables.size()); - wasRunning = true; - } - if (connections.size() < 1) { - openConnection(); - } - if (tables.size() < 1) { - createTable(random); - } - int p = random.nextInt(100); - if ((p -= 2) <= 0) { - // 2%: open new connection - if (connections.size() < 5) { - openConnection(); - } - } else if ((p -= 1) <= 0) { - // 1%: close connection - if (connections.size() > 1) { - Connection conn = connections.remove(random.nextInt(connections.size())); - if (random.nextBoolean()) { - conn.close(); - } - } - } else if ((p -= 10) <= 0) { - // 10% create table - createTable(random); - } else if ((p -= 20) <= 0) { - // 20% large insert, delete, or update - if (tables.size() > 0) { - Connection conn = connections.get(random.nextInt(connections.size())); - Statement stat = conn.createStatement(); - String table = tables.get(random.nextInt(tables.size())); - if (random.nextBoolean()) { - // 10% insert - stat.execute("INSERT INTO " + table + "(NAME) SELECT 'Hello ' || X FROM SYSTEM_RANGE(0, 20)"); - } else if (random.nextBoolean()) { - // 5% update - stat.execute("UPDATE " + table + " SET NAME='Hallo Welt'"); - } else { - // 5% delete - stat.execute("DELETE FROM " + table); - } - } - } else if ((p -= 5) < 0) { - // 5% truncate or drop table - if (tables.size() > 0) { - Connection conn = connections.get(random.nextInt(connections.size())); - Statement stat = conn.createStatement(); - String table = tables.get(random.nextInt(tables.size())); - if (random.nextBoolean()) { - stat.execute("TRUNCATE TABLE " + table); - } else { - stat.execute("DROP TABLE " + table); - System.out.println("#Info table dropped: " + table); - tables.remove(table); - } - } - } else if ((p -= 30) <= 0) { - // 30% insert - if (tables.size() > 0) { - Connection conn = connections.get(random.nextInt(connections.size())); - Statement stat = conn.createStatement(); - String table = tables.get(random.nextInt(tables.size())); - stat.execute("INSERT INTO " + table + "(NAME) VALUES('Hello World')"); - } - } else { - // 32% delete - if (tables.size() > 0) { - Connection conn = connections.get(random.nextInt(connections.size())); - Statement stat = conn.createStatement(); - String table = tables.get(random.nextInt(tables.size())); - stat.execute("DELETE FROM " + table + " WHERE ID = SELECT MIN(ID) FROM " + table); - } - } - } - System.out.println("#Fail: end " + wasRunning); - System.out.println("#End"); - } catch (Throwable e) { - System.out.println("#Fail: openCount=" + openCount + " url=" + url + " " + e.toString()); - e.printStackTrace(System.out); - System.out.println("#End"); - } - } - - private Connection openConnection() throws Exception { - Class.forName(driver); - openCount++; - Connection conn = DriverManager.getConnection(url, user, password); - connections.add(conn); - return conn; - } - - private void createTable(Random random) throws SQLException { - Connection conn = connections.get(random.nextInt(connections.size())); - Statement stat = conn.createStatement(); - String table = "TEST" + random.nextInt(10); - try { - stat.execute("CREATE TABLE " + table + "(ID IDENTITY, NAME VARCHAR)"); - System.out.println("#Info table created: " + table); - tables.add(table); - } catch (SQLException e) { - if (e.getErrorCode() == ErrorCode.TABLE_OR_VIEW_ALREADY_EXISTS_1) { - System.out.println("#Info table already exists: " + table); - if (!tables.contains(table)) { - tables.add(table); - } - // ok - } else { - throw e; - } - } - } - - private void testConsistent(Connection conn) throws SQLException { - for (int i = 0; i < 20; i++) { - Statement stat = conn.createStatement(); - try { - ResultSet rs = stat.executeQuery("SELECT * FROM TEST" + i); - while (rs.next()) { - rs.getLong("ID"); - rs.getString("NAME"); - } - rs = stat.executeQuery("SELECT * FROM TEST" + i + " ORDER BY ID"); - while (rs.next()) { - rs.getLong("ID"); - rs.getString("NAME"); - } - } catch (SQLException e) { - if (e.getErrorCode() == ErrorCode.TABLE_OR_VIEW_NOT_FOUND_1) { - // ok - } else { - throw e; - } - } - } - } - -} diff --git a/tools/h2/src/test/org/h2/test/synth/TestMultiThreaded.java b/tools/h2/src/test/org/h2/test/synth/TestMultiThreaded.java deleted file mode 100755 index 4ce1ad3..0000000 --- a/tools/h2/src/test/org/h2/test/synth/TestMultiThreaded.java +++ /dev/null @@ -1,175 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.test.synth; - -import java.sql.Connection; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.sql.Statement; -import java.util.Random; - -import org.h2.test.TestBase; - -/** - * Tests the multi-threaded mode. - */ -public class TestMultiThreaded extends TestBase { - - /** - * Run just this test. - * - * @param a ignored - */ - public static void main(String... a) throws Exception { - TestBase.createCaller().init().test(); - } - - /** - * Processes random operations. - */ - private class Processor extends Thread { - private int id; - private Statement stat; - private Random random; - private volatile Throwable exception; - private boolean stop; - - Processor(Connection conn, int id) throws SQLException { - this.id = id; - stat = conn.createStatement(); - random = new Random(id); - } - public Throwable getException() { - return exception; - } - public void run() { - int count = 0; - ResultSet rs; - try { - while (!stop) { - switch(random.nextInt(6)) { - case 0: - // insert a row for this connection - traceThread("insert " + id + " count: " + count); - stat.execute("INSERT INTO TEST(NAME) VALUES('"+ id +"')"); - traceThread("insert done"); - count++; - break; - case 1: - // delete a row for this connection - if (count > 0) { - traceThread("delete " + id + " count: " + count); - int updateCount = stat.executeUpdate( - "DELETE FROM TEST WHERE NAME = '"+ id +"' AND ROWNUM()<2"); - traceThread("delete done"); - if (updateCount != 1) { - throw new AssertionError("Expected: 1 Deleted: " + updateCount); - } - count--; - } - break; - case 2: - // select the number of rows of this connection - traceThread("select " + id + " count: " + count); - rs = stat.executeQuery("SELECT COUNT(*) FROM TEST WHERE NAME = '"+ id +"'"); - traceThread("select done"); - rs.next(); - int got = rs.getInt(1); - if (got != count) { - throw new AssertionError("Expected: " + count + " got: " + got); - } - break; - case 3: - traceThread("insert"); - stat.execute("INSERT INTO TEST(NAME) VALUES(NULL)"); - traceThread("insert done"); - break; - case 4: - traceThread("delete"); - stat.execute("DELETE FROM TEST WHERE NAME IS NULL"); - traceThread("delete done"); - break; - case 5: - traceThread("select"); - rs = stat.executeQuery("SELECT * FROM TEST WHERE NAME IS NULL"); - traceThread("select done"); - while (rs.next()) { - rs.getString(1); - } - break; - } - } - } catch (Throwable e) { - exception = e; - } - } - - private void traceThread(String s) { - if (config.traceTest) { - trace(id + " " + s); - } - } - public void stopNow() { - this.stop = true; - } - } - - public void test() throws Exception { - if (config.mvcc) { - return; - } - deleteDb("multiThreaded"); - int size = getSize(2, 4); - Connection[] connList = new Connection[size]; - for (int i = 0; i < size; i++) { - connList[i] = getConnection("multiThreaded;MULTI_THREADED=1;TRACE_LEVEL_SYSTEM_OUT=1"); - } - Connection conn = connList[0]; - Statement stat = conn.createStatement(); - stat.execute("CREATE SEQUENCE TEST_SEQ"); - stat.execute("CREATE TABLE TEST(ID BIGINT DEFAULT NEXT VALUE FOR TEST_SEQ, NAME VARCHAR)"); - // stat.execute("CREATE TABLE TEST(ID IDENTITY, NAME VARCHAR)"); - // stat.execute("CREATE INDEX IDX_TEST_NAME ON TEST(NAME)"); - trace("init done"); - Processor[] processors = new Processor[size]; - for (int i = 0; i < size; i++) { - conn = connList[i]; - conn.createStatement().execute("SET LOCK_TIMEOUT 1000"); - processors[i] = new Processor(conn, i); - processors[i].start(); - trace("started " + i); - Thread.sleep(100); - } - for (int t = 0; t < 2; t++) { - Thread.sleep(1000); - for (int i = 0; i < size; i++) { - Processor p = processors[i]; - if (p.getException() != null) { - throw new Exception("" + i, p.getException()); - } - } - } - trace("stopping"); - for (int i = 0; i < size; i++) { - Processor p = processors[i]; - p.stopNow(); - } - for (int i = 0; i < size; i++) { - Processor p = processors[i]; - p.join(100); - if (p.getException() != null) { - throw new Exception(p.getException()); - } - } - trace("close"); - for (int i = 0; i < size; i++) { - connList[i].close(); - } - deleteDb("multiThreaded"); - } - -} diff --git a/tools/h2/src/test/org/h2/test/synth/TestPowerOffFs.java b/tools/h2/src/test/org/h2/test/synth/TestPowerOffFs.java deleted file mode 100755 index 6c4125e..0000000 --- a/tools/h2/src/test/org/h2/test/synth/TestPowerOffFs.java +++ /dev/null @@ -1,98 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.test.synth; - -import java.sql.Connection; -import java.sql.DriverManager; -import java.sql.SQLException; -import java.sql.Statement; -import org.h2.constant.ErrorCode; -import org.h2.store.fs.FileSystem; -import org.h2.test.TestBase; -import org.h2.test.utils.DebugFileSystem; - -/** - * Tests that use the debug file system to simulate power failure. - */ -public class TestPowerOffFs extends TestBase { - - private DebugFileSystem fs; - - /** - * Run just this test. - * - * @param a ignored - */ - public static void main(String... a) throws Exception { - TestBase.createCaller().init().test(); - } - - public void test() throws Exception { - DebugFileSystem.register(); - fs = (DebugFileSystem) FileSystem.getInstance("debug:/"); - test(Integer.MAX_VALUE); - System.out.println(Integer.MAX_VALUE - fs.getPowerOffCount()); - System.out.println("done"); - for (int i = 0;; i++) { - boolean end = test(i); - if (end) { - break; - } - } - } - - private boolean test(int x) throws SQLException { - deleteDb("memFS:", null); - fs.setPowerOffCount(x); - String url = "jdbc:h2:debug:memFS:powerOffFs;FILE_LOCK=NO;TRACE_LEVEL_FILE=0;WRITE_DELAY=0;CACHE_SIZE=4096"; - Connection conn = null; - Statement stat = null; - try { - conn = DriverManager.getConnection(url); - stat = conn.createStatement(); - stat.execute("create table test(id int primary key, name varchar)"); - stat.execute("insert into test values(1, 'Hello')"); - stat.execute("create index idx_name on test(name)"); - stat.execute("insert into test values(2, 'World')"); - stat.execute("update test set name='Hallo' where id=1"); - stat.execute("delete from test where name=2"); - stat.execute("insert into test values(3, space(10000))"); - stat.execute("update test set name='Hallo' where id=3"); - stat.execute("drop table test"); - conn.close(); - conn = null; - return fs.getPowerOffCount() > 0; - } catch (SQLException e) { - if (e.getErrorCode() == ErrorCode.TABLE_OR_VIEW_ALREADY_EXISTS_1) { - throw e; - } - // ignore - } finally { - if (conn != null) { - try { - if (stat != null) { - stat.execute("shutdown immediately"); - } - } catch (Exception e2) { - // ignore - } - try { - conn.close(); - } catch (Exception e2) { - // ignore - } - } - } - fs.setPowerOffCount(0); - conn = DriverManager.getConnection(url); - stat = conn.createStatement(); - stat.execute("script to 'memFS:test.sql'"); - conn.close(); - return false; - } - -} diff --git a/tools/h2/src/test/org/h2/test/synth/TestPowerOffFs2.java b/tools/h2/src/test/org/h2/test/synth/TestPowerOffFs2.java deleted file mode 100755 index 135628c..0000000 --- a/tools/h2/src/test/org/h2/test/synth/TestPowerOffFs2.java +++ /dev/null @@ -1,224 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.test.synth; - -import java.sql.Connection; -import java.sql.DriverManager; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.sql.Statement; -import java.util.ArrayList; -import java.util.Random; -import org.h2.constant.ErrorCode; -import org.h2.store.fs.FileSystem; -import org.h2.test.TestBase; -import org.h2.test.utils.DebugFileSystem; -import org.h2.util.New; - -/** - * Tests that use the debug file system to simulate power failure. - * This test runs many random operations and stops after some time. - */ -public class TestPowerOffFs2 extends TestBase { - - private DebugFileSystem fs; - - private String url; - private String user = "sa"; - private String password = "sa"; - private ArrayList connections = New.arrayList(); - private ArrayList tables = New.arrayList(); - private int openCount; - - /** - * Run just this test. - * - * @param a ignored - */ - public static void main(String... a) throws Exception { - TestBase.createCaller().init().test(); - } - - public void test() throws Exception { - DebugFileSystem.register(); - url = "jdbc:h2:debug:memFS:powerOffFs;FILE_LOCK=NO;TRACE_LEVEL_FILE=0;WRITE_DELAY=0;CACHE_SIZE=32"; - fs = (DebugFileSystem) FileSystem.getInstance("debug:/"); - for (int i = 0;; i++) { - test(i); - } - } - - private void test(int x) throws SQLException { - System.out.println("x:" + x); - deleteDb("memFS:", null); - try { - testCrash(x); - fail(); - } catch (SQLException e) { - if (e.toString().indexOf("Simulated") < 0) { - throw e; - } - for (Connection c : connections) { - try { - Statement stat = c.createStatement(); - stat.execute("shutdown immediately"); - } catch (Exception e2) { - // ignore - } - try { - c.close(); - } catch (Exception e2) { - // ignore - } - } - } - fs.setPowerOffCount(0); - Connection conn; - conn = openConnection(); - testConsistent(conn); - conn.close(); - } - - private void testCrash(int x) throws SQLException { - connections.clear(); - tables.clear(); - openCount = 0; - Random random = new Random(x); - for (int i = 0;; i++) { - if (i > 200 && connections.size() > 1 && tables.size() > 1) { - fs.setPowerOffCount(100); - } - if (connections.size() < 1) { - openConnection(); - } - if (tables.size() < 1) { - createTable(random); - } - int p = random.nextInt(100); - if ((p -= 2) <= 0) { - // 2%: open new connection - if (connections.size() < 5) { - openConnection(); - } - } else if ((p -= 1) <= 0) { - // 1%: close connection - if (connections.size() > 1) { - Connection conn = connections.remove(random.nextInt(connections.size())); - conn.close(); - } - } else if ((p -= 10) <= 0) { - // 10% create table - createTable(random); - } else if ((p -= 20) <= 0) { - // 20% large insert, delete, or update - if (tables.size() > 0) { - Connection conn = connections.get(random.nextInt(connections.size())); - Statement stat = conn.createStatement(); - String table = tables.get(random.nextInt(tables.size())); - if (random.nextBoolean()) { - // 10% insert - stat.execute("INSERT INTO " + table + "(NAME) SELECT 'Hello ' || X FROM SYSTEM_RANGE(0, 20)"); - } else if (random.nextBoolean()) { - // 5% update - stat.execute("UPDATE " + table + " SET NAME='Hallo Welt'"); - } else { - // 5% delete - stat.execute("DELETE FROM " + table); - } - } - } else if ((p -= 5) < 0) { - // 5% truncate or drop table - if (tables.size() > 0) { - Connection conn = connections.get(random.nextInt(connections.size())); - Statement stat = conn.createStatement(); - String table = tables.get(random.nextInt(tables.size())); - if (random.nextBoolean()) { - stat.execute("TRUNCATE TABLE " + table); - } else { - stat.execute("DROP TABLE " + table); - tables.remove(table); - } - } - } else if ((p -= 30) <= 0) { - // 30% insert - if (tables.size() > 0) { - Connection conn = connections.get(random.nextInt(connections.size())); - Statement stat = conn.createStatement(); - String table = tables.get(random.nextInt(tables.size())); - int spaces = random.nextInt(4) * 30; - if (random.nextInt(15) == 2) { - spaces *= 100; - } - int name = random.nextInt(20); - stat.execute("INSERT INTO " + table + "(NAME) VALUES('" + name + "' || space( " + spaces + " ))"); - } - } else { - // 32% delete - if (tables.size() > 0) { - Connection conn = connections.get(random.nextInt(connections.size())); - Statement stat = conn.createStatement(); - String table = tables.get(random.nextInt(tables.size())); - stat.execute("DELETE FROM " + table + " WHERE ID = SELECT MIN(ID) FROM " + table); - } - } - } - } - - private Connection openConnection() throws SQLException { - openCount++; - Connection conn = DriverManager.getConnection(url, user, password); - connections.add(conn); - return conn; - } - - private void createTable(Random random) throws SQLException { - Connection conn = connections.get(random.nextInt(connections.size())); - Statement stat = conn.createStatement(); - String table = "TEST" + random.nextInt(10); - try { - stat.execute("CREATE TABLE " + table + "(ID IDENTITY, NAME VARCHAR)"); - if (random.nextBoolean()) { - stat.execute("CREATE INDEX IDX_" + table + " ON " + table + "(NAME)"); - } - tables.add(table); - } catch (SQLException e) { - if (e.getErrorCode() == ErrorCode.TABLE_OR_VIEW_ALREADY_EXISTS_1) { - if (!tables.contains(table)) { - tables.add(table); - } - // ok - } else { - throw e; - } - } - } - - private void testConsistent(Connection conn) throws SQLException { - for (int i = 0; i < 20; i++) { - Statement stat = conn.createStatement(); - try { - ResultSet rs = stat.executeQuery("SELECT * FROM TEST" + i); - while (rs.next()) { - rs.getLong("ID"); - rs.getString("NAME"); - } - rs = stat.executeQuery("SELECT * FROM TEST" + i + " ORDER BY ID"); - while (rs.next()) { - rs.getLong("ID"); - rs.getString("NAME"); - } - } catch (SQLException e) { - if (e.getErrorCode() == ErrorCode.TABLE_OR_VIEW_NOT_FOUND_1) { - // ok - } else { - throw e; - } - } - } - } - -} diff --git a/tools/h2/src/test/org/h2/test/synth/TestRandomSQL.java b/tools/h2/src/test/org/h2/test/synth/TestRandomSQL.java deleted file mode 100755 index 61fc423..0000000 --- a/tools/h2/src/test/org/h2/test/synth/TestRandomSQL.java +++ /dev/null @@ -1,135 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.test.synth; - -import java.sql.Connection; -import java.sql.SQLException; -import java.sql.Statement; -import org.h2.constant.SysProperties; -import org.h2.store.fs.FileSystemMemory; -import org.h2.test.TestAll; -import org.h2.test.TestBase; -import org.h2.tools.DeleteDbFiles; -import org.h2.util.IOUtils; -import org.h2.util.MathUtils; - -/** - * This test executes random SQL statements generated using the BNF tool. - */ -public class TestRandomSQL extends TestBase { - - private int seed; - private boolean exitOnError = true; - private BnfRandom bnfRandom; - private int success, total; - - /** - * Run just this test. - * - * @param a ignored - */ - public static void main(String... a) throws Exception { - TestBase.createCaller().init().test(); - } - - private void processException(String sql, SQLException e) { - if (e.getSQLState().equals("HY000")) { - TestBase.logError("new TestRandomSQL().init(test).testCase(" + seed + "); // FAIL: " + e.toString() + " sql: " + sql, e); - if (exitOnError) { - System.exit(0); - } - } - } - - private String getDatabaseName() { - return "dataRandomSQL/randomSql" + seed; - } - - private Connection connect() throws SQLException { - return getConnection(getDatabaseName()); - } - - private void deleteDb() throws SQLException { - String name = getDatabaseName(); - if (name.startsWith(FileSystemMemory.PREFIX)) { - DeleteDbFiles.execute("memFS:/", name, true); - } else { - DeleteDbFiles.execute(getBaseDir() + "/dataRandomSQL", null, true); - IOUtils.delete(getBaseDir() + "/dataRandomSQL"); - } - } - - public TestBase init(TestAll conf) throws Exception { - super.init(conf); - return this; - } - - private void testWithSeed() throws Exception { - Connection conn = null; - try { - conn = connect(); - } catch (SQLException e) { - processException("connect", e); - conn = connect(); - } - Statement stat = conn.createStatement(); - - bnfRandom = new BnfRandom(); - bnfRandom.setSeed(seed); - for (int i = 0; i < bnfRandom.getStatementCount(); i++) { - String sql = bnfRandom.getRandomSQL(); - if (sql != null) { - try { - Thread.yield(); - total++; - if (total % 100 == 0) { - printTime("total: " + total + " success: " + (100 * success / total) + "%"); - } - stat.execute(sql); - success++; - } catch (SQLException e) { - processException(sql, e); - } - } - } - try { - conn.close(); - conn = connect(); - conn.createStatement().execute("shutdown immediately"); - conn.close(); - } catch (SQLException e) { - processException("conn.close", e); - } - } - - public void testCase(int i) throws Exception { - String old = SysProperties.getScriptDirectory(); - try { - System.setProperty(SysProperties.H2_SCRIPT_DIRECTORY, "dataScript/"); - seed = i; - printTime("seed: " + seed); - deleteDb(); - testWithSeed(); - } finally { - System.setProperty(SysProperties.H2_SCRIPT_DIRECTORY, old); - } - deleteDb(); - } - - public void test() throws Exception { - if (config.networked) { - return; - } - int len = getSize(2, 6); - exitOnError = false; - for (int a = 0; a < len; a++) { - int s = MathUtils.randomInt(Integer.MAX_VALUE); - testCase(s); - } - } - -} diff --git a/tools/h2/src/test/org/h2/test/synth/TestSimpleIndex.java b/tools/h2/src/test/org/h2/test/synth/TestSimpleIndex.java deleted file mode 100755 index 4adaffc..0000000 --- a/tools/h2/src/test/org/h2/test/synth/TestSimpleIndex.java +++ /dev/null @@ -1,176 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.test.synth; - -import java.sql.Connection; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.sql.Statement; - -import org.h2.test.TestBase; -import org.h2.test.synth.sql.RandomGen; - -/** - * A test that runs random operations against a table to test the various index - * implementations. - */ -public class TestSimpleIndex extends TestBase { - - private Connection conn; - private Statement stat; - private RandomGen random; - - /** - * Run just this test. - * - * @param a ignored - */ - public static void main(String... a) throws Exception { - TestBase.createCaller().init().test(); - } - - public void test() throws SQLException { - deleteDb("simpleIndex"); - conn = getConnection("simpleIndex"); - random = new RandomGen(); - stat = conn.createStatement(); - for (int i = 0; i < 10000; i++) { - testIndex(i); - } - } - - private void testIndex(int seed) throws SQLException { - random.setSeed(seed); - String unique = random.nextBoolean() ? "UNIQUE " : ""; - int len = random.getInt(2) + 1; - StringBuilder buff = new StringBuilder(); - for (int i = 0; i < len; i++) { - if (i > 0) { - buff.append(", "); - } - buff.append((char) ('A' + random.getInt(3))); - } - String cols = buff.toString(); - execute("CREATE MEMORY TABLE TEST_M(A INT, B INT, C INT, DATA VARCHAR(255))"); - execute("CREATE CACHED TABLE TEST_D(A INT, B INT, C INT, DATA VARCHAR(255))"); - execute("CREATE MEMORY TABLE TEST_MI(A INT, B INT, C INT, DATA VARCHAR(255))"); - execute("CREATE CACHED TABLE TEST_DI(A INT, B INT, C INT, DATA VARCHAR(255))"); - execute("CREATE " + unique + "INDEX M ON TEST_MI(" + cols + ")"); - execute("CREATE " + unique + "INDEX D ON TEST_DI(" + cols + ")"); - for (int i = 0; i < 100; i++) { - println("i=" + i); - testRows(); - } - execute("DROP INDEX M"); - execute("DROP INDEX D"); - execute("DROP TABLE TEST_M"); - execute("DROP TABLE TEST_D"); - execute("DROP TABLE TEST_MI"); - execute("DROP TABLE TEST_DI"); - } - - private void testRows() throws SQLException { - String a = randomValue(), b = randomValue(), c = randomValue(); - String data = a + "/" + b + "/" + c; - String sql = "VALUES(" + a + ", " + b + ", " + c + ", '" + data + "')"; - boolean em, ed; - // if(id==73) { - // print("halt"); - // } - try { - execute("INSERT INTO TEST_MI " + sql); - em = false; - } catch (SQLException e) { - em = true; - } - try { - execute("INSERT INTO TEST_DI " + sql); - ed = false; - } catch (SQLException e) { - ed = true; - } - if (em != ed) { - fail("different result: "); - } - if (!em) { - execute("INSERT INTO TEST_M " + sql); - execute("INSERT INTO TEST_D " + sql); - } - StringBuilder buff = new StringBuilder("WHERE 1=1"); - int len = random.getLog(10); - for (int i = 0; i < len; i++) { - buff.append(" AND "); - buff.append('A' + random.getInt(3)); - switch (random.getInt(10)) { - case 0: - buff.append("<"); - buff.append(random.getInt(100) - 50); - break; - case 1: - buff.append("<="); - buff.append(random.getInt(100) - 50); - break; - case 2: - buff.append(">"); - buff.append(random.getInt(100) - 50); - break; - case 3: - buff.append(">="); - buff.append(random.getInt(100) - 50); - break; - case 4: - buff.append("<>"); - buff.append(random.getInt(100) - 50); - break; - case 5: - buff.append(" IS NULL"); - break; - case 6: - buff.append(" IS NOT NULL"); - break; - default: - buff.append("="); - buff.append(random.getInt(100) - 50); - } - } - String where = buff.toString(); - String r1 = getResult("SELECT DATA FROM TEST_M " + where + " ORDER BY DATA"); - String r2 = getResult("SELECT DATA FROM TEST_D " + where + " ORDER BY DATA"); - String r3 = getResult("SELECT DATA FROM TEST_MI " + where + " ORDER BY DATA"); - String r4 = getResult("SELECT DATA FROM TEST_DI " + where + " ORDER BY DATA"); - assertEquals(r1, r2); - assertEquals(r1, r3); - assertEquals(r1, r4); - } - - private String getResult(String sql) throws SQLException { - ResultSet rs = stat.executeQuery(sql); - StringBuilder buff = new StringBuilder(); - while (rs.next()) { - buff.append(rs.getString(1)); - buff.append("; "); - } - rs.close(); - return buff.toString(); - } - - private String randomValue() { - return random.getInt(10) == 0 ? "NULL" : "" + (random.getInt(100) - 50); - } - - private void execute(String sql) throws SQLException { - try { - println(sql + ";"); - stat.execute(sql); - println("> update count: 1"); - } catch (SQLException e) { - println("> exception"); - throw e; - } - } - -} diff --git a/tools/h2/src/test/org/h2/test/synth/TestThreads.java b/tools/h2/src/test/org/h2/test/synth/TestThreads.java deleted file mode 100755 index 1f6b0e8..0000000 --- a/tools/h2/src/test/org/h2/test/synth/TestThreads.java +++ /dev/null @@ -1,169 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.test.synth; - -import java.sql.Connection; -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.sql.Statement; -import java.util.Random; - -import org.h2.test.TestBase; - -/** - * This test starts multiple threads and executes random operations in each - * thread. - */ -public class TestThreads extends TestBase implements Runnable { - - private static final int INSERT = 0, UPDATE = 1, DELETE = 2; - private static final int SELECT_ONE = 3, SELECT_ALL = 4, CHECKPOINT = 5, RECONNECT = 6; - private static final int OP_TYPES = RECONNECT + 1; - - private int maxId = 1; - - private volatile boolean stop; - private TestThreads master; - private int type; - private String table; - private Random random = new Random(); - - public TestThreads() { - // nothing to do - } - - TestThreads(TestThreads master, int type, String table) { - this.master = master; - this.type = type; - this.table = table; - } - - /** - * Run just this test. - * - * @param a ignored - */ - public static void main(String... a) throws Exception { - TestBase.createCaller().init().test(); - } - - public void test() throws Exception { - deleteDb("threads"); - Connection conn = getConnection("threads;MAX_LOG_SIZE=1"); - Statement stat = conn.createStatement(); - stat.execute("CREATE TABLE TEST_A(ID INT PRIMARY KEY, NAME VARCHAR)"); - stat.execute("CREATE TABLE TEST_B(ID INT PRIMARY KEY, NAME VARCHAR)"); - stat.execute("CREATE TABLE TEST_C(ID INT PRIMARY KEY, NAME VARCHAR)"); - int len = 1000; - insertRows(conn, "TEST_A", len); - insertRows(conn, "TEST_B", len); - insertRows(conn, "TEST_C", len); - maxId = len; - int threadCount = 4; - Thread[] threads = new Thread[threadCount]; - for (int i = 0; i < threadCount; i++) { - String t = random.nextBoolean() ? null : getRandomTable(); - int op = random.nextInt(OP_TYPES); - op = i % 2 == 0 ? RECONNECT : CHECKPOINT; - threads[i] = new Thread(new TestThreads(this, op, t)); - } - for (int i = 0; i < threadCount; i++) { - threads[i].start(); - } - Thread.sleep(10000); - stop = true; - for (int i = 0; i < threadCount; i++) { - threads[i].join(); - } - conn.close(); - conn = getConnection("threads"); - checkTable(conn, "TEST_A"); - checkTable(conn, "TEST_B"); - checkTable(conn, "TEST_C"); - conn.close(); - } - - private void insertRows(Connection conn, String tableName, int len) throws SQLException { - PreparedStatement prep = conn.prepareStatement("INSERT INTO " + tableName + " VALUES(?, 'Hi')"); - for (int i = 0; i < len; i++) { - prep.setInt(1, i); - prep.execute(); - } - } - - private void checkTable(Connection conn, String tableName) throws SQLException { - Statement stat = conn.createStatement(); - ResultSet rs = stat.executeQuery("SELECT * FROM " + tableName + " ORDER BY ID"); - while (rs.next()) { - int id = rs.getInt(1); - String name = rs.getString(2); - System.out.println("id=" + id + " name=" + name); - } - } - - private int getMaxId() { - return maxId; - } - - private synchronized int incrementMaxId() { - return maxId++; - } - - private String getRandomTable() { - return "TEST_" + (char) ('A' + random.nextInt(3)); - } - - public void run() { - try { - String t = table == null ? getRandomTable() : table; - Connection conn = master.getConnection("threads"); - Statement stat = conn.createStatement(); - ResultSet rs; - int max = master.getMaxId(); - int rid = random.nextInt(max); - for (int i = 0; !master.stop; i++) { - switch (type) { - case INSERT: - max = master.incrementMaxId(); - stat.execute("INSERT INTO " + t + "(ID, NAME) VALUES(" + max + ", 'Hello')"); - break; - case UPDATE: - stat.execute("UPDATE " + t + " SET NAME='World " + rid + "' WHERE ID=" + rid); - break; - case DELETE: - stat.execute("DELETE FROM " + t + " WHERE ID=" + rid); - break; - case SELECT_ALL: - rs = stat.executeQuery("SELECT * FROM " + t + " ORDER BY ID"); - while (rs.next()) { - // nothing - } - break; - case SELECT_ONE: - rs = stat.executeQuery("SELECT * FROM " + t + " WHERE ID=" + rid); - while (rs.next()) { - // nothing - } - break; - case CHECKPOINT: - stat.execute("CHECKPOINT"); - break; - case RECONNECT: - conn.close(); - conn = master.getConnection("threads"); - break; - default: - } - } - conn.close(); - } catch (Exception e) { - TestBase.logError("error", e); - } - } - -} diff --git a/tools/h2/src/test/org/h2/test/synth/TestTimer.java b/tools/h2/src/test/org/h2/test/synth/TestTimer.java deleted file mode 100755 index 4265e15..0000000 --- a/tools/h2/src/test/org/h2/test/synth/TestTimer.java +++ /dev/null @@ -1,143 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.test.synth; - -import java.io.File; -import java.sql.Connection; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.sql.Statement; -import java.util.Random; - -import org.h2.test.TestBase; -import org.h2.tools.Backup; -import org.h2.tools.DeleteDbFiles; - -/** - * A recovery test that checks the consistency of a database (if it exists), - * then deletes everything and runs in an endless loop executing random - * operations. This loop is usually stopped by switching off the computer. - */ -public class TestTimer extends TestBase { - - /** - * Run just this test. - * - * @param a ignored - */ - public static void main(String... a) throws Exception { - TestBase.createCaller().init().test(); - } - - public void test() throws SQLException { - validateOld(); - DeleteDbFiles.execute(getBaseDir(), "timer", true); - loop(); - } - - private void loop() throws SQLException { - println("loop"); - Connection conn = getConnection("timer"); - Statement stat = conn.createStatement(); - stat.execute("CREATE TABLE TEST(ID IDENTITY, NAME VARCHAR)"); - Random random = new Random(); - int max = 0; - int count = 0; - long startTime = System.currentTimeMillis(); - while (true) { - int action = random.nextInt(10); - int x = max == 0 ? 0 : random.nextInt(max); - switch (action) { - case 0: - case 1: - case 2: - stat.execute("INSERT INTO TEST VALUES(NULL, 'Hello')"); - ResultSet rs = stat.getGeneratedKeys(); - rs.next(); - int i = rs.getInt(1); - max = i; - count++; - break; - case 3: - case 4: - if (count == 0) { - break; - } - stat.execute("UPDATE TEST SET NAME=NAME||'+' WHERE ID=" + x); - break; - case 5: - case 6: - if (count == 0) { - break; - } - count -= stat.executeUpdate("DELETE FROM TEST WHERE ID=" + x); - break; - case 7: - rs = stat.executeQuery("SELECT COUNT(*) FROM TEST"); - rs.next(); - int c = rs.getInt(1); - assertEquals(count, c); - long time = System.currentTimeMillis(); - if (time > startTime + 5000) { - println("rows: " + count); - startTime = time; - } - break; - default: - } - } - } - - private void validateOld() { - println("validate"); - try { - Connection conn = getConnection("timer"); - // TODO validate transactions - Statement stat = conn.createStatement(); - stat.execute("CREATE TABLE IF NOT EXISTS TEST(ID IDENTITY, NAME VARCHAR)"); - ResultSet rs = stat.executeQuery("SELECT COUNT(*) FROM TEST"); - rs.next(); - int count = rs.getInt(1); - println("row count: " + count); - int real = 0; - rs = stat.executeQuery("SELECT * FROM TEST"); - while (rs.next()) { - real++; - } - if (real != count) { - println("real count: " + real); - throw new AssertionError("COUNT(*)=" + count + " SELECT=" + real); - } - rs = stat.executeQuery("SCRIPT"); - while (rs.next()) { - rs.getString(1); - } - conn.close(); - } catch (Throwable e) { - logError("validate", e); - backup(); - } - } - - private void backup() { - println("backup"); - for (int i = 0;; i++) { - String s = "timer." + i + ".zip"; - File f = new File(s); - if (f.exists()) { - continue; - } - try { - Backup.execute(s, getBaseDir(), "timer", true); - } catch (SQLException e) { - logError("backup", e); - } - break; - } - } - -} diff --git a/tools/h2/src/test/org/h2/test/synth/package.html b/tools/h2/src/test/org/h2/test/synth/package.html deleted file mode 100755 index 9997243..0000000 --- a/tools/h2/src/test/org/h2/test/synth/package.html +++ /dev/null @@ -1,15 +0,0 @@ - - - - -Javadoc package documentation -

    - -Synthetic tests using random operations or statements. - -

    \ No newline at end of file diff --git a/tools/h2/src/test/org/h2/test/synth/sql/Column.java b/tools/h2/src/test/org/h2/test/synth/sql/Column.java deleted file mode 100755 index 7b638ca..0000000 --- a/tools/h2/src/test/org/h2/test/synth/sql/Column.java +++ /dev/null @@ -1,228 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.test.synth.sql; - -import java.sql.ResultSetMetaData; -import java.sql.SQLException; -import java.sql.Types; - -import org.h2.value.DataType; - -/** - * A column of a table. - */ -class Column { - - private static final int[] TYPES = { Types.INTEGER, Types.VARCHAR, Types.DECIMAL, Types.DATE, Types.TIME, - Types.TIMESTAMP, DataType.TYPE_BOOLEAN, Types.BINARY, Types.VARBINARY, Types.CLOB, Types.BLOB, - Types.DOUBLE, Types.BIGINT, Types.TIMESTAMP, Types.BIT, }; - - private TestSynth config; - private String name; - private int type; - private int precision; - private int scale; - private boolean isNullable; - private boolean isPrimaryKey; - // TODO test isAutoincrement; - - private Column(TestSynth config) { - this.config = config; - } - - Column(ResultSetMetaData meta, int index) throws SQLException { - name = meta.getColumnLabel(index); - type = meta.getColumnType(index); - switch (type) { - case Types.DECIMAL: - precision = meta.getPrecision(index); - scale = meta.getScale(index); - break; - case Types.BLOB: - case Types.BINARY: - case Types.VARBINARY: - case Types.CLOB: - case Types.LONGVARCHAR: - case Types.DATE: - case Types.TIME: - case Types.INTEGER: - case Types.VARCHAR: - case Types.CHAR: - case Types.BIGINT: - case Types.NUMERIC: - case Types.TIMESTAMP: - case Types.NULL: - case Types.LONGVARBINARY: - case Types.DOUBLE: - case Types.REAL: - case Types.OTHER: - case Types.BIT: - case DataType.TYPE_BOOLEAN: - break; - default: - throw new AssertionError("type=" + type); - } - } - - /** - * Check if this data type supports comparisons for this database. - * - * @param config the configuration - * @param type the SQL type - * @return true if the value can be used in conditions - */ - static boolean isConditionType(TestSynth config, int type) { - switch (config.getMode()) { - case TestSynth.H2: - case TestSynth.H2_MEM: - return true; - case TestSynth.MYSQL: - case TestSynth.HSQLDB: - case TestSynth.POSTGRESQL: - switch (type) { - case Types.INTEGER: - case Types.VARCHAR: - case Types.DECIMAL: - case Types.DATE: - case Types.TIME: - case Types.TIMESTAMP: - case Types.DOUBLE: - case Types.BIGINT: - case DataType.TYPE_BOOLEAN: - case Types.BIT: - return true; - case Types.BINARY: - case Types.VARBINARY: - case Types.BLOB: - case Types.CLOB: - case Types.LONGVARCHAR: - case Types.LONGVARBINARY: - return false; - default: - throw new AssertionError("type=" + type); - } - default: - throw new AssertionError("type=" + type); - } - } - - private String getTypeName() { - switch (type) { - case Types.INTEGER: - return "INT"; - case Types.VARCHAR: - return "VARCHAR(" + precision + ")"; - case Types.DECIMAL: - return "NUMERIC(" + precision + ", " + scale + ")"; - case Types.DATE: - return "DATE"; - case Types.TIME: - return "TIME"; - case Types.TIMESTAMP: - return "TIMESTAMP"; - case Types.BINARY: - case Types.VARBINARY: - if (config.is(TestSynth.POSTGRESQL)) { - return "BYTEA"; - } - return "BINARY(" + precision + ")"; - case Types.CLOB: { - if (config.is(TestSynth.HSQLDB)) { - return "LONGVARCHAR"; - } else if (config.is(TestSynth.POSTGRESQL)) { - return "TEXT"; - } - return "CLOB"; - } - case Types.BLOB: { - if (config.is(TestSynth.HSQLDB)) { - return "LONGVARBINARY"; - } - return "BLOB"; - } - case Types.DOUBLE: - if (config.is(TestSynth.POSTGRESQL)) { - return "DOUBLE PRECISION"; - } - return "DOUBLE"; - case Types.BIGINT: - return "BIGINT"; - case DataType.TYPE_BOOLEAN: - case Types.BIT: - return "BOOLEAN"; - default: - throw new AssertionError("type=" + type); - } - } - - String getCreateSQL() { - String sql = name + " " + getTypeName(); - if (!isNullable) { - sql += " NOT NULL"; - } - return sql; - } - - String getName() { - return name; - } - - Value getRandomValue() { - return Value.getRandom(config, type, precision, scale, isNullable); - } - -// Value getRandomValueNotNull() { -// return Value.getRandom(config, type, precision, scale, false); -// } - - /** - * Generate a random column. - * - * @param config the configuration - * @return the column - */ - static Column getRandomColumn(TestSynth config) { - Column column = new Column(config); - column.name = "C_" + config.randomIdentifier(); - int randomType; - while (true) { - randomType = TYPES[config.random().getLog(TYPES.length)]; - if (config.is(TestSynth.POSTGRESQL) - && (randomType == Types.BINARY || randomType == Types.VARBINARY || randomType == Types.BLOB)) { - continue; - } - break; - } - column.type = randomType; - column.precision = config.random().getInt(20) + 2; - column.scale = config.random().getInt(column.precision); - column.isNullable = config.random().getBoolean(50); - return column; - } - - boolean getPrimaryKey() { - return isPrimaryKey; - } - - void setPrimaryKey(boolean b) { - isPrimaryKey = b; - } - - void setNullable(boolean b) { - isNullable = b; - } - - /** - * The the column type. - * - * @return the type - */ - int getType() { - return type; - } - -} diff --git a/tools/h2/src/test/org/h2/test/synth/sql/Command.java b/tools/h2/src/test/org/h2/test/synth/sql/Command.java deleted file mode 100755 index 62b9f27..0000000 --- a/tools/h2/src/test/org/h2/test/synth/sql/Command.java +++ /dev/null @@ -1,427 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.test.synth.sql; - -import java.sql.SQLException; -import java.util.HashMap; -import org.h2.util.New; -import org.h2.util.StatementBuilder; - -/** - * Represents a statement. - */ -class Command { - private static final int CONNECT = 0, RESET = 1, DISCONNECT = 2, CREATE_TABLE = 3, INSERT = 4, DROP_TABLE = 5, SELECT = 6, - DELETE = 7, UPDATE = 8, COMMIT = 9, ROLLBACK = 10, AUTOCOMMIT_ON = 11, AUTOCOMMIT_OFF = 12, - CREATE_INDEX = 13, DROP_INDEX = 14, END = 15; - - /** - * The select list. - */ - String[] selectList; - - private TestSynth config; - private int type; - private Table table; - private HashMap tables; - private Index index; - private Column[] columns; - private Value[] values; - private String condition; - // private int nextAlias; - private String order; - private String join = ""; - private Result result; - - private Command(TestSynth config, int type) { - this.config = config; - this.type = type; - } - - private Command(TestSynth config, int type, Table table) { - this.config = config; - this.type = type; - this.table = table; - } - - private Command(TestSynth config, int type, Table table, String alias) { - this.config = config; - this.type = type; - this.table = table; - this.tables = New.hashMap(); - this.tables.put(alias, table); - } - - private Command(TestSynth config, int type, Index index) { - this.config = config; - this.type = type; - this.index = index; - } - - Command(int type, String alias, Table table) { - this.type = type; - if (alias == null) { - alias = table.getName(); - } - addSubqueryTable(alias, table); - this.table = table; - } - -// static Command getDropTable(TestSynth config, Table table) { -// return new Command(config, Command.DROP_TABLE, table); -// } - -// Command getCommit(TestSynth config) { -// return new Command(config, Command.COMMIT); -// } - -// Command getRollback(TestSynth config) { -// return new Command(config, Command.ROLLBACK); -// } - -// Command getSetAutoCommit(TestSynth config, boolean auto) { -// int type = auto ? Command.AUTOCOMMIT_ON : Command.AUTOCOMMIT_OFF; -// return new Command(config, type); -// } - - /** - * Create a connect command. - * - * @param config the configuration - * @return the command - */ - static Command getConnect(TestSynth config) { - return new Command(config, CONNECT); - } - - /** - * Create a reset command. - * - * @param config the configuration - * @return the command - */ - static Command getReset(TestSynth config) { - return new Command(config, RESET); - } - - /** - * Create a disconnect command. - * - * @param config the configuration - * @return the command - */ - static Command getDisconnect(TestSynth config) { - return new Command(config, DISCONNECT); - } - - /** - * Create an end command. - * - * @param config the configuration - * @return the command - */ - static Command getEnd(TestSynth config) { - return new Command(config, END); - } - - /** - * Create a create table command. - * - * @param config the configuration - * @param table the table - * @return the command - */ - static Command getCreateTable(TestSynth config, Table table) { - return new Command(config, CREATE_TABLE, table); - } - - /** - * Create a create index command. - * - * @param config the configuration - * @param index the index - * @return the command - */ - static Command getCreateIndex(TestSynth config, Index index) { - return new Command(config, CREATE_INDEX, index); - } - - /** - * Create a random select command. - * - * @param config the configuration - * @param table the table - * @return the command - */ - static Command getRandomSelect(TestSynth config, Table table) { - Command command = new Command(config, Command.SELECT, table, "M"); - command.selectList = Expression.getRandomSelectList(config, command); - // TODO group by, having, joins - command.condition = Expression.getRandomCondition(config, command).getSQL(); - command.order = Expression.getRandomOrder(config, command); - return command; - } - -// static Command getRandomSelectJoin(TestSynth config, Table table) { -// Command command = new Command(config, Command.SELECT, table, "M"); -// int len = config.random().getLog(5) + 1; -// String globalJoinCondition = ""; -// for (int i = 0; i < len; i++) { -// Table t2 = config.randomTable(); -// String alias = "J" + i; -// command.addSubqueryTable(alias, t2); -// Expression joinOn = -// Expression.getRandomJoinOn(config, command, alias); -// if (config.random().getBoolean(50)) { -// // regular join -// if (globalJoinCondition.length() > 0) { -// globalJoinCondition += " AND "; -// -// } -// globalJoinCondition += " (" + joinOn.getSQL() + ") "; -// command.addJoin(", " + t2.getName() + " " + alias); -// } else { -// String join = " JOIN " + t2.getName() + -// " " + alias + " ON " + joinOn.getSQL(); -// if (config.random().getBoolean(20)) { -// command.addJoin(" LEFT OUTER" + join); -// } else { -// command.addJoin(" INNER" + join); -// } -// } -// } -// command.selectList = -// Expression.getRandomSelectList(config, command); -// // TODO group by, having -// String cond = Expression.getRandomCondition(config, command).getSQL(); -// if (globalJoinCondition.length() > 0) { -// if (cond != null) { -// cond = "(" + globalJoinCondition + " ) AND (" + cond + ")"; -// } else { -// cond = globalJoinCondition; -// } -// } -// command.condition = cond; -// command.order = Expression.getRandomOrder(config, command); -// return command; -// } - - /** - * Create a random delete command. - * - * @param config the configuration - * @param table the table - * @return the command - */ - static Command getRandomDelete(TestSynth config, Table table) { - Command command = new Command(config, Command.DELETE, table); - command.condition = Expression.getRandomCondition(config, command).getSQL(); - return command; - } - - /** - * Create a random update command. - * - * @param config the configuration - * @param table the table - * @return the command - */ - static Command getRandomUpdate(TestSynth config, Table table) { - Command command = new Command(config, Command.UPDATE, table); - command.prepareUpdate(); - return command; - } - - /** - * Create a random insert command. - * - * @param config the configuration - * @param table the table - * @return the command - */ - static Command getRandomInsert(TestSynth config, Table table) { - Command command = new Command(config, Command.INSERT, table); - command.prepareInsert(); - return command; - } - - /** - * Add a subquery table to the command. - * - * @param alias the table alias - * @param t the table - */ - void addSubqueryTable(String alias, Table t) { - tables.put(alias, t); - } - -// void removeSubqueryTable(String alias) { -// tables.remove(alias); -// } - - private void prepareInsert() { - Column[] c; - if (config.random().getBoolean(70)) { - c = table.getColumns(); - } else { - int len = config.random().getInt(table.getColumnCount() - 1) + 1; - c = columns = table.getRandomColumns(len); - } - values = new Value[c.length]; - for (int i = 0; i < c.length; i++) { - values[i] = c[i].getRandomValue(); - } - } - - private void prepareUpdate() { - int len = config.random().getLog(table.getColumnCount() - 1) + 1; - Column[] c = columns = table.getRandomColumns(len); - values = new Value[c.length]; - for (int i = 0; i < c.length; i++) { - values[i] = c[i].getRandomValue(); - } - condition = Expression.getRandomCondition(config, this).getSQL(); - } - - private Result select(DbInterface db) throws SQLException { - StatementBuilder buff = new StatementBuilder("SELECT "); - for (String s : selectList) { - buff.appendExceptFirst(", "); - buff.append(s); - } - buff.append(" FROM ").append(table.getName()).append(" M"). - append(' ').append(join); - if (condition != null) { - buff.append(" WHERE ").append(condition); - } - if (order.trim().length() > 0) { - buff.append(" ORDER BY ").append(order); - } - return db.select(buff.toString()); - } - - /** - * Run the command against the specified database. - * - * @param db the database - * @return the result - */ - Result run(DbInterface db) throws Exception { - try { - switch (type) { - case CONNECT: - db.connect(); - result = new Result("connect"); - break; - case RESET: - db.reset(); - result = new Result("reset"); - break; - case DISCONNECT: - db.disconnect(); - result = new Result("disconnect"); - break; - case END: - db.end(); - result = new Result("disconnect"); - break; - case CREATE_TABLE: - db.createTable(table); - result = new Result("createTable"); - break; - case DROP_TABLE: - db.dropTable(table); - result = new Result("dropTable"); - break; - case CREATE_INDEX: - db.createIndex(index); - result = new Result("createIndex"); - break; - case DROP_INDEX: - db.dropIndex(index); - result = new Result("dropIndex"); - break; - case INSERT: - result = db.insert(table, columns, values); - break; - case SELECT: - result = select(db); - break; - case DELETE: - result = db.delete(table, condition); - break; - case UPDATE: - result = db.update(table, columns, values, condition); - break; - case AUTOCOMMIT_ON: - db.setAutoCommit(true); - result = new Result("setAutoCommit true"); - break; - case AUTOCOMMIT_OFF: - db.setAutoCommit(false); - result = new Result("setAutoCommit false"); - break; - case COMMIT: - db.commit(); - result = new Result("commit"); - break; - case ROLLBACK: - db.rollback(); - result = new Result("rollback"); - break; - default: - throw new AssertionError("type=" + type); - } - } catch (SQLException e) { - result = new Result("", e); - } - return result; - } - -// public String getNextTableAlias() { -// return "S" + nextAlias++; -// } - - /** - * Get a random table alias name. - * - * @return the alias name - */ - String getRandomTableAlias() { - if (tables == null) { - return null; - } - Object[] list = tables.keySet().toArray(); - int i = config.random().getInt(list.length); - return (String) list[i]; - } - - /** - * Get the table with the specified alias. - * - * @param alias the alias or null if there is only one table - * @return the table - */ - Table getTable(String alias) { - if (alias == null) { - return table; - } - return tables.get(alias); - } - -// public void addJoin(String string) { -// join += string; -// } - -// static Command getSelectAll(TestSynth config, Table table) { -// Command command = new Command(config, Command.SELECT, table, "M"); -// command.selectList = new String[] { "*" }; -// command.order = ""; -// return command; -// } - -} diff --git a/tools/h2/src/test/org/h2/test/synth/sql/DbConnection.java b/tools/h2/src/test/org/h2/test/synth/sql/DbConnection.java deleted file mode 100755 index ce63c00..0000000 --- a/tools/h2/src/test/org/h2/test/synth/sql/DbConnection.java +++ /dev/null @@ -1,192 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.test.synth.sql; - -import java.sql.Connection; -import java.sql.DatabaseMetaData; -import java.sql.DriverManager; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.sql.Statement; -import java.util.ArrayList; -import org.h2.util.New; - -/** - * Represents a connection to a real database. - */ -class DbConnection implements DbInterface { - private TestSynth config; - private int id; - private String driver; - private String url; - private String user; - private String password; - private Connection conn; - private Connection sentinel; - private boolean useSentinel; - - DbConnection(TestSynth config, String driver, String url, String user, String password, int id, boolean useSentinel) { - this.config = config; - this.driver = driver; - this.url = url; - this.user = user; - this.password = password; - this.id = id; - this.useSentinel = useSentinel; - log("url=" + url); - } - - public void reset() throws SQLException { - log("reset;"); - DatabaseMetaData meta = conn.getMetaData(); - Statement stat = conn.createStatement(); - ArrayList tables = New.arrayList(); - ResultSet rs = meta.getTables(null, null, null, new String[] { "TABLE" }); - while (rs.next()) { - String schemaName = rs.getString("TABLE_SCHEM"); - if (!"INFORMATION_SCHEMA".equals(schemaName)) { - tables.add(rs.getString("TABLE_NAME")); - } - } - while (tables.size() > 0) { - int dropped = 0; - for (int i = 0; i < tables.size(); i++) { - try { - String table = tables.get(i); - stat.execute("DROP TABLE " + table); - dropped++; - tables.remove(i); - i--; - } catch (SQLException e) { - // maybe a referential integrity - } - } - // could not drop any table and still tables to drop - if (dropped == 0 && tables.size() > 0) { - throw new AssertionError("Cannot drop " + tables); - } - } - } - - public void connect() throws Exception { - if (useSentinel && sentinel == null) { - sentinel = getConnection(); - } - log("connect to " + url + ";"); - conn = getConnection(); - } - - private Connection getConnection() throws Exception { - log("(getConnection to " + url + ");"); - if (driver == null) { - return config.getConnection("synth"); - } - Class.forName(driver); - return DriverManager.getConnection(url, user, password); - } - - public void disconnect() throws SQLException { - log("disconnect " + url + ";"); - conn.close(); - } - - public void end() throws SQLException { - log("end " + url + ";"); - if (sentinel != null) { - sentinel.close(); - sentinel = null; - } - } - - public void createTable(Table table) throws SQLException { - execute(table.getCreateSQL()); - } - - public void dropTable(Table table) throws SQLException { - execute(table.getDropSQL()); - } - - public void createIndex(Index index) throws SQLException { - execute(index.getCreateSQL()); - index.getTable().addIndex(index); - } - - public void dropIndex(Index index) throws SQLException { - execute(index.getDropSQL()); - index.getTable().removeIndex(index); - } - - public Result insert(Table table, Column[] c, Value[] v) throws SQLException { - String sql = table.getInsertSQL(c, v); - execute(sql); - return new Result(sql, 1); - } - - private void execute(String sql) throws SQLException { - log(sql + ";"); - conn.createStatement().execute(sql); - } - - public Result select(String sql) throws SQLException { - log(sql + ";"); - Statement stat = conn.createStatement(); - Result result = new Result(config, sql, stat.executeQuery(sql)); - return result; - } - - public Result delete(Table table, String condition) throws SQLException { - String sql = "DELETE FROM " + table.getName(); - if (condition != null) { - sql += " WHERE " + condition; - } - log(sql + ";"); - Statement stat = conn.createStatement(); - Result result = new Result(sql, stat.executeUpdate(sql)); - return result; - } - - public Result update(Table table, Column[] columns, Value[] values, String condition) throws SQLException { - String sql = "UPDATE " + table.getName() + " SET "; - for (int i = 0; i < columns.length; i++) { - if (i > 0) { - sql += ", "; - } - sql += columns[i].getName() + "=" + values[i].getSQL(); - } - if (condition != null) { - sql += " WHERE " + condition; - } - log(sql + ";"); - Statement stat = conn.createStatement(); - Result result = new Result(sql, stat.executeUpdate(sql)); - return result; - } - - public void setAutoCommit(boolean b) throws SQLException { - log("set autoCommit " + b + ";"); - conn.setAutoCommit(b); - } - - public void commit() throws SQLException { - log("commit;"); - conn.commit(); - } - - public void rollback() throws SQLException { - log("rollback;"); - conn.rollback(); - } - - private void log(String s) { - config.log(id, s); - } - - public String toString() { - return url; - } - -} diff --git a/tools/h2/src/test/org/h2/test/synth/sql/DbInterface.java b/tools/h2/src/test/org/h2/test/synth/sql/DbInterface.java deleted file mode 100755 index c20603f..0000000 --- a/tools/h2/src/test/org/h2/test/synth/sql/DbInterface.java +++ /dev/null @@ -1,118 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.test.synth.sql; - -import java.sql.SQLException; - -/** - * Represents a connection to a (real or simulated) database. - */ -public interface DbInterface { - - /** - * Drop all objects in the database. - */ - void reset() throws SQLException; - - /** - * Connect to the database. - */ - void connect() throws Exception; - - /** - * Disconnect from the database. - */ - void disconnect() throws SQLException; - - /** - * Close the connection and the database. - */ - void end() throws SQLException; - - /** - * Create the specified table. - * - * @param table the table to create - */ - void createTable(Table table) throws SQLException; - - /** - * Drop the specified table. - * - * @param table the table to drop - */ - void dropTable(Table table) throws SQLException; - - /** - * Create an index. - * - * @param index the index to create - */ - void createIndex(Index index) throws SQLException; - - /** - * Drop an index. - * - * @param index the index to drop - */ - void dropIndex(Index index) throws SQLException; - - /** - * Insert a row into a table. - * - * @param table the table - * @param c the column list - * @param v the values - * @return the result - */ - Result insert(Table table, Column[] c, Value[] v) throws SQLException; - - /** - * Execute a query. - * - * @param sql the SQL statement - * @return the result - */ - Result select(String sql) throws SQLException; - - /** - * Delete a number of rows. - * - * @param table the table - * @param condition the condition - * @return the result - */ - Result delete(Table table, String condition) throws SQLException; - - /** - * Update the given table with the new values. - * - * @param table the table - * @param columns the columns to update - * @param values the new values - * @param condition the condition - * @return the result of the update - */ - Result update(Table table, Column[] columns, Value[] values, String condition) throws SQLException; - - /** - * Enable or disable autocommit. - * - * @param b the new value - */ - void setAutoCommit(boolean b) throws SQLException; - - /** - * Commit a pending transaction. - */ - void commit() throws SQLException; - - /** - * Roll back a pending transaction. - */ - void rollback() throws SQLException; -} diff --git a/tools/h2/src/test/org/h2/test/synth/sql/DbState.java b/tools/h2/src/test/org/h2/test/synth/sql/DbState.java deleted file mode 100755 index 1f17eb6..0000000 --- a/tools/h2/src/test/org/h2/test/synth/sql/DbState.java +++ /dev/null @@ -1,105 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.test.synth.sql; - -import java.util.ArrayList; -import org.h2.util.New; - -/** - * Represents a connection to a simulated database. - */ -public class DbState implements DbInterface { - - private boolean connected; - private boolean autoCommit; - private TestSynth config; - private ArrayList tables = New.arrayList(); - private ArrayList indexes = New.arrayList(); - - DbState(TestSynth config) { - this.config = config; - } - - public void reset() { - tables = New.arrayList(); - indexes = New.arrayList(); - } - - public void connect() { - connected = true; - } - - public void disconnect() { - connected = false; - } - - public void createTable(Table table) { - tables.add(table); - } - - public void dropTable(Table table) { - tables.remove(table); - } - - public void createIndex(Index index) { - indexes.add(index); - } - - public void dropIndex(Index index) { - indexes.remove(index); - } - - public Result insert(Table table, Column[] c, Value[] v) { - return null; - } - - public Result select(String sql) { - return null; - } - - public Result delete(Table table, String condition) { - return null; - } - - public Result update(Table table, Column[] columns, Value[] values, String condition) { - return null; - } - - public void setAutoCommit(boolean b) { - autoCommit = b; - } - - public void commit() { - // nothing to do - } - - public void rollback() { - // nothing to do - } - - /** - * Get a random table. - * - * @return the table - */ - Table randomTable() { - if (tables.size() == 0) { - return null; - } - int i = config.random().getInt(tables.size()); - return tables.get(i); - } - - public void end() { - // nothing to do - } - - public String toString() { - return "autocommit: " + autoCommit + " connected: " + connected; - } - -} diff --git a/tools/h2/src/test/org/h2/test/synth/sql/Expression.java b/tools/h2/src/test/org/h2/test/synth/sql/Expression.java deleted file mode 100755 index 6fdada3..0000000 --- a/tools/h2/src/test/org/h2/test/synth/sql/Expression.java +++ /dev/null @@ -1,378 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.test.synth.sql; - -import java.sql.Types; -import java.util.ArrayList; -import org.h2.util.New; - -/** - * Represents an expression. - */ -public class Expression { - - private String sql; - private TestSynth config; - private Command command; - - private Expression(TestSynth config, Command command) { - this.config = config; - this.command = command; - sql = ""; - } - - /** - * Create a random select list. - * - * @param config the configuration - * @param command the command - * @return the select list - */ - static String[] getRandomSelectList(TestSynth config, Command command) { - if (config.random().getBoolean(30)) { - return new String[] { "*" }; - } - ArrayList exp = New.arrayList(); - String sql = ""; - if (config.random().getBoolean(10)) { - sql += "DISTINCT "; - } - int len = config.random().getLog(8) + 1; - for (int i = 0; i < len; i++) { - sql += getRandomExpression(config, command).getSQL(); - sql += " AS A" + i + " "; - exp.add(sql); - sql = ""; - } - String[] list = new String[exp.size()]; - exp.toArray(list); - return list; - } - - /** - * Generate a random condition. - * - * @param config the configuration - * @param command the command - * @return the random condition expression - */ - static Expression getRandomCondition(TestSynth config, Command command) { - Expression condition = new Expression(config, command); - if (config.random().getBoolean(50)) { - condition.create(); - } - return condition; - } - - private static Expression getRandomExpression(TestSynth config, Command command) { - Expression expression = new Expression(config, command); - String alias = command.getRandomTableAlias(); - Column column = command.getTable(alias).getRandomConditionColumn(); - if (column == null) { - expression.createValue(); - } else { - expression.createExpression(alias, column); - } - return expression; - } - - private void createValue() { - Value v = Column.getRandomColumn(config).getRandomValue(); - sql = v.getSQL(); - } - - /** - * Generate a random join condition. - * - * @param config the configuration - * @param command the command - * @param alias the alias name - * @return the join condition - */ - static Expression getRandomJoinOn(TestSynth config, Command command, String alias) { - Expression expression = new Expression(config, command); - expression.createJoinComparison(alias); - return expression; - } - - /** - * Generate a random sort order list. - * - * @param config the configuration - * @param command the command - * @return the ORDER BY list - */ - static String getRandomOrder(TestSynth config, Command command) { - int len = config.random().getLog(6); - String sql = ""; - for (int i = 0; i < len; i++) { - if (i > 0) { - sql += ", "; - } - int max = command.selectList.length; - int idx = config.random().getInt(max); - // sql += getRandomExpression(command).getSQL(); - // if (max > 1 && config.random().getBoolean(50)) { - sql += "A" + idx; - // } else { - // sql += String.valueOf(idx + 1); - // } - if (config.random().getBoolean(50)) { - if (config.random().getBoolean(10)) { - sql += " ASC"; - } else { - sql += " DESC"; - } - } - } - return sql; - } - - /** - * Get the SQL snippet of this expression. - * - * @return the SQL snippet - */ - String getSQL() { - return sql.trim().length() == 0 ? null : sql.trim(); - } - - private boolean is(int percent) { - return config.random().getBoolean(percent); - } - - private String oneOf(String[] list) { - int i = config.random().getInt(list.length); - if (!sql.endsWith(" ")) { - sql += " "; - } - sql += list[i] + " "; - return list[i]; - } - - private String getColumnName(String alias, Column column) { - if (alias == null) { - return column.getName(); - } - return alias + "." + column.getName(); - } - - private void createJoinComparison(String alias) { - int len = config.random().getLog(5) + 1; - for (int i = 0; i < len; i++) { - if (i > 0) { - sql += "AND "; - } - Column column = command.getTable(alias).getRandomConditionColumn(); - if (column == null) { - sql += "1=1"; - return; - } - sql += getColumnName(alias, column); - sql += "="; - String a2; - do { - a2 = command.getRandomTableAlias(); - } while (a2.equals(alias)); - Table t2 = command.getTable(a2); - Column c2 = t2.getRandomColumnOfType(column.getType()); - if (c2 == null) { - sql += column.getRandomValue().getSQL(); - } else { - sql += getColumnName(a2, c2); - } - sql += " "; - } - } - - private void create() { - createComparison(); - while (is(50)) { - oneOf(new String[] { "AND", "OR" }); - createComparison(); - } - } - - // private void createSubquery() { - // // String alias = command.getRandomTableAlias(); - // // Table t1 = command.getTable(alias); - // Database db = command.getDatabase(); - // Table t2 = db.getRandomTable(); - // String a2 = command.getNextTableAlias(); - // sql += "SELECT * FROM " + t2.getName() + " " + a2 + " WHERE "; - // command.addSubqueryTable(a2, t2); - // createComparison(); - // command.removeSubqueryTable(a2); - // } - - private void createComparison() { - if (is(5)) { - sql += " NOT( "; - createComparisonSub(); - sql += ")"; - } else { - createComparisonSub(); - } - } - - private void createComparisonSub() { - /* - * if (is(10)) { sql += " EXISTS("; createSubquery(); sql += ")"; - * return; } else - */ - if (is(10)) { - sql += "("; - create(); - sql += ")"; - return; - } - String alias = command.getRandomTableAlias(); - Column column = command.getTable(alias).getRandomConditionColumn(); - if (column == null) { - if (is(50)) { - sql += "1=1"; - } else { - sql += "1=0"; - } - return; - } - boolean columnFirst = is(90); - if (columnFirst) { - sql += getColumnName(alias, column); - } else { - Value v = column.getRandomValue(); - sql += v.getSQL(); - } - if (is(10)) { - oneOf(new String[] { "IS NULL", "IS NOT NULL" }); - } else if (is(10)) { - oneOf(new String[] { "BETWEEN", "NOT BETWEEN" }); - Value v = column.getRandomValue(); - sql += v.getSQL(); - sql += " AND "; - v = column.getRandomValue(); - sql += v.getSQL(); - // } else if (is(10)) { - // // oneOf(new String[] { "IN", "NOT IN" }); - // sql += " IN "; - // sql += "("; - // int len = config.random().getInt(8) + 1; - // for (int i = 0; i < len; i++) { - // if (i > 0) { - // sql += ", "; - // } - // sql += column.getRandomValueNotNull().getSQL(); - // } - // sql += ")"; - } else { - if (column.getType() == Types.VARCHAR) { - oneOf(new String[] { "=", "=", "=", "<", ">", "<=", ">=", "<>", "LIKE", "NOT LIKE" }); - } else { - oneOf(new String[] { "=", "=", "=", "<", ">", "<=", ">=", "<>" }); - } - if (columnFirst) { - Value v = column.getRandomValue(); - sql += v.getSQL(); - } else { - sql += getColumnName(alias, column); - } - } - } - - private void createExpression(String alias, Column type) { - boolean op = is(20); - // no null values if there is an operation - boolean allowNull = !op; - // boolean allowNull =true; - - createTerm(alias, type, true); - if (op) { - switch (type.getType()) { - case Types.INTEGER: - if (config.is(TestSynth.POSTGRESQL)) { - oneOf(new String[] { "+", "-", "/" }); - } else { - oneOf(new String[] { "+", "-", "*", "/" }); - } - createTerm(alias, type, allowNull); - break; - case Types.DECIMAL: - oneOf(new String[] { "+", "-", "*" }); - createTerm(alias, type, allowNull); - break; - case Types.VARCHAR: - sql += " || "; - createTerm(alias, type, allowNull); - break; - case Types.BLOB: - case Types.CLOB: - case Types.DATE: - break; - default: - } - } - } - - private void createTerm(String alias, Column type, boolean allowNull) { - int dt = type.getType(); - if (is(5) && (dt == Types.INTEGER) || (dt == Types.DECIMAL)) { - sql += " - "; - allowNull = false; - } - if (is(10)) { - sql += "("; - createTerm(alias, type, allowNull); - sql += ")"; - return; - } - if (is(20)) { - // if (is(10)) { - // sql += "CAST("; - // // TODO cast - // Column c = Column.getRandomColumn(config); - // createTerm(alias, c, allowNull); - // sql += " AS "; - // sql += type.getTypeName(); - // sql += ")"; - // return; - // } - switch (dt) { - // case Types.INTEGER: - // String function = oneOf(new String[] { "LENGTH" /*, "MOD" */ }); - // sql += "("; - // createTerm(alias, type, allowNull); - // sql += ")"; - // break; - case Types.VARCHAR: - oneOf(new String[] { "LOWER", "UPPER" }); - sql += "("; - createTerm(alias, type, allowNull); - sql += ")"; - break; - default: - createTerm(alias, type, allowNull); - } - return; - } - if (is(60)) { - String a2 = command.getRandomTableAlias(); - Column column = command.getTable(a2).getRandomColumnOfType(dt); - if (column != null) { - sql += getColumnName(a2, column); - return; - } - } - - Value v = Value.getRandom(config, dt, 20, 2, allowNull); - sql += v.getSQL(); - } - - public String toString() { - throw new AssertionError(); - } - -} diff --git a/tools/h2/src/test/org/h2/test/synth/sql/Index.java b/tools/h2/src/test/org/h2/test/synth/sql/Index.java deleted file mode 100755 index 9a74d8f..0000000 --- a/tools/h2/src/test/org/h2/test/synth/sql/Index.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.test.synth.sql; - -/** - * Represents an index. - */ -public class Index { - private Table table; - private String name; - private Column[] columns; - private boolean unique; - - Index(Table table, String name, Column[] columns, boolean unique) { - this.table = table; - this.name = name; - this.columns = columns; - this.unique = unique; - } - - String getName() { - return name; - } - - String getCreateSQL() { - String sql = "CREATE "; - if (unique) { - sql += "UNIQUE "; - } - sql += "INDEX " + name + " ON " + table.getName() + "("; - for (int i = 0; i < columns.length; i++) { - if (i > 0) { - sql += ", "; - } - sql += columns[i].getName(); - } - sql += ")"; - return sql; - } - - String getDropSQL() { - return "DROP INDEX " + name; - } - - Table getTable() { - return table; - } - -} diff --git a/tools/h2/src/test/org/h2/test/synth/sql/RandomGen.java b/tools/h2/src/test/org/h2/test/synth/sql/RandomGen.java deleted file mode 100755 index 9b95d47..0000000 --- a/tools/h2/src/test/org/h2/test/synth/sql/RandomGen.java +++ /dev/null @@ -1,346 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.test.synth.sql; - -import java.sql.Date; -import java.sql.Time; -import java.sql.Timestamp; -import java.util.Random; - -/** - * A random data generator class. - */ -public class RandomGen { - private Random random = new Random(); - - /** - * Create a new random instance with a fixed seed value. - */ - public RandomGen() { - random.setSeed(12); - } - - /** - * Get the next integer that is smaller than max. - * - * @param max the upper limit (exclusive) - * @return the random value - */ - public int getInt(int max) { - return max == 0 ? 0 : random.nextInt(max); - } - - /** - * Get the next gaussian value. - * - * @return the value - */ - public double nextGaussian() { - return random.nextGaussian(); - } - - /** - * Get the next random value that is at most max but probably much lower. - * - * @param max the maximum value - * @return the value - */ - public int getLog(int max) { - if (max == 0) { - return 0; - } - while (true) { - int d = Math.abs((int) (random.nextGaussian() / 2. * max)); - if (d < max) { - return d; - } - } - } - - /** - * Get a number of random bytes. - * - * @param data the target buffer - */ - public void getBytes(byte[] data) { - random.nextBytes(data); - } - - /** - * Get a boolean that is true with the given probability in percent. - * - * @param percent the probability - * @return the boolean value - */ - public boolean getBoolean(int percent) { - return random.nextInt(100) <= percent; - } - - /** - * Get a random string with the given length. - * - * @param len the length - * @return the string - */ - public String randomString(int len) { - StringBuilder buff = new StringBuilder(); - for (int i = 0; i < len; i++) { - String from = (i % 2 == 0) ? "bdfghklmnpqrst" : "aeiou"; - buff.append(from.charAt(getInt(from.length()))); - } - return buff.toString(); - } - - /** - * Get a random integer. In 10% of the cases, Integer.MAX_VALUE is returned, - * in 10% of the cases Integer.MIN_VALUE. Also in the 10% of the cases, a - * random value between those extremes is returned. In 20% of the cases, - * this method returns 0. In 10% of the cases, a gaussian value in the range - * -200 and +1800 is returned. In all other cases, a gaussian value in the - * range -5 and +20 is returned. - * - * @return the random value - */ - public int getRandomInt() { - switch (random.nextInt(10)) { - case 0: - return Integer.MAX_VALUE; - case 1: - return Integer.MIN_VALUE; - case 2: - return random.nextInt(); - case 3: - case 4: - return 0; - case 5: - return (int) (random.nextGaussian() * 2000) - 200; - default: - return (int) (random.nextGaussian() * 20) - 5; - } - } - - /** - * Get a random long. The algorithm is similar to a random int. - * - * @return the random value - */ - public long getRandomLong() { - switch (random.nextInt(10)) { - case 0: - return Long.MAX_VALUE; - case 1: - return Long.MIN_VALUE; - case 2: - return random.nextLong(); - case 3: - case 4: - return 0; - case 5: - return (int) (random.nextGaussian() * 20000) - 2000; - default: - return (int) (random.nextGaussian() * 200) - 50; - } - } - - /** - * Get a random double. The algorithm is similar to a random int. - * - * @return the random value - */ - public double getRandomDouble() { - switch (random.nextInt(10)) { - case 0: - return Double.MIN_VALUE; - case 1: - return Double.MAX_VALUE; - case 2: - return Float.MIN_VALUE; - case 3: - return Float.MAX_VALUE; - case 4: - return random.nextDouble(); - case 5: - case 6: - return 0; - case 7: - return random.nextGaussian() * 20000. - 2000.; - default: - return random.nextGaussian() * 200. - 50.; - } - } - - /** - * Get a random boolean. - * - * @return the random value - */ - public boolean nextBoolean() { - return random.nextBoolean(); - } - - /** - * Get a random integer array. In 10% of the cases, null is returned. - * - * @return the array - */ - public int[] getIntArray() { - switch (random.nextInt(10)) { - case 0: - return null; - default: - int len = getInt(100); - int[] list = new int[len]; - for (int i = 0; i < len; i++) { - list[i] = getRandomInt(); - } - return list; - } - } - - /** - * Get a random byte array. In 10% of the cases, null is returned. - * - * @return the array - */ - public byte[] getByteArray() { - switch (random.nextInt(10)) { - case 0: - return null; - default: - int len = getInt(100); - byte[] list = new byte[len]; - random.nextBytes(list); - return list; - } - } - - /** - * Get a random time value. In 10% of the cases, null is returned. - * - * @return the value - */ - public Time randomTime() { - if (random.nextInt(10) == 0) { - return null; - } - StringBuilder buff = new StringBuilder(); - buff.append(getInt(24)); - buff.append(':'); - buff.append(getInt(24)); - buff.append(':'); - buff.append(getInt(24)); - return Time.valueOf(buff.toString()); - - } - - /** - * Get a random timestamp value. In 10% of the cases, null is returned. - * - * @return the value - */ - public Timestamp randomTimestamp() { - if (random.nextInt(10) == 0) { - return null; - } - StringBuilder buff = new StringBuilder(); - buff.append(getInt(10) + 2000); - buff.append('-'); - int month = getInt(12) + 1; - if (month < 10) { - buff.append('0'); - } - buff.append(month); - buff.append('-'); - int day = getInt(28) + 1; - if (day < 10) { - buff.append('0'); - } - buff.append(day); - buff.append(' '); - int hour = getInt(24); - if (hour < 10) { - buff.append('0'); - } - buff.append(hour); - buff.append(':'); - int minute = getInt(60); - if (minute < 10) { - buff.append('0'); - } - buff.append(minute); - buff.append(':'); - int second = getInt(60); - if (second < 10) { - buff.append('0'); - } - buff.append(second); - // TODO test timestamp nanos - return Timestamp.valueOf(buff.toString()); - } - - /** - * Get a random date value. In 10% of the cases, null is returned. - * - * @return the value - */ - public Date randomDate() { - if (random.nextInt(10) == 0) { - return null; - } - StringBuilder buff = new StringBuilder(); - buff.append(getInt(10) + 2000); - buff.append('-'); - int month = getInt(12) + 1; - if (month < 10) { - buff.append('0'); - } - buff.append(month); - buff.append('-'); - int day = getInt(28) + 1; - if (day < 10) { - buff.append('0'); - } - buff.append(day); - return Date.valueOf(buff.toString()); - } - - /** - * Randomly modify a SQL statement. - * - * @param sql the original SQL statement - * @return the modified statement - */ - public String modify(String sql) { - int len = getLog(10); - for (int i = 0; i < len; i++) { - int pos = getInt(sql.length()); - if (getBoolean(50)) { - String badChars = "abcABCDEF\u00ef\u00f6\u00fcC1230=<>+\"\\*%&/()=?$_-.:,;{}[]"; - // auml, ouml, uuml - char bad = badChars.charAt(getInt(badChars.length())); - sql = sql.substring(0, pos) + bad + sql.substring(pos); - } else { - if (pos >= sql.length()) { - sql = sql.substring(0, pos); - } else { - sql = sql.substring(0, pos) + sql.substring(pos + 1); - } - } - } - return sql; - } - - /** - * Set the seed value. - * - * @param seed the new seed value - */ - public void setSeed(int seed) { - random.setSeed(seed); - } - -} diff --git a/tools/h2/src/test/org/h2/test/synth/sql/Result.java b/tools/h2/src/test/org/h2/test/synth/sql/Result.java deleted file mode 100755 index f0c0ff0..0000000 --- a/tools/h2/src/test/org/h2/test/synth/sql/Result.java +++ /dev/null @@ -1,152 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.test.synth.sql; - -import java.io.PrintWriter; -import java.io.StringWriter; -import java.sql.ResultSet; -import java.sql.ResultSetMetaData; -import java.sql.SQLException; -import java.util.ArrayList; -import java.util.Collections; - -import org.h2.test.TestBase; -import org.h2.util.New; - -/** - * Represents an in-memory result. - */ -class Result implements Comparable { - static final int SUCCESS = 0, BOOLEAN = 1, INT = 2, EXCEPTION = 3, RESULT_SET = 4; - - String sql; - - private int type; - private boolean bool; - private int intValue; - private SQLException exception; - private ArrayList rows; - private ArrayList header; - - Result(String sql) { - this.sql = sql; - type = SUCCESS; - } - - Result(String sql, SQLException e) { - this.sql = sql; - type = EXCEPTION; - exception = e; - } - - Result(String sql, boolean b) { - this.sql = sql; - type = BOOLEAN; - this.bool = b; - } - - Result(String sql, int i) { - this.sql = sql; - type = INT; - this.intValue = i; - } - - Result(TestSynth config, String sql, ResultSet rs) { - this.sql = sql; - type = RESULT_SET; - try { - rows = New.arrayList(); - header = New.arrayList(); - ResultSetMetaData meta = rs.getMetaData(); - int len = meta.getColumnCount(); - Column[] cols = new Column[len]; - for (int i = 0; i < len; i++) { - cols[i] = new Column(meta, i + 1); - } - while (rs.next()) { - Row row = new Row(config, rs, len); - rows.add(row); - } - Collections.sort(rows); - } catch (SQLException e) { - // type = EXCEPTION; - // exception = e; - TestBase.logError("error reading result set", e); - } - } - - public String toString() { - switch (type) { - case SUCCESS: - return "success"; - case BOOLEAN: - return "boolean: " + this.bool; - case INT: - return "int: " + this.intValue; - case EXCEPTION: { - StringWriter w = new StringWriter(); - exception.printStackTrace(new PrintWriter(w)); - return "exception: " + exception.getSQLState() + ": " + exception.getMessage() + "\r\n" + w.toString(); - } - case RESULT_SET: - String result = "ResultSet { // size=" + rows.size() + "\r\n "; - for (Column column : header) { - result += column.toString() + "; "; - } - result += "} = {\r\n"; - for (Row row : rows) { - result += " { " + row.toString() + "};\r\n"; - } - return result + "}"; - default: - throw new AssertionError("type=" + type); - } - } - - public int compareTo(Result r) { - switch (type) { - case EXCEPTION: - if (r.type != EXCEPTION) { - return 1; - } - return 0; - // return - // exception.getSQLState().compareTo(r.exception.getSQLState()); - case BOOLEAN: - case INT: - case SUCCESS: - case RESULT_SET: - return toString().compareTo(r.toString()); - default: - throw new AssertionError("type=" + type); - } - } - -// public void log() { -// switch (type) { -// case SUCCESS: -// System.out.println("> ok"); -// break; -// case EXCEPTION: -// System.out.println("> exception"); -// break; -// case INT: -// if (intValue == 0) { -// System.out.println("> ok"); -// } else { -// System.out.println("> update count: " + intValue); -// } -// break; -// case RESULT_SET: -// System.out.println("> rs " + rows.size()); -// break; -// default: -// } -// System.out.println(); -// } - -} diff --git a/tools/h2/src/test/org/h2/test/synth/sql/Row.java b/tools/h2/src/test/org/h2/test/synth/sql/Row.java deleted file mode 100755 index 272e6ad..0000000 --- a/tools/h2/src/test/org/h2/test/synth/sql/Row.java +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.test.synth.sql; - -import java.sql.ResultSet; -import java.sql.SQLException; - -/** - * Represents a row. - */ -class Row implements Comparable { - private Value[] data; - - public Row(TestSynth config, ResultSet rs, int len) throws SQLException { - data = new Value[len]; - for (int i = 0; i < len; i++) { - data[i] = Value.read(config, rs, i + 1); - } - } - - public String toString() { - String s = ""; - for (Object o : data) { - s += o == null ? "NULL" : o.toString(); - s += "; "; - } - return s; - } - - public int compareTo(Row r2) { - int result = 0; - for (int i = 0; i < data.length && result == 0; i++) { - Object o1 = data[i]; - Object o2 = r2.data[i]; - if (o1 == null) { - result = (o2 == null) ? 0 : -1; - } else if (o2 == null) { - result = 1; - } else { - result = o1.toString().compareTo(o2.toString()); - } - } - return result; - } - -} diff --git a/tools/h2/src/test/org/h2/test/synth/sql/Table.java b/tools/h2/src/test/org/h2/test/synth/sql/Table.java deleted file mode 100755 index 83e938d..0000000 --- a/tools/h2/src/test/org/h2/test/synth/sql/Table.java +++ /dev/null @@ -1,265 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.test.synth.sql; - -import java.util.ArrayList; -import org.h2.util.New; - -/** - * Represents a table. - */ -class Table { - private TestSynth config; - private String name; - private boolean temporary; - private boolean globalTemporary; - private Column[] columns; - private Column[] primaryKeys; - private ArrayList indexes = New.arrayList(); - - Table(TestSynth config) { - this.config = config; - } - - /** - * Create a new random table. - * - * @param config the configuration - * @return the table - */ - static Table newRandomTable(TestSynth config) { - Table table = new Table(config); - table.name = "T_" + config.randomIdentifier(); - - // there is a difference between local temp tables for persistent and - // in-memory mode - // table.temporary = config.random().getBoolean(10); - // if(table.temporary) { - // if(config.getMode() == TestSynth.H2_MEM) { - // table.globalTemporary = false; - // } else { - // table.globalTemporary = config.random().getBoolean(50); - // } - // } - - int len = config.random().getLog(10) + 1; - table.columns = new Column[len]; - for (int i = 0; i < len; i++) { - Column col = Column.getRandomColumn(config); - table.columns[i] = col; - } - if (config.random().getBoolean(90)) { - int pkLen = config.random().getLog(len); - table.primaryKeys = new Column[pkLen]; - for (int i = 0; i < pkLen; i++) { - Column pk = null; - do { - pk = table.columns[config.random().getInt(len)]; - } while (pk.getPrimaryKey()); - table.primaryKeys[i] = pk; - pk.setPrimaryKey(true); - pk.setNullable(false); - } - } - return table; - } - - /** - * Create a new random index. - * - * @return the index - */ - Index newRandomIndex() { - String indexName = "I_" + config.randomIdentifier(); - int len = config.random().getLog(getColumnCount() - 1) + 1; - boolean unique = config.random().getBoolean(50); - Column[] cols = getRandomColumns(len); - Index index = new Index(this, indexName, cols, unique); - return index; - } - - /** - * Get the DROP TABLE statement for this table. - * - * @return the SQL statement - */ - String getDropSQL() { - return "DROP TABLE " + name; - } - - /** - * Get the CREATE TABLE statement for this table. - * - * @return the SQL statement - */ - String getCreateSQL() { - String sql = "CREATE "; - if (temporary) { - if (globalTemporary) { - sql += "GLOBAL "; - } else { - sql += "LOCAL "; - } - sql += "TEMPORARY "; - } - sql += "TABLE " + name + "("; - for (int i = 0; i < columns.length; i++) { - if (i > 0) { - sql += ", "; - } - Column column = columns[i]; - sql += column.getCreateSQL(); - if (primaryKeys != null && primaryKeys.length == 1 && primaryKeys[0] == column) { - sql += " PRIMARY KEY"; - } - } - if (primaryKeys != null && primaryKeys.length > 1) { - sql += ", "; - sql += "PRIMARY KEY("; - for (int i = 0; i < primaryKeys.length; i++) { - if (i > 0) { - sql += ", "; - } - Column column = primaryKeys[i]; - sql += column.getName(); - } - sql += ")"; - } - sql += ")"; - return sql; - } - - /** - * Get the INSERT statement for this table. - * - * @param c the column list - * @param v the value list - * @return the SQL statement - */ - String getInsertSQL(Column[] c, Value[] v) { - String sql = "INSERT INTO " + name; - if (c != null) { - sql += "("; - for (int i = 0; i < c.length; i++) { - if (i > 0) { - sql += ", "; - } - sql += c[i].getName(); - } - sql += ")"; - } - sql += " VALUES("; - for (int i = 0; i < v.length; i++) { - if (i > 0) { - sql += ", "; - } - sql += v[i].getSQL(); - } - sql += ")"; - return sql; - } - - /** - * Get the table name. - * - * @return the name - */ - String getName() { - return name; - } - - /** - * Get a random column that can be used in a condition. - * - * @return the column - */ - Column getRandomConditionColumn() { - ArrayList list = New.arrayList(); - for (Column col : columns) { - if (Column.isConditionType(config, col.getType())) { - list.add(col); - } - } - if (list.size() == 0) { - return null; - } - return list.get(config.random().getInt(list.size())); - } - - Column getRandomColumn() { - return columns[config.random().getInt(columns.length)]; - } - - int getColumnCount() { - return columns.length; - } - - /** - * Get a random column of the specified type. - * - * @param type the type - * @return the column or null if no such column was found - */ - Column getRandomColumnOfType(int type) { - ArrayList list = New.arrayList(); - for (Column col : columns) { - if (col.getType() == type) { - list.add(col); - } - } - if (list.size() == 0) { - return null; - } - return list.get(config.random().getInt(list.size())); - } - - /** - * Get a number of random column from this table. - * - * @param len the column count - * @return the columns - */ - Column[] getRandomColumns(int len) { - int[] index = new int[columns.length]; - for (int i = 0; i < columns.length; i++) { - index[i] = i; - } - for (int i = 0; i < columns.length; i++) { - int temp = index[i]; - int r = index[config.random().getInt(columns.length)]; - index[i] = index[r]; - index[r] = temp; - } - Column[] c = new Column[len]; - for (int i = 0; i < len; i++) { - c[i] = columns[index[i]]; - } - return c; - } - - Column[] getColumns() { - return columns; - } - - /** - * Add this index to the table. - * - * @param index the index to add - */ - void addIndex(Index index) { - indexes.add(index); - } - - /** - * Remove an index from the table. - * - * @param index the index to remove - */ - void removeIndex(Index index) { - indexes.remove(index); - } -} diff --git a/tools/h2/src/test/org/h2/test/synth/sql/TestSynth.java b/tools/h2/src/test/org/h2/test/synth/sql/TestSynth.java deleted file mode 100755 index ad25ae1..0000000 --- a/tools/h2/src/test/org/h2/test/synth/sql/TestSynth.java +++ /dev/null @@ -1,340 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.test.synth.sql; - -import java.util.ArrayList; - -import org.h2.test.TestAll; -import org.h2.test.TestBase; -import org.h2.util.MathUtils; -import org.h2.util.New; - -/** - * A test that generates random SQL statements against a number of databases - * and compares the results. - */ -public class TestSynth extends TestBase { - - // TODO hsqldb: call 1||null should return 1 but returns null - // TODO hsqldb: call mod(1) should return invalid parameter count - - /** - * A H2 database connection. - */ - static final int H2 = 0; - - /** - * An in-memory H2 database connection. - */ - static final int H2_MEM = 1; - - /** - * An HSQLDB database connection. - */ - static final int HSQLDB = 2; - - /** - * A MySQL database connection. - */ - static final int MYSQL = 3; - - /** - * A PostgreSQL database connection. - */ - static final int POSTGRESQL = 4; - - private DbState dbState = new DbState(this); - private ArrayList databases; - private ArrayList commands; - private RandomGen random = new RandomGen(); - private boolean showError, showLog; - private boolean stopImmediately; - private int mode; - - /** - * Run just this test. - * - * @param a ignored - */ - public static void main(String... a) throws Exception { - TestBase.createCaller().init().test(); - } - - /** - * Check whether this database is of the specified type. - * - * @param isType the database type - * @return true if it is - */ - boolean is(int isType) { - return mode == isType; - } - - /** - * Get the random number generator. - * - * @return the random number generator - */ - RandomGen random() { - return random; - } - - /** - * Get a random identifier. - * - * @return the random identifier - */ - String randomIdentifier() { - int len = random.getLog(8) + 2; - while (true) { - return random.randomString(len); - } - } - - private void add(Command command) throws Exception { - command.run(dbState); - commands.add(command); - } - - private void addRandomCommands() throws Exception { - switch (random.getInt(20)) { - case 0: { - add(Command.getDisconnect(this)); - add(Command.getConnect(this)); - break; - } - case 1: { - Table table = Table.newRandomTable(this); - add(Command.getCreateTable(this, table)); - break; - } - case 2: { - Table table = randomTable(); - add(Command.getCreateIndex(this, table.newRandomIndex())); - break; - } - case 3: - case 4: - case 5: { - Table table = randomTable(); - add(Command.getRandomInsert(this, table)); - break; - } - case 6: - case 7: - case 8: { - Table table = randomTable(); - add(Command.getRandomUpdate(this, table)); - break; - } - case 9: - case 10: { - Table table = randomTable(); - add(Command.getRandomDelete(this, table)); - break; - } - default: { - Table table = randomTable(); - add(Command.getRandomSelect(this, table)); - } - } - } - - private void testRun(int seed) throws Exception { - random.setSeed(seed); - commands = New.arrayList(); - add(Command.getConnect(this)); - add(Command.getReset(this)); - - for (int i = 0; i < 1; i++) { - Table table = Table.newRandomTable(this); - add(Command.getCreateTable(this, table)); - add(Command.getCreateIndex(this, table.newRandomIndex())); - } - for (int i = 0; i < 2000; i++) { - addRandomCommands(); - } - // for (int i = 0; i < 20; i++) { - // Table table = randomTable(); - // add(Command.getRandomInsert(this, table)); - // } - // for (int i = 0; i < 100; i++) { - // Table table = randomTable(); - // add(Command.getRandomSelect(this, table)); - // } - // for (int i = 0; i < 10; i++) { - // Table table = randomTable(); - // add(Command.getRandomUpdate(this, table)); - // } - // for (int i = 0; i < 30; i++) { - // Table table = randomTable(); - // add(Command.getRandomSelect(this, table)); - // } - // for (int i = 0; i < 50; i++) { - // Table table = randomTable(); - // add(Command.getRandomDelete(this, table)); - // } - // for (int i = 0; i < 10; i++) { - // Table table = randomTable(); - // add(Command.getRandomSelect(this, table)); - // } - // while(true) { - // Table table = randomTable(); - // if(table == null) { - // break; - // } - // add(Command.getDropTable(this, table)); - // } - add(Command.getDisconnect(this)); - add(Command.getEnd(this)); - - for (int i = 0; i < commands.size(); i++) { - Command command = commands.get(i); - boolean stop = process(seed, i, command); - if (stop) { - break; - } - } - } - - private boolean process(int seed, int id, Command command) throws Exception { - try { - - ArrayList results = New.arrayList(); - for (int i = 0; i < databases.size(); i++) { - DbInterface db = databases.get(i); - Result result = command.run(db); - results.add(result); - if (showError && i == 0) { - // result.log(); - } - } - compareResults(results); - - } catch (Error e) { - if (showError) { - TestBase.logError("synth", e); - } - System.out.println("new TestSynth().init(test).testCase(" + seed + "); // id=" + id + " " + e.toString()); - if (stopImmediately) { - System.exit(0); - } - return true; - } - return false; - } - - private void compareResults(ArrayList results) { - Result original = results.get(0); - for (int i = 1; i < results.size(); i++) { - Result copy = results.get(i); - if (original.compareTo(copy) != 0) { - if (showError) { - throw new AssertionError("Results don't match: original (0): \r\n" + original + "\r\n" + "other:\r\n" + copy); - } - throw new AssertionError("Results don't match"); - } - } - } - - /** - * Get a random table. - * - * @return the table - */ - Table randomTable() { - return dbState.randomTable(); - } - - /** - * Print this message if the log is enabled. - * - * @param id the id - * @param s the message - */ - void log(int id, String s) { - if (showLog && id == 0) { - System.out.println(s); - } - } - - int getMode() { - return mode; - } - - private void addDatabase(String className, String url, String user, String password, boolean useSentinel) { - DbConnection db = new DbConnection(this, className, url, user, password, databases.size(), useSentinel); - databases.add(db); - } - - public TestBase init(TestAll conf) throws Exception { - super.init(conf); - deleteDb("synth/synth"); - databases = New.arrayList(); - - // mode = HSQLDB; - // addDatabase("org.hsqldb.jdbcDriver", "jdbc:hsqldb:test", "sa", "" ); - // addDatabase("org.h2.Driver", "jdbc:h2:synth;mode=hsqldb", "sa", ""); - - // mode = POSTGRESQL; - // addDatabase("org.postgresql.Driver", "jdbc:postgresql:test", "sa", - // "sa"); - // addDatabase("org.h2.Driver", "jdbc:h2:synth;mode=postgresql", "sa", - // ""); - - mode = H2_MEM; - org.h2.Driver.load(); - addDatabase("org.h2.Driver", "jdbc:h2:mem:synth", "sa", "", true); - addDatabase("org.h2.Driver", "jdbc:h2:" + getBaseDir() + "/synth/synth", "sa", "", false); - - // addDatabase("com.mysql.jdbc.Driver", "jdbc:mysql://localhost/test", - // "sa", ""); - // addDatabase("org.h2.Driver", "jdbc:h2:synth;mode=mysql", "sa", ""); - - // addDatabase("com.mysql.jdbc.Driver", "jdbc:mysql://localhost/test", - // "sa", ""); - // addDatabase("org.ldbc.jdbc.jdbcDriver", - // "jdbc:ldbc:mysql://localhost/test", "sa", ""); - // addDatabase("org.h2.Driver", "jdbc:h2:memFS:synth", "sa", ""); - - // MySQL: NOT is bound to column: NOT ID = 1 means (NOT ID) = 1 instead - // of NOT (ID=1) - for (int i = 0; i < databases.size(); i++) { - DbConnection conn = (DbConnection) databases.get(i); - System.out.println(i + " = " + conn.toString()); - } - showError = true; - showLog = false; - - // stopImmediately = true; - // showLog = true; - // testRun(110600); // id=27 java.lang.Error: results don't match: - // original (0): - // System.exit(0); - - return this; - } - - public void testCase(int seed) throws Exception { - deleteDb("synth/synth"); - try { - printTime("TestSynth " + seed); - testRun(seed); - } catch (Error e) { - TestBase.logError("error", e); - System.exit(0); - } - } - - public void test() throws Exception { - while (true) { - int seed = MathUtils.randomInt(Integer.MAX_VALUE); - testCase(seed); - } - } - -} diff --git a/tools/h2/src/test/org/h2/test/synth/sql/Value.java b/tools/h2/src/test/org/h2/test/synth/sql/Value.java deleted file mode 100755 index aa90168..0000000 --- a/tools/h2/src/test/org/h2/test/synth/sql/Value.java +++ /dev/null @@ -1,337 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.test.synth.sql; - -import java.math.BigDecimal; -import java.sql.Date; -import java.sql.ResultSet; -import java.sql.ResultSetMetaData; -import java.sql.SQLException; -import java.sql.Time; -import java.sql.Timestamp; -import java.sql.Types; - -import org.h2.value.DataType; - -/** - * Represents a simple value. - */ -public class Value { - private int type; - private Object data; - private TestSynth config; - - private Value(TestSynth config, int type, Object data) { - this.config = config; - this.type = type; - this.data = data; - } - - /** - * Convert the value to a SQL string. - * - * @return the SQL string - */ - String getSQL() { - if (data == null) { - return "NULL"; - } - switch (type) { - case Types.DECIMAL: - case Types.NUMERIC: - case Types.BIGINT: - case Types.INTEGER: - case Types.DOUBLE: - case Types.REAL: - return data.toString(); - case Types.CLOB: - case Types.VARCHAR: - case Types.CHAR: - case Types.OTHER: - case Types.LONGVARCHAR: - return "'" + data.toString() + "'"; - case Types.BLOB: - case Types.BINARY: - case Types.VARBINARY: - case Types.LONGVARBINARY: - return getBlobSQL(); - case Types.DATE: - return getDateSQL((Date) data); - case Types.TIME: - return getTimeSQL((Time) data); - case Types.TIMESTAMP: - return getTimestampSQL((Timestamp) data); - case DataType.TYPE_BOOLEAN: - case Types.BIT: - return (String) data; - default: - throw new AssertionError("type=" + type); - } - } - - private static Date randomDate(TestSynth config) { - return config.random().randomDate(); - - } - - private static Double randomDouble(TestSynth config) { - return new Double(config.random().getInt(100) / 10.); - } - - private static Long randomLong(TestSynth config) { - return new Long(config.random().getInt(1000)); - } - - private static Time randomTime(TestSynth config) { - return config.random().randomTime(); - } - - private static Timestamp randomTimestamp(TestSynth config) { - return config.random().randomTimestamp(); - } - - private String getTimestampSQL(Timestamp ts) { - String s = "'" + ts.toString() + "'"; - if (config.getMode() != TestSynth.HSQLDB) { - s = "TIMESTAMP " + s; - } - return s; - } - - private String getDateSQL(Date date) { - String s = "'" + date.toString() + "'"; - if (config.getMode() != TestSynth.HSQLDB) { - s = "DATE " + s; - } - return s; - } - - private String getTimeSQL(Time time) { - String s = "'" + time.toString() + "'"; - if (config.getMode() != TestSynth.HSQLDB) { - s = "TIME " + s; - } - return s; - } - - private String getBlobSQL() { - byte[] bytes = (byte[]) data; - // StringBuilder buff = new StringBuilder("X'"); - StringBuilder buff = new StringBuilder("'"); - for (byte b : bytes) { - int c = b & 0xff; - buff.append(Integer.toHexString(c >> 4 & 0xf)); - buff.append(Integer.toHexString(c & 0xf)); - - } - buff.append("'"); - return buff.toString(); - } - - /** - * Read a value from a result set. - * - * @param config the configuration - * @param rs the result set - * @param index the column index - * @return the value - */ - static Value read(TestSynth config, ResultSet rs, int index) throws SQLException { - ResultSetMetaData meta = rs.getMetaData(); - Object data; - int type = meta.getColumnType(index); - switch (type) { - case Types.REAL: - case Types.DOUBLE: - data = new Double(rs.getDouble(index)); - break; - case Types.BIGINT: - data = new Long(rs.getLong(index)); - break; - case Types.DECIMAL: - case Types.NUMERIC: - data = rs.getBigDecimal(index); - break; - case Types.BLOB: - case Types.BINARY: - case Types.VARBINARY: - case Types.LONGVARBINARY: - data = rs.getBytes(index); - break; - case Types.OTHER: - case Types.CLOB: - case Types.VARCHAR: - case Types.LONGVARCHAR: - case Types.CHAR: - data = rs.getString(index); - break; - case Types.DATE: - data = rs.getDate(index); - break; - case Types.TIME: - data = rs.getTime(index); - break; - case Types.TIMESTAMP: - data = rs.getTimestamp(index); - break; - case Types.INTEGER: - data = new Integer(rs.getInt(index)); - break; - case Types.NULL: - data = null; - break; - case DataType.TYPE_BOOLEAN: - case Types.BIT: - data = rs.getBoolean(index) ? "TRUE" : "FALSE"; - break; - default: - throw new AssertionError("type=" + type); - } - if (rs.wasNull()) { - data = null; - } - return new Value(config, type, data); - } - - /** - * Generate a random value. - * - * @param config the configuration - * @param type the value type - * @param precision the precision - * @param scale the scale - * @param mayBeNull if the value may be null or not - * @return the value - */ - static Value getRandom(TestSynth config, int type, int precision, int scale, boolean mayBeNull) { - Object data; - if (mayBeNull && config.random().getBoolean(20)) { - return new Value(config, type, null); - } - switch (type) { - case Types.BIGINT: - data = randomLong(config); - break; - case Types.DOUBLE: - data = randomDouble(config); - break; - case Types.DECIMAL: - data = randomDecimal(config, precision, scale); - break; - case Types.VARBINARY: - case Types.BINARY: - case Types.BLOB: - data = randomBytes(config, precision); - break; - case Types.CLOB: - case Types.VARCHAR: - data = config.random().randomString(config.random().getInt(precision)); - break; - case Types.DATE: - data = randomDate(config); - break; - case Types.TIME: - data = randomTime(config); - break; - case Types.TIMESTAMP: - data = randomTimestamp(config); - break; - case Types.INTEGER: - data = randomInt(config); - break; - case DataType.TYPE_BOOLEAN: - case Types.BIT: - data = config.random().getBoolean(50) ? "TRUE" : "FALSE"; - break; - default: - throw new AssertionError("type=" + type); - } - return new Value(config, type, data); - } - - private static Object randomInt(TestSynth config) { - int value; - if (config.is(TestSynth.POSTGRESQL)) { - value = config.random().getInt(1000000); - } else { - value = config.random().getRandomInt(); - } - return new Integer(value); - } - - private static byte[] randomBytes(TestSynth config, int max) { - int len = config.random().getLog(max); - byte[] data = new byte[len]; - config.random().getBytes(data); - return data; - } - - private static BigDecimal randomDecimal(TestSynth config, int precision, int scale) { - int len = config.random().getLog(precision - scale) + scale; - if (len == 0) { - len++; - } - StringBuilder buff = new StringBuilder(); - for (int i = 0; i < len; i++) { - buff.append((char) ('0' + config.random().getInt(10))); - } - buff.insert(len - scale, '.'); - if (config.random().getBoolean(20)) { - buff.insert(0, '-'); - } - return new BigDecimal(buff.toString()); - } - -// private int compareTo(Object o) { -// Value v = (Value) o; -// if (type != v.type) { -// throw new AssertionError("compare " + type + -// " " + v.type + " " + data + " " + v.data); -// } -// if (data == null) { -// return (v.data == null) ? 0 : -1; -// } else if (v.data == null) { -// return 1; -// } -// switch (type) { -// case Types.DECIMAL: -// return ((BigDecimal) data).compareTo((BigDecimal) v.data); -// case Types.BLOB: -// case Types.VARBINARY: -// case Types.BINARY: -// return compareBytes((byte[]) data, (byte[]) v.data); -// case Types.CLOB: -// case Types.VARCHAR: -// return data.toString().compareTo(v.data.toString()); -// case Types.DATE: -// return ((Date) data).compareTo((Date) v.data); -// case Types.INTEGER: -// return ((Integer) data).compareTo((Integer) v.data); -// default: -// throw new AssertionError("type=" + type); -// } -// } - -// private static int compareBytes(byte[] a, byte[] b) { -// int al = a.length, bl = b.length; -// int len = Math.min(al, bl); -// for (int i = 0; i < len; i++) { -// int x = a[i] & 0xff; -// int y = b[i] & 0xff; -// if (x == y) { -// continue; -// } -// return x > y ? 1 : -1; -// } -// return al == bl ? 0 : al > bl ? 1 : -1; -// } - - public String toString() { - return getSQL(); - } - -} diff --git a/tools/h2/src/test/org/h2/test/synth/sql/package.html b/tools/h2/src/test/org/h2/test/synth/sql/package.html deleted file mode 100755 index f50bd63..0000000 --- a/tools/h2/src/test/org/h2/test/synth/sql/package.html +++ /dev/null @@ -1,15 +0,0 @@ - - - - -Javadoc package documentation -

    - -A synthetic test using random SQL statements executed against multiple databases. - -

    \ No newline at end of file diff --git a/tools/h2/src/test/org/h2/test/synth/thread/TestMulti.java b/tools/h2/src/test/org/h2/test/synth/thread/TestMulti.java deleted file mode 100755 index bd29657..0000000 --- a/tools/h2/src/test/org/h2/test/synth/thread/TestMulti.java +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.test.synth.thread; - -import java.sql.Connection; -import java.sql.DriverManager; -import java.sql.SQLException; - -import org.h2.test.TestBase; - -/** - * Starts multiple threads and performs random operations on each thread. - */ -public class TestMulti extends TestBase { - - /** - * If set, the test should stop. - */ - public volatile boolean stop; - - /** - * Run just this test. - * - * @param a ignored - */ - public static void main(String... a) throws Exception { - TestBase.createCaller().init().test(); - } - - public void test() throws Exception { - org.h2.Driver.load(); - deleteDb("openClose"); - - // int len = getSize(5, 100); - int len = 10; - TestMultiThread[] threads = new TestMultiThread[len]; - for (int i = 0; i < len; i++) { - threads[i] = new TestMultiNews(this); - } - threads[0].first(); - for (int i = 0; i < len; i++) { - threads[i].start(); - } - Thread.sleep(10000); - this.stop = true; - for (int i = 0; i < len; i++) { - threads[i].join(); - } - threads[0].finalTest(); - } - - Connection getConnection() throws SQLException { - final String url = "jdbc:h2:" + getBaseDir() + "/openClose;LOCK_MODE=3;DB_CLOSE_DELAY=-1"; - Connection conn = DriverManager.getConnection(url, "sa", ""); - return conn; - } - -} diff --git a/tools/h2/src/test/org/h2/test/synth/thread/TestMultiNews.java b/tools/h2/src/test/org/h2/test/synth/thread/TestMultiNews.java deleted file mode 100755 index db23171..0000000 --- a/tools/h2/src/test/org/h2/test/synth/thread/TestMultiNews.java +++ /dev/null @@ -1,121 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.test.synth.thread; - -import java.sql.Connection; -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.sql.Statement; - -/** - * The operation part of {@link TestMulti}. - * Queries and updates a table. - */ -public class TestMultiNews extends TestMultiThread { - - private static final String PREFIX_URL = - "http://feeds.wizbangblog.com/WizbangFullFeed?m="; - - private int len = 10000; - private Connection conn; - - TestMultiNews(TestMulti base) throws SQLException { - super(base); - conn = base.getConnection(); - } - - void operation() throws SQLException { - if (random.nextInt(10) == 0) { - conn.close(); - conn = base.getConnection(); - } else if (random.nextInt(10) == 0) { - if (random.nextBoolean()) { - conn.commit(); - } else { - conn.rollback(); - } - } else if (random.nextInt(10) == 0) { - conn.setAutoCommit(random.nextBoolean()); - } else { - if (random.nextBoolean()) { - PreparedStatement prep; - if (random.nextBoolean()) { - prep = conn.prepareStatement("SELECT * FROM NEWS WHERE LINK = ?"); - } else { - prep = conn.prepareStatement("SELECT * FROM NEWS WHERE VALUE = ?"); - } - prep.setString(1, PREFIX_URL + random.nextInt(len)); - ResultSet rs = prep.executeQuery(); - if (!rs.next()) { - throw new SQLException("expected one row, got none"); - } - if (rs.next()) { - throw new SQLException("expected one row, got more"); - } - } else { - PreparedStatement prep = conn.prepareStatement("UPDATE NEWS SET STATE = ? WHERE FID = ?"); - prep.setInt(1, random.nextInt(100)); - prep.setInt(2, random.nextInt(len)); - int count = prep.executeUpdate(); - if (count != 1) { - throw new SQLException("expected one row, got " + count); - } - } - } - } - - void begin() { - // nothing to do - } - - void end() throws SQLException { - conn.close(); - } - - void finalTest() { - // nothing to do - } - - void first() throws SQLException { - Connection c = base.getConnection(); - Statement stat = c.createStatement(); - stat.execute("CREATE TABLE TEST (ID IDENTITY, NAME VARCHAR)"); - stat.execute("CREATE TABLE NEWS (FID NUMERIC(19) PRIMARY KEY, COMMENTS LONGVARCHAR, " - + "LINK VARCHAR(255), STATE INTEGER, VALUE VARCHAR(255))"); - stat.execute("CREATE INDEX IF NOT EXISTS NEWS_GUID_VALUE_INDEX ON NEWS(VALUE)"); - stat.execute("CREATE INDEX IF NOT EXISTS NEWS_LINK_INDEX ON NEWS(LINK)"); - stat.execute("CREATE INDEX IF NOT EXISTS NEWS_STATE_INDEX ON NEWS(STATE)"); - PreparedStatement prep = c.prepareStatement("INSERT INTO NEWS (FID, COMMENTS, LINK, STATE, VALUE) VALUES " - + "(?, ?, ?, ?, ?) "); - PreparedStatement prep2 = c.prepareStatement("INSERT INTO TEST (NAME) VALUES (?)"); - for (int i = 0; i < len; i++) { - int x = random.nextInt(10) * 128; - StringBuilder buff = new StringBuilder(); - while (buff.length() < x) { - buff.append("Test "); - buff.append(buff.length()); - buff.append(' '); - } - String comment = buff.toString(); - // FID - prep.setInt(1, i); - // COMMENTS - prep.setString(2, comment); - // LINK - prep.setString(3, PREFIX_URL + i); - // STATE - prep.setInt(4, 0); - // VALUE - prep.setString(5, PREFIX_URL + i); - prep.execute(); - prep2.setString(1, comment); - prep2.execute(); - } - } - -} diff --git a/tools/h2/src/test/org/h2/test/synth/thread/TestMultiNewsSimple.java b/tools/h2/src/test/org/h2/test/synth/thread/TestMultiNewsSimple.java deleted file mode 100755 index 0d720cc..0000000 --- a/tools/h2/src/test/org/h2/test/synth/thread/TestMultiNewsSimple.java +++ /dev/null @@ -1,87 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.test.synth.thread; - -import java.sql.Connection; -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.SQLException; - -/** - * The operation part of {@link TestMulti}. - * Executes simple queries and updates in a table. - */ -public class TestMultiNewsSimple extends TestMultiThread { - - private static int newsCount = 10000; - - private Connection conn; - - TestMultiNewsSimple(TestMulti base) throws SQLException { - super(base); - conn = base.getConnection(); - } - - private static int getNewsCount() { - return newsCount; - } - - void first() throws SQLException { - Connection c = base.getConnection(); - c.createStatement().execute("create table news(id identity, state int default 0, text varchar default '')"); - PreparedStatement prep = c.prepareStatement("insert into news() values()"); - for (int i = 0; i < newsCount; i++) { - prep.executeUpdate(); - } - c.createStatement().execute("update news set text = 'Text' || id"); - c.close(); - } - - void begin() { - // nothing to do - } - - void end() throws SQLException { - conn.close(); - } - - void operation() throws SQLException { - if (random.nextInt(10) == 0) { - conn.setAutoCommit(random.nextBoolean()); - } else if (random.nextInt(10) == 0) { - if (random.nextBoolean()) { - conn.commit(); - } else { - // conn.rollback(); - } - } else { - if (random.nextBoolean()) { - PreparedStatement prep = conn.prepareStatement("update news set state = ? where id = ?"); - prep.setInt(1, random.nextInt(getNewsCount())); - prep.setInt(2, random.nextInt(10)); - prep.execute(); - } else { - PreparedStatement prep = conn.prepareStatement("select * from news where id = ?"); - prep.setInt(1, random.nextInt(getNewsCount())); - ResultSet rs = prep.executeQuery(); - if (!rs.next()) { - System.out.println("No row found"); - // throw new AssertionError("No row found"); - } - if (rs.next()) { - System.out.println("Multiple rows found"); - // throw new AssertionError("Multiple rows found"); - } - } - } - } - - void finalTest() { - // nothing to do - } - -} diff --git a/tools/h2/src/test/org/h2/test/synth/thread/TestMultiOrder.java b/tools/h2/src/test/org/h2/test/synth/thread/TestMultiOrder.java deleted file mode 100755 index 78a82e4..0000000 --- a/tools/h2/src/test/org/h2/test/synth/thread/TestMultiOrder.java +++ /dev/null @@ -1,150 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.test.synth.thread; - -import java.math.BigDecimal; -import java.sql.Connection; -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.util.Random; - -/** - * The operation part of {@link TestMulti}. - * Queries and updates two tables. - */ -public class TestMultiOrder extends TestMultiThread { - - private static int customerCount; - private static int orderCount; - private static int orderLineCount; - - private static final String[] ITEMS = { "Apples", "Oranges", "Bananas", "Coffee" }; - - private Connection conn; - private PreparedStatement insertLine; - - TestMultiOrder(TestMulti base) throws SQLException { - super(base); - conn = base.getConnection(); - } - - void begin() throws SQLException { - insertLine = conn.prepareStatement("insert into orderLine(order_id, line_id, text, amount) values(?, ?, ?, ?)"); - insertCustomer(); - } - - void end() throws SQLException { - conn.close(); - } - - void operation() throws SQLException { - if (random.nextInt(10) == 0) { - insertCustomer(); - } else { - insertOrder(); - } - } - - private void insertOrder() throws SQLException { - PreparedStatement prep = conn.prepareStatement("insert into orders(customer_id , total) values(?, ?)"); - prep.setInt(1, random.nextInt(getCustomerCount())); - BigDecimal total = new BigDecimal("0"); - prep.setBigDecimal(2, total); - prep.executeUpdate(); - ResultSet rs = prep.getGeneratedKeys(); - rs.next(); - int orderId = rs.getInt(1); - int lines = random.nextInt(20); - for (int i = 0; i < lines; i++) { - insertLine.setInt(1, orderId); - insertLine.setInt(2, i); - insertLine.setString(3, ITEMS[random.nextInt(ITEMS.length)]); - BigDecimal amount = new BigDecimal(random.nextInt(100) + "." + random.nextInt(10)); - insertLine.setBigDecimal(4, amount); - total = total.add(amount); - insertLine.addBatch(); - } - insertLine.executeBatch(); - increaseOrderLines(lines); - prep = conn.prepareStatement("update orders set total = ? where id = ?"); - prep.setBigDecimal(1, total); - prep.setInt(2, orderId); - increaseOrders(); - prep.execute(); - } - - private void insertCustomer() throws SQLException { - PreparedStatement prep = conn.prepareStatement("insert into customer(id, name) values(?, ?)"); - int customerId = getNextCustomerId(); - prep.setInt(1, customerId); - prep.setString(2, getString(customerId)); - prep.execute(); - } - - private String getString(int id) { - StringBuilder buff = new StringBuilder(); - Random rnd = new Random(id); - int len = rnd.nextInt(40); - for (int i = 0; i < len; i++) { - String s = "bcdfghklmnprstwz"; - char c = s.charAt(rnd.nextInt(s.length())); - buff.append(i == 0 ? Character.toUpperCase(c) : c); - s = "aeiou "; - - buff.append(s.charAt(rnd.nextInt(s.length()))); - } - return buff.toString(); - } - - private synchronized int getNextCustomerId() { - return customerCount++; - } - - private synchronized int increaseOrders() { - return orderCount++; - } - - private synchronized int increaseOrderLines(int count) { - return orderLineCount += count; - } - - private int getCustomerCount() { - return customerCount; - } - - void first() throws SQLException { - Connection c = base.getConnection(); - c.createStatement().execute("drop table customer if exists"); - c.createStatement().execute("drop table orders if exists"); - c.createStatement().execute("drop table orderLine if exists"); - c.createStatement().execute("create table customer(id int primary key, name varchar, account decimal)"); - c.createStatement().execute("create table orders(id int identity primary key, customer_id int, total decimal)"); - c.createStatement().execute("create table orderLine(order_id int, line_id int, text varchar, amount decimal, primary key(order_id, line_id))"); - c.close(); - } - - void finalTest() throws SQLException { - conn = base.getConnection(); - ResultSet rs = conn.createStatement().executeQuery("select count(*) from customer"); - rs.next(); - base.assertEquals(customerCount, rs.getInt(1)); - // System.out.println("customers: " + rs.getInt(1)); - - rs = conn.createStatement().executeQuery("select count(*) from orders"); - rs.next(); - base.assertEquals(orderCount, rs.getInt(1)); - // System.out.println("orders: " + rs.getInt(1)); - - rs = conn.createStatement().executeQuery("select count(*) from orderLine"); - rs.next(); - base.assertEquals(orderLineCount, rs.getInt(1)); - // System.out.println("orderLines: " + rs.getInt(1)); - - conn.close(); - } -} diff --git a/tools/h2/src/test/org/h2/test/synth/thread/TestMultiThread.java b/tools/h2/src/test/org/h2/test/synth/thread/TestMultiThread.java deleted file mode 100755 index f58282c..0000000 --- a/tools/h2/src/test/org/h2/test/synth/thread/TestMultiThread.java +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.test.synth.thread; - -import java.sql.SQLException; -import java.util.Random; - -import org.h2.test.TestBase; - -/** - * The is an abstract operation for {@link TestMulti}. - */ -abstract class TestMultiThread extends Thread { - - /** - * The base object. - */ - TestMulti base; - - /** - * The random number generator. - */ - Random random = new Random(); - - TestMultiThread(TestMulti base) { - this.base = base; - } - - /** - * Execute statements that need to be executed before starting the thread. - * This includes CREATE TABLE statements. - */ - abstract void first() throws SQLException; - - /** - * The main operation to perform. This method is called in a loop. - */ - abstract void operation() throws SQLException; - - /** - * Execute statements before entering the loop, but after starting the - * thread. - */ - abstract void begin() throws SQLException; - - /** - * This method is called once after the test is stopped. - */ - abstract void end() throws SQLException; - - /** - * This method is called once after all threads have been stopped. - * @throws SQLException - */ - abstract void finalTest() throws SQLException; - - public void run() { - try { - begin(); - while (!base.stop) { - operation(); - } - end(); - } catch (Throwable e) { - TestBase.logError("error", e); - } - } - -} diff --git a/tools/h2/src/test/org/h2/test/synth/thread/package.html b/tools/h2/src/test/org/h2/test/synth/thread/package.html deleted file mode 100755 index 4f08177..0000000 --- a/tools/h2/src/test/org/h2/test/synth/thread/package.html +++ /dev/null @@ -1,15 +0,0 @@ - - - - -Javadoc package documentation -

    - -Synthetic tests using random operations in multiple threads. - -

    \ No newline at end of file diff --git a/tools/h2/src/test/org/h2/test/test-1.2.txt b/tools/h2/src/test/org/h2/test/test-1.2.txt deleted file mode 100755 index 46bf3be..0000000 --- a/tools/h2/src/test/org/h2/test/test-1.2.txt +++ /dev/null @@ -1,9363 +0,0 @@ ---- special grammar and test cases --------------------------------------------------------------------------------------------- -select * from (select null as x) where x=1; -> X -> - -> rows: 0 - -create table test(a int primary key, b int references(a)); -> ok - -merge into test values(1, 2); -> exception - -drop table test; -> ok - -create table test(id int primary key, d int); -> ok - -insert into test values(1,1), (2, 1); -> update count: 2 - -select id from test where id in (1, 2) and d = 1; -> ID -> -- -> 1 -> 2 -> rows: 2 - -drop table test; -> ok - -create table test(id decimal(10, 2) primary key) as select 0; -> ok - -select * from test where id = 0.00; -> ID -> ---- -> 0.00 -> rows: 1 - -select * from test where id = 0.0; -> ID -> ---- -> 0.00 -> rows: 1 - -drop table test; -> ok - -select count(*) from (select 1 union (select 2 intersect select 2)) x; -> COUNT(*) -> -------- -> 2 -> rows: 1 - -create table test(id varchar(1) primary key) as select 'X'; -> ok - -select count(*) from (select 1 from dual where x in ((select 1 union select 1))) a; -> COUNT(*) -> -------- -> 1 -> rows: 1 - -insert into test ((select 1 union select 2) union select 3); -> update count: 3 - -select count(*) from test where id = 'X1'; -> COUNT(*) -> -------- -> 0 -> rows: 1 - -drop table test; -> ok - -create table test(id int primary key, name varchar(255), x int); -> ok - -create unique index idx_name1 on test(name); -> ok - -create unique index idx_name2 on test(name); -> ok - -show columns from test; -> FIELD TYPE NULL KEY DEFAULT -> ----- ------------ ---- --- ------- -> ID INTEGER(10) NO PRI NULL -> NAME VARCHAR(255) YES UNI NULL -> X INTEGER(10) YES NULL -> rows: 3 - -drop table test; -> ok - -create table a(a int) as select 1; -> ok - -create table b(b int) as select 1; -> ok - -create table c(c int) as select x from system_range(1, 2); -> ok - -select * from a inner join b on a=b right outer join c on c=a; -> C A B -> - ---- ---- -> 1 1 1 -> 2 null null -> rows: 2 - -select * from c left outer join (a inner join b on b=a) on c=a; -> C A B -> - ---- ---- -> 1 1 1 -> 2 null null -> rows: 2 - -select * from c left outer join a on c=a inner join b on b=a; -> C A B -> - - - -> 1 1 1 -> rows: 1 - -drop table a, b, c; -> ok - -create table test(a int, b int) as select x, x from system_range(1, 100); -> ok - --- the table t1 should be processed first -explain select * from test t2, test t1 where t1.a=1 and t1.b = t2.b; -> PLAN -> -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -> SELECT T2.A, T2.B, T1.A, T1.B FROM PUBLIC.TEST T1 /* PUBLIC.TEST.tableScan */ /* WHERE T1.A = 1 */ INNER JOIN PUBLIC.TEST T2 /* PUBLIC.TEST.tableScan */ ON 1=1 WHERE (T1.A = 1) AND (T1.B = T2.B) -> rows: 1 - -explain select * from test t1, test t2 where t1.a=1 and t1.b = t2.b; -> PLAN -> -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -> SELECT T1.A, T1.B, T2.A, T2.B FROM PUBLIC.TEST T1 /* PUBLIC.TEST.tableScan */ /* WHERE T1.A = 1 */ INNER JOIN PUBLIC.TEST T2 /* PUBLIC.TEST.tableScan */ ON 1=1 WHERE (T1.A = 1) AND (T1.B = T2.B) -> rows: 1 - -drop table test; -> ok - -create table test(id int, constraint pk primary key(id), constraint x unique(id)); -> ok - -select constraint_name from information_schema.indexes where table_name = 'TEST'; -> CONSTRAINT_NAME -> --------------- -> PK -> rows: 1 - -drop table test; -> ok - -create table parent(id int primary key); -> ok - -create table child(id int, parent_id int, constraint child_parent foreign key (parent_id) references parent(id)); -> ok - -select constraint_name from information_schema.indexes where table_name = 'CHILD'; -> CONSTRAINT_NAME -> --------------- -> CHILD_PARENT -> rows: 1 - -drop table parent, child; -> ok - -create table test(id int, name varchar); -> ok - -alter table test alter column id identity; -> ok - -drop table test; -> ok - -create table test(id int primary key, name varchar); -> ok - -alter table test alter column id int auto_increment; -> ok - -drop table test; -> ok - -create table test(id identity) as select x from system_range(1, 4); -> ok - -select a.id from test a inner join test b on a.id > b.id and b.id < 3 group by a.id; -> ID -> -- -> 2 -> 3 -> 4 -> rows: 3 - -drop table test; -> ok - -create table test(id identity); -> ok - -set password test; -> exception - -alter user sa set password test; -> exception - -comment on table test is test; -> exception - -select 1 from test a where 1 in(select 1 from test b where b.id in(select 1 from test c where c.id=a.id)); -> 1 -> - -> rows: 0 - -drop table test; -> ok - -select @n := case when x = 1 then 1 else @n * x end f from system_range(1, 4); -> F -> -- -> 1 -> 2 -> 24 -> 6 -> rows: 4 - -select * from (select "x" from dual); -> exception - -select * from(select 1 from system_range(1, 2) group by sin(x) order by sin(x)); -> 1 -> - -> 1 -> 1 -> rows (ordered): 2 - -create table parent as select 1 id, 2 x; -> ok - -create table child(id int references parent(id)) as select 1; -> ok - -delete from parent; -> exception - -drop table parent, child; -> ok - -create domain integer as varchar; -> exception - -create domain int as varchar; -> ok - -create memory table test(id int); -> ok - -script nodata nopasswords nosettings; -> SCRIPT -> -------------------------------------------------- -> -- 0 +/- SELECT COUNT(*) FROM PUBLIC.TEST; -> CREATE DOMAIN INT AS VARCHAR; -> CREATE MEMORY TABLE PUBLIC.TEST( ID VARCHAR ); -> CREATE USER IF NOT EXISTS SA PASSWORD '' ADMIN; -> rows: 4 - -drop table test; -> ok - -drop domain int; -> ok - -create table test(id identity, parent bigint, foreign key(parent) references(id)); -> ok - -insert into test values(0, 0), (1, NULL), (2, 1), (3, 3), (4, 3); -> update count: 5 - -delete from test where id = 3; -> exception - -delete from test where id = 0; -> update count: 1 - -delete from test where id = 1; -> exception - -drop table test; -> ok - -select iso_week('2006-12-31') w, iso_year('2007-12-31') y, iso_day_of_week('2007-12-31') w; -> W Y W -> -- ---- - -> 52 2008 1 -> rows: 1 - -create schema a; -> ok - -set autocommit false; -> ok - -set schema a; -> ok - -create table t1 ( k int, v varchar(10) ); -> ok - -insert into t1 values ( 1, 't1' ); -> update count: 1 - -create table t2 ( k int, v varchar(10) ); -> ok - -insert into t2 values ( 2, 't2' ); -> update count: 1 - -create view v_test(a, b, c, d) as select t1.*, t2.* from t1 join t2 on ( t1.k = t2.k ); -> ok - -select * from v_test; -> A B C D -> - - - - -> rows: 0 - -set schema public; -> ok - -drop schema a; -> ok - -set autocommit true; -> ok - -select x/3 as a, count(*) c from system_range(1, 10) group by a having c>2; -> A C -> - - -> 1 3 -> 2 3 -> rows: 2 - -create table test(id int); -> ok - -insert into test values(1), (2); -> update count: 2 - -select id+1 as x, count(*) from test group by x; -> X COUNT(*) -> - -------- -> 2 1 -> 3 1 -> rows: 2 - -select 1 as id, id as b, count(*) from test group by id; -> ID B COUNT(*) -> -- - -------- -> 1 1 1 -> 1 2 1 -> rows: 2 - -select id+1 as x, count(*) from test group by -x; -> exception - -select id+1 as x, count(*) from test group by x having x>2; -> exception - -select id+1 as x, count(*) from test group by 1; -> exception - -drop table test; -> ok - -create table test(t0 timestamp(0), t1 timestamp(1), t4 timestamp(4)); -> ok - -select column_name, numeric_scale from information_schema.columns c where c.table_name = 'TEST' order by column_name; -> COLUMN_NAME NUMERIC_SCALE -> ----------- ------------- -> T0 0 -> T1 1 -> T4 4 -> rows (ordered): 3 - -drop table test; -> ok - -create table test(id int); -> ok - -insert into test values(null), (1); -> update count: 2 - -select * from test where id not in (select id from test where 1=0); -> ID -> ---- -> 1 -> null -> rows: 2 - -select * from test where null not in (select id from test where 1=0); -> ID -> ---- -> 1 -> null -> rows: 2 - -select * from test where not (id in (select id from test where 1=0)); -> ID -> ---- -> 1 -> null -> rows: 2 - -select * from test where not (null in (select id from test where 1=0)); -> ID -> ---- -> 1 -> null -> rows: 2 - -drop table test; -> ok - -create table test(a int); -> ok - -insert into test values(1), (2); -> update count: 2 - -select -test.a a from test order by test.a; -> A -> -- -> -1 -> -2 -> rows (ordered): 2 - -select -test.a from test order by test.a; -> - TEST.A -> -------- -> -1 -> -2 -> rows (ordered): 2 - -select -test.a aa from test order by a; -> AA -> -- -> -1 -> -2 -> rows (ordered): 2 - -select -test.a aa from test order by aa; -> AA -> -- -> -2 -> -1 -> rows (ordered): 2 - -select -test.a a from test order by a; -> A -> -- -> -2 -> -1 -> rows (ordered): 2 - -drop table test; -> ok - -CREATE TABLE table_a(a_id INT PRIMARY KEY, left_id INT, right_id INT); -> ok - -CREATE TABLE table_b(b_id INT PRIMARY KEY, a_id INT); -> ok - -CREATE TABLE table_c(left_id INT, right_id INT, center_id INT); -> ok - -CREATE VIEW view_a AS -SELECT table_c.center_id, table_a.a_id, table_b.b_id -FROM table_c -INNER JOIN table_a ON table_c.left_id = table_a.left_id -AND table_c.right_id = table_a.right_id -LEFT JOIN table_b ON table_b.a_id = table_a.a_id; -> ok - -SELECT * FROM table_c INNER JOIN view_a -ON table_c.center_id = view_a.center_id; -> LEFT_ID RIGHT_ID CENTER_ID CENTER_ID A_ID B_ID -> ------- -------- --------- --------- ---- ---- -> rows: 0 - -drop view view_a; -> ok - -drop table table_a, table_b, table_c; -> ok - -create table t (pk int primary key, attr int); -> ok - -insert into t values (1, 5), (5, 1); -> update count: 2 - -select t1.pk from t t1, t t2 where t1.pk = t2.attr order by t1.pk; -> PK -> -- -> 1 -> 5 -> rows (ordered): 2 - -drop table t; -> ok - -CREATE TABLE T(A NULL); -> exception - -CREATE TABLE T(A INT); -> ok - -ALTER TABLE T ALTER COLUMN A NULL; -> exception - -DROP TABLE T; -> ok - -CREATE ROLE TEST_A; -> ok - -GRANT TEST_A TO TEST_A; -> exception - -CREATE ROLE TEST_B; -> ok - -GRANT TEST_A TO TEST_B; -> ok - -GRANT TEST_B TO TEST_A; -> exception - -DROP ROLE TEST_A; -> ok - -DROP ROLE TEST_B; -> ok - -CREATE ROLE PUBLIC2; -> ok - -GRANT PUBLIC2 TO SA; -> ok - -GRANT PUBLIC2 TO SA; -> ok - -REVOKE PUBLIC2 FROM SA; -> ok - -REVOKE PUBLIC2 FROM SA; -> ok - -DROP ROLE PUBLIC2; -> ok - -create table test(id int primary key, lastname varchar, firstname varchar, parent int references(id)); -> ok - -alter table test add constraint name unique (lastname, firstname); -> ok - -SELECT CONSTRAINT_NAME, UNIQUE_INDEX_NAME, COLUMN_LIST FROM INFORMATION_SCHEMA.CONSTRAINTS ; -> CONSTRAINT_NAME UNIQUE_INDEX_NAME COLUMN_LIST -> --------------- ----------------- ------------------ -> CONSTRAINT_2 PRIMARY_KEY_2 ID -> CONSTRAINT_27 PRIMARY_KEY_2 PARENT -> NAME NAME_INDEX_2 LASTNAME,FIRSTNAME -> rows: 3 - -drop table test; -> ok - -alter table information_schema.help rename to information_schema.help2; -> exception - -help abc; -> ID SECTION TOPIC SYNTAX TEXT -> -- ------- ----- ------ ---- -> rows: 0 - -CREATE TABLE test (id int(25) NOT NULL auto_increment, name varchar NOT NULL, PRIMARY KEY (id,name)); -> ok - -drop table test; -> ok - -CREATE MEMORY TABLE TEST(ID INT, D DOUBLE, F FLOAT); -> ok - -insert into test values(0, POWER(0, -1), POWER(0, -1)), (1, -POWER(0, -1), -POWER(0, -1)), (2, SQRT(-1), SQRT(-1)); -> update count: 3 - -select * from test order by id; -> ID D F -> -- --------- --------- -> 0 Infinity Infinity -> 1 -Infinity -Infinity -> 2 NaN NaN -> rows (ordered): 3 - -script nopasswords nosettings; -> SCRIPT -> ----------------------------------------------------------------------------------------------------------------------------------------- -> -- 3 +/- SELECT COUNT(*) FROM PUBLIC.TEST; -> CREATE MEMORY TABLE PUBLIC.TEST( ID INT, D DOUBLE, F FLOAT ); -> CREATE USER IF NOT EXISTS SA PASSWORD '' ADMIN; -> INSERT INTO PUBLIC.TEST(ID, D, F) VALUES (0, POWER(0, -1), POWER(0, -1)), (1, (-POWER(0, -1)), (-POWER(0, -1))), (2, SQRT(-1), SQRT(-1)); -> rows: 4 - -DROP TABLE TEST; -> ok - -create schema a; -> ok - -create table a.x(ax int); -> ok - -create schema b; -> ok - -create table b.x(bx int); -> ok - -select * from a.x, b.x; -> AX BX -> -- -- -> rows: 0 - -drop schema a; -> ok - -drop schema b; -> ok - -create table t1 (id int primary key); -> ok - -create table t2 (id int primary key); -> ok - -insert into t1 select x from system_range(1, 1000); -> update count: 1000 - -insert into t2 select x from system_range(1, 1000); -> update count: 1000 - -explain select count(*) from t1 where t1.id in ( select t2.id from t2 ); -> PLAN -> ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -> SELECT COUNT(*) FROM PUBLIC.T1 /* PUBLIC.PRIMARY_KEY_A: ID IN(SELECT DISTINCT T2.ID FROM PUBLIC.T2 /++ PUBLIC.T2.tableScan ++/) */ WHERE T1.ID IN(SELECT DISTINCT T2.ID FROM PUBLIC.T2 /* PUBLIC.T2.tableScan */) -> rows: 1 - -select count(*) from t1 where t1.id in ( select t2.id from t2 ); -> COUNT(*) -> -------- -> 1000 -> rows: 1 - -drop table t1, t2; -> ok - -select * from system_range(1, 3) t1 inner join system_range(2, 3) t2 inner join system_range(1, 2) t3 on t3.x=t2.x on t1.x=t2.x; -> X X X -> - - - -> 2 2 2 -> rows: 1 - -CREATE TABLE p(d date); -> ok - -INSERT INTO p VALUES('-1-01-01'), ('0-01-01'), ('0001-01-01'); -> update count: 3 - -select d, year(d), extract(year from d), cast(d as timestamp) from p; -> D YEAR(D) EXTRACT(YEAR FROM D) CAST(D AS TIMESTAMP) -> ---------- ------- -------------------- --------------------- -> -1-01-01 -1 -1 -1-01-01 00:00:00.0 -> 0-01-01 0 0 0-01-01 00:00:00.0 -> 0001-01-01 1 1 0001-01-01 00:00:00.0 -> rows: 3 - -drop table p; -> ok - -(SELECT X FROM DUAL ORDER BY X+2) UNION SELECT X FROM DUAL; -> X -> - -> 1 -> 1 -> rows (ordered): 2 - -create table test(a int, b int default 1); -> ok - -insert into test values(1, default), (2, 2), (3, null); -> update count: 3 - -select * from test; -> A B -> - ---- -> 1 1 -> 2 2 -> 3 null -> rows: 3 - -update test set b = default where a = 2; -> update count: 1 - -explain update test set b = default where a = 2; -> PLAN -> -------------------------------------------------------------------------- -> UPDATE PUBLIC.TEST /* PUBLIC.TEST.tableScan */ SET B = DEFAULT WHERE A = 2 -> rows: 1 - -select * from test; -> A B -> - ---- -> 1 1 -> 2 1 -> 3 null -> rows: 3 - -update test set a=default; -> update count: 3 - -drop table test; -> ok - -CREATE ROLE X; -> ok - -GRANT X TO X; -> exception - -CREATE ROLE Y; -> ok - -GRANT Y TO X; -> ok - -DROP ROLE Y; -> ok - -DROP ROLE X; -> ok - -create table test as select * from table(id int=(1, 2, 3)); -> ok - -SELECT * FROM (SELECT * FROM TEST) ORDER BY id; -> ID -> -- -> 1 -> 2 -> 3 -> rows (ordered): 3 - -SELECT * FROM (SELECT * FROM TEST) x ORDER BY id; -> ID -> -- -> 1 -> 2 -> 3 -> rows (ordered): 3 - -drop table test; -> ok - -select top sum(1) 0 from dual; -> exception - -create table test(id int primary key, name varchar) as select 1, 'Hello World'; -> ok - -select * from test; -> ID NAME -> -- ----------- -> 1 Hello World -> rows: 1 - -drop table test; -> ok - -select rtrim() from dual; -> exception - -CREATE TABLE COUNT(X INT); -> ok - -CREATE FORCE TRIGGER T_COUNT BEFORE INSERT ON COUNT CALL "com.Unknown"; -> ok - -INSERT INTO COUNT VALUES(NULL); -> exception - -DROP TRIGGER T_COUNT; -> ok - -CREATE TABLE ITEMS(ID INT CHECK ID < SELECT MAX(ID) FROM COUNT); -> ok - -insert into items values(DEFAULT); -> update count: 1 - -DROP TABLE COUNT; -> exception - -insert into items values(DEFAULT); -> update count: 1 - -drop table items, count; -> ok - -CREATE TABLE TEST(ID INT PRIMARY KEY, LABEL CHAR(20), LOOKUP CHAR(30)); -> ok - -INSERT INTO TEST VALUES (1, 'Mouse', 'MOUSE'), (2, 'MOUSE', 'Mouse'); -> update count: 2 - -SELECT * FROM TEST; -> ID LABEL LOOKUP -> -- ----- ------ -> 1 Mouse MOUSE -> 2 MOUSE Mouse -> rows: 2 - -DROP TABLE TEST; -> ok - -call 'a' regexp '\Ho.*'; -> exception - -set @t = 0; -> ok - -call set(1, 2); -> exception - -select x, set(@t, ifnull(@t, 0) + x) from system_range(1, 3); -> X SET(@T, (IFNULL(@T, 0) + X)) -> - ---------------------------- -> 1 1 -> 2 3 -> 3 6 -> rows: 3 - -select * from system_range(1, 2) a, -(select * from system_range(1, 2) union select * from system_range(1, 2) -union select * from system_range(1, 1)) v where a.x = v.x; -> X X -> - - -> 1 1 -> 2 2 -> rows: 2 - -create table test(id int); -> ok - -select * from ((select * from test) union (select * from test)) where id = 0; -> ID -> -- -> rows: 0 - -select * from ((test d1 inner join test d2 on d1.id = d2.id) inner join test d3 on d1.id = d3.id) inner join test d4 on d4.id = d1.id; -> ID ID ID ID -> -- -- -- -- -> rows: 0 - -select * from dual a left join dual b on b.x=(select max(x) from dual); -> exception - -drop table test; -> ok - -select count(*) from system_range(1, 2) where x in(1, 1, 1); -> COUNT(*) -> -------- -> 1 -> rows: 1 - -create table person(id bigint auto_increment, name varchar(100)); -> ok - -insert into person(name) values ('a'), ('b'), ('c'); -> update count: 3 - -select * from person order by id; -> ID NAME -> -- ---- -> 1 a -> 2 b -> 3 c -> rows (ordered): 3 - -select * from person order by id limit 2; -> ID NAME -> -- ---- -> 1 a -> 2 b -> rows (ordered): 2 - -select * from person order by id limit 2 offset 1; -> ID NAME -> -- ---- -> 2 b -> 3 c -> rows (ordered): 2 - -select * from person order by id limit 2147483647 offset 1; -> ID NAME -> -- ---- -> 2 b -> 3 c -> rows (ordered): 2 - -select * from person order by id limit 2147483647-1 offset 1; -> ID NAME -> -- ---- -> 2 b -> 3 c -> rows (ordered): 2 - -select * from person order by id limit 2147483647-1 offset 2; -> ID NAME -> -- ---- -> 3 c -> rows (ordered): 1 - -select * from person order by id limit 2147483647-2 offset 2; -> ID NAME -> -- ---- -> 3 c -> rows (ordered): 1 - -drop table person; -> ok - -CREATE TABLE TEST(ID INTEGER NOT NULL, ID2 INTEGER DEFAULT 0); -> ok - -ALTER TABLE test ALTER COLUMN ID2 RENAME TO ID; -> exception - -drop table test; -> ok - -create table test(id int primary key, data array); -> ok - -insert into test values(1, (1, 1)), (2, (1, 2)), (3, (1, 1, 1)); -> update count: 3 - -select * from test order by data; -> ID DATA -> -- --------- -> 1 (1, 1) -> 3 (1, 1, 1) -> 2 (1, 2) -> rows (ordered): 3 - -drop table test; -> ok - -CREATE TABLE FOO (A CHAR(10)); -> ok - -CREATE TABLE BAR AS SELECT * FROM FOO; -> ok - -select table_name, numeric_precision from information_schema.columns where column_name = 'A'; -> TABLE_NAME NUMERIC_PRECISION -> ---------- ----------------- -> BAR 10 -> FOO 10 -> rows: 2 - -DROP TABLE FOO, BAR; -> ok - -create table multi_pages(dir_num int, bh_id int); -> ok - -insert into multi_pages values(1, 1), (2, 2), (3, 3); -> update count: 3 - -create table b_holding(id int primary key, site varchar(255)); -> ok - -insert into b_holding values(1, 'Hello'), (2, 'Hello'), (3, 'Hello'); -> update count: 3 - -select * from (select dir_num, count(*) as cnt from multi_pages t, b_holding bh -where t.bh_id=bh.id and bh.site='Hello' group by dir_num) as x -where cnt < 1000 order by dir_num asc; -> DIR_NUM CNT -> ------- --- -> 1 1 -> 2 1 -> 3 1 -> rows (ordered): 3 - -explain select * from (select dir_num, count(*) as cnt from multi_pages t, b_holding bh -where t.bh_id=bh.id and bh.site='Hello' group by dir_num) as x -where cnt < 1000 order by dir_num asc; -> PLAN -> -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -> SELECT X.DIR_NUM, X.CNT FROM (SELECT DIR_NUM, COUNT(*) AS CNT FROM PUBLIC.MULTI_PAGES T /* PUBLIC.MULTI_PAGES.tableScan */ INNER JOIN PUBLIC.B_HOLDING BH /* PUBLIC.PRIMARY_KEY_3: ID = T.BH_ID */ ON 1=1 WHERE (BH.SITE = 'Hello') AND (T.BH_ID = BH.ID) GROUP BY DIR_NUM) X /* SELECT DIR_NUM, COUNT(*) AS CNT FROM PUBLIC.MULTI_PAGES T /++ PUBLIC.MULTI_PAGES.tableScan ++/ INNER JOIN PUBLIC.B_HOLDING BH /++ PUBLIC.PRIMARY_KEY_3: ID = T.BH_ID ++/ ON 1=1 WHERE (BH.SITE = 'Hello') AND (T.BH_ID = BH.ID) GROUP BY DIR_NUM HAVING COUNT(*) <= ?1: CNT < 1000 */ WHERE CNT < 1000 ORDER BY 1 -> rows (ordered): 1 - -select dir_num, count(*) as cnt from multi_pages t, b_holding bh -where t.bh_id=bh.id and bh.site='Hello' group by dir_num -having count(*) < 1000 order by dir_num asc; -> DIR_NUM CNT -> ------- --- -> 1 1 -> 2 1 -> 3 1 -> rows (ordered): 3 - -drop table multi_pages, b_holding; -> ok - -select * from dual where x = 1000000000000000000000; -> X -> - -> rows: 0 - -select * from dual where x = 'Hello'; -> exception - -CREATE TABLE PARENT(ID INT PRIMARY KEY); -> ok - -CREATE TABLE CHILD(ID INT PRIMARY KEY); -> ok - -INSERT INTO PARENT VALUES(1); -> update count: 1 - -SELECT * FROM PARENT P LEFT OUTER JOIN CHILD C ON C.PARENTID=P.ID; -> exception - -DROP TABLE PARENT, CHILD; -> ok - -create table test(id smallint primary key); -> ok - -insert into test values(1), (2), (3); -> update count: 3 - -explain select * from test where id = 1; -> PLAN -> ------------------------------------------------------------------------------- -> SELECT TEST.ID FROM PUBLIC.TEST /* PUBLIC.PRIMARY_KEY_2: ID = 1 */ WHERE ID = 1 -> rows: 1 - -EXPLAIN SELECT * FROM TEST WHERE ID = (SELECT MAX(ID) FROM TEST); -> PLAN -> --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -> SELECT TEST.ID FROM PUBLIC.TEST /* PUBLIC.PRIMARY_KEY_2: ID = (SELECT MAX(ID) FROM PUBLIC.TEST /++ PUBLIC.TEST.tableScan ++/ /++ direct lookup ++/) */ WHERE ID = (SELECT MAX(ID) FROM PUBLIC.TEST /* PUBLIC.TEST.tableScan */ /* direct lookup */) -> rows: 1 - -drop table test; -> ok - -create table test(id tinyint primary key); -> ok - -insert into test values(1), (2), (3); -> update count: 3 - -explain select * from test where id = 3; -> PLAN -> ------------------------------------------------------------------------------- -> SELECT TEST.ID FROM PUBLIC.TEST /* PUBLIC.PRIMARY_KEY_2: ID = 3 */ WHERE ID = 3 -> rows: 1 - -explain select * from test where id = 255; -> PLAN -> ----------------------------------------------------------------------------------- -> SELECT TEST.ID FROM PUBLIC.TEST /* PUBLIC.PRIMARY_KEY_2: ID = 255 */ WHERE ID = 255 -> rows: 1 - -drop table test; -> ok - -create table test(id int primary key); -> ok - -insert into test values(1), (2), (3); -> update count: 3 - -explain select * from test where id in(1, 2, null); -> PLAN -> ----------------------------------------------------------------------------------------------------- -> SELECT TEST.ID FROM PUBLIC.TEST /* PUBLIC.PRIMARY_KEY_2: ID IN(1, 2, NULL) */ WHERE ID IN(1, 2, NULL) -> rows: 1 - -drop table test; -> ok - -create alias "SYSDATE" for "java.lang.Integer.parseInt(java.lang.String)"; -> exception - -create alias "MIN" for "java.lang.Integer.parseInt(java.lang.String)"; -> exception - -create alias "CAST" for "java.lang.Integer.parseInt(java.lang.String)"; -> exception - -CREATE TABLE PARENT(A INT, B INT, PRIMARY KEY(A, B)); -> ok - -CREATE TABLE CHILD(A INT, B INT, CONSTRAINT CP FOREIGN KEY(A, B) REFERENCES PARENT(A, B)); -> ok - -INSERT INTO PARENT VALUES(1, 2); -> update count: 1 - -INSERT INTO CHILD VALUES(2, NULL), (NULL, 3), (NULL, NULL), (1, 2); -> update count: 4 - -set autocommit false; -> ok - -ALTER TABLE CHILD SET REFERENTIAL_INTEGRITY FALSE; -> ok - -ALTER TABLE CHILD SET REFERENTIAL_INTEGRITY TRUE CHECK; -> ok - -set autocommit true; -> ok - -DROP TABLE CHILD, PARENT; -> ok - -CREATE TABLE TEST(BIRTH TIMESTAMP); -> ok - -INSERT INTO TEST VALUES('2006-04-03 10:20:30'), ('2006-04-03 10:20:31'), ('2006-05-05 00:00:00'), ('2006-07-03 22:30:00'), ('2006-07-03 22:31:00'); -> update count: 5 - -SELECT * FROM (SELECT CAST(BIRTH AS DATE) B -FROM TEST GROUP BY CAST(BIRTH AS DATE)) A -WHERE A.B >= '2006-05-05'; -> B -> ---------- -> 2006-05-05 -> 2006-07-03 -> rows: 2 - -DROP TABLE TEST; -> ok - -CREATE TABLE Parent(ID INT PRIMARY KEY, Name VARCHAR); -> ok - -CREATE TABLE Child(ID INT); -> ok - -ALTER TABLE Child ADD FOREIGN KEY(ID) REFERENCES Parent(ID); -> ok - -INSERT INTO Parent VALUES(1, '0'), (2, '0'), (3, '0'); -> update count: 3 - -INSERT INTO Child VALUES(1); -> update count: 1 - -ALTER TABLE Parent ALTER COLUMN Name BOOLEAN NULL; -> ok - -DELETE FROM Parent WHERE ID=3; -> update count: 1 - -DROP TABLE Parent, Child; -> ok - -set autocommit false; -> ok - -CREATE TABLE A(ID INT PRIMARY KEY, SK INT); -> ok - -ALTER TABLE A ADD CONSTRAINT AC FOREIGN KEY(SK) REFERENCES A(ID); -> ok - -INSERT INTO A VALUES(1, 1); -> update count: 1 - -INSERT INTO A VALUES(-2, NULL); -> update count: 1 - -ALTER TABLE A SET REFERENTIAL_INTEGRITY FALSE; -> ok - -ALTER TABLE A SET REFERENTIAL_INTEGRITY TRUE CHECK; -> ok - -ALTER TABLE A SET REFERENTIAL_INTEGRITY FALSE; -> ok - -INSERT INTO A VALUES(2, 3); -> update count: 1 - -ALTER TABLE A SET REFERENTIAL_INTEGRITY TRUE; -> ok - -ALTER TABLE A SET REFERENTIAL_INTEGRITY FALSE; -> ok - -ALTER TABLE A SET REFERENTIAL_INTEGRITY TRUE CHECK; -> exception - -DROP TABLE A; -> ok - -set autocommit true; -> ok - -CREATE TABLE PARENT(ID INT); -> ok - -CREATE TABLE CHILD(PID INT); -> ok - -INSERT INTO PARENT VALUES(1); -> update count: 1 - -INSERT INTO CHILD VALUES(2); -> update count: 1 - -ALTER TABLE CHILD ADD CONSTRAINT CP FOREIGN KEY(PID) REFERENCES PARENT(ID); -> exception - -UPDATE CHILD SET PID=1; -> update count: 1 - -ALTER TABLE CHILD ADD CONSTRAINT CP FOREIGN KEY(PID) REFERENCES PARENT(ID); -> ok - -DROP TABLE CHILD, PARENT; -> ok - -CREATE TABLE A(ID INT PRIMARY KEY, SK INT); -> ok - -INSERT INTO A VALUES(1, 2); -> update count: 1 - -ALTER TABLE A ADD CONSTRAINT AC FOREIGN KEY(SK) REFERENCES A(ID); -> exception - -DROP TABLE A; -> ok - -CREATE TABLE TEST(ID INT); -> ok - -INSERT INTO TEST VALUES(0), (1), (100); -> update count: 3 - -ALTER TABLE TEST ADD CONSTRAINT T CHECK ID<100; -> exception - -UPDATE TEST SET ID=20 WHERE ID=100; -> update count: 1 - -ALTER TABLE TEST ADD CONSTRAINT T CHECK ID<100; -> ok - -DROP TABLE TEST; -> ok - -create table test(id int); -> ok - -set autocommit false; -> ok - -insert into test values(1); -> update count: 1 - -prepare commit tx1; -> ok - -commit transaction tx1; -> ok - -rollback; -> ok - -select * from test; -> ID -> -- -> 1 -> rows: 1 - -drop table test; -> ok - -set autocommit true; -> ok - -CALL REGEXP_REPLACE('abckaboooom', 'o+', 'o'); -> 'abckabom' -> ---------- -> abckabom -> rows: 1 - -SELECT 'Hello' ~ 'He.*' T1, 'HELLO' ~ 'He.*' F2, CAST('HELLO' AS VARCHAR_IGNORECASE) ~ 'He.*' T3; -> T1 F2 T3 -> ---- ----- ---- -> TRUE FALSE TRUE -> rows: 1 - -SELECT 'Hello' ~* 'He.*' T1, 'HELLO' ~* 'He.*' T2, 'hallo' ~* 'He.*' F3; -> T1 T2 F3 -> ---- ---- ----- -> TRUE TRUE FALSE -> rows: 1 - -SELECT 'Hello' !~* 'Ho.*' T1, 'HELLO' !~* 'He.*' F2, 'hallo' !~* 'Ha.*' F3; -> T1 F2 F3 -> ---- ----- ----- -> TRUE FALSE FALSE -> rows: 1 - -create table test(parent int primary key, child int, foreign key(child) references (parent)); -> ok - -insert into test values(1, 1); -> update count: 1 - -insert into test values(2, 3); -> exception - -set autocommit false; -> ok - -set referential_integrity false; -> ok - -insert into test values(4, 4); -> update count: 1 - -insert into test values(5, 6); -> update count: 1 - -set referential_integrity true; -> ok - -insert into test values(7, 7), (8, 9); -> exception - -set autocommit true; -> ok - -drop table test; -> ok - -create table test as select 1, space(10) from dual where 1=0 union all select x, cast(space(100) as varchar(101)) d from system_range(1, 100); -> ok - -drop table test; -> ok - -explain select * from system_range(1, 2) where x=x+1 and x=1; -> PLAN -> --------------------------------------------------------------------------------------------------------------------------------- -> SELECT SYSTEM_RANGE.X FROM SYSTEM_RANGE(1, 2) /* PUBLIC.RANGE_INDEX: X = 1 */ WHERE ((X = 1) AND (X = (X + 1))) AND (1 = (X + 1)) -> rows: 1 - -explain select * from system_range(1, 2) where not (x = 1 and x*2 = 2); -> PLAN -> ------------------------------------------------------------------------------------------------------- -> SELECT SYSTEM_RANGE.X FROM SYSTEM_RANGE(1, 2) /* PUBLIC.RANGE_INDEX */ WHERE (X <> 1) OR ((X * 2) <> 2) -> rows: 1 - -explain select * from system_range(1, 10) where (NOT x >= 5); -> PLAN -> ------------------------------------------------------------------------------------------ -> SELECT SYSTEM_RANGE.X FROM SYSTEM_RANGE(1, 10) /* PUBLIC.RANGE_INDEX: X < 5 */ WHERE X < 5 -> rows: 1 - -CREATE TABLE TEST(ID INT PRIMARY KEY, NAME VARCHAR(255)); -> ok - -INSERT INTO TEST VALUES(1, 'Hello'), (-1, '-1'); -> update count: 2 - -select * from test where name = -1 and name = id; -> ID NAME -> -- ---- -> -1 -1 -> rows: 1 - -explain select * from test where name = -1 and name = id; -> PLAN -> -------------------------------------------------------------------------------------------------------------------------------- -> SELECT TEST.ID, TEST.NAME FROM PUBLIC.TEST /* PUBLIC.PRIMARY_KEY_2: ID = -1 */ WHERE ((NAME = -1) AND (NAME = ID)) AND (ID = -1) -> rows: 1 - -DROP TABLE TEST; -> ok - -select * from system_range(1, 2) where x=x+1 and x=1; -> X -> - -> rows: 0 - -CREATE TABLE A as select 6 a; -> ok - -CREATE TABLE B(B INT PRIMARY KEY); -> ok - -CREATE VIEW V(V) AS (SELECT A FROM A UNION SELECT B FROM B); -> ok - -create table C as select * from table(c int = (0,6)); -> ok - -select * from V, C where V.V = C.C; -> V C -> - - -> 6 6 -> rows: 1 - -drop table A, B, C, V; -> ok - -explain select * from table(id int = (1, 2), name varchar=('Hello', 'World')); -> PLAN -> ------------------------------------------------------------------------------------------------------ -> SELECT TABLE.ID, TABLE.NAME FROM TABLE(ID INT=(1, 2), NAME VARCHAR=('Hello', 'World')) /* PUBLIC."" */ -> rows: 1 - -CREATE TABLE TEST(ID INT PRIMARY KEY, FLAG BOOLEAN, NAME VARCHAR); -> ok - -CREATE INDEX IDX_FLAG ON TEST(FLAG, NAME); -> ok - -INSERT INTO TEST VALUES(1, TRUE, 'Hello'), (2, FALSE, 'World'); -> update count: 2 - -EXPLAIN SELECT * FROM TEST WHERE FLAG; -> PLAN -> --------------------------------------------------------------------------------------------------- -> SELECT TEST.ID, TEST.FLAG, TEST.NAME FROM PUBLIC.TEST /* PUBLIC.IDX_FLAG: FLAG = TRUE */ WHERE FLAG -> rows: 1 - -EXPLAIN SELECT * FROM TEST WHERE FLAG AND NAME>'I'; -> PLAN -> ----------------------------------------------------------------------------------------------------------------------------------- -> SELECT TEST.ID, TEST.FLAG, TEST.NAME FROM PUBLIC.TEST /* PUBLIC.IDX_FLAG: FLAG = TRUE AND NAME > 'I' */ WHERE FLAG AND (NAME > 'I') -> rows: 1 - -DROP TABLE TEST; -> ok - -CREATE TABLE test_table (first_col varchar(20), second_col integer); -> ok - -insert into test_table values('a', 10), ('a', 4), ('b', 30), ('b', 3); -> update count: 4 - -CREATE VIEW test_view AS SELECT first_col AS renamed_col, MIN(second_col) AS also_renamed FROM test_table GROUP BY first_col; -> ok - -SELECT * FROM test_view WHERE renamed_col = 'a'; -> RENAMED_COL ALSO_RENAMED -> ----------- ------------ -> a 4 -> rows: 1 - -drop view test_view; -> ok - -drop table test_table; -> ok - -create table test(id int); -> ok - -explain select id+1 a from test group by id+1; -> PLAN -> --------------------------------------------------------------------------------- -> SELECT (ID + 1) AS A FROM PUBLIC.TEST /* PUBLIC.TEST.tableScan */ GROUP BY ID + 1 -> rows: 1 - -drop table test; -> ok - -set autocommit off; -> ok - -set search_path = public, information_schema; -> ok - -select table_name from tables where 1=0; -> TABLE_NAME -> ---------- -> rows: 0 - -set search_path = public; -> ok - -set autocommit on; -> ok - -create table script.public.x(a int); -> ok - -select * from script.PUBLIC.x; -> A -> - -> rows: 0 - -create index script.public.idx on script.public.x(a); -> ok - -drop table script.public.x; -> ok - -create table t1 (i int); -> ok - -create table t2 (i int); -> ok - -create table t3 (i int); -> ok - -select a.i from t1 a inner join (select a.i from t2 a inner join (select i from t3) b on a.i=b.i) b on a.i=b.i; -> I -> - -> rows: 0 - -drop table t1, t2, t3; -> ok - -create table d(d double, r real); -> ok - -insert into d(d, d, r) values(1.1234567890123456789, 1.1234567890123456789, 3); -> exception - -insert into d values(1.1234567890123456789, 1.1234567890123456789); -> update count: 1 - -select r+d, r+r, d+d from d; -> R + D R + R D + D -> ----------------- --------- ------------------ -> 2.246913624759111 2.2469137 2.2469135780246914 -> rows: 1 - -drop table d; -> ok - -create table test(id int, c char(5), v varchar(5)); -> ok - -insert into test values(1, 'a', 'a'); -> update count: 1 - -insert into test values(2, 'a ', 'a '); -> update count: 1 - -insert into test values(3, 'abcde ', 'abcde'); -> update count: 1 - -select distinct length(c) from test order by length(c); -> LENGTH(C) -> --------- -> 1 -> 5 -> rows (ordered): 2 - -select id, c, v, length(c), length(v) from test order by id; -> ID C V LENGTH(C) LENGTH(V) -> -- ----- ----- --------- --------- -> 1 a a 1 1 -> 2 a a 1 2 -> 3 abcde abcde 5 5 -> rows (ordered): 3 - -select id from test where c='a' order by id; -> ID -> -- -> 1 -> 2 -> rows (ordered): 2 - -select id from test where c='a ' order by id; -> ID -> -- -> 1 -> 2 -> rows (ordered): 2 - -select id from test where c=v order by id; -> ID -> -- -> 1 -> 2 -> 3 -> rows (ordered): 3 - -drop table test; -> ok - -CREATE TABLE TEST(ID INT PRIMARY KEY, NAME VARCHAR(255), C INT); -> ok - -INSERT INTO TEST VALUES(1, '10', NULL), (2, '0', NULL); -> update count: 2 - -SELECT LEAST(ID, C, NAME), GREATEST(ID, C, NAME), LEAST(NULL, C), GREATEST(NULL, NULL), ID FROM TEST ORDER BY ID; -> LEAST(ID, C, NAME) GREATEST(ID, C, NAME) LEAST(NULL, C) NULL ID -> ------------------ --------------------- -------------- ---- -- -> 1 10 null null 1 -> 0 2 null null 2 -> rows (ordered): 2 - -DROP TABLE IF EXISTS TEST; -> ok - -create table people (family varchar(1) not null, person varchar(1) not null); -> ok - -create table cars (family varchar(1) not null, car varchar(1) not null); -> ok - -insert into people values(1, 1), (2, 1), (2, 2), (3, 1), (5, 1); -> update count: 5 - -insert into cars values(2, 1), (2, 2), (3, 1), (3, 2), (3, 3), (4, 1); -> update count: 6 - -select family, (select count(car) from cars where cars.family = people.family) as x -from people group by family order by family; -> FAMILY X -> ------ - -> 1 0 -> 2 2 -> 3 3 -> 5 0 -> rows (ordered): 4 - -drop table people, cars; -> ok - -select (1, 2); -> 1, 2 -> ------ -> (1, 2) -> rows: 1 - -select * from table(id int=(1, 2), name varchar=('Hello', 'World')) x order by id; -> ID NAME -> -- ----- -> 1 Hello -> 2 World -> rows (ordered): 2 - -create table array_test(x array); -> ok - -insert into array_test values((1, 2, 3)), ((2, 3, 4)); -> update count: 2 - -select * from array_test where x = (1, 2, 3); -> X -> --------- -> (1, 2, 3) -> rows: 1 - -drop table array_test; -> ok - -select * from (select 1), (select 2); -> 1 2 -> - - -> 1 2 -> rows: 1 - -CREATE TABLE TEST(A VARCHAR, B VARCHAR, C VARCHAR AS LOWER(A)); -> ok - -ALTER TABLE TEST DROP COLUMN B; -> ok - -DROP TABLE TEST; -> ok - -create table t1(c1 int, c2 int); -> ok - -create table t2(c1 int, c2 int); -> ok - -insert into t1 values(1, null), (2, 2), (3, 3); -> update count: 3 - -insert into t2 values(1, 1), (1, 2), (2, null), (3, 3); -> update count: 4 - -select * from t2 where c1 not in(select c2 from t1); -> C1 C2 -> -- -- -> rows: 0 - -select * from t2 where c1 not in(null, 2, 3); -> C1 C2 -> -- -- -> rows: 0 - -select * from t1 where c2 not in(select c1 from t2); -> C1 C2 -> -- -- -> rows: 0 - -select * from t1 where not exists(select * from t2 where t1.c2=t2.c1); -> C1 C2 -> -- ---- -> 1 null -> rows: 1 - -drop table t1; -> ok - -drop table t2; -> ok - -create constant abc value 1; -> ok - -call abc; -> 1 -> - -> 1 -> rows: 1 - -drop all objects; -> ok - -call abc; -> exception - -create table FOO(id integer primary key); -> ok - -create table BAR(fooId integer); -> ok - -alter table bar add foreign key (fooId) references foo (id); -> ok - -truncate table bar; -> ok - -truncate table foo; -> exception - -drop table bar, foo; -> ok - -CREATE TABLE TESTA(ID IDENTITY); -> ok - -CREATE TABLE TESTB(ID IDENTITY); -> ok - -explain SELECT TESTA.ID A, TESTB.ID B FROM TESTA, TESTB ORDER BY TESTA.ID, TESTB.ID; -> PLAN -> ------------------------------------------------------------------------------------------------------------------------------------------------------------ -> SELECT TESTA.ID AS A, TESTB.ID AS B FROM PUBLIC.TESTA /* PUBLIC.TESTA.tableScan */ INNER JOIN PUBLIC.TESTB /* PUBLIC.TESTB.tableScan */ ON 1=1 ORDER BY 1, 2 -> rows (ordered): 1 - -DROP TABLE IF EXISTS TESTA, TESTB; -> ok - -CREATE TABLE test (family_name VARCHAR_IGNORECASE(63) NOT NULL); -> ok - -INSERT INTO test VALUES('Smith'), ('de Smith'), ('el Smith'), ('von Smith'); -> update count: 4 - -SELECT * FROM test WHERE family_name IN ('de Smith', 'Smith'); -> FAMILY_NAME -> ----------- -> Smith -> de Smith -> rows: 2 - -SELECT * FROM test WHERE family_name BETWEEN 'D' AND 'T'; -> FAMILY_NAME -> ----------- -> Smith -> de Smith -> el Smith -> rows: 3 - -CREATE INDEX family_name ON test(family_name); -> ok - -SELECT * FROM test WHERE family_name IN ('de Smith', 'Smith'); -> FAMILY_NAME -> ----------- -> Smith -> de Smith -> rows: 2 - -drop table test; -> ok - -create memory table test(id int primary key, data clob); -> ok - -insert into test values(1, 'abc' || space(20)); -> update count: 1 - -script nopasswords nosettings blocksize 10; -> SCRIPT -> -------------------------------------------------------------------------------------------------------------- -> -- 1 +/- SELECT COUNT(*) FROM PUBLIC.TEST; -> ALTER TABLE PUBLIC.TEST ADD CONSTRAINT PUBLIC.CONSTRAINT_2 PRIMARY KEY(ID); -> CALL SYSTEM_COMBINE_BLOB(-1); -> CREATE ALIAS IF NOT EXISTS SYSTEM_COMBINE_BLOB FOR "org.h2.command.dml.ScriptCommand.combineBlob"; -> CREATE ALIAS IF NOT EXISTS SYSTEM_COMBINE_CLOB FOR "org.h2.command.dml.ScriptCommand.combineClob"; -> CREATE MEMORY TABLE PUBLIC.TEST( ID INT NOT NULL, DATA CLOB ); -> CREATE PRIMARY KEY SYSTEM_LOB_STREAM_PRIMARY_KEY ON SYSTEM_LOB_STREAM(ID, PART); -> CREATE TABLE IF NOT EXISTS SYSTEM_LOB_STREAM(ID INT NOT NULL, PART INT NOT NULL, CDATA VARCHAR, BDATA BINARY); -> CREATE USER IF NOT EXISTS SA PASSWORD '' ADMIN; -> DROP ALIAS IF EXISTS SYSTEM_COMBINE_BLOB; -> DROP ALIAS IF EXISTS SYSTEM_COMBINE_CLOB; -> DROP TABLE IF EXISTS SYSTEM_LOB_STREAM; -> INSERT INTO PUBLIC.TEST(ID, DATA) VALUES (1, SYSTEM_COMBINE_CLOB(0)); -> INSERT INTO SYSTEM_LOB_STREAM VALUES(0, 0, 'abc ', NULL); -> INSERT INTO SYSTEM_LOB_STREAM VALUES(0, 1, ' ', NULL); -> INSERT INTO SYSTEM_LOB_STREAM VALUES(0, 2, ' ', NULL); -> rows: 16 - -drop table test; -> ok - -CREATE TABLE TEST(ID INT PRIMARY KEY, NAME VARCHAR(255)); -> ok - -INSERT INTO TEST VALUES(1, 'Hello'), (2, 'World'); -> update count: 2 - -SELECT DISTINCT * FROM TEST ORDER BY ID; -> ID NAME -> -- ----- -> 1 Hello -> 2 World -> rows (ordered): 2 - -DROP TABLE TEST; -> ok - -create table Foo (A varchar(20), B integer); -> ok - -insert into Foo (A, B) values ('abcd', 1), ('abcd', 2); -> update count: 2 - -select * from Foo where A like 'abc%' escape '\' AND B=1; -> A B -> ---- - -> abcd 1 -> rows: 1 - -drop table Foo; -> ok - -create memory table orders ( orderid varchar(10), name varchar(20), customer_id varchar(10), completed numeric(1) not null, verified numeric(1) ); -> ok - -select * from information_schema.columns where table_name = 'ORDERS'; -> TABLE_CATALOG TABLE_SCHEMA TABLE_NAME COLUMN_NAME ORDINAL_POSITION COLUMN_DEFAULT IS_NULLABLE DATA_TYPE CHARACTER_MAXIMUM_LENGTH CHARACTER_OCTET_LENGTH NUMERIC_PRECISION NUMERIC_PRECISION_RADIX NUMERIC_SCALE CHARACTER_SET_NAME COLLATION_NAME TYPE_NAME NULLABLE IS_COMPUTED SELECTIVITY CHECK_CONSTRAINT SEQUENCE_NAME REMARKS SOURCE_DATA_TYPE -> ------------- ------------ ---------- ----------- ---------------- -------------- ----------- --------- ------------------------ ---------------------- ----------------- ----------------------- ------------- ------------------ -------------- --------- -------- ----------- ----------- ---------------- ------------- ------- ---------------- -> SCRIPT PUBLIC ORDERS COMPLETED 4 null NO 3 1 1 1 10 0 Unicode OFF DECIMAL 0 FALSE 50 null null -> SCRIPT PUBLIC ORDERS CUSTOMER_ID 3 null YES 12 10 10 10 10 0 Unicode OFF VARCHAR 1 FALSE 50 null null -> SCRIPT PUBLIC ORDERS NAME 2 null YES 12 20 20 20 10 0 Unicode OFF VARCHAR 1 FALSE 50 null null -> SCRIPT PUBLIC ORDERS ORDERID 1 null YES 12 10 10 10 10 0 Unicode OFF VARCHAR 1 FALSE 50 null null -> SCRIPT PUBLIC ORDERS VERIFIED 5 null YES 3 1 1 1 10 0 Unicode OFF DECIMAL 1 FALSE 50 null null -> rows: 5 - -drop table orders; -> ok - -create table test(id int, d timestamp); -> ok - -insert into test values(1, '2006-01-01 12:00:00.000'); -> update count: 1 - -insert into test values(1, '1999-12-01 23:59:00.000'); -> update count: 1 - -select * from test where d= '1999-12-01 23:59:00.000'; -> ID D -> -- --------------------- -> 1 1999-12-01 23:59:00.0 -> rows: 1 - -select * from test where d= timestamp '2006-01-01 12:00:00.000'; -> ID D -> -- --------------------- -> 1 2006-01-01 12:00:00.0 -> rows: 1 - -drop table test; -> ok - -create table test(id int, b binary); -> ok - -insert into test values(1, 'face'); -> update count: 1 - -select * from test where b = 'FaCe'; -> ID B -> -- ---- -> 1 face -> rows: 1 - -drop table test; -> ok - -create sequence main_seq; -> ok - -create schema "TestSchema"; -> ok - -create sequence "TestSchema"."TestSeq"; -> ok - -create sequence "TestSchema"."ABC"; -> ok - -select currval('main_seq'), currval('TestSchema', 'TestSeq'), nextval('TestSchema', 'ABC'); -> CURRVAL('main_seq') CURRVAL('TestSchema', 'TestSeq') NEXTVAL('TestSchema', 'ABC') -> ------------------- -------------------------------- ---------------------------- -> 0 0 1 -> rows: 1 - -set autocommit off; -> ok - -set schema "TestSchema"; -> ok - -select nextval('abc'), currval('Abc'), nextval('TestSchema', 'ABC'); -> NEXTVAL('abc') CURRVAL('Abc') NEXTVAL('TestSchema', 'ABC') -> -------------- -------------- ---------------------------- -> 2 2 3 -> rows: 1 - -set schema public; -> ok - -drop schema "TestSchema"; -> ok - -drop sequence main_seq; -> ok - -set autocommit on; -> ok - -CREATE TABLE parent(id int PRIMARY KEY); -> ok - -CREATE TABLE child(parentid int REFERENCES parent); -> ok - -select * from INFORMATION_SCHEMA.CROSS_REFERENCES; -> PKTABLE_CATALOG PKTABLE_SCHEMA PKTABLE_NAME PKCOLUMN_NAME FKTABLE_CATALOG FKTABLE_SCHEMA FKTABLE_NAME FKCOLUMN_NAME ORDINAL_POSITION UPDATE_RULE DELETE_RULE FK_NAME PK_NAME DEFERRABILITY -> --------------- -------------- ------------ ------------- --------------- -------------- ------------ ------------- ---------------- ----------- ----------- ------------ ------- ------------- -> SCRIPT PUBLIC PARENT ID SCRIPT PUBLIC CHILD PARENTID 1 1 1 CONSTRAINT_3 null 7 -> rows: 1 - -ALTER TABLE parent ADD COLUMN name varchar; -> ok - -select * from INFORMATION_SCHEMA.CROSS_REFERENCES; -> PKTABLE_CATALOG PKTABLE_SCHEMA PKTABLE_NAME PKCOLUMN_NAME FKTABLE_CATALOG FKTABLE_SCHEMA FKTABLE_NAME FKCOLUMN_NAME ORDINAL_POSITION UPDATE_RULE DELETE_RULE FK_NAME PK_NAME DEFERRABILITY -> --------------- -------------- ------------ ------------- --------------- -------------- ------------ ------------- ---------------- ----------- ----------- ------------ ------- ------------- -> SCRIPT PUBLIC PARENT ID SCRIPT PUBLIC CHILD PARENTID 1 1 1 CONSTRAINT_3 null 7 -> rows: 1 - -drop table parent, child; -> ok - -create table test(id int); -> ok - -create schema TEST_SCHEMA; -> ok - -set autocommit false; -> ok - -set schema TEST_SCHEMA; -> ok - -create table test(id int, name varchar); -> ok - -explain select * from test; -> PLAN -> -------------------------------------------------------------------------------- -> SELECT TEST.ID, TEST.NAME FROM TEST_SCHEMA.TEST /* TEST_SCHEMA.TEST.tableScan */ -> rows: 1 - -explain select * from public.test; -> PLAN -> ----------------------------------------------------------- -> SELECT TEST.ID FROM PUBLIC.TEST /* PUBLIC.TEST.tableScan */ -> rows: 1 - -drop schema TEST_SCHEMA; -> ok - -set autocommit true; -> ok - -set schema public; -> ok - -select * from test; -> ID -> -- -> rows: 0 - -drop table test; -> ok - -create table content(thread_id int, parent_id int); -> ok - -alter table content add constraint content_parent_id check (parent_id = thread_id) or (parent_id is null) or ( parent_id in (select thread_id from content)); -> ok - -create index content_thread_id ON content(thread_id); -> ok - -insert into content values(0, 0), (0, 0); -> update count: 2 - -insert into content values(0, 1); -> exception - -insert into content values(1, 1), (2, 2); -> update count: 2 - -insert into content values(2, 1); -> update count: 1 - -insert into content values(2, 3); -> exception - -drop table content; -> ok - -select x/10 y from system_range(1, 100) group by x/10; -> Y -> -- -> 0 -> 1 -> 10 -> 2 -> 3 -> 4 -> 5 -> 6 -> 7 -> 8 -> 9 -> rows: 11 - -select timestamp '2001-02-03T10:30:33'; -> TIMESTAMP '2001-02-03 10:30:33.0' -> --------------------------------- -> 2001-02-03 10:30:33.0 -> rows: 1 - -CREATE TABLE TEST(ID INT PRIMARY KEY, NAME VARCHAR(255)); -> ok - -INSERT INTO TEST VALUES(1, 'Hello'), (2, 'World'); -> update count: 2 - -select * from test where id in (select id from test); -> ID NAME -> -- ----- -> 1 Hello -> 2 World -> rows: 2 - -select * from test where id in ((select id from test)); -> ID NAME -> -- ----- -> 1 Hello -> 2 World -> rows: 2 - -select * from test where id in (((select id from test))); -> ID NAME -> -- ----- -> 1 Hello -> 2 World -> rows: 2 - -DROP TABLE TEST; -> ok - -create table test(id int); -> ok - -insert into test (select x from system_range(1, 100)); -> update count: 100 - -select id/1000 from test group by id/1000; -> ID / 1000 -> --------- -> 0 -> rows: 1 - -select id/(10*100) from test group by id/(10*100); -> ID / 1000 -> --------- -> 0 -> rows: 1 - -select id/1000 from test group by id/100; -> exception - -drop table test; -> ok - -select (x/10000) from system_range(10, 20) group by (x/10000); -> X / 10000 -> --------- -> 0 -> rows: 1 - -select sum(x), (x/10) from system_range(10, 100) group by (x/10); -> SUM(X) X / 10 -> ------ ------ -> 100 10 -> 145 1 -> 245 2 -> 345 3 -> 445 4 -> 545 5 -> 645 6 -> 745 7 -> 845 8 -> 945 9 -> rows: 10 - -CREATE FORCE VIEW ADDRESS_VIEW AS SELECT * FROM ADDRESS; -> ok - -CREATE memory TABLE ADDRESS(ID INT); -> ok - -alter view address_view recompile; -> ok - -select * from ADDRESS_VIEW; -> ID -> -- -> rows: 0 - -drop view address_view; -> ok - -drop table address; -> ok - -select cast('12345678123456781234567812345678' as uuid); -> '12345678-1234-5678-1234-567812345678' -> -------------------------------------- -> 12345678-1234-5678-1234-567812345678 -> rows: 1 - -select cast('000102030405060708090a0b0c0d0e0f' as uuid); -> '00010203-0405-0607-0809-0a0b0c0d0e0f' -> -------------------------------------- -> 00010203-0405-0607-0809-0a0b0c0d0e0f -> rows: 1 - -CREATE ALIAS PARSE_INT2 FOR "java.lang.Integer.parseInt(java.lang.String, int)"; -> ok - -select min(SUBSTRING(random_uuid(), 15,1)='4') from system_range(1, 10); -> MIN(SUBSTRING(RANDOM_UUID(), 15, 1) = '4') -> ------------------------------------------ -> TRUE -> rows: 1 - -select min(8=bitand(12, PARSE_INT2(SUBSTRING(random_uuid(), 20,1), 16))) from system_range(1, 10); -> MIN(8 = BITAND(12, PARSE_INT2(SUBSTRING(RANDOM_UUID(), 20, 1), 16))) -> -------------------------------------------------------------------- -> TRUE -> rows: 1 - -drop alias PARSE_INT2; -> ok - -create memory table test(name varchar check(name = upper(name))); -> ok - -insert into test values(null); -> update count: 1 - -insert into test values('aa'); -> exception - -insert into test values('AA'); -> update count: 1 - -script nodata nopasswords nosettings; -> SCRIPT -> ------------------------------------------------------------------------------- -> -- 2 +/- SELECT COUNT(*) FROM PUBLIC.TEST; -> CREATE MEMORY TABLE PUBLIC.TEST( NAME VARCHAR CHECK (NAME = UPPER(NAME)) ); -> CREATE USER IF NOT EXISTS SA PASSWORD '' ADMIN; -> rows: 3 - -drop table test; -> ok - -create domain email as varchar(200) check (position('@' in value) > 1); -> ok - -create domain gmail as email default '@gmail.com' check (position('gmail' in value) > 1); -> ok - -create memory table address(id int primary key, name email, name2 gmail); -> ok - -insert into address(id, name, name2) values(1, 'test@abc', 'test@gmail.com'); -> update count: 1 - -insert into address(id, name, name2) values(2, 'test@abc', 'test@acme'); -> exception - -insert into address(id, name, name2) values(3, 'test_abc', 'test@gmail'); -> exception - -insert into address2(name) values('test@abc'); -> exception - -CREATE DOMAIN STRING AS VARCHAR(255) DEFAULT '' NOT NULL; -> ok - -CREATE DOMAIN IF NOT EXISTS STRING AS VARCHAR(255) DEFAULT '' NOT NULL; -> ok - -CREATE DOMAIN STRING1 AS VARCHAR NULL; -> ok - -CREATE DOMAIN STRING2 AS VARCHAR NOT NULL; -> ok - -CREATE DOMAIN STRING3 AS VARCHAR DEFAULT ''; -> ok - -create domain string_x as string3; -> ok - -create memory table test(a string, b string1, c string2, d string3); -> ok - -insert into test() values(); -> update count: 1 - -select * from test; -> A B C D -> - ---- ---- ------- -> null null -> rows: 1 - -select DOMAIN_NAME, COLUMN_DEFAULT, IS_NULLABLE, DATA_TYPE, PRECISION, SCALE, TYPE_NAME, SELECTIVITY, CHECK_CONSTRAINT, REMARKS, SQL from information_schema.domains; -> DOMAIN_NAME COLUMN_DEFAULT IS_NULLABLE DATA_TYPE PRECISION SCALE TYPE_NAME SELECTIVITY CHECK_CONSTRAINT REMARKS SQL -> ----------- -------------- ----------- --------- ---------- ----- --------- ----------- --------------------------------------------------------------- ------- ------------------------------------------------------------------------------------------------------------------------------ -> EMAIL null YES 12 200 0 VARCHAR 50 (POSITION('@', VALUE) > 1) CREATE DOMAIN EMAIL AS VARCHAR(200) CHECK (POSITION('@', VALUE) > 1) -> GMAIL '@gmail.com' YES 12 200 0 VARCHAR 50 ((POSITION('@', VALUE) > 1) AND (POSITION('gmail', VALUE) > 1)) CREATE DOMAIN GMAIL AS VARCHAR(200) DEFAULT '@gmail.com' CHECK ((POSITION('@', VALUE) > 1) AND (POSITION('gmail', VALUE) > 1)) -> STRING '' NO 12 255 0 VARCHAR 50 CREATE DOMAIN STRING AS VARCHAR(255) DEFAULT '' NOT NULL -> STRING1 null YES 12 2147483647 0 VARCHAR 50 CREATE DOMAIN STRING1 AS VARCHAR -> STRING2 null NO 12 2147483647 0 VARCHAR 50 CREATE DOMAIN STRING2 AS VARCHAR NOT NULL -> STRING3 '' YES 12 2147483647 0 VARCHAR 50 CREATE DOMAIN STRING3 AS VARCHAR DEFAULT '' -> STRING_X '' YES 12 2147483647 0 VARCHAR 50 CREATE DOMAIN STRING_X AS VARCHAR DEFAULT '' -> rows: 7 - -script nodata nopasswords nosettings; -> SCRIPT -> ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ -> -- 1 +/- SELECT COUNT(*) FROM PUBLIC.ADDRESS; -> -- 1 +/- SELECT COUNT(*) FROM PUBLIC.TEST; -> ALTER TABLE PUBLIC.ADDRESS ADD CONSTRAINT PUBLIC.CONSTRAINT_E PRIMARY KEY(ID); -> CREATE DOMAIN EMAIL AS VARCHAR(200) CHECK (POSITION('@', VALUE) > 1); -> CREATE DOMAIN GMAIL AS VARCHAR(200) DEFAULT '@gmail.com' CHECK ((POSITION('@', VALUE) > 1) AND (POSITION('gmail', VALUE) > 1)); -> CREATE DOMAIN STRING AS VARCHAR(255) DEFAULT '' NOT NULL; -> CREATE DOMAIN STRING1 AS VARCHAR; -> CREATE DOMAIN STRING2 AS VARCHAR NOT NULL; -> CREATE DOMAIN STRING3 AS VARCHAR DEFAULT ''; -> CREATE DOMAIN STRING_X AS VARCHAR DEFAULT ''; -> CREATE MEMORY TABLE PUBLIC.ADDRESS( ID INT NOT NULL, NAME VARCHAR(200) CHECK (POSITION('@', NAME) > 1), NAME2 VARCHAR(200) DEFAULT '@gmail.com' CHECK ((POSITION('@', NAME2) > 1) AND (POSITION('gmail', NAME2) > 1)) ); -> CREATE MEMORY TABLE PUBLIC.TEST( A VARCHAR(255) DEFAULT '', B VARCHAR, C VARCHAR, D VARCHAR DEFAULT '' ); -> CREATE USER IF NOT EXISTS SA PASSWORD '' ADMIN; -> rows: 13 - -drop table test; -> ok - -drop domain string; -> ok - -drop domain string1; -> ok - -drop domain string2; -> ok - -drop domain string3; -> ok - -drop domain string_x; -> ok - -drop table address; -> ok - -drop domain email; -> ok - -drop domain gmail; -> ok - -create force view address_view as select * from address; -> ok - -create table address(id identity, name varchar check instr(value, '@') > 1); -> exception - -create table address(id identity, name varchar check instr(name, '@') > 1); -> ok - -drop table address; -> ok - -drop view if exists address_view; -> ok - -create memory table a(k10 blob(10k), m20 blob(20m), g30 clob(30g)); -> ok - -script NODATA NOPASSWORDS NOSETTINGS drop; -> SCRIPT -> ------------------------------------------------------------------------------------------------------- -> -- 0 +/- SELECT COUNT(*) FROM PUBLIC.A; -> CREATE MEMORY TABLE PUBLIC.A( K10 BLOB(10240), M20 BLOB(20971520), G30 CLOB(32212254720) ); -> CREATE USER IF NOT EXISTS SA PASSWORD '' ADMIN; -> DROP TABLE IF EXISTS PUBLIC.A; -> rows: 4 - -create table b(); -> ok - -create table c(); -> ok - -drop table information_schema.columns; -> exception - -create table columns as select * from information_schema.columns; -> ok - -create table tables as select * from information_schema.tables where false; -> ok - -create table dual2 as select 1 from dual; -> ok - -select * from dual2; -> 1 -> - -> 1 -> rows: 1 - -drop table dual2, columns, tables; -> ok - -drop table a, a; -> ok - -drop table b, c; -> ok - -CREATE SCHEMA CONST; -> ok - -CREATE CONSTANT IF NOT EXISTS ONE VALUE 1; -> ok - -COMMENT ON CONSTANT ONE IS 'Eins'; -> ok - -CREATE CONSTANT IF NOT EXISTS ONE VALUE 1; -> ok - -CREATE CONSTANT CONST.ONE VALUE 1; -> ok - -SELECT CONSTANT_SCHEMA, CONSTANT_NAME, DATA_TYPE, REMARKS, SQL FROM INFORMATION_SCHEMA.CONSTANTS; -> CONSTANT_SCHEMA CONSTANT_NAME DATA_TYPE REMARKS SQL -> --------------- ------------- --------- ------- --- -> CONST ONE 4 1 -> PUBLIC ONE 4 Eins 1 -> rows: 2 - -SELECT ONE, CONST.ONE FROM DUAL; -> 1 1 -> - - -> 1 1 -> rows: 1 - -COMMENT ON CONSTANT ONE IS NULL; -> ok - -DROP SCHEMA CONST; -> ok - -SELECT CONSTANT_SCHEMA, CONSTANT_NAME, DATA_TYPE, REMARKS, SQL FROM INFORMATION_SCHEMA.CONSTANTS; -> CONSTANT_SCHEMA CONSTANT_NAME DATA_TYPE REMARKS SQL -> --------------- ------------- --------- ------- --- -> PUBLIC ONE 4 1 -> rows: 1 - -DROP CONSTANT ONE; -> ok - -DROP CONSTANT IF EXISTS ONE; -> ok - -DROP CONSTANT IF EXISTS ONE; -> ok - -CREATE TABLE A (ID_A int primary key); -> ok - -CREATE TABLE B (ID_B int primary key); -> ok - -CREATE TABLE C (ID_C int primary key); -> ok - -insert into A values (1); -> update count: 1 - -insert into A values (2); -> update count: 1 - -insert into B values (1); -> update count: 1 - -insert into C values (1); -> update count: 1 - -SELECT * FROM C WHERE NOT EXISTS ((SELECT ID_A FROM A) EXCEPT (SELECT ID_B FROM B)); -> ID_C -> ---- -> rows: 0 - -(SELECT ID_A FROM A) EXCEPT (SELECT ID_B FROM B); -> ID_A -> ---- -> 2 -> rows: 1 - -drop table a; -> ok - -drop table b; -> ok - -drop table c; -> ok - -CREATE TABLE X (ID INTEGER PRIMARY KEY); -> ok - -insert into x values(0), (1), (10); -> update count: 3 - -SELECT t1.ID, (SELECT t1.id || ':' || AVG(t2.ID) FROM X t2) FROM X t1; -> ID SELECT ((T1.ID || ':') || AVG(T2.ID)) FROM PUBLIC.X T2 /* PUBLIC.X.tableScan */ /* scanCount: 4 */ -> -- -------------------------------------------------------------------------------------------------- -> 0 0:3 -> 1 1:3 -> 10 10:3 -> rows: 3 - -drop table x; -> ok - -select (select t1.x from system_range(1,1) t2) from system_range(1,1) t1; -> SELECT T1.X FROM SYSTEM_RANGE(1, 1) T2 /* PUBLIC.RANGE_INDEX */ /* scanCount: 2 */ -> ---------------------------------------------------------------------------------- -> 1 -> rows: 1 - -create table test(id int primary key, name varchar); -> ok - -insert into test values(rownum, '11'), (rownum, '22'), (rownum, '33'); -> update count: 3 - -select * from test order by id; -> ID NAME -> -- ---- -> 1 11 -> 2 22 -> 3 33 -> rows (ordered): 3 - -select rownum, (select count(*) from test), rownum from test; -> ROWNUM() SELECT COUNT(*) FROM PUBLIC.TEST /* PUBLIC.TEST.tableScan */ /* direct lookup */ ROWNUM() -> -------- -------------------------------------------------------------------------------- -------- -> 1 3 1 -> 2 3 2 -> 3 3 3 -> rows: 3 - -delete from test t0 where rownum<2; -> update count: 1 - -select rownum, * from (select * from test where id>1 order by id desc); -> ROWNUM() ID NAME -> -------- -- ---- -> 1 3 33 -> 2 2 22 -> rows (ordered): 2 - -update test set name='x' where rownum<2; -> update count: 1 - -select * from test; -> ID NAME -> -- ---- -> 2 x -> 3 33 -> rows: 2 - -merge into test values(2, 'r' || rownum), (10, rownum), (11, rownum); -> update count: 3 - -select * from test; -> ID NAME -> -- ---- -> 10 2 -> 11 3 -> 2 r1 -> 3 33 -> rows: 4 - -call rownum; -> ROWNUM() -> -------- -> 1 -> rows: 1 - -drop table test; -> ok - -CREATE TABLE TEST(ID INT PRIMARY KEY, NAME VARCHAR(255)); -> ok - -create index idx_test_name on test(name); -> ok - -INSERT INTO TEST VALUES(1, 'Hello'); -> update count: 1 - -INSERT INTO TEST VALUES(2, 'World'); -> update count: 1 - -set ignorecase true; -> ok - -CREATE TABLE TEST2(ID INT PRIMARY KEY, NAME VARCHAR(255)); -> ok - -create unique index idx_test2_name on test2(name); -> ok - -INSERT INTO TEST2 VALUES(1, 'HElLo'); -> update count: 1 - -INSERT INTO TEST2 VALUES(2, 'World'); -> update count: 1 - -INSERT INTO TEST2 VALUES(3, 'WoRlD'); -> exception - -drop index idx_test2_name; -> ok - -select * from test where name='HELLO'; -> ID NAME -> -- ---- -> rows: 0 - -select * from test2 where name='HELLO'; -> ID NAME -> -- ----- -> 1 HElLo -> rows: 1 - -select * from test where name like 'HELLO'; -> ID NAME -> -- ---- -> rows: 0 - -select * from test2 where name like 'HELLO'; -> ID NAME -> -- ----- -> 1 HElLo -> rows: 1 - -explain plan for select * from test2, test where test2.name = test.name; -> PLAN -> ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -> SELECT TEST2.ID, TEST2.NAME, TEST.ID, TEST.NAME FROM PUBLIC.TEST2 /* PUBLIC.TEST2.tableScan */ INNER JOIN PUBLIC.TEST /* PUBLIC.IDX_TEST_NAME: NAME = TEST2.NAME */ ON 1=1 WHERE TEST2.NAME = TEST.NAME -> rows: 1 - -select * from test2, test where test2.name = test.name; -> ID NAME ID NAME -> -- ----- -- ----- -> 1 HElLo 1 Hello -> 2 World 2 World -> rows: 2 - -explain plan for select * from test, test2 where test2.name = test.name; -> PLAN -> ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -> SELECT TEST.ID, TEST.NAME, TEST2.ID, TEST2.NAME FROM PUBLIC.TEST2 /* PUBLIC.TEST2.tableScan */ INNER JOIN PUBLIC.TEST /* PUBLIC.IDX_TEST_NAME: NAME = TEST2.NAME */ ON 1=1 WHERE TEST2.NAME = TEST.NAME -> rows: 1 - -select * from test, test2 where test2.name = test.name; -> ID NAME ID NAME -> -- ----- -- ----- -> 1 Hello 1 HElLo -> 2 World 2 World -> rows: 2 - -create index idx_test2_name on test2(name); -> ok - -explain plan for select * from test2, test where test2.name = test.name; -> PLAN -> ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -> SELECT TEST2.ID, TEST2.NAME, TEST.ID, TEST.NAME FROM PUBLIC.TEST2 /* PUBLIC.TEST2.tableScan */ INNER JOIN PUBLIC.TEST /* PUBLIC.IDX_TEST_NAME: NAME = TEST2.NAME */ ON 1=1 WHERE TEST2.NAME = TEST.NAME -> rows: 1 - -select * from test2, test where test2.name = test.name; -> ID NAME ID NAME -> -- ----- -- ----- -> 1 HElLo 1 Hello -> 2 World 2 World -> rows: 2 - -explain plan for select * from test, test2 where test2.name = test.name; -> PLAN -> ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ -> SELECT TEST.ID, TEST.NAME, TEST2.ID, TEST2.NAME FROM PUBLIC.TEST /* PUBLIC.TEST.tableScan */ INNER JOIN PUBLIC.TEST2 /* PUBLIC.IDX_TEST2_NAME: NAME = TEST.NAME */ ON 1=1 WHERE TEST2.NAME = TEST.NAME -> rows: 1 - -select * from test, test2 where test2.name = test.name; -> ID NAME ID NAME -> -- ----- -- ----- -> 1 Hello 1 HElLo -> 2 World 2 World -> rows: 2 - -DROP TABLE IF EXISTS TEST; -> ok - -DROP TABLE IF EXISTS TEST2; -> ok - -set ignorecase false; -> ok - -create table test(f1 varchar, f2 varchar); -> ok - -insert into test values('abc','222'); -> update count: 1 - -insert into test values('abc','111'); -> update count: 1 - -insert into test values('abc','333'); -> update count: 1 - -SELECT t.f1, t.f2 FROM test t ORDER BY t.f2; -> F1 F2 -> --- --- -> abc 111 -> abc 222 -> abc 333 -> rows (ordered): 3 - -SELECT t1.f1, t1.f2, t2.f1, t2.f2 FROM test t1, test t2 ORDER BY t2.f2; -> F1 F2 F1 F2 -> --- --- --- --- -> abc 222 abc 111 -> abc 111 abc 111 -> abc 333 abc 111 -> abc 222 abc 222 -> abc 111 abc 222 -> abc 333 abc 222 -> abc 222 abc 333 -> abc 111 abc 333 -> abc 333 abc 333 -> rows (ordered): 9 - -drop table if exists test; -> ok - -CREATE TABLE TEST(ID INT PRIMARY KEY, NAME VARCHAR(255)); -> ok - -INSERT INTO TEST VALUES(1, 'Hello'); -> update count: 1 - -explain select t0.id, t1.id from test t0, test t1 order by t0.id, t1.id; -> PLAN -> ---------------------------------------------------------------------------------------------------------------------------------------------- -> SELECT T0.ID, T1.ID FROM PUBLIC.TEST T0 /* PUBLIC.TEST.tableScan */ INNER JOIN PUBLIC.TEST T1 /* PUBLIC.TEST.tableScan */ ON 1=1 ORDER BY 1, 2 -> rows (ordered): 1 - -INSERT INTO TEST VALUES(2, 'World'); -> update count: 1 - -SELECT id, sum(id) FROM test GROUP BY id ORDER BY id*sum(id); -> ID SUM(ID) -> -- ------- -> 1 1 -> 2 2 -> rows (ordered): 2 - -select * -from test t1 -inner join test t2 on t2.id=t1.id -inner join test t3 on t3.id=t2.id -where exists (select 1 from test t4 where t2.id=t4.id); -> ID NAME ID NAME ID NAME -> -- ----- -- ----- -- ----- -> 1 Hello 1 Hello 1 Hello -> 2 World 2 World 2 World -> rows: 2 - -explain select * from test t1 where id in(select id from test t2 where t1.id=t2.id); -> PLAN -> ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ -> SELECT T1.ID, T1.NAME FROM PUBLIC.TEST T1 /* PUBLIC.TEST.tableScan */ WHERE ID IN(SELECT DISTINCT ID FROM PUBLIC.TEST T2 /* PUBLIC.PRIMARY_KEY_2: ID = T1.ID */ WHERE T1.ID = T2.ID) -> rows: 1 - -select * from test t1 where id in(select id from test t2 where t1.id=t2.id); -> ID NAME -> -- ----- -> 1 Hello -> 2 World -> rows: 2 - -explain select * from test t1 where id in(id, id+1); -> PLAN -> ----------------------------------------------------------------------------------------------- -> SELECT T1.ID, T1.NAME FROM PUBLIC.TEST T1 /* PUBLIC.TEST.tableScan */ WHERE ID IN(ID, (ID + 1)) -> rows: 1 - -select * from test t1 where id in(id, id+1); -> ID NAME -> -- ----- -> 1 Hello -> 2 World -> rows: 2 - -explain select * from test t1 where id in(id); -> PLAN -> ----------------------------------------------------------------------------------- -> SELECT T1.ID, T1.NAME FROM PUBLIC.TEST T1 /* PUBLIC.TEST.tableScan */ WHERE ID = ID -> rows: 1 - -select * from test t1 where id in(id); -> ID NAME -> -- ----- -> 1 Hello -> 2 World -> rows: 2 - -explain select * from test t1 where id in(select id from test); -> PLAN -> --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -> SELECT T1.ID, T1.NAME FROM PUBLIC.TEST T1 /* PUBLIC.PRIMARY_KEY_2: ID IN(SELECT DISTINCT ID FROM PUBLIC.TEST /++ PUBLIC.TEST.tableScan ++/) */ WHERE ID IN(SELECT DISTINCT ID FROM PUBLIC.TEST /* PUBLIC.TEST.tableScan */) -> rows: 1 - -select * from test t1 where id in(select id from test); -> ID NAME -> -- ----- -> 1 Hello -> 2 World -> rows: 2 - -explain select * from test t1 where id in(1, select max(id) from test); -> PLAN -> ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -> SELECT T1.ID, T1.NAME FROM PUBLIC.TEST T1 /* PUBLIC.PRIMARY_KEY_2: ID IN(1, (SELECT MAX(ID) FROM PUBLIC.TEST /++ PUBLIC.TEST.tableScan ++/ /++ direct lookup ++/)) */ WHERE ID IN(1, (SELECT MAX(ID) FROM PUBLIC.TEST /* PUBLIC.TEST.tableScan */ /* direct lookup */)) -> rows: 1 - -select * from test t1 where id in(1, select max(id) from test); -> ID NAME -> -- ----- -> 1 Hello -> 2 World -> rows: 2 - -explain select * from test t1 where id in(1, select max(id) from test t2 where t1.id=t2.id); -> PLAN -> ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -> SELECT T1.ID, T1.NAME FROM PUBLIC.TEST T1 /* PUBLIC.TEST.tableScan */ WHERE ID IN(1, (SELECT MAX(ID) FROM PUBLIC.TEST T2 /* PUBLIC.PRIMARY_KEY_2: ID = T1.ID */ WHERE T1.ID = T2.ID)) -> rows: 1 - -select * from test t1 where id in(1, select max(id) from test t2 where t1.id=t2.id); -> ID NAME -> -- ----- -> 1 Hello -> 2 World -> rows: 2 - -DROP TABLE TEST; -> ok - -create force view t1 as select * from t1; -> ok - -select * from t1; -> exception - -drop table t1; -> ok - -create table one (id int primary key); -> ok - -create table two (id int primary key, val date); -> ok - -insert into one values(0); -> update count: 1 - -insert into one values(1); -> update count: 1 - -insert into one values(2); -> update count: 1 - -insert into two values(0, null); -> update count: 1 - -insert into two values(1, DATE'2006-01-01'); -> update count: 1 - -insert into two values(2, DATE'2006-07-01'); -> update count: 1 - -insert into two values(3, null); -> update count: 1 - -select * from one; -> ID -> -- -> 0 -> 1 -> 2 -> rows: 3 - -select * from two; -> ID VAL -> -- ---------- -> 0 null -> 1 2006-01-01 -> 2 2006-07-01 -> 3 null -> rows: 4 - --- Query #1: should return one row --- okay -select * from one natural join two left join two three on -one.id=three.id left join one four on two.id=four.id where three.val -is null; -> ID VAL ID VAL ID -> -- ---- -- ---- -- -> 0 null 0 null 0 -> rows: 1 - --- Query #2: should return one row --- okay -select * from one natural join two left join two three on -one.id=three.id left join one four on two.id=four.id where -three.val>=DATE'2006-07-01'; -> ID VAL ID VAL ID -> -- ---------- -- ---------- -- -> 2 2006-07-01 2 2006-07-01 2 -> rows: 1 - --- Query #3: should return the union of #1 and #2 -select * from one natural join two left join two three on -one.id=three.id left join one four on two.id=four.id where three.val -is null or three.val>=DATE'2006-07-01'; -> ID VAL ID VAL ID -> -- ---------- -- ---------- -- -> 0 null 0 null 0 -> 2 2006-07-01 2 2006-07-01 2 -> rows: 2 - -explain select * from one natural join two left join two three on -one.id=three.id left join one four on two.id=four.id where three.val -is null or three.val>=DATE'2006-07-01'; -> PLAN -> -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -> SELECT ONE.ID, TWO.VAL, THREE.ID, THREE.VAL, FOUR.ID FROM PUBLIC.ONE /* PUBLIC.ONE.tableScan */ INNER JOIN PUBLIC.TWO /* PUBLIC.PRIMARY_KEY_14: ID = PUBLIC.ONE.ID AND ID = PUBLIC.ONE.ID */ ON 1=1 /* WHERE PUBLIC.ONE.ID = PUBLIC.TWO.ID */ LEFT OUTER JOIN PUBLIC.TWO THREE /* PUBLIC.PRIMARY_KEY_14: ID = ONE.ID */ ON ONE.ID = THREE.ID LEFT OUTER JOIN PUBLIC.ONE FOUR /* PUBLIC.PRIMARY_KEY_1: ID = TWO.ID */ ON TWO.ID = FOUR.ID WHERE (PUBLIC.ONE.ID = PUBLIC.TWO.ID) AND ((THREE.VAL IS NULL) OR (THREE.VAL >= DATE '2006-07-01')) -> rows: 1 - --- Query #4: same as #3, but the joins have been manually re-ordered --- Correct result set, same as expected for #3. -select * from one natural join two left join one four on -two.id=four.id left join two three on one.id=three.id where three.val -is null or three.val>=DATE'2006-07-01'; -> ID VAL ID ID VAL -> -- ---------- -- -- ---------- -> 0 null 0 0 null -> 2 2006-07-01 2 2 2006-07-01 -> rows: 2 - -drop table one; -> ok - -drop table two; -> ok - -CREATE TABLE TEST(id INT PRIMARY KEY, foo BIGINT); -> ok - -INSERT INTO TEST VALUES(1, 100); -> update count: 1 - -INSERT INTO TEST VALUES(2, 123456789012345678); -> update count: 1 - -SELECT * FROM TEST WHERE foo = 123456789014567; -> ID FOO -> -- --- -> rows: 0 - -DROP TABLE IF EXISTS TEST; -> ok - -create table test1 (id int primary key); -> ok - -create table test2 (id int primary key); -> ok - -create table test3 (id int primary key); -> ok - -insert into test1 values(1); -> update count: 1 - -insert into test2 values(1); -> update count: 1 - -insert into test3 values(1); -> update count: 1 - -select * from test1 -inner join test2 on test1.id=test2.id left -outer join test3 on test2.id=test3.id -where test3.id is null; -> ID ID ID -> -- -- -- -> rows: 0 - -explain select * from test1 -inner join test2 on test1.id=test2.id left -outer join test3 on test2.id=test3.id -where test3.id is null; -> PLAN -> ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -> SELECT TEST1.ID, TEST2.ID, TEST3.ID FROM PUBLIC.TEST1 /* PUBLIC.TEST1.tableScan */ INNER JOIN PUBLIC.TEST2 /* PUBLIC.PRIMARY_KEY_4C: ID = TEST1.ID AND ID = TEST1.ID */ ON 1=1 /* WHERE TEST1.ID = TEST2.ID */ LEFT OUTER JOIN PUBLIC.TEST3 /* PUBLIC.PRIMARY_KEY_4C0: ID = TEST2.ID AND ID = NULL */ ON TEST2.ID = TEST3.ID WHERE (TEST3.ID IS NULL) AND (TEST1.ID = TEST2.ID) -> rows: 1 - -insert into test1 select x from system_range(2, 1000); -> update count: 999 - -select * from test1 -inner join test2 on test1.id=test2.id -left outer join test3 on test2.id=test3.id -where test3.id is null; -> ID ID ID -> -- -- -- -> rows: 0 - -explain select * from test1 -inner join test2 on test1.id=test2.id -left outer join test3 on test2.id=test3.id -where test3.id is null; -> PLAN -> ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -> SELECT TEST1.ID, TEST2.ID, TEST3.ID FROM PUBLIC.TEST2 /* PUBLIC.TEST2.tableScan */ LEFT OUTER JOIN PUBLIC.TEST3 /* PUBLIC.PRIMARY_KEY_4C0: ID = TEST2.ID AND ID = NULL */ ON TEST2.ID = TEST3.ID INNER JOIN PUBLIC.TEST1 /* PUBLIC.PRIMARY_KEY_4: ID = TEST2.ID */ ON 1=1 WHERE (TEST3.ID IS NULL) AND (TEST1.ID = TEST2.ID) -> rows: 1 - -SELECT TEST1.ID, TEST2.ID, TEST3.ID -FROM TEST2 -LEFT OUTER JOIN TEST3 ON TEST2.ID = TEST3.ID -INNER JOIN TEST1 -WHERE TEST3.ID IS NULL AND TEST1.ID = TEST2.ID; -> ID ID ID -> -- -- -- -> rows: 0 - -drop table test1; -> ok - -drop table test2; -> ok - -drop table test3; -> ok - -create table test(v boolean); -> ok - -insert into test values(null), (true), (false); -> update count: 3 - -SELECT CASE WHEN NOT (false IN (null)) THEN false END; -> NULL -> ---- -> null -> rows: 1 - -select a.v as av, b.v as bv, a.v IN (b.v), not a.v IN (b.v) from test a, test b; -> AV BV A.V = B.V NOT (A.V = B.V) -> ----- ----- --------- --------------- -> FALSE FALSE TRUE FALSE -> FALSE TRUE FALSE TRUE -> FALSE null null null -> TRUE FALSE FALSE TRUE -> TRUE TRUE TRUE FALSE -> TRUE null null null -> null FALSE null null -> null TRUE null null -> null null null null -> rows: 9 - -select a.v as av, b.v as bv, a.v IN (b.v, null), not a.v IN (b.v, null) from test a, test b; -> AV BV A.V IN(B.V, NULL) NOT (A.V IN(B.V, NULL)) -> ----- ----- ----------------- ----------------------- -> FALSE FALSE TRUE FALSE -> FALSE TRUE null null -> FALSE null null null -> TRUE FALSE null null -> TRUE TRUE TRUE FALSE -> TRUE null null null -> null FALSE null null -> null TRUE null null -> null null null null -> rows: 9 - -drop table test; -> ok - -SELECT CASE WHEN NOT (false IN (null)) THEN false END; -> NULL -> ---- -> null -> rows: 1 - -SELECT DATEDIFF('SECOND', '1900-01-01 00:00:00.001', '1900-01-01 00:00:00.002'), DATEDIFF('SECOND', '2000-01-01 00:00:00.001', '2000-01-01 00:00:00.002'); -> 0 0 -> - - -> 0 0 -> rows: 1 - -SELECT DATEDIFF('SECOND', '1900-01-01 00:00:00.000', '1900-01-01 00:00:00.001'), DATEDIFF('SECOND', '2000-01-01 00:00:00.000', '2000-01-01 00:00:00.001'); -> 0 0 -> - - -> 0 0 -> rows: 1 - -SELECT DATEDIFF('MINUTE', '1900-01-01 00:00:00.000', '1900-01-01 00:00:01.000'), DATEDIFF('MINUTE', '2000-01-01 00:00:00.000', '2000-01-01 00:00:01.000'); -> 0 0 -> - - -> 0 0 -> rows: 1 - -SELECT DATEDIFF('MINUTE', '1900-01-01 00:00:01.000', '1900-01-01 00:00:02.000'), DATEDIFF('MINUTE', '2000-01-01 00:00:01.000', '2000-01-01 00:00:02.000'); -> 0 0 -> - - -> 0 0 -> rows: 1 - -SELECT DATEDIFF('HOUR', '1900-01-01 00:00:00.000', '1900-01-01 00:00:01.000'), DATEDIFF('HOUR', '2000-01-01 00:00:00.000', '2000-01-01 00:00:01.000'); -> 0 0 -> - - -> 0 0 -> rows: 1 - -SELECT DATEDIFF('HOUR', '1900-01-01 00:00:00.001', '1900-01-01 00:00:01.000'), DATEDIFF('HOUR', '2000-01-01 00:00:00.001', '2000-01-01 00:00:01.000'); -> 0 0 -> - - -> 0 0 -> rows: 1 - -SELECT DATEDIFF('HOUR', '1900-01-01 01:00:00.000', '1900-01-01 01:00:01.000'), DATEDIFF('HOUR', '2000-01-01 01:00:00.000', '2000-01-01 01:00:01.000'); -> 0 0 -> - - -> 0 0 -> rows: 1 - -SELECT DATEDIFF('HOUR', '1900-01-01 01:00:00.001', '1900-01-01 01:00:01.000'), DATEDIFF('HOUR', '2000-01-01 01:00:00.001', '2000-01-01 01:00:01.000'); -> 0 0 -> - - -> 0 0 -> rows: 1 - -create table test(id int); -> ok - -insert into test values(1), (2), (3), (4); -> update count: 4 - -(select * from test a, test b) minus (select * from test a, test b); -> ID ID -> -- -- -> rows: 0 - -drop table test; -> ok - -call datediff('MS', TIMESTAMP '2001-02-03 04:05:06.789001', TIMESTAMP '2001-02-03 04:05:06.789002'); -> 0 -> - -> 0 -> rows: 1 - -call datediff('MS', TIMESTAMP '1900-01-01 00:00:01.000', TIMESTAMP '2008-01-01 00:00:00.000'); -> 3408134399000 -> ------------- -> 3408134399000 -> rows: 1 - -call select 1.0/3.0*3.0, 100.0/2.0, -25.0/100.0, 0.0/3.0, 6.9/2.0; -> C1 C2 C3 C4 C5 -> ----------------------------- -- ----- -- ---- -> 0.999999999999999999999999990 50 -0.25 0 3.45 -> rows: 1 - -call dateadd('MS', 1, TIMESTAMP '2001-02-03 04:05:06.789001'); -> TIMESTAMP '2001-02-03 04:05:06.790001' -> -------------------------------------- -> 2001-02-03 04:05:06.790001 -> rows: 1 - -CALL 1 /* comment */ ;; -> 1 -> - -> 1 -> rows: 1 - -CALL 1 /* comment */ ; -> 1 -> - -> 1 -> rows: 1 - -call /* remark * / * /* ** // end */ 1; -> 1 -> - -> 1 -> rows: 1 - -call (select x from dual where x is null); -> SELECT X FROM SYSTEM_RANGE(1, 1) /* PUBLIC.RANGE_INDEX: X = NULL */ /* scanCount: 1 */ WHERE X IS NULL -> ------------------------------------------------------------------------------------------------------ -> null -> rows: 1 - -create sequence test_seq; -> ok - -create table test(id int primary key, parent int); -> ok - -create index ni on test(parent); -> ok - -alter table test add constraint nu unique(parent); -> ok - -alter table test add constraint fk foreign key(parent) references(id); -> ok - -select TABLE_NAME, NON_UNIQUE, INDEX_NAME, ORDINAL_POSITION, COLUMN_NAME, CARDINALITY, PRIMARY_KEY from INFORMATION_SCHEMA.INDEXES; -> TABLE_NAME NON_UNIQUE INDEX_NAME ORDINAL_POSITION COLUMN_NAME CARDINALITY PRIMARY_KEY -> ---------- ---------- ------------- ---------------- ----------- ----------- ----------- -> TEST FALSE NU_INDEX_2 1 PARENT 0 FALSE -> TEST FALSE PRIMARY_KEY_2 1 ID 0 TRUE -> TEST TRUE NI 1 PARENT 0 FALSE -> rows: 3 - -select SEQUENCE_NAME, CURRENT_VALUE, INCREMENT, IS_GENERATED, REMARKS from INFORMATION_SCHEMA.SEQUENCES; -> SEQUENCE_NAME CURRENT_VALUE INCREMENT IS_GENERATED REMARKS -> ------------- ------------- --------- ------------ ------- -> TEST_SEQ 0 1 FALSE -> rows: 1 - -drop table test; -> ok - -drop sequence test_seq; -> ok - -create table test(id int); -> ok - -insert into test values(1), (2); -> update count: 2 - -select count(*) from test where id in ((select id from test where 1=0)); -> COUNT(*) -> -------- -> 0 -> rows: 1 - -select count(*) from test where id = ((select id from test where 1=0)+1); -> COUNT(*) -> -------- -> 0 -> rows: 1 - -select count(*) from test where id = (select id from test where 1=0); -> COUNT(*) -> -------- -> 0 -> rows: 1 - -select count(*) from test where id in ((select id from test)); -> COUNT(*) -> -------- -> 2 -> rows: 1 - -select count(*) from test where id = ((select id from test)); -> exception - -select count(*) from test where id = ((select id from test), 1); -> exception - -select (select id from test where 1=0) from test; -> SELECT ID FROM PUBLIC.TEST /* PUBLIC.TEST.tableScan: FALSE */ WHERE FALSE -> ------------------------------------------------------------------------- -> null -> null -> rows: 2 - -drop table test; -> ok - -select TRIM(' ' FROM ' abc ') from dual; -> 'abc' -> ----- -> abc -> rows: 1 - -create table test(id int primary key, a boolean); -> ok - -insert into test values(1, 'Y'); -> update count: 1 - -call select a from test order by id; -> SELECT A FROM PUBLIC.TEST /* PUBLIC.PRIMARY_KEY_2 */ /* scanCount: 2 */ ORDER BY =ID /* index sorted */ -> ------------------------------------------------------------------------------------------------------- -> TRUE -> rows (ordered): 1 - -select select a from test order by id; -> SELECT A FROM PUBLIC.TEST /* PUBLIC.PRIMARY_KEY_2 */ /* scanCount: 2 */ ORDER BY =ID /* index sorted */ -> ------------------------------------------------------------------------------------------------------- -> TRUE -> rows (ordered): 1 - -insert into test values(2, 'N'); -> update count: 1 - -insert into test values(3, '1'); -> update count: 1 - -insert into test values(4, '0'); -> update count: 1 - -insert into test values(5, 'T'); -> update count: 1 - -insert into test values(6, 'F'); -> update count: 1 - -select max(id) from test where id = max(id) group by id; -> exception - -select * from test where a=TRUE=a; -> ID A -> -- ----- -> 1 TRUE -> 2 FALSE -> 3 TRUE -> 4 FALSE -> 5 TRUE -> 6 FALSE -> rows: 6 - -drop table test; -> ok - -CREATE memory TABLE TEST(ID INT PRIMARY KEY, PARENT INT REFERENCES TEST); -> ok - -CREATE memory TABLE s(S_NO VARCHAR(5) PRIMARY KEY, name VARCHAR(16), city VARCHAR(16)); -> ok - -CREATE memory TABLE p(p_no VARCHAR(5) PRIMARY KEY, descr VARCHAR(16), color VARCHAR(8)); -> ok - -CREATE memory TABLE sp1(S_NO VARCHAR(5) REFERENCES s, p_no VARCHAR(5) REFERENCES p, qty INT, PRIMARY KEY (S_NO, p_no)); -> ok - -CREATE memory TABLE sp2(S_NO VARCHAR(5), p_no VARCHAR(5), qty INT, constraint c1 FOREIGN KEY (S_NO) references s, PRIMARY KEY (S_NO, p_no)); -> ok - -script NOPASSWORDS NOSETTINGS; -> SCRIPT -> ------------------------------------------------------------------------------------------------------------------- -> -- 0 +/- SELECT COUNT(*) FROM PUBLIC.P; -> -- 0 +/- SELECT COUNT(*) FROM PUBLIC.S; -> -- 0 +/- SELECT COUNT(*) FROM PUBLIC.SP1; -> -- 0 +/- SELECT COUNT(*) FROM PUBLIC.SP2; -> -- 0 +/- SELECT COUNT(*) FROM PUBLIC.TEST; -> ALTER TABLE PUBLIC.P ADD CONSTRAINT PUBLIC.CONSTRAINT_50_0 PRIMARY KEY(P_NO); -> ALTER TABLE PUBLIC.S ADD CONSTRAINT PUBLIC.CONSTRAINT_5 PRIMARY KEY(S_NO); -> ALTER TABLE PUBLIC.SP1 ADD CONSTRAINT PUBLIC.CONSTRAINT_1 FOREIGN KEY(S_NO) REFERENCES PUBLIC.S(S_NO) NOCHECK; -> ALTER TABLE PUBLIC.SP1 ADD CONSTRAINT PUBLIC.CONSTRAINT_14 FOREIGN KEY(P_NO) REFERENCES PUBLIC.P(P_NO) NOCHECK; -> ALTER TABLE PUBLIC.SP1 ADD CONSTRAINT PUBLIC.CONSTRAINT_141 PRIMARY KEY(S_NO, P_NO); -> ALTER TABLE PUBLIC.SP2 ADD CONSTRAINT PUBLIC.C1 FOREIGN KEY(S_NO) REFERENCES PUBLIC.S(S_NO) NOCHECK; -> ALTER TABLE PUBLIC.SP2 ADD CONSTRAINT PUBLIC.CONSTRAINT_1417 PRIMARY KEY(S_NO, P_NO); -> ALTER TABLE PUBLIC.TEST ADD CONSTRAINT PUBLIC.CONSTRAINT_2 PRIMARY KEY(ID); -> ALTER TABLE PUBLIC.TEST ADD CONSTRAINT PUBLIC.CONSTRAINT_27 FOREIGN KEY(PARENT) REFERENCES PUBLIC.TEST(ID) NOCHECK; -> CREATE MEMORY TABLE PUBLIC.P( P_NO VARCHAR(5) NOT NULL, DESCR VARCHAR(16), COLOR VARCHAR(8) ); -> CREATE MEMORY TABLE PUBLIC.S( S_NO VARCHAR(5) NOT NULL, NAME VARCHAR(16), CITY VARCHAR(16) ); -> CREATE MEMORY TABLE PUBLIC.SP1( S_NO VARCHAR(5) NOT NULL, P_NO VARCHAR(5) NOT NULL, QTY INT ); -> CREATE MEMORY TABLE PUBLIC.SP2( S_NO VARCHAR(5) NOT NULL, P_NO VARCHAR(5) NOT NULL, QTY INT ); -> CREATE MEMORY TABLE PUBLIC.TEST( ID INT NOT NULL, PARENT INT ); -> CREATE USER IF NOT EXISTS SA PASSWORD '' ADMIN; -> rows: 20 - -drop table test; -> ok - -drop table sp1; -> ok - -drop table sp2; -> ok - -drop table s; -> ok - -drop table p; -> ok - -create table test (id identity, value int not null); -> ok - -create primary key on test(id); -> exception - -alter table test drop primary key; -> ok - -alter table test drop primary key; -> exception - -create primary key on test(id, id, id); -> ok - -alter table test drop primary key; -> ok - -drop table test; -> ok - -set autocommit off; -> ok - -create local temporary table test (id identity, b int, foreign key(b) references(id)); -> ok - -drop table test; -> ok - -script NOPASSWORDS NOSETTINGS drop; -> SCRIPT -> ----------------------------------------------- -> CREATE USER IF NOT EXISTS SA PASSWORD '' ADMIN; -> rows: 1 - -create local temporary table test1 (id identity); -> ok - -create local temporary table test2 (id identity); -> ok - -alter table test2 add constraint test2_test1 foreign key (id) references test1; -> ok - -drop table test1; -> ok - -drop table test2; -> ok - -create local temporary table test1 (id identity); -> ok - -create local temporary table test2 (id identity); -> ok - -alter table test2 add constraint test2_test1 foreign key (id) references test1; -> ok - -drop table test1; -> ok - -drop table test2; -> ok - -set autocommit on; -> ok - -create table test(id int primary key, ref int, foreign key(ref) references(id)); -> ok - -insert into test values(1, 1), (2, 2); -> update count: 2 - -update test set ref=3-ref; -> update count: 2 - -alter table test add column dummy int; -> ok - -insert into test values(4, 4, null); -> update count: 1 - -drop table test; -> ok - -create table test(id int primary key); -> ok - -explain select * from test a inner join test b left outer join test c on c.id = a.id; -> PLAN -> --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -> SELECT A.ID, C.ID, B.ID FROM PUBLIC.TEST A /* PUBLIC.TEST.tableScan */ LEFT OUTER JOIN PUBLIC.TEST C /* PUBLIC.PRIMARY_KEY_2: ID = A.ID */ ON C.ID = A.ID INNER JOIN PUBLIC.TEST B /* PUBLIC.TEST.tableScan */ ON 1=1 -> rows: 1 - -SELECT T.ID FROM TEST "T"; -> ID -> -- -> rows: 0 - -SELECT T."ID" FROM TEST "T"; -> ID -> -- -> rows: 0 - -SELECT "T".ID FROM TEST "T"; -> ID -> -- -> rows: 0 - -SELECT "T"."ID" FROM TEST "T"; -> ID -> -- -> rows: 0 - -SELECT T.ID FROM "TEST" T; -> ID -> -- -> rows: 0 - -SELECT T."ID" FROM "TEST" T; -> ID -> -- -> rows: 0 - -SELECT "T".ID FROM "TEST" T; -> ID -> -- -> rows: 0 - -SELECT "T"."ID" FROM "TEST" T; -> ID -> -- -> rows: 0 - -SELECT T.ID FROM "TEST" "T"; -> ID -> -- -> rows: 0 - -SELECT T."ID" FROM "TEST" "T"; -> ID -> -- -> rows: 0 - -SELECT "T".ID FROM "TEST" "T"; -> ID -> -- -> rows: 0 - -SELECT "T"."ID" FROM "TEST" "T"; -> ID -> -- -> rows: 0 - -select "TEST".id from test; -> ID -> -- -> rows: 0 - -select test."ID" from test; -> ID -> -- -> rows: 0 - -select test."id" from test; -> exception - -select "TEST"."ID" from test; -> ID -> -- -> rows: 0 - -select "test"."ID" from test; -> exception - -select public."TEST".id from test; -> ID -> -- -> rows: 0 - -select public.test."ID" from test; -> ID -> -- -> rows: 0 - -select public."TEST"."ID" from test; -> ID -> -- -> rows: 0 - -select public."test"."ID" from test; -> exception - -select "PUBLIC"."TEST".id from test; -> ID -> -- -> rows: 0 - -select "PUBLIC".test."ID" from test; -> ID -> -- -> rows: 0 - -select public."TEST"."ID" from test; -> ID -> -- -> rows: 0 - -select "public"."TEST"."ID" from test; -> exception - -drop table test; -> ok - -create schema s authorization sa; -> ok - -create memory table s.test(id int); -> ok - -create index if not exists idx_id on s.test(id); -> ok - -create index if not exists idx_id on s.test(id); -> ok - -alter index s.idx_id rename to s.index_id; -> ok - -create sequence s.seq; -> ok - -alter sequence s.seq restart with 10; -> ok - -alter table s.test add constraint cu_id unique(id); -> ok - -alter table s.test add name varchar; -> ok - -alter table s.test drop column name; -> ok - -alter table s.test drop constraint cu_id; -> ok - -alter table s.test rename to testtab; -> ok - -alter table s.testtab rename to test; -> ok - -create trigger test_trigger before insert on s.test call "org.h2.test.db.TestTriggersConstraints"; -> ok - -script NOPASSWORDS NOSETTINGS drop; -> SCRIPT -> --------------------------------------------------------------------------------------------------------------------- -> -- 0 +/- SELECT COUNT(*) FROM S.TEST; -> CREATE FORCE TRIGGER S.TEST_TRIGGER BEFORE INSERT ON S.TEST QUEUE 1024 CALL "org.h2.test.db.TestTriggersConstraints"; -> CREATE INDEX S.INDEX_ID ON S.TEST(ID); -> CREATE MEMORY TABLE S.TEST( ID INT ); -> CREATE SCHEMA IF NOT EXISTS S AUTHORIZATION SA; -> CREATE SEQUENCE S.SEQ START WITH 10; -> CREATE USER IF NOT EXISTS SA PASSWORD '' ADMIN; -> DROP SEQUENCE IF EXISTS S.SEQ; -> DROP TABLE IF EXISTS S.TEST; -> rows: 9 - -drop trigger s.test_trigger; -> ok - -drop schema s; -> ok - -CREATE MEMORY TABLE TEST(ID INT PRIMARY KEY, NAME VARCHAR(255), y int as id+1); -> ok - -INSERT INTO TEST(id, name) VALUES(1, 'Hello'); -> update count: 1 - -create index idx_n_id on test(name, id); -> ok - -alter table test add constraint abc foreign key(id) references (id); -> ok - -alter table test alter column id rename to i; -> ok - -script NOPASSWORDS NOSETTINGS drop; -> SCRIPT -> --------------------------------------------------------------------------------------------------- -> -- 1 +/- SELECT COUNT(*) FROM PUBLIC.TEST; -> ALTER TABLE PUBLIC.TEST ADD CONSTRAINT PUBLIC.ABC FOREIGN KEY(I) REFERENCES PUBLIC.TEST(I) NOCHECK; -> ALTER TABLE PUBLIC.TEST ADD CONSTRAINT PUBLIC.CONSTRAINT_2 PRIMARY KEY(I); -> CREATE INDEX PUBLIC.IDX_N_ID ON PUBLIC.TEST(NAME, I); -> CREATE MEMORY TABLE PUBLIC.TEST( I INT NOT NULL, NAME VARCHAR(255), Y INT AS (I + 1) ); -> CREATE USER IF NOT EXISTS SA PASSWORD '' ADMIN; -> DROP TABLE IF EXISTS PUBLIC.TEST; -> INSERT INTO PUBLIC.TEST(I, NAME, Y) VALUES (1, 'Hello', 2); -> rows: 8 - -INSERT INTO TEST(i, name) VALUES(2, 'World'); -> update count: 1 - -SELECT * FROM TEST ORDER BY I; -> I NAME Y -> - ----- - -> 1 Hello 2 -> 2 World 3 -> rows (ordered): 2 - -UPDATE TEST SET NAME='Hi' WHERE I=1; -> update count: 1 - -DELETE FROM TEST t0 WHERE t0.I=2; -> update count: 1 - -drop table test; -> ok - -create table test(current int); -> ok - -select current from test; -> CURRENT -> ------- -> rows: 0 - -drop table test; -> ok - -CREATE table my_table(my_int integer, my_char varchar); -> ok - -INSERT INTO my_table VALUES(1, 'Testing'); -> update count: 1 - -ALTER TABLE my_table ALTER COLUMN my_int RENAME to my_new_int; -> ok - -SELECT my_new_int FROM my_table; -> MY_NEW_INT -> ---------- -> 1 -> rows: 1 - -UPDATE my_table SET my_new_int = 33; -> update count: 1 - -SELECT * FROM my_table; -> MY_NEW_INT MY_CHAR -> ---------- ------- -> 33 Testing -> rows: 1 - -DROP TABLE my_table; -> ok - -create sequence seq1; -> ok - -create table test(ID INT default next value for seq1); -> ok - -drop sequence seq1; -> exception - -alter table test add column name varchar; -> ok - -insert into test(name) values('Hello'); -> update count: 1 - -select * from test; -> ID NAME -> -- ----- -> 1 Hello -> rows: 1 - -drop table test; -> ok - -drop sequence seq1; -> ok - -create table test(a int primary key, b int, c int); -> ok - -create unique index idx_ba on test(b, a); -> ok - -alter table test add constraint abc foreign key(c, a) references test(b, a); -> ok - -insert into test values(1, 1, null); -> update count: 1 - -drop table test; -> ok - -create table ADDRESS (ADDRESS_ID int primary key, ADDRESS_TYPE int not null, SERVER_ID int not null); -> ok - -create unique index idx_a on address(ADDRESS_TYPE, SERVER_ID); -> ok - -create table SERVER (SERVER_ID int primary key, SERVER_TYPE int not null, ADDRESS_TYPE int); -> ok - -alter table ADDRESS add constraint addr foreign key (SERVER_ID) references SERVER; -> ok - -alter table SERVER add constraint server_const foreign key (ADDRESS_TYPE, SERVER_ID) references ADDRESS (ADDRESS_TYPE, SERVER_ID); -> ok - -insert into SERVER (SERVER_ID, SERVER_TYPE) values (1, 1); -> update count: 1 - -drop table address; -> ok - -drop table server; -> ok - -create table left_hand (id int primary key); -> ok - -create table right_hand (id int primary key); -> ok - -insert into left_hand values(0); -> update count: 1 - -insert into left_hand values(1); -> update count: 1 - -insert into right_hand values(0); -> update count: 1 - --- h2, postgresql, mysql, derby, hsqldb: 2 -select * from left_hand left outer join right_hand on left_hand.id=right_hand.id; -> ID ID -> -- ---- -> 0 0 -> 1 null -> rows: 2 - --- h2, postgresql, mysql, derby, hsqldb: 2 -select * from left_hand left join right_hand on left_hand.id=right_hand.id; -> ID ID -> -- ---- -> 0 0 -> 1 null -> rows: 2 - --- h2: 1 (2 cols); postgresql, mysql: 1 (1 col); derby, hsqldb: no natural join -select * from left_hand natural join right_hand; -> ID -> -- -> 0 -> rows: 1 - --- h2, postgresql, mysql, derby, hsqldb: 1 -select * from left_hand left outer join right_hand on left_hand.id=right_hand.id where left_hand.id=1; -> ID ID -> -- ---- -> 1 null -> rows: 1 - --- h2, postgresql, mysql, derby, hsqldb: 1 -select * from left_hand left join right_hand on left_hand.id=right_hand.id where left_hand.id=1; -> ID ID -> -- ---- -> 1 null -> rows: 1 - --- h2: 0 (2 cols); postgresql, mysql: 0 (1 col); derby, hsqldb: no natural join -select * from left_hand natural join right_hand where left_hand.id=1; -> ID -> -- -> rows: 0 - --- !!! h2: 1; postgresql, mysql, hsqldb: 0; derby: exception -select * from left_hand left outer join right_hand on left_hand.id=right_hand.id where left_hand.id=1 having right_hand.id=2; -> ID ID -> -- -- -> rows: 0 - --- !!! h2: 1; postgresql, mysql, hsqldb: 0; derby: exception -select * from left_hand left join right_hand on left_hand.id=right_hand.id where left_hand.id=1 having right_hand.id=2; -> ID ID -> -- -- -> rows: 0 - --- h2: 0 (2 cols); postgresql: 0 (1 col), mysql: exception; derby, hsqldb: no natural join -select * from left_hand natural join right_hand where left_hand.id=1 having right_hand.id=2; -> exception - --- h2, mysql, hsqldb: 0 rows; postgresql, derby: exception -select * from left_hand left outer join right_hand on left_hand.id=right_hand.id where left_hand.id=1 group by left_hand.id having right_hand.id=2; -> ID ID -> -- -- -> rows: 0 - --- h2, mysql, hsqldb: 0 rows; postgresql, derby: exception -select * from left_hand left join right_hand on left_hand.id=right_hand.id where left_hand.id=1 group by left_hand.id having right_hand.id=2; -> ID ID -> -- -- -> rows: 0 - --- h2: 0 rows; postgresql, mysql: exception; derby, hsqldb: no natural join -select * from left_hand natural join right_hand where left_hand.id=1 group by left_hand.id having right_hand.id=2; -> ID -> -- -> rows: 0 - -drop table right_hand; -> ok - -drop table left_hand; -> ok - -CREATE TABLE PlanElements(id int primary key, name varchar, parent_id int, foreign key(parent_id) references(id) on delete cascade); -> ok - -INSERT INTO PlanElements(id,name,parent_id) VALUES(1, '#1', null), (2, '#1-A', 1), (3, '#1-A-1', 2), (4, '#1-A-2', 2); -> update count: 4 - -INSERT INTO PlanElements(id,name,parent_id) VALUES(5, '#1-B', 1), (6, '#1-B-1', 5), (7, '#1-B-2', 5); -> update count: 3 - -INSERT INTO PlanElements(id,name,parent_id) VALUES(8, '#1-C', 1), (9, '#1-C-1', 8), (10, '#1-C-2', 8); -> update count: 3 - -INSERT INTO PlanElements(id,name,parent_id) VALUES(11, '#1-D', 1), (12, '#1-D-1', 11), (13, '#1-D-2', 11), (14, '#1-D-3', 11); -> update count: 4 - -INSERT INTO PlanElements(id,name,parent_id) VALUES(15, '#1-E', 1), (16, '#1-E-1', 15), (17, '#1-E-2', 15), (18, '#1-E-3', 15), (19, '#1-E-4', 15); -> update count: 5 - -DELETE FROM PlanElements WHERE id = 1; -> update count: 1 - -SELECT * FROM PlanElements; -> ID NAME PARENT_ID -> -- ---- --------- -> rows: 0 - -DROP TABLE PlanElements; -> ok - -CREATE TABLE PARENT(ID INT PRIMARY KEY, NAME VARCHAR(255)); -> ok - -CREATE TABLE CHILD(ID INT PRIMARY KEY, NAME VARCHAR(255), FOREIGN KEY(NAME) REFERENCES PARENT(ID)); -> ok - -INSERT INTO PARENT VALUES(1, '1'); -> update count: 1 - -INSERT INTO CHILD VALUES(1, '1'); -> update count: 1 - -INSERT INTO CHILD VALUES(2, 'Hello'); -> exception - -DROP TABLE IF EXISTS CHILD; -> ok - -DROP TABLE IF EXISTS PARENT; -> ok - -(SELECT * FROM DUAL) UNION ALL (SELECT * FROM DUAL); -> X -> - -> 1 -> 1 -> rows: 2 - -DECLARE GLOBAL TEMPORARY TABLE TEST(ID INT PRIMARY KEY); -> ok - -SELECT * FROM TEST; -> ID -> -- -> rows: 0 - -SELECT GROUP_CONCAT(ID) FROM TEST; -> GROUP_CONCAT(ID) -> ---------------- -> null -> rows: 1 - -SELECT * FROM SESSION.TEST; -> ID -> -- -> rows: 0 - -DROP TABLE TEST; -> ok - -VALUES(1, 2); -> C1 C2 -> -- -- -> 1 2 -> rows: 1 - -DROP TABLE IF EXISTS TEST; -> ok - -CREATE TABLE TEST(ID INT PRIMARY KEY, NAME VARCHAR(255)); -> ok - -INSERT INTO TEST VALUES(1, 'Hello'); -> update count: 1 - -INSERT INTO TEST VALUES(2, 'World'); -> update count: 1 - -SELECT group_concat(name) FROM TEST group by id; -> GROUP_CONCAT(NAME) -> ------------------ -> Hello -> World -> rows: 2 - -drop table test; -> ok - ---- script drop --------------------------------------------------------------------------------------------- -create memory table test (id int primary key, im_ie varchar(10)); -> ok - -create sequence test_seq; -> ok - -script NODATA NOPASSWORDS NOSETTINGS drop; -> SCRIPT -> ------------------------------------------------------------------------------ -> -- 0 +/- SELECT COUNT(*) FROM PUBLIC.TEST; -> ALTER TABLE PUBLIC.TEST ADD CONSTRAINT PUBLIC.CONSTRAINT_2 PRIMARY KEY(ID); -> CREATE MEMORY TABLE PUBLIC.TEST( ID INT NOT NULL, IM_IE VARCHAR(10) ); -> CREATE SEQUENCE PUBLIC.TEST_SEQ START WITH 1; -> CREATE USER IF NOT EXISTS SA PASSWORD '' ADMIN; -> DROP SEQUENCE IF EXISTS PUBLIC.TEST_SEQ; -> DROP TABLE IF EXISTS PUBLIC.TEST; -> rows: 7 - -drop sequence test_seq; -> ok - -drop table test; -> ok - ---- constraints --------------------------------------------------------------------------------------------- -CREATE MEMORY TABLE TEST(ID IDENTITY(100, 10), NAME VARCHAR); -> ok - -INSERT INTO TEST(NAME) VALUES('Hello'), ('World'); -> update count: 2 - -SELECT * FROM TEST; -> ID NAME -> --- ----- -> 100 Hello -> 110 World -> rows: 2 - -DROP TABLE TEST; -> ok - -CREATE MEMORY TABLE TEST(ID BIGINT NOT NULL IDENTITY(10, 5), NAME VARCHAR); -> ok - -INSERT INTO TEST(NAME) VALUES('Hello'), ('World'); -> update count: 2 - -SELECT * FROM TEST; -> ID NAME -> -- ----- -> 10 Hello -> 15 World -> rows: 2 - -DROP TABLE TEST; -> ok - -CREATE CACHED TABLE account( -id INTEGER NOT NULL IDENTITY, -name VARCHAR NOT NULL, -mail_address VARCHAR NOT NULL, -UNIQUE(name), -PRIMARY KEY(id) -); -> ok - -CREATE CACHED TABLE label( -id INTEGER NOT NULL IDENTITY, -parent_id INTEGER NOT NULL, -account_id INTEGER NOT NULL, -name VARCHAR NOT NULL, -PRIMARY KEY(id), -UNIQUE(parent_id, name), -UNIQUE(id, account_id), -FOREIGN KEY(account_id) REFERENCES account (id), -FOREIGN KEY(parent_id, account_id) REFERENCES label (id, account_id) -); -> ok - -INSERT INTO account VALUES (0, 'example', 'example@example.com'); -> update count: 1 - -INSERT INTO label VALUES ( 0, 0, 0, 'TEST'); -> update count: 1 - -INSERT INTO label VALUES ( 1, 0, 0, 'TEST'); -> exception - -INSERT INTO label VALUES ( 1, 0, 0, 'TEST1'); -> update count: 1 - -INSERT INTO label VALUES ( 2, 2, 1, 'TEST'); -> exception - -drop table label; -> ok - -drop table account; -> ok - ---- constraints and alter table add column --------------------------------------------------------------------------------------------- -CREATE TABLE TEST(ID INT, PARENTID INT, FOREIGN KEY(PARENTID) REFERENCES(ID)); -> ok - -INSERT INTO TEST VALUES(0, 0); -> update count: 1 - -ALTER TABLE TEST ADD COLUMN CHILD_ID INT; -> ok - -ALTER TABLE TEST ALTER COLUMN CHILD_ID VARCHAR; -> ok - -ALTER TABLE TEST ALTER COLUMN PARENTID VARCHAR; -> ok - -ALTER TABLE TEST DROP COLUMN PARENTID; -> exception - -ALTER TABLE TEST DROP COLUMN CHILD_ID; -> ok - -SELECT * FROM TEST; -> ID PARENTID -> -- -------- -> 0 0 -> rows: 1 - -DROP TABLE TEST; -> ok - -CREATE MEMORY TABLE A(X INT); -> ok - -CREATE MEMORY TABLE B(XX INT, CONSTRAINT B2A FOREIGN KEY(XX) REFERENCES A(X)); -> ok - -CREATE MEMORY TABLE C(X_MASTER INT); -> ok - -ALTER TABLE A ADD CONSTRAINT A2C FOREIGN KEY(X) REFERENCES C(X_MASTER); -> ok - -insert into c values(1); -> update count: 1 - -insert into a values(1); -> update count: 1 - -insert into b values(1); -> update count: 1 - -ALTER TABLE A ADD COLUMN Y INT; -> ok - -insert into c values(2); -> update count: 1 - -insert into a values(2, 2); -> update count: 1 - -insert into b values(2); -> update count: 1 - -DROP TABLE IF EXISTS A; -> ok - -DROP TABLE IF EXISTS B; -> ok - -DROP TABLE IF EXISTS C; -> ok - ---- quoted keywords --------------------------------------------------------------------------------------------- -CREATE TABLE "CREATE"("SELECT" INT, "PRIMARY" INT, "KEY" INT, "INDEX" INT, "ROWNUM" INT, "NEXTVAL" INT, "FROM" INT); -> ok - -INSERT INTO "CREATE" default values; -> update count: 1 - -INSERT INTO "CREATE" default values; -> update count: 1 - -SELECT "ROWNUM", ROWNUM, "SELECT" "AS", "PRIMARY" AS "X", "KEY", "NEXTVAL", "INDEX", "SELECT" "FROM" FROM "CREATE"; -> ROWNUM ROWNUM() AS X KEY NEXTVAL INDEX FROM -> ------ -------- ---- ---- ---- ------- ----- ---- -> null 1 null null null null null null -> null 2 null null null null null null -> rows: 2 - -DROP TABLE "CREATE"; -> ok - ---- truncate table --------------------------------------------------------------------------------------------- -CREATE TABLE TEST(ID INT PRIMARY KEY, NAME VARCHAR); -> ok - -INSERT INTO TEST VALUES(1, 'Hello'), (2, 'World'); -> update count: 2 - -TRUNCATE TABLE TEST; -> ok - -SELECT * FROM TEST; -> ID NAME -> -- ---- -> rows: 0 - -DROP TABLE TEST; -> ok - -CREATE TABLE PARENT(ID INT PRIMARY KEY, NAME VARCHAR); -> ok - -CREATE TABLE CHILD(PARENTID INT, FOREIGN KEY(PARENTID) REFERENCES PARENT(ID), NAME VARCHAR); -> ok - -TRUNCATE TABLE CHILD; -> ok - -TRUNCATE TABLE PARENT; -> exception - -DROP TABLE CHILD; -> ok - -DROP TABLE PARENT; -> ok - ---- test case for number like string --------------------------------------------------------------------------------------------- -CREATE TABLE test (one bigint primary key, two bigint, three bigint); -> ok - -CREATE INDEX two ON test(two); -> ok - -INSERT INTO TEST VALUES(1, 2, 3), (10, 20, 30), (100, 200, 300); -> update count: 3 - -INSERT INTO TEST VALUES(2, 6, 9), (20, 60, 90), (200, 600, 900); -> update count: 3 - -SELECT * FROM test WHERE one LIKE '2%'; -> ONE TWO THREE -> --- --- ----- -> 2 6 9 -> 20 60 90 -> 200 600 900 -> rows: 3 - -SELECT * FROM test WHERE two LIKE '2%'; -> ONE TWO THREE -> --- --- ----- -> 1 2 3 -> 10 20 30 -> 100 200 300 -> rows: 3 - -SELECT * FROM test WHERE three LIKE '2%'; -> ONE TWO THREE -> --- --- ----- -> rows: 0 - -DROP TABLE TEST; -> ok - ---- merge (upsert) --------------------------------------------------------------------------------------------- -CREATE TABLE TEST(ID INT PRIMARY KEY, NAME VARCHAR(255)); -> ok - -EXPLAIN SELECT * FROM TEST WHERE ID=1; -> PLAN -> ------------------------------------------------------------------------------------------ -> SELECT TEST.ID, TEST.NAME FROM PUBLIC.TEST /* PUBLIC.PRIMARY_KEY_2: ID = 1 */ WHERE ID = 1 -> rows: 1 - -EXPLAIN MERGE INTO TEST VALUES(1, 'Hello'); -> PLAN -> ------------------------------------------------------------ -> MERGE INTO PUBLIC.TEST(ID, NAME) KEY(ID) VALUES (1, 'Hello') -> rows: 1 - -MERGE INTO TEST VALUES(1, 'Hello'); -> update count: 1 - -MERGE INTO TEST VALUES(1, 'Hi'); -> update count: 1 - -MERGE INTO TEST VALUES(2, 'World'); -> update count: 1 - -MERGE INTO TEST VALUES(2, 'World!'); -> update count: 1 - -MERGE INTO TEST(ID, NAME) VALUES(3, 'How are you'); -> update count: 1 - -EXPLAIN MERGE INTO TEST(ID, NAME) VALUES(3, 'How are you'); -> PLAN -> ------------------------------------------------------------------ -> MERGE INTO PUBLIC.TEST(ID, NAME) KEY(ID) VALUES (3, 'How are you') -> rows: 1 - -MERGE INTO TEST(ID, NAME) KEY(ID) VALUES(3, 'How do you do'); -> update count: 1 - -EXPLAIN MERGE INTO TEST(ID, NAME) KEY(ID) VALUES(3, 'How do you do'); -> PLAN -> -------------------------------------------------------------------- -> MERGE INTO PUBLIC.TEST(ID, NAME) KEY(ID) VALUES (3, 'How do you do') -> rows: 1 - -MERGE INTO TEST(ID, NAME) KEY(NAME) VALUES(3, 'Fine'); -> exception - -MERGE INTO TEST(ID, NAME) KEY(NAME) VALUES(4, 'Fine!'); -> update count: 1 - -MERGE INTO TEST(ID, NAME) KEY(NAME) VALUES(4, 'Fine! And you'); -> exception - -MERGE INTO TEST(ID, NAME) KEY(NAME, ID) VALUES(5, 'I''m ok'); -> update count: 1 - -MERGE INTO TEST(ID, NAME) KEY(NAME, ID) VALUES(5, 'Oh, fine'); -> exception - -MERGE INTO TEST(ID, NAME) VALUES(6, 'Oh, fine.'); -> update count: 1 - -SELECT * FROM TEST; -> ID NAME -> -- ------------- -> 1 Hi -> 2 World! -> 3 How do you do -> 4 Fine! -> 5 I'm ok -> 6 Oh, fine. -> rows: 6 - -MERGE INTO TEST SELECT ID+4, NAME FROM TEST; -> update count: 6 - -SELECT * FROM TEST; -> ID NAME -> -- ------------- -> 1 Hi -> 10 Oh, fine. -> 2 World! -> 3 How do you do -> 4 Fine! -> 5 Hi -> 6 World! -> 7 How do you do -> 8 Fine! -> 9 I'm ok -> rows: 10 - -DROP TABLE TEST; -> ok - -CREATE TABLE PARENT(ID INT, NAME VARCHAR); -> ok - -CREATE TABLE CHILD(ID INT, PARENTID INT, FOREIGN KEY(PARENTID) REFERENCES PARENT(ID)); -> ok - -INSERT INTO PARENT VALUES(1, 'Mary'), (2, 'John'); -> update count: 2 - -INSERT INTO CHILD VALUES(10, 1), (11, 1), (20, 2), (21, 2); -> update count: 4 - -MERGE INTO PARENT KEY(ID) VALUES(1, 'Marcy'); -> update count: 1 - -SELECT * FROM PARENT; -> ID NAME -> -- ----- -> 1 Marcy -> 2 John -> rows: 2 - -SELECT * FROM CHILD; -> ID PARENTID -> -- -------- -> 10 1 -> 11 1 -> 20 2 -> 21 2 -> rows: 4 - -DROP TABLE PARENT; -> ok - -DROP TABLE CHILD; -> ok - ---- -create table STRING_TEST(label varchar(31), label2 varchar(255)); -> ok - -create table STRING_TEST_ic(label varchar_ignorecase(31), label2 -varchar_ignorecase(255)); -> ok - -insert into STRING_TEST values('HELLO','Bye'); -> update count: 1 - -insert into STRING_TEST values('HELLO','Hello'); -> update count: 1 - -insert into STRING_TEST_ic select * from STRING_TEST; -> update count: 2 - --- Expect rows of STRING_TEST_ic and STRING_TEST to be identical -select * from STRING_TEST; -> LABEL LABEL2 -> ----- ------ -> HELLO Bye -> HELLO Hello -> rows: 2 - --- correct -select * from STRING_TEST_ic; -> LABEL LABEL2 -> ----- ------ -> HELLO Bye -> HELLO Hello -> rows: 2 - -drop table STRING_TEST; -> ok - -drop table STRING_TEST_ic; -> ok - -CREATE TABLE TEST(ID INT PRIMARY KEY, NAME VARCHAR_IGNORECASE); -> ok - -INSERT INTO TEST VALUES(1, 'Hello'), (2, 'World'), (3, 'hallo'), (4, 'hoi'); -> update count: 4 - -SELECT * FROM TEST WHERE NAME = 'HELLO'; -> ID NAME -> -- ----- -> 1 Hello -> rows: 1 - -SELECT * FROM TEST WHERE NAME = 'HE11O'; -> ID NAME -> -- ---- -> rows: 0 - -SELECT * FROM TEST ORDER BY NAME; -> ID NAME -> -- ----- -> 3 hallo -> 1 Hello -> 4 hoi -> 2 World -> rows (ordered): 4 - -DROP TABLE IF EXISTS TEST; -> ok - ---- old-fashioned Oracle outer joins syntax --------------------------------------------------------------------------------------------- -CREATE TABLE Customers(CustomerID int); -> ok - -CREATE TABLE Orders(CustomerID int); -> ok - -INSERT INTO Customers VALUES(1), (2), (3); -> update count: 3 - -INSERT INTO Orders VALUES(1), (3); -> update count: 2 - -SELECT * FROM Customers LEFT OUTER JOIN Orders ON Customers.CustomerID = Orders.CustomerID; -> CUSTOMERID CUSTOMERID -> ---------- ---------- -> 1 1 -> 2 null -> 3 3 -> rows: 3 - -SELECT * FROM Customers, Orders WHERE Customers.CustomerID = Orders.CustomerID(+); -> CUSTOMERID CUSTOMERID -> ---------- ---------- -> 1 1 -> 2 null -> 3 3 -> rows: 3 - -DROP TABLE Customers; -> ok - -DROP TABLE Orders; -> ok - ---- complex join --------------------------------------------------------------------------------------------- -CREATE TABLE T1(ID INT PRIMARY KEY, NAME VARCHAR(255)); -> ok - -CREATE TABLE T2(ID INT PRIMARY KEY, NAME VARCHAR(255)); -> ok - -CREATE TABLE T3(ID INT PRIMARY KEY, NAME VARCHAR(255)); -> ok - -INSERT INTO T1 VALUES(1, 'Hello'); -> update count: 1 - -INSERT INTO T1 VALUES(2, 'World'); -> update count: 1 - -INSERT INTO T1 VALUES(3, 'Peace'); -> update count: 1 - -INSERT INTO T2 VALUES(1, 'Hello'); -> update count: 1 - -INSERT INTO T2 VALUES(2, 'World'); -> update count: 1 - -INSERT INTO T3 VALUES(1, 'Hello'); -> update count: 1 - -SELECT * FROM t1 left outer join t2 on t1.id=t2.id; -> ID NAME ID NAME -> -- ----- ---- ----- -> 1 Hello 1 Hello -> 2 World 2 World -> 3 Peace null null -> rows: 3 - -SELECT * FROM t1 left outer join t2 on t1.id=t2.id left outer join t3 on t1.id=t3.id; -> ID NAME ID NAME ID NAME -> -- ----- ---- ----- ---- ----- -> 1 Hello 1 Hello 1 Hello -> 2 World 2 World null null -> 3 Peace null null null null -> rows: 3 - -SELECT * FROM t1 left outer join t2 on t1.id=t2.id inner join t3 on t1.id=t3.id; -> ID NAME ID NAME ID NAME -> -- ----- -- ----- -- ----- -> 1 Hello 1 Hello 1 Hello -> rows: 1 - -drop table t1; -> ok - -drop table t2; -> ok - -drop table t3; -> ok - -CREATE TABLE TEST(ID INT PRIMARY KEY, parent int, sid int); -> ok - -create index idx_p on test(sid); -> ok - -insert into test select x, x, x from system_range(0,20); -> update count: 21 - -select * from test l0 inner join test l1 on l0.sid=l1.sid, test l3 where l0.sid=l3.parent; -> ID PARENT SID ID PARENT SID ID PARENT SID -> -- ------ --- -- ------ --- -- ------ --- -> 0 0 0 0 0 0 0 0 0 -> 1 1 1 1 1 1 1 1 1 -> 10 10 10 10 10 10 10 10 10 -> 11 11 11 11 11 11 11 11 11 -> 12 12 12 12 12 12 12 12 12 -> 13 13 13 13 13 13 13 13 13 -> 14 14 14 14 14 14 14 14 14 -> 15 15 15 15 15 15 15 15 15 -> 16 16 16 16 16 16 16 16 16 -> 17 17 17 17 17 17 17 17 17 -> 18 18 18 18 18 18 18 18 18 -> 19 19 19 19 19 19 19 19 19 -> 2 2 2 2 2 2 2 2 2 -> 20 20 20 20 20 20 20 20 20 -> 3 3 3 3 3 3 3 3 3 -> 4 4 4 4 4 4 4 4 4 -> 5 5 5 5 5 5 5 5 5 -> 6 6 6 6 6 6 6 6 6 -> 7 7 7 7 7 7 7 7 7 -> 8 8 8 8 8 8 8 8 8 -> 9 9 9 9 9 9 9 9 9 -> rows: 21 - -select * from -test l0 -inner join test l1 on l0.sid=l1.sid -inner join test l2 on l0.sid=l2.id, -test l5 -inner join test l3 on l5.sid=l3.sid -inner join test l4 on l5.sid=l4.id -where l2.id is not null -and l0.sid=l5.parent; -> ID PARENT SID ID PARENT SID ID PARENT SID ID PARENT SID ID PARENT SID ID PARENT SID -> -- ------ --- -- ------ --- -- ------ --- -- ------ --- -- ------ --- -- ------ --- -> 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -> 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 -> 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 -> 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 -> 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 -> 13 13 13 13 13 13 13 13 13 13 13 13 13 13 13 13 13 13 -> 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 -> 15 15 15 15 15 15 15 15 15 15 15 15 15 15 15 15 15 15 -> 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 -> 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 -> 18 18 18 18 18 18 18 18 18 18 18 18 18 18 18 18 18 18 -> 19 19 19 19 19 19 19 19 19 19 19 19 19 19 19 19 19 19 -> 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 -> 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 -> 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 -> 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 -> 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 -> 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 -> 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 -> 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 -> 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 -> rows: 21 - -DROP TABLE IF EXISTS TEST; -> ok - ---- update with list --------------------------------------------------------------------------------------------- -CREATE TABLE TEST(ID INT PRIMARY KEY, NAME VARCHAR(255)); -> ok - -INSERT INTO TEST VALUES(1, 'Hello'); -> update count: 1 - -INSERT INTO TEST VALUES(2, 'World'); -> update count: 1 - -SELECT * FROM TEST ORDER BY ID; -> ID NAME -> -- ----- -> 1 Hello -> 2 World -> rows (ordered): 2 - -UPDATE TEST t0 SET t0.NAME='Hi' WHERE t0.ID=1; -> update count: 1 - -update test set (id, name)=(id+1, name || 'Hi'); -> update count: 2 - -update test set (id, name)=(select id+1, name || 'Ho' from test t1 where test.id=t1.id); -> update count: 2 - -explain update test set (id, name)=(id+1, name || 'Hi'); -> PLAN -> ------------------------------------------------------------------------------------------------------------------------------------------------- -> UPDATE PUBLIC.TEST /* PUBLIC.TEST.tableScan */ SET ID = ARRAY_GET(((ID + 1), (NAME || 'Hi')), 1), NAME = ARRAY_GET(((ID + 1), (NAME || 'Hi')), 2) -> rows: 1 - -explain update test set (id, name)=(select id+1, name || 'Ho' from test t1 where test.id=t1.id); -> PLAN -> ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -> UPDATE PUBLIC.TEST /* PUBLIC.TEST.tableScan */ SET ID = ARRAY_GET((SELECT (ID + 1), (NAME || 'Ho') FROM PUBLIC.TEST T1 /* PUBLIC.PRIMARY_KEY_2: ID = TEST.ID */ WHERE TEST.ID = T1.ID), 1), NAME = ARRAY_GET((SELECT (ID + 1), (NAME || 'Ho') FROM PUBLIC.TEST T1 /* PUBLIC.PRIMARY_KEY_2: ID = TEST.ID */ WHERE TEST.ID = T1.ID), 2) -> rows: 1 - -select * from test; -> ID NAME -> -- --------- -> 3 HiHiHo -> 4 WorldHiHo -> rows: 2 - -DROP TABLE IF EXISTS TEST; -> ok - ---- script --------------------------------------------------------------------------------------------- -create memory table test(id int primary key, c clob, b blob); -> ok - -insert into test values(0, null, null); -> update count: 1 - -insert into test values(1, '', ''); -> update count: 1 - -insert into test values(2, 'Cafe', X'cafe'); -> update count: 1 - -script simple nopasswords nosettings; -> SCRIPT -> ------------------------------------------------------------------------------- -> -- 3 +/- SELECT COUNT(*) FROM PUBLIC.TEST; -> ALTER TABLE PUBLIC.TEST ADD CONSTRAINT PUBLIC.CONSTRAINT_2 PRIMARY KEY(ID); -> CREATE MEMORY TABLE PUBLIC.TEST( ID INT NOT NULL, C CLOB, B BLOB ); -> CREATE USER IF NOT EXISTS SA PASSWORD '' ADMIN; -> INSERT INTO PUBLIC.TEST(ID, C, B) VALUES(0, NULL, NULL); -> INSERT INTO PUBLIC.TEST(ID, C, B) VALUES(1, '', X''); -> INSERT INTO PUBLIC.TEST(ID, C, B) VALUES(2, 'Cafe', X'cafe'); -> rows: 7 - -drop table test; -> ok - ---- optimizer --------------------------------------------------------------------------------------------- -create table b(id int primary key, p int); -> ok - -create index bp on b(p); -> ok - -insert into b values(0, 0), (1, 1), (2, 2), (3, 3), (4, 4), (5, 5), (6, 6), (7, 7), (8, 8), (9, 9); -> update count: 10 - -insert into b select id+10, p+10 from b; -> update count: 10 - -explain select * from b b0, b b1, b b2 where b1.p = b0.id and b2.p = b1.id and b0.id=10; -> PLAN -> ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ -> SELECT B0.ID, B0.P, B1.ID, B1.P, B2.ID, B2.P FROM PUBLIC.B B0 /* PUBLIC.PRIMARY_KEY_4: ID = 10 */ /* WHERE B0.ID = 10 */ INNER JOIN PUBLIC.B B1 /* PUBLIC.BP: P = B0.ID */ ON 1=1 /* WHERE B1.P = B0.ID */ INNER JOIN PUBLIC.B B2 /* PUBLIC.BP: P = B1.ID */ ON 1=1 WHERE (B0.ID = 10) AND ((B1.P = B0.ID) AND (B2.P = B1.ID)) -> rows: 1 - -explain select * from b b0, b b1, b b2, b b3 where b1.p = b0.id and b2.p = b1.id and b3.p = b2.id and b0.id=10; -> PLAN -> -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -> SELECT B0.ID, B0.P, B1.ID, B1.P, B2.ID, B2.P, B3.ID, B3.P FROM PUBLIC.B B0 /* PUBLIC.PRIMARY_KEY_4: ID = 10 */ /* WHERE B0.ID = 10 */ INNER JOIN PUBLIC.B B1 /* PUBLIC.BP: P = B0.ID */ ON 1=1 /* WHERE B1.P = B0.ID */ INNER JOIN PUBLIC.B B2 /* PUBLIC.BP: P = B1.ID */ ON 1=1 /* WHERE B2.P = B1.ID */ INNER JOIN PUBLIC.B B3 /* PUBLIC.BP: P = B2.ID */ ON 1=1 WHERE (B0.ID = 10) AND ((B3.P = B2.ID) AND ((B1.P = B0.ID) AND (B2.P = B1.ID))) -> rows: 1 - -explain select * from b b0, b b1, b b2, b b3, b b4 where b1.p = b0.id and b2.p = b1.id and b3.p = b2.id and b4.p = b3.id and b0.id=10; -> PLAN -> ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -> SELECT B0.ID, B0.P, B1.ID, B1.P, B2.ID, B2.P, B3.ID, B3.P, B4.ID, B4.P FROM PUBLIC.B B0 /* PUBLIC.PRIMARY_KEY_4: ID = 10 */ /* WHERE B0.ID = 10 */ INNER JOIN PUBLIC.B B1 /* PUBLIC.BP: P = B0.ID */ ON 1=1 /* WHERE B1.P = B0.ID */ INNER JOIN PUBLIC.B B2 /* PUBLIC.BP: P = B1.ID */ ON 1=1 /* WHERE B2.P = B1.ID */ INNER JOIN PUBLIC.B B3 /* PUBLIC.BP: P = B2.ID */ ON 1=1 /* WHERE B3.P = B2.ID */ INNER JOIN PUBLIC.B B4 /* PUBLIC.BP: P = B3.ID */ ON 1=1 WHERE (B0.ID = 10) AND ((B4.P = B3.ID) AND ((B3.P = B2.ID) AND ((B1.P = B0.ID) AND (B2.P = B1.ID)))) -> rows: 1 - -analyze; -> ok - -explain select * from b b0, b b1, b b2, b b3, b b4 where b1.p = b0.id and b2.p = b1.id and b3.p = b2.id and b4.p = b3.id and b0.id=10; -> PLAN -> ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -> SELECT B0.ID, B0.P, B1.ID, B1.P, B2.ID, B2.P, B3.ID, B3.P, B4.ID, B4.P FROM PUBLIC.B B0 /* PUBLIC.PRIMARY_KEY_4: ID = 10 */ /* WHERE B0.ID = 10 */ INNER JOIN PUBLIC.B B1 /* PUBLIC.BP: P = B0.ID */ ON 1=1 /* WHERE B1.P = B0.ID */ INNER JOIN PUBLIC.B B2 /* PUBLIC.BP: P = B1.ID */ ON 1=1 /* WHERE B2.P = B1.ID */ INNER JOIN PUBLIC.B B3 /* PUBLIC.BP: P = B2.ID */ ON 1=1 /* WHERE B3.P = B2.ID */ INNER JOIN PUBLIC.B B4 /* PUBLIC.BP: P = B3.ID */ ON 1=1 WHERE (B0.ID = 10) AND ((B4.P = B3.ID) AND ((B3.P = B2.ID) AND ((B1.P = B0.ID) AND (B2.P = B1.ID)))) -> rows: 1 - -drop table if exists b; -> ok - -create table test(id int primary key, first_name varchar, name varchar, state int); -> ok - -create index idx_first_name on test(first_name); -> ok - -create index idx_name on test(name); -> ok - -create index idx_state on test(state); -> ok - -insert into test values -(0, 'Anne', 'Smith', 0), (1, 'Tom', 'Smith', 0), -(2, 'Tom', 'Jones', 0), (3, 'Steve', 'Johnson', 0), -(4, 'Steve', 'Martin', 0), (5, 'Jon', 'Jones', 0), -(6, 'Marc', 'Scott', 0), (7, 'Marc', 'Miller', 0), -(8, 'Susan', 'Wood', 0), (9, 'Jon', 'Bennet', 0); -> update count: 10 - -EXPLAIN SELECT * FROM TEST WHERE ID = 3; -> PLAN -> ----------------------------------------------------------------------------------------------------------------------- -> SELECT TEST.ID, TEST.FIRST_NAME, TEST.NAME, TEST.STATE FROM PUBLIC.TEST /* PUBLIC.PRIMARY_KEY_2: ID = 3 */ WHERE ID = 3 -> rows: 1 - -SELECT SELECTIVITY(ID), SELECTIVITY(FIRST_NAME), -SELECTIVITY(NAME), SELECTIVITY(STATE) -FROM TEST WHERE ROWNUM()<100000; -> SELECTIVITY(ID) SELECTIVITY(FIRST_NAME) SELECTIVITY(NAME) SELECTIVITY(STATE) -> --------------- ----------------------- ----------------- ------------------ -> 100 60 80 10 -> rows: 1 - -explain select * from test where name='Smith' and first_name='Tom' and state=0; -> PLAN -> ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -> SELECT TEST.ID, TEST.FIRST_NAME, TEST.NAME, TEST.STATE FROM PUBLIC.TEST /* PUBLIC.IDX_FIRST_NAME: FIRST_NAME = 'Tom' */ WHERE (STATE = 0) AND ((NAME = 'Smith') AND (FIRST_NAME = 'Tom')) -> rows: 1 - -alter table test alter column name selectivity 100; -> ok - -explain select * from test where name='Smith' and first_name='Tom' and state=0; -> PLAN -> ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -> SELECT TEST.ID, TEST.FIRST_NAME, TEST.NAME, TEST.STATE FROM PUBLIC.TEST /* PUBLIC.IDX_NAME: NAME = 'Smith' */ WHERE (STATE = 0) AND ((NAME = 'Smith') AND (FIRST_NAME = 'Tom')) -> rows: 1 - -drop table test; -> ok - -CREATE TABLE O(X INT PRIMARY KEY, Y INT); -> ok - -INSERT INTO O SELECT X, X+1 FROM SYSTEM_RANGE(1, 1000); -> update count: 1000 - -EXPLAIN SELECT A.X FROM O B, O A, O F, O D, O C, O E, O G, O H, O I, O J -WHERE 1=J.X and J.Y=I.X AND I.Y=H.X AND H.Y=G.X AND G.Y=F.X AND F.Y=E.X -AND E.Y=D.X AND D.Y=C.X AND C.Y=B.X AND B.Y=A.X; -> PLAN -> --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -> SELECT A.X FROM PUBLIC.O J /* PUBLIC.PRIMARY_KEY_4: X = 1 */ /* WHERE J.X = 1 */ INNER JOIN PUBLIC.O I /* PUBLIC.PRIMARY_KEY_4: X = J.Y */ ON 1=1 /* WHERE J.Y = I.X */ INNER JOIN PUBLIC.O H /* PUBLIC.PRIMARY_KEY_4: X = I.Y */ ON 1=1 /* WHERE I.Y = H.X */ INNER JOIN PUBLIC.O G /* PUBLIC.PRIMARY_KEY_4: X = H.Y */ ON 1=1 /* WHERE H.Y = G.X */ INNER JOIN PUBLIC.O F /* PUBLIC.PRIMARY_KEY_4: X = G.Y */ ON 1=1 /* WHERE G.Y = F.X */ INNER JOIN PUBLIC.O E /* PUBLIC.PRIMARY_KEY_4: X = F.Y */ ON 1=1 /* WHERE F.Y = E.X */ INNER JOIN PUBLIC.O D /* PUBLIC.PRIMARY_KEY_4: X = E.Y */ ON 1=1 /* WHERE E.Y = D.X */ INNER JOIN PUBLIC.O C /* PUBLIC.PRIMARY_KEY_4: X = D.Y */ ON 1=1 /* WHERE D.Y = C.X */ INNER JOIN PUBLIC.O B /* PUBLIC.PRIMARY_KEY_4: X = C.Y */ ON 1=1 /* WHERE C.Y = B.X */ INNER JOIN PUBLIC.O A /* PUBLIC.PRIMARY_KEY_4: X = B.Y */ ON 1=1 WHERE (B.Y = A.X) AND ((C.Y = B.X) AND ((D.Y = C.X) AND ((E.Y = D.X) AND ((F.Y = E.X) AND ((G.Y = F.X) AND ((H.Y = G.X) AND ((I.Y = H.X) AND ((J.X = 1) AND (J.Y = I.X))))))))) -> rows: 1 - -DROP TABLE O; -> ok - -CREATE TABLE PARENT(ID INT PRIMARY KEY, AID INT, BID INT, CID INT, DID INT, EID INT, FID INT, GID INT, HID INT); -> ok - -CREATE TABLE CHILD(ID INT PRIMARY KEY); -> ok - -INSERT INTO PARENT SELECT X, 1, 2, 1, 2, 1, 2, 1, 2 FROM SYSTEM_RANGE(0, 1000); -> update count: 1001 - -INSERT INTO CHILD SELECT X FROM SYSTEM_RANGE(0, 1000); -> update count: 1001 - -SELECT COUNT(*) FROM PARENT, CHILD A, CHILD B, CHILD C, CHILD D, CHILD E, CHILD F, CHILD G, CHILD H -WHERE AID=A.ID AND BID=B.ID AND CID=C.ID -AND DID=D.ID AND EID=E.ID AND FID=F.ID AND GID=G.ID AND HID=H.ID; -> COUNT(*) -> -------- -> 1001 -> rows: 1 - -EXPLAIN SELECT COUNT(*) FROM PARENT, CHILD A, CHILD B, CHILD C, CHILD D, CHILD E, CHILD F, CHILD G, CHILD H -WHERE AID=A.ID AND BID=B.ID AND CID=C.ID -AND DID=D.ID AND EID=E.ID AND FID=F.ID AND GID=G.ID AND HID=H.ID; -> PLAN -> ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -> SELECT COUNT(*) FROM PUBLIC.PARENT /* PUBLIC.PARENT.tableScan */ INNER JOIN PUBLIC.CHILD A /* PUBLIC.PRIMARY_KEY_3: ID = AID */ ON 1=1 /* WHERE AID = A.ID */ INNER JOIN PUBLIC.CHILD B /* PUBLIC.PRIMARY_KEY_3: ID = BID */ ON 1=1 /* WHERE BID = B.ID */ INNER JOIN PUBLIC.CHILD C /* PUBLIC.PRIMARY_KEY_3: ID = CID */ ON 1=1 /* WHERE CID = C.ID */ INNER JOIN PUBLIC.CHILD D /* PUBLIC.PRIMARY_KEY_3: ID = DID */ ON 1=1 /* WHERE DID = D.ID */ INNER JOIN PUBLIC.CHILD E /* PUBLIC.PRIMARY_KEY_3: ID = EID */ ON 1=1 /* WHERE EID = E.ID */ INNER JOIN PUBLIC.CHILD F /* PUBLIC.PRIMARY_KEY_3: ID = FID */ ON 1=1 /* WHERE FID = F.ID */ INNER JOIN PUBLIC.CHILD G /* PUBLIC.PRIMARY_KEY_3: ID = GID */ ON 1=1 /* WHERE GID = G.ID */ INNER JOIN PUBLIC.CHILD H /* PUBLIC.PRIMARY_KEY_3: ID = HID */ ON 1=1 WHERE (HID = H.ID) AND ((GID = G.ID) AND ((FID = F.ID) AND ((EID = E.ID) AND ((DID = D.ID) AND ((CID = C.ID) AND ((AID = A.ID) AND (BID = B.ID))))))) -> rows: 1 - -CREATE TABLE FAMILY(ID INT PRIMARY KEY, PARENTID INT); -> ok - -INSERT INTO FAMILY SELECT X, X-1 FROM SYSTEM_RANGE(0, 1000); -> update count: 1001 - -EXPLAIN SELECT COUNT(*) FROM CHILD A, CHILD B, FAMILY, CHILD C, CHILD D, PARENT, CHILD E, CHILD F, CHILD G -WHERE FAMILY.ID=1 AND FAMILY.PARENTID=PARENT.ID -AND AID=A.ID AND BID=B.ID AND CID=C.ID AND DID=D.ID AND EID=E.ID AND FID=F.ID AND GID=G.ID; -> PLAN -> ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -> SELECT COUNT(*) FROM PUBLIC.FAMILY /* PUBLIC.PRIMARY_KEY_7: ID = 1 */ /* WHERE FAMILY.ID = 1 */ INNER JOIN PUBLIC.PARENT /* PUBLIC.PRIMARY_KEY_8: ID = FAMILY.PARENTID */ ON 1=1 /* WHERE FAMILY.PARENTID = PARENT.ID */ INNER JOIN PUBLIC.CHILD A /* PUBLIC.PRIMARY_KEY_3: ID = AID */ ON 1=1 /* WHERE AID = A.ID */ INNER JOIN PUBLIC.CHILD B /* PUBLIC.PRIMARY_KEY_3: ID = BID */ ON 1=1 /* WHERE BID = B.ID */ INNER JOIN PUBLIC.CHILD C /* PUBLIC.PRIMARY_KEY_3: ID = CID */ ON 1=1 /* WHERE CID = C.ID */ INNER JOIN PUBLIC.CHILD D /* PUBLIC.PRIMARY_KEY_3: ID = DID */ ON 1=1 /* WHERE DID = D.ID */ INNER JOIN PUBLIC.CHILD E /* PUBLIC.PRIMARY_KEY_3: ID = EID */ ON 1=1 /* WHERE EID = E.ID */ INNER JOIN PUBLIC.CHILD F /* PUBLIC.PRIMARY_KEY_3: ID = FID */ ON 1=1 /* WHERE FID = F.ID */ INNER JOIN PUBLIC.CHILD G /* PUBLIC.PRIMARY_KEY_3: ID = GID */ ON 1=1 WHERE (GID = G.ID) AND ((FID = F.ID) AND ((EID = E.ID) AND ((DID = D.ID) AND ((CID = C.ID) AND ((BID = B.ID) AND ((AID = A.ID) AND ((FAMILY.ID = 1) AND (FAMILY.PARENTID = PARENT.ID)))))))) -> rows: 1 - -DROP TABLE FAMILY; -> ok - -DROP TABLE PARENT; -> ok - -DROP TABLE CHILD; -> ok - ---- is null / not is null --------------------------------------------------------------------------------------------- -CREATE TABLE TEST(ID INT UNIQUE, NAME VARCHAR CHECK LENGTH(NAME)>3); -> ok - -DROP TABLE TEST; -> ok - -CREATE TABLE TEST(ID INT, NAME VARCHAR(255), B INT); -> ok - -CREATE UNIQUE INDEX IDXNAME ON TEST(NAME); -> ok - -CREATE UNIQUE INDEX IDX_NAME_B ON TEST(NAME, B); -> ok - -INSERT INTO TEST(ID, NAME, B) VALUES (0, NULL, NULL); -> update count: 1 - -INSERT INTO TEST(ID, NAME, B) VALUES (1, 'Hello', NULL); -> update count: 1 - -INSERT INTO TEST(ID, NAME, B) VALUES (2, NULL, NULL); -> update count: 1 - -INSERT INTO TEST(ID, NAME, B) VALUES (3, 'World', NULL); -> update count: 1 - -select * from test; -> ID NAME B -> -- ----- ---- -> 0 null null -> 1 Hello null -> 2 null null -> 3 World null -> rows: 4 - -UPDATE test SET name='Hi'; -> exception - -select * from test; -> ID NAME B -> -- ----- ---- -> 0 null null -> 1 Hello null -> 2 null null -> 3 World null -> rows: 4 - -UPDATE test SET name=NULL; -> update count: 4 - -UPDATE test SET B=1; -> update count: 4 - -DROP TABLE TEST; -> ok - -CREATE TABLE TEST(ID INT, NAME VARCHAR); -> ok - -INSERT INTO TEST VALUES(NULL, NULL), (0, 'Hello'), (1, 'World'); -> update count: 3 - -SELECT * FROM TEST WHERE NOT (1=1); -> ID NAME -> -- ---- -> rows: 0 - -DROP TABLE TEST; -> ok - -create table test_null(a int, b int); -> ok - -insert into test_null values(0, 0); -> update count: 1 - -insert into test_null values(0, null); -> update count: 1 - -insert into test_null values(null, null); -> update count: 1 - -insert into test_null values(null, 0); -> update count: 1 - -select * from test_null where a=0; -> A B -> - ---- -> 0 0 -> 0 null -> rows: 2 - -select * from test_null where not a=0; -> A B -> - - -> rows: 0 - -select * from test_null where (a=0 or b=0); -> A B -> ---- ---- -> 0 0 -> 0 null -> null 0 -> rows: 3 - -select * from test_null where not (a=0 or b=0); -> A B -> - - -> rows: 0 - -select * from test_null where (a=1 or b=0); -> A B -> ---- - -> 0 0 -> null 0 -> rows: 2 - -select * from test_null where not( a=1 or b=0); -> A B -> - - -> rows: 0 - -select * from test_null where not(not( a=1 or b=0)); -> A B -> ---- - -> 0 0 -> null 0 -> rows: 2 - -select * from test_null where a=0 or b=0; -> A B -> ---- ---- -> 0 0 -> 0 null -> null 0 -> rows: 3 - -SELECT count(*) FROM test_null WHERE not ('X'=null and 1=0); -> COUNT(*) -> -------- -> 4 -> rows: 1 - -drop table if exists test_null; -> ok - ---- function alias --------------------------------------------------------------------------------------------- -CREATE ALIAS MY_SQRT FOR "java.lang.Math.sqrt"; -> ok - -SELECT MY_SQRT(2.0) MS, SQRT(2.0); -> MS 1.4142135623730951 -> ------------------ ------------------ -> 1.4142135623730951 1.4142135623730951 -> rows: 1 - -SELECT MY_SQRT(SUM(X)), SUM(X), MY_SQRT(55) FROM SYSTEM_RANGE(1, 10); -> MY_SQRT(SUM(X)) SUM(X) MY_SQRT(55) -> ----------------- ------ ----------------- -> 7.416198487095663 55 7.416198487095663 -> rows: 1 - -SELECT MY_SQRT(-1.0) MS, SQRT(NULL) S; -> MS S -> --- ---- -> NaN null -> rows: 1 - -SCRIPT NOPASSWORDS NOSETTINGS; -> SCRIPT -> ----------------------------------------------------- -> CREATE FORCE ALIAS MY_SQRT FOR "java.lang.Math.sqrt"; -> CREATE USER IF NOT EXISTS SA PASSWORD '' ADMIN; -> rows: 2 - -SELECT ALIAS_NAME, JAVA_CLASS, JAVA_METHOD, DATA_TYPE, COLUMN_COUNT, RETURNS_RESULT, REMARKS FROM INFORMATION_SCHEMA.FUNCTION_ALIASES; -> ALIAS_NAME JAVA_CLASS JAVA_METHOD DATA_TYPE COLUMN_COUNT RETURNS_RESULT REMARKS -> ---------- -------------- ----------- --------- ------------ -------------- ------- -> MY_SQRT java.lang.Math sqrt 8 1 2 -> rows: 1 - -DROP ALIAS MY_SQRT; -> ok - ---- schema ---------------------------------------------------------------------------------------------- -SELECT DISTINCT TABLE_SCHEMA, TABLE_CATALOG FROM INFORMATION_SCHEMA.TABLES ORDER BY TABLE_SCHEMA; -> TABLE_SCHEMA TABLE_CATALOG -> ------------------ ------------- -> INFORMATION_SCHEMA SCRIPT -> rows (ordered): 1 - -SELECT * FROM INFORMATION_SCHEMA.SCHEMATA; -> CATALOG_NAME SCHEMA_NAME SCHEMA_OWNER DEFAULT_CHARACTER_SET_NAME DEFAULT_COLLATION_NAME IS_DEFAULT REMARKS ID -> ------------ ------------------ ------------ -------------------------- ---------------------- ---------- ------- -- -> SCRIPT INFORMATION_SCHEMA SA Unicode OFF FALSE -1 -> SCRIPT PUBLIC SA Unicode OFF TRUE 0 -> rows: 2 - -SELECT * FROM INFORMATION_SCHEMA.CATALOGS; -> CATALOG_NAME -> ------------ -> SCRIPT -> rows: 1 - -SELECT INFORMATION_SCHEMA.SCHEMATA.SCHEMA_NAME FROM INFORMATION_SCHEMA.SCHEMATA; -> SCHEMA_NAME -> ------------------ -> INFORMATION_SCHEMA -> PUBLIC -> rows: 2 - -SELECT INFORMATION_SCHEMA.SCHEMATA.* FROM INFORMATION_SCHEMA.SCHEMATA; -> CATALOG_NAME SCHEMA_NAME SCHEMA_OWNER DEFAULT_CHARACTER_SET_NAME DEFAULT_COLLATION_NAME IS_DEFAULT REMARKS ID -> ------------ ------------------ ------------ -------------------------- ---------------------- ---------- ------- -- -> SCRIPT INFORMATION_SCHEMA SA Unicode OFF FALSE -1 -> SCRIPT PUBLIC SA Unicode OFF TRUE 0 -> rows: 2 - -CREATE SCHEMA TEST_SCHEMA AUTHORIZATION SA; -> ok - -DROP SCHEMA TEST_SCHEMA; -> ok - -create schema Contact_Schema AUTHORIZATION SA; -> ok - -CREATE TABLE Contact_Schema.Address ( -address_id BIGINT NOT NULL -CONSTRAINT address_id_check -CHECK (address_id > 0), -address_type VARCHAR(20) NOT NULL -CONSTRAINT address_type -CHECK (address_type in ('postal','email','web')), -CONSTRAINT X_PKAddress -PRIMARY KEY (address_id) -); -> ok - -create schema ClientServer_Schema AUTHORIZATION SA; -> ok - -CREATE TABLE ClientServer_Schema.PrimaryKey_Seq ( -sequence_name VARCHAR(100) NOT NULL, -seq_number BIGINT NOT NULL, -CONSTRAINT X_PKPrimaryKey_Seq -PRIMARY KEY (sequence_name) -); -> ok - -alter table Contact_Schema.Address add constraint abc foreign key(address_id) -references ClientServer_Schema.PrimaryKey_Seq(seq_number); -> ok - -drop table ClientServer_Schema.PrimaryKey_Seq; -> ok - -drop table Contact_Schema.Address; -> ok - -drop schema Contact_Schema; -> ok - -drop schema ClientServer_Schema; -> ok - ---- alter table add / drop / rename column ---------------------------------------------------------------------------------------------- -CREATE MEMORY TABLE TEST(ID INT PRIMARY KEY); -> ok - -SCRIPT NOPASSWORDS NOSETTINGS; -> SCRIPT -> --------------------------------------------------------------------------- -> -- 0 +/- SELECT COUNT(*) FROM PUBLIC.TEST; -> ALTER TABLE PUBLIC.TEST ADD CONSTRAINT PUBLIC.CONSTRAINT_2 PRIMARY KEY(ID); -> CREATE MEMORY TABLE PUBLIC.TEST( ID INT NOT NULL ); -> CREATE USER IF NOT EXISTS SA PASSWORD '' ADMIN; -> rows: 4 - -ALTER TABLE TEST ADD CREATEDATE VARCHAR(255) DEFAULT '2001-01-01' NOT NULL; -> ok - -ALTER TABLE TEST ADD NAME VARCHAR(255) NULL BEFORE CREATEDATE; -> ok - -CREATE INDEX IDXNAME ON TEST(NAME); -> ok - -INSERT INTO TEST(ID, NAME) VALUES(1, 'Hi'); -> update count: 1 - -ALTER TABLE TEST ALTER COLUMN NAME SET NOT NULL; -> ok - -ALTER TABLE TEST ALTER COLUMN NAME SET NOT NULL; -> ok - -ALTER TABLE TEST ALTER COLUMN NAME SET NULL; -> ok - -ALTER TABLE TEST ALTER COLUMN NAME SET NULL; -> ok - -ALTER TABLE TEST ALTER COLUMN NAME SET DEFAULT 1; -> ok - -SELECT * FROM TEST; -> ID NAME CREATEDATE -> -- ---- ---------- -> 1 Hi 2001-01-01 -> rows: 1 - -ALTER TABLE TEST ADD MODIFY_DATE TIMESTAMP; -> ok - -CREATE MEMORY TABLE TEST_SEQ(ID INT, NAME VARCHAR); -> ok - -INSERT INTO TEST_SEQ VALUES(-1, '-1'); -> update count: 1 - -ALTER TABLE TEST_SEQ ALTER COLUMN ID IDENTITY; -> ok - -INSERT INTO TEST_SEQ VALUES(NULL, '1'); -> update count: 1 - -ALTER TABLE TEST_SEQ ALTER COLUMN ID RESTART WITH 10; -> ok - -INSERT INTO TEST_SEQ VALUES(NULL, '10'); -> update count: 1 - -alter table test_seq drop primary key; -> ok - -ALTER TABLE TEST_SEQ ALTER COLUMN ID INT DEFAULT 20; -> ok - -INSERT INTO TEST_SEQ VALUES(DEFAULT, '20'); -> update count: 1 - -ALTER TABLE TEST_SEQ ALTER COLUMN NAME RENAME TO DATA; -> ok - -SELECT * FROM TEST_SEQ ORDER BY ID; -> ID DATA -> -- ---- -> -1 -1 -> 1 1 -> 10 10 -> 20 20 -> rows (ordered): 4 - -SCRIPT SIMPLE NOPASSWORDS NOSETTINGS; -> SCRIPT -> ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ -> -- 1 +/- SELECT COUNT(*) FROM PUBLIC.TEST; -> -- 4 +/- SELECT COUNT(*) FROM PUBLIC.TEST_SEQ; -> ALTER TABLE PUBLIC.TEST ADD CONSTRAINT PUBLIC.CONSTRAINT_2 PRIMARY KEY(ID); -> CREATE INDEX PUBLIC.IDXNAME ON PUBLIC.TEST(NAME); -> CREATE MEMORY TABLE PUBLIC.TEST( ID INT NOT NULL, NAME VARCHAR(255) DEFAULT 1, CREATEDATE VARCHAR(255) DEFAULT '2001-01-01' NOT NULL, MODIFY_DATE TIMESTAMP ); -> CREATE MEMORY TABLE PUBLIC.TEST_SEQ( ID INT DEFAULT 20 NOT NULL, DATA VARCHAR ); -> CREATE USER IF NOT EXISTS SA PASSWORD '' ADMIN; -> INSERT INTO PUBLIC.TEST(ID, NAME, CREATEDATE, MODIFY_DATE) VALUES(1, 'Hi', '2001-01-01', NULL); -> INSERT INTO PUBLIC.TEST_SEQ(ID, DATA) VALUES(-1, '-1'); -> INSERT INTO PUBLIC.TEST_SEQ(ID, DATA) VALUES(1, '1'); -> INSERT INTO PUBLIC.TEST_SEQ(ID, DATA) VALUES(10, '10'); -> INSERT INTO PUBLIC.TEST_SEQ(ID, DATA) VALUES(20, '20'); -> rows: 12 - -CREATE UNIQUE INDEX IDX_NAME_ID ON TEST(ID, NAME); -> ok - -ALTER TABLE TEST DROP COLUMN NAME; -> exception - -DROP INDEX IDX_NAME_ID; -> ok - -DROP INDEX IDX_NAME_ID IF EXISTS; -> ok - -ALTER TABLE TEST DROP NAME; -> ok - -DROP TABLE TEST_SEQ; -> ok - -SCRIPT NOPASSWORDS NOSETTINGS; -> SCRIPT -> --------------------------------------------------------------------------------------------------------------------------------------------- -> -- 1 +/- SELECT COUNT(*) FROM PUBLIC.TEST; -> ALTER TABLE PUBLIC.TEST ADD CONSTRAINT PUBLIC.CONSTRAINT_2 PRIMARY KEY(ID); -> CREATE MEMORY TABLE PUBLIC.TEST( ID INT NOT NULL, CREATEDATE VARCHAR(255) DEFAULT '2001-01-01' NOT NULL, MODIFY_DATE TIMESTAMP ); -> CREATE USER IF NOT EXISTS SA PASSWORD '' ADMIN; -> INSERT INTO PUBLIC.TEST(ID, CREATEDATE, MODIFY_DATE) VALUES (1, '2001-01-01', NULL); -> rows: 5 - -ALTER TABLE TEST ADD NAME VARCHAR(255) NULL BEFORE CREATEDATE; -> ok - -SCRIPT NOPASSWORDS NOSETTINGS; -> SCRIPT -> -------------------------------------------------------------------------------------------------------------------------------------------------------------------- -> -- 1 +/- SELECT COUNT(*) FROM PUBLIC.TEST; -> ALTER TABLE PUBLIC.TEST ADD CONSTRAINT PUBLIC.CONSTRAINT_2 PRIMARY KEY(ID); -> CREATE MEMORY TABLE PUBLIC.TEST( ID INT NOT NULL, NAME VARCHAR(255), CREATEDATE VARCHAR(255) DEFAULT '2001-01-01' NOT NULL, MODIFY_DATE TIMESTAMP ); -> CREATE USER IF NOT EXISTS SA PASSWORD '' ADMIN; -> INSERT INTO PUBLIC.TEST(ID, NAME, CREATEDATE, MODIFY_DATE) VALUES (1, NULL, '2001-01-01', NULL); -> rows: 5 - -UPDATE TEST SET NAME = 'Hi'; -> update count: 1 - -INSERT INTO TEST VALUES(2, 'Hello', DEFAULT, DEFAULT); -> update count: 1 - -SELECT * FROM TEST; -> ID NAME CREATEDATE MODIFY_DATE -> -- ----- ---------- ----------- -> 1 Hi 2001-01-01 null -> 2 Hello 2001-01-01 null -> rows: 2 - -DROP TABLE TEST; -> ok - ---- autoIncrement ---------------------------------------------------------------------------------------------- -CREATE MEMORY TABLE TEST(ID INT PRIMARY KEY, NAME VARCHAR); -> ok - -SCRIPT NOPASSWORDS NOSETTINGS; -> SCRIPT -> --------------------------------------------------------------------------- -> -- 0 +/- SELECT COUNT(*) FROM PUBLIC.TEST; -> ALTER TABLE PUBLIC.TEST ADD CONSTRAINT PUBLIC.CONSTRAINT_2 PRIMARY KEY(ID); -> CREATE MEMORY TABLE PUBLIC.TEST( ID INT NOT NULL, NAME VARCHAR ); -> CREATE USER IF NOT EXISTS SA PASSWORD '' ADMIN; -> rows: 4 - -INSERT INTO TEST(ID, NAME) VALUES(1, 'Hi'), (2, 'World'); -> update count: 2 - -SELECT * FROM TEST; -> ID NAME -> -- ----- -> 1 Hi -> 2 World -> rows: 2 - -SELECT * FROM TEST WHERE ? IS NULL; -{ -Hello -> ID NAME -> -- ---- -> rows: 0 -}; -> update count: 0 - -DROP TABLE TEST; -> ok - ---- limit/offset ---------------------------------------------------------------------------------------------- -CREATE TABLE TEST(ID INT PRIMARY KEY, NAME VARCHAR); -> ok - -INSERT INTO TEST VALUES(1, 'Hello'), (2, 'World'), (3, 'with'), (4, 'limited'), (5, 'resources'); -> update count: 5 - -SELECT TOP 2 * FROM TEST ORDER BY ID; -> ID NAME -> -- ----- -> 1 Hello -> 2 World -> rows (ordered): 2 - -SELECT LIMIT (0+0) (2+0) * FROM TEST ORDER BY ID; -> ID NAME -> -- ----- -> 1 Hello -> 2 World -> rows (ordered): 2 - -SELECT LIMIT (1+0) (2+0) NAME, -ID, ID _ID_ FROM TEST ORDER BY _ID_; -> NAME - ID _ID_ -> ----- ---- ---- -> World -2 2 -> with -3 3 -> rows (ordered): 2 - -EXPLAIN SELECT LIMIT (1+0) (2+0) * FROM TEST ORDER BY ID; -> PLAN -> -------------------------------------------------------------------------------------------------------------------- -> SELECT TEST.ID, TEST.NAME FROM PUBLIC.TEST /* PUBLIC.PRIMARY_KEY_2 */ ORDER BY 1 LIMIT 2 OFFSET 1 /* index sorted */ -> rows (ordered): 1 - -SELECT * FROM TEST ORDER BY ID LIMIT 2+0 OFFSET 1+0; -> ID NAME -> -- ----- -> 2 World -> 3 with -> rows (ordered): 2 - -SELECT * FROM TEST UNION ALL SELECT * FROM TEST ORDER BY ID LIMIT 2+0 OFFSET 1+0; -> ID NAME -> -- ----- -> 1 Hello -> 2 World -> rows (ordered): 2 - -SELECT ID FROM TEST GROUP BY ID UNION ALL SELECT ID FROM TEST GROUP BY ID; -> ID -> -- -> 1 -> 1 -> 2 -> 2 -> 3 -> 3 -> 4 -> 4 -> 5 -> 5 -> rows: 10 - -SELECT * FROM (SELECT ID FROM TEST GROUP BY ID); -> ID -> -- -> 1 -> 2 -> 3 -> 4 -> 5 -> rows: 5 - -EXPLAIN SELECT * FROM TEST UNION ALL SELECT * FROM TEST ORDER BY ID LIMIT 2+0 OFFSET 1+0; -> PLAN -> --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -> (SELECT TEST.ID, TEST.NAME FROM PUBLIC.TEST /* PUBLIC.TEST.tableScan */) UNION ALL (SELECT TEST.ID, TEST.NAME FROM PUBLIC.TEST /* PUBLIC.TEST.tableScan */) ORDER BY 1 LIMIT 2 OFFSET 1 -> rows (ordered): 1 - -EXPLAIN DELETE FROM TEST WHERE ID=1; -> PLAN -> ----------------------------------------------------------------------- -> DELETE FROM PUBLIC.TEST /* PUBLIC.PRIMARY_KEY_2: ID = 1 */ WHERE ID = 1 -> rows: 1 - -DROP TABLE TEST; -> ok - -CREATE TABLE TEST2COL(A INT, B INT, C VARCHAR(255), PRIMARY KEY(A, B)); -> ok - -INSERT INTO TEST2COL VALUES(0, 0, 'Hallo'), (0, 1, 'Welt'), (1, 0, 'Hello'), (1, 1, 'World'); -> update count: 4 - -SELECT * FROM TEST2COL WHERE A=0 AND B=0; -> A B C -> - - ----- -> 0 0 Hallo -> rows: 1 - -EXPLAIN SELECT * FROM TEST2COL WHERE A=0 AND B=0; -> PLAN -> -------------------------------------------------------------------------------------------------------------------------------------------------- -> SELECT TEST2COL.A, TEST2COL.B, TEST2COL.C FROM PUBLIC.TEST2COL /* PUBLIC.PRIMARY_KEY_E: A = 0 AND B = 0 */ WHERE ((A = 0) AND (B = 0)) AND (A = B) -> rows: 1 - -SELECT * FROM TEST2COL WHERE A=0; -> A B C -> - - ----- -> 0 0 Hallo -> 0 1 Welt -> rows: 2 - -EXPLAIN SELECT * FROM TEST2COL WHERE A=0; -> PLAN -> ------------------------------------------------------------------------------------------------------------ -> SELECT TEST2COL.A, TEST2COL.B, TEST2COL.C FROM PUBLIC.TEST2COL /* PUBLIC.PRIMARY_KEY_E: A = 0 */ WHERE A = 0 -> rows: 1 - -SELECT * FROM TEST2COL WHERE B=0; -> A B C -> - - ----- -> 0 0 Hallo -> 1 0 Hello -> rows: 2 - -EXPLAIN SELECT * FROM TEST2COL WHERE B=0; -> PLAN -> ---------------------------------------------------------------------------------------------------------- -> SELECT TEST2COL.A, TEST2COL.B, TEST2COL.C FROM PUBLIC.TEST2COL /* PUBLIC.TEST2COL.tableScan */ WHERE B = 0 -> rows: 1 - -DROP TABLE TEST2COL; -> ok - ---- testCases ---------------------------------------------------------------------------------------------- -CREATE TABLE t_1 (ch CHARACTER(10), dec DECIMAL(10,2), do DOUBLE, lo BIGINT, "IN" INTEGER, sm SMALLINT, ty TINYINT, -da DATE DEFAULT CURRENT_DATE, ti TIME DEFAULT CURRENT_TIME, ts TIMESTAMP DEFAULT CURRENT_TIMESTAMP ); -> ok - -INSERT INTO T_1 (ch, dec, do) VALUES ('name', 10.23, 0); -> update count: 1 - -SELECT COUNT(*) FROM T_1; -> COUNT(*) -> -------- -> 1 -> rows: 1 - -DROP TABLE T_1; -> ok - ---- rights ---------------------------------------------------------------------------------------------- -CREATE USER TEST_USER PASSWORD '123'; -> ok - -CREATE TABLE TEST(ID INT); -> ok - -CREATE ROLE TEST_ROLE; -> ok - -CREATE ROLE IF NOT EXISTS TEST_ROLE; -> ok - -GRANT SELECT, INSERT ON TEST TO TEST_USER; -> ok - -GRANT UPDATE ON TEST TO TEST_ROLE; -> ok - -GRANT TEST_ROLE TO TEST_USER; -> ok - -SELECT NAME FROM INFORMATION_SCHEMA.ROLES; -> NAME -> --------- -> PUBLIC -> TEST_ROLE -> rows: 2 - -SELECT GRANTEE, GRANTEETYPE, GRANTEDROLE, RIGHTS, TABLE_SCHEMA, TABLE_NAME FROM INFORMATION_SCHEMA.RIGHTS; -> GRANTEE GRANTEETYPE GRANTEDROLE RIGHTS TABLE_SCHEMA TABLE_NAME -> --------- ----------- ----------- -------------- ------------ ---------- -> TEST_ROLE ROLE UPDATE PUBLIC TEST -> TEST_USER USER SELECT, INSERT PUBLIC TEST -> TEST_USER USER TEST_ROLE -> rows: 3 - -SELECT * FROM INFORMATION_SCHEMA.TABLE_PRIVILEGES; -> GRANTOR GRANTEE TABLE_CATALOG TABLE_SCHEMA TABLE_NAME PRIVILEGE_TYPE IS_GRANTABLE -> ------- --------- ------------- ------------ ---------- -------------- ------------ -> null TEST_ROLE SCRIPT PUBLIC TEST UPDATE NO -> null TEST_USER SCRIPT PUBLIC TEST INSERT NO -> null TEST_USER SCRIPT PUBLIC TEST SELECT NO -> rows: 3 - -SELECT * FROM INFORMATION_SCHEMA.COLUMN_PRIVILEGES; -> GRANTOR GRANTEE TABLE_CATALOG TABLE_SCHEMA TABLE_NAME COLUMN_NAME PRIVILEGE_TYPE IS_GRANTABLE -> ------- --------- ------------- ------------ ---------- ----------- -------------- ------------ -> null TEST_ROLE SCRIPT PUBLIC TEST ID UPDATE NO -> null TEST_USER SCRIPT PUBLIC TEST ID INSERT NO -> null TEST_USER SCRIPT PUBLIC TEST ID SELECT NO -> rows: 3 - -REVOKE INSERT ON TEST FROM TEST_USER; -> ok - -REVOKE TEST_ROLE FROM TEST_USER; -> ok - -SELECT GRANTEE, GRANTEETYPE, GRANTEDROLE, RIGHTS, TABLE_NAME FROM INFORMATION_SCHEMA.RIGHTS; -> GRANTEE GRANTEETYPE GRANTEDROLE RIGHTS TABLE_NAME -> --------- ----------- ----------- ------ ---------- -> TEST_ROLE ROLE UPDATE TEST -> TEST_USER USER SELECT TEST -> rows: 2 - -SELECT * FROM INFORMATION_SCHEMA.TABLE_PRIVILEGES; -> GRANTOR GRANTEE TABLE_CATALOG TABLE_SCHEMA TABLE_NAME PRIVILEGE_TYPE IS_GRANTABLE -> ------- --------- ------------- ------------ ---------- -------------- ------------ -> null TEST_ROLE SCRIPT PUBLIC TEST UPDATE NO -> null TEST_USER SCRIPT PUBLIC TEST SELECT NO -> rows: 2 - -DROP USER TEST_USER; -> ok - -DROP TABLE TEST; -> ok - -DROP ROLE TEST_ROLE; -> ok - -SELECT * FROM INFORMATION_SCHEMA.ROLES; -> NAME REMARKS ID -> ------ ------- -- -> PUBLIC 0 -> rows: 1 - -SELECT * FROM INFORMATION_SCHEMA.RIGHTS; -> GRANTEE GRANTEETYPE GRANTEDROLE RIGHTS TABLE_SCHEMA TABLE_NAME ID -> ------- ----------- ----------- ------ ------------ ---------- -- -> rows: 0 - ---- plan ---------------------------------------------------------------------------------------------- -CREATE TABLE TEST(ID INT PRIMARY KEY, NAME VARCHAR(255)); -> ok - -INSERT INTO TEST VALUES(?, ?); -{ -1, Hello -2, World -3, Peace -}; -> update count: 3 - -EXPLAIN INSERT INTO TEST VALUES(1, 'Test'); -> PLAN -> ---------------------------------------------------- -> INSERT INTO PUBLIC.TEST(ID, NAME) VALUES (1, 'Test') -> rows: 1 - -EXPLAIN INSERT INTO TEST VALUES(1, 'Test'), (2, 'World'); -> PLAN -> ------------------------------------------------------------------ -> INSERT INTO PUBLIC.TEST(ID, NAME) VALUES (1, 'Test'), (2, 'World') -> rows: 1 - -EXPLAIN INSERT INTO TEST SELECT DISTINCT ID+1, NAME FROM TEST; -> PLAN -> ------------------------------------------------------------------------------------------------------------- -> INSERT INTO PUBLIC.TEST(ID, NAME) SELECT DISTINCT (ID + 1), NAME FROM PUBLIC.TEST /* PUBLIC.TEST.tableScan */ -> rows: 1 - -EXPLAIN SELECT DISTINCT ID + 1, NAME FROM TEST; -> PLAN -> --------------------------------------------------------------------------- -> SELECT DISTINCT (ID + 1), NAME FROM PUBLIC.TEST /* PUBLIC.TEST.tableScan */ -> rows: 1 - -EXPLAIN SELECT * FROM TEST WHERE 1=0; -> PLAN -> ----------------------------------------------------------------------------------------- -> SELECT TEST.ID, TEST.NAME FROM PUBLIC.TEST /* PUBLIC.TEST.tableScan: FALSE */ WHERE FALSE -> rows: 1 - -EXPLAIN SELECT TOP 1 * FROM TEST FOR UPDATE; -> PLAN -> ----------------------------------------------------------------------------------------- -> SELECT TEST.ID, TEST.NAME FROM PUBLIC.TEST /* PUBLIC.TEST.tableScan */ LIMIT 1 FOR UPDATE -> rows: 1 - -EXPLAIN SELECT COUNT(NAME) FROM TEST WHERE ID=1; -> PLAN -> ----------------------------------------------------------------------------------- -> SELECT COUNT(NAME) FROM PUBLIC.TEST /* PUBLIC.PRIMARY_KEY_2: ID = 1 */ WHERE ID = 1 -> rows: 1 - -EXPLAIN SELECT * FROM TEST WHERE (ID>=1 AND ID<=2) OR (ID>0 AND ID<3) AND (ID<>6) ORDER BY NAME NULLS FIRST, 1 NULLS LAST, (1+1) DESC; -> PLAN -> ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -> SELECT TEST.ID, TEST.NAME FROM PUBLIC.TEST /* PUBLIC.TEST.tableScan */ WHERE ((ID >= 1) AND (ID <= 2)) OR ((ID <> 6) AND ((ID > 0) AND (ID < 3))) ORDER BY 2 NULLS FIRST, 1 NULLS LAST, =2 DESC -> rows (ordered): 1 - -EXPLAIN SELECT * FROM TEST WHERE ID=1 GROUP BY NAME, ID; -> PLAN -> ------------------------------------------------------------------------------------------------------------ -> SELECT TEST.ID, TEST.NAME FROM PUBLIC.TEST /* PUBLIC.PRIMARY_KEY_2: ID = 1 */ WHERE ID = 1 GROUP BY NAME, ID -> rows: 1 - -EXPLAIN PLAN FOR UPDATE TEST SET NAME='Hello', ID=1 WHERE NAME LIKE 'T%' ESCAPE 'x'; -> PLAN -> --------------------------------------------------------------------------------------------------------- -> UPDATE PUBLIC.TEST /* PUBLIC.TEST.tableScan */ SET ID = 1, NAME = 'Hello' WHERE NAME LIKE 'T%' ESCAPE 'x' -> rows: 1 - -EXPLAIN PLAN FOR DELETE FROM TEST; -> PLAN -> --------------------------------------------------- -> DELETE FROM PUBLIC.TEST /* PUBLIC.TEST.tableScan */ -> rows: 1 - -EXPLAIN PLAN FOR SELECT NAME, COUNT(*) FROM TEST GROUP BY NAME HAVING COUNT(*) > 1; -> PLAN -> ---------------------------------------------------------------------------------------------------- -> SELECT NAME, COUNT(*) FROM PUBLIC.TEST /* PUBLIC.TEST.tableScan */ GROUP BY NAME HAVING COUNT(*) > 1 -> rows: 1 - -EXPLAIN PLAN FOR SELECT * FROM test t1 inner join test t2 on t1.id=t2.id and t2.name is not null where t1.id=1; -> PLAN -> --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -> SELECT T1.ID, T1.NAME, T2.ID, T2.NAME FROM PUBLIC.TEST T1 /* PUBLIC.PRIMARY_KEY_2: ID = 1 */ /* WHERE T1.ID = 1 */ INNER JOIN PUBLIC.TEST T2 /* PUBLIC.PRIMARY_KEY_2: ID = T1.ID AND ID = T1.ID */ ON 1=1 WHERE (T1.ID = 1) AND ((T2.NAME IS NOT NULL) AND (T1.ID = T2.ID)) -> rows: 1 - -EXPLAIN PLAN FOR SELECT * FROM test t1 left outer join test t2 on t1.id=t2.id and t2.name is not null where t1.id=1; -> PLAN -> ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -> SELECT T1.ID, T1.NAME, T2.ID, T2.NAME FROM PUBLIC.TEST T1 /* PUBLIC.PRIMARY_KEY_2: ID = 1 */ /* WHERE T1.ID = 1 */ LEFT OUTER JOIN PUBLIC.TEST T2 /* PUBLIC.PRIMARY_KEY_2: ID = T1.ID */ ON (T2.NAME IS NOT NULL) AND (T1.ID = T2.ID) WHERE T1.ID = 1 -> rows: 1 - -EXPLAIN PLAN FOR SELECT * FROM test t1 left outer join test t2 on t1.id=t2.id and t2.name is null where t1.id=1; -> PLAN -> ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -> SELECT T1.ID, T1.NAME, T2.ID, T2.NAME FROM PUBLIC.TEST T1 /* PUBLIC.PRIMARY_KEY_2: ID = 1 */ /* WHERE T1.ID = 1 */ LEFT OUTER JOIN PUBLIC.TEST T2 /* PUBLIC.PRIMARY_KEY_2: ID = T1.ID */ ON (T2.NAME IS NULL) AND (T1.ID = T2.ID) WHERE T1.ID = 1 -> rows: 1 - -EXPLAIN PLAN FOR SELECT * FROM TEST T1 WHERE EXISTS(SELECT * FROM TEST T2 WHERE T1.ID-1 = T2.ID); -> PLAN -> ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -> SELECT T1.ID, T1.NAME FROM PUBLIC.TEST T1 /* PUBLIC.TEST.tableScan */ WHERE EXISTS(SELECT T2.ID, T2.NAME FROM PUBLIC.TEST T2 /* PUBLIC.PRIMARY_KEY_2: ID = (T1.ID - 1) */ WHERE (T1.ID - 1) = T2.ID) -> rows: 1 - -EXPLAIN PLAN FOR SELECT * FROM TEST T1 WHERE ID IN(1, 2); -> PLAN -> --------------------------------------------------------------------------------------------------- -> SELECT T1.ID, T1.NAME FROM PUBLIC.TEST T1 /* PUBLIC.PRIMARY_KEY_2: ID IN(1, 2) */ WHERE ID IN(1, 2) -> rows: 1 - -EXPLAIN PLAN FOR SELECT * FROM TEST T1 WHERE ID IN(SELECT ID FROM TEST); -> PLAN -> --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -> SELECT T1.ID, T1.NAME FROM PUBLIC.TEST T1 /* PUBLIC.PRIMARY_KEY_2: ID IN(SELECT DISTINCT ID FROM PUBLIC.TEST /++ PUBLIC.TEST.tableScan ++/) */ WHERE ID IN(SELECT DISTINCT ID FROM PUBLIC.TEST /* PUBLIC.TEST.tableScan */) -> rows: 1 - -EXPLAIN PLAN FOR SELECT * FROM TEST T1 WHERE ID NOT IN(SELECT ID FROM TEST); -> PLAN -> -------------------------------------------------------------------------------------------------------------------------------------------------------- -> SELECT T1.ID, T1.NAME FROM PUBLIC.TEST T1 /* PUBLIC.TEST.tableScan */ WHERE NOT (ID IN(SELECT DISTINCT ID FROM PUBLIC.TEST /* PUBLIC.TEST.tableScan */)) -> rows: 1 - -EXPLAIN PLAN FOR SELECT CAST(ID AS VARCHAR(255)) FROM TEST; -> PLAN -> ---------------------------------------------------------------------------- -> SELECT CAST(ID AS VARCHAR(255)) FROM PUBLIC.TEST /* PUBLIC.TEST.tableScan */ -> rows: 1 - -EXPLAIN PLAN FOR SELECT LEFT(NAME, 2) FROM TEST; -> PLAN -> ----------------------------------------------------------------- -> SELECT LEFT(NAME, 2) FROM PUBLIC.TEST /* PUBLIC.TEST.tableScan */ -> rows: 1 - -EXPLAIN PLAN FOR SELECT * FROM SYSTEM_RANGE(1, 20); -> PLAN -> ----------------------------------------------------------------------- -> SELECT SYSTEM_RANGE.X FROM SYSTEM_RANGE(1, 20) /* PUBLIC.RANGE_INDEX */ -> rows: 1 - -SELECT * FROM test t1 inner join test t2 on t1.id=t2.id and t2.name is not null where t1.id=1; -> ID NAME ID NAME -> -- ----- -- ----- -> 1 Hello 1 Hello -> rows: 1 - -SELECT * FROM test t1 left outer join test t2 on t1.id=t2.id and t2.name is not null where t1.id=1; -> ID NAME ID NAME -> -- ----- -- ----- -> 1 Hello 1 Hello -> rows: 1 - -SELECT * FROM test t1 left outer join test t2 on t1.id=t2.id and t2.name is null where t1.id=1; -> ID NAME ID NAME -> -- ----- ---- ---- -> 1 Hello null null -> rows: 1 - -DROP TABLE TEST; -> ok - ---- union ---------------------------------------------------------------------------------------------- -SELECT * FROM SYSTEM_RANGE(1,2) UNION ALL SELECT * FROM SYSTEM_RANGE(1,2) ORDER BY 1; -> X -> - -> 1 -> 1 -> 2 -> 2 -> rows (ordered): 4 - -EXPLAIN (SELECT * FROM SYSTEM_RANGE(1,2) UNION ALL SELECT * FROM SYSTEM_RANGE(1,2) ORDER BY 1); -> PLAN -> ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- -> (SELECT SYSTEM_RANGE.X FROM SYSTEM_RANGE(1, 2) /* PUBLIC.RANGE_INDEX */) UNION ALL (SELECT SYSTEM_RANGE.X FROM SYSTEM_RANGE(1, 2) /* PUBLIC.RANGE_INDEX */) ORDER BY 1 -> rows (ordered): 1 - -CREATE TABLE CHILDREN(ID INT PRIMARY KEY, NAME VARCHAR(255), CLASS INT); -> ok - -CREATE TABLE CLASSES(ID INT PRIMARY KEY, NAME VARCHAR(255)); -> ok - -INSERT INTO CHILDREN VALUES(?, ?, ?); -{ -0, Joe, 0 -1, Anne, 1 -2, Joerg, 1 -3, Petra, 2 -}; -> update count: 4 - -INSERT INTO CLASSES VALUES(?, ?); -{ -0, Kindergarden -1, Class 1 -2, Class 2 -3, Class 3 -4, Class 4 -}; -> update count: 5 - -SELECT * FROM CHILDREN UNION ALL SELECT * FROM CHILDREN ORDER BY ID, NAME FOR UPDATE; -> ID NAME CLASS -> -- ----- ----- -> 0 Joe 0 -> 0 Joe 0 -> 1 Anne 1 -> 1 Anne 1 -> 2 Joerg 1 -> 2 Joerg 1 -> 3 Petra 2 -> 3 Petra 2 -> rows (ordered): 8 - -EXPLAIN SELECT * FROM CHILDREN UNION ALL SELECT * FROM CHILDREN ORDER BY ID, NAME FOR UPDATE; -> PLAN -> -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -> (SELECT CHILDREN.ID, CHILDREN.NAME, CHILDREN.CLASS FROM PUBLIC.CHILDREN /* PUBLIC.CHILDREN.tableScan */ FOR UPDATE) UNION ALL (SELECT CHILDREN.ID, CHILDREN.NAME, CHILDREN.CLASS FROM PUBLIC.CHILDREN /* PUBLIC.CHILDREN.tableScan */ FOR UPDATE) ORDER BY 1, 2 FOR UPDATE -> rows (ordered): 1 - -SELECT 'Child', ID, NAME FROM CHILDREN UNION SELECT 'Class', ID, NAME FROM CLASSES; -> 'Child' ID NAME -> ------- -- ------------ -> Child 0 Joe -> Child 1 Anne -> Child 2 Joerg -> Child 3 Petra -> Class 0 Kindergarden -> Class 1 Class1 -> Class 2 Class2 -> Class 3 Class3 -> Class 4 Class4 -> rows: 9 - -EXPLAIN SELECT 'Child', ID, NAME FROM CHILDREN UNION SELECT 'Class', ID, NAME FROM CLASSES; -> PLAN -> ------------------------------------------------------------------------------------------------------------------------------------------------------------------- -> (SELECT 'Child', ID, NAME FROM PUBLIC.CHILDREN /* PUBLIC.CHILDREN.tableScan */) UNION (SELECT 'Class', ID, NAME FROM PUBLIC.CLASSES /* PUBLIC.CLASSES.tableScan */) -> rows: 1 - -SELECT * FROM CHILDREN EXCEPT SELECT * FROM CHILDREN WHERE CLASS=0; -> ID NAME CLASS -> -- ----- ----- -> 1 Anne 1 -> 2 Joerg 1 -> 3 Petra 2 -> rows: 3 - -EXPLAIN SELECT * FROM CHILDREN EXCEPT SELECT * FROM CHILDREN WHERE CLASS=0; -> PLAN -> ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -> (SELECT CHILDREN.ID, CHILDREN.NAME, CHILDREN.CLASS FROM PUBLIC.CHILDREN /* PUBLIC.CHILDREN.tableScan */) EXCEPT (SELECT CHILDREN.ID, CHILDREN.NAME, CHILDREN.CLASS FROM PUBLIC.CHILDREN /* PUBLIC.CHILDREN.tableScan */ WHERE CLASS = 0) -> rows: 1 - -EXPLAIN SELECT CLASS FROM CHILDREN INTERSECT SELECT ID FROM CLASSES; -> PLAN -> -------------------------------------------------------------------------------------------------------------------------------------------- -> (SELECT CLASS FROM PUBLIC.CHILDREN /* PUBLIC.CHILDREN.tableScan */) INTERSECT (SELECT ID FROM PUBLIC.CLASSES /* PUBLIC.CLASSES.tableScan */) -> rows: 1 - -SELECT CLASS FROM CHILDREN INTERSECT SELECT ID FROM CLASSES; -> CLASS -> ----- -> 0 -> 1 -> 2 -> rows: 3 - -EXPLAIN SELECT * FROM CHILDREN EXCEPT SELECT * FROM CHILDREN WHERE CLASS=0; -> PLAN -> ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -> (SELECT CHILDREN.ID, CHILDREN.NAME, CHILDREN.CLASS FROM PUBLIC.CHILDREN /* PUBLIC.CHILDREN.tableScan */) EXCEPT (SELECT CHILDREN.ID, CHILDREN.NAME, CHILDREN.CLASS FROM PUBLIC.CHILDREN /* PUBLIC.CHILDREN.tableScan */ WHERE CLASS = 0) -> rows: 1 - -SELECT * FROM CHILDREN CH, CLASSES CL WHERE CH.CLASS = CL.ID; -> ID NAME CLASS ID NAME -> -- ----- ----- -- ------------ -> 0 Joe 0 0 Kindergarden -> 1 Anne 1 1 Class1 -> 2 Joerg 1 1 Class1 -> 3 Petra 2 2 Class2 -> rows: 4 - -SELECT CH.ID CH_ID, CH.NAME CH_NAME, CL.ID CL_ID, CL.NAME CL_NAME FROM CHILDREN CH, CLASSES CL WHERE CH.CLASS = CL.ID; -> CH_ID CH_NAME CL_ID CL_NAME -> ----- ------- ----- ------------ -> 0 Joe 0 Kindergarden -> 1 Anne 1 Class1 -> 2 Joerg 1 Class1 -> 3 Petra 2 Class2 -> rows: 4 - -CREATE VIEW CHILDREN_CLASSES(CH_ID, CH_NAME, CL_ID, CL_NAME) AS -SELECT CH.ID CH_ID1, CH.NAME CH_NAME2, CL.ID CL_ID3, CL.NAME CL_NAME4 -FROM CHILDREN CH, CLASSES CL WHERE CH.CLASS = CL.ID; -> ok - -SELECT * FROM CHILDREN_CLASSES WHERE CH_NAME <> 'X'; -> CH_ID CH_NAME CL_ID CL_NAME -> ----- ------- ----- ------------ -> 0 Joe 0 Kindergarden -> 1 Anne 1 Class1 -> 2 Joerg 1 Class1 -> 3 Petra 2 Class2 -> rows: 4 - -CREATE VIEW CHILDREN_CLASS1 AS SELECT * FROM CHILDREN_CLASSES WHERE CL_ID=1; -> ok - -SELECT * FROM CHILDREN_CLASS1; -> CH_ID CH_NAME CL_ID CL_NAME -> ----- ------- ----- ------- -> 1 Anne 1 Class1 -> 2 Joerg 1 Class1 -> rows: 2 - -CREATE VIEW CHILDREN_CLASS2 AS SELECT * FROM CHILDREN_CLASSES WHERE CL_ID=2; -> ok - -SELECT * FROM CHILDREN_CLASS2; -> CH_ID CH_NAME CL_ID CL_NAME -> ----- ------- ----- ------- -> 3 Petra 2 Class2 -> rows: 1 - -CREATE VIEW CHILDREN_CLASS12 AS SELECT * FROM CHILDREN_CLASS1 UNION ALL SELECT * FROM CHILDREN_CLASS1; -> ok - -SELECT * FROM CHILDREN_CLASS12; -> CH_ID CH_NAME CL_ID CL_NAME -> ----- ------- ----- ------- -> 1 Anne 1 Class1 -> 1 Anne 1 Class1 -> 2 Joerg 1 Class1 -> 2 Joerg 1 Class1 -> rows: 4 - -DROP VIEW CHILDREN_CLASS1; -> ok - -DROP VIEW CHILDREN_CLASS2; -> ok - -DROP VIEW CHILDREN_CLASSES; -> ok - -DROP VIEW CHILDREN_CLASS12; -> exception - -CREATE VIEW V_UNION AS SELECT * FROM CHILDREN UNION ALL SELECT * FROM CHILDREN; -> ok - -SELECT * FROM V_UNION WHERE ID=1; -> ID NAME CLASS -> -- ---- ----- -> 1 Anne 1 -> 1 Anne 1 -> rows: 2 - -EXPLAIN SELECT * FROM V_UNION WHERE ID=1; -> PLAN -> ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -> SELECT V_UNION.ID, V_UNION.NAME, V_UNION.CLASS FROM PUBLIC.V_UNION /* (SELECT CHILDREN.ID, CHILDREN.NAME, CHILDREN.CLASS FROM PUBLIC.CHILDREN /++ PUBLIC.PRIMARY_KEY_9: ID = ?1 ++/ WHERE CHILDREN.ID = ?1) UNION ALL (SELECT CHILDREN.ID, CHILDREN.NAME, CHILDREN.CLASS FROM PUBLIC.CHILDREN /++ PUBLIC.PRIMARY_KEY_9: ID = ?1 ++/ WHERE CHILDREN.ID = ?1): ID = 1 */ WHERE ID = 1 -> rows: 1 - -CREATE VIEW V_EXCEPT AS SELECT * FROM CHILDREN EXCEPT SELECT * FROM CHILDREN WHERE ID=2; -> ok - -SELECT * FROM V_EXCEPT WHERE ID=1; -> ID NAME CLASS -> -- ---- ----- -> 1 Anne 1 -> rows: 1 - -EXPLAIN SELECT * FROM V_EXCEPT WHERE ID=1; -> PLAN -> ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -> SELECT V_EXCEPT.ID, V_EXCEPT.NAME, V_EXCEPT.CLASS FROM PUBLIC.V_EXCEPT /* (SELECT CHILDREN.ID, CHILDREN.NAME, CHILDREN.CLASS FROM PUBLIC.CHILDREN /++ PUBLIC.PRIMARY_KEY_9: ID = ?1 ++/ WHERE CHILDREN.ID = ?1) EXCEPT (SELECT CHILDREN.ID, CHILDREN.NAME, CHILDREN.CLASS FROM PUBLIC.CHILDREN /++ PUBLIC.PRIMARY_KEY_9: ID = 2 ++/ WHERE ID = 2): ID = 1 */ WHERE ID = 1 -> rows: 1 - -CREATE VIEW V_INTERSECT AS SELECT ID, NAME FROM CHILDREN INTERSECT SELECT * FROM CLASSES; -> ok - -SELECT * FROM V_INTERSECT WHERE ID=1; -> ID NAME -> -- ---- -> rows: 0 - -EXPLAIN SELECT * FROM V_INTERSECT WHERE ID=1; -> PLAN -> ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -> SELECT V_INTERSECT.ID, V_INTERSECT.NAME FROM PUBLIC.V_INTERSECT /* (SELECT ID, NAME FROM PUBLIC.CHILDREN /++ PUBLIC.PRIMARY_KEY_9: ID = ?1 ++/ WHERE ID = ?1) INTERSECT (SELECT CLASSES.ID, CLASSES.NAME FROM PUBLIC.CLASSES /++ PUBLIC.PRIMARY_KEY_5: ID = ?1 ++/ WHERE CLASSES.ID = ?1): ID = 1 */ WHERE ID = 1 -> rows: 1 - -DROP VIEW V_UNION; -> ok - -DROP VIEW V_EXCEPT; -> ok - -DROP VIEW V_INTERSECT; -> ok - -DROP TABLE CHILDREN; -> ok - -DROP TABLE CLASSES; -> ok - ---- view ---------------------------------------------------------------------------------------------- -CREATE CACHED TABLE TEST_A(ID INT PRIMARY KEY, NAME VARCHAR(255)); -> ok - -CREATE CACHED TABLE TEST_B(ID INT PRIMARY KEY, NAME VARCHAR(255)); -> ok - -SELECT A.ID AID, A.NAME A_NAME, B.ID BID, B.NAME B_NAME FROM TEST_A A INNER JOIN TEST_B B WHERE A.ID = B.ID; -> AID A_NAME BID B_NAME -> --- ------ --- ------ -> rows: 0 - -CREATE VIEW IF NOT EXISTS TEST_ALL AS SELECT A.ID AID, A.NAME A_NAME, B.ID BID, B.NAME B_NAME FROM TEST_A A, TEST_B B WHERE A.ID = B.ID; -> ok - -SELECT COUNT(*) FROM TEST_ALL; -> COUNT(*) -> -------- -> 0 -> rows: 1 - -CREATE VIEW IF NOT EXISTS TEST_ALL AS -SELECT * FROM TEST_A; -> ok - -INSERT INTO TEST_A VALUES(1, 'Hello'); -> update count: 1 - -INSERT INTO TEST_B VALUES(1, 'Hallo'); -> update count: 1 - -INSERT INTO TEST_A VALUES(2, 'World'); -> update count: 1 - -INSERT INTO TEST_B VALUES(2, 'Welt'); -> update count: 1 - -INSERT INTO TEST_A VALUES(3, 'Record'); -> update count: 1 - -INSERT INTO TEST_B VALUES(3, 'Rekord'); -> update count: 1 - -SELECT * FROM TEST_ALL; -> AID A_NAME BID B_NAME -> --- ------ --- ------ -> 1 Hello 1 Hallo -> 2 World 2 Welt -> 3 Record 3 Rekord -> rows: 3 - -SELECT * FROM TEST_ALL WHERE AID=1; -> AID A_NAME BID B_NAME -> --- ------ --- ------ -> 1 Hello 1 Hallo -> rows: 1 - -SELECT * FROM TEST_ALL WHERE AID>0; -> AID A_NAME BID B_NAME -> --- ------ --- ------ -> 1 Hello 1 Hallo -> 2 World 2 Welt -> 3 Record 3 Rekord -> rows: 3 - -SELECT * FROM TEST_ALL WHERE AID<2; -> AID A_NAME BID B_NAME -> --- ------ --- ------ -> 1 Hello 1 Hallo -> rows: 1 - -SELECT * FROM TEST_ALL WHERE AID<=2; -> AID A_NAME BID B_NAME -> --- ------ --- ------ -> 1 Hello 1 Hallo -> 2 World 2 Welt -> rows: 2 - -SELECT * FROM TEST_ALL WHERE AID>=2; -> AID A_NAME BID B_NAME -> --- ------ --- ------ -> 2 World 2 Welt -> 3 Record 3 Rekord -> rows: 2 - -CREATE VIEW TEST_A_SUB AS SELECT * FROM TEST_A WHERE ID < 2; -> ok - -SELECT TABLE_NAME, SQL FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_TYPE='VIEW'; -> TABLE_NAME SQL -> ---------- -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -> TEST_ALL CREATE FORCE VIEW PUBLIC.TEST_ALL(AID, A_NAME, BID, B_NAME) AS SELECT A.ID AS AID, A.NAME AS A_NAME, B.ID AS BID, B.NAME AS B_NAME FROM PUBLIC.TEST_A A /* PUBLIC.TEST_A.tableScan */ INNER JOIN PUBLIC.TEST_B B /* PUBLIC.PRIMARY_KEY_93: ID = A.ID */ ON 1=1 WHERE A.ID = B.ID -> TEST_A_SUB CREATE FORCE VIEW PUBLIC.TEST_A_SUB(ID, NAME) AS SELECT TEST_A.ID, TEST_A.NAME FROM PUBLIC.TEST_A /* PUBLIC.PRIMARY_KEY_9: ID < 2 */ WHERE ID < 2 -> rows: 2 - -SELECT * FROM TEST_A_SUB WHERE NAME IS NOT NULL; -> ID NAME -> -- ----- -> 1 Hello -> rows: 1 - -DROP VIEW TEST_A_SUB; -> ok - -DROP TABLE TEST_A; -> ok - -DROP TABLE TEST_B; -> ok - -DROP VIEW TEST_ALL; -> exception - -DROP VIEW IF EXISTS TEST_ALL; -> ok - ---- commit/rollback ---------------------------------------------------------------------------------------------- -CREATE TABLE TEST(ID INT PRIMARY KEY, NAME VARCHAR(255)); -> ok - -SET AUTOCOMMIT FALSE; -> ok - -INSERT INTO TEST VALUES(1, 'Test'); -> update count: 1 - -ROLLBACK; -> ok - -SELECT * FROM TEST; -> ID NAME -> -- ---- -> rows: 0 - -INSERT INTO TEST VALUES(1, 'Test2'); -> update count: 1 - -SAVEPOINT TEST; -> ok - -INSERT INTO TEST VALUES(2, 'World'); -> update count: 1 - -ROLLBACK TO SAVEPOINT NOT_EXISTING; -> exception - -ROLLBACK TO SAVEPOINT TEST; -> ok - -SELECT * FROM TEST; -> ID NAME -> -- ----- -> 1 Test2 -> rows: 1 - -ROLLBACK WORK; -> ok - -SELECT * FROM TEST; -> ID NAME -> -- ---- -> rows: 0 - -INSERT INTO TEST VALUES(1, 'Test3'); -> update count: 1 - -SAVEPOINT TEST3; -> ok - -INSERT INTO TEST VALUES(2, 'World2'); -> update count: 1 - -ROLLBACK TO SAVEPOINT TEST3; -> ok - -COMMIT WORK; -> ok - -SELECT * FROM TEST; -> ID NAME -> -- ----- -> 1 Test3 -> rows: 1 - -SET AUTOCOMMIT TRUE; -> ok - -DROP TABLE TEST; -> ok - ---- insert..select ---------------------------------------------------------------------------------------------- -CREATE TABLE TEST(ID INT PRIMARY KEY, NAME VARCHAR(255)); -> ok - -INSERT INTO TEST VALUES(0, 'Hello'); -> update count: 1 - -INSERT INTO TEST SELECT ID+1, NAME||'+' FROM TEST; -> update count: 1 - -INSERT INTO TEST SELECT ID+2, NAME||'+' FROM TEST; -> update count: 2 - -INSERT INTO TEST SELECT ID+4, NAME||'+' FROM TEST; -> update count: 4 - -SELECT * FROM TEST; -> ID NAME -> -- -------- -> 0 Hello -> 1 Hello+ -> 2 Hello+ -> 3 Hello++ -> 4 Hello+ -> 5 Hello++ -> 6 Hello++ -> 7 Hello+++ -> rows: 8 - -DROP TABLE TEST; -> ok - ---- range ---------------------------------------------------------------------------------------------- ---import java.math.*; ---int s=0;for(int i=2;i<=1000;i++) ---s+=BigInteger.valueOf(i).isProbablePrime(10000)?i:0;s; -select sum(x) from system_range(2, 1000) r where -not exists(select * from system_range(2, 32) r2 where r.x>r2.x and mod(r.x, r2.x)=0); -> SUM(X) -> ------ -> 76127 -> rows: 1 - -SELECT COUNT(*) FROM SYSTEM_RANGE(0, 2111222333); -> COUNT(*) -> ---------- -> 2111222334 -> rows: 1 - -select * from system_range(2, 100) r where -not exists(select * from system_range(2, 11) r2 where r.x>r2.x and mod(r.x, r2.x)=0); -> X -> -- -> 11 -> 13 -> 17 -> 19 -> 2 -> 23 -> 29 -> 3 -> 31 -> 37 -> 41 -> 43 -> 47 -> 5 -> 53 -> 59 -> 61 -> 67 -> 7 -> 71 -> 73 -> 79 -> 83 -> 89 -> 97 -> rows: 25 - ---- joins ---------------------------------------------------------------------------------------------------- -create table t1(id int, name varchar); -> ok - -insert into t1 values(1, 'hi'), (2, 'world'); -> update count: 2 - -create table t2(id int, name varchar); -> ok - -insert into t2 values(1, 'Hallo'), (3, 'Welt'); -> update count: 2 - -select * from t1 join t2 on t1.id=t2.id; -> ID NAME ID NAME -> -- ---- -- ----- -> 1 hi 1 Hallo -> rows: 1 - -select * from t1 left join t2 on t1.id=t2.id; -> ID NAME ID NAME -> -- ----- ---- ----- -> 1 hi 1 Hallo -> 2 world null null -> rows: 2 - -select * from t1 right join t2 on t1.id=t2.id; -> ID NAME ID NAME -> -- ----- ---- ---- -> 1 Hallo 1 hi -> 3 Welt null null -> rows: 2 - -select * from t1 cross join t2; -> ID NAME ID NAME -> -- ----- -- ----- -> 1 hi 1 Hallo -> 1 hi 3 Welt -> 2 world 1 Hallo -> 2 world 3 Welt -> rows: 4 - -select * from t1 natural join t2; -> ID NAME -> -- ---- -> rows: 0 - -explain select * from t1 natural join t2; -> PLAN -> ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -> SELECT T1.ID, T1.NAME FROM PUBLIC.T2 /* PUBLIC.T2.tableScan */ INNER JOIN PUBLIC.T1 /* PUBLIC.T1.tableScan */ ON 1=1 WHERE (PUBLIC.T1.ID = PUBLIC.T2.ID) AND (PUBLIC.T1.NAME = PUBLIC.T2.NAME) -> rows: 1 - -drop table t1; -> ok - -drop table t2; -> ok - -create table customer(customerid int, customer_name varchar); -> ok - -insert into customer values(0, 'Acme'); -> update count: 1 - -create table invoice(customerid int, invoiceid int, invoice_text varchar); -> ok - -insert into invoice values(0, 1, 'Soap'), (0, 2, 'More Soap'); -> update count: 2 - -create table INVOICE_LINE(line_id int, invoiceid int, customerid int, line_text varchar); -> ok - -insert into INVOICE_LINE values(10, 1, 0, 'Super Soap'), (20, 1, 0, 'Regular Soap'); -> update count: 2 - -select c.*, i.*, l.* from customer c natural join invoice i natural join INVOICE_LINE l; -> CUSTOMERID CUSTOMER_NAME INVOICEID INVOICE_TEXT LINE_ID LINE_TEXT -> ---------- ------------- --------- ------------ ------- ------------ -> 0 Acme 1 Soap 10 Super Soap -> 0 Acme 1 Soap 20 Regular Soap -> rows: 2 - -explain select c.*, i.*, l.* from customer c natural join invoice i natural join INVOICE_LINE l; -> PLAN -> ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ -> SELECT C.CUSTOMERID, C.CUSTOMER_NAME, I.INVOICEID, I.INVOICE_TEXT, L.LINE_ID, L.LINE_TEXT FROM PUBLIC.INVOICE I /* PUBLIC.INVOICE.tableScan */ INNER JOIN PUBLIC.INVOICE_LINE L /* PUBLIC.INVOICE_LINE.tableScan */ ON 1=1 /* WHERE (PUBLIC.I.CUSTOMERID = PUBLIC.L.CUSTOMERID) AND (PUBLIC.I.INVOICEID = PUBLIC.L.INVOICEID) */ INNER JOIN PUBLIC.CUSTOMER C /* PUBLIC.CUSTOMER.tableScan */ ON 1=1 WHERE (PUBLIC.C.CUSTOMERID = PUBLIC.I.CUSTOMERID) AND ((PUBLIC.I.CUSTOMERID = PUBLIC.L.CUSTOMERID) AND (PUBLIC.I.INVOICEID = PUBLIC.L.INVOICEID)) -> rows: 1 - -drop table customer; -> ok - -drop table invoice; -> ok - -drop table INVOICE_LINE; -> ok - ---- outer joins ---------------------------------------------------------------------------------------------- -CREATE TABLE PARENT(ID INT, NAME VARCHAR(20)); -> ok - -CREATE TABLE CHILD(ID INT, PARENTID INT, NAME VARCHAR(20)); -> ok - -INSERT INTO PARENT VALUES(1, 'Sue'); -> update count: 1 - -INSERT INTO PARENT VALUES(2, 'Joe'); -> update count: 1 - -INSERT INTO CHILD VALUES(100, 1, 'Simon'); -> update count: 1 - -INSERT INTO CHILD VALUES(101, 1, 'Sabine'); -> update count: 1 - -SELECT * FROM PARENT P INNER JOIN CHILD C ON P.ID = C.PARENTID; -> ID NAME ID PARENTID NAME -> -- ---- --- -------- ------ -> 1 Sue 100 1 Simon -> 1 Sue 101 1 Sabine -> rows: 2 - -SELECT * FROM PARENT P LEFT OUTER JOIN CHILD C ON P.ID = C.PARENTID; -> ID NAME ID PARENTID NAME -> -- ---- ---- -------- ------ -> 1 Sue 100 1 Simon -> 1 Sue 101 1 Sabine -> 2 Joe null null null -> rows: 3 - -SELECT * FROM CHILD C RIGHT OUTER JOIN PARENT P ON P.ID = C.PARENTID; -> ID NAME ID PARENTID NAME -> -- ---- ---- -------- ------ -> 1 Sue 100 1 Simon -> 1 Sue 101 1 Sabine -> 2 Joe null null null -> rows: 3 - -DROP TABLE PARENT; -> ok - -DROP TABLE CHILD; -> ok - ---- syntax errors ---------------------------------------------------------------------------------------------- -CREATE SOMETHING STRANGE; -> exception - -SELECT T1.* T2; -> exception - -select replace('abchihihi', 'i', 'o') abcehohoho, replace('this is tom', 'i') 1e_th_st_om from test; -> exception - -select monthname(date )'005-0E9-12') d_set fm test; -> exception - -call substring('bob', 2, -1); -> '' -> -- -> -> rows: 1 - ---- like ---------------------------------------------------------------------------------------------- -CREATE TABLE TEST(ID INT PRIMARY KEY, NAME VARCHAR(255)); -> ok - -INSERT INTO TEST VALUES(0, NULL); -> update count: 1 - -INSERT INTO TEST VALUES(1, 'Hello'); -> update count: 1 - -INSERT INTO TEST VALUES(2, 'World'); -> update count: 1 - -INSERT INTO TEST VALUES(3, 'Word'); -> update count: 1 - -INSERT INTO TEST VALUES(4, 'Wo%'); -> update count: 1 - -SELECT * FROM TEST WHERE NAME IS NULL; -> ID NAME -> -- ---- -> 0 null -> rows: 1 - -SELECT * FROM TEST WHERE NAME IS NOT NULL; -> ID NAME -> -- ----- -> 1 Hello -> 2 World -> 3 Word -> 4 Wo% -> rows: 4 - -SELECT * FROM TEST WHERE NAME BETWEEN 'H' AND 'Word'; -> ID NAME -> -- ----- -> 1 Hello -> 3 Word -> 4 Wo% -> rows: 3 - -SELECT * FROM TEST WHERE ID >= 2 AND ID <= 3 AND ID <> 2; -> ID NAME -> -- ---- -> 3 Word -> rows: 1 - -SELECT * FROM TEST WHERE ID>0 AND ID<4 AND ID!=2; -> ID NAME -> -- ----- -> 1 Hello -> 3 Word -> rows: 2 - -SELECT * FROM TEST WHERE 'Hello' LIKE '_el%'; -> ID NAME -> -- ----- -> 0 null -> 1 Hello -> 2 World -> 3 Word -> 4 Wo% -> rows: 5 - -SELECT * FROM TEST WHERE NAME LIKE 'Hello%'; -> ID NAME -> -- ----- -> 1 Hello -> rows: 1 - -SELECT * FROM TEST WHERE NAME LIKE 'Wo%'; -> ID NAME -> -- ----- -> 2 World -> 3 Word -> 4 Wo% -> rows: 3 - -SELECT * FROM TEST WHERE NAME LIKE 'Wo\%'; -> ID NAME -> -- ---- -> 4 Wo% -> rows: 1 - -SELECT * FROM TEST WHERE NAME LIKE 'WoX%' ESCAPE 'X'; -> ID NAME -> -- ---- -> 4 Wo% -> rows: 1 - -SELECT * FROM TEST WHERE NAME LIKE 'Word_'; -> ID NAME -> -- ---- -> rows: 0 - -SELECT * FROM TEST WHERE NAME LIKE '%Hello%'; -> ID NAME -> -- ----- -> 1 Hello -> rows: 1 - -SELECT * FROM TEST WHERE 'Hello' LIKE NAME; -> ID NAME -> -- ----- -> 1 Hello -> rows: 1 - -SELECT T1.*, T2.* FROM TEST AS T1, TEST AS T2 WHERE T1.ID = T2.ID AND T1.NAME LIKE T2.NAME || '%'; -> ID NAME ID NAME -> -- ----- -- ----- -> 1 Hello 1 Hello -> 2 World 2 World -> 3 Word 3 Word -> 4 Wo% 4 Wo% -> rows: 4 - -SELECT ID, MAX(NAME) FROM TEST GROUP BY ID HAVING MAX(NAME) = 'World'; -> ID MAX(NAME) -> -- --------- -> 2 World -> rows: 1 - -SELECT ID, MAX(NAME) FROM TEST GROUP BY ID HAVING MAX(NAME) LIKE 'World%'; -> ID MAX(NAME) -> -- --------- -> 2 World -> rows: 1 - -DROP TABLE TEST; -> ok - ---- remarks/comments/syntax ---------------------------------------------------------------------------------------------- -CREATE TABLE TEST( -ID INT PRIMARY KEY, -- this is the primary key, type {integer} -NAME VARCHAR(255) -- this is a string -); -> ok - -INSERT INTO TEST VALUES( -1 /* ID */, -'Hello' // NAME -); -> update count: 1 - -SELECT * FROM TEST; -> ID NAME -> -- ----- -> 1 Hello -> rows: 1 - -DROP_ TABLE_ TEST_T; -> exception - -DROP TABLE TEST /*; -> exception - -DROP TABLE TEST; -> ok - ---- exists ---------------------------------------------------------------------------------------------- -CREATE TABLE TEST(ID INT PRIMARY KEY, NAME VARCHAR(255)); -> ok - -INSERT INTO TEST VALUES(0, NULL); -> update count: 1 - -INSERT INTO TEST VALUES(1, 'Hello'); -> update count: 1 - -INSERT INTO TEST VALUES(2, 'World'); -> update count: 1 - -SELECT * FROM TEST T WHERE NOT EXISTS( -SELECT * FROM TEST T2 WHERE T.ID > T2.ID); -> ID NAME -> -- ---- -> 0 null -> rows: 1 - -DROP TABLE TEST; -> ok - ---- subquery ---------------------------------------------------------------------------------------------- -CREATE TABLE TEST(ID INT PRIMARY KEY, NAME VARCHAR(255)); -> ok - -INSERT INTO TEST VALUES(0, NULL); -> update count: 1 - -INSERT INTO TEST VALUES(1, 'Hello'); -> update count: 1 - -select * from test where (select max(t1.id) from test t1) between 0 and 100; -> ID NAME -> -- ----- -> 0 null -> 1 Hello -> rows: 2 - -INSERT INTO TEST VALUES(2, 'World'); -> update count: 1 - -SELECT * FROM TEST T WHERE T.ID = (SELECT T2.ID FROM TEST T2 WHERE T2.ID=T.ID); -> ID NAME -> -- ----- -> 0 null -> 1 Hello -> 2 World -> rows: 3 - -SELECT (SELECT T2.NAME FROM TEST T2 WHERE T2.ID=T.ID), T.NAME FROM TEST T; -> SELECT T2.NAME FROM PUBLIC.TEST T2 /* PUBLIC.PRIMARY_KEY_2: ID = T.ID */ /* scanCount: 2 */ WHERE T2.ID = T.ID NAME -> -------------------------------------------------------------------------------------------------------------- ----- -> Hello Hello -> World World -> null null -> rows: 3 - -SELECT (SELECT SUM(T2.ID) FROM TEST T2 WHERE T2.ID>T.ID), T.ID FROM TEST T; -> SELECT SUM(T2.ID) FROM PUBLIC.TEST T2 /* PUBLIC.PRIMARY_KEY_2: ID > T.ID */ /* scanCount: 2 */ WHERE T2.ID > T.ID ID -> ----------------------------------------------------------------------------------------------------------------- -- -> 2 1 -> 3 0 -> null 2 -> rows: 3 - -select * from test t where t.id+1 in (select id from test); -> ID NAME -> -- ----- -> 0 null -> 1 Hello -> rows: 2 - -select * from test t where t.id in (select id from test where id=t.id); -> ID NAME -> -- ----- -> 0 null -> 1 Hello -> 2 World -> rows: 3 - -select 1 from test, test where 1 in (select 1 from test where id=1); -> 1 -> - -> 1 -> 1 -> 1 -> 1 -> 1 -> 1 -> 1 -> 1 -> 1 -> rows: 9 - -select * from test, test where id=id; -> exception - -select 1 from test, test where id=id; -> exception - -select 1 from test where id in (select id from test, test); -> exception - -DROP TABLE TEST; -> ok - ---- group by ---------------------------------------------------------------------------------------------- -CREATE TABLE TEST(A INT, B INT, VALUE INT, UNIQUE(A, B)); -> ok - -INSERT INTO TEST VALUES(?, ?, ?); -{ -NULL, NULL, NULL -NULL, 0, 0 -NULL, 1, 10 -0, 0, -1 -0, 1, 100 -1, 0, 200 -1, 1, 300 -}; -> update count: 7 - -SELECT A, B, COUNT(*) CAL, COUNT(A) CA, COUNT(B) CB, MIN(VALUE) MI, MAX(VALUE) MA, SUM(VALUE) S FROM TEST GROUP BY A, B; -> A B CAL CA CB MI MA S -> ---- ---- --- -- -- ---- ---- ---- -> 0 0 1 1 1 -1 -1 -1 -> 0 1 1 1 1 100 100 100 -> 1 0 1 1 1 200 200 200 -> 1 1 1 1 1 300 300 300 -> null 0 1 0 1 0 0 0 -> null 1 1 0 1 10 10 10 -> null null 1 0 0 null null null -> rows: 7 - -DROP TABLE TEST; -> ok - ---- data types (blob, clob, varchar_ignorecase) ---------------------------------------------------------------------------------------------- -CREATE TABLE TEST(ID INT, XB BINARY, XBL BLOB, XO OTHER, XCL CLOB, XVI VARCHAR_IGNORECASE); -> ok - -INSERT INTO TEST VALUES(0, X '', '', '', '', ''); -> update count: 1 - -INSERT INTO TEST VALUES(1, X '0101', '0101', '0101', 'abc', 'aa'); -> update count: 1 - -INSERT INTO TEST VALUES(2, X '0AFF', '08FE', 'F0F1', 'AbCdEfG', 'ZzAaBb'); -> update count: 1 - -INSERT INTO TEST VALUES(3, X '112233445566778899aabbccddeeff112233445566778899aabbccddeeff112233445566778899aabbccddeeff112233445566778899aabbccddeeff112233445566778899aabbccddeeff112233445566778899aabbccddeeff112233445566778899aabbccddeeff112233445566778899aabbccddeeff112233445566778899aabbccddeeff112233445566778899aabbccddeeff', '112233445566778899aabbccddeeff112233445566778899aabbccddeeff112233445566778899aabbccddeeff112233445566778899aabbccddeeff112233445566778899aabbccddeeff112233445566778899aabbccddeeff112233445566778899aabbccddeeff112233445566778899aabbccddeeff112233445566778899aabbccddeeff112233445566778899aabbccddeeff', '112233445566778899aabbccddeeff112233445566778899aabbccddeeff112233445566778899aabbccddeeff112233445566778899aabbccddeeff112233445566778899aabbccddeeff112233445566778899aabbccddeeff112233445566778899aabbccddeeff112233445566778899aabbccddeeff112233445566778899aabbccddeeff112233445566778899aabbccddeeff', 'AbCdEfGhIjKlMnOpQrStUvWxYzAbCdEfGhIjKlMnOpQrStUvWxYzAbCdEfGhIjKlMnOpQrStUvWxYzAbCdEfGhIjKlMnOpQrStUvWxYzAbCdEfGhIjKlMnOpQrStUvWxYzAbCdEfGhIjKlMnOpQrStUvWxYzAbCdEfGhIjKlMnOpQrStUvWxYzAbCdEfGhIjKlMnOpQrStUvWxYzAbCdEfGhIjKlMnOpQrStUvWxYzAbCdEfGhIjKlMnOpQrStUvWxYzAbCdEfGhIjKlMnOpQrStUvWxYzAbCdEfGhIjKlMnOpQrStUvWxYzAbCdEfGhIjKlMnOpQrStUvWxYzAbCdEfGhIjKlMnOpQrStUvWxYzAbCdEfGhIjKlMnOpQrStUvWxYzAbCdEfGhIjKlMnOpQrStUvWxYzAbCdEfGhIjKlMnOpQrStUvWxYzAbCdEfGhIjKlMnOpQrStUvWxYzAbCdEfGhIjKlMnOpQrStUvWxYzAbCdEfGhIjKlMnOpQrStUvWxYz', 'AbCdEfGhIjKlMnOpQrStUvWxYzAbCdEfGhIjKlMnOpQrStUvWxYzAbCdEfGhIjKlMnOpQrStUvWxYzAbCdEfGhIjKlMnOpQrStUvWxYzAbCdEfGhIjKlMnOpQrStUvWxYzAbCdEfGhIjKlMnOpQrStUvWxYzAbCdEfGhIjKlMnOpQrStUvWxYzAbCdEfGhIjKlMnOpQrStUvWxYzAbCdEfGhIjKlMnOpQrStUvWxYzAbCdEfGhIjKlMnOpQrStUvWxYzAbCdEfGhIjKlMnOpQrStUvWxYzAbCdEfGhIjKlMnOpQrStUvWxYzAbCdEfGhIjKlMnOpQrStUvWxYzAbCdEfGhIjKlMnOpQrStUvWxYzAbCdEfGhIjKlMnOpQrStUvWxYzAbCdEfGhIjKlMnOpQrStUvWxYzAbCdEfGhIjKlMnOpQrStUvWxYzAbCdEfGhIjKlMnOpQrStUvWxYzAbCdEfGhIjKlMnOpQrStUvWxYzAbCdEfGhIjKlMnOpQrStUvWxYz'); -> update count: 1 - -INSERT INTO TEST VALUES(4, NULL, NULL, NULL, NULL, NULL); -> update count: 1 - -SELECT * FROM TEST; -> ID XB XBL XO XCL XVI -> -- ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -> 0 -> 1 0101 0101 0101 abc aa -> 2 0aff 08fe f0f1 AbCdEfG ZzAaBb -> 3 112233445566778899aabbccddeeff112233445566778899aabbccddeeff112233445566778899aabbccddeeff112233445566778899aabbccddeeff112233445566778899aabbccddeeff112233445566778899aabbccddeeff112233445566778899aabbccddeeff112233445566778899aabbccddeeff112233445566778899aabbccddeeff112233445566778899aabbccddeeff 112233445566778899aabbccddeeff112233445566778899aabbccddeeff112233445566778899aabbccddeeff112233445566778899aabbccddeeff112233445566778899aabbccddeeff112233445566778899aabbccddeeff112233445566778899aabbccddeeff112233445566778899aabbccddeeff112233445566778899aabbccddeeff112233445566778899aabbccddeeff 112233445566778899aabbccddeeff112233445566778899aabbccddeeff112233445566778899aabbccddeeff112233445566778899aabbccddeeff112233445566778899aabbccddeeff112233445566778899aabbccddeeff112233445566778899aabbccddeeff112233445566778899aabbccddeeff112233445566778899aabbccddeeff112233445566778899aabbccddeeff AbCdEfGhIjKlMnOpQrStUvWxYzAbCdEfGhIjKlMnOpQrStUvWxYzAbCdEfGhIjKlMnOpQrStUvWxYzAbCdEfGhIjKlMnOpQrStUvWxYzAbCdEfGhIjKlMnOpQrStUvWxYzAbCdEfGhIjKlMnOpQrStUvWxYzAbCdEfGhIjKlMnOpQrStUvWxYzAbCdEfGhIjKlMnOpQrStUvWxYzAbCdEfGhIjKlMnOpQrStUvWxYzAbCdEfGhIjKlMnOpQrStUvWxYzAbCdEfGhIjKlMnOpQrStUvWxYzAbCdEfGhIjKlMnOpQrStUvWxYzAbCdEfGhIjKlMnOpQrStUvWxYzAbCdEfGhIjKlMnOpQrStUvWxYzAbCdEfGhIjKlMnOpQrStUvWxYzAbCdEfGhIjKlMnOpQrStUvWxYzAbCdEfGhIjKlMnOpQrStUvWxYzAbCdEfGhIjKlMnOpQrStUvWxYzAbCdEfGhIjKlMnOpQrStUvWxYzAbCdEfGhIjKlMnOpQrStUvWxYz AbCdEfGhIjKlMnOpQrStUvWxYzAbCdEfGhIjKlMnOpQrStUvWxYzAbCdEfGhIjKlMnOpQrStUvWxYzAbCdEfGhIjKlMnOpQrStUvWxYzAbCdEfGhIjKlMnOpQrStUvWxYzAbCdEfGhIjKlMnOpQrStUvWxYzAbCdEfGhIjKlMnOpQrStUvWxYzAbCdEfGhIjKlMnOpQrStUvWxYzAbCdEfGhIjKlMnOpQrStUvWxYzAbCdEfGhIjKlMnOpQrStUvWxYzAbCdEfGhIjKlMnOpQrStUvWxYzAbCdEfGhIjKlMnOpQrStUvWxYzAbCdEfGhIjKlMnOpQrStUvWxYzAbCdEfGhIjKlMnOpQrStUvWxYzAbCdEfGhIjKlMnOpQrStUvWxYzAbCdEfGhIjKlMnOpQrStUvWxYzAbCdEfGhIjKlMnOpQrStUvWxYzAbCdEfGhIjKlMnOpQrStUvWxYzAbCdEfGhIjKlMnOpQrStUvWxYzAbCdEfGhIjKlMnOpQrStUvWxYz -> 4 null null null null null -> rows: 5 - -SELECT ID FROM TEST WHERE XCL = XCL; -> ID -> -- -> 0 -> 1 -> 2 -> 3 -> rows: 4 - -SELECT ID FROM TEST WHERE XCL LIKE 'abc%'; -> ID -> -- -> 1 -> rows: 1 - -SELECT ID FROM TEST WHERE XVI LIKE 'abc%'; -> ID -> -- -> 3 -> rows: 1 - -SELECT 'abc', 'Papa Joe''s', CAST(-1 AS SMALLINT), CAST(2 AS BIGINT), CAST(0 AS DOUBLE), CAST('0a0f' AS BINARY), CAST(125 AS TINYINT), TRUE, FALSE FROM TEST WHERE ID=1; -> 'abc' 'Papa Joe''s' -1 2 0.0 X'0a0f' 125 TRUE FALSE -> ----- ------------- -- - --- ------- --- ---- ----- -> abc Papa Joe's -1 2 0.0 0a0f 125 TRUE FALSE -> rows: 1 - -SELECT CAST('abcd' AS VARCHAR(255)), CAST('ef_gh' AS VARCHAR(3)); -> 'abcd' 'ef_' -> ------ ----- -> abcd ef_ -> rows: 1 - -DROP TABLE TEST; -> ok - ---- data types (date and time) ---------------------------------------------------------------------------------------------- -CREATE MEMORY TABLE TEST(ID INT, XT TIME, XD DATE, XTS TIMESTAMP); -> ok - -INSERT INTO TEST VALUES(0, '0:0:0','1-2-3','2-3-4 0:0:0'); -> update count: 1 - -INSERT INTO TEST VALUES(1, '01:02:03','2001-02-03','2001-02-29 0:0:0'); -> exception - -INSERT INTO TEST VALUES(1, '24:02:03','2001-02-03','2001-02-01 0:0:0'); -> exception - -INSERT INTO TEST VALUES(1, '23:02:03','2001-04-31','2001-02-01 0:0:0'); -> exception - -INSERT INTO TEST VALUES(1,'1:2:3','4-5-6','7-8-9 0:1:2'); -> update count: 1 - -INSERT INTO TEST VALUES(2,'23:59:59','1999-12-31','1999-12-31 23:59:59.123456789'); -> update count: 1 - -INSERT INTO TEST VALUES(NULL,NULL,NULL,NULL); -> update count: 1 - -SELECT * FROM TEST; -> ID XT XD XTS -> ---- -------- ---------- ----------------------------- -> 0 00:00:00 0001-02-03 0002-03-04 00:00:00.0 -> 1 01:02:03 0004-05-06 0007-08-09 00:01:02.0 -> 2 23:59:59 1999-12-31 1999-12-31 23:59:59.123456789 -> null null null null -> rows: 4 - -SELECT XD+1, XD-1, XD-XD FROM TEST; -> DATEADD('DAY', 1, XD) DATEADD('DAY', -1, XD) DATEDIFF('DAY', XD, XD) -> --------------------- ---------------------- ----------------------- -> 0001-02-04 00:00:00.0 0001-02-02 00:00:00.0 0 -> 0004-05-07 00:00:00.0 0004-05-05 00:00:00.0 0 -> 2000-01-01 00:00:00.0 1999-12-30 00:00:00.0 0 -> null null null -> rows: 4 - -SELECT ID, CAST(XT AS DATE) T2D, CAST(XTS AS DATE) TS2D, -CAST(XD AS TIME) D2T, CAST(XTS AS TIME) TS2T, -CAST(XT AS TIMESTAMP) D2TS, CAST(XD AS TIMESTAMP) D2TS FROM TEST; -> ID T2D TS2D D2T TS2T D2TS D2TS -> ---- ---------- ---------- -------- -------- --------------------- --------------------- -> 0 1970-01-01 0002-03-04 00:00:00 00:00:00 1970-01-01 00:00:00.0 0001-02-03 00:00:00.0 -> 1 1970-01-01 0007-08-09 00:00:00 00:01:02 1970-01-01 01:02:03.0 0004-05-06 00:00:00.0 -> 2 1970-01-01 1999-12-31 00:00:00 23:59:59 1970-01-01 23:59:59.0 1999-12-31 00:00:00.0 -> null null null null null null null -> rows: 4 - -SCRIPT SIMPLE NOPASSWORDS NOSETTINGS; -> SCRIPT -> ---------------------------------------------------------------------------------------------------------------------------------- -> -- 4 +/- SELECT COUNT(*) FROM PUBLIC.TEST; -> CREATE MEMORY TABLE PUBLIC.TEST( ID INT, XT TIME, XD DATE, XTS TIMESTAMP ); -> CREATE USER IF NOT EXISTS SA PASSWORD '' ADMIN; -> INSERT INTO PUBLIC.TEST(ID, XT, XD, XTS) VALUES(0, TIME '00:00:00', DATE '0001-02-03', TIMESTAMP '0002-03-04 00:00:00.0'); -> INSERT INTO PUBLIC.TEST(ID, XT, XD, XTS) VALUES(1, TIME '01:02:03', DATE '0004-05-06', TIMESTAMP '0007-08-09 00:01:02.0'); -> INSERT INTO PUBLIC.TEST(ID, XT, XD, XTS) VALUES(2, TIME '23:59:59', DATE '1999-12-31', TIMESTAMP '1999-12-31 23:59:59.123456789'); -> INSERT INTO PUBLIC.TEST(ID, XT, XD, XTS) VALUES(NULL, NULL, NULL, NULL); -> rows: 7 - -DROP TABLE TEST; -> ok - -CREATE TABLE TEST(ID INT PRIMARY KEY, t0 timestamp(23, 0), t1 timestamp(23, 1), t2 timestamp(23, 2), t5 timestamp(23, 5)); -> ok - -INSERT INTO TEST VALUES(1, '2001-01-01 12:34:56.789123', '2001-01-01 12:34:56.789123', '2001-01-01 12:34:56.789123', '2001-01-01 12:34:56.789123'); -> update count: 1 - -select * from test; -> ID T0 T1 T2 T5 -> -- --------------------- --------------------- ---------------------- ------------------------- -> 1 2001-01-01 12:34:57.0 2001-01-01 12:34:56.8 2001-01-01 12:34:56.79 2001-01-01 12:34:56.78912 -> rows: 1 - -DROP TABLE IF EXISTS TEST; -> ok - ---- data types (decimal) ---------------------------------------------------------------------------------------------- -CALL 1.2E10+1; -> 12000000001 -> ----------- -> 12000000001 -> rows: 1 - -CALL -1.2E-10-1; -> -1.00000000012 -> -------------- -> -1.00000000012 -> rows: 1 - -CALL 1E-1; -> 0.1 -> --- -> 0.1 -> rows: 1 - -CREATE TABLE TEST(ID INT, X1 BIT, XT TINYINT, X_SM SMALLINT, XB BIGINT, XD DECIMAL(10,2), XD2 DOUBLE PRECISION, XR REAL); -> ok - -INSERT INTO TEST VALUES(?, ?, ?, ?, ?, ?, ?, ?); -{ -0,FALSE,0,0,0,0.0,0.0,0.0 -1,TRUE,1,1,1,1.0,1.0,1.0 -4,TRUE,4,4,4,4.0,4.0,4.0 --1,FALSE,-1,-1,-1,-1.0,-1.0,-1.0 -NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL -}; -> update count: 5 - -SELECT *, 0xFF, -0x1234567890abcd FROM TEST; -> ID X1 XT X_SM XB XD XD2 XR 255 -5124095575370701 -> ---- ----- ---- ---- ---- ----- ---- ---- --- ----------------- -> -1 FALSE -1 -1 -1 -1.00 -1.0 -1.0 255 -5124095575370701 -> 0 FALSE 0 0 0 0.00 0.0 0.0 255 -5124095575370701 -> 1 TRUE 1 1 1 1.00 1.0 1.0 255 -5124095575370701 -> 4 TRUE 4 4 4 4.00 4.0 4.0 255 -5124095575370701 -> null null null null null null null null 255 -5124095575370701 -> rows: 5 - -SELECT XD, CAST(XD AS DECIMAL(10,1)) D2DE, CAST(XD2 AS DECIMAL(4, 3)) DO2DE, CAST(XR AS DECIMAL(20,3)) R2DE FROM TEST; -> XD D2DE DO2DE R2DE -> ----- ---- ------ ------ -> -1.00 -1.0 -1.000 -1.000 -> 0.00 0.0 0.000 0.000 -> 1.00 1.0 1.000 1.000 -> 4.00 4.0 4.000 4.000 -> null null null null -> rows: 5 - -SELECT ID, CAST(XB AS DOUBLE) L2D, CAST(X_SM AS DOUBLE) S2D, CAST(XT AS DOUBLE) X2D FROM TEST; -> ID L2D S2D X2D -> ---- ---- ---- ---- -> -1 -1.0 -1.0 -1.0 -> 0 0.0 0.0 0.0 -> 1 1.0 1.0 1.0 -> 4 4.0 4.0 4.0 -> null null null null -> rows: 5 - -SELECT ID, CAST(XB AS REAL) L2D, CAST(X_SM AS REAL) S2D, CAST(XT AS REAL) T2R FROM TEST; -> ID L2D S2D T2R -> ---- ---- ---- ---- -> -1 -1.0 -1.0 -1.0 -> 0 0.0 0.0 0.0 -> 1 1.0 1.0 1.0 -> 4 4.0 4.0 4.0 -> null null null null -> rows: 5 - -SELECT ID, CAST(X_SM AS BIGINT) S2L, CAST(XT AS BIGINT) B2L, CAST(XD2 AS BIGINT) D2L, CAST(XR AS BIGINT) R2L FROM TEST; -> ID S2L B2L D2L R2L -> ---- ---- ---- ---- ---- -> -1 -1 -1 -1 -1 -> 0 0 0 0 0 -> 1 1 1 1 1 -> 4 4 4 4 4 -> null null null null null -> rows: 5 - -SELECT ID, CAST(XB AS INT) L2I, CAST(XD2 AS INT) D2I, CAST(XD2 AS SMALLINT) DO2I, CAST(XR AS SMALLINT) R2I FROM TEST; -> ID L2I D2I DO2I R2I -> ---- ---- ---- ---- ---- -> -1 -1 -1 -1 -1 -> 0 0 0 0 0 -> 1 1 1 1 1 -> 4 4 4 4 4 -> null null null null null -> rows: 5 - -SELECT ID, CAST(XD AS SMALLINT) D2S, CAST(XB AS SMALLINT) L2S, CAST(XT AS SMALLINT) B2S FROM TEST; -> ID D2S L2S B2S -> ---- ---- ---- ---- -> -1 -1 -1 -1 -> 0 0 0 0 -> 1 1 1 1 -> 4 4 4 4 -> null null null null -> rows: 5 - -SELECT ID, CAST(XD2 AS TINYINT) D2B, CAST(XD AS TINYINT) DE2B, CAST(XB AS TINYINT) L2B, CAST(X_SM AS TINYINT) S2B FROM TEST; -> ID D2B DE2B L2B S2B -> ---- ---- ---- ---- ---- -> -1 -1 -1 -1 -1 -> 0 0 0 0 0 -> 1 1 1 1 1 -> 4 4 4 4 4 -> null null null null null -> rows: 5 - -SELECT ID, CAST(XD2 AS BIT) D2B, CAST(XD AS BIT) DE2B, CAST(XB AS BIT) L2B, CAST(X_SM AS BIT) S2B FROM TEST; -> ID D2B DE2B L2B S2B -> ---- ----- ----- ----- ----- -> -1 TRUE TRUE TRUE TRUE -> 0 FALSE FALSE FALSE FALSE -> 1 TRUE TRUE TRUE TRUE -> 4 TRUE TRUE TRUE TRUE -> null null null null null -> rows: 5 - -SELECT CAST('TRUE' AS BIT) NT, CAST('1.0' AS BIT) N1, CAST('0.0' AS BIT) N0; -> NT N1 N0 -> ---- ---- ----- -> TRUE TRUE FALSE -> rows: 1 - -SELECT ID, ID+X1, ID+XT, ID+X_SM, ID+XB, ID+XD, ID+XD2, ID+XR FROM TEST; -> ID ID + X1 ID + XT ID + X_SM ID + XB ID + XD ID + XD2 ID + XR -> ---- ------- ------- --------- ------- ------- -------- ------- -> -1 -1 -2 -2 -2 -2.00 -2.0 -2.0 -> 0 0 0 0 0 0.00 0.0 0.0 -> 1 2 2 2 2 2.00 2.0 2.0 -> 4 5 8 8 8 8.00 8.0 8.0 -> null null null null null null null null -> rows: 5 - -SELECT ID, 10-X1, 10-XT, 10-X_SM, 10-XB, 10-XD, 10-XD2, 10-XR FROM TEST; -> ID 10 - X1 10 - XT 10 - X_SM 10 - XB 10 - XD 10 - XD2 10 - XR -> ---- ------- ------- --------- ------- ------- -------- ------- -> -1 10 11 11 11 11.00 11.0 11.0 -> 0 10 10 10 10 10.00 10.0 10.0 -> 1 9 9 9 9 9.00 9.0 9.0 -> 4 9 6 6 6 6.00 6.0 6.0 -> null null null null null null null null -> rows: 5 - -SELECT ID, 10*X1, 10*XT, 10*X_SM, 10*XB, 10*XD, 10*XD2, 10*XR FROM TEST; -> ID 10 * X1 10 * XT 10 * X_SM 10 * XB 10 * XD 10 * XD2 10 * XR -> ---- ------- ------- --------- ------- ------- -------- ------- -> -1 0 -10 -10 -10 -10.00 -10.0 -10.0 -> 0 0 0 0 0 0.00 0.0 0.0 -> 1 10 10 10 10 10.00 10.0 10.0 -> 4 10 40 40 40 40.00 40.0 40.0 -> null null null null null null null null -> rows: 5 - -SELECT ID, CAST(XT AS NUMBER(10,1)), -CAST(X_SM AS NUMBER(10,1)), CAST(XB AS NUMBER(10,1)), CAST(XD AS NUMBER(10,1)), -CAST(XD2 AS NUMBER(10,1)), CAST(XR AS NUMBER(10,1)) FROM TEST; -> ID CAST(XT AS DECIMAL(10, 1)) CAST(X_SM AS DECIMAL(10, 1)) CAST(XB AS DECIMAL(10, 1)) CAST(XD AS DECIMAL(10, 1)) CAST(XD2 AS DECIMAL(10, 1)) CAST(XR AS DECIMAL(10, 1)) -> ---- -------------------------- ---------------------------- -------------------------- -------------------------- --------------------------- -------------------------- -> -1 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -> 0 0.0 0.0 0.0 0.0 0.0 0.0 -> 1 1.0 1.0 1.0 1.0 1.0 1.0 -> 4 4.0 4.0 4.0 4.0 4.0 4.0 -> null null null null null null null -> rows: 5 - -SELECT ID, SIGN(XT), SIGN(X_SM), SIGN(XB), SIGN(XD), SIGN(XD2), SIGN(XR) FROM TEST; -> ID SIGN(XT) SIGN(X_SM) SIGN(XB) SIGN(XD) SIGN(XD2) SIGN(XR) -> ---- -------- ---------- -------- -------- --------- -------- -> -1 -1 -1 -1 -1 -1 -1 -> 0 0 0 0 0 0 0 -> 1 1 1 1 1 1 1 -> 4 1 1 1 1 1 1 -> null null null null null null null -> rows: 5 - -SELECT ID, XT-XT-XT, X_SM-X_SM-X_SM, XB-XB-XB, XD-XD-XD, XD2-XD2-XD2, XR-XR-XR FROM TEST; -> ID (XT - XT) - XT (X_SM - X_SM) - X_SM (XB - XB) - XB (XD - XD) - XD (XD2 - XD2) - XD2 (XR - XR) - XR -> ---- -------------- -------------------- -------------- -------------- ----------------- -------------- -> -1 1 1 1 1.00 1.0 1.0 -> 0 0 0 0 0.00 0.0 0.0 -> 1 -1 -1 -1 -1.00 -1.0 -1.0 -> 4 -4 -4 -4 -4.00 -4.0 -4.0 -> null null null null null null null -> rows: 5 - -SELECT ID, XT+XT, X_SM+X_SM, XB+XB, XD+XD, XD2+XD2, XR+XR FROM TEST; -> ID XT + XT X_SM + X_SM XB + XB XD + XD XD2 + XD2 XR + XR -> ---- ------- ----------- ------- ------- --------- ------- -> -1 -2 -2 -2 -2.00 -2.0 -2.0 -> 0 0 0 0 0.00 0.0 0.0 -> 1 2 2 2 2.00 2.0 2.0 -> 4 8 8 8 8.00 8.0 8.0 -> null null null null null null null -> rows: 5 - -SELECT ID, XT*XT, X_SM*X_SM, XB*XB, XD*XD, XD2*XD2, XR*XR FROM TEST; -> ID XT * XT X_SM * X_SM XB * XB XD * XD XD2 * XD2 XR * XR -> ---- ------- ----------- ------- ------- --------- ------- -> -1 1 1 1 1.0000 1.0 1.0 -> 0 0 0 0 0.0000 0.0 0.0 -> 1 1 1 1 1.0000 1.0 1.0 -> 4 16 16 16 16.0000 16.0 16.0 -> null null null null null null null -> rows: 5 - -SELECT 2/3 FROM TEST WHERE ID=1; -> 0 -> - -> 0 -> rows: 1 - -SELECT ID/ID FROM TEST; -> exception - -SELECT XT/XT FROM TEST; -> exception - -SELECT X_SM/X_SM FROM TEST; -> exception - -SELECT XB/XB FROM TEST; -> exception - -SELECT XD/XD FROM TEST; -> exception - -SELECT XD2/XD2 FROM TEST; -> exception - -SELECT XR/XR FROM TEST; -> exception - -SELECT ID++0, -X1, -XT, -X_SM, -XB, -XD, -XD2, -XR FROM TEST; -> ID + 0 - X1 - XT - X_SM - XB - XD - XD2 - XR -> ------ ----- ---- ------ ---- ----- ----- ---- -> -1 TRUE 1 1 1 1.00 1.0 1.0 -> 0 TRUE 0 0 0 0.00 0.0 0.0 -> 1 FALSE -1 -1 -1 -1.00 -1.0 -1.0 -> 4 FALSE -4 -4 -4 -4.00 -4.0 -4.0 -> null null null null null null null null -> rows: 5 - -SELECT ID, X1||'!', XT||'!', X_SM||'!', XB||'!', XD||'!', XD2||'!', XR||'!' FROM TEST; -> ID X1 || '!' XT || '!' X_SM || '!' XB || '!' XD || '!' XD2 || '!' XR || '!' -> ---- --------- --------- ----------- --------- --------- ---------- --------- -> -1 FALSE! -1! -1! -1! -1.00! -1.0! -1.0! -> 0 FALSE! 0! 0! 0! 0.00! 0.0! 0.0! -> 1 TRUE! 1! 1! 1! 1.00! 1.0! 1.0! -> 4 TRUE! 4! 4! 4! 4.00! 4.0! 4.0! -> null null null null null null null null -> rows: 5 - -DROP TABLE TEST; -> ok - ---- in ---------------------------------------------------------------------------------------------- -CREATE TABLE CUSTOMER(ID INT PRIMARY KEY, NAME VARCHAR(255)); -> ok - -CREATE TABLE INVOICE(ID INT, CUSTOMER_ID INT, PRIMARY KEY(CUSTOMER_ID, ID), VALUE DECIMAL(10,2)); -> ok - -INSERT INTO CUSTOMER VALUES(?, ?); -{ -1,Lehmann -2,Meier -3,Scott -4,NULL -}; -> update count: 4 - -INSERT INTO INVOICE VALUES(?, ?, ?); -{ -10,1,100.10 -11,1,10.01 -12,1,1.001 -20,2,22.2 -21,2,200.02 -}; -> update count: 5 - -SELECT * FROM CUSTOMER WHERE ID IN(1,2,4,-1); -> ID NAME -> -- ------- -> 1 Lehmann -> 2 Meier -> 4 null -> rows: 3 - -SELECT * FROM CUSTOMER WHERE ID NOT IN(3,4,5,'1'); -> ID NAME -> -- ----- -> 2 Meier -> rows: 1 - -SELECT * FROM CUSTOMER WHERE ID NOT IN(SELECT CUSTOMER_ID FROM INVOICE); -> ID NAME -> -- ----- -> 3 Scott -> 4 null -> rows: 2 - -SELECT * FROM INVOICE WHERE CUSTOMER_ID IN(SELECT C.ID FROM CUSTOMER C); -> ID CUSTOMER_ID VALUE -> -- ----------- ------ -> 10 1 100.10 -> 11 1 10.01 -> 12 1 1.00 -> 20 2 22.20 -> 21 2 200.02 -> rows: 5 - -SELECT * FROM CUSTOMER WHERE NAME IN('Lehmann', 20); -> ID NAME -> -- ------- -> 1 Lehmann -> rows: 1 - -SELECT * FROM CUSTOMER WHERE NAME NOT IN('Scott'); -> ID NAME -> -- ------- -> 1 Lehmann -> 2 Meier -> rows: 2 - -SELECT * FROM CUSTOMER WHERE NAME IN(SELECT NAME FROM CUSTOMER); -> ID NAME -> -- ------- -> 1 Lehmann -> 2 Meier -> 3 Scott -> rows: 3 - -SELECT * FROM CUSTOMER WHERE NAME NOT IN(SELECT NAME FROM CUSTOMER); -> ID NAME -> -- ---- -> rows: 0 - -SELECT * FROM CUSTOMER WHERE NAME = ANY(SELECT NAME FROM CUSTOMER); -> ID NAME -> -- ------- -> 1 Lehmann -> 2 Meier -> 3 Scott -> rows: 3 - -SELECT * FROM CUSTOMER WHERE NAME = ALL(SELECT NAME FROM CUSTOMER); -> ID NAME -> -- ---- -> rows: 0 - -SELECT * FROM CUSTOMER WHERE NAME > ALL(SELECT NAME FROM CUSTOMER); -> ID NAME -> -- ---- -> rows: 0 - -SELECT * FROM CUSTOMER WHERE NAME > ANY(SELECT NAME FROM CUSTOMER); -> ID NAME -> -- ----- -> 2 Meier -> 3 Scott -> rows: 2 - -SELECT * FROM CUSTOMER WHERE NAME < ANY(SELECT NAME FROM CUSTOMER); -> ID NAME -> -- ------- -> 1 Lehmann -> 2 Meier -> rows: 2 - -DROP TABLE INVOICE; -> ok - -DROP TABLE CUSTOMER; -> ok - ---- aggregates ---------------------------------------------------------------------------------------------- -drop table if exists t; -> ok - -create table t(x double precision, y double precision); -> ok - -create view s as -select stddev_pop(x) s_px, stddev_samp(x) s_sx, var_pop(x) v_px, var_samp(x) v_sx, -stddev_pop(y) s_py, stddev_samp(y) s_sy, var_pop(y) v_py, var_samp(y) v_sy from t; -> ok - -select * from s; -> S_PX S_SX V_PX V_SX S_PY S_SY V_PY V_SY -> ---- ---- ---- ---- ---- ---- ---- ---- -> null null null null null null null null -> rows: 1 - -select some(y>10), every(y>10), min(y), max(y) from t; -> BOOL_OR(Y > 10) BOOL_AND(Y > 10) MIN(Y) MAX(Y) -> --------------- ---------------- ------ ------ -> null null null null -> rows: 1 - -insert into t values(1000000004, 4); -> update count: 1 - -select * from s; -> S_PX S_SX V_PX V_SX S_PY S_SY V_PY V_SY -> ---- ---- ---- ---- ---- ---- ---- ---- -> 0.0 null 0.0 null 0.0 null 0.0 null -> rows: 1 - -insert into t values(1000000007, 7); -> update count: 1 - -select * from s; -> S_PX S_SX V_PX V_SX S_PY S_SY V_PY V_SY -> ---- ------------------ ---- ---- ---- ------------------ ---- ---- -> 1.5 2.1213203435596424 2.25 4.5 1.5 2.1213203435596424 2.25 4.5 -> rows: 1 - -insert into t values(1000000013, 13); -> update count: 1 - -select * from s; -> S_PX S_SX V_PX V_SX S_PY S_SY V_PY V_SY -> ------------------ ---------------- ---- ---- ------------------ ---------------- ---- ---- -> 3.7416573867739413 4.58257569495584 14.0 21.0 3.7416573867739413 4.58257569495584 14.0 21.0 -> rows: 1 - -insert into t values(1000000016, 16); -> update count: 1 - -select * from s; -> S_PX S_SX V_PX V_SX S_PY S_SY V_PY V_SY -> ----------------- ----------------- ---- ---- ----------------- ----------------- ---- ---- -> 4.743416490252569 5.477225575051661 22.5 30.0 4.743416490252569 5.477225575051661 22.5 30.0 -> rows: 1 - -insert into t values(1000000016, 16); -> update count: 1 - -select * from s; -> S_PX S_SX V_PX V_SX S_PY S_SY V_PY V_SY -> ----------------- ----------------- ------------------ ---- ----------------- ----------------- ------------------ ---- -> 4.874423042781576 5.449770637375485 23.759999999999998 29.7 4.874423042781576 5.449770637375485 23.759999999999998 29.7 -> rows: 1 - -select stddev_pop(distinct x) s_px, stddev_samp(distinct x) s_sx, var_pop(distinct x) v_px, var_samp(distinct x) v_sx, -stddev_pop(distinct y) s_py, stddev_samp(distinct y) s_sy, var_pop(distinct y) v_py, var_samp(distinct y) V_SY from t; -> S_PX S_SX V_PX V_SX S_PY S_SY V_PY V_SY -> ----------------- ----------------- ---- ---- ----------------- ----------------- ---- ---- -> 4.743416490252569 5.477225575051661 22.5 30.0 4.743416490252569 5.477225575051661 22.5 30.0 -> rows: 1 - -select some(y>10), every(y>10), min(y), max(y) from t; -> BOOL_OR(Y > 10) BOOL_AND(Y > 10) MIN(Y) MAX(Y) -> --------------- ---------------- ------ ------ -> TRUE FALSE 4.0 16.0 -> rows: 1 - -drop view s; -> ok - -drop table t; -> ok - -CREATE TABLE TEST(ID INT PRIMARY KEY, NAME VARCHAR(255), VALUE DECIMAL(10,2)); -> ok - -INSERT INTO TEST VALUES(?, ?, ?); -{ -1,Apples,1.20 -2,Oranges,2.05 -3,Cherries,5.10 -4,Apples,1.50 -5,Apples,1.10 -6,Oranges,1.80 -7,Bananas,2.50 -8,NULL,3.10 -9,NULL,-10.0 -}; -> update count: 9 - -SELECT IFNULL(NAME, '') || ': ' || GROUP_CONCAT(VALUE ORDER BY NAME, VALUE DESC SEPARATOR ', ') FROM TEST GROUP BY NAME; -> (IFNULL(NAME, '') || ': ') || GROUP_CONCAT(VALUE ORDER BY NAME, VALUE DESC SEPARATOR ', ') -> ------------------------------------------------------------------------------------------ -> Apples: 1.50, 1.20, 1.10 -> Oranges: 2.05, 1.80 -> Bananas: 2.50 -> Cherries: 5.10 -> : 3.10, -10.00 -> rows (ordered): 5 - -SELECT GROUP_CONCAT(ID ORDER BY ID) FROM TEST; -> GROUP_CONCAT(ID ORDER BY ID) -> ---------------------------- -> 1,2,3,4,5,6,7,8,9 -> rows (ordered): 1 - -SELECT DISTINCT NAME FROM TEST; -> NAME -> -------- -> Apples -> Bananas -> Cherries -> Oranges -> null -> rows: 5 - -SELECT DISTINCT NAME FROM TEST ORDER BY NAME DESC NULLS LAST; -> NAME -> -------- -> Oranges -> Cherries -> Bananas -> Apples -> null -> rows (ordered): 5 - -SELECT DISTINCT NAME FROM TEST ORDER BY NAME DESC NULLS LAST LIMIT 2 OFFSET 1; -> NAME -> -------- -> Cherries -> Bananas -> rows (ordered): 2 - -SELECT NAME, COUNT(*), SUM(VALUE), MAX(VALUE), MIN(VALUE), AVG(VALUE), COUNT(DISTINCT VALUE) FROM TEST GROUP BY NAME; -> NAME COUNT(*) SUM(VALUE) MAX(VALUE) MIN(VALUE) AVG(VALUE) COUNT(DISTINCT VALUE) -> -------- -------- ---------- ---------- ---------- ----------------------------- --------------------- -> Apples 3 3.80 1.50 1.10 1.266666666666666666666666667 3 -> Bananas 1 2.50 2.50 2.50 2.5 1 -> Cherries 1 5.10 5.10 5.10 5.1 1 -> Oranges 2 3.85 2.05 1.80 1.925 2 -> null 2 -6.90 3.10 -10.00 -3.45 2 -> rows: 5 - -SELECT NAME, MAX(VALUE), MIN(VALUE), MAX(VALUE+1)*MIN(VALUE+1) FROM TEST GROUP BY NAME; -> NAME MAX(VALUE) MIN(VALUE) MAX(VALUE + 1) * MIN(VALUE + 1) -> -------- ---------- ---------- ------------------------------- -> Apples 1.50 1.10 5.2500 -> Bananas 2.50 2.50 12.2500 -> Cherries 5.10 5.10 37.2100 -> Oranges 2.05 1.80 8.5400 -> null 3.10 -10.00 -36.9000 -> rows: 5 - -DROP TABLE TEST; -> ok - ---- order by ---------------------------------------------------------------------------------------------- -CREATE TABLE TEST(ID INT PRIMARY KEY, NAME VARCHAR(255)); -> ok - -CREATE UNIQUE INDEX IDXNAME ON TEST(NAME); -> ok - -INSERT INTO TEST VALUES(1, 'Hello'); -> update count: 1 - -INSERT INTO TEST VALUES(2, 'World'); -> update count: 1 - -INSERT INTO TEST VALUES(3, NULL); -> update count: 1 - -SELECT * FROM TEST ORDER BY NAME; -> ID NAME -> -- ----- -> 3 null -> 1 Hello -> 2 World -> rows (ordered): 3 - -SELECT * FROM TEST ORDER BY NAME DESC; -> ID NAME -> -- ----- -> 2 World -> 1 Hello -> 3 null -> rows (ordered): 3 - -SELECT * FROM TEST ORDER BY NAME NULLS FIRST; -> ID NAME -> -- ----- -> 3 null -> 1 Hello -> 2 World -> rows (ordered): 3 - -SELECT * FROM TEST ORDER BY NAME DESC NULLS FIRST; -> ID NAME -> -- ----- -> 3 null -> 2 World -> 1 Hello -> rows (ordered): 3 - -SELECT * FROM TEST ORDER BY NAME NULLS LAST; -> ID NAME -> -- ----- -> 1 Hello -> 2 World -> 3 null -> rows (ordered): 3 - -SELECT * FROM TEST ORDER BY NAME DESC NULLS LAST; -> ID NAME -> -- ----- -> 2 World -> 1 Hello -> 3 null -> rows (ordered): 3 - -SELECT ID, '=', NAME FROM TEST ORDER BY 2 FOR UPDATE; -> ID '=' NAME -> -- --- ----- -> 1 = Hello -> 2 = World -> 3 = null -> rows (ordered): 3 - -DROP TABLE TEST; -> ok - ---- having ---------------------------------------------------------------------------------------------- -CREATE TABLE TEST(ID INT PRIMARY KEY, NAME VARCHAR(255)); -> ok - -CREATE INDEX IDXNAME ON TEST(NAME); -> ok - -INSERT INTO TEST VALUES(1, 'Hello'); -> update count: 1 - -INSERT INTO TEST VALUES(2, 'Hello'); -> update count: 1 - -INSERT INTO TEST VALUES(3, 'World'); -> update count: 1 - -INSERT INTO TEST VALUES(4, 'World'); -> update count: 1 - -INSERT INTO TEST VALUES(5, 'Orange'); -> update count: 1 - -SELECT NAME, SUM(ID) FROM TEST GROUP BY NAME HAVING COUNT(*)>1 ORDER BY NAME; -> NAME SUM(ID) -> ----- ------- -> Hello 3 -> World 7 -> rows (ordered): 2 - -DROP INDEX IF EXISTS IDXNAME; -> ok - -DROP TABLE TEST; -> ok - ---- help ---------------------------------------------------------------------------------------------- -HELP ABCDE EF_GH; -> ID SECTION TOPIC SYNTAX TEXT -> -- ------- ----- ------ ---- -> rows: 0 - ---- sequence ---------------------------------------------------------------------------------------------- -CREATE CACHED TABLE TEST(ID INT PRIMARY KEY); -> ok - -CREATE CACHED TABLE IF NOT EXISTS TEST(ID INT PRIMARY KEY); -> ok - -CREATE SEQUENCE IF NOT EXISTS TEST_SEQ START WITH 10; -> ok - -CREATE SEQUENCE IF NOT EXISTS TEST_SEQ START WITH 20; -> ok - -INSERT INTO TEST VALUES(NEXT VALUE FOR TEST_SEQ); -> update count: 1 - -CALL CURRVAL('test_seq'); -> CURRVAL('test_seq') -> ------------------- -> 10 -> rows: 1 - -INSERT INTO TEST VALUES(NEXT VALUE FOR TEST_SEQ); -> update count: 1 - -CALL NEXT VALUE FOR TEST_SEQ; -> NEXT VALUE FOR PUBLIC.TEST_SEQ -> ------------------------------ -> 12 -> rows: 1 - -INSERT INTO TEST VALUES(NEXT VALUE FOR TEST_SEQ); -> update count: 1 - -SELECT * FROM TEST; -> ID -> -- -> 10 -> 11 -> 13 -> rows: 3 - -SELECT TOP 2 * FROM TEST; -> ID -> -- -> 10 -> 11 -> rows: 2 - -SELECT TOP 2 * FROM TEST ORDER BY ID DESC; -> ID -> -- -> 13 -> 11 -> rows (ordered): 2 - -ALTER SEQUENCE TEST_SEQ RESTART WITH 20 INCREMENT BY -1; -> ok - -INSERT INTO TEST VALUES(NEXT VALUE FOR TEST_SEQ); -> update count: 1 - -INSERT INTO TEST VALUES(NEXT VALUE FOR TEST_SEQ); -> update count: 1 - -SELECT * FROM TEST ORDER BY ID ASC; -> ID -> -- -> 10 -> 11 -> 13 -> 19 -> 20 -> rows (ordered): 5 - -CALL NEXTVAL('test_seq'); -> NEXTVAL('test_seq') -> ------------------- -> 18 -> rows: 1 - -DROP SEQUENCE IF EXISTS TEST_SEQ; -> ok - -DROP SEQUENCE IF EXISTS TEST_SEQ; -> ok - -CREATE SEQUENCE TEST_LONG START WITH 90123456789012345 INCREMENT BY -1; -> ok - -SET AUTOCOMMIT FALSE; -> ok - -CALL NEXT VALUE FOR TEST_LONG; -> NEXT VALUE FOR PUBLIC.TEST_LONG -> ------------------------------- -> 90123456789012345 -> rows: 1 - -CALL IDENTITY(); -> IDENTITY() -> ----------------- -> 90123456789012345 -> rows: 1 - -SELECT SEQUENCE_NAME, CURRENT_VALUE, INCREMENT FROM INFORMATION_SCHEMA.SEQUENCES; -> SEQUENCE_NAME CURRENT_VALUE INCREMENT -> ------------- ----------------- --------- -> TEST_LONG 90123456789012345 -1 -> rows: 1 - -SET AUTOCOMMIT TRUE; -> ok - -DROP SEQUENCE TEST_LONG; -> ok - -DROP TABLE TEST; -> ok - ---- call ---------------------------------------------------------------------------------------------- -CALL PI(); -> 3.141592653589793 -> ----------------- -> 3.141592653589793 -> rows: 1 - -CALL 1+1; -> 2 -> - -> 2 -> rows: 1 - ---- constraints ---------------------------------------------------------------------------------------------- -CREATE TABLE PARENT(A INT, B INT, PRIMARY KEY(A, B)); -> ok - -CREATE TABLE CHILD(ID INT PRIMARY KEY, PA INT, PB INT, CONSTRAINT AB FOREIGN KEY(PA, PB) REFERENCES PARENT(A, B)); -> ok - -SELECT * FROM INFORMATION_SCHEMA.CROSS_REFERENCES; -> PKTABLE_CATALOG PKTABLE_SCHEMA PKTABLE_NAME PKCOLUMN_NAME FKTABLE_CATALOG FKTABLE_SCHEMA FKTABLE_NAME FKCOLUMN_NAME ORDINAL_POSITION UPDATE_RULE DELETE_RULE FK_NAME PK_NAME DEFERRABILITY -> --------------- -------------- ------------ ------------- --------------- -------------- ------------ ------------- ---------------- ----------- ----------- ------- ------- ------------- -> SCRIPT PUBLIC PARENT A SCRIPT PUBLIC CHILD PA 1 1 1 AB null 7 -> SCRIPT PUBLIC PARENT B SCRIPT PUBLIC CHILD PB 2 1 1 AB null 7 -> rows: 2 - -DROP TABLE PARENT; -> ok - -DROP TABLE CHILD; -> ok - -drop table if exists test; -> ok - -create table test(id int primary key, parent int, foreign key(id) references test(parent)); -> ok - -insert into test values(1, 1); -> update count: 1 - -delete from test; -> update count: 1 - -drop table test; -> ok - -drop table if exists child; -> ok - -drop table if exists parent; -> ok - -create table child(a int, id int); -> ok - -create table parent(id int primary key); -> ok - -alter table child add foreign key(id) references parent; -> ok - -insert into parent values(1); -> update count: 1 - -delete from parent; -> update count: 1 - -drop table if exists child; -> ok - -drop table if exists parent; -> ok - -CREATE MEMORY TABLE PARENT(ID INT PRIMARY KEY); -> ok - -CREATE MEMORY TABLE CHILD(ID INT, PARENT_ID INT, FOREIGN KEY(PARENT_ID) REFERENCES PARENT); -> ok - -SCRIPT NOPASSWORDS NOSETTINGS; -> SCRIPT -> ------------------------------------------------------------------------------------------------------------------------ -> -- 0 +/- SELECT COUNT(*) FROM PUBLIC.CHILD; -> -- 0 +/- SELECT COUNT(*) FROM PUBLIC.PARENT; -> ALTER TABLE PUBLIC.CHILD ADD CONSTRAINT PUBLIC.CONSTRAINT_3 FOREIGN KEY(PARENT_ID) REFERENCES PUBLIC.PARENT(ID) NOCHECK; -> ALTER TABLE PUBLIC.PARENT ADD CONSTRAINT PUBLIC.CONSTRAINT_8 PRIMARY KEY(ID); -> CREATE MEMORY TABLE PUBLIC.CHILD( ID INT, PARENT_ID INT ); -> CREATE MEMORY TABLE PUBLIC.PARENT( ID INT NOT NULL ); -> CREATE USER IF NOT EXISTS SA PASSWORD '' ADMIN; -> rows: 7 - -DROP TABLE PARENT; -> ok - -DROP TABLE CHILD; -> ok - -CREATE TABLE TEST(ID INT, CONSTRAINT PK PRIMARY KEY(ID), NAME VARCHAR, PARENT INT, CONSTRAINT P FOREIGN KEY(PARENT) REFERENCES(ID)); -> ok - -ALTER TABLE TEST DROP PRIMARY KEY; -> exception - -ALTER TABLE TEST DROP CONSTRAINT PK; -> ok - -INSERT INTO TEST VALUES(1, 'Frank', 1); -> update count: 1 - -INSERT INTO TEST VALUES(2, 'Sue', 1); -> update count: 1 - -INSERT INTO TEST VALUES(3, 'Karin', 2); -> update count: 1 - -INSERT INTO TEST VALUES(4, 'Joe', 5); -> exception - -INSERT INTO TEST VALUES(4, 'Joe', 3); -> update count: 1 - -DROP TABLE TEST; -> ok - -CREATE MEMORY TABLE TEST(A_INT INT NOT NULL, B_INT INT NOT NULL, PRIMARY KEY(A_INT, B_INT)); -> ok - -ALTER TABLE TEST ADD CONSTRAINT A_UNIQUE UNIQUE(A_INT); -> ok - -ALTER TABLE TEST DROP PRIMARY KEY; -> ok - -ALTER TABLE TEST DROP PRIMARY KEY; -> exception - -ALTER TABLE TEST DROP CONSTRAINT A_UNIQUE; -> ok - -ALTER TABLE TEST ADD CONSTRAINT C1 FOREIGN KEY(A_INT) REFERENCES TEST(B_INT); -> ok - -SCRIPT NOPASSWORDS NOSETTINGS; -> SCRIPT -> ---------------------------------------------------------------------------------------------------------- -> -- 0 +/- SELECT COUNT(*) FROM PUBLIC.TEST; -> ALTER TABLE PUBLIC.TEST ADD CONSTRAINT PUBLIC.C1 FOREIGN KEY(A_INT) REFERENCES PUBLIC.TEST(B_INT) NOCHECK; -> CREATE MEMORY TABLE PUBLIC.TEST( A_INT INT NOT NULL, B_INT INT NOT NULL ); -> CREATE USER IF NOT EXISTS SA PASSWORD '' ADMIN; -> rows: 4 - -ALTER TABLE TEST DROP CONSTRAINT C1; -> ok - -ALTER TABLE TEST DROP CONSTRAINT C1; -> exception - -DROP TABLE TEST; -> ok - -CREATE MEMORY TABLE A_TEST(A_INT INT NOT NULL, A_VARCHAR VARCHAR(255) DEFAULT 'x', A_DATE DATE, A_DECIMAL DECIMAL(10,2)); -> ok - -ALTER TABLE A_TEST ADD PRIMARY KEY(A_INT); -> ok - -ALTER TABLE A_TEST ADD CONSTRAINT MIN_LENGTH CHECK LENGTH(A_VARCHAR)>1; -> ok - -ALTER TABLE A_TEST ADD CONSTRAINT DATE_UNIQUE UNIQUE(A_DATE); -> ok - -ALTER TABLE A_TEST ADD CONSTRAINT DATE_UNIQUE_2 UNIQUE(A_DATE); -> ok - -INSERT INTO A_TEST VALUES(NULL, NULL, NULL, NULL); -> exception - -INSERT INTO A_TEST VALUES(1, 'A', NULL, NULL); -> exception - -INSERT INTO A_TEST VALUES(1, 'AB', NULL, NULL); -> update count: 1 - -INSERT INTO A_TEST VALUES(1, 'AB', NULL, NULL); -> exception - -INSERT INTO A_TEST VALUES(2, 'AB', NULL, NULL); -> update count: 1 - -INSERT INTO A_TEST VALUES(3, 'AB', '2004-01-01', NULL); -> update count: 1 - -INSERT INTO A_TEST VALUES(4, 'AB', '2004-01-01', NULL); -> exception - -INSERT INTO A_TEST VALUES(5, 'ABC', '2004-01-02', NULL); -> update count: 1 - -CREATE MEMORY TABLE B_TEST(B_INT INT DEFAULT -1 NOT NULL , B_VARCHAR VARCHAR(255) DEFAULT NULL NULL, CONSTRAINT B_UNIQUE UNIQUE(B_INT)); -> ok - -ALTER TABLE B_TEST ADD CHECK LENGTH(B_VARCHAR)>1; -> ok - -ALTER TABLE B_TEST ADD CONSTRAINT C1 FOREIGN KEY(B_INT) REFERENCES A_TEST(A_INT) ON DELETE CASCADE ON UPDATE CASCADE; -> ok - -ALTER TABLE B_TEST ADD PRIMARY KEY(B_INT); -> ok - -INSERT INTO B_TEST VALUES(10, 'X'); -> exception - -INSERT INTO B_TEST VALUES(1, 'X'); -> exception - -INSERT INTO B_TEST VALUES(1, 'XX'); -> update count: 1 - -SELECT * FROM B_TEST; -> B_INT B_VARCHAR -> ----- --------- -> 1 XX -> rows: 1 - -UPDATE A_TEST SET A_INT = A_INT*10; -> update count: 4 - -SELECT * FROM B_TEST; -> B_INT B_VARCHAR -> ----- --------- -> 10 XX -> rows: 1 - -ALTER TABLE B_TEST DROP CONSTRAINT C1; -> ok - -ALTER TABLE B_TEST ADD CONSTRAINT C2 FOREIGN KEY(B_INT) REFERENCES A_TEST(A_INT) ON DELETE SET NULL ON UPDATE SET NULL; -> ok - -UPDATE A_TEST SET A_INT = A_INT*10; -> exception - -SELECT * FROM B_TEST; -> B_INT B_VARCHAR -> ----- --------- -> 10 XX -> rows: 1 - -ALTER TABLE B_TEST DROP CONSTRAINT C2; -> ok - -UPDATE B_TEST SET B_INT = 20; -> update count: 1 - -SELECT A_INT FROM A_TEST; -> A_INT -> ----- -> 10 -> 20 -> 30 -> 50 -> rows: 4 - -ALTER TABLE B_TEST ADD CONSTRAINT C3 FOREIGN KEY(B_INT) REFERENCES A_TEST(A_INT) ON DELETE SET DEFAULT ON UPDATE SET DEFAULT; -> ok - -UPDATE A_TEST SET A_INT = A_INT*10; -> update count: 4 - -SELECT * FROM B_TEST; -> B_INT B_VARCHAR -> ----- --------- -> -1 XX -> rows: 1 - -DELETE FROM A_TEST; -> update count: 4 - -SELECT * FROM B_TEST; -> B_INT B_VARCHAR -> ----- --------- -> -1 XX -> rows: 1 - -SCRIPT NOPASSWORDS NOSETTINGS; -> SCRIPT -> ---------------------------------------------------------------------------------------------------------------------------------------------------------- -> -- 0 +/- SELECT COUNT(*) FROM PUBLIC.A_TEST; -> -- 1 +/- SELECT COUNT(*) FROM PUBLIC.B_TEST; -> ALTER TABLE PUBLIC.A_TEST ADD CONSTRAINT PUBLIC.CONSTRAINT_7 PRIMARY KEY(A_INT); -> ALTER TABLE PUBLIC.A_TEST ADD CONSTRAINT PUBLIC.DATE_UNIQUE UNIQUE(A_DATE); -> ALTER TABLE PUBLIC.A_TEST ADD CONSTRAINT PUBLIC.DATE_UNIQUE_2 UNIQUE(A_DATE); -> ALTER TABLE PUBLIC.A_TEST ADD CONSTRAINT PUBLIC.MIN_LENGTH CHECK(LENGTH(A_VARCHAR) > 1) NOCHECK; -> ALTER TABLE PUBLIC.B_TEST ADD CONSTRAINT PUBLIC.B_UNIQUE UNIQUE(B_INT); -> ALTER TABLE PUBLIC.B_TEST ADD CONSTRAINT PUBLIC.C3 FOREIGN KEY(B_INT) REFERENCES PUBLIC.A_TEST(A_INT) ON DELETE SET DEFAULT ON UPDATE SET DEFAULT NOCHECK; -> ALTER TABLE PUBLIC.B_TEST ADD CONSTRAINT PUBLIC.CONSTRAINT_76 CHECK(LENGTH(B_VARCHAR) > 1) NOCHECK; -> ALTER TABLE PUBLIC.B_TEST ADD CONSTRAINT PUBLIC.CONSTRAINT_760 PRIMARY KEY(B_INT); -> CREATE MEMORY TABLE PUBLIC.A_TEST( A_INT INT NOT NULL, A_VARCHAR VARCHAR(255) DEFAULT 'x', A_DATE DATE, A_DECIMAL DECIMAL(10, 2) ); -> CREATE MEMORY TABLE PUBLIC.B_TEST( B_INT INT DEFAULT -1 NOT NULL, B_VARCHAR VARCHAR(255) DEFAULT NULL ); -> CREATE USER IF NOT EXISTS SA PASSWORD '' ADMIN; -> INSERT INTO PUBLIC.B_TEST(B_INT, B_VARCHAR) VALUES (-1, 'XX'); -> rows: 14 - -DROP TABLE A_TEST; -> ok - -DROP TABLE B_TEST; -> ok - -CREATE MEMORY TABLE FAMILY(ID INT, NAME VARCHAR(20)); -> ok - -CREATE INDEX FAMILY_ID_NAME ON FAMILY(ID, NAME); -> ok - -CREATE MEMORY TABLE PARENT(ID INT, FAMILY_ID INT, NAME VARCHAR(20)); -> ok - -ALTER TABLE PARENT ADD CONSTRAINT PARENT_FAMILY FOREIGN KEY(FAMILY_ID) -REFERENCES FAMILY(ID); -> ok - -CREATE MEMORY TABLE CHILD( -ID INT, -PARENTID INT, -FAMILY_ID INT, -UNIQUE(ID, PARENTID), -CONSTRAINT PARENT_CHILD FOREIGN KEY(PARENTID, FAMILY_ID) -REFERENCES PARENT(ID, FAMILY_ID) -ON UPDATE CASCADE -ON DELETE SET NULL, -NAME VARCHAR(20)); -> ok - -INSERT INTO FAMILY VALUES(1, 'Capone'); -> update count: 1 - -INSERT INTO CHILD VALUES(100, 1, 1, 'early'); -> exception - -INSERT INTO PARENT VALUES(1, 1, 'Sue'); -> update count: 1 - -INSERT INTO PARENT VALUES(2, 1, 'Joe'); -> update count: 1 - -INSERT INTO CHILD VALUES(100, 1, 1, 'Simon'); -> update count: 1 - -INSERT INTO CHILD VALUES(101, 1, 1, 'Sabine'); -> update count: 1 - -INSERT INTO CHILD VALUES(200, 2, 1, 'Jim'); -> update count: 1 - -INSERT INTO CHILD VALUES(201, 2, 1, 'Johann'); -> update count: 1 - -UPDATE PARENT SET ID=3 WHERE ID=1; -> update count: 1 - -SELECT * FROM CHILD; -> ID PARENTID FAMILY_ID NAME -> --- -------- --------- ------ -> 100 3 1 Simon -> 101 3 1 Sabine -> 200 2 1 Jim -> 201 2 1 Johann -> rows: 4 - -UPDATE CHILD SET PARENTID=-1 WHERE PARENTID IS NOT NULL; -> exception - -DELETE FROM PARENT WHERE ID=2; -> update count: 1 - -SELECT * FROM CHILD; -> ID PARENTID FAMILY_ID NAME -> --- -------- --------- ------ -> 100 3 1 Simon -> 101 3 1 Sabine -> 200 null null Jim -> 201 null null Johann -> rows: 4 - -SCRIPT SIMPLE NOPASSWORDS NOSETTINGS; -> SCRIPT -> ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -> -- 1 +/- SELECT COUNT(*) FROM PUBLIC.FAMILY; -> -- 1 +/- SELECT COUNT(*) FROM PUBLIC.PARENT; -> -- 4 +/- SELECT COUNT(*) FROM PUBLIC.CHILD; -> ALTER TABLE PUBLIC.CHILD ADD CONSTRAINT PUBLIC.CONSTRAINT_3 UNIQUE(ID, PARENTID); -> ALTER TABLE PUBLIC.CHILD ADD CONSTRAINT PUBLIC.PARENT_CHILD FOREIGN KEY(PARENTID, FAMILY_ID) REFERENCES PUBLIC.PARENT(ID, FAMILY_ID) ON DELETE SET NULL ON UPDATE CASCADE NOCHECK; -> ALTER TABLE PUBLIC.PARENT ADD CONSTRAINT PUBLIC.PARENT_FAMILY FOREIGN KEY(FAMILY_ID) REFERENCES PUBLIC.FAMILY(ID) NOCHECK; -> CREATE INDEX PUBLIC.FAMILY_ID_NAME ON PUBLIC.FAMILY(ID, NAME); -> CREATE MEMORY TABLE PUBLIC.CHILD( ID INT, PARENTID INT, FAMILY_ID INT, NAME VARCHAR(20) ); -> CREATE MEMORY TABLE PUBLIC.FAMILY( ID INT, NAME VARCHAR(20) ); -> CREATE MEMORY TABLE PUBLIC.PARENT( ID INT, FAMILY_ID INT, NAME VARCHAR(20) ); -> CREATE USER IF NOT EXISTS SA PASSWORD '' ADMIN; -> INSERT INTO PUBLIC.CHILD(ID, PARENTID, FAMILY_ID, NAME) VALUES(100, 3, 1, 'Simon'); -> INSERT INTO PUBLIC.CHILD(ID, PARENTID, FAMILY_ID, NAME) VALUES(101, 3, 1, 'Sabine'); -> INSERT INTO PUBLIC.CHILD(ID, PARENTID, FAMILY_ID, NAME) VALUES(200, NULL, NULL, 'Jim'); -> INSERT INTO PUBLIC.CHILD(ID, PARENTID, FAMILY_ID, NAME) VALUES(201, NULL, NULL, 'Johann'); -> INSERT INTO PUBLIC.FAMILY(ID, NAME) VALUES(1, 'Capone'); -> INSERT INTO PUBLIC.PARENT(ID, FAMILY_ID, NAME) VALUES(3, 1, 'Sue'); -> rows: 17 - -ALTER TABLE CHILD DROP CONSTRAINT PARENT_CHILD; -> ok - -SCRIPT SIMPLE NOPASSWORDS NOSETTINGS; -> SCRIPT -> -------------------------------------------------------------------------------------------------------------------------- -> -- 1 +/- SELECT COUNT(*) FROM PUBLIC.FAMILY; -> -- 1 +/- SELECT COUNT(*) FROM PUBLIC.PARENT; -> -- 4 +/- SELECT COUNT(*) FROM PUBLIC.CHILD; -> ALTER TABLE PUBLIC.CHILD ADD CONSTRAINT PUBLIC.CONSTRAINT_3 UNIQUE(ID, PARENTID); -> ALTER TABLE PUBLIC.PARENT ADD CONSTRAINT PUBLIC.PARENT_FAMILY FOREIGN KEY(FAMILY_ID) REFERENCES PUBLIC.FAMILY(ID) NOCHECK; -> CREATE INDEX PUBLIC.FAMILY_ID_NAME ON PUBLIC.FAMILY(ID, NAME); -> CREATE MEMORY TABLE PUBLIC.CHILD( ID INT, PARENTID INT, FAMILY_ID INT, NAME VARCHAR(20) ); -> CREATE MEMORY TABLE PUBLIC.FAMILY( ID INT, NAME VARCHAR(20) ); -> CREATE MEMORY TABLE PUBLIC.PARENT( ID INT, FAMILY_ID INT, NAME VARCHAR(20) ); -> CREATE USER IF NOT EXISTS SA PASSWORD '' ADMIN; -> INSERT INTO PUBLIC.CHILD(ID, PARENTID, FAMILY_ID, NAME) VALUES(100, 3, 1, 'Simon'); -> INSERT INTO PUBLIC.CHILD(ID, PARENTID, FAMILY_ID, NAME) VALUES(101, 3, 1, 'Sabine'); -> INSERT INTO PUBLIC.CHILD(ID, PARENTID, FAMILY_ID, NAME) VALUES(200, NULL, NULL, 'Jim'); -> INSERT INTO PUBLIC.CHILD(ID, PARENTID, FAMILY_ID, NAME) VALUES(201, NULL, NULL, 'Johann'); -> INSERT INTO PUBLIC.FAMILY(ID, NAME) VALUES(1, 'Capone'); -> INSERT INTO PUBLIC.PARENT(ID, FAMILY_ID, NAME) VALUES(3, 1, 'Sue'); -> rows: 16 - -DELETE FROM PARENT; -> update count: 1 - -SELECT * FROM CHILD; -> ID PARENTID FAMILY_ID NAME -> --- -------- --------- ------ -> 100 3 1 Simon -> 101 3 1 Sabine -> 200 null null Jim -> 201 null null Johann -> rows: 4 - -DROP TABLE PARENT; -> ok - -DROP TABLE CHILD; -> ok - -DROP TABLE FAMILY; -> ok - -CREATE TABLE INVOICE(CUSTOMER_ID INT, ID INT, TOTAL_AMOUNT DECIMAL(10,2), PRIMARY KEY(CUSTOMER_ID, ID)); -> ok - -CREATE TABLE INVOICE_LINE(CUSTOMER_ID INT, INVOICE_ID INT, LINE_ID INT, TEXT VARCHAR, AMOUNT DECIMAL(10,2)); -> ok - -CREATE INDEX ON INVOICE_LINE(CUSTOMER_ID); -> ok - -ALTER TABLE INVOICE_LINE ADD FOREIGN KEY(CUSTOMER_ID, INVOICE_ID) REFERENCES INVOICE(CUSTOMER_ID, ID) ON DELETE CASCADE; -> ok - -INSERT INTO INVOICE VALUES(1, 100, NULL), (1, 101, NULL); -> update count: 2 - -INSERT INTO INVOICE_LINE VALUES(1, 100, 10, 'Apples', 20.35), (1, 100, 20, 'Paper', 10.05), (1, 101, 10, 'Pencil', 1.10), (1, 101, 20, 'Chair', 540.40); -> update count: 4 - -INSERT INTO INVOICE_LINE VALUES(1, 102, 20, 'Nothing', 30.00); -> exception - -DELETE FROM INVOICE WHERE ID = 100; -> update count: 1 - -SELECT * FROM INVOICE_LINE; -> CUSTOMER_ID INVOICE_ID LINE_ID TEXT AMOUNT -> ----------- ---------- ------- ------ ------ -> 1 101 10 Pencil 1.10 -> 1 101 20 Chair 540.40 -> rows: 2 - -DROP TABLE INVOICE; -> ok - -DROP TABLE INVOICE_LINE; -> ok - -CREATE MEMORY TABLE TEST(A INT, B INT, FOREIGN KEY (B) REFERENCES(A) ON UPDATE RESTRICT ON DELETE NO ACTION); -> ok - -SCRIPT NOPASSWORDS NOSETTINGS; -> SCRIPT -> ------------------------------------------------------------------------------------------------------------ -> -- 0 +/- SELECT COUNT(*) FROM PUBLIC.TEST; -> ALTER TABLE PUBLIC.TEST ADD CONSTRAINT PUBLIC.CONSTRAINT_2 FOREIGN KEY(B) REFERENCES PUBLIC.TEST(A) NOCHECK; -> CREATE MEMORY TABLE PUBLIC.TEST( A INT, B INT ); -> CREATE USER IF NOT EXISTS SA PASSWORD '' ADMIN; -> rows: 4 - -DROP TABLE TEST; -> ok - ---- users ---------------------------------------------------------------------------------------------- -CREATE USER TEST PASSWORD 'abc'; -> ok - -CREATE USER TEST_ADMIN_X PASSWORD 'def' ADMIN; -> ok - -ALTER USER TEST_ADMIN_X RENAME TO TEST_ADMIN; -> ok - -ALTER USER TEST_ADMIN ADMIN TRUE; -> ok - -CREATE USER TEST2 PASSWORD '123' ADMIN; -> ok - -ALTER USER TEST2 SET PASSWORD 'abc'; -> ok - -ALTER USER TEST2 ADMIN FALSE; -> ok - -CREATE MEMORY TABLE TEST(ID INT PRIMARY KEY, NAME VARCHAR(255)); -> ok - -CREATE MEMORY TABLE TEST2_X(ID INT); -> ok - -CREATE INDEX IDX_ID ON TEST2_X(ID); -> ok - -ALTER TABLE TEST2_X RENAME TO TEST2; -> ok - -ALTER INDEX IDX_ID RENAME TO IDX_ID2; -> ok - -SCRIPT NOPASSWORDS NOSETTINGS; -> SCRIPT -> ------------------------------------------------------------------------------ -> -- 0 +/- SELECT COUNT(*) FROM PUBLIC.TEST2; -> -- 0 +/- SELECT COUNT(*) FROM PUBLIC.TEST; -> ALTER TABLE PUBLIC.TEST ADD CONSTRAINT PUBLIC.CONSTRAINT_2 PRIMARY KEY(ID); -> CREATE INDEX PUBLIC.IDX_ID2 ON PUBLIC.TEST2(ID); -> CREATE MEMORY TABLE PUBLIC.TEST( ID INT NOT NULL, NAME VARCHAR(255) ); -> CREATE MEMORY TABLE PUBLIC.TEST2( ID INT ); -> CREATE USER IF NOT EXISTS SA PASSWORD '' ADMIN; -> CREATE USER IF NOT EXISTS TEST PASSWORD ''; -> CREATE USER IF NOT EXISTS TEST2 PASSWORD ''; -> CREATE USER IF NOT EXISTS TEST_ADMIN PASSWORD '' ADMIN; -> rows: 10 - -SELECT NAME, ADMIN FROM INFORMATION_SCHEMA.USERS; -> NAME ADMIN -> ---------- ----- -> SA true -> TEST false -> TEST2 false -> TEST_ADMIN true -> rows: 4 - -DROP TABLE TEST2; -> ok - -DROP TABLE TEST; -> ok - -DROP USER TEST; -> ok - -DROP USER IF EXISTS TEST; -> ok - -DROP USER IF EXISTS TEST2; -> ok - -DROP USER TEST_ADMIN; -> ok - -SET AUTOCOMMIT FALSE; -> ok - -SET SALT '' HASH ''; -> ok - -CREATE USER SECURE SALT '001122' HASH '1122334455'; -> ok - -ALTER USER SECURE SET SALT '112233' HASH '2233445566'; -> ok - -SCRIPT NOSETTINGS; -> SCRIPT -> ----------------------------------------------------------------- -> CREATE USER IF NOT EXISTS SA SALT '' HASH '' ADMIN; -> CREATE USER IF NOT EXISTS SECURE SALT '112233' HASH '2233445566'; -> rows: 2 - -SET PASSWORD '123'; -> ok - -SET AUTOCOMMIT TRUE; -> ok - -DROP USER SECURE; -> ok - ---- functions ---------------------------------------------------------------------------------------------- -CALL FORMATDATETIME(PARSEDATETIME('2001-02-03 04:05:06 GMT', 'yyyy-MM-dd HH:mm:ss z', 'en', 'GMT'), 'EEE, d MMM yyyy HH:mm:ss z', 'en', 'GMT'); -> 'Sat, 3 Feb 2001 04:05:06 GMT' -> ------------------------------ -> Sat, 3 Feb 2001 04:05:06 GMT -> rows: 1 - -CALL FORMATDATETIME(TIMESTAMP '2001-02-03 04:05:06', 'yyyy-MM-dd HH:mm:ss'); -> '2001-02-03 04:05:06' -> --------------------- -> 2001-02-03 04:05:06 -> rows: 1 - -CALL FORMATDATETIME(TIMESTAMP '2001-02-03 04:05:06', 'MM/dd/yyyy HH:mm:ss'); -> '02/03/2001 04:05:06' -> --------------------- -> 02/03/2001 04:05:06 -> rows: 1 - -CALL FORMATDATETIME(TIMESTAMP '2001-02-03 04:05:06', 'd. MMMM yyyy', 'de'); -> '3. Februar 2001' -> ----------------- -> 3. Februar 2001 -> rows: 1 - -CALL FORMATDATETIME(PARSEDATETIME('Sat, 3 Feb 2001 04:05:06 GMT', 'EEE, d MMM yyyy HH:mm:ss z', 'en', 'GMT'), 'yyyy-MM-dd HH:mm:ss', 'en', 'GMT'); -> '2001-02-03 04:05:06' -> --------------------- -> 2001-02-03 04:05:06 -> rows: 1 - -CALL PARSEDATETIME('3. Februar 2001', 'd. MMMM yyyy', 'de'); -> TIMESTAMP '2001-02-03 00:00:00.0' -> --------------------------------- -> 2001-02-03 00:00:00.0 -> rows: 1 - -CALL PARSEDATETIME('02/03/2001 04:05:06', 'MM/dd/yyyy HH:mm:ss'); -> TIMESTAMP '2001-02-03 04:05:06.0' -> --------------------------------- -> 2001-02-03 04:05:06.0 -> rows: 1 - -CALL XMLNODE('a', XMLATTR('href', 'http://h2database.com')); -> STRINGDECODE('\n') -> ----------------------------------------------------- -> -> rows: 1 - -CALL XMLNODE('br'); -> STRINGDECODE('
    \n') -> ----------------------- ->
    -> rows: 1 - -CALL XMLNODE('p', null, 'Hello World'); -> STRINGDECODE('

    Hello World

    \n') -> ------------------------------------ ->

    Hello World

    -> rows: 1 - -CALL XMLCOMMENT('Test'); -> STRINGDECODE('\n') -> ------------------------------- -> -> rows: 1 - -CALL XMLCOMMENT('--- test ---'); -> STRINGDECODE('\n') -> ------------------------------------------- -> -> rows: 1 - -CALL XMLCDATA(''); -> ']]>' -> -------------------------- -> ]]> -> rows: 1 - -CALL XMLCDATA('special text ]]>'); -> 'special text ]]>' -> --------------------- -> special text ]]> -> rows: 1 - -CALL XMLSTARTDOC(); -> STRINGDECODE('\n') -> ----------------------------------------- -> -> rows: 1 - -CALL XMLTEXT('test'); -> 'test' -> ------ -> test -> rows: 1 - -CALL XMLTEXT(''); -> '<test>' -> -------------- -> <test> -> rows: 1 - -create memory table test(id int primary key, name varchar(255)); -> ok - -INSERT INTO TEST VALUES(2, STRINGDECODE('abcsond\344rzeich\344 ') || char(22222) || STRINGDECODE(' \366\344\374\326\304\334\351\350\340\361!')); -> update count: 1 - -script nopasswords nosettings; -> SCRIPT -> ------------------------------------------------------------------------------------------------------------------------------------------------------------- -> -- 1 +/- SELECT COUNT(*) FROM PUBLIC.TEST; -> ALTER TABLE PUBLIC.TEST ADD CONSTRAINT PUBLIC.CONSTRAINT_2 PRIMARY KEY(ID); -> CREATE MEMORY TABLE PUBLIC.TEST( ID INT NOT NULL, NAME VARCHAR(255) ); -> CREATE USER IF NOT EXISTS SA PASSWORD '' ADMIN; -> INSERT INTO PUBLIC.TEST(ID, NAME) VALUES (2, STRINGDECODE('abcsond\u00e4rzeich\u00e4 \u56ce \u00f6\u00e4\u00fc\u00d6\u00c4\u00dc\u00e9\u00e8\u00e0\u00f1!')); -> rows: 5 - -call STRINGENCODE(STRINGDECODE('abcsond\344rzeich\344 \u56ce \366\344\374\326\304\334\351\350\340\361!')); -> 'abcsond\u00e4rzeich\u00e4 \u56ce \u00f6\u00e4\u00fc\u00d6\u00c4\u00dc\u00e9\u00e8\u00e0\u00f1!' -> ------------------------------------------------------------------------------------------------ -> abcsond\u00e4rzeich\u00e4 \u56ce \u00f6\u00e4\u00fc\u00d6\u00c4\u00dc\u00e9\u00e8\u00e0\u00f1! -> rows: 1 - -delete from test; -> update count: 1 - -insert into test values(1, 'Hello'); -> update count: 1 - -select abs(-1) r1, abs(id) r1b from test; -> R1 R1B -> -- --- -> 1 1 -> rows: 1 - -select abs(sum(id)) r1 from test; -> R1 -> -- -> 1 -> rows: 1 - -select abs(null) vn, abs(-1) r1, abs(1) r2, abs(0) r3, abs(-0.1) r4, abs(0.1) r5 from test; -> VN R1 R2 R3 R4 R5 -> ---- -- -- -- --- --- -> null 1 1 0 0.1 0.1 -> rows: 1 - -select acos(null) vn, acos(-1) r1 from test; -> VN R1 -> ---- ----------------- -> null 3.141592653589793 -> rows: 1 - -select asin(null) vn, asin(-1) r1 from test; -> VN R1 -> ---- ------------------- -> null -1.5707963267948966 -> rows: 1 - -select atan(null) vn, atan(-1) r1 from test; -> VN R1 -> ---- ------------------- -> null -0.7853981633974483 -> rows: 1 - -select cos(null) vn, cos(-1) r1 from test; -> VN R1 -> ---- ------------------ -> null 0.5403023058681398 -> rows: 1 - -select cot(null) vn, cot(-1) r1 from test; -> VN R1 -> ---- ------------------- -> null -0.6420926159343306 -> rows: 1 - -select sin(null) vn, sin(-1) r1 from test; -> VN R1 -> ---- ------------------- -> null -0.8414709848078965 -> rows: 1 - -select tan(null) vn, tan(-1) r1 from test; -> VN R1 -> ---- ------------------- -> null -1.5574077246549023 -> rows: 1 - -select atan2(null, null) vn, atan2(10, 1) r1 from test; -> VN R1 -> ---- ------------------ -> null 1.4711276743037347 -> rows: 1 - -select bitand(null, 1) vn, bitand(1, null) vn1, bitand(null, null) vn2, bitand(3, 6) e2 from test; -> VN VN1 VN2 E2 -> ---- ---- ---- -- -> null null null 2 -> rows: 1 - -select bitor(null, 1) vn, bitor(1, null) vn1, bitor(null, null) vn2, bitor(3, 6) e7 from test; -> VN VN1 VN2 E7 -> ---- ---- ---- -- -> null null null 7 -> rows: 1 - -select bitxor(null, 1) vn, bitxor(1, null) vn1, bitxor(null, null) vn2, bitxor(3, 6) e5 from test; -> VN VN1 VN2 E5 -> ---- ---- ---- -- -> null null null 5 -> rows: 1 - -select mod(null, 1) vn, mod(1, null) vn1, mod(null, null) vn2, mod(10, 2) e1 from test; -> VN VN1 VN2 E1 -> ---- ---- ---- -- -> null null null 0 -> rows: 1 - -select ceiling(null) vn, ceiling(1) v1, ceiling(1.1) v2, ceiling(-1.1) v3, ceiling(1.9) v4, ceiling(-1.9) v5 from test; -> VN V1 V2 V3 V4 V5 -> ---- --- --- ---- --- ---- -> null 1.0 2.0 -1.0 2.0 -1.0 -> rows: 1 - -select floor(null) vn, floor(1) v1, floor(1.1) v2, floor(-1.1) v3, floor(1.9) v4, floor(-1.9) v5 from test; -> VN V1 V2 V3 V4 V5 -> ---- --- --- ---- --- ---- -> null 1.0 1.0 -2.0 1.0 -2.0 -> rows: 1 - -select log(null) vn, log(1) v1, log(1.1) v2, log(-1.1) v3, log(1.9) v4, log(-1.9) v5 from test; -> VN V1 V2 V3 V4 V5 -> ---- --- ------------------- --- ------------------ --- -> null 0.0 0.09531017980432493 NaN 0.6418538861723947 NaN -> rows: 1 - -select log10(null) vn, log10(0) v1, log10(10) v2, log10(0.0001) v3, log10(1000000) v4, log10(1) v5 from test; -> VN V1 V2 V3 V4 V5 -> ---- --------- --- ---- --- --- -> null -Infinity 1.0 -4.0 6.0 0.0 -> rows: 1 - -select log(null) vn, log(1) v1, log(1.1) v2, log(-1.1) v3, log(1.9) v4, log(-1.9) v5 from test; -> VN V1 V2 V3 V4 V5 -> ---- --- ------------------- --- ------------------ --- -> null 0.0 0.09531017980432493 NaN 0.6418538861723947 NaN -> rows: 1 - -select degrees(null) vn, degrees(1) v1, degrees(1.1) v2, degrees(-1.1) v3, degrees(1.9) v4, degrees(-1.9) v5 from test; -> VN V1 V2 V3 V4 V5 -> ---- ----------------- ----------------- ------------------ ------------------ ------------------- -> null 57.29577951308232 63.02535746439057 -63.02535746439057 108.86198107485642 -108.86198107485642 -> rows: 1 - -select exp(null) vn, exp(1) v1, exp(1.1) v2, exp(-1.1) v3, exp(1.9) v4, exp(-1.9) v5 from test; -> VN V1 V2 V3 V4 V5 -> ---- ------------------ ------------------ ------------------ ------------------ ------------------- -> null 2.7182818284590455 3.0041660239464334 0.3328710836980795 6.6858944422792685 0.14956861922263506 -> rows: 1 - -select radians(null) vn, radians(1) v1, radians(1.1) v2, radians(-1.1) v3, radians(1.9) v4, radians(-1.9) v5 from test; -> VN V1 V2 V3 V4 V5 -> ---- -------------------- -------------------- --------------------- ------------------- -------------------- -> null 0.017453292519943295 0.019198621771937624 -0.019198621771937624 0.03316125578789226 -0.03316125578789226 -> rows: 1 - -select sqrt(null) vn, sqrt(0) e0, sqrt(1) e1, sqrt(4) e2, sqrt(100) e10, sqrt(0.25) e05 from test; -> VN E0 E1 E2 E10 E05 -> ---- --- --- --- ---- --- -> null 0.0 1.0 2.0 10.0 0.5 -> rows: 1 - -select pi() pi from test; -> PI -> ----------------- -> 3.141592653589793 -> rows: 1 - -select power(null, null) en, power(2, 3) e8, power(16, 0.5) e4 from test; -> EN E8 E4 -> ---- --- --- -> null 8.0 4.0 -> rows: 1 - -SET AUTOCOMMIT FALSE; -> ok - -select rand(1) e from test; -> E -> ------------------ -> 0.7308781907032909 -> rows: 1 - -select rand() e from test; -> E -> ------------------- -> 0.41008081149220166 -> rows: 1 - -SET AUTOCOMMIT TRUE; -> ok - -select round(null, null) en, round(10.49, 0) e10, round(10.05, 1) e101 from test; -> EN E10 E101 -> ---- ---- ---- -> null 10.0 10.1 -> rows: 1 - -select roundmagic(null) en, roundmagic(cast(3.11 as double) - 3.1) e001, roundmagic(3.11-3.1-0.01) e000, roundmagic(2000000000000) e20x from test; -> EN E001 E000 E20X -> ---- ---- ---- ------ -> null 0.01 0.0 2.0E12 -> rows: 1 - -select sign(null) en, sign(10) e1, sign(0) e0, sign(-0.1) em1 from test; -> EN E1 E0 EM1 -> ---- -- -- --- -> null 1 0 -1 -> rows: 1 - -select truncate(null, null) en, truncate(1.99, 0) e1, truncate(-10.9, 0) em10 from test; -> EN E1 EM10 -> ---- --- ----- -> null 1.0 -10.0 -> rows: 1 - -select ascii(null) en, ascii('') en, ascii('Abc') e65 from test; -> EN EN E65 -> ---- ---- --- -> null null 65 -> rows: 1 - -select bit_length(null) en, bit_length('') e0, bit_length('ab') e32 from test; -> EN E0 E32 -> ---- -- --- -> null 0 32 -> rows: 1 - -select length(null) en, length('') e0, length('ab') e2 from test; -> EN E0 E2 -> ---- -- -- -> null 0 2 -> rows: 1 - -select char_length(null) en, char_length('') e0, char_length('ab') e2 from test; -> EN E0 E2 -> ---- -- -- -> null 0 2 -> rows: 1 - -select character_length(null) en, character_length('') e0, character_length('ab') e2 from test; -> EN E0 E2 -> ---- -- -- -> null 0 2 -> rows: 1 - -select octet_length(null) en, octet_length('') e0, octet_length('ab') e4 from test; -> EN E0 E4 -> ---- -- -- -> null 0 4 -> rows: 1 - -select char(null) en, char(65) ea from test; -> EN EA -> ---- -- -> null A -> rows: 1 - -select concat(null, null) en, concat(null, 'a') ea, concat('b', null) eb, concat('ab', 'c') abc from test; -> EN EA EB ABC -> ---- -- -- --- -> null a b abc -> rows: 1 - -SELECT CONCAT('a', 'b', 'c', 'd') AS test; -> TEST -> ---- -> abcd -> rows: 1 - -select difference(null, null) en, difference('a', null) en1, difference(null, 'a') en2 from test; -> EN EN1 EN2 -> ---- ---- ---- -> null null null -> rows: 1 - -select difference('abc', 'abc') e0, difference('Thomas', 'Tom') e1 from test; -> E0 E1 -> -- -- -> 4 3 -> rows: 1 - -select hextoraw(null) en, rawtohex(null) en1, hextoraw(rawtohex('abc')) abc from test; -> EN EN1 ABC -> ---- ---- --- -> null null abc -> rows: 1 - -select insert(null, null, null, null) en, insert('Rund', 1, 0, 'o') e_round, insert(null, 1, 1, 'a') ea from test; -> EN E_ROUND EA -> ---- ------- -- -> null Rund a -> rows: 1 - -select insert('World', 2, 4, 'e') welt, insert('Hello', 2, 1, 'a') hallo from test; -> WELT HALLO -> ---- ----- -> We Hallo -> rows: 1 - -select lcase(null) en, lcase('Hello') hello, lcase('ABC') abc from test; -> EN HELLO ABC -> ---- ----- --- -> null hello abc -> rows: 1 - -select lower(null) en, lower('Hello') hello, lower('ABC') abc from test; -> EN HELLO ABC -> ---- ----- --- -> null hello abc -> rows: 1 - -select ucase(null) en, ucase('Hello') hello, ucase('ABC') abc from test; -> EN HELLO ABC -> ---- ----- --- -> null HELLO ABC -> rows: 1 - -select upper(null) en, upper('Hello') hello, upper('ABC') abc from test; -> EN HELLO ABC -> ---- ----- --- -> null HELLO ABC -> rows: 1 - -select left(null, 10) en, left('abc', null) en2, left('boat', 2) e_bo, left('', 1) ee, left('a', -1) ee2 from test; -> EN EN2 E_BO EE EE2 -> ---- ---- ---- -- --- -> null null bo -> rows: 1 - -select right(null, 10) en, right('abc', null) en2, right('boat-trip', 2) e_ip, right('', 1) ee, right('a', -1) ee2 from test; -> EN EN2 E_IP EE EE2 -> ---- ---- ---- -- --- -> null null ip -> rows: 1 - -select locate(null, null) en, locate(null, null, null) en1 from test; -> EN EN1 -> ---- ---- -> null null -> rows: 1 - -select locate('World', 'Hello World') e7, locate('hi', 'abchihihi', 2) e3 from test; -> E7 E3 -> -- -- -> 7 4 -> rows: 1 - -select instr('Hello World', 'World') e7, instr('abchihihi', 'hi', 2) e3, instr('abcooo', 'o') e2 from test; -> E7 E3 E2 -> -- -- -- -> 7 4 4 -> rows: 1 - -select position(null, null) en, position(null, 'abc') en1, position('World', 'Hello World') e7, position('hi', 'abchihihi') e1 from test; -> EN EN1 E7 E1 -> ---- ---- -- -- -> null null 7 4 -> rows: 1 - -select ltrim(null) en, '>' || ltrim('a') || '<' ea, '>' || ltrim(' a ') || '<' e_as from test; -> EN EA E_AS -> ---- --- ---- -> null >a< >a < -> rows: 1 - -select TRIM(BOTH '_' FROM '__A__') A, TRIM(LEADING FROM ' B ') BS, TRIM(TRAILING 'x' FROM 'xAx') XA from test; -> A BS XA -> - ----- -- -> A B xA -> rows: 1 - -select rtrim(null) en, '>' || rtrim('a') || '<' ea, '>' || rtrim(' a ') || '<' es from test; -> EN EA ES -> ---- --- ---- -> null >a< > a< -> rows: 1 - -select repeat(null, null) en, repeat('Ho', 2) abcehoho , repeat('abc', 0) ee from test; -> EN ABCEHOHO EE -> ---- -------- -- -> null HoHo -> rows: 1 - -select replace(null, null) en, replace(null, null, null) en1 from test; -> EN EN1 -> ---- ---- -> null null -> rows: 1 - -select replace('abchihihi', 'i', 'o') abcehohoho, replace('that is tom', 'i') abcethstom from test; -> ABCEHOHOHO ABCETHSTOM -> ---------- ---------- -> abchohoho that s tom -> rows: 1 - -select soundex(null) en, soundex('tom') et from test; -> EN ET -> ---- ---- -> null t500 -> rows: 1 - -select -soundex('Washington') W252, soundex('Lee') L000, -soundex('Gutierrez') G362, soundex('Pfister') P236, -soundex('Jackson') J250, soundex('Tymczak') T522, -soundex('VanDeusen') V532, soundex('Ashcraft') A261 from test; -> W252 L000 G362 P236 J250 T522 V532 A261 -> ---- ---- ---- ---- ---- ---- ---- ---- -> W252 L000 G362 P236 J250 T522 V532 A261 -> rows: 1 - -select space(null) en, '>' || space(1) || '<' es, '>' || space(3) || '<' e2 from test; -> EN ES E2 -> ---- --- ----- -> null > < > < -> rows: 1 - -select substr(null, null) en, substr(null, null, null) e1, substr('bob', 2) e_ob, substr('bob', 2, 1) eo from test; -> EN E1 E_OB EO -> ---- ---- ---- -- -> null null ob o -> rows: 1 - -select substring(null, null) en, substring(null, null, null) e1, substring('bob', 2) e_ob, substring('bob', 2, 1) eo from test; -> EN E1 E_OB EO -> ---- ---- ---- -- -> null null ob o -> rows: 1 - -select substring(null from null) en, substring(null from null for null) e1, substring('bob' from 2) e_ob, substring('bob' from 2 for 1) eo from test; -> EN E1 E_OB EO -> ---- ---- ---- -- -> null null ob o -> rows: 1 - -call hash('SHA256', stringtoutf8('Hello'), 1); -> X'185f8db32271fe25f561a6fc938b2e264306ec304eda518007d1764826381969' -> ------------------------------------------------------------------- -> 185f8db32271fe25f561a6fc938b2e264306ec304eda518007d1764826381969 -> rows: 1 - -CALL HASH('SHA256', STRINGTOUTF8('Password'), 1000); -> X'c644a176ce920bde361ac336089b06cc2f1514dfa95ba5aabfe33f9a22d577f0' -> ------------------------------------------------------------------- -> c644a176ce920bde361ac336089b06cc2f1514dfa95ba5aabfe33f9a22d577f0 -> rows: 1 - -CALL UTF8TOSTRING(STRINGTOUTF8('This is a test')); -> 'This is a test' -> ---------------- -> This is a test -> rows: 1 - -CALL STRINGENCODE(STRINGDECODE('Lines 1\nLine 2')); -> 'Lines 1\nLine 2' -> ----------------- -> Lines 1\nLine 2 -> rows: 1 - -call encrypt('AES', '00000000000000000000000000000000', stringtoutf8('Hello World Test')); -> X'dbd42d55d4b923c4b03eba0396fac98e' -> ----------------------------------- -> dbd42d55d4b923c4b03eba0396fac98e -> rows: 1 - -call utf8tostring(decrypt('AES', '00000000000000000000000000000000', 'dbd42d55d4b923c4b03eba0396fac98e')); -> 'Hello World Test' -> ------------------ -> Hello World Test -> rows: 1 - -CALL ENCRYPT('XTEA', '00', STRINGTOUTF8('Test')); -> X'8bc9a4601b3062692a72a5941072425f' -> ----------------------------------- -> 8bc9a4601b3062692a72a5941072425f -> rows: 1 - -call encrypt('XTEA', '000102030405060708090a0b0c0d0e0f', '4142434445464748'); -> X'dea0b0b40966b0669fbae58ab503765f' -> ----------------------------------- -> dea0b0b40966b0669fbae58ab503765f -> rows: 1 - -call utf8tostring(decrypt('AES', hash('sha256', stringtoutf8('Hello'), 1000), encrypt('AES', hash('sha256', stringtoutf8('Hello'), 1000), stringtoutf8('Hello World Test')))); -> 'Hello World Test' -> ------------------ -> Hello World Test -> rows: 1 - -select length(curdate()) c1, length(current_date()) c2, substring(curdate(), 5, 1) c3 from test; -> C1 C2 C3 -> -- -- -- -> 10 10 - -> rows: 1 - -select length(curtime()) c1, length(current_time()) c2, substring(curtime(), 3, 1) c3 from test; -> C1 C2 C3 -> -- -- -- -> 8 8 : -> rows: 1 - -select length(now())>20 c1, length(current_timestamp())>20 c2, length(now(0))>20 c3, length(now(2))>20 c4, substring(now(5), 20, 1) c5 from test; -> C1 C2 C3 C4 C5 -> ---- ---- ---- ---- -- -> TRUE TRUE TRUE TRUE . -> rows: 1 - -select dateadd('month', 1, timestamp '2003-01-31 10:20:30.012345678') d1 from test; -> D1 -> ----------------------------- -> 2003-02-28 10:20:30.012345678 -> rows: 1 - -select dateadd('year', -1, timestamp '2000-02-29 10:20:30.012345678') d1 from test; -> D1 -> ----------------------------- -> 1999-02-28 10:20:30.012345678 -> rows: 1 - -select datediff('yy', timestamp '2003-12-01 10:20:30.0', timestamp '2004-01-01 10:00:00.0') d1 from test; -> D1 -> -- -> 1 -> rows: 1 - -select datediff('year', timestamp '2003-12-01 10:20:30.0', timestamp '2004-01-01 10:00:00.0') d1 from test; -> D1 -> -- -> 1 -> rows: 1 - -select datediff('mm', timestamp '2003-11-01 10:20:30.0', timestamp '2004-01-01 10:00:00.0') d2 from test; -> D2 -> -- -> 2 -> rows: 1 - -select datediff('month', timestamp '2003-11-01 10:20:30.0', timestamp '2004-01-01 10:00:00.0') d2 from test; -> D2 -> -- -> 2 -> rows: 1 - -select datediff('dd', timestamp '2004-01-01 10:20:30.0', timestamp '2004-01-05 10:00:00.0') d4 from test; -> D4 -> -- -> 4 -> rows: 1 - -select datediff('day', timestamp '2004-01-01 10:20:30.0', timestamp '2004-01-05 10:00:00.0') d4 from test; -> D4 -> -- -> 4 -> rows: 1 - -select datediff('hh', timestamp '2004-01-01 10:20:30.0', timestamp '2004-01-02 10:00:00.0') d24 from test; -> D24 -> --- -> 24 -> rows: 1 - -select datediff('hour', timestamp '2004-01-01 10:20:30.0', timestamp '2004-01-02 10:00:00.0') d24 from test; -> D24 -> --- -> 24 -> rows: 1 - -select datediff('mi', timestamp '2004-01-01 10:20:30.0', timestamp '2004-01-01 10:00:00.0') d20 from test; -> D20 -> --- -> -20 -> rows: 1 - -select datediff('minute', timestamp '2004-01-01 10:20:30.0', timestamp '2004-01-01 10:00:00.0') d20 from test; -> D20 -> --- -> -20 -> rows: 1 - -select datediff('ss', timestamp '2004-01-01 10:00:00.5', timestamp '2004-01-01 10:00:01.0') d1 from test; -> D1 -> -- -> 1 -> rows: 1 - -select datediff('second', timestamp '2004-01-01 10:00:00.5', timestamp '2004-01-01 10:00:01.0') d1 from test; -> D1 -> -- -> 1 -> rows: 1 - -select datediff('ms', timestamp '2004-01-01 10:00:00.5', timestamp '2004-01-01 10:00:01.0') d50x from test; -> D50X -> ---- -> 500 -> rows: 1 - -select datediff('millisecond', timestamp '2004-01-01 10:00:00.5', timestamp '2004-01-01 10:00:01.0') d50x from test; -> D50X -> ---- -> 500 -> rows: 1 - -select dayname(date '2005-09-12') d_monday from test; -> D_MONDAY -> -------- -> Monday -> rows: 1 - -select monthname(date '2005-09-12') d_sept from test; -> D_SEPT -> --------- -> September -> rows: 1 - -select dayofmonth(date '2005-09-12') d12 from test; -> D12 -> --- -> 12 -> rows: 1 - -select dayofweek(date '2005-09-12') d2 from test; -> D2 -> -- -> 2 -> rows: 1 - -select dayofyear(date '2005-01-01') d1 from test; -> D1 -> -- -> 1 -> rows: 1 - -select year(date '2005-01-01') d2005 from test; -> D2005 -> ----- -> 2005 -> rows: 1 - -select quarter(date '2005-09-01') d3 from test; -> D3 -> -- -> 3 -> rows: 1 - -select month(date '2005-09-25') d9 from test; -> D9 -> -- -> 9 -> rows: 1 - -select week(date '2003-01-09') d1 from test; -> D1 -> -- -> 2 -> rows: 1 - -select hour(time '23:10:59') d23 from test; -> D23 -> --- -> 23 -> rows: 1 - -select minute(timestamp '2005-01-01 23:10:59') d10 from test; -> D10 -> --- -> 10 -> rows: 1 - -select second(timestamp '2005-01-01 23:10:59') d59 from test; -> D59 -> --- -> 59 -> rows: 1 - -select right(database(), 6) x_script from test; -> X_SCRIPT -> -------- -> SCRIPT -> rows: 1 - -select user() x_sa, current_user() x_sa2 from test; -> X_SA X_SA2 -> ---- ----- -> SA SA -> rows: 1 - -select current_user() x_sa from test; -> X_SA -> ---- -> SA -> rows: 1 - -select autocommit() x_true from test; -> X_TRUE -> ------ -> TRUE -> rows: 1 - -select readonly() x_false from test; -> X_FALSE -> ------- -> FALSE -> rows: 1 - -select ifnull(null, '1') x1, ifnull(null, null) xn, ifnull('a', 'b') xa from test; -> X1 XN XA -> -- ---- -- -> 1 null a -> rows: 1 - -select casewhen(null, '1', '2') xn, casewhen(1>0, 'n', 'y') xy, casewhen(0<1, 'a', 'b') xa from test; -> XN XY XA -> -- -- -- -> 2 n a -> rows: 1 - -select x, case when x=0 then 'zero' else 'not zero' end y from system_range(0, 2); -> X Y -> - -------- -> 0 zero -> 1 not zero -> 2 not zero -> rows: 3 - -select x, case when x=0 then 'zero' end y from system_range(0, 1); -> X Y -> - ---- -> 0 zero -> 1 null -> rows: 2 - -select x, case x when 0 then 'zero' else 'not zero' end y from system_range(0, 1); -> X Y -> - -------- -> 0 zero -> 1 not zero -> rows: 2 - -select x, case x when 0 then 'zero' when 1 then 'one' end y from system_range(0, 2); -> X Y -> - ---- -> 0 zero -> 1 one -> 2 null -> rows: 3 - -select convert(null, varchar(255)) xn, convert(' 10', int) x10, convert(' 20 ', int) x20 from test; -> XN X10 X20 -> ---- --- --- -> null 10 20 -> rows: 1 - -select cast(null as varchar(255)) xn, cast(' 10' as int) x10, cast(' 20 ' as int) x20 from test; -> XN X10 X20 -> ---- --- --- -> null 10 20 -> rows: 1 - -select coalesce(null, null) xn, coalesce(null, 'a') xa, coalesce('1', '2') x1 from test; -> XN XA X1 -> ---- -- -- -> null a 1 -> rows: 1 - -select nullif(null, null) xn, nullif('a', 'a') xn, nullif('1', '2') x1 from test; -> XN XN X1 -> ---- ---- -- -> null null 1 -> rows: 1 - -drop table test; -> ok - ---- sequence with manual value ------------------ -drop table if exists test; -> ok - -CREATE TABLE TEST(ID bigint generated by default as identity (start with 1), name varchar); -> ok - -SET AUTOCOMMIT FALSE; -> ok - -insert into test(name) values('Hello'); -> update count: 1 - -insert into test(name) values('World'); -> update count: 1 - -call identity(); -> IDENTITY() -> ---------- -> 2 -> rows: 1 - -insert into test(id, name) values(1234567890123456, 'World'); -> update count: 1 - -call identity(); -> IDENTITY() -> ---------------- -> 1234567890123456 -> rows: 1 - -insert into test(name) values('World'); -> update count: 1 - -call identity(); -> IDENTITY() -> ---------------- -> 1234567890123457 -> rows: 1 - -select * from test order by id; -> ID NAME -> ---------------- ----- -> 1 Hello -> 2 World -> 1234567890123456 World -> 1234567890123457 World -> rows (ordered): 4 - -SET AUTOCOMMIT TRUE; -> ok - -drop table if exists test; -> ok - -CREATE TABLE TEST(ID bigint generated by default as identity (start with 1), name varchar); -> ok - -SET AUTOCOMMIT FALSE; -> ok - -insert into test(name) values('Hello'); -> update count: 1 - -insert into test(name) values('World'); -> update count: 1 - -call identity(); -> IDENTITY() -> ---------- -> 2 -> rows: 1 - -insert into test(id, name) values(1234567890123456, 'World'); -> update count: 1 - -call identity(); -> IDENTITY() -> ---------------- -> 1234567890123456 -> rows: 1 - -insert into test(name) values('World'); -> update count: 1 - -call identity(); -> IDENTITY() -> ---------------- -> 1234567890123457 -> rows: 1 - -select * from test order by id; -> ID NAME -> ---------------- ----- -> 1 Hello -> 2 World -> 1234567890123456 World -> 1234567890123457 World -> rows (ordered): 4 - -SET AUTOCOMMIT TRUE; -> ok - -drop table test; -> ok - ---- test cases --------------------------------------------------------------------------------------------- -create memory table word(word_id integer, name varchar); -> ok - -alter table word alter column word_id integer(10) auto_increment; -> ok - -insert into word(name) values('Hello'); -> update count: 1 - -alter table word alter column word_id restart with 30872; -> ok - -insert into word(name) values('World'); -> update count: 1 - -select * from word; -> WORD_ID NAME -> ------- ----- -> 1 Hello -> 30872 World -> rows: 2 - -drop table word; -> ok - diff --git a/tools/h2/src/test/org/h2/test/testSimple.in.txt b/tools/h2/src/test/org/h2/test/testSimple.in.txt deleted file mode 100755 index f7221f7..0000000 --- a/tools/h2/src/test/org/h2/test/testSimple.in.txt +++ /dev/null @@ -1,679 +0,0 @@ -create table test(a int, b int) as select 2, 0; -create index idx on test(b, a); -select count(*) from test where a in(2, 10) and b in(0, null); -> 1; -drop table test; -create table test(a int, b int) as select 1, 0; -create index idx on test(b, a); -select count(*) from test where b in(null, 0) and a in(1, null); -> 1; -drop table test; -create cached temp table test(id identity) not persistent; -drop table test; -create table test(a int, b int, unique(a, b)); -insert into test values(1,1), (1,2); -select count(*) from test where a in(1,2) and b in(1,2); -> 2; -drop table test; -create memory temp table test(name varchar primary key); -select index_class from information_schema.indexes where table_name = 'TEST'; -> org.h2.index.TreeIndex; -drop table test; -create cached temp table test(name varchar primary key); -select index_class from information_schema.indexes where table_name = 'TEST'; -> org.h2.index.PageBtreeIndex; -drop table test; -create table test(id int); -alter table test alter column id set default 'x'; -select column_default from information_schema.columns c where c.table_name = 'TEST' and c.column_name = 'ID'; -> 'x'; -alter table test alter column id set not null; -select is_nullable from information_schema.columns c where c.table_name = 'TEST' and c.column_name = 'ID'; -> NO; -alter table test alter column id set data type varchar; -select type_name from information_schema.columns c where c.table_name = 'TEST' and c.column_name = 'ID'; -> VARCHAR; -alter table test alter column id type int; -select type_name from information_schema.columns c where c.table_name = 'TEST' and c.column_name = 'ID'; -> INTEGER; -alter table test alter column id drop default; -select column_default from information_schema.columns c where c.table_name = 'TEST' and c.column_name = 'ID'; -> null; -alter table test alter column id drop not null; -select is_nullable from information_schema.columns c where c.table_name = 'TEST' and c.column_name = 'ID'; -> YES; -drop table test; -select cast(cast(0.1 as real) as decimal); -> 0.1; -select cast(cast(95605327.73 as float) as decimal); -> 95605327.73; -select timestampdiff(month, '2003-02-01','2003-05-01'); -> 3; -select timestampdiff(YEAR,'2002-05-01','2001-01-01'); -> -1; -select timestampdiff(MINUTE,'2003-02-01','2003-05-01 12:05:55'); -> 128885; -select x from (select *, rownum as r from system_range(1, 3)) where r=2; -> 2; -select cast(cast('01020304-0506-0708-090a-0b0c0d0e0f00' as uuid) as binary); -> 0102030405060708090a0b0c0d0e0f00; -create table test(name varchar(255)) as select 'Hello+World+'; -select count(*) from test where name like 'Hello++World++' escape '+'; -> 1; -select count(*) from test where name like '+H+e+l+l+o++World++' escape '+'; -> 1; -select count(*) from test where name like 'Hello+World++' escape '+'; -> 0; -select count(*) from test where name like 'Hello++World+' escape '+'; -> 0; -drop table test; - -select count(*) from system_range(1, 1); -> 1; -select count(*) from system_range(1, -1); -> 0; - -select 1 from dual where '\' like '\' escape ''; -> 1; -select left(timestamp '2001-02-03 08:20:31+04', 4); -> 2001; - -create table t1$2(id int); -drop table t1$2; - -create table test(id int primary key) as select x from system_range(1, 200); -delete from test; -insert into test(id) values(1); -select * from test order by id; -> 1; -drop table test; - -create memory table test(id int) as select 1 from dual not persistent; -insert into test values(1); -select count(1) from test; -> 2; -@reconnect; -select count(1) from test; -> 0; -drop table test; -create table test(t clob) as select 1; -select distinct t from test; -> 1; -drop table test; -create table test(id int unique not null); -drop table test; -create table test(id int not null unique); -drop table test; -select count(*)from((select 1 from dual limit 1)union(select 2 from dual limit 1)); -> 2; -select sum(cast(x as int)) from system_range(2147483547, 2147483637); -> 195421006872; -select sum(x) from system_range(9223372036854775707, 9223372036854775797); -> 839326855353784593432; -select sum(cast(100 as tinyint)) from system_range(1, 1000); -> 100000; -select sum(cast(100 as smallint)) from system_range(1, 1000); -> 100000; -select avg(cast(x as int)) from system_range(2147483547, 2147483637); -> 2147483592; -select avg(x) from system_range(9223372036854775707, 9223372036854775797); -> 9223372036854775752; -select avg(cast(100 as tinyint)) from system_range(1, 1000); -> 100; -select avg(cast(100 as smallint)) from system_range(1, 1000); -> 100; -select datediff(yyyy, now(), now()); -> 0; -create table t(d date) as select '2008-11-01' union select '2008-11-02'; -select 1 from t group by year(d) order by year(d); -> 1; -drop table t; -create table t(d int) as select 2001 union select 2002; -select 1 from t group by d/10 order by d/10; -> 1; -drop table t; - -create schema test; -create sequence test.report_id_seq; -select nextval('"test".REPORT_ID_SEQ'); -> 1; -select nextval('"test"."report_id_seq"'); -> 2; -select nextval('test.report_id_seq'); -> 3; -drop schema test; - -create table master(id int primary key); -create table detail(id int primary key, x bigint, foreign key(x) references master(id) on delete cascade); -alter table detail alter column x bigint; -insert into master values(0); -insert into detail values(0,0); -delete from master; -drop table master, detail; - -drop all objects; -create table test(id int, parent int references test(id) on delete cascade); -insert into test values(0, 0); -alter table test rename to test2; -delete from test2; -drop table test2; - -SELECT X FROM dual GROUP BY X HAVING X=AVG(X); -> 1; -create view test_view(id,) as select * from dual; -drop view test_view; -create table test(id int,); -insert into test(id,) values(1,); -merge into test(id,) key(id,) values(1,); -drop table test; - -SET MODE DB2; -SELECT * FROM SYSTEM_RANGE(1, 100) OFFSET 99 ROWS; -> 100; -SELECT * FROM SYSTEM_RANGE(1, 100) OFFSET 50 ROWS FETCH FIRST 1 ROW ONLY; -> 51; -SELECT * FROM SYSTEM_RANGE(1, 100) FETCH FIRST 1 ROWS ONLY; -> 1; -SELECT * FROM SYSTEM_RANGE(1, 100) FETCH FIRST ROW ONLY; -> 1; -SET MODE REGULAR; - -CREATE TABLE Address (id NUMBER NOT NULL, city VARCHAR2(255), PRIMARY KEY (id)); -CREATE TABLE Person (id NUMBER NOT NULL, name VARCHAR2(255), ADDRESS_ID NUMBER, PRIMARY KEY (id)); -INSERT INTO PERSON (id, name) values (1, 'Frank'); -SELECT 1 FROM Person t0, Address t1, Person t2 WHERE t0.ADDRESS_ID = t1.id(+) AND t1.id = t2.ADDRESS_ID(+); -> 1; -drop table Address, Person; - -create domain email as varchar comment 'e-mail'; -create table test(e email); -select remarks from INFORMATION_SCHEMA.COLUMNS where table_name='TEST'; -> e-mail; -drop table test; -drop domain email; - -create table test$test(id int); -drop table test$test; -create table test$$test(id int); -drop table test$$test; -create table test (id varchar(36) as random_uuid() primary key); -insert into test() values(); -delete from test where id = select id from test; -drop table test; -create table test (id varchar(36) as now() primary key); -insert into test() values(); -delete from test where id = select id from test; -drop table test; -SELECT SOME(X>4) FROM SYSTEM_RANGE(1,6); -> TRUE; -SELECT EVERY(X>4) FROM SYSTEM_RANGE(1,6); -> FALSE; -SELECT BOOL_OR(X>4) FROM SYSTEM_RANGE(1,6); -> TRUE; -SELECT BOOL_AND(X>4) FROM SYSTEM_RANGE(1,6); -> FALSE; -CREATE TABLE TEST(ID IDENTITY); -ALTER TABLE TEST ALTER COLUMN ID RESTART WITH ? {1:10}; -INSERT INTO TEST VALUES(NULL); -SELECT * FROM TEST; -> 10; -DROP TABLE TEST; -CREATE SEQUENCE TEST_SEQ; -ALTER SEQUENCE TEST_SEQ RESTART WITH ? INCREMENT BY ? {1:20, 2: 3}; -SELECT NEXT VALUE FOR TEST_SEQ; -> 20; -SELECT NEXT VALUE FOR TEST_SEQ; -> 23; -DROP SEQUENCE TEST_SEQ; - -create schema Contact; -CREATE TABLE Account (id BIGINT); -CREATE TABLE Person (id BIGINT, FOREIGN KEY (id) REFERENCES Account(id)); -CREATE TABLE Contact.Contact (id BIGINT, FOREIGN KEY (id) REFERENCES public.Person(id)); -drop schema contact; -drop table account, person; - -create schema Contact; -CREATE TABLE Account (id BIGINT primary key); -CREATE TABLE Person (id BIGINT primary key, FOREIGN KEY (id) REFERENCES Account); -CREATE TABLE Contact.Contact (id BIGINT primary key, FOREIGN KEY (id) REFERENCES public.Person); -drop schema contact; -drop table account, person; - -select extract(hour from timestamp '2001-02-03 14:15:16'); -> 14; -select extract(hour from '2001-02-03 14:15:16'); -> 14; -select hour('2001-02-03 14:15:16'); -> 14; - -CREATE TABLE TEST(A int NOT NULL, B int NOT NULL, C int) ; -ALTER TABLE TEST ADD CONSTRAINT CON UNIQUE(A,B); -ALTER TABLE TEST DROP C; -ALTER TABLE TEST DROP CONSTRAINT CON; -ALTER TABLE TEST DROP B; -DROP TABLE TEST; - -select count(d.*) from dual d group by d.x; -> 1; - -create table test(id int); -select count(*) from (select * from ((select * from test) union (select * from test)) a) b where id = 0; -> 0; -select count(*) from (select * from ((select * from test) union select * from test) a) b where id = 0; -> 0; -select count(*) from (select * from (select * from test union select * from test) a) b where id = 0; -> 0; -select 1 from ((test d1 inner join test d2 on d1.id = d2.id) inner join test d3 on d1.id = d3.id) inner join test d4 on d4.id = d1.id; -drop table test; - -select lpad('string', 10, '+'); -> ++++string; -select rpad('string', 10, '+'); -> string++++; -select lpad('string', 10); -> string; - -select count(*) from (select * from dual union select * from dual) where x = 0; -> 0; -select count(*) from (select * from (select * from dual union select * from dual)) where x = 0; -> 0; - -select instr('abcisj','s', -1) from dual; -> 5; -CREATE TABLE TEST(ID INT); -INSERT INTO TEST VALUES(1), (2), (3); -create index idx_desc on test(id desc); -select * from test where id between 0 and 1; -> 1; -select * from test where id between 3 and 4; -> 3; -drop table test; - -CREATE TABLE TEST(ID INT PRIMARY KEY, NAME VARCHAR(255)); -INSERT INTO TEST VALUES(1, 'Hello'), (2, 'HelloWorld'), (3, 'HelloWorldWorld'); -SELECT COUNT(*) FROM TEST WHERE NAME REGEXP 'World'; -> 2; -SELECT NAME FROM TEST WHERE NAME REGEXP 'WorldW'; -> HelloWorldWorld; -drop table test; - -select * from (select x from (select x from dual)) where 1=x; -> 1; -CREATE VIEW TEST_VIEW AS SELECT X FROM (SELECT X FROM DUAL); -SELECT * FROM TEST_VIEW; -> 1; -SELECT * FROM TEST_VIEW; -> 1; -DROP VIEW TEST_VIEW; - -SELECT X FROM (SELECT X, X AS "XY" FROM DUAL) WHERE X=1; -> 1; -SELECT X FROM (SELECT X, X AS "X Y" FROM DUAL) WHERE X=1; -> 1; -SELECT X FROM (SELECT X, X AS "X Y" FROM DUAL AS "D Z") WHERE X=1; -> 1; - -select * from (select x from dual union select convert(x, int) from dual) where x=0; -create table test(id int); -insert into scriptSimple.public.test(id) values(1), (2); -update test t set t.id=t.id+1; -update public.test set public.test.id=1; -select count(scriptSimple.public.test.id) from scriptSimple.public.test; -> 2; -update scriptSimple.public.test set scriptSimple.public.test.id=1; -drop table scriptSimple.public.test; - -select year(timestamp '2007-07-26 18:44:26.109000 +02:00'); -> 2007; - -create table test(id int primary key); -begin; -insert into test values(1); -rollback; -insert into test values(2); -rollback; -begin; -insert into test values(3); -commit; -insert into test values(4); -rollback; -select group_concat(id order by id) from test; -> 2,3,4; -drop table test; - -create table test(); -insert into test values(); -ALTER TABLE TEST ADD ID INTEGER; -select count(*) from test; -> 1; -drop table test; - -select * from dual where 'a_z' like '%=_%' escape '='; -> 1; - -create table test as select 1 from dual union all select 2 from dual; -drop table test; - -create table test_table(column_a integer); -insert into test_table values(1); -create view test_view AS SELECT * FROM (SELECT DISTINCT * FROM test_table) AS subquery; -select * FROM test_view; -> 1; -drop view test_view; -drop table test_table; - -CREATE TABLE TEST(ID INT); -INSERT INTO TEST VALUES(1); -CREATE VIEW TEST_VIEW AS SELECT COUNT(ID) X FROM TEST; -explain SELECT * FROM TEST_VIEW WHERE X>1; -DROP VIEW TEST_VIEW; -DROP TABLE TEST; - -create table test1(id int); -insert into test1 values(1), (1), (2), (3); -select sum(C0) from (select count(*) AS C0 from (select distinct * from test1) as temp); -> 3; -drop table test1; - -create table test(id int primary key check id>1); -drop table test; -create table table1(f1 int not null primary key); -create table table2(f2 int not null references table1(f1) on delete cascade); -drop table table2; -drop table table1; -create table table1(f1 int not null primary key); -create table table2(f2 int not null primary key references table1(f1)); -drop table table1; -drop table table2; - -select case when 1=null then 1 else 2 end; -> 2; - -select case (1) when 1 then 1 else 2 end; -> 1; - -create table test(id int); -insert into test values(1); -select distinct id from test a order by a.id; -> 1; -drop table test; - -create table FOO (ID int, A number(18, 2)); -insert into FOO (ID, A) values (1, 10.0), (2, 20.0); -select SUM (CASE when ID=1 then 0 ELSE A END) col0 from Foo; -> 20.00; -drop table FOO; - -select (SELECT true)+1 GROUP BY 1; -> 2; -create table FOO (ID int, A number(18, 2)); -insert into FOO (ID, A) values (1, 10.0), (2, 20.0); -select SUM (CASE when ID=1 then A ELSE 0 END) col0 from Foo; -> 10.00; -drop table FOO; - -create table A ( ID integer, a1 varchar(20) ); -create table B ( ID integer, AID integer, b1 varchar(20)); -create table C ( ID integer, BId integer, c1 varchar(20)); -insert into A (ID, a1) values (1, 'a1'); -insert into A (ID, a1) values (2, 'a2'); -select count(*) from A left outer join (B inner join C on C.BID=B.ID ) on B.AID=A.ID where A.id=1; -> 1; -select count(*) from A left outer join (B left join C on C.BID=B.ID ) on B.AID=A.ID where A.id=1; -> 1; -select count(*) from A left outer join B on B.AID=A.ID inner join C on C.BID=B.ID where A.id=1; -> 0; -select count(*) from (A left outer join B on B.AID=A.ID) inner join C on C.BID=B.ID where A.id=1; -> 0; -drop table a, b, c; - -create schema a; -create table a.test(id int); -insert into a.test values(1); -create schema b; -create table b.test(id int); -insert into b.test values(2); -select a.test.id + b.test.id from a.test, b.test; -> 3; -drop schema a; -drop schema b; - -select date '+0011-01-01'; -> 0011-01-01; -select date'-0010-01-01'; -> -10-01-01; -select datediff('HOUR', timestamp '2007-01-06 10:00:00Z', '2007-01-06 10:00:00Z'); -> 0; -select datediff('HOUR', timestamp '1234-05-06 10:00:00+01:00', '1234-05-06 10:00:00+02:00'); -> -1; -select datediff('HOUR', timestamp '1234-05-06 10:00:00+01:00', '1234-05-06 10:00:00-02:00'); -> 3; - -create schema TEST_SCHEMA; -create table TEST_SCHEMA.test(id int); -create sequence TEST_SCHEMA.TEST_SEQ; -select TEST_SCHEMA.TEST_SEQ.CURRVAL; -> 0; -select TEST_SCHEMA.TEST_SEQ.nextval; -> 1; -drop schema TEST_SCHEMA; - -create table test(id int); -create trigger TEST_TRIGGER before insert on test call "org.h2.test.db.TestTriggersConstraints"; -comment on trigger TEST_TRIGGER is 'just testing'; -select remarks from information_schema.triggers where trigger_name = 'TEST_TRIGGER'; -> just testing; -@reconnect; -select remarks from information_schema.triggers where trigger_name = 'TEST_TRIGGER'; -> just testing; -drop trigger TEST_TRIGGER; -@reconnect; - -create alias parse_long for "java.lang.Long.parseLong(java.lang.String)"; -comment on alias parse_long is 'Parse a long with base'; -select remarks from information_schema.function_aliases where alias_name = 'PARSE_LONG'; -> Parse a long with base; -@reconnect; -select remarks from information_schema.function_aliases where alias_name = 'PARSE_LONG'; -> Parse a long with base; -drop alias parse_long; -@reconnect; - -create role hr; -comment on role hr is 'Human Resources'; -select remarks from information_schema.roles where name = 'HR'; -> Human Resources; -@reconnect; -select remarks from information_schema.roles where name = 'HR'; -> Human Resources; -create user abc password 'x'; -grant hr to abc; -drop role hr; -@reconnect; -drop user abc; - -create domain email as varchar(100) check instr(value, '@') > 0; -comment on domain email is 'must contain @'; -select remarks from information_schema.domains where domain_name = 'EMAIL'; -> must contain @; -@reconnect; -select remarks from information_schema.domains where domain_name = 'EMAIL'; -> must contain @; -drop domain email; -@reconnect; - -create schema tests; -set schema tests; -create sequence walk; -comment on schema tests is 'Test Schema'; -comment on sequence walk is 'Walker'; -select remarks from information_schema.schemata where schema_name = 'TESTS'; -> Test Schema; -select remarks from information_schema.sequences where sequence_name = 'WALK'; -> Walker; -@reconnect; -select remarks from information_schema.schemata where schema_name = 'TESTS'; -> Test Schema; -select remarks from information_schema.sequences where sequence_name = 'WALK'; -> Walker; -drop schema tests; -@reconnect; - -create constant abc value 1; -comment on constant abc is 'One'; -select remarks from information_schema.constants where constant_name = 'ABC'; -> One; -@reconnect; -select remarks from information_schema.constants where constant_name = 'ABC'; -> One; -drop constant abc; -drop table test; -@reconnect; - -create table test(id int); -alter table test add constraint const1 unique(id); -create index IDX_ID on test(id); -comment on constraint const1 is 'unique id'; -comment on index IDX_ID is 'id_index'; -select remarks from information_schema.constraints where constraint_name = 'CONST1'; -> unique id; -select remarks from information_schema.indexes where index_name = 'IDX_ID'; -> id_index; -@reconnect; -select remarks from information_schema.constraints where constraint_name = 'CONST1'; -> unique id; -select remarks from information_schema.indexes where index_name = 'IDX_ID'; -> id_index; -drop table test; -@reconnect; - -create user sales password '1'; -comment on user sales is 'mr. money'; -select remarks from information_schema.users where name = 'SALES'; -> mr. money; -@reconnect; -select remarks from information_schema.users where name = 'SALES'; -> mr. money; -alter user sales rename to SALES_USER; -select remarks from information_schema.users where name = 'SALES_USER'; -> mr. money; -@reconnect; -select remarks from information_schema.users where name = 'SALES_USER'; -> mr. money; - -create table test(id int); -create linked table test_link('org.h2.Driver', 'jdbc:h2:mem:', 'sa', 'sa', 'DUAL'); -comment on table test_link is '123'; -select remarks from information_schema.tables where table_name = 'TEST_LINK'; -> 123; -@reconnect; -select remarks from information_schema.tables where table_name = 'TEST_LINK'; -> 123; -comment on table test_link is 'xyz'; -select remarks from information_schema.tables where table_name = 'TEST_LINK'; -> xyz; -alter table test_link rename to test_l; -select remarks from information_schema.tables where table_name = 'TEST_L'; -> xyz; -@reconnect; -select remarks from information_schema.tables where table_name = 'TEST_L'; -> xyz; -drop table test; -@reconnect; - -create table test(id int); -create view test_v as select * from test; -comment on table test_v is 'abc'; -select remarks from information_schema.tables where table_name = 'TEST_V'; -> abc; -@reconnect; -select remarks from information_schema.tables where table_name = 'TEST_V'; -> abc; -alter table test_v rename to TEST_VIEW; -select remarks from information_schema.tables where table_name = 'TEST_VIEW'; -> abc; -@reconnect; -select remarks from information_schema.tables where table_name = 'TEST_VIEW'; -> abc; -drop table test; -@reconnect; - -create table test(a int); -comment on table test is 'hi'; -select remarks from information_schema.tables where table_name = 'TEST'; -> hi; -alter table test add column b int; -select remarks from information_schema.tables where table_name = 'TEST'; -> hi; -alter table test rename to test1; -select remarks from information_schema.tables where table_name = 'TEST1'; -> hi; -@reconnect; -select remarks from information_schema.tables where table_name = 'TEST1'; -> hi; -comment on table test1 is 'ho'; -@reconnect; -select remarks from information_schema.tables where table_name = 'TEST1'; -> ho; -drop table test1; - -create table test(a int, b int); -comment on column test.b is 'test'; -select remarks from information_schema.columns where table_name = 'TEST' and column_name = 'B'; -> test; -@reconnect; -select remarks from information_schema.columns where table_name = 'TEST' and column_name = 'B'; -> test; -alter table test drop column b; -@reconnect; -comment on column test.a is 'ho'; -select remarks from information_schema.columns where table_name = 'TEST' and column_name = 'A'; -> ho; -@reconnect; -select remarks from information_schema.columns where table_name = 'TEST' and column_name = 'A'; -> ho; -drop table test; -@reconnect; - -create table test(a int); -comment on column test.a is 'test'; -alter table test rename to test2; -@reconnect; -select remarks from information_schema.columns where table_name = 'TEST2'; -> test; -@reconnect; -select remarks from information_schema.columns where table_name = 'TEST2'; -> test; -drop table test2; -@reconnect; - -create table test1 (a varchar(10)); -create hash index x1 on test1(a); -insert into test1 values ('abcaaaa'),('abcbbbb'),('abccccc'),('abcdddd'); -insert into test1 values ('abcaaaa'),('abcbbbb'),('abccccc'),('abcdddd'); -insert into test1 values ('abcaaaa'),('abcbbbb'),('abccccc'),('abcdddd'); -insert into test1 values ('abcaaaa'),('abcbbbb'),('abccccc'),('abcdddd'); -select count(*) from test1 where a='abcaaaa'; -> 4; -select count(*) from test1 where a='abcbbbb'; -> 4; -@reconnect; -select count(*) from test1 where a='abccccc'; -> 4; -select count(*) from test1 where a='abcdddd'; -> 4; -update test1 set a='abccccc' where a='abcdddd'; -select count(*) from test1 where a='abccccc'; -> 8; -select count(*) from test1 where a='abcdddd'; -> 0; -delete from test1 where a='abccccc'; -select count(*) from test1 where a='abccccc'; -> 0; -truncate table test1; -insert into test1 values ('abcaaaa'); -insert into test1 values ('abcaaaa'); -delete from test1; -drop table test1; -@reconnect; \ No newline at end of file diff --git a/tools/h2/src/test/org/h2/test/todo/TestDiskSpaceLeak.java b/tools/h2/src/test/org/h2/test/todo/TestDiskSpaceLeak.java deleted file mode 100755 index 63c0185..0000000 --- a/tools/h2/src/test/org/h2/test/todo/TestDiskSpaceLeak.java +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.test.todo; - -import java.io.File; -import java.sql.Connection; -import java.sql.DriverManager; -import java.sql.ResultSet; -import java.sql.SQLException; -import org.h2.jdbc.JdbcConnection; -import org.h2.tools.DeleteDbFiles; -import org.h2.tools.Recover; -import org.h2.util.JdbcUtils; - -/** - * A test to detect disk space leaks when killing a process. - */ -public class TestDiskSpaceLeak { - - /** - * Run just this test. - * - * @param args ignored - */ - public static void main(String... args) throws Exception { - System.setProperty("h2.lobInDatabase", "true"); - DeleteDbFiles.execute("data", null, true); - Class.forName("org.h2.Driver"); - Connection conn; - long before = 0; - for (int i = 0; i < 10; i++) { - conn = DriverManager.getConnection("jdbc:h2:data/test"); - ResultSet rs; - rs = conn.createStatement().executeQuery( - "select count(*) from information_schema.lobs"); - rs.next(); - System.out.println("lobs: " + rs.getInt(1)); - rs = conn.createStatement().executeQuery( - "select count(*) from information_schema.lob_map"); - rs.next(); - System.out.println("lob_map: " + rs.getInt(1)); - rs = conn.createStatement().executeQuery( - "select count(*) from information_schema.lob_data"); - rs.next(); - System.out.println("lob_data: " + rs.getInt(1)); - conn.close(); - Recover.execute("data", "test"); - new File("data/test.h2.sql").renameTo(new File("data/test." + i + ".sql")); - conn = DriverManager.getConnection("jdbc:h2:data/test"); - // ((JdbcConnection) conn).setPowerOffCount(i); - ((JdbcConnection) conn).setPowerOffCount(28); - String last = "connect"; - try { - conn.createStatement().execute("drop table test if exists"); - last = "drop"; - conn.createStatement().execute("create table test(id identity, b blob)"); - last = "create"; - conn.createStatement().execute("insert into test values(1, space(10000))"); - last = "insert"; - conn.createStatement().execute("delete from test"); - last = "delete"; - conn.createStatement().execute("insert into test values(1, space(10000))"); - last = "insert2"; - conn.createStatement().execute("delete from test"); - last = "delete2"; - } catch (SQLException e) { - // ignore - } finally { - JdbcUtils.closeSilently(conn); - } - long now = new File("data/test.h2.db").length(); - long diff = now - before; - before = now; - System.out.println(now + " " + diff + " " + i + " " + last); - } - } -} diff --git a/tools/h2/src/test/org/h2/test/todo/TestUndoLogMemory.java b/tools/h2/src/test/org/h2/test/todo/TestUndoLogMemory.java deleted file mode 100755 index c6d07f0..0000000 --- a/tools/h2/src/test/org/h2/test/todo/TestUndoLogMemory.java +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, Version - * 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). Initial Developer: H2 Group - */ -package org.h2.test.todo; - -import java.sql.Connection; -import java.sql.DriverManager; -import java.sql.PreparedStatement; -import java.sql.SQLException; -import java.sql.Statement; -import org.h2.tools.DeleteDbFiles; - -/** - * A test to reproduce out of memory using a large operation. - */ -public class TestUndoLogMemory { - - /** - * Run just this test. - * - * @param args ignored - */ - public static void main(String... args) throws Exception { - System.setProperty("h2.largeTransactions", "true"); - - int todoLargeRows; - - new TestUndoLogMemory().test(10, "null"); - new TestUndoLogMemory().test(100, "space(100000)"); -// new TestUndoLogMemory().test(100000, "null"); -// new TestUndoLogMemory().test(1000, "space(100000)"); - - } - - private void test(int count, String defaultValue) throws SQLException { - - // -Xmx1m -XX:+HeapDumpOnOutOfMemoryError - DeleteDbFiles.execute("data", "test", true); - Connection conn = DriverManager.getConnection("jdbc:h2:data/test"); - Statement stat = conn.createStatement(); - stat.execute("set cache_size 32"); - stat.execute("SET max_operation_memory 100"); - stat.execute("SET max_memory_undo 100"); - conn.setAutoCommit(false); - - // also a problem: tables without unique index - System.out.println("create--- " + count + " " + defaultValue); - stat.execute("create table test(id int, name varchar default " + defaultValue + " )"); - System.out.println("insert---"); - stat.execute("insert into test(id) select x from system_range(1, "+count+")"); - System.out.println("rollback---"); - conn.rollback(); - - System.out.println("drop---"); - stat.execute("drop table test"); - System.out.println("create---"); - stat.execute("create table test(id int primary key, name varchar default " + defaultValue + " )"); - - // INSERT problem - System.out.println("insert---"); - stat.execute( - "insert into test(id) select x from system_range(1, "+count+")"); - System.out.println("delete---"); - stat.execute("delete from test"); - - // DELETE problem - System.out.println("insert---"); - PreparedStatement prep = conn.prepareStatement("insert into test(id) values(?)"); - for (int i = 0; i < count; i++) { - prep.setInt(1, i); - prep.execute(); - } - System.out.println("delete---"); - stat.execute("delete from test"); - - System.out.println("close---"); - conn.close(); - } -} diff --git a/tools/h2/src/test/org/h2/test/todo/columnAlias.txt b/tools/h2/src/test/org/h2/test/todo/columnAlias.txt deleted file mode 100755 index 0c66332..0000000 --- a/tools/h2/src/test/org/h2/test/todo/columnAlias.txt +++ /dev/null @@ -1,31 +0,0 @@ -DROP TABLE TEST; -CREATE TABLE TEST(ID INT); -INSERT INTO TEST VALUES(1); -INSERT INTO TEST VALUES(2); - -SELECT ID AS A FROM TEST WHERE A>0; --- Yes: HSQLDB --- Fail: Oracle, MS SQL Server, PostgreSQL, MySQL, H2, Derby - -SELECT ID AS A FROM TEST ORDER BY A; --- Yes: Oracle, MS SQL Server, PostgreSQL, MySQL, H2, Derby, HSQLDB - -SELECT ID AS A FROM TEST ORDER BY -A; --- Yes: Oracle, MySQL, HSQLDB --- Fail: MS SQL Server, PostgreSQL, H2, Derby - -SELECT ID AS A FROM TEST GROUP BY A; --- Yes: PostgreSQL, MySQL, HSQLDB --- Fail: Oracle, MS SQL Server, H2, Derby - -SELECT ID AS A FROM TEST GROUP BY -A; --- Yes: MySQL, HSQLDB --- Fail: Oracle, MS SQL Server, PostgreSQL, H2, Derby - -SELECT ID AS A FROM TEST GROUP BY ID HAVING A>0; --- Yes: MySQL, HSQLDB --- Fail: Oracle, MS SQL Server, PostgreSQL, H2, Derby - -SELECT COUNT(*) AS A FROM TEST GROUP BY ID HAVING A>0; --- Yes: MySQL, HSQLDB --- Fail: Oracle, MS SQL Server, PostgreSQL, H2, Derby diff --git a/tools/h2/src/test/org/h2/test/todo/dateFunctions.txt b/tools/h2/src/test/org/h2/test/todo/dateFunctions.txt deleted file mode 100755 index 4f13eab..0000000 --- a/tools/h2/src/test/org/h2/test/todo/dateFunctions.txt +++ /dev/null @@ -1,10 +0,0 @@ -h2 -update FOO set a = dateadd('second', 4320000, a); -ms sql server -update FOO set a = dateadd(s, 4320000, a); -mysql -update FOO set a = date_add(a, interval 4320000 second); -postgresql -update FOO set a = a + interval '4320000 s'; -oracle -update FOO set a = a + INTERVAL '4320000' SECOND; diff --git a/tools/h2/src/test/org/h2/test/todo/package.html b/tools/h2/src/test/org/h2/test/todo/package.html deleted file mode 100755 index b13376f..0000000 --- a/tools/h2/src/test/org/h2/test/todo/package.html +++ /dev/null @@ -1,15 +0,0 @@ - - - - -Javadoc package documentation -

    - -Documentation and tests for open issues. - -

    \ No newline at end of file diff --git a/tools/h2/src/test/org/h2/test/todo/recursiveQueries.txt b/tools/h2/src/test/org/h2/test/todo/recursiveQueries.txt deleted file mode 100755 index da21c32..0000000 --- a/tools/h2/src/test/org/h2/test/todo/recursiveQueries.txt +++ /dev/null @@ -1,130 +0,0 @@ -WITH DirectReports (ManagerID, EmployeeID, Title, DeptID, Level) -AS -( --- Anchor member definition - SELECT e.ManagerID, e.EmployeeID, e.Title, edh.DepartmentID, - 0 AS Level - FROM Employee AS e - INNER JOIN EmployeeDepartmentHistory AS edh - ON e.EmployeeID = edh.EmployeeID AND edh.EndDate IS NULL - WHERE ManagerID IS NULL - UNION ALL --- Recursive member definition - SELECT e.ManagerID, e.EmployeeID, e.Title, edh.DepartmentID, - Level + 1 - FROM Employee AS e - INNER JOIN EmployeeDepartmentHistory AS edh - ON e.EmployeeID = edh.EmployeeID AND edh.EndDate IS NULL - INNER JOIN DirectReports AS d - ON e.ManagerID = d.EmployeeID -) --- Statement that executes the CTE -SELECT ManagerID, EmployeeID, Title, Level -FROM DirectReports -INNER JOIN Department AS dp - ON DirectReports.DeptID = dp.DepartmentID -WHERE dp.GroupName = N'Research and Development' OR Level = 0; -GO - - DROP VIEW IF EXISTS TEST_REC; - DROP VIEW IF EXISTS TEST_2; - DROP TABLE IF EXISTS TEST; - - CREATE TABLE TEST(ID INT PRIMARY KEY, PARENT INT, NAME VARCHAR(255)); - INSERT INTO TEST VALUES(1, NULL, 'Root'); - INSERT INTO TEST VALUES(2, 1, 'Plant'); - INSERT INTO TEST VALUES(3, 1, 'Animal'); - INSERT INTO TEST VALUES(4, 2, 'Tree'); - INSERT INTO TEST VALUES(5, 2, 'Flower'); - INSERT INTO TEST VALUES(6, 3, 'Elephant'); - INSERT INTO TEST VALUES(7, 3, 'Dog'); - - CREATE FORCE VIEW TEST_2(ID, PARENT, NAME) AS SELECT ID, PARENT, NAME FROM TEST_REC; - - CREATE FORCE VIEW TEST_REC(ID, PARENT, NAME) AS - SELECT ID, PARENT, NAME FROM TEST T - WHERE PARENT IS NULL - UNION ALL - SELECT T.ID, T.PARENT, T.NAME - FROM TEST T, TEST_2 R - WHERE T.PARENT=R.ID; - - SELECT * FROM TEST_REC; - ------------- - - DROP VIEW IF EXISTS TEST_REC; - DROP VIEW IF EXISTS TEST_2; - DROP TABLE IF EXISTS TEST; - - CREATE TABLE TEST(ID INT PRIMARY KEY, PARENT INT, NAME VARCHAR(255)); - INSERT INTO TEST VALUES(1, NULL, 'Root'); - INSERT INTO TEST VALUES(2, 1, 'Plant'); - INSERT INTO TEST VALUES(3, 1, 'Animal'); - INSERT INTO TEST VALUES(4, 2, 'Tree'); - INSERT INTO TEST VALUES(5, 2, 'Flower'); - INSERT INTO TEST VALUES(6, 3, 'Elephant'); - INSERT INTO TEST VALUES(7, 3, 'Dog'); - - CREATE VIEW RECURSIVE TEST_REC(ID, PARENT, NAME) AS - SELECT ID, PARENT, NAME FROM TEST T - WHERE PARENT IS NULL - UNION ALL - SELECT T.ID, T.PARENT, T.NAME - FROM TEST T, TEST_REC R - WHERE T.PARENT=R.ID; - - SELECT * FROM TEST_REC; - ----------------- - - -CREATE LOCAL TEMPORARY TABLE test (family_name VARCHAR_IGNORECASE(63) NOT NULL); -INSERT INTO test VALUES('Smith'); -INSERT INTO test VALUES('de Smith'); -INSERT INTO test VALUES('el Smith'); -INSERT INTO test VALUES('von Smith'); -SELECT * FROM test WHERE family_name IN ('de Smith', 'Smith'); --- okay IN(...) with TABLE_SCAN - -SELECT * FROM test WHERE family_name BETWEEN 'd' AND 'T'; --- okay, ignorecase honoured - -SELECT * FROM test WHERE family_name BETWEEN 'D' AND 'T'; --- okay, ignorecase honoured - -CREATE INDEX family_name ON test(family_name); -SELECT * FROM test WHERE family_name IN ('de Smith', 'Smith'); --- OOPS, the comparison's operands are sorted incorrectly for ignorecase! - -EXPLAIN SELECT * FROM test WHERE family_name IN ('de Smith', 'Smith'); - - -------------------- - - -complete recursive views: - -drop all objects; -create table parent(id int primary key, parent int); -insert into parent values(1, null), (2, 1), (3, 1); - -with test_view(id, parent) as -select id, parent from parent where id = ? -union all -select parent.id, parent.parent from test_view, parent -where parent.parent = test_view.id -select * from test_view {1: 1}; - -drop view test_view; - -with test_view(id, parent) as -select id, parent from parent where id = 1 -union all -select parent.id, parent.parent from test_view, parent -where parent.parent = test_view.id -select * from test_view; - -drop view test_view; - -drop table parent; diff --git a/tools/h2/src/test/org/h2/test/todo/supportTemplates.txt b/tools/h2/src/test/org/h2/test/todo/supportTemplates.txt deleted file mode 100755 index 7b854d0..0000000 --- a/tools/h2/src/test/org/h2/test/todo/supportTemplates.txt +++ /dev/null @@ -1,200 +0,0 @@ - -Benchmark: - -Hi, - -If you are running benchmarks, could you profile them please? To do that use java -Xrunhprof:cpu=samples,depth=8 ... - and then upload/post the file java.hprof.txt - -If the benchmark application is not a self contained application, another way is to generate 'full thread dumps' (maybe 30 or so) while running the benchmark, and upload them? To get a full thread dump, you can use "kill -QUIT ", or (Windows) press Ctrl+Pause, or (Java 1.6) use jps -l to get the , and then use jstack . - -Regards, -Thomas - ------------------ - -Can not reproduce: - -Hi, - -Sorry I can not reproduce this problem. Could you post a simple, standalone test case that reproduces the problem? It would be great if the test case does not have any dependencies except the H2 jar file (that is, a simple SQL script that can be run in the H2 Console, or a Java class uses the JDBC API and is run using a static main method). If the test case does have dependencies it would help a lot if you upload them somewhere (for example Rapidshare.com). Please include any initialization code (CREATE TABLE, INSERT and so on) in the Java class or in a .sql script file. - -Regards, -Thomas - ------------------ - -Defect report: - -What steps will reproduce the problem? -(simple SQL scripts or simple standalone applications are preferred) -1. -2. -3. - -What is the expected output? What do you see instead? - - -What version of the product are you using? On what operating system, file system, and virtual machine? - - -Do you know a workaround? - -How important/urgent is the problem for you? - -In your view, is this a defect or a feature request? - -Please provide any additional information below. - ------------------ -Hi, - -This looks like a corrupt database. A workarounds is: use the tool org.h2.tools.Recover to create the SQL script file, and then re-create the database using this script. Does it work when you do this? - -As far as I see, you are using version 1.2.128. An important corruption problem was fixed in version 1.2.135 (see the change log). Known causes for corrupt databases are: - -- If the database was used with a version older than 1.2.135, and the process was killed while the database was closing or writing a checkpoint. - -- Using the transaction isolation level READ_UNCOMMITTED (LOCK_MODE 0) while at the same time using multiple connections. - -- Disabling database file protection using (setting FILE_LOCK to NO in the database URL). - -Some other areas that are not fully tested are: - -- Platforms other than Windows XP, Linux, Mac OS X, or JVMs other than Sun 1.5 or 1.6 - -- The feature MULTI_THREADED - -- The features AUTO_SERVER and AUTO_RECONNECT - -- The file locking method 'Serialized' - -Regards, -Thomas - ------------------ - - -This looks like a serious problem. I have a few questions: - -- Could you send the full stack trace of the exception including message text? -- What is your database URL? -- Did you use multiple connections? -- Do you use temporary tables? -- A workarounds is: use the tool org.h2.tools.Recover to create - the SQL script file, and then re-create the database using this script. - Does it work when you do this? -- With which version of H2 was this database created? - You can find it out using: - select * from information_schema.settings where name='CREATE_BUILD' - or have a look in the SQL script created by the recover tool. -- Did the application run out of memory (once, or multiple times)? -- Do you use any settings or special features (for example cache settings, - two phase commit, linked tables)? -- Do you use any H2-specific system properties? -- Is the application multi-threaded? -- What operating system, file system, and virtual machine - (java -version) do you use? -- How did you start the Java process (java -Xmx... and so on)? -- Is it (or was it at some point) a networked file system? -- How big is the database (file sizes)? -- How much heap memory does the Java process have? -- Is the database usually closed normally, or is process terminated - forcefully or the computer switched off? -- Is it possible to reproduce this problem using a fresh database - (sometimes, or always)? -- Are there any other exceptions (maybe in the .trace.db file)? - Could you send them please? -- Do you still have any .trace.db files, and if yes could you send them? -- Could you send the .h2.db file where this exception occurs? - ------------------ - - -Hi, - -I have a few questions: - -- The database URL? -- With which version of H2 was this database created? - You can find it out using: - select * from information_schema.settings where name='CREATE_BUILD' -- Did the application run out of memory (once, or multiple times)? -- Did you use multiple connections? -- Do you use any settings or special features (for example, the setting - LOG=0, or two phase commit, linked tables, cache settings)? -- Is the application multi-threaded? -- What operating system, file system, and virtual machine - (java -version) do you use? -- How big is the database (file sizes)? -- Is the database usually closed normally, or is process terminated - forcefully or the computer switched off? -- Are there any other exceptions (maybe in the .trace.db file)? - Could you send them please? -- Do you still have any .trace.db files, and if yes could you send them? -- Could you send the .h2.db file where this exception occurs? - - - - -Corrupted database - -I am sorry to say that, but it looks like a corruption problem. I am very interested in analyzing and solving this problem. Corruption problems have top priority for me. I have a few questions: - -- Could you send the full stack trace of the exception including message text? -- What is your database URL? -- Do you use Tomcat or another web server? - Do you unload or reload the web application? -- You can find out if the database is corrupted when running - SCRIPT TO 'test.sql' -- What version H2 are you using? -- Did you use multiple connections? -- The first workarounds is: append ;RECOVER=1 to the database URL. - Does it work when you do this? -- The second workarounds is: delete the index.db file (it is re-created - automatically) and try again. Does it work when you do this? -- The third workarounds is: use the tool org.h2.tools.Recover to create - the SQL script file, and then re-create the database using this script. - Does it work when you do this? -- With which version of H2 was this database created? - You can find it out using: - select * from information_schema.settings where name='CREATE_BUILD' -- Did the application run out of memory (once, or multiple times)? -- Do you use any settings or special features (for example, the setting - LOG=0, or two phase commit, linked tables, cache settings)? -- Is the application multi-threaded? -- What operating system, file system, and virtual machine - (java -version) do you use? -- Is it (or was it at some point) a networked file system? -- How big is the database (file sizes)? -- Is the database usually closed normally, or is process terminated - forcefully or the computer switched off? -- Is it possible to reproduce this problem using a fresh database - (sometimes, or always)? -- Are there any other exceptions (maybe in the .trace.db file)? - Could you send them please? -- Do you still have any .trace.db files, and if yes could you send them? -- Could you send the .data.db file where this exception occurs? - - - -Hi, - -I have a few questions: - -- The database URL? -- With which version of H2 was this database created? - You can find it out using: - select * from information_schema.settings where name='CREATE_BUILD' -- Did you use multiple connections? -- Do you use any settings or special features (for example, the setting - LOG=0, or two phase commit, linked tables, cache settings)? -- Is the application multi-threaded? -- What operating system, file system, and virtual machine - (java -version) do you use? -- How big is the database (file sizes)? -- Is the database usually closed normally, or is process terminated - forcefully or the computer switched off? -- Are there any other exceptions (maybe in the .trace.db file)? - Could you send them please? -- Do you still have any .trace.db files, and if yes could you send them? -- Could you send the .h2.db file where this exception occurs? diff --git a/tools/h2/src/test/org/h2/test/todo/todo.txt b/tools/h2/src/test/org/h2/test/todo/todo.txt deleted file mode 100755 index 3204420..0000000 --- a/tools/h2/src/test/org/h2/test/todo/todo.txt +++ /dev/null @@ -1,173 +0,0 @@ -Nested Outer Joins ------------------ -Example: -create table a(x int); -create table b(x int); -create table c(x int, y int); -insert into a values(1); -insert into a values(2); -insert into b values(3); -insert into c values(1, 3); -insert into c values(4, 5); -select * from a left outer join (b left outer join c on b.x = c.y) on a.x = c.x; -explain select * from a left outer join (b left outer join c on b.x = c.y) on a.x = c.x; -drop table a; -drop table b; -drop table c; - -The following doesn't work correctly: -TableFilter, - private void mapAndAddFilter(Expression on) throws SQLException { - on.mapColumns(this, 0); - if (join == null || on.isEverything(ExpressionVisitor.RESOLVED)) { - addFilterCondition(on, true); - on.createIndexConditions(session, this); - } - if (join != null) { - join.mapAndAddFilter(on); - } - } - - -drop table base; -drop table a; -drop table b; -create table a( pk integer, val varchar(255) ); -create table b( pk integer, val varchar(255) ); -create table base( pk integer, deleted integer ); -insert into base values ( 1, 0 ); -insert into base values ( 2, 1 ); -insert into base values ( 3, 0 ); -insert into a values ( 1, 'a' ); -insert into b values ( 2, 'a' ); -insert into b values ( 3, 'a' ); - -select a.pk, a_base.pk, b.pk, b_base.pk from a inner join base a_base -on a.pk = a_base.pk left outer join -( b inner join base b_base on b.pk = b_base.pk and b_base.deleted = 0 ) ; --- H2: --- 1 1 2 null --- 1 1 3 3 --- PostgreSQL: ERROR: syntax error at end of input 42601/0 --- MySQL: You have an error in your SQL syntax; --- check the manual that corresponds to your MySQL server version --- for the right syntax to use near '' at line 3 --- Derby: Syntax error: Encountered "" at line 3, column 71. 42X01/30000 --- HSQLDB: Unexpected token B, requires SELECT in statement - -select a.pk, a_base.pk, b.pk, b_base.pk from a inner join base a_base -on a.pk = a_base.pk left outer join -( b inner join base b_base on b.pk = b_base.pk and b_base.deleted = 0 ) -on a.pk = b.pk; --- H2, MySQL, PostgreSQL, Derby: --- 1 1 null null --- HSQLDB: Unexpected token B, requires SELECT in statement - -select a.pk, a_base.pk, b.pk, b_base.pk from a inner join base a_base -on a.pk = a_base.pk left outer join -( b inner join base b_base on b.pk = b_base.pk and b_base.deleted = 0 ) -on 1=1; --- H2: --- 1 1 2 null --- 1 1 3 3 --- PostgreSQL, MySQL, Derby: --- 1 1 3 3 --- HSQLDB: Unexpected token B, requires SELECT in statement - -select a.pk, a_base.pk, b_pk, b_base_pk from a inner join base a_base -on a.pk = a_base.pk left outer join -( select b.pk b_pk, b_base.pk b_base_pk from b inner join base b_base on b.pk = b_base.pk and b_base.deleted = 0 ) x -on 1=1; --- PostgreSQL, MySQL, Derby, H2: --- 1 1 3 3 - - -drop table test; -create table test(id int primary key); -@loop 3 insert into test values(?); -select * from test a left outer join (test b inner join test c on b.id = c.id - 2) on a.id = b.id + 1; -select * from test a left outer join (select b.id, c.id from test b inner join test c on b.id = c.id - 2) on a.id = b.id + 1; - - -Auto Upgrade ------------------ -file conversion should be done automatically when the new engine connects. - -auto-upgrade application: -check if new version is available -(option: digital signature) -if yes download new version -(option: http, https, ftp) -backup database to SQL script -(option: list of databases, use recovery mechanism) -install new version - -ftp client -task to download new version from another HTTP / HTTPS / FTP server -multi-task - - -Direct Lookup ------------------ -drop table test; -create table test(id int, version int, idx int); -@LOOP 1000 insert into test values(1, 1, ?); -@LOOP 1000 insert into test values(1, 2, ?); -@LOOP 1000 insert into test values(2, 1, ?); -create index idx_test on test(id, version, idx); -@LOOP 1000 select max(id)+1 from test; -@LOOP 1000 select max(idx)+1 from test where id=1 and version=2; -@LOOP 1000 select max(id)+1 from test; -@LOOP 1000 select max(idx)+1 from test where id=1 and version=2; -@LOOP 1000 select max(id)+1 from test; -@LOOP 1000 select max(idx)+1 from test where id=1 and version=2; --- should be direct query - - -Update Multiple Tables with Merge ------------------ -drop table statisticlog; -create table statisticlog(id int primary key, datatext varchar, moment int); -@LOOP 20000 insert into statisticlog values(?, ?, ?); -merge into statisticlog(id, datatext) key(id) -select id, 'data1' from statisticlog order by moment limit 5; -select * from statisticlog where id < 10; -UPDATE statisticlog SET datatext = 'data2' -WHERE id IN (SELECT id FROM statisticlog ORDER BY moment LIMIT 5); -select * from statisticlog where id < 10; - -Auto-Reconnect ------------------ -Implemented: -- auto_server includes auto_reconnect -- works with server mode -- works with auto_server mode -- keep temporary linked tables, variables on client -- statements -- prepared statements -- small result sets (up to fetch size) -- throws an error when autocommit is false -- an error is thrown when the connection is lost - while looping over large result sets (larger than fetch size) -Not implemented / not tested: -- batch updates -- ignored in embedded mode -- keep temporary tables (including data) on client -- keep identity, getGeneratedKeys on client -- throw error when in cluster mode - -Support Model ------------------ -Check JBoss and Spring support models -http://wiki.bonita.ow2.org/xwiki/bin/view/Main/BullOffer -- starting 2500 euros / year -- unlimited support requests -- 2 named contacts -- optional half days of technical aid by remote services - -Durability ------------------ -Improve documentation. -You can't make a system that will not lose data, you can only make -a system that knows the last save point of 100% integrity. There are -too many variables and too much randomness on a cold hard power failure. diff --git a/tools/h2/src/test/org/h2/test/todo/tools.sql b/tools/h2/src/test/org/h2/test/todo/tools.sql deleted file mode 100755 index bfc365b..0000000 --- a/tools/h2/src/test/org/h2/test/todo/tools.sql +++ /dev/null @@ -1,84 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ - --- TO_DATE -create alias TO_DATE as $$ -java.util.Date toDate(String s) throws Exception { - return new java.text.SimpleDateFormat("yyyy.MM.dd").parse(s); -} -$$; -call TO_DATE('1990.02.03') - --- TO_CHAR -drop alias if exists TO_CHAR; -create alias TO_CHAR as $$ -String toChar(BigDecimal x, String pattern) throws Exception { - return new java.text.DecimalFormat(pattern).format(x); -} -$$; -call TO_CHAR(123456789.12, '###,###,###,###.##'); - --- update all rows in all tables -select 'update ' || table_schema || '.' || table_name || ' set ' || column_name || '=' || column_name || ';' -from information_schema.columns where ORDINAL_POSITION = 1 and table_schema <> 'INFORMATION_SCHEMA'; - --- read the first few bytes from a BLOB -drop table test; -drop alias first_bytes; -create alias first_bytes as $$ -import java.io.*; -@CODE -byte[] firstBytes(InputStream in, int len) throws IOException { - try { - byte[] data = new byte[len]; - DataInputStream dIn = new DataInputStream(in); - dIn.readFully(data, 0, len); - return data; - } finally { - in.close(); - } -} -$$; -create table test(data blob); -insert into test values('010203040506070809'); -select first_bytes(data, 3) from test; - --- encrypt and decrypt strings -CALL CAST(ENCRYPT('AES', HASH('SHA256', STRINGTOUTF8('key'), 1), STRINGTOUTF8('Hello')) AS VARCHAR); -CALL TRIM(CHAR(0) FROM UTF8TOSTRING(DECRYPT('AES', HASH('SHA256', STRINGTOUTF8('key'), 1), '16e44604230717eec9f5fa6058e77e83'))); -DROP ALIAS ENC; -DROP ALIAS DEC; -CREATE ALIAS ENC AS $$ -import org.h2.security.*; -import org.h2.util.*; -@CODE -String encrypt(String data, String key) throws Exception { - byte[] k = new SHA256().getHash(key.getBytes("UTF-8"), false); - byte[] b1 = data.getBytes("UTF-8"); - byte[] buff = new byte[(b1.length + 15) / 16 * 16]; - System.arraycopy(b1, 0, buff, 0, b1.length); - BlockCipher bc = CipherFactory.getBlockCipher("AES"); - bc.setKey(k); - bc.encrypt(buff, 0, buff.length); - return ByteUtils.convertBytesToString(buff); -} -$$; -CREATE ALIAS DEC AS $$ -import org.h2.security.*; -import org.h2.util.*; -@CODE -String decrypt(String data, String key) throws Exception { - byte[] k = new SHA256().getHash(key.getBytes("UTF-8"), false); - byte[] buff = ByteUtils.convertStringToBytes(data); - BlockCipher bc = CipherFactory.getBlockCipher("AES"); - bc.setKey(k); - bc.decrypt(buff, 0, buff.length); - return StringUtils.trim(new String(buff, "UTF-8"), false, true, "\u0000"); -} -$$; -CALL ENC('Hello', 'key'); -CALL DEC(ENC('Hello', 'key'), 'key'); diff --git a/tools/h2/src/test/org/h2/test/todo/versionlist.txt b/tools/h2/src/test/org/h2/test/todo/versionlist.txt deleted file mode 100755 index 5a1bed5..0000000 --- a/tools/h2/src/test/org/h2/test/todo/versionlist.txt +++ /dev/null @@ -1,47 +0,0 @@ - -1.0.78 2008-08-28 -1.0.77 2008-08-16 -1.0.76 2008-07-27 -1.0.75 2008-07-14 -1.0.74 2008-06-21 -1.0.73 2008-05-31 -1.0.72 2008-05-10 -1.0.71 2008-04-25 -1.0.70 2008-04-20 -1.0.69 2008-03-29 -1.0.68 2008-03-15 -1.0.67 2008-02-22 -1.0.66 2008-02-02 -1.0.65 2008-01-18 -1.0.64 2007-12-27 -1.0.63 2007-12-02 -1.0.62 2007-11-25 -1.0.61 2007-11-10 -1.0.60 2007-10-20 -1.0.59 2007-10-03 -1.0.58 2007-09-15 -1.0.57 2007-08-25 - -1.0 2007-08-02 -1.0 2007-07-12 - -build 50 2007-06-17 -build 46 2007-04-29 -build 41 2007-01-30 -build 2007-01-17 -build 34 2006-12-17 -build 2006-12-03 -build 2006-11-20 -build 2006-11-03 -build 2006-10-10 -build 2006-09-24 -build 2006-09-10 -build 2006-08-31 -build 2006-08-28 -build 2006-08-23 -build 2006-08-14 -build 2006-07-29 -build 2006-07-14 -build 2006-07-01 -build 10 2006-06-02 -alpha 2005-11-17 \ No newline at end of file diff --git a/tools/h2/src/test/org/h2/test/trace/Arg.java b/tools/h2/src/test/org/h2/test/trace/Arg.java deleted file mode 100755 index 957a0be..0000000 --- a/tools/h2/src/test/org/h2/test/trace/Arg.java +++ /dev/null @@ -1,88 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - */ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.h2.test.trace; - -import java.math.BigDecimal; - -import org.h2.util.StringUtils; - -/** - * An argument of a statement. - */ -class Arg { - private Class< ? > clazz; - private Object obj; - private Statement stat; - - Arg(Class< ? > clazz, Object obj) { - this.clazz = clazz; - this.obj = obj; - } - - Arg(Statement stat) { - this.stat = stat; - } - - public String toString() { - if (stat != null) { - return stat.toString(); - } - return quote(clazz, getValue()); - } - - /** - * Calculate the value if this is a statement. - */ - void execute() throws Exception { - if (stat != null) { - obj = stat.execute(); - clazz = stat.getReturnClass(); - stat = null; - } - } - - Class< ? > getValueClass() { - return clazz; - } - - Object getValue() { - return obj; - } - - private String quote(Class< ? > valueClass, Object value) { - if (value == null) { - return null; - } else if (valueClass == String.class) { - return StringUtils.quoteJavaString(value.toString()); - } else if (valueClass == BigDecimal.class) { - return "new BigDecimal(\"" + value.toString() + "\")"; - } else if (valueClass.isArray()) { - if (valueClass == String[].class) { - return StringUtils.quoteJavaStringArray((String[]) value); - } else if (valueClass == int[].class) { - return StringUtils.quoteJavaIntArray((int[]) value); - } - } - return value.toString(); - } - -} diff --git a/tools/h2/src/test/org/h2/test/trace/Parser.java b/tools/h2/src/test/org/h2/test/trace/Parser.java deleted file mode 100755 index cdc5131..0000000 --- a/tools/h2/src/test/org/h2/test/trace/Parser.java +++ /dev/null @@ -1,280 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - */ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.h2.test.trace; - -import java.math.BigDecimal; -import java.util.ArrayList; - -import org.h2.util.New; -import org.h2.util.StringUtils; - -/** - * Parses an entry in a Java-style log file. - */ -class Parser { - private static final int STRING = 0, NAME = 1, NUMBER = 2, SPECIAL = 3; - private Player player; - private Statement stat; - private String line; - private String token; - private int tokenType; - private int pos; - - private Parser(Player player, String line) { - this.player = player; - this.line = line; - read(); - } - - /** - * Parse a Java statement. - * - * @param player the player - * @param line the statement text - * @return the statement - */ - static Statement parseStatement(Player player, String line) { - Parser p = new Parser(player, line); - p.parseStatement(); - return p.stat; - } - - private Statement parseStatement() { - stat = new Statement(player); - String name = readToken(); - Object o = player.getObject(name); - if (o == null) { - if (readIf(".")) { - // example: java.lang.System.exit(0); - parseStaticCall(name); - } else { - // example: Statement s1 = ... - stat.setAssign(name, readToken()); - read("="); - name = readToken(); - o = player.getObject(name); - if (o != null) { - // example: ... = s1.executeQuery(); - read("."); - parseCall(name, o, readToken()); - } else if (readIf(".")) { - // ... = x.y.z("..."); - parseStaticCall(name); - } - } - } else { - // example: s1.execute() - read("."); - String methodName = readToken(); - parseCall(name, o, methodName); - } - return stat; - } - - private void read() { - while (line.charAt(pos) == ' ') { - pos++; - } - int start = pos; - char ch = line.charAt(pos); - switch (ch) { - case '\"': - tokenType = STRING; - pos++; - while (pos < line.length()) { - ch = line.charAt(pos); - if (ch == '\\') { - pos += 2; - } else if (ch == '\"') { - pos++; - break; - } else { - pos++; - } - } - break; - case '.': - case ',': - case '(': - case ')': - case ';': - case '{': - case '}': - case '[': - case ']': - case '=': - tokenType = SPECIAL; - pos++; - break; - default: - if (Character.isLetter(ch) || ch == '_') { - tokenType = NAME; - pos++; - while (true) { - ch = line.charAt(pos); - if (Character.isLetterOrDigit(ch) || ch == '_') { - pos++; - } else { - break; - } - } - } else if (ch == '-' || Character.isDigit(ch)) { - tokenType = NUMBER; - pos++; - while (true) { - ch = line.charAt(pos); - if (Character.isDigit(ch) - || ".+-eElLxabcdefABCDEF".indexOf(ch) >= 0) { - pos++; - } else { - break; - } - } - } - } - token = line.substring(start, pos); - } - - private boolean readIf(String s) { - if (token.equals(s)) { - read(); - return true; - } - return false; - } - - private String readToken() { - String s = token; - read(); - return s; - } - - private void read(String s) { - if (!readIf(s)) { - throw new RuntimeException("Expected: " + s + " got: " + token + " in " - + line); - } - } - - private Arg parseValue() { - if (tokenType == STRING) { - String s = readToken(); - s = StringUtils.javaDecode(s.substring(1, s.length() - 1)); - return new Arg(String.class, s); - } else if (tokenType == NUMBER) { - String number = readToken().toLowerCase(); - if (number.endsWith("f")) { - Float v = new Float(Float.parseFloat(number)); - return new Arg(float.class, v); - } else if (number.endsWith("d") || number.indexOf("e") >= 0 || number.indexOf(".") >= 0) { - Double v = new Double(Double.parseDouble(number)); - return new Arg(double.class, v); - } else if (number.endsWith("L") || number.endsWith("l")) { - Long v = new Long(Long.parseLong(number.substring(0, number.length() - 1))); - return new Arg(long.class, v); - } else { - Integer v = new Integer(Integer.parseInt(number)); - return new Arg(int.class, v); - } - } else if (tokenType == NAME) { - if (readIf("true")) { - return new Arg(boolean.class, Boolean.TRUE); - } else if (readIf("false")) { - return new Arg(boolean.class, Boolean.FALSE); - } else if (readIf("null")) { - throw new RuntimeException( - "Null: class not specified. Example: (java.lang.String)null"); - } else if (readIf("new")) { - if (readIf("String")) { - read("["); - read("]"); - read("{"); - ArrayList values = New.arrayList(); - do { - values.add(parseValue().getValue()); - } while (readIf(",")); - read("}"); - String[] list = new String[values.size()]; - values.toArray(list); - return new Arg(String[].class, list); - } else if (readIf("BigDecimal")) { - read("("); - BigDecimal value = new BigDecimal((String) parseValue().getValue()); - read(")"); - return new Arg(BigDecimal.class, value); - } else { - throw new RuntimeException("Unsupported constructor: " + readToken()); - } - } - String name = readToken(); - Object obj = player.getObject(name); - if (obj != null) { - return new Arg(obj.getClass(), obj); - } - read("."); - Statement outer = stat; - stat = new Statement(player); - parseStaticCall(name); - Arg s = new Arg(stat); - stat = outer; - return s; - } else if (readIf("(")) { - read("short"); - read(")"); - String number = readToken(); - return new Arg(short.class, new Short(Short.parseShort(number))); - } else { - throw new RuntimeException("Value expected, got: " + readToken() + " in " - + line); - } - } - - private void parseCall(String objectName, Object o, String methodName) { - stat.setMethodCall(objectName, o, methodName); - ArrayList args = New.arrayList(); - read("("); - while (true) { - if (readIf(")")) { - break; - } - Arg p = parseValue(); - args.add(p); - if (readIf(")")) { - break; - } - read(","); - } - stat.setArgs(args); - } - - private void parseStaticCall(String clazz) { - String last = readToken(); - while (readIf(".")) { - clazz += last == null ? "" : "." + last; - last = readToken(); - } - String methodName = last; - stat.setStaticCall(clazz); - parseCall(null, null, methodName); - } - -} diff --git a/tools/h2/src/test/org/h2/test/trace/Player.java b/tools/h2/src/test/org/h2/test/trace/Player.java deleted file mode 100755 index 008df2e..0000000 --- a/tools/h2/src/test/org/h2/test/trace/Player.java +++ /dev/null @@ -1,179 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - */ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.h2.test.trace; - -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStreamReader; -import java.io.LineNumberReader; -import java.util.HashMap; -import org.h2.util.IOUtils; -import org.h2.util.New; - -/** - * This tool can re-run Java style log files. There is no size limit. - */ -public class Player { - - // TODO support InputStream; - // TODO support Reader; - // TODO support int[]; - // TODO support Blob and Clob; - // TODO support Calendar - // TODO support Object - // TODO support Object[] - // TODO support URL - // TODO support Array - // TODO support Ref - // TODO support SQLInput, SQLOutput - // TODO support Properties - // TODO support Map - // TODO support SQLXML - - private static final String[] IMPORTED_PACKAGES = { "", "java.lang.", "java.sql.", "javax.sql." }; - private boolean trace; - private HashMap objects = New.hashMap(); - - /** - * Execute a trace file using the command line. The log file name to execute - * (replayed) must be specified as the last parameter. The following - * optional command line parameters are supported: - *
      - *
    • -log to enable logging the executed statement to - * System.out - *
    - * - * @param args the arguments of the application - */ - public static void main(String... args) throws IOException { - new Player().run(args); - } - - /** - * Execute a trace file. - * - * @param fileName the file name - * @param trace print debug information - */ - public static void execute(String fileName, boolean trace) throws IOException { - Player player = new Player(); - player.trace = trace; - player.runFile(fileName); - } - - private void run(String... args) throws IOException { - String fileName = "test.log.db"; - try { - fileName = args[args.length - 1]; - for (int i = 0; i < args.length - 1; i++) { - if ("-trace".equals(args[i])) { - trace = true; - } else { - throw new RuntimeException("Unknown setting: " + args[i]); - } - } - } catch (Exception e) { - e.printStackTrace(); - System.out.println("Usage: java " + getClass().getName() - + " [-trace] "); - return; - } - runFile(fileName); - } - - private void runFile(String fileName) throws IOException { - LineNumberReader reader = new LineNumberReader(new BufferedReader( - new InputStreamReader(IOUtils.openFileInputStream(fileName)))); - while (true) { - String line = reader.readLine(); - if (line == null) { - break; - } - runLine(line.trim()); - } - } - - /** - * Write trace information if trace is enabled. - * - * @param s the message to write - */ - void trace(String s) { - if (trace) { - System.out.println(s); - } - } - - private void runLine(String line) { - if (!line.startsWith("/**/")) { - return; - } - line = line.substring("/**/".length()) + ";"; - Statement s = Parser.parseStatement(this, line); - trace("> " + s.toString()); - try { - s.execute(); - } catch (Exception e) { - e.printStackTrace(); - trace("error: " + e.toString()); - } - } - - /** - * Get the class for the given class name. - * Only a limited set of classes is supported. - * - * @param className the class name - * @return the class - */ - static Class< ? > getClass(String className) { - for (String s : IMPORTED_PACKAGES) { - try { - return Class.forName(s + className); - } catch (ClassNotFoundException e) { - // ignore - } - } - throw new RuntimeException("Class not found: " + className); - } - - /** - * Assign an object to a variable. - * - * @param variableName the variable name - * @param obj the object - */ - void assign(String variableName, Object obj) { - objects.put(variableName, obj); - } - - /** - * Get an object. - * - * @param name the variable name - * @return the object - */ - Object getObject(String name) { - return objects.get(name); - } - -} diff --git a/tools/h2/src/test/org/h2/test/trace/Statement.java b/tools/h2/src/test/org/h2/test/trace/Statement.java deleted file mode 100755 index 14569a8..0000000 --- a/tools/h2/src/test/org/h2/test/trace/Statement.java +++ /dev/null @@ -1,168 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - */ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.h2.test.trace; - -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; -import java.util.ArrayList; - -/** - * A statement in a Java-style log file. - */ -class Statement { - private Player player; - private boolean assignment; - private boolean staticCall; - private String assignClass; - private String assignVariable; - private String staticCallClass; - private String objectName; - private Object object; - private String methodName; - private Arg[] args; - private Class< ? > returnClass; - - Statement(Player player) { - this.player = player; - } - - /** - * Execute the statement. - * - * @return the object returned if this was a method call - */ - Object execute() throws Exception { - if (object == player) { - // there was an exception previously - player.trace("> " + assignVariable + " not set"); - if (assignment) { - player.assign(assignVariable, player); - } - return null; - } - Class< ? > clazz; - if (staticCall) { - clazz = Player.getClass(staticCallClass); - } else { - clazz = object.getClass(); - } - Class< ? >[] parameterTypes = new Class[args.length]; - Object[] parameters = new Object[args.length]; - for (int i = 0; i < args.length; i++) { - Arg arg = args[i]; - arg.execute(); - parameterTypes[i] = arg.getValueClass(); - parameters[i] = arg.getValue(); - } - Method method = clazz.getMethod(methodName, parameterTypes); - returnClass = method.getReturnType(); - try { - Object obj = method.invoke(object, parameters); - if (assignment) { - player.assign(assignVariable, obj); - } - return obj; - } catch (IllegalArgumentException e) { - e.printStackTrace(); - } catch (IllegalAccessException e) { - e.printStackTrace(); - } catch (InvocationTargetException e) { - Throwable t = e.getTargetException(); - player.trace("> " + t.toString()); - if (assignment) { - player.assign(assignVariable, player); - } - } - return null; - } - - public String toString() { - StringBuilder buff = new StringBuilder(); - if (assignment) { - buff.append(assignClass); - buff.append(' '); - buff.append(assignVariable); - buff.append('='); - } - if (staticCall) { - buff.append(staticCallClass); - } else { - buff.append(objectName); - } - buff.append('.'); - buff.append(methodName); - buff.append('('); - for (int i = 0; args != null && i < args.length; i++) { - if (i > 0) { - buff.append(", "); - } - buff.append(args[i].toString()); - } - buff.append(");"); - return buff.toString(); - } - - Class< ? > getReturnClass() { - return returnClass; - } - - /** - * This statement is an assignment. - * - * @param className the class of the variable - * @param variableName the variable name - */ - void setAssign(String className, String variableName) { - this.assignment = true; - this.assignClass = className; - this.assignVariable = variableName; - } - - /** - * This statement is a static method call. - * - * @param className the class name - */ - void setStaticCall(String className) { - this.staticCall = true; - this.staticCallClass = className; - } - - /** - * This statement is a method call, and the result is assigned to a - * variable. - * - * @param variableName the variable name - * @param object the object - * @param methodName the method name - */ - void setMethodCall(String variableName, Object object, String methodName) { - this.objectName = variableName; - this.object = object; - this.methodName = methodName; - } - - public void setArgs(ArrayList list) { - args = new Arg[list.size()]; - list.toArray(args); - } -} diff --git a/tools/h2/src/test/org/h2/test/trace/package.html b/tools/h2/src/test/org/h2/test/trace/package.html deleted file mode 100755 index 951bc4f..0000000 --- a/tools/h2/src/test/org/h2/test/trace/package.html +++ /dev/null @@ -1,15 +0,0 @@ - - - - -Javadoc package documentation -

    - -A player to interpret and execute Java statements in a trace file. - -

    \ No newline at end of file diff --git a/tools/h2/src/test/org/h2/test/unit/FileObjectDatabase.java b/tools/h2/src/test/org/h2/test/unit/FileObjectDatabase.java deleted file mode 100755 index 718ef0a..0000000 --- a/tools/h2/src/test/org/h2/test/unit/FileObjectDatabase.java +++ /dev/null @@ -1,93 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.test.unit; - -import java.io.EOFException; -import java.io.IOException; - -import org.h2.store.fs.FileObject; -import org.h2.util.Utils; - -/** - * In this file system, files are kept fully in memory until stored. - */ -public class FileObjectDatabase implements FileObject { - - private FileSystemDatabase db; - private String fileName; - private byte[] data; - private int pos, length; - private boolean changed; - - FileObjectDatabase(FileSystemDatabase db, String fileName, byte[] data, boolean changed) { - this.db = db; - this.fileName = fileName; - this.data = data; - this.length = data.length; - this.changed = changed; - } - - public void close() { - sync(); - } - - public long getFilePointer() { - return pos; - } - - public long length() { - return length; - } - - public void readFully(byte[] b, int off, int len) throws IOException { - if (pos + len > length) { - throw new EOFException(); - } - System.arraycopy(data, pos, b, off, len); - pos += len; - } - - public void seek(long newPos) { - this.pos = (int) newPos; - } - - public void setFileLength(long newLength) { - this.length = (int) newLength; - if (length != data.length) { - byte[] n = Utils.newBytes(length); - System.arraycopy(data, 0, n, 0, Math.min(data.length, n.length)); - data = n; - changed = true; - } - pos = Math.min(pos, length); - } - - public void sync() { - if (changed) { - db.write(fileName, data, length); - changed = false; - } - } - - public void write(byte[] b, int off, int len) { - if (pos + len > data.length) { - int newLen = Math.max(data.length * 2, pos + len); - byte[] n = Utils.newBytes(newLen); - System.arraycopy(data, 0, n, 0, length); - data = n; - } - System.arraycopy(b, off, data, pos, len); - pos += len; - length = Math.max(length, pos); - changed = true; - } - - public String getName() { - return fileName; - } - -} diff --git a/tools/h2/src/test/org/h2/test/unit/FileSystemDatabase.java b/tools/h2/src/test/org/h2/test/unit/FileSystemDatabase.java deleted file mode 100755 index c53993b..0000000 --- a/tools/h2/src/test/org/h2/test/unit/FileSystemDatabase.java +++ /dev/null @@ -1,465 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.test.unit; - -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.sql.Connection; -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.sql.Statement; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.Properties; - -import org.h2.Driver; -import org.h2.message.DbException; -import org.h2.store.fs.FileObject; -import org.h2.store.fs.FileObjectInputStream; -import org.h2.store.fs.FileObjectOutputStream; -import org.h2.store.fs.FileSystem; -import org.h2.util.IOUtils; -import org.h2.util.JdbcUtils; -import org.h2.util.New; -import org.h2.util.StringUtils; - -/** - * This file system stores everything in a database. - */ -public class FileSystemDatabase extends FileSystem { - - private Connection conn; - private String url; - private HashMap preparedMap = New.hashMap(); - private boolean log; - - private FileSystemDatabase(String url, Connection conn, boolean log) throws SQLException { - this.url = url; - this.conn = conn; - this.log = log; - Statement stat = conn.createStatement(); - conn.setAutoCommit(false); - stat.execute("SET ALLOW_LITERALS NONE"); - stat.execute("CREATE TABLE IF NOT EXISTS FILES(" - + "ID IDENTITY, PARENTID BIGINT, NAME VARCHAR, " - + "LASTMODIFIED BIGINT, LENGTH BIGINT, " - + "UNIQUE(PARENTID, NAME))"); - stat.execute("CREATE TABLE IF NOT EXISTS FILEDATA(" - + "ID BIGINT PRIMARY KEY, DATA BLOB)"); - PreparedStatement prep = conn.prepareStatement("SET MAX_LENGTH_INPLACE_LOB ?"); - prep.setLong(1, 4096); - prep.execute(); - stat.execute("MERGE INTO FILES VALUES(ZERO(), NULL, SPACE(ZERO()), ZERO(), NULL)"); - commit(); - if (log) { - ResultSet rs = stat.executeQuery("SELECT * FROM FILES ORDER BY PARENTID, NAME"); - while (rs.next()) { - long id = rs.getLong("ID"); - long parentId = rs.getLong("PARENTID"); - String name = rs.getString("NAME"); - long lastModified = rs.getLong("LASTMODIFIED"); - long length = rs.getLong("LENGTH"); - log(id + " " + name + " parent:" + parentId + " length:" + length + " lastMod:" - + lastModified); - } - } - } - - protected boolean accepts(String fileName) { - return fileName.startsWith(url); - } - - public static synchronized FileSystemDatabase register(String url) { - Connection conn; - try { - if (url.startsWith("jdbc:h2:")) { - // avoid using DriverManager if possible - conn = Driver.load().connect(url, new Properties()); - } else { - conn = JdbcUtils.getConnection(null, url, new Properties()); - } - boolean log = url.toUpperCase().indexOf("TRACE_") >= 0; - FileSystemDatabase fs = new FileSystemDatabase(url, conn, log); - FileSystem.register(fs); - return fs; - } catch (SQLException e) { - throw new RuntimeException(e); - } - } - - /** - * Close the underlying database and unregister the file system. - */ - public void unregister() { - JdbcUtils.closeSilently(conn); - FileSystem.unregister(this); - } - - private void commit() { - try { - conn.commit(); - } catch (SQLException e) { - if (log) { - e.printStackTrace(); - } - } - } - - private void rollback() { - try { - conn.rollback(); - } catch (SQLException e) { - if (log) { - e.printStackTrace(); - } - } - } - - private void log(String s) { - if (log) { - System.out.println(s); - } - } - - private long getId(String fileName, boolean parent) { - fileName = translateFileName(fileName); - log(fileName); - try { - String[] path = StringUtils.arraySplit(fileName, '/', false); - long id = 0; - int len = parent ? path.length - 1 : path.length; - if (fileName.endsWith("/")) { - len--; - } - for (int i = 1; i < len; i++) { - PreparedStatement prep = prepare("SELECT ID FROM FILES WHERE PARENTID=? AND NAME=?"); - prep.setLong(1, id); - prep.setString(2, path[i]); - ResultSet rs = prep.executeQuery(); - if (!rs.next()) { - return -1; - } - id = rs.getLong(1); - } - return id; - } catch (SQLException e) { - throw convert(e); - } - } - - private String translateFileName(String fileName) { - if (fileName.startsWith(url)) { - fileName = fileName.substring(url.length()); - } - return fileName; - } - - private PreparedStatement prepare(String sql) throws SQLException { - PreparedStatement prep = preparedMap.get(sql); - if (prep == null) { - prep = conn.prepareStatement(sql); - preparedMap.put(sql, prep); - } - return prep; - } - - private RuntimeException convert(SQLException e) { - if (log) { - e.printStackTrace(); - } - return new RuntimeException(e.toString(), e); - } - - public boolean canWrite(String fileName) { - return true; - } - - public void copy(String original, String copy) { - try { - OutputStream out = openFileOutputStream(copy, false); - InputStream in = openFileInputStream(original); - IOUtils.copyAndClose(in, out); - } catch (IOException e) { - rollback(); - throw DbException.convertIOException(e, "Can not copy " + original + " to " + copy); - } - } - - public void createDirs(String fileName) { - fileName = translateFileName(fileName); - try { - String[] path = StringUtils.arraySplit(fileName, '/', false); - long parentId = 0; - int len = path.length; - if (fileName.endsWith("/")) { - len--; - } - len--; - for (int i = 1; i < len; i++) { - PreparedStatement prep = prepare("SELECT ID FROM FILES WHERE PARENTID=? AND NAME=?"); - prep.setLong(1, parentId); - prep.setString(2, path[i]); - ResultSet rs = prep.executeQuery(); - if (!rs.next()) { - prep = prepare("INSERT INTO FILES(NAME, PARENTID, LASTMODIFIED) VALUES(?, ?, ?)"); - prep.setString(1, path[i]); - prep.setLong(2, parentId); - prep.setLong(3, System.currentTimeMillis()); - prep.execute(); - rs = prep.getGeneratedKeys(); - rs.next(); - parentId = rs.getLong(1); - } else { - parentId = rs.getLong(1); - } - } - commit(); - } catch (SQLException e) { - rollback(); - throw convert(e); - } - } - - public boolean createNewFile(String fileName) { - try { - if (exists(fileName)) { - return false; - } - openFileObject(fileName, "rw").close(); - return true; - } catch (IOException e) { - throw DbException.convertIOException(e, fileName); - } - } - - public synchronized void delete(String fileName) { - try { - long id = getId(fileName, false); - PreparedStatement prep = prepare("DELETE FROM FILES WHERE ID=?"); - prep.setLong(1, id); - prep.execute(); - prep = prepare("DELETE FROM FILEDATA WHERE ID=?"); - prep.setLong(1, id); - prep.execute(); - commit(); - } catch (SQLException e) { - rollback(); - throw convert(e); - } - } - - public void deleteRecursive(String fileName, boolean tryOnly) { - throw DbException.getUnsupportedException("db"); - } - - public boolean exists(String fileName) { - long id = getId(fileName, false); - return id >= 0; - } - - public boolean fileStartsWith(String fileName, String prefix) { - fileName = translateFileName(fileName); - return fileName.startsWith(prefix); - } - - public String getAbsolutePath(String fileName) { - return fileName; - } - - public String getFileName(String fileName) { - fileName = translateFileName(fileName); - String[] path = StringUtils.arraySplit(fileName, '/', false); - return path[path.length - 1]; - } - - public synchronized long getLastModified(String fileName) { - try { - long id = getId(fileName, false); - PreparedStatement prep = prepare("SELECT LASTMODIFIED FROM FILES WHERE ID=?"); - prep.setLong(1, id); - ResultSet rs = prep.executeQuery(); - rs.next(); - return rs.getLong(1); - } catch (SQLException e) { - throw convert(e); - } - } - - public String getParent(String fileName) { - int idx = Math.max(fileName.indexOf(':'), fileName.lastIndexOf('/')); - return fileName.substring(0, idx); - } - - public boolean isAbsolute(String fileName) { - return true; - } - - public synchronized boolean isDirectory(String fileName) { - try { - long id = getId(fileName, false); - PreparedStatement prep = prepare("SELECT LENGTH FROM FILES WHERE ID=?"); - prep.setLong(1, id); - ResultSet rs = prep.executeQuery(); - rs.next(); - rs.getLong(1); - return rs.wasNull(); - } catch (SQLException e) { - throw convert(e); - } - } - - public boolean isReadOnly(String fileName) { - return false; - } - - public boolean setReadOnly(String fileName) { - return false; - } - - public synchronized long length(String fileName) { - try { - long id = getId(fileName, false); - PreparedStatement prep = prepare("SELECT LENGTH FROM FILES WHERE ID=?"); - prep.setLong(1, id); - ResultSet rs = prep.executeQuery(); - rs.next(); - return rs.getLong(1); - } catch (SQLException e) { - throw convert(e); - } - } - - public synchronized String[] listFiles(String path) { - try { - String name = path; - if (!name.endsWith("/")) { - name += "/"; - } - long id = getId(path, false); - PreparedStatement prep = prepare("SELECT NAME FROM FILES WHERE PARENTID=? ORDER BY NAME"); - prep.setLong(1, id); - ResultSet rs = prep.executeQuery(); - ArrayList list = New.arrayList(); - while (rs.next()) { - list.add(name + rs.getString(1)); - } - String[] result = new String[list.size()]; - list.toArray(result); - return result; - } catch (SQLException e) { - throw convert(e); - } - } - - public String normalize(String fileName) { - return fileName; - } - - public InputStream openFileInputStream(String fileName) throws IOException { - return new FileObjectInputStream(openFileObject(fileName, "r")); - } - - public FileObject openFileObject(String fileName, String mode) throws IOException { - try { - long id = getId(fileName, false); - PreparedStatement prep = prepare("SELECT DATA FROM FILEDATA WHERE ID=?"); - prep.setLong(1, id); - ResultSet rs = prep.executeQuery(); - if (rs.next()) { - InputStream in = rs.getBinaryStream(1); - ByteArrayOutputStream out = new ByteArrayOutputStream(); - IOUtils.copyAndClose(in, out); - byte[] data = out.toByteArray(); - return new FileObjectDatabase(this, fileName, data, false); - } - return new FileObjectDatabase(this, fileName, new byte[0], true); - } catch (SQLException e) { - throw convert(e); - } - } - - public OutputStream openFileOutputStream(String fileName, boolean append) { - try { - return new FileObjectOutputStream(openFileObject(fileName, "rw"), append); - } catch (IOException e) { - throw DbException.convertIOException(e, fileName); - } - } - - public synchronized void rename(String oldName, String newName) { - try { - long parentOld = getId(oldName, true); - long parentNew = getId(newName, true); - if (parentOld != parentNew) { - throw DbException.getUnsupportedException("different parents"); - } - newName = getFileName(newName); - long id = getId(oldName, false); - PreparedStatement prep = prepare("UPDATE FILES SET NAME=? WHERE ID=?"); - prep.setString(1, newName); - prep.setLong(2, id); - prep.execute(); - commit(); - } catch (SQLException e) { - rollback(); - throw convert(e); - } - } - - public boolean tryDelete(String fileName) { - delete(fileName); - return true; - } - - /** - * Update a file in the file system. - * - * @param fileName the file name - * @param b the data - * @param len the number of bytes - */ - synchronized void write(String fileName, byte[] b, int len) { - try { - long id = getId(fileName, false); - if (id >= 0) { - PreparedStatement prep = prepare("DELETE FROM FILES WHERE ID=?"); - prep.setLong(1, id); - prep.execute(); - prep = prepare("DELETE FROM FILEDATA WHERE ID=?"); - prep.setLong(1, id); - prep.execute(); - } - long parentId = getId(fileName, true); - PreparedStatement prep = prepare("INSERT INTO FILES(PARENTID, NAME, LASTMODIFIED) VALUES(?, ?, ?)"); - prep.setLong(1, parentId); - prep.setString(2, getFileName(fileName)); - prep.setLong(3, System.currentTimeMillis()); - prep.execute(); - ResultSet rs = prep.getGeneratedKeys(); - rs.next(); - id = rs.getLong(1); - prep = prepare("INSERT INTO FILEDATA(ID, DATA) VALUES(?, ?)"); - prep.setLong(1, id); - ByteArrayInputStream in = new ByteArrayInputStream(b, 0, len); - prep.setBinaryStream(2, in, -1); - prep.execute(); - prep = prepare("UPDATE FILES SET LENGTH=(SELECT LENGTH(DATA) FROM FILEDATA WHERE ID=?) WHERE ID=?"); - prep.setLong(1, id); - prep.setLong(2, id); - prep.execute(); - commit(); - } catch (SQLException e) { - rollback(); - throw convert(e); - } - } - -} diff --git a/tools/h2/src/test/org/h2/test/unit/TestAutoReconnect.java b/tools/h2/src/test/org/h2/test/unit/TestAutoReconnect.java deleted file mode 100755 index 3381cb3..0000000 --- a/tools/h2/src/test/org/h2/test/unit/TestAutoReconnect.java +++ /dev/null @@ -1,184 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.test.unit; - -import java.sql.Connection; -import java.sql.DriverManager; -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.sql.Statement; -import org.h2.api.DatabaseEventListener; -import org.h2.test.TestBase; -import org.h2.tools.Server; - -/** - * Tests automatic embedded/server mode. - */ -public class TestAutoReconnect extends TestBase implements DatabaseEventListener { - - private String url; - private boolean autoServer; - private Server server; - private Connection connServer; - private Connection conn; - - /** - * Run just this test. - * - * @param a ignored - */ - public static void main(String... a) throws Exception { - TestBase.createCaller().init().test(); - } - - private void restart() throws SQLException { - if (autoServer) { - if (connServer != null) { - connServer.createStatement().execute("SHUTDOWN"); - connServer.close(); - } - org.h2.Driver.load(); - connServer = DriverManager.getConnection(url); - } else { - server.stop(); - server.start(); - } - } - - public void test() throws Exception { - autoServer = true; - testReconnect(); - autoServer = false; - testReconnect(); - deleteDb("autoReconnect"); - } - - private void testReconnect() throws Exception { - deleteDb("autoReconnect"); - if (autoServer) { - url = "jdbc:h2:" + getBaseDir() + "/autoReconnect;" + - "FILE_LOCK=SOCKET;" + - "AUTO_SERVER=TRUE;OPEN_NEW=TRUE"; - restart(); - } else { - server = Server.createTcpServer("-tcpPort", "8181").start(); - url = "jdbc:h2:tcp://localhost:8181/" + getBaseDir() + "/autoReconnect;" + - "FILE_LOCK=SOCKET;AUTO_RECONNECT=TRUE"; - } - - // test the database event listener - conn = DriverManager.getConnection(url + ";DATABASE_EVENT_LISTENER='" + getClass().getName() + "'"); - conn.close(); - - Statement stat; - - conn = DriverManager.getConnection(url); - restart(); - stat = conn.createStatement(); - restart(); - stat.execute("create table test(id identity, name varchar)"); - restart(); - PreparedStatement prep = conn.prepareStatement("insert into test values(null, ?)"); - restart(); - prep.setString(1, "Hello"); - restart(); - prep.execute(); - restart(); - prep.setString(1, "World"); - restart(); - prep.execute(); - restart(); - ResultSet rs = stat.executeQuery("select * from test order by id"); - restart(); - assertTrue(rs.next()); - restart(); - assertEquals(1, rs.getInt(1)); - restart(); - assertEquals("Hello", rs.getString(2)); - restart(); - assertTrue(rs.next()); - restart(); - assertEquals(2, rs.getInt(1)); - restart(); - assertEquals("World", rs.getString(2)); - restart(); - assertFalse(rs.next()); - restart(); - stat.execute("SET @TEST 10"); - restart(); - rs = stat.executeQuery("CALL @TEST"); - rs.next(); - assertEquals(10, rs.getInt(1)); - stat.setFetchSize(10); - restart(); - rs = stat.executeQuery("select * from system_range(1, 20)"); - restart(); - for (int i = 0;; i++) { - try { - boolean more = rs.next(); - if (!more) { - assertEquals(i, 20); - break; - } - restart(); - int x = rs.getInt(1); - assertEquals(x, i + 1); - if (i > 10) { - fail(); - } - } catch (SQLException e) { - if (i < 10) { - throw e; - } - } - } - restart(); - rs.close(); - - conn.setAutoCommit(false); - restart(); - try { - conn.createStatement().execute("select * from test"); - fail(); - } catch (SQLException e) { - assertKnownException(e); - } - - conn.close(); - if (autoServer) { - connServer.close(); - } else { - server.stop(); - } - } - - public void closingDatabase() { - // ignore - } - - public void diskSpaceIsLow() { - // ignore - } - - public void exceptionThrown(SQLException e, String sql) { - // ignore - } - - public void init(String u) { - // ignore - } - - public void opened() { - // ignore - } - - public void setProgress(int state, String name, int x, int max) { - // ignore - } - -} diff --git a/tools/h2/src/test/org/h2/test/unit/TestCache.java b/tools/h2/src/test/org/h2/test/unit/TestCache.java deleted file mode 100755 index d800fbe..0000000 --- a/tools/h2/src/test/org/h2/test/unit/TestCache.java +++ /dev/null @@ -1,131 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.test.unit; - -import java.sql.Connection; -import java.sql.PreparedStatement; -import java.sql.SQLException; -import java.sql.Statement; -import java.util.Random; - -import org.h2.message.Trace; -import org.h2.test.TestBase; -import org.h2.util.Cache; -import org.h2.util.CacheLRU; -import org.h2.util.CacheObject; -import org.h2.util.CacheWriter; - -/** - * Tests the cache. - */ -public class TestCache extends TestBase implements CacheWriter { - - private String out; - - /** - * Run just this test. - * - * @param a ignored - */ - public static void main(String... a) throws Exception { - TestBase.createCaller().init().test(); - } - - public void test() throws SQLException { - // testCache(false); - testCache(true); - testCacheDb(false); - testCacheDb(true); - } - - private void testCache(boolean lru) { - out = ""; - Cache c = CacheLRU.getCache(this, lru ? "LRU" : "TQ", 16); - for (int i = 0; i < 20; i++) { - c.put(new Obj(i)); - } - assertEquals(lru ? "0 1 2 3 " : "4 5 6 ", out); - - } - - /** - * A simple cache object - */ - class Obj extends CacheObject { - - Obj(int pos) { - setPos(pos); - } - - public int getMemorySize() { - return 1024; - } - - public boolean canRemove() { - return true; - } - - public boolean isChanged() { - return true; - } - - public String toString() { - return "[" + getPos() + "]"; - } - - } - - public void flushLog() { - out += "flush "; - } - - public Trace getTrace() { - return null; - } - - public void writeBack(CacheObject entry) { - out += entry.getPos() + " "; - } - - private void testCacheDb(boolean lru) throws SQLException { - if (config.memory) { - return; - } - deleteDb("cache"); - Connection conn = getConnection("cache;CACHE_TYPE=" + (lru ? "LRU" : "SOFT_LRU")); - Statement stat = conn.createStatement(); - stat.execute("SET CACHE_SIZE 1024"); - stat.execute("CREATE TABLE TEST(ID INT PRIMARY KEY, NAME VARCHAR)"); - stat.execute("CREATE TABLE MAIN(ID INT PRIMARY KEY, NAME VARCHAR)"); - PreparedStatement prep = conn.prepareStatement("INSERT INTO TEST VALUES(?, ?)"); - PreparedStatement prep2 = conn.prepareStatement("INSERT INTO MAIN VALUES(?, ?)"); - int max = 10000; - for (int i = 0; i < max; i++) { - prep.setInt(1, i); - prep.setString(2, "Hello " + i); - prep.execute(); - prep2.setInt(1, i); - prep2.setString(2, "World " + i); - prep2.execute(); - } - conn.close(); - conn = getConnection("cache"); - stat = conn.createStatement(); - stat.execute("SET CACHE_SIZE 1024"); - Random random = new Random(1); - for (int i = 0; i < 100; i++) { - stat.executeQuery("SELECT * FROM MAIN WHERE ID BETWEEN 40 AND 50"); - stat.executeQuery("SELECT * FROM MAIN WHERE ID = " + random.nextInt(max)); - if ((i % 10) == 0) { - stat.executeQuery("SELECT * FROM TEST"); - } - } - conn.close(); - deleteDb("cache"); - } - -} diff --git a/tools/h2/src/test/org/h2/test/unit/TestClearReferences.java b/tools/h2/src/test/org/h2/test/unit/TestClearReferences.java deleted file mode 100755 index 6789e15..0000000 --- a/tools/h2/src/test/org/h2/test/unit/TestClearReferences.java +++ /dev/null @@ -1,166 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.test.unit; - -import java.io.File; -import java.lang.reflect.Field; -import java.lang.reflect.Modifier; -import java.util.ArrayList; -import org.h2.test.TestBase; -import org.h2.util.MathUtils; -import org.h2.util.New; - -/** - * Tests if Tomcat would clear static fields when re-loading a web application. - * See also - * http://svn.apache.org/repos/asf/tomcat/trunk/java/org/apache/catalina - * /loader/WebappClassLoader.java - */ -public class TestClearReferences extends TestBase { - - private static final String[] KNOWN_REFRESHED = { - "org.h2.compress.CompressLZF.cachedHashTable", - "org.h2.util.DateTimeUtils.cachedCalendar", - "org.h2.util.StringUtils.softCache", - "org.h2.value.Value.softCache", - "org.h2.jdbcx.JdbcDataSourceFactory.cachedTraceSystem", - "org.h2.store.fs.FileObjectMemory.cachedCompressedEmptyBlock", - "org.h2.tools.CompressTool.cachedBuffer", - "org.h2.util.MemoryUtils.reserveMemory", - "org.h2.util.NetUtils.cachedLocalAddress", - "org.h2.util.MathUtils.cachedSecureRandom", - "org.h2.value.CompareMode.lastUsed", - "org.h2.store.fs.FileSystem.tempRandom", - }; - - private boolean hasError; - - /** - * Run just this test. - * - * @param a ignored - */ - public static void main(String... a) throws Exception { - TestBase.createCaller().init().test(); - } - - public void test() throws Exception { - // initialize the known classes - MathUtils.secureRandomLong(); - - ArrayList> classes = New.arrayList(); - check(classes, new File("bin/org/h2")); - for (Class< ? > clazz : classes) { - clearClass(clazz); - } - if (hasError) { - fail("Tomcat may clear the field above when reloading the web app"); - } - } - - private void check(ArrayList> classes, File file) { - String name = file.getName(); - if (file.isDirectory()) { - if (name.equals("CVS") || name.equals(".svn")) { - return; - } - for (File f : file.listFiles()) { - check(classes, f); - } - } else { - if (!name.endsWith(".class")) { - return; - } - String className = file.getAbsolutePath().replace('\\', '/'); - className = className.substring(className.lastIndexOf("org/h2")); - String packageName = className.substring(0, className.lastIndexOf('/')); - if (!new File("src/main/" + packageName).exists()) { - return; - } - className = className.replace('/', '.'); - className = className.substring(0, className.length() - ".class".length()); - Class< ? > clazz = null; - try { - clazz = Class.forName(className); - } catch (ClassNotFoundException e) { - System.out.println("Could not load " + className + ": " + e.toString()); - } - if (clazz != null) { - classes.add(clazz); - } - } - } - - /** - * This is how Tomcat resets the fields as of 2009-01-30. - * - * @param clazz the class to clear - */ - private void clearClass(Class< ? > clazz) throws Exception { - for (Field field : clazz.getDeclaredFields()) { - if (field.getType().isPrimitive() || field.getName().indexOf("$") != -1) { - continue; - } - int modifiers = field.getModifiers(); - if (!Modifier.isStatic(modifiers)) { - continue; - } - field.setAccessible(true); - Object o = field.get(null); - if (o == null) { - continue; - } - if (Modifier.isFinal(modifiers)) { - if (field.getType().getName().startsWith("java.")) { - continue; - } - if (field.getType().getName().startsWith("javax.")) { - continue; - } - clearInstance(o); - } else { - clearField(clazz.getName() + "." + field.getName() + " = " + o); - } - } - } - - private void clearInstance(Object instance) throws Exception { - for (Field field : instance.getClass().getDeclaredFields()) { - if (field.getType().isPrimitive() || (field.getName().indexOf("$") != -1)) { - continue; - } - int modifiers = field.getModifiers(); - if (Modifier.isStatic(modifiers) && Modifier.isFinal(modifiers)) { - continue; - } - field.setAccessible(true); - Object o = field.get(instance); - if (o == null) { - continue; - } - // loadedByThisOrChild - if (o.getClass().getName().startsWith("java.lang.")) { - continue; - } - if (o.getClass().isArray() && o.getClass().getComponentType().isPrimitive()) { - continue; - } - clearField(instance.getClass().getName() + "." + field.getName() + " = " + o); - } - } - - private void clearField(String s) { - for (String k : KNOWN_REFRESHED) { - if (s.startsWith(k)) { - return; - } - } - hasError = true; - System.out.println(s); - } - -} diff --git a/tools/h2/src/test/org/h2/test/unit/TestCompress.java b/tools/h2/src/test/org/h2/test/unit/TestCompress.java deleted file mode 100755 index 23bb41b..0000000 --- a/tools/h2/src/test/org/h2/test/unit/TestCompress.java +++ /dev/null @@ -1,229 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.test.unit; - -import java.io.InputStream; -import java.sql.Connection; -import java.sql.ResultSet; -import java.sql.Statement; -import java.util.ArrayList; -import java.util.Random; -import org.h2.compress.CompressLZF; -import org.h2.compress.Compressor; -import org.h2.constant.SysProperties; -import org.h2.store.fs.FileSystem; -import org.h2.test.TestBase; -import org.h2.tools.CompressTool; -import org.h2.util.New; - -/** - * Data compression tests. - */ -public class TestCompress extends TestBase { - - private boolean testPerformance; - - /** - * Run just this test. - * - * @param a ignored - */ - public static void main(String... a) throws Exception { - TestBase.createCaller().init().test(); - } - - public void test() throws Exception { - if (testPerformance) { - testDatabase(); - System.exit(0); - return; - } - testMultiThreaded(); - if (config.big) { - for (int i = 0; i < 100; i++) { - test(i); - } - for (int i = 100; i < 10000; i += i + i + 1) { - test(i); - } - } else { - test(0); - test(1); - test(7); - test(50); - test(200); - } - test(4000000); - testVariableEnd(); - } - - private void testMultiThreaded() throws Exception { - Thread[] threads = new Thread[3]; - final boolean[] stop = { false }; - final Exception[] ex = { null }; - for (int i = 0; i < threads.length; i++) { - Thread t = new Thread() { - public void run() { - CompressTool tool = CompressTool.getInstance(); - byte[] buff = new byte[1024]; - Random r = new Random(); - while (!stop[0]) { - r.nextBytes(buff); - try { - byte[] test = tool.expand(tool.compress(buff, "LZF")); - assertEquals(buff, test); - } catch (Exception e) { - ex[0] = e; - } - } - } - }; - threads[i] = t; - t.start(); - } - try { - Thread.sleep(1000); - stop[0] = true; - for (Thread t : threads) { - t.join(); - } - } catch (InterruptedException e) { - // ignore - } - if (ex[0] != null) { - throw ex[0]; - } - } - - private void testVariableEnd() throws Exception { - CompressTool utils = CompressTool.getInstance(); - StringBuilder buff = new StringBuilder(); - for (int i = 0; i < 90; i++) { - buff.append('0'); - } - String prefix = buff.toString(); - for (int i = 0; i < 100; i++) { - buff = new StringBuilder(prefix); - for (int j = 0; j < i; j++) { - buff.append((char) ('1' + j)); - } - String test = buff.toString(); - byte[] in = test.getBytes(); - assertEquals(in, utils.expand(utils.compress(in, "LZF"))); - } - } - - private void testDatabase() throws Exception { - deleteDb("memFS:compress"); - Connection conn = getConnection("memFS:compress"); - Statement stat = conn.createStatement(); - ResultSet rs; - rs = stat.executeQuery("select table_name from information_schema.tables"); - Statement stat2 = conn.createStatement(); - while (rs.next()) { - String table = rs.getString(1); - if (!"COLLATIONS".equals(table)) { - stat2.execute("create table " + table + " as select * from information_schema." + table); - } - } - conn.close(); - Compressor compress = new CompressLZF(); - int pageSize = SysProperties.PAGE_SIZE; - byte[] buff = new byte[pageSize]; - byte[] test = new byte[2 * pageSize]; - compress.compress(buff, pageSize, test, 0); - for (int j = 0; j < 4; j++) { - long time = System.currentTimeMillis(); - for (int i = 0; i < 1000; i++) { - InputStream in = FileSystem.getInstance("memFS:").openFileInputStream("memFS:compress.h2.db"); - int total = 0; - while (true) { - int len = in.read(buff); - if (len < 0) { - break; - } - total += compress.compress(buff, pageSize, test, 0); - } - in.close(); - } - System.out.println("compress: " + (System.currentTimeMillis() - time) + " ms"); - } - - for (int j = 0; j < 4; j++) { - ArrayList comp = New.arrayList(); - InputStream in = FileSystem.getInstance("memFS:").openFileInputStream("memFS:compress.h2.db"); - while (true) { - int len = in.read(buff); - if (len < 0) { - break; - } - int b = compress.compress(buff, pageSize, test, 0); - byte[] data = new byte[b]; - System.arraycopy(test, 0, data, 0, b); - comp.add(data); - } - in.close(); - byte[] result = new byte[pageSize]; - long time = System.currentTimeMillis(); - for (int i = 0; i < 1000; i++) { - for (int k = 0; k < comp.size(); k++) { - byte[] data = comp.get(k); - compress.expand(data, 0, data.length, result, 0, pageSize); - } - } - System.out.println("expand: " + (System.currentTimeMillis() - time) + " ms"); - } - } - - private void test(int len) { - Random r = new Random(len); - for (int pattern = 0; pattern < 4; pattern++) { - byte[] buff = new byte[len]; - switch (pattern) { - case 0: - // leave empty - break; - case 1: { - r.nextBytes(buff); - break; - } - case 2: { - for (int x = 0; x < len; x++) { - buff[x] = (byte) (x & 10); - } - break; - } - case 3: { - for (int x = 0; x < len; x++) { - buff[x] = (byte) (x / 10); - } - break; - } - default: - } - if (r.nextInt(2) < 1) { - for (int x = 0; x < len; x++) { - if (r.nextInt(20) < 1) { - buff[x] = (byte) (r.nextInt(255)); - } - } - } - CompressTool utils = CompressTool.getInstance(); - for (String a : new String[] { "LZF", "No", "Deflate" }) { - long time = System.currentTimeMillis(); - byte[] out = utils.compress(buff, a); - byte[] test = utils.expand(out); - if (testPerformance) { - System.out.println("p:" + pattern + " len: " + out.length + " time: " + (System.currentTimeMillis() - time) + " " + a); - } - assertEquals(buff.length, test.length); - assertEquals(buff, test); - } - } - } - -} diff --git a/tools/h2/src/test/org/h2/test/unit/TestDataPage.java b/tools/h2/src/test/org/h2/test/unit/TestDataPage.java deleted file mode 100755 index b34c5e5..0000000 --- a/tools/h2/src/test/org/h2/test/unit/TestDataPage.java +++ /dev/null @@ -1,317 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.test.unit; - -import java.math.BigDecimal; -import java.sql.Connection; -import java.sql.Date; -import java.sql.Time; -import java.sql.Timestamp; -import org.h2.store.Data; -import org.h2.store.DataHandler; -import org.h2.store.FileStore; -import org.h2.store.LobStorage; -import org.h2.test.TestBase; -import org.h2.util.SmallLRUCache; -import org.h2.util.TempFileDeleter; -import org.h2.value.CompareMode; -import org.h2.value.Value; -import org.h2.value.ValueArray; -import org.h2.value.ValueBoolean; -import org.h2.value.ValueByte; -import org.h2.value.ValueBytes; -import org.h2.value.ValueDate; -import org.h2.value.ValueDecimal; -import org.h2.value.ValueDouble; -import org.h2.value.ValueFloat; -import org.h2.value.ValueInt; -import org.h2.value.ValueJavaObject; -import org.h2.value.ValueLong; -import org.h2.value.ValueNull; -import org.h2.value.ValueShort; -import org.h2.value.ValueString; -import org.h2.value.ValueStringFixed; -import org.h2.value.ValueStringIgnoreCase; -import org.h2.value.ValueTime; -import org.h2.value.ValueTimestamp; -import org.h2.value.ValueUuid; - -/** - * Data page tests. - */ -public class TestDataPage extends TestBase implements DataHandler { - - private boolean testPerformance; - private CompareMode compareMode = CompareMode.getInstance(null, 0); - - /** - * Run just this test. - * - * @param a ignored - */ - public static void main(String... a) throws Exception { - TestBase.createCaller().init().test(); - } - - public void test() { - if (testPerformance) { - testPerformance(); - System.exit(0); - return; - } - testValues(); - testAll(); - } - - private void testPerformance() { - Data data = Data.create(null, 1024); - for (int j = 0; j < 4; j++) { - long time = System.currentTimeMillis(); - for (int i = 0; i < 100000; i++) { - data.reset(); - for (int k = 0; k < 30; k++) { - data.writeString("Hello World"); - } - } - // for (int i = 0; i < 5000000; i++) { - // data.reset(); - // for (int k = 0; k < 100; k++) { - // data.writeInt(k * k); - // } - // } - // for (int i = 0; i < 200000; i++) { - // data.reset(); - // for (int k = 0; k < 100; k++) { - // data.writeVarInt(k * k); - // } - // } - System.out.println("write: " + (System.currentTimeMillis() - time) + " ms"); - } - for (int j = 0; j < 4; j++) { - long time = System.currentTimeMillis(); - for (int i = 0; i < 1000000; i++) { - data.reset(); - for (int k = 0; k < 30; k++) { - data.readString(); - } - } - // for (int i = 0; i < 3000000; i++) { - // data.reset(); - // for (int k = 0; k < 100; k++) { - // data.readVarInt(); - // } - // } - // for (int i = 0; i < 50000000; i++) { - // data.reset(); - // for (int k = 0; k < 100; k++) { - // data.readInt(); - // } - // } - System.out.println("read: " + (System.currentTimeMillis() - time) + " ms"); - } - } - - private void testValues() { - testValue(ValueNull.INSTANCE); - testValue(ValueBoolean.get(false)); - testValue(ValueBoolean.get(true)); - for (int i = 0; i < 256; i++) { - testValue(ValueByte.get((byte) i)); - } - for (int i = 0; i < 256 * 256; i += 10) { - testValue(ValueShort.get((short) i)); - } - for (int i = 0; i < 256 * 256; i += 10) { - testValue(ValueInt.get(i)); - testValue(ValueInt.get(-i)); - testValue(ValueLong.get(i)); - testValue(ValueLong.get(-i)); - } - testValue(ValueInt.get(Integer.MAX_VALUE)); - testValue(ValueInt.get(Integer.MIN_VALUE)); - for (long i = 0; i < Integer.MAX_VALUE; i += 10 + i / 4) { - testValue(ValueInt.get((int) i)); - testValue(ValueInt.get((int) -i)); - } - testValue(ValueLong.get(Long.MAX_VALUE)); - testValue(ValueLong.get(Long.MIN_VALUE)); - for (long i = 0; i >= 0; i += 10 + i / 4) { - testValue(ValueLong.get(i)); - testValue(ValueLong.get(-i)); - } - testValue(ValueDecimal.get(BigDecimal.ZERO)); - testValue(ValueDecimal.get(BigDecimal.ONE)); - testValue(ValueDecimal.get(BigDecimal.TEN)); - testValue(ValueDecimal.get(BigDecimal.ONE.negate())); - testValue(ValueDecimal.get(BigDecimal.TEN.negate())); - for (long i = 0; i >= 0; i += 10 + i / 4) { - testValue(ValueDecimal.get(new BigDecimal(i))); - testValue(ValueDecimal.get(new BigDecimal(-i))); - for (int j = 0; j < 200; j += 50) { - testValue(ValueDecimal.get(new BigDecimal(i).setScale(j))); - testValue(ValueDecimal.get(new BigDecimal(i * i).setScale(j))); - } - testValue(ValueDecimal.get(new BigDecimal(i * i))); - } - testValue(ValueDate.get(new Date(System.currentTimeMillis()))); - testValue(ValueDate.get(new Date(0))); - testValue(ValueTime.get(new Time(System.currentTimeMillis()))); - testValue(ValueTime.get(new Time(0))); - testValue(ValueTimestamp.get(new Timestamp(System.currentTimeMillis()))); - testValue(ValueTimestamp.get(new Timestamp(0))); - testValue(ValueJavaObject.getNoCopy(new byte[0])); - testValue(ValueJavaObject.getNoCopy(new byte[100])); - for (int i = 0; i < 300; i++) { - testValue(ValueBytes.getNoCopy(new byte[i])); - } - for (int i = 0; i < 65000; i += 10 + i) { - testValue(ValueBytes.getNoCopy(new byte[i])); - } - testValue(ValueUuid.getNewRandom()); - for (int i = 0; i < 100; i++) { - testValue(ValueString.get(new String(new char[i]))); - } - for (int i = 0; i < 65000; i += 10 + i) { - testValue(ValueString.get(new String(new char[i]))); - testValue(ValueStringFixed.get(new String(new char[i]))); - testValue(ValueStringIgnoreCase.get(new String(new char[i]))); - } - testValue(ValueFloat.get(0f)); - testValue(ValueFloat.get(1f)); - testValue(ValueFloat.get(-1f)); - testValue(ValueDouble.get(0)); - testValue(ValueDouble.get(1)); - testValue(ValueDouble.get(-1)); - for (int i = 0; i < 65000; i += 10 + i) { - for (double j = 0.1; j < 65000; j += 10 + j) { - testValue(ValueFloat.get((float) (i / j))); - testValue(ValueDouble.get(i / j)); - testValue(ValueFloat.get((float) -(i / j))); - testValue(ValueDouble.get(-(i / j))); - } - } - testValue(ValueArray.get(new Value[0])); - testValue(ValueArray.get(new Value[] {ValueBoolean.get(true), ValueInt.get(10)})); - } - - private void testValue(Value v) { - Data data = Data.create(null, 1024); - data.checkCapacity((int) v.getPrecision()); - data.writeValue(v); - data.writeInt(123); - data.reset(); - Value v2 = data.readValue(); - assertEquals(v.getType(), v2.getType()); - assertEquals(0, v.compareTo(v2, compareMode)); - assertEquals(123, data.readInt()); - } - - - private void testAll() { - Data page = Data.create(this, 128); - - char[] data = new char[0x10000]; - for (int i = 0; i < data.length; i++) { - data[i] = (char) i; - } - String s = new String(data); - page.checkCapacity(s.length() * 4); - page.writeString(s); - int len = page.length(); - assertEquals(len, Data.getStringLen(s)); - page.reset(); - assertEquals(s, page.readString()); - page.reset(); - - page.writeString("H\u1111!"); - page.writeString("John\tBrack's \"how are you\" M\u1111ller"); - page.writeValue(ValueInt.get(10)); - page.writeValue(ValueString.get("test")); - page.writeValue(ValueFloat.get(-2.25f)); - page.writeValue(ValueDouble.get(10.40)); - page.writeValue(ValueNull.INSTANCE); - trace(new String(page.getBytes())); - page.reset(); - - trace(page.readString()); - trace(page.readString()); - trace(page.readValue().getInt()); - trace(page.readValue().getString()); - trace("" + page.readValue().getFloat()); - trace("" + page.readValue().getDouble()); - trace(page.readValue().toString()); - page.reset(); - - page.writeInt(0); - page.writeInt(Integer.MAX_VALUE); - page.writeInt(Integer.MIN_VALUE); - page.writeInt(1); - page.writeInt(-1); - page.writeInt(1234567890); - page.writeInt(54321); - trace(new String(page.getBytes())); - page.reset(); - trace(page.readInt()); - trace(page.readInt()); - trace(page.readInt()); - trace(page.readInt()); - trace(page.readInt()); - trace(page.readInt()); - trace(page.readInt()); - - page = null; - } - - public String getDatabasePath() { - return null; - } - - public FileStore openFile(String name, String mode, boolean mustExist) { - return null; - } - - public void checkPowerOff() { - // nothing to do - } - - public void checkWritingAllowed() { - // ok - } - - public void freeUpDiskSpace() { - // nothing to do - } - - public int getMaxLengthInplaceLob() { - throw new AssertionError(); - } - - public String getLobCompressionAlgorithm(int type) { - throw new AssertionError(); - } - - public Object getLobSyncObject() { - return this; - } - - public SmallLRUCache getLobFileListCache() { - return null; - } - - public TempFileDeleter getTempFileDeleter() { - return TempFileDeleter.getInstance(); - } - - public LobStorage getLobStorage() { - return null; - } - - public Connection getLobConnection() { - return null; - } - -} diff --git a/tools/h2/src/test/org/h2/test/unit/TestDate.java b/tools/h2/src/test/org/h2/test/unit/TestDate.java deleted file mode 100755 index 48ff7b3..0000000 --- a/tools/h2/src/test/org/h2/test/unit/TestDate.java +++ /dev/null @@ -1,101 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.test.unit; - -import java.sql.Connection; -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.util.TimeZone; - -import org.h2.constant.ErrorCode; -import org.h2.test.TestBase; -import org.h2.util.DateTimeUtils; -import org.h2.value.Value; - -/** - * Tests the data parsing. The problem is that some dates are not allowed - * because of the summer time change. Most countries change at 2 o'clock in the - * morning to 3 o'clock, but some (for example Chile) change at midnight. - * Non-lenient parsing would not work in this case. - */ -public class TestDate extends TestBase { - - /** - * Run just this test. - * - * @param a ignored - */ - public static void main(String... a) throws Exception { - TestBase.createCaller().init().test(); - } - - public void test() throws SQLException { - testAllTimeZones(); - testCurrentTimeZone(); - } - - private void testCurrentTimeZone() { - for (int year = 1970; year < 2050; year += 3) { - for (int month = 1; month <= 12; month++) { - for (int day = 1; day < 29; day++) { - for (int hour = 0; hour < 24; hour++) { - test(year, month, day, hour); - } - } - } - } - } - - private void test(int year, int month, int day, int hour) { - DateTimeUtils.parseDateTime(year + "-" + month + "-" + day + " " + hour + ":00:00", Value.TIMESTAMP, ErrorCode.TIMESTAMP_CONSTANT_2); - } - - private void testAllTimeZones() throws SQLException { - Connection conn = getConnection("date"); - TimeZone defaultTimeZone = TimeZone.getDefault(); - PreparedStatement prep = conn.prepareStatement("CALL CAST(? AS DATE)"); - try { - String[] ids = TimeZone.getAvailableIDs(); - for (int i = 0; i < ids.length; i++) { - TimeZone.setDefault(TimeZone.getTimeZone(ids[i])); - DateTimeUtils.resetCalendar(); - for (int d = 101; d < 129; d++) { - test(prep, d); - } - } - } finally { - TimeZone.setDefault(defaultTimeZone); - DateTimeUtils.resetCalendar(); - } - conn.close(); - deleteDb("date"); - } - - private void test(PreparedStatement prep, int d) throws SQLException { - String s = "2040-10-" + ("" + d).substring(1); - // some dates don't work in some versions of Java - // java.sql.Date date = java.sql.Date.valueOf(s); - // long time = date.getTime(); - // int plus = 0; - // while (true) { - // date = new java.sql.Date(time); - // String x = date.toString(); - // if (x.equals(s)) { - // break; - // } - // time += 1000; - // plus += 1000; - // } - prep.setString(1, s); - ResultSet rs = prep.executeQuery(); - rs.next(); - String t = rs.getString(1); - assertEquals(s, t); - } - -} diff --git a/tools/h2/src/test/org/h2/test/unit/TestDateIso8601.java b/tools/h2/src/test/org/h2/test/unit/TestDateIso8601.java deleted file mode 100755 index defb8ae..0000000 --- a/tools/h2/src/test/org/h2/test/unit/TestDateIso8601.java +++ /dev/null @@ -1,262 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: Robert Rathsack (firstName dot lastName at gmx dot de) - */ -package org.h2.test.unit; - -import java.sql.Timestamp; -import java.text.ParseException; -import java.text.SimpleDateFormat; -import java.util.Date; - -import org.h2.test.TestBase; -import org.h2.util.DateTimeUtils; - -/** - * Test cases for DateTimeIso8601Utils. - */ -public class TestDateIso8601 extends TestBase { - - private SimpleDateFormat dateFormatter = new SimpleDateFormat("yyyy-MM-dd"); - - /** - * Run just this test. - * - * @param a ignored - */ - public static void main(String... a) throws Exception { - TestBase.createCaller().init().test(); - } - - public void test() throws Exception { - testIsoDayOfWeek(); - testIsoWeekJanuary1thMonday(); - testIsoWeekJanuary1thTuesday(); - testIsoWeekJanuary1thWednesday(); - testIsoWeekJanuary1thThursday(); - testIsoWeekJanuary1thFriday(); - testIsoWeekJanuary1thSaturday(); - testIsoWeekJanuary1thSunday(); - testIsoYearJanuary1thMonday(); - testIsoYearJanuary1thTuesday(); - testIsoYearJanuary1thWednesday(); - testIsoYearJanuary1thThursday(); - testIsoYearJanuary1thFriday(); - testIsoYearJanuary1thSaturday(); - testIsoYearJanuary1thSunday(); - } - - private Date parse(String s) throws ParseException { - return dateFormatter.parse(s); - } - - private static int getIsoDayOfWeek(Date date) { - return DateTimeUtils.getIsoDayOfWeek(date); - } - - /** - * Test if day of week is returned as Monday = 1 to Sunday = 7. - */ - private void testIsoDayOfWeek() throws Exception { - assertEquals(1, getIsoDayOfWeek(parse("2008-09-29"))); - assertEquals(2, getIsoDayOfWeek(parse("2008-09-30"))); - assertEquals(3, getIsoDayOfWeek(parse("2008-10-01"))); - assertEquals(4, getIsoDayOfWeek(parse("2008-10-02"))); - assertEquals(5, getIsoDayOfWeek(parse("2008-10-03"))); - assertEquals(6, getIsoDayOfWeek(parse("2008-10-04"))); - assertEquals(7, getIsoDayOfWeek(parse("2008-10-05"))); - } - - private static int getIsoWeek(Date date) { - Timestamp ts = new Timestamp(date.getTime()); - return DateTimeUtils.getIsoWeek(ts); - } - - /** - * January 1st is a Monday therefore the week belongs to the next year. - */ - private void testIsoWeekJanuary1thMonday() throws Exception { - assertEquals(52, getIsoWeek(parse("2006-12-31"))); - assertEquals(1, getIsoWeek(parse("2007-01-01"))); - assertEquals(1, getIsoWeek(parse("2007-01-07"))); - assertEquals(2, getIsoWeek(parse("2007-01-08"))); - } - - /** - * January 1st is a Tuesday therefore the week belongs to the next year. - */ - private void testIsoWeekJanuary1thTuesday() throws Exception { - assertEquals(52, getIsoWeek(parse("2007-12-30"))); - assertEquals(1, getIsoWeek(parse("2007-12-31"))); - assertEquals(1, getIsoWeek(parse("2008-01-01"))); - assertEquals(1, getIsoWeek(parse("2008-01-06"))); - assertEquals(2, getIsoWeek(parse("2008-01-07"))); - } - - /** - * January1th is a Wednesday therefore the week belongs to the next year. - */ - private void testIsoWeekJanuary1thWednesday() throws Exception { - assertEquals(52, getIsoWeek(parse("2002-12-28"))); - assertEquals(52, getIsoWeek(parse("2002-12-29"))); - assertEquals(1, getIsoWeek(parse("2002-12-30"))); - assertEquals(1, getIsoWeek(parse("2002-12-31"))); - assertEquals(1, getIsoWeek(parse("2003-01-01"))); - assertEquals(1, getIsoWeek(parse("2003-01-05"))); - assertEquals(2, getIsoWeek(parse("2003-01-06"))); - } - - /** - * January 1st is a Thursday therefore the week belongs to the next year. - */ - private void testIsoWeekJanuary1thThursday() throws Exception { - assertEquals(52, getIsoWeek(parse("2008-12-28"))); - assertEquals(1, getIsoWeek(parse("2008-12-29"))); - assertEquals(1, getIsoWeek(parse("2008-12-30"))); - assertEquals(1, getIsoWeek(parse("2008-12-31"))); - assertEquals(1, getIsoWeek(parse("2009-01-01"))); - assertEquals(1, getIsoWeek(parse("2009-01-04"))); - assertEquals(2, getIsoWeek(parse("2009-01-09"))); - } - - /** - * January 1st is a Friday therefore the week belongs to the previous year. - */ - private void testIsoWeekJanuary1thFriday() throws Exception { - assertEquals(53, getIsoWeek(parse("2009-12-31"))); - assertEquals(53, getIsoWeek(parse("2010-01-01"))); - assertEquals(53, getIsoWeek(parse("2010-01-03"))); - assertEquals(1, getIsoWeek(parse("2010-01-04"))); - } - - /** - * January 1st is a Saturday therefore the week belongs to the previous - * year. - */ - private void testIsoWeekJanuary1thSaturday() throws Exception { - assertEquals(52, getIsoWeek(parse("2010-12-31"))); - assertEquals(52, getIsoWeek(parse("2011-01-01"))); - assertEquals(52, getIsoWeek(parse("2011-01-02"))); - assertEquals(1, getIsoWeek(parse("2011-01-03"))); - } - - /** - * January 1st is a Sunday therefore the week belongs to the previous year. - */ - private void testIsoWeekJanuary1thSunday() throws Exception { - assertEquals(52, getIsoWeek(parse("2011-12-31"))); - assertEquals(52, getIsoWeek(parse("2012-01-01"))); - assertEquals(1, getIsoWeek(parse("2012-01-02"))); - assertEquals(1, getIsoWeek(parse("2012-01-08"))); - assertEquals(2, getIsoWeek(parse("2012-01-09"))); - } - - private static int getIsoYear(Date date) { - Timestamp ts = new Timestamp(date.getTime()); - return DateTimeUtils.getIsoYear(ts); - } - - /** - * January 1st is a Monday therefore year is equal to isoYear. - */ - private void testIsoYearJanuary1thMonday() throws Exception { - assertEquals(2006, getIsoYear(parse("2006-12-28"))); - assertEquals(2006, getIsoYear(parse("2006-12-29"))); - assertEquals(2006, getIsoYear(parse("2006-12-30"))); - assertEquals(2006, getIsoYear(parse("2006-12-31"))); - assertEquals(2007, getIsoYear(parse("2007-01-01"))); - assertEquals(2007, getIsoYear(parse("2007-01-02"))); - assertEquals(2007, getIsoYear(parse("2007-01-03"))); - } - - /** - * January 1st is a Tuesday therefore 31th of December belong to the next - * year. - */ - private void testIsoYearJanuary1thTuesday() throws Exception { - assertEquals(2007, getIsoYear(parse("2007-12-28"))); - assertEquals(2007, getIsoYear(parse("2007-12-29"))); - assertEquals(2007, getIsoYear(parse("2007-12-30"))); - assertEquals(2008, getIsoYear(parse("2007-12-31"))); - assertEquals(2008, getIsoYear(parse("2008-01-01"))); - assertEquals(2008, getIsoYear(parse("2008-01-02"))); - assertEquals(2008, getIsoYear(parse("2008-01-03"))); - assertEquals(2008, getIsoYear(parse("2008-01-04"))); - } - - /** - * January 1st is a Wednesday therefore 30th and 31th of December belong to - * the next year. - */ - private void testIsoYearJanuary1thWednesday() throws Exception { - assertEquals(2002, getIsoYear(parse("2002-12-28"))); - assertEquals(2002, getIsoYear(parse("2002-12-29"))); - assertEquals(2003, getIsoYear(parse("2002-12-30"))); - assertEquals(2003, getIsoYear(parse("2002-12-31"))); - assertEquals(2003, getIsoYear(parse("2003-01-01"))); - assertEquals(2003, getIsoYear(parse("2003-01-02"))); - assertEquals(2003, getIsoYear(parse("2003-12-02"))); - } - - /** - * January 1st is a Thursday therefore 29th - 31th of December belong to the - * next year. - */ - private void testIsoYearJanuary1thThursday() throws Exception { - assertEquals(2008, getIsoYear(parse("2008-12-28"))); - assertEquals(2009, getIsoYear(parse("2008-12-29"))); - assertEquals(2009, getIsoYear(parse("2008-12-30"))); - assertEquals(2009, getIsoYear(parse("2008-12-31"))); - assertEquals(2009, getIsoYear(parse("2009-01-01"))); - assertEquals(2009, getIsoYear(parse("2009-01-02"))); - assertEquals(2009, getIsoYear(parse("2009-01-03"))); - assertEquals(2009, getIsoYear(parse("2009-01-04"))); - } - - /** - * January 1st is a Friday therefore 1st - 3rd of January belong to the - * previous year. - */ - private void testIsoYearJanuary1thFriday() throws Exception { - assertEquals(2009, getIsoYear(parse("2009-12-28"))); - assertEquals(2009, getIsoYear(parse("2009-12-29"))); - assertEquals(2009, getIsoYear(parse("2009-12-30"))); - assertEquals(2009, getIsoYear(parse("2009-12-31"))); - assertEquals(2009, getIsoYear(parse("2010-01-01"))); - assertEquals(2009, getIsoYear(parse("2010-01-02"))); - assertEquals(2009, getIsoYear(parse("2010-01-03"))); - assertEquals(2010, getIsoYear(parse("2010-01-04"))); - } - - /** - * January 1st is a Saturday therefore 1st and 2nd of January belong to the - * previous year. - */ - private void testIsoYearJanuary1thSaturday() throws Exception { - assertEquals(2010, getIsoYear(parse("2010-12-28"))); - assertEquals(2010, getIsoYear(parse("2010-12-29"))); - assertEquals(2010, getIsoYear(parse("2010-12-30"))); - assertEquals(2010, getIsoYear(parse("2010-12-31"))); - assertEquals(2010, getIsoYear(parse("2011-01-01"))); - assertEquals(2010, getIsoYear(parse("2011-01-02"))); - assertEquals(2011, getIsoYear(parse("2011-01-03"))); - assertEquals(2011, getIsoYear(parse("2011-01-04"))); - } - - /** - * January 1st is a Sunday therefore this day belong to the previous year. - */ - private void testIsoYearJanuary1thSunday() throws Exception { - assertEquals(2011, getIsoYear(parse("2011-12-28"))); - assertEquals(2011, getIsoYear(parse("2011-12-29"))); - assertEquals(2011, getIsoYear(parse("2011-12-30"))); - assertEquals(2011, getIsoYear(parse("2011-12-31"))); - assertEquals(2011, getIsoYear(parse("2012-01-01"))); - assertEquals(2012, getIsoYear(parse("2012-01-02"))); - assertEquals(2012, getIsoYear(parse("2012-01-03"))); - assertEquals(2012, getIsoYear(parse("2012-01-04"))); - } - -} diff --git a/tools/h2/src/test/org/h2/test/unit/TestExit.java b/tools/h2/src/test/org/h2/test/unit/TestExit.java deleted file mode 100755 index 7d637dd..0000000 --- a/tools/h2/src/test/org/h2/test/unit/TestExit.java +++ /dev/null @@ -1,145 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.test.unit; - -import java.io.File; -import java.io.IOException; -import java.sql.Connection; -import java.sql.DriverManager; -import java.sql.SQLException; - -import org.h2.api.DatabaseEventListener; -import org.h2.test.TestBase; -import org.h2.test.utils.SelfDestructor; - -/** - * Tests the flag db_close_on_exit. - * A new process is started. - */ -public class TestExit extends TestBase implements DatabaseEventListener { - - public static Connection conn; - - static final int OPEN_WITH_CLOSE_ON_EXIT = 1, OPEN_WITHOUT_CLOSE_ON_EXIT = 2; - - public void test() throws Exception { - if (config.codeCoverage || config.networked) { - return; - } - if (getBaseDir().indexOf(':') > 0) { - return; - } - deleteDb("exit"); - String selfDestruct = SelfDestructor.getPropertyString(60); - String[] procDef = { "java", selfDestruct, - "-cp", getClassPath(), - getClass().getName(), "" + OPEN_WITH_CLOSE_ON_EXIT }; - Process proc = Runtime.getRuntime().exec(procDef); - while (true) { - int ch = proc.getErrorStream().read(); - if (ch < 0) { - break; - } - System.out.print((char) ch); - } - while (true) { - int ch = proc.getInputStream().read(); - if (ch < 0) { - break; - } - System.out.print((char) ch); - } - proc.waitFor(); - Thread.sleep(100); - if (!getClosedFile().exists()) { - fail("did not close database"); - } - procDef = new String[] { "java", - "-cp", getClassPath(), getClass().getName(), - "" + OPEN_WITHOUT_CLOSE_ON_EXIT }; - proc = Runtime.getRuntime().exec(procDef); - proc.waitFor(); - Thread.sleep(100); - if (getClosedFile().exists()) { - fail("closed database"); - } - deleteDb("exit"); - } - - /** - * This method is called when executing this application from the command - * line. - * - * @param args the command line parameters - */ - public static void main(String... args) throws SQLException { - SelfDestructor.startCountdown(60); - if (args.length == 0) { - System.exit(1); - } - int action = Integer.parseInt(args[0]); - TestExit app = new TestExit(); - app.execute(action); - } - - private void execute(int action) throws SQLException { - org.h2.Driver.load(); - String url = ""; - switch (action) { - case OPEN_WITH_CLOSE_ON_EXIT: - url = "jdbc:h2:" + getBaseDir() + "/exit;database_event_listener='" + getClass().getName() - + "';db_close_on_exit=true"; - break; - case OPEN_WITHOUT_CLOSE_ON_EXIT: - url = "jdbc:h2:" + getBaseDir() + "/exit;database_event_listener='" + getClass().getName() - + "';db_close_on_exit=false"; - break; - default: - } - conn = open(url); - Connection conn2 = open(url); - conn2.close(); - } - - private static Connection open(String url) throws SQLException { - getClosedFile().delete(); - return DriverManager.getConnection(url, "sa", ""); - } - - public void diskSpaceIsLow() { - // nothing to do - } - - public void exceptionThrown(SQLException e, String sql) { - // nothing to do - } - - public void closingDatabase() { - try { - getClosedFile().createNewFile(); - } catch (IOException e) { - TestBase.logError("error", e); - } - } - - private static File getClosedFile() { - return new File(TestBase.BASE_TEST_DIR + "/closed.txt"); - } - - public void setProgress(int state, String name, int x, int max) { - // nothing to do - } - - public void init(String url) { - // nothing to do - } - - public void opened() { - // nothing to do - } - -} diff --git a/tools/h2/src/test/org/h2/test/unit/TestFile.java b/tools/h2/src/test/org/h2/test/unit/TestFile.java deleted file mode 100755 index 64fc694..0000000 --- a/tools/h2/src/test/org/h2/test/unit/TestFile.java +++ /dev/null @@ -1,182 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.test.unit; - -import java.sql.Connection; -import java.util.Random; -import org.h2.store.DataHandler; -import org.h2.store.FileStore; -import org.h2.store.LobStorage; -import org.h2.test.TestBase; -import org.h2.util.IOUtils; -import org.h2.util.SmallLRUCache; -import org.h2.util.TempFileDeleter; - -/** - * Tests the in-memory file system. - */ -public class TestFile extends TestBase implements DataHandler { - - /** - * Run just this test. - * - * @param a ignored - */ - public static void main(String... a) throws Exception { - TestBase.createCaller().init().test(); - } - - public void test() throws Exception { - doTest(false); - doTest(true); - } - - private void doTest(boolean compress) throws Exception { - int len = getSize(1000, 10000); - Random random = new Random(); - FileStore mem = null, file = null; - byte[] buffMem = null; - byte[] buffFile = null; - String prefix = compress ? "memLZF:" : "memFS:"; - IOUtils.delete(prefix + "test"); - IOUtils.delete("~/testFile"); - - // config.traceTest = true; - - for (int i = 0; i < len; i++) { - if (buffMem == null) { - int l = 1 + random.nextInt(1000); - buffMem = new byte[l]; - buffFile = new byte[l]; - } - if (file == null) { - mem = FileStore.open(this, prefix + "test", "rw"); - file = FileStore.open(this, "~/testFile", "rw"); - } - assertEquals(file.getFilePointer(), mem.getFilePointer()); - assertEquals(file.length(), mem.length()); - int x = random.nextInt(100); - if ((x -= 20) < 0) { - if (file.length() > 0) { - long pos = random.nextInt((int) (file.length() / 16)) * 16; - trace("seek " + pos); - mem.seek(pos); - file.seek(pos); - } - } else if ((x -= 20) < 0) { - trace("close"); - mem.close(); - file.close(); - mem = null; - file = null; - } else if ((x -= 20) < 0) { - if (buffFile.length > 16) { - random.nextBytes(buffFile); - System.arraycopy(buffFile, 0, buffMem, 0, buffFile.length); - int off = random.nextInt(buffFile.length - 16); - int l = random.nextInt((buffFile.length - off) / 16) * 16; - trace("write " + off + " " + l); - mem.write(buffMem, off, l); - file.write(buffFile, off, l); - } - } else if ((x -= 20) < 0) { - if (buffFile.length > 16) { - int off = random.nextInt(buffFile.length - 16); - int l = random.nextInt((buffFile.length - off) / 16) * 16; - l = (int) Math.min(l, file.length() - file.getFilePointer()); - trace("read " + off + " " + l); - Exception a = null, b = null; - try { - file.readFully(buffFile, off, l); - } catch (Exception e) { - a = e; - } - try { - mem.readFully(buffMem, off, l); - } catch (Exception e) { - b = e; - } - if (a != b) { - if (a == null || b == null) { - fail("only one threw an exception"); - } - } - assertEquals(buffMem, buffFile); - } - } else if ((x -= 10) < 0) { - trace("reset buffers"); - buffMem = null; - buffFile = null; - } else { - int l = random.nextInt(10000) * 16; - long p = file.getFilePointer(); - file.setLength(l); - mem.setLength(l); - trace("setLength " + l); - if (p > l) { - file.seek(l); - mem.seek(l); - } - } - } - if (mem != null) { - mem.close(); - file.close(); - } - IOUtils.delete(prefix + "test"); - IOUtils.delete("~/testFile"); - } - - public void checkPowerOff() { - // nothing to do - } - - public void checkWritingAllowed() { - // nothing to do - } - - public void freeUpDiskSpace() { - // nothing to do - } - - public String getDatabasePath() { - return null; - } - - public String getLobCompressionAlgorithm(int type) { - return null; - } - - public Object getLobSyncObject() { - return null; - } - - public int getMaxLengthInplaceLob() { - return 0; - } - - public FileStore openFile(String name, String mode, boolean mustExist) { - return null; - } - - public SmallLRUCache getLobFileListCache() { - return null; - } - - public TempFileDeleter getTempFileDeleter() { - return TempFileDeleter.getInstance(); - } - - public LobStorage getLobStorage() { - return null; - } - - public Connection getLobConnection() { - return null; - } - -} diff --git a/tools/h2/src/test/org/h2/test/unit/TestFileLock.java b/tools/h2/src/test/org/h2/test/unit/TestFileLock.java deleted file mode 100755 index ca4351f..0000000 --- a/tools/h2/src/test/org/h2/test/unit/TestFileLock.java +++ /dev/null @@ -1,139 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.test.unit; - -import java.io.File; -import org.h2.engine.Constants; -import org.h2.message.TraceSystem; -import org.h2.store.FileLock; -import org.h2.test.TestBase; - -/** - * Tests the database file locking facility. - * Both lock files and sockets locking is tested. - */ -public class TestFileLock extends TestBase implements Runnable { - - private static volatile int locks; - private static volatile boolean stop; - private TestBase base; - private int wait; - private boolean allowSockets; - - public TestFileLock() { - // nothing to do - } - - TestFileLock(TestBase base, boolean allowSockets) { - this.base = base; - this.allowSockets = allowSockets; - } - - private String getFile() { - return getBaseDir() + "/test.lock"; - } - - /** - * Run just this test. - * - * @param a ignored - */ - public static void main(String... a) throws Exception { - TestBase.createCaller().init().test(); - } - - public void test() throws Exception { - if (!getFile().startsWith(TestBase.BASE_TEST_DIR)) { - return; - } - testFutureModificationDate(); - testSimple(); - test(false); - test(true); - } - - private void testFutureModificationDate() throws Exception { - File f = new File(getFile()); - f.delete(); - f.createNewFile(); - f.setLastModified(System.currentTimeMillis() + 10000); - FileLock lock = new FileLock(new TraceSystem(null), getFile(), Constants.LOCK_SLEEP); - lock.lock(FileLock.LOCK_FILE); - lock.unlock(); - } - - private void testSimple() { - FileLock lock1 = new FileLock(new TraceSystem(null), getFile(), Constants.LOCK_SLEEP); - FileLock lock2 = new FileLock(new TraceSystem(null), getFile(), Constants.LOCK_SLEEP); - lock1.lock(FileLock.LOCK_FILE); - try { - lock2.lock(FileLock.LOCK_FILE); - fail(); - } catch (Exception e) { - // expected - } - lock1.unlock(); - lock2 = new FileLock(new TraceSystem(null), getFile(), Constants.LOCK_SLEEP); - lock2.lock(FileLock.LOCK_FILE); - lock2.unlock(); - } - - private void test(boolean allowSocketsLock) throws Exception { - int threadCount = getSize(3, 5); - wait = getSize(20, 200); - Thread[] threads = new Thread[threadCount]; - new File(getFile()).delete(); - for (int i = 0; i < threadCount; i++) { - threads[i] = new Thread(new TestFileLock(this, allowSocketsLock)); - threads[i].start(); - Thread.sleep(wait + (int) (Math.random() * wait)); - } - trace("wait"); - Thread.sleep(500); - stop = true; - trace("STOP file"); - for (int i = 0; i < threadCount; i++) { - threads[i].join(); - } - assertEquals(0, locks); - } - - public void run() { - FileLock lock = null; - while (!stop) { - lock = new FileLock(new TraceSystem(null), getFile(), 100); - try { - lock.lock(allowSockets ? FileLock.LOCK_SOCKET : FileLock.LOCK_FILE); - base.trace(lock + " locked"); - locks++; - if (locks > 1) { - System.err.println("ERROR! LOCKS=" + locks + " sockets=" + allowSockets); - stop = true; - } - Thread.sleep(wait + (int) (Math.random() * wait)); - locks--; - base.trace(lock + " unlock"); - lock.unlock(); - if (locks < 0) { - System.err.println("ERROR! LOCKS=" + locks); - stop = true; - } - } catch (Exception e) { - // log(id+" cannot lock: " + e); - } - try { - Thread.sleep(wait + (int) (Math.random() * wait)); - } catch (InterruptedException e1) { - // ignore - } - } - if (lock != null) { - lock.unlock(); - } - } - -} diff --git a/tools/h2/src/test/org/h2/test/unit/TestFileLockSerialized.java b/tools/h2/src/test/org/h2/test/unit/TestFileLockSerialized.java deleted file mode 100755 index 2741a02..0000000 --- a/tools/h2/src/test/org/h2/test/unit/TestFileLockSerialized.java +++ /dev/null @@ -1,641 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.test.unit; - -import java.io.FileOutputStream; -import java.io.OutputStream; -import java.sql.Connection; -import java.sql.DriverManager; -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.sql.Statement; -import java.util.Arrays; -import java.util.List; -import org.h2.jdbc.JdbcConnection; -import org.h2.store.fs.FileSystem; -import org.h2.test.TestBase; -import org.h2.util.SortedProperties; - -/** - * Test the serialized (server-less) mode. - */ -public class TestFileLockSerialized extends TestBase { - - /** - * Run just this test. - * - * @param a ignored - */ - public static void main(String... a) throws Exception { - TestBase.createCaller().init().test(); - } - - public void test() throws Exception { - println("testAutoIncrement"); - testAutoIncrement(); - println("testSequenceFlush"); - testSequenceFlush(); - println("testLeftLogFiles"); - testLeftLogFiles(); - println("testWrongDatabaseInstanceOnReconnect"); - testWrongDatabaseInstanceOnReconnect(); - println("testCache()"); - testCache(); - println("testBigDatabase(false)"); - testBigDatabase(false); - println("testBigDatabase(true)"); - testBigDatabase(true); - println("testCheckpointInUpdateRaceCondition"); - testCheckpointInUpdateRaceCondition(); - println("testConcurrentUpdates"); - testConcurrentUpdates(); - println("testThreeMostlyReaders true"); - testThreeMostlyReaders(true); - println("testThreeMostlyReaders false"); - testThreeMostlyReaders(false); - println("testTwoReaders"); - testTwoReaders(); - println("testTwoWriters"); - testTwoWriters(); - println("testPendingWrite"); - testPendingWrite(); - println("testKillWriter"); - testKillWriter(); - println("testConcurrentReadWrite"); - testConcurrentReadWrite(); - deleteDb("fileLockSerialized"); - } - - private void testSequenceFlush() throws Exception { - deleteDb("fileLockSerialized"); - String url = "jdbc:h2:" + getBaseDir() + "/fileLockSerialized;FILE_LOCK=SERIALIZED;OPEN_NEW=TRUE"; - ResultSet rs; - Connection conn1 = DriverManager.getConnection(url); - Statement stat1 = conn1.createStatement(); - stat1.execute("create sequence seq"); - rs = stat1.executeQuery("call seq.nextval"); - rs.next(); - assertEquals(1, rs.getInt(1)); - Connection conn2 = DriverManager.getConnection(url); - Statement stat2 = conn2.createStatement(); - rs = stat2.executeQuery("call seq.nextval"); - rs.next(); - assertEquals(2, rs.getInt(1)); - conn1.close(); - conn2.close(); - } - - private void testThreeMostlyReaders(final boolean write) throws Exception { - boolean longRun = false; - deleteDb("fileLockSerialized"); - final String url = "jdbc:h2:" + getBaseDir() + "/fileLockSerialized;FILE_LOCK=SERIALIZED;OPEN_NEW=TRUE"; - - Connection conn = DriverManager.getConnection(url); - conn.createStatement().execute("create table test(id int) as select 1"); - conn.close(); - - final int len = 10; - final Exception[] ex = { null }; - final boolean[] stop = { false }; - Thread[] threads = new Thread[len]; - for (int i = 0; i < len; i++) { - Thread t = new Thread(new Runnable() { - public void run() { - try { - Connection c = DriverManager.getConnection(url); - PreparedStatement p = c.prepareStatement("select * from test where id = ?"); - while (!stop[0]) { - Thread.sleep(100); - if (write) { - if (Math.random() > 0.9) { - c.createStatement().execute("update test set id = id"); - } - } - p.setInt(1, 1); - p.executeQuery(); - p.clearParameters(); - } - c.close(); - } catch (Exception e) { - ex[0] = e; - } - } - }); - t.start(); - threads[i] = t; - } - if (longRun) { - Thread.sleep(40000); - } else { - Thread.sleep(1000); - } - stop[0] = true; - for (int i = 0; i < len; i++) { - threads[i].join(); - } - if (ex[0] != null) { - throw ex[0]; - } - DriverManager.getConnection(url).close(); - } - - private void testTwoReaders() throws Exception { - deleteDb("fileLockSerialized"); - String url = "jdbc:h2:" + getBaseDir() + "/fileLockSerialized;FILE_LOCK=SERIALIZED;OPEN_NEW=TRUE"; - Connection conn1 = DriverManager.getConnection(url); - conn1.createStatement().execute("create table test(id int)"); - Connection conn2 = DriverManager.getConnection(url); - Statement stat2 = conn2.createStatement(); - stat2.execute("drop table test"); - stat2.execute("create table test(id identity) as select 1"); - conn2.close(); - conn1.close(); - DriverManager.getConnection(url).close(); - } - - private void testTwoWriters() throws Exception { - deleteDb("fileLockSerialized"); - String url = "jdbc:h2:" + getBaseDir() + "/fileLockSerialized"; - final String writeUrl = url + ";FILE_LOCK=SERIALIZED;OPEN_NEW=TRUE"; - final boolean[] stop = { false }; - Connection conn = DriverManager.getConnection(writeUrl, "sa", "sa"); - conn.createStatement().execute("create table test(id identity) as select x from system_range(1, 100)"); - conn.close(); - new Thread() { - public void run() { - while (!stop[0]) { - try { - Thread.sleep(10); - Connection c = DriverManager.getConnection(writeUrl, "sa", "sa"); - c.createStatement().execute("select * from test"); - c.close(); - } catch (Exception e) { - // ignore - } - } - } - }.start(); - Thread.sleep(20); - for (int i = 0; i < 2; i++) { - conn = DriverManager.getConnection(writeUrl, "sa", "sa"); - Statement stat = conn.createStatement(); - stat.execute("drop table test"); - stat.execute("create table test(id identity) as select x from system_range(1, 100)"); - conn.createStatement().execute("select * from test"); - conn.close(); - } - stop[0] = true; - Thread.sleep(100); - conn = DriverManager.getConnection(writeUrl, "sa", "sa"); - conn.createStatement().execute("select * from test"); - conn.close(); - } - - private void testPendingWrite() throws Exception { - deleteDb("fileLockSerialized"); - String url = "jdbc:h2:" + getBaseDir() + "/fileLockSerialized"; - String writeUrl = url + ";FILE_LOCK=SERIALIZED;OPEN_NEW=TRUE;WRITE_DELAY=0"; - - Connection conn = DriverManager.getConnection(writeUrl, "sa", "sa"); - Statement stat = conn.createStatement(); - stat.execute("create table test(id int primary key)"); - Thread.sleep(100); - String propFile = getBaseDir() + "/fileLockSerialized.lock.db"; - SortedProperties p = SortedProperties.loadProperties(propFile); - p.setProperty("changePending", "true"); - p.setProperty("modificationDataId", "1000"); - OutputStream out = new FileOutputStream(propFile, false); - try { - p.store(out, "test"); - } finally { - out.close(); - } - Thread.sleep(100); - stat.execute("select * from test"); - conn.close(); - } - - private void testKillWriter() throws Exception { - deleteDb("fileLockSerialized"); - String url = "jdbc:h2:" + getBaseDir() + "/fileLockSerialized"; - String writeUrl = url + ";FILE_LOCK=SERIALIZED;OPEN_NEW=TRUE;WRITE_DELAY=0"; - - Connection conn = DriverManager.getConnection(writeUrl, "sa", "sa"); - Statement stat = conn.createStatement(); - stat.execute("create table test(id int primary key)"); - ((JdbcConnection) conn).setPowerOffCount(1); - try { - stat.execute("insert into test values(1)"); - fail(); - } catch (SQLException e) { - // ignore - } - - Connection conn2 = DriverManager.getConnection(writeUrl, "sa", "sa"); - Statement stat2 = conn2.createStatement(); - stat2.execute("insert into test values(1)"); - printResult(stat2, "select * from test"); - - conn2.close(); - - try { - conn.close(); - } catch (SQLException e) { - // ignore - } - } - - private void testConcurrentReadWrite() throws Exception { - deleteDb("fileLockSerialized"); - - String url = "jdbc:h2:" + getBaseDir() + "/fileLockSerialized"; - String writeUrl = url + ";FILE_LOCK=SERIALIZED;OPEN_NEW=TRUE"; - // ;TRACE_LEVEL_SYSTEM_OUT=3 - // String readUrl = writeUrl + ";ACCESS_MODE_DATA=R"; - - trace(" create database"); - Class.forName("org.h2.Driver"); - Connection conn = DriverManager.getConnection(writeUrl, "sa", "sa"); - Statement stat = conn.createStatement(); - stat.execute("create table test(id int primary key)"); - - Connection conn3 = DriverManager.getConnection(writeUrl, "sa", "sa"); - PreparedStatement prep3 = conn3.prepareStatement("insert into test values(?)"); - - Connection conn2 = DriverManager.getConnection(writeUrl, "sa", "sa"); - Statement stat2 = conn2.createStatement(); - printResult(stat2, "select * from test"); - - stat2.execute("create local temporary table temp(name varchar) not persistent"); - printResult(stat2, "select * from temp"); - - trace(" insert row 1"); - stat.execute("insert into test values(1)"); - trace(" insert row 2"); - prep3.setInt(1, 2); - prep3.execute(); - printResult(stat2, "select * from test"); - printResult(stat2, "select * from temp"); - - conn.close(); - conn2.close(); - conn3.close(); - } - - private void printResult(Statement stat, String sql) throws SQLException { - trace(" query: " + sql); - ResultSet rs = stat.executeQuery(sql); - int rowCount = 0; - while (rs.next()) { - trace(" " + rs.getString(1)); - rowCount++; - } - trace(" " + rowCount + " row(s)"); - } - - private void testConcurrentUpdates() throws Exception { - boolean longRun = false; - if (longRun) { - for (int waitTime = 100; waitTime < 10000; waitTime += 20) { - for (int howManyThreads = 1; howManyThreads < 10; howManyThreads++) { - testConcurrentUpdates(waitTime, howManyThreads, waitTime * howManyThreads * 10); - } - } - } else { - testConcurrentUpdates(100, 4, 2000); - } - } - - private void testAutoIncrement() throws Exception { - boolean longRun = false; - if (longRun) { - for (int waitTime = 100; waitTime < 10000; waitTime += 20) { - for (int howManyThreads = 1; howManyThreads < 10; howManyThreads++) { - testAutoIncrement(waitTime, howManyThreads, 2000); - } - } - } else { - testAutoIncrement(400, 2, 2000); - } - } - - private void testAutoIncrement(final int waitTime, int howManyThreads, int runTime) throws Exception { - println("testAutoIncrement waitTime: " + waitTime + " howManyThreads: " + howManyThreads + " runTime: " + runTime); - deleteDb("fileLockSerialized"); - final String url = "jdbc:h2:" + getBaseDir() + "/fileLockSerialized;FILE_LOCK=SERIALIZED;OPEN_NEW=TRUE;" + - "AUTO_RECONNECT=TRUE;MAX_LENGTH_INPLACE_LOB=8192;COMPRESS_LOB=DEFLATE;CACHE_SIZE=65536"; - - Connection conn = DriverManager.getConnection(url); - conn.createStatement().execute("create table test(id int auto_increment, id2 int)"); - conn.close(); - - final long endTime = System.currentTimeMillis() + runTime; - final Exception[] ex = { null }; - final Connection[] connList = new Connection[howManyThreads]; - final boolean[] stop = { false }; - final int[] nextInt = { 0 }; - Thread[] threads = new Thread[howManyThreads]; - for (int i = 0; i < howManyThreads; i++) { - final int finalNrOfConnection = i; - Thread t = new Thread(new Runnable() { - public void run() { - try { - Connection c = DriverManager.getConnection(url); - connList[finalNrOfConnection] = c; - while (!stop[0]) { - synchronized (nextInt) { - ResultSet rs = c.createStatement().executeQuery("select id, id2 from test"); - while (rs.next()) { - if (rs.getInt(1) != rs.getInt(2)) { - throw new Exception(Thread.currentThread().getId() + " nextInt: " + nextInt [0] + " rs.getInt(1): " + rs.getInt(1) + " rs.getInt(2): " + rs.getInt(2)); - } - } - nextInt[0]++; - Statement stat = c.createStatement(); - stat.execute("insert into test (id2) values(" + nextInt[0] + ")"); - ResultSet rsKeys = stat.getGeneratedKeys(); - while (rsKeys.next()) { - assertEquals(nextInt[0], rsKeys.getInt(1)); - } - rsKeys.close(); - } - Thread.sleep(waitTime); - } - c.close(); - } catch (Exception e) { - e.printStackTrace(); - ex[0] = e; - } - } - }); - t.start(); - threads[i] = t; - } - while ((ex[0] == null) && (System.currentTimeMillis() < endTime)) { - Thread.sleep(10); - } - - stop[0] = true; - for (int i = 0; i < howManyThreads; i++) { - threads[i].join(); - } - if (ex[0] != null) { - throw ex[0]; - } - DriverManager.getConnection(url).close(); - deleteDb("fileLockSerialized"); - } - - private void testConcurrentUpdates(final int waitTime, int howManyThreads, int runTime) throws Exception { - println("testConcurrentUpdates waitTime: " + waitTime + " howManyThreads: " + howManyThreads + " runTime: " + runTime); - deleteDb("fileLockSerialized"); - final String url = "jdbc:h2:" + getBaseDir() + "/fileLockSerialized;FILE_LOCK=SERIALIZED;OPEN_NEW=TRUE;" + - "AUTO_RECONNECT=TRUE;MAX_LENGTH_INPLACE_LOB=8192;COMPRESS_LOB=DEFLATE;CACHE_SIZE=65536"; - - Connection conn = DriverManager.getConnection(url); - conn.createStatement().execute("create table test(id int)"); - conn.createStatement().execute("insert into test values(1)"); - conn.close(); - - final long endTime = System.currentTimeMillis() + runTime; - final Exception[] ex = { null }; - final Connection[] connList = new Connection[howManyThreads]; - final boolean[] stop = { false }; - final int[] lastInt = { 1 }; - Thread[] threads = new Thread[howManyThreads]; - for (int i = 0; i < howManyThreads; i++) { - final int finalNrOfConnection = i; - Thread t = new Thread(new Runnable() { - public void run() { - try { - Connection c = DriverManager.getConnection(url); - connList[finalNrOfConnection] = c; - while (!stop[0]) { - ResultSet rs = c.createStatement().executeQuery("select * from test"); - rs.next(); - if (rs.getInt(1) != lastInt[0]) { - throw new Exception(finalNrOfConnection + " Expected: " + lastInt[0] + " got " + rs.getInt(1)); - } - Thread.sleep(waitTime); - if (Math.random() > 0.7) { - int newLastInt = (int) (Math.random() * 1000); - c.createStatement().execute("update test set id = " + newLastInt); - lastInt[0] = newLastInt; - } - } - c.close(); - } catch (Exception e) { - e.printStackTrace(); - ex[0] = e; - } - } - }); - t.start(); - threads[i] = t; - } - while ((ex[0] == null) && (System.currentTimeMillis() < endTime)) { - Thread.sleep(10); - } - - stop[0] = true; - for (int i = 0; i < howManyThreads; i++) { - threads[i].join(); - } - if (ex[0] != null) { - throw ex[0]; - } - DriverManager.getConnection(url).close(); - deleteDb("fileLockSerialized"); - } - - /** - * If a checkpoint occurs between beforeWriting and checkWritingAllowed - * then the result of checkWritingAllowed is READ_ONLY, which is wrong. - * - * Also, if a checkpoint started before beforeWriting, and ends between - * between beforeWriting and checkWritingAllowed, then the same error occurs. - * - * @throws Exception - */ - private void testCheckpointInUpdateRaceCondition() throws Exception { - boolean longRun = false; - deleteDb("fileLockSerialized"); - String url = "jdbc:h2:" + getBaseDir() + "/fileLockSerialized;FILE_LOCK=SERIALIZED;OPEN_NEW=TRUE"; - - Connection conn = DriverManager.getConnection(url); - conn.createStatement().execute("create table test(id int)"); - conn.createStatement().execute("insert into test values(1)"); - for (int i = 0; i < (longRun ? 10000 : 5); i++) { - Thread.sleep(402); - conn.createStatement().execute("update test set id = " + i); - } - conn.close(); - deleteDb("fileLockSerialized"); - } - - /** - * Caches must be cleared. Session.reconnect only closes the DiskFile (which is - * associated with the cache) if there is one session - */ - private void testCache() throws Exception { - deleteDb("fileLockSerialized"); - - String urlShared = "jdbc:h2:" + getBaseDir() + "/fileLockSerialized;FILE_LOCK=SERIALIZED"; - - Connection connShared1 = DriverManager.getConnection(urlShared); - Statement statement1 = connShared1.createStatement(); - Connection connShared2 = DriverManager.getConnection(urlShared); - Statement statement2 = connShared2.createStatement(); - - statement1.execute("create table test1(id int)"); - statement1.execute("insert into test1 values(1)"); - - ResultSet rs = statement1.executeQuery("select id from test1"); - rs.close(); - rs = statement2.executeQuery("select id from test1"); - rs.close(); - - statement1.execute("update test1 set id=2"); - Thread.sleep(500); - - rs = statement2.executeQuery("select id from test1"); - assertTrue(rs.next()); - assertEquals(2, rs.getInt(1)); - rs.close(); - - connShared1.close(); - connShared2.close(); - deleteDb("fileLockSerialized"); - } - - private void testWrongDatabaseInstanceOnReconnect() throws Exception { - deleteDb("fileLockSerialized"); - - String urlShared = "jdbc:h2:" + getBaseDir() + "/fileLockSerialized;FILE_LOCK=SERIALIZED"; - String urlForNew = urlShared + ";OPEN_NEW=TRUE"; - - Connection connShared1 = DriverManager.getConnection(urlShared); - Statement statement1 = connShared1.createStatement(); - Connection connShared2 = DriverManager.getConnection(urlShared); - Connection connNew = DriverManager.getConnection(urlForNew); - statement1.execute("create table test1(id int)"); - connShared1.close(); - connShared2.close(); - connNew.close(); - deleteDb("fileLockSerialized"); - } - - private void testBigDatabase(boolean withCache) throws Exception { - boolean longRun = false; - final int howMuchRows = longRun ? 2000000 : 500000; - deleteDb("fileLockSerialized"); - int cacheSizeKb = withCache ? 5000 : 0; - - final String url = "jdbc:h2:" + getBaseDir() + "/fileLockSerialized;FILE_LOCK=SERIALIZED;OPEN_NEW=TRUE;CACHE_SIZE=" + cacheSizeKb; - final boolean[] importFinished = { false }; - final Exception[] ex = { null }; - final Thread importUpdate = new Thread() { - public void run() { - try { - Connection conn = DriverManager.getConnection(url); - Statement stat = conn.createStatement(); - stat.execute("create table test(id int, id2 int)"); - for (int i = 0; i < howMuchRows; i++) { - stat.execute("insert into test values(" + i + ", " + i + ")"); - } - importFinished[0] = true; - Thread.sleep(5000); - stat.execute("update test set id2=999 where id=500"); - conn.close(); - } catch (Exception e) { - ex[0] = e; - } finally { - importFinished[0] = true; - } - } - }; - importUpdate.start(); - - Thread select = new Thread() { - public void run() { - try { - Connection conn = DriverManager.getConnection(url); - Statement stat = conn.createStatement(); - while (!importFinished[0]) { - Thread.sleep(100); - } - Thread.sleep(1000); - ResultSet rs = stat.executeQuery("select id2 from test where id=500"); - assertTrue(rs.next()); - assertEquals(500, rs.getInt(1)); - rs.close(); - importUpdate.join(); - Thread.sleep(1000); - rs = stat.executeQuery("select id2 from test where id=500"); - assertTrue(rs.next()); - assertEquals(999, rs.getInt(1)); - rs.close(); - conn.close(); - } catch (Exception e) { - ex[0] = e; - } - } - }; - select.start(); - importUpdate.join(); - select.join(); - if (ex[0] != null) { - throw ex[0]; - } - deleteDb("fileLockSerialized"); - } - - private void testLeftLogFiles() throws Exception { - deleteDb("fileLockSerialized"); - - // without serialized - String url; - url = "jdbc:h2:" + getBaseDir() + "/fileLockSerialized"; - Connection conn = DriverManager.getConnection(url); - Statement stat = conn.createStatement(); - stat.execute("create table test(id int)"); - stat.execute("insert into test values(0)"); - conn.close(); - - FileSystem fs = FileSystem.getInstance(getBaseDir()); - - List filesWithoutSerialized = Arrays.asList(fs.listFiles(getBaseDir())); - deleteDb("fileLockSerialized"); - - // with serialized - url = "jdbc:h2:" + getBaseDir() + "/fileLockSerialized;FILE_LOCK=SERIALIZED"; - conn = DriverManager.getConnection(url); - stat = conn.createStatement(); - stat.execute("create table test(id int)"); - Thread.sleep(500); - stat.execute("insert into test values(0)"); - conn.close(); - - List filesWithSerialized = Arrays.asList(fs.listFiles(getBaseDir())); - if (filesWithoutSerialized.size() != filesWithSerialized.size()) { - for (int i = 0; i < filesWithoutSerialized.size(); i++) { - if (!filesWithSerialized.contains(filesWithoutSerialized.get(i))) { - System.out.println("File left from 'without serialized' mode: " + filesWithoutSerialized.get(i)); - } - } - for (int i = 0; i < filesWithSerialized.size(); i++) { - if (!filesWithoutSerialized.contains(filesWithSerialized.get(i))) { - System.out.println("File left from 'with serialized' mode: " + filesWithSerialized.get(i)); - } - } - fail("With serialized it must create the same files than without serialized"); - } - deleteDb("fileLockSerialized"); - } - -} diff --git a/tools/h2/src/test/org/h2/test/unit/TestFileSystem.java b/tools/h2/src/test/org/h2/test/unit/TestFileSystem.java deleted file mode 100755 index 44860a8..0000000 --- a/tools/h2/src/test/org/h2/test/unit/TestFileSystem.java +++ /dev/null @@ -1,303 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.test.unit; - -import java.io.EOFException; -import java.io.File; -import java.io.InputStream; -import java.io.OutputStream; -import java.io.RandomAccessFile; -import java.sql.Connection; -import java.sql.DriverManager; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.sql.Statement; -import java.util.Random; - -import org.h2.store.fs.FileObject; -import org.h2.store.fs.FileSystem; -import org.h2.store.fs.FileSystemMemory; -import org.h2.test.TestBase; -import org.h2.util.IOUtils; - -/** - * Tests various file system. - */ -public class TestFileSystem extends TestBase { - - /** - * Run just this test. - * - * @param a ignored - */ - public static void main(String... a) throws Exception { - TestBase.createCaller().init().test(); - } - - public void test() throws Exception { - testDatabaseInMemFileSys(); - testDatabaseInJar(); - // set default part size to 1 << 10 - FileSystem.getInstance("split:10:" + getBaseDir() + "/fs"); - testFileSystem("split:" + getBaseDir() + "/fs"); - testFileSystem(getBaseDir() + "/fs"); - testFileSystem(FileSystemMemory.PREFIX); - FileSystemDatabase fs = FileSystemDatabase.register("jdbc:h2:mem:fs"); - // testFileSystem("jdbc:h2:mem:fs;TRACE_LEVEL_FILE=3"); - testFileSystem("jdbc:h2:mem:fs"); - testFileSystem(FileSystemMemory.PREFIX_LZF); - testUserHome(); - fs.unregister(); - IOUtils.delete(getBaseDir() + "/fs"); - } - - private void testDatabaseInMemFileSys() throws SQLException { - org.h2.Driver.load(); - deleteDb("fsMem"); - String url = "jdbc:h2:" + getBaseDir() + "/fsMem"; - Connection conn = DriverManager.getConnection(url, "sa", "sa"); - conn.createStatement().execute("CREATE TABLE TEST AS SELECT * FROM DUAL"); - conn.createStatement().execute("BACKUP TO '" + getBaseDir() + "/fsMem.zip'"); - conn.close(); - org.h2.tools.Restore.main("-file", getBaseDir() + "/fsMem.zip", "-dir", "memFS:"); - conn = DriverManager.getConnection("jdbc:h2:memFS:fsMem", "sa", "sa"); - ResultSet rs = conn.createStatement().executeQuery("SELECT * FROM TEST"); - rs.close(); - conn.close(); - deleteDb("fsMem"); - IOUtils.delete(getBaseDir() + "/fsMem.zip"); - } - - private void testDatabaseInJar() throws SQLException { - if (getBaseDir().indexOf(':') > 0) { - return; - } - if (config.networked) { - return; - } - org.h2.Driver.load(); - String url = "jdbc:h2:" + getBaseDir() + "/fsJar"; - Connection conn = DriverManager.getConnection(url, "sa", "sa"); - Statement stat = conn.createStatement(); - stat.execute("create table test(id int primary key, name varchar, b blob, c clob)"); - stat.execute("insert into test values(1, 'Hello', SECURE_RAND(2000), space(2000))"); - ResultSet rs; - rs = stat.executeQuery("select * from test"); - rs.next(); - byte[] b1 = rs.getBytes(3); - String s1 = rs.getString(4); - conn.close(); - conn = DriverManager.getConnection(url, "sa", "sa"); - stat = conn.createStatement(); - stat.execute("backup to '" + getBaseDir() + "/fsJar.zip'"); - conn.close(); - - deleteDb("fsJar"); - FileSystem fs = FileSystem.getInstance("zip:" + getBaseDir() + "/fsJar.zip"); - for (String f : fs.listFiles("zip:" + getBaseDir() + "/fsJar.zip")) { - assertTrue(fs.isAbsolute(f)); - assertTrue(!fs.isDirectory(f)); - assertTrue(fs.length(f) > 0); - assertTrue(f.endsWith(fs.getFileName(f))); - } - String urlJar = "jdbc:h2:zip:" + getBaseDir() + "/fsJar.zip!/fsJar"; - conn = DriverManager.getConnection(urlJar, "sa", "sa"); - stat = conn.createStatement(); - rs = stat.executeQuery("select * from test"); - rs.next(); - assertEquals(1, rs.getInt(1)); - assertEquals("Hello", rs.getString(2)); - byte[] b2 = rs.getBytes(3); - String s2 = rs.getString(4); - assertEquals(2000, b2.length); - assertEquals(2000, s2.length()); - assertEquals(b1, b2); - assertEquals(s1, s2); - assertFalse(rs.next()); - conn.close(); - IOUtils.delete(getBaseDir() + "/fsJar.zip"); - } - - private void testUserHome() { - FileSystem fs = FileSystem.getInstance("~/test"); - String fileName = fs.getAbsolutePath("~/test"); - String userDir = System.getProperty("user.home"); - assertTrue(fileName.startsWith(userDir)); - } - - private void testFileSystem(String fsBase) throws Exception { - testSimple(fsBase); - testTempFile(fsBase); - testRandomAccess(fsBase); - } - - private void testSimple(String fsBase) throws Exception { - FileSystem fs = FileSystem.getInstance(fsBase); - long time = System.currentTimeMillis(); - for (String s : fs.listFiles(fsBase)) { - fs.delete(s); - } - fs.mkdirs(fsBase + "/test"); - fs.delete(fsBase + "/test"); - fs.delete(fsBase + "/test2"); - assertTrue(fs.createNewFile(fsBase + "/test")); - assertTrue(fs.canWrite(fsBase + "/test")); - FileObject fo = fs.openFileObject(fsBase + "/test", "rw"); - byte[] buffer = new byte[10000]; - Random random = new Random(1); - random.nextBytes(buffer); - fo.write(buffer, 0, 10000); - fo.close(); - long lastMod = fs.getLastModified(fsBase + "/test"); - if (lastMod < time - 1999) { - // at most 2 seconds difference - assertEquals(time, lastMod); - } - assertEquals(10000, fs.length(fsBase + "/test")); - String[] list = fs.listFiles(fsBase); - assertEquals(1, list.length); - assertTrue(list[0].endsWith("test")); - - fs.copy(fsBase + "/test", fsBase + "/test3"); - fs.rename(fsBase + "/test3", fsBase + "/test2"); - assertTrue(!fs.exists(fsBase + "/test3")); - assertTrue(fs.exists(fsBase + "/test2")); - assertEquals(10000, fs.length(fsBase + "/test2")); - byte[] buffer2 = new byte[10000]; - InputStream in = fs.openFileInputStream(fsBase + "/test2"); - int pos = 0; - while (true) { - int l = in.read(buffer2, pos, Math.min(10000 - pos, 1000)); - if (l <= 0) { - break; - } - pos += l; - } - in.close(); - assertEquals(10000, pos); - assertEquals(buffer, buffer2); - - assertTrue(fs.tryDelete(fsBase + "/test2")); - fs.delete(fsBase + "/test"); - - if (fsBase.indexOf(FileSystemMemory.PREFIX) < 0 && fsBase.indexOf(FileSystemMemory.PREFIX_LZF) < 0) { - fs.createDirs(fsBase + "/testDir/test"); - assertTrue(fs.isDirectory(fsBase + "/testDir")); - if (!fsBase.startsWith("jdbc:")) { - fs.deleteRecursive(fsBase + "/testDir", false); - assertTrue(!fs.exists(fsBase + "/testDir")); - } - } - } - - private void testRandomAccess(String fsBase) throws Exception { - FileSystem fs = FileSystem.getInstance(fsBase); - String s = fs.createTempFile(fsBase + "/temp", ".tmp", false, false); - File file = new File(TestBase.BASE_TEST_DIR + "/temp"); - file.getParentFile().mkdirs(); - file.delete(); - RandomAccessFile ra = new RandomAccessFile(file, "rw"); - fs.delete(s); - FileObject f = fs.openFileObject(s, "rw"); - try { - f.readFully(new byte[1], 0, 1); - fail(); - } catch (EOFException e) { - // expected - } - f.sync(); - Random random = new Random(1); - int size = getSize(100, 500); - for (int i = 0; i < size; i++) { - int pos = random.nextInt(10000); - switch(random.nextInt(7)) { - case 0: { - pos = (int) Math.min(pos, ra.length()); - trace("seek " + pos); - f.seek(pos); - ra.seek(pos); - break; - } - case 1: { - byte[] buffer = new byte[random.nextInt(1000)]; - random.nextBytes(buffer); - trace("write " + buffer.length); - f.write(buffer, 0, buffer.length); - ra.write(buffer, 0, buffer.length); - break; - } - case 2: { - f.setFileLength(pos); - ra.setLength(pos); - if (ra.getFilePointer() > pos) { - f.seek(0); - ra.seek(0); - } - trace("setLength " + pos); - break; - } - case 3: { - int len = random.nextInt(1000); - len = (int) Math.min(len, ra.length() - ra.getFilePointer()); - byte[] b1 = new byte[len]; - byte[] b2 = new byte[len]; - ra.readFully(b1, 0, len); - f.readFully(b2, 0, len); - trace("readFully " + len); - assertEquals(b1, b2); - break; - } - case 4: { - trace("getFilePointer"); - assertEquals(ra.getFilePointer(), f.getFilePointer()); - break; - } - case 5: { - trace("length " + ra.length()); - assertEquals(ra.length(), f.length()); - break; - } - case 6: { - trace("reopen"); - f.close(); - ra.close(); - ra = new RandomAccessFile(file, "rw"); - f = fs.openFileObject(s, "rw"); - assertEquals(ra.length(), f.length()); - break; - } - default: - } - } - f.close(); - ra.close(); - file.delete(); - fs.delete(s); - } - - private void testTempFile(String fsBase) throws Exception { - FileSystem fs = FileSystem.getInstance(fsBase); - String s = fs.createTempFile(fsBase + "/temp", ".tmp", false, false); - OutputStream out = fs.openFileOutputStream(s, false); - byte[] buffer = new byte[10000]; - out.write(buffer); - out.close(); - out = fs.openFileOutputStream(s, true); - out.write(1); - out.close(); - InputStream in = fs.openFileInputStream(s); - for (int i = 0; i < 10000; i++) { - assertEquals(0, in.read()); - } - assertEquals(1, in.read()); - assertEquals(-1, in.read()); - in.close(); - out.close(); - fs.delete(s); - } - -} diff --git a/tools/h2/src/test/org/h2/test/unit/TestFtp.java b/tools/h2/src/test/org/h2/test/unit/TestFtp.java deleted file mode 100755 index e8175ed..0000000 --- a/tools/h2/src/test/org/h2/test/unit/TestFtp.java +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.test.unit; - -import org.h2.dev.ftp.FtpClient; -import org.h2.dev.ftp.server.FtpEvent; -import org.h2.dev.ftp.server.FtpEventListener; -import org.h2.dev.ftp.server.FtpServer; -import org.h2.test.TestBase; -import org.h2.tools.Server; -import org.h2.util.IOUtils; - -/** - * Tests the FTP server tool. - */ -public class TestFtp extends TestBase implements FtpEventListener { - - private FtpEvent lastEvent; - - /** - * Run just this test. - * - * @param a ignored - */ - public static void main(String... a) throws Exception { - TestBase.createCaller().init().test(); - } - - public void test() throws Exception { - if (getBaseDir().indexOf(':') > 0) { - return; - } - test(getBaseDir()); - IOUtils.delete(getBaseDir() + "/test"); - } - - private void test(String dir) throws Exception { - Server server = FtpServer.createFtpServer("-ftpDir", dir, "-ftpPort", "8121").start(); - FtpServer ftp = (FtpServer) server.getService(); - ftp.setEventListener(this); - FtpClient client = FtpClient.open("localhost:8121"); - client.login("sa", "sa"); - client.makeDirectory("test"); - client.changeWorkingDirectory("test"); - assertEquals("CWD", lastEvent.getCommand()); - client.makeDirectory("hello"); - client.changeWorkingDirectory("hello"); - client.changeDirectoryUp(); - assertEquals("CDUP", lastEvent.getCommand()); - client.nameList("hello"); - client.removeDirectory("hello"); - client.close(); - server.stop(); - } - - public void beforeCommand(FtpEvent event) { - lastEvent = event; - } - - public void afterCommand(FtpEvent event) { - lastEvent = event; - } - - public void onUnsupportedCommand(FtpEvent event) { - lastEvent = event; - } - -} diff --git a/tools/h2/src/test/org/h2/test/unit/TestIntArray.java b/tools/h2/src/test/org/h2/test/unit/TestIntArray.java deleted file mode 100755 index 104cd14..0000000 --- a/tools/h2/src/test/org/h2/test/unit/TestIntArray.java +++ /dev/null @@ -1,112 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.test.unit; - -import java.util.Random; -import org.h2.test.TestBase; -import org.h2.util.IntArray; - -/** - * Tests the IntArray class. - */ -public class TestIntArray extends TestBase { - - /** - * Run just this test. - * - * @param a ignored - */ - public static void main(String... a) throws Exception { - TestBase.createCaller().init().test(); - } - - public void test() { - testInit(); - testRandom(); - testRemoveRange(); - } - - private void testRemoveRange() { - IntArray array = new IntArray(new int[] {1, 2, 3, 4, 5}); - array.removeRange(1, 3); - assertEquals(3, array.size()); - assertEquals(1, array.get(0)); - assertEquals(4, array.get(1)); - assertEquals(5, array.get(2)); - } - - private void testInit() { - IntArray array = new IntArray(new int[0]); - array.add(10); - } - - private void testRandom() { - IntArray array = new IntArray(); - int[] test = {}; - Random random = new Random(1); - for (int i = 0; i < 10000; i++) { - int idx = test.length == 0 ? 0 : random.nextInt(test.length); - int v = random.nextInt(100); - int op = random.nextInt(4); - switch (op) { - case 0: - array.add(v); - test = add(test, v); - break; - case 1: - if (test.length > idx) { - assertEquals(get(test, idx), array.get(idx)); - } - break; - case 2: - if (test.length > 0) { - array.remove(idx); - test = remove(test, idx); - } - break; - case 3: - assertEquals(test.length, array.size()); - break; - default: - } - assertEquals(test.length, array.size()); - for (int j = 0; j < test.length; j++) { - assertEquals(test[j], array.get(j)); - } - - } - } - - private int[] add(int[] array, int i, int value) { - int[] a2 = new int[array.length + 1]; - System.arraycopy(array, 0, a2, 0, array.length); - if (i < array.length) { - System.arraycopy(a2, i, a2, i + 1, a2.length - i - 1); - } - array = a2; - array[i] = value; - return array; - } - - private int[] add(int[] array, int value) { - return add(array, array.length, value); - } - - private int get(int[] array, int i) { - return array[i]; - } - - private int[] remove(int[] array, int i) { - int[] a2 = new int[array.length - 1]; - System.arraycopy(array, 0, a2, 0, i); - if (i < a2.length) { - System.arraycopy(array, i + 1, a2, i, array.length - i - 1); - } - return a2; - } - -} diff --git a/tools/h2/src/test/org/h2/test/unit/TestIntIntHashMap.java b/tools/h2/src/test/org/h2/test/unit/TestIntIntHashMap.java deleted file mode 100755 index f09c02e..0000000 --- a/tools/h2/src/test/org/h2/test/unit/TestIntIntHashMap.java +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.test.unit; - -import java.util.Random; - -import org.h2.test.TestBase; -import org.h2.util.IntIntHashMap; - -/** - * Tests the IntHashMap class. - */ -public class TestIntIntHashMap extends TestBase { - - private Random rand = new Random(); - - /** - * Run just this test. - * - * @param a ignored - */ - public static void main(String... a) throws Exception { - TestBase.createCaller().init().test(); - } - - public void test() { - rand.setSeed(10); - test(true); - test(false); - } - - private void test(boolean random) { - int len = 2000; - int[] x = new int[len]; - for (int i = 0; i < len; i++) { - int key = random ? rand.nextInt() : i; - x[i] = key; - } - IntIntHashMap map = new IntIntHashMap(); - for (int i = 0; i < len; i++) { - map.put(x[i], i); - } - for (int i = 0; i < len; i++) { - if (map.get(x[i]) != i) { - throw new AssertionError("get " + x[i] + " = " + map.get(i) + " should be " + i); - } - } - for (int i = 1; i < len; i += 2) { - map.remove(x[i]); - } - for (int i = 1; i < len; i += 2) { - if (map.get(x[i]) != -1) { - throw new AssertionError("get " + x[i] + " = " + map.get(i) + " should be <=0"); - } - } - for (int i = 1; i < len; i += 2) { - map.put(x[i], i); - } - for (int i = 0; i < len; i++) { - if (map.get(x[i]) != i) { - throw new AssertionError("get " + x[i] + " = " + map.get(i) + " should be " + i); - } - } - } -} diff --git a/tools/h2/src/test/org/h2/test/unit/TestMathUtils.java b/tools/h2/src/test/org/h2/test/unit/TestMathUtils.java deleted file mode 100755 index cc80fa3..0000000 --- a/tools/h2/src/test/org/h2/test/unit/TestMathUtils.java +++ /dev/null @@ -1,107 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.test.unit; - -import java.math.BigInteger; -import java.util.Random; -import org.h2.test.TestBase; -import org.h2.util.MathUtils; - -/** - * Tests math utility methods. - */ -public class TestMathUtils extends TestBase { - - /** - * Run just this test. - * - * @param a ignored - */ - public static void main(String... a) throws Exception { - TestBase.createCaller().init().test(); - } - - public void test() { - testReverse(); - testFactorial(); - } - - private void testReverse() { - assertEquals(Integer.reverse(0), MathUtils.reverseInt(0)); - assertEquals(Integer.reverse(Integer.MAX_VALUE), MathUtils.reverseInt(Integer.MAX_VALUE)); - assertEquals(Integer.reverse(Integer.MIN_VALUE), MathUtils.reverseInt(Integer.MIN_VALUE)); - assertEquals(Long.reverse(0), MathUtils.reverseLong(0L)); - assertEquals(Long.reverse(Long.MAX_VALUE), MathUtils.reverseLong(Long.MAX_VALUE)); - assertEquals(Long.reverse(Long.MIN_VALUE), MathUtils.reverseLong(Long.MIN_VALUE)); - for (int i = Integer.MIN_VALUE; i < 0; i += 1019) { - int x = MathUtils.reverseInt(i); - assertEquals(Integer.reverse(i), x); - } - for (int i = 0; i > 0; i += 1019) { - int x = MathUtils.reverseInt(i); - assertEquals(Integer.reverse(i), x); - } - for (long i = Long.MIN_VALUE; i < 0; i += 1018764321251L) { - long x = MathUtils.reverseLong(i); - assertEquals(Long.reverse(i), x); - } - for (long i = 0; i > 0; i += 1018764321251L) { - long x = MathUtils.reverseLong(i); - assertEquals(Long.reverse(i), x); - } - Random random = new Random(10); - for (int i = 0; i < 1000000; i++) { - long x = random.nextLong(); - long r = MathUtils.reverseLong(x); - assertEquals(Long.reverse(x), r); - int y = random.nextInt(); - int s = MathUtils.reverseInt(y); - assertEquals(Integer.reverse(y), s); - } - } - - private void testFactorial() { - try { - factorial(-1); - fail(); - } catch (IllegalArgumentException e) { - // ignore - } - assertEquals("1", factorial(0).toString()); - assertEquals("1", factorial(1).toString()); - assertEquals("2", factorial(2).toString()); - assertEquals("6", factorial(3).toString()); - assertEquals("3628800", factorial(10).toString()); - assertEquals("2432902008176640000", factorial(20).toString()); - } - - /** - * Calculate the factorial (n!) of a number. - * This implementation uses a naive multiplication loop, and - * is very slow for large n. - * For n = 1000, it takes about 10 ms. - * For n = 8000, it takes about 800 ms. - * - * @param n the number - * @return the factorial of n - */ - public static BigInteger factorial(int n) { - if (n < 0) { - throw new IllegalArgumentException(n + "<0"); - } else if (n < 2) { - return BigInteger.ONE; - } - BigInteger x = new BigInteger("" + n); - BigInteger result = x; - for (int i = n - 1; i >= 2; i--) { - x = x.subtract(BigInteger.ONE); - result = result.multiply(x); - } - return result; - } - -} diff --git a/tools/h2/src/test/org/h2/test/unit/TestMultiThreadedKernel.java b/tools/h2/src/test/org/h2/test/unit/TestMultiThreadedKernel.java deleted file mode 100755 index a7ec8c7..0000000 --- a/tools/h2/src/test/org/h2/test/unit/TestMultiThreadedKernel.java +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.test.unit; - -import java.sql.Connection; -import java.sql.DriverManager; -import java.sql.PreparedStatement; -import java.sql.SQLException; - -import org.h2.test.TestBase; - -/** - * Tests the multi-threaded kernel feature. - */ -public class TestMultiThreadedKernel extends TestBase implements Runnable { - - private String url, user, password; - private int id; - private TestMultiThreadedKernel master; - private volatile boolean stop; - - /** - * Run just this test. - * - * @param a ignored - */ - public static void main(String... a) throws Exception { - TestBase.createCaller().init().test(); - } - - public void test() throws Exception { - if (config.networked || config.mvcc) { - return; - } - deleteDb("multiThreadedKernel"); - int count = getSize(2, 5); - Thread[] list = new Thread[count]; - for (int i = 0; i < count; i++) { - TestMultiThreadedKernel r = new TestMultiThreadedKernel(); - r.url = getURL("multiThreadedKernel;MULTI_THREADED=1", true); - r.user = getUser(); - r.password = getPassword(); - r.master = this; - r.id = i; - Thread thread = new Thread(r); - thread.setName("Thread " + i); - thread.start(); - list[i] = thread; - } - Thread.sleep(getSize(2000, 5000)); - stop = true; - for (int i = 0; i < count; i++) { - list[i].join(); - } - deleteDb("multiThreadedKernel"); - } - - public void run() { - try { - org.h2.Driver.load(); - Connection conn = DriverManager.getConnection(url + ";MULTI_THREADED=1;LOCK_MODE=3;WRITE_DELAY=0", user, password); - conn.createStatement().execute( - "CREATE TABLE TEST" + id + "(COL1 BIGINT AUTO_INCREMENT PRIMARY KEY, COL2 BIGINT)"); - PreparedStatement prep = conn.prepareStatement("insert into TEST" + id + "(col2) values (?)"); - for (int i = 0; !master.stop; i++) { - prep.setLong(1, i); - prep.execute(); - } - conn.close(); - } catch (SQLException e) { - e.printStackTrace(); - } - } - -} diff --git a/tools/h2/src/test/org/h2/test/unit/TestNetUtils.java b/tools/h2/src/test/org/h2/test/unit/TestNetUtils.java deleted file mode 100755 index 157f94b..0000000 --- a/tools/h2/src/test/org/h2/test/unit/TestNetUtils.java +++ /dev/null @@ -1,124 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: Sergi Vladykin - */ -package org.h2.test.unit; - -import java.io.IOException; -import java.net.ServerSocket; -import java.net.Socket; -import java.util.HashSet; -import java.util.Set; -import java.util.concurrent.atomic.AtomicInteger; -import org.h2.test.TestBase; -import org.h2.util.NetUtils; - -/** - * Test the network utilities. - * - * @author Sergi Vladykin - */ -public class TestNetUtils extends TestBase { - - private static final int WORKER_COUNT = 10; - private static final int PORT = 9111; - - /** - * Run just this test. - * - * @param a ignored - */ - public static void main(String... a) throws Exception { - TestBase.createCaller().init().test(); - } - - public void test() throws Exception { - testFrequentConnections(true, 100); - testFrequentConnections(false, 1000); - } - - private void testFrequentConnections(boolean ssl, int count) throws Exception { - final ServerSocket serverSocket = NetUtils.createServerSocket(PORT, ssl); - final AtomicInteger counter = new AtomicInteger(count); - Thread serverThread = new Thread() { - public void run() { - while (!isInterrupted()) { - try { - Socket socket = serverSocket.accept(); - // System.out.println("opened " + counter); - socket.close(); - } catch (Exception e) { - // ignore - } - } - // System.out.println("stopped "); - - } - }; - serverThread.start(); - try { - Set workers = new HashSet(); - for (int i = 0; i < WORKER_COUNT; i++) { - workers.add(new ConnectWorker(ssl, counter)); - } - // ensure the server is started - Thread.sleep(100); - for (ConnectWorker worker : workers) { - worker.start(); - } - for (ConnectWorker worker : workers) { - worker.join(); - Exception e = worker.getException(); - if (e != null) { - e.printStackTrace(); - } - } - } finally { - try { - serverSocket.close(); - } catch (Exception e) { - // ignore - } - serverThread.interrupt(); - serverThread.join(); - } - } - - /** - * A worker thread to test connecting. - */ - private class ConnectWorker extends Thread { - - private final boolean ssl; - private final AtomicInteger counter; - private Exception exception; - - public ConnectWorker(boolean ssl, AtomicInteger counter) { - this.ssl = ssl; - this.counter = counter; - } - - public void run() { - try { - while (!isInterrupted() && counter.decrementAndGet() > 0) { - Socket socket = NetUtils.createLoopbackSocket(PORT, ssl); - try { - socket.close(); - } catch (IOException e) { - // ignore - } - } - } catch (Exception e) { - exception = new Exception("count: " + counter, e); - } - } - - public Exception getException() { - return exception; - } - - } - -} diff --git a/tools/h2/src/test/org/h2/test/unit/TestOldVersion.java b/tools/h2/src/test/org/h2/test/unit/TestOldVersion.java deleted file mode 100755 index 18d23c0..0000000 --- a/tools/h2/src/test/org/h2/test/unit/TestOldVersion.java +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, Version - * 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). Initial Developer: H2 Group - */ -package org.h2.test.unit; - -import java.lang.reflect.Method; -import java.net.URL; -import java.net.URLClassLoader; -import java.sql.Connection; -import java.sql.Driver; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.sql.Statement; -import org.h2.constant.ErrorCode; -import org.h2.test.TestBase; -import org.h2.tools.Server; - -/** - * Tests the compatibility with older versions - */ -public class TestOldVersion extends TestBase { - - /** - * Run just this test. - * - * @param a ignored - */ - public static void main(String... a) throws Exception { - TestBase.createCaller().init().test(); - } - - public void test() throws Exception { - URL[] urls = { new URL("file:ext/h2-1.2.127.jar") }; - ClassLoader cl = new URLClassLoader(urls, null); - // cl = getClass().getClassLoader(); - Class< ? > driverClass = cl.loadClass("org.h2.Driver"); - Method m = driverClass.getMethod("load"); - Driver driver = (Driver) m.invoke(null); - Connection conn = driver.connect("jdbc:h2:mem:", null); - assertEquals("1.2.127 (2010-01-15)", conn.getMetaData().getDatabaseProductVersion()); - Server server = org.h2.tools.Server.createTcpServer("-tcpPort", "9001"); - server.start(); - try { - conn = driver.connect("jdbc:h2:tcp://localhost:9001/mem:test", null); - } catch (SQLException e) { - assertEquals(ErrorCode.DRIVER_VERSION_ERROR_2, e.getErrorCode()); - } - server.stop(); - - Class< ? > serverClass = cl.loadClass("org.h2.tools.Server"); - m = serverClass.getMethod("createTcpServer", String[].class); - Object serverOld = m.invoke(null, new Object[]{new String[]{"-tcpPort", "9001"}}); - m = serverOld.getClass().getMethod("start"); - m.invoke(serverOld); - conn = org.h2.Driver.load().connect("jdbc:h2:mem:", null); - Statement stat = conn.createStatement(); - ResultSet rs = stat.executeQuery("call 1"); - rs.next(); - assertEquals(1, rs.getInt(1)); - conn.close(); - m = serverOld.getClass().getMethod("stop"); - m.invoke(serverOld); - } - -} diff --git a/tools/h2/src/test/org/h2/test/unit/TestOverflow.java b/tools/h2/src/test/org/h2/test/unit/TestOverflow.java deleted file mode 100755 index 2436cfd..0000000 --- a/tools/h2/src/test/org/h2/test/unit/TestOverflow.java +++ /dev/null @@ -1,130 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.test.unit; - -import java.math.BigInteger; -import java.util.ArrayList; -import java.util.Random; -import org.h2.test.TestBase; -import org.h2.util.New; -import org.h2.value.Value; -import org.h2.value.ValueString; - -/** - * Tests numeric overflow on various data types. - * Other than in Java, overflow is detected and an exception is thrown. - */ -public class TestOverflow extends TestBase { - - private ArrayList values; - private int dataType; - private BigInteger min, max; - private boolean successExpected; - - /** - * Run just this test. - * - * @param a ignored - */ - public static void main(String... a) throws Exception { - TestBase.createCaller().init().test(); - } - - public void test() { - test(Value.BYTE, Byte.MIN_VALUE, Byte.MAX_VALUE); - test(Value.INT, Integer.MIN_VALUE, Integer.MAX_VALUE); - test(Value.LONG, Long.MIN_VALUE, Long.MAX_VALUE); - test(Value.SHORT, Short.MIN_VALUE, Short.MAX_VALUE); - } - - private void test(int type, long minValue, long maxValue) { - values = New.arrayList(); - this.dataType = type; - this.min = new BigInteger("" + minValue); - this.max = new BigInteger("" + maxValue); - add(0); - add(minValue); - add(maxValue); - add(maxValue - 1); - add(minValue + 1); - add(1); - add(-1); - Random random = new Random(1); - for (int i = 0; i < 40; i++) { - if (maxValue > Integer.MAX_VALUE) { - add(random.nextLong()); - } else { - add((random.nextBoolean() ? 1 : -1) * random.nextInt((int) maxValue)); - } - } - for (Value va : values) { - for (Value vb : values) { - testValues(va, vb); - } - } - } - - private void checkIfExpected(String a, String b) { - if (successExpected) { - assertEquals(a, b); - } - } - - private void onSuccess() { - if (!successExpected) { - fail(); - } - } - - private void onError() { - if (successExpected) { - fail(); - } - } - - private void testValues(Value va, Value vb) { - BigInteger a = new BigInteger(va.getString()); - BigInteger b = new BigInteger(vb.getString()); - successExpected = inRange(a.negate()); - try { - checkIfExpected(va.negate().getString(), a.negate().toString()); - onSuccess(); - } catch (Exception e) { - onError(); - } - successExpected = inRange(a.add(b)); - try { - checkIfExpected(va.add(vb).getString(), a.add(b).toString()); - onSuccess(); - } catch (Exception e) { - onError(); - } - successExpected = inRange(a.subtract(b)); - try { - checkIfExpected(va.subtract(vb).getString(), a.subtract(b).toString()); - onSuccess(); - } catch (Exception e) { - onError(); - } - successExpected = inRange(a.multiply(b)); - try { - checkIfExpected(va.multiply(vb).getString(), a.multiply(b).toString()); - onSuccess(); - } catch (Exception e) { - onError(); - } - } - - private boolean inRange(BigInteger v) { - return v.compareTo(min) >= 0 && v.compareTo(max) <= 0; - } - - private void add(long l) { - values.add(ValueString.get("" + l).convertTo(dataType)); - } - -} diff --git a/tools/h2/src/test/org/h2/test/unit/TestPageStore.java b/tools/h2/src/test/org/h2/test/unit/TestPageStore.java deleted file mode 100755 index 12b83fd..0000000 --- a/tools/h2/src/test/org/h2/test/unit/TestPageStore.java +++ /dev/null @@ -1,663 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.test.unit; - -import java.sql.Connection; -import java.sql.DriverManager; -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.sql.Statement; -import java.util.Random; -import java.util.Set; -import java.util.TreeSet; -import org.h2.api.DatabaseEventListener; -import org.h2.test.TestBase; -import org.h2.util.IOUtils; - -/** - * Test the page store. - */ -public class TestPageStore extends TestBase implements DatabaseEventListener { - - static StringBuilder eventBuffer = new StringBuilder(); - - /** - * Run just this test. - * - * @param a ignored - */ - public static void main(String... a) throws Exception { - TestBase.createCaller().init().test(); - } - - public void test() throws Exception { - testCheckpoint(); - testDropRecreate(); - testDropAll(); - testCloseTempTable(); - testDuplicateKey(); - testUpdateOverflow(); - testTruncateReconnect(); - testReverseIndex(); - testLargeUpdates(); - testLargeInserts(); - testLargeDatabaseFastOpen(); - testUniqueIndexReopen(); - testExistingOld(); - testLargeRows(); - testRecoverDropIndex(); - testDropPk(); - testCreatePkLater(); - testTruncate(); - testLargeIndex(); - testUniqueIndex(); - testCreateIndexLater(); - testFuzzOperations(); - deleteDb("pageStore"); - } - - private void testCheckpoint() throws SQLException { - deleteDb("pageStore"); - Connection conn; - conn = getConnection("pageStore"); - Statement stat = conn.createStatement(); - stat.execute("create table test(data varchar)"); - stat.execute("create sequence seq"); - stat.execute("set max_log_size 1"); - conn.setAutoCommit(false); - stat.execute("insert into test select space(1000) from system_range(1, 1000)"); - long before = System.currentTimeMillis(); - stat.execute("select nextval('SEQ') from system_range(1, 100000)"); - long after = System.currentTimeMillis(); - // it's hard to test - basically it shouldn't checkpoint too often - if (after - before > 10000) { - fail("Checkpoint took " + (after - before) + " ms"); - } - stat.execute("drop table test"); - stat.execute("drop sequence seq"); - conn.close(); - } - - private void testDropRecreate() throws SQLException { - if (config.memory) { - return; - } - deleteDb("pageStore"); - Connection conn; - conn = getConnection("pageStore"); - Statement stat = conn.createStatement(); - stat.execute("create table test(id int)"); - stat.execute("create index idx_test on test(id)"); - stat.execute("create table test2(id int)"); - stat.execute("drop table test"); - // this will re-used the object id of the test table, - // which is lower than the object id of test2 - stat.execute("create index idx_test on test2(id)"); - conn.close(); - conn = getConnection("pageStore"); - conn.close(); - } - - private void testDropAll() throws SQLException { - deleteDb("pageStore"); - Connection conn; - String url = "pageStore"; - conn = getConnection(url); - Statement stat = conn.createStatement(); - stat.execute("CREATE TEMP TABLE A(A INT)"); - stat.execute("CREATE TABLE B(A VARCHAR IDENTITY)"); - stat.execute("CREATE TEMP TABLE C(A INT)"); - conn.close(); - conn = getConnection(url); - stat = conn.createStatement(); - stat.execute("DROP ALL OBJECTS"); - conn.close(); - } - - private void testCloseTempTable() throws SQLException { - deleteDb("pageStore"); - Connection conn; - String url = "pageStore;CACHE_SIZE=0"; - conn = getConnection(url); - Statement stat = conn.createStatement(); - stat.execute("create local temporary table test(id int)"); - conn.rollback(); - Connection conn2 = getConnection(url); - Statement stat2 = conn2.createStatement(); - stat2.execute("create table test2 as select x from system_range(1, 5000)"); - stat2.execute("shutdown immediately"); - try { - conn.close(); - fail(); - } catch (SQLException e) { - assertKnownException(e); - } - try { - conn2.close(); - fail(); - } catch (SQLException e) { - assertKnownException(e); - } - } - - private void testDuplicateKey() throws SQLException { - deleteDb("pageStore"); - Connection conn; - conn = getConnection("pageStore"); - Statement stat = conn.createStatement(); - stat.execute("create table test(id int primary key, name varchar)"); - stat.execute("insert into test values(0, space(3000))"); - try { - stat.execute("insert into test values(0, space(3000))"); - } catch (SQLException e) { - // ignore - } - stat.execute("select * from test"); - conn.close(); - } - - private void testTruncateReconnect() throws SQLException { - if (config.memory) { - return; - } - deleteDb("pageStore"); - Connection conn; - conn = getConnection("pageStore"); - conn.createStatement().execute("create table test(id int primary key, name varchar)"); - conn.createStatement().execute("insert into test(id) select x from system_range(1, 390)"); - conn.createStatement().execute("checkpoint"); - conn.createStatement().execute("shutdown immediately"); - conn = getConnection("pageStore"); - conn.createStatement().execute("truncate table test"); - conn.createStatement().execute("insert into test(id) select x from system_range(1, 390)"); - conn.createStatement().execute("shutdown immediately"); - conn = getConnection("pageStore"); - conn.close(); - } - - private void testUpdateOverflow() throws SQLException { - if (config.memory) { - return; - } - deleteDb("pageStore"); - Connection conn; - conn = getConnection("pageStore"); - conn.createStatement().execute("create table test(id int primary key, name varchar)"); - conn.createStatement().execute("insert into test values(0, space(3000))"); - conn.createStatement().execute("checkpoint"); - conn.createStatement().execute("shutdown immediately"); - - conn = getConnection("pageStore"); - conn.createStatement().execute("update test set id = 1"); - conn.createStatement().execute("shutdown immediately"); - - conn = getConnection("pageStore"); - conn.close(); - } - - private void testReverseIndex() throws SQLException { - if (config.memory) { - return; - } - deleteDb("pageStore"); - Connection conn = getConnection("pageStore"); - Statement stat = conn.createStatement(); - stat.execute("create table test(x int, y varchar default space(200))"); - for (int i = 30; i < 100; i++) { - stat.execute("insert into test(x) select null from system_range(1, " + i + ")"); - stat.execute("insert into test(x) select x from system_range(1, " + i + ")"); - stat.execute("create index idx on test(x desc, y)"); - ResultSet rs = stat.executeQuery("select min(x) from test"); - rs.next(); - assertEquals(1, rs.getInt(1)); - stat.execute("drop index idx"); - stat.execute("truncate table test"); - } - conn.close(); - } - - private void testLargeUpdates() throws SQLException { - if (config.memory) { - return; - } - deleteDb("pageStore"); - Connection conn; - conn = getConnection("pageStore"); - Statement stat = conn.createStatement(); - int size = 1500; - stat.execute("call rand(1)"); - stat.execute("create table test(id int primary key, data varchar, test int) as " + - "select x, '', 123 from system_range(1, " + size + ")"); - Random random = new Random(1); - PreparedStatement prep = conn.prepareStatement( - "update test set data=space(?) where id=?"); - for (int i = 0; i < 2500; i++) { - int id = random.nextInt(size); - int newSize = random.nextInt(6000); - prep.setInt(1, newSize); - prep.setInt(2, id); - prep.execute(); - } - conn.close(); - conn = getConnection("pageStore"); - stat = conn.createStatement(); - ResultSet rs = stat.executeQuery("select * from test where test<>123"); - assertFalse(rs.next()); - conn.close(); - } - - private void testLargeInserts() throws SQLException { - if (config.memory) { - return; - } - deleteDb("pageStore"); - Connection conn; - conn = getConnection("pageStore"); - Statement stat = conn.createStatement(); - stat.execute("create table test(data varchar)"); - stat.execute("insert into test values(space(1024 * 1024))"); - stat.execute("insert into test values(space(1024 * 1024))"); - conn.close(); - } - - private void testLargeDatabaseFastOpen() throws SQLException { - if (config.memory) { - return; - } - deleteDb("pageStore"); - Connection conn; - String url = "pageStore"; - conn = getConnection(url); - conn.createStatement().execute("CREATE TABLE TEST(ID INT PRIMARY KEY, NAME VARCHAR)"); - conn.createStatement().execute("create unique index idx_test_name on test(name)"); - conn.createStatement().execute("INSERT INTO TEST SELECT X, X || space(10) FROM SYSTEM_RANGE(1, 1000)"); - conn.close(); - conn = getConnection(url); - conn.createStatement().execute("DELETE FROM TEST WHERE ID=1"); - conn.createStatement().execute("CHECKPOINT"); - conn.createStatement().execute("SHUTDOWN IMMEDIATELY"); - try { - conn.close(); - } catch (SQLException e) { - // ignore - } - eventBuffer.setLength(0); - conn = getConnection(url + ";DATABASE_EVENT_LISTENER='" + getClass().getName() + "'"); - assertEquals("init;opened;", eventBuffer.toString()); - conn.close(); - } - - private void testUniqueIndexReopen() throws SQLException { - if (config.memory) { - return; - } - deleteDb("pageStore"); - Connection conn; - String url = "pageStore"; - conn = getConnection(url); - conn.createStatement().execute("CREATE TABLE test(ID INT PRIMARY KEY, NAME VARCHAR(255))"); - conn.createStatement().execute("create unique index idx_test_name on test(name)"); - conn.createStatement().execute("INSERT INTO TEST VALUES(1, 'Hello')"); - conn.close(); - conn = getConnection(url); - try { - conn.createStatement().execute("INSERT INTO TEST VALUES(2, 'Hello')"); - fail(); - } catch (SQLException e) { - assertKnownException(e); - } - conn.close(); - } - - private void testExistingOld() throws SQLException { - if (config.memory) { - return; - } - Connection conn; - deleteDb("pageStore"); - String url; - url = "jdbc:h2:" + getBaseDir() + "/pageStore"; - conn = DriverManager.getConnection(url); - conn.createStatement().execute("create table test(id int) as select 1"); - conn.close(); - conn = DriverManager.getConnection(url); - conn.createStatement().execute("select * from test"); - conn.close(); - // the database is automatically converted - conn = DriverManager.getConnection(url); - assertResult("1", conn.createStatement(), "select * from test"); - conn.close(); - } - - private void testLargeRows() throws Exception { - if (config.memory) { - return; - } - for (int i = 0; i < 10; i++) { - testLargeRows(i); - } - } - - private void testLargeRows(int seed) throws Exception { - deleteDb("pageStore"); - String url = getURL("pageStore;CACHE_SIZE=16", true); - Connection conn = null; - Statement stat = null; - int count = 0; - try { - Class.forName("org.h2.Driver"); - conn = DriverManager.getConnection(url); - stat = conn.createStatement(); - int tableCount = 1; - PreparedStatement[] insert = new PreparedStatement[tableCount]; - PreparedStatement[] deleteMany = new PreparedStatement[tableCount]; - PreparedStatement[] updateMany = new PreparedStatement[tableCount]; - for (int i = 0; i < tableCount; i++) { - stat.execute("create table test" + i + "(id int primary key, name varchar)"); - stat.execute("create index idx_test" + i + " on test" + i + "(name)"); - insert[i] = conn.prepareStatement("insert into test" + i + " values(?, ? || space(?))"); - deleteMany[i] = conn.prepareStatement("delete from test" + i + " where id between ? and ?"); - updateMany[i] = conn.prepareStatement("update test" + i - + " set name=? || space(?) where id between ? and ?"); - } - Random random = new Random(seed); - for (int i = 0; i < 1000; i++) { - count = i; - PreparedStatement p; - if (random.nextInt(100) < 95) { - p = insert[random.nextInt(tableCount)]; - p.setInt(1, i); - p.setInt(2, i); - if (random.nextInt(30) == 5) { - p.setInt(3, 3000); - } else { - p.setInt(3, random.nextInt(100)); - } - p.execute(); - } else if (random.nextInt(100) < 90) { - p = updateMany[random.nextInt(tableCount)]; - p.setInt(1, i); - p.setInt(2, random.nextInt(50)); - int first = random.nextInt(1 + i); - p.setInt(3, first); - p.setInt(4, first + random.nextInt(50)); - p.executeUpdate(); - } else { - p = deleteMany[random.nextInt(tableCount)]; - int first = random.nextInt(1 + i); - p.setInt(1, first); - p.setInt(2, first + random.nextInt(100)); - p.executeUpdate(); - } - } - conn.close(); - conn = DriverManager.getConnection(url); - conn.close(); - conn = DriverManager.getConnection(url); - stat = conn.createStatement(); - stat.execute("script to '" + getBaseDir() + "/pageStore.sql'"); - conn.close(); - IOUtils.delete(getBaseDir() + "/pageStore.sql"); - } catch (Exception e) { - try { - stat.execute("shutdown immediately"); - } catch (SQLException e2) { - // ignore - } - try { - conn.close(); - } catch (SQLException e2) { - // ignore - } - fail("count: " + count + " " + e); - } - } - - private void testRecoverDropIndex() throws SQLException { - if (config.memory) { - return; - } - deleteDb("pageStore"); - Connection conn = getConnection("pageStore"); - Statement stat = conn.createStatement(); - stat.execute("set write_delay 0"); - stat.execute("create table test(id int, name varchar) as select x, x from system_range(1, 1400)"); - stat.execute("create index idx_name on test(name)"); - conn.close(); - conn = getConnection("pageStore"); - stat = conn.createStatement(); - stat.execute("drop index idx_name"); - stat.execute("shutdown immediately"); - try { - conn.close(); - } catch (SQLException e) { - // ignore - } - conn = getConnection("pageStore;cache_size=1"); - conn.close(); - } - - private void testDropPk() throws SQLException { - if (config.memory) { - return; - } - deleteDb("pageStore"); - Connection conn; - Statement stat; - conn = getConnection("pageStore"); - stat = conn.createStatement(); - stat.execute("create table test(id int primary key)"); - stat.execute("insert into test values(" + Integer.MIN_VALUE + "), (" + Integer.MAX_VALUE + ")"); - stat.execute("alter table test drop primary key"); - conn.close(); - conn = getConnection("pageStore"); - stat = conn.createStatement(); - stat.execute("insert into test values(" + Integer.MIN_VALUE + "), (" + Integer.MAX_VALUE + ")"); - conn.close(); - } - - private void testCreatePkLater() throws SQLException { - if (config.memory) { - return; - } - deleteDb("pageStore"); - Connection conn; - Statement stat; - conn = getConnection("pageStore"); - stat = conn.createStatement(); - stat.execute("create table test(id int not null) as select 100"); - stat.execute("create primary key on test(id)"); - conn.close(); - conn = getConnection("pageStore"); - stat = conn.createStatement(); - ResultSet rs = stat.executeQuery("select * from test where id = 100"); - assertTrue(rs.next()); - conn.close(); - } - - private void testTruncate() throws SQLException { - if (config.memory) { - return; - } - deleteDb("pageStore"); - Connection conn = getConnection("pageStore"); - Statement stat = conn.createStatement(); - stat.execute("set write_delay 0"); - stat.execute("create table test(id int) as select 1"); - stat.execute("truncate table test"); - stat.execute("insert into test values(1)"); - stat.execute("shutdown immediately"); - try { - conn.close(); - } catch (SQLException e) { - // ignore - } - conn = getConnection("pageStore"); - conn.close(); - } - - private void testLargeIndex() throws SQLException { - if (config.memory) { - return; - } - deleteDb("pageStore"); - Connection conn = getConnection("pageStore"); - conn.createStatement().execute("create table test(id varchar primary key, d varchar)"); - PreparedStatement prep = conn.prepareStatement("insert into test values(?, space(500))"); - for (int i = 0; i < 20000; i++) { - prep.setString(1, "" + i); - prep.executeUpdate(); - } - conn.close(); - } - - private void testUniqueIndex() throws SQLException { - if (config.memory) { - return; - } - deleteDb("pageStore"); - Connection conn = getConnection("pageStore"); - Statement stat = conn.createStatement(); - stat.execute("CREATE TABLE TEST(ID INT UNIQUE)"); - stat.execute("INSERT INTO TEST VALUES(1)"); - conn.close(); - conn = getConnection("pageStore"); - try { - conn.createStatement().execute("INSERT INTO TEST VALUES(1)"); - fail(); - } catch (SQLException e) { - assertKnownException(e); - } - conn.close(); - } - - private void testCreateIndexLater() throws SQLException { - deleteDb("pageStore"); - Connection conn = getConnection("pageStore"); - Statement stat = conn.createStatement(); - stat.execute("CREATE TABLE TEST(NAME VARCHAR) AS SELECT 1"); - stat.execute("CREATE INDEX IDX_N ON TEST(NAME)"); - stat.execute("INSERT INTO TEST SELECT X FROM SYSTEM_RANGE(20, 100)"); - stat.execute("INSERT INTO TEST SELECT X FROM SYSTEM_RANGE(1000, 1100)"); - stat.execute("SHUTDOWN IMMEDIATELY"); - try { - conn.close(); - } catch (SQLException e) { - // ignore - } - conn = getConnection("pageStore"); - conn.close(); - } - - private void testFuzzOperations() throws SQLException { - int best = Integer.MAX_VALUE; - for (int i = 0; i < 10; i++) { - int x = testFuzzOperationsSeed(i, 10); - if (x >= 0 && x < best) { - best = x; - fail("op:" + x + " seed:" + i); - } - } - } - - private int testFuzzOperationsSeed(int seed, int len) throws SQLException { - deleteDb("pageStore"); - Connection conn = getConnection("pageStore"); - Statement stat = conn.createStatement(); - log("DROP TABLE IF EXISTS TEST;"); - stat.execute("DROP TABLE IF EXISTS TEST"); - log("CREATE TABLE TEST(ID INT PRIMARY KEY, NAME VARCHAR DEFAULT 'Hello World');"); - stat.execute("CREATE TABLE TEST(ID INT PRIMARY KEY, NAME VARCHAR DEFAULT 'Hello World')"); - Set rows = new TreeSet(); - Random random = new Random(seed); - for (int i = 0; i < len; i++) { - int op = random.nextInt(3); - Integer x = new Integer(random.nextInt(100)); - switch (op) { - case 0: - if (!rows.contains(x)) { - log("insert into test(id) values(" + x + ");"); - stat.execute("INSERT INTO TEST(ID) VALUES(" + x + ");"); - rows.add(x); - } - break; - case 1: - if (rows.contains(x)) { - log("delete from test where id=" + x + ";"); - stat.execute("DELETE FROM TEST WHERE ID=" + x); - rows.remove(x); - } - break; - case 2: - conn.close(); - conn = getConnection("pageStore"); - stat = conn.createStatement(); - ResultSet rs = stat.executeQuery("SELECT * FROM TEST ORDER BY ID"); - log("--reconnect"); - for (int test : rows) { - if (!rs.next()) { - log("error: expected next"); - conn.close(); - return i; - } - int y = rs.getInt(1); - // System.out.println(" " + x); - if (y != test) { - log("error: " + y + " <> " + test); - conn.close(); - return i; - } - } - if (rs.next()) { - log("error: unexpected next"); - conn.close(); - return i; - } - } - } - conn.close(); - return -1; - } - - private void log(String m) { - trace(" " + m); - } - - public void closingDatabase() { - event("closing"); - } - - public void diskSpaceIsLow() { - event("diskSpaceIsLow"); - } - - public void exceptionThrown(SQLException e, String sql) { - event("exceptionThrown " + e + " " + sql); - } - - public void init(String url) { - event("init"); - } - - public void opened() { - event("opened"); - } - - public void setProgress(int state, String name, int x, int max) { - if (name.startsWith("SYS:SYS_ID")) { - // ignore - return; - } - event("setProgress " + state + " " + name + " " + x + " " + max); - } - - private void event(String s) { - eventBuffer.append(s).append(';'); - } - -} diff --git a/tools/h2/src/test/org/h2/test/unit/TestPageStoreCoverage.java b/tools/h2/src/test/org/h2/test/unit/TestPageStoreCoverage.java deleted file mode 100755 index 8137549..0000000 --- a/tools/h2/src/test/org/h2/test/unit/TestPageStoreCoverage.java +++ /dev/null @@ -1,238 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.test.unit; - -import java.sql.Connection; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.sql.Statement; -import org.h2.engine.Constants; -import org.h2.store.fs.FileObject; -import org.h2.store.fs.FileSystem; -import org.h2.test.TestBase; -import org.h2.tools.Restore; -import org.h2.util.IOUtils; - -/** - * Test the page store. - */ -public class TestPageStoreCoverage extends TestBase { - - private static final String URL = "pageStore;PAGE_SIZE=64;CACHE_SIZE=16;MAX_LOG_SIZE=1"; - - /** - * Run just this test. - * - * @param a ignored - */ - public static void main(String... a) throws Exception { - TestBase.createCaller().init().test(); - } - - public void test() throws Exception { - // TODO mvcc, 2-phase commit - if (config.memory) { - return; - } - deleteDb("pageStore"); - testMoveRoot(); - testBasic(); - testReadOnly(); - testIncompleteCreate(); - testBackupRestore(); - testTrim(); - testLongTransaction(); - testRecoverTemp(); - deleteDb("pageStore"); - } - - private void testMoveRoot() throws SQLException { - Connection conn; - conn = getConnection(URL); - Statement stat = conn.createStatement(); - stat.execute("create table test(id int primary key) as select x from system_range(1, 100)"); - for (int i = 0; i < 10; i++) { - stat.execute("create table test" + i + "(id int primary key) as select x from system_range(1, 2)"); - } - stat.execute("drop table test"); - conn.close(); - - conn = getConnection(URL); - stat = conn.createStatement(); - for (int i = 0; i < 10; i++) { - ResultSet rs = stat.executeQuery("select * from test" + i); - while (rs.next()) { - // ignore - } - } - stat.execute("drop all objects delete files"); - conn.close(); - } - - private void testRecoverTemp() throws SQLException { - Connection conn; - conn = getConnection(URL); - Statement stat = conn.createStatement(); - stat.execute("create cached temporary table test(id identity, name varchar)"); - stat.execute("create index idx_test_name on test(name)"); - stat.execute("create index idx_test_name2 on test(name, id)"); - stat.execute("create table test2(id identity, name varchar)"); - stat.execute("create index idx_test2_name on test2(name desc)"); - stat.execute("create index idx_test2_name2 on test2(name, id)"); - stat.execute("insert into test2 select null, space(10) from system_range(1, 10)"); - stat.execute("create table test3(id identity, name varchar)"); - stat.execute("checkpoint"); - conn.setAutoCommit(false); - stat.execute("create table test4(id identity, name varchar)"); - stat.execute("create index idx_test4_name2 on test(name, id)"); - stat.execute("insert into test select null, space(10) from system_range(1, 10)"); - stat.execute("insert into test3 select null, space(10) from system_range(1, 10)"); - stat.execute("insert into test4 select null, space(10) from system_range(1, 10)"); - stat.execute("truncate table test2"); - stat.execute("drop index idx_test_name"); - stat.execute("drop index idx_test2_name"); - stat.execute("drop table test2"); - stat.execute("insert into test select null, space(10) from system_range(1, 10)"); - stat.execute("shutdown immediately"); - try { - conn.close(); - fail(); - } catch (SQLException e) { - // ignore - } - conn = getConnection(URL); - stat = conn.createStatement(); - stat.execute("drop all objects"); - // re-allocate index root pages - for (int i = 0; i < 10; i++) { - stat.execute("create table test" + i + "(id identity, name varchar)"); - } - stat.execute("checkpoint"); - for (int i = 0; i < 10; i++) { - stat.execute("drop table test" + i); - } - for (int i = 0; i < 10; i++) { - stat.execute("create table test" + i + "(id identity, name varchar)"); - } - stat.execute("shutdown immediately"); - try { - conn.close(); - fail(); - } catch (SQLException e) { - // ignore - } - conn = getConnection(URL); - conn.createStatement().execute("drop all objects"); - conn.close(); - } - - private void testLongTransaction() throws SQLException { - Connection conn; - conn = getConnection(URL); - Statement stat = conn.createStatement(); - stat.execute("create table test(id identity, name varchar)"); - conn.setAutoCommit(false); - stat.execute("insert into test select null, space(10) from system_range(1, 10)"); - Connection conn2; - conn2 = getConnection(URL); - Statement stat2 = conn2.createStatement(); - stat2.execute("checkpoint"); - // large transaction - stat2.execute("create table test2(id identity, name varchar)"); - stat2.execute("create index idx_test2_name on test2(name)"); - stat2.execute("insert into test2 select null, x || space(10000) from system_range(1, 100)"); - stat2.execute("drop table test2"); - conn2.close(); - stat.execute("drop table test"); - conn.close(); - } - - private void testTrim() throws SQLException { - Connection conn; - conn = getConnection(URL); - Statement stat = conn.createStatement(); - stat.execute("create table test(id int primary key, name varchar)"); - stat.execute("create index idx_name on test(name, id)"); - stat.execute("insert into test select x, x || space(10) from system_range(1, 20)"); - stat.execute("create table test2(id int primary key, name varchar)"); - stat.execute("create index idx_test2_name on test2(name, id)"); - stat.execute("insert into test2 select x, x || space(10) from system_range(1, 20)"); - stat.execute("create table test3(id int primary key, name varchar)"); - stat.execute("create index idx_test3_name on test3(name, id)"); - stat.execute("insert into test3 select x, x || space(3) from system_range(1, 3)"); - stat.execute("delete from test"); - stat.execute("checkpoint"); - stat.execute("checkpoint sync"); - stat.execute("shutdown compact"); - conn.close(); - conn = getConnection(URL); - conn.createStatement().execute("drop all objects"); - conn.close(); - } - - private void testBasic() throws Exception { - Connection conn; - conn = getConnection(URL); - conn.close(); - conn = getConnection(URL); - conn.close(); - - } - - private void testReadOnly() throws Exception { - Connection conn; - conn = getConnection(URL); - conn.createStatement().execute("shutdown compact"); - conn.close(); - conn = getConnection(URL + ";access_mode_data=r"); - conn.close(); - } - - private void testBackupRestore() throws Exception { - Connection conn; - conn = getConnection(URL); - Statement stat = conn.createStatement(); - stat.execute("create table test(id int primary key, name varchar)"); - stat.execute("create index idx_name on test(name, id)"); - stat.execute("insert into test select x, x || space(200 * x) from system_range(1, 10)"); - conn.setAutoCommit(false); - stat.execute("delete from test where id > 5"); - stat.execute("backup to '" + getBaseDir() + "/backup.zip'"); - conn.rollback(); - Restore.execute(getBaseDir() + "/backup.zip", getBaseDir(), "pageStore2", true); - Connection conn2; - conn2 = getConnection("pageStore2"); - Statement stat2 = conn2.createStatement(); - assertEqualDatabases(stat, stat2); - conn.createStatement().execute("drop table test"); - conn2.close(); - conn.close(); - IOUtils.delete(getBaseDir() + "/backup.zip"); - deleteDb("pageStore2"); - } - - private void testIncompleteCreate() throws Exception { - deleteDb("pageStore"); - Connection conn; - String fileName = getBaseDir() + "/pageStore" + Constants.SUFFIX_PAGE_FILE; - conn = getConnection("pageStore"); - Statement stat = conn.createStatement(); - stat.execute("drop table if exists INFORMATION_SCHEMA.LOB_DATA"); - stat.execute("drop table if exists INFORMATION_SCHEMA.LOB_MAP"); - conn.close(); - FileObject f = FileSystem.getInstance(fileName).openFileObject(fileName, "rw"); - // create a new database - conn = getConnection("pageStore"); - conn.close(); - f = FileSystem.getInstance(fileName).openFileObject(fileName, "rw"); - f.setFileLength(16); - // create a new database - conn = getConnection("pageStore"); - deleteDb("pageStore"); - } - -} diff --git a/tools/h2/src/test/org/h2/test/unit/TestPattern.java b/tools/h2/src/test/org/h2/test/unit/TestPattern.java deleted file mode 100755 index b55722e..0000000 --- a/tools/h2/src/test/org/h2/test/unit/TestPattern.java +++ /dev/null @@ -1,123 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.test.unit; - -import java.text.Collator; -import org.h2.expression.CompareLike; -import org.h2.test.TestBase; -import org.h2.value.CompareMode; - -/** - * Tests LIKE pattern matching. - */ -public class TestPattern extends TestBase { - - /** - * Run just this test. - * - * @param a ignored - */ - public static void main(String... a) throws Exception { - TestBase.createCaller().init().test(); - } - - public void test() { - testCompareModeReuse(); - testPattern(); - } - - private void testCompareModeReuse() { - CompareMode mode1, mode2; - mode1 = CompareMode.getInstance(null, 0); - mode2 = CompareMode.getInstance(null, 0); - assertTrue(mode1 == mode2); - - mode1 = CompareMode.getInstance("DE", Collator.SECONDARY); - assertFalse(mode1 == mode2); - mode2 = CompareMode.getInstance("DE", Collator.SECONDARY); - assertTrue(mode1 == mode2); - } - - private void testPattern() { - CompareMode mode = CompareMode.getInstance(null, 0); - CompareLike comp = new CompareLike(mode, null, null, null, false); - test(comp, "B", "%_"); - test(comp, "A", "A%"); - test(comp, "A", "A%%"); - test(comp, "A_A", "%\\_%"); - - for (int i = 0; i < 10000; i++) { - String pattern = getRandomPattern(); - String value = getRandomValue(); - test(comp, value, pattern); - } - } - - private void test(CompareLike comp, String value, String pattern) { - String regexp = initPatternRegexp(pattern, '\\'); - boolean resultRegexp = value.matches(regexp); - boolean result = comp.test(pattern, value, '\\'); - if (result != resultRegexp) { - fail("Error: >" + value + "< LIKE >" + pattern + "< result=" + result + " resultReg=" + resultRegexp); - } - } - - private static String getRandomValue() { - StringBuilder buff = new StringBuilder(); - int len = (int) (Math.random() * 10); - String s = "AB_%\\"; - for (int i = 0; i < len; i++) { - buff.append(s.charAt((int) (Math.random() * s.length()))); - } - return buff.toString(); - } - - private static String getRandomPattern() { - StringBuilder buff = new StringBuilder(); - int len = (int) (Math.random() * 4); - String s = "A%_\\"; - for (int i = 0; i < len; i++) { - char c = s.charAt((int) (Math.random() * s.length())); - if ((c == '_' || c == '%') && Math.random() > 0.5) { - buff.append('\\'); - } else if (c == '\\') { - buff.append(c); - } - buff.append(c); - } - return buff.toString(); - } - - private String initPatternRegexp(String pattern, char escape) { - int len = pattern.length(); - StringBuilder buff = new StringBuilder(); - for (int i = 0; i < len; i++) { - char c = pattern.charAt(i); - if (escape == c) { - if (i >= len) { - fail("escape can't be last char"); - } - c = pattern.charAt(++i); - buff.append('\\'); - buff.append(c); - } else if (c == '%') { - buff.append(".*"); - } else if (c == '_') { - buff.append('.'); - } else if (c == '\\') { - buff.append("\\\\"); - } else { - buff.append(c); - } - // TODO regexp: there are other chars that need escaping - } - String regexp = buff.toString(); - // System.out.println("regexp = " + regexp); - return regexp; - } - -} diff --git a/tools/h2/src/test/org/h2/test/unit/TestPgServer.java b/tools/h2/src/test/org/h2/test/unit/TestPgServer.java deleted file mode 100755 index db77030..0000000 --- a/tools/h2/src/test/org/h2/test/unit/TestPgServer.java +++ /dev/null @@ -1,146 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.test.unit; - -import java.sql.Connection; -import java.sql.DatabaseMetaData; -import java.sql.DriverManager; -import java.sql.ParameterMetaData; -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.ResultSetMetaData; -import java.sql.SQLException; -import java.sql.Statement; -import java.sql.Types; - -import org.h2.test.TestBase; -import org.h2.tools.Server; - -/** - * Tests the PostgreSQL server protocol compliant implementation. - */ -public class TestPgServer extends TestBase { - - /** - * Run just this test. - * - * @param a ignored - */ - public static void main(String... a) throws Exception { - TestBase.createCaller().init().test(); - } - - public void test() throws SQLException { - deleteDb("test"); - Server server = Server.createPgServer("-baseDir", getBaseDir(), "-pgPort", "5535"); - server.start(); - try { - Class.forName("org.postgresql.Driver"); - testPgClient(); - } catch (ClassNotFoundException e) { - println("PostgreSQL JDBC driver not found - PgServer not tested"); - } finally { - server.stop(); - } - deleteDb("test"); - } - - private void testPgClient() throws SQLException { - Connection conn = DriverManager.getConnection("jdbc:postgresql://localhost:5535/test", "sa", "sa"); - Statement stat = conn.createStatement(); - try { - stat.execute("select ***"); - fail(); - } catch (SQLException e) { - assertKnownException(e); - } - conn.close(); - conn = DriverManager.getConnection("jdbc:postgresql://localhost:5535/test", "sa", "sa"); - stat = conn.createStatement(); - ResultSet rs; - - stat.execute("prepare test(int, int) as select ?1*?2"); - rs = stat.executeQuery("execute test(3, 2)"); - rs.next(); - assertEquals(6, rs.getInt(1)); - stat.execute("deallocate test"); - - stat.execute("create table test(id int primary key, name varchar)"); - PreparedStatement prep = conn.prepareStatement("insert into test values(?, ?)"); - ParameterMetaData meta = prep.getParameterMetaData(); - assertEquals(2, meta.getParameterCount()); - prep.setInt(1, 1); - prep.setString(2, "Hello"); - prep.execute(); - rs = stat.executeQuery("select * from test"); - rs.next(); - - ResultSetMetaData rsMeta = rs.getMetaData(); - assertEquals(Types.INTEGER, rsMeta.getColumnType(1)); - assertEquals(Types.VARCHAR, rsMeta.getColumnType(2)); - - prep.close(); - assertEquals(1, rs.getInt(1)); - assertEquals("Hello", rs.getString(2)); - assertFalse(rs.next()); - prep = conn.prepareStatement("select * from test where id = ? and name = ?"); - prep.setInt(1, 1); - prep.setString(2, "Hello"); - rs = prep.executeQuery(); - rs.next(); - assertEquals(1, rs.getInt(1)); - assertEquals("Hello", rs.getString(2)); - assertFalse(rs.next()); - rs.close(); - DatabaseMetaData dbMeta = conn.getMetaData(); - rs = dbMeta.getTables(null, null, "TEST", null); - rs.next(); - assertEquals("TEST", rs.getString("TABLE_NAME")); - assertFalse(rs.next()); - rs = dbMeta.getColumns(null, null, "TEST", null); - rs.next(); - assertEquals("ID", rs.getString("COLUMN_NAME")); - rs.next(); - assertEquals("NAME", rs.getString("COLUMN_NAME")); - assertFalse(rs.next()); - rs = dbMeta.getIndexInfo(null, null, "TEST", false, false); - rs.next(); - assertEquals("TEST", rs.getString("TABLE_NAME")); - rs.next(); - assertEquals("TEST", rs.getString("TABLE_NAME")); - assertFalse(rs.next()); - rs = stat.executeQuery("select version(), pg_postmaster_start_time(), current_schema()"); - rs.next(); - String s = rs.getString(1); - assertTrue(s.indexOf("H2") >= 0); - assertTrue(s.indexOf("PostgreSQL") >= 0); - s = rs.getString(2); - s = rs.getString(3); - assertEquals(s, "PUBLIC"); - assertFalse(rs.next()); - - conn.setAutoCommit(false); - stat.execute("delete from test"); - conn.rollback(); - stat.execute("update test set name = 'Hallo'"); - conn.commit(); - rs = stat.executeQuery("select * from test order by id"); - rs.next(); - assertEquals(1, rs.getInt(1)); - assertEquals("Hallo", rs.getString(2)); - assertFalse(rs.next()); - - rs = stat.executeQuery("select id, name, pg_get_userbyid(id) from information_schema.users order by id"); - rs.next(); - assertEquals(rs.getString(2), rs.getString(3)); - assertFalse(rs.next()); - - - conn.close(); - } - -} diff --git a/tools/h2/src/test/org/h2/test/unit/TestReader.java b/tools/h2/src/test/org/h2/test/unit/TestReader.java deleted file mode 100755 index 57a2182..0000000 --- a/tools/h2/src/test/org/h2/test/unit/TestReader.java +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.test.unit; - -import java.io.ByteArrayInputStream; -import java.io.InputStream; -import java.io.Reader; -import java.io.StringReader; - -import org.h2.dev.util.ReaderInputStream; -import org.h2.test.TestBase; -import org.h2.util.IOUtils; - -/** - * Tests the stream to UTF-8 reader conversion. - */ -public class TestReader extends TestBase { - - /** - * Run just this test. - * - * @param a ignored - */ - public static void main(String... a) throws Exception { - TestBase.createCaller().init().test(); - } - - public void test() throws Exception { - String s = "\u00ef\u00f6\u00fc"; - StringReader r = new StringReader(s); - InputStream in = new ReaderInputStream(r); - byte[] buff = IOUtils.readBytesAndClose(in, 0); - InputStream in2 = new ByteArrayInputStream(buff); - Reader r2 = IOUtils.getReader(in2); - String s2 = IOUtils.readStringAndClose(r2, Integer.MAX_VALUE); - assertEquals(s, s2); - } - -} diff --git a/tools/h2/src/test/org/h2/test/unit/TestRecovery.java b/tools/h2/src/test/org/h2/test/unit/TestRecovery.java deleted file mode 100755 index ce9bcaf..0000000 --- a/tools/h2/src/test/org/h2/test/unit/TestRecovery.java +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.test.unit; - -import java.io.ByteArrayOutputStream; -import java.io.PrintStream; -import java.sql.Connection; -import java.sql.SQLException; -import java.sql.Statement; -import org.h2.store.fs.FileSystem; -import org.h2.test.TestBase; -import org.h2.tools.DeleteDbFiles; -import org.h2.tools.Recover; -import org.h2.util.IOUtils; - -/** - * Tests database recovery. - */ -public class TestRecovery extends TestBase { - - /** - * Run just this test. - * - * @param a ignored - */ - public static void main(String... a) throws Exception { - TestBase.createCaller().init().test(); - } - - public void test() throws SQLException { - testRunScript(); - } - - private void testRunScript() throws SQLException { - DeleteDbFiles.execute(getBaseDir(), "recovery", true); - DeleteDbFiles.execute(getBaseDir(), "recovery2", true); - org.h2.Driver.load(); - Connection conn = getConnection("recovery"); - Statement stat = conn.createStatement(); - stat.execute("create table test as select * from system_range(1, 100)"); - stat.execute("create table a(id int primary key) as select * from system_range(1, 100)"); - stat.execute("create table b(id int references a(id)) as select * from system_range(1, 100)"); - stat.execute("create table c(d clob) as select space(10000) || 'end'"); - stat.execute("create table d(d varchar) as select space(10000) || 'end'"); - stat.execute("alter table a add foreign key(id) references b(id)"); - // all rows have the same value - so that SCRIPT can't re-order the rows - stat.execute("create table e(id varchar) as select space(10) from system_range(1, 1000)"); - stat.execute("create index idx_e_id on e(id)"); - conn.close(); - - Recover rec = new Recover(); - ByteArrayOutputStream buff = new ByteArrayOutputStream(); - rec.setOut(new PrintStream(buff)); - rec.runTool("-dir", getBaseDir(), "-db", "recovery", "-trace"); - String out = new String(buff.toByteArray()); - assertTrue(out.indexOf("Created file") >= 0); - - Connection conn2 = getConnection("recovery2", "diff", ""); - Statement stat2 = conn2.createStatement(); - String name = "recovery.h2.sql"; - - stat2.execute("runscript from '" + getBaseDir() + "/" + name + "'"); - stat2.execute("select * from test"); - stat2.execute("drop user diff"); - conn2.close(); - - conn = getConnection("recovery"); - stat = conn.createStatement(); - conn2 = getConnection("recovery2"); - stat2 = conn2.createStatement(); - - assertEqualDatabases(stat, stat2); - conn.close(); - conn2.close(); - - Recover.execute(getBaseDir(), "recovery"); - - deleteDb("recovery"); - deleteDb("recovery2"); - IOUtils.delete(getBaseDir() + "/recovery.h2.sql"); - String dir = getBaseDir() + "/recovery.lobs.db"; - FileSystem.getInstance(dir).deleteRecursive(dir, false); - - } - -} diff --git a/tools/h2/src/test/org/h2/test/unit/TestReopen.java b/tools/h2/src/test/org/h2/test/unit/TestReopen.java deleted file mode 100755 index a344e66..0000000 --- a/tools/h2/src/test/org/h2/test/unit/TestReopen.java +++ /dev/null @@ -1,174 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.test.unit; - -import java.sql.SQLException; -import java.util.HashSet; -import java.util.Properties; -import org.h2.constant.ErrorCode; -import org.h2.engine.ConnectionInfo; -import org.h2.engine.Constants; -import org.h2.engine.Database; -import org.h2.engine.Session; -import org.h2.message.DbException; -import org.h2.store.fs.FileSystem; -import org.h2.test.TestBase; -import org.h2.test.utils.Recorder; -import org.h2.test.utils.RecordingFileSystem; -import org.h2.util.IOUtils; -import org.h2.util.New; -import org.h2.util.Profiler; - -/** - * A test that calls another test, and after each write operation to the - * database file, it copies the file, and tries to reopen it. - */ -public class TestReopen extends TestBase implements Recorder { - - private static final int MAX_FILE_SIZE = 8 * 1024 * 1024; - private String testDatabase = "memFS:" + TestBase.BASE_TEST_DIR + "/reopen"; - private long lastCheck; - private int writeCount = Integer.parseInt(System.getProperty("reopenOffset", "0")); - private int testEvery = 1 << Integer.parseInt(System.getProperty("reopenShift", "8")); - private int verifyCount; - private HashSet knownErrors = New.hashSet(); - private volatile boolean testing; - - /** - * Run just this test. - * - * @param a ignored - */ - public static void main(String... a) throws Exception { - TestBase.createCaller().init().test(); - } - - public void test() throws Exception { - System.setProperty("h2.delayWrongPasswordMin", "0"); - RecordingFileSystem.register(); - RecordingFileSystem.setRecorder(this); - config.record = true; - - long time = System.currentTimeMillis(); - Profiler p = new Profiler(); - p.startCollecting(); - new TestPageStoreCoverage().init(config).test(); - System.out.println(p.getTop(3)); - System.out.println(System.currentTimeMillis() - time); - System.out.println("counter: " + writeCount); - } - - public void log(int op, String fileName, byte[] data, long x) { - if (op != Recorder.WRITE && op != Recorder.SET_LENGTH) { - return; - } - if (!fileName.endsWith(Constants.SUFFIX_PAGE_FILE)) { - return; - } - if (testing) { - // avoid deadlocks - return; - } - testing = true; - try { - logDb(fileName); - } finally { - testing = false; - } - } - - private synchronized void logDb(String fileName) { - writeCount++; - if ((writeCount & 1023) == 0) { - long now = System.currentTimeMillis(); - if (now > lastCheck + 5000) { - System.out.println("+ write #" + writeCount + " verify #" + verifyCount); - lastCheck = now; - } - } - if ((writeCount & (testEvery - 1)) != 0) { - return; - } - if (IOUtils.length(fileName) > MAX_FILE_SIZE) { - // System.out.println(fileName + " " + IOUtils.length(fileName)); - return; - } - FileSystem.getInstance(fileName).copy(fileName, testDatabase + Constants.SUFFIX_PAGE_FILE); - try { - verifyCount++; - // avoid using the Engine class to avoid deadlocks - Properties p = new Properties(); - String userName = getUser(); - p.setProperty("user", userName); - p.setProperty("password", getPassword()); - ConnectionInfo ci = new ConnectionInfo("jdbc:h2:" + testDatabase + ";FILE_LOCK=NO;TRACE_LEVEL_FILE=0", p); - Database database = new Database(ci, null); - // close the database - Session session = database.getSystemSession(); - session.prepare("shutdown immediately").update(); - database.removeSession(null); - // everything OK - return - return; - } catch (DbException e) { - SQLException e2 = DbException.toSQLException(e); - int errorCode = e2.getErrorCode(); - if (errorCode == ErrorCode.WRONG_USER_OR_PASSWORD) { - return; - } else if (errorCode == ErrorCode.FILE_ENCRYPTION_ERROR_1) { - return; - } - e.printStackTrace(System.out); - } catch (Exception e) { - // failed - int errorCode = 0; - if (e instanceof SQLException) { - errorCode = ((SQLException) e).getErrorCode(); - } - if (errorCode == ErrorCode.WRONG_USER_OR_PASSWORD) { - return; - } else if (errorCode == ErrorCode.FILE_ENCRYPTION_ERROR_1) { - return; - } - e.printStackTrace(System.out); - } - System.out.println("begin ------------------------------ " + writeCount); - testDatabase += "X"; - FileSystem.getInstance(fileName).copy(fileName, testDatabase + Constants.SUFFIX_PAGE_FILE); - try { - // avoid using the Engine class to avoid deadlocks - Properties p = new Properties(); - ConnectionInfo ci = new ConnectionInfo("jdbc:h2:" + testDatabase + ";FILE_LOCK=NO", p); - Database database = new Database(ci, null); - // close the database - database.removeSession(null); - } catch (Exception e) { - int errorCode = 0; - if (e instanceof SQLException) { - errorCode = ((SQLException) e).getErrorCode(); - } - if (errorCode == ErrorCode.WRONG_USER_OR_PASSWORD) { - return; - } else if (errorCode == ErrorCode.FILE_ENCRYPTION_ERROR_1) { - return; - } - StringBuilder buff = new StringBuilder(); - StackTraceElement[] list = e.getStackTrace(); - for (int i = 0; i < 10 && i < list.length; i++) { - buff.append(list[i].toString()).append('\n'); - } - String s = buff.toString(); - if (!knownErrors.contains(s)) { - System.out.println(writeCount + " code: " + errorCode + " " + e.toString()); - e.printStackTrace(System.out); - knownErrors.add(s); - } else { - System.out.println(writeCount + " code: " + errorCode); - } - } - } - -} diff --git a/tools/h2/src/test/org/h2/test/unit/TestSampleApps.java b/tools/h2/src/test/org/h2/test/unit/TestSampleApps.java deleted file mode 100755 index 7b7f81f..0000000 --- a/tools/h2/src/test/org/h2/test/unit/TestSampleApps.java +++ /dev/null @@ -1,105 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.test.unit; - -import java.io.ByteArrayOutputStream; -import java.io.File; -import java.io.FileOutputStream; -import java.io.InputStream; -import java.io.PrintStream; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; - -import org.h2.test.TestBase; -import org.h2.tools.DeleteDbFiles; -import org.h2.util.IOUtils; -import org.h2.util.StringUtils; - -/** - * Tests the sample apps. - */ -public class TestSampleApps extends TestBase { - - /** - * Run just this test. - * - * @param a ignored - */ - public static void main(String... a) throws Exception { - TestBase.createCaller().init().test(); - } - - public void test() throws Exception { - if (!getBaseDir().startsWith(TestBase.BASE_TEST_DIR)) { - return; - } - deleteDb("optimizations"); - InputStream in = getClass().getClassLoader().getResourceAsStream("org/h2/samples/optimizations.sql"); - new File(getBaseDir()).mkdirs(); - FileOutputStream out = new FileOutputStream(getBaseDir() + "/optimizations.sql"); - IOUtils.copyAndClose(in, out); - String url = "jdbc:h2:" + getBaseDir() + "/optimizations"; - testApp("", org.h2.tools.RunScript.class, "-url", url, "-user", "sa", "-password", "sa", "-script", - getBaseDir() + "/optimizations.sql", "-checkResults"); - deleteDb("optimizations"); - testApp("Compacting...\nDone.", org.h2.samples.Compact.class); - testApp("NAME: Bob Meier\n" + "EMAIL: bob.meier@abcde.abc\n" - + "PHONE: +41123456789\n\n" + "NAME: John Jones\n" + "EMAIL: john.jones@abcde.abc\n" - + "PHONE: +41976543210\n", - org.h2.samples.CsvSample.class); - testApp("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", - org.h2.samples.Function.class); - // 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) - // TODO test ShutdownServer (server needs to be started in a separate - // process) - testApp("The sum is 20.00", org.h2.samples.TriggerSample.class); - testApp("Hello: 1\nWorld: 2", org.h2.samples.TriggerPassData.class); - - // tools - testApp("Allows changing the database file encryption password or algorithm*", - org.h2.tools.ChangeFileEncryption.class, "-help"); - testApp("Allows changing the database file encryption password or algorithm*", - org.h2.tools.ChangeFileEncryption.class); - testApp("Deletes all files belonging to a database.*", - org.h2.tools.DeleteDbFiles.class, "-help"); - IOUtils.delete(getBaseDir() + "/optimizations.sql"); - } - - private void testApp(String expected, Class< ? > clazz, String... args) throws Exception { - DeleteDbFiles.execute("data", "test", true); - Method m = clazz.getMethod("main", String[].class); - PrintStream oldOut = System.out, oldErr = System.err; - ByteArrayOutputStream buff = new ByteArrayOutputStream(); - PrintStream out = new PrintStream(buff, false, "UTF-8"); - System.setOut(out); - System.setErr(out); - try { - m.invoke(null, new Object[] { args }); - } catch (InvocationTargetException e) { - TestBase.logError("error", e.getTargetException()); - } catch (Throwable e) { - TestBase.logError("error", e); - } - out.flush(); - System.setOut(oldOut); - System.setErr(oldErr); - String s = new String(buff.toByteArray(), "UTF-8"); - s = StringUtils.replaceAll(s, "\r\n", "\n"); - s = s.trim(); - expected = expected.trim(); - if (expected.endsWith("*")) { - expected = expected.substring(0, expected.length() - 1); - if (!s.startsWith(expected)) { - assertEquals(expected.trim(), s.trim()); - } - } else { - assertEquals(expected.trim(), s.trim()); - } - } -} diff --git a/tools/h2/src/test/org/h2/test/unit/TestScriptReader.java b/tools/h2/src/test/org/h2/test/unit/TestScriptReader.java deleted file mode 100755 index 96850a7..0000000 --- a/tools/h2/src/test/org/h2/test/unit/TestScriptReader.java +++ /dev/null @@ -1,190 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.test.unit; - -import java.io.StringReader; -import java.util.Random; -import org.h2.test.TestBase; -import org.h2.util.ScriptReader; - -/** - * Tests the script reader tool that breaks up SQL scripts in statements. - */ -public class TestScriptReader extends TestBase { - - /** - * Run just this test. - * - * @param a ignored - */ - public static void main(String... a) throws Exception { - TestBase.createCaller().init().test(); - } - - public void test() { - testCommon(); - testRandom(); - } - - private void testRandom() { - int len = getSize(1000, 10000); - Random random = new Random(10); - for (int i = 0; i < len; i++) { - int l = random.nextInt(10); - String[] sql = new String[l]; - StringBuilder buff = new StringBuilder(); - for (int j = 0; j < l; j++) { - sql[j] = randomStatement(random); - buff.append(sql[j]); - if (j < l - 1) { - buff.append(";"); - } - } - String s = buff.toString(); - StringReader reader = new StringReader(s); - ScriptReader source = new ScriptReader(reader); - for (int j = 0; j < l; j++) { - String e = source.readStatement(); - String c = sql[j]; - if (c.length() == 0 && j == l - 1) { - c = null; - } - assertEquals(c, e); - } - assertEquals(null, source.readStatement()); - } - } - - private String randomStatement(Random random) { - StringBuilder buff = new StringBuilder(); - int len = random.nextInt(5); - for (int i = 0; i < len; i++) { - switch (random.nextInt(10)) { - case 0: { - int l = random.nextInt(4); - String[] ch = { "\n", "\r", " ", "*", "a", "0", "$ " }; - for (int j = 0; j < l; j++) { - buff.append(ch[random.nextInt(ch.length)]); - } - break; - } - case 1: { - buff.append('\''); - int l = random.nextInt(4); - String[] ch = { ";", "\n", "\r", "--", "//", "/", "-", "*", "/*", "*/", "\"", "$ " }; - for (int j = 0; j < l; j++) { - buff.append(ch[random.nextInt(ch.length)]); - } - buff.append('\''); - break; - } - case 2: { - buff.append('"'); - int l = random.nextInt(4); - String[] ch = { ";", "\n", "\r", "--", "//", "/", "-", "*", "/*", "*/", "\'", "$" }; - for (int j = 0; j < l; j++) { - buff.append(ch[random.nextInt(ch.length)]); - } - buff.append('"'); - break; - } - case 3: { - buff.append('-'); - if (random.nextBoolean()) { - String[] ch = { "\n", "\r", "*", "a", " ", "$ " }; - int l = 1 + random.nextInt(4); - for (int j = 0; j < l; j++) { - buff.append(ch[random.nextInt(ch.length)]); - } - } else { - buff.append('-'); - String[] ch = { ";", "-", "//", "/*", "*/", "a", "$" }; - int l = random.nextInt(4); - for (int j = 0; j < l; j++) { - buff.append(ch[random.nextInt(ch.length)]); - } - buff.append('\n'); - } - break; - } - case 4: { - buff.append('/'); - if (random.nextBoolean()) { - String[] ch = { "\n", "\r", "a", " ", "- ", "$ " }; - int l = 1 + random.nextInt(4); - for (int j = 0; j < l; j++) { - buff.append(ch[random.nextInt(ch.length)]); - } - } else { - buff.append('*'); - String[] ch = { ";", "-", "//", "/* ", "--", "\n", "\r", "a", "$" }; - int l = random.nextInt(4); - for (int j = 0; j < l; j++) { - buff.append(ch[random.nextInt(ch.length)]); - } - buff.append("*/"); - } - break; - } - case 5: { - if (buff.length() > 0) { - buff.append(" "); - } - buff.append("$"); - if (random.nextBoolean()) { - String[] ch = { "\n", "\r", "a", " ", "- ", "/ " }; - int l = 1 + random.nextInt(4); - for (int j = 0; j < l; j++) { - buff.append(ch[random.nextInt(ch.length)]); - } - } else { - buff.append("$"); - String[] ch = { ";", "-", "//", "/* ", "--", "\n", "\r", "a", "$ " }; - int l = random.nextInt(4); - for (int j = 0; j < l; j++) { - buff.append(ch[random.nextInt(ch.length)]); - } - buff.append("$$"); - } - break; - } - default: - } - } - return buff.toString(); - } - - private void testCommon() { - String s; - ScriptReader source; - - s = "$$;$$;"; - source = new ScriptReader(new StringReader(s)); - assertEquals("$$;$$", source.readStatement()); - assertEquals(null, source.readStatement()); - source.close(); - - s = "a;';';\";\";--;\n;/*;\n*/;//;\na;"; - source = new ScriptReader(new StringReader(s)); - assertEquals("a", source.readStatement()); - assertEquals("';'", source.readStatement()); - assertEquals("\";\"", source.readStatement()); - assertEquals("--;\n", source.readStatement()); - assertEquals("/*;\n*/", source.readStatement()); - assertEquals("//;\na", source.readStatement()); - assertEquals(null, source.readStatement()); - source.close(); - - s = "/\n$ \n\n $';$$a$$ $\n;'"; - source = new ScriptReader(new StringReader(s)); - assertEquals("/\n$ \n\n $';$$a$$ $\n;'", source.readStatement()); - assertEquals(null, source.readStatement()); - source.close(); - - } - -} diff --git a/tools/h2/src/test/org/h2/test/unit/TestSecurity.java b/tools/h2/src/test/org/h2/test/unit/TestSecurity.java deleted file mode 100755 index a6be21f..0000000 --- a/tools/h2/src/test/org/h2/test/unit/TestSecurity.java +++ /dev/null @@ -1,103 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.test.unit; - -import org.h2.security.BlockCipher; -import org.h2.security.CipherFactory; -import org.h2.security.SHA256; -import org.h2.test.TestBase; -import org.h2.util.Utils; - -/** - * Tests various security primitives. - */ -public class TestSecurity extends TestBase { - - /** - * Run just this test. - * - * @param a ignored - */ - public static void main(String... a) throws Exception { - TestBase.createCaller().init().test(); - } - - public void test() { - testSHA(); - testAES(); - testXTEA(); - } - - private void testSHA() { - SHA256 sha = new SHA256(); - testOneSHA(sha); - } - - private String getHashString(SHA256 sha, byte[] data) { - byte[] result = sha.getHash(data, true); - if (data.length > 0) { - assertEquals(0, data[0]); - } - return Utils.convertBytesToString(result); - } - - private void testOneSHA(SHA256 sha) { - assertEquals("e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", - getHashString(sha, new byte[] {})); - assertEquals("68aa2e2ee5dff96e3355e6c7ee373e3d6a4e17f75f9518d843709c0c9bc3e3d4", - getHashString(sha, new byte[] { 0x19 })); - assertEquals("175ee69b02ba9b58e2b0a5fd13819cea573f3940a94f825128cf4209beabb4e8", - getHashString( - sha, - new byte[] { (byte) 0xe3, (byte) 0xd7, 0x25, 0x70, (byte) 0xdc, (byte) 0xdd, 0x78, 0x7c, (byte) 0xe3, - (byte) 0x88, 0x7a, (byte) 0xb2, (byte) 0xcd, 0x68, 0x46, 0x52 })); - checkSHA256("", "E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855"); - checkSHA256("a", "CA978112CA1BBDCAFAC231B39A23DC4DA786EFF8147C4E72B9807785AFEE48BB"); - checkSHA256("abc", "BA7816BF8F01CFEA414140DE5DAE2223B00361A396177A9CB410FF61F20015AD"); - checkSHA256("message digest", "F7846F55CF23E14EEBEAB5B4E1550CAD5B509E3348FBC4EFA3A1413D393CB650"); - checkSHA256("abcdefghijklmnopqrstuvwxyz", "71C480DF93D6AE2F1EFAD1447C66C9525E316218CF51FC8D9ED832F2DAF18B73"); - checkSHA256("abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", "248D6A61D20638B8E5C026930C3E6039A33CE45964FF2167F6ECEDD419DB06C1"); - checkSHA256("12345678901234567890123456789012345678901234567890123456789012345678901234567890", "F371BC4A311F2B009EEF952DD83CA80E2B60026C8E935592D0F9C308453C813E"); - StringBuilder buff = new StringBuilder(1000000); - buff.append('a'); - checkSHA256(buff.toString(), "CA978112CA1BBDCAFAC231B39A23DC4DA786EFF8147C4E72B9807785AFEE48BB"); - } - - private void checkSHA256(String message, String expected) { - SHA256 sha = new SHA256(); - String hash = Utils.convertBytesToString(sha.getHash(message.getBytes(), true)).toUpperCase(); - assertEquals(expected, hash); - } - - private void testXTEA() { - byte[] test = new byte[4096]; - BlockCipher xtea = CipherFactory.getBlockCipher("XTEA"); - xtea.setKey("abcdefghijklmnop".getBytes()); - for (int i = 0; i < 10; i++) { - xtea.decrypt(test, 0, test.length); - } - } - - private void testAES() { - BlockCipher test = CipherFactory.getBlockCipher("AES"); - test.setKey(Utils.convertStringToBytes("000102030405060708090A0B0C0D0E0F")); - - byte[] in = new byte[128]; - byte[] enc = new byte[128]; - test.encrypt(enc, 0, 128); - test.decrypt(enc, 0, 128); - if (Utils.compareNotNull(in, enc) != 0) { - throw new AssertionError(); - } - - for (int i = 0; i < 10; i++) { - test.encrypt(in, 0, 128); - test.decrypt(enc, 0, 128); - } - } - -} diff --git a/tools/h2/src/test/org/h2/test/unit/TestServlet.java b/tools/h2/src/test/org/h2/test/unit/TestServlet.java deleted file mode 100755 index f92806b..0000000 --- a/tools/h2/src/test/org/h2/test/unit/TestServlet.java +++ /dev/null @@ -1,234 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.test.unit; - -import java.io.InputStream; -import java.net.URL; -import java.sql.Connection; -import java.sql.DriverManager; -import java.sql.SQLException; -import java.sql.Statement; -import java.util.Enumeration; -import java.util.HashMap; -import java.util.Properties; -import java.util.Set; - -import javax.servlet.RequestDispatcher; -import javax.servlet.Servlet; -import javax.servlet.ServletContext; -import javax.servlet.ServletContextEvent; - -import org.h2.server.web.DbStarter; -import org.h2.test.TestBase; -import org.h2.util.New; - -/** - * Tests the DbStarter servlet. - * This test simulates a minimum servlet container environment. - */ -public class TestServlet extends TestBase { - - /** - * Run just this test. - * - * @param a ignored - */ - public static void main(String... a) throws Exception { - TestBase.createCaller().init().test(); - } - - /** - * Minimum ServletContext implementation. - * Most methods are not implemented. - */ - static class TestServletContext implements ServletContext { - - private Properties initParams = new Properties(); - private HashMap attributes = New.hashMap(); - - public void setAttribute(String key, Object value) { - attributes.put(key, value); - } - - public Object getAttribute(String key) { - return attributes.get(key); - } - - /** - * Set an initialization parameter. - * - * @param key the parameter key - * @param value the value - */ - void setInitParameter(String key, String value) { - initParams.setProperty(key, value); - } - - public String getInitParameter(String key) { - return initParams.getProperty(key); - } - - public Enumeration getAttributeNames() { - throw new UnsupportedOperationException(); - } - - public ServletContext getContext(String string) { - throw new UnsupportedOperationException(); - } - - public Enumeration getInitParameterNames() { - throw new UnsupportedOperationException(); - } - - public int getMajorVersion() { - throw new UnsupportedOperationException(); - } - - public String getMimeType(String string) { - throw new UnsupportedOperationException(); - } - - public int getMinorVersion() { - throw new UnsupportedOperationException(); - } - - public RequestDispatcher getNamedDispatcher(String string) { - throw new UnsupportedOperationException(); - } - - public String getRealPath(String string) { - throw new UnsupportedOperationException(); - } - - public RequestDispatcher getRequestDispatcher(String string) { - throw new UnsupportedOperationException(); - } - - public URL getResource(String string) { - throw new UnsupportedOperationException(); - } - - public InputStream getResourceAsStream(String string) { - throw new UnsupportedOperationException(); - } - - public Set getResourcePaths(String string) { - throw new UnsupportedOperationException(); - } - - public String getServerInfo() { - throw new UnsupportedOperationException(); - } - - /** - * @deprecated - */ - public Servlet getServlet(String string) { - throw new UnsupportedOperationException(); - } - - public String getServletContextName() { - throw new UnsupportedOperationException(); - } - - /** - * @deprecated - */ - public Enumeration getServletNames() { - throw new UnsupportedOperationException(); - } - - /** - * @deprecated - */ - public Enumeration getServlets() { - throw new UnsupportedOperationException(); - } - - public void log(String string) { - throw new UnsupportedOperationException(); - } - - /** - * @deprecated - */ - public void log(Exception exception, String string) { - throw new UnsupportedOperationException(); - } - - public void log(String string, Throwable throwable) { - throw new UnsupportedOperationException(); - } - - public void removeAttribute(String string) { - throw new UnsupportedOperationException(); - } - - } - - public void test() throws SQLException { - if (config.networked || config.memory) { - return; - } - DbStarter listener = new DbStarter(); - - TestServletContext context = new TestServletContext(); - String url = getURL("servlet", true); - context.setInitParameter("db.url", url); - context.setInitParameter("db.user", getUser()); - context.setInitParameter("db.password", getPassword()); - context.setInitParameter("db.tcpServer", "-tcpPort 8888"); - - ServletContextEvent event = new ServletContextEvent(context); - listener.contextInitialized(event); - - Connection conn1 = listener.getConnection(); - Connection conn1a = (Connection) context.getAttribute("connection"); - assertTrue(conn1 == conn1a); - Statement stat1 = conn1.createStatement(); - stat1.execute("CREATE TABLE T(ID INT)"); - - String u2 = url.substring(url.indexOf("servlet")); - u2 = "jdbc:h2:tcp://localhost:8888/" + getBaseDir() + "/" + u2; - Connection conn2 = DriverManager.getConnection( - u2, getUser(), getPassword()); - Statement stat2 = conn2.createStatement(); - stat2.execute("SELECT * FROM T"); - stat2.execute("DROP TABLE T"); - - try { - stat1.execute("SELECT * FROM T"); - fail(); - } catch (SQLException e) { - assertKnownException(e); - } - - conn2.close(); - - listener.contextDestroyed(event); - - // listener must be stopped - try { - DriverManager.getConnection("jdbc:h2:tcp://localhost:8888/" + getBaseDir() + "/servlet", getUser(), getPassword()); - fail(); - } catch (SQLException e) { - assertKnownException(e); - } - - // connection must be closed - try { - stat1.execute("SELECT * FROM DUAL"); - fail(); - } catch (SQLException e) { - assertKnownException(e); - } - - deleteDb("servlet"); - - } - -} diff --git a/tools/h2/src/test/org/h2/test/unit/TestShell.java b/tools/h2/src/test/org/h2/test/unit/TestShell.java deleted file mode 100755 index c7d13e5..0000000 --- a/tools/h2/src/test/org/h2/test/unit/TestShell.java +++ /dev/null @@ -1,122 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.test.unit; - -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.io.LineNumberReader; -import java.io.PipedInputStream; -import java.io.PipedOutputStream; -import java.io.PrintStream; -import java.sql.SQLException; - -import org.h2.test.TestBase; -import org.h2.tools.Shell; - -/** - * Test the shell tool. - */ -public class TestShell extends TestBase { - - /** - * The output stream of the tool. - */ - PrintStream toolOut; - - /** - * The input stream of the tool. - */ - InputStream toolIn; - - private PrintStream testOut; - private PipedInputStream testIn; - private LineNumberReader lineReader; - - /** - * Run just this test. - * - * @param a ignored - */ - public static void main(String... a) throws Exception { - TestBase.createCaller().init().test(); - } - - public void test() throws IOException { - testIn = new PipedInputStream(); - PipedOutputStream out = new PipedOutputStream(testIn); - toolOut = new PrintStream(out, true); - out = new PipedOutputStream(); - testOut = new PrintStream(out, true); - toolIn = new PipedInputStream(out); - new Thread(new Runnable() { - public void run() { - try { - Shell shell = new Shell(); - shell.setIn(toolIn); - shell.setOut(toolOut); - shell.setErr(toolOut); - shell.runTool(); - } catch (SQLException e) { - e.printStackTrace(); - } finally { - toolOut.close(); - } - } - }).start(); - InputStreamReader reader = new InputStreamReader(testIn); - lineReader = new LineNumberReader(reader); - read(""); - read("Welcome to H2 Shell"); - read("Exit with"); - read("[Enter]"); - testOut.println("jdbc:h2:mem:"); - read("URL"); - testOut.println("org.h2.Driver"); - read("Driver"); - testOut.println("sa"); - read("User"); - testOut.println("sa"); - read("Password"); - read("Commands are case insensitive"); - read("help or ?"); - read("list"); - read("maxwidth"); - read("show"); - read("describe"); - read("history"); - read("quit or exit"); - read(""); - testOut.println("create table test(id int primary key, name varchar)\n;"); - read("sql> ...>"); - testOut.println("show public"); - read("sql>"); - while (read("").startsWith("INFORMATION_SCHEMA")) { - // ignore - } - testOut.println("insert into test values(1, 'Hello');"); - read("sql>"); - testOut.println("select * from test;"); - read("sql> ID"); - read("1 "); - read("(1 row,"); - testOut.println("describe test"); - read("sql> Column Name"); - read("ID"); - read("NAME"); - testOut.println("exit"); - read("sql>"); - } - - private String read(String expectedStart) throws IOException { - String line = lineReader.readLine(); - // System.out.println(": " + line); - assertStartsWith(line, expectedStart); - return line; - } - -} diff --git a/tools/h2/src/test/org/h2/test/unit/TestStreams.java b/tools/h2/src/test/org/h2/test/unit/TestStreams.java deleted file mode 100755 index e907329..0000000 --- a/tools/h2/src/test/org/h2/test/unit/TestStreams.java +++ /dev/null @@ -1,118 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.test.unit; - -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.FileInputStream; -import java.io.FileOutputStream; -import java.io.IOException; -import java.util.Random; - -import org.h2.compress.LZFInputStream; -import org.h2.compress.LZFOutputStream; -import org.h2.test.TestBase; -import org.h2.util.IOUtils; - -/** - * Tests the LZF stream. - */ -public class TestStreams extends TestBase { - - /** - * Run just this test. - * - * @param a ignored - */ - public static void main(String... a) throws Exception { - TestBase.createCaller().init().test(); - } - - public void test() throws IOException { - testLZFStreams(); - testLZFStreamClose(); - } - - private byte[] getRandomBytes(Random random) { - int[] sizes = { 0, 1, random.nextInt(1000), random.nextInt(100000), random.nextInt(1000000) }; - int size = sizes[random.nextInt(sizes.length)]; - byte[] buffer = new byte[size]; - if (random.nextInt(5) == 1) { - random.nextBytes(buffer); - } else if (random.nextBoolean()) { - int patternLen = random.nextInt(100) + 1; - for (int j = 0; j < size; j++) { - buffer[j] = (byte) (j % patternLen); - } - } - return buffer; - } - - private void testLZFStreamClose() throws IOException { - String fileName = getBaseDir() + "/temp"; - IOUtils.createDirs(fileName); - LZFOutputStream out = new LZFOutputStream(new FileOutputStream(fileName)); - out.write("Hello".getBytes()); - out.close(); - LZFInputStream in = new LZFInputStream(new FileInputStream(fileName)); - byte[] buff = new byte[100]; - assertEquals(5, in.read(buff)); - in.read(); - in.close(); - IOUtils.delete(getBaseDir() + "/temp"); - } - - private void testLZFStreams() throws IOException { - Random random = new Random(1); - int max = getSize(100, 1000); - for (int i = 0; i < max; i += 3) { - byte[] buffer = getRandomBytes(random); - ByteArrayOutputStream out = new ByteArrayOutputStream(); - LZFOutputStream comp = new LZFOutputStream(out); - if (random.nextInt(10) == 1) { - comp.write(buffer); - } else { - for (int j = 0; j < buffer.length;) { - int[] sizes = { 0, 1, random.nextInt(100), random.nextInt(100000) }; - int size = sizes[random.nextInt(sizes.length)]; - size = Math.min(size, buffer.length - j); - if (size == 1) { - comp.write(buffer[j]); - } else { - comp.write(buffer, j, size); - } - j += size; - } - } - comp.close(); - byte[] compressed = out.toByteArray(); - ByteArrayInputStream in = new ByteArrayInputStream(compressed); - LZFInputStream decompress = new LZFInputStream(in); - byte[] test = new byte[buffer.length]; - for (int j = 0; j < buffer.length;) { - int[] sizes = { 0, 1, random.nextInt(100), random.nextInt(100000) }; - int size = sizes[random.nextInt(sizes.length)]; - if (size == 1) { - int x = decompress.read(); - if (x < 0) { - break; - } - test[j++] = (byte) x; - } else { - size = Math.min(size, test.length - j); - int l = decompress.read(test, j, size); - if (l < 0) { - break; - } - j += l; - } - } - assertEquals(buffer, test); - } - } - -} diff --git a/tools/h2/src/test/org/h2/test/unit/TestStringCache.java b/tools/h2/src/test/org/h2/test/unit/TestStringCache.java deleted file mode 100755 index 9b39e4c..0000000 --- a/tools/h2/src/test/org/h2/test/unit/TestStringCache.java +++ /dev/null @@ -1,137 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.test.unit; - -import java.util.Random; - -import org.h2.test.TestBase; -import org.h2.util.StringUtils; - -/** - * Tests the string cache facility. - */ -public class TestStringCache extends TestBase { - - /** - * Flag to indicate the test should stop. - */ - volatile boolean stop; - private Random random = new Random(1); - private String[] some = { null, "", "ABC", "this is a medium sized string", "1", "2" }; - private boolean returnNew; - private boolean useIntern; - - /** - * This method is called when executing this application from the command - * line. - * - * @param args the command line parameters - */ - public static void main(String... args) { - new TestStringCache().runBenchmark(); - } - - public void test() throws InterruptedException { - returnNew = true; - StringUtils.clearCache(); - testSingleThread(getSize(5000, 20000)); - testMultiThreads(); - returnNew = false; - StringUtils.clearCache(); - testSingleThread(getSize(5000, 20000)); - testMultiThreads(); - } - - private void runBenchmark() { - returnNew = false; - for (int i = 0; i < 6; i++) { - useIntern = (i % 2) == 0; - long time = System.currentTimeMillis(); - testSingleThread(100000); - time = System.currentTimeMillis() - time; - System.out.println(time + " ms (useIntern=" + useIntern + ")"); - } - - } - - private String randomString() { - if (random.nextBoolean()) { - String s = some[random.nextInt(some.length)]; - if (s != null && random.nextBoolean()) { - s = new String(s); - } - return s; - } - int len = random.nextBoolean() ? random.nextInt(1000) : random.nextInt(10); - StringBuilder buff = new StringBuilder(len); - for (int i = 0; i < len; i++) { - buff.append(random.nextInt(0xfff)); - } - return buff.toString(); - } - - /** - * Test one string operation using the string cache. - */ - void testString() { - String a = randomString(); - if (returnNew) { - String b = StringUtils.fromCacheOrNew(a); - try { - assertEquals(a, b); - } catch (Exception e) { - TestBase.logError("error", e); - } - if (a != null && a == b && a.length() > 0) { - throw new AssertionError("a=" + System.identityHashCode(a) + " b=" + System.identityHashCode(b)); - } - } else { - String b; - if (useIntern) { - b = a == null ? null : a.intern(); - } else { - b = StringUtils.cache(a); - } - try { - assertEquals(a, b); - } catch (Exception e) { - TestBase.logError("error", e); - } - } - } - - private void testSingleThread(int len) { - for (int i = 0; i < len; i++) { - testString(); - } - } - - private void testMultiThreads() throws InterruptedException { - int threadCount = getSize(3, 100); - Thread[] threads = new Thread[threadCount]; - for (int i = 0; i < threadCount; i++) { - Thread t = new Thread(new Runnable() { - public void run() { - while (!stop) { - testString(); - } - } - }); - threads[i] = t; - } - for (int i = 0; i < threadCount; i++) { - threads[i].start(); - } - int wait = getSize(200, 2000); - Thread.sleep(wait); - stop = true; - for (int i = 0; i < threadCount; i++) { - threads[i].join(); - } - } - -} diff --git a/tools/h2/src/test/org/h2/test/unit/TestStringUtils.java b/tools/h2/src/test/org/h2/test/unit/TestStringUtils.java deleted file mode 100755 index 1b011f0..0000000 --- a/tools/h2/src/test/org/h2/test/unit/TestStringUtils.java +++ /dev/null @@ -1,171 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.test.unit; - -import java.io.UnsupportedEncodingException; -import java.net.URLDecoder; -import java.net.URLEncoder; -import java.util.Date; -import java.util.Random; -import org.h2.message.DbException; -import org.h2.test.TestBase; -import org.h2.util.DateTimeUtils; -import org.h2.util.StringUtils; -import org.h2.util.Utils; - -/** - * Tests string utility methods. - */ -public class TestStringUtils extends TestBase { - - /** - * Run just this test. - * - * @param a ignored - */ - public static void main(String... a) throws Exception { - TestBase.createCaller().init().test(); - } - - public void test() throws Exception { - testHex(); - testXML(); - testSplit(); - testJavaString(); - testURL(); - testPad(); - } - - private void testHex() { - assertEquals("face", Utils.convertBytesToString(new byte[] { (byte) 0xfa, (byte) 0xce })); - assertEquals(new byte[] { (byte) 0xfa, (byte) 0xce }, Utils.convertStringToBytes("face")); - assertEquals(new byte[] { (byte) 0xfa, (byte) 0xce }, Utils.convertStringToBytes("fAcE")); - assertEquals(new byte[] { (byte) 0xfa, (byte) 0xce }, Utils.convertStringToBytes("FaCe")); - try { - Utils.convertStringToBytes("120"); - fail(); - } catch (DbException e) { - assertKnownException(DbException.toSQLException(e)); - } - try { - Utils.convertStringToBytes("fast"); - fail(); - } catch (DbException e) { - assertKnownException(DbException.toSQLException(e)); - } - } - - private void testPad() { - assertEquals("large", StringUtils.pad("larger text", 5, null, true)); - assertEquals("large", StringUtils.pad("larger text", 5, null, false)); - assertEquals("short+++++", StringUtils.pad("short", 10, "+", true)); - assertEquals("+++++short", StringUtils.pad("short", 10, "+", false)); - } - - private void testXML() { - assertEquals("\n", StringUtils.xmlComment("------abc------")); - assertEquals("\n", StringUtils.xmlNode("test", null, null)); - assertEquals("Grübel\n", StringUtils.xmlNode("test", null, StringUtils.xmlText("Gr\u00fcbel"))); - assertEquals("Rand&Blue", StringUtils.xmlText("Rand&Blue")); - assertEquals("<<[[[]]]>>", StringUtils.xmlCData("<<[[[]]]>>")); - Date dt = DateTimeUtils.parseDateTime("2001-02-03 04:05:06 GMT", "yyyy-MM-dd HH:mm:ss z", "en", "GMT"); - String s = StringUtils.xmlStartDoc() - + StringUtils.xmlComment("Test Comment") - + StringUtils.xmlNode("rss", StringUtils.xmlAttr("version", "2.0"), StringUtils - .xmlComment("Test Comment\nZeile2") - + StringUtils.xmlNode("channel", null, StringUtils.xmlNode("title", null, "H2 Database Engine") - + StringUtils.xmlNode("link", null, "http://www.h2database.com") - + StringUtils.xmlNode("description", null, "H2 Database Engine") - + StringUtils.xmlNode("language", null, "en-us") - + StringUtils.xmlNode("pubDate", null, DateTimeUtils.formatDateTime(dt, - "EEE, d MMM yyyy HH:mm:ss z", "en", "GMT")) - + StringUtils.xmlNode("lastBuildDate", null, DateTimeUtils.formatDateTime(dt, - "EEE, d MMM yyyy HH:mm:ss z", "en", "GMT")) - + StringUtils.xmlNode("item", null, StringUtils.xmlNode("title", null, - "New Version 0.9.9.9.9") - + StringUtils.xmlNode("link", null, "http://www.h2database.com") - + StringUtils.xmlNode("description", null, StringUtils - .xmlCData("\nNew Features\nTest\n"))))); - assertEquals(s, "\n" + "\n" + "\n" + " \n" + " \n" - + " H2 Database Engine\n" + " http://www.h2database.com\n" - + " H2 Database Engine\n" + " en-us\n" - + " Sat, 3 Feb 2001 04:05:06 GMT\n" - + " Sat, 3 Feb 2001 04:05:06 GMT\n" + " \n" - + " New Version 0.9.9.9.9\n" - + " http://www.h2database.com\n" + " \n" - + " \n" + " \n" + " \n" + " \n" - + "\n"); - } - - private void testURL() throws UnsupportedEncodingException { - Random random = new Random(1); - for (int i = 0; i < 100; i++) { - int len = random.nextInt(10); - StringBuilder buff = new StringBuilder(); - for (int j = 0; j < len; j++) { - if (random.nextBoolean()) { - buff.append((char) random.nextInt(0x3000)); - } else { - buff.append((char) random.nextInt(255)); - } - } - String a = buff.toString(); - String b = URLEncoder.encode(a, "UTF-8"); - String c = URLDecoder.decode(b, "UTF-8"); - assertEquals(a, c); - String d = StringUtils.urlDecode(b); - assertEquals(d, c); - } - } - - private void testJavaString() { - Random random = new Random(1); - for (int i = 0; i < 1000; i++) { - int len = random.nextInt(10); - StringBuilder buff = new StringBuilder(); - for (int j = 0; j < len; j++) { - if (random.nextBoolean()) { - buff.append((char) random.nextInt(0x3000)); - } else { - buff.append((char) random.nextInt(255)); - } - } - String a = buff.toString(); - String b = StringUtils.javaEncode(a); - String c = StringUtils.javaDecode(b); - assertEquals(a, c); - } - } - - private void testSplit() { - assertEquals(3, StringUtils.arraySplit("ABC,DEF,G\\,HI", ',', false).length); - assertEquals(StringUtils.arrayCombine(new String[] { "", " ", "," }, ','), ", ,\\,"); - Random random = new Random(1); - for (int i = 0; i < 100; i++) { - int len = random.nextInt(10); - StringBuilder buff = new StringBuilder(); - String select = "abcd,"; - for (int j = 0; j < len; j++) { - char c = select.charAt(random.nextInt(select.length())); - if (c == 'a') { - buff.append("\\\\"); - } else if (c == 'b') { - buff.append("\\,"); - } else { - buff.append(c); - } - } - String a = buff.toString(); - String[] b = StringUtils.arraySplit(a, ',', false); - String c = StringUtils.arrayCombine(b, ','); - assertEquals(a, c); - } - } - -} diff --git a/tools/h2/src/test/org/h2/test/unit/TestTools.java b/tools/h2/src/test/org/h2/test/unit/TestTools.java deleted file mode 100755 index b44e0c9..0000000 --- a/tools/h2/src/test/org/h2/test/unit/TestTools.java +++ /dev/null @@ -1,708 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.test.unit; - -import java.io.ByteArrayOutputStream; -import java.io.PrintStream; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; -import java.math.BigDecimal; -import java.net.ServerSocket; -import java.net.Socket; -import java.sql.Connection; -import java.sql.Date; -import java.sql.DriverManager; -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.sql.Statement; -import java.sql.Time; -import java.sql.Timestamp; -import java.sql.Types; -import java.util.ArrayList; -import java.util.Random; -import org.h2.constant.ErrorCode; -import org.h2.store.FileLister; -import org.h2.store.fs.FileSystem; -import org.h2.test.TestBase; -import org.h2.test.trace.Player; -import org.h2.tools.Backup; -import org.h2.tools.ChangeFileEncryption; -import org.h2.tools.ConvertTraceFile; -import org.h2.tools.DeleteDbFiles; -import org.h2.tools.Recover; -import org.h2.tools.Restore; -import org.h2.tools.RunScript; -import org.h2.tools.Script; -import org.h2.tools.Server; -import org.h2.tools.SimpleResultSet; -import org.h2.util.IOUtils; -import org.h2.util.JdbcUtils; - -/** - * Tests the database tools. - */ -public class TestTools extends TestBase { - - private Server server; - - /** - * Run just this test. - * - * @param a ignored - */ - public static void main(String... a) throws Exception { - TestBase.createCaller().init().test(); - } - - public void test() throws Exception { - if (config.networked) { - return; - } - testSimpleResultSet(); - org.h2.Driver.load(); - testJdbcDriverUtils(); - testWrongServer(); - deleteDb("utils"); - testDeleteFiles(); - testScriptRunscriptLob(); - deleteDb("utils"); - testServerMain(); - testRemove(); - testConvertTraceFile(); - testManagementDb(); - testChangeFileEncryption(); - testServer(); - testScriptRunscript(); - testBackupRestore(); - testRecover(); - deleteDb("utils"); - IOUtils.delete(getBaseDir() + "/b2.sql"); - IOUtils.delete(getBaseDir() + "/b2.sql.txt"); - IOUtils.delete(getBaseDir() + "/b2.zip"); - } - - private void testSimpleResultSet() throws Exception { - SimpleResultSet rs; - rs = new SimpleResultSet(); - rs.addColumn("a", Types.BIGINT, 0, 0); - rs.addColumn("b", Types.BINARY, 0, 0); - rs.addColumn("c", Types.BOOLEAN, 0, 0); - rs.addColumn("d", Types.DATE, 0, 0); - rs.addColumn("e", Types.DECIMAL, 0, 0); - rs.addColumn("f", Types.FLOAT, 0, 0); - rs.addColumn("g", Types.VARCHAR, 0, 0); - rs.addColumn("h", Types.ARRAY, 0, 0); - rs.addColumn("i", Types.TIME, 0, 0); - rs.addColumn("j", Types.TIMESTAMP, 0, 0); - - Date d = Date.valueOf("2001-02-03"); - byte[] b = {(byte) 0xab}; - Object[] a = {1, 2}; - Time t = Time.valueOf("10:20:30"); - Timestamp ts = Timestamp.valueOf("2002-03-04 10:20:30"); - rs.addRow(1, b, true, d, "10.3", Math.PI, "-3", a, t, ts); - - rs.next(); - - assertEquals(1, rs.getLong(1)); - assertEquals((byte) 1, rs.getByte(1)); - assertEquals((short) 1, rs.getShort(1)); - assertEquals(1, rs.getLong("a")); - assertEquals((byte) 1, rs.getByte("a")); - assertEquals(1, rs.getInt("a")); - assertEquals((short) 1, rs.getShort("a")); - assertTrue(rs.getObject(1).getClass() == Integer.class); - assertTrue(rs.getObject("a").getClass() == Integer.class); - - assertEquals(b, rs.getBytes(2)); - assertEquals(b, rs.getBytes("b")); - - assertTrue(rs.getBoolean(3)); - assertTrue(rs.getBoolean("c")); - assertEquals(d.getTime(), rs.getDate(4).getTime()); - assertEquals(d.getTime(), rs.getDate("d").getTime()); - - assertTrue(new BigDecimal("10.3").equals(rs.getBigDecimal(5))); - assertTrue(new BigDecimal("10.3").equals(rs.getBigDecimal("e"))); - assertEquals(10.3, rs.getDouble(5)); - assertEquals((float) 10.3, rs.getFloat(5)); - - assertTrue(Math.PI == rs.getDouble(6)); - assertTrue(Math.PI == rs.getDouble("f")); - assertTrue((float) Math.PI == rs.getFloat(6)); - assertTrue((float) Math.PI == rs.getFloat("f")); - - assertEquals(-3, rs.getInt(7)); - assertEquals(-3, rs.getByte(7)); - assertEquals(-3, rs.getShort(7)); - assertEquals(-3, rs.getLong(7)); - - Object[] a2 = (Object[]) rs.getArray(8).getArray(); - assertEquals(2, a2.length); - assertTrue(a == a2); - a2 = (Object[]) rs.getArray("h").getArray(); - assertEquals(2, a2.length); - assertTrue(a == a2); - - assertTrue(t == rs.getTime("i")); - assertTrue(t == rs.getTime(9)); - - assertTrue(ts == rs.getTimestamp("j")); - assertTrue(ts == rs.getTimestamp(10)); - - // all 'updateX' methods are not supported - for (Method m: rs.getClass().getMethods()) { - if (m.getName().startsWith("update")) { - int len = m.getParameterTypes().length; - Object[] params = new Object[len]; - int i = 0; - for (Class< ? > type : m.getParameterTypes()) { - Object o = null; - if (type == int.class) { - o = 1; - } else if (type == byte.class) { - o = (byte) 1; - } else if (type == double.class) { - o = (double) 1; - } else if (type == float.class) { - o = (float) 1; - } else if (type == long.class) { - o = (long) 1; - } else if (type == short.class) { - o = (short) 1; - } else if (type == boolean.class) { - o = false; - } - params[i] = o; - i++; - } - try { - m.invoke(rs, params); - } catch (InvocationTargetException e) { - SQLException e2 = (SQLException) e.getTargetException(); - assertEquals(ErrorCode.FEATURE_NOT_SUPPORTED_1, e2.getErrorCode()); - } - } - } - - assertEquals(ResultSet.TYPE_FORWARD_ONLY, rs.getType()); - assertFalse(rs.isClosed()); - rs.beforeFirst(); - assertEquals(0, rs.getRow()); - assertTrue(rs.next()); - assertFalse(rs.isClosed()); - assertEquals(1, rs.getRow()); - assertFalse(rs.next()); - assertTrue(rs.isClosed()); - assertEquals(0, rs.getRow()); - } - - private void testJdbcDriverUtils() { - assertEquals("org.h2.Driver", JdbcUtils.getDriver("jdbc:h2:~/test")); - assertEquals("org.postgresql.Driver", JdbcUtils.getDriver("jdbc:postgresql:test")); - assertEquals(null, JdbcUtils.getDriver("jdbc:unknown:test")); - } - - private void testWrongServer() throws Exception { - final ServerSocket serverSocket = new ServerSocket(9001); - Thread thread = new Thread() { - public void run() { - try { - Socket socket = serverSocket.accept(); - byte[] data = new byte[1024]; - data[0] = 'x'; - socket.getOutputStream().write(data); - socket.close(); - } catch (Exception e) { - // ignore - } - } - }; - thread.start(); - try { - Connection conn = getConnection("jdbc:h2:tcp://localhost:9001/test"); - conn.close(); - fail(); - } catch (SQLException e) { - assertEquals(ErrorCode.CONNECTION_BROKEN_1, e.getErrorCode()); - } - serverSocket.close(); - thread.join(); - } - - private void testDeleteFiles() throws SQLException { - deleteDb("utilsMore"); - Connection conn = getConnection("utilsMore"); - Statement stat = conn.createStatement(); - stat.execute("create table test(c clob) as select space(10000) from dual"); - conn.close(); - DeleteDbFiles.execute(getBaseDir(), "utils", true); - conn = getConnection("utilsMore"); - stat = conn.createStatement(); - ResultSet rs; - rs = stat.executeQuery("select * from test"); - rs.next(); - rs.getString(1); - conn.close(); - deleteDb("utilsMore"); - } - - private void testServerMain() throws SQLException { - String result; - Connection conn; - - result = runServer(0, new String[]{"-?"}); - assertTrue(result.indexOf("Starts the H2 Console") >= 0); - assertTrue(result.indexOf("Unknown option") < 0); - - result = runServer(1, new String[]{"-xy"}); - assertTrue(result.indexOf("Starts the H2 Console") >= 0); - assertTrue(result.indexOf("Unsupported option") >= 0); - result = runServer(0, new String[]{"-tcp", "-tcpPort", "9001", "-tcpPassword", "abc"}); - assertTrue(result.indexOf("tcp://") >= 0); - assertTrue(result.indexOf(":9001") >= 0); - assertTrue(result.indexOf("only local") >= 0); - assertTrue(result.indexOf("Starts the H2 Console") < 0); - conn = DriverManager.getConnection("jdbc:h2:tcp://localhost:9001/mem:", "sa", "sa"); - conn.close(); - result = runServer(0, new String[]{"-tcpShutdown", "tcp://localhost:9001", "-tcpPassword", "abc", "-tcpShutdownForce"}); - assertTrue(result.indexOf("Shutting down") >= 0); - - result = runServer(0, new String[]{"-tcp", "-tcpAllowOthers", "-tcpPort", "9001", "-tcpPassword", "abcdef", "-tcpSSL"}); - assertTrue(result.indexOf("ssl://") >= 0); - assertTrue(result.indexOf(":9001") >= 0); - assertTrue(result.indexOf("others can") >= 0); - assertTrue(result.indexOf("Starts the H2 Console") < 0); - conn = DriverManager.getConnection("jdbc:h2:ssl://localhost:9001/mem:", "sa", "sa"); - conn.close(); - - result = runServer(0, new String[]{"-tcpShutdown", "ssl://localhost:9001", "-tcpPassword", "abcdef"}); - assertTrue(result.indexOf("Shutting down") >= 0); - try { - DriverManager.getConnection("jdbc:h2:ssl://localhost:9001/mem:", "sa", "sa"); - fail(); - } catch (SQLException e) { - assertKnownException(e); - } - - result = runServer(0, new String[]{ - "-web", "-webPort", "9002", "-webAllowOthers", "-webSSL", - "-pg", "-pgAllowOthers", "-pgPort", "9003", - "-tcp", "-tcpAllowOthers", "-tcpPort", "9006", "-tcpPassword", "abc"}); - Server stop = server; - assertTrue(result.indexOf("https://") >= 0); - assertTrue(result.indexOf(":9002") >= 0); - assertTrue(result.indexOf("pg://") >= 0); - assertTrue(result.indexOf(":9003") >= 0); - assertTrue(result.indexOf("others can") >= 0); - assertTrue(result.indexOf("only local") < 0); - assertTrue(result.indexOf("tcp://") >= 0); - assertTrue(result.indexOf(":9006") >= 0); - - conn = DriverManager.getConnection("jdbc:h2:tcp://localhost:9006/mem:", "sa", "sa"); - conn.close(); - - result = runServer(0, new String[]{"-tcpShutdown", "tcp://localhost:9006", "-tcpPassword", "abc", "-tcpShutdownForce"}); - assertTrue(result.indexOf("Shutting down") >= 0); - stop.shutdown(); - try { - DriverManager.getConnection("jdbc:h2:tcp://localhost:9006/mem:", "sa", "sa"); - fail(); - } catch (SQLException e) { - assertKnownException(e); - } - } - - private String runServer(int exitCode, String... args) { - ByteArrayOutputStream buff = new ByteArrayOutputStream(); - PrintStream ps = new PrintStream(buff); - server = new Server(); - server.setOut(ps); - int result = 0; - try { - server.runTool(args); - } catch (SQLException e) { - result = 1; - e.printStackTrace(ps); - } - assertEquals(exitCode, result); - ps.flush(); - String s = new String(buff.toByteArray()); - return s; - } - - private void testConvertTraceFile() throws Exception { - deleteDb("toolsConvertTraceFile"); - org.h2.Driver.load(); - String url = "jdbc:h2:" + getBaseDir() + "/toolsConvertTraceFile"; - Connection conn = DriverManager.getConnection(url + ";TRACE_LEVEL_FILE=3", "sa", "sa"); - Statement stat = conn.createStatement(); - stat.execute("create table test(id int primary key, name varchar, amount decimal)"); - PreparedStatement prep = conn.prepareStatement("insert into test values(?, ?, ?)"); - prep.setInt(1, 1); - prep.setString(2, "Hello \\'Joe\n\\'"); - prep.setBigDecimal(3, new BigDecimal("10.20")); - prep.executeUpdate(); - stat.execute("create table test2(id int primary key,\n" + - "a real, b double, c bigint,\n" + - "d smallint, e boolean, f binary, g date, h time, i timestamp)", Statement.NO_GENERATED_KEYS); - prep = conn.prepareStatement("insert into test2 values(1, ?, ?, ?, ?, ?, ?, ?, ?, ?)"); - prep.setFloat(1, Float.MIN_VALUE); - prep.setDouble(2, Double.MIN_VALUE); - prep.setLong(3, Long.MIN_VALUE); - prep.setShort(4, Short.MIN_VALUE); - prep.setBoolean(5, false); - prep.setBytes(6, new byte[] { (byte) 10, (byte) 20 }); - prep.setDate(7, java.sql.Date.valueOf("2007-12-31")); - prep.setTime(8, java.sql.Time.valueOf("23:59:59")); - prep.setTimestamp(9, java.sql.Timestamp.valueOf("2007-12-31 23:59:59")); - prep.executeUpdate(); - conn.close(); - - ConvertTraceFile.main("-traceFile", getBaseDir() + "/toolsConvertTraceFile.trace.db", "-javaClass", getBaseDir() + "/Test", "-script", getBaseDir() + "/test.sql"); - FileSystem fs = FileSystem.getInstance(getBaseDir()); - fs.delete(getBaseDir() + "/Test.java"); - - String trace = getBaseDir() + "/toolsConvertTraceFile.trace.db"; - assertTrue(fs.exists(trace)); - String newTrace = getBaseDir() + "/test.trace.db"; - fs.delete(newTrace); - assertFalse(fs.exists(newTrace)); - fs.rename(trace, newTrace); - deleteDb("toolsConvertTraceFile"); - Player.main(getBaseDir() + "/test.trace.db"); - testTraceFile(url); - - deleteDb("toolsConvertTraceFile"); - RunScript.main("-url", url, "-user", "sa", "-script", getBaseDir() + "/test.sql"); - testTraceFile(url); - - deleteDb("toolsConvertTraceFile"); - IOUtils.delete(getBaseDir() + "/toolsConvertTraceFile.h2.sql"); - IOUtils.delete(getBaseDir() + "/test.sql"); - } - - private void testTraceFile(String url) throws SQLException { - Connection conn; - Recover.main("-removePassword", "-dir", getBaseDir(), "-db", "toolsConvertTraceFile"); - conn = DriverManager.getConnection(url, "sa", ""); - Statement stat = conn.createStatement(); - ResultSet rs; - rs = stat.executeQuery("select * from test"); - rs.next(); - assertEquals(1, rs.getInt(1)); - assertEquals("Hello \\'Joe\n\\'", rs.getString(2)); - assertEquals("10.20", rs.getBigDecimal(3).toString()); - assertFalse(rs.next()); - rs = stat.executeQuery("select * from test2"); - rs.next(); - assertEquals(Float.MIN_VALUE, rs.getFloat("a")); - assertEquals(Double.MIN_VALUE, rs.getDouble("b")); - assertEquals(Long.MIN_VALUE, rs.getLong("c")); - assertEquals(Short.MIN_VALUE, rs.getShort("d")); - assertTrue(!rs.getBoolean("e")); - assertEquals(new byte[] { (byte) 10, (byte) 20 }, rs.getBytes("f")); - assertEquals("2007-12-31", rs.getString("g")); - assertEquals("23:59:59", rs.getString("h")); - assertEquals("2007-12-31 23:59:59.0", rs.getString("i")); - assertFalse(rs.next()); - conn.close(); - } - - private void testRemove() throws SQLException { - deleteDb("toolsRemove"); - org.h2.Driver.load(); - String url = "jdbc:h2:" + getBaseDir() + "/toolsRemove"; - Connection conn = DriverManager.getConnection(url, "sa", "sa"); - Statement stat = conn.createStatement(); - stat.execute("create table test(id int primary key, name varchar)"); - stat.execute("insert into test values(1, 'Hello')"); - conn.close(); - Recover.main("-dir", getBaseDir(), "-db", "toolsRemove", "-removePassword"); - conn = DriverManager.getConnection(url, "sa", ""); - stat = conn.createStatement(); - ResultSet rs; - rs = stat.executeQuery("select * from test"); - rs.next(); - assertEquals(1, rs.getInt(1)); - assertEquals("Hello", rs.getString(2)); - conn.close(); - deleteDb("toolsRemove"); - IOUtils.delete(getBaseDir() + "/toolsRemove.h2.sql"); - } - - private void testRecover() throws SQLException { - deleteDb("toolsRecover"); - org.h2.Driver.load(); - String url = getURL("toolsRecover", true); - Connection conn = DriverManager.getConnection(url, "sa", "sa"); - Statement stat = conn.createStatement(); - stat.execute("create table test(id int primary key, name varchar, b blob, c clob)"); - stat.execute("create table \"test 2\"(id int primary key, name varchar)"); - stat.execute("comment on table test is ';-)'"); - stat.execute("insert into test values(1, 'Hello', SECURE_RAND(4100), '\u00e4' || space(4100))"); - ResultSet rs; - rs = stat.executeQuery("select * from test"); - rs.next(); - byte[] b1 = rs.getBytes(3); - String s1 = rs.getString(4); - - conn.close(); - Recover.main("-dir", getBaseDir(), "-db", "toolsRecover"); - - // deleteDb would delete the .lob.db directory as well - // deleteDb("toolsRecover"); - ArrayList list = FileLister.getDatabaseFiles(getBaseDir(), "toolsRecover", true); - for (String fileName : list) { - if (!IOUtils.isDirectory(fileName)) { - IOUtils.delete(fileName); - } - } - - conn = DriverManager.getConnection(url, "another", "another"); - stat = conn.createStatement(); - String suffix = ".h2.sql"; - stat.execute("runscript from '" + getBaseDir() + "/toolsRecover" + suffix + "'"); - rs = stat.executeQuery("select * from \"test 2\""); - assertFalse(rs.next()); - rs = stat.executeQuery("select * from test"); - rs.next(); - assertEquals(1, rs.getInt(1)); - assertEquals("Hello", rs.getString(2)); - byte[] b2 = rs.getBytes(3); - String s2 = rs.getString(4); - assertEquals("\u00e4 ", s2.substring(0, 2)); - assertEquals(4100, b2.length); - assertEquals(4101, s2.length()); - assertEquals(b1, b2); - assertEquals(s1, s2); - assertFalse(rs.next()); - conn.close(); - deleteDb("toolsRecover"); - IOUtils.delete(getBaseDir() + "/toolsRecover.h2.sql"); - String dir = getBaseDir() + "/toolsRecover.lobs.db"; - FileSystem.getInstance(dir).deleteRecursive(dir, false); - } - - private void testManagementDb() throws SQLException { - int count = getSize(2, 10); - for (int i = 0; i < count; i++) { - Server tcpServer = Server.createTcpServer("-tcpPort", "9192").start(); - tcpServer.stop(); - tcpServer = Server.createTcpServer("-tcpPassword", "abc", "-tcpPort", "9192").start(); - tcpServer.stop(); - } - } - - private void testScriptRunscriptLob() throws Exception { - org.h2.Driver.load(); - String url = "jdbc:h2:" + getBaseDir() + "/utils"; - String user = "sa", password = "abc"; - String fileName = getBaseDir() + "/b2.sql"; - Connection conn = DriverManager.getConnection(url, user, password); - conn.createStatement().execute("CREATE TABLE TEST(ID INT PRIMARY KEY, BDATA BLOB, CDATA CLOB)"); - PreparedStatement prep = conn.prepareStatement("INSERT INTO TEST VALUES(?, ?, ?)"); - - prep.setInt(1, 1); - prep.setNull(2, Types.BLOB); - prep.setNull(3, Types.CLOB); - prep.execute(); - - prep.setInt(1, 2); - prep.setString(2, "face"); - prep.setString(3, "face"); - prep.execute(); - - Random random = new Random(1); - prep.setInt(1, 3); - byte[] large = new byte[getSize(10 * 1024, 100 * 1024)]; - random.nextBytes(large); - prep.setBytes(2, large); - String largeText = new String(large, "ISO-8859-1"); - prep.setString(3, largeText); - prep.execute(); - - for (int i = 0; i < 2; i++) { - ResultSet rs = conn.createStatement().executeQuery("SELECT * FROM TEST ORDER BY ID"); - rs.next(); - assertEquals(1, rs.getInt(1)); - assertTrue(rs.getString(2) == null); - assertTrue(rs.getString(3) == null); - rs.next(); - assertEquals(2, rs.getInt(1)); - assertEquals("face", rs.getString(2)); - assertEquals("face", rs.getString(3)); - rs.next(); - assertEquals(3, rs.getInt(1)); - assertEquals(large, rs.getBytes(2)); - assertEquals(largeText, rs.getString(3)); - assertFalse(rs.next()); - - conn.close(); - Script.main("-url", url, "-user", user, "-password", password, "-script", fileName); - DeleteDbFiles.main("-dir", getBaseDir(), "-db", "utils", "-quiet"); - RunScript.main("-url", url, "-user", user, "-password", password, "-script", fileName); - conn = DriverManager.getConnection("jdbc:h2:" + getBaseDir() + "/utils", "sa", "abc"); - } - conn.close(); - - } - - private void testScriptRunscript() throws SQLException { - org.h2.Driver.load(); - String url = "jdbc:h2:" + getBaseDir() + "/utils"; - String user = "sa", password = "abc"; - String fileName = getBaseDir() + "/b2.sql"; - DeleteDbFiles.main("-dir", getBaseDir(), "-db", "utils", "-quiet"); - Connection conn = DriverManager.getConnection(url, user, password); - conn.createStatement().execute("CREATE TABLE TEST(ID INT PRIMARY KEY, NAME VARCHAR)"); - conn.createStatement().execute("INSERT INTO TEST VALUES(1, 'Hello')"); - conn.close(); - Script.main("-url", url, "-user", user, "-password", password, "-script", fileName, "-options", - "nodata", "compression", "lzf", "cipher", "xtea", "password", "'123'"); - Script.main("-url", url, "-user", user, "-password", password, "-script", fileName + ".txt"); - DeleteDbFiles.main("-dir", getBaseDir(), "-db", "utils", "-quiet"); - RunScript.main("-url", url, "-user", user, "-password", password, "-script", fileName, - "-options", "compression", "lzf", "cipher", "xtea", "password", "'123'"); - conn = DriverManager.getConnection("jdbc:h2:" + getBaseDir() + "/utils", "sa", "abc"); - ResultSet rs = conn.createStatement().executeQuery("SELECT * FROM TEST"); - assertFalse(rs.next()); - conn.close(); - - DeleteDbFiles.main("-dir", getBaseDir(), "-db", "utils", "-quiet"); - RunScript tool = new RunScript(); - ByteArrayOutputStream buff = new ByteArrayOutputStream(); - tool.setOut(new PrintStream(buff)); - tool.runTool("-url", url, "-user", user, "-password", password, "-script", fileName + ".txt", - "-showResults"); - assertTrue(buff.toString().indexOf("Hello") >= 0); - } - - private void testBackupRestore() throws SQLException { - org.h2.Driver.load(); - String url = "jdbc:h2:" + getBaseDir() + "/utils"; - String user = "sa", password = "abc"; - String fileName = getBaseDir() + "/b2.zip"; - DeleteDbFiles.main("-dir", getBaseDir(), "-db", "utils", "-quiet"); - Connection conn = DriverManager.getConnection(url, user, password); - conn.createStatement().execute("CREATE TABLE TEST(ID INT PRIMARY KEY, NAME VARCHAR)"); - conn.createStatement().execute("INSERT INTO TEST VALUES(1, 'Hello')"); - conn.close(); - Backup.main("-file", fileName, "-dir", getBaseDir(), "-db", "utils", "-quiet"); - DeleteDbFiles.main("-dir", getBaseDir(), "-db", "utils", "-quiet"); - Restore.main("-file", fileName, "-dir", getBaseDir(), "-db", "utils", "-quiet"); - conn = DriverManager.getConnection("jdbc:h2:" + getBaseDir() + "/utils", "sa", "abc"); - ResultSet rs = conn.createStatement().executeQuery("SELECT * FROM TEST"); - assertTrue(rs.next()); - assertFalse(rs.next()); - try { - // must fail when the database is in use - Backup.main("-file", fileName, "-dir", getBaseDir(), "-db", "utils"); - fail(); - } catch (SQLException e) { - assertKnownException(e); - } - conn.close(); - DeleteDbFiles.main("-dir", getBaseDir(), "-db", "utils", "-quiet"); - } - - private void testChangeFileEncryption() throws SQLException { - org.h2.Driver.load(); - DeleteDbFiles.execute(getBaseDir(), "utils", true); - Connection conn = DriverManager.getConnection("jdbc:h2:" + - getBaseDir() + "/utils;CIPHER=XTEA", "sa", "abc 123"); - Statement stat = conn.createStatement(); - stat.execute("CREATE TABLE TEST(ID INT PRIMARY KEY, DATA CLOB) " + - "AS SELECT X, SPACE(3000) FROM SYSTEM_RANGE(1, 300)"); - conn.close(); - String[] args = { "-dir", getBaseDir(), "-db", "utils", "-cipher", "XTEA", "-decrypt", "abc", "-quiet" }; - ChangeFileEncryption.main(args); - args = new String[] { "-dir", getBaseDir(), "-db", "utils", "-cipher", "AES", "-encrypt", "def", "-quiet" }; - ChangeFileEncryption.main(args); - conn = DriverManager.getConnection("jdbc:h2:" + - getBaseDir() + "/utils;CIPHER=AES", "sa", "def 123"); - stat = conn.createStatement(); - stat.execute("SELECT * FROM TEST"); - try { - args = new String[] { "-dir", getBaseDir(), "-db", "utils", "-cipher", "AES", "-decrypt", "def", "-quiet" }; - ChangeFileEncryption.main(args); - fail(); - } catch (SQLException e) { - assertKnownException(e); - } - conn.close(); - args = new String[] { "-dir", getBaseDir(), "-db", "utils", "-quiet" }; - DeleteDbFiles.main(args); - } - - private void testServer() throws SQLException { - Connection conn; - deleteDb("test"); - Server tcpServer = Server.createTcpServer( - "-baseDir", getBaseDir(), - "-tcpPort", "9192", - "-tcpAllowOthers").start(); - conn = DriverManager.getConnection("jdbc:h2:tcp://localhost:9192/test", "sa", ""); - conn.close(); - tcpServer.stop(); - Server.createTcpServer( - "-ifExists", - "-tcpPassword", "abc", - "-baseDir", getBaseDir(), - "-tcpPort", "9192").start(); - try { - conn = DriverManager.getConnection("jdbc:h2:tcp://localhost:9192/test2", "sa", ""); - fail("should not be able to create new db"); - } catch (SQLException e) { - assertKnownException(e); - } - conn = DriverManager.getConnection("jdbc:h2:tcp://localhost:9192/test", "sa", ""); - conn.close(); - try { - Server.shutdownTcpServer("tcp://localhost:9192", "", true, false); - fail("shouldn't work and should throw an exception"); - } catch (SQLException e) { - assertKnownException(e); - } - conn = DriverManager.getConnection("jdbc:h2:tcp://localhost:9192/test", "sa", ""); - // conn.close(); - Server.shutdownTcpServer("tcp://localhost:9192", "abc", true, false); - // check that the database is closed - deleteDb("test"); - try { - DriverManager.getConnection("jdbc:h2:tcp://localhost:9192/test", "sa", ""); - fail("server must have been closed"); - } catch (SQLException e) { - assertKnownException(e); - } - try { - conn.close(); - } catch (SQLException e) { - // ignore - } - // Test filesystem prefix and escape from baseDir - deleteDb("testSplit"); - server = Server.createTcpServer( - "-baseDir", getBaseDir(), - "-tcpPort", "9192", - "-tcpAllowOthers").start(); - conn = DriverManager.getConnection("jdbc:h2:tcp://localhost:9192/split:testSplit", "sa", ""); - conn.close(); - - try { - conn = DriverManager.getConnection("jdbc:h2:tcp://localhost:9192/../test", "sa", ""); - fail("Should throw an exception!"); - } catch (Throwable e) { - // Expected - } - - server.stop(); - deleteDb("testSplit"); - } - -} diff --git a/tools/h2/src/test/org/h2/test/unit/TestValue.java b/tools/h2/src/test/org/h2/test/unit/TestValue.java deleted file mode 100755 index 601c61f..0000000 --- a/tools/h2/src/test/org/h2/test/unit/TestValue.java +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.test.unit; - -import org.h2.test.TestBase; -import org.h2.value.Value; -import org.h2.value.ValueDouble; -import org.h2.value.ValueFloat; -import org.h2.value.ValueUuid; - -/** - * Tests features of values. - */ -public class TestValue extends TestBase { - - /** - * Run just this test. - * - * @param a ignored - */ - public static void main(String... a) throws Exception { - TestBase.createCaller().init().test(); - } - - public void test() { - testUUID(); - testDouble(false); - testDouble(true); - } - - private void testDouble(boolean useFloat) { - double[] d = { - Double.NEGATIVE_INFINITY, - -1, - 0, - 1, - Double.POSITIVE_INFINITY, - Double.NaN - }; - Value[] values = new Value[d.length]; - for (int i = 0; i < d.length; i++) { - Value v = useFloat ? (Value) ValueFloat.get((float) d[i]) : (Value) ValueDouble.get(d[i]); - values[i] = v; - assertTrue(values[i].compareTypeSave(values[i], null) == 0); - assertTrue(v.equals(v)); - assertEquals(i < 2 ? -1 : i > 2 ? 1 : 0, v.getSignum()); - } - for (int i = 0; i < d.length - 1; i++) { - assertTrue(values[i].compareTypeSave(values[i+1], null) < 0); - assertTrue(values[i + 1].compareTypeSave(values[i], null) > 0); - assertTrue(!values[i].equals(values[i+1])); - } - } - - private void testUUID() { - long maxHigh = 0, maxLow = 0, minHigh = -1L, minLow = -1L; - for (int i = 0; i < 100; i++) { - ValueUuid uuid = ValueUuid.getNewRandom(); - maxHigh |= uuid.getHigh(); - maxLow |= uuid.getLow(); - minHigh &= uuid.getHigh(); - minLow &= uuid.getLow(); - } - ValueUuid max = ValueUuid.get(maxHigh, maxLow); - assertEquals("ffffffff-ffff-4fff-bfff-ffffffffffff", max.getString()); - ValueUuid min = ValueUuid.get(minHigh, minLow); - assertEquals("00000000-0000-4000-8000-000000000000", min.getString()); - } - -} diff --git a/tools/h2/src/test/org/h2/test/unit/TestValueHashMap.java b/tools/h2/src/test/org/h2/test/unit/TestValueHashMap.java deleted file mode 100755 index a2192fc..0000000 --- a/tools/h2/src/test/org/h2/test/unit/TestValueHashMap.java +++ /dev/null @@ -1,160 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.test.unit; - -import java.sql.Connection; -import java.util.ArrayList; -import java.util.Collections; -import java.util.Comparator; -import java.util.HashMap; -import java.util.Random; -import org.h2.store.DataHandler; -import org.h2.store.FileStore; -import org.h2.store.LobStorage; -import org.h2.test.TestBase; -import org.h2.util.New; -import org.h2.util.SmallLRUCache; -import org.h2.util.TempFileDeleter; -import org.h2.util.ValueHashMap; -import org.h2.value.CompareMode; -import org.h2.value.Value; -import org.h2.value.ValueDouble; -import org.h2.value.ValueInt; - -/** - * Tests the value hash map. - */ -public class TestValueHashMap extends TestBase implements DataHandler { - - CompareMode compareMode = CompareMode.getInstance(null, 0); - - /** - * Run just this test. - * - * @param a ignored - */ - public static void main(String... a) throws Exception { - TestBase.createCaller().init().test(); - } - - public void test() { - testNotANumber(); - testRandomized(); - } - - private void testNotANumber() { - ValueHashMap map = ValueHashMap.newInstance(); - for (int i = 1; i < 100; i++) { - double d = Double.longBitsToDouble(0x7ff0000000000000L | i); - ValueDouble v = ValueDouble.get(d); - map.put(v, null); - assertEquals(1, map.size()); - } - } - - private void testRandomized() { - ValueHashMap map = ValueHashMap.newInstance(); - HashMap hash = New.hashMap(); - Random random = new Random(1); - Comparator vc = new Comparator() { - public int compare(Value v1, Value v2) { - return v1.compareTo(v2, compareMode); - } - }; - for (int i = 0; i < 10000; i++) { - int op = random.nextInt(10); - Value key = ValueInt.get(random.nextInt(100)); - Value value = ValueInt.get(random.nextInt(100)); - switch (op) { - case 0: - map.put(key, value); - hash.put(key, value); - break; - case 1: - map.remove(key); - hash.remove(key); - break; - case 2: - Value v1 = map.get(key); - Value v2 = hash.get(key); - assertTrue(v1 == null ? v2 == null : v1.equals(v2)); - break; - case 3: { - ArrayList a1 = map.keys(); - ArrayList a2 = New.arrayList(hash.keySet()); - assertEquals(a1.size(), a2.size()); - Collections.sort(a1, vc); - Collections.sort(a2, vc); - for (int j = 0; j < a1.size(); j++) { - assertTrue(a1.get(j).equals(a2.get(j))); - } - break; - } - case 4: - ArrayList a1 = map.values(); - ArrayList a2 = New.arrayList(hash.values()); - assertEquals(a1.size(), a2.size()); - Collections.sort(a1, vc); - Collections.sort(a2, vc); - for (int j = 0; j < a1.size(); j++) { - assertTrue(a1.get(j).equals(a2.get(j))); - } - break; - default: - } - } - } - - public String getDatabasePath() { - return null; - } - - public FileStore openFile(String name, String mode, boolean mustExist) { - return null; - } - - public void checkPowerOff() { - // nothing to do - } - - public void checkWritingAllowed() { - // nothing to do - } - - public void freeUpDiskSpace() { - // nothing to do - } - - public int getMaxLengthInplaceLob() { - return 0; - } - - public String getLobCompressionAlgorithm(int type) { - return null; - } - - public Object getLobSyncObject() { - return this; - } - - public SmallLRUCache getLobFileListCache() { - return null; - } - - public TempFileDeleter getTempFileDeleter() { - return TempFileDeleter.getInstance(); - } - - public LobStorage getLobStorage() { - return null; - } - - public Connection getLobConnection() { - return null; - } - -} diff --git a/tools/h2/src/test/org/h2/test/unit/TestValueMemory.java b/tools/h2/src/test/org/h2/test/unit/TestValueMemory.java deleted file mode 100755 index ac30290..0000000 --- a/tools/h2/src/test/org/h2/test/unit/TestValueMemory.java +++ /dev/null @@ -1,242 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.test.unit; - -import java.io.ByteArrayInputStream; -import java.io.StringReader; -import java.math.BigDecimal; -import java.sql.Connection; -import java.sql.SQLException; -import java.util.ArrayList; -import java.util.IdentityHashMap; -import java.util.Random; -import org.h2.store.DataHandler; -import org.h2.store.FileStore; -import org.h2.store.LobStorage; -import org.h2.test.TestBase; -import org.h2.util.SmallLRUCache; -import org.h2.util.TempFileDeleter; -import org.h2.util.Utils; -import org.h2.value.Value; -import org.h2.value.ValueArray; -import org.h2.value.ValueBoolean; -import org.h2.value.ValueByte; -import org.h2.value.ValueBytes; -import org.h2.value.ValueDate; -import org.h2.value.ValueDecimal; -import org.h2.value.ValueDouble; -import org.h2.value.ValueFloat; -import org.h2.value.ValueInt; -import org.h2.value.ValueJavaObject; -import org.h2.value.ValueLong; -import org.h2.value.ValueNull; -import org.h2.value.ValueShort; -import org.h2.value.ValueString; -import org.h2.value.ValueStringFixed; -import org.h2.value.ValueStringIgnoreCase; -import org.h2.value.ValueTime; -import org.h2.value.ValueTimestamp; -import org.h2.value.ValueUuid; - -/** - * Tests the memory consumption of values. Values can estimate how much memory - * they occupy, and this tests if this estimation is correct. - */ -public class TestValueMemory extends TestBase implements DataHandler { - - private Random random = new Random(1); - private SmallLRUCache lobFileListCache = SmallLRUCache.newInstance(128); - private LobStorage lobStorage; - - /** - * Run just this test. - * - * @param a ignored - */ - public static void main(String... a) throws Exception { - TestBase.createCaller().init().test(); - } - - public void test() throws SQLException { - testCompare(); - for (int i = 0; i < Value.TYPE_COUNT; i++) { - testType(i); - } - } - - private void testCompare() { - ValueDecimal a = ValueDecimal.get(new BigDecimal("0.0")); - ValueDecimal b = ValueDecimal.get(new BigDecimal("-0.00")); - assertTrue(a.hashCode() != b.hashCode()); - assertFalse(a.equals(b)); - } - - private void testType(int type) throws SQLException { - System.gc(); - System.gc(); - long first = Utils.getMemoryUsed(); - ArrayList list = new ArrayList(); - long memory = 0; - for (int i = 0; memory < 1000000; i++) { - Value v = create(type); - memory += v.getMemory(); - list.add(v); - } - Object[] array = list.toArray(); - IdentityHashMap map = new IdentityHashMap(); - for (Object a : array) { - map.put(a, a); - } - int size = map.size(); - map.clear(); - map = null; - list = null; - System.gc(); - System.gc(); - long used = Utils.getMemoryUsed() - first; - memory /= 1024; - if (used > memory * 3) { - fail("Type: " + type + " Used memory: " + used + " calculated: " + memory + " " + array.length + " size: " + size); - } - } - private Value create(int type) throws SQLException { - switch (type) { - case Value.NULL: - return ValueNull.INSTANCE; - case Value.BOOLEAN: - return ValueBoolean.get(false); - case Value.BYTE: - return ValueByte.get((byte) random.nextInt()); - case Value.SHORT: - return ValueShort.get((short) random.nextInt()); - case Value.INT: - return ValueInt.get(random.nextInt()); - case Value.LONG: - return ValueLong.get(random.nextLong()); - case Value.DECIMAL: - return ValueDecimal.get(new BigDecimal(random.nextInt())); - // + "12123344563456345634565234523451312312" - case Value.DOUBLE: - return ValueDouble.get(random.nextDouble()); - case Value.FLOAT: - return ValueFloat.get(random.nextFloat()); - case Value.TIME: - return ValueTime.get(new java.sql.Time(random.nextLong())); - case Value.DATE: - return ValueDate.get(new java.sql.Date(random.nextLong())); - case Value.TIMESTAMP: - return ValueTimestamp.get(new java.sql.Timestamp(random.nextLong())); - case Value.BYTES: - return ValueBytes.get(randomBytes(random.nextInt(1000))); - case Value.STRING: - return ValueString.get(randomString(random.nextInt(100))); - case Value.STRING_IGNORECASE: - return ValueStringIgnoreCase.get(randomString(random.nextInt(100))); - case Value.BLOB: { - int len = (int) Math.abs(random.nextGaussian() * 10); - byte[] data = randomBytes(len); - return getLobStorage().createBlob(new ByteArrayInputStream(data), len); - } - case Value.CLOB: { - int len = (int) Math.abs(random.nextGaussian() * 10); - String s = randomString(len); - return getLobStorage().createClob(new StringReader(s), len); - } - case Value.ARRAY: { - int len = random.nextInt(20); - Value[] list = new Value[len]; - for (int i = 0; i < list.length; i++) { - list[i] = create(Value.STRING); - } - return ValueArray.get(list); - } - case Value.RESULT_SET: - // not supported currently - return ValueNull.INSTANCE; - case Value.JAVA_OBJECT: - return ValueJavaObject.getNoCopy(randomBytes(random.nextInt(100))); - case Value.UUID: - return ValueUuid.get(random.nextLong(), random.nextLong()); - case Value.STRING_FIXED: - return ValueStringFixed.get(randomString(random.nextInt(100))); - default: - throw new AssertionError("type=" + type); - } - } - - private byte[] randomBytes(int len) { - byte[] data = new byte[len]; - if (random.nextBoolean()) { - // don't initialize always (compression) - random.nextBytes(data); - } - return data; - } - - private String randomString(int len) { - char[] chars = new char[len]; - if (random.nextBoolean()) { - // don't initialize always (compression) - for (int i = 0; i < chars.length; i++) { - chars[i] = (char) (random.nextGaussian() * 100); - } - } - return new String(chars); - } - - public void checkPowerOff() { - // nothing to do - } - - public void checkWritingAllowed() { - // nothing to do - } - - public void freeUpDiskSpace() { - // nothing to do - } - - public String getDatabasePath() { - return getBaseDir() + "/valueMemory"; - } - - public String getLobCompressionAlgorithm(int type) { - return "LZF"; - } - - public Object getLobSyncObject() { - return this; - } - - public int getMaxLengthInplaceLob() { - return 100; - } - - public FileStore openFile(String name, String mode, boolean mustExist) { - return FileStore.open(this, name, mode); - } - - public SmallLRUCache getLobFileListCache() { - return lobFileListCache; - } - - public TempFileDeleter getTempFileDeleter() { - return TempFileDeleter.getInstance(); - } - - public LobStorage getLobStorage() { - if (lobStorage == null) { - lobStorage = new LobStorage(this); - } - return lobStorage; - } - - public Connection getLobConnection() { - return null; - } - -} diff --git a/tools/h2/src/test/org/h2/test/unit/package.html b/tools/h2/src/test/org/h2/test/unit/package.html deleted file mode 100755 index 6523e4c..0000000 --- a/tools/h2/src/test/org/h2/test/unit/package.html +++ /dev/null @@ -1,15 +0,0 @@ - - - - -Javadoc package documentation -

    - -Unit tests that don't start the database (in most cases). - -

    \ No newline at end of file diff --git a/tools/h2/src/test/org/h2/test/utils/DebugFileObject.java b/tools/h2/src/test/org/h2/test/utils/DebugFileObject.java deleted file mode 100755 index e012bab..0000000 --- a/tools/h2/src/test/org/h2/test/utils/DebugFileObject.java +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.test.utils; - -import java.io.IOException; -import org.h2.store.fs.FileObject; - -/** - * A debugging file that logs all operations. - */ -public class DebugFileObject implements FileObject { - - private final DebugFileSystem fs; - private final FileObject file; - private final String name; - - DebugFileObject(DebugFileSystem fs, FileObject file) { - this.fs = fs; - this.file = file; - this.name = file.getName(); - } - - public void close() throws IOException { - debug("close"); - file.close(); - } - - public long getFilePointer() throws IOException { - debug("getFilePointer"); - return file.getFilePointer(); - } - - public String getName() { - debug("getName"); - return DebugFileSystem.PREFIX + file.getName(); - } - - public long length() throws IOException { - debug("length"); - return file.length(); - } - - public void readFully(byte[] b, int off, int len) throws IOException { - debug("readFully", off, len); - file.readFully(b, off, len); - } - - public void seek(long pos) throws IOException { - debug("seek", pos); - file.seek(pos); - } - - public void setFileLength(long newLength) throws IOException { - checkPowerOff(); - debug("setFileLength", newLength); - file.setFileLength(newLength); - } - - public void sync() throws IOException { - debug("sync"); - file.sync(); - } - - public void write(byte[] b, int off, int len) throws IOException { - checkPowerOff(); - debug("write", off, len); - file.write(b, off, len); - } - - private void debug(String method, Object... params) { - fs.trace(method, name, params); - } - - private void checkPowerOff() throws IOException { - try { - fs.checkPowerOff(); - } catch (IOException e) { - try { - file.close(); - } catch (IOException e2) { - // ignore - } - throw e; - } - } -} diff --git a/tools/h2/src/test/org/h2/test/utils/DebugFileSystem.java b/tools/h2/src/test/org/h2/test/utils/DebugFileSystem.java deleted file mode 100755 index cfd45fd..0000000 --- a/tools/h2/src/test/org/h2/test/utils/DebugFileSystem.java +++ /dev/null @@ -1,262 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.test.utils; - -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import org.h2.message.DbException; -import org.h2.store.fs.FileObject; -import org.h2.store.fs.FileSystem; - -/** - * A debugging file system that logs all operations. - */ -public class DebugFileSystem extends FileSystem { - - /** - * The prefix used for a debugging file system. - */ - static final String PREFIX = "debug:"; - - private static final DebugFileSystem INSTANCE = new DebugFileSystem(); - - private static final IOException POWER_OFF = new IOException("Simulated power failure"); - - private int powerOffCount; - private boolean trace; - - /** - * Register the file system. - */ - public static void register() { - FileSystem.register(INSTANCE); - } - - /** - * Check if the simulated power failure occurred. - * This call will decrement the countdown. - * - * @throws IOException if the simulated power failure occurred - */ - void checkPowerOff() throws IOException { - if (powerOffCount == 0) { - return; - } - if (powerOffCount > 1) { - powerOffCount--; - return; - } - powerOffCount = -1; - // throw new IOException("Simulated power failure"); - throw POWER_OFF; - } - - public boolean canWrite(String fileName) { - fileName = translateFileName(fileName); - trace("canWrite", fileName); - return FileSystem.getInstance(fileName).canWrite(fileName); - } - - public void copy(String original, String copy) { - original = translateFileName(original); - copy = translateFileName(copy); - trace("copy", original, copy); - FileSystem.getInstance(original).copy(original, copy); - } - - public void createDirs(String fileName) { - fileName = translateFileName(fileName); - trace("createDirs", fileName); - FileSystem.getInstance(fileName).createDirs(fileName); - } - - public boolean createNewFile(String fileName) { - fileName = translateFileName(fileName); - trace("createNewFile", fileName); - return FileSystem.getInstance(fileName).createNewFile(fileName); - } - - public String createTempFile(String prefix, String suffix, boolean deleteOnExit, boolean inTempDir) - throws IOException { - prefix = translateFileName(prefix); - trace("createTempFile", prefix, suffix, deleteOnExit, inTempDir); - return PREFIX + FileSystem.getInstance(prefix).createTempFile(prefix, suffix, deleteOnExit, inTempDir); - } - - public void delete(String fileName) { - fileName = translateFileName(fileName); - trace("fileName", fileName); - FileSystem.getInstance(fileName).delete(fileName); - } - - public void deleteRecursive(String directory, boolean tryOnly) { - directory = translateFileName(directory); - trace("deleteRecursive", directory); - FileSystem.getInstance(directory).deleteRecursive(directory, tryOnly); - } - - public boolean exists(String fileName) { - fileName = translateFileName(fileName); - trace("exists", fileName); - return FileSystem.getInstance(fileName).exists(fileName); - } - - public boolean fileStartsWith(String fileName, String prefix) { - fileName = translateFileName(fileName); - prefix = translateFileName(prefix); - trace("fileStartsWith", fileName, prefix); - return FileSystem.getInstance(fileName).fileStartsWith(fileName, prefix); - } - - public String getAbsolutePath(String fileName) { - fileName = translateFileName(fileName); - trace("getAbsolutePath", fileName); - return PREFIX + FileSystem.getInstance(fileName).getAbsolutePath(fileName); - } - - public String getFileName(String name) { - name = translateFileName(name); - trace("getFileName", name); - return FileSystem.getInstance(name).getFileName(name); - } - - public long getLastModified(String fileName) { - fileName = translateFileName(fileName); - trace("getLastModified", fileName); - return FileSystem.getInstance(fileName).getLastModified(fileName); - } - - public String getParent(String fileName) { - fileName = translateFileName(fileName); - trace("getParent", fileName); - return PREFIX + FileSystem.getInstance(fileName).getParent(fileName); - } - - public boolean isAbsolute(String fileName) { - fileName = translateFileName(fileName); - trace("isAbsolute", fileName); - return FileSystem.getInstance(fileName).isAbsolute(fileName); - } - - public boolean isDirectory(String fileName) { - fileName = translateFileName(fileName); - trace("isDirectory", fileName); - return FileSystem.getInstance(fileName).isDirectory(fileName); - } - - public boolean isReadOnly(String fileName) { - fileName = translateFileName(fileName); - trace("isReadOnly", fileName); - return FileSystem.getInstance(fileName).isReadOnly(fileName); - } - - public boolean setReadOnly(String fileName) { - fileName = translateFileName(fileName); - trace("setReadOnly", fileName); - return FileSystem.getInstance(fileName).setReadOnly(fileName); - } - - public long length(String fileName) { - fileName = translateFileName(fileName); - trace("length", fileName); - return FileSystem.getInstance(fileName).length(fileName); - } - - public String[] listFiles(String directory) { - directory = translateFileName(directory); - trace("listFiles", directory); - String[] list = FileSystem.getInstance(directory).listFiles(directory); - for (int i = 0; i < list.length; i++) { - list[i] = PREFIX + list[i]; - } - return list; - } - - public String normalize(String fileName) { - fileName = translateFileName(fileName); - trace("normalize", fileName); - return PREFIX + FileSystem.getInstance(fileName).normalize(fileName); - } - - public InputStream openFileInputStream(String fileName) throws IOException { - fileName = translateFileName(fileName); - trace("openFileInputStream", fileName); - return FileSystem.getInstance(fileName).openFileInputStream(fileName); - } - - public FileObject openFileObject(String fileName, String mode) throws IOException { - fileName = translateFileName(fileName); - trace("openFileObject", fileName, mode); - return new DebugFileObject(this, FileSystem.getInstance(fileName).openFileObject(fileName, mode)); - } - - public OutputStream openFileOutputStream(String fileName, boolean append) { - fileName = translateFileName(fileName); - trace("openFileOutputStream", fileName, append); - return FileSystem.getInstance(fileName).openFileOutputStream(fileName, append); - } - - public void rename(String oldName, String newName) { - oldName = translateFileName(oldName); - newName = translateFileName(newName); - trace("rename", oldName, newName); - FileSystem.getInstance(oldName).rename(oldName, newName); - } - - public boolean tryDelete(String fileName) { - fileName = translateFileName(fileName); - trace("tryDelete", fileName); - return FileSystem.getInstance(fileName).tryDelete(fileName); - } - - protected boolean accepts(String fileName) { - return fileName.startsWith(PREFIX); - } - - private String translateFileName(String fileName) { - if (!fileName.startsWith(PREFIX)) { - DbException.throwInternalError(fileName + " doesn't start with " + PREFIX); - } - return fileName.substring(PREFIX.length()); - } - - /** - * Print a debug message. - * - * @param method the method name - * @param fileName the file name - * @param params parameters if any - */ - void trace(String method, String fileName, Object... params) { - if (trace) { - StringBuilder buff = new StringBuilder(" "); - buff.append(fileName).append(' ').append(method); - for (Object s : params) { - buff.append(' ').append(s); - } - System.out.println(buff); - } - } - - public void setPowerOffCount(int count) { - this.powerOffCount = count; - } - - public int getPowerOffCount() { - return powerOffCount; - } - - public boolean isTrace() { - return trace; - } - - public void setTrace(boolean trace) { - this.trace = trace; - } - -} diff --git a/tools/h2/src/test/org/h2/test/utils/OutputCatcher.java b/tools/h2/src/test/org/h2/test/utils/OutputCatcher.java deleted file mode 100755 index 5b7da02..0000000 --- a/tools/h2/src/test/org/h2/test/utils/OutputCatcher.java +++ /dev/null @@ -1,210 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, Version - * 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). Initial Developer: H2 Group - */ -package org.h2.test.utils; - -import java.io.ByteArrayOutputStream; -import java.io.File; -import java.io.FileOutputStream; -import java.io.FilterOutputStream; -import java.io.IOException; -import java.io.OutputStream; -import java.io.PrintStream; -import java.io.PrintWriter; - -/** - * A tool to capture the output of System.out and System.err. The regular output - * still occurs, but it is additionally available as a String. - */ -public class OutputCatcher { - - /** - * The HTML text will contain this string if something was written to System.err. - */ - public static final String START_ERROR = ""; - - private ByteArrayOutputStream buff = new ByteArrayOutputStream(); - private HtmlOutputStream html; - private DualOutputStream out, err; - private String output; - - private OutputCatcher() { - html = new HtmlOutputStream(buff); - out = new DualOutputStream(html, System.out, false); - err = new DualOutputStream(html, System.err, true); - System.setOut(new PrintStream(out, true)); - System.setErr(new PrintStream(err, true)); - } - - /** - * Stop catching output. - */ - public void stop() { - System.out.flush(); - System.setOut(out.print); - System.err.flush(); - System.setErr(err.print); - output = new String(buff.toByteArray()); - } - - /** - * Write the output to a HTML file. - * - * @param title the title - * @param fileName the file name - */ - public void writeTo(String title, String fileName) throws IOException { - File file = new File(fileName); - file.getParentFile().mkdirs(); - PrintWriter writer = new PrintWriter(new FileOutputStream(file)); - writer.write("\n"); - writer.write("\n"); - writer.write("\n"); - writer.print(title); - writer.print("\n"); - writer.print("\n"); - writer.print("

    " + title + "


    \n"); - writer.print(output); - writer.write("\n"); - writer.close(); - } - - /** - * Create a new output catcher and start it. - * - * @return the output catcher - */ - public static OutputCatcher start() { - return new OutputCatcher(); - } - - /** - * An output stream that writes to both a HTML stream and a print stream. - */ - static class DualOutputStream extends FilterOutputStream { - - /** - * The original print stream. - */ - final PrintStream print; - - private final HtmlOutputStream out; - private final boolean error; - - DualOutputStream(HtmlOutputStream out, PrintStream print, boolean error) { - super(out); - this.out = out; - this.print = print; - this.error = error; - } - - public void close() throws IOException { - print.close(); - super.close(); - } - - public void flush() throws IOException { - print.flush(); - super.flush(); - } - - public void write(int b) throws IOException { - print.write(b); - out.write(error, b); - } - } - - /** - * An output stream that has two modes: error mode and regular mode. - */ - static class HtmlOutputStream extends FilterOutputStream { - - private static final byte[] START = START_ERROR.getBytes(); - private static final byte[] END = "
    ".getBytes(); - private static final byte[] BR = "
    \n".getBytes(); - private static final byte[] NBSP = " ".getBytes(); - private static final byte[] LT = "<".getBytes(); - private static final byte[] GT = ">".getBytes(); - private static final byte[] AMP = "&".getBytes(); - private boolean error; - private boolean hasError; - private boolean convertSpace; - - HtmlOutputStream(OutputStream out) { - super(out); - } - - /** - * Check if the error mode was used. - * - * @return true if it was - */ - boolean hasError() { - return hasError; - } - - /** - * Enable or disable the error mode. - * - * @param error the flag - */ - void setError(boolean error) throws IOException { - if (error != this.error) { - if (error) { - hasError = true; - super.write(START); - } else { - super.write(END); - } - this.error = error; - } - } - - /** - * Write a character. - * - * @param errorStream if the character comes from the error stream - * @param b the character - */ - void write(boolean errorStream, int b) throws IOException { - setError(errorStream); - switch (b) { - case '\n': - super.write(BR); - convertSpace = true; - break; - case '\t': - super.write(NBSP); - super.write(NBSP); - break; - case ' ': - if (convertSpace) { - super.write(NBSP); - } else { - super.write(b); - } - break; - case '<': - super.write(LT); - break; - case '>': - super.write(GT); - break; - case '&': - super.write(AMP); - break; - default: - if (b >= 128) { - super.write(("&#" + b + ";").getBytes()); - } else { - super.write(b); - } - convertSpace = false; - } - } - - } - -} diff --git a/tools/h2/src/test/org/h2/test/utils/Recorder.java b/tools/h2/src/test/org/h2/test/utils/Recorder.java deleted file mode 100755 index d3f4715..0000000 --- a/tools/h2/src/test/org/h2/test/utils/Recorder.java +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.test.utils; - -/** - * A recorder for the recording file system. - */ -public interface Recorder { - - /** - * Copy a file. The file name contains the source and the target file - * separated with a colon. - */ - int COPY = 3; - - /** - * Create all parent directories. - */ - int CREATE_DIRS = 4; - - /** - * Create a new file. - */ - int CREATE_NEW_FILE = 5; - - /** - * Create a temporary file. - */ - int CREATE_TEMP_FILE = 6; - - /** - * Delete a file. - */ - int DELETE = 7; - - /** - * Delete all files and directories recursively. - */ - int DELETE_RECURSIVE = 8; - - /** - * Open a file output stream. - */ - int OPEN_OUTPUT_STREAM = 9; - - /** - * Rename a file. The file name contains the source and the target file - * separated with a colon. - */ - int RENAME = 10; - - /** - * Set the length of the file. - */ - int SET_LENGTH = 1; - - /** - * Try to delete the file. - */ - int TRY_DELETE = 2; - - /** - * Write to the file. - */ - int WRITE = 0; - - /** - * Record the method. - * - * @param op the operation - * @param fileName the file name or file name list - * @param data the data or null - * @param x the value or 0 - */ - void log(int op, String fileName, byte[] data, long x); - -} diff --git a/tools/h2/src/test/org/h2/test/utils/RecordingFileObject.java b/tools/h2/src/test/org/h2/test/utils/RecordingFileObject.java deleted file mode 100755 index 93fd517..0000000 --- a/tools/h2/src/test/org/h2/test/utils/RecordingFileObject.java +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.test.utils; - -import java.io.IOException; -import org.h2.store.fs.FileObject; - -/** - * A file object that records all write operations and can re-play them. - */ -public class RecordingFileObject implements FileObject { - - private final RecordingFileSystem fs; - private final FileObject file; - private final String name; - - RecordingFileObject(RecordingFileSystem fs, FileObject file) { - this.fs = fs; - this.file = file; - this.name = file.getName(); - } - - public void close() throws IOException { - file.close(); - } - - public long getFilePointer() throws IOException { - return file.getFilePointer(); - } - - public String getName() { - return RecordingFileSystem.PREFIX + name; - } - - public long length() throws IOException { - return file.length(); - } - - public void readFully(byte[] b, int off, int len) throws IOException { - file.readFully(b, off, len); - } - - public void seek(long pos) throws IOException { - file.seek(pos); - } - - public void setFileLength(long newLength) throws IOException { - fs.log(Recorder.SET_LENGTH, name, null, newLength); - file.setFileLength(newLength); - } - - public void sync() throws IOException { - file.sync(); - } - - public void write(byte[] b, int off, int len) throws IOException { - byte[] buff = b; - if (off != 0 || len != b.length) { - buff = new byte[len]; - System.arraycopy(b, off, buff, 0, len); - } - file.write(b, off, len); - fs.log(Recorder.WRITE, name, buff, file.getFilePointer()); - } - -} diff --git a/tools/h2/src/test/org/h2/test/utils/RecordingFileSystem.java b/tools/h2/src/test/org/h2/test/utils/RecordingFileSystem.java deleted file mode 100755 index 2c5e899..0000000 --- a/tools/h2/src/test/org/h2/test/utils/RecordingFileSystem.java +++ /dev/null @@ -1,233 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.test.utils; - -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import org.h2.message.DbException; -import org.h2.store.fs.FileObject; -import org.h2.store.fs.FileSystem; - -/** - * A file system that records all write operations and can re-play them. - */ -public class RecordingFileSystem extends FileSystem { - - /** - * The prefix used for a debugging file system. - */ - public static final String PREFIX = "rec:"; - - private static final RecordingFileSystem INSTANCE = new RecordingFileSystem(); - - private static Recorder recorder; - - private boolean trace; - - /** - * Register the file system. - */ - public static void register() { - FileSystem.register(INSTANCE); - } - - /** - * Set the recorder class. - * - * @param recorder the recorder - */ - public static void setRecorder(Recorder recorder) { - RecordingFileSystem.recorder = recorder; - } - - public boolean canWrite(String fileName) { - fileName = translateFileName(fileName); - return FileSystem.getInstance(fileName).canWrite(fileName); - } - - public void copy(String original, String copy) { - original = translateFileName(original); - copy = translateFileName(copy); - log(Recorder.COPY, original + ":" + copy); - FileSystem.getInstance(original).copy(original, copy); - } - - public void createDirs(String fileName) { - fileName = translateFileName(fileName); - log(Recorder.CREATE_DIRS, fileName); - FileSystem.getInstance(fileName).createDirs(fileName); - } - - public boolean createNewFile(String fileName) { - fileName = translateFileName(fileName); - log(Recorder.CREATE_NEW_FILE, fileName); - return FileSystem.getInstance(fileName).createNewFile(fileName); - } - - public String createTempFile(String prefix, String suffix, boolean deleteOnExit, boolean inTempDir) - throws IOException { - prefix = translateFileName(prefix); - log(Recorder.CREATE_TEMP_FILE, prefix + ":" + suffix + ":" + deleteOnExit + ":" + inTempDir); - return PREFIX + FileSystem.getInstance(prefix).createTempFile(prefix, suffix, deleteOnExit, inTempDir); - } - - public void delete(String fileName) { - fileName = translateFileName(fileName); - log(Recorder.DELETE, fileName); - FileSystem.getInstance(fileName).delete(fileName); - } - - public void deleteRecursive(String directory, boolean tryOnly) { - directory = translateFileName(directory); - log(Recorder.DELETE_RECURSIVE, directory); - FileSystem.getInstance(directory).deleteRecursive(directory, tryOnly); - } - - public boolean exists(String fileName) { - fileName = translateFileName(fileName); - return FileSystem.getInstance(fileName).exists(fileName); - } - - public boolean fileStartsWith(String fileName, String prefix) { - fileName = translateFileName(fileName); - prefix = translateFileName(prefix); - return FileSystem.getInstance(fileName).fileStartsWith(fileName, prefix); - } - - public String getAbsolutePath(String fileName) { - fileName = translateFileName(fileName); - return PREFIX + FileSystem.getInstance(fileName).getAbsolutePath(fileName); - } - - public String getFileName(String name) { - name = translateFileName(name); - return FileSystem.getInstance(name).getFileName(name); - } - - public long getLastModified(String fileName) { - fileName = translateFileName(fileName); - return FileSystem.getInstance(fileName).getLastModified(fileName); - } - - public String getParent(String fileName) { - fileName = translateFileName(fileName); - return PREFIX + FileSystem.getInstance(fileName).getParent(fileName); - } - - public boolean isAbsolute(String fileName) { - fileName = translateFileName(fileName); - return FileSystem.getInstance(fileName).isAbsolute(fileName); - } - - public boolean isDirectory(String fileName) { - fileName = translateFileName(fileName); - return FileSystem.getInstance(fileName).isDirectory(fileName); - } - - public boolean isReadOnly(String fileName) { - fileName = translateFileName(fileName); - return FileSystem.getInstance(fileName).isReadOnly(fileName); - } - - public boolean setReadOnly(String fileName) { - fileName = translateFileName(fileName); - return FileSystem.getInstance(fileName).setReadOnly(fileName); - } - - public long length(String fileName) { - fileName = translateFileName(fileName); - return FileSystem.getInstance(fileName).length(fileName); - } - - public String[] listFiles(String directory) { - directory = translateFileName(directory); - String[] list = FileSystem.getInstance(directory).listFiles(directory); - for (int i = 0; i < list.length; i++) { - list[i] = PREFIX + list[i]; - } - return list; - } - - public String normalize(String fileName) { - fileName = translateFileName(fileName); - return PREFIX + FileSystem.getInstance(fileName).normalize(fileName); - } - - public InputStream openFileInputStream(String fileName) throws IOException { - fileName = translateFileName(fileName); - return FileSystem.getInstance(fileName).openFileInputStream(fileName); - } - - public FileObject openFileObject(String fileName, String mode) throws IOException { - fileName = translateFileName(fileName); - return new RecordingFileObject(this, FileSystem.getInstance(fileName).openFileObject(fileName, mode)); - } - - public OutputStream openFileOutputStream(String fileName, boolean append) { - fileName = translateFileName(fileName); - log(Recorder.OPEN_OUTPUT_STREAM, fileName); - return FileSystem.getInstance(fileName).openFileOutputStream(fileName, append); - } - - public void rename(String oldName, String newName) { - oldName = translateFileName(oldName); - newName = translateFileName(newName); - log(Recorder.RENAME, oldName + ":" + newName); - FileSystem.getInstance(oldName).rename(oldName, newName); - } - - public boolean tryDelete(String fileName) { - fileName = translateFileName(fileName); - log(Recorder.TRY_DELETE, fileName); - return FileSystem.getInstance(fileName).tryDelete(fileName); - } - - protected boolean accepts(String fileName) { - return fileName.startsWith(PREFIX); - } - - private String translateFileName(String fileName) { - if (!fileName.startsWith(PREFIX)) { - DbException.throwInternalError(fileName + " doesn't start with " + PREFIX); - } - return fileName.substring(PREFIX.length()); - } - - public boolean isTrace() { - return trace; - } - - public void setTrace(boolean trace) { - this.trace = trace; - } - - /** - * Log the operation. - * - * @param op the operation - * @param fileName the file name - */ - void log(int op, String fileName) { - log(op, fileName, null, 0); - } - - /** - * Log the operation. - * - * @param op the operation - * @param fileName the file name - * @param data the data or null - * @param x the value or 0 - */ - void log(int op, String fileName, byte[] data, long x) { - if (recorder != null) { - recorder.log(op, fileName, data, x); - } - } - -} diff --git a/tools/h2/src/test/org/h2/test/utils/SelfDestructor.java b/tools/h2/src/test/org/h2/test/utils/SelfDestructor.java deleted file mode 100755 index 03b156a..0000000 --- a/tools/h2/src/test/org/h2/test/utils/SelfDestructor.java +++ /dev/null @@ -1,109 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.test.utils; - -import java.lang.reflect.Method; -import java.sql.Timestamp; -import java.util.Map; - -/** - * This is a self-destructor class to kill a long running process automatically - * after a pre-defined time. The class reads the number of minutes from the - * system property 'h2.selfDestruct' and starts a countdown thread to kill the - * virtual machine if it still runs then. - */ -public class SelfDestructor extends Thread { - private static final String PROPERTY_NAME = "h2.selfDestruct"; - - /** - * Start the countdown. If the self-destruct system property is set, this - * value is used, otherwise the given default value is used. - * - * @param defaultMinutes the default number of minutes after which the - * current process is killed. - */ - public static void startCountdown(int defaultMinutes) { - final int minutes = Integer.parseInt(System.getProperty(PROPERTY_NAME, "" + defaultMinutes)); - if (minutes != 0) { - Thread thread = new Thread() { - public void run() { - for (int i = minutes; i >= 0; i--) { - while (true) { - try { - String name = "SelfDestructor " + i + " min"; - setName(name); - break; - } catch (OutOfMemoryError e) { - // ignore - } - } - try { - Thread.sleep(60 * 1000); - } catch (InterruptedException e) { - // ignore - } - } - String time = new Timestamp(System.currentTimeMillis()).toString(); - System.out.println(time + " Killing the process after " + minutes + " minute(s)"); - try { - Map map = Thread.getAllStackTraces(); - for (Map.Entry en : map.entrySet()) { - System.out.println(en.getKey()); - for (StackTraceElement el : en.getValue()) { - System.out.println(" " + el); - } - } - System.out.println(); - System.out.flush(); - try { - Thread.sleep(1000); - } catch (Exception e) { - // ignore - } - int activeCount = Thread.activeCount(); - Thread[] threads = new Thread[activeCount + 100]; - int len = Thread.enumerate(threads); - Method stop = Thread.class.getMethod("stop", Throwable.class); - for (int i = 0; i < len; i++) { - Thread t = threads[i]; - String threadName = "Thread #" + i + ": " + t.getName(); - Error e = new Error(threadName); - if (t != Thread.currentThread()) { - stop.invoke(t, e); - t.interrupt(); - } - } - } catch (Throwable t) { - t.printStackTrace(); - // ignore - } - try { - Thread.sleep(1000); - } catch (Exception e) { - // ignore - } - System.out.println("Killing the process now"); - - Runtime.getRuntime().halt(1); - } - }; - thread.setDaemon(true); - thread.start(); - } - } - - /** - * Get the string to be added when starting the Java process. - * - * @param minutes the countdown time in minutes - * @return the setting - */ - public static String getPropertyString(int minutes) { - return "-D" + PROPERTY_NAME + "=" + minutes; - } - -} diff --git a/tools/h2/src/test/org/h2/test/utils/package.html b/tools/h2/src/test/org/h2/test/utils/package.html deleted file mode 100755 index 7008cac..0000000 --- a/tools/h2/src/test/org/h2/test/utils/package.html +++ /dev/null @@ -1,15 +0,0 @@ - - - - -Javadoc package documentation -

    - -Utility classes used by the tests. - -

    \ No newline at end of file diff --git a/tools/h2/src/tools/WEB-INF/console.html b/tools/h2/src/tools/WEB-INF/console.html deleted file mode 100755 index 9929255..0000000 --- a/tools/h2/src/tools/WEB-INF/console.html +++ /dev/null @@ -1,17 +0,0 @@ - - - - - H2 Console - - - - H2 Console - - diff --git a/tools/h2/src/tools/WEB-INF/web.xml b/tools/h2/src/tools/WEB-INF/web.xml deleted file mode 100755 index 3eae42a..0000000 --- a/tools/h2/src/tools/WEB-INF/web.xml +++ /dev/null @@ -1,69 +0,0 @@ - - - - - H2 Console Web Application - - A web application that includes the H2 Console servlet. - - - - H2Console - org.h2.server.web.WebServlet - - 1 - - - - H2Console - /console/* - - - - /console.html - - - - - - - diff --git a/tools/h2/src/tools/com/caucho/jdbc/H2MetaData.java.txt b/tools/h2/src/tools/com/caucho/jdbc/H2MetaData.java.txt deleted file mode 100755 index 4eb2166..0000000 --- a/tools/h2/src/tools/com/caucho/jdbc/H2MetaData.java.txt +++ /dev/null @@ -1,47 +0,0 @@ -package com.caucho.jdbc; - -import com.caucho.util.Log; - -import javax.sql.DataSource; -import java.util.logging.Logger; - -/** - * Metadata for the H2 database. - * For details, see - * http://wondering.ru/java/H2ejb3onResinSupport1.0.zip - */ -public class H2MetaData extends JdbcMetaData { - private static final Logger log = Log.open(H2MetaData.class); - - protected H2MetaData(DataSource ds) { - super(ds); - } - - /** - * Returns the blob type. - */ - public String getBlobType(){ - return "BLOB"; - } - - /** - * Returns the long type. - */ - public String getLongType() { - return "BIGINT"; - } - - /** - * Returns true if identity is supported. - */ - public boolean supportsIdentity() { - return true; - } - - /** - * Returns the identity property - */ - public String createIdentitySQL(String sqlType) { - return "IDENTITY"; - } -} diff --git a/tools/h2/src/tools/com/caucho/jdbc/JdbcMetaData.java.txt b/tools/h2/src/tools/com/caucho/jdbc/JdbcMetaData.java.txt deleted file mode 100755 index 80d6972..0000000 --- a/tools/h2/src/tools/com/caucho/jdbc/JdbcMetaData.java.txt +++ /dev/null @@ -1,15 +0,0 @@ -Sorry I can not include this file because -http://ohloh.org says that this may conflict -with another license. - -In the file JdbcMetaData.java in package com.caucho.jdbc -in method public static JdbcMetaData create(DataSource ds), -you need to add - - if ("H2".equalsIgnoreCase(name)) - return new H2MetaData(ds); - else - -just before - - if ("oracle".equalsIgnoreCase(name)) diff --git a/tools/h2/src/tools/net/java/ao/db/H2DatabaseProvider.java.txt b/tools/h2/src/tools/net/java/ao/db/H2DatabaseProvider.java.txt deleted file mode 100755 index b37335a..0000000 --- a/tools/h2/src/tools/net/java/ao/db/H2DatabaseProvider.java.txt +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: Michael Manske - */ -package net.java.ao.db; - -import java.sql.Driver; - -/** - * This is a database provider for ActiveObjects. - * See also https://activeobjects.dev.java.net . - * Usage: - *
    - * EntityManager manager = new EntityManager(new H2DatabaseProvider(
    - *      dbProperties.getProperty("db.uri"),
    - *      dbProperties.getProperty("db.username"),
    - *      dbProperties.getProperty("db.password")));
    - * 
    - * - * @author Michael Manske - * @author Thomas Mueller - */ -public class H2DatabaseProvider extends HSQLDatabaseProvider { - - /** - * Create a new provider. - * - * @param uri the database uri - * @param username the user name - * @param password the password - */ - public H2DatabaseProvider(String uri, String username, String password) { - super(uri, username, password); - } - - public Class< ? extends Driver> getDriverClass() throws ClassNotFoundException { - return (Class< ? extends Driver>) Class.forName("org.h2.Driver"); - } - -} diff --git a/tools/h2/src/tools/oracle/toplink/essentials/platform/database/H2Platform.java.txt b/tools/h2/src/tools/oracle/toplink/essentials/platform/database/H2Platform.java.txt deleted file mode 100755 index 8f42f65..0000000 --- a/tools/h2/src/tools/oracle/toplink/essentials/platform/database/H2Platform.java.txt +++ /dev/null @@ -1,142 +0,0 @@ -/* - * The contents of this file are subject to the terms - * of the Common Development and Distribution License - * (the "License"). You may not use this file except - * in compliance with the License. - * - * You can obtain a copy of the license at - * glassfish/bootstrap/legal/CDDLv1.0.txt or - * https://glassfish.dev.java.net/public/CDDLv1.0.html. - * See the License for the specific language governing - * permissions and limitations under the License. - * - * When distributing Covered Code, include this CDDL - * HEADER in each file and include the License file at - * glassfish/bootstrap/legal/CDDLv1.0.txt. If applicable, - * add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your - * own identifying information: Portions Copyright [yyyy] - * [name of copyright owner] - */ -// Copyright (c) 1998, 2006, Oracle. All rights reserved. -package oracle.toplink.essentials.platform.database; - -import java.io.IOException; -import java.io.Writer; -import java.util.Hashtable; - -import oracle.toplink.essentials.exceptions.ValidationException; -import oracle.toplink.essentials.expressions.ExpressionOperator; -import oracle.toplink.essentials.internal.databaseaccess.FieldTypeDefinition; -import oracle.toplink.essentials.queryframework.ValueReadQuery; - -/** - * This platform provides H2 specific behaviour. - * To enable this platform change the following setting in persistence.xml: - *
    - * <property
    - *   name="toplink.target-database"
    - *   value="oracle.toplink.essentials.platform.database.H2Platform"/>
    - * 
    - * In old versions of Glassfish, the property name is - * toplink.platform.class.name. - * See also: https://glassfish.dev.java.net/issues/show_bug.cgi?id=4042 - * - * @author Thomas Mueller - * @author Marcio Borges (http://www.marciowb.net/blog/2008_08_01_) - */ -public class H2Platform extends DatabasePlatform { - - protected Hashtable buildFieldTypes() { - Hashtable fieldTypeMapping; - fieldTypeMapping = super.buildFieldTypes(); - fieldTypeMapping.put(Boolean.class, new FieldTypeDefinition("TINYINT", false)); - fieldTypeMapping.put(Integer.class, new FieldTypeDefinition("INTEGER", false)); - fieldTypeMapping.put(Long.class, new FieldTypeDefinition("NUMERIC", 19)); - fieldTypeMapping.put(Float.class, new FieldTypeDefinition("REAL", false)); - fieldTypeMapping.put(Double.class, new FieldTypeDefinition("REAL", false)); - fieldTypeMapping.put(Short.class, new FieldTypeDefinition("SMALLINT", false)); - fieldTypeMapping.put(Byte.class, new FieldTypeDefinition("SMALLINT", false)); - fieldTypeMapping.put(java.math.BigInteger.class, new FieldTypeDefinition("NUMERIC", 38)); - fieldTypeMapping.put(java.math.BigDecimal.class, new FieldTypeDefinition("NUMERIC", 38).setLimits(38, -19, 19)); - fieldTypeMapping.put(Number.class, new FieldTypeDefinition("NUMERIC", 38).setLimits(38, -19, 19)); - fieldTypeMapping.put(Byte[].class, new FieldTypeDefinition("BINARY", false)); - fieldTypeMapping.put(Character[].class, new FieldTypeDefinition("LONGVARCHAR", false)); - fieldTypeMapping.put(byte[].class, new FieldTypeDefinition("BINARY", false)); - fieldTypeMapping.put(char[].class, new FieldTypeDefinition("LONGVARCHAR", false)); - fieldTypeMapping.put(java.sql.Blob.class, new FieldTypeDefinition("BINARY", false)); - fieldTypeMapping.put(java.sql.Clob.class, new FieldTypeDefinition("LONGVARCHAR", false)); - fieldTypeMapping.put(java.sql.Date.class, new FieldTypeDefinition("DATE", false)); - fieldTypeMapping.put(java.sql.Time.class, new FieldTypeDefinition("TIME", false)); - fieldTypeMapping.put(java.sql.Timestamp.class, new FieldTypeDefinition("TIMESTAMP", false)); - return fieldTypeMapping; - } - - public boolean isH2() { - return true; - } - - public boolean supportsForeignKeyConstraints() { - return true; - } - - public ValueReadQuery buildSelectQueryForNativeSequence(String seqName, Integer size) { - StringBuffer buff = new StringBuffer(); - buff.append("SELECT MAX(NEXT VALUE FOR "); - buff.append(getQualifiedSequenceName(seqName)); - buff.append(") FROM SYSTEM_RANGE(1, "); - buff.append(size); - buff.append(")"); - String sql = buff.toString(); - return new ValueReadQuery(sql); - } - - public boolean supportsNativeSequenceNumbers() { - return true; - } - - protected String getQualifiedSequenceName(String seqName) { - if (getTableQualifier().equals("")) { - return seqName; - } - return getTableQualifier() + "." + seqName; - } - - public boolean supportsSelectForUpdateNoWait() { - return true; - } - - protected ExpressionOperator todayOperator() { - return ExpressionOperator.simpleFunctionNoParentheses(ExpressionOperator.Today, "SYSDATE"); - } - - protected void initializePlatformOperators() { - super.initializePlatformOperators(); - addOperator(ExpressionOperator.simpleMath(ExpressionOperator.Concat, "||")); - } - - public boolean shouldUseJDBCOuterJoinSyntax() { - return false; - } - - public boolean supportsSequenceObjects() { - return true; - } - - public boolean supportsIdentity() { - return true; - } - - public ValueReadQuery buildSelectQueryForIdentity() { - return new ValueReadQuery("SELECT IDENTITY()"); - } - - public void printFieldIdentityClause(Writer writer) throws ValidationException { - try { - writer.write(" IDENTITY"); - } catch (final IOException ioException) { - throw ValidationException.fileError(ioException); - } - } - -} diff --git a/tools/h2/src/tools/org/apache/openjpa/jdbc/sql/H2Dictionary.java.txt b/tools/h2/src/tools/org/apache/openjpa/jdbc/sql/H2Dictionary.java.txt deleted file mode 100755 index 34c87f0..0000000 --- a/tools/h2/src/tools/org/apache/openjpa/jdbc/sql/H2Dictionary.java.txt +++ /dev/null @@ -1,202 +0,0 @@ -package org.apache.openjpa.jdbc.sql; - -import java.math.BigDecimal; -import java.sql.Connection; -import java.sql.DatabaseMetaData; -import java.sql.PreparedStatement; -import java.sql.SQLException; -import java.sql.Types; -import java.util.Arrays; -import java.util.Locale; - -import org.apache.commons.lang.StringUtils; -import org.apache.openjpa.jdbc.kernel.exps.FilterValue; -import org.apache.openjpa.jdbc.schema.Column; -import org.apache.openjpa.jdbc.schema.PrimaryKey; -import org.apache.openjpa.jdbc.schema.Table; -import org.apache.openjpa.jdbc.schema.Unique; -import org.apache.openjpa.meta.JavaTypes; - -public class H2Dictionary extends DBDictionary { - - public H2Dictionary() { - platform = "H2"; - validationSQL = "CALL 1"; - closePoolSQL = "SHUTDOWN"; - - supportsAutoAssign = true; - lastGeneratedKeyQuery = "CALL IDENTITY()"; - autoAssignClause = "IDENTITY"; - autoAssignTypeName = "INTEGER"; - nextSequenceQuery = "CALL NEXT VALUE FOR {0}"; - - crossJoinClause = "CROSS JOIN"; - requiresConditionForCrossJoin = false; - stringLengthFunction = "LENGTH({0})"; - trimLeadingFunction = "LTRIM({0})"; - trimTrailingFunction = "RTRIM({0})"; - trimBothFunction = "TRIM({0})"; - - useSchemaName = true; - supportsSelectForUpdate = true; - supportsSelectStartIndex = true; - supportsSelectEndIndex = true; - rangePosition = RANGE_POST_LOCK; - supportsDeferredConstraints = false; - - blobTypeName = "BLOB"; - doubleTypeName = "DOUBLE"; - - supportsNullTableForGetPrimaryKeys = true; - supportsNullTableForGetIndexInfo = true; - - requiresCastForMathFunctions = false; - requiresCastForComparisons = false; - - reservedWordSet.addAll(Arrays.asList(new String[] { "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" })); - } - - public int getJDBCType(int metaTypeCode, boolean lob) { - int type = super.getJDBCType(metaTypeCode, lob); - switch (type) { - case Types.BIGINT: - if (metaTypeCode == JavaTypes.BIGINTEGER) - return Types.NUMERIC; - break; - } - return type; - } - - public int getPreferredType(int type) { - return super.getPreferredType(type); - } - - public String[] getAddPrimaryKeySQL(PrimaryKey pk) { - return new String[0]; - } - - public String[] getDropPrimaryKeySQL(PrimaryKey pk) { - return new String[0]; - } - - public String[] getAddColumnSQL(Column column) { - return new String[] { "ALTER TABLE " + getFullName(column.getTable(), false) + " ADD COLUMN " + getDeclareColumnSQL(column, true) }; - } - - public String[] getCreateTableSQL(Table table) { - StringBuffer buf = new StringBuffer(); - buf.append("CREATE TABLE ").append(getFullName(table, false)).append(" ("); - - Column[] cols = table.getColumns(); - for (int i = 0; i < cols.length; i++) { - if (i > 0) - buf.append(", "); - buf.append(getDeclareColumnSQL(cols[i], false)); - } - - PrimaryKey pk = table.getPrimaryKey(); - String pkStr; - if (pk != null) { - pkStr = getPrimaryKeyConstraintSQL(pk); - if (!StringUtils.isEmpty(pkStr)) - buf.append(", ").append(pkStr); - } - - Unique[] uniques = table.getUniques(); - String uniqueStr; - for (int i = 0; i < uniques.length; i++) { - uniqueStr = getUniqueConstraintSQL(uniques[i]); - if (uniqueStr != null) - buf.append(", ").append(uniqueStr); - } - - buf.append(")"); - return new String[] { buf.toString() }; - } - - protected String getPrimaryKeyConstraintSQL(PrimaryKey pk) { - Column[] cols = pk.getColumns(); - if (cols.length == 1 && cols[0].isAutoAssigned()) - return null; - return super.getPrimaryKeyConstraintSQL(pk); - } - - public boolean isSystemIndex(String name, Table table) { - return name.toUpperCase(Locale.ENGLISH).startsWith("SYSTEM_"); - } - - protected String getSequencesSQL(String schemaName, String sequenceName) { - StringBuffer buf = new StringBuffer(); - buf.append("SELECT SEQUENCE_SCHEMA, SEQUENCE_NAME FROM ").append("INFORMATION_SCHEMA.SEQUENCES"); - if (schemaName != null || sequenceName != null) - buf.append(" WHERE "); - if (schemaName != null) { - buf.append("SEQUENCE_SCHEMA = ?"); - if (sequenceName != null) - buf.append(" AND "); - } - if (sequenceName != null) - buf.append("SEQUENCE_NAME = ?"); - return buf.toString(); - } - - protected SQLBuffer toOperation(String op, SQLBuffer selects, SQLBuffer from, SQLBuffer where, SQLBuffer group, SQLBuffer having, SQLBuffer order, boolean distinct, - boolean forUpdate, long start, long end) { - return super.toOperation(op, selects, from, where, group, having, order, distinct, forUpdate, start, end); - } - - public Column[] getColumns(DatabaseMetaData meta, String catalog, String schemaName, String tableName, String columnName, Connection conn) throws SQLException { - Column[] cols = super.getColumns(meta, catalog, schemaName, tableName, columnName, conn); - return cols; - } - - public void setDouble(PreparedStatement stat, int idx, double val, Column col) throws SQLException { - super.setDouble(stat, idx, val, col); - } - - public void setBigDecimal(PreparedStatement stat, int idx, BigDecimal val, Column col) throws SQLException { - super.setBigDecimal(stat, idx, val, col); - } - - protected void appendSelectRange(SQLBuffer buf, long start, long end) { - if (end != Long.MAX_VALUE) - buf.append(" LIMIT ").appendValue(end - start); - if (start != 0) - buf.append(" OFFSET ").appendValue(start); - } - - public void substring(SQLBuffer buf, FilterValue str, FilterValue start, FilterValue end) { - buf.append("SUBSTR("); - str.appendTo(buf); - buf.append(", ("); - start.appendTo(buf); - buf.append(" + 1)"); - if (end != null) { - buf.append(", ("); - end.appendTo(buf); - buf.append(" - "); - start.appendTo(buf); - buf.append(")"); - } - buf.append(")"); - } - - public void indexOf(SQLBuffer buf, FilterValue str, FilterValue find, FilterValue start) { - buf.append("(POSITION("); - find.appendTo(buf); - buf.append(" IN "); - if (start != null) - substring(buf, str, start, null); - else - str.appendTo(buf); - buf.append(") - 1"); - if (start != null) { - buf.append(" + "); - start.appendTo(buf); - } - buf.append(")"); - } - -} diff --git a/tools/h2/src/tools/org/h2/dev/ftp/FtpClient.java b/tools/h2/src/tools/org/h2/dev/ftp/FtpClient.java deleted file mode 100755 index 267dc07..0000000 --- a/tools/h2/src/tools/org/h2/dev/ftp/FtpClient.java +++ /dev/null @@ -1,466 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.dev.ftp; - -import java.io.BufferedReader; -import java.io.ByteArrayOutputStream; -import java.io.File; -import java.io.FileInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.io.OutputStream; -import java.io.OutputStreamWriter; -import java.io.PrintWriter; -import java.net.InetAddress; -import java.net.Socket; - -import org.h2.engine.Constants; -import org.h2.util.IOUtils; -import org.h2.util.NetUtils; -import org.h2.util.StatementBuilder; -import org.h2.util.StringUtils; - -/** - * A simple standalone FTP client. - */ -public class FtpClient { - private Socket socket; - private BufferedReader reader; - private PrintWriter writer; - private int code; - private String message; - private Socket socketData; - private InputStream inData; - private OutputStream outData; - - private FtpClient() { - // don't allow construction - } - - /** - * Open an FTP connection. - * - * @param url the FTP URL - * @return the ftp client object - */ - public static FtpClient open(String url) throws IOException { - FtpClient client = new FtpClient(); - client.connect(url); - return client; - } - - private void connect(String url) throws IOException { - socket = NetUtils.createSocket(url, 21, false); - InputStream in = socket.getInputStream(); - OutputStream out = socket.getOutputStream(); - reader = new BufferedReader(new InputStreamReader(in)); - writer = new PrintWriter(new OutputStreamWriter(out, Constants.UTF8)); - readCode(220); - } - - private void readLine() throws IOException { - while (true) { - message = reader.readLine(); - if (message != null) { - int idxSpace = message.indexOf(' '); - int idxMinus = message.indexOf('-'); - int idx = idxSpace < 0 ? idxMinus : idxMinus < 0 ? idxSpace : Math.min(idxSpace, idxMinus); - if (idx < 0) { - code = 0; - } else { - code = Integer.parseInt(message.substring(0, idx)); - message = message.substring(idx + 1); - } - } - break; - } - } - - private void readCode(int optional, int expected) throws IOException { - readLine(); - if (code == optional) { - readLine(); - } - if (code != expected) { - throw new IOException("Expected: " + expected + " got: " + code + " " + message); - } - } - - private void readCode(int expected) throws IOException { - readCode(-1, expected); - } - - private void send(String command) { - writer.println(command); - writer.flush(); - } - - /** - * Login to this FTP server (USER, PASS, SYST, SITE, STRU F, TYPE I). - * - * @param userName the user name - * @param password the password - */ - public void login(String userName, String password) throws IOException { - send("USER " + userName); - readCode(331); - send("PASS " + password); - readCode(230); - send("SYST"); - readCode(215); - send("SITE"); - readCode(500); - send("STRU F"); - readCode(200); - send("TYPE I"); - readCode(200); - } - - /** - * Close the connection (QUIT). - */ - public void close() throws IOException { - if (socket != null) { - send("QUIT"); - readCode(221); - socket.close(); - } - } - - /** - * Change the working directory (CWD). - * - * @param dir the new directory - */ - public void changeWorkingDirectory(String dir) throws IOException { - send("CWD " + dir); - readCode(250); - } - - /** - * Change to the parent directory (CDUP). - */ - public void changeDirectoryUp() throws IOException { - send("CDUP"); - readCode(250); - } - - /** - * Delete a file (DELE). - * - * @param fileName the name of the file to delete - */ - void delete(String fileName) throws IOException { - send("DELE " + fileName); - readCode(226, 250); - } - - /** - * Create a directory (MKD). - * - * @param dir the directory to create - */ - public void makeDirectory(String dir) throws IOException { - send("MKD " + dir); - readCode(226, 257); - } - - /** - * Change the transfer mode (MODE). - * - * @param mode the mode - */ - void mode(String mode) throws IOException { - send("MODE " + mode); - readCode(200); - } - - /** - * Change the modified time of a file (MDTM). - * - * @param fileName the file name - */ - void modificationTime(String fileName) throws IOException { - send("MDTM " + fileName); - readCode(213); - } - - /** - * Issue a no-operation statement (NOOP). - */ - void noOperation() throws IOException { - send("NOOP"); - readCode(200); - } - - /** - * Print the working directory (PWD). - * - * @return the working directory - */ - String printWorkingDirectory() throws IOException { - send("PWD"); - readCode(257); - return removeQuotes(); - } - - private String removeQuotes() { - int first = message.indexOf('"') + 1; - int last = message.lastIndexOf('"'); - StringBuilder buff = new StringBuilder(); - for (int i = first; i < last; i++) { - char ch = message.charAt(i); - buff.append(ch); - if (ch == '\"') { - i++; - } - } - return buff.toString(); - } - - private void passive() throws IOException { - send("PASV"); - readCode(226, 227); - int first = message.indexOf('(') + 1; - int last = message.indexOf(')'); - String[] address = StringUtils.arraySplit(message.substring(first, last), ',', true); - StatementBuilder buff = new StatementBuilder(); - for (int i = 0; i < 4; i++) { - buff.appendExceptFirst("."); - buff.append(address[i]); - } - String ip = buff.toString(); - InetAddress addr = InetAddress.getByName(ip); - int port = (Integer.parseInt(address[4]) << 8) | Integer.parseInt(address[5]); - socketData = NetUtils.createSocket(addr, port, false); - inData = socketData.getInputStream(); - outData = socketData.getOutputStream(); - } - - /** - * Rename a file (RNFR / RNTO). - * - * @param fromFileName the old file name - * @param toFileName the new file name - */ - void rename(String fromFileName, String toFileName) throws IOException { - send("RNFR " + fromFileName); - readCode(350); - send("RNTO " + toFileName); - readCode(250); - } - - /** - * Read a file. - * - * @param fileName the file name - * @return the content, null if the file doesn't exist - */ - public byte[] retrieve(String fileName) throws IOException { - ByteArrayOutputStream buff = new ByteArrayOutputStream(); - retrieve(fileName, buff, 0); - return buff.toByteArray(); - } - - /** - * Read a file ([REST] RETR). - * - * @param fileName the file name - * @param out the output stream - * @param restartAt restart at the given position (0 if no restart is required). - */ - void retrieve(String fileName, OutputStream out, long restartAt) throws IOException { - passive(); - if (restartAt > 0) { - send("REST " + restartAt); - readCode(350); - } - send("RETR " + fileName); - IOUtils.copyAndClose(inData, out); - readCode(150, 226); - } - - /** - * Remove a directory (RMD). - * - * @param dir the directory to remove - */ - public void removeDirectory(String dir) throws IOException { - send("RMD " + dir); - readCode(226, 250); - } - - /** - * Remove all files and directory in a directory, and then delete the - * directory itself. - * - * @param dir the directory to remove - */ - public void removeDirectoryRecursive(String dir) throws IOException { - for (File f : listFiles(dir)) { - if (f.isDirectory()) { - removeDirectoryRecursive(dir + "/" + f.getName()); - } else { - delete(dir + "/" + f.getName()); - } - } - removeDirectory(dir); - } - - /** - * Get the size of a file (SIZE). - * - * @param fileName the file name - * @return the size - */ - long size(String fileName) throws IOException { - send("SIZE " + fileName); - readCode(250); - long size = Long.parseLong(message); - return size; - } - - /** - * Store a file (STOR). - * - * @param fileName the file name - * @param in the input stream - */ - public void store(String fileName, InputStream in) throws IOException { - passive(); - send("STOR " + fileName); - readCode(150); - IOUtils.copyAndClose(in, outData); - readCode(226); - } - - /** - * Copy a local file or directory to the FTP server, recursively. - * - * @param file the file to copy - */ - public void storeRecursive(File file) throws IOException { - if (file.isDirectory()) { - makeDirectory(file.getName()); - changeWorkingDirectory(file.getName()); - for (File f : file.listFiles()) { - storeRecursive(f); - } - changeWorkingDirectory(".."); - } else { - InputStream in = new FileInputStream(file); - store(file.getName(), in); - } - } - - /** - * Get the directory listing (NLST). - * - * @param dir the directory - * @return the listing - */ - public String nameList(String dir) throws IOException { - passive(); - send("NLST " + dir); - readCode(150); - ByteArrayOutputStream out = new ByteArrayOutputStream(); - IOUtils.copyAndClose(inData, out); - readCode(226); - byte[] data = out.toByteArray(); - return new String(data); - } - - /** - * Get the directory listing (LIST). - * - * @param dir the directory - * @return the listing - */ - public String list(String dir) throws IOException { - passive(); - send("LIST " + dir); - readCode(150); - ByteArrayOutputStream out = new ByteArrayOutputStream(); - IOUtils.copyAndClose(inData, out); - readCode(226); - byte[] data = out.toByteArray(); - return new String(data); - } - - /** - * A file on an FTP server. - */ - static class FtpFile extends File { - private static final long serialVersionUID = 1L; - private final boolean dir; - private final long length; - FtpFile(String name, boolean dir, long length) { - super(name); - this.dir = dir; - this.length = length; - } - public long length() { - return length; - } - public boolean isFile() { - return !dir; - } - public boolean isDirectory() { - return dir; - } - public boolean exists() { - return true; - } - } - - /** - * Check if a file exists on the FTP server. - * - * @param dir the directory - * @param name the directory or file name - * @return true if it exists - */ - public boolean exists(String dir, String name) throws IOException { - for (File f : listFiles(dir)) { - if (f.getName().equals(name)) { - return true; - } - } - return false; - } - - /** - * List the files on the FTP server. - * - * @param dir the directory - * @return the list of files - */ - public File[] listFiles(String dir) throws IOException { - String content = list(dir); - String[] list = StringUtils.arraySplit(content.trim(), '\n', true); - File[] files = new File[list.length]; - for (int i = 0; i < files.length; i++) { - String s = list[i]; - while (true) { - String s2 = StringUtils.replaceAll(s, " ", " "); - if (s2.equals(s)) { - break; - } - s = s2; - } - String[] tokens = StringUtils.arraySplit(s, ' ', true); - boolean directory = tokens[0].charAt(0) == 'd'; - long length = Long.parseLong(tokens[4]); - String name = tokens[8]; - File f = new FtpFile(name, directory, length); - files[i] = f; - } - return files; - } - -} diff --git a/tools/h2/src/tools/org/h2/dev/ftp/package.html b/tools/h2/src/tools/org/h2/dev/ftp/package.html deleted file mode 100755 index cc7740d..0000000 --- a/tools/h2/src/tools/org/h2/dev/ftp/package.html +++ /dev/null @@ -1,15 +0,0 @@ - - - - -Javadoc package documentation -

    - -A simple FTP client. - -

    \ No newline at end of file diff --git a/tools/h2/src/tools/org/h2/dev/ftp/server/FtpControl.java b/tools/h2/src/tools/org/h2/dev/ftp/server/FtpControl.java deleted file mode 100755 index 72c31a1..0000000 --- a/tools/h2/src/tools/org/h2/dev/ftp/server/FtpControl.java +++ /dev/null @@ -1,412 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.dev.ftp.server; - -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStreamReader; -import java.io.OutputStreamWriter; -import java.io.PrintWriter; -import java.net.InetAddress; -import java.net.ServerSocket; -import java.net.Socket; -import org.h2.engine.Constants; -import org.h2.store.fs.FileSystem; -import org.h2.util.StringUtils; - -/** - * The implementation of the control channel of the FTP server. - */ -public class FtpControl extends Thread { - - private static final String SERVER_NAME = "Small FTP Server"; - - private FtpServer server; - private FileSystem fs; - private Socket control; - private FtpData data; - private PrintWriter output; - private String userName; - private boolean connected, readonly; - private String currentDir = "/"; - private String serverIpAddress; - private boolean stop; - private String renameFrom; - private boolean replied; - private long restart; - - FtpControl(Socket control, FtpServer server, boolean stop) { - this.server = server; - this.fs = server.getFileSystem(); - this.control = control; - this.stop = stop; - } - - public void run() { - try { - output = new PrintWriter(new OutputStreamWriter(control.getOutputStream(), Constants.UTF8)); - if (stop) { - reply(421, "Too many users"); - } else { - reply(220, SERVER_NAME); - // TODO need option to configure the serverIpAddress? - serverIpAddress = control.getLocalAddress().getHostAddress().replace('.', ','); - BufferedReader input = new BufferedReader(new InputStreamReader(control.getInputStream())); - while (!stop) { - String command = null; - try { - command = input.readLine(); - } catch (IOException e) { - // ignore - } - if (command == null) { - break; - } - process(command); - } - if (data != null) { - data.close(); - } - } - } catch (Throwable t) { - server.traceError(t); - } - server.closeConnection(); - } - - private void process(String command) throws IOException { - int idx = command.indexOf(' '); - String param = ""; - if (idx >= 0) { - param = command.substring(idx).trim(); - command = command.substring(0, idx); - } - command = StringUtils.toUpperEnglish(command); - if (command.length() == 0) { - reply(506, "No command"); - return; - } - server.trace(">" + command); - FtpEventListener listener = server.getEventListener(); - FtpEvent event = null; - if (listener != null) { - event = new FtpEvent(this, command, param); - listener.beforeCommand(event); - } - replied = false; - if (connected) { - processConnected(command, param); - } - if (!replied) { - if ("USER".equals(command)) { - userName = param; - reply(331, "Need password"); - } else if ("QUIT".equals(command)) { - reply(221, "Bye"); - stop = true; - } else if ("PASS".equals(command)) { - if (userName == null) { - reply(332, "Need username"); - } else if (server.checkUserPasswordWrite(userName, param)) { - reply(230, "Ok"); - readonly = false; - connected = true; - } else if (server.checkUserPasswordReadOnly(userName)) { - reply(230, "Ok, readonly"); - readonly = true; - connected = true; - } else { - reply(431, "Wrong user/password"); - } - } else if ("REIN".equals(command)) { - userName = null; - connected = false; - currentDir = "/"; - reply(200, "Ok"); - } else if ("HELP".equals(command)) { - reply(214, SERVER_NAME); - } - } - if (!replied) { - if (listener != null) { - listener.onUnsupportedCommand(event); - } - reply(506, "Invalid command"); - } - if (listener != null) { - listener.afterCommand(event); - } - } - - private void processConnected(String command, String param) throws IOException { - switch (command.charAt(0)) { - case 'C': - if ("CWD".equals(command)) { - String path = getPath(param); - String fileName = getFileName(path); - if (fs.exists(fileName) && fs.isDirectory(fileName)) { - if (!path.endsWith("/")) { - path += "/"; - } - currentDir = path; - reply(250, "Ok"); - } else { - reply(550, "Failed"); - } - } else if ("CDUP".equals(command)) { - if (currentDir.length() > 1) { - int idx = currentDir.lastIndexOf("/", currentDir.length() - 2); - currentDir = currentDir.substring(0, idx + 1); - reply(250, "Ok"); - } else { - reply(550, "Failed"); - } - } - break; - case 'D': - if ("DELE".equals(command)) { - String fileName = getFileName(param); - if (!readonly && fs.exists(fileName) && !fs.isDirectory(fileName) && fs.tryDelete(fileName)) { - if (server.getAllowTask() && fileName.endsWith(FtpServer.TASK_SUFFIX)) { - server.stopTask(fileName); - } - reply(250, "Ok"); - } else { - reply(500, "Delete failed"); - } - } - break; - case 'L': - if ("LIST".equals(command)) { - processList(param, true); - } - break; - case 'M': - if ("MKD".equals(command)) { - processMakeDir(param); - } else if ("MODE".equals(command)) { - if ("S".equals(StringUtils.toUpperEnglish(param))) { - reply(200, "Ok"); - } else { - reply(504, "Invalid"); - } - } else if ("MDTM".equals(command)) { - String fileName = getFileName(param); - if (fs.exists(fileName) && !fs.isDirectory(fileName)) { - reply(213, server.formatLastModified(fileName)); - } else { - reply(550, "Failed"); - } - } - break; - case 'N': - if ("NLST".equals(command)) { - processList(param, false); - } else if ("NOOP".equals(command)) { - reply(200, "Ok"); - } - break; - case 'P': - if ("PWD".equals(command)) { - reply(257, StringUtils.quoteIdentifier(currentDir) + " directory"); - } else if ("PASV".equals(command)) { - ServerSocket dataSocket = server.createDataSocket(); - data = new FtpData(server, control.getInetAddress(), dataSocket); - data.start(); - int port = dataSocket.getLocalPort(); - reply(227, "Passive Mode (" + serverIpAddress + "," + (port >> 8) + "," + (port & 255) + ")"); - } else if ("PORT".equals(command)) { - String[] list = StringUtils.arraySplit(param, ',', true); - String host = list[0] + "." + list[1] + "." + list[2] + "." + list[3]; - int port = (Integer.parseInt(list[4]) << 8) | Integer.parseInt(list[5]); - InetAddress address = InetAddress.getByName(host); - if (address.equals(control.getInetAddress())) { - data = new FtpData(server, address, port); - reply(200, "Ok"); - } else { - server.trace("Port REJECTED:" + address + " expected:" + control.getInetAddress()); - reply(550, "Failed"); - } - } - break; - case 'R': - if ("RNFR".equals(command)) { - String fileName = getFileName(param); - if (fs.exists(fileName)) { - renameFrom = fileName; - reply(350, "Ok"); - } else { - reply(450, "Not found"); - } - } else if ("RNTO".equals(command)) { - if (renameFrom == null) { - reply(503, "RNFR required"); - } else { - String fileOld = renameFrom; - String fileNew = getFileName(param); - boolean ok = false; - if (!readonly) { - try { - fs.rename(fileOld, fileNew); - reply(250, "Ok"); - ok = true; - } catch (Exception e) { - server.traceError(e); - } - } - if (!ok) { - reply(550, "Failed"); - } - } - } else if ("RETR".equals(command)) { - String fileName = getFileName(param); - if (fs.exists(fileName) && !fs.isDirectory(fileName)) { - reply(150, "Starting transfer"); - try { - data.send(fs, fileName, restart); - reply(226, "Ok"); - } catch (IOException e) { - server.traceError(e); - reply(426, "Failed"); - } - restart = 0; - } else { - // Firefox compatibility - // (still not good) - processList(param, true); - // reply(426, "Not a file"); - } - } else if ("RMD".equals(command)) { - processRemoveDir(param); - } else if ("REST".equals(command)) { - try { - restart = Integer.parseInt(param); - reply(350, "Ok"); - } catch (NumberFormatException e) { - reply(500, "Invalid"); - } - } - break; - case 'S': - if ("SYST".equals(command)) { - reply(215, "UNIX Type: L8"); - } else if ("SITE".equals(command)) { - reply(500, "Not understood"); - } else if ("SIZE".equals(command)) { - param = getFileName(param); - if (fs.exists(param) && !fs.isDirectory(param)) { - reply(250, String.valueOf(fs.length(param))); - } else { - reply(500, "Failed"); - } - } else if ("STOR".equals(command)) { - String fileName = getFileName(param); - if (!readonly && !fs.exists(fileName) || !fs.isDirectory(fileName)) { - reply(150, "Starting transfer"); - try { - data.receive(fs, fileName); - if (server.getAllowTask() && param.endsWith(FtpServer.TASK_SUFFIX)) { - server.startTask(fileName); - } - reply(226, "Ok"); - } catch (Exception e) { - server.traceError(e); - reply(426, "Failed"); - } - } else { - reply(550, "Failed"); - } - } else if ("STRU".equals(command)) { - if ("F".equals(StringUtils.toUpperEnglish(param))) { - reply(200, "Ok"); - } else { - reply(504, "Invalid"); - } - } - break; - case 'T': - if ("TYPE".equals(command)) { - param = StringUtils.toUpperEnglish(param); - if ("A".equals(param) || "A N".equals(param)) { - reply(200, "Ok"); - } else if ("I".equals(param) || "L 8".equals(param)) { - reply(200, "Ok"); - } else { - reply(500, "Invalid"); - } - } - break; - case 'X': - if ("XMKD".equals(command)) { - processMakeDir(param); - } else if ("XRMD".equals(command)) { - processRemoveDir(param); - } - break; - } - } - - private void processMakeDir(String param) { - String fileName = getFileName(param); - boolean ok = false; - if (!readonly) { - try { - fs.mkdirs(fileName); - reply(257, StringUtils.quoteIdentifier(param) + " directory"); - ok = true; - } catch (Exception e) { - server.traceError(e); - } - } - if (!ok) { - reply(500, "Failed"); - } - } - - private void processRemoveDir(String param) { - String fileName = getFileName(param); - if (!readonly && fs.exists(fileName) && fs.isDirectory(fileName) && fs.tryDelete(fileName)) { - reply(250, "Ok"); - } else { - reply(500, "Failed"); - } - } - - private String getFileName(String file) { - return server.getFileName(file.startsWith("/") ? file : currentDir + file); - } - - private String getPath(String path) { - return path.startsWith("/") ? path : currentDir + path; - } - - private void processList(String param, boolean directories) throws IOException { - String directory = getFileName(param); - if (!fs.exists(directory)) { - reply(450, "Directory does not exist"); - return; - } else if (!fs.isDirectory(directory)) { - reply(450, "Not a directory"); - return; - } - String list = server.getDirectoryListing(directory, directories); - reply(150, "Starting transfer"); - server.trace(list); - // need to use the current locale (UTF-8 would be wrong for the Windows - // Explorer) - data.send(list.getBytes()); - reply(226, "Done"); - } - - private void reply(int code, String message) { - server.trace(code + " " + message); - output.print(code + " " + message + "\r\n"); - output.flush(); - replied = true; - } - -} diff --git a/tools/h2/src/tools/org/h2/dev/ftp/server/FtpData.java b/tools/h2/src/tools/org/h2/dev/ftp/server/FtpData.java deleted file mode 100755 index b397c98..0000000 --- a/tools/h2/src/tools/org/h2/dev/ftp/server/FtpData.java +++ /dev/null @@ -1,145 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.dev.ftp.server; - -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.net.InetAddress; -import java.net.ServerSocket; -import java.net.Socket; -import org.h2.store.fs.FileSystem; -import org.h2.util.IOUtils; - -/** - * The implementation of the data channel of the FTP server. - */ -public class FtpData extends Thread { - - private FtpServer server; - private InetAddress address; - private ServerSocket serverSocket; - private volatile Socket socket; - private boolean active; - private int port; - - FtpData(FtpServer server, InetAddress address, ServerSocket serverSocket) { - this.server = server; - this.address = address; - this.serverSocket = serverSocket; - } - - FtpData(FtpServer server, InetAddress address, int port) { - this.server = server; - this.address = address; - this.port = port; - active = true; - } - - public void run() { - try { - synchronized (this) { - Socket s = serverSocket.accept(); - if (s.getInetAddress().equals(address)) { - server.trace("Data connected:" + s.getInetAddress() + " expected:" + address); - socket = s; - notifyAll(); - } else { - server.trace("Data REJECTED:" + s.getInetAddress() + " expected:" + address); - close(); - } - } - } catch (IOException e) { - e.printStackTrace(); - } - } - - private void connect() throws IOException { - if (active) { - socket = new Socket(address, port); - } else { - waitUntilConnected(); - } - } - - private void waitUntilConnected() { - while (serverSocket != null && socket == null) { - try { - wait(); - } catch (InterruptedException e) { - // ignore - } - } - server.trace("connected"); - } - - /** - * Close the socket. - */ - void close() { - serverSocket = null; - socket = null; - } - - /** - * Read a file from a client. - * - * @param fs the target file system - * @param fileName the target file name - */ - synchronized void receive(FileSystem fs, String fileName) throws IOException { - connect(); - try { - InputStream in = socket.getInputStream(); - OutputStream out = fs.openFileOutputStream(fileName, false); - IOUtils.copy(in, out); - out.close(); - } finally { - socket.close(); - } - server.trace("closed"); - } - - /** - * Send a file to the client. This method waits until the client has - * connected. - * - * @param fs the source file system - * @param fileName the source file name - * @param skip the number of bytes to skip - */ - synchronized void send(FileSystem fs, String fileName, long skip) throws IOException { - connect(); - try { - OutputStream out = socket.getOutputStream(); - InputStream in = fs.openFileInputStream(fileName); - IOUtils.skipFully(in, skip); - IOUtils.copy(in, out); - in.close(); - } finally { - socket.close(); - } - server.trace("closed"); - } - - /** - * Wait until the client has connected, and then send the data to him. - * - * @param data the data to send - */ - synchronized void send(byte[] data) throws IOException { - connect(); - try { - OutputStream out = socket.getOutputStream(); - out.write(data); - } finally { - socket.close(); - } - server.trace("closed"); - } - -} diff --git a/tools/h2/src/tools/org/h2/dev/ftp/server/FtpEvent.java b/tools/h2/src/tools/org/h2/dev/ftp/server/FtpEvent.java deleted file mode 100755 index b5300ee..0000000 --- a/tools/h2/src/tools/org/h2/dev/ftp/server/FtpEvent.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.dev.ftp.server; - -/** - * Describes an FTP event. This class is used by the FtpEventListener. - */ -public class FtpEvent { - private final FtpControl control; - private final String command; - private final String param; - - FtpEvent(FtpControl control, String command, String param) { - this.control = control; - this.command = command; - this.param = param; - } - - /** - * Get the FTP command. Example: RETR - * - * @return the command - */ - public String getCommand() { - return command; - } - - /** - * Get the FTP control object. - * - * @return the control object - */ - public FtpControl getControl() { - return control; - } - - /** - * Get the parameter of the FTP command (if any). - * - * @return the parameter - */ - public String getParam() { - return param; - } -} diff --git a/tools/h2/src/tools/org/h2/dev/ftp/server/FtpEventListener.java b/tools/h2/src/tools/org/h2/dev/ftp/server/FtpEventListener.java deleted file mode 100755 index bf77ffd..0000000 --- a/tools/h2/src/tools/org/h2/dev/ftp/server/FtpEventListener.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.dev.ftp.server; - -/** - * Event listener for the FTP Server. - */ -public interface FtpEventListener { - - /** - * Called before the given command is processed. - * - * @param event the event - */ - void beforeCommand(FtpEvent event); - - /** - * Called after the command has been processed. - * - * @param event the event - */ - void afterCommand(FtpEvent event); - - /** - * Called when an unsupported command is processed. - * This method is called after beforeCommand. - * - * @param event the event - */ - void onUnsupportedCommand(FtpEvent event); -} diff --git a/tools/h2/src/tools/org/h2/dev/ftp/server/FtpServer.java b/tools/h2/src/tools/org/h2/dev/ftp/server/FtpServer.java deleted file mode 100755 index fbb2299..0000000 --- a/tools/h2/src/tools/org/h2/dev/ftp/server/FtpServer.java +++ /dev/null @@ -1,559 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.dev.ftp.server; - -import java.io.File; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.net.ServerSocket; -import java.net.Socket; -import java.sql.SQLException; -import java.text.SimpleDateFormat; -import java.util.Date; -import java.util.HashMap; -import java.util.Locale; -import java.util.Properties; -import org.h2.server.Service; -import org.h2.store.fs.FileSystem; -import org.h2.tools.Server; -import org.h2.util.IOUtils; -import org.h2.util.NetUtils; -import org.h2.util.SortedProperties; -import org.h2.util.Tool; - -/** - * Small FTP Server. Intended for ad-hoc networks in a secure environment. - * Remote connections are possible. - * See also http://cr.yp.to/ftp.html http://www.ftpguide.com/ - */ -public class FtpServer extends Tool implements Service { - - /** - * The default port to use for the FTP server. - * This value is also in the documentation and in the Server javadoc. - */ - public static final int DEFAULT_PORT = 8021; - - /** - * The default root directory name used by the FTP server. - * This value is also in the documentation and in the Server javadoc. - */ - public static final String DEFAULT_ROOT = "ftp"; - - /** - * The default user name that is allowed to read data. - * This value is also in the documentation and in the Server javadoc. - */ - public static final String DEFAULT_READ = "guest"; - - /** - * The default user name that is allowed to read and write data. - * This value is also in the documentation and in the Server javadoc. - */ - public static final String DEFAULT_WRITE = "sa"; - - /** - * The default password of the user that is allowed to read and write data. - * This value is also in the documentation and in the Server javadoc. - */ - public static final String DEFAULT_WRITE_PASSWORD = "sa"; - - static final String TASK_SUFFIX = ".task"; - - private ServerSocket serverSocket; - private int port = DEFAULT_PORT; - private int openConnectionCount; - private int maxConnectionCount = 100; - - private SimpleDateFormat dateFormatNew = new SimpleDateFormat("MMM dd HH:mm", Locale.ENGLISH); - private SimpleDateFormat dateFormatOld = new SimpleDateFormat("MMM dd yyyy", Locale.ENGLISH); - private SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMddHHmmss"); - - private String root = DEFAULT_ROOT; - private String writeUserName = DEFAULT_WRITE, writePassword = DEFAULT_WRITE_PASSWORD; - private String readUserName = DEFAULT_READ; - private HashMap tasks = new HashMap(); - - private FileSystem fs; - private boolean trace; - private boolean allowTask; - - private FtpEventListener eventListener; - - - /** - * When running without options, -tcp, -web, -browser and -pg are started.
    - * Options are case sensitive. Supported options are: - *
    - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - *
    [-help] or [-?]Print the list of options
    [-web]Start the web server with the H2 Console
    [-webAllowOthers]Allow other computers to connect
    [-webPort <port>]The port (default: 8082)
    [-webSSL]Use encrypted (HTTPS) connections
    [-browser]Start a browser and open a page to connect to the web server
    [-tcp]Start the TCP server
    [-tcpAllowOthers]Allow other computers to connect
    [-tcpPort <port>]The port (default: 9092)
    [-tcpSSL]Use encrypted (SSL) connections
    [-tcpPassword <pwd>]The password for shutting down a TCP server
    [-tcpShutdown "<url>"]Stop the TCP server; example: tcp://localhost:9094
    [-tcpShutdownForce]Do not wait until all connections are closed
    [-pg]Start the PG server
    [-pgAllowOthers]Allow other computers to connect
    [-pgPort <port>]The port (default: 5435)
    [-ftp]Start the FTP server
    [-ftpPort <port>]The port (default: 8021)
    [-ftpDir <dir>]The base directory (default: ftp)
    [-ftpRead <user>]The user name for reading (default: guest)
    [-ftpWrite <user>]The user name for writing (default: sa)
    [-ftpWritePassword <p>]The write password (default: sa)
    [-baseDir <dir>]The base directory for H2 databases; for all servers
    [-ifExists]Only existing databases may be opened; for all servers
    [-trace]Print additional trace information; for all servers
    - * @h2.resource - * - * @param args the command line arguments - */ - public static void main(String... args) throws SQLException { - new FtpServer().runTool(args); - } - - public void runTool(String... args) throws SQLException { - for (int i = 0; args != null && i < args.length; i++) { - String arg = args[i]; - if (arg == null) { - continue; - } else if ("-?".equals(arg) || "-help".equals(arg)) { - showUsage(); - return; - } else if (arg.startsWith("-ftp")) { - if ("-ftpPort".equals(arg)) { - i++; - } else if ("-ftpDir".equals(arg)) { - i++; - } else if ("-ftpRead".equals(arg)) { - i++; - } else if ("-ftpWrite".equals(arg)) { - i++; - } else if ("-ftpWritePassword".equals(arg)) { - i++; - } else if ("-ftpTask".equals(arg)) { - // no parameters - } else { - throwUnsupportedOption(arg); - } - } else if ("-trace".equals(arg)) { - // no parameters - } else { - throwUnsupportedOption(arg); - } - } - Server server = new Server(this, args); - server.start(); - out.println(server.getStatus()); - } - - public void listen() { - try { - while (serverSocket != null) { - Socket s = serverSocket.accept(); - boolean stop; - synchronized (this) { - openConnectionCount++; - stop = openConnectionCount > maxConnectionCount; - } - FtpControl c = new FtpControl(s, this, stop); - c.start(); - } - } catch (Exception e) { - traceError(e); - } - } - - /** - * Close a connection. The open connection count will be decremented. - */ - void closeConnection() { - synchronized (this) { - openConnectionCount--; - } - } - - /** - * Create a socket to listen for incoming data connections. - * - * @return the server socket - */ - ServerSocket createDataSocket() { - return NetUtils.createServerSocket(0, false); - } - - private void appendFile(StringBuilder buff, String fileName) { - buff.append(fs.isDirectory(fileName) ? 'd' : '-'); - buff.append('r'); - buff.append(fs.canWrite(fileName) ? 'w' : '-'); - buff.append("------- 1 owner group "); - String size = String.valueOf(fs.length(fileName)); - for (int i = size.length(); i < 15; i++) { - buff.append(' '); - } - buff.append(size); - buff.append(' '); - Date now = new Date(), mod = new Date(fs.getLastModified(fileName)); - String date; - if (mod.after(now) || Math.abs((now.getTime() - mod.getTime()) / 1000 / 60 / 60 / 24) > 180) { - synchronized (dateFormatOld) { - date = dateFormatOld.format(mod); - } - } else { - synchronized (dateFormatNew) { - date = dateFormatNew.format(mod); - } - } - buff.append(date); - buff.append(' '); - buff.append(IOUtils.getFileName(fileName)); - buff.append("\r\n"); - } - - /** - * Get the last modified date of a date and format it as required by the FTP - * protocol. - * - * @param fileName the file name - * @return the last modified date of this file - */ - String formatLastModified(String fileName) { - synchronized (dateFormat) { - return dateFormat.format(new Date(fs.getLastModified(fileName))); - } - } - - /** - * Get the full file name of this relative path. - * - * @param path the relative path - * @return the file name - */ - String getFileName(String path) { - return root + getPath(path); - } - - private String getPath(String path) { - if (path.indexOf("..") > 0) { - path = "/"; - } - while (path.startsWith("/") && root.endsWith("/")) { - path = path.substring(1); - } - while (path.endsWith("/")) { - path = path.substring(0, path.length() - 1); - } - trace("path: " + path); - return path; - } - - /** - * Get the directory listing for this directory. - * - * @param directory the directory to list - * @param listDirectories if sub-directories should be listed - * @return the list - */ - String getDirectoryListing(String directory, boolean listDirectories) { - StringBuilder buff = new StringBuilder(); - for (String fileName : fs.listFiles(directory)) { - if (!fs.isDirectory(fileName) || (fs.isDirectory(fileName) && listDirectories)) { - appendFile(buff, fileName); - } - } - return buff.toString(); - } - - /** - * Check if this user name is allowed to write. - * - * @param userName the user name - * @param password the password - * @return true if this user may write - */ - boolean checkUserPasswordWrite(String userName, String password) { - return userName.equals(this.writeUserName) && password.equals(this.writePassword); - } - - /** - * Check if this user name is allowed to read. - * - * @param userName the user name - * @return true if this user may read - */ - boolean checkUserPasswordReadOnly(String userName) { - return userName.equals(this.readUserName); - } - - public void init(String... args) { - for (int i = 0; args != null && i < args.length; i++) { - String a = args[i]; - if ("-ftpPort".equals(a)) { - port = Integer.decode(args[++i]); - } else if ("-ftpDir".equals(a)) { - root = IOUtils.normalize(args[++i]); - } else if ("-ftpRead".equals(a)) { - readUserName = args[++i]; - } else if ("-ftpWrite".equals(a)) { - writeUserName = args[++i]; - } else if ("-ftpWritePassword".equals(a)) { - writePassword = args[++i]; - } else if ("-trace".equals(a)) { - trace = true; - } else if ("-ftpTask".equals(a)) { - allowTask = true; - } - } - } - - public String getURL() { - return "ftp://" + NetUtils.getLocalAddress() + ":" + port; - } - - public int getPort() { - return port; - } - - public void start() { - fs = FileSystem.getInstance(root); - root = fs.normalize(root); - fs.mkdirs(root); - serverSocket = NetUtils.createServerSocket(port, false); - port = serverSocket.getLocalPort(); - } - - public void stop() { - if (serverSocket == null) { - return; - } - try { - serverSocket.close(); - } catch (IOException e) { - traceError(e); - } - serverSocket = null; - } - - public boolean isRunning(boolean traceError) { - if (serverSocket == null) { - return false; - } - try { - Socket s = NetUtils.createLoopbackSocket(port, false); - s.close(); - return true; - } catch (IOException e) { - if (traceError) { - traceError(e); - } - return false; - } - } - - public boolean getAllowOthers() { - return true; - } - - public String getType() { - return "FTP"; - } - - public String getName() { - return "H2 FTP Server"; - } - - /** - * Write trace information if trace is enabled. - * - * @param s the message to write - */ - void trace(String s) { - if (trace) { - System.out.println(s); - } - } - - /** - * Write the stack trace if trace is enabled. - * - * @param e the exception - */ - void traceError(Throwable e) { - if (trace) { - e.printStackTrace(); - } - } - - boolean getAllowTask() { - return allowTask; - } - - /** - * Start a task. - * - * @param path the name of the task file - */ - void startTask(String path) throws IOException { - stopTask(path); - if (path.endsWith(".zip.task")) { - trace("expand: " + path); - Process p = Runtime.getRuntime().exec("jar -xf " + path, null, new File(root)); - new StreamRedirect(path, p.getInputStream(), null).start(); - return; - } - Properties prop = SortedProperties.loadProperties(path); - String command = prop.getProperty("command"); - String outFile = path.substring(0, path.length() - TASK_SUFFIX.length()); - String errorFile = root + "/" + prop.getProperty("error", outFile + ".err.txt"); - String outputFile = root + "/" + prop.getProperty("output", outFile + ".out.txt"); - trace("start process: " + path + " / " + command); - Process p = Runtime.getRuntime().exec(command, null, new File(root)); - new StreamRedirect(path, p.getErrorStream(), errorFile).start(); - new StreamRedirect(path, p.getInputStream(), outputFile).start(); - tasks.put(path, p); - } - - /** - * This class re-directs an input stream to a file. - */ - private static class StreamRedirect extends Thread { - private InputStream in; - private OutputStream out; - private String outFile; - private String processFile; - - StreamRedirect(String processFile, InputStream in, String outFile) { - this.processFile = processFile; - this.in = in; - this.outFile = outFile; - } - - private void openOutput() { - if (outFile != null) { - try { - this.out = IOUtils.openFileOutputStream(outFile, false); - } catch (Exception e) { - // ignore - } - outFile = null; - } - } - - public void run() { - while (true) { - try { - int x = in.read(); - if (x < 0) { - break; - } - openOutput(); - if (out != null) { - out.write(x); - } - } catch (IOException e) { - // ignore - } - } - IOUtils.closeSilently(out); - IOUtils.closeSilently(in); - new File(processFile).delete(); - } - } - - /** - * Stop a running task. - * - * @param processName the task name - */ - void stopTask(String processName) { - trace("kill process: " + processName); - Process p = tasks.remove(processName); - if (p == null) { - return; - } - p.destroy(); - } - - /** - * Get the file system used by this FTP server. - * - * @return the file system - */ - FileSystem getFileSystem() { - return fs; - } - - /** - * Set the event listener. Only one listener can be registered. - * - * @param eventListener the new listener, or null to de-register - */ - public void setEventListener(FtpEventListener eventListener) { - this.eventListener = eventListener; - } - - /** - * Get the registered event listener. - * - * @return the event listener, or null if non is registered - */ - FtpEventListener getEventListener() { - return eventListener; - } - - /** - * Create a new FTP server, but does not start it yet. Example: - * - *
    -     * Server server = FtpServer.createFtpServer(null).start();
    -     * 
    - * - * @param args the argument list - * @return the server - */ - public static Server createFtpServer(String... args) throws SQLException { - return new Server(new FtpServer(), args); - } - - public boolean isDaemon() { - return false; - } - -} diff --git a/tools/h2/src/tools/org/h2/dev/ftp/server/package.html b/tools/h2/src/tools/org/h2/dev/ftp/server/package.html deleted file mode 100755 index a938d8e..0000000 --- a/tools/h2/src/tools/org/h2/dev/ftp/server/package.html +++ /dev/null @@ -1,15 +0,0 @@ - - - - -Javadoc package documentation -

    - -A simple FTP server. - -

    \ No newline at end of file diff --git a/tools/h2/src/tools/org/h2/dev/jpox/H2Adapter.java.txt b/tools/h2/src/tools/org/h2/dev/jpox/H2Adapter.java.txt deleted file mode 100755 index b35f2a9..0000000 --- a/tools/h2/src/tools/org/h2/dev/jpox/H2Adapter.java.txt +++ /dev/null @@ -1,352 +0,0 @@ -/********************************************************************** -Copyright (c) 2006 Andy Jefferson and others. All rights reserved. -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. - -Contributors: -2006 Thomas Mueller - updated the dialect for the H2 database engine -**********************************************************************/ -package org.jpox.store.rdbms.adapter; - -import java.sql.Connection; -import java.sql.DatabaseMetaData; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.util.ArrayList; - -import javax.sql.DataSource; - -import org.jpox.store.DatastoreContainerObject; -import org.jpox.store.DatastoreIdentifier; -import org.jpox.store.Dictionary; -import org.jpox.store.expression.LogicSetExpression; -import org.jpox.store.expression.NumericExpression; -import org.jpox.store.expression.QueryExpression; -import org.jpox.store.expression.ScalarExpression; -import org.jpox.store.expression.TableExprAsJoins; -import org.jpox.store.rdbms.Column; -import org.jpox.store.rdbms.key.PrimaryKey; -import org.jpox.store.rdbms.table.Table; - -/** - * Provides methods for adapting SQL language elements to the H2 Database Engine. - * - * @version $Revision: 1.1 $ - */ -class H2Adapter extends DatabaseAdapter -{ - private String schemaName; - - /** - * Constructs a H2 adapter based on the given JDBC metadata. - * @param dictionary The Dictionary to use - * @param metadata the database metadata. - */ - public H2Adapter(Dictionary dictionary, DatabaseMetaData metadata) - { - super(dictionary, metadata); - - // Set schema name - try - { - ResultSet rs = metadata.getSchemas(); - while (rs.next()) - { - if (rs.getBoolean("IS_DEFAULT")) - { - schemaName = rs.getString("TABLE_SCHEM"); - } - } - } - catch (SQLException e) - { - e.printStackTrace(); - // ignore - } - } - - /** - * Getter for the vendor ID for this adapter. - * @return The vendor ID - */ - public String getVendorID() - { - return "h2"; - } - - /** - * Accessor for a Connection to the datastore. - * @param ds The data source. Possible to have more than one data source for fail over - * @param userName The username for the datastore - * @param password The password for the datastore - * @param isolationLevel The level of transaction isolation - * @return The Connection - * @throws SQLException Thrown when an error occurs in the creation. - **/ - public Connection getConnection(DataSource[] ds, String userName, String password, int isolationLevel) - throws SQLException - { - return super.getConnection(ds,userName,password,Connection.TRANSACTION_SERIALIZABLE); - } - - /** - * Accessor for the maximum table name length permitted on this - * datastore. - * @return Max table name length - **/ - public int getMaxTableNameLength() - { - return SQLConstants.MAX_IDENTIFIER_LENGTH; - } - - /** - * Accessor for the maximum constraint name length permitted on this - * datastore. - * @return Max constraint name length - **/ - public int getMaxConstraintNameLength() - { - return SQLConstants.MAX_IDENTIFIER_LENGTH; - } - - /** - * Accessor for the maximum index name length permitted on this datastore. - * @return Max index name length - **/ - public int getMaxIndexNameLength() - { - return SQLConstants.MAX_IDENTIFIER_LENGTH; - } - - /** - * Accessor for the maximum column name length permitted on this datastore. - * @return Max column name length - **/ - public int getMaxColumnNameLength() - { - return SQLConstants.MAX_IDENTIFIER_LENGTH; - } - - /** - * Accessor for the SQL statement to add a column to a table. - * @param table The table - * @param col The column - * @return The SQL necessary to add the column - */ - public String getAddColumnStatement(DatastoreContainerObject table, Column col) - { - return "ALTER TABLE " + table.toString() + " ADD COLUMN " + col.getSQLDefinition(); - } - - /** - * Method to return the SQL to append to the SELECT clause of a SELECT statement to handle - * restriction of ranges using the LIMIT keyword. - * @param offset The offset to return from - * @param count The number of items to return - * @return The SQL to append to allow for ranges using LIMIT. - */ - public String getRangeByLimitSelectClause(long offset, long count) - { - if (offset >= 0 && count > 0) - { - return " LIMIT " + offset + " " + count + " "; - } - else if (offset <= 0 && count > 0) - { - return " LIMIT 0 " + count + " "; - } - else - { - return ""; - } - } - - /** - * Accessor for whether the adapter supports the transaction isolation level - * - * @param isolationLevel the isolation level - * @return Whether the transaction isolation level setting is supported. - */ - public boolean supportsTransactionIsolationLevel(int isolationLevel) - { - if (isolationLevel == Connection.TRANSACTION_READ_COMMITTED || isolationLevel == Connection.TRANSACTION_SERIALIZABLE) - { - return true; - } - return false; - } - - /** - * Whether the datastore supports specification of the primary key in CREATE - * TABLE statements. - * @return Whether it allows "PRIMARY KEY ..." - */ - public boolean supportsPrimaryKeyInCreateStatements() - { - return true; - } - - /** - * Accessor for the Schema Name for this datastore. - * - * @param conn Connection to the datastore - * @return The schema name - **/ - public String getSchemaName(Connection conn) - throws SQLException - { - return schemaName; - } - - /** - * @param pk An object describing the primary key. - * @return The PK statement - */ - public String getAddPrimaryKeyStatement(PrimaryKey pk) - { - // PK is created by the CREATE TABLE statement so we just return null - return null; - } - - - /** - * Returns the appropriate SQL to drop the given table. - * It should return something like: - *

    - *

    -     * DROP TABLE FOO
    -     * 
    - * - * @param table The table to drop. - * @return The text of the SQL statement. - */ - public String getDropTableStatement(DatastoreContainerObject table) - { - return "DROP TABLE " + table.toString(); - } - - /** - * Whether we support deferred constraints in keys. - * @return whether we support deferred constraints in keys. - **/ - public boolean supportsDeferredConstraints() - { - return false; - } - - /** - * Whether we support auto incrementing fields. - * @return whether we support auto incrementing fields. - **/ - public boolean supportsAutoIncrementFields() - { - return true; - } - - /** - * Accessor for the auto-increment sql statement for this datastore. - * @param tableName Name of the table that the autoincrement is for - * @param columnName Name of the column that the autoincrement is for - * @return The statement for getting the latest auto-increment key - **/ - public String getAutoIncrementStmt(String tableName, String columnName) - { - return "CALL IDENTITY()"; - } - - /** - * Accessor for the auto-increment keyword for generating DDLs (CREATE TABLE...). - * @return The keyword for a column using auto-increment - **/ - public String getAutoIncrementKeyword() - { - return "IDENTITY"; - } - - /** - * Method to return the INSERT statement to use when inserting into a table that has no - * columns specified. This is the case when we have a single column in the table and that column - * is autoincrement/identity (and so is assigned automatically in the datastore). - * @param table The table - * @return The INSERT statement - */ - public String getInsertStatementForNoColumns(Table table) - { - return "INSERT INTO " + table.toString() + " VALUES(NULL)"; - } - - /** - * Whether to allow Unique statements in the section of CREATE TABLE after the - * column definitions. - * @see org.jpox.store.rdbms.adapter.DatabaseAdapter#supportsUniqueConstraintsInEndCreateStatements() - */ - public boolean supportsUniqueConstraintsInEndCreateStatements() - { - return true; - } - - /** - * Whether this datastore supports the use of CHECK after the column - * definitions in CREATE TABLE statements (DDL). - * e.g. - * CREATE TABLE XYZ - * ( - * COL_A int, - * COL_B char(1), - * PRIMARY KEY (COL_A), - * CHECK (COL_B IN ('Y','N')) - * ) - * @return whether we can use CHECK after the column definitions in CREATE TABLE. - **/ - public boolean supportsCheckConstraintsInEndCreateStatements() - { - return true; - } - - /** - * Accessor for whether the specified type is allow to be part of a PK. - * @param datatype The JDBC type - * @return Whether it is permitted in the PK - */ - public boolean isValidPrimaryKeyType(int datatype) - { - return true; - } - - /** - * Method to generate a modulus expression. The binary % operator is said to - * yield the remainder of its operands from an implied division; the - * left-hand operand is the dividend and the right-hand operand is the - * divisor. This returns MOD(expr1, expr2). - * @param operand1 the left expression - * @param operand2 the right expression - * @return The Expression for modulus - */ - public NumericExpression modOperator(ScalarExpression operand1, ScalarExpression operand2) - { - ArrayList args = new ArrayList(); - args.add(operand1); - args.add(operand2); - return new NumericExpression("MOD", args); - } - /** - * Return a new TableExpression. - * @param qs The QueryStatement to add the expression to - * @param table The table in the expression - * @param rangeVar range variable to assign to the expression. - * @return The expression. - **/ - public LogicSetExpression newTableExpression(QueryExpression qs, DatastoreContainerObject table, DatastoreIdentifier rangeVar) - { - return new TableExprAsJoins(qs, table, rangeVar); - } -} diff --git a/tools/h2/src/tools/org/h2/dev/mail/SendMail.java.txt b/tools/h2/src/tools/org/h2/dev/mail/SendMail.java.txt deleted file mode 100755 index 8489d12..0000000 --- a/tools/h2/src/tools/org/h2/dev/mail/SendMail.java.txt +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.dev.mail; -import java.util.Properties; -import javax.mail.Session; -import javax.mail.Transport; -import javax.mail.Message.RecipientType; -import javax.mail.internet.MimeMessage; - -/** - * Utility class to send a mail over a fixed gmail account. - */ -public class SendMail { - // http://repo2.maven.org/maven2/javax/mail/mail/1.4.1/mail-1.4.1.jar - // http://repo2.maven.org/maven2/javax/activation/activation/1.1/activation-1.1.jar - - public static void main(String[] args) throws Exception { - String to = "thomas.tom.mueller" + "@" + "gmail.com"; - sendMailOverGmail("", to, "Test", "Test Mail"); - } - - static void sendMailOverGmail(String password, String to, String subject, String body) throws Exception { - String username = "testing1212123" + "@" + "gmail.com"; - String host = "smtp.gmail.com"; - Properties prop = new Properties(); - prop.put("mail.smtps.auth", "true"); - Session session = Session.getDefaultInstance(prop); - session.setProtocolForAddress("rfc822", "smtps"); - session.setDebug(true); - MimeMessage msg = new MimeMessage(session); - msg.setRecipients(RecipientType.TO, to); - msg.setSubject(subject); - msg.setText(body); - Transport t = session.getTransport("smtps"); - try { - t.connect(host, username, password); - t.sendMessage(msg, msg.getAllRecipients()); - } finally { - t.close(); - } - } -} diff --git a/tools/h2/src/tools/org/h2/dev/net/PgTcpRedirect.java b/tools/h2/src/tools/org/h2/dev/net/PgTcpRedirect.java deleted file mode 100755 index 408dc59..0000000 --- a/tools/h2/src/tools/org/h2/dev/net/PgTcpRedirect.java +++ /dev/null @@ -1,554 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.dev.net; - -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.DataInputStream; -import java.io.DataOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.net.ServerSocket; -import java.net.Socket; - -/** - * This class helps debug the PostgreSQL network protocol. - * It listens on one port, and sends the exact same data to another port. - */ -public class PgTcpRedirect { - - private static final boolean DEBUG = false; - - /** - * This method is called when executing this application from the command - * line. - * - * @param args the command line parameters - */ - public static void main(String... args) throws Exception { - new PgTcpRedirect().loop(args); - } - - private void loop(String... args) throws Exception { - // MySQL protocol: - // http://www.redferni.uklinux.net/mysql/MySQL-Protocol.html - // PostgreSQL protocol: - // http://developer.postgresql.org/pgdocs/postgres/protocol.html - // int portServer = 9083, portClient = 9084; - // int portServer = 3306, portClient = 3307; - // H2 PgServer - // int portServer = 5435, portClient = 5433; - // PostgreSQL - int portServer = 5432, portClient = 5433; - - for (int i = 0; i < args.length; i++) { - if ("-client".equals(args[i])) { - portClient = Integer.parseInt(args[++i]); - } else if ("-server".equals(args[i])) { - portServer = Integer.parseInt(args[++i]); - } - } - ServerSocket listener = new ServerSocket(portClient); - while (true) { - Socket client = listener.accept(); - Socket server = new Socket("localhost", portServer); - TcpRedirectThread c = new TcpRedirectThread(client, server, true); - TcpRedirectThread s = new TcpRedirectThread(server, client, false); - new Thread(c).start(); - new Thread(s).start(); - } - } - - /** - * This is the working thread of the TCP redirector. - */ - private class TcpRedirectThread implements Runnable { - - private static final int STATE_INIT_CLIENT = 0, STATE_REGULAR = 1; - private Socket read, write; - private int state; - private boolean client; - - TcpRedirectThread(Socket read, Socket write, boolean client) { - this.read = read; - this.write = write; - this.client = client; - state = client ? STATE_INIT_CLIENT : STATE_REGULAR; - } - - String readStringNull(InputStream in) throws IOException { - StringBuilder buff = new StringBuilder(); - while (true) { - int x = in.read(); - if (x <= 0) { - break; - } - buff.append((char) x); - } - return buff.toString(); - } - - private void println(String s) { - if (DEBUG) { - System.out.println(s); - } - } - - private boolean processClient(InputStream inStream, OutputStream outStream) throws IOException { - DataInputStream dataIn = new DataInputStream(inStream); - ByteArrayOutputStream buff = new ByteArrayOutputStream(); - DataOutputStream dataOut = new DataOutputStream(buff); - if (state == STATE_INIT_CLIENT) { - state = STATE_REGULAR; - int len = dataIn.readInt(); - dataOut.writeInt(len); - len -= 4; - byte[] data = new byte[len]; - dataIn.readFully(data, 0, len); - dataOut.write(data); - dataIn = new DataInputStream(new ByteArrayInputStream(data, 0, len)); - int version = dataIn.readInt(); - if (version == 80877102) { - println("CancelRequest"); - println(" pid: " + dataIn.readInt()); - println(" key: " + dataIn.readInt()); - } else if (version == 80877103) { - println("SSLRequest"); - } else { - println("StartupMessage"); - println(" version " + version + " (" + (version >> 16) + "." + (version & 0xff) + ")"); - while (true) { - String param = readStringNull(dataIn); - if (param.length() == 0) { - break; - } - String value = readStringNull(dataIn); - println(" param " + param + "=" + value); - } - } - } else { - int x = dataIn.read(); - if (x < 0) { - println("end"); - return false; - } - // System.out.println(" x=" + (char)x+" " +x); - dataOut.write(x); - int len = dataIn.readInt(); - dataOut.writeInt(len); - len -= 4; - byte[] data = new byte[len]; - dataIn.readFully(data, 0, len); - dataOut.write(data); - dataIn = new DataInputStream(new ByteArrayInputStream(data, 0, len)); - switch (x) { - case 'B': { - println("Bind"); - println(" destPortal: " + readStringNull(dataIn)); - println(" prepName: " + readStringNull(dataIn)); - int formatCodesCount = dataIn.readShort(); - for (int i = 0; i < formatCodesCount; i++) { - println(" formatCode[" + i + "]=" + dataIn.readShort()); - } - int paramCount = dataIn.readShort(); - for (int i = 0; i < paramCount; i++) { - int paramLen = dataIn.readInt(); - println(" length[" + i + "]=" + paramLen); - byte[] d2 = new byte[paramLen]; - dataIn.readFully(d2); - } - int resultCodeCount = dataIn.readShort(); - for (int i = 0; i < resultCodeCount; i++) { - println(" resultCodeCount[" + i + "]=" + dataIn.readShort()); - } - break; - } - case 'C': { - println("Close"); - println(" type: (S:prepared statement, P:portal): " + dataIn.read()); - break; - } - case 'd': { - println("CopyData"); - break; - } - case 'c': { - println("CopyDone"); - break; - } - case 'f': { - println("CopyFail"); - println(" message: " + readStringNull(dataIn)); - break; - } - case 'D': { - println("Describe"); - println(" type (S=prepared statement, P=portal): " + (char) dataIn.readByte()); - println(" name: " + readStringNull(dataIn)); - break; - } - case 'E': { - println("Execute"); - println(" name: " + readStringNull(dataIn)); - println(" maxRows: " + dataIn.readShort()); - break; - } - case 'H': { - println("Flush"); - break; - } - case 'F': { - println("FunctionCall"); - println(" objectId:" + dataIn.readInt()); - int columns = dataIn.readShort(); - for (int i = 0; i < columns; i++) { - println(" formatCode[" + i + "]: " + dataIn.readShort()); - } - int count = dataIn.readShort(); - for (int i = 0; i < count; i++) { - int l = dataIn.readInt(); - println(" len[" + i + "]: " + l); - if (l >= 0) { - for (int j = 0; j < l; j++) { - dataIn.readByte(); - } - } - } - println(" resultFormat: " + dataIn.readShort()); - break; - } - case 'P': { - println("Parse"); - println(" name:" + readStringNull(dataIn)); - println(" query:" + readStringNull(dataIn)); - int count = dataIn.readShort(); - for (int i = 0; i < count; i++) { - println(" [" + i + "]: " + dataIn.readInt()); - } - break; - } - case 'p': { - println("PasswordMessage"); - println(" password: " + readStringNull(dataIn)); - break; - } - case 'Q': { - println("Query"); - println(" sql : " + readStringNull(dataIn)); - break; - } - case 'S': { - println("Sync"); - break; - } - case 'X': { - println("Terminate"); - break; - } - default: - println("############## UNSUPPORTED: " + (char) x); - } - } - dataOut.flush(); - byte[] buffer = buff.toByteArray(); - printData(buffer, buffer.length); - try { - outStream.write(buffer, 0, buffer.length); - outStream.flush(); - } catch (IOException e) { - e.printStackTrace(); - } - return true; - } - - private boolean processServer(InputStream inStream, OutputStream outStream) throws IOException { - DataInputStream dataIn = new DataInputStream(inStream); - ByteArrayOutputStream buff = new ByteArrayOutputStream(); - DataOutputStream dataOut = new DataOutputStream(buff); - int x = dataIn.read(); - if (x < 0) { - println("end"); - return false; - } - // System.out.println(" x=" + (char)x+" " +x); - dataOut.write(x); - int len = dataIn.readInt(); - dataOut.writeInt(len); - len -= 4; - byte[] data = new byte[len]; - dataIn.readFully(data, 0, len); - dataOut.write(data); - dataIn = new DataInputStream(new ByteArrayInputStream(data, 0, len)); - switch (x) { - case 'R': { - println("Authentication"); - int value = dataIn.readInt(); - if (value == 0) { - println(" Ok"); - } else if (value == 2) { - println(" KerberosV5"); - } else if (value == 3) { - println(" CleartextPassword"); - } else if (value == 4) { - println(" CryptPassword"); - byte b1 = dataIn.readByte(); - byte b2 = dataIn.readByte(); - println(" salt1=" + b1 + " salt2=" + b2); - } else if (value == 5) { - println(" MD5Password"); - byte b1 = dataIn.readByte(); - byte b2 = dataIn.readByte(); - byte b3 = dataIn.readByte(); - byte b4 = dataIn.readByte(); - println(" salt1=" + b1 + " salt2=" + b2 + " 3=" + b3 + " 4=" + b4); - } else if (value == 6) { - println(" SCMCredential"); - } - break; - } - case 'K': { - println("BackendKeyData"); - println(" process ID " + dataIn.readInt()); - println(" key " + dataIn.readInt()); - break; - } - case '2': { - println("BindComplete"); - break; - } - case '3': { - println("CloseComplete"); - break; - } - case 'C': { - println("CommandComplete"); - println(" command tag: " + readStringNull(dataIn)); - break; - } - case 'd': { - println("CopyData"); - break; - } - case 'c': { - println("CopyDone"); - break; - } - case 'G': { - println("CopyInResponse"); - println(" format: " + dataIn.readByte()); - int columns = dataIn.readShort(); - for (int i = 0; i < columns; i++) { - println(" formatCode[" + i + "]: " + dataIn.readShort()); - } - break; - } - case 'H': { - println("CopyOutResponse"); - println(" format: " + dataIn.readByte()); - int columns = dataIn.readShort(); - for (int i = 0; i < columns; i++) { - println(" formatCode[" + i + "]: " + dataIn.readShort()); - } - break; - } - case 'D': { - println("DataRow"); - int columns = dataIn.readShort(); - println(" columns : " + columns); - for (int i = 0; i < columns; i++) { - int l = dataIn.readInt(); - if (l > 0) { - for (int j = 0; j < l; j++) { - dataIn.readByte(); - } - } - // println(" ["+i+"] len: " + l); - } - break; - } - case 'I': { - println("EmptyQueryResponse"); - break; - } - case 'E': { - println("ErrorResponse"); - while (true) { - int fieldType = dataIn.readByte(); - if (fieldType == 0) { - break; - } - String msg = readStringNull(dataIn); - // http://developer.postgresql.org/pgdocs/postgres/protocol-error-fields.html - // S Severity - // C Code: the SQLSTATE code - // M Message - // D Detail - // H Hint - // P Position - // p Internal position - // q Internal query - // W Where - // F File - // L Line - // R Routine - println(" fieldType: " + fieldType + " msg: " + msg); - } - break; - } - case 'V': { - println("FunctionCallResponse"); - int resultLen = dataIn.readInt(); - println(" len: " + resultLen); - break; - } - case 'n': { - println("NoData"); - break; - } - case 'N': { - println("NoticeResponse"); - while (true) { - int fieldType = dataIn.readByte(); - if (fieldType == 0) { - break; - } - String msg = readStringNull(dataIn); - // http://developer.postgresql.org/pgdocs/postgres/protocol-error-fields.html - // S Severity - // C Code: the SQLSTATE code - // M Message - // D Detail - // H Hint - // P Position - // p Internal position - // q Internal query - // W Where - // F File - // L Line - // R Routine - println(" fieldType: " + fieldType + " msg: " + msg); - } - break; - } - case 'A': { - println("NotificationResponse"); - println(" processID: " + dataIn.readInt()); - println(" condition: " + readStringNull(dataIn)); - println(" information: " + readStringNull(dataIn)); - break; - } - case 't': { - println("ParameterDescription"); - println(" processID: " + dataIn.readInt()); - int count = dataIn.readShort(); - for (int i = 0; i < count; i++) { - println(" [" + i + "] objectId: " + dataIn.readInt()); - } - break; - } - case 'S': { - println("ParameterStatus"); - println(" parameter " + readStringNull(dataIn) + " = " + readStringNull(dataIn)); - break; - } - case '1': { - println("ParseComplete"); - break; - } - case 's': { - println("ParseComplete"); - break; - } - case 'Z': { - println("ReadyForQuery"); - println(" status (I:idle, T:transaction, E:failed): " + (char) dataIn.readByte()); - break; - } - case 'T': { - println("RowDescription"); - int columns = dataIn.readShort(); - println(" columns : " + columns); - for (int i = 0; i < columns; i++) { - println(" [" + i + "]"); - println(" name:" + readStringNull(dataIn)); - println(" tableId:" + dataIn.readInt()); - println(" columnId:" + dataIn.readShort()); - println(" dataTypeId:" + dataIn.readInt()); - println(" dataTypeSize (pg_type.typlen):" + dataIn.readShort()); - println(" modifier (pg_attribute.atttypmod):" + dataIn.readInt()); - println(" format code:" + dataIn.readShort()); - } - break; - } - default: - println("############## UNSUPPORTED: " + (char) x); - } - dataOut.flush(); - byte[] buffer = buff.toByteArray(); - printData(buffer, buffer.length); - try { - outStream.write(buffer, 0, buffer.length); - outStream.flush(); - } catch (IOException e) { - e.printStackTrace(); - } - return true; - } - - public void run() { - try { - OutputStream out = write.getOutputStream(); - InputStream in = read.getInputStream(); - while (true) { - boolean more; - if (client) { - more = processClient(in, out); - } else { - more = processServer(in, out); - } - if (!more) { - break; - } - } - try { - read.close(); - } catch (IOException e) { - // ignore - } - try { - write.close(); - } catch (IOException e) { - // ignore - } - } catch (Throwable e) { - e.printStackTrace(); - } - } - } - - /** - * Print the uninterpreted byte array. - * - * @param buffer the byte array - * @param len the length - */ - synchronized void printData(byte[] buffer, int len) { - if (DEBUG) { - System.out.print(" "); - for (int i = 0; i < len; i++) { - int c = buffer[i] & 255; - if (c >= ' ' && c <= 127 && c != '[' & c != ']') { - System.out.print((char) c); - } else { - System.out.print("[" + Integer.toHexString(c) + "]"); - } - } - System.out.println(); - } - } -} diff --git a/tools/h2/src/tools/org/h2/dev/net/package.html b/tools/h2/src/tools/org/h2/dev/net/package.html deleted file mode 100755 index 5784c61..0000000 --- a/tools/h2/src/tools/org/h2/dev/net/package.html +++ /dev/null @@ -1,15 +0,0 @@ - - - - -Javadoc package documentation -

    - -A tool to redirect and interpret PostgreSQL network protocol packets. - -

    \ No newline at end of file diff --git a/tools/h2/src/tools/org/h2/dev/security/SecureKeyStoreBuilder.java b/tools/h2/src/tools/org/h2/dev/security/SecureKeyStoreBuilder.java deleted file mode 100755 index 1639c5b..0000000 --- a/tools/h2/src/tools/org/h2/dev/security/SecureKeyStoreBuilder.java +++ /dev/null @@ -1,91 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.dev.security; - -import java.security.Key; -import java.security.KeyStore; -import java.security.KeyStoreException; -import java.security.NoSuchAlgorithmException; -import java.security.UnrecoverableKeyException; -import java.security.cert.Certificate; -import java.security.cert.CertificateEncodingException; -import java.util.Enumeration; - -import org.h2.security.CipherFactory; -import org.h2.util.Utils; - -/** - * Tool to generate source code for the SecureSocketFactory. First, create a - * keystore using: - *
    - * keytool -genkey -alias h2 -keyalg RSA -dname "cn=H2" -validity 25000
    - *      -keypass h2pass -keystore h2.keystore -storepass h2pass
    - * 
    - * Then run this application to generate the source code. Then replace the code - * in the function SecureSocketFactory.getKeyStore as specified - */ -public class SecureKeyStoreBuilder { - - private SecureKeyStoreBuilder() { - // utility class - } - - /** - * This method is called when executing this application from the command - * line. - * - * @param args the command line parameters - */ - public static void main(String... args) throws Exception { - String password = CipherFactory.KEYSTORE_PASSWORD; - KeyStore store = CipherFactory.getKeyStore(password); - printKeystore(store, password); - } - - private static void printKeystore(KeyStore store, String password) throws KeyStoreException, NoSuchAlgorithmException, UnrecoverableKeyException, CertificateEncodingException { - System.out.println("KeyStore store = KeyStore.getInstance(\""+store.getType()+"\");"); - System.out.println("store.load(null, password.toCharArray());"); - //System.out.println("keystore provider="+store.getProvider().getName()); - Enumeration en = store.aliases(); - while (en.hasMoreElements()) { - String alias = en.nextElement(); - Key key = store.getKey(alias, password.toCharArray()); - System.out.println("KeyFactory keyFactory = KeyFactory.getInstance(\"" + key.getAlgorithm() + "\");"); - System.out.println("store.load(null, password.toCharArray());"); - String pkFormat = key.getFormat(); - String encoded = Utils.convertBytesToString(key.getEncoded()); - System.out.println(pkFormat + "EncodedKeySpec keySpec = new " + pkFormat + "EncodedKeySpec(getBytes(\"" - + encoded + "\"));"); - System.out.println("PrivateKey privateKey = keyFactory.generatePrivate(keySpec);"); - System.out.println("Certificate[] certs = {"); - for (Certificate cert : store.getCertificateChain(alias)) { - System.out.println(" CertificateFactory.getInstance(\""+cert.getType()+"\")."); - String enc = Utils.convertBytesToString(cert.getEncoded()); - System.out.println(" generateCertificate(new ByteArrayInputStream(getBytes(\""+enc+"\"))),"); - // PublicKey pubKey = cert.getPublicKey(); - // System.out.println(" pubKey algorithm="+pubKey.getAlgorithm()); - // System.out.println(" pubKey format="+pubKey.getFormat()); - // System.out.println(" pubKey format="+ - // Utils.convertBytesToString(pubKey.getEncoded())); - } - System.out.println("};"); - System.out.println("store.setKeyEntry(\""+alias+"\", privateKey, password.toCharArray(), certs);"); - } - } - -// private void listCipherSuites(SSLServerSocketFactory f) { -// String[] def = f.getDefaultCipherSuites(); -// for (int i = 0; i < def.length; i++) { -// System.out.println("default = " + def[i]); -// } -// String[] sup = f.getSupportedCipherSuites(); -// for (int i = 0; i < sup.length; i++) { -// System.out.println("supported = " + sup[i]); -// } -// } - -} diff --git a/tools/h2/src/tools/org/h2/dev/security/package.html b/tools/h2/src/tools/org/h2/dev/security/package.html deleted file mode 100755 index aa3155c..0000000 --- a/tools/h2/src/tools/org/h2/dev/security/package.html +++ /dev/null @@ -1,15 +0,0 @@ - - - - -Javadoc package documentation -

    - -Security tools. - -

    \ No newline at end of file diff --git a/tools/h2/src/tools/org/h2/dev/util/ArrayUtils.java b/tools/h2/src/tools/org/h2/dev/util/ArrayUtils.java deleted file mode 100755 index f3a6a6e..0000000 --- a/tools/h2/src/tools/org/h2/dev/util/ArrayUtils.java +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.dev.util; - -import java.util.Comparator; - -/** - * Array utility methods. - */ -public class ArrayUtils { - - /** - * Sort an array using binary insertion sort - * - * @param the type - * @param d the data - * @param left the index of the leftmost element - * @param right the index of the rightmost element - * @param comp the comparison class - */ - public void binaryInsertionSort(T[] d, int left, int right, Comparator comp) { - for (int i = left + 1; i <= right; i++) { - T t = d[i]; - int l = left; - for (int r = i; l < r;) { - int m = (l + r) >>> 1; - if (comp.compare(t, d[m]) >= 0) { - l = m + 1; - } else { - r = m; - } - } - for (int n = i - l; n > 0;) { - d[l + n--] = d[l + n]; - } - d[l] = t; - } - } - - /** - * Sort an array using insertion sort - * - * @param the type - * @param d the data - * @param left the index of the leftmost element - * @param right the index of the rightmost element - * @param comp the comparison class - */ - public void insertionSort(T[] d, int left, int right, Comparator comp) { - for (int i = left + 1, j; i <= right; i++) { - T t = d[i]; - for (j = i - 1; j >= left && comp.compare(d[j], t) > 0; j--) { - d[j + 1] = d[j]; - } - d[j + 1] = t; - } - } - - -} diff --git a/tools/h2/src/tools/org/h2/dev/util/Base64.java b/tools/h2/src/tools/org/h2/dev/util/Base64.java deleted file mode 100755 index 60d5674..0000000 --- a/tools/h2/src/tools/org/h2/dev/util/Base64.java +++ /dev/null @@ -1,234 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.dev.util; - -import java.util.Random; - -/** - * This class converts binary to base64 and vice versa. - */ -public class Base64 { - - private static final byte[] CODE = new byte[64]; - private static final byte[] REV = new byte[256]; - - private Base64() { - // utility class - } - - static { - for (int i = 'A'; i <= 'Z'; i++) { - CODE[i - 'A'] = (byte) i; - CODE[i - 'A' + 26] = (byte) (i + 'a' - 'A'); - } - for (int i = 0; i < 10; i++) { - CODE[i + 2 * 26] = (byte) ('0' + i); - } - CODE[62] = (byte) '+'; - CODE[63] = (byte) '/'; - for (int i = 0; i < 255; i++) { - REV[i] = -1; - } - for (int i = 0; i < 64; i++) { - REV[CODE[i]] = (byte) i; - } - } - - private static void check(String a, String b) { - if (!a.equals(b)) { - throw new RuntimeException("mismatch: " + a + " <> " + b); - } - } - - /** - * Run the tests. - * - * @param args the command line parameters - */ - public static void main(String... args) { - check(new String(encode(new byte[] {})), ""); - check(new String(encode("A".getBytes())), "QQ=="); - check(new String(encode("AB".getBytes())), "QUI="); - check(new String(encode("ABC".getBytes())), "QUJD"); - check(new String(encode("ABCD".getBytes())), "QUJDRA=="); - check(new String(decode(new byte[] {})), ""); - check(new String(decode("QQ==".getBytes())), "A"); - check(new String(decode("QUI=".getBytes())), "AB"); - check(new String(decode("QUJD".getBytes())), "ABC"); - check(new String(decode("QUJDRA==".getBytes())), "ABCD"); - int len = 10000; - test(false, len); - test(true, len); - test(false, len); - test(true, len); - } - - private static void test(boolean fast, int len) { - Random random = new Random(10); - long time = System.currentTimeMillis(); - byte[] bin = new byte[len]; - random.nextBytes(bin); - for (int i = 0; i < len; i++) { - byte[] dec; - if (fast) { - byte[] enc = encodeFast(bin); - dec = decodeFast(enc); - } else { - byte[] enc = encode(bin); - dec = decode(enc); - } - test(bin, dec); - } - time = System.currentTimeMillis() - time; - System.out.println("fast=" + fast + " time=" + time); - } - - private static void test(byte[] in, byte[] out) { - if (in.length != out.length) { - throw new RuntimeException("Length error"); - } - for (int i = 0; i < in.length; i++) { - if (in[i] != out[i]) { - throw new RuntimeException("Error at " + i); - } - } - } - - private static byte[] encode(byte[] bin) { - byte[] code = CODE; - int size = bin.length; - int len = ((size + 2) / 3) * 4; - byte[] enc = new byte[len]; - int fast = size / 3 * 3, i = 0, j = 0; - for (; i < fast; i += 3, j += 4) { - int a = ((bin[i] & 255) << 16) + ((bin[i + 1] & 255) << 8) + (bin[i + 2] & 255); - enc[j] = code[a >> 18]; - enc[j + 1] = code[(a >> 12) & 63]; - enc[j + 2] = code[(a >> 6) & 63]; - enc[j + 3] = code[a & 63]; - } - if (i < size) { - int a = (bin[i++] & 255) << 16; - enc[j] = code[a >> 18]; - if (i < size) { - a += (bin[i] & 255) << 8; - enc[j + 2] = code[(a >> 6) & 63]; - } else { - enc[j + 2] = (byte) '='; - } - enc[j + 1] = code[(a >> 12) & 63]; - enc[j + 3] = (byte) '='; - } - return enc; - } - - private static byte[] encodeFast(byte[] bin) { - byte[] code = CODE; - int size = bin.length; - int len = ((size * 4) + 2) / 3; - byte[] enc = new byte[len]; - int fast = size / 3 * 3, i = 0, j = 0; - for (; i < fast; i += 3, j += 4) { - int a = ((bin[i] & 255) << 16) + ((bin[i + 1] & 255) << 8) + (bin[i + 2] & 255); - enc[j] = code[a >> 18]; - enc[j + 1] = code[(a >> 12) & 63]; - enc[j + 2] = code[(a >> 6) & 63]; - enc[j + 3] = code[a & 63]; - } - if (i < size) { - int a = (bin[i++] & 255) << 16; - enc[j] = code[a >> 18]; - if (i < size) { - a += (bin[i] & 255) << 8; - enc[j + 2] = code[(a >> 6) & 63]; - } - enc[j + 1] = code[(a >> 12) & 63]; - } - return enc; - } - - private static byte[] trim(byte[] enc) { - byte[] rev = REV; - int j = 0, size = enc.length; - if (size > 1 && enc[size - 2] == '=') { - size--; - } - if (size > 0 && enc[size - 1] == '=') { - size--; - } - for (int i = 0; i < size; i++) { - if (rev[enc[i] & 255] < 0) { - j++; - } - } - if (j == 0) { - return enc; - } - byte[] buff = new byte[size - j]; - for (int i = 0, k = 0; i < size; i++) { - int x = enc[i] & 255; - if (rev[x] >= 0) { - buff[k++] = (byte) x; - } - } - return buff; - } - - private static byte[] decode(byte[] enc) { - enc = trim(enc); - byte[] rev = REV; - int len = enc.length, size = (len * 3) / 4; - if (len > 0 && enc[len - 1] == '=') { - size--; - if (len > 1 && enc[len - 2] == '=') { - size--; - } - } - byte[] bin = new byte[size]; - int fast = size / 3 * 3, i = 0, j = 0; - for (; i < fast; i += 3, j += 4) { - int a = (rev[enc[j] & 255] << 18) + (rev[enc[j + 1] & 255] << 12) + - (rev[enc[j + 2] & 255] << 6) + rev[enc[j + 3] & 255]; - bin[i] = (byte) (a >> 16); - bin[i + 1] = (byte) (a >> 8); - bin[i + 2] = (byte) a; - } - if (i < size) { - int a = (rev[enc[j] & 255] << 10) + (rev[enc[j + 1] & 255] << 4); - bin[i++] = (byte) (a >> 8); - if (i < size) { - a += rev[enc[j + 2] & 255] >> 2; - bin[i] = (byte) a; - } - } - return bin; - } - - private static byte[] decodeFast(byte[] enc) { - byte[] rev = REV; - int len = enc.length, size = (len * 3) / 4; - byte[] bin = new byte[size]; - int fast = size / 3 * 3, i = 0, j = 0; - for (; i < fast; i += 3, j += 4) { - int a = (rev[enc[j] & 255] << 18) + (rev[enc[j + 1] & 255] << 12) + - (rev[enc[j + 2] & 255] << 6) + rev[enc[j + 3] & 255]; - bin[i] = (byte) (a >> 16); - bin[i + 1] = (byte) (a >> 8); - bin[i + 2] = (byte) a; - } - if (i < size) { - int a = (rev[enc[j] & 255] << 10) + (rev[enc[j + 1] & 255] << 4); - bin[i++] = (byte) (a >> 8); - if (i < size) { - a += rev[enc[j + 2] & 255] >> 2; - bin[i] = (byte) a; - } - } - return bin; - } - -} diff --git a/tools/h2/src/tools/org/h2/dev/util/FileViewer.java b/tools/h2/src/tools/org/h2/dev/util/FileViewer.java deleted file mode 100755 index fa3ac1f..0000000 --- a/tools/h2/src/tools/org/h2/dev/util/FileViewer.java +++ /dev/null @@ -1,209 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.dev.util; - -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.RandomAccessFile; -import java.sql.SQLException; -import java.util.ArrayList; - -import org.h2.message.DbException; -import org.h2.util.Tool; - - -/** - * A text file viewer that support very large files. - */ -public class FileViewer extends Tool { - - /** - * Run the viewer. - * - * @param args the command line arguments - */ - public static void main(String... args) throws SQLException { - new FileViewer().runTool(args); - } - - protected void showUsage() { - out.println("A text file viewer that support very large files."); - out.println("java "+getClass().getName() + "\n" + - " -file The name of the file to view\n" + - " [-find ] Find a string and display the next lines\n" + - " [-start ] Start at the given position\n" + - " [-head] Display the first lines\n" + - " [-tail] Display the last lines\n" + - " [-lines ] Display only x lines (default: 30)\n" + - " [-quiet] Do not print progress information"); - } - - public void runTool(String... args) throws SQLException { - String file = null; - String find = null; - boolean head = false, tail = false; - int lines = 30; - boolean quiet = false; - long start = 0; - for (int i = 0; args != null && i < args.length; i++) { - String arg = args[i]; - if (arg.equals("-file")) { - file = args[++i]; - } else if (arg.equals("-find")) { - find = args[++i]; - } else if (arg.equals("-start")) { - start = Long.decode(args[++i]).longValue(); - } else if (arg.equals("-head")) { - head = true; - } else if (arg.equals("-tail")) { - tail = true; - } else if (arg.equals("-lines")) { - lines = Integer.decode(args[++i]).intValue(); - } else if (arg.equals("-quiet")) { - quiet = true; - } else if (arg.equals("-help") || arg.equals("-?")) { - showUsage(); - return; - } else { - throwUnsupportedOption(arg); - } - } - if (file == null) { - showUsage(); - return; - } - if (!head && !tail && find == null) { - head = true; - } - try { - process(file, find, head, tail, start, lines, quiet); - } catch (IOException e) { - throw DbException.toSQLException(e); - } - } - - private void process(String fileName, String find, boolean head, boolean tail, long start, int lines, boolean quiet) throws IOException { - RandomAccessFile file = new RandomAccessFile(fileName, "r"); - long length = file.length(); - if (head) { - file.seek(start); - list(start, "Head", readLines(file, lines)); - } - if (find != null) { - file.seek(start); - long pos = find(file, find.getBytes(), quiet); - if (pos >= 0) { - file.seek(pos); - list(pos, "Found " + find, readLines(file, lines)); - } - } - if (tail) { - long pos = length - 100L * lines; - ArrayList list = null; - while (pos > 0) { - file.seek(pos); - list = readLines(file, Integer.MAX_VALUE); - if (list.size() > lines) { - break; - } - pos -= 100L * lines; - } - // remove the first (maybe partial) line - list.remove(0); - while (list.size() > lines) { - list.remove(0); - } - list(pos, "Tail", list); - } - } - - private long find(RandomAccessFile file, byte[] find, boolean quiet) throws IOException { - long pos = file.getFilePointer(); - long length = file.length(); - int bufferSize = 4 * 1024; - byte[] data = new byte[bufferSize * 2]; - long last = System.currentTimeMillis(); - while (pos < length) { - System.arraycopy(data, bufferSize, data, 0, bufferSize); - if (pos + bufferSize > length) { - file.readFully(data, bufferSize, (int) (length - pos)); - return find(data, find, (int) (bufferSize + length - pos - find.length)); - } - if (!quiet) { - long now = System.currentTimeMillis(); - if (now > last + 5000) { - System.out.println((100 * pos / length) + "%"); - last = now; - } - } - file.readFully(data, bufferSize, bufferSize); - int f = find(data, find, bufferSize); - if (f >= 0) { - return f + pos - bufferSize; - } - pos += bufferSize; - } - return -1; - } - - private int find(byte[] data, byte[] find, int max) { - outer: - for (int i = 0; i < max; i++) { - for (int j = 0; j < find.length; j++) { - if (data[i + j] != find[j]) { - continue outer; - } - } - return i; - } - return -1; - } - - private void list(long pos, String header, ArrayList list) { - System.out.println("-----------------------------------------------"); - System.out.println("[" + pos + "]: " + header); - System.out.println("-----------------------------------------------"); - for (String l : list) { - System.out.println(l); - } - System.out.println("-----------------------------------------------"); - } - - private ArrayList readLines(RandomAccessFile file, int maxLines) throws IOException { - ArrayList lines = new ArrayList(); - ByteArrayOutputStream buff = new ByteArrayOutputStream(100); - boolean lastNewline = false; - while (maxLines > 0) { - int x = file.read(); - if (x < 0) { - break; - } - if (x == '\r' || x == '\n') { - if (!lastNewline) { - maxLines--; - lastNewline = true; - byte[] data = buff.toByteArray(); - String s = new String(data); - lines.add(s); - buff.reset(); - } - continue; - } - if (lastNewline) { - lastNewline = false; - } - buff.write(x); - } - byte[] data = buff.toByteArray(); - if (data.length > 0) { - String s = new String(data); - lines.add(s); - } - return lines; - } - -} diff --git a/tools/h2/src/tools/org/h2/dev/util/Migrate.java b/tools/h2/src/tools/org/h2/dev/util/Migrate.java deleted file mode 100755 index 86d75a6..0000000 --- a/tools/h2/src/tools/org/h2/dev/util/Migrate.java +++ /dev/null @@ -1,239 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.dev.util; - -import java.io.BufferedInputStream; -import java.io.ByteArrayOutputStream; -import java.io.File; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.io.PrintStream; -import java.io.RandomAccessFile; -import java.net.URL; -import java.security.MessageDigest; -import java.security.NoSuchAlgorithmException; -import org.h2.tools.RunScript; - -/** - * Migrate a H2 database version 1.1.x (page store not enabled) to 1.2.x (page - * store format). This will download the H2 jar file version 1.2.127 from - * maven.org if it doesn't exist, execute the Script tool (using Runtime.exec) - * to create a backup.sql script, rename the old database file to *.backup, - * created a new database (using the H2 jar file in the class path) using the - * Script tool, and then delete the backup.sql file. Most utility methods are - * copied from h2/src/tools/org/h2/build/BuildBase.java. - */ -public class Migrate { - - private static final String USER = "sa"; - private static final String PASSWORD = "sa"; - private static final File OLD_H2_FILE = new File("./h2-1.2.127.jar"); - private static final String DOWNLOAD_URL = "http://repo2.maven.org/maven2/com/h2database/h2/1.2.127/h2-1.2.127.jar"; - private static final String CHECKSUM = "056e784c7cf009483366ab9cd8d21d02fe47031a"; - private static final String TEMP_SCRIPT = "backup.sql"; - private PrintStream sysOut = System.out; - private boolean quiet; - - /** - * Migrate databases. The user name and password are both "sa". - * - * @param args the path (default is the current directory) - * @throws Exception if conversion fails - */ - public static void main(String... args) throws Exception { - new Migrate().execute(new File(args.length == 1 ? args[0] : "."), true, USER, PASSWORD, false); - } - - /** - * Migrate a database. - * - * @param file the database file (must end with .data.db) or directory - * @param recursive if the file parameter is in fact a directory (in which - * case the directory is scanned recursively) - * @param user the user name of the database - * @param password the password - * @param runQuiet to run in quiet mode - * @throws Exception if conversion fails - */ - public void execute(File file, boolean recursive, String user, String password, boolean runQuiet) throws Exception { - String pathToJavaExe = getJavaExecutablePath(); - this.quiet = runQuiet; - if (file.isDirectory() && recursive) { - for (File f : file.listFiles()) { - execute(f, recursive, user, password, runQuiet); - } - return; - } - if (!file.getName().endsWith(".data.db")) { - return; - } - println("Migrating " + file.getName()); - if (!OLD_H2_FILE.exists()) { - download(OLD_H2_FILE.getAbsolutePath(), DOWNLOAD_URL, CHECKSUM); - } - String url = "jdbc:h2:" + file.getAbsolutePath(); - url = url.substring(0, url.length() - ".data.db".length()); - exec(new String[] { - pathToJavaExe, - "-Xmx128m", - "-cp", OLD_H2_FILE.getAbsolutePath(), - "org.h2.tools.Script", - "-script", TEMP_SCRIPT, - "-url", url, - "-user", user, - "-password", password - }); - file.renameTo(new File(file.getAbsoluteFile() + ".backup")); - RunScript.execute(url, user, password, TEMP_SCRIPT, "UTF-8", true); - new File(TEMP_SCRIPT).delete(); - } - - private String getJavaExecutablePath() { - String pathToJava; - if (File.separator.equals("\\")) { - pathToJava = System.getProperty("java.home") + File.separator + "bin" + File.separator + "java.exe"; - } else { - pathToJava = System.getProperty("java.home") + File.separator + "bin" + File.separator + "java"; - } - if (!new File(pathToJava).exists()) { - // Fallback to old behaviour - pathToJava = "java"; - } - return pathToJava; - } - - private void download(String target, String fileURL, String sha1Checksum) { - File targetFile = new File(target); - if (targetFile.exists()) { - return; - } - mkdirs(targetFile.getAbsoluteFile().getParentFile()); - ByteArrayOutputStream buff = new ByteArrayOutputStream(); - try { - println("Downloading " + fileURL); - URL url = new URL(fileURL); - InputStream in = new BufferedInputStream(url.openStream()); - long last = System.currentTimeMillis(); - int len = 0; - while (true) { - long now = System.currentTimeMillis(); - if (now > last + 1000) { - println("Downloaded " + len + " bytes"); - last = now; - } - int x = in.read(); - len++; - if (x < 0) { - break; - } - buff.write(x); - } - in.close(); - } catch (IOException e) { - throw new RuntimeException("Error downloading", e); - } - byte[] data = buff.toByteArray(); - String got = getSHA1(data); - if (sha1Checksum == null) { - println("SHA1 checksum: " + got); - } else { - if (!got.equals(sha1Checksum)) { - throw new RuntimeException("SHA1 checksum mismatch; got: " + got); - } - } - writeFile(targetFile, data); - } - - private void mkdirs(File f) { - if (!f.exists()) { - if (!f.mkdirs()) { - throw new RuntimeException("Can not create directory " + f.getAbsolutePath()); - } - } - } - - private void println(String s) { - if (!quiet) { - sysOut.println(s); - } - } - - private void print(String s) { - if (!quiet) { - sysOut.print(s); - } - } - - private String getSHA1(byte[] data) { - MessageDigest md; - try { - md = MessageDigest.getInstance("SHA-1"); - return convertBytesToString(md.digest(data)); - } catch (NoSuchAlgorithmException e) { - throw new RuntimeException(e); - } - } - - private String convertBytesToString(byte[] value) { - StringBuilder buff = new StringBuilder(value.length * 2); - for (byte c : value) { - int x = c & 0xff; - buff.append(Integer.toString(x >> 4, 16)). - append(Integer.toString(x & 0xf, 16)); - } - return buff.toString(); - } - - private static void writeFile(File file, byte[] data) { - try { - RandomAccessFile ra = new RandomAccessFile(file, "rw"); - ra.write(data); - ra.setLength(data.length); - ra.close(); - } catch (IOException e) { - throw new RuntimeException("Error writing to file " + file, e); - } - } - - private int exec(String[] command) { - try { - for (String c : command) { - print(c + " "); - } - println(""); - Process p = Runtime.getRuntime().exec(command); - copyInThread(p.getInputStream(), quiet ? null : sysOut); - copyInThread(p.getErrorStream(), quiet ? null : sysOut); - p.waitFor(); - return p.exitValue(); - } catch (Exception e) { - throw new RuntimeException(e); - } - } - - private void copyInThread(final InputStream in, final OutputStream out) { - new Thread() { - public void run() { - try { - while (true) { - int x = in.read(); - if (x < 0) { - return; - } - if (out != null) { - out.write(x); - } - } - } catch (Exception e) { - throw new RuntimeException(e); - } - } - } .start(); - } - -} diff --git a/tools/h2/src/tools/org/h2/dev/util/ReaderInputStream.java b/tools/h2/src/tools/org/h2/dev/util/ReaderInputStream.java deleted file mode 100755 index 6fa4976..0000000 --- a/tools/h2/src/tools/org/h2/dev/util/ReaderInputStream.java +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.dev.util; - -import java.io.BufferedWriter; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStreamWriter; -import java.io.Reader; -import java.io.UnsupportedEncodingException; -import java.io.Writer; -import org.h2.engine.Constants; -import org.h2.message.DbException; - -/** - * The reader input stream wraps a reader and convert the character to the UTF-8 - * format. - */ -public class ReaderInputStream extends InputStream { - - private final Reader reader; - private final char[] chars; - private final ByteArrayOutputStream out; - private final Writer writer; - private int pos; - private int remaining; - private byte[] buffer; - - public ReaderInputStream(Reader reader) { - chars = new char[Constants.IO_BUFFER_SIZE]; - this.reader = reader; - out = new ByteArrayOutputStream(Constants.IO_BUFFER_SIZE); - try { - writer = new BufferedWriter(new OutputStreamWriter(out, Constants.UTF8)); - } catch (UnsupportedEncodingException e) { - throw DbException.convert(e); - } - } - - private void fillBuffer() throws IOException { - if (remaining == 0) { - pos = 0; - remaining = reader.read(chars, 0, Constants.IO_BUFFER_SIZE); - if (remaining < 0) { - return; - } - writer.write(chars, 0, remaining); - writer.flush(); - buffer = out.toByteArray(); - remaining = buffer.length; - out.reset(); - } - } - - public int read() throws IOException { - if (remaining == 0) { - fillBuffer(); - } - if (remaining < 0) { - return -1; - } - remaining--; - return buffer[pos++] & 0xff; - } - -} diff --git a/tools/h2/src/tools/org/h2/dev/util/ThreadDumpFilter.java b/tools/h2/src/tools/org/h2/dev/util/ThreadDumpFilter.java deleted file mode 100755 index abd8caa..0000000 --- a/tools/h2/src/tools/org/h2/dev/util/ThreadDumpFilter.java +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.dev.util; - -import java.io.InputStreamReader; -import java.io.LineNumberReader; - -/** - * Filter full thread dumps from a log file. - */ -public class ThreadDumpFilter { - - /** - * Usage: java ThreadDumpFilter threadDump.txt - * @param a ignored - */ - public static void main(String... a) throws Exception { - LineNumberReader in = new LineNumberReader(new InputStreamReader(System.in)); - for (String s; (s = in.readLine()) != null;) { - if (s.startsWith("Full thread")) { - do { - System.out.println(s); - s = in.readLine(); - } while(s != null && (s.length() == 0 || " \t\"".indexOf(s.charAt(0)) >= 0)); - } - } - } -} diff --git a/tools/h2/src/tools/org/h2/dev/util/package.html b/tools/h2/src/tools/org/h2/dev/util/package.html deleted file mode 100755 index a21255c..0000000 --- a/tools/h2/src/tools/org/h2/dev/util/package.html +++ /dev/null @@ -1,15 +0,0 @@ - - - - -Javadoc package documentation -

    - -Utility classes that are currently not used in the database engine. - -

    \ No newline at end of file diff --git a/tools/h2/src/tools/org/h2/jaqu/CompareType.java b/tools/h2/src/tools/org/h2/jaqu/CompareType.java deleted file mode 100755 index 7421cca..0000000 --- a/tools/h2/src/tools/org/h2/jaqu/CompareType.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.jaqu; - -/** - * An enumeration of compare operations. - */ -//## Java 1.5 begin ## -enum CompareType { - EQUAL("=", true), - BIGGER(">", true), - BIGGER_EQUAL(">=", true), - SMALLER("<", true), - SMALLER_EQUAL("<=", true), - NOT_EQUAL("<>", true), - IS_NOT_NULL("IS NOT NULL", false), - IS_NULL("IS NULL", false), - LIKE("LIKE", true); - - private String text; - private boolean hasRightExpression; - - CompareType(String text, boolean hasRightExpression) { - this.text = text; - this.hasRightExpression = hasRightExpression; - } - - String getString() { - return text; - } - - boolean hasRightExpression() { - return hasRightExpression; - } - -} -//## Java 1.5 end ## - diff --git a/tools/h2/src/tools/org/h2/jaqu/Condition.java b/tools/h2/src/tools/org/h2/jaqu/Condition.java deleted file mode 100755 index 542c3da..0000000 --- a/tools/h2/src/tools/org/h2/jaqu/Condition.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.jaqu; - -/** - * A condition contains one or two operands and a compare operation. - * - * @param the operand type - */ -//## Java 1.5 begin ## -class Condition implements Token { - CompareType compareType; - A x, y; - - Condition(A x, A y, CompareType compareType) { - this.compareType = compareType; - this.x = x; - this.y = y; - } - - public void appendSQL(SQLStatement stat, Query query) { - query.appendSQL(stat, x); - stat.appendSQL(" "); - stat.appendSQL(compareType.getString()); - if (compareType.hasRightExpression()) { - stat.appendSQL(" "); - query.appendSQL(stat, y); - } - } -} -//## Java 1.5 end ## diff --git a/tools/h2/src/tools/org/h2/jaqu/ConditionAndOr.java b/tools/h2/src/tools/org/h2/jaqu/ConditionAndOr.java deleted file mode 100755 index a0fc0d7..0000000 --- a/tools/h2/src/tools/org/h2/jaqu/ConditionAndOr.java +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.jaqu; - -/** - * An OR or an AND condition. - */ -//## Java 1.5 begin ## -enum ConditionAndOr implements Token { - AND("AND"), - OR("OR"); - - private String text; - - ConditionAndOr(String text) { - this.text = text; - } - - public void appendSQL(SQLStatement stat, Query query) { - stat.appendSQL(text); - } - -} -//## Java 1.5 end ## diff --git a/tools/h2/src/tools/org/h2/jaqu/Db.java b/tools/h2/src/tools/org/h2/jaqu/Db.java deleted file mode 100755 index 7b07637..0000000 --- a/tools/h2/src/tools/org/h2/jaqu/Db.java +++ /dev/null @@ -1,194 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.jaqu; - -//## Java 1.5 begin ## -import java.sql.Connection; -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.sql.Statement; -import java.util.List; -import java.util.Map; -import java.util.Properties; - -import org.h2.jaqu.util.Utils; -import org.h2.jaqu.util.WeakIdentityHashMap; -import org.h2.util.JdbcUtils; -//## Java 1.5 end ## - -/** - * This class represents a connection to a database. - */ -//## Java 1.5 begin ## -public class Db { - - private static final WeakIdentityHashMap TOKENS = - Utils.newWeakIdentityHashMap(); - - private final Connection conn; - private final Map, TableDefinition< ? >> classMap = - Utils.newHashMap(); - - Db(Connection conn) { - this.conn = conn; - } - - static X registerToken(X x, Token token) { - TOKENS.put(x, token); - return x; - } - - static Token getToken(Object x) { - return TOKENS.get(x); - } - - private static T instance(Class clazz) { - try { - return clazz.newInstance(); - } catch (Exception e) { - throw new RuntimeException(e); - } - } - - public static Db open(String url, String user, String password) { - try { - Connection conn = JdbcUtils.getConnection(null, url, user, password); - return new Db(conn); - } catch (SQLException e) { - throw convert(e); - } - } - - public static Db open(String url, String user, char[] password) { - try { - Properties prop = new Properties(); - prop.setProperty("user", user); - prop.put("password", password); - Connection conn = JdbcUtils.getConnection(null, url, prop); - return new Db(conn); - } catch (SQLException e) { - throw convert(e); - } - } - - private static Error convert(Exception e) { - return new Error(e); - } - - public void insert(T t) { - Class< ? > clazz = t.getClass(); - define(clazz).createTableIfRequired(this).insert(this, t); - } - - public void merge(T t) { - Class< ? > clazz = t.getClass(); - define(clazz).createTableIfRequired(this).merge(this, t); - } - - public void update(T t) { - Class< ? > clazz = t.getClass(); - define(clazz).createTableIfRequired(this).update(this, t); - } - - public Query from(T alias) { - Class< ? > clazz = alias.getClass(); - define(clazz).createTableIfRequired(this); - return Query.from(this, alias); - } - - void createTable(Class clazz) { - define(clazz).createTableIfRequired(this); - } - - TableDefinition define(Class clazz) { - TableDefinition def = getTableDefinition(clazz); - if (def == null) { - def = new TableDefinition(clazz); - def.mapFields(); - classMap.put(clazz, def); - if (Table.class.isAssignableFrom(clazz)) { - T t = instance(clazz); - Table table = (Table) t; - Define.define(def, table); - } - } - return def; - } - - public void close() { - try { - conn.close(); - } catch (Exception e) { - throw new RuntimeException(e); - } - } - - public TestCondition test(A x) { - return new TestCondition(x); - } - - public void insertAll(List list) { - for (T t : list) { - insert(t); - } - } - - PreparedStatement prepare(String sql) { - try { - return conn.prepareStatement(sql); - } catch (SQLException e) { - throw new RuntimeException(e); - } - } - - @SuppressWarnings("unchecked") - TableDefinition getTableDefinition(Class clazz) { - return (TableDefinition) classMap.get(clazz); - } - - /** - * Run a SQL query directly against the database. - * - * @param sql the SQL statement - * @return the result set - */ - public ResultSet executeQuery(String sql) { - try { - return conn.createStatement().executeQuery(sql); - } catch (SQLException e) { - throw new RuntimeException(e); - } - } - - /** - * Run a SQL statement directly against the database. - * - * @param sql the SQL statement - * @return the update count - */ - public int executeUpdate(String sql) { - try { - Statement stat = conn.createStatement(); - int updateCount = stat.executeUpdate(sql); - stat.close(); - return updateCount; - } catch (SQLException e) { - throw new RuntimeException(e); - } - } - -// FieldDefinition getFieldDefinition(X x) { -// return aliasMap.get(x).getFieldDefinition(); -// } -// -// SelectColumn getSelectColumn(X x) { -// return aliasMap.get(x); -// } - -} -//## Java 1.5 end ## diff --git a/tools/h2/src/tools/org/h2/jaqu/Define.java b/tools/h2/src/tools/org/h2/jaqu/Define.java deleted file mode 100755 index 22746e6..0000000 --- a/tools/h2/src/tools/org/h2/jaqu/Define.java +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.jaqu; - -/** - * This class provides utility methods to define primary keys, indexes, and set - * the name of the table. - */ -//## Java 1.5 begin ## -public class Define { - - private static TableDefinition< ? > currentTableDefinition; - private static Table currentTable; - - public static void primaryKey(Object... columns) { - checkInDefine(); - currentTableDefinition.setPrimaryKey(columns); - } - - public static void index(Object... columns) { - checkInDefine(); - currentTableDefinition.addIndex(columns); - } - - public static void maxLength(Object column, int length) { - checkInDefine(); - currentTableDefinition.setMaxLength(column, length); - } - - public static void tableName(String tableName) { - currentTableDefinition.setTableName(tableName); - } - - static synchronized void define(TableDefinition tableDefinition, - Table table) { - currentTableDefinition = tableDefinition; - currentTable = table; - tableDefinition.mapObject(table); - table.define(); - currentTable = null; - } - - private static void checkInDefine() { - if (currentTable == null) { - throw new RuntimeException("This method may only be called " + - "from within the define() method, and the define() method " + - "is called by the framework."); - } - } - -} -//## Java 1.5 end ## diff --git a/tools/h2/src/tools/org/h2/jaqu/Filter.java b/tools/h2/src/tools/org/h2/jaqu/Filter.java deleted file mode 100755 index 1ae4cf9..0000000 --- a/tools/h2/src/tools/org/h2/jaqu/Filter.java +++ /dev/null @@ -1,14 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.jaqu; - -/** - * Represents the WHERE clause of a query. - */ -public interface Filter { - boolean where(); -} diff --git a/tools/h2/src/tools/org/h2/jaqu/Function.java b/tools/h2/src/tools/org/h2/jaqu/Function.java deleted file mode 100755 index d47bced..0000000 --- a/tools/h2/src/tools/org/h2/jaqu/Function.java +++ /dev/null @@ -1,152 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.jaqu; - -//## Java 1.5 begin ## -import org.h2.jaqu.util.Utils; -//## Java 1.5 end ## - -/** - * This class provides static methods that represents common SQL functions. - */ -public class Function implements Token { -//## Java 1.5 begin ## - - // must be a new instance - private static final Long COUNT_STAR = new Long(0); - - protected Object[] x; - private String name; - - protected Function(String name, Object... x) { - this.name = name; - this.x = x; - } - - public void appendSQL(SQLStatement stat, Query query) { - stat.appendSQL(name).appendSQL("("); - int i = 0; - for (Object o : x) { - if (i++ > 0) { - stat.appendSQL(","); - } - query.appendSQL(stat, o); - } - stat.appendSQL(")"); - } - - public static Long count() { - return COUNT_STAR; - } - - public static Integer length(Object x) { - return Db.registerToken( - Utils.newObject(Integer.class), new Function("LENGTH", x)); - } - - @SuppressWarnings("unchecked") - public static T sum(T x) { - return (T) Db.registerToken( - Utils.newObject(x.getClass()), new Function("SUM", x)); - } - - public static Long count(Object x) { - return Db.registerToken( - Utils.newObject(Long.class), new Function("COUNT", x)); - } - - public static Boolean isNull(Object x) { - return Db.registerToken( - Utils.newObject(Boolean.class), new Function("", x) { - public void appendSQL(SQLStatement stat, Query query) { - query.appendSQL(stat, x[0]); - stat.appendSQL(" IS NULL"); - } - }); - } - - public static Boolean isNotNull(Object x) { - return Db.registerToken( - Utils.newObject(Boolean.class), new Function("", x) { - public void appendSQL(SQLStatement stat, Query query) { - query.appendSQL(stat, x[0]); - stat.appendSQL(" IS NOT NULL"); - } - }); - } - - public static Boolean not(Boolean x) { - return Db.registerToken( - Utils.newObject(Boolean.class), new Function("", x) { - public void appendSQL(SQLStatement stat, Query query) { - stat.appendSQL("NOT "); - query.appendSQL(stat, x[0]); - } - }); - } - - public static Boolean or(Boolean... x) { - return Db.registerToken( - Utils.newObject(Boolean.class), - new Function("", (Object[]) x) { - public void appendSQL(SQLStatement stat, Query query) { - int i = 0; - for (Object o : x) { - if (i++ > 0) { - stat.appendSQL(" OR "); - } - query.appendSQL(stat, o); - } - } - }); - } - - public static Boolean and(Boolean... x) { - return Db.registerToken( - Utils.newObject(Boolean.class), - new Function("", (Object[]) x) { - public void appendSQL(SQLStatement stat, Query query) { - int i = 0; - for (Object o : x) { - if (i++ > 0) { - stat.appendSQL(" AND "); - } - query.appendSQL(stat, o); - } - } - }); - } - - @SuppressWarnings("unchecked") - public static X min(X x) { - Class clazz = (Class) x.getClass(); - X o = Utils.newObject(clazz); - return Db.registerToken(o, new Function("MIN", x)); - } - - @SuppressWarnings("unchecked") - public static X max(X x) { - Class clazz = (Class) x.getClass(); - X o = Utils.newObject(clazz); - return Db.registerToken(o, new Function("MAX", x)); - } - - public static Boolean like(String x, String pattern) { - Boolean o = Utils.newObject(Boolean.class); - return Db.registerToken(o, new Function("LIKE", x, pattern) { - public void appendSQL(SQLStatement stat, Query query) { - stat.appendSQL("("); - query.appendSQL(stat, x[0]); - stat.appendSQL(" LIKE "); - query.appendSQL(stat, x[1]); - stat.appendSQL(")"); - } - }); - } - -//## Java 1.5 end ## -} diff --git a/tools/h2/src/tools/org/h2/jaqu/OrderExpression.java b/tools/h2/src/tools/org/h2/jaqu/OrderExpression.java deleted file mode 100755 index e7808f9..0000000 --- a/tools/h2/src/tools/org/h2/jaqu/OrderExpression.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.jaqu; - -/** - * An expression to order by in a query. - * - * @param the query data type - */ -//## Java 1.5 begin ## -class OrderExpression { - private Query query; - private Object expression; - private boolean desc; - private boolean nullsFirst; - private boolean nullsLast; - - OrderExpression(Query query, Object expression, boolean desc, - boolean nullsFirst, boolean nullsLast) { - this.query = query; - this.expression = expression; - this.desc = desc; - this.nullsFirst = nullsFirst; - this.nullsLast = nullsLast; - } - - void appendSQL(SQLStatement stat) { - query.appendSQL(stat, expression); - if (desc) { - stat.appendSQL(" DESC"); - } - if (nullsLast) { - stat.appendSQL(" NULLS LAST"); - } - if (nullsFirst) { - stat.appendSQL(" NULLS FIRST"); - } - } - -} -//## Java 1.5 end ## diff --git a/tools/h2/src/tools/org/h2/jaqu/Query.java b/tools/h2/src/tools/org/h2/jaqu/Query.java deleted file mode 100755 index 49e6972..0000000 --- a/tools/h2/src/tools/org/h2/jaqu/Query.java +++ /dev/null @@ -1,357 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.jaqu; - -//## Java 1.5 begin ## -import java.lang.reflect.Field; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.IdentityHashMap; -import java.util.List; -import org.h2.jaqu.bytecode.ClassReader; -import org.h2.jaqu.util.Utils; -import org.h2.util.JdbcUtils; -import org.h2.util.New; -//## Java 1.5 end ## - -/** - * This class represents a query. - * - * @param the return type - */ -//## Java 1.5 begin ## -public class Query { - - private Db db; - private SelectTable from; - private ArrayList conditions = Utils.newArrayList(); - private ArrayList> joins = Utils.newArrayList(); - private final IdentityHashMap> aliasMap = Utils.newIdentityHashMap(); - private ArrayList> orderByList = Utils.newArrayList(); - private Object[] groupByExpressions; - - Query(Db db) { - this.db = db; - } - - @SuppressWarnings("unchecked") - static Query from(Db db, T alias) { - Query query = new Query(db); - TableDefinition def = (TableDefinition) db.define(alias.getClass()); - query.from = new SelectTable(db, query, alias, false); - def.initSelectObject(query.from, alias, query.aliasMap); - return query; - } - - public long selectCount() { - SQLStatement selectList = new SQLStatement(db); - selectList.setSQL("COUNT(*)"); - ResultSet rs = prepare(selectList, false).executeQuery(); - try { - rs.next(); - long value = rs.getLong(1); - return value; - } catch (SQLException e) { - throw new RuntimeException(e); - } finally { - JdbcUtils.closeSilently(rs); - } - } - - public List select() { - return select(false); - } - - public T selectFirst() { - return select(false).get(0); - } - - public List selectDistinct() { - return select(true); - } - - @SuppressWarnings("unchecked") - public X selectFirst(Z x) { - List list = (List) select(x); - return list.isEmpty() ? null : list.get(0); - } - - public String getSQL() { - SQLStatement selectList = new SQLStatement(db); - selectList.setSQL("*"); - return prepare(selectList, false).getSQL().trim(); - } - - private List select(boolean distinct) { - List result = Utils.newArrayList(); - TableDefinition def = from.getAliasDefinition(); - SQLStatement selectList = def.getSelectList(db); - ResultSet rs = prepare(selectList, distinct).executeQuery(); - try { - while (rs.next()) { - T item = from.newObject(); - from.getAliasDefinition().readRow(item, rs); - result.add(item); - } - } catch (SQLException e) { - throw new RuntimeException(e); - } finally { - JdbcUtils.closeSilently(rs); - } - return result; - } - - public int delete() { - SQLStatement stat = new SQLStatement(db); - stat.appendSQL("DELETE FROM "); - from.appendSQL(stat); - appendWhere(stat); - return stat.executeUpdate(); - } - - public List selectDistinct(Z x) { - return select(x, true); - } - - public List select(Z x) { - return select(x, false); - } - - @SuppressWarnings("unchecked") - private List select(Z x, boolean distinct) { - Class< ? > clazz = x.getClass(); - if (Utils.isSimpleType(clazz)) { - return getSimple((X) x, distinct); - } - clazz = clazz.getSuperclass(); - return select((Class) clazz, (X) x, distinct); - } - - private List select(Class clazz, X x, boolean distinct) { - List result = Utils.newArrayList(); - TableDefinition def = db.define(clazz); - SQLStatement selectList = def.getSelectList(this, x); - ResultSet rs = prepare(selectList, distinct).executeQuery(); - try { - while (rs.next()) { - X row = Utils.newObject(clazz); - def.readRow(row, rs); - result.add(row); - } - } catch (SQLException e) { - throw new RuntimeException(e); - } finally { - JdbcUtils.closeSilently(rs); - } - return result; - } - - @SuppressWarnings("unchecked") - private List getSimple(X x, boolean distinct) { - SQLStatement selectList = new SQLStatement(db); - appendSQL(selectList, x); - ResultSet rs = prepare(selectList, distinct).executeQuery(); - List result = Utils.newArrayList(); - try { - while (rs.next()) { - try { - X value = (X) rs.getObject(1); - result.add(value); - } catch (Exception e) { - throw new RuntimeException(e); - } - } - } catch (SQLException e) { - throw new RuntimeException(e); - } finally { - JdbcUtils.closeSilently(rs); - } - return result; - } - - public QueryCondition where(A x) { - return new QueryCondition(this, x); - } - - public QueryWhere where(Filter filter) { - HashMap fieldMap = New.hashMap(); - for (Field f : filter.getClass().getDeclaredFields()) { - f.setAccessible(true); - try { - Object obj = f.get(filter); - if (obj == from.getAlias()) { - List fields = from.getAliasDefinition().getFields(); - String name = f.getName(); - for (TableDefinition.FieldDefinition field : fields) { - String n = name + "." + field.field.getName(); - Object o = field.field.get(obj); - fieldMap.put(n, o); - } - } - fieldMap.put(f.getName(), f.get(filter)); - } catch (Exception e) { - throw new RuntimeException(e); - } - } - Token filterCode = new ClassReader().decompile(filter, fieldMap, "where"); - // String filterQuery = filterCode.toString(); - conditions.add(filterCode); - return new QueryWhere(this); - } - - public QueryWhere whereTrue(Boolean condition) { - Token token = new Function("", condition); - addConditionToken(token); - return new QueryWhere(this); - } -//## Java 1.5 end ## - - /** - * Order by a number of columns. - * - * @param expressions the columns - * @return the query - */ -//## Java 1.5 begin ## - public Query orderBy(Object... expressions) { - for (Object expr : expressions) { - OrderExpression e = - new OrderExpression(this, expr, false, false, false); - addOrderBy(e); - } - return this; - } - - public Query orderByDesc(Object expr) { - OrderExpression e = - new OrderExpression(this, expr, true, false, false); - addOrderBy(e); - return this; - } - - public Query groupBy(Object... groupBy) { - this.groupByExpressions = groupBy; - return this; - } - - /** - * INTERNAL - * - * @param stat the statement - * @param x the alias object - */ - public void appendSQL(SQLStatement stat, Object x) { - if (x == Function.count()) { - stat.appendSQL("COUNT(*)"); - return; - } - Token token = Db.getToken(x); - if (token != null) { - token.appendSQL(stat, this); - return; - } - SelectColumn col = aliasMap.get(x); - if (col != null) { - col.appendSQL(stat); - return; - } - stat.appendSQL("?"); - stat.addParameter(x); - } - - void addConditionToken(Token condition) { - conditions.add(condition); - } - - void appendWhere(SQLStatement stat) { - if (!conditions.isEmpty()) { - stat.appendSQL(" WHERE "); - for (Token token : conditions) { - token.appendSQL(stat, this); - stat.appendSQL(" "); - } - } - } - - @SuppressWarnings("unchecked") - SQLStatement prepare(SQLStatement selectList, boolean distinct) { - SQLStatement stat = selectList; - String selectSQL = stat.getSQL(); - stat.setSQL(""); - stat.appendSQL("SELECT "); - if (distinct) { - stat.appendSQL("DISTINCT "); - } - stat.appendSQL(selectSQL); - stat.appendSQL(" FROM "); - from.appendSQL(stat); - for (SelectTable join : joins) { - join.appendSQLAsJoin(stat, this); - } - appendWhere(stat); - if (groupByExpressions != null) { - stat.appendSQL(" GROUP BY "); - int i = 0; - for (Object obj : groupByExpressions) { - if (i++ > 0) { - stat.appendSQL(", "); - } - appendSQL(stat, obj); - stat.appendSQL(" "); - } - } - if (!orderByList.isEmpty()) { - stat.appendSQL(" ORDER BY "); - int i = 0; - for (OrderExpression o : orderByList) { - if (i++ > 0) { - stat.appendSQL(", "); - } - o.appendSQL(stat); - stat.appendSQL(" "); - } - } - return stat; - } -//## Java 1.5 end ## - - /** - * Join another table. - * - * @param alias an alias for the table to join - * @return the joined query - */ -//## Java 1.5 begin ## - @SuppressWarnings("unchecked") - public QueryJoin innerJoin(U alias) { - TableDefinition def = (TableDefinition) db.define(alias.getClass()); - SelectTable join = new SelectTable(db, this, alias, false); - def.initSelectObject(join, alias, aliasMap); - joins.add(join); - return new QueryJoin(this, join); - } - - Db getDb() { - return db; - } - - boolean isJoin() { - return !joins.isEmpty(); - } - - SelectColumn getSelectColumn(Object obj) { - return aliasMap.get(obj); - } - - void addOrderBy(OrderExpression expr) { - orderByList.add(expr); - } - -} -//## Java 1.5 end ## diff --git a/tools/h2/src/tools/org/h2/jaqu/QueryCondition.java b/tools/h2/src/tools/org/h2/jaqu/QueryCondition.java deleted file mode 100755 index bd982e1..0000000 --- a/tools/h2/src/tools/org/h2/jaqu/QueryCondition.java +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.jaqu; - -/** - * This class represents a query with an incomplete condition. - * - * @param the return type of the query - * @param the incomplete condition data type - */ -//## Java 1.5 begin ## -public class QueryCondition { - - private Query query; - private A x; - - QueryCondition(Query query, A x) { - this.query = query; - this.x = x; - } - - public QueryWhere is(A y) { - query.addConditionToken( - new Condition(x, y, CompareType.EQUAL)); - return new QueryWhere(query); - } - - public QueryWhere bigger(A y) { - query.addConditionToken( - new Condition(x, y, CompareType.BIGGER)); - return new QueryWhere(query); - } - - public QueryWhere biggerEqual(A y) { - query.addConditionToken( - new Condition(x, y, CompareType.BIGGER_EQUAL)); - return new QueryWhere(query); - } - - public QueryWhere smaller(A y) { - query.addConditionToken( - new Condition(x, y, CompareType.SMALLER)); - return new QueryWhere(query); - } - - public QueryWhere smallerEqual(A y) { - query.addConditionToken( - new Condition(x, y, CompareType.SMALLER_EQUAL)); - return new QueryWhere(query); - } - - public QueryWhere like(A pattern) { - query.addConditionToken( - new Condition(x, pattern, CompareType.LIKE)); - return new QueryWhere(query); - } - -} -//## Java 1.5 end ## diff --git a/tools/h2/src/tools/org/h2/jaqu/QueryJoin.java b/tools/h2/src/tools/org/h2/jaqu/QueryJoin.java deleted file mode 100755 index b72d405..0000000 --- a/tools/h2/src/tools/org/h2/jaqu/QueryJoin.java +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.jaqu; - -/** - * This class represents a query with a join. - */ -//## Java 1.5 begin ## -public class QueryJoin { - - private Query< ? > query; - private SelectTable< ? > join; - - QueryJoin(Query< ? > query, SelectTable< ? > join) { - this.query = query; - this.join = join; - } - - public QueryJoinCondition on(A x) { - return new QueryJoinCondition(query, join, x); - } -} -//## Java 1.5 end ## diff --git a/tools/h2/src/tools/org/h2/jaqu/QueryJoinCondition.java b/tools/h2/src/tools/org/h2/jaqu/QueryJoinCondition.java deleted file mode 100755 index cba0963..0000000 --- a/tools/h2/src/tools/org/h2/jaqu/QueryJoinCondition.java +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.jaqu; - -/** - * This class represents a query with join and an incomplete condition. - * - * @param the incomplete condition data type - */ -//## Java 1.5 begin ## -public class QueryJoinCondition { - - private Query< ? > query; - private SelectTable< ? > join; - private A x; - - QueryJoinCondition(Query< ? > query, SelectTable< ? > join, A x) { - this.query = query; - this.join = join; - this.x = x; - } - - public Query< ? > is(A y) { - join.addConditionToken(new Condition(x, y, CompareType.EQUAL)); - return query; - } -} -//## Java 1.5 end ## diff --git a/tools/h2/src/tools/org/h2/jaqu/QueryWhere.java b/tools/h2/src/tools/org/h2/jaqu/QueryWhere.java deleted file mode 100755 index 5258223..0000000 --- a/tools/h2/src/tools/org/h2/jaqu/QueryWhere.java +++ /dev/null @@ -1,131 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.jaqu; - -//## Java 1.5 begin ## -import java.util.List; -//## Java 1.5 end ## - -/** - * This class represents a query with a condition. - * - * @param the return type - */ -//## Java 1.5 begin ## -public class QueryWhere { - - Query query; - - QueryWhere(Query query) { - this.query = query; - } - - public QueryCondition and(A x) { - query.addConditionToken(ConditionAndOr.AND); - return new QueryCondition(query, x); - } - - public QueryCondition or(A x) { - query.addConditionToken(ConditionAndOr.OR); - return new QueryCondition(query, x); - } - - public List select(Z x) { - return query.select(x); - } - - public String getSQL() { - SQLStatement selectList = new SQLStatement(query.getDb()); - selectList.appendSQL("*"); - return query.prepare(selectList, false).getSQL().trim(); - } - - public List selectDistinct(Z x) { - return query.selectDistinct(x); - } - - public X selectFirst(Z x) { - List list = query.select(x); - return list.isEmpty() ? null : list.get(0); - } - - public List select() { - return query.select(); - } - - public T selectFirst() { - List list = select(); - return list.isEmpty() ? null : list.get(0); - } - - public List selectDistinct() { - return query.selectDistinct(); - } - -//## Java 1.5 end ## - - /** - * Order by a number of columns. - * - * @param expressions the order by expressions - * @return the query - */ -//## Java 1.5 begin ## - public QueryWhere orderBy(Object... expressions) { - for (Object expr : expressions) { - OrderExpression e = - new OrderExpression(query, expr, false, false, false); - query.addOrderBy(e); - } - return this; - } - - public QueryWhere orderByNullsFirst(Object expr) { - OrderExpression e = - new OrderExpression(query, expr, false, true, false); - query.addOrderBy(e); - return this; - } - - public QueryWhere orderByNullsLast(Object expr) { - OrderExpression e = - new OrderExpression(query, expr, false, false, true); - query.addOrderBy(e); - return this; - } - - public QueryWhere orderByDesc(Object expr) { - OrderExpression e = - new OrderExpression(query, expr, true, false, false); - query.addOrderBy(e); - return this; - } - - public QueryWhere orderByDescNullsFirst(Object expr) { - OrderExpression e = - new OrderExpression(query, expr, true, true, false); - query.addOrderBy(e); - return this; - } - - public QueryWhere orderByDescNullsLast(Object expr) { - OrderExpression e = - new OrderExpression(query, expr, true, false, true); - query.addOrderBy(e); - return this; - } - - public int delete() { - return query.delete(); - } - - public long selectCount() { - return query.selectCount(); - } - -} -//## Java 1.5 end ## diff --git a/tools/h2/src/tools/org/h2/jaqu/SQLStatement.java b/tools/h2/src/tools/org/h2/jaqu/SQLStatement.java deleted file mode 100755 index 17e03b7..0000000 --- a/tools/h2/src/tools/org/h2/jaqu/SQLStatement.java +++ /dev/null @@ -1,87 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.jaqu; - -//## Java 1.5 begin ## -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.util.ArrayList; -//## Java 1.5 end ## - -/** - * This class represents a parameterized SQL statement. - */ -//## Java 1.5 begin ## -public class SQLStatement { - private Db db; - private StringBuilder buff = new StringBuilder(); - private String sql; - private ArrayList params = new ArrayList(); - - SQLStatement(Db db) { - this.db = db; - } - - void setSQL(String sql) { - this.sql = sql; - buff = new StringBuilder(sql); - } - - public SQLStatement appendSQL(String s) { - buff.append(s); - sql = null; - return this; - } - - String getSQL() { - if (sql == null) { - sql = buff.toString(); - } - return sql; - } - - SQLStatement addParameter(Object o) { - params.add(o); - return this; - } - - ResultSet executeQuery() { - try { - return prepare().executeQuery(); - } catch (SQLException e) { - throw new RuntimeException(e); - } - } - - int executeUpdate() { - try { - return prepare().executeUpdate(); - } catch (SQLException e) { - throw new RuntimeException(e); - } - } - - private void setValue(PreparedStatement prep, int parameterIndex, Object x) { - try { - prep.setObject(parameterIndex, x); - } catch (SQLException e) { - throw new RuntimeException(e); - } - } - - private PreparedStatement prepare() { - PreparedStatement prep = db.prepare(getSQL()); - for (int i = 0; i < params.size(); i++) { - Object o = params.get(i); - setValue(prep, i + 1, o); - } - return prep; - } - -} -//## Java 1.5 end ## diff --git a/tools/h2/src/tools/org/h2/jaqu/SelectColumn.java b/tools/h2/src/tools/org/h2/jaqu/SelectColumn.java deleted file mode 100755 index 7a3e796..0000000 --- a/tools/h2/src/tools/org/h2/jaqu/SelectColumn.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.jaqu; - -//## Java 1.5 begin ## -import org.h2.jaqu.TableDefinition.FieldDefinition; -//## Java 1.5 end ## - -/** - * This class represents a column of a table in a query. - * - * @param the table data type - */ -//## Java 1.5 begin ## -class SelectColumn { - private SelectTable selectTable; - private FieldDefinition fieldDef; - - SelectColumn(SelectTable table, FieldDefinition fieldDef) { - this.selectTable = table; - this.fieldDef = fieldDef; - } - - void appendSQL(SQLStatement stat) { - if (selectTable.getQuery().isJoin()) { - stat.appendSQL(selectTable.getAs() + "." + fieldDef.columnName); - } else { - stat.appendSQL(fieldDef.columnName); - } - } - - FieldDefinition getFieldDefinition() { - return fieldDef; - } - - SelectTable getSelectTable() { - return selectTable; - } - - Object getCurrentValue() { - return fieldDef.getValue(selectTable.getCurrent()); - } -} -//## Java 1.5 end ## diff --git a/tools/h2/src/tools/org/h2/jaqu/SelectTable.java b/tools/h2/src/tools/org/h2/jaqu/SelectTable.java deleted file mode 100755 index bb9c4e8..0000000 --- a/tools/h2/src/tools/org/h2/jaqu/SelectTable.java +++ /dev/null @@ -1,105 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.jaqu; - -//## Java 1.5 begin ## -import java.util.ArrayList; - -import org.h2.jaqu.util.ClassUtils; -import org.h2.jaqu.util.Utils; -//## Java 1.5 end ## - -/** - * This class represents a table in a query. - * - * @param the table class - */ -//## Java 1.5 begin ## -class SelectTable { - - private static int asCounter; - private Query query; - private Class clazz; - private T current; - private String as; - private TableDefinition aliasDef; - private boolean outerJoin; - private ArrayList joinConditions = Utils.newArrayList(); - private T alias; - - @SuppressWarnings("unchecked") - SelectTable(Db db, Query query, T alias, boolean outerJoin) { - this.alias = alias; - this.query = query; - this.outerJoin = outerJoin; - aliasDef = (TableDefinition) db.getTableDefinition(alias.getClass()); - clazz = ClassUtils.getClass(alias); - as = "T" + asCounter++; - } - - T getAlias() { - return alias; - } - - T newObject() { - return Utils.newObject(clazz); - } - - TableDefinition getAliasDefinition() { - return aliasDef; - } - - void appendSQL(SQLStatement stat) { - if (query.isJoin()) { - stat.appendSQL(aliasDef.tableName + " AS " + as); - } else { - stat.appendSQL(aliasDef.tableName); - } - } - - void appendSQLAsJoin(SQLStatement stat, Query q) { - if (outerJoin) { - stat.appendSQL(" LEFT OUTER JOIN "); - } else { - stat.appendSQL(" INNER JOIN "); - } - appendSQL(stat); - if (!joinConditions.isEmpty()) { - stat.appendSQL(" ON "); - for (Token token : joinConditions) { - token.appendSQL(stat, q); - stat.appendSQL(" "); - } - } - } - - boolean getOuterJoin() { - return outerJoin; - } - - Query getQuery() { - return query; - } - - String getAs() { - return as; - } - - void addConditionToken(Token condition) { - joinConditions.add(condition); - } - - T getCurrent() { - return current; - } - - void setCurrent(T current) { - this.current = current; - } - -} -//## Java 1.5 end ## diff --git a/tools/h2/src/tools/org/h2/jaqu/Table.java b/tools/h2/src/tools/org/h2/jaqu/Table.java deleted file mode 100755 index 516bbe1..0000000 --- a/tools/h2/src/tools/org/h2/jaqu/Table.java +++ /dev/null @@ -1,19 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.jaqu; - -/** - * A class that implements this interface can be used as a database table. - */ -public interface Table { - - /** - * This method is called to let the table define the primary key, indexes, - * and the table name. - */ - void define(); -} diff --git a/tools/h2/src/tools/org/h2/jaqu/TableDefinition.java b/tools/h2/src/tools/org/h2/jaqu/TableDefinition.java deleted file mode 100755 index 367fd73..0000000 --- a/tools/h2/src/tools/org/h2/jaqu/TableDefinition.java +++ /dev/null @@ -1,364 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.jaqu; - -//## Java 1.5 begin ## -import java.lang.reflect.Field; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.util.ArrayList; -import java.util.IdentityHashMap; -import java.util.List; -import java.util.Map; - -import org.h2.jaqu.util.Utils; -import org.h2.util.StatementBuilder; - -/** - * A table definition contains the index definitions of a table, the field - * definitions, the table name, and other meta data. - * - * @param the table type - */ -//## Java 1.5 begin ## -class TableDefinition { -//## Java 1.5 end ## - - /** - * The meta data of an index. - */ -//## Java 1.5 begin ## - static class IndexDefinition { - boolean unique; - String indexName; - List columnNames; - } -//## Java 1.5 end ## - - /** - * The meta data of a field. - */ -//## Java 1.5 begin ## - static class FieldDefinition { - String columnName; - Field field; - String dataType; - int maxLength; - boolean isPrimaryKey; - - Object getValue(Object obj) { - try { - return field.get(obj); - } catch (Exception e) { - throw new RuntimeException(e); - } - } - - void initWithNewObject(Object obj) { - Object o = Utils.newObject(field.getType()); - setValue(obj, o); - } - - void setValue(Object obj, Object o) { - try { - o = Utils.convert(o, field.getType()); - field.set(obj, o); - } catch (Exception e) { - throw new RuntimeException(e); - } - } - - Object read(ResultSet rs, int columnIndex) { - try { - return rs.getObject(columnIndex); - } catch (SQLException e) { - throw new RuntimeException(e); - } - } - } - - String tableName; - private Class clazz; - private ArrayList fields = Utils.newArrayList(); - private IdentityHashMap fieldMap = - Utils.newIdentityHashMap(); - private List primaryKeyColumnNames; - private ArrayList indexes = Utils.newArrayList(); - - TableDefinition(Class clazz) { - this.clazz = clazz; - tableName = clazz.getSimpleName(); - } - - List getFields() { - return fields; - } - - void setTableName(String tableName) { - this.tableName = tableName; - } - - void setPrimaryKey(Object[] primaryKeyColumns) { - this.primaryKeyColumnNames = mapColumnNames(primaryKeyColumns); - // set isPrimaryKey flag for all field definitions - for (FieldDefinition fieldDefinition : fieldMap.values()) { - fieldDefinition.isPrimaryKey = this.primaryKeyColumnNames - .contains(fieldDefinition.columnName); - } - } - - String getColumnName(A fieldObject) { - FieldDefinition def = fieldMap.get(fieldObject); - return def == null ? null : def.columnName; - } - - private List mapColumnNames(Object[] columns) { - List columnNames = Utils.newArrayList(); - for (Object column : columns) { - columnNames.add(getColumnName(column)); - } - return columnNames; - } - - void addIndex(Object[] columns) { - IndexDefinition index = new IndexDefinition(); - index.indexName = tableName + "_" + indexes.size(); - index.columnNames = mapColumnNames(columns); - indexes.add(index); - } - - public void setMaxLength(Object column, int maxLength) { - String columnName = getColumnName(column); - for (FieldDefinition f: fields) { - if (f.columnName.equals(columnName)) { - f.maxLength = maxLength; - break; - } - } - } - - void mapFields() { - Field[] classFields = clazz.getFields(); - for (Field f : classFields) { - FieldDefinition fieldDef = new FieldDefinition(); - fieldDef.field = f; - fieldDef.columnName = f.getName(); - fieldDef.dataType = getDataType(f); - fields.add(fieldDef); - } - } - - private String getDataType(Field field) { - Class< ? > fieldClass = field.getType(); - if (fieldClass == Integer.class) { - return "INT"; - } else if (fieldClass == String.class) { - return "VARCHAR"; - } else if (fieldClass == Double.class) { - return "DOUBLE"; - } else if (fieldClass == java.math.BigDecimal.class) { - return "DECIMAL"; - } else if (fieldClass == java.util.Date.class) { - return "DATE"; - } else if (fieldClass == java.sql.Date.class) { - return "DATE"; - } else if (fieldClass == java.sql.Time.class) { - return "TIME"; - } else if (fieldClass == java.sql.Timestamp.class) { - return "TIMESTAMP"; - } - return "VARCHAR"; - // TODO add more data types - } - - void insert(Db db, Object obj) { - SQLStatement stat = new SQLStatement(db); - StatementBuilder buff = new StatementBuilder("INSERT INTO "); - buff.append(tableName).append('('); - for (FieldDefinition field : fields) { - buff.appendExceptFirst(", "); - buff.append(field.columnName); - } - buff.append(") VALUES("); - buff.resetCount(); - for (FieldDefinition field : fields) { - buff.appendExceptFirst(", "); - buff.append('?'); - Object value = field.getValue(obj); - stat.addParameter(value); - } - buff.append(')'); - stat.setSQL(buff.toString()); - stat.executeUpdate(); - } - - void merge(Db db, Object obj) { - if (primaryKeyColumnNames == null || primaryKeyColumnNames.size() == 0) { - throw new IllegalStateException("No primary key columns defined " - + "for table " + obj.getClass() + " - no update possible"); - } - SQLStatement stat = new SQLStatement(db); - StatementBuilder buff = new StatementBuilder("MERGE INTO "); - buff.append(tableName).append(" ("); - buff.resetCount(); - for (FieldDefinition field : fields) { - buff.appendExceptFirst(", "); - buff.append(field.columnName); - } - buff.append(") KEY("); - buff.resetCount(); - for (FieldDefinition field : fields) { - if (field.isPrimaryKey) { - buff.appendExceptFirst(", "); - buff.append(field.columnName); - } - } - buff.append(") "); - buff.resetCount(); - buff.append("VALUES ("); - for (FieldDefinition field : fields) { - buff.appendExceptFirst(", "); - buff.append('?'); - Object value = field.getValue(obj); - stat.addParameter(value); - } - buff.append(')'); - stat.setSQL(buff.toString()); - stat.executeUpdate(); - } - - void update(Db db, Object obj) { - if (primaryKeyColumnNames == null || primaryKeyColumnNames.size() == 0) { - throw new IllegalStateException("No primary key columns defined " - + "for table " + obj.getClass() + " - no update possible"); - } - SQLStatement stat = new SQLStatement(db); - StatementBuilder buff = new StatementBuilder("UPDATE "); - buff.append(tableName).append(" SET "); - buff.resetCount(); - for (FieldDefinition field : fields) { - if (!field.isPrimaryKey) { - buff.appendExceptFirst(", "); - buff.append(field.columnName); - buff.append(" = ?"); - Object value = field.getValue(obj); - stat.addParameter(value); - } - } - Object alias = Utils.newObject(obj.getClass()); - Query query = Query.from(db, alias); - boolean firstCondition = true; - for (FieldDefinition field : fields) { - if (field.isPrimaryKey) { - Object aliasValue = field.getValue(alias); - Object value = field.getValue(obj); - if (!firstCondition) { - query.addConditionToken(ConditionAndOr.AND); - } - firstCondition = false; - query.addConditionToken( - new Condition( - aliasValue, value, CompareType.EQUAL)); - } - } - stat.setSQL(buff.toString()); - query.appendWhere(stat); - stat.executeUpdate(); - } - - TableDefinition createTableIfRequired(Db db) { - SQLStatement stat = new SQLStatement(db); - StatementBuilder buff = new StatementBuilder("CREATE TABLE IF NOT EXISTS "); - buff.append(tableName).append('('); - for (FieldDefinition field : fields) { - buff.appendExceptFirst(", "); - buff.append(field.columnName).append(' ').append(field.dataType); - if (field.maxLength != 0) { - buff.append('(').append(field.maxLength).append(')'); - } - } - if (primaryKeyColumnNames != null) { - buff.append(", PRIMARY KEY("); - buff.resetCount(); - for (String n : primaryKeyColumnNames) { - buff.appendExceptFirst(", "); - buff.append(n); - } - buff.append(')'); - } - buff.append(')'); - stat.setSQL(buff.toString()); - stat.executeUpdate(); - // TODO create indexes - return this; - } - - void mapObject(Object obj) { - fieldMap.clear(); - initObject(obj, fieldMap); - } - - void initObject(Object obj, Map map) { - for (FieldDefinition def : fields) { - def.initWithNewObject(obj); - map.put(def.getValue(obj), def); - } - } - - void initSelectObject(SelectTable table, Object obj, - Map> map) { - for (FieldDefinition def : fields) { - def.initWithNewObject(obj); - SelectColumn column = new SelectColumn(table, def); - map.put(def.getValue(obj), column); - } - } - - void readRow(Object item, ResultSet rs) { - for (int i = 0; i < fields.size(); i++) { - FieldDefinition def = fields.get(i); - Object o = def.read(rs, i + 1); - def.setValue(item, o); - } - } - - SQLStatement getSelectList(Db db) { - SQLStatement selectList = new SQLStatement(db); - for (int i = 0; i < fields.size(); i++) { - if (i > 0) { - selectList.appendSQL(", "); - } - FieldDefinition def = fields.get(i); - selectList.appendSQL(def.columnName); - } - return selectList; - } - - SQLStatement getSelectList(Query query, X x) { - SQLStatement selectList = new SQLStatement(query.getDb()); - for (int i = 0; i < fields.size(); i++) { - if (i > 0) { - selectList.appendSQL(", "); - } - FieldDefinition def = fields.get(i); - Object obj = def.getValue(x); - query.appendSQL(selectList, obj); - } - return selectList; - } - - void copyAttributeValues(Query query, X to, X map) { - for (FieldDefinition def : fields) { - Object obj = def.getValue(map); - SelectColumn col = query.getSelectColumn(obj); - Object value = col.getCurrentValue(); - def.setValue(to, value); - } - } - -} -//## Java 1.5 end ## diff --git a/tools/h2/src/tools/org/h2/jaqu/TestCondition.java b/tools/h2/src/tools/org/h2/jaqu/TestCondition.java deleted file mode 100755 index 4260f64..0000000 --- a/tools/h2/src/tools/org/h2/jaqu/TestCondition.java +++ /dev/null @@ -1,104 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.jaqu; - -import org.h2.jaqu.util.Utils; - -/** - * This class represents an incomplete condition. - * - * @param the incomplete condition data type - */ -//## Java 1.5 begin ## -public class TestCondition { - - private A x; - - public TestCondition(A x) { - this.x = x; - } - - public Boolean is(A y) { - Boolean o = Utils.newObject(Boolean.class); - return Db.registerToken(o, new Function("=", x, y) { - public void appendSQL(SQLStatement stat, Query query) { - stat.appendSQL("("); - query.appendSQL(stat, x[0]); - stat.appendSQL(" = "); - query.appendSQL(stat, x[1]); - stat.appendSQL(")"); - } - }); - } - - public Boolean bigger(A y) { - Boolean o = Utils.newObject(Boolean.class); - return Db.registerToken(o, new Function(">", x, y) { - public void appendSQL(SQLStatement stat, Query query) { - stat.appendSQL("("); - query.appendSQL(stat, x[0]); - stat.appendSQL(" > "); - query.appendSQL(stat, x[1]); - stat.appendSQL(")"); - } - }); - } - - public Boolean biggerEqual(A y) { - Boolean o = Utils.newObject(Boolean.class); - return Db.registerToken(o, new Function(">=", x, y) { - public void appendSQL(SQLStatement stat, Query query) { - stat.appendSQL("("); - query.appendSQL(stat, x[0]); - stat.appendSQL(" >= "); - query.appendSQL(stat, x[1]); - stat.appendSQL(")"); - } - }); - } - - public Boolean smaller(A y) { - Boolean o = Utils.newObject(Boolean.class); - return Db.registerToken(o, new Function("<", x, y) { - public void appendSQL(SQLStatement stat, Query query) { - stat.appendSQL("("); - query.appendSQL(stat, x[0]); - stat.appendSQL(" < "); - query.appendSQL(stat, x[1]); - stat.appendSQL(")"); - } - }); - } - - public Boolean smallerEqual(A y) { - Boolean o = Utils.newObject(Boolean.class); - return Db.registerToken(o, new Function("<=", x, y) { - public void appendSQL(SQLStatement stat, Query query) { - stat.appendSQL("("); - query.appendSQL(stat, x[0]); - stat.appendSQL(" <= "); - query.appendSQL(stat, x[1]); - stat.appendSQL(")"); - } - }); - } - - public Boolean like(A pattern) { - Boolean o = Utils.newObject(Boolean.class); - return Db.registerToken(o, new Function("LIKE", x, pattern) { - public void appendSQL(SQLStatement stat, Query query) { - stat.appendSQL("("); - query.appendSQL(stat, x[0]); - stat.appendSQL(" LIKE "); - query.appendSQL(stat, x[1]); - stat.appendSQL(")"); - } - }); - } - -} -//## Java 1.5 end ## diff --git a/tools/h2/src/tools/org/h2/jaqu/Token.java b/tools/h2/src/tools/org/h2/jaqu/Token.java deleted file mode 100755 index 7d4c98f..0000000 --- a/tools/h2/src/tools/org/h2/jaqu/Token.java +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.jaqu; - -/** - * Classes implementing this interface can be used as a token in a statement. - */ -public interface Token { - /** - * Append the SQL to the given statement using the given query. - * - * @param stat the statement to append the SQL to - * @param query the query to use - */ -//## Java 1.5 begin ## - void appendSQL(SQLStatement stat, Query query); -//## Java 1.5 end ## -} diff --git a/tools/h2/src/tools/org/h2/jaqu/bytecode/And.java b/tools/h2/src/tools/org/h2/jaqu/bytecode/And.java deleted file mode 100755 index 182c6a5..0000000 --- a/tools/h2/src/tools/org/h2/jaqu/bytecode/And.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.jaqu.bytecode; - -import org.h2.jaqu.Query; -import org.h2.jaqu.SQLStatement; -import org.h2.jaqu.Token; - -/** - * An AND expression. - */ -public class And implements Token { - - private final Token left, right; - - private And(Token left, Token right) { - this.left = left; - this.right = right; - } - - static And get(Token left, Token right) { - return new And(left, right); - } - - public void appendSQL(SQLStatement stat, Query query) { - left.appendSQL(stat, query); - stat.appendSQL(" AND "); - right.appendSQL(stat, query); - } - -} diff --git a/tools/h2/src/tools/org/h2/jaqu/bytecode/ArrayGet.java b/tools/h2/src/tools/org/h2/jaqu/bytecode/ArrayGet.java deleted file mode 100755 index 6d7fb88..0000000 --- a/tools/h2/src/tools/org/h2/jaqu/bytecode/ArrayGet.java +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.jaqu.bytecode; - -import org.h2.jaqu.Query; -import org.h2.jaqu.SQLStatement; -import org.h2.jaqu.Token; - -/** - * An array access operation. - */ -public class ArrayGet implements Token { - - private final Token variable; - private final Token index; - - private ArrayGet(Token variable, Token index) { - this.variable = variable; - this.index = index; - } - - static ArrayGet get(Token variable, Token index) { - return new ArrayGet(variable, index); - } - - public void appendSQL(SQLStatement stat, Query query) { - // untested - variable.appendSQL(stat, query); - stat.appendSQL("["); - index.appendSQL(stat, query); - stat.appendSQL("]"); - } - -} diff --git a/tools/h2/src/tools/org/h2/jaqu/bytecode/CaseWhen.java b/tools/h2/src/tools/org/h2/jaqu/bytecode/CaseWhen.java deleted file mode 100755 index a165b4d..0000000 --- a/tools/h2/src/tools/org/h2/jaqu/bytecode/CaseWhen.java +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.jaqu.bytecode; - -import org.h2.jaqu.Query; -import org.h2.jaqu.SQLStatement; -import org.h2.jaqu.Token; - -/** - * A conditional expression. - */ -public class CaseWhen implements Token { - - private final Token condition, ifTrue, ifFalse; - - private CaseWhen(Token condition, Token ifTrue, Token ifFalse) { - this.condition = condition; - this.ifTrue = ifTrue; - this.ifFalse = ifFalse; - } - - static Token get(Token condition, Token ifTrue, Token ifFalse) { - if ("0".equals(ifTrue.toString()) && "1".equals(ifFalse.toString())) { - return Not.get(condition); - } else if ("1".equals(ifTrue.toString()) && "0".equals(ifFalse.toString())) { - return condition; - } else if ("0".equals(ifTrue.toString())) { - return And.get(Not.get(condition), ifFalse); - } - return new CaseWhen(condition, ifTrue, ifFalse); - } - - public String toString() { - return "CASEWHEN(" + condition + ", " + ifTrue + ", " + ifFalse + ")"; - } - - public void appendSQL(SQLStatement stat, Query query) { - stat.appendSQL("CASEWHEN "); - condition.appendSQL(stat, query); - stat.appendSQL(" THEN "); - ifTrue.appendSQL(stat, query); - stat.appendSQL(" ELSE "); - ifFalse.appendSQL(stat, query); - stat.appendSQL(" END"); - } - -} diff --git a/tools/h2/src/tools/org/h2/jaqu/bytecode/ClassReader.java b/tools/h2/src/tools/org/h2/jaqu/bytecode/ClassReader.java deleted file mode 100755 index 4180631..0000000 --- a/tools/h2/src/tools/org/h2/jaqu/bytecode/ClassReader.java +++ /dev/null @@ -1,1439 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.jaqu.bytecode; - -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.Map; -import java.util.Stack; -import org.h2.jaqu.Token; - -/** - * This class converts a method to a SQL Token by interpreting - * (decompiling) the bytecode of the class. - */ -public class ClassReader { - - private static final boolean DEBUG = false; - - private byte[] data; - private int pos; - private Constant[] constantPool; - private int startByteCode; - private String methodName; - - private String convertMethodName; - private Token result; - private Stack stack = new Stack(); - private ArrayList variables = new ArrayList(); - private boolean endOfMethod; - private boolean condition; - private int nextPc; - private Map fieldMap = new HashMap(); - - private void debug(String s) { - if (DEBUG) { - System.out.println(s); - } - } - - public Token decompile(Object instance, Map fields, String method) { - this.fieldMap = fields; - this.convertMethodName = method; - Class< ? > clazz = instance.getClass(); - String className = clazz.getName(); - debug("class name " + className); - ByteArrayOutputStream buff = new ByteArrayOutputStream(); - try { - InputStream in = clazz.getClassLoader().getResource(className.replace('.', '/') + ".class").openStream(); - while (true) { - int x = in.read(); - if (x < 0) { - break; - } - buff.write(x); - } - } catch (IOException e) { - throw new RuntimeException("Could not read class bytecode", e); - } - data = buff.toByteArray(); - int header = readInt(); - debug("header: " + Integer.toHexString(header)); - int minorVersion = readShort(); - int majorVersion = readShort(); - debug("version: " + majorVersion + "." + minorVersion); - int constantPoolCount = readShort(); - constantPool = new Constant[constantPoolCount]; - for (int i = 1; i < constantPoolCount; i++) { - int type = readByte(); - switch(type) { - case 1: - constantPool[i] = ConstantString.get(readString()); - break; - case 3: { - int x = readInt(); - constantPool[i] = ConstantNumber.get(x); - break; - } - case 4: { - int x = readInt(); - constantPool[i] = ConstantNumber.get("" + Float.intBitsToFloat(x), x, Constant.Type.FLOAT); - break; - } - case 5: { - long x = readLong(); - constantPool[i] = ConstantNumber.get(x); - i++; - break; - } - case 6: { - long x = readLong(); - constantPool[i] = ConstantNumber.get("" + Double.longBitsToDouble(x), x, Constant.Type.DOUBLE); - i++; - break; - } - case 7: { - int x = readShort(); - constantPool[i] = ConstantNumber.get(null, x, ConstantNumber.Type.CLASS_REF); - break; - } - case 8: { - int x = readShort(); - constantPool[i] = ConstantNumber.get(null, x, ConstantNumber.Type.STRING_REF); - break; - } - case 9: { - int x = readInt(); - constantPool[i] = ConstantNumber.get(null, x, ConstantNumber.Type.FIELD_REF); - break; - } - case 10: { - int x = readInt(); - constantPool[i] = ConstantNumber.get(null, x, ConstantNumber.Type.METHOD_REF); - break; - } - case 11: { - int x = readInt(); - constantPool[i] = ConstantNumber.get(null, x, ConstantNumber.Type.INTERFACE_METHOD_REF); - break; - } - case 12: { - int x = readInt(); - constantPool[i] = ConstantNumber.get(null, x, ConstantNumber.Type.NAME_AND_TYPE); - break; - } - default: - throw new RuntimeException("Unsupported constant pool tag: " + type); - } - } - int accessFlags = readShort(); - debug("access flags: " + accessFlags); - int classRef = readShort(); - debug("class: " + constantPool[constantPool[classRef].intValue()]); - int superClassRef = readShort(); - debug(" extends " + constantPool[constantPool[superClassRef].intValue()]); - int interfaceCount = readShort(); - for (int i = 0; i < interfaceCount; i++) { - int interfaceRef = readShort(); - debug(" implements " + constantPool[constantPool[interfaceRef].intValue()]); - } - int fieldCount = readShort(); - for (int i = 0; i < fieldCount; i++) { - readField(); - } - int methodCount = readShort(); - for (int i = 0; i < methodCount; i++) { - readMethod(); - } - readAttributes(); - return result; - } - - private void readField() { - int accessFlags = readShort(); - int nameIndex = readShort(); - int descIndex = readShort(); - debug(" " + constantPool[descIndex] + " " + constantPool[nameIndex] + " " + accessFlags); - readAttributes(); - } - - private void readMethod() { - int accessFlags = readShort(); - int nameIndex = readShort(); - int descIndex = readShort(); - String desc = constantPool[descIndex].toString(); - methodName = constantPool[nameIndex].toString(); - debug(" " + desc + " " + methodName + " " + accessFlags); - readAttributes(); - } - - private void readAttributes() { - int attributeCount = readShort(); - for (int i = 0; i < attributeCount; i++) { - int attributeNameIndex = readShort(); - String attributeName = constantPool[attributeNameIndex].toString(); - debug(" attribute " + attributeName); - int attributeLength = readInt(); - int end = pos + attributeLength; - if ("Code".equals(attributeName)) { - readCode(); - } - pos = end; - } - } - - void decompile() { - int maxStack = readShort(); - int maxLocals = readShort(); - debug("stack: " + maxStack + " locals: " + maxLocals); - int codeLength = readInt(); - startByteCode = pos; - int end = pos + codeLength; - while (pos < end) { - readByteCode(); - } - debug(""); - pos = startByteCode + codeLength; - int exceptionTableLength = readShort(); - pos += 2 * exceptionTableLength; - readAttributes(); - } - - private void readCode() { - variables.clear(); - stack.clear(); - int maxStack = readShort(); - int maxLocals = readShort(); - debug("stack: " + maxStack + " locals: " + maxLocals); - int codeLength = readInt(); - startByteCode = pos; - if (methodName.startsWith(convertMethodName)) { - result = getResult(); - } - pos = startByteCode + codeLength; - int exceptionTableLength = readShort(); - pos += 2 * exceptionTableLength; - readAttributes(); - } - - private Token getResult() { - while (true) { - readByteCode(); - if (endOfMethod) { - return stack.pop(); - } - if (condition) { - Token c = stack.pop(); - Stack currentStack = new Stack(); - currentStack.addAll(stack); - ArrayList currentVariables = new ArrayList(); - currentVariables.addAll(variables); - int branch = nextPc; - Token a = getResult(); - stack = currentStack; - variables = currentVariables; - pos = branch + startByteCode; - Token b = getResult(); - if (a.equals("0") && b.equals("1")) { - return c; - } else if (a.equals("1") && b.equals("0")) { - return Not.get(c); - } else if (b.equals("0")) { - return And.get(Not.get(c), a); - } else if (a.equals("0")) { - return And.get(c, b); - } else if (b.equals("1")) { - return Or.get(c, a); - } else if (a.equals("1")) { - return And.get(Not.get(c), b); - } - return CaseWhen.get(c, b, a); - } - if (nextPc != 0) { - pos = nextPc + startByteCode; - } - } - } - - private void readByteCode() { - int startPos = pos - startByteCode; - int opCode = readByte(); - String op; - endOfMethod = false; - condition = false; - nextPc = 0; - switch(opCode) { - case 0: - op = "nop"; - break; - case 1: - op = "aconst_null"; - stack.push(Null.INSTANCE); - break; - case 2: - op = "iconst_m1"; - stack.push(ConstantNumber.get("-1")); - break; - case 3: - op = "iconst_0"; - stack.push(ConstantNumber.get("0")); - break; - case 4: - op = "iconst_1"; - stack.push(ConstantNumber.get("1")); - break; - case 5: - op = "iconst_2"; - stack.push(ConstantNumber.get("2")); - break; - case 6: - op = "iconst_3"; - stack.push(ConstantNumber.get("3")); - break; - case 7: - op = "iconst_4"; - stack.push(ConstantNumber.get("4")); - break; - case 8: - op = "iconst_5"; - stack.push(ConstantNumber.get("5")); - break; - case 9: - op = "lconst_0"; - stack.push(ConstantNumber.get("0")); - break; - case 10: - op = "lconst_1"; - stack.push(ConstantNumber.get("1")); - break; - case 11: - op = "fconst_0"; - stack.push(ConstantNumber.get("0.0")); - break; - case 12: - op = "fconst_1"; - stack.push(ConstantNumber.get("1.0")); - break; - case 13: - op = "fconst_2"; - stack.push(ConstantNumber.get("2.0")); - break; - case 14: - op = "dconst_0"; - stack.push(ConstantNumber.get("0.0")); - break; - case 15: - op = "dconst_1"; - stack.push(ConstantNumber.get("1.0")); - break; - case 16: { - int x = (byte) readByte(); - op = "bipush " + x; - stack.push(ConstantNumber.get(x)); - break; - } - case 17: { - int x = (short) readShort(); - op = "sipush " + x; - stack.push(ConstantNumber.get(x)); - break; - } - case 18: { - Token s = getConstant(readByte()); - op = "ldc " + s; - stack.push(s); - break; - } - case 19: { - Token s = getConstant(readShort()); - op = "ldc_w " + s; - stack.push(s); - break; - } - case 20: { - Token s = getConstant(readShort()); - op = "ldc2_w " + s; - stack.push(s); - break; - } - case 21: { - int x = readByte(); - op = "iload " + x; - stack.push(getVariable(x)); - break; - } - case 22: { - int x = readByte(); - op = "lload " + x; - stack.push(getVariable(x)); - break; - } - case 23: { - int x = readByte(); - op = "fload " + x; - stack.push(getVariable(x)); - break; - } - case 24: { - int x = readByte(); - op = "dload " + x; - stack.push(getVariable(x)); - break; - } - case 25: { - int x = readByte(); - op = "aload " + x; - stack.push(getVariable(x)); - break; - } - case 26: - op = "iload_0"; - stack.push(getVariable(0)); - break; - case 27: - op = "iload_1"; - stack.push(getVariable(1)); - break; - case 28: - op = "iload_2"; - stack.push(getVariable(2)); - break; - case 29: - op = "iload_3"; - stack.push(getVariable(3)); - break; - case 30: - op = "lload_0"; - stack.push(getVariable(0)); - break; - case 31: - op = "lload_1"; - stack.push(getVariable(1)); - break; - case 32: - op = "lload_2"; - stack.push(getVariable(2)); - break; - case 33: - op = "lload_3"; - stack.push(getVariable(3)); - break; - case 34: - op = "fload_0"; - stack.push(getVariable(0)); - break; - case 35: - op = "fload_1"; - stack.push(getVariable(1)); - break; - case 36: - op = "fload_2"; - stack.push(getVariable(2)); - break; - case 37: - op = "fload_3"; - stack.push(getVariable(3)); - break; - case 38: - op = "dload_0"; - stack.push(getVariable(0)); - break; - case 39: - op = "dload_1"; - stack.push(getVariable(1)); - break; - case 40: - op = "dload_2"; - stack.push(getVariable(2)); - break; - case 41: - op = "dload_3"; - stack.push(getVariable(3)); - break; - case 42: - op = "aload_0"; - stack.push(getVariable(0)); - break; - case 43: - op = "aload_1"; - stack.push(getVariable(1)); - break; - case 44: - op = "aload_2"; - stack.push(getVariable(2)); - break; - case 45: - op = "aload_3"; - stack.push(getVariable(3)); - break; - case 46: { - Token index = stack.pop(); - Token ref = stack.pop(); - op = "iaload"; - stack.push(ArrayGet.get(ref, index)); - break; - } - case 47: { - Token index = stack.pop(); - Token ref = stack.pop(); - op = "laload"; - stack.push(ArrayGet.get(ref, index)); - break; - } - case 48: { - Token index = stack.pop(); - Token ref = stack.pop(); - op = "faload"; - stack.push(ArrayGet.get(ref, index)); - break; - } - case 49: { - Token index = stack.pop(); - Token ref = stack.pop(); - op = "daload"; - stack.push(ArrayGet.get(ref, index)); - break; - } - case 50: { - Token index = stack.pop(); - Token ref = stack.pop(); - op = "aaload"; - stack.push(ArrayGet.get(ref, index)); - break; - } - case 51: { - Token index = stack.pop(); - Token ref = stack.pop(); - op = "baload"; - stack.push(ArrayGet.get(ref, index)); - break; - } - case 52: { - Token index = stack.pop(); - Token ref = stack.pop(); - op = "caload"; - stack.push(ArrayGet.get(ref, index)); - break; - } - case 53: { - Token index = stack.pop(); - Token ref = stack.pop(); - op = "saload"; - stack.push(ArrayGet.get(ref, index)); - break; - } - case 54: { - int var = readByte(); - op = "istore " + var; - setVariable(var, stack.pop()); - break; - } - case 55: { - int var = readByte(); - op = "lstore " + var; - setVariable(var, stack.pop()); - break; - } - case 56: { - int var = readByte(); - op = "fstore " + var; - setVariable(var, stack.pop()); - break; - } - case 57: { - int var = readByte(); - op = "dstore " + var; - setVariable(var, stack.pop()); - break; - } - case 58: { - int var = readByte(); - op = "astore " + var; - setVariable(var, stack.pop()); - break; - } - case 59: - op = "istore_0"; - setVariable(0, stack.pop()); - break; - case 60: - op = "istore_1"; - setVariable(1, stack.pop()); - break; - case 61: - op = "istore_2"; - setVariable(2, stack.pop()); - break; - case 62: - op = "istore_3"; - setVariable(3, stack.pop()); - break; - case 63: - op = "lstore_0"; - setVariable(0, stack.pop()); - break; - case 64: - op = "lstore_1"; - setVariable(1, stack.pop()); - break; - case 65: - op = "lstore_2"; - setVariable(2, stack.pop()); - break; - case 66: - op = "lstore_3"; - setVariable(3, stack.pop()); - break; - case 67: - op = "fstore_0"; - setVariable(0, stack.pop()); - break; - case 68: - op = "fstore_1"; - setVariable(1, stack.pop()); - break; - case 69: - op = "fstore_2"; - setVariable(2, stack.pop()); - break; - case 70: - op = "fstore_3"; - setVariable(3, stack.pop()); - break; - case 71: - op = "dstore_0"; - setVariable(0, stack.pop()); - break; - case 72: - op = "dstore_1"; - setVariable(1, stack.pop()); - break; - case 73: - op = "dstore_2"; - setVariable(2, stack.pop()); - break; - case 74: - op = "dstore_3"; - setVariable(3, stack.pop()); - break; - case 75: - op = "astore_0"; - setVariable(0, stack.pop()); - break; - case 76: - op = "astore_1"; - setVariable(1, stack.pop()); - break; - case 77: - op = "astore_2"; - setVariable(2, stack.pop()); - break; - case 78: - op = "astore_3"; - setVariable(3, stack.pop()); - break; - case 79: { - // String value = stack.pop(); - // String index = stack.pop(); - // String ref = stack.pop(); - op = "iastore"; - // TODO side effect - not supported - break; - } - case 80: - op = "lastore"; - // TODO side effect - not supported - break; - case 81: - op = "fastore"; - // TODO side effect - not supported - break; - case 82: - op = "dastore"; - // TODO side effect - not supported - break; - case 83: - op = "aastore"; - // TODO side effect - not supported - break; - case 84: - op = "bastore"; - // TODO side effect - not supported - break; - case 85: - op = "castore"; - // TODO side effect - not supported - break; - case 86: - op = "sastore"; - // TODO side effect - not supported - break; - case 87: - op = "pop"; - stack.pop(); - break; - case 88: - op = "pop2"; - // TODO currently we don't know the stack types - stack.pop(); - stack.pop(); - break; - case 89: { - op = "dup"; - Token x = stack.pop(); - stack.push(x); - stack.push(x); - break; - } - case 90: { - op = "dup_x1"; - Token a = stack.pop(); - Token b = stack.pop(); - stack.push(a); - stack.push(b); - stack.push(a); - break; - } - case 91: { - // TODO currently we don't know the stack types - op = "dup_x2"; - Token a = stack.pop(); - Token b = stack.pop(); - Token c = stack.pop(); - stack.push(a); - stack.push(c); - stack.push(b); - stack.push(a); - break; - } - case 92: { - // TODO currently we don't know the stack types - op = "dup2"; - Token a = stack.pop(); - Token b = stack.pop(); - stack.push(b); - stack.push(a); - stack.push(b); - stack.push(a); - break; - } - case 93: { - // TODO currently we don't know the stack types - op = "dup2_x1"; - Token a = stack.pop(); - Token b = stack.pop(); - Token c = stack.pop(); - stack.push(b); - stack.push(a); - stack.push(c); - stack.push(b); - stack.push(a); - break; - } - case 94: { - // TODO currently we don't know the stack types - op = "dup2_x2"; - Token a = stack.pop(); - Token b = stack.pop(); - Token c = stack.pop(); - Token d = stack.pop(); - stack.push(b); - stack.push(a); - stack.push(d); - stack.push(c); - stack.push(b); - stack.push(a); - break; - } - case 95: { - op = "swap"; - Token a = stack.pop(); - Token b = stack.pop(); - stack.push(a); - stack.push(b); - break; - } - case 96: { - Token b = stack.pop(); - Token a = stack.pop(); - op = "iadd"; - stack.push(Operation.get(a, Operation.Type.ADD, b)); - break; - } - case 97: { - Token b = stack.pop(); - Token a = stack.pop(); - op = "ladd"; - stack.push(Operation.get(a, Operation.Type.ADD, b)); - break; - } - case 98: { - Token b = stack.pop(); - Token a = stack.pop(); - op = "fadd"; - stack.push(Operation.get(a, Operation.Type.ADD, b)); - break; - } - case 99: { - Token b = stack.pop(); - Token a = stack.pop(); - op = "dadd"; - stack.push(Operation.get(a, Operation.Type.ADD, b)); - break; - } - case 100: { - Token b = stack.pop(); - Token a = stack.pop(); - op = "isub"; - stack.push(Operation.get(a, Operation.Type.SUBTRACT, b)); - break; - } - case 101: { - Token b = stack.pop(); - Token a = stack.pop(); - op = "lsub"; - stack.push(Operation.get(a, Operation.Type.SUBTRACT, b)); - break; - } - case 102: { - Token b = stack.pop(); - Token a = stack.pop(); - op = "fsub"; - stack.push(Operation.get(a, Operation.Type.SUBTRACT, b)); - break; - } - case 103: { - Token b = stack.pop(); - Token a = stack.pop(); - op = "dsub"; - stack.push(Operation.get(a, Operation.Type.SUBTRACT, b)); - break; - } - case 104: { - Token b = stack.pop(); - Token a = stack.pop(); - op = "imul"; - stack.push(Operation.get(a, Operation.Type.MULTIPLY, b)); - break; - } - case 105: { - Token b = stack.pop(); - Token a = stack.pop(); - op = "lmul"; - stack.push(Operation.get(a, Operation.Type.MULTIPLY, b)); - break; - } - case 106: { - Token b = stack.pop(); - Token a = stack.pop(); - op = "fmul"; - stack.push(Operation.get(a, Operation.Type.MULTIPLY, b)); - break; - } - case 107: { - Token b = stack.pop(); - Token a = stack.pop(); - op = "dmul"; - stack.push(Operation.get(a, Operation.Type.MULTIPLY, b)); - break; - } - case 108: { - Token b = stack.pop(); - Token a = stack.pop(); - op = "idiv"; - stack.push(Operation.get(a, Operation.Type.DIVIDE, b)); - break; - } - case 109: { - Token b = stack.pop(); - Token a = stack.pop(); - op = "ldiv"; - stack.push(Operation.get(a, Operation.Type.DIVIDE, b)); - break; - } - case 110: { - Token b = stack.pop(); - Token a = stack.pop(); - op = "fdiv"; - stack.push(Operation.get(a, Operation.Type.DIVIDE, b)); - break; - } - case 111: { - Token b = stack.pop(); - Token a = stack.pop(); - op = "ddiv"; - stack.push(Operation.get(a, Operation.Type.DIVIDE, b)); - break; - } - case 112: { - Token b = stack.pop(); - Token a = stack.pop(); - op = "irem"; - stack.push(Operation.get(a, Operation.Type.MOD, b)); - break; - } - case 113: { - Token b = stack.pop(); - Token a = stack.pop(); - op = "lrem"; - stack.push(Operation.get(a, Operation.Type.MOD, b)); - break; - } - case 114: { - Token b = stack.pop(); - Token a = stack.pop(); - op = "frem"; - stack.push(Operation.get(a, Operation.Type.MOD, b)); - break; - } - case 115: { - Token b = stack.pop(); - Token a = stack.pop(); - op = "drem"; - stack.push(Operation.get(a, Operation.Type.MOD, b)); - break; - } -// case 116: -// op = "ineg"; -// break; -// case 117: -// op = "lneg"; -// break; -// case 118: -// op = "fneg"; -// break; -// case 119: -// op = "dneg"; -// break; -// case 120: -// op = "ishl"; -// break; -// case 121: -// op = "lshl"; -// break; -// case 122: -// op = "ishr"; -// break; -// case 123: -// op = "lshr"; -// break; -// case 124: -// op = "iushr"; -// break; -// case 125: -// op = "lushr"; -// break; -// case 126: -// op = "iand"; -// break; -// case 127: -// op = "land"; -// break; -// case 128: -// op = "ior"; -// break; -// case 129: -// op = "lor"; -// break; -// case 130: -// op = "ixor"; -// break; -// case 131: -// op = "lxor"; -// break; -// case 132: { -// int var = readByte(); -// int off = (byte) readByte(); -// op = "iinc " + var + " " + off; -// break; -// } -// case 133: -// op = "i2l"; -// break; -// case 134: -// op = "i2f"; -// break; -// case 135: -// op = "i2d"; -// break; -// case 136: -// op = "l2i"; -// break; -// case 137: -// op = "l2f"; -// break; -// case 138: -// op = "l2d"; -// break; -// case 139: -// op = "f2i"; -// break; -// case 140: -// op = "f2l"; -// break; -// case 141: -// op = "f2d"; -// break; -// case 142: -// op = "d2i"; -// break; -// case 143: -// op = "d2l"; -// break; -// case 144: -// op = "d2f"; -// break; -// case 145: -// op = "i2b"; -// break; -// case 146: -// op = "i2c"; -// break; -// case 147: -// op = "i2s"; -// break; - case 148: { - Token b = stack.pop(), a = stack.pop(); - stack.push(new Function("SIGN", Operation.get(a, Operation.Type.SUBTRACT, b))); - op = "lcmp"; - break; - } -// case 149: -// op = "fcmpl"; -// break; -// case 150: -// op = "fcmpg"; -// break; -// case 151: -// op = "dcmpl"; -// break; -// case 152: -// op = "dcmpg"; -// break; - case 153: - condition = true; - nextPc = getAbsolutePos(pos, readShort()); - stack.push(Operation.get(stack.pop(), Operation.Type.EQUALS, ConstantNumber.get(0))); - op = "ifeq " + nextPc; - break; - case 154: - condition = true; - nextPc = getAbsolutePos(pos, readShort()); - stack.push(Operation.get(stack.pop(), Operation.Type.NOT_EQUALS, ConstantNumber.get(0))); - op = "ifne " + nextPc; - break; - case 155: - condition = true; - nextPc = getAbsolutePos(pos, readShort()); - stack.push(Operation.get(stack.pop(), Operation.Type.SMALLER, ConstantNumber.get(0))); - op = "iflt " + nextPc; - break; - case 156: - condition = true; - nextPc = getAbsolutePos(pos, readShort()); - stack.push(Operation.get(stack.pop(), Operation.Type.BIGGER_EQUALS, ConstantNumber.get(0))); - op = "ifge " + nextPc; - break; - case 157: - condition = true; - nextPc = getAbsolutePos(pos, readShort()); - stack.push(Operation.get(stack.pop(), Operation.Type.BIGGER, ConstantNumber.get(0))); - op = "ifgt " + nextPc; - break; - case 158: - condition = true; - nextPc = getAbsolutePos(pos, readShort()); - stack.push(Operation.get(stack.pop(), Operation.Type.SMALLER_EQUALS, ConstantNumber.get(0))); - op = "ifle " + nextPc; - break; - case 159: { - condition = true; - nextPc = getAbsolutePos(pos, readShort()); - Token b = stack.pop(), a = stack.pop(); - stack.push(Operation.get(a, Operation.Type.EQUALS, b)); - op = "if_icmpeq " + nextPc; - break; - } - case 160: { - condition = true; - nextPc = getAbsolutePos(pos, readShort()); - Token b = stack.pop(), a = stack.pop(); - stack.push(Operation.get(a, Operation.Type.NOT_EQUALS, b)); - op = "if_icmpne " + nextPc; - break; - } - case 161: { - condition = true; - nextPc = getAbsolutePos(pos, readShort()); - Token b = stack.pop(), a = stack.pop(); - stack.push(Operation.get(a, Operation.Type.SMALLER, b)); - op = "if_icmplt " + nextPc; - break; - } - case 162: { - condition = true; - nextPc = getAbsolutePos(pos, readShort()); - Token b = stack.pop(), a = stack.pop(); - stack.push(Operation.get(a, Operation.Type.BIGGER_EQUALS, b)); - op = "if_icmpge " + nextPc; - break; - } - case 163: { - condition = true; - nextPc = getAbsolutePos(pos, readShort()); - Token b = stack.pop(), a = stack.pop(); - stack.push(Operation.get(a, Operation.Type.BIGGER, b)); - op = "if_icmpgt " + nextPc; - break; - } - case 164: { - condition = true; - nextPc = getAbsolutePos(pos, readShort()); - Token b = stack.pop(), a = stack.pop(); - stack.push(Operation.get(a, Operation.Type.SMALLER_EQUALS, b)); - op = "if_icmple " + nextPc; - break; - } - case 165: { - condition = true; - nextPc = getAbsolutePos(pos, readShort()); - Token b = stack.pop(), a = stack.pop(); - stack.push(Operation.get(a, Operation.Type.EQUALS, b)); - op = "if_acmpeq " + nextPc; - break; - } - case 166: { - condition = true; - nextPc = getAbsolutePos(pos, readShort()); - Token b = stack.pop(), a = stack.pop(); - stack.push(Operation.get(a, Operation.Type.NOT_EQUALS, b)); - op = "if_acmpne " + nextPc; - break; - } - case 167: - nextPc = getAbsolutePos(pos, readShort()); - op = "goto " + nextPc; - break; -// case 168: -// // TODO not supported yet -// op = "jsr " + getAbsolutePos(pos, readShort()); -// break; -// case 169: -// // TODO not supported yet -// op = "ret " + readByte(); -// break; -// case 170: { -// int start = pos; -// pos += 4 - ((pos - startByteCode) & 3); -// int def = readInt(); -// int low = readInt(), high = readInt(); -// int n = high - low + 1; -// op = "tableswitch default:" + getAbsolutePos(start, def); -// StringBuilder buff = new StringBuilder(); -// for (int i = 0; i < n; i++) { -// buff.append(' ').append(low++). -// append(":"). -// append(getAbsolutePos(start, readInt())); -// } -// op += buff.toString(); -// // pos += n * 4; -// break; -// } -// case 171: { -// int start = pos; -// pos += 4 - ((pos - startByteCode) & 3); -// int def = readInt(); -// int n = readInt(); -// op = "lookupswitch default:" + getAbsolutePos(start, def); -// StringBuilder buff = new StringBuilder(); -// for (int i = 0; i < n; i++) { -// buff.append(' '). -// append(readInt()). -// append(":"). -// append(getAbsolutePos(start, readInt())); -// } -// op += buff.toString(); -// // pos += n * 8; -// break; -// } - case 172: - op = "ireturn"; - endOfMethod = true; - break; - case 173: - op = "lreturn"; - endOfMethod = true; - break; - case 174: - op = "freturn"; - endOfMethod = true; - break; - case 175: - op = "dreturn"; - endOfMethod = true; - break; - case 176: - op = "areturn"; - endOfMethod = true; - break; - case 177: - op = "return"; - // no value returned - stack.push(null); - endOfMethod = true; - break; -// case 178: -// op = "getstatic " + getField(readShort()); -// break; -// case 179: -// op = "putstatic " + getField(readShort()); -// break; - case 180: { - String field = getField(readShort()); - Token p = stack.pop(); - String s = p + "." + field.substring(field.lastIndexOf('.') + 1, field.indexOf(' ')); - if (s.startsWith("this.")) { - s = s.substring(5); - } - stack.push(Variable.get(s, fieldMap.get(s))); - op = "getfield " + field; - break; - } -// case 181: -// op = "putfield " + getField(readShort()); -// break; - case 182: { - String method = getMethod(readShort()); - op = "invokevirtual " + method; - if (method.equals("java/lang/String.equals (Ljava/lang/Object;)Z")) { - Token a = stack.pop(); - Token b = stack.pop(); - stack.push(Operation.get(a, Operation.Type.EQUALS, b)); - } else if (method.equals("java/lang/Integer.intValue ()I")) { - // ignore - } else if (method.equals("java/lang/Long.longValue ()J")) { - // ignore - } - break; - } - case 183: { - String method = getMethod(readShort()); - op = "invokespecial " + method; - break; - } - case 184: - op = "invokestatic " + getMethod(readShort()); - break; -// case 185: { -// int methodRef = readShort(); -// readByte(); -// readByte(); -// op = "invokeinterface " + getMethod(methodRef); -// break; -// } - case 187: { - String className = constantPool[constantPool[readShort()].intValue()].toString(); - op = "new " + className; - break; - } -// case 188: -// op = "newarray " + readByte(); -// break; -// case 189: -// op = "anewarray " + cpString[readShort()]; -// break; -// case 190: -// op = "arraylength"; -// break; -// case 191: -// op = "athrow"; -// break; -// case 192: -// op = "checkcast " + cpString[readShort()]; -// break; -// case 193: -// op = "instanceof " + cpString[readShort()]; -// break; -// case 194: -// op = "monitorenter"; -// break; -// case 195: -// op = "monitorexit"; -// break; -// case 196: { -// opCode = readByte(); -// switch (opCode) { -// case 21: -// op = "wide iload " + readShort(); -// break; -// case 22: -// op = "wide lload " + readShort(); -// break; -// case 23: -// op = "wide fload " + readShort(); -// break; -// case 24: -// op = "wide dload " + readShort(); -// break; -// case 25: -// op = "wide aload " + readShort(); -// break; -// case 54: -// op = "wide istore " + readShort(); -// break; -// case 55: -// op = "wide lstore " + readShort(); -// break; -// case 56: -// op = "wide fstore " + readShort(); -// break; -// case 57: -// op = "wide dstore " + readShort(); -// break; -// case 58: -// op = "wide astore " + readShort(); -// break; -// case 132: { -// int var = readShort(); -// int off = (short) readShort(); -// op = "wide iinc " + var + " " + off; -// break; -// } -// case 169: -// op = "wide ret " + readShort(); -// break; -// default: -// throw new RuntimeException( -// "Unsupported wide opCode " + opCode); -// } -// break; -// } -// case 197: -// op = "multianewarray " + cpString[readShort()] + " " + readByte(); -// break; -// case 198: { -// condition = true; -// nextPc = getAbsolutePos(pos, readShort()); -// Token a = stack.pop(); -// stack.push("(" + a + " IS NULL)"); -// op = "ifnull " + nextPc; -// break; -// } -// case 199: { -// condition = true; -// nextPc = getAbsolutePos(pos, readShort()); -// Token a = stack.pop(); -// stack.push("(" + a + " IS NOT NULL)"); -// op = "ifnonnull " + nextPc; -// break; -// } - case 200: - op = "goto_w " + getAbsolutePos(pos, readInt()); - break; - case 201: - op = "jsr_w " + getAbsolutePos(pos, readInt()); - break; - default: - throw new RuntimeException("Unsupported opCode " + opCode); - } - debug(" " + startPos + ": " + op); - } - - private void setVariable(int x, Token value) { - while (x >= variables.size()) { - variables.add(Variable.get("p" + variables.size(), null)); - } - variables.set(x, value); - } - - private Token getVariable(int x) { - if (x == 0) { - return Variable.THIS; - } - while (x >= variables.size()) { - variables.add(Variable.get("p" + variables.size(), null)); - } - return variables.get(x); - } - - private String getField(int fieldRef) { - int field = constantPool[fieldRef].intValue(); - int classIndex = field >>> 16; - int nameAndType = constantPool[field & 0xffff].intValue(); - String className = constantPool[constantPool[classIndex].intValue()] + "." + constantPool[nameAndType >>> 16] + " " + constantPool[nameAndType & 0xffff]; - return className; - } - - private String getMethod(int methodRef) { - int method = constantPool[methodRef].intValue(); - int classIndex = method >>> 16; - int nameAndType = constantPool[method & 0xffff].intValue(); - String className = constantPool[constantPool[classIndex].intValue()] + "." + constantPool[nameAndType >>> 16] + " " + constantPool[nameAndType & 0xffff]; - return className; - } - - private Constant getConstant(int constantRef) { - Constant c = constantPool[constantRef]; - switch (c.getType()) { - case INT: - case FLOAT: - case DOUBLE: - case LONG: - return c; - case STRING_REF: - return constantPool[c.intValue()]; - default: - throw new RuntimeException("Not a constant: " + constantRef); - } - } - - private String readString() { - int size = readShort(); - byte[] buff = data; - int p = pos, end = p + size; - char[] chars = new char[size]; - int j = 0; - for (; p < end; j++) { - int x = buff[p++] & 0xff; - if (x < 0x80) { - chars[j] = (char) x; - } else if (x >= 0xe0) { - chars[j] = (char) (((x & 0xf) << 12) + ((buff[p++] & 0x3f) << 6) + (buff[p++] & 0x3f)); - } else { - chars[j] = (char) (((x & 0x1f) << 6) + (buff[p++] & 0x3f)); - } - } - pos = p; - return new String(chars, 0, j); - } - - private int getAbsolutePos(int start, int offset) { - return start - startByteCode - 1 + (short) offset; - } - - private int readByte() { - return data[pos++] & 0xff; - } - - private int readShort() { - byte[] buff = data; - return ((buff[pos++] & 0xff) << 8) + (buff[pos++] & 0xff); - } - - private int readInt() { - byte[] buff = data; - return (buff[pos++] << 24) + ((buff[pos++] & 0xff) << 16) + ((buff[pos++] & 0xff) << 8) + (buff[pos++] & 0xff); - } - - private long readLong() { - return ((long) (readInt()) << 32) + (readInt() & 0xffffffffL); - } - -} diff --git a/tools/h2/src/tools/org/h2/jaqu/bytecode/Constant.java b/tools/h2/src/tools/org/h2/jaqu/bytecode/Constant.java deleted file mode 100755 index a1da5d3..0000000 --- a/tools/h2/src/tools/org/h2/jaqu/bytecode/Constant.java +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.jaqu.bytecode; - -import org.h2.jaqu.Token; - -/** - * An expression in the constant pool. - */ -public interface Constant extends Token { - - /** - * The constant pool type. - */ - enum Type { - STRING, - INT, - FLOAT, - DOUBLE, - LONG, - CLASS_REF, - STRING_REF, - FIELD_REF, - METHOD_REF, - INTERFACE_METHOD_REF, - NAME_AND_TYPE - } - - Constant.Type getType(); - - int intValue(); - -} diff --git a/tools/h2/src/tools/org/h2/jaqu/bytecode/ConstantNumber.java b/tools/h2/src/tools/org/h2/jaqu/bytecode/ConstantNumber.java deleted file mode 100755 index 4eb5c65..0000000 --- a/tools/h2/src/tools/org/h2/jaqu/bytecode/ConstantNumber.java +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.jaqu.bytecode; - -import org.h2.jaqu.Query; -import org.h2.jaqu.SQLStatement; - -/** - * A literal number. - */ -public class ConstantNumber implements Constant { - - private final String value; - private final Type type; - private final long longValue; - - private ConstantNumber(String value, long longValue, Type type) { - this.value = value; - this.longValue = longValue; - this.type = type; - } - - static ConstantNumber get(String v) { - return new ConstantNumber(v, 0, Type.STRING); - } - - static ConstantNumber get(int v) { - return new ConstantNumber("" + v, v, Type.INT); - } - - static ConstantNumber get(long v) { - return new ConstantNumber("" + v, v, Type.LONG); - } - - static ConstantNumber get(String s, long x, Type type) { - return new ConstantNumber(s, x, type); - } - - public int intValue() { - return (int) longValue; - } - - public String toString() { - return value; - } - - public void appendSQL(SQLStatement stat, Query query) { - stat.appendSQL(toString()); - } - - public Constant.Type getType() { - return type; - } - -} diff --git a/tools/h2/src/tools/org/h2/jaqu/bytecode/ConstantString.java b/tools/h2/src/tools/org/h2/jaqu/bytecode/ConstantString.java deleted file mode 100755 index 2ddf82f..0000000 --- a/tools/h2/src/tools/org/h2/jaqu/bytecode/ConstantString.java +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.jaqu.bytecode; - -import org.h2.jaqu.Query; -import org.h2.jaqu.SQLStatement; -import org.h2.util.StringUtils; - -/** - * A string constant. - */ -public class ConstantString implements Constant { - - private final String value; - - private ConstantString(String value) { - this.value = value; - } - - static ConstantString get(String v) { - return new ConstantString(v); - } - - public String toString() { - return value; - } - - public int intValue() { - return 0; - } - - public void appendSQL(SQLStatement stat, Query query) { - stat.appendSQL(StringUtils.quoteStringSQL(value)); - } - - public Constant.Type getType() { - return Constant.Type.STRING; - } - -} diff --git a/tools/h2/src/tools/org/h2/jaqu/bytecode/Function.java b/tools/h2/src/tools/org/h2/jaqu/bytecode/Function.java deleted file mode 100755 index 9bfcff4..0000000 --- a/tools/h2/src/tools/org/h2/jaqu/bytecode/Function.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.jaqu.bytecode; - -import org.h2.jaqu.Query; -import org.h2.jaqu.SQLStatement; -import org.h2.jaqu.Token; - -/** - * A method call. - */ -class Function implements Token { - - private final String name; - private final Token expr; - - Function(String name, Token expr) { - this.name = name; - this.expr = expr; - } - - public String toString() { - return name + "(" + expr + ")"; - } - - public void appendSQL(SQLStatement stat, Query query) { - // untested - stat.appendSQL(name + "("); - expr.appendSQL(stat, query); - stat.appendSQL(")"); - } -} diff --git a/tools/h2/src/tools/org/h2/jaqu/bytecode/Not.java b/tools/h2/src/tools/org/h2/jaqu/bytecode/Not.java deleted file mode 100755 index f558c8e..0000000 --- a/tools/h2/src/tools/org/h2/jaqu/bytecode/Not.java +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.jaqu.bytecode; - -import org.h2.jaqu.Query; -import org.h2.jaqu.SQLStatement; -import org.h2.jaqu.Token; - -/** - * A NOT condition. - */ -public class Not implements Token { - - private Token expr; - - private Not(Token expr) { - this.expr = expr; - } - - static Token get(Token expr) { - if (expr instanceof Not) { - return ((Not) expr).expr; - } else if (expr instanceof Operation) { - return ((Operation) expr).reverse(); - } - return new Not(expr); - } - - Token not() { - return expr; - } - - public void appendSQL(SQLStatement stat, Query query) { - // untested - stat.appendSQL("NOT("); - expr.appendSQL(stat, query); - stat.appendSQL(")"); - } - -} diff --git a/tools/h2/src/tools/org/h2/jaqu/bytecode/Null.java b/tools/h2/src/tools/org/h2/jaqu/bytecode/Null.java deleted file mode 100755 index c08f1cf..0000000 --- a/tools/h2/src/tools/org/h2/jaqu/bytecode/Null.java +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.jaqu.bytecode; - -import org.h2.jaqu.Query; -import org.h2.jaqu.SQLStatement; -import org.h2.jaqu.Token; - -/** - * The Java 'null'. - */ -public class Null implements Token { - - static final Null INSTANCE = new Null(); - - private Null() { - // don't allow to create new instances - } - - public String toString() { - return "null"; - } - - public void appendSQL(SQLStatement stat, Query query) { - // untested - stat.appendSQL("NULL"); - } - -} diff --git a/tools/h2/src/tools/org/h2/jaqu/bytecode/Operation.java b/tools/h2/src/tools/org/h2/jaqu/bytecode/Operation.java deleted file mode 100755 index 32c7b80..0000000 --- a/tools/h2/src/tools/org/h2/jaqu/bytecode/Operation.java +++ /dev/null @@ -1,104 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.jaqu.bytecode; - -import org.h2.jaqu.Query; -import org.h2.jaqu.SQLStatement; -import org.h2.jaqu.Token; - -/** - * A mathematical or comparison operation. - */ -class Operation implements Token { - - /** - * The operation type. - */ - enum Type { - EQUALS("=") { - Type reverse() { - return NOT_EQUALS; - } - }, - NOT_EQUALS("<>") { - Type reverse() { - return EQUALS; - } - }, - BIGGER(">") { - Type reverse() { - return SMALLER_EQUALS; - } - }, - BIGGER_EQUALS(">=") { - Type reverse() { - return SMALLER; - } - }, - SMALLER_EQUALS("<=") { - Type reverse() { - return BIGGER; - } - }, - SMALLER("<") { - Type reverse() { - return BIGGER_EQUALS; - } - }, - ADD("+"), - SUBTRACT("-"), - MULTIPLY("*"), - DIVIDE("/"), - MOD("%"); - - private String name; - - Type(String name) { - this.name = name; - } - - public String toString() { - return name; - } - - Type reverse() { - return null; - } - - } - - private final Token left, right; - private final Type op; - - private Operation(Token left, Type op, Token right) { - this.left = left; - this.op = op; - this.right = right; - } - - static Token get(Token left, Type op, Token right) { - if (op == Type.NOT_EQUALS && "0".equals(right.toString())) { - return left; - } - return new Operation(left, op, right); - } - - public String toString() { - return left + " " + op + " " + right; - } - - public Token reverse() { - return get(left, op.reverse(), right); - } - - public void appendSQL(SQLStatement stat, Query query) { - left.appendSQL(stat, query); - stat.appendSQL(op.toString()); - right.appendSQL(stat, query); - } - -} diff --git a/tools/h2/src/tools/org/h2/jaqu/bytecode/Or.java b/tools/h2/src/tools/org/h2/jaqu/bytecode/Or.java deleted file mode 100755 index 8484c20..0000000 --- a/tools/h2/src/tools/org/h2/jaqu/bytecode/Or.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.jaqu.bytecode; - -import org.h2.jaqu.Query; -import org.h2.jaqu.SQLStatement; -import org.h2.jaqu.Token; - -/** - * An OR expression. - */ -public class Or implements Token { - - private final Token left, right; - - private Or(Token left, Token right) { - this.left = left; - this.right = right; - } - - static Or get(Token left, Token right) { - return new Or(left, right); - } - - public void appendSQL(SQLStatement stat, Query query) { - // untested - left.appendSQL(stat, query); - stat.appendSQL(" OR "); - right.appendSQL(stat, query); - } - -} diff --git a/tools/h2/src/tools/org/h2/jaqu/bytecode/Variable.java b/tools/h2/src/tools/org/h2/jaqu/bytecode/Variable.java deleted file mode 100755 index 8562ce6..0000000 --- a/tools/h2/src/tools/org/h2/jaqu/bytecode/Variable.java +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.jaqu.bytecode; - -import org.h2.jaqu.Query; -import org.h2.jaqu.SQLStatement; -import org.h2.jaqu.Token; - -/** - * A variable. - */ -public class Variable implements Token { - - static final Variable THIS = new Variable("this", null); - - private final String name; - private final Object obj; - - private Variable(String name, Object obj) { - this.name = name; - this.obj = obj; - } - - static Variable get(String name, Object obj) { - return new Variable(name, obj); - } - - public String toString() { - return name; - } - - public void appendSQL(SQLStatement stat, Query query) { - query.appendSQL(stat, obj); - } - -} diff --git a/tools/h2/src/tools/org/h2/jaqu/bytecode/package.html b/tools/h2/src/tools/org/h2/jaqu/bytecode/package.html deleted file mode 100755 index a22a771..0000000 --- a/tools/h2/src/tools/org/h2/jaqu/bytecode/package.html +++ /dev/null @@ -1,15 +0,0 @@ - - - - -Javadoc package documentation -

    - -The decompiler for the JaQu (Java Query) tool. - -

    \ No newline at end of file diff --git a/tools/h2/src/tools/org/h2/jaqu/package.html b/tools/h2/src/tools/org/h2/jaqu/package.html deleted file mode 100755 index 125731d..0000000 --- a/tools/h2/src/tools/org/h2/jaqu/package.html +++ /dev/null @@ -1,15 +0,0 @@ - - - - -Javadoc package documentation -

    - -The implementation of the JaQu (Java Query) tool. - -

    \ No newline at end of file diff --git a/tools/h2/src/tools/org/h2/jaqu/util/ClassUtils.java b/tools/h2/src/tools/org/h2/jaqu/util/ClassUtils.java deleted file mode 100755 index b84c6c5..0000000 --- a/tools/h2/src/tools/org/h2/jaqu/util/ClassUtils.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.jaqu.util; - - -/** - * This utility class contains functions related to class loading. - * There is a mechanism to restrict class loading. - */ -public class ClassUtils { - - private ClassUtils() { - // utility class - } - -//## Java 1.5 begin ## - - @SuppressWarnings("unchecked") - public static Class getClass(X x) { - return (Class) x.getClass(); - } - - public static Class< ? > loadClass(String className) { - try { - return Class.forName(className); - } catch (Exception e) { - throw new RuntimeException(e); - } - } -//## Java 1.5 end ## -} diff --git a/tools/h2/src/tools/org/h2/jaqu/util/Message.java b/tools/h2/src/tools/org/h2/jaqu/util/Message.java deleted file mode 100755 index c0ff9e6..0000000 --- a/tools/h2/src/tools/org/h2/jaqu/util/Message.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.jaqu.util; - -import java.io.IOException; -import java.lang.reflect.InvocationTargetException; -import java.sql.SQLException; - -/** - * Messages used in the database engine. - * Use the PropertiesToUTF8 tool to translate properties files to UTF-8 and back. - * If the word 'SQL' appears then the whole SQL statement must be a parameter, - * otherwise this may be added: '; SQL statement: ' + sql - */ -public class Message { - - private Message() { - // utility class - } - - /** - * Convert an exception to a SQL exception using the default mapping. - * - * @param e the root cause - * @return the SQL exception object - */ - public static SQLException convert(Throwable e) { - if (e instanceof SQLException) { - return (SQLException) e; - } - String message; - if (e instanceof InvocationTargetException) { - InvocationTargetException te = (InvocationTargetException) e; - Throwable t = te.getTargetException(); - if (t instanceof SQLException) { - return (SQLException) t; - } - message = "Invocation exception"; - } else if (e instanceof IOException) { - message = "IO exception"; - } else { - message = "General exception"; - } - SQLException e2 = new SQLException(message + ": " + e.toString()); - e2.initCause(e); - return e2; - } - -} diff --git a/tools/h2/src/tools/org/h2/jaqu/util/Utils.java b/tools/h2/src/tools/org/h2/jaqu/util/Utils.java deleted file mode 100755 index 5740c0f..0000000 --- a/tools/h2/src/tools/org/h2/jaqu/util/Utils.java +++ /dev/null @@ -1,156 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.jaqu.util; - -//## Java 1.5 begin ## -import java.lang.reflect.Constructor; -import java.math.BigDecimal; -import java.math.BigInteger; -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashMap; -import java.util.IdentityHashMap; -import java.util.List; -import java.util.Map; -//## Java 1.5 end ## - -/** - * Generic utility methods. - */ -public class Utils { -//## Java 1.5 begin ## - - private static volatile long counter; - - private static final boolean MAKE_ACCESSIBLE = true; - - public static ArrayList newArrayList() { - return new ArrayList(); - } - - public static HashMap newHashMap() { - return new HashMap(); - } - - public static Map newSynchronizedHashMap() { - HashMap map = newHashMap(); - return Collections.synchronizedMap(map); - } - - public static WeakIdentityHashMap newWeakIdentityHashMap() { - return new WeakIdentityHashMap(); - } - - public static IdentityHashMap newIdentityHashMap() { - return new IdentityHashMap(); - } - - @SuppressWarnings("unchecked") - public static T newObject(Class clazz) { - // must create new instances - if (clazz == Integer.class) { - return (T) new Integer((int) counter++); - } else if (clazz == String.class) { - return (T) ("" + counter++); - } else if (clazz == Long.class) { - return (T) new Long(counter++); - } else if (clazz == Short.class) { - return (T) new Short((short) counter++); - } else if (clazz == Byte.class) { - return (T) new Byte((byte) counter++); - } else if (clazz == Float.class) { - return (T) new Float(counter++); - } else if (clazz == Double.class) { - return (T) new Double(counter++); - } else if (clazz == Boolean.class) { - return (T) new Boolean(false); - } else if (clazz == BigDecimal.class) { - return (T) new BigDecimal(counter++); - } else if (clazz == BigInteger.class) { - return (T) new BigInteger("" + counter++); - } else if (clazz == java.sql.Date.class) { - return (T) new java.sql.Date(counter++); - } else if (clazz == java.sql.Time.class) { - return (T) new java.sql.Time(counter++); - } else if (clazz == java.sql.Timestamp.class) { - return (T) new java.sql.Timestamp(counter++); - } else if (clazz == java.util.Date.class) { - return (T) new java.util.Date(counter++); - } else if (clazz == List.class) { - return (T) new ArrayList(); - } - try { - return clazz.newInstance(); - } catch (Exception e) { - if (MAKE_ACCESSIBLE) { - Constructor[] constructors = clazz.getDeclaredConstructors(); - // try 0 length constructors - for (Constructor c : constructors) { - if (c.getParameterTypes().length == 0) { - c.setAccessible(true); - try { - return clazz.newInstance(); - } catch (Exception e2) { - // ignore - } - } - } - // try 1 length constructors - for (Constructor c : constructors) { - if (c.getParameterTypes().length == 1) { - c.setAccessible(true); - try { - return (T) c.newInstance(new Object[1]); - } catch (Exception e2) { - // ignore - } - } - } - } - throw new RuntimeException("Exception trying to create " + - clazz.getName() + ": " + e, e); - } - } - - public static boolean isSimpleType(Class clazz) { - if (Number.class.isAssignableFrom(clazz)) { - return true; - } else if (clazz == String.class) { - return true; - } - return false; - } - - public static Object convert(Object o, Class< ? > targetType) { - if (o == null) { - return null; - } - Class< ? > currentType = o.getClass(); - if (targetType.isAssignableFrom(currentType)) { - return o; - } - if (targetType == String.class) { - return o.toString(); - } - if (Number.class.isAssignableFrom(currentType)) { - Number n = (Number) o; - if (targetType == Integer.class) { - return n.intValue(); - } else if (targetType == Long.class) { - return n.longValue(); - } else if (targetType == Double.class) { - return n.doubleValue(); - } else if (targetType == Float.class) { - return n.floatValue(); - } - } - throw new RuntimeException("Can not convert the value " + o + - " from " + currentType + " to " + targetType); - } - -//## Java 1.5 end ## -} diff --git a/tools/h2/src/tools/org/h2/jaqu/util/WeakIdentityHashMap.java b/tools/h2/src/tools/org/h2/jaqu/util/WeakIdentityHashMap.java deleted file mode 100755 index 28d28c1..0000000 --- a/tools/h2/src/tools/org/h2/jaqu/util/WeakIdentityHashMap.java +++ /dev/null @@ -1,230 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.jaqu.util; - -//## Java 1.5 begin ## -import java.lang.ref.WeakReference; -import java.util.Collection; -import java.util.Map; -import java.util.Set; -//## Java 1.5 end ## - -/** - * This hash map uses weak references, so that elements that are no longer - * referenced elsewhere can be garbage collected. It also uses object identity - * to compare keys. - * - * @param the keys - * @param the value - */ -//## Java 1.5 begin ## -public class WeakIdentityHashMap implements Map { - private static final int MAX_LOAD = 90; - private static final WeakReference DELETED_KEY = - new WeakReference(null); - private int mask, len, size, deletedCount, level; - private int maxSize, minSize, maxDeleted; - private WeakReference[] keys; - private V[] values; - - public WeakIdentityHashMap() { - reset(2); - } - - public int size() { - return size; - } - - private void checkSizePut() { - if (deletedCount > size) { - rehash(level); - } - if (size + deletedCount >= maxSize) { - rehash(level + 1); - } - } - - private void checkSizeRemove() { - if (size < minSize && level > 0) { - rehash(level - 1); - } else if (deletedCount > maxDeleted) { - rehash(level); - } - } - - private int getIndex(Object key) { - return System.identityHashCode(key) & mask; - } - - @SuppressWarnings("unchecked") - private void reset(int newLevel) { - minSize = size * 3 / 4; - size = 0; - level = newLevel; - len = 2 << level; - mask = len - 1; - maxSize = (int) (len * MAX_LOAD / 100L); - deletedCount = 0; - maxDeleted = 20 + len / 2; - keys = new WeakReference[len]; - values = (V[]) new Object[len]; - } - - public V put(K key, V value) { - checkSizePut(); - int index = getIndex(key); - int plus = 1; - int deleted = -1; - do { - WeakReference k = keys[index]; - if (k == null) { - // found an empty record - if (deleted >= 0) { - index = deleted; - deletedCount--; - } - size++; - keys[index] = new WeakReference(key); - values[index] = value; - return null; - } else if (k == DELETED_KEY) { - if (deleted < 0) { - // found the first deleted record - deleted = index; - } - } else { - Object r = k.get(); - if (r == null) { - delete(index); - } else if (r == key) { - // update existing - V old = values[index]; - values[index] = value; - return old; - } - } - index = (index + plus++) & mask; - } while(plus <= len); - throw new RuntimeException("Hashmap is full"); - } - - public V remove(Object key) { - checkSizeRemove(); - int index = getIndex(key); - int plus = 1; - do { - WeakReference k = keys[index]; - if (k == null) { - // found an empty record - return null; - } else if (k == DELETED_KEY) { - // continue - } else { - Object r = k.get(); - if (r == null) { - delete(index); - } else if (r == key) { - // found the record - V old = values[index]; - delete(index); - return old; - } - } - index = (index + plus++) & mask; - k = keys[index]; - } while(plus <= len); - // not found - return null; - } - - @SuppressWarnings("unchecked") - private void delete(int index) { - keys[index] = (WeakReference) DELETED_KEY; - values[index] = null; - deletedCount++; - size--; - } - - private void rehash(int newLevel) { - WeakReference[] oldKeys = keys; - V[] oldValues = values; - reset(newLevel); - for (int i = 0; i < oldKeys.length; i++) { - WeakReference k = oldKeys[i]; - if (k != null && k != DELETED_KEY) { - K key = k.get(); - if (key != null) { - put(key, oldValues[i]); - } - } - } - } - - public V get(Object key) { - int index = getIndex(key); - int plus = 1; - do { - WeakReference k = keys[index]; - if (k == null) { - return null; - } else if (k == DELETED_KEY) { - // continue - } else { - Object r = k.get(); - if (r == null) { - delete(index); - } else if (r == key) { - return values[index]; - } - } - index = (index + plus++) & mask; - } while(plus <= len); - return null; - } - - public void clear() { - reset(2); - } - - public boolean containsKey(Object key) { - return get(key) != null; - } - - public boolean containsValue(Object value) { - if (value == null) { - return false; - } - for (V item: values) { - if (value.equals(item)) { - return true; - } - } - return false; - } - - public Set> entrySet() { - throw new UnsupportedOperationException(); - } - - public boolean isEmpty() { - return size == 0; - } - - public Set keySet() { - throw new UnsupportedOperationException(); - } - - public void putAll(Map< ? extends K, ? extends V> m) { - throw new UnsupportedOperationException(); - } - - public Collection values() { - throw new UnsupportedOperationException(); - } - -} -//## Java 1.5 end ## diff --git a/tools/h2/src/tools/org/h2/jaqu/util/package.html b/tools/h2/src/tools/org/h2/jaqu/util/package.html deleted file mode 100755 index 9323b58..0000000 --- a/tools/h2/src/tools/org/h2/jaqu/util/package.html +++ /dev/null @@ -1,15 +0,0 @@ - - - - -Javadoc package documentation -

    - -Utility classes used for the JaQu (Java Query) tool. - -

    \ No newline at end of file diff --git a/tools/h2/src/tools/org/h2/java/ClassObj.java b/tools/h2/src/tools/org/h2/java/ClassObj.java deleted file mode 100755 index a765037..0000000 --- a/tools/h2/src/tools/org/h2/java/ClassObj.java +++ /dev/null @@ -1,348 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.java; - -import java.util.ArrayList; -import java.util.LinkedHashMap; - -/** - * A class or interface. - */ -public class ClassObj { - - /** - * The super class (null for java.lang.Object or primitive types). - */ - String superClassName; - - /** - * The list of interfaces that this class implements. - */ - ArrayList interfaceNames = new ArrayList(); - - - /** - * The fully qualified class name. - */ - String className; - - /** - * Whether this is an interface. - */ - boolean isInterface; - - /** - * Whether this class is public. - */ - boolean isPublic; - - /** - * Whether this is a primitive class (int, char,...) - */ - boolean isPrimitive; - - /** - * The primitive type (higher types are more complex) - */ - int primitiveType; - - /** - * The imported classes. - */ - ArrayList imports = new ArrayList(); - - /** - * The per-instance fields. - */ - LinkedHashMap instanceFields = new LinkedHashMap(); - - /** - * The static fields of this class. - */ - LinkedHashMap staticFields = new LinkedHashMap(); - - /** - * The methods. - */ - LinkedHashMap> methods = new LinkedHashMap>(); - - /** - * The list of native statements. - */ - ArrayList nativeCode = new ArrayList(); - - /** - * The class number. - */ - int id; - - /** - * Get the base type of this class. - */ - Type baseType; - - ClassObj() { - baseType = new Type(); - baseType.classObj = this; - } - - /** - * Add a method. - * - * @param method the method - */ - void addMethod(MethodObj method) { - ArrayList list = methods.get(method.name); - if (list == null) { - list = new ArrayList(); - methods.put(method.name, list); - } else { - method.name = method.name + "_" + (list.size() + 1); - } - list.add(method); - } - - /** - * Add an instance field. - * - * @param field the field - */ - void addInstanceField(FieldObj field) { - instanceFields.put(field.name, field); - } - - /** - * Add a static field. - * - * @param field the field - */ - void addStaticField(FieldObj field) { - staticFields.put(field.name, field); - } - - public String toString() { - if (isPrimitive) { - return "j" + className; - } - return className; - } - - /** - * Get the method. - * - * @param find the method name in the source code - * @param args the parameters - * @return the method - */ - MethodObj getMethod(String find, ArrayList args) { - ArrayList list = methods.get(find); - if (list == null) { - throw new RuntimeException("Method not found: " + className + " " + find); - } - if (list.size() == 1) { - return list.get(0); - } - for (MethodObj m : list) { - if (!m.isVarArgs && m.parameters.size() != args.size()) { - continue; - } - boolean match = true; - int i = 0; - for (FieldObj f : m.parameters.values()) { - Expr a = args.get(i++); - Type t = a.getType(); - if (!t.equals(f.type)) { - match = false; - break; - } - } - if (match) { - return m; - } - } - throw new RuntimeException("Method not found: " + className); - } - - /** - * Get the field with the given name. - * - * @param name the field name - * @return the field - */ - FieldObj getField(String name) { - return instanceFields.get(name); - } - -} - -/** - * A method. - */ -class MethodObj { - - /** - * Whether the last parameter is a var args parameter. - */ - boolean isVarArgs; - - /** - * Whether this method is static. - */ - boolean isStatic; - - /** - * Whether this method is private. - */ - boolean isPrivate; - - /** - * Whether this method is overridden. - */ - boolean isVirtual; - - /** - * The name. - */ - String name; - - /** - * The statement block (if any). - */ - Statement block; - - /** - * The return type. - */ - Type returnType; - - /** - * The parameter list. - */ - LinkedHashMap parameters = new LinkedHashMap(); - - /** - * Whether this method is final. - */ - boolean isFinal; - - /** - * Whether this method is public. - */ - boolean isPublic; - - /** - * Whether this method is native. - */ - boolean isNative; - - /** - * Whether this is a constructor. - */ - boolean isConstructor; -} - -/** - * A field. - */ -class FieldObj { - - /** - * The type. - */ - Type type; - - /** - * Whether this is a local field. - */ - boolean isLocal; - - /** - * The field name. - */ - String name; - - /** - * Whether this field is static. - */ - boolean isStatic; - - /** - * Whether this field is final. - */ - boolean isFinal; - - /** - * Whether this field is private. - */ - boolean isPrivate; - - /** - * Whether this field is public. - */ - boolean isPublic; - - /** - * The initial value expression (may be null). - */ - Expr value; - - /** - * The class where this field is declared. - */ - ClassObj declaredClass; - -} - -/** - * A type. - */ -class Type { - - /** - * The class. - */ - ClassObj classObj; - - /** - * The array nesting level. 0 if not an array. - */ - int arrayLevel; - - /** - * Whether this is a var args parameter. - */ - boolean isVarArgs; - - public String toString() { - StringBuilder buff = new StringBuilder(); - buff.append(JavaParser.toC(classObj.toString())); - if (!classObj.isPrimitive) { - buff.append("*"); - } - for (int i = 0; i < arrayLevel; i++) { - buff.append("*"); - } - return buff.toString(); - } - - boolean isObject() { - return arrayLevel > 0 || !classObj.isPrimitive; - } - - public int hashCode() { - return toString().hashCode(); - } - - public boolean equals(Object other) { - if (other instanceof Type) { - return this.toString().equals(other.toString()); - } - return false; - } - -} - diff --git a/tools/h2/src/tools/org/h2/java/Expr.java b/tools/h2/src/tools/org/h2/java/Expr.java deleted file mode 100755 index 0092e18..0000000 --- a/tools/h2/src/tools/org/h2/java/Expr.java +++ /dev/null @@ -1,518 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.java; - -import java.util.ArrayList; - -/** - * An expression. - */ -public interface Expr { - // toString - Type getType(); -} - -/** - * A method call. - */ -class CallExpr implements Expr { - - final JavaParser context; - final Expr expr; - final ArrayList args = new ArrayList(); - final boolean isStatic; - final String className; - final String name; - private ClassObj classObj; - private MethodObj method; - - CallExpr(JavaParser context, Expr expr, String className, String name, boolean isStatic) { - this.context = context; - this.expr = expr; - this.className = className; - this.name = name; - this.isStatic = isStatic; - } - - private void initMethod() { - if (method != null) { - return; - } - if (className != null) { - classObj = context.getClassObj(className); - } else { - classObj = expr.getType().classObj; - } - method = classObj.getMethod(name, args); - } - - public String toString() { - StringBuilder buff = new StringBuilder(); - String methodName; - initMethod(); - if (method.isVirtual) { - methodName = "virtual_" + method.name + "[CLASS_ID("+expr.toString()+")]"; - } else { - methodName = JavaParser.toC(classObj.toString() + "." + method.name); - } - buff.append(methodName).append("("); - int i = 0; - if (expr != null) { - buff.append(expr.toString()); - i++; - } - for (Expr a : args) { - if (i > 0) { - buff.append(", "); - } - i++; - buff.append(a); - } - return buff.append(")").toString(); - } - - public Type getType() { - initMethod(); - return method.returnType; - } - -} - -/** - * A assignment expression. - */ -class AssignExpr implements Expr { - - Expr left; - String op; - Expr right; - - public String toString() { - return left + " " + op + " " + right; - } - - public Type getType() { - // TODO - return null; - } - -} - -/** - * A conditional expression. - */ -class ConditionalExpr implements Expr { - - Expr condition; - Expr ifTrue, ifFalse; - - public String toString() { - return condition + " ? " + ifTrue + " : " + ifFalse; - } - - public Type getType() { - // TODO - return null; - } - -} - -/** - * A literal. - */ -class LiteralExpr implements Expr { - - String literal; - private final JavaParser context; - private final String className; - private Type type; - - public LiteralExpr(JavaParser context, String className) { - this.context = context; - this.className = className; - } - - public String toString() { - return literal; - } - - public Type getType() { - if (type == null) { - type = new Type(); - type.classObj = context.getClassObj(className); - } - return type; - } - -} - -/** - * An operation. - */ -class OpExpr implements Expr { - - Expr left; - String op; - Expr right; - private final JavaParser context; - - OpExpr(JavaParser context) { - this.context = context; - } - - public String toString() { - if (left == null) { - return op + right; - } else if (right == null) { - return left + op; - } - if (op.equals(">>>")) { - // ujint / ujlong - return "(((u" + left.getType() + ") " + left + ") >> " + right + ")"; - } else if (op.equals("+")) { - if (left.getType().isObject() || right.getType().isObject()) { - // TODO convert primitive to to String, call toString - StringBuilder buff = new StringBuilder(); - buff.append("java_lang_StringBuilder_toString("); - buff.append("java_lang_StringBuilder_append("); - buff.append("java_lang_StringBuilder_init_obj("); - buff.append(convertToString(left)); - buff.append("), "); - buff.append(convertToString(right)); - buff.append("))"); - return buff.toString(); - } - } - return "(" + left + " " + op + " " + right + ")"; - } - - private String convertToString(Expr e) { - Type t = e.getType(); - if (t.arrayLevel > 0) { - return e.toString() + ".toString()"; - } - if (t.classObj.isPrimitive) { - ClassObj wrapper = context.getWrapper(t.classObj); - return JavaParser.toC(wrapper + ".toString") + "(" + e.toString() + ")"; - } else if (e.getType().toString().equals("java_lang_String*")) { - return e.toString(); - } - return e.toString() + ".toString()"; - } - - public Type getType() { - if (left == null) { - return right.getType(); - } - if (right == null) { - return left.getType(); - } - if (op.equals("+")) { - if (left.getType().isObject() || right.getType().isObject()) { - Type t = new Type(); - t.classObj = context.getClassObj("java.lang.String"); - return t; - } - } - Type lt = left.getType(); - Type rt = right.getType(); - if (lt.classObj.primitiveType < rt.classObj.primitiveType) { - return rt; - } - return lt; - } - -} - -/** - * A "new" expression. - */ -class NewExpr implements Expr { - - ClassObj classObj; - ArrayList arrayInitExpr = new ArrayList(); - ArrayList args = new ArrayList(); - final JavaParser context; - - NewExpr(JavaParser context) { - this.context = context; - } - - public String toString() { - StringBuilder buff = new StringBuilder(); - if (arrayInitExpr.size() > 0) { - if (classObj.isPrimitive) { - buff.append("NEW_ARRAY(sizeof(" + classObj + ")"); - buff.append(", 1 "); - for (Expr e : arrayInitExpr) { - buff.append("* ").append(e); - } - buff.append(")"); - } else { - buff.append("NEW_OBJ_ARRAY(1 "); - for (Expr e : arrayInitExpr) { - buff.append("* ").append(e); - } - buff.append(")"); - } - } else { - MethodObj m = classObj.getMethod("init_obj", args); - buff.append(JavaParser.toC(classObj.toString() + "." + m.name)).append("("); - int i = 0; - for (Expr a : args) { - if (i++ > 0) { - buff.append(", "); - } - buff.append(a); - } - buff.append(")"); - } - return buff.toString(); - } - - public Type getType() { - Type t = new Type(); - t.classObj = classObj; - t.arrayLevel = arrayInitExpr.size(); - return t; - } - -} - -/** - * A String literal. - */ -class StringExpr implements Expr { - - /** - * The literal. - */ - String text; - - private final JavaParser context; - private Type type; - - StringExpr(JavaParser context) { - this.context = context; - } - - public String toString() { - return "STRING(\"" + javaEncode(text) + "\")"; - } - - public Type getType() { - if (type == null) { - type = new Type(); - type.classObj = context.getClassObj("java.lang.String"); - } - return type; - } - - /** - * Encode the String to Java syntax. - * - * @param s the string - * @return the encoded string - */ - static String javaEncode(String s) { - StringBuilder buff = new StringBuilder(s.length()); - for (int i = 0; i < s.length(); i++) { - char c = s.charAt(i); - switch (c) { - case '\t': - // HT horizontal tab - buff.append("\\t"); - break; - case '\n': - // LF linefeed - buff.append("\\n"); - break; - case '\f': - // FF form feed - buff.append("\\f"); - break; - case '\r': - // CR carriage return - buff.append("\\r"); - break; - case '"': - // double quote - buff.append("\\\""); - break; - case '\\': - // backslash - buff.append("\\\\"); - break; - default: - int ch = c & 0xffff; - if (ch >= ' ' && (ch < 0x80)) { - buff.append(c); - // not supported in properties files - // } else if(ch < 0xff) { - // buff.append("\\"); - // // make sure it's three characters (0x200 is octal 1000) - // buff.append(Integer.toOctalString(0x200 | ch).substring(1)); - } else { - buff.append("\\u"); - // make sure it's four characters - buff.append(Integer.toHexString(0x10000 | ch).substring(1)); - } - } - } - return buff.toString(); - } -} - -/** - * A variable. - */ -class VariableExpr implements Expr { - - Expr base; - FieldObj field; - String name; - private final JavaParser context; - - VariableExpr(JavaParser context) { - this.context = context; - } - - public String toString() { - init(); - StringBuilder buff = new StringBuilder(); - if ("length".equals(name) && base.getType().arrayLevel > 0) { - buff.append("LENGTH("); - buff.append(base.toString()); - buff.append(")"); - } else { - if (base != null) { - buff.append(base.toString()).append("->"); - } - if (field != null) { - if (field.isStatic) { - buff.append(JavaParser.toC(field.declaredClass + "." + field.name)); - } else { - buff.append(field.name); - } - } else { - buff.append(JavaParser.toC(name)); - } - } - return buff.toString(); - } - - private void init() { - if (field == null) { - Type t = base.getType(); - if (t.arrayLevel > 0) { - if ("length".equals(name)) { - field = new FieldObj(); - field.type = context.getClassObj("int").baseType; - } else { - throw new RuntimeException("Unknown array method: " + name); - } - } else { - field = t.classObj.getField(name); - } - } - } - - public Type getType() { - init(); - return field.type; - } - -} - -/** - * A array access expression. - */ -class ArrayExpr implements Expr { - - Expr expr; - ArrayList indexes = new ArrayList(); - - public String toString() { - StringBuilder buff = new StringBuilder(); - buff.append(expr.toString()); - for (Expr e : indexes) { - buff.append('[').append(e.toString()).append(']'); - } - return buff.toString(); - } - - public Type getType() { - return expr.getType(); - } - -} - -/** - * An array initializer expression. - */ -class ArrayInitExpr implements Expr { - - Type type; - ArrayList list = new ArrayList(); - - public Type getType() { - return type; - } - - public String toString() { - StringBuilder buff = new StringBuilder("{ "); - int i = 0; - for (Expr e : list) { - if (i++ > 0) { - buff.append(", "); - } - buff.append(e.toString()); - } - buff.append(" }"); - return buff.toString(); - } - -} - -/** - * A type cast expression. - */ -class CastExpr implements Expr { - - Type type; - Expr expr; - - public Type getType() { - return type; - } - - public String toString() { - return "(" + type + ") " + expr; - } - -} - -/** - * An array access expression (get or set). - */ -class ArrayAccessExpr implements Expr { - - Expr base; - Expr index; - - public Type getType() { - Type t = new Type(); - t.classObj = base.getType().classObj; - t.arrayLevel = base.getType().arrayLevel - 1; - return t; - } - - public String toString() { - return base + "[" + index + "]"; - } - -} diff --git a/tools/h2/src/tools/org/h2/java/JavaParser.java b/tools/h2/src/tools/org/h2/java/JavaParser.java deleted file mode 100755 index 2404989..0000000 --- a/tools/h2/src/tools/org/h2/java/JavaParser.java +++ /dev/null @@ -1,1562 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.java; - -import java.io.IOException; -import java.io.PrintWriter; -import java.io.RandomAccessFile; -import java.text.ParseException; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.HashSet; -import java.util.LinkedHashMap; - -/** - * Converts Java to C. - */ -public class JavaParser { - - private static final int TOKEN_LITERAL_CHAR = 0; - private static final int TOKEN_LITERAL_STRING = 1; - private static final int TOKEN_LITERAL_NUMBER = 2; - private static final int TOKEN_RESERVED = 3; - private static final int TOKEN_IDENTIFIER = 4; - private static final int TOKEN_OTHER = 5; - - private static final HashSet RESERVED = new HashSet(); - private static final HashMap JAVA_IMPORT_MAP = new HashMap(); - - private final ArrayList allClasses = new ArrayList(); - private final HashMap builtInTypes = new HashMap(); - - private String source; - - private ParseState current = new ParseState(); - - private String packageName; - private ClassObj classObj; - private int nextClassId; - private MethodObj method; - private FieldObj thisPointer; - private HashMap importMap = new HashMap(); - private HashMap classes = new HashMap(); - private LinkedHashMap localVars = new LinkedHashMap(); - private HashMap allMethodsMap = new HashMap(); - - private ArrayList nativeHeaders = new ArrayList(); - - public JavaParser() { - addBuiltInTypes(); - } - - private void addBuiltInTypes() { - String[] list = { "abstract", "continue", "for", "new", "switch", "assert", "default", "if", - "package", "synchronized", "boolean", "do", "goto", "private", "this", "break", "double", "implements", - "protected", "throw", "byte", "else", "import", "public", "throws", "case", "enum", "instanceof", - "return", "transient", "catch", "extends", "int", "short", "try", "char", "final", "interface", - "static", "void", "class", "finally", "long", "strictfp", "volatile", "const", "float", "native", - "super", "while", "true", "false", "null" }; - for (String s : list) { - RESERVED.add(s); - } - int id = 0; - addBuiltInType(id++, true, 0, "void"); - addBuiltInType(id++, true, 1, "boolean"); - addBuiltInType(id++, true, 2, "byte"); - addBuiltInType(id++, true, 3, "short"); - addBuiltInType(id++, true, 4, "char"); - addBuiltInType(id++, true, 5, "int"); - addBuiltInType(id++, true, 6, "long"); - addBuiltInType(id++, true, 7, "float"); - addBuiltInType(id++, true, 8, "double"); - String[] java = { "Boolean", "Byte", "Character", "Class", "ClassLoader", "Double", "Float", - "Integer", "Long", "Math", "Number", "Object", "Runtime", "Short", "String", "StringBuffer", - "StringBuilder", "System", "Thread", "ThreadGroup", "ThreadLocal", "Throwable", "Void" }; - for (String s : java) { - JAVA_IMPORT_MAP.put(s, "java.lang." + s); - addBuiltInType(id++, false, 0, "java.lang." + s); - } - nextClassId = id; - } - - /** - * Get the wrapper class for the given primitive class. - * - * @param c the class - * @return the wrapper class - */ - ClassObj getWrapper(ClassObj c) { - switch (c.id) { - case 1: - return getClass("java.lang.Boolean"); - case 2: - return getClass("java.lang.Byte"); - case 3: - return getClass("java.lang.Short"); - case 4: - return getClass("java.lang.Character"); - case 5: - return getClass("java.lang.Integer"); - case 6: - return getClass("java.lang.Long"); - case 7: - return getClass("java.lang.Float"); - case 8: - return getClass("java.lang.Double"); - } - throw new RuntimeException("not a primitive type: " + classObj); - } - - private void addBuiltInType(int id, boolean primitive, int primitiveType, String type) { - ClassObj c = new ClassObj(); - c.id = id; - c.className = type; - c.isPrimitive = primitive; - c.primitiveType = primitiveType; - builtInTypes.put(type, c); - addClass(c); - } - - private void addClass(ClassObj c) { - int id = c.id; - while (id >= allClasses.size()) { - allClasses.add(null); - } - allClasses.set(id, c); - } - - /** - * Parse the source code. - * - * @param baseDir the base directory - * @param className the fully qualified name of the class to parse - */ - void parse(String baseDir, String className) { - String fileName = baseDir + "/" + className.replace('.', '/') + ".java"; - current = new ParseState(); - try { - RandomAccessFile file = new RandomAccessFile(fileName, "r"); - byte[] buff = new byte[(int) file.length()]; - file.readFully(buff); - source = new String(buff, "UTF-8"); - file.close(); - } catch (IOException e) { - throw new RuntimeException(e); - } - source = replaceUnicode(source); - source = removeRemarks(source); - try { - readToken(); - parseCompilationUnit(); - } catch (Exception e) { - throw new RuntimeException(source.substring(0, current.index) + "[*]" + source.substring(current.index), e); - } - } - - private String cleanPackageName(String name) { - if (name.startsWith("org.h2.java.lang") || name.startsWith("org.h2.java.io")) { - return name.substring("org.h2.".length()); - } - return name; - } - - private void parseCompilationUnit() { - if (readIf("package")) { - packageName = cleanPackageName(readQualifiedIdentifier()); - read(";"); - } - while (readIf("import")) { - String importPackageName = cleanPackageName(readQualifiedIdentifier()); - String importClass = importPackageName.substring(importPackageName.lastIndexOf('.') + 1); - importMap.put(importClass, importPackageName); - read(";"); - } - while (true) { - Statement s = readNativeStatementIf(); - if (s == null) { - break; - } - nativeHeaders.add(s); - } - while (true) { - boolean isPublic = readIf("public"); - boolean isInterface; - if (readIf("class")) { - isInterface = false; - } else { - read("interface"); - isInterface = true; - } - String name = readIdentifier(); - classObj = builtInTypes.get(packageName + "." + name); - if (classObj == null) { - classObj = new ClassObj(); - classObj.id = nextClassId++; - } - classObj.isPublic = isPublic; - classObj.isInterface = isInterface; - classObj.className = packageName == null ? "" : (packageName + ".") + name; - // import this class - importMap.put(name, classObj.className); - addClass(classObj); - classes.put(classObj.className, classObj); - if (readIf("extends")) { - classObj.superClassName = readQualifiedIdentifier(); - } - if (readIf("implements")) { - while (true) { - classObj.interfaceNames.add(readQualifiedIdentifier()); - if (!readIf(",")) { - break; - } - } - } - parseClassBody(); - if (current.token == null) { - break; - } - } - } - - private boolean isTypeOrIdentifier() { - if (builtInTypes.containsKey(current.token)) { - return true; - } - return current.type == TOKEN_IDENTIFIER; - } - - private ClassObj getClass(String type) { - ClassObj c = getClassIf(type); - if (c == null) { - throw new RuntimeException("Unknown type: " + type); - } - return c; - } - - private ClassObj getClassIf(String type) { - ClassObj c = builtInTypes.get(type); - if (c != null) { - return c; - } - c = classes.get(type); - if (c != null) { - return c; - } - String mappedType = importMap.get(type); - if (mappedType == null) { - mappedType = JAVA_IMPORT_MAP.get(type); - if (mappedType == null) { - return null; - } - } - c = classes.get(mappedType); - if (c == null) { - c = builtInTypes.get(mappedType); - if (c == null) { - throw new RuntimeException("Unknown class: " + mappedType); - } - } - return c; - } - - private void parseClassBody() { - read("{"); - localVars.clear(); - while (true) { - if (readIf("}")) { - break; - } - thisPointer = null; - while (true) { - Statement s = readNativeStatementIf(); - if (s == null) { - break; - } - classObj.nativeCode.add(s); - } - thisPointer = null; - boolean isStatic = false; - boolean isFinal = false; - boolean isPrivate = false; - boolean isPublic = false; - boolean isNative = false; - while (true) { - if (readIf("static")) { - isStatic = true; - } else if (readIf("final")) { - isFinal = true; - } else if (readIf("native")) { - isNative = true; - } else if (readIf("private")) { - isPrivate = true; - } else if (readIf("public")) { - isPublic = true; - } else { - break; - } - } - if (readIf("{")) { - method = new MethodObj(); - method.name = isStatic ? "cl_init_obj" : "init_obj"; - method.isStatic = isStatic; - localVars.clear(); - if (!isStatic) { - initThisPointer(); - } - method.block = readStatement(); - classObj.addMethod(method); - } else { - String typeName = readTypeOrIdentifier(); - Type type = readType(typeName); - method = new MethodObj(); - method.returnType = type; - method.isStatic = isStatic; - method.isFinal = isFinal; - method.isPublic = isPublic; - method.isPrivate = isPrivate; - method.isNative = isNative; - localVars.clear(); - if (!isStatic) { - initThisPointer(); - } - if (readIf("(")) { - if (type.classObj != classObj) { - throw getSyntaxException("Constructor of wrong type: " + type); - } - method.name = "init_obj"; - method.isConstructor = true; - parseFormalParameters(method); - if (!readIf(";")) { - method.block = readStatement(); - } - classObj.addMethod(method); - addMethod(method); - } else { - String name = readIdentifier(); - method.name = name; - if (readIf("(")) { - parseFormalParameters(method); - if (!readIf(";")) { - method.block = readStatement(); - } - classObj.addMethod(method); - addMethod(method); - } else { - FieldObj field = new FieldObj(); - field.type = type; - field.name = name; - field.isStatic = isStatic; - field.isFinal = isFinal; - field.isPublic = isPublic; - field.isPrivate = isPrivate; - field.declaredClass = classObj; - if (isStatic) { - classObj.addStaticField(field); - } else { - classObj.addInstanceField(field); - } - if (readIf("=")) { - if (field.type.arrayLevel > 0 && readIf("{")) { - field.value = readArrayInit(field.type); - } else { - field.value = readExpr(); - } - } - read(";"); - } - } - } - } - } - - private void addMethod(MethodObj m) { - if (m.isStatic) { - return; - } - MethodObj old = allMethodsMap.get(m.name); - if (old != null) { - old.isVirtual = true; - m.isVirtual = true; - } else { - allMethodsMap.put(m.name, m); - } - } - - private Expr readArrayInit(Type type) { - ArrayInitExpr expr = new ArrayInitExpr(); - expr.type = new Type(); - expr.type.classObj = type.classObj; - expr.type.arrayLevel = type.arrayLevel - 1; - if (!readIf("}")) { - while (true) { - expr.list.add(readExpr()); - if (readIf("}")) { - break; - } - read(","); - if (readIf("}")) { - break; - } - } - } - return expr; - } - - private void initThisPointer() { - thisPointer = new FieldObj(); - thisPointer.isLocal = true; - thisPointer.name = "this"; - thisPointer.type = new Type(); - thisPointer.type.classObj = classObj; - } - - private Type readType(String name) { - Type type = new Type(); - type.classObj = getClass(name); - while (readIf("[")) { - read("]"); - type.arrayLevel++; - } - if (readIf("...")) { - type.arrayLevel++; - type.isVarArgs = true; - } - return type; - } - - private void parseFormalParameters(MethodObj methodObj) { - if (readIf(")")) { - return; - } - while (true) { - FieldObj field = new FieldObj(); - field.isLocal = true; - String typeName = readTypeOrIdentifier(); - field.type = readType(typeName); - if (field.type.isVarArgs) { - methodObj.isVarArgs = true; - } - field.name = readIdentifier(); - methodObj.parameters.put(field.name, field); - if (readIf(")")) { - break; - } - read(","); - } - } - - private String readTypeOrIdentifier() { - if (current.type == TOKEN_RESERVED) { - if (builtInTypes.containsKey(current.token)) { - return read(); - } - } - String s = readIdentifier(); - while (readIf(".")) { - s += "." + readIdentifier(); - } - return s; - } - - private Statement readNativeStatementIf() { - if (readIf("//")) { - read(); - int start = current.index; - while (source.charAt(current.index) != '\n') { - current.index++; - } - StatementNative stat = new StatementNative(); - stat.code = source.substring(start, current.index).trim(); - read(); - return stat; - } else if (readIf("/*")) { - read(); - int start = current.index; - while (source.charAt(current.index) != '*' || source.charAt(current.index + 1) != '/') { - current.index++; - } - StatementNative stat = new StatementNative(); - stat.code = source.substring(start, current.index).trim(); - current.index += 2; - read(); - return stat; - } - return null; - } - - private Statement readStatement() { - Statement s = readNativeStatementIf(); - if (s != null) { - return s; - } - if (readIf(";")) { - return new EmptyStatement(); - } else if (readIf("{")) { - StatementBlock stat = new StatementBlock(); - while (true) { - if (readIf("}")) { - break; - } - stat.instructions.add(readStatement()); - } - return stat; - } else if (readIf("if")) { - IfStatement ifStat = new IfStatement(); - read("("); - ifStat.condition = readExpr(); - read(")"); - ifStat.block = readStatement(); - if (readIf("else")) { - ifStat.elseBlock = readStatement(); - } - return ifStat; - } else if (readIf("while")) { - WhileStatement whileStat = new WhileStatement(); - read("("); - whileStat.condition = readExpr(); - read(")"); - whileStat.block = readStatement(); - return whileStat; - } else if (readIf("break")) { - read(";"); - return new BreakStatement(); - } else if (readIf("continue")) { - read(";"); - return new ContinueStatement(); - } else if (readIf("switch")) { - SwitchStatement switchStat = new SwitchStatement(); - read("("); - switchStat.expr = readExpr(); - read(")"); - read("{"); - while (true) { - if (readIf("default")) { - read(":"); - StatementBlock block = new StatementBlock(); - switchStat.defaultBlock = block; - while (true) { - block.instructions.add(readStatement()); - if (current.token.equals("case") || current.token.equals("default") || current.token.equals("}")) { - break; - } - } - } else if (readIf("case")) { - switchStat.cases.add(readExpr()); - read(":"); - StatementBlock block = new StatementBlock(); - while (true) { - block.instructions.add(readStatement()); - if (current.token.equals("case") || current.token.equals("default") || current.token.equals("}")) { - break; - } - } - switchStat.blocks.add(block); - } else if (readIf("}")) { - break; - } - } - return switchStat; - } else if (readIf("for")) { - ForStatement forStat = new ForStatement(); - read("("); - ParseState back = copyParseState(); - try { - String typeName = readTypeOrIdentifier(); - Type type = readType(typeName); - String name = readIdentifier(); - FieldObj f = new FieldObj(); - f.name = name; - f.type = type; - f.isLocal = true; - localVars.put(name, f); - read(":"); - forStat.iterableType = type; - forStat.iterableVariable = name; - forStat.iterable = readExpr(); - } catch (Exception e) { - current = back; - forStat.init = readStatement(); - forStat.condition = readExpr(); - read(";"); - do { - forStat.updates.add(readExpr()); - } while (readIf(",")); - } - read(")"); - forStat.block = readStatement(); - return forStat; - } else if (readIf("do")) { - DoWhileStatement doWhileStat = new DoWhileStatement(); - doWhileStat.block = readStatement(); - read("while"); - read("("); - doWhileStat.condition = readExpr(); - read(")"); - read(";"); - return doWhileStat; - } else if (readIf("return")) { - ReturnStatement returnStat = new ReturnStatement(); - if (!readIf(";")) { - returnStat.expr = readExpr(); - read(";"); - } - return returnStat; - } else { - if (isTypeOrIdentifier()) { - ParseState start = copyParseState(); - String name = readTypeOrIdentifier(); - ClassObj c = getClassIf(name); - if (c != null) { - VarDecStatement dec = new VarDecStatement(); - dec.type = readType(name); - while (true) { - String varName = readIdentifier(); - Expr value = null; - if (readIf("=")) { - if (dec.type.arrayLevel > 0 && readIf("{")) { - value = readArrayInit(dec.type); - } else { - value = readExpr(); - } - } - FieldObj f = new FieldObj(); - f.isLocal = true; - f.type = dec.type; - f.name = varName; - localVars.put(varName, f); - dec.variables.add(varName); - dec.values.add(value); - if (readIf(";")) { - break; - } - read(","); - } - return dec; - } - current = start; - // ExprStatement - } - ExprStatement stat = new ExprStatement(); - stat.expr = readExpr(); - read(";"); - return stat; - } - } - - private ParseState copyParseState() { - ParseState state = new ParseState(); - state.index = current.index; - state.line = current.line; - state.token = current.token; - state.type = current.type; - return state; - } - - private Expr readExpr() { - Expr expr = readExpr1(); - String assign = current.token; - if (readIf("=") || readIf("+=") || readIf("-=") || readIf("*=") || readIf("/=") || readIf("&=") || readIf("|=") - || readIf("^=") || readIf("%=") || readIf("<<=") || readIf(">>=") || readIf(">>>=")) { - AssignExpr assignOp = new AssignExpr(); - assignOp.left = expr; - assignOp.op = assign; - assignOp.right = readExpr1(); - expr = assignOp; - } - return expr; - } - - private Expr readExpr1() { - Expr expr = readExpr2(); - if (readIf("?")) { - ConditionalExpr ce = new ConditionalExpr(); - ce.condition = expr; - ce.ifTrue = readExpr(); - read(":"); - ce.ifFalse = readExpr(); - return ce; - } - return expr; - } - - private Expr readExpr2() { - Expr expr = readExpr3(); - while (true) { - String infixOp = current.token; - if (readIf("||") || readIf("&&") || readIf("|") || readIf("^") || readIf("&") || readIf("==") || readIf("!=") - || readIf("<") || readIf(">") || readIf("<=") || readIf(">=") || readIf("<<") || readIf(">>") - || readIf(">>>") || readIf("+") || readIf("-") || readIf("*") || readIf("/") || readIf("%")) { - OpExpr opExpr = new OpExpr(this); - opExpr.left = expr; - opExpr.op = infixOp; - opExpr.right = readExpr3(); - expr = opExpr; - } else { - break; - } - } - return expr; - } - - private Expr readExpr3() { - if (readIf("(")) { - if (isTypeOrIdentifier()) { - ParseState start = copyParseState(); - String name = readTypeOrIdentifier(); - ClassObj c = getClassIf(name); - if (c != null) { - read(")"); - CastExpr expr = new CastExpr(); - expr.type = new Type(); - expr.type.classObj = c; - expr.expr = readExpr(); - return expr; - } - current = start; - } - Expr expr = readExpr(); - read(")"); - return expr; - } - String prefix = current.token; - if (readIf("++") || readIf("--") || readIf("!") || readIf("~") || readIf("+") || readIf("-")) { - OpExpr expr = new OpExpr(this); - expr.op = prefix; - expr.right = readExpr3(); - return expr; - } - Expr expr = readExpr4(); - String suffix = current.token; - if (readIf("++") || readIf("--")) { - OpExpr opExpr = new OpExpr(this); - opExpr.left = expr; - opExpr.op = suffix; - expr = opExpr; - } - return expr; - } - - private Expr readExpr4() { - if (readIf("false")) { - LiteralExpr expr = new LiteralExpr(this, "boolean"); - expr.literal = "false"; - return expr; - } - if (readIf("true")) { - LiteralExpr expr = new LiteralExpr(this, "boolean"); - expr.literal = "true"; - return expr; - } - if (readIf("null")) { - LiteralExpr expr = new LiteralExpr(this, "java.lang.Object"); - expr.literal = "null"; - return expr; - } - if (current.type == TOKEN_LITERAL_NUMBER) { - // TODO or long, float, double - LiteralExpr expr = new LiteralExpr(this, "int"); - expr.literal = current.token.substring(1); - readToken(); - return expr; - } - Expr expr; - expr = readExpr5(); - while (true) { - if (readIf(".")) { - String n = readIdentifier(); - if (readIf("(")) { - CallExpr e2 = new CallExpr(this, expr, null, n, false); - if (!readIf(")")) { - while (true) { - e2.args.add(readExpr()); - if (!readIf(",")) { - read(")"); - break; - } - } - } - expr = e2; - } else { - VariableExpr e2 = new VariableExpr(this); - e2.base = expr; - expr = e2; - e2.name = n; - } - } else if (readIf("[")) { - ArrayAccessExpr arrayExpr = new ArrayAccessExpr(); - arrayExpr.base = expr; - arrayExpr.index = readExpr(); - read("]"); - return arrayExpr; - } else { - break; - } - } - return expr; - } - - private Expr readExpr5() { - if (readIf("new")) { - NewExpr expr = new NewExpr(this); - String typeName = readTypeOrIdentifier(); - expr.classObj = getClass(typeName); - if (readIf("(")) { - if (!readIf(")")) { - while (true) { - expr.args.add(readExpr()); - if (!readIf(",")) { - read(")"); - break; - } - } - } - } else { - while (readIf("[")) { - expr.arrayInitExpr.add(readExpr()); - read("]"); - } - } - return expr; - } - if (current.type == TOKEN_LITERAL_STRING) { - StringExpr expr = new StringExpr(this); - expr.text = current.token.substring(1); - readToken(); - return expr; - } - if (readIf("this")) { - VariableExpr expr = new VariableExpr(this); - expr.field = thisPointer; - if (thisPointer == null) { - throw getSyntaxException("this usage in static context"); - } - return expr; - } - String name = readIdentifier(); - if (readIf("(")) { - VariableExpr t = new VariableExpr(this); - t.field = thisPointer; - CallExpr expr = new CallExpr(this, t, classObj.className, name, false); - if (!readIf(")")) { - while (true) { - expr.args.add(readExpr()); - if (!readIf(",")) { - read(")"); - break; - } - } - } - return expr; - } - VariableExpr expr = new VariableExpr(this); - FieldObj f = localVars.get(name); - if (f == null) { - f = method.parameters.get(name); - } - if (f == null) { - f = classObj.staticFields.get(name); - } - if (f == null) { - f = classObj.instanceFields.get(name); - } - if (f == null) { - String imp = importMap.get(name); - if (imp == null) { - imp = JAVA_IMPORT_MAP.get(name); - } - if (imp != null) { - name = imp; - if (readIf(".")) { - String n = readIdentifier(); - if (readIf("(")) { - CallExpr e2 = new CallExpr(this, null, imp, n, true); - if (!readIf(")")) { - while (true) { - e2.args.add(readExpr()); - if (!readIf(",")) { - read(")"); - break; - } - } - } - return e2; - } - VariableExpr e2 = new VariableExpr(this); - // static member variable - e2.name = imp + "." + n; - ClassObj c = classes.get(imp); - FieldObj sf = c.staticFields.get(n); - e2.field = sf; - return e2; - } - // TODO static field or method of a class - } - } - expr.field = f; - if (f != null && (!f.isLocal && !f.isStatic)) { - VariableExpr ve = new VariableExpr(this); - ve.field = thisPointer; - expr.base = ve; - if (thisPointer == null) { - throw getSyntaxException("this usage in static context"); - } - } - expr.name = name; - return expr; - } - - private void read(String string) { - if (!readIf(string)) { - throw getSyntaxException(string + " expected, got " + current.token); - } - } - - private String readQualifiedIdentifier() { - String id = readIdentifier(); - if (localVars.containsKey(id)) { - return id; - } - if (classObj != null) { - if (classObj.staticFields.containsKey(id)) { - return id; - } - if (classObj.instanceFields.containsKey(id)) { - return id; - } - } - String fullName = importMap.get(id); - if (fullName != null) { - return fullName; - } - while (readIf(".")) { - id += "." + readIdentifier(); - } - return id; - } - - private String readIdentifier() { - if (current.type != TOKEN_IDENTIFIER) { - throw getSyntaxException("identifier expected, got " + current.token); - } - String result = current.token; - readToken(); - return result; - } - - private boolean readIf(String token) { - if (current.type != TOKEN_IDENTIFIER && token.equals(current.token)) { - readToken(); - return true; - } - return false; - } - - private String read() { - String token = current.token; - readToken(); - return token; - } - - private RuntimeException getSyntaxException(String message) { - return new RuntimeException(message, new ParseException(source, current.index)); - } - - /** - * Replace all Unicode escapes. - * - * @param s the text - * @return the cleaned text - */ - static String replaceUnicode(String s) { - if (s.indexOf("\\u") < 0) { - return s; - } - StringBuilder buff = new StringBuilder(s.length()); - for (int i = 0; i < s.length(); i++) { - if (s.substring(i).startsWith("\\\\")) { - buff.append("\\\\"); - i++; - } else if (s.substring(i).startsWith("\\u")) { - i += 2; - while (s.charAt(i) == 'u') { - i++; - } - String c = s.substring(i, i + 4); - buff.append((char) Integer.parseInt(c, 16)); - i += 4; - } else { - buff.append(s.charAt(i)); - } - } - return buff.toString(); - } - - /** - * Replace all Unicode escapes and remove all remarks. - * - * @param s the source code - * @return the cleaned source code - */ - static String removeRemarks(String s) { - char[] chars = s.toCharArray(); - for (int i = 0; i >= 0 && i < s.length(); i++) { - if (s.charAt(i) == '\'') { - i++; - while (true) { - if (s.charAt(i) == '\\') { - i++; - } else if (s.charAt(i) == '\'') { - break; - } - i++; - } - continue; - } else if (s.charAt(i) == '\"') { - i++; - while (true) { - if (s.charAt(i) == '\\') { - i++; - } else if (s.charAt(i) == '\"') { - break; - } - i++; - } - continue; - } - String sub = s.substring(i); - if (sub.startsWith("/*") && !sub.startsWith("/* c:")) { - int j = i; - i = s.indexOf("*/", i + 2) + 2; - for (; j < i; j++) { - if (chars[j] > ' ') { - chars[j] = ' '; - } - } - } else if (sub.startsWith("//") && !sub.startsWith("// c:")) { - int j = i; - i = s.indexOf('\n', i); - while (j < i) { - chars[j++] = ' '; - } - } - } - return new String(chars) + " "; - } - - private void readToken() { - int ch; - while (true) { - if (current.index >= source.length()) { - current.token = null; - return; - } - ch = source.charAt(current.index); - if (ch == '\n') { - current.line++; - } else if (ch > ' ') { - break; - } - current.index++; - } - int start = current.index; - if (Character.isJavaIdentifierStart(ch)) { - while (Character.isJavaIdentifierPart(source.charAt(current.index))) { - current.index++; - } - current.token = source.substring(start, current.index); - if (RESERVED.contains(current.token)) { - current.type = TOKEN_RESERVED; - } else { - current.type = TOKEN_IDENTIFIER; - } - return; - } else if (Character.isDigit(ch) || (ch == '.' && Character.isDigit(source.charAt(current.index + 1)))) { - String s = source.substring(current.index); - current.token = "0" + readNumber(s); - current.index += current.token.length() - 1; - current.type = TOKEN_LITERAL_NUMBER; - return; - } - current.index++; - switch (ch) { - case '\'': { - while (true) { - if (source.charAt(current.index) == '\\') { - current.index++; - } else if (source.charAt(current.index) == '\'') { - break; - } - current.index++; - } - current.index++; - current.token = source.substring(start + 1, current.index); - current.token = "\'" + javaDecode(current.token, '\''); - current.type = TOKEN_LITERAL_CHAR; - return; - } - case '\"': { - while (true) { - if (source.charAt(current.index) == '\\') { - current.index++; - } else if (source.charAt(current.index) == '\"') { - break; - } - current.index++; - } - current.index++; - current.token = source.substring(start + 1, current.index); - current.token = "\"" + javaDecode(current.token, '\"'); - current.type = TOKEN_LITERAL_STRING; - return; - } - case '(': - case ')': - case '[': - case ']': - case '{': - case '}': - case ';': - case ',': - case '?': - case ':': - break; - case '.': - if (source.charAt(current.index) == '.' && source.charAt(current.index + 1) == '.') { - current.index += 2; - } - break; - case '+': - if (source.charAt(current.index) == '=' || source.charAt(current.index) == '+') { - current.index++; - } - break; - case '-': - if (source.charAt(current.index) == '=' || source.charAt(current.index) == '-') { - current.index++; - } - break; - case '>': - if (source.charAt(current.index) == '>') { - current.index++; - if (source.charAt(current.index) == '>') { - current.index++; - } - } - if (source.charAt(current.index) == '=') { - current.index++; - } - break; - case '<': - if (source.charAt(current.index) == '<') { - current.index++; - } - if (source.charAt(current.index) == '=') { - current.index++; - } - break; - case '/': - if (source.charAt(current.index) == '*' || source.charAt(current.index) == '/') { - current.index++; - } - break; - case '*': - case '~': - case '!': - case '=': - case '%': - case '^': - if (source.charAt(current.index) == '=') { - current.index++; - } - break; - case '&': - if (source.charAt(current.index) == '&') { - current.index++; - } else if (source.charAt(current.index) == '=') { - current.index++; - } - break; - case '|': - if (source.charAt(current.index) == '|') { - current.index++; - } else if (source.charAt(current.index) == '=') { - current.index++; - } - break; - } - current.type = TOKEN_OTHER; - current.token = source.substring(start, current.index); - } - - /** - * Parse a number literal and returns it. - * - * @param s the source code - * @return the number - */ - static String readNumber(String s) { - int i = 0; - if (s.startsWith("0x") || s.startsWith("0X")) { - i = 2; - while (true) { - char ch = s.charAt(i); - if ((ch < '0' || ch > '9') && (ch < 'a' || ch > 'f') && (ch < 'A' || ch > 'F')) { - break; - } - i++; - } - if (s.charAt(i) == 'l' || s.charAt(i) == 'L') { - i++; - } - } else { - while (true) { - char ch = s.charAt(i); - if ((ch < '0' || ch > '9') && ch != '.') { - break; - } - i++; - } - if (s.charAt(i) == 'e' || s.charAt(i) == 'E') { - i++; - if (s.charAt(i) == '-' || s.charAt(i) == '+') { - i++; - } - while (Character.isDigit(s.charAt(i))) { - i++; - } - } - if (s.charAt(i) == 'f' || s.charAt(i) == 'F' || s.charAt(i) == 'd' - || s.charAt(i) == 'D' || s.charAt(i) == 'L' || s.charAt(i) == 'l') { - i++; - } - } - return s.substring(0, i); - } - - private static RuntimeException getFormatException(String s, int i) { - return new RuntimeException(new ParseException(s, i)); - } - - private static String javaDecode(String s, char end) { - StringBuilder buff = new StringBuilder(s.length()); - for (int i = 0; i < s.length(); i++) { - char c = s.charAt(i); - if (c == end) { - break; - } else if (c == '\\') { - if (i >= s.length()) { - throw getFormatException(s, s.length() - 1); - } - c = s.charAt(++i); - switch (c) { - case 't': - buff.append('\t'); - break; - case 'r': - buff.append('\r'); - break; - case 'n': - buff.append('\n'); - break; - case 'b': - buff.append('\b'); - break; - case 'f': - buff.append('\f'); - break; - case '"': - buff.append('"'); - break; - case '\'': - buff.append('\''); - break; - case '\\': - buff.append('\\'); - break; - case 'u': { - try { - c = (char) (Integer.parseInt(s.substring(i + 1, i + 5), 16)); - } catch (NumberFormatException e) { - throw getFormatException(s, i); - } - i += 4; - buff.append(c); - break; - } - default: - if (c >= '0' && c <= '9') { - try { - c = (char) (Integer.parseInt(s.substring(i, i + 3), 8)); - } catch (NumberFormatException e) { - throw getFormatException(s, i); - } - i += 2; - buff.append(c); - } else { - throw getFormatException(s, i); - } - } - } else { - buff.append(c); - } - } - return buff.toString(); - } - - /** - * Write the C header. - * - * @param out the output writer - */ - void writeHeader(PrintWriter out) { - for (Statement s : nativeHeaders) { - out.println(s); - } - out.println(); - for (ClassObj c : classes.values()) { - out.println("/* " + c.className + ".h */"); - for (FieldObj f : c.staticFields.values()) { - StringBuilder buff = new StringBuilder(); - buff.append("extern "); - if (f.isFinal) { - buff.append("const "); - } - buff.append(toC(f.type.classObj.toString())); - if (!f.type.classObj.isPrimitive) { - buff.append("*"); - } - buff.append(" ").append(toC(c.className + "." + f.name)); - for (int i = 0; i < f.type.arrayLevel; i++) { - buff.append("[]"); - } - buff.append(";"); - out.println(buff.toString()); - } - out.println("struct " + toC(c.className) + " {"); - for (FieldObj f : c.instanceFields.values()) { - out.print(" " + toC(f.type.toString()) + " " + f.name); - if (f.value != null) { - out.print(" = " + f.value); - } - out.println(";"); - } - if (c.instanceFields.size() == 0) { - out.println("int dummy;"); - } - out.println("};"); - out.println("typedef struct " + toC(c.className) + " " + toC(c.className) + ";"); - for (ArrayList list : c.methods.values()) { - for (MethodObj m : list) { - out.print(m.returnType + " " + toC(c.className) + "_" + m.name + "("); - int i = 0; - if (!m.isStatic && !m.isConstructor) { - out.print(toC(c.className) + "* this"); - i++; - } - for (FieldObj p : m.parameters.values()) { - if (i > 0) { - out.print(", "); - } - out.print(p.type + " " + p.name); - i++; - } - out.println(");"); - } - } - out.println(); - } - out.println(); - out.println("/* method pointers */"); - for (MethodObj m : allMethodsMap.values()) { - out.print("extern " + m.returnType + " (*virtual_" + m.name + "[])("); - int i = 0; - if (!m.isConstructor) { - out.print("void*"); - i++; - } - for (FieldObj p : m.parameters.values()) { - if (i > 0) { - out.print(", "); - } - out.print(p.type); - i++; - } - out.println(");"); - out.println(); - } - } - - /** - * Write the C source code. - * - * @param out the output writer - */ - void writeSource(PrintWriter out) { - out.println("/* method pointers */"); - for (MethodObj m : allMethodsMap.values()) { - out.print(m.returnType + " (*virtual_" + m.name + "[])("); - int i = 0; - if (!m.isConstructor) { - out.print("void*"); - i++; - } - for (FieldObj p : m.parameters.values()) { - if (i > 0) { - out.print(", "); - } - out.print(p.type); - i++; - } - out.println(") = {"); - for (ClassObj c : allClasses) { - if (c != null && c.methods.containsKey(m.name)) { - out.println(toC(c.className) + "_" + m.name + ", "); - } else { - out.print("0, "); - } - } - out.println("};"); - } - out.println(); - for (ClassObj c : classes.values()) { - out.println("/* " + c.className + ".c */"); - for (Statement s : c.nativeCode) { - out.println(s); - } - for (FieldObj f : c.staticFields.values()) { - StringBuilder buff = new StringBuilder(); - if (f.isFinal) { - buff.append("const "); - } - buff.append(toC(f.type.classObj.toString())); - if (!f.type.classObj.isPrimitive) { - buff.append("*"); - } - buff.append(" ").append(toC(c.className + "." + f.name)); - for (int i = 0; i < f.type.arrayLevel; i++) { - buff.append("[]"); - } - if (f.value != null) { - buff.append(" = " + f.value); - } - buff.append(";"); - out.println(buff.toString()); - } - for (ArrayList list : c.methods.values()) { - for (MethodObj m : list) { - out.print(m.returnType + " " + toC(c.className) + "_" + m.name + "("); - int i = 0; - if (!m.isStatic && !m.isConstructor) { - out.print(toC(c.className) + "* this"); - i++; - } - for (FieldObj p : m.parameters.values()) { - if (i > 0) { - out.print(", "); - } - out.print(p.type + " " + p.name); - i++; - } - out.println(") {"); - if (m.isConstructor) { - out.println(indent(toC(c.className) + "* this = NEW_OBJ(" + c.id + ", " + toC(c.className) +");")); - } - if (m.block != null) { - out.print(m.block.toString()); - } - if (m.isConstructor) { - out.println(indent("return this;")); - } - out.println("}"); - out.println(); - } - } - } - } - - private static String indent(String s, int spaces) { - StringBuilder buff = new StringBuilder(s.length() + spaces); - for (int i = 0; i < s.length();) { - for (int j = 0; j < spaces; j++) { - buff.append(' '); - } - int n = s.indexOf('\n', i); - n = n < 0 ? s.length() : n + 1; - buff.append(s.substring(i, n)); - i = n; - } - if (!s.endsWith("\n")) { - buff.append('\n'); - } - return buff.toString(); - } - - /** - * Move the source code 4 levels to the right. - * - * @param o the source code - * @return the indented code - */ - static String indent(String o) { - return indent(o, 4); - } - - /** - * Get the C representation of this identifier. - * - * @param identifier the identifier - * @return the C representation - */ - static String toC(String identifier) { - return identifier.replace('.', '_'); - } - - ClassObj getClassObj() { - return classObj; - } - - /** - * Get the class of the given name. - * - * @param className the name - * @return the class - */ - ClassObj getClassObj(String className) { - ClassObj c = builtInTypes.get(className); - if (c == null) { - c = classes.get(className); - } - return c; - } - -} - -/** - * The parse state. - */ -class ParseState { - - /** - * The parse index. - */ - int index; - - /** - * The token type - */ - int type; - - /** - * The token text. - */ - String token; - - /** - * The line number. - */ - int line; -} \ No newline at end of file diff --git a/tools/h2/src/tools/org/h2/java/Statement.java b/tools/h2/src/tools/org/h2/java/Statement.java deleted file mode 100755 index 593d06c..0000000 --- a/tools/h2/src/tools/org/h2/java/Statement.java +++ /dev/null @@ -1,227 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.java; - -import java.util.ArrayList; - -/** - * A statement. - */ -public interface Statement { - - // toString - -} - -/** - * A "return" statement. - */ -class ReturnStatement implements Statement { - Expr expr; - public String toString() { - return "return " + (expr == null ? "" : expr) + ";"; - } -} - -/** - * A "do .. while" statement. - */ -class DoWhileStatement implements Statement { - Expr condition; - Statement block; - public String toString() { - return "do {\n" + block + "} while (" + condition + ");"; - } -} - -/** - * A "continue" statement. - */ -class ContinueStatement implements Statement { - public String toString() { - return "continue;"; - } -} - -/** - * A "break" statement. - */ -class BreakStatement implements Statement { - public String toString() { - return "break;"; - } -} - -/** - * An empty statement. - */ -class EmptyStatement implements Statement { - public String toString() { - return ";"; - } -} - -/** - * A "switch" statement. - */ -class SwitchStatement implements Statement { - Expr expr; - StatementBlock defaultBlock; - ArrayList cases = new ArrayList(); - ArrayList blocks = new ArrayList(); - public String toString() { - StringBuilder buff = new StringBuilder(); - buff.append("switch (").append(expr).append(") {\n"); - for (int i = 0; i < cases.size(); i++) { - buff.append("case " + cases.get(i) + ":\n"); - buff.append(blocks.get(i).toString()); - } - if (defaultBlock != null) { - buff.append("default:\n"); - buff.append(defaultBlock.toString()); - } - buff.append("}"); - return buff.toString(); - } -} - -/** - * An expression statement. - */ -class ExprStatement implements Statement { - Expr expr; - public String toString() { - return expr + ";"; - } -} - -/** - * A "while" statement. - */ -class WhileStatement implements Statement { - Expr condition; - Statement block; - public String toString() { - String w = "while (" + condition + ")"; - String s = block.toString(); - return w + "\n" + s; - } -} - -/** - * An "if" statement. - */ -class IfStatement implements Statement { - Expr condition; - Statement block; - Statement elseBlock; - public String toString() { - String w = "if (" + condition + ") {\n"; - String s = block.toString(); - if (elseBlock != null) { - s += "} else {\n" + elseBlock.toString(); - } - return w + s + "}"; - } -} - -/** - * A "for" statement. - */ -class ForStatement implements Statement { - Statement init; - Expr condition; - Expr update; - Statement block; - ArrayList updates = new ArrayList(); - Type iterableType; - String iterableVariable; - Expr iterable; - public String toString() { - StringBuffer buff = new StringBuffer(); - buff.append("for ("); - if (iterableType != null) { - Type it = iterable.getType(); - if (it != null && it.arrayLevel > 0) { - String idx = "i_" + iterableVariable; - buff.append("int " + idx + " = 0; " + idx + " < LENGTH(" + iterable + "); " + idx + "++"); - buff.append(") {\n"); - buff.append(JavaParser.indent(iterableType + " " + iterableVariable + " = " + iterable + "["+ idx +"];\n")); - buff.append(block.toString()).append("}"); - } else { - // TODO iterate over a collection - buff.append(iterableType).append(' '); - buff.append(iterableVariable).append(": "); - buff.append(iterable); - buff.append(") {\n"); - buff.append(block.toString()).append("}"); - } - } else { - buff.append(init.toString()); - buff.append(" ").append(condition.toString()).append("; "); - for (int i = 0; i < updates.size(); i++) { - if (i > 0) { - buff.append(", "); - } - buff.append(updates.get(i)); - } - buff.append(") {\n"); - buff.append(block.toString()).append("}"); - } - return buff.toString(); - } -} - -/** - * A statement block. - */ -class StatementBlock implements Statement { - ArrayList instructions = new ArrayList(); - public String toString() { - StringBuilder buff = new StringBuilder(); - for (Statement s : instructions) { - buff.append(JavaParser.indent(s.toString())); - } - return buff.toString(); - } -} - -/** - * A variable declaration. - */ -class VarDecStatement implements Statement { - Type type; - ArrayList variables = new ArrayList(); - ArrayList values = new ArrayList(); - public String toString() { - StringBuilder buff = new StringBuilder(); - buff.append(type).append(' '); - for (int i = 0; i < variables.size(); i++) { - if (i > 0) { - buff.append(", "); - } - buff.append(variables.get(i)); - Expr value = values.get(i); - if (value != null) { - buff.append(" = ").append(value); - } - } - buff.append(";"); - return buff.toString(); - } -} - -/** - * A native statement. - */ -class StatementNative implements Statement { - String code; - public String toString() { - return code; - } -} - diff --git a/tools/h2/src/tools/org/h2/java/Test.java b/tools/h2/src/tools/org/h2/java/Test.java deleted file mode 100755 index a91eb5c..0000000 --- a/tools/h2/src/tools/org/h2/java/Test.java +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.java; - -import java.io.FileWriter; -import java.io.IOException; -import java.io.PrintWriter; -import org.h2.test.TestBase; - -/** - * A test for the Java parser. - */ -public class Test extends TestBase { - - /** - * Start the task with the given arguments. - * - * @param args the arguments, or null - */ - public static void main(String... args) throws IOException { - new Test().test(); - } - - public void test() throws IOException { - // gcc --std=c99 test.c - // (for "mixed declarations and code") - - // not supported yet: - // HexadecimalFloatingPointLiteral - // int x()[] { return null; } - // annotations - // import static - // import * - // initializer blocks - // access to static fields with instance variable - // final variables (within blocks, parameter list) - // Identifier : (labels) - // ClassOrInterfaceDeclaration within blocks (or any other nested classes) - // assert - - assertEquals("\\\\" + "u0000", JavaParser.replaceUnicode("\\\\" + "u0000")); - assertEquals("\u0000", JavaParser.replaceUnicode("\\" + "u0000")); - assertEquals("\u0000", JavaParser.replaceUnicode("\\" + "uu0000")); - assertEquals("\\\\" + "\u0000", JavaParser.replaceUnicode("\\\\\\" + "u0000")); - - assertEquals("0", JavaParser.readNumber("0a")); - assertEquals("0l", JavaParser.readNumber("0l")); - assertEquals("0xFFL", JavaParser.readNumber("0xFFLx")); - assertEquals("0xDadaCafe", JavaParser.readNumber("0xDadaCafex")); - assertEquals("1.40e-45f", JavaParser.readNumber("1.40e-45fx")); - assertEquals("1e1f", JavaParser.readNumber("1e1fx")); - assertEquals("2.f", JavaParser.readNumber("2.fx")); - assertEquals(".3d", JavaParser.readNumber(".3dx")); - assertEquals("6.022137e+23f", JavaParser.readNumber("6.022137e+23f+1")); - - JavaParser parser = new JavaParser(); - parser.parse("src/tools/org/h2", "java.lang.Object"); - parser.parse("src/tools/org/h2", "java.lang.String"); - parser.parse("src/tools/org/h2", "java.lang.Math"); - parser.parse("src/tools/org/h2", "java.lang.Integer"); - parser.parse("src/tools/org/h2", "java.lang.StringBuilder"); - parser.parse("src/tools/org/h2", "java.io.PrintStream"); - parser.parse("src/tools/org/h2", "java.lang.System"); - parser.parse("src/tools/org/h2", "java.util.Arrays"); - parser.parse("src/tools", "org.h2.java.TestApp"); - - PrintWriter w = new PrintWriter(System.out); - parser.writeHeader(w); - parser.writeSource(w); - w.flush(); - w = new PrintWriter(new FileWriter("bin/test.c")); - parser.writeHeader(w); - parser.writeSource(w); - w.close(); - - } -} diff --git a/tools/h2/src/tools/org/h2/java/TestApp.java b/tools/h2/src/tools/org/h2/java/TestApp.java deleted file mode 100755 index 13b2ffd..0000000 --- a/tools/h2/src/tools/org/h2/java/TestApp.java +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.java; - -/** - * A test application. - */ -public class TestApp { - -/* c: - -int main(int argc, char** argv) { - org_h2_java_TestApp_main(null); -} - -*/ - - /** - * Run this application. - * - * @param args the command line arguments - */ - public static void main(String... args) { - System.out.println("Hello " + "World" + 1); - } - -} diff --git a/tools/h2/src/tools/org/h2/java/io/PrintStream.java b/tools/h2/src/tools/org/h2/java/io/PrintStream.java deleted file mode 100755 index ee8a537..0000000 --- a/tools/h2/src/tools/org/h2/java/io/PrintStream.java +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.java.io; - -/** - * A print stream. - */ -public class PrintStream { - - /** - * Print the given string. - * - * @param s the string - */ - public void println(String s) { - // c: int x = LENGTH(s->chars); - // c: printf("%.*S\n", x, s->chars); - } - -} diff --git a/tools/h2/src/tools/org/h2/java/io/package.html b/tools/h2/src/tools/org/h2/java/io/package.html deleted file mode 100755 index 2339d75..0000000 --- a/tools/h2/src/tools/org/h2/java/io/package.html +++ /dev/null @@ -1,15 +0,0 @@ - - - - -Javadoc package documentation -

    - -A simple implementation of the java.lang.* package for the Java parser. - -

    \ No newline at end of file diff --git a/tools/h2/src/tools/org/h2/java/lang/Integer.java b/tools/h2/src/tools/org/h2/java/lang/Integer.java deleted file mode 100755 index e1d6f50..0000000 --- a/tools/h2/src/tools/org/h2/java/lang/Integer.java +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.java.lang; - -/** - * A java.lang.Integer implementation. - */ -public class Integer { - - /** - * Convert a value to a String. - * - * @param x the value - * @return the String - */ - public static String toString(int x) { - // c: char ch[20]; - // c: snprintf(ch, 20, "%d", x); - // c: return string(ch); - return null; - } - -} diff --git a/tools/h2/src/tools/org/h2/java/lang/Math.java b/tools/h2/src/tools/org/h2/java/lang/Math.java deleted file mode 100755 index 6238b2a..0000000 --- a/tools/h2/src/tools/org/h2/java/lang/Math.java +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.java.lang; - -/** - * A java.lang.String implementation. - */ -public class Math { - - /** - * Get the larger of both values. - * - * @param a the first value - * @param b the second value - * @return the larger - */ - public static int max(int a, int b) { - return a > b ? a : b; - } - -} diff --git a/tools/h2/src/tools/org/h2/java/lang/Object.java b/tools/h2/src/tools/org/h2/java/lang/Object.java deleted file mode 100755 index 3144dec..0000000 --- a/tools/h2/src/tools/org/h2/java/lang/Object.java +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.java.lang; - -/** - * A java.lang.Object implementation. - */ -public class Object { - - private static final int[] K = { 1 }; - - public int hashCode() { - return K[0]; - } - - public boolean equals(Object other) { - return this == other; - } - -} diff --git a/tools/h2/src/tools/org/h2/java/lang/String.java b/tools/h2/src/tools/org/h2/java/lang/String.java deleted file mode 100755 index e26b3a9..0000000 --- a/tools/h2/src/tools/org/h2/java/lang/String.java +++ /dev/null @@ -1,147 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.java.lang; - -/* c: - -#include -#include -#include -#include -#include - -#define jvoid void -#define jboolean int8_t -#define jbyte int8_t -#define jchar wchar_t -#define jint int32_t -#define jlong int64_t -#define jfloat float -#define jdouble double -#define ujint uint32_t -#define ujlong uint64_t -#define true 1 -#define false 0 -#define null 0 - -#define LENGTH(a) (*(((jint*)(a))-3)) -#define CLASS_ID(a) (*(((jint*)(a))-2)) -#define NEW_ARRAY(size, length) new_array(0, size, length) -#define NEW_OBJ_ARRAY(length) new_array(0, sizeof(void*), length) -#define NEW_OBJ(typeId, typeName) new_object(typeId, sizeof(struct typeName)) -#define SET(variable, p) set_object(variable, p) -#define STRING(s) ((java_lang_String*) string(s)) - -void* new_array(jint object, jint size, jint length); -void* new_object(jint type, jint size); -void* set_object(void** target, void* o); -void* string(char* s); - -*/ - -/* - * Object layout: - * m-3: arrays: length; otherwise not allocated - * m-2: arrays: 0; otherwise type - * m-1: number of references - */ - -/** - * A java.lang.String implementation. - */ -public class String { - -/* c: - -void* new_array(jint object, jint size, jint length) { - int count = sizeof(jint) * 3 + size * length; - int* m = (jint*) calloc(1, count); - *m = length; - *(m + 2) = 1; - return m + 3; -} - -void* new_object(jint type, jint size) { - int count = sizeof(jint) * 2 + size; - int* m = (jint*) calloc(1, count); - *m = type; - *(m + 1) = 1; - return m + 2; -} - -void* set_object(void** target, void* o) { - int* m = (jint*) target; - if (*(m - 1) == 1) { - if (*(m - 2) == 0) { - free(m - 3); - } else { - free(m - 2); - } - } else { - (*(m - 1))--; - } - *target = o; - m = (jint*) target; - if (o != 0) { - (*(m - 1))++; - } - return m; -} - -void* string(char* s) { - int len = strlen(s); - jchar* chars = NEW_ARRAY(sizeof(jchar), len); - for (int i = 0; i < len; i++) { - chars[i] = s[i]; - } - return java_lang_String_init_obj(chars); -} - -*/ - - /** - * The character array. - */ - char[] chars; - - private int hashCode; - - public String(char[] chars) { - this.chars = new char[chars.length]; - System.arraycopy(chars, 0, this.chars, 0, chars.length); - } - - public String(char[] chars, int offset, int count) { - this.chars = new char[count]; - System.arraycopy(chars, offset, this.chars, 0, count); - } - - public int hashCode() { - if (hashCode == 0) { - if (chars.length == 0) { - return 0; - } - int h = 0; - for (char c : chars) { - h = h * 31 + c; - } - hashCode = h; - return h; - } - return hashCode; - } - - /** - * Get the length of the string. - * - * @return the length - */ - public int length() { - return chars.length; - } - -} diff --git a/tools/h2/src/tools/org/h2/java/lang/StringBuilder.java b/tools/h2/src/tools/org/h2/java/lang/StringBuilder.java deleted file mode 100755 index f18a5f7..0000000 --- a/tools/h2/src/tools/org/h2/java/lang/StringBuilder.java +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.java.lang; - -/** - * A java.lang.String implementation. - */ -public class StringBuilder { - - private int length; - private char[] buffer; - - public StringBuilder(String s) { - char[] chars = s.chars; - int len = chars.length; - buffer = new char[len]; - System.arraycopy(chars, 0, buffer, 0, len); - this.length = len; - } - - public StringBuilder() { - buffer = new char[10]; - } - - /** - * Append the given value. - * - * @param x the value - * @return this - */ - public StringBuilder append(String x) { - int l = x.length(); - ensureCapacity(l); - System.arraycopy(x.chars, 0, buffer, length, l); - length += l; - return this; - } - - /** - * Append the given value. - * - * @param x the value - * @return this - */ - public StringBuilder append(int x) { - append(Integer.toString(x)); - return this; - } - - public java.lang.String toString() { - return new java.lang.String(buffer, 0, length); - } - - private void ensureCapacity(int plus) { - if (buffer.length < length + plus) { - char[] b = new char[Math.max(length + plus, buffer.length * 2)]; - System.arraycopy(buffer, 0, b, 0, length); - buffer = b; - } - } - -} diff --git a/tools/h2/src/tools/org/h2/java/lang/System.java b/tools/h2/src/tools/org/h2/java/lang/System.java deleted file mode 100755 index 4c9aba9..0000000 --- a/tools/h2/src/tools/org/h2/java/lang/System.java +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.java.lang; - -import java.io.PrintStream; - -/** - * A simple java.lang.System implementation. - */ -public class System { - - /** - * The stdout stream. - */ - public static PrintStream out; - - /** - * Copy data from the source to the target. - * Source and target may overlap. - * - * @param src the source array - * @param srcPos the first element in the source array - * @param dest the destination - * @param destPos the first element in the destination - * @param length the number of element to copy - */ - public static void arraycopy(char[] src, int srcPos, char[] dest, int destPos, int length) { - /* c: - memmove(((jchar*)dest) + destPos, - ((jchar*)src) + srcPos, sizeof(jchar) * length); - */ - } - - /** - * Copy data from the source to the target. - * Source and target may overlap. - * - * @param src the source array - * @param srcPos the first element in the source array - * @param dest the destination - * @param destPos the first element in the destination - * @param length the number of element to copy - */ - public static void arraycopy(byte[] src, int srcPos, byte[] dest, int destPos, int length) { - /* c: - memmove(((jbyte*)dest) + destPos, - ((jbyte*)src) + srcPos, sizeof(jbyte) * length); - */ - } - - -} diff --git a/tools/h2/src/tools/org/h2/java/lang/package.html b/tools/h2/src/tools/org/h2/java/lang/package.html deleted file mode 100755 index 2339d75..0000000 --- a/tools/h2/src/tools/org/h2/java/lang/package.html +++ /dev/null @@ -1,15 +0,0 @@ - - - - -Javadoc package documentation -

    - -A simple implementation of the java.lang.* package for the Java parser. - -

    \ No newline at end of file diff --git a/tools/h2/src/tools/org/h2/java/package.html b/tools/h2/src/tools/org/h2/java/package.html deleted file mode 100755 index 000fbd8..0000000 --- a/tools/h2/src/tools/org/h2/java/package.html +++ /dev/null @@ -1,15 +0,0 @@ - - - - -Javadoc package documentation -

    - -A Java parser implementation. - -

    \ No newline at end of file diff --git a/tools/h2/src/tools/org/h2/java/util/Arrays.java b/tools/h2/src/tools/org/h2/java/util/Arrays.java deleted file mode 100755 index d5d5c97..0000000 --- a/tools/h2/src/tools/org/h2/java/util/Arrays.java +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.java.util; - -/** - * An simple implementation of java.util.Arrays - */ -public class Arrays { - - /** - * Fill an array with the given value. - * - * @param array the array - * @param x the value - */ - public static void fill(char[] array, char x) { - for (int i = 0; i < array.length; i++) { - array[i] = x; - } - } - - /** - * Fill an array with the given value. - * - * @param array the array - * @param x the value - */ - public static void fill(byte[] array, byte x) { - for (int i = 0; i < array.length; i++) { - array[i] = x; - } - } - - /** - * Fill an array with the given value. - * - * @param array the array - * @param x the value - */ - public static void fill(int[] array, int x) { - for (int i = 0; i < array.length; i++) { - array[i] = x; - } - } - - - /** - * Fill an array with the given value. - * - * @param array the array - * @param x the value - */ - public static void fillByte(byte[] array, byte x) { - for (int i = 0; i < array.length; i++) { - array[i] = x; - } - } - - /** - * Fill an array with the given value. - * - * @param array the array - * @param x the value - */ - public static void fillInt(int[] array, int x) { - for (int i = 0; i < array.length; i++) { - array[i] = x; - } - } - -} diff --git a/tools/h2/src/tools/org/h2/java/util/package.html b/tools/h2/src/tools/org/h2/java/util/package.html deleted file mode 100755 index 2339d75..0000000 --- a/tools/h2/src/tools/org/h2/java/util/package.html +++ /dev/null @@ -1,15 +0,0 @@ - - - - -Javadoc package documentation -

    - -A simple implementation of the java.lang.* package for the Java parser. - -

    \ No newline at end of file diff --git a/tools/h2/src/tools/org/h2/jcr/Railroads.java b/tools/h2/src/tools/org/h2/jcr/Railroads.java deleted file mode 100755 index e3c1d5a..0000000 --- a/tools/h2/src/tools/org/h2/jcr/Railroads.java +++ /dev/null @@ -1,126 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.jcr; - -import java.io.File; -import java.io.FileInputStream; -import java.io.FileOutputStream; -import java.io.InputStreamReader; -import java.io.Reader; -import java.sql.ResultSet; -import java.sql.ResultSetMetaData; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import org.h2.bnf.Bnf; -import org.h2.build.BuildBase; -import org.h2.build.doc.BnfRailroad; -import org.h2.build.doc.BnfSyntax; -import org.h2.build.doc.RailroadImages; -import org.h2.server.web.PageParser; -import org.h2.tools.Csv; -import org.h2.util.IOUtils; -import org.h2.util.StringUtils; - -/** - * JCR 2.0 / SQL-2 railroad generator. - */ -public class Railroads { - - private Bnf bnf; - private HashMap session = new HashMap(); - - /** - * This method is called when executing this application from the command - * line. - * - * @param args the command line parameters - */ - public static void main(String... args) throws Exception { - new Railroads().process(); - } - - private void process() throws Exception { - RailroadImages.main(); - bnf = Bnf.getInstance(getReader()); - ResultSet rs = Csv.getInstance().read(getReader(), null); - map("grammar", rs, true); - processHtml("jcr-sql2.html"); - } - - private void processHtml(String fileName) throws Exception { - String source = "src/tools/org/h2/jcr/"; - String target = "docs/html/"; - byte[] s = BuildBase.readFile(new File(source + "stylesheet.css")); - BuildBase.writeFile(new File(target + "stylesheet.css"), s); - String inFile = source + fileName; - String outFile = target + fileName; - new File(outFile).getParentFile().mkdirs(); - FileOutputStream out = new FileOutputStream(outFile); - FileInputStream in = new FileInputStream(inFile); - byte[] bytes = IOUtils.readBytesAndClose(in, 0); - if (fileName.endsWith(".html")) { - String page = new String(bytes); - page = PageParser.parse(page, session); - bytes = page.getBytes(); - } - out.write(bytes); - out.close(); - } - - private static Reader getReader() { - return new InputStreamReader(Railroads.class.getResourceAsStream("help.csv")); - } - - private void map(String key, ResultSet rs, boolean railroads) throws Exception { - ArrayList> list = new ArrayList>(); - while (rs.next()) { - HashMap map = new HashMap(); - ResultSetMetaData meta = rs.getMetaData(); - for (int i = 0; i < meta.getColumnCount(); i++) { - String k = StringUtils.toLowerEnglish(meta.getColumnLabel(i + 1)); - String value = rs.getString(i + 1); - value = value.trim(); - map.put(k, PageParser.escapeHtml(value)); - } - String topic = rs.getString("TOPIC"); - String syntax = rs.getString("SYNTAX").trim(); - if (railroads) { - BnfRailroad r = new BnfRailroad(); - String railroad = r.getHtml(bnf, syntax); - map.put("railroad", railroad); - } - BnfSyntax visitor = new BnfSyntax(); - String syntaxHtml = visitor.getHtml(bnf, syntax); - map.put("syntax", syntaxHtml); - // remove newlines in the regular text - String text = map.get("text"); - if (text != null) { - // text is enclosed in

    ..

    so this works. - text = StringUtils.replaceAll(text, "

    ", "

    "); - text = StringUtils.replaceAll(text, "
    ", " "); - map.put("text", text); - } - - String link = topic.toLowerCase(); - link = StringUtils.replaceAll(link, " ", "_"); - // link = StringUtils.replaceAll(link, "_", ""); - link = StringUtils.replaceAll(link, "@", "_"); - map.put("link", StringUtils.urlEncode(link)); - list.add(map); - } - session.put(key, list); - int div = 3; - int part = (list.size() + div - 1) / div; - for (int i = 0, start = 0; i < div; i++, start += part) { - List> listThird = list.subList(start, Math.min(start + part, list.size())); - session.put(key + "-" + i, listThird); - } - rs.close(); - } - -} diff --git a/tools/h2/src/tools/org/h2/jcr/help.csv b/tools/h2/src/tools/org/h2/jcr/help.csv deleted file mode 100755 index 348d563..0000000 --- a/tools/h2/src/tools/org/h2/jcr/help.csv +++ /dev/null @@ -1,100 +0,0 @@ -# Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, -# Version 1.0, and under the Eclipse Public License, Version 1.0 -# (http://h2database.com/html/license.html). -# Initial Developer: H2 Group) - -"SECTION","TOPIC","SYNTAX","TEXT" -"Grammar","Query"," -SELECT { * | { column [ , ... ] } } FROM { selector [ join ... ] } -[ WHERE constraint ] [ ORDER BY { ordering [ , ... ] } ] -"," -" - -"Grammar","Column"," -{ [ selectorName . ] propertyName [ AS columnName ] } | { selectorName . * } -"," -" - -"Grammar","Selector"," -nodeTypeName [ AS selectorName ] -"," -" - -"Grammar","Join"," -{ INNER | { LEFT | RIGHT } OUTER } JOIN rightSelector ON -{ selectorName . propertyName = joinSelectorName . joinPropertyName } - | { ISSAMENODE( selectorName , joinSelectorName [ , selectorPathName ] ) } - | { ISCHILDNODE( childSelectorName , parentSelectorName ) } - | { ISDESCENDANTNODE( descendantSelectorName , ancestorSelectorName ) } -"," -" - -"Grammar","Constraint"," -andCondition [ { OR andCondition } [...] ] -"," -" - -"Grammar","And Condition"," -condition [ { AND condition } [...] ] -"," -" - -"Grammar","Condition"," -comparison | NOT constraint | ( constraint ) - | [ selectorName . ] propertyName IS [ NOT ] NULL - | CONTAINS( { { [ selectorName . ] propertyName } | { selectorName . * } } , fulltextSearchExpression ) - | { ISSAMENODE | ISCHILDNODE | ISDESCENDANTNODE } ( [ selectorName , ] PathName ) -"," -" - -"Grammar","Comparison"," -dynamicOperand { = | <> | < | <= | > | >= | LIKE } staticOperand -"," -" - -"Grammar","Fulltext Search Expression"," -' anythingExceptSingleQuote ' | $ bindVariableName -"," -" - -"Grammar","Static Operand"," -literal - | $ bindVariableName - | CAST ( literal AS { STRING | BINARY | DATE | LONG | DOUBLE | DECIMAL | BOOLEAN | NAME | PATH | REFERENCE | WEAKREFERENCE | URI } ) -"," -" - -"Grammar","Literal"," -' anythingExceptSingleQuote ' - | "" anythingExceptDoubleQuote "" - | numberLiteral -"," -" - -"Grammar","Number Literal"," -[ + | - ] { { number [ . number ] } | { . number } } [ E [ + | - ] expNumber [...] ] ] -"," -" - -"Grammar","Number"," -0-9 [...] -"," -" - -"Grammar","Dynamic Operand"," -[ selectorName . ] propertyName - | LENGTH( [ selectorName . ] propertyName ) - | { NAME | LOCALNAME | SCORE } ( [ selectorName ] ) - | { LOWER | UPPER } ( dynamicOperand ) -"," -" - -"Grammar","Ordering"," -simpleName [ ASC | DESC ] -"," -" - -"Grammar","Name"," -simpleName | '[' quotedName ']' -"," -" \ No newline at end of file diff --git a/tools/h2/src/tools/org/h2/jcr/jcr-sql2.html b/tools/h2/src/tools/org/h2/jcr/jcr-sql2.html deleted file mode 100755 index a893e28..0000000 --- a/tools/h2/src/tools/org/h2/jcr/jcr-sql2.html +++ /dev/null @@ -1,73 +0,0 @@ - - - - -JCR 2.0 SQL-2 Grammar - - - -

    JCR 2.0 SQL-2 Grammar

    - - - - - - -
    - - ${item.topic}
    -
    -
    - - ${item.topic}
    -
    -
    - - ${item.topic}
    -
    -
    - - -
    -

    -These railroad diagrams are based on the -JCR 2.0 specification. -

    -The diagrams are created with a small Java program -and this BNF. The program uses the BNF parser / converter -of the the H2 database engine. -

    -Please send feedback to the Jackrabbit User List. -

    - - -
    -

    ${item.topic}

    - -${item.railroad} - - -

    ${item.text}

    - -
    - - diff --git a/tools/h2/src/tools/org/h2/jcr/package.html b/tools/h2/src/tools/org/h2/jcr/package.html deleted file mode 100755 index 3bb9f90..0000000 --- a/tools/h2/src/tools/org/h2/jcr/package.html +++ /dev/null @@ -1,15 +0,0 @@ - - - - -Javadoc package documentation -

    - -Utility classes related to the JCR API. - -

    \ No newline at end of file diff --git a/tools/h2/src/tools/org/h2/jcr/stylesheet.css b/tools/h2/src/tools/org/h2/jcr/stylesheet.css deleted file mode 100755 index a21bf0f..0000000 --- a/tools/h2/src/tools/org/h2/jcr/stylesheet.css +++ /dev/null @@ -1,333 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ - -td, input, select, textarea, body, code, pre, td, th { - font: 9pt/130% Tahoma, Arial, Helvetica, sans-serif; - font-weight: normal; -} - -h1, h2, h3, h4, h5 { - font: 9pt Tahoma, Arial, Helvetica, sans-serif; - font-weight: bold; -} - -td, input, select, textarea, body, code, pre { - font-size: 9pt; -} - -pre { - background-color: #ece9d8; - border: 1px solid rgb(172, 168, 153); - padding: 4px; -} - -code { - background-color: #ece9d8; - padding: 0px 2px; -} - -img { - border: 0px; -} - -body { - margin: 20px; - max-width: 800px; -} - -h1 { - background-color: #0000bb; - padding: 2px 4px 2px 4px; - color: #fff; - font-size: 15pt; - line-height: normal; -} - -h2 { - font-size: 13pt; - margin-top: 1.5em; -} - -h3 { - font-size: 11pt; - margin-top: 1.5em; -} - -h4 { - font-size: 9pt; - margin-top: 1.5em; -} - -hr { - color: #CCC; - background-color: #CCC; - height: 1px; - border: 0px solid blue; -} - -table { - background-color: #ffffff; - border-collapse: collapse; - border: 1px solid #aca899; -} - -th { - text-align: left; - background-color: #ece9d8; - border: 1px solid #aca899; - padding: 2px; -} - -td { - background-color: #ffffff; - text-align: left; - vertical-align: top; - border: 1px solid #aca899; - padding: 2px; -} - -form { -} - -ul, ol { - list-style-position: outside; - padding-left: 20px; -} - -li { - margin-top: 2px; -} - -a { - text-decoration: none; - color: #0000ff; -} - -a:hover { - text-decoration: underline; -} - -em.u { - text-decoration: underline; - font-style: normal; -} - -.menu { - margin: 10px 10px 10px 10px; -} - -table.search { - width: 100%; - border: 0px; -} - -tr.search { - border: 0px; -} - -td.search { - border: 0px; - padding: 2px 0px 2px 10px; -} - -td.searchKeyword { - border: 0px; - padding: 0px 0px 0px 2px; -} - -td.searchKeyword a { - text-decoration: none; - color: #000000; -} - -td.searchKeyword a:hover { - text-decoration: underline; -} - -td.searchLink { - border: 0px; - padding: 0px 0px 0px 32px; - text-indent: -16px; -} - -td.searchLink a { - text-decoration: none; - color: #0000ff; -} - -td.searchLink a:hover { - text-decoration: underline; -} - -table.nav { - border: 0px; -} - -tr.nav { - border: 0px; -} - -td.nav { - border: 0px; -} - -table.content { - width: 100%; - height: 100%; - border: 0px; -} - -tr.content { - border:0px; -} - -td.content { - border:0px; -} - -.contentDiv { - margin:10px; -} - -.content { - margin: 10px 10px 10px 0px; -} - -.screenshot { - border: 1px outset #800; - padding: 10px; - margin: 10px 0px; -} - -.compareFeature { -} - -.compareY { - color: #050; -} - -.compareN { - color: #800; -} - -table.index { - width: 100%; - border: 0px; - padding: 0px; - margin: 0px; - border: 0px none; - border-collapse: collapse; -} - -/* width: 570px; - width: 190px; - */ - -td.index { - width: 33%; - border: 0px; - padding: 0px; - margin: 0px; - border: 0px none; - border-collapse: collapse; - vertical-align: top; -} - -.railroad { - border: 0px; - padding: 0px; - margin: 0px; - border-collapse: collapse; - vertical-align: top; -} - -.c { - padding: 1px 3px; - margin: 0px 0px; - border: 2px solid; - -moz-border-radius: 0.4em; - border-radius: 0.4em; - background-color: #fff; -} - -.ts { - border: 0px; - padding: 0px; - margin: 0px; - border-collapse: collapse; - vertical-align: top; - height: 24px; - background-image: url(images/div-ts.png); - width: 16px; -} - -.ls { - border: 0px; - padding: 0px; - margin: 0px; - border-collapse: collapse; - vertical-align: top; - height: 24px; - background-image: url(images/div-ls.png); - width: 16px; -} - -.ks { - border: 0px; - padding: 0px; - margin: 0px; - border-collapse: collapse; - vertical-align: top; - height: 24px; - background-image: url(images/div-ks.png); - width: 16px; -} - -.te { - border: 0px; - padding: 0px; - margin: 0px; - border-collapse: collapse; - vertical-align: top; - height: 24px; - background-image: url(images/div-te.png); - width: 16px; -} - -.le { - border: 0px; - padding: 0px; - margin: 0px; - border-collapse: collapse; - vertical-align: top; - height: 24px; - background-image: url(images/div-le.png); - width: 16px; -} - -.ke { - border: 0px; - padding: 0px; - margin: 0px; - border-collapse: collapse; - vertical-align: top; - height: 24px; - background-image: url(images/div-ke.png); - width: 16px; -} - -.d { - border: 0px; - padding: 0px; - margin: 0px; - border-collapse: collapse; - vertical-align: top; - height: 24px; - background-image: url(images/div-d.png); - background-repeat: repeat-x; - min-width: 16px; -} diff --git a/tools/h2/src/tools/org/h2/mode/FunctionsMySQL.java b/tools/h2/src/tools/org/h2/mode/FunctionsMySQL.java deleted file mode 100755 index 1f4adcb..0000000 --- a/tools/h2/src/tools/org/h2/mode/FunctionsMySQL.java +++ /dev/null @@ -1,163 +0,0 @@ -/* - * Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: Jason Brittain (jason.brittain at gmail.com) - */ -package org.h2.mode; - -import java.sql.Connection; -import java.sql.SQLException; -import java.sql.Statement; -import java.text.SimpleDateFormat; -import java.util.Date; -import java.util.Locale; - -import org.h2.util.StringUtils; - -/** - * This class implements some MySQL-specific functions. - * - * @author Jason Brittain - * @author Thomas Mueller - */ -public class FunctionsMySQL { - - /** - * The date format of a MySQL formatted date/time. - * Example: 2008-09-25 08:40:59 - */ - private static final String DATE_TIME_FORMAT = "yyyy-MM-dd HH:mm:ss"; - - /** - * Format replacements for MySQL date formats. - * See - * http://dev.mysql.com/doc/refman/5.1/en/date-and-time-functions.html#function_date-format - */ - private static final String[] FORMAT_REPLACE = { - "%a", "EEE", - "%b", "MMM", - "%c", "MM", - "%d", "dd", - "%e", "d", - "%H", "HH", - "%h", "hh", - "%I", "hh", - "%i", "mm", - "%j", "DDD", - "%k", "H", - "%l", "h", - "%M", "MMMM", - "%m", "MM", - "%p", "a", - "%r", "hh:mm:ss a", - "%S", "ss", - "%s", "ss", - "%T", "HH:mm:ss", - "%W", "EEEE", - "%w", "F", - "%Y", "yyyy", - "%y", "yy", - "%%", "%", - }; - - /** - * Register the functionality in the database. - * Nothing happens if the functions are already registered. - * - * @param conn the connection - */ - public static void register(Connection conn) throws SQLException { - String[] init = { - "UNIX_TIMESTAMP", "unixTimestamp", - "FROM_UNIXTIME", "fromUnixTime", - "DATE", "date", - }; - Statement stat = conn.createStatement(); - for (int i = 0; i < init.length; i += 2) { - String alias = init[i], method = init[i + 1]; - stat.execute( - "CREATE ALIAS IF NOT EXISTS " + alias + - " FOR \"" + FunctionsMySQL.class.getName() + "." + method + "\""); - } - } - - /** - * Get the seconds since 1970-01-01 00:00:00 UTC. - * See - * http://dev.mysql.com/doc/refman/5.1/en/date-and-time-functions.html#function_unix-timestamp - * - * @return the current timestamp in seconds (not milliseconds). - */ - public static int unixTimestamp() { - return (int) (System.currentTimeMillis() / 1000L); - } - - /** - * Get the seconds since 1970-01-01 00:00:00 UTC of the given timestamp. - * See - * http://dev.mysql.com/doc/refman/5.1/en/date-and-time-functions.html#function_unix-timestamp - * - * @param timestamp the timestamp - * @return the current timestamp in seconds (not milliseconds). - */ - public static int unixTimestamp(java.sql.Timestamp timestamp) { - return (int) (timestamp.getTime() / 1000L); - } - - /** - * See - * http://dev.mysql.com/doc/refman/5.1/en/date-and-time-functions.html#function_from-unixtime - * - * @param seconds The current timestamp in seconds. - * @return a formatted date/time String in the format "yyyy-MM-dd HH:mm:ss". - */ - public static String fromUnixTime(int seconds) { - SimpleDateFormat formatter = new SimpleDateFormat(DATE_TIME_FORMAT, Locale.ENGLISH); - return formatter.format(new Date(seconds * 1000L)); - } - - /** - * See - * http://dev.mysql.com/doc/refman/5.1/en/date-and-time-functions.html#function_from-unixtime - * - * @param seconds The current timestamp in seconds. - * @param format The format of the date/time String to return. - * @return a formatted date/time String in the given format. - */ - public static String fromUnixTime(int seconds, String format) { - format = convertToSimpleDateFormat(format); - SimpleDateFormat formatter = new SimpleDateFormat(format, Locale.ENGLISH); - return formatter.format(new Date(seconds * 1000L)); - } - - private static String convertToSimpleDateFormat(String format) { - String[] replace = FORMAT_REPLACE; - for (int i = 0; i < replace.length; i += 2) { - format = StringUtils.replaceAll(format, replace[i], replace[i + 1]); - } - return format; - } - - /** - * See - * http://dev.mysql.com/doc/refman/5.1/en/date-and-time-functions.html#function_date - * This function is dependent on the exact formatting of the MySQL date/time - * string. - * - * @param dateTime The date/time String from which to extract just the date - * part. - * @return the date part of the given date/time String argument. - */ - public static String date(String dateTime) { - if (dateTime == null) { - return null; - } - int index = dateTime.indexOf(' '); - if (index != -1) { - return dateTime.substring(0, index); - } - return dateTime; - } - -} diff --git a/tools/h2/src/tools/org/h2/mode/package.html b/tools/h2/src/tools/org/h2/mode/package.html deleted file mode 100755 index 43e9b21..0000000 --- a/tools/h2/src/tools/org/h2/mode/package.html +++ /dev/null @@ -1,15 +0,0 @@ - - - - -Javadoc package documentation -

    - -Utility classes for compatibility with other database, for example MySQL. - -

    \ No newline at end of file diff --git a/tools/h2/src/tools/org/hibernate/dialect/H2Dialect.java.txt b/tools/h2/src/tools/org/hibernate/dialect/H2Dialect.java.txt deleted file mode 100755 index 70c1160..0000000 --- a/tools/h2/src/tools/org/hibernate/dialect/H2Dialect.java.txt +++ /dev/null @@ -1,298 +0,0 @@ -package org.hibernate.dialect; - -import java.sql.SQLException; -import java.sql.Types; - -import org.hibernate.Hibernate; -import org.hibernate.cfg.Environment; -import org.hibernate.dialect.function.NoArgSQLFunction; -import org.hibernate.dialect.function.StandardSQLFunction; -import org.hibernate.dialect.function.VarArgsSQLFunction; -import org.hibernate.exception.TemplatedViolatedConstraintNameExtracter; -import org.hibernate.exception.ViolatedConstraintNameExtracter; -import org.hibernate.util.ReflectHelper; - -/** - * A dialect compatible with the H2 database. - * - * @author Thomas Mueller - * - */ -public class H2Dialect extends Dialect { - - private String querySequenceString; - public H2Dialect() { - super(); - - querySequenceString = "select sequence_name from information_schema.sequences"; - try { - // HHH-2300 - Class constants = ReflectHelper.classForName( "org.h2.engine.Constants" ); - Integer build = (Integer)constants.getDeclaredField("BUILD_ID" ).get(null); - int buildid = build.intValue(); - if(buildid < 32) { - querySequenceString = "select name from information_schema.sequences"; - } - } catch(Throwable e) { - // ignore (probably H2 not in the classpath) - } - registerColumnType(Types.BOOLEAN, "boolean"); - registerColumnType(Types.BIGINT, "bigint"); - registerColumnType(Types.BINARY, "binary"); - registerColumnType(Types.BIT, "boolean"); - registerColumnType(Types.CHAR, "char($l)"); - registerColumnType(Types.DATE, "date"); - registerColumnType(Types.DECIMAL, "decimal($p,$s)"); - registerColumnType(Types.DOUBLE, "double"); - registerColumnType(Types.FLOAT, "float"); - registerColumnType(Types.INTEGER, "integer"); - registerColumnType(Types.LONGVARBINARY, "longvarbinary"); - registerColumnType(Types.LONGVARCHAR, "longvarchar"); - registerColumnType(Types.REAL, "real"); - registerColumnType(Types.SMALLINT, "smallint"); - registerColumnType(Types.TINYINT, "tinyint"); - registerColumnType(Types.TIME, "time"); - registerColumnType(Types.TIMESTAMP, "timestamp"); - registerColumnType(Types.VARCHAR, "varchar($l)"); - registerColumnType(Types.VARBINARY, "binary($l)"); - registerColumnType(Types.NUMERIC, "decimal($p,$s)"); - registerColumnType(Types.BLOB, "blob"); - registerColumnType(Types.CLOB, "clob"); - - // select topic, syntax from information_schema.help - // where section like 'Function%' order by section, topic - -// registerFunction("abs", new StandardSQLFunction("abs")); - registerFunction("acos", new StandardSQLFunction("acos", Hibernate.DOUBLE)); - registerFunction("asin", new StandardSQLFunction("asin", Hibernate.DOUBLE)); - registerFunction("atan", new StandardSQLFunction("atan", Hibernate.DOUBLE)); - registerFunction("atan2", new StandardSQLFunction("atan2", Hibernate.DOUBLE)); - registerFunction("bitand", new StandardSQLFunction("bitand", Hibernate.INTEGER)); - registerFunction("bitor", new StandardSQLFunction("bitor", Hibernate.INTEGER)); - registerFunction("bitxor", new StandardSQLFunction("bitxor", Hibernate.INTEGER)); - registerFunction("ceiling", new StandardSQLFunction("ceiling", Hibernate.DOUBLE)); - registerFunction("cos", new StandardSQLFunction("cos", Hibernate.DOUBLE)); - registerFunction("cot", new StandardSQLFunction("cot", Hibernate.DOUBLE)); - registerFunction("degrees", new StandardSQLFunction("degrees", Hibernate.DOUBLE)); - registerFunction("exp", new StandardSQLFunction("exp", Hibernate.DOUBLE)); - registerFunction("floor", new StandardSQLFunction("floor", Hibernate.DOUBLE)); - registerFunction("log", new StandardSQLFunction("log", Hibernate.DOUBLE)); - registerFunction("log10", new StandardSQLFunction("log10", Hibernate.DOUBLE)); -// registerFunction("mod", new StandardSQLFunction("mod", Hibernate.INTEGER)); - registerFunction("pi", new NoArgSQLFunction("pi", Hibernate.DOUBLE)); - registerFunction("power", new StandardSQLFunction("power", Hibernate.DOUBLE)); - registerFunction("radians", new StandardSQLFunction("radians", Hibernate.DOUBLE)); - registerFunction("rand", new NoArgSQLFunction("rand", Hibernate.DOUBLE)); - registerFunction("round", new StandardSQLFunction("round", Hibernate.DOUBLE)); - registerFunction("roundmagic", new StandardSQLFunction("roundmagic", Hibernate.DOUBLE)); - registerFunction("sign", new StandardSQLFunction("sign", Hibernate.INTEGER)); - registerFunction("sin", new StandardSQLFunction("sin", Hibernate.DOUBLE)); -// registerFunction("sqrt", new StandardSQLFunction("sqrt", Hibernate.DOUBLE)); - registerFunction("tan", new StandardSQLFunction("tan", Hibernate.DOUBLE)); - registerFunction("truncate", new StandardSQLFunction("truncate", Hibernate.DOUBLE)); - - registerFunction("compress", new StandardSQLFunction("compress", Hibernate.BINARY)); - registerFunction("expand", new StandardSQLFunction("compress", Hibernate.BINARY)); - registerFunction("decrypt", new StandardSQLFunction("decrypt", Hibernate.BINARY)); - registerFunction("encrypt", new StandardSQLFunction("encrypt", Hibernate.BINARY)); - registerFunction("hash", new StandardSQLFunction("hash", Hibernate.BINARY)); - - registerFunction("ascii", new StandardSQLFunction("ascii", Hibernate.INTEGER)); -// registerFunction("bit_length", new StandardSQLFunction("bit_length", Hibernate.INTEGER)); - registerFunction("char", new StandardSQLFunction("char", Hibernate.CHARACTER)); - registerFunction("concat", new VarArgsSQLFunction(Hibernate.STRING, "(", "||", ")")); - registerFunction("difference", new StandardSQLFunction("difference", Hibernate.INTEGER)); - registerFunction("hextoraw", new StandardSQLFunction("hextoraw", Hibernate.STRING)); - registerFunction("lower", new StandardSQLFunction("lower", Hibernate.STRING)); - registerFunction("insert", new StandardSQLFunction("lower", Hibernate.STRING)); - registerFunction("left", new StandardSQLFunction("left", Hibernate.STRING)); -// registerFunction("length", new StandardSQLFunction("length", Hibernate.INTEGER)); -// registerFunction("locate", new StandardSQLFunction("locate", Hibernate.INTEGER)); -// registerFunction("lower", new StandardSQLFunction("lower", Hibernate.STRING)); - registerFunction("lcase", new StandardSQLFunction("lcase", Hibernate.STRING)); - registerFunction("ltrim", new StandardSQLFunction("ltrim", Hibernate.STRING)); - registerFunction("octet_length", new StandardSQLFunction("octet_length", Hibernate.INTEGER)); - registerFunction("position", new StandardSQLFunction("position", Hibernate.INTEGER)); - registerFunction("rawtohex", new StandardSQLFunction("rawtohex", Hibernate.STRING)); - registerFunction("repeat", new StandardSQLFunction("repeat", Hibernate.STRING)); - registerFunction("replace", new StandardSQLFunction("replace", Hibernate.STRING)); - registerFunction("right", new StandardSQLFunction("right", Hibernate.STRING)); - registerFunction("rtrim", new StandardSQLFunction("rtrim", Hibernate.STRING)); - registerFunction("soundex", new StandardSQLFunction("soundex", Hibernate.STRING)); - registerFunction("space", new StandardSQLFunction("space", Hibernate.STRING)); - registerFunction("stringencode", new StandardSQLFunction("stringencode", Hibernate.STRING)); - registerFunction("stringdecode", new StandardSQLFunction("stringdecode", Hibernate.STRING)); -// registerFunction("substring", new StandardSQLFunction("substring", Hibernate.STRING)); -// registerFunction("upper", new StandardSQLFunction("upper", Hibernate.STRING)); - registerFunction("ucase", new StandardSQLFunction("ucase", Hibernate.STRING)); - - registerFunction("stringtoutf8", new StandardSQLFunction("stringtoutf8", Hibernate.BINARY)); - registerFunction("utf8tostring", new StandardSQLFunction("utf8tostring", Hibernate.STRING)); - - registerFunction("current_date", new NoArgSQLFunction("current_date", Hibernate.DATE)); - registerFunction("current_time", new NoArgSQLFunction("current_time", Hibernate.TIME)); - registerFunction("current_timestamp", new NoArgSQLFunction("current_timestamp", Hibernate.TIMESTAMP)); - registerFunction("datediff", new StandardSQLFunction("datediff", Hibernate.INTEGER)); - registerFunction("dayname", new StandardSQLFunction("dayname", Hibernate.STRING)); - registerFunction("dayofmonth", new StandardSQLFunction("dayofmonth", Hibernate.INTEGER)); - registerFunction("dayofweek", new StandardSQLFunction("dayofweek", Hibernate.INTEGER)); - registerFunction("dayofyear", new StandardSQLFunction("dayofyear", Hibernate.INTEGER)); -// registerFunction("hour", new StandardSQLFunction("hour", Hibernate.INTEGER)); -// registerFunction("minute", new StandardSQLFunction("minute", Hibernate.INTEGER)); -// registerFunction("month", new StandardSQLFunction("month", Hibernate.INTEGER)); - registerFunction("monthname", new StandardSQLFunction("monthname", Hibernate.STRING)); - registerFunction("quarter", new StandardSQLFunction("quarter", Hibernate.INTEGER)); -// registerFunction("second", new StandardSQLFunction("second", Hibernate.INTEGER)); - registerFunction("week", new StandardSQLFunction("week", Hibernate.INTEGER)); -// registerFunction("year", new StandardSQLFunction("year", Hibernate.INTEGER)); - - registerFunction("curdate", new NoArgSQLFunction("curdate", Hibernate.DATE)); - registerFunction("curtime", new NoArgSQLFunction("curtime", Hibernate.TIME)); - registerFunction("curtimestamp", new NoArgSQLFunction("curtimestamp", Hibernate.TIME)); - registerFunction("now", new NoArgSQLFunction("now", Hibernate.TIMESTAMP)); - - registerFunction("database", new NoArgSQLFunction("database", Hibernate.STRING)); - registerFunction("user", new NoArgSQLFunction("user", Hibernate.STRING)); - - getDefaultProperties().setProperty(Environment.STATEMENT_BATCH_SIZE, DEFAULT_BATCH_SIZE); - - } - - public String getAddColumnString() { - return "add column"; - } - - public boolean supportsIdentityColumns() { - return true; - } - - public String getIdentityColumnString() { - return "generated by default as identity"; // not null is implicit - } - - public String getIdentitySelectString() { - return "call identity()"; - } - - public String getIdentityInsertString() { - return "null"; - } - - public String getForUpdateString() { - return " for update"; - } - - public boolean supportsUnique() { - return true; - } - - public boolean supportsLimit() { - return true; - } - - public String getLimitString(String sql, boolean hasOffset) { - return new StringBuffer(sql.length() + 20). - append(sql). - append(hasOffset ? " limit ? offset ?" : " limit ?"). - toString(); - } - - public boolean bindLimitParametersInReverseOrder() { - return true; - } - - public boolean bindLimitParametersFirst() { - return false; - } - - public boolean supportsIfExistsAfterTableName() { - return true; - } - - public boolean supportsSequences() { - return true; - } - - public boolean supportsPooledSequences() { - return true; - } - - public String getCreateSequenceString(String sequenceName) { - return "create sequence " + sequenceName; - } - - public String getDropSequenceString(String sequenceName) { - return "drop sequence " + sequenceName; - } - - public String getSelectSequenceNextValString(String sequenceName) { - return "next value for " + sequenceName; - } - - public String getSequenceNextValString(String sequenceName) { - return "call next value for " + sequenceName; - } - - public String getQuerySequencesString() { - return querySequenceString; - } - - public ViolatedConstraintNameExtracter getViolatedConstraintNameExtracter() { - return EXTRACTER; - } - - private static ViolatedConstraintNameExtracter EXTRACTER = new TemplatedViolatedConstraintNameExtracter() { - - /** - * Extract the name of the violated constraint from the given SQLException. - * - * @param sqle The exception that was the result of the constraint violation. - * @return The extracted constraint name. - */ - public String extractConstraintName(SQLException sqle) { - String constraintName = null; - // 23000: Check constraint violation: {0} - // 23001: Unique index or primary key violation: {0} - if(sqle.getSQLState().startsWith("23")) { - String message = sqle.getMessage(); - int idx = message.indexOf("violation: "); - if(idx > 0) { - constraintName = message.substring(idx + "violation: ".length()); - } - } - return constraintName; - } - - }; - - public boolean supportsTemporaryTables() { - return true; - } - - public String getCreateTemporaryTableString() { - return "create temporary table if not exists"; - } - - public boolean supportsCurrentTimestampSelection() { - return true; - } - - public boolean isCurrentTimestampSelectStringCallable() { - return false; - } - - public String getCurrentTimestampSelectString() { - return "call current_timestamp()"; - } - - public boolean supportsUnionAll() { - return true; - } - - - // Overridden informational metadata ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - - public boolean supportsLobValueChangePropogation() { - return false; - } -} \ No newline at end of file