[MM-38996] - Migrate from gorp to sqlx in store/sqlstore/compliance_store.go (#18633)

* migrate from gorp to sqlx in store/sqlstore/compliance_store.go

Signed-off-by: Penthaa Patel <penthaapatel@gmail.com>

* fix SQL syntax

Signed-off-by: Penthaa Patel <penthaapatel@gmail.com>

* fix SQL syntax

Signed-off-by: Penthaa Patel <penthaapatel@gmail.com>

* fix SQL syntax

Signed-off-by: Penthaa Patel <penthaapatel@gmail.com>

* fix SQL syntax error

Signed-off-by: Penthaa Patel <penthaapatel@gmail.com>

* Fixes

```release-note
NONE
```

Co-authored-by: Agniva De Sarker <agnivade@yahoo.co.in>
Этот коммит содержится в:
Penthaa Patel
2021-10-15 20:06:57 +05:30
коммит произвёл GitHub
родитель c27814393d
Коммит c02cdd842a

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

@@ -4,9 +4,11 @@
package sqlstore
import (
"strconv"
"database/sql"
"fmt"
"strings"
sq "github.com/Masterminds/squirrel"
"github.com/pkg/errors"
"github.com/mattermost/mattermost-server/v6/model"
@@ -43,7 +45,18 @@ func (s SqlComplianceStore) Save(compliance *model.Compliance) (*model.Complianc
return nil, err
}
if err := s.GetMaster().Insert(compliance); err != nil {
// DESC is a keyword
var desc string
if s.DriverName() == model.DatabaseDriverPostgres {
desc = `"desc"`
} else {
desc = "`Desc`"
}
query := `INSERT INTO Compliances (Id, CreateAt, UserId, Status, Count, ` + desc + `, Type, StartAt, EndAt, Keywords, Emails)
VALUES
(:Id, :CreateAt, :UserId, :Status, :Count, :Desc, :Type, :StartAt, :EndAt, :Keywords, :Emails)`
if _, err := s.GetMasterX().NamedExec(query, compliance); err != nil {
return nil, errors.Wrap(err, "failed to save Compliance")
}
return compliance, nil
@@ -54,58 +67,93 @@ func (s SqlComplianceStore) Update(compliance *model.Compliance) (*model.Complia
return nil, err
}
if _, err := s.GetMaster().Update(compliance); err != nil {
query := s.getQueryBuilder().
Update("Compliances").
Set("CreateAt", compliance.CreateAt).
Set("UserId", compliance.UserId).
Set("Status", compliance.Status).
Set("Count", compliance.Count).
Set("Type", compliance.Type).
Set("StartAt", compliance.StartAt).
Set("EndAt", compliance.EndAt).
Set("Keywords", compliance.Keywords).
Set("Emails", compliance.Emails).
Where(sq.Eq{"Id": compliance.Id})
// DESC is a keyword
if s.DriverName() == model.DatabaseDriverPostgres {
query = query.Set(`"desc"`, compliance.Desc)
} else {
query = query.Set("`Desc`", compliance.Desc)
}
queryString, args, err := query.ToSql()
if err != nil {
return nil, errors.Wrap(err, "compliances_tosql")
}
res, err := s.GetMasterX().Exec(queryString, args...)
if err != nil {
return nil, errors.Wrap(err, "failed to update Compliance")
}
count, err := res.RowsAffected()
if err != nil {
return nil, errors.Wrap(err, "error while getting rows_affected")
}
if count > 1 {
return nil, fmt.Errorf("unexpected count while updating compliances: count=%d, Id=%s", count, compliance.Id)
}
return compliance, nil
}
func (s SqlComplianceStore) GetAll(offset, limit int) (model.Compliances, error) {
query := "SELECT * FROM Compliances ORDER BY CreateAt DESC LIMIT :Limit OFFSET :Offset"
var compliances model.Compliances
if _, err := s.GetReplica().Select(&compliances, query, map[string]interface{}{"Offset": offset, "Limit": limit}); err != nil {
query := "SELECT * FROM Compliances ORDER BY CreateAt DESC LIMIT ? OFFSET ?"
compliances := model.Compliances{}
if err := s.GetReplicaX().Select(&compliances, query, limit, offset); err != nil {
return nil, errors.Wrap(err, "failed to find all Compliances")
}
return compliances, nil
}
func (s SqlComplianceStore) Get(id string) (*model.Compliance, error) {
obj, err := s.GetReplica().Get(model.Compliance{}, id)
if err != nil {
var compliance model.Compliance
if err := s.GetReplicaX().Get(&compliance, `SELECT * FROM Compliances WHERE Id = ?`, id); err != nil {
if err == sql.ErrNoRows {
return nil, store.NewErrNotFound("Compliances", id)
}
return nil, errors.Wrapf(err, "failed to get Compliance with id=%s", id)
}
if obj == nil {
if compliance.Id == "" {
return nil, store.NewErrNotFound("Compliance", id)
}
return obj.(*model.Compliance), nil
return &compliance, nil
}
func (s SqlComplianceStore) ComplianceExport(job *model.Compliance, cursor model.ComplianceExportCursor, limit int) ([]*model.CompliancePost, model.ComplianceExportCursor, error) {
props := map[string]interface{}{"EndTime": job.EndAt, "Limit": limit}
keywordQuery := ""
var argsKeywords []interface{}
keywords := strings.Fields(strings.TrimSpace(strings.ToLower(strings.Replace(job.Keywords, ",", " ", -1))))
if len(keywords) > 0 {
clauses := make([]string, len(keywords))
for i, keyword := range keywords {
keyword = sanitizeSearchTerm(keyword, "\\")
clauses[i] = "LOWER(Posts.Message) LIKE :Keyword" + strconv.Itoa(i)
props["Keyword"+strconv.Itoa(i)] = "%" + keyword + "%"
clauses[i] = "LOWER(Posts.Message) LIKE ?"
argsKeywords = append(argsKeywords, "%"+keyword+"%")
}
keywordQuery = "AND (" + strings.Join(clauses, " OR ") + ")"
}
emailQuery := ""
var argsEmails []interface{}
emails := strings.Fields(strings.TrimSpace(strings.ToLower(strings.Replace(job.Emails, ",", " ", -1))))
if len(emails) > 0 {
clauses := make([]string, len(emails))
for i, email := range emails {
clauses[i] = "Users.Email = :Email" + strconv.Itoa(i)
props["Email"+strconv.Itoa(i)] = email
clauses[i] = "Users.Email = ?"
argsEmails = append(argsEmails, email)
}
emailQuery = "AND (" + strings.Join(clauses, " OR ") + ")"
@@ -114,14 +162,18 @@ func (s SqlComplianceStore) ComplianceExport(job *model.Compliance, cursor model
// The idea is to first iterate over the channel posts, and then when we run out of those,
// start iterating over the direct message posts.
var channelPosts []*model.CompliancePost
channelPosts := []*model.CompliancePost{}
channelsQuery := ""
var argsChannelsQuery []interface{}
if !cursor.ChannelsQueryCompleted {
if cursor.LastChannelsQueryPostCreateAt == 0 {
cursor.LastChannelsQueryPostCreateAt = job.StartAt
}
props["LastPostCreateAt"] = cursor.LastChannelsQueryPostCreateAt
props["LastPostId"] = cursor.LastChannelsQueryPostID
//append the named parameters of SQL query in the correct order to argsChannelsQuery
argsChannelsQuery = append(argsChannelsQuery, cursor.LastChannelsQueryPostCreateAt, cursor.LastChannelsQueryPostCreateAt, cursor.LastChannelsQueryPostID, job.EndAt)
argsChannelsQuery = append(argsChannelsQuery, argsEmails...)
argsChannelsQuery = append(argsChannelsQuery, argsKeywords...)
argsChannelsQuery = append(argsChannelsQuery, limit)
channelsQuery = `
SELECT
Teams.Name AS TeamName,
@@ -156,15 +208,15 @@ func (s SqlComplianceStore) ComplianceExport(job *model.Compliance, cursor model
AND Posts.ChannelId = Channels.Id
AND Posts.UserId = Users.Id
AND (
Posts.CreateAt > :LastPostCreateAt
OR (Posts.CreateAt = :LastPostCreateAt AND Posts.Id > :LastPostId)
Posts.CreateAt > ?
OR (Posts.CreateAt = ? AND Posts.Id > ?)
)
AND Posts.CreateAt < :EndTime
AND Posts.CreateAt < ?
` + emailQuery + `
` + keywordQuery + `
ORDER BY Posts.CreateAt, Posts.Id
LIMIT :Limit`
if _, err := s.GetReplica().Select(&channelPosts, channelsQuery, props); err != nil {
LIMIT ?`
if err := s.GetReplicaX().Select(&channelPosts, channelsQuery, argsChannelsQuery...); err != nil {
return nil, cursor, errors.Wrap(err, "unable to export compliance")
}
if len(channelPosts) < limit {
@@ -175,15 +227,18 @@ func (s SqlComplianceStore) ComplianceExport(job *model.Compliance, cursor model
}
}
var directMessagePosts []*model.CompliancePost
directMessagePosts := []*model.CompliancePost{}
directMessagesQuery := ""
var argsDirectMessagesQuery []interface{}
if !cursor.DirectMessagesQueryCompleted && len(channelPosts) < limit {
if cursor.LastDirectMessagesQueryPostCreateAt == 0 {
cursor.LastDirectMessagesQueryPostCreateAt = job.StartAt
}
props["LastPostCreateAt"] = cursor.LastDirectMessagesQueryPostCreateAt
props["LastPostId"] = cursor.LastDirectMessagesQueryPostID
props["Limit"] = limit - len(channelPosts)
//append the named parameters of SQL query in the correct order to argsDirectMessagesQuery
argsDirectMessagesQuery = append(argsDirectMessagesQuery, cursor.LastDirectMessagesQueryPostCreateAt, cursor.LastDirectMessagesQueryPostCreateAt, cursor.LastDirectMessagesQueryPostID, job.EndAt)
argsDirectMessagesQuery = append(argsDirectMessagesQuery, argsEmails...)
argsDirectMessagesQuery = append(argsDirectMessagesQuery, argsKeywords...)
argsDirectMessagesQuery = append(argsDirectMessagesQuery, limit-len(channelPosts))
directMessagesQuery = `
SELECT
'direct-messages' AS TeamName,
@@ -217,16 +272,16 @@ func (s SqlComplianceStore) ComplianceExport(job *model.Compliance, cursor model
AND Posts.ChannelId = Channels.Id
AND Posts.UserId = Users.Id
AND (
Posts.CreateAt > :LastPostCreateAt
OR (Posts.CreateAt = :LastPostCreateAt AND Posts.Id > :LastPostId)
Posts.CreateAt > ?
OR (Posts.CreateAt = ? AND Posts.Id > ?)
)
AND Posts.CreateAt < :EndTime
AND Posts.CreateAt < ?
` + emailQuery + `
` + keywordQuery + `
ORDER BY Posts.CreateAt, Posts.Id
LIMIT :Limit`
LIMIT ?`
if _, err := s.GetReplica().Select(&directMessagePosts, directMessagesQuery, props); err != nil {
if err := s.GetReplicaX().Select(&directMessagePosts, directMessagesQuery, argsDirectMessagesQuery...); err != nil {
return nil, cursor, errors.Wrap(err, "unable to export compliance")
}
if len(directMessagePosts) < limit {
@@ -241,11 +296,8 @@ func (s SqlComplianceStore) ComplianceExport(job *model.Compliance, cursor model
}
func (s SqlComplianceStore) MessageExport(cursor model.MessageExportCursor, limit int) ([]*model.MessageExport, model.MessageExportCursor, error) {
props := map[string]interface{}{
"LastPostUpdateAt": cursor.LastPostUpdateAt,
"LastPostId": cursor.LastPostId,
"Limit": limit,
}
var args []interface{}
args = append(args, cursor.LastPostUpdateAt, cursor.LastPostUpdateAt, cursor.LastPostId, limit)
query :=
`SELECT
Posts.Id AS PostId,
@@ -280,17 +332,17 @@ func (s SqlComplianceStore) MessageExport(cursor model.MessageExportCursor, limi
LEFT OUTER JOIN Users ON Posts.UserId = Users.Id
LEFT JOIN Bots ON Bots.UserId = Posts.UserId
WHERE (
Posts.UpdateAt > :LastPostUpdateAt
Posts.UpdateAt > ?
OR (
Posts.UpdateAt = :LastPostUpdateAt
AND Posts.Id > :LastPostId
Posts.UpdateAt = ?
AND Posts.Id > ?
)
) AND Posts.Type NOT LIKE 'system_%'
ORDER BY PostUpdateAt, PostId
LIMIT :Limit`
LIMIT ?`
var cposts []*model.MessageExport
if _, err := s.GetReplica().Select(&cposts, query, props); err != nil {
cposts := []*model.MessageExport{}
if err := s.GetReplicaX().Select(&cposts, query, args...); err != nil {
return nil, cursor, errors.Wrap(err, "unable to export messages")
}
if len(cposts) > 0 {