Skip to content

Commit

Permalink
implicit ByteStringSerializer (for keys and values) #4
Browse files Browse the repository at this point in the history
  • Loading branch information
Valerian Barbot committed Aug 31, 2013
1 parent c5e157c commit b41da0b
Show file tree
Hide file tree
Showing 24 changed files with 495 additions and 478 deletions.
98 changes: 50 additions & 48 deletions src/main/scala/redis/Converter.scala
Original file line number Diff line number Diff line change
Expand Up @@ -6,54 +6,6 @@ import scala.util.Try
import scala.annotation.tailrec
import scala.collection.mutable

trait RedisValueConverter[A] {
def from(a: A): ByteString
}

object RedisValueConverter {

implicit object StringConverter extends RedisValueConverter[String] {
def from(s: String): ByteString = ByteString(s)
}

implicit object ShortConverter extends RedisValueConverter[Short] {
def from(i: Short): ByteString = ByteString(i.toString)
}

implicit object IntConverter extends RedisValueConverter[Int] {
def from(i: Int): ByteString = ByteString(i.toString)
}

implicit object LongConverter extends RedisValueConverter[Long] {
def from(i: Long): ByteString = ByteString(i.toString)
}

implicit object FloatConverter extends RedisValueConverter[Float] {
def from(f: Float): ByteString = ByteString(f.toString)
}

implicit object DoubleConverter extends RedisValueConverter[Double] {
def from(d: Double): ByteString = ByteString(d.toString)
}

implicit object CharConverter extends RedisValueConverter[Char] {
def from(c: Char): ByteString = ByteString(c)
}

implicit object ByteConverter extends RedisValueConverter[Byte] {
def from(b: Byte): ByteString = ByteString(b)
}

implicit object ArrayByteConverter extends RedisValueConverter[Array[Byte]] {
def from(b: Array[Byte]): ByteString = ByteString(b)
}

implicit object ByteStringConverter extends RedisValueConverter[ByteString] {
def from(bs: ByteString): ByteString = bs
}

}

trait MultiBulkConverter[A] {
def to(redisReply: MultiBulk): Try[A]
}
Expand Down Expand Up @@ -109,3 +61,53 @@ object MultiBulkConverter {
}

}

trait ByteStringSerializer[K] {
def serialize(key: K): ByteString
}

object ByteStringSerializer extends ByteStringSerializerLowPriority

trait ByteStringSerializerLowPriority {

implicit object String extends ByteStringSerializer[String] {
def serialize(key: String): ByteString = ByteString(key)
}

implicit object ShortConverter extends ByteStringSerializer[Short] {
def serialize(i: Short): ByteString = ByteString(i.toString)
}

implicit object IntConverter extends ByteStringSerializer[Int] {
def serialize(i: Int): ByteString = ByteString(i.toString)
}

implicit object LongConverter extends ByteStringSerializer[Long] {
def serialize(i: Long): ByteString = ByteString(i.toString)
}

implicit object FloatConverter extends ByteStringSerializer[Float] {
def serialize(f: Float): ByteString = ByteString(f.toString)
}

implicit object DoubleConverter extends ByteStringSerializer[Double] {
def serialize(d: Double): ByteString = ByteString(d.toString)
}

implicit object CharConverter extends ByteStringSerializer[Char] {
def serialize(c: Char): ByteString = ByteString(c)
}

implicit object ByteConverter extends ByteStringSerializer[Byte] {
def serialize(b: Byte): ByteString = ByteString(b)
}

implicit object ArrayByteConverter extends ByteStringSerializer[Array[Byte]] {
def serialize(b: Array[Byte]): ByteString = ByteString(b)
}

implicit object ByteStringConverter extends ByteStringSerializer[ByteString] {
def serialize(bs: ByteString): ByteString = bs
}

}
22 changes: 12 additions & 10 deletions src/main/scala/redis/api/BLists.scala
Original file line number Diff line number Diff line change
@@ -1,31 +1,33 @@
package redis.api.blists

import scala.concurrent.duration.{Duration, FiniteDuration}
import redis.{RedisCommandRedisReply, RedisCommandMultiBulk, MultiBulkConverter}
import redis.{ByteStringSerializer, RedisCommandRedisReply, RedisCommandMultiBulk, MultiBulkConverter}
import akka.util.ByteString
import redis.protocol.{RedisReply, MultiBulk, Bulk}

case class Blpop(keys: Seq[String], timeout: FiniteDuration = Duration.Zero)
extends BXpop("BLPOP")
case class Blpop[KK: ByteStringSerializer](keys: Seq[KK], timeout: FiniteDuration = Duration.Zero)
extends BXpop[KK]("BLPOP")


case class Brpop(keys: Seq[String], timeout: FiniteDuration = Duration.Zero)
extends BXpop("BRPOP")
case class Brpop[KK: ByteStringSerializer](keys: Seq[KK], timeout: FiniteDuration = Duration.Zero)
extends BXpop[KK]("BRPOP")


private[redis] abstract class BXpop(command: String) extends RedisCommandMultiBulk[Option[(String, ByteString)]] {
val keys: Seq[String]
private[redis] abstract class BXpop[KK](command: String)(implicit redisKeys: ByteStringSerializer[KK])
extends RedisCommandMultiBulk[Option[(String, ByteString)]] {
val keys: Seq[KK]
val timeout: FiniteDuration

val encodedRequest: ByteString = encode(command, keys.map(ByteString.apply).seq ++ Seq(ByteString(timeout.toSeconds.toString)))
val encodedRequest: ByteString = encode(command, keys.map(redisKeys.serialize).seq ++ Seq(ByteString(timeout.toSeconds.toString)))

def decodeReply(mb: MultiBulk) = MultiBulkConverter.toOptionStringByteString(mb)
}

case class Brpopplush(source: String, destination: String, timeout: FiniteDuration = Duration.Zero)
case class Brpopplush[KS, KD](source: KS, destination: KD, timeout: FiniteDuration = Duration.Zero)
(implicit bsSource: ByteStringSerializer[KS], bsDest: ByteStringSerializer[KD])
extends RedisCommandRedisReply[Option[ByteString]] {
val encodedRequest: ByteString = encode("BRPOPLPUSH",
Seq(ByteString(source), ByteString(destination), ByteString(timeout.toSeconds.toString)))
Seq(bsSource.serialize(source), bsDest.serialize(destination), ByteString(timeout.toSeconds.toString)))

def decodeReply(redisReply: RedisReply): Option[ByteString] = redisReply match {
case b: Bulk => b.asOptByteString
Expand Down
8 changes: 4 additions & 4 deletions src/main/scala/redis/api/Connection.scala
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,14 @@ import redis._
import akka.util.ByteString
import redis.protocol.Status

case class Auth[A](value: A)(implicit convert: RedisValueConverter[A]) extends RedisCommandStatus[Status] {
val encodedRequest: ByteString = encode("AUTH", Seq(convert.from(value)))
case class Auth[V](value: V)(implicit convert: ByteStringSerializer[V]) extends RedisCommandStatus[Status] {
val encodedRequest: ByteString = encode("AUTH", Seq(convert.serialize(value)))

def decodeReply(s: Status) = s
}

case class Echo[A](value: A)(implicit convert: RedisValueConverter[A]) extends RedisCommandBulkOptionByteString {
val encodedRequest: ByteString = encode("ECHO", Seq(convert.from(value)))
case class Echo[V](value: V)(implicit convert: ByteStringSerializer[V]) extends RedisCommandBulkOptionByteString {
val encodedRequest: ByteString = encode("ECHO", Seq(convert.serialize(value)))
}

case object Ping extends RedisCommandStatus[String] {
Expand Down
57 changes: 30 additions & 27 deletions src/main/scala/redis/api/Hashes.scala
Original file line number Diff line number Diff line change
Expand Up @@ -6,20 +6,20 @@ import scala.collection.mutable
import scala.annotation.tailrec
import redis.protocol.MultiBulk

case class Hdel(key: String, fields: Seq[String]) extends RedisCommandIntegerLong {
val encodedRequest: ByteString = encode("HDEL", ByteString(key) +: fields.map(ByteString.apply))
case class Hdel[K, KK](key: K, fields: Seq[KK])(implicit redisKey: ByteStringSerializer[K], redisFields: ByteStringSerializer[KK]) extends RedisCommandIntegerLong {
val encodedRequest: ByteString = encode("HDEL", redisKey.serialize(key) +: fields.map(redisFields.serialize))
}

case class Hexists(key: String, field: String) extends RedisCommandIntegerBoolean {
val encodedRequest: ByteString = encode("HEXISTS", Seq(ByteString(key), ByteString(field)))
case class Hexists[K, KK](key: K, field: KK)(implicit redisKey: ByteStringSerializer[K], redisFields: ByteStringSerializer[KK]) extends RedisCommandIntegerBoolean {
val encodedRequest: ByteString = encode("HEXISTS", Seq(redisKey.serialize(key), redisFields.serialize(field)))
}

case class Hget(key: String, field: String) extends RedisCommandBulkOptionByteString {
val encodedRequest: ByteString = encode("HGET", Seq(ByteString(key), ByteString(field)))
case class Hget[K, KK](key: K, field: KK)(implicit redisKey: ByteStringSerializer[K], redisFields: ByteStringSerializer[KK]) extends RedisCommandBulkOptionByteString {
val encodedRequest: ByteString = encode("HGET", Seq(redisKey.serialize(key), redisFields.serialize(field)))
}

case class Hgetall(key: String) extends RedisCommandMultiBulk[Map[String, ByteString]] {
val encodedRequest: ByteString = encode("HGETALL", Seq(ByteString(key)))
case class Hgetall[K](key: K)(implicit redisKey: ByteStringSerializer[K]) extends RedisCommandMultiBulk[Map[String, ByteString]] {
val encodedRequest: ByteString = encode("HGETALL", Seq(redisKey.serialize(key)))

def decodeReply(mb: MultiBulk) = mb.responses.map(r => {
val seq = r.map(_.toByteString)
Expand All @@ -37,47 +37,50 @@ case class Hgetall(key: String) extends RedisCommandMultiBulk[Map[String, ByteSt
}
}

case class Hincrby(key: String, fields: String, increment: Long) extends RedisCommandIntegerLong {
val encodedRequest: ByteString = encode("HINCRBY", Seq(ByteString(key), ByteString(fields), ByteString(increment.toString)))
case class Hincrby[K, KK](key: K, fields: KK, increment: Long)(implicit redisKey: ByteStringSerializer[K], redisFields: ByteStringSerializer[KK])
extends RedisCommandIntegerLong {
val encodedRequest: ByteString = encode("HINCRBY", Seq(redisKey.serialize(key), redisFields.serialize(fields), ByteString(increment.toString)))
}

case class Hincrbyfloat(key: String, fields: String, increment: Double) extends RedisCommandBulkDouble {
val encodedRequest: ByteString = encode("HINCRBYFLOAT", Seq(ByteString(key), ByteString(fields), ByteString(increment.toString)))
case class Hincrbyfloat[K, KK](key: K, fields: KK, increment: Double)(implicit redisKey: ByteStringSerializer[K], redisFields: ByteStringSerializer[KK])
extends RedisCommandBulkDouble {
val encodedRequest: ByteString = encode("HINCRBYFLOAT", Seq(redisKey.serialize(key), redisFields.serialize(fields), ByteString(increment.toString)))
}

case class Hkeys(key: String) extends RedisCommandMultiBulk[Seq[String]] {
val encodedRequest: ByteString = encode("HKEYS", Seq(ByteString(key)))
case class Hkeys[K](key: K)(implicit redisKey: ByteStringSerializer[K]) extends RedisCommandMultiBulk[Seq[String]] {
val encodedRequest: ByteString = encode("HKEYS", Seq(redisKey.serialize(key)))

def decodeReply(mb: MultiBulk) = MultiBulkConverter.toSeqString(mb)
}

case class Hlen(key: String) extends RedisCommandIntegerLong {
val encodedRequest: ByteString = encode("HLEN", Seq(ByteString(key)))
case class Hlen[K](key: K)(implicit redisKey: ByteStringSerializer[K]) extends RedisCommandIntegerLong {
val encodedRequest: ByteString = encode("HLEN", Seq(redisKey.serialize(key)))
}

case class Hmget(key: String, fields: Seq[String]) extends RedisCommandMultiBulk[Seq[Option[ByteString]]] {
val encodedRequest: ByteString = encode("HMGET", ByteString(key) +: fields.map(ByteString.apply))
case class Hmget[K, KK](key: K, fields: Seq[KK])(implicit redisKey: ByteStringSerializer[K], redisFields: ByteStringSerializer[KK])
extends RedisCommandMultiBulk[Seq[Option[ByteString]]] {
val encodedRequest: ByteString = encode("HMGET", redisKey.serialize(key) +: fields.map(redisFields.serialize))

def decodeReply(mb: MultiBulk) = MultiBulkConverter.toSeqOptionByteString(mb)
}

case class Hmset[A](key: String, keysValues: Map[String, A])(implicit convert: RedisValueConverter[A])
case class Hmset[K, KK, V](key: K, keysValues: Map[KK, V])(implicit redisKey: ByteStringSerializer[K], redisFields: ByteStringSerializer[KK], convert: ByteStringSerializer[V])
extends RedisCommandStatusBoolean {
val encodedRequest: ByteString = encode("HMSET", ByteString(key) +: keysValues.foldLeft(Seq.empty[ByteString])({
case (acc, e) => ByteString(e._1) +: convert.from(e._2) +: acc
val encodedRequest: ByteString = encode("HMSET", redisKey.serialize(key) +: keysValues.foldLeft(Seq.empty[ByteString])({
case (acc, e) => redisFields.serialize(e._1) +: convert.serialize(e._2) +: acc
}))
}

case class Hset[A](key: String, field: String, value: A)(implicit convert: RedisValueConverter[A])
case class Hset[K, KK, V](key: K, field: KK, value: V)(implicit redisKey: ByteStringSerializer[K], redisFields: ByteStringSerializer[KK], convert: ByteStringSerializer[V])
extends RedisCommandIntegerBoolean {
val encodedRequest: ByteString = encode("HSET", Seq(ByteString(key), ByteString(field), convert.from(value)))
val encodedRequest: ByteString = encode("HSET", Seq(redisKey.serialize(key), redisFields.serialize(field), convert.serialize(value)))
}

case class Hsetnx[A](key: String, field: String, value: A)(implicit convert: RedisValueConverter[A])
case class Hsetnx[K, KK, V](key: K, field: KK, value: V)(implicit redisKey: ByteStringSerializer[K], redisFields: ByteStringSerializer[KK], convert: ByteStringSerializer[V])
extends RedisCommandIntegerBoolean {
val encodedRequest: ByteString = encode("HSETNX", Seq(ByteString(key), ByteString(field), convert.from(value)))
val encodedRequest: ByteString = encode("HSETNX", Seq(redisKey.serialize(key), redisFields.serialize(field), convert.serialize(value)))
}

case class Hvals(key: String) extends RedisCommandMultiBulkSeqByteString {
val encodedRequest: ByteString = encode("HVALS", Seq(ByteString(key)))
case class Hvals[K](key: K)(implicit redisKey: ByteStringSerializer[K]) extends RedisCommandMultiBulkSeqByteString {
val encodedRequest: ByteString = encode("HVALS", Seq(redisKey.serialize(key)))
}
Loading

0 comments on commit b41da0b

Please # to comment.