提交 2bfae6de authored 作者: Thomas Mueller's avatar Thomas Mueller

--no commit message

--no commit message
上级 e4a5e558
......@@ -112,10 +112,13 @@
</target>
<target name="compileServlet" depends="compileServletTest, compile" if="servlet.jar.present">
<javac executable="${javac}" srcdir="src/main" destdir="bin" debug="true">
<javac executable="${javac}" destdir="bin" debug="true">
<src path="src/main"/>
<src path="src/test"/>
<classpath location="${path.servlet.jar}" />
<include name="org/h2/server/web/WebServlet.java"/>
<include name="org/h2/server/web/DbStarter.java"/>
<include name="org/h2/test/unit/TestServlet.java"/>
</javac>
</target>
......@@ -133,6 +136,7 @@
<exclude name="org/h2/fulltext/FullTextLucene.java"/>
<exclude name="org/h2/server/web/WebServlet.java"/>
<exclude name="org/h2/server/web/DbStarter.java"/>
<exclude name="org/h2/test/unit/TestServlet.java"/>
</javac>
<copy todir="bin" overwrite="true">
<fileset dir="src/main" includes="META-INF/**/*"/>
......
......@@ -53,6 +53,7 @@ login.connect=Connect
login.driverClass=Driver Class
login.driverNotFound=Database driver not found<br />See in the Help for how to add drivers
login.goAdmin=Preferences
login.goTools=Tools
login.jdbcUrl=JDBC URL
login.language=Language
login.login=Login
......
......@@ -4,6 +4,7 @@
*/
package org.h2.constant;
/**
* This class defines the error codes used for SQL exceptions.
*/
......@@ -245,9 +246,6 @@ public class ErrorCode {
*/
public static final int COLUMN_NOT_FOUND_1 = 42122;
public static final int SETTING_NOT_FOUND_1 = 42132;
// 0A: feature not supported
// HZ: remote database access
......@@ -509,6 +507,15 @@ public class ErrorCode {
* </pre>
*/
public static final int TRACE_CONNECTION_NOT_CLOSED = 90018;
/**
* The error with code <code>90019</code> is thrown when
* trying to drop the current user.
* Example:
* <pre>
* DROP USER SA;
* </pre>
*/
public static final int CANNOT_DROP_CURRENT_USER = 90019;
/**
......@@ -541,8 +548,32 @@ public class ErrorCode {
* </pre>
*/
public static final int DATA_CONVERSION_ERROR_1 = 90021;
/**
* The error with code <code>90022</code> is thrown when
* trying to call a unknown function.
* Example:
* <pre>
* CALL SPECIAL_SIN(10);
* </pre>
*/
public static final int FUNCTION_NOT_FOUND_1 = 90022;
/**
* The error with code <code>90023</code> is thrown when
* trying to set a primary key on a nullable column.
* Example:
* <pre>
* CREATE TABLE TEST(ID INT, NAME VARCHAR);
* ALTER TABLE TEST ADD CONSTRAINT PK PRIMARY KEY(ID);
* </pre>
*/
public static final int COLUMN_MUST_NOT_BE_NULLABLE_1 = 90023;
/**
* The error with code <code>90024</code> is thrown when
* a file could not be renamed.
*/
public static final int FILE_RENAME_FAILED_2 = 90024;
/**
......@@ -551,7 +582,17 @@ public class ErrorCode {
* (only in Windows), or because an error occured when deleting.
*/
public static final int FILE_DELETE_FAILED_1 = 90025;
/**
* The error with code <code>90026</code> is thrown when
* an object could not be serialized.
*/
public static final int SERIALIZATION_FAILED_1 = 90026;
/**
* The error with code <code>90027</code> is thrown when
* an object could not be de-serialized.
*/
public static final int DESERIALIZATION_FAILED_1 = 90027;
/**
......@@ -560,8 +601,33 @@ public class ErrorCode {
* cause of the exception.
*/
public static final int IO_EXCEPTION_1 = 90028;
/**
* The error with code <code>90029</code> is thrown when
* calling ResultSet.deleteRow(), insertRow(), or updateRow()
* when the current row is not updatable.
* Example:
* <pre>
* ResultSet rs = stat.executeQuery("SELECT * FROM TEST");
* rs.next();
* rs.insertRow();
* </pre>
*/
public static final int NOT_ON_UPDATABLE_ROW = 90029;
/**
* The error with code <code>90030</code> is thrown when
* the database engine has detected a checksum mismatch in the data
* or index. To solve this problem, restore a backup or use the
* Recovery tool (org.h2.tools.Recover).
*/
public static final int FILE_CORRUPTED_1 = 90030;
/**
* The error with code <code>90031</code> is thrown when
* an input / output error occured. For more information, see the root
* cause of the exception.
*/
public static final int IO_EXCEPTION_2 = 90031;
/**
......@@ -569,13 +635,50 @@ public class ErrorCode {
* trying to drop or alter a user that does not exist.
* Example:
* <pre>
* DROP USER TESTUSER;
* DROP USER TEST_USER;
* </pre>
*/
public static final int USER_NOT_FOUND_1 = 90032;
/**
* The error with code <code>90033</code> is thrown when
* trying to create a user or role if a user with this name already exists.
* Example:
* <pre>
* CREATE USER TEST_USER;
* CREATE USER TEST_USER;
* </pre>
*/
public static final int USER_ALREADY_EXISTS_1 = 90033;
public static final int LOG_FILE_ERROR_2 = 90034;
/**
* The error with code <code>90034</code> is thrown when
* writing to the trace file failed, for example because the there
* is an I/O exception. This message is printed to System.out,
* but only once.
*/
public static final int TRACE_FILE_ERROR_2 = 90034;
/**
* The error with code <code>90035</code> is thrown when
* trying to create a sequence if a sequence with this name already
* exists.
* Example:
* <pre>
* CREATE SEQUENCE TEST_SEQ;
* CREATE SEQUENCE TEST_SEQ;
* </pre>
*/
public static final int SEQUENCE_ALREADY_EXISTS_1 = 90035;
/**
* The error with code <code>90036</code> is thrown when
* trying to access a sequence that does not exist.
* Example:
* <pre>
* SELECT NEXT VALUE FOR SEQUENCE XYZ;
* </pre>
*/
public static final int SEQUENCE_NOT_FOUND_1 = 90036;
/**
......@@ -587,15 +690,81 @@ public class ErrorCode {
* </pre>
*/
public static final int VIEW_NOT_FOUND_1 = 90037;
/**
* The error with code <code>90038</code> is thrown when
* trying to create a view if a view with this name already
* exists.
* Example:
* <pre>
* CREATE VIEW DUMMY AS SELECT * FROM DUAL;
* CREATE VIEW DUMMY AS SELECT * FROM DUAL;
* </pre>
*/
public static final int VIEW_ALREADY_EXISTS_1 = 90038;
/**
* The error with code <code>90039</code> is thrown when
* trying to convert a decimal value to lower precision if the
* value is out of range for this precision.
* Example:
* <pre>
* SELECT * FROM TABLE(X DECIMAL(2, 2) = (123.34));
* </pre>
*/
public static final int VALUE_TOO_LARGE_FOR_PRECISION_1 = 90039;
/**
* The error with code <code>90040</code> is thrown when
* a user that is not administrator tries to execute a statement
* that requires admin privileges.
*/
public static final int ADMIN_RIGHTS_REQUIRED = 90040;
/**
* The error with code <code>90041</code> is thrown when
* trying to create a trigger and there is already a trigger with that name.
* <pre>
* CREATE TABLE TEST(ID INT);
* CREATE TRIGGER TRIGGER_A AFTER INSERT ON TEST
* CALL "org.h2.samples.TriggerSample$MyTrigger";
* CREATE TRIGGER TRIGGER_A AFTER INSERT ON TEST
* CALL "org.h2.samples.TriggerSample$MyTrigger";
* </pre>
*/
public static final int TRIGGER_ALREADY_EXISTS_1 = 90041;
/**
* The error with code <code>90042</code> is thrown when
* trying to drop a trigger that does not exist.
* Example:
* <pre>
* DROP TRIGGER TRIGGER_XYZ;
* </pre>
*/
public static final int TRIGGER_NOT_FOUND_1 = 90042;
private int test;
public static final int ERROR_CREATING_TRIGGER_OBJECT_3 = 90043;
public static final int ERROR_EXECUTING_TRIGGER_3 = 90044;
public static final int CONSTRAINT_ALREADY_EXISTS_1 = 90045;
/**
* The error with code <code>90046</code> is thrown when
* trying to open a connection to a database using an unsupported URL format.
* Please see the documentation on the supported URL format and examples.
* Example:
* <pre>
* jdbc:h2:;;
* </pre>
*/
public static final int URL_FORMAT_ERROR_2 = 90046;
/**
* The error with code <code>90047</code> is thrown when
* trying to connect to a TCP server with an incompatible client.
*/
public static final int DRIVER_VERSION_ERROR_2 = 90047;
public static final int FILE_VERSION_ERROR_1 = 90048;
......@@ -1025,7 +1194,6 @@ public class ErrorCode {
case INDEX_NOT_FOUND_1: return "42S12";
case DUPLICATE_COLUMN_NAME_1: return "42S21";
case COLUMN_NOT_FOUND_1: return "42S22";
case SETTING_NOT_FOUND_1: return "42S32";
// 0A: feature not supported
......
......@@ -26,6 +26,11 @@ public class SysProperties {
*/
public static final String H2_MAX_QUERY_TIMEOUT = "h2.maxQueryTimeout";
/**
* INTERNAL
*/
public static final String H2_LOG_DELETE_DELAY = "h2.logDeleteDelay";
/**
* System property <code>file.encoding</code> (default: Cp1252).<br />
* It is usually set by the system and is the default encoding used for the RunScript and CSV tool.
......@@ -384,4 +389,10 @@ public class SysProperties {
return getIntSetting(H2_MAX_QUERY_TIMEOUT, 0);
}
/**
* INTERNAL
*/
public static int getLogFileDeleteDelay() {
return getIntSetting(H2_LOG_DELETE_DELAY, 500);
}
}
......@@ -1343,6 +1343,14 @@ public class Database implements DataHandler {
}
}
public void deleteLogFileLater(String fileName) throws SQLException {
if (writer == null) {
FileUtils.delete(fileName);
} else {
writer.deleteLater(fileName);
}
}
public Class loadUserClass(String className) throws SQLException {
try {
return ClassUtils.loadUserClass(className);
......
......@@ -390,7 +390,7 @@ public class LogFile {
file.close();
file = null;
if (delete) {
FileUtils.delete(fileName);
database.deleteLogFileLater(fileName);
}
} catch (IOException e) {
if (closeException == null) {
......
......@@ -195,7 +195,7 @@ public class TraceSystem {
}
writingErrorLogged = true;
// TODO translate trace messages
SQLException se = Message.getSQLException(ErrorCode.LOG_FILE_ERROR_2, new String[] { fileName, e.toString() },
SQLException se = Message.getSQLException(ErrorCode.TRACE_FILE_ERROR_2, new String[] { fileName, e.toString() },
e);
// print this error only once
fileName = null;
......
......@@ -41,6 +41,7 @@ public class DbStarter implements ServletContextListener {
if (serverParams != null) {
String[] params = StringUtils.arraySplit(serverParams, ' ', true);
server = Server.createTcpServer(params);
server.start();
}
// To access the database using the server, use the URL:
// jdbc:h2:tcp://localhost/~/test
......
......@@ -949,7 +949,7 @@ class WebThread extends Thread implements DatabaseEventListener {
class LoginTask implements Runnable, DatabaseEventListener {
private DataOutputStream output;
private PrintWriter writer;
SimpleDateFormat dateFormat = new SimpleDateFormat("HH:mm:ss.SSS");
private SimpleDateFormat dateFormat = new SimpleDateFormat("HH:mm:ss.SSS");
LoginTask() throws IOException {
String message = "HTTP/1.1 200 OK\n";
......@@ -974,6 +974,7 @@ class WebThread extends Thread implements DatabaseEventListener {
public void exceptionThrown(SQLException e, String sql) {
log("Exception: " + PageParser.escapeHtml(e.toString()) + " SQL: " + PageParser.escapeHtml(sql));
server.traceError(e);
}
public void init(String url) {
......@@ -1019,6 +1020,7 @@ class WebThread extends Thread implements DatabaseEventListener {
writer.println(message + "<br />");
writer.flush();
}
server.trace(message);
}
public void run() {
......
......@@ -53,6 +53,7 @@ login.connect=Verbinden
login.driverClass=Datenbank-Treiber Klasse
login.driverNotFound=Datenbank-Treiber nicht gefunden<br />F&uuml;r Informationen zum Hinzuf&uuml;gen von Treibern siehe Hilfe
login.goAdmin=Optionen
login.goTools=\#Tools
login.jdbcUrl=JDBC URL
login.language=Sprache
login.login=Login
......
......@@ -53,6 +53,7 @@ login.connect=Conectar
login.driverClass=Controlador
login.driverNotFound=Controlador no encontrado
login.goAdmin=Preferencias
login.goTools=\#Tools
login.jdbcUrl=URL JDBC
login.language=Idioma
login.login=Registrar
......
......@@ -53,6 +53,7 @@ login.connect=Connecter
login.driverClass=Pilote JDBC
login.driverNotFound=Driver non trouv&eacute;.<br />Veuillez consulter dans l'aide la proc&eacute;dure d'ajout de drivers.
login.goAdmin=Options
login.goTools=\#Tools
login.jdbcUrl=URL JDBC
login.language=Langue
login.login=Connexion
......
......@@ -53,6 +53,7 @@ login.connect=Csatlakoz&aacute;s
login.driverClass=Illeszt&\#337;program oszt&aacute;ly
login.driverNotFound=Adatb&aacute;zis-illeszt&\#337;program nem tal&aacute;lhat&oacute;&lt;br&gt;Illeszt&\#337;programok hozz&aacute;ad&aacute;s&aacute;r&oacute;l a S&uacute;g&oacute; ad felvil&aacute;gos&iacute;t&aacute;st.
login.goAdmin=Tulajdons&aacute;gok
login.goTools=\#Tools
login.jdbcUrl=JDBC URL
login.language=Nyelv
login.login=Bel&eacute;p&eacute;s
......
......@@ -53,6 +53,7 @@ login.connect=Hubungkan
login.driverClass=Kelas Pengendali
login.driverNotFound=Pengendali basis data tidak ditemukan<br />Pelajari bagian Bantuan untuk mengetahui bagaimana cara menambah pengendali basis data
login.goAdmin=Pilihan
login.goTools=\#Tools
login.jdbcUrl=JDBC URL
login.language=Bahasa
login.login=Login
......
......@@ -53,6 +53,7 @@ login.connect=Connetti
login.driverClass=Classe driver
login.driverNotFound=Il driver del database non \u00E8 stato trovato<br />Guardare in Aiuto su come aggiungere dei drivers
login.goAdmin=Preferenze
login.goTools=\#Tools
login.jdbcUrl=JDBC URL
login.language=Lingua
login.login=Accesso
......
......@@ -53,6 +53,7 @@ login.connect=\u63A5\u7D9A
login.driverClass=\u30C9\u30E9\u30A4\u30D0\u30AF\u30E9\u30B9
login.driverNotFound=\u30C7\u30FC\u30BF\u30D9\u30FC\u30B9\u30C9\u30E9\u30A4\u30D0\u304C\u898B\u4ED8\u304B\u308A\u307E\u305B\u3093<br />\u30D8\u30EB\u30D7\u3067\u30C9\u30E9\u30A4\u30D0\u306E\u8FFD\u52A0\u65B9\u6CD5\u3092\u78BA\u8A8D\u3057\u3066\u304F\u3060\u3055\u3044
login.goAdmin=\u8A2D\u5B9A
login.goTools=\#Tools
login.jdbcUrl=JDBC URL
login.language=\u8A00\u8A9E
login.login=\u30ED\u30B0\u30A4\u30F3
......
......@@ -53,6 +53,7 @@ login.connect=Po&\#322;&\#261;cz
login.driverClass=Klasa sterownika
login.driverNotFound=Sterownik nie istnieje&lt;br /&gt;Zobacz w dokumentacji opis dodawania sterownik&oacute;w
login.goAdmin=Opcje
login.goTools=\#Tools
login.jdbcUrl=JDBC URL
login.language=J&\#281;zyk
login.login=U&\#380;ytkownik
......
......@@ -53,6 +53,7 @@ login.connect=Conectar
login.driverClass=Classe com o driver
login.driverNotFound=O driver n&atilde;o foi encontrado&lt;br/&gt;Ver na se&ccedil;&atilde;o de ajuda, como adicionar drivers
login.goAdmin=Prefer&ecirc;ncias
login.goTools=\#Tools
login.jdbcUrl=JDBC URL
login.language=L&iacute;ngua
login.login=Login
......
......@@ -53,6 +53,7 @@ login.connect=Estabelecer conex&atilde;o
login.driverClass=Classe com o driver
login.driverNotFound=O driver n&atilde;o foi encontrado&lt;br/&gt;Ver na sec&ccedil;&atilde;o de ajuda, como adicionar drivers
login.goAdmin=Preferencias
login.goTools=\#Tools
login.jdbcUrl=JDBC URL
login.language=Lingua
login.login=Login
......
......@@ -53,6 +53,7 @@ login.connect=&\#1057;&\#1086;&\#1077;&\#1076;&\#1080;&\#1085;&\#1080;&\#1090;&\
login.driverClass=&\#1050;&\#1083;&\#1072;&\#1089;&\#1089; &\#1076;&\#1088;&\#1072;&\#1081;&\#1074;&\#1077;&\#1088;&\#1072;
login.driverNotFound=&\#1044;&\#1088;&\#1072;&\#1081;&\#1074;&\#1077;&\#1088; &\#1073;&\#1072;&\#1079;&\#1099; &\#1076;&\#1072;&\#1085;&\#1085;&\#1099;&\#1093; &\#1085;&\#1077; &\#1085;&\#1072;&\#1081;&\#1076;&\#1077;&\#1085;&lt;br /&gt;&\#1055;&\#1086;&\#1089;&\#1084;&\#1086;&\#1090;&\#1088;&\#1080;&\#1090;&\#1077; &\#1074; &\#1055;&\#1086;&\#1084;&\#1086;&\#1097;&\#1080;, &\#1082;&\#1072;&\#1082; &\#1076;&\#1086;&\#1073;&\#1072;&\#1074;&\#1080;&\#1090;&\#1100; &\#1076;&\#1088;&\#1072;&\#1081;&\#1074;&\#1077;&\#1088; &\#1073;&\#1072;&\#1079;&\#1099; &\#1076;&\#1072;&\#1085;&\#1085;&\#1099;&\#1093;
login.goAdmin=Preferences
login.goTools=\#Tools
login.jdbcUrl=JDBC URL
login.language=&\#1071;&\#1079;&\#1099;&\#1082;
login.login=&\#1051;&\#1086;&\#1075;&\#1080;&\#1085;
......
......@@ -53,6 +53,7 @@ login.connect=Ba&\#287;lan
login.driverClass=Veri taban&\#305; s&\#252;r&\#252;c&\#252; s&\#305;n&\#305;f&\#305;
login.driverNotFound=&\#304;stenilen veri taban&\#305; s&\#252;r&\#252;c&\#252;s&\#252; bulunamad&\#305;<br />S&\#252;r&\#252;c&\#252; ekleme konusunda bilgi i&\#231;in Yard&\#305;m'a ba&\#351;vurunuz
login.goAdmin=Se&\#231;enekler
login.goTools=\#Tools
login.jdbcUrl=JDBC URL
login.language=Dil
login.login=Gir
......
......@@ -53,6 +53,7 @@ login.connect=&\#x041F;&\#x0456;&\#x0434;'&\#x0454;&\#x0434;&\#x043D;&\#x0430;&\
login.driverClass=Driver Class
login.driverNotFound=&\#x0414;&\#x0440;&\#x0430;&\#x0432;&\#x0435;&\#x0440; &\#x0431;&\#x0430;&\#x0437;&\#x0438; &\#x0434;&\#x0430;&\#x043D;&\#x0438;&\#x0445; &\#x043D;&\#x0435; &\#x0437;&\#x043D;&\#x0430;&\#x0439;&\#x0434;&\#x0435;&\#x043D;&\#x043E;<br />&\#x041F;&\#x043E;&\#x0434;&\#x0438;&\#x0432;&\#x0456;&\#x0442;&\#x044C;&\#x0441;&\#x044F; &\#x0432; &\#x0434;&\#x043E;&\#x043F;&\#x043E;&\#x043C;&\#x043E;&\#x0437;&\#x0456; &\#x044F;&\#x043A; &\#x0434;&\#x043E;&\#x0434;&\#x0430;&\#x0442;&\#x0438; &\#x043D;&\#x043E;&\#x0432;&\#x0456; &\#x0434;&\#x0440;&\#x0430;&\#x0439;&\#x0432;&\#x0435;&\#x0440;&\#x0438;
login.goAdmin=&\#x041D;&\#x0430;&\#x0441;&\#x0442;&\#x0440;&\#x043E;&\#x0439;&\#x043A;&\#x0438;
login.goTools=\#Tools
login.jdbcUrl=JDBC URL
login.language=&\#x041C;&\#x043E;&\#x0432;&\#x0430;
login.login=&\#x041B;&\#x043E;&\#x0433;&\#x0456;&\#x043D;
......
......@@ -53,6 +53,7 @@ login.connect=\u8FDE\u63A5
login.driverClass=\u9A71\u52A8\u7C7B
login.driverNotFound=\u6570\u636E\u5E93\u9A71\u52A8\u6CA1\u6709\u53D1\u73B0<br />\u8BF7\u53C2\u8003\u5E2E\u52A9\u53BB\u6DFB\u52A0\u6570\u636E\u5E93\u9A71\u52A8
login.goAdmin=\u914D\u7F6E
login.goTools=\#Tools
login.jdbcUrl=JDBC URL
login.language=\u8BED\u8A00
login.login=\u767B\u5F55
......
......@@ -6,6 +6,9 @@ package org.h2.store;
import java.lang.ref.WeakReference;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map.Entry;
import org.h2.constant.SysProperties;
import org.h2.engine.Constants;
......@@ -16,23 +19,80 @@ import org.h2.log.LogSystem;
import org.h2.message.Trace;
import org.h2.message.TraceSystem;
import org.h2.table.Table;
import org.h2.util.FileUtils;
import org.h2.util.ObjectArray;
import org.h2.util.ObjectUtils;
import org.h2.util.TempFileDeleter;
/**
* The writer thread is responsible to flush the transaction log file from time to time.
*/
public class WriterThread extends Thread {
// Thread objects are not garbage collected
// until they returned from the run() method
// (even if they where never started)
// so if the connection was not closed,
// the database object cannot get reclaimed
// by the garbage collector if we use a hard reference
/**
* The reference to the database.
*
* Thread objects are not garbage collected
* until they returned from the run() method
* (even if they where never started)
* so if the connection was not closed,
* the database object cannot get reclaimed
* by the garbage collector if we use a hard reference.
*/
private volatile WeakReference databaseRef;
private int writeDelay;
private long lastIndexFlush;
private volatile boolean stop;
private HashMap deleteLater = new HashMap();
private volatile long deleteNext;
public void deleteLater(String fileName) {
long at = System.currentTimeMillis() + SysProperties.getLogFileDeleteDelay();
if (at < deleteNext || deleteNext == 0) {
deleteNext = at;
}
synchronized (deleteLater) {
deleteLater.put(fileName, ObjectUtils.getLong(at));
}
}
private void delete(boolean now) {
if (!now && (deleteNext == 0 || System.currentTimeMillis() < deleteNext)) {
return;
}
long time = System.currentTimeMillis();
ObjectArray delete = new ObjectArray();
synchronized (deleteLater) {
deleteNext = 0;
for (Iterator it = deleteLater.entrySet().iterator(); it.hasNext();) {
Entry entry = (Entry) it.next();
long at = ((Long) entry.getValue()).longValue();
if (now || time >= at) {
String fileName = (String) entry.getKey();
delete.add(fileName);
} else {
if (at < deleteNext || deleteNext == 0) {
deleteNext = at;
}
}
}
}
for (int i = 0; i < delete.size(); i++) {
String fileName = (String) delete.get(i);
try {
FileUtils.delete(fileName);
synchronized (deleteLater) {
deleteLater.remove(fileName);
}
} catch (SQLException e) {
Database database = (Database) databaseRef.get();
if (database != null) {
database.getTrace(Trace.DATABASE).error("delete " + fileName, e);
}
}
}
}
private WriterThread(Database database, int writeDelay) {
this.databaseRef = new WeakReference(database);
......@@ -101,6 +161,7 @@ public class WriterThread extends Thread {
public void run() {
while (!stop) {
delete(false);
TempFileDeleter.deleteUnused();
Database database = (Database) databaseRef.get();
if (database == null) {
......@@ -135,6 +196,7 @@ public class WriterThread extends Thread {
}
public void stopThread() {
delete(true);
stop = true;
}
......
......@@ -149,16 +149,25 @@ java org.h2.test.TestAll timer
TestAll test = new TestAll();
test.printSystem();
/*
integrate tools in H2 Console
// TestRecover.main(new String[0]);
for all tools: add link to javadoc (like Recover)
/*
Automate real power off tests
Extend tests that simulate power off
timer test
DbStarter: server.start();
add test case!
java org.h2.tool.Server -baseDir C:\temp\test
web console: jdbc:h2:~/test
C:\temp\test\~
C:\temp\crash_db
- try delayed log file delete
integrate tools in H2 Console
for all tools: add link to javadoc (like Recover)
recovery tool: bad blocks should be converted to INSERT INTO SYSTEM_ERRORS(...),
and things should go into the .trace.db file
......@@ -167,14 +176,7 @@ RECOVER=2 to backup the database, run recovery, open the database
Recovery should work with encrypted databases
java org.h2.tool.Server -baseDir C:\temp\dbtest
web console: jdbc:h2:~/chin
C:\temp\dbtest\~
Automate real power off tests
Adjust cache memory usage
Extend tests that simulate power off
timer test
// test with garbage at the end of the log file (must be consistently detected as such)
// TestRandomSQL is too random; most statements fails
// extend the random join test that compared the result against PostgreSQL
......@@ -185,10 +187,15 @@ Test Recovery with MAX_LOG_FILE_SIZE=1; test with various log file sizes
Test with many columns (180), create index
add a 'kill process while altering tables' test case
SysProperties: change everything to H2_...
Use FilterIn / FilterOut putStream
Roadmap:
History:
Old log files are now deleted a bit after a new log file is created. This helps recovery.
The DbStarter servlet didn't start the TCP listener even if configured.
Statement.setQueryTimeout() is now supported. New session setting QUERY_TIMEOUT, and new system property h2.maxQueryTimeout.
Changing the transaction log level (SET LOG) is now written to the trace file by default.
In a SQL script, primary key constraints are now ordered before foreign key constraints.
......@@ -490,6 +497,7 @@ It was not possible to create a referential constraint to a table in a different
new TestReader().runTest(this);
new TestSampleApps().runTest(this);
new TestScriptReader().runTest(this);
runTest("org.h2.test.unit.TestServlet");
new TestSecurity().runTest(this);
new TestStreams().runTest(this);
new TestStringCache().runTest(this);
......@@ -502,6 +510,17 @@ It was not possible to create a referential constraint to a table in a different
afterTest();
}
private void runTest(String className) {
try {
Class clazz = Class.forName(className);
TestBase test = (TestBase) clazz.newInstance();
test.runTest(this);
} catch (Exception e) {
// ignore
TestBase.logError("Class not found: " + className, null);
}
}
public void beforeTest() throws SQLException {
DeleteDbFiles.execute(TestBase.baseDir, null, true);
FileSystemDisk.getInstance().deleteRecursive("trace.db");
......
......@@ -38,6 +38,7 @@ public class TestUpdatableResultSet extends TestBase {
stat.execute("INSERT INTO TEST VALUES(1, 'Hello'), (2, 'World'), (3, 'Test')");
ResultSet rs = stat.executeQuery("SELECT * FROM TEST ORDER BY ID");
check(rs.isBeforeFirst());
checkFalse(rs.isAfterLast());
check(rs.getRow(), 0);
......@@ -49,6 +50,14 @@ public class TestUpdatableResultSet extends TestBase {
check(rs.getRow(), 1);
rs.next();
try {
rs.insertRow();
error("Unexpected success");
} catch (SQLException e) {
checkNotGeneralException(e);
}
checkFalse(rs.isBeforeFirst());
checkFalse(rs.isAfterLast());
check(rs.getInt(1), 2);
......
/*
* Copyright 2004-2008 H2 Group. Licensed under the H2 License, Version 1.0 (http://h2database.com/html/license.html).
* Initial Developer: H2 Group
*/
package org.h2.test.unit;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Properties;
import java.util.Set;
import javax.servlet.RequestDispatcher;
import javax.servlet.Servlet;
import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletException;
import org.h2.server.web.DbStarter;
import org.h2.test.TestBase;
/**
* Tests the DbStarter servlet.
* This test simulates a minimum servlet container environment.
*/
public class TestServlet extends TestBase {
/**
* Minimum ServletContext implementation.
* Most methods are not implemented.
*/
private static class TestServletContext implements ServletContext {
private Properties initParams = new Properties();
private HashMap attributes = new HashMap();
public void setAttribute(String key, Object value) {
attributes.put(key, value);
}
public Object getAttribute(String key) {
return attributes.get(key);
}
private void setInitParameter(String key, String value) {
initParams.setProperty(key, value);
}
public String getInitParameter(String key) {
return initParams.getProperty(key);
}
public Enumeration getAttributeNames() {
throw new UnsupportedOperationException();
}
public ServletContext getContext(String string) {
throw new UnsupportedOperationException();
}
public Enumeration getInitParameterNames() {
throw new UnsupportedOperationException();
}
public int getMajorVersion() {
throw new UnsupportedOperationException();
}
public String getMimeType(String string) {
throw new UnsupportedOperationException();
}
public int getMinorVersion() {
throw new UnsupportedOperationException();
}
public RequestDispatcher getNamedDispatcher(String string) {
throw new UnsupportedOperationException();
}
public String getRealPath(String string) {
throw new UnsupportedOperationException();
}
public RequestDispatcher getRequestDispatcher(String string) {
throw new UnsupportedOperationException();
}
public URL getResource(String string) throws MalformedURLException {
throw new UnsupportedOperationException();
}
public InputStream getResourceAsStream(String string) {
throw new UnsupportedOperationException();
}
public Set getResourcePaths(String string) {
throw new UnsupportedOperationException();
}
public String getServerInfo() {
throw new UnsupportedOperationException();
}
public Servlet getServlet(String string) throws ServletException {
throw new UnsupportedOperationException();
}
public String getServletContextName() {
throw new UnsupportedOperationException();
}
public Enumeration getServletNames() {
throw new UnsupportedOperationException();
}
public Enumeration getServlets() {
throw new UnsupportedOperationException();
}
public void log(String string) {
throw new UnsupportedOperationException();
}
public void log(Exception exception, String string) {
throw new UnsupportedOperationException();
}
public void log(String string, Throwable throwable) {
throw new UnsupportedOperationException();
}
public void removeAttribute(String string) {
throw new UnsupportedOperationException();
}
};
public void test() throws Exception {
DbStarter listener = new DbStarter();
TestServletContext context = new TestServletContext();
context.setInitParameter("db.url", getURL("servlet", true));
context.setInitParameter("db.user", getUser());
context.setInitParameter("db.password", getPassword());
context.setInitParameter("db.tcpServer", "-tcpPort 8888");
ServletContextEvent event = new ServletContextEvent(context);
listener.contextInitialized(event);
Connection conn1 = listener.getConnection();
Connection conn1a = (Connection) context.getAttribute("connection");
check(conn1 == conn1a);
Statement stat1 = conn1.createStatement();
stat1.execute("CREATE TABLE T(ID INT)");
Connection conn2 = DriverManager.getConnection("jdbc:h2:tcp://localhost:8888/" + baseDir + "/servlet", getUser(), getPassword());
Statement stat2 = conn2.createStatement();
stat2.execute("SELECT * FROM T");
stat2.execute("DROP TABLE T");
try {
stat1.execute("SELECT * FROM T");
error("Unexpected success");
} catch (SQLException e) {
checkNotGeneralException(e);
}
conn2.close();
listener.contextDestroyed(event);
// listener must be stopped
try {
conn2 = DriverManager.getConnection("jdbc:h2:tcp://localhost:8888/" + baseDir + "/servlet", getUser(), getPassword());
error("Unexpected success");
} catch (SQLException e) {
checkNotGeneralException(e);
}
// connection must be closed
try {
stat1.execute("SELECT * FROM DUAL");
error("Unexpected success");
} catch (SQLException e) {
checkNotGeneralException(e);
}
}
}
......@@ -525,3 +525,4 @@ compares packets destroying echo homed hosts clock countries validated catches t
echo callablestatement procid homed getstart staging prices meantime qujd qujdra qui divided quaere restrictions hudson scoped design inverting newlines
violate verysmallint eremainder iee cgi adjust estimation consumption occupy ikvm light gray viewer grover harpal
upgrading consecutive acting
simulates dispatcher servlets chf destruction separating consulting reached
\ No newline at end of file
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论