197 lines
4.8 KiB
Go
197 lines
4.8 KiB
Go
|
package repository
|
||
|
|
||
|
import (
|
||
|
"backend/pkg/library/errs/code"
|
||
|
"backend/pkg/permission/domain"
|
||
|
"context"
|
||
|
"errors"
|
||
|
"go.mongodb.org/mongo-driver/v2/mongo/options"
|
||
|
"time"
|
||
|
|
||
|
"backend/pkg/library/errs"
|
||
|
"backend/pkg/library/mongo"
|
||
|
"backend/pkg/permission/domain/entity"
|
||
|
"backend/pkg/permission/domain/repository"
|
||
|
|
||
|
"github.com/zeromicro/go-zero/core/stores/cache"
|
||
|
"github.com/zeromicro/go-zero/core/stores/mon"
|
||
|
"go.mongodb.org/mongo-driver/v2/bson"
|
||
|
mongodriver "go.mongodb.org/mongo-driver/v2/mongo"
|
||
|
)
|
||
|
|
||
|
type ClientRepositoryParam struct {
|
||
|
Conf *mongo.Conf
|
||
|
CacheConf cache.CacheConf
|
||
|
DBOpts []mon.Option
|
||
|
CacheOpts []cache.Option
|
||
|
}
|
||
|
|
||
|
type ClientRepository struct {
|
||
|
DB mongo.DocumentDBWithCacheUseCase
|
||
|
}
|
||
|
|
||
|
// NewClientRepository 創建客戶端倉庫實例
|
||
|
func NewClientRepository(param ClientRepositoryParam) repository.ClientRepository {
|
||
|
e := entity.Client{}
|
||
|
documentDB, err := mongo.MustDocumentDBWithCache(
|
||
|
param.Conf,
|
||
|
e.CollectionName(),
|
||
|
param.CacheConf,
|
||
|
param.DBOpts,
|
||
|
param.CacheOpts,
|
||
|
)
|
||
|
if err != nil {
|
||
|
panic(err)
|
||
|
}
|
||
|
|
||
|
return &ClientRepository{
|
||
|
DB: documentDB,
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func (repo *ClientRepository) Create(ctx context.Context, client *entity.Client) error {
|
||
|
now := time.Now()
|
||
|
client.CreateTime = now
|
||
|
client.UpdateTime = now
|
||
|
id := bson.NewObjectID()
|
||
|
client.ID = id
|
||
|
rk := domain.GeClientRedisKey(id.Hex())
|
||
|
_, err := repo.DB.InsertOne(ctx, rk, client)
|
||
|
if err != nil {
|
||
|
// 檢查是否為重複鍵錯誤
|
||
|
if mongodriver.IsDuplicateKeyError(err) {
|
||
|
return errs.ResourceAlreadyExist(client.ClientID)
|
||
|
}
|
||
|
|
||
|
return errs.DBErrorWithScope(code.CloudEPPermission, err.Error())
|
||
|
}
|
||
|
|
||
|
return nil
|
||
|
}
|
||
|
|
||
|
func (repo *ClientRepository) GetByID(ctx context.Context, id string) (*entity.Client, error) {
|
||
|
var client entity.Client
|
||
|
objID, err := bson.ObjectIDFromHex(id)
|
||
|
if err != nil {
|
||
|
return nil, err
|
||
|
}
|
||
|
rk := domain.GeClientRedisKey(objID.Hex())
|
||
|
err = repo.DB.FindOne(ctx, rk, &client, bson.M{"_id": objID})
|
||
|
if err != nil {
|
||
|
if errors.Is(err, mongodriver.ErrNoDocuments) {
|
||
|
return nil, errs.ResourceNotFoundWithScope(
|
||
|
code.CloudEPPermission,
|
||
|
domain.FailedToGetByID,
|
||
|
"failed to get client by id")
|
||
|
}
|
||
|
|
||
|
return nil, errs.DBErrorWithScope(code.CloudEPPermission, err.Error())
|
||
|
}
|
||
|
|
||
|
return &client, nil
|
||
|
}
|
||
|
|
||
|
func (repo *ClientRepository) GetByClientID(ctx context.Context, clientID string) (*entity.Client, error) {
|
||
|
var client entity.Client
|
||
|
rk := domain.GeClientRedisKey(clientID)
|
||
|
err := repo.DB.FindOne(ctx, rk, &client, bson.M{"client_id": clientID})
|
||
|
if err != nil {
|
||
|
if errors.Is(err, mongodriver.ErrNoDocuments) {
|
||
|
return nil, errs.ResourceNotFoundWithScope(
|
||
|
code.CloudEPPermission,
|
||
|
domain.FailedToGetByClientID,
|
||
|
"failed to get client by client id")
|
||
|
}
|
||
|
|
||
|
return nil, errs.DBErrorWithScope(code.CloudEPPermission, err.Error())
|
||
|
}
|
||
|
|
||
|
return &client, nil
|
||
|
}
|
||
|
|
||
|
func (repo *ClientRepository) Update(ctx context.Context, id string, client *entity.Client) error {
|
||
|
client.UpdateTime = time.Now()
|
||
|
objID, err := bson.ObjectIDFromHex(id)
|
||
|
if err != nil {
|
||
|
return err
|
||
|
}
|
||
|
update := bson.M{
|
||
|
"$set": bson.M{
|
||
|
"name": client.Name,
|
||
|
"secret": client.Secret,
|
||
|
"status": client.Status,
|
||
|
"update_time": client.UpdateTime,
|
||
|
},
|
||
|
}
|
||
|
gc, err := repo.GetByID(ctx, id)
|
||
|
if err != nil {
|
||
|
return err
|
||
|
}
|
||
|
rk := domain.GeClientRedisKey(objID.Hex())
|
||
|
_, err = repo.DB.UpdateOne(ctx, rk, bson.M{"_id": objID}, update)
|
||
|
if err != nil {
|
||
|
return errs.DBErrorWithScope(code.CloudEPPermission, err.Error())
|
||
|
}
|
||
|
|
||
|
rk = domain.GeClientRedisKey(gc.ClientID)
|
||
|
err = repo.DB.DelCache(ctx, rk)
|
||
|
if err != nil {
|
||
|
return err
|
||
|
}
|
||
|
|
||
|
return nil
|
||
|
}
|
||
|
|
||
|
func (repo *ClientRepository) Delete(ctx context.Context, id string) error {
|
||
|
objID, err := bson.ObjectIDFromHex(id)
|
||
|
if err != nil {
|
||
|
return err
|
||
|
}
|
||
|
gc, err := repo.GetByID(ctx, id)
|
||
|
if err != nil {
|
||
|
return err
|
||
|
}
|
||
|
|
||
|
rk := domain.GeClientRedisKey(gc.ClientID)
|
||
|
err = repo.DB.DelCache(ctx, rk)
|
||
|
if err != nil {
|
||
|
return err
|
||
|
}
|
||
|
|
||
|
rk = domain.GeClientRedisKey(objID.Hex())
|
||
|
_, err = repo.DB.DeleteOne(ctx, rk, bson.M{"_id": objID})
|
||
|
if err != nil {
|
||
|
return errs.DBErrorWithScope(code.CloudEPPermission, err.Error())
|
||
|
}
|
||
|
|
||
|
return nil
|
||
|
}
|
||
|
|
||
|
func (repo *ClientRepository) List(ctx context.Context, filter repository.ClientFilter) ([]*entity.Client, error) {
|
||
|
query := bson.M{}
|
||
|
|
||
|
if filter.Status != nil {
|
||
|
query["status"] = *filter.Status
|
||
|
}
|
||
|
|
||
|
var clients []*entity.Client
|
||
|
err := repo.DB.GetClient().Find(ctx, query, &clients,
|
||
|
options.Find().SetLimit(int64(filter.Limit)),
|
||
|
options.Find().SetSkip(int64(filter.Skip)),
|
||
|
)
|
||
|
|
||
|
if err != nil {
|
||
|
return nil, errs.DBErrorWithScope(code.CloudEPPermission, err.Error())
|
||
|
}
|
||
|
|
||
|
return clients, nil
|
||
|
}
|
||
|
|
||
|
// Index20241226001UP 創建索引
|
||
|
func (repo *ClientRepository) Index20241226001UP(ctx context.Context) (*mongodriver.Cursor, error) {
|
||
|
repo.DB.PopulateIndex(ctx, "client_id", 1, true)
|
||
|
repo.DB.PopulateIndex(ctx, "status", 1, false)
|
||
|
|
||
|
return repo.DB.GetClient().Indexes().List(ctx)
|
||
|
}
|