PreferenceStore: Use native upsert for Postgres (#17894)

* PreferenceStore: Use native upsert for Postgres

Now that version 10 is minimum, we can start to use
advanced postgres features.

https://focalboard-community.octo.mattermost.com/workspace/zyoahc9uapdn3xdptac6jb69ic?id=285b80a3-257d-41f6-8cf4-ed80ca9d92e5&v=495cdb4d-c13a-4992-8eb9-80cfee2819a4&c=0445b560-91b9-469b-8f19-febf1881bcd6

```release-note
NONE
```

* fix lint issues

```release-note
NONE
```
Этот коммит содержится в:
Agniva De Sarker
2021-07-09 23:38:52 +05:30
коммит произвёл GitHub
родитель ba9cbae0d5
Коммит f5610801e3

Просмотреть файл

@@ -4,8 +4,6 @@
package sqlstore
import (
"fmt"
sq "github.com/Masterminds/squirrel"
"github.com/mattermost/gorp"
"github.com/mattermost/mattermost-server/v5/model"
@@ -81,66 +79,27 @@ func (s SqlPreferenceStore) save(transaction *gorp.Transaction, preference *mode
return err
}
query := s.getQueryBuilder().
Insert("Preferences").
Columns("UserId", "Category", "Name", "Value").
Values(preference.UserId, preference.Category, preference.Name, preference.Value)
if s.DriverName() == model.DATABASE_DRIVER_MYSQL {
queryString, args, err := s.getQueryBuilder().
Insert("Preferences").
Columns("UserId", "Category", "Name", "Value").
Values(preference.UserId, preference.Category, preference.Name, preference.Value).
SuffixExpr(sq.Expr("ON DUPLICATE KEY UPDATE Value = ?", preference.Value)).
ToSql()
if err != nil {
return errors.Wrap(err, "failed to generate sqlquery")
}
if _, err = transaction.Exec(queryString, args...); err != nil {
return errors.Wrap(err, "failed to save Preference")
}
return nil
query = query.SuffixExpr(sq.Expr("ON DUPLICATE KEY UPDATE Value = ?", preference.Value))
} else if s.DriverName() == model.DATABASE_DRIVER_POSTGRES {
// postgres has no way to upsert values until version 9.5 and trying inserting and then updating causes transactions to abort
queryString, args, err := s.getQueryBuilder().
Select("count(0)").
From("Preferences").
Where(sq.Eq{"UserId": preference.UserId}).
Where(sq.Eq{"Category": preference.Category}).
Where(sq.Eq{"Name": preference.Name}).
ToSql()
if err != nil {
return errors.Wrap(err, "failed to generate sqlquery")
}
count, err := transaction.SelectInt(queryString, args...)
if err != nil {
return errors.Wrap(err, "failed to count Preferences")
}
if count == 1 {
return s.update(transaction, preference)
}
return s.insert(transaction, preference)
}
return store.NewErrNotImplemented("failed to update preference because of missing driver")
}
func (s SqlPreferenceStore) insert(transaction *gorp.Transaction, preference *model.Preference) error {
if err := transaction.Insert(preference); err != nil {
if IsUniqueConstraintError(err, []string{"UserId", "preferences_pkey"}) {
return store.NewErrInvalidInput("Preference", "<userId, category, name>", fmt.Sprintf("<%s, %s, %s>", preference.UserId, preference.Category, preference.Name))
}
return errors.Wrapf(err, "failed to save Preference with userId=%s, category=%s, name=%s", preference.UserId, preference.Category, preference.Name)
query = query.SuffixExpr(sq.Expr("ON CONFLICT (userid, category, name) DO UPDATE SET Value = ?", preference.Value))
} else {
return store.NewErrNotImplemented("failed to update preference because of missing driver")
}
return nil
}
func (s SqlPreferenceStore) update(transaction *gorp.Transaction, preference *model.Preference) error {
if _, err := transaction.Update(preference); err != nil {
return errors.Wrapf(err, "failed to update Preference with userId=%s, category=%s, name=%s", preference.UserId, preference.Category, preference.Name)
queryString, args, err := query.ToSql()
if err != nil {
return errors.Wrap(err, "failed to generate sqlquery")
}
if _, err = transaction.Exec(queryString, args...); err != nil {
return errors.Wrap(err, "failed to save Preference")
}
return nil
}