mirror of
https://github.com/ThisTine/Snip.git
synced 2026-08-18 23:18:47 +07:00
feat: first commit
This commit is contained in:
@@ -0,0 +1,58 @@
|
||||
package postgres
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/rand"
|
||||
"errors"
|
||||
|
||||
"github.com/jackc/pgx/v5"
|
||||
"github.com/jackc/pgx/v5/pgxpool"
|
||||
|
||||
"github.com/snip/backend/internal/domain"
|
||||
)
|
||||
|
||||
type UserRepo struct{ pool *pgxpool.Pool }
|
||||
|
||||
func NewUserRepo(pool *pgxpool.Pool) *UserRepo { return &UserRepo{pool: pool} }
|
||||
|
||||
func (r *UserRepo) Upsert(ctx context.Context, u *domain.User) (*domain.User, error) {
|
||||
id := newUserID()
|
||||
var out domain.User
|
||||
err := r.pool.QueryRow(ctx,
|
||||
`INSERT INTO users (id, email, name, provider, subject)
|
||||
VALUES ($1,$2,$3,$4,$5)
|
||||
ON CONFLICT (provider, subject)
|
||||
DO UPDATE SET email = EXCLUDED.email, name = EXCLUDED.name
|
||||
RETURNING id, email, name, provider, subject`,
|
||||
id, u.Email, u.Name, u.Provider, u.Subject).
|
||||
Scan(&out.ID, &out.Email, &out.Name, &out.Provider, &out.Subject)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &out, nil
|
||||
}
|
||||
|
||||
func (r *UserRepo) GetByID(ctx context.Context, id string) (*domain.User, error) {
|
||||
var u domain.User
|
||||
err := r.pool.QueryRow(ctx,
|
||||
`SELECT id, email, name, provider, subject FROM users WHERE id=$1`, id).
|
||||
Scan(&u.ID, &u.Email, &u.Name, &u.Provider, &u.Subject)
|
||||
if errors.Is(err, pgx.ErrNoRows) {
|
||||
return nil, domain.ErrNotFound
|
||||
}
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &u, nil
|
||||
}
|
||||
|
||||
func newUserID() string {
|
||||
const hex = "0123456789abcdef"
|
||||
b := make([]byte, 16)
|
||||
_, _ = rand.Read(b)
|
||||
out := make([]byte, 16)
|
||||
for i := range out {
|
||||
out[i] = hex[int(b[i])%16]
|
||||
}
|
||||
return "u_" + string(out)
|
||||
}
|
||||
Reference in New Issue
Block a user