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

Documentation / cleanup

上级 05519749
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.
......@@ -367,28 +367,33 @@ public class SysProperties {
Utils.getProperty("h2.useThreadContextClassLoader", false);
/**
* System property <code>h2.serializeJavaObject</code>
* (default: true).<br />
* System property <code>h2.serializeJavaObject</code> (default: true).<br />
* <b>If true</b>, values of type OTHER will be stored in serialized form
* and have the semantics of binary data for all operations (such as sorting and conversion to string).
* and have the semantics of binary data for all operations (such as sorting
* and conversion to string).
* <br />
* <b>If false</b>, the objects will be serialized only for I/O operations and a few other special cases
* (for example when someone tries to get the value in binary form or when comparing objects
* that are not comparable otherwise).
* <b>If false</b>, the objects will be serialized only for I/O operations
* and a few other special cases (for example when someone tries to get the
* value in binary form or when comparing objects that are not comparable
* otherwise).
* <br />
* If the object implements the Comparable interface, the method compareTo
* will be used for sorting (but only if objects being compared have a common comparable
* super type). Otherwise the objects will be compared by type, and if they are the same by hashCode, and
* if the hash codes are equal, but objects are not, the serialized forms (the byte arrays) are compared.
* will be used for sorting (but only if objects being compared have a
* common comparable super type). Otherwise the objects will be compared by
* type, and if they are the same by hashCode, and if the hash codes are
* equal, but objects are not, the serialized forms (the byte arrays) are
* compared.
* <br />
* The string representation of the values use the toString method of object.
* The string representation of the values use the toString method of
* object.
* <br />
* In client-server mode, the server must have all required classes in the class path.
* On the client side, this setting is required to be disabled as well, to have correct string representation
* and display size.
* In client-server mode, the server must have all required classes in the
* class path. On the client side, this setting is required to be disabled
* as well, to have correct string representation and display size.
* <br />
* In embedded mode, no data copying occurs, so the user has to make defensive copy himself before storing,
* or ensure that the value object is immutable.
* In embedded mode, no data copying occurs, so the user has to make
* defensive copy himself before storing, or ensure that the value object is
* immutable.
*/
public static final boolean SERIALIZE_JAVA_OBJECT = Utils.getProperty("h2.serializeJavaObject", true);
......
......@@ -75,7 +75,7 @@ public class Constants {
* The TCP protocol version number 11.
*/
public static final int TCP_PROTOCOL_VERSION_12 = 12;
/**
* The major version of this database.
*/
......
......@@ -72,7 +72,11 @@ public class FullTextLucene extends FullText {
private static final String LUCENE_FIELD_MODIFIED = "_modified";
private static final String LUCENE_FIELD_COLUMN_PREFIX = "_";
private static final String IN_MEMORY_PERFIX = "mem:";
/**
* The prefix for a in-memory path. This prefix is only used internally
* within this class and not related to the database URL.
*/
private static final String IN_MEMORY_PREFIX = "mem:";
/**
* Initializes full text search functionality for this database. This adds
......@@ -265,7 +269,7 @@ public class FullTextLucene extends FullText {
access.modifier = new IndexModifier(path, analyzer, recreate);
//*/
//## LUCENE3 ##
Directory indexDir = path.startsWith(IN_MEMORY_PERFIX) ? new RAMDirectory() : FSDirectory.open(new File(path));
Directory indexDir = path.startsWith(IN_MEMORY_PREFIX) ? new RAMDirectory() : FSDirectory.open(new File(path));
boolean recreate = !IndexReader.indexExists(indexDir);
Analyzer analyzer = new StandardAnalyzer(Version.LUCENE_30);
IndexWriter writer = new IndexWriter(indexDir, analyzer,
......@@ -299,10 +303,11 @@ public class FullTextLucene extends FullText {
String path = rs.getString(1);
if (path == null) {
/*## LUCENE2 ##
throw throwException("Fulltext search for in-memory databases is not supported with Lucene 2. Please use Lucene 3 instead.");
//*/
throw throwException("Fulltext search for in-memory databases " +
"is not supported with Lucene 2. Please use Lucene 3 instead.");
//*/
//## LUCENE3 ##
return IN_MEMORY_PERFIX + conn.getCatalog();
return IN_MEMORY_PREFIX + conn.getCatalog();
//*/
}
int index = path.lastIndexOf(':');
......@@ -343,7 +348,7 @@ public class FullTextLucene extends FullText {
if (access != null) {
removeIndexAccess(access, path);
}
if (!path.startsWith(IN_MEMORY_PERFIX)) {
if (!path.startsWith(IN_MEMORY_PREFIX)) {
FileUtils.deleteRecursive(path, false);
}
}
......
......@@ -31,7 +31,6 @@ 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.CloseWatcher;
......@@ -81,7 +80,6 @@ public class JdbcConnection extends TraceObject implements Connection {
private CommandInterface setQueryTimeout, getQueryTimeout;
private int savepointId;
private Trace trace;
private String catalog;
private Statement executingStatement;
private CompareMode compareMode = CompareMode.getInstance(null, 0);
......
......@@ -103,6 +103,7 @@ public interface DataHandler {
* Read from a lob.
*
* @param lobId the lob
* @param hmac the message authentication code
* @param offset the offset within the lob
* @param buff the target buffer
* @param off the offset within the target buffer
......
......@@ -282,7 +282,7 @@ public class LobStorage {
private final long lob;
private final byte[] hmac;
/**
* The position.
*/
......@@ -547,6 +547,7 @@ public class LobStorage {
* Get the input stream for the given lob.
*
* @param lobId the lob id
* @param hmac the message authentication code (for remote input streams)
* @param byteCount the number of bytes to read, or -1 if not known
* @return the stream
*/
......
......@@ -268,8 +268,10 @@ public class FilePathDisk extends FilePath {
}
public InputStream newInputStream() throws IOException {
if (name.indexOf(':') > 1) {
// if the : is in position 1, a windows file access is assumed: C:.. or D:
int index = name.indexOf(':');
if (index > 1 && index < 20) {
// if the ':' is in position 1, a windows file access is assumed: C:.. or D:
// if the ':' is not at the beginning, assume its a file name with a colon
if (name.startsWith(CLASSPATH_PREFIX)) {
String fileName = name.substring(CLASSPATH_PREFIX.length());
if (!fileName.startsWith("/")) {
......
......@@ -626,7 +626,8 @@ public class Server extends Tool implements Runnable, ShutdownHandler {
// Mac OS: to open a page with Safari, use "open -a Safari"
Runtime.getRuntime().exec(new String[] { "open", url });
} else {
String[] browsers = { "google-chrome", "firefox", "mozilla-firefox", "mozilla", "konqueror", "netscape", "opera", "midori" };
String[] browsers = { "google-chrome", "firefox", "mozilla-firefox",
"mozilla", "konqueror", "netscape", "opera", "midori" };
boolean ok = false;
for (String b : browsers) {
try {
......
......@@ -404,7 +404,11 @@ public class Utils {
}
/**
* Checks if given classes have common Comparable superclass.
* Checks if given classes have a common Comparable superclass.
*
* @param c1 the first class
* @param c2 the second class
* @return true if they have
*/
public static boolean haveCommonComparableSuperclass(Class<?> c1, Class<?> c2) {
if (c1 == c2 || c1.isAssignableFrom(c2) || c2.isAssignableFrom(c1)) {
......
......@@ -21,7 +21,6 @@ import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.sql.Time;
import java.sql.Timestamp;
import java.util.Arrays;
import org.h2.constant.ErrorCode;
import org.h2.engine.Constants;
import org.h2.engine.SessionInterface;
......@@ -729,11 +728,13 @@ public class Transfer {
/**
* Verify the HMAC.
*
* @throws DbException if the HMAC does not verify
* @param hmac the message authentication code
* @param lobId the lobId
* @throws DbException if the HMAC does not match
*/
public void verifyLobMac(byte[] hmacData, long lobId) {
public void verifyLobMac(byte[] hmac, long lobId) {
byte[] result = calculateLobMac(lobId);
if (!Arrays.equals(result, hmacData)) {
if (!Utils.compareSecure(hmac, result)) {
throw DbException.get(ErrorCode.REMOTE_CONNECTION_NOT_ALLOWED);
}
}
......
......@@ -21,7 +21,14 @@ public class ValueBytes extends Value {
private static final ValueBytes EMPTY = new ValueBytes(Utils.EMPTY_BYTES);
/**
* The value.
*/
protected byte[] value;
/**
* The hash code.
*/
protected int hash;
protected ValueBytes(byte[] v) {
......
......@@ -97,17 +97,19 @@ public class ValueJavaObject extends ValueBytes {
boolean o1Comparable = o1 instanceof Comparable;
boolean o2Comparable = o2 instanceof Comparable;
if (o1Comparable && o2Comparable &&
Utils.haveCommonComparableSuperclass(o1.getClass(), o2.getClass())) {
return ((Comparable) o1).compareTo(o2);
Utils.haveCommonComparableSuperclass(o1.getClass(), o2.getClass())) {
@SuppressWarnings("unchecked")
Comparable<Object> c1 = (Comparable<Object>) o1;
return c1.compareTo(o2);
}
// group by types
if (o1.getClass() != o2.getClass()) {
if (o1Comparable != o2Comparable) {
return o1Comparable ? -1 : 1;
}
if (o1Comparable != o2Comparable) {
return o1Comparable ? -1 : 1;
}
return o1.getClass().getName().compareTo(o2.getClass().getName());
}
......@@ -119,7 +121,7 @@ public class ValueJavaObject extends ValueBytes {
if (o1.equals(o2)) {
return 0;
}
return Utils.compareNotNull(getBytesNoCopy(), v.getBytesNoCopy());
}
......
......@@ -69,6 +69,7 @@ public class ValueLobDb extends Value implements Value.ValueClob, Value.ValueBlo
* @param lobStorage the storage
* @param tableId the table id
* @param id the lob id
* @param hmac the message authentication code
* @param precision the precision (number of bytes / characters)
* @return the value
*/
......
......@@ -42,7 +42,7 @@ public class TestFullText extends TestBase {
}
public void test() throws Exception {
testUuidPrimaryKey(false);
testUuidPrimaryKey(false);
testAutoAnalyze();
testNativeFeatures();
testTransaction(false);
......@@ -75,16 +75,16 @@ public class TestFullText extends TestBase {
deleteDb("fullTextReopen");
}
private static void close(Collection<Connection> conns) throws SQLException {
for (Connection conn : conns) {
conn.close();
}
private static void close(Collection<Connection> list) throws SQLException {
for (Connection conn : list) {
conn.close();
}
}
private Connection getConnection(String name, Collection<Connection> conns) throws SQLException {
Connection conn = getConnection(name);
conns.add(conn);
return conn;
private Connection getConnection(String name, Collection<Connection> list) throws SQLException {
Connection conn = getConnection(name);
list.add(conn);
return conn;
}
private void testAutoAnalyze() throws SQLException {
......@@ -92,9 +92,9 @@ public class TestFullText extends TestBase {
Connection conn;
Statement stat;
ArrayList<Connection> conns = new ArrayList<Connection>();
ArrayList<Connection> connList = new ArrayList<Connection>();
conn = getConnection("fullTextNative", conns);
conn = getConnection("fullTextNative", connList);
stat = conn.createStatement();
stat.execute("create alias if not exists ft_init for \"org.h2.fulltext.FullText.init\"");
stat.execute("call ft_init()");
......@@ -102,19 +102,19 @@ public class TestFullText extends TestBase {
stat.execute("call ft_create_index('PUBLIC', 'TEST', 'NAME')");
if (!config.memory) {
conn.close();
conn.close();
}
conn = getConnection("fullTextNative", conns);
conn = getConnection("fullTextNative", connList);
stat = conn.createStatement();
stat.execute("insert into test select x, 'x' from system_range(1, 3000)");
close(conns);
close(connList);
}
private void testNativeFeatures() throws SQLException {
deleteDb("fullTextNative");
ArrayList<Connection> conns = new ArrayList<Connection>();
Connection conn = getConnection("fullTextNative", conns);
ArrayList<Connection> connList = new ArrayList<Connection>();
Connection conn = getConnection("fullTextNative", connList);
Statement stat = conn.createStatement();
stat.execute("CREATE ALIAS IF NOT EXISTS FT_INIT FOR \"org.h2.fulltext.FullText.init\"");
stat.execute("CALL FT_INIT()");
......@@ -149,9 +149,9 @@ public class TestFullText extends TestBase {
assertFalse(rs.next());
if (!config.memory) {
conn.close();
conn.close();
}
conn = getConnection("fullTextNative", conns);
conn = getConnection("fullTextNative", connList);
stat = conn.createStatement();
conn.setAutoCommit(false);
stat.execute("delete from test");
......@@ -161,14 +161,14 @@ public class TestFullText extends TestBase {
rs = stat.executeQuery("SELECT * FROM FT_SEARCH_DATA('Welcome', 0, 0)");
assertTrue(rs.next());
conn.setAutoCommit(true);
close(conns);
close(connList);
}
private void testUuidPrimaryKey(boolean lucene) throws SQLException {
deleteDb("fullText");
Connection conn = getConnection("fullText");
Statement stat = conn.createStatement();
String prefix = lucene ? "FTL" : "FT";
deleteDb("fullText");
Connection conn = getConnection("fullText");
Statement stat = conn.createStatement();
String prefix = lucene ? "FTL" : "FT";
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()");
......@@ -193,8 +193,8 @@ public class TestFullText extends TestBase {
String prefix = lucene ? "FTL" : "FT";
deleteDb("fullTextTransaction");
FileUtils.deleteRecursive(getBaseDir() + "/fullTextTransaction", false);
ArrayList<Connection> conns = new ArrayList<Connection>();
Connection conn = getConnection("fullTextTransaction", conns);
ArrayList<Connection> connList = new ArrayList<Connection>();
Connection conn = getConnection("fullTextTransaction", connList);
Statement stat = conn.createStatement();
String className = lucene ? "FullTextLucene" : "FullText";
stat.execute("CREATE ALIAS IF NOT EXISTS " + prefix + "_INIT FOR \"org.h2.fulltext." + className + ".init\"");
......@@ -210,16 +210,16 @@ public class TestFullText extends TestBase {
stat.execute("insert into test values(2, 'Hello Moon!')");
conn.rollback();
if (!config.memory) {
conn.close();
conn.close();
}
conn = getConnection("fullTextTransaction", conns);
conn = getConnection("fullTextTransaction", connList);
stat = conn.createStatement();
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);
close(conns);
close(connList);
deleteDb("fullTextTransaction");
FileUtils.deleteRecursive(getBaseDir() + "/fullTextTransaction", false);
}
......@@ -228,13 +228,13 @@ public class TestFullText extends TestBase {
final String prefix = lucene ? "FTL" : "FT";
trace("Testing multithreaded " + prefix);
deleteDb("fullText");
ArrayList<Connection> conns = new ArrayList<Connection>();
ArrayList<Connection> connList = new ArrayList<Connection>();
int len = 2;
Task[] task = new Task[len];
for (int i = 0; i < len; i++) {
// final Connection conn =
// getConnection("fullText;MULTI_THREADED=1;LOCK_TIMEOUT=10000");
final Connection conn = getConnection("fullText", conns);
final Connection conn = getConnection("fullText", connList);
Statement stat = conn.createStatement();
String className = lucene ? "FullTextLucene" : "FullText";
stat.execute("CREATE ALIAS IF NOT EXISTS " + prefix + "_INIT FOR \"org.h2.fulltext." + className + ".init\"");
......@@ -271,7 +271,7 @@ public class TestFullText extends TestBase {
}
trace("closing connection");
if (!config.memory) {
conn.close();
conn.close();
}
trace("completed thread " + Thread.currentThread());
}
......@@ -289,7 +289,7 @@ public class TestFullText extends TestBase {
t.get();
trace("done joining " + t);
}
close(conns);
close(connList);
}
private void testStreamLob() throws SQLException {
......@@ -347,8 +347,8 @@ public class TestFullText extends TestBase {
}
private void testReopen(boolean lucene) throws SQLException {
if (config.memory) {
return;
if (config.memory) {
return;
}
String prefix = lucene ? "FTL" : "FT";
deleteDb("fullTextReopen");
......@@ -427,8 +427,8 @@ public class TestFullText extends TestBase {
return;
}
deleteDb("fullText");
ArrayList<Connection> conns = new ArrayList<Connection>();
Connection conn = getConnection("fullText", conns);
ArrayList<Connection> connList = new ArrayList<Connection>();
Connection conn = getConnection("fullText", connList);
String prefix = lucene ? "FTL_" : "FT_";
Statement stat = conn.createStatement();
String className = lucene ? "FullTextLucene" : "FullText";
......@@ -512,15 +512,15 @@ public class TestFullText extends TestBase {
}
if (!config.memory) {
conn.close();
conn.close();
}
conn = getConnection("fullText", conns);
conn = getConnection("fullText", connList);
stat = conn.createStatement();
stat.executeQuery("SELECT * FROM " + prefix + "SEARCH('World', 0, 0)");
stat.execute("CALL " + prefix + "DROP_ALL()");
close(conns);
close(connList);
}
}
......@@ -46,6 +46,7 @@ public class TestPageStore extends TestBase implements DatabaseEventListener {
}
public void test() throws Exception {
testLogLimitFalsePositive();
testLogLimit();
testRecoverLobInDatabase();
testWriteTransactionLogBeforeData();
......@@ -105,6 +106,23 @@ public class TestPageStore extends TestBase implements DatabaseEventListener {
conn.close();
}
private void testLogLimitFalsePositive() throws Exception {
deleteDb("pageStore");
String url = "pageStore;TRACE_LEVEL_FILE=2";
Connection conn = getConnection(url);
Statement stat = conn.createStatement();
stat.execute("set max_log_size 1");
stat.execute("create table test(x varchar)");
for (int i = 0; i < 1000; ++i) {
stat.execute("insert into test values (space(2000))");
}
stat.execute("checkpoint");
InputStream in = FileUtils.newInputStream(getBaseDir() + "/pageStore.trace.db");
String s = IOUtils.readStringAndClose(new InputStreamReader(in), -1);
assertFalse(s.indexOf("Transaction log could not be truncated") > 0);
conn.close();
}
private void testRecoverLobInDatabase() throws SQLException {
deleteDb("pageStore");
String url = getURL("pageStore;MVCC=TRUE;CACHE_SIZE=1", true);
......
......@@ -25,6 +25,7 @@ public class H2Cursor extends AbstractWindowedCursor {
private ResultInterface result;
H2Cursor(H2Database db, H2CursorDriver driver, String editTable, H2Query query) {
this.database = db;
// TODO
}
......
......@@ -80,12 +80,6 @@ public class CheckJavadoc {
System.out.println("No Javadoc comment: " + file.getAbsolutePath());
errorCount++;
}
int open = text.indexOf('{');
if (open < 0 || open < comment) {
System.out.println("No '{' or '{' before the first Javadoc comment: " +
file.getAbsolutePath());
errorCount++;
}
int pos = 0;
int lineNumber = 1;
boolean inComment = false;
......
......@@ -701,4 +701,8 @@ hub rewind spawn shimizu fumiyuki nelson github laird rollover millions
ljnelson edugility sormula pushed backslashes slashes lukas batched typesafe
bundled jacob terrence policies periodic eases eder corporate regulatory
burden isnull periodically suse optimisation krenger qvortrup huang jmxremote
clusterable shortcut quota
\ No newline at end of file
clusterable shortcut quota wcslen flyway cacao tea memcpy someone iced
korea cpp raspberry inttypes korean hmac swprintf ptr agile rawtypes belgium
jia laurent midori stdc macros clocks xaltjvm teruo dylan debian counted
serializes semantics advances severe defensive maintaining collision
authenticating
......@@ -89,7 +89,7 @@ public class FilePathCache extends FilePathWrapper {
return len;
}
private long getCachePos(long pos) {
private static long getCachePos(long pos) {
return (pos / CACHE_BLOCK_SIZE) * CACHE_BLOCK_SIZE;
}
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论