init
This commit is contained in:
@@ -0,0 +1,76 @@
|
||||
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
|
||||
}
|
||||
Reference in New Issue
Block a user