A community based topic aggregation platform built on atproto
1package postgres
2
3import (
4 "context"
5 "database/sql"
6 "fmt"
7 "strings"
8
9 "Coves/internal/core/users"
10)
11
12type postgresUserRepo struct {
13 db *sql.DB
14}
15
16// NewUserRepository creates a new PostgreSQL user repository
17func NewUserRepository(db *sql.DB) users.UserRepository {
18 return &postgresUserRepo{db: db}
19}
20
21// Create inserts a new user into the users table
22func (r *postgresUserRepo) Create(ctx context.Context, user *users.User) (*users.User, error) {
23 query := `
24 INSERT INTO users (did, handle, pds_url)
25 VALUES ($1, $2, $3)
26 RETURNING did, handle, pds_url, created_at, updated_at`
27
28 err := r.db.QueryRowContext(ctx, query, user.DID, user.Handle, user.PDSURL).
29 Scan(&user.DID, &user.Handle, &user.PDSURL, &user.CreatedAt, &user.UpdatedAt)
30
31 if err != nil {
32 // Check for unique constraint violations
33 if strings.Contains(err.Error(), "duplicate key") {
34 if strings.Contains(err.Error(), "users_pkey") {
35 return nil, fmt.Errorf("user with DID already exists")
36 }
37 if strings.Contains(err.Error(), "users_handle_key") {
38 return nil, fmt.Errorf("handle already taken")
39 }
40 }
41 return nil, fmt.Errorf("failed to create user: %w", err)
42 }
43
44 return user, nil
45}
46
47// GetByDID retrieves a user by their DID
48func (r *postgresUserRepo) GetByDID(ctx context.Context, did string) (*users.User, error) {
49 user := &users.User{}
50 query := `SELECT did, handle, pds_url, created_at, updated_at FROM users WHERE did = $1`
51
52 err := r.db.QueryRowContext(ctx, query, did).
53 Scan(&user.DID, &user.Handle, &user.PDSURL, &user.CreatedAt, &user.UpdatedAt)
54
55 if err == sql.ErrNoRows {
56 return nil, fmt.Errorf("user not found")
57 }
58 if err != nil {
59 return nil, fmt.Errorf("failed to get user by DID: %w", err)
60 }
61
62 return user, nil
63}
64
65// GetByHandle retrieves a user by their handle
66func (r *postgresUserRepo) GetByHandle(ctx context.Context, handle string) (*users.User, error) {
67 user := &users.User{}
68 query := `SELECT did, handle, pds_url, created_at, updated_at FROM users WHERE handle = $1`
69
70 err := r.db.QueryRowContext(ctx, query, handle).
71 Scan(&user.DID, &user.Handle, &user.PDSURL, &user.CreatedAt, &user.UpdatedAt)
72
73 if err == sql.ErrNoRows {
74 return nil, fmt.Errorf("user not found")
75 }
76 if err != nil {
77 return nil, fmt.Errorf("failed to get user by handle: %w", err)
78 }
79
80 return user, nil
81}