提交 11ecd55b authored 作者: sainsbury.kerry's avatar sainsbury.kerry

Implemented INIT connection property

上级 691ae37d
......@@ -21,6 +21,9 @@ Change Log
<ul><li>Large transactions could run out of heap space. Fixed.
</li><li>The default setting for the system property h2.webMaxValueLength is now 100000 (it was 10000 before).
</li><li>Creating a database was delayed about 2 seconds if the directory didn't exist.
</li><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)
</li></ul>
<h2>Version 1.2.129 (2010-02-19)</h2>
......
......@@ -516,6 +516,13 @@ This is achieved using different database URLs. Settings in the URLs are not cas
jdbc:h2:&lt;url&gt;;DB_CLOSE_ON_EXIT=FALSE
</td>
</tr>
<tr>
<td><a href="#execute_sql_on_connection">Execute SQL on connection</a></td>
<td class="notranslate">
jdbc:h2:&lt;url&gt;;INIT=RUNSCRIPT FROM '~/create.sql'<br />
jdbc:h2:file:~/sample;INIT=RUNSCRIPT FROM '~/create.sql'\\;RUNSCRIPT FROM '~/populate.sql'<br />
</td>
</tr>
<tr>
<td><a href="#passwords">User name and/or password</a></td>
<td class="notranslate">
......@@ -749,6 +756,18 @@ The database URL to disable database closing on exit is:
String url = "jdbc:h2:~/test;DB_CLOSE_ON_EXIT=FALSE";
</pre>
<h2 id="execute_sql_on_connection">Execute SQL on Connection</h2>
<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.
</p>
<pre>
String url = "jdbc:h2:mem;INIT=RUNSCRIPT FROM '~/create.sql'\\;RUNSCRIPT FROM '~/populate.sql'";
</pre>
<h2 id="ignore_unknown_settings">Ignore Unknown Settings</h2>
<p>
Some applications (for example OpenOffice.org Base) pass some additional parameters
......
......@@ -382,7 +382,6 @@ See also <a href="build.html#providing_patches">Providing Patches</a>.
</li><li>OSGi: create a sample application, test, document.
</li><li>help.csv: use complete examples for functions; run as test case.
</li><li>Functions to calculate the memory and disk space usage of a table, a row, or a value.
</li><li>If the database URL ends with ";INIT=&lt;url&gt;" then the SQL script from the given file or URL is executed (the user name must have admin rights). Example URL: jdbc:h2:mem:test;INIT=~/init.sql
</li><li>Re-implement PooledConnection; use a lightweight connection object.
</li><li>Doclet: convert tests in javadocs to a java class.
</li><li>Doclet: format fields like methods, but support sorting by name and value.
......
......@@ -77,7 +77,7 @@ public class ConnectionInfo implements Cloneable {
set.addAll(list);
String[] connectionTime = new String[] { "ACCESS_MODE_DATA", "AUTOCOMMIT", "CIPHER",
"CREATE", "CACHE_TYPE", "DB_CLOSE_ON_EXIT", "FILE_LOCK", "IGNORE_UNKNOWN_SETTINGS", "IFEXISTS",
"PASSWORD", "RECOVER", "USER", "AUTO_SERVER",
"INIT", "PASSWORD", "RECOVER", "USER", "AUTO_SERVER",
"AUTO_RECONNECT", "OPEN_NEW" };
for (String key : connectionTime) {
if (SysProperties.CHECK && set.contains(key)) {
......
......@@ -6,6 +6,8 @@
*/
package org.h2.engine;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.HashMap;
import org.h2.command.CommandInterface;
import org.h2.command.Parser;
......@@ -117,11 +119,19 @@ public class Engine {
throw DbException.convert(e);
}
}
String init = ci.removeProperty("INIT", null);
Session session = openSession(ci);
validateUserAndPassword(true);
if (backup != null) {
session.setConnectionInfo(backup);
}
if (init != null) {
runInitScripts(session, init);
}
return session;
} catch (DbException e) {
if (e.getErrorCode() == ErrorCode.WRONG_USER_OR_PASSWORD) {
......@@ -131,6 +141,24 @@ public class Engine {
}
}
private void runInitScripts(Session session, String init) throws DbException {
Statement stat = null;
try {
stat = session.createConnection(false).createStatement();
stat.execute(init);
} catch (SQLException e) {
throw DbException.convert(e);
} finally {
if (stat != null) {
try {
stat.close();
} catch (SQLException e) {
throw DbException.convert(e);
}
}
}
}
private synchronized Session openSession(ConnectionInfo ci) {
boolean ifExists = ci.removeProperty("IFEXISTS", false);
boolean ignoreUnknownSetting = ci.removeProperty("IGNORE_UNKNOWN_SETTINGS", false);
......
......@@ -87,6 +87,7 @@ 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;
......@@ -136,6 +137,7 @@ import org.h2.test.unit.TestValueHashMap;
import org.h2.test.unit.TestValueMemory;
import org.h2.test.utils.OutputCatcher;
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;
......@@ -460,6 +462,7 @@ kill -9 `jps -l | grep "org.h2.test." | cut -d " " -f 1`
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);
......@@ -468,6 +471,7 @@ kill -9 `jps -l | grep "org.h2.test." | cut -d " " -f 1`
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);
......
/*
* Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License,
* Version 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;
/**
*/
public class TestConnectionInfo extends TestBase {
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=INSERT this...\\;UPDATE that..." +
";IFEXISTS=TRUE",
info);
assertEquals("jdbc:h2:mem:testdb", connectionInfo.getURL());
assertEquals("2", connectionInfo.getProperty("LOG", ""));
assertEquals("rws", connectionInfo.getProperty("ACCESS_MODE_DATA", ""));
assertEquals("INSERT this...;UPDATE that...", connectionInfo.getProperty("INIT", ""));
assertEquals("TRUE", connectionInfo.getProperty("IFEXISTS", ""));
assertEquals("undefined", connectionInfo.getProperty("CACHE_TYPE", "undefined"));
}
}
/*
* Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License,
* Version 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.util.IOUtils;
import java.sql.*;
import java.io.FileWriter;
import java.io.PrintWriter;
/**
* 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 {
// Create two scripts that we will run via "INIT"
FileWriter fw = new FileWriter(baseDir + "/test-init-1.sql");
PrintWriter writer = new PrintWriter(fw);
writer.println("create table test(id int identity, name varchar);");
writer.println("insert into test(name) values('cat');");
writer.close();
fw = new FileWriter(baseDir + "/test-init-2.sql");
writer = new PrintWriter(fw);
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 '" + baseDir + "/test-init-1.sql'\\;" +
"RUNSCRIPT FROM '" + baseDir + "/test-init-2.sql'");
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(baseDir + "/test-init-1.sql");
IOUtils.delete(baseDir + "/test-init-2.sql");
}
}
......@@ -79,7 +79,7 @@ compounds compress compressed compresses compression compressor compsci compute
computed computer computers computing con concat concatenate concatenated
concatenates concatenation concentrate concept concerning concur concurrency
concurrent concurrently cond condition conditions conf config configuration
configure configured confirmed conflict conforming confusing confusingly cong
configure configured confirm confirmed conflict conforming confusing confusingly cong
conn connect connected connecting connection connections connects cons
consecutive consequential considerations considered consistency consistent
consisting console conspicuously const constant constants constitute constitutes
......@@ -231,7 +231,7 @@ javascript javax javolution jcr jdbc jdbcx jdk jdo jee jefferson jetty jim jira
jndi jnlp job joe joel joerg johann john johnson join joined joins jon jones jpa
jpackage jpox jre jsessionid jsmooth json jsp jsr jsse jts judgment judicial
julia jun june jurisdiction jurisdictions just jvm kappa karin keep keeps kept
kerberos kernel kernelpanic key keyalg keying keypass keys keystore keystores
kerberos kernel kernelpanic kerry key keyalg keying keypass keys keystore keystores
keytool keyword keywords kill killed killing kills kind kindergarden kinds kit
know knowledge known knows koi konqueror label labeled labels lack lambda lamp
land lang language languages laptop laquo large larger largest larr last
......@@ -302,7 +302,7 @@ ownership oymaurice pack package packages packaging packets pad padded padding
page pages pair pairs pal panel panels paolo papa paper para paradox paragraph
paragraphs param parameter parameterized parameters params paren parent
parentheses parentid parse parsed parsedatetime parser parses parsing part
partial partially participant particular parties partition partnership parts
partial partially participant particular particularly parties partition partnership parts
party pass passed passes passing passive password passwords past paste pasv patch
patent patents path paths pattern patterns paul pause paused pay payment pdf
peace peek pencil pending people per percent perform performance performed
......@@ -313,7 +313,7 @@ philip phone php phrase phrases physical pid pieces pier pilot ping pinned pipe
piv pivot pkcolumn pkcs pktable place placeholders plain plaintext plan planned
plans plant platform platforms play player please pluggable plugin plus plusmn
pmd png point pointer pointers pointing points polar pole poleposition poll
polling polski pool poolable pooled pooling pop populated population popup port
polling polski pool poolable pooled pooling pop populate populated population popup port
portability portable portal portals ported porting portions portlet ports
portugal portugu portuguese pos position positioned positions positive
possibility possible possibly post postal postgre postgres postgresql postmaster
......@@ -371,7 +371,7 @@ rmiregistry rnd rnfr rnto road roadmap role roles roll rollback rolled rolling
rolls roman ronni room root roots rot round rounded rounding roundmagic rounds
routine row rowcount rowid rownum rows rowsize royalty rpad rpm rsa rsaquo rsquo
rss rtrim ruby rubyforge ruebezahl rule rules run rund rundll runnable running
runs runscript runtime russian rwd rws sabine safari safe safely said salary sale
runs runscript runtime russian rwd rws sabine safari safe safely said sainsbury salary sale
sales salt salz sam same samp sample samples sans sat sata save saved savepoint
savepoints saves saving say saying says sbquo scala scalar scale scan scanned
scanner scanners scanning scans scheduler schem schema schemas schemata schmorp
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论