Merge pull request #1066 from ithkuil/devel
Transaction support for redis
This commit is contained in:
commit
d02af5cc4c
1 changed files with 42 additions and 14 deletions
|
|
@ -45,7 +45,7 @@ proc raiseInvalidReply(expected, got: char) =
|
||||||
[$expected, $got])
|
[$expected, $got])
|
||||||
|
|
||||||
proc raiseNoOK(status: string) =
|
proc raiseNoOK(status: string) =
|
||||||
if status != "OK":
|
if status != "QUEUED" and status != "OK":
|
||||||
raise newException(EInvalidReply, "Expected \"OK\" got \"$1\"" % status)
|
raise newException(EInvalidReply, "Expected \"OK\" got \"$1\"" % status)
|
||||||
|
|
||||||
proc parseStatus(r: TRedis): TRedisStatus =
|
proc parseStatus(r: TRedis): TRedisStatus =
|
||||||
|
|
@ -64,6 +64,10 @@ proc parseStatus(r: TRedis): TRedisStatus =
|
||||||
proc parseInteger(r: TRedis): TRedisInteger =
|
proc parseInteger(r: TRedis): TRedisInteger =
|
||||||
var line = ""
|
var line = ""
|
||||||
r.socket.readLine(line)
|
r.socket.readLine(line)
|
||||||
|
|
||||||
|
if line == "+QUEUED": # inside of multi
|
||||||
|
return -1
|
||||||
|
|
||||||
if line == "":
|
if line == "":
|
||||||
raise newException(ERedis, "Server closed connection prematurely")
|
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:
|
if sock.recv(cstring(result), size) != size:
|
||||||
raise newException(EInvalidReply, "recv failed")
|
raise newException(EInvalidReply, "recv failed")
|
||||||
|
|
||||||
proc parseBulk(r: TRedis, allowMBNil = False): TRedisString =
|
proc parseSingle(r: TRedis, line:string, allowMBNil = False): TRedisString =
|
||||||
var line = ""
|
|
||||||
r.socket.readLine(line.TaintedString)
|
|
||||||
|
|
||||||
# Error.
|
# Error.
|
||||||
if line[0] == '-':
|
if line[0] == '-':
|
||||||
raise newException(ERedis, strip(line))
|
raise newException(ERedis, strip(line))
|
||||||
|
|
@ -94,6 +95,9 @@ proc parseBulk(r: TRedis, allowMBNil = False): TRedisString =
|
||||||
if line == "*-1":
|
if line == "*-1":
|
||||||
return RedisNil
|
return RedisNil
|
||||||
|
|
||||||
|
if line == "+QUEUED" or line == "+OK" : # inside of a transaction (multi)
|
||||||
|
return nil
|
||||||
|
|
||||||
if line[0] != '$':
|
if line[0] != '$':
|
||||||
raiseInvalidReply('$', line[0])
|
raiseInvalidReply('$', line[0])
|
||||||
|
|
||||||
|
|
@ -104,18 +108,41 @@ proc parseBulk(r: TRedis, allowMBNil = False): TRedisString =
|
||||||
var s = r.socket.recv(numBytes+2)
|
var s = r.socket.recv(numBytes+2)
|
||||||
result = strip(s.string)
|
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 =
|
proc parseMultiBulk(r: TRedis): TRedisList =
|
||||||
var line = TaintedString""
|
var line = TaintedString""
|
||||||
r.socket.readLine(line)
|
r.socket.readLine(line)
|
||||||
|
|
||||||
if line.string[0] != '*':
|
if line == "+QUEUED": # inside of a transaction (multi)
|
||||||
raiseInvalidReply('*', line.string[0])
|
return nil
|
||||||
|
|
||||||
|
return r.parseMultiLines(line)
|
||||||
|
|
||||||
var numElems = parseInt(line.string.substr(1))
|
|
||||||
if numElems == -1: return nil
|
|
||||||
result = @[]
|
|
||||||
for i in 1..numElems:
|
|
||||||
result.add(r.parseBulk())
|
|
||||||
|
|
||||||
proc sendCommand(r: TRedis, cmd: string, args: varargs[string]) =
|
proc sendCommand(r: TRedis, cmd: string, args: varargs[string]) =
|
||||||
var request = "*" & $(1 + args.len()) & "\c\L"
|
var request = "*" & $(1 + args.len()) & "\c\L"
|
||||||
|
|
@ -722,6 +749,7 @@ proc discardMulti*(r: TRedis) =
|
||||||
proc exec*(r: TRedis): TRedisList =
|
proc exec*(r: TRedis): TRedisList =
|
||||||
## Execute all commands issued after MULTI
|
## Execute all commands issued after MULTI
|
||||||
r.sendCommand("EXEC")
|
r.sendCommand("EXEC")
|
||||||
|
|
||||||
return r.parseMultiBulk()
|
return r.parseMultiBulk()
|
||||||
|
|
||||||
proc multi*(r: TRedis) =
|
proc multi*(r: TRedis) =
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue