158 lines
4.0 KiB
Go
158 lines
4.0 KiB
Go
package postgres
|
|
|
|
import (
|
|
"context"
|
|
"database/sql"
|
|
"encoding/json"
|
|
"fmt"
|
|
"time"
|
|
|
|
"github.com/google/uuid"
|
|
"github.com/jmoiron/sqlx"
|
|
|
|
"github.com/RyanCopley/skybridge/user/internal/domain"
|
|
"github.com/RyanCopley/skybridge/user/internal/repository/interfaces"
|
|
)
|
|
|
|
type userProfileRepository struct {
|
|
db *sqlx.DB
|
|
}
|
|
|
|
// NewUserProfileRepository creates a new user profile repository
|
|
func NewUserProfileRepository(db *sqlx.DB) interfaces.UserProfileRepository {
|
|
return &userProfileRepository{db: db}
|
|
}
|
|
|
|
func (r *userProfileRepository) Create(ctx context.Context, profile *domain.UserProfile) error {
|
|
profile.CreatedAt = time.Now()
|
|
profile.UpdatedAt = time.Now()
|
|
|
|
// Convert preferences to JSON
|
|
var preferencesJSON []byte
|
|
if profile.Preferences != nil {
|
|
var err error
|
|
preferencesJSON, err = json.Marshal(profile.Preferences)
|
|
if err != nil {
|
|
return fmt.Errorf("failed to marshal preferences: %w", err)
|
|
}
|
|
}
|
|
|
|
query := `
|
|
INSERT INTO user_profiles (
|
|
user_id, bio, location, website, timezone, language,
|
|
preferences, created_at, updated_at
|
|
) VALUES (
|
|
$1, $2, $3, $4, $5, $6, $7, $8, $9
|
|
)`
|
|
|
|
_, err := r.db.ExecContext(ctx, query,
|
|
profile.UserID, profile.Bio, profile.Location, profile.Website,
|
|
profile.Timezone, profile.Language, preferencesJSON,
|
|
profile.CreatedAt, profile.UpdatedAt,
|
|
)
|
|
if err != nil {
|
|
return fmt.Errorf("failed to create user profile: %w", err)
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func (r *userProfileRepository) GetByUserID(ctx context.Context, userID uuid.UUID) (*domain.UserProfile, error) {
|
|
query := `
|
|
SELECT user_id, bio, location, website, timezone, language,
|
|
preferences, created_at, updated_at
|
|
FROM user_profiles
|
|
WHERE user_id = $1`
|
|
|
|
row := r.db.QueryRowContext(ctx, query, userID)
|
|
|
|
var profile domain.UserProfile
|
|
var preferencesJSON sql.NullString
|
|
|
|
err := row.Scan(
|
|
&profile.UserID, &profile.Bio, &profile.Location, &profile.Website,
|
|
&profile.Timezone, &profile.Language, &preferencesJSON,
|
|
&profile.CreatedAt, &profile.UpdatedAt,
|
|
)
|
|
if err != nil {
|
|
if err == sql.ErrNoRows {
|
|
return nil, fmt.Errorf("user profile not found")
|
|
}
|
|
return nil, fmt.Errorf("failed to get user profile: %w", err)
|
|
}
|
|
|
|
// Parse preferences JSON
|
|
if preferencesJSON.Valid && preferencesJSON.String != "" {
|
|
var preferences map[string]interface{}
|
|
err = json.Unmarshal([]byte(preferencesJSON.String), &preferences)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("failed to unmarshal preferences: %w", err)
|
|
}
|
|
profile.Preferences = preferences
|
|
}
|
|
|
|
return &profile, nil
|
|
}
|
|
|
|
func (r *userProfileRepository) Update(ctx context.Context, profile *domain.UserProfile) error {
|
|
profile.UpdatedAt = time.Now()
|
|
|
|
// Convert preferences to JSON
|
|
var preferencesJSON []byte
|
|
if profile.Preferences != nil {
|
|
var err error
|
|
preferencesJSON, err = json.Marshal(profile.Preferences)
|
|
if err != nil {
|
|
return fmt.Errorf("failed to marshal preferences: %w", err)
|
|
}
|
|
}
|
|
|
|
query := `
|
|
UPDATE user_profiles SET
|
|
bio = $2,
|
|
location = $3,
|
|
website = $4,
|
|
timezone = $5,
|
|
language = $6,
|
|
preferences = $7,
|
|
updated_at = $8
|
|
WHERE user_id = $1`
|
|
|
|
result, err := r.db.ExecContext(ctx, query,
|
|
profile.UserID, profile.Bio, profile.Location, profile.Website,
|
|
profile.Timezone, profile.Language, preferencesJSON,
|
|
profile.UpdatedAt,
|
|
)
|
|
if err != nil {
|
|
return fmt.Errorf("failed to update user profile: %w", err)
|
|
}
|
|
|
|
rowsAffected, err := result.RowsAffected()
|
|
if err != nil {
|
|
return fmt.Errorf("failed to get affected rows: %w", err)
|
|
}
|
|
if rowsAffected == 0 {
|
|
return fmt.Errorf("user profile not found")
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func (r *userProfileRepository) Delete(ctx context.Context, userID uuid.UUID) error {
|
|
query := `DELETE FROM user_profiles WHERE user_id = $1`
|
|
|
|
result, err := r.db.ExecContext(ctx, query, userID)
|
|
if err != nil {
|
|
return fmt.Errorf("failed to delete user profile: %w", err)
|
|
}
|
|
|
|
rowsAffected, err := result.RowsAffected()
|
|
if err != nil {
|
|
return fmt.Errorf("failed to get affected rows: %w", err)
|
|
}
|
|
if rowsAffected == 0 {
|
|
return fmt.Errorf("user profile not found")
|
|
}
|
|
|
|
return nil
|
|
} |