-
Notifications
You must be signed in to change notification settings - Fork 143
/
Scripting.scala
83 lines (70 loc) · 3.18 KB
/
Scripting.scala
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
package redis.api.scripting
import java.io.File
import java.security.MessageDigest
import redis.protocol.{MultiBulk, Bulk}
import redis._
import akka.util.ByteString
object RedisScript {
def fromFile(file: File): RedisScript = {
val source = scala.io.Source.fromFile(file)
val lines = try source.mkString.stripMargin.replaceAll("[\n\r]","") finally source.close()
RedisScript(lines)
}
def fromResource(path: String): RedisScript = {
val source = scala.io.Source.fromURL(getClass.getResource(path))
val lines = try source.mkString.stripMargin.replaceAll("[\n\r]","") finally source.close()
RedisScript(lines)
}
}
case class RedisScript(script: String) {
lazy val sha1 = {
val messageDigestSha1 = MessageDigest.getInstance("SHA-1")
messageDigestSha1.digest(script.getBytes("UTF-8")).map("%02x".format(_)).mkString
}
}
trait EvaledScript {
val isMasterOnly = true
def encodeRequest[KK, KA](
encoder: ((String, Seq[ByteString]) => ByteString),
command: String,
param: String,
keys: Seq[KK],
args: Seq[KA],
keySerializer: ByteStringSerializer[KK],
argSerializer: ByteStringSerializer[KA]): ByteString = {
encoder(command,
(ByteString(param)
+: ByteString(keys.length.toString)
+: keys.map(keySerializer.serialize)) ++ args.map(argSerializer.serialize))
}
}
case class Eval[R, KK, KA](script: String, keys: Seq[KK] = Seq(), args: Seq[KA] = Seq())(implicit redisKeys: ByteStringSerializer[KK], redisArgs: ByteStringSerializer[KA], deserializerR: RedisReplyDeserializer[R])
extends RedisCommandRedisReplyRedisReply[R]
with EvaledScript {
val encodedRequest: ByteString = encodeRequest(encode, "EVAL", script, keys, args, redisKeys, redisArgs)
val deserializer: RedisReplyDeserializer[R] = deserializerR
}
case class Evalsha[R, KK, KA](sha1: String, keys: Seq[KK] = Seq(), args: Seq[KA] = Seq())(implicit redisKeys: ByteStringSerializer[KK], redisArgs: ByteStringSerializer[KA], deserializerR: RedisReplyDeserializer[R])
extends RedisCommandRedisReplyRedisReply[R]
with EvaledScript {
val encodedRequest: ByteString = encodeRequest(encode, "EVALSHA", sha1, keys, args, redisKeys, redisArgs)
val deserializer: RedisReplyDeserializer[R] = deserializerR
}
case object ScriptFlush extends RedisCommandStatusBoolean {
val isMasterOnly = true
val encodedRequest: ByteString = encode("SCRIPT", Seq(ByteString("FLUSH")))
}
case object ScriptKill extends RedisCommandStatusBoolean {
val isMasterOnly = true
val encodedRequest: ByteString = encode("SCRIPT", Seq(ByteString("KILL")))
}
case class ScriptLoad(script: String) extends RedisCommandBulk[String] {
val isMasterOnly = true
val encodedRequest: ByteString = encode("SCRIPT", Seq(ByteString("LOAD"), ByteString(script)))
def decodeReply(bulk: Bulk) = bulk.toString
}
case class ScriptExists(sha1: Seq[String]) extends RedisCommandMultiBulk[Seq[Boolean]] {
val isMasterOnly = true
val encodedRequest: ByteString = encode("SCRIPT", ByteString("EXISTS") +: sha1.map(ByteString(_)))
def decodeReply(mb: MultiBulk) = MultiBulkConverter.toSeqBoolean(mb)
}