mirror of
https://gitlab.com/mbugroup/lti-api.git
synced 2026-05-20 13:31:56 +00:00
113 lines
2.7 KiB
Go
113 lines
2.7 KiB
Go
package repository
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"time"
|
|
|
|
"github.com/jackc/pgconn"
|
|
commonrepo "gitlab.com/mbugroup/lti-api.git/internal/common/repository"
|
|
entity "gitlab.com/mbugroup/lti-api.git/internal/entities"
|
|
"gorm.io/gorm"
|
|
"gorm.io/gorm/clause"
|
|
)
|
|
|
|
type UserRepository interface {
|
|
commonrepo.BaseRepository[entity.User]
|
|
GetByIdUser(ctx context.Context, idUser int64, modifier func(*gorm.DB) *gorm.DB) (*entity.User, error)
|
|
UpsertByIdUser(ctx context.Context, user *entity.User) error
|
|
SoftDeleteByIdUser(ctx context.Context, idUser int64) error
|
|
}
|
|
|
|
type UserRepositoryImpl struct {
|
|
*commonrepo.BaseRepositoryImpl[entity.User]
|
|
}
|
|
|
|
func NewUserRepository(db *gorm.DB) UserRepository {
|
|
return &UserRepositoryImpl{
|
|
BaseRepositoryImpl: commonrepo.NewBaseRepository[entity.User](db),
|
|
}
|
|
}
|
|
|
|
func (r *UserRepositoryImpl) GetByIdUser(
|
|
ctx context.Context,
|
|
idUser int64,
|
|
modifier func(*gorm.DB) *gorm.DB,
|
|
) (*entity.User, error) {
|
|
return r.BaseRepositoryImpl.First(ctx, func(db *gorm.DB) *gorm.DB {
|
|
return db.Where("id_user = ?", idUser)
|
|
})
|
|
}
|
|
|
|
func (r *UserRepositoryImpl) UpsertByIdUser(ctx context.Context, user *entity.User) error {
|
|
if user == nil {
|
|
return gorm.ErrInvalidData
|
|
}
|
|
|
|
return r.DB().WithContext(ctx).Transaction(func(tx *gorm.DB) error {
|
|
now := time.Now()
|
|
user.DeletedAt = gorm.DeletedAt{}
|
|
user.UpdatedAt = now
|
|
|
|
err := tx.Clauses(clause.OnConflict{
|
|
Columns: []clause.Column{{Name: "id_user"}},
|
|
UpdateAll: true,
|
|
}).Omit("id", "created_at").Create(user).Error
|
|
if err == nil {
|
|
return nil
|
|
}
|
|
|
|
if !isUniqueViolation(err, "users_email_unique") {
|
|
return err
|
|
}
|
|
|
|
var existing entity.User
|
|
lockQuery := tx.Clauses(clause.Locking{Strength: "UPDATE"}).Where("email = ?", user.Email)
|
|
if err := lockQuery.First(&existing).Error; err != nil {
|
|
return err
|
|
}
|
|
|
|
user.Id = existing.Id
|
|
|
|
updates := map[string]any{
|
|
"id_user": user.IdUser,
|
|
"email": user.Email,
|
|
"name": user.Name,
|
|
"updated_at": now,
|
|
"deleted_at": gorm.DeletedAt{},
|
|
}
|
|
|
|
if err := tx.Model(&entity.User{}).Where("id = ?", existing.Id).Updates(updates).Error; err != nil {
|
|
return err
|
|
}
|
|
|
|
return nil
|
|
})
|
|
}
|
|
|
|
func (r *UserRepositoryImpl) SoftDeleteByIdUser(ctx context.Context, idUser int64) error {
|
|
query := r.DB().WithContext(ctx).Where("id_user = ?", idUser)
|
|
result := query.Delete(&entity.User{})
|
|
if result.Error != nil {
|
|
return result.Error
|
|
}
|
|
if result.RowsAffected == 0 {
|
|
return gorm.ErrRecordNotFound
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func isUniqueViolation(err error, constraint string) bool {
|
|
var pgErr *pgconn.PgError
|
|
if !errors.As(err, &pgErr) {
|
|
return false
|
|
}
|
|
if pgErr.Code != "23505" {
|
|
return false
|
|
}
|
|
if constraint == "" {
|
|
return true
|
|
}
|
|
return pgErr.ConstraintName == constraint
|
|
}
|