From 8d1c4a23dee164ec0aff3dcf6bd3b769bc8b4148 Mon Sep 17 00:00:00 2001 From: Jason Livesay Date: Fri, 4 Apr 2014 16:11:43 -0700 Subject: Allow multi/exec replies so transactions work. --- lib/pure/redis.nim | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) (limited to 'lib/pure/redis.nim') diff --git a/lib/pure/redis.nim b/lib/pure/redis.nim index 8171dc12b..563e522df 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") @@ -84,7 +88,10 @@ proc recv(sock: TSocket, size: int): TaintedString = 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 + # Error. if line[0] == '-': raise newException(ERedis, strip(line)) @@ -107,6 +114,9 @@ proc parseBulk(r: TRedis, allowMBNil = False): TRedisString = 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]) @@ -722,6 +732,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) = -- cgit 1.4.1-2-gfad0 From e6d2490b9c71fcd7b30ed3afaaacb11331a21979 Mon Sep 17 00:00:00 2001 From: Jason Livesay Date: Fri, 4 Apr 2014 23:29:50 -0700 Subject: Support transactions --- lib/pure/redis.nim | 47 ++++++++++++++++++++++++++++++++--------------- 1 file changed, 32 insertions(+), 15 deletions(-) (limited to 'lib/pure/redis.nim') diff --git a/lib/pure/redis.nim b/lib/pure/redis.nim index 563e522df..f4c45b99c 100644 --- a/lib/pure/redis.nim +++ b/lib/pure/redis.nim @@ -85,13 +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) - - if line == "+QUEUED" or line == "+OK": # inside of a transaction (multi) - return nil - +proc parseSingle(r: TRedis, line:string, allowMBNil = False): TRedisString = # Error. if line[0] == '-': raise newException(ERedis, strip(line)) @@ -101,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]) @@ -111,6 +108,32 @@ 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) @@ -118,14 +141,8 @@ proc parseMultiBulk(r: TRedis): TRedisList = 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" -- cgit 1.4.1-2-gfad0