aboutsummaryrefslogtreecommitdiffstats
path: root/server/src/com/vaadin/data/util/sqlcontainer/query/TableQuery.java
diff options
context:
space:
mode:
authorHenri Sara <hesara@vaadin.com>2013-04-25 09:18:51 +0300
committerVaadin Code Review <review@vaadin.com>2013-04-25 08:30:35 +0000
commitf31cdf4e67a2465db20e661d3f406e24b792ec06 (patch)
tree5ccda6859f6e3155a0e7503f77442c13cf0b70ee /server/src/com/vaadin/data/util/sqlcontainer/query/TableQuery.java
parentbb248c0a5e41eefe3727ae50a809d135f0a7d4aa (diff)
downloadvaadin-framework-f31cdf4e67a2465db20e661d3f406e24b792ec06.tar.gz
vaadin-framework-f31cdf4e67a2465db20e661d3f406e24b792ec06.zip
Support schemas and catalogs in TableQuery (#7827)
Change-Id: Ib8282dc77e3d06d49ce8815a3f4b036541d9acea
Diffstat (limited to 'server/src/com/vaadin/data/util/sqlcontainer/query/TableQuery.java')
-rw-r--r--server/src/com/vaadin/data/util/sqlcontainer/query/TableQuery.java200
1 files changed, 167 insertions, 33 deletions
diff --git a/server/src/com/vaadin/data/util/sqlcontainer/query/TableQuery.java b/server/src/com/vaadin/data/util/sqlcontainer/query/TableQuery.java
index caed5526e3..39c8365076 100644
--- a/server/src/com/vaadin/data/util/sqlcontainer/query/TableQuery.java
+++ b/server/src/com/vaadin/data/util/sqlcontainer/query/TableQuery.java
@@ -50,9 +50,23 @@ import com.vaadin.data.util.sqlcontainer.query.generator.StatementHelper;
public class TableQuery extends AbstractTransactionalQuery implements
QueryDelegate, QueryDelegate.RowIdChangeNotifier {
- /** Table name, primary key column name(s) and version column name */
+ /**
+ * Table name (without catalog or schema information).
+ */
private String tableName;
+ private String catalogName;
+ private String schemaName;
+ /**
+ * Cached concatenated version of the table name.
+ */
+ private String fullTableName;
+ /**
+ * Primary key column name(s) in the table.
+ */
private List<String> primaryKeyColumns;
+ /**
+ * Version column name in the table.
+ */
private String versionColumn;
/** Currently set Filters and OrderBys */
@@ -70,15 +84,15 @@ public class TableQuery extends AbstractTransactionalQuery implements
/** Set to true to output generated SQL Queries to System.out */
private final boolean debug = false;
- /** Prevent no-parameters instantiation of TableQuery */
- @SuppressWarnings("unused")
- private TableQuery() {
- }
-
/**
* Creates a new TableQuery using the given connection pool, SQL generator
* and table name to fetch the data from. All parameters must be non-null.
*
+ * The table name must be a simple name with no catalog or schema
+ * information. If those are needed, use
+ * {@link #TableQuery(String, String, String, JDBCConnectionPool, SQLGenerator)}
+ * .
+ *
* @param tableName
* Name of the database table to connect to
* @param connectionPool
@@ -88,15 +102,30 @@ public class TableQuery extends AbstractTransactionalQuery implements
*/
public TableQuery(String tableName, JDBCConnectionPool connectionPool,
SQLGenerator sqlGenerator) {
- super(connectionPool);
- if (tableName == null || tableName.trim().length() < 1
- || connectionPool == null || sqlGenerator == null) {
- throw new IllegalArgumentException(
- "All parameters must be non-null and a table name must be given.");
- }
- this.tableName = tableName;
- this.sqlGenerator = sqlGenerator;
- fetchMetaData();
+ this(null, null, tableName, connectionPool, sqlGenerator);
+ }
+
+ /**
+ * Creates a new TableQuery using the given connection pool, SQL generator
+ * and table name to fetch the data from. Catalog and schema names can be
+ * null, all other parameters must be non-null.
+ *
+ * @param catalogName
+ * Name of the database catalog (can be null)
+ * @param schemaName
+ * Name of the database schema (can be null)
+ * @param tableName
+ * Name of the database table to connect to
+ * @param connectionPool
+ * Connection pool for accessing the database
+ * @param sqlGenerator
+ * SQL query generator implementation
+ * @since 7.1
+ */
+ public TableQuery(String catalogName, String schemaName, String tableName,
+ JDBCConnectionPool connectionPool, SQLGenerator sqlGenerator) {
+ this(catalogName, schemaName, tableName, connectionPool, sqlGenerator,
+ true);
}
/**
@@ -104,6 +133,11 @@ public class TableQuery extends AbstractTransactionalQuery implements
* to fetch the data from. All parameters must be non-null. The default SQL
* generator will be used for queries.
*
+ * The table name must be a simple name with no catalog or schema
+ * information. If those are needed, use
+ * {@link #TableQuery(String, String, String, JDBCConnectionPool, SQLGenerator)}
+ * .
+ *
* @param tableName
* Name of the database table to connect to
* @param connectionPool
@@ -113,6 +147,48 @@ public class TableQuery extends AbstractTransactionalQuery implements
this(tableName, connectionPool, new DefaultSQLGenerator());
}
+ /**
+ * Creates a new TableQuery using the given connection pool, SQL generator
+ * and table name to fetch the data from. Catalog and schema names can be
+ * null, all other parameters must be non-null.
+ *
+ * @param catalogName
+ * Name of the database catalog (can be null)
+ * @param schemaName
+ * Name of the database schema (can be null)
+ * @param tableName
+ * Name of the database table to connect to
+ * @param connectionPool
+ * Connection pool for accessing the database
+ * @param sqlGenerator
+ * SQL query generator implementation
+ * @param escapeNames
+ * true to escape special characters in catalog, schema and table
+ * names, false to use the names as-is
+ * @since 7.1
+ */
+ protected TableQuery(String catalogName, String schemaName,
+ String tableName, JDBCConnectionPool connectionPool,
+ SQLGenerator sqlGenerator, boolean escapeNames) {
+ super(connectionPool);
+ if (tableName == null || tableName.trim().length() < 1
+ || connectionPool == null || sqlGenerator == null) {
+ throw new IllegalArgumentException(
+ "Table name, connection pool and SQL generator parameters must be non-null and non-empty.");
+ }
+ if (escapeNames) {
+ this.catalogName = SQLUtil.escapeSQL(catalogName);
+ this.schemaName = SQLUtil.escapeSQL(schemaName);
+ this.tableName = SQLUtil.escapeSQL(tableName);
+ } else {
+ this.catalogName = catalogName;
+ this.schemaName = schemaName;
+ this.tableName = tableName;
+ }
+ this.sqlGenerator = sqlGenerator;
+ fetchMetaData();
+ }
+
/*
* (non-Javadoc)
*
@@ -121,8 +197,8 @@ public class TableQuery extends AbstractTransactionalQuery implements
@Override
public int getCount() throws SQLException {
getLogger().log(Level.FINE, "Fetching count...");
- StatementHelper sh = sqlGenerator.generateSelectQuery(tableName,
- filters, null, 0, 0, "COUNT(*)");
+ StatementHelper sh = sqlGenerator.generateSelectQuery(
+ getFullTableName(), filters, null, 0, 0, "COUNT(*)");
boolean shouldCloseTransaction = false;
if (!isInTransaction()) {
shouldCloseTransaction = true;
@@ -167,11 +243,11 @@ public class TableQuery extends AbstractTransactionalQuery implements
for (int i = 0; i < primaryKeyColumns.size(); i++) {
ob.add(new OrderBy(primaryKeyColumns.get(i), true));
}
- sh = sqlGenerator.generateSelectQuery(tableName, filters, ob,
- offset, pagelength, null);
+ sh = sqlGenerator.generateSelectQuery(getFullTableName(), filters,
+ ob, offset, pagelength, null);
} else {
- sh = sqlGenerator.generateSelectQuery(tableName, filters, orderBys,
- offset, pagelength, null);
+ sh = sqlGenerator.generateSelectQuery(getFullTableName(), filters,
+ orderBys, offset, pagelength, null);
}
return executeQuery(sh);
}
@@ -204,11 +280,11 @@ public class TableQuery extends AbstractTransactionalQuery implements
int result = 0;
if (row.getId() instanceof TemporaryRowId) {
setVersionColumnFlagInProperty(row);
- sh = sqlGenerator.generateInsertQuery(tableName, row);
+ sh = sqlGenerator.generateInsertQuery(getFullTableName(), row);
result = executeUpdateReturnKeys(sh, row);
} else {
setVersionColumnFlagInProperty(row);
- sh = sqlGenerator.generateUpdateQuery(tableName, row);
+ sh = sqlGenerator.generateUpdateQuery(getFullTableName(), row);
result = executeUpdate(sh);
}
if (versionColumn != null && result == 0) {
@@ -244,7 +320,8 @@ public class TableQuery extends AbstractTransactionalQuery implements
/* Set version column, if one is provided */
setVersionColumnFlagInProperty(row);
/* Generate query */
- StatementHelper sh = sqlGenerator.generateInsertQuery(tableName, row);
+ StatementHelper sh = sqlGenerator.generateInsertQuery(
+ getFullTableName(), row);
Connection connection = null;
PreparedStatement pstmt = null;
ResultSet generatedKeys = null;
@@ -371,10 +448,61 @@ public class TableQuery extends AbstractTransactionalQuery implements
versionColumn = column;
}
+ /**
+ * Returns the table name for the query without catalog and schema
+ * information.
+ *
+ * @return table name, not null
+ */
public String getTableName() {
return tableName;
}
+ /**
+ * Returns the catalog name for the query.
+ *
+ * @return catalog name, can be null
+ * @since 7.1
+ */
+ public String getCatalogName() {
+ return catalogName;
+ }
+
+ /**
+ * Returns the catalog name for the query.
+ *
+ * @return catalog name, can be null
+ * @since 7.1
+ */
+ public String getSchemaName() {
+ return schemaName;
+ }
+
+ /**
+ * Returns the complete table name obtained by concatenation of the catalog
+ * and schema names (if any) and the table name.
+ *
+ * This method can be overridden if customization is needed.
+ *
+ * @return table name in the form it should be used in query and update
+ * statements
+ * @since 7.1
+ */
+ protected String getFullTableName() {
+ if (fullTableName == null) {
+ StringBuilder sb = new StringBuilder();
+ if (catalogName != null) {
+ sb.append(catalogName).append(".");
+ }
+ if (schemaName != null) {
+ sb.append(schemaName).append(".");
+ }
+ sb.append(tableName);
+ fullTableName = sb.toString();
+ }
+ return fullTableName;
+ }
+
public SQLGenerator getSqlGenerator() {
return sqlGenerator;
}
@@ -480,22 +608,28 @@ public class TableQuery extends AbstractTransactionalQuery implements
connection = getConnection();
DatabaseMetaData dbmd = connection.getMetaData();
if (dbmd != null) {
- tableName = SQLUtil.escapeSQL(tableName);
- tables = dbmd.getTables(null, null, tableName, null);
+ tables = dbmd.getTables(catalogName, schemaName, tableName,
+ null);
if (!tables.next()) {
- tables = dbmd.getTables(null, null,
+ String catalog = (catalogName != null) ? catalogName
+ .toUpperCase() : null;
+ String schema = (schemaName != null) ? schemaName
+ .toUpperCase() : null;
+ tables = dbmd.getTables(catalog, schema,
tableName.toUpperCase(), null);
if (!tables.next()) {
throw new IllegalArgumentException(
"Table with the name \""
- + tableName
+ + getFullTableName()
+ "\" was not found. Check your database contents.");
} else {
+ catalogName = catalog;
+ schemaName = schema;
tableName = tableName.toUpperCase();
}
}
tables.close();
- rs = dbmd.getPrimaryKeys(null, null, tableName);
+ rs = dbmd.getPrimaryKeys(catalogName, schemaName, tableName);
List<String> names = new ArrayList<String>();
while (rs.next()) {
names.add(rs.getString("COLUMN_NAME"));
@@ -507,7 +641,7 @@ public class TableQuery extends AbstractTransactionalQuery implements
if (primaryKeyColumns == null || primaryKeyColumns.isEmpty()) {
throw new IllegalArgumentException(
"Primary key constraints have not been defined for the table \""
- + tableName
+ + getFullTableName()
+ "\". Use FreeFormQuery to access this table.");
}
for (String colName : primaryKeyColumns) {
@@ -592,7 +726,7 @@ public class TableQuery extends AbstractTransactionalQuery implements
getLogger().log(Level.FINE, "Removing row with id: {0}",
row.getId().getId()[0]);
}
- if (executeUpdate(sqlGenerator.generateDeleteQuery(getTableName(),
+ if (executeUpdate(sqlGenerator.generateDeleteQuery(getFullTableName(),
primaryKeyColumns, versionColumn, row)) == 1) {
return true;
}
@@ -622,8 +756,8 @@ public class TableQuery extends AbstractTransactionalQuery implements
filtersAndKeys.add(new Equal(colName, keys[ix]));
ix++;
}
- StatementHelper sh = sqlGenerator.generateSelectQuery(tableName,
- filtersAndKeys, orderBys, 0, 0, "*");
+ StatementHelper sh = sqlGenerator.generateSelectQuery(
+ getFullTableName(), filtersAndKeys, orderBys, 0, 0, "*");
boolean shouldCloseTransaction = false;
if (!isInTransaction()) {