package store import ( "strings" "github.com/oklog/ulid/v2" "github.com/rs/zerolog/log" "gorm.io/gorm" ) type UserAttribute struct { ID ulid.ULID `gorm:"primaryKey"` UserID ulid.ULID `gorm:"not null"` Value string `gorm:"not null"` db *gorm.DB `gorm:"-"` } func (UserAttribute) TableName() string { return UserAttributesTableName } func (u *User) AddAttribute(value string) error { value = strings.ToLower(value) if u.HasAttribute(value) { log.Debug().Str("attribute", value).Msg("attribute already exists") return nil } attribute := &UserAttribute{ UserID: u.ID, Value: value, db: u.db, } result := u.db.Create(attribute) if result.Error != nil { log.Error().Err(result.Error).Msg("unable to add user attribute") return result.Error } log.Debug(). Str("email", *u.Email). Str("attribute", value). Msg("user attribute added") return nil } func (u *User) DeleteAttribute(value string) error { value = strings.ToLower(value) result := u.db.Where("user_id = ? AND value = ?", u.ID, value).Delete(&UserAttribute{}) if result.Error != nil { log.Error().Err(result.Error).Msg("unable to delete user attribute") return result.Error } log.Debug(). Str("email", *u.Email). Str("attribute", value). Msg("user attribute deleted") return nil } func (u *User) HasAttribute(value string) bool { value = strings.ToLower(value) var count int64 result := u.db.Model(&UserAttribute{}).Where("user_id = ? AND value = ?", u.ID, value).Count(&count) if result.Error != nil { log.Error().Err(result.Error).Msg("unable to check user attribute") return false } return count > 0 } func (u *User) GetAttributes() ([]string, error) { var attributes []UserAttribute result := u.db.Where("user_id = ?", u.ID).Find(&attributes) if result.Error != nil { log.Error().Err(result.Error).Msg("unable to get user attributes") return nil, result.Error } var attributeValues []string for _, attr := range attributes { attributeValues = append(attributeValues, attr.Value) } return attributeValues, nil }