Go · 9576 bytes Raw Blame History
1 // Code generated by sqlc. DO NOT EDIT.
2 // versions:
3 // sqlc v1.31.1
4 // source: notifications.sql
5
6 package notifdb
7
8 import (
9 "context"
10
11 "github.com/jackc/pgx/v5/pgtype"
12 )
13
14 const countNotificationsForRecipient = `-- name: CountNotificationsForRecipient :one
15 SELECT count(*) FROM notifications
16 WHERE recipient_user_id = $1
17 AND ($2::boolean = false OR unread = true)
18 `
19
20 type CountNotificationsForRecipientParams struct {
21 RecipientUserID int64
22 Column2 bool
23 }
24
25 func (q *Queries) CountNotificationsForRecipient(ctx context.Context, db DBTX, arg CountNotificationsForRecipientParams) (int64, error) {
26 row := db.QueryRow(ctx, countNotificationsForRecipient, arg.RecipientUserID, arg.Column2)
27 var count int64
28 err := row.Scan(&count)
29 return count, err
30 }
31
32 const countUnreadForRecipient = `-- name: CountUnreadForRecipient :one
33 SELECT count(*) FROM notifications
34 WHERE recipient_user_id = $1 AND unread = true
35 `
36
37 func (q *Queries) CountUnreadForRecipient(ctx context.Context, db DBTX, recipientUserID int64) (int64, error) {
38 row := db.QueryRow(ctx, countUnreadForRecipient, recipientUserID)
39 var count int64
40 err := row.Scan(&count)
41 return count, err
42 }
43
44 const getNotification = `-- name: GetNotification :one
45 SELECT id, recipient_user_id, kind, reason, repo_id,
46 thread_kind, thread_id, source_event_id, unread,
47 last_event_at, last_actor_user_id, summary, created_at, updated_at
48 FROM notifications WHERE id = $1
49 `
50
51 func (q *Queries) GetNotification(ctx context.Context, db DBTX, id int64) (Notification, error) {
52 row := db.QueryRow(ctx, getNotification, id)
53 var i Notification
54 err := row.Scan(
55 &i.ID,
56 &i.RecipientUserID,
57 &i.Kind,
58 &i.Reason,
59 &i.RepoID,
60 &i.ThreadKind,
61 &i.ThreadID,
62 &i.SourceEventID,
63 &i.Unread,
64 &i.LastEventAt,
65 &i.LastActorUserID,
66 &i.Summary,
67 &i.CreatedAt,
68 &i.UpdatedAt,
69 )
70 return i, err
71 }
72
73 const insertThreadlessNotification = `-- name: InsertThreadlessNotification :one
74 INSERT INTO notifications (
75 recipient_user_id, kind, reason, repo_id,
76 source_event_id, last_actor_user_id
77 ) VALUES ($1, $2, $3, $4, $5, $6)
78 RETURNING id, recipient_user_id, kind, reason, repo_id,
79 thread_kind, thread_id, source_event_id, unread,
80 last_event_at, last_actor_user_id, summary, created_at, updated_at
81 `
82
83 type InsertThreadlessNotificationParams struct {
84 RecipientUserID int64
85 Kind string
86 Reason string
87 RepoID pgtype.Int8
88 SourceEventID pgtype.Int8
89 LastActorUserID pgtype.Int8
90 }
91
92 // For events with no thread (e.g. repo-admin lifecycle: archived).
93 // These don't coalesce; each fires its own row. Used sparingly.
94 func (q *Queries) InsertThreadlessNotification(ctx context.Context, db DBTX, arg InsertThreadlessNotificationParams) (Notification, error) {
95 row := db.QueryRow(ctx, insertThreadlessNotification,
96 arg.RecipientUserID,
97 arg.Kind,
98 arg.Reason,
99 arg.RepoID,
100 arg.SourceEventID,
101 arg.LastActorUserID,
102 )
103 var i Notification
104 err := row.Scan(
105 &i.ID,
106 &i.RecipientUserID,
107 &i.Kind,
108 &i.Reason,
109 &i.RepoID,
110 &i.ThreadKind,
111 &i.ThreadID,
112 &i.SourceEventID,
113 &i.Unread,
114 &i.LastEventAt,
115 &i.LastActorUserID,
116 &i.Summary,
117 &i.CreatedAt,
118 &i.UpdatedAt,
119 )
120 return i, err
121 }
122
123 const listNotificationsForRecipient = `-- name: ListNotificationsForRecipient :many
124 SELECT n.id, n.recipient_user_id, n.kind, n.reason, n.repo_id,
125 n.thread_kind, n.thread_id, n.source_event_id, n.unread,
126 n.last_event_at, n.last_actor_user_id, n.summary,
127 n.created_at, n.updated_at,
128 coalesce(u.username, '') AS actor_username,
129 coalesce(r.name, '') AS repo_name,
130 coalesce(ru.username, '') AS repo_owner_username,
131 coalesce(i.number, 0) AS thread_number,
132 coalesce(i.title, '') AS thread_title
133 FROM notifications n
134 LEFT JOIN users u ON u.id = n.last_actor_user_id
135 LEFT JOIN repos r ON r.id = n.repo_id
136 LEFT JOIN users ru ON ru.id = r.owner_user_id
137 LEFT JOIN issues i ON i.id = n.thread_id
138 WHERE n.recipient_user_id = $1
139 AND ($2::boolean = false OR n.unread = true)
140 ORDER BY n.last_event_at DESC
141 LIMIT $3 OFFSET $4
142 `
143
144 type ListNotificationsForRecipientParams struct {
145 RecipientUserID int64
146 Column2 bool
147 Limit int32
148 Offset int32
149 }
150
151 type ListNotificationsForRecipientRow struct {
152 ID int64
153 RecipientUserID int64
154 Kind string
155 Reason string
156 RepoID pgtype.Int8
157 ThreadKind NullNotificationThreadKind
158 ThreadID pgtype.Int8
159 SourceEventID pgtype.Int8
160 Unread bool
161 LastEventAt pgtype.Timestamptz
162 LastActorUserID pgtype.Int8
163 Summary []byte
164 CreatedAt pgtype.Timestamptz
165 UpdatedAt pgtype.Timestamptz
166 ActorUsername string
167 RepoName string
168 RepoOwnerUsername string
169 ThreadNumber int64
170 ThreadTitle string
171 }
172
173 // Inbox view, recency-sorted. `onlyUnread` toggles the inbox
174 // filter ("Unread" tab vs "All").
175 func (q *Queries) ListNotificationsForRecipient(ctx context.Context, db DBTX, arg ListNotificationsForRecipientParams) ([]ListNotificationsForRecipientRow, error) {
176 rows, err := db.Query(ctx, listNotificationsForRecipient,
177 arg.RecipientUserID,
178 arg.Column2,
179 arg.Limit,
180 arg.Offset,
181 )
182 if err != nil {
183 return nil, err
184 }
185 defer rows.Close()
186 items := []ListNotificationsForRecipientRow{}
187 for rows.Next() {
188 var i ListNotificationsForRecipientRow
189 if err := rows.Scan(
190 &i.ID,
191 &i.RecipientUserID,
192 &i.Kind,
193 &i.Reason,
194 &i.RepoID,
195 &i.ThreadKind,
196 &i.ThreadID,
197 &i.SourceEventID,
198 &i.Unread,
199 &i.LastEventAt,
200 &i.LastActorUserID,
201 &i.Summary,
202 &i.CreatedAt,
203 &i.UpdatedAt,
204 &i.ActorUsername,
205 &i.RepoName,
206 &i.RepoOwnerUsername,
207 &i.ThreadNumber,
208 &i.ThreadTitle,
209 ); err != nil {
210 return nil, err
211 }
212 items = append(items, i)
213 }
214 if err := rows.Err(); err != nil {
215 return nil, err
216 }
217 return items, nil
218 }
219
220 const markAllReadForRecipient = `-- name: MarkAllReadForRecipient :exec
221 UPDATE notifications SET unread = false, updated_at = now()
222 WHERE recipient_user_id = $1 AND unread = true
223 `
224
225 // Bounded sweep: a single call doesn't try to update millions of
226 // rows. Caller paginates via repeated calls when count > batch.
227 func (q *Queries) MarkAllReadForRecipient(ctx context.Context, db DBTX, recipientUserID int64) error {
228 _, err := db.Exec(ctx, markAllReadForRecipient, recipientUserID)
229 return err
230 }
231
232 const setNotificationRead = `-- name: SetNotificationRead :exec
233 UPDATE notifications SET unread = false, updated_at = now()
234 WHERE id = $1 AND recipient_user_id = $2
235 `
236
237 type SetNotificationReadParams struct {
238 ID int64
239 RecipientUserID int64
240 }
241
242 func (q *Queries) SetNotificationRead(ctx context.Context, db DBTX, arg SetNotificationReadParams) error {
243 _, err := db.Exec(ctx, setNotificationRead, arg.ID, arg.RecipientUserID)
244 return err
245 }
246
247 const setNotificationUnread = `-- name: SetNotificationUnread :exec
248 UPDATE notifications SET unread = true, updated_at = now()
249 WHERE id = $1 AND recipient_user_id = $2
250 `
251
252 type SetNotificationUnreadParams struct {
253 ID int64
254 RecipientUserID int64
255 }
256
257 func (q *Queries) SetNotificationUnread(ctx context.Context, db DBTX, arg SetNotificationUnreadParams) error {
258 _, err := db.Exec(ctx, setNotificationUnread, arg.ID, arg.RecipientUserID)
259 return err
260 }
261
262 const upsertNotificationByThread = `-- name: UpsertNotificationByThread :one
263
264 INSERT INTO notifications (
265 recipient_user_id, kind, reason, repo_id,
266 thread_kind, thread_id, source_event_id,
267 last_event_at, last_actor_user_id
268 ) VALUES (
269 $1, $2, $3, $4, $5, $6, $7, now(), $8
270 )
271 ON CONFLICT (recipient_user_id, thread_kind, thread_id) WHERE thread_id IS NOT NULL
272 DO UPDATE SET
273 kind = EXCLUDED.kind,
274 reason = EXCLUDED.reason,
275 source_event_id = EXCLUDED.source_event_id,
276 last_event_at = now(),
277 last_actor_user_id = EXCLUDED.last_actor_user_id,
278 unread = true,
279 updated_at = now()
280 RETURNING id, recipient_user_id, kind, reason, repo_id,
281 thread_kind, thread_id, source_event_id, unread,
282 last_event_at, last_actor_user_id, summary, created_at, updated_at
283 `
284
285 type UpsertNotificationByThreadParams struct {
286 RecipientUserID int64
287 Kind string
288 Reason string
289 RepoID pgtype.Int8
290 ThreadKind NullNotificationThreadKind
291 ThreadID pgtype.Int8
292 SourceEventID pgtype.Int8
293 LastActorUserID pgtype.Int8
294 }
295
296 // ─── notifications ─────────────────────────────────────────────────
297 // Coalesce-or-insert: if a row exists for (recipient, thread), bump
298 // last_event_at + last_actor + reason and re-flip unread=true so the
299 // inbox surfaces it again. Otherwise insert a fresh row.
300 //
301 // Returns the resulting row (whether it was created or updated)
302 // so the caller can chain an email-enqueue without a re-read.
303 func (q *Queries) UpsertNotificationByThread(ctx context.Context, db DBTX, arg UpsertNotificationByThreadParams) (Notification, error) {
304 row := db.QueryRow(ctx, upsertNotificationByThread,
305 arg.RecipientUserID,
306 arg.Kind,
307 arg.Reason,
308 arg.RepoID,
309 arg.ThreadKind,
310 arg.ThreadID,
311 arg.SourceEventID,
312 arg.LastActorUserID,
313 )
314 var i Notification
315 err := row.Scan(
316 &i.ID,
317 &i.RecipientUserID,
318 &i.Kind,
319 &i.Reason,
320 &i.RepoID,
321 &i.ThreadKind,
322 &i.ThreadID,
323 &i.SourceEventID,
324 &i.Unread,
325 &i.LastEventAt,
326 &i.LastActorUserID,
327 &i.Summary,
328 &i.CreatedAt,
329 &i.UpdatedAt,
330 )
331 return i, err
332 }
333