Skip to content
项目
群组
代码片段
帮助
正在加载...
帮助
为 GitLab 提交贡献
登录/注册
切换导航
H
h2database
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
分枝图
比较
统计图
议题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
计划
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
分枝图
统计图
创建新议题
作业
提交
议题看板
打开侧边栏
Administrator
h2database
Commits
304fb601
提交
304fb601
authored
9月 15, 2007
作者:
Thomas Mueller
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
--no commit message
--no commit message
上级
0ae9a7c4
隐藏空白字符变更
内嵌
并排
正在显示
7 个修改的文件
包含
110 行增加
和
57 行删除
+110
-57
history.html
h2/src/docsrc/html/history.html
+3
-1
WebServer.java
h2/src/main/org/h2/server/web/WebServer.java
+10
-10
WebThread.java
h2/src/main/org/h2/server/web/WebThread.java
+1
-3
Console.java
h2/src/main/org/h2/tools/Console.java
+43
-9
Server.java
h2/src/main/org/h2/tools/Server.java
+51
-7
TestAll.java
h2/src/test/org/h2/test/TestAll.java
+2
-26
WebServlet.java
h2/src/tools/org/h2/server/web/WebServlet.java
+0
-1
没有找到文件。
h2/src/docsrc/html/history.html
浏览文件 @
304fb601
...
@@ -40,7 +40,9 @@ Hypersonic SQL or HSQLDB. H2 is built from scratch.
...
@@ -40,7 +40,9 @@ Hypersonic SQL or HSQLDB. H2 is built from scratch.
<h3>
Version 1.0 (Current)
</h3>
<h3>
Version 1.0 (Current)
</h3>
<h3>
Version 1.0.x (2007-09-x)
</h3><ul>
<h3>
Version 1.0.x (2007-09-x)
</h3><ul>
<li>
Optimization for independent subqueries. For example, this query can now an index:
<li>
System.exit is no longer called by the WebServer, the Console and the Server tool
(except to set the exit code if required). This is important when using OSGi.
</li><li>
Optimization for independent subqueries. For example, this query can now an index:
SELECT * FROM TEST WHERE ID = (SELECT MAX(ID) FROM TEST)
SELECT * FROM TEST WHERE ID = (SELECT MAX(ID) FROM TEST)
This can be disabled by setting the system property h2.optimizeSubqueryCache to false.
This can be disabled by setting the system property h2.optimizeSubqueryCache to false.
</li><li>
The explain plan now says: /* direct lookup query */ if the query can be processed directly without reading rows,
</li><li>
The explain plan now says: /* direct lookup query */ if the query can be processed directly without reading rows,
...
...
h2/src/main/org/h2/server/web/WebServer.java
浏览文件 @
304fb601
...
@@ -24,6 +24,7 @@ import org.h2.constant.SysProperties;
...
@@ -24,6 +24,7 @@ import org.h2.constant.SysProperties;
import
org.h2.engine.Constants
;
import
org.h2.engine.Constants
;
import
org.h2.message.TraceSystem
;
import
org.h2.message.TraceSystem
;
import
org.h2.server.Service
;
import
org.h2.server.Service
;
import
org.h2.server.ShutdownHandler
;
import
org.h2.util.ByteUtils
;
import
org.h2.util.ByteUtils
;
import
org.h2.util.FileUtils
;
import
org.h2.util.FileUtils
;
import
org.h2.util.JdbcUtils
;
import
org.h2.util.JdbcUtils
;
...
@@ -35,8 +36,6 @@ import org.h2.util.SortedProperties;
...
@@ -35,8 +36,6 @@ import org.h2.util.SortedProperties;
public
class
WebServer
implements
Service
{
public
class
WebServer
implements
Service
{
// TODO tool: implement a watchdog for a server
private
static
final
String
DEFAULT_LANGUAGE
=
"en"
;
private
static
final
String
DEFAULT_LANGUAGE
=
"en"
;
/**
/**
...
@@ -61,12 +60,12 @@ public class WebServer implements Service {
...
@@ -61,12 +60,12 @@ public class WebServer implements Service {
"Generic OneDollarDB|in.co.daffodil.db.jdbc.DaffodilDBDriver|jdbc:daffodilDB_embedded:school;path=C:/temp;create=true|sa"
,
"Generic OneDollarDB|in.co.daffodil.db.jdbc.DaffodilDBDriver|jdbc:daffodilDB_embedded:school;path=C:/temp;create=true|sa"
,
"Generic DB2|COM.ibm.db2.jdbc.net.DB2Driver|jdbc:db2://<host>/<db>|"
,
"Generic DB2|COM.ibm.db2.jdbc.net.DB2Driver|jdbc:db2://<host>/<db>|"
,
"Generic Oracle|oracle.jdbc.driver.OracleDriver|jdbc:oracle:thin:@<host>:1521:<instance>|scott"
,
"Generic Oracle|oracle.jdbc.driver.OracleDriver|jdbc:oracle:thin:@<host>:1521:<instance>|scott"
,
"Generic PostgreSQL|org.postgresql.Driver|jdbc:postgresql:<db>|"
,
"Generic MS SQL Server|com.microsoft.jdbc.sqlserver.SQLServerDriver|jdbc:Microsoft:sqlserver://localhost:1433;DatabaseName=sqlexpress|sa"
,
"Generic MS SQL Server|com.microsoft.jdbc.sqlserver.SQLServerDriver|jdbc:Microsoft:sqlserver://localhost:1433;DatabaseName=sqlexpress|sa"
,
"Generic MS SQL Server 2005|com.microsoft.sqlserver.jdbc.SQLServerDriver|jdbc:sqlserver://localhost;DatabaseName=test|sa"
,
"Generic MS SQL Server 2005|com.microsoft.sqlserver.jdbc.SQLServerDriver|jdbc:sqlserver://localhost;DatabaseName=test|sa"
,
"Generic PostgreSQL|org.postgresql.Driver|jdbc:postgresql:<db>|"
,
"Generic MySQL|com.mysql.jdbc.Driver|jdbc:mysql://<host>:<port>/<db>|"
,
"Generic MySQL|com.mysql.jdbc.Driver|jdbc:mysql://<host>:<port>/<db>|"
,
"Generic Derby (Embedded)|org.apache.derby.jdbc.EmbeddedDriver|jdbc:derby:test;create=true|sa"
,
"Generic Derby (Server)|org.apache.derby.jdbc.ClientDriver|jdbc:derby://localhost:1527/test;create=true|sa"
,
"Generic Derby (Server)|org.apache.derby.jdbc.ClientDriver|jdbc:derby://localhost:1527/test;create=true|sa"
,
"Generic Derby (Embedded)|org.apache.derby.jdbc.EmbeddedDriver|jdbc:derby:test;create=true|sa"
,
"Generic HSQLDB|org.hsqldb.jdbcDriver|jdbc:hsqldb:test;hsqldb.default_table_type=cached|sa"
,
"Generic HSQLDB|org.hsqldb.jdbcDriver|jdbc:hsqldb:test;hsqldb.default_table_type=cached|sa"
,
// this will be listed on top for new installations
// this will be listed on top for new installations
"Generic H2|org.h2.Driver|jdbc:h2:~/test|sa"
,
"Generic H2|org.h2.Driver|jdbc:h2:~/test|sa"
,
...
@@ -95,7 +94,7 @@ public class WebServer implements Service {
...
@@ -95,7 +94,7 @@ public class WebServer implements Service {
private
String
startDateTime
;
private
String
startDateTime
;
private
ServerSocket
serverSocket
;
private
ServerSocket
serverSocket
;
private
String
url
;
private
String
url
;
private
boolean
allowShutdown
=
true
;
private
ShutdownHandler
shutdownHandler
;
private
Thread
listenerThread
;
private
Thread
listenerThread
;
byte
[]
getFile
(
String
file
)
throws
IOException
{
byte
[]
getFile
(
String
file
)
throws
IOException
{
...
@@ -148,7 +147,6 @@ public class WebServer implements Service {
...
@@ -148,7 +147,6 @@ public class WebServer implements Service {
}
while
(
sessions
.
get
(
newId
)
!=
null
);
}
while
(
sessions
.
get
(
newId
)
!=
null
);
WebSession
session
=
new
WebSession
(
this
);
WebSession
session
=
new
WebSession
(
this
);
session
.
put
(
"sessionId"
,
newId
);
session
.
put
(
"sessionId"
,
newId
);
//session.put("ip", socket.getInetAddress().getCanonicalHostName());
session
.
put
(
"ip"
,
hostname
);
session
.
put
(
"ip"
,
hostname
);
session
.
put
(
"language"
,
DEFAULT_LANGUAGE
);
session
.
put
(
"language"
,
DEFAULT_LANGUAGE
);
sessions
.
put
(
newId
,
session
);
sessions
.
put
(
newId
,
session
);
...
@@ -438,12 +436,14 @@ public class WebServer implements Service {
...
@@ -438,12 +436,14 @@ public class WebServer implements Service {
return
JdbcUtils
.
getConnection
(
driver
,
url
,
user
,
password
);
return
JdbcUtils
.
getConnection
(
driver
,
url
,
user
,
password
);
}
}
public
void
setAllowShutdown
(
boolean
b
)
{
void
shutdown
()
{
this
.
allowShutdown
=
b
;
if
(
shutdownHandler
!=
null
)
{
shutdownHandler
.
shutdown
();
}
}
}
boolean
getAllowShutdown
(
)
{
public
void
setShutdownHandler
(
ShutdownHandler
shutdownHandler
)
{
return
allowShutdown
;
this
.
shutdownHandler
=
shutdownHandler
;
}
}
}
}
h2/src/main/org/h2/server/web/WebThread.java
浏览文件 @
304fb601
...
@@ -474,9 +474,7 @@ class WebThread extends Thread {
...
@@ -474,9 +474,7 @@ class WebThread extends Thread {
}
}
private
String
adminShutdown
()
{
private
String
adminShutdown
()
{
if
(
server
.
getAllowShutdown
())
{
server
.
shutdown
();
System
.
exit
(
0
);
}
return
"admin.jsp"
;
return
"admin.jsp"
;
}
}
...
...
h2/src/main/org/h2/tools/Console.java
浏览文件 @
304fb601
...
@@ -27,6 +27,7 @@ import java.awt.event.WindowEvent;
...
@@ -27,6 +27,7 @@ import java.awt.event.WindowEvent;
import
java.io.InputStream
;
import
java.io.InputStream
;
import
java.sql.SQLException
;
import
java.sql.SQLException
;
import
org.h2.server.ShutdownHandler
;
import
org.h2.util.IOUtils
;
import
org.h2.util.IOUtils
;
import
org.h2.util.StartBrowser
;
import
org.h2.util.StartBrowser
;
...
@@ -36,11 +37,13 @@ import org.h2.util.StartBrowser;
...
@@ -36,11 +37,13 @@ import org.h2.util.StartBrowser;
* Otherwise, a small window opens.
* Otherwise, a small window opens.
*
*
*/
*/
public
class
Console
implements
ActionListener
,
MouseListener
{
public
class
Console
implements
ActionListener
,
MouseListener
,
ShutdownHandler
{
private
Font
font
;
private
Font
font
;
private
Image
icon
;
private
Image
icon
;
private
Server
web
;
private
Frame
frame
;
private
static
final
int
EXIT_ERROR
=
1
;
private
Server
web
,
tcp
,
pg
;
/**
/**
* The command line interface for this tool.
* The command line interface for this tool.
...
@@ -50,12 +53,17 @@ public class Console implements ActionListener, MouseListener {
...
@@ -50,12 +53,17 @@ public class Console implements ActionListener, MouseListener {
* @throws Exception
* @throws Exception
*/
*/
public
static
void
main
(
String
[]
args
)
throws
Exception
{
public
static
void
main
(
String
[]
args
)
throws
Exception
{
new
Console
().
run
(
args
);
int
exitCode
=
new
Console
().
run
(
args
);
if
(
exitCode
!=
0
)
{
System
.
exit
(
exitCode
);
}
}
}
private
void
run
(
String
[]
args
)
{
private
int
run
(
String
[]
args
)
{
int
exitCode
=
0
;
try
{
try
{
web
=
Server
.
createWebServer
(
args
);
web
=
Server
.
createWebServer
(
args
);
web
.
setShutdownHandler
(
this
);
web
.
start
();
web
.
start
();
}
catch
(
SQLException
e
)
{
}
catch
(
SQLException
e
)
{
if
(
web
==
null
)
{
if
(
web
==
null
)
{
...
@@ -64,7 +72,6 @@ public class Console implements ActionListener, MouseListener {
...
@@ -64,7 +72,6 @@ public class Console implements ActionListener, MouseListener {
System
.
out
.
println
(
web
.
getStatus
());
System
.
out
.
println
(
web
.
getStatus
());
}
}
}
}
Server
tcp
=
null
,
pg
=
null
;
try
{
try
{
tcp
=
Server
.
createTcpServer
(
args
);
tcp
=
Server
.
createTcpServer
(
args
);
tcp
.
start
();
tcp
.
start
();
...
@@ -105,7 +112,34 @@ public class Console implements ActionListener, MouseListener {
...
@@ -105,7 +112,34 @@ public class Console implements ActionListener, MouseListener {
// but are wondering why nothing happens
// but are wondering why nothing happens
StartBrowser
.
openURL
(
web
.
getURL
());
StartBrowser
.
openURL
(
web
.
getURL
());
if
(!
web
.
isRunning
())
{
if
(!
web
.
isRunning
())
{
System
.
exit
(
1
);
exitCode
=
EXIT_ERROR
;
}
return
exitCode
;
}
/**
* INTERNAL
*/
public
void
shutdown
()
{
stopAll
();
}
private
void
stopAll
()
{
if
(
web
!=
null
&&
web
.
isRunning
())
{
web
.
stop
();
web
=
null
;
}
if
(
tcp
!=
null
&&
tcp
.
isRunning
())
{
tcp
.
stop
();
tcp
=
null
;
}
if
(
pg
!=
null
&&
pg
.
isRunning
())
{
pg
.
stop
();
pg
=
null
;
}
if
(
frame
!=
null
)
{
frame
.
dispose
();
frame
=
null
;
}
}
}
}
...
@@ -164,11 +198,11 @@ public class Console implements ActionListener, MouseListener {
...
@@ -164,11 +198,11 @@ public class Console implements ActionListener, MouseListener {
}
}
private
void
showWindow
(
final
boolean
exit
)
{
private
void
showWindow
(
final
boolean
exit
)
{
f
inal
Frame
f
rame
=
new
Frame
(
"H2 Console"
);
frame
=
new
Frame
(
"H2 Console"
);
frame
.
addWindowListener
(
new
WindowAdapter
()
{
frame
.
addWindowListener
(
new
WindowAdapter
()
{
public
void
windowClosing
(
WindowEvent
we
)
{
public
void
windowClosing
(
WindowEvent
we
)
{
if
(
exit
)
{
if
(
exit
)
{
System
.
exit
(
0
);
stopAll
(
);
}
else
{
}
else
{
frame
.
dispose
();
frame
.
dispose
();
}
}
...
@@ -232,7 +266,7 @@ public class Console implements ActionListener, MouseListener {
...
@@ -232,7 +266,7 @@ public class Console implements ActionListener, MouseListener {
public
void
actionPerformed
(
ActionEvent
e
)
{
public
void
actionPerformed
(
ActionEvent
e
)
{
String
command
=
e
.
getActionCommand
();
String
command
=
e
.
getActionCommand
();
if
(
"exit"
.
equals
(
command
))
{
if
(
"exit"
.
equals
(
command
))
{
System
.
exit
(
0
);
stopAll
(
);
}
else
if
(
"console"
.
equals
(
command
))
{
}
else
if
(
"console"
.
equals
(
command
))
{
startBrowser
();
startBrowser
();
}
else
if
(
"status"
.
equals
(
command
))
{
}
else
if
(
"status"
.
equals
(
command
))
{
...
...
h2/src/main/org/h2/tools/Server.java
浏览文件 @
304fb601
...
@@ -14,6 +14,7 @@ import org.h2.engine.Constants;
...
@@ -14,6 +14,7 @@ import org.h2.engine.Constants;
import
org.h2.message.Message
;
import
org.h2.message.Message
;
import
org.h2.message.TraceSystem
;
import
org.h2.message.TraceSystem
;
import
org.h2.server.Service
;
import
org.h2.server.Service
;
import
org.h2.server.ShutdownHandler
;
import
org.h2.server.TcpServer
;
import
org.h2.server.TcpServer
;
import
org.h2.server.ftp.FtpServer
;
import
org.h2.server.ftp.FtpServer
;
import
org.h2.server.pg.PgServer
;
import
org.h2.server.pg.PgServer
;
...
@@ -25,11 +26,13 @@ import org.h2.util.StartBrowser;
...
@@ -25,11 +26,13 @@ import org.h2.util.StartBrowser;
/**
/**
* This tool can be used to start various database servers (listeners).
* This tool can be used to start various database servers (listeners).
*/
*/
public
class
Server
implements
Runnable
{
public
class
Server
implements
Runnable
,
ShutdownHandler
{
private
String
name
;
private
String
name
;
private
Service
service
;
private
Service
service
;
private
static
final
int
EXIT_ERROR
=
1
;
private
static
final
int
EXIT_ERROR
=
1
;
private
Server
web
,
tcp
,
pg
,
ftp
;
private
ShutdownHandler
shutdownHandler
;
private
void
showUsage
()
{
private
void
showUsage
()
{
System
.
out
.
println
(
"java "
+
getClass
().
getName
()
+
" [options]"
);
System
.
out
.
println
(
"java "
+
getClass
().
getName
()
+
" [options]"
);
...
@@ -164,7 +167,7 @@ public class Server implements Runnable {
...
@@ -164,7 +167,7 @@ public class Server implements Runnable {
shutdownTcpServer
(
tcpShutdownServer
,
tcpPassword
,
tcpShutdownForce
);
shutdownTcpServer
(
tcpShutdownServer
,
tcpPassword
,
tcpShutdownForce
);
}
}
if
(
tcpStart
)
{
if
(
tcpStart
)
{
Server
tcp
=
createTcpServer
(
args
);
tcp
=
createTcpServer
(
args
);
try
{
try
{
tcp
.
start
();
tcp
.
start
();
}
catch
(
SQLException
e
)
{
}
catch
(
SQLException
e
)
{
...
@@ -175,7 +178,7 @@ public class Server implements Runnable {
...
@@ -175,7 +178,7 @@ public class Server implements Runnable {
System
.
out
.
println
(
tcp
.
getStatus
());
System
.
out
.
println
(
tcp
.
getStatus
());
}
}
if
(
pgStart
)
{
if
(
pgStart
)
{
Server
pg
=
createPgServer
(
args
);
pg
=
createPgServer
(
args
);
try
{
try
{
pg
.
start
();
pg
.
start
();
}
catch
(
SQLException
e
)
{
}
catch
(
SQLException
e
)
{
...
@@ -186,7 +189,8 @@ public class Server implements Runnable {
...
@@ -186,7 +189,8 @@ public class Server implements Runnable {
System
.
out
.
println
(
pg
.
getStatus
());
System
.
out
.
println
(
pg
.
getStatus
());
}
}
if
(
webStart
)
{
if
(
webStart
)
{
Server
web
=
createWebServer
(
args
);
web
=
createWebServer
(
args
);
web
.
setShutdownHandler
(
this
);
try
{
try
{
web
.
start
();
web
.
start
();
}
catch
(
SQLException
e
)
{
}
catch
(
SQLException
e
)
{
...
@@ -203,7 +207,7 @@ public class Server implements Runnable {
...
@@ -203,7 +207,7 @@ public class Server implements Runnable {
}
}
}
}
if
(
ftpStart
)
{
if
(
ftpStart
)
{
Server
ftp
=
createFtpServer
(
args
);
ftp
=
createFtpServer
(
args
);
try
{
try
{
ftp
.
start
();
ftp
.
start
();
}
catch
(
SQLException
e
)
{
}
catch
(
SQLException
e
)
{
...
@@ -298,7 +302,10 @@ public class Server implements Runnable {
...
@@ -298,7 +302,10 @@ public class Server implements Runnable {
* @return the server
* @return the server
*/
*/
public
static
Server
createWebServer
(
String
[]
args
)
throws
SQLException
{
public
static
Server
createWebServer
(
String
[]
args
)
throws
SQLException
{
return
new
Server
(
"H2 Console Server"
,
new
WebServer
(),
args
);
WebServer
service
=
new
WebServer
();
Server
server
=
new
Server
(
"H2 Console Server"
,
service
,
args
);
service
.
setShutdownHandler
(
server
);
return
server
;
}
}
/**
/**
...
@@ -355,7 +362,26 @@ public class Server implements Runnable {
...
@@ -355,7 +362,26 @@ public class Server implements Runnable {
}
catch
(
InterruptedException
e
)
{
}
catch
(
InterruptedException
e
)
{
// ignore
// ignore
}
}
}
}
private
void
stopAll
()
{
if
(
web
!=
null
&&
web
.
isRunning
())
{
web
.
stop
();
web
=
null
;
}
if
(
tcp
!=
null
&&
tcp
.
isRunning
())
{
tcp
.
stop
();
tcp
=
null
;
}
if
(
pg
!=
null
&&
pg
.
isRunning
())
{
pg
.
stop
();
pg
=
null
;
}
if
(
ftp
!=
null
&&
ftp
.
isRunning
())
{
ftp
.
stop
();
ftp
=
null
;
}
}
/**
/**
* Checks if the server is running.
* Checks if the server is running.
...
@@ -401,4 +427,22 @@ public class Server implements Runnable {
...
@@ -401,4 +427,22 @@ public class Server implements Runnable {
TraceSystem
.
traceThrowable
(
e
);
TraceSystem
.
traceThrowable
(
e
);
}
}
}
}
/**
* INTERNAL
*/
public
void
setShutdownHandler
(
ShutdownHandler
shutdownHandler
)
{
this
.
shutdownHandler
=
shutdownHandler
;
}
/**
* INTERNAL
*/
public
void
shutdown
()
{
if
(
shutdownHandler
!=
null
)
{
shutdownHandler
.
shutdown
();
}
else
{
stopAll
();
}
}
}
}
h2/src/test/org/h2/test/TestAll.java
浏览文件 @
304fb601
...
@@ -143,37 +143,13 @@ java org.h2.test.TestAll timer
...
@@ -143,37 +143,13 @@ java org.h2.test.TestAll timer
/*
/*
Avoid System.exit()
Sorry.... I just read the doc and it says using LOG=0 can lead to
Sorry.... I just read the doc and it says using LOG=0 can lead to
corruption...
corruption...
"At startup, when corrupted, say if LOG=0 was used before"
"At startup, when corrupted, say if LOG=0 was used before"
In fact, the reason I mentioned this is that I found out it was slow
when used in a sub query, thus I split it in two queries and forgot to
mention it. Try this and you will see why:
DROP TABLE TEST;
CREATE TABLE TEST(COL1 BIGINT PRIMARY KEY, COL2 VARCHAR);
INSERT INTO TEST SELECT X, CONCAT('Test', X) FROM SYSTEM_RANGE(1,
1000000);
SELECT MAX(COL1) FROM TEST;
SELECT * FROM TEST where col1=(select MAX(COL1) from test)
SELECT MAX(COL1) FROM TEST;
MAX(COL1)
1000000
(1 row, 0 ms)
SELECT * FROM TEST where col1=(select MAX(COL1) from test);
COL1 COL2
1000000 Test1000000
(1 row, 6815 ms)
I generally felt that sub queries were not properly optimized in h2
and I had to split them all (I understand it's a complex thing (I've
worked a (very) little on db2 a long long time ago...))
add MVCC
add MVCC
slow:
slow:
...
...
h2/src/tools/org/h2/server/web/WebServlet.java
浏览文件 @
304fb601
...
@@ -42,7 +42,6 @@ public class WebServlet extends HttpServlet {
...
@@ -42,7 +42,6 @@ public class WebServlet extends HttpServlet {
String
[]
args
=
new
String
[
list
.
size
()];
String
[]
args
=
new
String
[
list
.
size
()];
list
.
toArray
(
args
);
list
.
toArray
(
args
);
server
=
new
WebServer
();
server
=
new
WebServer
();
server
.
setAllowShutdown
(
false
);
try
{
try
{
server
.
init
(
args
);
server
.
init
(
args
);
}
catch
(
Exception
e
)
{
}
catch
(
Exception
e
)
{
...
...
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论