From 7c25648cbf631544c8440138787366d04325c0fb Mon Sep 17 00:00:00 2001 From: Alessio Date: Thu, 22 Jun 2023 18:40:46 -0300 Subject: [PATCH] Add DB queries for DM chat messages and reactions - also change reactions to be a map instead of a slice --- pkg/persistence/dm_queries.go | 24 ++++++++++++++++-------- pkg/persistence/dm_queries_test.go | 19 +++++++++++++++++++ pkg/persistence/schema.sql | 3 +-- pkg/persistence/utils_test.go | 22 ++++++++++++++++++++++ pkg/scraper/api_types_dms_test.go | 3 ++- pkg/scraper/dm_message.go | 6 +++--- 6 files changed, 63 insertions(+), 14 deletions(-) diff --git a/pkg/persistence/dm_queries.go b/pkg/persistence/dm_queries.go index 067a92e..8b03d5b 100644 --- a/pkg/persistence/dm_queries.go +++ b/pkg/persistence/dm_queries.go @@ -99,13 +99,15 @@ func (p Profile) SaveChatMessage(m scraper.DMMessage) error { return fmt.Errorf("Error saving message: %#v\n %w", m, err) } - _, err = p.DB.NamedExec(` - insert into chat_message_reactions (id, message_id, sender_id, sent_at, emoji) - values (:id, :message_id, :sender_id, :sent_at, :emoji) - `, m.Reactions, - ) - if err != nil { - return fmt.Errorf("Error saving message reactions: %#v\n %w", m, err) + for _, reacc := range m.Reactions { + _, err = p.DB.NamedExec(` + insert into chat_message_reactions (id, message_id, sender_id, sent_at, emoji) + values (:id, :message_id, :sender_id, :sent_at, :emoji) + `, reacc, + ) + if err != nil { + return fmt.Errorf("Error saving message reaction (message %d, reacc %d): %#v\n %w", m.ID, reacc.ID, m, err) + } } return nil } @@ -113,6 +115,7 @@ func (p Profile) SaveChatMessage(m scraper.DMMessage) error { func (p Profile) GetChatMessage(id scraper.DMMessageID) (ret scraper.DMMessage, err error) { err = p.DB.Get(&ret, ` select id, chat_room_id, sender_id, sent_at, request_id, text, in_reply_to_id + from chat_messages where id = ? `, id, ) @@ -120,7 +123,8 @@ func (p Profile) GetChatMessage(id scraper.DMMessageID) (ret scraper.DMMessage, return ret, fmt.Errorf("Error getting chat message (%d):\n %w", id, err) } - err = p.DB.Select(&ret.Reactions, ` + reaccs := []scraper.DMReaction{} + err = p.DB.Select(&reaccs, ` select id, message_id, sender_id, sent_at, emoji from chat_message_reactions where message_id = ? @@ -129,5 +133,9 @@ func (p Profile) GetChatMessage(id scraper.DMMessageID) (ret scraper.DMMessage, if err != nil { return ret, fmt.Errorf("Error getting reactions to chat message (%d):\n %w", id, err) } + ret.Reactions = make(map[scraper.UserID]scraper.DMReaction) + for _, r := range reaccs { + ret.Reactions[r.SenderID] = r + } return ret, nil } diff --git a/pkg/persistence/dm_queries_test.go b/pkg/persistence/dm_queries_test.go index d130731..7d97084 100644 --- a/pkg/persistence/dm_queries_test.go +++ b/pkg/persistence/dm_queries_test.go @@ -99,3 +99,22 @@ func TestModifyChatParticipant(t *testing.T) { t.Error(diff) } } + +func TestSaveAndLoadChatMessage(t *testing.T) { + require := require.New(t) + profile_path := "test_profiles/TestDMs" + profile := create_or_load_profile(profile_path) + + // Save it + message := create_dummy_chat_message() + err := profile.SaveChatMessage(message) + require.NoError(err) + + // Reload it + new_message, err := profile.GetChatMessage(message.ID) + require.NoError(err) + + if diff := deep.Equal(message, new_message); diff != nil { + t.Error(diff) + } +} diff --git a/pkg/persistence/schema.sql b/pkg/persistence/schema.sql index f45ed7a..e14ac5d 100644 --- a/pkg/persistence/schema.sql +++ b/pkg/persistence/schema.sql @@ -237,7 +237,6 @@ create table chat_messages (rowid integer primary key, text text not null, foreign key(chat_room_id) references chat_rooms(id) foreign key(sender_id) references users(id) - foreign key(in_reply_to_id) references chat_messages(id) ); create table chat_message_reactions (rowid integer primary key, @@ -246,7 +245,7 @@ create table chat_message_reactions (rowid integer primary key, sender_id integer not null, sent_at integer not null, emoji text not null check (length(emoji) = 1), - foreign key(message_id) references messages(id) + foreign key(message_id) references chat_messages(id) foreign key(sender_id) references users(id) ); diff --git a/pkg/persistence/utils_test.go b/pkg/persistence/utils_test.go index af16a78..fdd6ede 100644 --- a/pkg/persistence/utils_test.go +++ b/pkg/persistence/utils_test.go @@ -354,3 +354,25 @@ func create_dummy_chat_room() scraper.DMChatRoom { }, } } + +func create_dummy_chat_message() scraper.DMMessage { + rand.Seed(time.Now().UnixNano()) + id := scraper.DMMessageID(rand.Int()) + return scraper.DMMessage{ + ID: id, + DMChatRoomID: create_stable_chat_room().ID, + SenderID: create_stable_user().ID, + SentAt: scraper.TimestampFromUnix(50000), + RequestID: "fwjefkj", + Text: fmt.Sprintf("This is message #%d", id), + Reactions: map[scraper.UserID]scraper.DMReaction{ + scraper.UserID(-1): { + ID: id + 1, + DMMessageID: id, + SenderID: scraper.UserID(-1), + SentAt: scraper.TimestampFromUnix(51000), + Emoji: "🤔", + }, + }, + } +} diff --git a/pkg/scraper/api_types_dms_test.go b/pkg/scraper/api_types_dms_test.go index 227176f..4c568b4 100644 --- a/pkg/scraper/api_types_dms_test.go +++ b/pkg/scraper/api_types_dms_test.go @@ -45,7 +45,8 @@ func TestParseAPIDMMessageWithReaction(t *testing.T) { assert.Equal(message.ID, DMMessageID(1663623062195957773)) require.Len(t, message.Reactions, 1) - reacc := message.Reactions[0] + reacc, is_ok := message.Reactions[UserID(1458284524761075714)] + require.True(t, is_ok) assert.Equal(reacc.ID, DMMessageID(1665914315742781440)) assert.Equal(reacc.SentAt, TimestampFromUnix(1686019898732)) assert.Equal(reacc.DMMessageID, DMMessageID(1663623062195957773)) diff --git a/pkg/scraper/dm_message.go b/pkg/scraper/dm_message.go index cc2d635..3fab350 100644 --- a/pkg/scraper/dm_message.go +++ b/pkg/scraper/dm_message.go @@ -27,7 +27,7 @@ type DMMessage struct { RequestID string `db:"request_id"` Text string `db:"text"` InReplyToID DMMessageID `db:"in_reply_to_id"` - Reactions []DMReaction + Reactions map[UserID]DMReaction } func ParseAPIDMMessage(message APIDMMessage) DMMessage { @@ -40,11 +40,11 @@ func ParseAPIDMMessage(message APIDMMessage) DMMessage { ret.InReplyToID = DMMessageID(message.MessageData.ReplyData.ID) // Will be "0" if not a reply - ret.Reactions = []DMReaction{} + ret.Reactions = make(map[UserID]DMReaction) for _, api_reacc := range message.MessageReactions { reacc := ParseAPIDMReaction(api_reacc) reacc.DMMessageID = ret.ID - ret.Reactions = append(ret.Reactions, reacc) + ret.Reactions[reacc.SenderID] = reacc } return ret }