Skip to content
项目
群组
代码片段
帮助
正在加载...
帮助
为 GitLab 提交贡献
登录/注册
切换导航
H
h2database
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
分枝图
比较
统计图
议题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
计划
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
分枝图
统计图
创建新议题
作业
提交
议题看板
打开侧边栏
Administrator
h2database
Commits
a85afcb5
提交
a85afcb5
authored
5月 03, 2007
作者:
Thomas Mueller
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
--no commit message
--no commit message
上级
973875f3
显示空白字符变更
内嵌
并排
正在显示
8 个修改的文件
包含
225 行增加
和
45 行删除
+225
-45
Session.java
h2/src/main/org/h2/engine/Session.java
+6
-1
Function.java
h2/src/main/org/h2/expression/Function.java
+29
-2
LinkedIndex.java
h2/src/main/org/h2/index/LinkedIndex.java
+77
-34
help.csv
h2/src/main/org/h2/res/help.csv
+21
-0
AppServer.java
h2/src/main/org/h2/server/web/AppServer.java
+1
-4
Table.java
h2/src/main/org/h2/table/Table.java
+19
-0
TableLink.java
h2/src/main/org/h2/table/TableLink.java
+32
-4
TestLinkedTable.java
h2/src/test/org/h2/test/db/TestLinkedTable.java
+40
-0
没有找到文件。
h2/src/main/org/h2/engine/Session.java
浏览文件 @
a85afcb5
...
...
@@ -19,6 +19,7 @@ import org.h2.jdbc.JdbcConnection;
import
org.h2.message.Message
;
import
org.h2.message.Trace
;
import
org.h2.message.TraceSystem
;
import
org.h2.result.Row
;
import
org.h2.schema.Schema
;
import
org.h2.store.DataHandler
;
import
org.h2.store.InDoubtTransaction
;
...
...
@@ -269,7 +270,11 @@ public class Session implements SessionInterface {
locks
.
add
(
table
);
}
public
void
log
(
UndoLogRecord
log
)
throws
SQLException
{
public
void
log
(
Table
table
,
short
type
,
Row
row
)
throws
SQLException
{
log
(
new
UndoLogRecord
(
table
,
type
,
row
));
}
private
void
log
(
UndoLogRecord
log
)
throws
SQLException
{
// called _after_ the row was inserted successfully into the table,
// otherwise rollback will try to rollback a not-inserted row
if
(
Constants
.
CHECK
)
{
...
...
h2/src/main/org/h2/expression/Function.java
浏览文件 @
a85afcb5
...
...
@@ -94,7 +94,7 @@ public class Function extends Expression implements FunctionCall {
COALESCE
=
204
,
NULLIF
=
205
,
CASE
=
206
,
NEXTVAL
=
207
,
CURRVAL
=
208
,
ARRAY_GET
=
209
,
CSVREAD
=
210
,
CSVWRITE
=
211
,
MEMORY_FREE
=
212
,
MEMORY_USED
=
213
,
LOCK_MODE
=
214
,
SCHEMA
=
215
,
SESSION_ID
=
216
,
ARRAY_LENGTH
=
217
,
LINK_SCHEMA
=
218
,
TABLE
=
219
;
LINK_SCHEMA
=
218
,
TABLE
=
219
,
LEAST
=
220
,
GREATEST
=
221
;
private
static
final
int
VAR_ARGS
=
-
1
;
...
...
@@ -286,6 +286,8 @@ public class Function extends Expression implements FunctionCall {
addFunction
(
"ARRAY_LENGTH"
,
ARRAY_LENGTH
,
1
,
Value
.
INT
);
addFunction
(
"LINK_SCHEMA"
,
LINK_SCHEMA
,
6
,
Value
.
RESULT_SET
);
addFunctionWithNull
(
"TABLE"
,
TABLE
,
VAR_ARGS
,
Value
.
RESULT_SET
);
addFunctionWithNull
(
"LEAST"
,
LEAST
,
VAR_ARGS
,
Value
.
NULL
);
addFunctionWithNull
(
"GREATEST"
,
GREATEST
,
VAR_ARGS
,
Value
.
NULL
);
}
private
static
void
addFunction
(
String
name
,
int
type
,
int
parameterCount
,
...
...
@@ -394,6 +396,27 @@ public class Function extends Expression implements FunctionCall {
}
return
v0
;
}
case
GREATEST:
case
LEAST:
{
Value
result
=
ValueNull
.
INSTANCE
;
for
(
int
i
=
0
;
i
<
args
.
length
;
i
++)
{
Value
v
=
i
==
0
?
v0
:
args
[
i
].
getValue
(
session
);
if
(!(
v
==
ValueNull
.
INSTANCE
))
{
v
=
v
.
convertTo
(
dataType
);
if
(
result
==
ValueNull
.
INSTANCE
)
{
result
=
v
;
}
else
{
int
comp
=
database
.
compareTypeSave
(
result
,
v
);
if
(
info
.
type
==
GREATEST
&&
comp
<
0
)
{
result
=
v
;
}
else
if
(
info
.
type
==
LEAST
&&
comp
>
0
)
{
result
=
v
;
}
}
}
}
return
result
;
}
case
CASE:
{
// TODO function CASE: document & implement functionality
int
i
=
0
;
...
...
@@ -1220,6 +1243,8 @@ public class Function extends Expression implements FunctionCall {
case
COALESCE:
case
CSVREAD:
case
TABLE:
case
LEAST:
case
GREATEST:
min
=
1
;
break
;
case
NOW:
...
...
@@ -1303,7 +1328,9 @@ public class Function extends Expression implements FunctionCall {
switch
(
info
.
type
)
{
case
IFNULL:
case
NULLIF:
case
COALESCE:
{
case
COALESCE:
case
LEAST:
case
GREATEST:
{
dataType
=
Value
.
STRING
;
scale
=
0
;
precision
=
0
;
...
...
h2/src/main/org/h2/index/LinkedIndex.java
浏览文件 @
a85afcb5
...
...
@@ -78,39 +78,6 @@ public class LinkedIndex extends Index {
}
}
public
void
remove
(
Session
session
,
Row
row
)
throws
SQLException
{
StringBuffer
buff
=
new
StringBuffer
(
"DELETE FROM "
);
buff
.
append
(
originalTable
);
buff
.
append
(
" WHERE "
);
for
(
int
i
=
0
;
i
<
row
.
getColumnCount
();
i
++)
{
if
(
i
>
0
)
{
buff
.
append
(
"AND "
);
}
buff
.
append
(
table
.
getColumn
(
i
).
getSQL
());
Value
v
=
row
.
getValue
(
i
);
if
(
isNull
(
v
))
{
buff
.
append
(
" IS NULL "
);
}
else
{
buff
.
append
(
"=? "
);
}
}
String
sql
=
buff
.
toString
();
try
{
PreparedStatement
prep
=
link
.
getPreparedStatement
(
sql
);
for
(
int
i
=
0
,
j
=
0
;
i
<
row
.
getColumnCount
();
i
++)
{
Value
v
=
row
.
getValue
(
i
);
if
(!
isNull
(
v
))
{
v
.
set
(
prep
,
j
+
1
);
j
++;
}
}
int
count
=
prep
.
executeUpdate
();
rowCount
-=
count
;
}
catch
(
SQLException
e
)
{
throw
Message
.
getSQLException
(
Message
.
ERROR_ACCESSING_LINKED_TABLE_1
,
new
String
[]{
sql
},
e
);
}
}
public
Cursor
find
(
Session
session
,
SearchRow
first
,
SearchRow
last
)
throws
SQLException
{
StringBuffer
buff
=
new
StringBuffer
();
for
(
int
i
=
0
;
first
!=
null
&&
i
<
first
.
getColumnCount
();
i
++)
{
...
...
@@ -198,4 +165,80 @@ public class LinkedIndex extends Index {
throw
Message
.
getUnsupportedException
();
}
public
void
remove
(
Session
session
,
Row
row
)
throws
SQLException
{
StringBuffer
buff
=
new
StringBuffer
(
"DELETE FROM "
);
buff
.
append
(
originalTable
);
buff
.
append
(
" WHERE "
);
for
(
int
i
=
0
;
i
<
row
.
getColumnCount
();
i
++)
{
if
(
i
>
0
)
{
buff
.
append
(
"AND "
);
}
buff
.
append
(
table
.
getColumn
(
i
).
getSQL
());
Value
v
=
row
.
getValue
(
i
);
if
(
isNull
(
v
))
{
buff
.
append
(
" IS NULL "
);
}
else
{
buff
.
append
(
"=? "
);
}
}
String
sql
=
buff
.
toString
();
try
{
PreparedStatement
prep
=
link
.
getPreparedStatement
(
sql
);
for
(
int
i
=
0
,
j
=
0
;
i
<
row
.
getColumnCount
();
i
++)
{
Value
v
=
row
.
getValue
(
i
);
if
(!
isNull
(
v
))
{
v
.
set
(
prep
,
j
+
1
);
j
++;
}
}
int
count
=
prep
.
executeUpdate
();
rowCount
-=
count
;
}
catch
(
SQLException
e
)
{
throw
Message
.
getSQLException
(
Message
.
ERROR_ACCESSING_LINKED_TABLE_1
,
new
String
[]{
sql
},
e
);
}
}
public
void
update
(
Session
session
,
Row
oldRow
,
Row
newRow
)
throws
SQLException
{
StringBuffer
buff
=
new
StringBuffer
(
"UPDATE "
);
buff
.
append
(
originalTable
).
append
(
" SET "
);
for
(
int
i
=
0
;
i
<
newRow
.
getColumnCount
();
i
++)
{
if
(
i
>
0
)
{
buff
.
append
(
", "
);
}
buff
.
append
(
table
.
getColumn
(
i
).
getSQL
()).
append
(
"=?"
);
}
buff
.
append
(
" WHERE "
);
for
(
int
i
=
0
;
i
<
oldRow
.
getColumnCount
();
i
++)
{
if
(
i
>
0
)
{
buff
.
append
(
"AND "
);
}
buff
.
append
(
table
.
getColumn
(
i
).
getSQL
());
Value
v
=
oldRow
.
getValue
(
i
);
if
(
isNull
(
v
))
{
buff
.
append
(
" IS NULL "
);
}
else
{
buff
.
append
(
"=? "
);
}
}
String
sql
=
buff
.
toString
();
try
{
int
j
=
1
;
PreparedStatement
prep
=
link
.
getPreparedStatement
(
sql
);
for
(
int
i
=
0
;
i
<
newRow
.
getColumnCount
();
i
++)
{
newRow
.
getValue
(
i
).
set
(
prep
,
j
);
j
++;
}
for
(
int
i
=
0
;
i
<
oldRow
.
getColumnCount
();
i
++)
{
Value
v
=
oldRow
.
getValue
(
i
);
if
(!
isNull
(
v
))
{
v
.
set
(
prep
,
j
);
j
++;
}
}
prep
.
executeUpdate
();
}
catch
(
SQLException
e
)
{
throw
Message
.
getSQLException
(
Message
.
ERROR_ACCESSING_LINKED_TABLE_1
,
new
String
[]{
sql
},
e
);
}
}
}
h2/src/main/org/h2/res/help.csv
浏览文件 @
a85afcb5
...
...
@@ -362,9 +362,14 @@ CREATE INDEX IDXNAME ON TEST(NAME)
CREATE LINKED TABLE [IF NOT EXISTS]
name(driverString, urlString,
userString, passwordString, originalTableString)
[EMIT UPDATES]
","
Creates a table link to an external table.
The driver name may be empty if the driver is already loaded.
Usually, for update statements, the old rows are deleted first
and then the new rows inserted. It is possible to emit update
statements (however this is not possible on rollback), however
in this case multi-row unique key updates may not always work.
The current user owner must have admin rights.
","
CREATE LINKED TABLE LINK('org.h2.Driver', 'jdbc:h2:test', 'sa', '', 'TEST')
...
...
@@ -2460,6 +2465,14 @@ Returns NULL otherwise.
DATABASE_PATH()
"
"Functions (System)","GREATEST","
GREATEST(aValue, bValue [,...]): value
","
Returns the largest value that is not NULL, or NULL if all values are NULL.
","
GREATEST(A, B, C)
"
"Functions (System)","IDENTITY","
IDENTITY(): int
","
...
...
@@ -2476,6 +2489,14 @@ Returns the value of 'a' if it is not null, otherwise 'b'.
IFNULL(A, B)
"
"Functions (System)","LEAST","
LEAST(aValue, bValue [,...]): value
","
Returns the smallest value that is not NULL, or NULL if all values are NULL.
","
LEAST(A, B, C)
"
"Functions (System)","LOCK_MODE","
LOCK_MODE(): int
","
...
...
h2/src/main/org/h2/server/web/AppServer.java
浏览文件 @
a85afcb5
...
...
@@ -9,7 +9,6 @@ import java.io.FileOutputStream;
import
java.io.IOException
;
import
java.sql.Connection
;
import
java.sql.DriverManager
;
import
java.util.ArrayList
;
import
java.util.HashMap
;
import
java.util.Properties
;
...
...
@@ -211,8 +210,6 @@ public class AppServer {
user
=
user
.
trim
();
password
=
password
.
trim
();
org
.
h2
.
Driver
.
load
();
JdbcUtils
.
getConnection
(
driver
,
url
,
user
,
password
);
Class
.
forName
(
driver
);
// try {
// Driver dr = (Driver) urlClassLoader.loadClass(driver).newInstance();
// Properties p = new Properties();
...
...
@@ -222,7 +219,7 @@ public class AppServer {
// } catch(ClassNotFoundException e2) {
// throw e2;
// }
return
DriverManager
.
getConnection
(
url
,
user
,
password
);
return
JdbcUtils
.
getConnection
(
driver
,
url
,
user
,
password
);
}
}
h2/src/main/org/h2/table/Table.java
浏览文件 @
a85afcb5
...
...
@@ -7,6 +7,7 @@ package org.h2.table;
import
java.sql.SQLException
;
import
java.util.HashMap
;
import
org.h2.command.Prepared
;
import
org.h2.constraint.Constraint
;
import
org.h2.engine.Constants
;
import
org.h2.engine.DbObject
;
...
...
@@ -24,6 +25,7 @@ import org.h2.schema.Schema;
import
org.h2.schema.SchemaObject
;
import
org.h2.schema.Sequence
;
import
org.h2.schema.TriggerObject
;
import
org.h2.store.UndoLogRecord
;
import
org.h2.util.ObjectArray
;
import
org.h2.value.Value
;
import
org.h2.value.ValueNull
;
...
...
@@ -126,6 +128,23 @@ public abstract class Table extends SchemaObject {
public
abstract
boolean
isLockedExclusively
();
public
abstract
long
getMaxDataModificationId
();
public
void
updateRows
(
Prepared
prepared
,
Session
session
,
ObjectArray
oldRows
,
ObjectArray
newRows
)
throws
SQLException
{
// remove the old rows
for
(
int
i
=
0
;
i
<
oldRows
.
size
();
i
++)
{
prepared
.
checkCancelled
();
Row
o
=
(
Row
)
oldRows
.
get
(
i
);
removeRow
(
session
,
o
);
session
.
log
(
this
,
UndoLogRecord
.
DELETE
,
o
);
}
// add the new rows
for
(
int
i
=
0
;
i
<
newRows
.
size
();
i
++)
{
prepared
.
checkCancelled
();
Row
n
=
(
Row
)
newRows
.
get
(
i
);
addRow
(
session
,
n
);
session
.
log
(
this
,
UndoLogRecord
.
INSERT
,
n
);
}
}
public
void
removeChildrenAndResources
(
Session
session
)
throws
SQLException
{
while
(
views
!=
null
&&
views
.
size
()
>
0
)
{
TableView
view
=
(
TableView
)
views
.
get
(
0
);
...
...
h2/src/main/org/h2/table/TableLink.java
浏览文件 @
a85afcb5
...
...
@@ -13,6 +13,7 @@ import java.sql.SQLException;
import
java.sql.Statement
;
import
java.util.HashMap
;
import
org.h2.command.Prepared
;
import
org.h2.engine.Session
;
import
org.h2.index.Index
;
import
org.h2.index.IndexType
;
...
...
@@ -20,6 +21,7 @@ import org.h2.index.LinkedIndex;
import
org.h2.message.Message
;
import
org.h2.result.Row
;
import
org.h2.schema.Schema
;
import
org.h2.store.UndoLogRecord
;
import
org.h2.util.JdbcUtils
;
import
org.h2.util.ObjectArray
;
import
org.h2.util.StringUtils
;
...
...
@@ -35,15 +37,18 @@ public class TableLink extends Table {
private
Connection
conn
;
private
HashMap
prepared
=
new
HashMap
();
private
ObjectArray
indexes
=
new
ObjectArray
();
private
boolean
emitUpdates
;
private
LinkedIndex
linkedIndex
;
public
TableLink
(
Schema
schema
,
int
id
,
String
name
,
String
driver
,
String
url
,
String
user
,
String
password
,
String
originalTable
)
throws
SQLException
{
String
user
,
String
password
,
String
originalTable
,
boolean
emitUpdates
)
throws
SQLException
{
super
(
schema
,
id
,
name
,
false
);
this
.
driver
=
driver
;
this
.
url
=
url
;
this
.
user
=
user
;
this
.
password
=
password
;
this
.
originalTable
=
originalTable
;
this
.
emitUpdates
=
emitUpdates
;
conn
=
JdbcUtils
.
getConnection
(
driver
,
url
,
user
,
password
);
DatabaseMetaData
meta
=
conn
.
getMetaData
();
boolean
storesLowerCase
=
meta
.
storesLowerCaseIdentifiers
();
...
...
@@ -94,8 +99,8 @@ public class TableLink extends Table {
Column
[]
cols
=
new
Column
[
columnList
.
size
()];
columnList
.
toArray
(
cols
);
setColumns
(
cols
);
Index
i
ndex
=
new
LinkedIndex
(
this
,
id
,
cols
,
IndexType
.
createNonUnique
(
false
));
indexes
.
add
(
i
ndex
);
linkedI
ndex
=
new
LinkedIndex
(
this
,
id
,
cols
,
IndexType
.
createNonUnique
(
false
));
indexes
.
add
(
linkedI
ndex
);
rs
=
meta
.
getPrimaryKeys
(
null
,
null
,
originalTable
);
String
pkName
=
""
;
ObjectArray
list
;
...
...
@@ -179,6 +184,9 @@ public class TableLink extends Table {
buff
.
append
(
", "
);
buff
.
append
(
StringUtils
.
quoteStringSQL
(
originalTable
));
buff
.
append
(
")"
);
if
(
emitUpdates
)
{
buff
.
append
(
" EMIT UPDATES"
);
}
return
buff
.
toString
();
}
...
...
@@ -195,7 +203,7 @@ public class TableLink extends Table {
}
public
Index
getScanIndex
(
Session
session
)
{
return
(
Index
)
indexes
.
get
(
0
)
;
return
linkedIndex
;
}
public
void
removeRow
(
Session
session
,
Row
row
)
throws
SQLException
{
...
...
@@ -294,4 +302,24 @@ public class TableLink extends Table {
return
null
;
}
public
void
updateRows
(
Prepared
prepared
,
Session
session
,
ObjectArray
oldRows
,
ObjectArray
newRows
)
throws
SQLException
{
boolean
deleteInsert
;
if
(
emitUpdates
)
{
for
(
int
i
=
0
;
i
<
oldRows
.
size
();
i
++)
{
session
.
checkCancelled
();
Row
oldRow
=
(
Row
)
oldRows
.
get
(
i
);
Row
newRow
=
(
Row
)
newRows
.
get
(
i
);
linkedIndex
.
update
(
session
,
oldRow
,
newRow
);
session
.
log
(
this
,
UndoLogRecord
.
DELETE
,
oldRow
);
session
.
log
(
this
,
UndoLogRecord
.
INSERT
,
newRow
);
}
deleteInsert
=
false
;
}
else
{
deleteInsert
=
true
;
}
if
(
deleteInsert
)
{
super
.
updateRows
(
prepared
,
session
,
oldRows
,
newRows
);
}
}
}
h2/src/test/org/h2/test/db/TestLinkedTable.java
浏览文件 @
a85afcb5
...
...
@@ -13,9 +13,49 @@ public class TestLinkedTable extends TestBase {
public
void
test
()
throws
Exception
{
testLinkSchema
();
testLinkEmitUpdates
();
testLinkTable
();
}
private
void
testLinkEmitUpdates
()
throws
Exception
{
deleteDb
(
"linked1"
);
deleteDb
(
"linked2"
);
Class
.
forName
(
"org.h2.Driver"
);
Connection
conn
=
DriverManager
.
getConnection
(
"jdbc:h2:"
+
BASE_DIR
+
"/linked1"
,
"sa1"
,
"abc"
);
Statement
stat
=
conn
.
createStatement
();
stat
.
execute
(
"CREATE TABLE TEST(ID INT PRIMARY KEY, NAME VARCHAR)"
);
Connection
conn2
=
DriverManager
.
getConnection
(
"jdbc:h2:"
+
BASE_DIR
+
"/linked2"
,
"sa2"
,
"def"
);
Statement
stat2
=
conn2
.
createStatement
();
String
link
=
"CREATE LINKED TABLE TEST_LINK_U('', 'jdbc:h2:"
+
BASE_DIR
+
"/linked1', 'sa1', 'abc', 'TEST') EMIT UPDATES"
;
stat2
.
execute
(
link
);
link
=
"CREATE LINKED TABLE TEST_LINK_DI('', 'jdbc:h2:"
+
BASE_DIR
+
"/linked1', 'sa1', 'abc', 'TEST')"
;
stat2
.
execute
(
link
);
stat2
.
executeUpdate
(
"INSERT INTO TEST_LINK_U VALUES(1, 'Hello')"
);
stat2
.
executeUpdate
(
"INSERT INTO TEST_LINK_DI VALUES(2, 'World')"
);
try
{
stat2
.
executeUpdate
(
"UPDATE TEST_LINK_U SET ID=ID+1"
);
error
(
"unexpected success"
);
}
catch
(
SQLException
e
)
{
checkNotGeneralException
(
e
);
}
stat2
.
executeUpdate
(
"UPDATE TEST_LINK_DI SET ID=ID+1"
);
stat2
.
executeUpdate
(
"UPDATE TEST_LINK_U SET NAME=NAME || ID"
);
ResultSet
rs
;
rs
=
stat
.
executeQuery
(
"SELECT * FROM TEST ORDER BY ID"
);
rs
.
next
();
check
(
rs
.
getInt
(
1
),
2
);
check
(
rs
.
getString
(
2
),
"Hello2"
);
rs
.
next
();
check
(
rs
.
getInt
(
1
),
3
);
check
(
rs
.
getString
(
2
),
"World3"
);
checkFalse
(
rs
.
next
());
conn
.
close
();
conn2
.
close
();
}
private
void
testLinkSchema
()
throws
Exception
{
deleteDb
(
"linked1"
);
deleteDb
(
"linked2"
);
...
...
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论