summaryrefslogtreecommitdiff
path: root/model/mysql/users.go
diff options
context:
space:
mode:
Diffstat (limited to 'model/mysql/users.go')
-rw-r--r--model/mysql/users.go181
1 files changed, 181 insertions, 0 deletions
diff --git a/model/mysql/users.go b/model/mysql/users.go
new file mode 100644
index 0000000..f07f472
--- /dev/null
+++ b/model/mysql/users.go
@@ -0,0 +1,181 @@
+package mysql
+
+import (
+ "database/sql"
+ "kch42.de/gostuff/mailremind/model"
+ "log"
+ "time"
+)
+
+type User struct {
+ con *MySQLDBCon
+
+ id DBID
+ email, passwd, acCode string
+ location *time.Location
+ added time.Time
+ active bool
+}
+
+func userFromSQL(con *MySQLDBCon, s scanner) (*User, error) {
+ var id uint64
+ var added int64
+ var email, passwd, _loc, acCode string
+ var active int
+
+ switch err := s.Scan(&id, &email, &passwd, &_loc, &active, &acCode, &added); err {
+ case nil:
+ case sql.ErrNoRows:
+ return nil, model.NotFound
+ default:
+ return nil, err
+ }
+
+ user := &User{
+ con: con,
+ id: DBID(id),
+ email: email,
+ passwd: passwd,
+ acCode: acCode,
+ added: time.Unix(added, 0),
+ active: i2b(active),
+ }
+
+ loc, err := time.LoadLocation(_loc)
+ if err != nil {
+ loc = time.UTC
+ }
+ user.location = loc
+
+ return user, nil
+}
+
+func (con *MySQLDBCon) UserByID(_id model.DBID) (model.User, error) {
+ id := _id.(DBID)
+
+ row := con.stmt[qUserByID].QueryRow(uint64(id))
+ return userFromSQL(con, row)
+}
+
+func (con *MySQLDBCon) UserByMail(email string) (model.User, error) {
+ row := con.stmt[qUserByEmail].QueryRow(email)
+ return userFromSQL(con, row)
+}
+
+func (u *User) ID() model.DBID { return u.id }
+func (u *User) Email() string { return u.email }
+func (u *User) PWHash() []byte { return []byte(u.PWHash()) }
+func (u *User) Active() bool { return u.active }
+func (u *User) ActivationCode() string { return u.acCode }
+
+func (u *User) SetPWHash(_pwhash []byte) error {
+ pwhash := string(_pwhash)
+
+ if _, err := u.con.stmt[qSetPWHash].Query(pwhash, uint64(u.id)); err != nil {
+ return err
+ }
+
+ u.passwd = string(_pwhash)
+ return nil
+}
+
+func (u *User) SetActive(b bool) error {
+ if _, err := u.con.stmt[qSetActive].Query(b2i(b), uint64(u.id)); err != nil {
+ return err
+ }
+
+ u.active = b
+ return nil
+}
+
+func (u *User) SetActivationCode(c string) error {
+ if _, err := u.con.stmt[qSetAcCode].Query(c, uint64(u.id)); err != nil {
+ return err
+ }
+
+ u.acCode = c
+ return nil
+}
+
+func (u *User) Delete() error {
+ tx, err := u.con.con.Begin()
+ if err != nil {
+ return err
+ }
+
+ id := uint64(u.id)
+
+ deljobs := tx.Stmt(u.con.stmt[qDelUsersJobs])
+ deluser := tx.Stmt(u.con.stmt[qDelUser])
+
+ if _, err := deljobs.Query(id); err != nil {
+ return rollbackAfterFail(err, tx)
+ }
+
+ if _, err := deluser.Query(id); err != nil {
+ return rollbackAfterFail(err, tx)
+ }
+
+ return tx.Commit()
+}
+
+func (con *MySQLDBCon) InactiveUsers(olderthan time.Time) []model.DBID {
+ ids := make([]model.DBID, 0)
+
+ rows, err := con.stmt[qGetOldInactiveUsers].Query(olderthan.Unix())
+ if err != nil {
+ log.Printf("Failed to get old, inactive users: %s", err)
+ return ids
+ }
+
+ for rows.Next() {
+ var _id uint64
+
+ if err := rows.Scan(&_id); err != nil {
+ log.Printf("Failed to get old, inactive users: %s", err)
+ return ids
+ }
+
+ ids = append(ids, DBID(_id))
+ }
+
+ return ids
+}
+
+func (con *MySQLDBCon) AddUser(email string, pwhash []byte, location *time.Location, active bool, acCode string) (model.User, error) {
+ now := time.Now()
+
+ tx, err := con.con.Begin()
+ if err != nil {
+ return nil, err
+ }
+
+ insjob := tx.Stmt(con.stmt[qInsertUser])
+
+ res, err := insjob.Exec(email, string(pwhash), location.String(), b2i(active), acCode, now.Unix())
+ if err != nil {
+ tx.Rollback()
+ return nil, err
+ }
+
+ _id, err := res.LastInsertId()
+ if err != nil {
+ tx.Rollback()
+ return nil, err
+ }
+
+ if err := tx.Commit(); err != nil {
+ return nil, err
+ }
+
+ return &User{
+ con: con,
+ id: DBID(_id),
+ email: email,
+ passwd: string(pwhash),
+ acCode: acCode,
+ location: location,
+ added: now,
+ active: active,
+ }, nil
+}