/*
_____       _    _    Corso   Italia,  178
(_|__   .  (_   |_|_  56125           Pisa
(_|_) |)|(()_)()| |   tel.  +39  050 46380
  |   |               picosoft@picosoft.it

 Copyright (C) Picosoft s.r.l. 1995-2002

 This program is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation; either version 2, or (at your option)
 any later version.

 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.

 You should have received a copy of the GNU General Public License
 along with this program; if not, write to the Free Software
 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.

*/
package IT.picosoft.jdbc;

import java.sql.*;
import java.util.Hashtable;

public class PicoResultSetMetaData /* extends PicoObject */
   implements ResultSetMetaData
{

   protected PicoDbApi odbcApi;
   protected PicoResultSet resultSet;
   private Hashtable columnNameMap;

   public PicoResultSetMetaData(PicoDbApi api, PicoResultSet rs) {
      odbcApi = api;
      resultSet =  rs;
      columnNameMap = new Hashtable();
      columnNameMap.put ("TABLE_QUALIFIER", "TABLE_CAT");
      columnNameMap.put ("TABLE_OWNER", "TABLE_SCHEM");
      columnNameMap.put ("PRECISION", "COLUMN_SIZE");
      columnNameMap.put ("LENGTH", "BUFFER_LENGTH");
      columnNameMap.put ("SCALE", "DECIMAL_DIGITS");
      columnNameMap.put ("RADIX", "NUM_PREC_RADIX");
   }

   public String getCatalogName(int i) throws SQLException {
      if(DriverManager.getLogWriter() != null)
         DriverManager.println("*ResultSetMetaData.getCatalogName (" + i + ")");
      i = resultSet.mapColumn(i);
      if(resultSet.getPseudoCol(i) != null)
         i = 1;
      return getColAttributeString(i, OdbcDef.SQL_COLUMN_QUALIFIER_NAME);
   }

   protected int getColAttribute(int i, int j) throws SQLException {
      return resultSet.getColAttribute(i, (short)j);
   }

   protected boolean getColAttributeBoolean(int i, int j) throws SQLException {
      int k = getColAttribute(i, j);
      boolean flag = false;
      if(k == 1)
         flag = true;
      return flag;
   }

   protected String getColAttributeString(int i, int j) throws SQLException {
      String s = "";
      resultSet.clearWarnings();
      try {
         s = odbcApi.SQLColAttributesString(resultSet.getHSTMT(), i, (short)j);
      } catch(PicoSQLWarning jdbcodbcsqlwarning) {
         s = (String)jdbcodbcsqlwarning.value;
         resultSet.setWarning(PicoDbApi.convertWarning(jdbcodbcsqlwarning));
      }
      return s.trim();
   }

   public String getColumnClassName(int i) {
      throw new UnsupportedOperationException();
   }

   public int getColumnCount() throws SQLException {
      return resultSet.getColumnCount();
   }

   public int getColumnDisplaySize(int i) throws SQLException {
      if(DriverManager.getLogWriter() != null)
         DriverManager.println("*ResultSetMetaData.getColumnDisplaySize (" + i + ")");
      i = resultSet.mapColumn(i);
      PicoPseudoCol jdbcodbcpseudocol = resultSet.getPseudoCol(i);
      int j;
      if(jdbcodbcpseudocol != null)
         j = jdbcodbcpseudocol.getColumnDisplaySize();
      else
         j = getColAttribute(i, OdbcDef.SQL_COLUMN_DISPLAY_SIZE);
      return j;
   }

   public String getColumnLabel(int i) throws SQLException {
      if(DriverManager.getLogWriter() != null)
         DriverManager.println("*ResultSetMetaData.getColumnLabel (" + i + ")");
      i = resultSet.mapColumn(i);
      PicoPseudoCol jdbcodbcpseudocol = resultSet.getPseudoCol(i);
      String s;
      if(jdbcodbcpseudocol != null)
         s = jdbcodbcpseudocol.getColumnLabel();
      else
         s = getColAttributeString(i, OdbcDef.SQL_COLUMN_LABEL);
      return s;
   }

   public String getColumnName(int i) throws SQLException {
      if(DriverManager.getLogWriter() != null)
         DriverManager.println("*ResultSetMetaData.getColumnName (" + i + ")");
      i = resultSet.mapColumn(i);
      PicoPseudoCol jdbcodbcpseudocol = resultSet.getPseudoCol(i);
      String s, alias;
      if(jdbcodbcpseudocol != null)
         s = jdbcodbcpseudocol.getColumnLabel();
      else {
         s = getColAttributeString(i, OdbcDef.SQL_COLUMN_NAME);
         if ((alias = (String) columnNameMap.get(s)) != null)
            s = alias;
      }
      return s;
   }

   public int getColumnType(int i) throws SQLException {
      if(DriverManager.getLogWriter() != null)
         DriverManager.println("*ResultSetMetaData.getColumnType (" + i + ")");
      PicoPseudoCol jdbcodbcpseudocol = resultSet.getPseudoCol(i);
      int j;
      if(jdbcodbcpseudocol != null)
         j = jdbcodbcpseudocol.getColumnType() - 1;
      else
         j = resultSet.getColumnType(i);
      return j;
   }

   public String getColumnTypeName(int i) throws SQLException {
      if(DriverManager.getLogWriter() != null)
         DriverManager.println("*ResultSetMetaData.getColumnTypeName (" + i + ")");
      i = resultSet.mapColumn(i);
      String s;
      if(resultSet.getPseudoCol(i) != null)
         s = "";
      else
         s = getColAttributeString(i, OdbcDef.SQL_COLUMN_TYPE_NAME);
      return s;
   }

   public int getPrecision(int i) throws SQLException {
      if(DriverManager.getLogWriter() != null)
         DriverManager.println("*ResultSetMetaData.getPrecision (" + i + ")");
      i = resultSet.mapColumn(i);
      PicoPseudoCol jdbcodbcpseudocol = resultSet.getPseudoCol(i);
      int j;
      if(jdbcodbcpseudocol != null)
         j = jdbcodbcpseudocol.getColumnDisplaySize() - 1;
      else
         j = getColAttribute(i, OdbcDef.SQL_COLUMN_PRECISION);
      return j;
   }

   public int getScale(int i) throws SQLException {
      if(DriverManager.getLogWriter() != null)
         DriverManager.println("*ResultSetMetaData.getScale (" + i + ")");
      return resultSet.getScale(i);
   }

   public String getSchemaName(int i) throws SQLException {
      if(DriverManager.getLogWriter() != null)
         DriverManager.println("*ResultSetMetaData.getSchemaName (" + i + ")");
      i = resultSet.mapColumn(i);
      if(resultSet.getPseudoCol(i) != null)
         i = 1;
      return getColAttributeString(i, OdbcDef.SQL_COLUMN_OWNER_NAME);
   }

   public String getTableName(int i) throws SQLException {
      if(DriverManager.getLogWriter() != null)
         DriverManager.println("*ResultSetMetaData.getTableName (" + i + ")");
      i = resultSet.mapColumn(i);
      if(resultSet.getPseudoCol(i) != null)
         i = 1;
      return getColAttributeString(i, OdbcDef.SQL_COLUMN_TABLE_NAME);
   }

   public boolean isAutoIncrement(int i) throws SQLException {
      if(DriverManager.getLogWriter() != null)
         DriverManager.println("*ResultSetMetaData.isAutoIncrement (" + i + ")");
      i = resultSet.mapColumn(i);
      boolean flag;
      if(resultSet.getPseudoCol(i) != null)
         flag = false;
      else
         flag = getColAttributeBoolean(i, OdbcDef.SQL_COLUMN_AUTO_INCREMENT);
      return flag;
   }

   public boolean isCaseSensitive(int i) throws SQLException {
      if(DriverManager.getLogWriter() != null)
         DriverManager.println("*ResultSetMetaData.isCaseSensitive (" + i + ")");
      i = resultSet.mapColumn(i);
      boolean flag;
      if(resultSet.getPseudoCol(i) != null)
         flag = false;
      else
         flag = getColAttributeBoolean(i, OdbcDef.SQL_COLUMN_CASE_SENSITIVE);
      return flag;
   }

   public boolean isCurrency(int i) throws SQLException {
      if(DriverManager.getLogWriter() != null)
         DriverManager.println("*ResultSetMetaData.isCurrency (" + i + ")");
      i = resultSet.mapColumn(i);
      boolean flag;
      if(resultSet.getPseudoCol(i) != null)
         flag = false;
      else
         flag = getColAttributeBoolean(i, OdbcDef.SQL_COLUMN_MONEY);
      return flag;
   }

   public boolean isDefinitelyWritable(int i) throws SQLException {
      if(DriverManager.getLogWriter() != null)
         DriverManager.println("*ResultSetMetaData.isDefinitelyWritable (" + i + ")");
      i = resultSet.mapColumn(i);
      boolean flag;
      if(resultSet.getPseudoCol(i) != null) {
         flag = false;
      } else {
         int j = getColAttribute(i, OdbcDef.SQL_COLUMN_UPDATABLE);
         flag = j == 1;
      }
      return flag;
   }

   public int isNullable(int i) throws SQLException {
      if(DriverManager.getLogWriter() != null)
         DriverManager.println("*ResultSetMetaData.isNullable (" + i + ")");
      i = resultSet.mapColumn(i);
      int j;
      if(resultSet.getPseudoCol(i) != null)
         j = 0;
      else
         j = getColAttribute(i, OdbcDef.SQL_COLUMN_NULLABLE);
      return j;
   }

   public boolean isReadOnly(int i) throws SQLException {
      if(DriverManager.getLogWriter() != null)
         DriverManager.println("*ResultSetMetaData.isReadOnly (" + i + ")");
      i = resultSet.mapColumn(i);
      boolean flag;
      if(resultSet.getPseudoCol(i) != null) {
         flag = true;
      } else {
         int j = getColAttribute(i, OdbcDef.SQL_COLUMN_UPDATABLE);
         flag = j == 0;
      }
      return flag;
   }

   public boolean isSearchable(int i) throws SQLException {
      if(DriverManager.getLogWriter() != null)
         DriverManager.println("*ResultSetMetaData.isSearchable (" + i + ")");
      i = resultSet.mapColumn(i);
      boolean flag;
      if(resultSet.getPseudoCol(i) != null) {
         flag = false;
      } else {
         int j = getColAttribute(i, OdbcDef.SQL_COLUMN_SEARCHABLE);
         flag = j != 0;
      }
      return flag;
   }

   public boolean isSigned(int i) throws SQLException {
      if(DriverManager.getLogWriter() != null)
         DriverManager.println("*ResultSetMetaData.isSigned (" + i + ")");
      i = resultSet.mapColumn(i);
      boolean flag;
      if(resultSet.getPseudoCol(i) != null)
         flag = false;
      else
         flag = !getColAttributeBoolean(i, OdbcDef.SQL_COLUMN_UNSIGNED);
      return flag;
   }

   public boolean isWritable(int i) throws SQLException {
      if(DriverManager.getLogWriter() != null)
         DriverManager.println("*ResultSetMetaData.isWritable (" + i + ")");
      i = resultSet.mapColumn(i);
      boolean flag;
      if(resultSet.getPseudoCol(i) != null) {
         flag = false;
      } else {
         int j = getColAttribute(i,OdbcDef.SQL_COLUMN_UPDATABLE);
         flag = j == 2;
      }
      return flag;
   }
}
