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

2 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207
  1. package db
  2. /*
  3. import (
  4. "database/sql"
  5. "errors"
  6. "fmt"
  7. "github.com/jmoiron/sqlx"
  8. "github.com/samber/lo"
  9. cdssdk "gitlink.org.cn/cloudream/common/sdks/storage"
  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 cdssdk.PackageID) (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 cdssdk.BucketID, 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 (db *PackageDB) BatchTestPackageID(ctx SQLContext, pkgIDs []cdssdk.PackageID) (map[cdssdk.PackageID]bool, error) {
  29. if len(pkgIDs) == 0 {
  30. return make(map[cdssdk.PackageID]bool), nil
  31. }
  32. stmt, args, err := sqlx.In("select PackageID from Package where PackageID in (?)", lo.Uniq(pkgIDs))
  33. if err != nil {
  34. return nil, err
  35. }
  36. var avaiIDs []cdssdk.PackageID
  37. err = sqlx.Select(ctx, &avaiIDs, stmt, args...)
  38. if err != nil {
  39. return nil, err
  40. }
  41. avaiIDMap := make(map[cdssdk.PackageID]bool)
  42. for _, pkgID := range avaiIDs {
  43. avaiIDMap[pkgID] = true
  44. }
  45. return avaiIDMap, nil
  46. }
  47. func (*PackageDB) BatchGetAllPackageIDs(ctx SQLContext, start int, count int) ([]cdssdk.PackageID, error) {
  48. var ret []cdssdk.PackageID
  49. err := sqlx.Select(ctx, &ret, "select PackageID from Package limit ?, ?", start, count)
  50. return ret, err
  51. }
  52. func (db *PackageDB) GetBucketPackages(ctx SQLContext, userID cdssdk.UserID, bucketID cdssdk.BucketID) ([]model.Package, error) {
  53. var ret []model.Package
  54. err := sqlx.Select(ctx, &ret, "select Package.* from UserBucket, Package where UserID = ? and UserBucket.BucketID = ? and UserBucket.BucketID = Package.BucketID", userID, bucketID)
  55. return ret, err
  56. }
  57. // IsAvailable 判断一个用户是否拥有指定对象
  58. func (db *PackageDB) IsAvailable(ctx SQLContext, userID cdssdk.UserID, packageID cdssdk.PackageID) (bool, error) {
  59. var pkgID cdssdk.PackageID
  60. // 先根据PackageID找到Package,然后判断此Package所在的Bucket是不是归此用户所有
  61. err := sqlx.Get(ctx, &pkgID,
  62. "select Package.PackageID from Package, UserBucket where "+
  63. "Package.PackageID = ? and "+
  64. "Package.BucketID = UserBucket.BucketID and "+
  65. "UserBucket.UserID = ?",
  66. packageID, userID)
  67. if err == sql.ErrNoRows {
  68. return false, nil
  69. }
  70. if err != nil {
  71. return false, fmt.Errorf("find package failed, err: %w", err)
  72. }
  73. return true, nil
  74. }
  75. // GetUserPackage 获得Package,如果用户没有权限访问,则不会获得结果
  76. func (db *PackageDB) GetUserPackage(ctx SQLContext, userID cdssdk.UserID, packageID cdssdk.PackageID) (model.Package, error) {
  77. var ret model.Package
  78. err := sqlx.Get(ctx, &ret,
  79. "select Package.* from Package, UserBucket where"+
  80. " Package.PackageID = ? and"+
  81. " Package.BucketID = UserBucket.BucketID and"+
  82. " UserBucket.UserID = ?",
  83. packageID, userID)
  84. return ret, err
  85. }
  86. // 在指定名称的Bucket中查找指定名称的Package
  87. func (*PackageDB) GetUserPackageByName(ctx SQLContext, userID cdssdk.UserID, bucketName string, packageName string) (cdssdk.Package, error) {
  88. var ret model.Package
  89. err := sqlx.Get(ctx, &ret,
  90. "select Package.* from Package, Bucket, UserBucket where"+
  91. " Package.Name = ? and"+
  92. " Package.BucketID = Bucket.BucketID and"+
  93. " Bucket.Name = ? and"+
  94. " UserBucket.UserID = ? and"+
  95. " UserBucket.BucketID = Bucket.BucketID",
  96. packageName, bucketName, userID)
  97. return ret, err
  98. }
  99. func (db *PackageDB) Create(ctx SQLContext, bucketID cdssdk.BucketID, name string) (cdssdk.PackageID, error) {
  100. // 根据packagename和bucketid查询,若不存在则插入,若存在则返回错误
  101. var packageID int64
  102. err := sqlx.Get(ctx, &packageID, "select PackageID from Package where Name = ? AND BucketID = ? for update", name, bucketID)
  103. // 无错误代表存在记录
  104. if err == nil {
  105. return 0, fmt.Errorf("package with given Name and BucketID already exists")
  106. }
  107. // 错误不是记录不存在
  108. if !errors.Is(err, sql.ErrNoRows) {
  109. return 0, fmt.Errorf("query Package by PackageName and BucketID failed, err: %w", err)
  110. }
  111. sql := "insert into Package(Name, BucketID, State) values(?,?,?)"
  112. r, err := ctx.Exec(sql, name, bucketID, cdssdk.PackageStateNormal)
  113. if err != nil {
  114. return 0, fmt.Errorf("insert package failed, err: %w", err)
  115. }
  116. packageID, err = r.LastInsertId()
  117. if err != nil {
  118. return 0, fmt.Errorf("get id of inserted package failed, err: %w", err)
  119. }
  120. return cdssdk.PackageID(packageID), nil
  121. }
  122. // SoftDelete 设置一个对象被删除,并将相关数据删除
  123. func (db *PackageDB) SoftDelete(ctx SQLContext, packageID cdssdk.PackageID) error {
  124. obj, err := db.GetByID(ctx, packageID)
  125. if err != nil {
  126. return fmt.Errorf("get package failed, err: %w", err)
  127. }
  128. // 不是正常状态的Package,则不删除
  129. // TODO 未来可能有其他状态
  130. if obj.State != cdssdk.PackageStateNormal {
  131. return nil
  132. }
  133. err = db.ChangeState(ctx, packageID, cdssdk.PackageStateDeleted)
  134. if err != nil {
  135. return fmt.Errorf("change package state failed, err: %w", err)
  136. }
  137. err = db.ObjectAccessStat().DeleteInPackage(ctx, packageID)
  138. if err != nil {
  139. return fmt.Errorf("delete from object access stat: %w", err)
  140. }
  141. err = db.ObjectBlock().DeleteInPackage(ctx, packageID)
  142. if err != nil {
  143. return fmt.Errorf("delete from object rep failed, err: %w", err)
  144. }
  145. if err := db.PinnedObject().DeleteInPackage(ctx, packageID); err != nil {
  146. return fmt.Errorf("deleting pinned objects in package: %w", err)
  147. }
  148. if err := db.Object().DeleteInPackage(ctx, packageID); err != nil {
  149. return fmt.Errorf("deleting objects in package: %w", err)
  150. }
  151. _, err = db.StoragePackage().SetAllPackageDeleted(ctx, packageID)
  152. if err != nil {
  153. return fmt.Errorf("set storage package deleted failed, err: %w", err)
  154. }
  155. return nil
  156. }
  157. // DeleteUnused 删除一个已经是Deleted状态,且不再被使用的对象。目前可能被使用的地方只有StoragePackage
  158. func (PackageDB) DeleteUnused(ctx SQLContext, packageID cdssdk.PackageID) error {
  159. _, err := ctx.Exec("delete from Package where PackageID = ? and State = ? and "+
  160. "not exists(select StorageID from StoragePackage where PackageID = ?)",
  161. packageID,
  162. cdssdk.PackageStateDeleted,
  163. packageID,
  164. )
  165. return err
  166. }
  167. func (*PackageDB) ChangeState(ctx SQLContext, packageID cdssdk.PackageID, state string) error {
  168. _, err := ctx.Exec("update Package set State = ? where PackageID = ?", state, packageID)
  169. return err
  170. }
  171. */

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