Skip to content

Commit

Permalink
all: unwrap database.NoticesStore interface (#7695)
Browse files Browse the repository at this point in the history
  • Loading branch information
unknwon committed Mar 18, 2024
1 parent e634aa6 commit b89f20e
Show file tree
Hide file tree
Showing 6 changed files with 67 additions and 78 deletions.
5 changes: 4 additions & 1 deletion internal/database/database.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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)
}
6 changes: 3 additions & 3 deletions internal/database/mirror.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand All @@ -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)
}
}
Expand Down
62 changes: 24 additions & 38 deletions internal/database/notices.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,64 +15,50 @@ 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,
},
).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
}

Expand All @@ -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:"-"`
Expand All @@ -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
}
Expand All @@ -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)
}
}
Expand Down
54 changes: 27 additions & 27 deletions internal/database/notices_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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},
Expand All @@ -81,30 +81,30 @@ 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
}
}
}

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 {
Expand All @@ -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)
}
10 changes: 5 additions & 5 deletions internal/database/repo.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}
}
Expand Down Expand Up @@ -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)
}
}
Expand All @@ -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)
}
}
Expand All @@ -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)
}
}
Expand Down Expand Up @@ -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)
}
}
Expand Down
8 changes: 4 additions & 4 deletions internal/route/admin/notice.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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 {
Expand All @@ -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
}
Expand Down

0 comments on commit b89f20e

Please sign in to comment.