├── .gitignore
├── LICENSE
├── README.md
├── build.sbt
├── project
└── build.properties
└── src
├── main
└── scala
│ └── redis
│ └── algebra
│ ├── connection.scala
│ ├── data.scala
│ ├── hash.scala
│ ├── key.scala
│ ├── list.scala
│ ├── package.scala
│ ├── script.scala
│ ├── server.scala
│ ├── set.scala
│ ├── string.scala
│ └── zset.scala
└── test
└── scala
└── redis
└── algebra
├── bytestring.scala
├── interpreter.scala
└── keyspec.scala
/.gitignore:
--------------------------------------------------------------------------------
1 | project/project
2 | project/target
3 | target
4 | tmp
5 | .history
6 | /.idea
7 | /*.iml
8 | /out
9 | /.idea_modules
10 | /.classpath
11 | /.project
12 | /.settings
13 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Copyright (c) 2013 Eric Thul
2 |
3 | Permission is hereby granted, free of charge, to any person obtaining a
4 | copy of this software and associated documentation files (the
5 | "Software"), in the Software without restriction, including without
6 | limitation the rights to use, copy, modify, merge, publish, distribute,
7 | sublicense, and/or sell copies of the Software, and to permit persons to
8 | whom the Software is furnished to do so, subject to the following
9 | conditions:
10 |
11 | The above copyright notice and this permission notice shall be included
12 | in all copies or substantial portions of the Software.
13 |
14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15 | OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
17 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
18 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
19 | TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
20 | SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Redis Algebra
2 |
3 | A Redis library for Scala that is built on Scalaz's free monad implementation, designed in the spirit of Swierstra's [Data types a la carte](http://www.staff.science.uu.nl/~swier004/Publications/DataTypesALaCarte.pdf). The library is intended to be used in combination with other free monad based libraries to build rich algebras tailored to the user's needs.
4 |
5 | The functions that this library provides correspond to the list of [Redis commands](http://redis.io/commands). In order to run programs that have been written using this library, an interpreter needs to be implemented to handle each of the commands. There is no interpreter included by default; however, one may be made available in a separate repository. Interpreters may be interchanged freely based on the user's desired behaviour. For instance, a non-blocking interpreter that sends commands to Redis may be used in production, while an interpreter that uses an in-memory representation may be used when running tests.
6 |
7 | # Install
8 |
9 | Releases and snapshots of the Redis Algebra library are published to the [Sonatype OSS Repository Hosting Service](https://oss.sonatype.org). The necessary [SBT Resolvers](http://www.scala-sbt.org/release/docs/Detailed-Topics/Resolvers.html) may be added as follows to your SBT build file.
10 |
11 | ```scala
12 | resolvers += "Sonatype releases" at "http://oss.sonatype.org/content/repositories/releases/"
13 |
14 | resolvers += "Sonatype snapshots" at "http://oss.sonatype.org/content/repositories/snapshots/"
15 | ```
16 |
17 | # Usage
18 |
19 | ```scala
20 | import scala.language.implicitConversions
21 | import scalaz.{CharSet, NonEmptyList}, NonEmptyList.nels
22 | import scalaz.std.list._
23 | import scalaz.syntax.{Ops, monad, traverse}, monad._, traverse._
24 |
25 | import redis.algebra.{F, R}
26 | import redis.algebra.all._
27 |
28 | val e0 =
29 | set[R]("key".utf8, "value".utf8) >>
30 | get[R]("key".utf8)
31 |
32 | val e1 =
33 | set[R]("counter".utf8, 100L.utf8) >>
34 | incr[R]("counter".utf8) >>
35 | incr[R]("counter".utf8) >>
36 | incrby[R]("counter".utf8, 10L)
37 |
38 | val e2 =
39 | List("first".utf8, "second".utf8, "third".utf8).map(a => rpush[R]("messages".utf8, nels(a))).sequenceU >>
40 | lrange[R]("messages".utf8, 0, 2)
41 |
42 | implicit def StringToStringOps(a: String): StringOps = new StringOps { val self = a }
43 |
44 | implicit def LongToStringOps(a: Long): StringOps = new StringOps { val self = a.toString }
45 |
46 | sealed abstract class StringOps extends Ops[String] { final def utf8 = self.getBytes(CharSet.UTF8).toIndexedSeq }
47 | ```
48 |
--------------------------------------------------------------------------------
/build.sbt:
--------------------------------------------------------------------------------
1 | organization := "com.github.ethul"
2 |
3 | name := "redis-algebra"
4 |
5 | version := "0.1.3"
6 |
7 | scalaVersion := "2.11.2"
8 |
9 | crossScalaVersions := Seq("2.10.4", "2.11.2")
10 |
11 | libraryDependencies += "org.scalaz" %% "scalaz-core" % "7.1.0"
12 |
13 | libraryDependencies += "org.specs2" %% "specs2" % "2.4" % "test"
14 |
15 | resolvers += "Sonatype releases" at "https://oss.sonatype.org/content/repositories/releases/"
16 |
17 | scalacOptions <<= scalaVersion map { a =>
18 | if (a.startsWith("2.10.")) {
19 | Seq("-deprecation",
20 | "-feature",
21 | "-language:higherKinds",
22 | "-unchecked",
23 | "-Xlint",
24 | "-Xfatal-warnings",
25 | "-Yno-adapted-args")
26 | }
27 | else {
28 | Seq("-deprecation",
29 | "-encoding", "UTF-8",
30 | "-feature",
31 | "-language:higherKinds",
32 | "-language:implicitConversions",
33 | "-language:postfixOps",
34 | "-unchecked",
35 | "-Xfatal-warnings",
36 | "-Xlint:_",
37 | "-Yno-adapted-args",
38 | "-Ywarn-adapted-args",
39 | "-Ywarn-dead-code",
40 | "-Ywarn-inaccessible",
41 | "-Ywarn-infer-any",
42 | "-Ywarn-nullary-override",
43 | "-Ywarn-nullary-unit",
44 | "-Ywarn-numeric-widen",
45 | "-Ywarn-unused",
46 | "-Ywarn-unused-import",
47 | "-Ywarn-value-discard")
48 | }
49 | }
50 |
51 | publishTo <<= version.apply { v =>
52 | val nexus = "https://oss.sonatype.org/"
53 | if (v.trim.endsWith("SNAPSHOT"))
54 | Some("Snapshots" at nexus + "content/repositories/snapshots")
55 | else
56 | Some("Releases" at nexus + "service/local/staging/deploy/maven2")
57 | }
58 |
59 | credentials += Credentials(Path.userHome / ".ivy2" / ".credentials")
60 |
61 | pomIncludeRepository := Function.const(false)
62 |
63 | pomExtra :=
64 | https://github.com/ethul/redis-algebra
65 |
66 |
67 | MIT
68 | http://www.opensource.org/licenses/mit-license.php
69 | repo
70 |
71 |
72 |
73 | https://github.com/ethul/redis-algebra
74 | scm:git:git@github.com:ethul/redis-algebra.git
75 | scm:git:git@github.com:ethul/redis-algebra.git
76 |
77 |
78 |
79 | ethul
80 | Eric Thul
81 | https://github.com/ethul
82 |
83 |
84 |
--------------------------------------------------------------------------------
/project/build.properties:
--------------------------------------------------------------------------------
1 | sbt.version=0.13.5
2 |
--------------------------------------------------------------------------------
/src/main/scala/redis/algebra/connection.scala:
--------------------------------------------------------------------------------
1 | package redis
2 | package algebra
3 |
4 | import scalaz.{Free, Functor, Inject, InjectFunctions}
5 |
6 | import data.Status
7 |
8 | sealed abstract class ConnectionAlgebra[A]
9 |
10 | final case class Auth[A](password: ByteString, h: Status => A) extends ConnectionAlgebra[A]
11 |
12 | final case class Echo[A](message: ByteString, h: ByteString => A) extends ConnectionAlgebra[A]
13 |
14 | final case class Ping[A](h: Status => A) extends ConnectionAlgebra[A]
15 |
16 | final case class Quit[A](h: Status => A) extends ConnectionAlgebra[A]
17 |
18 | final case class Select[A](index: Short, h: Status => A) extends ConnectionAlgebra[A]
19 |
20 | trait ConnectionInstances {
21 | implicit val connectionAlgebraFunctor: Functor[ConnectionAlgebra] =
22 | new Functor[ConnectionAlgebra] {
23 | def map[A, B](a: ConnectionAlgebra[A])(f: A => B): ConnectionAlgebra[B] =
24 | a match {
25 | case Auth(p, h) => Auth(p, x => f(h(x)))
26 | case Echo(m, h) => Echo(m, x => f(h(x)))
27 | case Ping(h) => Ping(x => f(h(x)))
28 | case Quit(h) => Quit(x => f(h(x)))
29 | case Select(i, h) => Select(i, x => f(h(x)))
30 | }
31 | }
32 | }
33 |
34 | trait ConnectionFunctions extends InjectFunctions {
35 | def auth[F[_]: Functor](password: ByteString)(implicit I: Inject[ConnectionAlgebra, F]): Free[F, Status] =
36 | inject[F, ConnectionAlgebra, Status](Auth(password, Free.point(_)))
37 |
38 | def echo[F[_]: Functor](message: ByteString)(implicit I: Inject[ConnectionAlgebra, F]): Free[F, ByteString] =
39 | inject[F, ConnectionAlgebra, ByteString](Echo(message, Free.point(_)))
40 |
41 | def ping[F[_]: Functor](implicit I: Inject[ConnectionAlgebra, F]): Free[F, Status] =
42 | inject[F, ConnectionAlgebra, Status](Ping(Free.point(_)))
43 |
44 | def quit[F[_]: Functor](implicit I: Inject[ConnectionAlgebra, F]): Free[F, Status] =
45 | inject[F, ConnectionAlgebra, Status](Quit(Free.point(_)))
46 |
47 | def select[F[_]: Functor](index: Short)(implicit I: Inject[ConnectionAlgebra, F]): Free[F, Status] =
48 | inject[F, ConnectionAlgebra, Status](Select(index, Free.point(_)))
49 | }
50 |
--------------------------------------------------------------------------------
/src/main/scala/redis/algebra/data.scala:
--------------------------------------------------------------------------------
1 | package redis
2 | package algebra
3 | package data
4 |
5 | import scalaz.NonEmptyList
6 |
7 | sealed abstract class Status
8 | case object Ok extends Status
9 | case object Error extends Status
10 | case object Wrongtype extends Status
11 |
12 | sealed abstract class Type
13 | case object String extends Type
14 | case object List extends Type
15 | case object Set extends Type
16 | case object ZSet extends Type
17 | case object Hash extends Type
18 |
19 | sealed abstract class ObjectSubcommand
20 | final case class Refcount(key: ByteString) extends ObjectSubcommand
21 | final case class Encoding(key: ByteString) extends ObjectSubcommand
22 | final case class Idletime(key: ByteString) extends ObjectSubcommand
23 |
24 | sealed abstract class ObjectResult
25 | final case class RefcountResult(value: Long) extends ObjectResult
26 | final case class EncodingResult(value: ByteString) extends ObjectResult
27 | final case class IdletimeResult(value: Long) extends ObjectResult
28 |
29 | sealed abstract class LuaResult
30 | final case class LuaNumber(value: Long) extends LuaResult
31 | final case class LuaString(value: ByteString) extends LuaResult
32 | final case class LuaTable(value: Seq[ByteString]) extends LuaResult
33 | final case class LuaStatus(value: Status) extends LuaResult
34 | final case class LuaBoolean(value: Boolean) extends LuaResult
35 |
36 | sealed abstract class Master
37 | final case class Host(name: ByteString, port: Int) extends Master
38 | case object Noone extends Master
39 |
40 | sealed abstract class SlowlogSubcommand
41 | final case class Get(limit: Option[Int] = None) extends SlowlogSubcommand
42 | case object Len extends SlowlogSubcommand
43 | case object Reset extends SlowlogSubcommand
44 |
45 | sealed abstract class SlowlogResult
46 | final case class GetResult(value: Seq[ByteString]) extends SlowlogResult
47 | final case class LenResult(value: Int) extends SlowlogResult
48 | case object ResetResult extends SlowlogResult
49 |
50 | sealed abstract class BitOperation
51 | final case class And(dest: ByteString, keys: NonEmptyList[ByteString]) extends BitOperation
52 | final case class Or(dest: ByteString, keys: NonEmptyList[ByteString]) extends BitOperation
53 | final case class Xor(dest: ByteString, keys: NonEmptyList[ByteString]) extends BitOperation
54 | final case class Not(dest: ByteString, key: ByteString) extends BitOperation
55 |
56 | sealed abstract class SetOption
57 | case object Nx extends SetOption
58 | case object Xx extends SetOption
59 |
60 | sealed abstract class Endpoint
61 | final case class Closed(value: Double) extends Endpoint
62 | final case class Open(value: Double) extends Endpoint
63 | case object -∞ extends Endpoint
64 | case object +∞ extends Endpoint
65 |
66 | sealed abstract class Aggregate
67 | case object Sum extends Aggregate
68 | case object Min extends Aggregate
69 | case object Max extends Aggregate
70 |
71 | sealed abstract class Order
72 | case object Asc extends Order
73 | case object Desc extends Order
74 |
75 | sealed abstract class Position
76 | case object Before extends Position
77 | case object After extends Position
78 |
79 | sealed abstract class By
80 | case object Nosort extends By
81 | final case class Pattern(pattern: ByteString) extends By
82 |
83 | final case class Limit(offset: Long, count: Long)
84 |
--------------------------------------------------------------------------------
/src/main/scala/redis/algebra/hash.scala:
--------------------------------------------------------------------------------
1 | package redis
2 | package algebra
3 |
4 | import scalaz.{Free, Functor, Inject, InjectFunctions, NonEmptyList}
5 |
6 | import data.Status
7 |
8 | sealed abstract class HashAlgebra[A]
9 |
10 | final case class Hdel[A](key: ByteString, fields: NonEmptyList[ByteString], h: Long => A) extends HashAlgebra[A]
11 |
12 | final case class Hexists[A](key: ByteString, field: ByteString, h: Boolean => A) extends HashAlgebra[A]
13 |
14 | final case class Hget[A](key: ByteString, field: ByteString, h: Option[ByteString] => A) extends HashAlgebra[A]
15 |
16 | final case class Hgetall[A](key: ByteString, h: Seq[(ByteString, ByteString)] => A) extends HashAlgebra[A]
17 |
18 | final case class Hincrby[A](key: ByteString, field: ByteString, increment: Long, h: Long => A) extends HashAlgebra[A]
19 |
20 | final case class Hincrbyfloat[A](key: ByteString, field: ByteString, increment: BigDecimal, h: BigDecimal => A) extends HashAlgebra[A]
21 |
22 | final case class Hkeys[A](key: ByteString, h: Seq[ByteString] => A) extends HashAlgebra[A]
23 |
24 | final case class Hlen[A](key: ByteString, h: Long => A) extends HashAlgebra[A]
25 |
26 | final case class Hmget[A](key: ByteString, fields: NonEmptyList[ByteString], h: Seq[Option[ByteString]] => A) extends HashAlgebra[A]
27 |
28 | final case class Hmset[A](key: ByteString, pairs: NonEmptyList[(ByteString, ByteString)], h: Status => A) extends HashAlgebra[A]
29 |
30 | final case class Hset[A](key: ByteString, field: ByteString, value: ByteString, h: Boolean => A) extends HashAlgebra[A]
31 |
32 | final case class Hsetnx[A](key: ByteString, field: ByteString, value: ByteString, h: Boolean => A) extends HashAlgebra[A]
33 |
34 | final case class Hvals[A](key: ByteString, h: Seq[ByteString] => A) extends HashAlgebra[A]
35 |
36 | trait HashInstances {
37 | implicit val hashAlgebraFunctor: Functor[HashAlgebra] =
38 | new Functor[HashAlgebra] {
39 | def map[A, B](a: HashAlgebra[A])(f: A => B): HashAlgebra[B] =
40 | a match {
41 | case Hdel(k, s, h) => Hdel(k, s, x => f(h(x)))
42 | case Hexists(k, s, h) => Hexists(k, s, x => f(h(x)))
43 | case Hget(k, s, h) => Hget(k, s, x => f(h(x)))
44 | case Hgetall(k, h) => Hgetall(k, x => f(h(x)))
45 | case Hincrby(k, s, i, h) => Hincrby(k, s, i, x => f(h(x)))
46 | case Hincrbyfloat(k, s, i, h) => Hincrbyfloat(k, s, i, x => f(h(x)))
47 | case Hkeys(k, h) => Hkeys(k, x => f(h(x)))
48 | case Hlen(k, h) => Hlen(k, x => f(h(x)))
49 | case Hmget(k, s, h) => Hmget(k, s, x => f(h(x)))
50 | case Hmset(k, p, h) => Hmset(k, p, x => f(h(x)))
51 | case Hset(k, s, v, h) => Hset(k, s, v, x => f(h(x)))
52 | case Hsetnx(k, s, v, h) => Hsetnx(k, s, v, x => f(h(x)))
53 | case Hvals(k, h) => Hvals(k, x => f(h(x)))
54 | }
55 | }
56 | }
57 |
58 | trait HashFunctions extends InjectFunctions {
59 | def hdel[F[_]: Functor](key: ByteString, fields: NonEmptyList[ByteString])(implicit I: Inject[HashAlgebra, F]): Free[F, Long] =
60 | inject[F, HashAlgebra, Long](Hdel(key, fields, Free.point(_)))
61 |
62 | def hexists[F[_]: Functor](key: ByteString, field: ByteString)(implicit I: Inject[HashAlgebra, F]): Free[F, Boolean] =
63 | inject[F, HashAlgebra, Boolean](Hexists(key, field, Free.point(_)))
64 |
65 | def hget[F[_]: Functor](key: ByteString, field: ByteString)(implicit I: Inject[HashAlgebra, F]): Free[F, Option[ByteString]] =
66 | inject[F, HashAlgebra, Option[ByteString]](Hget(key, field, Free.point(_)))
67 |
68 | def hgetall[F[_]: Functor](key: ByteString)(implicit I: Inject[HashAlgebra, F]): Free[F, Seq[(ByteString, ByteString)]] =
69 | inject[F, HashAlgebra, Seq[(ByteString, ByteString)]](Hgetall(key, Free.point(_)))
70 |
71 | def hincrby[F[_]: Functor](key: ByteString, field: ByteString, increment: Long)(implicit I: Inject[HashAlgebra, F]): Free[F, Long] =
72 | inject[F, HashAlgebra, Long](Hincrby(key, field, increment, Free.point(_)))
73 |
74 | def hincrbyfloat[F[_]: Functor](key: ByteString, field: ByteString, increment: BigDecimal)(implicit I: Inject[HashAlgebra, F]): Free[F, BigDecimal] =
75 | inject[F, HashAlgebra, BigDecimal](Hincrbyfloat(key, field, increment, Free.point(_)))
76 |
77 | def hkeys[F[_]: Functor](key: ByteString)(implicit I: Inject[HashAlgebra, F]): Free[F, Seq[ByteString]] =
78 | inject[F, HashAlgebra, Seq[ByteString]](Hkeys(key, Free.point(_)))
79 |
80 | def hlen[F[_]: Functor](key: ByteString)(implicit I: Inject[HashAlgebra, F]): Free[F, Long] =
81 | inject[F, HashAlgebra, Long](Hlen(key, Free.point(_)))
82 |
83 | def hmget[F[_]: Functor](key: ByteString, fields: NonEmptyList[ByteString])(implicit I: Inject[HashAlgebra, F]): Free[F, Seq[Option[ByteString]]] =
84 | inject[F, HashAlgebra, Seq[Option[ByteString]]](Hmget(key, fields, Free.point(_)))
85 |
86 | def hmset[F[_]: Functor](key: ByteString, pairs: NonEmptyList[(ByteString, ByteString)])(implicit I: Inject[HashAlgebra, F]): Free[F, Status] =
87 | inject[F, HashAlgebra, Status](Hmset(key, pairs, Free.point(_)))
88 |
89 | def hset[F[_]: Functor](key: ByteString, field: ByteString, value: ByteString)(implicit I: Inject[HashAlgebra, F]): Free[F, Boolean] =
90 | inject[F, HashAlgebra, Boolean](Hset(key, field, value, Free.point(_)))
91 |
92 | def hsetnx[F[_]: Functor](key: ByteString, field: ByteString, value: ByteString)(implicit I: Inject[HashAlgebra, F]): Free[F, Boolean] =
93 | inject[F, HashAlgebra, Boolean](Hsetnx(key, field, value, Free.point(_)))
94 |
95 | def hvals[F[_]: Functor](key: ByteString)(implicit I: Inject[HashAlgebra, F]): Free[F, Seq[ByteString]] =
96 | inject[F, HashAlgebra, Seq[ByteString]](Hvals(key, Free.point(_)))
97 | }
98 |
--------------------------------------------------------------------------------
/src/main/scala/redis/algebra/key.scala:
--------------------------------------------------------------------------------
1 | package redis
2 | package algebra
3 |
4 | import scalaz.{\/, Free, Functor, Inject, InjectFunctions, NonEmptyList}
5 |
6 | import data.{Asc, By, Limit, ObjectSubcommand, ObjectResult, Order, Type => DataType, Status}
7 |
8 | sealed abstract class KeyAlgebra[A]
9 |
10 | final case class Del[A](keys: NonEmptyList[ByteString], h: Long => A) extends KeyAlgebra[A]
11 |
12 | final case class Dump[A](key: ByteString, h: Option[ByteString] => A) extends KeyAlgebra[A]
13 |
14 | final case class Exists[A](key: ByteString, h: Boolean => A) extends KeyAlgebra[A]
15 |
16 | final case class Expire[A](key: ByteString, in: Seconds, h: Boolean => A) extends KeyAlgebra[A]
17 |
18 | final case class Expireat[A](key: ByteString, at: Seconds, h: Boolean => A) extends KeyAlgebra[A]
19 |
20 | final case class Keys[A](pattern: ByteString, h: Seq[ByteString] => A) extends KeyAlgebra[A]
21 |
22 | final case class Migrate[A](host: ByteString, port: Int, key: ByteString, timeout: Milliseconds, destination: Short, copy: Boolean, replace: Boolean, h: Status => A) extends KeyAlgebra[A]
23 |
24 | final case class Move[A](key: ByteString, db: Short, h: Boolean => A) extends KeyAlgebra[A]
25 |
26 | final case class Object[A](subcommand: ObjectSubcommand, h: Option[ObjectResult] => A) extends KeyAlgebra[A]
27 |
28 | final case class Persist[A](key: ByteString, h: Boolean => A) extends KeyAlgebra[A]
29 |
30 | final case class Pexpire[A](key: ByteString, in: Milliseconds, h: Boolean => A) extends KeyAlgebra[A]
31 |
32 | final case class Pexpireat[A](key: ByteString, at: Milliseconds, h: Boolean => A) extends KeyAlgebra[A]
33 |
34 | final case class Pttl[A](key: ByteString, h: Option[Milliseconds] => A) extends KeyAlgebra[A]
35 |
36 | final case class Randomkey[A](h: Option[ByteString] => A) extends KeyAlgebra[A]
37 |
38 | final case class Rename[A](key: ByteString, name: ByteString, h: Status => A) extends KeyAlgebra[A]
39 |
40 | final case class Renamenx[A](key: ByteString, name: ByteString, h: Boolean => A) extends KeyAlgebra[A]
41 |
42 | final case class Restore[A](key: ByteString, ttl: Option[Milliseconds], value: ByteString, h: Status => A) extends KeyAlgebra[A]
43 |
44 | final case class Sort[A](key: ByteString, by: Option[By], limit: Option[Limit], get: Seq[ByteString], order: Order, alpha: Boolean, store: Option[ByteString], h: Seq[ByteString] \/ Long => A) extends KeyAlgebra[A]
45 |
46 | final case class Ttl[A](key: ByteString, h: Option[Seconds] => A) extends KeyAlgebra[A]
47 |
48 | final case class Type[A](key: ByteString, h: Option[DataType] => A) extends KeyAlgebra[A]
49 |
50 | trait KeyInstances {
51 | implicit val keyAlgebraFunctor: Functor[KeyAlgebra] =
52 | new Functor[KeyAlgebra] {
53 | def map[A, B](a: KeyAlgebra[A])(f: A => B): KeyAlgebra[B] =
54 | a match {
55 | case Del(k, h) => Del(k, x => f(h(x)))
56 | case Dump(k, h) => Dump(k, x => f(h(x)))
57 | case Exists(k, h) => Exists(k, x => f(h(x)))
58 | case Expire(k, i, h) => Expire(k, i, x => f(h(x)))
59 | case Expireat(k, t, h) => Expireat(k, t, x => f(h(x)))
60 | case Keys(k, h) => Keys(k, x => f(h(x)))
61 | case Migrate(o, p, k, t, d, c, r, h) => Migrate(o, p, k, t, d, c, r, x => f(h(x)))
62 | case Move(k, d, h) => Move(k, d, x => f(h(x)))
63 | case Object(s, h) => Object(s, x => f(h(x)))
64 | case Persist(k, h) => Persist(k, x => f(h(x)))
65 | case Pexpire(k, i, h) => Pexpire(k, i, x => f(h(x)))
66 | case Pexpireat(k, t, h) => Pexpireat(k, t, x => f(h(x)))
67 | case Pttl(k, h) => Pttl(k, x => f(h(x)))
68 | case Randomkey(h) => Randomkey(x => f(h(x)))
69 | case Rename(k, n, h) => Rename(k, n, x => f(h(x)))
70 | case Renamenx(k, n, h) => Renamenx(k, n, x => f(h(x)))
71 | case Restore(k, t, v, h) => Restore(k, t, v, x => f(h(x)))
72 | case Sort(k, b, l, g, o, a, s, h) => Sort(k, b, l, g, o, a, s, x => f(h(x)))
73 | case Ttl(k, h) => Ttl(k, x => f(h(x)))
74 | case Type(k, h) => Type(k, x => f(h(x)))
75 | }
76 | }
77 | }
78 |
79 | trait KeyFunctions extends InjectFunctions {
80 | def del[F[_]: Functor](keys: NonEmptyList[ByteString])(implicit I: Inject[KeyAlgebra, F]): Free[F, Long] =
81 | inject[F, KeyAlgebra, Long](Del(keys, Free.point(_)))
82 |
83 | def dump[F[_]: Functor](key: ByteString)(implicit I: Inject[KeyAlgebra, F]): Free[F, Option[ByteString]] =
84 | inject[F, KeyAlgebra, Option[ByteString]](Dump(key, Free.point(_)))
85 |
86 | def exists[F[_]: Functor](key: ByteString)(implicit I: Inject[KeyAlgebra, F]): Free[F, Boolean] =
87 | inject[F, KeyAlgebra, Boolean](Exists(key, Free.point(_)))
88 |
89 | def expire[F[_]: Functor](key: ByteString, in: Seconds)(implicit I: Inject[KeyAlgebra, F]): Free[F, Boolean] =
90 | inject[F, KeyAlgebra, Boolean](Expire(key, in, Free.point(_)))
91 |
92 | def expireat[F[_]: Functor](key: ByteString, at: Seconds)(implicit I: Inject[KeyAlgebra, F]): Free[F, Boolean] =
93 | inject[F, KeyAlgebra, Boolean](Expireat(key, at, Free.point(_)))
94 |
95 | def keys[F[_]: Functor](pattern: ByteString)(implicit I: Inject[KeyAlgebra, F]): Free[F, Seq[ByteString]] =
96 | inject[F, KeyAlgebra, Seq[ByteString]](Keys(pattern, Free.point(_)))
97 |
98 | def migrate[F[_]: Functor](
99 | host: ByteString,
100 | port: Int,
101 | key: ByteString,
102 | timeout: Milliseconds,
103 | destination: Short,
104 | copy: Boolean = false,
105 | replace: Boolean = false)(implicit I: Inject[KeyAlgebra, F]): Free[F, Status] =
106 | inject[F, KeyAlgebra, Status](Migrate(host, port, key, timeout, destination, copy, replace, Free.point(_)))
107 |
108 | def move[F[_]: Functor](key: ByteString, db: Short)(implicit I: Inject[KeyAlgebra, F]): Free[F, Boolean] =
109 | inject[F, KeyAlgebra, Boolean](Move(key, db, Free.point(_)))
110 |
111 | def `object`[F[_]: Functor](subcommand: ObjectSubcommand)(implicit I: Inject[KeyAlgebra, F]): Free[F, Option[ObjectResult]] =
112 | inject[F, KeyAlgebra, Option[ObjectResult]](Object(subcommand, Free.point(_)))
113 |
114 | def persist[F[_]: Functor](key: ByteString)(implicit I: Inject[KeyAlgebra, F]): Free[F, Boolean] =
115 | inject[F, KeyAlgebra, Boolean](Persist(key, Free.point(_)))
116 |
117 | def pexpire[F[_]: Functor](key: ByteString, in: Milliseconds)(implicit I: Inject[KeyAlgebra, F]): Free[F, Boolean] =
118 | inject[F, KeyAlgebra, Boolean](Pexpire(key, in, Free.point(_)))
119 |
120 | def pexpireat[F[_]: Functor](key: ByteString, at: Milliseconds)(implicit I: Inject[KeyAlgebra, F]): Free[F, Boolean] =
121 | inject[F, KeyAlgebra, Boolean](Pexpireat(key, at, Free.point(_)))
122 |
123 | def pttl[F[_]: Functor](key: ByteString)(implicit I: Inject[KeyAlgebra, F]): Free[F, Option[Milliseconds]] =
124 | inject[F, KeyAlgebra, Option[Milliseconds]](Pttl(key, Free.point(_)))
125 |
126 | def randomkey[F[_]: Functor](implicit I: Inject[KeyAlgebra, F]): Free[F, Option[ByteString]] =
127 | inject[F, KeyAlgebra, Option[ByteString]](Randomkey(Free.point(_)))
128 |
129 | def rename[F[_]: Functor](key: ByteString, name: ByteString)(implicit I: Inject[KeyAlgebra, F]): Free[F, Status] =
130 | inject[F, KeyAlgebra, Status](Rename(key, name, Free.point(_)))
131 |
132 | def renamenx[F[_]: Functor](key: ByteString, name: ByteString)(implicit I: Inject[KeyAlgebra, F]): Free[F, Boolean] =
133 | inject[F, KeyAlgebra, Boolean](Renamenx(key, name, Free.point(_)))
134 |
135 | def restore[F[_]: Functor](key: ByteString, value: ByteString, ttl: Option[Milliseconds] = None)(implicit I: Inject[KeyAlgebra, F]): Free[F, Status] =
136 | inject[F, KeyAlgebra, Status](Restore(key, ttl, value, Free.point(_)))
137 |
138 | def sort[F[_]: Functor](
139 | key: ByteString,
140 | by: Option[By] = None,
141 | limit: Option[Limit] = None,
142 | get: Seq[ByteString] = Nil,
143 | order: Order = Asc,
144 | alpha: Boolean = false,
145 | store: Option[ByteString] = None)(implicit I: Inject[KeyAlgebra, F]): Free[F, Seq[ByteString] \/ Long] =
146 | inject[F, KeyAlgebra, Seq[ByteString] \/ Long](Sort(key, by, limit, get, order, alpha, store, Free.point(_)))
147 |
148 | def ttl[F[_]: Functor](key: ByteString)(implicit I: Inject[KeyAlgebra, F]): Free[F, Option[Seconds]] =
149 | inject[F, KeyAlgebra, Option[Seconds]](Ttl(key, Free.point(_)))
150 |
151 | def `type`[F[_]: Functor](key: ByteString)(implicit I: Inject[KeyAlgebra, F]): Free[F, Option[DataType]] =
152 | inject[F, KeyAlgebra, Option[DataType]](Type(key, Free.point(_)))
153 | }
154 |
--------------------------------------------------------------------------------
/src/main/scala/redis/algebra/list.scala:
--------------------------------------------------------------------------------
1 | package redis
2 | package algebra
3 |
4 | import scalaz.{Free, Functor, Inject, InjectFunctions, NonEmptyList}
5 |
6 | import data.{Asc, Position, Status}
7 |
8 | sealed abstract class ListAlgebra[A]
9 |
10 | final case class Blpop[A](keys: NonEmptyList[ByteString], timeout: Seconds, h: Option[(ByteString, ByteString)] => A) extends ListAlgebra[A]
11 |
12 | final case class Brpop[A](keys: NonEmptyList[ByteString], timeout: Seconds, h: Option[(ByteString, ByteString)] => A) extends ListAlgebra[A]
13 |
14 | final case class Brpoplpush[A](source: ByteString, destination: ByteString, timeout: Seconds, h: Option[ByteString] => A) extends ListAlgebra[A]
15 |
16 | final case class Lindex[A](key: ByteString, index: Long, h: Option[ByteString] => A) extends ListAlgebra[A]
17 |
18 | final case class Linsert[A](key: ByteString, position: Position, pivot: ByteString, value: ByteString, h: Option[Long] => A) extends ListAlgebra[A]
19 |
20 | final case class Llen[A](key: ByteString, h: Long => A) extends ListAlgebra[A]
21 |
22 | final case class Lpop[A](key: ByteString, h: Option[ByteString] => A) extends ListAlgebra[A]
23 |
24 | final case class Lpush[A](key: ByteString, values: NonEmptyList[ByteString], h: Long => A) extends ListAlgebra[A]
25 |
26 | final case class Lpushx[A](key: ByteString, value: ByteString, h: Long => A) extends ListAlgebra[A]
27 |
28 | final case class Lrange[A](key: ByteString, start: Long, stop: Long, h: Seq[ByteString] => A) extends ListAlgebra[A]
29 |
30 | final case class Lrem[A](key: ByteString, count: Long, value: ByteString, h: Long => A) extends ListAlgebra[A]
31 |
32 | final case class Lset[A](key: ByteString, index: Long, value: ByteString, h: Status => A) extends ListAlgebra[A]
33 |
34 | final case class Ltrim[A](key: ByteString, start: Long, stop: Long, a: Status => A) extends ListAlgebra[A]
35 |
36 | final case class Rpop[A](key: ByteString, h: Option[ByteString] => A) extends ListAlgebra[A]
37 |
38 | final case class Rpoplpush[A](source: ByteString, destination: ByteString, h: Option[ByteString] => A) extends ListAlgebra[A]
39 |
40 | final case class Rpush[A](key: ByteString, values: NonEmptyList[ByteString], h: Long => A) extends ListAlgebra[A]
41 |
42 | final case class Rpushx[A](key: ByteString, value: ByteString, h: Long => A) extends ListAlgebra[A]
43 |
44 | trait ListInstances {
45 | implicit val listAlgebraFunctor: Functor[ListAlgebra] =
46 | new Functor[ListAlgebra] {
47 | def map[A, B](a: ListAlgebra[A])(f: A => B): ListAlgebra[B] =
48 | a match {
49 | case Blpop(k, t, h) => Blpop(k, t, x => f(h(x)))
50 | case Brpop(k, t, h) => Brpop(k, t, x => f(h(x)))
51 | case Brpoplpush(s, d, t, h) => Brpoplpush(s, d, t, x => f(h(x)))
52 | case Lindex(k, i, h) => Lindex(k, i, x => f(h(x)))
53 | case Linsert(k, p, i, v, h) => Linsert(k, p, i, v, x => f(h(x)))
54 | case Llen(k, h) => Llen(k, x => f(h(x)))
55 | case Lpop(k, h) => Lpop(k, x => f(h(x)))
56 | case Lpush(k, v, h) => Lpush(k, v, x => f(h(x)))
57 | case Lpushx(k, v, h) => Lpushx(k, v, x => f(h(x)))
58 | case Lrange(k, s, t, h) => Lrange(k, s, t, x => f(h(x)))
59 | case Lrem(k, c, v, h) => Lrem(k, c, v, x => f(h(x)))
60 | case Lset(k, i, v, h) => Lset(k, i, v, x => f(h(x)))
61 | case Ltrim(k, s, t, h) => Ltrim(k, s, t, x => f(h(x)))
62 | case Rpop(k, h) => Rpop(k, x => f(h(x)))
63 | case Rpoplpush(s, d, h) => Rpoplpush(s, d, x => f(h(x)))
64 | case Rpush(k, v, h) => Rpush(k, v, x => f(h(x)))
65 | case Rpushx(k, v, h) => Rpushx(k, v, x => f(h(x)))
66 | }
67 | }
68 | }
69 |
70 | trait ListFunctions extends InjectFunctions {
71 | def blpop[F[_]: Functor](keys: NonEmptyList[ByteString], timeout: Seconds)(implicit I: Inject[ListAlgebra, F]): Free[F, Option[(ByteString, ByteString)]] =
72 | inject[F, ListAlgebra, Option[(ByteString, ByteString)]](Blpop(keys, timeout, Free.point(_)))
73 |
74 | def brpop[F[_]: Functor](keys: NonEmptyList[ByteString], timeout: Seconds)(implicit I: Inject[ListAlgebra, F]): Free[F, Option[(ByteString, ByteString)]] =
75 | inject[F, ListAlgebra, Option[(ByteString, ByteString)]](Brpop(keys, timeout, Free.point(_)))
76 |
77 | def brpoplpush[F[_]: Functor](source: ByteString, destination: ByteString, timeout: Seconds)(implicit I: Inject[ListAlgebra, F]): Free[F, Option[ByteString]] =
78 | inject[F, ListAlgebra, Option[ByteString]](Brpoplpush(source, destination, timeout, Free.point(_)))
79 |
80 | def lindex[F[_]: Functor](key: ByteString, index: Long)(implicit I: Inject[ListAlgebra, F]): Free[F, Option[ByteString]] =
81 | inject[F, ListAlgebra, Option[ByteString]](Lindex(key, index, Free.point(_)))
82 |
83 | def linsert[F[_]: Functor](key: ByteString, position: Position, pivot: ByteString, value: ByteString)(implicit I: Inject[ListAlgebra, F]): Free[F, Option[Long]] =
84 | inject[F, ListAlgebra, Option[Long]](Linsert(key, position, pivot, value, Free.point(_)))
85 |
86 | def llen[F[_]: Functor](key: ByteString)(implicit I: Inject[ListAlgebra, F]): Free[F, Long] =
87 | inject[F, ListAlgebra, Long](Llen(key, Free.point(_)))
88 |
89 | def lpop[F[_]: Functor](key: ByteString)(implicit I: Inject[ListAlgebra, F]): Free[F, Option[ByteString]] =
90 | inject[F, ListAlgebra, Option[ByteString]](Lpop(key, Free.point(_)))
91 |
92 | def lpush[F[_]: Functor](key: ByteString, values: NonEmptyList[ByteString])(implicit I: Inject[ListAlgebra, F]): Free[F, Long] =
93 | inject[F, ListAlgebra, Long](Lpush(key, values, Free.point(_)))
94 |
95 | def lpushx[F[_]: Functor](key: ByteString, value: ByteString)(implicit I: Inject[ListAlgebra, F]): Free[F, Long] =
96 | inject[F, ListAlgebra, Long](Lpushx(key, value, Free.point(_)))
97 |
98 | def lrange[F[_]: Functor](key: ByteString, start: Long, stop: Long)(implicit I: Inject[ListAlgebra, F]): Free[F, Seq[ByteString]] =
99 | inject[F, ListAlgebra, Seq[ByteString]](Lrange(key, start, stop, Free.point(_)))
100 |
101 | def lrem[F[_]: Functor](key: ByteString, count: Long, value: ByteString)(implicit I: Inject[ListAlgebra, F]): Free[F, Long] =
102 | inject[F, ListAlgebra, Long](Lrem(key, count, value, Free.point(_)))
103 |
104 | def lset[F[_]: Functor](key: ByteString, index: Long, value: ByteString)(implicit I: Inject[ListAlgebra, F]): Free[F, Status] =
105 | inject[F, ListAlgebra, Status](Lset(key, index, value, Free.point(_)))
106 |
107 | def ltrim[F[_]: Functor](key: ByteString, start: Long, stop: Long)(implicit I: Inject[ListAlgebra, F]): Free[F, Status] =
108 | inject[F, ListAlgebra, Status](Ltrim(key, start, stop, Free.point(_)))
109 |
110 | def rpop[F[_]: Functor](key: ByteString)(implicit I: Inject[ListAlgebra, F]): Free[F, Option[ByteString]] =
111 | inject[F, ListAlgebra, Option[ByteString]](Rpop(key, Free.point(_)))
112 |
113 | def rpoplpush[F[_]: Functor](source: ByteString, destination: ByteString)(implicit I: Inject[ListAlgebra, F]): Free[F, Option[ByteString]] =
114 | inject[F, ListAlgebra, Option[ByteString]](Rpoplpush(source, destination, Free.point(_)))
115 |
116 | def rpush[F[_]: Functor](key: ByteString, values: NonEmptyList[ByteString])(implicit I: Inject[ListAlgebra, F]): Free[F, Long] =
117 | inject[F, ListAlgebra, Long](Rpush(key, values, Free.point(_)))
118 |
119 | def rpushx[F[_]: Functor](key: ByteString, value: ByteString)(implicit I: Inject[ListAlgebra, F]): Free[F, Long] =
120 | inject[F, ListAlgebra, Long](Rpushx(key, value, Free.point(_)))
121 | }
122 |
--------------------------------------------------------------------------------
/src/main/scala/redis/algebra/package.scala:
--------------------------------------------------------------------------------
1 | package redis
2 |
3 | import scala.collection.immutable.Seq
4 |
5 | import scalaz.{Coproduct, Free}
6 |
7 | package object algebra {
8 | type Seconds = Long
9 |
10 | type Milliseconds = Long
11 |
12 | type Microseconds = Int
13 |
14 | type ByteString = Seq[Byte]
15 |
16 | type C0[A] = Coproduct[ConnectionAlgebra, HashAlgebra, A]
17 |
18 | type C1[A] = Coproduct[KeyAlgebra, C0, A]
19 |
20 | type C2[A] = Coproduct[ListAlgebra, C1, A]
21 |
22 | type C3[A] = Coproduct[ScriptAlgebra, C2, A]
23 |
24 | type C4[A] = Coproduct[ServerAlgebra, C3, A]
25 |
26 | type C5[A] = Coproduct[SetAlgebra, C4, A]
27 |
28 | type C6[A] = Coproduct[StringAlgebra, C5, A]
29 |
30 | type C7[A] = Coproduct[ZSetAlgebra, C6, A]
31 |
32 | type RedisAlgebra[A] = C7[A]
33 |
34 | type RedisAlgebraFree[A] = Free[RedisAlgebra, A]
35 |
36 | type R[A] = RedisAlgebra[A]
37 |
38 | type F[A] = RedisAlgebraFree[A]
39 |
40 | object connection extends ConnectionInstances with ConnectionFunctions
41 |
42 | object hash extends HashInstances with HashFunctions
43 |
44 | object key extends KeyInstances with KeyFunctions
45 |
46 | object list extends ListInstances with ListFunctions
47 |
48 | object script extends ScriptInstances with ScriptFunctions
49 |
50 | object server extends ServerInstances with ServerFunctions
51 |
52 | object set extends SetInstances with SetFunctions
53 |
54 | object string extends StringInstances with StringFunctions
55 |
56 | object zset extends ZSetInstances with ZSetFunctions
57 |
58 | object all
59 | extends ConnectionInstances
60 | with ConnectionFunctions
61 | with HashInstances
62 | with HashFunctions
63 | with KeyInstances
64 | with KeyFunctions
65 | with ListInstances
66 | with ListFunctions
67 | with ScriptInstances
68 | with ScriptFunctions
69 | with ServerInstances
70 | with ServerFunctions
71 | with SetInstances
72 | with SetFunctions
73 | with StringInstances
74 | with StringFunctions
75 | with ZSetInstances
76 | with ZSetFunctions
77 | }
78 |
--------------------------------------------------------------------------------
/src/main/scala/redis/algebra/script.scala:
--------------------------------------------------------------------------------
1 | package redis
2 | package algebra
3 |
4 | import scalaz.{\/, Free, Functor, Inject, InjectFunctions, NonEmptyList}
5 |
6 | import data.{LuaResult, Status}
7 |
8 | sealed abstract class ScriptAlgebra[A]
9 |
10 | final case class Eval[A](script: ByteString, keys: Seq[ByteString], args: Seq[ByteString], h: LuaResult => A) extends ScriptAlgebra[A]
11 |
12 | final case class Evalsha[A](sha1: ByteString, keys: Seq[ByteString], args: Seq[ByteString], h: LuaResult => A) extends ScriptAlgebra[A]
13 |
14 | final case class Scriptexists[A](scripts: NonEmptyList[ByteString], h: NonEmptyList[Boolean] => A) extends ScriptAlgebra[A]
15 |
16 | final case class Scriptflush[A](h: Status => A) extends ScriptAlgebra[A]
17 |
18 | final case class Scriptkill[A](h: Status => A) extends ScriptAlgebra[A]
19 |
20 | final case class Scriptload[A](script: ByteString, h: Option[ByteString] => A) extends ScriptAlgebra[A]
21 |
22 | trait ScriptInstances {
23 | implicit val scriptAlgebraFunctor: Functor[ScriptAlgebra] =
24 | new Functor[ScriptAlgebra] {
25 | def map[A, B](a: ScriptAlgebra[A])(f: A => B): ScriptAlgebra[B] =
26 | a match {
27 | case Eval(s, k, a, h) => Eval(s, k, a, x => f(h(x)))
28 | case Evalsha(s, k, a, h) => Evalsha(s, k, a, x => f(h(x)))
29 | case Scriptexists(s, h) => Scriptexists(s, x => f(h(x)))
30 | case Scriptflush(h) => Scriptflush(x => f(h(x)))
31 | case Scriptkill(h) => Scriptkill(x => f(h(x)))
32 | case Scriptload(s, h) => Scriptload(s, x => f(h(x)))
33 | }
34 | }
35 | }
36 |
37 | trait ScriptFunctions extends InjectFunctions {
38 | def eval[F[_]: Functor](
39 | script: ByteString,
40 | keys: Seq[ByteString] = Nil,
41 | args: Seq[ByteString] = Nil)(implicit I: Inject[ScriptAlgebra, F]): Free[F, LuaResult] =
42 | inject[F, ScriptAlgebra, LuaResult](Eval(script, keys, args, Free.point(_)))
43 |
44 | def evalsha[F[_]: Functor](
45 | sha1: ByteString,
46 | keys: Seq[ByteString] = Nil,
47 | args: Seq[ByteString] = Nil)(implicit I: Inject[ScriptAlgebra, F]): Free[F, LuaResult] =
48 | inject[F, ScriptAlgebra, LuaResult](Evalsha(sha1, keys, args, Free.point(_)))
49 |
50 | def scriptexists[F[_]: Functor](scripts: NonEmptyList[ByteString])(implicit I: Inject[ScriptAlgebra, F]): Free[F, NonEmptyList[Boolean]] =
51 | inject[F, ScriptAlgebra, NonEmptyList[Boolean]](Scriptexists(scripts, Free.point(_)))
52 |
53 | def scriptflush[F[_]: Functor](implicit I: Inject[ScriptAlgebra, F]): Free[F, Status] =
54 | inject[F, ScriptAlgebra, Status](Scriptflush(Free.point(_)))
55 |
56 | def scriptkill[F[_]: Functor](implicit I: Inject[ScriptAlgebra, F]): Free[F, Status] =
57 | inject[F, ScriptAlgebra, Status](Scriptkill(Free.point(_)))
58 |
59 | def scriptload[F[_]: Functor](script: ByteString)(implicit I: Inject[ScriptAlgebra, F]): Free[F, Option[ByteString]] =
60 | inject[F, ScriptAlgebra, Option[ByteString]](Scriptload(script, Free.point(_)))
61 | }
62 |
--------------------------------------------------------------------------------
/src/main/scala/redis/algebra/server.scala:
--------------------------------------------------------------------------------
1 | package redis
2 | package algebra
3 |
4 | import scalaz.{Free, Functor, Inject, InjectFunctions}
5 |
6 | import data.{Master, SlowlogResult, SlowlogSubcommand, Status}
7 |
8 | sealed abstract class ServerAlgebra[A]
9 |
10 | final case class Bgrewriteaof[A](h: Status => A) extends ServerAlgebra[A]
11 |
12 | final case class Bgsave[A](h: Status => A) extends ServerAlgebra[A]
13 |
14 | final case class Clientgetname[A](h: Option[ByteString] => A) extends ServerAlgebra[A]
15 |
16 | final case class Clientkill[A](ip: ByteString, port: Int, h: Status => A) extends ServerAlgebra[A]
17 |
18 | final case class Clientlist[A](h: Seq[ByteString] => A) extends ServerAlgebra[A]
19 |
20 | final case class Clientsetname[A](name: ByteString, h: Status => A) extends ServerAlgebra[A]
21 |
22 | final case class Configget[A](parameter: ByteString, h: Seq[ByteString] => A) extends ServerAlgebra[A]
23 |
24 | final case class Configresetstat[A](h: Status => A) extends ServerAlgebra[A]
25 |
26 | final case class Configrewrite[A](h: Status => A) extends ServerAlgebra[A]
27 |
28 | final case class Configset[A](parameter: ByteString, value: ByteString, h: Status => A) extends ServerAlgebra[A]
29 |
30 | final case class Dbsize[A](h: Short => A) extends ServerAlgebra[A]
31 |
32 | final case class Debugobject[A](key: ByteString, h: Status => A) extends ServerAlgebra[A]
33 |
34 | final case class Debugsegfault[A](h: Status => A) extends ServerAlgebra[A]
35 |
36 | final case class Flushall[A](h: Status => A) extends ServerAlgebra[A]
37 |
38 | final case class Flushdb[A](h: Status => A) extends ServerAlgebra[A]
39 |
40 | final case class Info[A](section: Option[ByteString], h: ByteString => A) extends ServerAlgebra[A]
41 |
42 | final case class Lastsave[A](h: Seconds => A) extends ServerAlgebra[A]
43 |
44 | final case class Monitor[A](h: Stream[ByteString] => A) extends ServerAlgebra[A]
45 |
46 | final case class Save[A](h: Status => A) extends ServerAlgebra[A]
47 |
48 | final case class Shutdown[A](save: Option[Boolean], h: Status => A) extends ServerAlgebra[A]
49 |
50 | final case class Slaveof[A](master: Master, h: Status => A) extends ServerAlgebra[A]
51 |
52 | final case class Slowlog[A](subcommand: SlowlogSubcommand, h: SlowlogResult => A) extends ServerAlgebra[A]
53 |
54 | final case class Sync[A](a: A) extends ServerAlgebra[A]
55 |
56 | final case class Time[A](h: ((Seconds, Microseconds)) => A) extends ServerAlgebra[A]
57 |
58 | trait ServerInstances {
59 | implicit val serverAlgebraFunctor: Functor[ServerAlgebra] =
60 | new Functor[ServerAlgebra] {
61 | def map[A, B](a: ServerAlgebra[A])(f: A => B): ServerAlgebra[B] =
62 | a match {
63 | case Bgrewriteaof(h) => Bgrewriteaof(x => f(h(x)))
64 | case Bgsave(h) => Bgsave(x => f(h(x)))
65 | case Clientgetname(h) => Clientgetname(x => f(h(x)))
66 | case Clientkill(i, p, h) => Clientkill(i, p, x => f(h(x)))
67 | case Clientlist(h) => Clientlist(x => f(h(x)))
68 | case Clientsetname(n, h) => Clientsetname(n, x => f(h(x)))
69 | case Configget(p, h) => Configget(p, x => f(h(x)))
70 | case Configresetstat(h) => Configresetstat(x => f(h(x)))
71 | case Configrewrite(h) => Configrewrite(x => f(h(x)))
72 | case Configset(p, v, h) => Configset(p, v, x => f(h(x)))
73 | case Dbsize(h) => Dbsize(x => f(h(x)))
74 | case Debugobject(k, h) => Debugobject(k, x => f(h(x)))
75 | case Debugsegfault(h) => Debugsegfault(x => f(h(x)))
76 | case Flushall(h) => Flushall(x => f(h(x)))
77 | case Flushdb(h) => Flushdb(x => f(h(x)))
78 | case Info(s, h) => Info(s, x => f(h(x)))
79 | case Lastsave(h) => Lastsave(x => f(h(x)))
80 | case Monitor(h) => Monitor(x => f(h(x)))
81 | case Save(h) => Save(x => f(h(x)))
82 | case Shutdown(s, h) => Shutdown(s, x => f(h(x)))
83 | case Slaveof(m, h) => Slaveof(m, x => f(h(x)))
84 | case Slowlog(s, h) => Slowlog(s, x => f(h(x)))
85 | case Sync(a) => Sync(f(a))
86 | case Time(h) => Time(x => f(h(x)))
87 | }
88 | }
89 | }
90 |
91 | trait ServerFunctions extends InjectFunctions {
92 | def bgrewriteaof[F[_]: Functor](implicit I: Inject[ServerAlgebra, F]): Free[F, Status] =
93 | inject[F, ServerAlgebra, Status](Bgrewriteaof(Free.point(_)))
94 |
95 | def bgsave[F[_]: Functor](implicit I: Inject[ServerAlgebra, F]): Free[F, Status] =
96 | inject[F, ServerAlgebra, Status](Bgsave(Free.point(_)))
97 |
98 | def clientgetname[F[_]: Functor](implicit I: Inject[ServerAlgebra, F]): Free[F, Option[ByteString]] =
99 | inject[F, ServerAlgebra, Option[ByteString]](Clientgetname(Free.point(_)))
100 |
101 | def clientkill[F[_]: Functor](ip: ByteString, port: Int)(implicit I: Inject[ServerAlgebra, F]): Free[F, Status] =
102 | inject[F, ServerAlgebra, Status](Clientkill(ip, port, Free.point(_)))
103 |
104 | def clientlist[F[_]: Functor](implicit I: Inject[ServerAlgebra, F]): Free[F, Seq[ByteString]] =
105 | inject[F, ServerAlgebra, Seq[ByteString]](Clientlist(Free.point(_)))
106 |
107 | def clientsetname[F[_]: Functor](name: ByteString)(implicit I: Inject[ServerAlgebra, F]): Free[F, Status] =
108 | inject[F, ServerAlgebra, Status](Clientsetname(name, Free.point(_)))
109 |
110 | def configget[F[_]: Functor](parameter: ByteString)(implicit I: Inject[ServerAlgebra, F]): Free[F, Seq[ByteString]] =
111 | inject[F, ServerAlgebra, Seq[ByteString]](Configget(parameter, Free.point(_)))
112 |
113 | def configresetstat[F[_]: Functor](implicit I: Inject[ServerAlgebra, F]): Free[F, Status] =
114 | inject[F, ServerAlgebra, Status](Configresetstat(Free.point(_)))
115 |
116 | def configrewrite[F[_]: Functor](implicit I: Inject[ServerAlgebra, F]): Free[F, Status] =
117 | inject[F, ServerAlgebra, Status](Configrewrite(Free.point(_)))
118 |
119 | def configset[F[_]: Functor](parameter: ByteString, value: ByteString)(implicit I: Inject[ServerAlgebra, F]): Free[F, Status] =
120 | inject[F, ServerAlgebra, Status](Configset(parameter, value, Free.point(_)))
121 |
122 | def dbsize[F[_]: Functor](implicit I: Inject[ServerAlgebra, F]): Free[F, Short] =
123 | inject[F, ServerAlgebra, Short](Dbsize(Free.point(_)))
124 |
125 | def debugobject[F[_]: Functor](key: ByteString)(implicit I: Inject[ServerAlgebra, F]): Free[F, Status] =
126 | inject[F, ServerAlgebra, Status](Debugobject(key, Free.point(_)))
127 |
128 | def debugsegfault[F[_]: Functor](implicit I: Inject[ServerAlgebra, F]): Free[F, Status] =
129 | inject[F, ServerAlgebra, Status](Debugsegfault(Free.point(_)))
130 |
131 | def flushall[F[_]: Functor](implicit I: Inject[ServerAlgebra, F]): Free[F, Status] =
132 | inject[F, ServerAlgebra, Status](Flushall(Free.point(_)))
133 |
134 | def flushdb[F[_]: Functor](implicit I: Inject[ServerAlgebra, F]): Free[F, Status] =
135 | inject[F, ServerAlgebra, Status](Flushdb(Free.point(_)))
136 |
137 | def info[F[_]: Functor](section: Option[ByteString] = None)(implicit I: Inject[ServerAlgebra, F]): Free[F, ByteString] =
138 | inject[F, ServerAlgebra, ByteString](Info(section, Free.point(_)))
139 |
140 | def lastsave[F[_]: Functor](implicit I: Inject[ServerAlgebra, F]): Free[F, Seconds] =
141 | inject[F, ServerAlgebra, Seconds](Lastsave(Free.point(_)))
142 |
143 | def monitor[F[_]: Functor](implicit I: Inject[ServerAlgebra, F]): Free[F, Stream[ByteString]] =
144 | inject[F, ServerAlgebra, Stream[ByteString]](Monitor(Free.point(_)))
145 |
146 | def save[F[_]: Functor](implicit I: Inject[ServerAlgebra, F]): Free[F, Status] =
147 | inject[F, ServerAlgebra, Status](Save(Free.point(_)))
148 |
149 | def shutdown[F[_]: Functor](save: Option[Boolean] = None)(implicit I: Inject[ServerAlgebra, F]): Free[F, Status] =
150 | inject[F, ServerAlgebra, Status](Shutdown(save, Free.point(_)))
151 |
152 | def slaveof[F[_]: Functor](master: Master)(implicit I: Inject[ServerAlgebra, F]): Free[F, Status] =
153 | inject[F, ServerAlgebra, Status](Slaveof(master, Free.point(_)))
154 |
155 | def slowlog[F[_]: Functor](subcommand: SlowlogSubcommand)(implicit I: Inject[ServerAlgebra, F]): Free[F, SlowlogResult] =
156 | inject[F, ServerAlgebra, SlowlogResult](Slowlog(subcommand, Free.point(_)))
157 |
158 | def sync[F[_]: Functor](implicit I: Inject[ServerAlgebra, F]): Free[F, Unit] =
159 | inject[F, ServerAlgebra, Unit](Sync(Free.point(())))
160 |
161 | def time[F[_]: Functor](implicit I: Inject[ServerAlgebra, F]): Free[F, (Seconds, Microseconds)] =
162 | inject[F, ServerAlgebra, (Seconds, Microseconds)](Time(Free.point(_)))
163 | }
164 |
--------------------------------------------------------------------------------
/src/main/scala/redis/algebra/set.scala:
--------------------------------------------------------------------------------
1 | package redis
2 | package algebra
3 |
4 | import scala.collection.immutable.{Set => ScalaSet}
5 |
6 | import scalaz.{Free, Functor, Inject, InjectFunctions, NonEmptyList}
7 |
8 | sealed abstract class SetAlgebra[A]
9 |
10 | final case class Sadd[A](key: ByteString, members: NonEmptyList[ByteString], h: Long => A) extends SetAlgebra[A]
11 |
12 | final case class Scard[A](key: ByteString, h: Long => A) extends SetAlgebra[A]
13 |
14 | final case class Sdiff[A](keys: NonEmptyList[ByteString], h: ScalaSet[ByteString] => A) extends SetAlgebra[A]
15 |
16 | final case class Sdiffstore[A](destination: ByteString, keys: NonEmptyList[ByteString], h: Long => A) extends SetAlgebra[A]
17 |
18 | final case class Sinter[A](keys: NonEmptyList[ByteString], h: ScalaSet[ByteString] => A) extends SetAlgebra[A]
19 |
20 | final case class Sinterstore[A](destination: ByteString, keys: NonEmptyList[ByteString], h: Long => A) extends SetAlgebra[A]
21 |
22 | final case class Sismember[A](key: ByteString, member: ByteString, h: Boolean => A) extends SetAlgebra[A]
23 |
24 | final case class Smembers[A](key: ByteString, h: ScalaSet[ByteString] => A) extends SetAlgebra[A]
25 |
26 | final case class Smove[A](source: ByteString, destination: ByteString, member: ByteString, h: Boolean => A) extends SetAlgebra[A]
27 |
28 | final case class Spop[A](key: ByteString, h: Option[ByteString] => A) extends SetAlgebra[A]
29 |
30 | final case class Srandmember[A](key: ByteString, count: Option[Long], h: ScalaSet[ByteString] => A) extends SetAlgebra[A]
31 |
32 | final case class Srem[A](key: ByteString, members: NonEmptyList[ByteString], h: Long => A) extends SetAlgebra[A]
33 |
34 | final case class Sunion[A](keys: NonEmptyList[ByteString], h: ScalaSet[ByteString] => A) extends SetAlgebra[A]
35 |
36 | final case class Sunionstore[A](destination: ByteString, keys: NonEmptyList[ByteString], h: Long => A) extends SetAlgebra[A]
37 |
38 | trait SetInstances {
39 | implicit val setAlgebraFunctor: Functor[SetAlgebra] =
40 | new Functor[SetAlgebra] {
41 | def map[A, B](a: SetAlgebra[A])(f: A => B): SetAlgebra[B] =
42 | a match {
43 | case Sadd(k, m, h) => Sadd(k, m, x => f(h(x)))
44 | case Scard(k, h) => Scard(k, x => f(h(x)))
45 | case Sdiff(k, h) => Sdiff(k, x => f(h(x)))
46 | case Sdiffstore(d, k, h) => Sdiffstore(d, k, x => f(h(x)))
47 | case Sinter(k, h) => Sinter(k, x => f(h(x)))
48 | case Sinterstore(d, k, h) => Sinterstore(d, k, x => f(h(x)))
49 | case Sismember(k, m, h) => Sismember(k, m, x => f(h(x)))
50 | case Smembers(k, h) => Smembers(k, x => f(h(x)))
51 | case Smove(s, d, m, h) => Smove(s, d, m, x => f(h(x)))
52 | case Spop(k, h) => Spop(k, x => f(h(x)))
53 | case Srandmember(k, c, h) => Srandmember(k, c, x => f(h(x)))
54 | case Srem(k, m, h) => Srem(k, m, x => f(h(x)))
55 | case Sunion(k, h) => Sunion(k, x => f(h(x)))
56 | case Sunionstore(d, k, h) => Sunionstore(d, k, x => f(h(x)))
57 | }
58 | }
59 | }
60 |
61 | trait SetFunctions extends InjectFunctions {
62 | def sadd[F[_]: Functor](key: ByteString, members: NonEmptyList[ByteString])(implicit I: Inject[SetAlgebra, F]): Free[F, Long] =
63 | inject[F, SetAlgebra, Long](Sadd(key, members, Free.point(_)))
64 |
65 | def scard[F[_]: Functor](key: ByteString)(implicit I: Inject[SetAlgebra, F]): Free[F, Long] =
66 | inject[F, SetAlgebra, Long](Scard(key, Free.point(_)))
67 |
68 | def sdiff[F[_]: Functor](keys: NonEmptyList[ByteString])(implicit I: Inject[SetAlgebra, F]): Free[F, ScalaSet[ByteString]] =
69 | inject[F, SetAlgebra, ScalaSet[ByteString]](Sdiff(keys, Free.point(_)))
70 |
71 | def sdiffstore[F[_]: Functor](destination: ByteString, keys: NonEmptyList[ByteString])(implicit I: Inject[SetAlgebra, F]): Free[F, Long] =
72 | inject[F, SetAlgebra, Long](Sdiffstore(destination, keys, Free.point(_)))
73 |
74 | def sinter[F[_]: Functor](keys: NonEmptyList[ByteString])(implicit I: Inject[SetAlgebra, F]): Free[F, ScalaSet[ByteString]] =
75 | inject[F, SetAlgebra, ScalaSet[ByteString]](Sinter(keys, Free.point(_)))
76 |
77 | def sinterstore[F[_]: Functor](destination: ByteString, keys: NonEmptyList[ByteString])(implicit I: Inject[SetAlgebra, F]): Free[F, Long] =
78 | inject[F, SetAlgebra, Long](Sinterstore(destination, keys, Free.point(_)))
79 |
80 | def sismember[F[_]: Functor](key: ByteString, member: ByteString)(implicit I: Inject[SetAlgebra, F]): Free[F, Boolean] =
81 | inject[F, SetAlgebra, Boolean](Sismember(key, member, Free.point(_)))
82 |
83 | def smembers[F[_]: Functor](key: ByteString)(implicit I: Inject[SetAlgebra, F]): Free[F, ScalaSet[ByteString]] =
84 | inject[F, SetAlgebra, ScalaSet[ByteString]](Smembers(key, Free.point(_)))
85 |
86 | def smove[F[_]: Functor](source: ByteString, destination: ByteString, member: ByteString)(implicit I: Inject[SetAlgebra, F]): Free[F, Boolean] =
87 | inject[F, SetAlgebra, Boolean](Smove(source, destination, member, Free.point(_)))
88 |
89 | def spop[F[_]: Functor](key: ByteString)(implicit I: Inject[SetAlgebra, F]): Free[F, Option[ByteString]] =
90 | inject[F, SetAlgebra, Option[ByteString]](Spop(key, Free.point(_)))
91 |
92 | def srandmember[F[_]: Functor](key: ByteString, count: Option[Long] = None)(implicit I: Inject[SetAlgebra, F]): Free[F, ScalaSet[ByteString]] =
93 | inject[F, SetAlgebra, ScalaSet[ByteString]](Srandmember(key, count, Free.point(_)))
94 |
95 | def srem[F[_]: Functor](key: ByteString, members: NonEmptyList[ByteString])(implicit I: Inject[SetAlgebra, F]): Free[F, Long] =
96 | inject[F, SetAlgebra, Long](Srem(key, members, Free.point(_)))
97 |
98 | def sunion[F[_]: Functor](keys: NonEmptyList[ByteString])(implicit I: Inject[SetAlgebra, F]): Free[F, ScalaSet[ByteString]] =
99 | inject[F, SetAlgebra, ScalaSet[ByteString]](Sunion(keys, Free.point(_)))
100 |
101 | def sunionstore[F[_]: Functor](destination: ByteString, keys: NonEmptyList[ByteString])(implicit I: Inject[SetAlgebra, F]): Free[F, Long] =
102 | inject[F, SetAlgebra, Long](Sunionstore(destination, keys, Free.point(_)))
103 | }
104 |
--------------------------------------------------------------------------------
/src/main/scala/redis/algebra/string.scala:
--------------------------------------------------------------------------------
1 | package redis
2 | package algebra
3 |
4 | import scalaz.{\/, Free, Functor, Inject, InjectFunctions, NonEmptyList}
5 |
6 | import data.{BitOperation, SetOption, Status}
7 |
8 | sealed abstract class StringAlgebra[A]
9 |
10 | final case class Append[A](key: ByteString, value: ByteString, h: Long => A) extends StringAlgebra[A]
11 |
12 | final case class Bitcount[A](key: ByteString, range: Option[(Long, Long)], h: Long => A) extends StringAlgebra[A]
13 |
14 | final case class Bitop[A](operation: BitOperation, h: Long => A) extends StringAlgebra[A]
15 |
16 | final case class Decr[A](key: ByteString, h: Long => A) extends StringAlgebra[A]
17 |
18 | final case class Decrby[A](key: ByteString, decrement: Long, h: Long => A) extends StringAlgebra[A]
19 |
20 | final case class Get[A](key: ByteString, h: Option[ByteString] => A) extends StringAlgebra[A]
21 |
22 | final case class Getbit[A](key: ByteString, offset: Long, h: Boolean => A) extends StringAlgebra[A]
23 |
24 | final case class Getrange[A](key: ByteString, start: Long, end: Long, h: ByteString => A) extends StringAlgebra[A]
25 |
26 | final case class Getset[A](key: ByteString, value: ByteString, h: Option[ByteString] => A) extends StringAlgebra[A]
27 |
28 | final case class Incr[A](key: ByteString, h: Long => A) extends StringAlgebra[A]
29 |
30 | final case class Incrby[A](key: ByteString, increment: Long, h: Long => A) extends StringAlgebra[A]
31 |
32 | final case class Incrbyfloat[A](key: ByteString, increment: BigDecimal, h: BigDecimal => A) extends StringAlgebra[A]
33 |
34 | final case class Mget[A](keys: NonEmptyList[ByteString], h: Seq[Option[ByteString]] => A) extends StringAlgebra[A]
35 |
36 | final case class Mset[A](pairs: NonEmptyList[(ByteString, ByteString)], h: Status => A) extends StringAlgebra[A]
37 |
38 | final case class Msetnx[A](pairs: NonEmptyList[(ByteString, ByteString)], h: Boolean => A) extends StringAlgebra[A]
39 |
40 | final case class Psetex[A](key: ByteString, in: Milliseconds, value: ByteString, h: Status => A) extends StringAlgebra[A]
41 |
42 | final case class Set[A](key: ByteString, value: ByteString, in: Option[Seconds \/ Milliseconds], option: Option[SetOption], h: Boolean => A) extends StringAlgebra[A]
43 |
44 | final case class Setbit[A](key: ByteString, offset: Long, value: Boolean, h: Long => A) extends StringAlgebra[A]
45 |
46 | final case class Setex[A](key: ByteString, in: Seconds, value: ByteString, h: Status => A) extends StringAlgebra[A]
47 |
48 | final case class Setnx[A](key: ByteString, value: ByteString, h: Boolean => A) extends StringAlgebra[A]
49 |
50 | final case class Setrange[A](key: ByteString, offset: Long, value: ByteString, h: Long => A) extends StringAlgebra[A]
51 |
52 | final case class Strlen[A](key: ByteString, h: Long => A) extends StringAlgebra[A]
53 |
54 | trait StringInstances {
55 | implicit val stringAlgebraFunctor: Functor[StringAlgebra] =
56 | new Functor[StringAlgebra] {
57 | def map[A, B](a: StringAlgebra[A])(f: A => B): StringAlgebra[B] =
58 | a match {
59 | case Append(k, v, h) => Append(k, v, x => f(h(x)))
60 | case Bitcount(k, r, h) => Bitcount(k, r, x => f(h(x)))
61 | case Bitop(o, h) => Bitop(o, x => f(h(x)))
62 | case Decr(k, h) => Decr(k, x => f(h(x)))
63 | case Decrby(k, d, h) => Decrby(k, d, x => f(h(x)))
64 | case Get(k, h) => Get(k, x => f(h(x)))
65 | case Getbit(k, o, h) => Getbit(k, o, x => f(h(x)))
66 | case Getrange(k, s, e, h) => Getrange(k, s, e, x => f(h(x)))
67 | case Getset(k, v, h) => Getset(k, v, x => f(h(x)))
68 | case Incr(k, h) => Incr(k, x => f(h(x)))
69 | case Incrby(k, i, h) => Incrby(k, i, x => f(h(x)))
70 | case Incrbyfloat(k, i, h) => Incrbyfloat(k, i, x => f(h(x)))
71 | case Mget(k, h) => Mget(k, x => f(h(x)))
72 | case Mset(p, h) => Mset(p, x => f(h(x)))
73 | case Msetnx(p, h) => Msetnx(p, x => f(h(x)))
74 | case Psetex(k, i, v, h) => Psetex(k, i, v, x => f(h(x)))
75 | case Set(k, v, i, o, h) => Set(k, v, i, o, x => f(h(x)))
76 | case Setbit(k, o, v, h) => Setbit(k, o, v, x => f(h(x)))
77 | case Setex(k, i, v, h) => Setex(k, i, v, x => f(h(x)))
78 | case Setnx(k, v, h) => Setnx(k, v, x => f(h(x)))
79 | case Setrange(k, o, v, h) => Setrange(k, o, v, x => f(h(x)))
80 | case Strlen(k, h) => Strlen(k, x => f(h(x)))
81 | }
82 | }
83 | }
84 |
85 | trait StringFunctions extends InjectFunctions {
86 | def append[F[_]: Functor](key: ByteString, value: ByteString)(implicit I: Inject[StringAlgebra, F]): Free[F, Long] =
87 | inject[F, StringAlgebra, Long](Append(key, value, Free.point(_)))
88 |
89 | def bitcount[F[_]: Functor](key: ByteString, range: Option[(Long, Long)])(implicit I: Inject[StringAlgebra, F]): Free[F, Long] =
90 | inject[F, StringAlgebra, Long](Bitcount(key, range, Free.point(_)))
91 |
92 | def bitop[F[_]: Functor](operation: BitOperation)(implicit I: Inject[StringAlgebra, F]): Free[F, Long] =
93 | inject[F, StringAlgebra, Long](Bitop(operation, Free.point(_)))
94 |
95 | def decr[F[_]: Functor](key: ByteString)(implicit I: Inject[StringAlgebra, F]): Free[F, Long] =
96 | inject[F, StringAlgebra, Long](Decr(key, Free.point(_)))
97 |
98 | def decrby[F[_]: Functor](key: ByteString, decrement: Long)(implicit I: Inject[StringAlgebra, F]): Free[F, Long] =
99 | inject[F, StringAlgebra, Long](Decrby(key, decrement, Free.point(_)))
100 |
101 | def get[F[_]: Functor](key: ByteString)(implicit I: Inject[StringAlgebra, F]): Free[F, Option[ByteString]] =
102 | inject[F, StringAlgebra, Option[ByteString]](Get(key, Free.point(_)))
103 |
104 | def getbit[F[_]: Functor](key: ByteString, offset: Long)(implicit I: Inject[StringAlgebra, F]): Free[F, Boolean] =
105 | inject[F, StringAlgebra, Boolean](Getbit(key, offset, Free.point(_)))
106 |
107 | def getrange[F[_]: Functor](key: ByteString, start: Long, end: Long)(implicit I: Inject[StringAlgebra, F]): Free[F, ByteString] =
108 | inject[F, StringAlgebra, ByteString](Getrange(key, start, end, Free.point(_)))
109 |
110 | def getset[F[_]: Functor](key: ByteString, value: ByteString)(implicit I: Inject[StringAlgebra, F]): Free[F, Option[ByteString]] =
111 | inject[F, StringAlgebra, Option[ByteString]](Getset(key, value, Free.point(_)))
112 |
113 | def incr[F[_]: Functor](key: ByteString)(implicit I: Inject[StringAlgebra, F]): Free[F, Long] =
114 | inject[F, StringAlgebra, Long](Incr(key, Free.point(_)))
115 |
116 | def incrby[F[_]: Functor](key: ByteString, increment: Long)(implicit I: Inject[StringAlgebra, F]): Free[F, Long] =
117 | inject[F, StringAlgebra, Long](Incrby(key, increment, Free.point(_)))
118 |
119 | def incrbyfloat[F[_]: Functor](key: ByteString, increment: BigDecimal)(implicit I: Inject[StringAlgebra, F]): Free[F, BigDecimal] =
120 | inject[F, StringAlgebra, BigDecimal](Incrbyfloat(key, increment, Free.point(_)))
121 |
122 | def mget[F[_]: Functor](keys: NonEmptyList[ByteString])(implicit I: Inject[StringAlgebra, F]): Free[F, Seq[Option[ByteString]]] =
123 | inject[F, StringAlgebra, Seq[Option[ByteString]]](Mget(keys, Free.point(_)))
124 |
125 | def mset[F[_]: Functor](pairs: NonEmptyList[(ByteString, ByteString)])(implicit I: Inject[StringAlgebra, F]): Free[F, Status] =
126 | inject[F, StringAlgebra, Status](Mset(pairs, Free.point(_)))
127 |
128 | def msetnx[F[_]: Functor](pairs: NonEmptyList[(ByteString, ByteString)])(implicit I: Inject[StringAlgebra, F]): Free[F, Boolean] =
129 | inject[F, StringAlgebra, Boolean](Msetnx(pairs, Free.point(_)))
130 |
131 | def psetex[F[_]: Functor](key: ByteString, in: Milliseconds, value: ByteString)(implicit I: Inject[StringAlgebra, F]): Free[F, Status] =
132 | inject[F, StringAlgebra, Status](Psetex(key, in, value, Free.point(_)))
133 |
134 | def set[F[_]: Functor](
135 | key: ByteString,
136 | value: ByteString,
137 | in: Option[Seconds \/ Milliseconds] = None,
138 | option: Option[SetOption] = None)(implicit I: Inject[StringAlgebra, F]): Free[F, Boolean] =
139 | inject[F, StringAlgebra, Boolean](Set(key, value, in, option, Free.point(_)))
140 |
141 | def setbit[F[_]: Functor](key: ByteString, offset: Long, value: Boolean)(implicit I: Inject[StringAlgebra, F]): Free[F, Long] =
142 | inject[F, StringAlgebra, Long](Setbit(key, offset, value, Free.point(_)))
143 |
144 | def setex[F[_]: Functor](key: ByteString, in: Seconds, value: ByteString)(implicit I: Inject[StringAlgebra, F]): Free[F, Status] =
145 | inject[F, StringAlgebra, Status](Setex(key, in, value, Free.point(_)))
146 |
147 | def setnx[F[_]: Functor](key: ByteString, value: ByteString)(implicit I: Inject[StringAlgebra, F]): Free[F, Boolean] =
148 | inject[F, StringAlgebra, Boolean](Setnx(key, value, Free.point(_)))
149 |
150 | def setrange[F[_]: Functor](key: ByteString, offset: Long, value: ByteString)(implicit I: Inject[StringAlgebra, F]): Free[F, Long] =
151 | inject[F, StringAlgebra, Long](Setrange(key, offset, value, Free.point(_)))
152 |
153 | def strlen[F[_]: Functor](key: ByteString)(implicit I: Inject[StringAlgebra, F]): Free[F, Long] =
154 | inject[F, StringAlgebra, Long](Strlen(key, Free.point(_)))
155 | }
156 |
--------------------------------------------------------------------------------
/src/main/scala/redis/algebra/zset.scala:
--------------------------------------------------------------------------------
1 | package redis
2 | package algebra
3 |
4 | import scalaz.{Free, Functor, Inject, InjectFunctions, NonEmptyList}
5 |
6 | import data.{Aggregate, Endpoint, Limit, Sum}
7 |
8 | sealed abstract class ZSetAlgebra[A]
9 |
10 | final case class Zadd[A](key: ByteString, pairs: NonEmptyList[(Double, ByteString)], h: Long => A) extends ZSetAlgebra[A]
11 |
12 | final case class Zcard[A](key: ByteString, h: Long => A) extends ZSetAlgebra[A]
13 |
14 | final case class Zcount[A](key: ByteString, min: Endpoint, max: Endpoint, h: Long => A) extends ZSetAlgebra[A]
15 |
16 | final case class Zincrby[A](key: ByteString, increment: Double, member: ByteString, h: Double => A) extends ZSetAlgebra[A]
17 |
18 | final case class Zinterstore[A](destination: ByteString, keys: NonEmptyList[ByteString], weights: Option[NonEmptyList[Double]], aggregate: Aggregate, h: Long => A) extends ZSetAlgebra[A]
19 |
20 | final case class Zrange[A](key: ByteString, start: Long, stop: Long, withScores: Boolean, h: Seq[(ByteString, Option[Double])] => A) extends ZSetAlgebra[A]
21 |
22 | final case class Zrangebyscore[A](key: ByteString, min: Endpoint, max: Endpoint, withScores: Boolean, limit: Option[Limit], h: Seq[(ByteString, Option[Double])] => A) extends ZSetAlgebra[A]
23 |
24 | final case class Zrank[A](key: ByteString, member: ByteString, h: Option[Long] => A) extends ZSetAlgebra[A]
25 |
26 | final case class Zrem[A](key: ByteString, members: NonEmptyList[ByteString], h: Long => A) extends ZSetAlgebra[A]
27 |
28 | final case class Zremrangebyrank[A](key: ByteString, start: Long, stop: Long, h: Long => A) extends ZSetAlgebra[A]
29 |
30 | final case class Zremrangebyscore[A](key: ByteString, start: Endpoint, stop: Endpoint, h: Long => A) extends ZSetAlgebra[A]
31 |
32 | final case class Zrevrange[A](key: ByteString, start: Long, stop: Long, withScores: Boolean, h: Seq[(ByteString, Option[Double])] => A) extends ZSetAlgebra[A]
33 |
34 | final case class Zrevrangebyscore[A](key: ByteString, min: Endpoint, max: Endpoint, withScores: Boolean, limit: Option[Limit], h: Seq[(ByteString, Option[Double])] => A) extends ZSetAlgebra[A]
35 |
36 | final case class Zrevrank[A](key: ByteString, member: ByteString, h: Option[Long] => A) extends ZSetAlgebra[A]
37 |
38 | final case class Zscore[A](key: ByteString, member: ByteString, h: Option[Double] => A) extends ZSetAlgebra[A]
39 |
40 | final case class Zunionstore[A](destination: ByteString, keys: NonEmptyList[ByteString], weights: Option[NonEmptyList[Double]], aggregate: Aggregate, h: Long => A) extends ZSetAlgebra[A]
41 |
42 | trait ZSetInstances {
43 | implicit val zsetAlgebraFunctor: Functor[ZSetAlgebra] =
44 | new Functor[ZSetAlgebra] {
45 | def map[A, B](a: ZSetAlgebra[A])(f: A => B): ZSetAlgebra[B] =
46 | a match {
47 | case Zadd(k, p, h) => Zadd(k, p, x => f(h(x)))
48 | case Zcard(k, h) => Zcard(k, x => f(h(x)))
49 | case Zcount(k, m, n, h) => Zcount(k, m, n, x => f(h(x)))
50 | case Zincrby(k, i, m, h) => Zincrby(k, i, m, x => f(h(x)))
51 | case Zinterstore(d, k, w, g, h) => Zinterstore(d, k, w, g, x => f(h(x)))
52 | case Zrange(k, s, t, w, h) => Zrange(k, s, t, w, x => f(h(x)))
53 | case Zrangebyscore(k, m, n, w, l, h) => Zrangebyscore(k, m, n, w, l, x => f(h(x)))
54 | case Zrank(k, m, h) => Zrank(k, m, x => f(h(x)))
55 | case Zrem(k, m, h) => Zrem(k, m, x => f(h(x)))
56 | case Zremrangebyrank(k, s, t, h) => Zremrangebyrank(k, s, t, x => f(h(x)))
57 | case Zremrangebyscore(k, s, t, h) => Zremrangebyscore(k, s, t, x => f(h(x)))
58 | case Zrevrange(k, s, t, w, h) => Zrevrange(k, s, t, w, x => f(h(x)))
59 | case Zrevrangebyscore(k, m, n, w, l, h) => Zrevrangebyscore(k, m, n, w, l, x => f(h(x)))
60 | case Zrevrank(k, m, h) => Zrevrank(k, m, x => f(h(x)))
61 | case Zscore(k, m, h) => Zscore(k, m, x => f(h(x)))
62 | case Zunionstore(d, k, w, g, h) => Zunionstore(d, k, w, g, x => f(h(x)))
63 | }
64 | }
65 | }
66 |
67 | trait ZSetFunctions extends InjectFunctions {
68 | def zadd[F[_]: Functor](key: ByteString, pairs: NonEmptyList[(Double, ByteString)])(implicit I: Inject[ZSetAlgebra, F]): Free[F, Long] =
69 | inject[F, ZSetAlgebra, Long](Zadd(key, pairs, Free.point(_)))
70 |
71 | def zcard[F[_]: Functor](key: ByteString)(implicit I: Inject[ZSetAlgebra, F]): Free[F, Long] =
72 | inject[F, ZSetAlgebra, Long](Zcard(key, Free.point(_)))
73 |
74 | def zcount[F[_]: Functor](key: ByteString, min: Endpoint, max: Endpoint)(implicit I: Inject[ZSetAlgebra, F]): Free[F, Long] =
75 | inject[F, ZSetAlgebra, Long](Zcount(key, min, max, Free.point(_)))
76 |
77 | def zincrby[F[_]: Functor](key: ByteString, increment: Double, member: ByteString)(implicit I: Inject[ZSetAlgebra, F]): Free[F, Double] =
78 | inject[F, ZSetAlgebra, Double](Zincrby(key, increment, member, Free.point(_)))
79 |
80 | def zinterstore[F[_]: Functor](
81 | destination: ByteString,
82 | keys: NonEmptyList[ByteString],
83 | weights: Option[NonEmptyList[Double]] = None,
84 | aggregate: Aggregate = Sum)(implicit I: Inject[ZSetAlgebra, F]): Free[F, Long] =
85 | inject[F, ZSetAlgebra, Long](Zinterstore(destination, keys, weights, aggregate, Free.point(_)))
86 |
87 | def zrange[F[_]: Functor](
88 | key: ByteString,
89 | start: Long,
90 | stop: Long,
91 | withScores: Boolean = false)(implicit I: Inject[ZSetAlgebra, F]): Free[F, Seq[(ByteString, Option[Double])]] =
92 | inject[F, ZSetAlgebra, Seq[(ByteString, Option[Double])]](Zrange(key, start, stop, withScores, Free.point(_)))
93 |
94 | def zrangebyscore[F[_]: Functor](
95 | key: ByteString,
96 | min: Endpoint,
97 | max: Endpoint,
98 | withScores: Boolean = false,
99 | limit: Option[Limit] = None)(implicit I: Inject[ZSetAlgebra, F]): Free[F, Seq[(ByteString, Option[Double])]] =
100 | inject[F, ZSetAlgebra, Seq[(ByteString, Option[Double])]](Zrangebyscore(key, min, max, withScores, limit, Free.point(_)))
101 |
102 | def zrank[F[_]: Functor](key: ByteString, member: ByteString)(implicit I: Inject[ZSetAlgebra, F]): Free[F, Option[Long]] =
103 | inject[F, ZSetAlgebra, Option[Long]](Zrank(key, member, Free.point(_)))
104 |
105 | def zrem[F[_]: Functor](key: ByteString, members: NonEmptyList[ByteString])(implicit I: Inject[ZSetAlgebra, F]): Free[F, Long] =
106 | inject[F, ZSetAlgebra, Long](Zrem(key, members, Free.point(_)))
107 |
108 | def zremrangebyrank[F[_]: Functor](key: ByteString, start: Long, stop: Long)(implicit I: Inject[ZSetAlgebra, F]): Free[F, Long] =
109 | inject[F, ZSetAlgebra, Long](Zremrangebyrank(key, start, stop, Free.point(_)))
110 |
111 | def zremrangebyscore[F[_]: Functor](key: ByteString, start: Endpoint, stop: Endpoint)(implicit I: Inject[ZSetAlgebra, F]): Free[F, Long] =
112 | inject[F, ZSetAlgebra, Long](Zremrangebyscore(key, start, stop, Free.point(_)))
113 |
114 | def zrevrange[F[_]: Functor](
115 | key: ByteString,
116 | start: Long,
117 | stop: Long,
118 | withScores: Boolean = false)(implicit I: Inject[ZSetAlgebra, F]): Free[F, Seq[(ByteString, Option[Double])]] =
119 | inject[F, ZSetAlgebra, Seq[(ByteString, Option[Double])]](Zrevrange(key, start, stop, withScores, Free.point(_)))
120 |
121 | def zrevrangebyscore[F[_]: Functor](
122 | key: ByteString,
123 | min: Endpoint,
124 | max: Endpoint,
125 | withScores: Boolean = false,
126 | limit: Option[Limit] = None)(implicit I: Inject[ZSetAlgebra, F]): Free[F, Seq[(ByteString, Option[Double])]] =
127 | inject[F, ZSetAlgebra, Seq[(ByteString, Option[Double])]](Zrevrangebyscore(key, min, max, withScores, limit, Free.point(_)))
128 |
129 | def zrevrank[F[_]: Functor](key: ByteString, member: ByteString)(implicit I: Inject[ZSetAlgebra, F]): Free[F, Option[Long]] =
130 | inject[F, ZSetAlgebra, Option[Long]](Zrevrank(key, member, Free.point(_)))
131 |
132 | def zscore[F[_]: Functor](key: ByteString, member: ByteString)(implicit I: Inject[ZSetAlgebra, F]): Free[F, Option[Double]] =
133 | inject[F, ZSetAlgebra, Option[Double]](Zscore(key, member, Free.point(_)))
134 |
135 | def zunionstore[F[_]: Functor](
136 | destination: ByteString,
137 | keys: NonEmptyList[ByteString],
138 | weights: Option[NonEmptyList[Double]] = None,
139 | aggregate: Aggregate = Sum)(implicit I: Inject[ZSetAlgebra, F]): Free[F, Long] =
140 | inject[F, ZSetAlgebra, Long](Zunionstore(destination, keys, weights, aggregate, Free.point(_)))
141 | }
142 |
--------------------------------------------------------------------------------
/src/test/scala/redis/algebra/bytestring.scala:
--------------------------------------------------------------------------------
1 | package redis
2 | package algebra
3 |
4 | import scalaz.{ImmutableArray => IA}
5 |
6 | trait ByteStringFunctions {
7 | def bytes(a: String) = IA.make(a.getBytes(`UTF-8`))
8 |
9 | def string(a: ByteString) = new String(a.toArray, `UTF-8`)
10 |
11 | private val `UTF-8` = "UTF-8"
12 | }
13 |
--------------------------------------------------------------------------------
/src/test/scala/redis/algebra/interpreter.scala:
--------------------------------------------------------------------------------
1 | package redis
2 | package algebra
3 |
4 | import scalaz.{-\/, \/-, Coproduct, Free, Functor, ImmutableArray => IA}
5 |
6 | import all._, Interpreter._
7 |
8 | sealed abstract class Interpreter[F[_] : Functor] {
9 | def runAlgebra[A](algebra: F[Mem => (A, Mem)], mem: Mem): (A, Mem)
10 | }
11 |
12 | sealed trait InterpreterInstances {
13 | implicit val connectionAlgebraInterpreter: Interpreter[ConnectionAlgebra] =
14 | new Interpreter[ConnectionAlgebra] {
15 | def runAlgebra[A](algebra: ConnectionAlgebra[Mem => (A, Mem)], mem: Mem) =
16 | algebra match {
17 | case _ => ???
18 | }
19 | }
20 | implicit val hashAlgebraInterpreter: Interpreter[HashAlgebra] =
21 | new Interpreter[HashAlgebra] {
22 | def runAlgebra[A](algebra: HashAlgebra[Mem => (A, Mem)], mem: Mem) =
23 | algebra match {
24 | case _ => ???
25 | }
26 | }
27 |
28 | implicit val keyAgebraInterpreter: Interpreter[KeyAlgebra] =
29 | new Interpreter[KeyAlgebra] with ByteStringFunctions {
30 | def runAlgebra[A](algebra: KeyAlgebra[Mem => (A, Mem)], mem: Mem) =
31 | algebra match {
32 | case Del(k, h) =>
33 | val (b, c) = k.list.foldLeft((0L, mem)) {
34 | case ((b,c), a) =>
35 | if (c.contains(string(a))) (b + 1, c - string(a)) else (b, c)
36 | }
37 | h(b)(c)
38 | case Dump(k, h) => h(mem.get(string(k)).map(a => bytes(a.hashCode.toString)))(mem)
39 | case Exists(k, h) => h(mem.contains(string(k)))(mem)
40 | case _ => ???
41 | }
42 | }
43 |
44 | implicit val listAlgebraInterpreter: Interpreter[ListAlgebra] =
45 | new Interpreter[ListAlgebra] {
46 | def runAlgebra[A](algebra: ListAlgebra[Mem => (A, Mem)], mem: Mem) =
47 | algebra match {
48 | case _ => ???
49 | }
50 | }
51 |
52 | implicit val scriptAlgebraInterpreter: Interpreter[ScriptAlgebra] =
53 | new Interpreter[ScriptAlgebra] {
54 | def runAlgebra[A](algebra: ScriptAlgebra[Mem => (A, Mem)], mem: Mem) =
55 | algebra match {
56 | case _ => ???
57 | }
58 | }
59 |
60 | implicit val serverAlgebraInterpreter: Interpreter[ServerAlgebra] =
61 | new Interpreter[ServerAlgebra] {
62 | def runAlgebra[A](algebra: ServerAlgebra[Mem => (A, Mem)], mem: Mem) =
63 | algebra match {
64 | case _ => ???
65 | }
66 | }
67 |
68 | implicit val setAlgebraInterpreter: Interpreter[SetAlgebra] =
69 | new Interpreter[SetAlgebra] {
70 | def runAlgebra[A](algebra: SetAlgebra[Mem => (A, Mem)], mem: Mem) =
71 | algebra match {
72 | case _ => ???
73 | }
74 | }
75 |
76 | implicit val stringAlgebraInterpreter: Interpreter[StringAlgebra] =
77 | new Interpreter[StringAlgebra] {
78 | def runAlgebra[A](algebra: StringAlgebra[Mem => (A, Mem)], mem: Mem) =
79 | algebra match {
80 | case _ => ???
81 | }
82 | }
83 |
84 | implicit val zsetAlgebraInterpreter: Interpreter[ZSetAlgebra] =
85 | new Interpreter[ZSetAlgebra] {
86 | def runAlgebra[A](algebra: ZSetAlgebra[Mem => (A, Mem)], mem: Mem) =
87 | algebra match {
88 | case _ => ???
89 | }
90 | }
91 |
92 | implicit def coproductAlgebraInterpreter[F[_]: Interpreter: Functor, G[_]: Interpreter: Functor]:
93 | Interpreter[({ type l[a] = Coproduct[F, G, a] })#l] = {
94 | type H[A] = Coproduct[F, G, A]
95 | new Interpreter[H] {
96 | def runAlgebra[A](algebra: H[Mem => (A, Mem)], mem: Mem) =
97 | algebra.run match {
98 | case -\/(fa) => implicitly[Interpreter[F]].runAlgebra(fa, mem)
99 | case \/-(fa) => implicitly[Interpreter[G]].runAlgebra(fa, mem)
100 | }
101 | }
102 | }
103 | }
104 |
105 | sealed trait InterpreterFunctions {
106 | type Mem = Map[String, String]
107 |
108 | def run[A](algebra: Free[R, A], mem: Mem): A =
109 | algebra.resume.fold({ (a: R[Free[R, A]]) =>
110 | val (x, y) = implicitly[Interpreter[R]].runAlgebra(a.map(a => (mem: Mem) => (a, mem)), mem)
111 | run(x, y)
112 | }, a => a)
113 | }
114 |
115 | object Interpreter extends InterpreterInstances with InterpreterFunctions
116 |
--------------------------------------------------------------------------------
/src/test/scala/redis/algebra/keyspec.scala:
--------------------------------------------------------------------------------
1 | package redis
2 | package algebra
3 |
4 | import org.specs2._
5 |
6 | import scalaz.{ImmutableArray => IA, NonEmptyList}, NonEmptyList._
7 |
8 | import all._
9 |
10 | class KeyAlgebraSpec extends Specification with ByteStringFunctions { def is = s2"""
11 | This is the specification for the KeyAlgebra.
12 |
13 | A Del command issued with some existing keys should
14 | result in the number of keys deleted $e1
15 |
16 | A Dump command issued with an existing key should
17 | result in a some(serialized value) $e2
18 |
19 | A Dump command issued with a nonexisting key should
20 | result in a none $e3
21 |
22 | An Exists command issued with an existing key should
23 | result in true $e4
24 |
25 | An Exists command issued with a nonexisting key should
26 | result in false $e5
27 | """
28 |
29 | def e1 = interpreter.run(del(nels(keya, keyb, nonexisting)), map) === 2
30 |
31 | def e2 = interpreter.run(dump(keya), map).map(string(_)) must beSome(serialize(string(keya)))
32 |
33 | def e3 = interpreter.run(dump(nonexisting), map) must beNone
34 |
35 | def e4 = interpreter.run(exists(keya), map) === true
36 |
37 | def e5 = interpreter.run(exists(nonexisting), map) === false
38 |
39 | def serialize(k: String) = map(k).hashCode.toString
40 |
41 | val keya = bytes("a")
42 |
43 | val keyb = bytes("b")
44 |
45 | val keyc = bytes("c")
46 |
47 | val nonexisting = bytes("x")
48 |
49 | val map = Map(string(keya) -> "x", string(keyb) -> "y", string(keyc) -> "z")
50 |
51 | val interpreter = Interpreter
52 | }
53 |
--------------------------------------------------------------------------------