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

.uniform.interpreter-play27_2.13.5.0.0-RC6.source-code.Persistence.scala Maven / Gradle / Ivy

The newest version!
package ltbs.uniform
package interpreters.playframework

import play.api._,mvc._
import concurrent.{Future,ExecutionContext}
import java.util.UUID

trait PersistenceEngine[A <: Request[AnyContent]] {
  def apply(request: A)(f: DB => Future[(DB,Result)]): Future[Result]
}

case class DebugPersistence[REQ <: Request[AnyContent]](underlying: UUIDPersistence[REQ])(implicit ec: ExecutionContext) extends UUIDPersistence[REQ] {

  val log: Logger = Logger("persistence")

  def load(uuid: UUID): Future[DB] =
    underlying.load(uuid).map{ r =>
      log.info(s"load($uuid): ${r.toString}")
      r
    }

  def save(uuid: UUID, db: DB): Future[Unit] = {
    underlying.save(uuid, db).map{ case _ =>
      log.info(s"save($uuid, ${db.toString})")
    }
  }
}

abstract class UUIDPersistence[REQ <: Request[AnyContent]]()(implicit ec: ExecutionContext) extends PersistenceEngine[REQ] {
  def load(uuid: UUID): Future[DB]
  def save(uuid: UUID, db: DB): Future[Unit]
  def apply(request: REQ)(f: DB => Future[(DB,Result)]): Future[Result] = {

    val uuid: UUID = request.session.get("uuid").map{UUID.fromString}
      .getOrElse( UUID.randomUUID )

    for {
      db              <- load(uuid)
      (newDb, result) <- f(db)
      _               <- save(uuid, newDb)
    } yield result.withSession(
      request.session + ("uuid" -> uuid.toString)
    )
  }
}

final case class UnsafePersistence[REQ <: Request[AnyContent]](
  var state: Map[UUID,DB] = Map.empty
)(implicit ec: ExecutionContext) extends UUIDPersistence[REQ]()(ec) {

  def load(uuid: UUID): Future[DB] =
    Future.successful(state.withDefaultValue(Map.empty)(uuid))

  def save(uuid: UUID,db: DB): Future[Unit] = {
    state = state + (uuid -> db)
    Future.successful(())
  }
}

case class SessionPersistence[REQ <: Request[AnyContent]](name: String)(implicit req: REQ, ec: ExecutionContext)
    extends PersistenceEngine[REQ] {

  def convertIn(sessionData: Option[String]): DB = sessionData.fold(DB.empty){ str =>
    Input.fromUrlEncodedString(str) match {
      case Left(err) => throw new IllegalStateException(err.toString)
      case Right(r) => r.collect{ case (k,v :: Nil) if v.trim.nonEmpty => (k,v) }
    }
  }

  def convertOut(db: DB): String =
    db.mapValues(List.apply(_)).toMap.toUrlEncodedString

  def load: DB = convertIn(req.session.get(name))

  def apply(request: REQ)(f: DB => Future[(DB,Result)]): Future[Result] = 
    f(load).map{ case (newDb, result) =>
      result.withSession(
        request.session + (name -> convertOut(newDb))
      )
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy