content: /*
   * Copyright 1999-2018 Alibaba Group Holding Ltd.
   *
   * 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://www.apache.org/licenses/LICENSE-2.0
   *
   * Unless required by applicable law or agreed to in writing, software
   * distributed under the License 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.alibaba.druid.proxy.jdbc;
  
  import com.alibaba.druid.filter.FilterChainImpl;
  
  import java.sql.ResultSetMetaData;
  import java.sql.SQLException;
  
  /**
   * @author kiki
   */
  public class ResultSetMetaDataProxyImpl extends WrapperProxyImpl implements ResultSetMetaDataProxy {
      private final ResultSetMetaData metaData;
      private final ResultSetProxy resultSet;
  
      private FilterChainImpl filterChain;
  
      public ResultSetMetaDataProxyImpl(ResultSetMetaData metaData, long id, ResultSetProxy resultSet) {
          super(metaData, id);
          this.metaData = metaData;
          this.resultSet = resultSet;
      }
  
      @Override
      public int getColumnCount() throws SQLException {
          FilterChainImpl chain = createChain();
          int value = chain.resultSetMetaData_getColumnCount(this);
          recycleFilterChain(chain);
          return value;
      }
  
      @Override
      public boolean isAutoIncrement(int column) throws SQLException {
          FilterChainImpl chain = createChain();
          boolean value = chain.resultSetMetaData_isAutoIncrement(this, column);
          recycleFilterChain(chain);
          return value;
      }
  
      @Override
      public boolean isCaseSensitive(int column) throws SQLException {
          FilterChainImpl chain = createChain();
          boolean value = chain.resultSetMetaData_isCaseSensitive(this, column);
          recycleFilterChain(chain);
          return value;
      }
  
      @Override
      public boolean isSearchable(int column) throws SQLException {
          FilterChainImpl chain = createChain();
          boolean value = chain.resultSetMetaData_isSearchable(this, column);
          recycleFilterChain(chain);
          return value;
      }
  
      @Override
      public boolean isCurrency(int column) throws SQLException {
          FilterChainImpl chain = createChain();
          boolean value = chain.resultSetMetaData_isCurrency(this, column);
          recycleFilterChain(chain);
          return value;
      }
  
      @Override
      public int isNullable(int column) throws SQLException {
          FilterChainImpl chain = createChain();
          int value = chain.resultSetMetaData_isNullable(this, column);
          recycleFilterChain(chain);
          return value;
      }
  
      @Override
      public boolean isSigned(int column) throws SQLException {
          FilterChainImpl chain = createChain();
          boolean value = chain.resultSetMetaData_isSigned(this, column);
          recycleFilterChain(chain);
          return value;
      }
  
      @Override
      public int getColumnDisplaySize(int column) throws SQLException {
          FilterChainImpl chain = createChain();
          int value = chain.resultSetMetaData_getColumnDisplaySize(this, column);
          recycleFilterChain(chain);
          return value;
      }
  
      @Override
      public String getColumnLabel(int column) throws SQLException {
          FilterChainImpl chain = createChain();
          String value = chain.resultSetMetaData_getColumnLabel(this, column);
          recycleFilterChain(chain);
          return value;
      }
  
      @Override
      public String getColumnName(int column) throws SQLException {
          FilterChainImpl chain = createChain();
          String value = chain.resultSetMetaData_getColumnName(this, column);
          recycleFilterChain(chain);
          return value;
      }
  
      @Override
      public String getSchemaName(int column) throws SQLException {
          FilterChainImpl chain = createChain();
          String value = chain.resultSetMetaData_getSchemaName(this, column);
          recycleFilterChain(chain);
          return value;
      }
  
      @Override
      public int getPrecision(int column) throws SQLException {
          FilterChainImpl chain = createChain();
          int value = chain.resultSetMetaData_getPrecision(this, column);
          recycleFilterChain(chain);
          return value;
      }
  
      @Override
      public int getScale(int column) throws SQLException {
          FilterChainImpl chain = createChain();
          int value = chain.resultSetMetaData_getScale(this, column);
          recycleFilterChain(chain);
          return value;
      }
  
      @Override
      public String getTableName(int column) throws SQLException {
          FilterChainImpl chain = createChain();
          String value = chain.resultSetMetaData_getTableName(this, column);
          recycleFilterChain(chain);
          return value;
      }
  
      @Override
      public String getCatalogName(int column) throws SQLException {
          FilterChainImpl chain = createChain();
          String value = chain.resultSetMetaData_getCatalogName(this, column);
          recycleFilterChain(chain);
          return value;
      }
  
      @Override
      public int getColumnType(int column) throws SQLException {
          FilterChainImpl chain = createChain();
          int value = chain.resultSetMetaData_getColumnType(this, column);
          recycleFilterChain(chain);
          return value;
      }
  
      @Override
      public String getColumnTypeName(int column) throws SQLException {
          FilterChainImpl chain = createChain();
          String value = chain.resultSetMetaData_getColumnTypeName(this, column);
          recycleFilterChain(chain);
          return value;
      }
  
      @Override
      public boolean isReadOnly(int column) throws SQLException {
          FilterChainImpl chain = createChain();
          boolean value = chain.resultSetMetaData_isReadOnly(this, column);
          recycleFilterChain(chain);
          return value;
      }
  
      @Override
      public boolean isWritable(int column) throws SQLException {
          FilterChainImpl chain = createChain();
          boolean value = chain.resultSetMetaData_isWritable(this, column);
          recycleFilterChain(chain);
          return value;
      }
  
      @Override
      public boolean isDefinitelyWritable(int column) throws SQLException {
          FilterChainImpl chain = createChain();
          boolean value = chain.resultSetMetaData_isDefinitelyWritable(this, column);
          recycleFilterChain(chain);
          return value;
      }
  
      @Override
      public String getColumnClassName(int column) throws SQLException {
          FilterChainImpl chain = createChain();
          String value = chain.resultSetMetaData_getColumnClassName(this, column);
          recycleFilterChain(chain);
          return value;
      }
  
      public FilterChainImpl createChain() {
          FilterChainImpl chain = this.filterChain;
          if (chain == null) {
              chain = new FilterChainImpl(this.resultSet.getStatementProxy().getConnectionProxy().getDirectDataSource());
          } else {
              this.filterChain = null;
          }
  
          return chain;
      }
  
      public void recycleFilterChain(FilterChainImpl chain) {
          chain.reset();
          this.filterChain = chain;
      }
  
      @Override
      public ResultSetProxy getResultSetProxy() {
          return this.resultSet;
      }
  
      @Override
      public ResultSetMetaData getResultSetMetaDataRaw() {
          return this.metaData;
      }
  
  }
  