user_setting.go 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131
  1. package postgres
  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 *storepb.UserSetting) (*storepb.UserSetting, error) {
  12. stmt := `
  13. INSERT INTO user_setting (
  14. user_id, key, value
  15. )
  16. VALUES ($1, $2, $3)
  17. ON CONFLICT(user_id, key) DO UPDATE
  18. SET value = EXCLUDED.value
  19. `
  20. var valueString string
  21. if upsert.Key == storepb.UserSettingKey_USER_SETTING_ACCESS_TOKENS {
  22. valueBytes, err := protojson.Marshal(upsert.GetAccessTokens())
  23. if err != nil {
  24. return nil, err
  25. }
  26. valueString = string(valueBytes)
  27. } else if upsert.Key == storepb.UserSettingKey_USER_SETTING_LOCALE {
  28. valueString = upsert.GetLocale()
  29. } else if upsert.Key == storepb.UserSettingKey_USER_SETTING_APPEARANCE {
  30. valueString = upsert.GetAppearance()
  31. } else if upsert.Key == storepb.UserSettingKey_USER_SETTING_MEMO_VISIBILITY {
  32. valueString = upsert.GetMemoVisibility()
  33. } else if upsert.Key == storepb.UserSettingKey_USER_SETTING_TELEGRAM_USER_ID {
  34. valueString = upsert.GetTelegramUserId()
  35. } else {
  36. return nil, errors.Errorf("unknown user setting key: %s", upsert.Key.String())
  37. }
  38. if _, err := d.db.ExecContext(ctx, stmt, upsert.UserId, upsert.Key.String(), valueString); err != nil {
  39. return nil, err
  40. }
  41. return upsert, nil
  42. }
  43. func (d *DB) ListUserSettings(ctx context.Context, find *store.FindUserSetting) ([]*storepb.UserSetting, error) {
  44. where, args := []string{"1 = 1"}, []any{}
  45. if v := find.Key; v != storepb.UserSettingKey_USER_SETTING_KEY_UNSPECIFIED {
  46. where, args = append(where, "key = "+placeholder(len(args)+1)), append(args, v.String())
  47. }
  48. if v := find.UserID; v != nil {
  49. where, args = append(where, "user_id = "+placeholder(len(args)+1)), append(args, *find.UserID)
  50. }
  51. query := `
  52. SELECT
  53. user_id,
  54. key,
  55. value
  56. FROM user_setting
  57. WHERE ` + strings.Join(where, " AND ")
  58. rows, err := d.db.QueryContext(ctx, query, args...)
  59. if err != nil {
  60. return nil, err
  61. }
  62. defer rows.Close()
  63. userSettingList := make([]*storepb.UserSetting, 0)
  64. for rows.Next() {
  65. userSetting := &storepb.UserSetting{}
  66. var keyString, valueString string
  67. if err := rows.Scan(
  68. &userSetting.UserId,
  69. &keyString,
  70. &valueString,
  71. ); err != nil {
  72. return nil, err
  73. }
  74. userSetting.Key = storepb.UserSettingKey(storepb.UserSettingKey_value[keyString])
  75. if userSetting.Key == storepb.UserSettingKey_USER_SETTING_ACCESS_TOKENS {
  76. accessTokensUserSetting := &storepb.AccessTokensUserSetting{}
  77. if err := protojson.Unmarshal([]byte(valueString), accessTokensUserSetting); err != nil {
  78. return nil, err
  79. }
  80. userSetting.Value = &storepb.UserSetting_AccessTokens{
  81. AccessTokens: accessTokensUserSetting,
  82. }
  83. } else if userSetting.Key == storepb.UserSettingKey_USER_SETTING_LOCALE {
  84. userSetting.Value = &storepb.UserSetting_Locale{
  85. Locale: valueString,
  86. }
  87. } else if userSetting.Key == storepb.UserSettingKey_USER_SETTING_APPEARANCE {
  88. userSetting.Value = &storepb.UserSetting_Appearance{
  89. Appearance: valueString,
  90. }
  91. } else if userSetting.Key == storepb.UserSettingKey_USER_SETTING_MEMO_VISIBILITY {
  92. userSetting.Value = &storepb.UserSetting_MemoVisibility{
  93. MemoVisibility: valueString,
  94. }
  95. } else if userSetting.Key == storepb.UserSettingKey_USER_SETTING_TELEGRAM_USER_ID {
  96. userSetting.Value = &storepb.UserSetting_TelegramUserId{
  97. TelegramUserId: valueString,
  98. }
  99. } else {
  100. // Skip unknown user setting key.
  101. continue
  102. }
  103. userSettingList = append(userSettingList, userSetting)
  104. }
  105. if err := rows.Err(); err != nil {
  106. return nil, err
  107. }
  108. return userSettingList, nil
  109. }
  110. func vacuumUserSetting(ctx context.Context, tx *sql.Tx) error {
  111. stmt := `DELETE FROM user_setting WHERE user_id NOT IN (SELECT id FROM "user")`
  112. _, err := tx.ExecContext(ctx, stmt)
  113. if err != nil {
  114. return err
  115. }
  116. return nil
  117. }