// DBCollection.java

package ed.db;

import java.util.*;

import ed.js.*;
import ed.js.func.*;
import ed.js.engine.*;

public abstract class DBCollection extends JSObjectLame {
    
    public abstract JSObject save( JSObject o );
    public abstract JSObject update( JSObject q , JSObject o , boolean upsert );

    public abstract ObjectId apply( JSObject o );
    public abstract int remove( JSObject id );
    
    public abstract JSObject find( ObjectId id );    
    
    public abstract Iterator<JSObject> find( JSObject ref , JSObject fields );

    // ------

    public Iterator<JSObject> find( JSObject ref ){
        return find( ref , null );
    }


    // ------

    protected DBCollection( String name ){
        _name = name;

        _entries.put( "name" , _name );

        _save = new JSFunctionCalls1() {
                public Object call( Scope s , Object o , Object foo[] ){
                    
                    if ( o == null && s.getThis() != null )
                        o = s.getThis();
                    
                    if ( ! ( o instanceof JSObject ) )
                        throw new RuntimeException( "can't only save JSObject" );
                    
                    JSObject jo = (JSObject)o;
                    if ( jo.get( "_id" ) != null ){
                        JSObject q = new JSObjectBase();
                        q.set( "_id" , jo.get( "_id" ) );
                        return update( q , jo , true );
                    }
                    
                    return save( jo );
                }
            };
        _entries.put( "save" , _save );

        _update = new JSFunctionCalls2() {
                public Object call( Scope s , Object q , Object o , Object foo[] ){
                    
                    if ( ! ( o instanceof JSObject ) )
                        throw new RuntimeException( "can't only save JSObject" );
                    
                    if ( ! ( q instanceof JSObject ) )
                        throw new RuntimeException( "can't only save JSObject" );
                    
                    return update( (JSObject)q , (JSObject)o , false );
                }
            };
        _entries.put( "update" , _update );

        _entries.put( "remove" , 
                      new JSFunctionCalls1(){
                          public Object call( Scope s , Object o , Object foo[] ){
                              
                              if ( o == null && s.getThis() != null )
                                  o = s.getThis();
                              
                              if ( ! ( o instanceof JSObject ) )
                                  throw new RuntimeException( "can't only save JSObject" );
                              
                              return remove( (JSObject)o );
                              
                          }
                      } );

                          
        
        
        _apply = new JSFunctionCalls1() {
                public Object call( Scope s , Object o , Object foo[] ){
                    if ( ! ( o instanceof JSObject ) )
                        throw new RuntimeException( "can't only apply JSObject" );
                    JSObject jo = (JSObject)o;
                    jo.set( "save" , _save );
                    return apply( jo );
                }
            };
        _entries.put( "apply" , _apply );

        _find = new JSFunctionCalls2() {
                public Object call( Scope s , Object o , Object fieldsWantedO , Object foo[] ){
                    
                    if ( o == null )
                        o = new JSObjectBase();
                    
                    if ( o instanceof ObjectId )
                        return find( (ObjectId)o );

                    if ( o instanceof JSObject ){
                        Iterator<JSObject> l = find( (JSObject)o , (JSObject)fieldsWantedO );
                        if ( l == null )
                            l = (new LinkedList<JSObject>()).iterator();
                        return new DBCursor( l );
                    }
                    
                    throw new RuntimeException( "wtf : " + o.getClass() );
                }
            };
        _entries.put( "find" , _find );

        _entries.put( "findOne" , 
                      new JSFunctionCalls1() {
                          public Object call( Scope s , Object o , Object foo[] ){
                              Object res = _find.call( s , o , foo );
                              if ( res == null )
                                  return null;
                              
                              if ( res instanceof JSArray ){
                                  JSArray a = (JSArray)res;
                                  if ( a.size() == 0 )
                                      return null;
                                  return a.getInt( 0 );
                              }
                              
                              if ( res instanceof JSObject )
                                  return res;
                              
                              if ( res instanceof Iterator ){
                                  Iterator<JSObject> it = (Iterator<JSObject>)res;
                                  if ( ! it.hasNext() )
                                      return null;
                                  return it.next();
                              }

                              throw new RuntimeException( "wtf : " + res.getClass() );
                          }
                      } );

        _entries.put( "tojson" , 
                      new JSFunctionCalls0() {
                          public Object call( Scope s , Object foo[] ){
                              return "{DBCollection:" + _name + "}";
                          }
                      } );
        
    }

    public Object get( Object n ){
        if ( n == null )
            return null;
        return _entries.get( n.toString() );
    }

    final JSFunction _save;
    final JSFunction _update;
    final JSFunction _apply;
    final JSFunction _find;

    protected Map _entries = new TreeMap();
    final protected String _name;
}

@@ -5001,146 +5001,8 @@
    %0A
-                              if ( res instanceof JSObject )%0A                                  return res;%0A                              %0A
     
@@ -5330,24 +5330,162 @@
          %7D%0A%0A
+                              if ( res instanceof JSObject )%0A                                  return res;%0A                              %0A
             

fix for curosr