Property definitions

popcorn $ MongoRepository :: defaultinit
# 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