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

import com.eactive.eai.common.dao.Keys;
import com.eactive.eai.common.util.ServiceLocator;

import javax.sql.DataSource;
import java.sql.*;

/** 
* 1. 기능 : DB Operation을 위한 JDBC 추상 클래스
* 2. 처리 개요 : 
* 3. 주의사항 
*
* @author  : 
* @version : v 1.0.0
* @see : 
* @since   : 
*/
public abstract class BaseJDBC
{
    /**
     * JDBC Connection object
     */
    protected Connection conn;
    
    /**
     * JDBC preparedStatement object
     */
    protected PreparedStatement preparedStatement;
    
     /**
     * JDBC Statement object
     */
    protected Statement Statement;
    
     /**
     * JDBC DataSource JNDI 이름
     */
    protected String jndiName;
    
    /** 
    * 1. 기능 :  Default Constructor
    * 2. 처리 개요 : 
    * 3. 주의사항 
    *
    **/
    public BaseJDBC() {
        this.jndiName = Keys.EAI_DATASOURCE;
    }
    
    /** 
    * 1. 기능 :  JNDI 설정
    * 2. 처리 개요 : 
    *     - 
    * 3. 주의사항 
    *
    * @param jndiDataSource jndi 이름
    **/
    protected void setJNDIName(String jndiDataSource) {
        this.jndiName = jndiDataSource;
    }
    
    /** 
    * 1. 기능 :  PreparedStatement객체 획득	
    * 2. 처리 개요 : 
    *     - 
    * 3. 주의사항 
    *
    * @param sql 실행 query
    **/
    public PreparedStatement getStatement(String sql) throws SQLException {
		return conn.prepareStatement(sql);
	}
    
   /** 
    * 1. 기능 :  auto-commit 모드 설정 
    * 2. 처리 개요 : 
    *     - 
    * 3. 주의사항 
    *
    * @param b_autoCommit (true to enable auto-commit mode; false to disable it )
    **/
    public void setAutoCommit(boolean b_autoCommit) throws SQLException	{
        conn.setAutoCommit(b_autoCommit);        
	}
    
    /** 
    * 1. 기능 :  commit 실행
    * 2. 처리 개요 : 
    * 3. 주의사항 
    **/
    public void commit() throws SQLException {
        conn.commit();
        setAutoCommit(true);
	}
    
    /** 
    * 1. 기능 :  rollback 실행
    * 2. 처리 개요 : 
    * 3. 주의사항 
    **/
    public void rollback() throws SQLException {
        conn.rollback();
        setAutoCommit(true);
	}
    
    /** 
    * 1. 기능 :  close 실행
    * 2. 처리 개요 :  Connection object 및 JDBC resources 반환
    * 3. 주의사항 
    **/
    public void close() {
        close(null);
    }
    
    /** 
    * 1. 기능 :  close 실행
    * 2. 처리 개요 :  Connection object 및 JDBC resources 반환
    * 3. 주의사항 
    * 
    * @param rs ResultSet Object
    **/
	public void close(ResultSet rs) {
        if (rs != null) {
            try{ rs.close(); } catch (Exception ignore) {}
        }
		if (preparedStatement != null) {
            try { preparedStatement.close(); } catch (Exception ignore) {}
        }
        if (Statement != null) {
            try { Statement.close(); } catch (Exception ignore) {}
        }
		if (conn != null) {
		      try { conn.close(); } catch (Exception ignore) {}
		}
    }
    
    /** 
    * 1. 기능 :  검색 query 실행 
    * 2. 처리 개요 :  preparedStatement Object에 query 실행 
    * 3. 주의사항 
    * 
    * @result rs ResultSet Object
    **/
    public ResultSet executeSelect() throws SQLException {  
    	ResultSet rs = preparedStatement.executeQuery();
		return rs;
	}
    
    /** 
    * 1. 기능 :  변경 query 실행 
    * 2. 처리 개요 :  preparedStatement Object에 query 실행 
    * 3. 주의사항 
    * 
    * @result rs ResultSet Object
    **/
    public int executeUpdate() throws SQLException {
    	return preparedStatement.executeUpdate();
	}
       
    /** 
    * 1. 기능 :  query 설정
    * 2. 처리 개요 :  preparedStatement Object에 query 설정 
    * 3. 주의사항 
    * 
    * @result rs ResultSet Object
    **/ 
    public void setStatement(String query) throws SQLException {
        if (preparedStatement != null) try { preparedStatement.close(); } catch(SQLException e) {}
        preparedStatement = conn.prepareStatement(query);		 
        preparedStatement.clearParameters();
		//preparedStatement.setQueryTimeout(300); // 단위 초
    }

    /** 
    * 1. 기능 :  JDBC Connection 생성
    * 2. 처리 개요 : 
    * 3. 주의사항 
    *
    * @exception    JDBCException JDBC 에러
    ***/
    public void getDsConnection() throws JDBCException {
        DataSource dataSource = null;
        try {            
            dataSource = getDataSource(jndiName);
            if(dataSource == null) {
            	throw new Exception("datasource is NULL - "+jndiName); 
            }
            conn = dataSource.getConnection();
        } 
        catch(Exception e) {              
        	throw new JDBCException("["+jndiName+"] connection을 얻을 수 없습니다.");
        }
    }
    
    /** 
    * 1. 기능 :  JNDI 서비스로부터 JDBC DataSource 반환
    * 2. 처리 개요 : 
    * 3. 주의사항 
    *
    * @exception    JDBCException JDBC 에러
    ***/
    private DataSource getDataSource(String dataSourceName) throws JDBCException {
		DataSource dataSource = null;
        try {
            ServiceLocator sl = ServiceLocator.getInstance();
            dataSource = sl.getDataSource(jndiName);
            return dataSource;
        }  
        catch (Exception e) {   
            throw new JDBCException("["+jndiName+"]을 얻을 수 없습니다.");
        }
	} 
} 
