提交 f0dd328d authored 作者: Thomas Mueller's avatar Thomas Mueller

Documentation, formatting (remove trailing spaces)

上级 0f64da5b
......@@ -60,7 +60,7 @@ Change Log
in the Session query cache being invalidated.
</li><li>New feature from Davide Cavestro - allow using custom Java object serialization
engines on a per-DB basis.
</li><li>When running the Recover tool on very large (>6G) databases, some statistics were reported with
</li><li>When running the Recover tool on very large (&gt;6G) databases, some statistics were reported with
negative numbers.
</li><li>Add a CONTAINS_UNCOMMITTED column to the SESSIONS metadata table, to allow detecting when rogue
sessions are creating large transactions.
......@@ -84,14 +84,14 @@ Change Log
extremely large statements.
</li><li>Fix bug with ALLOW_LITERALS=NONE, where the periodic analyze table on insert would throw an exception.
</li><li>Issue 510: Make org.h2.bnf public for consumption by external projects, patch by Nicolas Fortin
</li><li>Issue 509: Important fix on ValueGeometry, patch by Nicolas Fortin (with some tweaking)
</li><li>Issue 509: Important fix on ValueGeometry, patch by Nicolas Fortin (with some tweaking)
Make ValueGeometry#getDimensionCount more reliable.
Add unit test to check for illegal ValueGeometry comparison
Add unit test for conversion of Geometry object into Object
Add optional export to MANIFEST.MF for JTS Geometry classes
Validate that geometry values can be represented in WKB.
</li><li>Issue 506: RFE: Include Thread.getName() in case of a deadlock
</li><li>Adding support for "GRANT ALTER ANY SCHEMA TO <user>", patch by John Yates
</li><li>Adding support for "GRANT ALTER ANY SCHEMA TO &lt;user&gt;", patch by John Yates
</li></ul>
<h2>Version 1.3.173 (2013-07-28)</h2>
......
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
/*
* Copyright 2004-2013 H2 Group. Multiple-Licensed under the H2 License,
* Version 1.0, and under the Eclipse Public License, Version 1.0
* (http://h2database.com/html/license.html).
* Initial Developer: H2 Group
*/
package org.h2.bnf.context;
import java.sql.DatabaseMetaData;
import java.sql.ResultSet;
import java.sql.SQLException;
/**
* Keeps the meta data information of a column.
* This class is used by the H2 Console.
*/
public class DbColumn {
private final String name;
private final String quotedName;
private final String dataType;
private int position;
public DbColumn(DbContents contents, ResultSet rs) throws SQLException {
name = rs.getString("COLUMN_NAME");
quotedName = contents.quoteIdentifier(name);
String type = rs.getString("TYPE_NAME");
// A procedures column size is identified by PRECISION, for table this is COLUMN_SIZE
int precisionColumnIndex = DbContents.findColumn(rs, "PRECISION", 0);
int size;
if (precisionColumnIndex == 0) {
size = rs.getInt(DbContents.findColumn(rs, "COLUMN_SIZE", 7));
} else {
size = rs.getInt(precisionColumnIndex);
}
position = rs.getInt("ORDINAL_POSITION");
boolean isSQLite = contents.isSQLite();
if (size > 0 && !isSQLite) {
type += "(" + size;
int prec = rs.getInt(DbContents.findColumn(rs, "DECIMAL_DIGITS", 9));
if (prec > 0) {
type += ", " + prec;
}
type += ")";
}
if (rs.getInt("NULLABLE") == DatabaseMetaData.columnNoNulls) {
type += " NOT NULL";
}
dataType = type;
}
/**
* @return The data type name (including precision and the NOT NULL flag if
* applicable).
*/
public String getDataType() {
return dataType;
}
/**
* @return The column name.
*/
public String getName() {
return name;
}
/**
* @return The quoted table name.
*/
public String getQuotedName() {
return quotedName;
}
/**
* @return Column index
*/
public int getPosition() {
return position;
}
}
/*
* Copyright 2004-2013 H2 Group. Multiple-Licensed under the H2 License,
* Version 1.0, and under the Eclipse Public License, Version 1.0
* (http://h2database.com/html/license.html).
* Initial Developer: H2 Group
*/
package org.h2.bnf.context;
import java.sql.DatabaseMetaData;
import java.sql.ResultSet;
import java.sql.SQLException;
/**
* Keeps the meta data information of a column.
* This class is used by the H2 Console.
*/
public class DbColumn {
private final String name;
private final String quotedName;
private final String dataType;
private int position;
public DbColumn(DbContents contents, ResultSet rs) throws SQLException {
name = rs.getString("COLUMN_NAME");
quotedName = contents.quoteIdentifier(name);
String type = rs.getString("TYPE_NAME");
// a procedures column size is identified by PRECISION, for table this
// is COLUMN_SIZE
int precisionColumnIndex = DbContents.findColumn(rs, "PRECISION", 0);
int size;
if (precisionColumnIndex == 0) {
size = rs.getInt(DbContents.findColumn(rs, "COLUMN_SIZE", 7));
} else {
size = rs.getInt(precisionColumnIndex);
}
position = rs.getInt("ORDINAL_POSITION");
boolean isSQLite = contents.isSQLite();
if (size > 0 && !isSQLite) {
type += "(" + size;
int prec = rs.getInt(DbContents.findColumn(rs, "DECIMAL_DIGITS", 9));
if (prec > 0) {
type += ", " + prec;
}
type += ")";
}
if (rs.getInt("NULLABLE") == DatabaseMetaData.columnNoNulls) {
type += " NOT NULL";
}
dataType = type;
}
/**
* @return The data type name (including precision and the NOT NULL flag if
* applicable).
*/
public String getDataType() {
return dataType;
}
/**
* @return The column name.
*/
public String getName() {
return name;
}
/**
* @return The quoted table name.
*/
public String getQuotedName() {
return quotedName;
}
/**
* @return Column index
*/
public int getPosition() {
return position;
}
}
/*
* Copyright 2004-2013 H2 Group. Multiple-Licensed under the H2 License,
* Version 1.0, and under the Eclipse Public License, Version 1.0
* (http://h2database.com/html/license.html).
* Initial Developer: H2 Group
*/
package org.h2.bnf.context;
import java.sql.DatabaseMetaData;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import org.h2.command.Parser;
import org.h2.util.New;
import org.h2.util.StringUtils;
/**
* Keeps meta data information about a database.
* This class is used by the H2 Console.
*/
public class DbContents {
private DbSchema[] schemas;
private DbSchema defaultSchema;
private boolean isOracle;
private boolean isH2;
private boolean isPostgreSQL;
private boolean isDerby;
private boolean isSQLite;
private boolean isH2ModeMySQL;
private boolean isMySQL;
private boolean isFirebird;
private boolean isMSSQLServer;
/**
* @return The default schema.
*/
public DbSchema getDefaultSchema() {
return defaultSchema;
}
/**
* @return True if this is an Apache Derby database.
*/
public boolean isDerby() {
return isDerby;
}
/**
* @return True if this is a Firebird database.
*/
public boolean isFirebird() {
return isFirebird;
}
/**
* @return True if this is a H2 database.
*/
public boolean isH2() {
return isH2;
}
/**
* @return True if this is a H2 database in MySQL mode.
*/
public boolean isH2ModeMySQL() {
return isH2ModeMySQL;
}
/**
* @return True if this is a MS SQL Server database.
*/
public boolean isMSSQLServer() {
return isMSSQLServer;
}
/**
* @return True if this is a MySQL database.
*/
public boolean isMySQL() {
return isMySQL;
}
/**
* @return True if this is an Oracle database.
*/
public boolean isOracle() {
return isOracle;
}
/**
* @return True if this is a PostgreSQL database.
*/
public boolean isPostgreSQL() {
return isPostgreSQL;
}
/**
* @return True if this is an SQLite database.
*/
public boolean isSQLite() {
return isSQLite;
}
/**
* @return The list of schemas.
*/
public DbSchema[] getSchemas() {
return schemas;
}
/**
* Get the column index of a column in a result set. If the column is not
* found, the default column index is returned.
* This is a workaround for a JDBC-ODBC bridge problem.
*
* @param rs the result set
* @param columnName the column name
* @param defaultColumnIndex the default column index
* @return the column index
*/
public static int findColumn(ResultSet rs, String columnName, int defaultColumnIndex) {
try {
return rs.findColumn(columnName);
} catch (SQLException e) {
return defaultColumnIndex;
}
}
/**
* Read the contents of this database from the database meta data.
*
* @param meta the database meta data
*/
public synchronized void readContents(DatabaseMetaData meta) throws SQLException {
String prod = StringUtils.toLowerEnglish(meta.getDatabaseProductName());
isSQLite = prod.indexOf("sqlite") >= 0;
String url = meta.getURL();
if (url != null) {
isH2 = url.startsWith("jdbc:h2:");
if (isH2) {
Statement stat = meta.getConnection().createStatement();
ResultSet rs = stat.executeQuery(
"SELECT UPPER(VALUE) FROM INFORMATION_SCHEMA.SETTINGS WHERE NAME='MODE'");
rs.next();
if ("MYSQL".equals(rs.getString(1))) {
isH2ModeMySQL = true;
}
rs.close();
stat.close();
}
isOracle = url.startsWith("jdbc:oracle:");
isPostgreSQL = url.startsWith("jdbc:postgresql:");
// isHSQLDB = url.startsWith("jdbc:hsqldb:");
isMySQL = url.startsWith("jdbc:mysql:");
isDerby = url.startsWith("jdbc:derby:");
isFirebird = url.startsWith("jdbc:firebirdsql:");
isMSSQLServer = url.startsWith("jdbc:sqlserver:");
}
String defaultSchemaName = getDefaultSchemaName(meta);
String[] schemaNames = getSchemaNames(meta);
schemas = new DbSchema[schemaNames.length];
for (int i = 0; i < schemaNames.length; i++) {
String schemaName = schemaNames[i];
boolean isDefault = defaultSchemaName == null || defaultSchemaName.equals(schemaName);
DbSchema schema = new DbSchema(this, schemaName, isDefault);
if (schema.isDefault) {
defaultSchema = schema;
}
schemas[i] = schema;
String[] tableTypes = { "TABLE", "SYSTEM TABLE", "VIEW", "SYSTEM VIEW",
"TABLE LINK", "SYNONYM", "EXTERNAL" };
schema.readTables(meta, tableTypes);
schema.readProcedures(meta);
}
if (defaultSchema == null) {
String best = null;
for (DbSchema schema : schemas) {
if ("dbo".equals(schema.name)) {
// MS SQL Server
defaultSchema = schema;
break;
}
if (defaultSchema == null || best == null || schema.name.length() < best.length()) {
best = schema.name;
defaultSchema = schema;
}
}
}
}
private String[] getSchemaNames(DatabaseMetaData meta) throws SQLException {
if (isMySQL || isSQLite) {
return new String[] { "" };
} else if (isFirebird) {
return new String[] { null };
}
ResultSet rs = meta.getSchemas();
ArrayList<String> schemaList = New.arrayList();
while (rs.next()) {
String schema = rs.getString(findColumn(rs, "TABLE_SCHEM", 1));
String[] ignoreNames = null;
if (isOracle) {
ignoreNames = new String[] { "CTXSYS", "DIP", "DBSNMP",
"DMSYS", "EXFSYS", "FLOWS_020100", "FLOWS_FILES",
"MDDATA", "MDSYS", "MGMT_VIEW", "OLAPSYS", "ORDSYS",
"ORDPLUGINS", "OUTLN", "SI_INFORMTN_SCHEMA", "SYS",
"SYSMAN", "SYSTEM", "TSMSYS", "WMSYS", "XDB" };
} else if (isMSSQLServer) {
ignoreNames = new String[] { "sys", "db_accessadmin",
"db_backupoperator", "db_datareader", "db_datawriter",
"db_ddladmin", "db_denydatareader",
"db_denydatawriter", "db_owner", "db_securityadmin" };
}
if (ignoreNames != null) {
for (String ignore : ignoreNames) {
if (ignore.equals(schema)) {
schema = null;
break;
}
}
}
if (schema == null) {
continue;
}
schemaList.add(schema);
}
rs.close();
String[] list = new String[schemaList.size()];
schemaList.toArray(list);
return list;
}
private String getDefaultSchemaName(DatabaseMetaData meta) {
String defaultSchemaName = "";
try {
if (isOracle) {
return meta.getUserName();
} else if (isPostgreSQL) {
return "public";
} else if (isMySQL) {
return "";
} else if (isDerby) {
return StringUtils.toUpperEnglish(meta.getUserName());
} else if (isFirebird) {
return null;
}
ResultSet rs = meta.getSchemas();
int index = rs.findColumn("IS_DEFAULT");
while (rs.next()) {
if (rs.getBoolean(index)) {
defaultSchemaName = rs.getString("TABLE_SCHEM");
}
}
} catch (SQLException e) {
// IS_DEFAULT not found
}
return defaultSchemaName;
}
/**
* Add double quotes around an identifier if required.
* For the H2 database, all identifiers are quoted.
*
* @param identifier the identifier
* @return the quoted identifier
*/
public String quoteIdentifier(String identifier) {
if (identifier == null) {
return null;
}
if (isH2 && !isH2ModeMySQL) {
return Parser.quoteIdentifier(identifier);
}
return StringUtils.toUpperEnglish(identifier);
}
}
/*
* Copyright 2004-2013 H2 Group. Multiple-Licensed under the H2 License,
* Version 1.0, and under the Eclipse Public License, Version 1.0
* (http://h2database.com/html/license.html).
* Initial Developer: H2 Group
*/
package org.h2.bnf.context;
import java.sql.DatabaseMetaData;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import org.h2.command.Parser;
import org.h2.util.New;
import org.h2.util.StringUtils;
/**
* Keeps meta data information about a database.
* This class is used by the H2 Console.
*/
public class DbContents {
private DbSchema[] schemas;
private DbSchema defaultSchema;
private boolean isOracle;
private boolean isH2;
private boolean isPostgreSQL;
private boolean isDerby;
private boolean isSQLite;
private boolean isH2ModeMySQL;
private boolean isMySQL;
private boolean isFirebird;
private boolean isMSSQLServer;
/**
* @return The default schema.
*/
public DbSchema getDefaultSchema() {
return defaultSchema;
}
/**
* @return True if this is an Apache Derby database.
*/
public boolean isDerby() {
return isDerby;
}
/**
* @return True if this is a Firebird database.
*/
public boolean isFirebird() {
return isFirebird;
}
/**
* @return True if this is a H2 database.
*/
public boolean isH2() {
return isH2;
}
/**
* @return True if this is a H2 database in MySQL mode.
*/
public boolean isH2ModeMySQL() {
return isH2ModeMySQL;
}
/**
* @return True if this is a MS SQL Server database.
*/
public boolean isMSSQLServer() {
return isMSSQLServer;
}
/**
* @return True if this is a MySQL database.
*/
public boolean isMySQL() {
return isMySQL;
}
/**
* @return True if this is an Oracle database.
*/
public boolean isOracle() {
return isOracle;
}
/**
* @return True if this is a PostgreSQL database.
*/
public boolean isPostgreSQL() {
return isPostgreSQL;
}
/**
* @return True if this is an SQLite database.
*/
public boolean isSQLite() {
return isSQLite;
}
/**
* @return The list of schemas.
*/
public DbSchema[] getSchemas() {
return schemas;
}
/**
* Get the column index of a column in a result set. If the column is not
* found, the default column index is returned.
* This is a workaround for a JDBC-ODBC bridge problem.
*
* @param rs the result set
* @param columnName the column name
* @param defaultColumnIndex the default column index
* @return the column index
*/
public static int findColumn(ResultSet rs, String columnName, int defaultColumnIndex) {
try {
return rs.findColumn(columnName);
} catch (SQLException e) {
return defaultColumnIndex;
}
}
/**
* Read the contents of this database from the database meta data.
*
* @param meta the database meta data
*/
public synchronized void readContents(DatabaseMetaData meta) throws SQLException {
String prod = StringUtils.toLowerEnglish(meta.getDatabaseProductName());
isSQLite = prod.indexOf("sqlite") >= 0;
String url = meta.getURL();
if (url != null) {
isH2 = url.startsWith("jdbc:h2:");
if (isH2) {
Statement stat = meta.getConnection().createStatement();
ResultSet rs = stat.executeQuery(
"SELECT UPPER(VALUE) FROM INFORMATION_SCHEMA.SETTINGS WHERE NAME='MODE'");
rs.next();
if ("MYSQL".equals(rs.getString(1))) {
isH2ModeMySQL = true;
}
rs.close();
stat.close();
}
isOracle = url.startsWith("jdbc:oracle:");
isPostgreSQL = url.startsWith("jdbc:postgresql:");
// isHSQLDB = url.startsWith("jdbc:hsqldb:");
isMySQL = url.startsWith("jdbc:mysql:");
isDerby = url.startsWith("jdbc:derby:");
isFirebird = url.startsWith("jdbc:firebirdsql:");
isMSSQLServer = url.startsWith("jdbc:sqlserver:");
}
String defaultSchemaName = getDefaultSchemaName(meta);
String[] schemaNames = getSchemaNames(meta);
schemas = new DbSchema[schemaNames.length];
for (int i = 0; i < schemaNames.length; i++) {
String schemaName = schemaNames[i];
boolean isDefault = defaultSchemaName == null || defaultSchemaName.equals(schemaName);
DbSchema schema = new DbSchema(this, schemaName, isDefault);
if (schema.isDefault) {
defaultSchema = schema;
}
schemas[i] = schema;
String[] tableTypes = { "TABLE", "SYSTEM TABLE", "VIEW", "SYSTEM VIEW",
"TABLE LINK", "SYNONYM", "EXTERNAL" };
schema.readTables(meta, tableTypes);
schema.readProcedures(meta);
}
if (defaultSchema == null) {
String best = null;
for (DbSchema schema : schemas) {
if ("dbo".equals(schema.name)) {
// MS SQL Server
defaultSchema = schema;
break;
}
if (defaultSchema == null || best == null || schema.name.length() < best.length()) {
best = schema.name;
defaultSchema = schema;
}
}
}
}
private String[] getSchemaNames(DatabaseMetaData meta) throws SQLException {
if (isMySQL || isSQLite) {
return new String[] { "" };
} else if (isFirebird) {
return new String[] { null };
}
ResultSet rs = meta.getSchemas();
ArrayList<String> schemaList = New.arrayList();
while (rs.next()) {
String schema = rs.getString(findColumn(rs, "TABLE_SCHEM", 1));
String[] ignoreNames = null;
if (isOracle) {
ignoreNames = new String[] { "CTXSYS", "DIP", "DBSNMP",
"DMSYS", "EXFSYS", "FLOWS_020100", "FLOWS_FILES",
"MDDATA", "MDSYS", "MGMT_VIEW", "OLAPSYS", "ORDSYS",
"ORDPLUGINS", "OUTLN", "SI_INFORMTN_SCHEMA", "SYS",
"SYSMAN", "SYSTEM", "TSMSYS", "WMSYS", "XDB" };
} else if (isMSSQLServer) {
ignoreNames = new String[] { "sys", "db_accessadmin",
"db_backupoperator", "db_datareader", "db_datawriter",
"db_ddladmin", "db_denydatareader",
"db_denydatawriter", "db_owner", "db_securityadmin" };
}
if (ignoreNames != null) {
for (String ignore : ignoreNames) {
if (ignore.equals(schema)) {
schema = null;
break;
}
}
}
if (schema == null) {
continue;
}
schemaList.add(schema);
}
rs.close();
String[] list = new String[schemaList.size()];
schemaList.toArray(list);
return list;
}
private String getDefaultSchemaName(DatabaseMetaData meta) {
String defaultSchemaName = "";
try {
if (isOracle) {
return meta.getUserName();
} else if (isPostgreSQL) {
return "public";
} else if (isMySQL) {
return "";
} else if (isDerby) {
return StringUtils.toUpperEnglish(meta.getUserName());
} else if (isFirebird) {
return null;
}
ResultSet rs = meta.getSchemas();
int index = rs.findColumn("IS_DEFAULT");
while (rs.next()) {
if (rs.getBoolean(index)) {
defaultSchemaName = rs.getString("TABLE_SCHEM");
}
}
} catch (SQLException e) {
// IS_DEFAULT not found
}
return defaultSchemaName;
}
/**
* Add double quotes around an identifier if required.
* For the H2 database, all identifiers are quoted.
*
* @param identifier the identifier
* @return the quoted identifier
*/
public String quoteIdentifier(String identifier) {
if (identifier == null) {
return null;
}
if (isH2 && !isH2ModeMySQL) {
return Parser.quoteIdentifier(identifier);
}
return StringUtils.toUpperEnglish(identifier);
}
}
/*
* Copyright 2004-2013 H2 Group. Multiple-Licensed under the H2 License,
* Version 1.0, and under the Eclipse Public License, Version 1.0
* (http://h2database.com/html/license.html).
* Initial Developer: H2 Group
*/
package org.h2.bnf.context;
import java.util.HashMap;
import java.util.HashSet;
import org.h2.bnf.BnfVisitor;
import org.h2.bnf.Rule;
import org.h2.bnf.RuleElement;
import org.h2.bnf.RuleHead;
import org.h2.bnf.RuleList;
import org.h2.bnf.Sentence;
import org.h2.command.Parser;
import org.h2.message.DbException;
import org.h2.util.StringUtils;
/**
* A BNF terminal rule that is linked to the database context information.
* This class is used by the H2 Console, to support auto-complete.
*/
public class DbContextRule implements Rule {
public static final int COLUMN = 0, TABLE = 1, TABLE_ALIAS = 2;
public static final int NEW_TABLE_ALIAS = 3;
public static final int COLUMN_ALIAS = 4, SCHEMA = 5, PROCEDURE = 6;
private final DbContents contents;
private final int type;
private String columnType;
/**
* BNF terminal rule Constructor
* @param contents Extract rule from this component
* @param type Rule type, one of
* {@link DbContextRule#COLUMN},
* {@link DbContextRule#TABLE},
* {@link DbContextRule#TABLE_ALIAS},
* {@link DbContextRule#NEW_TABLE_ALIAS},
* {@link DbContextRule#COLUMN_ALIAS},
* {@link DbContextRule#SCHEMA}
*/
public DbContextRule(DbContents contents, int type) {
this.contents = contents;
this.type = type;
}
/**
* @param columnType COLUMN Auto completion can be filtered by column type
*/
public void setColumnType(String columnType) {
this.columnType = columnType;
}
@Override
public void setLinks(HashMap<String, RuleHead> ruleMap) {
// nothing to do
}
@Override
public void accept(BnfVisitor visitor) {
// nothing to do
}
@Override
public boolean autoComplete(Sentence sentence) {
String query = sentence.getQuery(), s = query;
String up = sentence.getQueryUpper();
switch (type) {
case SCHEMA: {
DbSchema[] schemas = contents.getSchemas();
String best = null;
DbSchema bestSchema = null;
for (DbSchema schema: schemas) {
String name = StringUtils.toUpperEnglish(schema.name);
if (up.startsWith(name)) {
if (best == null || name.length() > best.length()) {
best = name;
bestSchema = schema;
}
} else if (s.length() == 0 || name.startsWith(up)) {
if (s.length() < name.length()) {
sentence.add(name, name.substring(s.length()), type);
sentence.add(schema.quotedName + ".", schema.quotedName.substring(s.length()) + ".", Sentence.CONTEXT);
}
}
}
if (best != null) {
sentence.setLastMatchedSchema(bestSchema);
s = s.substring(best.length());
}
break;
}
case TABLE: {
DbSchema schema = sentence.getLastMatchedSchema();
if (schema == null) {
schema = contents.getDefaultSchema();
}
DbTableOrView[] tables = schema.getTables();
String best = null;
DbTableOrView bestTable = null;
for (DbTableOrView table : tables) {
String compare = up;
String name = StringUtils.toUpperEnglish(table.getName());
if (table.getQuotedName().length() > name.length()) {
name = table.getQuotedName();
compare = query;
}
if (compare.startsWith(name)) {
if (best == null || name.length() > best.length()) {
best = name;
bestTable = table;
}
} else if (s.length() == 0 || name.startsWith(compare)) {
if (s.length() < name.length()) {
sentence.add(table.getQuotedName(), table.getQuotedName().substring(s.length()), Sentence.CONTEXT);
}
}
}
if (best != null) {
sentence.setLastMatchedTable(bestTable);
sentence.addTable(bestTable);
s = s.substring(best.length());
}
break;
}
case NEW_TABLE_ALIAS:
s = autoCompleteTableAlias(sentence, true);
break;
case TABLE_ALIAS:
s = autoCompleteTableAlias(sentence, false);
break;
case COLUMN_ALIAS: {
int i = 0;
if (query.indexOf(' ') < 0) {
break;
}
for (; i < up.length(); i++) {
char ch = up.charAt(i);
if (ch != '_' && !Character.isLetterOrDigit(ch)) {
break;
}
}
if (i == 0) {
break;
}
String alias = up.substring(0, i);
if (Parser.isKeyword(alias, true)) {
break;
}
s = s.substring(alias.length());
break;
}
case COLUMN: {
HashSet<DbTableOrView> set = sentence.getTables();
String best = null;
DbTableOrView last = sentence.getLastMatchedTable();
if (last != null && last.getColumns() != null) {
for (DbColumn column : last.getColumns()) {
String compare = up;
String name = StringUtils.toUpperEnglish(column.getName());
if (column.getQuotedName().length() > name.length()) {
name = column.getQuotedName();
compare = query;
}
if (compare.startsWith(name) && (columnType == null || column.getDataType().contains(columnType))) {
String b = s.substring(name.length());
if (best == null || b.length() < best.length()) {
best = b;
} else if (s.length() == 0 || name.startsWith(compare)) {
if (s.length() < name.length()) {
sentence.add(column.getName(), column.getName().substring(s.length()), Sentence.CONTEXT);
}
}
}
}
}
for (DbSchema schema : contents.getSchemas()) {
for (DbTableOrView table : schema.getTables()) {
if (table != last && set != null && !set.contains(table)) {
continue;
}
if (table == null || table.getColumns() == null) {
continue;
}
for (DbColumn column : table.getColumns()) {
String name = StringUtils.toUpperEnglish(column
.getName());
if (columnType == null
|| column.getDataType().contains(columnType)) {
if (up.startsWith(name)) {
String b = s.substring(name.length());
if (best == null || b.length() < best.length()) {
best = b;
}
} else if (s.length() == 0 || name.startsWith(up)) {
if (s.length() < name.length()) {
sentence.add(column.getName(), column.getName().substring(s.length()), Sentence.CONTEXT);
}
}
}
}
}
}
if (best != null) {
s = best;
}
break;
}
case PROCEDURE:
autoCompleteProcedure(sentence);
break;
default:
throw DbException.throwInternalError("type=" + type);
}
if (!s.equals(query)) {
while (s.length() > 0 && Character.isSpaceChar(s.charAt(0))) {
s = s.substring(1);
}
sentence.setQuery(s);
return true;
}
return false;
}
private void autoCompleteProcedure(Sentence sentence) {
DbSchema schema = sentence.getLastMatchedSchema();
if (schema == null) {
schema = contents.getDefaultSchema();
}
String incompleteSentence = sentence.getQueryUpper();
String incompleteFunctionName = incompleteSentence;
if (incompleteSentence.contains("(")) {
incompleteFunctionName = incompleteSentence.substring(0, incompleteSentence.indexOf('(')).trim();
}
// Common elements
RuleElement openBracket = new RuleElement("(", "Function");
RuleElement closeBracket = new RuleElement(")", "Function");
RuleElement comma = new RuleElement(",", "Function");
// Fetch all elements
for (DbProcedure procedure : schema.getProcedures()) {
final String procName = procedure.getName();
if (procName.startsWith(incompleteFunctionName)) {
// That's it, build a RuleList from this function
RuleElement procedureElement = new RuleElement(procName,
"Function");
RuleList rl = new RuleList(procedureElement, openBracket, false);
// Go further only if the user use open bracket
if (incompleteSentence.contains("(")) {
for (DbColumn parameter : procedure.getParameters()) {
if (parameter.getPosition() > 1) {
rl = new RuleList(rl, comma, false);
}
DbContextRule columnRule = new DbContextRule(contents,
COLUMN);
String parameterType = parameter.getDataType();
// Remove precision
if (parameterType.contains("(")) {
parameterType = parameterType.substring(0,
parameterType.indexOf('('));
}
columnRule.setColumnType(parameterType);
rl = new RuleList(rl, columnRule, false);
}
rl = new RuleList(rl, closeBracket , false);
}
rl.autoComplete(sentence);
}
}
}
private static String autoCompleteTableAlias(Sentence sentence, boolean newAlias) {
String s = sentence.getQuery();
String up = sentence.getQueryUpper();
int i = 0;
for (; i < up.length(); i++) {
char ch = up.charAt(i);
if (ch != '_' && !Character.isLetterOrDigit(ch)) {
break;
}
}
if (i == 0) {
return s;
}
String alias = up.substring(0, i);
if ("SET".equals(alias) || Parser.isKeyword(alias, true)) {
return s;
}
if (newAlias) {
sentence.addAlias(alias, sentence.getLastTable());
}
HashMap<String, DbTableOrView> map = sentence.getAliases();
if ((map != null && map.containsKey(alias)) || (sentence.getLastTable() == null)) {
if (newAlias && s.length() == alias.length()) {
return s;
}
s = s.substring(alias.length());
if (s.length() == 0) {
sentence.add(alias + ".", ".", Sentence.CONTEXT);
}
return s;
}
HashSet<DbTableOrView> tables = sentence.getTables();
if (tables != null) {
String best = null;
for (DbTableOrView table : tables) {
String tableName = StringUtils.toUpperEnglish(table.getName());
if (alias.startsWith(tableName) && (best == null || tableName.length() > best.length())) {
sentence.setLastMatchedTable(table);
best = tableName;
} else if (s.length() == 0 || tableName.startsWith(alias)) {
sentence.add(tableName + ".", tableName.substring(s.length()) + ".", Sentence.CONTEXT);
}
}
if (best != null) {
s = s.substring(best.length());
if (s.length() == 0) {
sentence.add(alias + ".", ".", Sentence.CONTEXT);
}
return s;
}
}
return s;
}
}
/*
* Copyright 2004-2013 H2 Group. Multiple-Licensed under the H2 License,
* Version 1.0, and under the Eclipse Public License, Version 1.0
* (http://h2database.com/html/license.html).
* Initial Developer: H2 Group
*/
package org.h2.bnf.context;
import java.util.HashMap;
import java.util.HashSet;
import org.h2.bnf.BnfVisitor;
import org.h2.bnf.Rule;
import org.h2.bnf.RuleElement;
import org.h2.bnf.RuleHead;
import org.h2.bnf.RuleList;
import org.h2.bnf.Sentence;
import org.h2.command.Parser;
import org.h2.message.DbException;
import org.h2.util.StringUtils;
/**
* A BNF terminal rule that is linked to the database context information.
* This class is used by the H2 Console, to support auto-complete.
*/
public class DbContextRule implements Rule {
public static final int COLUMN = 0, TABLE = 1, TABLE_ALIAS = 2;
public static final int NEW_TABLE_ALIAS = 3;
public static final int COLUMN_ALIAS = 4, SCHEMA = 5, PROCEDURE = 6;
private final DbContents contents;
private final int type;
private String columnType;
/**
* BNF terminal rule Constructor
* @param contents Extract rule from this component
* @param type Rule type, one of
* {@link DbContextRule#COLUMN},
* {@link DbContextRule#TABLE},
* {@link DbContextRule#TABLE_ALIAS},
* {@link DbContextRule#NEW_TABLE_ALIAS},
* {@link DbContextRule#COLUMN_ALIAS},
* {@link DbContextRule#SCHEMA}
*/
public DbContextRule(DbContents contents, int type) {
this.contents = contents;
this.type = type;
}
/**
* @param columnType COLUMN Auto completion can be filtered by column type
*/
public void setColumnType(String columnType) {
this.columnType = columnType;
}
@Override
public void setLinks(HashMap<String, RuleHead> ruleMap) {
// nothing to do
}
@Override
public void accept(BnfVisitor visitor) {
// nothing to do
}
@Override
public boolean autoComplete(Sentence sentence) {
String query = sentence.getQuery(), s = query;
String up = sentence.getQueryUpper();
switch (type) {
case SCHEMA: {
DbSchema[] schemas = contents.getSchemas();
String best = null;
DbSchema bestSchema = null;
for (DbSchema schema: schemas) {
String name = StringUtils.toUpperEnglish(schema.name);
if (up.startsWith(name)) {
if (best == null || name.length() > best.length()) {
best = name;
bestSchema = schema;
}
} else if (s.length() == 0 || name.startsWith(up)) {
if (s.length() < name.length()) {
sentence.add(name, name.substring(s.length()), type);
sentence.add(schema.quotedName + ".", schema.quotedName.substring(s.length()) + ".", Sentence.CONTEXT);
}
}
}
if (best != null) {
sentence.setLastMatchedSchema(bestSchema);
s = s.substring(best.length());
}
break;
}
case TABLE: {
DbSchema schema = sentence.getLastMatchedSchema();
if (schema == null) {
schema = contents.getDefaultSchema();
}
DbTableOrView[] tables = schema.getTables();
String best = null;
DbTableOrView bestTable = null;
for (DbTableOrView table : tables) {
String compare = up;
String name = StringUtils.toUpperEnglish(table.getName());
if (table.getQuotedName().length() > name.length()) {
name = table.getQuotedName();
compare = query;
}
if (compare.startsWith(name)) {
if (best == null || name.length() > best.length()) {
best = name;
bestTable = table;
}
} else if (s.length() == 0 || name.startsWith(compare)) {
if (s.length() < name.length()) {
sentence.add(table.getQuotedName(), table.getQuotedName().substring(s.length()), Sentence.CONTEXT);
}
}
}
if (best != null) {
sentence.setLastMatchedTable(bestTable);
sentence.addTable(bestTable);
s = s.substring(best.length());
}
break;
}
case NEW_TABLE_ALIAS:
s = autoCompleteTableAlias(sentence, true);
break;
case TABLE_ALIAS:
s = autoCompleteTableAlias(sentence, false);
break;
case COLUMN_ALIAS: {
int i = 0;
if (query.indexOf(' ') < 0) {
break;
}
for (; i < up.length(); i++) {
char ch = up.charAt(i);
if (ch != '_' && !Character.isLetterOrDigit(ch)) {
break;
}
}
if (i == 0) {
break;
}
String alias = up.substring(0, i);
if (Parser.isKeyword(alias, true)) {
break;
}
s = s.substring(alias.length());
break;
}
case COLUMN: {
HashSet<DbTableOrView> set = sentence.getTables();
String best = null;
DbTableOrView last = sentence.getLastMatchedTable();
if (last != null && last.getColumns() != null) {
for (DbColumn column : last.getColumns()) {
String compare = up;
String name = StringUtils.toUpperEnglish(column.getName());
if (column.getQuotedName().length() > name.length()) {
name = column.getQuotedName();
compare = query;
}
if (compare.startsWith(name) && (columnType == null || column.getDataType().contains(columnType))) {
String b = s.substring(name.length());
if (best == null || b.length() < best.length()) {
best = b;
} else if (s.length() == 0 || name.startsWith(compare)) {
if (s.length() < name.length()) {
sentence.add(column.getName(), column.getName().substring(s.length()), Sentence.CONTEXT);
}
}
}
}
}
for (DbSchema schema : contents.getSchemas()) {
for (DbTableOrView table : schema.getTables()) {
if (table != last && set != null && !set.contains(table)) {
continue;
}
if (table == null || table.getColumns() == null) {
continue;
}
for (DbColumn column : table.getColumns()) {
String name = StringUtils.toUpperEnglish(column
.getName());
if (columnType == null
|| column.getDataType().contains(columnType)) {
if (up.startsWith(name)) {
String b = s.substring(name.length());
if (best == null || b.length() < best.length()) {
best = b;
}
} else if (s.length() == 0 || name.startsWith(up)) {
if (s.length() < name.length()) {
sentence.add(column.getName(), column.getName().substring(s.length()), Sentence.CONTEXT);
}
}
}
}
}
}
if (best != null) {
s = best;
}
break;
}
case PROCEDURE:
autoCompleteProcedure(sentence);
break;
default:
throw DbException.throwInternalError("type=" + type);
}
if (!s.equals(query)) {
while (s.length() > 0 && Character.isSpaceChar(s.charAt(0))) {
s = s.substring(1);
}
sentence.setQuery(s);
return true;
}
return false;
}
private void autoCompleteProcedure(Sentence sentence) {
DbSchema schema = sentence.getLastMatchedSchema();
if (schema == null) {
schema = contents.getDefaultSchema();
}
String incompleteSentence = sentence.getQueryUpper();
String incompleteFunctionName = incompleteSentence;
if (incompleteSentence.contains("(")) {
incompleteFunctionName = incompleteSentence.substring(0, incompleteSentence.indexOf('(')).trim();
}
// Common elements
RuleElement openBracket = new RuleElement("(", "Function");
RuleElement closeBracket = new RuleElement(")", "Function");
RuleElement comma = new RuleElement(",", "Function");
// Fetch all elements
for (DbProcedure procedure : schema.getProcedures()) {
final String procName = procedure.getName();
if (procName.startsWith(incompleteFunctionName)) {
// That's it, build a RuleList from this function
RuleElement procedureElement = new RuleElement(procName,
"Function");
RuleList rl = new RuleList(procedureElement, openBracket, false);
// Go further only if the user use open bracket
if (incompleteSentence.contains("(")) {
for (DbColumn parameter : procedure.getParameters()) {
if (parameter.getPosition() > 1) {
rl = new RuleList(rl, comma, false);
}
DbContextRule columnRule = new DbContextRule(contents,
COLUMN);
String parameterType = parameter.getDataType();
// Remove precision
if (parameterType.contains("(")) {
parameterType = parameterType.substring(0,
parameterType.indexOf('('));
}
columnRule.setColumnType(parameterType);
rl = new RuleList(rl, columnRule, false);
}
rl = new RuleList(rl, closeBracket , false);
}
rl.autoComplete(sentence);
}
}
}
private static String autoCompleteTableAlias(Sentence sentence, boolean newAlias) {
String s = sentence.getQuery();
String up = sentence.getQueryUpper();
int i = 0;
for (; i < up.length(); i++) {
char ch = up.charAt(i);
if (ch != '_' && !Character.isLetterOrDigit(ch)) {
break;
}
}
if (i == 0) {
return s;
}
String alias = up.substring(0, i);
if ("SET".equals(alias) || Parser.isKeyword(alias, true)) {
return s;
}
if (newAlias) {
sentence.addAlias(alias, sentence.getLastTable());
}
HashMap<String, DbTableOrView> map = sentence.getAliases();
if ((map != null && map.containsKey(alias)) || (sentence.getLastTable() == null)) {
if (newAlias && s.length() == alias.length()) {
return s;
}
s = s.substring(alias.length());
if (s.length() == 0) {
sentence.add(alias + ".", ".", Sentence.CONTEXT);
}
return s;
}
HashSet<DbTableOrView> tables = sentence.getTables();
if (tables != null) {
String best = null;
for (DbTableOrView table : tables) {
String tableName = StringUtils.toUpperEnglish(table.getName());
if (alias.startsWith(tableName) && (best == null || tableName.length() > best.length())) {
sentence.setLastMatchedTable(table);
best = tableName;
} else if (s.length() == 0 || tableName.startsWith(alias)) {
sentence.add(tableName + ".", tableName.substring(s.length()) + ".", Sentence.CONTEXT);
}
}
if (best != null) {
s = s.substring(best.length());
if (s.length() == 0) {
sentence.add(alias + ".", ".", Sentence.CONTEXT);
}
return s;
}
}
return s;
}
}
/*
* Copyright 2004-2013 H2 Group. Multiple-Licensed under the H2 License,
* Version 1.0, and under the Eclipse Public License, Version 1.0
* (http://h2database.com/html/license.html).
* Initial Developer: H2 Group
*/
package org.h2.bnf.context;
import org.h2.util.New;
import java.sql.DatabaseMetaData;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
/**
* Contains meta data information about a procedure.
* This class is used by the H2 Console.
*/
public class DbProcedure {
private final DbSchema schema;
private final String name;
private final String quotedName;
private boolean returnsResult;
private DbColumn[] parameters;
public DbProcedure(DbSchema schema, ResultSet rs) throws SQLException {
this.schema = schema;
name = rs.getString("PROCEDURE_NAME");
returnsResult = rs.getShort("PROCEDURE_TYPE") == DatabaseMetaData.procedureReturnsResult;
quotedName = schema.getContents().quoteIdentifier(name);
}
/**
* @return The schema this table belongs to.
*/
public DbSchema getSchema() {
return schema;
}
/**
* @return The column list.
*/
public DbColumn[] getParameters() {
return parameters;
}
/**
* @return The table name.
*/
public String getName() {
return name;
}
/**
* @return The quoted table name.
*/
public String getQuotedName() {
return quotedName;
}
/**
* @return True if this function return a value
*/
public boolean isReturnsResult() {
return returnsResult;
}
/**
* Read the column for this table from the database meta data.
*
* @param meta the database meta data
*/
void readParameters(DatabaseMetaData meta) throws SQLException {
ResultSet rs = meta.getProcedureColumns(null, schema.name, name, null);
ArrayList<DbColumn> list = New.arrayList();
while (rs.next()) {
DbColumn column = new DbColumn(schema.getContents(), rs);
if (column.getPosition() > 0) {
// Not the return type
list.add(column);
}
}
rs.close();
parameters = new DbColumn[list.size()];
// Store the parameter in the good position [1-n]
for (int i = 0; i < parameters.length; i++) {
DbColumn column = list.get(i);
if (column.getPosition() > 0
&& column.getPosition() <= parameters.length) {
parameters[column.getPosition() - 1] = column;
}
}
}
}
/*
* Copyright 2004-2013 H2 Group. Multiple-Licensed under the H2 License,
* Version 1.0, and under the Eclipse Public License, Version 1.0
* (http://h2database.com/html/license.html).
* Initial Developer: H2 Group
*/
package org.h2.bnf.context;
import org.h2.util.New;
import java.sql.DatabaseMetaData;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
/**
* Contains meta data information about a procedure.
* This class is used by the H2 Console.
*/
public class DbProcedure {
private final DbSchema schema;
private final String name;
private final String quotedName;
private boolean returnsResult;
private DbColumn[] parameters;
public DbProcedure(DbSchema schema, ResultSet rs) throws SQLException {
this.schema = schema;
name = rs.getString("PROCEDURE_NAME");
returnsResult = rs.getShort("PROCEDURE_TYPE") == DatabaseMetaData.procedureReturnsResult;
quotedName = schema.getContents().quoteIdentifier(name);
}
/**
* @return The schema this table belongs to.
*/
public DbSchema getSchema() {
return schema;
}
/**
* @return The column list.
*/
public DbColumn[] getParameters() {
return parameters;
}
/**
* @return The table name.
*/
public String getName() {
return name;
}
/**
* @return The quoted table name.
*/
public String getQuotedName() {
return quotedName;
}
/**
* @return True if this function return a value
*/
public boolean isReturnsResult() {
return returnsResult;
}
/**
* Read the column for this table from the database meta data.
*
* @param meta the database meta data
*/
void readParameters(DatabaseMetaData meta) throws SQLException {
ResultSet rs = meta.getProcedureColumns(null, schema.name, name, null);
ArrayList<DbColumn> list = New.arrayList();
while (rs.next()) {
DbColumn column = new DbColumn(schema.getContents(), rs);
if (column.getPosition() > 0) {
// Not the return type
list.add(column);
}
}
rs.close();
parameters = new DbColumn[list.size()];
// Store the parameter in the good position [1-n]
for (int i = 0; i < parameters.length; i++) {
DbColumn column = list.get(i);
if (column.getPosition() > 0
&& column.getPosition() <= parameters.length) {
parameters[column.getPosition() - 1] = column;
}
}
}
}
/*
* Copyright 2004-2013 H2 Group. Multiple-Licensed under the H2 License,
* Version 1.0, and under the Eclipse Public License, Version 1.0
* (http://h2database.com/html/license.html).
* Initial Developer: H2 Group
*/
package org.h2.bnf.context;
import java.sql.DatabaseMetaData;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import org.h2.util.New;
import org.h2.util.StringUtils;
/**
* Contains meta data information about a database schema.
* This class is used by the H2 Console.
*/
public class DbSchema {
/**
* Up to this many tables, the column type and indexes are listed.
*/
public static final int MAX_TABLES_LIST_INDEXES = 100;
/**
* Up to this many tables, the column names are listed.
*/
public static final int MAX_TABLES_LIST_COLUMNS = 500;
/**
* Up to this many tables, the column names are listed.
*/
public static final int MAX_PROCEDURES_LIST_COLUMNS = 500;
/**
* The schema name.
*/
public final String name;
/**
* True if this is the default schema for this database.
*/
public final boolean isDefault;
/**
* True if this is a system schema (for example the INFORMATION_SCHEMA).
*/
public final boolean isSystem;
/**
* The quoted schema name.
*/
public final String quotedName;
/**
* The database content container.
*/
private final DbContents contents;
/**
* The table list.
*/
private DbTableOrView[] tables;
/**
* The procedures list.
*/
private DbProcedure[] procedures;
DbSchema(DbContents contents, String name, boolean isDefault) {
this.contents = contents;
this.name = name;
this.quotedName = contents.quoteIdentifier(name);
this.isDefault = isDefault;
if (name.equals("INFORMATION_SCHEMA")) {
isSystem = true;
} else if (!contents.isH2() && StringUtils.toUpperEnglish(name).startsWith("INFO")) {
isSystem = true;
} else if (contents.isPostgreSQL() && StringUtils.toUpperEnglish(name).startsWith("PG_")) {
isSystem = true;
} else if (contents.isDerby() && name.startsWith("SYS")) {
isSystem = true;
} else {
isSystem = false;
}
}
/**
* @return The database content container.
*/
public DbContents getContents() {
return contents;
}
/**
* @return The table list.
*/
public DbTableOrView[] getTables() {
return tables;
}
/**
* @return The procedure list.
*/
public DbProcedure[] getProcedures() {
return procedures;
}
/**
* Read all tables for this schema from the database meta data.
*
* @param meta the database meta data
* @param tableTypes the table types to read
*/
public void readTables(DatabaseMetaData meta, String[] tableTypes) throws SQLException {
ResultSet rs = meta.getTables(null, name, null, tableTypes);
ArrayList<DbTableOrView> list = New.arrayList();
while (rs.next()) {
DbTableOrView table = new DbTableOrView(this, rs);
if (contents.isOracle() && table.getName().indexOf('$') > 0) {
continue;
}
list.add(table);
}
rs.close();
tables = new DbTableOrView[list.size()];
list.toArray(tables);
if (tables.length < MAX_TABLES_LIST_COLUMNS) {
for (DbTableOrView tab : tables) {
tab.readColumns(meta);
}
}
}
/**
* Read all procedures in the dataBase.
* @param meta the database meta data
* @throws SQLException Error while fetching procedures
*/
public void readProcedures(DatabaseMetaData meta) throws SQLException {
ResultSet rs = meta.getProcedures(null, name, null);
ArrayList<DbProcedure> list = New.arrayList();
while (rs.next()) {
list.add(new DbProcedure(this, rs));
}
rs.close();
procedures = new DbProcedure[list.size()];
list.toArray(procedures);
if (procedures.length < MAX_PROCEDURES_LIST_COLUMNS) {
for (DbProcedure procedure : procedures) {
procedure.readParameters(meta);
}
}
}
}
/*
* Copyright 2004-2013 H2 Group. Multiple-Licensed under the H2 License,
* Version 1.0, and under the Eclipse Public License, Version 1.0
* (http://h2database.com/html/license.html).
* Initial Developer: H2 Group
*/
package org.h2.bnf.context;
import java.sql.DatabaseMetaData;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import org.h2.util.New;
import org.h2.util.StringUtils;
/**
* Contains meta data information about a database schema.
* This class is used by the H2 Console.
*/
public class DbSchema {
/**
* Up to this many tables, the column type and indexes are listed.
*/
public static final int MAX_TABLES_LIST_INDEXES = 100;
/**
* Up to this many tables, the column names are listed.
*/
public static final int MAX_TABLES_LIST_COLUMNS = 500;
/**
* Up to this many tables, the column names are listed.
*/
public static final int MAX_PROCEDURES_LIST_COLUMNS = 500;
/**
* The schema name.
*/
public final String name;
/**
* True if this is the default schema for this database.
*/
public final boolean isDefault;
/**
* True if this is a system schema (for example the INFORMATION_SCHEMA).
*/
public final boolean isSystem;
/**
* The quoted schema name.
*/
public final String quotedName;
/**
* The database content container.
*/
private final DbContents contents;
/**
* The table list.
*/
private DbTableOrView[] tables;
/**
* The procedures list.
*/
private DbProcedure[] procedures;
DbSchema(DbContents contents, String name, boolean isDefault) {
this.contents = contents;
this.name = name;
this.quotedName = contents.quoteIdentifier(name);
this.isDefault = isDefault;
if (name.equals("INFORMATION_SCHEMA")) {
isSystem = true;
} else if (!contents.isH2() && StringUtils.toUpperEnglish(name).startsWith("INFO")) {
isSystem = true;
} else if (contents.isPostgreSQL() && StringUtils.toUpperEnglish(name).startsWith("PG_")) {
isSystem = true;
} else if (contents.isDerby() && name.startsWith("SYS")) {
isSystem = true;
} else {
isSystem = false;
}
}
/**
* @return The database content container.
*/
public DbContents getContents() {
return contents;
}
/**
* @return The table list.
*/
public DbTableOrView[] getTables() {
return tables;
}
/**
* @return The procedure list.
*/
public DbProcedure[] getProcedures() {
return procedures;
}
/**
* Read all tables for this schema from the database meta data.
*
* @param meta the database meta data
* @param tableTypes the table types to read
*/
public void readTables(DatabaseMetaData meta, String[] tableTypes) throws SQLException {
ResultSet rs = meta.getTables(null, name, null, tableTypes);
ArrayList<DbTableOrView> list = New.arrayList();
while (rs.next()) {
DbTableOrView table = new DbTableOrView(this, rs);
if (contents.isOracle() && table.getName().indexOf('$') > 0) {
continue;
}
list.add(table);
}
rs.close();
tables = new DbTableOrView[list.size()];
list.toArray(tables);
if (tables.length < MAX_TABLES_LIST_COLUMNS) {
for (DbTableOrView tab : tables) {
tab.readColumns(meta);
}
}
}
/**
* Read all procedures in the dataBase.
* @param meta the database meta data
* @throws SQLException Error while fetching procedures
*/
public void readProcedures(DatabaseMetaData meta) throws SQLException {
ResultSet rs = meta.getProcedures(null, name, null);
ArrayList<DbProcedure> list = New.arrayList();
while (rs.next()) {
list.add(new DbProcedure(this, rs));
}
rs.close();
procedures = new DbProcedure[list.size()];
list.toArray(procedures);
if (procedures.length < MAX_PROCEDURES_LIST_COLUMNS) {
for (DbProcedure procedure : procedures) {
procedure.readParameters(meta);
}
}
}
}
/*
* Copyright 2004-2013 H2 Group. Multiple-Licensed under the H2 License,
* Version 1.0, and under the Eclipse Public License, Version 1.0
* (http://h2database.com/html/license.html).
* Initial Developer: H2 Group
*/
package org.h2.bnf.context;
import java.sql.DatabaseMetaData;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import org.h2.util.New;
/**
* Contains meta data information about a table or a view.
* This class is used by the H2 Console.
*/
public class DbTableOrView {
/**
* The schema this table belongs to.
*/
private final DbSchema schema;
/**
* The table name.
*/
private final String name;
/**
* The quoted table name.
*/
private final String quotedName;
/**
* True if this represents a view.
*/
private final boolean isView;
/**
* The column list.
*/
private DbColumn[] columns;
public DbTableOrView(DbSchema schema, ResultSet rs) throws SQLException {
this.schema = schema;
name = rs.getString("TABLE_NAME");
String type = rs.getString("TABLE_TYPE");
isView = "VIEW".equals(type);
quotedName = schema.getContents().quoteIdentifier(name);
}
/**
* @return The schema this table belongs to.
*/
public DbSchema getSchema() {
return schema;
}
/**
* @return The column list.
*/
public DbColumn[] getColumns() {
return columns;
}
/**
* @return The table name.
*/
public String getName() {
return name;
}
/**
* @return True if this represents a view.
*/
public boolean isView() {
return isView;
}
/**
* @return The quoted table name.
*/
public String getQuotedName() {
return quotedName;
}
/**
* Read the column for this table from the database meta data.
*
* @param meta the database meta data
*/
public void readColumns(DatabaseMetaData meta) throws SQLException {
ResultSet rs = meta.getColumns(null, schema.name, name, null);
ArrayList<DbColumn> list = New.arrayList();
while (rs.next()) {
DbColumn column = new DbColumn(schema.getContents(), rs);
list.add(column);
}
rs.close();
columns = new DbColumn[list.size()];
list.toArray(columns);
}
}
/*
* Copyright 2004-2013 H2 Group. Multiple-Licensed under the H2 License,
* Version 1.0, and under the Eclipse Public License, Version 1.0
* (http://h2database.com/html/license.html).
* Initial Developer: H2 Group
*/
package org.h2.bnf.context;
import java.sql.DatabaseMetaData;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import org.h2.util.New;
/**
* Contains meta data information about a table or a view.
* This class is used by the H2 Console.
*/
public class DbTableOrView {
/**
* The schema this table belongs to.
*/
private final DbSchema schema;
/**
* The table name.
*/
private final String name;
/**
* The quoted table name.
*/
private final String quotedName;
/**
* True if this represents a view.
*/
private final boolean isView;
/**
* The column list.
*/
private DbColumn[] columns;
public DbTableOrView(DbSchema schema, ResultSet rs) throws SQLException {
this.schema = schema;
name = rs.getString("TABLE_NAME");
String type = rs.getString("TABLE_TYPE");
isView = "VIEW".equals(type);
quotedName = schema.getContents().quoteIdentifier(name);
}
/**
* @return The schema this table belongs to.
*/
public DbSchema getSchema() {
return schema;
}
/**
* @return The column list.
*/
public DbColumn[] getColumns() {
return columns;
}
/**
* @return The table name.
*/
public String getName() {
return name;
}
/**
* @return True if this represents a view.
*/
public boolean isView() {
return isView;
}
/**
* @return The quoted table name.
*/
public String getQuotedName() {
return quotedName;
}
/**
* Read the column for this table from the database meta data.
*
* @param meta the database meta data
*/
public void readColumns(DatabaseMetaData meta) throws SQLException {
ResultSet rs = meta.getColumns(null, schema.name, name, null);
ArrayList<DbColumn> list = New.arrayList();
while (rs.next()) {
DbColumn column = new DbColumn(schema.getContents(), rs);
list.add(column);
}
rs.close();
columns = new DbColumn[list.size()];
list.toArray(columns);
}
}
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<!--
Copyright 2004-2013 H2 Group. Multiple-Licensed under the H2 License, Version 1.0,
and under the Eclipse Public License, Version 1.0
(http://h2database.com/html/license.html).
Initial Developer: H2 Group
-->
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
<head><meta http-equiv="Content-Type" content="text/html;charset=utf-8" /><title>
Javadoc package documentation
</title></head><body style="font: 9pt/130% Tahoma, Arial, Helvetica, sans-serif; font-weight: normal;"><p>
Classes that provide context for the BNF tool, in order to provide BNF-based auto-complete.
</p></body></html>
\ No newline at end of file
......@@ -189,7 +189,7 @@ public class GrantRevoke extends DefineCommand {
public boolean isRoleMode() {
return roleNames != null;
}
/**
* @return true if this command is using Rights
*/
......
......@@ -1295,7 +1295,7 @@ public class Session extends SessionWithState {
/**
* Set the table this session is waiting for, and the thread that is waiting.
*
*
* @param waitForLock the table
* @param waitForLockThread the current thread (the one that is waiting)
*/
......@@ -1311,7 +1311,7 @@ public class Session extends SessionWithState {
public Thread getWaitForLockThread() {
return waitForLockThread;
}
public int getModificationId() {
return modificationId;
}
......
......@@ -204,7 +204,7 @@ public class User extends RightOwner {
throw DbException.get(ErrorCode.ADMIN_RIGHTS_REQUIRED);
}
}
/**
* Check if this user has schema admin rights. An exception is thrown if he does
* not have them.
......
......@@ -951,7 +951,7 @@ public class MVStore {
fileStore.markUsed(end, length);
}
boolean storeAtEndOfFile = filePos + length >= end;
// try {
// Thread.sleep(10);
// } catch (InterruptedException e) {
......@@ -995,7 +995,7 @@ public class MVStore {
// some pages might have been changed in the meantime (in the newest version)
unsavedPageCount = Math.max(0, unsavedPageCount - currentUnsavedPageCount);
if (!temp) {
metaChanged = false;
lastStoredVersion = storeVersion;
......
......@@ -14,7 +14,7 @@ import java.nio.ByteBuffer;
public class WriteBuffer {
private static final int MAX_REUSE_LIMIT = 4 * 1024 * 1024;
/**
* The maximum byte to grow a buffer at a time.
*/
......@@ -23,10 +23,10 @@ public class WriteBuffer {
private ByteBuffer reuse = ByteBuffer.allocate(512 * 1024);
private ByteBuffer buff = reuse;
/**
* Write a variable size integer.
*
*
* @param x the value
* @return this
*/
......@@ -34,10 +34,10 @@ public class WriteBuffer {
DataUtils.writeVarInt(ensureCapacity(5), x);
return this;
}
/**
* Write a variable size long.
*
*
* @param x the value
* @return this
*/
......@@ -48,7 +48,7 @@ public class WriteBuffer {
/**
* Write the characters of a string in a format similar to UTF-8.
*
*
* @param s the string
* @param len the number of characters to write
* @return this
......@@ -73,7 +73,7 @@ public class WriteBuffer {
/**
* Put a byte.
*
*
* @param x the value
* @return this
*/
......@@ -81,10 +81,10 @@ public class WriteBuffer {
ensureCapacity(1).put(x);
return this;
}
/**
* Put a character.
*
*
* @param x the value
* @return this
*/
......@@ -92,10 +92,10 @@ public class WriteBuffer {
ensureCapacity(2).putChar(x);
return this;
}
/**
* Put a short.
*
*
* @param x the value
* @return this
*/
......@@ -103,10 +103,10 @@ public class WriteBuffer {
ensureCapacity(2).putShort(x);
return this;
}
/**
* Put an integer.
*
*
* @param x the value
* @return this
*/
......@@ -114,10 +114,10 @@ public class WriteBuffer {
ensureCapacity(4).putInt(x);
return this;
}
/**
* Put a long.
*
*
* @param x the value
* @return this
*/
......@@ -125,10 +125,10 @@ public class WriteBuffer {
ensureCapacity(8).putLong(x);
return this;
}
/**
* Put a float.
*
*
* @param x the value
* @return this
*/
......@@ -136,10 +136,10 @@ public class WriteBuffer {
ensureCapacity(4).putFloat(x);
return this;
}
/**
* Put a double.
*
*
* @param x the value
* @return this
*/
......@@ -150,7 +150,7 @@ public class WriteBuffer {
/**
* Put a byte array.
*
*
* @param bytes the value
* @return this
*/
......@@ -158,10 +158,10 @@ public class WriteBuffer {
ensureCapacity(bytes.length).put(bytes);
return this;
}
/**
* Put a byte array.
*
*
* @param bytes the value
* @param offset the source offset
* @param length the number of bytes
......@@ -174,7 +174,7 @@ public class WriteBuffer {
/**
* Put the contents of a byte buffer.
*
*
* @param src the source buffer
* @return this
*/
......@@ -185,7 +185,7 @@ public class WriteBuffer {
/**
* Set the limit, possibly growing the buffer.
*
*
* @param newLimit the new limit
* @return this
*/
......@@ -193,19 +193,19 @@ public class WriteBuffer {
ensureCapacity(newLimit - buff.position()).limit(newLimit);
return this;
}
/**
* Get the capacity.
*
*
* @return the capacity
*/
public int capacity() {
return buff.capacity();
}
/**
* Set the position.
*
*
* @param newPosition the new position
* @return the new position
*/
......@@ -216,25 +216,25 @@ public class WriteBuffer {
/**
* Get the limit.
*
*
* @return the limit
*/
public int limit() {
return buff.limit();
}
/**
* Get the current position.
*
*
* @return the position
*/
public int position() {
return buff.position();
}
/**
* Copy the data into the destination array.
*
*
* @param dst the destination array
* @return this
*/
......@@ -242,10 +242,10 @@ public class WriteBuffer {
buff.get(dst);
return this;
}
/**
* Update an integer at the given index.
*
*
* @param index the index
* @param value the value
* @return this
......@@ -254,10 +254,10 @@ public class WriteBuffer {
buff.putInt(index, value);
return this;
}
/**
* Update a short at the given index.
*
*
* @param index the index
* @param value the value
* @return this
......@@ -269,7 +269,7 @@ public class WriteBuffer {
/**
* Clear the buffer after use.
*
*
* @return this
*/
public WriteBuffer clear() {
......@@ -281,10 +281,10 @@ public class WriteBuffer {
buff.clear();
return this;
}
/**
* Get the byte buffer.
*
*
* @return the byte buffer
*/
public ByteBuffer getBuffer() {
......@@ -297,7 +297,7 @@ public class WriteBuffer {
}
return buff;
}
private void grow(int len) {
ByteBuffer temp = buff;
len = temp.remaining() + len;
......@@ -310,5 +310,5 @@ public class WriteBuffer {
reuse = buff;
}
}
}
......@@ -880,7 +880,7 @@ public class CacheLongKeyLIRS<V> {
/**
* Remove the entry from the stack. The head itself must not be removed.
*
*
* @param e the entry
*/
private void removeFromStack(Entry<V> e) {
......
......@@ -205,7 +205,7 @@ public class ValueDataType implements DataType {
buff.put((byte) DECIMAL_SMALL_0).
putVarLong(b.longValue());
} else {
buff.put((byte) DECIMAL_SMALL).
buff.put((byte) DECIMAL_SMALL).
putVarInt(scale).
putVarLong(b.longValue());
}
......
......@@ -294,6 +294,10 @@ GRANT { SELECT | INSERT | UPDATE | DELETE | ALL } [,...] ON
tableName [,...] TO { PUBLIC | userName | roleName }
","
Grants rights for a table to a user or role."
"Commands (Other)","GRANT ALTER ANY SCHEMA","
GRANT ALTER ANY SCHEMA TO userName
","
Grant schema altering rights to a user."
"Commands (Other)","GRANT ROLE","
GRANT roleName TO { PUBLIC | userName | roleName }
","
......
......@@ -160,5 +160,5 @@ public class WebServlet extends HttpServlet {
public void doPost(HttpServletRequest req, HttpServletResponse resp) throws IOException {
doGet(req, resp);
}
}
......@@ -190,7 +190,7 @@ class FileRec extends FileBase {
rec.log(Recorder.WRITE, name, buff, channel.position());
return result;
}
@Override
public int write(ByteBuffer src, long position) throws IOException {
byte[] buff = src.array();
......
......@@ -52,8 +52,8 @@ public class ValueGeometry extends Value {
}
private static ValueGeometry get(Geometry g) {
// not all WKT values can be represented in WKB, but since we persist it in WKB format,
// it has to be valid in WKB
// not all WKT values can be represented in WKB, but since we persist it
// in WKB format, it has to be valid in WKB
toWKB(g);
return (ValueGeometry) Value.cache(new ValueGeometry(g));
}
......@@ -66,8 +66,8 @@ public class ValueGeometry extends Value {
*/
public static ValueGeometry get(String s) {
Geometry g = fromWKT(s);
// not all WKT values can be represented in WKB, but since we persist it in WKB format,
// it has to be valid in WKB
// not all WKT values can be represented in WKB, but since we persist it
// in WKB format, it has to be valid in WKB
toWKB(g);
return (ValueGeometry) Value.cache(new ValueGeometry(g));
}
......@@ -216,7 +216,7 @@ public class ValueGeometry extends Value {
public byte[] toWKB() {
return toWKB(geometry);
}
private static byte[] toWKB(Geometry geometry) {
int dimensionCount = getDimensionCount(geometry);
boolean includeSRID = geometry.getSRID() != 0;
......@@ -265,7 +265,7 @@ public class ValueGeometry extends Value {
}
return super.convertTo(targetType);
}
/**
* A visitor that checks if there is a Z coordinate.
*/
......@@ -292,7 +292,7 @@ public class ValueGeometry extends Value {
public boolean isGeometryChanged() {
return false;
}
}
}
......@@ -231,7 +231,7 @@ java -cp . org.h2.test.TestAll crash >testCrash.txt
java org.h2.test.TestAll timer
*/
;
private static final boolean MV_STORE = false;
......
......@@ -42,7 +42,7 @@ public class TestRights extends TestBase {
testDropTempTables();
// testLowerCaseUser();
testSchemaRenameUser();
testAccessRights();
testAccessRights();
testSchemaAdminRole();
deleteDb("rights");
}
......@@ -199,7 +199,7 @@ public class TestRights extends TestBase {
stat.execute("drop user test1");
conn.close();
}
private void testSchemaAdminRole() throws SQLException {
if (config.memory) {
return;
......@@ -213,14 +213,14 @@ public class TestRights extends TestBase {
testTableType(conn, "CACHED");
executeSuccess("CREATE USER SCHEMA_CREATOR PASSWORD 'xyz'");
executeSuccess("CREATE SCHEMA SCHEMA_RIGHT_TEST");
executeSuccess("ALTER SCHEMA SCHEMA_RIGHT_TEST RENAME TO SCHEMA_RIGHT_TEST_RENAMED");
executeSuccess("DROP SCHEMA SCHEMA_RIGHT_TEST_RENAMED");
executeSuccess("CREATE SCHEMA SCHEMA_RIGHT_TEST_EXISTS");
conn.close();
/* try and fail */
// try and fail
conn = getConnection("rights;LOG=2", "SCHEMA_CREATOR", getPassword("xyz"));
stat = conn.createStatement();
assertThrows(ErrorCode.ADMIN_RIGHTS_REQUIRED, stat).execute(
......@@ -230,15 +230,15 @@ public class TestRights extends TestBase {
assertThrows(ErrorCode.ADMIN_RIGHTS_REQUIRED, stat).execute(
"DROP SCHEMA SCHEMA_RIGHT_TEST_EXISTS");
conn.close();
/* give them */
// give them
conn = getConnection("rights");
stat = conn.createStatement();
executeSuccess("DROP SCHEMA SCHEMA_RIGHT_TEST_EXISTS");
executeSuccess("GRANT ALTER ANY SCHEMA TO SCHEMA_CREATOR");
conn.close();
/* try and succeed */
// try and succeed
conn = getConnection("rights;LOG=2", "SCHEMA_CREATOR", getPassword("xyz"));
stat = conn.createStatement();
executeSuccess("CREATE SCHEMA SCHEMA_RIGHT_TEST");
......@@ -246,14 +246,14 @@ public class TestRights extends TestBase {
executeSuccess("DROP SCHEMA SCHEMA_RIGHT_TEST_RENAMED");
executeSuccess("CREATE SCHEMA SCHEMA_RIGHT_TEST_EXISTS");
conn.close();
/* revoke them */
// revoke them
conn = getConnection("rights");
stat = conn.createStatement();
executeSuccess("REVOKE ALTER ANY SCHEMA FROM SCHEMA_CREATOR");
conn.close();
/* try and fail */
// try and fail
conn = getConnection("rights;LOG=2", "SCHEMA_CREATOR", getPassword("xyz"));
stat = conn.createStatement();
assertThrows(ErrorCode.ADMIN_RIGHTS_REQUIRED, stat).
......
......@@ -548,7 +548,7 @@ public class TestSpatial extends TestBase {
/**
* Get the toString value of the object.
*
*
* @param object the object
* @return the string representation
*/
......@@ -581,5 +581,5 @@ public class TestSpatial extends TestBase {
// expected
}
}
}
......@@ -74,7 +74,7 @@ public class TestWeb extends TestBase {
testWebApp();
testIfExists();
}
private void testServlet() throws Exception {
WebServlet servlet = new WebServlet();
final HashMap<String, String> configMap = new HashMap<String, String>();
......@@ -88,7 +88,7 @@ public class TestWeb extends TestBase {
public String getServletName() {
return "H2Console";
}
@Override
public Enumeration<String> getInitParameterNames() {
return new Vector<String>(configMap.keySet()).elements();
......@@ -278,10 +278,10 @@ public class TestWeb extends TestBase {
result = client.get(url);
client.readSessionId(result);
result = client.get(url, "login.jsp");
result = client.get(url, "test.do?driver=org.h2.Driver&url=jdbc:h2:mem:webExists" +
result = client.get(url, "test.do?driver=org.h2.Driver&url=jdbc:h2:mem:webExists" +
"&user=" + getUser() + "&password=" + getPassword() + "&name=_test_");
assertTrue(result.indexOf("Exception") < 0);
result = client.get(url, "test.do?driver=org.h2.Driver&url=jdbc:h2:mem:web" +
result = client.get(url, "test.do?driver=org.h2.Driver&url=jdbc:h2:mem:web" +
"&user=" + getUser() + "&password=" + getPassword() + "&name=_test_");
assertContains(result, "Exception");
} finally {
......@@ -289,7 +289,7 @@ public class TestWeb extends TestBase {
conn.close();
}
}
private void testWebApp() throws Exception {
Server server = new Server();
server.setOut(new PrintStream(new ByteArrayOutputStream()));
......@@ -561,18 +561,18 @@ public class TestWeb extends TestBase {
public static void openBrowser(String url) {
lastUrl = url;
}
/**
* A HTTP servlet request for testing.
*/
static class TestHttpServletRequest implements HttpServletRequest {
private String pathInfo;
void setPathInfo(String pathInfo) {
this.pathInfo = pathInfo;
}
@Override
public Object getAttribute(String name) {
return null;
......@@ -843,16 +843,16 @@ public class TestWeb extends TestBase {
public boolean isUserInRole(String x) {
return false;
}
}
/**
* A HTTP servlet response for testing.
*/
static class TestHttpServletResponse implements HttpServletResponse {
ServletOutputStream servletOutputStream;
void setServletOutputStream(ServletOutputStream servletOutputStream) {
this.servletOutputStream = servletOutputStream;
}
......@@ -1016,21 +1016,21 @@ public class TestWeb extends TestBase {
public void setStatus(int arg0, String arg1) {
// ignore
}
}
/**
* A servlet output stream for testing.
*/
static class TestServletOutputStream extends ServletOutputStream {
private final ByteArrayOutputStream buff = new ByteArrayOutputStream();
@Override
public void write(int b) throws IOException {
buff.write(b);
}
@Override
public String toString() {
try {
......@@ -1039,7 +1039,7 @@ public class TestWeb extends TestBase {
return e.toString();
}
}
}
}
......@@ -46,7 +46,7 @@ public class TestCacheLIRS extends TestBase {
testScanResistance();
testRandomOperations();
}
private static void testRandomSmallCache() {
Random r = new Random(1);
for (int i = 0; i < 10000; i++) {
......
......@@ -45,7 +45,7 @@ public class TestCacheLongKeyLIRS extends TestBase {
testScanResistance();
testRandomOperations();
}
private static void testRandomSmallCache() {
Random r = new Random(1);
for (int i = 0; i < 10000; i++) {
......
......@@ -39,7 +39,7 @@ public class TestKillProcessWhileWriting extends TestBase {
fs.setPartialWrites(false);
test("unstable:memFS:killProcess.h3");
if (config.big) {
if (config.big) {
fs.setPartialWrites(true);
test("unstable:memFS:killProcess.h3");
}
......
/*
* Copyright 2004-2013 H2 Group. Multiple-Licensed under the H2 License,
* Version 1.0, and under the Eclipse Public License, Version 1.0
* (http://h2database.com/html/license.html).
* Initial Developer: H2 Group
*/
package org.h2.test.unit;
import org.h2.bnf.Bnf;
import org.h2.bnf.context.DbContents;
import org.h2.bnf.context.DbContextRule;
import org.h2.bnf.context.DbProcedure;
import org.h2.bnf.context.DbSchema;
import org.h2.test.TestBase;
import java.sql.Connection;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
/**
* Test Bnf Sql parser
* @author Nicolas Fortin
*/
public class TestBnf extends TestBase {
/**
* Run just this test.
*
* @param a ignored
*/
public static void main(String... a) throws Exception {
TestBase.createCaller().init().test();
}
@Override
public void test() throws Exception {
deleteDb("bnf");
Connection conn = getConnection("bnf");
try {
testProcedures(conn, false);
} finally {
conn.close();
}
conn = getConnection("bnf;mode=mysql");
try {
testProcedures(conn, true);
} finally {
conn.close();
}
}
private void testProcedures(Connection conn, boolean isMySQLMode) throws Exception {
// Register a procedure and check if it is present in DbContents
conn.createStatement().execute("DROP ALIAS IF EXISTS CUSTOM_PRINT");
conn.createStatement().execute("CREATE ALIAS CUSTOM_PRINT AS $$ void print(String s) { System.out.println(s); } $$");
conn.createStatement().execute("DROP TABLE IF EXISTS TABLE_WITH_STRING_FIELD");
conn.createStatement().execute("CREATE TABLE TABLE_WITH_STRING_FIELD (STRING_FIELD VARCHAR(50), INT_FIELD integer)");
DbContents dbContents = new DbContents();
dbContents.readContents(conn.getMetaData());
assertTrue(dbContents.isH2());
assertFalse(dbContents.isDerby());
assertFalse(dbContents.isFirebird());
assertEquals(null, dbContents.quoteIdentifier(null));
if (isMySQLMode) {
assertTrue(dbContents.isH2ModeMySQL());
assertEquals("TEST", dbContents.quoteIdentifier("TEST"));
assertEquals("TEST", dbContents.quoteIdentifier("Test"));
assertEquals("TEST", dbContents.quoteIdentifier("test"));
} else {
assertFalse(dbContents.isH2ModeMySQL());
assertEquals("TEST", dbContents.quoteIdentifier("TEST"));
assertEquals("\"Test\"", dbContents.quoteIdentifier("Test"));
assertEquals("\"test\"", dbContents.quoteIdentifier("test"));
}
assertFalse(dbContents.isMSSQLServer());
assertFalse(dbContents.isMySQL());
assertFalse(dbContents.isOracle());
assertFalse(dbContents.isPostgreSQL());
assertFalse(dbContents.isSQLite());
DbSchema defaultSchema = dbContents.getDefaultSchema();
DbProcedure[] procedures = defaultSchema.getProcedures();
Set<String> procedureName = new HashSet<String>(procedures.length);
for (DbProcedure procedure : procedures) {
assertTrue(defaultSchema == procedure.getSchema());
procedureName.add(procedure.getName());
}
if (isMySQLMode) {
assertTrue(procedureName.contains("custom_print"));
} else {
assertTrue(procedureName.contains("CUSTOM_PRINT"));
}
if (isMySQLMode) {
return;
}
// Test completion
Bnf bnf = Bnf.getInstance(null);
DbContextRule columnRule = new DbContextRule(dbContents, DbContextRule.COLUMN);
bnf.updateTopic("column_name", columnRule);
bnf.updateTopic("expression", new DbContextRule(dbContents, DbContextRule.PROCEDURE));
bnf.linkStatements();
// Test partial
Map<String, String> tokens = bnf.getNextTokenList("SELECT CUSTOM_PR");
assertTrue(tokens.values().contains("INT"));
// Test parameters
tokens = bnf.getNextTokenList("SELECT CUSTOM_PRINT(");
assertTrue(tokens.values().contains("STRING_FIELD"));
assertFalse(tokens.values().contains("INT_FIELD"));
// Test parameters with spaces
tokens = bnf.getNextTokenList("SELECT CUSTOM_PRINT ( ");
assertTrue(tokens.values().contains("STRING_FIELD"));
assertFalse(tokens.values().contains("INT_FIELD"));
// Test parameters with close bracket
tokens = bnf.getNextTokenList("SELECT CUSTOM_PRINT ( STRING_FIELD");
assertTrue(tokens.values().contains(")"));
}
/*
* Copyright 2004-2013 H2 Group. Multiple-Licensed under the H2 License,
* Version 1.0, and under the Eclipse Public License, Version 1.0
* (http://h2database.com/html/license.html).
* Initial Developer: H2 Group
*/
package org.h2.test.unit;
import org.h2.bnf.Bnf;
import org.h2.bnf.context.DbContents;
import org.h2.bnf.context.DbContextRule;
import org.h2.bnf.context.DbProcedure;
import org.h2.bnf.context.DbSchema;
import org.h2.test.TestBase;
import java.sql.Connection;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
/**
* Test Bnf Sql parser
* @author Nicolas Fortin
*/
public class TestBnf extends TestBase {
/**
* Run just this test.
*
* @param a ignored
*/
public static void main(String... a) throws Exception {
TestBase.createCaller().init().test();
}
@Override
public void test() throws Exception {
deleteDb("bnf");
Connection conn = getConnection("bnf");
try {
testProcedures(conn, false);
} finally {
conn.close();
}
conn = getConnection("bnf;mode=mysql");
try {
testProcedures(conn, true);
} finally {
conn.close();
}
}
private void testProcedures(Connection conn, boolean isMySQLMode) throws Exception {
// Register a procedure and check if it is present in DbContents
conn.createStatement().execute("DROP ALIAS IF EXISTS CUSTOM_PRINT");
conn.createStatement().execute("CREATE ALIAS CUSTOM_PRINT AS $$ void print(String s) { System.out.println(s); } $$");
conn.createStatement().execute("DROP TABLE IF EXISTS TABLE_WITH_STRING_FIELD");
conn.createStatement().execute("CREATE TABLE TABLE_WITH_STRING_FIELD (STRING_FIELD VARCHAR(50), INT_FIELD integer)");
DbContents dbContents = new DbContents();
dbContents.readContents(conn.getMetaData());
assertTrue(dbContents.isH2());
assertFalse(dbContents.isDerby());
assertFalse(dbContents.isFirebird());
assertEquals(null, dbContents.quoteIdentifier(null));
if (isMySQLMode) {
assertTrue(dbContents.isH2ModeMySQL());
assertEquals("TEST", dbContents.quoteIdentifier("TEST"));
assertEquals("TEST", dbContents.quoteIdentifier("Test"));
assertEquals("TEST", dbContents.quoteIdentifier("test"));
} else {
assertFalse(dbContents.isH2ModeMySQL());
assertEquals("TEST", dbContents.quoteIdentifier("TEST"));
assertEquals("\"Test\"", dbContents.quoteIdentifier("Test"));
assertEquals("\"test\"", dbContents.quoteIdentifier("test"));
}
assertFalse(dbContents.isMSSQLServer());
assertFalse(dbContents.isMySQL());
assertFalse(dbContents.isOracle());
assertFalse(dbContents.isPostgreSQL());
assertFalse(dbContents.isSQLite());
DbSchema defaultSchema = dbContents.getDefaultSchema();
DbProcedure[] procedures = defaultSchema.getProcedures();
Set<String> procedureName = new HashSet<String>(procedures.length);
for (DbProcedure procedure : procedures) {
assertTrue(defaultSchema == procedure.getSchema());
procedureName.add(procedure.getName());
}
if (isMySQLMode) {
assertTrue(procedureName.contains("custom_print"));
} else {
assertTrue(procedureName.contains("CUSTOM_PRINT"));
}
if (isMySQLMode) {
return;
}
// Test completion
Bnf bnf = Bnf.getInstance(null);
DbContextRule columnRule = new DbContextRule(dbContents, DbContextRule.COLUMN);
bnf.updateTopic("column_name", columnRule);
bnf.updateTopic("expression", new DbContextRule(dbContents, DbContextRule.PROCEDURE));
bnf.linkStatements();
// Test partial
Map<String, String> tokens = bnf.getNextTokenList("SELECT CUSTOM_PR");
assertTrue(tokens.values().contains("INT"));
// Test parameters
tokens = bnf.getNextTokenList("SELECT CUSTOM_PRINT(");
assertTrue(tokens.values().contains("STRING_FIELD"));
assertFalse(tokens.values().contains("INT_FIELD"));
// Test parameters with spaces
tokens = bnf.getNextTokenList("SELECT CUSTOM_PRINT ( ");
assertTrue(tokens.values().contains("STRING_FIELD"));
assertFalse(tokens.values().contains("INT_FIELD"));
// Test parameters with close bracket
tokens = bnf.getNextTokenList("SELECT CUSTOM_PRINT ( STRING_FIELD");
assertTrue(tokens.values().contains(")"));
}
}
\ No newline at end of file
......@@ -206,7 +206,7 @@ public class TestFileSystem extends TestBase {
private void testMemFsDir() throws IOException {
FileUtils.newOutputStream("memFS:data/test/a.txt", false).close();
assertEquals(FileUtils.newDirectoryStream("memFS:data/test").toString(),
assertEquals(FileUtils.newDirectoryStream("memFS:data/test").toString(),
1, FileUtils.newDirectoryStream("memFS:data/test").size());
FileUtils.deleteRecursive("memFS:", false);
}
......
......@@ -71,7 +71,7 @@ public class TestReopen extends TestBase implements Recorder {
if (op != Recorder.WRITE && op != Recorder.TRUNCATE) {
return;
}
if (!fileName.endsWith(Constants.SUFFIX_PAGE_FILE) &&
if (!fileName.endsWith(Constants.SUFFIX_PAGE_FILE) &&
!fileName.endsWith(Constants.SUFFIX_MV_FILE)) {
return;
}
......
......@@ -30,9 +30,9 @@ public class FilePathUnstable extends FilePathWrapper {
private static final IOException DISK_FULL = new IOException("Disk full");
private static int diskFullOffCount;
private static boolean partialWrites;
private static Random random = new Random(1);
/**
......@@ -44,32 +44,32 @@ public class FilePathUnstable extends FilePathWrapper {
FilePath.register(INSTANCE);
return INSTANCE;
}
/**
* Whether partial writes are possible (writing only part of the data).
*
*
* @param partialWrites true to enable
*/
public void setPartialWrites(boolean partialWrites) {
FilePathUnstable.partialWrites = partialWrites;
}
boolean getPartialWrites() {
return partialWrites;
}
/**
* Set the random seed.
*
*
* @param seed the new seed
*/
public void setSeed(long seed) {
random.setSeed(seed);
}
/**
* Get a buffer with a subset (the head) of the data of the source buffer.
*
*
* @param src the source buffer
* @return a buffer with a subset of the data
*/
......@@ -278,7 +278,7 @@ class FileUnstable extends FileBase {
}
return channel.write(src);
}
@Override
public int write(ByteBuffer src, long position) throws IOException {
checkError();
......
......@@ -828,7 +828,7 @@ public class CacheLIRS<K, V> extends AbstractMap<K, V> {
/**
* Remove the entry from the stack. The head itself must not be removed.
*
*
* @param e the entry
*/
private void removeFromStack(Entry<K, V> e) {
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论