user_setting.go 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  1. package mysql
  2. import (
  3. "context"
  4. "database/sql"
  5. "strings"
  6. "github.com/pkg/errors"
  7. "google.golang.org/protobuf/encoding/protojson"
  8. storepb "github.com/usememos/memos/proto/gen/store"
  9. "github.com/usememos/memos/store"
  10. )
  11. func (d *DB) UpsertUserSetting(ctx context.Context, upsert *store.UserSetting) (*store.UserSetting, error) {
  12. stmt := "INSERT INTO `user_setting` (`user_id`, `key`, `value`) VALUES (?, ?, ?) ON DUPLICATE KEY UPDATE `value` = ?"
  13. if _, err := d.db.ExecContext(ctx, stmt, upsert.UserID, upsert.Key, upsert.Value, upsert.Value); err != nil {
  14. return nil, err
  15. }
  16. return upsert, nil
  17. }
  18. func (d *DB) ListUserSettings(ctx context.Context, find *store.FindUserSetting) ([]*store.UserSetting, error) {
  19. where, args := []string{"1 = 1"}, []any{}
  20. if v := find.Key; v != "" {
  21. where, args = append(where, "`key` = ?"), append(args, v)
  22. }
  23. if v := find.UserID; v != nil {
  24. where, args = append(where, "`user_id` = ?"), append(args, *find.UserID)
  25. }
  26. query := "SELECT `user_id`, `key`, `value` FROM `user_setting` WHERE " + strings.Join(where, " AND ")
  27. rows, err := d.db.QueryContext(ctx, query, args...)
  28. if err != nil {
  29. return nil, err
  30. }
  31. defer rows.Close()
  32. userSettingList := make([]*store.UserSetting, 0)
  33. for rows.Next() {
  34. var userSetting store.UserSetting
  35. if err := rows.Scan(
  36. &userSetting.UserID,
  37. &userSetting.Key,
  38. &userSetting.Value,
  39. ); err != nil {
  40. return nil, err
  41. }
  42. userSettingList = append(userSettingList, &userSetting)
  43. }
  44. if err := rows.Err(); err != nil {
  45. return nil, err
  46. }
  47. return userSettingList, nil
  48. }
  49. func (d *DB) UpsertUserSettingV1(ctx context.Context, upsert *storepb.UserSetting) (*storepb.UserSetting, error) {
  50. stmt := "INSERT INTO `user_setting` (`user_id`, `key`, `value`) VALUES (?, ?, ?) ON DUPLICATE KEY UPDATE `value` = ?"
  51. var valueString string
  52. if upsert.Key == storepb.UserSettingKey_USER_SETTING_ACCESS_TOKENS {
  53. valueBytes, err := protojson.Marshal(upsert.GetAccessTokens())
  54. if err != nil {
  55. return nil, err
  56. }
  57. valueString = string(valueBytes)
  58. } else {
  59. return nil, errors.New("invalid user setting key")
  60. }
  61. if _, err := d.db.ExecContext(ctx, stmt, upsert.UserId, upsert.Key.String(), valueString, valueString); err != nil {
  62. return nil, err
  63. }
  64. return upsert, nil
  65. }
  66. func (d *DB) ListUserSettingsV1(ctx context.Context, find *store.FindUserSettingV1) ([]*storepb.UserSetting, error) {
  67. where, args := []string{"1 = 1"}, []any{}
  68. if v := find.Key; v != storepb.UserSettingKey_USER_SETTING_KEY_UNSPECIFIED {
  69. where, args = append(where, "`key` = ?"), append(args, v.String())
  70. }
  71. if v := find.UserID; v != nil {
  72. where, args = append(where, "`user_id` = ?"), append(args, *find.UserID)
  73. }
  74. query := "SELECT `user_id`, `key`, `value` FROM `user_setting` WHERE " + strings.Join(where, " AND ")
  75. rows, err := d.db.QueryContext(ctx, query, args...)
  76. if err != nil {
  77. return nil, err
  78. }
  79. defer rows.Close()
  80. userSettingList := make([]*storepb.UserSetting, 0)
  81. for rows.Next() {
  82. userSetting := &storepb.UserSetting{}
  83. var keyString, valueString string
  84. if err := rows.Scan(
  85. &userSetting.UserId,
  86. &keyString,
  87. &valueString,
  88. ); err != nil {
  89. return nil, err
  90. }
  91. userSetting.Key = storepb.UserSettingKey(storepb.UserSettingKey_value[keyString])
  92. if userSetting.Key == storepb.UserSettingKey_USER_SETTING_ACCESS_TOKENS {
  93. accessTokensUserSetting := &storepb.AccessTokensUserSetting{}
  94. if err := protojson.Unmarshal([]byte(valueString), accessTokensUserSetting); err != nil {
  95. return nil, err
  96. }
  97. userSetting.Value = &storepb.UserSetting_AccessTokens{
  98. AccessTokens: accessTokensUserSetting,
  99. }
  100. } else {
  101. // Skip unknown user setting v1 key.
  102. continue
  103. }
  104. userSettingList = append(userSettingList, userSetting)
  105. }
  106. if err := rows.Err(); err != nil {
  107. return nil, err
  108. }
  109. return userSettingList, nil
  110. }
  111. func vacuumUserSetting(ctx context.Context, tx *sql.Tx) error {
  112. stmt := "DELETE FROM `user_setting` WHERE `user_id` NOT IN (SELECT `id` FROM `user`)"
  113. _, err := tx.ExecContext(ctx, stmt)
  114. if err != nil {
  115. return err
  116. }
  117. return nil
  118. }