lfs.go 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  1. // Copyright 2020 The Gogs Authors. All rights reserved.
  2. // Use of this source code is governed by a MIT-style
  3. // license that can be found in the LICENSE file.
  4. package db
  5. import (
  6. "context"
  7. "fmt"
  8. "time"
  9. "gorm.io/gorm"
  10. "gogs.io/gogs/internal/errutil"
  11. "gogs.io/gogs/internal/lfsutil"
  12. )
  13. // LFSStore is the persistent interface for LFS objects.
  14. //
  15. // NOTE: All methods are sorted in alphabetical order.
  16. type LFSStore interface {
  17. // CreateObject creates a LFS object record in database.
  18. CreateObject(ctx context.Context, repoID int64, oid lfsutil.OID, size int64, storage lfsutil.Storage) error
  19. // GetObjectByOID returns the LFS object with given OID. It returns
  20. // ErrLFSObjectNotExist when not found.
  21. GetObjectByOID(ctx context.Context, repoID int64, oid lfsutil.OID) (*LFSObject, error)
  22. // GetObjectsByOIDs returns LFS objects found within "oids". The returned list
  23. // could have less elements if some oids were not found.
  24. GetObjectsByOIDs(ctx context.Context, repoID int64, oids ...lfsutil.OID) ([]*LFSObject, error)
  25. }
  26. var LFS LFSStore
  27. // LFSObject is the relation between an LFS object and a repository.
  28. type LFSObject struct {
  29. RepoID int64 `gorm:"primaryKey;auto_increment:false"`
  30. OID lfsutil.OID `gorm:"primaryKey;column:oid"`
  31. Size int64 `gorm:"not null"`
  32. Storage lfsutil.Storage `gorm:"not null"`
  33. CreatedAt time.Time `gorm:"not null"`
  34. }
  35. var _ LFSStore = (*lfs)(nil)
  36. type lfs struct {
  37. *gorm.DB
  38. }
  39. func (db *lfs) CreateObject(ctx context.Context, repoID int64, oid lfsutil.OID, size int64, storage lfsutil.Storage) error {
  40. object := &LFSObject{
  41. RepoID: repoID,
  42. OID: oid,
  43. Size: size,
  44. Storage: storage,
  45. }
  46. return db.WithContext(ctx).Create(object).Error
  47. }
  48. type ErrLFSObjectNotExist struct {
  49. args errutil.Args
  50. }
  51. func IsErrLFSObjectNotExist(err error) bool {
  52. _, ok := err.(ErrLFSObjectNotExist)
  53. return ok
  54. }
  55. func (err ErrLFSObjectNotExist) Error() string {
  56. return fmt.Sprintf("LFS object does not exist: %v", err.args)
  57. }
  58. func (ErrLFSObjectNotExist) NotFound() bool {
  59. return true
  60. }
  61. func (db *lfs) GetObjectByOID(ctx context.Context, repoID int64, oid lfsutil.OID) (*LFSObject, error) {
  62. object := new(LFSObject)
  63. err := db.WithContext(ctx).Where("repo_id = ? AND oid = ?", repoID, oid).First(object).Error
  64. if err != nil {
  65. if err == gorm.ErrRecordNotFound {
  66. return nil, ErrLFSObjectNotExist{args: errutil.Args{"repoID": repoID, "oid": oid}}
  67. }
  68. return nil, err
  69. }
  70. return object, err
  71. }
  72. func (db *lfs) GetObjectsByOIDs(ctx context.Context, repoID int64, oids ...lfsutil.OID) ([]*LFSObject, error) {
  73. if len(oids) == 0 {
  74. return []*LFSObject{}, nil
  75. }
  76. objects := make([]*LFSObject, 0, len(oids))
  77. err := db.WithContext(ctx).Where("repo_id = ? AND oid IN (?)", repoID, oids).Find(&objects).Error
  78. if err != nil && err != gorm.ErrRecordNotFound {
  79. return nil, err
  80. }
  81. return objects, nil
  82. }