# A Repository that uses MongoDB as backend.
#
# ~~~nitish
# import popcorn
# import popcorn::pop_repos
# import popcorn::pop_json
#
# # First, let's create a User abstraction:
#
# # Serializable user representation.
# class User
# super RepoObject
# serialize
#
# # User login
# var login: String
#
# # User password
# var password: String is writable
#
# redef fun to_s do return login
# end
#
# # We then need to subclass the `MongoRepository` to provide User specific services:
#
# # User repository for Mongo
# class UserRepo
# super MongoRepository[User]
#
# # Find a user by its login
# fun find_by_login(login: String): nullable User do
# var q = new JsonObject
# q["login"] = login
# return find(q)
# end
# end
#
# # The repository can then be used with User instances:
#
# # Init database
# var mongo = new MongoClient("mongodb://mongo:27017/")
# var db = mongo.database("tests")
# var coll = db.collection("test_pop_repo_{100000.rand}")
#
# # Create a user repo to store User instances
# var repo = new UserRepo(coll)
#
# # Create some users
# repo.save(new User("Morriar", "1234"))
# repo.save(new User("Alex", "password"))
#
# assert repo.find_all.length == 2
# assert repo.find_by_login("Morriar").password == "1234"
# repo.clear
# assert repo.find_all.length == 0
# ~~~
class MongoRepository[E: Serializable]
super JsonRepository[E]
redef type QUERY: JsonObject
# MongoDB collection used to store objects
var collection: MongoCollection
redef fun find_by_id(id) do
var query = new JsonObject
query["_id"] = id
return find(query)
end
redef fun find(query) do
var res = collection.find(query)
if res == null then return null
return deserialize(res.to_json)
end
redef fun find_all(query, skip, limit) do
var res = new Array[E]
for e in collection.find_all(query or else new JsonObject, skip, limit) do
res.add deserialize(e.to_json).as(E)
end
return res
end
redef fun count(query) do
return collection.count(query or else new JsonObject)
end
redef fun save(item) do
var json = serialize(item).as(String)
var obj = json.parse_json.as(JsonObject)
return collection.save(obj)
end
redef fun remove_by_id(id) do
var query = new JsonObject
query["_id"] = id
return remove(query)
end
redef fun remove(query) do
return collection.remove(query or else new JsonObject)
end
redef fun remove_all(query) do
return collection.remove_all(query or else new JsonObject)
end
redef fun clear do return collection.drop
# Perform an aggregation query over the repo.
fun aggregate(pipeline: JsonArray): Array[E] do
var res = new Array[E]
for obj in collection.aggregate(pipeline) do
var instance = deserialize(obj.to_json)
if instance == null then continue
res.add instance
end
return res
end
end
lib/popcorn/pop_repos.nit:253,1--373,3