169 lines
4.3 KiB
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())
|
|
}
|
|
}
|