lfs.go 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687
  1. package database
  2. import (
  3. "context"
  4. "errors"
  5. "fmt"
  6. "time"
  7. "gorm.io/gorm"
  8. "gogs.io/gogs/internal/errutil"
  9. "gogs.io/gogs/internal/lfsutil"
  10. )
  11. // LFSObject is the relation between an LFS object and a repository.
  12. type LFSObject struct {
  13. RepoID int64 `gorm:"primaryKey;auto_increment:false"`
  14. OID lfsutil.OID `gorm:"primaryKey;column:oid"`
  15. Size int64 `gorm:"not null"`
  16. Storage lfsutil.Storage `gorm:"not null"`
  17. CreatedAt time.Time `gorm:"not null"`
  18. }
  19. // LFSStore is the storage layer for LFS objects.
  20. type LFSStore struct {
  21. db *gorm.DB
  22. }
  23. func newLFSStore(db *gorm.DB) *LFSStore {
  24. return &LFSStore{db: db}
  25. }
  26. // CreateObject creates an LFS object record in database.
  27. func (s *LFSStore) CreateObject(ctx context.Context, repoID int64, oid lfsutil.OID, size int64, storage lfsutil.Storage) error {
  28. object := &LFSObject{
  29. RepoID: repoID,
  30. OID: oid,
  31. Size: size,
  32. Storage: storage,
  33. }
  34. return s.db.WithContext(ctx).Create(object).Error
  35. }
  36. type ErrLFSObjectNotExist struct {
  37. args errutil.Args
  38. }
  39. func IsErrLFSObjectNotExist(err error) bool {
  40. return errors.As(err, &ErrLFSObjectNotExist{})
  41. }
  42. func (err ErrLFSObjectNotExist) Error() string {
  43. return fmt.Sprintf("LFS object does not exist: %v", err.args)
  44. }
  45. func (ErrLFSObjectNotExist) NotFound() bool {
  46. return true
  47. }
  48. // GetObjectByOID returns the LFS object with given OID. It returns
  49. // ErrLFSObjectNotExist when not found.
  50. func (s *LFSStore) GetObjectByOID(ctx context.Context, repoID int64, oid lfsutil.OID) (*LFSObject, error) {
  51. object := new(LFSObject)
  52. err := s.db.WithContext(ctx).Where("repo_id = ? AND oid = ?", repoID, oid).First(object).Error
  53. if err != nil {
  54. if errors.Is(err, gorm.ErrRecordNotFound) {
  55. return nil, ErrLFSObjectNotExist{args: errutil.Args{"repoID": repoID, "oid": oid}}
  56. }
  57. return nil, err
  58. }
  59. return object, err
  60. }
  61. // GetObjectsByOIDs returns LFS objects found within "oids". The returned list
  62. // could have fewer elements if some oids were not found.
  63. func (s *LFSStore) GetObjectsByOIDs(ctx context.Context, repoID int64, oids ...lfsutil.OID) ([]*LFSObject, error) {
  64. if len(oids) == 0 {
  65. return []*LFSObject{}, nil
  66. }
  67. objects := make([]*LFSObject, 0, len(oids))
  68. err := s.db.WithContext(ctx).Where("repo_id = ? AND oid IN (?)", repoID, oids).Find(&objects).Error
  69. if err != nil && !errors.Is(err, gorm.ErrRecordNotFound) {
  70. return nil, err
  71. }
  72. return objects, nil
  73. }