提交 132e613f authored 作者: Thomas Mueller's avatar Thomas Mueller

--no commit message

--no commit message
上级 58197110
#Wed Jan 16 10:26:35 CET 2008 #Thu Jan 17 08:51:17 CET 2008
javac=javac javac=javac
benchmark.drivers.dir=C\:/data/java benchmark.drivers.dir=C\:/data/java
path.servlet.jar=C\:/data/classpath/servlet-api.jar path.servlet.jar=C\:/data/classpath/servlet-api.jar
......
...@@ -822,17 +822,28 @@ public class Select extends Query { ...@@ -822,17 +822,28 @@ public class Select extends Query {
} }
public boolean isEverything(ExpressionVisitor visitor) { public boolean isEverything(ExpressionVisitor visitor) {
if (visitor.type == ExpressionVisitor.SET_MAX_DATA_MODIFICATION_ID) { switch(visitor.type) {
case ExpressionVisitor.SET_MAX_DATA_MODIFICATION_ID: {
for (int i = 0; i < filters.size(); i++) { for (int i = 0; i < filters.size(); i++) {
TableFilter f = (TableFilter) filters.get(i); TableFilter f = (TableFilter) filters.get(i);
long m = f.getTable().getMaxDataModificationId(); long m = f.getTable().getMaxDataModificationId();
visitor.addDataModificationId(m); visitor.addDataModificationId(m);
} }
break;
} }
if (visitor.type == ExpressionVisitor.EVALUATABLE) { case ExpressionVisitor.EVALUATABLE: {
if (!SysProperties.OPTIMIZE_EVALUATABLE_SUBQUERIES) { if (!SysProperties.OPTIMIZE_EVALUATABLE_SUBQUERIES) {
return false; return false;
} }
break;
}
case ExpressionVisitor.GET_DEPENDENCIES: {
for (int i = 0; i < filters.size(); i++) {
TableFilter filter = (TableFilter) filters.get(i);
filter.getTable().addDependencies(visitor.getDependencies());
}
break;
}
} }
visitor.queryLevel(1); visitor.queryLevel(1);
boolean result = true; boolean result = true;
......
...@@ -168,6 +168,17 @@ public class SysProperties { ...@@ -168,6 +168,17 @@ public class SysProperties {
* Maximum size of an object in the cache. * Maximum size of an object in the cache.
*/ */
public static final int OBJECT_CACHE_SIZE = getIntSetting("h2.objectCacheSize", 1024); public static final int OBJECT_CACHE_SIZE = getIntSetting("h2.objectCacheSize", 1024);
/**
* System property <code>h2.optimizeDropDependencies</code> (default: true).<br />
* Improve the performance of DROP and DROP ALL OBJECTS by quicker scanning if other objects depend on this object.
*/
public static final boolean OPTIMIZE_DROP_DEPENDENCIES = getBooleanSetting("h2.optimizeDropDependencies", true);
/**
* System property <code>h2.optimizeDistinct</code> (default: true).<br />
* Improve the performance of simple DISTINCT queries if an index is available for the given column.
*/
public static final boolean OPTIMIZE_DISTINCT = getBooleanSetting("h2.optimizeDistinct", true); public static final boolean OPTIMIZE_DISTINCT = getBooleanSetting("h2.optimizeDistinct", true);
/** /**
......
...@@ -1188,6 +1188,29 @@ public class Database implements DataHandler { ...@@ -1188,6 +1188,29 @@ public class Database implements DataHandler {
removeMeta(session, id); removeMeta(session, id);
} }
private String getDependentObject(SchemaObject obj) {
switch (obj.getType()) {
case DbObject.COMMENT:
case DbObject.CONSTRAINT:
case DbObject.INDEX:
case DbObject.RIGHT:
case DbObject.TRIGGER:
case DbObject.USER:
return null;
}
ObjectArray list = getAllSchemaObjects(DbObject.TABLE_OR_VIEW);
HashSet set = new HashSet();
for (int i = 0; i < list.size(); i++) {
Table t = (Table) list.get(i);
set.clear();
t.addDependencies(set);
if (set.contains(obj)) {
return t.getSQL();
}
}
return null;
}
private String getFirstInvalidTable(Session session) { private String getFirstInvalidTable(Session session) {
String conflict = null; String conflict = null;
try { try {
...@@ -1216,7 +1239,12 @@ public class Database implements DataHandler { ...@@ -1216,7 +1239,12 @@ public class Database implements DataHandler {
removeDatabaseObject(session, comment); removeDatabaseObject(session, comment);
} }
obj.getSchema().remove(session, obj); obj.getSchema().remove(session, obj);
String invalid = getFirstInvalidTable(session); String invalid;
if (SysProperties.OPTIMIZE_DROP_DEPENDENCIES) {
invalid = getDependentObject(obj);
} else {
invalid = getFirstInvalidTable(session);
}
if (invalid != null) { if (invalid != null) {
obj.getSchema().add(obj); obj.getSchema().add(obj);
throw Message.getSQLException(ErrorCode.CANNOT_DROP_2, new String[] { obj.getSQL(), invalid }); throw Message.getSQLException(ErrorCode.CANNOT_DROP_2, new String[] { obj.getSQL(), invalid });
......
...@@ -357,16 +357,14 @@ public class Aggregate extends Expression { ...@@ -357,16 +357,14 @@ public class Aggregate extends Expression {
buff.append(on.getSQL()); buff.append(on.getSQL());
if (orderList != null) { if (orderList != null) {
buff.append(" ORDER BY "); buff.append(" ORDER BY ");
if (orderList != null) { for (int i = 0; i < orderList.size(); i++) {
for (int i = 0; i < orderList.size(); i++) { SelectOrderBy o = (SelectOrderBy) orderList.get(i);
SelectOrderBy o = (SelectOrderBy) orderList.get(i); if (i > 0) {
if (i > 0) { buff.append(", ");
buff.append(", "); }
} buff.append(o.expression.getSQL());
buff.append(o.expression.getSQL()); if (o.descending) {
if (o.descending) { buff.append(" DESC");
buff.append(" DESC");
}
} }
} }
} }
...@@ -457,7 +455,19 @@ public class Aggregate extends Expression { ...@@ -457,7 +455,19 @@ public class Aggregate extends Expression {
return false; return false;
} }
} }
return (on == null || on.isEverything(visitor)) && (separator == null || separator.isEverything(visitor)); if (on != null && !on.isEverything(visitor)) {
return false;
}
if (separator != null && !separator.isEverything(visitor)) {
return false;
}
for (int i = 0; orderList != null && i < orderList.size(); i++) {
SelectOrderBy o = (SelectOrderBy) orderList.get(i);
if (!o.expression.isEverything(visitor)) {
return false;
}
}
return true;
} }
public int getCost() { public int getCost() {
......
...@@ -297,4 +297,5 @@ public abstract class Expression { ...@@ -297,4 +297,5 @@ public abstract class Expression {
public Expression optimizeInJoin(Session session, Select select) throws SQLException { public Expression optimizeInJoin(Session session, Select select) throws SQLException {
return this; return this;
} }
} }
...@@ -246,6 +246,8 @@ public class ExpressionColumn extends Expression { ...@@ -246,6 +246,8 @@ public class ExpressionColumn extends Expression {
return true; return true;
case ExpressionVisitor.NOT_FROM_RESOLVER: case ExpressionVisitor.NOT_FROM_RESOLVER:
return resolver != visitor.getResolver(); return resolver != visitor.getResolver();
case ExpressionVisitor.GET_DEPENDENCIES:
return true;
default: default:
throw Message.getInternalError("type=" + visitor.type); throw Message.getInternalError("type=" + visitor.type);
} }
......
...@@ -4,6 +4,9 @@ ...@@ -4,6 +4,9 @@
*/ */
package org.h2.expression; package org.h2.expression;
import java.util.HashSet;
import org.h2.engine.DbObject;
import org.h2.table.ColumnResolver; import org.h2.table.ColumnResolver;
import org.h2.table.Table; import org.h2.table.Table;
...@@ -12,32 +15,53 @@ import org.h2.table.Table; ...@@ -12,32 +15,53 @@ import org.h2.table.Table;
* to optimize a statement. * to optimize a statement.
*/ */
public class ExpressionVisitor { public class ExpressionVisitor {
// Is the value independent on unset parameters or on columns of a higher level query, or sequence values (that means can it be evaluated right now) /**
* Is the value independent on unset parameters or on columns of a higher level query,
* or sequence values (that means can it be evaluated right now)?
*/
public static final int INDEPENDENT = 0; public static final int INDEPENDENT = 0;
// Are all aggregates MIN(column), MAX(column), or COUNT(*)? /**
* Are all aggregates MIN(column), MAX(column), or COUNT(*)?
*/
public static final int OPTIMIZABLE_MIN_MAX_COUNT_ALL = 1; public static final int OPTIMIZABLE_MIN_MAX_COUNT_ALL = 1;
// Does the expression return the same results for the same parameters? /**
* Does the expression return the same results for the same parameters?
*/
public static final int DETERMINISTIC = 2; public static final int DETERMINISTIC = 2;
// Can the expression be evaluated, that means are all columns set to 'evaluatable'? /**
* Can the expression be evaluated, that means are all columns set to 'evaluatable'?
*/
public static final int EVALUATABLE = 3; public static final int EVALUATABLE = 3;
// Request to set the latest modification id /**
* Request to set the latest modification id.
*/
public static final int SET_MAX_DATA_MODIFICATION_ID = 4; public static final int SET_MAX_DATA_MODIFICATION_ID = 4;
// Does the expression have no side effects (change the data)? /**
* Does the expression have no side effects (change the data)?
*/
public static final int READONLY = 5; public static final int READONLY = 5;
// Does an expression have no relation to the given table filter? /**
* Does an expression have no relation to the given table filter?
*/
public static final int NOT_FROM_RESOLVER = 6; public static final int NOT_FROM_RESOLVER = 6;
/**
* Request to get the set of dependencies.
*/
public static final int GET_DEPENDENCIES = 7;
int queryLevel; int queryLevel;
public Table table; public Table table;
public int type; public int type;
private long maxDataModificationId; private long maxDataModificationId;
private ColumnResolver resolver; private ColumnResolver resolver;
private HashSet dependencies;
public static ExpressionVisitor get(int type) { public static ExpressionVisitor get(int type) {
return new ExpressionVisitor(type); return new ExpressionVisitor(type);
...@@ -47,6 +71,18 @@ public class ExpressionVisitor { ...@@ -47,6 +71,18 @@ public class ExpressionVisitor {
return maxDataModificationId; return maxDataModificationId;
} }
public void addDependency(DbObject obj) {
dependencies.add(obj);
}
public HashSet getDependencies() {
return dependencies;
}
public void setDependencies(HashSet dependencies) {
this.dependencies = dependencies;
}
private ExpressionVisitor(int type) { private ExpressionVisitor(int type) {
this.type = type; this.type = type;
} }
......
...@@ -80,10 +80,14 @@ public class JavaAggregate extends Expression { ...@@ -80,10 +80,14 @@ public class JavaAggregate extends Expression {
} }
public boolean isEverything(ExpressionVisitor visitor) { public boolean isEverything(ExpressionVisitor visitor) {
if (visitor.type == ExpressionVisitor.DETERMINISTIC) { switch(visitor.type) {
case ExpressionVisitor.DETERMINISTIC:
// TODO optimization: some functions are deterministic, but we don't // TODO optimization: some functions are deterministic, but we don't
// know (no setting for that) // know (no setting for that)
return false; return false;
case ExpressionVisitor.GET_DEPENDENCIES:
visitor.addDependency(userAggregate);
break;
} }
for (int i = 0; i < args.length; i++) { for (int i = 0; i < args.length; i++) {
Expression e = args[i]; Expression e = args[i];
......
...@@ -117,10 +117,14 @@ public class JavaFunction extends Expression implements FunctionCall { ...@@ -117,10 +117,14 @@ public class JavaFunction extends Expression implements FunctionCall {
} }
public boolean isEverything(ExpressionVisitor visitor) { public boolean isEverything(ExpressionVisitor visitor) {
if (visitor.type == ExpressionVisitor.DETERMINISTIC) { switch(visitor.type) {
case ExpressionVisitor.DETERMINISTIC:
// TODO optimization: some functions are deterministic, but we don't // TODO optimization: some functions are deterministic, but we don't
// know (no setting for that) // know (no setting for that)
return false; return false;
case ExpressionVisitor.GET_DEPENDENCIES:
visitor.addDependency(functionAlias);
break;
} }
for (int i = 0; i < args.length; i++) { for (int i = 0; i < args.length; i++) {
Expression e = args[i]; Expression e = args[i];
......
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
package org.h2.expression; package org.h2.expression;
import java.sql.SQLException; import java.sql.SQLException;
import org.h2.constant.ErrorCode; import org.h2.constant.ErrorCode;
import org.h2.engine.Session; import org.h2.engine.Session;
import org.h2.message.Message; import org.h2.message.Message;
...@@ -114,6 +115,8 @@ public class Parameter extends Expression implements ParameterInterface { ...@@ -114,6 +115,8 @@ public class Parameter extends Expression implements ParameterInterface {
return true; return true;
case ExpressionVisitor.NOT_FROM_RESOLVER: case ExpressionVisitor.NOT_FROM_RESOLVER:
return true; return true;
case ExpressionVisitor.GET_DEPENDENCIES:
return true;
default: default:
throw Message.getInternalError("type="+visitor.type); throw Message.getInternalError("type="+visitor.type);
} }
......
...@@ -79,6 +79,8 @@ public class Rownum extends Expression { ...@@ -79,6 +79,8 @@ public class Rownum extends Expression {
return true; return true;
case ExpressionVisitor.NOT_FROM_RESOLVER: case ExpressionVisitor.NOT_FROM_RESOLVER:
return true; return true;
case ExpressionVisitor.GET_DEPENDENCIES:
return true;
default: default:
throw Message.getInternalError("type="+visitor.type); throw Message.getInternalError("type="+visitor.type);
} }
......
...@@ -88,6 +88,9 @@ public class SequenceValue extends Expression { ...@@ -88,6 +88,9 @@ public class SequenceValue extends Expression {
return true; return true;
case ExpressionVisitor.NOT_FROM_RESOLVER: case ExpressionVisitor.NOT_FROM_RESOLVER:
return true; return true;
case ExpressionVisitor.GET_DEPENDENCIES:
visitor.addDependency(sequence);
return true;
default: default:
throw Message.getInternalError("type="+visitor.type); throw Message.getInternalError("type="+visitor.type);
} }
......
...@@ -230,4 +230,5 @@ public class TableFunction extends Expression implements FunctionCall { ...@@ -230,4 +230,5 @@ public class TableFunction extends Expression implements FunctionCall {
public ValueResultSet getValueForColumnList(Session session, Expression[] nullArgs) throws SQLException { public ValueResultSet getValueForColumnList(Session session, Expression[] nullArgs) throws SQLException {
return getTable(session, args, true, false); return getTable(session, args, true, false);
} }
} }
...@@ -107,6 +107,8 @@ public class ValueExpression extends Expression { ...@@ -107,6 +107,8 @@ public class ValueExpression extends Expression {
return true; return true;
case ExpressionVisitor.NOT_FROM_RESOLVER: case ExpressionVisitor.NOT_FROM_RESOLVER:
return true; return true;
case ExpressionVisitor.GET_DEPENDENCIES:
return true;
default: default:
throw Message.getInternalError("type=" + visitor.type); throw Message.getInternalError("type=" + visitor.type);
} }
......
...@@ -73,6 +73,8 @@ public class Variable extends Expression { ...@@ -73,6 +73,8 @@ public class Variable extends Expression {
return true; return true;
case ExpressionVisitor.NOT_FROM_RESOLVER: case ExpressionVisitor.NOT_FROM_RESOLVER:
return true; return true;
case ExpressionVisitor.GET_DEPENDENCIES:
return true;
default: default:
throw Message.getInternalError("type="+visitor.type); throw Message.getInternalError("type="+visitor.type);
} }
......
...@@ -15,6 +15,7 @@ import org.h2.engine.Mode; ...@@ -15,6 +15,7 @@ import org.h2.engine.Mode;
import org.h2.engine.Session; import org.h2.engine.Session;
import org.h2.expression.ConditionAndOr; import org.h2.expression.ConditionAndOr;
import org.h2.expression.Expression; import org.h2.expression.Expression;
import org.h2.expression.ExpressionVisitor;
import org.h2.expression.SequenceValue; import org.h2.expression.SequenceValue;
import org.h2.expression.ValueExpression; import org.h2.expression.ValueExpression;
import org.h2.message.Message; import org.h2.message.Message;
...@@ -490,4 +491,19 @@ public class Column { ...@@ -490,4 +491,19 @@ public class Column {
this.primaryKey = primaryKey; this.primaryKey = primaryKey;
} }
boolean isEverything(ExpressionVisitor visitor) {
if (visitor.type == ExpressionVisitor.GET_DEPENDENCIES) {
if (sequence != null) {
visitor.getDependencies().add(sequence);
}
}
if (defaultExpression != null && !defaultExpression.isEverything(visitor)) {
return false;
}
if (checkConstraint != null && !checkConstraint.isEverything(visitor)) {
return false;
}
return true;
}
} }
...@@ -6,6 +6,7 @@ package org.h2.table; ...@@ -6,6 +6,7 @@ package org.h2.table;
import java.sql.SQLException; import java.sql.SQLException;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet;
import org.h2.command.Prepared; import org.h2.command.Prepared;
import org.h2.constant.ErrorCode; import org.h2.constant.ErrorCode;
...@@ -14,6 +15,7 @@ import org.h2.engine.Constants; ...@@ -14,6 +15,7 @@ import org.h2.engine.Constants;
import org.h2.engine.DbObject; import org.h2.engine.DbObject;
import org.h2.engine.Right; import org.h2.engine.Right;
import org.h2.engine.Session; import org.h2.engine.Session;
import org.h2.expression.ExpressionVisitor;
import org.h2.index.Index; import org.h2.index.Index;
import org.h2.index.IndexType; import org.h2.index.IndexType;
import org.h2.log.UndoLogRecord; import org.h2.log.UndoLogRecord;
...@@ -211,6 +213,19 @@ public abstract class Table extends SchemaObjectBase { ...@@ -211,6 +213,19 @@ public abstract class Table extends SchemaObjectBase {
throw Message.getInternalError(); throw Message.getInternalError();
} }
public void addDependencies(HashSet dependencies) {
if (sequences != null) {
for (int i = 0; i < sequences.size(); i++) {
dependencies.add(sequences.get(i));
}
}
ExpressionVisitor visitor = ExpressionVisitor.get(ExpressionVisitor.GET_DEPENDENCIES);
visitor.setDependencies(dependencies);
for (int i = 0; i < columns.length; i++) {
columns[i].isEverything(visitor);
}
}
public ObjectArray getChildren() { public ObjectArray getChildren() {
ObjectArray children = new ObjectArray(); ObjectArray children = new ObjectArray();
ObjectArray indexes = getIndexes(); ObjectArray indexes = getIndexes();
......
...@@ -24,19 +24,19 @@ public class ChangePassword { ...@@ -24,19 +24,19 @@ public class ChangePassword {
private String cipher; private String cipher;
private byte[] decrypt; private byte[] decrypt;
private byte[] encrypt; private byte[] encrypt;
// TODO security: maybe allow functions in the url // TODO security: maybe allow functions in the url
// jdbc:h2:test;action=[decrypt|encrypt|check|reindex|recover|compress...] // jdbc:h2:test;action=[decrypt|encrypt|check|reindex|recover|compress...]
// and/or implement SQL commands that call this functions (only for the admin) // and/or implement SQL commands that call this functions (only for the admin)
private void showUsage() { private void showUsage() {
System.out.println("java "+getClass().getName() System.out.println("java "+getClass().getName()
+ " [-dir <dir>] [-db <database>] [-cipher <cipher>] [-decrypt <pwd>] [-encrypt <pwd>] [-quiet]"); + " [-dir <dir>] [-db <database>] [-cipher <cipher>] [-decrypt <pwd>] [-encrypt <pwd>] [-quiet]");
} }
/** /**
* The command line interface for this tool. * The command line interface for this tool.
* The options must be split into strings like this: "-db", "test",... * The options must be split into strings like this: "-db", "test",...
* Options are case sensitive. The following options are supported: * Options are case sensitive. The following options are supported:
* <ul> * <ul>
* <li>-help or -? (print the list of options) * <li>-help or -? (print the list of options)
...@@ -47,10 +47,10 @@ public class ChangePassword { ...@@ -47,10 +47,10 @@ public class ChangePassword {
* </li><li>-encrypt password (null if the database should not be encrypted) * </li><li>-encrypt password (null if the database should not be encrypted)
* </li><li>-quiet does not print progress information * </li><li>-quiet does not print progress information
* </li></ul> * </li></ul>
* *
* @param args the command line arguments * @param args the command line arguments
* @throws SQLException * @throws SQLException
*/ */
public static void main(String[] args) throws SQLException { public static void main(String[] args) throws SQLException {
new ChangePassword().run(args); new ChangePassword().run(args);
} }
...@@ -58,8 +58,8 @@ public class ChangePassword { ...@@ -58,8 +58,8 @@ public class ChangePassword {
private void run(String[] args) throws SQLException { private void run(String[] args) throws SQLException {
String dir = "."; String dir = ".";
String cipher = null; String cipher = null;
byte[] decrypt = null; char[] decryptPassword = null;
byte[] encrypt = null; char[] encryptPassword = null;
String db = null; String db = null;
boolean quiet = false; boolean quiet = false;
for (int i = 0; args != null && i < args.length; i++) { for (int i = 0; args != null && i < args.length; i++) {
...@@ -70,9 +70,9 @@ public class ChangePassword { ...@@ -70,9 +70,9 @@ public class ChangePassword {
} else if (args[i].equals("-db")) { } else if (args[i].equals("-db")) {
db = args[++i]; db = args[++i];
} else if (args[i].equals("-decrypt")) { } else if (args[i].equals("-decrypt")) {
decrypt = getFileEncryptionKey(args[++i].toCharArray()); decryptPassword = args[++i].toCharArray();
} else if (args[i].equals("-encrypt")) { } else if (args[i].equals("-encrypt")) {
encrypt = getFileEncryptionKey(args[++i].toCharArray()); encryptPassword = args[++i].toCharArray();
} else if (args[i].equals("-quiet")) { } else if (args[i].equals("-quiet")) {
quiet = true; quiet = true;
} else { } else {
...@@ -80,27 +80,30 @@ public class ChangePassword { ...@@ -80,27 +80,30 @@ public class ChangePassword {
return; return;
} }
} }
if (encrypt == null && decrypt == null) { if (encryptPassword == null && decryptPassword == null) {
showUsage(); showUsage();
return; return;
} }
execute(dir, db, cipher, decrypt, encrypt, quiet); execute(dir, db, cipher, decryptPassword, encryptPassword, quiet);
} }
/** /**
* Get the file encryption key for a given password. * Get the file encryption key for a given password.
* *
* @param password * @param password the password as a char array
* @return the encryption key * @return the encryption key
*/ */
public byte[] getFileEncryptionKey(char[] password) { private static byte[] getFileEncryptionKey(char[] password) {
if (password == null) {
return null;
}
SHA256 sha = new SHA256(); SHA256 sha = new SHA256();
return sha.getKeyPasswordHash("file", password); return sha.getKeyPasswordHash("file", password);
} }
/** /**
* Changes the password for a database. * Changes the password for a database.
* *
* @param dir the directory (. for the current directory) * @param dir the directory (. for the current directory)
* @param db the database name (null for all databases) * @param db the database name (null for all databases)
* @param cipher the cipher (AES, XTEA) * @param cipher the cipher (AES, XTEA)
...@@ -109,12 +112,12 @@ public class ChangePassword { ...@@ -109,12 +112,12 @@ public class ChangePassword {
* @param quiet don't print progress information * @param quiet don't print progress information
* @throws SQLException * @throws SQLException
*/ */
public static void execute(String dir, String db, String cipher, byte[] decrypt, byte[] encrypt, boolean quiet) throws SQLException { public static void execute(String dir, String db, String cipher, char[] decryptPassword, char[] encryptPassword, boolean quiet) throws SQLException {
ChangePassword change = new ChangePassword(); ChangePassword change = new ChangePassword();
change.dir = dir; change.dir = dir;
change.cipher = cipher; change.cipher = cipher;
change.decrypt = decrypt; change.decrypt = getFileEncryptionKey(decryptPassword);
change.encrypt = encrypt; change.encrypt = getFileEncryptionKey(encryptPassword);
// first, test only if the file can be renamed (to find errors with locked files early) // first, test only if the file can be renamed (to find errors with locked files early)
ArrayList files = FileLister.getDatabaseFiles(dir, db, false); ArrayList files = FileLister.getDatabaseFiles(dir, db, false);
...@@ -125,7 +128,7 @@ public class ChangePassword { ...@@ -125,7 +128,7 @@ public class ChangePassword {
FileUtils.rename(fileName, temp); FileUtils.rename(fileName, temp);
FileUtils.rename(temp, fileName); FileUtils.rename(temp, fileName);
} }
// if this worked, the operation will (hopefully) be successful // if this worked, the operation will (hopefully) be successful
// TODO changePassword: this is a workaround! make the operation atomic (all files or none) // TODO changePassword: this is a workaround! make the operation atomic (all files or none)
for (int i = 0; i < files.size(); i++) { for (int i = 0; i < files.size(); i++) {
String fileName = (String) files.get(i); String fileName = (String) files.get(i);
...@@ -133,7 +136,7 @@ public class ChangePassword { ...@@ -133,7 +136,7 @@ public class ChangePassword {
} }
if (files.size() == 0 && !quiet) { if (files.size() == 0 && !quiet) {
System.out.println("No database files found"); System.out.println("No database files found");
} }
} }
private void process(String fileName) throws SQLException { private void process(String fileName) throws SQLException {
......
...@@ -146,7 +146,7 @@ public class ObjectArray { ...@@ -146,7 +146,7 @@ public class ObjectArray {
public void addAll(ObjectArray list) { public void addAll(ObjectArray list) {
for (int i = 0; i < list.size; i++) { for (int i = 0; i < list.size; i++) {
add(list.get(i)); add(list.data[i]);
} }
} }
......
...@@ -150,6 +150,8 @@ java org.h2.test.TestAll timer ...@@ -150,6 +150,8 @@ java org.h2.test.TestAll timer
/* /*
where is base64 code?
Roadmap: Roadmap:
History: History:
......
...@@ -89,6 +89,15 @@ public class TestCrashAPI extends TestBase { ...@@ -89,6 +89,15 @@ public class TestCrashAPI extends TestBase {
Statement stat = conn.createStatement(); Statement stat = conn.createStatement();
stat.execute("SET LOCK_TIMEOUT 10"); stat.execute("SET LOCK_TIMEOUT 10");
stat.execute("SET WRITE_DELAY 0"); stat.execute("SET WRITE_DELAY 0");
if (random.nextBoolean()) {
if (random.nextBoolean()) {
double g = random.nextGaussian();
int size = (int) Math.abs(10000 * g * g);
stat.execute("SET CACHE_SIZE " + size);
} else {
stat.execute("SET CACHE_SIZE 0");
}
}
stat.execute("SCRIPT NOPASSWORDS NOSETTINGS"); stat.execute("SCRIPT NOPASSWORDS NOSETTINGS");
for (int i = start; i < end && i < statements.size(); i++) { for (int i = start; i < end && i < statements.size(); i++) {
try { try {
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论