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

javadoc

上级 1d66e95d
......@@ -12,7 +12,7 @@ import java.sql.SQLException;
* The class must be public and must have a public non-argument constructor.
*/
public interface AggregateFunction {
/**
* This method is called when the aggregate function is used.
* A new object is created for each invocation.
......@@ -20,28 +20,30 @@ public interface AggregateFunction {
* @param conn a connection to the database
*/
void init(Connection conn) throws SQLException;
/**
* This method must return the SQL type of the method,
* given the SQL type of the input data.
* The method should check here if the number of parameters passed is correct,
* and if not it should throw an exception.
*
* and if not it should throw an exception.
*
* @param inputType the SQL type of the parameters
* @return the SQL type of the result
*/
int getType(int[] inputType) throws SQLException;
/**
* This method is called once for each row.
* If the aggregate function is called with multiple parameters, those are passed as array.
*
*
* @param value the value(s) for this row
*/
void add(Object value) throws SQLException;
/**
* This method returns the computed aggregate value.
*
* @return the aggregated value
*/
Object getResult() throws SQLException;
}
......@@ -14,7 +14,25 @@ import java.util.EventListener;
*/
public interface DatabaseEventListener extends EventListener {
int STATE_SCAN_FILE = 0, STATE_CREATE_INDEX = 1, STATE_RECOVER = 2, STATE_BACKUP_FILE = 3;
/**
* This state is used when scanning the data or index file.
*/
int STATE_SCAN_FILE = 0;
/**
* This state is used when re-creating an index.
*/
int STATE_CREATE_INDEX = 1;
/**
* This state is used when re-applying the transaction log or rolling back uncommitted transactions.
*/
int STATE_RECOVER = 2;
/**
* This state is used during the BACKUP command.
*/
int STATE_BACKUP_FILE = 3;
/**
* This method is called just after creating the object.
......@@ -24,7 +42,7 @@ public interface DatabaseEventListener extends EventListener {
* @param url - the database URL
*/
void init(String url);
/**
* This method is called after the database has been opened.
* It is save to connect to the database and execute statements at this point.
......@@ -32,7 +50,7 @@ public interface DatabaseEventListener extends EventListener {
void opened();
/**
* This method is called if the disk space is very low.
* This method is called if the disk space is very low.
* One strategy is to inform the user and wait for it to clean up disk space.
* Another strategy is to send an email to the administrator in this method and
* then throw a SQLException. The database should not be accessed from
......
......@@ -9,13 +9,24 @@ import java.sql.SQLException;
/**
* A class that implements this interface can be used as a trigger.
*
* @author Thomas
*/
public interface Trigger {
int INSERT = 1, UPDATE = 2, DELETE = 4;
/**
* The trigger is called for INSERT statements.
*/
int INSERT = 1;
/**
* The trigger is called for UPDATE statements.
*/
int UPDATE = 2;
/**
* The trigger is called for DELETE statements.
*/
int DELETE = 4;
/**
* This method is called by the database engine once when initializing the trigger.
......
......@@ -13,11 +13,51 @@ import org.h2.util.ObjectArray;
* Represents a SQL statement.
*/
public interface CommandInterface {
/**
* Check if this is a query.
*
* @return true if it is a query
*/
boolean isQuery();
/**
* Get the parameters (if any).
*
* @return the parameters
*/
ObjectArray getParameters();
/**
* Execute the query.
*
* @param maxRows the maximum number of rows returned
* @param scrollable if the result set must be scrollable
* @return the result
*/
ResultInterface executeQuery(int maxRows, boolean scrollable) throws SQLException;
/**
* Execute the statement
*
* @return the update count
*/
int executeUpdate() throws SQLException;
/**
* Close the statement.
*/
void close();
/**
* Cancel the statement if it is still processing.
*/
void cancel();
/**
* Get an empty result set containing the meta data of the result.
*
* @return the empty result
*/
ResultInterface getMetaData() throws SQLException;
}
......@@ -89,8 +89,8 @@ public class CreateTrigger extends SchemaCommand {
trigger.setNoWait(noWait);
trigger.setQueueSize(queueSize);
trigger.setRowBased(rowBased);
trigger.setTriggerClassName(session, triggerClassName);
trigger.setTypeMask(typeMask);
trigger.setTriggerClassName(session, triggerClassName);
db.addSchemaObject(session, trigger);
table.addTrigger(trigger);
return 0;
......
......@@ -11,10 +11,48 @@ import java.sql.SQLException;
*/
public interface Compressor {
int NO = 0, LZF = 1, DEFLATE = 2;
/**
* No compression is used.
*/
int NO = 0;
/**
* The LZF compression algorithm is used
*/
int LZF = 1;
/**
* The DEFLATE compression algorithm is used.
*/
int DEFLATE = 2;
/**
* Get the compression algorithm type.
*
* @return the type
*/
int getAlgorithm();
/**
* Compress a number of bytes.
*
* @param in the input data
* @param inLen the number of bytes to compress
* @param out the output area
* @param outPos the offset at the output array
* @return the size of the compressed data
*/
int compress(byte[] in, int inLen, byte[] out, int outPos);
/**
* Expand a number of compressed bytes.
* @param in the compressed data
* @param inPos the offset at the input array
* @param inLen the number of bytes to read
* @param out the output area
* @param outPos the offset at the output array
* @param outLen the size of the uncompressed data
*/
void expand(byte[] in, int inPos, int inLen, byte[] out, int outPos, int outLen) throws SQLException;
void setOptions(String options) throws SQLException;
}
......@@ -72,6 +72,7 @@ public class SysProperties {
public static final boolean NEW_DISPLAY_SIZE = getBooleanSetting("h2.newDisplaySize", true);
public static final int DEFAULT_MAX_OPERATION_MEMORY = getIntSetting("h2.defaultMaxOperationMemory", 100000);
public static final String ALLOWED_CLASSES = getStringSetting("h2.allowedClasses", "*");
public static final int MIN_COLUMN_NAME_MAP = getIntSetting("h2.minColumnNameMap", 3);
private static boolean getBooleanSetting(String name, boolean defaultValue) {
String s = getProperty(name);
......
......@@ -11,7 +11,7 @@ import org.h2.constant.SysProperties;
* - Test with Hibernate
* - Run FindBugs
* - ant jarClient, check jar file size
*
*
* - Compile with JDK 1.4, 1.5 and 1.6:
* set path=C:\Programme\Java\jdk1.6.0\bin;%PATH%
* set JAVA_HOME=C:\Programme\Java\jdk1.6.0
......@@ -23,8 +23,8 @@ import org.h2.constant.SysProperties;
* ant javadocImpl (to find missing javadocs)
* ant codeswitchJdk14
* ant javadocImpl
*
* - Change version and build number in
*
* - Change version and build number in
* Constants.java
* ant-build.properties
* build.html
......@@ -35,7 +35,7 @@ import org.h2.constant.SysProperties;
* - No " Message.getInternalError" (must be "throw Message.getInternalError")
* - No TODO in the docs, remove @~ in .utf8.txt files
* - Run regression test with JDK 1.4 and 1.5
*
*
* - Change version(s) in performance.html; use latest versions of other databases
* - Run 'ant benchmark' (with JDK 1.4 currently)
* - Copy the benchmark results and update the performance page and diagram
......@@ -66,8 +66,6 @@ import org.h2.constant.SysProperties;
* - Add to freshmeat
* - Upload to http://code.google.com/p/h2database/downloads/list
* - svn copy: .../svn/trunk .../svn/tags/version-1.0.x; Version 1.0.x (yyyy-mm-dd)
*
* @author Thomas
*/
/**
* Constants are fixed values that are used in the whole database code.
......@@ -172,7 +170,7 @@ public class Constants {
public static final int VIEW_INDEX_CACHE_SIZE = 64;
public static final int VIEW_COST_CACHE_MAX_AGE = 10000; // 10 seconds
public static final int MAX_PARAMETER_INDEX = 100000;
// to slow down dictionary attacks
public static final int ENCRYPTION_KEY_HASH_ITERATIONS = 1024;
public static final String SCRIPT_SQL = "script.sql";
......
......@@ -14,12 +14,62 @@ import org.h2.store.DataHandler;
* A local or remote session. A session represents a database connection.
*/
public interface SessionInterface {
/**
* Parse a command and prepare it for execution.
*
* @param sql the SQL statement
* @return the prepared command
*/
CommandInterface prepareCommand(String sql) throws SQLException;
/**
* Roll back pending transactions and close the session.
*/
void close() throws SQLException;
/**
* Get the trace object
*
* @return the trace object
*/
Trace getTrace();
/**
* Check if close was called.
*
* @return if the session has been closed
*/
boolean isClosed();
/**
* Open a new session.
*
* @param ci the connection parameters
* @return the new session
*/
SessionInterface createSession(ConnectionInfo ci) throws SQLException;
/**
* Get the number of disk operations before power failure is simulated.
* This is used for testing. If not set, 0 is returned
*
* @return the number of operations, or 0
*/
int getPowerOffCount();
/**
* Set the number of disk operations before power failure is simulated.
* To disable the countdown, use 0.
*
* @param i the number of operations
*/
void setPowerOffCount(int i) throws SQLException;
/**
* Get the data handler object.
*
* @return the data handler
*/
DataHandler getDataHandler();
}
......@@ -16,13 +16,64 @@ import org.h2.value.ValueResultSet;
*/
public interface FunctionCall {
/**
* Get the name of the function.
*
* @return the name
*/
String getName();
/**
* Get the number of parameters.
*
* @return the number of parameters
*/
int getParameterCount() throws SQLException;
/**
* Get an empty result set with the column names set.
*
* @param session the session
* @param nullArgs the argument list (some arguments may be null)
* @return the empty result set
*/
ValueResultSet getValueForColumnList(Session session, Expression[] nullArgs) throws SQLException;
/**
* Get the data type.
*
* @return the data type
*/
int getType();
/**
* Optimize the function if possible.
*
* @param session the session
* @return the optimized expression
*/
Expression optimize(Session session) throws SQLException;
/**
* Calculate the result.
*
* @param session the session
* @return the result
*/
Value getValue(Session session) throws SQLException;
/**
* Get the function arguments.
*
* @return argument list
*/
Expression[] getArgs();
/**
* Get the SQL snippet of the function (including arguments).
*
* @return the SQL snippet.
*/
String getSQL();
}
......@@ -12,7 +12,25 @@ import org.h2.value.Value;
* The interface for client side (remote) and server side parameters.
*/
public interface ParameterInterface {
/**
* Set the value of the parameter.
*
* @param value the new value
*/
void setValue(Value value);
/**
* Get the value of the parameter if set.
*
* @return the value or null
*/
Value getParamValue() throws SQLException;
/**
* Check if the value is set.
*
* @throws SQLException if not set.
*/
void checkSet() throws SQLException;
}
......@@ -23,9 +23,9 @@ import org.h2.value.Value;
* An outer page of a btree index.
*
* Page format:
* <pre>
* L { P(pointers) | D(data) } data.len { data[0].pos [data[0]], ... }
*
* @author Thomas
* </pre>
*/
public class BtreeLeaf extends BtreePage {
......
......@@ -23,9 +23,9 @@ import org.h2.value.Value;
* An inner page of a b-tree index.
*
* Page format:
* <pre>
* N children.len children[0..len] data.len { data[0].pos [data[0]], ... }
*
* @author Thomas
*</pre>
*/
public class BtreeNode extends BtreePage {
......
......@@ -21,9 +21,11 @@ import java.sql.Statement;
import java.sql.Time;
import java.sql.Timestamp;
import java.util.Calendar;
import java.util.HashMap;
import java.util.Map;
import org.h2.constant.ErrorCode;
import org.h2.constant.SysProperties;
import org.h2.engine.Constants;
import org.h2.engine.SessionInterface;
import org.h2.message.Message;
......@@ -69,6 +71,7 @@ public class JdbcResultSet extends TraceObject implements ResultSet {
private boolean wasNull;
private Value[] insertRow;
private Value[] updateRow;
private HashMap columnNameMap;
JdbcResultSet(SessionInterface session, JdbcConnection conn, JdbcStatement stat, ResultInterface result, int id, boolean closeStatement, boolean scrollable) {
setTrace(session.getTrace(), TraceObject.RESULT_SET, id);
......@@ -2819,6 +2822,31 @@ public class JdbcResultSet extends TraceObject implements ResultSet {
if (columnName == null) {
throw Message.getInvalidValueException("columnName", null);
}
if (columnCount >= SysProperties.MIN_COLUMN_NAME_MAP) {
if (columnNameMap == null) {
HashMap map = new HashMap(columnCount);
for (int i = 0; i < columnCount; i++) {
String c = result.getAlias(i).toUpperCase();
map.put(c, ObjectUtils.getInteger(i));
String tabName = result.getTableName(i);
if (tabName != null) {
String colName = result.getColumnName(i);
if (colName != null) {
c = tabName + "." + colName;
if (!map.containsKey(c)) {
map.put(c, ObjectUtils.getInteger(i));
}
}
}
}
columnNameMap = map;
}
Integer index = (Integer) columnNameMap.get(columnName.toUpperCase());
if (index == null) {
throw Message.getSQLException(ErrorCode.COLUMN_NOT_FOUND_1, columnName);
}
return index.intValue() + 1;
}
for (int i = 0; i < columnCount; i++) {
if (columnName.equalsIgnoreCase(result.getAlias(i))) {
return i + 1;
......@@ -2829,7 +2857,7 @@ public class JdbcResultSet extends TraceObject implements ResultSet {
String table = columnName.substring(0, idx);
String col = columnName.substring(idx+1);
for (int i = 0; i < columnCount; i++) {
if (table.equals(result.getTableName(i)) && col.equalsIgnoreCase(result.getColumnName(i))) {
if (table.equalsIgnoreCase(result.getTableName(i)) && col.equalsIgnoreCase(result.getColumnName(i))) {
return i + 1;
}
}
......
......@@ -13,21 +13,117 @@ import org.h2.value.Value;
* The most important implementing class is a database.
*/
public interface DataHandler {
/**
* Check if text storage is used.
*
* @return if text storage is used.
*/
boolean getTextStorage();
/**
* Get the database path.
*
* @return the database path
*/
String getDatabasePath();
/**
* Open a file at the given location.
*
* @param name the file name
* @param mode the mode
* @param mustExist whether the file must already exist
* @return the file
*/
FileStore openFile(String name, String mode, boolean mustExist) throws SQLException;
/**
* Calculate the checksum for the byte array.
*
* @param data the byte array
* @param start the starting offset
* @param end the end offset
* @return the checksum
*/
int getChecksum(byte[] data, int start, int end);
/**
* Check if the simulated power failure occured.
* This call will decrement the countdown.
*
* @throws SQLException if the simulated power failure occured
*/
void checkPowerOff() throws SQLException;
/**
* Check if writing is allowed.
*
* @throws SQLException if it is not allowed
*/
void checkWritingAllowed() throws SQLException;
/**
* Free up disk space if possible.
* This method is called if more space is needed.
*
* @throws SQLException if no more space could be freed
*/
void freeUpDiskSpace() throws SQLException;
/**
* Called when the checksum was invalid.
*
* @throws SQLException if this should not be ignored
*/
void handleInvalidChecksum() throws SQLException;
/**
* Compare two values.
*
* @param a the first value
* @param b the second value
* @return 0 for equal, 1 if a is larger than b, and -1 otherwise
*/
int compareTypeSave(Value a, Value b) throws SQLException;
/**
* Get the maximum length of a in-place large object
*
* @return the maximum size
*/
int getMaxLengthInplaceLob();
/**
* Get the compression algorithm used for large objects.
*
* @param type the data type (CLOB or BLOB)
* @return the compression algorithm, or null
*/
String getLobCompressionAlgorithm(int type);
// only temporarily, until LOB_FILES_IN_DIRECTORIES is enabled
/**
* Get the next object id.
* This method is not required if LOB_FILES_IN_DIRECTORIES is enabled.
*
* @param needFresh if a fresh id is required
* @param dataFile true if the id is for the data file
* @return the new id
*/
int allocateObjectId(boolean needFresh, boolean dataFile);
/**
* Create a temporary file and return the file name.
*
* @return the file name
*/
String createTempFile() throws SQLException;
/**
* Get the synchronization object for lob operations.
*
* @return the synchronization object
*/
Object getLobSyncObject();
}
......@@ -11,5 +11,13 @@ import org.h2.engine.Session;
* A record reader is able to create a {@link Record} from a {@link DataPage}.
*/
public interface RecordReader {
/**
* Read a record from the data page.
*
* @param session the session
* @param s the data page
* @return the record
*/
Record read(Session session, DataPage s) throws SQLException;
}
......@@ -10,17 +10,59 @@ import org.h2.command.dml.Select;
import org.h2.value.Value;
/**
* A column resolver is list of column (for example, a table) that can map a
* A column resolver is list of column (for example, a table) that can map a
* column name to an actual column.
*/
public interface ColumnResolver {
/**
* Get the table alias.
*
* @return the table alias
*/
String getTableAlias();
/**
* Get the column list.
*
* @return the column list
*/
Column[] getColumns();
/**
* Get the list of system columns, if any.
*
* @return the system columns
*/
Column[] getSystemColumns();
/**
* Get the schema name.
*
* @return the schema name
*/
String getSchemaName();
/**
* Get the value for the given column.
*
* @param column the column
* @return the value
*/
Value getValue(Column column) throws SQLException;
/**
* Get the table filter.
*
* @return the table filter
*/
TableFilter getTableFilter();
/**
* Get the select statement.
*
* @return the select statement
*/
Select getSelect();
}
......@@ -62,7 +62,7 @@ public interface Cache {
* This will not move the item to the front of the list.
*
* @param pos the unique key of the element
* @return
* @return the element or null
*/
CacheObject find(int pos);
......
......@@ -152,6 +152,7 @@ java org.h2.test.TestAll timer
/*
History:
The performance has been improved for ResultSet methods with column name.
The method Trigger.init has been changed: the parameters 'before' and 'type', have been added to the init method.
C:\temp\test\db
......
......@@ -145,11 +145,11 @@ public class TestTriggersConstraints extends TestBase implements Trigger {
if (!"TEST".equals(tableName)) {
throw new Error("supposed to be TEST");
}
if (!before) {
throw new Error("before:" + before);
if ((triggerName.endsWith("AFTER") && before) || (triggerName.endsWith("BEFORE") && !before)) {
throw new Error("triggerName: " + triggerName + " before:" + before);
}
if (type != INSERT) {
throw new Error("type:" + type);
if ((triggerName.startsWith("UPD") && type != UPDATE) || (triggerName.startsWith("INS") && type != INSERT) || (triggerName.startsWith("DEL") && type != DELETE)) {
throw new Error("triggerName: " + triggerName + " type:" + type);
}
}
......
......@@ -35,6 +35,8 @@ public class TestResultSet extends TestBase {
stat = conn.createStatement();
testFindColumn();
testColumnLength();
testArray();
testLimitMaxRows();
......@@ -58,11 +60,49 @@ public class TestResultSet extends TestBase {
}
private void testFindColumn() throws Exception {
trace("testFindColumn");
ResultSet rs;
stat.execute("CREATE TABLE TEST(ID INT, NAME VARCHAR)");
rs = stat.executeQuery("SELECT * FROM TEST");
check(rs.findColumn("ID"), 1);
check(rs.findColumn("NAME"), 2);
check(rs.findColumn("id"), 1);
check(rs.findColumn("name"), 2);
check(rs.findColumn("Id"), 1);
check(rs.findColumn("Name"), 2);
check(rs.findColumn("TEST.ID"), 1);
check(rs.findColumn("TEST.NAME"), 2);
check(rs.findColumn("Test.Id"), 1);
check(rs.findColumn("Test.Name"), 2);
stat.execute("DROP TABLE TEST");
stat.execute("CREATE TABLE TEST(ID INT, NAME VARCHAR, DATA VARCHAR)");
rs = stat.executeQuery("SELECT * FROM TEST");
check(rs.findColumn("ID"), 1);
check(rs.findColumn("NAME"), 2);
check(rs.findColumn("DATA"), 3);
check(rs.findColumn("id"), 1);
check(rs.findColumn("name"), 2);
check(rs.findColumn("data"), 3);
check(rs.findColumn("Id"), 1);
check(rs.findColumn("Name"), 2);
check(rs.findColumn("Data"), 3);
check(rs.findColumn("TEST.ID"), 1);
check(rs.findColumn("TEST.NAME"), 2);
check(rs.findColumn("TEST.DATA"), 3);
check(rs.findColumn("Test.Id"), 1);
check(rs.findColumn("Test.Name"), 2);
check(rs.findColumn("Test.Data"), 3);
stat.execute("DROP TABLE TEST");
}
private void testColumnLength() throws Exception {
trace("testColumnDisplayLength");
ResultSet rs;
ResultSetMetaData meta;
stat.execute("CREATE TABLE one (ID INT, NAME VARCHAR(255))");
rs = stat.executeQuery("select * from one");
meta = rs.getMetaData();
......@@ -71,22 +111,22 @@ public class TestResultSet extends TestBase {
check("NAME", meta.getColumnLabel(2));
check(255, meta.getColumnDisplaySize(2));
stat.execute("DROP TABLE one");
rs = stat.executeQuery("select 1, 'Hello' union select 2, 'Hello World!'");
meta = rs.getMetaData();
check(11, meta.getColumnDisplaySize(1));
check(12, meta.getColumnDisplaySize(2));
rs = stat.executeQuery("explain select * from dual");
meta = rs.getMetaData();
check(Integer.MAX_VALUE, meta.getColumnDisplaySize(1));
check(Integer.MAX_VALUE, meta.getPrecision(1));
rs = stat.executeQuery("script");
meta = rs.getMetaData();
check(Integer.MAX_VALUE, meta.getColumnDisplaySize(1));
check(Integer.MAX_VALUE, meta.getPrecision(1));
rs = stat.executeQuery("select group_concat(table_name) from information_schema.tables");
rs.next();
meta = rs.getMetaData();
......
......@@ -516,4 +516,5 @@ webtest einstellung redirects endless ran gives replication lxabcdef asf package
russian backward alexahin vlad ffffffffffff bfff ffffffff webapp undeploy initializer brasil uncached slowing translating uploaded
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
\ No newline at end of file
involves ukrainian chile machines restricting summer aliased backus naur multiples avl operates grow normalized rijndael
countdown
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论