feat(modpacks): implement simple zip importer and API
This commit is contained in:
@@ -7,6 +7,8 @@ import (
|
||||
|
||||
"gitea.mrixs.me/minecraft-platform/backend/internal/models"
|
||||
"github.com/google/uuid"
|
||||
"github.com/jackc/pgx/v5"
|
||||
"github.com/jackc/pgx/v5/pgxpool"
|
||||
)
|
||||
|
||||
var (
|
||||
@@ -14,21 +16,20 @@ var (
|
||||
)
|
||||
|
||||
type UserRepository struct {
|
||||
DB *sql.DB
|
||||
DB *pgxpool.Pool
|
||||
}
|
||||
|
||||
// CreateUserTx создает нового пользователя и его профиль в рамках одной транзакции
|
||||
func (r *UserRepository) CreateUserTx(ctx context.Context, user *models.User) error {
|
||||
tx, err := r.DB.BeginTx(ctx, nil)
|
||||
tx, err := r.DB.Begin(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer tx.Rollback()
|
||||
defer tx.Rollback(ctx)
|
||||
|
||||
var exists bool
|
||||
err = tx.QueryRowContext(ctx,
|
||||
"SELECT EXISTS(SELECT 1 FROM users WHERE username = $1 OR email = $2)",
|
||||
user.Username, user.Email).Scan(&exists)
|
||||
err = tx.QueryRow(ctx,
|
||||
"SELECT EXISTS(SELECT 1 FROM users WHERE username = $1 OR email = $2)").Scan(&exists)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -37,20 +38,17 @@ func (r *UserRepository) CreateUserTx(ctx context.Context, user *models.User) er
|
||||
}
|
||||
|
||||
var newUserID int
|
||||
err = tx.QueryRowContext(ctx,
|
||||
"INSERT INTO users (uuid, username, email, password_hash, role) VALUES ($1, $2, $3, $4, $5) RETURNING id",
|
||||
user.UUID, user.Username, user.Email, user.PasswordHash, user.Role,
|
||||
).Scan(&newUserID)
|
||||
err = tx.QueryRow(ctx, "INSERT INTO users (uuid, username, email, password_hash, role) VALUES ($1, $2, $3, $4, $5) RETURNING id").Scan(&newUserID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
_, err = tx.ExecContext(ctx, "INSERT INTO profiles (user_id) VALUES ($1)", newUserID)
|
||||
_, err = tx.Exec(ctx, "INSERT INTO profiles (user_id) VALUES ($1)")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return tx.Commit()
|
||||
return tx.Commit(ctx)
|
||||
}
|
||||
|
||||
var (
|
||||
@@ -64,12 +62,12 @@ func (r *UserRepository) GetUserByUsername(ctx context.Context, username string)
|
||||
var userUUID string
|
||||
|
||||
query := "SELECT id, uuid, username, email, password_hash, role FROM users WHERE username = $1"
|
||||
err := r.DB.QueryRowContext(ctx, query, username).Scan(
|
||||
err := r.DB.QueryRow(ctx, query, username).Scan(
|
||||
&user.ID, &userUUID, &user.Username, &user.Email, &user.PasswordHash, &user.Role,
|
||||
)
|
||||
|
||||
if err != nil {
|
||||
if errors.Is(err, sql.ErrNoRows) {
|
||||
if errors.Is(err, pgx.ErrNoRows) {
|
||||
return nil, ErrUserNotFound
|
||||
}
|
||||
return nil, err
|
||||
@@ -82,7 +80,7 @@ func (r *UserRepository) GetUserByUsername(ctx context.Context, username string)
|
||||
// CreateAccessToken сохраняет новый токен доступа в базу данных.
|
||||
func (r *UserRepository) CreateAccessToken(ctx context.Context, userID int, accessToken, clientToken string) error {
|
||||
query := "INSERT INTO access_tokens (user_id, access_token, client_token) VALUES ($1, $2, $3)"
|
||||
_, err := r.DB.ExecContext(ctx, query, userID, accessToken, clientToken)
|
||||
_, err := r.DB.Exec(ctx, query, userID, accessToken, clientToken)
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -98,12 +96,12 @@ func (r *UserRepository) GetProfileByUUID(ctx context.Context, userUUID uuid.UUI
|
||||
JOIN profiles p ON u.id = p.user_id
|
||||
WHERE u.uuid = $1`
|
||||
|
||||
err := r.DB.QueryRowContext(ctx, query, userUUID).Scan(
|
||||
err := r.DB.QueryRow(ctx, query, userUUID).Scan(
|
||||
&user.ID, &user.Username, &skinHash, &capeHash,
|
||||
)
|
||||
|
||||
if err != nil {
|
||||
if errors.Is(err, sql.ErrNoRows) {
|
||||
if errors.Is(err, pgx.ErrNoRows) {
|
||||
return nil, nil, ErrUserNotFound
|
||||
}
|
||||
return nil, nil, err
|
||||
@@ -136,7 +134,7 @@ func (r *UserRepository) ValidateAccessToken(ctx context.Context, token string,
|
||||
WHERE at.access_token = $1 AND u.uuid = $2
|
||||
)`
|
||||
|
||||
err := r.DB.QueryRowContext(ctx, query, token, userUUID).Scan(&exists)
|
||||
err := r.DB.QueryRow(ctx, query, token, userUUID).Scan(&exists)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -151,16 +149,12 @@ func (r *UserRepository) ValidateAccessToken(ctx context.Context, token string,
|
||||
// UpdateSkinHash обновляет хеш скина для пользователя.
|
||||
func (r *UserRepository) UpdateSkinHash(ctx context.Context, userID int, skinHash string) error {
|
||||
query := "UPDATE profiles SET skin_hash = $1, updated_at = NOW() WHERE user_id = $2"
|
||||
result, err := r.DB.ExecContext(ctx, query, skinHash, userID)
|
||||
result, err := r.DB.Exec(ctx, query, skinHash, userID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
rowsAffected, err := result.RowsAffected()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if rowsAffected == 0 {
|
||||
if result.RowsAffected() == 0 {
|
||||
return ErrUserNotFound
|
||||
}
|
||||
|
||||
@@ -173,12 +167,12 @@ func (r *UserRepository) GetUserByLogin(ctx context.Context, login string) (*mod
|
||||
var userUUID string
|
||||
|
||||
query := "SELECT id, uuid, username, email, password_hash, role, created_at, updated_at FROM users WHERE username = $1 OR email = $1"
|
||||
err := r.DB.QueryRowContext(ctx, query, login).Scan(
|
||||
err := r.DB.QueryRow(ctx, query, login).Scan(
|
||||
&user.ID, &userUUID, &user.Username, &user.Email, &user.PasswordHash, &user.Role, &user.CreatedAt, &user.UpdatedAt,
|
||||
)
|
||||
|
||||
if err != nil {
|
||||
if errors.Is(err, sql.ErrNoRows) {
|
||||
if errors.Is(err, pgx.ErrNoRows) {
|
||||
return nil, ErrUserNotFound
|
||||
}
|
||||
return nil, err
|
||||
|
||||
Reference in New Issue
Block a user