package com.eactive.eai.adapter.wca.jdbc;


import com.eactive.eai.common.util.Logger;

import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;

/** 
* 1. 기능 : DB Operation을 위한 공통 JDBC 클래스
* 2. 처리 개요 : 
* 3. 주의사항 
*
* @author  : 
* @version : v 1.0.0
* @see : 
* @since   : 
*/
public class CommonJDBC extends BaseJDBC
{   
    /**
     * SNAAdapter 로깅을 위한 logger 
     */
    Logger trc_logger = Logger.getLogger(Logger.LOGGER_ADAPTER);    

   /** 
    * 1. 기능 :  insert/update/delete SQL 실행	  	 
    * 2. 처리 개요 : 
    * 3. 주의사항 
    *
    * @param sQuery 실행 Query
    **/
    public void update(String sQuery) throws JDBCException {
        int nExeCnt = 0;
		try {
			getDsConnection();
			setAutoCommit(false);		  
			setStatement(sQuery);
			nExeCnt = executeUpdate();
			commit();
		}				
		catch (SQLException sqle) {		
			try { rollback(); } catch(Exception e) {
				trc_logger.error("rollback error");
			}
			//throw new JDBCException(sqle.getErrorCode(), sqle.getMessage());
			throw new JDBCException("SQLProc", "update", sqle);
		}
		finally {		  
			close();		  
		}
	}
    
    /** 
    * 1. 기능 :  insert/update/delete MULTI SQL 실행
    * 2. 처리 개요 : 
    * 3. 주의사항 
    *
    * @param saSql[] 실행 Query 배열
    **/
	public void update(String[] saSql) throws JDBCException {
		try {
			getDsConnection();
			setAutoCommit(false);
		  
			for( int i =0; i< saSql.length; i++) {
				setStatement(saSql[i]);         
				executeUpdate();
			}		  
			commit();
		}
		catch (SQLException sqle) {		
            try { rollback(); } catch(Exception r) {
            	trc_logger.error("rollback error");
            }
            //throw new JDBCException(sqle.getErrorCode(), sqle.getMessage());
            throw new JDBCException("SQLProc", "update", sqle);
		}
        catch (Exception e) {
            try { rollback(); } catch(Exception r) {
            	trc_logger.error("rollback error");
            }
            throw new JDBCException("SQLProc", "update", e);
        }
		finally {		  
            close();
		}
	}
    
    /**
     * 1. 기능 :  Query 검색
     * 2. 처리 개요 : 
     * 3. 주의사항 :
     * 
     * @return SQLData Object
     **/
    public SQLData select(String sQuery) throws JDBCException {
        return select(sQuery, 0, 0, 0);
    }
                                    
    /**
     * 1. 기능 :  Query 검색
     * 2. 처리 개요 : 
     * 3. 주의사항 :
     * 
     * @param sQuery        실행 query
     * @param nCurPageNum   현재 page 번호
     * @param nDispRowsCnt  한 화면에 보여줄수 있는 데이타수
     * @param nDispPagesCnt 한 화면에 보여줄수 있는 페이지수
     * @return SQLData Object
     **/
    public SQLData select(String sQuery, 
								int nCurPageNum, 
								int nDispRowsCnt, 
								int nDispPagesCnt) throws JDBCException {
		ResultSet rs = null;
         
        int nFromIndx = 0;
        int nOrderByIndx = 0; 
        String sCountQuery = "";
        
        SQLData dao_data = null; //데이타 object
        int nTotalDatasCnt = 0; //전체 데이타 수
        int nTotalPagesCnt = 0; //전체 페이지 수
        
        try {
            getDsConnection();
            if (nCurPageNum != 0 && nDispRowsCnt != 0 && nDispPagesCnt != 0) {
                nFromIndx = sQuery.toUpperCase().indexOf(" FROM ");     // From 절이 시작되는 자리의 값		 
				nOrderByIndx = sQuery.toUpperCase().indexOf("ORDER BY"); // ORDER BY 절이 시작되는 자리의 값
 
				if (nOrderByIndx != -1) {
					sCountQuery = new StringBuffer()
					   .append("SELECT count(*) ")
					   .append(sQuery.substring(nFromIndx + 1, nOrderByIndx)).toString();
				}
				else {
					sCountQuery = new StringBuffer()
					   .append("SELECT count(*) ")
					   .append(sQuery.substring(nFromIndx + 1)).toString();
				}            
            
                setStatement(sCountQuery);         
                rs = executeSelect();
                
                if (rs.next()) {
                    nTotalDatasCnt = rs.getInt(1);
                }
                
                try {
    				if (rs != null)
    					rs.close();
    			} 
                catch (Exception ex) {
    			}
                
                nTotalPagesCnt = nTotalDatasCnt / nDispRowsCnt;
                if (nTotalDatasCnt % nDispRowsCnt > 0) {
                   nTotalPagesCnt++;
                }
                
                //전체 페이지가 현재 페이지보다 작을 경우 마지막 페이지번호를 현재페이지로...
                if (nTotalPagesCnt < nCurPageNum) {
                    nCurPageNum = nTotalPagesCnt;
                }
            }
            
            //if(trc_logger.isDebug())  trc_logger.debug("DAO select query] nCurPageNum = " + nCurPageNum + "\n" + sQuery);
            setStatement(sQuery);
            rs = executeSelect();
            
            dao_data = setSQLData(rs, nCurPageNum, nDispRowsCnt,
                              nDispPagesCnt, nTotalDatasCnt,
                              nTotalPagesCnt);
            return dao_data;
            
        } 
        catch (SQLException sqle) {
        	throw new JDBCException("SQLProc", "select", sqle);
		}
        catch (Exception e) {
        	// System.out.println("select error - " + e.getMessage());
            throw new JDBCException("SQLProc", "select", e);
        } 
        finally {        	
            close(rs);
        }
    }
    
    /**
     * 1. 기능 :  검색된 데이타를 SQLData Object 설정
     * 2. 처리 개요 : 
     * 3. 주의사항 :
     * 
     * @param rs            ResultSet Object
     * @param nCurPageNum   현재 page 번호
     * @param nDispRowsCnt  한 화면에 보여줄수 있는 데이타수
     * @param nDispPagesCnt 한 화면에 보여줄수 있는 페이지수
     * @return SQLData Object
     **/
	public SQLData setSQLData(ResultSet rs, int nCurPagesNum, 
                             int nDispRowsCnt, int nDispPagesCnt, 
                             int nTotalDatasCnt, int nTotalPagesCnt)  throws JDBCException	{
	   try {
		   ResultSetMetaData rsmd = null;
		   int nColumnCnt = 0; // resultSet에 담아있는 data의 열수
		
		   SQLData dao_data = new SQLData(); // DATA OBJECT
		   rsmd = rs.getMetaData();
		   nColumnCnt = rsmd.getColumnCount(); // resultSet에 담아있는 data의 열수
		
		   // DAOData 객체의 hashtable에 넣을 행 값
		   int nRowsNum = 0;
		 
		   // SQLDATA 객체에 Column Name을 Set
		   for (int nIndx = 1; nIndx <= nColumnCnt; nIndx++) {
			   dao_data.setColumnName(rsmd.getColumnName(nIndx));
		   }
		
		   // page를 나누지 않을 경우
		   if (nCurPagesNum == 0 && nDispRowsCnt == 0 &&  nDispPagesCnt == 0) {
			   for (int nRowIndx = 0; rs.next(); nRowIndx++) {
				   for (int nColIndx = 1; nColIndx <= nColumnCnt; nColIndx++) {
					   // DAODATA 객체에 data를 set
					   dao_data.setHashData(nRowsNum, rsmd.getColumnName(nColIndx), rs.getString(rsmd.getColumnName(nColIndx)));			   
					   if (nColIndx == nColumnCnt) {
						   nRowsNum++; // hashtable의 행의 수 증가
					   }
				   }
				   nTotalDatasCnt++;
			   }
		   }
		   // page를 나눌경우
		   else {
			   for (int nRowIndx = 0; rs.next(); nRowIndx++) {
				   // display하는 page의 정보만을 DAODATA 객체 SET
				   if ( (nRowIndx >= ( (nCurPagesNum - 1) * nDispRowsCnt)) && (nRowIndx < (nCurPagesNum * nDispRowsCnt))) {
					   for (int nColIndx = 1; nColIndx <= nColumnCnt;nColIndx++) {
						   // DAODATA 객체에 Column Name을 Set
						   dao_data.setColumnName(rsmd.getColumnName(nColIndx));
		
						   // SQLDATA 객체에 data를 set
						   dao_data.setHashData(nRowsNum, rsmd.getColumnName(nColIndx), rs.getString(rsmd.getColumnName(nColIndx)));
		
						   if (nColIndx == nColumnCnt) {
							   nRowsNum++; // hashtable의 행의 수 증가
						   }
					   }
				   }
			   }
		   }
		 
		   // 페이지이동시 필요한 정보 SET 
		   dao_data.setCurrentPageNum(nCurPagesNum); 
		   dao_data.setDispRowsCount(nDispRowsCnt); 
		   dao_data.setDispPagesCount(nDispPagesCnt); 
		   dao_data.setTotalRowsCount(nTotalDatasCnt); 
		   dao_data.setTotalPagesCount(nTotalPagesCnt); 
		   dao_data.setTotalColumnsCount(nColumnCnt);
		
		 	return dao_data;
	   	}
	   	catch (Exception e) {		 
	   		trc_logger.error("setDAOData error - " + e.toString());
	   		throw new JDBCException("SQLProc", "setDAOData", e);
	   	}
	}
}
