/
task-dao-mongo.go
158 lines (128 loc) · 3.87 KB
/
task-dao-mongo.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
package dao
import (
"github.com/Sfeir/golang-200/model"
"github.com/satori/go.uuid"
logger "github.com/sirupsen/logrus"
"gopkg.in/mgo.v2"
"gopkg.in/mgo.v2/bson"
)
// compilation time interface check
var _ TaskDAO = (*TaskDAOMongo)(nil)
const (
collection = "tasks"
index = "id"
)
// TaskDAOMongo is the mongo implementation of the TaskDAO
type TaskDAOMongo struct {
session *mgo.Session
}
// NewTaskDAOMongo creates a new TaskDAO mongo implementation
func NewTaskDAOMongo(session *mgo.Session) TaskDAO {
// create index
err := session.DB("").C(collection).EnsureIndex(mgo.Index{
Key: []string{index},
Unique: true,
DropDups: true,
Background: true,
Sparse: true,
})
if err != nil {
logger.WithField("error", err).Warn("mongo db connection")
}
return &TaskDAOMongo{
session: session,
}
}
// GetByID returns a task by its ID
func (s *TaskDAOMongo) GetByID(ID string) (*model.Task, error) {
// check ID
if _, err := uuid.FromString(ID); err != nil {
return nil, ErrInvalidUUID
}
session := s.session.Copy()
defer session.Close()
task := model.Task{}
c := session.DB("").C(collection)
err := c.Find(bson.M{"id": ID}).One(&task)
// if no result found wrap with dao known error
if err != nil && err == mgo.ErrNotFound {
return nil, ErrNotFound
}
return &task, err
}
// getAllTasksByQuery returns tasks by query and paging capability
func (s *TaskDAOMongo) getAllTasksByQuery(query interface{}, start, end int) ([]model.Task, error) {
session := s.session.Copy()
defer session.Close()
c := session.DB("").C(collection)
// check param
hasPaging := start > NoPaging && end > NoPaging && end >= start
// perform request
var err error
var tasks []model.Task
if hasPaging {
err = c.Find(query).Skip(start).Limit(end - start + 1).All(&tasks)
} else {
err = c.Find(query).All(&tasks)
}
// if no result found wrap with dao known error
if err != nil && err == mgo.ErrNotFound {
return nil, ErrNotFound
}
return tasks, err
}
// GetAll returns all tasks with paging capability
func (s *TaskDAOMongo) GetAll(start, end int) ([]model.Task, error) {
return s.getAllTasksByQuery(nil, start, end)
}
// GetByTitle returns all tasks by title
func (s *TaskDAOMongo) GetByTitle(title string) ([]model.Task, error) {
return s.getAllTasksByQuery(bson.M{"title": title}, NoPaging, NoPaging)
}
// GetByStatus returns all tasks by status
func (s *TaskDAOMongo) GetByStatus(status model.TaskStatus) ([]model.Task, error) {
return s.getAllTasksByQuery(bson.M{"status": status}, NoPaging, NoPaging)
}
// GetByStatusAndPriority returns all tasks by status and priority
func (s *TaskDAOMongo) GetByStatusAndPriority(status model.TaskStatus, priority model.TaskPriority) ([]model.Task, error) {
return s.getAllTasksByQuery(bson.M{"status": status, "priority": priority}, NoPaging, NoPaging)
}
// Save saves the task
func (s *TaskDAOMongo) Save(task *model.Task) error {
// check task has an ID, if not create one
if len(task.ID) == 0 {
task.ID = uuid.NewV4().String()
}
session := s.session.Copy()
defer session.Close()
c := session.DB("").C(collection)
return c.Insert(task)
}
// Upsert updates or creates a task, returns true if updated, false otherwise or on error
func (s *TaskDAOMongo) Upsert(task *model.Task) (bool, error) {
// check ID
// check task has an ID, if not create one
if len(task.ID) == 0 {
task.ID = uuid.NewV4().String()
}
session := s.session.Copy()
defer session.Close()
c := session.DB("").C(collection)
chg, err := c.Upsert(bson.M{"id": task.ID}, task)
if err != nil {
return false, err
}
return chg.Updated > 0, err
}
// Delete deletes a tasks by its ID
func (s *TaskDAOMongo) Delete(ID string) error {
// check ID
if _, err := uuid.FromString(ID); err != nil {
return ErrInvalidUUID
}
session := s.session.Copy()
defer session.Close()
c := session.DB("").C(collection)
err := c.Remove(bson.M{"id": ID})
return err
}