Skip to content
项目
群组
代码片段
帮助
正在加载...
帮助
为 GitLab 提交贡献
登录/注册
切换导航
H
h2database
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
分枝图
比较
统计图
议题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
计划
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
分枝图
统计图
创建新议题
作业
提交
议题看板
打开侧边栏
Administrator
h2database
Commits
cde29719
提交
cde29719
authored
1月 30, 2009
作者:
Thomas Mueller
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Tomcat sets fields to null when unloading the web application.
上级
14664665
隐藏空白字符变更
内嵌
并排
正在显示
44 个修改的文件
包含
518 行增加
和
308 行删除
+518
-308
changelog.html
h2/src/docsrc/html/changelog.html
+3
-3
faq.html
h2/src/docsrc/html/faq.html
+10
-7
Parser.java
h2/src/main/org/h2/command/Parser.java
+3
-3
ScriptBase.java
h2/src/main/org/h2/command/dml/ScriptBase.java
+1
-1
ScriptCommand.java
h2/src/main/org/h2/command/dml/ScriptCommand.java
+10
-14
SetTypes.java
h2/src/main/org/h2/command/dml/SetTypes.java
+46
-51
Update.java
h2/src/main/org/h2/command/dml/Update.java
+1
-1
CompressLZF.java
h2/src/main/org/h2/compress/CompressLZF.java
+5
-4
SysProperties.java
h2/src/main/org/h2/constant/SysProperties.java
+21
-11
ConnectionInfo.java
h2/src/main/org/h2/engine/ConnectionInfo.java
+29
-25
Database.java
h2/src/main/org/h2/engine/Database.java
+0
-9
Engine.java
h2/src/main/org/h2/engine/Engine.java
+7
-8
MetaRecord.java
h2/src/main/org/h2/engine/MetaRecord.java
+12
-14
CompareLike.java
h2/src/main/org/h2/expression/CompareLike.java
+3
-3
Comparison.java
h2/src/main/org/h2/expression/Comparison.java
+3
-3
ConditionIn.java
h2/src/main/org/h2/expression/ConditionIn.java
+1
-1
ConditionNot.java
h2/src/main/org/h2/expression/ConditionNot.java
+1
-1
Function.java
h2/src/main/org/h2/expression/Function.java
+1
-1
ValueExpression.java
h2/src/main/org/h2/expression/ValueExpression.java
+22
-4
JdbcDataSourceFactory.java
h2/src/main/org/h2/jdbcx/JdbcDataSourceFactory.java
+8
-6
LogSystem.java
h2/src/main/org/h2/log/LogSystem.java
+5
-7
Message.java
h2/src/main/org/h2/message/Message.java
+5
-1
DiskFile.java
h2/src/main/org/h2/store/DiskFile.java
+11
-13
FileObjectMemory.java
h2/src/main/org/h2/store/fs/FileObjectMemory.java
+10
-7
FileSystemMemory.java
h2/src/main/org/h2/store/fs/FileSystemMemory.java
+19
-19
MetaTable.java
h2/src/main/org/h2/table/MetaTable.java
+3
-2
CompressTool.java
h2/src/main/org/h2/tools/CompressTool.java
+8
-8
MultiDimension.java
h2/src/main/org/h2/tools/MultiDimension.java
+2
-2
CacheObject.java
h2/src/main/org/h2/util/CacheObject.java
+12
-5
DateTimeUtils.java
h2/src/main/org/h2/util/DateTimeUtils.java
+14
-7
JdbcDriverUtils.java
h2/src/main/org/h2/util/JdbcDriverUtils.java
+0
-4
MemoryUtils.java
h2/src/main/org/h2/util/MemoryUtils.java
+0
-12
RandomUtils.java
h2/src/main/org/h2/util/RandomUtils.java
+30
-15
Resources.java
h2/src/main/org/h2/util/Resources.java
+0
-4
StringCache.java
h2/src/main/org/h2/util/StringCache.java
+0
-4
DataType.java
h2/src/main/org/h2/value/DataType.java
+17
-10
Value.java
h2/src/main/org/h2/value/Value.java
+4
-1
ValueBoolean.java
h2/src/main/org/h2/value/ValueBoolean.java
+7
-4
ValueDecimal.java
h2/src/main/org/h2/value/ValueDecimal.java
+4
-4
TestAll.java
h2/src/test/org/h2/test/TestAll.java
+5
-0
TestRandomSQL.java
h2/src/test/org/h2/test/synth/TestRandomSQL.java
+12
-9
supportTemplates.txt
h2/src/test/org/h2/test/todo/supportTemplates.txt
+1
-0
TestCache.java
h2/src/test/org/h2/test/unit/TestCache.java
+9
-0
TestClearReferences.java
h2/src/test/org/h2/test/unit/TestClearReferences.java
+153
-0
没有找到文件。
h2/src/docsrc/html/changelog.html
浏览文件 @
cde29719
...
...
@@ -24,11 +24,11 @@ Change Log
</li><li>
Connection.isValid is a bit faster.
</li><li>
H2 Console: The autocomplete feature has been improved a bit. It can now better
parse conditions.
</li><li>
When restarting a web application in Tomcat, an exception
i
s thrown sometimes.
In most cases this
is a NullPointerException
.
</li><li>
When restarting a web application in Tomcat, an exception
wa
s thrown sometimes.
In most cases this
was a NullPointerException. A workaround in H2 has been implemented
.
The root cause of the problem is now documented in the FAQ:
Tomcat sets all static fields (final or non-final) to null when unloading a web application.
A workaround is to set the system property
A workaround is to
put the h2.jar in the lib directory, or
set the system property
org.apache.catalina.loader.WebappClassLoader.ENABLE_CLEAR_REFERENCES
to false.
</li></ul>
...
...
h2/src/docsrc/html/faq.html
浏览文件 @
cde29719
...
...
@@ -46,17 +46,20 @@ Frequently Asked Questions
Usually, bugs get fixes as they are found. There is a release every few weeks.
Here is the list of known and confirmed issues:
</p>
<ul>
<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.
<ul><li>
Tomcat and Glassfish 3 sets all 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
to false, however Tomcat may then run out of memory. A known workaround is to
put the h2.jar file in the
<code>
lib
</code>
directory.
</li><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.
</li><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.
</li><li>
Tomcat sets all static fields (final or non-final) to null when unloading a web application.
This can cause a NullPointerException in H2. In Tomcat >= 6.0 this behavior can be disabled
by setting the system property org.apache.catalina.loader.WebappClassLoader.ENABLE_CLEAR_REFERENCES
to false.
</li></ul>
<br
/><a
name=
"open_source"
></a>
...
...
h2/src/main/org/h2/command/Parser.java
浏览文件 @
cde29719
...
...
@@ -659,7 +659,7 @@ public class Parser {
read
(
"="
);
Expression
expression
;
if
(
readIf
(
"DEFAULT"
))
{
expression
=
ValueExpression
.
DEFAULT
;
expression
=
ValueExpression
.
getDefault
()
;
}
else
{
expression
=
readExpression
();
}
...
...
@@ -2344,7 +2344,7 @@ public class Parser {
break
;
case
NULL:
read
();
r
=
ValueExpression
.
NULL
;
r
=
ValueExpression
.
getNull
()
;
break
;
case
VALUE:
r
=
ValueExpression
.
get
(
currentValue
);
...
...
@@ -2376,7 +2376,7 @@ public class Parser {
private
Expression
readWhen
(
Expression
left
)
throws
SQLException
{
if
(
readIf
(
"END"
))
{
readIf
(
"CASE"
);
return
ValueExpression
.
NULL
;
return
ValueExpression
.
getNull
()
;
}
if
(
readIf
(
"ELSE"
))
{
Expression
elsePart
=
readExpression
();
...
...
h2/src/main/org/h2/command/dml/ScriptBase.java
浏览文件 @
cde29719
...
...
@@ -87,7 +87,7 @@ public abstract class ScriptBase extends Prepared implements DataHandler {
if
(
fileName
==
null
||
fileName
.
trim
().
length
()
==
0
)
{
fileName
=
"script.sql"
;
}
fileName
=
SysProperties
.
scriptDirectory
+
fileName
;
fileName
=
SysProperties
.
getScriptDirectory
()
+
fileName
;
}
return
fileName
;
}
...
...
h2/src/main/org/h2/command/dml/ScriptCommand.java
浏览文件 @
cde29719
/*
* Copyright 2004-2009 H2 Group. Multiple-Licensed under the H2 License,
* Version 1.0, and under the Eclipse Public License, Version 1.0
* (http://h2database.com/html/license.html).
* Initial Developer: H2 Group
* Copyright 2004-2009 H2 Group. Multiple-Licensed under the H2 License, Version
* 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
;
...
...
@@ -16,7 +15,6 @@ import java.sql.PreparedStatement;
import
java.sql.ResultSet
;
import
java.sql.SQLException
;
import
java.util.Comparator
;
import
org.h2.command.Parser
;
import
org.h2.constant.SysProperties
;
import
org.h2.constraint.Constraint
;
...
...
@@ -61,14 +59,6 @@ import org.h2.value.ValueString;
*/
public
class
ScriptCommand
extends
ScriptBase
{
private
static
final
Comparator
TABLE_COMPARATOR
=
new
Comparator
()
{
public
int
compare
(
Object
o1
,
Object
o2
)
{
Table
t1
=
(
Table
)
o1
;
Table
t2
=
(
Table
)
o2
;
return
t1
.
getId
()
-
t2
.
getId
();
}
};
private
boolean
passwords
;
private
boolean
data
;
private
boolean
settings
;
...
...
@@ -196,7 +186,13 @@ public class ScriptCommand extends ScriptBase {
ObjectArray
tables
=
db
.
getAllSchemaObjects
(
DbObject
.
TABLE_OR_VIEW
);
// sort by id, so that views are after tables and views on views
// after the base views
tables
.
sort
(
TABLE_COMPARATOR
);
tables
.
sort
(
new
Comparator
()
{
public
int
compare
(
Object
o1
,
Object
o2
)
{
Table
t1
=
(
Table
)
o1
;
Table
t2
=
(
Table
)
o2
;
return
t1
.
getId
()
-
t2
.
getId
();
}
});
for
(
int
i
=
0
;
i
<
tables
.
size
();
i
++)
{
Table
table
=
(
Table
)
tables
.
get
(
i
);
table
.
lock
(
session
,
false
,
false
);
...
...
h2/src/main/org/h2/command/dml/SetTypes.java
浏览文件 @
cde29719
...
...
@@ -6,7 +6,7 @@
*/
package
org
.
h2
.
command
.
dml
;
import
org.h2.util.ObjectArray
;
import
java.util.ArrayList
;
/**
* The list of setting for a SET statement.
...
...
@@ -193,56 +193,51 @@ public class SetTypes {
*/
public
static
final
int
QUERY_TIMEOUT
=
36
;
private
static
ObjectArray
types
=
new
ObjectArray
();
static
{
setType
(
IGNORECASE
,
"IGNORECASE"
);
setType
(
MAX_LOG_SIZE
,
"MAX_LOG_SIZE"
);
setType
(
MODE
,
"MODE"
);
setType
(
READONLY
,
"READONLY"
);
setType
(
LOCK_TIMEOUT
,
"LOCK_TIMEOUT"
);
setType
(
DEFAULT_LOCK_TIMEOUT
,
"DEFAULT_LOCK_TIMEOUT"
);
setType
(
DEFAULT_TABLE_TYPE
,
"DEFAULT_TABLE_TYPE"
);
setType
(
CACHE_SIZE
,
"CACHE_SIZE"
);
setType
(
TRACE_LEVEL_SYSTEM_OUT
,
"TRACE_LEVEL_SYSTEM_OUT"
);
setType
(
TRACE_LEVEL_FILE
,
"TRACE_LEVEL_FILE"
);
setType
(
TRACE_MAX_FILE_SIZE
,
"TRACE_MAX_FILE_SIZE"
);
setType
(
COLLATION
,
"COLLATION"
);
setType
(
CLUSTER
,
"CLUSTER"
);
setType
(
WRITE_DELAY
,
"WRITE_DELAY"
);
setType
(
DATABASE_EVENT_LISTENER
,
"DATABASE_EVENT_LISTENER"
);
setType
(
MAX_MEMORY_ROWS
,
"MAX_MEMORY_ROWS"
);
setType
(
LOCK_MODE
,
"LOCK_MODE"
);
setType
(
DB_CLOSE_DELAY
,
"DB_CLOSE_DELAY"
);
setType
(
LOG
,
"LOG"
);
setType
(
THROTTLE
,
"THROTTLE"
);
setType
(
MAX_MEMORY_UNDO
,
"MAX_MEMORY_UNDO"
);
setType
(
MAX_LENGTH_INPLACE_LOB
,
"MAX_LENGTH_INPLACE_LOB"
);
setType
(
COMPRESS_LOB
,
"COMPRESS_LOB"
);
setType
(
ALLOW_LITERALS
,
"ALLOW_LITERALS"
);
setType
(
MULTI_THREADED
,
"MULTI_THREADED"
);
setType
(
SCHEMA
,
"SCHEMA"
);
setType
(
OPTIMIZE_REUSE_RESULTS
,
"OPTIMIZE_REUSE_RESULTS"
);
setType
(
SCHEMA_SEARCH_PATH
,
"SCHEMA_SEARCH_PATH"
);
setType
(
UNDO_LOG
,
"UNDO_LOG"
);
setType
(
REFERENTIAL_INTEGRITY
,
"REFERENTIAL_INTEGRITY"
);
setType
(
MVCC
,
"MVCC"
);
setType
(
MAX_OPERATION_MEMORY
,
"MAX_OPERATION_MEMORY"
);
setType
(
EXCLUSIVE
,
"EXCLUSIVE"
);
setType
(
CREATE_BUILD
,
"CREATE_BUILD"
);
setType
(
VARIABLE
,
"@"
);
setType
(
QUERY_TIMEOUT
,
"QUERY_TIMEOUT"
);
}
private
static
final
ArrayList
TYPES
=
new
ArrayList
();
private
SetTypes
()
{
// utility class
}
private
static
void
setType
(
int
type
,
String
name
)
{
while
(
types
.
size
()
<=
type
)
{
types
.
add
(
null
);
}
types
.
set
(
type
,
name
);
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"
);
}
/**
...
...
@@ -252,16 +247,16 @@ public class SetTypes {
* @return the number
*/
public
static
int
getType
(
String
name
)
{
for
(
int
i
=
0
;
i
<
types
.
size
();
i
++)
{
if
(
name
.
equals
(
types
.
get
(
i
)))
{
for
(
int
i
=
0
;
i
<
getTypes
()
.
size
();
i
++)
{
if
(
name
.
equals
(
getTypes
()
.
get
(
i
)))
{
return
i
;
}
}
return
-
1
;
}
public
static
ObjectArray
getSetting
s
()
{
return
types
;
public
static
ArrayList
getType
s
()
{
return
TYPES
;
}
/**
...
...
@@ -271,7 +266,7 @@ public class SetTypes {
* @return the name
*/
public
static
String
getTypeName
(
int
type
)
{
return
(
String
)
types
.
get
(
type
);
return
(
String
)
getTypes
()
.
get
(
type
);
}
}
h2/src/main/org/h2/command/dml/Update.java
浏览文件 @
cde29719
...
...
@@ -94,7 +94,7 @@ public class Update extends Prepared {
Value
newValue
;
if
(
newExpr
==
null
)
{
newValue
=
oldRow
.
getValue
(
i
);
}
else
if
(
newExpr
==
ValueExpression
.
DEFAULT
)
{
}
else
if
(
newExpr
==
ValueExpression
.
getDefault
()
)
{
Column
column
=
table
.
getColumn
(
i
);
Expression
defaultExpr
=
column
.
getDefaultExpression
();
Value
v
;
...
...
h2/src/main/org/h2/compress/CompressLZF.java
浏览文件 @
cde29719
...
...
@@ -45,7 +45,7 @@ public class CompressLZF implements Compressor {
private
static
final
int
MAX_OFF
=
1
<<
13
;
private
static
final
int
MAX_REF
=
(
1
<<
8
)
+
(
1
<<
3
);
private
int
[]
hashTab
;
private
int
[]
cachedHashTable
;
public
void
setOptions
(
String
options
)
{
// nothing to do
...
...
@@ -70,11 +70,12 @@ public class CompressLZF implements Compressor {
public
int
compress
(
byte
[]
in
,
int
inLen
,
byte
[]
out
,
int
outPos
)
{
int
inPos
=
0
;
if
(
hashTab
==
null
)
{
hashTab
=
new
int
[
HASH_SIZE
];
if
(
cachedHashTable
==
null
)
{
cachedHashTable
=
new
int
[
HASH_SIZE
];
}
else
{
System
.
arraycopy
(
EMPTY
,
0
,
hashTab
,
0
,
HASH_SIZE
);
System
.
arraycopy
(
EMPTY
,
0
,
cachedHashTable
,
0
,
HASH_SIZE
);
}
int
[]
hashTab
=
cachedHashTable
;
int
literals
=
0
;
int
hash
=
first
(
in
,
inPos
);
while
(
true
)
{
...
...
h2/src/main/org/h2/constant/SysProperties.java
浏览文件 @
cde29719
...
...
@@ -492,14 +492,6 @@ public class SysProperties {
*/
public
static
boolean
runFinalize
=
getBooleanSetting
(
"h2.runFinalize"
,
true
);
/**
* System property <code>h2.scriptDirectory</code> (default: empty
* string).<br />
* Relative or absolute directory where the script files are stored to or
* read from.
*/
public
static
String
scriptDirectory
=
getStringSetting
(
"h2.scriptDirectory"
,
""
);
/**
* System property <code>h2.serverCachedObjects</code> (default: 64).<br />
* TCP Server: number of cached objects per session.
...
...
@@ -566,7 +558,7 @@ public class SysProperties {
*/
public
static
final
int
COLLATOR_CACHE_SIZE
=
getCollatorCacheSize
();
private
static
String
baseDir
=
getStringSetting
(
"h2.baseDir"
,
null
)
;
private
static
final
String
H2_BASE_DIR
=
"h2.baseDir"
;
private
SysProperties
()
{
// utility class
...
...
@@ -623,14 +615,32 @@ public class SysProperties {
if
(!
dir
.
endsWith
(
"/"
))
{
dir
+=
"/"
;
}
baseDir
=
dir
;
System
.
setProperty
(
H2_BASE_DIR
,
dir
)
;
}
/**
* INTERNAL
*/
public
static
String
getBaseDir
()
{
return
baseDir
;
return
getStringSetting
(
H2_BASE_DIR
,
null
);
}
/**
* INTERNAL
* System property <code>h2.scriptDirectory</code> (default: empty
* string).<br />
* Relative or absolute directory where the script files are stored to or
* read from.
*/
public
static
String
getScriptDirectory
()
{
return
getStringSetting
(
"h2.scriptDirectory"
,
""
);
}
/**
* INTERNAL
*/
public
static
void
setScriptDirectory
(
String
dir
)
{
System
.
setProperty
(
"h2.scriptDirectory"
,
dir
);
}
/**
...
...
h2/src/main/org/h2/engine/ConnectionInfo.java
浏览文件 @
cde29719
...
...
@@ -7,10 +7,10 @@
package
org
.
h2
.
engine
;
import
java.sql.SQLException
;
import
java.util.ArrayList
;
import
java.util.Arrays
;
import
java.util.HashSet
;
import
java.util.Properties
;
import
org.h2.api.DatabaseEventListener
;
import
org.h2.command.dml.SetTypes
;
import
org.h2.constant.ErrorCode
;
...
...
@@ -20,7 +20,6 @@ import org.h2.security.SHA256;
import
org.h2.util.ByteUtils
;
import
org.h2.util.FileUtils
;
import
org.h2.util.MathUtils
;
import
org.h2.util.ObjectArray
;
import
org.h2.util.StringUtils
;
/**
...
...
@@ -44,25 +43,6 @@ public class ConnectionInfo implements Cloneable {
private
boolean
persistent
;
private
boolean
unnamed
;
static
{
ObjectArray
list
=
SetTypes
.
getSettings
();
for
(
int
i
=
0
;
i
<
list
.
size
();
i
++)
{
KNOWN_SETTINGS
.
add
(
list
.
get
(
i
));
}
// TODO document these settings
String
[]
connectionTime
=
new
String
[]
{
"ACCESS_MODE_LOG"
,
"ACCESS_MODE_DATA"
,
"AUTOCOMMIT"
,
"CIPHER"
,
"CREATE"
,
"CACHE_TYPE"
,
"DB_CLOSE_ON_EXIT"
,
"FILE_LOCK"
,
"IGNORE_UNKNOWN_SETTINGS"
,
"IFEXISTS"
,
"PASSWORD"
,
"RECOVER"
,
"USER"
,
"DATABASE_EVENT_LISTENER_OBJECT"
,
"AUTO_SERVER"
,
"AUTO_RECONNECT"
,
"OPEN_NEW"
};
for
(
int
i
=
0
;
i
<
connectionTime
.
length
;
i
++)
{
String
key
=
connectionTime
[
i
];
if
(
SysProperties
.
CHECK
&&
KNOWN_SETTINGS
.
contains
(
key
))
{
Message
.
throwInternalError
(
key
);
}
KNOWN_SETTINGS
.
add
(
key
);
}
}
/**
* Create a connection info object.
*
...
...
@@ -93,6 +73,30 @@ public class ConnectionInfo implements Cloneable {
parseName
();
}
static
{
ArrayList
list
=
SetTypes
.
getTypes
();
HashSet
set
=
KNOWN_SETTINGS
;
for
(
int
i
=
0
;
i
<
list
.
size
();
i
++)
{
set
.
add
(
list
.
get
(
i
));
}
// TODO document these settings
String
[]
connectionTime
=
new
String
[]
{
"ACCESS_MODE_LOG"
,
"ACCESS_MODE_DATA"
,
"AUTOCOMMIT"
,
"CIPHER"
,
"CREATE"
,
"CACHE_TYPE"
,
"DB_CLOSE_ON_EXIT"
,
"FILE_LOCK"
,
"IGNORE_UNKNOWN_SETTINGS"
,
"IFEXISTS"
,
"PASSWORD"
,
"RECOVER"
,
"USER"
,
"DATABASE_EVENT_LISTENER_OBJECT"
,
"AUTO_SERVER"
,
"AUTO_RECONNECT"
,
"OPEN_NEW"
};
for
(
int
i
=
0
;
i
<
connectionTime
.
length
;
i
++)
{
String
key
=
connectionTime
[
i
];
if
(
SysProperties
.
CHECK
&&
set
.
contains
(
key
))
{
Message
.
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
();
...
...
@@ -174,7 +178,7 @@ public class ConnectionInfo implements Cloneable {
if
(
prop
.
containsKey
(
key
))
{
throw
Message
.
getSQLException
(
ErrorCode
.
DUPLICATE_PROPERTY_1
,
key
);
}
if
(
KNOWN_SETTINGS
.
contains
(
key
))
{
if
(
isKnownSetting
(
key
))
{
prop
.
put
(
key
,
info
.
get
(
list
[
i
]));
}
}
...
...
@@ -195,7 +199,7 @@ public class ConnectionInfo implements Cloneable {
String
value
=
setting
.
substring
(
equal
+
1
);
String
key
=
setting
.
substring
(
0
,
equal
);
key
=
StringUtils
.
toUpperEnglish
(
key
);
if
(!
KNOWN_SETTINGS
.
contains
(
key
))
{
if
(!
isKnownSetting
(
key
))
{
throw
Message
.
getSQLException
(
ErrorCode
.
UNSUPPORTED_SETTING_1
,
key
);
}
String
old
=
prop
.
getProperty
(
key
);
...
...
@@ -293,7 +297,7 @@ public class ConnectionInfo implements Cloneable {
* @return the value
*/
String
removeProperty
(
String
key
,
String
defaultValue
)
{
if
(
SysProperties
.
CHECK
&&
!
KNOWN_SETTINGS
.
contains
(
key
))
{
if
(
SysProperties
.
CHECK
&&
!
isKnownSetting
(
key
))
{
Message
.
throwInternalError
(
key
);
}
Object
x
=
prop
.
remove
(
key
);
...
...
@@ -378,7 +382,7 @@ public class ConnectionInfo implements Cloneable {
* @return the value as a String
*/
public
String
getProperty
(
String
key
,
String
defaultValue
)
{
if
(
SysProperties
.
CHECK
&&
!
KNOWN_SETTINGS
.
contains
(
key
))
{
if
(
SysProperties
.
CHECK
&&
!
isKnownSetting
(
key
))
{
Message
.
throwInternalError
(
key
);
}
String
s
=
getProperty
(
key
);
...
...
h2/src/main/org/h2/engine/Database.java
浏览文件 @
cde29719
...
...
@@ -60,7 +60,6 @@ import org.h2.util.CacheLRU;
import
org.h2.util.ClassUtils
;
import
org.h2.util.FileUtils
;
import
org.h2.util.IntHashMap
;
import
org.h2.util.MemoryUtils
;
import
org.h2.util.NetUtils
;
import
org.h2.util.ObjectArray
;
import
org.h2.util.SmallLRUCache
;
...
...
@@ -1007,14 +1006,6 @@ public class Database implements DataHandler {
if
(
closing
)
{
return
;
}
if
(
MemoryUtils
.
isShutdown
())
{
try
{
traceSystem
.
getTrace
(
Trace
.
DATABASE
).
error
(
"already shut down"
);
}
catch
(
Exception
e
)
{
// ignore
}
return
;
}
closing
=
true
;
stopServer
();
if
(
userSessions
.
size
()
>
0
)
{
...
...
h2/src/main/org/h2/engine/Engine.java
浏览文件 @
cde29719
...
...
@@ -27,9 +27,8 @@ import org.h2.util.StringUtils;
public
class
Engine
{
private
static
final
Engine
INSTANCE
=
new
Engine
();
private
static
final
HashMap
DATABASES
=
new
HashMap
();
private
static
volatile
long
wrongPasswordDelay
=
SysProperties
.
DELAY_WRONG_PASSWORD_MIN
;
private
static
Object
wrongPasswordSync
=
new
Object
();
private
final
HashMap
databases
=
new
HashMap
();
private
Engine
()
{
// don't allow others to instantiate
...
...
@@ -46,7 +45,7 @@ public class Engine {
if
(
openNew
||
ci
.
isUnnamedInMemory
())
{
database
=
null
;
}
else
{
database
=
(
Database
)
databases
.
get
(
name
);
database
=
(
Database
)
DATABASES
.
get
(
name
);
}
User
user
=
null
;
boolean
opened
=
false
;
...
...
@@ -65,7 +64,7 @@ public class Engine {
database
.
setMasterUser
(
user
);
}
if
(!
ci
.
isUnnamedInMemory
())
{
databases
.
put
(
name
,
database
);
DATABASES
.
put
(
name
,
database
);
}
database
.
opened
();
}
...
...
@@ -182,7 +181,7 @@ public class Engine {
* @param name the database name
*/
public
void
close
(
String
name
)
{
databases
.
remove
(
name
);
DATABASES
.
remove
(
name
);
}
/**
...
...
@@ -208,10 +207,10 @@ public class Engine {
if
(
delay
>
min
&&
delay
>
0
)
{
// the first correct password must be blocked,
// otherwise parallel attacks are possible
synchronized
(
wrongPasswordSync
)
{
synchronized
(
INSTANCE
)
{
// delay up to the last delay
// an attacker can't know how long it will be
delay
=
RandomUtils
.
nextInt
((
int
)
delay
);
delay
=
RandomUtils
.
next
Secure
Int
((
int
)
delay
);
try
{
Thread
.
sleep
(
delay
);
}
catch
(
InterruptedException
e
)
{
...
...
@@ -223,7 +222,7 @@ public class Engine {
}
else
{
// this method is not synchronized on the Engine, so that
// regular successful attempts are not blocked
synchronized
(
wrongPasswordSync
)
{
synchronized
(
INSTANCE
)
{
long
delay
=
wrongPasswordDelay
;
int
max
=
SysProperties
.
DELAY_WRONG_PASSWORD_MAX
;
if
(
max
<=
0
)
{
...
...
h2/src/main/org/h2/engine/MetaRecord.java
浏览文件 @
cde29719
...
...
@@ -24,19 +24,6 @@ import org.h2.value.ValueString;
*/
public
class
MetaRecord
{
private
static
final
Comparator
META_RECORD_COMPARATOR
=
new
Comparator
()
{
public
int
compare
(
Object
o1
,
Object
o2
)
{
MetaRecord
m1
=
(
MetaRecord
)
o1
;
MetaRecord
m2
=
(
MetaRecord
)
o2
;
int
c1
=
DbObjectBase
.
getCreateOrder
(
m1
.
getObjectType
());
int
c2
=
DbObjectBase
.
getCreateOrder
(
m2
.
getObjectType
());
if
(
c1
!=
c2
)
{
return
c1
-
c2
;
}
return
m1
.
getId
()
-
m2
.
getId
();
}
};
private
int
id
;
private
int
objectType
;
private
int
headPos
;
...
...
@@ -62,7 +49,18 @@ public class MetaRecord {
* @param records the list of meta records
*/
public
static
void
sort
(
ObjectArray
records
)
{
records
.
sort
(
META_RECORD_COMPARATOR
);
records
.
sort
(
new
Comparator
()
{
public
int
compare
(
Object
o1
,
Object
o2
)
{
MetaRecord
m1
=
(
MetaRecord
)
o1
;
MetaRecord
m2
=
(
MetaRecord
)
o2
;
int
c1
=
DbObjectBase
.
getCreateOrder
(
m1
.
getObjectType
());
int
c2
=
DbObjectBase
.
getCreateOrder
(
m2
.
getObjectType
());
if
(
c1
!=
c2
)
{
return
c1
-
c2
;
}
return
m1
.
getId
()
-
m2
.
getId
();
}
});
}
void
setRecord
(
SearchRow
r
)
{
...
...
h2/src/main/org/h2/expression/CompareLike.java
浏览文件 @
cde29719
...
...
@@ -76,7 +76,7 @@ public class CompareLike extends Condition {
Value
l
=
left
.
getValue
(
session
);
if
(
l
==
ValueNull
.
INSTANCE
)
{
// NULL LIKE something > NULL
return
ValueExpression
.
NULL
;
return
ValueExpression
.
getNull
()
;
}
}
if
(
escape
!=
null
)
{
...
...
@@ -89,11 +89,11 @@ public class CompareLike extends Condition {
Value
r
=
right
.
getValue
(
session
);
if
(
r
==
ValueNull
.
INSTANCE
)
{
// something LIKE NULL > NULL
return
ValueExpression
.
NULL
;
return
ValueExpression
.
getNull
()
;
}
Value
e
=
escape
==
null
?
null
:
escape
.
getValue
(
session
);
if
(
e
==
ValueNull
.
INSTANCE
)
{
return
ValueExpression
.
NULL
;
return
ValueExpression
.
getNull
()
;
}
String
p
=
r
.
getString
();
initPattern
(
p
,
getEscapeChar
(
e
));
...
...
h2/src/main/org/h2/expression/Comparison.java
浏览文件 @
cde29719
...
...
@@ -119,7 +119,7 @@ public class Comparison extends Condition {
private
Expression
getCast
(
Expression
expr
,
int
dataType
,
long
precision
,
int
scale
,
int
displaySize
,
Session
session
)
throws
SQLException
{
if
(
expr
==
ValueExpression
.
NULL
)
{
if
(
expr
==
ValueExpression
.
getNull
()
)
{
return
expr
;
}
Function
function
=
Function
.
getFunction
(
session
.
getDatabase
(),
"CAST"
);
...
...
@@ -186,10 +186,10 @@ public class Comparison extends Condition {
if
(
SysProperties
.
CHECK
&&
(
left
==
null
||
right
==
null
))
{
Message
.
throwInternalError
();
}
if
(
left
==
ValueExpression
.
NULL
||
right
==
ValueExpression
.
NULL
)
{
if
(
left
==
ValueExpression
.
getNull
()
||
right
==
ValueExpression
.
getNull
()
)
{
// TODO NULL handling: maybe issue a warning when comparing with
// a NULL constants
return
ValueExpression
.
NULL
;
return
ValueExpression
.
getNull
()
;
}
if
(
left
.
isConstant
()
&&
right
.
isConstant
())
{
return
ValueExpression
.
get
(
getValue
(
session
));
...
...
h2/src/main/org/h2/expression/ConditionIn.java
浏览文件 @
cde29719
...
...
@@ -85,7 +85,7 @@ public class ConditionIn extends Condition {
}
left
=
left
.
optimize
(
session
);
boolean
constant
=
left
.
isConstant
();
if
(
constant
&&
left
==
ValueExpression
.
NULL
)
{
if
(
constant
&&
left
==
ValueExpression
.
getNull
()
)
{
return
left
;
}
boolean
allValuesConstant
=
true
;
...
...
h2/src/main/org/h2/expression/ConditionNot.java
浏览文件 @
cde29719
...
...
@@ -55,7 +55,7 @@ public class ConditionNot extends Condition {
if
(
expr
.
isConstant
())
{
Value
v
=
expr
.
getValue
(
session
);
if
(
v
==
ValueNull
.
INSTANCE
)
{
return
ValueExpression
.
NULL
;
return
ValueExpression
.
getNull
()
;
}
return
ValueExpression
.
get
(
v
.
convertTo
(
Value
.
BOOLEAN
).
negate
());
}
...
...
h2/src/main/org/h2/expression/Function.java
浏览文件 @
cde29719
...
...
@@ -1621,7 +1621,7 @@ public class Function extends Expression implements FunctionCall {
displaySize
=
0
;
for
(
int
i
=
0
;
i
<
args
.
length
;
i
++)
{
Expression
e
=
args
[
i
];
if
(
e
!=
ValueExpression
.
NULL
&&
e
.
getType
()
!=
Value
.
UNKNOWN
)
{
if
(
e
!=
ValueExpression
.
getNull
()
&&
e
.
getType
()
!=
Value
.
UNKNOWN
)
{
dataType
=
Value
.
getHigherOrder
(
dataType
,
e
.
getType
());
scale
=
Math
.
max
(
scale
,
e
.
getScale
());
precision
=
Math
.
max
(
precision
,
e
.
getPrecision
());
...
...
h2/src/main/org/h2/expression/ValueExpression.java
浏览文件 @
cde29719
...
...
@@ -22,21 +22,39 @@ public class ValueExpression extends Expression {
/**
* The expression represents ValueNull.INSTANCE.
*/
p
ublic
static
final
ValueExpression
NULL
=
new
ValueExpression
(
ValueNull
.
INSTANCE
);
p
rivate
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.
*/
p
ublic
static
final
ValueExpression
DEFAULT
=
new
ValueExpression
(
ValueNull
.
INSTANCE
);
p
rivate
static
final
Object
DEFAULT
=
new
ValueExpression
(
ValueNull
.
INSTANCE
);
private
Value
value
;
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.
*
...
...
@@ -45,7 +63,7 @@ public class ValueExpression extends Expression {
*/
public
static
ValueExpression
get
(
Value
value
)
{
if
(
value
==
ValueNull
.
INSTANCE
)
{
return
ValueExpression
.
NULL
;
return
getNull
()
;
}
return
new
ValueExpression
(
value
);
}
...
...
h2/src/main/org/h2/jdbcx/JdbcDataSourceFactory.java
浏览文件 @
cde29719
...
...
@@ -30,20 +30,18 @@ implements ObjectFactory
//## Java 1.4 end ##
{
private
static
TraceSystem
t
raceSystem
;
private
static
TraceSystem
cachedT
raceSystem
;
private
Trace
trace
;
static
{
org
.
h2
.
Driver
.
load
();
traceSystem
=
new
TraceSystem
(
SysProperties
.
CLIENT_TRACE_DIRECTORY
+
"h2datasource"
+
Constants
.
SUFFIX_TRACE_FILE
,
false
);
traceSystem
.
setLevelFile
(
SysProperties
.
DATASOURCE_TRACE_LEVEL
);
}
/**
* The public constructor to create new factory objects.
*/
public
JdbcDataSourceFactory
()
{
trace
=
traceSystem
.
getTrace
(
"JDBCX"
);
trace
=
getTraceSystem
()
.
getTrace
(
"JDBCX"
);
}
/**
...
...
@@ -77,8 +75,12 @@ implements ObjectFactory
}
//## Java 1.4 end ##
TraceSystem
getTraceSystem
()
{
return
traceSystem
;
private
TraceSystem
getTraceSystem
()
{
if
(
cachedTraceSystem
==
null
)
{
cachedTraceSystem
=
new
TraceSystem
(
SysProperties
.
CLIENT_TRACE_DIRECTORY
+
"h2datasource"
+
Constants
.
SUFFIX_TRACE_FILE
,
false
);
cachedTraceSystem
.
setLevelFile
(
SysProperties
.
DATASOURCE_TRACE_LEVEL
);
}
return
cachedTraceSystem
;
}
Trace
getTrace
()
{
...
...
h2/src/main/org/h2/log/LogSystem.java
浏览文件 @
cde29719
...
...
@@ -37,12 +37,6 @@ public class LogSystem {
*/
public
static
final
int
LOG_WRITTEN
=
-
1
;
private
static
final
Comparator
LOG_FILE_COMPARATOR
=
new
Comparator
()
{
public
int
compare
(
Object
a
,
Object
b
)
{
return
((
LogFile
)
a
).
getId
()
-
((
LogFile
)
b
).
getId
();
}
};
private
Database
database
;
private
ObjectArray
activeLogs
;
private
LogFile
currentLog
;
...
...
@@ -319,7 +313,11 @@ public class LogSystem {
}
}
}
activeLogs
.
sort
(
LOG_FILE_COMPARATOR
);
activeLogs
.
sort
(
new
Comparator
()
{
public
int
compare
(
Object
a
,
Object
b
)
{
return
((
LogFile
)
a
).
getId
()
-
((
LogFile
)
b
).
getId
();
}
});
if
(
activeLogs
.
size
()
==
0
)
{
LogFile
l
=
new
LogFile
(
this
,
0
,
fileNamePrefix
);
activeLogs
.
add
(
l
);
...
...
h2/src/main/org/h2/message/Message.java
浏览文件 @
cde29719
...
...
@@ -78,7 +78,11 @@ public class Message {
}
private
static
String
translate
(
String
key
,
String
[]
param
)
{
String
message
=
MESSAGES
.
getProperty
(
key
);
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)"
;
}
...
...
h2/src/main/org/h2/store/DiskFile.java
浏览文件 @
cde29719
...
...
@@ -80,18 +80,6 @@ public class DiskFile implements CacheWriter {
private
static
final
int
OFFSET
=
FileStore
.
HEADER_LENGTH
;
private
static
final
int
FREE_PAGE
=
-
1
;
private
static
final
Comparator
REDO_LOG_COMPARATOR
=
new
Comparator
()
{
public
int
compare
(
Object
o1
,
Object
o2
)
{
RedoLogRecord
e1
=
(
RedoLogRecord
)
o1
;
RedoLogRecord
e2
=
(
RedoLogRecord
)
o2
;
int
comp
=
e1
.
recordId
-
e2
.
recordId
;
if
(
comp
==
0
)
{
comp
=
e1
.
sequenceId
-
e2
.
sequenceId
;
}
return
comp
;
}
};
private
Database
database
;
private
String
fileName
;
private
FileStore
file
;
...
...
@@ -1203,7 +1191,17 @@ public class DiskFile implements CacheWriter {
if
(
redoBuffer
.
size
()
==
0
)
{
return
;
}
redoBuffer
.
sort
(
REDO_LOG_COMPARATOR
);
redoBuffer
.
sort
(
new
Comparator
()
{
public
int
compare
(
Object
o1
,
Object
o2
)
{
RedoLogRecord
e1
=
(
RedoLogRecord
)
o1
;
RedoLogRecord
e2
=
(
RedoLogRecord
)
o2
;
int
comp
=
e1
.
recordId
-
e2
.
recordId
;
if
(
comp
==
0
)
{
comp
=
e1
.
sequenceId
-
e2
.
sequenceId
;
}
return
comp
;
}
});
// first write all deleted entries
// because delete entries are always 1 block,
// while not-deleted entries can be many blocks
...
...
h2/src/main/org/h2/store/fs/FileObjectMemory.java
浏览文件 @
cde29719
...
...
@@ -25,7 +25,7 @@ public class FileObjectMemory implements FileObject {
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_BLOCK
;
private
static
byte
[]
cachedCompressedEmptyBlock
;
//## Java 1.4 begin ##
private
static
final
Cache
COMPRESS_LATER
=
new
Cache
(
CACHE_SIZE
);
...
...
@@ -137,11 +137,14 @@ public class FileObjectMemory implements FileObject {
}
}
static
{
byte
[]
n
=
new
byte
[
BLOCK_SIZE
];
int
len
=
LZF
.
compress
(
n
,
BLOCK_SIZE
,
BUFFER
,
0
);
COMPRESSED_BLOCK
=
new
byte
[
len
];
System
.
arraycopy
(
BUFFER
,
0
,
COMPRESSED_BLOCK
,
0
,
len
);
static
byte
[]
getCompressedEmptyBlock
()
{
if
(
cachedCompressedEmptyBlock
==
null
)
{
byte
[]
n
=
new
byte
[
BLOCK_SIZE
];
int
len
=
LZF
.
compress
(
n
,
BLOCK_SIZE
,
BUFFER
,
0
);
cachedCompressedEmptyBlock
=
new
byte
[
len
];
System
.
arraycopy
(
BUFFER
,
0
,
cachedCompressedEmptyBlock
,
0
,
len
);
}
return
cachedCompressedEmptyBlock
;
}
private
void
touch
()
{
...
...
@@ -186,7 +189,7 @@ public class FileObjectMemory implements FileObject {
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_BLOCK
;
n
[
i
]
=
getCompressedEmptyBlock
()
;
}
data
=
n
;
}
...
...
h2/src/main/org/h2/store/fs/FileSystemMemory.java
浏览文件 @
cde29719
...
...
@@ -25,7 +25,7 @@ import org.h2.util.RandomUtils;
public
class
FileSystemMemory
extends
FileSystem
{
private
static
final
FileSystemMemory
INSTANCE
=
new
FileSystemMemory
();
private
final
HashMap
memoryFiles
=
new
HashMap
();
private
static
final
HashMap
MEMORY_FILES
=
new
HashMap
();
private
FileSystemMemory
()
{
// don't allow construction
...
...
@@ -42,16 +42,16 @@ public class FileSystemMemory extends FileSystem {
public
void
rename
(
String
oldName
,
String
newName
)
{
oldName
=
normalize
(
oldName
);
newName
=
normalize
(
newName
);
synchronized
(
memoryFiles
)
{
synchronized
(
MEMORY_FILES
)
{
FileObjectMemory
f
=
getMemoryFile
(
oldName
);
f
.
setName
(
newName
);
memoryFiles
.
remove
(
oldName
);
memoryFiles
.
put
(
newName
,
f
);
MEMORY_FILES
.
remove
(
oldName
);
MEMORY_FILES
.
put
(
newName
,
f
);
}
}
public
boolean
createNewFile
(
String
fileName
)
{
synchronized
(
memoryFiles
)
{
synchronized
(
MEMORY_FILES
)
{
if
(
exists
(
fileName
))
{
return
false
;
}
...
...
@@ -62,29 +62,29 @@ public class FileSystemMemory extends FileSystem {
public
boolean
exists
(
String
fileName
)
{
fileName
=
normalize
(
fileName
);
synchronized
(
memoryFiles
)
{
return
memoryFiles
.
get
(
fileName
)
!=
null
;
synchronized
(
MEMORY_FILES
)
{
return
MEMORY_FILES
.
get
(
fileName
)
!=
null
;
}
}
public
void
delete
(
String
fileName
)
{
fileName
=
normalize
(
fileName
);
synchronized
(
memoryFiles
)
{
memoryFiles
.
remove
(
fileName
);
synchronized
(
MEMORY_FILES
)
{
MEMORY_FILES
.
remove
(
fileName
);
}
}
public
boolean
tryDelete
(
String
fileName
)
{
fileName
=
normalize
(
fileName
);
synchronized
(
memoryFiles
)
{
memoryFiles
.
remove
(
fileName
);
synchronized
(
MEMORY_FILES
)
{
MEMORY_FILES
.
remove
(
fileName
);
}
return
true
;
}
public
String
createTempFile
(
String
name
,
String
suffix
,
boolean
deleteOnExit
,
boolean
inTempDir
)
{
name
+=
"."
;
synchronized
(
memoryFiles
)
{
synchronized
(
MEMORY_FILES
)
{
for
(
int
i
=
0
;;
i
++)
{
String
n
=
name
+
(
RandomUtils
.
getSecureLong
()
>>>
1
)
+
suffix
;
if
(!
exists
(
n
))
{
...
...
@@ -97,8 +97,8 @@ public class FileSystemMemory extends FileSystem {
public
String
[]
listFiles
(
String
path
)
{
ObjectArray
list
=
new
ObjectArray
();
synchronized
(
memoryFiles
)
{
for
(
Iterator
it
=
memoryFiles
.
keySet
().
iterator
();
it
.
hasNext
();)
{
synchronized
(
MEMORY_FILES
)
{
for
(
Iterator
it
=
MEMORY_FILES
.
keySet
().
iterator
();
it
.
hasNext
();)
{
String
name
=
(
String
)
it
.
next
();
if
(
name
.
startsWith
(
path
))
{
list
.
add
(
name
);
...
...
@@ -112,8 +112,8 @@ public class FileSystemMemory extends FileSystem {
public
void
deleteRecursive
(
String
fileName
)
throws
SQLException
{
fileName
=
normalize
(
fileName
);
synchronized
(
memoryFiles
)
{
Iterator
it
=
memoryFiles
.
keySet
().
iterator
();
synchronized
(
MEMORY_FILES
)
{
Iterator
it
=
MEMORY_FILES
.
keySet
().
iterator
();
while
(
it
.
hasNext
())
{
String
name
=
(
String
)
it
.
next
();
if
(
name
.
startsWith
(
fileName
))
{
...
...
@@ -217,12 +217,12 @@ public class FileSystemMemory extends FileSystem {
private
FileObjectMemory
getMemoryFile
(
String
fileName
)
{
fileName
=
normalize
(
fileName
);
synchronized
(
memoryFiles
)
{
FileObjectMemory
m
=
(
FileObjectMemory
)
memoryFiles
.
get
(
fileName
);
synchronized
(
MEMORY_FILES
)
{
FileObjectMemory
m
=
(
FileObjectMemory
)
MEMORY_FILES
.
get
(
fileName
);
if
(
m
==
null
)
{
boolean
compress
=
fileName
.
startsWith
(
FileSystem
.
PREFIX_MEMORY_LZF
);
m
=
new
FileObjectMemory
(
fileName
,
compress
);
memoryFiles
.
put
(
fileName
,
m
);
MEMORY_FILES
.
put
(
fileName
,
m
);
}
return
m
;
}
...
...
h2/src/main/org/h2/table/MetaTable.java
浏览文件 @
cde29719
...
...
@@ -16,6 +16,7 @@ import java.sql.ResultSet;
import
java.sql.SQLException
;
import
java.sql.Timestamp
;
import
java.text.Collator
;
import
java.util.ArrayList
;
import
java.util.Locale
;
import
org.h2.command.Command
;
...
...
@@ -865,7 +866,7 @@ public class MetaTable extends Table {
add
(
rows
,
new
String
[]{
"h2.recompileAlways"
,
""
+
SysProperties
.
RECOMPILE_ALWAYS
});
add
(
rows
,
new
String
[]{
"h2.redoBufferSize"
,
""
+
SysProperties
.
REDO_BUFFER_SIZE
});
add
(
rows
,
new
String
[]{
"h2.runFinalize"
,
""
+
SysProperties
.
runFinalize
});
add
(
rows
,
new
String
[]{
"h2.scriptDirectory"
,
SysProperties
.
scriptDirectory
});
add
(
rows
,
new
String
[]{
"h2.scriptDirectory"
,
SysProperties
.
getScriptDirectory
()
});
add
(
rows
,
new
String
[]{
"h2.serverCachedObjects"
,
""
+
SysProperties
.
SERVER_CACHED_OBJECTS
});
add
(
rows
,
new
String
[]{
"h2.serverResultSetFetchSize"
,
""
+
SysProperties
.
SERVER_RESULT_SET_FETCH_SIZE
});
add
(
rows
,
new
String
[]{
"h2.sortNullsHigh"
,
""
+
SysProperties
.
SORT_NULLS_HIGH
});
...
...
@@ -887,7 +888,7 @@ public class MetaTable extends Table {
break
;
}
case
TYPE_INFO:
{
ObjectArray
types
=
DataType
.
getTypes
();
ArrayList
types
=
DataType
.
getTypes
();
for
(
int
i
=
0
;
i
<
types
.
size
();
i
++)
{
DataType
t
=
(
DataType
)
types
.
get
(
i
);
if
(
t
.
hidden
||
t
.
sqlType
==
Value
.
NULL
)
{
...
...
h2/src/main/org/h2/tools/CompressTool.java
浏览文件 @
cde29719
...
...
@@ -34,22 +34,22 @@ import org.h2.util.StringUtils;
*/
public
class
CompressTool
{
private
static
CompressTool
instance
=
new
CompressTool
();
private
static
byte
[]
buffer
;
private
static
final
int
MAX_BUFFER_SIZE
=
64
*
1024
*
1024
;
private
static
final
CompressTool
INSTANCE
=
new
CompressTool
();
private
static
final
int
MAX_BUFFER_SIZE
=
64
*
1024
;
private
byte
[]
cachedBuffer
;
private
CompressTool
()
{
// don't allow construction
}
private
static
byte
[]
getBuffer
(
int
min
)
{
private
byte
[]
getBuffer
(
int
min
)
{
if
(
min
>
MAX_BUFFER_SIZE
)
{
return
ByteUtils
.
newBytes
(
min
);
}
if
(
buffer
==
null
||
b
uffer
.
length
<
min
)
{
b
uffer
=
ByteUtils
.
newBytes
(
min
);
if
(
cachedBuffer
==
null
||
cachedB
uffer
.
length
<
min
)
{
cachedB
uffer
=
ByteUtils
.
newBytes
(
min
);
}
return
b
uffer
;
return
cachedB
uffer
;
}
/**
...
...
@@ -58,7 +58,7 @@ public class CompressTool {
* @return the singleton
*/
public
static
CompressTool
getInstance
()
{
return
instance
;
return
INSTANCE
;
}
/**
...
...
h2/src/main/org/h2/tools/MultiDimension.java
浏览文件 @
cde29719
...
...
@@ -23,7 +23,7 @@ import org.h2.util.StringUtils;
*/
public
class
MultiDimension
{
private
static
MultiDimension
instance
=
new
MultiDimension
();
private
static
final
MultiDimension
INSTANCE
=
new
MultiDimension
();
private
MultiDimension
()
{
// don't allow construction
...
...
@@ -35,7 +35,7 @@ public class MultiDimension {
* @return the singleton
*/
public
static
MultiDimension
getInstance
()
{
return
instance
;
return
INSTANCE
;
}
/**
...
...
h2/src/main/org/h2/util/CacheObject.java
浏览文件 @
cde29719
...
...
@@ -18,11 +18,9 @@ import org.h2.store.DiskFile;
public
abstract
class
CacheObject
{
/**
* Ensure the class is loaded when initialized, so that sorting is possible
* even when loading new classes is not allowed any more. This can occur
* when stopping a web application.
* Compare cache objects by position.
*/
private
static
final
Comparator
CACHE_COMPARATOR
=
new
Comparator
()
{
private
static
class
CacheComparator
implements
Comparator
{
public
int
compare
(
Object
a
,
Object
b
)
{
int
pa
=
((
CacheObject
)
a
).
getPos
();
int
pb
=
((
CacheObject
)
b
).
getPos
();
...
...
@@ -30,6 +28,15 @@ public abstract class CacheObject {
}
};
/**
* Ensure the class is loaded when initialized, so that sorting is possible
* even when loading new classes is not allowed any more. This can occur
* when stopping a web application.
*/
static
{
new
CacheComparator
();
}
/**
* The previous element in the LRU linked list. If the previous element is
* the head, then this element is the most recently used object.
...
...
@@ -75,7 +82,7 @@ public abstract class CacheObject {
* @param recordList the list of cache objects
*/
public
static
void
sort
(
ObjectArray
recordList
)
{
recordList
.
sort
(
CACHE_COMPARATOR
);
recordList
.
sort
(
new
CacheComparator
()
);
}
public
void
setBlockCount
(
int
size
)
{
...
...
h2/src/main/org/h2/util/DateTimeUtils.java
浏览文件 @
cde29719
...
...
@@ -30,7 +30,7 @@ public class DateTimeUtils {
private
static
final
int
DEFAULT_DAY
=
1
;
private
static
final
int
DEFAULT_HOUR
=
0
;
private
static
Calendar
calendar
=
Calendar
.
getInstance
();
private
static
Calendar
ca
chedCa
lendar
=
Calendar
.
getInstance
();
private
DateTimeUtils
()
{
// utility class
...
...
@@ -40,7 +40,14 @@ public class DateTimeUtils {
* Reset the calendar, for example after changing the default timezone.
*/
public
static
void
resetCalendar
()
{
calendar
=
Calendar
.
getInstance
();
cachedCalendar
=
null
;
}
private
static
Calendar
getCalendar
()
{
if
(
cachedCalendar
==
null
)
{
cachedCalendar
=
Calendar
.
getInstance
();
}
return
cachedCalendar
;
}
/**
...
...
@@ -67,7 +74,7 @@ public class DateTimeUtils {
* @return the time value without the date component
*/
public
static
Time
cloneAndNormalizeTime
(
Time
value
)
{
Calendar
cal
=
calendar
;
Calendar
cal
=
getCalendar
()
;
long
time
;
synchronized
(
cal
)
{
cal
.
setTime
(
value
);
...
...
@@ -86,7 +93,7 @@ public class DateTimeUtils {
* @return the date value at midnight
*/
public
static
Date
cloneAndNormalizeDate
(
Date
value
)
{
Calendar
cal
=
calendar
;
Calendar
cal
=
getCalendar
()
;
long
time
;
synchronized
(
cal
)
{
cal
.
setTime
(
value
);
...
...
@@ -147,7 +154,7 @@ public class DateTimeUtils {
throw
Message
.
getInvalidValueException
(
"calendar"
,
null
);
}
source
=
(
Calendar
)
source
.
clone
();
Calendar
universal
=
calendar
;
Calendar
universal
=
getCalendar
()
;
synchronized
(
universal
)
{
source
.
setTime
(
x
);
convertTime
(
source
,
universal
);
...
...
@@ -334,7 +341,7 @@ public class DateTimeUtils {
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
=
calendar
;
c
=
getCalendar
()
;
}
else
{
c
=
Calendar
.
getInstance
(
tz
);
}
...
...
@@ -369,7 +376,7 @@ public class DateTimeUtils {
* @return the value
*/
public
static
int
getDatePart
(
java
.
util
.
Date
d
,
int
field
)
{
Calendar
c
=
calendar
;
Calendar
c
=
getCalendar
()
;
int
value
;
synchronized
(
c
)
{
c
.
setTime
(
d
);
...
...
h2/src/main/org/h2/util/JdbcDriverUtils.java
浏览文件 @
cde29719
...
...
@@ -75,8 +75,4 @@ public class JdbcDriverUtils {
}
}
static
boolean
isShutdown
()
{
return
DRIVERS
==
null
;
}
}
h2/src/main/org/h2/util/MemoryUtils.java
浏览文件 @
cde29719
...
...
@@ -80,16 +80,4 @@ public class MemoryUtils {
reserveMemory
=
null
;
}
/**
* Check if Tomcat has set the static references to null,
* which can cause a NullPointerException. A workaround is to
* disable the system property org.apache.catalina.loader.
* WebappClassLoader.ENABLE_CLEAR_REFERENCES
*
* @return true if static references are set to null
*/
public
static
boolean
isShutdown
()
{
return
StringCache
.
isShutdown
()
||
JdbcDriverUtils
.
isShutdown
()
||
Resources
.
isShutdown
();
}
}
h2/src/main/org/h2/util/RandomUtils.java
浏览文件 @
cde29719
...
...
@@ -25,28 +25,29 @@ public class RandomUtils {
/**
* The secure random object.
*/
static
SecureRandom
s
ecureRandom
;
static
SecureRandom
cachedS
ecureRandom
;
/**
* True if the secure random object is seeded.
*/
static
volatile
boolean
seeded
;
private
static
Random
random
=
new
Random
();
private
static
final
Random
RANDOM
=
new
Random
();
private
RandomUtils
()
{
// utility class
}
private
static
synchronized
SecureRandom
getSecureRandom
()
{
if
(
s
ecureRandom
!=
null
)
{
return
s
ecureRandom
;
if
(
cachedS
ecureRandom
!=
null
)
{
return
cachedS
ecureRandom
;
}
// 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 after the initializer block exits
// threads are not started
until
after the initializer block exits
try
{
s
ecureRandom
=
SecureRandom
.
getInstance
(
"SHA1PRNG"
);
cachedS
ecureRandom
=
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.
...
...
@@ -55,8 +56,8 @@ public class RandomUtils {
try
{
SecureRandom
sr
=
SecureRandom
.
getInstance
(
"SHA1PRNG"
);
byte
[]
seed
=
sr
.
generateSeed
(
20
);
synchronized
(
s
ecureRandom
)
{
s
ecureRandom
.
setSeed
(
seed
);
synchronized
(
cachedS
ecureRandom
)
{
cachedS
ecureRandom
.
setSeed
(
seed
);
seeded
=
true
;
}
}
catch
(
NoSuchAlgorithmException
e
)
{
...
...
@@ -78,15 +79,15 @@ public class RandomUtils {
if
(!
seeded
)
{
byte
[]
seed
=
generateAlternativeSeed
();
// this never reduces randomness
synchronized
(
s
ecureRandom
)
{
s
ecureRandom
.
setSeed
(
seed
);
synchronized
(
cachedS
ecureRandom
)
{
cachedS
ecureRandom
.
setSeed
(
seed
);
}
}
}
catch
(
NoSuchAlgorithmException
e
)
{
warn
(
"SecureRandom"
,
e
);
s
ecureRandom
=
new
SecureRandom
();
cachedS
ecureRandom
=
new
SecureRandom
();
}
return
s
ecureRandom
;
return
cachedS
ecureRandom
;
}
private
static
byte
[]
generateAlternativeSeed
()
{
...
...
@@ -183,15 +184,29 @@ public class RandomUtils {
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
nextInt
(
int
lowerThan
)
{
return
RANDOM
.
nextInt
(
lowerThan
);
}
/**
* Get a cryptographically secure pseudo random int value between 0
* (including and the given value (excluding).
*
* @param lower the value returned will be lower than this value
* @param lower
Than
the value returned will be lower than this value
* @return the random long value
*/
public
static
int
nextInt
(
int
lower
)
{
return
random
.
nextInt
(
lower
);
public
static
int
nextSecureInt
(
int
lowerThan
)
{
SecureRandom
sr
=
getSecureRandom
();
synchronized
(
sr
)
{
return
sr
.
nextInt
(
lowerThan
);
}
}
/**
...
...
h2/src/main/org/h2/util/Resources.java
浏览文件 @
cde29719
...
...
@@ -79,8 +79,4 @@ public class Resources {
return
data
==
null
?
new
byte
[
0
]
:
data
;
}
static
boolean
isShutdown
()
{
return
FILES
==
null
;
}
}
h2/src/main/org/h2/util/StringCache.java
浏览文件 @
cde29719
...
...
@@ -120,8 +120,4 @@ public class StringCache {
softCache
=
new
SoftReference
(
null
);
}
static
boolean
isShutdown
()
{
return
softCache
==
null
;
}
}
h2/src/main/org/h2/value/DataType.java
浏览文件 @
cde29719
...
...
@@ -18,6 +18,7 @@ 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
org.h2.constant.ErrorCode
;
...
...
@@ -27,7 +28,6 @@ import org.h2.jdbc.JdbcBlob;
import
org.h2.jdbc.JdbcClob
;
import
org.h2.jdbc.JdbcConnection
;
import
org.h2.message.Message
;
import
org.h2.util.ObjectArray
;
import
org.h2.util.ObjectUtils
;
import
org.h2.util.StringUtils
;
...
...
@@ -49,9 +49,13 @@ public class DataType {
*/
public
static
final
int
TYPE_DATALINK
=
70
;
private
static
final
ObjectArray
TYPES
=
new
ObjectArray
();
/**
* 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
DataType
[]
TYPES_BY_VALUE_TYPE
=
new
DataType
[
Value
.
TYPE_COUNT
]
;
private
static
final
ArrayList
TYPES_BY_VALUE_TYPE
=
new
ArrayList
()
;
/**
* The value type of this data type.
...
...
@@ -160,6 +164,9 @@ public class DataType {
public
int
memory
;
static
{
for
(
int
i
=
0
;
i
<
Value
.
TYPE_COUNT
;
i
++)
{
TYPES_BY_VALUE_TYPE
.
add
(
null
);
}
//## Java 1.4 begin ##
if
(
TYPE_BOOLEAN
!=
Types
.
BOOLEAN
)
{
new
Exception
(
"Types.BOOLEAN: "
+
Types
.
BOOLEAN
).
printStackTrace
();
...
...
@@ -318,8 +325,8 @@ public class DataType {
new
String
[]{
"RESULT_SET"
},
20
);
for
(
int
i
=
0
;
i
<
TYPES_BY_VALUE_TYPE
.
length
;
i
++)
{
DataType
dt
=
TYPES_BY_VALUE_TYPE
[
i
]
;
for
(
int
i
=
0
;
i
<
TYPES_BY_VALUE_TYPE
.
size
()
;
i
++)
{
DataType
dt
=
(
DataType
)
TYPES_BY_VALUE_TYPE
.
get
(
i
)
;
if
(
dt
==
null
)
{
Message
.
throwInternalError
(
"unmapped type "
+
i
);
}
...
...
@@ -357,8 +364,8 @@ public class DataType {
}
}
TYPES_BY_NAME
.
put
(
dt
.
name
,
dt
);
if
(
TYPES_BY_VALUE_TYPE
[
type
]
==
null
)
{
TYPES_BY_VALUE_TYPE
[
type
]
=
dt
;
if
(
TYPES_BY_VALUE_TYPE
.
get
(
type
)
==
null
)
{
TYPES_BY_VALUE_TYPE
.
set
(
type
,
dt
)
;
}
TYPES
.
add
(
dt
);
}
...
...
@@ -411,7 +418,7 @@ public class DataType {
*
* @return the list
*/
public
static
ObjectArray
getTypes
()
{
public
static
ArrayList
getTypes
()
{
return
TYPES
;
}
...
...
@@ -639,9 +646,9 @@ public class DataType {
* @return the data type object
*/
public
static
DataType
getDataType
(
int
type
)
{
DataType
dt
=
TYPES_BY_VALUE_TYPE
[
type
]
;
DataType
dt
=
(
DataType
)
TYPES_BY_VALUE_TYPE
.
get
(
type
)
;
if
(
dt
==
null
)
{
dt
=
TYPES_BY_VALUE_TYPE
[
Value
.
NULL
]
;
dt
=
(
DataType
)
TYPES_BY_VALUE_TYPE
.
get
(
Value
.
NULL
)
;
}
return
dt
;
}
...
...
h2/src/main/org/h2/value/Value.java
浏览文件 @
cde29719
...
...
@@ -329,8 +329,11 @@ public abstract class Value {
*/
static
Value
cache
(
Value
v
)
{
if
(
SysProperties
.
OBJECT_CACHE
)
{
Value
[]
cache
=
(
Value
[])
softCache
.
get
();
int
hash
=
v
.
hashCode
();
if
(
softCache
==
null
)
{
softCache
=
new
SoftReference
(
null
);
}
Value
[]
cache
=
(
Value
[])
softCache
.
get
();
if
(
cache
==
null
)
{
cache
=
new
Value
[
SysProperties
.
OBJECT_CACHE_SIZE
];
softCache
=
new
SoftReference
(
cache
);
...
...
h2/src/main/org/h2/value/ValueBoolean.java
浏览文件 @
cde29719
...
...
@@ -25,8 +25,11 @@ public class ValueBoolean extends Value {
*/
public
static
final
int
DISPLAY_SIZE
=
5
;
private
static
final
ValueBoolean
TRUE
=
new
ValueBoolean
(
true
);
private
static
final
ValueBoolean
FALSE
=
new
ValueBoolean
(
false
);
/**
* 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
;
...
...
@@ -47,7 +50,7 @@ public class ValueBoolean extends Value {
}
public
Value
negate
()
{
return
value
.
booleanValue
()
?
FALSE
:
TRUE
;
return
(
ValueBoolean
)
(
value
.
booleanValue
()
?
FALSE
:
TRUE
)
;
}
public
Boolean
getBoolean
()
{
...
...
@@ -83,7 +86,7 @@ public class ValueBoolean extends Value {
* @return the value
*/
public
static
ValueBoolean
get
(
boolean
b
)
{
return
b
?
TRUE
:
FALSE
;
return
(
ValueBoolean
)
(
b
?
TRUE
:
FALSE
)
;
}
public
int
getDisplaySize
()
{
...
...
h2/src/main/org/h2/value/ValueDecimal.java
浏览文件 @
cde29719
...
...
@@ -38,8 +38,8 @@ public class ValueDecimal extends Value {
private
static
final
int
DIVIDE_SCALE_ADD
=
25
;
private
static
final
BigDecimal
DEC_ZERO
=
new
BigDecimal
(
"0"
);
private
static
final
BigDecimal
DEC_ONE
=
new
BigDecimal
(
"1"
);
private
static
final
ValueDecimal
ZERO
=
new
ValueDecimal
(
DEC_ZERO
);
private
static
final
ValueDecimal
ONE
=
new
ValueDecimal
(
DEC_ONE
);
private
static
final
Object
ZERO
=
new
ValueDecimal
(
DEC_ZERO
);
private
static
final
Object
ONE
=
new
ValueDecimal
(
DEC_ONE
);
private
final
BigDecimal
value
;
private
String
valueString
;
...
...
@@ -187,9 +187,9 @@ public class ValueDecimal extends Value {
*/
public
static
ValueDecimal
get
(
BigDecimal
dec
)
{
if
(
DEC_ZERO
.
equals
(
dec
))
{
return
ZERO
;
return
(
ValueDecimal
)
ZERO
;
}
else
if
(
DEC_ONE
.
equals
(
dec
))
{
return
ONE
;
return
(
ValueDecimal
)
ONE
;
}
// TODO value optimization: find a way to read size of BigDecimal,
// check max cache size
...
...
h2/src/test/org/h2/test/TestAll.java
浏览文件 @
cde29719
...
...
@@ -102,6 +102,7 @@ import org.h2.test.synth.thread.TestMulti;
import
org.h2.test.unit.SelfDestructor
;
import
org.h2.test.unit.TestBitField
;
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
;
...
...
@@ -282,6 +283,9 @@ java org.h2.test.TestAll timer
/*
include ClearReferences test case
isShutdown
PageStore.switchLogIfPossible()
drop table test;
...
...
@@ -609,6 +613,7 @@ http://www.w3schools.com/sql/
private
void
testUnit
()
{
new
TestBitField
().
runTest
(
this
);
new
TestCache
().
runTest
(
this
);
new
TestClearReferences
().
runTest
(
this
);
new
TestCompress
().
runTest
(
this
);
new
TestDataPage
().
runTest
(
this
);
new
TestDate
().
runTest
(
this
);
...
...
h2/src/test/org/h2/test/synth/TestRandomSQL.java
浏览文件 @
cde29719
...
...
@@ -165,17 +165,20 @@ public class TestRandomSQL extends TestBase {
}
public
void
testCase
(
int
i
)
throws
SQLException
{
String
old
=
SysProperties
.
scriptDirectory
;
SysProperties
.
scriptDirectory
=
"dataScript/"
;
seed
=
i
;
printTime
(
"seed: "
+
seed
);
String
old
=
SysProperties
.
getScriptDirectory
();
try
{
deleteDb
();
}
catch
(
SQLException
e
)
{
processException
(
"deleteDb"
,
e
);
SysProperties
.
setScriptDirectory
(
"dataScript/"
);
seed
=
i
;
printTime
(
"seed: "
+
seed
);
try
{
deleteDb
();
}
catch
(
SQLException
e
)
{
processException
(
"deleteDb"
,
e
);
}
testWithSeed
(
bnf
);
}
finally
{
SysProperties
.
setScriptDirectory
(
old
);
}
testWithSeed
(
bnf
);
SysProperties
.
scriptDirectory
=
old
;
try
{
deleteDb
();
}
catch
(
SQLException
e
)
{
...
...
h2/src/test/org/h2/test/todo/supportTemplates.txt
浏览文件 @
cde29719
...
...
@@ -52,6 +52,7 @@ I am sorry to say that, but it looks like a corruption problem. I am very intere
- 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?
...
...
h2/src/test/org/h2/test/unit/TestCache.java
浏览文件 @
cde29719
...
...
@@ -19,6 +19,15 @@ import org.h2.test.TestBase;
*/
public
class
TestCache
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
;
...
...
h2/src/test/org/h2/test/unit/TestClearReferences.java
0 → 100644
浏览文件 @
cde29719
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
;
/**
* 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.util.DateTimeUtils.cachedCalendar"
,
"org.h2.util.StringCache.softCache"
,
"org.h2.value.Value.softCache"
,
"org.h2.jdbcx.JdbcDataSourceFactory.cachedTraceSystem"
,
"org.h2.compress.CompressLZF.cachedHashTable"
,
"org.h2.store.fs.FileObjectMemory.cachedCompressedEmptyBlock"
,
"org.h2.tools.CompressTool.cachedBuffer"
,
"org.h2.util.MemoryUtils.reserveMemory"
,
"org.h2.util.NetUtils.cachedLocalAddress"
,
"org.h2.util.RandomUtils.cachedSecureRandom"
};
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
{
String
baseDir
=
"bin/org/h2"
;
ArrayList
classes
=
new
ArrayList
();
check
(
classes
,
new
File
(
baseDir
));
for
(
int
i
=
0
;
i
<
classes
.
size
();
i
++)
{
Class
clazz
=
(
Class
)
classes
.
get
(
i
);
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
;
}
File
[]
list
=
file
.
listFiles
();
for
(
int
i
=
0
;
i
<
list
.
length
;
i
++)
{
check
(
classes
,
list
[
i
]);
}
}
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
{
Field
[]
fields
=
clazz
.
getDeclaredFields
();
for
(
int
i
=
0
;
i
<
fields
.
length
;
i
++)
{
Field
field
=
fields
[
i
];
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
);
}
}
}
protected
void
clearInstance
(
Object
instance
)
throws
Exception
{
Field
[]
fields
=
instance
.
getClass
().
getDeclaredFields
();
for
(
int
i
=
0
;
i
<
fields
.
length
;
i
++)
{
Field
field
=
fields
[
i
];
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
;
}
clearField
(
instance
.
getClass
().
getName
()
+
"."
+
field
.
getName
()
+
" = "
+
o
);
}
}
private
void
clearField
(
String
s
)
{
for
(
int
i
=
0
;
i
<
KNOWN_REFRESHED
.
length
;
i
++)
{
if
(
s
.
startsWith
(
KNOWN_REFRESHED
[
i
]))
{
return
;
}
}
hasError
=
true
;
System
.
out
.
println
(
s
);
}
}
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论