db: rename `AccessTokensStore.Save` to `Touch` (#7029)

pull/7032/head
Joe Chen 2022-06-08 13:34:10 +08:00 committed by GitHub
parent 390fd3d283
commit fe1d07f29c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 59 additions and 62 deletions

View File

@ -137,8 +137,8 @@ func authenticatedUserID(c *macaron.Context, sess session.Store) (_ int64, isTok
} }
return 0, false return 0, false
} }
if err = db.AccessTokens.Save(c.Req.Context(), t); err != nil { if err = db.AccessTokens.Touch(c.Req.Context(), t.ID); err != nil {
log.Error("UpdateAccessToken: %v", err) log.Error("Failed to touch access token: %v", err)
} }
return t.UserID, true return t.UserID, true
} }

View File

@ -34,9 +34,8 @@ type AccessTokensStore interface {
GetBySHA1(ctx context.Context, sha1 string) (*AccessToken, error) GetBySHA1(ctx context.Context, sha1 string) (*AccessToken, error)
// List returns all access tokens belongs to given user. // List returns all access tokens belongs to given user.
List(ctx context.Context, userID int64) ([]*AccessToken, error) List(ctx context.Context, userID int64) ([]*AccessToken, error)
// Save persists all values of given access token. The Updated field is set to // Touch updates the updated time of the given access token to the current time.
// current time automatically. Touch(ctx context.Context, id int64) error
Save(ctx context.Context, t *AccessToken) error
} }
var AccessTokens AccessTokensStore var AccessTokens AccessTokensStore
@ -65,12 +64,6 @@ func (t *AccessToken) BeforeCreate(tx *gorm.DB) error {
return nil return nil
} }
// BeforeUpdate implements the GORM update hook.
func (t *AccessToken) BeforeUpdate(tx *gorm.DB) error {
t.UpdatedUnix = tx.NowFunc().Unix()
return nil
}
// AfterFind implements the GORM query hook. // AfterFind implements the GORM query hook.
func (t *AccessToken) AfterFind(tx *gorm.DB) error { func (t *AccessToken) AfterFind(tx *gorm.DB) error {
t.Created = time.Unix(t.CreatedUnix, 0).Local() t.Created = time.Unix(t.CreatedUnix, 0).Local()
@ -116,7 +109,7 @@ func (db *accessTokens) Create(ctx context.Context, userID int64, name string) (
Sha1: sha256[:40], // To pass the column unique constraint, keep the length of SHA1. Sha1: sha256[:40], // To pass the column unique constraint, keep the length of SHA1.
SHA256: sha256, SHA256: sha256,
} }
if err = db.DB.WithContext(ctx).Create(accessToken).Error; err != nil { if err = db.WithContext(ctx).Create(accessToken).Error; err != nil {
return nil, err return nil, err
} }
@ -166,6 +159,10 @@ func (db *accessTokens) List(ctx context.Context, userID int64) ([]*AccessToken,
return tokens, db.WithContext(ctx).Where("uid = ?", userID).Order("id ASC").Find(&tokens).Error return tokens, db.WithContext(ctx).Where("uid = ?", userID).Order("id ASC").Find(&tokens).Error
} }
func (db *accessTokens) Save(ctx context.Context, t *AccessToken) error { func (db *accessTokens) Touch(ctx context.Context, id int64) error {
return db.DB.WithContext(ctx).Save(t).Error return db.WithContext(ctx).
Model(new(AccessToken)).
Where("id = ?", id).
UpdateColumn("updated_unix", db.NowFunc().Unix()).
Error
} }

View File

@ -61,7 +61,7 @@ func TestAccessTokens(t *testing.T) {
{"DeleteByID", accessTokensDeleteByID}, {"DeleteByID", accessTokensDeleteByID},
{"GetBySHA1", accessTokensGetBySHA}, {"GetBySHA1", accessTokensGetBySHA},
{"List", accessTokensList}, {"List", accessTokensList},
{"Save", accessTokensSave}, {"Touch", accessTokensTouch},
} { } {
t.Run(tc.name, func(t *testing.T) { t.Run(tc.name, func(t *testing.T) {
t.Cleanup(func() { t.Cleanup(func() {
@ -169,7 +169,7 @@ func accessTokensList(t *testing.T, db *accessTokens) {
assert.Equal(t, "user1_2", tokens[1].Name) assert.Equal(t, "user1_2", tokens[1].Name)
} }
func accessTokensSave(t *testing.T, db *accessTokens) { func accessTokensTouch(t *testing.T, db *accessTokens) {
ctx := context.Background() ctx := context.Background()
// Create an access token with name "Test" // Create an access token with name "Test"
@ -179,7 +179,7 @@ func accessTokensSave(t *testing.T, db *accessTokens) {
// Updated field is zero now // Updated field is zero now
assert.True(t, token.Updated.IsZero()) assert.True(t, token.Updated.IsZero())
err = db.Save(ctx, token) err = db.Touch(ctx, token.ID)
require.NoError(t, err) require.NoError(t, err)
// Get back from DB should have Updated set // Get back from DB should have Updated set

View File

@ -23,9 +23,9 @@ type MockAccessTokensStore struct {
// ListFunc is an instance of a mock function object controlling the // ListFunc is an instance of a mock function object controlling the
// behavior of the method List. // behavior of the method List.
ListFunc *AccessTokensStoreListFunc ListFunc *AccessTokensStoreListFunc
// SaveFunc is an instance of a mock function object controlling the // TouchFunc is an instance of a mock function object controlling the
// behavior of the method Save. // behavior of the method Touch.
SaveFunc *AccessTokensStoreSaveFunc TouchFunc *AccessTokensStoreTouchFunc
} }
// NewMockAccessTokensStore creates a new mock of the AccessTokensStore // NewMockAccessTokensStore creates a new mock of the AccessTokensStore
@ -53,8 +53,8 @@ func NewMockAccessTokensStore() *MockAccessTokensStore {
return return
}, },
}, },
SaveFunc: &AccessTokensStoreSaveFunc{ TouchFunc: &AccessTokensStoreTouchFunc{
defaultHook: func(context.Context, *AccessToken) (r0 error) { defaultHook: func(context.Context, int64) (r0 error) {
return return
}, },
}, },
@ -86,9 +86,9 @@ func NewStrictMockAccessTokensStore() *MockAccessTokensStore {
panic("unexpected invocation of MockAccessTokensStore.List") panic("unexpected invocation of MockAccessTokensStore.List")
}, },
}, },
SaveFunc: &AccessTokensStoreSaveFunc{ TouchFunc: &AccessTokensStoreTouchFunc{
defaultHook: func(context.Context, *AccessToken) error { defaultHook: func(context.Context, int64) error {
panic("unexpected invocation of MockAccessTokensStore.Save") panic("unexpected invocation of MockAccessTokensStore.Touch")
}, },
}, },
} }
@ -111,8 +111,8 @@ func NewMockAccessTokensStoreFrom(i AccessTokensStore) *MockAccessTokensStore {
ListFunc: &AccessTokensStoreListFunc{ ListFunc: &AccessTokensStoreListFunc{
defaultHook: i.List, defaultHook: i.List,
}, },
SaveFunc: &AccessTokensStoreSaveFunc{ TouchFunc: &AccessTokensStoreTouchFunc{
defaultHook: i.Save, defaultHook: i.Touch,
}, },
} }
} }
@ -553,35 +553,35 @@ func (c AccessTokensStoreListFuncCall) Results() []interface{} {
return []interface{}{c.Result0, c.Result1} return []interface{}{c.Result0, c.Result1}
} }
// AccessTokensStoreSaveFunc describes the behavior when the Save method of // AccessTokensStoreTouchFunc describes the behavior when the Touch method
// the parent MockAccessTokensStore instance is invoked. // of the parent MockAccessTokensStore instance is invoked.
type AccessTokensStoreSaveFunc struct { type AccessTokensStoreTouchFunc struct {
defaultHook func(context.Context, *AccessToken) error defaultHook func(context.Context, int64) error
hooks []func(context.Context, *AccessToken) error hooks []func(context.Context, int64) error
history []AccessTokensStoreSaveFuncCall history []AccessTokensStoreTouchFuncCall
mutex sync.Mutex mutex sync.Mutex
} }
// Save delegates to the next hook function in the queue and stores the // Touch delegates to the next hook function in the queue and stores the
// parameter and result values of this invocation. // parameter and result values of this invocation.
func (m *MockAccessTokensStore) Save(v0 context.Context, v1 *AccessToken) error { func (m *MockAccessTokensStore) Touch(v0 context.Context, v1 int64) error {
r0 := m.SaveFunc.nextHook()(v0, v1) r0 := m.TouchFunc.nextHook()(v0, v1)
m.SaveFunc.appendCall(AccessTokensStoreSaveFuncCall{v0, v1, r0}) m.TouchFunc.appendCall(AccessTokensStoreTouchFuncCall{v0, v1, r0})
return r0 return r0
} }
// SetDefaultHook sets function that is called when the Save method of the // SetDefaultHook sets function that is called when the Touch method of the
// parent MockAccessTokensStore instance is invoked and the hook queue is // parent MockAccessTokensStore instance is invoked and the hook queue is
// empty. // empty.
func (f *AccessTokensStoreSaveFunc) SetDefaultHook(hook func(context.Context, *AccessToken) error) { func (f *AccessTokensStoreTouchFunc) SetDefaultHook(hook func(context.Context, int64) error) {
f.defaultHook = hook f.defaultHook = hook
} }
// PushHook adds a function to the end of hook queue. Each invocation of the // PushHook adds a function to the end of hook queue. Each invocation of the
// Save method of the parent MockAccessTokensStore instance invokes the hook // Touch method of the parent MockAccessTokensStore instance invokes the
// at the front of the queue and discards it. After the queue is empty, the // hook at the front of the queue and discards it. After the queue is empty,
// default hook function is invoked for any future action. // the default hook function is invoked for any future action.
func (f *AccessTokensStoreSaveFunc) PushHook(hook func(context.Context, *AccessToken) error) { func (f *AccessTokensStoreTouchFunc) PushHook(hook func(context.Context, int64) error) {
f.mutex.Lock() f.mutex.Lock()
f.hooks = append(f.hooks, hook) f.hooks = append(f.hooks, hook)
f.mutex.Unlock() f.mutex.Unlock()
@ -589,20 +589,20 @@ func (f *AccessTokensStoreSaveFunc) PushHook(hook func(context.Context, *AccessT
// SetDefaultReturn calls SetDefaultHook with a function that returns the // SetDefaultReturn calls SetDefaultHook with a function that returns the
// given values. // given values.
func (f *AccessTokensStoreSaveFunc) SetDefaultReturn(r0 error) { func (f *AccessTokensStoreTouchFunc) SetDefaultReturn(r0 error) {
f.SetDefaultHook(func(context.Context, *AccessToken) error { f.SetDefaultHook(func(context.Context, int64) error {
return r0 return r0
}) })
} }
// PushReturn calls PushHook with a function that returns the given values. // PushReturn calls PushHook with a function that returns the given values.
func (f *AccessTokensStoreSaveFunc) PushReturn(r0 error) { func (f *AccessTokensStoreTouchFunc) PushReturn(r0 error) {
f.PushHook(func(context.Context, *AccessToken) error { f.PushHook(func(context.Context, int64) error {
return r0 return r0
}) })
} }
func (f *AccessTokensStoreSaveFunc) nextHook() func(context.Context, *AccessToken) error { func (f *AccessTokensStoreTouchFunc) nextHook() func(context.Context, int64) error {
f.mutex.Lock() f.mutex.Lock()
defer f.mutex.Unlock() defer f.mutex.Unlock()
@ -615,32 +615,32 @@ func (f *AccessTokensStoreSaveFunc) nextHook() func(context.Context, *AccessToke
return hook return hook
} }
func (f *AccessTokensStoreSaveFunc) appendCall(r0 AccessTokensStoreSaveFuncCall) { func (f *AccessTokensStoreTouchFunc) appendCall(r0 AccessTokensStoreTouchFuncCall) {
f.mutex.Lock() f.mutex.Lock()
f.history = append(f.history, r0) f.history = append(f.history, r0)
f.mutex.Unlock() f.mutex.Unlock()
} }
// History returns a sequence of AccessTokensStoreSaveFuncCall objects // History returns a sequence of AccessTokensStoreTouchFuncCall objects
// describing the invocations of this function. // describing the invocations of this function.
func (f *AccessTokensStoreSaveFunc) History() []AccessTokensStoreSaveFuncCall { func (f *AccessTokensStoreTouchFunc) History() []AccessTokensStoreTouchFuncCall {
f.mutex.Lock() f.mutex.Lock()
history := make([]AccessTokensStoreSaveFuncCall, len(f.history)) history := make([]AccessTokensStoreTouchFuncCall, len(f.history))
copy(history, f.history) copy(history, f.history)
f.mutex.Unlock() f.mutex.Unlock()
return history return history
} }
// AccessTokensStoreSaveFuncCall is an object that describes an invocation // AccessTokensStoreTouchFuncCall is an object that describes an invocation
// of method Save on an instance of MockAccessTokensStore. // of method Touch on an instance of MockAccessTokensStore.
type AccessTokensStoreSaveFuncCall struct { type AccessTokensStoreTouchFuncCall struct {
// Arg0 is the value of the 1st argument passed to this method // Arg0 is the value of the 1st argument passed to this method
// invocation. // invocation.
Arg0 context.Context Arg0 context.Context
// Arg1 is the value of the 2nd argument passed to this method // Arg1 is the value of the 2nd argument passed to this method
// invocation. // invocation.
Arg1 *AccessToken Arg1 int64
// Result0 is the value of the 1st result returned from this method // Result0 is the value of the 1st result returned from this method
// invocation. // invocation.
Result0 error Result0 error
@ -648,12 +648,12 @@ type AccessTokensStoreSaveFuncCall struct {
// Args returns an interface slice containing the arguments of this // Args returns an interface slice containing the arguments of this
// invocation. // invocation.
func (c AccessTokensStoreSaveFuncCall) Args() []interface{} { func (c AccessTokensStoreTouchFuncCall) Args() []interface{} {
return []interface{}{c.Arg0, c.Arg1} return []interface{}{c.Arg0, c.Arg1}
} }
// Results returns an interface slice containing the results of this // Results returns an interface slice containing the results of this
// invocation. // invocation.
func (c AccessTokensStoreSaveFuncCall) Results() []interface{} { func (c AccessTokensStoreTouchFuncCall) Results() []interface{} {
return []interface{}{c.Result0} return []interface{}{c.Result0}
} }

View File

@ -82,8 +82,8 @@ func authenticate() macaron.Handler {
} }
return return
} }
if err = db.AccessTokens.Save(c.Req.Context(), token); err != nil { if err = db.AccessTokens.Touch(c.Req.Context(), token.ID); err != nil {
log.Error("Failed to update access token: %v", err) log.Error("Failed to touch access token: %v", err)
} }
user, err = db.Users.GetByID(token.UserID) user, err = db.Users.GetByID(token.UserID)

View File

@ -142,8 +142,8 @@ func HTTPContexter() macaron.Handler {
} }
return return
} }
if err = db.AccessTokens.Save(c.Req.Context(), token); err != nil { if err = db.AccessTokens.Touch(c.Req.Context(), token.ID); err != nil {
log.Error("Failed to update access token: %v", err) log.Error("Failed to touch access token: %v", err)
} }
authUser, err = db.Users.GetByID(token.UserID) authUser, err = db.Users.GetByID(token.UserID)