-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathdb.go
130 lines (118 loc) · 3.64 KB
/
db.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
package main
import (
"fmt"
"strings"
"github.com/jmoiron/sqlx"
_ "github.com/lib/pq"
)
// Store represents a data source.
type Store struct {
dsn string
db *sqlx.DB
}
// NewStore creates a new Store.
func NewStore(dsn string) *Store {
return &Store{dsn, nil}
}
// Connect connects to the database.
func (s *Store) Connect() (err error) {
s.db, err = sqlx.Connect("postgres", s.dsn)
return
}
// Events returns an EventsCollection. Events are filtered to match users and keywords.
func (s *Store) Events(users, keywords []string) (events EventsCollection, err error) {
var (
userpos, kwpos []string
userq, kwq string
params []interface{}
pos int
)
for _, user := range users {
pos += 1
params = append(params, user)
userpos = append(userpos, fmt.Sprintf("c.login = $%d", pos))
}
if len(userpos) > 0 {
userq = fmt.Sprintf("AND (%s)", strings.Join(userpos, " OR "))
}
for _, kw := range keywords {
pos += 1
params = append(params, "%"+kw+"%")
kwpos = append(kwpos, fmt.Sprintf("e.title ILIKE $%d", pos))
}
if len(kwpos) > 0 {
kwq = fmt.Sprintf("AND (%s)", strings.Join(kwpos, " OR "))
}
q := fmt.Sprintf(`WITH RECURSIVE logins(n) AS (
SELECT c.company_id AS n
FROM company c,
date_company_assignment dc,
events
WHERE c.company_id = dc.company_id
AND c.is_team = 1
AND dc.date_id = events.date_id
UNION ALL
SELECT c.company_id
FROM company c,
logins,
company_assignment ca
WHERE c.company_id = ca.sub_company_id
AND logins.n = ca.company_id
%s
), events AS (
SELECT ((((d.start_date AT TIME ZONE 'UTC')::timestamp without time zone)::timestamp with time zone) AT TIME ZONE 'UTC') AS start_date,
((((d.end_date AT TIME ZONE 'UTC')::timestamp without time zone)::timestamp with time zone) AT TIME ZONE 'UTC') AS end_date,
((d.start_date AT TIME ZONE 'UTC')::time = '00:00:00'::time AND (d.end_date AT TIME ZONE 'UTC')::time = '23:59:00'::time) AS all_day,
d.date_id,
d.title,
di.comment,
d.location,
d.resource_names,
d.type,
d.apt_type,
d.access_team_id IS NULL AS is_private,
CASE WHEN c.firstname IS NULL AND c.name IS NULL
THEN c.description
ELSE (c.firstname || ' ' || c.name) END AS organizer_name,
cv.value_string AS organizer_email,
(SELECT array_agg(CASE WHEN c.firstname IS NULL AND c.name IS NULL
THEN c.description
ELSE (c.firstname || ' ' || c.name) END)
FROM company c,
date_company_assignment dc
WHERE d.date_id = dc.date_id
AND c.company_id = dc.company_id) AS attendees
FROM date_x d, date_info di, company c, company_value cv
WHERE d.date_id = di.date_id
AND (d.start_date AT TIME ZONE 'UTC')::date >= (CURRENT_DATE - interval '2 mon')::date
AND c.company_id = d.owner_id
AND cv.company_id = c.company_id
AND cv.attribute = 'email1'
)
SELECT DISTINCT
e.date_id AS id,
e.title,
e.attendees,
e.organizer_name,
e.organizer_email,
e.start_date,
e.end_date,
e.all_day,
e.location,
e.comment,
e.is_private,
e.resource_names AS resources,
e.type AS recurrence,
e.apt_type AS type
FROM logins l,
company c,
date_company_assignment dca,
events e
WHERE e.date_id = dca.date_id
AND dca.company_id = c.company_id
AND l.n = c.company_id
%s
ORDER BY e.start_date DESC;`, userq, kwq)
err = s.db.Select(&events, q, params...)
return
}