diff --git a/mongo/src/MongoJsonRepository.scala b/mongo/src/MongoJsonRepository.scala new file mode 100644 index 0000000..411fba9 --- /dev/null +++ b/mongo/src/MongoJsonRepository.scala @@ -0,0 +1,56 @@ +package works.iterative.mongo + +import zio.* +import zio.json.* +import zio.config.* +import org.mongodb.scala.* +import org.mongodb.scala.model.Filters.* +import org.bson.json.JsonObject +import org.mongodb.scala.model.ReplaceOptions +import org.mongodb.scala.bson.conversions.Bson + +case class MongoConfig(uri: String) + +object MongoConfig: + val configDesc = + import ConfigDescriptor.* + nested("MONGO")(string("URI").default("mongodb://localhost:27017")) + .to[MongoConfig] + val fromEnv = ZConfig.fromSystemEnv( + configDesc, + keyDelimiter = Some('_'), + valueDelimiter = Some(',') + ) + +extension (m: MongoClient.type) + def layer: RLayer[MongoConfig, MongoClient] = + ZIO + .serviceWithZIO[MongoConfig](c => Task.attempt(MongoClient(c.uri))) + .toLayer + +class MongoJsonRepository[Elem, Key, Criteria]( + collection: MongoCollection[JsonObject], + toFilter: Criteria => Bson, + idFilter: Elem => (String, Key) +)(using JsonCodec[Elem]): + def matching(criteria: Criteria): Task[List[Elem]] = + val filter = toFilter(criteria) + val query = collection.find(filter) + + for + result <- ZIO.fromFuture(_ => query.toFuture) + proof <- ZIO.collect(result)(j => + ZIO.fromOption(j.getJson.fromJson[Elem].toOption) + ) + yield proof.to(List) + + def put(elem: Elem): Task[Unit] = + Task.async(cb => + collection + .replaceOne( + equal.tupled(idFilter(elem)), + JsonObject(elem.toJson), + ReplaceOptions().upsert(true) + ) + .subscribe(_ => cb(Task.unit), t => cb(Task.fail(t))) + ) diff --git a/mongo/src/MongoJsonRepository.scala b/mongo/src/MongoJsonRepository.scala new file mode 100644 index 0000000..411fba9 --- /dev/null +++ b/mongo/src/MongoJsonRepository.scala @@ -0,0 +1,56 @@ +package works.iterative.mongo + +import zio.* +import zio.json.* +import zio.config.* +import org.mongodb.scala.* +import org.mongodb.scala.model.Filters.* +import org.bson.json.JsonObject +import org.mongodb.scala.model.ReplaceOptions +import org.mongodb.scala.bson.conversions.Bson + +case class MongoConfig(uri: String) + +object MongoConfig: + val configDesc = + import ConfigDescriptor.* + nested("MONGO")(string("URI").default("mongodb://localhost:27017")) + .to[MongoConfig] + val fromEnv = ZConfig.fromSystemEnv( + configDesc, + keyDelimiter = Some('_'), + valueDelimiter = Some(',') + ) + +extension (m: MongoClient.type) + def layer: RLayer[MongoConfig, MongoClient] = + ZIO + .serviceWithZIO[MongoConfig](c => Task.attempt(MongoClient(c.uri))) + .toLayer + +class MongoJsonRepository[Elem, Key, Criteria]( + collection: MongoCollection[JsonObject], + toFilter: Criteria => Bson, + idFilter: Elem => (String, Key) +)(using JsonCodec[Elem]): + def matching(criteria: Criteria): Task[List[Elem]] = + val filter = toFilter(criteria) + val query = collection.find(filter) + + for + result <- ZIO.fromFuture(_ => query.toFuture) + proof <- ZIO.collect(result)(j => + ZIO.fromOption(j.getJson.fromJson[Elem].toOption) + ) + yield proof.to(List) + + def put(elem: Elem): Task[Unit] = + Task.async(cb => + collection + .replaceOne( + equal.tupled(idFilter(elem)), + JsonObject(elem.toJson), + ReplaceOptions().upsert(true) + ) + .subscribe(_ => cb(Task.unit), t => cb(Task.fail(t))) + ) diff --git a/mongo/src/main/scala/fiftyforms/mongo/MongoJsonRepository.scala b/mongo/src/main/scala/fiftyforms/mongo/MongoJsonRepository.scala deleted file mode 100644 index 40540c4..0000000 --- a/mongo/src/main/scala/fiftyforms/mongo/MongoJsonRepository.scala +++ /dev/null @@ -1,57 +0,0 @@ -package works.iterative.mongo - -import zio.* -import zio.json.* -import zio.config.* -import org.mongodb.scala.* -import org.mongodb.scala.model.Filters.* -import org.bson.json.JsonObject -import org.mongodb.scala.model.ReplaceOptions -import org.mongodb.scala.bson.conversions.Bson - -case class MongoConfig(uri: String) - -object MongoConfig: - val configDesc = - import ConfigDescriptor.* - nested("MONGO")(string("URI").default("mongodb://localhost:27017")) - .to[MongoConfig] - val fromEnv = ZConfig.fromSystemEnv( - configDesc, - keyDelimiter = Some('_'), - valueDelimiter = Some(',') - ) - -extension (m: MongoClient.type) - def layer: RLayer[MongoConfig, MongoClient] = - ZIO - .serviceWithZIO[MongoConfig](c => Task.attempt(MongoClient(c.uri))) - .toLayer - -class MongoJsonRepository[Elem, Key, Criteria]( - collection: MongoCollection[JsonObject], - toFilter: Criteria => Bson, - idFilter: Elem => (String, Key) -)(using JsonCodec[Elem]) { - def matching(criteria: Criteria): Task[List[Elem]] = - val filter = toFilter(criteria) - val query = collection.find(filter) - - for - result <- ZIO.fromFuture(_ => query.toFuture) - proof <- ZIO.collect(result)(j => - ZIO.fromOption(j.getJson.fromJson[Elem].toOption) - ) - yield proof.to(List) - - def put(elem: Elem): Task[Unit] = - Task.async(cb => - collection - .replaceOne( - equal.tupled(idFilter(elem)), - JsonObject(elem.toJson), - ReplaceOptions().upsert(true) - ) - .subscribe(_ => cb(Task.unit), t => cb(Task.fail(t))) - ) -}