Liam Staskawicz avatar Liam Staskawicz committed 923cff5

* beginnings of handling in place for responseFlags in Cursor
* formatting cleanup

Comments (0)

Files changed (1)

 **
 class Cursor 
 {
+  private static const Int CURSOR_NOT_FOUND :=    1.shiftl(0)
+  private static const Int QUERY_FAILURE :=       1.shiftl(1)
+  private static const Int SHARD_CONFIG_STALE :=  1.shiftl(2)
+  private static const Int AWAIT_CAPABLE :=       1.shiftl(3)
+  
   private static const Log log := Log.get("mongo")
   internal const Collection coll
   const Map selector            // document selector
   private Void fillErUp()
   {
     if (!closed && cache.size == 0) {
-      if(itemsSeen < 0) { // we haven't sent our initial query yet
+      if (itemsSeen < 0) { // we haven't sent our initial query yet
         itemsSeen = 0
-        doQuery(numToReturn())
+        doQuery(numToReturn)
       }
       else {
-        num := numToReturn()
-        if(num < opts.get("limit", num) && num > 0)
+        num := numToReturn
+        if (num < opts.get("limit", num) && num > 0)
           getMore(num)
       }
     }
   private Int numToReturn()
   {
     num := opts.get("batchsize", 0) // default to 0 which lets the DB decide how much to send back
-    if(opts.containsKey("limit")) {
+    if (opts.containsKey("limit")) {
       num = ((Int)opts["limit"] - itemsSeen)
-      if(num == 0)
+      if (num == 0)
         num = -1
     }
     return num
   **
   This limit(Int lim)
   {
-    if(lim > itemsSeen)
+    if (lim > itemsSeen)
       opts["limit"] = lim
     return this
   }
   List toList()
   {
     objects := Map[,]
-    while(this.more)
+    while (this.more)
       objects.add(next)
     return objects
   }
   Void each(|Str:Obj? item, Int index| c)
   {
     i := 0
-    while(this.more) { c.callList([this.next, i++]) }
+    while (this.more) { c.callList([this.next, i++]) }
   }
   
   **
   
   private [Str:Int]? fieldsForQuery(Str[] fields)
   {
-    if(fields.isEmpty) return null
+    if (fields.isEmpty) return null
     m := Str:Int[:]
     fields.each |val| { m[val] = 1 }
     return m
   private Str:Obj specialFields()
   {
     Str:Obj special := [:] { ordered = true }
-    if(opts.containsKey("explain"))
+    if (opts.containsKey("explain"))
       special["\$explain"] = true
-    if(opts.containsKey("order"))
+    if (opts.containsKey("order"))
       special["orderby"] = opts["order"]
     // todo snapshot, hint and order
     return special
     b.writeI4(numToRetrieve)                    // num to return
     
     sf := specialFields()
-    if(sf.size > 0) {
+    if (sf.size > 0) {
       sf["query"] = selector
       Bson.write(b.out, sf)                     // query object
       // no need to check for fields in this case
     }
     else {
       Bson.write(b.out, selector)                 // query object
-      if(opts.containsKey("fields"))              // optional fieldReturnSelector
+      if (opts.containsKey("fields"))              // optional fieldReturnSelector
         Bson.write(b.out, fieldsForQuery(opts["fields"]))
     }
     
-    s := coll.db.connection.getSocket()
+    s := coll.db.connection.getSocket
     reqID := coll.db.connection.sendMsg(s.out, b.flip, Mongo.OP_QUERY)
     readResponse(s.in, reqID)
   }
     b.writeI4(numToRetrieve)              // num to return
     b.writeI8(this.cursorID)              // cursor ID
     
-    s := coll.db.connection.getSocket()
+    s := coll.db.connection.getSocket
     reqID := coll.db.connection.sendMsg(s.out, b.flip, Mongo.OP_GET_MORE)
     readResponse(s.in, reqID)
   }
   {
     // if we don't have a good ID, or we've read through to completion, and received
     // a cursorID of 0 as a result, no need to talk to the DB - just mark our state
-    if(this.cursorID != 0) {
+    if (this.cursorID != 0) {
       b := Buf() { endian = Endian.little }
       b.writeI4(0)                          // reserved
       b.writeI4(1)                          // number of cursors
       b.writeI8(this.cursorID)              // cursor ID
       
-      s := coll.db.connection.getSocket()
+      s := coll.db.connection.getSocket
       coll.db.connection.sendMsg(s.out, b.flip, Mongo.OP_KILL_CURSORS)
     }
     cursorID = 0
   {
     // standard header
     ins.skip(8) // eat the length and the request ID
-    if(requestID != ins.readS4())
+    if (requestID != ins.readS4)
       log.warn("Connection - mismatching request/response IDs")
-    if(Mongo.OP_REPLY != ins.readS4())
+    if (Mongo.OP_REPLY != ins.readS4)
       log.warn("Connection - unexpected opcode from DB")
     // end standard header
     
-    if(0 != ins.readS4()) // not much doc on what to do if this is not 0...
-      log.warn("Connection - non-zero responseFlag")
-    if((cursorID = ins.readS8()) == 0) // this reply had everything in it...nothing more to get
+    // handle response flags
+    responseFlags := ins.readS4 // bit mask of status
+    // TODO - handle any errors here better
+    if (responseFlags.and(CURSOR_NOT_FOUND) != 0)
+      log.warn("Connection - cursor not found: $responseFlags")
+    if (responseFlags.and(QUERY_FAILURE) != 0)
+      log.warn("Connection - query failure: $responseFlags")
+    if (responseFlags.and(SHARD_CONFIG_STALE) != 0)
+      log.warn("Connection - shard config stale: $responseFlags")
+    // TODO - manage AWAIT_CAPABLE properly
+    // if (!responseFlags.and(AWAIT_CAPABLE))
+      // log.warn("Connection - not await capable: $responseFlags")
+    // end of response flags handling
+    
+    if ((cursorID = ins.readS8) == 0) // this reply had everything in it...nothing more to get
       close
-    startingFrom := ins.readS4()
-    numberReturned := ins.readS4()
+    startingFrom := ins.readS4
+    numberReturned := ins.readS4
     itemsSeen += numberReturned
     // Sys.out.printLine("cursorID - ${cursorID}, startingFrom - ${startingFrom}, numberReturned - ${numberReturned}")
     
-    while(numberReturned-- > 0)
+    while (numberReturned-- > 0)
       cache.add(Bson.read(ins))
   }
   
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.