package org.maachang.dao.dbms;

import java.io.IOException;
import java.sql.Connection;

import org.maachang.dao.dbms.kind.SupportKind;
import org.maachang.dao.dbms.pool.ConnectManager;
import org.maachang.dao.dbms.pool.ConnectPoolFactory;

/**
 * レコード管理.
 * 
 * @version 2007/10/18
 * @author masahito suzuki
 * @since MaachangDao 1.00
 */
public class RecordFactory {

    /**
     * サポートDB種類情報.
     */
    private SupportKind kind = null ;
    
    /**
     * レコード管理オブジェクト.
     */
    private ConnectManager manager = null;
    
    /**
     * AutoCommitモード.
     */
    private boolean autoCommit = false ;
    
    /**
     * デバッグモード.
     */
    private boolean debug = false ;

    /**
     * コンストラクタ.
     */
    public RecordFactory() {

    }

    /**
     * デストラクタ.
     */
    protected void finalize() throws Exception {
        this.clear() ;
    }

    /**
     * オブジェクト生成. <BR>
     * <BR>
     * コネクション条件を設定してオブジェクトを生成します. <BR>
     * 
     * @param kind
     *            対象のDBMS種類を設定します.
     * @param debug
     *            対象のデバッグモードを設定します.
     * @param driver
     *            対象のドライバ名を設定します.
     * @param url
     *            接続先のURLを設定します.
     * @param user
     *            対象のユーザ名を設定します.
     * @param passwd
     *            対象のポート番号を設定します.
     * @param max
     *            最大プーリングコネクション管理要素を設定します.
     * @param autoCommit
     *            AutoCommitモードを設定します.
     * @param checkSQL
     *            コネクションチェックSQLを設定します.
     * @exception Exception
     *                例外.
     */
    public void create(SupportKind kind,boolean debug,String driver, String url, String user, String passwd,
            int max, boolean autoCommit,String checkSQL) throws Exception {
        if (driver == null || (driver = driver.trim()).length() <= 0
                || url == null || (url = url.trim()).length() <= 0) {
            throw new IllegalArgumentException("必須条件[adapter or driver or url]が設定されていません");
        }
        else if( kind == null ) {
            throw new IllegalArgumentException("非サポートのDBMS種類が設定されています");
        }
        // アダプタ名を設定.
        this.kind = kind ;
        // ドライバをロード.
        Class.forName(driver);
        // コネクションオブジェクトを取得.
        ConnectManager manager = ConnectPoolFactory.get(url, user, passwd, max,
                checkSQL);
        // AutoCommitモード.
        this.autoCommit = autoCommit ;

        // メンバー変数に設定.
        this.manager = manager;
        
        // debug.
        this.debug = debug ;
    }

    /**
     * 情報クリア.
     * <BR><BR>
     * 情報をクリアします.
     */
    public void clear() {
        if( manager != null ) {
            manager.destroy() ;
        }
        kind = null ;
        manager = null;
    }

    /**
     * 新しいレコードオブジェクトを取得. <BR>
     * <BR>
     * 新しいレコードオブジェクトを取得します. <BR>
     * 
     * @return Record 新しいレコードオブジェクトが返されます.
     * @exception Exception
     *                例外.
     */
    public Record getRecord() throws Exception {
        Connection conn = manager.getConnection();
        if (conn == null) {
            throw new IOException("コネクションオブジェクトの取得に失敗しました");
        }
        conn.setAutoCommit( autoCommit ) ;
        return new BaseRecord(kind,debug,conn);
    }

    /**
     * サポートDBMS種類オブジェクトを取得.
     * <BR><BR>
     * サポートDBMS種類オブジェクトを取得します.
     * <BR>
     * @return SupportKind サポートDBMS種類が返されます.
     */
    public SupportKind getSupportKind() {
        return kind ;
    }

    /**
     * コネクションマネージャを取得. <BR>
     * <BR>
     * コネクションマネージャを取得します. <BR>
     * 
     * @return ConnectManager コネクションマネージャが返されます.
     */
    public ConnectManager getConnectionManager() {
        return manager;
    }
    
    /**
     * AutoCommitモードを取得.
     * <BR><BR>
     * AutoCommitモードを取得します.
     * <BR>
     * @return boolean [true]の場合はAutoCommitが有効です.
     */
    public boolean isAutoCommit() {
        return autoCommit ;
    }
}
