X-Git-Url: http://nitlanguage.org?ds=sidebyside diff --git a/lib/mongodb/mongodb.nit b/lib/mongodb/mongodb.nit index 889fc2e..98b271d 100644 --- a/lib/mongodb/mongodb.nit +++ b/lib/mongodb/mongodb.nit @@ -24,8 +24,13 @@ # # Opens the connexion with the Mongo server. # var client = new MongoClient("mongodb://localhost:27017/") # +# # Select the database. +# var db_suffix = "NIT_TESTING_ID".environ +# var db_name = "test_{db_suffix}" +# var db = client.database(db_name) +# # # Retrieve a collection. -# var col = client.database("test").collection("test") +# var col = db.collection("test") # # # Insert a document in the collection. # var doc = new JsonObject @@ -42,6 +47,7 @@ # ~~~ module mongodb +import json::static import json private import native_mongodb @@ -90,9 +96,9 @@ private class BSON end 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 + var ns = native.to_c_string + var res = ns.to_s + ns.free # manual free of gc allocated CString return res end @@ -121,7 +127,7 @@ end redef class JsonObject # Inits `self` from a BSON object. - private init from_bson(bson: BSON) do recover_with(bson.to_json) + private init from_bson(bson: BSON) do add_all(bson.to_json) # Returns a new BSON object from `self`. private fun to_bson: BSON do return new BSON.from_json(self) @@ -146,7 +152,7 @@ class MongoError # Human readable error message. fun message: String do var ns = native.message - var res = ns.to_s_with_copy + var res = ns.to_s ns.free return res end @@ -162,9 +168,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 + + private var native: BSONObjectId = new BSONObjectId - var native: 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 @@ -221,9 +231,11 @@ class MongoClient # # ~~~ # var client = new MongoClient("mongodb://localhost:27017/") - # var db = client.database("test") + # var db_suffix = "NIT_TESTING_ID".environ + # var db_name = "test_{db_suffix}" + # var db = client.database(db_name) # db.collection("test").insert(new JsonObject) - # assert client.database_names.has("test") + # assert client.database_names.has(db_name) # ~~~ fun database_names: Array[String] do var res = new Array[String] @@ -232,7 +244,7 @@ class MongoClient var i = 0 var name = nas[i] while not name.address_is_null do - res.add name.to_s_with_copy + res.add name.to_s name.free i += 1 name = nas[i] @@ -248,7 +260,10 @@ class MongoClient # # ~~~ # var client = new MongoClient("mongodb://localhost:27017/") - # assert client.database("test").name == "test" + # var db_suffix = "NIT_TESTING_ID".environ + # var db_name = "test_{db_suffix}" + # var db = client.database(db_name) + # assert db.name == db_name # ~~~ fun database(name: String): MongoDb do return new MongoDb(self, name) @@ -270,7 +285,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. @@ -307,7 +322,9 @@ class MongoDb # # ~~~ # var client = new MongoClient("mongodb://localhost:27017/") - # var db = client.database("test") + # var db_suffix = "NIT_TESTING_ID".environ + # var db_name = "test_{db_suffix}" + # var db = client.database(db_name) # db.collection("test").insert(new JsonObject) # assert db.collection_names.has("test") # ~~~ @@ -318,7 +335,7 @@ class MongoDb var i = 0 var name = nas[i] while not name.address_is_null do - res.add name.to_s_with_copy + res.add name.to_s name.free i += 1 name = nas[i] @@ -330,7 +347,9 @@ class MongoDb # # ~~~ # var client = new MongoClient("mongodb://localhost:27017/") - # var db = client.database("test") + # var db_suffix = "NIT_TESTING_ID".environ + # var db_name = "test_{db_suffix}" + # var db = client.database(db_name) # var col = db.collection("test") # assert col.name == "test" # ~~~ @@ -342,7 +361,9 @@ class MongoDb # # ~~~ # var client = new MongoClient("mongodb://localhost:27017/") - # var db = client.database("test") + # var db_suffix = "NIT_TESTING_ID".environ + # var db_name = "test_{db_suffix}" + # var db = client.database(db_name) # assert not db.has_collection("qwerty") # ~~~ fun has_collection(name: String): Bool do @@ -400,7 +421,10 @@ class MongoCollection # # ~~~ # var client = new MongoClient("mongodb://localhost:27017/") - # var col = client.database("test").collection("test") + # var db_suffix = "NIT_TESTING_ID".environ + # var db_name = "test_{db_suffix}" + # var db = client.database(db_name) + # var col = db.collection("test") # var doc = new JsonObject # doc["foo"] = 10 # doc["bar"] = "bar" @@ -432,7 +456,10 @@ class MongoCollection # # ~~~ # var client = new MongoClient("mongodb://localhost:27017/") - # var col = client.database("test").collection("test") + # var db_suffix = "NIT_TESTING_ID".environ + # var db_name = "test_{db_suffix}" + # var db = client.database(db_name) + # var col = db.collection("test") # # var doc = new JsonObject # doc["foo"] = 10 @@ -462,7 +489,10 @@ class MongoCollection # # ~~~ # var client = new MongoClient("mongodb://localhost:27017/") - # var col = client.database("test").collection("test") + # var db_suffix = "NIT_TESTING_ID".environ + # var db_name = "test_{db_suffix}" + # var db = client.database(db_name) + # var col = db.collection("test") # var sel = new JsonObject # sel["foo"] = 10 # assert col.remove(sel) @@ -484,7 +514,10 @@ class MongoCollection # # ~~~ # var client = new MongoClient("mongodb://localhost:27017/") - # var col = client.database("test").collection("test") + # var db_suffix = "NIT_TESTING_ID".environ + # var db_name = "test_{db_suffix}" + # var db = client.database(db_name) + # var col = db.collection("test") # var sel = new JsonObject # sel["foo"] = 10 # var upd = new JsonObject @@ -512,7 +545,10 @@ class MongoCollection # # ~~~ # var client = new MongoClient("mongodb://localhost:27017/") - # var col = client.database("test").collection("test") + # var db_suffix = "NIT_TESTING_ID".environ + # var db_name = "test_{db_suffix}" + # var db = client.database(db_name) + # var col = db.collection("test") # var query = new JsonObject # query["foo"] = 10 # assert col.count(query) > 0 @@ -523,19 +559,28 @@ class MongoCollection # Finds the first document that matches `query`. # + # Params: + # * `skip` number of documents to skip + # * `limit` number of documents to return + # # Returns `null` if an error occured. See `Sys::last_mongoc_error`. # # ~~~ # var client = new MongoClient("mongodb://localhost:27017/") - # var col = client.database("test").collection("test") + # var db_suffix = "NIT_TESTING_ID".environ + # var db_name = "test_{db_suffix}" + # var db = client.database(db_name) + # var col = db.collection("test") # var query = new JsonObject # query["foo"] = 10 # var doc = col.find(query) # assert doc["foo"] == 10 # ~~~ - fun find(query: JsonObject): nullable JsonObject do + fun find(query: JsonObject, skip, limit: nullable Int): nullable JsonObject do var q = new NativeBSON.from_json_string(query.to_json.to_cstring) - var c = native.find(q) + var s = skip or else 0 + var l = limit or else 0 + var c = native.find(q, s, l) q.destroy if c == null then return null var cursor = new MongoCursor(c) @@ -549,19 +594,69 @@ class MongoCollection # Finds all the documents matching the `query`. # + # Params: + # * `skip` number of documents to skip + # * `limit` number of documents to return + # # ~~~ # var client = new MongoClient("mongodb://localhost:27017/") - # var col = client.database("test").collection("test") + # var db_suffix = "NIT_TESTING_ID".environ + # var db_name = "test_{db_suffix}" + # var db = client.database(db_name) + # var col = db.collection("test") # var query = new JsonObject # query["foo"] = 10 # assert col.find_all(query).length > 0 # ~~~ - fun find_all(query: JsonObject): Array[JsonObject] do + fun find_all(query: JsonObject, skip, limit: nullable Int): Array[JsonObject] do + var s = skip or else 0 + var l = limit or else 0 var res = new Array[JsonObject] - var c = native.find(query.to_bson.native) + var c = native.find(query.to_bson.native, s, l) if c == null then return res var cursor = new MongoCursor(c) - for item in cursor do res.add item + while cursor.is_ok do + res.add cursor.item + cursor.next + end + return res + end + + # Applies an aggregation `pipeline` over the collection. + # + # ~~~ + # var client = new MongoClient("mongodb://localhost:27017/") + # var db_suffix = "NIT_TESTING_ID".environ + # var db_name = "test_{db_suffix}" + # var db = client.database(db_name) + # var col = db.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 @@ -571,8 +666,11 @@ class MongoCollection # # ~~~ # var client = new MongoClient("mongodb://localhost:27017/") - # var col = client.database("test").collection("test") - # assert col.stats["ns"] == "test.test" + # var db_suffix = "NIT_TESTING_ID".environ + # var db_name = "test_{db_suffix}" + # var db = client.database(db_name) + # var col = db.collection("test") + # assert col.stats["ns"] == "{db_name}.test" # ~~~ fun stats: nullable JsonObject do var bson = native.stats @@ -618,9 +716,9 @@ class MongoCursor init do next - redef fun is_ok do return native.more + redef var is_ok = true - redef fun next do native.next + redef fun next do is_ok = native.next redef fun item do return new JsonObject.from_bson(new BSON(native.current))