/*
* Copyright 2008-2012 Amazon Technologies, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at:
*
* http://aws.amazon.com/apache2.0
*
* This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES
* OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and
* limitations under the License.
*/
package com.amazonaws.eclipse.datatools.enablement.simpledb.internal.driver;
import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.RowIdLifetime;
import java.sql.SQLException;
import com.amazonaws.eclipse.datatools.enablement.simpledb.driver.JdbcConnection;
import com.amazonaws.eclipse.datatools.enablement.simpledb.driver.SimpleDBItemName;
/**
* SDB JDBC metadata wrapper. Provides domains and attributes and all other
* database properties. For metadata queries creates specific JDBC statements
* which are transformed later into requests through the Amazon SDB client, see
* {@link JdbcStatement}.
*/
public class JdbcDatabaseMetaData implements DatabaseMetaData {
private JdbcConnection conn;
private PreparedStatement getTables = null, getColumns = null,
getTableTypes = null, getTypeInfo = null, getCrossReference = null,
getCatalogs = null, getSchemas = null, getUDTs = null,
getColumnsTblName = null, getSuperTypes = null,
getSuperTables = null, getTablePrivileges = null,
getExportedKeys = null, getPrimaryKeys = null,
getProcedures = null, getProcedureColumns = null,
getAttributes = null, getBestRowIdentifier = null,
getVersionColumns = null, getColumnPrivileges = null;
/** Used by PrepStmt to save generating a new statement every call. */
private PreparedStatement getGeneratedKeys = null;
public JdbcDatabaseMetaData(final JdbcConnection connection) {
this.conn = connection;
}
void checkOpen() throws SQLException {
if (this.conn == null) {
throw new SQLException("connection closed"); //$NON-NLS-1$
}
}
synchronized void close() throws SQLException {
if (this.conn == null) {
return;
}
try {
if (this.getTables != null) {
this.getTables.close();
}
if (this.getColumns != null) {
this.getColumns.close();
}
if (this.getTableTypes != null) {
this.getTableTypes.close();
}
if (this.getTypeInfo != null) {
this.getTypeInfo.close();
}
if (this.getCrossReference != null) {
this.getCrossReference.close();
}
if (this.getCatalogs != null) {
this.getCatalogs.close();
}
if (this.getSchemas != null) {
this.getSchemas.close();
}
if (this.getUDTs != null) {
this.getUDTs.close();
}
if (this.getColumnsTblName != null) {
this.getColumnsTblName.close();
}
if (this.getSuperTypes != null) {
this.getSuperTypes.close();
}
if (this.getSuperTables != null) {
this.getSuperTables.close();
}
if (this.getTablePrivileges != null) {
this.getTablePrivileges.close();
}
if (this.getExportedKeys != null) {
this.getExportedKeys.close();
}
if (this.getPrimaryKeys != null) {
this.getPrimaryKeys.close();
}
if (this.getProcedures != null) {
this.getProcedures.close();
}
if (this.getProcedureColumns != null) {
this.getProcedureColumns.close();
}
if (this.getAttributes != null) {
this.getAttributes.close();
}
if (this.getBestRowIdentifier != null) {
this.getBestRowIdentifier.close();
}
if (this.getVersionColumns != null) {
this.getVersionColumns.close();
}
if (this.getColumnPrivileges != null) {
this.getColumnPrivileges.close();
}
if (this.getGeneratedKeys != null) {
this.getGeneratedKeys.close();
}
this.getTables = null;
this.getColumns = null;
this.getTableTypes = null;
this.getTypeInfo = null;
this.getCrossReference = null;
this.getCatalogs = null;
this.getSchemas = null;
this.getUDTs = null;
this.getColumnsTblName = null;
this.getSuperTypes = null;
this.getSuperTables = null;
this.getTablePrivileges = null;
this.getExportedKeys = null;
this.getPrimaryKeys = null;
this.getProcedures = null;
this.getProcedureColumns = null;
this.getAttributes = null;
this.getBestRowIdentifier = null;
this.getVersionColumns = null;
this.getColumnPrivileges = null;
this.getGeneratedKeys = null;
} finally {
this.conn = null;
}
}
public ResultSet getAttributes(final String catalog,
final String schemaPattern, final String typeNamePattern,
final String attributeNamePattern) throws SQLException {
// XXX
return new JdbcResultSet(null);
}
public ResultSet getBestRowIdentifier(final String catalog,
final String schema, final String table, final int scope,
final boolean nullable) throws SQLException {
return new JdbcResultSet(null);
// throw new SQLException("not supported: bestRowIdentifier");
}
public ResultSet getCatalogs() throws SQLException {
if (this.getCatalogs == null) {
this.getCatalogs = new JdbcPreparedStatement(this.conn,
"select null as TABLE_CAT") { //$NON-NLS-1$
@Override
ExecutionResult execute(final String queryText,
final int startingRow, final int maxRows,
final int requestSize, final String nextToken)
throws SQLException {
this.data.add("TABLE_CAT", "", 0); //$NON-NLS-1$ //$NON-NLS-2$
return new ExecutionResult(null, 1);
}
};
}
this.getCatalogs.clearParameters();
return this.getCatalogs.executeQuery();
}
public ResultSet getColumnPrivileges(final String catalog,
final String schema, final String table,
final String columnNamePattern) throws SQLException {
return new JdbcResultSet(null);
}
public ResultSet getColumns(final String catalog,
final String schemaPattern, final String tableNamePattern,
final String columnNamePattern) throws SQLException {
if (this.getColumns == null) {
this.getColumns = new ListAttributesStatement(this.conn, null);
}
this.getColumns.clearParameters();
if (tableNamePattern == null || tableNamePattern.length() == 0) {
return new JdbcResultSet(null);
}
return this.getColumns
.executeQuery("select * from " + JdbcStatement.DELIMITED_IDENTIFIER_QUOTE + tableNamePattern //$NON-NLS-1$
+ JdbcStatement.DELIMITED_IDENTIFIER_QUOTE
+ " limit 10"); //$NON-NLS-1$
}
public ResultSet getCrossReference(final String primaryCatalog,
final String primarySchema, final String primaryTable,
final String foreignCatalog, final String foreignSchema,
final String foreignTable) throws SQLException {
return new JdbcResultSet(null);
}
public ResultSet getExportedKeys(final String catalog, final String schema,
final String table) throws SQLException {
return new JdbcResultSet(null);
}
public ResultSet getImportedKeys(final String catalog, final String schema,
final String table) throws SQLException {
return new JdbcResultSet(null);
}
public ResultSet getIndexInfo(final String catalog, final String schema,
final String table, final boolean unique, final boolean approximate)
throws SQLException {
return new JdbcResultSet(null);
}
public ResultSet getPrimaryKeys(final String catalog, final String schema,
final String table) throws SQLException {
if (this.getPrimaryKeys == null) {
this.getPrimaryKeys = new JdbcPreparedStatement(this.conn,
"select null") { //$NON-NLS-1$
@Override
ExecutionResult execute(final String queryText,
final int startingRow, final int maxRows,
final int requestSize, final String nextToken)
throws SQLException {
this.data.add("TABLE_CAT", catalog, 0); //$NON-NLS-1$
this.data.add("TABLE_SCHEM", schema, 0); //$NON-NLS-1$
this.data.add("TABLE_NAME", table, 0); //$NON-NLS-1$
this.data.add(
"COLUMN_NAME", SimpleDBItemName.ITEM_HEADER, 0); //$NON-NLS-1$
this.data.add("KEY_SEQ", "0", 0); //$NON-NLS-1$ //$NON-NLS-2$
this.data.add("PK_NAME", null, 0); //$NON-NLS-1$
return new ExecutionResult(null, 1);
}
};
}
this.getPrimaryKeys.clearParameters();
return this.getPrimaryKeys.executeQuery();
}
public ResultSet getProcedureColumns(final String catalog,
final String schemaPattern, final String procedureNamePattern,
final String columnNamePattern) throws SQLException {
return new JdbcResultSet(null);
}
public ResultSet getProcedures(final String catalog,
final String schemaPattern, final String procedureNamePattern)
throws SQLException {
return new JdbcResultSet(null);
}
public ResultSet getSchemas() throws SQLException {
if (this.getSchemas == null) {
this.getSchemas = new JdbcPreparedStatement(this.conn,
"select null as TABLE_SCHEM, null as TABLE_CATALOG") { //$NON-NLS-1$
@Override
ExecutionResult execute(final String queryText,
final int startingRow, final int maxRows,
final int requestSize, final String nextToken)
throws SQLException {
this.data.add("TABLE_SCHEM", "", 0); //$NON-NLS-1$ //$NON-NLS-2$
this.data.add("TABLE_CATALOG", "", 0); //$NON-NLS-1$ //$NON-NLS-2$
return new ExecutionResult(null, 1);
}
};
}
this.getSchemas.clearParameters();
return this.getSchemas.executeQuery();
}
public ResultSet getSuperTables(final String catalog,
final String schemaPattern, final String tableNamePattern)
throws SQLException {
return new JdbcResultSet(null);
}
public ResultSet getSuperTypes(final String catalog,
final String schemaPattern, final String typeNamePattern)
throws SQLException {
return new JdbcResultSet(null);
}
public ResultSet getTablePrivileges(final String catalog,
final String schemaPattern, final String tableNamePattern)
throws SQLException {
return new JdbcResultSet(null);
}
public ResultSet getTableTypes() throws SQLException {
checkOpen();
if (this.getTableTypes == null) {
this.getTableTypes = new JdbcPreparedStatement(this.conn,
"select 'TABLE' as TABLE_TYPE;") { //$NON-NLS-1$
@Override
ExecutionResult execute(final String queryText,
final int startingRow, final int maxRows,
final int requestSize, final String nextToken)
throws SQLException {
this.data.add("TABLE_TYPE", "TABLE", 0); //$NON-NLS-1$ //$NON-NLS-2$
return new ExecutionResult(null, 1);
}
};
}
this.getTableTypes.clearParameters();
return this.getTableTypes.executeQuery();
}
public synchronized ResultSet getTables(final String c, final String s,
String t, final String[] types) throws SQLException {
if (this.getTables == null) {
this.getTables = new ListDomainsStatement(this.conn, null);
}
this.getTables.clearParameters();
checkOpen();
t = (t == null || t.length() == 0) ? "%" : t.toUpperCase(); //$NON-NLS-1$
// String sql =
// "select null as TABLE_CAT, null as TABLE_SCHEM, upper(name) as TABLE_NAME,"
// +
// " upper(type) as TABLE_TYPE, null as REMARKS, null as TYPE_CAT, null as TYPE_SCHEM,"
// +
// " null as TYPE_NAME, null as SELF_REFERENCING_COL_NAME, null as REF_GENERATION from domains"
// + " where TABLE_NAME like '" + escape(t) + "'";
//
// if (types != null) {
// sql += " and TABLE_TYPE in (";
// for (int i = 0; i < types.length; i++) {
// if (i > 0) {
// sql += ", ";
// }
// sql += "'" + types[i].toUpperCase() + "'";
// }
// sql += ")";
// }
//
// sql += ";";
return this.getTables
.executeQuery("select * from ALL_TABLES where " + JdbcStatement.DELIMITED_IDENTIFIER_QUOTE //$NON-NLS-1$
+ "TABLE_NAME" + JdbcStatement.DELIMITED_IDENTIFIER_QUOTE + "='" + t + "'"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
}
public ResultSet getTypeInfo() throws SQLException {
return new JdbcResultSet(null);
}
public ResultSet getUDTs(final String catalog, final String schemaPattern,
final String typeNamePattern, final int[] types)
throws SQLException {
return new JdbcResultSet(null);
}
public ResultSet getVersionColumns(final String catalog,
final String schema, final String table) throws SQLException {
return new JdbcResultSet(null);
}
public Connection getConnection() {
return this.conn;
}
public int getDatabaseMajorVersion() {
return 1;
}
public int getDatabaseMinorVersion() {
return 0;
}
public int getDriverMajorVersion() {
return 1;
}
public int getDriverMinorVersion() {
return 0;
}
public int getJDBCMajorVersion() {
return 2009;
}
public int getJDBCMinorVersion() {
return 4;
}
public int getDefaultTransactionIsolation() {
return Connection.TRANSACTION_SERIALIZABLE;
}
public int getMaxBinaryLiteralLength() {
return 0;
}
public int getMaxCatalogNameLength() {
return 0;
}
public int getMaxCharLiteralLength() {
return 0;
}
public int getMaxColumnNameLength() {
return 0;
}
public int getMaxColumnsInGroupBy() {
return 0;
}
public int getMaxColumnsInIndex() {
return 0;
}
public int getMaxColumnsInOrderBy() {
return 0;
}
public int getMaxColumnsInSelect() {
return 0;
}
public int getMaxColumnsInTable() {
return 0;
}
public int getMaxConnections() {
return 0;
}
public int getMaxCursorNameLength() {
return 0;
}
public int getMaxIndexLength() {
return 0;
}
public int getMaxProcedureNameLength() {
return 0;
}
public int getMaxRowSize() {
return 0;
}
public int getMaxSchemaNameLength() {
return 0;
}
public int getMaxStatementLength() {
return 0;
}
public int getMaxStatements() {
return 0;
}
public int getMaxTableNameLength() {
return 0;
}
public int getMaxTablesInSelect() {
return 0;
}
public int getMaxUserNameLength() {
return 0;
}
public int getResultSetHoldability() {
return ResultSet.CLOSE_CURSORS_AT_COMMIT;
}
public int getSQLStateType() {
return sqlStateSQL99;
}
public String getDatabaseProductName() {
return "SimpleDB"; //$NON-NLS-1$
}
public String getDatabaseProductVersion() throws SQLException {
return "2009.4.15"; // ? //$NON-NLS-1$
}
public String getDriverName() {
return "SimpleDB"; //$NON-NLS-1$
}
public String getDriverVersion() {
return "1.0"; //$NON-NLS-1$
}
public String getExtraNameCharacters() {
return ""; //$NON-NLS-1$
}
public String getCatalogSeparator() {
return "."; //$NON-NLS-1$
}
public String getCatalogTerm() {
return "catalog"; //$NON-NLS-1$
}
public String getSchemaTerm() {
return "schema"; //$NON-NLS-1$
}
public String getProcedureTerm() {
return "not_implemented"; //$NON-NLS-1$
}
public String getSearchStringEscape() {
return null;
}
public String getIdentifierQuoteString() {
return "`"; //$NON-NLS-1$
}
public String getSQLKeywords() {
return ""; //$NON-NLS-1$
}
public String getNumericFunctions() {
return ""; //$NON-NLS-1$
}
public String getStringFunctions() {
return ""; //$NON-NLS-1$
}
public String getSystemFunctions() {
return ""; //$NON-NLS-1$
}
public String getTimeDateFunctions() {
return ""; //$NON-NLS-1$
}
public String getURL() {
return null;
}
public String getUserName() {
return null;
}
public boolean allProceduresAreCallable() {
return false;
}
public boolean allTablesAreSelectable() {
return true;
}
public boolean dataDefinitionCausesTransactionCommit() {
return false;
}
public boolean dataDefinitionIgnoredInTransactions() {
return false;
}
public boolean doesMaxRowSizeIncludeBlobs() {
return false;
}
public boolean deletesAreDetected(final int type) {
return false;
}
public boolean insertsAreDetected(final int type) {
return false;
}
public boolean isCatalogAtStart() {
return true;
}
public boolean locatorsUpdateCopy() {
return false;
}
public boolean nullPlusNonNullIsNull() {
return true;
}
public boolean nullsAreSortedAtEnd() {
return !nullsAreSortedAtStart();
}
public boolean nullsAreSortedAtStart() {
return true;
}
public boolean nullsAreSortedHigh() {
return true;
}
public boolean nullsAreSortedLow() {
return !nullsAreSortedHigh();
}
public boolean othersDeletesAreVisible(final int type) {
return false;
}
public boolean othersInsertsAreVisible(final int type) {
return false;
}
public boolean othersUpdatesAreVisible(final int type) {
return false;
}
public boolean ownDeletesAreVisible(final int type) {
return false;
}
public boolean ownInsertsAreVisible(final int type) {
return false;
}
public boolean ownUpdatesAreVisible(final int type) {
return false;
}
public boolean storesLowerCaseIdentifiers() {
return false;
}
public boolean storesLowerCaseQuotedIdentifiers() {
return false;
}
public boolean storesMixedCaseIdentifiers() {
return true;
}
public boolean storesMixedCaseQuotedIdentifiers() {
return false;
}
public boolean storesUpperCaseIdentifiers() {
return false;
}
public boolean storesUpperCaseQuotedIdentifiers() {
return false;
}
public boolean supportsAlterTableWithAddColumn() {
return false;
}
public boolean supportsAlterTableWithDropColumn() {
return false;
}
public boolean supportsANSI92EntryLevelSQL() {
return false;
}
public boolean supportsANSI92FullSQL() {
return false;
}
public boolean supportsANSI92IntermediateSQL() {
return false;
}
public boolean supportsBatchUpdates() {
return true;
}
public boolean supportsCatalogsInDataManipulation() {
return false;
}
public boolean supportsCatalogsInIndexDefinitions() {
return false;
}
public boolean supportsCatalogsInPrivilegeDefinitions() {
return false;
}
public boolean supportsCatalogsInProcedureCalls() {
return false;
}
public boolean supportsCatalogsInTableDefinitions() {
return false;
}
public boolean supportsColumnAliasing() {
return true;
}
public boolean supportsConvert() {
return false;
}
public boolean supportsConvert(final int fromType, final int toType) {
return false;
}
public boolean supportsCorrelatedSubqueries() {
return false;
}
public boolean supportsDataDefinitionAndDataManipulationTransactions() {
return true;
}
public boolean supportsDataManipulationTransactionsOnly() {
return false;
}
public boolean supportsDifferentTableCorrelationNames() {
return false;
}
public boolean supportsExpressionsInOrderBy() {
return true;
}
public boolean supportsMinimumSQLGrammar() {
return true;
}
public boolean supportsCoreSQLGrammar() {
return true;
}
public boolean supportsExtendedSQLGrammar() {
return false;
}
public boolean supportsLimitedOuterJoins() {
return true;
}
public boolean supportsFullOuterJoins() {
return false;
}
public boolean supportsGetGeneratedKeys() {
return false;
}
public boolean supportsGroupBy() {
return true;
}
public boolean supportsGroupByBeyondSelect() {
return false;
}
public boolean supportsGroupByUnrelated() {
return false;
}
public boolean supportsIntegrityEnhancementFacility() {
return false;
}
public boolean supportsLikeEscapeClause() {
return false;
}
public boolean supportsMixedCaseIdentifiers() {
return true;
}
public boolean supportsMixedCaseQuotedIdentifiers() {
return false;
}
public boolean supportsMultipleOpenResults() {
return false;
}
public boolean supportsMultipleResultSets() {
return false;
}
public boolean supportsMultipleTransactions() {
return true;
}
public boolean supportsNamedParameters() {
return true;
}
public boolean supportsNonNullableColumns() {
return true;
}
public boolean supportsOpenCursorsAcrossCommit() {
return false;
}
public boolean supportsOpenCursorsAcrossRollback() {
return false;
}
public boolean supportsOpenStatementsAcrossCommit() {
return false;
}
public boolean supportsOpenStatementsAcrossRollback() {
return false;
}
public boolean supportsOrderByUnrelated() {
return false;
}
public boolean supportsOuterJoins() {
return true;
}
public boolean supportsPositionedDelete() {
return false;
}
public boolean supportsPositionedUpdate() {
return false;
}
public boolean supportsResultSetConcurrency(final int t, final int c) {
return t == ResultSet.TYPE_FORWARD_ONLY
&& c == ResultSet.CONCUR_READ_ONLY;
}
public boolean supportsResultSetHoldability(final int h) {
return h == ResultSet.CLOSE_CURSORS_AT_COMMIT;
}
public boolean supportsResultSetType(final int t) {
return t == ResultSet.TYPE_FORWARD_ONLY;
}
public boolean supportsSavepoints() {
return false;
}
public boolean supportsSchemasInDataManipulation() {
return false;
}
public boolean supportsSchemasInIndexDefinitions() {
return false;
}
public boolean supportsSchemasInPrivilegeDefinitions() {
return false;
}
public boolean supportsSchemasInProcedureCalls() {
return false;
}
public boolean supportsSchemasInTableDefinitions() {
return false;
}
public boolean supportsSelectForUpdate() {
return false;
}
public boolean supportsStatementPooling() {
return false;
}
public boolean supportsStoredProcedures() {
return false;
}
public boolean supportsSubqueriesInComparisons() {
return false;
}
public boolean supportsSubqueriesInExists() {
return false;
}
public boolean supportsSubqueriesInIns() {
return false;
}
public boolean supportsSubqueriesInQuantifieds() {
return false;
}
public boolean supportsTableCorrelationNames() {
return false;
}
public boolean supportsTransactionIsolationLevel(final int level) {
return level == Connection.TRANSACTION_SERIALIZABLE;
}
public boolean supportsTransactions() {
return true;
}
public boolean supportsUnion() {
return true;
}
public boolean supportsUnionAll() {
return true;
}
public boolean updatesAreDetected(final int type) {
return false;
}
public boolean usesLocalFilePerTable() {
return false;
}
public boolean usesLocalFiles() {
return true;
}
public boolean isReadOnly() throws SQLException {
return this.conn.isReadOnly();
}
public boolean autoCommitFailureClosesAllResultSets() throws SQLException {
// TODO Auto-generated method stub
return false;
}
public ResultSet getClientInfoProperties() throws SQLException {
// TODO Auto-generated method stub
return null;
}
public ResultSet getFunctionColumns(final String arg0, final String arg1, final String arg2,
final String arg3) throws SQLException {
// TODO Auto-generated method stub
return null;
}
public ResultSet getFunctions(final String arg0, final String arg1, final String arg2)
throws SQLException {
// TODO Auto-generated method stub
return null;
}
public RowIdLifetime getRowIdLifetime() throws SQLException {
// TODO Auto-generated method stub
return null;
}
public ResultSet getSchemas(final String arg0, final String arg1) throws SQLException {
// TODO Auto-generated method stub
return null;
}
public boolean supportsStoredFunctionsUsingCallSyntax() throws SQLException {
// TODO Auto-generated method stub
return false;
}
public boolean isWrapperFor(final Class<?> iface) throws SQLException {
// TODO Auto-generated method stub
return false;
}
public <T> T unwrap(final Class<T> iface) throws SQLException {
// TODO Auto-generated method stub
return null;
}
public ResultSet getPseudoColumns(String catalog, String schemaPattern,
String tableNamePattern, String columnNamePattern)
throws SQLException {
return null;
}
public boolean generatedKeyAlwaysReturned() throws SQLException {
return false;
}
}