Migrating Emoji store to use sqlx (#18301)

* Migrating Emoji store to use sqlx

https://community-daily.mattermost.com/boards/workspace/zyoahc9uapdn3xdptac6jb69ic/285b80a3-257d-41f6-8cf4-ed80ca9d92e5/495cdb4d-c13a-4992-8eb9-80cfee2819a4?c=646cee9a-219c-49f3-8e0b-6ec2cff4deba

```release-note
NONE
```

* Incorporate review suggestions

```release-note
NONE
```

Co-authored-by: Mattermod <mattermod@users.noreply.github.com>
Этот коммит содержится в:
Agniva De Sarker
2021-09-14 13:46:42 +05:30
коммит произвёл GitHub
родитель e542842bd1
Коммит 0953e3f0cf
3 изменённых файлов: 46 добавлений и 25 удалений

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

@@ -42,3 +42,11 @@ func (ss *SqlStore) DBFromContext(ctx context.Context) *gorp.DbMap {
} }
return ss.GetReplica() return ss.GetReplica()
} }
// DBXFromContext is a helper utility that returns the sqlx DB handle from a given context.
func (ss *SqlStore) DBXFromContext(ctx context.Context) *sqlxDBWrapper {
if hasMaster(ctx) {
return ss.GetMasterX()
}
return ss.GetReplicaX()
}

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

@@ -7,6 +7,7 @@ import (
"context" "context"
"database/sql" "database/sql"
"fmt" "fmt"
"strings"
"github.com/pkg/errors" "github.com/pkg/errors"
@@ -50,7 +51,10 @@ func (es SqlEmojiStore) Save(emoji *model.Emoji) (*model.Emoji, error) {
return nil, err return nil, err
} }
if err := es.GetMaster().Insert(emoji); err != nil { if _, err := es.GetMasterX().NamedExec(`INSERT INTO Emoji
(Id, CreateAt, UpdateAt, DeleteAt, CreatorId, Name)
VALUES
(:Id, :CreateAt, :UpdateAt, :DeleteAt, :CreatorId, :Name)`, emoji); err != nil {
return nil, errors.Wrap(err, "error saving emoji") return nil, errors.Wrap(err, "error saving emoji")
} }
@@ -66,25 +70,26 @@ func (es SqlEmojiStore) GetByName(ctx context.Context, name string, allowFromCac
} }
func (es SqlEmojiStore) GetMultipleByName(names []string) ([]*model.Emoji, error) { func (es SqlEmojiStore) GetMultipleByName(names []string) ([]*model.Emoji, error) {
keys, params := MapStringsToQueryParams(names, "Emoji") // Creating (?, ?, ?) len(names) number of times.
keys := strings.Join(strings.Fields(strings.Repeat("? ", len(names))), ",")
args := makeStringArgs(names)
var emojis []*model.Emoji emojis := []*model.Emoji{}
if err := es.GetReplicaX().Select(&emojis,
if _, err := es.GetReplica().Select(&emojis,
`SELECT `SELECT
* *
FROM FROM
Emoji Emoji
WHERE WHERE
Name IN `+keys+` Name IN (`+keys+`)
AND DeleteAt = 0`, params); err != nil { AND DeleteAt = 0`, args...); err != nil {
return nil, errors.Wrapf(err, "error getting emoji by names %v", names) return nil, errors.Wrapf(err, "error getting emoji by names %v", names)
} }
return emojis, nil return emojis, nil
} }
func (es SqlEmojiStore) GetList(offset, limit int, sort string) ([]*model.Emoji, error) { func (es SqlEmojiStore) GetList(offset, limit int, sort string) ([]*model.Emoji, error) {
var emoji []*model.Emoji emojis := []*model.Emoji{}
query := "SELECT * FROM Emoji WHERE DeleteAt = 0" query := "SELECT * FROM Emoji WHERE DeleteAt = 0"
@@ -92,24 +97,24 @@ func (es SqlEmojiStore) GetList(offset, limit int, sort string) ([]*model.Emoji,
query += " ORDER BY Name" query += " ORDER BY Name"
} }
query += " LIMIT :Limit OFFSET :Offset" query += " LIMIT ? OFFSET ?"
if _, err := es.GetReplica().Select(&emoji, query, map[string]interface{}{"Offset": offset, "Limit": limit}); err != nil { if err := es.GetReplicaX().Select(&emojis, query, limit, offset); err != nil {
return nil, errors.Wrap(err, "could not get list of emojis") return nil, errors.Wrap(err, "could not get list of emojis")
} }
return emoji, nil return emojis, nil
} }
func (es SqlEmojiStore) Delete(emoji *model.Emoji, time int64) error { func (es SqlEmojiStore) Delete(emoji *model.Emoji, time int64) error {
if sqlResult, err := es.GetMaster().Exec( if sqlResult, err := es.GetMasterX().Exec(
`UPDATE `UPDATE
Emoji Emoji
SET SET
DeleteAt = :DeleteAt, DeleteAt = ?,
UpdateAt = :UpdateAt UpdateAt = ?
WHERE WHERE
Id = :Id Id = ?
AND DeleteAt = 0`, map[string]interface{}{"DeleteAt": time, "UpdateAt": time, "Id": emoji.Id}); err != nil { AND DeleteAt = 0`, time, time, emoji.Id); err != nil {
return errors.Wrap(err, "could not delete emoji") return errors.Wrap(err, "could not delete emoji")
} else if rows, _ := sqlResult.RowsAffected(); rows == 0 { } else if rows, _ := sqlResult.RowsAffected(); rows == 0 {
return store.NewErrNotFound("Emoji", emoji.Id) return store.NewErrNotFound("Emoji", emoji.Id)
@@ -119,7 +124,7 @@ func (es SqlEmojiStore) Delete(emoji *model.Emoji, time int64) error {
} }
func (es SqlEmojiStore) Search(name string, prefixOnly bool, limit int) ([]*model.Emoji, error) { func (es SqlEmojiStore) Search(name string, prefixOnly bool, limit int) ([]*model.Emoji, error) {
var emojis []*model.Emoji emojis := []*model.Emoji{}
name = sanitizeSearchTerm(name, "\\") name = sanitizeSearchTerm(name, "\\")
@@ -130,16 +135,16 @@ func (es SqlEmojiStore) Search(name string, prefixOnly bool, limit int) ([]*mode
term += name + "%" term += name + "%"
if _, err := es.GetReplica().Select(&emojis, if err := es.GetReplicaX().Select(&emojis,
`SELECT `SELECT
* *
FROM FROM
Emoji Emoji
WHERE WHERE
Name LIKE :Name Name LIKE ?
AND DeleteAt = 0 AND DeleteAt = 0
ORDER BY Name ORDER BY Name
LIMIT :Limit`, map[string]interface{}{"Name": term, "Limit": limit}); err != nil { LIMIT ?`, term, limit); err != nil {
return nil, errors.Wrapf(err, "could not search emojis by name %s", name) return nil, errors.Wrapf(err, "could not search emojis by name %s", name)
} }
return emojis, nil return emojis, nil
@@ -147,16 +152,16 @@ func (es SqlEmojiStore) Search(name string, prefixOnly bool, limit int) ([]*mode
// getBy returns one active (not deleted) emoji, found by any one column (what/key). // getBy returns one active (not deleted) emoji, found by any one column (what/key).
func (es SqlEmojiStore) getBy(ctx context.Context, what, key string) (*model.Emoji, error) { func (es SqlEmojiStore) getBy(ctx context.Context, what, key string) (*model.Emoji, error) {
var emoji *model.Emoji var emoji model.Emoji
err := es.DBFromContext(ctx).SelectOne(&emoji, err := es.DBXFromContext(ctx).Get(&emoji,
`SELECT `SELECT
* *
FROM FROM
Emoji Emoji
WHERE WHERE
`+what+` = :Key `+what+` = ?
AND DeleteAt = 0`, map[string]string{"Key": key}) AND DeleteAt = 0`, key)
if err != nil { if err != nil {
if err == sql.ErrNoRows { if err == sql.ErrNoRows {
return nil, store.NewErrNotFound("Emoji", fmt.Sprintf("%s=%s", what, key)) return nil, store.NewErrNotFound("Emoji", fmt.Sprintf("%s=%s", what, key))
@@ -165,5 +170,5 @@ func (es SqlEmojiStore) getBy(ctx context.Context, what, key string) (*model.Emo
return nil, errors.Wrapf(err, "could not get emoji by %s with value %s", what, key) return nil, errors.Wrapf(err, "could not get emoji by %s with value %s", what, key)
} }
return emoji, nil return &emoji, nil
} }

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

@@ -124,3 +124,11 @@ func constructMySQLJSONArgs(props map[string]string) ([]interface{}, string) {
return args, argString return args, argString
} }
func makeStringArgs(params []string) []interface{} {
args := make([]interface{}, len(params))
for i, name := range params {
args[i] = name
}
return args
}