Commits

vadimtsushko  committed ccd8fe4

1

  • Participants
  • Parent commits 100f714

Comments (0)

Files changed (10)

File lib/collection.dart

+class MCollection{
+  Db db;
+  String collectionName;
+  MCollection(this.db, this.collectionName){}  
+  
+}

File lib/cursor.dart

+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;
+  List items;
+  MCollection collection;
+  Map selector;
+  Map fields;
+  int skip;
+  int limit;
+  Map sort;
+  Map hint;
+  var eachCallback;
+  var eachComplete;
+  bool explain;
+  int flags = 0;
+  String collectionName() => "${db.databaseName}.${collection.collectionName}";
+  Cursor(this.db, this.collection, [this.selector, this.fields, this.skip=0, this.limit=1
+  , this.sort, this.hint, this.explain]){
+    if (selector === null){
+      selector = {};
+    }
+    items = [];
+  }
+
+  MongoQueryMessage generateQueryMessage(){
+    return new  MongoQueryMessage(collectionName(),
+            flags,
+            skip,
+            limit,
+            selector,
+            fields);
+  }
+  getNextItem(){
+    return items.removeLast();
+  }
+  Future nextObject(){
+    if (state == INIT){
+      Completer nextItem = new Completer();
+      MongoQueryMessage qm = generateQueryMessage();
+      Future<MongoReplyMessage> reply = db._executeQueryMessage(qm);
+      reply.then((replyMessage){
+        state = OPEN;
+        items.addAll(replyMessage.documents);
+        if (items.length > 0){
+          nextItem.complete(getNextItem());
+        }
+        else{
+          nextItem.complete(null);
+        }
+      });
+      return nextItem.future;
+    }  
+    else if (state == OPEN && items.length > 0){
+      return new Future.immediate(getNextItem());
+    }
+    else {
+      state = CLOSED;
+      return new Future.immediate(null);
+    }
+  }
+  nextTick(Timer timer){
+    nextObject().then((val){
+      if (val === null){
+          eachCallback = null;
+         eachComplete.complete(true);
+      } else {
+            eachCallback(val);
+            new Timer(nextTick,0);
+      }            
+    });
+  }
+  Future<bool> each(callback){
+     eachCallback = callback; 
+     eachComplete = new Completer();
+     new Timer(nextTick,0);
+     return eachComplete.future;
+  }
+}
+class Db{
+  String databaseName;
+  ServerConfig serverConfig;
+  Connection connection;
+  validateDatabaseName(String databaseName) {
+    if(databaseName.length === 0) throw "database name cannot be the empty string";  
+    var invalidChars = [" ", ".", "\$", "/", "\\"];
+    for(var i = 0; i < invalidChars.length; i++) {
+      if(databaseName.indexOf(invalidChars[i]) != -1) throw new Exception("database names cannot contain the character '" + invalidChars[i] + "'");
+    }
+  }    
+  Db(this.databaseName, [this.serverConfig]){
+     if (serverConfig === null) {
+      serverConfig = new ServerConfig();
+     }
+    connection = new Connection(serverConfig);
+  }      
+  MCollection collection(String collectionName){
+      return new MCollection(this,collectionName);
+  }
+  Future<Map> _executeQueryMessage(MongoQueryMessage queryMessage){
+    return connection.query(queryMessage);
+  }  
+  open(){
+    connection.connect();
+  }
+}

File lib/networking/mongo_insert_message.dart

+class MongoInsertMessage extends MongoMessage{
+  BsonCString _collectionFullName;
+  int flags;
+  int numberToSkip;
+  int numberToReturn;
+  BsonMap _query;
+  BsonMap _fields;
+  MongoInsertMessage(String collectionFullName,
+            this.flags,
+            this.numberToSkip,
+            this.numberToReturn,
+            Map query,
+            Map fields){
+    _collectionFullName = new BsonCString(collectionFullName);
+    _query = new BsonMap(query);
+    if (fields !== null){
+      _fields = new BsonMap(fields);
+    }
+    opcode = MongoMessage.Query;    
+  }
+  int get messageLength(){
+    int result = 16+4+_collectionFullName.byteLength()+4+4+_query.byteLength();
+    if (_fields !== null){
+      result += _fields.byteLength();
+    }
+    return result;
+  }
+  Binary serialize(){
+    Binary buffer = new Binary(messageLength);
+    writeMessageHeaderTo(buffer);
+    buffer.writeInt(flags);
+    _collectionFullName.packValue(buffer);
+    buffer.writeInt(numberToSkip);
+    buffer.writeInt(numberToReturn);
+    _query.packValue(buffer);
+    buffer.offset = 0;
+    return buffer;
+  }
+}

File lib/networking/mongo_update_message.dart

+class MongoUpdateMessage extends MongoMessage{
+  BsonCString _collectionFullName;
+  int flags;
+  int numberToSkip;
+  int numberToReturn;
+  BsonMap _query;
+  BsonMap _fields;
+  MongoUpdateMessage(String collectionFullName,
+            this.flags,
+            this.numberToSkip,
+            this.numberToReturn,
+            Map query,
+            Map fields){
+    _collectionFullName = new BsonCString(collectionFullName);
+    _query = new BsonMap(query);
+    if (fields !== null){
+      _fields = new BsonMap(fields);
+    }
+    opcode = MongoMessage.Query;    
+  }
+  int get messageLength(){
+    int result = 16+4+_collectionFullName.byteLength()+4+4+_query.byteLength();
+    if (_fields !== null){
+      result += _fields.byteLength();
+    }
+    return result;
+  }
+  Binary serialize(){
+    Binary buffer = new Binary(messageLength);
+    writeMessageHeaderTo(buffer);
+    buffer.writeInt(flags);
+    _collectionFullName.packValue(buffer);
+    buffer.writeInt(numberToSkip);
+    buffer.writeInt(numberToReturn);
+    _query.packValue(buffer);
+    buffer.offset = 0;
+    return buffer;
+  }
+}

File lib/networking/server_config.dart

+class ServerConfig{
+  String host;
+  int port;  
+  ServerConfig([this.host='127.0.0.1', this.port=27017]);
+}

File tests/CompleterTest.dart

+#import("dart:io");
+main(){  
+  Completer c = new Completer();
+  new Timer((timer){c.complete('Tra');},4000);
+
+  var f  = c.future; 
+  //c.complete('Tra');
+  waitFor(f){    
+    f.then((v){return v;});
+  }  
+  print(waitFor(f));
+}

File tests/CursorTest.dart

+#import("../lib/mongo.dart");
+testCursorCreation(){
+  Db db = new Db('db');
+  MCollection collection = db.collection('student');
+  Cursor cursor = new Cursor(db,collection);
+}
+testPingRaw(){
+  Db db = new Db('db');
+  db.open();
+  MCollection collection = db.collection('\$cmd');
+  Cursor cursor = new Cursor(db,collection,{"ping":1},limit:1);  
+  Connection conn = new Connection();
+  conn.connect();  
+  MongoQueryMessage queryMessage = cursor.generateQueryMessage();
+  Future<Map> mapFuture = conn.query(queryMessage);
+  mapFuture.then((msg) {
+ //   print(msg.documents);
+    Expect.mapEquals({'ok': 1.0},msg.documents[0]);
+  });
+}
+testNextObject(){
+  Db db = new Db('db');
+  db.open();
+  MCollection collection = db.collection('\$cmd');
+  Cursor cursor = new Cursor(db,collection,{"ping":1},limit:1);
+  var res = cursor.nextObject();
+  res.then((v){
+//    print(v);
+    Expect.mapEquals({'ok': 1.0},v);
+  });
+}
+testNextObjectToEnd(){
+  var res;
+  Db db = new Db('test');
+  db.open();
+  MCollection collection = db.collection('student');
+  Cursor cursor = new Cursor(db,collection,limit:10);  
+  res = cursor.nextObject();  
+  res.then((v){
+//    print(v);    
+    res = cursor.nextObject();
+    res.then((v){
+//      print(v);    
+      res = cursor.nextObject();
+      res.then((v){
+//        print(v);
+        res = cursor.nextObject();
+        res.then((v){
+//          print(v);    
+        });  
+      });  
+    });  
+  });  
+
+}
+
+testEach(){
+  var res;
+  Db db = new Db('test');
+  db.open();
+  MCollection collection = db.collection('student');
+  Cursor cursor = new Cursor(db,collection,limit:10);  
+  cursor.each((v) => print(v)).then((v){
+    Expect.isTrue(v);
+    Expect.isTrue(cursor.state == Cursor.CLOSED);
+    });
+  Expect.isTrue(cursor.state == Cursor.INIT);
+}
+
+main(){
+  testCursorCreation();
+  testPingRaw();
+  testNextObject();
+  testNextObjectToEnd();
+  testEach();
+}

File tests/DbTest.dart

+#import("../lib/mongo.dart");
+testDatabaseName(){
+  Db db = new Db('db');
+  String dbName;
+  dbName = 'db';
+  db.validateDatabaseName(dbName);
+  dbName = 'db';
+  db.validateDatabaseName(dbName);  
+}
+main(){
+  testDatabaseName();
+}

File tests/MCollectionTest.dart

+#import("../lib/mongo.dart");
+testCollectionCreation(){
+  Db db = new Db('db');
+  MCollection collection = db.collection('student');
+}
+main(){
+
+  testCollectionCreation();
+}