Skip to content
项目
群组
代码片段
帮助
正在加载...
帮助
为 GitLab 提交贡献
登录/注册
切换导航
H
h2database
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
分枝图
比较
统计图
议题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
计划
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
分枝图
统计图
创建新议题
作业
提交
议题看板
打开侧边栏
Administrator
h2database
Commits
43214cca
提交
43214cca
authored
7月 28, 2007
作者:
Thomas Mueller
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
--no commit message
--no commit message
上级
2531186c
显示空白字符变更
内嵌
并排
正在显示
23 个修改的文件
包含
144 行增加
和
1376 行删除
+144
-1376
build.xml
h2/build.xml
+1
-5
advanced.html
h2/src/docsrc/html/advanced.html
+68
-30
history.html
h2/src/docsrc/html/history.html
+3
-1
odbcDataSource.png
h2/src/docsrc/html/odbcDataSource.png
+0
-0
h2.nsi
h2/src/installer/h2.nsi
+0
-2
Constants.java
h2/src/main/org/h2/engine/Constants.java
+0
-1
Function.java
h2/src/main/org/h2/expression/Function.java
+0
-1
LinearHashEntry.java
h2/src/main/org/h2/index/LinearHashEntry.java
+8
-0
OdbcServer.java
h2/src/main/org/h2/server/OdbcServer.java
+0
-181
OdbcServerThread.java
h2/src/main/org/h2/server/OdbcServerThread.java
+0
-749
OdbcTransfer.java
h2/src/main/org/h2/server/OdbcTransfer.java
+0
-247
PgServer.java
h2/src/main/org/h2/server/pg/PgServer.java
+21
-30
PgServerThread.java
h2/src/main/org/h2/server/pg/PgServerThread.java
+17
-70
pg_catalog.sql
h2/src/main/org/h2/server/pg/pg_catalog.sql
+5
-1
Console.java
h2/src/main/org/h2/tools/Console.java
+1
-1
Server.java
h2/src/main/org/h2/tools/Server.java
+2
-34
Cache2Q.java
h2/src/main/org/h2/util/Cache2Q.java
+7
-3
CacheLRU.java
h2/src/main/org/h2/util/CacheLRU.java
+1
-7
DataType.java
h2/src/main/org/h2/value/DataType.java
+0
-1
TestAll.java
h2/src/test/org/h2/test/TestAll.java
+1
-1
test.properties
h2/src/test/org/h2/test/bench/test.properties
+7
-8
TestBackup.java
h2/src/test/org/h2/test/db/TestBackup.java
+0
-1
testSimple.in.txt
h2/src/test/org/h2/test/testSimple.in.txt
+2
-2
没有找到文件。
h2/build.xml
浏览文件 @
43214cca
...
@@ -37,13 +37,10 @@
...
@@ -37,13 +37,10 @@
<target
name=
"clean"
depends=
"init"
>
<target
name=
"clean"
depends=
"init"
>
<mkdir
dir=
"bin"
/>
<mkdir
dir=
"bin"
/>
<mkdir
dir=
"odbc"
/>
<mkdir
dir=
"docs"
/>
<mkdir
dir=
"docs"
/>
<delete
includeemptydirs=
"true"
>
<delete
includeemptydirs=
"true"
>
<fileset
dir=
"."
includes=
"*.sql,*.txt,*.lock,**/*.db,node*"
/>
<fileset
dir=
"."
includes=
"*.sql,*.txt,*.lock,**/*.db,node*"
/>
<fileset
dir=
"bin"
includes=
"**/*"
excludes=
"**/*.bat,**/*.sh"
/>
<fileset
dir=
"bin"
includes=
"**/*"
excludes=
"**/*.bat,**/*.sh"
/>
<fileset
dir=
"odbc"
includes=
"*.a,*.def,"
/>
<fileset
dir=
"odbc"
includes=
"*.def,h2odbcTest.exe"
/>
<fileset
dir=
"docs"
includes=
"**/*"
/>
<fileset
dir=
"docs"
includes=
"**/*"
/>
</delete>
</delete>
<delete
file=
"src/tools/org/h2/tools/code/CodeSwitch.class"
/>
<delete
file=
"src/tools/org/h2/tools/code/CodeSwitch.class"
/>
...
@@ -251,7 +248,7 @@
...
@@ -251,7 +248,7 @@
<fileset
dir=
"src/main"
/>
<fileset
dir=
"src/main"
/>
</copy>
</copy>
<java
classname=
"org.h2.test.coverage.Coverage"
classpath=
"bin"
dir=
"bin"
fork=
"true"
>
<java
classname=
"org.h2.test.coverage.Coverage"
classpath=
"bin"
dir=
"bin"
fork=
"true"
>
<arg
line=
"-e org/h2/web -e org/h2/
server/Odbc -e org/h2/
jdbcx -e org/h2/bnf -r org/h2"
/>
<arg
line=
"-e org/h2/web -e org/h2/jdbcx -e org/h2/bnf -r org/h2"
/>
</java>
</java>
<javac
target=
"${jdk}"
source=
"${jdk}"
executable=
"${javac}"
srcdir=
"bin"
destdir=
"bin"
debug=
"true"
includes=
"org/h2/**"
/>
<javac
target=
"${jdk}"
source=
"${jdk}"
executable=
"${javac}"
srcdir=
"bin"
destdir=
"bin"
debug=
"true"
includes=
"org/h2/**"
/>
<java
classname=
"org.h2.test.TestAll"
fork=
"true"
classpath=
"bin"
dir=
"bin"
>
<java
classname=
"org.h2.test.TestAll"
fork=
"true"
classpath=
"bin"
dir=
"bin"
>
...
@@ -279,7 +276,6 @@
...
@@ -279,7 +276,6 @@
<fileset
dir=
".."
includes=
"h2/ant-build.properties"
/>
<fileset
dir=
".."
includes=
"h2/ant-build.properties"
/>
<fileset
dir=
".."
includes=
"h2/bin/**/*"
/>
<fileset
dir=
".."
includes=
"h2/bin/**/*"
/>
<fileset
dir=
".."
includes=
"h2/docs/**/*"
/>
<fileset
dir=
".."
includes=
"h2/docs/**/*"
/>
<fileset
dir=
".."
includes=
"h2/odbc/**/*"
/>
<fileset
dir=
".."
includes=
"h2/service/**/*"
/>
<fileset
dir=
".."
includes=
"h2/service/**/*"
/>
<fileset
dir=
".."
includes=
"h2/src/**/*"
/>
<fileset
dir=
".."
includes=
"h2/src/**/*"
/>
</zip>
</zip>
...
...
h2/src/docsrc/html/advanced.html
浏览文件 @
43214cca
...
@@ -311,48 +311,86 @@ If successful, a command prompt window will pop up and disappear immediately. If
...
@@ -311,48 +311,86 @@ If successful, a command prompt window will pop up and disappear immediately. If
<br
/><a
name=
"odbc_driver"
></a>
<br
/><a
name=
"odbc_driver"
></a>
<h2>
ODBC Driver
</h2>
<h2>
ODBC Driver
</h2>
The ODBC driver of this database is currently not very stable and only tested superficially
This database does not come with its own ODBC driver at this time,
with a few applications (OpenOffice 2.0, Microsoft Excel and Microsoft Access) and
but it supports the PostgreSQL network protocol.
data types (INT and VARCHAR), and should not be used for production applications.
Therefore, the PostgreSQL ODBC driver can be used.
Only a Windows version of the driver is available at this time.
Support for the PostgreSQL network protocol is quite new and should be viewed
as experimental. It should not be used for production applications.
<h3>
ODBC Installation
</h3>
<h3>
ODBC Installation
</h3>
<p>
<p>
Before the ODBC driver can be used, it needs to be installed. To do this,
First, the ODBC driver must be installed.
double click on h2odbcSetup.exe. If you do this the first time, it will ask you to locate the
Any recent PostgreSQL ODBC driver should work, however version 8.2.4 or newer is recommended.
driver dll (h2odbc.dll). If you already installed it, the ODBC administration dialog will open
The Windows version of the PostgreSQL ODBC driver is available at
where you can create new or modify existing data sources.
<a
href=
"http://www.postgresql.org/ftp/odbc/versions/msi"
>
http://www.postgresql.org/ftp/odbc/versions/msi
</a>
.
When you create a new H2 ODBC data source, a dialog window will appear
and ask for the database settings:
</p>
</p>
<img
src=
"odbcDataSource.png"
alt=
"ODBC Configuration"
/>
<h3>
Log Option
</h3>
The driver is able to log operations to a file.
To enable logging, the log file name must be set in the registry under the key
CURRENT_USER/Software/H2/ODBC/LogFile. This key will only be read when the
driver starts, so you need to make sure all applications that may use the driver
are closed before changing this setting.
If this registry entry is not found when the driver starts, logging is disabled.
A sample registry key file may look like this:
<pre>
Windows Registry Editor Version 5.00
[HKEY_CURRENT_USER\Software\H2\ODBC]
<h3>
Starting the Server
</h3>
"LogFile"="C:\\temp\\h2odbc.txt"
<p>
After installing the ODBC driver, start the H2 Server using the command line:
<pre>
java -cp h2.jar org.h2.tools.Server
</pre>
The PG Server (PG for PostgreSQL protocol) is started as well.
By default, databases are stored in the current working directory where the server is started.
Use -baseDir to save databases in another directory, for example the user home directory:
<pre>
java -cp h2.jar org.h2.tools.Server -baseDir ~
</pre>
</pre>
The PG server can be started and stopped from within a Java application as follows:
<pre>
Server server = Server.createPgServer(new String[]{"-baseDir", "~"});
server.start();
...
server.stop();
</pre>
By default, only connections from localhost are allowed. To allow remote connections, use
<code>
-pgAllowOthers true
</code>
when starting the server.
</p>
<h3>
ODBC Configuration
</h3>
<p>
After installing the driver, a new Data Source must be added. In Windows,
run
<code>
odbcad32.exe
</code>
to open the Data Source Administrator. Then click on 'Add...'
and select the PostgreSQL Unicode driver. Then click 'Finish'.
You will be able to change the connection properties:
</p>
<table>
<tr><th>
Property
</th><th>
Example
</th><th>
Remarks
</th></th>
<tr><td>
Data Source
</td><td>
H2 Test
</td><td>
The name of the ODBC Data Source
</td></tr>
<tr><td>
Database
</td><td>
test
</td>
<td>
The database name. Only simple names are supported at this time;
<br
/>
relative or absolute path are not supported in the database name.
<br
/>
By default, the database is stored in the current working directory
<br
/>
where the Server is started except when the -baseDir setting is used.
<br
/>
The name must be at least 3 characters.
</td></tr>
<tr><td>
Server
</td><td>
localhost
</td><td>
The server name or IP address.
<br
/>
By default, only remote connections are allowed
</td></tr>
<tr><td>
User Name
</td><td>
sa
</td><td>
The database user name.
</td></tr>
<tr><td>
SSL Mode
</td><td>
disabled
</td><td>
At this time, SSL is not supported.
</td></tr>
<tr><td>
Port
</td><td>
5435
</td><td>
The port where the PG Server is listening.
</td></tr>
<tr><td>
Password
</td><td>
sa
</td><td>
The database password.
</td></tr>
</table>
<p>
Afterwards, you may use this data source.
</p>
<h3>
PG Protocol Support Limitations
</h3>
<p>
At this time, only a subset of the PostgreSQL network protocol is implemented.
Also, there may be compatibility problems on the SQL level, with the catalog, or with text encoding.
Problems are fixed as they are found.
Currently, statements can not be cancelled when using the PG protocol.
</p>
<h3>
Security Considerations
</h3>
<h3>
Security Considerations
</h3>
Currently, the
ODBC does not encrypt the password before sending it over TCP/IP to the server
.
Currently, the
PG Server does not support challenge response or encrypt passwords
.
This may be a problem if an attacker can listen to the data transferred between the ODBC
client
This may be a problem if an attacker can listen to the data transferred between the ODBC
driver
and the server, because the password is readable to the attacker.
and the server, because the password is readable to the attacker.
Also, it is currently not possible to use encrypted SSL connections.
Also, it is currently not possible to use encrypted SSL connections.
The password for a data source is stored unencrypted in the registry.
Therefore the ODBC driver should not be used where security is important.
Therefore the ODBC driver should not be used where security is important.
<h3>
Uninstalling
</h3>
To uninstall the ODBC driver, double click on h2odbcUninstall.exe. This will uninstall the driver.
<br
/><a
name=
"acid"
></a>
<br
/><a
name=
"acid"
></a>
<h2>
ACID
</h2>
<h2>
ACID
</h2>
In the database world, ACID stands for:
In the database world, ACID stands for:
...
...
h2/src/docsrc/html/history.html
浏览文件 @
43214cca
...
@@ -39,7 +39,9 @@ Hypersonic SQL or HSQLDB. H2 is built from scratch.
...
@@ -39,7 +39,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 / 2007-TODO
</h3><ul>
<h3>
Version 1.0 / 2007-TODO
</h3><ul>
<li>
The default value for h2.defaultMaxMemoryUndo is now 50000.
<li>
</li><li>
The experimental H2 ODBC driver has been removed.
</li><li>
The default value for h2.defaultMaxMemoryUndo is now 50000.
This avoids out of memory problems when using very large transactions,
This avoids out of memory problems when using very large transactions,
however large transactions are slower because they are buffered to disk.
however large transactions are slower because they are buffered to disk.
To disable, use -Dh2.defaultMaxMemoryUndo=2000000000.
To disable, use -Dh2.defaultMaxMemoryUndo=2000000000.
...
...
h2/src/docsrc/html/odbcDataSource.png
deleted
100644 → 0
浏览文件 @
2531186c
8.0 KB
h2/src/installer/h2.nsi
浏览文件 @
43214cca
...
@@ -119,8 +119,6 @@ Section "All"
...
@@ -119,8 +119,6 @@ Section "All"
File /r /x CVS /x .cvsignore ..\..\bin\*.*
File /r /x CVS /x .cvsignore ..\..\bin\*.*
SetOutPath "$INSTDIR\docs"
SetOutPath "$INSTDIR\docs"
File /r /x CVS /x .cvsignore ..\..\docs\*.*
File /r /x CVS /x .cvsignore ..\..\docs\*.*
SetOutPath "$INSTDIR\odbc"
File /r /x CVS /x .cvsignore ..\..\odbc\*.*
SetOutPath "$INSTDIR\service"
SetOutPath "$INSTDIR\service"
File /r /x CVS /x .cvsignore /x .svn ..\..\service\*.*
File /r /x CVS /x .cvsignore /x .svn ..\..\service\*.*
SetOutPath "$INSTDIR"
SetOutPath "$INSTDIR"
...
...
h2/src/main/org/h2/engine/Constants.java
浏览文件 @
43214cca
...
@@ -50,7 +50,6 @@ import org.h2.message.TraceSystem;
...
@@ -50,7 +50,6 @@ import org.h2.message.TraceSystem;
* - table of contents
* - table of contents
* - Switch off auto-build
* - Switch off auto-build
* - ant all
* - ant all
* - Make sure odbc files are the
* - Copy the pdf file to h2/docs
* - Copy the pdf file to h2/docs
* - Make sure the build files are removed
* - Make sure the build files are removed
* - ant zip
* - ant zip
...
...
h2/src/main/org/h2/expression/Function.java
浏览文件 @
43214cca
...
@@ -58,7 +58,6 @@ import org.h2.value.ValueUuid;
...
@@ -58,7 +58,6 @@ import org.h2.value.ValueUuid;
*/
*/
public
class
Function
extends
Expression
implements
FunctionCall
{
public
class
Function
extends
Expression
implements
FunctionCall
{
// TODO functions: ODBC TIMESTAMPDIFF
// TODO functions: add function hashcode(value)
// TODO functions: add function hashcode(value)
public
static
final
int
ABS
=
0
,
ACOS
=
1
,
ASIN
=
2
,
ATAN
=
3
,
ATAN2
=
4
,
public
static
final
int
ABS
=
0
,
ACOS
=
1
,
ASIN
=
2
,
ATAN
=
3
,
ATAN2
=
4
,
...
...
h2/src/main/org/h2/index/LinearHashEntry.java
浏览文件 @
43214cca
...
@@ -10,6 +10,14 @@ import org.h2.value.Value;
...
@@ -10,6 +10,14 @@ import org.h2.value.Value;
* @author Thomas
* @author Thomas
*/
*/
public
class
LinearHashEntry
{
public
class
LinearHashEntry
{
// private LinearHashEntry(int home, int hash, Value key, int value) {
// this.home = home;
// this.hash = hash;
// this.key = key;
// this.value = value;
// }
public
int
home
;
public
int
home
;
public
int
hash
;
public
int
hash
;
public
Value
key
;
public
Value
key
;
...
...
h2/src/main/org/h2/server/OdbcServer.java
deleted
100644 → 0
浏览文件 @
2531186c
/*
* Copyright 2004-2006 H2 Group. Licensed under the H2 License, Version 1.0 (http://h2database.com/html/license.html).
* Initial Developer: H2 Group
*/
package
org
.
h2
.
server
;
import
java.io.IOException
;
import
java.net.InetAddress
;
import
java.net.ServerSocket
;
import
java.net.Socket
;
import
java.sql.SQLException
;
import
java.util.ArrayList
;
import
java.util.HashSet
;
import
org.h2.message.TraceSystem
;
import
org.h2.util.MathUtils
;
import
org.h2.util.NetUtils
;
/**
* @author Thomas
*/
public
class
OdbcServer
implements
Service
{
public
static
final
int
DEFAULT_PORT
=
9083
;
// also in the docs
private
int
port
=
OdbcServer
.
DEFAULT_PORT
;
private
boolean
stop
;
private
boolean
log
;
private
ServerSocket
serverSocket
;
private
HashSet
running
=
new
HashSet
();
private
String
baseDir
;
private
String
url
;
private
boolean
allowOthers
;
private
boolean
ifExists
;
private
Thread
listenerThread
;
boolean
getLog
()
{
return
log
;
}
void
log
(
String
s
)
{
if
(
log
)
{
System
.
out
.
println
(
s
);
}
}
synchronized
void
remove
(
OdbcServerThread
t
)
{
running
.
remove
(
t
);
}
void
logError
(
Exception
e
)
{
if
(
log
)
{
e
.
printStackTrace
();
}
}
public
void
init
(
String
[]
args
)
throws
Exception
{
port
=
DEFAULT_PORT
;
for
(
int
i
=
0
;
i
<
args
.
length
;
i
++)
{
String
a
=
args
[
i
];
if
(
a
.
equals
(
"-log"
))
{
log
=
Boolean
.
valueOf
(
args
[++
i
]).
booleanValue
();
}
else
if
(
a
.
equals
(
"-odbcPort"
))
{
port
=
MathUtils
.
decodeInt
(
args
[++
i
]);
}
else
if
(
a
.
equals
(
"-baseDir"
))
{
baseDir
=
args
[++
i
];
}
else
if
(
a
.
equals
(
"-odbcAllowOthers"
))
{
allowOthers
=
Boolean
.
valueOf
(
args
[++
i
]).
booleanValue
();
}
else
if
(
a
.
equals
(
"-ifExists"
))
{
ifExists
=
Boolean
.
valueOf
(
args
[++
i
]).
booleanValue
();
}
}
org
.
h2
.
Driver
.
load
();
url
=
"odbc://localhost:"
+
port
;
}
public
String
getURL
()
{
return
url
;
}
boolean
allow
(
Socket
socket
)
{
if
(
allowOthers
)
{
return
true
;
}
return
NetUtils
.
isLoopbackAddress
(
socket
);
}
public
void
start
()
throws
SQLException
{
serverSocket
=
NetUtils
.
createServerSocket
(
port
,
false
);
}
public
void
listen
()
{
listenerThread
=
Thread
.
currentThread
();
String
threadName
=
listenerThread
.
getName
();
try
{
while
(!
stop
)
{
Socket
s
=
serverSocket
.
accept
();
if
(!
allow
(
s
))
{
log
(
"Connection not allowed"
);
s
.
close
();
}
else
{
OdbcServerThread
c
=
new
OdbcServerThread
(
s
,
this
);
running
.
add
(
c
);
Thread
thread
=
new
Thread
(
c
);
thread
.
setName
(
threadName
+
" thread"
);
c
.
setThread
(
thread
);
thread
.
start
();
}
}
}
catch
(
Exception
e
)
{
if
(!
stop
)
{
e
.
printStackTrace
();
}
}
}
public
void
stop
()
{
// TODO server: share code between web and tcp servers
if
(!
stop
)
{
stop
=
true
;
if
(
serverSocket
!=
null
)
{
try
{
serverSocket
.
close
();
}
catch
(
IOException
e
)
{
// TODO log exception
e
.
printStackTrace
();
}
serverSocket
=
null
;
}
if
(
listenerThread
!=
null
)
{
try
{
listenerThread
.
join
(
1000
);
}
catch
(
InterruptedException
e
)
{
TraceSystem
.
traceThrowable
(
e
);
}
}
}
// TODO server: using a boolean 'now' argument? a timeout?
ArrayList
list
=
new
ArrayList
(
running
);
for
(
int
i
=
0
;
i
<
list
.
size
();
i
++)
{
OdbcServerThread
c
=
(
OdbcServerThread
)
list
.
get
(
i
);
c
.
close
();
try
{
c
.
getThread
().
join
(
100
);
}
catch
(
Exception
e
)
{
// TODO log exception
e
.
printStackTrace
();
}
}
}
public
boolean
isRunning
()
{
if
(
serverSocket
==
null
)
{
return
false
;
}
try
{
Socket
s
=
NetUtils
.
createSocket
(
InetAddress
.
getLocalHost
(),
serverSocket
.
getLocalPort
(),
false
);
s
.
close
();
return
true
;
}
catch
(
Exception
e
)
{
return
false
;
}
}
public
String
getBaseDir
()
{
return
baseDir
;
}
public
boolean
getAllowOthers
()
{
return
allowOthers
;
}
public
String
getType
()
{
return
"ODBC"
;
}
public
boolean
getIfExists
()
{
return
ifExists
;
}
}
h2/src/main/org/h2/server/OdbcServerThread.java
deleted
100644 → 0
浏览文件 @
2531186c
/*
* Copyright 2004-2006 H2 Group. Licensed under the H2 License, Version 1.0 (http://h2database.com/html/license.html).
* Initial Developer: H2 Group
*/
package
org
.
h2
.
server
;
import
java.io.BufferedInputStream
;
import
java.io.BufferedOutputStream
;
import
java.io.DataInputStream
;
import
java.io.DataOutputStream
;
import
java.io.IOException
;
import
java.io.InputStream
;
import
java.io.OutputStream
;
import
java.net.Socket
;
import
java.sql.Connection
;
import
java.sql.DatabaseMetaData
;
import
java.sql.DriverManager
;
import
java.sql.PreparedStatement
;
import
java.sql.ResultSet
;
import
java.sql.ResultSetMetaData
;
import
java.sql.SQLException
;
import
java.sql.Statement
;
import
java.sql.Types
;
import
java.util.HashMap
;
import
org.h2.engine.ConnectionInfo
;
import
org.h2.message.Message
;
import
org.h2.util.ObjectUtils
;
import
org.h2.util.JdbcUtils
;
import
org.h2.util.StringUtils
;
import
org.h2.value.DataType
;
/**
* @author Thomas
*/
public
class
OdbcServerThread
implements
Runnable
{
private
OdbcServer
server
;
private
Socket
socket
;
private
Connection
conn
;
private
DatabaseMetaData
meta
;
private
boolean
stop
;
private
int
cacheId
;
private
Object
cache
;
private
OdbcTransfer
transfer
;
private
Thread
thread
;
private
BufferedOutputStream
outBuff
;
private
HashMap
object
=
new
HashMap
();
private
int
nextId
;
OdbcServerThread
(
Socket
socket
,
OdbcServer
server
)
{
this
.
server
=
server
;
this
.
socket
=
socket
;
}
private
int
addObject
(
Object
o
)
{
int
id
=
nextId
++;
server
.
log
(
"addObj "
+
id
+
" "
+
o
);
object
.
put
(
ObjectUtils
.
getInteger
(
id
),
o
);
cacheId
=
id
;
cache
=
o
;
return
id
;
}
private
void
freeObject
(
int
id
)
{
if
(
cacheId
==
id
)
{
cacheId
=
-
1
;
cache
=
null
;
}
object
.
remove
(
ObjectUtils
.
getInteger
(
id
));
}
private
Object
getObject
(
int
id
)
{
if
(
id
==
cacheId
)
{
server
.
log
(
"getObj "
+
id
+
" "
+
cache
);
return
cache
;
}
server
.
log
(
"getObj "
+
id
+
" "
+
object
.
get
(
ObjectUtils
.
getInteger
(
id
)));
return
object
.
get
(
ObjectUtils
.
getInteger
(
id
));
}
public
void
run
()
{
try
{
server
.
log
(
"Connect"
);
InputStream
ins
=
socket
.
getInputStream
();
OutputStream
outs
=
socket
.
getOutputStream
();
DataInputStream
in
;
in
=
new
DataInputStream
(
new
BufferedInputStream
(
ins
,
OdbcTransfer
.
BUFFER_SIZE
));
outBuff
=
new
BufferedOutputStream
(
outs
,
OdbcTransfer
.
BUFFER_SIZE
);
DataOutputStream
out
=
new
DataOutputStream
(
outBuff
);
transfer
=
new
OdbcTransfer
(
in
,
out
);
outBuff
.
flush
();
while
(!
stop
)
{
process
();
outBuff
.
flush
();
}
server
.
log
(
"Disconnect"
);
}
catch
(
Exception
e
)
{
server
.
logError
(
e
);
}
}
public
void
close
()
{
try
{
stop
=
true
;
conn
.
close
();
socket
.
close
();
server
.
log
(
"Close"
);
}
catch
(
Exception
e
)
{
server
.
logError
(
e
);
}
conn
=
null
;
socket
=
null
;
server
.
remove
(
this
);
}
private
void
sendError
(
Throwable
e
)
throws
IOException
{
SQLException
s
=
Message
.
convert
(
e
);
server
.
log
(
"Exception "
+
s
);
s
.
printStackTrace
();
transfer
.
writeByte
((
byte
)
'E'
);
}
private
void
processResultSet
(
ResultSet
rs
)
throws
IOException
,
SQLException
{
int
id
=
addObject
(
rs
);
transfer
.
writeInt
(
id
);
ResultSetMetaData
m
=
rs
.
getMetaData
();
int
columnCount
=
m
.
getColumnCount
();
transfer
.
writeInt
(
columnCount
);
for
(
int
i
=
0
;
i
<
columnCount
;
i
++)
{
transfer
.
writeInt
(
mapType
(
m
.
getColumnType
(
i
+
1
)));
transfer
.
writeString
(
m
.
getTableName
(
i
+
1
));
transfer
.
writeString
(
m
.
getColumnLabel
(
i
+
1
));
transfer
.
writeInt
(
m
.
getPrecision
(
i
+
1
));
transfer
.
writeInt
(
m
.
getScale
(
i
+
1
));
transfer
.
writeInt
(
m
.
getColumnDisplaySize
(
i
+
1
));
}
}
private
void
setParameter
(
PreparedStatement
prep
,
int
index
,
int
type
)
throws
SQLException
,
IOException
{
switch
(
type
)
{
case
Types
.
NULL
:
{
// fake: use Integer data type for now
prep
.
setNull
(
index
,
Types
.
INTEGER
);
break
;
}
case
Types
.
INTEGER
:
{
int
value
=
transfer
.
readInt
();
server
.
log
(
" index="
+
index
+
" int="
+
value
);
prep
.
setInt
(
index
,
value
);
break
;
}
case
Types
.
VARCHAR
:
{
String
value
=
transfer
.
readString
();
server
.
log
(
" index="
+
index
+
" string="
+
value
);
prep
.
setString
(
index
,
value
);
break
;
}
default
:
throw
Message
.
getInternalError
(
"unexpected data type "
+
type
);
}
}
private
void
setParameters
(
PreparedStatement
prep
)
throws
SQLException
,
IOException
{
while
(
true
)
{
int
x
=
transfer
.
readByte
();
if
(
x
==
'0'
)
{
break
;
}
else
if
(
x
==
'1'
)
{
int
index
=
transfer
.
readInt
();
int
type
=
transfer
.
readInt
();
setParameter
(
prep
,
index
+
1
,
type
);
}
else
{
throw
Message
.
getInternalError
(
"unexpected "
+
x
);
}
}
}
private
void
processMeta
()
throws
IOException
{
int
operation
=
transfer
.
readByte
();
server
.
log
(
"meta op="
+(
char
)
operation
);
switch
(
operation
)
{
case
'B'
:
{
String
catalog
=
transfer
.
readString
();
String
schema
=
transfer
.
readString
();
String
table
=
transfer
.
readString
();
if
(
table
==
null
||
table
.
length
()==
0
)
{
table
=
"%"
;
}
int
scope
=
transfer
.
readInt
();
boolean
nullable
=
transfer
.
readBoolean
();
try
{
ResultSet
rs
=
meta
.
getBestRowIdentifier
(
catalog
,
schema
,
table
,
scope
,
nullable
);
processResultSet
(
rs
);
}
catch
(
Throwable
e
)
{
sendError
(
e
);
}
break
;
}
case
'C'
:
{
// String catalog = transfer.readString();
String
schemaPattern
=
transfer
.
readString
();
String
tableNamePattern
=
transfer
.
readString
();
String
columnNamePattern
=
transfer
.
readString
();
if
(
tableNamePattern
==
null
||
tableNamePattern
.
length
()==
0
)
{
tableNamePattern
=
"%"
;
}
if
(
columnNamePattern
==
null
||
columnNamePattern
.
length
()==
0
)
{
columnNamePattern
=
"%"
;
}
PreparedStatement
prep
=
null
;
try
{
prep
=
conn
.
prepareStatement
(
"SELECT "
+
"TABLE_CATALOG TABLE_CAT, "
+
"TABLE_SCHEMA TABLE_SCHEM, "
+
"TABLE_NAME, "
+
"COLUMN_NAME, "
+
"DATA_TYPE, "
+
"TYPE_NAME, "
+
"CHARACTER_MAXIMUM_LENGTH COLUMN_SIZE, "
+
"CHARACTER_MAXIMUM_LENGTH BUFFER_LENGTH, "
+
"CAST(NUMERIC_SCALE AS SMALLINT) DECIMAL_DIGITS, "
// different in JDBC
+
"CAST(10 AS SMALLINT) NUM_PREC_RADIX, "
// different in JDBC
+
"CAST(NULLABLE AS SMALLINT) NULLABLE, "
// different in JDBC
+
"'' REMARKS, "
+
"COLUMN_DEFAULT COLUMN_DEF, "
+
"CAST(DATA_TYPE AS SMALLINT) SQL_DATA_TYPE, "
// different in JDBC
+
"CAST(0 AS SMALLINT) SQL_DATETIME_SUB, "
// different in JDBC
+
"CHARACTER_OCTET_LENGTH CHAR_OCTET_LENGTH, "
+
"ORDINAL_POSITION ORDINAL_POSITION, "
+
"NULLABLE IS_NULLABLE "
+
"FROM INFORMATION_SCHEMA.COLUMNS "
+
"WHERE TABLE_SCHEMA LIKE ? "
+
"AND TABLE_NAME LIKE ? "
+
"AND COLUMN_NAME LIKE ? "
+
"ORDER BY TABLE_SCHEM, TABLE_NAME, ORDINAL_POSITION"
);
prep
.
setString
(
1
,
schemaPattern
==
null
?
"%"
:
schemaPattern
);
prep
.
setString
(
2
,
tableNamePattern
==
null
?
"%"
:
tableNamePattern
);
prep
.
setString
(
3
,
columnNamePattern
==
null
?
"%"
:
columnNamePattern
);
// ResultSet rs = meta.getColumns(catalog, schemaPattern, tableNamePattern, columnNamePattern);
ResultSet
rs
=
prep
.
executeQuery
();
processResultSet
(
rs
);
}
catch
(
SQLException
e
)
{
sendError
(
e
);
}
finally
{
JdbcUtils
.
closeSilently
(
prep
);
}
break
;
}
case
'D'
:
{
String
where
;
if
(
transfer
.
readByte
()==
'A'
)
{
where
=
""
;
}
else
{
int
type
=
transfer
.
readInt
();
where
=
" WHERE TYPE="
+
type
+
" "
;
}
Statement
stat
=
null
;
try
{
stat
=
conn
.
createStatement
();
ResultSet
rs
=
stat
.
executeQuery
(
"SELECT "
+
"TYPE_NAME, "
+
"DATA_TYPE, "
+
"PRECISION COLUMN_SIZE, "
+
"PREFIX LITERAL_PREFIX, "
+
"PREFIX LITERAL_SUFFIX, "
+
"PARAMS CREATE_PARAMS, "
+
"CAST("
+
DatabaseMetaData
.
typeNullable
+
" AS SMALLINT) NULLABLE, "
+
"CAST(1 AS SMALLINT) CASE_SENSITIVE, "
// TODO metadata: check if this is ok
+
"CAST(1 AS SMALLINT) SEARCHABLE, "
// TODO metadata: check if this is ok
+
"CAST(0 AS SMALLINT) UNSIGNED_ATTRIBUTE, "
// TODO metadata: check if this is ok
+
"CAST(0 AS SMALLINT) FIXED_PREC_SCALE, "
// TODO metadata: check if this is ok
+
"CAST(0 AS SMALLINT) AUTO_UNIQUE_VALUE, "
// TODO metadata: check if this is ok
+
"TYPE_NAME LOCAL_TYPE_NAME, "
+
"MINIMUM_SCALE, "
+
"MAXIMUM_SCALE, "
+
"DATA_TYPE SQL_DATA_TYPE, "
+
"CAST(1 AS SMALLINT) SQL_DATETIME_SUB, "
// TODO metadata: check if this is ok
+
"RADIX NUM_PREC_RADIX, "
+
"CAST(0 AS SMALLINT) INTERVAL_PRECISION "
+
"FROM INFORMATION_SCHEMA.TYPE_INFO "
+
where
+
"ORDER BY DATA_TYPE, POS"
);
processResultSet
(
rs
);
}
catch
(
SQLException
e
)
{
sendError
(
e
);
}
finally
{
JdbcUtils
.
closeSilently
(
stat
);
}
break
;
}
case
'I'
:
{
// String catalog = transfer.readString();
String
schemaPattern
=
transfer
.
readString
();
String
tableNamePattern
=
transfer
.
readString
();
if
(
tableNamePattern
==
null
||
tableNamePattern
.
length
()==
0
)
{
tableNamePattern
=
"%"
;
}
// boolean unique = transfer.readBoolean();
// boolean approximate = transfer.readBoolean();
PreparedStatement
prep
=
null
;
try
{
//ResultSet rs = meta.getIndexInfo(catalog, schemaPattern, tableNamePattern, unique, approximate);
prep
=
conn
.
prepareStatement
(
"SELECT "
+
"TABLE_CATALOG TABLE_CAT, "
+
"TABLE_SCHEMA TABLE_SCHEM, "
+
"TABLE_NAME, "
+
"CAST(NON_UNIQUE AS SMALLINT) NON_UNIQUE, "
+
"TABLE_CATALOG INDEX_QUALIFIER, "
+
"INDEX_NAME, "
+
"CAST("
+
DatabaseMetaData
.
tableIndexOther
+
" AS SMALLINT) TYPE, "
+
"ORDINAL_POSITION, "
+
"COLUMN_NAME, "
+
"'A' ASC_OR_DESC, "
+
"CARDINALITY, "
+
"0 PAGES, "
+
"'' FILTER_CONDITION "
+
"FROM INFORMATION_SCHEMA.INDEXES "
+
"WHERE CATALOG_NAME LIKE ? "
+
"AND TABLE_NAME LIKE ? "
+
"ORDER BY NON_UNIQUE, TYPE, TABLE_SCHEM, INDEX_NAME, ORDINAL_POSITION"
);
prep
.
setString
(
1
,
schemaPattern
);
prep
.
setString
(
2
,
tableNamePattern
);
ResultSet
rs
=
prep
.
executeQuery
();
processResultSet
(
rs
);
}
catch
(
SQLException
e
)
{
sendError
(
e
);
}
finally
{
JdbcUtils
.
closeSilently
(
prep
);
}
break
;
}
case
'N'
:
{
String
sql
=
transfer
.
readString
();
try
{
sql
=
conn
.
nativeSQL
(
sql
);
}
catch
(
SQLException
e
)
{
sendError
(
e
);
}
transfer
.
writeString
(
sql
);
break
;
}
case
'T'
:
{
String
catalog
=
transfer
.
readString
();
String
schema
=
transfer
.
readString
();
String
table
=
transfer
.
readString
();
String
tableTypes
=
transfer
.
readString
();
server
.
log
(
" catalog="
+
catalog
+
" schema="
+
schema
+
" table="
+
table
+
" tableTypes="
+
tableTypes
);
ResultSet
rs
;
String
[]
types
=
null
;
PreparedStatement
prep
=
null
;
try
{
if
(
catalog
.
equals
(
"%"
)
&&
schema
.
length
()==
0
&&
table
.
length
()==
0
)
{
server
.
log
(
" allCatalogs"
);
prep
=
conn
.
prepareStatement
(
"SELECT "
+
"CATALOG_NAME TABLE_CAT, "
+
"NULL TABLE_SCHEM, "
+
"NULL TABLE_NAME, "
+
"NULL TABLE_TYPE, "
+
"'' REMARKS "
+
"FROM INFORMATION_SCHEMA.CATALOGS"
);
rs
=
prep
.
executeQuery
();
}
else
if
(
catalog
.
length
()==
0
&&
schema
.
equals
(
"%"
)
&&
table
.
length
()==
0
)
{
server
.
log
(
" allSchemas"
);
prep
=
conn
.
prepareStatement
(
"SELECT "
+
"CATALOG_NAME TABLE_CAT, "
+
"SCHEMA_NAME TABLE_SCHEM, "
+
"NULL TABLE_NAME, "
+
"NULL TABLE_TYPE, "
+
"'' REMARKS "
+
"FROM INFORMATION_SCHEMA.SCHEMATA"
);
rs
=
prep
.
executeQuery
();
}
else
if
(
catalog
.
length
()==
0
&&
schema
.
length
()==
0
&&
table
.
length
()==
0
&&
tableTypes
.
equals
(
"%"
))
{
server
.
log
(
" allTableTypes"
);
prep
=
conn
.
prepareStatement
(
"SELECT "
+
"NULL TABLE_CAT, "
+
"NULL TABLE_SCHEM, "
+
"NULL TABLE_NAME, "
+
"TYPE TABLE_TYPE, "
+
"'' REMARKS "
+
"FROM INFORMATION_SCHEMA.TABLE_TYPES"
);
rs
=
prep
.
executeQuery
();
}
else
{
server
.
log
(
" getTables"
);
if
(
tableTypes
.
equals
(
"%"
)
||
tableTypes
.
length
()==
0
)
{
types
=
null
;
}
else
{
types
=
StringUtils
.
arraySplit
(
tableTypes
,
','
,
false
);
for
(
int
i
=
0
;
i
<
types
.
length
;
i
++)
{
String
t
=
StringUtils
.
toUpperEnglish
(
types
[
i
]);
if
(
t
.
startsWith
(
"\'"
))
{
t
=
t
.
substring
(
1
,
t
.
length
()-
2
);
}
types
[
i
]
=
t
;
}
}
server
.
log
(
"getTables "
+
catalog
+
" "
+
schema
+
" "
+
table
);
if
(
table
.
length
()
==
0
)
{
table
=
null
;
}
rs
=
meta
.
getTables
(
catalog
,
schema
,
table
,
types
);
}
processResultSet
(
rs
);
}
catch
(
SQLException
e
)
{
sendError
(
e
);
}
finally
{
JdbcUtils
.
closeSilently
(
prep
);
}
break
;
}
case
'V'
:
{
String
catalog
=
transfer
.
readString
();
String
schema
=
transfer
.
readString
();
String
table
=
transfer
.
readString
();
if
(
table
==
null
||
table
.
length
()==
0
)
{
table
=
"%"
;
}
try
{
ResultSet
rs
=
meta
.
getVersionColumns
(
catalog
,
schema
,
table
);
// PreparedStatement prep = conn.prepareStatement("SELECT "
// + "CAST(NULL AS INT) SCOPE, "
// + "NULL COLUMN_NAME, "
// + "CAST(NULL AS INT) DATA_TYPE, "
// + "NULL TYPE_NAME, "
// + "CAST(NULL AS INT) COLUMN_SIZE, "
// + "CAST(NULL AS INT) BUFFER_LENGTH, "
// + "CAST(NULL AS INT) DECIMAL_DIGITS, "
// + "CAST(NULL AS INT) PSEUDO_COLUMN "
// + "FROM SYSTEM_TABLES "
// + "WHERE 1=0");
// ResultSet rs = prep.executeQuery();
processResultSet
(
rs
);
}
catch
(
SQLException
e
)
{
sendError
(
e
);
}
break
;
}
default
:
server
.
log
(
"meta operation? "
+
(
char
)
operation
);
}
}
private
void
process
()
throws
IOException
{
int
operation
=
transfer
.
readByte
();
if
(
operation
==
-
1
)
{
stop
=
true
;
return
;
}
server
.
log
(
"op="
+(
char
)
operation
);
switch
(
operation
)
{
case
'A'
:
{
try
{
int
op
=
transfer
.
readByte
();
switch
(
op
)
{
case
'0'
:
server
.
log
(
"autoCommit false"
);
conn
.
setAutoCommit
(
false
);
break
;
case
'1'
:
server
.
log
(
"autoCommit true"
);
conn
.
setAutoCommit
(
true
);
break
;
case
'C'
:
server
.
log
(
"commit"
);
conn
.
commit
();
break
;
case
'R'
:
server
.
log
(
"rollback"
);
conn
.
rollback
();
break
;
default
:
server
.
log
(
"operation? "
+
(
char
)
operation
);
}
}
catch
(
SQLException
e
)
{
sendError
(
e
);
}
break
;
}
case
'C'
:
server
.
log
(
"connect"
);
String
db
=
transfer
.
readString
();
server
.
log
(
" db="
+
db
);
String
user
=
transfer
.
readString
();
server
.
log
(
" user="
+
user
);
String
password
=
transfer
.
readString
();
server
.
log
(
" password="
+
password
);
String
baseDir
=
server
.
getBaseDir
();
ConnectionInfo
ci
=
new
ConnectionInfo
(
db
);
if
(
baseDir
!=
null
)
{
ci
.
setBaseDir
(
baseDir
);
}
if
(
server
.
getIfExists
())
{
ci
.
setProperty
(
"IFEXISTS"
,
"TRUE"
);
}
String
dbName
=
ci
.
getDatabaseName
();
try
{
conn
=
DriverManager
.
getConnection
(
"jdbc:h2:"
+
dbName
,
user
,
password
);
meta
=
conn
.
getMetaData
();
transfer
.
writeByte
((
byte
)
'O'
);
}
catch
(
SQLException
e
)
{
sendError
(
e
);
}
break
;
case
'E'
:
{
String
sql
=
transfer
.
readString
();
server
.
log
(
"<"
+
sql
+
">"
);
try
{
int
params
=
getParametersCount
(
sql
);
if
(
params
>
0
)
{
// it is a prepared statement
PreparedStatement
prep
=
conn
.
prepareStatement
(
sql
);
int
id
=
addObject
(
prep
);
transfer
.
writeByte
((
byte
)
'O'
);
transfer
.
writeInt
(
id
);
transfer
.
writeInt
(
params
);
}
else
{
Statement
stat
=
null
;
try
{
stat
=
conn
.
createStatement
();
boolean
isResultSet
=
stat
.
execute
(
sql
);
if
(
isResultSet
)
{
transfer
.
writeByte
((
byte
)
'R'
);
ResultSet
rs
=
stat
.
getResultSet
();
processResultSet
(
rs
);
}
else
{
transfer
.
writeByte
((
byte
)
'U'
);
transfer
.
writeInt
(
stat
.
getUpdateCount
());
}
}
finally
{
JdbcUtils
.
closeSilently
(
stat
);
}
}
}
catch
(
SQLException
e
)
{
sendError
(
e
);
}
break
;
}
case
'F'
:
{
int
id
=
transfer
.
readInt
();
server
.
log
(
"free "
+
id
);
freeObject
(
id
);
break
;
}
case
'G'
:
{
int
objectId
=
transfer
.
readInt
();
ResultSet
rs
=
(
ResultSet
)
getObject
(
objectId
);
try
{
boolean
hasNext
=
rs
.
next
();
if
(
hasNext
)
{
transfer
.
writeByte
((
byte
)
'1'
);
ResultSetMetaData
m
=
rs
.
getMetaData
();
int
columnCount
=
m
.
getColumnCount
();
for
(
int
i
=
0
;
i
<
columnCount
;
i
++)
{
write
(
m
,
rs
,
i
);
}
}
else
{
transfer
.
writeByte
((
byte
)
'0'
);
}
}
catch
(
SQLException
e
)
{
sendError
(
e
);
}
break
;
}
case
'M'
:
processMeta
();
break
;
case
'P'
:
{
String
sql
=
transfer
.
readString
();
server
.
log
(
"<"
+
sql
+
">"
);
try
{
PreparedStatement
prep
=
conn
.
prepareStatement
(
sql
);
int
id
=
addObject
(
prep
);
transfer
.
writeByte
((
byte
)
'O'
);
transfer
.
writeInt
(
id
);
int
params
=
getParametersCount
(
sql
);
transfer
.
writeInt
(
params
);
}
catch
(
SQLException
e
)
{
sendError
(
e
);
}
break
;
}
case
'Q'
:
{
// executePrepared
int
id
=
transfer
.
readInt
();
PreparedStatement
prep
=
(
PreparedStatement
)
getObject
(
id
);
try
{
setParameters
(
prep
);
boolean
isResultSet
=
prep
.
execute
();
if
(
isResultSet
)
{
transfer
.
writeByte
((
byte
)
'R'
);
ResultSet
rs
=
prep
.
getResultSet
();
processResultSet
(
rs
);
}
else
{
transfer
.
writeByte
((
byte
)
'U'
);
transfer
.
writeInt
(
prep
.
getUpdateCount
());
}
}
catch
(
SQLException
e
)
{
sendError
(
e
);
}
break
;
}
case
'X'
:
stop
=
true
;
break
;
default
:
server
.
log
(
"operation? "
+
(
char
)
operation
);
}
}
private
void
write
(
ResultSetMetaData
m
,
ResultSet
rs
,
int
i
)
throws
IOException
{
try
{
int
type
=
mapType
(
m
.
getColumnType
(
i
+
1
));
switch
(
type
)
{
case
Types
.
SMALLINT
:
case
Types
.
INTEGER
:
{
int
value
=
rs
.
getInt
(
i
+
1
);
if
(
rs
.
wasNull
())
{
transfer
.
writeBoolean
(
true
);
}
else
{
transfer
.
writeBoolean
(
false
);
transfer
.
writeInt
(
value
);
}
break
;
}
case
Types
.
NULL
:
break
;
case
Types
.
VARCHAR
:
transfer
.
writeString
(
rs
.
getString
(
i
+
1
));
break
;
default
:
throw
Message
.
getInternalError
(
"unsupported data type "
+
type
);
}
}
catch
(
SQLException
e
)
{
sendError
(
e
);
}
}
int
mapType
(
int
sqlType
)
{
switch
(
sqlType
)
{
case
Types
.
SMALLINT
:
case
Types
.
INTEGER
:
case
Types
.
NULL
:
case
Types
.
VARCHAR
:
return
sqlType
;
case
Types
.
TINYINT
:
case
Types
.
BIT
:
case
DataType
.
TYPE_BOOLEAN
:
return
Types
.
INTEGER
;
case
Types
.
BIGINT
:
case
Types
.
BINARY
:
case
Types
.
BLOB
:
case
Types
.
CHAR
:
case
Types
.
DATE
:
case
Types
.
TIME
:
case
Types
.
TIMESTAMP
:
case
Types
.
DECIMAL
:
case
Types
.
DOUBLE
:
case
Types
.
FLOAT
:
case
Types
.
JAVA_OBJECT
:
case
Types
.
LONGVARBINARY
:
case
Types
.
LONGVARCHAR
:
case
Types
.
NUMERIC
:
case
Types
.
OTHER
:
case
Types
.
REAL
:
case
Types
.
VARBINARY
:
return
Types
.
VARCHAR
;
default
:
throw
Message
.
getInternalError
(
"sqlType "
+
sqlType
);
}
}
int
getParametersCount
(
String
sql
)
throws
SQLException
{
if
(
sql
==
null
||
sql
.
indexOf
(
'?'
)
<
0
)
{
return
0
;
}
int
len
=
sql
.
length
();
int
param
=
0
;
for
(
int
i
=
0
;
i
<
len
;
i
++)
{
try
{
char
c
=
sql
.
charAt
(
i
);
switch
(
c
)
{
case
'\''
:
{
int
j
=
sql
.
indexOf
(
'\''
,
i
+
1
);
if
(
j
<
0
)
{
throw
Message
.
getSyntaxError
(
sql
,
i
);
}
i
=
j
;
break
;
}
case
'"'
:
{
int
j
=
sql
.
indexOf
(
'"'
,
i
+
1
);
if
(
j
<
0
)
{
throw
Message
.
getSyntaxError
(
sql
,
i
);
}
i
=
j
;
break
;
}
case
'/'
:
{
if
(
sql
.
charAt
(
i
+
1
)
==
'*'
)
{
// block comment
int
j
=
sql
.
indexOf
(
"*/"
,
i
+
2
);
if
(
j
<
0
)
{
throw
Message
.
getSyntaxError
(
sql
,
i
);
}
i
=
j
+
1
;
}
else
if
(
sql
.
charAt
(
i
+
1
)
==
'/'
)
{
// single line comment
i
+=
2
;
while
(
i
<
len
&&
(
c
=
sql
.
charAt
(
i
))
!=
'\r'
&&
c
!=
'\n'
)
{
i
++;
}
}
break
;
}
case
'-'
:
if
(
sql
.
charAt
(
i
+
1
)
==
'-'
)
{
// single line comment
i
+=
2
;
while
(
i
<
len
&&
(
c
=
sql
.
charAt
(
i
))
!=
'\r'
&&
c
!=
'\n'
)
{
i
++;
}
}
break
;
case
'?'
:
param
++;
break
;
}
}
catch
(
ArrayIndexOutOfBoundsException
e
)
{
throw
Message
.
getSyntaxError
(
sql
,
i
);
}
}
return
param
;
}
public
void
setThread
(
Thread
thread
)
{
this
.
thread
=
thread
;
}
public
Thread
getThread
()
{
return
thread
;
}
}
h2/src/main/org/h2/server/OdbcTransfer.java
deleted
100644 → 0
浏览文件 @
2531186c
/*
* Copyright 2004-2006 H2 Group. Licensed under the H2 License, Version 1.0 (http://h2database.com/html/license.html).
* Initial Developer: H2 Group
*/
package
org
.
h2
.
server
;
import
java.io.DataInputStream
;
import
java.io.DataOutputStream
;
import
java.io.IOException
;
/**
* @author Thomas
*/
public
class
OdbcTransfer
{
static
final
int
BUFFER_SIZE
=
1024
;
private
DataInputStream
in
;
private
DataOutputStream
out
;
OdbcTransfer
(
DataInputStream
in
,
DataOutputStream
out
)
{
this
.
in
=
in
;
this
.
out
=
out
;
}
OdbcTransfer
writeBoolean
(
boolean
x
)
throws
IOException
{
writeInt
(
x
?
1
:
0
);
return
this
;
}
OdbcTransfer
writeOk
()
throws
IOException
{
writeBoolean
(
true
);
return
this
;
}
boolean
readBoolean
()
throws
IOException
{
return
readInt
()
==
1
;
}
OdbcTransfer
writeByte
(
byte
x
)
throws
IOException
{
out
.
write
(
x
);
return
this
;
}
int
readByte
()
throws
IOException
{
return
in
.
read
();
}
OdbcTransfer
writeShort
(
short
x
)
throws
IOException
{
return
writeInt
(
x
);
}
short
readShort
()
throws
IOException
{
return
(
short
)
readInt
();
}
OdbcTransfer
writeInt
(
int
i
)
throws
IOException
{
out
.
writeInt
(
i
);
return
this
;
}
int
readInt
()
throws
IOException
{
return
in
.
readInt
();
}
OdbcTransfer
writeLong
(
long
i
)
throws
IOException
{
out
.
writeLong
(
i
);
return
this
;
}
long
readLong
()
throws
IOException
{
return
in
.
readLong
();
}
OdbcTransfer
writeFloat
(
float
i
)
throws
IOException
{
out
.
writeFloat
(
i
);
return
this
;
}
float
readFloat
()
throws
IOException
{
return
in
.
readFloat
();
}
OdbcTransfer
writeDouble
(
double
i
)
throws
IOException
{
out
.
writeDouble
(
i
);
return
this
;
}
double
readDouble
()
throws
IOException
{
return
in
.
readDouble
();
}
OdbcTransfer
writeString
(
String
s
)
throws
IOException
{
if
(
s
==
null
)
{
out
.
writeInt
(-
1
);
}
else
{
out
.
writeInt
(
s
.
length
());
for
(
int
i
=
0
;
i
<
s
.
length
();
i
++)
{
out
.
write
(
s
.
charAt
(
i
));
}
}
return
this
;
}
String
readString
()
throws
IOException
{
int
len
=
in
.
readInt
();
if
(
len
==
-
1
)
{
return
null
;
}
char
[]
chars
=
new
char
[
len
];
for
(
int
i
=
0
;
i
<
len
;
i
++)
{
chars
[
i
]
=
(
char
)
in
.
readByte
();
}
return
new
String
(
chars
);
}
OdbcTransfer
writeDate
(
java
.
sql
.
Date
x
)
throws
IOException
{
if
(
x
==
null
)
{
writeString
(
null
);
}
else
{
writeString
(
x
.
toString
());
}
return
this
;
}
OdbcTransfer
writeTime
(
java
.
sql
.
Time
x
)
throws
IOException
{
if
(
x
==
null
)
{
writeString
(
null
);
}
else
{
writeString
(
x
.
toString
());
}
return
this
;
}
OdbcTransfer
writeTimestamp
(
java
.
sql
.
Timestamp
x
)
throws
IOException
{
if
(
x
==
null
)
{
writeString
(
null
);
}
else
{
writeString
(
x
.
toString
());
}
return
this
;
}
java
.
sql
.
Date
readDate
()
throws
IOException
{
String
s
=
readString
();
if
(
s
==
null
)
{
return
null
;
}
return
java
.
sql
.
Date
.
valueOf
(
s
);
}
java
.
sql
.
Time
readTime
()
throws
IOException
{
String
s
=
readString
();
if
(
s
==
null
)
{
return
null
;
}
return
java
.
sql
.
Time
.
valueOf
(
s
);
}
java
.
sql
.
Timestamp
readTimestamp
()
throws
IOException
{
String
s
=
readString
();
if
(
s
==
null
)
{
return
null
;
}
return
java
.
sql
.
Timestamp
.
valueOf
(
s
);
}
OdbcTransfer
writeByteArray
(
byte
[]
data
)
throws
IOException
{
if
(
data
==
null
)
{
writeInt
(-
1
);
}
else
{
writeInt
(
data
.
length
);
}
out
.
write
(
data
);
return
this
;
}
byte
[]
readByteArray
()
throws
IOException
{
int
len
=
readInt
();
if
(
len
==
-
1
)
{
return
null
;
}
byte
[]
b
=
new
byte
[
len
];
in
.
readFully
(
b
);
return
b
;
}
OdbcTransfer
writeIntArray
(
int
[]
s
)
throws
IOException
{
if
(
s
==
null
)
{
writeInt
(-
1
);
}
else
{
writeInt
(
s
.
length
);
for
(
int
i
=
0
;
i
<
s
.
length
;
i
++)
{
writeInt
(
s
[
i
]);
}
}
return
this
;
}
int
[]
readIntArray
()
throws
IOException
{
int
len
=
readInt
();
if
(
len
==
-
1
)
{
return
null
;
}
int
[]
s
=
new
int
[
len
];
for
(
int
i
=
0
;
i
<
len
;
i
++)
{
s
[
i
]
=
readInt
();
}
return
s
;
}
OdbcTransfer
writeStringArray
(
String
[]
s
)
throws
IOException
{
if
(
s
==
null
)
{
writeInt
(-
1
);
}
else
{
writeInt
(
s
.
length
);
for
(
int
i
=
0
;
i
<
s
.
length
;
i
++)
{
writeString
(
s
[
i
]);
}
}
return
this
;
}
String
[]
readStringArray
()
throws
IOException
{
int
len
=
readInt
();
if
(
len
==
-
1
)
{
return
null
;
}
String
[]
s
=
new
String
[
len
];
for
(
int
i
=
0
;
i
<
len
;
i
++)
{
s
[
i
]
=
readString
();
}
return
s
;
}
// buffer - cannot be null
OdbcTransfer
writeBuffer
(
byte
[]
buffer
)
throws
IOException
{
out
.
write
(
buffer
);
return
this
;
}
}
h2/src/main/org/h2/server/pg/PgServer.java
浏览文件 @
43214cca
...
@@ -38,11 +38,25 @@ public class PgServer implements Service {
...
@@ -38,11 +38,25 @@ public class PgServer implements Service {
private
boolean
allowOthers
;
private
boolean
allowOthers
;
private
boolean
ifExists
;
private
boolean
ifExists
;
public
static
void
main
(
String
[]
args
)
throws
Exception
{
public
void
init
(
String
[]
args
)
throws
Exception
{
PgServer
app
=
new
PgServer
();
port
=
DEFAULT_PORT
;
app
.
init
(
args
);
for
(
int
i
=
0
;
i
<
args
.
length
;
i
++)
{
app
.
start
();
String
a
=
args
[
i
];
app
.
listen
();
if
(
a
.
equals
(
"-log"
))
{
log
=
Boolean
.
valueOf
(
args
[++
i
]).
booleanValue
();
}
else
if
(
a
.
equals
(
"-pgPort"
))
{
port
=
MathUtils
.
decodeInt
(
args
[++
i
]);
}
else
if
(
a
.
equals
(
"-baseDir"
))
{
baseDir
=
args
[++
i
];
}
else
if
(
a
.
equals
(
"-pgAllowOthers"
))
{
allowOthers
=
Boolean
.
valueOf
(
args
[++
i
]).
booleanValue
();
}
else
if
(
a
.
equals
(
"-ifExists"
))
{
ifExists
=
Boolean
.
valueOf
(
args
[++
i
]).
booleanValue
();
}
}
org
.
h2
.
Driver
.
load
();
url
=
"pg://localhost:"
+
port
;
// log = true;
}
}
boolean
getLog
()
{
boolean
getLog
()
{
...
@@ -65,29 +79,6 @@ public class PgServer implements Service {
...
@@ -65,29 +79,6 @@ public class PgServer implements Service {
}
}
}
}
public
void
init
(
String
[]
args
)
throws
Exception
{
port
=
DEFAULT_PORT
;
for
(
int
i
=
0
;
i
<
args
.
length
;
i
++)
{
String
a
=
args
[
i
];
if
(
a
.
equals
(
"-log"
))
{
log
=
Boolean
.
valueOf
(
args
[++
i
]).
booleanValue
();
}
else
if
(
a
.
equals
(
"-pgPort"
))
{
port
=
MathUtils
.
decodeInt
(
args
[++
i
]);
}
else
if
(
a
.
equals
(
"-baseDir"
))
{
baseDir
=
args
[++
i
];
}
else
if
(
a
.
equals
(
"-pgAllowOthers"
))
{
allowOthers
=
Boolean
.
valueOf
(
args
[++
i
]).
booleanValue
();
}
else
if
(
a
.
equals
(
"-ifExists"
))
{
ifExists
=
Boolean
.
valueOf
(
args
[++
i
]).
booleanValue
();
}
}
org
.
h2
.
Driver
.
load
();
url
=
"pg://localhost:"
+
port
;
int
testing
;
log
=
true
;
}
public
String
getURL
()
{
public
String
getURL
()
{
return
url
;
return
url
;
}
}
...
@@ -129,7 +120,7 @@ public class PgServer implements Service {
...
@@ -129,7 +120,7 @@ public class PgServer implements Service {
}
}
public
void
stop
()
{
public
void
stop
()
{
// TODO server:
share code between web and tcp servers
// TODO server:
combine with tcp server
if
(!
stop
)
{
if
(!
stop
)
{
stop
=
true
;
stop
=
true
;
if
(
serverSocket
!=
null
)
{
if
(
serverSocket
!=
null
)
{
...
@@ -243,7 +234,7 @@ public class PgServer implements Service {
...
@@ -243,7 +234,7 @@ public class PgServer implements Service {
}
}
public
static
boolean
hasDatabasePrivilege
(
int
id
,
String
privilege
)
{
public
static
boolean
hasDatabasePrivilege
(
int
id
,
String
privilege
)
{
return
fals
e
;
return
tru
e
;
}
}
public
static
boolean
hasTablePrivilege
(
String
table
,
String
privilege
)
{
public
static
boolean
hasTablePrivilege
(
String
table
,
String
privilege
)
{
...
...
h2/src/main/org/h2/server/pg/PgServerThread.java
浏览文件 @
43214cca
...
@@ -26,7 +26,6 @@ import java.sql.Statement;
...
@@ -26,7 +26,6 @@ import java.sql.Statement;
import
java.sql.Types
;
import
java.sql.Types
;
import
java.util.HashMap
;
import
java.util.HashMap
;
import
java.util.HashSet
;
import
java.util.HashSet
;
import
java.util.Hashtable
;
import
java.util.Properties
;
import
java.util.Properties
;
import
org.h2.Driver
;
import
org.h2.Driver
;
...
@@ -37,7 +36,7 @@ import org.h2.util.ScriptReader;
...
@@ -37,7 +36,7 @@ import org.h2.util.ScriptReader;
* This class implements a subset of the PostgreSQL protocol as described here:
* This class implements a subset of the PostgreSQL protocol as described here:
* http://developer.postgresql.org/pgdocs/postgres/protocol.html
* http://developer.postgresql.org/pgdocs/postgres/protocol.html
* The PostgreSQL catalog is described here:
* The PostgreSQL catalog is described here:
* http://www.postgresql.org/docs/7.4/static/
view-pg-user.html
* http://www.postgresql.org/docs/7.4/static/
catalogs.html
* @author Thomas
* @author Thomas
*/
*/
...
@@ -117,17 +116,6 @@ public class PgServerThread implements Runnable {
...
@@ -117,17 +116,6 @@ public class PgServerThread implements Runnable {
}
}
private
void
error
(
String
message
,
Exception
e
)
{
private
void
error
(
String
message
,
Exception
e
)
{
int
todoDocumentLimitations
;
/*
Limitations:
- The database name can not contains the path (~ or directory).
Workaround: use -baseDir when starting the server.
- SSL is not supported.
- Statements can not be cancelled.
- Metadata is static.
*/
if
(
e
!=
null
)
{
if
(
e
!=
null
)
{
server
.
logError
(
e
);
server
.
logError
(
e
);
}
}
...
@@ -154,8 +142,7 @@ Limitations:
...
@@ -154,8 +142,7 @@ Limitations:
server
.
log
(
"Init"
);
server
.
log
(
"Init"
);
int
version
=
readInt
();
int
version
=
readInt
();
if
(
version
==
80877102
)
{
if
(
version
==
80877102
)
{
int
todoSupport
;
server
.
log
(
"CancelRequest (not supported)"
);
server
.
log
(
"CancelRequest"
);
server
.
log
(
" pid: "
+
readInt
());
server
.
log
(
" pid: "
+
readInt
());
server
.
log
(
" key: "
+
readInt
());
server
.
log
(
" key: "
+
readInt
());
error
(
"CancelRequest"
,
null
);
error
(
"CancelRequest"
,
null
);
...
@@ -382,7 +369,6 @@ Limitations:
...
@@ -382,7 +369,6 @@ Limitations:
private
String
getSQL
(
String
s
)
{
private
String
getSQL
(
String
s
)
{
String
lower
=
s
.
toLowerCase
();
String
lower
=
s
.
toLowerCase
();
int
todo
;
if
(
lower
.
startsWith
(
"show max_identifier_length"
))
{
if
(
lower
.
startsWith
(
"show max_identifier_length"
))
{
s
=
"CALL 63"
;
s
=
"CALL 63"
;
}
else
if
(
lower
.
startsWith
(
"set client_encoding to"
))
{
}
else
if
(
lower
.
startsWith
(
"set client_encoding to"
))
{
...
@@ -458,8 +444,7 @@ Limitations:
...
@@ -458,8 +444,7 @@ Limitations:
if
(
text
)
{
if
(
text
)
{
s
=
new
String
(
d2
,
getEncoding
());
s
=
new
String
(
d2
,
getEncoding
());
}
else
{
}
else
{
int
testing
;
server
.
logError
(
new
SQLException
(
"Binary format not supported"
));
System
.
out
.
println
(
"binary format!"
);
s
=
new
String
(
d2
,
getEncoding
());
s
=
new
String
(
d2
,
getEncoding
());
}
}
}
catch
(
Exception
e
)
{
}
catch
(
Exception
e
)
{
...
@@ -483,6 +468,7 @@ Limitations:
...
@@ -483,6 +468,7 @@ Limitations:
writeString
(
e
.
getMessage
());
writeString
(
e
.
getMessage
());
write
(
'D'
);
write
(
'D'
);
writeString
(
e
.
toString
());
writeString
(
e
.
toString
());
write
(
0
);
sendMessage
();
sendMessage
();
}
}
...
@@ -534,7 +520,7 @@ Limitations:
...
@@ -534,7 +520,7 @@ Limitations:
writeString
(
names
[
i
].
toLowerCase
());
writeString
(
names
[
i
].
toLowerCase
());
writeInt
(
0
);
// object ID
writeInt
(
0
);
// object ID
writeShort
(
0
);
// attribute number of the column
writeShort
(
0
);
// attribute number of the column
writeInt
(
getType
(
types
[
i
])
);
// data type
writeInt
(
types
[
i
]
);
// data type
writeShort
(
getTypeSize
(
types
[
i
]));
// pg_type.typlen
writeShort
(
getTypeSize
(
types
[
i
]));
// pg_type.typlen
writeInt
(
getModifier
(
types
[
i
]));
// pg_attribute.atttypmod
writeInt
(
getModifier
(
types
[
i
]));
// pg_attribute.atttypmod
writeShort
(
0
);
// text
writeShort
(
0
);
// text
...
@@ -546,15 +532,6 @@ Limitations:
...
@@ -546,15 +532,6 @@ Limitations:
}
}
}
}
private
int
getType
(
int
type
)
{
int
testing
;
// switch(type) {
// case Types.VARCHAR:
// return 19;
// }
return
type
;
}
private
int
getTypeSize
(
int
type
)
{
private
int
getTypeSize
(
int
type
)
{
switch
(
type
)
{
switch
(
type
)
{
case
Types
.
VARCHAR
:
case
Types
.
VARCHAR
:
...
@@ -590,8 +567,18 @@ Limitations:
...
@@ -590,8 +567,18 @@ Limitations:
}
}
private
void
initDb
()
throws
SQLException
{
private
void
initDb
()
throws
SQLException
{
int
todoUseVersionOnlyInitWhenRequired
;
ResultSet
rs
=
conn
.
getMetaData
().
getTables
(
null
,
"PG_CATALOG"
,
"PG_VERSION"
,
null
);
boolean
tableFound
=
rs
.
next
();
Statement
stat
=
conn
.
createStatement
();
Statement
stat
=
conn
.
createStatement
();
if
(
tableFound
)
{
rs
=
stat
.
executeQuery
(
"SELECT VERION FROM PG_CATALOG.PG_VERSION"
);
if
(
rs
.
next
())
{
if
(
rs
.
getInt
(
1
)
==
1
)
{
// already installed
return
;
}
}
}
Reader
r
=
new
InputStreamReader
(
getClass
().
getResourceAsStream
(
"pg_catalog.sql"
));
Reader
r
=
new
InputStreamReader
(
getClass
().
getResourceAsStream
(
"pg_catalog.sql"
));
r
=
new
BufferedReader
(
r
);
r
=
new
BufferedReader
(
r
);
ScriptReader
reader
=
new
ScriptReader
(
r
);
ScriptReader
reader
=
new
ScriptReader
(
r
);
...
@@ -604,52 +591,12 @@ Limitations:
...
@@ -604,52 +591,12 @@ Limitations:
}
}
reader
.
close
();
reader
.
close
();
ResultSet
rs
=
stat
.
executeQuery
(
"SELECT OID FROM PG_CATALOG.PG_TYPE"
);
rs
=
stat
.
executeQuery
(
"SELECT OID FROM PG_CATALOG.PG_TYPE"
);
while
(
rs
.
next
())
{
while
(
rs
.
next
())
{
types
.
add
(
new
Integer
(
rs
.
getInt
(
1
)));
types
.
add
(
new
Integer
(
rs
.
getInt
(
1
)));
}
}
}
}
// private void sendResultSet(ResultSet rs) throws SQLException, IOException {
// ResultSetMetaData meta = rs.getMetaData();
// int columnCount = meta.getColumnCount();
// //
// startMessage('T');
// writeShort(columnCount);
// for(int i=0; i<columnCount; i++) {
// writeString(meta.getColumnName(i + 1));
// writeInt(0); // table id
// writeShort(0); // column id
// writeInt(0); // data type id
// writeShort(26); // data type size (see pg_type.typlen)
// writeInt(4); // type modifier (see pg_attribute.atttypmod)
// writeShort(0); // format code 0=text, 1=binary
// }
// sendMessage();
// while(rs.next()) {
// // DataRow
// startMessage('D');
// writeShort(columnCount);
// for(int i=0; i<columnCount; i++) {
// String v = rs.getString(i + 1);
// if(v == null) {
// writeInt(-1);
// } else {
// byte[] data = v.getBytes();
// writeInt(data.length);
// write(data);
// }
// }
// sendMessage();
// }
//
// // CommandComplete
// startMessage('C');
// writeString("SELECT");
// sendMessage();
// sendReadyForQuery('I');
// }
public
void
close
()
{
public
void
close
()
{
try
{
try
{
stop
=
true
;
stop
=
true
;
...
...
h2/src/main/org/h2/server/pg/pg_catalog.sql
浏览文件 @
43214cca
...
@@ -6,6 +6,8 @@
...
@@ -6,6 +6,8 @@
drop
schema
if
exists
pg_catalog
;
drop
schema
if
exists
pg_catalog
;
create
schema
pg_catalog
;
create
schema
pg_catalog
;
create
table
pg_version
as
select
1
as
version
;
set
search_path
=
PUBLIC
,
pg_catalog
;
set
search_path
=
PUBLIC
,
pg_catalog
;
create
view
pg_catalog
.
pg_roles
-- (oid, rolname, rolcreaterole, rolcreatedb)
create
view
pg_catalog
.
pg_roles
-- (oid, rolname, rolcreaterole, rolcreatedb)
...
@@ -87,7 +89,9 @@ from information_schema.indexes;
...
@@ -87,7 +89,9 @@ from information_schema.indexes;
create
table
pg_catalog
.
pg_proc
(
create
table
pg_catalog
.
pg_proc
(
oid
int
,
oid
int
,
proname
varchar_ignorecase
proname
varchar_ignorecase
,
prorettype
int
,
pronamespace
int
);
);
create
table
pg_catalog
.
pg_trigger
(
create
table
pg_catalog
.
pg_trigger
(
...
...
h2/src/main/org/h2/tools/Console.java
浏览文件 @
43214cca
...
@@ -31,7 +31,7 @@ import org.h2.util.IOUtils;
...
@@ -31,7 +31,7 @@ import org.h2.util.IOUtils;
import
org.h2.util.StartBrowser
;
import
org.h2.util.StartBrowser
;
/**
/**
* This tool starts the H2 Console (web-) server, as well as the TCP and
ODBC
server.
* This tool starts the H2 Console (web-) server, as well as the TCP and
PG
server.
* For JDK 1.6, a system tray icon is created, for platforms that support it.
* For JDK 1.6, a system tray icon is created, for platforms that support it.
* Otherwise, a small window opens.
* Otherwise, a small window opens.
*
*
...
...
h2/src/main/org/h2/tools/Server.java
浏览文件 @
43214cca
...
@@ -12,7 +12,6 @@ import java.sql.SQLException;
...
@@ -12,7 +12,6 @@ import java.sql.SQLException;
import
org.h2.engine.Constants
;
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.OdbcServer
;
import
org.h2.server.Service
;
import
org.h2.server.Service
;
import
org.h2.server.TcpServer
;
import
org.h2.server.TcpServer
;
import
org.h2.server.ftp.FtpServer
;
import
org.h2.server.ftp.FtpServer
;
...
@@ -52,10 +51,6 @@ public class Server implements Runnable {
...
@@ -52,10 +51,6 @@ public class Server implements Runnable {
System
.
out
.
println
(
"-pgPort <port> (default: "
+
PgServer
.
DEFAULT_PORT
+
")"
);
System
.
out
.
println
(
"-pgPort <port> (default: "
+
PgServer
.
DEFAULT_PORT
+
")"
);
System
.
out
.
println
(
"-pgAllowOthers [true|false]"
);
System
.
out
.
println
(
"-pgAllowOthers [true|false]"
);
System
.
out
.
println
(
"-odbc (start the ODBC Server)"
);
System
.
out
.
println
(
"-odbcPort <port> (default: "
+
OdbcServer
.
DEFAULT_PORT
+
")"
);
System
.
out
.
println
(
"-odbcAllowOthers [true|false]"
);
System
.
out
.
println
(
"-ftp (start the FTP Server)"
);
System
.
out
.
println
(
"-ftp (start the FTP Server)"
);
System
.
out
.
println
(
"-ftpPort <port> (default: "
+
Constants
.
DEFAULT_FTP_PORT
+
")"
);
System
.
out
.
println
(
"-ftpPort <port> (default: "
+
Constants
.
DEFAULT_FTP_PORT
+
")"
);
System
.
out
.
println
(
"-ftpDir <directory> (default: "
+
FtpServer
.
DEFAULT_ROOT
+
", use jdbc:... to access a database)"
);
System
.
out
.
println
(
"-ftpDir <directory> (default: "
+
FtpServer
.
DEFAULT_ROOT
+
", use jdbc:... to access a database)"
);
...
@@ -74,7 +69,7 @@ public class Server implements Runnable {
...
@@ -74,7 +69,7 @@ public class Server implements Runnable {
/**
/**
* The command line interface for this tool.
* The command line interface for this tool.
* The options must be split into strings like this: "-baseDir", "/temp/data",...
* The options must be split into strings like this: "-baseDir", "/temp/data",...
* By default, -tcp, -web, -browser and -
odbc
are started.
* By default, -tcp, -web, -browser and -
pg
are started.
* If there is a problem starting a service, the program terminates with an exit code of 1.
* If there is a problem starting a service, the program terminates with an exit code of 1.
* The following options are supported:
* The following options are supported:
* <ul>
* <ul>
...
@@ -83,7 +78,6 @@ public class Server implements Runnable {
...
@@ -83,7 +78,6 @@ public class Server implements Runnable {
* </li><li>-tcp (start the TCP Server)
* </li><li>-tcp (start the TCP Server)
* </li><li>-tcpShutdown {url} (shutdown the running TCP Server, URL example: tcp://localhost:9094)
* </li><li>-tcpShutdown {url} (shutdown the running TCP Server, URL example: tcp://localhost:9094)
* </li><li>-pg (start the PG Server)
* </li><li>-pg (start the PG Server)
* </li><li>-odbc (start the ODBC Server)
* </li><li>-browser (start a browser and open a page to connect to the Web Server)
* </li><li>-browser (start a browser and open a page to connect to the Web Server)
* </li><li>-log [true|false] (enable or disable logging)
* </li><li>-log [true|false] (enable or disable logging)
* </li><li>-baseDir {directory} (sets the base directory for database files; not for H2 Console)
* </li><li>-baseDir {directory} (sets the base directory for database files; not for H2 Console)
...
@@ -102,8 +96,6 @@ public class Server implements Runnable {
...
@@ -102,8 +96,6 @@ public class Server implements Runnable {
* </li><li>-tcpShutdownForce [true|false] (don't wait for other connections to close)
* </li><li>-tcpShutdownForce [true|false] (don't wait for other connections to close)
* </li><li>-pgPort {port} (the port of PG Server, default: 5435)
* </li><li>-pgPort {port} (the port of PG Server, default: 5435)
* </li><li>-pgAllowOthers [true|false] (enable/disable remote connections)
* </li><li>-pgAllowOthers [true|false] (enable/disable remote connections)
* </li><li>-odbcPort {port} (the port of ODBC Server, default: 9083)
* </li><li>-odbcAllowOthers [true|false] (enable/disable remote connections)
* </li><li>-ftpPort {port}
* </li><li>-ftpPort {port}
* </li><li>-ftpDir {directory}
* </li><li>-ftpDir {directory}
* </li><li>-ftpRead {readUserName}
* </li><li>-ftpRead {readUserName}
...
@@ -122,7 +114,7 @@ public class Server implements Runnable {
...
@@ -122,7 +114,7 @@ public class Server implements Runnable {
}
}
private
int
run
(
String
[]
args
)
throws
SQLException
{
private
int
run
(
String
[]
args
)
throws
SQLException
{
boolean
tcpStart
=
false
,
odbcStart
=
false
,
pgStart
=
false
,
webStart
=
false
,
ftpStart
=
false
;
boolean
tcpStart
=
false
,
pgStart
=
false
,
webStart
=
false
,
ftpStart
=
false
;
boolean
browserStart
=
false
;
boolean
browserStart
=
false
;
boolean
tcpShutdown
=
false
,
tcpShutdownForce
=
false
;
boolean
tcpShutdown
=
false
,
tcpShutdownForce
=
false
;
String
tcpPassword
=
""
;
String
tcpPassword
=
""
;
...
@@ -136,9 +128,6 @@ public class Server implements Runnable {
...
@@ -136,9 +128,6 @@ public class Server implements Runnable {
}
else
if
(
a
.
equals
(
"-web"
))
{
}
else
if
(
a
.
equals
(
"-web"
))
{
startDefaultServers
=
false
;
startDefaultServers
=
false
;
webStart
=
true
;
webStart
=
true
;
}
else
if
(
a
.
equals
(
"-odbc"
))
{
startDefaultServers
=
false
;
odbcStart
=
true
;
}
else
if
(
a
.
equals
(
"-tcp"
))
{
}
else
if
(
a
.
equals
(
"-tcp"
))
{
startDefaultServers
=
false
;
startDefaultServers
=
false
;
tcpStart
=
true
;
tcpStart
=
true
;
...
@@ -165,7 +154,6 @@ public class Server implements Runnable {
...
@@ -165,7 +154,6 @@ public class Server implements Runnable {
if
(
startDefaultServers
)
{
if
(
startDefaultServers
)
{
tcpStart
=
true
;
tcpStart
=
true
;
pgStart
=
true
;
pgStart
=
true
;
odbcStart
=
false
;
webStart
=
true
;
webStart
=
true
;
browserStart
=
true
;
browserStart
=
true
;
}
}
...
@@ -196,17 +184,6 @@ public class Server implements Runnable {
...
@@ -196,17 +184,6 @@ public class Server implements Runnable {
}
}
System
.
out
.
println
(
pg
.
getStatus
());
System
.
out
.
println
(
pg
.
getStatus
());
}
}
if
(
odbcStart
)
{
Server
odbc
=
createOdbcServer
(
args
);
try
{
odbc
.
start
();
}
catch
(
SQLException
e
)
{
// ignore (status is displayed)
e
.
printStackTrace
();
exitCode
=
EXIT_ERROR
;
}
System
.
out
.
println
(
odbc
.
getStatus
());
}
if
(
webStart
)
{
if
(
webStart
)
{
Server
web
=
createWebServer
(
args
);
Server
web
=
createWebServer
(
args
);
try
{
try
{
...
@@ -341,15 +318,6 @@ public class Server implements Runnable {
...
@@ -341,15 +318,6 @@ public class Server implements Runnable {
return
new
Server
(
"H2 TCP Server"
,
new
TcpServer
(),
args
);
return
new
Server
(
"H2 TCP Server"
,
new
TcpServer
(),
args
);
}
}
/**
* Create a new ODBC server, but does not start it yet.
* @param args
* @return the server
*/
public
static
Server
createOdbcServer
(
String
[]
args
)
throws
SQLException
{
return
new
Server
(
"H2 ODBC Server"
,
new
OdbcServer
(),
args
);
}
/**
/**
* Create a new PG server, but does not start it yet.
* Create a new PG server, but does not start it yet.
* @param args
* @param args
...
...
h2/src/main/org/h2/util/Cache2Q.java
浏览文件 @
43214cca
...
@@ -17,7 +17,7 @@ public class Cache2Q implements Cache {
...
@@ -17,7 +17,7 @@ public class Cache2Q implements Cache {
public
static
final
String
TYPE_NAME
=
"TQ"
;
public
static
final
String
TYPE_NAME
=
"TQ"
;
private
static
final
int
MAIN
=
1
,
IN
=
2
,
OUT
=
3
;
private
static
final
int
MAIN
=
1
,
IN
=
2
,
OUT
=
3
;
private
final
static
int
PERCENT_IN
=
20
,
PERCENT_OUT
=
50
;
private
static
final
int
PERCENT_IN
=
20
,
PERCENT_OUT
=
50
;
private
final
CacheWriter
writer
;
private
final
CacheWriter
writer
;
private
int
maxSize
;
private
int
maxSize
;
...
@@ -160,7 +160,11 @@ public class Cache2Q implements Cache {
...
@@ -160,7 +160,11 @@ public class Cache2Q implements Cache {
int
i
=
0
;
int
i
=
0
;
ObjectArray
changed
=
new
ObjectArray
();
ObjectArray
changed
=
new
ObjectArray
();
while
(((
sizeIn
*
4
>
maxIn
*
3
)
||
(
sizeOut
*
4
>
maxOut
*
3
)
||
(
sizeMain
*
4
>
maxMain
*
3
))
&&
recordCount
>
Constants
.
CACHE_MIN_RECORDS
)
{
while
(((
sizeIn
*
4
>
maxIn
*
3
)
||
(
sizeOut
*
4
>
maxOut
*
3
)
||
(
sizeMain
*
4
>
maxMain
*
3
))
&&
recordCount
>
Constants
.
CACHE_MIN_RECORDS
)
{
if
(
i
++
>=
recordCount
)
{
i
++;
if
(
i
==
recordCount
)
{
writer
.
flushLog
();
}
if
(
i
>=
recordCount
*
2
)
{
// can't remove any record, because the log is not written yet
// can't remove any record, because the log is not written yet
// hopefully this does not happen too much, but it could happen theoretically
// hopefully this does not happen too much, but it could happen theoretically
// TODO log this
// TODO log this
...
...
h2/src/main/org/h2/util/CacheLRU.java
浏览文件 @
43214cca
...
@@ -90,23 +90,17 @@ public class CacheLRU implements Cache {
...
@@ -90,23 +90,17 @@ public class CacheLRU implements Cache {
int
i
=
0
;
int
i
=
0
;
ObjectArray
changed
=
new
ObjectArray
();
ObjectArray
changed
=
new
ObjectArray
();
while
(
sizeMemory
*
4
>
maxSize
*
3
&&
recordCount
>
Constants
.
CACHE_MIN_RECORDS
)
{
while
(
sizeMemory
*
4
>
maxSize
*
3
&&
recordCount
>
Constants
.
CACHE_MIN_RECORDS
)
{
CacheObject
last
=
head
.
next
;
i
++;
i
++;
if
(
i
==
recordCount
)
{
if
(
i
==
recordCount
)
{
int
testing
;
int
todoCopyTo2Q
;
System
.
out
.
println
(
"flush log"
);
writer
.
flushLog
();
writer
.
flushLog
();
}
}
if
(
i
>=
recordCount
*
2
)
{
if
(
i
>=
recordCount
*
2
)
{
// can't remove any record, because the log is not written yet
// can't remove any record, because the log is not written yet
// hopefully this does not happen too much, but it could happen theoretically
// hopefully this does not happen too much, but it could happen theoretically
// TODO log this
// TODO log this
System
.
out
.
println
(
"can not shrink cache"
);
break
;
break
;
}
}
CacheObject
last
=
head
.
next
;
if
(
Constants
.
CHECK
&&
last
==
head
)
{
if
(
Constants
.
CHECK
&&
last
==
head
)
{
throw
Message
.
getInternalError
(
"try to remove head"
);
throw
Message
.
getInternalError
(
"try to remove head"
);
}
}
...
...
h2/src/main/org/h2/value/DataType.java
浏览文件 @
43214cca
...
@@ -230,7 +230,6 @@ public class DataType {
...
@@ -230,7 +230,6 @@ public class DataType {
}
}
Value
.
getOrder
(
i
);
Value
.
getOrder
(
i
);
}
}
// TODO data types: try to support other types as well (longvarchar for odbc/access,...) - maybe map them to regular types?
}
}
private
static
void
add
(
int
type
,
int
sqlType
,
String
jdbc
,
DataType
dataType
,
String
[]
names
,
int
memory
)
{
private
static
void
add
(
int
type
,
int
sqlType
,
String
jdbc
,
DataType
dataType
,
String
[]
names
,
int
memory
)
{
...
...
h2/src/test/org/h2/test/TestAll.java
浏览文件 @
43214cca
...
@@ -201,7 +201,7 @@ CREATE TABLE TEST( ID BIGINT PRIMARY KEY, CREATED TIMESTAMP);
...
@@ -201,7 +201,7 @@ CREATE TABLE TEST( ID BIGINT PRIMARY KEY, CREATED TIMESTAMP);
INSERT INTO TEST VALUES(1, '2007-01-01 00:00:00');
INSERT INTO TEST VALUES(1, '2007-01-01 00:00:00');
SELECT * FROM TEST;
SELECT * FROM TEST;
Server: use one listener (detect if the request comes from an
ODBC
or TCP client).
Server: use one listener (detect if the request comes from an
PG
or TCP client).
PMD
PMD
...
...
h2/src/test/org/h2/test/bench/test.properties
浏览文件 @
43214cca
db2
=
H2, org.h2.Driver, jdbc:h2:data/test;LOCK_TIMEOUT=10000;LOCK_MODE=3, sa, sa
db1
=
H2, org.h2.Driver, jdbc:h2:data/test;LOCK_TIMEOUT=10000;LOCK_MODE=3, sa, sa
xdb2
=
H2 (XTEA), org.h2.Driver, jdbc:h2:data/test_xtea;LOCK_TIMEOUT=10000;LOCK_MODE=3;CIPHER=XTEA, sa, sa 123
xdb3
=
H2 (AES), org.h2.Driver, jdbc:h2:data/test_aes;LOCK_TIMEOUT=10000;LOCK_MODE=3;CIPHER=AES, sa, sa 123
xdb4
=
H2, org.h2.Driver, jdbc:h2:data/test;LOCK_TIMEOUT=10000;LOCK_MODE=3;write_mode_log=rws;write_delay=0, sa, sa
db1
=
H2_PG, org.postgresql.Driver, jdbc:postgresql://localhost:5435/h2test, sa, sa
#xdb2 = H2 (XTEA), org.h2.Driver, jdbc:h2:data/test_xtea;LOCK_TIMEOUT=10000;LOCK_MODE=3;CIPHER=XTEA, sa, sa 123
xdb2
=
HSQLDB, org.hsqldb.jdbcDriver, jdbc:hsqldb:data/test;hsqldb.default_table_type=cached;sql.enforce_size=true, sa
#xdb3 = H2 (AES), org.h2.Driver, jdbc:h2:data/test_aes;LOCK_TIMEOUT=10000;LOCK_MODE=3;CIPHER=AES, sa, sa 123
#xdb4 = H2, org.h2.Driver, jdbc:h2:data/test;LOCK_TIMEOUT=10000;LOCK_MODE=3;write_mode_log=rws;write_delay=0, sa, sa
#xdb5 = H2_PG, org.postgresql.Driver, jdbc:postgresql://localhost:5435/h2test, sa, sa
db2
=
HSQLDB, org.hsqldb.jdbcDriver, jdbc:hsqldb:data/test;hsqldb.default_table_type=cached;sql.enforce_size=true, sa
db3
=
Derby, org.apache.derby.jdbc.EmbeddedDriver, jdbc:derby:data/test;create=true, sa, sa
db3
=
Derby, org.apache.derby.jdbc.EmbeddedDriver, jdbc:derby:data/test;create=true, sa, sa
db4
=
H2, org.h2.Driver, jdbc:h2:tcp://localhost/data/testServer;LOCK_TIMEOUT=10000;LOCK_MODE=3, sa, sa
db4
=
H2, org.h2.Driver, jdbc:h2:tcp://localhost/data/testServer;LOCK_TIMEOUT=10000;LOCK_MODE=3, sa, sa
...
@@ -30,5 +30,4 @@ oracle.datetime = TIMESTAMP
...
@@ -30,5 +30,4 @@ oracle.datetime = TIMESTAMP
#test3 = org.h2.test.bench.BenchB
#test3 = org.h2.test.bench.BenchB
test1
=
org.h2.test.bench.BenchC
test1
=
org.h2.test.bench.BenchC
#size = 400
size
=
400
size
=
10
\ No newline at end of file
h2/src/test/org/h2/test/db/TestBackup.java
浏览文件 @
43214cca
...
@@ -7,7 +7,6 @@ package org.h2.test.db;
...
@@ -7,7 +7,6 @@ package org.h2.test.db;
import
java.sql.Connection
;
import
java.sql.Connection
;
import
java.sql.Statement
;
import
java.sql.Statement
;
import
org.h2.engine.Constants
;
import
org.h2.test.TestBase
;
import
org.h2.test.TestBase
;
import
org.h2.tools.Restore
;
import
org.h2.tools.Restore
;
...
...
h2/src/test/org/h2/test/testSimple.in.txt
浏览文件 @
43214cca
call
timestamp '2007-07-26 18:44:26.109000 +02:00';
select
timestamp '2007-07-26 18:44:26.109000 +02:00';
>
1
;
>
2007-07-26 18:44:26.109
;
create table test(id int primary key);
create table test(id int primary key);
begin;
begin;
...
...
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论