common/repository/account/account.go
Mikhail 95703fcd61 Merge branch 'hlog' into 'main'
Hlog

See merge request backend/quiz/common!24
2024-06-04 22:40:09 +00:00

368 lines
10 KiB
Go

package account
import (
"context"
"database/sql"
"fmt"
"github.com/google/uuid"
"penahub.gitlab.yandexcloud.net/backend/quiz/common.git/dal/sqlcgen"
"penahub.gitlab.yandexcloud.net/backend/quiz/common.git/model"
"penahub.gitlab.yandexcloud.net/backend/quiz/common.git/pj_errors"
"strconv"
)
type Deps struct {
Queries *sqlcgen.Queries
Pool *sql.DB
}
type AccountRepository struct {
queries *sqlcgen.Queries
pool *sql.DB
}
func NewAccountRepository(deps Deps) *AccountRepository {
return &AccountRepository{
queries: deps.Queries,
pool: deps.Pool,
}
}
// test +
func (r *AccountRepository) GetAccountByID(ctx context.Context, userID string) (model.Account, error) {
userIDSql := sql.NullString{String: userID, Valid: userID != ""}
accountRows, err := r.queries.GetAccountWithPrivileges(ctx, userIDSql)
if err != nil {
return model.Account{}, err
}
var account model.Account
privileges := make(map[string]model.ShortPrivilege)
for _, row := range accountRows {
if account.ID == "" {
account.ID = row.ID.String()
account.UserID = row.UserID.String
account.CreatedAt = row.CreatedAt.Time
account.Deleted = row.Deleted.Bool
}
if row.PrivilegeID != 0 {
privilege := model.ShortPrivilege{
ID: fmt.Sprintf("%d", row.PrivilegeID),
PrivilegeID: row.Privilegeid,
PrivilegeName: row.PrivilegeName,
Amount: uint64(row.Amount),
CreatedAt: row.PrivilegeCreatedAt.Time,
}
privileges[privilege.PrivilegeID] = privilege
}
}
if account.ID == "" {
return model.Account{}, sql.ErrNoRows
}
account.Privileges = privileges
return account, nil
}
// test +
func (r *AccountRepository) GetPrivilegesByAccountID(ctx context.Context, userID string) ([]model.ShortPrivilege, error) {
userIDSql := sql.NullString{String: userID, Valid: userID != ""}
privilegeRows, err := r.queries.GetPrivilegesByAccountIDWC(ctx, userIDSql)
if err != nil {
return nil, err
}
var privileges []model.ShortPrivilege
for _, row := range privilegeRows {
privilege := model.ShortPrivilege{
ID: fmt.Sprintf("%d", row.ID),
PrivilegeID: row.Privilegeid.String,
PrivilegeName: row.PrivilegeName.String,
Amount: uint64(row.Amount.Int32),
CreatedAt: row.CreatedAt.Time,
}
privileges = append(privileges, privilege)
}
return privileges, nil
}
// todo test
func (r *AccountRepository) CreateAccount(ctx context.Context, data *model.Account) (model.Account, error) {
data.ID = uuid.NewString()
row, err := r.queries.CreateAccount(ctx, sqlcgen.CreateAccountParams{
ID: uuid.MustParse(data.ID),
UserID: sql.NullString{String: data.UserID, Valid: data.UserID != ""},
Email: sql.NullString{String: data.Email, Valid: data.Email != ""},
CreatedAt: sql.NullTime{Time: data.CreatedAt, Valid: !data.CreatedAt.IsZero()},
Deleted: sql.NullBool{Bool: data.Deleted, Valid: true},
})
if err != nil {
return model.Account{}, fmt.Errorf("failed to create account: %w", err)
}
createdAccount := model.Account{
ID: row.ID.String(),
UserID: row.UserID.String,
Email: row.Email.String,
}
for _, privilege := range data.Privileges {
err := r.queries.InsertPrivilege(ctx, sqlcgen.InsertPrivilegeParams{
Privilegeid: sql.NullString{String: privilege.PrivilegeID, Valid: privilege.PrivilegeID != ""},
AccountID: uuid.NullUUID{UUID: uuid.MustParse(data.ID), Valid: true},
PrivilegeName: sql.NullString{String: privilege.PrivilegeName, Valid: privilege.PrivilegeName != ""},
Amount: sql.NullInt32{Int32: int32(privilege.Amount), Valid: true},
CreatedAt: sql.NullTime{Time: privilege.CreatedAt, Valid: !privilege.CreatedAt.IsZero()},
})
if err != nil {
return model.Account{}, fmt.Errorf("failed to insert privilege: %w", err)
}
}
return createdAccount, nil
}
func (r *AccountRepository) DeleteAccount(ctx context.Context, accountID string) error {
tx, err := r.pool.BeginTx(ctx, nil)
if err != nil {
return err
}
err = r.queries.DeleteAccountById(ctx, uuid.MustParse(accountID))
if err != nil {
tx.Rollback()
return err
}
err = r.queries.DeletePrivilegeByAccID(ctx, uuid.NullUUID{UUID: uuid.MustParse(accountID), Valid: true})
if err != nil {
tx.Rollback()
return err
}
return tx.Commit()
}
// test +
func (r *AccountRepository) GetAccounts(ctx context.Context, limit uint64, offset uint64) ([]model.Account, uint64, error) {
rows, err := r.queries.AccountPagination(ctx, sqlcgen.AccountPaginationParams{
Limit: int32(limit),
Offset: int32(offset),
})
if err != nil {
return nil, 0, err
}
var accounts []model.Account
for _, row := range rows {
account := model.Account{
ID: row.ID.String(),
UserID: row.UserID.String,
CreatedAt: row.CreatedAt.Time,
Deleted: row.Deleted.Bool,
}
accounts = append(accounts, account)
}
return accounts, uint64(len(accounts)), nil
}
// test +
func (r *AccountRepository) UpdatePrivilege(ctx context.Context, privilege *model.ShortPrivilege, accountID string) error {
err := r.queries.UpdatePrivilege(ctx, sqlcgen.UpdatePrivilegeParams{
Amount: sql.NullInt32{Int32: int32(privilege.Amount), Valid: true},
CreatedAt: sql.NullTime{Time: privilege.CreatedAt, Valid: !privilege.CreatedAt.IsZero()},
AccountID: uuid.NullUUID{UUID: uuid.MustParse(accountID), Valid: true},
Privilegeid: sql.NullString{String: privilege.PrivilegeID, Valid: privilege.PrivilegeID != ""},
})
if err != nil {
return err
}
return nil
}
// test +
func (r *AccountRepository) InsertPrivilege(ctx context.Context, privilege *model.ShortPrivilege, accountID string) error {
err := r.queries.InsertPrivilege(ctx, sqlcgen.InsertPrivilegeParams{
Amount: sql.NullInt32{Int32: int32(privilege.Amount), Valid: true},
CreatedAt: sql.NullTime{Time: privilege.CreatedAt, Valid: !privilege.CreatedAt.IsZero()},
AccountID: uuid.NullUUID{UUID: uuid.MustParse(accountID), Valid: true},
Privilegeid: sql.NullString{String: privilege.PrivilegeID, Valid: privilege.PrivilegeID != ""},
PrivilegeName: sql.NullString{String: privilege.PrivilegeName, Valid: privilege.PrivilegeName != ""},
})
if err != nil {
return err
}
return nil
}
// test +
func (r *AccountRepository) GetExpired(ctx context.Context, privilegeID string) ([]model.ExpiredPrivileges, error) {
rows, err := r.queries.GetExpiredDayPrivilege(ctx, sql.NullString{String: privilegeID, Valid: privilegeID != ""})
if err != nil {
return nil, err
}
var expiredRecords []model.ExpiredPrivileges
for _, row := range rows {
privilege := model.ShortPrivilege{
ID: fmt.Sprintf("%d", row.ID),
PrivilegeID: row.Privilegeid.String,
PrivilegeName: row.PrivilegeName.String,
Amount: uint64(row.Amount.Int32),
CreatedAt: row.CreatedAt.Time,
}
expiredRecords = append(expiredRecords, model.ExpiredPrivileges{
UserID: row.UserID.String,
Privilege: privilege,
})
}
return expiredRecords, nil
}
func (r *AccountRepository) GetExpiredCount(ctx context.Context, privilegeID string) ([]model.ExpiredPrivileges, error) {
rows, err := r.queries.GetExpiredCountPrivilege(ctx, sql.NullString{String: privilegeID, Valid: privilegeID != ""})
if err != nil {
return nil, err
}
var expiredRecords []model.ExpiredPrivileges
for _, row := range rows {
privilege := model.ShortPrivilege{
ID: fmt.Sprintf("%d", row.ID),
PrivilegeID: row.Privilegeid.String,
PrivilegeName: row.PrivilegeName.String,
Amount: uint64(row.Amount.Int32),
CreatedAt: row.CreatedAt.Time,
}
expiredRecords = append(expiredRecords, model.ExpiredPrivileges{
UserID: row.UserID.String,
Privilege: privilege,
})
}
return expiredRecords, nil
}
func (r *AccountRepository) CheckAndAddDefault(ctx context.Context, amount uint64, privilegeID string, zeroAmount uint64) error {
err := r.queries.CheckAndAddDefault(ctx, sqlcgen.CheckAndAddDefaultParams{
Amount: sql.NullInt32{Int32: int32(amount), Valid: true},
PrivilegeName: sql.NullString{String: privilegeID, Valid: privilegeID != ""},
Amount_2: sql.NullInt32{Int32: int32(zeroAmount), Valid: true},
})
if err != nil {
return fmt.Errorf("error executing SQL query: %v", err)
}
return nil
}
// test +
func (r *AccountRepository) DeletePrivilegeByID(ctx context.Context, id string) error {
intID, err := strconv.Atoi(id)
if err != nil {
return fmt.Errorf("failed to convert id to integer: %v", err)
}
return r.queries.DeletePrivilegeByID(ctx, int32(intID))
}
// test +
func (r *AccountRepository) UpdatePrivilegeAmount(ctx context.Context, ID string, newAmount uint64) error {
intID, err := strconv.Atoi(ID)
if err != nil {
return fmt.Errorf("failed to convert id to integer: %v", err)
}
err = r.queries.UpdatePrivilegeAmount(ctx, sqlcgen.UpdatePrivilegeAmountParams{
Amount: sql.NullInt32{Int32: int32(newAmount), Valid: true},
ID: int32(intID),
})
if err != nil {
return err
}
return nil
}
// test +
func (r *AccountRepository) GetAccAndPrivilegeByEmail(ctx context.Context, email string) (model.Account, []model.ShortPrivilege, error) {
var account model.Account
var privileges []model.ShortPrivilege
row, err := r.queries.GetAccAndPrivilegeByEmail(ctx, sql.NullString{String: email, Valid: true})
if err != nil {
return account, privileges, err
}
account.ID = row.ID.String()
account.UserID = row.UserID.String
account.Email = row.Email.String
account.CreatedAt = row.CreatedAt.Time
if row.ID_2 != 0 {
privilege := model.ShortPrivilege{
ID: fmt.Sprint(row.ID_2),
PrivilegeID: row.Privilegeid,
Amount: uint64(row.Amount),
CreatedAt: row.CreatedAt_2.Time,
}
privileges = append(privileges, privilege)
}
return account, privileges, nil
}
func (r *AccountRepository) GetQidOwner(ctx context.Context, qId string) (string, error) {
qUUID, err := uuid.Parse(qId)
if err != nil {
return "", err
}
qNullUUID := uuid.NullUUID{UUID: qUUID, Valid: true}
userID, err := r.queries.GetQidOwner(ctx, qNullUUID)
if err != nil {
return "", err
}
return userID, nil
}
func (r *AccountRepository) ManualDone(ctx context.Context, userID string) error {
_, err := r.queries.DecrementManual(ctx, sqlcgen.DecrementManualParams{
UserID: sql.NullString{String: userID, Valid: true},
Privilegeid: sql.NullString{String: "quizManual", Valid: true},
})
if err != nil {
if err == sql.ErrNoRows {
return pj_errors.ErrNotFound
}
return err
}
return nil
}