backend/tmp/reborn/repository/permission_repository.go

162 lines
4.3 KiB
Go

package repository
import (
"context"
"permission/reborn/domain/entity"
"permission/reborn/domain/errors"
"permission/reborn/domain/repository"
"gorm.io/gorm"
)
type permissionRepository struct {
db *gorm.DB
cache repository.CacheRepository
}
// NewPermissionRepository 建立權限 Repository
func NewPermissionRepository(db *gorm.DB, cache repository.CacheRepository) repository.PermissionRepository {
return &permissionRepository{
db: db,
cache: cache,
}
}
func (r *permissionRepository) Get(ctx context.Context, id int64) (*entity.Permission, error) {
var perm entity.Permission
err := r.db.WithContext(ctx).
Where("id = ? AND status != ?", id, entity.StatusDeleted).
First(&perm).Error
if err != nil {
if err == gorm.ErrRecordNotFound {
return nil, errors.ErrPermissionNotFound
}
return nil, errors.Wrap(errors.ErrCodeDBQuery, "failed to get permission", err)
}
return &perm, nil
}
func (r *permissionRepository) GetByName(ctx context.Context, name string) (*entity.Permission, error) {
var perm entity.Permission
err := r.db.WithContext(ctx).
Where("name = ? AND status != ?", name, entity.StatusDeleted).
First(&perm).Error
if err != nil {
if err == gorm.ErrRecordNotFound {
return nil, errors.ErrPermissionNotFound
}
return nil, errors.Wrap(errors.ErrCodeDBQuery, "failed to get permission by name", err)
}
return &perm, nil
}
func (r *permissionRepository) GetByNames(ctx context.Context, names []string) ([]*entity.Permission, error) {
if len(names) == 0 {
return []*entity.Permission{}, nil
}
var perms []*entity.Permission
err := r.db.WithContext(ctx).
Where("name IN ? AND status != ?", names, entity.StatusDeleted).
Find(&perms).Error
if err != nil {
return nil, errors.Wrap(errors.ErrCodeDBQuery, "failed to get permissions by names", err)
}
return perms, nil
}
func (r *permissionRepository) GetByHTTP(ctx context.Context, path, method string) (*entity.Permission, error) {
var perm entity.Permission
err := r.db.WithContext(ctx).
Where("http_path = ? AND http_method = ? AND status != ?", path, method, entity.StatusDeleted).
First(&perm).Error
if err != nil {
if err == gorm.ErrRecordNotFound {
return nil, errors.ErrPermissionNotFound
}
return nil, errors.Wrap(errors.ErrCodeDBQuery, "failed to get permission by http", err)
}
return &perm, nil
}
func (r *permissionRepository) List(ctx context.Context, filter repository.PermissionFilter) ([]*entity.Permission, error) {
query := r.buildQuery(ctx, filter)
var perms []*entity.Permission
if err := query.Find(&perms).Error; err != nil {
return nil, errors.Wrap(errors.ErrCodeDBQuery, "failed to list permissions", err)
}
return perms, nil
}
func (r *permissionRepository) ListActive(ctx context.Context) ([]*entity.Permission, error) {
// 嘗試從快取取得
if r.cache != nil {
var perms []*entity.Permission
err := r.cache.GetObject(ctx, repository.CacheKeyPermissionList, &perms)
if err == nil && len(perms) > 0 {
return perms, nil
}
}
// 從資料庫查詢
var perms []*entity.Permission
err := r.db.WithContext(ctx).
Where("status = ?", entity.StatusActive).
Order("parent_id, id").
Find(&perms).Error
if err != nil {
return nil, errors.Wrap(errors.ErrCodeDBQuery, "failed to list active permissions", err)
}
// 存入快取
if r.cache != nil {
_ = r.cache.SetObject(ctx, repository.CacheKeyPermissionList, perms, 0) // 使用預設 TTL
}
return perms, nil
}
func (r *permissionRepository) GetChildren(ctx context.Context, parentID int64) ([]*entity.Permission, error) {
var perms []*entity.Permission
err := r.db.WithContext(ctx).
Where("parent_id = ? AND status != ?", parentID, entity.StatusDeleted).
Find(&perms).Error
if err != nil {
return nil, errors.Wrap(errors.ErrCodeDBQuery, "failed to get children permissions", err)
}
return perms, nil
}
func (r *permissionRepository) buildQuery(ctx context.Context, filter repository.PermissionFilter) *gorm.DB {
query := r.db.WithContext(ctx).
Model(&entity.Permission{}).
Where("status != ?", entity.StatusDeleted)
if filter.Type != nil {
query = query.Where("type = ?", *filter.Type)
}
if filter.Status != nil {
query = query.Where("status = ?", *filter.Status)
}
if filter.ParentID != nil {
query = query.Where("parent_id = ?", *filter.ParentID)
}
return query.Order("parent_id, id")
}