/*
 *
 * Copyright 2000 Sun Microsystems, Inc. All Rights Reserved.
 * 
 * This software is the proprietary information of Sun Microsystems, Inc.  
 * Use is subject to license terms.
 * 
 */

package ejb.dataAccess;


import java.util.*;
import javax.ejb.*;
import javax.sql.*;
import java.sql.*;
import javax.naming.*;
import sun.jdbc.rowset.*;

import utils.*;
import helpers.*;



public class DataEJB implements SessionBean {


    Connection con;


   public void ejbCreate() throws CreateException {

    }//public void ejbCreate() throws CreateException




   public void ejbCreate(String dbName) throws CreateException {

      try {
         makeConnection(dbName);
      } catch (Exception ex) {
          throw new EJBException("DataEJB.ejbCreate(), unable to connect to database. " +
             ex.getMessage());
      }


    }//public void ejbCreate(String dbName) throws CreateException



    private void makeConnection(String dbName) throws NamingException, SQLException {

        if(ServerConstants.debug) {
            System.out.println("DataEJB.makeConnection()");
        }//if(ServerConstants.debug)


         if(con == null) {

            InitialContext ic = new InitialContext();
            DataSource ds = (DataSource) ic.lookup(dbName);
            con = ds.getConnection();

         } //if(con == null)


    } //private void makeConnection(String dbName)





    public void setTypeMap(String schema,String className) {


        try {

            java.util.Map map = con.getTypeMap();
            map.put(schema,Class.forName(className));

        } //try

        catch(ClassNotFoundException e) {

            System.out.println("DataEJB.setTypeMap(), ClassNotFoundException");
            e.printStackTrace();

        } //catch(ClassNotFoundException e)

        catch(java.sql.SQLException e) {

            System.out.println("DataEJB.setTypeMap(), java.sql.SQLException");
            e.printStackTrace();

        } //catch(java.sql.SQLException e)

    } //public void setTypeMap(String schema,String className)





    private void closeConnection() {

        if(ServerConstants.debug) {
            System.out.println("DataEJB.closeConnection()");
        }//if(ServerConstants.debug)

      try {
         if(con != null)
             con.close();
      } //try

      catch (SQLException ex) {
          throw new EJBException("DataEJB.closeConnection(), unsetEntityContext: " + ex.getMessage());
      } //catch (SQLException ex)

    } //private void closeConnection()





    private int executeUpdate(String query,String dbName) {

      int numRows = 0;


        if(ServerConstants.debug) {
            System.out.println("DataEJB.executeUpdate(String,String)");
        }//if(ServerConstants.debug)


      try {
         makeConnection(dbName);
      } catch (Exception ex) {
          throw new EJBException("DataEJB.executeUpdate(String,String), unable to connect to database. " +
             ex.getMessage());
      }


      PreparedStatement prepStmt;

      try {
          prepStmt = con.prepareStatement(query);

          numRows = prepStmt.executeUpdate();
          prepStmt.close();

      } //try

      catch(SQLException e) {
          System.out.println("DataEJB.executeUpdate(String,String) : " + e.toString());

      } //catch(SQLException e)

      //closeConnection();

      return numRows;

    } //private int executeUpdate(String query)







    private int executeUpdate(String query,String dbName,Object o) {

      int numRows = 0;


        if(ServerConstants.debug) {
            System.out.println("DataEJB.executeUpdate(String,String,Object)");
            System.out.println("query : " + query);
            System.out.println("ObjectString : " + o.toString());
        }//if(ServerConstants.debug)

      try {
         makeConnection(dbName);
      } catch (Exception ex) {
          throw new EJBException("DataEJB.executeUpdate(String, String, Object), Unable to connect to database. " +
             ex.getMessage());
      }


      PreparedStatement prepStmt;

      try {
          prepStmt = con.prepareStatement(query);
            prepStmt.setObject(1,o);
          numRows = prepStmt.executeUpdate();
          prepStmt.close();

      } //try

      catch(SQLException e) {
          System.out.println("DataEJB.executeUpdate(String,String,Object) : " + e.toString());

      } //catch(SQLException e)

      //closeConnection();

      return numRows;

    } //private int executeUpdate(String query,String dbName,Object o)






    public int insert(String sqlQuery,String dbName) {

        if(ServerConstants.debug) {
            System.out.println("DataEJB.insert(String,String)");
        }//if(ServerConstants.debug)

        return executeUpdate(sqlQuery,dbName);

    } //public int insert(String sqlQuery,String dbName)



    public int insert(String sqlQuery,String dbName,Object o) {

        if(ServerConstants.debug) {
            System.out.println("DataEJB.insert(String,String,Object)");
        }//if(ServerConstants.debug)

        return executeUpdate(sqlQuery,dbName,o);

    } //public int insert(String sqlQuery,String dbName,Object o)




    public int update(String sqlQuery,String dbName) {

        if(ServerConstants.debug) {
            System.out.println("DataEJB.update(String,String)");
        }//if(ServerConstants.debug)

        return executeUpdate(sqlQuery,dbName);

    } //public int update(String sqlQuery,String dbName)




    public int update(String sqlQuery,String dbName,Object o) {

        if(ServerConstants.debug) {
            System.out.println("DataEJB.update(String,String,Object)");
        }//if(ServerConstants.debug)

        return executeUpdate(sqlQuery,dbName,o);

    } //public int update(String sqlQuery,String dbName,Object o)





    public int delete(String sqlQuery,String dbName) {

        if(ServerConstants.debug) {
            System.out.println("DataEJB.delete(String,String)");
        }//if(ServerConstants.debug)

        return executeUpdate(sqlQuery,dbName);

    } //public int delete(String sqlQuery,String dbName)




    public DataSet select(String selectStatement,String dbName)
                                throws Exception, SQLException {



        if(ServerConstants.debug) {
            System.out.println("DataEJB.select(), selectStatement : " + selectStatement);
        }//if(ServerConstants.debug)



      if (dbName == null) {
        throw new Exception("DataEJB.select(), Null database name not allowed");
      } //if (dbName == null)


      try {
         makeConnection(dbName);
      } catch (Exception ex) {
          throw new EJBException("DataEJB.select(), Unable to connect to database. " +
             ex.getMessage());
      }


      PreparedStatement prepStmt = null;
      ResultSet rs = null;

      try {
          prepStmt = con.prepareStatement(selectStatement);
          rs = prepStmt.executeQuery();
      } //try

      catch (SQLException e) {
            System.out.println("DataEJB.select() : " + e.toString());
      } //catch (SQLException e)



/**
      CachedRowSet crs = new CachedRowSet();
      crs.populate(rs);
      rs.close();
      prepStmt.close();
      crs.setTableName("TableName");
      return crs;
**/

      DataSet ds = new DataSet(selectStatement,getColumnNamesVector(rs),getRowDataVector(rs));
      return ds;


    } //public DataSet select(String sqlQuery,String dbName)










    private Vector getColumnNamesVector(ResultSet rs) {


        if(ServerConstants.debug) {
            System.out.println("DataEJB.getColumnNamesVector()");
        }//if(ServerConstants.debug)

      Vector columnHeads = new Vector();

      try {
        ResultSetMetaData rsmd = rs.getMetaData();
        for (int i = 1;i<=rsmd.getColumnCount();++i) {
           columnHeads.addElement(rsmd.getColumnName(i));
        }
      }


      catch(SQLException sqlex) {
         sqlex.printStackTrace();
         System.out.println("DataEJB.getColumnNamesVector(), SQLException occured");
         return null;
      }


      return columnHeads;

    } //private Vector getColumnNamesVector()








    private Vector getRowDataVector(ResultSet rs) {


        if(ServerConstants.debug) {
            System.out.println("DataEJB.getRowDataVector()");
        }//if(ServerConstants.debug)

       Vector rows = new Vector();

        long counter = 0;
       try {
         ResultSetMetaData rsmd = rs.getMetaData();
         while(rs.next()){
            System.out.println(counter++);
             rows.addElement(getNextRow(rs,rsmd));

          }
       }

      catch(SQLException sqlex) {
         sqlex.printStackTrace();
         System.out.println("DataEJB.getRowDataVector(), SQLException occured");
         return null;
      }

       return rows;

    } //private Vector getRowDataVector()







      private Vector getNextRow(ResultSet rs, ResultSetMetaData rsmd) throws SQLException {

/**
        if(ServerConstants.debug) {
            System.out.println("DataEJB.getNextRow()");
        }//if(ServerConstants.debug)

**/

         Vector currentRow = new Vector();
         for (int i = 1;i<=rsmd.getColumnCount();++i)
            switch(rsmd.getColumnType(i)) {
               case Types.VARCHAR:
                  currentRow.addElement(rs.getString(i));
                  //System.out.println(rs.getString(i));
                  break;
               case Types.CHAR:
                  currentRow.addElement(rs.getString(i));
                  break;
               case Types.INTEGER:
                  //currentRow.addElement(new Long(rs.getLong(i)));
                  currentRow.addElement(new Integer(rs.getInt(i)));
                  //PoolMan doesn't support ResultSet.getLong()
                  break;
               case -5:     //LONGINT
                  currentRow.addElement(new Long(rs.getLong(i)));
                  break;
               case Types.DOUBLE:
                  currentRow.addElement(new Double(rs.getDouble(i)));
                  break;

               case Types.FLOAT:
                  currentRow.addElement(new Float(rs.getFloat(i)));
                  break;

               case Types.OTHER:
                  currentRow.addElement(rs.getObject(i));
                  break;

               case 93:         //TIMESTAMP
                  currentRow.addElement(Timestamp.valueOf(rs.getString(i)));
                  break;

               default:
                  System.out.println ("Type was: " + rsmd.getColumnTypeName(i) +"," + rsmd.getColumnType(i));
                  
            }
         return currentRow;
            
      } //End of getNextRow










    public DataEJB() {}

    public void ejbRemove() {

        closeConnection();

    } //public void ejbRemove()

    public void ejbActivate() {}
    public void ejbPassivate() {}
    public void setSessionContext(SessionContext sc) {}






} //public class DataEJB implements SessionBean
