lfs.go 2.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  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. "fmt"
  7. "time"
  8. "github.com/jinzhu/gorm"
  9. "gogs.io/gogs/internal/errutil"
  10. "gogs.io/gogs/internal/lfsutil"
  11. )
  12. // LFSStore is the persistent interface for LFS objects.
  13. //
  14. // NOTE: All methods are sorted in alphabetical order.
  15. type LFSStore interface {
  16. // CreateObject creates a LFS object record in database.
  17. CreateObject(repoID int64, oid lfsutil.OID, size int64, storage lfsutil.Storage) error
  18. // GetObjectByOID returns the LFS object with given OID. It returns ErrLFSObjectNotExist
  19. // when not found.
  20. GetObjectByOID(repoID int64, oid lfsutil.OID) (*LFSObject, error)
  21. // GetObjectsByOIDs returns LFS objects found within "oids". The returned list could have
  22. // less elements if some oids were not found.
  23. GetObjectsByOIDs(repoID int64, oids ...lfsutil.OID) ([]*LFSObject, error)
  24. }
  25. var LFS LFSStore
  26. // LFSObject is the relation between an LFS object and a repository.
  27. type LFSObject struct {
  28. RepoID int64 `gorm:"PRIMARY_KEY;AUTO_INCREMENT:false"`
  29. OID lfsutil.OID `gorm:"PRIMARY_KEY;COLUMN:oid"`
  30. Size int64 `gorm:"NOT NULL"`
  31. Storage lfsutil.Storage `gorm:"NOT NULL"`
  32. CreatedAt time.Time `gorm:"NOT NULL"`
  33. }
  34. var _ LFSStore = (*lfs)(nil)
  35. type lfs struct {
  36. *gorm.DB
  37. }
  38. func (db *lfs) CreateObject(repoID int64, oid lfsutil.OID, size int64, storage lfsutil.Storage) error {
  39. object := &LFSObject{
  40. RepoID: repoID,
  41. OID: oid,
  42. Size: size,
  43. Storage: storage,
  44. }
  45. return db.DB.Create(object).Error
  46. }
  47. type ErrLFSObjectNotExist struct {
  48. args errutil.Args
  49. }
  50. func IsErrLFSObjectNotExist(err error) bool {
  51. _, ok := err.(ErrLFSObjectNotExist)
  52. return ok
  53. }
  54. func (err ErrLFSObjectNotExist) Error() string {
  55. return fmt.Sprintf("LFS object does not exist: %v", err.args)
  56. }
  57. func (ErrLFSObjectNotExist) NotFound() bool {
  58. return true
  59. }
  60. func (db *lfs) GetObjectByOID(repoID int64, oid lfsutil.OID) (*LFSObject, error) {
  61. object := new(LFSObject)
  62. err := db.Where("repo_id = ? AND oid = ?", repoID, oid).First(object).Error
  63. if err != nil {
  64. if gorm.IsRecordNotFoundError(err) {
  65. return nil, ErrLFSObjectNotExist{args: errutil.Args{"repoID": repoID, "oid": oid}}
  66. }
  67. return nil, err
  68. }
  69. return object, err
  70. }
  71. func (db *lfs) GetObjectsByOIDs(repoID int64, oids ...lfsutil.OID) ([]*LFSObject, error) {
  72. if len(oids) == 0 {
  73. return []*LFSObject{}, nil
  74. }
  75. objects := make([]*LFSObject, 0, len(oids))
  76. err := db.Where("repo_id = ? AND oid IN (?)", repoID, oids).Find(&objects).Error
  77. if err != nil && err != gorm.ErrRecordNotFound {
  78. return nil, err
  79. }
  80. return objects, nil
  81. }