Skip to content
项目
群组
代码片段
帮助
正在加载...
帮助
为 GitLab 提交贡献
登录/注册
切换导航
H
h2database
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
分枝图
比较
统计图
议题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
计划
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
分枝图
统计图
创建新议题
作业
提交
议题看板
打开侧边栏
Administrator
h2database
Commits
815b32a9
提交
815b32a9
authored
6月 18, 2008
作者:
Thomas Mueller
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
javadocs
上级
57b810ca
全部展开
隐藏空白字符变更
内嵌
并排
正在显示
67 个修改的文件
包含
2440 行增加
和
1334 行删除
+2440
-1334
Optimizer.java
h2/src/main/org/h2/command/dml/Optimizer.java
+5
-4
Select.java
h2/src/main/org/h2/command/dml/Select.java
+3
-2
ConnectionInfo.java
h2/src/main/org/h2/server/web/ConnectionInfo.java
+4
-0
DbContents.java
h2/src/main/org/h2/server/web/DbContents.java
+8
-0
DiskFile.java
h2/src/main/org/h2/store/DiskFile.java
+106
-2
FileObjectMemory.java
h2/src/main/org/h2/store/fs/FileObjectMemory.java
+42
-28
FileSystemDatabase.java
h2/src/main/org/h2/store/fs/FileSystemDatabase.java
+7
-0
FileSystemDisk.java
h2/src/main/org/h2/store/fs/FileSystemDisk.java
+1
-1
Column.java
h2/src/main/org/h2/table/Column.java
+30
-2
Plan.java
h2/src/main/org/h2/table/Plan.java
+2
-1
PlanItem.java
h2/src/main/org/h2/table/PlanItem.java
+5
-0
TableFilter.java
h2/src/main/org/h2/table/TableFilter.java
+8
-0
TableView.java
h2/src/main/org/h2/table/TableView.java
+2
-2
Console.java
h2/src/main/org/h2/tools/Console.java
+3
-0
RunScript.java
h2/src/main/org/h2/tools/RunScript.java
+10
-1
Script.java
h2/src/main/org/h2/tools/Script.java
+10
-3
SimpleResultSet.java
h2/src/main/org/h2/tools/SimpleResultSet.java
+16
-0
ByteUtils.java
h2/src/main/org/h2/util/ByteUtils.java
+1
-1
FileUtils.java
h2/src/main/org/h2/util/FileUtils.java
+0
-1
ObjectArray.java
h2/src/main/org/h2/util/ObjectArray.java
+1
-3
ObjectUtils.java
h2/src/main/org/h2/util/ObjectUtils.java
+26
-0
TempFileDeleter.java
h2/src/main/org/h2/util/TempFileDeleter.java
+8
-0
Value.java
h2/src/main/org/h2/value/Value.java
+975
-967
ValueDate.java
h2/src/main/org/h2/value/ValueDate.java
+4
-0
ValueFloat.java
h2/src/main/org/h2/value/ValueFloat.java
+4
-0
ValueShort.java
h2/src/main/org/h2/value/ValueShort.java
+3
-0
ValueTime.java
h2/src/main/org/h2/value/ValueTime.java
+4
-0
ValueTimestamp.java
h2/src/main/org/h2/value/ValueTimestamp.java
+4
-0
TestAll.java
h2/src/test/org/h2/test/TestAll.java
+2
-6
TestBase.java
h2/src/test/org/h2/test/TestBase.java
+13
-6
BenchC.java
h2/src/test/org/h2/test/bench/BenchC.java
+2
-2
BenchCRandom.java
h2/src/test/org/h2/test/bench/BenchCRandom.java
+75
-2
BenchCThread.java
h2/src/test/org/h2/test/bench/BenchCThread.java
+4
-1
Database.java
h2/src/test/org/h2/test/bench/Database.java
+155
-24
TestPerformance.java
h2/src/test/org/h2/test/bench/TestPerformance.java
+12
-0
Tokenizer.java
h2/src/test/org/h2/test/coverage/Tokenizer.java
+12
-0
Db.java
h2/src/test/org/h2/test/db/Db.java
+8
-2
TestDeadlock.java
h2/src/test/org/h2/test/db/TestDeadlock.java
+5
-0
WebClient.java
h2/src/test/org/h2/test/server/WebClient.java
+22
-4
OutputCatcher.java
h2/src/test/org/h2/test/synth/OutputCatcher.java
+6
-0
TestHalt.java
h2/src/test/org/h2/test/synth/TestHalt.java
+62
-45
Column.java
h2/src/test/org/h2/test/synth/sql/Column.java
+33
-15
Command.java
h2/src/test/org/h2/test/synth/sql/Command.java
+177
-83
DbState.java
h2/src/test/org/h2/test/synth/sql/DbState.java
+11
-2
Expression.java
h2/src/test/org/h2/test/synth/sql/Expression.java
+42
-14
Index.java
h2/src/test/org/h2/test/synth/sql/Index.java
+8
-8
Result.java
h2/src/test/org/h2/test/synth/sql/Result.java
+22
-22
Table.java
h2/src/test/org/h2/test/synth/sql/Table.java
+73
-15
TestSynth.java
h2/src/test/org/h2/test/synth/sql/TestSynth.java
+52
-2
Value.java
h2/src/test/org/h2/test/synth/sql/Value.java
+65
-41
TestMultiThread.java
h2/src/test/org/h2/test/synth/thread/TestMultiThread.java
+26
-0
Arg.java
h2/src/test/org/h2/test/trace/Arg.java
+4
-1
Parser.java
h2/src/test/org/h2/test/trace/Parser.java
+7
-0
Player.java
h2/src/test/org/h2/test/trace/Player.java
+27
-3
Statement.java
h2/src/test/org/h2/test/trace/Statement.java
+26
-2
FtpClient.java
h2/src/test/org/h2/test/unit/FtpClient.java
+92
-2
TestExit.java
h2/src/test/org/h2/test/unit/TestExit.java
+1
-1
Build.java
h2/src/tools/org/h2/build/Build.java
+1
-1
BuildBase.java
h2/src/tools/org/h2/build/BuildBase.java
+8
-0
dictionary.txt
h2/src/tools/org/h2/build/doc/dictionary.txt
+1
-1
Doclet.java
h2/src/tools/org/h2/build/doclet/Doclet.java
+1
-1
PropertiesToUTF8.java
h2/src/tools/org/h2/build/i18n/PropertiesToUTF8.java
+19
-0
Page.java
h2/src/tools/org/h2/build/indexer/Page.java
+20
-0
Weight.java
h2/src/tools/org/h2/build/indexer/Weight.java
+23
-1
Word.java
h2/src/tools/org/h2/build/indexer/Word.java
+13
-2
PgTcpRedirect.java
h2/src/tools/org/h2/dev/net/PgTcpRedirect.java
+7
-1
Base64.java
h2/src/tools/org/h2/dev/util/Base64.java
+11
-6
没有找到文件。
h2/src/main/org/h2/command/dml/Optimizer.java
浏览文件 @
815b32a9
...
...
@@ -15,6 +15,7 @@ import org.h2.expression.Expression;
import
org.h2.table.Plan
;
import
org.h2.table.PlanItem
;
import
org.h2.table.TableFilter
;
import
org.h2.util.ObjectUtils
;
import
org.h2.util.Permutations
;
/**
...
...
@@ -151,20 +152,20 @@ public class Optimizer {
}
boolean
generateRandom
=
(
x
&
127
)
==
0
;
if
(!
generateRandom
)
{
System
.
arraycopy
(
best
,
0
,
list
,
0
,
filters
.
length
);
ObjectUtils
.
arrayCopy
(
best
,
list
,
filters
.
length
);
if
(!
shuffleTwo
(
list
))
{
generateRandom
=
true
;
}
}
if
(
generateRandom
)
{
switched
=
new
BitSet
();
System
.
arraycopy
(
filters
,
0
,
best
,
0
,
filters
.
length
);
ObjectUtils
.
arrayCopy
(
filters
,
best
,
filters
.
length
);
shuffleAll
(
best
);
System
.
arraycopy
(
best
,
0
,
list
,
0
,
filters
.
length
);
ObjectUtils
.
arrayCopy
(
best
,
list
,
filters
.
length
);
}
if
(
testPlan
(
list
))
{
switched
=
new
BitSet
();
System
.
arraycopy
(
list
,
0
,
best
,
0
,
filters
.
length
);
ObjectUtils
.
arrayCopy
(
list
,
best
,
filters
.
length
);
}
}
}
...
...
h2/src/main/org/h2/command/dml/Select.java
浏览文件 @
815b32a9
...
...
@@ -35,6 +35,7 @@ import org.h2.table.IndexColumn;
import
org.h2.table.Table
;
import
org.h2.table.TableFilter
;
import
org.h2.util.ObjectArray
;
import
org.h2.util.ObjectUtils
;
import
org.h2.util.StringUtils
;
import
org.h2.util.ValueHashMap
;
import
org.h2.value.Value
;
...
...
@@ -205,7 +206,7 @@ public class Select extends Query {
if
(
columnCount
!=
distinctColumnCount
)
{
// remove columns so that 'distinct' can filter duplicate rows
Value
[]
r2
=
new
Value
[
distinctColumnCount
];
System
.
arraycopy
(
row
,
0
,
r2
,
0
,
distinctColumnCount
);
ObjectUtils
.
arrayCopy
(
row
,
r2
,
distinctColumnCount
);
row
=
r2
;
}
result
.
addRow
(
row
);
...
...
@@ -337,7 +338,7 @@ public class Select extends Query {
if
(
columnCount
!=
distinctColumnCount
)
{
// remove columns so that 'distinct' can filter duplicate rows
Value
[]
r2
=
new
Value
[
distinctColumnCount
];
System
.
arraycopy
(
row
,
0
,
r2
,
0
,
distinctColumnCount
);
ObjectUtils
.
arrayCopy
(
row
,
r2
,
distinctColumnCount
);
row
=
r2
;
}
result
.
addRow
(
row
);
...
...
h2/src/main/org/h2/server/web/ConnectionInfo.java
浏览文件 @
815b32a9
...
...
@@ -33,6 +33,10 @@ public class ConnectionInfo {
* The connection display name.
*/
String
name
;
/**
* The last time this connection was used.
*/
int
lastAccess
;
ConnectionInfo
()
{
...
...
h2/src/main/org/h2/server/web/DbContents.java
浏览文件 @
815b32a9
...
...
@@ -162,6 +162,14 @@ public class DbContents {
return
defaultSchemaName
;
}
/**
* Add double quotes around an identifier if required.
* For the H2 database, only keywords are quoted; for other databases,
* all identifiers are.
*
* @param identifier the identifier
* @return the quoted identifier
*/
String
quoteIdentifier
(
String
identifier
)
{
if
(
identifier
==
null
)
{
return
null
;
...
...
h2/src/main/org/h2/store/DiskFile.java
浏览文件 @
815b32a9
...
...
@@ -237,6 +237,12 @@ public class DiskFile implements CacheWriter {
}
}
/**
* Check if a page is free, that is, if all blocks of the page are not in use.
*
* @param page the page id
* @return true if no blocks are used
*/
boolean
isPageFree
(
int
page
)
{
for
(
int
i
=
page
*
BLOCKS_PER_PAGE
;
i
<
(
page
+
1
)
*
BLOCKS_PER_PAGE
;
i
++)
{
if
(
used
.
get
(
i
))
{
...
...
@@ -492,6 +498,15 @@ public class DiskFile implements CacheWriter {
return
((
long
)
block
*
BLOCK_SIZE
)
+
OFFSET
;
}
/**
* Get the record if it is stored in the file, or null if not.
*
* @param session the session
* @param pos the block id
* @param reader the record reader that can parse the data
* @param storageId the storage id
* @return the record or null
*/
Record
getRecordIfStored
(
Session
session
,
int
pos
,
RecordReader
reader
,
int
storageId
)
throws
SQLException
{
synchronized
(
database
)
{
...
...
@@ -518,6 +533,15 @@ public class DiskFile implements CacheWriter {
}
}
/**
* Get a record from the cache or read it from the file if required.
*
* @param session the session
* @param pos the block id
* @param reader the record reader that can parse the data
* @param storageId the storage id
* @return the record
*/
Record
getRecord
(
Session
session
,
int
pos
,
RecordReader
reader
,
int
storageId
)
throws
SQLException
{
synchronized
(
database
)
{
if
(
file
==
null
)
{
...
...
@@ -561,6 +585,13 @@ public class DiskFile implements CacheWriter {
}
}
/**
* Allocate space in the file.
*
* @param storage the storage
* @param blockCount the number of blocks required
* @return the position of the first entry
*/
int
allocate
(
Storage
storage
,
int
blockCount
)
throws
SQLException
{
reuseSpace
();
synchronized
(
database
)
{
...
...
@@ -666,6 +697,13 @@ public class DiskFile implements CacheWriter {
}
}
/**
* Called after a session deleted a row. This sets the last uncommitted
* delete id in the session. This is used to make sure empty space is not
* re-used before the change is committed.
*
* @param session the session
*/
void
uncommittedDelete
(
Session
session
)
{
if
(
session
!=
null
&&
logChanges
&&
SysProperties
.
REUSE_SPACE_QUICKLY
)
{
int
deleteId
=
session
.
getLastUncommittedDelete
();
...
...
@@ -676,6 +714,11 @@ public class DiskFile implements CacheWriter {
}
}
/**
* Free a page, that is, reset the page owner.
*
* @param page the page
*/
void
freePage
(
int
page
)
throws
SQLException
{
if
(!
logChanges
)
{
setPageOwner
(
page
,
FREE_PAGE
);
...
...
@@ -686,10 +729,22 @@ public class DiskFile implements CacheWriter {
}
}
/**
* Calculate the page number from a block number.
*
* @param pos the block number
* @return the page number
*/
int
getPage
(
int
pos
)
{
return
pos
>>>
BLOCK_PAGE_PAGE_SHIFT
;
}
/**
* Get the storage id of a page.
*
* @param page the page id
* @return the storage id
*/
int
getPageOwner
(
int
page
)
{
if
(
page
*
BLOCKS_PER_PAGE
>
fileBlockCount
||
page
>=
pageOwners
.
size
())
{
return
FREE_PAGE
;
...
...
@@ -736,6 +791,12 @@ public class DiskFile implements CacheWriter {
pageOwners
.
set
(
page
,
storageId
);
}
/**
* Mark a number of blocks as used.
*
* @param pos the first block id
* @param blockCount the number of blocks
*/
void
setUsed
(
int
pos
,
int
blockCount
)
{
synchronized
(
database
)
{
if
(
pos
+
blockCount
>
fileBlockCount
)
{
...
...
@@ -812,6 +873,12 @@ public class DiskFile implements CacheWriter {
return
used
;
}
/**
* Update a record.
*
* @param session the session
* @param record the record
*/
void
updateRecord
(
Session
session
,
Record
record
)
throws
SQLException
{
synchronized
(
database
)
{
record
.
setChanged
(
true
);
...
...
@@ -911,6 +978,15 @@ public class DiskFile implements CacheWriter {
}
}
/**
* Remove a record from the cache and mark it as deleted. This writes the
* old data to the transaction log.
*
* @param session the session
* @param pos the block id
* @param record the record
* @param blockCount the number of blocks
*/
void
removeRecord
(
Session
session
,
int
pos
,
Record
record
,
int
blockCount
)
throws
SQLException
{
synchronized
(
database
)
{
if
(
logChanges
)
{
...
...
@@ -922,6 +998,14 @@ public class DiskFile implements CacheWriter {
}
}
/**
* Add a record to the file. The position of the record must already be set
* before. This method will write the change to the transaction log and will
* update the cache.
*
* @param session the session
* @param record the record
*/
void
addRecord
(
Session
session
,
Record
record
)
throws
SQLException
{
synchronized
(
database
)
{
cache
.
put
(
record
);
...
...
@@ -931,23 +1015,43 @@ public class DiskFile implements CacheWriter {
}
}
/*
* Must be synchronized externally
/**
* Get the cache. The cache must be synchronized externally.
*
* @return the cache
*/
public
Cache
getCache
()
{
return
cache
;
}
/**
* Free up a number of blocks.
*
* @param pos the position of the first block
* @param blockCount the number of blocks
*/
void
free
(
int
pos
,
int
blockCount
)
{
synchronized
(
database
)
{
used
.
setRange
(
pos
,
blockCount
,
false
);
}
}
/**
* Get the overhead for each record in bytes.
*
* @return the overhead
*/
int
getRecordOverhead
()
{
return
recordOverhead
;
}
/**
* Remove all rows for this storage.
*
* @param session the session
* @param storage the storage
* @param pages the page id array
*/
void
truncateStorage
(
Session
session
,
Storage
storage
,
IntArray
pages
)
throws
SQLException
{
synchronized
(
database
)
{
int
storageId
=
storage
.
getId
();
...
...
h2/src/main/org/h2/store/fs/FileObjectMemory.java
浏览文件 @
815b32a9
...
...
@@ -55,7 +55,7 @@ public class FileObjectMemory implements FileObject {
return
false
;
}
CompressItem
c
=
(
CompressItem
)
eldest
.
getKey
();
compress
(
c
.
data
,
c
.
l
);
compress
(
c
.
data
,
c
.
page
);
return
true
;
}
}
...
...
@@ -64,17 +64,25 @@ public class FileObjectMemory implements FileObject {
* Represents a compressed item.
*/
static
class
CompressItem
{
/**
* The file data.
*/
byte
[][]
data
;
int
l
;
/**
* The page to compress.
*/
int
page
;
public
int
hashCode
()
{
return
data
.
hashCode
()
^
l
;
return
data
.
hashCode
()
^
page
;
}
public
boolean
equals
(
Object
o
)
{
if
(
o
instanceof
CompressItem
)
{
CompressItem
c
=
(
CompressItem
)
o
;
return
c
.
data
==
data
&&
c
.
l
==
l
;
return
c
.
data
==
data
&&
c
.
page
==
page
;
}
return
false
;
}
...
...
@@ -88,19 +96,19 @@ public class FileObjectMemory implements FileObject {
touch
();
}
private
static
void
compressLater
(
byte
[][]
data
,
int
l
)
{
private
static
void
compressLater
(
byte
[][]
data
,
int
page
)
{
//## Java 1.4 begin ##
CompressItem
c
=
new
CompressItem
();
c
.
data
=
data
;
c
.
l
=
l
;
c
.
page
=
page
;
synchronized
(
LZF
)
{
COMPRESS_LATER
.
put
(
c
,
c
);
}
//## Java 1.4 end ##
}
private
static
void
expand
(
byte
[][]
data
,
int
i
)
{
byte
[]
d
=
data
[
i
];
private
static
void
expand
(
byte
[][]
data
,
int
page
)
{
byte
[]
d
=
data
[
page
];
if
(
d
.
length
==
BLOCK_SIZE
)
{
return
;
}
...
...
@@ -108,17 +116,23 @@ public class FileObjectMemory implements FileObject {
synchronized
(
LZF
)
{
LZF
.
expand
(
d
,
0
,
d
.
length
,
out
,
0
,
BLOCK_SIZE
);
}
data
[
i
]
=
out
;
data
[
page
]
=
out
;
}
static
void
compress
(
byte
[][]
data
,
int
i
)
{
byte
[]
d
=
data
[
i
];
/**
* Compress the data in a byte array.
*
* @param data the page array
* @param page which page to compress
*/
static
void
compress
(
byte
[][]
data
,
int
page
)
{
byte
[]
d
=
data
[
page
];
synchronized
(
LZF
)
{
int
len
=
LZF
.
compress
(
d
,
BLOCK_SIZE
,
BUFFER
,
0
);
if
(
len
<=
BLOCK_SIZE
)
{
d
=
new
byte
[
len
];
System
.
arraycopy
(
BUFFER
,
0
,
d
,
0
,
len
);
data
[
i
]
=
d
;
data
[
page
]
=
d
;
}
}
}
...
...
@@ -138,25 +152,25 @@ public class FileObjectMemory implements FileObject {
return
length
;
}
public
void
setFileLength
(
long
l
)
{
public
void
setFileLength
(
long
newLength
)
{
touch
();
if
(
l
<
length
)
{
pos
=
Math
.
min
(
pos
,
l
);
changeLength
(
l
);
long
end
=
MathUtils
.
roundUpLong
(
l
,
BLOCK_SIZE
);
if
(
end
!=
l
)
{
int
last
Block
=
(
int
)
(
l
>>>
BLOCK_SIZE_SHIFT
);
expand
(
data
,
last
Block
);
byte
[]
d
=
data
[
last
Block
];
for
(
int
i
=
(
int
)
(
l
&
BLOCK_SIZE_MASK
);
i
<
BLOCK_SIZE
;
i
++)
{
if
(
newLength
<
length
)
{
pos
=
Math
.
min
(
pos
,
newLength
);
changeLength
(
newLength
);
long
end
=
MathUtils
.
roundUpLong
(
newLength
,
BLOCK_SIZE
);
if
(
end
!=
newLength
)
{
int
last
Page
=
(
int
)
(
newLength
>>>
BLOCK_SIZE_SHIFT
);
expand
(
data
,
last
Page
);
byte
[]
d
=
data
[
last
Page
];
for
(
int
i
=
(
int
)
(
newLength
&
BLOCK_SIZE_MASK
);
i
<
BLOCK_SIZE
;
i
++)
{
d
[
i
]
=
0
;
}
if
(
compress
)
{
compressLater
(
data
,
last
Block
);
compressLater
(
data
,
last
Page
);
}
}
}
else
{
changeLength
(
l
);
changeLength
(
newLength
);
}
}
...
...
@@ -193,9 +207,9 @@ public class FileObjectMemory implements FileObject {
}
while
(
len
>
0
)
{
int
l
=
(
int
)
Math
.
min
(
len
,
BLOCK_SIZE
-
(
pos
&
BLOCK_SIZE_MASK
));
int
id
=
(
int
)
(
pos
>>>
BLOCK_SIZE_SHIFT
);
expand
(
data
,
id
);
byte
[]
block
=
data
[
id
];
int
page
=
(
int
)
(
pos
>>>
BLOCK_SIZE_SHIFT
);
expand
(
data
,
page
);
byte
[]
block
=
data
[
page
];
int
blockOffset
=
(
int
)
(
pos
&
BLOCK_SIZE_MASK
);
if
(
write
)
{
System
.
arraycopy
(
b
,
off
,
block
,
blockOffset
,
l
);
...
...
@@ -203,7 +217,7 @@ public class FileObjectMemory implements FileObject {
System
.
arraycopy
(
block
,
blockOffset
,
b
,
off
,
l
);
}
if
(
compress
)
{
compressLater
(
data
,
id
);
compressLater
(
data
,
page
);
}
off
+=
l
;
pos
+=
l
;
...
...
h2/src/main/org/h2/store/fs/FileSystemDatabase.java
浏览文件 @
815b32a9
...
...
@@ -427,6 +427,13 @@ public class FileSystemDatabase extends FileSystem {
return
true
;
}
/**
* Update a file in the file system.
*
* @param fileName the file name
* @param b the data
* @param len the number of bytes
*/
synchronized
void
write
(
String
fileName
,
byte
[]
b
,
int
len
)
{
try
{
long
id
=
getId
(
fileName
,
false
);
...
...
h2/src/main/org/h2/store/fs/FileSystemDisk.java
浏览文件 @
815b32a9
...
...
@@ -82,7 +82,7 @@ public class FileSystemDisk extends FileSystem {
throw
Message
.
getSQLException
(
ErrorCode
.
FILE_RENAME_FAILED_2
,
new
String
[]{
oldName
,
newName
});
}
void
trace
(
String
method
,
String
fileName
,
Object
o
)
{
private
void
trace
(
String
method
,
String
fileName
,
Object
o
)
{
if
(
SysProperties
.
TRACE_IO
)
{
System
.
out
.
println
(
"FileSystem."
+
method
+
" "
+
fileName
+
" "
+
o
);
}
...
...
h2/src/main/org/h2/table/Column.java
浏览文件 @
815b32a9
...
...
@@ -140,6 +140,13 @@ public class Column {
return
isComputed
;
}
/**
* Compute the value of this computed column.
*
* @param session the session
* @param row the row
* @return the value
*/
Value
computeValue
(
Session
session
,
Row
row
)
throws
SQLException
{
synchronized
(
this
)
{
computeTableFilter
.
setSession
(
session
);
...
...
@@ -159,6 +166,12 @@ public class Column {
this
.
defaultExpression
=
expression
;
}
/**
* Set the table and column id.
*
* @param table the table
* @param columnId the column index
*/
void
setTable
(
Table
table
,
int
columnId
)
{
this
.
table
=
table
;
this
.
columnId
=
columnId
;
...
...
@@ -571,8 +584,15 @@ public class Column {
return
DataType
.
getDataType
(
type
);
}
String
getCheckConstraintSQL
(
Session
session
,
String
name
)
throws
SQLException
{
Expression
constraint
=
getCheckConstraint
(
session
,
name
);
/**
* Get the check constraint SQL snippet.
*
* @param session the session
* @param asColumnName the column name to use
* @return the SQL snippet
*/
String
getCheckConstraintSQL
(
Session
session
,
String
asColumnName
)
throws
SQLException
{
Expression
constraint
=
getCheckConstraint
(
session
,
asColumnName
);
return
constraint
==
null
?
""
:
constraint
.
getSQL
();
}
...
...
@@ -588,6 +608,14 @@ public class Column {
this
.
primaryKey
=
primaryKey
;
}
/**
* Visit the default expression, the check constraint, and the sequence (if
* any).
*
* @param visitor the visitor
* @return true if every visited expression returned true, or if there are
* no expressions
*/
boolean
isEverything
(
ExpressionVisitor
visitor
)
{
if
(
visitor
.
getType
()
==
ExpressionVisitor
.
GET_DEPENDENCIES
)
{
if
(
sequence
!=
null
)
{
...
...
h2/src/main/org/h2/table/Plan.java
浏览文件 @
815b32a9
...
...
@@ -13,6 +13,7 @@ import org.h2.engine.Session;
import
org.h2.expression.Expression
;
import
org.h2.expression.ExpressionVisitor
;
import
org.h2.util.ObjectArray
;
import
org.h2.util.ObjectUtils
;
/**
* A possible query execution plan. The time required to execute a query depends
...
...
@@ -33,7 +34,7 @@ public class Plan {
*/
public
Plan
(
TableFilter
[]
filters
,
int
count
,
Expression
condition
)
{
this
.
filters
=
new
TableFilter
[
count
];
System
.
arraycopy
(
filters
,
0
,
this
.
filters
,
0
,
count
);
ObjectUtils
.
arrayCopy
(
filters
,
this
.
filters
,
count
);
ObjectArray
allCond
=
new
ObjectArray
();
ObjectArray
all
=
new
ObjectArray
();
if
(
condition
!=
null
)
{
...
...
h2/src/main/org/h2/table/PlanItem.java
浏览文件 @
815b32a9
...
...
@@ -13,7 +13,12 @@ import org.h2.index.Index;
* using it.
*/
public
class
PlanItem
{
/**
* The cost.
*/
double
cost
;
private
Index
index
;
private
PlanItem
joinPlan
;
...
...
h2/src/main/org/h2/table/TableFilter.java
浏览文件 @
815b32a9
...
...
@@ -521,6 +521,9 @@ public class TableFilter implements ColumnResolver {
return
buff
.
toString
();
}
/**
* Remove all index conditions that are not used by the current index.
*/
void
removeUnusableIndexConditions
()
{
for
(
int
i
=
0
;
i
<
indexConditions
.
size
();
i
++)
{
IndexCondition
cond
=
(
IndexCondition
)
indexConditions
.
get
(
i
);
...
...
@@ -557,6 +560,11 @@ public class TableFilter implements ColumnResolver {
return
used
;
}
/**
* Set the session of this table filter.
*
* @param session
*/
void
setSession
(
Session
session
)
{
this
.
session
=
session
;
}
...
...
h2/src/main/org/h2/table/TableView.java
浏览文件 @
815b32a9
...
...
@@ -53,7 +53,7 @@ public class TableView extends Table {
initColumnsAndTables
(
session
);
}
Query
recompileQuery
(
Session
session
)
throws
SQLException
{
private
Query
recompileQuery
(
Session
session
)
throws
SQLException
{
Prepared
p
=
session
.
prepare
(
querySQL
);
if
(!(
p
instanceof
Query
))
{
throw
Message
.
getSyntaxError
(
querySQL
,
0
);
...
...
@@ -310,7 +310,7 @@ public class TableView extends Table {
}
}
void
setOwner
(
User
owner
)
{
private
void
setOwner
(
User
owner
)
{
this
.
owner
=
owner
;
}
...
...
h2/src/main/org/h2/tools/Console.java
浏览文件 @
815b32a9
...
...
@@ -152,6 +152,9 @@ ShutdownHandler {
stopAll
();
}
/**
* Stop all servers that were started using the console.
*/
void
stopAll
()
{
if
(
web
!=
null
&&
web
.
isRunning
(
false
))
{
web
.
stop
();
...
...
h2/src/main/org/h2/tools/RunScript.java
浏览文件 @
815b32a9
...
...
@@ -298,12 +298,21 @@ public class RunScript extends Tool {
* @param fileName the script file
* @param charsetName the character set name or null for UTF-8
* @param continueOnError if execution should be continued if an error occurs
* @throws SQLException
*/
public
static
void
execute
(
String
url
,
String
user
,
String
password
,
String
fileName
,
String
charsetName
,
boolean
continueOnError
)
throws
SQLException
{
new
RunScript
().
process
(
url
,
user
,
password
,
fileName
,
charsetName
,
continueOnError
);
}
/**
* Executes the SQL commands in a script file against a database.
*
* @param url the database URL
* @param user the user name
* @param password the password
* @param fileName the script file
* @param charsetName the character set name or null for UTF-8
* @param continueOnError if execution should be continued if an error occurs
*/
void
process
(
String
url
,
String
user
,
String
password
,
String
fileName
,
String
charsetName
,
boolean
continueOnError
)
throws
SQLException
{
try
{
org
.
h2
.
Driver
.
load
();
...
...
h2/src/main/org/h2/tools/Script.java
浏览文件 @
815b32a9
...
...
@@ -126,18 +126,25 @@ public class Script extends Tool {
}
/**
* Backs up a database to a file.
* Backs up a database to a
SQL script
file.
*
* @param url the database URL
* @param user the user name
* @param password the password
* @param fileName the script file
* @throws SQLException
*/
public
static
void
execute
(
String
url
,
String
user
,
String
password
,
String
fileName
)
throws
SQLException
{
new
Script
().
process
(
url
,
user
,
password
,
fileName
);
}
/**
* Backs up a database to a SQL script file.
*
* @param url the database URL
* @param user the user name
* @param password the password
* @param fileName the script file
*/
void
process
(
String
url
,
String
user
,
String
password
,
String
fileName
)
throws
SQLException
{
Connection
conn
=
null
;
Statement
stat
=
null
;
...
...
h2/src/main/org/h2/tools/SimpleResultSet.java
浏览文件 @
815b32a9
...
...
@@ -64,9 +64,25 @@ public class SimpleResultSet implements ResultSet, ResultSetMetaData {
* This class holds the data of a result column.
*/
static
class
Column
{
/**
* The column name.
*/
String
name
;
/**
* The SQL type.
*/
int
sqlType
;
/**
* The precision.
*/
int
precision
;
/**
* The scale.
*/
int
scale
;
}
...
...
h2/src/main/org/h2/util/ByteUtils.java
浏览文件 @
815b32a9
...
...
@@ -236,6 +236,6 @@ public class ByteUtils {
byte
[]
copy
=
new
byte
[
len
];
System
.
arraycopy
(
b
,
0
,
copy
,
0
,
len
);
return
copy
;
}
}
}
h2/src/main/org/h2/util/FileUtils.java
浏览文件 @
815b32a9
...
...
@@ -107,7 +107,6 @@ public class FileUtils {
* Try to delete a file.
*
* @param fileName the file name
* @return true if it could be deleted
*/
public
static
void
tryDelete
(
String
fileName
)
{
FileSystem
.
getInstance
(
fileName
).
tryDelete
(
fileName
);
...
...
h2/src/main/org/h2/util/ObjectArray.java
浏览文件 @
815b32a9
...
...
@@ -184,9 +184,7 @@ public class ObjectArray {
* @param array the target array
*/
public
void
toArray
(
Object
[]
array
)
{
for
(
int
i
=
0
;
i
<
size
;
i
++)
{
array
[
i
]
=
data
[
i
];
}
ObjectUtils
.
arrayCopy
(
data
,
array
,
size
);
}
/**
...
...
h2/src/main/org/h2/util/ObjectUtils.java
浏览文件 @
815b32a9
...
...
@@ -21,6 +21,13 @@ import org.h2.message.Message;
*/
public
class
ObjectUtils
{
/**
* The maximum number of elements to copy using a Java loop. This value was
* found by running tests using the Sun JDK 1.4 and JDK 1.6 on Windows XP.
* The biggest difference is for size smaller than 40 (more than 50% saving).
*/
private
static
final
int
MAX_JAVA_LOOP_COPY
=
100
;
private
ObjectUtils
()
{
// utility class
}
...
...
@@ -168,5 +175,24 @@ public class ObjectUtils {
throw
Message
.
getSQLException
(
ErrorCode
.
DESERIALIZATION_FAILED_1
,
new
String
[]
{
e
.
toString
()
},
e
);
}
}
/**
* Copy the elements of the source array to the target array.
* System.arraycopy is used for larger arrays, but for very small arrays it
* is faster to use a regular loop.
*
* @param source the source array
* @param target the target array
* @param size the number of elements to copy
*/
public
static
void
arrayCopy
(
Object
[]
source
,
Object
[]
target
,
int
size
)
{
if
(
size
>
MAX_JAVA_LOOP_COPY
)
{
System
.
arraycopy
(
source
,
0
,
target
,
0
,
size
);
}
else
{
for
(
int
i
=
0
;
i
<
size
;
i
++)
{
target
[
i
]
=
source
[
i
];
}
}
}
}
h2/src/main/org/h2/util/TempFileDeleter.java
浏览文件 @
815b32a9
...
...
@@ -30,7 +30,15 @@ public class TempFileDeleter {
* Contains information about a file.
*/
static
class
TempFile
{
/**
* The file name.
*/
String
fileName
;
/**
* The last modified date of this file.
*/
long
lastModified
;
}
...
...
h2/src/main/org/h2/value/Value.java
浏览文件 @
815b32a9
差异被折叠。
点击展开。
h2/src/main/org/h2/value/ValueDate.java
浏览文件 @
815b32a9
...
...
@@ -18,6 +18,10 @@ import org.h2.util.DateTimeUtils;
* Implementation of the DATE data type.
*/
public
class
ValueDate
extends
Value
{
/**
* The precision in digits.
*/
static
final
int
PRECISION
=
8
;
/**
...
...
h2/src/main/org/h2/value/ValueFloat.java
浏览文件 @
815b32a9
...
...
@@ -17,6 +17,10 @@ import org.h2.util.ObjectUtils;
* Implementation of the REAL data type.
*/
public
class
ValueFloat
extends
Value
{
/**
* The precision in digits.
*/
static
final
int
PRECISION
=
7
;
/**
...
...
h2/src/main/org/h2/value/ValueShort.java
浏览文件 @
815b32a9
...
...
@@ -19,6 +19,9 @@ import org.h2.util.ObjectUtils;
*/
public
class
ValueShort
extends
Value
{
/**
* The precision in digits.
*/
static
final
int
PRECISION
=
5
;
/**
...
...
h2/src/main/org/h2/value/ValueTime.java
浏览文件 @
815b32a9
...
...
@@ -16,6 +16,10 @@ import org.h2.util.DateTimeUtils;
* Implementation of the TIME data type.
*/
public
class
ValueTime
extends
Value
{
/**
* The precision in digits.
*/
static
final
int
PRECISION
=
6
;
/**
...
...
h2/src/main/org/h2/value/ValueTimestamp.java
浏览文件 @
815b32a9
...
...
@@ -21,6 +21,10 @@ import org.h2.util.MathUtils;
* Implementation of the TIMESTAMP data type.
*/
public
class
ValueTimestamp
extends
Value
{
/**
* The precision in digits.
*/
static
final
int
PRECISION
=
23
;
/**
...
...
h2/src/test/org/h2/test/TestAll.java
浏览文件 @
815b32a9
...
...
@@ -266,14 +266,12 @@ java org.h2.test.TestAll timer
/*
jazoon
run the performance tests as part of the unit test
measure and improve performance of ObjectArray.toArray()
jazoon
H2 Console should support Java Queries
convert test.in.sql to RunScript syntax
C:\download\Data Concurrency and Consistency.pdf
not tested:
...
...
@@ -290,8 +288,6 @@ create an mbean for each database? server? (jconsole)
in help.csv, use complete examples for functions; add a test case
improve javadocs
option to write complete page right after checkpoint
test case for out of memory (try to corrupt the database using out of memory)
...
...
h2/src/test/org/h2/test/TestBase.java
浏览文件 @
815b32a9
...
...
@@ -365,6 +365,12 @@ public abstract class TestBase {
printlnWithTime
(
time
,
getClass
().
getName
()
+
" "
+
s
);
}
/**
* Print a message, prepended with the specified time in milliseconds.
*
* @param time the milliseconds
* @param s the message
*/
static
void
printlnWithTime
(
long
time
,
String
s
)
{
String
t
=
"0000000000"
+
time
;
t
=
t
.
substring
(
t
.
length
()
-
6
);
...
...
@@ -743,9 +749,10 @@ public abstract class TestBase {
* @param data the expected data
* @throws Exception if there is a mismatch
*/
void
assertResultSetUnordered
(
ResultSet
rs
,
String
[][]
data
)
throws
Exception
{
assertResultSet
(
false
,
rs
,
data
);
}
// void assertResultSetUnordered(ResultSet rs, String[][] data)
// throws Exception {
// assertResultSet(false, rs, data);
// }
/**
* Check if a result set contains the expected data.
...
...
@@ -755,7 +762,7 @@ public abstract class TestBase {
* @param data the expected data
* @throws Exception if there is a mismatch
*/
void
assertResultSet
(
boolean
ordered
,
ResultSet
rs
,
String
[][]
data
)
throws
Exception
{
private
void
assertResultSet
(
boolean
ordered
,
ResultSet
rs
,
String
[][]
data
)
throws
Exception
{
int
len
=
rs
.
getMetaData
().
getColumnCount
();
int
rows
=
data
.
length
;
if
(
rows
==
0
)
{
...
...
@@ -815,7 +822,7 @@ public abstract class TestBase {
return
true
;
}
String
[]
getData
(
ResultSet
rs
,
int
len
)
throws
SQLException
{
private
String
[]
getData
(
ResultSet
rs
,
int
len
)
throws
SQLException
{
String
[]
data
=
new
String
[
len
];
for
(
int
i
=
0
;
i
<
len
;
i
++)
{
data
[
i
]
=
rs
.
getString
(
i
+
1
);
...
...
@@ -825,7 +832,7 @@ public abstract class TestBase {
return
data
;
}
String
formatRow
(
String
[]
row
)
{
private
String
formatRow
(
String
[]
row
)
{
String
sb
=
""
;
for
(
int
i
=
0
;
i
<
row
.
length
;
i
++)
{
sb
+=
"{"
+
row
[
i
]
+
"}"
;
...
...
h2/src/test/org/h2/test/bench/BenchC.java
浏览文件 @
815b32a9
...
...
@@ -143,11 +143,11 @@ public class BenchC implements Bench {
trace
(
"load done"
);
}
void
trace
(
String
s
)
{
private
void
trace
(
String
s
)
{
action
=
s
;
}
void
trace
(
int
i
,
int
max
)
{
private
void
trace
(
int
i
,
int
max
)
{
db
.
trace
(
action
,
i
,
max
);
}
...
...
h2/src/test/org/h2/test/bench/BenchCRandom.java
浏览文件 @
815b32a9
...
...
@@ -17,16 +17,39 @@ public class BenchCRandom {
private
Random
random
=
new
Random
(
10
);
/**
* Get a non-uniform random integer value between min and max.
*
* @param a the bit mask
* @param min the minimum value
* @param max the maximum value
* @return the random value
*/
int
getNonUniform
(
int
a
,
int
min
,
int
max
)
{
int
c
=
0
;
return
(((
getInt
(
0
,
a
)
|
getInt
(
min
,
max
))
+
c
)
%
(
max
-
min
+
1
))
+
min
;
}
/**
* Get a random integer value between min and max.
*
* @param min the minimum value
* @param max the maximum value
* @return the random value
*/
int
getInt
(
int
min
,
int
max
)
{
return
max
<=
min
?
min
:
(
random
.
nextInt
(
max
-
min
)
+
min
);
}
/**
* Generate a boolean array with this many items set to true (randomly
* distributed).
*
* @param length the size of the array
* @param trueCount the number of true elements
* @return the boolean array
*/
boolean
[]
getBoolean
(
int
length
,
int
trueCount
)
{
boolean
[]
data
=
new
boolean
[
length
];
for
(
int
i
=
0
,
pos
;
i
<
trueCount
;
i
++)
{
...
...
@@ -38,6 +61,13 @@ public class BenchCRandom {
return
data
;
}
/**
* Replace a random part of the string with another text.
*
* @param text the original text
* @param replacement the replacement
* @return the patched string
*/
String
replace
(
String
text
,
String
replacement
)
{
int
pos
=
getInt
(
0
,
text
.
length
()
-
replacement
.
length
());
StringBuffer
buffer
=
new
StringBuffer
(
text
);
...
...
@@ -45,6 +75,13 @@ public class BenchCRandom {
return
buffer
.
toString
();
}
/**
* Get a random number string.
*
* @param min the minimum value
* @param max the maximum value
* @return the number string
*/
String
getNumberString
(
int
min
,
int
max
)
{
int
len
=
getInt
(
min
,
max
);
char
[]
buff
=
new
char
[
len
];
...
...
@@ -54,6 +91,11 @@ public class BenchCRandom {
return
new
String
(
buff
);
}
/**
* Get random address data.
*
* @return the address
*/
String
[]
getAddress
()
{
String
str1
=
getString
(
10
,
20
);
String
str2
=
getString
(
10
,
20
);
...
...
@@ -63,10 +105,23 @@ public class BenchCRandom {
return
new
String
[]
{
str1
,
str2
,
city
,
state
,
zip
};
}
/**
* Get a random string.
*
* @param min the minimum size
* @param max the maximum size
* @return the string
*/
String
getString
(
int
min
,
int
max
)
{
return
getString
(
getInt
(
min
,
max
));
}
/**
* Get a random string.
*
* @param len the size
* @return the string
*/
String
getString
(
int
len
)
{
char
[]
buff
=
new
char
[
len
];
for
(
int
i
=
0
;
i
<
len
;
i
++)
{
...
...
@@ -75,6 +130,12 @@ public class BenchCRandom {
return
new
String
(
buff
);
}
/**
* Generate a random permutation if the values 0 .. length.
*
* @param length the number of elements
* @return the random permutation
*/
int
[]
getPermutation
(
int
length
)
{
int
[]
data
=
new
int
[
length
];
for
(
int
i
=
0
;
i
<
length
;
i
++)
{
...
...
@@ -89,11 +150,23 @@ public class BenchCRandom {
return
data
;
}
/**
* Create a big decimal value.
*
* @param value the value
* @param scale the scale
* @return the big decimal object
*/
BigDecimal
getBigDecimal
(
int
value
,
int
scale
)
{
return
new
BigDecimal
(
new
BigInteger
(
String
.
valueOf
(
value
)),
scale
);
}
/**
* Generate a last name composed of three elements
*
* @param i the last name index
* @return the name
*/
String
getLastname
(
int
i
)
{
String
[]
n
=
{
"BAR"
,
"OUGHT"
,
"ABLE"
,
"PRI"
,
"PRES"
,
"ESE"
,
"ANTI"
,
"CALLY"
,
"ATION"
,
"EING"
};
...
...
h2/src/test/org/h2/test/bench/BenchCThread.java
浏览文件 @
815b32a9
...
...
@@ -38,7 +38,10 @@ public class BenchCThread {
this
.
random
=
random
;
warehouseId
=
random
.
getInt
(
1
,
bench
.
warehouses
);
}
/**
* Process the list of operations (a 'deck') in random order.
*/
void
process
()
throws
Exception
{
int
[]
deck
=
new
int
[]
{
OP_NEW_ORDER
,
OP_NEW_ORDER
,
OP_NEW_ORDER
,
OP_NEW_ORDER
,
OP_NEW_ORDER
,
OP_NEW_ORDER
,
OP_NEW_ORDER
,
...
...
h2/src/test/org/h2/test/bench/Database.java
浏览文件 @
815b32a9
...
...
@@ -13,6 +13,7 @@ import java.sql.DriverManager;
import
java.sql.PreparedStatement
;
import
java.sql.ResultSet
;
import
java.sql.ResultSetMetaData
;
import
java.sql.SQLException
;
import
java.sql.Statement
;
import
java.util.ArrayList
;
import
java.util.Iterator
;
...
...
@@ -49,22 +50,45 @@ class Database {
private
Object
serverDerby
;
private
boolean
serverHSQLDB
;
/**
* Get the database name.
*
* @return the database name
*/
String
getName
()
{
return
name
;
}
/**
* Get the total measured time.
*
* @return the time
*/
int
getTotalTime
()
{
return
totalTime
;
}
/**
* Get the result array.
*
* @return the result array
*/
ArrayList
getResults
()
{
return
results
;
}
/**
* Get the random number generator.
*
* @return the generator
*/
Random
getRandom
()
{
return
random
;
}
/**
* Start the server if the this is a remote connection.
*/
void
startServer
()
throws
Exception
{
if
(
url
.
startsWith
(
"jdbc:h2:tcp:"
))
{
serverH2
=
Server
.
createTcpServer
(
new
String
[
0
]).
start
();
...
...
@@ -90,6 +114,9 @@ class Database {
}
}
/**
* Stop the server if this is a remote connection.
*/
void
stopServer
()
throws
Exception
{
if
(
serverH2
!=
null
)
{
serverH2
.
stop
();
...
...
@@ -110,6 +137,14 @@ class Database {
}
}
/**
* Parse a database configuration and create a database object from it.
*
* @param test the test application
* @param id the database id
* @param dbString the configuration string
* @return a new database object with the given settings
*/
static
Database
parse
(
TestPerformance
test
,
int
id
,
String
dbString
)
{
try
{
StringTokenizer
tokenizer
=
new
StringTokenizer
(
dbString
,
","
);
...
...
@@ -133,8 +168,20 @@ class Database {
}
}
Connection
getConnection
()
throws
Exception
{
Connection
conn
=
DriverManager
.
getConnection
(
url
,
user
,
password
);
/**
* Get the database connection. The connection must be opened first.
*
* @return the connection
*/
Connection
getConnection
()
{
return
conn
;
}
/**
* Open a database connection.
*/
void
openConnection
()
throws
SQLException
{
conn
=
DriverManager
.
getConnection
(
url
,
user
,
password
);
if
(
url
.
startsWith
(
"jdbc:derby:"
))
{
// Derby: use higher cache size
Statement
stat
=
null
;
...
...
@@ -159,15 +206,13 @@ class Database {
JdbcUtils
.
closeSilently
(
stat
);
}
}
return
conn
;
}
void
openConnection
()
throws
Exception
{
conn
=
DriverManager
.
getConnection
(
url
,
user
,
password
);
stat
=
conn
.
createStatement
();
}
void
closeConnection
()
throws
Exception
{
/**
* Close the database connection.
*/
void
closeConnection
()
throws
SQLException
{
// if(!serverHSQLDB && url.startsWith("jdbc:hsqldb:")) {
// stat.execute("SHUTDOWN");
// }
...
...
@@ -176,7 +221,12 @@ class Database {
conn
=
null
;
}
public
void
setTranslations
(
Properties
prop
)
{
/**
* Initialize the SQL statement translation of this database.
*
* @param prop the properties with the translations to use
*/
void
setTranslations
(
Properties
prop
)
{
String
id
=
url
.
substring
(
"jdbc:"
.
length
());
id
=
id
.
substring
(
0
,
id
.
indexOf
(
':'
));
for
(
Iterator
it
=
prop
.
keySet
().
iterator
();
it
.
hasNext
();)
{
...
...
@@ -191,12 +241,18 @@ class Database {
}
}
PreparedStatement
prepare
(
String
sql
)
throws
Exception
{
/**
* Prepare a SQL statement.
*
* @param sql the SQL statement
* @return the prepared statement
*/
PreparedStatement
prepare
(
String
sql
)
throws
SQLException
{
sql
=
getSQL
(
sql
);
return
conn
.
prepareStatement
(
sql
);
}
p
ublic
String
getSQL
(
String
sql
)
{
p
rivate
String
getSQL
(
String
sql
)
{
for
(
int
i
=
0
;
i
<
replace
.
size
();
i
++)
{
String
[]
pair
=
(
String
[])
replace
.
get
(
i
);
String
pattern
=
pair
[
0
];
...
...
@@ -206,11 +262,21 @@ class Database {
return
sql
;
}
/**
* Start the benchmark.
*
* @param bench the benchmark
* @param action the action
*/
void
start
(
Bench
bench
,
String
action
)
{
this
.
action
=
bench
.
getName
()
+
": "
+
action
;
this
.
startTime
=
System
.
currentTimeMillis
();
}
/**
* This method is called when the test run ends. This will stop collecting
* data.
*/
void
end
()
{
long
time
=
System
.
currentTimeMillis
()
-
startTime
;
log
(
action
,
"ms"
,
(
int
)
time
);
...
...
@@ -219,6 +285,11 @@ class Database {
}
}
/**
* Drop a table. Errors are ignored.
*
* @param table the table name
*/
void
dropTable
(
String
table
)
{
try
{
update
(
"DROP TABLE "
+
table
);
...
...
@@ -227,13 +298,24 @@ class Database {
}
}
public
void
update
(
PreparedStatement
prep
,
String
trace
)
throws
Exception
{
/**
* Execute an SQL statement.
*
* @param prep the prepared statement
* @param trace the trace message
*/
void
update
(
PreparedStatement
prep
,
String
trace
)
throws
SQLException
{
test
.
trace
(
trace
);
prep
.
executeUpdate
();
executedStatements
++;
}
public
void
update
(
String
sql
)
throws
Exception
{
/**
* Execute an SQL statement.
*
* @param sql the SQL statement
*/
void
update
(
String
sql
)
throws
SQLException
{
sql
=
getSQL
(
sql
);
if
(
sql
.
trim
().
length
()
>
0
)
{
executedStatements
++;
...
...
@@ -243,18 +325,36 @@ class Database {
}
}
public
void
setAutoCommit
(
boolean
b
)
throws
Exception
{
/**
* Enable or disable auto-commit.
*
* @param b false to disable
*/
void
setAutoCommit
(
boolean
b
)
throws
SQLException
{
conn
.
setAutoCommit
(
b
);
}
public
void
commit
()
throws
Exception
{
/**
* Commit a transaction.
*/
void
commit
()
throws
SQLException
{
conn
.
commit
();
}
public
void
rollback
()
throws
Exception
{
/**
* Roll a transaction back.
*/
void
rollback
()
throws
SQLException
{
conn
.
rollback
();
}
/**
* Print trace information if trace is enabled.
*
* @param action the action
* @param i the current value
* @param max the maximum value
*/
void
trace
(
String
action
,
int
i
,
int
max
)
{
if
(
trace
)
{
long
time
=
System
.
currentTimeMillis
();
...
...
@@ -267,17 +367,37 @@ class Database {
}
}
/**
* If data collection is enabled, add the currently used memory size to the
* log.
*
* @param bench the benchmark
* @param action the action
*/
void
logMemory
(
Bench
bench
,
String
action
)
{
log
(
bench
.
getName
()
+
": "
+
action
,
"MB"
,
TestBase
.
getMemoryUsed
());
}
/**
* If data collection is enabled, add this information to the log.
*
* @param action the action
* @param scale the scale
* @param value the value
*/
void
log
(
String
action
,
String
scale
,
int
value
)
{
if
(
test
.
collect
)
{
results
.
add
(
new
Object
[]
{
action
,
scale
,
new
Integer
(
value
)
});
}
}
public
ResultSet
query
(
PreparedStatement
prep
)
throws
Exception
{
/**
* Execute a query.
*
* @param prep the prepared statement
* @return the result set
*/
ResultSet
query
(
PreparedStatement
prep
)
throws
SQLException
{
// long time = System.currentTimeMillis();
ResultSet
rs
=
prep
.
executeQuery
();
// time = System.currentTimeMillis() - time;
...
...
@@ -288,7 +408,12 @@ class Database {
return
rs
;
}
public
void
queryReadResult
(
PreparedStatement
prep
)
throws
Exception
{
/**
* Execute a query and read all rows.
*
* @param prep the prepared statement
*/
void
queryReadResult
(
PreparedStatement
prep
)
throws
SQLException
{
ResultSet
rs
=
prep
.
executeQuery
();
ResultSetMetaData
meta
=
rs
.
getMetaData
();
int
columnCount
=
meta
.
getColumnCount
();
...
...
@@ -299,16 +424,22 @@ class Database {
}
}
/**
* Get the number of executed statements.
*
* @return the number of statements
*/
int
getExecutedStatements
()
{
return
executedStatements
;
}
public
int
getId
()
{
/**
* Get the database id.
*
* @return the id
*/
int
getId
()
{
return
id
;
}
public
Connection
getCurrentConnection
()
{
return
conn
;
}
}
h2/src/test/org/h2/test/bench/TestPerformance.java
浏览文件 @
815b32a9
...
...
@@ -27,7 +27,14 @@ import org.h2.util.JdbcUtils;
*/
public
class
TestPerformance
{
/**
* Whether data should be collected.
*/
boolean
collect
;
/**
* The flag used to enable or disable trace messages.
*/
boolean
trace
;
/**
...
...
@@ -238,6 +245,11 @@ public class TestPerformance {
bench
.
runTest
();
}
/**
* Print a message to system out if trace is enabled.
*
* @param s the message
*/
void
trace
(
String
s
)
{
if
(
trace
)
{
System
.
out
.
println
(
s
);
...
...
h2/src/test/org/h2/test/coverage/Tokenizer.java
浏览文件 @
815b32a9
...
...
@@ -15,7 +15,11 @@ import java.io.Reader;
*/
public
class
Tokenizer
{
/**
* This token type means no more tokens are available.
*/
static
final
int
TYPE_EOF
=
-
1
;
private
static
final
int
TYPE_WORD
=
-
2
;
private
static
final
int
TYPE_NOTHING
=
-
3
;
private
static
final
byte
WHITESPACE
=
1
;
...
...
@@ -78,6 +82,9 @@ public class Tokenizer {
return
i
;
}
/**
* Initialize the tokenizer.
*/
void
initToken
()
{
buffer
=
new
StringBuffer
();
}
...
...
@@ -91,6 +98,11 @@ public class Tokenizer {
buffer
.
append
((
char
)
i
);
}
/**
* Read the next token and get the token type.
*
* @return the token type
*/
int
nextToken
()
throws
IOException
{
byte
[]
ct
=
charTypes
;
int
c
;
...
...
h2/src/test/org/h2/test/db/Db.java
浏览文件 @
815b32a9
...
...
@@ -179,8 +179,14 @@ public class Db {
}
}
static
Error
convert
(
Exception
e
)
{
return
new
Error
(
"Error: "
+
e
.
toString
(),
e
);
/**
* Convert a checked exception to a runtime exception.
*
* @param e the checked exception
* @return the runtime exception
*/
static
RuntimeException
convert
(
Exception
e
)
{
return
new
RuntimeException
(
e
.
toString
(),
e
);
}
public
void
setAutoCommit
(
boolean
autoCommit
)
{
...
...
h2/src/test/org/h2/test/db/TestDeadlock.java
浏览文件 @
815b32a9
...
...
@@ -66,7 +66,12 @@ public class TestDeadlock extends TestBase {
* that execute a statement.
*/
abstract
class
DoIt
extends
Thread
{
/**
* The operation to execute.
*/
abstract
void
execute
()
throws
SQLException
;
public
void
run
()
{
try
{
execute
();
...
...
h2/src/test/org/h2/test/server/WebClient.java
浏览文件 @
815b32a9
...
...
@@ -21,6 +21,12 @@ public class WebClient {
private
String
sessionId
;
/**
* Open an URL and get the HTML data.
*
* @param url the HTTP URL
* @return the HTML as a string
*/
String
get
(
String
url
)
throws
IOException
{
HttpURLConnection
connection
=
(
HttpURLConnection
)
new
URL
(
url
).
openConnection
();
connection
.
setRequestMethod
(
"GET"
);
...
...
@@ -36,10 +42,15 @@ public class WebClient {
return
result
;
}
void
readSessionId
(
String
result
)
{
int
idx
=
result
.
indexOf
(
"jsessionid="
);
String
id
=
result
.
substring
(
idx
+
"jsessionid="
.
length
());
for
(
int
i
=
0
;
i
<
result
.
length
();
i
++)
{
/**
* Read the session ID from a URL.
*
* @param url the URL
*/
void
readSessionId
(
String
url
)
{
int
idx
=
url
.
indexOf
(
"jsessionid="
);
String
id
=
url
.
substring
(
idx
+
"jsessionid="
.
length
());
for
(
int
i
=
0
;
i
<
url
.
length
();
i
++)
{
char
ch
=
id
.
charAt
(
i
);
if
(!
Character
.
isLetterOrDigit
(
ch
))
{
id
=
id
.
substring
(
0
,
i
);
...
...
@@ -49,6 +60,13 @@ public class WebClient {
this
.
sessionId
=
id
;
}
/**
* Read the specified HTML page.
*
* @param url the base URL
* @param page the page to read
* @return the HTML page
*/
String
get
(
String
url
,
String
page
)
throws
IOException
{
if
(
sessionId
!=
null
)
{
if
(
page
.
indexOf
(
'?'
)
<
0
)
{
...
...
h2/src/test/org/h2/test/synth/OutputCatcher.java
浏览文件 @
815b32a9
...
...
@@ -23,6 +23,12 @@ class OutputCatcher extends Thread {
this
.
in
=
in
;
}
/**
* Read a line from the output.
*
* @param wait the maximum number of milliseconds to wait
* @return the line
*/
String
readLine
(
long
wait
)
{
long
start
=
System
.
currentTimeMillis
();
while
(
true
)
{
...
...
h2/src/test/org/h2/test/synth/TestHalt.java
浏览文件 @
815b32a9
...
...
@@ -13,7 +13,6 @@ import java.io.InputStream;
import
java.io.PrintWriter
;
import
java.sql.Connection
;
import
java.sql.DriverManager
;
import
java.sql.SQLException
;
import
java.text.SimpleDateFormat
;
import
java.util.Date
;
import
java.util.Random
;
...
...
@@ -97,14 +96,30 @@ public abstract class TestHalt extends TestBase {
private
int
errorId
;
private
int
sequenceId
;
/**
* Initialize the test.
*/
abstract
void
testInit
()
throws
Exception
;
/**
* Check if the database is consistent after a simulated database crash.
*/
abstract
void
testCheckAfterCrash
()
throws
Exception
;
/**
* Wait for some time after the application has been started.
*/
abstract
void
testWaitAfterAppStart
()
throws
Exception
;
/**
* Start the application.
*/
abstract
void
appStart
()
throws
Exception
;
/**
* Run the application.
* @throws Exception
*/
abstract
void
appRun
()
throws
Exception
;
public
void
test
()
throws
Exception
{
...
...
@@ -272,53 +287,55 @@ public abstract class TestHalt extends TestBase {
}
}
public
Connection
getConnectionHSQLDB
()
throws
Exception
{
File
lock
=
new
File
(
"test.lck"
);
while
(
lock
.
exists
())
{
lock
.
delete
();
System
.
gc
();
}
Class
.
forName
(
"org.hsqldb.jdbcDriver"
);
return
DriverManager
.
getConnection
(
"jdbc:hsqldb:test"
,
"sa"
,
""
);
}
//
public Connection getConnectionHSQLDB() throws Exception {
//
File lock = new File("test.lck");
//
while (lock.exists()) {
//
lock.delete();
//
System.gc();
//
}
//
Class.forName("org.hsqldb.jdbcDriver");
//
return DriverManager.getConnection("jdbc:hsqldb:test", "sa", "");
//
}
public
Connection
getConnectionDerby
()
throws
Exception
{
File
lock
=
new
File
(
"test3/db.lck"
);
while
(
lock
.
exists
())
{
lock
.
delete
();
System
.
gc
();
}
Class
.
forName
(
"org.apache.derby.jdbc.EmbeddedDriver"
).
newInstance
();
try
{
return
DriverManager
.
getConnection
(
"jdbc:derby:test3;create=true"
,
"sa"
,
"sa"
);
}
catch
(
SQLException
e
)
{
Exception
e2
=
e
;
do
{
e
.
printStackTrace
();
e
=
e
.
getNextException
();
}
while
(
e
!=
null
);
throw
e2
;
}
}
// public Connection getConnectionDerby() throws Exception {
// File lock = new File("test3/db.lck");
// while (lock.exists()) {
// lock.delete();
// System.gc();
// }
// Class.forName("org.apache.derby.jdbc.EmbeddedDriver").newInstance();
// try {
// return DriverManager.getConnection(
// "jdbc:derby:test3;create=true", "sa", "sa");
// } catch (SQLException e) {
// Exception e2 = e;
// do {
// e.printStackTrace();
// e = e.getNextException();
// } while (e != null);
// throw e2;
// }
// }
void
disconnectHSQLDB
()
{
try
{
conn
.
createStatement
().
execute
(
"SHUTDOWN"
);
}
catch
(
Exception
e
)
{
// ignore
}
// super.disconnect();
}
//
void disconnectHSQLDB() {
//
try {
//
conn.createStatement().execute("SHUTDOWN");
//
} catch (Exception e) {
//
// ignore
//
}
//
// super.disconnect();
//
}
void
disconnectDerby
()
{
// super.disconnect();
try
{
Class
.
forName
(
"org.apache.derby.jdbc.EmbeddedDriver"
);
DriverManager
.
getConnection
(
"jdbc:derby:;shutdown=true"
,
"sa"
,
"sa"
);
}
catch
(
Exception
e
)
{
// ignore
}
}
// void disconnectDerby() {
// // super.disconnect();
// try {
// Class.forName("org.apache.derby.jdbc.EmbeddedDriver");
// DriverManager.getConnection(
// "jdbc:derby:;shutdown=true", "sa", "sa");
// } catch (Exception e) {
// // ignore
// }
// }
/**
* Create a random string with the specified length.
...
...
h2/src/test/org/h2/test/synth/sql/Column.java
浏览文件 @
815b32a9
...
...
@@ -30,7 +30,7 @@ class Column {
private
boolean
isPrimaryKey
;
// TODO test isAutoincrement;
Column
(
TestSynth
config
)
{
private
Column
(
TestSynth
config
)
{
this
.
config
=
config
;
}
...
...
@@ -68,7 +68,14 @@ class Column {
}
}
public
static
boolean
isConditionType
(
TestSynth
config
,
int
type
)
{
/**
* Check if this data type supports comparisons for this database.
*
* @param config the configuration
* @param type the SQL type
* @return true if the value can be used in conditions
*/
static
boolean
isConditionType
(
TestSynth
config
,
int
type
)
{
switch
(
config
.
getMode
())
{
case
TestSynth
.
H2
:
case
TestSynth
.
H2_MEM
:
...
...
@@ -103,7 +110,7 @@ class Column {
}
}
String
getTypeName
()
{
private
String
getTypeName
()
{
switch
(
type
)
{
case
Types
.
INTEGER
:
return
"INT"
;
...
...
@@ -152,7 +159,7 @@ class Column {
}
}
public
String
getCreateSQL
()
{
String
getCreateSQL
()
{
String
sql
=
name
+
" "
+
getTypeName
();
if
(!
isNullable
)
{
sql
+=
" NOT NULL"
;
...
...
@@ -160,19 +167,25 @@ class Column {
return
sql
;
}
public
String
getName
()
{
String
getName
()
{
return
name
;
}
public
Value
getRandomValue
()
{
Value
getRandomValue
()
{
return
Value
.
getRandom
(
config
,
type
,
precision
,
scale
,
isNullable
);
}
public
Value
getRandomValueNotNull
()
{
return
Value
.
getRandom
(
config
,
type
,
precision
,
scale
,
false
);
}
public
static
Column
getRandomColumn
(
TestSynth
config
)
{
// Value getRandomValueNotNull() {
// return Value.getRandom(config, type, precision, scale, false);
// }
/**
* Generate a random column.
*
* @param config the configuration
* @return the column
*/
static
Column
getRandomColumn
(
TestSynth
config
)
{
Column
column
=
new
Column
(
config
);
column
.
name
=
"C_"
+
config
.
randomIdentifier
();
int
randomType
;
...
...
@@ -191,19 +204,24 @@ class Column {
return
column
;
}
public
boolean
is
PrimaryKey
()
{
boolean
get
PrimaryKey
()
{
return
isPrimaryKey
;
}
public
void
setPrimaryKey
(
boolean
b
)
{
void
setPrimaryKey
(
boolean
b
)
{
isPrimaryKey
=
b
;
}
public
void
setNullable
(
boolean
b
)
{
void
setNullable
(
boolean
b
)
{
isNullable
=
b
;
}
public
int
getType
()
{
/**
* The the column type.
*
* @return the type
*/
int
getType
()
{
return
type
;
}
...
...
h2/src/test/org/h2/test/synth/sql/Command.java
浏览文件 @
815b32a9
差异被折叠。
点击展开。
h2/src/test/org/h2/test/synth/sql/DbState.java
浏览文件 @
815b32a9
...
...
@@ -13,8 +13,8 @@ import java.util.ArrayList;
*/
public
class
DbState
implements
DbInterface
{
boolean
connected
;
boolean
autoCommit
;
private
boolean
connected
;
private
boolean
autoCommit
;
private
TestSynth
config
;
private
ArrayList
tables
=
new
ArrayList
();
private
ArrayList
indexes
=
new
ArrayList
();
...
...
@@ -80,6 +80,11 @@ public class DbState implements DbInterface {
// nothing to do
}
/**
* Get a random table.
*
* @return the table
*/
Table
randomTable
()
{
if
(
tables
.
size
()
==
0
)
{
return
null
;
...
...
@@ -91,5 +96,9 @@ public class DbState implements DbInterface {
public
void
end
()
{
// nothing to do
}
public
String
toString
()
{
return
"autocommit: "
+
autoCommit
+
" connected: "
+
connected
;
}
}
h2/src/test/org/h2/test/synth/sql/Expression.java
浏览文件 @
815b32a9
...
...
@@ -13,19 +13,24 @@ import java.util.ArrayList;
* Represents an expression.
*/
public
class
Expression
{
boolean
isCondition
;
private
String
sql
;
private
TestSynth
config
;
private
Command
command
;
private
Expression
(
TestSynth
config
,
Command
command
,
boolean
isCondition
)
{
private
Expression
(
TestSynth
config
,
Command
command
)
{
this
.
config
=
config
;
this
.
isCondition
=
isCondition
;
this
.
command
=
command
;
sql
=
""
;
}
/**
* Create a random select list.
*
* @param config the configuration
* @param command the command
* @return the select list
*/
static
String
[]
getRandomSelectList
(
TestSynth
config
,
Command
command
)
{
if
(
config
.
random
().
getBoolean
(
30
))
{
return
new
String
[]
{
"*"
};
...
...
@@ -47,16 +52,23 @@ public class Expression {
return
list
;
}
/**
* Generate a random condition.
*
* @param config the configuration
* @param command the command
* @return the random condition expression
*/
static
Expression
getRandomCondition
(
TestSynth
config
,
Command
command
)
{
Expression
condition
=
new
Expression
(
config
,
command
,
true
);
Expression
condition
=
new
Expression
(
config
,
command
);
if
(
config
.
random
().
getBoolean
(
50
))
{
condition
.
create
();
}
return
condition
;
}
static
Expression
getRandomExpression
(
TestSynth
config
,
Command
command
)
{
Expression
expression
=
new
Expression
(
config
,
command
,
false
);
private
static
Expression
getRandomExpression
(
TestSynth
config
,
Command
command
)
{
Expression
expression
=
new
Expression
(
config
,
command
);
String
alias
=
command
.
getRandomTableAlias
();
Column
column
=
command
.
getTable
(
alias
).
getRandomConditionColumn
();
if
(
column
==
null
)
{
...
...
@@ -72,12 +84,27 @@ public class Expression {
sql
=
v
.
getSQL
();
}
/**
* Generate a random join condition.
*
* @param config the configuration
* @param command the command
* @param alias the alias name
* @return the join condition
*/
static
Expression
getRandomJoinOn
(
TestSynth
config
,
Command
command
,
String
alias
)
{
Expression
expression
=
new
Expression
(
config
,
command
,
true
);
Expression
expression
=
new
Expression
(
config
,
command
);
expression
.
createJoinComparison
(
alias
);
return
expression
;
}
/**
* Generate a random sort order list.
*
* @param config the configuration
* @param command the command
* @return the ORDER BY list
*/
static
String
getRandomOrder
(
TestSynth
config
,
Command
command
)
{
int
len
=
config
.
random
().
getLog
(
6
);
String
sql
=
""
;
...
...
@@ -104,6 +131,11 @@ public class Expression {
return
sql
;
}
/**
* Get the SQL snippet of this expression.
*
* @return the SQL snippet
*/
String
getSQL
()
{
return
sql
.
trim
().
length
()
==
0
?
null
:
sql
.
trim
();
}
...
...
@@ -250,11 +282,7 @@ public class Expression {
}
}
boolean
isEmpty
()
{
return
sql
==
null
||
sql
.
trim
().
length
()
==
0
;
}
void
createExpression
(
String
alias
,
Column
type
)
{
private
void
createExpression
(
String
alias
,
Column
type
)
{
boolean
op
=
is
(
20
);
// no null values if there is an operation
boolean
allowNull
=
!
op
;
...
...
@@ -288,7 +316,7 @@ public class Expression {
}
}
void
createTerm
(
String
alias
,
Column
type
,
boolean
allowNull
)
{
private
void
createTerm
(
String
alias
,
Column
type
,
boolean
allowNull
)
{
int
dt
=
type
.
getType
();
if
(
is
(
5
)
&&
(
dt
==
Types
.
INTEGER
)
||
(
dt
==
Types
.
DECIMAL
))
{
sql
+=
" - "
;
...
...
h2/src/test/org/h2/test/synth/sql/Index.java
浏览文件 @
815b32a9
...
...
@@ -10,10 +10,10 @@ package org.h2.test.synth.sql;
* Represents an index.
*/
public
class
Index
{
Table
table
;
String
name
;
Column
[]
columns
;
boolean
unique
;
private
Table
table
;
private
String
name
;
private
Column
[]
columns
;
private
boolean
unique
;
Index
(
Table
table
,
String
name
,
Column
[]
columns
,
boolean
unique
)
{
this
.
table
=
table
;
...
...
@@ -22,11 +22,11 @@ public class Index {
this
.
unique
=
unique
;
}
public
String
getName
()
{
String
getName
()
{
return
name
;
}
public
String
getCreateSQL
()
{
String
getCreateSQL
()
{
String
sql
=
"CREATE "
;
if
(
unique
)
{
sql
+=
"UNIQUE "
;
...
...
@@ -42,11 +42,11 @@ public class Index {
return
sql
;
}
public
String
getDropSQL
()
{
String
getDropSQL
()
{
return
"DROP INDEX "
+
name
;
}
public
Table
getTable
()
{
Table
getTable
()
{
return
table
;
}
...
...
h2/src/test/org/h2/test/synth/sql/Result.java
浏览文件 @
815b32a9
...
...
@@ -128,27 +128,27 @@ class Result implements Comparable {
}
}
public
void
log
()
{
switch
(
type
)
{
case
SUCCESS:
System
.
out
.
println
(
"> ok"
);
break
;
case
EXCEPTION:
System
.
out
.
println
(
"> exception"
);
break
;
case
INT:
if
(
intValue
==
0
)
{
System
.
out
.
println
(
"> ok"
);
}
else
{
System
.
out
.
println
(
"> update count: "
+
intValue
);
}
break
;
case
RESULT_SET:
System
.
out
.
println
(
"> rs "
+
rows
.
size
());
break
;
default
:
}
System
.
out
.
println
();
}
//
public void log() {
//
switch (type) {
//
case SUCCESS:
//
System.out.println("> ok");
//
break;
//
case EXCEPTION:
//
System.out.println("> exception");
//
break;
//
case INT:
//
if (intValue == 0) {
//
System.out.println("> ok");
//
} else {
//
System.out.println("> update count: " + intValue);
//
}
//
break;
//
case RESULT_SET:
//
System.out.println("> rs " + rows.size());
//
break;
//
default:
//
}
//
System.out.println();
//
}
}
h2/src/test/org/h2/test/synth/sql/Table.java
浏览文件 @
815b32a9
...
...
@@ -24,7 +24,13 @@ class Table {
this
.
config
=
config
;
}
public
static
Table
newRandomTable
(
TestSynth
config
)
{
/**
* Create a new random table.
*
* @param config the configuration
* @return the table
*/
static
Table
newRandomTable
(
TestSynth
config
)
{
Table
table
=
new
Table
(
config
);
table
.
name
=
"T_"
+
config
.
randomIdentifier
();
...
...
@@ -52,7 +58,7 @@ class Table {
Column
pk
=
null
;
do
{
pk
=
table
.
columns
[
config
.
random
().
getInt
(
len
)];
}
while
(
pk
.
is
PrimaryKey
());
}
while
(
pk
.
get
PrimaryKey
());
table
.
primaryKeys
[
i
]
=
pk
;
pk
.
setPrimaryKey
(
true
);
pk
.
setNullable
(
false
);
...
...
@@ -61,7 +67,12 @@ class Table {
return
table
;
}
public
Index
newRandomIndex
()
{
/**
* Create a new random index.
*
* @return the index
*/
Index
newRandomIndex
()
{
String
indexName
=
"I_"
+
config
.
randomIdentifier
();
int
len
=
config
.
random
().
getLog
(
getColumnCount
()
-
1
)
+
1
;
boolean
unique
=
config
.
random
().
getBoolean
(
50
);
...
...
@@ -70,11 +81,21 @@ class Table {
return
index
;
}
public
String
getDropSQL
()
{
/**
* Get the DROP TABLE statement for this table.
*
* @return the SQL statement
*/
String
getDropSQL
()
{
return
"DROP TABLE "
+
name
;
}
public
String
getCreateSQL
()
{
/**
* Get the CREATE TABLE statement for this table.
*
* @return the SQL statement
*/
String
getCreateSQL
()
{
String
sql
=
"CREATE "
;
if
(
temporary
)
{
if
(
globalTemporary
)
{
...
...
@@ -111,7 +132,12 @@ class Table {
return
sql
;
}
public
String
getInsertSQL
(
Column
[]
c
,
Value
[]
v
)
{
/**
* Get the INSERT statement for this table.
*
* @return the SQL statement
*/
String
getInsertSQL
(
Column
[]
c
,
Value
[]
v
)
{
String
sql
=
"INSERT INTO "
+
name
;
if
(
c
!=
null
)
{
sql
+=
"("
;
...
...
@@ -134,11 +160,21 @@ class Table {
return
sql
;
}
public
String
getName
()
{
/**
* Get the table name.
*
* @return the name
*/
String
getName
()
{
return
name
;
}
public
Column
getRandomConditionColumn
()
{
/**
* Get a random column that can be used in a condition.
*
* @return the column
*/
Column
getRandomConditionColumn
()
{
ArrayList
list
=
new
ArrayList
();
for
(
int
i
=
0
;
i
<
columns
.
length
;
i
++)
{
if
(
Column
.
isConditionType
(
config
,
columns
[
i
].
getType
()))
{
...
...
@@ -151,15 +187,21 @@ class Table {
return
(
Column
)
list
.
get
(
config
.
random
().
getInt
(
list
.
size
()));
}
public
Column
getRandomColumn
()
{
Column
getRandomColumn
()
{
return
columns
[
config
.
random
().
getInt
(
columns
.
length
)];
}
public
int
getColumnCount
()
{
int
getColumnCount
()
{
return
columns
.
length
;
}
public
Column
getRandomColumnOfType
(
int
type
)
{
/**
* Get a random column of the specified type.
*
* @param type the type
* @return the column or null if no such column was found
*/
Column
getRandomColumnOfType
(
int
type
)
{
ArrayList
list
=
new
ArrayList
();
for
(
int
i
=
0
;
i
<
columns
.
length
;
i
++)
{
if
(
columns
[
i
].
getType
()
==
type
)
{
...
...
@@ -172,7 +214,13 @@ class Table {
return
(
Column
)
list
.
get
(
config
.
random
().
getInt
(
list
.
size
()));
}
public
Column
[]
getRandomColumns
(
int
len
)
{
/**
* Get a number of random column from this table.
*
* @param len the column count
* @return the columns
*/
Column
[]
getRandomColumns
(
int
len
)
{
int
[]
index
=
new
int
[
columns
.
length
];
for
(
int
i
=
0
;
i
<
columns
.
length
;
i
++)
{
index
[
i
]
=
i
;
...
...
@@ -190,15 +238,25 @@ class Table {
return
c
;
}
public
Column
[]
getColumns
()
{
Column
[]
getColumns
()
{
return
columns
;
}
public
void
addIndex
(
Index
index
)
{
/**
* Add this index to the table.
*
* @param index the index to add
*/
void
addIndex
(
Index
index
)
{
indexes
.
add
(
index
);
}
public
void
removeIndex
(
Index
index
)
{
/**
* Remove an index from the table.
*
* @param index the index to remove
*/
void
removeIndex
(
Index
index
)
{
indexes
.
remove
(
index
);
}
}
h2/src/test/org/h2/test/synth/sql/TestSynth.java
浏览文件 @
815b32a9
...
...
@@ -21,7 +21,30 @@ public class TestSynth extends TestBase {
// TODO hsqldb: call 1||null should return 1 but returns null
// TODO hsqldb: call mod(1) should return invalid parameter count
static
final
int
H2
=
0
,
H2_MEM
=
1
,
HSQLDB
=
2
,
MYSQL
=
3
,
POSTGRESQL
=
4
;
/**
* A H2 database connection.
*/
static
final
int
H2
=
0
;
/**
* An in-memory H2 database connection.
*/
static
final
int
H2_MEM
=
1
;
/**
* An HSQLDB database connection.
*/
static
final
int
HSQLDB
=
2
;
/**
* A MySQL database connection.
*/
static
final
int
MYSQL
=
3
;
/**
* A PostgreSQL database connection.
*/
static
final
int
POSTGRESQL
=
4
;
private
static
final
String
DIR
=
"synth"
;
private
DbState
db
=
new
DbState
(
this
);
...
...
@@ -32,14 +55,30 @@ public class TestSynth extends TestBase {
private
boolean
stopImmediately
;
private
int
mode
;
/**
* Check whether this database is of the specified type.
*
* @param isType the database type
* @return true if it is
*/
boolean
is
(
int
isType
)
{
return
mode
==
isType
;
}
/**
* Get the random number generator.
*
* @return the random number generator
*/
RandomGen
random
()
{
return
random
;
}
/**
* Get a random identifier.
*
* @return the random identifier
*/
String
randomIdentifier
()
{
int
len
=
random
.
getLog
(
8
)
+
2
;
while
(
true
)
{
...
...
@@ -193,17 +232,28 @@ public class TestSynth extends TestBase {
}
}
/**
* Get a random table.
*
* @return the table
*/
Table
randomTable
()
{
return
db
.
randomTable
();
}
/**
* Print this message if the log is enabled.
*
* @param id the id
* @param s the message
*/
void
log
(
int
id
,
String
s
)
{
if
(
showLog
&&
id
==
0
)
{
System
.
out
.
println
(
s
);
}
}
public
int
getMode
()
{
int
getMode
()
{
return
mode
;
}
...
...
h2/src/test/org/h2/test/synth/sql/Value.java
浏览文件 @
815b32a9
...
...
@@ -31,6 +31,11 @@ public class Value {
this
.
data
=
data
;
}
/**
* Convert the value to a SQL string.
*
* @return the SQL string
*/
String
getSQL
()
{
if
(
data
==
null
)
{
return
"NULL"
;
...
...
@@ -127,6 +132,14 @@ public class Value {
return
buff
.
toString
();
}
/**
* Read a value from a result set.
*
* @param config the configuration
* @param rs the result set
* @param index the column index
* @return the value
*/
static
Value
read
(
TestSynth
config
,
ResultSet
rs
,
int
index
)
throws
SQLException
{
ResultSetMetaData
meta
=
rs
.
getMetaData
();
Object
data
;
...
...
@@ -184,6 +197,16 @@ public class Value {
return
new
Value
(
config
,
type
,
data
);
}
/**
* Generate a random value.
*
* @param config the configuration
* @param type the value type
* @param precision the precision
* @param scale the scale
* @param mayBeNull if the value may be null or not
* @return the value
*/
static
Value
getRandom
(
TestSynth
config
,
int
type
,
int
precision
,
int
scale
,
boolean
mayBeNull
)
{
Object
data
;
if
(
mayBeNull
&&
config
.
random
().
getBoolean
(
20
))
{
...
...
@@ -263,48 +286,49 @@ public class Value {
return
new
BigDecimal
(
buff
.
toString
());
}
int
compareTo
(
Object
o
)
{
Value
v
=
(
Value
)
o
;
if
(
type
!=
v
.
type
)
{
throw
new
Error
(
"compare "
+
type
+
" "
+
v
.
type
+
" "
+
data
+
" "
+
v
.
data
);
}
if
(
data
==
null
)
{
return
(
v
.
data
==
null
)
?
0
:
-
1
;
}
else
if
(
v
.
data
==
null
)
{
return
1
;
}
switch
(
type
)
{
case
Types
.
DECIMAL
:
return
((
BigDecimal
)
data
).
compareTo
((
BigDecimal
)
v
.
data
);
case
Types
.
BLOB
:
case
Types
.
VARBINARY
:
case
Types
.
BINARY
:
return
compareBytes
((
byte
[])
data
,
(
byte
[])
v
.
data
);
case
Types
.
CLOB
:
case
Types
.
VARCHAR
:
return
data
.
toString
().
compareTo
(
v
.
data
.
toString
());
case
Types
.
DATE
:
return
((
Date
)
data
).
compareTo
((
Date
)
v
.
data
);
case
Types
.
INTEGER
:
return
((
Integer
)
data
).
compareTo
((
Integer
)
v
.
data
);
default
:
throw
new
Error
(
"type="
+
type
);
}
}
// private int compareTo(Object o) {
// Value v = (Value) o;
// if (type != v.type) {
// throw new Error("compare " + type +
// " " + v.type + " " + data + " " + v.data);
// }
// if (data == null) {
// return (v.data == null) ? 0 : -1;
// } else if (v.data == null) {
// return 1;
// }
// switch (type) {
// case Types.DECIMAL:
// return ((BigDecimal) data).compareTo((BigDecimal) v.data);
// case Types.BLOB:
// case Types.VARBINARY:
// case Types.BINARY:
// return compareBytes((byte[]) data, (byte[]) v.data);
// case Types.CLOB:
// case Types.VARCHAR:
// return data.toString().compareTo(v.data.toString());
// case Types.DATE:
// return ((Date) data).compareTo((Date) v.data);
// case Types.INTEGER:
// return ((Integer) data).compareTo((Integer) v.data);
// default:
// throw new Error("type=" + type);
// }
// }
static
int
compareBytes
(
byte
[]
a
,
byte
[]
b
)
{
int
al
=
a
.
length
,
bl
=
b
.
length
;
int
len
=
Math
.
min
(
al
,
bl
);
for
(
int
i
=
0
;
i
<
len
;
i
++)
{
int
x
=
a
[
i
]
&
0xff
;
int
y
=
b
[
i
]
&
0xff
;
if
(
x
==
y
)
{
continue
;
}
return
x
>
y
?
1
:
-
1
;
}
return
al
==
bl
?
0
:
al
>
bl
?
1
:
-
1
;
}
// private
static int compareBytes(byte[] a, byte[] b) {
//
int al = a.length, bl = b.length;
//
int len = Math.min(al, bl);
//
for (int i = 0; i < len; i++) {
//
int x = a[i] & 0xff;
//
int y = b[i] & 0xff;
//
if (x == y) {
//
continue;
//
}
//
return x > y ? 1 : -1;
//
}
//
return al == bl ? 0 : al > bl ? 1 : -1;
//
}
public
String
toString
()
{
return
getSQL
();
...
...
h2/src/test/org/h2/test/synth/thread/TestMultiThread.java
浏览文件 @
815b32a9
...
...
@@ -16,25 +16,51 @@ import org.h2.test.TestBase;
*/
abstract
class
TestMultiThread
extends
Thread
{
/**
* The base object.
*/
TestMulti
base
;
/**
* The random number generator.
*/
Random
random
=
new
Random
();
TestMultiThread
(
TestMulti
base
)
{
this
.
base
=
base
;
}
/**
* Execute statements that need to be executed before starting the thread.
* This includes CREATE TABLE statements.
*/
abstract
void
first
()
throws
SQLException
;
/**
* The main operation to perform. This method is called in a loop.
*/
abstract
void
operation
()
throws
SQLException
;
/**
* Execute statements before entering the loop, but after starting the
* thread.
*/
abstract
void
begin
()
throws
SQLException
;
/**
* This method is called once after the test is stopped.
*/
abstract
void
end
()
throws
SQLException
;
/**
* This method is called once after all threads have been stopped.
* @throws Exception
*/
abstract
void
finalTest
()
throws
Exception
;
public
void
run
()
{
try
{
begin
();
while
(!
base
.
stop
)
{
operation
();
}
...
...
h2/src/test/org/h2/test/trace/Arg.java
浏览文件 @
815b32a9
...
...
@@ -49,6 +49,9 @@ class Arg {
return
quote
(
clazz
,
getValue
());
}
/**
* Calculate the value if this is a statement.
*/
void
execute
()
throws
Exception
{
if
(
stat
!=
null
)
{
obj
=
stat
.
execute
();
...
...
@@ -65,7 +68,7 @@ class Arg {
return
obj
;
}
String
quote
(
Class
clazz
,
Object
value
)
{
private
String
quote
(
Class
clazz
,
Object
value
)
{
if
(
value
==
null
)
{
return
null
;
}
else
if
(
clazz
==
String
.
class
)
{
...
...
h2/src/test/org/h2/test/trace/Parser.java
浏览文件 @
815b32a9
...
...
@@ -45,6 +45,13 @@ class Parser {
read
();
}
/**
* Parse a Java statement.
*
* @param player the player
* @param line the statement text
* @return the statement
*/
static
Statement
parseStatement
(
Player
player
,
String
line
)
{
Parser
p
=
new
Parser
(
player
,
line
);
p
.
parseStatement
();
...
...
h2/src/test/org/h2/test/trace/Player.java
浏览文件 @
815b32a9
...
...
@@ -111,6 +111,11 @@ public class Player {
}
}
/**
* Write trace information if trace is enabled.
*
* @param s the message to write
*/
void
trace
(
String
s
)
{
if
(
trace
)
{
System
.
out
.
println
(
s
);
...
...
@@ -131,7 +136,14 @@ public class Player {
trace
(
"error: "
+
e
.
toString
());
}
}
/**
* Get the class for the given class name.
* Only a limited set of classes is supported.
*
* @param className the class name
* @return the class
*/
static
Class
getClass
(
String
className
)
{
for
(
int
i
=
0
;
i
<
IMPORTED_PACKAGES
.
length
;
i
++)
{
try
{
...
...
@@ -143,10 +155,22 @@ public class Player {
throw
new
Error
(
"Class not found: "
+
className
);
}
void
assign
(
String
objectName
,
Object
obj
)
{
objects
.
put
(
objectName
,
obj
);
/**
* Assign an object to a variable.
*
* @param variableName the variable name
* @param obj the object
*/
void
assign
(
String
variableName
,
Object
obj
)
{
objects
.
put
(
variableName
,
obj
);
}
/**
* Get an object.
*
* @param name the variable name
* @return the object
*/
Object
getObject
(
String
name
)
{
return
objects
.
get
(
name
);
}
...
...
h2/src/test/org/h2/test/trace/Statement.java
浏览文件 @
815b32a9
...
...
@@ -45,6 +45,11 @@ class Statement {
this
.
player
=
player
;
}
/**
* Execute the statement.
*
* @return the object returned if this was a method call
*/
Object
execute
()
throws
Exception
{
if
(
object
==
player
)
{
// there was an exception previously
...
...
@@ -120,19 +125,38 @@ class Statement {
return
returnClass
;
}
/**
* This statement is an assignment.
*
* @param className the class of the variable
* @param variableName the variable name
*/
void
setAssign
(
String
className
,
String
variableName
)
{
this
.
assignment
=
true
;
this
.
assignClass
=
className
;
this
.
assignVariable
=
variableName
;
}
/**
* This statement is a static method call.
*
* @param className the class name
*/
void
setStaticCall
(
String
className
)
{
this
.
staticCall
=
true
;
this
.
staticCallClass
=
className
;
}
void
setMethodCall
(
String
objectName
,
Object
object
,
String
methodName
)
{
this
.
objectName
=
objectName
;
/**
* This statement is a method call, and the result is assigned to a
* variable.
*
* @param variableName the variable name
* @param object the object
* @param methodName the method name
*/
void
setMethodCall
(
String
variableName
,
Object
object
,
String
methodName
)
{
this
.
objectName
=
variableName
;
this
.
object
=
object
;
this
.
methodName
=
methodName
;
}
...
...
h2/src/test/org/h2/test/unit/FtpClient.java
浏览文件 @
815b32a9
...
...
@@ -39,6 +39,12 @@ public class FtpClient {
// don't allow construction
}
/**
* Open an FTP connection.
*
* @param url the FTP URL
* @return the ftp client object
*/
static
FtpClient
open
(
String
url
)
throws
IOException
{
FtpClient
client
=
new
FtpClient
();
client
.
connect
(
url
);
...
...
@@ -77,6 +83,12 @@ public class FtpClient {
writer
.
flush
();
}
/**
* Login to this FTP server (USER, PASS, SYST, SITE, STRU F, TYPE I).
*
* @param userName the user name
* @param password the password
*/
void
login
(
String
userName
,
String
password
)
throws
IOException
{
send
(
"USER "
+
userName
);
readCode
(
331
);
...
...
@@ -92,6 +104,9 @@ public class FtpClient {
readCode
(
200
);
}
/**
* Close the connection (QUIT).
*/
void
close
()
throws
IOException
{
if
(
socket
!=
null
)
{
send
(
"QUIT"
);
...
...
@@ -100,42 +115,75 @@ public class FtpClient {
}
}
/**
* Change the working directory (CWD).
*
* @param dir the new directory
*/
void
changeWorkingDirectory
(
String
dir
)
throws
IOException
{
send
(
"CWD "
+
dir
);
readCode
(
250
);
}
/**
* Change to the parent directory (CDUP).
*/
void
changeDirectoryUp
()
throws
IOException
{
send
(
"CDUP"
);
readCode
(
250
);
}
/**
* Delete a file (DELE).
*
* @param fileName the name of the file to delete
*/
void
delete
(
String
fileName
)
throws
IOException
{
send
(
"DELE "
+
fileName
);
readCode
(
250
);
}
/**
* Create a directory (MKD).
*
* @param dir the directory to create
*/
void
makeDirectory
(
String
dir
)
throws
IOException
{
send
(
"MKD "
+
dir
);
readCode
(
257
);
}
/**
* Change the transfer mode (MODE).
*
* @param mode the mode
*/
void
mode
(
String
mode
)
throws
IOException
{
send
(
"MODE "
+
mode
);
readCode
(
200
);
}
/**
* Change the modified time of a file (MDTM).
*
* @param fileName the file name
*/
void
modificationTime
(
String
fileName
)
throws
IOException
{
send
(
"MDTM "
+
fileName
);
readCode
(
213
);
}
/**
* Issue a no-operation statement (NOOP).
*/
void
noOperation
()
throws
IOException
{
send
(
"NOOP"
);
readCode
(
200
);
}
/**
* Print the working directory (PWD).
*/
String
printWorkingDirectory
()
throws
IOException
{
send
(
"PWD"
);
readCode
(
257
);
...
...
@@ -177,6 +225,12 @@ public class FtpClient {
outData
=
socketData
.
getOutputStream
();
}
/**
* Rename a file (RNFR / RNTO).
*
* @param fromFileName the old file name
* @param toFileName the new file name
*/
void
rename
(
String
fromFileName
,
String
toFileName
)
throws
IOException
{
send
(
"RNFR "
+
fromFileName
);
readCode
(
350
);
...
...
@@ -184,6 +238,13 @@ public class FtpClient {
readCode
(
250
);
}
/**
* Read a file ([REST] RETR).
*
* @param fileName the file name
* @param out the output stream
* @param restartAt restart at the given position (0 if no restart is required).
*/
void
retrieve
(
String
fileName
,
OutputStream
out
,
long
restartAt
)
throws
IOException
{
passive
();
if
(
restartAt
>
0
)
{
...
...
@@ -195,11 +256,22 @@ public class FtpClient {
readCode
(
226
);
}
/**
* Remove a directory (RMD).
*
* @param dir the directory to remove
*/
void
removeDirectory
(
String
dir
)
throws
IOException
{
send
(
"RMD "
+
dir
);
readCode
(
250
);
}
/**
* Get the size of a file (SIZE).
*
* @param fileName the file name
* @return the size
*/
long
size
(
String
fileName
)
throws
IOException
{
send
(
"SIZE "
+
fileName
);
readCode
(
250
);
...
...
@@ -207,6 +279,12 @@ public class FtpClient {
return
size
;
}
/**
* Store a file (STOR).
*
* @param fileName the file name
* @param in the input stream
*/
void
store
(
String
fileName
,
InputStream
in
)
throws
IOException
{
passive
();
send
(
"STOR "
+
fileName
);
...
...
@@ -215,6 +293,12 @@ public class FtpClient {
readCode
(
226
);
}
/**
* Get the directory listing (NLST).
*
* @param dir the directory
* @return the listing
*/
String
nameList
(
String
dir
)
throws
IOException
{
passive
();
send
(
"NLST "
+
dir
);
...
...
@@ -226,6 +310,12 @@ public class FtpClient {
return
new
String
(
data
);
}
/**
* Get the directory listing (LIST).
*
* @param dir the directory
* @return the listing
*/
String
list
(
String
dir
)
throws
IOException
{
passive
();
send
(
"LIST "
+
dir
);
...
...
h2/src/test/org/h2/test/unit/TestExit.java
浏览文件 @
815b32a9
差异被折叠。
点击展开。
h2/src/tools/org/h2/build/Build.java
浏览文件 @
815b32a9
差异被折叠。
点击展开。
h2/src/tools/org/h2/build/BuildBase.java
浏览文件 @
815b32a9
差异被折叠。
点击展开。
h2/src/tools/org/h2/build/doc/dictionary.txt
浏览文件 @
815b32a9
差异被折叠。
点击展开。
h2/src/tools/org/h2/build/doclet/Doclet.java
浏览文件 @
815b32a9
差异被折叠。
点击展开。
h2/src/tools/org/h2/build/i18n/PropertiesToUTF8.java
浏览文件 @
815b32a9
差异被折叠。
点击展开。
h2/src/tools/org/h2/build/indexer/Page.java
浏览文件 @
815b32a9
差异被折叠。
点击展开。
h2/src/tools/org/h2/build/indexer/Weight.java
浏览文件 @
815b32a9
差异被折叠。
点击展开。
h2/src/tools/org/h2/build/indexer/Word.java
浏览文件 @
815b32a9
差异被折叠。
点击展开。
h2/src/tools/org/h2/dev/net/PgTcpRedirect.java
浏览文件 @
815b32a9
差异被折叠。
点击展开。
h2/src/tools/org/h2/dev/util/Base64.java
浏览文件 @
815b32a9
差异被折叠。
点击展开。
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论