summaryrefslogtreecommitdiff
path: root/model/mysql/jobs.go
diff options
context:
space:
mode:
Diffstat (limited to 'model/mysql/jobs.go')
-rw-r--r--model/mysql/jobs.go202
1 files changed, 202 insertions, 0 deletions
diff --git a/model/mysql/jobs.go b/model/mysql/jobs.go
new file mode 100644
index 0000000..d5abb1b
--- /dev/null
+++ b/model/mysql/jobs.go
@@ -0,0 +1,202 @@
+package mysql
+
+import (
+ "database/sql"
+ "fmt"
+ "kch42.de/gostuff/mailremind/chronos"
+ "kch42.de/gostuff/mailremind/model"
+ "log"
+ "time"
+)
+
+type Job struct {
+ con *MySQLDBCon
+
+ id DBID
+ user DBID
+ subject string
+ content []byte
+ next time.Time
+ chron []chronos.Chronos
+}
+
+func jobFromSQL(con *MySQLDBCon, s scanner) (*Job, error) {
+ var _id, _user uint64
+ var subject string
+ var content []byte
+ var _next int64
+ var _mchron string
+
+ if err := s.Scan(&_id, &_user, &subject, &content, &_next, &_mchron); err != nil {
+ return nil, err
+ }
+
+ chron, err := chronos.ParseMultiChronos(_mchron)
+ if err != nil {
+ return nil, err
+ }
+
+ return &Job{
+ con: con,
+ id: DBID(_id),
+ user: DBID(_user),
+ subject: subject,
+ content: content,
+ next: time.Unix(_next, 0),
+ chron: chron,
+ }, nil
+}
+
+func (u *User) CountJobs() (c int) {
+ row := u.con.stmt[qCountJobs].QueryRow(uint64(u.id))
+ if err := row.Scan(&c); err != nil {
+ log.Printf("Failed counting user's (%d) jobs: %s", u.id, err)
+ c = 0
+ }
+ return
+}
+
+func (u *User) Jobs() []model.Job {
+ rows, err := u.con.stmt[qJobsOfUser].Query(uint64(u.id))
+ if err != nil {
+ log.Printf("Failed getting jobs of user %d: %s", u.id, err)
+ return nil
+ }
+
+ jobs := make([]model.Job, 0)
+ for rows.Next() {
+ job, err := jobFromSQL(u.con, rows)
+ if err != nil {
+ log.Printf("Failed getting all jobs of user %d: %s", u.id, err)
+ break
+ }
+ jobs = append(jobs, job)
+ }
+
+ return jobs
+}
+
+func (u *User) JobByID(_id model.DBID) (model.Job, error) {
+ id := _id.(DBID)
+
+ row := u.con.stmt[qJobFromUserAndID].QueryRow(uint64(u.id), uint64(id))
+ switch job, err := jobFromSQL(u.con, row); err {
+ case nil:
+ return job, nil
+ case sql.ErrNoRows:
+ return nil, model.NotFound
+ default:
+ return nil, err
+ }
+}
+
+func (u *User) AddJob(subject string, content []byte, chron chronos.MultiChronos, next time.Time) (model.Job, error) {
+ tx, err := u.con.con.Begin()
+ if err != nil {
+ return nil, err
+ }
+
+ insjob := tx.Stmt(u.con.stmt[qInsertJob])
+
+ res, err := insjob.Exec(uint64(u.id), subject, content, next.Unix(), chron.String())
+ 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 &Job{
+ con: u.con,
+ id: DBID(_id),
+ user: u.id,
+ subject: subject,
+ content: content,
+ next: next,
+ chron: chron,
+ }, nil
+}
+
+func (j *Job) ID() model.DBID { return j.id }
+func (j *Job) Subject() string { return j.subject }
+func (j *Job) Content() []byte { return j.content }
+func (j *Job) Chronos() chronos.MultiChronos { return j.chron }
+func (j *Job) Next() time.Time { return j.next }
+
+func (j *Job) User() model.User {
+ u, err := j.con.UserByID(j.user)
+ if err != nil {
+ // TODO: Should we really panic here? If yes, we need to recover panics!
+ panic(fmt.Errorf("Could not get user (%d) of Job %d: %s", j.user, j.id, err))
+ }
+
+ return u
+}
+
+func (j *Job) SetSubject(sub string) error {
+ if _, err := j.con.stmt[qSetSubject].Exec(sub, uint64(j.id)); err != nil {
+ return err
+ }
+
+ j.subject = sub
+ return nil
+}
+
+func (j *Job) SetContent(cont []byte) error {
+ if _, err := j.con.stmt[qSetContent].Exec(cont, uint64(j.id)); err != nil {
+ return err
+ }
+
+ j.content = cont
+ return nil
+}
+
+func (j *Job) SetChronos(chron chronos.MultiChronos) error {
+ if _, err := j.con.stmt[qSetChronos].Exec(chron.String(), uint64(j.id)); err != nil {
+ return err
+ }
+
+ j.chron = chron
+ return nil
+}
+
+func (j *Job) SetNext(next time.Time) error {
+ if _, err := j.con.stmt[qSetNext].Exec(next.Unix(), uint64(j.id)); err != nil {
+ return err
+ }
+
+ j.next = next
+ return nil
+}
+
+func (j *Job) Delete() error {
+ _, err := j.con.stmt[qDelJob].Exec(j.id)
+ return err
+}
+
+func (con *MySQLDBCon) JobsBefore(t time.Time) []model.DBID {
+ rows, err := con.stmt[qJobsBefore].Query(t.Unix())
+ if err != nil {
+ log.Fatalf("Could not get jobs before %s: %s", t, err) // TODO: Really fatal?
+ }
+
+ ids := make([]model.DBID, 0)
+ for rows.Next() {
+ var _id uint64
+ if err := rows.Scan(&_id); err != nil {
+ log.Printf("Could not get all jobs before %s: %s", t, err)
+ break
+ }
+ ids = append(ids, DBID(_id))
+ }
+
+ return ids
+}