All Downloads are FREE. Search and download functionalities are using the official Maven repository.

mongo4cats.client.MongoClient.scala Maven / Gradle / Ivy

There is a newer version: 0.7.11
Show newest version
/*
 * Copyright 2020 Kirill5k
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package mongo4cats.client

import cats.effect.{Async, Resource, Sync}
import cats.syntax.flatMap._
import cats.syntax.functor._
import com.mongodb.reactivestreams.client.{ClientSession => JClientSession, MongoClient => JMongoClient, MongoClients}
import mongo4cats.AsJava
import mongo4cats.bson.Document
import mongo4cats.database.MongoDatabase
import mongo4cats.syntax._
import mongo4cats.models.client.{
  ClientSessionOptions,
  ConnectionString,
  MongoClientSettings,
  MongoConnection,
  MongoDriverInformation,
  ServerAddress,
  TransactionOptions
}
import org.bson.UuidRepresentation

import scala.util.Try

final private class LiveClientSession[F[_]](
    val underlying: JClientSession
)(implicit
    F: Async[F]
) extends ClientSession[F] {
  def startTransaction(options: TransactionOptions): F[Unit] = F.fromTry(Try(underlying.startTransaction(options)))
  def commitTransaction: F[Unit]                             = underlying.commitTransaction().asyncVoid[F]
  def abortTransaction: F[Unit]                              = underlying.abortTransaction().asyncVoid[F]
}

final private class LiveMongoClient[F[_]](
    val underlying: JMongoClient
)(implicit
    F: Async[F]
) extends MongoClient[F] {
  def getDatabase(name: String): F[MongoDatabase[F]] =
    F.delay(underlying.getDatabase(name)).flatMap(MongoDatabase.make[F])

  def listDatabaseNames: F[Iterable[String]] =
    underlying.listDatabaseNames().asyncIterable[F]

  def listDatabases: F[Iterable[Document]] =
    underlying.listDatabases().asyncIterable[F].map(_.map(Document.fromJava))

  def listDatabases(cs: ClientSession[F]): F[Iterable[Document]] =
    underlying.listDatabases(cs.underlying).asyncIterable[F].map(_.map(Document.fromJava))

  def startSession(options: ClientSessionOptions): Resource[F, ClientSession[F]] =
    Resource.fromAutoCloseable(underlying.startSession(options).asyncSingle[F].unNone).map(new LiveClientSession(_))
}

object MongoClient extends AsJava {

  def fromConnection[F[_]: Async](connection: MongoConnection): Resource[F, MongoClient[F]] =
    fromConnectionString(connection.toString)

  def fromConnectionString[F[_]: Async](connectionString: String): Resource[F, MongoClient[F]] =
    clientResource[F](
      MongoClients.create(
        MongoClientSettings
          .builder()
          .uuidRepresentation(UuidRepresentation.STANDARD)
          .applyConnectionString(ConnectionString(connectionString))
          .build()
      )
    )

  def fromServerAddress[F[_]: Async](serverAddress: ServerAddress, serverAddresses: ServerAddress*): Resource[F, MongoClient[F]] =
    create {
      MongoClientSettings
        .builder()
        .uuidRepresentation(UuidRepresentation.STANDARD)
        .applyToClusterSettings { builder =>
          val _ = builder.hosts(asJava(serverAddress :: serverAddresses.toList))
        }
        .build()
    }

  def create[F[_]: Async](settings: MongoClientSettings): Resource[F, MongoClient[F]] =
    create(settings, null)

  def create[F[_]: Async](settings: MongoClientSettings, driver: MongoDriverInformation): Resource[F, MongoClient[F]] =
    clientResource(MongoClients.create(settings, driver))

  private def clientResource[F[_]: Async](client: => JMongoClient): Resource[F, MongoClient[F]] =
    Resource.fromAutoCloseable(Sync[F].delay(client)).map(c => new LiveMongoClient[F](c))
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy