From 14ec524805f019a08b388533f56885a2a618b9d6 Mon Sep 17 00:00:00 2001 From: Athurg Gooth Date: Tue, 26 Sep 2023 19:02:48 +0800 Subject: [PATCH] chore: move sql code of UserSetting into Driver (#2282) * Move SQL code of UserSetting into Driver * Fix golang import issue --- store/driver.go | 11 ++- store/sqlite3/user_setting.go | 155 ++++++++++++++++++++++++++++++++++ store/user_setting.go | 125 ++------------------------- 3 files changed, 171 insertions(+), 120 deletions(-) create mode 100644 store/sqlite3/user_setting.go diff --git a/store/driver.go b/store/driver.go index 3d17b362..11a8903c 100644 --- a/store/driver.go +++ b/store/driver.go @@ -1,6 +1,10 @@ package store -import "context" +import ( + "context" + + storepb "github.com/usememos/memos/proto/gen/store" +) type Driver interface { CreateActivity(ctx context.Context, create *Activity) (*Activity, error) @@ -12,4 +16,9 @@ type Driver interface { UpdateUser(ctx context.Context, update *UpdateUser) (*User, error) ListUsers(ctx context.Context, find *FindUser) ([]*User, error) DeleteUser(ctx context.Context, delete *DeleteUser) error + + UpsertUserSetting(ctx context.Context, upsert *UserSetting) (*UserSetting, error) + ListUserSettings(ctx context.Context, find *FindUserSetting) ([]*UserSetting, error) + UpsertUserSettingV1(ctx context.Context, upsert *storepb.UserSetting) (*storepb.UserSetting, error) + ListUserSettingsV1(ctx context.Context, find *FindUserSettingV1) ([]*storepb.UserSetting, error) } diff --git a/store/sqlite3/user_setting.go b/store/sqlite3/user_setting.go new file mode 100644 index 00000000..72bff4cf --- /dev/null +++ b/store/sqlite3/user_setting.go @@ -0,0 +1,155 @@ +package sqlite3 + +import ( + "context" + "errors" + "strings" + + "google.golang.org/protobuf/encoding/protojson" + + storepb "github.com/usememos/memos/proto/gen/store" + "github.com/usememos/memos/store" +) + +func (d *Driver) UpsertUserSetting(ctx context.Context, upsert *store.UserSetting) (*store.UserSetting, error) { + stmt := ` + INSERT INTO user_setting ( + user_id, key, value + ) + VALUES (?, ?, ?) + ON CONFLICT(user_id, key) DO UPDATE + SET value = EXCLUDED.value + ` + if _, err := d.db.ExecContext(ctx, stmt, upsert.UserID, upsert.Key, upsert.Value); err != nil { + return nil, err + } + + return upsert, nil +} + +func (d *Driver) ListUserSettings(ctx context.Context, find *store.FindUserSetting) ([]*store.UserSetting, error) { + where, args := []string{"1 = 1"}, []any{} + + if v := find.Key; v != "" { + where, args = append(where, "key = ?"), append(args, v) + } + if v := find.UserID; v != nil { + where, args = append(where, "user_id = ?"), append(args, *find.UserID) + } + + query := ` + SELECT + user_id, + key, + value + FROM user_setting + WHERE ` + strings.Join(where, " AND ") + rows, err := d.db.QueryContext(ctx, query, args...) + if err != nil { + return nil, err + } + defer rows.Close() + + userSettingList := make([]*store.UserSetting, 0) + for rows.Next() { + var userSetting store.UserSetting + if err := rows.Scan( + &userSetting.UserID, + &userSetting.Key, + &userSetting.Value, + ); err != nil { + return nil, err + } + userSettingList = append(userSettingList, &userSetting) + } + + if err := rows.Err(); err != nil { + return nil, err + } + + return userSettingList, nil +} + +func (d *Driver) UpsertUserSettingV1(ctx context.Context, upsert *storepb.UserSetting) (*storepb.UserSetting, error) { + stmt := ` + INSERT INTO user_setting ( + user_id, key, value + ) + VALUES (?, ?, ?) + ON CONFLICT(user_id, key) DO UPDATE + SET value = EXCLUDED.value + ` + var valueString string + if upsert.Key == storepb.UserSettingKey_USER_SETTING_ACCESS_TOKENS { + valueBytes, err := protojson.Marshal(upsert.GetAccessTokens()) + if err != nil { + return nil, err + } + valueString = string(valueBytes) + } else { + return nil, errors.New("invalid user setting key") + } + + if _, err := d.db.ExecContext(ctx, stmt, upsert.UserId, upsert.Key.String(), valueString); err != nil { + return nil, err + } + + return upsert, nil +} + +func (d *Driver) ListUserSettingsV1(ctx context.Context, find *store.FindUserSettingV1) ([]*storepb.UserSetting, error) { + where, args := []string{"1 = 1"}, []any{} + + if v := find.Key; v != storepb.UserSettingKey_USER_SETTING_KEY_UNSPECIFIED { + where, args = append(where, "key = ?"), append(args, v.String()) + } + if v := find.UserID; v != nil { + where, args = append(where, "user_id = ?"), append(args, *find.UserID) + } + + query := ` + SELECT + user_id, + key, + value + FROM user_setting + WHERE ` + strings.Join(where, " AND ") + rows, err := d.db.QueryContext(ctx, query, args...) + if err != nil { + return nil, err + } + defer rows.Close() + + userSettingList := make([]*storepb.UserSetting, 0) + for rows.Next() { + userSetting := &storepb.UserSetting{} + var keyString, valueString string + if err := rows.Scan( + &userSetting.UserId, + &keyString, + &valueString, + ); err != nil { + return nil, err + } + userSetting.Key = storepb.UserSettingKey(storepb.UserSettingKey_value[keyString]) + if userSetting.Key == storepb.UserSettingKey_USER_SETTING_ACCESS_TOKENS { + accessTokensUserSetting := &storepb.AccessTokensUserSetting{} + if err := protojson.Unmarshal([]byte(valueString), accessTokensUserSetting); err != nil { + return nil, err + } + userSetting.Value = &storepb.UserSetting_AccessTokens{ + AccessTokens: accessTokensUserSetting, + } + } else { + // Skip unknown user setting v1 key. + continue + } + userSettingList = append(userSettingList, userSetting) + } + + if err := rows.Err(); err != nil { + return nil, err + } + + return userSettingList, nil +} diff --git a/store/user_setting.go b/store/user_setting.go index 3b395efe..7726f7a8 100644 --- a/store/user_setting.go +++ b/store/user_setting.go @@ -3,10 +3,6 @@ package store import ( "context" "database/sql" - "errors" - "strings" - - "google.golang.org/protobuf/encoding/protojson" storepb "github.com/usememos/memos/proto/gen/store" ) @@ -23,62 +19,20 @@ type FindUserSetting struct { } func (s *Store) UpsertUserSetting(ctx context.Context, upsert *UserSetting) (*UserSetting, error) { - stmt := ` - INSERT INTO user_setting ( - user_id, key, value - ) - VALUES (?, ?, ?) - ON CONFLICT(user_id, key) DO UPDATE - SET value = EXCLUDED.value - ` - if _, err := s.db.ExecContext(ctx, stmt, upsert.UserID, upsert.Key, upsert.Value); err != nil { + userSetting, err := s.driver.UpsertUserSetting(ctx, upsert) + if err != nil { return nil, err } - userSetting := upsert s.userSettingCache.Store(getUserSettingCacheKey(userSetting.UserID, userSetting.Key), userSetting) return userSetting, nil } func (s *Store) ListUserSettings(ctx context.Context, find *FindUserSetting) ([]*UserSetting, error) { - where, args := []string{"1 = 1"}, []any{} - - if v := find.Key; v != "" { - where, args = append(where, "key = ?"), append(args, v) - } - if v := find.UserID; v != nil { - where, args = append(where, "user_id = ?"), append(args, *find.UserID) - } - - query := ` - SELECT - user_id, - key, - value - FROM user_setting - WHERE ` + strings.Join(where, " AND ") - rows, err := s.db.QueryContext(ctx, query, args...) + userSettingList, err := s.driver.ListUserSettings(ctx, find) if err != nil { return nil, err } - defer rows.Close() - - userSettingList := make([]*UserSetting, 0) - for rows.Next() { - var userSetting UserSetting - if err := rows.Scan( - &userSetting.UserID, - &userSetting.Key, - &userSetting.Value, - ); err != nil { - return nil, err - } - userSettingList = append(userSettingList, &userSetting) - } - - if err := rows.Err(); err != nil { - return nil, err - } for _, userSetting := range userSettingList { s.userSettingCache.Store(getUserSettingCacheKey(userSetting.UserID, userSetting.Key), userSetting) @@ -113,87 +67,20 @@ type FindUserSettingV1 struct { } func (s *Store) UpsertUserSettingV1(ctx context.Context, upsert *storepb.UserSetting) (*storepb.UserSetting, error) { - stmt := ` - INSERT INTO user_setting ( - user_id, key, value - ) - VALUES (?, ?, ?) - ON CONFLICT(user_id, key) DO UPDATE - SET value = EXCLUDED.value - ` - var valueString string - if upsert.Key == storepb.UserSettingKey_USER_SETTING_ACCESS_TOKENS { - valueBytes, err := protojson.Marshal(upsert.GetAccessTokens()) - if err != nil { - return nil, err - } - valueString = string(valueBytes) - } else { - return nil, errors.New("invalid user setting key") - } - - if _, err := s.db.ExecContext(ctx, stmt, upsert.UserId, upsert.Key.String(), valueString); err != nil { + userSettingMessage, err := s.driver.UpsertUserSettingV1(ctx, upsert) + if err != nil { return nil, err } - userSettingMessage := upsert s.userSettingCache.Store(getUserSettingV1CacheKey(userSettingMessage.UserId, userSettingMessage.Key.String()), userSettingMessage) return userSettingMessage, nil } func (s *Store) ListUserSettingsV1(ctx context.Context, find *FindUserSettingV1) ([]*storepb.UserSetting, error) { - where, args := []string{"1 = 1"}, []any{} - - if v := find.Key; v != storepb.UserSettingKey_USER_SETTING_KEY_UNSPECIFIED { - where, args = append(where, "key = ?"), append(args, v.String()) - } - if v := find.UserID; v != nil { - where, args = append(where, "user_id = ?"), append(args, *find.UserID) - } - - query := ` - SELECT - user_id, - key, - value - FROM user_setting - WHERE ` + strings.Join(where, " AND ") - rows, err := s.db.QueryContext(ctx, query, args...) + userSettingList, err := s.driver.ListUserSettingsV1(ctx, find) if err != nil { return nil, err } - defer rows.Close() - - userSettingList := make([]*storepb.UserSetting, 0) - for rows.Next() { - userSetting := &storepb.UserSetting{} - var keyString, valueString string - if err := rows.Scan( - &userSetting.UserId, - &keyString, - &valueString, - ); err != nil { - return nil, err - } - userSetting.Key = storepb.UserSettingKey(storepb.UserSettingKey_value[keyString]) - if userSetting.Key == storepb.UserSettingKey_USER_SETTING_ACCESS_TOKENS { - accessTokensUserSetting := &storepb.AccessTokensUserSetting{} - if err := protojson.Unmarshal([]byte(valueString), accessTokensUserSetting); err != nil { - return nil, err - } - userSetting.Value = &storepb.UserSetting_AccessTokens{ - AccessTokens: accessTokensUserSetting, - } - } else { - // Skip unknown user setting v1 key. - continue - } - userSettingList = append(userSettingList, userSetting) - } - - if err := rows.Err(); err != nil { - return nil, err - } for _, userSetting := range userSettingList { s.userSettingCache.Store(getUserSettingV1CacheKey(userSetting.UserId, userSetting.Key.String()), userSetting)