JCS-pub/client/internal/services/package.go

169 lines
4.3 KiB
Go

package services
import (
"fmt"
"time"
"gitlink.org.cn/cloudream/common/pkgs/logger"
"gitlink.org.cn/cloudream/jcs-pub/client/internal/db"
jcstypes "gitlink.org.cn/cloudream/jcs-pub/common/types"
"gitlink.org.cn/cloudream/jcs-pub/common/types/datamap"
)
// PackageService 提供对包相关操作的服务接口
type PackageService struct {
*Service
}
// PackageSvc 创建并返回一个PackageService的实例
func (svc *Service) PackageSvc() *PackageService {
return &PackageService{Service: svc}
}
func (svc *PackageService) GetBucketPackages(bucketID jcstypes.BucketID) ([]jcstypes.Package, error) {
return svc.DB.Package().GetBucketPackages(svc.DB.DefCtx(), bucketID)
}
func (svc *PackageService) Create(bucketID jcstypes.BucketID, name string) (jcstypes.Package, error) {
pkg, err := svc.DB.Package().Create(svc.DB.DefCtx(), bucketID, name, time.Now())
if err != nil {
return jcstypes.Package{}, err
}
svc.EvtPub.Publish(&datamap.BodyNewPackage{
Info: pkg,
})
return pkg, nil
}
// DeletePackage 删除指定的包
func (svc *PackageService) DeletePackage(packageID jcstypes.PackageID) error {
err := svc.DB.Package().DeleteComplete(svc.DB.DefCtx(), packageID)
if err != nil {
return err
}
svc.EvtPub.Publish(&datamap.BodyPackageDeleted{
PackageID: packageID,
})
return nil
}
func (svc *PackageService) Clone(packageID jcstypes.PackageID, bucketID jcstypes.BucketID, name string) (jcstypes.Package, error) {
var pkg jcstypes.Package
var oldObjIDs []jcstypes.ObjectID
var newObjIDs []jcstypes.ObjectID
err := svc.DB.DoTx(func(tx db.SQLContext) error {
var err error
pkg, err = svc.DB.Package().Create(tx, bucketID, name, time.Now())
if err != nil {
return fmt.Errorf("creating package: %w", err)
}
objs, err := svc.DB.Object().GetPackageObjects(tx, packageID)
if err != nil {
return fmt.Errorf("getting package objects: %w", err)
}
objBlks, err := svc.DB.ObjectBlock().GetInPackageID(tx, packageID)
if err != nil {
return fmt.Errorf("getting object blocks: %w", err)
}
clonedObjs := make([]jcstypes.Object, len(objs))
for i, obj := range objs {
clonedObjs[i] = obj
clonedObjs[i].ObjectID = 0
clonedObjs[i].PackageID = pkg.PackageID
}
err = svc.DB.Object().BatchCreate(tx, &clonedObjs)
if err != nil {
return fmt.Errorf("batch creating objects: %w", err)
}
oldToNew := make(map[jcstypes.ObjectID]jcstypes.ObjectID)
for i, obj := range clonedObjs {
oldToNew[objs[i].ObjectID] = obj.ObjectID
oldObjIDs = append(oldObjIDs, objs[i].ObjectID)
newObjIDs = append(newObjIDs, obj.ObjectID)
}
clonedBlks := make([]jcstypes.ObjectBlock, len(objBlks))
for i, blk := range objBlks {
clonedBlks[i] = blk
clonedBlks[i].ObjectID = oldToNew[blk.ObjectID]
}
err = svc.DB.ObjectBlock().BatchCreate(tx, clonedBlks)
if err != nil {
return fmt.Errorf("batch creating object blocks: %w", err)
}
return nil
})
if err != nil {
return jcstypes.Package{}, err
}
svc.EvtPub.Publish(&datamap.BodyPackageCloned{
SourcePackageID: packageID,
NewPackage: pkg,
SourceObjectIDs: oldObjIDs,
NewObjectIDs: newObjIDs,
})
return pkg, nil
}
func (svc *PackageService) AddAccessStat(entries []db.AddAccessStatEntry) {
pkgIDs := make([]jcstypes.PackageID, len(entries))
objIDs := make([]jcstypes.ObjectID, len(entries))
for i, e := range entries {
pkgIDs[i] = e.PackageID
objIDs[i] = e.ObjectID
}
err := svc.DB.DoTx(func(tx db.SQLContext) error {
avaiPkgIDs, err := svc.DB.Package().BatchTestPackageID(tx, pkgIDs)
if err != nil {
return fmt.Errorf("batch test package id: %w", err)
}
avaiObjIDs, err := svc.DB.Object().BatchTestObjectID(tx, objIDs)
if err != nil {
return fmt.Errorf("batch test object id: %w", err)
}
var willAdds []db.AddAccessStatEntry
for _, e := range entries {
if avaiPkgIDs[e.PackageID] && avaiObjIDs[e.ObjectID] {
willAdds = append(willAdds, e)
}
}
if len(willAdds) > 0 {
err := svc.DB.PackageAccessStat().BatchAddCounter(tx, willAdds)
if err != nil {
return fmt.Errorf("batch add package access stat counter: %w", err)
}
err = svc.DB.ObjectAccessStat().BatchAddCounter(tx, willAdds)
if err != nil {
return fmt.Errorf("batch add object access stat counter: %w", err)
}
}
return nil
})
if err != nil {
logger.Warn(err.Error())
}
}