提交 abe7c7b2 authored 作者: Thomas Mueller's avatar Thomas Mueller

Documentation.

上级 85fbafb2
...@@ -18,7 +18,7 @@ Change Log ...@@ -18,7 +18,7 @@ Change Log
<h1>Change Log</h1> <h1>Change Log</h1>
<h2>Next Version (unreleased)</h2> <h2>Next Version (unreleased)</h2>
<ul><li>DATABASE_TO_UPPER: when set to false, all identifier names (table names, column names) <ul><li>DATABASE_TO_UPPER: when set to false, all identifier names (table names, column names)
are case sensitive (except aggregate, built-in functions, data types, and keywords). are case sensitive (except aggregate, built-in functions, data types, and keywords).
This is for improved compatibility with MySQL and PostgreSQL. This is for improved compatibility with MySQL and PostgreSQL.
</li><li>When upgrading from an older 1.3.x version to version 1.3.157, when using BLOB or CLOB data, </li><li>When upgrading from an older 1.3.x version to version 1.3.157, when using BLOB or CLOB data,
...@@ -32,7 +32,7 @@ Change Log ...@@ -32,7 +32,7 @@ Change Log
</li><li>H2 Console: improved system tray icon for Mac OS X (transparent background). </li><li>H2 Console: improved system tray icon for Mac OS X (transparent background).
</li><li>String.toUpperCase() was used a few places, which is problematic when using the Turkish locale. </li><li>String.toUpperCase() was used a few places, which is problematic when using the Turkish locale.
The method has been replaced with toUpperCase(Locale.ENGLISH) to solve such problems. The method has been replaced with toUpperCase(Locale.ENGLISH) to solve such problems.
</li><li>Shell tool: the built-in command "distinct" has been removed </li><li>Shell tool: the built-in command "distinct" has been removed
(use the SQL statements "show tables" / "show columns from tableName" instead). (use the SQL statements "show tables" / "show columns from tableName" instead).
The result set formatting has been improved. The result set formatting has been improved.
</li><li>MERGE: if a unique key was violated (but not the primary key or the key columns of the merge itself), </li><li>MERGE: if a unique key was violated (but not the primary key or the key columns of the merge itself),
......
...@@ -1031,7 +1031,7 @@ or the SQL statement <code>SET MODE Derby</code>. ...@@ -1031,7 +1031,7 @@ or the SQL statement <code>SET MODE Derby</code>.
That means only one row with <code>NULL</code> in one of the columns is allowed. That means only one row with <code>NULL</code> in one of the columns is allowed.
</li><li>Concatenating <code>NULL</code> with another value </li><li>Concatenating <code>NULL</code> with another value
results in the other value. results in the other value.
</li><li>Support the pseudo-table SYSIBM.SYSDUMMY1. </li><li>Support the pseudo-table SYSIBM.SYSDUMMY1.
</li></ul> </li></ul>
<h3>HSQLDB Compatibility Mode</h3> <h3>HSQLDB Compatibility Mode</h3>
......
...@@ -552,7 +552,7 @@ See also <a href="build.html#providing_patches">Providing Patches</a>. ...@@ -552,7 +552,7 @@ See also <a href="build.html#providing_patches">Providing Patches</a>.
</li><li>Support [INNER | OUTER] JOIN USING(column [,...]). </li><li>Support [INNER | OUTER] JOIN USING(column [,...]).
</li><li>Support NATURAL [ { LEFT | RIGHT } [ OUTER ] | INNER ] JOIN (Derby, Oracle) </li><li>Support NATURAL [ { LEFT | RIGHT } [ OUTER ] | INNER ] JOIN (Derby, Oracle)
</li><li>GROUP BY columnNumber (similar to ORDER BY columnNumber) (MySQL, PostgreSQL, SQLite; not by HSQLDB and Derby). </li><li>GROUP BY columnNumber (similar to ORDER BY columnNumber) (MySQL, PostgreSQL, SQLite; not by HSQLDB and Derby).
</li><li>Sybase / MS SQL Server compatiblitiy: CONVERT(..) parameters are swapped. </li><li>Sybase / MS SQL Server compatibility: CONVERT(..) parameters are swapped.
</li></ul> </li></ul>
<h2>Not Planned</h2> <h2>Not Planned</h2>
......
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
...@@ -1280,6 +1280,14 @@ public abstract class TestBase { ...@@ -1280,6 +1280,14 @@ public abstract class TestBase {
memory.clear(); memory.clear();
} }
/**
* Verify the next method call on the object will throw an exception.
*
* @param <T> the class of the object
* @param exceptionClass the expected exception class to be thrown
* @param obj the object to wrap
* @return a proxy for the object
*/
protected <T> T assertThrows(final Class<?> exceptionClass, final T obj) { protected <T> T assertThrows(final Class<?> exceptionClass, final T obj) {
return assertThrows(new Thread.UncaughtExceptionHandler() { return assertThrows(new Thread.UncaughtExceptionHandler() {
public void uncaughtException(Thread t, Throwable e) { public void uncaughtException(Thread t, Throwable e) {
...@@ -1291,6 +1299,14 @@ public abstract class TestBase { ...@@ -1291,6 +1299,14 @@ public abstract class TestBase {
}, exceptionClass.toString(), obj); }, exceptionClass.toString(), obj);
} }
/**
* Verify the next method call on the object will throw an exception.
*
* @param <T> the class of the object
* @param errorCode the expected error code
* @param obj the object to wrap
* @return a proxy for the object
*/
protected <T> T assertThrows(final int errorCode, final T obj) { protected <T> T assertThrows(final int errorCode, final T obj) {
return assertThrows(new Thread.UncaughtExceptionHandler() { return assertThrows(new Thread.UncaughtExceptionHandler() {
public void uncaughtException(Thread t, Throwable e) { public void uncaughtException(Thread t, Throwable e) {
...@@ -1309,6 +1325,16 @@ public abstract class TestBase { ...@@ -1309,6 +1325,16 @@ public abstract class TestBase {
}, "SQLException with error code " + errorCode, obj); }, "SQLException with error code " + errorCode, obj);
} }
/**
* Verify the next method call on the object will throw an exception.
*
* @param <T> the class of the object
* @param handler the exception handler to call
* @param expected the message to print if the method didn't throw an
* exception
* @param obj the object to wrap
* @return a proxy for the object
*/
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
protected <T> T assertThrows(final Thread.UncaughtExceptionHandler handler, final String expected, final T obj) { protected <T> T assertThrows(final Thread.UncaughtExceptionHandler handler, final String expected, final T obj) {
Class<?> c = obj.getClass(); Class<?> c = obj.getClass();
......
...@@ -19,6 +19,12 @@ import org.h2.message.DbException; ...@@ -19,6 +19,12 @@ import org.h2.message.DbException;
*/ */
public abstract class AssertThrows { public abstract class AssertThrows {
/**
* Create a new assertion object, and call the test method to verify the
* expected exception is thrown.
*
* @param expectedExceptionClass the expected exception class
*/
public AssertThrows(final Class<? extends Exception> expectedExceptionClass) { public AssertThrows(final Class<? extends Exception> expectedExceptionClass) {
this(new Thread.UncaughtExceptionHandler() { this(new Thread.UncaughtExceptionHandler() {
public void uncaughtException(Thread t, Throwable e) { public void uncaughtException(Thread t, Throwable e) {
...@@ -33,7 +39,7 @@ public abstract class AssertThrows { ...@@ -33,7 +39,7 @@ public abstract class AssertThrows {
expectedExceptionClass.getSimpleName() + expectedExceptionClass.getSimpleName() +
" to be thrown, but the method under test threw an exception of type\n" + " to be thrown, but the method under test threw an exception of type\n" +
e.getClass().getSimpleName() + e.getClass().getSimpleName() +
" (see in the 'Caused by' for the exception tha was thrown)"); " (see in the 'Caused by' for the exception that was thrown)");
ae.initCause(e); ae.initCause(e);
throw ae; throw ae;
} }
...@@ -41,6 +47,10 @@ public abstract class AssertThrows { ...@@ -41,6 +47,10 @@ public abstract class AssertThrows {
}); });
} }
/**
* Create a new assertion object, and call the test method to verify the
* expected exception is thrown.
*/
public AssertThrows() { public AssertThrows() {
this(new Thread.UncaughtExceptionHandler() { this(new Thread.UncaughtExceptionHandler() {
public void uncaughtException(Thread t, Throwable e) { public void uncaughtException(Thread t, Throwable e) {
...@@ -53,6 +63,12 @@ public abstract class AssertThrows { ...@@ -53,6 +63,12 @@ public abstract class AssertThrows {
}); });
} }
/**
* Create a new assertion object, and call the test method to verify the
* expected exception is thrown.
*
* @param expectedErrorCode the error code of the exception
*/
public AssertThrows(final int expectedErrorCode) { public AssertThrows(final int expectedErrorCode) {
this(new Thread.UncaughtExceptionHandler() { this(new Thread.UncaughtExceptionHandler() {
public void uncaughtException(Thread t, Throwable e) { public void uncaughtException(Thread t, Throwable e) {
...@@ -74,7 +90,6 @@ public abstract class AssertThrows { ...@@ -74,7 +90,6 @@ public abstract class AssertThrows {
}); });
} }
private AssertThrows(Thread.UncaughtExceptionHandler handler) { private AssertThrows(Thread.UncaughtExceptionHandler handler) {
try { try {
test(); test();
...@@ -84,6 +99,11 @@ public abstract class AssertThrows { ...@@ -84,6 +99,11 @@ public abstract class AssertThrows {
} }
} }
/**
* The test method that is called.
*
* @throws Exception the exception
*/
public abstract void test() throws Exception; public abstract void test() throws Exception;
} }
...@@ -22,8 +22,8 @@ import org.h2.util.SourceCompiler; ...@@ -22,8 +22,8 @@ import org.h2.util.SourceCompiler;
*/ */
public class ProxyCodeGenerator { public class ProxyCodeGenerator {
static SourceCompiler compiler = new SourceCompiler(); private static SourceCompiler compiler = new SourceCompiler();
static HashMap<Class<?>, Class<?>> proxyMap = New.hashMap(); private static HashMap<Class<?>, Class<?>> proxyMap = New.hashMap();
private TreeSet<String> imports = new TreeSet<String>(); private TreeSet<String> imports = new TreeSet<String>();
private TreeMap<String, Method> methods = new TreeMap<String, Method>(); private TreeMap<String, Method> methods = new TreeMap<String, Method>();
...@@ -31,6 +31,12 @@ public class ProxyCodeGenerator { ...@@ -31,6 +31,12 @@ public class ProxyCodeGenerator {
private String className; private String className;
private Class<?> extendsClass; private Class<?> extendsClass;
/**
* Generate a proxy class. The returned class extends the given class.
*
* @param c the class to extend
* @return the proxy class
*/
public static Class<?> getClassProxy(Class<?> c) throws ClassNotFoundException { public static Class<?> getClassProxy(Class<?> c) throws ClassNotFoundException {
Class<?> p = proxyMap.get(c); Class<?> p = proxyMap.get(c);
if (p != null) { if (p != null) {
...@@ -53,10 +59,16 @@ public class ProxyCodeGenerator { ...@@ -53,10 +59,16 @@ public class ProxyCodeGenerator {
return px; return px;
} }
void setPackageName(String packageName) { private void setPackageName(String packageName) {
this.packageName = packageName; this.packageName = packageName;
} }
/**
* Generate a class that implements all static methods of the given class,
* but as non-static.
*
* @param c the class to extend
*/
void generateStaticProxy(Class<?> clazz) { void generateStaticProxy(Class<?> clazz) {
imports.clear(); imports.clear();
addImport(InvocationHandler.class); addImport(InvocationHandler.class);
...@@ -72,7 +84,7 @@ public class ProxyCodeGenerator { ...@@ -72,7 +84,7 @@ public class ProxyCodeGenerator {
} }
} }
void generateClassProxy(Class<?> clazz) { private void generateClassProxy(Class<?> clazz) {
imports.clear(); imports.clear();
addImport(InvocationHandler.class); addImport(InvocationHandler.class);
addImport(Method.class); addImport(Method.class);
...@@ -90,7 +102,7 @@ public class ProxyCodeGenerator { ...@@ -90,7 +102,7 @@ public class ProxyCodeGenerator {
} }
} }
void addMethod(Method m) { private void addMethod(Method m) {
if (methods.containsKey(getMethodName(m))) { if (methods.containsKey(getMethodName(m))) {
// already declared in a subclass // already declared in a subclass
return; return;
...@@ -117,7 +129,7 @@ public class ProxyCodeGenerator { ...@@ -117,7 +129,7 @@ public class ProxyCodeGenerator {
return buff.toString(); return buff.toString();
} }
void addImport(Class<?> c) { private void addImport(Class<?> c) {
while (c.isArray()) { while (c.isArray()) {
c = c.getComponentType(); c = c.getComponentType();
} }
...@@ -127,6 +139,7 @@ public class ProxyCodeGenerator { ...@@ -127,6 +139,7 @@ public class ProxyCodeGenerator {
} }
} }
} }
private static String getClassName(Class<?> c) { private static String getClassName(Class<?> c) {
String s = c.getSimpleName(); String s = c.getSimpleName();
while (true) { while (true) {
...@@ -138,7 +151,8 @@ public class ProxyCodeGenerator { ...@@ -138,7 +151,8 @@ public class ProxyCodeGenerator {
} }
return s; return s;
} }
void write(PrintWriter writer) {
private void write(PrintWriter writer) {
if (packageName != null) { if (packageName != null) {
writer.println("package " + packageName + ";"); writer.println("package " + packageName + ";");
} }
......
...@@ -686,4 +686,4 @@ mcleod decade experience travel willing scjp himself routinely tsi retrieving ...@@ -686,4 +686,4 @@ mcleod decade experience travel willing scjp himself routinely tsi retrieving
multiplied ross judson closeable watcher enqueued referent refs watch tracked multiplied ross judson closeable watcher enqueued referent refs watch tracked
preserving disallowed restrictive dst regions kiritimati flow wider nanosecond preserving disallowed restrictive dst regions kiritimati flow wider nanosecond
march april cutover julian transitions enderbury kwajalein viewport onscroll march april cutover julian transitions enderbury kwajalein viewport onscroll
umlaut reconstruct inclusive umlaut reconstruct inclusive proxies
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论