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

2 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172
  1. package db
  2. import (
  3. "database/sql"
  4. "errors"
  5. "fmt"
  6. "github.com/jmoiron/sqlx"
  7. cdssdk "gitlink.org.cn/cloudream/common/sdks/storage"
  8. "gitlink.org.cn/cloudream/common/utils/serder"
  9. "gitlink.org.cn/cloudream/storage/common/consts"
  10. "gitlink.org.cn/cloudream/storage/common/pkgs/db/model"
  11. )
  12. type PackageDB struct {
  13. *DB
  14. }
  15. func (db *DB) Package() *PackageDB {
  16. return &PackageDB{DB: db}
  17. }
  18. func (db *PackageDB) GetByID(ctx SQLContext, packageID int64) (model.Package, error) {
  19. var ret model.Package
  20. err := sqlx.Get(ctx, &ret, "select * from Package where PackageID = ?", packageID)
  21. return ret, err
  22. }
  23. func (db *PackageDB) GetByName(ctx SQLContext, bucketID int64, name string) (model.Package, error) {
  24. var ret model.Package
  25. err := sqlx.Get(ctx, &ret, "select * from Package where BucketID = ? and Name = ?", bucketID, name)
  26. return ret, err
  27. }
  28. func (*PackageDB) BatchGetAllPackageIDs(ctx SQLContext, start int, count int) ([]int64, error) {
  29. var ret []int64
  30. err := sqlx.Select(ctx, &ret, "select PackageID from Package limit ?, ?", start, count)
  31. return ret, err
  32. }
  33. func (db *PackageDB) GetBucketPackages(ctx SQLContext, userID int64, bucketID int64) ([]model.Package, error) {
  34. var ret []model.Package
  35. err := sqlx.Select(ctx, &ret, "select Package.* from UserBucket, Package where UserID = ? and UserBucket.BucketID = ? and UserBucket.BucketID = Package.BucketID", userID, bucketID)
  36. return ret, err
  37. }
  38. // IsAvailable 判断一个用户是否拥有指定对象
  39. func (db *PackageDB) IsAvailable(ctx SQLContext, userID int64, packageID int64) (bool, error) {
  40. var objID int64
  41. // 先根据PackageID找到Package,然后判断此Package所在的Bucket是不是归此用户所有
  42. err := sqlx.Get(ctx, &objID,
  43. "select Package.PackageID from Package, UserBucket where "+
  44. "Package.PackageID = ? and "+
  45. "Package.BucketID = UserBucket.BucketID and "+
  46. "UserBucket.UserID = ?",
  47. packageID, userID)
  48. if err == sql.ErrNoRows {
  49. return false, nil
  50. }
  51. if err != nil {
  52. return false, fmt.Errorf("find package failed, err: %w", err)
  53. }
  54. return true, nil
  55. }
  56. // GetUserPackage 获得Package,如果用户没有权限访问,则不会获得结果
  57. func (db *PackageDB) GetUserPackage(ctx SQLContext, userID int64, packageID int64) (model.Package, error) {
  58. var ret model.Package
  59. err := sqlx.Get(ctx, &ret,
  60. "select Package.* from Package, UserBucket where"+
  61. " Package.PackageID = ? and"+
  62. " Package.BucketID = UserBucket.BucketID and"+
  63. " UserBucket.UserID = ?",
  64. packageID, userID)
  65. return ret, err
  66. }
  67. func (db *PackageDB) Create(ctx SQLContext, bucketID int64, name string, redundancy cdssdk.TypedRedundancyInfo) (int64, error) {
  68. // 根据packagename和bucketid查询,若不存在则插入,若存在则返回错误
  69. var packageID int64
  70. err := sqlx.Get(ctx, &packageID, "select PackageID from Package where Name = ? AND BucketID = ?", name, bucketID)
  71. // 无错误代表存在记录
  72. if err == nil {
  73. return 0, fmt.Errorf("package with given Name and BucketID already exists")
  74. }
  75. // 错误不是记录不存在
  76. if !errors.Is(err, sql.ErrNoRows) {
  77. return 0, fmt.Errorf("query Package by PackageName and BucketID failed, err: %w", err)
  78. }
  79. redundancyJSON, err := serder.ObjectToJSON(redundancy)
  80. if err != nil {
  81. return 0, fmt.Errorf("redundancy to json: %w", err)
  82. }
  83. sql := "insert into Package(Name, BucketID, State, Redundancy) values(?,?,?,?)"
  84. r, err := ctx.Exec(sql, name, bucketID, consts.PackageStateNormal, redundancyJSON)
  85. if err != nil {
  86. return 0, fmt.Errorf("insert package failed, err: %w", err)
  87. }
  88. packageID, err = r.LastInsertId()
  89. if err != nil {
  90. return 0, fmt.Errorf("get id of inserted package failed, err: %w", err)
  91. }
  92. return packageID, nil
  93. }
  94. // SoftDelete 设置一个对象被删除,并将相关数据删除
  95. func (db *PackageDB) SoftDelete(ctx SQLContext, packageID int64) error {
  96. obj, err := db.GetByID(ctx, packageID)
  97. if err != nil {
  98. return fmt.Errorf("get package failed, err: %w", err)
  99. }
  100. // 不是正常状态的Package,则不删除
  101. // TODO 未来可能有其他状态
  102. if obj.State != consts.PackageStateNormal {
  103. return nil
  104. }
  105. err = db.ChangeState(ctx, packageID, consts.PackageStateDeleted)
  106. if err != nil {
  107. return fmt.Errorf("change package state failed, err: %w", err)
  108. }
  109. if obj.Redundancy.IsRepInfo() {
  110. err = db.ObjectRep().DeleteInPackage(ctx, packageID)
  111. if err != nil {
  112. return fmt.Errorf("delete from object rep failed, err: %w", err)
  113. }
  114. } else {
  115. err = db.ObjectBlock().DeleteInPackage(ctx, packageID)
  116. if err != nil {
  117. return fmt.Errorf("delete from object rep failed, err: %w", err)
  118. }
  119. }
  120. if err := db.Object().DeleteInPackage(ctx, packageID); err != nil {
  121. return fmt.Errorf("deleting objects in package: %w", err)
  122. }
  123. _, err = db.StoragePackage().SetAllPackageDeleted(ctx, packageID)
  124. if err != nil {
  125. return fmt.Errorf("set storage package deleted failed, err: %w", err)
  126. }
  127. return nil
  128. }
  129. // DeleteUnused 删除一个已经是Deleted状态,且不再被使用的对象。目前可能被使用的地方只有StoragePackage
  130. func (PackageDB) DeleteUnused(ctx SQLContext, packageID int64) error {
  131. _, err := ctx.Exec("delete from Package where PackageID = ? and State = ? and "+
  132. "not exists(select StorageID from StoragePackage where PackageID = ?)",
  133. packageID,
  134. consts.PackageStateDeleted,
  135. packageID,
  136. )
  137. return err
  138. }
  139. func (*PackageDB) ChangeState(ctx SQLContext, packageID int64, state string) error {
  140. _, err := ctx.Exec("update Package set State = ? where PackageID = ?", state, packageID)
  141. return err
  142. }

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