Fix custom mail type conversion to citext

Signed-off-by: Sacha Al Himdani <sacha@getprobo.com>
This commit is contained in:
Sacha Al Himdani
2026-01-12 18:57:28 +01:00
parent 1a3249de66
commit 0fb281e0e9
2 changed files with 83 additions and 11 deletions

View File

@@ -31,17 +31,17 @@ import (
type (
People struct {
ID gid.GID `db:"id"`
OrganizationID gid.GID `db:"organization_id"`
Kind PeopleKind `db:"kind"`
FullName string `db:"full_name"`
PrimaryEmailAddress mail.Addr `db:"primary_email_address"`
AdditionalEmailAddresses []mail.Addr `db:"additional_email_addresses"`
Position *string `db:"position"`
ContractStartDate *time.Time `db:"contract_start_date"`
ContractEndDate *time.Time `db:"contract_end_date"`
CreatedAt time.Time `db:"created_at"`
UpdatedAt time.Time `db:"updated_at"`
ID gid.GID `db:"id"`
OrganizationID gid.GID `db:"organization_id"`
Kind PeopleKind `db:"kind"`
FullName string `db:"full_name"`
PrimaryEmailAddress mail.Addr `db:"primary_email_address"`
AdditionalEmailAddresses mail.Addrs `db:"additional_email_addresses"`
Position *string `db:"position"`
ContractStartDate *time.Time `db:"contract_start_date"`
ContractEndDate *time.Time `db:"contract_end_date"`
CreatedAt time.Time `db:"created_at"`
UpdatedAt time.Time `db:"updated_at"`
}
Peoples []*People

View File

@@ -92,3 +92,75 @@ func (a *Addr) UnmarshalJSON(data []byte) error {
func (a Addr) MarshalJSON() ([]byte, error) {
return json.Marshal(a.String())
}
type Addrs []Addr
func (a Addrs) Value() (driver.Value, error) {
if a == nil {
return nil, nil
}
if len(a) == 0 {
return "{}", nil
}
strs := make([]string, len(a))
for i, addr := range a {
strs[i] = addr.String()
}
return "{" + strings.Join(strs, ",") + "}", nil
}
func (a *Addrs) Scan(value any) error {
if value == nil {
*a = nil
return nil
}
var strs []string
switch v := value.(type) {
case []string:
strs = v
case []byte:
s := strings.Trim(string(v), "{}")
if s == "" {
strs = []string{}
} else {
strs = strings.Split(s, ",")
}
case string:
s := strings.Trim(v, "{}")
if s == "" {
strs = []string{}
} else {
strs = strings.Split(s, ",")
}
case []any:
strs = make([]string, len(v))
for i, elem := range v {
if elem == nil {
strs[i] = ""
continue
}
str, ok := elem.(string)
if !ok {
return fmt.Errorf("array element is not a string: %T", elem)
}
strs[i] = str
}
default:
return fmt.Errorf("cannot scan %T into Addrs", value)
}
*a = make([]Addr, len(strs))
for i, str := range strs {
if str == "" {
(*a)[i] = Nil
continue
}
parsed, err := ParseAddr(str)
if err != nil {
return fmt.Errorf("invalid email at index %d: %w", i, err)
}
(*a)[i] = parsed
}
return nil
}