From b31ae8a4a39d1a352a2b2ef8b1c39d62ef422a74 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dragutin=20Marjanovi=C4=87?= Date: Wed, 5 Apr 2023 14:37:28 +0200 Subject: [PATCH 01/16] Use unique 'SET' command --- README.md | 10 +- docs/index.md | 19 ++- .../zio/redis/example/ContributorsCache.scala | 2 +- .../scala/zio/redis/HyperLogLogSpec.scala | 6 +- .../test/scala/zio/redis/SortedSetsSpec.scala | 4 +- .../test/scala/zio/redis/StringsSpec.scala | 102 ++++++-------- .../src/main/scala/zio/redis/Input.scala | 55 ++++---- .../main/scala/zio/redis/api/SortedSets.scala | 4 + .../main/scala/zio/redis/api/Strings.scala | 131 +++--------------- .../main/scala/zio/redis/options/Shared.scala | 39 +++--- .../scala/zio/redis/options/Strings.scala | 44 +++--- .../src/test/scala/zio/redis/InputSpec.scala | 54 +++----- 12 files changed, 166 insertions(+), 304 deletions(-) diff --git a/README.md b/README.md index e82f5ce7f..cd48f4704 100644 --- a/README.md +++ b/README.md @@ -44,15 +44,15 @@ import zio.schema._ import zio.schema.codec._ object ZIORedisExample extends ZIOAppDefault { - + object ProtobufCodecSupplier extends CodecSupplier { def get[A: Schema]: BinaryCodec[A] = ProtobufCodec.protobufCodec } - - val myApp: ZIO[Redis, RedisError, Unit] = + + val myApp: ZIO[Redis, RedisError, Unit] = for { redis <- ZIO.service[Redis] - _ <- redis.set("myKey", 8L, Some(1.minutes)) + _ <- redis.set("myKey", 8L, expireAt = Some(SetExpire.SetExpireSeconds(1.minutes))) v <- redis.get("myKey").returning[Long] _ <- Console.printLine(s"Value of myKey: $v").orDie _ <- redis.hSet("myHash", ("k1", 6), ("k2", 2)) @@ -60,7 +60,7 @@ object ZIORedisExample extends ZIOAppDefault { _ <- redis.sAdd("mySet", "a", "b", "a", "c") } yield () - override def run = + override def run = myApp.provide(Redis.local, ZLayer.succeed[CodecSupplier](ProtobufCodecSupplier)) } ``` diff --git a/docs/index.md b/docs/index.md index b9478ea0f..b1b0753cb 100644 --- a/docs/index.md +++ b/docs/index.md @@ -49,16 +49,15 @@ object ZIORedisExample extends ZIOAppDefault { def get[A: Schema]: BinaryCodec[A] = ProtobufCodec.protobufCodec } - val myApp: ZIO[Redis, RedisError, Unit] = - for { - redis <- ZIO.service[Redis] - _ <- redis.set("myKey", 8L, Some(1.minutes)) - v <- redis.get("myKey").returning[Long] - _ <- Console.printLine(s"Value of myKey: $v").orDie - _ <- redis.hSet("myHash", ("k1", 6), ("k2", 2)) - _ <- redis.rPush("myList", 1, 2, 3, 4) - _ <- redis.sAdd("mySet", "a", "b", "a", "c") - } yield () + val myApp: ZIO[Redis, RedisError, Unit] = for { + redis <- ZIO.service[Redis] + _ <- redis.set("myKey", 8L, expireAt = Some(SetExpire.SetExpireSeconds(1.minutes))) + v <- redis.get("myKey").returning[Long] + _ <- Console.printLine(s"Value of myKey: $v").orDie + _ <- redis.hSet("myHash", ("k1", 6), ("k2", 2)) + _ <- redis.rPush("myList", 1, 2, 3, 4) + _ <- redis.sAdd("mySet", "a", "b", "a", "c") + } yield () override def run = myApp.provide(Redis.local, ZLayer.succeed[CodecSupplier](ProtobufCodecSupplier)) diff --git a/modules/example/src/main/scala/zio/redis/example/ContributorsCache.scala b/modules/example/src/main/scala/zio/redis/example/ContributorsCache.scala index 4a666169a..a6d65f58b 100644 --- a/modules/example/src/main/scala/zio/redis/example/ContributorsCache.scala +++ b/modules/example/src/main/scala/zio/redis/example/ContributorsCache.scala @@ -40,7 +40,7 @@ object ContributorsCache { ZIO .fromOption(NonEmptyChunk.fromChunk(contributors)) .map(Contributors(_).toJson) - .flatMap(data => redis.set(repository.key, data, Some(1.minute)).orDie) + .flatMap(data => redis.set(repository.key, data, expireAt = Some(SetExpire.SetExpireSeconds(1.minute))).orDie) .ignore private def read(repository: Repository): IO[ApiError, Contributors] = diff --git a/modules/redis-it/src/test/scala/zio/redis/HyperLogLogSpec.scala b/modules/redis-it/src/test/scala/zio/redis/HyperLogLogSpec.scala index 05738907d..cb860871a 100644 --- a/modules/redis-it/src/test/scala/zio/redis/HyperLogLogSpec.scala +++ b/modules/redis-it/src/test/scala/zio/redis/HyperLogLogSpec.scala @@ -28,7 +28,7 @@ trait HyperLogLogSpec extends IntegrationSpec { redis <- ZIO.service[Redis] key <- uuid value <- uuid - _ <- redis.set(key, value, None, None, None) + _ <- redis.set(key, value, None, None) add <- redis.pfAdd(key, "one", "two", "three").either } yield assert(add)(isLeft(isSubtype[RedisError.WrongType](anything))) } @@ -63,7 +63,7 @@ trait HyperLogLogSpec extends IntegrationSpec { redis <- ZIO.service[Redis] key <- uuid value <- uuid - _ <- redis.set(key, value, None, None, None) + _ <- redis.set(key, value, None, None) count <- redis.pfCount(key).either } yield assert(count)(isLeft) } @@ -101,7 +101,7 @@ trait HyperLogLogSpec extends IntegrationSpec { value <- uuid key2 <- uuid key3 <- uuid - _ <- redis.set(key, value, None, None, None) + _ <- redis.set(key, value, None, None) _ <- redis.pfAdd(key2, "five", "six", "seven") merge <- redis.pfMerge(key3, key2, key).either } yield assert(merge)(isLeft) diff --git a/modules/redis-it/src/test/scala/zio/redis/SortedSetsSpec.scala b/modules/redis-it/src/test/scala/zio/redis/SortedSetsSpec.scala index 5e1b72685..118e0a123 100644 --- a/modules/redis-it/src/test/scala/zio/redis/SortedSetsSpec.scala +++ b/modules/redis-it/src/test/scala/zio/redis/SortedSetsSpec.scala @@ -431,9 +431,7 @@ trait SortedSetsSpec extends IntegrationSpec { _ <- redis.zAdd(second)(MemberScore("b", 2d), MemberScore("b", 2d), MemberScore("d", 4d)) _ <- redis.zAdd(third)(MemberScore("a", 1d), MemberScore("b", 2d), MemberScore("c", 3d)) members <- redis.zInter(first, second, third)().returning[String] - } yield assert(members)( - equalTo(Chunk("b")) - ) + } yield assert(members)(equalTo(Chunk("b"))) }, test("error when first parameter is not set") { for { diff --git a/modules/redis-it/src/test/scala/zio/redis/StringsSpec.scala b/modules/redis-it/src/test/scala/zio/redis/StringsSpec.scala index 48ddd36b1..6d3a1cfcc 100644 --- a/modules/redis-it/src/test/scala/zio/redis/StringsSpec.scala +++ b/modules/redis-it/src/test/scala/zio/redis/StringsSpec.scala @@ -3,7 +3,7 @@ package zio.redis import zio._ import zio.redis.RedisError.{ProtocolError, WrongType} import zio.test.Assertion.{exists => _, _} -import zio.test.TestAspect.{flaky, ignore} +import zio.test.TestAspect.flaky import zio.test._ trait StringsSpec extends IntegrationSpec { @@ -315,7 +315,7 @@ trait StringsSpec extends IntegrationSpec { for { redis <- ZIO.service[Redis] key <- uuid - _ <- redis.set(key, "value", None, None, None) + _ <- redis.set(key, "value", None, None) result <- redis.bitField( key, BitFieldCommand.BitFieldSet(BitFieldType.UnsignedInt(8), 8, 98L), @@ -333,9 +333,9 @@ trait StringsSpec extends IntegrationSpec { for { redis <- ZIO.service[Redis] key1 <- uuid - _ <- redis.set(key1, str1, None, None, None) + _ <- redis.set(key1, str1, None, None) key2 <- uuid - _ <- redis.set(key2, str2, None, None, None) + _ <- redis.set(key2, str2, None, None) result <- redis.lcs(key1, key2) } yield assert(result)(equalTo(Lcs.PlainLcs("fo"))) }, @@ -346,9 +346,9 @@ trait StringsSpec extends IntegrationSpec { for { redis <- ZIO.service[Redis] key1 <- uuid - _ <- redis.set(key1, str1, None, None, None) + _ <- redis.set(key1, str1, None, None) key2 <- uuid - _ <- redis.set(key2, str2, None, None, None) + _ <- redis.set(key2, str2, None, None) result <- redis.lcs("unknown", "unknown") } yield assert(result)(equalTo(Lcs.PlainLcs(""))) }, @@ -359,9 +359,9 @@ trait StringsSpec extends IntegrationSpec { for { redis <- ZIO.service[Redis] key1 <- uuid - _ <- redis.set(key1, str1, None, None, None) + _ <- redis.set(key1, str1, None, None) key2 <- uuid - _ <- redis.set(key2, str2, None, None, None) + _ <- redis.set(key2, str2, None, None) result <- redis.lcs(key1, key2, Some(LcsQueryType.Len)) } yield assert(result)(equalTo(Lcs.Length(2))) }, @@ -372,9 +372,9 @@ trait StringsSpec extends IntegrationSpec { for { redis <- ZIO.service[Redis] key1 <- uuid - _ <- redis.set(key1, str1, None, None, None) + _ <- redis.set(key1, str1, None, None) key2 <- uuid - _ <- redis.set(key2, str2, None, None, None) + _ <- redis.set(key2, str2, None, None) result <- redis.lcs("unknown", "unknown", Some(LcsQueryType.Len)) } yield assert(result)(equalTo(Lcs.Length(0))) }, @@ -1507,7 +1507,7 @@ trait StringsSpec extends IntegrationSpec { redis <- ZIO.service[Redis] key <- uuid value <- uuid - result <- redis.set(key, value, Some(1.second)) + result <- redis.set(key, value, expireAt = Some(SetExpire.SetExpireSeconds(1.second))) } yield assert(result)(isTrue) }, test("new value with ttl 100 milliseconds") { @@ -1515,7 +1515,7 @@ trait StringsSpec extends IntegrationSpec { redis <- ZIO.service[Redis] key <- uuid value <- uuid - result <- redis.set(key, value, Some(100.milliseconds)) + result <- redis.set(key, value, expireAt = Some(SetExpire.SetExpireMilliseconds(100.milliseconds))) } yield assert(result)(isTrue) }, test("error when negative ttl") { @@ -1523,7 +1523,7 @@ trait StringsSpec extends IntegrationSpec { redis <- ZIO.service[Redis] key <- uuid value <- uuid - result <- redis.set(key, value, Some((-1).millisecond)).either + result <- redis.set(key, value, expireAt = Some(SetExpire.SetExpireMilliseconds((-1).millisecond))).either } yield assert(result)(isLeft(isSubtype[ProtocolError](anything))) }, test("new value with SetNew parameter") { @@ -1569,33 +1569,24 @@ trait StringsSpec extends IntegrationSpec { result <- redis.set(key, value, update = Some(Update.SetExisting)) } yield assert(result)(isTrue) }, - // next three tests include KEEPTTL parameter that is valid for Redis version >= 6 + // next two tests include KEEPTTL parameter that is valid for Redis version >= 6 test("new value with KeepTtl parameter") { for { redis <- ZIO.service[Redis] key <- uuid value <- uuid - result <- redis.set(key, value, keepTtl = Some(KeepTtl)) + result <- redis.set(key, value, expireAt = Some(SetExpire.KeepTtl)) } yield assert(result)(isTrue) - } @@ ignore, + }, test("existing value with KeepTtl parameter") { for { redis <- ZIO.service[Redis] key <- uuid value <- uuid - _ <- redis.set(key, "value", Some(1.second)) - result <- redis.set(key, value, keepTtl = Some(KeepTtl)) + _ <- redis.set(key, "value", expireAt = Some(SetExpire.SetExpireSeconds(1.second))) + result <- redis.set(key, value, expireAt = Some(SetExpire.KeepTtl)) } yield assert(result)(isTrue) - } @@ ignore, - test("existing value with both ttl and KeepTtl parameters") { - for { - redis <- ZIO.service[Redis] - key <- uuid - value <- uuid - _ <- redis.set(key, "value", Some(1.second)) - result <- redis.set(key, value, Some(1.second), keepTtl = Some(KeepTtl)) - } yield assert(result)(isTrue) - } @@ ignore + } ), suite("setBit")( test("for existing key") { @@ -1644,7 +1635,7 @@ trait StringsSpec extends IntegrationSpec { redis <- ZIO.service[Redis] key <- uuid value <- uuid - _ <- redis.setEx(key, 1.second, value) + _ <- redis.set(key, value, expireAt = Some(SetExpire.SetExpireSeconds(1.second))) existsBefore <- redis.exists(key) fiber <- ZIO.sleep(1010.millis).fork <* TestClock.adjust(1010.millis) _ <- fiber.join @@ -1657,7 +1648,7 @@ trait StringsSpec extends IntegrationSpec { key <- uuid value <- uuid _ <- redis.set(key, "value") - _ <- redis.setEx(key, 1.second, value) + _ <- redis.set(key, value, expireAt = Some(SetExpire.SetExpireSeconds(1.second))) existsBefore <- redis.exists(key) fiber <- ZIO.sleep(1010.millis).fork <* TestClock.adjust(1010.millis) _ <- fiber.join @@ -1670,7 +1661,7 @@ trait StringsSpec extends IntegrationSpec { key <- uuid value <- uuid _ <- redis.sAdd(key, "a") - _ <- redis.setEx(key, 1.second, value) + _ <- redis.set(key, value, expireAt = Some(SetExpire.SetExpireSeconds(1.second))) existsBefore <- redis.exists(key) fiber <- ZIO.sleep(1010.millis).fork <* TestClock.adjust(1010.millis) _ <- fiber.join @@ -1682,7 +1673,7 @@ trait StringsSpec extends IntegrationSpec { redis <- ZIO.service[Redis] key <- uuid value <- uuid - result <- redis.setEx(key, 0.seconds, value).either + result <- redis.set(key, value, expireAt = Some(SetExpire.SetExpireSeconds(0.seconds))).either } yield assert(result)(isLeft(isSubtype[ProtocolError](anything))) }, test("error when negative ttl") { @@ -1690,7 +1681,7 @@ trait StringsSpec extends IntegrationSpec { redis <- ZIO.service[Redis] key <- uuid value <- uuid - result <- redis.setEx(key, (-1).second, value).either + result <- redis.set(key, value, expireAt = Some(SetExpire.SetExpireSeconds((-1).second))).either } yield assert(result)(isLeft(isSubtype[ProtocolError](anything))) } ), @@ -1700,7 +1691,7 @@ trait StringsSpec extends IntegrationSpec { redis <- ZIO.service[Redis] key <- uuid value <- uuid - result <- redis.setNx(key, value) + result <- redis.set(key, value, update = Some(Update.SetNew)) } yield assert(result)(isTrue) }, test("existing value") { @@ -1709,7 +1700,7 @@ trait StringsSpec extends IntegrationSpec { key <- uuid value <- uuid _ <- redis.set(key, "value") - result <- redis.setNx(key, value) + result <- redis.set(key, value, update = Some(Update.SetNew)) } yield assert(result)(isFalse) }, test("not string") { @@ -1718,7 +1709,7 @@ trait StringsSpec extends IntegrationSpec { key <- uuid value <- uuid _ <- redis.sAdd(key, "a") - result <- redis.setNx(key, value) + result <- redis.set(key, value, update = Some(Update.SetNew)) } yield assert(result)(isFalse) } ), @@ -1788,29 +1779,17 @@ trait StringsSpec extends IntegrationSpec { } ), suite("getEx")( - test("value exists after removing ttl") { - for { - redis <- ZIO.service[Redis] - key <- uuid - value <- uuid - _ <- redis.pSetEx(key, 10.millis, value) - exists <- redis.getEx(key, persist = true).returning[String] - fiber <- ZIO.sleep(20.millis).fork <* TestClock.adjust(20.millis) - _ <- fiber.join - res <- redis.get(key).returning[String] - } yield assert(res.isDefined)(equalTo(true)) && assert(exists)(equalTo(Some(value))) - } @@ flaky, test("not found value when set seconds ttl") { for { redis <- ZIO.service[Redis] key <- uuid value <- uuid _ <- redis.set(key, value) - exists <- redis.getEx(key, Expire.SetExpireSeconds, 1.second).returning[String] + exists <- redis.getEx(key, GetExpire.GetExpireSeconds(1.second)).returning[String] fiber <- ZIO.sleep(1020.millis).fork <* TestClock.adjust(1020.millis) _ <- fiber.join res <- redis.get(key).returning[String] - } yield assert(res.isDefined)(equalTo(false)) && assert(exists)(equalTo(Some(value))) + } yield assert(res.isDefined)(equalTo(false)) && assert(exists)(isSome(equalTo(value))) } @@ flaky, test("not found value when set milliseconds ttl") { for { @@ -1818,11 +1797,11 @@ trait StringsSpec extends IntegrationSpec { key <- uuid value <- uuid _ <- redis.set(key, value) - exists <- redis.getEx(key, Expire.SetExpireMilliseconds, 10.millis).returning[String] + exists <- redis.getEx(key, GetExpire.GetExpireMilliseconds(10.millis)).returning[String] fiber <- ZIO.sleep(20.millis).fork <* TestClock.adjust(20.millis) _ <- fiber.join res <- redis.get(key).returning[String] - } yield assert(res.isDefined)(equalTo(false)) && assert(exists)(equalTo(Some(value))) + } yield assert(res.isDefined)(equalTo(false)) && assert(exists)(isSome(equalTo(value))) } @@ flaky, test("not found value when set seconds timestamp") { for { @@ -1831,11 +1810,11 @@ trait StringsSpec extends IntegrationSpec { value <- uuid _ <- redis.set(key, value) expiresAt <- Clock.instant.map(_.plusMillis(10.millis.toMillis)) - exists <- redis.getEx(key, ExpiredAt.SetExpireAtSeconds, expiresAt).returning[String] + exists <- redis.getEx(key, GetExpire.GetExpireUnixTimeSeconds(expiresAt)).returning[String] fiber <- ZIO.sleep(20.millis).fork <* TestClock.adjust(20.millis) _ <- fiber.join res <- redis.get(key).returning[String] - } yield assert(res.isDefined)(equalTo(false)) && assert(exists)(equalTo(Some(value))) + } yield assert(res.isDefined)(equalTo(false)) && assert(exists)(isSome(equalTo(value))) } @@ flaky, test("not found value when set milliseconds timestamp") { for { @@ -1844,11 +1823,11 @@ trait StringsSpec extends IntegrationSpec { value <- uuid _ <- redis.set(key, value) expiresAt <- Clock.instant.map(_.plusMillis(10.millis.toMillis)) - exists <- redis.getEx(key, ExpiredAt.SetExpireAtMilliseconds, expiresAt).returning[String] + exists <- redis.getEx(key, GetExpire.GetExpireUnixTimeMilliseconds(expiresAt)).returning[String] fiber <- ZIO.sleep(20.millis).fork <* TestClock.adjust(20.millis) _ <- fiber.join res <- redis.get(key).returning[String] - } yield assert(res.isDefined)(equalTo(false)) && assert(exists)(equalTo(Some(value))) + } yield assert(res.isDefined)(equalTo(false)) && assert(exists)(isSome(equalTo(value))) } @@ flaky, test("key not found") { for { @@ -1857,10 +1836,9 @@ trait StringsSpec extends IntegrationSpec { value <- uuid _ <- redis.set(key, value) expiresAt <- Clock.instant.map(_.plusMillis(10.millis.toMillis)) - res <- redis.getEx(value, ExpiredAt.SetExpireAtMilliseconds, expiresAt).returning[String] - res2 <- redis.getEx(value, Expire.SetExpireMilliseconds, 10.millis).returning[String] - res3 <- redis.getEx(value, persist = true).returning[String] - } yield assert(res)(equalTo(None)) && assert(res2)(equalTo(None)) && assert(res3)(equalTo(None)) + res <- redis.getEx(value, GetExpire.GetExpireUnixTimeMilliseconds(expiresAt)).returning[String] + res2 <- redis.getEx(value, GetExpire.GetExpireMilliseconds(10.millis)).returning[String] + } yield assert(res)(isNone) && assert(res2)(isNone) } @@ flaky ), suite("getDel")( @@ -1877,7 +1855,7 @@ trait StringsSpec extends IntegrationSpec { redis <- ZIO.service[Redis] key <- uuid res <- redis.getDel(key).returning[String] - } yield assert(res)(equalTo(None)) + } yield assert(res)(isNone) }, test("get and remove key") { for { @@ -1887,7 +1865,7 @@ trait StringsSpec extends IntegrationSpec { _ <- redis.set(key, value) res <- redis.getDel(key).returning[String] notFound <- redis.getDel(key).returning[String] - } yield assert(res)(equalTo(Some(value))) && assert(notFound)(equalTo(None)) + } yield assert(res)(isSome(equalTo(value))) && assert(notFound)(isNone) } ) ) diff --git a/modules/redis/src/main/scala/zio/redis/Input.scala b/modules/redis/src/main/scala/zio/redis/Input.scala index 5cde6684b..94aae8f7f 100644 --- a/modules/redis/src/main/scala/zio/redis/Input.scala +++ b/modules/redis/src/main/scala/zio/redis/Input.scala @@ -126,7 +126,7 @@ object Input { case object DbInput extends Input[Long] { def encode(db: Long): RespCommand = - RespCommand(RespCommandArgument.Literal("DB"), RespCommandArgument.Value(db.toString())) + RespCommand(RespCommandArgument.Literal("DB"), RespCommandArgument.Value(db.toString)) } case object BoolInput extends Input[Boolean] { @@ -212,40 +212,28 @@ object Input { RespCommand(RespCommandArgument.Literal("GET"), RespCommandArgument.Value(data)) } - final case class GetExInput[K: BinaryCodec]() extends Input[(K, Expire, Duration)] { - def encode(data: (K, Expire, Duration)): RespCommand = + final case class GetExInput[K: BinaryCodec]() extends Input[(K, GetExpire)] { + def encode(data: (K, GetExpire)): RespCommand = data match { - case (key, Expire.SetExpireSeconds, duration) => + case (key, GetExpire.GetExpireSeconds(duration)) => RespCommand(RespCommandArgument.Key(key), RespCommandArgument.Literal("EX")) ++ DurationSecondsInput.encode( duration ) - case (key, Expire.SetExpireMilliseconds, duration) => + case (key, GetExpire.GetExpireMilliseconds(duration)) => RespCommand(RespCommandArgument.Key(key), RespCommandArgument.Literal("PX")) ++ DurationMillisecondsInput .encode(duration) - } - } - - final case class GetExAtInput[K: BinaryCodec]() extends Input[(K, ExpiredAt, Instant)] { - def encode(data: (K, ExpiredAt, Instant)): RespCommand = - data match { - case (key, ExpiredAt.SetExpireAtSeconds, instant) => + case (key, GetExpire.GetExpireUnixTimeMilliseconds(instant)) => + RespCommand(RespCommandArgument.Key(key), RespCommandArgument.Literal("PXAT")) ++ TimeMillisecondsInput + .encode(instant) + case (key, GetExpire.GetExpireUnixTimeSeconds(instant)) => RespCommand(RespCommandArgument.Key(key), RespCommandArgument.Literal("EXAT")) ++ TimeSecondsInput.encode( instant ) - case (key, ExpiredAt.SetExpireAtMilliseconds, instant) => - RespCommand(RespCommandArgument.Key(key), RespCommandArgument.Literal("PXAT")) ++ TimeMillisecondsInput - .encode(instant) + case (key, GetExpire.Persist) => + RespCommand(RespCommandArgument.Key(key), RespCommandArgument.Literal("PERSIST")) } } - final case class GetExPersistInput[K: BinaryCodec]() extends Input[(K, Boolean)] { - def encode(data: (K, Boolean)): RespCommand = - RespCommand( - if (data._2) Chunk(RespCommandArgument.Key(data._1), RespCommandArgument.Literal("PERSIST")) - else Chunk(RespCommandArgument.Key(data._1)) - ) - } - case object GetKeywordInput extends Input[GetKeyword] { def encode(data: GetKeyword): RespCommand = RespCommand(RespCommandArgument.Literal(data.asString)) @@ -285,11 +273,6 @@ object Input { RespCommand(RespCommandArgument.Value(data.toString)) } - case object KeepTtlInput extends Input[KeepTtl] { - def encode(data: KeepTtl): RespCommand = - RespCommand(RespCommandArgument.Literal(data.asString)) - } - case object LcsQueryTypeInput extends Input[LcsQueryType] { def encode(data: LcsQueryType): RespCommand = data match { case LcsQueryType.Len => RespCommand(RespCommandArgument.Literal("LEN")) @@ -423,6 +406,22 @@ object Input { RespCommand(RespCommandArgument.Literal(data.asString)) } + case object SetExpireInput extends Input[SetExpire] { + def encode(data: SetExpire): RespCommand = + data match { + case SetExpire.KeepTtl => + RespCommand(RespCommandArgument.Literal("KEEPTTL")) + case SetExpire.SetExpireSeconds(duration) => + RespCommand(RespCommandArgument.Literal("EX")) ++ DurationSecondsInput.encode(duration) + case SetExpire.SetExpireMilliseconds(duration) => + RespCommand(RespCommandArgument.Literal("PX")) ++ DurationMillisecondsInput.encode(duration) + case SetExpire.SetExpireUnixTimeMilliseconds(instant) => + RespCommand(RespCommandArgument.Literal("PXAT")) ++ TimeMillisecondsInput.encode(instant) + case SetExpire.SetExpireUnixTimeSeconds(instant) => + RespCommand(RespCommandArgument.Literal("EXAT")) ++ TimeSecondsInput.encode(instant) + } + } + case object SideInput extends Input[Side] { def encode(data: Side): RespCommand = RespCommand(RespCommandArgument.Literal(data.asString)) diff --git a/modules/redis/src/main/scala/zio/redis/api/SortedSets.scala b/modules/redis/src/main/scala/zio/redis/api/SortedSets.scala index 98516baf6..5c108a0be 100644 --- a/modules/redis/src/main/scala/zio/redis/api/SortedSets.scala +++ b/modules/redis/src/main/scala/zio/redis/api/SortedSets.scala @@ -110,6 +110,8 @@ trait SortedSets[G[+_]] extends RedisEnvironment[G] { * Key of set to add to * @param update * Set existing and never add elements or always set new elements and don't update existing elements + * @param updateByScore + * Set update existing elements if the new score is less than the current score or greater than the current score * @param change * Modify the return value from the number of new elements added, to the total number of elements change * @param memberScore @@ -144,6 +146,8 @@ trait SortedSets[G[+_]] extends RedisEnvironment[G] { * Key of set to add to. * @param update * Set existing and never add elements or always set new elements and don't update existing elements + * @param updateByScore + * Set update existing elements if the new score is less than the current score or greater than the current score * @param change * Modify the return value from the number of new elements added, to the total number of elements change * @param increment diff --git a/modules/redis/src/main/scala/zio/redis/api/Strings.scala b/modules/redis/src/main/scala/zio/redis/api/Strings.scala index a2c50d78b..ab2696442 100644 --- a/modules/redis/src/main/scala/zio/redis/api/Strings.scala +++ b/modules/redis/src/main/scala/zio/redis/api/Strings.scala @@ -24,8 +24,6 @@ import zio.redis._ import zio.redis.internal.{RedisCommand, RedisEnvironment} import zio.schema.Schema -import java.time.Instant - trait Strings[G[+_]] extends RedisEnvironment[G] { import Strings._ @@ -216,50 +214,13 @@ trait Strings[G[+_]] extends RedisEnvironment[G] { * @param expire * The option which can modify command behavior. e.g. use `Expire.SetExpireSeconds` set the specified expire time in * seconds - * @param expireTime - * Time in seconds/milliseconds until the string should expire - * @return - * Returns the value of the string or None if it did not previously have a value. - */ - final def getEx[K: Schema](key: K, expire: Expire, expireTime: Duration): ResultBuilder1[Option, G] = - new ResultBuilder1[Option, G] { - def returning[R: Schema]: G[Option[R]] = - RedisCommand(GetEx, GetExInput[K](), OptionalOutput(ArbitraryOutput[R]())).run((key, expire, expireTime)) - } - - /** - * Get the value of key and set its expiration. - * - * @param key - * Key to get the value of - * @param expiredAt - * The option which can modify command behavior. e.g. use `Expire.SetExpireAtSeconds` set the specified Unix time at - * which the key will expire in seconds - * @param timestamp - * an absolute Unix timestamp (seconds/milliseconds since January 1, 1970) * @return * Returns the value of the string or None if it did not previously have a value. */ - final def getEx[K: Schema](key: K, expiredAt: ExpiredAt, timestamp: Instant): ResultBuilder1[Option, G] = + final def getEx[K: Schema](key: K, expire: GetExpire): ResultBuilder1[Option, G] = new ResultBuilder1[Option, G] { def returning[R: Schema]: G[Option[R]] = - RedisCommand(GetEx, GetExAtInput[K](), OptionalOutput(ArbitraryOutput[R]())).run((key, expiredAt, timestamp)) - } - - /** - * Get the value of key and remove the time to live associated with the key. - * - * @param key - * Key to get the value of - * @param persist - * if true, remove the time to live associated with the key, otherwise not - * @return - * Returns the value of the string or None if it did not previously have a value. - */ - final def getEx[K: Schema](key: K, persist: Boolean): ResultBuilder1[Option, G] = - new ResultBuilder1[Option, G] { - def returning[R: Schema]: G[Option[R]] = - RedisCommand(GetEx, GetExPersistInput[K](), OptionalOutput(ArbitraryOutput[R]())).run((key, persist)) + RedisCommand(GetEx, GetExInput[K](), OptionalOutput(ArbitraryOutput[R]())).run((key, expire)) } /** @@ -457,12 +418,10 @@ trait Strings[G[+_]] extends RedisEnvironment[G] { * Key of the string to set * @param value * Value to set - * @param expireTime - * Time until the string expires * @param update * Update can be Update.SetExisting which only sets the key if it exists, or Update.SetNew which nly sets the key if * it does not exist - * @param keepTtl + * @param expireAt * When set any previously set expire time remains unchanged * @return * true if set was executed correctly, false otherwise. @@ -470,21 +429,17 @@ trait Strings[G[+_]] extends RedisEnvironment[G] { final def set[K: Schema, V: Schema]( key: K, value: V, - expireTime: Option[Duration] = None, update: Option[Update] = None, - keepTtl: Option[KeepTtl] = None + expireAt: Option[SetExpire] = None ): G[Boolean] = { - val input = - Tuple5( - ArbitraryKeyInput[K](), - ArbitraryValueInput[V](), - OptionalInput(DurationTtlInput), - OptionalInput(UpdateInput), - OptionalInput(KeepTtlInput) - ) - + val input = Tuple4( + ArbitraryKeyInput[K](), + ArbitraryValueInput[V](), + OptionalInput(UpdateInput), + OptionalInput(SetExpireInput) + ) val command = RedisCommand(Set, input, SetOutput) - command.run((key, value, expireTime, update, keepTtl)) + command.run((key, value, update, expireAt)) } /** @@ -505,26 +460,6 @@ trait Strings[G[+_]] extends RedisEnvironment[G] { command.run((key, offset, value)) } - /** - * Set the value and expiration of a key. - * - * @param key - * Key of the value to update - * @param expiration - * Expiration time for the value - * @param value - * New value to set - */ - final def setEx[K: Schema, V: Schema]( - key: K, - expiration: Duration, - value: V - ): G[Unit] = { - val command = - RedisCommand(SetEx, Tuple3(ArbitraryKeyInput[K](), DurationSecondsInput, ArbitraryValueInput[V]()), UnitOutput) - command.run((key, expiration, value)) - } - /** * Set the string value of a key with a 'GET' option. * @@ -532,12 +467,10 @@ trait Strings[G[+_]] extends RedisEnvironment[G] { * Key of the string to set * @param value * Value to set - * @param expireTime - * Time until the string expires * @param update * Update can be Update.SetExisting which only sets the key if it exists, or Update.SetNew which nly sets the key if * it does not exist - * @param keepTtl + * @param expireAt * When set any previously set expire time remains unchanged * @return * the old value stored at key, or None if key did not exist @@ -545,38 +478,18 @@ trait Strings[G[+_]] extends RedisEnvironment[G] { final def setGet[K: Schema, V: Schema]( key: K, value: V, - expireTime: Option[Duration] = None, update: Option[Update] = None, - keepTtl: Option[KeepTtl] = None + expireAt: Option[SetExpire] = None ): G[Option[V]] = { - val input = - Tuple6( - ArbitraryKeyInput[K](), - ArbitraryValueInput[V](), - OptionalInput(DurationTtlInput), - OptionalInput(UpdateInput), - OptionalInput(KeepTtlInput), - GetKeywordInput - ) - + val input = Tuple5( + ArbitraryKeyInput[K](), + ArbitraryValueInput[V](), + OptionalInput(UpdateInput), + OptionalInput(SetExpireInput), + GetKeywordInput + ) val command = RedisCommand(Set, input, OptionalOutput(ArbitraryOutput[V]())) - command.run((key, value, expireTime, update, keepTtl, GetKeyword)) - } - - /** - * Set the value of a key, only if the key does not exist. - * - * @param key - * Key of the value to set if the key does not exist - * @param value - * Value to set - * @return - * Returns 1 if the key was set. 0 if the key was not set. - */ - final def setNx[K: Schema, V: Schema](key: K, value: V): G[Boolean] = { - val command = - RedisCommand(SetNx, Tuple2(ArbitraryKeyInput[K](), ArbitraryValueInput[V]()), BoolOutput) - command.run((key, value)) + command.run((key, value, update, expireAt, GetKeyword)) } /** @@ -635,8 +548,6 @@ private[redis] object Strings { final val PSetEx = "PSETEX" final val Set = "SET" final val SetBit = "SETBIT" - final val SetEx = "SETEX" - final val SetNx = "SETNX" final val SetRange = "SETRANGE" final val StrLen = "STRLEN" } diff --git a/modules/redis/src/main/scala/zio/redis/options/Shared.scala b/modules/redis/src/main/scala/zio/redis/options/Shared.scala index 2139779ba..ed65b1a0e 100644 --- a/modules/redis/src/main/scala/zio/redis/options/Shared.scala +++ b/modules/redis/src/main/scala/zio/redis/options/Shared.scala @@ -17,25 +17,10 @@ package zio.redis.options trait Shared { - sealed trait Update { self => - private[redis] final def asString: String = - self match { - case Update.SetExisting => "XX" - case Update.SetNew => "NX" - case Update.SetLessThan => "LT" - case Update.SetGreaterThan => "GT" - } - } - - object Update { - case object SetExisting extends Update - case object SetNew extends Update - case object SetLessThan extends Update - case object SetGreaterThan extends Update - } - sealed case class Count(count: Long) + sealed case class Limit(offset: Long, count: Long) + sealed trait Order { self => private[redis] final def asString: String = self match { @@ -49,9 +34,25 @@ trait Shared { case object Descending extends Order } - sealed case class Limit(offset: Long, count: Long) + sealed case class Pattern(pattern: String) sealed case class Store(key: String) - sealed case class Pattern(pattern: String) + sealed trait Update { self => + private[redis] final def asString: String = + self match { + case Update.SetExisting => "XX" + case Update.SetNew => "NX" + case Update.SetLessThan => "LT" + case Update.SetGreaterThan => "GT" + } + } + + object Update { + case object SetExisting extends Update + case object SetNew extends Update + case object SetLessThan extends Update + case object SetGreaterThan extends Update + } + } diff --git a/modules/redis/src/main/scala/zio/redis/options/Strings.scala b/modules/redis/src/main/scala/zio/redis/options/Strings.scala index 6efd60809..7f086ad2c 100644 --- a/modules/redis/src/main/scala/zio/redis/options/Strings.scala +++ b/modules/redis/src/main/scala/zio/redis/options/Strings.scala @@ -16,6 +16,10 @@ package zio.redis.options +import zio.Duration + +import java.time.Instant + trait Strings { sealed trait Lcs @@ -93,36 +97,24 @@ trait Strings { sealed case class BitPosRange(start: Long, end: Option[Long]) - case object KeepTtl { - private[redis] def asString: String = "KEEPTTL" - } - - type KeepTtl = KeepTtl.type + sealed trait SetExpire - sealed trait Expire { self => - private[redis] final def asString: String = - self match { - case Expire.SetExpireSeconds => "EX" - case Expire.SetExpireMilliseconds => "PX" - } + object SetExpire { + case object KeepTtl extends SetExpire + case class SetExpireMilliseconds(duration: Duration) extends SetExpire + case class SetExpireSeconds(duration: Duration) extends SetExpire + case class SetExpireUnixTimeMilliseconds(instant: Instant) extends SetExpire + case class SetExpireUnixTimeSeconds(instant: Instant) extends SetExpire } - object Expire { - case object SetExpireSeconds extends Expire - case object SetExpireMilliseconds extends Expire - } - - sealed trait ExpiredAt { self => - private[redis] final def asString: String = - self match { - case ExpiredAt.SetExpireAtSeconds => "EXAT" - case ExpiredAt.SetExpireAtMilliseconds => "PXAT" - } - } + sealed trait GetExpire - object ExpiredAt { - case object SetExpireAtSeconds extends ExpiredAt - case object SetExpireAtMilliseconds extends ExpiredAt + object GetExpire { + case class GetExpireMilliseconds(duration: Duration) extends GetExpire + case class GetExpireSeconds(duration: Duration) extends GetExpire + case class GetExpireUnixTimeMilliseconds(instant: Instant) extends GetExpire + case class GetExpireUnixTimeSeconds(instant: Instant) extends GetExpire + case object Persist extends GetExpire } case object GetKeyword { diff --git a/modules/redis/src/test/scala/zio/redis/InputSpec.scala b/modules/redis/src/test/scala/zio/redis/InputSpec.scala index d753f895f..1f34fcde8 100644 --- a/modules/redis/src/test/scala/zio/redis/InputSpec.scala +++ b/modules/redis/src/test/scala/zio/redis/InputSpec.scala @@ -414,13 +414,6 @@ object InputSpec extends BaseSpec { } yield assert(result)(equalTo(RespCommand(Value("0")))) } ), - suite("KeepTtl")( - test("valid value") { - for { - result <- ZIO.attempt(KeepTtlInput.encode(KeepTtl)) - } yield assert(result)(equalTo(RespCommand(Literal("KEEPTTL")))) - } - ), suite("LexRange")( test("with unbound min and unbound max") { for { @@ -1294,42 +1287,29 @@ object InputSpec extends BaseSpec { suite("GetEx")( test("GetExInput - valid value") { for { - resultSeconds <- - ZIO.attempt(GetExInput[String]().encode(scala.Tuple3.apply("key", Expire.SetExpireSeconds, 1.second))) - resultMilliseconds <- - ZIO.attempt(GetExInput[String]().encode(scala.Tuple3("key", Expire.SetExpireMilliseconds, 100.millis))) - } yield assert(resultSeconds)(equalTo(RespCommand(Key("key"), Literal("EX"), Value("1")))) && assert( - resultMilliseconds - )( - equalTo(RespCommand(Key("key"), Literal("PX"), Value("100"))) - ) - }, - test("GetExAtInput - valid value") { - for { - resultSeconds <- + resultSeconds <- + ZIO.attempt(GetExInput[String]().encode(scala.Tuple2("key", GetExpire.GetExpireSeconds(1.second)))) + resultMilliseconds <- + ZIO.attempt(GetExInput[String]().encode(scala.Tuple2("key", GetExpire.GetExpireMilliseconds(100.millis)))) + resultUnixTimeSeconds <- ZIO.attempt( - GetExAtInput[String]().encode( - scala.Tuple3("key", ExpiredAt.SetExpireAtSeconds, Instant.parse("2021-04-06T00:00:00Z")) + GetExInput[String]().encode( + scala.Tuple2("key", GetExpire.GetExpireUnixTimeSeconds(Instant.parse("2021-04-06T00:00:00Z"))) ) ) - resultMilliseconds <- + resultUnixTimeMilliseconds <- ZIO.attempt( - GetExAtInput[String]().encode( - scala.Tuple3("key", ExpiredAt.SetExpireAtMilliseconds, Instant.parse("2021-04-06T00:00:00Z")) + GetExInput[String]().encode( + scala.Tuple2("key", GetExpire.GetExpireUnixTimeMilliseconds(Instant.parse("2021-04-06T00:00:00Z"))) ) ) - } yield assert(resultSeconds)( - equalTo(RespCommand(Key("key"), Literal("EXAT"), Value("1617667200"))) - ) && assert(resultMilliseconds)( - equalTo(RespCommand(Key("key"), Literal("PXAT"), Value("1617667200000"))) - ) - }, - test("GetExPersistInput - valid value") { - for { - result <- ZIO.attempt(GetExPersistInput[String]().encode("key" -> true)) - resultWithoutOption <- ZIO.attempt(GetExPersistInput[String]().encode("key" -> false)) - } yield assert(result)(equalTo(RespCommand(Key("key"), Literal("PERSIST")))) && - assert(resultWithoutOption)(equalTo(RespCommand(Key("key")))) + resultPersist <- ZIO.attempt(GetExInput[String]().encode(scala.Tuple2("key", GetExpire.Persist))) + } yield assert(resultSeconds)(equalTo(RespCommand(Key("key"), Literal("EX"), Value("1")))) && + assert(resultMilliseconds)(equalTo(RespCommand(Key("key"), Literal("PX"), Value("100")))) && + assert(resultUnixTimeSeconds)(equalTo(RespCommand(Key("key"), Literal("EXAT"), Value("1617667200")))) && + assert(resultUnixTimeMilliseconds)( + equalTo(RespCommand(Key("key"), Literal("PXAT"), Value("1617667200000"))) + ) && assert(resultPersist)(equalTo(RespCommand(Key("key"), Literal("PERSIST")))) } ) ) From f8158570e2ba9bbeab669096b12aa51ca62e33cd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dragutin=20Marjanovi=C4=87?= Date: Sun, 15 Sep 2024 21:55:32 +0200 Subject: [PATCH 02/16] Format index.md --- docs/index.md | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/docs/index.md b/docs/index.md index b1b0753cb..a10a68a80 100644 --- a/docs/index.md +++ b/docs/index.md @@ -49,15 +49,16 @@ object ZIORedisExample extends ZIOAppDefault { def get[A: Schema]: BinaryCodec[A] = ProtobufCodec.protobufCodec } - val myApp: ZIO[Redis, RedisError, Unit] = for { - redis <- ZIO.service[Redis] - _ <- redis.set("myKey", 8L, expireAt = Some(SetExpire.SetExpireSeconds(1.minutes))) - v <- redis.get("myKey").returning[Long] - _ <- Console.printLine(s"Value of myKey: $v").orDie - _ <- redis.hSet("myHash", ("k1", 6), ("k2", 2)) - _ <- redis.rPush("myList", 1, 2, 3, 4) - _ <- redis.sAdd("mySet", "a", "b", "a", "c") - } yield () + val myApp: ZIO[Redis, RedisError, Unit] = + for { + redis <- ZIO.service[Redis] + _ <- redis.set("myKey", 8L, expireAt = Some(SetExpire.SetExpireSeconds(1.minutes))) + v <- redis.get("myKey").returning[Long] + _ <- Console.printLine(s"Value of myKey: $v").orDie + _ <- redis.hSet("myHash", ("k1", 6), ("k2", 2)) + _ <- redis.rPush("myList", 1, 2, 3, 4) + _ <- redis.sAdd("mySet", "a", "b", "a", "c") + } yield () override def run = myApp.provide(Redis.local, ZLayer.succeed[CodecSupplier](ProtobufCodecSupplier)) From 2292dd1900c94e2924d9d719b276d5bdae127041 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dragutin=20Marjanovi=C4=87?= Date: Mon, 16 Sep 2024 16:06:58 +0200 Subject: [PATCH 03/16] Introduce 'UpdateByScore' --- .../test/scala/zio/redis/SortedSetsSpec.scala | 12 ++++++--- .../src/main/scala/zio/redis/Input.scala | 5 ++++ .../main/scala/zio/redis/api/SortedSets.scala | 24 +++++++++++++----- .../main/scala/zio/redis/options/Shared.scala | 25 +++++++++++++------ .../src/test/scala/zio/redis/InputSpec.scala | 12 +++++++++ 5 files changed, 61 insertions(+), 17 deletions(-) diff --git a/modules/redis-it/src/test/scala/zio/redis/SortedSetsSpec.scala b/modules/redis-it/src/test/scala/zio/redis/SortedSetsSpec.scala index 118e0a123..1331b3412 100644 --- a/modules/redis-it/src/test/scala/zio/redis/SortedSetsSpec.scala +++ b/modules/redis-it/src/test/scala/zio/redis/SortedSetsSpec.scala @@ -183,7 +183,10 @@ trait SortedSetsSpec extends IntegrationSpec { key <- uuid _ <- redis.zAdd(key)(MemberScore("v1", 3d)) _ <- redis.zAdd(key)(MemberScore("v2", 4d)) - added <- redis.zAdd(key, update = Some(Update.SetLessThan))(MemberScore("v3", 1d), MemberScore("v1", 2d)) + added <- redis.zAdd(key, updateByScore = Some(UpdateByScore.SetLessThan))( + MemberScore("v3", 1d), + MemberScore("v1", 2d) + ) result <- redis.zRange(key, 0 to -1).returning[String] } yield assert(added)(equalTo(1L)) && assert(result.toList)(equalTo(List("v3", "v1", "v2"))) }, @@ -193,7 +196,10 @@ trait SortedSetsSpec extends IntegrationSpec { key <- uuid _ <- redis.zAdd(key)(MemberScore("v1", 1d)) _ <- redis.zAdd(key)(MemberScore("v2", 2d)) - added <- redis.zAdd(key, update = Some(Update.SetGreaterThan))(MemberScore("v3", 1d), MemberScore("v1", 3d)) + added <- redis.zAdd(key, updateByScore = Some(UpdateByScore.SetGreaterThan))( + MemberScore("v3", 1d), + MemberScore("v1", 3d) + ) result <- redis.zRange(key, 0 to -1).returning[String] } yield assert(added)(equalTo(1L)) && assert(result.toList)(equalTo(List("v3", "v2", "v1"))) }, @@ -203,7 +209,7 @@ trait SortedSetsSpec extends IntegrationSpec { key <- uuid _ <- redis.zAdd(key)(MemberScore("v1", 1d)) _ <- redis.zAdd(key)(MemberScore("v2", 2d)) - added <- redis.zAdd(key, update = Some(Update.SetGreaterThan), change = Some(Changed))( + added <- redis.zAdd(key, updateByScore = Some(UpdateByScore.SetGreaterThan), change = Some(Changed))( MemberScore("v3", 1d), MemberScore("v1", 3d) ) diff --git a/modules/redis/src/main/scala/zio/redis/Input.scala b/modules/redis/src/main/scala/zio/redis/Input.scala index 94aae8f7f..a16dffeae 100644 --- a/modules/redis/src/main/scala/zio/redis/Input.scala +++ b/modules/redis/src/main/scala/zio/redis/Input.scala @@ -584,6 +584,11 @@ object Input { RespCommand(RespCommandArgument.Value(data.asString)) } + case object UpdateByScoreInput extends Input[UpdateByScore] { + def encode(data: UpdateByScore): RespCommand = + RespCommand(RespCommandArgument.Value(data.asString)) + } + case object ValueInput extends Input[Chunk[Byte]] { def encode(data: Chunk[Byte]): RespCommand = RespCommand(RespCommandArgument.Value(data)) diff --git a/modules/redis/src/main/scala/zio/redis/api/SortedSets.scala b/modules/redis/src/main/scala/zio/redis/api/SortedSets.scala index 5c108a0be..bb61be8c7 100644 --- a/modules/redis/src/main/scala/zio/redis/api/SortedSets.scala +++ b/modules/redis/src/main/scala/zio/redis/api/SortedSets.scala @@ -122,21 +122,27 @@ trait SortedSets[G[+_]] extends RedisEnvironment[G] { * The number of elements added to the sorted set, not including elements already existing for which the score was * updated. */ - final def zAdd[K: Schema, M: Schema](key: K, update: Option[Update] = None, change: Option[Changed] = None)( + final def zAdd[K: Schema, M: Schema]( + key: K, + update: Option[Update] = None, + updateByScore: Option[UpdateByScore] = None, + change: Option[Changed] = None + )( memberScore: MemberScore[M], memberScores: MemberScore[M]* ): G[Long] = { val command = RedisCommand( ZAdd, - Tuple4( + Tuple5( ArbitraryKeyInput[K](), OptionalInput(UpdateInput), + OptionalInput(UpdateByScoreInput), OptionalInput(ChangedInput), NonEmptyList(MemberScoreInput[M]()) ), LongOutput ) - command.run((key, update, change, (memberScore, memberScores.toList))) + command.run((key, update, updateByScore, change, (memberScore, memberScores.toList))) } /** @@ -160,23 +166,29 @@ trait SortedSets[G[+_]] extends RedisEnvironment[G] { * The new score of member (a double precision floating point number), or None if the operation was aborted (when * called with either the XX or the NX option). */ - final def zAddWithIncr[K: Schema, M: Schema](key: K, update: Option[Update] = None, change: Option[Changed] = None)( + final def zAddWithIncr[K: Schema, M: Schema]( + key: K, + update: Option[Update] = None, + updateByScore: Option[UpdateByScore] = None, + change: Option[Changed] = None + )( increment: Increment, memberScore: MemberScore[M], memberScores: MemberScore[M]* ): G[Option[Double]] = { val command = RedisCommand( ZAdd, - Tuple5( + Tuple6( ArbitraryKeyInput[K](), OptionalInput(UpdateInput), + OptionalInput(UpdateByScoreInput), OptionalInput(ChangedInput), IncrementInput, NonEmptyList(MemberScoreInput[M]()) ), OptionalOutput(DoubleOutput) ) - command.run((key, update, change, increment, (memberScore, memberScores.toList))) + command.run((key, update, updateByScore, change, increment, (memberScore, memberScores.toList))) } /** diff --git a/modules/redis/src/main/scala/zio/redis/options/Shared.scala b/modules/redis/src/main/scala/zio/redis/options/Shared.scala index ed65b1a0e..c7aaef268 100644 --- a/modules/redis/src/main/scala/zio/redis/options/Shared.scala +++ b/modules/redis/src/main/scala/zio/redis/options/Shared.scala @@ -41,18 +41,27 @@ trait Shared { sealed trait Update { self => private[redis] final def asString: String = self match { - case Update.SetExisting => "XX" - case Update.SetNew => "NX" - case Update.SetLessThan => "LT" - case Update.SetGreaterThan => "GT" + case Update.SetExisting => "XX" + case Update.SetNew => "NX" } } object Update { - case object SetExisting extends Update - case object SetNew extends Update - case object SetLessThan extends Update - case object SetGreaterThan extends Update + case object SetExisting extends Update + case object SetNew extends Update + } + + sealed trait UpdateByScore { self => + private[redis] final def asString: String = + self match { + case UpdateByScore.SetLessThan => "LT" + case UpdateByScore.SetGreaterThan => "GT" + } + } + + object UpdateByScore { + case object SetLessThan extends UpdateByScore + case object SetGreaterThan extends UpdateByScore } } diff --git a/modules/redis/src/test/scala/zio/redis/InputSpec.scala b/modules/redis/src/test/scala/zio/redis/InputSpec.scala index 1f34fcde8..0e892e456 100644 --- a/modules/redis/src/test/scala/zio/redis/InputSpec.scala +++ b/modules/redis/src/test/scala/zio/redis/InputSpec.scala @@ -1022,6 +1022,18 @@ object InputSpec extends BaseSpec { } yield assert(result)(equalTo(RespCommand(Value("NX")))) } ), + suite("UpdateByScore")( + test("set greater than") { + for { + result <- ZIO.attempt(UpdateByScoreInput.encode(UpdateByScore.SetGreaterThan)) + } yield assert(result)(equalTo(RespCommand(Value("XX")))) + }, + test("set less than") { + for { + result <- ZIO.attempt(UpdateByScoreInput.encode(UpdateByScore.SetLessThan)) + } yield assert(result)(equalTo(RespCommand(Value("NX")))) + } + ), suite("Id")( test("valid value") { for { From e2422688efc31552813065efeda8d3617793cbdf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dragutin=20Marjanovi=C4=87?= Date: Mon, 16 Sep 2024 18:49:53 +0200 Subject: [PATCH 04/16] Fix tests --- modules/redis/src/test/scala/zio/redis/InputSpec.scala | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/redis/src/test/scala/zio/redis/InputSpec.scala b/modules/redis/src/test/scala/zio/redis/InputSpec.scala index 0e892e456..de450f8a2 100644 --- a/modules/redis/src/test/scala/zio/redis/InputSpec.scala +++ b/modules/redis/src/test/scala/zio/redis/InputSpec.scala @@ -1026,12 +1026,12 @@ object InputSpec extends BaseSpec { test("set greater than") { for { result <- ZIO.attempt(UpdateByScoreInput.encode(UpdateByScore.SetGreaterThan)) - } yield assert(result)(equalTo(RespCommand(Value("XX")))) + } yield assert(result)(equalTo(RespCommand(Value("GT")))) }, test("set less than") { for { result <- ZIO.attempt(UpdateByScoreInput.encode(UpdateByScore.SetLessThan)) - } yield assert(result)(equalTo(RespCommand(Value("NX")))) + } yield assert(result)(equalTo(RespCommand(Value("LT")))) } ), suite("Id")( From 246a65f12908f257060abe44860ffbdac38e1139 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dragutin=20Marjanovi=C4=87?= Date: Fri, 27 Sep 2024 01:00:26 +0200 Subject: [PATCH 05/16] Fix typos --- modules/redis/src/main/scala/zio/redis/api/Connection.scala | 2 +- modules/redis/src/main/scala/zio/redis/api/SortedSets.scala | 4 ++-- modules/redis/src/main/scala/zio/redis/api/Streams.scala | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/modules/redis/src/main/scala/zio/redis/api/Connection.scala b/modules/redis/src/main/scala/zio/redis/api/Connection.scala index 501154ba5..ac934df0b 100644 --- a/modules/redis/src/main/scala/zio/redis/api/Connection.scala +++ b/modules/redis/src/main/scala/zio/redis/api/Connection.scala @@ -26,7 +26,7 @@ trait Connection[G[+_]] extends RedisEnvironment[G] { /** * Authenticates the current connection to the server in two cases: - * - If the Redis server is password protected via the the ''requirepass'' option + * - If the Redis server is password protected via the ''requirepass'' option * - If a Redis 6.0 instance, or greater, is using the [[https://redis.io/topics/acl Redis ACL system]]. In this * case it is assumed that the implicit username is ''default''. * diff --git a/modules/redis/src/main/scala/zio/redis/api/SortedSets.scala b/modules/redis/src/main/scala/zio/redis/api/SortedSets.scala index bb61be8c7..d1d7c4169 100644 --- a/modules/redis/src/main/scala/zio/redis/api/SortedSets.scala +++ b/modules/redis/src/main/scala/zio/redis/api/SortedSets.scala @@ -117,7 +117,7 @@ trait SortedSets[G[+_]] extends RedisEnvironment[G] { * @param memberScore * Score that should be added to specific element for a given sorted set key * @param memberScores - * Rest scores that should be added to specific elements fr a given sorted set key + * Rest scores that should be added to specific elements for a given sorted set key * @return * The number of elements added to the sorted set, not including elements already existing for which the score was * updated. @@ -769,7 +769,7 @@ trait SortedSets[G[+_]] extends RedisEnvironment[G] { * @param members * Rest members to be removed * @return - * The number of members removed from the sorted set, not including non existing members. + * The number of members removed from the sorted set, not including non-existing members. */ final def zRem[K: Schema, M: Schema](key: K, member: M, members: M*): G[Long] = { val command = diff --git a/modules/redis/src/main/scala/zio/redis/api/Streams.scala b/modules/redis/src/main/scala/zio/redis/api/Streams.scala index b6a8cc4de..fc7af7caf 100644 --- a/modules/redis/src/main/scala/zio/redis/api/Streams.scala +++ b/modules/redis/src/main/scala/zio/redis/api/Streams.scala @@ -730,7 +730,7 @@ trait Streams[G[+_]] extends RedisEnvironment[G] { Tuple3(OptionalInput(CountInput), OptionalInput(BlockInput), StreamsInput[SK, I]()), ChunkOutput(StreamOutput[SK, I, RK, RV]()) ) - command.run((count.map(Count(_)), block, (stream, Chunk.fromIterable(streams)))) + command.run((count.map(Count), block, (stream, Chunk.fromIterable(streams)))) } } @@ -781,7 +781,7 @@ trait Streams[G[+_]] extends RedisEnvironment[G] { ) val noAckOpt = if (noAck) Some(NoAck) else None - command.run((group, consumer, count.map(Count(_)), block, noAckOpt, (stream, Chunk.fromIterable(streams)))) + command.run((group, consumer, count.map(Count), block, noAckOpt, (stream, Chunk.fromIterable(streams)))) } } From 9ac94fa1ef116f034ae14175f89e920401b47c5a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dragutin=20Marjanovi=C4=87?= Date: Fri, 27 Sep 2024 01:21:55 +0200 Subject: [PATCH 06/16] Fix code remarks --- .../zio/redis/example/ContributorsCache.scala | 2 +- .../test/scala/zio/redis/StringsSpec.scala | 30 +++++----- .../src/main/scala/zio/redis/Input.scala | 56 +++++++++++-------- .../scala/zio/redis/options/Strings.scala | 22 ++++---- .../src/test/scala/zio/redis/InputSpec.scala | 22 ++++---- 5 files changed, 71 insertions(+), 61 deletions(-) diff --git a/modules/example/src/main/scala/zio/redis/example/ContributorsCache.scala b/modules/example/src/main/scala/zio/redis/example/ContributorsCache.scala index a6d65f58b..af71b4bd6 100644 --- a/modules/example/src/main/scala/zio/redis/example/ContributorsCache.scala +++ b/modules/example/src/main/scala/zio/redis/example/ContributorsCache.scala @@ -40,7 +40,7 @@ object ContributorsCache { ZIO .fromOption(NonEmptyChunk.fromChunk(contributors)) .map(Contributors(_).toJson) - .flatMap(data => redis.set(repository.key, data, expireAt = Some(SetExpire.SetExpireSeconds(1.minute))).orDie) + .flatMap(data => redis.set(repository.key, data, expireAt = Some(SetExpire.Seconds(60))).orDie) .ignore private def read(repository: Repository): IO[ApiError, Contributors] = diff --git a/modules/redis-it/src/test/scala/zio/redis/StringsSpec.scala b/modules/redis-it/src/test/scala/zio/redis/StringsSpec.scala index 6d3a1cfcc..08983c91f 100644 --- a/modules/redis-it/src/test/scala/zio/redis/StringsSpec.scala +++ b/modules/redis-it/src/test/scala/zio/redis/StringsSpec.scala @@ -1507,7 +1507,7 @@ trait StringsSpec extends IntegrationSpec { redis <- ZIO.service[Redis] key <- uuid value <- uuid - result <- redis.set(key, value, expireAt = Some(SetExpire.SetExpireSeconds(1.second))) + result <- redis.set(key, value, expireAt = Some(SetExpire.Seconds(1))) } yield assert(result)(isTrue) }, test("new value with ttl 100 milliseconds") { @@ -1515,7 +1515,7 @@ trait StringsSpec extends IntegrationSpec { redis <- ZIO.service[Redis] key <- uuid value <- uuid - result <- redis.set(key, value, expireAt = Some(SetExpire.SetExpireMilliseconds(100.milliseconds))) + result <- redis.set(key, value, expireAt = Some(SetExpire.Milliseconds(100))) } yield assert(result)(isTrue) }, test("error when negative ttl") { @@ -1523,7 +1523,7 @@ trait StringsSpec extends IntegrationSpec { redis <- ZIO.service[Redis] key <- uuid value <- uuid - result <- redis.set(key, value, expireAt = Some(SetExpire.SetExpireMilliseconds((-1).millisecond))).either + result <- redis.set(key, value, expireAt = Some(SetExpire.Milliseconds(-1))).either } yield assert(result)(isLeft(isSubtype[ProtocolError](anything))) }, test("new value with SetNew parameter") { @@ -1583,7 +1583,7 @@ trait StringsSpec extends IntegrationSpec { redis <- ZIO.service[Redis] key <- uuid value <- uuid - _ <- redis.set(key, "value", expireAt = Some(SetExpire.SetExpireSeconds(1.second))) + _ <- redis.set(key, "value", expireAt = Some(SetExpire.Seconds(1))) result <- redis.set(key, value, expireAt = Some(SetExpire.KeepTtl)) } yield assert(result)(isTrue) } @@ -1635,7 +1635,7 @@ trait StringsSpec extends IntegrationSpec { redis <- ZIO.service[Redis] key <- uuid value <- uuid - _ <- redis.set(key, value, expireAt = Some(SetExpire.SetExpireSeconds(1.second))) + _ <- redis.set(key, value, expireAt = Some(SetExpire.Seconds(1))) existsBefore <- redis.exists(key) fiber <- ZIO.sleep(1010.millis).fork <* TestClock.adjust(1010.millis) _ <- fiber.join @@ -1648,7 +1648,7 @@ trait StringsSpec extends IntegrationSpec { key <- uuid value <- uuid _ <- redis.set(key, "value") - _ <- redis.set(key, value, expireAt = Some(SetExpire.SetExpireSeconds(1.second))) + _ <- redis.set(key, value, expireAt = Some(SetExpire.Seconds(1))) existsBefore <- redis.exists(key) fiber <- ZIO.sleep(1010.millis).fork <* TestClock.adjust(1010.millis) _ <- fiber.join @@ -1661,7 +1661,7 @@ trait StringsSpec extends IntegrationSpec { key <- uuid value <- uuid _ <- redis.sAdd(key, "a") - _ <- redis.set(key, value, expireAt = Some(SetExpire.SetExpireSeconds(1.second))) + _ <- redis.set(key, value, expireAt = Some(SetExpire.Seconds(1))) existsBefore <- redis.exists(key) fiber <- ZIO.sleep(1010.millis).fork <* TestClock.adjust(1010.millis) _ <- fiber.join @@ -1673,7 +1673,7 @@ trait StringsSpec extends IntegrationSpec { redis <- ZIO.service[Redis] key <- uuid value <- uuid - result <- redis.set(key, value, expireAt = Some(SetExpire.SetExpireSeconds(0.seconds))).either + result <- redis.set(key, value, expireAt = Some(SetExpire.Seconds(0))).either } yield assert(result)(isLeft(isSubtype[ProtocolError](anything))) }, test("error when negative ttl") { @@ -1681,7 +1681,7 @@ trait StringsSpec extends IntegrationSpec { redis <- ZIO.service[Redis] key <- uuid value <- uuid - result <- redis.set(key, value, expireAt = Some(SetExpire.SetExpireSeconds((-1).second))).either + result <- redis.set(key, value, expireAt = Some(SetExpire.Seconds(-1))).either } yield assert(result)(isLeft(isSubtype[ProtocolError](anything))) } ), @@ -1785,7 +1785,7 @@ trait StringsSpec extends IntegrationSpec { key <- uuid value <- uuid _ <- redis.set(key, value) - exists <- redis.getEx(key, GetExpire.GetExpireSeconds(1.second)).returning[String] + exists <- redis.getEx(key, GetExpire.Seconds(1)).returning[String] fiber <- ZIO.sleep(1020.millis).fork <* TestClock.adjust(1020.millis) _ <- fiber.join res <- redis.get(key).returning[String] @@ -1797,7 +1797,7 @@ trait StringsSpec extends IntegrationSpec { key <- uuid value <- uuid _ <- redis.set(key, value) - exists <- redis.getEx(key, GetExpire.GetExpireMilliseconds(10.millis)).returning[String] + exists <- redis.getEx(key, GetExpire.Milliseconds(10)).returning[String] fiber <- ZIO.sleep(20.millis).fork <* TestClock.adjust(20.millis) _ <- fiber.join res <- redis.get(key).returning[String] @@ -1810,7 +1810,7 @@ trait StringsSpec extends IntegrationSpec { value <- uuid _ <- redis.set(key, value) expiresAt <- Clock.instant.map(_.plusMillis(10.millis.toMillis)) - exists <- redis.getEx(key, GetExpire.GetExpireUnixTimeSeconds(expiresAt)).returning[String] + exists <- redis.getEx(key, GetExpire.UnixTimeSeconds(expiresAt.getEpochSecond)).returning[String] fiber <- ZIO.sleep(20.millis).fork <* TestClock.adjust(20.millis) _ <- fiber.join res <- redis.get(key).returning[String] @@ -1823,7 +1823,7 @@ trait StringsSpec extends IntegrationSpec { value <- uuid _ <- redis.set(key, value) expiresAt <- Clock.instant.map(_.plusMillis(10.millis.toMillis)) - exists <- redis.getEx(key, GetExpire.GetExpireUnixTimeMilliseconds(expiresAt)).returning[String] + exists <- redis.getEx(key, GetExpire.UnixTimeMilliseconds(expiresAt.toEpochMilli)).returning[String] fiber <- ZIO.sleep(20.millis).fork <* TestClock.adjust(20.millis) _ <- fiber.join res <- redis.get(key).returning[String] @@ -1836,8 +1836,8 @@ trait StringsSpec extends IntegrationSpec { value <- uuid _ <- redis.set(key, value) expiresAt <- Clock.instant.map(_.plusMillis(10.millis.toMillis)) - res <- redis.getEx(value, GetExpire.GetExpireUnixTimeMilliseconds(expiresAt)).returning[String] - res2 <- redis.getEx(value, GetExpire.GetExpireMilliseconds(10.millis)).returning[String] + res <- redis.getEx(value, GetExpire.UnixTimeMilliseconds(expiresAt.toEpochMilli)).returning[String] + res2 <- redis.getEx(value, GetExpire.Milliseconds(10)).returning[String] } yield assert(res)(isNone) && assert(res2)(isNone) } @@ flaky ), diff --git a/modules/redis/src/main/scala/zio/redis/Input.scala b/modules/redis/src/main/scala/zio/redis/Input.scala index a16dffeae..9de35da98 100644 --- a/modules/redis/src/main/scala/zio/redis/Input.scala +++ b/modules/redis/src/main/scala/zio/redis/Input.scala @@ -215,22 +215,32 @@ object Input { final case class GetExInput[K: BinaryCodec]() extends Input[(K, GetExpire)] { def encode(data: (K, GetExpire)): RespCommand = data match { - case (key, GetExpire.GetExpireSeconds(duration)) => - RespCommand(RespCommandArgument.Key(key), RespCommandArgument.Literal("EX")) ++ DurationSecondsInput.encode( - duration + case (key, GetExpire.Milliseconds(milliseconds)) => + RespCommand( + RespCommandArgument.Key(key), + RespCommandArgument.Literal("PX"), + RespCommandArgument.Value(milliseconds.toString) ) - case (key, GetExpire.GetExpireMilliseconds(duration)) => - RespCommand(RespCommandArgument.Key(key), RespCommandArgument.Literal("PX")) ++ DurationMillisecondsInput - .encode(duration) - case (key, GetExpire.GetExpireUnixTimeMilliseconds(instant)) => - RespCommand(RespCommandArgument.Key(key), RespCommandArgument.Literal("PXAT")) ++ TimeMillisecondsInput - .encode(instant) - case (key, GetExpire.GetExpireUnixTimeSeconds(instant)) => - RespCommand(RespCommandArgument.Key(key), RespCommandArgument.Literal("EXAT")) ++ TimeSecondsInput.encode( - instant - ) - case (key, GetExpire.Persist) => + case (key, GetExpire.Persist) => RespCommand(RespCommandArgument.Key(key), RespCommandArgument.Literal("PERSIST")) + case (key, GetExpire.Seconds(seconds)) => + RespCommand( + RespCommandArgument.Key(key), + RespCommandArgument.Literal("EX"), + RespCommandArgument.Value(seconds.toString) + ) + case (key, GetExpire.UnixTimeMilliseconds(milliseconds)) => + RespCommand( + RespCommandArgument.Key(key), + RespCommandArgument.Literal("PXAT"), + RespCommandArgument.Value(milliseconds.toString) + ) + case (key, GetExpire.UnixTimeSeconds(seconds)) => + RespCommand( + RespCommandArgument.Key(key), + RespCommandArgument.Literal("EXAT"), + RespCommandArgument.Value(seconds.toString) + ) } } @@ -409,16 +419,16 @@ object Input { case object SetExpireInput extends Input[SetExpire] { def encode(data: SetExpire): RespCommand = data match { - case SetExpire.KeepTtl => + case SetExpire.KeepTtl => RespCommand(RespCommandArgument.Literal("KEEPTTL")) - case SetExpire.SetExpireSeconds(duration) => - RespCommand(RespCommandArgument.Literal("EX")) ++ DurationSecondsInput.encode(duration) - case SetExpire.SetExpireMilliseconds(duration) => - RespCommand(RespCommandArgument.Literal("PX")) ++ DurationMillisecondsInput.encode(duration) - case SetExpire.SetExpireUnixTimeMilliseconds(instant) => - RespCommand(RespCommandArgument.Literal("PXAT")) ++ TimeMillisecondsInput.encode(instant) - case SetExpire.SetExpireUnixTimeSeconds(instant) => - RespCommand(RespCommandArgument.Literal("EXAT")) ++ TimeSecondsInput.encode(instant) + case SetExpire.Milliseconds(milliseconds) => + RespCommand(RespCommandArgument.Literal("PX"), RespCommandArgument.Value(milliseconds.toString)) + case SetExpire.Seconds(seconds) => + RespCommand(RespCommandArgument.Literal("EX"), RespCommandArgument.Value(seconds.toString)) + case SetExpire.UnixTimeMilliseconds(milliseconds) => + RespCommand(RespCommandArgument.Literal("PXAT"), RespCommandArgument.Value(milliseconds.toString)) + case SetExpire.UnixTimeSeconds(seconds) => + RespCommand(RespCommandArgument.Literal("EXAT"), RespCommandArgument.Value(seconds.toString)) } } diff --git a/modules/redis/src/main/scala/zio/redis/options/Strings.scala b/modules/redis/src/main/scala/zio/redis/options/Strings.scala index 7f086ad2c..7c80df22c 100644 --- a/modules/redis/src/main/scala/zio/redis/options/Strings.scala +++ b/modules/redis/src/main/scala/zio/redis/options/Strings.scala @@ -16,8 +16,6 @@ package zio.redis.options -import zio.Duration - import java.time.Instant trait Strings { @@ -100,21 +98,21 @@ trait Strings { sealed trait SetExpire object SetExpire { - case object KeepTtl extends SetExpire - case class SetExpireMilliseconds(duration: Duration) extends SetExpire - case class SetExpireSeconds(duration: Duration) extends SetExpire - case class SetExpireUnixTimeMilliseconds(instant: Instant) extends SetExpire - case class SetExpireUnixTimeSeconds(instant: Instant) extends SetExpire + case object KeepTtl extends SetExpire + final case class Milliseconds(milliseconds: Long) extends SetExpire + final case class Seconds(seconds: Long) extends SetExpire + final case class UnixTimeMilliseconds(milliseconds: Long) extends SetExpire + final case class UnixTimeSeconds(seconds: Instant) extends SetExpire } sealed trait GetExpire object GetExpire { - case class GetExpireMilliseconds(duration: Duration) extends GetExpire - case class GetExpireSeconds(duration: Duration) extends GetExpire - case class GetExpireUnixTimeMilliseconds(instant: Instant) extends GetExpire - case class GetExpireUnixTimeSeconds(instant: Instant) extends GetExpire - case object Persist extends GetExpire + final case class Milliseconds(milliseconds: Long) extends GetExpire + case object Persist extends GetExpire + final case class Seconds(seconds: Long) extends GetExpire + final case class UnixTimeMilliseconds(milliseconds: Long) extends GetExpire + final case class UnixTimeSeconds(seconds: Long) extends GetExpire } case object GetKeyword { diff --git a/modules/redis/src/test/scala/zio/redis/InputSpec.scala b/modules/redis/src/test/scala/zio/redis/InputSpec.scala index de450f8a2..c7cdefec9 100644 --- a/modules/redis/src/test/scala/zio/redis/InputSpec.scala +++ b/modules/redis/src/test/scala/zio/redis/InputSpec.scala @@ -1300,28 +1300,30 @@ object InputSpec extends BaseSpec { test("GetExInput - valid value") { for { resultSeconds <- - ZIO.attempt(GetExInput[String]().encode(scala.Tuple2("key", GetExpire.GetExpireSeconds(1.second)))) + ZIO.attempt(GetExInput[String]().encode(scala.Tuple2("key", GetExpire.Seconds(1)))) resultMilliseconds <- - ZIO.attempt(GetExInput[String]().encode(scala.Tuple2("key", GetExpire.GetExpireMilliseconds(100.millis)))) + ZIO.attempt(GetExInput[String]().encode(scala.Tuple2("key", GetExpire.Milliseconds(100)))) resultUnixTimeSeconds <- ZIO.attempt( GetExInput[String]().encode( - scala.Tuple2("key", GetExpire.GetExpireUnixTimeSeconds(Instant.parse("2021-04-06T00:00:00Z"))) + scala.Tuple2("key", GetExpire.UnixTimeSeconds(Instant.parse("2021-04-06T00:00:00Z").getEpochSecond)) ) ) resultUnixTimeMilliseconds <- ZIO.attempt( GetExInput[String]().encode( - scala.Tuple2("key", GetExpire.GetExpireUnixTimeMilliseconds(Instant.parse("2021-04-06T00:00:00Z"))) + scala + .Tuple2("key", GetExpire.UnixTimeMilliseconds(Instant.parse("2021-04-06T00:00:00Z").toEpochMilli)) ) ) resultPersist <- ZIO.attempt(GetExInput[String]().encode(scala.Tuple2("key", GetExpire.Persist))) - } yield assert(resultSeconds)(equalTo(RespCommand(Key("key"), Literal("EX"), Value("1")))) && - assert(resultMilliseconds)(equalTo(RespCommand(Key("key"), Literal("PX"), Value("100")))) && - assert(resultUnixTimeSeconds)(equalTo(RespCommand(Key("key"), Literal("EXAT"), Value("1617667200")))) && - assert(resultUnixTimeMilliseconds)( - equalTo(RespCommand(Key("key"), Literal("PXAT"), Value("1617667200000"))) - ) && assert(resultPersist)(equalTo(RespCommand(Key("key"), Literal("PERSIST")))) + } yield assertTrue( + resultSeconds == RespCommand(Key("key"), Literal("EX"), Value("1")), + resultMilliseconds == RespCommand(Key("key"), Literal("PX"), Value("100")), + resultUnixTimeSeconds == RespCommand(Key("key"), Literal("EXAT"), Value("1617667200")), + resultUnixTimeMilliseconds == RespCommand(Key("key"), Literal("PXAT"), Value("1617667200000")), + resultPersist == RespCommand(Key("key"), Literal("PERSIST")) + ) } ) ) From e609e20b808953993a08f03065a0f20314f781b5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dragutin=20Marjanovi=C4=87?= Date: Fri, 27 Sep 2024 01:28:08 +0200 Subject: [PATCH 07/16] Remove 'PSETEX' command --- .../src/test/scala/zio/redis/KeysSpec.scala | 4 +- .../test/scala/zio/redis/StringsSpec.scala | 50 ------------------- .../main/scala/zio/redis/api/Strings.scala | 25 ---------- 3 files changed, 2 insertions(+), 77 deletions(-) diff --git a/modules/redis-it/src/test/scala/zio/redis/KeysSpec.scala b/modules/redis-it/src/test/scala/zio/redis/KeysSpec.scala index eddc8d940..bc0c40152 100644 --- a/modules/redis-it/src/test/scala/zio/redis/KeysSpec.scala +++ b/modules/redis-it/src/test/scala/zio/redis/KeysSpec.scala @@ -244,7 +244,7 @@ trait KeysSpec extends IntegrationSpec { redis <- ZIO.service[Redis] key <- uuid value <- uuid - _ <- redis.pSetEx(key, 1000.millis, value) + _ <- redis.set(key, value, expireAt = Some(SetExpire.Milliseconds(1000))) ttl <- redis.ttl(key).either } yield assert(ttl)(isRight) } @@ flaky, @@ -260,7 +260,7 @@ trait KeysSpec extends IntegrationSpec { redis <- ZIO.service[Redis] key <- uuid value <- uuid - _ <- redis.pSetEx(key, 1000.millis, value) + _ <- redis.set(key, value, expireAt = Some(SetExpire.Milliseconds(1000))) pTtl <- redis.pTtl(key).either } yield assert(pTtl)(isRight) } @@ flaky, diff --git a/modules/redis-it/src/test/scala/zio/redis/StringsSpec.scala b/modules/redis-it/src/test/scala/zio/redis/StringsSpec.scala index 08983c91f..fd1b5af28 100644 --- a/modules/redis-it/src/test/scala/zio/redis/StringsSpec.scala +++ b/modules/redis-it/src/test/scala/zio/redis/StringsSpec.scala @@ -1425,56 +1425,6 @@ trait StringsSpec extends IntegrationSpec { } yield assert(set)(isFalse) } ) @@ clusterExecutorUnsupported, - suite("pSetEx")( - test("new value with 1000 milliseconds") { - for { - redis <- ZIO.service[Redis] - key <- uuid - value <- uuid - _ <- redis.pSetEx(key, 1000.millis, value) - existsBefore <- redis.exists(key) - fiber <- ZIO.sleep(1010.millis).fork <* TestClock.adjust(1010.millis) - _ <- fiber.join - existsAfter <- redis.exists(key) - } yield assert(existsBefore)(equalTo(1L)) && assert(existsAfter)(equalTo(0L)) - } @@ flaky, - test("override existing string") { - for { - redis <- ZIO.service[Redis] - key <- uuid - value <- uuid - _ <- redis.set(key, "value") - _ <- redis.pSetEx(key, 1000.millis, value) - currentVal <- redis.get(key).returning[String] - } yield assert(currentVal)(isSome(equalTo(value))) - }, - test("override not string") { - for { - redis <- ZIO.service[Redis] - key <- uuid - value <- uuid - _ <- redis.sAdd(key, "a") - _ <- redis.pSetEx(key, 1000.millis, value) - currentVal <- redis.get(key).returning[String] - } yield assert(currentVal)(isSome(equalTo(value))) - }, - test("error when 0 milliseconds") { - for { - redis <- ZIO.service[Redis] - key <- uuid - value <- uuid - result <- redis.pSetEx(key, 0.millis, value).either - } yield assert(result)(isLeft(isSubtype[ProtocolError](anything))) - }, - test("error when negative milliseconds") { - for { - redis <- ZIO.service[Redis] - key <- uuid - value <- uuid - result <- redis.pSetEx(key, (-1).millis, value).either - } yield assert(result)(isLeft(isSubtype[ProtocolError](anything))) - } - ), suite("set")( test("new value") { for { diff --git a/modules/redis/src/main/scala/zio/redis/api/Strings.scala b/modules/redis/src/main/scala/zio/redis/api/Strings.scala index ab2696442..3bdf9e76d 100644 --- a/modules/redis/src/main/scala/zio/redis/api/Strings.scala +++ b/modules/redis/src/main/scala/zio/redis/api/Strings.scala @@ -387,30 +387,6 @@ trait Strings[G[+_]] extends RedisEnvironment[G] { command.run((keyValue, keyValues.toList)) } - /** - * Set the value and expiration in milliseconds of a key. - * - * @param key - * Key of the string to set the expiry time on - * @param milliseconds - * Time in milliseconds until the string should expire - * @param value - * Value to set - */ - final def pSetEx[K: Schema, V: Schema]( - key: K, - milliseconds: Duration, - value: V - ): G[Unit] = { - val command = - RedisCommand( - PSetEx, - Tuple3(ArbitraryKeyInput[K](), DurationMillisecondsInput, ArbitraryValueInput[V]()), - UnitOutput - ) - command.run((key, milliseconds, value)) - } - /** * Set the string value of a key. * @@ -545,7 +521,6 @@ private[redis] object Strings { final val MGet = "MGET" final val MSet = "MSET" final val MSetNx = "MSETNX" - final val PSetEx = "PSETEX" final val Set = "SET" final val SetBit = "SETBIT" final val SetRange = "SETRANGE" From 7fdda22d195d220130a2aed841918e3ba9df7e59 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dragutin=20Marjanovi=C4=87?= Date: Fri, 27 Sep 2024 01:33:03 +0200 Subject: [PATCH 08/16] Fix build --- .../zio/redis/example/ContributorsCache.scala | 2 +- .../src/test/scala/zio/redis/KeysSpec.scala | 4 +-- .../test/scala/zio/redis/StringsSpec.scala | 31 ++++++++++--------- .../src/main/scala/zio/redis/Input.scala | 20 ++++++------ .../scala/zio/redis/options/Strings.scala | 20 ++++++------ .../src/test/scala/zio/redis/InputSpec.scala | 14 ++++++--- 6 files changed, 49 insertions(+), 42 deletions(-) diff --git a/modules/example/src/main/scala/zio/redis/example/ContributorsCache.scala b/modules/example/src/main/scala/zio/redis/example/ContributorsCache.scala index af71b4bd6..2d6b4e8d9 100644 --- a/modules/example/src/main/scala/zio/redis/example/ContributorsCache.scala +++ b/modules/example/src/main/scala/zio/redis/example/ContributorsCache.scala @@ -40,7 +40,7 @@ object ContributorsCache { ZIO .fromOption(NonEmptyChunk.fromChunk(contributors)) .map(Contributors(_).toJson) - .flatMap(data => redis.set(repository.key, data, expireAt = Some(SetExpire.Seconds(60))).orDie) + .flatMap(data => redis.set(repository.key, data, expireAt = Some(SetExpire.SetExpireSeconds(60))).orDie) .ignore private def read(repository: Repository): IO[ApiError, Contributors] = diff --git a/modules/redis-it/src/test/scala/zio/redis/KeysSpec.scala b/modules/redis-it/src/test/scala/zio/redis/KeysSpec.scala index bc0c40152..12d899f83 100644 --- a/modules/redis-it/src/test/scala/zio/redis/KeysSpec.scala +++ b/modules/redis-it/src/test/scala/zio/redis/KeysSpec.scala @@ -244,7 +244,7 @@ trait KeysSpec extends IntegrationSpec { redis <- ZIO.service[Redis] key <- uuid value <- uuid - _ <- redis.set(key, value, expireAt = Some(SetExpire.Milliseconds(1000))) + _ <- redis.set(key, value, expireAt = Some(SetExpire.SetExpireMilliseconds(1000))) ttl <- redis.ttl(key).either } yield assert(ttl)(isRight) } @@ flaky, @@ -260,7 +260,7 @@ trait KeysSpec extends IntegrationSpec { redis <- ZIO.service[Redis] key <- uuid value <- uuid - _ <- redis.set(key, value, expireAt = Some(SetExpire.Milliseconds(1000))) + _ <- redis.set(key, value, expireAt = Some(SetExpire.SetExpireMilliseconds(1000))) pTtl <- redis.pTtl(key).either } yield assert(pTtl)(isRight) } @@ flaky, diff --git a/modules/redis-it/src/test/scala/zio/redis/StringsSpec.scala b/modules/redis-it/src/test/scala/zio/redis/StringsSpec.scala index fd1b5af28..de06078d2 100644 --- a/modules/redis-it/src/test/scala/zio/redis/StringsSpec.scala +++ b/modules/redis-it/src/test/scala/zio/redis/StringsSpec.scala @@ -1457,7 +1457,7 @@ trait StringsSpec extends IntegrationSpec { redis <- ZIO.service[Redis] key <- uuid value <- uuid - result <- redis.set(key, value, expireAt = Some(SetExpire.Seconds(1))) + result <- redis.set(key, value, expireAt = Some(SetExpire.SetExpireSeconds(1))) } yield assert(result)(isTrue) }, test("new value with ttl 100 milliseconds") { @@ -1465,7 +1465,7 @@ trait StringsSpec extends IntegrationSpec { redis <- ZIO.service[Redis] key <- uuid value <- uuid - result <- redis.set(key, value, expireAt = Some(SetExpire.Milliseconds(100))) + result <- redis.set(key, value, expireAt = Some(SetExpire.SetExpireMilliseconds(100))) } yield assert(result)(isTrue) }, test("error when negative ttl") { @@ -1473,7 +1473,7 @@ trait StringsSpec extends IntegrationSpec { redis <- ZIO.service[Redis] key <- uuid value <- uuid - result <- redis.set(key, value, expireAt = Some(SetExpire.Milliseconds(-1))).either + result <- redis.set(key, value, expireAt = Some(SetExpire.SetExpireMilliseconds(-1))).either } yield assert(result)(isLeft(isSubtype[ProtocolError](anything))) }, test("new value with SetNew parameter") { @@ -1533,7 +1533,7 @@ trait StringsSpec extends IntegrationSpec { redis <- ZIO.service[Redis] key <- uuid value <- uuid - _ <- redis.set(key, "value", expireAt = Some(SetExpire.Seconds(1))) + _ <- redis.set(key, "value", expireAt = Some(SetExpire.SetExpireSeconds(1))) result <- redis.set(key, value, expireAt = Some(SetExpire.KeepTtl)) } yield assert(result)(isTrue) } @@ -1585,7 +1585,7 @@ trait StringsSpec extends IntegrationSpec { redis <- ZIO.service[Redis] key <- uuid value <- uuid - _ <- redis.set(key, value, expireAt = Some(SetExpire.Seconds(1))) + _ <- redis.set(key, value, expireAt = Some(SetExpire.SetExpireSeconds(1))) existsBefore <- redis.exists(key) fiber <- ZIO.sleep(1010.millis).fork <* TestClock.adjust(1010.millis) _ <- fiber.join @@ -1598,7 +1598,7 @@ trait StringsSpec extends IntegrationSpec { key <- uuid value <- uuid _ <- redis.set(key, "value") - _ <- redis.set(key, value, expireAt = Some(SetExpire.Seconds(1))) + _ <- redis.set(key, value, expireAt = Some(SetExpire.SetExpireSeconds(1))) existsBefore <- redis.exists(key) fiber <- ZIO.sleep(1010.millis).fork <* TestClock.adjust(1010.millis) _ <- fiber.join @@ -1611,7 +1611,7 @@ trait StringsSpec extends IntegrationSpec { key <- uuid value <- uuid _ <- redis.sAdd(key, "a") - _ <- redis.set(key, value, expireAt = Some(SetExpire.Seconds(1))) + _ <- redis.set(key, value, expireAt = Some(SetExpire.SetExpireSeconds(1))) existsBefore <- redis.exists(key) fiber <- ZIO.sleep(1010.millis).fork <* TestClock.adjust(1010.millis) _ <- fiber.join @@ -1623,7 +1623,7 @@ trait StringsSpec extends IntegrationSpec { redis <- ZIO.service[Redis] key <- uuid value <- uuid - result <- redis.set(key, value, expireAt = Some(SetExpire.Seconds(0))).either + result <- redis.set(key, value, expireAt = Some(SetExpire.SetExpireSeconds(0))).either } yield assert(result)(isLeft(isSubtype[ProtocolError](anything))) }, test("error when negative ttl") { @@ -1631,7 +1631,7 @@ trait StringsSpec extends IntegrationSpec { redis <- ZIO.service[Redis] key <- uuid value <- uuid - result <- redis.set(key, value, expireAt = Some(SetExpire.Seconds(-1))).either + result <- redis.set(key, value, expireAt = Some(SetExpire.SetExpireSeconds(-1))).either } yield assert(result)(isLeft(isSubtype[ProtocolError](anything))) } ), @@ -1735,7 +1735,7 @@ trait StringsSpec extends IntegrationSpec { key <- uuid value <- uuid _ <- redis.set(key, value) - exists <- redis.getEx(key, GetExpire.Seconds(1)).returning[String] + exists <- redis.getEx(key, GetExpire.GetExpireSeconds(1)).returning[String] fiber <- ZIO.sleep(1020.millis).fork <* TestClock.adjust(1020.millis) _ <- fiber.join res <- redis.get(key).returning[String] @@ -1747,7 +1747,7 @@ trait StringsSpec extends IntegrationSpec { key <- uuid value <- uuid _ <- redis.set(key, value) - exists <- redis.getEx(key, GetExpire.Milliseconds(10)).returning[String] + exists <- redis.getEx(key, GetExpire.GetExpireMilliseconds(10)).returning[String] fiber <- ZIO.sleep(20.millis).fork <* TestClock.adjust(20.millis) _ <- fiber.join res <- redis.get(key).returning[String] @@ -1760,7 +1760,7 @@ trait StringsSpec extends IntegrationSpec { value <- uuid _ <- redis.set(key, value) expiresAt <- Clock.instant.map(_.plusMillis(10.millis.toMillis)) - exists <- redis.getEx(key, GetExpire.UnixTimeSeconds(expiresAt.getEpochSecond)).returning[String] + exists <- redis.getEx(key, GetExpire.GetExpireUnixTimeSeconds(expiresAt.getEpochSecond)).returning[String] fiber <- ZIO.sleep(20.millis).fork <* TestClock.adjust(20.millis) _ <- fiber.join res <- redis.get(key).returning[String] @@ -1773,7 +1773,8 @@ trait StringsSpec extends IntegrationSpec { value <- uuid _ <- redis.set(key, value) expiresAt <- Clock.instant.map(_.plusMillis(10.millis.toMillis)) - exists <- redis.getEx(key, GetExpire.UnixTimeMilliseconds(expiresAt.toEpochMilli)).returning[String] + exists <- + redis.getEx(key, GetExpire.GetExpireUnixTimeMilliseconds(expiresAt.toEpochMilli)).returning[String] fiber <- ZIO.sleep(20.millis).fork <* TestClock.adjust(20.millis) _ <- fiber.join res <- redis.get(key).returning[String] @@ -1786,8 +1787,8 @@ trait StringsSpec extends IntegrationSpec { value <- uuid _ <- redis.set(key, value) expiresAt <- Clock.instant.map(_.plusMillis(10.millis.toMillis)) - res <- redis.getEx(value, GetExpire.UnixTimeMilliseconds(expiresAt.toEpochMilli)).returning[String] - res2 <- redis.getEx(value, GetExpire.Milliseconds(10)).returning[String] + res <- redis.getEx(value, GetExpire.GetExpireUnixTimeMilliseconds(expiresAt.toEpochMilli)).returning[String] + res2 <- redis.getEx(value, GetExpire.GetExpireMilliseconds(10)).returning[String] } yield assert(res)(isNone) && assert(res2)(isNone) } @@ flaky ), diff --git a/modules/redis/src/main/scala/zio/redis/Input.scala b/modules/redis/src/main/scala/zio/redis/Input.scala index 9de35da98..23e207d03 100644 --- a/modules/redis/src/main/scala/zio/redis/Input.scala +++ b/modules/redis/src/main/scala/zio/redis/Input.scala @@ -215,27 +215,27 @@ object Input { final case class GetExInput[K: BinaryCodec]() extends Input[(K, GetExpire)] { def encode(data: (K, GetExpire)): RespCommand = data match { - case (key, GetExpire.Milliseconds(milliseconds)) => + case (key, GetExpire.GetExpireMilliseconds(milliseconds)) => RespCommand( RespCommandArgument.Key(key), RespCommandArgument.Literal("PX"), RespCommandArgument.Value(milliseconds.toString) ) - case (key, GetExpire.Persist) => + case (key, GetExpire.Persist) => RespCommand(RespCommandArgument.Key(key), RespCommandArgument.Literal("PERSIST")) - case (key, GetExpire.Seconds(seconds)) => + case (key, GetExpire.GetExpireSeconds(seconds)) => RespCommand( RespCommandArgument.Key(key), RespCommandArgument.Literal("EX"), RespCommandArgument.Value(seconds.toString) ) - case (key, GetExpire.UnixTimeMilliseconds(milliseconds)) => + case (key, GetExpire.GetExpireUnixTimeMilliseconds(milliseconds)) => RespCommand( RespCommandArgument.Key(key), RespCommandArgument.Literal("PXAT"), RespCommandArgument.Value(milliseconds.toString) ) - case (key, GetExpire.UnixTimeSeconds(seconds)) => + case (key, GetExpire.GetExpireUnixTimeSeconds(seconds)) => RespCommand( RespCommandArgument.Key(key), RespCommandArgument.Literal("EXAT"), @@ -419,15 +419,15 @@ object Input { case object SetExpireInput extends Input[SetExpire] { def encode(data: SetExpire): RespCommand = data match { - case SetExpire.KeepTtl => + case SetExpire.KeepTtl => RespCommand(RespCommandArgument.Literal("KEEPTTL")) - case SetExpire.Milliseconds(milliseconds) => + case SetExpire.SetExpireMilliseconds(milliseconds) => RespCommand(RespCommandArgument.Literal("PX"), RespCommandArgument.Value(milliseconds.toString)) - case SetExpire.Seconds(seconds) => + case SetExpire.SetExpireSeconds(seconds) => RespCommand(RespCommandArgument.Literal("EX"), RespCommandArgument.Value(seconds.toString)) - case SetExpire.UnixTimeMilliseconds(milliseconds) => + case SetExpire.SetExpireUnixTimeMilliseconds(milliseconds) => RespCommand(RespCommandArgument.Literal("PXAT"), RespCommandArgument.Value(milliseconds.toString)) - case SetExpire.UnixTimeSeconds(seconds) => + case SetExpire.SetExpireUnixTimeSeconds(seconds) => RespCommand(RespCommandArgument.Literal("EXAT"), RespCommandArgument.Value(seconds.toString)) } } diff --git a/modules/redis/src/main/scala/zio/redis/options/Strings.scala b/modules/redis/src/main/scala/zio/redis/options/Strings.scala index 7c80df22c..6daaaca24 100644 --- a/modules/redis/src/main/scala/zio/redis/options/Strings.scala +++ b/modules/redis/src/main/scala/zio/redis/options/Strings.scala @@ -98,21 +98,21 @@ trait Strings { sealed trait SetExpire object SetExpire { - case object KeepTtl extends SetExpire - final case class Milliseconds(milliseconds: Long) extends SetExpire - final case class Seconds(seconds: Long) extends SetExpire - final case class UnixTimeMilliseconds(milliseconds: Long) extends SetExpire - final case class UnixTimeSeconds(seconds: Instant) extends SetExpire + case object KeepTtl extends SetExpire + final case class SetExpireMilliseconds(milliseconds: Long) extends SetExpire + final case class SetExpireSeconds(seconds: Long) extends SetExpire + final case class SetExpireUnixTimeMilliseconds(milliseconds: Long) extends SetExpire + final case class SetExpireUnixTimeSeconds(seconds: Instant) extends SetExpire } sealed trait GetExpire object GetExpire { - final case class Milliseconds(milliseconds: Long) extends GetExpire - case object Persist extends GetExpire - final case class Seconds(seconds: Long) extends GetExpire - final case class UnixTimeMilliseconds(milliseconds: Long) extends GetExpire - final case class UnixTimeSeconds(seconds: Long) extends GetExpire + final case class GetExpireMilliseconds(milliseconds: Long) extends GetExpire + final case class GetExpireSeconds(seconds: Long) extends GetExpire + final case class GetExpireUnixTimeMilliseconds(milliseconds: Long) extends GetExpire + final case class GetExpireUnixTimeSeconds(seconds: Long) extends GetExpire + case object Persist extends GetExpire } case object GetKeyword { diff --git a/modules/redis/src/test/scala/zio/redis/InputSpec.scala b/modules/redis/src/test/scala/zio/redis/InputSpec.scala index c7cdefec9..7a1b40ed5 100644 --- a/modules/redis/src/test/scala/zio/redis/InputSpec.scala +++ b/modules/redis/src/test/scala/zio/redis/InputSpec.scala @@ -1300,20 +1300,26 @@ object InputSpec extends BaseSpec { test("GetExInput - valid value") { for { resultSeconds <- - ZIO.attempt(GetExInput[String]().encode(scala.Tuple2("key", GetExpire.Seconds(1)))) + ZIO.attempt(GetExInput[String]().encode(scala.Tuple2("key", GetExpire.GetExpireSeconds(1)))) resultMilliseconds <- - ZIO.attempt(GetExInput[String]().encode(scala.Tuple2("key", GetExpire.Milliseconds(100)))) + ZIO.attempt(GetExInput[String]().encode(scala.Tuple2("key", GetExpire.GetExpireMilliseconds(100)))) resultUnixTimeSeconds <- ZIO.attempt( GetExInput[String]().encode( - scala.Tuple2("key", GetExpire.UnixTimeSeconds(Instant.parse("2021-04-06T00:00:00Z").getEpochSecond)) + scala.Tuple2( + "key", + GetExpire.GetExpireUnixTimeSeconds(Instant.parse("2021-04-06T00:00:00Z").getEpochSecond) + ) ) ) resultUnixTimeMilliseconds <- ZIO.attempt( GetExInput[String]().encode( scala - .Tuple2("key", GetExpire.UnixTimeMilliseconds(Instant.parse("2021-04-06T00:00:00Z").toEpochMilli)) + .Tuple2( + "key", + GetExpire.GetExpireUnixTimeMilliseconds(Instant.parse("2021-04-06T00:00:00Z").toEpochMilli) + ) ) ) resultPersist <- ZIO.attempt(GetExInput[String]().encode(scala.Tuple2("key", GetExpire.Persist))) From 9373ff892f96b50d342eacd3079ca417f3a8b1e5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dragutin=20Marjanovi=C4=87?= Date: Sat, 28 Sep 2024 16:35:47 +0200 Subject: [PATCH 09/16] Fix tests compile --- .../zio/redis/example/ContributorsCache.scala | 2 +- .../src/test/scala/zio/redis/KeysSpec.scala | 4 +-- .../test/scala/zio/redis/StringsSpec.scala | 30 +++++++++---------- .../src/main/scala/zio/redis/Input.scala | 20 ++++++------- .../scala/zio/redis/options/Strings.scala | 22 +++++++------- .../src/test/scala/zio/redis/InputSpec.scala | 8 ++--- 6 files changed, 42 insertions(+), 44 deletions(-) diff --git a/modules/example/src/main/scala/zio/redis/example/ContributorsCache.scala b/modules/example/src/main/scala/zio/redis/example/ContributorsCache.scala index 2d6b4e8d9..af71b4bd6 100644 --- a/modules/example/src/main/scala/zio/redis/example/ContributorsCache.scala +++ b/modules/example/src/main/scala/zio/redis/example/ContributorsCache.scala @@ -40,7 +40,7 @@ object ContributorsCache { ZIO .fromOption(NonEmptyChunk.fromChunk(contributors)) .map(Contributors(_).toJson) - .flatMap(data => redis.set(repository.key, data, expireAt = Some(SetExpire.SetExpireSeconds(60))).orDie) + .flatMap(data => redis.set(repository.key, data, expireAt = Some(SetExpire.Seconds(60))).orDie) .ignore private def read(repository: Repository): IO[ApiError, Contributors] = diff --git a/modules/redis-it/src/test/scala/zio/redis/KeysSpec.scala b/modules/redis-it/src/test/scala/zio/redis/KeysSpec.scala index 12d899f83..bc0c40152 100644 --- a/modules/redis-it/src/test/scala/zio/redis/KeysSpec.scala +++ b/modules/redis-it/src/test/scala/zio/redis/KeysSpec.scala @@ -244,7 +244,7 @@ trait KeysSpec extends IntegrationSpec { redis <- ZIO.service[Redis] key <- uuid value <- uuid - _ <- redis.set(key, value, expireAt = Some(SetExpire.SetExpireMilliseconds(1000))) + _ <- redis.set(key, value, expireAt = Some(SetExpire.Milliseconds(1000))) ttl <- redis.ttl(key).either } yield assert(ttl)(isRight) } @@ flaky, @@ -260,7 +260,7 @@ trait KeysSpec extends IntegrationSpec { redis <- ZIO.service[Redis] key <- uuid value <- uuid - _ <- redis.set(key, value, expireAt = Some(SetExpire.SetExpireMilliseconds(1000))) + _ <- redis.set(key, value, expireAt = Some(SetExpire.Milliseconds(1000))) pTtl <- redis.pTtl(key).either } yield assert(pTtl)(isRight) } @@ flaky, diff --git a/modules/redis-it/src/test/scala/zio/redis/StringsSpec.scala b/modules/redis-it/src/test/scala/zio/redis/StringsSpec.scala index de06078d2..1ecf71fbf 100644 --- a/modules/redis-it/src/test/scala/zio/redis/StringsSpec.scala +++ b/modules/redis-it/src/test/scala/zio/redis/StringsSpec.scala @@ -1457,7 +1457,7 @@ trait StringsSpec extends IntegrationSpec { redis <- ZIO.service[Redis] key <- uuid value <- uuid - result <- redis.set(key, value, expireAt = Some(SetExpire.SetExpireSeconds(1))) + result <- redis.set(key, value, expireAt = Some(SetExpire.Seconds(1))) } yield assert(result)(isTrue) }, test("new value with ttl 100 milliseconds") { @@ -1465,7 +1465,7 @@ trait StringsSpec extends IntegrationSpec { redis <- ZIO.service[Redis] key <- uuid value <- uuid - result <- redis.set(key, value, expireAt = Some(SetExpire.SetExpireMilliseconds(100))) + result <- redis.set(key, value, expireAt = Some(SetExpire.Milliseconds(100))) } yield assert(result)(isTrue) }, test("error when negative ttl") { @@ -1473,7 +1473,7 @@ trait StringsSpec extends IntegrationSpec { redis <- ZIO.service[Redis] key <- uuid value <- uuid - result <- redis.set(key, value, expireAt = Some(SetExpire.SetExpireMilliseconds(-1))).either + result <- redis.set(key, value, expireAt = Some(SetExpire.Milliseconds(-1))).either } yield assert(result)(isLeft(isSubtype[ProtocolError](anything))) }, test("new value with SetNew parameter") { @@ -1533,7 +1533,7 @@ trait StringsSpec extends IntegrationSpec { redis <- ZIO.service[Redis] key <- uuid value <- uuid - _ <- redis.set(key, "value", expireAt = Some(SetExpire.SetExpireSeconds(1))) + _ <- redis.set(key, "value", expireAt = Some(SetExpire.Seconds(1))) result <- redis.set(key, value, expireAt = Some(SetExpire.KeepTtl)) } yield assert(result)(isTrue) } @@ -1585,7 +1585,7 @@ trait StringsSpec extends IntegrationSpec { redis <- ZIO.service[Redis] key <- uuid value <- uuid - _ <- redis.set(key, value, expireAt = Some(SetExpire.SetExpireSeconds(1))) + _ <- redis.set(key, value, expireAt = Some(SetExpire.Seconds(1))) existsBefore <- redis.exists(key) fiber <- ZIO.sleep(1010.millis).fork <* TestClock.adjust(1010.millis) _ <- fiber.join @@ -1598,7 +1598,7 @@ trait StringsSpec extends IntegrationSpec { key <- uuid value <- uuid _ <- redis.set(key, "value") - _ <- redis.set(key, value, expireAt = Some(SetExpire.SetExpireSeconds(1))) + _ <- redis.set(key, value, expireAt = Some(SetExpire.Seconds(1))) existsBefore <- redis.exists(key) fiber <- ZIO.sleep(1010.millis).fork <* TestClock.adjust(1010.millis) _ <- fiber.join @@ -1611,7 +1611,7 @@ trait StringsSpec extends IntegrationSpec { key <- uuid value <- uuid _ <- redis.sAdd(key, "a") - _ <- redis.set(key, value, expireAt = Some(SetExpire.SetExpireSeconds(1))) + _ <- redis.set(key, value, expireAt = Some(SetExpire.Seconds(1))) existsBefore <- redis.exists(key) fiber <- ZIO.sleep(1010.millis).fork <* TestClock.adjust(1010.millis) _ <- fiber.join @@ -1623,7 +1623,7 @@ trait StringsSpec extends IntegrationSpec { redis <- ZIO.service[Redis] key <- uuid value <- uuid - result <- redis.set(key, value, expireAt = Some(SetExpire.SetExpireSeconds(0))).either + result <- redis.set(key, value, expireAt = Some(SetExpire.Seconds(0))).either } yield assert(result)(isLeft(isSubtype[ProtocolError](anything))) }, test("error when negative ttl") { @@ -1631,7 +1631,7 @@ trait StringsSpec extends IntegrationSpec { redis <- ZIO.service[Redis] key <- uuid value <- uuid - result <- redis.set(key, value, expireAt = Some(SetExpire.SetExpireSeconds(-1))).either + result <- redis.set(key, value, expireAt = Some(SetExpire.Seconds(-1))).either } yield assert(result)(isLeft(isSubtype[ProtocolError](anything))) } ), @@ -1735,7 +1735,7 @@ trait StringsSpec extends IntegrationSpec { key <- uuid value <- uuid _ <- redis.set(key, value) - exists <- redis.getEx(key, GetExpire.GetExpireSeconds(1)).returning[String] + exists <- redis.getEx(key, GetExpire.Seconds(1)).returning[String] fiber <- ZIO.sleep(1020.millis).fork <* TestClock.adjust(1020.millis) _ <- fiber.join res <- redis.get(key).returning[String] @@ -1747,7 +1747,7 @@ trait StringsSpec extends IntegrationSpec { key <- uuid value <- uuid _ <- redis.set(key, value) - exists <- redis.getEx(key, GetExpire.GetExpireMilliseconds(10)).returning[String] + exists <- redis.getEx(key, GetExpire.Milliseconds(10)).returning[String] fiber <- ZIO.sleep(20.millis).fork <* TestClock.adjust(20.millis) _ <- fiber.join res <- redis.get(key).returning[String] @@ -1760,7 +1760,7 @@ trait StringsSpec extends IntegrationSpec { value <- uuid _ <- redis.set(key, value) expiresAt <- Clock.instant.map(_.plusMillis(10.millis.toMillis)) - exists <- redis.getEx(key, GetExpire.GetExpireUnixTimeSeconds(expiresAt.getEpochSecond)).returning[String] + exists <- redis.getEx(key, GetExpire.UnixTimeSeconds(expiresAt.getEpochSecond)).returning[String] fiber <- ZIO.sleep(20.millis).fork <* TestClock.adjust(20.millis) _ <- fiber.join res <- redis.get(key).returning[String] @@ -1774,7 +1774,7 @@ trait StringsSpec extends IntegrationSpec { _ <- redis.set(key, value) expiresAt <- Clock.instant.map(_.plusMillis(10.millis.toMillis)) exists <- - redis.getEx(key, GetExpire.GetExpireUnixTimeMilliseconds(expiresAt.toEpochMilli)).returning[String] + redis.getEx(key, GetExpire.UnixTimeMilliseconds(expiresAt.toEpochMilli)).returning[String] fiber <- ZIO.sleep(20.millis).fork <* TestClock.adjust(20.millis) _ <- fiber.join res <- redis.get(key).returning[String] @@ -1787,8 +1787,8 @@ trait StringsSpec extends IntegrationSpec { value <- uuid _ <- redis.set(key, value) expiresAt <- Clock.instant.map(_.plusMillis(10.millis.toMillis)) - res <- redis.getEx(value, GetExpire.GetExpireUnixTimeMilliseconds(expiresAt.toEpochMilli)).returning[String] - res2 <- redis.getEx(value, GetExpire.GetExpireMilliseconds(10)).returning[String] + res <- redis.getEx(value, GetExpire.UnixTimeMilliseconds(expiresAt.toEpochMilli)).returning[String] + res2 <- redis.getEx(value, GetExpire.Milliseconds(10)).returning[String] } yield assert(res)(isNone) && assert(res2)(isNone) } @@ flaky ), diff --git a/modules/redis/src/main/scala/zio/redis/Input.scala b/modules/redis/src/main/scala/zio/redis/Input.scala index 23e207d03..9de35da98 100644 --- a/modules/redis/src/main/scala/zio/redis/Input.scala +++ b/modules/redis/src/main/scala/zio/redis/Input.scala @@ -215,27 +215,27 @@ object Input { final case class GetExInput[K: BinaryCodec]() extends Input[(K, GetExpire)] { def encode(data: (K, GetExpire)): RespCommand = data match { - case (key, GetExpire.GetExpireMilliseconds(milliseconds)) => + case (key, GetExpire.Milliseconds(milliseconds)) => RespCommand( RespCommandArgument.Key(key), RespCommandArgument.Literal("PX"), RespCommandArgument.Value(milliseconds.toString) ) - case (key, GetExpire.Persist) => + case (key, GetExpire.Persist) => RespCommand(RespCommandArgument.Key(key), RespCommandArgument.Literal("PERSIST")) - case (key, GetExpire.GetExpireSeconds(seconds)) => + case (key, GetExpire.Seconds(seconds)) => RespCommand( RespCommandArgument.Key(key), RespCommandArgument.Literal("EX"), RespCommandArgument.Value(seconds.toString) ) - case (key, GetExpire.GetExpireUnixTimeMilliseconds(milliseconds)) => + case (key, GetExpire.UnixTimeMilliseconds(milliseconds)) => RespCommand( RespCommandArgument.Key(key), RespCommandArgument.Literal("PXAT"), RespCommandArgument.Value(milliseconds.toString) ) - case (key, GetExpire.GetExpireUnixTimeSeconds(seconds)) => + case (key, GetExpire.UnixTimeSeconds(seconds)) => RespCommand( RespCommandArgument.Key(key), RespCommandArgument.Literal("EXAT"), @@ -419,15 +419,15 @@ object Input { case object SetExpireInput extends Input[SetExpire] { def encode(data: SetExpire): RespCommand = data match { - case SetExpire.KeepTtl => + case SetExpire.KeepTtl => RespCommand(RespCommandArgument.Literal("KEEPTTL")) - case SetExpire.SetExpireMilliseconds(milliseconds) => + case SetExpire.Milliseconds(milliseconds) => RespCommand(RespCommandArgument.Literal("PX"), RespCommandArgument.Value(milliseconds.toString)) - case SetExpire.SetExpireSeconds(seconds) => + case SetExpire.Seconds(seconds) => RespCommand(RespCommandArgument.Literal("EX"), RespCommandArgument.Value(seconds.toString)) - case SetExpire.SetExpireUnixTimeMilliseconds(milliseconds) => + case SetExpire.UnixTimeMilliseconds(milliseconds) => RespCommand(RespCommandArgument.Literal("PXAT"), RespCommandArgument.Value(milliseconds.toString)) - case SetExpire.SetExpireUnixTimeSeconds(seconds) => + case SetExpire.UnixTimeSeconds(seconds) => RespCommand(RespCommandArgument.Literal("EXAT"), RespCommandArgument.Value(seconds.toString)) } } diff --git a/modules/redis/src/main/scala/zio/redis/options/Strings.scala b/modules/redis/src/main/scala/zio/redis/options/Strings.scala index 6daaaca24..72971bbe1 100644 --- a/modules/redis/src/main/scala/zio/redis/options/Strings.scala +++ b/modules/redis/src/main/scala/zio/redis/options/Strings.scala @@ -16,8 +16,6 @@ package zio.redis.options -import java.time.Instant - trait Strings { sealed trait Lcs @@ -98,21 +96,21 @@ trait Strings { sealed trait SetExpire object SetExpire { - case object KeepTtl extends SetExpire - final case class SetExpireMilliseconds(milliseconds: Long) extends SetExpire - final case class SetExpireSeconds(seconds: Long) extends SetExpire - final case class SetExpireUnixTimeMilliseconds(milliseconds: Long) extends SetExpire - final case class SetExpireUnixTimeSeconds(seconds: Instant) extends SetExpire + case object KeepTtl extends SetExpire + final case class Milliseconds(milliseconds: Long) extends SetExpire + final case class Seconds(seconds: Long) extends SetExpire + final case class UnixTimeMilliseconds(milliseconds: Long) extends SetExpire + final case class UnixTimeSeconds(seconds: Long) extends SetExpire } sealed trait GetExpire object GetExpire { - final case class GetExpireMilliseconds(milliseconds: Long) extends GetExpire - final case class GetExpireSeconds(seconds: Long) extends GetExpire - final case class GetExpireUnixTimeMilliseconds(milliseconds: Long) extends GetExpire - final case class GetExpireUnixTimeSeconds(seconds: Long) extends GetExpire - case object Persist extends GetExpire + final case class Milliseconds(milliseconds: Long) extends GetExpire + case object Persist extends GetExpire + final case class Seconds(seconds: Long) extends GetExpire + final case class UnixTimeMilliseconds(milliseconds: Long) extends GetExpire + final case class UnixTimeSeconds(seconds: Long) extends GetExpire } case object GetKeyword { diff --git a/modules/redis/src/test/scala/zio/redis/InputSpec.scala b/modules/redis/src/test/scala/zio/redis/InputSpec.scala index 7a1b40ed5..f1056c98e 100644 --- a/modules/redis/src/test/scala/zio/redis/InputSpec.scala +++ b/modules/redis/src/test/scala/zio/redis/InputSpec.scala @@ -1300,15 +1300,15 @@ object InputSpec extends BaseSpec { test("GetExInput - valid value") { for { resultSeconds <- - ZIO.attempt(GetExInput[String]().encode(scala.Tuple2("key", GetExpire.GetExpireSeconds(1)))) + ZIO.attempt(GetExInput[String]().encode(scala.Tuple2("key", GetExpire.Seconds(1)))) resultMilliseconds <- - ZIO.attempt(GetExInput[String]().encode(scala.Tuple2("key", GetExpire.GetExpireMilliseconds(100)))) + ZIO.attempt(GetExInput[String]().encode(scala.Tuple2("key", GetExpire.Milliseconds(100)))) resultUnixTimeSeconds <- ZIO.attempt( GetExInput[String]().encode( scala.Tuple2( "key", - GetExpire.GetExpireUnixTimeSeconds(Instant.parse("2021-04-06T00:00:00Z").getEpochSecond) + GetExpire.UnixTimeSeconds(Instant.parse("2021-04-06T00:00:00Z").getEpochSecond) ) ) ) @@ -1318,7 +1318,7 @@ object InputSpec extends BaseSpec { scala .Tuple2( "key", - GetExpire.GetExpireUnixTimeMilliseconds(Instant.parse("2021-04-06T00:00:00Z").toEpochMilli) + GetExpire.UnixTimeMilliseconds(Instant.parse("2021-04-06T00:00:00Z").toEpochMilli) ) ) ) From 8325b1348f8415e575405750573601953e373302 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dragutin=20Marjanovi=C4=87?= Date: Sat, 28 Sep 2024 16:36:56 +0200 Subject: [PATCH 10/16] Put final before case class keywords --- .../main/scala/zio/redis/options/Strings.scala | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/modules/redis/src/main/scala/zio/redis/options/Strings.scala b/modules/redis/src/main/scala/zio/redis/options/Strings.scala index 72971bbe1..b9f474105 100644 --- a/modules/redis/src/main/scala/zio/redis/options/Strings.scala +++ b/modules/redis/src/main/scala/zio/redis/options/Strings.scala @@ -21,20 +21,20 @@ trait Strings { sealed trait Lcs object Lcs { - case class PlainLcs(lcs: String) extends Lcs - case class Length(length: Long) extends Lcs - case class Matches(matches: List[Match], length: Long) extends Lcs + final case class PlainLcs(lcs: String) extends Lcs + final case class Length(length: Long) extends Lcs + final case class Matches(matches: List[Match], length: Long) extends Lcs } sealed trait LcsQueryType object LcsQueryType { - case object Len extends LcsQueryType - case class Idx(minMatchLength: Int = 1, withMatchLength: Boolean = false) extends LcsQueryType + case object Len extends LcsQueryType + final case class Idx(minMatchLength: Int = 1, withMatchLength: Boolean = false) extends LcsQueryType } - case class MatchIdx(start: Long, end: Long) - case class Match(matchIdxA: MatchIdx, matchIdxB: MatchIdx, matchLength: Option[Long] = None) + final case class MatchIdx(start: Long, end: Long) + final case class Match(matchIdxA: MatchIdx, matchIdxB: MatchIdx, matchLength: Option[Long] = None) sealed trait BitFieldCommand @@ -106,8 +106,8 @@ trait Strings { sealed trait GetExpire object GetExpire { - final case class Milliseconds(milliseconds: Long) extends GetExpire case object Persist extends GetExpire + final case class Milliseconds(milliseconds: Long) extends GetExpire final case class Seconds(seconds: Long) extends GetExpire final case class UnixTimeMilliseconds(milliseconds: Long) extends GetExpire final case class UnixTimeSeconds(seconds: Long) extends GetExpire From 1f98b10d8b786a286708c04893db7cdc3ff12573 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dragutin=20Marjanovi=C4=87?= Date: Sat, 28 Sep 2024 16:41:24 +0200 Subject: [PATCH 11/16] Remove final keywords --- .../scala/zio/redis/options/Strings.scala | 28 +++++++++---------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/modules/redis/src/main/scala/zio/redis/options/Strings.scala b/modules/redis/src/main/scala/zio/redis/options/Strings.scala index b9f474105..655ecf1cb 100644 --- a/modules/redis/src/main/scala/zio/redis/options/Strings.scala +++ b/modules/redis/src/main/scala/zio/redis/options/Strings.scala @@ -21,20 +21,20 @@ trait Strings { sealed trait Lcs object Lcs { - final case class PlainLcs(lcs: String) extends Lcs - final case class Length(length: Long) extends Lcs - final case class Matches(matches: List[Match], length: Long) extends Lcs + case class Length(length: Long) extends Lcs + case class Matches(matches: List[Match], length: Long) extends Lcs + case class PlainLcs(lcs: String) extends Lcs } sealed trait LcsQueryType object LcsQueryType { case object Len extends LcsQueryType - final case class Idx(minMatchLength: Int = 1, withMatchLength: Boolean = false) extends LcsQueryType + case class Idx(minMatchLength: Int = 1, withMatchLength: Boolean = false) extends LcsQueryType } - final case class MatchIdx(start: Long, end: Long) - final case class Match(matchIdxA: MatchIdx, matchIdxB: MatchIdx, matchLength: Option[Long] = None) + case class MatchIdx(start: Long, end: Long) + case class Match(matchIdxA: MatchIdx, matchIdxB: MatchIdx, matchLength: Option[Long] = None) sealed trait BitFieldCommand @@ -97,20 +97,20 @@ trait Strings { object SetExpire { case object KeepTtl extends SetExpire - final case class Milliseconds(milliseconds: Long) extends SetExpire - final case class Seconds(seconds: Long) extends SetExpire - final case class UnixTimeMilliseconds(milliseconds: Long) extends SetExpire - final case class UnixTimeSeconds(seconds: Long) extends SetExpire + case class Milliseconds(milliseconds: Long) extends SetExpire + case class Seconds(seconds: Long) extends SetExpire + case class UnixTimeMilliseconds(milliseconds: Long) extends SetExpire + case class UnixTimeSeconds(seconds: Long) extends SetExpire } sealed trait GetExpire object GetExpire { case object Persist extends GetExpire - final case class Milliseconds(milliseconds: Long) extends GetExpire - final case class Seconds(seconds: Long) extends GetExpire - final case class UnixTimeMilliseconds(milliseconds: Long) extends GetExpire - final case class UnixTimeSeconds(seconds: Long) extends GetExpire + case class Milliseconds(milliseconds: Long) extends GetExpire + case class Seconds(seconds: Long) extends GetExpire + case class UnixTimeMilliseconds(milliseconds: Long) extends GetExpire + case class UnixTimeSeconds(seconds: Long) extends GetExpire } case object GetKeyword { From c9bbc2efdffaeb1659c5bfe2903cad291210a16d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dragutin=20Marjanovi=C4=87?= Date: Sat, 28 Sep 2024 16:52:08 +0200 Subject: [PATCH 12/16] Use sealed instead of final --- .../scala/zio/redis/options/Strings.scala | 34 +++++++++---------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/modules/redis/src/main/scala/zio/redis/options/Strings.scala b/modules/redis/src/main/scala/zio/redis/options/Strings.scala index 655ecf1cb..812a071ea 100644 --- a/modules/redis/src/main/scala/zio/redis/options/Strings.scala +++ b/modules/redis/src/main/scala/zio/redis/options/Strings.scala @@ -21,20 +21,20 @@ trait Strings { sealed trait Lcs object Lcs { - case class Length(length: Long) extends Lcs - case class Matches(matches: List[Match], length: Long) extends Lcs - case class PlainLcs(lcs: String) extends Lcs + sealed case class Length(length: Long) extends Lcs + sealed case class Matches(matches: List[Match], length: Long) extends Lcs + sealed case class PlainLcs(lcs: String) extends Lcs } sealed trait LcsQueryType object LcsQueryType { - case object Len extends LcsQueryType - case class Idx(minMatchLength: Int = 1, withMatchLength: Boolean = false) extends LcsQueryType + case object Len extends LcsQueryType + sealed case class Idx(minMatchLength: Int = 1, withMatchLength: Boolean = false) extends LcsQueryType } - case class MatchIdx(start: Long, end: Long) - case class Match(matchIdxA: MatchIdx, matchIdxB: MatchIdx, matchLength: Option[Long] = None) + sealed case class MatchIdx(start: Long, end: Long) + sealed case class Match(matchIdxA: MatchIdx, matchIdxB: MatchIdx, matchLength: Option[Long] = None) sealed trait BitFieldCommand @@ -96,21 +96,21 @@ trait Strings { sealed trait SetExpire object SetExpire { - case object KeepTtl extends SetExpire - case class Milliseconds(milliseconds: Long) extends SetExpire - case class Seconds(seconds: Long) extends SetExpire - case class UnixTimeMilliseconds(milliseconds: Long) extends SetExpire - case class UnixTimeSeconds(seconds: Long) extends SetExpire + case object KeepTtl extends SetExpire + sealed case class Milliseconds(milliseconds: Long) extends SetExpire + sealed case class Seconds(seconds: Long) extends SetExpire + sealed case class UnixTimeMilliseconds(milliseconds: Long) extends SetExpire + sealed case class UnixTimeSeconds(seconds: Long) extends SetExpire } sealed trait GetExpire object GetExpire { - case object Persist extends GetExpire - case class Milliseconds(milliseconds: Long) extends GetExpire - case class Seconds(seconds: Long) extends GetExpire - case class UnixTimeMilliseconds(milliseconds: Long) extends GetExpire - case class UnixTimeSeconds(seconds: Long) extends GetExpire + case object Persist extends GetExpire + sealed case class Milliseconds(milliseconds: Long) extends GetExpire + sealed case class Seconds(seconds: Long) extends GetExpire + sealed case class UnixTimeMilliseconds(milliseconds: Long) extends GetExpire + sealed case class UnixTimeSeconds(seconds: Long) extends GetExpire } case object GetKeyword { From 61ce4610d37ee4dcb44e33c65b7d221d57398ac7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dragutin=20Marjanovi=C4=87?= Date: Sat, 28 Sep 2024 16:59:47 +0200 Subject: [PATCH 13/16] Fix website --- docs/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/index.md b/docs/index.md index a10a68a80..a705672d7 100644 --- a/docs/index.md +++ b/docs/index.md @@ -52,7 +52,7 @@ object ZIORedisExample extends ZIOAppDefault { val myApp: ZIO[Redis, RedisError, Unit] = for { redis <- ZIO.service[Redis] - _ <- redis.set("myKey", 8L, expireAt = Some(SetExpire.SetExpireSeconds(1.minutes))) + _ <- redis.set("myKey", 8L, expireAt = Some(SetExpire.Seconds(60))) v <- redis.get("myKey").returning[Long] _ <- Console.printLine(s"Value of myKey: $v").orDie _ <- redis.hSet("myHash", ("k1", 6), ("k2", 2)) From 4e8550a8246ab2e8b08aa8029ef26e3396524bba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dragutin=20Marjanovi=C4=87?= Date: Sat, 28 Sep 2024 21:59:57 +0200 Subject: [PATCH 14/16] Use NonNegativeLong --- .../zio/redis/example/ContributorsCache.scala | 3 +- .../src/test/scala/zio/redis/KeysSpec.scala | 5 +- .../test/scala/zio/redis/StringsSpec.scala | 90 ++++++++----------- .../scala/zio/redis/options/Strings.scala | 20 ++--- .../scala/zio/redis/options/package.scala | 12 +++ .../src/test/scala/zio/redis/InputSpec.scala | 25 ++---- 6 files changed, 75 insertions(+), 80 deletions(-) create mode 100644 modules/redis/src/main/scala/zio/redis/options/package.scala diff --git a/modules/example/src/main/scala/zio/redis/example/ContributorsCache.scala b/modules/example/src/main/scala/zio/redis/example/ContributorsCache.scala index af71b4bd6..5f94d4764 100644 --- a/modules/example/src/main/scala/zio/redis/example/ContributorsCache.scala +++ b/modules/example/src/main/scala/zio/redis/example/ContributorsCache.scala @@ -23,6 +23,7 @@ import zio._ import zio.json._ import zio.redis._ import zio.redis.example.ApiError._ +import zio.redis.options.NonNegativeLong trait ContributorsCache { def fetchAll(repository: Repository): IO[ApiError, Contributors] @@ -40,7 +41,7 @@ object ContributorsCache { ZIO .fromOption(NonEmptyChunk.fromChunk(contributors)) .map(Contributors(_).toJson) - .flatMap(data => redis.set(repository.key, data, expireAt = Some(SetExpire.Seconds(60))).orDie) + .flatMap(data => redis.set(repository.key, data, expireAt = Some(SetExpire.Seconds(NonNegativeLong(60)))).orDie) .ignore private def read(repository: Repository): IO[ApiError, Contributors] = diff --git a/modules/redis-it/src/test/scala/zio/redis/KeysSpec.scala b/modules/redis-it/src/test/scala/zio/redis/KeysSpec.scala index bc0c40152..1ceb4a628 100644 --- a/modules/redis-it/src/test/scala/zio/redis/KeysSpec.scala +++ b/modules/redis-it/src/test/scala/zio/redis/KeysSpec.scala @@ -3,6 +3,7 @@ package zio.redis import com.dimafeng.testcontainers.DockerComposeContainer import zio._ import zio.redis.RedisError.ProtocolError +import zio.redis.options.NonNegativeLong import zio.test.Assertion.{exists => _, _} import zio.test.TestAspect.{restore => _, _} import zio.test._ @@ -244,7 +245,7 @@ trait KeysSpec extends IntegrationSpec { redis <- ZIO.service[Redis] key <- uuid value <- uuid - _ <- redis.set(key, value, expireAt = Some(SetExpire.Milliseconds(1000))) + _ <- redis.set(key, value, expireAt = Some(SetExpire.Milliseconds(NonNegativeLong(1000)))) ttl <- redis.ttl(key).either } yield assert(ttl)(isRight) } @@ flaky, @@ -260,7 +261,7 @@ trait KeysSpec extends IntegrationSpec { redis <- ZIO.service[Redis] key <- uuid value <- uuid - _ <- redis.set(key, value, expireAt = Some(SetExpire.Milliseconds(1000))) + _ <- redis.set(key, value, expireAt = Some(SetExpire.Milliseconds(NonNegativeLong(1000)))) pTtl <- redis.pTtl(key).either } yield assert(pTtl)(isRight) } @@ flaky, diff --git a/modules/redis-it/src/test/scala/zio/redis/StringsSpec.scala b/modules/redis-it/src/test/scala/zio/redis/StringsSpec.scala index 1ecf71fbf..bff61e4e4 100644 --- a/modules/redis-it/src/test/scala/zio/redis/StringsSpec.scala +++ b/modules/redis-it/src/test/scala/zio/redis/StringsSpec.scala @@ -1,7 +1,9 @@ package zio.redis import zio._ +import zio.prelude.Newtype.unsafeWrap import zio.redis.RedisError.{ProtocolError, WrongType} +import zio.redis.options.NonNegativeLong import zio.test.Assertion.{exists => _, _} import zio.test.TestAspect.flaky import zio.test._ @@ -1457,7 +1459,7 @@ trait StringsSpec extends IntegrationSpec { redis <- ZIO.service[Redis] key <- uuid value <- uuid - result <- redis.set(key, value, expireAt = Some(SetExpire.Seconds(1))) + result <- redis.set(key, value, expireAt = Some(SetExpire.Seconds(NonNegativeLong(1)))) } yield assert(result)(isTrue) }, test("new value with ttl 100 milliseconds") { @@ -1465,17 +1467,9 @@ trait StringsSpec extends IntegrationSpec { redis <- ZIO.service[Redis] key <- uuid value <- uuid - result <- redis.set(key, value, expireAt = Some(SetExpire.Milliseconds(100))) + result <- redis.set(key, value, expireAt = Some(SetExpire.Milliseconds(NonNegativeLong(100)))) } yield assert(result)(isTrue) }, - test("error when negative ttl") { - for { - redis <- ZIO.service[Redis] - key <- uuid - value <- uuid - result <- redis.set(key, value, expireAt = Some(SetExpire.Milliseconds(-1))).either - } yield assert(result)(isLeft(isSubtype[ProtocolError](anything))) - }, test("new value with SetNew parameter") { for { redis <- ZIO.service[Redis] @@ -1533,7 +1527,7 @@ trait StringsSpec extends IntegrationSpec { redis <- ZIO.service[Redis] key <- uuid value <- uuid - _ <- redis.set(key, "value", expireAt = Some(SetExpire.Seconds(1))) + _ <- redis.set(key, "value", expireAt = Some(SetExpire.Seconds(NonNegativeLong(1)))) result <- redis.set(key, value, expireAt = Some(SetExpire.KeepTtl)) } yield assert(result)(isTrue) } @@ -1585,7 +1579,7 @@ trait StringsSpec extends IntegrationSpec { redis <- ZIO.service[Redis] key <- uuid value <- uuid - _ <- redis.set(key, value, expireAt = Some(SetExpire.Seconds(1))) + _ <- redis.set(key, value, expireAt = Some(SetExpire.Seconds(NonNegativeLong(1)))) existsBefore <- redis.exists(key) fiber <- ZIO.sleep(1010.millis).fork <* TestClock.adjust(1010.millis) _ <- fiber.join @@ -1598,7 +1592,7 @@ trait StringsSpec extends IntegrationSpec { key <- uuid value <- uuid _ <- redis.set(key, "value") - _ <- redis.set(key, value, expireAt = Some(SetExpire.Seconds(1))) + _ <- redis.set(key, value, expireAt = Some(SetExpire.Seconds(NonNegativeLong(1)))) existsBefore <- redis.exists(key) fiber <- ZIO.sleep(1010.millis).fork <* TestClock.adjust(1010.millis) _ <- fiber.join @@ -1611,7 +1605,7 @@ trait StringsSpec extends IntegrationSpec { key <- uuid value <- uuid _ <- redis.sAdd(key, "a") - _ <- redis.set(key, value, expireAt = Some(SetExpire.Seconds(1))) + _ <- redis.set(key, value, expireAt = Some(SetExpire.Seconds(NonNegativeLong(1)))) existsBefore <- redis.exists(key) fiber <- ZIO.sleep(1010.millis).fork <* TestClock.adjust(1010.millis) _ <- fiber.join @@ -1623,15 +1617,7 @@ trait StringsSpec extends IntegrationSpec { redis <- ZIO.service[Redis] key <- uuid value <- uuid - result <- redis.set(key, value, expireAt = Some(SetExpire.Seconds(0))).either - } yield assert(result)(isLeft(isSubtype[ProtocolError](anything))) - }, - test("error when negative ttl") { - for { - redis <- ZIO.service[Redis] - key <- uuid - value <- uuid - result <- redis.set(key, value, expireAt = Some(SetExpire.Seconds(-1))).either + result <- redis.set(key, value, expireAt = Some(SetExpire.Seconds(NonNegativeLong(1)))).either } yield assert(result)(isLeft(isSubtype[ProtocolError](anything))) } ), @@ -1735,7 +1721,7 @@ trait StringsSpec extends IntegrationSpec { key <- uuid value <- uuid _ <- redis.set(key, value) - exists <- redis.getEx(key, GetExpire.Seconds(1)).returning[String] + exists <- redis.getEx(key, GetExpire.Seconds(NonNegativeLong(1))).returning[String] fiber <- ZIO.sleep(1020.millis).fork <* TestClock.adjust(1020.millis) _ <- fiber.join res <- redis.get(key).returning[String] @@ -1747,7 +1733,7 @@ trait StringsSpec extends IntegrationSpec { key <- uuid value <- uuid _ <- redis.set(key, value) - exists <- redis.getEx(key, GetExpire.Milliseconds(10)).returning[String] + exists <- redis.getEx(key, GetExpire.Milliseconds(NonNegativeLong(10))).returning[String] fiber <- ZIO.sleep(20.millis).fork <* TestClock.adjust(20.millis) _ <- fiber.join res <- redis.get(key).returning[String] @@ -1755,40 +1741,42 @@ trait StringsSpec extends IntegrationSpec { } @@ flaky, test("not found value when set seconds timestamp") { for { - redis <- ZIO.service[Redis] - key <- uuid - value <- uuid - _ <- redis.set(key, value) - expiresAt <- Clock.instant.map(_.plusMillis(10.millis.toMillis)) - exists <- redis.getEx(key, GetExpire.UnixTimeSeconds(expiresAt.getEpochSecond)).returning[String] - fiber <- ZIO.sleep(20.millis).fork <* TestClock.adjust(20.millis) - _ <- fiber.join - res <- redis.get(key).returning[String] + redis <- ZIO.service[Redis] + key <- uuid + value <- uuid + _ <- redis.set(key, value) + expiresAt <- Clock.instant.map(_.plusMillis(10.millis.toMillis)) + expiresAtMillis = unsafeWrap(NonNegativeLong)(expiresAt.toEpochMilli) + exists <- redis.getEx(key, GetExpire.UnixTimeSeconds(expiresAtMillis)).returning[String] + fiber <- ZIO.sleep(20.millis).fork <* TestClock.adjust(20.millis) + _ <- fiber.join + res <- redis.get(key).returning[String] } yield assert(res.isDefined)(equalTo(false)) && assert(exists)(isSome(equalTo(value))) } @@ flaky, test("not found value when set milliseconds timestamp") { for { - redis <- ZIO.service[Redis] - key <- uuid - value <- uuid - _ <- redis.set(key, value) - expiresAt <- Clock.instant.map(_.plusMillis(10.millis.toMillis)) - exists <- - redis.getEx(key, GetExpire.UnixTimeMilliseconds(expiresAt.toEpochMilli)).returning[String] - fiber <- ZIO.sleep(20.millis).fork <* TestClock.adjust(20.millis) - _ <- fiber.join - res <- redis.get(key).returning[String] + redis <- ZIO.service[Redis] + key <- uuid + value <- uuid + _ <- redis.set(key, value) + expiresAt <- Clock.instant.map(_.plusMillis(10.millis.toMillis)) + expiresAtMillis = unsafeWrap(NonNegativeLong)(expiresAt.toEpochMilli) + exists <- redis.getEx(key, GetExpire.UnixTimeMilliseconds(expiresAtMillis)).returning[String] + fiber <- ZIO.sleep(20.millis).fork <* TestClock.adjust(20.millis) + _ <- fiber.join + res <- redis.get(key).returning[String] } yield assert(res.isDefined)(equalTo(false)) && assert(exists)(isSome(equalTo(value))) } @@ flaky, test("key not found") { for { - redis <- ZIO.service[Redis] - key <- uuid - value <- uuid - _ <- redis.set(key, value) - expiresAt <- Clock.instant.map(_.plusMillis(10.millis.toMillis)) - res <- redis.getEx(value, GetExpire.UnixTimeMilliseconds(expiresAt.toEpochMilli)).returning[String] - res2 <- redis.getEx(value, GetExpire.Milliseconds(10)).returning[String] + redis <- ZIO.service[Redis] + key <- uuid + value <- uuid + _ <- redis.set(key, value) + expiresAt <- Clock.instant.map(_.plusMillis(10.millis.toMillis)) + expiresAtMillis = unsafeWrap(NonNegativeLong)(expiresAt.toEpochMilli) + res <- redis.getEx(value, GetExpire.UnixTimeMilliseconds(expiresAtMillis)).returning[String] + res2 <- redis.getEx(value, GetExpire.Milliseconds(NonNegativeLong(10))).returning[String] } yield assert(res)(isNone) && assert(res2)(isNone) } @@ flaky ), diff --git a/modules/redis/src/main/scala/zio/redis/options/Strings.scala b/modules/redis/src/main/scala/zio/redis/options/Strings.scala index 812a071ea..99ffe3024 100644 --- a/modules/redis/src/main/scala/zio/redis/options/Strings.scala +++ b/modules/redis/src/main/scala/zio/redis/options/Strings.scala @@ -96,21 +96,21 @@ trait Strings { sealed trait SetExpire object SetExpire { - case object KeepTtl extends SetExpire - sealed case class Milliseconds(milliseconds: Long) extends SetExpire - sealed case class Seconds(seconds: Long) extends SetExpire - sealed case class UnixTimeMilliseconds(milliseconds: Long) extends SetExpire - sealed case class UnixTimeSeconds(seconds: Long) extends SetExpire + case object KeepTtl extends SetExpire + sealed case class Milliseconds(milliseconds: NonNegativeLong) extends SetExpire + sealed case class Seconds(seconds: NonNegativeLong) extends SetExpire + sealed case class UnixTimeMilliseconds(milliseconds: NonNegativeLong) extends SetExpire + sealed case class UnixTimeSeconds(seconds: NonNegativeLong) extends SetExpire } sealed trait GetExpire object GetExpire { - case object Persist extends GetExpire - sealed case class Milliseconds(milliseconds: Long) extends GetExpire - sealed case class Seconds(seconds: Long) extends GetExpire - sealed case class UnixTimeMilliseconds(milliseconds: Long) extends GetExpire - sealed case class UnixTimeSeconds(seconds: Long) extends GetExpire + case object Persist extends GetExpire + sealed case class Milliseconds(milliseconds: NonNegativeLong) extends GetExpire + sealed case class Seconds(seconds: NonNegativeLong) extends GetExpire + sealed case class UnixTimeMilliseconds(milliseconds: NonNegativeLong) extends GetExpire + sealed case class UnixTimeSeconds(seconds: NonNegativeLong) extends GetExpire } case object GetKeyword { diff --git a/modules/redis/src/main/scala/zio/redis/options/package.scala b/modules/redis/src/main/scala/zio/redis/options/package.scala new file mode 100644 index 000000000..739073f2d --- /dev/null +++ b/modules/redis/src/main/scala/zio/redis/options/package.scala @@ -0,0 +1,12 @@ +package zio.redis + +import zio.prelude.Assertion.greaterThanOrEqualTo +import zio.prelude.Newtype + +package object options { + object NonNegativeLong extends Newtype[Long] { + override def assertion = assert(greaterThanOrEqualTo(0L)) // scalafix:ok + } + + type NonNegativeLong = NonNegativeLong.Type +} diff --git a/modules/redis/src/test/scala/zio/redis/InputSpec.scala b/modules/redis/src/test/scala/zio/redis/InputSpec.scala index f1056c98e..a048ca70c 100644 --- a/modules/redis/src/test/scala/zio/redis/InputSpec.scala +++ b/modules/redis/src/test/scala/zio/redis/InputSpec.scala @@ -1,9 +1,11 @@ package zio.redis import zio._ +import zio.prelude.Newtype.unsafeWrap import zio.redis.Input._ import zio.redis.internal.RespCommand import zio.redis.internal.RespCommandArgument._ +import zio.redis.options.NonNegativeLong import zio.test.Assertion._ import zio.test._ @@ -1300,27 +1302,18 @@ object InputSpec extends BaseSpec { test("GetExInput - valid value") { for { resultSeconds <- - ZIO.attempt(GetExInput[String]().encode(scala.Tuple2("key", GetExpire.Seconds(1)))) + ZIO.attempt(GetExInput[String]().encode(scala.Tuple2("key", GetExpire.Seconds(NonNegativeLong(1))))) resultMilliseconds <- - ZIO.attempt(GetExInput[String]().encode(scala.Tuple2("key", GetExpire.Milliseconds(100)))) - resultUnixTimeSeconds <- ZIO.attempt( - GetExInput[String]().encode( - scala.Tuple2( - "key", - GetExpire.UnixTimeSeconds(Instant.parse("2021-04-06T00:00:00Z").getEpochSecond) - ) - ) + GetExInput[String]().encode(scala.Tuple2("key", GetExpire.Milliseconds(NonNegativeLong(100)))) ) + unixTimeSeconds = unsafeWrap(NonNegativeLong)(Instant.parse("2021-04-06T00:00:00Z").getEpochSecond) + resultUnixTimeSeconds <- + ZIO.attempt(GetExInput[String]().encode(scala.Tuple2("key", GetExpire.UnixTimeSeconds(unixTimeSeconds)))) + unixTimeMilliseconds = unsafeWrap(NonNegativeLong)(Instant.parse("2021-04-06T00:00:00Z").toEpochMilli) resultUnixTimeMilliseconds <- ZIO.attempt( - GetExInput[String]().encode( - scala - .Tuple2( - "key", - GetExpire.UnixTimeMilliseconds(Instant.parse("2021-04-06T00:00:00Z").toEpochMilli) - ) - ) + GetExInput[String]().encode(scala.Tuple2("key", GetExpire.UnixTimeMilliseconds(unixTimeMilliseconds))) ) resultPersist <- ZIO.attempt(GetExInput[String]().encode(scala.Tuple2("key", GetExpire.Persist))) } yield assertTrue( From 0d0e2453eee2c848f4e6c6792b528192b8ea770f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dragutin=20Marjanovi=C4=87?= Date: Sat, 28 Sep 2024 22:02:47 +0200 Subject: [PATCH 15/16] Fix docs --- README.md | 3 ++- docs/index.md | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index cd48f4704..1d6c919e4 100644 --- a/README.md +++ b/README.md @@ -40,6 +40,7 @@ libraryDependencies ++= Seq( ```scala import zio._ import zio.redis._ +import zio.redis.options.NonNegativeLong import zio.schema._ import zio.schema.codec._ @@ -52,7 +53,7 @@ object ZIORedisExample extends ZIOAppDefault { val myApp: ZIO[Redis, RedisError, Unit] = for { redis <- ZIO.service[Redis] - _ <- redis.set("myKey", 8L, expireAt = Some(SetExpire.SetExpireSeconds(1.minutes))) + _ <- redis.set("myKey", 8L, expireAt = Some(SetExpire.SetExpireSeconds(NonNegativeLong(60)))) v <- redis.get("myKey").returning[Long] _ <- Console.printLine(s"Value of myKey: $v").orDie _ <- redis.hSet("myHash", ("k1", 6), ("k2", 2)) diff --git a/docs/index.md b/docs/index.md index a705672d7..c441e41a6 100644 --- a/docs/index.md +++ b/docs/index.md @@ -40,6 +40,7 @@ libraryDependencies ++= Seq( ```scala mdoc:compile-only import zio._ import zio.redis._ +import zio.redis.options.NonNegativeLong import zio.schema._ import zio.schema.codec._ @@ -52,7 +53,7 @@ object ZIORedisExample extends ZIOAppDefault { val myApp: ZIO[Redis, RedisError, Unit] = for { redis <- ZIO.service[Redis] - _ <- redis.set("myKey", 8L, expireAt = Some(SetExpire.Seconds(60))) + _ <- redis.set("myKey", 8L, expireAt = Some(SetExpire.Seconds(NonNegativeLong(60)))) v <- redis.get("myKey").returning[Long] _ <- Console.printLine(s"Value of myKey: $v").orDie _ <- redis.hSet("myHash", ("k1", 6), ("k2", 2)) From 20a22c75312e35ca893a081a162b8f514c18d732 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dragutin=20Marjanovi=C4=87?= Date: Sat, 28 Sep 2024 22:14:55 +0200 Subject: [PATCH 16/16] Change NonNegativeLong to PositiveLong --- .../zio/redis/example/ContributorsCache.scala | 4 +- .../src/test/scala/zio/redis/KeysSpec.scala | 6 +-- .../test/scala/zio/redis/StringsSpec.scala | 52 ++++++++----------- .../main/scala/zio/redis/api/Connection.scala | 2 +- .../scala/zio/redis/options/Strings.scala | 20 +++---- .../scala/zio/redis/options/package.scala | 6 +-- .../src/test/scala/zio/redis/InputSpec.scala | 10 ++-- 7 files changed, 46 insertions(+), 54 deletions(-) diff --git a/modules/example/src/main/scala/zio/redis/example/ContributorsCache.scala b/modules/example/src/main/scala/zio/redis/example/ContributorsCache.scala index 5f94d4764..67524a5bf 100644 --- a/modules/example/src/main/scala/zio/redis/example/ContributorsCache.scala +++ b/modules/example/src/main/scala/zio/redis/example/ContributorsCache.scala @@ -23,7 +23,7 @@ import zio._ import zio.json._ import zio.redis._ import zio.redis.example.ApiError._ -import zio.redis.options.NonNegativeLong +import zio.redis.options.PositiveLong trait ContributorsCache { def fetchAll(repository: Repository): IO[ApiError, Contributors] @@ -41,7 +41,7 @@ object ContributorsCache { ZIO .fromOption(NonEmptyChunk.fromChunk(contributors)) .map(Contributors(_).toJson) - .flatMap(data => redis.set(repository.key, data, expireAt = Some(SetExpire.Seconds(NonNegativeLong(60)))).orDie) + .flatMap(data => redis.set(repository.key, data, expireAt = Some(SetExpire.Seconds(PositiveLong(60)))).orDie) .ignore private def read(repository: Repository): IO[ApiError, Contributors] = diff --git a/modules/redis-it/src/test/scala/zio/redis/KeysSpec.scala b/modules/redis-it/src/test/scala/zio/redis/KeysSpec.scala index 1ceb4a628..994e496a3 100644 --- a/modules/redis-it/src/test/scala/zio/redis/KeysSpec.scala +++ b/modules/redis-it/src/test/scala/zio/redis/KeysSpec.scala @@ -3,7 +3,7 @@ package zio.redis import com.dimafeng.testcontainers.DockerComposeContainer import zio._ import zio.redis.RedisError.ProtocolError -import zio.redis.options.NonNegativeLong +import zio.redis.options.PositiveLong import zio.test.Assertion.{exists => _, _} import zio.test.TestAspect.{restore => _, _} import zio.test._ @@ -245,7 +245,7 @@ trait KeysSpec extends IntegrationSpec { redis <- ZIO.service[Redis] key <- uuid value <- uuid - _ <- redis.set(key, value, expireAt = Some(SetExpire.Milliseconds(NonNegativeLong(1000)))) + _ <- redis.set(key, value, expireAt = Some(SetExpire.Milliseconds(PositiveLong(1000)))) ttl <- redis.ttl(key).either } yield assert(ttl)(isRight) } @@ flaky, @@ -261,7 +261,7 @@ trait KeysSpec extends IntegrationSpec { redis <- ZIO.service[Redis] key <- uuid value <- uuid - _ <- redis.set(key, value, expireAt = Some(SetExpire.Milliseconds(NonNegativeLong(1000)))) + _ <- redis.set(key, value, expireAt = Some(SetExpire.Milliseconds(PositiveLong(1000)))) pTtl <- redis.pTtl(key).either } yield assert(pTtl)(isRight) } @@ flaky, diff --git a/modules/redis-it/src/test/scala/zio/redis/StringsSpec.scala b/modules/redis-it/src/test/scala/zio/redis/StringsSpec.scala index bff61e4e4..8598b3d1d 100644 --- a/modules/redis-it/src/test/scala/zio/redis/StringsSpec.scala +++ b/modules/redis-it/src/test/scala/zio/redis/StringsSpec.scala @@ -3,7 +3,7 @@ package zio.redis import zio._ import zio.prelude.Newtype.unsafeWrap import zio.redis.RedisError.{ProtocolError, WrongType} -import zio.redis.options.NonNegativeLong +import zio.redis.options.PositiveLong import zio.test.Assertion.{exists => _, _} import zio.test.TestAspect.flaky import zio.test._ @@ -1459,7 +1459,7 @@ trait StringsSpec extends IntegrationSpec { redis <- ZIO.service[Redis] key <- uuid value <- uuid - result <- redis.set(key, value, expireAt = Some(SetExpire.Seconds(NonNegativeLong(1)))) + result <- redis.set(key, value, expireAt = Some(SetExpire.Seconds(PositiveLong(1)))) } yield assert(result)(isTrue) }, test("new value with ttl 100 milliseconds") { @@ -1467,7 +1467,7 @@ trait StringsSpec extends IntegrationSpec { redis <- ZIO.service[Redis] key <- uuid value <- uuid - result <- redis.set(key, value, expireAt = Some(SetExpire.Milliseconds(NonNegativeLong(100)))) + result <- redis.set(key, value, expireAt = Some(SetExpire.Milliseconds(PositiveLong(100)))) } yield assert(result)(isTrue) }, test("new value with SetNew parameter") { @@ -1527,7 +1527,7 @@ trait StringsSpec extends IntegrationSpec { redis <- ZIO.service[Redis] key <- uuid value <- uuid - _ <- redis.set(key, "value", expireAt = Some(SetExpire.Seconds(NonNegativeLong(1)))) + _ <- redis.set(key, "value", expireAt = Some(SetExpire.Seconds(PositiveLong(1)))) result <- redis.set(key, value, expireAt = Some(SetExpire.KeepTtl)) } yield assert(result)(isTrue) } @@ -1579,7 +1579,7 @@ trait StringsSpec extends IntegrationSpec { redis <- ZIO.service[Redis] key <- uuid value <- uuid - _ <- redis.set(key, value, expireAt = Some(SetExpire.Seconds(NonNegativeLong(1)))) + _ <- redis.set(key, value, expireAt = Some(SetExpire.Seconds(PositiveLong(1)))) existsBefore <- redis.exists(key) fiber <- ZIO.sleep(1010.millis).fork <* TestClock.adjust(1010.millis) _ <- fiber.join @@ -1592,7 +1592,7 @@ trait StringsSpec extends IntegrationSpec { key <- uuid value <- uuid _ <- redis.set(key, "value") - _ <- redis.set(key, value, expireAt = Some(SetExpire.Seconds(NonNegativeLong(1)))) + _ <- redis.set(key, value, expireAt = Some(SetExpire.Seconds(PositiveLong(1)))) existsBefore <- redis.exists(key) fiber <- ZIO.sleep(1010.millis).fork <* TestClock.adjust(1010.millis) _ <- fiber.join @@ -1605,20 +1605,12 @@ trait StringsSpec extends IntegrationSpec { key <- uuid value <- uuid _ <- redis.sAdd(key, "a") - _ <- redis.set(key, value, expireAt = Some(SetExpire.Seconds(NonNegativeLong(1)))) + _ <- redis.set(key, value, expireAt = Some(SetExpire.Seconds(PositiveLong(1)))) existsBefore <- redis.exists(key) fiber <- ZIO.sleep(1010.millis).fork <* TestClock.adjust(1010.millis) _ <- fiber.join existsAfter <- redis.exists(key) } yield assert(existsBefore)(equalTo(1L)) && assert(existsAfter)(equalTo(0L)) - }, - test("error when 0 seconds ttl") { - for { - redis <- ZIO.service[Redis] - key <- uuid - value <- uuid - result <- redis.set(key, value, expireAt = Some(SetExpire.Seconds(NonNegativeLong(1)))).either - } yield assert(result)(isLeft(isSubtype[ProtocolError](anything))) } ), suite("setNx")( @@ -1721,7 +1713,7 @@ trait StringsSpec extends IntegrationSpec { key <- uuid value <- uuid _ <- redis.set(key, value) - exists <- redis.getEx(key, GetExpire.Seconds(NonNegativeLong(1))).returning[String] + exists <- redis.getEx(key, GetExpire.Seconds(PositiveLong(1))).returning[String] fiber <- ZIO.sleep(1020.millis).fork <* TestClock.adjust(1020.millis) _ <- fiber.join res <- redis.get(key).returning[String] @@ -1733,7 +1725,7 @@ trait StringsSpec extends IntegrationSpec { key <- uuid value <- uuid _ <- redis.set(key, value) - exists <- redis.getEx(key, GetExpire.Milliseconds(NonNegativeLong(10))).returning[String] + exists <- redis.getEx(key, GetExpire.Milliseconds(PositiveLong(10))).returning[String] fiber <- ZIO.sleep(20.millis).fork <* TestClock.adjust(20.millis) _ <- fiber.join res <- redis.get(key).returning[String] @@ -1741,16 +1733,16 @@ trait StringsSpec extends IntegrationSpec { } @@ flaky, test("not found value when set seconds timestamp") { for { - redis <- ZIO.service[Redis] - key <- uuid - value <- uuid - _ <- redis.set(key, value) - expiresAt <- Clock.instant.map(_.plusMillis(10.millis.toMillis)) - expiresAtMillis = unsafeWrap(NonNegativeLong)(expiresAt.toEpochMilli) - exists <- redis.getEx(key, GetExpire.UnixTimeSeconds(expiresAtMillis)).returning[String] - fiber <- ZIO.sleep(20.millis).fork <* TestClock.adjust(20.millis) - _ <- fiber.join - res <- redis.get(key).returning[String] + redis <- ZIO.service[Redis] + key <- uuid + value <- uuid + _ <- redis.set(key, value) + expiresAt <- Clock.instant.map(_.plusMillis(10.millis.toMillis)) + expiresAtSeconds = unsafeWrap(PositiveLong)(expiresAt.getEpochSecond) + exists <- redis.getEx(key, GetExpire.UnixTimeSeconds(expiresAtSeconds)).returning[String] + fiber <- ZIO.sleep(20.millis).fork <* TestClock.adjust(20.millis) + _ <- fiber.join + res <- redis.get(key).returning[String] } yield assert(res.isDefined)(equalTo(false)) && assert(exists)(isSome(equalTo(value))) } @@ flaky, test("not found value when set milliseconds timestamp") { @@ -1760,7 +1752,7 @@ trait StringsSpec extends IntegrationSpec { value <- uuid _ <- redis.set(key, value) expiresAt <- Clock.instant.map(_.plusMillis(10.millis.toMillis)) - expiresAtMillis = unsafeWrap(NonNegativeLong)(expiresAt.toEpochMilli) + expiresAtMillis = unsafeWrap(PositiveLong)(expiresAt.toEpochMilli) exists <- redis.getEx(key, GetExpire.UnixTimeMilliseconds(expiresAtMillis)).returning[String] fiber <- ZIO.sleep(20.millis).fork <* TestClock.adjust(20.millis) _ <- fiber.join @@ -1774,9 +1766,9 @@ trait StringsSpec extends IntegrationSpec { value <- uuid _ <- redis.set(key, value) expiresAt <- Clock.instant.map(_.plusMillis(10.millis.toMillis)) - expiresAtMillis = unsafeWrap(NonNegativeLong)(expiresAt.toEpochMilli) + expiresAtMillis = unsafeWrap(PositiveLong)(expiresAt.toEpochMilli) res <- redis.getEx(value, GetExpire.UnixTimeMilliseconds(expiresAtMillis)).returning[String] - res2 <- redis.getEx(value, GetExpire.Milliseconds(NonNegativeLong(10))).returning[String] + res2 <- redis.getEx(value, GetExpire.Milliseconds(PositiveLong(10))).returning[String] } yield assert(res)(isNone) && assert(res2)(isNone) } @@ flaky ), diff --git a/modules/redis/src/main/scala/zio/redis/api/Connection.scala b/modules/redis/src/main/scala/zio/redis/api/Connection.scala index ac934df0b..0261a207d 100644 --- a/modules/redis/src/main/scala/zio/redis/api/Connection.scala +++ b/modules/redis/src/main/scala/zio/redis/api/Connection.scala @@ -26,7 +26,7 @@ trait Connection[G[+_]] extends RedisEnvironment[G] { /** * Authenticates the current connection to the server in two cases: - * - If the Redis server is password protected via the ''requirepass'' option + * - If the Redis server is password protected via the ''requirepass'' option * - If a Redis 6.0 instance, or greater, is using the [[https://redis.io/topics/acl Redis ACL system]]. In this * case it is assumed that the implicit username is ''default''. * diff --git a/modules/redis/src/main/scala/zio/redis/options/Strings.scala b/modules/redis/src/main/scala/zio/redis/options/Strings.scala index 99ffe3024..7d365648c 100644 --- a/modules/redis/src/main/scala/zio/redis/options/Strings.scala +++ b/modules/redis/src/main/scala/zio/redis/options/Strings.scala @@ -96,21 +96,21 @@ trait Strings { sealed trait SetExpire object SetExpire { - case object KeepTtl extends SetExpire - sealed case class Milliseconds(milliseconds: NonNegativeLong) extends SetExpire - sealed case class Seconds(seconds: NonNegativeLong) extends SetExpire - sealed case class UnixTimeMilliseconds(milliseconds: NonNegativeLong) extends SetExpire - sealed case class UnixTimeSeconds(seconds: NonNegativeLong) extends SetExpire + case object KeepTtl extends SetExpire + sealed case class Milliseconds(milliseconds: PositiveLong) extends SetExpire + sealed case class Seconds(seconds: PositiveLong) extends SetExpire + sealed case class UnixTimeMilliseconds(milliseconds: PositiveLong) extends SetExpire + sealed case class UnixTimeSeconds(seconds: PositiveLong) extends SetExpire } sealed trait GetExpire object GetExpire { - case object Persist extends GetExpire - sealed case class Milliseconds(milliseconds: NonNegativeLong) extends GetExpire - sealed case class Seconds(seconds: NonNegativeLong) extends GetExpire - sealed case class UnixTimeMilliseconds(milliseconds: NonNegativeLong) extends GetExpire - sealed case class UnixTimeSeconds(seconds: NonNegativeLong) extends GetExpire + case object Persist extends GetExpire + sealed case class Milliseconds(milliseconds: PositiveLong) extends GetExpire + sealed case class Seconds(seconds: PositiveLong) extends GetExpire + sealed case class UnixTimeMilliseconds(milliseconds: PositiveLong) extends GetExpire + sealed case class UnixTimeSeconds(seconds: PositiveLong) extends GetExpire } case object GetKeyword { diff --git a/modules/redis/src/main/scala/zio/redis/options/package.scala b/modules/redis/src/main/scala/zio/redis/options/package.scala index 739073f2d..8ba7b1d6f 100644 --- a/modules/redis/src/main/scala/zio/redis/options/package.scala +++ b/modules/redis/src/main/scala/zio/redis/options/package.scala @@ -4,9 +4,9 @@ import zio.prelude.Assertion.greaterThanOrEqualTo import zio.prelude.Newtype package object options { - object NonNegativeLong extends Newtype[Long] { - override def assertion = assert(greaterThanOrEqualTo(0L)) // scalafix:ok + object PositiveLong extends Newtype[Long] { + override def assertion = assert(greaterThanOrEqualTo(1L)) // scalafix:ok } - type NonNegativeLong = NonNegativeLong.Type + type PositiveLong = PositiveLong.Type } diff --git a/modules/redis/src/test/scala/zio/redis/InputSpec.scala b/modules/redis/src/test/scala/zio/redis/InputSpec.scala index a048ca70c..e6ab36fe6 100644 --- a/modules/redis/src/test/scala/zio/redis/InputSpec.scala +++ b/modules/redis/src/test/scala/zio/redis/InputSpec.scala @@ -5,7 +5,7 @@ import zio.prelude.Newtype.unsafeWrap import zio.redis.Input._ import zio.redis.internal.RespCommand import zio.redis.internal.RespCommandArgument._ -import zio.redis.options.NonNegativeLong +import zio.redis.options.PositiveLong import zio.test.Assertion._ import zio.test._ @@ -1302,15 +1302,15 @@ object InputSpec extends BaseSpec { test("GetExInput - valid value") { for { resultSeconds <- - ZIO.attempt(GetExInput[String]().encode(scala.Tuple2("key", GetExpire.Seconds(NonNegativeLong(1))))) + ZIO.attempt(GetExInput[String]().encode(scala.Tuple2("key", GetExpire.Seconds(PositiveLong(1))))) resultMilliseconds <- ZIO.attempt( - GetExInput[String]().encode(scala.Tuple2("key", GetExpire.Milliseconds(NonNegativeLong(100)))) + GetExInput[String]().encode(scala.Tuple2("key", GetExpire.Milliseconds(PositiveLong(100)))) ) - unixTimeSeconds = unsafeWrap(NonNegativeLong)(Instant.parse("2021-04-06T00:00:00Z").getEpochSecond) + unixTimeSeconds = unsafeWrap(PositiveLong)(Instant.parse("2021-04-06T00:00:00Z").getEpochSecond) resultUnixTimeSeconds <- ZIO.attempt(GetExInput[String]().encode(scala.Tuple2("key", GetExpire.UnixTimeSeconds(unixTimeSeconds)))) - unixTimeMilliseconds = unsafeWrap(NonNegativeLong)(Instant.parse("2021-04-06T00:00:00Z").toEpochMilli) + unixTimeMilliseconds = unsafeWrap(PositiveLong)(Instant.parse("2021-04-06T00:00:00Z").toEpochMilli) resultUnixTimeMilliseconds <- ZIO.attempt( GetExInput[String]().encode(scala.Tuple2("key", GetExpire.UnixTimeMilliseconds(unixTimeMilliseconds)))