Continued work around getting messages and notifications cleaned up since moving to MySQL and changing to Gin, SCS, NoSurf.
This commit is contained in:
80
internal/platform/services/notifications/service.go
Normal file
80
internal/platform/services/notifications/service.go
Normal file
@@ -0,0 +1,80 @@
|
||||
// ToDo: carve out sql
|
||||
package notifysvc
|
||||
|
||||
import (
|
||||
"context"
|
||||
"database/sql"
|
||||
"errors"
|
||||
"time"
|
||||
|
||||
accountNotificationHandler "synlotto-website/internal/handlers/account/notifications"
|
||||
)
|
||||
|
||||
type Service struct {
|
||||
DB *sql.DB
|
||||
Now func() time.Time
|
||||
Timeout time.Duration
|
||||
}
|
||||
|
||||
func New(db *sql.DB, opts ...func(*Service)) *Service {
|
||||
s := &Service{
|
||||
DB: db,
|
||||
Now: time.Now,
|
||||
Timeout: 5 * time.Second,
|
||||
}
|
||||
for _, opt := range opts {
|
||||
opt(s)
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
||||
func WithTimeout(d time.Duration) func(*Service) { return func(s *Service) { s.Timeout = d } }
|
||||
|
||||
// List returns newest-first notifications for a user.
|
||||
func (s *Service) List(userID int64) ([]accountNotificationHandler.Notification, error) {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), s.Timeout)
|
||||
defer cancel()
|
||||
|
||||
const q = `
|
||||
SELECT id, title, body, is_read, created_at
|
||||
FROM notifications
|
||||
WHERE user_id = ?
|
||||
ORDER BY created_at DESC`
|
||||
|
||||
rows, err := s.DB.QueryContext(ctx, q, userID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
|
||||
var out []accountNotificationHandler.Notification
|
||||
for rows.Next() {
|
||||
var n accountNotificationHandler.Notification
|
||||
if err := rows.Scan(&n.ID, &n.Title, &n.Body, &n.IsRead, &n.CreatedAt); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
out = append(out, n)
|
||||
}
|
||||
return out, rows.Err()
|
||||
}
|
||||
|
||||
func (s *Service) GetByID(userID, id int64) (*accountNotificationHandler.Notification, error) {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), s.Timeout)
|
||||
defer cancel()
|
||||
|
||||
const q = `
|
||||
SELECT id, title, body, is_read, created_at
|
||||
FROM notifications
|
||||
WHERE user_id = ? AND id = ?`
|
||||
|
||||
var n accountNotificationHandler.Notification
|
||||
err := s.DB.QueryRowContext(ctx, q, userID, id).
|
||||
Scan(&n.ID, &n.Title, &n.Body, &n.IsRead, &n.CreatedAt)
|
||||
if errors.Is(err, sql.ErrNoRows) {
|
||||
return nil, nil
|
||||
}
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &n, nil
|
||||
}
|
||||
Reference in New Issue
Block a user