feature(@status-go/chat): implement search results for communities, channels (#2303)
AllMessagesFromChatsAndCommunitiesWhichMatchTerm method added which returns all messages which match the search term, if they belong to either any chat from the chatIds array or any channel of any community from communityIds array. This api point is necessary for desktop issue 2934. Fixes: #2934
This commit is contained in:
parent
2b566db298
commit
b8959e3f66
|
@ -652,6 +652,106 @@ func (db sqlitePersistence) AllMessageByChatIDWhichMatchTerm(chatID string, sear
|
|||
return result, nil
|
||||
}
|
||||
|
||||
// AllMessagesFromChatsAndCommunitiesWhichMatchTerm returns all messages which match the search
|
||||
// term, if they belong to either any chat from the chatIds array or any channel of any community
|
||||
// from communityIds array.
|
||||
// Ordering is accomplished using two concatenated values: ClockValue and ID.
|
||||
// These two values are also used to compose a cursor which is returned to the result.
|
||||
func (db sqlitePersistence) AllMessagesFromChatsAndCommunitiesWhichMatchTerm(communityIds []string, chatIds []string, searchTerm string, caseSensitive bool) ([]*common.Message, error) {
|
||||
if searchTerm == "" {
|
||||
return nil, fmt.Errorf("empty search term")
|
||||
}
|
||||
|
||||
chatsCond := ""
|
||||
if len(chatIds) > 0 {
|
||||
inVector := strings.Repeat("?, ", len(chatIds)-1) + "?"
|
||||
chatsCond = `m1.local_chat_id IN (%s)`
|
||||
chatsCond = fmt.Sprintf(chatsCond, inVector)
|
||||
}
|
||||
|
||||
communitiesCond := ""
|
||||
if len(communityIds) > 0 {
|
||||
inVector := strings.Repeat("?, ", len(communityIds)-1) + "?"
|
||||
communitiesCond = `m1.local_chat_id IN (SELECT id FROM chats WHERE community_id IN (%s))`
|
||||
communitiesCond = fmt.Sprintf(communitiesCond, inVector)
|
||||
}
|
||||
|
||||
searchCond := ""
|
||||
if caseSensitive {
|
||||
searchCond = "m1.text LIKE '%' || ? || '%'"
|
||||
} else {
|
||||
searchCond = "LOWER(m1.text) LIKE LOWER('%' || ? || '%')"
|
||||
}
|
||||
|
||||
finalCond := "AND %s AND %s"
|
||||
if len(communityIds) > 0 && len(chatIds) > 0 {
|
||||
finalCond = "AND (%s OR %s) AND %s"
|
||||
finalCond = fmt.Sprintf(finalCond, chatsCond, communitiesCond, searchCond)
|
||||
} else if len(chatIds) > 0 {
|
||||
finalCond = fmt.Sprintf(finalCond, chatsCond, searchCond)
|
||||
} else if len(communityIds) > 0 {
|
||||
finalCond = fmt.Sprintf(finalCond, communitiesCond, searchCond)
|
||||
} else {
|
||||
return nil, fmt.Errorf("you must specify either community ids or chat ids or both")
|
||||
}
|
||||
|
||||
var parameters []string
|
||||
parameters = append(parameters, chatIds...)
|
||||
parameters = append(parameters, communityIds...)
|
||||
parameters = append(parameters, searchTerm)
|
||||
|
||||
idsArgs := make([]interface{}, 0, len(parameters))
|
||||
for _, param := range parameters {
|
||||
idsArgs = append(idsArgs, param)
|
||||
}
|
||||
|
||||
allFields := db.tableUserMessagesAllFieldsJoin()
|
||||
|
||||
finalQuery := fmt.Sprintf(`
|
||||
SELECT
|
||||
%s,
|
||||
substr('0000000000000000000000000000000000000000000000000000000000000000' || m1.clock_value, -64, 64) || m1.id as cursor
|
||||
FROM
|
||||
user_messages m1
|
||||
LEFT JOIN
|
||||
user_messages m2
|
||||
ON
|
||||
m1.response_to = m2.id
|
||||
|
||||
LEFT JOIN
|
||||
contacts c
|
||||
ON
|
||||
|
||||
m1.source = c.id
|
||||
WHERE
|
||||
NOT(m1.hide) %s
|
||||
ORDER BY cursor DESC
|
||||
`, allFields, finalCond)
|
||||
|
||||
rows, err := db.db.Query(finalQuery, idsArgs...)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
|
||||
var (
|
||||
result []*common.Message
|
||||
)
|
||||
for rows.Next() {
|
||||
var (
|
||||
message common.Message
|
||||
cursor string
|
||||
)
|
||||
if err := db.tableUserMessagesScanAllFields(rows, &message, &cursor); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
result = append(result, &message)
|
||||
}
|
||||
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// PinnedMessageByChatID returns all pinned messages for a given chatID in descending order.
|
||||
// Ordering is accomplished using two concatenated values: ClockValue and ID.
|
||||
// These two values are also used to compose a cursor which is returned to the result.
|
||||
|
|
|
@ -3170,6 +3170,10 @@ func (m *Messenger) AllMessageByChatIDWhichMatchTerm(chatID string, searchTerm s
|
|||
return m.persistence.AllMessageByChatIDWhichMatchTerm(chatID, searchTerm, caseSensitive)
|
||||
}
|
||||
|
||||
func (m *Messenger) AllMessagesFromChatsAndCommunitiesWhichMatchTerm(communityIds []string, chatIds []string, searchTerm string, caseSensitive bool) ([]*common.Message, error) {
|
||||
return m.persistence.AllMessagesFromChatsAndCommunitiesWhichMatchTerm(communityIds, chatIds, searchTerm, caseSensitive)
|
||||
}
|
||||
|
||||
func (m *Messenger) SaveMessages(messages []*common.Message) error {
|
||||
return m.persistence.SaveMessages(messages)
|
||||
}
|
||||
|
|
|
@ -490,7 +490,7 @@ func (api *PublicAPI) ChatMessages(chatID, cursor string, limit int) (*Applicati
|
|||
}, nil
|
||||
}
|
||||
|
||||
func (api *PublicAPI) AllChatMessagesWhichMatchTerm(chatID, searchTerm string, caseSensitive bool) (*ApplicationMessagesResponse, error) {
|
||||
func (api *PublicAPI) AllMessagesFromChatWhichMatchTerm(chatID, searchTerm string, caseSensitive bool) (*ApplicationMessagesResponse, error) {
|
||||
messages, err := api.service.messenger.AllMessageByChatIDWhichMatchTerm(chatID, searchTerm, caseSensitive)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
@ -501,6 +501,17 @@ func (api *PublicAPI) AllChatMessagesWhichMatchTerm(chatID, searchTerm string, c
|
|||
}, nil
|
||||
}
|
||||
|
||||
func (api *PublicAPI) AllMessagesFromChatsAndCommunitiesWhichMatchTerm(communityIds []string, chatIds []string, searchTerm string, caseSensitive bool) (*ApplicationMessagesResponse, error) {
|
||||
messages, err := api.service.messenger.AllMessagesFromChatsAndCommunitiesWhichMatchTerm(communityIds, chatIds, searchTerm, caseSensitive)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &ApplicationMessagesResponse{
|
||||
Messages: messages,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (api *PublicAPI) ChatPinnedMessages(chatID, cursor string, limit int) (*ApplicationPinnedMessagesResponse, error) {
|
||||
pinnedMessages, cursor, err := api.service.messenger.PinnedMessageByChatID(chatID, cursor, limit)
|
||||
if err != nil {
|
||||
|
|
Loading…
Reference in New Issue