mediocregopher / radix.v2

Redis client for Go
http://godoc.org/github.com/mediocregopher/radix.v2
MIT License
433 stars 92 forks source link

HDEL or HEXISTS on non-existing keys #49

Closed psuedowolf closed 7 years ago

psuedowolf commented 7 years ago

Hello,

I am using this redis go client for my application,

While doing a HGET on a non-existing field I am getting an error : "wrong-type" which means the field doesn't exist. value, err := client.Cmd("HGET",key,field).Str() However, a HDEL or HEXISTS returns no error. err := client.Cmd("HDEL", key, field).Err

in this case err is nil.

Am I understanding anything wrong?

mediocregopher commented 7 years ago

Hi there! What's happening is that you're using Str to attempt to retrieve the string value of the response, but for HGET if either the key or field aren't set then a Nil response is returned, which is a different type than string. So you can do:

r := client.Cmd("HGET", key, field)
if r.isType(redis.Nil) {
    // do something in this case
}
value, err := r.Str()
if err != nil {
    // do something in this case
}

If you find yourself doing that often and it becomes a pain you can write a little wrapper, something like:

func maybeStr(r *redis.Resp) (string, bool, error) {
    if !r.IsType(redis.Str) {
        return "", false, nil
    }
    s, err := r.Str()
    return s, true, err
}

val, ok, err := maybeStr(client.Cmd("HGET", key, field))

Hope this helps, let me know if you have any more questions!

psuedowolf commented 7 years ago

Thank you for explaining this,

while testing this HEXISTS command:

//check if key exists: 103 104 p := client.Cmd("HEXISTS", key, field) 105 if p.IsType(redis.Nil) { 106 //do something log.Println("key doesnt exist") 107 108 } else { 109 log.Println(p.Int) 110 111 }

Its not entering p.IsType(redis.Nil) though field doesnt exist.

On Tue, Nov 22, 2016 at 1:17 PM, Brian Picciano notifications@github.com wrote:

Hi there! What's happening is that you're using Str to attempt to retrieve the string value of the response, but for HGET if either the key or field aren't set then a Nil response is returned, which is a different type than string. So you can do:

r := client.Cmd("HGET", key, field) if r.isType(redis.Nil) { // do something in this case } value, err := r.Str() if err != nil { // do something in this case }

If you find yourself doing that often and it becomes a pain you can a little wrapper, something like:

func maybeStr(r *redis.Resp) (string, bool, error) { if !r.IsType(redis.Str) { return "", false, nil } s, err := r.Str() return s, true, err }

Hope this helps, let me know if you have any more questions!

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/mediocregopher/radix.v2/issues/49#issuecomment-262368361, or mute the thread https://github.com/notifications/unsubscribe-auth/AKFkPO6W0INEEd3zRHiuWipnG4Y0QDfCks5rA1wHgaJpZM4K58Ya .

mediocregopher commented 7 years ago

np! HEXISTS will return either a 0 or a 1, both Int types, to indicate existence of the key. So you can use the Int method for that one:

i, err := client.Cmd("HEXISTS", key, field)
if err != nil {
    // do something
}
exists := i == 1

If you check out the docs at http://redis.io/commands/hexists and related commands you can see the exact types that each command returns. The responses from client.Cmd will be directly mapped to those types, so if the docs say a command returns a Bulk String or Simple String you should use the Str method, if it returns an Integer then you should use the Int method, etc... Some commands will return two different types depending on circumstances (like GET and HGET), so in those cases you may have to use IsType to determine which you got.