75 lines
2.1 KiB
Go
75 lines
2.1 KiB
Go
// Package postgres provides PostgreSQL implementations of repository interfaces.
|
|
package postgres
|
|
|
|
import (
|
|
"context"
|
|
"database/sql"
|
|
"encoding/json"
|
|
"errors"
|
|
"time"
|
|
|
|
"git.threesix.ai/jordan/slack5-1770603014/pkg/database"
|
|
"git.threesix.ai/jordan/slack5-1770603014/services/preferences-api/internal/domain"
|
|
"git.threesix.ai/jordan/slack5-1770603014/services/preferences-api/internal/port"
|
|
)
|
|
|
|
// Compile-time verification that PreferencesRepository implements port.PreferencesRepository.
|
|
var _ port.PreferencesRepository = (*PreferencesRepository)(nil)
|
|
|
|
// PreferencesRepository is a PostgreSQL implementation of port.PreferencesRepository.
|
|
type PreferencesRepository struct {
|
|
pool *database.Pool
|
|
}
|
|
|
|
// NewPreferencesRepository creates a new PostgreSQL preferences repository.
|
|
func NewPreferencesRepository(pool *database.Pool) *PreferencesRepository {
|
|
return &PreferencesRepository{pool: pool}
|
|
}
|
|
|
|
// Get returns preferences for a user by ID.
|
|
// Returns nil, nil if no preferences exist for the user.
|
|
func (r *PreferencesRepository) Get(ctx context.Context, userID domain.UserID) (*domain.UserPreferences, error) {
|
|
var prefsJSON []byte
|
|
var updatedAt time.Time
|
|
|
|
err := r.pool.DB.QueryRowContext(ctx,
|
|
`SELECT preferences, updated_at FROM user_preferences WHERE user_id = $1`,
|
|
string(userID),
|
|
).Scan(&prefsJSON, &updatedAt)
|
|
|
|
if errors.Is(err, sql.ErrNoRows) {
|
|
return nil, nil
|
|
}
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
var prefs domain.Preferences
|
|
if err := json.Unmarshal(prefsJSON, &prefs); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return &domain.UserPreferences{
|
|
UserID: userID,
|
|
Preferences: prefs,
|
|
UpdatedAt: updatedAt,
|
|
}, nil
|
|
}
|
|
|
|
// Upsert creates or updates preferences for a user.
|
|
func (r *PreferencesRepository) Upsert(ctx context.Context, prefs *domain.UserPreferences) error {
|
|
prefsJSON, err := json.Marshal(prefs.Preferences)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
_, err = r.pool.DB.ExecContext(ctx,
|
|
`INSERT INTO user_preferences (user_id, preferences, created_at, updated_at)
|
|
VALUES ($1, $2, $3, $3)
|
|
ON CONFLICT (user_id)
|
|
DO UPDATE SET preferences = $2, updated_at = $3`,
|
|
string(prefs.UserID), prefsJSON, prefs.UpdatedAt,
|
|
)
|
|
return err
|
|
}
|