mirror of
https://github.com/go-gitea/gitea.git
synced 2025-07-19 06:20:48 +02:00
DATABASE
This commit is contained in:
parent
7a635ddf97
commit
540c3f00eb
84
models/fixtures/user_notification_settings.yml
Normal file
84
models/fixtures/user_notification_settings.yml
Normal file
@ -0,0 +1,84 @@
|
||||
- user_id: 1
|
||||
actions: failureonly
|
||||
- user_id: 2
|
||||
actions: failureonly
|
||||
- user_id: 3
|
||||
actions: failureonly
|
||||
- user_id: 4
|
||||
actions: failureonly
|
||||
- user_id: 5
|
||||
actions: failureonly
|
||||
- user_id: 6
|
||||
actions: failureonly
|
||||
- user_id: 7
|
||||
actions: failureonly
|
||||
- user_id: 8
|
||||
actions: failureonly
|
||||
- user_id: 9
|
||||
actions: failureonly
|
||||
- user_id: 10
|
||||
actions: failureonly
|
||||
- user_id: 11
|
||||
actions: failureonly
|
||||
- user_id: 12
|
||||
actions: failureonly
|
||||
- user_id: 13
|
||||
actions: failureonly
|
||||
- user_id: 14
|
||||
actions: failureonly
|
||||
- user_id: 15
|
||||
actions: failureonly
|
||||
- user_id: 16
|
||||
actions: failureonly
|
||||
- user_id: 17
|
||||
actions: failureonly
|
||||
- user_id: 18
|
||||
actions: failureonly
|
||||
- user_id: 19
|
||||
actions: failureonly
|
||||
- user_id: 20
|
||||
actions: failureonly
|
||||
- user_id: 21
|
||||
actions: failureonly
|
||||
- user_id: 22
|
||||
actions: failureonly
|
||||
- user_id: 23
|
||||
actions: failureonly
|
||||
- user_id: 24
|
||||
actions: failureonly
|
||||
- user_id: 25
|
||||
actions: failureonly
|
||||
- user_id: 26
|
||||
actions: failureonly
|
||||
- user_id: 27
|
||||
actions: failureonly
|
||||
- user_id: 28
|
||||
actions: failureonly
|
||||
- user_id: 29
|
||||
actions: failureonly
|
||||
- user_id: 30
|
||||
actions: failureonly
|
||||
- user_id: 31
|
||||
actions: failureonly
|
||||
- user_id: 32
|
||||
actions: failureonly
|
||||
- user_id: 33
|
||||
actions: failureonly
|
||||
- user_id: 34
|
||||
actions: failureonly
|
||||
- user_id: 35
|
||||
actions: failureonly
|
||||
- user_id: 36
|
||||
actions: failureonly
|
||||
- user_id: 37
|
||||
actions: failureonly
|
||||
- user_id: 38
|
||||
actions: failureonly
|
||||
- user_id: 39
|
||||
actions: failureonly
|
||||
- user_id: 40
|
||||
actions: failureonly
|
||||
- user_id: 41
|
||||
actions: failureonly
|
||||
- user_id: 42
|
||||
actions: failureonly
|
@ -382,6 +382,7 @@ func prepareMigrationTasks() []*migration {
|
||||
newMigration(318, "Add anonymous_access_mode for repo_unit", v1_24.AddRepoUnitAnonymousAccessMode),
|
||||
newMigration(319, "Add ExclusiveOrder to Label table", v1_24.AddExclusiveOrderColumnToLabelTable),
|
||||
newMigration(320, "Migrate two_factor_policy to login_source table", v1_24.MigrateSkipTwoFactor),
|
||||
newMigration(321, "Add new table for fine-grained notification settings", v1_24.AddFineGrainedActionsNotificationSettings),
|
||||
}
|
||||
return preparedMigrations
|
||||
}
|
||||
|
59
models/migrations/v1_24/v321.go
Normal file
59
models/migrations/v1_24/v321.go
Normal file
@ -0,0 +1,59 @@
|
||||
// Copyright 2025 The Gitea Authors. All rights reserved.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package v1_24
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"code.gitea.io/gitea/models/db"
|
||||
user_model "code.gitea.io/gitea/models/user"
|
||||
|
||||
"xorm.io/xorm"
|
||||
)
|
||||
|
||||
type NotificationSettings struct {
|
||||
UserID int64 `xorm:"pk"`
|
||||
Actions string `xorm:"NOT NULL DEFAULT 'failureonly'"`
|
||||
}
|
||||
|
||||
func (*NotificationSettings) TableName() string {
|
||||
return "user_notification_settings"
|
||||
}
|
||||
|
||||
func AddFineGrainedActionsNotificationSettings(x *xorm.Engine) error {
|
||||
if err := x.Sync(&NotificationSettings{}); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
settings := make([]NotificationSettings, 0, 100)
|
||||
|
||||
type User struct {
|
||||
ID int64 `xorm:"pk autoincr"`
|
||||
}
|
||||
|
||||
if err := db.Iterate(context.Background(), nil, func(ctx context.Context, user *User) error {
|
||||
settings = append(settings, NotificationSettings{
|
||||
UserID: user.ID,
|
||||
Actions: user_model.NotificationActionsFailureOnly,
|
||||
})
|
||||
if len(settings) >= 100 {
|
||||
_, err := x.Insert(&settings)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
settings = settings[:0]
|
||||
}
|
||||
return nil
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if len(settings) > 0 {
|
||||
if _, err := x.Insert(&settings); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
@ -798,6 +798,12 @@ func createUser(ctx context.Context, u *User, meta *Meta, createdByAdmin bool, o
|
||||
return err
|
||||
}
|
||||
|
||||
if err := db.Insert(ctx, &NotificationSettings{
|
||||
UserID: u.ID,
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return committer.Commit()
|
||||
}
|
||||
|
||||
|
54
models/user/user_notification.go
Normal file
54
models/user/user_notification.go
Normal file
@ -0,0 +1,54 @@
|
||||
// Copyright 2025 The Gitea Authors. All rights reserved.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package user
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"code.gitea.io/gitea/models/db"
|
||||
)
|
||||
|
||||
const (
|
||||
NotificationActionsAll = "all"
|
||||
NotificationActionsFailureOnly = "failureonly"
|
||||
NotificationActionsDisabled = "disabled"
|
||||
)
|
||||
|
||||
type NotificationSettings struct {
|
||||
UserID int64 `xorm:"pk"`
|
||||
User *User `xorm:"-"`
|
||||
Actions string `xorm:"NOT NULL DEFAULT 'failureonly'"`
|
||||
}
|
||||
|
||||
func (NotificationSettings) TableName() string {
|
||||
return "user_notification_settings"
|
||||
}
|
||||
|
||||
func init() {
|
||||
db.RegisterModel(new(NotificationSettings))
|
||||
}
|
||||
|
||||
// GetUserNotificationSettings returns a user's fine-grained notification preference
|
||||
func GetUserNotificationSettings(ctx context.Context, userID int64) (*NotificationSettings, error) {
|
||||
settings := &NotificationSettings{}
|
||||
if has, err := db.GetEngine(ctx).Where("user_id=?", userID).Get(settings); err != nil {
|
||||
return nil, err
|
||||
} else if !has {
|
||||
return nil, nil
|
||||
}
|
||||
user, err := GetUserByID(ctx, userID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
settings.User = user
|
||||
return settings, nil
|
||||
}
|
||||
|
||||
func UpdateUserNotificationSettings(ctx context.Context, settings *NotificationSettings) error {
|
||||
_, err := db.GetEngine(ctx).Where("user_id = ?", settings.UserID).
|
||||
Update(&NotificationSettings{
|
||||
Actions: settings.Actions,
|
||||
})
|
||||
return err
|
||||
}
|
37
models/user/user_notification_test.go
Normal file
37
models/user/user_notification_test.go
Normal file
@ -0,0 +1,37 @@
|
||||
// Copyright 2025 The Gitea Authors. All rights reserved.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package user
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"code.gitea.io/gitea/models/db"
|
||||
"code.gitea.io/gitea/models/unittest"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestUserNotificationSettings(t *testing.T) {
|
||||
assert.NoError(t, unittest.PrepareTestDatabase())
|
||||
|
||||
settings, err := GetUserNotificationSettings(db.DefaultContext, 1)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, NotificationActionsFailureOnly, settings.Actions)
|
||||
|
||||
assert.NoError(t, UpdateUserNotificationSettings(db.DefaultContext, &NotificationSettings{
|
||||
UserID: 1,
|
||||
Actions: NotificationActionsAll,
|
||||
}))
|
||||
settings, err = GetUserNotificationSettings(db.DefaultContext, 1)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, NotificationActionsAll, settings.Actions)
|
||||
|
||||
assert.NoError(t, UpdateUserNotificationSettings(db.DefaultContext, &NotificationSettings{
|
||||
UserID: 1,
|
||||
Actions: NotificationActionsDisabled,
|
||||
}))
|
||||
settings, err = GetUserNotificationSettings(db.DefaultContext, 1)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, NotificationActionsDisabled, settings.Actions)
|
||||
}
|
@ -95,6 +95,7 @@ func deleteUser(ctx context.Context, u *user_model.User, purge bool) (err error)
|
||||
&user_model.Blocking{BlockerID: u.ID},
|
||||
&user_model.Blocking{BlockeeID: u.ID},
|
||||
&actions_model.ActionRunnerToken{OwnerID: u.ID},
|
||||
&user_model.NotificationSettings{UserID: u.ID},
|
||||
); err != nil {
|
||||
return fmt.Errorf("deleteBeans: %w", err)
|
||||
}
|
||||
|
@ -244,3 +244,15 @@ func UpdateAuth(ctx context.Context, u *user_model.User, opts *UpdateAuthOptions
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type UpdateNotificationSettingsOptions struct {
|
||||
Actions optional.Option[string]
|
||||
}
|
||||
|
||||
func UpdateNotificationSettings(ctx context.Context, settings *user_model.NotificationSettings, opts *UpdateNotificationSettingsOptions) error {
|
||||
if opts.Actions.Has() {
|
||||
settings.Actions = opts.Actions.Value()
|
||||
}
|
||||
|
||||
return user_model.UpdateUserNotificationSettings(ctx, settings)
|
||||
}
|
||||
|
@ -122,3 +122,25 @@ func TestUpdateAuth(t *testing.T) {
|
||||
Password: optional.Some("aaaa"),
|
||||
}), password_module.ErrMinLength)
|
||||
}
|
||||
|
||||
func TestUpdateNotificationSettings(t *testing.T) {
|
||||
assert.NoError(t, unittest.PrepareTestDatabase())
|
||||
|
||||
settings := &user_model.NotificationSettings{UserID: 2}
|
||||
exists, err := db.GetEngine(db.DefaultContext).Get(settings)
|
||||
assert.NoError(t, err)
|
||||
assert.True(t, exists)
|
||||
settingsCopy := *settings
|
||||
|
||||
assert.NoError(t, UpdateNotificationSettings(db.DefaultContext, settings, &UpdateNotificationSettingsOptions{
|
||||
Actions: optional.Some(user_model.NotificationActionsAll),
|
||||
}))
|
||||
assert.Equal(t, user_model.NotificationActionsAll, settings.Actions)
|
||||
assert.NotEqual(t, settingsCopy.Actions, settings.Actions)
|
||||
|
||||
assert.NoError(t, UpdateNotificationSettings(db.DefaultContext, settings, &UpdateNotificationSettingsOptions{
|
||||
Actions: optional.Some(user_model.NotificationActionsDisabled),
|
||||
}))
|
||||
assert.Equal(t, user_model.NotificationActionsDisabled, settings.Actions)
|
||||
assert.NotEqual(t, settingsCopy.Actions, settings.Actions)
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user