mongo-dart / lib / cursor.dart

typedef MonadicBlock(var value);
class Cursor{
/**
 * Init state
 *  
 * @classconstant INIT
 **/
static final INIT = 0;

/**
 * Cursor open
 *  
 * @classconstant OPEN
 **/
static final OPEN = 1;

/**
 * Cursor closed
 *  
 * @classconstant CLOSED
 **/
static final CLOSED = 2;


  int state = INIT;
  int cursorId = 0;
  Db db;
  Queue items;
  DbCollection collection;
  Map selector;
  Map fields;
  int skip;
  int limit;
  Map sort;
  Map hint;
  MonadicBlock eachCallback;
  var eachComplete;
  bool explain;
  int flags = 0;  
  Cursor(this.db, this.collection, [this.selector, this.fields, this.skip=0, this.limit=0
  , this.sort, this.hint, this.explain]){
    if (selector === null){
      selector = {};
    } else{
      if (!selector.containsKey("query")){
        selector = {"query": selector};
      }          
    }
    if (sort !== null){
      selector["orderby"] = sort;
    }
    items = new Queue();
  }
  MongoQueryMessage generateQueryMessage(){
    return new  MongoQueryMessage(collection.fullName(),
            flags,
            skip,
            limit,
            selector,
            fields);
  }
  MongoGetMoreMessage generateGetMoreMessage(){
    return new  MongoGetMoreMessage(collection.fullName(),
            cursorId);
  }
  
  
  Map getNextItem(){
    return items.removeFirst();
  }
  Future<Map> nextObject(){
    if (state == INIT){
      Completer<Map> nextItem = new Completer<Map>();
      MongoQueryMessage qm = generateQueryMessage();
      Future<MongoReplyMessage> reply = db.executeQueryMessage(qm);
      reply.then((replyMessage){
        state = OPEN;
        //print("${replyMessage.cursorId}");
        cursorId = replyMessage.cursorId;
        items.addAll(replyMessage.documents);
        if (items.length > 0){
          Map nextDoc = getNextItem();
          debug("Cursor getNextItem $nextDoc");
          nextItem.complete(nextDoc);
        }
        else{
          nextItem.complete(null);
        }
      });
      return nextItem.future;
    }  
    else if (state == OPEN && items.length > 0){
      return new Future.immediate(getNextItem());
    }
    else if (state == OPEN && cursorId > 0){
      Completer nextItem = new Completer();
      var qm = generateGetMoreMessage();
      Future<MongoReplyMessage> reply = db.executeQueryMessage(qm);
      reply.then((replyMessage){
        state = OPEN;
        cursorId = replyMessage.cursorId;
        items.addAll(replyMessage.documents);
        if (items.length > 0){
          nextItem.complete(getNextItem());
        }
        else{
          state = CLOSED;          
          nextItem.complete(null);
        }
      });
      return nextItem.future;
    }    
    else {
      state = CLOSED;
      return new Future.immediate(null);
    }
  }
  nextEach(){
    nextObject().then((val){
      if (val === null){
        eachCallback = null;
        eachComplete.complete(true);
      } else {
        eachCallback(val);
        nextEach();
      }            
    });
  }
  
  Future<bool> each(MonadicBlock callback){
    eachCallback = callback; 
    eachComplete = new Completer();
    nextEach();
    return eachComplete.future;
  }
  Future<List<Map>> toList(){
    List<Map> result = [];
    Completer completer = new Completer();
    this.each((v)=>result.addLast(v)).then((v)=>completer.complete(result));
    return completer.future;    
  }
  close(){
    debug("Closing cursor, cursorId = $cursorId");
    if (cursorId != 0){      
      MongoKillCursorsMessage msg = new MongoKillCursorsMessage(cursorId);
      db.executeMessage(msg);
      cursorId = 0;
    } 
    state = CLOSED;
  }
}
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.