// record実装.
//

////////////////////////////////////////////////////////////////////////////////
// Record系.
////////////////////////////////////////////////////////////////////////////////

// モデル情報を取得.
script_model = function() {
    return _$script$base_model ;
} ;

// BaseModel生成用.
create_base_model = function() {
    // dummy-baseModelの場合は、生成されたことにする.
    if( script_model().isType() == false ) {
        return true ;
    }
    if( _$$maachang_comet_manager.get( "DBMS_POOL" )  == null ) {
        return false ;
    }
    if( script_model().isCreate() == false ) {
        script_model().create(
            (__$type$script != "console" ),
            _$script$context,
            _$$maachang_comet_manager.get( "DBMS_POOL" ).getRecord() ) ;
    }
    return true ;
} ;

// データベースコミット.
commit = function() {
    if( script_model().isCreate() == true ) {
        script_model().commit() ;
    }
} ;

// データベースロールバック.
rollback = function() {
    if( script_model().isCreate() == true ) {
        script_model().rollback() ;
    }
} ;

// SQL文を実行.
sql = function( sql ) {
    if( create_base_model() == false ) {
        return null ;
    }
    if( script_model().isCreate() == true ) {
        var ret = script_model().sql( sql ) ;
        if( ret == null ) {
            return null ;
        }
        else if( ret instanceof java.lang.Integer ) {
            return ""+ret ;
        }
        else if( ret instanceof java.lang.String ) {
            return ""+ret ;
        }
        return SubModel.convertResultByJList( ret ) ;
    }
    return null ;
} ;

////////////////////////////////////////////////////////////////////////////////
// Model-Sub定義.
////////////////////////////////////////////////////////////////////////////////

// サブModelメソッド群用オブジェクト.
SubModel = function() {} ;

// 予約カラム名.
SubModel.COLUMN_ID = org.maachang.dao.dbms.DbUtil.convertDBNameByJavaName(
    false,org.maachang.dao.ExecutionDao.SEQ_COLUMN ) ;
SubModel.COLUMN_CREATE_TIME = org.maachang.dao.dbms.DbUtil.convertDBNameByJavaName(
    false,org.maachang.dao.ExecutionDao.CREATE_TIME ) ;
SubModel.COLUMN_UPDATE_TIME = org.maachang.dao.dbms.DbUtil.convertDBNameByJavaName(
    false,org.maachang.dao.ExecutionDao.UPDATE_TIME ) ;
SubModel.COLUMN_OPTIMISTIC_LOCK = org.maachang.dao.dbms.DbUtil.convertDBNameByJavaName(
    false,org.maachang.dao.ExecutionDao.OPTIMISTIC_LOCK_COLUMN ) ;

// 楽観的ロックエラーパラメータ格納名.
SubModel.ERROR_OPTIMISTIC_LOCK = "~error_optimisticLock" ;

// 日付カラムタイプを示すオブジェクト.
SubModel.OUTPUT_DATE_TYPE = "new Date:" ;

// dbmap.
SubModel.dbmap = function(map) {
    if( isNull( map ) || ( map instanceof java.util.Map ) == false ) {
        return null ;
    }
    return new JSAdapter({
        __get__ : function(name) {
            if( "core" == name ) {
                return map ;
            }
            if (map.containsKey(name)) {
                var ret = map.get(name);
                return parseValue( ret ) ;
            }
            else if( name == "toString" ) {
                var ret = "{" ;
                var o = map.keySet().toArray() ;
                if( o != null && o.length > 0 ) {
                    var len = o.length ;
                    var cnt = 0 ;
                    for( var i = 0 ; i < len ; i ++ ) {
                        var x = org.maachang.comet.httpd.engine.script.js.JsDef.getArray( o,i ) ;
                        if( cnt != 0 ) {
                            ret += " ," ;
                        }
                        var v = map.get( x ) ;
                        if( v != null ) {
                            if( className( v ) == "JSAdapter" ) {
                                ret += x + ": " + "\""+v.toString+"\"" ;
                            }
                            else {
                                ret += x + ": " + "\""+v+"\"" ;
                            }
                        }
                        else {
                            ret += x + ": \"\"" ;
                        }
                        cnt ++ ;
                    }
                }
                ret += "}" ;
                return ret ;
            }
            else if( name == "length" ) {
                var ret = map.size() ;
                if( isNull( ret ) == true ) {
                    return null ;
                }
                else if( useString( ret ) == false ) {
                    return "" ;
                }
                return parseValue(ret) ;
            }
            else {
                return null ;
            }
        },
        __has__ :  function(name) {
            return map.containsKey(name);
        },
        __delete__ : function (name) {
            if (map.containsKey(name)) {
                map.remove(name) ;
            }
        },
        __put__ : function(name, value) {
            map.put(name, value);
        },
        __getIds__ : function() {
            return map.keySet().toArray();
        },
        toString: function() {
            var ret = "{" ;
            var it = map.keySet().iterator() ;
            var cnt = 0 ;
            for( var x = it.next() ;it.hasNext() ; x = it.next() ) {
                var v = map.get( x ) ;
                if( v != null ) {
                    if( cnt != 0 ) {
                        ret += " ," ;
                    }
                    var v = map.get( x ) ;
                    if( v != null ) {
                        if( className( v ) == "JSAdapter" ) {
                            ret += x + ": " + "\""+v.toString+"\"" ;
                        }
                        else {
                            ret += x + ": " + "\""+v+"\"" ;
                        }
                    }
                    else {
                        ret += x + ": \"\"" ;
                    }
                    cnt ++ ;
                }
            }
            ret += "}" ;
            return ret ;
        },
        length: function() {
            var ret = map.size() ;
            if( isNull( ret ) == true ) {
                return null ;
            }
            else if( useString( ret ) == false ) {
                return "" ;
            }
            ret = parseValue( ret ) ;
            return ret ;
        }
    });
} ;

// パラメータをHashMapに変換.
SubModel.convertParamByMap = function(params) {
    if( isNull( params ) || params.length <= 0 ) {
        return null ;
    }
    var ret = new java.util.HashMap() ;
    for( var k in params ) {
        if( k == SubModel.ERROR_OPTIMISTIC_LOCK ) {
            continue ;
        }
        var x = params[k] ;
        x = SubModel.convertOneParam( x ) ;
        ret.put( k,x ) ;
    }
    return ret ;
}

// 指定リストをArrayListに変換.
SubModel.convertParamByList = function( params ) {
    if( isNull( params ) || params.length <= 0 ) {
        return null ;
    }
    var ret = new java.util.ArrayList() ;
    var len = params.length ;
    for( var i = 0 ; i < len ; i ++ ) {
        var x = params[ i ] ;
        x = SubModel.convertOneParam( x ) ;
        ret.add( x ) ;
    }
    return ret ;
}

// 指定条件を変換.
SubModel.convertOneParam = function( x ) {
    if( isNull( x ) == false ) {
        var clz_x = className( x ) ;
        var type_x = typeof(x) ;
        if( type_x == "object" ) {
            if( clz_x == "NativeDate" ) {
                x = org.maachang.comet.httpd.engine.script.dao.DaoUtil.convertStringByDate( x.toString() ) ;
            }
        }
        else if( type_x == "function" ) {
            if( clz_x == "JSAdapter" ) {
                var vof = valueof( x ) ;
                if( vof == "array" ) {
                    x = SubModel.convertParamByList( x ) ;
                }
                else if( vof == "map" ) {
                    x = SubModel.convertParamByMap( x ) ;
                }
            }
        }
        else if( type_x == "boolean" ) {
            x = new java.lang.Boolean( x ) ;
        }
        else if( type_x != "string" ) {
            x = "" + x ;
        }
    }
    return x ;
}

// 日付オブジェクトを生成.
SubModel.createStringByDate = function(str) {
    if( isNull( str ) ) {
        return ;
    }
    var lst = str.split( "," ) ;
    return new Date( parseValue(lst[0]),
        parseValue(lst[1])-1,
        parseValue(lst[2]),
        parseValue(lst[3]),
        parseValue(lst[4]),
        parseValue(lst[5]) ) ;
}

// 戻りオブジェクトをjlistに変換.
SubModel.convertResultByJList = function(res) {
    if( isNull( res ) || res.size() <= 0 ) {
        return jlist() ;
    }
    var len = res.size() ;
    if( len > 0 ) {
        var lst = new java.util.ArrayList() ;
        for( var i = 0 ; i < len ; i ++ ) {
            var d = res.get( i ) ;
            lst.add( SubModel.convertResultByJMap( d ) ) ;
        }
        var ret = jlist( lst ) ;
        return ret ;
    }
    return jlist() ;
}

// 戻りオブジェクトをjmapに変換.
SubModel.convertResultByJMap = function(map) {
    if( isNull( map ) || map.size() <= 0 ) {
        return null ;
    }
    var o = map.keySet().toArray() ;
    var len = o.length ;
    for( var i = 0 ; i < len ; i ++ ) {
        var one = org.maachang.comet.httpd.engine.script.js.JsDef.getArray( o,i ) ;
        var val = map.get( one ) ;
        if( isNull( val ) ) {
            map.put( one,null ) ;
            continue ;
        }
        else if( valueof(val) == "string" ) {
            if( val instanceof java.lang.String ) {
                val = ""+val ;
            }
            if( val.indexOf( SubModel.OUTPUT_DATE_TYPE ) == 0 ) {
                map.put( one,SubModel.createStringByDate( val.substring( SubModel.OUTPUT_DATE_TYPE.length,val.length ) ) ) ;
            }
        }
        else if( val instanceof java.util.Map ) {// 1件のjoin.
            if( val.size() <= 0 ) {
                map.put( one,SubModel.dbmap() ) ;
            }
            else {
                map.put( one,SubModel.convertResultByJMap( val ) ) ;
            }
        }
        else if( val instanceof java.util.List ) {// join.
            if( val.size() <= 0 ) {
                map.put( one,jlist() ) ;
            }
            else {
                map.put( one,SubModel.convertResultByJList( val ) ) ;
            }
        }
    }
    return SubModel.dbmap( map ) ;
}

// joinキー群を取得.
SubModel.getModelByJoinKeys = function( map ) {
    if( isNull( map ) ) {
        return null ;
    }
    var join = map.get( "join" ) ;
    if( join == null || valueof( join ) != "map" ) {
        return null ;
    }
    var ret = new java.util.HashMap() ;
    for( var k in join ) {
        ret.put( k,join[k] ) ;
    }
    if( ret.size() <= 0 ) {
        return null ;
    }
    return ret ;
}

// ImageJoin群を取得.
SubModel.getModelByImageJoin = function( map ) {
    if( isNull( map ) ) {
        return null ;
    }
    var join = map.get( "imageJoin" ) ;
    if( join == null || valueof( join ) != "array" ) {
        return null ;
    }
    var ret = new java.util.ArrayList() ;
    var len = join.length ;
    for( var i = 0 ; i < len ; i ++ ) {
        ret.add( join[ i ] ) ;
    }
    if( ret.size() <= 0 ) {
        return null ;
    }
    return ret ;
}

// 対象テーブルのSrcJoinキー群を取得.
SubModel.getModelBySrcJoinKeys = function( thisModel,map ) {
    var cnt = 0 ;
    var tables = map.get( "srcJoin" ) ;
    if( isNull( tables ) == false && tables.length > 0 ) {
        var len = tables.length ;
        var ret = new java.util.HashMap() ;
        var bindings = context.getBindings(
            javax.script.ScriptContext.ENGINE_SCOPE ) ;
        for( var i = 0 ; i < len ; i ++ ) {
            var addList = null ;
            var name = tables[i] ;
            var model = bindings.get( name ) ;
            if( isNull( model ) ) {
                continue ;
            }
            var join = model.join ;
            if( isNull( join ) == false ) {
                for( var k in join ) {
                    if( join[k] == thisModel ) {
                        if( addList == null ) {
                            addList = new java.util.ArrayList() ;
                            ret.put( name,addList ) ;
                        }
                        addList.add( k ) ;
                        cnt ++ ;
                    }
                }
            }
        }
    }
    if( cnt <= 0 ) {
        return null ;
    }
    return ret ;
}

// １対他の外部結合条件を削除.
// findManyなどで取得された、データには、結合を示すカラム名($結合テーブル名)となります。
// これらは、saveや、remove時には必要ないので、その内容を省いた形で利用しなければ
// する必要があり、このメソッドで、その処理を実施させます.
SubModel.removeManyColumn = function( map ) {
    if( isNull( map ) ) {
        return ;
    }
    if( map instanceof java.util.Map ) {
        if( map.size() <= 0 ) {
            return ;
        }
        var o = map.keySet().toArray() ;
        var len = o.length ;
        for( var i = 0 ; i < len ; i ++ ) {
            var one = org.maachang.comet.httpd.engine.script.js.JsDef.getArray( o,i ) ;
            if( startsWith( one,"$" ) ) {
                map.remove( one ) ;
            }
        }
    }
    else {
        if( map.length <= 0 ) {
            return ;
        }
        for( var k in map ) {
            if( startsWith( k,"$" ) ) {
                delete map[k] ;
            }
        }
    }
}

