95 lines
2.1 KiB
Go
95 lines
2.1 KiB
Go
package postgres
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"fmt"
|
|
|
|
"github.com/jackc/pgx/v5"
|
|
)
|
|
|
|
type User struct {
|
|
ID string
|
|
PublicID string
|
|
Status string
|
|
Nickname *string
|
|
AvatarURL *string
|
|
}
|
|
|
|
type CreateUserParams struct {
|
|
PublicID string
|
|
Status string
|
|
}
|
|
|
|
type queryRower interface {
|
|
QueryRow(context.Context, string, ...any) pgx.Row
|
|
}
|
|
|
|
func (s *Store) FindUserByMobile(ctx context.Context, tx Tx, countryCode, mobile string) (*User, error) {
|
|
row := tx.QueryRow(ctx, `
|
|
SELECT u.id, u.user_public_id, u.status, u.nickname, u.avatar_url
|
|
FROM users u
|
|
JOIN login_identities li ON li.user_id = u.id
|
|
WHERE li.provider = 'mobile'
|
|
AND li.country_code = $1
|
|
AND li.mobile = $2
|
|
AND li.status = 'active'
|
|
LIMIT 1
|
|
`, countryCode, mobile)
|
|
return scanUser(row)
|
|
}
|
|
|
|
func (s *Store) CreateUser(ctx context.Context, tx Tx, params CreateUserParams) (*User, error) {
|
|
row := tx.QueryRow(ctx, `
|
|
INSERT INTO users (user_public_id, status)
|
|
VALUES ($1, $2)
|
|
RETURNING id, user_public_id, status, nickname, avatar_url
|
|
`, params.PublicID, params.Status)
|
|
return scanUser(row)
|
|
}
|
|
|
|
func (s *Store) TouchUserLogin(ctx context.Context, tx Tx, userID string) error {
|
|
_, err := tx.Exec(ctx, `
|
|
UPDATE users
|
|
SET last_login_at = NOW()
|
|
WHERE id = $1
|
|
`, userID)
|
|
if err != nil {
|
|
return fmt.Errorf("touch user last login: %w", err)
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (s *Store) DeactivateUser(ctx context.Context, tx Tx, userID string) error {
|
|
_, err := tx.Exec(ctx, `
|
|
UPDATE users
|
|
SET status = 'deleted', updated_at = NOW()
|
|
WHERE id = $1
|
|
`, userID)
|
|
if err != nil {
|
|
return fmt.Errorf("deactivate user: %w", err)
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (s *Store) GetUserByID(ctx context.Context, db queryRower, userID string) (*User, error) {
|
|
row := db.QueryRow(ctx, `
|
|
SELECT id, user_public_id, status, nickname, avatar_url
|
|
FROM users
|
|
WHERE id = $1
|
|
`, userID)
|
|
return scanUser(row)
|
|
}
|
|
|
|
func scanUser(row pgx.Row) (*User, error) {
|
|
var user User
|
|
err := row.Scan(&user.ID, &user.PublicID, &user.Status, &user.Nickname, &user.AvatarURL)
|
|
if errors.Is(err, pgx.ErrNoRows) {
|
|
return nil, nil
|
|
}
|
|
if err != nil {
|
|
return nil, fmt.Errorf("scan user: %w", err)
|
|
}
|
|
return &user, nil
|
|
}
|