summary refs log tree commit diff stats
path: root/lib
diff options
context:
space:
mode:
authorDominik Picheta <dominikpicheta@googlemail.com>2014-04-05 20:26:54 +0100
committerDominik Picheta <dominikpicheta@googlemail.com>2014-04-05 20:26:54 +0100
commit694fc87b1d3259c49ba61f46ef27d87552faf431 (patch)
tree91a41e7eb17af3c76b4bb11a59eb30b81f6211ed /lib
parent5a4afbef8422d67e31be85172a735db9ac464009 (diff)
parentfc814b87dccd8f630f701e000f54c35ad4203cad (diff)
downloadNim-694fc87b1d3259c49ba61f46ef27d87552faf431.tar.gz
Merge branch 'devel' of github.com:Araq/Nimrod into devel
Diffstat (limited to 'lib')
-rw-r--r--lib/pure/redis.nim54
1 files changed, 41 insertions, 13 deletions
diff --git a/lib/pure/redis.nim b/lib/pure/redis.nim
index 8171dc12b..f4c45b99c 100644
--- a/lib/pure/redis.nim
+++ b/lib/pure/redis.nim
@@ -45,7 +45,7 @@ proc raiseInvalidReply(expected, got: char) =
           [$expected, $got])
 
 proc raiseNoOK(status: string) =
-  if status != "OK":
+  if status != "QUEUED" and status != "OK":
     raise newException(EInvalidReply, "Expected \"OK\" got \"$1\"" % status)
 
 proc parseStatus(r: TRedis): TRedisStatus =
@@ -64,6 +64,10 @@ proc parseStatus(r: TRedis): TRedisStatus =
 proc parseInteger(r: TRedis): TRedisInteger =
   var line = ""
   r.socket.readLine(line)
+
+  if line == "+QUEUED":  # inside of multi
+    return -1
+
   if line == "":
     raise newException(ERedis, "Server closed connection prematurely")
 
@@ -81,10 +85,7 @@ proc recv(sock: TSocket, size: int): TaintedString =
   if sock.recv(cstring(result), size) != size:
     raise newException(EInvalidReply, "recv failed")
 
-proc parseBulk(r: TRedis, allowMBNil = False): TRedisString =
-  var line = ""
-  r.socket.readLine(line.TaintedString)
-  
+proc parseSingle(r: TRedis, line:string, allowMBNil = False): TRedisString =
   # Error.
   if line[0] == '-':
     raise newException(ERedis, strip(line))
@@ -94,6 +95,9 @@ proc parseBulk(r: TRedis, allowMBNil = False): TRedisString =
     if line == "*-1":
        return RedisNil
   
+  if line == "+QUEUED" or line == "+OK" : # inside of a transaction (multi)
+    return nil
+
   if line[0] != '$':
     raiseInvalidReply('$', line[0])
   
@@ -104,18 +108,41 @@ proc parseBulk(r: TRedis, allowMBNil = False): TRedisString =
   var s = r.socket.recv(numBytes+2)
   result = strip(s.string)
 
+proc parseMultiLines(r: TRedis, countLine:string): TRedisList =
+  if countLine.string[0] != '*':
+    raiseInvalidReply('*', countLine.string[0])
+
+  var numElems = parseInt(countLine.string.substr(1))
+  if numElems == -1: return nil
+  result = @[]
+  for i in 1..numElems:
+    var line = ""
+    r.socket.readLine(line.TaintedString)
+    if line[0] == '*':  # after exec() may contain more multi-bulk replies
+      var parsed = r.parseMultiLines(line)
+      for item in parsed:
+        result.add(item)
+    else:
+     result.add(r.parseSingle(line))
+
+proc parseBulk(r: TRedis, allowMBNil = False): TRedisString =
+  var line = ""
+  r.socket.readLine(line.TaintedString)
+
+  if line == "+QUEUED" or line == "+OK": # inside of a transaction (multi)
+    return nil
+
+  return r.parseSingle(line, allowMBNil)
+
 proc parseMultiBulk(r: TRedis): TRedisList =
   var line = TaintedString""
   r.socket.readLine(line)
+
+  if line == "+QUEUED": # inside of a transaction (multi)
+    return nil
     
-  if line.string[0] != '*':
-    raiseInvalidReply('*', line.string[0])
-  
-  var numElems = parseInt(line.string.substr(1))
-  if numElems == -1: return nil
-  result = @[]
-  for i in 1..numElems:
-    result.add(r.parseBulk())
+  return r.parseMultiLines(line)
+
 
 proc sendCommand(r: TRedis, cmd: string, args: varargs[string]) =
   var request = "*" & $(1 + args.len()) & "\c\L"
@@ -722,6 +749,7 @@ proc discardMulti*(r: TRedis) =
 proc exec*(r: TRedis): TRedisList =
   ## Execute all commands issued after MULTI
   r.sendCommand("EXEC")
+
   return r.parseMultiBulk()
 
 proc multi*(r: TRedis) =