/**
 * Copyright (c) 2003-2004 System Integrator Corporation.
 *                 All Rights Reserved.
 */
package jp.co.sint.database;

import java.util.*;
import java.sql.*;
import org.apache.log4j.Category;
import jp.co.sint.config.*;

/**
 * @version $Id: SIExecute.java,v 1.0 Exp $
 * @author     : Jinwang Chen
 * <br>Description: テーブルに新規レコード＆既存レコードを作成するSQL文を構成します。
 * <p>History</p>
 * <p>Author&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Date&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Reason</p>
 * ============&nbsp;&nbsp;&nbsp;==========&nbsp;&nbsp;===========================<br>
 * J.W.Chen       2003/07/25  Original
 */

public abstract class SIExecute {

  //ログ用のインスタンスの生成
  private static Category log=Category.getInstance(SIConfig.SILOG4J_WEBSHOP_CATEGORY_NAME);
  //テーブル名
  protected String tableName;

  //SQL文
  protected String sQL="";

  //insertあるいは、修正するとき、設定する項目名と値のpair
  protected HashMap valuesMap=new HashMap();

  /**
   * <b>SIExecute</b>
   * コンストラクタ
   * @param  なし
   * @return なし
   * @throws なし
   */
  public SIExecute(){}

  /**
   * <b>setTableName</b>
   * テーブル名を設定します。
   * @param  なし
   * @return なし
   * @throws なし
   */
  public void setTableName(String lTableName){
    this.tableName =lTableName;
  }

  /**
   * <b>getTableName</b>
   * テーブル名を取得します。
   * @param  なし
   * @return テーブル名
   * @throws なし
   */
  public String getTableName(){
    return this.tableName;
  }

  /**
   * <b>add</b>
   * 項目名と値のpairを追加します。
   * @param  lName 項目名
   * @return lValue 上記の項目名に対する値
   * @throws なし
   */
  public void add(String lName,String lValue){
    valuesMap.put(lName,lValue);
  }

  /**
   * <b>add</b>
   * 項目名と値のpairを追加します。
   * @param  lName 項目名
   * @return lValue 上記の項目名に対する値
   * @throws なし
   */
  public void add(String lName,int lValue){
    valuesMap.put(lName,new Integer(lValue));
  }

  /**
   * <b>add</b>
   * 項目名と値のpairを追加します。
   * @param  lName 項目名
   * @return lValue 上記の項目名に対する値
   * @throws なし
   */
  public void add(String lName,long lValue){
    valuesMap.put(lName,new Long(lValue));
  }

  /**
   * <b>add</b>
   * 項目名と値のpairを追加します。
   * @param  lName 項目名
   * @return lValue 上記の項目名に対する値
   * @throws なし
   */
  public void add(String lName,float lValue){
    valuesMap.put(lName,new Float(lValue));
  }

  /**
   * <b>add</b>
   * 項目名と値のpairを追加します。
   * @param  lName 項目名
   * @return lValue 上記の項目名に対する値
   * @throws なし
   */
  public void add(String lName,SISpcType lValue){
    valuesMap.put(lName,lValue);
  }

  /**
   * <b>execute</b>
   * 実行SQL文を取得して、実行します。
   * @param  lConnection データベースへのコネクション
   * @return なし
   * @throws SIDuplicateKeyException
   * @throws SIDBAccessException
   */
  public void execute(Connection lConnection) throws SIDuplicateKeyException,SIDBAccessException{

    log.debug("execute:getSQL="+this.getSQL());
    Statement lStatement=null;
    String test="";
    try {
      lStatement=lConnection.createStatement();
      lStatement.execute(this.getSQL());
    }catch(SQLException sqle) {
      log.debug("sqle.toString()="+sqle.toString());
      if (SIDBMultiConf.SIDB_CURRENT_INX==SIDBMultiConf.SIDB_POSTGRESQL_INX){
        if (sqle.toString().indexOf("insert a duplicate key")!=-1) throw new SIDuplicateKeyException("Cannot insert a duplicate key");
        else throw new SIDBAccessException("update database error.");
      }else{
        if (sqle.getErrorCode()==1) throw new SIDuplicateKeyException("Cannot insert a duplicate key");
        else throw new SIDBAccessException("update database error.");
      }
    }finally{
      try {if (lStatement!=null) lStatement.close();}catch(SQLException sqle){}
    }
  }

  /**
   * <b>execute</b>
   * 実行SQL文を取得して、実行します。
   * @param  lConnection データベースへのコネクション
   * @param  String SQL
   * @return なし
   * @throws SIDuplicateKeyException
   * @throws SIDBAccessException
   */
  public void execute(Connection lConnection,String sql) throws SIDuplicateKeyException,SIDBAccessException{

	log.debug("execute:getSQL="+sql);
	Statement lStatement=null;
	String test="";
	try {
	  lStatement=lConnection.createStatement();
	  lStatement.execute(sql);
	}catch(SQLException sqle) {
	  log.debug("sqle.toString()="+sql);
	  if (sqle.toString().indexOf("insert a duplicate key")!=-1) throw new SIDuplicateKeyException("Cannot insert a duplicate key");
	  else throw new SIDBAccessException("update database error.");
	}finally{
	  try {if (lStatement!=null) lStatement.close();}catch(SQLException sqle){}
	}
  }

	/**
	 * <b>setSQL</b>
	 * 実行のSQL文を設定するために、abstractのメソッド
	 * @param  なし
	 * @return なし
	 * @throws なし
	 */
	public abstract void setSQL(String lSQL);

  /**
   * <b>getSQL</b>
   * 実行のSQL文を取得するために、abstractのメソッド
   * @param  なし
   * @return なし
   * @throws なし
   */
  public abstract String getSQL();
}