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/core.git/clients/auth" "strconv" ) type Deps struct { Queries *sqlcgen.Queries AuthClient *auth.AuthClient Pool *sql.DB } type AccountRepository struct { queries *sqlcgen.Queries authClient *auth.AuthClient pool *sql.DB } func NewAccountRepository(deps Deps) *AccountRepository { return &AccountRepository{ queries: deps.Queries, authClient: deps.AuthClient, 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) error { email, err := r.authClient.GetUserEmail(data.UserID) if err != nil { return err } data.ID = uuid.NewString() 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: email, Valid: email != ""}, CreatedAt: sql.NullTime{Time: data.CreatedAt, Valid: !data.CreatedAt.IsZero()}, Deleted: sql.NullBool{Bool: data.Deleted, Valid: true}, }) if err != nil { return fmt.Errorf("failed to create account: %w", err) } 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 fmt.Errorf("failed to insert privilege: %w", err) } } return 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.InsertPrivilegeWC(ctx, sqlcgen.InsertPrivilegeWCParams{ 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) GetExpired(ctx context.Context, privilegeID string) ([]model.ShortPrivilege, error) { rows, err := r.queries.GetExpiredPrivilege(ctx, sql.NullString{String: privilegeID, Valid: privilegeID != ""}) if err != nil { return nil, err } var expiredRecords []model.ShortPrivilege 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, 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 }