156 lines
3.8 KiB
Go
156 lines
3.8 KiB
Go
|
package repository
|
||
|
|
||
|
import (
|
||
|
"app-cloudep-member-server/pkg/domain"
|
||
|
"app-cloudep-member-server/pkg/domain/entity"
|
||
|
"app-cloudep-member-server/pkg/domain/repository"
|
||
|
"context"
|
||
|
"errors"
|
||
|
"time"
|
||
|
|
||
|
mgo "code.30cm.net/digimon/library-go/mongo"
|
||
|
"github.com/zeromicro/go-zero/core/stores/cache"
|
||
|
"github.com/zeromicro/go-zero/core/stores/mon"
|
||
|
"go.mongodb.org/mongo-driver/bson"
|
||
|
"go.mongodb.org/mongo-driver/bson/primitive"
|
||
|
"go.mongodb.org/mongo-driver/mongo"
|
||
|
)
|
||
|
|
||
|
type AccountRepositoryParam struct {
|
||
|
Conf *mgo.Conf
|
||
|
CacheConf cache.CacheConf
|
||
|
DbOpts []mon.Option
|
||
|
CacheOpts []cache.Option
|
||
|
}
|
||
|
|
||
|
type AccountRepository struct {
|
||
|
DB mgo.DocumentDBWithCacheUseCase
|
||
|
}
|
||
|
|
||
|
func NewAccountRepository(param AccountRepositoryParam) repository.AccountRepository {
|
||
|
e := entity.Account{}
|
||
|
documentDB, err := mgo.MustDocumentDBWithCache(
|
||
|
param.Conf,
|
||
|
e.CollectionName(),
|
||
|
param.CacheConf,
|
||
|
param.DbOpts,
|
||
|
param.CacheOpts,
|
||
|
)
|
||
|
if err != nil {
|
||
|
panic(err)
|
||
|
}
|
||
|
|
||
|
return &AccountRepository{
|
||
|
DB: documentDB,
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func (repo *AccountRepository) Insert(ctx context.Context, data *entity.Account) error {
|
||
|
if data.ID.IsZero() {
|
||
|
now := time.Now().UTC().UnixNano()
|
||
|
data.ID = primitive.NewObjectID()
|
||
|
data.CreateAt = &now
|
||
|
data.UpdateAt = &now
|
||
|
}
|
||
|
rk := domain.GetAccountRedisKey(data.ID.Hex())
|
||
|
_, err := repo.DB.InsertOne(ctx, rk, data)
|
||
|
|
||
|
return err
|
||
|
}
|
||
|
|
||
|
func (repo *AccountRepository) FindOne(ctx context.Context, id string) (*entity.Account, error) {
|
||
|
oid, err := primitive.ObjectIDFromHex(id)
|
||
|
if err != nil {
|
||
|
return nil, ErrInvalidObjectID
|
||
|
}
|
||
|
|
||
|
var data entity.Account
|
||
|
rk := domain.GetAccountRedisKey(id)
|
||
|
err = repo.DB.FindOne(ctx, rk, &data, bson.M{"_id": oid})
|
||
|
|
||
|
switch {
|
||
|
case err == nil:
|
||
|
return &data, nil
|
||
|
case errors.Is(err, mon.ErrNotFound):
|
||
|
return nil, ErrNotFound
|
||
|
default:
|
||
|
return nil, err
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func (repo *AccountRepository) Update(ctx context.Context, data *entity.Account) (*mongo.UpdateResult, error) {
|
||
|
now := time.Now().UTC().UnixNano()
|
||
|
data.UpdateAt = &now
|
||
|
|
||
|
rk := domain.GetAccountRedisKey(data.ID.Hex())
|
||
|
res, err := repo.DB.UpdateOne(ctx, rk, bson.M{"_id": data.ID}, bson.M{"$set": data})
|
||
|
|
||
|
return res, err
|
||
|
}
|
||
|
|
||
|
func (repo *AccountRepository) Delete(ctx context.Context, id string) (int64, error) {
|
||
|
oid, err := primitive.ObjectIDFromHex(id)
|
||
|
if err != nil {
|
||
|
return 0, ErrInvalidObjectID
|
||
|
}
|
||
|
rk := domain.GetAccountRedisKey(id)
|
||
|
|
||
|
return repo.DB.DeleteOne(ctx, rk, bson.M{"_id": oid})
|
||
|
}
|
||
|
|
||
|
func (repo *AccountRepository) FindOneByAccount(ctx context.Context, loginID string) (*entity.Account, error) {
|
||
|
// todo: 之後需要同步快取
|
||
|
var data entity.Account
|
||
|
err := repo.DB.GetClient().FindOne(ctx, &data, bson.M{"login_id": loginID})
|
||
|
switch {
|
||
|
case err == nil:
|
||
|
return &data, nil
|
||
|
case errors.Is(err, mon.ErrNotFound):
|
||
|
return nil, ErrNotFound
|
||
|
default:
|
||
|
return nil, err
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func (repo *AccountRepository) UpdateTokenByLoginID(ctx context.Context, account string, token string) error {
|
||
|
// todo: 之後需要同步快取
|
||
|
filter := bson.M{"login_id": account}
|
||
|
update := bson.M{
|
||
|
"$set": bson.M{
|
||
|
"token": token,
|
||
|
"update_at": time.Now().UTC().UnixNano(),
|
||
|
},
|
||
|
}
|
||
|
var data entity.Account
|
||
|
err := repo.DB.GetClient().FindOne(ctx, &data, filter)
|
||
|
if err != nil {
|
||
|
return err
|
||
|
}
|
||
|
|
||
|
rk := domain.GetAccountRedisKey(data.ID.Hex())
|
||
|
|
||
|
modify, err := repo.DB.UpdateOne(ctx, rk, bson.M{"_id": data.ID}, update)
|
||
|
if err != nil {
|
||
|
return err
|
||
|
}
|
||
|
|
||
|
if modify.MatchedCount == 0 {
|
||
|
return ErrNotFound // 自定義的錯誤表示未找到記錄
|
||
|
}
|
||
|
|
||
|
return nil
|
||
|
}
|
||
|
|
||
|
func (repo *AccountRepository) Index20241226001UP(ctx context.Context) (*mongo.Cursor, error) {
|
||
|
// 等價於 db.account.createIndex({ "login_id": 1, "platform": 1}, {unique: true})
|
||
|
repo.DB.PopulateMultiIndex(ctx, []string{
|
||
|
"login_id",
|
||
|
"platform",
|
||
|
}, []int32{1, 1}, true)
|
||
|
|
||
|
// 等價於 db.account.createIndex({"create_at": 1})
|
||
|
repo.DB.PopulateIndex(ctx, "create_at", 1, false)
|
||
|
|
||
|
return repo.DB.GetClient().Indexes().List(ctx)
|
||
|
}
|