diff --git a/backend-services/feed-service/app/repositories/Repository.scala b/backend-services/feed-service/app/repositories/Repository.scala new file mode 100644 index 0000000000000000000000000000000000000000..ee79ca590688d34bd9ae1271c59943be492a1e80 --- /dev/null +++ b/backend-services/feed-service/app/repositories/Repository.scala @@ -0,0 +1,102 @@ +package repositories + +import utils.ConfigHelper + +import utils.MongoConnection + +import org.mongodb.scala.{MongoClient, MongoDatabase, MongoCollection} +import org.mongodb.scala.model.Filters +import org.bson.types.ObjectId +import org.bson.conversions.Bson + +import scala.concurrent.ExecutionContext.Implicits.global +import scala.concurrent.{Future, Await} +import scala.concurrent.duration._ +import scala.reflect.ClassTag + + +/** + * The base repository class that provides basic CRUD operations for a MongoDB collection. + * + * @tparam T The type of objects stored in the collection. + * @param databaseName The name of the MongoDB database to use. + * @param collectionName The name of the MongoDB collection to use. + */ +class Repository[T: ClassTag](databaseName: String, collectionName: String) { + + /** + * Returns a reference to a MongoDB collection within a database. + * Once Future completes, collection reference is returned. + * + * @return a MongoCollection[T] object representing the collection. + * @throws TimeoutException if the Future doesn't complete within the 3 second timeout. + */ + protected val collection: MongoCollection[T] = { + val mongoUri: String = ConfigHelper.getString("mongodb.uri") + + val futureCollection: Future[MongoCollection[T]] = for { + client: MongoClient <- MongoConnection.getClient(mongoUri) + database: MongoDatabase <- MongoConnection.getDatabase(client, databaseName) + collection: MongoCollection[T] <- MongoConnection.getCollection[T](database, collectionName) + } yield collection: MongoCollection[T] + + Await.result[MongoCollection[T]](futureCollection, 3.seconds) + } + + /** + * Gets all the records in the collection. + * + * @return A Future containing a sequence of the collection's records. + */ + def getAll(): Future[Seq[T]] = { + MongoConnection.find[T](collection) + } + + /** + * Gets a record with the given ID in the collection. + * + * @return A Future containing a sequence of matching documents. + */ + def getById(id: ObjectId): Future[T] = { + val filter: Bson = Filters.equal[ObjectId]("_id", id) + MongoConnection.find[T](collection, filter).map(_.head) + } + + /** + * Retrieves records from the collection that have the specified value for the given field name. + * + * @tparam V The type of the query value. + * @param field_name The name of the field to search for. + * @param value The value to search for. + * + * @return A Future containing a sequence of matching documents. + */ + def getByValue[V](field_name: String, value: V): Future[Seq[T]] = { + val filter: Bson = Filters.equal[V](field_name, value) + MongoConnection.find[T](collection, filter) + } + + /** + * Retrieves records from the collection that contain any of the specified values for the given field name. + * + * @tparam V The type of the query values. + * @param field_name The name of the field to search for. + * @param value A sequence of values to search for. + * + * @return A Future containing a sequence of matching documents. + */ + def getByValues[V](field_name: String, values: Seq[V]): Future[Seq[T]] = { + val filter: Bson = Filters.in[V](field_name, values: _*) + MongoConnection.find[T](collection, filter) + } + + /** + * Updates a document in the collection. + * + * @param documentId The ID of the document to update. + * @param updates A sequence of Bson documents defining the updates. + */ + def updateOne(documentId: ObjectId, updates: Seq[Bson]): Future[Unit] = { + MongoConnection.updateOne[T](collection, documentId, updates) + } +}