11package chat
22
33import (
4- "fmt "
4+ "database/sql "
55 "strings"
66 "time"
77
@@ -207,20 +207,14 @@ type rowData struct {
207207 userType * string
208208}
209209
210- func getChat (query string ) []interface {} {
210+ func getChat (rows * sql. Rows ) ( []interface {}, error ) {
211211 history := make ([]interface {}, 0 )
212- rows , err := _datastore .DB .Query (query )
213- if err != nil || rows .Err () != nil {
214- log .Errorln ("error fetching chat history" , err )
215- return history
216- }
217- defer rows .Close ()
218212
219213 for rows .Next () {
220214 row := rowData {}
221215
222216 // Convert a database row into a chat event
223- if err = rows .Scan (
217+ if err : = rows .Scan (
224218 & row .id ,
225219 & row .userID ,
226220 & row .body ,
@@ -241,9 +235,7 @@ func getChat(query string) []interface{} {
241235 & row .userScopes ,
242236 & row .userType ,
243237 ); err != nil {
244- log .Errorln (err )
245- log .Errorln ("There is a problem converting query to chat objects. Please report this:" , query )
246- break
238+ return nil , err
247239 }
248240
249241 var message interface {}
@@ -266,7 +258,7 @@ func getChat(query string) []interface{} {
266258 history = append (history , message )
267259 }
268260
269- return history
261+ return history , nil
270262}
271263
272264var _historyCache * []interface {}
@@ -277,20 +269,89 @@ func GetChatModerationHistory() []interface{} {
277269 return * _historyCache
278270 }
279271
272+ tx , err := _datastore .DB .Begin ()
273+ if err != nil {
274+ log .Errorln ("error fetching chat moderation history" , err )
275+ return nil
276+ }
277+
278+ defer tx .Rollback () // nolint
279+
280280 // Get all messages regardless of visibility
281281 query := "SELECT messages.id, user_id, body, title, subtitle, image, link, eventType, hidden_at, timestamp, display_name, display_color, created_at, disabled_at, previous_names, namechanged_at, authenticated_at, scopes, type FROM messages INNER JOIN users ON messages.user_id = users.id ORDER BY timestamp DESC"
282- result := getChat (query )
282+ stmt , err := tx .Prepare (query )
283+ if err != nil {
284+ log .Errorln ("error fetching chat moderation history" , err )
285+ return nil
286+ }
287+
288+ rows , err := stmt .Query ()
289+ if err != nil {
290+ log .Errorln ("error fetching chat moderation history" , err )
291+ return nil
292+ }
293+
294+ defer stmt .Close ()
295+ defer rows .Close ()
296+
297+ result , err := getChat (rows )
298+
299+ if err != nil {
300+ log .Errorln (err )
301+ log .Errorln ("There is a problem enumerating chat message rows. Please report this:" , query )
302+ return nil
303+ }
283304
284305 _historyCache = & result
285306
307+ if err = tx .Commit (); err != nil {
308+ log .Errorln ("error fetching chat moderation history" , err )
309+ return nil
310+ }
311+
286312 return result
287313}
288314
289315// GetChatHistory will return all the chat messages suitable for returning as user-facing chat history.
290316func GetChatHistory () []interface {} {
317+ tx , err := _datastore .DB .Begin ()
318+ if err != nil {
319+ log .Errorln ("error fetching chat history" , err )
320+ return nil
321+ }
322+
323+ defer tx .Rollback () // nolint
324+
291325 // Get all visible messages
292- query := fmt .Sprintf ("SELECT messages.id, messages.user_id, messages.body, messages.title, messages.subtitle, messages.image, messages.link, messages.eventType, messages.hidden_at, messages.timestamp, users.display_name, users.display_color, users.created_at, users.disabled_at, users.previous_names, users.namechanged_at, users.authenticated_at, users.scopes, users.type FROM users JOIN messages ON users.id = messages.user_id WHERE hidden_at IS NULL AND disabled_at IS NULL ORDER BY timestamp DESC LIMIT %d" , maxBacklogNumber )
293- m := getChat (query )
326+ query := "SELECT messages.id, messages.user_id, messages.body, messages.title, messages.subtitle, messages.image, messages.link, messages.eventType, messages.hidden_at, messages.timestamp, users.display_name, users.display_color, users.created_at, users.disabled_at, users.previous_names, users.namechanged_at, users.authenticated_at, users.scopes, users.type FROM users JOIN messages ON users.id = messages.user_id WHERE hidden_at IS NULL AND disabled_at IS NULL ORDER BY timestamp DESC LIMIT ?"
327+
328+ stmt , err := tx .Prepare (query )
329+ if err != nil {
330+ log .Errorln ("error fetching chat history" , err )
331+ return nil
332+ }
333+
334+ rows , err := stmt .Query (maxBacklogNumber )
335+ if err != nil {
336+ log .Errorln ("error fetching chat history" , err )
337+ return nil
338+ }
339+
340+ defer stmt .Close ()
341+ defer rows .Close ()
342+
343+ m , err := getChat (rows )
344+
345+ if err != nil {
346+ log .Errorln (err )
347+ log .Errorln ("There is a problem enumerating chat message rows. Please report this:" , query )
348+ return nil
349+ }
350+
351+ if err = tx .Commit (); err != nil {
352+ log .Errorln ("error fetching chat history" , err )
353+ return nil
354+ }
294355
295356 // Invert order of messages
296357 for i , j := 0 , len (m )- 1 ; i < j ; i , j = i + 1 , j - 1 {
@@ -307,10 +368,40 @@ func SetMessageVisibilityForUserID(userID string, visible bool) error {
307368 _historyCache = nil
308369 }()
309370
371+ tx , err := _datastore .DB .Begin ()
372+ if err != nil {
373+ log .Errorln ("error while setting message visibility" , err )
374+ return nil
375+ }
376+
377+ defer tx .Rollback () // nolint
378+ query := "SELECT messages.id, user_id, body, title, subtitle, image, link, eventType, hidden_at, timestamp, display_name, display_color, created_at, disabled_at, previous_names, namechanged_at, authenticated_at, scopes, type FROM messages INNER JOIN users ON messages.user_id = users.id WHERE user_id IS ?"
379+
380+ stmt , err := tx .Prepare (query )
381+ if err != nil {
382+ log .Errorln ("error while setting message visibility" , err )
383+ return nil
384+ }
385+
386+ rows , err := stmt .Query (userID )
387+ if err != nil {
388+ log .Errorln ("error while setting message visibility" , err )
389+ return nil
390+ }
391+
392+ defer stmt .Close ()
393+ defer rows .Close ()
394+
310395 // Get a list of IDs to send to the connected clients to hide
311396 ids := make ([]string , 0 )
312- query := fmt .Sprintf ("SELECT messages.id, user_id, body, title, subtitle, image, link, eventType, hidden_at, timestamp, display_name, display_color, created_at, disabled_at, previous_names, namechanged_at, authenticated_at, scopes, type FROM messages INNER JOIN users ON messages.user_id = users.id WHERE user_id IS '%s'" , userID )
313- messages := getChat (query )
397+
398+ messages , err := getChat (rows )
399+
400+ if err != nil {
401+ log .Errorln (err )
402+ log .Errorln ("There is a problem enumerating chat message rows. Please report this:" , query )
403+ return nil
404+ }
314405
315406 if len (messages ) == 0 {
316407 return nil
@@ -320,6 +411,11 @@ func SetMessageVisibilityForUserID(userID string, visible bool) error {
320411 ids = append (ids , message .(events.UserMessageEvent ).ID )
321412 }
322413
414+ if err = tx .Commit (); err != nil {
415+ log .Errorln ("error while setting message visibility " , err )
416+ return nil
417+ }
418+
323419 // Tell the clients to hide/show these messages.
324420 return SetMessagesVisibility (ids , visible )
325421}
0 commit comments