github.com/dhax/go-base@v0.0.0-20231004214136-8be7e5c1972b/database/admAccountStore.go (about) 1 package database 2 3 import ( 4 "errors" 5 "net/url" 6 7 "github.com/dhax/go-base/auth/jwt" 8 "github.com/dhax/go-base/auth/pwdless" 9 "github.com/dhax/go-base/models" 10 "github.com/go-pg/pg" 11 "github.com/go-pg/pg/orm" 12 "github.com/go-pg/pg/urlvalues" 13 ) 14 15 var ( 16 // ErrUniqueEmailConstraint provides error message for already registered email address. 17 ErrUniqueEmailConstraint = errors.New("email already registered") 18 // ErrBadParams could not parse params to filter 19 ErrBadParams = errors.New("bad parameters") 20 ) 21 22 // AdmAccountStore implements database operations for account management by admin. 23 type AdmAccountStore struct { 24 db *pg.DB 25 } 26 27 // NewAdmAccountStore returns an AccountStore. 28 func NewAdmAccountStore(db *pg.DB) *AdmAccountStore { 29 return &AdmAccountStore{ 30 db: db, 31 } 32 } 33 34 // AccountFilter provides pagination and filtering options on accounts. 35 type AccountFilter struct { 36 Pager *urlvalues.Pager 37 Filter *urlvalues.Filter 38 Order []string 39 } 40 41 // NewAccountFilter returns an AccountFilter with options parsed from request url values. 42 func NewAccountFilter(params interface{}) (*AccountFilter, error) { 43 v, ok := params.(url.Values) 44 if !ok { 45 return nil, ErrBadParams 46 } 47 p := urlvalues.Values(v) 48 f := &AccountFilter{ 49 Pager: urlvalues.NewPager(p), 50 Filter: urlvalues.NewFilter(p), 51 Order: p["order"], 52 } 53 return f, nil 54 } 55 56 // Apply applies an AccountFilter on an orm.Query. 57 func (f *AccountFilter) Apply(q *orm.Query) (*orm.Query, error) { 58 q = q.Apply(f.Pager.Pagination) 59 q = q.Apply(f.Filter.Filters) 60 q = q.Order(f.Order...) 61 return q, nil 62 } 63 64 // List applies a filter and returns paginated array of matching results and total count. 65 func (s *AdmAccountStore) List(f *AccountFilter) ([]pwdless.Account, int, error) { 66 a := []pwdless.Account{} 67 count, err := s.db.Model(&a). 68 Apply(f.Apply). 69 SelectAndCount() 70 if err != nil { 71 return nil, 0, err 72 } 73 return a, count, nil 74 } 75 76 // Create creates a new account. 77 func (s *AdmAccountStore) Create(a *pwdless.Account) error { 78 count, _ := s.db.Model(a). 79 Where("email = ?email"). 80 Count() 81 82 if count != 0 { 83 return ErrUniqueEmailConstraint 84 } 85 86 err := s.db.RunInTransaction(func(tx *pg.Tx) error { 87 err := tx.Insert(a) 88 if err != nil { 89 return err 90 } 91 p := &models.Profile{ 92 AccountID: a.ID, 93 } 94 return tx.Insert(p) 95 }) 96 97 return err 98 } 99 100 // Get account by ID. 101 func (s *AdmAccountStore) Get(id int) (*pwdless.Account, error) { 102 a := pwdless.Account{ID: id} 103 err := s.db.Select(&a) 104 return &a, err 105 } 106 107 // Update account. 108 func (s *AdmAccountStore) Update(a *pwdless.Account) error { 109 err := s.db.Update(a) 110 return err 111 } 112 113 // Delete account. 114 func (s *AdmAccountStore) Delete(a *pwdless.Account) error { 115 err := s.db.RunInTransaction(func(tx *pg.Tx) error { 116 if _, err := tx.Model(&jwt.Token{}). 117 Where("account_id = ?", a.ID). 118 Delete(); err != nil { 119 return err 120 } 121 if _, err := tx.Model(&models.Profile{}). 122 Where("account_id = ?", a.ID). 123 Delete(); err != nil { 124 return err 125 } 126 return tx.Delete(a) 127 }) 128 return err 129 }