DelegatingDatabaseMetaData.java

  1. /*
  2.  * Licensed to the Apache Software Foundation (ASF) under one or more
  3.  * contributor license agreements.  See the NOTICE file distributed with
  4.  * this work for additional information regarding copyright ownership.
  5.  * The ASF licenses this file to You under the Apache License, Version 2.0
  6.  * (the "License"); you may not use this file except in compliance with
  7.  * the License.  You may obtain a copy of the License at
  8.  *
  9.  *      http://www.apache.org/licenses/LICENSE-2.0
  10.  *
  11.  * Unless required by applicable law or agreed to in writing, software
  12.  * distributed under the License is distributed on an "AS IS" BASIS,
  13.  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14.  * See the License for the specific language governing permissions and
  15.  * limitations under the License.
  16.  */
  17. package org.apache.commons.dbcp2;

  18. import java.sql.Connection;
  19. import java.sql.DatabaseMetaData;
  20. import java.sql.ResultSet;
  21. import java.sql.RowIdLifetime;
  22. import java.sql.SQLException;
  23. import java.util.Objects;
  24. import java.util.concurrent.Callable;

  25. /**
  26.  * <p>
  27.  * A base delegating implementation of {@link DatabaseMetaData}.
  28.  * </p>
  29.  * <p>
  30.  * Methods that create {@link ResultSet} objects are wrapped to create {@link DelegatingResultSet} objects and the remaining methods simply call the
  31.  * corresponding method on the "delegate" provided in the constructor.
  32.  * </p>
  33.  *
  34.  * @since 2.0
  35.  */
  36. public class DelegatingDatabaseMetaData implements DatabaseMetaData {

  37.     /** My delegate {@link DatabaseMetaData} */
  38.     private final DatabaseMetaData databaseMetaData;

  39.     /** The connection that created me. **/
  40.     private final DelegatingConnection<?> connection;

  41.     /**
  42.      * Constructs a new instance for the given delegating connection and database meta data.
  43.      *
  44.      * @param connection       the delegating connection
  45.      * @param databaseMetaData the database meta data
  46.      */
  47.     public DelegatingDatabaseMetaData(final DelegatingConnection<?> connection, final DatabaseMetaData databaseMetaData) {
  48.         this.connection = Objects.requireNonNull(connection, "connection");
  49.         this.databaseMetaData = Objects.requireNonNull(databaseMetaData, "databaseMetaData");
  50.     }

  51.     @Override
  52.     public boolean allProceduresAreCallable() throws SQLException {
  53.         return getB(databaseMetaData::allProceduresAreCallable);
  54.     }

  55.     @Override
  56.     public boolean allTablesAreSelectable() throws SQLException {
  57.         return getB(databaseMetaData::allTablesAreSelectable);
  58.     }

  59.     @Override
  60.     public boolean autoCommitFailureClosesAllResultSets() throws SQLException {
  61.         return getB(databaseMetaData::autoCommitFailureClosesAllResultSets);
  62.     }

  63.     @Override
  64.     public boolean dataDefinitionCausesTransactionCommit() throws SQLException {
  65.         return getB(databaseMetaData::dataDefinitionCausesTransactionCommit);
  66.     }

  67.     @Override
  68.     public boolean dataDefinitionIgnoredInTransactions() throws SQLException {
  69.         return getB(databaseMetaData::dataDefinitionIgnoredInTransactions);
  70.     }

  71.     @Override
  72.     public boolean deletesAreDetected(final int type) throws SQLException {
  73.         return getB(() -> databaseMetaData.deletesAreDetected(type));
  74.     }

  75.     @Override
  76.     public boolean doesMaxRowSizeIncludeBlobs() throws SQLException {
  77.         return getB(databaseMetaData::doesMaxRowSizeIncludeBlobs);
  78.     }

  79.     @Override
  80.     public boolean generatedKeyAlwaysReturned() throws SQLException {
  81.         connection.checkOpen();
  82.         return getB(() -> Jdbc41Bridge.generatedKeyAlwaysReturned(databaseMetaData));
  83.     }

  84.     private <T> T get(final Callable<T> s) throws SQLException {
  85.         return get(s, null);
  86.     }

  87.     private <T> T get(final Callable<T> s, final T defaultValue) throws SQLException {
  88.         try {
  89.             return s.call();
  90.         } catch (final Exception e) {
  91.             if (e instanceof SQLException) {
  92.                 handleException((SQLException) e);
  93.             }
  94.             return defaultValue;
  95.         }
  96.     }

  97.     @Override
  98.     public ResultSet getAttributes(final String catalog, final String schemaPattern, final String typeNamePattern, final String attributeNamePattern)
  99.             throws SQLException {
  100.         return getRS(() -> databaseMetaData.getAttributes(catalog, schemaPattern, typeNamePattern, attributeNamePattern));
  101.     }

  102.     private boolean getB(final Callable<Boolean> s) throws SQLException {
  103.         return get(s, false);
  104.     }

  105.     @Override
  106.     public ResultSet getBestRowIdentifier(final String catalog, final String schema, final String table, final int scope, final boolean nullable)
  107.             throws SQLException {
  108.         return getRS(() -> databaseMetaData.getBestRowIdentifier(catalog, schema, table, scope, nullable));
  109.     }

  110.     @Override
  111.     public ResultSet getCatalogs() throws SQLException {
  112.         return getRS(databaseMetaData::getCatalogs);
  113.     }

  114.     @Override
  115.     public String getCatalogSeparator() throws SQLException {
  116.         return get(databaseMetaData::getCatalogSeparator);
  117.     }

  118.     @Override
  119.     public String getCatalogTerm() throws SQLException {
  120.         return get(databaseMetaData::getCatalogTerm);
  121.     }

  122.     @Override
  123.     public ResultSet getClientInfoProperties() throws SQLException {
  124.         return getRS(databaseMetaData::getClientInfoProperties);
  125.     }

  126.     @Override
  127.     public ResultSet getColumnPrivileges(final String catalog, final String schema, final String table, final String columnNamePattern) throws SQLException {
  128.         return getRS(() -> databaseMetaData.getColumnPrivileges(catalog, schema, table, columnNamePattern));
  129.     }

  130.     @Override
  131.     public ResultSet getColumns(final String catalog, final String schemaPattern, final String tableNamePattern, final String columnNamePattern)
  132.             throws SQLException {
  133.         return getRS(() -> databaseMetaData.getColumns(catalog, schemaPattern, tableNamePattern, columnNamePattern));
  134.     }

  135.     @Override
  136.     public Connection getConnection() throws SQLException {
  137.         return connection;
  138.     }

  139.     @Override
  140.     public ResultSet getCrossReference(final String parentCatalog, final String parentSchema, final String parentTable, final String foreignCatalog,
  141.             final String foreignSchema, final String foreignTable) throws SQLException {
  142.         return getRS(() -> databaseMetaData.getCrossReference(parentCatalog, parentSchema, parentTable, foreignCatalog, foreignSchema, foreignTable));
  143.     }

  144.     @Override
  145.     public int getDatabaseMajorVersion() throws SQLException {
  146.         return getI(databaseMetaData::getDatabaseMajorVersion);
  147.     }

  148.     @Override
  149.     public int getDatabaseMinorVersion() throws SQLException {
  150.         return getI(databaseMetaData::getDatabaseMinorVersion);
  151.     }

  152.     @Override
  153.     public String getDatabaseProductName() throws SQLException {
  154.         return get(databaseMetaData::getDatabaseProductName);
  155.     }

  156.     @Override
  157.     public String getDatabaseProductVersion() throws SQLException {
  158.         return get(databaseMetaData::getDatabaseProductVersion);
  159.     }

  160.     @Override
  161.     public int getDefaultTransactionIsolation() throws SQLException {
  162.         return getI(databaseMetaData::getDefaultTransactionIsolation);
  163.     }

  164.     /**
  165.      * Gets the underlying database meta data.
  166.      *
  167.      * @return The underlying database meta data.
  168.      */
  169.     public DatabaseMetaData getDelegate() {
  170.         return databaseMetaData;
  171.     }

  172.     @Override
  173.     public int getDriverMajorVersion() {
  174.         return databaseMetaData.getDriverMajorVersion();
  175.     }

  176.     @Override
  177.     public int getDriverMinorVersion() {
  178.         return databaseMetaData.getDriverMinorVersion();
  179.     }

  180.     @Override
  181.     public String getDriverName() throws SQLException {
  182.         return get(databaseMetaData::getDriverName);
  183.     }

  184.     @Override
  185.     public String getDriverVersion() throws SQLException {
  186.         return get(databaseMetaData::getDriverVersion);
  187.     }

  188.     @Override
  189.     public ResultSet getExportedKeys(final String catalog, final String schema, final String table) throws SQLException {
  190.         return getRS(() -> databaseMetaData.getExportedKeys(catalog, schema, table));
  191.     }

  192.     @Override
  193.     public String getExtraNameCharacters() throws SQLException {
  194.         return get(databaseMetaData::getExtraNameCharacters);
  195.     }

  196.     @Override
  197.     public ResultSet getFunctionColumns(final String catalog, final String schemaPattern, final String functionNamePattern, final String columnNamePattern)
  198.             throws SQLException {
  199.         return getRS(() -> databaseMetaData.getFunctionColumns(catalog, schemaPattern, functionNamePattern, columnNamePattern));
  200.     }

  201.     @Override
  202.     public ResultSet getFunctions(final String catalog, final String schemaPattern, final String functionNamePattern) throws SQLException {
  203.         return getRS(() -> databaseMetaData.getFunctions(catalog, schemaPattern, functionNamePattern));
  204.     }

  205.     private int getI(final Callable<Integer> s) throws SQLException {
  206.         return get(s, 0);
  207.     }

  208.     @Override
  209.     public String getIdentifierQuoteString() throws SQLException {
  210.         return get(databaseMetaData::getIdentifierQuoteString);
  211.     }

  212.     @Override
  213.     public ResultSet getImportedKeys(final String catalog, final String schema, final String table) throws SQLException {
  214.         return getRS(() -> databaseMetaData.getImportedKeys(catalog, schema, table));
  215.     }

  216.     @Override
  217.     public ResultSet getIndexInfo(final String catalog, final String schema, final String table, final boolean unique, final boolean approximate)
  218.             throws SQLException {
  219.         return getRS(() -> databaseMetaData.getIndexInfo(catalog, schema, table, unique, approximate));
  220.     }

  221.     /**
  222.      * If my underlying {@link ResultSet} is not a {@code DelegatingResultSet}, returns it, otherwise recursively invokes this method on my delegate.
  223.      * <p>
  224.      * Hence this method will return the first delegate that is not a {@code DelegatingResultSet}, or {@code null} when no non-{@code DelegatingResultSet}
  225.      * delegate can be found by traversing this chain.
  226.      * </p>
  227.      * <p>
  228.      * This method is useful when you may have nested {@code DelegatingResultSet}s, and you want to make sure to obtain a "genuine" {@link ResultSet}.
  229.      * </p>
  230.      *
  231.      * @return the innermost database meta data.
  232.      */
  233.     public DatabaseMetaData getInnermostDelegate() {
  234.         DatabaseMetaData m = databaseMetaData;
  235.         while (m instanceof DelegatingDatabaseMetaData) {
  236.             m = ((DelegatingDatabaseMetaData) m).getDelegate();
  237.             if (this == m) {
  238.                 return null;
  239.             }
  240.         }
  241.         return m;
  242.     }

  243.     @Override
  244.     public int getJDBCMajorVersion() throws SQLException {
  245.         return getI(databaseMetaData::getJDBCMajorVersion);
  246.     }

  247.     @Override
  248.     public int getJDBCMinorVersion() throws SQLException {
  249.         return getI(databaseMetaData::getJDBCMinorVersion);
  250.     }

  251.     private long getL(final Callable<Long> s) throws SQLException {
  252.         return get(s, 0L);
  253.     }

  254.     @Override
  255.     public int getMaxBinaryLiteralLength() throws SQLException {
  256.         return getI(databaseMetaData::getMaxBinaryLiteralLength);
  257.     }

  258.     @Override
  259.     public int getMaxCatalogNameLength() throws SQLException {
  260.         return getI(databaseMetaData::getMaxCatalogNameLength);
  261.     }

  262.     @Override
  263.     public int getMaxCharLiteralLength() throws SQLException {
  264.         return getI(databaseMetaData::getMaxCharLiteralLength);
  265.     }

  266.     @Override
  267.     public int getMaxColumnNameLength() throws SQLException {
  268.         return getI(databaseMetaData::getMaxColumnNameLength);
  269.     }

  270.     @Override
  271.     public int getMaxColumnsInGroupBy() throws SQLException {
  272.         return getI(databaseMetaData::getMaxColumnsInGroupBy);
  273.     }

  274.     @Override
  275.     public int getMaxColumnsInIndex() throws SQLException {
  276.         return getI(databaseMetaData::getMaxColumnsInIndex);
  277.     }

  278.     @Override
  279.     public int getMaxColumnsInOrderBy() throws SQLException {
  280.         return getI(databaseMetaData::getMaxColumnsInOrderBy);
  281.     }

  282.     @Override
  283.     public int getMaxColumnsInSelect() throws SQLException {
  284.         return getI(databaseMetaData::getMaxColumnsInSelect);
  285.     }

  286.     @Override
  287.     public int getMaxColumnsInTable() throws SQLException {
  288.         return getI(databaseMetaData::getMaxColumnsInTable);
  289.     }

  290.     @Override
  291.     public int getMaxConnections() throws SQLException {
  292.         return getI(databaseMetaData::getMaxConnections);
  293.     }

  294.     @Override
  295.     public int getMaxCursorNameLength() throws SQLException {
  296.         return getI(databaseMetaData::getMaxCursorNameLength);
  297.     }

  298.     @Override
  299.     public int getMaxIndexLength() throws SQLException {
  300.         return getI(databaseMetaData::getMaxIndexLength);
  301.     }

  302.     /**
  303.      * @since 2.5.0
  304.      */
  305.     @Override
  306.     public long getMaxLogicalLobSize() throws SQLException {
  307.         return getL(databaseMetaData::getMaxLogicalLobSize);
  308.     }

  309.     @Override
  310.     public int getMaxProcedureNameLength() throws SQLException {
  311.         return getI(databaseMetaData::getMaxProcedureNameLength);
  312.     }

  313.     @Override
  314.     public int getMaxRowSize() throws SQLException {
  315.         return getI(databaseMetaData::getMaxRowSize);
  316.     }

  317.     @Override
  318.     public int getMaxSchemaNameLength() throws SQLException {
  319.         return getI(databaseMetaData::getMaxSchemaNameLength);
  320.     }

  321.     @Override
  322.     public int getMaxStatementLength() throws SQLException {
  323.         return getI(databaseMetaData::getMaxStatementLength);
  324.     }

  325.     @Override
  326.     public int getMaxStatements() throws SQLException {
  327.         return getI(databaseMetaData::getMaxStatements);
  328.     }

  329.     @Override
  330.     public int getMaxTableNameLength() throws SQLException {
  331.         return getI(databaseMetaData::getMaxTableNameLength);
  332.     }

  333.     @Override
  334.     public int getMaxTablesInSelect() throws SQLException {
  335.         return getI(databaseMetaData::getMaxTablesInSelect);
  336.     }

  337.     @Override
  338.     public int getMaxUserNameLength() throws SQLException {
  339.         return getI(databaseMetaData::getMaxUserNameLength);
  340.     }

  341.     @Override
  342.     public String getNumericFunctions() throws SQLException {
  343.         return get(databaseMetaData::getNumericFunctions);
  344.     }

  345.     @Override
  346.     public ResultSet getPrimaryKeys(final String catalog, final String schema, final String table) throws SQLException {
  347.         return getRS(() -> databaseMetaData.getPrimaryKeys(catalog, schema, table));
  348.     }

  349.     @Override
  350.     public ResultSet getProcedureColumns(final String catalog, final String schemaPattern, final String procedureNamePattern, final String columnNamePattern)
  351.             throws SQLException {
  352.         return getRS(() -> databaseMetaData.getProcedureColumns(catalog, schemaPattern, procedureNamePattern, columnNamePattern));
  353.     }

  354.     @Override
  355.     public ResultSet getProcedures(final String catalog, final String schemaPattern, final String procedureNamePattern) throws SQLException {
  356.         return getRS(() -> databaseMetaData.getProcedures(catalog, schemaPattern, procedureNamePattern));
  357.     }

  358.     @Override
  359.     public String getProcedureTerm() throws SQLException {
  360.         return get(databaseMetaData::getProcedureTerm);
  361.     }

  362.     @Override
  363.     public ResultSet getPseudoColumns(final String catalog, final String schemaPattern, final String tableNamePattern, final String columnNamePattern)
  364.             throws SQLException {
  365.         return getRS(() -> Jdbc41Bridge.getPseudoColumns(databaseMetaData, catalog, schemaPattern, tableNamePattern, columnNamePattern));
  366.     }

  367.     @Override
  368.     public int getResultSetHoldability() throws SQLException {
  369.         return getI(databaseMetaData::getResultSetHoldability);
  370.     }

  371.     @Override
  372.     public RowIdLifetime getRowIdLifetime() throws SQLException {
  373.         return get(databaseMetaData::getRowIdLifetime);
  374.     }

  375.     @SuppressWarnings("resource")
  376.     private ResultSet getRS(final Callable<ResultSet> s) throws SQLException {
  377.         connection.checkOpen();
  378.         return DelegatingResultSet.wrapResultSet(connection, get(s));
  379.     }

  380.     @Override
  381.     public ResultSet getSchemas() throws SQLException {
  382.         return getRS(databaseMetaData::getSchemas);
  383.     }

  384.     @Override
  385.     public ResultSet getSchemas(final String catalog, final String schemaPattern) throws SQLException {
  386.         return getRS(() -> databaseMetaData.getSchemas(catalog, schemaPattern));
  387.     }

  388.     @Override
  389.     public String getSchemaTerm() throws SQLException {
  390.         return get(databaseMetaData::getSchemaTerm);
  391.     }

  392.     @Override
  393.     public String getSearchStringEscape() throws SQLException {
  394.         return get(databaseMetaData::getSearchStringEscape);
  395.     }

  396.     @Override
  397.     public String getSQLKeywords() throws SQLException {
  398.         return get(databaseMetaData::getSQLKeywords);
  399.     }

  400.     @Override
  401.     public int getSQLStateType() throws SQLException {
  402.         return getI(databaseMetaData::getSQLStateType);
  403.     }

  404.     @Override
  405.     public String getStringFunctions() throws SQLException {
  406.         return get(databaseMetaData::getStringFunctions);
  407.     }

  408.     @Override
  409.     public ResultSet getSuperTables(final String catalog, final String schemaPattern, final String tableNamePattern) throws SQLException {
  410.         return getRS(() -> databaseMetaData.getSuperTables(catalog, schemaPattern, tableNamePattern));
  411.     }

  412.     @Override
  413.     public ResultSet getSuperTypes(final String catalog, final String schemaPattern, final String typeNamePattern) throws SQLException {
  414.         return getRS(() -> databaseMetaData.getSuperTypes(catalog, schemaPattern, typeNamePattern));
  415.     }

  416.     @Override
  417.     public String getSystemFunctions() throws SQLException {
  418.         return get(databaseMetaData::getSystemFunctions);
  419.     }

  420.     @Override
  421.     public ResultSet getTablePrivileges(final String catalog, final String schemaPattern, final String tableNamePattern) throws SQLException {
  422.         return getRS(() -> databaseMetaData.getTablePrivileges(catalog, schemaPattern, tableNamePattern));
  423.     }

  424.     @Override
  425.     public ResultSet getTables(final String catalog, final String schemaPattern, final String tableNamePattern, final String[] types) throws SQLException {
  426.         return getRS(() -> databaseMetaData.getTables(catalog, schemaPattern, tableNamePattern, types));
  427.     }

  428.     @Override
  429.     public ResultSet getTableTypes() throws SQLException {
  430.         return getRS(databaseMetaData::getTableTypes);
  431.     }

  432.     @Override
  433.     public String getTimeDateFunctions() throws SQLException {
  434.         return get(databaseMetaData::getTimeDateFunctions);
  435.     }

  436.     @Override
  437.     public ResultSet getTypeInfo() throws SQLException {
  438.         return getRS(databaseMetaData::getTypeInfo);
  439.     }

  440.     @Override
  441.     public ResultSet getUDTs(final String catalog, final String schemaPattern, final String typeNamePattern, final int[] types) throws SQLException {
  442.         return getRS(() -> databaseMetaData.getUDTs(catalog, schemaPattern, typeNamePattern, types));
  443.     }

  444.     @Override
  445.     public String getURL() throws SQLException {
  446.         return get(databaseMetaData::getURL);
  447.     }

  448.     @Override
  449.     public String getUserName() throws SQLException {
  450.         return get(databaseMetaData::getUserName);
  451.     }

  452.     @Override
  453.     public ResultSet getVersionColumns(final String catalog, final String schema, final String table) throws SQLException {
  454.         return getRS(() -> databaseMetaData.getVersionColumns(catalog, schema, table));
  455.     }

  456.     /**
  457.      * Delegates to the connection's {@link DelegatingConnection#handleException(SQLException)}.
  458.      *
  459.      * @param e the exception to throw or delegate.
  460.      * @throws SQLException the exception to throw.
  461.      */
  462.     protected void handleException(final SQLException e) throws SQLException {
  463.         if (connection == null) {
  464.             throw e;
  465.         }
  466.         connection.handleException(e);
  467.     }

  468.     @Override
  469.     public boolean insertsAreDetected(final int type) throws SQLException {
  470.         return getB(() -> databaseMetaData.insertsAreDetected(type));
  471.     }

  472.     @Override
  473.     public boolean isCatalogAtStart() throws SQLException {
  474.         return getB(databaseMetaData::isCatalogAtStart);
  475.     }

  476.     @Override
  477.     public boolean isReadOnly() throws SQLException {
  478.         return getB(databaseMetaData::isReadOnly);
  479.     }

  480.     @Override
  481.     public boolean isWrapperFor(final Class<?> iface) throws SQLException {
  482.         if (iface.isAssignableFrom(getClass())) {
  483.             return true;
  484.         }
  485.         if (iface.isAssignableFrom(databaseMetaData.getClass())) {
  486.             return true;
  487.         }
  488.         return databaseMetaData.isWrapperFor(iface);
  489.     }

  490.     @Override
  491.     public boolean locatorsUpdateCopy() throws SQLException {
  492.         return getB(databaseMetaData::locatorsUpdateCopy);
  493.     }

  494.     @Override
  495.     public boolean nullPlusNonNullIsNull() throws SQLException {
  496.         return getB(databaseMetaData::nullPlusNonNullIsNull);
  497.     }

  498.     @Override
  499.     public boolean nullsAreSortedAtEnd() throws SQLException {
  500.         return getB(databaseMetaData::nullsAreSortedAtEnd);
  501.     }

  502.     @Override
  503.     public boolean nullsAreSortedAtStart() throws SQLException {
  504.         return getB(databaseMetaData::nullsAreSortedAtStart);
  505.     }

  506.     @Override
  507.     public boolean nullsAreSortedHigh() throws SQLException {
  508.         return getB(databaseMetaData::nullsAreSortedHigh);
  509.     }

  510.     @Override
  511.     public boolean nullsAreSortedLow() throws SQLException {
  512.         return getB(databaseMetaData::nullsAreSortedLow);
  513.     }

  514.     @Override
  515.     public boolean othersDeletesAreVisible(final int type) throws SQLException {
  516.         return getB(() -> databaseMetaData.othersDeletesAreVisible(type));
  517.     }

  518.     @Override
  519.     public boolean othersInsertsAreVisible(final int type) throws SQLException {
  520.         return getB(() -> databaseMetaData.othersInsertsAreVisible(type));
  521.     }

  522.     @Override
  523.     public boolean othersUpdatesAreVisible(final int type) throws SQLException {
  524.         return getB(() -> databaseMetaData.othersUpdatesAreVisible(type));
  525.     }

  526.     @Override
  527.     public boolean ownDeletesAreVisible(final int type) throws SQLException {
  528.         return getB(() -> databaseMetaData.ownDeletesAreVisible(type));
  529.     }

  530.     @Override
  531.     public boolean ownInsertsAreVisible(final int type) throws SQLException {
  532.         return getB(() -> databaseMetaData.ownInsertsAreVisible(type));
  533.     }

  534.     @Override
  535.     public boolean ownUpdatesAreVisible(final int type) throws SQLException {
  536.         return getB(() -> databaseMetaData.ownUpdatesAreVisible(type));
  537.     }

  538.     @Override
  539.     public boolean storesLowerCaseIdentifiers() throws SQLException {
  540.         return getB(databaseMetaData::storesLowerCaseIdentifiers);
  541.     }

  542.     @Override
  543.     public boolean storesLowerCaseQuotedIdentifiers() throws SQLException {
  544.         return getB(databaseMetaData::storesLowerCaseQuotedIdentifiers);
  545.     }

  546.     @Override
  547.     public boolean storesMixedCaseIdentifiers() throws SQLException {
  548.         return getB(databaseMetaData::storesMixedCaseIdentifiers);
  549.     }

  550.     @Override
  551.     public boolean storesMixedCaseQuotedIdentifiers() throws SQLException {
  552.         return getB(databaseMetaData::storesMixedCaseQuotedIdentifiers);
  553.     }

  554.     @Override
  555.     public boolean storesUpperCaseIdentifiers() throws SQLException {
  556.         return getB(databaseMetaData::storesUpperCaseIdentifiers);

  557.     }

  558.     @Override
  559.     public boolean storesUpperCaseQuotedIdentifiers() throws SQLException {
  560.         return getB(databaseMetaData::storesUpperCaseQuotedIdentifiers);
  561.     }

  562.     @Override
  563.     public boolean supportsAlterTableWithAddColumn() throws SQLException {
  564.         return getB(databaseMetaData::supportsAlterTableWithAddColumn);
  565.     }

  566.     @Override
  567.     public boolean supportsAlterTableWithDropColumn() throws SQLException {
  568.         return getB(databaseMetaData::supportsAlterTableWithDropColumn);
  569.     }

  570.     @Override
  571.     public boolean supportsANSI92EntryLevelSQL() throws SQLException {
  572.         return getB(databaseMetaData::supportsANSI92EntryLevelSQL);
  573.     }

  574.     @Override
  575.     public boolean supportsANSI92FullSQL() throws SQLException {
  576.         return getB(databaseMetaData::supportsANSI92FullSQL);
  577.     }

  578.     @Override
  579.     public boolean supportsANSI92IntermediateSQL() throws SQLException {
  580.         return getB(databaseMetaData::supportsANSI92IntermediateSQL);
  581.     }

  582.     @Override
  583.     public boolean supportsBatchUpdates() throws SQLException {
  584.         return getB(databaseMetaData::supportsBatchUpdates);
  585.     }

  586.     @Override
  587.     public boolean supportsCatalogsInDataManipulation() throws SQLException {
  588.         return getB(databaseMetaData::supportsCatalogsInDataManipulation);
  589.     }

  590.     @Override
  591.     public boolean supportsCatalogsInIndexDefinitions() throws SQLException {
  592.         return getB(databaseMetaData::supportsCatalogsInIndexDefinitions);
  593.     }

  594.     @Override
  595.     public boolean supportsCatalogsInPrivilegeDefinitions() throws SQLException {
  596.         return getB(databaseMetaData::supportsCatalogsInPrivilegeDefinitions);
  597.     }

  598.     @Override
  599.     public boolean supportsCatalogsInProcedureCalls() throws SQLException {
  600.         return getB(databaseMetaData::supportsCatalogsInProcedureCalls);
  601.     }

  602.     @Override
  603.     public boolean supportsCatalogsInTableDefinitions() throws SQLException {
  604.         return getB(databaseMetaData::supportsCatalogsInTableDefinitions);
  605.     }

  606.     @Override
  607.     public boolean supportsColumnAliasing() throws SQLException {
  608.         return getB(databaseMetaData::supportsColumnAliasing);
  609.     }

  610.     @Override
  611.     public boolean supportsConvert() throws SQLException {
  612.         return getB(databaseMetaData::supportsConvert);
  613.     }

  614.     @Override
  615.     public boolean supportsConvert(final int fromType, final int toType) throws SQLException {
  616.         return getB(() -> databaseMetaData.supportsConvert(fromType, toType));
  617.     }

  618.     @Override
  619.     public boolean supportsCoreSQLGrammar() throws SQLException {
  620.         return getB(databaseMetaData::supportsCoreSQLGrammar);
  621.     }

  622.     @Override
  623.     public boolean supportsCorrelatedSubqueries() throws SQLException {
  624.         return getB(databaseMetaData::supportsCorrelatedSubqueries);
  625.     }

  626.     @Override
  627.     public boolean supportsDataDefinitionAndDataManipulationTransactions() throws SQLException {
  628.         return getB(databaseMetaData::supportsDataDefinitionAndDataManipulationTransactions);
  629.     }

  630.     @Override
  631.     public boolean supportsDataManipulationTransactionsOnly() throws SQLException {
  632.         return getB(databaseMetaData::supportsDataManipulationTransactionsOnly);
  633.     }

  634.     @Override
  635.     public boolean supportsDifferentTableCorrelationNames() throws SQLException {
  636.         return getB(databaseMetaData::supportsDifferentTableCorrelationNames);
  637.     }

  638.     @Override
  639.     public boolean supportsExpressionsInOrderBy() throws SQLException {
  640.         return getB(databaseMetaData::supportsExpressionsInOrderBy);
  641.     }

  642.     @Override
  643.     public boolean supportsExtendedSQLGrammar() throws SQLException {
  644.         return getB(databaseMetaData::supportsExtendedSQLGrammar);
  645.     }

  646.     @Override
  647.     public boolean supportsFullOuterJoins() throws SQLException {
  648.         return getB(databaseMetaData::supportsFullOuterJoins);
  649.     }

  650.     @Override
  651.     public boolean supportsGetGeneratedKeys() throws SQLException {
  652.         return getB(databaseMetaData::supportsGetGeneratedKeys);
  653.     }

  654.     @Override
  655.     public boolean supportsGroupBy() throws SQLException {
  656.         return getB(databaseMetaData::supportsGroupBy);
  657.     }

  658.     @Override
  659.     public boolean supportsGroupByBeyondSelect() throws SQLException {
  660.         return getB(databaseMetaData::supportsGroupByBeyondSelect);
  661.     }

  662.     @Override
  663.     public boolean supportsGroupByUnrelated() throws SQLException {
  664.         return getB(databaseMetaData::supportsGroupByUnrelated);
  665.     }

  666.     @Override
  667.     public boolean supportsIntegrityEnhancementFacility() throws SQLException {
  668.         return getB(databaseMetaData::supportsIntegrityEnhancementFacility);
  669.     }

  670.     @Override
  671.     public boolean supportsLikeEscapeClause() throws SQLException {
  672.         return getB(databaseMetaData::supportsLikeEscapeClause);
  673.     }

  674.     @Override
  675.     public boolean supportsLimitedOuterJoins() throws SQLException {
  676.         return getB(databaseMetaData::supportsLimitedOuterJoins);
  677.     }

  678.     @Override
  679.     public boolean supportsMinimumSQLGrammar() throws SQLException {
  680.         return getB(databaseMetaData::supportsMinimumSQLGrammar);
  681.     }

  682.     @Override
  683.     public boolean supportsMixedCaseIdentifiers() throws SQLException {
  684.         return getB(databaseMetaData::supportsMixedCaseIdentifiers);
  685.     }

  686.     @Override
  687.     public boolean supportsMixedCaseQuotedIdentifiers() throws SQLException {
  688.         return getB(databaseMetaData::supportsMixedCaseQuotedIdentifiers);
  689.     }

  690.     @Override
  691.     public boolean supportsMultipleOpenResults() throws SQLException {
  692.         return getB(databaseMetaData::supportsMultipleOpenResults);
  693.     }

  694.     @Override
  695.     public boolean supportsMultipleResultSets() throws SQLException {
  696.         return getB(databaseMetaData::supportsMultipleResultSets);
  697.     }

  698.     @Override
  699.     public boolean supportsMultipleTransactions() throws SQLException {
  700.         return getB(databaseMetaData::supportsMultipleTransactions);
  701.     }

  702.     @Override
  703.     public boolean supportsNamedParameters() throws SQLException {
  704.         return getB(databaseMetaData::supportsNamedParameters);
  705.     }

  706.     @Override
  707.     public boolean supportsNonNullableColumns() throws SQLException {
  708.         return getB(databaseMetaData::supportsNonNullableColumns);
  709.     }

  710.     @Override
  711.     public boolean supportsOpenCursorsAcrossCommit() throws SQLException {
  712.         return getB(databaseMetaData::supportsOpenCursorsAcrossCommit);
  713.     }

  714.     @Override
  715.     public boolean supportsOpenCursorsAcrossRollback() throws SQLException {
  716.         return getB(databaseMetaData::supportsOpenCursorsAcrossRollback);
  717.     }

  718.     @Override
  719.     public boolean supportsOpenStatementsAcrossCommit() throws SQLException {
  720.         return getB(databaseMetaData::supportsOpenStatementsAcrossCommit);
  721.     }

  722.     @Override
  723.     public boolean supportsOpenStatementsAcrossRollback() throws SQLException {
  724.         return getB(databaseMetaData::supportsOpenStatementsAcrossRollback);
  725.     }

  726.     @Override
  727.     public boolean supportsOrderByUnrelated() throws SQLException {
  728.         return getB(databaseMetaData::supportsOrderByUnrelated);
  729.     }

  730.     @Override
  731.     public boolean supportsOuterJoins() throws SQLException {
  732.         return getB(databaseMetaData::supportsOuterJoins);
  733.     }

  734.     @Override
  735.     public boolean supportsPositionedDelete() throws SQLException {
  736.         return getB(databaseMetaData::supportsPositionedDelete);
  737.     }

  738.     @Override
  739.     public boolean supportsPositionedUpdate() throws SQLException {
  740.         return getB(databaseMetaData::supportsPositionedUpdate);
  741.     }

  742.     /**
  743.      * @since 2.5.0
  744.      */
  745.     @Override
  746.     public boolean supportsRefCursors() throws SQLException {
  747.         return getB(databaseMetaData::supportsRefCursors);
  748.     }

  749.     @Override
  750.     public boolean supportsResultSetConcurrency(final int type, final int concurrency) throws SQLException {
  751.         return getB(() -> databaseMetaData.supportsResultSetConcurrency(type, concurrency));
  752.     }

  753.     @Override
  754.     public boolean supportsResultSetHoldability(final int holdability) throws SQLException {
  755.         return getB(() -> databaseMetaData.supportsResultSetHoldability(holdability));
  756.     }

  757.     @Override
  758.     public boolean supportsResultSetType(final int type) throws SQLException {
  759.         return getB(() -> databaseMetaData.supportsResultSetType(type));
  760.     }

  761.     @Override
  762.     public boolean supportsSavepoints() throws SQLException {
  763.         return getB(databaseMetaData::supportsSavepoints);
  764.     }

  765.     @Override
  766.     public boolean supportsSchemasInDataManipulation() throws SQLException {
  767.         return getB(databaseMetaData::supportsSchemasInDataManipulation);
  768.     }

  769.     @Override
  770.     public boolean supportsSchemasInIndexDefinitions() throws SQLException {
  771.         return getB(databaseMetaData::supportsSchemasInIndexDefinitions);
  772.     }

  773.     @Override
  774.     public boolean supportsSchemasInPrivilegeDefinitions() throws SQLException {
  775.         return getB(databaseMetaData::supportsSchemasInPrivilegeDefinitions);
  776.     }

  777.     @Override
  778.     public boolean supportsSchemasInProcedureCalls() throws SQLException {
  779.         return getB(databaseMetaData::supportsSchemasInProcedureCalls);
  780.     }

  781.     @Override
  782.     public boolean supportsSchemasInTableDefinitions() throws SQLException {
  783.         return getB(databaseMetaData::supportsSchemasInTableDefinitions);
  784.     }

  785.     @Override
  786.     public boolean supportsSelectForUpdate() throws SQLException {
  787.         return getB(databaseMetaData::supportsSelectForUpdate);
  788.     }

  789.     @Override
  790.     public boolean supportsStatementPooling() throws SQLException {
  791.         return getB(databaseMetaData::supportsStatementPooling);
  792.     }

  793.     @Override
  794.     public boolean supportsStoredFunctionsUsingCallSyntax() throws SQLException {
  795.         return getB(databaseMetaData::supportsStoredFunctionsUsingCallSyntax);
  796.     }

  797.     @Override
  798.     public boolean supportsStoredProcedures() throws SQLException {
  799.         return getB(databaseMetaData::supportsStoredProcedures);
  800.     }

  801.     @Override
  802.     public boolean supportsSubqueriesInComparisons() throws SQLException {
  803.         return getB(databaseMetaData::supportsSubqueriesInComparisons);
  804.     }

  805.     @Override
  806.     public boolean supportsSubqueriesInExists() throws SQLException {
  807.         return getB(databaseMetaData::supportsSubqueriesInExists);
  808.     }

  809.     @Override
  810.     public boolean supportsSubqueriesInIns() throws SQLException {
  811.         return getB(databaseMetaData::supportsSubqueriesInIns);
  812.     }

  813.     @Override
  814.     public boolean supportsSubqueriesInQuantifieds() throws SQLException {
  815.         return getB(databaseMetaData::supportsSubqueriesInQuantifieds);
  816.     }

  817.     @Override
  818.     public boolean supportsTableCorrelationNames() throws SQLException {
  819.         return getB(databaseMetaData::supportsTableCorrelationNames);
  820.     }

  821.     @Override
  822.     public boolean supportsTransactionIsolationLevel(final int level) throws SQLException {
  823.         return getB(() -> databaseMetaData.supportsTransactionIsolationLevel(level));
  824.     }

  825.     @Override
  826.     public boolean supportsTransactions() throws SQLException {
  827.         return getB(databaseMetaData::supportsTransactions);
  828.     }

  829.     @Override
  830.     public boolean supportsUnion() throws SQLException {
  831.         return getB(databaseMetaData::supportsUnion);
  832.     }

  833.     @Override
  834.     public boolean supportsUnionAll() throws SQLException {
  835.         return getB(databaseMetaData::supportsUnionAll);
  836.     }

  837.     @Override
  838.     public <T> T unwrap(final Class<T> iface) throws SQLException {
  839.         if (iface.isAssignableFrom(getClass())) {
  840.             return iface.cast(this);
  841.         }
  842.         if (iface.isAssignableFrom(databaseMetaData.getClass())) {
  843.             return iface.cast(databaseMetaData);
  844.         }
  845.         return databaseMetaData.unwrap(iface);
  846.     }

  847.     @Override
  848.     public boolean updatesAreDetected(final int type) throws SQLException {
  849.         return getB(() -> databaseMetaData.updatesAreDetected(type));
  850.     }

  851.     @Override
  852.     public boolean usesLocalFilePerTable() throws SQLException {
  853.         return getB(databaseMetaData::usesLocalFilePerTable);
  854.     }

  855.     @Override
  856.     public boolean usesLocalFiles() throws SQLException {
  857.         return getB(databaseMetaData::usesLocalFiles);
  858.     }
  859. }