Building a map of maps from database query

I am trying to convert each row of a database query into a map[string] interface{} (which ive defined as type obj). I then want to create a map[interface{}] obj which is a map from primary key value to the obj for that particular row (which ive defined as type objs). Im getting a problem when I try to add the obj to the objs map : ‘hash of unhashable type’. I cant see what im doing wrong here…

type field interface{}
type object map[string]field
type objects map[field]object

func DbQuery2(params dbparams, key string, query string, args …interface{}) (objects, error) {
dbinfo := fmt.Sprintf(“user=%s password=%s host=%s dbname=%s sslmode=disable”,
params.username, params.password, params.hostname, params.database)

db, e := sql.Open("postgres", dbinfo)
check(e)
defer db.Close()

rows, e := db.Query(query, args...)
check(e)

names, e := rows.Columns()
check(e)

keyIndex := indexOf(key, names)
if keyIndex < 0 {
	return nil, fmt.Errorf("Primary key field '%s' not found in list of columns '%v'", key, names)
}

cols := len(names)
objs := make(objects)

for rows.Next() {
	vals := make([]interface{}, cols)
	pvals := make([]interface{}, cols)
	for i := range vals {
		pvals[i] = &vals[i]
	}
	e := rows.Scan(pvals...)
	check(e)

	obj := make(object)
	for i, name := range names {
		obj[name] = vals[i]
	}
	objs[vals[keyIndex]] = obj <--- hash of unhashable type
}

return objs, nil

}

P.S. my types are defined as :slight_smile:

type field interface{}
type object map[string]field
type objects map[field]object

Think Ive figured this out. The key field im adding to the map is a []uint8, so I do a type coercion step on each field using a type switch, converting it to a string. Code now looks like this

func coerce(value interface{}) interface{} {
switch value.(type) {
case []uint8:
return fmt.Sprintf("%s", value)
default:
return value
}
}

type field interface{}
type object map[string]field
type objects map[field]object

func DbQuery2(params dbparams, key string, query string, args …interface{}) (objects, error) {
dbinfo := fmt.Sprintf(“user=%s password=%s host=%s dbname=%s sslmode=disable”,
params.username, params.password, params.hostname, params.database)

db, e := sql.Open("postgres", dbinfo)
check(e)
defer db.Close()

rows, e := db.Query(query, args...)
check(e)

names, e := rows.Columns()
check(e)

cols := len(names)
objs := make(objects)

for rows.Next() {
	vals := make([]interface{}, cols)
	pvals := make([]interface{}, cols)
	for i := range vals {
		pvals[i] = &vals[i]
	}

	e := rows.Scan(pvals...)
	check(e)

	obj := make(object)
	for i, name := range names {
		obj[name] = coerce(vals[i])
	}
	objs[obj[key]] = obj
}

return objs, nil

}

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.