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;
    
    /**
     * デバッグモード.
     */
    private boolean debug = false ;
    
    /**
     * コンストラクタ.
     */
    public RecordFactory() {
    
    }
    
    /**
     * デストラクタ.
     */
    protected void finalize() throws Exception {
        this.clear() ;
    }

    /**
     * オブジェクト生成. 
     * @param kind 対象のDBMS種類を設定します.
     * @param debug 対象のデバッグモードを設定します.
     * @param driver 対象のJDBCドライバ名を設定します.
     * @param url JDBC接続先URLを設定します.
     * @param user JDBC接続ユーザ名を設定します.
     * @param passwd JDBC接続パスワードを設定します.
     * @param keepAlive アイドル時の破棄時間を設定します.
     * @param max プーリング最大数を設定します.
     * @param checkSQL 接続確認用SQL文を設定します.
     * @param readOnly 接続オブジェクトを読み込み専用にするか設定します.
     * @param autoCommit オートコミットを行う場合は[true]を設定します.
     * @exception Exception 例外.
     */
    public void create(SupportKind kind,boolean debug,String driver,String url, String user, 
            String passwd,long keepAlive,int max,String checkSQL,boolean readOnly,boolean autoCommit) 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 ;
        
        // コネクションオブジェクトを取得.
        ConnectManager manager = ConnectPoolFactory.get( driver,url,user,passwd,keepAlive,max,checkSQL,readOnly,autoCommit ) ;
        
        // メンバー変数に設定.
        this.manager = manager;
        
        // debug.
        this.debug = debug ;
        
        // MetaFactory初期化.
        MetaFactory.getInstance().init( this ) ;
    }

    /**
     * 情報クリア.
     * <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("コネクションオブジェクトの取得に失敗しました");
        }
        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;
    }
}
