You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

package.go 4.9 kB

8 months ago
8 months ago
8 months ago
8 months ago
8 months ago
8 months ago
8 months ago
8 months ago
8 months ago
8 months ago
8 months ago
8 months ago
8 months ago
8 months ago
8 months ago
8 months ago
8 months ago
8 months ago
8 months ago
8 months ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182
  1. package services
  2. import (
  3. "fmt"
  4. "time"
  5. "gitlink.org.cn/cloudream/common/pkgs/logger"
  6. "gitlink.org.cn/cloudream/jcs-pub/client/internal/db"
  7. "gitlink.org.cn/cloudream/jcs-pub/client/internal/downloader"
  8. "gitlink.org.cn/cloudream/jcs-pub/client/types"
  9. "gitlink.org.cn/cloudream/jcs-pub/common/models/datamap"
  10. )
  11. // PackageService 提供对包相关操作的服务接口
  12. type PackageService struct {
  13. *Service
  14. }
  15. // PackageSvc 创建并返回一个PackageService的实例
  16. func (svc *Service) PackageSvc() *PackageService {
  17. return &PackageService{Service: svc}
  18. }
  19. func (svc *PackageService) Get(packageID types.PackageID) (types.Package, error) {
  20. return svc.DB.Package().GetByID(svc.DB.DefCtx(), packageID)
  21. }
  22. func (svc *PackageService) GetByFullName(bucketName string, packageName string) (types.Package, error) {
  23. return svc.DB.Package().GetByFullName(svc.DB.DefCtx(), bucketName, packageName)
  24. }
  25. func (svc *PackageService) GetBucketPackages(bucketID types.BucketID) ([]types.Package, error) {
  26. return svc.DB.Package().GetBucketPackages(svc.DB.DefCtx(), bucketID)
  27. }
  28. func (svc *PackageService) Create(bucketID types.BucketID, name string) (types.Package, error) {
  29. pkg, err := svc.DB.Package().Create(svc.DB.DefCtx(), bucketID, name, time.Now())
  30. if err != nil {
  31. return types.Package{}, err
  32. }
  33. svc.EvtPub.Publish(&datamap.BodyNewPackage{
  34. Info: pkg,
  35. })
  36. return pkg, nil
  37. }
  38. func (svc *PackageService) DownloadPackage(packageID types.PackageID) (downloader.DownloadIterator, error) {
  39. // TODO 检查用户ID
  40. return svc.Downloader.DownloadPackage(packageID), nil
  41. }
  42. // DeletePackage 删除指定的包
  43. func (svc *PackageService) DeletePackage(packageID types.PackageID) error {
  44. err := svc.DB.Package().DeleteComplete(svc.DB.DefCtx(), packageID)
  45. if err != nil {
  46. return err
  47. }
  48. svc.EvtPub.Publish(&datamap.BodyPackageDeleted{
  49. PackageID: packageID,
  50. })
  51. return nil
  52. }
  53. func (svc *PackageService) Clone(packageID types.PackageID, bucketID types.BucketID, name string) (types.Package, error) {
  54. var pkg types.Package
  55. var oldObjIDs []types.ObjectID
  56. var newObjIDs []types.ObjectID
  57. err := svc.DB.DoTx(func(tx db.SQLContext) error {
  58. var err error
  59. pkg, err = svc.DB.Package().Create(tx, bucketID, name, time.Now())
  60. if err != nil {
  61. return fmt.Errorf("creating package: %w", err)
  62. }
  63. objs, err := svc.DB.Object().GetPackageObjects(tx, packageID)
  64. if err != nil {
  65. return fmt.Errorf("getting package objects: %w", err)
  66. }
  67. objBlks, err := svc.DB.ObjectBlock().GetInPackageID(tx, packageID)
  68. if err != nil {
  69. return fmt.Errorf("getting object blocks: %w", err)
  70. }
  71. clonedObjs := make([]types.Object, len(objs))
  72. for i, obj := range objs {
  73. clonedObjs[i] = obj
  74. clonedObjs[i].ObjectID = 0
  75. clonedObjs[i].PackageID = pkg.PackageID
  76. }
  77. err = svc.DB.Object().BatchCreate(tx, &clonedObjs)
  78. if err != nil {
  79. return fmt.Errorf("batch creating objects: %w", err)
  80. }
  81. oldToNew := make(map[types.ObjectID]types.ObjectID)
  82. for i, obj := range clonedObjs {
  83. oldToNew[objs[i].ObjectID] = obj.ObjectID
  84. oldObjIDs = append(oldObjIDs, objs[i].ObjectID)
  85. newObjIDs = append(newObjIDs, obj.ObjectID)
  86. }
  87. clonedBlks := make([]types.ObjectBlock, len(objBlks))
  88. for i, blk := range objBlks {
  89. clonedBlks[i] = blk
  90. clonedBlks[i].ObjectID = oldToNew[blk.ObjectID]
  91. }
  92. err = svc.DB.ObjectBlock().BatchCreate(tx, clonedBlks)
  93. if err != nil {
  94. return fmt.Errorf("batch creating object blocks: %w", err)
  95. }
  96. return nil
  97. })
  98. if err != nil {
  99. return types.Package{}, err
  100. }
  101. svc.EvtPub.Publish(&datamap.BodyPackageCloned{
  102. SourcePackageID: packageID,
  103. NewPackage: pkg,
  104. SourceObjectIDs: oldObjIDs,
  105. NewObjectIDs: newObjIDs,
  106. })
  107. return pkg, nil
  108. }
  109. func (svc *PackageService) AddAccessStat(entries []db.AddAccessStatEntry) {
  110. pkgIDs := make([]types.PackageID, len(entries))
  111. objIDs := make([]types.ObjectID, len(entries))
  112. for i, e := range entries {
  113. pkgIDs[i] = e.PackageID
  114. objIDs[i] = e.ObjectID
  115. }
  116. err := svc.DB.DoTx(func(tx db.SQLContext) error {
  117. avaiPkgIDs, err := svc.DB.Package().BatchTestPackageID(tx, pkgIDs)
  118. if err != nil {
  119. return fmt.Errorf("batch test package id: %w", err)
  120. }
  121. avaiObjIDs, err := svc.DB.Object().BatchTestObjectID(tx, objIDs)
  122. if err != nil {
  123. return fmt.Errorf("batch test object id: %w", err)
  124. }
  125. var willAdds []db.AddAccessStatEntry
  126. for _, e := range entries {
  127. if avaiPkgIDs[e.PackageID] && avaiObjIDs[e.ObjectID] {
  128. willAdds = append(willAdds, e)
  129. }
  130. }
  131. if len(willAdds) > 0 {
  132. err := svc.DB.PackageAccessStat().BatchAddCounter(tx, willAdds)
  133. if err != nil {
  134. return fmt.Errorf("batch add package access stat counter: %w", err)
  135. }
  136. err = svc.DB.ObjectAccessStat().BatchAddCounter(tx, willAdds)
  137. if err != nil {
  138. return fmt.Errorf("batch add object access stat counter: %w", err)
  139. }
  140. }
  141. return nil
  142. })
  143. if err != nil {
  144. logger.Warn(err.Error())
  145. }
  146. }

本项目旨在将云际存储公共基础设施化,使个人及企业可低门槛使用高效的云际存储服务(安装开箱即用云际存储客户端即可,无需关注其他组件的部署),同时支持用户灵活便捷定制云际存储的功能细节。