use sync.OnceValue when building the list with UserData column names

This commit is contained in:
floss4good 2025-04-01 01:41:32 +03:00
parent a5e7a815d8
commit 9aa5624872
No known key found for this signature in database
GPG key ID: 5B948B4F4DAF819D

View file

@ -7,6 +7,7 @@ import (
"context"
"reflect"
"slices"
"sync"
"forgejo.org/models/moderation"
"forgejo.org/modules/json"
@ -56,6 +57,18 @@ func newUserData(user *User) UserData {
}
}
// userDataColumnNames builds (only once) and returns a slice with the column names
// (e.g. FieldName -> field_name) corresponding to UserData struct fields.
var userDataColumnNames = sync.OnceValue(func() []string {
mapper := new(names.GonicMapper)
udType := reflect.TypeOf(UserData{})
columnNames := make([]string, 0, udType.NumField())
for i := 0; i < udType.NumField(); i++ {
columnNames = append(columnNames, mapper.Obj2Table(udType.Field(i).Name))
}
return columnNames
})
// IfNeededCreateShadowCopyForUser checks if for the given user there are any reports of abusive content submitted
// and if found a shadow copy of relevant user fields will be stored into DB and linked to the above report(s).
// This function should be called when a user is deleted or updated.
@ -70,13 +83,7 @@ func IfNeededCreateShadowCopyForUser(ctx context.Context, user *User, alteredCol
shouldCheckIfReported := len(alteredCols) == 0 // no columns being updated, therefore a deletion
if !shouldCheckIfReported {
// for updates we need to go further only if certain column are being changed
mapper := new(names.GonicMapper)
ucType := reflect.TypeOf(UserData{})
for i := 0; i < ucType.NumField(); i++ {
field := ucType.Field(i)
// get the corresponding column name for a field name (e.g. FieldName -> field_name).
colName := mapper.Obj2Table(field.Name)
for _, colName := range userDataColumnNames() {
if shouldCheckIfReported = slices.Contains(alteredCols, colName); shouldCheckIfReported {
break
}