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

com.twitter.finagle.redis.protocol.commands.CommandArguments.scala Maven / Gradle / Ivy

There is a newer version: 6.39.0
Show newest version
package com.twitter.finagle.redis.protocol

import com.twitter.finagle.netty3.BufChannelBuffer
import com.twitter.finagle.redis.ClientError
import com.twitter.finagle.redis.util._
import com.twitter.io.Buf
import org.jboss.netty.buffer.ChannelBuffer
import scala.collection.breakOut
import java.lang.{Long => JLong}

trait CommandArgument extends Command {
  override def toChannelBuffer: ChannelBuffer = BufChannelBuffer(encoded.reduce(_ concat _))

  private[redis] def encoded: Seq[Buf]
}

case object WithScores extends CommandArgument {
  def command = Commands.WITHSCORES

  def unapply(s: String) = s.toUpperCase match {
    case Commands.WITHSCORES => Some(s)
    case _ => None
  }

  override def encoded = Seq(Buf.Utf8(command))
  override def toString = command
}

case class Limit(offset: Long, count: Long) extends CommandArgument {
  def command = Commands.LIMIT

  override private[redis] def encoded = Seq(
    CommandBytes.LIMIT,
    Buf.Utf8(offset.toString),
    Buf.Utf8(count.toString)
  )

  override def toString = "%s %d %d".format(command, offset, count)
}

object Limit {
  def apply(args: Seq[String]) = {
    RequireClientProtocol(args != null && args.length == 3, "LIMIT requires two arguments")
    RequireClientProtocol(args.head == Commands.LIMIT, "LIMIT must start with LIMIT clause")
    RequireClientProtocol.safe {
      val offset = NumberFormat.toLong(args(1))
      val count = NumberFormat.toLong(args(2))
      new Limit(offset, count)
    }
  }
}

// Represents a list of WEIGHTS
class Weights(underlying: Array[Double]) extends CommandArgument with IndexedSeq[Double] {
  def command = Commands.WEIGHTS

  def apply(idx: Int) = underlying(idx)
  def length = underlying.length

  override private[redis] def encoded: Seq[Buf] =
    CommandBytes.WEIGHTS +: underlying.map(w => Buf.Utf8(w.toString))(breakOut)

  override def toString = Weights.toString + " " + this.mkString(" ")

}

// Handles parsing and manipulation of WEIGHTS arguments
object Weights {
  def apply(weight: Double) = new Weights(Array(weight))
  def apply(weights: Double*) = new Weights(weights.toArray)
  def apply(weights: Array[Double]) = new Weights(weights)

  def apply(args: Seq[String]): Option[Weights] = {
    val argLength = args.length
    RequireClientProtocol(
      args != null && argLength > 0,
      "WEIGHTS can not be specified with an empty list")
    args.head.toUpperCase match {
      case Commands.WEIGHTS =>
        RequireClientProtocol(argLength > 1, "WEIGHTS requires additional arguments")
        val weights: Array[Double] = RequireClientProtocol.safe {
          args.tail.map { item => NumberFormat.toDouble(item) }(collection.breakOut)
        }
        Some(new Weights(weights))
      case _ => None
    }
  }
  override def toString = Commands.WEIGHTS
}

// Handles parsing and manipulation of AGGREGATE arguments
sealed abstract class Aggregate(val name: String) extends CommandArgument {

  def command: String = s"${Commands.AGGREGATE} ${name.toUpperCase}"

  override private[redis] def encoded: Seq[Buf] =
    Seq(CommandBytes.AGGREGATE, Buf.Utf8(name.toUpperCase))

  def equals(str: String) = str.equals(name)
  override def toString = command
}

object Aggregate {
  case object Sum extends Aggregate("SUM")
  case object Min extends Aggregate("MIN")
  case object Max extends Aggregate("MAX")
  override def toString = Commands.AGGREGATE

  def apply(args: Seq[String]): Option[Aggregate] = {
    val argLength = args.length
    RequireClientProtocol(
      args != null && argLength > 0,
      "AGGREGATE can not be specified with empty list")
    args.head.toUpperCase match {
      case Commands.AGGREGATE =>
        RequireClientProtocol(argLength == 2, "AGGREGATE requires a type (MIN, MAX, SUM)")
        args(1).toUpperCase match {
          case Aggregate.Sum.name => Some(Aggregate.Sum)
          case Aggregate.Max.name => Some(Aggregate.Max)
          case Aggregate.Min.name => Some(Aggregate.Min)
          case _ => throw new ClientError("AGGREGATE type must be one of MIN, MAX or SUM")
        }
      case _ => None
    }
  }
}


object Count {

  def apply(args: Seq[String]): Option[JLong] = {
    RequireClientProtocol(
      args != null && !args.isEmpty,
      "COUNT can not be specified with empty list")
    args.head.toUpperCase match {
      case Commands.AGGREGATE =>
        RequireClientProtocol(args.length == 2, "COUNT requires two arguments")
        Some(RequireClientProtocol.safe { NumberFormat.toLong(args(1)) })
      case _ => None
    }
  }
}


object Pattern {
  def apply(args: Seq[String]): Option[String] = {
    RequireClientProtocol(
      args != null && !args.isEmpty,
      "AGGREGATE can not be specified with empty list")
    args.head.toUpperCase match {
      case Commands.AGGREGATE => Some(args(1))
      case _ => None
    }
  }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy