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.

object_block.go 4.0 kB

2 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  1. package db
  2. import (
  3. "database/sql"
  4. "fmt"
  5. "strconv"
  6. "strings"
  7. "github.com/jmoiron/sqlx"
  8. cdssdk "gitlink.org.cn/cloudream/common/sdks/storage"
  9. stgmod "gitlink.org.cn/cloudream/storage/common/models"
  10. "gitlink.org.cn/cloudream/storage/common/pkgs/db/model"
  11. )
  12. type ObjectBlockDB struct {
  13. *DB
  14. }
  15. func (db *DB) ObjectBlock() *ObjectBlockDB {
  16. return &ObjectBlockDB{DB: db}
  17. }
  18. func (db *ObjectBlockDB) Create(ctx SQLContext, objectID cdssdk.ObjectID, index int, fileHash string, nodeID cdssdk.NodeID) error {
  19. _, err := ctx.Exec("insert into ObjectBlock values(?,?,?,?)", objectID, index, fileHash, nodeID)
  20. return err
  21. }
  22. func (db *ObjectBlockDB) DeleteObjectAll(ctx SQLContext, objectID cdssdk.ObjectID) error {
  23. _, err := ctx.Exec("delete from ObjectBlock where ObjectID = ?", objectID)
  24. return err
  25. }
  26. func (db *ObjectBlockDB) DeleteInPackage(ctx SQLContext, packageID cdssdk.PackageID) error {
  27. _, err := ctx.Exec("delete ObjectBlock from ObjectBlock inner join Object on ObjectBlock.ObjectID = Object.ObjectID where PackageID = ?", packageID)
  28. return err
  29. }
  30. func (db *ObjectBlockDB) CountBlockWithHash(ctx SQLContext, fileHash string) (int, error) {
  31. var cnt int
  32. err := sqlx.Get(ctx, &cnt,
  33. "select count(FileHash) from ObjectBlock, Object, Package where FileHash = ? and"+
  34. " ObjectBlock.ObjectID = Object.ObjectID and"+
  35. " Object.PackageID = Package.PackageID and"+
  36. " Package.State = ?", fileHash, cdssdk.PackageStateNormal)
  37. if err == sql.ErrNoRows {
  38. return 0, nil
  39. }
  40. return cnt, err
  41. }
  42. func (db *ObjectBlockDB) GetPackageBlockDetails(ctx SQLContext, packageID cdssdk.PackageID) ([]stgmod.ObjectDetail, error) {
  43. var objs []model.Object
  44. err := sqlx.Select(ctx, &objs, "select * from Object where PackageID = ? order by ObjectID asc", packageID)
  45. if err != nil {
  46. return nil, fmt.Errorf("query objectIDs: %w", err)
  47. }
  48. rets := make([]stgmod.ObjectDetail, 0, len(objs))
  49. for _, obj := range objs {
  50. var cachedObjectNodeIDs []cdssdk.NodeID
  51. err := sqlx.Select(ctx, &cachedObjectNodeIDs,
  52. "select NodeID from Object, Cache where"+
  53. " ObjectID = ? and Object.FileHash = Cache.FileHash",
  54. obj.ObjectID,
  55. )
  56. if err != nil {
  57. return nil, err
  58. }
  59. var blockTmpRets []struct {
  60. Index int `db:"Index"`
  61. FileHashes string `db:"FileHashes"`
  62. NodeIDs string `db:"NodeIDs"`
  63. CachedNodeIDs *string `db:"CachedNodeIDs"`
  64. }
  65. err = sqlx.Select(ctx,
  66. &blockTmpRets,
  67. "select ObjectBlock.Index, group_concat(distinct ObjectBlock.FileHash) as FileHashes, group_concat(distinct ObjectBlock.NodeID) as NodeIDs, group_concat(distinct Cache.NodeID) as CachedNodeIDs"+
  68. " from ObjectBlock left join Cache on ObjectBlock.FileHash = Cache.FileHash"+
  69. " where ObjectID = ? group by ObjectBlock.Index",
  70. obj.ObjectID,
  71. )
  72. if err != nil {
  73. return nil, err
  74. }
  75. blocks := make([]stgmod.ObjectBlockDetail, 0, len(blockTmpRets))
  76. for _, tmp := range blockTmpRets {
  77. var block stgmod.ObjectBlockDetail
  78. block.Index = tmp.Index
  79. block.FileHash = splitConcatedFileHash(tmp.FileHashes)[0]
  80. block.NodeIDs = splitConcatedNodeID(tmp.NodeIDs)
  81. if tmp.CachedNodeIDs != nil {
  82. block.CachedNodeIDs = splitConcatedNodeID(*tmp.CachedNodeIDs)
  83. }
  84. blocks = append(blocks, block)
  85. }
  86. rets = append(rets, stgmod.NewObjectDetail(obj, cachedObjectNodeIDs, blocks))
  87. }
  88. return rets, nil
  89. }
  90. // 按逗号切割字符串,并将每一个部分解析为一个int64的ID。
  91. // 注:需要外部保证分隔的每一个部分都是正确的10进制数字格式
  92. func splitConcatedNodeID(idStr string) []cdssdk.NodeID {
  93. idStrs := strings.Split(idStr, ",")
  94. ids := make([]cdssdk.NodeID, 0, len(idStrs))
  95. for _, str := range idStrs {
  96. // 假设传入的ID是正确的数字格式
  97. id, _ := strconv.ParseInt(str, 10, 64)
  98. ids = append(ids, cdssdk.NodeID(id))
  99. }
  100. return ids
  101. }
  102. // 按逗号切割字符串
  103. func splitConcatedFileHash(idStr string) []string {
  104. idStrs := strings.Split(idStr, ",")
  105. return idStrs
  106. }

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