/*
_____       _    _    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.io.PrintStream;
import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.sql.*;
import java.net.*;
import java.util.Vector;
import java.util.Calendar;
import org.omg.CORBA.*;

public class PicoDbApi {
   public static final short SQL_NTS = -3;
/*
   public static final int MajorVersion = 1;
   public static final int MinorVersion = 0;
*/
   private static final String id = JDBCPicoDbHelper.id();
   private static final String key = "key";
   //private static ORB orb = ORB.init(new String[0], null);
   private ORB orb;
   private int hEnv = OdbcDef.SQL_NULL_HENV;
   private JDBCPicoDb getCORBAServer(String host, int port) {
      return JDBCPicoDbHelper.narrow((org.omg.CORBA.Object)orb.string_to_object((new IOR(id, host, port, key)).toString()));
   }
   public static String getLocalHost() {
      String hostName = null;
      try {hostName = InetAddress.getLocalHost().getHostName();}
      catch (Exception e) {}
      return hostName;
   }
   public String charSet;
   private JDBCPicoDb server;
   private IntHolder returnCodeHolder = new IntHolder();
   private String sqlState = "";
   private String sqlErrMess = "";

   public PicoDbApi() {
      if (DriverManager.getLogWriter() != null) {
         java.util.Date date = new java.util.Date();
         DriverManager.println ("Jdbc PicoDb thin client");
         DriverManager.println ("Current Date/Time: " + date.toString());
         DriverManager.println ("Loading PicoDbApi library");
         DriverManager.println ("orb = " + orb);
      }
      orb = ORB.init(new String[0], null);
   }
   public void finalize () {
   }

   public int SQLAllocEnv() throws SQLException { if(DriverManager.getLogWriter() != null) DriverManager.println("(SQLAllocEnv)");
      return 1;
   }

   public int SQLAllocConnect(int i) throws SQLException {
      if(DriverManager.getLogWriter() != null)
         DriverManager.println("(SQLAllocConnect)");
      return 1;
   }

   public int SQLAllocStmt(OdbcConnection HDBC) throws SQLException {
      int hDbc = HDBC.getHDBC();
      if(DriverManager.getLogWriter() != null)
         DriverManager.println("!--(SQLAllocStmt), hDbc=" + hDbc);
      IntHolder hStmtHolder = new IntHolder();
      server.SQLAllocStmt(returnCodeHolder, hDbc, hStmtHolder);
      if (returnCodeHolder.value != OdbcDef.SQL_SUCCESS)
         standardError (returnCodeHolder.value, 0, hDbc, 0);
      if(DriverManager.getLogWriter() != null)
         DriverManager.println("hStmt=" + hStmtHolder.value);
      return hStmtHolder.value;
   }

   public void SQLFreeEnv(int hEnv) throws SQLException {
      if(DriverManager.getLogWriter() != null)
         DriverManager.println("(SQLFreeEnv), hEnv=" + hEnv);
   }

   public void SQLFreeConnect(OdbcConnection HDBC) throws SQLException {
      int hDbc;
      hDbc = HDBC != null ? HDBC.getHDBC() : 0;
      if(DriverManager.getLogWriter() != null)
         DriverManager.println("(SQLFreeConnect), hDbc=" + hDbc);
      try {
         server.SQLFreeConnect(returnCodeHolder, hDbc);
      } catch (org.omg.CORBA.SystemException e) {
        // vfc jdk1.4
      }
      if (returnCodeHolder.value != OdbcDef.SQL_SUCCESS)
         standardError (returnCodeHolder.value, 0, hDbc, 0);
   }


   public void SQLFreeStmt(OdbcStatement HSTMT, short fOption) throws SQLException {
      int hStmt = HSTMT.getHSTMT();
      if(DriverManager.getLogWriter() != null)
         DriverManager.println("!--(SQLFreeStmt), hStmt=" + hStmt +
                          ", fOption=" + fOption);
      server.SQLFreeStmt(returnCodeHolder, hStmt, fOption);
      if (returnCodeHolder.value != OdbcDef.SQL_SUCCESS)
         standardError (returnCodeHolder.value, 0, 0, hStmt);
   }

   public void SQLDisconnect(OdbcConnection HDBC) throws SQLException {
      int hDbc = HDBC.getHDBC();
      if(DriverManager.getLogWriter() != null)
         DriverManager.println("(SQLDisconnect), hDbc=" + hDbc);
      server.SQLDisconnect(returnCodeHolder, hDbc);
      if (returnCodeHolder.value != OdbcDef.SQL_SUCCESS)
         standardError (returnCodeHolder.value, 0, hDbc, 0);
   }

   public int SQLConnect(String connStr, String user, String pass)
                       throws SQLException, SQLWarning {
      String host = getLocalHost();
      String port = "9876";
      String dsn = "default";
      IntHolder hDbcHolder = new IntHolder();
      IntHolder hEnvHolder = new IntHolder();

      if(DriverManager.getLogWriter() != null)
         DriverManager.println("(SQLConnect), this=" + this + " thread = " + Thread.currentThread());
      int j, i = connStr.indexOf(':');
      if (i >= 0) {
         host = connStr.substring(0, i);
         j = connStr.indexOf(':', i + 1);
         if (j >= 0) {
            port = connStr.substring(i + 1, j);
            dsn = connStr.substring(j + 1);
         } else {
            port = connStr.substring(i);
         }
      } else {
         host = connStr;
      }
      if (host.charAt(0) == '@')
         host = host.substring(1);
     
      if(DriverManager.getLogWriter() != null)
         DriverManager.println("Debug " + host + " " + port);
      server = getCORBAServer(host, Integer.parseInt(port));
      if(DriverManager.getLogWriter() != null)
         DriverManager.println("Debug " + server + ","  + hEnv);
      if (hEnv == OdbcDef.SQL_NULL_HENV) {
         server.SQLAllocEnv(returnCodeHolder, hEnvHolder);
         if (returnCodeHolder.value == OdbcDef.SQL_ERROR) {
            standardError (returnCodeHolder.value, 0, 0, 0);
         }
         hEnv = hEnvHolder.value;
      }
      server.SQLAllocConnect(returnCodeHolder, hEnv, hDbcHolder);
      if(DriverManager.getLogWriter() != null)
         DriverManager.println("Debug " + hEnv + "," + hDbcHolder);
      if (returnCodeHolder.value == OdbcDef.SQL_ERROR) {
         standardError (returnCodeHolder.value, 0, hDbcHolder.value, 0);
      } else {
         if(DriverManager.getLogWriter() != null)
            DriverManager.println("(SQLAlloc), hDbc=" + hDbcHolder.value +
                                   ",rc=" + returnCodeHolder.value);
         if (returnCodeHolder.value != OdbcDef.SQL_SUCCESS)
            standardError (returnCodeHolder.value, 0, 0, 0);
         if(DriverManager.getLogWriter() != null)
            DriverManager.println("(SQLConnect), hDbc=" +
                                  hDbcHolder.value + 
                                  ", dsn=" + dsn +
                                  ", user=" + user +
                                  ", pass=" + pass +
                                  ", host=" + host +
                                  ", port=" + port);
         server.SQLConnect(
            returnCodeHolder,
            hDbcHolder.value,
            dsn, SQL_NTS,
            user, SQL_NTS,
            pass, SQL_NTS
         );
         if (returnCodeHolder.value != OdbcDef.SQL_SUCCESS) {
            standardError (returnCodeHolder.value, 0, hDbcHolder.value, 0);
         }
      }
      return hDbcHolder.value;
   }

   public void SQLCancel(OdbcStatement HSTMT)
      throws SQLException, SQLWarning
   {
      int hStmt = HSTMT.getHSTMT();
      if(DriverManager.getLogWriter() != null)
         DriverManager.println("(SQLCancel), hStmt=" + hStmt);
      server.SQLCancel(returnCodeHolder, hStmt);
      if (returnCodeHolder.value != OdbcDef.SQL_SUCCESS)
         standardError (returnCodeHolder.value, 0, 0, hStmt);
   }

   public int SQLColAttributes(OdbcStatement HSTMT, int icol, short type)
      throws SQLException, PicoSQLWarning {
      int hStmt = HSTMT.getHSTMT();
      if(DriverManager.getLogWriter() != null)
         DriverManager.println("(SQLColAttributes int), hStmt=" + hStmt + ", icol=" + icol + ", type=" + type);
      OctetSequenceHolder rgbDesc = new OctetSequenceHolder(new byte[2]);
      ShortHolder pcbDesc = new ShortHolder();
      IntHolder pfDesc = new IntHolder();
      short cbDescMax = 2;
      server.SQLColAttributes(returnCodeHolder,hStmt,(short)icol,type,rgbDesc,
                              cbDescMax, pcbDesc, pfDesc);
      if (returnCodeHolder.value != OdbcDef.SQL_SUCCESS)
         standardError (returnCodeHolder.value, 0, 0, hStmt);
      if(DriverManager.getLogWriter() != null)
         DriverManager.println("value (int)=" + pfDesc.value);
      return pfDesc.value;
   }

   public String SQLColAttributesString(OdbcStatement HSTMT, int icol, short type)
      throws SQLException, PicoSQLWarning {
      int hStmt = HSTMT.getHSTMT();
      if(DriverManager.getLogWriter() != null)
         DriverManager.println("(SQLColAttributes String), hStmt=" + hStmt + ", icol=" + icol + ", type=" + type);
      OctetSequenceHolder rgbDesc = new OctetSequenceHolder(new byte[128]);
      ShortHolder pcbDesc = new ShortHolder();
      IntHolder pfDesc = new IntHolder();
      short cbDescMax = 128;
      server.SQLColAttributes(returnCodeHolder,hStmt,(short)icol,type,rgbDesc,
                              cbDescMax, pcbDesc, pfDesc);
      String Return = new String();
      try {
         Return = PicoUtil.BytesToChars(charSet, rgbDesc.value);
      } catch(UnsupportedEncodingException unsupportedencodingexception) {
         if(DriverManager.getLogWriter() != null)
            DriverManager.println(unsupportedencodingexception.toString());
      }
      if(DriverManager.getLogWriter() != null)
         DriverManager.println("value (String)=" + Return.trim());
      return Return.trim();
   }

   public void SQLColumns(OdbcStatement HSTMT, String catalog, String schema, String table, String colType)
      throws SQLException, SQLWarning
   {
      int hStmt = HSTMT.getHSTMT();
      if(DriverManager.getLogWriter() != null) {
         DriverManager.println("(SQLColumns), hStmt=" + hStmt + ", catalog=" + catalog + ", schema=" + schema + ", table=" + table + ", colType=" + colType);
      }

      server.SQLColumns(
         returnCodeHolder,
         hStmt,
         catalog == null ? "" : catalog,
         catalog == null ? OdbcDef.SQL_NULL_DATA : SQL_NTS,
         schema == null ? "" : schema,
         schema == null ? OdbcDef.SQL_NULL_DATA : SQL_NTS,
         table == null ? "%" : table,
         table == null ? OdbcDef.SQL_NULL_DATA : SQL_NTS,
         colType == null ? "" : colType,
         colType == null ? OdbcDef.SQL_NULL_DATA : SQL_NTS
      );
      if (returnCodeHolder.value != OdbcDef.SQL_SUCCESS)
         standardError (returnCodeHolder.value, 0, 0, hStmt);
   }

   public void SQLExecDirect(OdbcStatement HSTMT, String szSqlStr)
      throws SQLException, SQLWarning {
      int hStmt = HSTMT.getHSTMT();
      if(DriverManager.getLogWriter() != null)
         DriverManager.println("(SQLExecDirect), hStmt=" + hStmt + ", szSqlStr=" + szSqlStr);
      server.SQLExecDirect(returnCodeHolder, hStmt, szSqlStr, SQL_NTS);
      if (returnCodeHolder.value != OdbcDef.SQL_SUCCESS)
         standardError (returnCodeHolder.value, 0, 0, hStmt);
   }

   public boolean SQLExecute(OdbcStatement HSTMT) throws SQLException, SQLWarning {
      int hStmt = HSTMT.getHSTMT();
      if(DriverManager.getLogWriter() != null)
         DriverManager.println("(SQLExecute), hStmt=" + hStmt);
      server.SQLExecute(returnCodeHolder, hStmt);
      if (returnCodeHolder.value != OdbcDef.SQL_SUCCESS)
         standardError (returnCodeHolder.value, 0, 0, hStmt);
      return true;
   }

   public boolean SQLExecuteParams(OdbcStatement HSTMT, Vector params)
           throws SQLException, SQLWarning {
      int hStmt = HSTMT.getHSTMT();
      int nParams;

      if(DriverManager.getLogWriter() != null)
         DriverManager.println("(SQLExecuteParams), hStmt=" + hStmt);

      if (params != null) {
         for (nParams = 1; nParams < params.size(); nParams++)
            if (params.get(nParams) == null)
               break;
         nParams--;
      } else
         nParams = 0;
       
      Param_item parSeq[] = new Param_item[nParams];
      PicoBoundParam par;
      for (int i = 0; i < nParams; i++) {
         par = (PicoBoundParam) params.get(i + 1);
         parSeq[i] = new Param_item ();
         parSeq[i].fParamType = par.fInputOutput;
	 parSeq[i].fSqlType = par.fSqlType;
	 parSeq[i].ibScale = (short) par.ibScale;
	 parSeq[i].rgbValue = orb.create_any();

         switch (par.fSqlType) {
         case OdbcDef.SQL_TYPE_NULL: 
            parSeq[i].fSqlType = OdbcDef.SQL_CHAR;
            parSeq[i].fCType = OdbcDef.SQL_C_CHAR;
	    parSeq[i].cbColDef = 1;
	    parSeq[i].cbValueMax = 1;
            parSeq[i].rgbValue.insert_string("");
	    parSeq[i].pcbValue = OdbcDef.SQL_NULL_DATA;
            break;
         case OdbcDef.SQL_CHAR:
         case OdbcDef.SQL_VARCHAR:
         case OdbcDef.SQL_LONGVARCHAR: 
         case OdbcDef.SQL_NUMERIC:
         case OdbcDef.SQL_DECIMAL:
         case OdbcDef.SQL_BIGINT: 
            parSeq[i].fCType = OdbcDef.SQL_C_CHAR;
            if (par.rgbValue == null) {
	       parSeq[i].cbColDef = 1;
	       parSeq[i].cbValueMax = 1;
               parSeq[i].rgbValue.insert_string("");
	       parSeq[i].pcbValue = OdbcDef.SQL_NULL_DATA;
            } else {
	       parSeq[i].cbColDef = par.rgbValue.toString().length();
	       parSeq[i].cbValueMax = parSeq[i].cbColDef;
               parSeq[i].rgbValue.insert_string(par.rgbValue.toString());
	       parSeq[i].pcbValue = parSeq[i].cbColDef;
            }
            break;
         case OdbcDef.SQL_BIT: 
            parSeq[i].fCType = OdbcDef.SQL_C_BIT;
            if (par.rgbValue == null) {
	       parSeq[i].cbColDef = 1;
	       parSeq[i].cbValueMax = 1;
               parSeq[i].rgbValue.insert_octet((byte)0);
	       parSeq[i].pcbValue = OdbcDef.SQL_NULL_DATA;
            } else {
	       parSeq[i].cbColDef = 1;
	       parSeq[i].cbValueMax = 1;
               parSeq[i].rgbValue.insert_octet(
                       (byte)(((Boolean)par.rgbValue).booleanValue() ? 1 : 0));
	       parSeq[i].pcbValue = parSeq[i].cbColDef;
            }
            break;
         case OdbcDef.SQL_TINYINT: 
            parSeq[i].fCType = OdbcDef.SQL_C_CHAR;
            if (par.rgbValue == null) {
	       parSeq[i].cbColDef = 1;
	       parSeq[i].cbValueMax = 1;
               parSeq[i].rgbValue.insert_octet((byte)0);
	       parSeq[i].pcbValue = OdbcDef.SQL_NULL_DATA;
            } else {
	       parSeq[i].cbColDef = 1;
	       parSeq[i].cbValueMax = 1;
               parSeq[i].rgbValue.insert_octet(
                       (byte)((Byte)par.rgbValue).byteValue());
	       parSeq[i].pcbValue = parSeq[i].cbColDef;
            }
            break;
         case OdbcDef.SQL_SMALLINT:
            parSeq[i].fCType = OdbcDef.SQL_C_SHORT;
            if (par.rgbValue == null) {
	       parSeq[i].cbColDef = 2;
	       parSeq[i].cbValueMax = 2;
               parSeq[i].rgbValue.insert_short((short)0);
	       parSeq[i].pcbValue = OdbcDef.SQL_NULL_DATA;
            } else {
	       parSeq[i].cbColDef = 2;
	       parSeq[i].cbValueMax = 2;
               parSeq[i].rgbValue.insert_short(
                                         ((Integer)par.rgbValue).shortValue());
	       parSeq[i].pcbValue = parSeq[i].cbColDef;
            }
            break;
         case OdbcDef.SQL_INTEGER:
            parSeq[i].fCType = OdbcDef.SQL_C_LONG;
            if (par.rgbValue == null) {
	       parSeq[i].cbColDef = 4;
	       parSeq[i].cbValueMax = 4;
               parSeq[i].rgbValue.insert_long(0);
	       parSeq[i].pcbValue = OdbcDef.SQL_NULL_DATA;
            } else {
	       parSeq[i].cbColDef = 4;
	       parSeq[i].cbValueMax = 4;
               parSeq[i].rgbValue.insert_long(
                                        ((Integer)par.rgbValue).intValue());
	       parSeq[i].pcbValue = parSeq[i].cbColDef;
            }
            break;
         case OdbcDef.SQL_REAL:
            parSeq[i].fCType = OdbcDef.SQL_C_FLOAT;
            if (par.rgbValue == null) {
	       parSeq[i].cbColDef = 4;
	       parSeq[i].cbValueMax = 4;
               parSeq[i].rgbValue.insert_float(0F);
	       parSeq[i].pcbValue = OdbcDef.SQL_NULL_DATA;
            } else {
	       parSeq[i].cbColDef = 4;
	       parSeq[i].cbValueMax = 4;
               parSeq[i].rgbValue.insert_float(
                                        ((Float)par.rgbValue).floatValue());
	       parSeq[i].pcbValue = parSeq[i].cbColDef;
            }
            break;
         case OdbcDef.SQL_FLOAT:
         case OdbcDef.SQL_DOUBLE:
            parSeq[i].fCType = OdbcDef.SQL_C_DOUBLE;
            if (par.rgbValue == null) {
	       parSeq[i].cbColDef = 8;
	       parSeq[i].cbValueMax = 8;
               parSeq[i].rgbValue.insert_double(0D);
	       parSeq[i].pcbValue = OdbcDef.SQL_NULL_DATA;
            } else {
	       parSeq[i].cbColDef = 8;
	       parSeq[i].cbValueMax = 8;
               parSeq[i].rgbValue.insert_double(
                                        ((Double)par.rgbValue).doubleValue());
	       parSeq[i].pcbValue = parSeq[i].cbColDef;
            }
            break;
         case OdbcDef.SQL_BINARY: 
         case OdbcDef.SQL_LONGVARBINARY: 
         case OdbcDef.SQL_VARBINARY:
            parSeq[i].fCType = OdbcDef.SQL_C_BINARY;
            OctetSequenceHelper.insert (parSeq[i].rgbValue,
                                                       (byte[])(par.rgbValue));
            if (par.rgbValue == null) {
	       parSeq[i].cbColDef = 1;
	       parSeq[i].cbValueMax = 1;
	       parSeq[i].pcbValue = OdbcDef.SQL_NULL_DATA;
            } else {
	       parSeq[i].cbColDef = ((byte[])(par.rgbValue)).length;
	       parSeq[i].cbValueMax = 0x7FFFFFFF;
	       parSeq[i].pcbValue = parSeq[i].cbColDef;
            }
            break;
         case OdbcDef.SQL_C_DATE:
         case OdbcDef.SQL_C_TIME:
         case OdbcDef.SQL_C_TIMESTAMP:
            if (par.rgbValue != null) {
               Timestamp_struct ts = new Timestamp_struct();
               Calendar cal = par.cal == null ? Calendar.getInstance():par.cal;
               cal.setTime ((java.util.Date) par.rgbValue);
               ts.year = (short) cal.get(Calendar.YEAR);
               ts.month = (short) (cal.get(Calendar.MONTH) + 1);
               ts.day = (short) cal.get(Calendar.DAY_OF_MONTH);
               ts.hour = (short) cal.get(Calendar.HOUR_OF_DAY);
               ts.minute = (short) cal.get(Calendar.MINUTE);
               ts.second = (short) cal.get(Calendar.SECOND);
               ts.fraction = (short) cal.get(Calendar.MILLISECOND);
               parSeq[i].fCType = OdbcDef.SQL_TIMESTAMP;
               parSeq[i].fSqlType = OdbcDef.SQL_TIMESTAMP;
               Timestamp_structHelper.insert (parSeq[i].rgbValue, ts);
            }
            if (par.rgbValue == null) {
	       parSeq[i].cbColDef = 1;
	       parSeq[i].cbValueMax = 1;
               parSeq[i].fCType = OdbcDef.SQL_TIMESTAMP;
               parSeq[i].fSqlType = OdbcDef.SQL_TIMESTAMP;
	       parSeq[i].pcbValue = OdbcDef.SQL_NULL_DATA;
            } else {
	       parSeq[i].cbColDef = 16;
	       parSeq[i].cbValueMax = 16;
	       parSeq[i].pcbValue = parSeq[i].cbColDef;
            }
            break;
         default:
            throw new SQLException("Unknown SQL Type in SQLEcecuteParams=" +
                                    par.fSqlType);
         }
      }
      server.SQLExecuteParams(returnCodeHolder, hStmt, parSeq);
      if (returnCodeHolder.value != OdbcDef.SQL_SUCCESS)
         standardError (returnCodeHolder.value, 0, 0, hStmt);
      return true;
   }

   public boolean SQLFetch(OdbcStatement HSTMT) throws SQLException, SQLWarning {
      int hStmt = HSTMT.getHSTMT();
      boolean Return = true;
      if(DriverManager.getLogWriter() != null)
         DriverManager.println("(SQLFetch), hStmt=" + hStmt);
      IntHolder numCols = new IntHolder();
      server.SQLFetch(returnCodeHolder, hStmt, numCols);
      if (returnCodeHolder.value == OdbcDef.SQL_NO_DATA_FOUND)
         Return = false;
      else if (returnCodeHolder.value != OdbcDef.SQL_SUCCESS)
         standardError (returnCodeHolder.value, 0, 0, hStmt);
      if(DriverManager.getLogWriter() != null)
         DriverManager.println("(SQLFetch), ret=" + returnCodeHolder.value + "col=" + numCols.value);
      return Return;
   }
   public boolean SQLFetch(OdbcStatement HSTMT, int nCol[]) throws SQLException, SQLWarning {
      int hStmt = HSTMT.getHSTMT();
      boolean Return = true;
      if(DriverManager.getLogWriter() != null)
         DriverManager.println("(SQLFetch), hStmt=" + hStmt);
      IntHolder numCols = new IntHolder();
      server.SQLFetch(returnCodeHolder, hStmt, numCols);
      if (returnCodeHolder.value == OdbcDef.SQL_NO_DATA_FOUND)
         Return = false;
      else if (returnCodeHolder.value != OdbcDef.SQL_SUCCESS)
         standardError (returnCodeHolder.value, 0, 0, hStmt);
      nCol[0] = numCols.value;
      if(DriverManager.getLogWriter() != null)
         DriverManager.println("(SQLFetch), ret=" + returnCodeHolder.value + "col=" + numCols.value);
      return Return;
   }

   public int SQLGetConnectOption(OdbcConnection HDBC, short fOption)
      throws SQLException
   {
      int hDbc = HDBC.getHDBC();
      if(DriverManager.getLogWriter() != null)
         DriverManager.println("(SQLGetConnectOption), hDbc=" + hDbc + ", fOption=" + fOption);
      IntHolder optionValueHolder = new IntHolder();
      StringHolder optionStringValueHolder = new StringHolder();
      server.SQLGetConnectOption(returnCodeHolder, hDbc, fOption, optionStringValueHolder, optionValueHolder);
      if (returnCodeHolder.value != OdbcDef.SQL_SUCCESS)
         standardError (returnCodeHolder.value, 0, hDbc, 0);
      if(DriverManager.getLogWriter() != null)
         DriverManager.println("option value (int)=" + optionValueHolder.value);
      return optionValueHolder.value;
   }

   public String SQLGetConnectOptionString(OdbcConnection HDBC, short fOption)
      throws SQLException
   {
      int hDbc = HDBC.getHDBC();
      if(DriverManager.getLogWriter() != null)
         DriverManager.println("(SQLGetConnectOption), hDbc=" + hDbc + ", fOption=" + fOption);
      IntHolder optionValueHolder = new IntHolder();
      StringHolder optionStringValueHolder = new StringHolder();
      server.SQLGetConnectOption(returnCodeHolder, hDbc, fOption, optionStringValueHolder, optionValueHolder);
      if (returnCodeHolder.value != OdbcDef.SQL_SUCCESS)
         standardError (returnCodeHolder.value, 0, hDbc, 0);
      if(DriverManager.getLogWriter() != null)
         DriverManager.println("option value (int)=" + optionStringValueHolder.value.trim());
      return optionStringValueHolder.value.trim();
   }

   public String SQLGetCursorName(OdbcStatement HSTMT)
      throws SQLException, PicoSQLWarning
   {
      int hStmt = HSTMT.getHSTMT();
      if(DriverManager.getLogWriter() != null)
         DriverManager.println("(SQLGetCursorName), hStmt=" + hStmt);
      StringHolder cursorNameHolder = new StringHolder();
      ShortHolder cursorNameLengthHolder = new ShortHolder();
      server.SQLGetCursorName(returnCodeHolder, hStmt, cursorNameHolder, (short)256, cursorNameLengthHolder);
      if (returnCodeHolder.value != OdbcDef.SQL_SUCCESS)
         standardError (returnCodeHolder.value, 0, 0, hStmt);
      String cursorName = cursorNameHolder.value.trim();
      if(DriverManager.getLogWriter() != null)
         DriverManager.println("value=" + cursorName);
      return cursorName;
   }

   public java.lang.Object[] SQLGetAllData (OdbcStatement HSTMT,
                                            PicoBoundCol attr[])
                                  throws SQLException, PicoSQLWarning {
      int hStmt = HSTMT.getHSTMT();
      AnySequenceHolder dataHolder = new AnySequenceHolder();
      CommAttr_seqHolder attrHolder = new CommAttr_seqHolder();
      if(DriverManager.getLogWriter() != null)
         DriverManager.println("(SQLGetAllData), hStmt=" + hStmt);
      server.SQLGetAllData(returnCodeHolder,hStmt,dataHolder,attrHolder);
      if (returnCodeHolder.value == OdbcDef.SQL_ERROR)
         standardError (returnCodeHolder.value, 0, 0, hStmt);
      if (DriverManager.getLogWriter() != null)
         DriverManager.println("value=" + dataHolder);
      java.lang.Object Return[]=new java.lang.Object[dataHolder.value.length];
      for (int i = 0; i < dataHolder.value.length; i++) {
         attr[i].setLength (attrHolder.value[i].length);
         attr[i].setType (OdbcDef.odbcTypeToJdbc(attrHolder.value[i].type));
         attr[i].setPrecision (attrHolder.value[i].precision);
         attr[i].setScale (attrHolder.value[i].scale);
         switch (dataHolder.value[i].type().kind().value()) {
         case TCKind._tk_short:
            Return[i] = new Short (dataHolder.value[i].extract_short());
            break;
         case TCKind._tk_ushort:
            Return[i] = new Short (dataHolder.value[i].extract_ushort());
            break;
         case TCKind._tk_long:
            Return[i] = new Integer (dataHolder.value[i].extract_long());
            break;
         case TCKind._tk_ulong:
            Return[i] = new Integer (dataHolder.value[i].extract_ulong());
            break;
         case TCKind._tk_float:
            Return[i] = new Float (dataHolder.value[i].extract_float());
            break;
         case TCKind._tk_double:
            Return[i] = new Double (dataHolder.value[i].extract_double());
            break;
         case TCKind._tk_string:
            Return[i] = dataHolder.value[i].extract_string();
            break;
         case TCKind._tk_Principal:
            org.omg.CORBA.portable.InputStream in =
                                      dataHolder.value[i].create_input_stream();
            int size = in.read_long();
            Return[i] = (java.lang.Object) new byte[size];
            in.read_octet_array ((byte[])Return[i], 0, size);
            break;
         case TCKind._tk_null:
            Return[i] = null;
            break;
         case TCKind._tk_struct:
            try {
               if (Timestamp_structHelper.type().name().equals(
                                        dataHolder.value[i].type().name())) {
                  Timestamp_struct ts = Timestamp_structHelper.extract(
                                                           dataHolder.value[i]);
                  Return[i] = Timestamp.valueOf(
                            ""+ ts.year + "-" + ts.month + "-" + ts.day +
                            " "   + ts.hour + ":" + ts.minute +":" + ts.second +
                            "." + fractToString (ts.fraction));
               } else {
                  Return[i] = null;
                  throw new SQLException ("Unknown struct " + 
                               dataHolder.value[i].type().name() +
                               " col # " + i);
               }
            } catch (org.omg.CORBA.TypeCodePackage.BadKind ex) {
               Return[i] = null;
               throw new SQLException (ex.toString());
            }
            break;
         default:
            Return[i] = null;
            throw new SQLException ("Unknown tk type " + 
                               dataHolder.value[i].type().kind().value() +
                               " col # " + i);
         }
      }
      /*
      if (returnCodeHolder.value != OdbcDef.SQL_SUCCESS)
         standardError (returnCodeHolder.value, 0, 0, hStmt);
       */
      return Return;
   }

   public Double SQLGetDataDouble(OdbcStatement HSTMT, int icol)
                                  throws SQLException, PicoSQLWarning {
      int hStmt = HSTMT.getHSTMT();
      Double Return = null;
      if(DriverManager.getLogWriter() != null)
         DriverManager.println("(SQLGetData Double), hStmt=" + hStmt + ", icol=" + icol);
      AnyHolder rgbValue = new AnyHolder();
      int cbValueMax = 0;
      IntHolder pcbValue = new IntHolder();
      server.SQLGetData(returnCodeHolder,hStmt,(short)icol,OdbcDef.SQL_DOUBLE,
                        rgbValue, cbValueMax, pcbValue);
      if (returnCodeHolder.value != OdbcDef.SQL_SUCCESS)
         standardError (returnCodeHolder.value, 0, 0, hStmt);
      if (pcbValue.value >= 0)
         Return = new Double (rgbValue.value.extract_double());
      if (DriverManager.getLogWriter() != null)
         DriverManager.println("type=" + rgbValue.value.type().kind().value() +
                               ",value=" + Return + ",len=" + pcbValue.value);
      return Return;
   }

   public Float SQLGetDataFloat(OdbcStatement HSTMT, int icol)
                                       throws SQLException, PicoSQLWarning {
      int hStmt = HSTMT.getHSTMT();
      Float Return = null;
      if(DriverManager.getLogWriter() != null)
         DriverManager.println("(SQLGetData Float), hStmt=" + hStmt + ", icol=" + icol);
      AnyHolder rgbValue = new AnyHolder();
      int cbValueMax = 0;
      IntHolder pcbValue = new IntHolder();
      server.SQLGetData(returnCodeHolder,hStmt,(short)icol,OdbcDef.SQL_REAL,
                        rgbValue, cbValueMax, pcbValue);
      if (returnCodeHolder.value != OdbcDef.SQL_SUCCESS)
         standardError (returnCodeHolder.value, 0, 0, hStmt);
      if (pcbValue.value >= 0)
         Return = new Float (rgbValue.value.extract_float());
      if (DriverManager.getLogWriter() != null)
         DriverManager.println("type=" + rgbValue.value.type().kind().value() +
                               ",value=" + Return + ",len=" + pcbValue.value);
      return Return;
   }

   public Integer SQLGetDataInteger(OdbcStatement HSTMT, int icol)
                              throws SQLException, PicoSQLWarning {
      int hStmt = HSTMT.getHSTMT();
      Integer Return = null;
      if(DriverManager.getLogWriter() != null)
         DriverManager.println("(SQLGetData Integer), hStmt=" + hStmt + ", column=" + icol);
      AnyHolder rgbValue = new AnyHolder();
      int cbValueMax = 0;
      IntHolder pcbValue = new IntHolder();
      server.SQLGetData(returnCodeHolder,hStmt,(short)icol,OdbcDef.SQL_INTEGER,
                        rgbValue, cbValueMax, pcbValue);
      if (returnCodeHolder.value != OdbcDef.SQL_SUCCESS)
         standardError (returnCodeHolder.value, 0, 0, hStmt);
      if (pcbValue.value >= 0)
         Return = new Integer (rgbValue.value.extract_long());
      if (DriverManager.getLogWriter() != null)
         DriverManager.println("type=" + rgbValue.value.type().kind().value() +
                               ",value=" + Return + ",len=" + pcbValue.value);
      return Return;
   }

   public String SQLGetDataString(OdbcStatement HSTMT, int icol, int cbValueMax,
                                  boolean trim)
                      throws SQLException, PicoSQLWarning {
      int hStmt = HSTMT.getHSTMT();
      String Return = null;
      if(DriverManager.getLogWriter() != null)
         DriverManager.println("(SQLGetData String), hStmt=" + hStmt + ", icol=" + icol + ", cbValueMax=" + cbValueMax);
      AnyHolder rgbValue = new AnyHolder();
      IntHolder pcbValue = new IntHolder();
      server.SQLGetData(returnCodeHolder,hStmt,(short)icol,OdbcDef.SQL_CHAR,
                        rgbValue, cbValueMax, pcbValue);
      if (returnCodeHolder.value != OdbcDef.SQL_SUCCESS)
         standardError (returnCodeHolder.value, 0, 0, hStmt);
      if (pcbValue.value >= 0)
         Return = rgbValue.value.extract_string();
      if (DriverManager.getLogWriter() != null)
         DriverManager.println("type=" + rgbValue.value.type().kind().value() +
                               ",value=[" + Return + "],len=" + pcbValue.value);
      if (trim && Return != null)
         return Return.trim();
      else
         return Return;
   }

   public byte[] SQLGetDataBytes(OdbcStatement HSTMT, int icol)
                      throws SQLException, PicoSQLWarning {
      int hStmt = HSTMT.getHSTMT();
      byte[] Return = null;
      if(DriverManager.getLogWriter() != null)
         DriverManager.println("(SQLGetData Bytes), hStmt=" + hStmt + ", icol=" + icol);
      AnyHolder rgbValue = new AnyHolder();
      IntHolder pcbValue = new IntHolder();
      server.SQLGetData (returnCodeHolder,hStmt,(short)icol,
                         OdbcDef.SQL_LONGVARBINARY,
                         rgbValue, 0x7fffffff, pcbValue);
      if (returnCodeHolder.value != OdbcDef.SQL_SUCCESS)
         standardError (returnCodeHolder.value, 0, 0, hStmt);
      if (DriverManager.getLogWriter() != null)
         DriverManager.println("type=" + rgbValue.value.type().kind().value() +
                               ",value=[" + Return + "],len=" + pcbValue.value);
      org.omg.CORBA.portable.InputStream in =
                                           rgbValue.value.create_input_stream();
      int size = in.read_long();
      Return = new byte[size];
      in.read_octet_array ((byte[])Return, 0, size);
      return Return;
   }
   
   public Timestamp SQLGetDataTimestamp (OdbcStatement HSTMT, int icol)
                      throws SQLException, PicoSQLWarning {
      int hStmt = HSTMT.getHSTMT();
      Timestamp Return = null;
      if(DriverManager.getLogWriter() != null)
         DriverManager.println("(SQLGetData Timestamp), hStmt=" + hStmt + 
                                                             ", icol=" + icol);
      AnyHolder rgbValue = new AnyHolder();
      IntHolder pcbValue = new IntHolder();
      server.SQLGetData (returnCodeHolder,hStmt,(short)icol,
                         OdbcDef.SQL_TIMESTAMP,
                         rgbValue, 0, pcbValue);
      if (returnCodeHolder.value != OdbcDef.SQL_SUCCESS)
         standardError (returnCodeHolder.value, 0, 0, hStmt);
      if (DriverManager.getLogWriter() != null)
         DriverManager.println("type=" + rgbValue.value.type().kind().value() +
                               ",value=[" + Return + "],len=" + pcbValue.value);
      Timestamp_struct ts = Timestamp_structHelper.extract(rgbValue.value);
      Return = Timestamp.valueOf(
                            ""+ ts.year + "-" + ts.month + "-" + ts.day +
                            " "   + ts.hour + ":" + ts.minute +":" + ts.second +
                            "."   + fractToString(ts.fraction));
      return Return;
   }
   
   public int SQLGetStmtOption(OdbcStatement HSTMT, short fOption)
      throws SQLException, SQLWarning {
      int hStmt = HSTMT.getHSTMT();
      if(DriverManager.getLogWriter() != null)
         DriverManager.println("(SQLGetStmtOption), hStmt=" + hStmt + ", fOption=" + fOption);
      IntHolder optionValueHolder = new IntHolder();
      StringHolder optionStringValueHolder = new StringHolder();
      server.SQLGetStmtOption(returnCodeHolder, hStmt, fOption, optionStringValueHolder, optionValueHolder);
      if (returnCodeHolder.value != OdbcDef.SQL_SUCCESS)
         standardError (returnCodeHolder.value, 0, 0, hStmt);
      if(DriverManager.getLogWriter() != null)
         DriverManager.println("value=" + optionValueHolder.value);
      return optionValueHolder.value;
   }

   public void SQLGetTypeInfo(OdbcStatement HSTMT, short fSqlType) throws SQLException {
      int hStmt = HSTMT.getHSTMT();
      if(DriverManager.getLogWriter() != null)
         DriverManager.println("(SQLGetTypeInfo), hStmt=" + hStmt + ", fSqlType=" + fSqlType);
      server.SQLGetTypeInfo(returnCodeHolder, hStmt, fSqlType);
      if (returnCodeHolder.value != OdbcDef.SQL_SUCCESS)
         standardError (returnCodeHolder.value, 0, 0, hStmt);
   }

   public int SQLNumParams(OdbcStatement HSTMT)
      throws SQLException, PicoSQLWarning
   {
      int hStmt = HSTMT.getHSTMT();
      int numPar = 0;
      if(DriverManager.getLogWriter() != null)
         DriverManager.println("(SQLNumParams), hStmt=" + hStmt);
      ShortHolder numParHolder = new ShortHolder();
      server.SQLNumResultCols(returnCodeHolder, hStmt, numParHolder);
      if (returnCodeHolder.value != OdbcDef.SQL_SUCCESS)
         standardError (returnCodeHolder.value, 0, 0, hStmt);
      if(DriverManager.getLogWriter() != null)
         DriverManager.println("value=" + numParHolder.value);
      return numParHolder.value;
   }

   public int SQLNumResultCols(OdbcStatement HSTMT) throws SQLException, PicoSQLWarning {
      int hStmt = HSTMT.getHSTMT();
      if(DriverManager.getLogWriter() != null)
         DriverManager.println("(SQLNumResultCols), hStmt=" + hStmt);
      ShortHolder pccol = new ShortHolder();
      server.SQLNumResultCols(returnCodeHolder, hStmt, pccol);
      if (returnCodeHolder.value != OdbcDef.SQL_SUCCESS)
         standardError (returnCodeHolder.value, 0, 0, hStmt);
      if(DriverManager.getLogWriter() != null)
         DriverManager.println("value=" + pccol.value);
      return pccol.value;
   }

   public void SQLPrepare(OdbcStatement HSTMT, String szSqlStr)
      throws SQLException, SQLWarning {
      int hStmt = HSTMT.getHSTMT();
      if(DriverManager.getLogWriter() != null)
         DriverManager.println("(SQLPrepare), hStmt=" + hStmt + ", szSqlStr=" + szSqlStr);
      server.SQLPrepare (returnCodeHolder, hStmt, szSqlStr, szSqlStr.length());
      if (returnCodeHolder.value != OdbcDef.SQL_SUCCESS)
         standardError (returnCodeHolder.value, 0, 0, hStmt);
   }

   public int SQLRowCount(OdbcStatement HSTMT) throws SQLException, PicoSQLWarning {
      int hStmt = HSTMT.getHSTMT();
      if(DriverManager.getLogWriter() != null)
         DriverManager.println("(SQLRowCount), hStmt=" + hStmt);
         IntHolder pcrow = new IntHolder();
         server.SQLRowCount(returnCodeHolder, hStmt, pcrow);
      if(DriverManager.getLogWriter() != null)
         DriverManager.println("value=" + pcrow.value);
      return pcrow.value;
   }

   public void SQLSetConnectOption(OdbcConnection HDBC, short fOption, int vParam)
      throws SQLException {
      int hDbc = HDBC.getHDBC();
      if(DriverManager.getLogWriter() != null)
         DriverManager.println("(SQLSetConnectOption), hDbc=" + hDbc + ", fOption=" + fOption + ", vParam=" + vParam);
      server.SQLSetConnectOption(returnCodeHolder, hDbc, fOption, "", vParam);
      if (returnCodeHolder.value != OdbcDef.SQL_SUCCESS)
         standardError (returnCodeHolder.value, 0, hDbc, 0);
   }

   public void SQLSetConnectOption(OdbcConnection HDBC, short fOption, String vParam)
      throws SQLException {
      int hDbc = HDBC.getHDBC();
      if(DriverManager.getLogWriter() != null)
         DriverManager.println("(SQLSetConnectOption), hDbc=" + hDbc + ", fOption=" + fOption + ", vParam=" + vParam);
      server.SQLSetConnectOption(returnCodeHolder, hDbc, fOption, vParam, 0);
      if (returnCodeHolder.value != OdbcDef.SQL_SUCCESS)
         standardError (returnCodeHolder.value, 0, hDbc, 0);
   }

   public void SQLSetStmtOption(OdbcStatement HSTMT, short fOption, int vParam)
      throws SQLException
   {
      int hStmt = HSTMT.getHSTMT();
      if(DriverManager.getLogWriter() != null)
         DriverManager.println("(SQLSetStmtOption), hStmt=" + hStmt + ", fOption=" + fOption + ", vParam=" + vParam);
      server.SQLSetStmtOption(returnCodeHolder, hStmt, fOption, "", vParam);
      if (returnCodeHolder.value != OdbcDef.SQL_SUCCESS)
         standardError (returnCodeHolder.value, 0, 0, hStmt);
   }

   public void SQLSpecialColumns(OdbcStatement HSTMT, short fColType, String catalog, String schema, String table, int fScope, boolean fNullable)
      throws SQLException, SQLWarning
   {
      int hStmt = HSTMT.getHSTMT();
      if(DriverManager.getLogWriter() != null)
         DriverManager.println("(SQLSpecialColumns), hStmt=" + hStmt + ", fColType=" + fColType + ",catalog=" + catalog + ", schema=" + schema + ", table=" + table + ", fScope=" + fScope + ", fNullable=" + fNullable);
      server.SQLSpecialColumns(
         returnCodeHolder,
         hStmt,
         fColType,
         catalog == null ? "" : catalog,
         catalog == null ? OdbcDef.SQL_NULL_DATA : SQL_NTS,
         schema == null ? "" : schema,
         schema == null ? OdbcDef.SQL_NULL_DATA : SQL_NTS,
         table == null ? "%" : table,
         table == null ? OdbcDef.SQL_NULL_DATA : SQL_NTS,
         (short)fScope,
         (short)(fNullable ? OdbcDef.SQL_NULLABLE : OdbcDef.SQL_NO_NULLS)
      );
      if (returnCodeHolder.value != OdbcDef.SQL_SUCCESS)
         standardError (returnCodeHolder.value, 0, 0, hStmt);
   }

   public void SQLStatistics(OdbcStatement HSTMT, String catalog, String schema, String table, boolean unique, boolean approximate)
      throws SQLException, SQLWarning
   {
      int hStmt = HSTMT.getHSTMT();
      if(DriverManager.getLogWriter() != null)
         DriverManager.println("(SQLStatistics), hStmt=" + hStmt + ",catalog=" + catalog + ", schema=" + schema + ", table=" + table + ", unique=" + unique + ", approximate=" + approximate);
      server.SQLStatistics(
         returnCodeHolder,
         hStmt,
         catalog == null ? "" : catalog,
         catalog == null ? OdbcDef.SQL_NULL_DATA : SQL_NTS,
         schema == null ? "" : schema,
         schema == null ? OdbcDef.SQL_NULL_DATA : SQL_NTS,
         table == null ? "%" : table,
         table == null ? OdbcDef.SQL_NULL_DATA : SQL_NTS,
         (short)(unique ? OdbcDef.SQL_INDEX_UNIQUE : OdbcDef.SQL_INDEX_ALL),
         (short)(approximate ? OdbcDef.SQL_QUICK : OdbcDef.SQL_ENSURE)
      );
      if (returnCodeHolder.value != OdbcDef.SQL_SUCCESS)
         standardError (returnCodeHolder.value, 0, 0, hStmt);
   }

   public void SQLTables(OdbcStatement HSTMT, String catalog, String schema, String table, String types)
      throws SQLException, SQLWarning
   {
      int hStmt = HSTMT.getHSTMT();
      if(DriverManager.getLogWriter() != null)
         DriverManager.println("(SQLTables), hStmt=" + hStmt + ",catalog=" + catalog + ", schema=" + schema + ", table=" + table + ", types=" + types);
      
      server.SQLTables(
         returnCodeHolder,
         hStmt,
         catalog == null ? "" : catalog,
         catalog == null ? OdbcDef.SQL_NULL_DATA : SQL_NTS,
         schema == null ? "" : schema,
         schema == null ? OdbcDef.SQL_NULL_DATA : SQL_NTS,
         table == null ? "%" : table,
         table == null ? OdbcDef.SQL_NULL_DATA : SQL_NTS,
         types == null ? "" : types,
         types == null ? OdbcDef.SQL_NULL_DATA : SQL_NTS
      );
      if (returnCodeHolder.value != OdbcDef.SQL_SUCCESS)
         standardError (returnCodeHolder.value, 0, 0, hStmt);
   }

   public void SQLTransact(int hEnv, OdbcConnection HDBC, short fType)
      throws SQLException
   {
      int hDbc = HDBC.getHDBC();
      if(DriverManager.getLogWriter() != null)
         DriverManager.println("(SQLTransact), hEnv=" + hEnv + ", hDbc=" + hDbc + ", fType=" + fType);
      server.SQLTransact(returnCodeHolder, hEnv, hDbc, fType);
      if (returnCodeHolder.value != OdbcDef.SQL_SUCCESS)
         standardError (returnCodeHolder.value, hEnv, hDbc, 0);
   }
   public int SQLError(int hEnv, int hDbc, int hStmt) {
      int Return;
      StringHolder outSqlState = new StringHolder();
      StringHolder outErrorMsg = new StringHolder();
      IntHolder outNativeError = new IntHolder();
      ShortHolder pcbErrorMsg = new ShortHolder();
      server.SQLError(returnCodeHolder, hEnv, hDbc, hStmt, outSqlState,
                      outNativeError, outErrorMsg, (short)512, pcbErrorMsg);
      if (returnCodeHolder.value == OdbcDef.SQL_NO_DATA_FOUND) {
         sqlState = "";
         sqlErrMess = "";
         Return = 0;
      } else if (returnCodeHolder.value == OdbcDef.SQL_ERROR) {
         sqlState = "S10000";
         sqlErrMess = "General Error - Error on SQLError";
         Return = 0;
      } else {
         sqlState = outSqlState.value;
         sqlErrMess = outErrorMsg.value;
         Return = (outNativeError.value == 0) ? 9999 : outNativeError.value;
      }
      if(DriverManager.getLogWriter() != null)
         DriverManager.println("(SQLError), hEnv=" + hEnv +
                               ", hDbc=" + hDbc + ", hStmt=" + hStmt +
                                " [" + sqlErrMess + "]=" + Return);
      return Return;
   }

   public static SQLWarning convertWarning(PicoSQLWarning warn) {
      SQLWarning Return = warn;
      if(warn.getSQLState().equals("01004")) {
         Return = new DataTruncation(-1, false, true, 0, 0);
      }
      return Return;
   }

   SQLException createSQLException(int hEnv, int hDbc, int hStmt) {
      int error;
      SQLException Return = null, currEx = null, lastEx = null;
      if (DriverManager.getLogWriter() != null)
         DriverManager.println("ERROR - Generating SQLException...");
      while((error = SQLError (hEnv, hDbc, hStmt)) != 0) {
         currEx = new SQLException(sqlErrMess, sqlState, error);
         if (Return == null)
            Return = currEx;
         else
            lastEx.setNextException(currEx);
         lastEx = currEx;
      }
      if (Return == null) {
         Return = new PicoSQLWarning("General Error", "S1000");
      }
      return Return;
   }

   PicoSQLWarning createSQLWarning(int hEnv, int hDbc, int hStmt) {
      int error;
      PicoSQLWarning Return = null, currEx = null, lastEx = null;
      if(DriverManager.getLogWriter() != null)
         DriverManager.println("WARNING - Generating SQLWarning...");
      while((error = SQLError (hEnv, hDbc, hStmt)) != 0) {
         currEx = new PicoSQLWarning(sqlErrMess, sqlState, error);
         if (Return == null)
            Return = currEx;
         else
            lastEx.setNextWarning(currEx);
         lastEx = currEx;
      }
      if (Return == null) {
         Return = new PicoSQLWarning("General warning", "01000");
      }
      return Return;
   }

   void standardError(int retCode, int hEnv, int hDbc, int hStmt)
      throws SQLException, PicoSQLWarning {
      if(DriverManager.getLogWriter() != null)
         DriverManager.println("RETCODE = " + retCode);
      switch(retCode) {
      case OdbcDef.SQL_SUCCESS: 
         return;
      case OdbcDef.SQL_ERROR: 
         throw createSQLException(hEnv, hDbc, hStmt);

      case OdbcDef.SQL_SUCCESS_WITH_INFO:
         throw createSQLWarning(hEnv, hDbc, hStmt);

      case OdbcDef.SQL_INVALID_HANDLE: 
         throw new SQLException("Invalid handle");

      case OdbcDef.SQL_NO_DATA_FOUND:
         throw new SQLException("No data found");

      }
      throwGenericSQLException(retCode);
   }

   void throwGenericSQLException(int code) throws SQLException {
      String reason = "Unknown return code " + code;
      String sqlstate = "S1000";
      if(DriverManager.getLogWriter() != null)
         DriverManager.println("ERROR - " + sqlstate + " " + reason);
      throw new SQLException(reason, sqlstate);
   }

   protected void ReleaseStoredBytes(int i, int j){}

   protected void ReleaseStoredChars(int i, int j){}

   public int bufferToInt(byte abyte0[]){return 0;}
   
   static private String fractToString (int fract) {
      String Return = "000" + fract;
      return Return.substring(Return.length() - 3);
   }
}
