gosexy / redis

Redis client for Go that maps the full redis command list into equivalent Go functions.
MIT License
167 stars 44 forks source link

Using ZRevRange within a Multi block results in "Unsupported conversion: redis array to string" #17

Closed jeremyricharddavies closed 11 years ago

jeremyricharddavies commented 11 years ago

This code results in the error:

    self.redis.Multi()
    for i := 1; i <= max; i++ {
        s := compact[:i]
        self.redis.ZAdd("keywordlookup", 0, s)
    }
    self.redis.ZInterStore("keywordmatch", 2, "keywordlookup", route)
    self.redis.ZRevRange("keywordmatch", 0, 0)
    res, err = self.redis.Exec()

If I execute the ZRevRange after the Exec everything is fine.

This is with the Master branch

jeremyricharddavies commented 11 years ago

Doing the above in redis-cli shows the actual redis output:

redis 127.0.0.1:6379> multi
OK
redis 127.0.0.1:6379> zadd keywordlookup 0 H
QUEUED
redis 127.0.0.1:6379> zadd keywordlookup 0 HE
QUEUED
redis 127.0.0.1:6379> zadd keywordlookup 0 HEL
QUEUED
redis 127.0.0.1:6379> zadd keywordlookup 0 HELL
QUEUED
redis 127.0.0.1:6379> zadd keywordlookup 0 HELLO
QUEUED
redis 127.0.0.1:6379> zadd keywordlookup 0 HELLOT
QUEUED
redis 127.0.0.1:6379> zadd keywordlookup 0 HELLOTH
QUEUED
redis 127.0.0.1:6379> zinterstore keywordmatch 2 keywordlookup 89245
QUEUED
redis 127.0.0.1:6379> zrevrange keywordmatch 0 0
QUEUED
redis 127.0.0.1:6379> exec
1) (integer) 1
2) (integer) 1
3) (integer) 1
4) (integer) 1
5) (integer) 1
6) (integer) 1
7) (integer) 1
8) (integer) 1
9) 1) "HELLO"
redis 127.0.0.1:6379>
xiam commented 11 years ago

Confirmed, Exec fails because it can't handle 9). Looking into it.

xiam commented 11 years ago

The redis.Exec return value had to be changed from ([]string, error) to ([]interface{}, error).

Could you please update and try again?

Thanks!

jeremyricharddavies commented 11 years ago

Hi

Yes, I can confirm that it works now. Thanks!

My only issue now is how to extract the underlying string value from the response at 9).

fmt will print it out nicely, but trying to use reflection to get at the value is proving slightly more taxing. I can get the Len() of the slice (1) but not the string "HELLO".

xiam commented 11 years ago

If you have to deal with interface{} values, besides reflect, you could use v.(type), on a switch like this:

switch v := el.(type) {
  case int:
  ...
  case string: 
  ...
}

I've added an example, please see: https://github.com/gosexy/redis/blob/228b80f3602fa0540cb55aa439631b33b1b7b4f7/_examples/test-multi-exec/main.go

Output should be:

2013/09/30 12:26:50 Got value of kind int64 (1), we convert it to string: 1
2013/09/30 12:26:50 Got value of kind int64 (1), we convert it to string: 1
2013/09/30 12:26:50 Got value of kind int64 (1), we convert it to string: 1
2013/09/30 12:26:50 Got value of kind int64 (1), we convert it to string: 1
2013/09/30 12:26:50 Got value of kind int64 (1), we convert it to string: 1
2013/09/30 12:26:50 Got value of kind int64 (1), we convert it to string: 1
2013/09/30 12:26:50 Got value of kind int64 (1), we convert it to string: 1
2013/09/30 12:26:50 Got value of kind int64 (1), we convert it to string: 1
2013/09/30 12:26:50 Got value of kind int64 (1), we convert it to string: 1
2013/09/30 12:26:50 Got value of kind int64 (1), we convert it to string: 1
2013/09/30 12:26:50 Got value of kind int64 (1), we convert it to string: 1
2013/09/30 12:26:50 Got value of kind int64 (1), we convert it to string: 1
2013/09/30 12:26:50 Got value of kind int64 (5), we convert it to string: 5
2013/09/30 12:26:50 Got []interface{}
2013/09/30 12:26:50 Value at index 0 (HELLO) has kind string, we convert it to string: HELLO

Please feel free to comment over this issue, if this solution is not appropriate we could search for one :-).

jeremyricharddavies commented 11 years ago

Thanks, that has helped. I should have thought to use your to package!