Skip to content
项目
群组
代码片段
帮助
正在加载...
帮助
为 GitLab 提交贡献
登录/注册
切换导航
H
h2database
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
分枝图
比较
统计图
议题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
计划
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
分枝图
统计图
创建新议题
作业
提交
议题看板
打开侧边栏
Administrator
h2database
Commits
47ed036f
Unverified
提交
47ed036f
authored
2月 18, 2018
作者:
Noel Grandin
提交者:
GitHub
2月 18, 2018
浏览文件
操作
浏览文件
下载
差异文件
Merge pull request #858 from katzyn/generated_keys
Return all generated rows and columns from getGeneratedKeys()
上级
8556fd23
7108c22b
隐藏空白字符变更
内嵌
并排
正在显示
37 个修改的文件
包含
2719 行增加
和
242 行删除
+2719
-242
Command.java
h2/src/main/org/h2/command/Command.java
+11
-5
CommandInterface.java
h2/src/main/org/h2/command/CommandInterface.java
+9
-1
CommandList.java
h2/src/main/org/h2/command/CommandList.java
+1
-1
CommandRemote.java
h2/src/main/org/h2/command/CommandRemote.java
+41
-2
Parser.java
h2/src/main/org/h2/command/Parser.java
+4
-0
Insert.java
h2/src/main/org/h2/command/dml/Insert.java
+20
-1
Merge.java
h2/src/main/org/h2/command/dml/Merge.java
+10
-0
ConnectionInfo.java
h2/src/main/org/h2/engine/ConnectionInfo.java
+2
-1
Constants.java
h2/src/main/org/h2/engine/Constants.java
+15
-0
Engine.java
h2/src/main/org/h2/engine/Engine.java
+2
-2
GeneratedKeys.java
h2/src/main/org/h2/engine/GeneratedKeys.java
+239
-0
GeneratedKeysMode.java
h2/src/main/org/h2/engine/GeneratedKeysMode.java
+67
-0
Session.java
h2/src/main/org/h2/engine/Session.java
+27
-2
SessionInterface.java
h2/src/main/org/h2/engine/SessionInterface.java
+9
-0
SessionRemote.java
h2/src/main/org/h2/engine/SessionRemote.java
+12
-6
SessionWithState.java
h2/src/main/org/h2/engine/SessionWithState.java
+1
-1
FullText.java
h2/src/main/org/h2/fulltext/FullText.java
+5
-2
JdbcCallableStatement.java
h2/src/main/org/h2/jdbc/JdbcCallableStatement.java
+1
-1
JdbcConnection.java
h2/src/main/org/h2/jdbc/JdbcConnection.java
+65
-31
JdbcPreparedStatement.java
h2/src/main/org/h2/jdbc/JdbcPreparedStatement.java
+27
-18
JdbcSavepoint.java
h2/src/main/org/h2/jdbc/JdbcSavepoint.java
+1
-1
JdbcStatement.java
h2/src/main/org/h2/jdbc/JdbcStatement.java
+78
-44
ResultWithGeneratedKeys.java
h2/src/main/org/h2/result/ResultWithGeneratedKeys.java
+71
-0
TriggerObject.java
h2/src/main/org/h2/schema/TriggerObject.java
+3
-1
TcpServerThread.java
h2/src/main/org/h2/server/TcpServerThread.java
+65
-11
WebApp.java
h2/src/main/org/h2/server/web/WebApp.java
+4
-4
FileLock.java
h2/src/main/org/h2/store/FileLock.java
+2
-2
Column.java
h2/src/main/org/h2/table/Column.java
+2
-0
Table.java
h2/src/main/org/h2/table/Table.java
+1
-1
MergedResultSet.java
h2/src/main/org/h2/util/MergedResultSet.java
+141
-0
TestAll.java
h2/src/test/org/h2/test/TestAll.java
+2
-0
TestTriggersConstraints.java
h2/src/test/org/h2/test/db/TestTriggersConstraints.java
+1
-1
TestGetGeneratedKeys.java
h2/src/test/org/h2/test/jdbc/TestGetGeneratedKeys.java
+1760
-0
TestPreparedStatement.java
h2/src/test/org/h2/test/jdbc/TestPreparedStatement.java
+7
-96
TestResultSet.java
h2/src/test/org/h2/test/jdbc/TestResultSet.java
+4
-2
TestStatement.java
h2/src/test/org/h2/test/jdbc/TestStatement.java
+8
-4
TestWeb.java
h2/src/test/org/h2/test/server/TestWeb.java
+1
-1
没有找到文件。
h2/src/main/org/h2/command/Command.java
浏览文件 @
47ed036f
...
...
@@ -15,6 +15,7 @@ import org.h2.expression.ParameterInterface;
import
org.h2.message.DbException
;
import
org.h2.message.Trace
;
import
org.h2.result.ResultInterface
;
import
org.h2.result.ResultWithGeneratedKeys
;
import
org.h2.util.MathUtils
;
/**
...
...
@@ -149,7 +150,7 @@ public abstract class Command implements CommandInterface {
@Override
public
void
stop
()
{
session
.
endStatement
();
session
.
setCurrentCommand
(
null
);
session
.
setCurrentCommand
(
null
,
false
);
if
(!
isTransactional
())
{
session
.
commit
(
true
);
}
else
if
(
session
.
getAutoCommit
())
{
...
...
@@ -193,7 +194,7 @@ public abstract class Command implements CommandInterface {
}
}
synchronized
(
sync
)
{
session
.
setCurrentCommand
(
this
);
session
.
setCurrentCommand
(
this
,
false
);
try
{
while
(
true
)
{
database
.
checkPowerOff
();
...
...
@@ -238,7 +239,7 @@ public abstract class Command implements CommandInterface {
}
@Override
public
int
executeUpdate
(
)
{
public
ResultWithGeneratedKeys
executeUpdate
(
Object
generatedKeysRequest
)
{
long
start
=
0
;
Database
database
=
session
.
getDatabase
();
Object
sync
=
database
.
isMultiThreaded
()
?
(
Object
)
session
:
(
Object
)
database
;
...
...
@@ -252,12 +253,17 @@ public abstract class Command implements CommandInterface {
}
synchronized
(
sync
)
{
Session
.
Savepoint
rollback
=
session
.
setSavepoint
();
session
.
setCurrentCommand
(
this
);
session
.
setCurrentCommand
(
this
,
generatedKeysRequest
);
try
{
while
(
true
)
{
database
.
checkPowerOff
();
try
{
return
update
();
int
updateCount
=
update
();
if
(!
Boolean
.
FALSE
.
equals
(
generatedKeysRequest
))
{
return
new
ResultWithGeneratedKeys
.
WithKeys
(
updateCount
,
session
.
getGeneratedKeys
().
getKeys
(
session
));
}
return
ResultWithGeneratedKeys
.
of
(
updateCount
);
}
catch
(
DbException
e
)
{
start
=
filterConcurrentUpdate
(
e
,
start
);
}
catch
(
OutOfMemoryError
e
)
{
...
...
h2/src/main/org/h2/command/CommandInterface.java
浏览文件 @
47ed036f
...
...
@@ -8,6 +8,7 @@ package org.h2.command;
import
java.util.ArrayList
;
import
org.h2.expression.ParameterInterface
;
import
org.h2.result.ResultInterface
;
import
org.h2.result.ResultWithGeneratedKeys
;
/**
* Represents a SQL statement.
...
...
@@ -510,9 +511,16 @@ public interface CommandInterface {
/**
* Execute the statement
*
* @param generatedKeysRequest
* {@code false} if generated keys are not needed, {@code true} if
* generated keys should be configured automatically, {@code int[]}
* to specify column indices to return generated keys from, or
* {@code String[]} to specify column names to return generated keys
* from
*
* @return the update count
*/
int
executeUpdate
(
);
ResultWithGeneratedKeys
executeUpdate
(
Object
generatedKeysRequest
);
/**
* Stop the command execution, release all locks and resources
...
...
h2/src/main/org/h2/command/CommandList.java
浏览文件 @
47ed036f
...
...
@@ -39,7 +39,7 @@ class CommandList extends Command {
@Override
public
int
update
()
{
int
updateCount
=
command
.
executeUpdate
();
int
updateCount
=
command
.
executeUpdate
(
false
).
getUpdateCount
(
);
executeRemaining
();
return
updateCount
;
}
...
...
h2/src/main/org/h2/command/CommandRemote.java
浏览文件 @
47ed036f
...
...
@@ -9,6 +9,7 @@ import java.io.IOException;
import
java.util.ArrayList
;
import
org.h2.engine.Constants
;
import
org.h2.engine.GeneratedKeysMode
;
import
org.h2.engine.SessionRemote
;
import
org.h2.engine.SysProperties
;
import
org.h2.expression.ParameterInterface
;
...
...
@@ -17,6 +18,7 @@ import org.h2.message.DbException;
import
org.h2.message.Trace
;
import
org.h2.result.ResultInterface
;
import
org.h2.result.ResultRemote
;
import
org.h2.result.ResultWithGeneratedKeys
;
import
org.h2.util.New
;
import
org.h2.value.Transfer
;
import
org.h2.value.Value
;
...
...
@@ -194,10 +196,14 @@ public class CommandRemote implements CommandInterface {
}
@Override
public
int
executeUpdate
(
)
{
public
ResultWithGeneratedKeys
executeUpdate
(
Object
generatedKeysRequest
)
{
checkParameters
();
boolean
supportsGeneratedKeys
=
session
.
isSupportsGeneratedKeys
();
boolean
readGeneratedKeys
=
supportsGeneratedKeys
&&
!
Boolean
.
FALSE
.
equals
(
generatedKeysRequest
);
int
objectId
=
readGeneratedKeys
?
session
.
getNextId
()
:
0
;
synchronized
(
session
)
{
int
updateCount
=
0
;
ResultRemote
generatedKeys
=
null
;
boolean
autoCommit
=
false
;
for
(
int
i
=
0
,
count
=
0
;
i
<
transferList
.
size
();
i
++)
{
prepareIfRequired
();
...
...
@@ -206,9 +212,39 @@ public class CommandRemote implements CommandInterface {
session
.
traceOperation
(
"COMMAND_EXECUTE_UPDATE"
,
id
);
transfer
.
writeInt
(
SessionRemote
.
COMMAND_EXECUTE_UPDATE
).
writeInt
(
id
);
sendParameters
(
transfer
);
if
(
supportsGeneratedKeys
)
{
int
mode
=
GeneratedKeysMode
.
valueOf
(
generatedKeysRequest
);
transfer
.
writeInt
(
mode
);
switch
(
mode
)
{
case
GeneratedKeysMode
.
COLUMN_NUMBERS
:
{
int
[]
keys
=
(
int
[])
generatedKeysRequest
;
transfer
.
writeInt
(
keys
.
length
);
for
(
int
key
:
keys
)
{
transfer
.
writeInt
(
key
);
}
break
;
}
case
GeneratedKeysMode
.
COLUMN_NAMES
:
{
String
[]
keys
=
(
String
[])
generatedKeysRequest
;
transfer
.
writeInt
(
keys
.
length
);
for
(
String
key
:
keys
)
{
transfer
.
writeString
(
key
);
}
break
;
}
}
}
session
.
done
(
transfer
);
updateCount
=
transfer
.
readInt
();
autoCommit
=
transfer
.
readBoolean
();
if
(
readGeneratedKeys
)
{
int
columnCount
=
transfer
.
readInt
();
if
(
generatedKeys
!=
null
)
{
generatedKeys
.
close
();
generatedKeys
=
null
;
}
generatedKeys
=
new
ResultRemote
(
session
,
transfer
,
objectId
,
columnCount
,
Integer
.
MAX_VALUE
);
}
}
catch
(
IOException
e
)
{
session
.
removeServer
(
e
,
i
--,
++
count
);
}
...
...
@@ -216,7 +252,10 @@ public class CommandRemote implements CommandInterface {
session
.
setAutoCommitFromServer
(
autoCommit
);
session
.
autoCommitIfCluster
();
session
.
readSessionState
();
return
updateCount
;
if
(
generatedKeys
!=
null
)
{
return
new
ResultWithGeneratedKeys
.
WithKeys
(
updateCount
,
generatedKeys
);
}
return
ResultWithGeneratedKeys
.
of
(
updateCount
);
}
}
...
...
h2/src/main/org/h2/command/Parser.java
浏览文件 @
47ed036f
...
...
@@ -5667,6 +5667,10 @@ public class Parser {
readIfEqualOrTo
();
read
();
return
new
NoOperation
(
session
);
}
else
if
(
readIf
(
"SCOPE_GENERATED_KEYS"
))
{
readIfEqualOrTo
();
read
();
return
new
NoOperation
(
session
);
}
else
if
(
readIf
(
"SCHEMA"
))
{
readIfEqualOrTo
();
Set
command
=
new
Set
(
session
,
SetTypes
.
SCHEMA
);
...
...
h2/src/main/org/h2/command/dml/Insert.java
浏览文件 @
47ed036f
...
...
@@ -12,6 +12,7 @@ import org.h2.api.Trigger;
import
org.h2.command.Command
;
import
org.h2.command.CommandInterface
;
import
org.h2.command.Prepared
;
import
org.h2.engine.GeneratedKeys
;
import
org.h2.engine.Right
;
import
org.h2.engine.Session
;
import
org.h2.engine.UndoLogRecord
;
...
...
@@ -20,6 +21,7 @@ import org.h2.expression.ConditionAndOr;
import
org.h2.expression.Expression
;
import
org.h2.expression.ExpressionColumn
;
import
org.h2.expression.Parameter
;
import
org.h2.expression.SequenceValue
;
import
org.h2.index.Index
;
import
org.h2.message.DbException
;
import
org.h2.mvstore.db.MVPrimaryIndex
;
...
...
@@ -142,11 +144,14 @@ public class Insert extends Prepared implements ResultTarget {
setCurrentRowNumber
(
0
);
table
.
fire
(
session
,
Trigger
.
INSERT
,
true
);
rowNumber
=
0
;
GeneratedKeys
generatedKeys
=
session
.
getGeneratedKeys
();
generatedKeys
.
initialize
(
table
);
int
listSize
=
list
.
size
();
if
(
listSize
>
0
)
{
int
columnLen
=
columns
.
length
;
for
(
int
x
=
0
;
x
<
listSize
;
x
++)
{
session
.
startStatementWithinTransaction
();
generatedKeys
.
nextRow
();
Row
newRow
=
table
.
getTemplateRow
();
Expression
[]
expr
=
list
.
get
(
x
);
setCurrentRowNumber
(
x
+
1
);
...
...
@@ -160,6 +165,9 @@ public class Insert extends Prepared implements ResultTarget {
try
{
Value
v
=
c
.
convert
(
e
.
getValue
(
session
),
session
.
getDatabase
().
getMode
());
newRow
.
setValue
(
index
,
v
);
if
(
e
instanceof
SequenceValue
)
{
generatedKeys
.
add
(
c
);
}
}
catch
(
DbException
ex
)
{
throw
setRow
(
ex
,
x
,
getSQL
(
expr
));
}
...
...
@@ -179,6 +187,7 @@ public class Insert extends Prepared implements ResultTarget {
continue
;
}
}
generatedKeys
.
confirmRow
(
newRow
);
session
.
log
(
table
,
UndoLogRecord
.
INSERT
,
newRow
);
table
.
fireAfterRow
(
session
,
null
,
newRow
,
false
);
}
...
...
@@ -190,8 +199,12 @@ public class Insert extends Prepared implements ResultTarget {
}
else
{
ResultInterface
rows
=
query
.
query
(
0
);
while
(
rows
.
next
())
{
generatedKeys
.
nextRow
();
Value
[]
r
=
rows
.
currentRow
();
addRow
(
r
);
Row
newRow
=
addRowImpl
(
r
);
if
(
newRow
!=
null
)
{
generatedKeys
.
confirmRow
(
newRow
);
}
}
rows
.
close
();
}
...
...
@@ -202,6 +215,10 @@ public class Insert extends Prepared implements ResultTarget {
@Override
public
void
addRow
(
Value
[]
values
)
{
addRowImpl
(
values
);
}
private
Row
addRowImpl
(
Value
[]
values
)
{
Row
newRow
=
table
.
getTemplateRow
();
setCurrentRowNumber
(++
rowNumber
);
for
(
int
j
=
0
,
len
=
columns
.
length
;
j
<
len
;
j
++)
{
...
...
@@ -220,7 +237,9 @@ public class Insert extends Prepared implements ResultTarget {
table
.
addRow
(
session
,
newRow
);
session
.
log
(
table
,
UndoLogRecord
.
INSERT
,
newRow
);
table
.
fireAfterRow
(
session
,
null
,
newRow
,
false
);
return
newRow
;
}
return
null
;
}
@Override
...
...
h2/src/main/org/h2/command/dml/Merge.java
浏览文件 @
47ed036f
...
...
@@ -11,11 +11,13 @@ import org.h2.api.Trigger;
import
org.h2.command.Command
;
import
org.h2.command.CommandInterface
;
import
org.h2.command.Prepared
;
import
org.h2.engine.GeneratedKeys
;
import
org.h2.engine.Right
;
import
org.h2.engine.Session
;
import
org.h2.engine.UndoLogRecord
;
import
org.h2.expression.Expression
;
import
org.h2.expression.Parameter
;
import
org.h2.expression.SequenceValue
;
import
org.h2.index.Index
;
import
org.h2.message.DbException
;
import
org.h2.result.ResultInterface
;
...
...
@@ -84,11 +86,14 @@ public class Merge extends Prepared {
session
.
getUser
().
checkRight
(
targetTable
,
Right
.
INSERT
);
session
.
getUser
().
checkRight
(
targetTable
,
Right
.
UPDATE
);
setCurrentRowNumber
(
0
);
GeneratedKeys
generatedKeys
=
session
.
getGeneratedKeys
();
if
(!
valuesExpressionList
.
isEmpty
())
{
// process values in list
count
=
0
;
generatedKeys
.
initialize
(
targetTable
);
for
(
int
x
=
0
,
size
=
valuesExpressionList
.
size
();
x
<
size
;
x
++)
{
setCurrentRowNumber
(
x
+
1
);
generatedKeys
.
nextRow
();
Expression
[]
expr
=
valuesExpressionList
.
get
(
x
);
Row
newRow
=
targetTable
.
getTemplateRow
();
for
(
int
i
=
0
,
len
=
columns
.
length
;
i
<
len
;
i
++)
{
...
...
@@ -100,6 +105,9 @@ public class Merge extends Prepared {
try
{
Value
v
=
c
.
convert
(
e
.
getValue
(
session
));
newRow
.
setValue
(
index
,
v
);
if
(
e
instanceof
SequenceValue
)
{
generatedKeys
.
add
(
c
);
}
}
catch
(
DbException
ex
)
{
throw
setRow
(
ex
,
count
,
getSQL
(
expr
));
}
...
...
@@ -116,6 +124,7 @@ public class Merge extends Prepared {
targetTable
.
lock
(
session
,
true
,
false
);
while
(
rows
.
next
())
{
count
++;
generatedKeys
.
nextRow
();
Value
[]
r
=
rows
.
currentRow
();
Row
newRow
=
targetTable
.
getTemplateRow
();
setCurrentRowNumber
(
count
);
...
...
@@ -171,6 +180,7 @@ public class Merge extends Prepared {
if
(!
done
)
{
targetTable
.
lock
(
session
,
true
,
false
);
targetTable
.
addRow
(
session
,
row
);
session
.
getGeneratedKeys
().
confirmRow
(
row
);
session
.
log
(
targetTable
,
UndoLogRecord
.
INSERT
,
row
);
targetTable
.
fireAfterRow
(
session
,
null
,
row
,
false
);
}
...
...
h2/src/main/org/h2/engine/ConnectionInfo.java
浏览文件 @
47ed036f
...
...
@@ -96,7 +96,8 @@ public class ConnectionInfo implements Cloneable {
"CREATE"
,
"CACHE_TYPE"
,
"FILE_LOCK"
,
"IGNORE_UNKNOWN_SETTINGS"
,
"IFEXISTS"
,
"INIT"
,
"PASSWORD"
,
"RECOVER"
,
"RECOVER_TEST"
,
"USER"
,
"AUTO_SERVER"
,
"AUTO_SERVER_PORT"
,
"NO_UPGRADE"
,
"AUTO_RECONNECT"
,
"OPEN_NEW"
,
"PAGE_SIZE"
,
"PASSWORD_HASH"
,
"JMX"
};
"AUTO_RECONNECT"
,
"OPEN_NEW"
,
"PAGE_SIZE"
,
"PASSWORD_HASH"
,
"JMX"
,
"SCOPE_GENERATED_KEYS"
};
HashSet
<
String
>
set
=
new
HashSet
<>(
list
.
size
()
+
connectionTime
.
length
);
set
.
addAll
(
list
);
for
(
String
key
:
connectionTime
)
{
...
...
h2/src/main/org/h2/engine/Constants.java
浏览文件 @
47ed036f
...
...
@@ -100,6 +100,21 @@ public class Constants {
*/
public
static
final
int
TCP_PROTOCOL_VERSION_16
=
16
;
/**
* The TCP protocol version number 17.
*/
public
static
final
int
TCP_PROTOCOL_VERSION_17
=
17
;
/**
* Minimum supported version of TCP protocol.
*/
public
static
final
int
TCP_PROTOCOL_VERSION_MIN_SUPPORTED
=
TCP_PROTOCOL_VERSION_6
;
/**
* Maximum supported version of TCP protocol.
*/
public
static
final
int
TCP_PROTOCOL_VERSION_MAX_SUPPORTED
=
TCP_PROTOCOL_VERSION_17
;
/**
* The major version of this database.
*/
...
...
h2/src/main/org/h2/engine/Engine.java
浏览文件 @
47ed036f
...
...
@@ -206,7 +206,7 @@ public class Engine implements SessionFactory {
CommandInterface
command
=
session
.
prepareCommand
(
"SET "
+
Parser
.
quoteIdentifier
(
setting
)
+
" "
+
value
,
Integer
.
MAX_VALUE
);
command
.
executeUpdate
();
command
.
executeUpdate
(
false
);
}
catch
(
DbException
e
)
{
if
(
e
.
getErrorCode
()
==
ErrorCode
.
ADMIN_RIGHTS_REQUIRED
)
{
session
.
getTrace
().
error
(
e
,
"admin rights required; user: \""
+
...
...
@@ -224,7 +224,7 @@ public class Engine implements SessionFactory {
try
{
CommandInterface
command
=
session
.
prepareCommand
(
init
,
Integer
.
MAX_VALUE
);
command
.
executeUpdate
();
command
.
executeUpdate
(
false
);
}
catch
(
DbException
e
)
{
if
(!
ignoreUnknownSetting
)
{
session
.
close
();
...
...
h2/src/main/org/h2/engine/GeneratedKeys.java
0 → 100644
浏览文件 @
47ed036f
/*
* Copyright 2004-2018 H2 Group. Multiple-Licensed under the MPL 2.0,
* and the EPL 1.0 (http://h2database.com/html/license.html).
* Initial Developer: H2 Group
*/
package
org
.
h2
.
engine
;
import
java.util.ArrayList
;
import
java.util.Collections
;
import
java.util.HashMap
;
import
java.util.Map
;
import
org.h2.expression.Expression
;
import
org.h2.expression.ExpressionColumn
;
import
org.h2.result.LocalResult
;
import
org.h2.result.Row
;
import
org.h2.table.Column
;
import
org.h2.table.Table
;
import
org.h2.util.New
;
import
org.h2.util.StringUtils
;
import
org.h2.value.Value
;
import
org.h2.value.ValueNull
;
/**
* Class for gathering and processing of generated keys.
*/
public
final
class
GeneratedKeys
{
/**
* Data for result set with generated keys.
*/
private
final
ArrayList
<
Map
<
Column
,
Value
>>
data
=
New
.
arrayList
();
/**
* Columns with generated keys in the current row.
*/
private
final
ArrayList
<
Column
>
row
=
New
.
arrayList
();
/**
* All columns with generated keys.
*/
private
final
ArrayList
<
Column
>
allColumns
=
New
.
arrayList
();
/**
* Request for keys gathering. {@code false} if generated keys are not needed,
* {@code true} if generated keys should be configured automatically,
* {@code int[]} to specify column indices to return generated keys from, or
* {@code String[]} to specify column names to return generated keys from.
*/
private
Object
generatedKeysRequest
;
/**
* Processed table.
*/
private
Table
table
;
/**
* Remembers columns with generated keys.
*
* @param column
* table column
*/
public
void
add
(
Column
column
)
{
if
(
Boolean
.
FALSE
.
equals
(
generatedKeysRequest
))
{
return
;
}
row
.
add
(
column
);
}
/**
* Clears all information from previous runs and sets a new request for
* gathering of generated keys.
*
* @param generatedKeysRequest
* {@code false} if generated keys are not needed, {@code true} if
* generated keys should be configured automatically, {@code int[]}
* to specify column indices to return generated keys from, or
* {@code String[]} to specify column names to return generated keys
* from
*/
public
void
clear
(
Object
generatedKeysRequest
)
{
this
.
generatedKeysRequest
=
generatedKeysRequest
;
data
.
clear
();
row
.
clear
();
allColumns
.
clear
();
table
=
null
;
}
/**
* Saves row with generated keys if any.
*
* @param tableRow
* table row that was inserted
*/
public
void
confirmRow
(
Row
tableRow
)
{
if
(
Boolean
.
FALSE
.
equals
(
generatedKeysRequest
))
{
return
;
}
int
size
=
row
.
size
();
if
(
size
>
0
)
{
if
(
size
==
1
)
{
Column
column
=
row
.
get
(
0
);
data
.
add
(
Collections
.
singletonMap
(
column
,
tableRow
.
getValue
(
column
.
getColumnId
())));
if
(!
allColumns
.
contains
(
column
))
{
allColumns
.
add
(
column
);
}
}
else
{
HashMap
<
Column
,
Value
>
map
=
new
HashMap
<>();
for
(
Column
column
:
row
)
{
map
.
put
(
column
,
tableRow
.
getValue
(
column
.
getColumnId
()));
if
(!
allColumns
.
contains
(
column
))
{
allColumns
.
add
(
column
);
}
}
data
.
add
(
map
);
}
row
.
clear
();
}
}
/**
* Returns generated keys.
*
* @return local result with generated keys
*/
public
LocalResult
getKeys
(
Session
session
)
{
Database
db
=
session
==
null
?
null
:
session
.
getDatabase
();
if
(
Boolean
.
FALSE
.
equals
(
generatedKeysRequest
))
{
clear
(
null
);
return
new
LocalResult
();
}
ArrayList
<
ExpressionColumn
>
expressionColumns
;
if
(
Boolean
.
TRUE
.
equals
(
generatedKeysRequest
))
{
expressionColumns
=
new
ArrayList
<>(
allColumns
.
size
());
for
(
Column
column
:
allColumns
)
{
expressionColumns
.
add
(
new
ExpressionColumn
(
db
,
column
));
}
}
else
if
(
generatedKeysRequest
instanceof
int
[])
{
if
(
table
!=
null
)
{
int
[]
indices
=
(
int
[])
generatedKeysRequest
;
Column
[]
columns
=
table
.
getColumns
();
int
cnt
=
columns
.
length
;
allColumns
.
clear
();
expressionColumns
=
new
ArrayList
<>(
indices
.
length
);
for
(
int
idx
:
indices
)
{
if
(
idx
>=
1
&&
idx
<=
cnt
)
{
Column
column
=
columns
[
idx
-
1
];
expressionColumns
.
add
(
new
ExpressionColumn
(
db
,
column
));
allColumns
.
add
(
column
);
}
}
}
else
{
clear
(
null
);
return
new
LocalResult
();
}
}
else
if
(
generatedKeysRequest
instanceof
String
[])
{
if
(
table
!=
null
)
{
String
[]
names
=
(
String
[])
generatedKeysRequest
;
allColumns
.
clear
();
expressionColumns
=
new
ArrayList
<>(
names
.
length
);
for
(
String
name
:
names
)
{
Column
column
;
search:
if
(
table
.
doesColumnExist
(
name
))
{
column
=
table
.
getColumn
(
name
);
}
else
{
name
=
StringUtils
.
toUpperEnglish
(
name
);
if
(
table
.
doesColumnExist
(
name
))
{
column
=
table
.
getColumn
(
name
);
}
else
{
for
(
Column
c
:
table
.
getColumns
())
{
if
(
c
.
getName
().
equalsIgnoreCase
(
name
))
{
column
=
c
;
break
search
;
}
}
continue
;
}
}
expressionColumns
.
add
(
new
ExpressionColumn
(
db
,
column
));
allColumns
.
add
(
column
);
}
}
else
{
clear
(
null
);
return
new
LocalResult
();
}
}
else
{
clear
(
null
);
return
new
LocalResult
();
}
int
columnCount
=
expressionColumns
.
size
();
if
(
columnCount
==
0
)
{
clear
(
null
);
return
new
LocalResult
();
}
LocalResult
result
=
new
LocalResult
(
session
,
expressionColumns
.
toArray
(
new
Expression
[
0
]),
columnCount
);
for
(
Map
<
Column
,
Value
>
map
:
data
)
{
Value
[]
row
=
new
Value
[
columnCount
];
for
(
Map
.
Entry
<
Column
,
Value
>
entry
:
map
.
entrySet
())
{
int
idx
=
allColumns
.
indexOf
(
entry
.
getKey
());
if
(
idx
>=
0
)
{
row
[
idx
]
=
entry
.
getValue
();
}
}
for
(
int
i
=
0
;
i
<
columnCount
;
i
++)
{
if
(
row
[
i
]
==
null
)
{
row
[
i
]
=
ValueNull
.
INSTANCE
;
}
}
result
.
addRow
(
row
);
}
clear
(
null
);
return
result
;
}
/**
* Initializes processing of the specified table. Should be called after
* {@code clear()}, but before other methods.
*
* @param table
* table
*/
public
void
initialize
(
Table
table
)
{
this
.
table
=
table
;
}
/**
* Clears unsaved information about previous row, if any. Should be called
* before processing of a new row if previous row was not confirmed or simply
* always before each row.
*/
public
void
nextRow
()
{
row
.
clear
();
}
@Override
public
String
toString
()
{
return
allColumns
+
": "
+
data
.
size
();
}
}
h2/src/main/org/h2/engine/GeneratedKeysMode.java
0 → 100644
浏览文件 @
47ed036f
/*
* Copyright 2004-2018 H2 Group. Multiple-Licensed under the MPL 2.0,
* and the EPL 1.0 (http://h2database.com/html/license.html).
* Initial Developer: H2 Group
*/
package
org
.
h2
.
engine
;
import
org.h2.api.ErrorCode
;
import
org.h2.message.DbException
;
/**
* Modes of generated keys' gathering.
*/
public
final
class
GeneratedKeysMode
{
/**
* Generated keys are not needed.
*/
public
static
final
int
NONE
=
0
;
/**
* Generated keys should be configured automatically.
*/
public
static
final
int
AUTO
=
1
;
/**
* Use specified column indices to return generated keys from.
*/
public
static
final
int
COLUMN_NUMBERS
=
2
;
/**
* Use specified column names to return generated keys from.
*/
public
static
final
int
COLUMN_NAMES
=
3
;
/**
* Determines mode of generated keys' gathering.
*
* @param generatedKeysRequest
* {@code false} if generated keys are not needed, {@code true} if
* generated keys should be configured automatically, {@code int[]}
* to specify column indices to return generated keys from, or
* {@code String[]} to specify column names to return generated keys
* from
* @return mode for the specified generated keys request
*/
public
static
int
valueOf
(
Object
generatedKeysRequest
)
{
if
(
Boolean
.
FALSE
.
equals
(
generatedKeysRequest
))
{
return
NONE
;
}
if
(
Boolean
.
TRUE
.
equals
(
generatedKeysRequest
))
{
return
AUTO
;
}
if
(
generatedKeysRequest
instanceof
int
[])
{
return
COLUMN_NUMBERS
;
}
if
(
generatedKeysRequest
instanceof
String
[])
{
return
COLUMN_NAMES
;
}
throw
DbException
.
get
(
ErrorCode
.
INVALID_VALUE_2
,
generatedKeysRequest
==
null
?
"null"
:
generatedKeysRequest
.
toString
());
}
private
GeneratedKeysMode
()
{
}
}
h2/src/main/org/h2/engine/Session.java
浏览文件 @
47ed036f
...
...
@@ -85,6 +85,7 @@ public class Session extends SessionWithState {
private
Value
lastIdentity
=
ValueLong
.
get
(
0
);
private
Value
lastScopeIdentity
=
ValueLong
.
get
(
0
);
private
Value
lastTriggerIdentity
;
private
GeneratedKeys
generatedKeys
;
private
int
firstUncommittedLog
=
Session
.
LOG_WRITTEN
;
private
int
firstUncommittedPos
=
Session
.
LOG_WRITTEN
;
private
HashMap
<
String
,
Savepoint
>
savepoints
;
...
...
@@ -1075,6 +1076,13 @@ public class Session extends SessionWithState {
return
lastTriggerIdentity
;
}
public
GeneratedKeys
getGeneratedKeys
()
{
if
(
generatedKeys
==
null
)
{
generatedKeys
=
new
GeneratedKeys
();
}
return
generatedKeys
;
}
/**
* Called when a log entry for this session is added. The session keeps
* track of the first entry in the transaction log that is not yet
...
...
@@ -1237,9 +1245,20 @@ public class Session extends SessionWithState {
* executing the statement.
*
* @param command the command
*/
public
void
setCurrentCommand
(
Command
command
)
{
* @param generatedKeysRequest
* {@code false} if generated keys are not needed, {@code true} if
* generated keys should be configured automatically, {@code int[]}
* to specify column indices to return generated keys from, or
* {@code String[]} to specify column names to return generated keys
* from
*/
public
void
setCurrentCommand
(
Command
command
,
Object
generatedKeysRequest
)
{
this
.
currentCommand
=
command
;
// Preserve generated keys in case of a new query due to possible nested
// queries in update
if
(
command
!=
null
&&
!
command
.
isQuery
())
{
getGeneratedKeys
().
clear
(
generatedKeysRequest
);
}
if
(
queryTimeout
>
0
&&
command
!=
null
)
{
currentCommandStart
=
System
.
currentTimeMillis
();
long
now
=
System
.
nanoTime
();
...
...
@@ -1790,4 +1809,10 @@ public class Session extends SessionWithState {
public
void
setColumnNamerConfiguration
(
ColumnNamerConfiguration
columnNamerConfiguration
)
{
this
.
columnNamerConfiguration
=
columnNamerConfiguration
;
}
@Override
public
boolean
isSupportsGeneratedKeys
()
{
return
true
;
}
}
h2/src/main/org/h2/engine/SessionInterface.java
浏览文件 @
47ed036f
...
...
@@ -153,4 +153,13 @@ public interface SessionInterface extends Closeable {
* @return the current schema name
*/
String
getCurrentSchemaName
();
/**
* Returns is this session supports generated keys.
*
* @return {@code true} if generated keys are supported, {@code false} if only
* {@code SCOPE_IDENTITY()} is supported
*/
boolean
isSupportsGeneratedKeys
();
}
h2/src/main/org/h2/engine/SessionRemote.java
浏览文件 @
47ed036f
...
...
@@ -117,8 +117,8 @@ public class SessionRemote extends SessionWithState implements DataHandler {
Transfer
trans
=
new
Transfer
(
this
,
socket
);
trans
.
setSSL
(
ci
.
isSSL
());
trans
.
init
();
trans
.
writeInt
(
Constants
.
TCP_PROTOCOL_VERSION_
6
);
trans
.
writeInt
(
Constants
.
TCP_PROTOCOL_VERSION_
16
);
trans
.
writeInt
(
Constants
.
TCP_PROTOCOL_VERSION_
MIN_SUPPORTED
);
trans
.
writeInt
(
Constants
.
TCP_PROTOCOL_VERSION_
MAX_SUPPORTED
);
trans
.
writeString
(
db
);
trans
.
writeString
(
ci
.
getOriginalURL
());
trans
.
writeString
(
ci
.
getUserName
());
...
...
@@ -210,7 +210,7 @@ public class SessionRemote extends SessionWithState implements DataHandler {
CommandInterface
c
=
prepareCommand
(
"SET CLUSTER "
+
serverList
,
Integer
.
MAX_VALUE
);
// this will set autoCommit to false
c
.
executeUpdate
();
c
.
executeUpdate
(
false
);
// so we need to switch it on
autoCommit
=
true
;
cluster
=
true
;
...
...
@@ -265,13 +265,13 @@ public class SessionRemote extends SessionWithState implements DataHandler {
autoCommitTrue
=
prepareCommand
(
"SET AUTOCOMMIT TRUE"
,
Integer
.
MAX_VALUE
);
}
autoCommitTrue
.
executeUpdate
();
autoCommitTrue
.
executeUpdate
(
false
);
}
else
{
if
(
autoCommitFalse
==
null
)
{
autoCommitFalse
=
prepareCommand
(
"SET AUTOCOMMIT FALSE"
,
Integer
.
MAX_VALUE
);
}
autoCommitFalse
.
executeUpdate
();
autoCommitFalse
.
executeUpdate
(
false
);
}
}
}
...
...
@@ -468,7 +468,7 @@ public class SessionRemote extends SessionWithState implements DataHandler {
private
void
switchOffCluster
()
{
CommandInterface
ci
=
prepareCommand
(
"SET CLUSTER ''"
,
Integer
.
MAX_VALUE
);
ci
.
executeUpdate
();
ci
.
executeUpdate
(
false
);
}
/**
...
...
@@ -869,4 +869,10 @@ public class SessionRemote extends SessionWithState implements DataHandler {
public
void
setCurrentSchemaName
(
String
schema
)
{
throw
DbException
.
getUnsupportedException
(
"setSchema && remote session"
);
}
@Override
public
boolean
isSupportsGeneratedKeys
()
{
return
getClientVersion
()
>=
Constants
.
TCP_PROTOCOL_VERSION_17
;
}
}
h2/src/main/org/h2/engine/SessionWithState.java
浏览文件 @
47ed036f
...
...
@@ -29,7 +29,7 @@ abstract class SessionWithState implements SessionInterface {
try
{
for
(
String
sql
:
sessionState
)
{
CommandInterface
ci
=
prepareCommand
(
sql
,
Integer
.
MAX_VALUE
);
ci
.
executeUpdate
();
ci
.
executeUpdate
(
false
);
}
}
finally
{
sessionStateUpdating
=
false
;
...
...
h2/src/main/org/h2/fulltext/FullText.java
浏览文件 @
47ed036f
...
...
@@ -950,7 +950,8 @@ public class FullText {
useOwnConnection
=
isMultiThread
(
conn
);
if
(!
useOwnConnection
)
{
for
(
int
i
=
0
;
i
<
SQL
.
length
;
i
++)
{
prepStatements
[
i
]
=
conn
.
prepareStatement
(
SQL
[
i
]);
prepStatements
[
i
]
=
conn
.
prepareStatement
(
SQL
[
i
],
Statement
.
RETURN_GENERATED_KEYS
);
}
}
}
...
...
@@ -1154,7 +1155,9 @@ public class FullText {
}
private
PreparedStatement
getStatement
(
Connection
conn
,
int
index
)
throws
SQLException
{
return
useOwnConnection
?
conn
.
prepareStatement
(
SQL
[
index
])
:
prepStatements
[
index
];
return
useOwnConnection
?
conn
.
prepareStatement
(
SQL
[
index
],
Statement
.
RETURN_GENERATED_KEYS
)
:
prepStatements
[
index
];
}
}
...
...
h2/src/main/org/h2/jdbc/JdbcCallableStatement.java
浏览文件 @
47ed036f
...
...
@@ -47,7 +47,7 @@ public class JdbcCallableStatement extends JdbcPreparedStatement implements
JdbcCallableStatement
(
JdbcConnection
conn
,
String
sql
,
int
id
,
int
resultSetType
,
int
resultSetConcurrency
)
{
super
(
conn
,
sql
,
id
,
resultSetType
,
resultSetConcurrency
,
false
);
super
(
conn
,
sql
,
id
,
resultSetType
,
resultSetConcurrency
,
false
,
false
);
setTrace
(
session
.
getTrace
(),
TraceObject
.
CALLABLE_STATEMENT
,
id
);
}
...
...
h2/src/main/org/h2/jdbc/JdbcConnection.java
浏览文件 @
47ed036f
...
...
@@ -94,6 +94,7 @@ public class JdbcConnection extends TraceObject
private
Map
<
String
,
String
>
clientInfo
;
private
String
mode
;
private
final
boolean
scopeGeneratedKeys
;
/**
* INTERNAL
...
...
@@ -132,6 +133,7 @@ public class JdbcConnection extends TraceObject
+
", \"\");"
);
}
this
.
url
=
ci
.
getURL
();
scopeGeneratedKeys
=
ci
.
getProperty
(
"SCOPE_GENERATED_KEYS"
,
false
);
closeOld
();
watcher
=
CloseWatcher
.
register
(
this
,
session
,
keepOpenStackTrace
);
}
catch
(
Exception
e
)
{
...
...
@@ -156,6 +158,7 @@ public class JdbcConnection extends TraceObject
this
.
getQueryTimeout
=
clone
.
getQueryTimeout
;
this
.
getReadOnly
=
clone
.
getReadOnly
;
this
.
rollback
=
clone
.
rollback
;
this
.
scopeGeneratedKeys
=
clone
.
scopeGeneratedKeys
;
this
.
watcher
=
null
;
if
(
clone
.
clientInfo
!=
null
)
{
this
.
clientInfo
=
new
HashMap
<>(
clone
.
clientInfo
);
...
...
@@ -172,6 +175,7 @@ public class JdbcConnection extends TraceObject
setTrace
(
trace
,
TraceObject
.
CONNECTION
,
id
);
this
.
user
=
user
;
this
.
url
=
url
;
this
.
scopeGeneratedKeys
=
false
;
this
.
watcher
=
null
;
}
...
...
@@ -299,7 +303,7 @@ public class JdbcConnection extends TraceObject
sql
=
translateSQL
(
sql
);
return
new
JdbcPreparedStatement
(
this
,
sql
,
id
,
ResultSet
.
TYPE_FORWARD_ONLY
,
Constants
.
DEFAULT_RESULT_SET_CONCURRENCY
,
false
);
Constants
.
DEFAULT_RESULT_SET_CONCURRENCY
,
false
,
false
);
}
catch
(
Exception
e
)
{
throw
logAndConvert
(
e
);
}
...
...
@@ -325,7 +329,7 @@ public class JdbcConnection extends TraceObject
sql
=
translateSQL
(
sql
);
return
new
JdbcPreparedStatement
(
this
,
sql
,
id
,
ResultSet
.
TYPE_FORWARD_ONLY
,
Constants
.
DEFAULT_RESULT_SET_CONCURRENCY
,
true
);
Constants
.
DEFAULT_RESULT_SET_CONCURRENCY
,
true
,
false
);
}
catch
(
Exception
e
)
{
throw
logAndConvert
(
e
);
}
...
...
@@ -490,7 +494,7 @@ public class JdbcConnection extends TraceObject
checkClosedForWrite
();
try
{
commit
=
prepareCommand
(
"COMMIT"
,
commit
);
commit
.
executeUpdate
();
commit
.
executeUpdate
(
false
);
}
finally
{
afterWriting
();
}
...
...
@@ -688,7 +692,7 @@ public class JdbcConnection extends TraceObject
checkClosed
();
sql
=
translateSQL
(
sql
);
return
new
JdbcPreparedStatement
(
this
,
sql
,
id
,
resultSetType
,
resultSetConcurrency
,
false
);
resultSetConcurrency
,
false
,
false
);
}
catch
(
Exception
e
)
{
throw
logAndConvert
(
e
);
}
...
...
@@ -743,7 +747,7 @@ public class JdbcConnection extends TraceObject
setLockMode
=
prepareCommand
(
"SET LOCK_MODE ?"
,
setLockMode
);
setLockMode
.
getParameters
().
get
(
0
).
setValue
(
ValueInt
.
get
(
lockMode
),
false
);
setLockMode
.
executeUpdate
();
setLockMode
.
executeUpdate
(
false
);
}
catch
(
Exception
e
)
{
throw
logAndConvert
(
e
);
}
...
...
@@ -760,7 +764,7 @@ public class JdbcConnection extends TraceObject
setQueryTimeout
);
setQueryTimeout
.
getParameters
().
get
(
0
)
.
setValue
(
ValueInt
.
get
(
seconds
*
1000
),
false
);
setQueryTimeout
.
executeUpdate
();
setQueryTimeout
.
executeUpdate
(
false
);
queryTimeoutCache
=
seconds
;
}
catch
(
Exception
e
)
{
throw
logAndConvert
(
e
);
...
...
@@ -1016,7 +1020,7 @@ public class JdbcConnection extends TraceObject
CommandInterface
set
=
prepareCommand
(
"SAVEPOINT "
+
JdbcSavepoint
.
getName
(
null
,
savepointId
),
Integer
.
MAX_VALUE
);
set
.
executeUpdate
();
set
.
executeUpdate
(
false
);
JdbcSavepoint
savepoint
=
new
JdbcSavepoint
(
this
,
savepointId
,
null
,
trace
,
id
);
savepointId
++;
...
...
@@ -1044,7 +1048,7 @@ public class JdbcConnection extends TraceObject
CommandInterface
set
=
prepareCommand
(
"SAVEPOINT "
+
JdbcSavepoint
.
getName
(
name
,
0
),
Integer
.
MAX_VALUE
);
set
.
executeUpdate
();
set
.
executeUpdate
(
false
);
JdbcSavepoint
savepoint
=
new
JdbcSavepoint
(
this
,
0
,
name
,
trace
,
id
);
return
savepoint
;
...
...
@@ -1130,19 +1134,20 @@ public class JdbcConnection extends TraceObject
checkClosed
();
sql
=
translateSQL
(
sql
);
return
new
JdbcPreparedStatement
(
this
,
sql
,
id
,
resultSetType
,
resultSetConcurrency
,
false
);
resultSetConcurrency
,
false
,
false
);
}
catch
(
Exception
e
)
{
throw
logAndConvert
(
e
);
}
}
/**
* Creates a new prepared statement. This method just calls
* prepareStatement(String sql) internally. The method getGeneratedKeys only
* supports one column.
* Creates a new prepared statement.
*
* @param sql the SQL statement
* @param autoGeneratedKeys ignored
* @param autoGeneratedKeys
* {@link Statement#RETURN_GENERATED_KEYS} if generated keys should
* be available for retrieval, {@link Statement#NO_GENERATED_KEYS} if
* generated keys should not be available
* @return the prepared statement
* @throws SQLException if the connection is closed
*/
...
...
@@ -1150,23 +1155,31 @@ public class JdbcConnection extends TraceObject
public
PreparedStatement
prepareStatement
(
String
sql
,
int
autoGeneratedKeys
)
throws
SQLException
{
try
{
int
id
=
getNextId
(
TraceObject
.
PREPARED_STATEMENT
);
if
(
isDebugEnabled
())
{
debugCode
(
"prepareStatement("
+
quote
(
sql
)
+
", "
+
autoGeneratedKeys
+
");"
);
debugCodeAssign
(
"PreparedStatement"
,
TraceObject
.
PREPARED_STATEMENT
,
id
,
"prepareStatement("
+
quote
(
sql
)
+
", "
+
autoGeneratedKeys
+
");"
);
}
return
prepareStatement
(
sql
);
checkClosed
();
sql
=
translateSQL
(
sql
);
return
new
JdbcPreparedStatement
(
this
,
sql
,
id
,
ResultSet
.
TYPE_FORWARD_ONLY
,
Constants
.
DEFAULT_RESULT_SET_CONCURRENCY
,
false
,
autoGeneratedKeys
==
Statement
.
RETURN_GENERATED_KEYS
);
}
catch
(
Exception
e
)
{
throw
logAndConvert
(
e
);
}
}
/**
* Creates a new prepared statement. This method just calls
* prepareStatement(String sql) internally. The method getGeneratedKeys only
* supports one column.
* Creates a new prepared statement.
*
* @param sql the SQL statement
* @param columnIndexes ignored
* @param columnIndexes
* an array of column indexes indicating the columns with generated
* keys that should be returned from the inserted row
* @return the prepared statement
* @throws SQLException if the connection is closed
*/
...
...
@@ -1174,23 +1187,30 @@ public class JdbcConnection extends TraceObject
public
PreparedStatement
prepareStatement
(
String
sql
,
int
[]
columnIndexes
)
throws
SQLException
{
try
{
int
id
=
getNextId
(
TraceObject
.
PREPARED_STATEMENT
);
if
(
isDebugEnabled
())
{
debugCode
(
"prepareStatement("
+
quote
(
sql
)
+
", "
+
quoteIntArray
(
columnIndexes
)
+
");"
);
debugCodeAssign
(
"PreparedStatement"
,
TraceObject
.
PREPARED_STATEMENT
,
id
,
"prepareStatement("
+
quote
(
sql
)
+
", "
+
quoteIntArray
(
columnIndexes
)
+
");"
);
}
return
prepareStatement
(
sql
);
checkClosed
();
sql
=
translateSQL
(
sql
);
return
new
JdbcPreparedStatement
(
this
,
sql
,
id
,
ResultSet
.
TYPE_FORWARD_ONLY
,
Constants
.
DEFAULT_RESULT_SET_CONCURRENCY
,
false
,
columnIndexes
);
}
catch
(
Exception
e
)
{
throw
logAndConvert
(
e
);
}
}
/**
* Creates a new prepared statement. This method just calls
* prepareStatement(String sql) internally. The method getGeneratedKeys only
* supports one column.
* Creates a new prepared statement.
*
* @param sql the SQL statement
* @param columnNames ignored
* @param columnNames
* an array of column names indicating the columns with generated
* keys that should be returned from the inserted row
* @return the prepared statement
* @throws SQLException if the connection is closed
*/
...
...
@@ -1198,11 +1218,18 @@ public class JdbcConnection extends TraceObject
public
PreparedStatement
prepareStatement
(
String
sql
,
String
[]
columnNames
)
throws
SQLException
{
try
{
int
id
=
getNextId
(
TraceObject
.
PREPARED_STATEMENT
);
if
(
isDebugEnabled
())
{
debugCode
(
"prepareStatement("
+
quote
(
sql
)
+
", "
+
quoteArray
(
columnNames
)
+
");"
);
debugCodeAssign
(
"PreparedStatement"
,
TraceObject
.
PREPARED_STATEMENT
,
id
,
"prepareStatement("
+
quote
(
sql
)
+
", "
+
quoteArray
(
columnNames
)
+
");"
);
}
return
prepareStatement
(
sql
);
checkClosed
();
sql
=
translateSQL
(
sql
);
return
new
JdbcPreparedStatement
(
this
,
sql
,
id
,
ResultSet
.
TYPE_FORWARD_ONLY
,
Constants
.
DEFAULT_RESULT_SET_CONCURRENCY
,
false
,
columnNames
);
}
catch
(
Exception
e
)
{
throw
logAndConvert
(
e
);
}
...
...
@@ -1529,7 +1556,7 @@ public class JdbcConnection extends TraceObject
private
void
rollbackInternal
()
{
rollback
=
prepareCommand
(
"ROLLBACK"
,
rollback
);
rollback
.
executeUpdate
();
rollback
.
executeUpdate
(
false
);
}
/**
...
...
@@ -1556,6 +1583,13 @@ public class JdbcConnection extends TraceObject
executingStatement
=
stat
;
}
/**
* INTERNAL
*/
boolean
scopeGeneratedKeys
()
{
return
scopeGeneratedKeys
;
}
/**
* INTERNAL
*/
...
...
h2/src/main/org/h2/jdbc/JdbcPreparedStatement.java
浏览文件 @
47ed036f
...
...
@@ -31,9 +31,10 @@ import org.h2.expression.ParameterInterface;
import
org.h2.message.DbException
;
import
org.h2.message.TraceObject
;
import
org.h2.result.ResultInterface
;
import
org.h2.
tools.SimpleResultSet
;
import
org.h2.
result.ResultWithGeneratedKeys
;
import
org.h2.util.DateTimeUtils
;
import
org.h2.util.IOUtils
;
import
org.h2.util.MergedResultSet
;
import
org.h2.util.New
;
import
org.h2.value.DataType
;
import
org.h2.value.Value
;
...
...
@@ -61,13 +62,15 @@ public class JdbcPreparedStatement extends JdbcStatement implements
protected
CommandInterface
command
;
private
final
String
sqlStatement
;
private
ArrayList
<
Value
[]>
batchParameters
;
private
ArrayList
<
Object
>
batchIdentities
;
private
MergedResultSet
batchIdentities
;
private
HashMap
<
String
,
Integer
>
cachedColumnLabelMap
;
private
final
Object
generatedKeysRequest
;
JdbcPreparedStatement
(
JdbcConnection
conn
,
String
sql
,
int
id
,
int
resultSetType
,
int
resultSetConcurrency
,
boolean
closeWithResultSet
)
{
boolean
closeWithResultSet
,
Object
generatedKeysRequest
)
{
super
(
conn
,
id
,
resultSetType
,
resultSetConcurrency
,
closeWithResultSet
);
this
.
generatedKeysRequest
=
conn
.
scopeGeneratedKeys
()
?
false
:
generatedKeysRequest
;
setTrace
(
session
.
getTrace
(),
TraceObject
.
PREPARED_STATEMENT
,
id
);
this
.
sqlStatement
=
sql
;
command
=
conn
.
prepareCommand
(
sql
,
fetchSize
);
...
...
@@ -193,7 +196,14 @@ public class JdbcPreparedStatement extends JdbcStatement implements
synchronized
(
session
)
{
try
{
setExecutingStatement
(
command
);
updateCount
=
command
.
executeUpdate
();
ResultWithGeneratedKeys
result
=
command
.
executeUpdate
(
generatedKeysRequest
);
updateCount
=
result
.
getUpdateCount
();
ResultInterface
gk
=
result
.
getGeneratedKeys
();
if
(
gk
!=
null
)
{
int
id
=
getNextId
(
TraceObject
.
RESULT_SET
);
generatedKeys
=
new
JdbcResultSet
(
conn
,
this
,
command
,
gk
,
id
,
false
,
true
,
false
);
}
}
finally
{
setExecutingStatement
(
null
);
}
...
...
@@ -236,7 +246,13 @@ public class JdbcPreparedStatement extends JdbcStatement implements
updatable
,
cachedColumnLabelMap
);
}
else
{
returnsResultSet
=
false
;
updateCount
=
command
.
executeUpdate
();
ResultWithGeneratedKeys
result
=
command
.
executeUpdate
(
generatedKeysRequest
);
updateCount
=
result
.
getUpdateCount
();
ResultInterface
gk
=
result
.
getGeneratedKeys
();
if
(
gk
!=
null
)
{
generatedKeys
=
new
JdbcResultSet
(
conn
,
this
,
command
,
gk
,
id
,
false
,
true
,
false
);
}
}
}
finally
{
if
(!
lazy
)
{
...
...
@@ -1243,7 +1259,7 @@ public class JdbcPreparedStatement extends JdbcStatement implements
// set
batchParameters
=
New
.
arrayList
();
}
batchIdentities
=
New
.
arrayLis
t
();
batchIdentities
=
new
MergedResultSe
t
();
int
size
=
batchParameters
.
size
();
int
[]
result
=
new
int
[
size
];
boolean
error
=
false
;
...
...
@@ -1261,10 +1277,9 @@ public class JdbcPreparedStatement extends JdbcStatement implements
}
try
{
result
[
i
]
=
executeUpdateInternal
();
ResultSet
rs
=
conn
.
getGeneratedKeys
(
this
,
id
);
while
(
rs
.
next
())
{
batchIdentities
.
add
(
rs
.
getObject
(
1
));
}
// Cannot use own implementation, it returns batch identities
ResultSet
rs
=
super
.
getGeneratedKeys
();
batchIdentities
.
add
(
rs
);
}
catch
(
Exception
re
)
{
SQLException
e
=
logAndConvert
(
re
);
if
(
next
==
null
)
{
...
...
@@ -1293,14 +1308,8 @@ public class JdbcPreparedStatement extends JdbcStatement implements
@Override
public
ResultSet
getGeneratedKeys
()
throws
SQLException
{
if
(
batchIdentities
!=
null
&&
!
batchIdentities
.
isEmpty
())
{
SimpleResultSet
rs
=
new
SimpleResultSet
();
rs
.
addColumn
(
"identity"
,
java
.
sql
.
Types
.
INTEGER
,
10
,
0
);
for
(
Object
o
:
batchIdentities
)
{
rs
.
addRow
(
o
);
}
return
rs
;
if
(
batchIdentities
!=
null
)
{
return
batchIdentities
.
getResult
();
}
return
super
.
getGeneratedKeys
();
}
...
...
h2/src/main/org/h2/jdbc/JdbcSavepoint.java
浏览文件 @
47ed036f
...
...
@@ -65,7 +65,7 @@ public class JdbcSavepoint extends TraceObject implements Savepoint {
checkValid
();
conn
.
prepareCommand
(
"ROLLBACK TO SAVEPOINT "
+
getName
(
name
,
savepointId
),
Integer
.
MAX_VALUE
).
executeUpdate
();
Integer
.
MAX_VALUE
).
executeUpdate
(
false
);
}
private
void
checkValid
()
{
...
...
h2/src/main/org/h2/jdbc/JdbcStatement.java
浏览文件 @
47ed036f
...
...
@@ -18,6 +18,8 @@ import org.h2.engine.SysProperties;
import
org.h2.message.DbException
;
import
org.h2.message.TraceObject
;
import
org.h2.result.ResultInterface
;
import
org.h2.result.ResultWithGeneratedKeys
;
import
org.h2.tools.SimpleResultSet
;
import
org.h2.util.New
;
import
org.h2.util.ParserUtil
;
import
org.h2.util.StringUtils
;
...
...
@@ -33,6 +35,7 @@ public class JdbcStatement extends TraceObject implements Statement, JdbcStateme
protected
int
maxRows
;
protected
int
fetchSize
=
SysProperties
.
SERVER_RESULT_SET_FETCH_SIZE
;
protected
int
updateCount
;
protected
JdbcResultSet
generatedKeys
;
protected
final
int
resultSetType
;
protected
final
int
resultSetConcurrency
;
protected
final
boolean
closedByResultSet
;
...
...
@@ -120,7 +123,7 @@ public class JdbcStatement extends TraceObject implements Statement, JdbcStateme
public
int
executeUpdate
(
String
sql
)
throws
SQLException
{
try
{
debugCodeCall
(
"executeUpdate"
,
sql
);
return
executeUpdateInternal
(
sql
);
return
executeUpdateInternal
(
sql
,
false
);
}
catch
(
Exception
e
)
{
throw
logAndConvert
(
e
);
}
...
...
@@ -148,13 +151,13 @@ public class JdbcStatement extends TraceObject implements Statement, JdbcStateme
public
long
executeLargeUpdate
(
String
sql
)
throws
SQLException
{
try
{
debugCodeCall
(
"executeLargeUpdate"
,
sql
);
return
executeUpdateInternal
(
sql
);
return
executeUpdateInternal
(
sql
,
false
);
}
catch
(
Exception
e
)
{
throw
logAndConvert
(
e
);
}
}
private
int
executeUpdateInternal
(
String
sql
)
throws
SQLException
{
private
int
executeUpdateInternal
(
String
sql
,
Object
generatedKeysRequest
)
throws
SQLException
{
checkClosedForWrite
();
try
{
closeOldResultSet
();
...
...
@@ -163,7 +166,15 @@ public class JdbcStatement extends TraceObject implements Statement, JdbcStateme
synchronized
(
session
)
{
setExecutingStatement
(
command
);
try
{
updateCount
=
command
.
executeUpdate
();
ResultWithGeneratedKeys
result
=
command
.
executeUpdate
(
conn
.
scopeGeneratedKeys
()
?
false
:
generatedKeysRequest
);
updateCount
=
result
.
getUpdateCount
();
ResultInterface
gk
=
result
.
getGeneratedKeys
();
if
(
gk
!=
null
)
{
int
id
=
getNextId
(
TraceObject
.
RESULT_SET
);
generatedKeys
=
new
JdbcResultSet
(
conn
,
this
,
command
,
gk
,
id
,
false
,
true
,
false
);
}
}
finally
{
setExecutingStatement
(
null
);
}
...
...
@@ -191,13 +202,13 @@ public class JdbcStatement extends TraceObject implements Statement, JdbcStateme
public
boolean
execute
(
String
sql
)
throws
SQLException
{
try
{
debugCodeCall
(
"execute"
,
sql
);
return
executeInternal
(
sql
);
return
executeInternal
(
sql
,
false
);
}
catch
(
Exception
e
)
{
throw
logAndConvert
(
e
);
}
}
private
boolean
executeInternal
(
String
sql
)
throws
SQLException
{
private
boolean
executeInternal
(
String
sql
,
Object
generatedKeysRequest
)
throws
SQLException
{
int
id
=
getNextId
(
TraceObject
.
RESULT_SET
);
checkClosedForWrite
();
try
{
...
...
@@ -219,7 +230,14 @@ public class JdbcStatement extends TraceObject implements Statement, JdbcStateme
closedByResultSet
,
scrollable
,
updatable
);
}
else
{
returnsResultSet
=
false
;
updateCount
=
command
.
executeUpdate
();
ResultWithGeneratedKeys
result
=
command
.
executeUpdate
(
conn
.
scopeGeneratedKeys
()
?
false
:
generatedKeysRequest
);
updateCount
=
result
.
getUpdateCount
();
ResultInterface
gk
=
result
.
getGeneratedKeys
();
if
(
gk
!=
null
)
{
generatedKeys
=
new
JdbcResultSet
(
conn
,
this
,
command
,
gk
,
id
,
false
,
true
,
false
);
}
}
}
finally
{
if
(!
lazy
)
{
...
...
@@ -756,7 +774,7 @@ public class JdbcStatement extends TraceObject implements Statement, JdbcStateme
for
(
int
i
=
0
;
i
<
size
;
i
++)
{
String
sql
=
batchCommands
.
get
(
i
);
try
{
result
[
i
]
=
executeUpdateInternal
(
sql
);
result
[
i
]
=
executeUpdateInternal
(
sql
,
false
);
}
catch
(
Exception
re
)
{
SQLException
e
=
logAndConvert
(
re
);
if
(
next
==
null
)
{
...
...
@@ -816,6 +834,15 @@ public class JdbcStatement extends TraceObject implements Statement, JdbcStateme
debugCodeAssign
(
"ResultSet"
,
TraceObject
.
RESULT_SET
,
id
,
"getGeneratedKeys()"
);
}
checkClosed
();
if
(!
conn
.
scopeGeneratedKeys
())
{
if
(
generatedKeys
!=
null
)
{
return
generatedKeys
;
}
if
(
session
.
isSupportsGeneratedKeys
())
{
return
new
SimpleResultSet
();
}
}
// Compatibility mode or an old server, so use SCOPE_IDENTITY()
return
conn
.
getGeneratedKeys
(
this
,
id
);
}
catch
(
Exception
e
)
{
throw
logAndConvert
(
e
);
...
...
@@ -876,11 +903,12 @@ public class JdbcStatement extends TraceObject implements Statement, JdbcStateme
/**
* Executes a statement and returns the update count.
* This method just calls executeUpdate(String sql) internally.
* The method getGeneratedKeys supports at most one columns and row.
*
* @param sql the SQL statement
* @param autoGeneratedKeys ignored
* @param autoGeneratedKeys
* {@link Statement.RETURN_GENERATED_KEYS} if generated keys should
* be available for retrieval, {@link Statement.NO_GENERATED_KEYS} if
* generated keys should not be available
* @return the update count (number of row affected by an insert,
* update or delete, or 0 if no rows or the statement was a
* create, drop, commit or rollback)
...
...
@@ -894,7 +922,7 @@ public class JdbcStatement extends TraceObject implements Statement, JdbcStateme
if
(
isDebugEnabled
())
{
debugCode
(
"executeUpdate("
+
quote
(
sql
)+
", "
+
autoGeneratedKeys
+
");"
);
}
return
executeUpdateInternal
(
sql
);
return
executeUpdateInternal
(
sql
,
autoGeneratedKeys
==
RETURN_GENERATED_KEYS
);
}
catch
(
Exception
e
)
{
throw
logAndConvert
(
e
);
}
...
...
@@ -902,11 +930,12 @@ public class JdbcStatement extends TraceObject implements Statement, JdbcStateme
/**
* Executes a statement and returns the update count.
* This method just calls executeUpdate(String sql) internally.
* The method getGeneratedKeys supports at most one columns and row.
*
* @param sql the SQL statement
* @param autoGeneratedKeys ignored
* @param autoGeneratedKeys
* {@link Statement.RETURN_GENERATED_KEYS} if generated keys should
* be available for retrieval, {@link Statement.NO_GENERATED_KEYS} if
* generated keys should not be available
* @return the update count (number of row affected by an insert,
* update or delete, or 0 if no rows or the statement was a
* create, drop, commit or rollback)
...
...
@@ -919,7 +948,7 @@ public class JdbcStatement extends TraceObject implements Statement, JdbcStateme
if
(
isDebugEnabled
())
{
debugCode
(
"executeLargeUpdate("
+
quote
(
sql
)+
", "
+
autoGeneratedKeys
+
");"
);
}
return
executeUpdateInternal
(
sql
);
return
executeUpdateInternal
(
sql
,
autoGeneratedKeys
==
RETURN_GENERATED_KEYS
);
}
catch
(
Exception
e
)
{
throw
logAndConvert
(
e
);
}
...
...
@@ -927,11 +956,11 @@ public class JdbcStatement extends TraceObject implements Statement, JdbcStateme
/**
* Executes a statement and returns the update count.
* This method just calls executeUpdate(String sql) internally.
* The method getGeneratedKeys supports at most one columns and row.
*
* @param sql the SQL statement
* @param columnIndexes ignored
* @param columnIndexes
* an array of column indexes indicating the columns with generated
* keys that should be returned from the inserted row
* @return the update count (number of row affected by an insert,
* update or delete, or 0 if no rows or the statement was a
* create, drop, commit or rollback)
...
...
@@ -944,7 +973,7 @@ public class JdbcStatement extends TraceObject implements Statement, JdbcStateme
if
(
isDebugEnabled
())
{
debugCode
(
"executeUpdate("
+
quote
(
sql
)+
", "
+
quoteIntArray
(
columnIndexes
)+
");"
);
}
return
executeUpdateInternal
(
sql
);
return
executeUpdateInternal
(
sql
,
columnIndexes
);
}
catch
(
Exception
e
)
{
throw
logAndConvert
(
e
);
}
...
...
@@ -952,11 +981,11 @@ public class JdbcStatement extends TraceObject implements Statement, JdbcStateme
/**
* Executes a statement and returns the update count.
* This method just calls executeUpdate(String sql) internally.
* The method getGeneratedKeys supports at most one columns and row.
*
* @param sql the SQL statement
* @param columnIndexes ignored
* @param columnIndexes
* an array of column indexes indicating the columns with generated
* keys that should be returned from the inserted row
* @return the update count (number of row affected by an insert,
* update or delete, or 0 if no rows or the statement was a
* create, drop, commit or rollback)
...
...
@@ -969,7 +998,7 @@ public class JdbcStatement extends TraceObject implements Statement, JdbcStateme
if
(
isDebugEnabled
())
{
debugCode
(
"executeLargeUpdate("
+
quote
(
sql
)+
", "
+
quoteIntArray
(
columnIndexes
)+
");"
);
}
return
executeUpdateInternal
(
sql
);
return
executeUpdateInternal
(
sql
,
columnIndexes
);
}
catch
(
Exception
e
)
{
throw
logAndConvert
(
e
);
}
...
...
@@ -977,11 +1006,11 @@ public class JdbcStatement extends TraceObject implements Statement, JdbcStateme
/**
* Executes a statement and returns the update count.
* This method just calls executeUpdate(String sql) internally.
* The method getGeneratedKeys supports at most one columns and row.
*
* @param sql the SQL statement
* @param columnNames ignored
* @param columnNames
* an array of column names indicating the columns with generated
* keys that should be returned from the inserted row
* @return the update count (number of row affected by an insert,
* update or delete, or 0 if no rows or the statement was a
* create, drop, commit or rollback)
...
...
@@ -994,7 +1023,7 @@ public class JdbcStatement extends TraceObject implements Statement, JdbcStateme
if
(
isDebugEnabled
())
{
debugCode
(
"executeUpdate("
+
quote
(
sql
)+
", "
+
quoteArray
(
columnNames
)+
");"
);
}
return
executeUpdateInternal
(
sql
);
return
executeUpdateInternal
(
sql
,
columnNames
);
}
catch
(
Exception
e
)
{
throw
logAndConvert
(
e
);
}
...
...
@@ -1002,11 +1031,11 @@ public class JdbcStatement extends TraceObject implements Statement, JdbcStateme
/**
* Executes a statement and returns the update count.
* This method just calls executeUpdate(String sql) internally.
* The method getGeneratedKeys supports at most one columns and row.
*
* @param sql the SQL statement
* @param columnNames ignored
* @param columnNames
* an array of column names indicating the columns with generated
* keys that should be returned from the inserted row
* @return the update count (number of row affected by an insert,
* update or delete, or 0 if no rows or the statement was a
* create, drop, commit or rollback)
...
...
@@ -1019,7 +1048,7 @@ public class JdbcStatement extends TraceObject implements Statement, JdbcStateme
if
(
isDebugEnabled
())
{
debugCode
(
"executeLargeUpdate("
+
quote
(
sql
)+
", "
+
quoteArray
(
columnNames
)+
");"
);
}
return
executeUpdateInternal
(
sql
);
return
executeUpdateInternal
(
sql
,
columnNames
);
}
catch
(
Exception
e
)
{
throw
logAndConvert
(
e
);
}
...
...
@@ -1027,11 +1056,12 @@ public class JdbcStatement extends TraceObject implements Statement, JdbcStateme
/**
* Executes a statement and returns the update count.
* This method just calls execute(String sql) internally.
* The method getGeneratedKeys supports at most one columns and row.
*
* @param sql the SQL statement
* @param autoGeneratedKeys ignored
* @param autoGeneratedKeys
* {@link Statement.RETURN_GENERATED_KEYS} if generated keys should
* be available for retrieval, {@link Statement.NO_GENERATED_KEYS} if
* generated keys should not be available
* @return the update count (number of row affected by an insert,
* update or delete, or 0 if no rows or the statement was a
* create, drop, commit or rollback)
...
...
@@ -1044,7 +1074,7 @@ public class JdbcStatement extends TraceObject implements Statement, JdbcStateme
if
(
isDebugEnabled
())
{
debugCode
(
"execute("
+
quote
(
sql
)+
", "
+
autoGeneratedKeys
+
");"
);
}
return
executeInternal
(
sql
);
return
executeInternal
(
sql
,
autoGeneratedKeys
==
RETURN_GENERATED_KEYS
);
}
catch
(
Exception
e
)
{
throw
logAndConvert
(
e
);
}
...
...
@@ -1052,11 +1082,11 @@ public class JdbcStatement extends TraceObject implements Statement, JdbcStateme
/**
* Executes a statement and returns the update count.
* This method just calls execute(String sql) internally.
* The method getGeneratedKeys supports at most one columns and row.
*
* @param sql the SQL statement
* @param columnIndexes ignored
* @param columnIndexes
* an array of column indexes indicating the columns with generated
* keys that should be returned from the inserted row
* @return the update count (number of row affected by an insert,
* update or delete, or 0 if no rows or the statement was a
* create, drop, commit or rollback)
...
...
@@ -1069,7 +1099,7 @@ public class JdbcStatement extends TraceObject implements Statement, JdbcStateme
if
(
isDebugEnabled
())
{
debugCode
(
"execute("
+
quote
(
sql
)+
", "
+
quoteIntArray
(
columnIndexes
)+
");"
);
}
return
executeInternal
(
sql
);
return
executeInternal
(
sql
,
columnIndexes
);
}
catch
(
Exception
e
)
{
throw
logAndConvert
(
e
);
}
...
...
@@ -1077,11 +1107,11 @@ public class JdbcStatement extends TraceObject implements Statement, JdbcStateme
/**
* Executes a statement and returns the update count.
* This method just calls execute(String sql) internally.
* The method getGeneratedKeys supports at most one columns and row.
*
* @param sql the SQL statement
* @param columnNames ignored
* @param columnNames
* an array of column names indicating the columns with generated
* keys that should be returned from the inserted row
* @return the update count (number of row affected by an insert,
* update or delete, or 0 if no rows or the statement was a
* create, drop, commit or rollback)
...
...
@@ -1094,7 +1124,7 @@ public class JdbcStatement extends TraceObject implements Statement, JdbcStateme
if
(
isDebugEnabled
())
{
debugCode
(
"execute("
+
quote
(
sql
)+
", "
+
quoteArray
(
columnNames
)+
");"
);
}
return
executeInternal
(
sql
);
return
executeInternal
(
sql
,
columnNames
);
}
catch
(
Exception
e
)
{
throw
logAndConvert
(
e
);
}
...
...
@@ -1197,11 +1227,15 @@ public class JdbcStatement extends TraceObject implements Statement, JdbcStateme
if
(
resultSet
!=
null
)
{
resultSet
.
closeInternal
();
}
if
(
generatedKeys
!=
null
)
{
generatedKeys
.
closeInternal
();
}
}
}
finally
{
cancelled
=
false
;
resultSet
=
null
;
updateCount
=
-
1
;
generatedKeys
=
null
;
}
}
...
...
h2/src/main/org/h2/result/ResultWithGeneratedKeys.java
0 → 100644
浏览文件 @
47ed036f
/*
* Copyright 2004-2018 H2 Group. Multiple-Licensed under the MPL 2.0,
* and the EPL 1.0 (http://h2database.com/html/license.html).
* Initial Developer: H2 Group
*/
package
org
.
h2
.
result
;
/**
* Result of update command with optional generated keys.
*/
public
class
ResultWithGeneratedKeys
{
/**
* Result of update command with generated keys;
*/
public
static
final
class
WithKeys
extends
ResultWithGeneratedKeys
{
private
final
ResultInterface
generatedKeys
;
/**
* Creates a result with update count and generated keys.
*
* @param updateCount
* update count
* @param generatedKeys
* generated keys
*/
public
WithKeys
(
int
updateCount
,
ResultInterface
generatedKeys
)
{
super
(
updateCount
);
this
.
generatedKeys
=
generatedKeys
;
}
@Override
public
ResultInterface
getGeneratedKeys
()
{
return
generatedKeys
;
}
}
/**
* Returns a result with only update count.
*
* @param updateCount
* update count
*/
public
static
ResultWithGeneratedKeys
of
(
int
updateCount
)
{
return
new
ResultWithGeneratedKeys
(
updateCount
);
}
private
final
int
updateCount
;
ResultWithGeneratedKeys
(
int
updateCount
)
{
this
.
updateCount
=
updateCount
;
}
/**
* Returns generated keys, or {@code null}.
*
* @return generated keys, or {@code null}
*/
public
ResultInterface
getGeneratedKeys
()
{
return
null
;
}
/**
* Returns update count.
*
* @return update count
*/
public
int
getUpdateCount
()
{
return
updateCount
;
}
}
h2/src/main/org/h2/schema/TriggerObject.java
浏览文件 @
47ed036f
...
...
@@ -203,6 +203,7 @@ public class TriggerObject extends SchemaObjectBase {
* times for each statement.
*
* @param session the session
* @param table the table
* @param oldRow the old row
* @param newRow the new row
* @param beforeAction true if this method is called before the operation is
...
...
@@ -210,7 +211,7 @@ public class TriggerObject extends SchemaObjectBase {
* @param rollback when the operation occurred within a rollback
* @return true if no further action is required (for 'instead of' triggers)
*/
public
boolean
fireRow
(
Session
session
,
Row
oldRow
,
Row
newRow
,
public
boolean
fireRow
(
Session
session
,
Table
table
,
Row
oldRow
,
Row
newRow
,
boolean
beforeAction
,
boolean
rollback
)
{
if
(!
rowBased
||
before
!=
beforeAction
)
{
return
false
;
...
...
@@ -260,6 +261,7 @@ public class TriggerObject extends SchemaObjectBase {
Object
o
=
newList
[
i
];
if
(
o
!=
newListBackup
[
i
])
{
Value
v
=
DataType
.
convertToValue
(
session
,
o
,
Value
.
UNKNOWN
);
session
.
getGeneratedKeys
().
add
(
table
.
getColumn
(
i
));
newRow
.
setValue
(
i
,
v
);
}
}
...
...
h2/src/main/org/h2/server/TcpServerThread.java
浏览文件 @
47ed036f
...
...
@@ -21,6 +21,7 @@ import org.h2.command.Command;
import
org.h2.engine.ConnectionInfo
;
import
org.h2.engine.Constants
;
import
org.h2.engine.Engine
;
import
org.h2.engine.GeneratedKeysMode
;
import
org.h2.engine.Session
;
import
org.h2.engine.SessionRemote
;
import
org.h2.engine.SysProperties
;
...
...
@@ -31,6 +32,7 @@ import org.h2.jdbc.JdbcSQLException;
import
org.h2.message.DbException
;
import
org.h2.result.ResultColumn
;
import
org.h2.result.ResultInterface
;
import
org.h2.result.ResultWithGeneratedKeys
;
import
org.h2.store.LobStorageInterface
;
import
org.h2.util.IOUtils
;
import
org.h2.util.SmallLRUCache
;
...
...
@@ -88,15 +90,15 @@ public class TcpServerThread implements Runnable {
}
int
minClientVersion
=
transfer
.
readInt
();
int
maxClientVersion
=
transfer
.
readInt
();
if
(
maxClientVersion
<
Constants
.
TCP_PROTOCOL_VERSION_
6
)
{
if
(
maxClientVersion
<
Constants
.
TCP_PROTOCOL_VERSION_
MIN_SUPPORTED
)
{
throw
DbException
.
get
(
ErrorCode
.
DRIVER_VERSION_ERROR_2
,
""
+
clientVersion
,
""
+
Constants
.
TCP_PROTOCOL_VERSION_
6
);
}
else
if
(
minClientVersion
>
Constants
.
TCP_PROTOCOL_VERSION_
16
)
{
""
+
clientVersion
,
""
+
Constants
.
TCP_PROTOCOL_VERSION_
MIN_SUPPORTED
);
}
else
if
(
minClientVersion
>
Constants
.
TCP_PROTOCOL_VERSION_
MAX_SUPPORTED
)
{
throw
DbException
.
get
(
ErrorCode
.
DRIVER_VERSION_ERROR_2
,
""
+
clientVersion
,
""
+
Constants
.
TCP_PROTOCOL_VERSION_
16
);
""
+
clientVersion
,
""
+
Constants
.
TCP_PROTOCOL_VERSION_
MAX_SUPPORTED
);
}
if
(
maxClientVersion
>=
Constants
.
TCP_PROTOCOL_VERSION_
16
)
{
clientVersion
=
Constants
.
TCP_PROTOCOL_VERSION_
16
;
if
(
maxClientVersion
>=
Constants
.
TCP_PROTOCOL_VERSION_
MAX_SUPPORTED
)
{
clientVersion
=
Constants
.
TCP_PROTOCOL_VERSION_
MAX_SUPPORTED
;
}
else
{
clientVersion
=
maxClientVersion
;
}
...
...
@@ -178,7 +180,7 @@ public class TcpServerThread implements Runnable {
RuntimeException
closeError
=
null
;
try
{
Command
rollback
=
session
.
prepareLocal
(
"ROLLBACK"
);
rollback
.
executeUpdate
();
rollback
.
executeUpdate
(
false
);
}
catch
(
RuntimeException
e
)
{
closeError
=
e
;
server
.
traceError
(
e
);
...
...
@@ -302,7 +304,7 @@ public class TcpServerThread implements Runnable {
commit
=
session
.
prepareLocal
(
"COMMIT"
);
}
int
old
=
session
.
getModificationId
();
commit
.
executeUpdate
();
commit
.
executeUpdate
(
false
);
transfer
.
writeInt
(
getState
(
old
)).
flush
();
break
;
}
...
...
@@ -353,10 +355,48 @@ public class TcpServerThread implements Runnable {
int
id
=
transfer
.
readInt
();
Command
command
=
(
Command
)
cache
.
getObject
(
id
,
false
);
setParameters
(
command
);
boolean
supportsGeneratedKeys
=
clientVersion
>=
Constants
.
TCP_PROTOCOL_VERSION_17
;
boolean
writeGeneratedKeys
=
supportsGeneratedKeys
;
Object
generatedKeysRequest
;
if
(
supportsGeneratedKeys
)
{
int
mode
=
transfer
.
readInt
();
switch
(
mode
)
{
case
GeneratedKeysMode
.
NONE
:
generatedKeysRequest
=
false
;
writeGeneratedKeys
=
false
;
break
;
case
GeneratedKeysMode
.
AUTO
:
generatedKeysRequest
=
true
;
break
;
case
GeneratedKeysMode
.
COLUMN_NUMBERS
:
{
int
len
=
transfer
.
readInt
();
int
[]
keys
=
new
int
[
len
];
for
(
int
i
=
0
;
i
<
len
;
i
++)
{
keys
[
i
]
=
transfer
.
readInt
();
}
generatedKeysRequest
=
keys
;
break
;
}
case
GeneratedKeysMode
.
COLUMN_NAMES
:
{
int
len
=
transfer
.
readInt
();
String
[]
keys
=
new
String
[
len
];
for
(
int
i
=
0
;
i
<
len
;
i
++)
{
keys
[
i
]
=
transfer
.
readString
();
}
generatedKeysRequest
=
keys
;
break
;
}
default
:
throw
DbException
.
get
(
ErrorCode
.
CONNECTION_BROKEN_1
,
"Unsupported generated keys' mode "
+
mode
);
}
}
else
{
generatedKeysRequest
=
false
;
}
int
old
=
session
.
getModificationId
();
int
updateCoun
t
;
ResultWithGeneratedKeys
resul
t
;
synchronized
(
session
)
{
updateCount
=
command
.
executeUpdate
(
);
result
=
command
.
executeUpdate
(
generatedKeysRequest
);
}
int
status
;
if
(
session
.
isClosed
())
{
...
...
@@ -365,8 +405,22 @@ public class TcpServerThread implements Runnable {
}
else
{
status
=
getState
(
old
);
}
transfer
.
writeInt
(
status
).
writeInt
(
updateCount
).
transfer
.
writeInt
(
status
).
writeInt
(
result
.
getUpdateCount
()
).
writeBoolean
(
session
.
getAutoCommit
());
if
(
writeGeneratedKeys
)
{
ResultInterface
generatedKeys
=
result
.
getGeneratedKeys
();
int
columnCount
=
generatedKeys
.
getVisibleColumnCount
();
transfer
.
writeInt
(
columnCount
);
int
rowCount
=
generatedKeys
.
getRowCount
();
transfer
.
writeInt
(
rowCount
);
for
(
int
i
=
0
;
i
<
columnCount
;
i
++)
{
ResultColumn
.
writeColumn
(
transfer
,
generatedKeys
,
i
);
}
for
(
int
i
=
0
;
i
<
rowCount
;
i
++)
{
sendRow
(
generatedKeys
);
}
generatedKeys
.
close
();
}
transfer
.
flush
();
break
;
}
...
...
h2/src/main/org/h2/server/web/WebApp.java
浏览文件 @
47ed036f
...
...
@@ -1284,7 +1284,7 @@ public class WebApp {
ResultSet
rs
;
long
time
=
System
.
currentTimeMillis
();
boolean
metadata
=
false
;
boolean
generatedKeys
=
false
;
int
generatedKeys
=
Statement
.
NO_GENERATED_KEYS
;
boolean
edit
=
false
;
boolean
list
=
false
;
if
(
isBuiltIn
(
sql
,
"@autocommit_true"
))
{
...
...
@@ -1316,7 +1316,7 @@ public class WebApp {
sql
=
sql
.
substring
(
"@meta"
.
length
()).
trim
();
}
if
(
isBuiltIn
(
sql
,
"@generated"
))
{
generatedKeys
=
true
;
generatedKeys
=
Statement
.
RETURN_GENERATED_KEYS
;
sql
=
sql
.
substring
(
"@generated"
.
length
()).
trim
();
}
else
if
(
isBuiltIn
(
sql
,
"@history"
))
{
buff
.
append
(
getCommandHistoryString
());
...
...
@@ -1385,9 +1385,9 @@ public class WebApp {
int
maxrows
=
getMaxrows
();
stat
.
setMaxRows
(
maxrows
);
session
.
executingStatement
=
stat
;
boolean
isResultSet
=
stat
.
execute
(
sql
);
boolean
isResultSet
=
stat
.
execute
(
sql
,
generatedKeys
);
session
.
addCommand
(
sql
);
if
(
generatedKeys
)
{
if
(
generatedKeys
==
Statement
.
RETURN_GENERATED_KEYS
)
{
rs
=
null
;
rs
=
stat
.
getGeneratedKeys
();
}
else
{
...
...
h2/src/main/org/h2/store/FileLock.java
浏览文件 @
47ed036f
...
...
@@ -210,8 +210,8 @@ public class FileLock implements Runnable {
Constants
.
DEFAULT_TCP_PORT
,
false
);
Transfer
transfer
=
new
Transfer
(
null
,
socket
);
transfer
.
init
();
transfer
.
writeInt
(
Constants
.
TCP_PROTOCOL_VERSION_
6
);
transfer
.
writeInt
(
Constants
.
TCP_PROTOCOL_VERSION_
16
);
transfer
.
writeInt
(
Constants
.
TCP_PROTOCOL_VERSION_
MIN_SUPPORTED
);
transfer
.
writeInt
(
Constants
.
TCP_PROTOCOL_VERSION_
MAX_SUPPORTED
);
transfer
.
writeString
(
null
);
transfer
.
writeString
(
null
);
transfer
.
writeString
(
id
);
...
...
h2/src/main/org/h2/table/Column.java
浏览文件 @
47ed036f
...
...
@@ -321,6 +321,7 @@ public class Column {
value
=
ValueNull
.
INSTANCE
;
}
else
{
value
=
localDefaultExpression
.
getValue
(
session
).
convertTo
(
type
);
session
.
getGeneratedKeys
().
add
(
this
);
if
(
primaryKey
)
{
session
.
setLastIdentity
(
value
);
}
...
...
@@ -330,6 +331,7 @@ public class Column {
if
(
value
==
ValueNull
.
INSTANCE
)
{
if
(
convertNullToDefault
)
{
value
=
localDefaultExpression
.
getValue
(
session
).
convertTo
(
type
);
session
.
getGeneratedKeys
().
add
(
this
);
}
if
(
value
==
ValueNull
.
INSTANCE
&&
!
nullable
)
{
if
(
mode
.
convertInsertNullToZero
)
{
...
...
h2/src/main/org/h2/table/Table.java
浏览文件 @
47ed036f
...
...
@@ -1026,7 +1026,7 @@ public abstract class Table extends SchemaObjectBase {
boolean
beforeAction
,
boolean
rollback
)
{
if
(
triggers
!=
null
)
{
for
(
TriggerObject
trigger
:
triggers
)
{
boolean
done
=
trigger
.
fireRow
(
session
,
oldRow
,
newRow
,
beforeAction
,
rollback
);
boolean
done
=
trigger
.
fireRow
(
session
,
this
,
oldRow
,
newRow
,
beforeAction
,
rollback
);
if
(
done
)
{
return
true
;
}
...
...
h2/src/main/org/h2/util/MergedResultSet.java
0 → 100644
浏览文件 @
47ed036f
/*
* Copyright 2004-2018 H2 Group. Multiple-Licensed under the MPL 2.0,
* and the EPL 1.0 (http://h2database.com/html/license.html).
* Initial Developer: H2 Group
*/
package
org
.
h2
.
util
;
import
java.sql.ResultSet
;
import
java.sql.ResultSetMetaData
;
import
java.sql.SQLException
;
import
java.util.ArrayList
;
import
java.util.Collections
;
import
java.util.HashMap
;
import
java.util.Map
;
import
org.h2.tools.SimpleResultSet
;
/**
* Merged result set. Used to combine several result sets into one. Merged
* result set will contain rows from all appended result sets. Result sets are
* not required to have the same lists of columns, but required to have
* compatible column definitions, for example, if one result set has a
* {@link java.sql.Types#VARCHAR} column {@code NAME} then another results sets
* that have {@code NAME} column should also define it with the same type.
*/
public
final
class
MergedResultSet
{
/**
* Metadata of a column.
*/
private
static
final
class
ColumnInfo
{
final
String
name
;
final
int
type
;
final
int
precision
;
final
int
scale
;
/**
* Creates metadata.
*
* @param name
* name of the column
* @param type
* type of the column, see {@link java.sql.Types}
* @param precision
* precision of the column
* @param scale
* scale of the column
*/
ColumnInfo
(
String
name
,
int
type
,
int
precision
,
int
scale
)
{
this
.
name
=
name
;
this
.
type
=
type
;
this
.
precision
=
precision
;
this
.
scale
=
scale
;
}
@Override
public
boolean
equals
(
Object
obj
)
{
if
(
this
==
obj
)
return
true
;
if
(
obj
==
null
||
getClass
()
!=
obj
.
getClass
())
return
false
;
ColumnInfo
other
=
(
ColumnInfo
)
obj
;
return
name
.
equals
(
other
.
name
);
}
@Override
public
int
hashCode
()
{
return
name
.
hashCode
();
}
}
private
final
ArrayList
<
Map
<
ColumnInfo
,
Object
>>
data
=
New
.
arrayList
();
private
final
ArrayList
<
ColumnInfo
>
columns
=
New
.
arrayList
();
/**
* Appends a result set.
*
* @param rs
* result set to append
* @throws SQLException
* on SQL exception
*/
public
void
add
(
ResultSet
rs
)
throws
SQLException
{
ResultSetMetaData
meta
=
rs
.
getMetaData
();
int
cols
=
meta
.
getColumnCount
();
if
(
cols
==
0
)
{
return
;
}
ColumnInfo
[]
info
=
new
ColumnInfo
[
cols
];
for
(
int
i
=
1
;
i
<=
cols
;
i
++)
{
ColumnInfo
ci
=
new
ColumnInfo
(
meta
.
getColumnName
(
i
),
meta
.
getColumnType
(
i
),
meta
.
getPrecision
(
i
),
meta
.
getScale
(
i
));
info
[
i
-
1
]
=
ci
;
if
(!
columns
.
contains
(
ci
))
{
columns
.
add
(
ci
);
}
}
while
(
rs
.
next
())
{
if
(
cols
==
1
)
{
data
.
add
(
Collections
.
singletonMap
(
info
[
0
],
rs
.
getObject
(
1
)));
}
else
{
HashMap
<
ColumnInfo
,
Object
>
map
=
new
HashMap
<>();
for
(
int
i
=
1
;
i
<=
cols
;
i
++)
{
ColumnInfo
ci
=
info
[
i
-
1
];
map
.
put
(
ci
,
rs
.
getObject
(
i
));
}
data
.
add
(
map
);
}
}
}
/**
* Returns merged results set.
*
* @return result set with rows from all appended result sets
*/
public
SimpleResultSet
getResult
()
{
SimpleResultSet
rs
=
new
SimpleResultSet
();
for
(
ColumnInfo
ci
:
columns
)
{
rs
.
addColumn
(
ci
.
name
,
ci
.
type
,
ci
.
precision
,
ci
.
scale
);
}
for
(
Map
<
ColumnInfo
,
Object
>
map
:
data
)
{
Object
[]
row
=
new
Object
[
columns
.
size
()];
for
(
Map
.
Entry
<
ColumnInfo
,
Object
>
entry
:
map
.
entrySet
())
{
row
[
columns
.
indexOf
(
entry
.
getKey
())]
=
entry
.
getValue
();
}
rs
.
addRow
(
row
);
}
return
rs
;
}
@Override
public
String
toString
()
{
return
columns
+
": "
+
data
.
size
();
}
}
h2/src/test/org/h2/test/TestAll.java
浏览文件 @
47ed036f
...
...
@@ -97,6 +97,7 @@ import org.h2.test.jdbc.TestConnection;
import
org.h2.test.jdbc.TestCustomDataTypesHandler
;
import
org.h2.test.jdbc.TestDatabaseEventListener
;
import
org.h2.test.jdbc.TestDriver
;
import
org.h2.test.jdbc.TestGetGeneratedKeys
;
import
org.h2.test.jdbc.TestJavaObject
;
import
org.h2.test.jdbc.TestJavaObjectSerializer
;
import
org.h2.test.jdbc.TestLimitUpdates
;
...
...
@@ -814,6 +815,7 @@ kill -9 `jps -l | grep "org.h2.test." | cut -d " " -f 1`
addTest
(
new
TestPreparedStatement
());
addTest
(
new
TestResultSet
());
addTest
(
new
TestStatement
());
addTest
(
new
TestGetGeneratedKeys
());
addTest
(
new
TestTransactionIsolation
());
addTest
(
new
TestUpdatableResultSet
());
addTest
(
new
TestZloty
());
...
...
h2/src/test/org/h2/test/db/TestTriggersConstraints.java
浏览文件 @
47ed036f
...
...
@@ -227,7 +227,7 @@ public class TestTriggersConstraints extends TestBase implements Trigger {
assertEquals
(
1
,
count
);
ResultSet
gkRs
;
gkRs
=
pstat
.
getGeneratedKeys
(
);
gkRs
=
stat
.
executeQuery
(
"select scope_identity()"
);
assertTrue
(
gkRs
.
next
());
assertEquals
(
1
,
gkRs
.
getInt
(
1
));
...
...
h2/src/test/org/h2/test/jdbc/TestGetGeneratedKeys.java
0 → 100644
浏览文件 @
47ed036f
/*
* Copyright 2004-2018 H2 Group. Multiple-Licensed under the MPL 2.0,
* and the EPL 1.0 (http://h2database.com/html/license.html).
* Initial Developer: H2 Group
*/
package
org
.
h2
.
test
.
jdbc
;
import
java.sql.Connection
;
import
java.sql.PreparedStatement
;
import
java.sql.ResultSet
;
import
java.sql.SQLException
;
import
java.sql.Statement
;
import
java.util.UUID
;
import
org.h2.api.Trigger
;
import
org.h2.jdbc.JdbcPreparedStatement
;
import
org.h2.jdbc.JdbcStatement
;
import
org.h2.test.TestBase
;
/**
* Tests for the {@link Statement#getGeneratedKeys()}.
*/
public
class
TestGetGeneratedKeys
extends
TestBase
{
public
static
class
TestGetGeneratedKeysTrigger
implements
Trigger
{
@Override
public
void
close
()
throws
SQLException
{
}
@Override
public
void
fire
(
Connection
conn
,
Object
[]
oldRow
,
Object
[]
newRow
)
throws
SQLException
{
if
(
newRow
[
0
]
==
null
)
{
newRow
[
0
]
=
UUID
.
randomUUID
();
}
}
@Override
public
void
init
(
Connection
conn
,
String
schemaName
,
String
triggerName
,
String
tableName
,
boolean
before
,
int
type
)
throws
SQLException
{
}
@Override
public
void
remove
()
throws
SQLException
{
}
}
/**
* Run just this test.
*
* @param a
* ignored
*/
public
static
void
main
(
String
...
a
)
throws
Exception
{
TestBase
.
createCaller
().
init
().
test
();
}
@Override
public
void
test
()
throws
Exception
{
deleteDb
(
"getGeneratedKeys"
);
Connection
conn
=
getConnection
(
"getGeneratedKeys"
);
testBatchAndMergeInto
(
conn
);
testCalledSequenses
(
conn
);
testInsertWithSelect
(
conn
);
testMergeUsing
(
conn
);
testMultithreaded
(
conn
);
testNameCase
(
conn
);
testPrepareStatement_Execute
(
conn
);
testPrepareStatement_ExecuteBatch
(
conn
);
testPrepareStatement_ExecuteLargeBatch
(
conn
);
testPrepareStatement_ExecuteLargeUpdate
(
conn
);
testPrepareStatement_ExecuteUpdate
(
conn
);
testPrepareStatement_int_Execute
(
conn
);
testPrepareStatement_int_ExecuteBatch
(
conn
);
testPrepareStatement_int_ExecuteLargeBatch
(
conn
);
testPrepareStatement_int_ExecuteLargeUpdate
(
conn
);
testPrepareStatement_int_ExecuteUpdate
(
conn
);
testPrepareStatement_intArray_Execute
(
conn
);
testPrepareStatement_intArray_ExecuteBatch
(
conn
);
testPrepareStatement_intArray_ExecuteLargeBatch
(
conn
);
testPrepareStatement_intArray_ExecuteLargeUpdate
(
conn
);
testPrepareStatement_intArray_ExecuteUpdate
(
conn
);
testPrepareStatement_StringArray_Execute
(
conn
);
testPrepareStatement_StringArray_ExecuteBatch
(
conn
);
testPrepareStatement_StringArray_ExecuteLargeBatch
(
conn
);
testPrepareStatement_StringArray_ExecuteLargeUpdate
(
conn
);
testPrepareStatement_StringArray_ExecuteUpdate
(
conn
);
testStatementExecute
(
conn
);
testStatementExecute_int
(
conn
);
testStatementExecute_intArray
(
conn
);
testStatementExecute_StringArray
(
conn
);
testStatementExecuteLargeUpdate
(
conn
);
testStatementExecuteLargeUpdate_int
(
conn
);
testStatementExecuteLargeUpdate_intArray
(
conn
);
testStatementExecuteLargeUpdate_StringArray
(
conn
);
testStatementExecuteUpdate
(
conn
);
testStatementExecuteUpdate_int
(
conn
);
testStatementExecuteUpdate_intArray
(
conn
);
testStatementExecuteUpdate_StringArray
(
conn
);
testTrigger
(
conn
);
conn
.
close
();
deleteDb
(
"getGeneratedKeys"
);
}
/**
* Test for batch updates and MERGE INTO operator.
*
* @param conn
* connection
* @throws Exception
* on exception
*/
private
void
testBatchAndMergeInto
(
Connection
conn
)
throws
Exception
{
Statement
stat
=
conn
.
createStatement
();
stat
.
execute
(
"CREATE TABLE TEST(ID BIGINT AUTO_INCREMENT, UID UUID DEFAULT RANDOM_UUID(), VALUE INT)"
);
PreparedStatement
prep
=
conn
.
prepareStatement
(
"INSERT INTO TEST(VALUE) VALUES (?), (?)"
,
Statement
.
RETURN_GENERATED_KEYS
);
prep
.
setInt
(
1
,
1
);
prep
.
setInt
(
2
,
2
);
prep
.
addBatch
();
prep
.
setInt
(
1
,
3
);
prep
.
setInt
(
1
,
4
);
prep
.
addBatch
();
prep
.
executeBatch
();
ResultSet
rs
=
prep
.
getGeneratedKeys
();
rs
.
next
();
assertEquals
(
1L
,
rs
.
getLong
(
1
));
UUID
u1
=
(
UUID
)
rs
.
getObject
(
2
);
assertTrue
(
u1
!=
null
);
rs
.
next
();
assertEquals
(
2L
,
rs
.
getLong
(
1
));
UUID
u2
=
(
UUID
)
rs
.
getObject
(
2
);
assertTrue
(
u2
!=
null
);
rs
.
next
();
assertEquals
(
3L
,
rs
.
getLong
(
1
));
UUID
u3
=
(
UUID
)
rs
.
getObject
(
2
);
assertTrue
(
u3
!=
null
);
rs
.
next
();
assertEquals
(
4L
,
rs
.
getLong
(
1
));
UUID
u4
=
(
UUID
)
rs
.
getObject
(
2
);
assertTrue
(
u4
!=
null
);
assertFalse
(
rs
.
next
());
assertFalse
(
u1
.
equals
(
u2
));
assertFalse
(
u2
.
equals
(
u3
));
assertFalse
(
u3
.
equals
(
u4
));
prep
=
conn
.
prepareStatement
(
"MERGE INTO TEST(ID, VALUE) KEY(ID) VALUES (?, ?)"
,
Statement
.
RETURN_GENERATED_KEYS
);
prep
.
setInt
(
1
,
2
);
prep
.
setInt
(
2
,
10
);
prep
.
execute
();
rs
=
prep
.
getGeneratedKeys
();
assertFalse
(
rs
.
next
());
prep
.
setInt
(
1
,
5
);
prep
.
executeUpdate
();
rs
=
prep
.
getGeneratedKeys
();
rs
.
next
();
assertEquals
(
UUID
.
class
,
rs
.
getObject
(
1
).
getClass
());
assertFalse
(
rs
.
next
());
stat
.
execute
(
"DROP TABLE TEST"
);
}
/**
* Test for keys generated by sequences.
*
* @param conn
* connection
* @throws Exception
* on exception
*/
private
void
testCalledSequenses
(
Connection
conn
)
throws
Exception
{
Statement
stat
=
conn
.
createStatement
();
stat
.
execute
(
"CREATE SEQUENCE SEQ"
);
stat
.
execute
(
"CREATE TABLE TEST(ID INT)"
);
PreparedStatement
prep
;
prep
=
conn
.
prepareStatement
(
"INSERT INTO TEST VALUES(NEXT VALUE FOR SEQ)"
,
Statement
.
RETURN_GENERATED_KEYS
);
prep
.
execute
();
ResultSet
rs
=
prep
.
getGeneratedKeys
();
rs
.
next
();
assertEquals
(
1
,
rs
.
getInt
(
1
));
assertFalse
(
rs
.
next
());
prep
=
conn
.
prepareStatement
(
"INSERT INTO TEST VALUES(NEXT VALUE FOR SEQ)"
,
Statement
.
RETURN_GENERATED_KEYS
);
prep
.
execute
();
rs
=
prep
.
getGeneratedKeys
();
rs
.
next
();
assertEquals
(
2
,
rs
.
getInt
(
1
));
assertFalse
(
rs
.
next
());
prep
=
conn
.
prepareStatement
(
"INSERT INTO TEST VALUES(NEXT VALUE FOR SEQ)"
,
new
int
[]
{
1
});
prep
.
execute
();
rs
=
prep
.
getGeneratedKeys
();
rs
.
next
();
assertEquals
(
3
,
rs
.
getInt
(
1
));
assertFalse
(
rs
.
next
());
prep
=
conn
.
prepareStatement
(
"INSERT INTO TEST VALUES(NEXT VALUE FOR SEQ)"
,
new
String
[]
{
"ID"
});
prep
.
execute
();
rs
=
prep
.
getGeneratedKeys
();
rs
.
next
();
assertEquals
(
4
,
rs
.
getInt
(
1
));
assertFalse
(
rs
.
next
());
prep
=
conn
.
prepareStatement
(
"INSERT INTO TEST VALUES(NEXT VALUE FOR SEQ)"
,
ResultSet
.
TYPE_FORWARD_ONLY
,
ResultSet
.
CONCUR_READ_ONLY
,
ResultSet
.
HOLD_CURSORS_OVER_COMMIT
);
prep
.
execute
();
rs
=
prep
.
getGeneratedKeys
();
rs
.
next
();
assertFalse
(
rs
.
next
());
stat
.
execute
(
"DROP TABLE TEST"
);
stat
.
execute
(
"DROP SEQUENCE SEQ"
);
stat
.
execute
(
"CREATE TABLE TEST(ID BIGINT)"
);
stat
.
execute
(
"CREATE SEQUENCE SEQ"
);
prep
=
conn
.
prepareStatement
(
"INSERT INTO TEST VALUES (30), (NEXT VALUE FOR SEQ),"
+
" (NEXT VALUE FOR SEQ), (NEXT VALUE FOR SEQ), (20)"
,
Statement
.
RETURN_GENERATED_KEYS
);
prep
.
executeUpdate
();
rs
=
prep
.
getGeneratedKeys
();
rs
.
next
();
assertEquals
(
1L
,
rs
.
getLong
(
1
));
rs
.
next
();
assertEquals
(
2L
,
rs
.
getLong
(
1
));
rs
.
next
();
assertEquals
(
3L
,
rs
.
getLong
(
1
));
assertFalse
(
rs
.
next
());
stat
.
execute
(
"DROP TABLE TEST"
);
stat
.
execute
(
"DROP SEQUENCE SEQ"
);
}
/**
* Test method for INSERT ... SELECT operator.
*
* @param conn
* connection
* @throws Exception
* on exception
*/
private
void
testInsertWithSelect
(
Connection
conn
)
throws
Exception
{
Statement
stat
=
conn
.
createStatement
();
stat
.
execute
(
"CREATE TABLE TEST (ID BIGINT PRIMARY KEY AUTO_INCREMENT, VALUE INT NOT NULL)"
);
PreparedStatement
prep
=
conn
.
prepareStatement
(
"INSERT INTO TEST(VALUE) SELECT 10"
,
Statement
.
RETURN_GENERATED_KEYS
);
prep
.
executeUpdate
();
ResultSet
rs
=
prep
.
getGeneratedKeys
();
assertTrue
(
rs
.
next
());
assertEquals
(
1
,
rs
.
getLong
(
1
));
rs
.
close
();
stat
.
execute
(
"DROP TABLE TEST"
);
}
/**
* Test method for MERGE USING operator.
*
* @param conn
* connection
* @throws Exception
* on exception
*/
private
void
testMergeUsing
(
Connection
conn
)
throws
Exception
{
Statement
stat
=
conn
.
createStatement
();
stat
.
execute
(
"CREATE TABLE SOURCE (ID BIGINT PRIMARY KEY AUTO_INCREMENT,"
+
" UID INT NOT NULL UNIQUE, VALUE INT NOT NULL)"
);
stat
.
execute
(
"CREATE TABLE DESTINATION (ID BIGINT PRIMARY KEY AUTO_INCREMENT,"
+
" UID INT NOT NULL UNIQUE, VALUE INT NOT NULL)"
);
PreparedStatement
ps
=
conn
.
prepareStatement
(
"INSERT INTO SOURCE(UID, VALUE) VALUES (?, ?)"
);
for
(
int
i
=
1
;
i
<=
100
;
i
++)
{
ps
.
setInt
(
1
,
i
);
ps
.
setInt
(
2
,
i
*
10
+
5
);
ps
.
executeUpdate
();
}
// Insert first half of a rows with different values
ps
=
conn
.
prepareStatement
(
"INSERT INTO DESTINATION(UID, VALUE) VALUES (?, ?)"
);
for
(
int
i
=
1
;
i
<=
50
;
i
++)
{
ps
.
setInt
(
1
,
i
);
ps
.
setInt
(
2
,
i
*
10
);
ps
.
executeUpdate
();
}
// And merge second half into it, first half will be updated with a new values
ps
=
conn
.
prepareStatement
(
"MERGE INTO DESTINATION USING SOURCE ON (DESTINATION.UID = SOURCE.UID)"
+
" WHEN MATCHED THEN UPDATE SET VALUE = SOURCE.VALUE"
+
" WHEN NOT MATCHED THEN INSERT (UID, VALUE) VALUES (SOURCE.UID, SOURCE.VALUE)"
,
Statement
.
RETURN_GENERATED_KEYS
);
// All rows should be either updated or inserted
assertEquals
(
100
,
ps
.
executeUpdate
());
ResultSet
rs
=
ps
.
getGeneratedKeys
();
// Only 50 keys for inserted rows should be generated
for
(
int
i
=
1
;
i
<=
50
;
i
++)
{
assertTrue
(
rs
.
next
());
assertEquals
(
i
+
50
,
rs
.
getLong
(
1
));
}
assertFalse
(
rs
.
next
());
rs
.
close
();
// Check merged data
rs
=
stat
.
executeQuery
(
"SELECT ID, UID, VALUE FROM DESTINATION ORDER BY ID"
);
for
(
int
i
=
1
;
i
<=
100
;
i
++)
{
assertTrue
(
rs
.
next
());
assertEquals
(
i
,
rs
.
getLong
(
1
));
assertEquals
(
i
,
rs
.
getInt
(
2
));
assertEquals
(
i
*
10
+
5
,
rs
.
getInt
(
3
));
}
assertFalse
(
rs
.
next
());
stat
.
execute
(
"DROP TABLE SOURCE"
);
stat
.
execute
(
"DROP TABLE DESTINATION"
);
}
/**
* Test method for shared connection between several statements in different
* threads.
*
* @param conn
* connection
* @throws Exception
* on exception
*/
private
void
testMultithreaded
(
final
Connection
conn
)
throws
Exception
{
Statement
stat
=
conn
.
createStatement
();
stat
.
execute
(
"CREATE TABLE TEST (ID BIGINT PRIMARY KEY AUTO_INCREMENT,"
+
"VALUE INT NOT NULL)"
);
final
int
count
=
4
,
iterations
=
10_000
;
Thread
[]
threads
=
new
Thread
[
count
];
final
long
[]
keys
=
new
long
[
count
*
iterations
];
for
(
int
i
=
0
;
i
<
count
;
i
++)
{
final
int
num
=
i
;
threads
[
num
]
=
new
Thread
(
"getGeneratedKeys-"
+
num
)
{
@Override
public
void
run
()
{
try
{
PreparedStatement
prep
=
conn
.
prepareStatement
(
"INSERT INTO TEST(VALUE) VALUES (?)"
,
Statement
.
RETURN_GENERATED_KEYS
);
for
(
int
i
=
0
;
i
<
iterations
;
i
++)
{
int
value
=
iterations
*
num
+
i
;
prep
.
setInt
(
1
,
value
);
prep
.
execute
();
ResultSet
rs
=
prep
.
getGeneratedKeys
();
rs
.
next
();
keys
[
value
]
=
rs
.
getLong
(
1
);
rs
.
close
();
}
}
catch
(
SQLException
ex
)
{
ex
.
printStackTrace
();
}
}
};
}
for
(
int
i
=
0
;
i
<
count
;
i
++)
{
threads
[
i
].
start
();
}
for
(
int
i
=
0
;
i
<
count
;
i
++)
{
threads
[
i
].
join
();
}
ResultSet
rs
=
stat
.
executeQuery
(
"SELECT VALUE, ID FROM TEST ORDER BY VALUE"
);
for
(
int
i
=
0
;
i
<
keys
.
length
;
i
++)
{
assertTrue
(
rs
.
next
());
assertEquals
(
i
,
rs
.
getInt
(
1
));
assertEquals
(
keys
[
i
],
rs
.
getLong
(
2
));
}
assertFalse
(
rs
.
next
());
rs
.
close
();
stat
.
execute
(
"DROP TABLE TEST"
);
}
/**
* Test method for case of letters in column names.
*
* @param conn
* connection
* @throws Exception
* on exception
*/
private
void
testNameCase
(
Connection
conn
)
throws
Exception
{
Statement
stat
=
conn
.
createStatement
();
stat
.
execute
(
"CREATE TABLE TEST (ID BIGINT PRIMARY KEY AUTO_INCREMENT,"
+
"\"id\" UUID NOT NULL DEFAULT RANDOM_UUID(), VALUE INT NOT NULL)"
);
// Test columns with only difference in case
PreparedStatement
prep
=
conn
.
prepareStatement
(
"INSERT INTO TEST(VALUE) VALUES (10)"
,
new
String
[]
{
"id"
,
"ID"
});
prep
.
executeUpdate
();
ResultSet
rs
=
prep
.
getGeneratedKeys
();
assertEquals
(
2
,
rs
.
getMetaData
().
getColumnCount
());
assertEquals
(
"id"
,
rs
.
getMetaData
().
getColumnName
(
1
));
assertEquals
(
"ID"
,
rs
.
getMetaData
().
getColumnName
(
2
));
assertTrue
(
rs
.
next
());
assertEquals
(
UUID
.
class
,
rs
.
getObject
(
1
).
getClass
());
assertEquals
(
1L
,
rs
.
getLong
(
2
));
assertFalse
(
rs
.
next
());
rs
.
close
();
// Test lower case name of upper case column
stat
.
execute
(
"ALTER TABLE TEST DROP COLUMN \"id\""
);
prep
=
conn
.
prepareStatement
(
"INSERT INTO TEST(VALUE) VALUES (20)"
,
new
String
[]
{
"id"
});
prep
.
executeUpdate
();
rs
=
prep
.
getGeneratedKeys
();
assertEquals
(
1
,
rs
.
getMetaData
().
getColumnCount
());
assertEquals
(
"ID"
,
rs
.
getMetaData
().
getColumnName
(
1
));
assertTrue
(
rs
.
next
());
assertEquals
(
2L
,
rs
.
getLong
(
1
));
assertFalse
(
rs
.
next
());
rs
.
close
();
// Test upper case name of lower case column
stat
.
execute
(
"ALTER TABLE TEST ALTER COLUMN ID RENAME TO \"id\""
);
prep
=
conn
.
prepareStatement
(
"INSERT INTO TEST(VALUE) VALUES (30)"
,
new
String
[]
{
"ID"
});
prep
.
executeUpdate
();
rs
=
prep
.
getGeneratedKeys
();
assertEquals
(
1
,
rs
.
getMetaData
().
getColumnCount
());
assertEquals
(
"id"
,
rs
.
getMetaData
().
getColumnName
(
1
));
assertTrue
(
rs
.
next
());
assertEquals
(
3L
,
rs
.
getLong
(
1
));
assertFalse
(
rs
.
next
());
rs
.
close
();
stat
.
execute
(
"DROP TABLE TEST"
);
}
/**
* Test method for
* {@link Connection#prepareStatement(String)}.{@link PreparedStatement#execute()}.
*
* @param conn
* connection
* @throws Exception
* on exception
*/
private
void
testPrepareStatement_Execute
(
Connection
conn
)
throws
Exception
{
Statement
stat
=
conn
.
createStatement
();
stat
.
execute
(
"CREATE TABLE TEST (ID BIGINT PRIMARY KEY AUTO_INCREMENT,"
+
"UID UUID NOT NULL DEFAULT RANDOM_UUID(), VALUE INT NOT NULL)"
);
PreparedStatement
prep
=
conn
.
prepareStatement
(
"INSERT INTO TEST(VALUE) VALUES (10)"
);
prep
.
execute
();
ResultSet
rs
=
prep
.
getGeneratedKeys
();
assertFalse
(
rs
.
next
());
rs
.
close
();
stat
.
execute
(
"DROP TABLE TEST"
);
}
/**
* Test method for
* {@link Connection#prepareStatement(String)}.{@link PreparedStatement#executeBatch()}.
*
* @param conn
* connection
* @throws Exception
* on exception
*/
private
void
testPrepareStatement_ExecuteBatch
(
Connection
conn
)
throws
Exception
{
Statement
stat
=
conn
.
createStatement
();
stat
.
execute
(
"CREATE TABLE TEST (ID BIGINT PRIMARY KEY AUTO_INCREMENT,"
+
"UID UUID NOT NULL DEFAULT RANDOM_UUID(), VALUE INT NOT NULL)"
);
PreparedStatement
prep
=
conn
.
prepareStatement
(
"INSERT INTO TEST(VALUE) VALUES (10)"
);
prep
.
addBatch
();
prep
.
addBatch
();
prep
.
executeBatch
();
ResultSet
rs
=
prep
.
getGeneratedKeys
();
assertFalse
(
rs
.
next
());
rs
.
close
();
stat
.
execute
(
"DROP TABLE TEST"
);
}
/**
* Test method for
* {@link Connection#prepareStatement(String)}.{@link PreparedStatement#executeLargeBatch()}.
*
* @param conn
* connection
* @throws Exception
* on exception
*/
private
void
testPrepareStatement_ExecuteLargeBatch
(
Connection
conn
)
throws
Exception
{
Statement
stat
=
conn
.
createStatement
();
stat
.
execute
(
"CREATE TABLE TEST (ID BIGINT PRIMARY KEY AUTO_INCREMENT,"
+
"UID UUID NOT NULL DEFAULT RANDOM_UUID(), VALUE INT NOT NULL)"
);
JdbcPreparedStatement
prep
=
(
JdbcPreparedStatement
)
conn
.
prepareStatement
(
"INSERT INTO TEST(VALUE) VALUES (10)"
);
prep
.
addBatch
();
prep
.
addBatch
();
prep
.
executeLargeBatch
();
ResultSet
rs
=
prep
.
getGeneratedKeys
();
assertFalse
(
rs
.
next
());
rs
.
close
();
stat
.
execute
(
"DROP TABLE TEST"
);
}
/**
* Test method for
* {@link Connection#prepareStatement(String)}.{@link PreparedStatement#executeLargeUpdate()}.
*
* @param conn
* connection
* @throws Exception
* on exception
*/
private
void
testPrepareStatement_ExecuteLargeUpdate
(
Connection
conn
)
throws
Exception
{
Statement
stat
=
conn
.
createStatement
();
stat
.
execute
(
"CREATE TABLE TEST (ID BIGINT PRIMARY KEY AUTO_INCREMENT,"
+
"UID UUID NOT NULL DEFAULT RANDOM_UUID(), VALUE INT NOT NULL)"
);
JdbcPreparedStatement
prep
=
(
JdbcPreparedStatement
)
conn
.
prepareStatement
(
"INSERT INTO TEST(VALUE) VALUES (10)"
);
prep
.
executeLargeUpdate
();
ResultSet
rs
=
prep
.
getGeneratedKeys
();
assertFalse
(
rs
.
next
());
rs
.
close
();
stat
.
execute
(
"DROP TABLE TEST"
);
}
/**
* Test method for
* {@link Connection#prepareStatement(String)}.{@link PreparedStatement#executeUpdate()}.
*
* @param conn
* connection
* @throws Exception
* on exception
*/
private
void
testPrepareStatement_ExecuteUpdate
(
Connection
conn
)
throws
Exception
{
Statement
stat
=
conn
.
createStatement
();
stat
.
execute
(
"CREATE TABLE TEST (ID BIGINT PRIMARY KEY AUTO_INCREMENT,"
+
"UID UUID NOT NULL DEFAULT RANDOM_UUID(), VALUE INT NOT NULL)"
);
PreparedStatement
prep
=
conn
.
prepareStatement
(
"INSERT INTO TEST(VALUE) VALUES (10)"
);
prep
.
executeUpdate
();
ResultSet
rs
=
prep
.
getGeneratedKeys
();
assertFalse
(
rs
.
next
());
rs
.
close
();
stat
.
execute
(
"DROP TABLE TEST"
);
}
/**
* Test method for
* {@link Connection#prepareStatement(String, int)}.{@link PreparedStatement#execute()}.
*
* @param conn
* connection
* @throws Exception
* on exception
*/
private
void
testPrepareStatement_int_Execute
(
Connection
conn
)
throws
Exception
{
Statement
stat
=
conn
.
createStatement
();
stat
.
execute
(
"CREATE TABLE TEST (ID BIGINT PRIMARY KEY AUTO_INCREMENT,"
+
"UID UUID NOT NULL DEFAULT RANDOM_UUID(), VALUE INT NOT NULL)"
);
PreparedStatement
prep
=
conn
.
prepareStatement
(
"INSERT INTO TEST(VALUE) VALUES (10)"
,
Statement
.
NO_GENERATED_KEYS
);
prep
.
execute
();
ResultSet
rs
=
prep
.
getGeneratedKeys
();
assertFalse
(
rs
.
next
());
rs
.
close
();
prep
=
conn
.
prepareStatement
(
"INSERT INTO TEST(VALUE) VALUES (20)"
,
Statement
.
RETURN_GENERATED_KEYS
);
prep
.
execute
();
rs
=
prep
.
getGeneratedKeys
();
assertEquals
(
2
,
rs
.
getMetaData
().
getColumnCount
());
assertEquals
(
"ID"
,
rs
.
getMetaData
().
getColumnName
(
1
));
assertEquals
(
"UID"
,
rs
.
getMetaData
().
getColumnName
(
2
));
assertTrue
(
rs
.
next
());
assertEquals
(
2L
,
rs
.
getLong
(
1
));
assertEquals
(
UUID
.
class
,
rs
.
getObject
(
2
).
getClass
());
assertFalse
(
rs
.
next
());
rs
.
close
();
stat
.
execute
(
"DROP TABLE TEST"
);
}
/**
* Test method for
* {@link Connection#prepareStatement(String, int)}.{@link PreparedStatement#executeBatch()}.
*
* @param conn
* connection
* @throws Exception
* on exception
*/
private
void
testPrepareStatement_int_ExecuteBatch
(
Connection
conn
)
throws
Exception
{
Statement
stat
=
conn
.
createStatement
();
stat
.
execute
(
"CREATE TABLE TEST (ID BIGINT PRIMARY KEY AUTO_INCREMENT,"
+
"UID UUID NOT NULL DEFAULT RANDOM_UUID(), VALUE INT NOT NULL)"
);
PreparedStatement
prep
=
conn
.
prepareStatement
(
"INSERT INTO TEST(VALUE) VALUES (10)"
,
Statement
.
NO_GENERATED_KEYS
);
prep
.
addBatch
();
prep
.
addBatch
();
prep
.
executeBatch
();
ResultSet
rs
=
prep
.
getGeneratedKeys
();
assertFalse
(
rs
.
next
());
rs
.
close
();
prep
=
conn
.
prepareStatement
(
"INSERT INTO TEST(VALUE) VALUES (20)"
,
Statement
.
RETURN_GENERATED_KEYS
);
prep
.
addBatch
();
prep
.
addBatch
();
prep
.
executeBatch
();
rs
=
prep
.
getGeneratedKeys
();
assertEquals
(
2
,
rs
.
getMetaData
().
getColumnCount
());
assertEquals
(
"ID"
,
rs
.
getMetaData
().
getColumnName
(
1
));
assertEquals
(
"UID"
,
rs
.
getMetaData
().
getColumnName
(
2
));
assertTrue
(
rs
.
next
());
assertEquals
(
3L
,
rs
.
getLong
(
1
));
assertEquals
(
UUID
.
class
,
rs
.
getObject
(
2
).
getClass
());
assertTrue
(
rs
.
next
());
assertEquals
(
4L
,
rs
.
getLong
(
1
));
assertEquals
(
UUID
.
class
,
rs
.
getObject
(
2
).
getClass
());
assertFalse
(
rs
.
next
());
rs
.
close
();
stat
.
execute
(
"DROP TABLE TEST"
);
}
/**
* Test method for
* {@link Connection#prepareStatement(String, int)}.{@link PreparedStatement#executeLargeBatch()}.
*
* @param conn
* connection
* @throws Exception
* on exception
*/
private
void
testPrepareStatement_int_ExecuteLargeBatch
(
Connection
conn
)
throws
Exception
{
Statement
stat
=
conn
.
createStatement
();
stat
.
execute
(
"CREATE TABLE TEST (ID BIGINT PRIMARY KEY AUTO_INCREMENT,"
+
"UID UUID NOT NULL DEFAULT RANDOM_UUID(), VALUE INT NOT NULL)"
);
JdbcPreparedStatement
prep
=
(
JdbcPreparedStatement
)
conn
.
prepareStatement
(
"INSERT INTO TEST(VALUE) VALUES (10)"
,
Statement
.
NO_GENERATED_KEYS
);
prep
.
addBatch
();
prep
.
addBatch
();
prep
.
executeLargeBatch
();
ResultSet
rs
=
prep
.
getGeneratedKeys
();
assertFalse
(
rs
.
next
());
rs
.
close
();
prep
=
(
JdbcPreparedStatement
)
conn
.
prepareStatement
(
"INSERT INTO TEST(VALUE) VALUES (20)"
,
Statement
.
RETURN_GENERATED_KEYS
);
prep
.
addBatch
();
prep
.
addBatch
();
prep
.
executeLargeBatch
();
rs
=
prep
.
getGeneratedKeys
();
assertEquals
(
2
,
rs
.
getMetaData
().
getColumnCount
());
assertEquals
(
"ID"
,
rs
.
getMetaData
().
getColumnName
(
1
));
assertEquals
(
"UID"
,
rs
.
getMetaData
().
getColumnName
(
2
));
assertTrue
(
rs
.
next
());
assertEquals
(
3L
,
rs
.
getLong
(
1
));
assertEquals
(
UUID
.
class
,
rs
.
getObject
(
2
).
getClass
());
assertTrue
(
rs
.
next
());
assertEquals
(
4L
,
rs
.
getLong
(
1
));
assertEquals
(
UUID
.
class
,
rs
.
getObject
(
2
).
getClass
());
assertFalse
(
rs
.
next
());
rs
.
close
();
stat
.
execute
(
"DROP TABLE TEST"
);
}
/**
* Test method for
* {@link Connection#prepareStatement(String, int)}.{@link PreparedStatement#executeLargeUpdate()}.
*
* @param conn
* connection
* @throws Exception
* on exception
*/
private
void
testPrepareStatement_int_ExecuteLargeUpdate
(
Connection
conn
)
throws
Exception
{
Statement
stat
=
conn
.
createStatement
();
stat
.
execute
(
"CREATE TABLE TEST (ID BIGINT PRIMARY KEY AUTO_INCREMENT,"
+
"UID UUID NOT NULL DEFAULT RANDOM_UUID(), VALUE INT NOT NULL)"
);
JdbcPreparedStatement
prep
=
(
JdbcPreparedStatement
)
conn
.
prepareStatement
(
"INSERT INTO TEST(VALUE) VALUES (10)"
,
Statement
.
NO_GENERATED_KEYS
);
prep
.
executeLargeUpdate
();
ResultSet
rs
=
prep
.
getGeneratedKeys
();
assertFalse
(
rs
.
next
());
rs
.
close
();
prep
=
(
JdbcPreparedStatement
)
conn
.
prepareStatement
(
"INSERT INTO TEST(VALUE) VALUES (20)"
,
Statement
.
RETURN_GENERATED_KEYS
);
prep
.
executeLargeUpdate
();
rs
=
prep
.
getGeneratedKeys
();
assertEquals
(
2
,
rs
.
getMetaData
().
getColumnCount
());
assertEquals
(
"ID"
,
rs
.
getMetaData
().
getColumnName
(
1
));
assertEquals
(
"UID"
,
rs
.
getMetaData
().
getColumnName
(
2
));
assertTrue
(
rs
.
next
());
assertEquals
(
2L
,
rs
.
getLong
(
1
));
assertEquals
(
UUID
.
class
,
rs
.
getObject
(
2
).
getClass
());
assertFalse
(
rs
.
next
());
rs
.
close
();
stat
.
execute
(
"DROP TABLE TEST"
);
}
/**
* Test method for
* {@link Connection#prepareStatement(String, int)}.{@link PreparedStatement#executeUpdate()}.
*
* @param conn
* connection
* @throws Exception
* on exception
*/
private
void
testPrepareStatement_int_ExecuteUpdate
(
Connection
conn
)
throws
Exception
{
Statement
stat
=
conn
.
createStatement
();
stat
.
execute
(
"CREATE TABLE TEST (ID BIGINT PRIMARY KEY AUTO_INCREMENT,"
+
"UID UUID NOT NULL DEFAULT RANDOM_UUID(), VALUE INT NOT NULL)"
);
PreparedStatement
prep
=
conn
.
prepareStatement
(
"INSERT INTO TEST(VALUE) VALUES (10)"
,
Statement
.
NO_GENERATED_KEYS
);
prep
.
executeUpdate
();
ResultSet
rs
=
prep
.
getGeneratedKeys
();
assertFalse
(
rs
.
next
());
rs
.
close
();
prep
=
conn
.
prepareStatement
(
"INSERT INTO TEST(VALUE) VALUES (20)"
,
Statement
.
RETURN_GENERATED_KEYS
);
prep
.
executeUpdate
();
rs
=
prep
.
getGeneratedKeys
();
assertEquals
(
2
,
rs
.
getMetaData
().
getColumnCount
());
assertEquals
(
"ID"
,
rs
.
getMetaData
().
getColumnName
(
1
));
assertEquals
(
"UID"
,
rs
.
getMetaData
().
getColumnName
(
2
));
assertTrue
(
rs
.
next
());
assertEquals
(
2L
,
rs
.
getLong
(
1
));
assertEquals
(
UUID
.
class
,
rs
.
getObject
(
2
).
getClass
());
assertFalse
(
rs
.
next
());
rs
.
close
();
stat
.
execute
(
"DROP TABLE TEST"
);
}
/**
* Test method for
* {@link Connection#prepareStatement(String, int[])}.{@link PreparedStatement#execute()}.
*
* @param conn
* connection
* @throws Exception
* on exception
*/
private
void
testPrepareStatement_intArray_Execute
(
Connection
conn
)
throws
Exception
{
Statement
stat
=
conn
.
createStatement
();
stat
.
execute
(
"CREATE TABLE TEST (ID BIGINT PRIMARY KEY AUTO_INCREMENT,"
+
"UID UUID NOT NULL DEFAULT RANDOM_UUID(), VALUE INT NOT NULL)"
);
PreparedStatement
prep
=
conn
.
prepareStatement
(
"INSERT INTO TEST(VALUE) VALUES (10)"
,
new
int
[
0
]);
prep
.
execute
();
ResultSet
rs
=
prep
.
getGeneratedKeys
();
assertFalse
(
rs
.
next
());
rs
.
close
();
prep
=
conn
.
prepareStatement
(
"INSERT INTO TEST(VALUE) VALUES (20)"
,
new
int
[]
{
1
,
2
});
prep
.
execute
();
rs
=
prep
.
getGeneratedKeys
();
assertEquals
(
2
,
rs
.
getMetaData
().
getColumnCount
());
assertEquals
(
"ID"
,
rs
.
getMetaData
().
getColumnName
(
1
));
assertEquals
(
"UID"
,
rs
.
getMetaData
().
getColumnName
(
2
));
assertTrue
(
rs
.
next
());
assertEquals
(
2L
,
rs
.
getLong
(
1
));
assertEquals
(
UUID
.
class
,
rs
.
getObject
(
2
).
getClass
());
assertFalse
(
rs
.
next
());
rs
.
close
();
prep
=
conn
.
prepareStatement
(
"INSERT INTO TEST(VALUE) VALUES (30)"
,
new
int
[]
{
2
,
1
});
prep
.
execute
();
rs
=
prep
.
getGeneratedKeys
();
assertEquals
(
2
,
rs
.
getMetaData
().
getColumnCount
());
assertEquals
(
"UID"
,
rs
.
getMetaData
().
getColumnName
(
1
));
assertEquals
(
"ID"
,
rs
.
getMetaData
().
getColumnName
(
2
));
assertTrue
(
rs
.
next
());
assertEquals
(
UUID
.
class
,
rs
.
getObject
(
1
).
getClass
());
assertEquals
(
3L
,
rs
.
getLong
(
2
));
assertFalse
(
rs
.
next
());
rs
.
close
();
prep
=
conn
.
prepareStatement
(
"INSERT INTO TEST(VALUE) VALUES (40)"
,
new
int
[]
{
2
});
prep
.
execute
();
rs
=
prep
.
getGeneratedKeys
();
assertEquals
(
1
,
rs
.
getMetaData
().
getColumnCount
());
assertEquals
(
"UID"
,
rs
.
getMetaData
().
getColumnName
(
1
));
assertTrue
(
rs
.
next
());
assertEquals
(
UUID
.
class
,
rs
.
getObject
(
1
).
getClass
());
assertFalse
(
rs
.
next
());
rs
.
close
();
stat
.
execute
(
"DROP TABLE TEST"
);
}
/**
* Test method for
* {@link Connection#prepareStatement(String, int[])}.{@link PreparedStatement#executeBatch()}.
*
* @param conn
* connection
* @throws Exception
* on exception
*/
private
void
testPrepareStatement_intArray_ExecuteBatch
(
Connection
conn
)
throws
Exception
{
Statement
stat
=
conn
.
createStatement
();
stat
.
execute
(
"CREATE TABLE TEST (ID BIGINT PRIMARY KEY AUTO_INCREMENT,"
+
"UID UUID NOT NULL DEFAULT RANDOM_UUID(), VALUE INT NOT NULL)"
);
PreparedStatement
prep
=
conn
.
prepareStatement
(
"INSERT INTO TEST(VALUE) VALUES (10)"
,
new
int
[
0
]);
prep
.
addBatch
();
prep
.
addBatch
();
prep
.
executeBatch
();
ResultSet
rs
=
prep
.
getGeneratedKeys
();
assertFalse
(
rs
.
next
());
rs
.
close
();
prep
=
conn
.
prepareStatement
(
"INSERT INTO TEST(VALUE) VALUES (20)"
,
new
int
[]
{
1
,
2
});
prep
.
addBatch
();
prep
.
addBatch
();
prep
.
executeBatch
();
rs
=
prep
.
getGeneratedKeys
();
assertEquals
(
2
,
rs
.
getMetaData
().
getColumnCount
());
assertEquals
(
"ID"
,
rs
.
getMetaData
().
getColumnName
(
1
));
assertEquals
(
"UID"
,
rs
.
getMetaData
().
getColumnName
(
2
));
assertTrue
(
rs
.
next
());
assertEquals
(
3L
,
rs
.
getLong
(
1
));
assertEquals
(
UUID
.
class
,
rs
.
getObject
(
2
).
getClass
());
assertTrue
(
rs
.
next
());
assertEquals
(
4L
,
rs
.
getLong
(
1
));
assertEquals
(
UUID
.
class
,
rs
.
getObject
(
2
).
getClass
());
assertFalse
(
rs
.
next
());
rs
.
close
();
prep
=
conn
.
prepareStatement
(
"INSERT INTO TEST(VALUE) VALUES (30)"
,
new
int
[]
{
2
,
1
});
prep
.
addBatch
();
prep
.
addBatch
();
prep
.
executeBatch
();
rs
=
prep
.
getGeneratedKeys
();
assertEquals
(
2
,
rs
.
getMetaData
().
getColumnCount
());
assertEquals
(
"UID"
,
rs
.
getMetaData
().
getColumnName
(
1
));
assertEquals
(
"ID"
,
rs
.
getMetaData
().
getColumnName
(
2
));
assertTrue
(
rs
.
next
());
assertEquals
(
UUID
.
class
,
rs
.
getObject
(
1
).
getClass
());
assertEquals
(
5L
,
rs
.
getLong
(
2
));
assertTrue
(
rs
.
next
());
assertEquals
(
UUID
.
class
,
rs
.
getObject
(
1
).
getClass
());
assertEquals
(
6L
,
rs
.
getLong
(
2
));
assertFalse
(
rs
.
next
());
rs
.
close
();
prep
=
conn
.
prepareStatement
(
"INSERT INTO TEST(VALUE) VALUES (40)"
,
new
int
[]
{
2
});
prep
.
addBatch
();
prep
.
addBatch
();
prep
.
executeBatch
();
rs
=
prep
.
getGeneratedKeys
();
assertEquals
(
1
,
rs
.
getMetaData
().
getColumnCount
());
assertEquals
(
"UID"
,
rs
.
getMetaData
().
getColumnName
(
1
));
assertTrue
(
rs
.
next
());
assertEquals
(
UUID
.
class
,
rs
.
getObject
(
1
).
getClass
());
assertTrue
(
rs
.
next
());
assertEquals
(
UUID
.
class
,
rs
.
getObject
(
1
).
getClass
());
assertFalse
(
rs
.
next
());
rs
.
close
();
stat
.
execute
(
"DROP TABLE TEST"
);
}
/**
* Test method for
* {@link Connection#prepareStatement(String, int[])}.{@link PreparedStatement#executeLargeBatch()}.
*
* @param conn
* connection
* @throws Exception
* on exception
*/
private
void
testPrepareStatement_intArray_ExecuteLargeBatch
(
Connection
conn
)
throws
Exception
{
Statement
stat
=
conn
.
createStatement
();
stat
.
execute
(
"CREATE TABLE TEST (ID BIGINT PRIMARY KEY AUTO_INCREMENT,"
+
"UID UUID NOT NULL DEFAULT RANDOM_UUID(), VALUE INT NOT NULL)"
);
JdbcPreparedStatement
prep
=
(
JdbcPreparedStatement
)
conn
.
prepareStatement
(
"INSERT INTO TEST(VALUE) VALUES (10)"
,
new
int
[
0
]);
prep
.
addBatch
();
prep
.
addBatch
();
prep
.
executeLargeBatch
();
ResultSet
rs
=
prep
.
getGeneratedKeys
();
assertFalse
(
rs
.
next
());
rs
.
close
();
prep
=
(
JdbcPreparedStatement
)
conn
.
prepareStatement
(
"INSERT INTO TEST(VALUE) VALUES (20)"
,
new
int
[]
{
1
,
2
});
prep
.
addBatch
();
prep
.
addBatch
();
prep
.
executeLargeBatch
();
rs
=
prep
.
getGeneratedKeys
();
assertEquals
(
2
,
rs
.
getMetaData
().
getColumnCount
());
assertEquals
(
"ID"
,
rs
.
getMetaData
().
getColumnName
(
1
));
assertEquals
(
"UID"
,
rs
.
getMetaData
().
getColumnName
(
2
));
assertTrue
(
rs
.
next
());
assertEquals
(
3L
,
rs
.
getLong
(
1
));
assertEquals
(
UUID
.
class
,
rs
.
getObject
(
2
).
getClass
());
assertTrue
(
rs
.
next
());
assertEquals
(
4L
,
rs
.
getLong
(
1
));
assertEquals
(
UUID
.
class
,
rs
.
getObject
(
2
).
getClass
());
assertFalse
(
rs
.
next
());
rs
.
close
();
prep
=
(
JdbcPreparedStatement
)
conn
.
prepareStatement
(
"INSERT INTO TEST(VALUE) VALUES (30)"
,
new
int
[]
{
2
,
1
});
prep
.
addBatch
();
prep
.
addBatch
();
prep
.
executeLargeBatch
();
rs
=
prep
.
getGeneratedKeys
();
assertEquals
(
2
,
rs
.
getMetaData
().
getColumnCount
());
assertEquals
(
"UID"
,
rs
.
getMetaData
().
getColumnName
(
1
));
assertEquals
(
"ID"
,
rs
.
getMetaData
().
getColumnName
(
2
));
assertTrue
(
rs
.
next
());
assertEquals
(
UUID
.
class
,
rs
.
getObject
(
1
).
getClass
());
assertEquals
(
5L
,
rs
.
getLong
(
2
));
assertTrue
(
rs
.
next
());
assertEquals
(
UUID
.
class
,
rs
.
getObject
(
1
).
getClass
());
assertEquals
(
6L
,
rs
.
getLong
(
2
));
assertFalse
(
rs
.
next
());
rs
.
close
();
prep
=
(
JdbcPreparedStatement
)
conn
.
prepareStatement
(
"INSERT INTO TEST(VALUE) VALUES (40)"
,
new
int
[]
{
2
});
prep
.
addBatch
();
prep
.
addBatch
();
prep
.
executeLargeBatch
();
rs
=
prep
.
getGeneratedKeys
();
assertEquals
(
1
,
rs
.
getMetaData
().
getColumnCount
());
assertEquals
(
"UID"
,
rs
.
getMetaData
().
getColumnName
(
1
));
assertTrue
(
rs
.
next
());
assertEquals
(
UUID
.
class
,
rs
.
getObject
(
1
).
getClass
());
assertTrue
(
rs
.
next
());
assertEquals
(
UUID
.
class
,
rs
.
getObject
(
1
).
getClass
());
assertFalse
(
rs
.
next
());
rs
.
close
();
stat
.
execute
(
"DROP TABLE TEST"
);
}
/**
* Test method for
* {@link Connection#prepareStatement(String, int[])}.{@link PreparedStatement#executeLargeUpdate()}.
*
* @param conn
* connection
* @throws Exception
* on exception
*/
private
void
testPrepareStatement_intArray_ExecuteLargeUpdate
(
Connection
conn
)
throws
Exception
{
Statement
stat
=
conn
.
createStatement
();
stat
.
execute
(
"CREATE TABLE TEST (ID BIGINT PRIMARY KEY AUTO_INCREMENT,"
+
"UID UUID NOT NULL DEFAULT RANDOM_UUID(), VALUE INT NOT NULL)"
);
JdbcPreparedStatement
prep
=
(
JdbcPreparedStatement
)
conn
.
prepareStatement
(
"INSERT INTO TEST(VALUE) VALUES (10)"
,
new
int
[
0
]);
prep
.
executeLargeUpdate
();
ResultSet
rs
=
prep
.
getGeneratedKeys
();
assertFalse
(
rs
.
next
());
rs
.
close
();
prep
=
(
JdbcPreparedStatement
)
conn
.
prepareStatement
(
"INSERT INTO TEST(VALUE) VALUES (20)"
,
new
int
[]
{
1
,
2
});
prep
.
executeLargeUpdate
();
rs
=
prep
.
getGeneratedKeys
();
assertEquals
(
2
,
rs
.
getMetaData
().
getColumnCount
());
assertEquals
(
"ID"
,
rs
.
getMetaData
().
getColumnName
(
1
));
assertEquals
(
"UID"
,
rs
.
getMetaData
().
getColumnName
(
2
));
assertTrue
(
rs
.
next
());
assertEquals
(
2L
,
rs
.
getLong
(
1
));
assertEquals
(
UUID
.
class
,
rs
.
getObject
(
2
).
getClass
());
assertFalse
(
rs
.
next
());
rs
.
close
();
prep
=
(
JdbcPreparedStatement
)
conn
.
prepareStatement
(
"INSERT INTO TEST(VALUE) VALUES (30)"
,
new
int
[]
{
2
,
1
});
prep
.
executeLargeUpdate
();
rs
=
prep
.
getGeneratedKeys
();
assertEquals
(
2
,
rs
.
getMetaData
().
getColumnCount
());
assertEquals
(
"UID"
,
rs
.
getMetaData
().
getColumnName
(
1
));
assertEquals
(
"ID"
,
rs
.
getMetaData
().
getColumnName
(
2
));
assertTrue
(
rs
.
next
());
assertEquals
(
UUID
.
class
,
rs
.
getObject
(
1
).
getClass
());
assertEquals
(
3L
,
rs
.
getLong
(
2
));
assertFalse
(
rs
.
next
());
rs
.
close
();
prep
=
(
JdbcPreparedStatement
)
conn
.
prepareStatement
(
"INSERT INTO TEST(VALUE) VALUES (40)"
,
new
int
[]
{
2
});
prep
.
executeLargeUpdate
();
rs
=
prep
.
getGeneratedKeys
();
assertEquals
(
1
,
rs
.
getMetaData
().
getColumnCount
());
assertEquals
(
"UID"
,
rs
.
getMetaData
().
getColumnName
(
1
));
assertTrue
(
rs
.
next
());
assertEquals
(
UUID
.
class
,
rs
.
getObject
(
1
).
getClass
());
assertFalse
(
rs
.
next
());
rs
.
close
();
stat
.
execute
(
"DROP TABLE TEST"
);
}
/**
* Test method for
* {@link Connection#prepareStatement(String, int[])}.{@link PreparedStatement#executeUpdate()}.
*
* @param conn
* connection
* @throws Exception
* on exception
*/
private
void
testPrepareStatement_intArray_ExecuteUpdate
(
Connection
conn
)
throws
Exception
{
Statement
stat
=
conn
.
createStatement
();
stat
.
execute
(
"CREATE TABLE TEST (ID BIGINT PRIMARY KEY AUTO_INCREMENT,"
+
"UID UUID NOT NULL DEFAULT RANDOM_UUID(), VALUE INT NOT NULL)"
);
PreparedStatement
prep
=
conn
.
prepareStatement
(
"INSERT INTO TEST(VALUE) VALUES (10)"
,
new
int
[
0
]);
prep
.
executeUpdate
();
ResultSet
rs
=
prep
.
getGeneratedKeys
();
assertFalse
(
rs
.
next
());
rs
.
close
();
prep
=
conn
.
prepareStatement
(
"INSERT INTO TEST(VALUE) VALUES (20)"
,
new
int
[]
{
1
,
2
});
prep
.
executeUpdate
();
rs
=
prep
.
getGeneratedKeys
();
assertEquals
(
2
,
rs
.
getMetaData
().
getColumnCount
());
assertEquals
(
"ID"
,
rs
.
getMetaData
().
getColumnName
(
1
));
assertEquals
(
"UID"
,
rs
.
getMetaData
().
getColumnName
(
2
));
assertTrue
(
rs
.
next
());
assertEquals
(
2L
,
rs
.
getLong
(
1
));
assertEquals
(
UUID
.
class
,
rs
.
getObject
(
2
).
getClass
());
assertFalse
(
rs
.
next
());
rs
.
close
();
prep
=
conn
.
prepareStatement
(
"INSERT INTO TEST(VALUE) VALUES (30)"
,
new
int
[]
{
2
,
1
});
prep
.
executeUpdate
();
rs
=
prep
.
getGeneratedKeys
();
assertEquals
(
2
,
rs
.
getMetaData
().
getColumnCount
());
assertEquals
(
"UID"
,
rs
.
getMetaData
().
getColumnName
(
1
));
assertEquals
(
"ID"
,
rs
.
getMetaData
().
getColumnName
(
2
));
assertTrue
(
rs
.
next
());
assertEquals
(
UUID
.
class
,
rs
.
getObject
(
1
).
getClass
());
assertEquals
(
3L
,
rs
.
getLong
(
2
));
assertFalse
(
rs
.
next
());
rs
.
close
();
prep
=
conn
.
prepareStatement
(
"INSERT INTO TEST(VALUE) VALUES (40)"
,
new
int
[]
{
2
});
prep
.
executeUpdate
();
rs
=
prep
.
getGeneratedKeys
();
assertEquals
(
1
,
rs
.
getMetaData
().
getColumnCount
());
assertEquals
(
"UID"
,
rs
.
getMetaData
().
getColumnName
(
1
));
assertTrue
(
rs
.
next
());
assertEquals
(
UUID
.
class
,
rs
.
getObject
(
1
).
getClass
());
assertFalse
(
rs
.
next
());
rs
.
close
();
stat
.
execute
(
"DROP TABLE TEST"
);
}
/**
* Test method for
* {@link Connection#prepareStatement(String, String[])}.{@link PreparedStatement#execute()}.
*
* @param conn
* connection
* @throws Exception
* on exception
*/
private
void
testPrepareStatement_StringArray_Execute
(
Connection
conn
)
throws
Exception
{
Statement
stat
=
conn
.
createStatement
();
stat
.
execute
(
"CREATE TABLE TEST (ID BIGINT PRIMARY KEY AUTO_INCREMENT,"
+
"UID UUID NOT NULL DEFAULT RANDOM_UUID(), VALUE INT NOT NULL)"
);
PreparedStatement
prep
=
conn
.
prepareStatement
(
"INSERT INTO TEST(VALUE) VALUES (10)"
,
new
String
[
0
]);
prep
.
executeUpdate
();
ResultSet
rs
=
prep
.
getGeneratedKeys
();
assertFalse
(
rs
.
next
());
rs
.
close
();
prep
=
conn
.
prepareStatement
(
"INSERT INTO TEST(VALUE) VALUES (20)"
,
new
String
[]
{
"ID"
,
"UID"
});
prep
.
execute
();
rs
=
prep
.
getGeneratedKeys
();
assertEquals
(
2
,
rs
.
getMetaData
().
getColumnCount
());
assertEquals
(
"ID"
,
rs
.
getMetaData
().
getColumnName
(
1
));
assertEquals
(
"UID"
,
rs
.
getMetaData
().
getColumnName
(
2
));
assertTrue
(
rs
.
next
());
assertEquals
(
2L
,
rs
.
getLong
(
1
));
assertEquals
(
UUID
.
class
,
rs
.
getObject
(
2
).
getClass
());
assertFalse
(
rs
.
next
());
rs
.
close
();
prep
=
conn
.
prepareStatement
(
"INSERT INTO TEST(VALUE) VALUES (30)"
,
new
String
[]
{
"UID"
,
"ID"
});
prep
.
execute
();
rs
=
prep
.
getGeneratedKeys
();
assertEquals
(
2
,
rs
.
getMetaData
().
getColumnCount
());
assertEquals
(
"UID"
,
rs
.
getMetaData
().
getColumnName
(
1
));
assertEquals
(
"ID"
,
rs
.
getMetaData
().
getColumnName
(
2
));
assertTrue
(
rs
.
next
());
assertEquals
(
UUID
.
class
,
rs
.
getObject
(
1
).
getClass
());
assertEquals
(
3L
,
rs
.
getLong
(
2
));
assertFalse
(
rs
.
next
());
rs
.
close
();
prep
=
conn
.
prepareStatement
(
"INSERT INTO TEST(VALUE) VALUES (40)"
,
new
String
[]
{
"UID"
});
prep
.
execute
();
rs
=
prep
.
getGeneratedKeys
();
assertEquals
(
1
,
rs
.
getMetaData
().
getColumnCount
());
assertEquals
(
"UID"
,
rs
.
getMetaData
().
getColumnName
(
1
));
assertTrue
(
rs
.
next
());
assertEquals
(
UUID
.
class
,
rs
.
getObject
(
1
).
getClass
());
assertFalse
(
rs
.
next
());
rs
.
close
();
stat
.
execute
(
"DROP TABLE TEST"
);
}
/**
* Test method for
* {@link Connection#prepareStatement(String, String[])}.{@link PreparedStatement#executeBatch()}.
*
* @param conn
* connection
* @throws Exception
* on exception
*/
private
void
testPrepareStatement_StringArray_ExecuteBatch
(
Connection
conn
)
throws
Exception
{
Statement
stat
=
conn
.
createStatement
();
stat
.
execute
(
"CREATE TABLE TEST (ID BIGINT PRIMARY KEY AUTO_INCREMENT,"
+
"UID UUID NOT NULL DEFAULT RANDOM_UUID(), VALUE INT NOT NULL)"
);
PreparedStatement
prep
=
conn
.
prepareStatement
(
"INSERT INTO TEST(VALUE) VALUES (10)"
,
new
String
[
0
]);
prep
.
addBatch
();
prep
.
addBatch
();
prep
.
executeBatch
();
ResultSet
rs
=
prep
.
getGeneratedKeys
();
assertFalse
(
rs
.
next
());
rs
.
close
();
prep
=
conn
.
prepareStatement
(
"INSERT INTO TEST(VALUE) VALUES (20)"
,
new
String
[]
{
"ID"
,
"UID"
});
prep
.
addBatch
();
prep
.
addBatch
();
prep
.
executeBatch
();
rs
=
prep
.
getGeneratedKeys
();
assertEquals
(
2
,
rs
.
getMetaData
().
getColumnCount
());
assertEquals
(
"ID"
,
rs
.
getMetaData
().
getColumnName
(
1
));
assertEquals
(
"UID"
,
rs
.
getMetaData
().
getColumnName
(
2
));
assertTrue
(
rs
.
next
());
assertEquals
(
3L
,
rs
.
getLong
(
1
));
assertEquals
(
UUID
.
class
,
rs
.
getObject
(
2
).
getClass
());
assertTrue
(
rs
.
next
());
assertEquals
(
4L
,
rs
.
getLong
(
1
));
assertEquals
(
UUID
.
class
,
rs
.
getObject
(
2
).
getClass
());
assertFalse
(
rs
.
next
());
rs
.
close
();
prep
=
conn
.
prepareStatement
(
"INSERT INTO TEST(VALUE) VALUES (30)"
,
new
String
[]
{
"UID"
,
"ID"
});
prep
.
addBatch
();
prep
.
addBatch
();
prep
.
executeBatch
();
rs
=
prep
.
getGeneratedKeys
();
assertEquals
(
2
,
rs
.
getMetaData
().
getColumnCount
());
assertEquals
(
"UID"
,
rs
.
getMetaData
().
getColumnName
(
1
));
assertEquals
(
"ID"
,
rs
.
getMetaData
().
getColumnName
(
2
));
assertTrue
(
rs
.
next
());
assertEquals
(
UUID
.
class
,
rs
.
getObject
(
1
).
getClass
());
assertEquals
(
5L
,
rs
.
getLong
(
2
));
assertTrue
(
rs
.
next
());
assertEquals
(
UUID
.
class
,
rs
.
getObject
(
1
).
getClass
());
assertEquals
(
6L
,
rs
.
getLong
(
2
));
assertFalse
(
rs
.
next
());
rs
.
close
();
prep
=
conn
.
prepareStatement
(
"INSERT INTO TEST(VALUE) VALUES (40)"
,
new
String
[]
{
"UID"
});
prep
.
addBatch
();
prep
.
addBatch
();
prep
.
executeBatch
();
rs
=
prep
.
getGeneratedKeys
();
assertEquals
(
1
,
rs
.
getMetaData
().
getColumnCount
());
assertEquals
(
"UID"
,
rs
.
getMetaData
().
getColumnName
(
1
));
assertTrue
(
rs
.
next
());
assertEquals
(
UUID
.
class
,
rs
.
getObject
(
1
).
getClass
());
assertTrue
(
rs
.
next
());
assertEquals
(
UUID
.
class
,
rs
.
getObject
(
1
).
getClass
());
assertFalse
(
rs
.
next
());
rs
.
close
();
stat
.
execute
(
"DROP TABLE TEST"
);
}
/**
* Test method for
* {@link Connection#prepareStatement(String, String[])}.{@link PreparedStatement#executeLargeBatch()}.
*
* @param conn
* connection
* @throws Exception
* on exception
*/
private
void
testPrepareStatement_StringArray_ExecuteLargeBatch
(
Connection
conn
)
throws
Exception
{
Statement
stat
=
conn
.
createStatement
();
stat
.
execute
(
"CREATE TABLE TEST (ID BIGINT PRIMARY KEY AUTO_INCREMENT,"
+
"UID UUID NOT NULL DEFAULT RANDOM_UUID(), VALUE INT NOT NULL)"
);
JdbcPreparedStatement
prep
=
(
JdbcPreparedStatement
)
conn
.
prepareStatement
(
"INSERT INTO TEST(VALUE) VALUES (10)"
,
new
String
[
0
]);
prep
.
addBatch
();
prep
.
addBatch
();
prep
.
executeLargeBatch
();
ResultSet
rs
=
prep
.
getGeneratedKeys
();
assertFalse
(
rs
.
next
());
rs
.
close
();
prep
=
(
JdbcPreparedStatement
)
conn
.
prepareStatement
(
"INSERT INTO TEST(VALUE) VALUES (20)"
,
new
String
[]
{
"ID"
,
"UID"
});
prep
.
addBatch
();
prep
.
addBatch
();
prep
.
executeLargeBatch
();
rs
=
prep
.
getGeneratedKeys
();
assertEquals
(
2
,
rs
.
getMetaData
().
getColumnCount
());
assertEquals
(
"ID"
,
rs
.
getMetaData
().
getColumnName
(
1
));
assertEquals
(
"UID"
,
rs
.
getMetaData
().
getColumnName
(
2
));
assertTrue
(
rs
.
next
());
assertEquals
(
3L
,
rs
.
getLong
(
1
));
assertEquals
(
UUID
.
class
,
rs
.
getObject
(
2
).
getClass
());
assertTrue
(
rs
.
next
());
assertEquals
(
4L
,
rs
.
getLong
(
1
));
assertEquals
(
UUID
.
class
,
rs
.
getObject
(
2
).
getClass
());
assertFalse
(
rs
.
next
());
rs
.
close
();
prep
=
(
JdbcPreparedStatement
)
conn
.
prepareStatement
(
"INSERT INTO TEST(VALUE) VALUES (30)"
,
new
String
[]
{
"UID"
,
"ID"
});
prep
.
addBatch
();
prep
.
addBatch
();
prep
.
executeLargeBatch
();
rs
=
prep
.
getGeneratedKeys
();
assertEquals
(
2
,
rs
.
getMetaData
().
getColumnCount
());
assertEquals
(
"UID"
,
rs
.
getMetaData
().
getColumnName
(
1
));
assertEquals
(
"ID"
,
rs
.
getMetaData
().
getColumnName
(
2
));
assertTrue
(
rs
.
next
());
assertEquals
(
UUID
.
class
,
rs
.
getObject
(
1
).
getClass
());
assertEquals
(
5L
,
rs
.
getLong
(
2
));
assertTrue
(
rs
.
next
());
assertEquals
(
UUID
.
class
,
rs
.
getObject
(
1
).
getClass
());
assertEquals
(
6L
,
rs
.
getLong
(
2
));
assertFalse
(
rs
.
next
());
rs
.
close
();
prep
=
(
JdbcPreparedStatement
)
conn
.
prepareStatement
(
"INSERT INTO TEST(VALUE) VALUES (40)"
,
new
String
[]
{
"UID"
});
prep
.
addBatch
();
prep
.
addBatch
();
prep
.
executeLargeBatch
();
rs
=
prep
.
getGeneratedKeys
();
assertEquals
(
1
,
rs
.
getMetaData
().
getColumnCount
());
assertEquals
(
"UID"
,
rs
.
getMetaData
().
getColumnName
(
1
));
assertTrue
(
rs
.
next
());
assertEquals
(
UUID
.
class
,
rs
.
getObject
(
1
).
getClass
());
assertTrue
(
rs
.
next
());
assertEquals
(
UUID
.
class
,
rs
.
getObject
(
1
).
getClass
());
assertFalse
(
rs
.
next
());
rs
.
close
();
stat
.
execute
(
"DROP TABLE TEST"
);
}
/**
* Test method for
* {@link Connection#prepareStatement(String, String[])}.{@link PreparedStatement#executeLargeUpdate()}.
*
* @param conn
* connection
* @throws Exception
* on exception
*/
private
void
testPrepareStatement_StringArray_ExecuteLargeUpdate
(
Connection
conn
)
throws
Exception
{
Statement
stat
=
conn
.
createStatement
();
stat
.
execute
(
"CREATE TABLE TEST (ID BIGINT PRIMARY KEY AUTO_INCREMENT,"
+
"UID UUID NOT NULL DEFAULT RANDOM_UUID(), VALUE INT NOT NULL)"
);
JdbcPreparedStatement
prep
=
(
JdbcPreparedStatement
)
conn
.
prepareStatement
(
"INSERT INTO TEST(VALUE) VALUES (10)"
,
new
String
[
0
]);
prep
.
executeLargeUpdate
();
ResultSet
rs
=
prep
.
getGeneratedKeys
();
assertFalse
(
rs
.
next
());
rs
.
close
();
prep
=
(
JdbcPreparedStatement
)
conn
.
prepareStatement
(
"INSERT INTO TEST(VALUE) VALUES (20)"
,
new
String
[]
{
"ID"
,
"UID"
});
prep
.
executeLargeUpdate
();
rs
=
prep
.
getGeneratedKeys
();
assertEquals
(
2
,
rs
.
getMetaData
().
getColumnCount
());
assertEquals
(
"ID"
,
rs
.
getMetaData
().
getColumnName
(
1
));
assertEquals
(
"UID"
,
rs
.
getMetaData
().
getColumnName
(
2
));
assertTrue
(
rs
.
next
());
assertEquals
(
2L
,
rs
.
getLong
(
1
));
assertEquals
(
UUID
.
class
,
rs
.
getObject
(
2
).
getClass
());
assertFalse
(
rs
.
next
());
rs
.
close
();
prep
=
(
JdbcPreparedStatement
)
conn
.
prepareStatement
(
"INSERT INTO TEST(VALUE) VALUES (30)"
,
new
String
[]
{
"UID"
,
"ID"
});
prep
.
executeLargeUpdate
();
rs
=
prep
.
getGeneratedKeys
();
assertEquals
(
2
,
rs
.
getMetaData
().
getColumnCount
());
assertEquals
(
"UID"
,
rs
.
getMetaData
().
getColumnName
(
1
));
assertEquals
(
"ID"
,
rs
.
getMetaData
().
getColumnName
(
2
));
assertTrue
(
rs
.
next
());
assertEquals
(
UUID
.
class
,
rs
.
getObject
(
1
).
getClass
());
assertEquals
(
3L
,
rs
.
getLong
(
2
));
assertFalse
(
rs
.
next
());
rs
.
close
();
prep
=
(
JdbcPreparedStatement
)
conn
.
prepareStatement
(
"INSERT INTO TEST(VALUE) VALUES (40)"
,
new
String
[]
{
"UID"
});
prep
.
executeLargeUpdate
();
rs
=
prep
.
getGeneratedKeys
();
assertEquals
(
1
,
rs
.
getMetaData
().
getColumnCount
());
assertEquals
(
"UID"
,
rs
.
getMetaData
().
getColumnName
(
1
));
assertTrue
(
rs
.
next
());
assertEquals
(
UUID
.
class
,
rs
.
getObject
(
1
).
getClass
());
assertFalse
(
rs
.
next
());
rs
.
close
();
stat
.
execute
(
"DROP TABLE TEST"
);
}
/**
* Test method for
* {@link Connection#prepareStatement(String, String[])}.{@link PreparedStatement#executeUpdate()}.
*
* @param conn
* connection
* @throws Exception
* on exception
*/
private
void
testPrepareStatement_StringArray_ExecuteUpdate
(
Connection
conn
)
throws
Exception
{
Statement
stat
=
conn
.
createStatement
();
stat
.
execute
(
"CREATE TABLE TEST (ID BIGINT PRIMARY KEY AUTO_INCREMENT,"
+
"UID UUID NOT NULL DEFAULT RANDOM_UUID(), VALUE INT NOT NULL)"
);
PreparedStatement
prep
=
conn
.
prepareStatement
(
"INSERT INTO TEST(VALUE) VALUES (10)"
,
new
String
[
0
]);
prep
.
executeUpdate
();
ResultSet
rs
=
prep
.
getGeneratedKeys
();
assertFalse
(
rs
.
next
());
rs
.
close
();
prep
=
conn
.
prepareStatement
(
"INSERT INTO TEST(VALUE) VALUES (20)"
,
new
String
[]
{
"ID"
,
"UID"
});
prep
.
executeUpdate
();
rs
=
prep
.
getGeneratedKeys
();
assertEquals
(
2
,
rs
.
getMetaData
().
getColumnCount
());
assertEquals
(
"ID"
,
rs
.
getMetaData
().
getColumnName
(
1
));
assertEquals
(
"UID"
,
rs
.
getMetaData
().
getColumnName
(
2
));
assertTrue
(
rs
.
next
());
assertEquals
(
2L
,
rs
.
getLong
(
1
));
assertEquals
(
UUID
.
class
,
rs
.
getObject
(
2
).
getClass
());
assertFalse
(
rs
.
next
());
rs
.
close
();
prep
=
conn
.
prepareStatement
(
"INSERT INTO TEST(VALUE) VALUES (30)"
,
new
String
[]
{
"UID"
,
"ID"
});
prep
.
executeUpdate
();
rs
=
prep
.
getGeneratedKeys
();
assertEquals
(
2
,
rs
.
getMetaData
().
getColumnCount
());
assertEquals
(
"UID"
,
rs
.
getMetaData
().
getColumnName
(
1
));
assertEquals
(
"ID"
,
rs
.
getMetaData
().
getColumnName
(
2
));
assertTrue
(
rs
.
next
());
assertEquals
(
UUID
.
class
,
rs
.
getObject
(
1
).
getClass
());
assertEquals
(
3L
,
rs
.
getLong
(
2
));
assertFalse
(
rs
.
next
());
rs
.
close
();
prep
=
conn
.
prepareStatement
(
"INSERT INTO TEST(VALUE) VALUES (40)"
,
new
String
[]
{
"UID"
});
prep
.
executeUpdate
();
rs
=
prep
.
getGeneratedKeys
();
assertEquals
(
1
,
rs
.
getMetaData
().
getColumnCount
());
assertEquals
(
"UID"
,
rs
.
getMetaData
().
getColumnName
(
1
));
assertTrue
(
rs
.
next
());
assertEquals
(
UUID
.
class
,
rs
.
getObject
(
1
).
getClass
());
assertFalse
(
rs
.
next
());
rs
.
close
();
stat
.
execute
(
"DROP TABLE TEST"
);
}
/**
* Test method for {@link Statement#execute(String)}.
*
* @param conn
* connection
* @throws Exception
* on exception
*/
private
void
testStatementExecute
(
Connection
conn
)
throws
Exception
{
Statement
stat
=
conn
.
createStatement
();
stat
.
execute
(
"CREATE TABLE TEST (ID BIGINT PRIMARY KEY AUTO_INCREMENT,"
+
"UID UUID NOT NULL DEFAULT RANDOM_UUID(), VALUE INT NOT NULL)"
);
stat
.
execute
(
"INSERT INTO TEST(VALUE) VALUES (10)"
);
ResultSet
rs
=
stat
.
getGeneratedKeys
();
assertFalse
(
rs
.
next
());
rs
.
close
();
stat
.
execute
(
"DROP TABLE TEST"
);
}
/**
* Test method for {@link Statement#execute(String, int)}.
*
* @param conn
* connection
* @throws Exception
* on exception
*/
private
void
testStatementExecute_int
(
Connection
conn
)
throws
Exception
{
Statement
stat
=
conn
.
createStatement
();
stat
.
execute
(
"CREATE TABLE TEST (ID BIGINT PRIMARY KEY AUTO_INCREMENT,"
+
"UID UUID NOT NULL DEFAULT RANDOM_UUID(), VALUE INT NOT NULL)"
);
stat
.
execute
(
"INSERT INTO TEST(VALUE) VALUES (10)"
,
Statement
.
NO_GENERATED_KEYS
);
ResultSet
rs
=
stat
.
getGeneratedKeys
();
assertFalse
(
rs
.
next
());
rs
.
close
();
stat
.
execute
(
"INSERT INTO TEST(VALUE) VALUES (20)"
,
Statement
.
RETURN_GENERATED_KEYS
);
rs
=
stat
.
getGeneratedKeys
();
assertEquals
(
2
,
rs
.
getMetaData
().
getColumnCount
());
assertEquals
(
"ID"
,
rs
.
getMetaData
().
getColumnName
(
1
));
assertEquals
(
"UID"
,
rs
.
getMetaData
().
getColumnName
(
2
));
assertTrue
(
rs
.
next
());
assertEquals
(
2L
,
rs
.
getLong
(
1
));
assertEquals
(
UUID
.
class
,
rs
.
getObject
(
2
).
getClass
());
assertFalse
(
rs
.
next
());
rs
.
close
();
stat
.
execute
(
"DROP TABLE TEST"
);
}
/**
* Test method for {@link Statement#execute(String, int[])}.
*
* @param conn
* connection
* @throws Exception
* on exception
*/
private
void
testStatementExecute_intArray
(
Connection
conn
)
throws
Exception
{
Statement
stat
=
conn
.
createStatement
();
stat
.
execute
(
"CREATE TABLE TEST (ID BIGINT PRIMARY KEY AUTO_INCREMENT,"
+
"UID UUID NOT NULL DEFAULT RANDOM_UUID(), VALUE INT NOT NULL)"
);
stat
.
execute
(
"INSERT INTO TEST(VALUE) VALUES (10)"
,
new
int
[
0
]);
ResultSet
rs
=
stat
.
getGeneratedKeys
();
assertFalse
(
rs
.
next
());
rs
.
close
();
stat
.
execute
(
"INSERT INTO TEST(VALUE) VALUES (20)"
,
new
int
[]
{
1
,
2
});
rs
=
stat
.
getGeneratedKeys
();
assertEquals
(
2
,
rs
.
getMetaData
().
getColumnCount
());
assertEquals
(
"ID"
,
rs
.
getMetaData
().
getColumnName
(
1
));
assertEquals
(
"UID"
,
rs
.
getMetaData
().
getColumnName
(
2
));
assertTrue
(
rs
.
next
());
assertEquals
(
2L
,
rs
.
getLong
(
1
));
assertEquals
(
UUID
.
class
,
rs
.
getObject
(
2
).
getClass
());
assertFalse
(
rs
.
next
());
rs
.
close
();
stat
.
execute
(
"INSERT INTO TEST(VALUE) VALUES (30)"
,
new
int
[]
{
2
,
1
});
rs
=
stat
.
getGeneratedKeys
();
assertEquals
(
2
,
rs
.
getMetaData
().
getColumnCount
());
assertEquals
(
"UID"
,
rs
.
getMetaData
().
getColumnName
(
1
));
assertEquals
(
"ID"
,
rs
.
getMetaData
().
getColumnName
(
2
));
assertTrue
(
rs
.
next
());
assertEquals
(
UUID
.
class
,
rs
.
getObject
(
1
).
getClass
());
assertEquals
(
3L
,
rs
.
getLong
(
2
));
assertFalse
(
rs
.
next
());
rs
.
close
();
stat
.
execute
(
"INSERT INTO TEST(VALUE) VALUES (40)"
,
new
int
[]
{
2
});
rs
=
stat
.
getGeneratedKeys
();
assertEquals
(
1
,
rs
.
getMetaData
().
getColumnCount
());
assertEquals
(
"UID"
,
rs
.
getMetaData
().
getColumnName
(
1
));
assertTrue
(
rs
.
next
());
assertEquals
(
UUID
.
class
,
rs
.
getObject
(
1
).
getClass
());
assertFalse
(
rs
.
next
());
rs
.
close
();
stat
.
execute
(
"DROP TABLE TEST"
);
}
/**
* Test method for {@link Statement#executeUpdate(String, String[])}.
*
* @param conn
* connection
* @throws Exception
* on exception
*/
private
void
testStatementExecute_StringArray
(
Connection
conn
)
throws
Exception
{
Statement
stat
=
conn
.
createStatement
();
stat
.
execute
(
"CREATE TABLE TEST (ID BIGINT PRIMARY KEY AUTO_INCREMENT,"
+
"UID UUID NOT NULL DEFAULT RANDOM_UUID(), VALUE INT NOT NULL)"
);
stat
.
execute
(
"INSERT INTO TEST(VALUE) VALUES (10)"
,
new
String
[
0
]);
ResultSet
rs
=
stat
.
getGeneratedKeys
();
assertFalse
(
rs
.
next
());
rs
.
close
();
stat
.
execute
(
"INSERT INTO TEST(VALUE) VALUES (20)"
,
new
String
[]
{
"ID"
,
"UID"
});
rs
=
stat
.
getGeneratedKeys
();
assertEquals
(
2
,
rs
.
getMetaData
().
getColumnCount
());
assertEquals
(
"ID"
,
rs
.
getMetaData
().
getColumnName
(
1
));
assertEquals
(
"UID"
,
rs
.
getMetaData
().
getColumnName
(
2
));
assertTrue
(
rs
.
next
());
assertEquals
(
2L
,
rs
.
getLong
(
1
));
assertEquals
(
UUID
.
class
,
rs
.
getObject
(
2
).
getClass
());
assertFalse
(
rs
.
next
());
rs
.
close
();
stat
.
execute
(
"INSERT INTO TEST(VALUE) VALUES (30)"
,
new
String
[]
{
"UID"
,
"ID"
});
rs
=
stat
.
getGeneratedKeys
();
assertEquals
(
2
,
rs
.
getMetaData
().
getColumnCount
());
assertEquals
(
"UID"
,
rs
.
getMetaData
().
getColumnName
(
1
));
assertEquals
(
"ID"
,
rs
.
getMetaData
().
getColumnName
(
2
));
assertTrue
(
rs
.
next
());
assertEquals
(
UUID
.
class
,
rs
.
getObject
(
1
).
getClass
());
assertEquals
(
3L
,
rs
.
getLong
(
2
));
assertFalse
(
rs
.
next
());
rs
.
close
();
stat
.
execute
(
"INSERT INTO TEST(VALUE) VALUES (40)"
,
new
String
[]
{
"UID"
});
rs
=
stat
.
getGeneratedKeys
();
assertEquals
(
1
,
rs
.
getMetaData
().
getColumnCount
());
assertEquals
(
"UID"
,
rs
.
getMetaData
().
getColumnName
(
1
));
assertTrue
(
rs
.
next
());
assertEquals
(
UUID
.
class
,
rs
.
getObject
(
1
).
getClass
());
assertFalse
(
rs
.
next
());
rs
.
close
();
stat
.
execute
(
"DROP TABLE TEST"
);
}
/**
* Test method for {@link Statement#executeLargeUpdate(String)}.
*
* @param conn
* connection
* @throws Exception
* on exception
*/
private
void
testStatementExecuteLargeUpdate
(
Connection
conn
)
throws
Exception
{
JdbcStatement
stat
=
(
JdbcStatement
)
conn
.
createStatement
();
stat
.
execute
(
"CREATE TABLE TEST (ID BIGINT PRIMARY KEY AUTO_INCREMENT,"
+
"UID UUID NOT NULL DEFAULT RANDOM_UUID(), VALUE INT NOT NULL)"
);
stat
.
executeLargeUpdate
(
"INSERT INTO TEST(VALUE) VALUES (10)"
);
ResultSet
rs
=
stat
.
getGeneratedKeys
();
assertFalse
(
rs
.
next
());
rs
.
close
();
stat
.
execute
(
"DROP TABLE TEST"
);
}
/**
* Test method for {@link Statement#executeLargeUpdate(String, int)}.
*
* @param conn
* connection
* @throws Exception
* on exception
*/
private
void
testStatementExecuteLargeUpdate_int
(
Connection
conn
)
throws
Exception
{
JdbcStatement
stat
=
(
JdbcStatement
)
conn
.
createStatement
();
stat
.
execute
(
"CREATE TABLE TEST (ID BIGINT PRIMARY KEY AUTO_INCREMENT,"
+
"UID UUID NOT NULL DEFAULT RANDOM_UUID(), VALUE INT NOT NULL)"
);
stat
.
executeLargeUpdate
(
"INSERT INTO TEST(VALUE) VALUES (10)"
,
Statement
.
NO_GENERATED_KEYS
);
ResultSet
rs
=
stat
.
getGeneratedKeys
();
assertFalse
(
rs
.
next
());
rs
.
close
();
stat
.
executeLargeUpdate
(
"INSERT INTO TEST(VALUE) VALUES (20)"
,
Statement
.
RETURN_GENERATED_KEYS
);
rs
=
stat
.
getGeneratedKeys
();
assertEquals
(
2
,
rs
.
getMetaData
().
getColumnCount
());
assertEquals
(
"ID"
,
rs
.
getMetaData
().
getColumnName
(
1
));
assertEquals
(
"UID"
,
rs
.
getMetaData
().
getColumnName
(
2
));
assertTrue
(
rs
.
next
());
assertEquals
(
2L
,
rs
.
getLong
(
1
));
assertEquals
(
UUID
.
class
,
rs
.
getObject
(
2
).
getClass
());
assertFalse
(
rs
.
next
());
rs
.
close
();
stat
.
execute
(
"DROP TABLE TEST"
);
}
/**
* Test method for {@link Statement#executeLargeUpdate(String, int[])}.
*
* @param conn
* connection
* @throws Exception
* on exception
*/
private
void
testStatementExecuteLargeUpdate_intArray
(
Connection
conn
)
throws
Exception
{
JdbcStatement
stat
=
(
JdbcStatement
)
conn
.
createStatement
();
stat
.
execute
(
"CREATE TABLE TEST (ID BIGINT PRIMARY KEY AUTO_INCREMENT,"
+
"UID UUID NOT NULL DEFAULT RANDOM_UUID(), VALUE INT NOT NULL)"
);
stat
.
executeLargeUpdate
(
"INSERT INTO TEST(VALUE) VALUES (10)"
,
new
int
[
0
]);
ResultSet
rs
=
stat
.
getGeneratedKeys
();
assertFalse
(
rs
.
next
());
rs
.
close
();
stat
.
executeLargeUpdate
(
"INSERT INTO TEST(VALUE) VALUES (20)"
,
new
int
[]
{
1
,
2
});
rs
=
stat
.
getGeneratedKeys
();
assertEquals
(
2
,
rs
.
getMetaData
().
getColumnCount
());
assertEquals
(
"ID"
,
rs
.
getMetaData
().
getColumnName
(
1
));
assertEquals
(
"UID"
,
rs
.
getMetaData
().
getColumnName
(
2
));
assertTrue
(
rs
.
next
());
assertEquals
(
2L
,
rs
.
getLong
(
1
));
assertEquals
(
UUID
.
class
,
rs
.
getObject
(
2
).
getClass
());
assertFalse
(
rs
.
next
());
rs
.
close
();
stat
.
executeLargeUpdate
(
"INSERT INTO TEST(VALUE) VALUES (30)"
,
new
int
[]
{
2
,
1
});
rs
=
stat
.
getGeneratedKeys
();
assertEquals
(
2
,
rs
.
getMetaData
().
getColumnCount
());
assertEquals
(
"UID"
,
rs
.
getMetaData
().
getColumnName
(
1
));
assertEquals
(
"ID"
,
rs
.
getMetaData
().
getColumnName
(
2
));
assertTrue
(
rs
.
next
());
assertEquals
(
UUID
.
class
,
rs
.
getObject
(
1
).
getClass
());
assertEquals
(
3L
,
rs
.
getLong
(
2
));
assertFalse
(
rs
.
next
());
rs
.
close
();
stat
.
executeLargeUpdate
(
"INSERT INTO TEST(VALUE) VALUES (40)"
,
new
int
[]
{
2
});
rs
=
stat
.
getGeneratedKeys
();
assertEquals
(
1
,
rs
.
getMetaData
().
getColumnCount
());
assertEquals
(
"UID"
,
rs
.
getMetaData
().
getColumnName
(
1
));
assertTrue
(
rs
.
next
());
assertEquals
(
UUID
.
class
,
rs
.
getObject
(
1
).
getClass
());
assertFalse
(
rs
.
next
());
rs
.
close
();
stat
.
execute
(
"DROP TABLE TEST"
);
}
/**
* Test method for {@link Statement#executeLargeUpdate(String, String[])}.
*
* @param conn
* connection
* @throws Exception
* on exception
*/
private
void
testStatementExecuteLargeUpdate_StringArray
(
Connection
conn
)
throws
Exception
{
JdbcStatement
stat
=
(
JdbcStatement
)
conn
.
createStatement
();
stat
.
execute
(
"CREATE TABLE TEST (ID BIGINT PRIMARY KEY AUTO_INCREMENT,"
+
"UID UUID NOT NULL DEFAULT RANDOM_UUID(), VALUE INT NOT NULL)"
);
stat
.
executeLargeUpdate
(
"INSERT INTO TEST(VALUE) VALUES (10)"
,
new
String
[
0
]);
ResultSet
rs
=
stat
.
getGeneratedKeys
();
assertFalse
(
rs
.
next
());
rs
.
close
();
stat
.
executeLargeUpdate
(
"INSERT INTO TEST(VALUE) VALUES (20)"
,
new
String
[]
{
"ID"
,
"UID"
});
rs
=
stat
.
getGeneratedKeys
();
assertEquals
(
2
,
rs
.
getMetaData
().
getColumnCount
());
assertEquals
(
"ID"
,
rs
.
getMetaData
().
getColumnName
(
1
));
assertEquals
(
"UID"
,
rs
.
getMetaData
().
getColumnName
(
2
));
assertTrue
(
rs
.
next
());
assertEquals
(
2L
,
rs
.
getLong
(
1
));
assertEquals
(
UUID
.
class
,
rs
.
getObject
(
2
).
getClass
());
assertFalse
(
rs
.
next
());
rs
.
close
();
stat
.
executeLargeUpdate
(
"INSERT INTO TEST(VALUE) VALUES (30)"
,
new
String
[]
{
"UID"
,
"ID"
});
rs
=
stat
.
getGeneratedKeys
();
assertEquals
(
2
,
rs
.
getMetaData
().
getColumnCount
());
assertEquals
(
"UID"
,
rs
.
getMetaData
().
getColumnName
(
1
));
assertEquals
(
"ID"
,
rs
.
getMetaData
().
getColumnName
(
2
));
assertTrue
(
rs
.
next
());
assertEquals
(
UUID
.
class
,
rs
.
getObject
(
1
).
getClass
());
assertEquals
(
3L
,
rs
.
getLong
(
2
));
assertFalse
(
rs
.
next
());
rs
.
close
();
stat
.
executeLargeUpdate
(
"INSERT INTO TEST(VALUE) VALUES (40)"
,
new
String
[]
{
"UID"
});
rs
=
stat
.
getGeneratedKeys
();
assertEquals
(
1
,
rs
.
getMetaData
().
getColumnCount
());
assertEquals
(
"UID"
,
rs
.
getMetaData
().
getColumnName
(
1
));
assertTrue
(
rs
.
next
());
assertEquals
(
UUID
.
class
,
rs
.
getObject
(
1
).
getClass
());
assertFalse
(
rs
.
next
());
rs
.
close
();
stat
.
execute
(
"DROP TABLE TEST"
);
}
/**
* Test method for {@link Statement#executeUpdate(String)}.
*
* @param conn
* connection
* @throws Exception
* on exception
*/
private
void
testStatementExecuteUpdate
(
Connection
conn
)
throws
Exception
{
Statement
stat
=
conn
.
createStatement
();
stat
.
execute
(
"CREATE TABLE TEST (ID BIGINT PRIMARY KEY AUTO_INCREMENT,"
+
"UID UUID NOT NULL DEFAULT RANDOM_UUID(), VALUE INT NOT NULL)"
);
stat
.
executeUpdate
(
"INSERT INTO TEST(VALUE) VALUES (10)"
);
ResultSet
rs
=
stat
.
getGeneratedKeys
();
assertFalse
(
rs
.
next
());
rs
.
close
();
stat
.
execute
(
"DROP TABLE TEST"
);
}
/**
* Test method for {@link Statement#executeUpdate(String, int)}.
*
* @param conn
* connection
* @throws Exception
* on exception
*/
private
void
testStatementExecuteUpdate_int
(
Connection
conn
)
throws
Exception
{
Statement
stat
=
conn
.
createStatement
();
stat
.
execute
(
"CREATE TABLE TEST (ID BIGINT PRIMARY KEY AUTO_INCREMENT,"
+
"UID UUID NOT NULL DEFAULT RANDOM_UUID(), VALUE INT NOT NULL)"
);
stat
.
executeUpdate
(
"INSERT INTO TEST(VALUE) VALUES (10)"
,
Statement
.
NO_GENERATED_KEYS
);
ResultSet
rs
=
stat
.
getGeneratedKeys
();
assertFalse
(
rs
.
next
());
rs
.
close
();
stat
.
executeUpdate
(
"INSERT INTO TEST(VALUE) VALUES (20)"
,
Statement
.
RETURN_GENERATED_KEYS
);
rs
=
stat
.
getGeneratedKeys
();
assertEquals
(
2
,
rs
.
getMetaData
().
getColumnCount
());
assertEquals
(
"ID"
,
rs
.
getMetaData
().
getColumnName
(
1
));
assertEquals
(
"UID"
,
rs
.
getMetaData
().
getColumnName
(
2
));
assertTrue
(
rs
.
next
());
assertEquals
(
2L
,
rs
.
getLong
(
1
));
assertEquals
(
UUID
.
class
,
rs
.
getObject
(
2
).
getClass
());
assertFalse
(
rs
.
next
());
rs
.
close
();
stat
.
execute
(
"DROP TABLE TEST"
);
}
/**
* Test method for {@link Statement#executeUpdate(String, int[])}.
*
* @param conn
* connection
* @throws Exception
* on exception
*/
private
void
testStatementExecuteUpdate_intArray
(
Connection
conn
)
throws
Exception
{
Statement
stat
=
conn
.
createStatement
();
stat
.
execute
(
"CREATE TABLE TEST (ID BIGINT PRIMARY KEY AUTO_INCREMENT,"
+
"UID UUID NOT NULL DEFAULT RANDOM_UUID(), VALUE INT NOT NULL)"
);
stat
.
executeUpdate
(
"INSERT INTO TEST(VALUE) VALUES (10)"
,
new
int
[
0
]);
ResultSet
rs
=
stat
.
getGeneratedKeys
();
assertFalse
(
rs
.
next
());
rs
.
close
();
stat
.
executeUpdate
(
"INSERT INTO TEST(VALUE) VALUES (20)"
,
new
int
[]
{
1
,
2
});
rs
=
stat
.
getGeneratedKeys
();
assertEquals
(
2
,
rs
.
getMetaData
().
getColumnCount
());
assertEquals
(
"ID"
,
rs
.
getMetaData
().
getColumnName
(
1
));
assertEquals
(
"UID"
,
rs
.
getMetaData
().
getColumnName
(
2
));
assertTrue
(
rs
.
next
());
assertEquals
(
2L
,
rs
.
getLong
(
1
));
assertEquals
(
UUID
.
class
,
rs
.
getObject
(
2
).
getClass
());
assertFalse
(
rs
.
next
());
rs
.
close
();
stat
.
executeUpdate
(
"INSERT INTO TEST(VALUE) VALUES (30)"
,
new
int
[]
{
2
,
1
});
rs
=
stat
.
getGeneratedKeys
();
assertEquals
(
2
,
rs
.
getMetaData
().
getColumnCount
());
assertEquals
(
"UID"
,
rs
.
getMetaData
().
getColumnName
(
1
));
assertEquals
(
"ID"
,
rs
.
getMetaData
().
getColumnName
(
2
));
assertTrue
(
rs
.
next
());
assertEquals
(
UUID
.
class
,
rs
.
getObject
(
1
).
getClass
());
assertEquals
(
3L
,
rs
.
getLong
(
2
));
assertFalse
(
rs
.
next
());
rs
.
close
();
stat
.
executeUpdate
(
"INSERT INTO TEST(VALUE) VALUES (40)"
,
new
int
[]
{
2
});
rs
=
stat
.
getGeneratedKeys
();
assertEquals
(
1
,
rs
.
getMetaData
().
getColumnCount
());
assertEquals
(
"UID"
,
rs
.
getMetaData
().
getColumnName
(
1
));
assertTrue
(
rs
.
next
());
assertEquals
(
UUID
.
class
,
rs
.
getObject
(
1
).
getClass
());
assertFalse
(
rs
.
next
());
rs
.
close
();
stat
.
execute
(
"DROP TABLE TEST"
);
}
/**
* Test method for {@link Statement#executeUpdate(String, String[])}.
*
* @param conn
* connection
* @throws Exception
* on exception
*/
private
void
testStatementExecuteUpdate_StringArray
(
Connection
conn
)
throws
Exception
{
Statement
stat
=
conn
.
createStatement
();
stat
.
execute
(
"CREATE TABLE TEST (ID BIGINT PRIMARY KEY AUTO_INCREMENT,"
+
"UID UUID NOT NULL DEFAULT RANDOM_UUID(), VALUE INT NOT NULL)"
);
stat
.
executeUpdate
(
"INSERT INTO TEST(VALUE) VALUES (10)"
,
new
String
[
0
]);
ResultSet
rs
=
stat
.
getGeneratedKeys
();
assertFalse
(
rs
.
next
());
rs
.
close
();
stat
.
executeUpdate
(
"INSERT INTO TEST(VALUE) VALUES (20)"
,
new
String
[]
{
"ID"
,
"UID"
});
rs
=
stat
.
getGeneratedKeys
();
assertEquals
(
2
,
rs
.
getMetaData
().
getColumnCount
());
assertEquals
(
"ID"
,
rs
.
getMetaData
().
getColumnName
(
1
));
assertEquals
(
"UID"
,
rs
.
getMetaData
().
getColumnName
(
2
));
assertTrue
(
rs
.
next
());
assertEquals
(
2L
,
rs
.
getLong
(
1
));
assertEquals
(
UUID
.
class
,
rs
.
getObject
(
2
).
getClass
());
assertFalse
(
rs
.
next
());
rs
.
close
();
stat
.
executeUpdate
(
"INSERT INTO TEST(VALUE) VALUES (30)"
,
new
String
[]
{
"UID"
,
"ID"
});
rs
=
stat
.
getGeneratedKeys
();
assertEquals
(
2
,
rs
.
getMetaData
().
getColumnCount
());
assertEquals
(
"UID"
,
rs
.
getMetaData
().
getColumnName
(
1
));
assertEquals
(
"ID"
,
rs
.
getMetaData
().
getColumnName
(
2
));
assertTrue
(
rs
.
next
());
assertEquals
(
UUID
.
class
,
rs
.
getObject
(
1
).
getClass
());
assertEquals
(
3L
,
rs
.
getLong
(
2
));
assertFalse
(
rs
.
next
());
rs
.
close
();
stat
.
executeUpdate
(
"INSERT INTO TEST(VALUE) VALUES (40)"
,
new
String
[]
{
"UID"
});
rs
=
stat
.
getGeneratedKeys
();
assertEquals
(
1
,
rs
.
getMetaData
().
getColumnCount
());
assertEquals
(
"UID"
,
rs
.
getMetaData
().
getColumnName
(
1
));
assertTrue
(
rs
.
next
());
assertEquals
(
UUID
.
class
,
rs
.
getObject
(
1
).
getClass
());
assertFalse
(
rs
.
next
());
rs
.
close
();
stat
.
execute
(
"DROP TABLE TEST"
);
}
/**
* Test for keys generated by trigger.
*
* @param conn
* connection
* @throws Exception
* on exception
*/
private
void
testTrigger
(
Connection
conn
)
throws
Exception
{
Statement
stat
=
conn
.
createStatement
();
stat
.
execute
(
"CREATE TABLE TEST(ID UUID, VALUE INT)"
);
stat
.
execute
(
"CREATE TRIGGER TEST_INSERT BEFORE INSERT ON TEST FOR EACH ROW CALL \""
+
TestGetGeneratedKeysTrigger
.
class
.
getName
()
+
'"'
);
stat
.
executeUpdate
(
"INSERT INTO TEST(VALUE) VALUES (10), (20)"
,
Statement
.
RETURN_GENERATED_KEYS
);
ResultSet
rs
=
stat
.
getGeneratedKeys
();
rs
.
next
();
UUID
u1
=
(
UUID
)
rs
.
getObject
(
1
);
rs
.
next
();
UUID
u2
=
(
UUID
)
rs
.
getObject
(
1
);
assertFalse
(
rs
.
next
());
rs
=
stat
.
executeQuery
(
"SELECT ID FROM TEST ORDER BY VALUE"
);
rs
.
next
();
assertEquals
(
u1
,
rs
.
getObject
(
1
));
rs
.
next
();
assertEquals
(
u2
,
rs
.
getObject
(
1
));
stat
.
execute
(
"DROP TRIGGER TEST_INSERT"
);
stat
.
execute
(
"DROP TABLE TEST"
);
}
}
h2/src/test/org/h2/test/jdbc/TestPreparedStatement.java
浏览文件 @
47ed036f
...
...
@@ -27,6 +27,7 @@ import java.sql.Types;
import
java.util.Calendar
;
import
java.util.GregorianCalendar
;
import
java.util.UUID
;
import
org.h2.api.ErrorCode
;
import
org.h2.api.Trigger
;
import
org.h2.engine.SysProperties
;
...
...
@@ -83,15 +84,12 @@ public class TestPreparedStatement extends TestBase {
testOffsetDateTime8
(
conn
);
testInstant8
(
conn
);
testArray
(
conn
);
testUUIDGeneratedKeys
(
conn
);
testSetObject
(
conn
);
testPreparedSubquery
(
conn
);
testLikeIndex
(
conn
);
testCasewhen
(
conn
);
testSubquery
(
conn
);
testObject
(
conn
);
testIdentity
(
conn
);
testBatchGeneratedKeys
(
conn
);
testDataTypes
(
conn
);
testGetMoreResults
(
conn
);
testBlob
(
conn
);
...
...
@@ -521,21 +519,6 @@ public class TestPreparedStatement extends TestBase {
stat
.
execute
(
"drop table test_uuid"
);
}
private
void
testUUIDGeneratedKeys
(
Connection
conn
)
throws
SQLException
{
Statement
stat
=
conn
.
createStatement
();
stat
.
execute
(
"CREATE TABLE TEST_UUID(id UUID DEFAULT "
+
"random_UUID() PRIMARY KEY)"
);
stat
.
execute
(
"INSERT INTO TEST_UUID() VALUES()"
);
ResultSet
rs
=
stat
.
getGeneratedKeys
();
rs
.
next
();
byte
[]
data
=
rs
.
getBytes
(
1
);
assertEquals
(
16
,
data
.
length
);
stat
.
execute
(
"INSERT INTO TEST_UUID VALUES(random_UUID())"
);
rs
=
stat
.
getGeneratedKeys
();
assertFalse
(
rs
.
next
());
stat
.
execute
(
"DROP TABLE TEST_UUID"
);
}
/**
* A trigger that creates a sequence value.
*/
...
...
@@ -572,12 +555,17 @@ public class TestPreparedStatement extends TestBase {
stat
.
execute
(
"create sequence seq start with 1000"
);
stat
.
execute
(
"create trigger test_ins after insert on test call \""
+
SequenceTrigger
.
class
.
getName
()
+
"\""
);
stat
.
execute
(
"insert into test values(null)"
);
stat
.
execute
(
"insert into test values(null)"
,
Statement
.
RETURN_GENERATED_KEYS
);
ResultSet
rs
=
stat
.
getGeneratedKeys
();
rs
.
next
();
// Generated key
assertEquals
(
1
,
rs
.
getLong
(
1
));
stat
.
execute
(
"insert into test values(100)"
);
rs
=
stat
.
getGeneratedKeys
();
// No generated keys
assertFalse
(
rs
.
next
());
// Value from sequence from trigger
rs
=
stat
.
executeQuery
(
"select scope_identity()"
);
rs
.
next
();
assertEquals
(
100
,
rs
.
getLong
(
1
));
stat
.
execute
(
"drop sequence seq"
);
...
...
@@ -1263,83 +1251,6 @@ public class TestPreparedStatement extends TestBase {
}
private
void
testIdentity
(
Connection
conn
)
throws
SQLException
{
Statement
stat
=
conn
.
createStatement
();
stat
.
execute
(
"CREATE SEQUENCE SEQ"
);
stat
.
execute
(
"CREATE TABLE TEST(ID INT)"
);
PreparedStatement
prep
;
prep
=
conn
.
prepareStatement
(
"INSERT INTO TEST VALUES(NEXT VALUE FOR SEQ)"
);
prep
.
execute
();
ResultSet
rs
=
prep
.
getGeneratedKeys
();
rs
.
next
();
assertEquals
(
1
,
rs
.
getInt
(
1
));
assertFalse
(
rs
.
next
());
prep
=
conn
.
prepareStatement
(
"INSERT INTO TEST VALUES(NEXT VALUE FOR SEQ)"
,
Statement
.
RETURN_GENERATED_KEYS
);
prep
.
execute
();
rs
=
prep
.
getGeneratedKeys
();
rs
.
next
();
assertEquals
(
2
,
rs
.
getInt
(
1
));
assertFalse
(
rs
.
next
());
prep
=
conn
.
prepareStatement
(
"INSERT INTO TEST VALUES(NEXT VALUE FOR SEQ)"
,
new
int
[]
{
1
});
prep
.
execute
();
rs
=
prep
.
getGeneratedKeys
();
rs
.
next
();
assertEquals
(
3
,
rs
.
getInt
(
1
));
assertFalse
(
rs
.
next
());
prep
=
conn
.
prepareStatement
(
"INSERT INTO TEST VALUES(NEXT VALUE FOR SEQ)"
,
new
String
[]
{
"ID"
});
prep
.
execute
();
rs
=
prep
.
getGeneratedKeys
();
rs
.
next
();
assertEquals
(
4
,
rs
.
getInt
(
1
));
assertFalse
(
rs
.
next
());
prep
=
conn
.
prepareStatement
(
"INSERT INTO TEST VALUES(NEXT VALUE FOR SEQ)"
,
ResultSet
.
TYPE_FORWARD_ONLY
,
ResultSet
.
CONCUR_READ_ONLY
,
ResultSet
.
HOLD_CURSORS_OVER_COMMIT
);
prep
.
execute
();
rs
=
prep
.
getGeneratedKeys
();
rs
.
next
();
assertEquals
(
5
,
rs
.
getInt
(
1
));
assertFalse
(
rs
.
next
());
stat
.
execute
(
"DROP TABLE TEST"
);
stat
.
execute
(
"DROP SEQUENCE SEQ"
);
}
private
void
testBatchGeneratedKeys
(
Connection
conn
)
throws
SQLException
{
Statement
stat
=
conn
.
createStatement
();
stat
.
execute
(
"CREATE SEQUENCE SEQ"
);
stat
.
execute
(
"CREATE TABLE TEST(ID INT)"
);
PreparedStatement
prep
=
conn
.
prepareStatement
(
"INSERT INTO TEST VALUES(NEXT VALUE FOR SEQ)"
);
prep
.
addBatch
();
prep
.
addBatch
();
prep
.
addBatch
();
prep
.
executeBatch
();
ResultSet
keys
=
prep
.
getGeneratedKeys
();
keys
.
next
();
assertEquals
(
1
,
keys
.
getLong
(
1
));
keys
.
next
();
assertEquals
(
2
,
keys
.
getLong
(
1
));
keys
.
next
();
assertEquals
(
3
,
keys
.
getLong
(
1
));
assertFalse
(
keys
.
next
());
stat
.
execute
(
"DROP TABLE TEST"
);
stat
.
execute
(
"DROP SEQUENCE SEQ"
);
}
private
int
getLength
()
{
return
getSize
(
LOB_SIZE
,
LOB_SIZE_BIG
);
}
...
...
h2/src/test/org/h2/test/jdbc/TestResultSet.java
浏览文件 @
47ed036f
...
...
@@ -573,12 +573,14 @@ public class TestResultSet extends TestBase {
ResultSet
rs
;
stat
.
execute
(
"CREATE TABLE TEST(ID IDENTITY NOT NULL, NAME VARCHAR NULL)"
);
stat
.
execute
(
"INSERT INTO TEST(NAME) VALUES('Hello')"
);
stat
.
execute
(
"INSERT INTO TEST(NAME) VALUES('Hello')"
,
Statement
.
RETURN_GENERATED_KEYS
);
rs
=
stat
.
getGeneratedKeys
();
assertTrue
(
rs
.
next
());
assertEquals
(
1
,
rs
.
getInt
(
1
));
stat
.
execute
(
"INSERT INTO TEST(NAME) VALUES('World')"
);
stat
.
execute
(
"INSERT INTO TEST(NAME) VALUES('World')"
,
Statement
.
RETURN_GENERATED_KEYS
);
rs
=
stat
.
getGeneratedKeys
();
assertTrue
(
rs
.
next
());
assertEquals
(
2
,
rs
.
getInt
(
1
));
...
...
h2/src/test/org/h2/test/jdbc/TestStatement.java
浏览文件 @
47ed036f
...
...
@@ -351,16 +351,19 @@ public class TestStatement extends TestBase {
stat
.
execute
(
"create table test1(id identity, x int)"
);
stat
.
execute
(
"drop table if exists test2"
);
stat
.
execute
(
"create table test2(id identity, x int)"
);
stat
.
execute
(
"merge into test1(x) key(x) values(5)"
);
stat
.
execute
(
"merge into test1(x) key(x) values(5)"
,
Statement
.
RETURN_GENERATED_KEYS
);
ResultSet
keys
;
keys
=
stat
.
getGeneratedKeys
();
keys
.
next
();
assertEquals
(
1
,
keys
.
getInt
(
1
));
stat
.
execute
(
"insert into test2(x) values(10), (11), (12)"
);
stat
.
execute
(
"merge into test1(x) key(x) values(5)"
);
stat
.
execute
(
"merge into test1(x) key(x) values(5)"
,
Statement
.
RETURN_GENERATED_KEYS
);
keys
=
stat
.
getGeneratedKeys
();
assertFalse
(
keys
.
next
());
stat
.
execute
(
"merge into test1(x) key(x) values(6)"
);
stat
.
execute
(
"merge into test1(x) key(x) values(6)"
,
Statement
.
RETURN_GENERATED_KEYS
);
keys
=
stat
.
getGeneratedKeys
();
keys
.
next
();
assertEquals
(
2
,
keys
.
getInt
(
1
));
...
...
@@ -371,7 +374,8 @@ public class TestStatement extends TestBase {
Statement
stat
=
conn
.
createStatement
();
stat
.
execute
(
"CREATE SEQUENCE SEQ"
);
stat
.
execute
(
"CREATE TABLE TEST(ID INT)"
);
stat
.
execute
(
"INSERT INTO TEST VALUES(NEXT VALUE FOR SEQ)"
);
stat
.
execute
(
"INSERT INTO TEST VALUES(NEXT VALUE FOR SEQ)"
,
Statement
.
RETURN_GENERATED_KEYS
);
ResultSet
rs
=
stat
.
getGeneratedKeys
();
rs
.
next
();
assertEquals
(
1
,
rs
.
getInt
(
1
));
...
...
h2/src/test/org/h2/test/server/TestWeb.java
浏览文件 @
47ed036f
...
...
@@ -447,7 +447,7 @@ public class TestWeb extends TestBase {
assertContains
(
result
,
"There is currently no running statement"
);
result
=
client
.
get
(
url
,
"query.do?sql=@generated insert into test(id) values(test_sequence.nextval)"
);
assertContains
(
result
,
"
SCOPE_IDENTITY()
"
);
assertContains
(
result
,
"
<tr><th>ID</th></tr><tr><td>1</td></tr>
"
);
result
=
client
.
get
(
url
,
"query.do?sql=@maxrows 2000"
);
assertContains
(
result
,
"Max rowcount is set"
);
result
=
client
.
get
(
url
,
"query.do?sql=@password_hash user password"
);
...
...
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论