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 6.0 kB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186
  1. package db2
  2. import (
  3. "fmt"
  4. "gorm.io/gorm"
  5. cdssdk "gitlink.org.cn/cloudream/common/sdks/storage"
  6. "gitlink.org.cn/cloudream/storage/common/pkgs/db2/model"
  7. )
  8. type PackageDB struct {
  9. *DB
  10. }
  11. func (db *DB) Package() *PackageDB {
  12. return &PackageDB{DB: db}
  13. }
  14. func (db *PackageDB) GetByID(ctx SQLContext, packageID cdssdk.PackageID) (model.Package, error) {
  15. var ret model.Package
  16. err := ctx.Table("Package").Where("PackageID = ?", packageID).First(&ret).Error
  17. return ret, err
  18. }
  19. func (db *PackageDB) GetByName(ctx SQLContext, bucketID cdssdk.BucketID, name string) (model.Package, error) {
  20. var ret model.Package
  21. err := ctx.Table("Package").Where("BucketID = ? AND Name = ?", bucketID, name).First(&ret).Error
  22. return ret, err
  23. }
  24. func (db *PackageDB) BatchTestPackageID(ctx SQLContext, pkgIDs []cdssdk.PackageID) (map[cdssdk.PackageID]bool, error) {
  25. if len(pkgIDs) == 0 {
  26. return make(map[cdssdk.PackageID]bool), nil
  27. }
  28. var avaiIDs []cdssdk.PackageID
  29. err := ctx.Table("Package").
  30. Select("PackageID").
  31. Where("PackageID IN ?", pkgIDs).
  32. Find(&avaiIDs).Error
  33. if err != nil {
  34. return nil, err
  35. }
  36. avaiIDMap := make(map[cdssdk.PackageID]bool)
  37. for _, pkgID := range avaiIDs {
  38. avaiIDMap[pkgID] = true
  39. }
  40. return avaiIDMap, nil
  41. }
  42. func (*PackageDB) BatchGetAllPackageIDs(ctx SQLContext, start int, count int) ([]cdssdk.PackageID, error) {
  43. var ret []cdssdk.PackageID
  44. err := ctx.Table("Package").Select("PackageID").Limit(count).Offset(start).Find(&ret).Error
  45. return ret, err
  46. }
  47. func (db *PackageDB) GetBucketPackages(ctx SQLContext, userID cdssdk.UserID, bucketID cdssdk.BucketID) ([]model.Package, error) {
  48. var ret []model.Package
  49. err := ctx.Table("UserBucket").
  50. Select("Package.*").
  51. Joins("JOIN Package ON UserBucket.BucketID = Package.BucketID").
  52. Where("UserBucket.UserID = ? AND UserBucket.BucketID = ?", userID, bucketID).
  53. Find(&ret).Error
  54. return ret, err
  55. }
  56. // IsAvailable 判断一个用户是否拥有指定对象
  57. func (db *PackageDB) IsAvailable(ctx SQLContext, userID cdssdk.UserID, packageID cdssdk.PackageID) (bool, error) {
  58. var pkgID cdssdk.PackageID
  59. err := ctx.Table("Package").
  60. Select("Package.PackageID").
  61. Joins("JOIN UserBucket ON Package.BucketID = UserBucket.BucketID").
  62. Where("Package.PackageID = ? AND UserBucket.UserID = ?", packageID, userID).
  63. Scan(&pkgID).Error
  64. if err == gorm.ErrRecordNotFound {
  65. return false, nil
  66. }
  67. if err != nil {
  68. return false, fmt.Errorf("find package failed, err: %w", err)
  69. }
  70. return true, nil
  71. }
  72. // GetUserPackage 获得Package,如果用户没有权限访问,则不会获得结果
  73. func (db *PackageDB) GetUserPackage(ctx SQLContext, userID cdssdk.UserID, packageID cdssdk.PackageID) (model.Package, error) {
  74. var ret model.Package
  75. err := ctx.Table("Package").
  76. Select("Package.*").
  77. Joins("JOIN UserBucket ON Package.BucketID = UserBucket.BucketID").
  78. Where("Package.PackageID = ? AND UserBucket.UserID = ?", packageID, userID).
  79. First(&ret).Error
  80. return ret, err
  81. }
  82. // 在指定名称的Bucket中查找指定名称的Package
  83. func (*PackageDB) GetUserPackageByName(ctx SQLContext, userID cdssdk.UserID, bucketName string, packageName string) (model.Package, error) {
  84. var ret model.Package
  85. err := ctx.Table("Package").
  86. Select("Package.*").
  87. Joins("JOIN Bucket ON Package.BucketID = Bucket.BucketID").
  88. Joins("JOIN UserBucket ON Bucket.BucketID = UserBucket.BucketID").
  89. Where("Package.Name = ? AND Bucket.Name = ? AND UserBucket.UserID = ?", packageName, bucketName, userID).
  90. First(&ret).Error
  91. return ret, err
  92. }
  93. func (db *PackageDB) Create(ctx SQLContext, bucketID cdssdk.BucketID, name string) (cdssdk.PackageID, error) {
  94. var packageID int64
  95. err := ctx.Table("Package").
  96. Select("PackageID").
  97. Where("Name = ? AND BucketID = ?", name, bucketID).
  98. Scan(&packageID).Error
  99. if err != nil {
  100. return 0, err
  101. }
  102. if packageID != 0 {
  103. return 0, gorm.ErrDuplicatedKey
  104. }
  105. newPackage := cdssdk.Package{Name: name, BucketID: bucketID, State: cdssdk.PackageStateNormal}
  106. if err := ctx.Create(&newPackage).Error; err != nil {
  107. return 0, fmt.Errorf("insert package failed, err: %w", err)
  108. }
  109. return newPackage.PackageID, nil
  110. }
  111. // SoftDelete 设置一个对象被删除,并将相关数据删除
  112. func (db *PackageDB) SoftDelete(ctx SQLContext, packageID cdssdk.PackageID) error {
  113. obj, err := db.GetByID(ctx, packageID)
  114. if err != nil {
  115. return fmt.Errorf("get package failed, err: %w", err)
  116. }
  117. if obj.State != cdssdk.PackageStateNormal {
  118. return nil
  119. }
  120. if err := db.ChangeState(ctx, packageID, cdssdk.PackageStateDeleted); err != nil {
  121. return fmt.Errorf("change package state failed, err: %w", err)
  122. }
  123. if err := db.ObjectAccessStat().DeleteInPackage(ctx, packageID); err != nil {
  124. return fmt.Errorf("delete from object access stat: %w", err)
  125. }
  126. if err := db.ObjectBlock().DeleteInPackage(ctx, packageID); err != nil {
  127. return fmt.Errorf("delete from object block failed, err: %w", err)
  128. }
  129. if err := db.PinnedObject().DeleteInPackage(ctx, packageID); err != nil {
  130. return fmt.Errorf("deleting pinned objects in package: %w", err)
  131. }
  132. if err := db.Object().DeleteInPackage(ctx, packageID); err != nil {
  133. return fmt.Errorf("deleting objects in package: %w", err)
  134. }
  135. if _, err := db.StoragePackage().SetAllPackageDeleted(ctx, packageID); err != nil {
  136. return fmt.Errorf("set storage package deleted failed, err: %w", err)
  137. }
  138. return nil
  139. }
  140. // DeleteUnused 删除一个已经是Deleted状态,且不再被使用的对象
  141. func (PackageDB) DeleteUnused(ctx SQLContext, packageID cdssdk.PackageID) error {
  142. err := ctx.Exec("DELETE FROM Package WHERE PackageID = ? AND State = ? AND NOT EXISTS (SELECT StorageID FROM StoragePackage WHERE PackageID = ?)",
  143. packageID,
  144. cdssdk.PackageStateDeleted,
  145. packageID,
  146. ).Error
  147. return err
  148. }
  149. func (*PackageDB) ChangeState(ctx SQLContext, packageID cdssdk.PackageID, state string) error {
  150. err := ctx.Exec("UPDATE Package SET State = ? WHERE PackageID = ?", state, packageID).Error
  151. return err
  152. }

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