// マスターDBキャッシュ用.
//

// すべてのスクリプト実行Map.
var SCRIPT_MAP = this ;

// マスタキャッシュ管理.
MasterCache = {
    // マスターキャッシュ情報を生成.
    create : function(name) {
        if( isNull( _$cachedb$params ) || useString( name ) == false ) {
            return null ;
        }
        if( isNull( SCRIPT_MAP[name] ) ||
            isNull( SCRIPT_MAP[name].isCacheMap ) ||
            SCRIPT_MAP[name].isCacheMap != true ) {
            return null ;
        }
        if( _$cachedb$params.containsKey( name ) ) {
            var o = _$cachedb$params.get( name ) ;
            if( objectClassName( o ) == "org.maachang.comet.httpd.engine.script.dao.MasterCacheChild" ) {
                if( o.isNoValue() == false ) {
                    return o.getValue() ;
                }
            }
            _$cachedb$params.remove( name ) ;
        }
        var model = SCRIPT_MAP[name] ;
        var ary = null ;
        if( model.isDeleteFlag == true ) {
            ary = model.find_by_deleteFlag( false,"id" ) ;
        }
        else {
            ary = model.find( null,null,"id" ) ;
        }
        if( isNull( ary ) == false && ary.length > 0 ) {
            var cmodel = {} ;
            cmodel["list"] = ary ;
            var map = {} ;
            var len = ary.length ;
            for( var i = 0 ; i < len ; i ++ ) {
                map[ ary[ i ].id ] = ary[ i ] ;
            }
            cmodel["map"] = map ;
            _$cachedb$params.putByCache( name,cmodel ) ;
            return cmodel ;
        }
        else {
            var cmodel = {list:[],map:{}} ;
            _$cachedb$params.putByCache( name,cmodel ) ;
            return cmodel ;
        }
    },
    
    // マスターキャッシュ情報をMap形式で取得.
    getCacheDB : function(name) {
        var ret = this.create(name) ;
        if( isNull( ret ) ) {
            return null ;
        }
        return ret['map'] ;
    },
    
    // マスターキャッシュ情報をリスト形式で取得.
    getCacheDBByList : function(name) {
        var ret = this.create(name) ;
        if( isNull( ret ) ) {
            return null ;
        }
        return ret['list'] ;
    },
    
    // マスターキャッシュ削除.
    remove : function( name ) {
        if( isNull( _$cachedb$params ) || isNull( name ) ) {
            return ;
        }
        _$cachedb$params.remove( name ) ;
    },
    
    // 指定したDB名がキャッシュ化されているかチェック.
    containsKey : function( name ) {
        if( isNull( _$cachedb$params ) || isNull( name ) ) {
            return false ;
        }
        return _$cachedb$params.containsKey( name ) ;
    },
    
    // 現在存在するキャッシュ情報をリセット.
    resetCacheDB : function() {
        if( isNull( _$cachedb$params ) ) {
            return ;
        }
        var it = _$cachedb$params.getMap().keySet().iterator() ;
        while( it.hasNext() ) {
            this.remove( it.next() ) ;
        }
    },
    
    // 単体内容チェック.
    _chkToLike : function( c1,c2 ) {
        // like検索のような感じで行う.
        if( startsWith( c2,"%" ) ) {
            if( endsWith( c2,"%" ) ) {
                if( c1.indexOf( c2.substring( 1,c2.length-1 ) ) <= -1 ) {
                    return false ;
                }
            }
            else {
                if( startsWith( c1,c2.substring( 1 ) ) == false ) {
                    return false ;
                }
            }
        }
        else if( endsWith( c2,"%" ) ) {
            if( endsWith( c1,c2.substring( 0,c2.length-1 ) ) == false ) {
                return false ;
            }
        }
        else {
            if( c1 != c2 ) {
                return false ;
            }
        }
        return true ;
    },
    
    // データベース名に変換.
    _convertDatabaseName : function( name ) {
        return name.substring( 0,1 ).toUpperCase() + name.substring( 1 ) ;
    },
    
    // MasterCacheから、一致する条件を検索.
    find : function( name,where,offset,limit ) {
        var res = this.create( name ) ;
        if( isNull( res ) || isNull( res['list'] ) || res['list'].length <= 0 ) {
            return [] ;
        }
        if( isNull( offset ) || isNumeric( offset ) == false || offset < 0 ) {
            offset = 0 ;
        }
        if( isNull( limit ) || isNumeric( limit ) == false || limit < 0 ) {
            limit = -1 ;
        }
        
        // 検索条件が存在しない場合.
        if( isNull( where ) || valueof( where ) != "map" ) {
            // 範囲取得の場合は、部分ごとで取得する.
            if( offset >= 0 || limit >= 0 ) {
                var lst = res['list'] ;
                var len = lst.length ;
                var ret = [] ;
                for( var i = offset ; i < len ; i ++ ) {
                    ret[ ret.length ] = cloneMap( lst[ i ] ) ;
                    if( limit > 0 && ret.length >= limit ) {
                        return ret ;
                    }
                }
                return ret ;
            }
            return res['list'] ;
        }
        // 検索条件が存在する場合.
        var ret = [] ;
        var lst = res['list'] ;
        var len = lst.length ;
        for( var i = offset ; i < len ; i ++ ) {
            var x = lst[ i ] ;
            var f = true ;
            for( var k in where ) {
                var w = where[ k ] ;
                var t = valueof( w ) ;
                // orでチェック.
                if( t == "array" ) {
                    var lenJ = w.length ;
                    var fj = false ;
                    for( var j = 0 ; j < lenJ ; j ++ ) {
                        if( this._chkToLike( x[ k ],w[ j ] ) == false ) {
                            fj = true ;
                            break ;
                        }
                    }
                    if( fj == false ) {
                        f = false ;
                        break ;
                    }
                }
                // 範囲チェック.
                else if( t == "map" ) {
                    var min = w['min'] ;
                    var max = w['max'] ;
                    // 範囲指定の用件でない場合は無視する.
                    if( isNull( min ) || isNull( max ) ) {
                        continue ;
                    }
                    if( (x[ k ] >= min && x[ k ] <= max) == false ) {
                        f = false ;
                        break ;
                    }
                }
                else {
                    if( this._chkToLike( x[ k ],w ) == false ) {
                        f = false ;
                        break ;
                    }
                }
            }
            if( f ) {
                ret[ ret.length ] = cloneMap( x ) ;
                if( limit > 0 && ret.length >= limit ) {
                    break ;
                }
            }
        }
        return ret ;
    },
    
    // MasterCacheから、一致する条件の数を検索.
    count : function( name,where ) {
        var res = this.create( name ) ;
        if( isNull( res ) || isNull( res['list'] ) || res['list'].length <= 0 ) {
            return 0 ;
        }
        
        if( isNull( where ) || valueof( where ) != "map" ) {
            return res['list'].length ;
        }
        var ret = 0 ;
        var lst = res['list'] ;
        var len = lst.length ;
        for( var i = 0 ; i < len ; i ++ ) {
            var x = lst[ i ] ;
            var f = true ;
            for( var k in where ) {
                var w = where[ k ] ;
                var t = valueof( w ) ;
                // orでチェック.
                if( t == "array" ) {
                    var lenJ = w.length ;
                    var fj = false ;
                    for( var j = 0 ; j < lenJ ; j ++ ) {
                        if( this._chkToLike( x[ k ],w[ j ] ) == false ) {
                            fj = true ;
                            break ;
                        }
                    }
                    if( fj == false ) {
                        f = false ;
                        break ;
                    }
                }
                // 範囲チェック.
                else if( t == "map" ) {
                    var min = w['min'] ;
                    var max = w['max'] ;
                    // 範囲指定の用件でない場合は無視する.
                    if( isNull( min ) || isNull( max ) ) {
                        continue ;
                    }
                    if( (x[ k ] >= min && x[ k ] <= max) == false ) {
                        f = false ;
                        break ;
                    }
                }
                // 通常チェック.
                else {
                    if( this._chkToLike( x[ k ],w ) == false ) {
                        f = false ;
                        break ;
                    }
                }
            }
            if( f ) {
                ret ++ ;
            }
        }
        return ret ;
    },
}

// マスターキャッシュパラメータ.
cacheDBParams = function() {
    return new JSAdapter({
        __get__ : function(name) {
            // 先頭に＄が付加されている.
            if( startsWith( name,"$" ) ) {
                // 先頭が[$find_]の場合は、Find処理を行う.
                if( startsWith( name,"$find_" ) ) {
                    var dbName = MasterCache._convertDatabaseName( name.substring( "$find_".length ) ) ;
                    return function( where,offset,limit ) {
                        return MasterCache.find( dbName,where,offset,limit ) ;
                    }
                }
                // 先頭が[$count_]の場合は、count処理を行う.
                else if( startsWith( name,"$count_" ) ) {
                    var dbName = MasterCache._convertDatabaseName( name.substring( "$count_".length ) ) ;
                    return function( where ) {
                        return MasterCache.count( dbName,where ) ;
                    }
                }
                // 先頭に＄が２つ存在する場合は、名前をキーとして処理する.
                else if( startsWith( name,"$$" ) || startsWith( name,"$key_" ) ) {
                    if( startsWith( name,"$$" ) ) {
                        name = MasterCache._convertDatabaseName( name.substring( "$$".length ) ) ;
                    }
                    else {
                        name = MasterCache._convertDatabaseName( name.substring( "$key_".length ) ) ;
                    }
                    var res = MasterCache.create( name ) ;
                    if( isNull( res ) || isNull( res['list'] ) || res['list'].length <= 0 ) {
                        return {} ;
                    }
                    var lst = res['list'] ; 
                    if( isNull( lst[ 0 ].name ) ) {
                        return {} ;
                    }
                    var len = lst.length ;
                    var ret = {} ;
                    for( var i = 0 ; i < len ; i ++ ) {
                        ret[ lst[ i ].name ] = lst[ i ].id ;
                    }
                    return ret ;
                }
                // 先頭に＄が存在する場合は、Array配列で返す.
                else if( startsWith( name,"$" ) ) {
                    name = MasterCache._convertDatabaseName( name.substring( 1 ) ) ;
                    var res = MasterCache.create( name ) ;
                    if( isNull( res ) || isNull( res['list'] ) || res['list'].length <= 0 ) {
                        return [] ;
                    }
                    return res['list'] ;
                }
            }
            // ＄が先頭にない場合はMAP形式で返す.
            var ret = MasterCache.getCacheDB( MasterCache._convertDatabaseName( name ) ) ;
            if( isNull( ret ) ) {
                return {} ;
            }
            return ret ;
        },
        __has__ :  function(name) {
            if( startsWith( name,"$" ) ) {
                if( startsWith( name,"$find_" ) ) {
                    return MasterCache.containsKey( MasterCache._convertDatabaseName( name.substring( "$find_".length ) ) ) ;
                }
                else if( startsWith( name,"$count_" ) ) {
                    return MasterCache.containsKey( MasterCache._convertDatabaseName( name.substring( "$count_".length ) ) ) ;
                }
                else if( startsWith( name,"$key_" ) ) {
                    return MasterCache.containsKey( MasterCache._convertDatabaseName( name.substring( "$key_".length ) ) ) ;
                }
                else if( startsWith( name,"$$" ) ) {
                    return MasterCache.containsKey( MasterCache._convertDatabaseName( name.substring( "$$".length ) ) ) ;
                }
                else if( startsWith( name,"$" ) ) {
                    return MasterCache.containsKey( MasterCache._convertDatabaseName( name.substring( 1 ) ) ) ;
                }
            }
            return MasterCache.containsKey( MasterCache._convertDatabaseName( name ) ) ;
        },
        __delete__ : function (name) {
            return null
        },
        __put__ : function(name, value) {
            return null ;
        },
        __getIds__ : function() {
            return null ;
        }
    });
} ;

// 

///////////////////////////////////////////////////////////////////////////////
// キャッシュDBパラメータ展開.
///////////////////////////////////////////////////////////////////////////////
cacheDB = cacheDBParams() ;

