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

com.github.jeroenr.tepkin.MongoDatabase.scala Maven / Gradle / Ivy

The newest version!
package com.github.jeroenr.tepkin

import akka.actor.ActorRef
import akka.pattern.ask
import akka.stream.scaladsl.Source
import akka.util.Timeout
import com.github.jeroenr.bson.BsonDocument
import com.github.jeroenr.tepkin.TepkinMessage.WhatsYourVersion
import com.github.jeroenr.tepkin.protocol.MongoWireVersion
import com.github.jeroenr.tepkin.protocol.command.{Command, Create, ListCollections}
import com.github.jeroenr.tepkin.protocol.message.Reply

import scala.concurrent.{ExecutionContext, Future}

class MongoDatabase(pool: ActorRef, databaseName: String) {

  def apply(collectionName: String): MongoCollection = {
    require(collectionName != null && collectionName.getBytes("UTF-8").size < 123,
      "Collection name must be shorter than 123 bytes")
    new MongoCollection(databaseName, collectionName, pool)
  }

  def collection(collectionName: String): MongoCollection = apply(collectionName)

  def gridFs(prefix: String = "fs"): GridFs = {
    new GridFs(this, prefix)
  }

  /**
   * Creates a new collection explicitly. Because MongoDB creates a collection implicitly when the collection is first
   * referenced in a command, this method is used primarily for creating new capped collections. This is also used to
   * pre-allocate space for an ordinary collection.
   *
   * @param name The name of the collection to create.
   * @param capped Optional. To create a capped collection. specify true. If you specify true, you must also set a
   *               maximum size in the size field.
   * @param autoIndexId Optional. Specify false to disable the automatic creation of an index on the _id field.
   * @param size Optional. The maximum size for the capped collection. Once a capped collection reaches its maximum size,
   *             MongoDB overwrites older old documents with new documents. The size field is required for capped
   *             collections.
   * @param max Optional. The maximum number of documents to keep in the capped collection. The size limit takes
   *            precedence over this limit. If a capped collection reaches its maximum size before it reaches the maximum
   *            number of documents, MongoDB removes old documents. If you use this limit, ensure that the size limit is
   *            sufficient to contain the documents limit.
   * @param usePowerOf2Sizes Optional. Available for the MMAPv1 storage engine only.
   *                         Deprecated since version 3.0: For the MMAPv1 storage engine, all collections use the power
   *                         of 2 sizes allocation unless the noPadding option is true. The usePowerOf2Sizes option does
   *                         not affect the allocation strategy. Defaults to true.
   * @param noPadding Optional. Available for the MMAPv1 storage engine only.
   *                  New in version 3.0: noPadding flag disables the power of 2 sizes allocation for the collection.
   *                  With noPadding flag set to true, the allocation strategy does not include additional space to
   *                  accommodate document growth, as such, document growth will result in new allocation. Use for
   *                  collections with workloads that are insert-only or in-place updates (such as incrementing
   *                  counters). Defaults to false.
   * @param storageEngine Optional. Available for the WiredTiger storage engine only.
   */
  def createCollection(name: String,
                       capped: Option[Boolean] = None,
                       autoIndexId: Option[Boolean] = None,
                       size: Option[Int] = None,
                       max: Option[Int] = None,
                       usePowerOf2Sizes: Boolean = true,
                       noPadding: Boolean = false,
                       storageEngine: Option[BsonDocument] = None)
                      (implicit ec: ExecutionContext, timeout: Timeout): Future[BsonDocument] = {
    (pool ? Create(
      databaseName,
      name,
      capped,
      autoIndexId,
      size,
      max,
      usePowerOf2Sizes,
      noPadding,
      storageEngine)).mapTo[Reply].map(_.documents.head)
  }

  def listCollections(filter: Option[BsonDocument] = None, batchMultiplier: Int = 1000)
                     (implicit ec: ExecutionContext, timeout: Timeout): Future[Source[List[BsonDocument], ActorRef]] = {
    (pool ? WhatsYourVersion).mapTo[Int].map { maxWireVersion =>
      if (maxWireVersion == MongoWireVersion.v30) {
        val message = ListCollections(databaseName, filter)
        val extractor = { reply: Reply =>
          val cursor = reply.documents(0).getAs[BsonDocument]("cursor").get
          val cursorID = cursor.getAs[Long]("id").get
          val ns = cursor.getAs[String]("ns").get
          val initial = cursor.getAsList[BsonDocument]("firstBatch").get
          (ns, cursorID, initial)
        }

        Source.actorPublisher(MongoCursor.props(pool, message, extractor, batchMultiplier, timeout))
      } else {
        apply("system.namespaces").find(BsonDocument.empty)
      }
    }
  }

  def runCommand(document: BsonDocument)(implicit ec: ExecutionContext, timeout: Timeout): Future[Reply] = {
    val command = new Command {

      override def command: BsonDocument = document

      override def databaseName: String = MongoDatabase.this.databaseName
    }

    (pool ? command).mapTo[Reply]
  }

}





© 2015 - 2024 Weber Informatics LLC | Privacy Policy