Skip to content
项目
群组
代码片段
帮助
正在加载...
帮助
为 GitLab 提交贡献
登录/注册
切换导航
H
h2database
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
分枝图
比较
统计图
议题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
计划
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
分枝图
统计图
创建新议题
作业
提交
议题看板
打开侧边栏
Administrator
h2database
Commits
68bcd1cb
提交
68bcd1cb
authored
12月 15, 2006
作者:
Thomas Mueller
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
--no commit message
--no commit message
上级
3e2897c4
全部展开
隐藏空白字符变更
内嵌
并排
正在显示
19 个修改的文件
包含
2840 行增加
和
0 行删除
+2840
-0
TestMultiConn.java
h2/src/test/org/h2/test/db/TestMultiConn.java
+183
-0
TestMultiDimension.java
h2/src/test/org/h2/test/db/TestMultiDimension.java
+101
-0
TestMultiThread.java
h2/src/test/org/h2/test/db/TestMultiThread.java
+86
-0
TestOpenClose.java
h2/src/test/org/h2/test/db/TestOpenClose.java
+141
-0
TestOptimizations.java
h2/src/test/org/h2/test/db/TestOptimizations.java
+211
-0
TestPowerOff.java
h2/src/test/org/h2/test/db/TestPowerOff.java
+275
-0
TestReadOnly.java
h2/src/test/org/h2/test/db/TestReadOnly.java
+63
-0
TestRights.java
h2/src/test/org/h2/test/db/TestRights.java
+188
-0
TestRunscript.java
h2/src/test/org/h2/test/db/TestRunscript.java
+111
-0
TestSQLInjection.java
h2/src/test/org/h2/test/db/TestSQLInjection.java
+89
-0
TestScript.java
h2/src/test/org/h2/test/db/TestScript.java
+355
-0
TestScriptSimple.java
h2/src/test/org/h2/test/db/TestScriptSimple.java
+62
-0
TestSequence.java
h2/src/test/org/h2/test/db/TestSequence.java
+48
-0
TestSpaceReuse.java
h2/src/test/org/h2/test/db/TestSpaceReuse.java
+39
-0
TestSpeed.java
h2/src/test/org/h2/test/db/TestSpeed.java
+404
-0
TestTempTables.java
h2/src/test/org/h2/test/db/TestTempTables.java
+67
-0
TestTransaction.java
h2/src/test/org/h2/test/db/TestTransaction.java
+194
-0
TestTriggersConstraints.java
h2/src/test/org/h2/test/db/TestTriggersConstraints.java
+142
-0
TestTwoPhaseCommit.java
h2/src/test/org/h2/test/db/TestTwoPhaseCommit.java
+81
-0
没有找到文件。
h2/src/test/org/h2/test/db/TestMultiConn.java
0 → 100644
浏览文件 @
68bcd1cb
/*
* Copyright 2004-2006 H2 Group. Licensed under the H2 License, Version 1.0 (http://h2database.com/html/license.html).
* Initial Developer: H2 Group
*/
package
org
.
h2
.
test
.
db
;
import
java.sql.Connection
;
import
java.sql.ResultSet
;
import
java.sql.SQLException
;
import
java.sql.Statement
;
import
org.h2.api.DatabaseEventListener
;
import
org.h2.test.TestBase
;
/**
* @author Thomas
*/
public
class
TestMultiConn
extends
TestBase
implements
DatabaseEventListener
{
public
void
test
()
throws
Exception
{
// testCommitRollback();
try
{
testConcurrentOpen
();
}
catch
(
SQLException
e
)
{
e
.
printStackTrace
();
System
.
exit
(
0
);
}
// testThreeThreads();
}
private
static
int
wait
;
private
void
testThreeThreads
()
throws
Exception
{
deleteDb
(
"multiConn"
);
final
Connection
conn1
=
getConnection
(
"multiConn"
);
final
Connection
conn2
=
getConnection
(
"multiConn"
);
final
Connection
conn3
=
getConnection
(
"multiConn"
);
conn1
.
setAutoCommit
(
false
);
conn2
.
setAutoCommit
(
false
);
conn3
.
setAutoCommit
(
false
);
final
Statement
s1
=
conn1
.
createStatement
();
final
Statement
s2
=
conn2
.
createStatement
();
final
Statement
s3
=
conn3
.
createStatement
();
s1
.
execute
(
"CREATE TABLE TEST1(ID INT)"
);
s2
.
execute
(
"CREATE TABLE TEST2(ID INT)"
);
s3
.
execute
(
"CREATE TABLE TEST3(ID INT)"
);
s1
.
execute
(
"INSERT INTO TEST1 VALUES(1)"
);
s2
.
execute
(
"INSERT INTO TEST2 VALUES(2)"
);
s3
.
execute
(
"INSERT INTO TEST3 VALUES(3)"
);
s1
.
execute
(
"SET LOCK_TIMEOUT 1000"
);
s2
.
execute
(
"SET LOCK_TIMEOUT 1000"
);
s3
.
execute
(
"SET LOCK_TIMEOUT 1000"
);
Thread
t1
=
new
Thread
(
new
Runnable
()
{
public
void
run
()
{
try
{
s3
.
execute
(
"INSERT INTO TEST2 VALUES(4)"
);
conn3
.
commit
();
}
catch
(
SQLException
e
)
{
e
.
printStackTrace
();
}
}
});
t1
.
start
();
Thread
.
sleep
(
20
);
Thread
t2
=
new
Thread
(
new
Runnable
()
{
public
void
run
()
{
try
{
s2
.
execute
(
"INSERT INTO TEST1 VALUES(5)"
);
conn2
.
commit
();
}
catch
(
SQLException
e
)
{
e
.
printStackTrace
();
}
}
});
t2
.
start
();
Thread
.
sleep
(
20
);
conn1
.
commit
();
t2
.
join
(
100
);
t1
.
join
(
100
);
ResultSet
rs
=
s1
.
executeQuery
(
"SELECT * FROM TEST1 ORDER BY ID"
);
rs
.
next
();
check
(
rs
.
getInt
(
1
),
1
);
rs
.
next
();
check
(
rs
.
getInt
(
1
),
5
);
checkFalse
(
rs
.
next
());
conn1
.
close
();
conn2
.
close
();
conn3
.
close
();
}
private
void
testConcurrentOpen
()
throws
Exception
{
if
(
config
.
memory
)
{
return
;
}
deleteDb
(
"multiConn"
);
Connection
conn
=
getConnection
(
"multiConn"
);
conn
.
createStatement
().
execute
(
"CREATE TABLE TEST(ID INT PRIMARY KEY, NAME VARCHAR)"
);
conn
.
createStatement
().
execute
(
"INSERT INTO TEST VALUES(0, 'Hello'), (1, 'World')"
);
conn
.
createStatement
().
execute
(
"SHUTDOWN"
);
conn
.
close
();
final
String
listener
=
getClass
().
getName
();
Runnable
r
=
new
Runnable
()
{
public
void
run
()
{
try
{
Connection
c1
=
getConnection
(
"multiConn;DATABASE_EVENT_LISTENER='"
+
listener
+
"';file_lock=socket"
);
c1
.
close
();
}
catch
(
Exception
e
)
{
e
.
printStackTrace
();
}
}
};
Thread
thread
=
new
Thread
(
r
);
thread
.
start
();
Thread
.
sleep
(
10
);
Connection
c2
=
getConnection
(
"multiConn;file_lock=socket"
);
c2
.
close
();
thread
.
join
();
}
public
void
diskSpaceIsLow
(
long
stillAvailable
)
throws
SQLException
{
}
public
void
exceptionThrown
(
SQLException
e
)
{
}
public
void
setProgress
(
int
state
,
String
name
,
int
x
,
int
max
)
{
while
(
wait
>
0
)
{
try
{
Thread
.
sleep
(
wait
);
wait
=
0
;
}
catch
(
InterruptedException
e
)
{
e
.
printStackTrace
();
}
}
}
public
void
closingDatabase
()
{
}
private
void
testCommitRollback
()
throws
Exception
{
deleteDb
(
"multiConn"
);
Connection
c1
=
getConnection
(
"multiConn"
);
Connection
c2
=
getConnection
(
"multiConn"
);
c1
.
setAutoCommit
(
false
);
c2
.
setAutoCommit
(
false
);
Statement
s1
=
c1
.
createStatement
();
s1
.
execute
(
"DROP TABLE IF EXISTS MULTI_A"
);
s1
.
execute
(
"CREATE TABLE MULTI_A(ID INT, NAME VARCHAR(255))"
);
s1
.
execute
(
"INSERT INTO MULTI_A VALUES(0, '0-insert-A')"
);
Statement
s2
=
c2
.
createStatement
();
s1
.
execute
(
"DROP TABLE IF EXISTS MULTI_B"
);
s1
.
execute
(
"CREATE TABLE MULTI_B(ID INT, NAME VARCHAR(255))"
);
s2
.
execute
(
"INSERT INTO MULTI_B VALUES(0, '1-insert-B')"
);
c1
.
commit
();
c2
.
rollback
();
s1
.
execute
(
"INSERT INTO MULTI_A VALUES(1, '0-insert-C')"
);
s2
.
execute
(
"INSERT INTO MULTI_B VALUES(1, '1-insert-D')"
);
c1
.
rollback
();
c2
.
commit
();
c1
.
close
();
c2
.
close
();
if
(!
config
.
memory
)
{
Connection
conn
=
getConnection
(
"multiConn"
);
ResultSet
rs
;
rs
=
conn
.
createStatement
().
executeQuery
(
"SELECT * FROM MULTI_A ORDER BY ID"
);
rs
.
next
();
check
(
rs
.
getString
(
"NAME"
),
"0-insert-A"
);
checkFalse
(
rs
.
next
());
rs
=
conn
.
createStatement
().
executeQuery
(
"SELECT * FROM MULTI_B ORDER BY ID"
);
rs
.
next
();
check
(
rs
.
getString
(
"NAME"
),
"1-insert-D"
);
checkFalse
(
rs
.
next
());
conn
.
close
();
}
}
public
void
init
(
String
url
)
{
}
}
h2/src/test/org/h2/test/db/TestMultiDimension.java
0 → 100644
浏览文件 @
68bcd1cb
/*
* Copyright 2004-2006 H2 Group. Licensed under the H2 License, Version 1.0 (http://h2database.com/html/license.html).
* Initial Developer: H2 Group
*/
package
org
.
h2
.
test
.
db
;
import
java.sql.Connection
;
import
java.sql.PreparedStatement
;
import
java.sql.ResultSet
;
import
java.sql.Statement
;
import
java.util.Random
;
import
org.h2.test.TestBase
;
import
org.h2.tools.MultiDimension
;
public
class
TestMultiDimension
extends
TestBase
{
public
void
test
()
throws
Exception
{
Random
rand
=
new
Random
(
10
);
for
(
int
i
=
0
;
i
<
1000
;
i
++)
{
int
x
=
rand
.
nextInt
(
1000
),
y
=
rand
.
nextInt
(
1000
),
z
=
rand
.
nextInt
(
1000
);
MultiDimension
tool
=
MultiDimension
.
getInstance
();
long
xyz
=
tool
.
interleave
(
new
int
[]{
x
,
y
,
z
});
check
(
x
,
tool
.
deinterleave
(
xyz
,
3
,
0
));
check
(
y
,
tool
.
deinterleave
(
xyz
,
3
,
1
));
check
(
z
,
tool
.
deinterleave
(
xyz
,
3
,
2
));
}
deleteDb
(
"multiDimension"
);
Connection
conn
;
conn
=
getConnection
(
"multiDimension"
);
Statement
stat
=
conn
.
createStatement
();
stat
.
execute
(
"CREATE ALIAS MAP FOR \""
+
getClass
().
getName
()
+
".interleave\""
);
stat
.
execute
(
"CREATE TABLE TEST(X INT NOT NULL, Y INT NOT NULL, Z INT NOT NULL, XYZ BIGINT AS MAP(X, Y, Z), DATA VARCHAR)"
);
stat
.
execute
(
"CREATE INDEX IDX_X ON TEST(X, Y, Z)"
);
stat
.
execute
(
"CREATE INDEX IDX_XYZ ON TEST(XYZ)"
);
PreparedStatement
prep
=
conn
.
prepareStatement
(
"INSERT INTO TEST(X, Y, Z, DATA) VALUES(?, ?, ?, ?)"
);
// a reasonable value to see the performance difference is 60
int
max
=
10
;
long
time
=
System
.
currentTimeMillis
();
for
(
int
x
=
0
;
x
<
max
;
x
++)
{
for
(
int
y
=
0
;
y
<
max
;
y
++)
{
for
(
int
z
=
0
;
z
<
max
;
z
++)
{
long
t2
=
System
.
currentTimeMillis
();
if
(
t2
-
time
>
1000
)
{
int
percent
=
(
int
)(
100.0
*
((
double
)
x
*
x
*
x
)
/
((
double
)
max
*
max
*
max
));
trace
(
percent
+
"%"
);
time
=
t2
;
try
{
Thread
.
sleep
(
10
);
}
catch
(
Exception
e
)
{}
}
prep
.
setInt
(
1
,
x
);
prep
.
setInt
(
2
,
y
);
prep
.
setInt
(
3
,
z
);
prep
.
setString
(
4
,
"Test data"
);
prep
.
execute
();
}
}
}
for
(
int
i
=
0
;
i
<
50
;
i
++)
{
int
size
=
rand
.
nextInt
(
max
/
10
);
int
minX
=
rand
.
nextInt
(
max
-
size
);
int
minY
=
rand
.
nextInt
(
max
-
size
);
int
minZ
=
rand
.
nextInt
(
max
-
size
);
int
maxX
=
minX
+
size
,
maxY
=
minY
+
size
,
maxZ
=
minZ
+
size
;
long
time1
=
System
.
currentTimeMillis
();
String
query1
=
MultiDimension
.
getInstance
().
getMultiDimensionalQuery
(
"TEST"
,
"XYZ"
,
new
String
[]{
"X"
,
"Y"
,
"Z"
},
new
int
[]{
minX
,
minY
,
minZ
},
new
int
[]{
minX
+
size
,
minY
+
size
,
minZ
+
size
});
ResultSet
rs1
=
conn
.
createStatement
().
executeQuery
(
query1
+
" ORDER BY X, Y, Z"
);
time1
=
System
.
currentTimeMillis
()
-
time1
;
long
time2
=
System
.
currentTimeMillis
();
String
query2
=
"SELECT * FROM TEST WHERE "
+
"X BETWEEN "
+
minX
+
" AND "
+
maxX
+
" AND "
+
"Y BETWEEN "
+
minY
+
" AND "
+
maxY
+
" AND "
+
"Z BETWEEN "
+
minZ
+
" AND "
+
maxZ
;
PreparedStatement
prep2
=
conn
.
prepareStatement
(
query2
+
" ORDER BY X, Y, Z"
);
ResultSet
rs2
=
prep2
.
executeQuery
();
time2
=
System
.
currentTimeMillis
()
-
time2
;
while
(
rs1
.
next
())
{
check
(
rs2
.
next
());
check
(
rs1
.
getInt
(
1
),
rs2
.
getInt
(
1
));
check
(
rs1
.
getInt
(
2
),
rs2
.
getInt
(
2
));
}
checkFalse
(
rs2
.
next
());
trace
(
"t1="
+
time1
+
" t2="
+
time2
+
" size="
+
size
);
}
conn
.
close
();
}
public
static
long
interleave
(
int
x
,
int
y
,
int
z
)
{
return
MultiDimension
.
getInstance
().
interleave
(
new
int
[]{
x
,
y
,
z
});
}
}
h2/src/test/org/h2/test/db/TestMultiThread.java
0 → 100644
浏览文件 @
68bcd1cb
/*
* Copyright 2004-2006 H2 Group. Licensed under the H2 License, Version 1.0 (http://h2database.com/html/license.html).
* Initial Developer: H2 Group
*/
package
org
.
h2
.
test
.
db
;
import
java.sql.Connection
;
import
java.sql.PreparedStatement
;
import
java.sql.ResultSet
;
import
java.sql.Statement
;
import
java.util.Random
;
import
org.h2.test.TestAll
;
import
org.h2.test.TestBase
;
public
class
TestMultiThread
extends
TestBase
implements
Runnable
{
private
boolean
stop
;
private
TestMultiThread
parent
;
private
Random
random
;
private
Connection
conn
;
private
Statement
stat
;
public
TestMultiThread
()
{
}
private
TestMultiThread
(
TestAll
config
,
TestMultiThread
parent
)
throws
Exception
{
this
.
config
=
config
;
this
.
parent
=
parent
;
random
=
new
Random
();
conn
=
getConnection
();
stat
=
conn
.
createStatement
();
}
public
void
test
()
throws
Exception
{
Connection
conn
=
getConnection
();
Statement
stat
=
conn
.
createStatement
();
stat
.
execute
(
"CREATE TABLE TEST(ID IDENTITY, NAME VARCHAR)"
);
int
len
=
getSize
(
10
,
200
);
Thread
[]
threads
=
new
Thread
[
len
];
for
(
int
i
=
0
;
i
<
len
;
i
++)
{
threads
[
i
]
=
new
Thread
(
new
TestMultiThread
(
config
,
this
));
}
for
(
int
i
=
0
;
i
<
len
;
i
++)
{
threads
[
i
].
start
();
}
int
sleep
=
getSize
(
400
,
10000
);
Thread
.
sleep
(
sleep
);
this
.
stop
=
true
;
for
(
int
i
=
0
;
i
<
len
;
i
++)
{
threads
[
i
].
join
();
}
ResultSet
rs
=
stat
.
executeQuery
(
"SELECT COUNT(*) FROM TEST"
);
rs
.
next
();
trace
(
"max id="
+
rs
.
getInt
(
1
));
conn
.
close
();
}
Connection
getConnection
()
throws
Exception
{
return
getConnection
(
"jdbc:h2:mem:multiThread"
);
}
public
void
run
()
{
try
{
while
(!
parent
.
stop
)
{
stat
.
execute
(
"SELECT COUNT(*) FROM TEST"
);
stat
.
execute
(
"INSERT INTO TEST VALUES(NULL, 'Hi')"
);
PreparedStatement
prep
=
conn
.
prepareStatement
(
"UPDATE TEST SET NAME='Hello' WHERE ID=?"
);
prep
.
setInt
(
1
,
random
.
nextInt
(
10000
));
prep
.
execute
();
prep
=
conn
.
prepareStatement
(
"SELECT * FROM TEST WHERE ID=?"
);
prep
.
setInt
(
1
,
random
.
nextInt
(
10000
));
ResultSet
rs
=
prep
.
executeQuery
();
while
(
rs
.
next
())
{
rs
.
getString
(
"NAME"
);
}
}
conn
.
close
();
}
catch
(
Exception
e
)
{
e
.
printStackTrace
();
System
.
exit
(
0
);
}
}
}
h2/src/test/org/h2/test/db/TestOpenClose.java
0 → 100644
浏览文件 @
68bcd1cb
/*
* Copyright 2004-2006 H2 Group. Licensed under the H2 License, Version 1.0 (http://h2database.com/html/license.html).
* Initial Developer: H2 Group
*/
package
org
.
h2
.
test
.
db
;
import
java.sql.*
;
import
org.h2.api.DatabaseEventListener
;
import
org.h2.test.TestBase
;
public
class
TestOpenClose
extends
TestBase
implements
DatabaseEventListener
{
int
nextId
=
10
;
public
static
void
main
(
String
[]
a
)
throws
Exception
{
new
TestOpenClose
().
test
();
}
public
void
test
()
throws
Exception
{
testCase
();
testReconnectFast
();
}
private
void
testReconnectFast
()
throws
Exception
{
deleteDb
(
BASE_DIR
,
"openClose"
);
String
url
=
"jdbc:h2:"
+
BASE_DIR
+
"/openClose;DATABASE_EVENT_LISTENER='"
+
TestOpenClose
.
class
.
getName
()+
"'"
;
Connection
conn
=
DriverManager
.
getConnection
(
url
,
"sa"
,
"sa"
);
Statement
stat
=
conn
.
createStatement
();
try
{
stat
.
execute
(
"CREATE TABLE TEST(ID IDENTITY, NAME VARCHAR)"
);
stat
.
execute
(
"SET MAX_MEMORY_UNDO 100000"
);
stat
.
execute
(
"CREATE INDEX IDXNAME ON TEST(NAME)"
);
stat
.
execute
(
"INSERT INTO TEST SELECT X, X || ' Data' FROM SYSTEM_RANGE(1, 1000)"
);
}
catch
(
SQLException
e
)
{
// ok
}
stat
.
close
();
conn
.
close
();
conn
=
DriverManager
.
getConnection
(
url
,
"sa"
,
"sa"
);
stat
=
conn
.
createStatement
();
ResultSet
rs
=
stat
.
executeQuery
(
"SELECT * FROM DUAL"
);
if
(
rs
.
next
())
{
rs
.
getString
(
1
);
}
rs
.
close
();
stat
.
close
();
conn
.
close
();
conn
=
DriverManager
.
getConnection
(
url
,
"sa"
,
"sa"
);
stat
=
conn
.
createStatement
();
// stat.execute("SET DB_CLOSE_DELAY 0");
stat
.
executeUpdate
(
"SHUTDOWN"
);
stat
.
close
();
conn
.
close
();
}
void
testCase
()
throws
Exception
{
Class
.
forName
(
"org.h2.Driver"
);
deleteDb
(
BASE_DIR
,
"openClose"
);
final
String
url
=
"jdbc:h2:"
+
BASE_DIR
+
"/openClose;FILE_LOCK=NO"
;
Connection
conn
=
DriverManager
.
getConnection
(
url
,
"sa"
,
""
);
conn
.
createStatement
().
execute
(
"drop table employee if exists"
);
conn
.
createStatement
().
execute
(
"create table employee(id int primary key, name varchar, salary int)"
);
conn
.
close
();
int
len
=
this
.
getSize
(
200
,
4000
);
Thread
[]
threads
=
new
Thread
[
len
];
for
(
int
i
=
0
;
i
<
len
;
i
++)
{
threads
[
i
]
=
new
Thread
()
{
public
void
run
()
{
try
{
Connection
conn
=
DriverManager
.
getConnection
(
url
,
"sa"
,
""
);
PreparedStatement
prep
=
conn
.
prepareStatement
(
"insert into employee values(?, ?, 0)"
);
int
id
=
getNextId
();
prep
.
setInt
(
1
,
id
);
prep
.
setString
(
2
,
"emp "
+
id
);
prep
.
execute
();
conn
.
close
();
}
catch
(
Throwable
e
)
{
// e.printStackTrace();
System
.
out
.
println
(
"FAIL: "
+
e
.
toString
());
}
}
};
threads
[
i
].
start
();
}
// for(int i=0; i<len; i++) {
// threads[i].start();
// }
for
(
int
i
=
0
;
i
<
len
;
i
++)
{
threads
[
i
].
join
();
}
conn
=
DriverManager
.
getConnection
(
url
,
"sa"
,
""
);
ResultSet
rs
=
conn
.
createStatement
().
executeQuery
(
"select count(*) from employee"
);
rs
.
next
();
check
(
rs
.
getInt
(
1
),
len
);
conn
.
close
();
}
synchronized
int
getNextId
()
{
return
nextId
++;
}
public
void
diskSpaceIsLow
(
long
stillAvailable
)
throws
SQLException
{
throw
new
SQLException
(
"unexpected"
);
}
public
void
exceptionThrown
(
SQLException
e
)
{
throw
new
Error
(
"unexpected: "
+
e
);
}
public
void
setProgress
(
int
state
,
String
name
,
int
current
,
int
max
)
{
String
stateName
;
switch
(
state
)
{
case
STATE_SCAN_FILE:
stateName
=
"Scan "
+
name
+
" "
+
current
+
"/"
+
max
;
if
(
current
>
0
)
{
throw
new
Error
(
"unexpected: "
+
stateName
);
}
break
;
case
STATE_CREATE_INDEX:
stateName
=
"Create Index "
+
name
+
" "
+
current
+
"/"
+
max
;
if
(!
"SYS"
.
equals
(
name
))
{
throw
new
Error
(
"unexpected: "
+
stateName
);
}
break
;
case
STATE_RECOVER:
stateName
=
"Recover "
+
current
+
"/"
+
max
;
break
;
default
:
stateName
=
"?"
;
}
// System.out.println(": " + stateName);
}
public
void
closingDatabase
()
{
}
public
void
init
(
String
url
)
{
}
}
h2/src/test/org/h2/test/db/TestOptimizations.java
0 → 100644
浏览文件 @
68bcd1cb
/*
* Copyright 2004-2006 H2 Group. Licensed under the H2 License, Version 1.0 (http://h2database.com/html/license.html).
* Initial Developer: H2 Group
*/
package
org
.
h2
.
test
.
db
;
import
java.sql.Connection
;
import
java.sql.PreparedStatement
;
import
java.sql.ResultSet
;
import
java.sql.Statement
;
import
java.util.ArrayList
;
import
java.util.HashMap
;
import
java.util.Random
;
import
java.util.TreeSet
;
import
org.h2.test.TestBase
;
public
class
TestOptimizations
extends
TestBase
{
public
void
test
()
throws
Exception
{
if
(
config
.
networked
)
{
return
;
}
testQueryCacheSpeed
();
testQueryCache
(
true
);
testQueryCache
(
false
);
testIn
();
testMinMaxCountOptimization
(
true
);
testMinMaxCountOptimization
(
false
);
}
private
void
testQueryCacheSpeed
()
throws
Exception
{
deleteDb
(
"optimizations"
);
Connection
conn
=
getConnection
(
"optimizations"
);
Statement
stat
=
conn
.
createStatement
();
testQuerySpeed
(
stat
,
"select sum(x) from system_range(1, 10000) a where a.x in (select b.x from system_range(1, 30) b)"
);
testQuerySpeed
(
stat
,
"select sum(a.n), sum(b.x) from system_range(1, 100) b, (select sum(x) n from system_range(1, 4000)) a"
);
conn
.
close
();
}
private
void
testQuerySpeed
(
Statement
stat
,
String
sql
)
throws
Exception
{
stat
.
execute
(
"set OPTIMIZE_REUSE_RESULTS 0"
);
stat
.
execute
(
sql
);
long
time
=
System
.
currentTimeMillis
();
stat
.
execute
(
sql
);
time
=
System
.
currentTimeMillis
()
-
time
;
stat
.
execute
(
"set OPTIMIZE_REUSE_RESULTS 1"
);
stat
.
execute
(
sql
);
long
time2
=
System
.
currentTimeMillis
();
stat
.
execute
(
sql
);
time2
=
System
.
currentTimeMillis
()
-
time2
;
if
(
time2
>
time
)
{
error
(
"not optimized: "
+
time
+
" optimized: "
+
time2
+
" sql:"
+
sql
);
}
}
private
void
testQueryCache
(
boolean
optimize
)
throws
Exception
{
deleteDb
(
"optimizations"
);
Connection
conn
=
getConnection
(
"optimizations"
);
Statement
stat
=
conn
.
createStatement
();
if
(
optimize
)
{
stat
.
execute
(
"set OPTIMIZE_REUSE_RESULTS 1"
);
}
else
{
stat
.
execute
(
"set OPTIMIZE_REUSE_RESULTS 0"
);
}
stat
.
execute
(
"create table test(id int)"
);
stat
.
execute
(
"create table test2(id int)"
);
stat
.
execute
(
"insert into test values(1), (1), (2)"
);
stat
.
execute
(
"insert into test2 values(1)"
);
PreparedStatement
prep
=
conn
.
prepareStatement
(
"select * from test where id = (select id from test2)"
);
ResultSet
rs1
=
prep
.
executeQuery
();
rs1
.
next
();
check
(
rs1
.
getInt
(
1
),
1
);
rs1
.
next
();
check
(
rs1
.
getInt
(
1
),
1
);
checkFalse
(
rs1
.
next
());
stat
.
execute
(
"update test2 set id = 2"
);
ResultSet
rs2
=
prep
.
executeQuery
();
rs2
.
next
();
check
(
rs2
.
getInt
(
1
),
2
);
conn
.
close
();
}
private
void
testMinMaxCountOptimization
(
boolean
memory
)
throws
Exception
{
deleteDb
(
"optimizations"
);
Connection
conn
=
getConnection
(
"optimizations"
);
Statement
stat
=
conn
.
createStatement
();
stat
.
execute
(
"create "
+(
memory
?
"memory"
:
""
)
+
" table test(id int primary key, value int)"
);
stat
.
execute
(
"create index idxvalueid on test(value, id);"
);
int
len
=
getSize
(
1000
,
10000
);
HashMap
map
=
new
HashMap
();
TreeSet
set
=
new
TreeSet
();
Random
random
=
new
Random
(
1
);
for
(
int
i
=
0
;
i
<
len
;
i
++)
{
if
(
i
==
len
/
2
)
{
if
(!
config
.
memory
)
{
conn
.
close
();
conn
=
getConnection
(
"optimizations"
);
stat
=
conn
.
createStatement
();
}
}
switch
(
random
.
nextInt
(
10
))
{
case
0
:
case
1
:
case
2
:
case
3
:
case
4
:
case
5
:
if
(
random
.
nextInt
(
1000
)==
1
)
{
stat
.
execute
(
"insert into test values("
+
i
+
", null)"
);
map
.
put
(
new
Integer
(
i
),
null
);
}
else
{
int
value
=
random
.
nextInt
();
stat
.
execute
(
"insert into test values("
+
i
+
", "
+
value
+
")"
);
map
.
put
(
new
Integer
(
i
),
new
Integer
(
value
));
set
.
add
(
new
Integer
(
value
));
}
break
;
case
6
:
case
7
:
case
8
:
{
if
(
map
.
size
()>
0
)
{
for
(
int
j
=
random
.
nextInt
(
i
),
k
=
0
;
k
<
10
;
k
++,
j
++)
{
if
(
map
.
containsKey
(
new
Integer
(
j
)))
{
Integer
x
=
(
Integer
)
map
.
remove
(
new
Integer
(
j
));
if
(
x
!=
null
)
{
set
.
remove
(
x
);
}
stat
.
execute
(
"delete from test where id="
+
j
);
}
}
}
break
;
}
case
9
:
{
ArrayList
list
=
new
ArrayList
(
map
.
values
());
int
count
=
list
.
size
();
Integer
min
=
null
,
max
=
null
;
if
(
count
>
0
)
{
min
=
(
Integer
)
set
.
first
();
max
=
(
Integer
)
set
.
last
();
}
ResultSet
rs
=
stat
.
executeQuery
(
"select min(value), max(value), count(*) from test"
);
rs
.
next
();
Integer
minDb
=
(
Integer
)
rs
.
getObject
(
1
);
Integer
maxDb
=
(
Integer
)
rs
.
getObject
(
2
);
int
countDb
=
rs
.
getInt
(
3
);
check
(
minDb
,
min
);
check
(
maxDb
,
max
);
check
(
countDb
,
count
);
}
}
}
conn
.
close
();
}
private
void
testIn
()
throws
Exception
{
deleteDb
(
"optimizations"
);
Connection
conn
=
getConnection
(
"optimizations"
);
Statement
stat
=
conn
.
createStatement
();
stat
.
execute
(
"create table test(id int primary key, name varchar)"
);
stat
.
execute
(
"insert into test values(1, 'Hello')"
);
stat
.
execute
(
"insert into test values(2, 'World')"
);
PreparedStatement
prep
;
ResultSet
rs
;
prep
=
conn
.
prepareStatement
(
"select * from test t1 where t1.id in(?)"
);
prep
.
setInt
(
1
,
1
);
rs
=
prep
.
executeQuery
();
rs
.
next
();
check
(
rs
.
getInt
(
1
),
1
);
check
(
rs
.
getString
(
2
),
"Hello"
);
checkFalse
(
rs
.
next
());
prep
=
conn
.
prepareStatement
(
"select * from test t1 where t1.id in(?, ?) order by id"
);
prep
.
setInt
(
1
,
1
);
prep
.
setInt
(
2
,
2
);
rs
=
prep
.
executeQuery
();
rs
.
next
();
check
(
rs
.
getInt
(
1
),
1
);
check
(
rs
.
getString
(
2
),
"Hello"
);
rs
.
next
();
check
(
rs
.
getInt
(
1
),
2
);
check
(
rs
.
getString
(
2
),
"World"
);
checkFalse
(
rs
.
next
());
prep
=
conn
.
prepareStatement
(
"select * from test t1 where t1.id in(select t2.id from test t2 where t2.id=?)"
);
prep
.
setInt
(
1
,
2
);
rs
=
prep
.
executeQuery
();
rs
.
next
();
check
(
rs
.
getInt
(
1
),
2
);
check
(
rs
.
getString
(
2
),
"World"
);
checkFalse
(
rs
.
next
());
prep
=
conn
.
prepareStatement
(
"select * from test t1 where t1.id in(select t2.id from test t2 where t2.id=? and t1.id<>t2.id)"
);
prep
.
setInt
(
1
,
2
);
rs
=
prep
.
executeQuery
();
checkFalse
(
rs
.
next
());
prep
=
conn
.
prepareStatement
(
"select * from test t1 where t1.id in(select t2.id from test t2 where t2.id in(cast(?+10 as varchar)))"
);
prep
.
setInt
(
1
,
2
);
rs
=
prep
.
executeQuery
();
checkFalse
(
rs
.
next
());
conn
.
close
();
}
}
h2/src/test/org/h2/test/db/TestPowerOff.java
0 → 100644
浏览文件 @
68bcd1cb
/*
* Copyright 2004-2006 H2 Group. Licensed under the H2 License, Version 1.0 (http://h2database.com/html/license.html).
* Initial Developer: H2 Group
*/
package
org
.
h2
.
test
.
db
;
import
java.sql.Connection
;
import
java.sql.DatabaseMetaData
;
import
java.sql.ResultSet
;
import
java.sql.SQLException
;
import
java.sql.Statement
;
import
java.util.ArrayList
;
import
java.util.Random
;
import
org.h2.engine.Constants
;
import
org.h2.engine.Database
;
import
org.h2.jdbc.JdbcConnection
;
import
org.h2.test.TestBase
;
import
org.h2.tools.FileBase
;
import
org.h2.util.FileUtils
;
public
class
TestPowerOff
extends
TestBase
{
private
String
dbName
=
"powerOff"
;
private
String
dir
,
url
;
private
int
maxPowerOffCount
;
public
void
test
()
throws
Exception
{
if
(
config
.
memory
||
config
.
logMode
==
0
)
{
return
;
}
if
(
config
.
big
)
{
dir
=
BASE_DIR
;
}
else
{
dir
=
"inmemory:"
;
}
url
=
dir
+
"/"
+
dbName
+
";file_lock=no"
;
testCrash
();
testShutdown
();
testNoIndexFile
();
testMemoryTables
();
testPersistentTables
();
}
private
void
testCrash
()
throws
Exception
{
if
(
config
.
networked
)
{
return
;
}
deleteDb
(
dir
,
dbName
);
Random
random
=
new
Random
(
1
);
Constants
.
RUN_FINALIZERS
=
false
;
int
repeat
=
getSize
(
1
,
20
);
for
(
int
i
=
0
;
i
<
repeat
;
i
++)
{
Connection
conn
=
getConnection
(
url
);
conn
.
close
();
conn
=
getConnection
(
url
);
Statement
stat
=
conn
.
createStatement
();
stat
.
execute
(
"SET WRITE_DELAY 0"
);
((
JdbcConnection
)
conn
).
setPowerOffCount
(
random
.
nextInt
(
100
));
try
{
stat
.
execute
(
"DROP TABLE IF EXISTS TEST"
);
stat
.
execute
(
"CREATE TABLE TEST(ID INT PRIMARY KEY, NAME VARCHAR(255))"
);
conn
.
setAutoCommit
(
false
);
int
len
=
getSize
(
3
,
100
);
for
(
int
j
=
0
;
j
<
len
;
j
++)
{
stat
.
execute
(
"INSERT INTO TEST VALUES("
+
j
+
", 'Hello')"
);
if
(
random
.
nextInt
(
5
)
==
0
)
{
conn
.
commit
();
}
if
(
random
.
nextInt
(
10
)
==
0
)
{
stat
.
execute
(
"DROP TABLE IF EXISTS TEST"
);
stat
.
execute
(
"CREATE TABLE TEST(ID INT PRIMARY KEY, NAME VARCHAR(255))"
);
}
}
stat
.
execute
(
"DROP TABLE IF EXISTS TEST"
);
conn
.
close
();
}
catch
(
SQLException
e
)
{
if
(!
e
.
getSQLState
().
equals
(
"90098"
))
{
e
.
printStackTrace
();
}
}
}
}
private
void
testShutdown
()
throws
Exception
{
deleteDb
(
dir
,
dbName
);
Connection
conn
=
getConnection
(
url
);
Statement
stat
=
conn
.
createStatement
();
stat
.
execute
(
"CREATE TABLE TEST(ID INT PRIMARY KEY, NAME VARCHAR(255))"
);
stat
.
execute
(
"INSERT INTO TEST VALUES(1, 'Hello')"
);
stat
.
execute
(
"SHUTDOWN"
);
conn
.
close
();
conn
=
getConnection
(
url
);
stat
=
conn
.
createStatement
();
ResultSet
rs
=
stat
.
executeQuery
(
"SELECT * FROM TEST"
);
check
(
rs
.
next
());
checkFalse
(
rs
.
next
());
conn
.
close
();
}
private
void
testNoIndexFile
()
throws
Exception
{
if
(
config
.
networked
)
{
return
;
}
deleteDb
(
dir
,
dbName
);
Connection
conn
=
getConnection
(
url
);
Statement
stat
=
conn
.
createStatement
();
stat
.
execute
(
"CREATE MEMORY TABLE TEST(ID INT PRIMARY KEY, NAME VARCHAR(255))"
);
stat
.
execute
(
"INSERT INTO TEST VALUES(1, 'Hello')"
);
((
JdbcConnection
)
conn
).
setPowerOffCount
(
1
);
try
{
stat
.
execute
(
"INSERT INTO TEST VALUES(2, 'Hello')"
);
stat
.
execute
(
"CHECKPOINT"
);
error
(
"should not work!"
);
}
catch
(
SQLException
e
)
{
// expected
}
boolean
deleted
=
false
;
ArrayList
files
=
FileBase
.
getDatabaseFiles
(
dir
,
dbName
,
false
);
for
(
int
i
=
0
;
i
<
files
.
size
();
i
++)
{
String
fileName
=
(
String
)
files
.
get
(
i
);
if
(
fileName
.
endsWith
(
Constants
.
SUFFIX_INDEX_FILE
))
{
FileUtils
.
delete
(
fileName
);
deleted
=
true
;
}
}
check
(
deleted
);
conn
=
getConnection
(
url
);
conn
.
close
();
}
private
void
testMemoryTables
()
throws
Exception
{
if
(
config
.
networked
)
{
return
;
}
deleteDb
(
dir
,
dbName
);
Connection
conn
=
getConnection
(
url
);
Statement
stat
=
conn
.
createStatement
();
stat
.
execute
(
"CREATE MEMORY TABLE TEST(ID INT PRIMARY KEY, NAME VARCHAR(255))"
);
stat
.
execute
(
"INSERT INTO TEST VALUES(1, 'Hello')"
);
stat
.
execute
(
"CHECKPOINT"
);
((
JdbcConnection
)
conn
).
setPowerOffCount
(
1
);
try
{
stat
.
execute
(
"INSERT INTO TEST VALUES(2, 'Hello')"
);
stat
.
execute
(
"INSERT INTO TEST VALUES(3, 'Hello')"
);
stat
.
execute
(
"CHECKPOINT"
);
error
(
"should have failed!"
);
}
catch
(
Exception
e
)
{
// ok
}
((
JdbcConnection
)
conn
).
setPowerOffCount
(
0
);
conn
=
getConnection
(
url
);
stat
=
conn
.
createStatement
();
ResultSet
rs
=
stat
.
executeQuery
(
"SELECT COUNT(*) FROM TEST"
);
rs
.
next
();
check
(
rs
.
getInt
(
1
),
1
);
conn
.
close
();
}
private
void
testPersistentTables
()
throws
Exception
{
if
(
config
.
networked
)
{
return
;
}
deleteDb
(
dir
,
dbName
);
// ((JdbcConnection)conn).setPowerOffCount(Integer.MAX_VALUE);
testRun
(
true
);
int
max
=
maxPowerOffCount
;
trace
(
"max="
+
max
);
runTest
(
0
,
max
,
true
);
recoverAndCheckConsistency
();
runTest
(
0
,
max
,
false
);
recoverAndCheckConsistency
();
}
void
runTest
(
int
min
,
int
max
,
boolean
withConsistencyCheck
)
throws
Exception
{
for
(
int
i
=
min
;
i
<
max
;
i
++)
{
deleteDb
(
dir
,
dbName
);
Database
.
setInitialPowerOffCount
(
i
);
int
expect
=
testRun
(
false
);
if
(
withConsistencyCheck
)
{
int
got
=
recoverAndCheckConsistency
();
trace
(
"test "
+
i
+
" of "
+
max
+
" expect="
+
expect
+
" got="
+
got
);
}
else
{
trace
(
"test "
+
i
+
" of "
+
max
+
" expect="
+
expect
);
}
}
Database
.
setInitialPowerOffCount
(
0
);
}
int
testRun
(
boolean
init
)
throws
Exception
{
if
(
init
)
{
Database
.
setInitialPowerOffCount
(
Integer
.
MAX_VALUE
);
}
int
state
=
0
;
try
{
Connection
conn
=
getConnection
(
url
);
Statement
stat
=
conn
.
createStatement
();
stat
.
execute
(
"SET WRITE_DELAY 0"
);
stat
.
execute
(
"CREATE TABLE IF NOT EXISTS TEST(ID INT PRIMARY KEY, NAME VARCHAR(255))"
);
state
=
1
;
conn
.
setAutoCommit
(
false
);
stat
.
execute
(
"INSERT INTO TEST VALUES(1, 'Hello')"
);
stat
.
execute
(
"INSERT INTO TEST VALUES(2, 'World')"
);
conn
.
commit
();
state
=
2
;
stat
.
execute
(
"UPDATE TEST SET NAME='Hallo' WHERE ID=1"
);
stat
.
execute
(
"UPDATE TEST SET NAME='Welt' WHERE ID=2"
);
conn
.
commit
();
state
=
3
;
stat
.
execute
(
"DELETE FROM TEST WHERE ID=1"
);
stat
.
execute
(
"DELETE FROM TEST WHERE ID=2"
);
conn
.
commit
();
state
=
1
;
stat
.
execute
(
"DROP TABLE TEST"
);
state
=
0
;
if
(
init
)
{
maxPowerOffCount
=
Integer
.
MAX_VALUE
-
((
JdbcConnection
)
conn
).
getPowerOffCount
();
}
conn
.
close
();
}
catch
(
SQLException
e
)
{
if
(
e
.
getSQLState
().
equals
(
"90098"
))
{
// this is ok
}
else
{
throw
e
;
}
//log("error="+e);
// e.printStackTrace();
}
return
state
;
}
int
recoverAndCheckConsistency
()
throws
Exception
{
int
state
;
Database
.
setInitialPowerOffCount
(
0
);
Connection
conn
=
getConnection
(
url
);
if
(((
JdbcConnection
)
conn
).
getPowerOffCount
()
!=
0
)
{
error
(
"power off count is not 0"
);
}
Statement
stat
=
conn
.
createStatement
();
DatabaseMetaData
meta
=
conn
.
getMetaData
();
ResultSet
rs
=
meta
.
getTables
(
null
,
null
,
"TEST"
,
null
);
if
(!
rs
.
next
())
{
state
=
0
;
}
else
{
// table does not exist
rs
=
stat
.
executeQuery
(
"SELECT * FROM TEST ORDER BY ID"
);
if
(!
rs
.
next
())
{
state
=
1
;
}
else
{
check
(
rs
.
getInt
(
1
),
1
);
String
name1
=
rs
.
getString
(
2
);
check
(
rs
.
next
());
check
(
rs
.
getInt
(
1
),
2
);
String
name2
=
rs
.
getString
(
2
);
checkFalse
(
rs
.
next
());
if
(
"Hello"
.
equals
(
name1
))
{
check
(
name2
,
"World"
);
state
=
2
;
}
else
{
check
(
name1
,
"Hallo"
);
check
(
name2
,
"Welt"
);
state
=
3
;
}
}
}
conn
.
close
();
return
state
;
}
}
h2/src/test/org/h2/test/db/TestReadOnly.java
0 → 100644
浏览文件 @
68bcd1cb
/*
* Copyright 2004-2006 H2 Group. Licensed under the H2 License, Version 1.0 (http://h2database.com/html/license.html).
* Initial Developer: H2 Group
*/
package
org
.
h2
.
test
.
db
;
import
java.io.File
;
import
java.sql.Connection
;
import
java.sql.SQLException
;
import
java.sql.Statement
;
import
java.util.ArrayList
;
import
org.h2.test.TestBase
;
import
org.h2.tools.FileBase
;
public
class
TestReadOnly
extends
TestBase
{
public
void
test
()
throws
Exception
{
if
(
config
.
memory
)
{
return
;
}
deleteDb
(
"readonly"
);
Connection
conn
=
getConnection
(
"readonly"
);
Statement
stat
=
conn
.
createStatement
();
stat
.
execute
(
"CREATE TABLE TEST(ID INT PRIMARY KEY, NAME VARCHAR)"
);
stat
.
execute
(
"INSERT INTO TEST VALUES(1, 'Hello')"
);
stat
.
execute
(
"INSERT INTO TEST VALUES(2, 'World')"
);
conn
.
close
();
setReadOnly
();
conn
=
getConnection
(
"readonly"
);
stat
=
conn
.
createStatement
();
stat
.
execute
(
"SELECT * FROM TEST"
);
try
{
stat
.
execute
(
"DELETE FROM TEST"
);
error
(
"read only delete"
);
}
catch
(
SQLException
e
)
{
checkNotGeneralException
(
e
);
}
conn
.
close
();
conn
=
getConnection
(
"readonly;DB_CLOSE_DELAY=1"
);
stat
=
conn
.
createStatement
();
stat
.
execute
(
"SELECT * FROM TEST"
);
try
{
stat
.
execute
(
"DELETE FROM TEST"
);
error
(
"read only delete"
);
}
catch
(
SQLException
e
)
{
checkNotGeneralException
(
e
);
}
conn
.
close
();
}
private
void
setReadOnly
()
throws
SQLException
{
ArrayList
list
=
FileBase
.
getDatabaseFiles
(
TestBase
.
BASE_DIR
,
"readonly"
,
true
);
for
(
int
i
=
0
;
i
<
list
.
size
();
i
++)
{
String
fileName
=
(
String
)
list
.
get
(
i
);
File
file
=
new
File
(
fileName
);
file
.
setReadOnly
();
}
}
}
h2/src/test/org/h2/test/db/TestRights.java
0 → 100644
浏览文件 @
68bcd1cb
/*
* Copyright 2004-2006 H2 Group. Licensed under the H2 License, Version 1.0 (http://h2database.com/html/license.html).
* Initial Developer: H2 Group
*/
package
org
.
h2
.
test
.
db
;
import
java.sql.*
;
import
org.h2.test.TestBase
;
public
class
TestRights
extends
TestBase
{
Statement
stat
;
public
void
test
()
throws
Exception
{
if
(
config
.
memory
)
{
return
;
}
deleteDb
(
"rights"
);
Connection
conn
=
getConnection
(
"rights"
);
stat
=
conn
.
createStatement
();
// default table type
testTableType
(
conn
,
"MEMORY"
);
testTableType
(
conn
,
"CACHED"
);
// rights on tables and views
executeSuccess
(
"CREATE USER PASSREADER PASSWORD 'abc'"
);
executeSuccess
(
"CREATE TABLE PASS(ID INT PRIMARY KEY, NAME VARCHAR, PASSWORD VARCHAR)"
);
executeSuccess
(
"CREATE VIEW PASS_NAME AS SELECT ID, NAME FROM PASS"
);
executeSuccess
(
"GRANT SELECT ON PASS_NAME TO PASSREADER"
);
conn
.
close
();
conn
=
getConnection
(
"rights"
,
"PASSREADER"
,
"abc"
);
stat
=
conn
.
createStatement
();
executeSuccess
(
"SELECT * FROM PASS_NAME"
);
executeError
(
"SELECT * FROM PASS"
);
conn
.
close
();
conn
=
getConnection
(
"rights"
);
stat
=
conn
.
createStatement
();
executeSuccess
(
"CREATE USER TEST PASSWORD 'abc'"
);
executeSuccess
(
"ALTER USER TEST ADMIN TRUE"
);
executeSuccess
(
"CREATE TABLE TEST(ID INT)"
);
executeSuccess
(
"CREATE SCHEMA SCHEMA_A AUTHORIZATION SA"
);
executeSuccess
(
"CREATE TABLE SCHEMA_A.TABLE_B(ID INT)"
);
executeSuccess
(
"GRANT ALL ON SCHEMA_A.TABLE_B TO TEST"
);
executeSuccess
(
"CREATE TABLE HIDDEN(ID INT)"
);
executeSuccess
(
"CREATE TABLE PUBTABLE(ID INT)"
);
executeSuccess
(
"CREATE TABLE ROLETABLE(ID INT)"
);
executeSuccess
(
"CREATE ROLE TESTROLE"
);
executeSuccess
(
"GRANT SELECT ON ROLETABLE TO TESTROLE"
);
executeSuccess
(
"GRANT UPDATE ON ROLETABLE TO TESTROLE"
);
executeSuccess
(
"REVOKE UPDATE ON ROLETABLE FROM TESTROLE"
);
executeError
(
"REVOKE SELECT, SUB1 ON ROLETABLE FROM TESTROLE"
);
executeSuccess
(
"GRANT TESTROLE TO TEST"
);
executeSuccess
(
"GRANT SELECT ON PUBTABLE TO PUBLIC"
);
executeSuccess
(
"GRANT SELECT ON TEST TO TEST"
);
executeSuccess
(
"CREATE ROLE SUB1"
);
executeSuccess
(
"CREATE ROLE SUB2"
);
executeSuccess
(
"CREATE TABLE SUBTABLE(ID INT)"
);
executeSuccess
(
"GRANT ALL ON SUBTABLE TO SUB2"
);
executeSuccess
(
"REVOKE UPDATE, DELETE ON SUBTABLE FROM SUB2"
);
executeSuccess
(
"GRANT SUB2 TO SUB1"
);
executeSuccess
(
"GRANT SUB1 TO TEST"
);
executeSuccess
(
"ALTER USER TEST SET PASSWORD 'def'"
);
executeSuccess
(
"CREATE USER TEST2 PASSWORD 'def' ADMIN"
);
executeSuccess
(
"ALTER USER TEST ADMIN FALSE"
);
executeSuccess
(
"SCRIPT TO '"
+
BASE_DIR
+
"/rights.sql' CIPHER XTEA PASSWORD 'test'"
);
conn
.
close
();
try
{
conn
=
getConnection
(
"rights"
,
"Test"
,
"abc"
);
error
(
"unexpected success (mixed case user name)"
);
}
catch
(
SQLException
e
)
{
checkNotGeneralException
(
e
);
}
try
{
conn
=
getConnection
(
"rights"
,
"TEST"
,
"abc"
);
error
(
"unexpected success (wrong password)"
);
}
catch
(
SQLException
e
)
{
checkNotGeneralException
(
e
);
}
try
{
conn
=
getConnection
(
"rights"
,
"TEST"
,
null
);
error
(
"unexpected success (wrong password)"
);
}
catch
(
SQLException
e
)
{
checkNotGeneralException
(
e
);
}
conn
=
getConnection
(
"rights"
,
"TEST"
,
"def"
);
stat
=
conn
.
createStatement
();
executeError
(
"SET DEFAULT_TABLE_TYPE MEMORY"
);
executeSuccess
(
"SELECT * FROM TEST"
);
executeSuccess
(
"SELECT * FROM SYSTEM_RANGE(1,2)"
);
executeSuccess
(
"SELECT * FROM SCHEMA_A.TABLE_B"
);
executeSuccess
(
"SELECT * FROM PUBTABLE"
);
executeSuccess
(
"SELECT * FROM ROLETABLE"
);
executeError
(
"UPDATE ROLETABLE SET ID=0"
);
executeError
(
"DELETE FROM ROLETABLE"
);
executeError
(
"SELECT * FROM HIDDEN"
);
executeError
(
"UPDATE TEST SET ID=0"
);
executeSuccess
(
"SELECT * FROM SUBTABLE"
);
executeSuccess
(
"INSERT INTO SUBTABLE VALUES(1)"
);
executeError
(
"DELETE FROM SUBTABLE"
);
executeError
(
"UPDATE FROM SUBTABLE"
);
executeError
(
"CREATE USER TEST3 PASSWORD 'def'"
);
executeError
(
"ALTER USER TEST2 ADMIN FALSE"
);
executeError
(
"ALTER USER TEST2 SET PASSWORD 'ghi'"
);
executeError
(
"ALTER USER TEST2 RENAME TO TEST_X"
);
executeError
(
"ALTER USER TEST RENAME TO TEST_X"
);
executeSuccess
(
"ALTER USER TEST SET PASSWORD 'ghi'"
);
executeError
(
"DROP USER TEST2"
);
conn
.
close
();
conn
=
getConnection
(
"rights"
);
stat
=
conn
.
createStatement
();
executeSuccess
(
"DROP ROLE SUB1"
);
executeSuccess
(
"DROP TABLE ROLETABLE"
);
executeSuccess
(
"DROP USER TEST"
);
conn
.
close
();
conn
=
getConnection
(
"rights"
);
stat
=
conn
.
createStatement
();
executeSuccess
(
"DROP TABLE IF EXISTS TEST"
);
executeSuccess
(
"CREATE TABLE TEST(ID INT PRIMARY KEY, NAME VARCHAR(255))"
);
executeSuccess
(
"CREATE USER GUEST PASSWORD 'abc'"
);
executeSuccess
(
"GRANT SELECT ON TEST TO GUEST"
);
executeSuccess
(
"ALTER USER GUEST RENAME TO GAST"
);
conn
.
close
();
conn
=
getConnection
(
"rights"
);
conn
.
close
();
}
private
void
testTableType
(
Connection
conn
,
String
type
)
throws
Exception
{
executeSuccess
(
"SET DEFAULT_TABLE_TYPE "
+
type
);
executeSuccess
(
"CREATE TABLE TEST(ID INT)"
);
ResultSet
rs
=
conn
.
createStatement
().
executeQuery
(
"SELECT STORAGE_TYPE FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME='TEST'"
);
rs
.
next
();
check
(
rs
.
getString
(
1
),
type
);
executeSuccess
(
"DROP TABLE TEST"
);
}
public
void
executeError
(
String
sql
)
throws
Exception
{
try
{
stat
.
execute
(
sql
);
error
(
"unexpected success (not admin)"
);
}
catch
(
SQLException
e
)
{
checkNotGeneralException
(
e
);
}
}
public
void
executeSuccess
(
String
sql
)
throws
Exception
{
if
(
stat
.
execute
(
sql
))
{
ResultSet
rs
=
stat
.
getResultSet
();
// this will check if the resultset is updatable
rs
.
getConcurrency
();
ResultSetMetaData
meta
=
rs
.
getMetaData
();
int
columnCount
=
meta
.
getColumnCount
();
for
(
int
i
=
0
;
i
<
columnCount
;
i
++)
{
meta
.
getCatalogName
(
i
+
1
);
meta
.
getColumnClassName
(
i
+
1
);
meta
.
getColumnDisplaySize
(
i
+
1
);
meta
.
getColumnLabel
(
i
+
1
);
meta
.
getColumnName
(
i
+
1
);
meta
.
getColumnType
(
i
+
1
);
meta
.
getColumnTypeName
(
i
+
1
);
meta
.
getPrecision
(
i
+
1
);
meta
.
getScale
(
i
+
1
);
meta
.
getSchemaName
(
i
+
1
);
meta
.
getTableName
(
i
+
1
);
}
while
(
rs
.
next
())
{
for
(
int
i
=
0
;
i
<
columnCount
;
i
++)
{
rs
.
getObject
(
i
+
1
);
}
}
}
}
}
h2/src/test/org/h2/test/db/TestRunscript.java
0 → 100644
浏览文件 @
68bcd1cb
/*
* Copyright 2004-2006 H2 Group. Licensed under the H2 License, Version 1.0 (http://h2database.com/html/license.html).
* Initial Developer: H2 Group
*/
package
org
.
h2
.
test
.
db
;
import
java.sql.Connection
;
import
java.sql.ResultSet
;
import
java.sql.SQLException
;
import
java.sql.Statement
;
import
java.util.ArrayList
;
import
org.h2.api.Trigger
;
import
org.h2.test.TestBase
;
public
class
TestRunscript
extends
TestBase
implements
Trigger
{
public
void
test
()
throws
Exception
{
test
(
false
);
test
(
true
);
}
public
static
int
test
(
int
a
)
{
return
Math
.
abs
(
a
);
}
private
void
test
(
boolean
password
)
throws
Exception
{
deleteDb
(
"runscript"
);
Connection
conn1
,
conn2
;
Statement
stat1
,
stat2
;
conn1
=
getConnection
(
"runscript"
);
stat1
=
conn1
.
createStatement
();
stat1
.
execute
(
"create table test (id identity, name varchar(12))"
);
stat1
.
execute
(
"insert into test (name) values ('first'), ('second')"
);
stat1
.
execute
(
"create sequence testseq start with 100 increment by 10"
);
stat1
.
execute
(
"create alias mytest for \""
+
getClass
().
getName
()+
".test\""
);
stat1
.
execute
(
"create trigger mytrigger before insert on test nowait call \""
+
getClass
().
getName
()+
"\""
);
stat1
.
execute
(
"create view testview as select * from test where 1=0 union all select * from test where 0=1"
);
stat1
.
execute
(
"create user testadmin salt '00' hash '01' admin"
);
stat1
.
execute
(
"create schema testschema authorization testadmin"
);
stat1
.
execute
(
"create table testschema.parent(id int primary key, name varchar)"
);
stat1
.
execute
(
"create index idxname on testschema.parent(name)"
);
stat1
.
execute
(
"create table testschema.child(id int primary key, parentId int, name varchar, foreign key(parentId) references parent(id))"
);
stat1
.
execute
(
"create user testuser salt '02' hash '03'"
);
stat1
.
execute
(
"create role testrole"
);
stat1
.
execute
(
"grant all on testschema.child to testuser"
);
stat1
.
execute
(
"grant select, insert on testschema.parent to testrole"
);
stat1
.
execute
(
"grant testrole to testuser"
);
String
sql
=
"script to 'backup.2.sql'"
;
if
(
password
)
{
sql
+=
" CIPHER AES PASSWORD 't1e2s3t4'"
;
}
stat1
.
execute
(
sql
);
deleteDb
(
"runscriptRestore"
);
conn2
=
getConnection
(
"runscriptRestore"
);
stat2
=
conn2
.
createStatement
();
sql
=
"runscript from 'backup.2.sql'"
;
if
(
password
)
{
sql
+=
" CIPHER AES PASSWORD 'wrongpassword'"
;
}
if
(
password
)
{
try
{
stat2
.
execute
(
sql
);
error
(
"should fail"
);
}
catch
(
SQLException
e
)
{
checkNotGeneralException
(
e
);
}
}
sql
=
"runscript from 'backup.2.sql'"
;
if
(
password
)
{
sql
+=
" CIPHER AES PASSWORD 't1e2s3t4'"
;
}
stat2
.
execute
(
sql
);
stat2
.
execute
(
"script to 'backup.3.sql'"
);
compareDatabases
(
stat1
,
stat2
);
conn1
.
close
();
conn2
.
close
();
}
private
void
compareDatabases
(
Statement
stat1
,
Statement
stat2
)
throws
Exception
{
ResultSet
rs1
=
stat1
.
executeQuery
(
"SCRIPT NOPASSWORDS"
);
ResultSet
rs2
=
stat2
.
executeQuery
(
"SCRIPT NOPASSWORDS"
);
ArrayList
list1
=
new
ArrayList
();
ArrayList
list2
=
new
ArrayList
();
while
(
rs1
.
next
())
{
check
(
rs2
.
next
());
list1
.
add
(
rs1
.
getString
(
1
));
list2
.
add
(
rs2
.
getString
(
1
));
}
for
(
int
i
=
0
;
i
<
list1
.
size
();
i
++)
{
String
s
=
(
String
)
list1
.
get
(
i
);
if
(!
list2
.
remove
(
s
))
{
error
(
"not found: "
+
s
);
}
}
check
(
list2
.
size
(),
0
);
checkFalse
(
rs2
.
next
());
}
public
void
init
(
Connection
conn
,
String
schemaName
,
String
triggerName
,
String
tableName
)
{
}
public
void
fire
(
Connection
conn
,
Object
[]
oldRow
,
Object
[]
newRow
)
throws
SQLException
{
}
}
h2/src/test/org/h2/test/db/TestSQLInjection.java
0 → 100644
浏览文件 @
68bcd1cb
/*
* Copyright 2004-2006 H2 Group. Licensed under the H2 License, Version 1.0 (http://h2database.com/html/license.html).
* Initial Developer: H2 Group
*/
package
org
.
h2
.
test
.
db
;
import
java.sql.Connection
;
import
java.sql.PreparedStatement
;
import
java.sql.ResultSet
;
import
java.sql.SQLException
;
import
java.sql.Statement
;
import
org.h2.test.TestBase
;
public
class
TestSQLInjection
extends
TestBase
{
Connection
conn
;
Statement
stat
;
public
void
test
()
throws
Exception
{
deleteDb
(
"sqlinjection"
);
reconnect
(
"sqlinjection"
);
stat
.
execute
(
"DROP TABLE IF EXISTS USERS"
);
stat
.
execute
(
"CREATE TABLE USERS(NAME VARCHAR PRIMARY KEY, PASSWORD VARCHAR, TYPE VARCHAR)"
);
stat
.
execute
(
"CREATE SCHEMA CONST"
);
stat
.
execute
(
"CREATE CONSTANT CONST.ACTIVE VALUE 'Active'"
);
stat
.
execute
(
"INSERT INTO USERS VALUES('James', '123456', CONST.ACTIVE)"
);
check
(
checkPasswordInsecure
(
"123456"
));
checkFalse
(
checkPasswordInsecure
(
"abcdef"
));
check
(
checkPasswordInsecure
(
"' OR ''='"
));
check
(
checkPasswordSecure
(
"123456"
));
checkFalse
(
checkPasswordSecure
(
"abcdef"
));
checkFalse
(
checkPasswordSecure
(
"' OR ''='"
));
stat
.
execute
(
"SET ALLOW_LITERALS NONE"
);
try
{
check
(
checkPasswordInsecure
(
"123456"
));
error
(
"Should fail now"
);
}
catch
(
SQLException
e
)
{
checkNotGeneralException
(
e
);
}
check
(
checkPasswordSecure
(
"123456"
));
checkFalse
(
checkPasswordSecure
(
"' OR ''='"
));
conn
.
close
();
if
(
config
.
memory
)
{
return
;
}
reconnect
(
"sqlinjection"
);
try
{
check
(
checkPasswordInsecure
(
"123456"
));
error
(
"Should fail now"
);
}
catch
(
SQLException
e
)
{
checkNotGeneralException
(
e
);
}
check
(
checkPasswordSecure
(
"123456"
));
checkFalse
(
checkPasswordSecure
(
"' OR ''='"
));
conn
.
close
();
}
boolean
checkPasswordInsecure
(
String
pwd
)
throws
SQLException
{
String
sql
=
"SELECT * FROM USERS WHERE PASSWORD='"
+
pwd
+
"'"
;
ResultSet
rs
=
conn
.
createStatement
().
executeQuery
(
sql
);
return
(
rs
.
next
());
}
boolean
checkPasswordSecure
(
String
pwd
)
throws
Exception
{
String
sql
=
"SELECT * FROM USERS WHERE PASSWORD=?"
;
PreparedStatement
prep
=
conn
.
prepareStatement
(
sql
);
prep
.
setString
(
1
,
pwd
);
ResultSet
rs
=
prep
.
executeQuery
();
return
(
rs
.
next
());
}
private
void
reconnect
(
String
name
)
throws
Exception
{
if
(!
config
.
memory
)
{
if
(
conn
!=
null
)
{
conn
.
close
();
conn
=
null
;
}
}
if
(
conn
==
null
)
{
conn
=
getConnection
(
name
);
stat
=
conn
.
createStatement
();
}
}
}
h2/src/test/org/h2/test/db/TestScript.java
0 → 100644
浏览文件 @
68bcd1cb
差异被折叠。
点击展开。
h2/src/test/org/h2/test/db/TestScriptSimple.java
0 → 100644
浏览文件 @
68bcd1cb
/*
* Copyright 2004-2006 H2 Group. Licensed under the H2 License, Version 1.0 (http://h2database.com/html/license.html).
* Initial Developer: H2 Group
*/
package
org
.
h2
.
test
.
db
;
import
java.io.InputStream
;
import
java.io.InputStreamReader
;
import
java.io.LineNumberReader
;
import
java.sql.Connection
;
import
java.sql.ResultSet
;
import
org.h2.test.TestBase
;
import
org.h2.util.ScriptReader
;
public
class
TestScriptSimple
extends
TestBase
{
private
Connection
conn
;
public
void
test
()
throws
Exception
{
if
(
config
.
memory
||
config
.
big
||
config
.
networked
)
{
return
;
}
deleteDb
(
"scriptSimple"
);
reconnect
();
String
infile
=
"org/h2/test/testSimple.in.txt"
;
InputStream
is
=
getClass
().
getClassLoader
().
getResourceAsStream
(
infile
);
LineNumberReader
lineReader
=
new
LineNumberReader
(
new
InputStreamReader
(
is
,
"Cp1252"
));
ScriptReader
reader
=
new
ScriptReader
(
lineReader
);
while
(
true
)
{
String
sql
=
reader
.
readStatement
();
if
(
sql
==
null
)
{
break
;
}
sql
=
sql
.
trim
();
// System.out.println(sql);
if
(
"@reconnect"
.
equals
(
sql
))
{
reconnect
();
}
else
if
(
sql
.
length
()
==
0
)
{
// ignore
}
else
if
(
sql
.
startsWith
(
"select"
))
{
ResultSet
rs
=
conn
.
createStatement
().
executeQuery
(
sql
);
while
(
rs
.
next
())
{
String
expected
=
reader
.
readStatement
().
trim
();
String
got
=
"> "
+
rs
.
getString
(
1
);
check
(
expected
,
got
);
}
}
else
{
conn
.
createStatement
().
execute
(
sql
);
}
}
conn
.
close
();
}
private
void
reconnect
()
throws
Exception
{
if
(
conn
!=
null
)
{
conn
.
close
();
}
conn
=
getConnection
(
"scriptSimple"
);
}
}
h2/src/test/org/h2/test/db/TestSequence.java
0 → 100644
浏览文件 @
68bcd1cb
/*
* Copyright 2004-2006 H2 Group. Licensed under the H2 License, Version 1.0 (http://h2database.com/html/license.html).
* Initial Developer: H2 Group
*/
package
org
.
h2
.
test
.
db
;
import
java.sql.Connection
;
import
java.sql.ResultSet
;
import
java.sql.Statement
;
import
org.h2.test.TestBase
;
public
class
TestSequence
extends
TestBase
{
public
void
test
()
throws
Exception
{
deleteDb
(
"sequence"
);
Connection
conn
=
getConnection
(
"sequence"
);
Statement
stat
=
conn
.
createStatement
();
stat
.
execute
(
"create sequence testseq"
);
conn
.
setAutoCommit
(
false
);
Connection
conn2
=
getConnection
(
"sequence"
);
Statement
stat2
=
conn2
.
createStatement
();
conn2
.
setAutoCommit
(
false
);
long
last
=
0
;
for
(
int
i
=
0
;
i
<
100
;
i
++)
{
long
v1
=
getNext
(
stat
);
check
(
v1
>
last
);
last
=
v1
;
for
(
int
j
=
0
;
j
<
100
;
j
++)
{
long
v2
=
getNext
(
stat2
);
check
(
v2
>
last
);
last
=
v2
;
}
}
conn2
.
close
();
conn
.
close
();
}
private
long
getNext
(
Statement
stat
)
throws
Exception
{
ResultSet
rs
=
stat
.
executeQuery
(
"call next value for testseq"
);
rs
.
next
();
long
value
=
rs
.
getLong
(
1
);
return
value
;
}
}
h2/src/test/org/h2/test/db/TestSpaceReuse.java
0 → 100644
浏览文件 @
68bcd1cb
/*
* Copyright 2004-2006 H2 Group. Licensed under the H2 License, Version 1.0 (http://h2database.com/html/license.html).
* Initial Developer: H2 Group
*/
package
org
.
h2
.
test
.
db
;
import
java.io.*
;
import
java.sql.*
;
import
org.h2.test.TestBase
;
public
class
TestSpaceReuse
extends
TestBase
{
public
void
test
()
throws
Exception
{
if
(
config
.
memory
)
{
return
;
}
deleteDb
(
"spaceReuse"
);
long
first
=
0
,
now
=
0
;
for
(
int
i
=
0
;
i
<
10
;
i
++)
{
Connection
conn
=
getConnection
(
"spaceReuse"
);
Statement
stat
=
conn
.
createStatement
();
stat
.
execute
(
"create table if not exists t(i int)"
);
stat
.
execute
(
"insert into t select x from system_range(1, 500)"
);
conn
.
close
();
conn
=
getConnection
(
"spaceReuse"
);
conn
.
createStatement
().
execute
(
"delete from t"
);
conn
.
close
();
now
=
new
File
(
BASE_DIR
+
"/spaceReuse.data.db"
).
length
();
if
(
first
==
0
)
{
first
=
now
;
}
}
if
(
now
>
first
)
{
this
.
error
(
"first: "
+
first
+
" now: "
+
now
);
}
}
}
h2/src/test/org/h2/test/db/TestSpeed.java
0 → 100644
浏览文件 @
68bcd1cb
差异被折叠。
点击展开。
h2/src/test/org/h2/test/db/TestTempTables.java
0 → 100644
浏览文件 @
68bcd1cb
/*
* Copyright 2004-2006 H2 Group. Licensed under the H2 License, Version 1.0 (http://h2database.com/html/license.html).
* Initial Developer: H2 Group
*/
package
org
.
h2
.
test
.
db
;
import
java.sql.Connection
;
import
java.sql.ResultSet
;
import
java.sql.SQLException
;
import
java.sql.Statement
;
import
org.h2.test.TestBase
;
public
class
TestTempTables
extends
TestBase
{
public
void
test
()
throws
Exception
{
deleteDb
(
"tempTables"
);
Connection
c1
=
getConnection
(
"tempTables"
);
Connection
c2
=
getConnection
(
"tempTables"
);
Statement
s1
=
c1
.
createStatement
();
Statement
s2
=
c2
.
createStatement
();
s1
.
execute
(
"CREATE LOCAL TEMPORARY TABLE LT(A INT)"
);
s1
.
execute
(
"CREATE GLOBAL TEMPORARY TABLE GT1(ID INT)"
);
s2
.
execute
(
"CREATE GLOBAL TEMPORARY TABLE GT2(ID INT)"
);
s2
.
execute
(
"CREATE LOCAL TEMPORARY TABLE LT(B INT)"
);
s2
.
execute
(
"SELECT B FROM LT"
);
s1
.
execute
(
"SELECT A FROM LT"
);
s1
.
execute
(
"SELECT * FROM GT1"
);
s2
.
execute
(
"SELECT * FROM GT1"
);
s1
.
execute
(
"SELECT * FROM GT2"
);
s2
.
execute
(
"SELECT * FROM GT2"
);
s2
.
execute
(
"DROP TABLE GT1"
);
s2
.
execute
(
"DROP TABLE GT2"
);
s2
.
execute
(
"DROP TABLE LT"
);
s1
.
execute
(
"DROP TABLE LT"
);
// temp tables: 'on commit' syntax is currently not documented, because not tested well
// and hopefully nobody is using it, as it looks like functional sugar
// (this features are here for compatibility only)
ResultSet
rs
;
c1
.
setAutoCommit
(
false
);
s1
.
execute
(
"create local temporary table testtemp(id int) on commit delete rows"
);
s1
.
execute
(
"insert into testtemp values(1)"
);
rs
=
s1
.
executeQuery
(
"select * from testtemp"
);
checkResultRowCount
(
rs
,
1
);
c1
.
commit
();
rs
=
s1
.
executeQuery
(
"select * from testtemp"
);
checkResultRowCount
(
rs
,
0
);
s1
.
execute
(
"drop table testtemp"
);
s1
.
execute
(
"create local temporary table testtemp(id int) on commit drop"
);
s1
.
execute
(
"insert into testtemp values(1)"
);
rs
=
s1
.
executeQuery
(
"select * from testtemp"
);
checkResultRowCount
(
rs
,
1
);
c1
.
commit
();
try
{
rs
=
s1
.
executeQuery
(
"select * from testtemp"
);
error
(
"testtemp should have been dropped automatically"
);
}
catch
(
SQLException
e
)
{
checkNotGeneralException
(
e
);
}
c1
.
close
();
c2
.
close
();
}
}
h2/src/test/org/h2/test/db/TestTransaction.java
0 → 100644
浏览文件 @
68bcd1cb
/*
* Copyright 2004-2006 H2 Group. Licensed under the H2 License, Version 1.0 (http://h2database.com/html/license.html).
* Initial Developer: H2 Group
*/
package
org
.
h2
.
test
.
db
;
import
java.sql.Connection
;
import
java.sql.DatabaseMetaData
;
import
java.sql.ResultSet
;
import
java.sql.SQLException
;
import
java.sql.Savepoint
;
import
java.sql.Statement
;
import
java.util.Random
;
import
java.util.Vector
;
import
org.h2.test.TestBase
;
public
class
TestTransaction
extends
TestBase
{
public
void
test
()
throws
Exception
{
testSavepoint
();
testIsolation
();
}
public
void
testSavepoint
()
throws
Exception
{
deleteDb
(
"transaction"
);
Connection
conn
=
getConnection
(
"transaction"
);
Statement
stat
=
conn
.
createStatement
();
stat
.
execute
(
"CREATE TABLE TEST0(ID IDENTITY, NAME VARCHAR)"
);
stat
.
execute
(
"CREATE TABLE TEST1(NAME VARCHAR, ID IDENTITY, X TIMESTAMP DEFAULT CURRENT_TIMESTAMP)"
);
conn
.
setAutoCommit
(
false
);
int
[]
count
=
new
int
[
2
];
int
[]
countCommitted
=
new
int
[
2
];
int
[]
countSave
=
new
int
[
2
];
int
len
=
getSize
(
2000
,
10000
);
Random
random
=
new
Random
(
10
);
Savepoint
sp
=
null
;
for
(
int
i
=
0
;
i
<
len
;
i
++)
{
int
tableId
=
random
.
nextInt
(
2
);
String
table
=
"TEST"
+
tableId
;
int
op
=
random
.
nextInt
(
6
);
switch
(
op
)
{
case
0
:
stat
.
execute
(
"INSERT INTO "
+
table
+
"(NAME) VALUES('op"
+
i
+
"')"
);
count
[
tableId
]++;
break
;
case
1
:
if
(
count
[
tableId
]
>
0
)
{
stat
.
execute
(
"DELETE FROM "
+
table
+
" WHERE ID=SELECT MIN(ID) FROM "
+
table
);
count
[
tableId
]--;
}
break
;
case
2
:
sp
=
conn
.
setSavepoint
();
countSave
[
0
]
=
count
[
0
];
countSave
[
1
]
=
count
[
1
];
break
;
case
3
:
if
(
sp
!=
null
)
{
conn
.
rollback
(
sp
);
count
[
0
]
=
countSave
[
0
];
count
[
1
]
=
countSave
[
1
];
}
break
;
case
4
:
conn
.
commit
();
sp
=
null
;
countCommitted
[
0
]
=
count
[
0
];
countCommitted
[
1
]
=
count
[
1
];
break
;
case
5
:
conn
.
rollback
();
sp
=
null
;
count
[
0
]
=
countCommitted
[
0
];
count
[
1
]
=
countCommitted
[
1
];
break
;
}
checkTableCount
(
stat
,
"TEST0"
,
count
[
0
]);
checkTableCount
(
stat
,
"TEST1"
,
count
[
1
]);
}
conn
.
close
();
}
private
void
checkTableCount
(
Statement
stat
,
String
tableName
,
int
count
)
throws
Exception
{
ResultSet
rs
;
rs
=
stat
.
executeQuery
(
"SELECT COUNT(*) FROM "
+
tableName
);
rs
.
next
();
check
(
count
,
rs
.
getInt
(
1
));
}
public
void
testIsolation
()
throws
Exception
{
Connection
conn
=
getConnection
(
"transaction"
);
trace
(
"default TransactionIsolation="
+
conn
.
getTransactionIsolation
());
conn
.
setTransactionIsolation
(
Connection
.
TRANSACTION_READ_COMMITTED
);
check
(
conn
.
getTransactionIsolation
()==
Connection
.
TRANSACTION_READ_COMMITTED
);
conn
.
setTransactionIsolation
(
Connection
.
TRANSACTION_SERIALIZABLE
);
check
(
conn
.
getTransactionIsolation
()==
Connection
.
TRANSACTION_SERIALIZABLE
);
Statement
stat
=
conn
.
createStatement
();
check
(
conn
.
getAutoCommit
());
conn
.
setAutoCommit
(
false
);
checkFalse
(
conn
.
getAutoCommit
());
conn
.
setAutoCommit
(
true
);
check
(
conn
.
getAutoCommit
());
test
(
stat
,
"CREATE TABLE TEST(ID INT PRIMARY KEY)"
);
conn
.
commit
();
test
(
stat
,
"INSERT INTO TEST VALUES(0)"
);
conn
.
rollback
();
testValue
(
stat
,
"SELECT COUNT(*) FROM TEST"
,
"1"
);
conn
.
setAutoCommit
(
false
);
test
(
stat
,
"DELETE FROM TEST"
);
//testValue("SELECT COUNT(*) FROM TEST", "0");
conn
.
rollback
();
testValue
(
stat
,
"SELECT COUNT(*) FROM TEST"
,
"1"
);
conn
.
commit
();
conn
.
setAutoCommit
(
true
);
testNestedResultSets
(
conn
);
conn
.
setAutoCommit
(
false
);
testNestedResultSets
(
conn
);
conn
.
close
();
}
void
testNestedResultSets
(
Connection
conn
)
throws
Exception
{
Statement
stat
=
conn
.
createStatement
();
test
(
stat
,
"CREATE TABLE NEST1(ID INT PRIMARY KEY,VALUE VARCHAR(255))"
);
test
(
stat
,
"CREATE TABLE NEST2(ID INT PRIMARY KEY,VALUE VARCHAR(255))"
);
DatabaseMetaData
meta
=
conn
.
getMetaData
();
Vector
result
;
ResultSet
rs1
,
rs2
;
result
=
new
Vector
();
rs1
=
meta
.
getTables
(
null
,
null
,
"NEST%"
,
null
);
while
(
rs1
.
next
())
{
String
table
=
rs1
.
getString
(
"TABLE_NAME"
);
rs2
=
meta
.
getColumns
(
null
,
null
,
table
,
null
);
while
(
rs2
.
next
())
{
String
column
=
rs2
.
getString
(
"COLUMN_NAME"
);
trace
(
"Table: "
+
table
+
" Column: "
+
column
);
result
.
add
(
table
+
"."
+
column
);
}
}
if
(
result
.
size
()!=
4
)
{
error
(
"Wrong result, should be NEST1.ID, NEST1.NAME, NEST2.ID, NEST2.NAME but is "
+
result
);
}
result
=
new
Vector
();
test
(
stat
,
"INSERT INTO NEST1 VALUES(1,'A')"
);
test
(
stat
,
"INSERT INTO NEST1 VALUES(2,'B')"
);
test
(
stat
,
"INSERT INTO NEST2 VALUES(1,'1')"
);
test
(
stat
,
"INSERT INTO NEST2 VALUES(2,'2')"
);
Statement
s1
=
conn
.
createStatement
();
Statement
s2
=
conn
.
createStatement
();
rs1
=
s1
.
executeQuery
(
"SELECT * FROM NEST1 ORDER BY ID"
);
while
(
rs1
.
next
())
{
rs2
=
s2
.
executeQuery
(
"SELECT * FROM NEST2 ORDER BY ID"
);
while
(
rs2
.
next
())
{
String
v1
=
rs1
.
getString
(
"VALUE"
);
String
v2
=
rs2
.
getString
(
"VALUE"
);
result
.
add
(
v1
+
"/"
+
v2
);
}
}
if
(
result
.
size
()!=
4
)
{
error
(
"Wrong result, should be A/1, A/2, B/1, B/2 but is "
+
result
);
}
result
=
new
Vector
();
rs1
=
s1
.
executeQuery
(
"SELECT * FROM NEST1 ORDER BY ID"
);
rs2
=
s1
.
executeQuery
(
"SELECT * FROM NEST2 ORDER BY ID"
);
try
{
rs1
.
next
();
error
(
"next worked on a closed result set"
);
}
catch
(
SQLException
e
)
{
checkNotGeneralException
(
e
);
}
// this is already closed, so but closing again should no do any harm
rs1
.
close
();
while
(
rs2
.
next
())
{
String
v1
=
rs2
.
getString
(
"VALUE"
);
result
.
add
(
v1
);
}
if
(
result
.
size
()!=
2
)
{
error
(
"Wrong result, should be A, B but is "
+
result
);
}
test
(
stat
,
"DROP TABLE NEST1"
);
test
(
stat
,
"DROP TABLE NEST2"
);
}
void
testValue
(
Statement
stat
,
String
sql
,
String
data
)
throws
Exception
{
ResultSet
rs
=
stat
.
executeQuery
(
sql
);
rs
.
next
();
String
s
=
rs
.
getString
(
1
);
if
(
s
==
null
?
(
data
!=
null
)
:
(!
s
.
equals
(
data
)))
{
error
(
"s= "
+
s
+
" should be: "
+
data
);
}
}
void
test
(
Statement
stat
,
String
sql
)
throws
Exception
{
trace
(
sql
);
stat
.
execute
(
sql
);
}
}
h2/src/test/org/h2/test/db/TestTriggersConstraints.java
0 → 100644
浏览文件 @
68bcd1cb
/*
* Copyright 2004-2006 H2 Group. Licensed under the H2 License, Version 1.0 (http://h2database.com/html/license.html).
* Initial Developer: H2 Group
*/
package
org
.
h2
.
test
.
db
;
import
java.sql.Connection
;
import
java.sql.ResultSet
;
import
java.sql.SQLException
;
import
java.sql.Statement
;
import
java.util.Arrays
;
import
java.util.HashSet
;
import
org.h2.api.Trigger
;
import
org.h2.test.TestBase
;
/**
* @author Thomas
*/
public
class
TestTriggersConstraints
extends
TestBase
implements
Trigger
{
private
static
boolean
mustNotCallTrigger
;
public
void
test
()
throws
Exception
{
deleteDb
(
"trigger"
);
testTriggers
();
testConstraints
();
}
private
void
testConstraints
()
throws
Exception
{
Connection
conn
=
getConnection
(
"trigger"
);
Statement
stat
=
conn
.
createStatement
();
stat
.
execute
(
"DROP TABLE IF EXISTS TEST"
);
stat
.
execute
(
"create table test(id int primary key, parent int)"
);
stat
.
execute
(
"alter table test add constraint test_parent_id foreign key(parent) references test (id) on delete cascade"
);
stat
.
execute
(
"insert into test select x, x/2 from system_range(0, 100)"
);
stat
.
execute
(
"delete from test"
);
checkSingleValue
(
stat
,
"select count(*) from test"
,
0
);
stat
.
execute
(
"drop table test"
);
conn
.
close
();
}
private
void
testTriggers
()
throws
Exception
{
mustNotCallTrigger
=
false
;
Connection
conn
=
getConnection
(
"trigger"
);
Statement
stat
=
conn
.
createStatement
();
stat
.
execute
(
"DROP TABLE IF EXISTS TEST"
);
stat
.
execute
(
"CREATE TABLE TEST(ID INT PRIMARY KEY, NAME VARCHAR(255))"
);
// CREATE TRIGGER trigger {BEFORE|AFTER} {INSERT|UPDATE|DELETE} ON table [FOR EACH ROW] [QUEUE n] [NOWAIT] CALL triggeredClass
stat
.
execute
(
"CREATE TRIGGER IF NOT EXISTS INS_BEFORE BEFORE INSERT ON TEST FOR EACH ROW NOWAIT CALL \""
+
getClass
().
getName
()+
"\""
);
stat
.
execute
(
"CREATE TRIGGER IF NOT EXISTS INS_BEFORE BEFORE INSERT ON TEST FOR EACH ROW NOWAIT CALL \""
+
getClass
().
getName
()+
"\""
);
stat
.
execute
(
"CREATE TRIGGER INS_AFTER AFTER INSERT ON TEST FOR EACH ROW NOWAIT CALL \""
+
getClass
().
getName
()+
"\""
);
stat
.
execute
(
"CREATE TRIGGER UPD_BEFORE BEFORE UPDATE ON TEST FOR EACH ROW NOWAIT CALL \""
+
getClass
().
getName
()+
"\""
);
stat
.
execute
(
"INSERT INTO TEST VALUES(1, 'Hello')"
);
ResultSet
rs
;
rs
=
stat
.
executeQuery
(
"SCRIPT"
);
checkRows
(
rs
,
new
String
[]{
"CREATE TRIGGER PUBLIC.INS_BEFORE BEFORE INSERT ON PUBLIC.TEST FOR EACH ROW NOWAIT CALL \""
+
getClass
().
getName
()+
"\""
,
"CREATE TRIGGER PUBLIC.INS_AFTER AFTER INSERT ON PUBLIC.TEST FOR EACH ROW NOWAIT CALL \""
+
getClass
().
getName
()+
"\""
,
"CREATE TRIGGER PUBLIC.UPD_BEFORE BEFORE UPDATE ON PUBLIC.TEST FOR EACH ROW NOWAIT CALL \""
+
getClass
().
getName
()+
"\""
});
while
(
rs
.
next
())
{
String
sql
=
rs
.
getString
(
1
);
if
(
sql
.
startsWith
(
"CREATE TRIGGER"
))
{
System
.
out
.
println
(
sql
);
}
}
rs
=
stat
.
executeQuery
(
"SELECT * FROM TEST"
);
rs
.
next
();
check
(
rs
.
getString
(
2
),
"Hello-updated"
);
checkFalse
(
rs
.
next
());
stat
.
execute
(
"UPDATE TEST SET NAME=NAME||'-upd'"
);
rs
=
stat
.
executeQuery
(
"SELECT * FROM TEST"
);
rs
.
next
();
check
(
rs
.
getString
(
2
),
"Hello-updated-upd-updated2"
);
checkFalse
(
rs
.
next
());
mustNotCallTrigger
=
true
;
stat
.
execute
(
"DROP TRIGGER IF EXISTS INS_BEFORE"
);
stat
.
execute
(
"DROP TRIGGER IF EXISTS INS_BEFORE"
);
try
{
stat
.
execute
(
"DROP TRIGGER INS_BEFORE"
);
error
(
"must not work"
);
}
catch
(
SQLException
e
)
{
checkNotGeneralException
(
e
);
}
stat
.
execute
(
"DROP TRIGGER INS_AFTER"
);
stat
.
execute
(
"DROP TRIGGER UPD_BEFORE"
);
stat
.
execute
(
"UPDATE TEST SET NAME=NAME||'-upd-notrigger'"
);
stat
.
execute
(
"INSERT INTO TEST VALUES(100, 'Insert-notrigger')"
);
conn
.
close
();
conn
=
getConnection
(
"trigger"
);
mustNotCallTrigger
=
false
;
conn
.
close
();
}
private
void
checkRows
(
ResultSet
rs
,
String
[]
expected
)
throws
Exception
{
HashSet
set
=
new
HashSet
(
Arrays
.
asList
(
expected
));
while
(
rs
.
next
())
{
set
.
remove
(
rs
.
getString
(
1
));
}
if
(
set
.
size
()>
0
)
{
error
(
"set should be empty: "
+
set
);
}
}
private
String
triggerName
;
public
void
fire
(
Connection
conn
,
Object
[]
oldRow
,
Object
[]
newRow
)
throws
SQLException
{
if
(
mustNotCallTrigger
)
{
throw
new
Error
(
"must not be called now"
);
}
if
(
conn
==
null
)
{
throw
new
Error
(
"connection is null"
);
}
if
(
triggerName
.
startsWith
(
"INS_BEFORE"
))
{
newRow
[
1
]
=
newRow
[
1
]
+
"-updated"
;
}
else
if
(
triggerName
.
startsWith
(
"INS_AFTER"
))
{
if
(!
newRow
[
1
].
toString
().
endsWith
(
"-updated"
))
{
throw
new
Error
(
"supposed to be updated"
);
}
}
else
if
(
triggerName
.
startsWith
(
"UPD_BEFORE"
))
{
newRow
[
1
]
=
newRow
[
1
]
+
"-updated2"
;
}
else
if
(
triggerName
.
startsWith
(
"UPD_AFTER"
))
{
if
(!
newRow
[
1
].
toString
().
endsWith
(
"-updated2"
))
{
throw
new
Error
(
"supposed to be updated2"
);
}
}
}
public
void
init
(
Connection
conn
,
String
schemaName
,
String
triggerName
,
String
tableName
)
{
this
.
triggerName
=
triggerName
;
if
(!
"TEST"
.
equals
(
tableName
))
{
throw
new
Error
(
"supposed to be TEST"
);
}
}
}
h2/src/test/org/h2/test/db/TestTwoPhaseCommit.java
0 → 100644
浏览文件 @
68bcd1cb
/*
* Copyright 2004-2006 H2 Group. Licensed under the H2 License, Version 1.0 (http://h2database.com/html/license.html).
* Initial Developer: H2 Group
*/
package
org
.
h2
.
test
.
db
;
import
java.sql.Connection
;
import
java.sql.ResultSet
;
import
java.sql.Statement
;
import
java.util.ArrayList
;
import
org.h2.test.TestBase
;
public
class
TestTwoPhaseCommit
extends
TestBase
{
public
void
test
()
throws
Exception
{
if
(
config
.
memory
||
config
.
networked
||
config
.
logMode
==
0
)
{
return
;
}
deleteDb
(
"twoPhaseCommit"
);
prepare
();
openWith
(
true
);
test
(
true
);
prepare
();
openWith
(
false
);
test
(
false
);
}
void
test
(
boolean
rolledBack
)
throws
Exception
{
Connection
conn
=
getConnection
(
"twoPhaseCommit"
);
Statement
stat
=
conn
.
createStatement
();
stat
.
execute
(
"SET WRITE_DELAY 0"
);
ResultSet
rs
=
stat
.
executeQuery
(
"SELECT * FROM TEST ORDER BY ID"
);
rs
.
next
();
check
(
rs
.
getInt
(
1
),
1
);
check
(
rs
.
getString
(
2
),
"Hello"
);
if
(
rolledBack
)
{
}
else
{
rs
.
next
();
check
(
rs
.
getInt
(
1
),
2
);
check
(
rs
.
getString
(
2
),
"World"
);
}
checkFalse
(
rs
.
next
());
conn
.
close
();
}
void
openWith
(
boolean
rollback
)
throws
Exception
{
Connection
conn
=
getConnection
(
"twoPhaseCommit"
);
Statement
stat
=
conn
.
createStatement
();
ArrayList
list
=
new
ArrayList
();
ResultSet
rs
=
stat
.
executeQuery
(
"SELECT * FROM INFORMATION_SCHEMA.IN_DOUBT"
);
while
(
rs
.
next
())
{
list
.
add
(
rs
.
getString
(
"TRANSACTION"
));
}
for
(
int
i
=
0
;
i
<
list
.
size
();
i
++)
{
String
s
=
(
String
)
list
.
get
(
i
);
if
(
rollback
)
{
stat
.
execute
(
"ROLLBACK TRANSACTION "
+
s
);
}
else
{
stat
.
execute
(
"COMMIT TRANSACTION "
+
s
);
}
}
conn
.
close
();
}
void
prepare
()
throws
Exception
{
deleteDb
(
"twoPhaseCommit"
);
Connection
conn
=
getConnection
(
"twoPhaseCommit"
);
Statement
stat
=
conn
.
createStatement
();
stat
.
execute
(
"SET WRITE_DELAY 0"
);
conn
.
setAutoCommit
(
false
);
stat
.
execute
(
"CREATE TABLE TEST(ID INT PRIMARY KEY, NAME VARCHAR)"
);
stat
.
execute
(
"INSERT INTO TEST VALUES(1, 'Hello')"
);
conn
.
commit
();
stat
.
execute
(
"INSERT INTO TEST VALUES(2, 'World')"
);
stat
.
execute
(
"PREPARE COMMIT XID_TEST_TRANSACTION_WITH_LONG_NAME"
);
crash
(
conn
);
}
}
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论