package org.maachang.mimdb.core;

import java.lang.ref.SoftReference;

import org.maachang.mimdb.MimdbException;
import org.maachang.mimdb.core.util.ObjectKeyValue;


/**
 * 組み込み用コネクションオブジェクト.
 * 
 * @version 2014/01/16
 * @author masahito suzuki
 * @since MasterInMemDB 1.02
 */
final class EmbeddedConnection extends MimdbConnection {
    
    /** プリコンパイル済みオブジェクト管理. **/
    protected ObjectKeyValue<String,SoftReference<QueryCompileInfo>> preparedList =
        new ObjectKeyValue<String,SoftReference<QueryCompileInfo>>() ;
    
    /** ステートメント. **/
    protected EmbeddedStatement statement = null ;
    
    /** クローズフラグ. **/
    private boolean closeFlag = false ;
    
    /** コンストラクタ. **/
    protected EmbeddedConnection() {
        statement = new EmbeddedStatement( this ) ;
    }
    
    /** ファイナライズ. **/
    protected final void finalize() throws Exception {
        close() ;
    }
    
    /**
     * オブジェクトクローズ.
     */
    public final void close() {
        closeFlag = true ;
        if( preparedList != null ) {
            preparedList.clear() ;
            preparedList = null ;
        }
        statement = null ;
    }
    
    /**
     * オブジェクトがクローズしているか取得.
     * @return boolean [true]の場合、クローズしています.
     */
    public final boolean isClose() {
        return closeFlag ;
    }
    
    /** チェック処理. **/
    protected final void check() {
        if( closeFlag ) {
            throw new MimdbException( "オブジェクトは既にクローズしています" ) ;
        }
    }
    
    /**
     * テーブルオブジェクトを取得
     * @param name 対象のテーブル名を設定します.
     * @return BaseTable テーブルオブジェクトが返却されます.
     * @exception Exception 例外.
     */
    public final BaseTable getTable( String name )
        throws Exception {
        BaseTable ret = MimdbTableManager.getInstance().get( name ) ;
        if( ret == null ) {
            throw new MimdbException( "テーブル名[" + name + "]は存在しません" ) ;
        }
        return ret ;
    }
    
    /**
     * ステートメントオブジェクトを取得.
     * @exception Exception 例外.
     */
    public final MimdbStatement getStatement()
        throws Exception {
        check() ;
        statement.clearOffLimit() ;
        return statement ;
    }
    
    /**
     * プリコンパイル済みのステートメントオブジェクトを取得.
     * @param sql 対象のSQL文を設定します.
     * @return MimdbPreparedStatement プリコンパイル済みオブジェクトが返却されます.
     * @exception Exception 例外.
     */
    public final MimdbPreparedStatement getPreparedStatement( final String sql )
        throws Exception {
        check() ;
        QueryCompileInfo info ;
        SoftReference<QueryCompileInfo> o = preparedList.get( sql ) ;
        if( o == null || ( info = o.get() ) == null ) {
            preparedList.remove( sql ) ;
            info = MimdbQuery.createCompile( sql ) ;
            preparedList.put( sql,new SoftReference<QueryCompileInfo>( info ) ) ;
        }
        return new EmbeddedPreparedStatement( this,info ) ;
    }
    
}

