github.com/qichengzx/mattermost-server@v4.5.1-0.20180604164826-2c75247c97d0+incompatible/store/sqlstore/compliance_store.go (about) 1 // Copyright (c) 2016-present Mattermost, Inc. All Rights Reserved. 2 // See License.txt for license information. 3 4 package sqlstore 5 6 import ( 7 "net/http" 8 "strconv" 9 "strings" 10 11 "github.com/mattermost/mattermost-server/model" 12 "github.com/mattermost/mattermost-server/store" 13 ) 14 15 type SqlComplianceStore struct { 16 SqlStore 17 } 18 19 func NewSqlComplianceStore(sqlStore SqlStore) store.ComplianceStore { 20 s := &SqlComplianceStore{sqlStore} 21 22 for _, db := range sqlStore.GetAllConns() { 23 table := db.AddTableWithName(model.Compliance{}, "Compliances").SetKeys(false, "Id") 24 table.ColMap("Id").SetMaxSize(26) 25 table.ColMap("UserId").SetMaxSize(26) 26 table.ColMap("Status").SetMaxSize(64) 27 table.ColMap("Desc").SetMaxSize(512) 28 table.ColMap("Type").SetMaxSize(64) 29 table.ColMap("Keywords").SetMaxSize(512) 30 table.ColMap("Emails").SetMaxSize(1024) 31 } 32 33 return s 34 } 35 36 func (s SqlComplianceStore) CreateIndexesIfNotExists() { 37 } 38 39 func (s SqlComplianceStore) Save(compliance *model.Compliance) store.StoreChannel { 40 return store.Do(func(result *store.StoreResult) { 41 compliance.PreSave() 42 if result.Err = compliance.IsValid(); result.Err != nil { 43 return 44 } 45 46 if err := s.GetMaster().Insert(compliance); err != nil { 47 result.Err = model.NewAppError("SqlComplianceStore.Save", "store.sql_compliance.save.saving.app_error", nil, err.Error(), http.StatusInternalServerError) 48 } else { 49 result.Data = compliance 50 } 51 }) 52 } 53 54 func (us SqlComplianceStore) Update(compliance *model.Compliance) store.StoreChannel { 55 return store.Do(func(result *store.StoreResult) { 56 if result.Err = compliance.IsValid(); result.Err != nil { 57 return 58 } 59 60 if _, err := us.GetMaster().Update(compliance); err != nil { 61 result.Err = model.NewAppError("SqlComplianceStore.Update", "store.sql_compliance.save.saving.app_error", nil, err.Error(), http.StatusInternalServerError) 62 } else { 63 result.Data = compliance 64 } 65 }) 66 } 67 68 func (s SqlComplianceStore) GetAll(offset, limit int) store.StoreChannel { 69 return store.Do(func(result *store.StoreResult) { 70 query := "SELECT * FROM Compliances ORDER BY CreateAt DESC LIMIT :Limit OFFSET :Offset" 71 72 var compliances model.Compliances 73 if _, err := s.GetReplica().Select(&compliances, query, map[string]interface{}{"Offset": offset, "Limit": limit}); err != nil { 74 result.Err = model.NewAppError("SqlComplianceStore.Get", "store.sql_compliance.get.finding.app_error", nil, err.Error(), http.StatusInternalServerError) 75 } else { 76 result.Data = compliances 77 } 78 }) 79 } 80 81 func (us SqlComplianceStore) Get(id string) store.StoreChannel { 82 return store.Do(func(result *store.StoreResult) { 83 if obj, err := us.GetReplica().Get(model.Compliance{}, id); err != nil { 84 result.Err = model.NewAppError("SqlComplianceStore.Get", "store.sql_compliance.get.finding.app_error", nil, err.Error(), http.StatusInternalServerError) 85 } else if obj == nil { 86 result.Err = model.NewAppError("SqlComplianceStore.Get", "store.sql_compliance.get.finding.app_error", nil, err.Error(), http.StatusNotFound) 87 } else { 88 result.Data = obj.(*model.Compliance) 89 } 90 }) 91 } 92 93 func (s SqlComplianceStore) ComplianceExport(job *model.Compliance) store.StoreChannel { 94 return store.Do(func(result *store.StoreResult) { 95 props := map[string]interface{}{"StartTime": job.StartAt, "EndTime": job.EndAt} 96 97 keywordQuery := "" 98 keywords := strings.Fields(strings.TrimSpace(strings.ToLower(strings.Replace(job.Keywords, ",", " ", -1)))) 99 if len(keywords) > 0 { 100 101 keywordQuery = "AND (" 102 103 for index, keyword := range keywords { 104 if index >= 1 { 105 keywordQuery += " OR LOWER(Posts.Message) LIKE :Keyword" + strconv.Itoa(index) 106 } else { 107 keywordQuery += "LOWER(Posts.Message) LIKE :Keyword" + strconv.Itoa(index) 108 } 109 110 props["Keyword"+strconv.Itoa(index)] = "%" + keyword + "%" 111 } 112 113 keywordQuery += ")" 114 } 115 116 emailQuery := "" 117 emails := strings.Fields(strings.TrimSpace(strings.ToLower(strings.Replace(job.Emails, ",", " ", -1)))) 118 if len(emails) > 0 { 119 120 emailQuery = "AND (" 121 122 for index, email := range emails { 123 if index >= 1 { 124 emailQuery += " OR Users.Email = :Email" + strconv.Itoa(index) 125 } else { 126 emailQuery += "Users.Email = :Email" + strconv.Itoa(index) 127 } 128 129 props["Email"+strconv.Itoa(index)] = email 130 } 131 132 emailQuery += ")" 133 } 134 135 query := 136 `(SELECT 137 Teams.Name AS TeamName, 138 Teams.DisplayName AS TeamDisplayName, 139 Channels.Name AS ChannelName, 140 Channels.DisplayName AS ChannelDisplayName, 141 Channels.Type AS ChannelType, 142 Users.Username AS UserUsername, 143 Users.Email AS UserEmail, 144 Users.Nickname AS UserNickname, 145 Posts.Id AS PostId, 146 Posts.CreateAt AS PostCreateAt, 147 Posts.UpdateAt AS PostUpdateAt, 148 Posts.DeleteAt AS PostDeleteAt, 149 Posts.RootId AS PostRootId, 150 Posts.ParentId AS PostParentId, 151 Posts.OriginalId AS PostOriginalId, 152 Posts.Message AS PostMessage, 153 Posts.Type AS PostType, 154 Posts.Props AS PostProps, 155 Posts.Hashtags AS PostHashtags, 156 Posts.FileIds AS PostFileIds 157 FROM 158 Teams, 159 Channels, 160 Users, 161 Posts 162 WHERE 163 Teams.Id = Channels.TeamId 164 AND Posts.ChannelId = Channels.Id 165 AND Posts.UserId = Users.Id 166 AND Posts.CreateAt > :StartTime 167 AND Posts.CreateAt <= :EndTime 168 ` + emailQuery + ` 169 ` + keywordQuery + `) 170 UNION ALL 171 (SELECT 172 'direct-messages' AS TeamName, 173 'Direct Messages' AS TeamDisplayName, 174 Channels.Name AS ChannelName, 175 Channels.DisplayName AS ChannelDisplayName, 176 Channels.Type AS ChannelType, 177 Users.Username AS UserUsername, 178 Users.Email AS UserEmail, 179 Users.Nickname AS UserNickname, 180 Posts.Id AS PostId, 181 Posts.CreateAt AS PostCreateAt, 182 Posts.UpdateAt AS PostUpdateAt, 183 Posts.DeleteAt AS PostDeleteAt, 184 Posts.RootId AS PostRootId, 185 Posts.ParentId AS PostParentId, 186 Posts.OriginalId AS PostOriginalId, 187 Posts.Message AS PostMessage, 188 Posts.Type AS PostType, 189 Posts.Props AS PostProps, 190 Posts.Hashtags AS PostHashtags, 191 Posts.FileIds AS PostFileIds 192 FROM 193 Channels, 194 Users, 195 Posts 196 WHERE 197 Channels.TeamId = '' 198 AND Posts.ChannelId = Channels.Id 199 AND Posts.UserId = Users.Id 200 AND Posts.CreateAt > :StartTime 201 AND Posts.CreateAt <= :EndTime 202 ` + emailQuery + ` 203 ` + keywordQuery + `) 204 ORDER BY PostCreateAt 205 LIMIT 30000` 206 207 var cposts []*model.CompliancePost 208 209 if _, err := s.GetReplica().Select(&cposts, query, props); err != nil { 210 result.Err = model.NewAppError("SqlPostStore.ComplianceExport", "store.sql_post.compliance_export.app_error", nil, err.Error(), http.StatusInternalServerError) 211 } else { 212 result.Data = cposts 213 } 214 }) 215 } 216 217 func (s SqlComplianceStore) MessageExport(after int64, limit int) store.StoreChannel { 218 return store.Do(func(result *store.StoreResult) { 219 props := map[string]interface{}{"StartTime": after, "Limit": limit} 220 query := 221 `SELECT 222 Posts.Id AS PostId, 223 Posts.CreateAt AS PostCreateAt, 224 Posts.Message AS PostMessage, 225 Posts.Type AS PostType, 226 Posts.FileIds AS PostFileIds, 227 Channels.Id AS ChannelId, 228 CASE 229 WHEN Channels.Type = 'D' THEN 'Direct Message' 230 WHEN Channels.Type = 'G' THEN 'Group Message' 231 ELSE Channels.DisplayName 232 END AS ChannelDisplayName, 233 Channels.Type AS ChannelType, 234 Users.Id AS UserId, 235 Users.Email AS UserEmail, 236 Users.Username 237 FROM 238 Posts 239 LEFT OUTER JOIN Channels ON Posts.ChannelId = Channels.Id 240 LEFT OUTER JOIN Users ON Posts.UserId = Users.Id 241 WHERE 242 Posts.CreateAt > :StartTime AND 243 Posts.Type = '' 244 ORDER BY PostCreateAt 245 LIMIT :Limit` 246 247 var cposts []*model.MessageExport 248 if _, err := s.GetReplica().Select(&cposts, query, props); err != nil { 249 result.Err = model.NewAppError("SqlComplianceStore.MessageExport", "store.sql_compliance.message_export.app_error", nil, err.Error(), http.StatusInternalServerError) 250 } else { 251 result.Data = cposts 252 } 253 }) 254 }