提交 8da94fcb authored 作者: Thomas Mueller's avatar Thomas Mueller

--no commit message

--no commit message
上级 2e63b5ff
......@@ -155,6 +155,8 @@
90132=Aggregate {0} not found
90133=Cannot change the setting {0} when the database is already open
90134=Access to the class {0} is denied
90135=The database is open in exclusive mode; can not open additional connections
90136=Unsupported outer join condition\: {0}
HY000=General error\: {0}
HY004=Unknown data type\: {0}
HYC00=Feature not supported
......
......@@ -2397,7 +2397,10 @@ public class Parser {
if (types[i] == CHAR_SPECIAL_2) {
i++;
}
// fall through
currentToken = sqlCommand.substring(start, i);
currentTokenType = getSpecialType(currentToken);
parseIndex = i;
return;
case CHAR_SPECIAL_1:
currentToken = sqlCommand.substring(start, i);
currentTokenType = getSpecialType(currentToken);
......@@ -2600,7 +2603,6 @@ public class Parser {
command[i] = ' ';
command[i + 1] = ' ';
i++;
break;
} else if (command[i + 1] == '/') {
// single line comment
changed = true;
......@@ -2613,9 +2615,10 @@ public class Parser {
command[i++] = ' ';
checkRunOver(i, len, startLoop);
}
break;
} else {
type = CHAR_SPECIAL_1;
}
// fall through
break;
case '-':
if (command[i + 1] == '-') {
// single line comment
......@@ -2629,9 +2632,10 @@ public class Parser {
command[i++] = ' ';
checkRunOver(i, len, startLoop);
}
break;
} else {
type = CHAR_SPECIAL_1;
}
// fall through
break;
case '(':
case ')':
case '{':
......
......@@ -549,6 +549,9 @@ public class Select extends Query {
Expression on = f.getJoinCondition();
if (on != null) {
if (!on.isEverything(ExpressionVisitor.EVALUATABLE)) {
if (f.isJoinOuter()) {
throw Message.getSQLException(ErrorCode.UNSUPPORTED_OUTER_JOIN_CONDITION_1, on.getSQL());
}
f.removeJoinCondition();
// need to check that all added are bound to a table
on = on.optimize(session);
......
......@@ -316,6 +316,7 @@ public class ErrorCode {
public static final int CANNOT_CHANGE_SETTING_WHEN_OPEN_1 = 90133;
public static final int ACCESS_DENIED_TO_CLASS_1 = 90134;
public static final int DATABASE_IS_IN_EXCLUSIVE_MODE = 90135;
public static final int UNSUPPORTED_OUTER_JOIN_CONDITION_1 = 90136;
/**
* INTERNAL
......
......@@ -127,6 +127,7 @@ public class ScanIndex extends BaseIndex {
row.setPos(key);
rows.set(key, row);
}
row.setDeleted(false);
}
if (database.isMultiVersion()) {
if (delta == null) {
......
......@@ -155,7 +155,8 @@
90132=Aggregat-Funktion {0} nicht gefunden
90133=Kann das Setting {0} nicht \u00E4ndern wenn die Datenbank bereits ge\u00F6ffnet ist
90134=Der Zugriff auf die Klasse {0} ist nicht erlaubt
90135=Die Datenbank befindet sich im Exclusiv Modus; es können keine zusätzlichen Verbindungen geöffnet werden
90135=Die Datenbank befindet sich im Exclusiv Modus; es k\u00F6nnen keine zus\u00E4tzlichen Verbindungen ge\u00F6ffnet werden
90136=Diese Outer Join Bedingung wird nicht unterst\u00FCtzt\: {0}
HY000=Allgemeiner Fehler\: {0}
HY004=Unbekannter Datentyp\: {0}
HYC00=Dieses Feature wird unterst\u00FCtzt
......
......@@ -156,6 +156,7 @@
90133=Cannot change the setting {0} when the database is already open
90134=Access to the class {0} is denied
90135=The database is open in exclusive mode; can not open additional connections
90136=Unsupported outer join condition\: {0}
HY000=General error\: {0}
HY004=Unknown data type\: {0}
HYC00=Feature not supported
......
......@@ -156,6 +156,7 @@
90133=\#Cannot change the setting {0} when the database is already open
90134=\#Access to the class {0} is denied
90135=\#The database is open in exclusive mode; can not open additional connections
90136=\#Unsupported outer join condition\: {0}
HY000=\u4E00\u822C\u30A8\u30E9\u30FC\: {0}
HY004=\u4E0D\u660E\u306A\u30C7\u30FC\u30BF\u578B\: {0}
HYC00=\u6A5F\u80FD\u306F\u30B5\u30DD\u30FC\u30C8\u3055\u308C\u3066\u3044\u307E\u305B\u3093
......
......@@ -156,6 +156,7 @@
90133=\#Cannot change the setting {0} when the database is already open
90134=\#Access to the class {0} is denied
90135=\#The database is open in exclusive mode; can not open additional connections
90136=\#Unsupported outer join condition\: {0}
HY000=Blad ogolny\: {0}
HY004=Nieznany typ danyche\: {0}
HYC00=Cecha nie jest wspierana
......
......@@ -156,6 +156,7 @@
90133=\#Cannot change the setting {0} when the database is already open
90134=\#Access to the class {0} is denied
90135=\#The database is open in exclusive mode; can not open additional connections
90136=\#Unsupported outer join condition\: {0}
HY000=Erro geral\: {0}
HY004=Tipo de dados desconhecido\: {0}
HYC00=Recurso n\u00E3o suportado
......
......@@ -91,6 +91,12 @@ public class FtpControl extends Thread {
return;
}
server.log(">" + command);
FtpEventListener listener = server.getEventListener();
FtpEvent event = null;
if (listener != null) {
event = new FtpEvent(this, command, param);
listener.beforeCommand(event);
}
replied = false;
if (connected) {
processConnected(command, param);
......@@ -126,8 +132,12 @@ public class FtpControl extends Thread {
}
}
if (!replied) {
listener.onUnsupportedCommand(event);
reply(506, "Invalid command");
}
if (listener != null) {
listener.afterCommand(event);
}
}
private void processConnected(String command, String param) throws SQLException, IOException {
......
/*
* Copyright 2004-2007 H2 Group. Licensed under the H2 License, Version 1.0 (http://h2database.com/html/license.html).
* Initial Developer: H2 Group
*/
package org.h2.server.ftp;
/**
* Describes an FTP event. This class is used by the FtpEventListener.
*/
public class FtpEvent {
private final FtpControl control;
private final String command;
private final String param;
FtpEvent(FtpControl control, String command, String param) {
this.control = control;
this.command = command;
this.param = param;
}
/**
* Get the FTP command. Example: RETR
*
* @return the command
*/
public String getCommand() {
return command;
}
/**
* Get the FTP control object.
*
* @return the control object
*/
public FtpControl getControl() {
return control;
}
/**
* Get the parameter of the FTP command (if any).
*
* @return the parameter
*/
public String getParam() {
return param;
}
}
/*
* Copyright 2004-2007 H2 Group. Licensed under the H2 License, Version 1.0 (http://h2database.com/html/license.html).
* Initial Developer: H2 Group
*/
package org.h2.server.ftp;
/**
* Event listener for the FTP Server.
*/
public interface FtpEventListener {
/**
* Called before the given command is processed.
*
* @param event the event
*/
void beforeCommand(FtpEvent event);
/**
* Called after the command has been processed.
*
* @param event the event
*/
void afterCommand(FtpEvent event);
/**
* Called when an unsupported command is processed.
* This method is called after beforeCommand.
*
* @param event the event
*/
void onUnsupportedCommand(FtpEvent event);
}
......@@ -56,6 +56,8 @@ public class FtpServer implements Service {
private boolean allowTask;
static final String TASK_SUFFIX = ".task";
private FtpEventListener eventListener;
public void listen() {
try {
while (serverSocket != null) {
......@@ -311,8 +313,31 @@ public class FtpServer implements Service {
p.destroy();
}
/**
* Get the file system used by this FTP server.
*
* @return the file system
*/
public FileSystem getFileSystem() {
return fs;
}
/**
* Set the event listener. Only one listener can be registered.
*
* @param eventListener the new listener, or null to de-register
*/
public void setEventListener(FtpEventListener eventListener) {
this.eventListener = eventListener;
}
/**
* Get the registered event listener.
*
* @return the event listener, or null if non is registered
*/
public FtpEventListener getEventListener() {
return eventListener;
}
}
......@@ -336,8 +336,6 @@ public class DiskFile implements CacheWriter {
Record rec = (Record) list.get(i);
writeBack(rec);
}
// TODO flush performance: maybe it would be faster to write records in
// the same loop
for (int i = 0; i < fileBlockCount; i++) {
i = deleted.nextSetBit(i);
if (i < 0) {
......@@ -351,32 +349,33 @@ public class DiskFile implements CacheWriter {
}
}
public void flushNew() throws SQLException {
int todoTest;
synchronized (database) {
database.checkPowerOff();
ObjectArray list = cache.getAllChanged();
CacheObject.sort(list);
int deletePos = deleted.nextSetBit(0);
int writeIndex = 0;
Record writeRecord = null;
while (true) {
if (writeRecord == null && writeIndex < list.size()) {
writeRecord = (Record) list.get(writeIndex++);
}
if (writeRecord != null && (deletePos < 0 || writeRecord.getPos() < deletePos)) {
writeBack(writeRecord);
writeRecord = null;
} else if (deletePos < fileBlockCount && deletePos >= 0) {
writeDirectDeleted(deletePos, 1);
deleted.clear(deletePos);
deletePos = deleted.nextSetBit(deletePos);
} else {
break;
}
}
}
}
// this implementation accesses the file in a linear way
// public void flushNew() throws SQLException {
// int todoTest;
// synchronized (database) {
// database.checkPowerOff();
// ObjectArray list = cache.getAllChanged();
// CacheObject.sort(list);
// int deletePos = deleted.nextSetBit(0);
// int writeIndex = 0;
// Record writeRecord = null;
// while (true) {
// if (writeRecord == null && writeIndex < list.size()) {
// writeRecord = (Record) list.get(writeIndex++);
// }
// if (writeRecord != null && (deletePos < 0 || writeRecord.getPos() < deletePos)) {
// writeBack(writeRecord);
// writeRecord = null;
// } else if (deletePos < fileBlockCount && deletePos >= 0) {
// writeDirectDeleted(deletePos, 1);
// deleted.clear(deletePos);
// deletePos = deleted.nextSetBit(deletePos);
// } else {
// break;
// }
// }
// }
// }
public void close() throws SQLException {
synchronized (database) {
......
......@@ -31,7 +31,6 @@ public class FileLister {
* files are included. If false, only data, index and log files
* are returned
* @return the list of files
* @throws SQLException
*/
public static ArrayList getDatabaseFiles(String dir, String db, boolean all) throws SQLException {
if (dir == null || dir.equals("")) {
......
......@@ -347,15 +347,6 @@ public class Csv implements SimpleRowSource {
continue;
} else if (ch == fieldSeparatorRead) {
break;
} else if (ch == commentLineStart) {
while (true) {
ch = readChar();
if (ch < 0 || ch == '\r' || ch == '\n') {
break;
}
}
endOfLine = true;
break;
} else if (ch == fieldDelimiter) {
StringBuffer buff = new StringBuffer();
boolean containsEscape = false;
......@@ -406,6 +397,15 @@ public class Csv implements SimpleRowSource {
}
}
break;
} else if (ch == commentLineStart) {
while (true) {
ch = readChar();
if (ch < 0 || ch == '\r' || ch == '\n') {
break;
}
}
endOfLine = true;
break;
} else {
StringBuffer buff = new StringBuffer();
buff.append((char) ch);
......@@ -433,13 +433,22 @@ public class Csv implements SimpleRowSource {
private String unEscape(String s) {
StringBuffer buff = new StringBuffer(s.length());
int start = 0;
char[] chars = null;
while (true) {
int idx = s.indexOf(escapeCharacter, start);
if (idx < 0) {
break;
}
buff.append(s.toCharArray(), start, idx);
start = idx + 1;
if (chars == null) {
chars = s.toCharArray();
}
buff.append(chars, start, idx - start);
if (idx == s.length() - 1) {
start = s.length();
break;
}
buff.append(chars[idx + 1]);
start = idx + 2;
}
buff.append(s.substring(start));
return buff.toString();
......
......@@ -534,4 +534,13 @@ public class Server implements Runnable, ShutdownHandler {
stopAll();
}
}
/**
* Get the service attached to this server.
*
* @return the service
*/
public Service getService() {
return service;
}
}
......@@ -12,6 +12,11 @@ import org.h2.tools.Script;
import org.h2.tools.DeleteDbFiles;
import org.h2.tools.RunScript;
/**
* This sample application shows how to compact the database files.
* This is done by creating a SQL script, and then re-creating the database
* using this script.
*/
public class Compact {
public static void main(String[] args) throws Exception {
DeleteDbFiles.execute("data", "test", true);
......
......@@ -11,6 +11,11 @@ import java.sql.Types;
import org.h2.tools.Csv;
import org.h2.tools.SimpleResultSet;
/**
* This sample application shows how to use the CSV tool
* to write CSV (comma separated values) files, and
* how to use the tool to read such files.
*/
public class CsvSample {
public static void main(String[] args) throws Exception {
CsvSample.write();
......
......@@ -11,6 +11,10 @@ import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
/**
* This sample application shows how to create a user defined function
* to read a file from the file system.
*/
public class FileFunctions {
public static void main(String[] args) throws Exception {
......
......@@ -14,6 +14,10 @@ import java.sql.Types;
import org.h2.tools.SimpleResultSet;
/**
* This sample application shows how to define and use
* custom (user defined) functions in this database.
*/
public class Function {
public static void main(String[] args) throws Exception {
......
......@@ -14,6 +14,12 @@ import java.sql.Types;
import org.h2.tools.SimpleResultSet;
/**
* User defined functions can return a result set,
* and can therefore be used like a table.
* This sample application uses such a function to convert
* polar to cartesian coordinates.
*/
public class FunctionMultiReturn {
public static void main(String[] args) throws Exception {
......
......@@ -13,6 +13,9 @@ import java.sql.Statement;
import org.h2.tools.RunScript;
/**
* In this example a database is initialized from compressed script in a jar file.
*/
public class InitDatabaseFromJar {
public static void main(String[] args) throws Exception {
......
......@@ -10,11 +10,16 @@ import java.sql.SQLException;
import java.sql.Statement;
import org.h2.tools.Server;
/**
* This sample program opens the same database once in embedded mode,
* and once in the server mode. The embedded mode is faster, but only
* the server mode supports remote connections.
*/
public class MixedMode {
public static void main(String[] args) throws Exception {
// start the server, allows to access the database remotly
Server server = Server.createTcpServer(new String[]{"-tcpPort", "9081"});
Server server = Server.createTcpServer(new String[] { "-tcpPort", "9081" });
server.start();
System.out.println("You can access the database remotely now, using the URL:");
System.out.println("jdbc:h2:tcp://localhost:9081/~/test (user: sa, password: sa)");
......
......@@ -16,6 +16,10 @@ import java.sql.ResultSet;
import org.h2.tools.RunScript;
import org.h2.util.StringUtils;
/**
* The newsfeed application uses XML functions to create an RSS and Atom feed
* from a simple SQL script. A textual representation of the data is created as well.
*/
public class Newsfeed {
public static void main(String[] args) throws Exception {
Class.forName("org.h2.Driver");
......
......@@ -13,10 +13,16 @@ import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
/**
* SQL Injection is a common security vulnerability for applications that use database.
* It is one of the most common security vulnerabilities for web applications today.
* This sample application shows how SQL injection works, and how to protect
* the application from it.
*/
public class SQLInjection {
Connection conn;
Statement stat;
private Connection conn;
private Statement stat;
public static void main(String[] args) throws Exception {
new SQLInjection().run("org.h2.Driver",
......@@ -47,14 +53,14 @@ public class SQLInjection {
stat.execute("INSERT INTO USERS VALUES(2, 'guest', '123456')");
stat.execute("INSERT INTO USERS VALUES(3, 'test', 'abc')");
// loginByNameInsecure();
loginByNameInsecure();
if (url.startsWith("jdbc:h2:")) {
// loginStoredProcedureInsecure();
loginStoredProcedureInsecure();
limitRowAccess();
}
// loginByNameSecure();
loginByNameSecure();
if (url.startsWith("jdbc:h2:")) {
stat.execute("SET ALLOW_LITERALS NONE");
......@@ -62,8 +68,8 @@ public class SQLInjection {
stat.execute("SET ALLOW_LITERALS ALL");
}
// loginByIdInsecure();
// loginByIdSecure();
loginByIdInsecure();
loginByIdSecure();
try {
stat.execute("DROP TABLE ITEMS");
......@@ -89,12 +95,12 @@ public class SQLInjection {
listActiveItemsUsingConstants();
}
// listItemsSortedInsecure();
// listItemsSortedSecure();
listItemsSortedInsecure();
listItemsSortedSecure();
if (url.startsWith("jdbc:h2:")) {
listItemsSortedSecureParam();
// storePasswordHashWithSalt();
storePasswordHashWithSalt();
}
conn.close();
......
......@@ -13,6 +13,11 @@ import java.sql.Statement;
import org.h2.api.DatabaseEventListener;
import org.h2.jdbc.JdbcConnection;
/**
* This example application implements a database event listener.
* This is useful to display progress information while opening a large database,
* or to log database exceptions.
*/
public class ShowProgress implements DatabaseEventListener {
private long last, start;
......
......@@ -4,6 +4,10 @@
*/
package org.h2.samples;
/**
* This very simple sample application stops a H2 TCP server
* if it is running.
*/
public class ShutdownServer {
public static void main(String[] args) throws Exception {
org.h2.tools.Server.shutdownTcpServer("tcp://localhost:9094", "", false);
......
......@@ -14,6 +14,9 @@ import java.sql.Statement;
import org.h2.api.Trigger;
/**
* This sample application shows how to use database triggers.
*/
public class TriggerSample {
public static void main(String[] args) throws Exception {
......
<?xml version="1.0"?>
<rss version="2.0">
<channel>
<title>H2 Database Engine</title>
<link>http://www.h2database.com</link>
<description>H2 Database Engine</description>
<language>en-us</language>
<pubDate>Thu, 15 Jun 2006 05:59:06 GMT</pubDate>
<lastBuildDate>Thu, 15 Jun 2006 05:59:06 GMT</lastBuildDate>
<item>
<title>New version available: 0.9 Alpha / 2006-06-02</title>
<link>http://www.h2database.com</link>
<description>
<![CDATA[A new version of H2 is available for download at http://www.h2database.com
Changes and new functionality:
- The GCJ version for Windows is no longer included in the download.
It was not stable in this release.
- ORDER BY now uses an index if possible.
Queries with LIMIT with ORDER BY
are faster when the index can be used.
- Statements containing LIKE are now re-compiled when executed.
Depending on the data, an index on the column is used or not.
- New option to disable automatic closing of a database
when the virtual machine exits.
Database URL: jdbc:h2:test;db_close_on_exit=false
- New event: DatabaseEventListener.closingDatabase()
- Connection.getCatalog() now returns the database name
- The function DATABASE() now return the short name
- Automatic starting of a web browser for Mac OS X should work now.
Security:
- TCP Server: Can now specify a password (tcpPassword).
- New option -ifExists for the TCP and ODBC server
to disallow creating new databases.
Bugfixes:
- Issue #103: Shutdown of a TCP Server from command line
didn't always work.
- Issue #104: A HAVING condition on a column
that was not in the GROUP BY list didn't work.
- Issue #105: RUNSCRIPT (the command) didn't commit
after each command if autocommit was on.
- Issue #106: SET commands where not persisted
- Issue# 107: When executing scripts that contained inserts
with many columns, an OutOfMemory error could occur.
- Issue #108: There is a concurrency problem when multi threads
access the same database.
- Issue #109: ALTER TABLE ADD COLUMN can make
the database unusable.
For details see also the history. The plans for the next release are:
- Bugfixes, write more tests, more bugfixes, more tests
- Define which modules are alpha, beta and production quality
- Proposal for changed license (still pending...)
- For other plans, see the new 'Roadmap' part on the web site
]]>
</description>
</item>
</channel>
</rss>
......@@ -63,7 +63,8 @@ import org.h2.test.jdbc.TestTransactionIsolation;
import org.h2.test.jdbc.TestUpdatableResultSet;
import org.h2.test.jdbc.TestZloty;
import org.h2.test.jdbc.xa.TestXA;
import org.h2.test.mvcc.TestMVCC;
import org.h2.test.mvcc.TestMvcc1;
import org.h2.test.mvcc.TestMvcc2;
import org.h2.test.server.TestNestedLoop;
import org.h2.test.server.TestPgServer;
import org.h2.test.server.TestWeb;
......@@ -153,7 +154,19 @@ java org.h2.test.TestAll timer
/*
C:\temp\test\db
documentation: package.html
write to the db file what version was used to create a database
History:
CSV tool: the character # could not be used as a separator when reading.
CSV tool: some escape/separator character combinations did not work. Fixed.
Roadmap:
remove
* Stop the server: close all open databases first
Web site:
link to history page, bug page
......@@ -188,12 +201,8 @@ CREATE TABLE TEST(ID INT PRIMARY KEY, NAME VARCHAR);
<reconnect>
out of memory?
shrink newsletter list (migrate to google groups)
don't create @~ of not translated
clustered tables: test, document
extend tests that simulate power off
HSQLDB compatibility:
......@@ -214,20 +223,16 @@ move Performance Tuning > Advanced Topics
testHalt
java org.h2.test.TestAll halt
Automate real power off tests
timer test
java.lang.Exception: query was too quick; result: 0 time:968
at org.h2.test.TestBase.logError(TestBase.java:220)
at org.h2.test.db.TestCases$1.run(TestCases.java:170)
at java.lang.Thread.run(Thread.java:595)
ftp server: problem with multithreading?
h2\src\docsrc\html\images\SQLInjection.txt
Convert SQL-injection-2.txt to html document, include SQLInjection.java sample
send http://thecodist.com/fiche/thecodist/article/sql-injections-how-not-to-get-stuck to JavaWorld, TheServerSide,
Send SQL Injection solution proposal to PostgreSQL, MySQL, Derby, HSQLDB,...
Convert SQL-injection-2.txt to html document, include SQLInjection.java sample
MySQL, PostgreSQL
READ_TEXT(fileName String) returning a CLOB.
......@@ -235,8 +240,6 @@ I am not sure if this will read the CLOB in memory however.
Improve LOB in directories performance
Automate real power off tests
http://fastutil.dsi.unimi.it/
http://javolution.org/
http://joda-time.sourceforge.net/
......@@ -251,8 +254,6 @@ glossary
spell check / word list per language
translated .pdf
write tests using the PostgreSQL JDBC driver
*/
// run TestHalt
......@@ -280,6 +281,9 @@ write tests using the PostgreSQL JDBC driver
Features of H2
- Case insensitive string data type
- GROUP_CONCAT aggregate, User defined aggregates
- Fulltext search
- MVCC
- User defined types
*/
if (args.length > 0) {
......@@ -499,6 +503,8 @@ Features of H2
cache2Q = false;
testAll();
memory = true;
testAll();
}
void testAll() throws Exception {
......@@ -539,9 +545,6 @@ Features of H2
System.out.println("test big:"+big+" net:"+networked+" cipher:"+cipher+" memory:"+memory+" log:"+logMode+" diskResult:"+diskResult + " mvcc:" + mvcc);
beforeTest();
// int testMvcc;
// mvcc = true;
// db
new TestScriptSimple().runTest(this);
new TestScript().runTest(this);
......@@ -607,7 +610,8 @@ Features of H2
new TestZloty().runTest(this);
// mvcc
new TestMVCC().runTest(this);
new TestMvcc1().runTest(this);
new TestMvcc2().runTest(this);
// synthetic
new TestCrashAPI().runTest(this);
......
......@@ -52,9 +52,6 @@ public abstract class TestBase {
}
public void runTest(TestAll conf) {
if (conf.networked) {
return;
}
try {
init(conf);
start = System.currentTimeMillis();
......
......@@ -8,9 +8,12 @@ import java.io.File;
import java.io.FileReader;
import java.io.RandomAccessFile;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.Random;
import org.h2.test.TestBase;
import org.h2.tools.Csv;
......@@ -20,6 +23,7 @@ import org.h2.util.StringUtils;
public class TestCsv extends TestBase {
public void test() throws Exception {
testRandomData();
testEmptyFieldDelimiter();
testFieldDelimiter();
testAsTable();
......@@ -28,6 +32,48 @@ public class TestCsv extends TestBase {
testPipe();
}
private void testRandomData() throws Exception {
deleteDb("csv");
Connection conn = getConnection("csv");
Statement stat = conn.createStatement();
stat.execute("drop table if exists test");
stat.execute("create table test(a varchar, b varchar)");
int len = getSize(1000, 10000);
PreparedStatement prep = conn.prepareStatement("insert into test values(?, ?)");
ArrayList list = new ArrayList();
Random random = new Random(1);
for (int i = 0; i < len; i++) {
String a = randomData(random), b = randomData(random);
prep.setString(1, a);
prep.setString(2, b);
list.add(new String[]{a, b});
prep.execute();
}
stat.execute("CALL CSVWRITE('test.csv', 'SELECT * FROM test', 'UTF-8', '|', '#')");
Csv csv = Csv.getInstance();
csv.setFieldSeparatorRead('|');
csv.setFieldDelimiter('#');
ResultSet rs = csv.read("test.csv", null, "UTF-8");
for (int i = 0; i < len; i++) {
check(rs.next());
String[] pair = (String[]) list.get(i);
check(pair[0], rs.getString(1));
check(pair[1], rs.getString(2));
}
checkFalse(rs.next());
conn.close();
}
private String randomData(Random random) {
int len = random.nextInt(5);
StringBuffer buff = new StringBuffer();
String chars = "\\\'\",\r\n\t ;.-123456|#";
for (int i = 0; i < len; i++) {
buff.append(chars.charAt(random.nextInt(chars.length())));
}
return buff.toString();
}
private void testEmptyFieldDelimiter() throws Exception {
File f = new File(baseDir + "/test.csv");
f.delete();
......
......@@ -15,7 +15,10 @@ import org.h2.constant.ErrorCode;
import org.h2.test.TestBase;
import org.h2.tools.DeleteDbFiles;
public class TestMVCC extends TestBase {
/**
* Basic MVCC (multi version concurrency) test cases.
*/
public class TestMvcc1 extends TestBase {
Connection c1, c2;
Statement s1, s2;
......@@ -359,8 +362,6 @@ public class TestMVCC extends TestBase {
c1.close();
c2.close();
}
private void test(Statement stat, String sql, String expected) throws Exception {
......@@ -377,7 +378,5 @@ public class TestMVCC extends TestBase {
throw new Error("expected: " + expected + ", got: no rows");
}
}
// TODO Auto-generated method stub
}
}
/*
* Copyright 2004-2007 H2 Group. Licensed under the H2 License, Version 1.0 (http://h2database.com/html/license.html).
* Initial Developer: H2 Group
*/
package org.h2.test.mvcc;
import java.sql.Connection;
import java.sql.Statement;
import org.h2.test.TestBase;
/**
* Additional MVCC (multi version concurrency) test cases.
*/
public class TestMvcc2 extends TestBase {
private static final String DROP_TABLE = "DROP TABLE IF EXISTS EMPLOYEE";
private static final String CREATE_TABLE = "CREATE TABLE EMPLOYEE (id BIGINT, version BIGINT, NAME VARCHAR(255))";
private static final String INSERT = "INSERT INTO EMPLOYEE (id, version, NAME) VALUES (1, 1, 'Jones')";
private static final String UPDATE = "UPDATE EMPLOYEE SET NAME = 'Miller' WHERE version = 1";
public void test() throws Exception {
if (!config.mvcc) {
return;
}
deleteDb("mvcc2");
testInsertUpdateRollback();
testInsertRollback();
}
Connection getConnection() throws Exception {
return getConnection("mvcc2");
}
public void testInsertUpdateRollback() throws Exception {
Connection conn = getConnection();
conn.setAutoCommit(false);
Statement stmt = conn.createStatement();
stmt.execute(DROP_TABLE);
stmt.execute(CREATE_TABLE);
conn.commit();
stmt.execute(INSERT);
stmt.execute(UPDATE);
conn.rollback();
conn.close();
}
public void testInsertRollback() throws Exception {
Connection conn = getConnection();
conn.setAutoCommit(false);
Statement stmt = conn.createStatement();
stmt.execute(DROP_TABLE);
stmt.execute(CREATE_TABLE);
conn.commit();
stmt.execute(INSERT);
conn.rollback();
conn.close();
}
}
--- special grammar and test cases ---------------------------------------------------------------------------------------------
select * from dual a left join dual b on b.x=(select max(x) from dual);
> exception
select count(*) from system_range(1, 2) where x in(1, 1, 1);
> COUNT(*)
> --------
......
Defect report:
What steps will reproduce the problem?
(simple SQL scripts or simple standalone applications are preferred)
1.
2.
3.
What is the expected output? What do you see instead?
What version of the product are you using? On what operating system, file system, and virtual machine?
Do you know a workaround?
How important/urgent is the problem for you?
In your view, is this a defect or a feature request?
Please provide any additional information below.
-----------------
Corrupted database
I am sorry to say that, but it looks like a corruption problem. I am very interested in analyzing and solving this problem. It has top priority for me. I have a few question:
- What is your database URL?
- What version H2 are you using?
- Do you use any settings or special features (for example, the setting LOG=0, or two phase commit, linked tables, cache settings)?
- On what operating system, file system, and virtual machine?
- How big is the database?
- Is the database usually closed normally, or is process terminated forcefully or the computer switched off?
- Is it possible to reproduce this problem using a fresh database?
- Are there any other exceptions (maybe in the .trace.db file)? Could you post them please?
- Was the database originally created with an older version of H2?
- Do you still have any .trace.db files, and if yes could you send them?
- Could you send me the .data.db file where this exception occurs?
......@@ -4,10 +4,15 @@
*/
package org.h2.test.unit;
import org.h2.server.ftp.FtpEvent;
import org.h2.server.ftp.FtpEventListener;
import org.h2.server.ftp.FtpServer;
import org.h2.test.TestBase;
import org.h2.tools.Server;
public class TestFtp extends TestBase {
public class TestFtp extends TestBase implements FtpEventListener {
private FtpEvent lastEvent;
public void test() throws Exception {
test(baseDir);
......@@ -15,17 +20,33 @@ public class TestFtp extends TestBase {
private void test(String dir) throws Exception {
Server server = Server.createFtpServer(new String[]{"-ftpDir", dir}).start();
FtpServer ftp = (FtpServer) server.getService();
ftp.setEventListener(this);
FtpClient client = FtpClient.open("localhost:8021");
client.login("sa", "sa");
client.makeDirectory("test");
client.changeWorkingDirectory("test");
check(lastEvent.getCommand(), "CWD");
client.makeDirectory("hello");
client.changeWorkingDirectory("hello");
client.changeDirectoryUp();
check(lastEvent.getCommand(), "CDUP");
client.nameList("hello");
client.removeDirectory("hello");
client.close();
server.stop();
}
public void beforeCommand(FtpEvent event) {
lastEvent = event;
}
public void afterCommand(FtpEvent event) {
lastEvent = event;
}
public void onUnsupportedCommand(FtpEvent event) {
lastEvent = event;
}
}
......@@ -237,6 +237,9 @@ public class TestTools extends TestBase {
}
private void testManagementDb() throws Exception {
if (config.networked) {
return;
}
int count = getSize(2, 10);
for (int i = 0; i < count; i++) {
Server server = Server.createTcpServer(new String[] {}).start();
......@@ -331,11 +334,13 @@ public class TestTools extends TestBase {
Server.shutdownTcpServer("tcp://localhost", "", true);
error("shouldn't work and should throw an exception");
} catch (SQLException e) {
// expected
checkNotGeneralException(e);
}
conn = DriverManager.getConnection("jdbc:h2:tcp://localhost/test", "sa", "");
conn.close();
// conn.close();
Server.shutdownTcpServer("tcp://localhost", "abc", true);
// check that the database is closed
deleteDb("test");
try {
conn = DriverManager.getConnection("jdbc:h2:tcp://localhost/test", "sa", "");
error("server must have been closed");
......
......@@ -517,4 +517,4 @@ russian backward alexahin vlad ffffffffffff bfff ffffffff webapp undeploy initia
llc computing oliver road inaccessible android velasques duplicates eduardo chunk brazilian near langpair xrmd xmkd
encapsulates negating igor midnight fulfill prefixes communicates nesting convenience negated resides optimizing principal applets dobrovolskyi
involves ukrainian chile machines restricting summer aliased backus naur multiples avl operates grow normalized rijndael
countdown paused javac
countdown paused javac analyzing accesses solving forcefully urgent originally defect coordinates
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论