diff --git a/modules/effects/src/main/scala/dev/profunktor/redis4cats/algebra/connection.scala b/modules/effects/src/main/scala/dev/profunktor/redis4cats/algebra/connection.scala index bc05fa07..1a9929ee 100644 --- a/modules/effects/src/main/scala/dev/profunktor/redis4cats/algebra/connection.scala +++ b/modules/effects/src/main/scala/dev/profunktor/redis4cats/algebra/connection.scala @@ -16,7 +16,7 @@ package dev.profunktor.redis4cats.algebra -trait ConnectionCommands[F[_]] extends Ping[F] with Auth[F] +trait ConnectionCommands[F[_], K] extends Ping[F] with Auth[F] with Client[F, K] trait Ping[F[_]] { def ping: F[String] @@ -27,3 +27,9 @@ trait Auth[F[_]] { def auth(password: CharSequence): F[Boolean] def auth(username: String, password: CharSequence): F[Boolean] } + +trait Client[F[_], K] { + def setClientName(name: K): F[Boolean] + def getClientName(): F[Option[K]] + def getClientId(): F[Long] +} diff --git a/modules/effects/src/main/scala/dev/profunktor/redis4cats/commands.scala b/modules/effects/src/main/scala/dev/profunktor/redis4cats/commands.scala index d0c018f7..727855d3 100644 --- a/modules/effects/src/main/scala/dev/profunktor/redis4cats/commands.scala +++ b/modules/effects/src/main/scala/dev/profunktor/redis4cats/commands.scala @@ -27,7 +27,7 @@ trait RedisCommands[F[_], K, V] with SortedSetCommands[F, K, V] with ListCommands[F, K, V] with GeoCommands[F, K, V] - with ConnectionCommands[F] + with ConnectionCommands[F, K] with ServerCommands[F, K] with TransactionalCommands[F, K] with PipelineCommands[F] diff --git a/modules/effects/src/main/scala/dev/profunktor/redis4cats/redis.scala b/modules/effects/src/main/scala/dev/profunktor/redis4cats/redis.scala index c68a3814..484d7d23 100644 --- a/modules/effects/src/main/scala/dev/profunktor/redis4cats/redis.scala +++ b/modules/effects/src/main/scala/dev/profunktor/redis4cats/redis.scala @@ -1130,6 +1130,15 @@ private[redis4cats] class BaseRedis[F[_]: FutureLift: MonadThrow: Log, K, V]( override def auth(username: String, password: CharSequence): F[Boolean] = async.flatMap(_.auth(username, password).futureLift.map(_ == "OK")) + override def setClientName(name: K): F[Boolean] = + async.flatMap(_.clientSetname(name).futureLift.map(_ == "OK")) + + override def getClientName(): F[Option[K]] = + async.flatMap(_.clientGetname().futureLift).map(Option.apply) + + override def getClientId(): F[Long] = + async.flatMap(_.clientId().futureLift.map(Long.unbox)) + /******************************* Server API **********************************/ override val flushAll: F[Unit] = async.flatMap(_.flushall().futureLift.void) diff --git a/modules/tests/src/test/scala/dev/profunktor/redis4cats/TestScenarios.scala b/modules/tests/src/test/scala/dev/profunktor/redis4cats/TestScenarios.scala index 507ff4f8..a6aaa2ec 100644 --- a/modules/tests/src/test/scala/dev/profunktor/redis4cats/TestScenarios.scala +++ b/modules/tests/src/test/scala/dev/profunktor/redis4cats/TestScenarios.scala @@ -462,8 +462,20 @@ trait TestScenarios { self: FunSuite => } yield () } - def connectionScenario(redis: RedisCommands[IO, String, String]): IO[Unit] = - redis.ping.flatMap(pong => IO(assertEquals(pong, "PONG"))).void + def connectionScenario(redis: RedisCommands[IO, String, String]): IO[Unit] = { + val clientName = "hello_world" + for { + pong <- redis.ping + _ <- IO(assertEquals(pong, "PONG")) + oldClientName <- redis.getClientName() + _ <- IO(assertEquals(oldClientName, None)) + res <- redis.setClientName(clientName) + _ <- IO(assert(res, s"Failed to set client name: '$clientName'")) + newClientName <- redis.getClientName() + _ <- IO(assertEquals(newClientName, Some(clientName))) + _ <- redis.getClientId() + } yield () + } def serverScenario(redis: RedisCommands[IO, String, String]): IO[Unit] = for { diff --git a/site/docs/effects/connection.md b/site/docs/effects/connection.md index caad220f..45b5564d 100644 --- a/site/docs/effects/connection.md +++ b/site/docs/effects/connection.md @@ -20,8 +20,8 @@ import org.typelevel.log4cats.slf4j.Slf4jLogger implicit val logger: Logger[IO] = Slf4jLogger.getLogger[IO] -val commandsApi: Resource[IO, ConnectionCommands[IO]] = { - Redis[IO].fromClient[String, String](null, null.asInstanceOf[RedisCodec[String, String]]).widen[ConnectionCommands[IO]] +val commandsApi: Resource[IO, ConnectionCommands[IO, String]] = { + Redis[IO].fromClient[String, String](null, null.asInstanceOf[RedisCodec[String, String]]).widen[ConnectionCommands[IO, String]] } ``` @@ -34,8 +34,14 @@ import cats.effect.IO def putStrLn(str: String): IO[Unit] = IO(println(str)) -commandsApi.use { redis => // ConnectionCommands[IO] - redis.ping.flatMap(putStrLn) // "pong" +commandsApi.use { redis => // ConnectionCommands[IO, String] + val clientName = "client_x" + for { + _ <- redis.ping.flatMap(putStrLn) // "pong" + _ <- redis.setClientName(clientName) // true + retrievedClientName <- redis.getClientName() + _ <- putStrLn(retrievedClientName.getOrElse("")) // "client_x" + } yield () } ```