77 lines
2.2 KiB
Go
77 lines
2.2 KiB
Go
package user
|
|
|
|
import (
|
|
"context"
|
|
"database/sql"
|
|
"errors"
|
|
"time"
|
|
)
|
|
|
|
// User مدل کاربر.
|
|
type User struct {
|
|
ID int64 `json:"id"`
|
|
Mobile string `json:"mobile"`
|
|
FirstName *string `json:"first_name"`
|
|
LastName *string `json:"last_name"`
|
|
Avatar *string `json:"avatar"`
|
|
Coins int64 `json:"coins"`
|
|
IsAdmin bool `json:"is_admin"`
|
|
CreatedAt time.Time `json:"created_at"`
|
|
}
|
|
|
|
var ErrNotFound = errors.New("user not found")
|
|
|
|
// Repo دسترسی به جدول users.
|
|
type Repo struct{ db *sql.DB }
|
|
|
|
func NewRepo(db *sql.DB) *Repo { return &Repo{db: db} }
|
|
|
|
// FindByMobile کاربر را با شماره موبایل پیدا میکند.
|
|
func (r *Repo) FindByMobile(ctx context.Context, mobile string) (*User, error) {
|
|
row := r.db.QueryRowContext(ctx,
|
|
`SELECT id, mobile, first_name, last_name, avatar, coins, is_admin, created_at
|
|
FROM users WHERE mobile = ?`, mobile)
|
|
return scan(row)
|
|
}
|
|
|
|
// FindByID کاربر را با شناسه پیدا میکند.
|
|
func (r *Repo) FindByID(ctx context.Context, id int64) (*User, error) {
|
|
row := r.db.QueryRowContext(ctx,
|
|
`SELECT id, mobile, first_name, last_name, avatar, coins, is_admin, created_at
|
|
FROM users WHERE id = ?`, id)
|
|
return scan(row)
|
|
}
|
|
|
|
// Create کاربر جدید میسازد.
|
|
func (r *Repo) Create(ctx context.Context, mobile string) (*User, error) {
|
|
res, err := r.db.ExecContext(ctx, `INSERT INTO users (mobile) VALUES (?)`, mobile)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
id, _ := res.LastInsertId()
|
|
return r.FindByID(ctx, id)
|
|
}
|
|
|
|
// FindOrCreate اگر کاربر نبود میسازد (مطابق فلوی login-otp).
|
|
func (r *Repo) FindOrCreate(ctx context.Context, mobile string) (*User, error) {
|
|
u, err := r.FindByMobile(ctx, mobile)
|
|
if errors.Is(err, ErrNotFound) {
|
|
return r.Create(ctx, mobile)
|
|
}
|
|
return u, err
|
|
}
|
|
|
|
func scan(row *sql.Row) (*User, error) {
|
|
var u User
|
|
var created string
|
|
err := row.Scan(&u.ID, &u.Mobile, &u.FirstName, &u.LastName, &u.Avatar, &u.Coins, &u.IsAdmin, &created)
|
|
if errors.Is(err, sql.ErrNoRows) {
|
|
return nil, ErrNotFound
|
|
}
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
u.CreatedAt, _ = time.Parse("2006-01-02 15:04:05", created)
|
|
return &u, nil
|
|
}
|