diff options
author | Thomas Boerger <thomas@webhippie.de> | 2016-11-03 23:16:01 +0100 |
---|---|---|
committer | Thomas Boerger <thomas@webhippie.de> | 2016-11-04 08:43:11 +0100 |
commit | 1ebb35b98889ff77299f24d82da426b434b0cca0 (patch) | |
tree | 6dcb814d6df4d11c7e7a0ba6da8a6945628e2c5d /vendor/gopkg.in/redis.v2/multi.go | |
parent | 78f86abba45cb35018c58b8bd5f4c48a86cc8634 (diff) | |
download | gitea-1ebb35b98889ff77299f24d82da426b434b0cca0.tar.gz gitea-1ebb35b98889ff77299f24d82da426b434b0cca0.zip |
Added all required dependencies
Diffstat (limited to 'vendor/gopkg.in/redis.v2/multi.go')
-rw-r--r-- | vendor/gopkg.in/redis.v2/multi.go | 138 |
1 files changed, 138 insertions, 0 deletions
diff --git a/vendor/gopkg.in/redis.v2/multi.go b/vendor/gopkg.in/redis.v2/multi.go new file mode 100644 index 0000000000..bff38dfaaa --- /dev/null +++ b/vendor/gopkg.in/redis.v2/multi.go @@ -0,0 +1,138 @@ +package redis + +import ( + "errors" + "fmt" +) + +var errDiscard = errors.New("redis: Discard can be used only inside Exec") + +// Not thread-safe. +type Multi struct { + *Client +} + +func (c *Client) Multi() *Multi { + return &Multi{ + Client: &Client{ + baseClient: &baseClient{ + opt: c.opt, + connPool: newSingleConnPool(c.connPool, true), + }, + }, + } +} + +func (c *Multi) Close() error { + if err := c.Unwatch().Err(); err != nil { + return err + } + return c.Client.Close() +} + +func (c *Multi) Watch(keys ...string) *StatusCmd { + args := append([]string{"WATCH"}, keys...) + cmd := NewStatusCmd(args...) + c.Process(cmd) + return cmd +} + +func (c *Multi) Unwatch(keys ...string) *StatusCmd { + args := append([]string{"UNWATCH"}, keys...) + cmd := NewStatusCmd(args...) + c.Process(cmd) + return cmd +} + +func (c *Multi) Discard() error { + if c.cmds == nil { + return errDiscard + } + c.cmds = c.cmds[:1] + return nil +} + +// Exec always returns list of commands. If transaction fails +// TxFailedErr is returned. Otherwise Exec returns error of the first +// failed command or nil. +func (c *Multi) Exec(f func() error) ([]Cmder, error) { + c.cmds = []Cmder{NewStatusCmd("MULTI")} + if err := f(); err != nil { + return nil, err + } + c.cmds = append(c.cmds, NewSliceCmd("EXEC")) + + cmds := c.cmds + c.cmds = nil + + if len(cmds) == 2 { + return []Cmder{}, nil + } + + cn, err := c.conn() + if err != nil { + setCmdsErr(cmds[1:len(cmds)-1], err) + return cmds[1 : len(cmds)-1], err + } + + err = c.execCmds(cn, cmds) + if err != nil { + c.freeConn(cn, err) + return cmds[1 : len(cmds)-1], err + } + + c.putConn(cn) + return cmds[1 : len(cmds)-1], nil +} + +func (c *Multi) execCmds(cn *conn, cmds []Cmder) error { + err := c.writeCmd(cn, cmds...) + if err != nil { + setCmdsErr(cmds[1:len(cmds)-1], err) + return err + } + + statusCmd := NewStatusCmd() + + // Omit last command (EXEC). + cmdsLen := len(cmds) - 1 + + // Parse queued replies. + for i := 0; i < cmdsLen; i++ { + if err := statusCmd.parseReply(cn.rd); err != nil { + setCmdsErr(cmds[1:len(cmds)-1], err) + return err + } + } + + // Parse number of replies. + line, err := readLine(cn.rd) + if err != nil { + setCmdsErr(cmds[1:len(cmds)-1], err) + return err + } + if line[0] != '*' { + err := fmt.Errorf("redis: expected '*', but got line %q", line) + setCmdsErr(cmds[1:len(cmds)-1], err) + return err + } + if len(line) == 3 && line[1] == '-' && line[2] == '1' { + setCmdsErr(cmds[1:len(cmds)-1], TxFailedErr) + return TxFailedErr + } + + var firstCmdErr error + + // Parse replies. + // Loop starts from 1 to omit MULTI cmd. + for i := 1; i < cmdsLen; i++ { + cmd := cmds[i] + if err := cmd.parseReply(cn.rd); err != nil { + if firstCmdErr == nil { + firstCmdErr = err + } + } + } + + return firstCmdErr +} |