package models import ( "strings" "time" ) // Message table. type Message struct { ID uint64 `gorm:"primaryKey"` SourceUserID uint64 `gorm:"index"` TargetUserID uint64 `gorm:"index"` Read bool `gorm:"index"` Message string CreatedAt time.Time UpdatedAt time.Time } // GetMessage by ID. func GetMessage(id uint64) (*Message, error) { m := &Message{} result := DB.First(&m, id) return m, result.Error } // GetMessages for a user. func GetMessages(userID uint64, sent bool, pager *Pagination) ([]*Message, error) { var ( m = []*Message{} blockedUserIDs = BlockedUserIDs(userID) where = []string{} placeholders = []interface{}{} ) if sent { where = append(where, "source_user_id = ?") placeholders = append(placeholders, userID) if len(blockedUserIDs) > 0 { where = append(where, "target_user_id NOT IN ?") placeholders = append(placeholders, blockedUserIDs) } } else { where = append(where, "target_user_id = ?") placeholders = append(placeholders, userID) if len(blockedUserIDs) > 0 { where = append(where, "source_user_id NOT IN ?") placeholders = append(placeholders, blockedUserIDs) } } query := DB.Where( strings.Join(where, " AND "), placeholders..., ).Order(pager.Sort) query.Model(&Message{}).Count(&pager.Total) result := query.Offset(pager.GetOffset()).Limit(pager.PerPage).Find(&m) return m, result.Error } // GetMessageThread returns paginated message history between two people. func GetMessageThread(sourceUserID, targetUserID uint64, pager *Pagination) ([]*Message, error) { var m = []*Message{} query := DB.Where( "(source_user_id = ? AND target_user_id = ?) OR (source_user_id = ? AND target_user_id = ?)", sourceUserID, targetUserID, targetUserID, sourceUserID, ).Order(pager.Sort) query.Model(&Message{}).Count(&pager.Total) result := query.Offset(pager.GetOffset()).Limit(pager.PerPage).Find(&m) return m, result.Error } // DeleteMessageThread removes all message history between two people. func DeleteMessageThread(message *Message) error { return DB.Where( "(source_user_id = ? AND target_user_id = ?) OR (source_user_id = ? AND target_user_id = ?)", message.SourceUserID, message.TargetUserID, message.TargetUserID, message.SourceUserID, ).Delete(&Message{}).Error } // CountUnreadMessages gets the count of unread messages for a user. func CountUnreadMessages(userID uint64) (int64, error) { query := DB.Where( "target_user_id = ? AND read = ?", userID, false, ) var count int64 result := query.Model(&Message{}).Count(&count) return count, result.Error } // SendMessage from a source to a target user. func SendMessage(sourceUserID, targetUserID uint64, message string) (*Message, error) { m := &Message{ SourceUserID: sourceUserID, TargetUserID: targetUserID, Message: message, Read: false, } result := DB.Create(m) return m, result.Error } // Save message. func (m *Message) Save() error { result := DB.Save(m) return result.Error } // Delete a message. func (m *Message) Delete() error { return DB.Delete(m).Error }