I'm using go-pg to write a custom query cache system that takes a query arguments that are passed to Query function and generates a hash key that is used for Redis. I'm using Go's reflect to check the argument types which works, until I use pg.Array as a passed argument.
Reflect gives me reflect.Ptr, but how do I extract the pointer's struct/Array when the switch case block is called?
func GenerateQueryCacheKey(args ...interface{}) string {
var argumentString = ""
for _, arg := range args {
v := reflect.ValueOf(arg)
switch v.Kind() {
case reflect.Array, reflect.Slice:
ret := make([]interface{}, v.Len())
for i := 0; i < v.Len(); i++ {
ret[i] = v.Index(i).Interface()
}
GenerateQueryCacheKey(ret...)
case reflect.Bool:
argumentString += strconv.FormatBool(v.Bool())
case reflect.String:
argumentString += v.String()
case reflect.Int:
argumentString += string(v.Int())
case reflect.Uint:
argumentString += string(v.Uint())
case reflect.Float32:
argumentString += strconv.FormatFloat(v.Float(), 'E', -1, 32)
case reflect.Invalid:
log.Printf("Invalid type handle! " + fmt.Sprintf("%T", arg))
argumentString += "nil"
case reflect.Ptr:
p := v.Elem()
ret := make([]interface{}, p.Len())
for i := 0; i < p.Len(); i++ {
ret[i] = p.Index(i).Interface()
}
GenerateQueryCacheKey(ret...)
default:
log.Printf("Unhandled reflect type supplied! " + fmt.Sprintf("%T %T", arg, v))
argumentString += "nil"
}
}
h := md5.New()
io.WriteString(h, argumentString)
return fmt.Sprintf("%x", h.Sum(nil))
}
pg.Array definition: https://sourcegraph.com/github.com/lib/pq/-/blob/array.go#L29:6
EDIT: The link posted has the incorrect definition of pg.Array. I accidentally grabbed the wrong library from sourcegraph.com.