rename `NativeString` to `CString`
[nit.git] / lib / mongodb / mongodb.nit
index ab4d387..e7416f8 100644 (file)
@@ -42,6 +42,7 @@
 # ~~~
 module mongodb
 
+import json::static
 import json
 private import native_mongodb
 
@@ -92,7 +93,7 @@ private class BSON
        redef fun to_s do
                var ns = native.to_native_string
                var res = ns.to_s_with_copy
-               ns.free # manual free of gc allocated NativeString
+               ns.free # manual free of gc allocated CString
                return res
        end
 
@@ -162,9 +163,13 @@ end
 # Since the MongoDB notation is not JSON complient, the mongoc wrapper uses
 # a JSON based notation like `{"$oid": "hash"}`.
 # This is the notation returned by the `to_json` service.
-private class MongoObjectId
+class MongoObjectId
 
-       var native: BSONObjectId
+       private var native: BSONObjectId = new BSONObjectId
+
+       private init with_native(native: BSONObjectId) do
+               self.native = native
+       end
 
        # The unique ID as an MongoDB Object ID string.
        fun id: String do return native.id
@@ -270,7 +275,7 @@ class MongoClient
        private fun last_id: nullable MongoObjectId do
                var last_id = sys.last_mongoc_id
                if last_id == null then return null
-               return new MongoObjectId(last_id)
+               return new MongoObjectId.with_native(last_id)
        end
 
        # Set the last generated id or `null` to unset once used.
@@ -580,6 +585,41 @@ class MongoCollection
                return res
        end
 
+       # Applies an aggregation `pipeline` over the collection.
+       #
+       # ~~~
+       # var client = new MongoClient("mongodb://localhost:27017/")
+       # var col = client.database("test").collection("test_aggregate")
+       #
+       # col.drop
+       #
+       # col.insert("""{ "cust_id": "A123", "amount": 500, "status": "A"}""".parse_json.as(JsonObject))
+       # col.insert("""{ "cust_id": "A123", "amount": 250, "status": "A"}""".parse_json.as(JsonObject))
+       # col.insert("""{ "cust_id": "B212", "amount": 200, "status": "A"}""".parse_json.as(JsonObject))
+       # col.insert("""{ "cust_id": "A123", "amount": 300, "status": "D"}""".parse_json.as(JsonObject))
+       #
+       # var res = col.aggregate("""[
+       #       { "$match": { "status": "A" } },
+       #       { "$group": { "_id": "$cust_id", "total": { "$sum": "$amount" } } }
+       # ]""".parse_json.as(JsonArray))
+       #
+       # assert res[0].to_json == """{"_id":"B212","total":200}"""
+       # assert res[1].to_json == """{"_id":"A123","total":750}"""
+       # ~~~
+       fun aggregate(pipeline: JsonArray): Array[JsonObject] do
+               var q = new JsonObject
+               q["pipeline"] = pipeline
+               var res = new Array[JsonObject]
+               var c = native.aggregate(q.to_bson.native)
+               if c == null then return res
+               var cursor = new MongoCursor(c)
+               while cursor.is_ok do
+                       res.add cursor.item
+                       cursor.next
+               end
+               return res
+       end
+
        # Retrieves statistics about the collection.
        #
        # Returns `null` if an error occured. See `Sys::last_mongoc_error`.