package services import ( "fmt" "gitlink.org.cn/cloudream/common/pkgs/logger" "gitlink.org.cn/cloudream/jcs-pub/client/internal/db" "gitlink.org.cn/cloudream/jcs-pub/client/internal/downloader" "gitlink.org.cn/cloudream/jcs-pub/client/types" "gitlink.org.cn/cloudream/jcs-pub/common/models/datamap" ) // PackageService 提供对包相关操作的服务接口 type PackageService struct { *Service } // PackageSvc 创建并返回一个PackageService的实例 func (svc *Service) PackageSvc() *PackageService { return &PackageService{Service: svc} } func (svc *PackageService) Get(packageID types.PackageID) (types.Package, error) { return svc.DB.Package().GetByID(svc.DB.DefCtx(), packageID) } func (svc *PackageService) GetByFullName(bucketName string, packageName string) (types.Package, error) { return svc.DB.Package().GetByFullName(svc.DB.DefCtx(), bucketName, packageName) } func (svc *PackageService) GetBucketPackages(bucketID types.BucketID) ([]types.Package, error) { return svc.DB.Package().GetBucketPackages(svc.DB.DefCtx(), bucketID) } func (svc *PackageService) Create(bucketID types.BucketID, name string) (types.Package, error) { pkg, err := svc.DB.Package().Create(svc.DB.DefCtx(), bucketID, name) if err != nil { return types.Package{}, err } svc.EvtPub.Publish(&datamap.BodyNewPackage{ Info: pkg, }) return pkg, nil } func (svc *PackageService) DownloadPackage(packageID types.PackageID) (downloader.DownloadIterator, error) { // TODO 检查用户ID return svc.Downloader.DownloadPackage(packageID), nil } // DeletePackage 删除指定的包 func (svc *PackageService) DeletePackage(packageID types.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 types.PackageID, bucketID types.BucketID, name string) (types.Package, error) { var pkg types.Package var oldObjIDs []types.ObjectID var newObjIDs []types.ObjectID err := svc.DB.DoTx(func(tx db.SQLContext) error { var err error pkg, err = svc.DB.Package().Create(tx, bucketID, name) 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([]types.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[types.ObjectID]types.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([]types.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 types.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([]types.PackageID, len(entries)) objIDs := make([]types.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()) } }