#TIL 22 - Enum Type with PostgreSQL and sqlx

Oct 22, 2021 · Dung Huynh

What

Implement custom Scan and Value methods for PostgreSQL enum types with sqlx.

Why

PostgreSQL returns enums as "{value1,value2}". Need parsing to convert to Go types.

How

type ProjectSector string
type ProjectSectors []ProjectSector

func parseEnumFormat(str []byte) string {
    if len(str) == 0 { return "" }
    return strings.Replace(string(str[1:len(str)-1]), "\"", "", -1)
}

func (ps *ProjectSector) Scan(val interface{}) error {
    if b, ok := val.([]byte); ok {
        *ps = ProjectSector(parseEnumFormat(b))
        return nil
    }
    return fmt.Errorf("unsupported type: %T", val)
}

func (ps *ProjectSectors) Scan(val interface{}) error {
    if val == nil { *ps = []ProjectSector{}; return }
    parts := strings.Split(parseEnumFormat(val.([]byte)), ",")
    for _, p := range parts {
        *ps = append(*ps, ProjectSector(p))
    }
    return nil
}

func (ps ProjectSectors) Value() (driver.Value, error) {
    if ps == nil { return "", nil }
    return fmt.Sprintf(`{%s}`, ps), nil
}