From 3bb2ba2faedaeb097cc510295b639e2b0c0a18cd Mon Sep 17 00:00:00 2001 From: Felipe D'Abrantes <felidabrantes@gmail> Date: Fri, 7 Apr 2023 22:59:41 +0100 Subject: [PATCH] Add a Mongo Codec for Daily objects --- .../feed-service/app/models/Daily.scala | 51 +++++++++++++++++++ .../feed-service/app/utils/MongoCodecs.scala | 26 ++++++++++ 2 files changed, 77 insertions(+) create mode 100644 backend-services/feed-service/app/utils/MongoCodecs.scala diff --git a/backend-services/feed-service/app/models/Daily.scala b/backend-services/feed-service/app/models/Daily.scala index 1430cacc..3638ce7e 100644 --- a/backend-services/feed-service/app/models/Daily.scala +++ b/backend-services/feed-service/app/models/Daily.scala @@ -13,6 +13,10 @@ import java.text.SimpleDateFormat import play.api.libs.json.{Json, JsValue, JsString, JsObject, JsArray} +import org.bson.{BsonWriter, BsonReader, BsonType} +import org.bson.codecs.{Codec, EncoderContext, DecoderContext} +import org.bson.conversions.Bson +import org.mongodb.scala.model.Updates case class Daily( id: Option[ObjectId], @@ -98,4 +102,51 @@ object Daily { def toString(daily: Daily): String = return s"Daily(${daily.id.toString()}, ${daily.userId.toString()}, ${daily.questionId.toString()}, ${daily.content}, ${daily.usersLiked.toString()})" + + // Codec instance for serialising/deserialising type User to or from BSON. + // Implicit keyword lets Scala compiler automatically insert this into the code where it's needed. + implicit val codec: Codec[Daily] = new Codec[Daily] { + override def encode(writer: BsonWriter, value: Daily, encoderContext: EncoderContext): Unit = { + writer.writeStartDocument() + writer.writeObjectId("user_id", value.userId) + writer.writeObjectId("question_id", value.questionId) + writer.writeString("content", value.content) + writer.writeStartArray("usersLiked") + value.usersLiked.foreach(writer.writeObjectId) + writer.writeEndArray() + writer.writeDateTime("createdAt", value.createdAt.getTime()) + writer.writeDateTime("updatedAt", value.updatedAt.getTime()) + writer.writeEndDocument() + } + + override def decode(reader: BsonReader, decoderContext: DecoderContext): Daily = { + reader.readStartDocument() + println("hi") + val id = reader.readObjectId("_id") + println(id) + val userId = reader.readObjectId("user_id") + val questionId = reader.readObjectId("question_id") + val content = reader.readString("content") + val usersLiked = { + reader.readName("usersLiked") + reader.readStartArray() + val buffer = collection.mutable.Buffer.empty[ObjectId] + while (reader.readBsonType() != BsonType.END_OF_DOCUMENT) { + buffer += reader.readObjectId() + } + reader.readEndArray() + buffer.toSeq + } + val createdAt = reader.readDateTime("createdAt") + val updatedAt = reader.readDateTime("updatedAt") + reader.readEndDocument() + + val createdAtDate: Date = Date.from(Instant.ofEpochMilli(createdAt)) + val updatedAtDate: Date = Date.from(Instant.ofEpochMilli(updatedAt)) + + Daily(Some(id), userId, questionId, content, usersLiked, createdAtDate, updatedAtDate) + } + + override def getEncoderClass: Class[Daily] = classOf[Daily] + } } diff --git a/backend-services/feed-service/app/utils/MongoCodecs.scala b/backend-services/feed-service/app/utils/MongoCodecs.scala new file mode 100644 index 00000000..f755d934 --- /dev/null +++ b/backend-services/feed-service/app/utils/MongoCodecs.scala @@ -0,0 +1,26 @@ +package utils + +import models.Daily +import org.bson.codecs.Codec +import org.bson.codecs.configuration.{CodecProvider, CodecRegistry, CodecRegistries} + +import org.mongodb.scala.MongoClient + +object MongoCodecs { + // Define a custom CodecProvider that returns a Codec for the case classes + val customCodecProvider = new CodecProvider { + override def get[T](clazz: Class[T], registry: CodecRegistry): Codec[T] = { + if (clazz == classOf[Daily]) { + // If the class is the Daily case class, return the Daily codec + Daily.codec.asInstanceOf[Codec[T]] + } + else { + // If the class is not the User case class, return null + null + } + } + } + + // Create a CodecRegistry that includes the custom CodecProvider and the default codecs + val codecRegistry: CodecRegistry = CodecRegistries.fromProviders(customCodecProvider, MongoClient.DEFAULT_CODEC_REGISTRY) +} -- GitLab