Jelajahi Sumber

all: unwrap `database.NoticesStore` interface (#7695)

Joe Chen 11 bulan lalu
induk
melakukan
b89f20e02d

+ 4 - 1
internal/database/database.go

@@ -123,7 +123,6 @@ func NewConnection(w logger.Writer) (*gorm.DB, error) {
 	}
 
 	// Initialize stores, sorted in alphabetical order.
-	Notices = NewNoticesStore(db)
 	Orgs = NewOrgsStore(db)
 	Perms = NewPermsStore(db)
 	Repos = NewReposStore(db)
@@ -173,3 +172,7 @@ var loadedLoginSourceFilesStore loginSourceFilesStore
 func (db *DB) LoginSources() *LoginSourcesStore {
 	return newLoginSourcesStore(db.db, loadedLoginSourceFilesStore)
 }
+
+func (db *DB) Notices() *NoticesStore {
+	return newNoticesStore(db.db)
+}

+ 3 - 3
internal/database/mirror.go

@@ -215,7 +215,7 @@ func (m *Mirror) runSync() ([]*mirrorSyncResult, bool) {
 	// good condition to prevent long blocking on URL resolution without syncing anything.
 	if !git.IsURLAccessible(time.Minute, m.RawAddress()) {
 		desc := fmt.Sprintf("Source URL of mirror repository '%s' is not accessible: %s", m.Repo.FullName(), m.MosaicsAddress())
-		if err := Notices.Create(context.TODO(), NoticeTypeRepository, desc); err != nil {
+		if err := Handle.Notices().Create(context.TODO(), NoticeTypeRepository, desc); err != nil {
 			log.Error("CreateRepositoryNotice: %v", err)
 		}
 		return nil, false
@@ -231,7 +231,7 @@ func (m *Mirror) runSync() ([]*mirrorSyncResult, bool) {
 	if err != nil {
 		desc := fmt.Sprintf("Failed to update mirror repository '%s': %s", repoPath, stderr)
 		log.Error(desc)
-		if err = Notices.Create(context.TODO(), NoticeTypeRepository, desc); err != nil {
+		if err = Handle.Notices().Create(context.TODO(), NoticeTypeRepository, desc); err != nil {
 			log.Error("CreateRepositoryNotice: %v", err)
 		}
 		return nil, false
@@ -249,7 +249,7 @@ func (m *Mirror) runSync() ([]*mirrorSyncResult, bool) {
 			"git", "remote", "update", "--prune"); err != nil {
 			desc := fmt.Sprintf("Failed to update mirror wiki repository '%s': %s", wikiPath, stderr)
 			log.Error(desc)
-			if err = Notices.Create(context.TODO(), NoticeTypeRepository, desc); err != nil {
+			if err = Handle.Notices().Create(context.TODO(), NoticeTypeRepository, desc); err != nil {
 				log.Error("CreateRepositoryNotice: %v", err)
 			}
 		}

+ 24 - 38
internal/database/notices.go

@@ -15,37 +15,18 @@ import (
 	log "unknwon.dev/clog/v2"
 )
 
-// NoticesStore is the persistent interface for system notices.
-type NoticesStore interface {
-	// Create creates a system notice with the given type and description.
-	Create(ctx context.Context, typ NoticeType, desc string) error
-	// DeleteByIDs deletes system notices by given IDs.
-	DeleteByIDs(ctx context.Context, ids ...int64) error
-	// DeleteAll deletes all system notices.
-	DeleteAll(ctx context.Context) error
-	// List returns a list of system notices. Results are paginated by given page
-	// and page size, and sorted by primary key (id) in descending order.
-	List(ctx context.Context, page, pageSize int) ([]*Notice, error)
-	// Count returns the total number of system notices.
-	Count(ctx context.Context) int64
+// NoticesStore is the storage layer for system notices.
+type NoticesStore struct {
+	db *gorm.DB
 }
 
-var Notices NoticesStore
-
-var _ NoticesStore = (*noticesStore)(nil)
-
-type noticesStore struct {
-	*gorm.DB
-}
-
-// NewNoticesStore returns a persistent interface for system notices with given
-// database connection.
-func NewNoticesStore(db *gorm.DB) NoticesStore {
-	return &noticesStore{DB: db}
+func newNoticesStore(db *gorm.DB) *NoticesStore {
+	return &NoticesStore{db: db}
 }
 
-func (s *noticesStore) Create(ctx context.Context, typ NoticeType, desc string) error {
-	return s.WithContext(ctx).Create(
+// Create creates a system notice with the given type and description.
+func (s *NoticesStore) Create(ctx context.Context, typ NoticeType, desc string) error {
+	return s.db.WithContext(ctx).Create(
 		&Notice{
 			Type:        typ,
 			Description: desc,
@@ -53,26 +34,31 @@ func (s *noticesStore) Create(ctx context.Context, typ NoticeType, desc string)
 	).Error
 }
 
-func (s *noticesStore) DeleteByIDs(ctx context.Context, ids ...int64) error {
-	return s.WithContext(ctx).Where("id IN (?)", ids).Delete(&Notice{}).Error
+// DeleteByIDs deletes system notices by given IDs.
+func (s *NoticesStore) DeleteByIDs(ctx context.Context, ids ...int64) error {
+	return s.db.WithContext(ctx).Where("id IN (?)", ids).Delete(&Notice{}).Error
 }
 
-func (s *noticesStore) DeleteAll(ctx context.Context) error {
-	return s.WithContext(ctx).Where("TRUE").Delete(&Notice{}).Error
+// DeleteAll deletes all system notices.
+func (s *NoticesStore) DeleteAll(ctx context.Context) error {
+	return s.db.WithContext(ctx).Where("TRUE").Delete(&Notice{}).Error
 }
 
-func (s *noticesStore) List(ctx context.Context, page, pageSize int) ([]*Notice, error) {
+// List returns a list of system notices. Results are paginated by given page
+// and page size, and sorted by primary key (id) in descending order.
+func (s *NoticesStore) List(ctx context.Context, page, pageSize int) ([]*Notice, error) {
 	notices := make([]*Notice, 0, pageSize)
-	return notices, s.WithContext(ctx).
+	return notices, s.db.WithContext(ctx).
 		Limit(pageSize).Offset((page - 1) * pageSize).
 		Order("id DESC").
 		Find(&notices).
 		Error
 }
 
-func (s *noticesStore) Count(ctx context.Context) int64 {
+// Count returns the total number of system notices.
+func (s *NoticesStore) Count(ctx context.Context) int64 {
 	var count int64
-	s.WithContext(ctx).Model(&Notice{}).Count(&count)
+	s.db.WithContext(ctx).Model(&Notice{}).Count(&count)
 	return count
 }
 
@@ -89,7 +75,7 @@ func (t NoticeType) TrStr() string {
 
 // Notice represents a system notice for admin.
 type Notice struct {
-	ID          int64 `gorm:"primarykey"`
+	ID          int64 `gorm:"primaryKey"`
 	Type        NoticeType
 	Description string    `xorm:"TEXT" gorm:"type:TEXT"`
 	Created     time.Time `xorm:"-" gorm:"-" json:"-"`
@@ -105,7 +91,7 @@ func (n *Notice) BeforeCreate(tx *gorm.DB) error {
 }
 
 // AfterFind implements the GORM query hook.
-func (n *Notice) AfterFind(_ *gorm.DB) error {
+func (n *Notice) AfterFind(*gorm.DB) error {
 	n.Created = time.Unix(n.CreatedUnix, 0).Local()
 	return nil
 }
@@ -115,7 +101,7 @@ func (n *Notice) AfterFind(_ *gorm.DB) error {
 func RemoveAllWithNotice(title, path string) {
 	if err := os.RemoveAll(path); err != nil {
 		desc := fmt.Sprintf("%s [%s]: %v", title, path, err)
-		if err = Notices.Create(context.Background(), NoticeTypeRepository, desc); err != nil {
+		if err = Handle.Notices().Create(context.Background(), NoticeTypeRepository, desc); err != nil {
 			log.Error("Failed to create repository notice: %v", err)
 		}
 	}

+ 27 - 27
internal/database/notices_test.go

@@ -65,13 +65,13 @@ func TestNotices(t *testing.T) {
 	t.Parallel()
 
 	ctx := context.Background()
-	db := &noticesStore{
-		DB: newTestDB(t, "noticesStore"),
+	s := &NoticesStore{
+		db: newTestDB(t, "NoticesStore"),
 	}
 
 	for _, tc := range []struct {
 		name string
-		test func(t *testing.T, ctx context.Context, db *noticesStore)
+		test func(t *testing.T, ctx context.Context, s *NoticesStore)
 	}{
 		{"Create", noticesCreate},
 		{"DeleteByIDs", noticesDeleteByIDs},
@@ -81,10 +81,10 @@ func TestNotices(t *testing.T) {
 	} {
 		t.Run(tc.name, func(t *testing.T) {
 			t.Cleanup(func() {
-				err := clearTables(t, db.DB)
+				err := clearTables(t, s.db)
 				require.NoError(t, err)
 			})
-			tc.test(t, ctx, db)
+			tc.test(t, ctx, s)
 		})
 		if t.Failed() {
 			break
@@ -92,19 +92,19 @@ func TestNotices(t *testing.T) {
 	}
 }
 
-func noticesCreate(t *testing.T, ctx context.Context, db *noticesStore) {
-	err := db.Create(ctx, NoticeTypeRepository, "test")
+func noticesCreate(t *testing.T, ctx context.Context, s *NoticesStore) {
+	err := s.Create(ctx, NoticeTypeRepository, "test")
 	require.NoError(t, err)
 
-	count := db.Count(ctx)
+	count := s.Count(ctx)
 	assert.Equal(t, int64(1), count)
 }
 
-func noticesDeleteByIDs(t *testing.T, ctx context.Context, db *noticesStore) {
-	err := db.Create(ctx, NoticeTypeRepository, "test")
+func noticesDeleteByIDs(t *testing.T, ctx context.Context, s *NoticesStore) {
+	err := s.Create(ctx, NoticeTypeRepository, "test")
 	require.NoError(t, err)
 
-	notices, err := db.List(ctx, 1, 10)
+	notices, err := s.List(ctx, 1, 10)
 	require.NoError(t, err)
 	ids := make([]int64, 0, len(notices))
 	for _, notice := range notices {
@@ -113,51 +113,51 @@ func noticesDeleteByIDs(t *testing.T, ctx context.Context, db *noticesStore) {
 
 	// Non-existing IDs should be ignored
 	ids = append(ids, 404)
-	err = db.DeleteByIDs(ctx, ids...)
+	err = s.DeleteByIDs(ctx, ids...)
 	require.NoError(t, err)
 
-	count := db.Count(ctx)
+	count := s.Count(ctx)
 	assert.Equal(t, int64(0), count)
 }
 
-func noticesDeleteAll(t *testing.T, ctx context.Context, db *noticesStore) {
-	err := db.Create(ctx, NoticeTypeRepository, "test")
+func noticesDeleteAll(t *testing.T, ctx context.Context, s *NoticesStore) {
+	err := s.Create(ctx, NoticeTypeRepository, "test")
 	require.NoError(t, err)
 
-	err = db.DeleteAll(ctx)
+	err = s.DeleteAll(ctx)
 	require.NoError(t, err)
 
-	count := db.Count(ctx)
+	count := s.Count(ctx)
 	assert.Equal(t, int64(0), count)
 }
 
-func noticesList(t *testing.T, ctx context.Context, db *noticesStore) {
-	err := db.Create(ctx, NoticeTypeRepository, "test 1")
+func noticesList(t *testing.T, ctx context.Context, s *NoticesStore) {
+	err := s.Create(ctx, NoticeTypeRepository, "test 1")
 	require.NoError(t, err)
-	err = db.Create(ctx, NoticeTypeRepository, "test 2")
+	err = s.Create(ctx, NoticeTypeRepository, "test 2")
 	require.NoError(t, err)
 
-	got1, err := db.List(ctx, 1, 1)
+	got1, err := s.List(ctx, 1, 1)
 	require.NoError(t, err)
 	require.Len(t, got1, 1)
 
-	got2, err := db.List(ctx, 2, 1)
+	got2, err := s.List(ctx, 2, 1)
 	require.NoError(t, err)
 	require.Len(t, got2, 1)
 	assert.True(t, got1[0].ID > got2[0].ID)
 
-	got, err := db.List(ctx, 1, 3)
+	got, err := s.List(ctx, 1, 3)
 	require.NoError(t, err)
 	require.Len(t, got, 2)
 }
 
-func noticesCount(t *testing.T, ctx context.Context, db *noticesStore) {
-	count := db.Count(ctx)
+func noticesCount(t *testing.T, ctx context.Context, s *NoticesStore) {
+	count := s.Count(ctx)
 	assert.Equal(t, int64(0), count)
 
-	err := db.Create(ctx, NoticeTypeRepository, "test")
+	err := s.Create(ctx, NoticeTypeRepository, "test")
 	require.NoError(t, err)
 
-	count = db.Count(ctx)
+	count = s.Count(ctx)
 	assert.Equal(t, int64(1), count)
 }

+ 5 - 5
internal/database/repo.go

@@ -1947,7 +1947,7 @@ func DeleteOldRepositoryArchives() {
 					if err = os.Remove(archivePath); err != nil {
 						desc := fmt.Sprintf("Failed to health delete archive '%s': %v", archivePath, err)
 						log.Warn(desc)
-						if err = Notices.Create(context.TODO(), NoticeTypeRepository, desc); err != nil {
+						if err = Handle.Notices().Create(context.TODO(), NoticeTypeRepository, desc); err != nil {
 							log.Error("CreateRepositoryNotice: %v", err)
 						}
 					}
@@ -1985,7 +1985,7 @@ func gatherMissingRepoRecords() ([]*Repository, error) {
 			}
 			return nil
 		}); err != nil {
-		if err2 := Notices.Create(context.TODO(), NoticeTypeRepository, fmt.Sprintf("gatherMissingRepoRecords: %v", err)); err2 != nil {
+		if err2 := Handle.Notices().Create(context.TODO(), NoticeTypeRepository, fmt.Sprintf("gatherMissingRepoRecords: %v", err)); err2 != nil {
 			return nil, fmt.Errorf("CreateRepositoryNotice: %v", err)
 		}
 	}
@@ -2006,7 +2006,7 @@ func DeleteMissingRepositories() error {
 	for _, repo := range repos {
 		log.Trace("Deleting %d/%d...", repo.OwnerID, repo.ID)
 		if err := DeleteRepository(repo.OwnerID, repo.ID); err != nil {
-			if err2 := Notices.Create(context.TODO(), NoticeTypeRepository, fmt.Sprintf("DeleteRepository [%d]: %v", repo.ID, err)); err2 != nil {
+			if err2 := Handle.Notices().Create(context.TODO(), NoticeTypeRepository, fmt.Sprintf("DeleteRepository [%d]: %v", repo.ID, err)); err2 != nil {
 				return fmt.Errorf("CreateRepositoryNotice: %v", err)
 			}
 		}
@@ -2028,7 +2028,7 @@ func ReinitMissingRepositories() error {
 	for _, repo := range repos {
 		log.Trace("Initializing %d/%d...", repo.OwnerID, repo.ID)
 		if err := git.Init(repo.RepoPath(), git.InitOptions{Bare: true}); err != nil {
-			if err2 := Notices.Create(context.TODO(), NoticeTypeRepository, fmt.Sprintf("init repository [repo_id: %d]: %v", repo.ID, err)); err2 != nil {
+			if err2 := Handle.Notices().Create(context.TODO(), NoticeTypeRepository, fmt.Sprintf("init repository [repo_id: %d]: %v", repo.ID, err)); err2 != nil {
 				return fmt.Errorf("create repository notice: %v", err)
 			}
 		}
@@ -2086,7 +2086,7 @@ func GitFsck() {
 			if err != nil {
 				desc := fmt.Sprintf("Failed to perform health check on repository '%s': %v", repoPath, err)
 				log.Warn(desc)
-				if err = Notices.Create(context.TODO(), NoticeTypeRepository, desc); err != nil {
+				if err = Handle.Notices().Create(context.TODO(), NoticeTypeRepository, desc); err != nil {
 					log.Error("CreateRepositoryNotice: %v", err)
 				}
 			}

+ 4 - 4
internal/route/admin/notice.go

@@ -25,14 +25,14 @@ func Notices(c *context.Context) {
 	c.Data["PageIsAdmin"] = true
 	c.Data["PageIsAdminNotices"] = true
 
-	total := database.Notices.Count(c.Req.Context())
+	total := database.Handle.Notices().Count(c.Req.Context())
 	page := c.QueryInt("page")
 	if page <= 1 {
 		page = 1
 	}
 	c.Data["Page"] = paginater.New(int(total), conf.UI.Admin.NoticePagingNum, page, 5)
 
-	notices, err := database.Notices.List(c.Req.Context(), page, conf.UI.Admin.NoticePagingNum)
+	notices, err := database.Handle.Notices().List(c.Req.Context(), page, conf.UI.Admin.NoticePagingNum)
 	if err != nil {
 		c.Error(err, "list notices")
 		return
@@ -53,7 +53,7 @@ func DeleteNotices(c *context.Context) {
 		}
 	}
 
-	if err := database.Notices.DeleteByIDs(c.Req.Context(), ids...); err != nil {
+	if err := database.Handle.Notices().DeleteByIDs(c.Req.Context(), ids...); err != nil {
 		c.Flash.Error("DeleteNoticesByIDs: " + err.Error())
 		c.Status(http.StatusInternalServerError)
 	} else {
@@ -63,7 +63,7 @@ func DeleteNotices(c *context.Context) {
 }
 
 func EmptyNotices(c *context.Context) {
-	if err := database.Notices.DeleteAll(c.Req.Context()); err != nil {
+	if err := database.Handle.Notices().DeleteAll(c.Req.Context()); err != nil {
 		c.Error(err, "delete notices")
 		return
 	}