package common import ( "database/sql" qgen "git.tuxpa.in/a/gosora/query_gen" ) var Emails EmailStore type Email struct { UserID int Email string Validated bool Primary bool Token string } type EmailStore interface { // TODO: Add an autoincrement key Get(u *User, email string) (Email, error) GetEmailsByUser(u *User) (emails []Email, err error) Add(uid int, email, token string) error Delete(uid int, email string) error VerifyEmail(email string) error } type DefaultEmailStore struct { get *sql.Stmt getEmailsByUser *sql.Stmt add *sql.Stmt delete *sql.Stmt verifyEmail *sql.Stmt } func NewDefaultEmailStore(acc *qgen.Accumulator) (*DefaultEmailStore, error) { e := "emails" return &DefaultEmailStore{ get: acc.Select(e).Columns("email,validated,token").Where("uid=? AND email=?").Prepare(), getEmailsByUser: acc.Select(e).Columns("email,validated,token").Where("uid=?").Prepare(), add: acc.Insert(e).Columns("uid,email,validated,token").Fields("?,?,?,?").Prepare(), delete: acc.Delete(e).Where("uid=? AND email=?").Prepare(), // Need to fix this: Empty string isn't working, it gets set to 1 instead x.x -- Has this been fixed? verifyEmail: acc.Update(e).Set("validated=1,token=''").Where("email=?").Prepare(), }, acc.FirstError() } func (s *DefaultEmailStore) Get(user *User, email string) (Email, error) { e := Email{UserID: user.ID, Primary: email != "" && user.Email == email} err := s.get.QueryRow(user.ID, email).Scan(&e.Email, &e.Validated, &e.Token) return e, err } func (s *DefaultEmailStore) GetEmailsByUser(user *User) (emails []Email, err error) { e := Email{UserID: user.ID} rows, err := s.getEmailsByUser.Query(user.ID) if err != nil { return emails, err } defer rows.Close() for rows.Next() { err := rows.Scan(&e.Email, &e.Validated, &e.Token) if err != nil { return emails, err } if e.Email == user.Email { e.Primary = true } emails = append(emails, e) } return emails, rows.Err() } func (s *DefaultEmailStore) Add(uid int, email, token string) error { email = CanonEmail(SanitiseSingleLine(email)) _, err := s.add.Exec(uid, email, 0, token) return err } func (s *DefaultEmailStore) Delete(uid int, email string) error { _, err := s.delete.Exec(uid, email) return err } func (s *DefaultEmailStore) VerifyEmail(email string) error { email = CanonEmail(SanitiseSingleLine(email)) _, err := s.verifyEmail.Exec(email) return err }