From 1317939dec9ab389842dec0cb7623b9aac1ae747 Mon Sep 17 00:00:00 2001 From: Denis Arh Date: Fri, 8 Jan 2021 10:47:53 +0100 Subject: [PATCH] Fix messaging attachment loading --- messaging/service/message.go | 32 ++++++----- messaging/types/attachment.go | 11 ++-- messaging/types/sets.go | 10 ++++ messaging/types/type_set.gen.go | 35 ++++++++++++ messaging/types/type_set.gen_test.go | 56 +++++++++++++++++++ messaging/types/types.yaml | 2 + store/messaging_attachments.yaml | 3 +- store/messaging_message_attachments.gen.go | 6 ++ store/messaging_message_attachments.yaml | 5 +- store/rdbms/messaging_attachments.gen.go | 19 +------ store/rdbms/messaging_attachments.go | 7 +-- .../messaging_message_attachments.gen.go | 21 ++++++- store/rdbms/messaging_message_attachments.go | 16 ++++++ 13 files changed, 180 insertions(+), 43 deletions(-) create mode 100644 store/rdbms/messaging_message_attachments.go diff --git a/messaging/service/message.go b/messaging/service/message.go index 9a23bbbf3..3d9e61886 100644 --- a/messaging/service/message.go +++ b/messaging/service/message.go @@ -681,27 +681,33 @@ func (message) preloadMentions(ctx context.Context, s store.Storer, mm types.Mes func (message) preloadAttachments(ctx context.Context, s store.Storer, mm types.MessageSet) (err error) { var ( - aa types.AttachmentSet + aa types.AttachmentSet + mma types.MessageAttachmentSet ) if err != nil || len(mm) == 0 { return } - if aa, _, err = store.SearchMessagingAttachments(ctx, s, types.AttachmentFilter{MessageID: mm.IDs()}); err != nil { + // clumsy way to make a many-to-many join + // @todo make a specialized function in store + if mma, _, err = store.SearchMessagingMessageAttachments(ctx, s, types.MessageAttachmentFilter{MessageID: mm.IDs()}); err != nil { + return + } else if aa, _, err = store.SearchMessagingAttachments(ctx, s, types.AttachmentFilter{AttachmentID: mma.AttachmentIDs()}); err != nil { return } else { - _ = aa - //return aa.Walk(func(a *types.Attachment) error { - // if a.MessageID > 0 { - // if m := mm.FindByID(a.MessageID); m != nil { - // m.Attachment = &a.Attachment - // } - // } - // - // return nil - //}) - return + return mma.Walk(func(mma *types.MessageAttachment) error { + var ( + msg = mm.FindByID(mma.MessageID) + att = aa.FindByID(mma.AttachmentID) + ) + + if msg != nil && att != nil { + msg.Attachment = att + + } + return nil + }) } } diff --git a/messaging/types/attachment.go b/messaging/types/attachment.go index 625611082..a19421a1f 100644 --- a/messaging/types/attachment.go +++ b/messaging/types/attachment.go @@ -28,13 +28,12 @@ type ( // AttachmentFilter is used for filtering and as a return value from Find AttachmentFilter struct { - MessageID []uint64 + AttachmentID []uint64 + } - // Check fn is called by store backend for each resource found function can - // modify the resource and return false if store should not return it - // - // Store then loads additional resources to satisfy the paging parameters - Check func(*Attachment) (bool, error) + // MessageAttachmentFilter is used for filtering and as a return value from Find + MessageAttachmentFilter struct { + MessageID []uint64 } attachmentImageMeta struct { diff --git a/messaging/types/sets.go b/messaging/types/sets.go index 90337533f..f82b05cd9 100644 --- a/messaging/types/sets.go +++ b/messaging/types/sets.go @@ -174,3 +174,13 @@ func (set UnreadSet) FindByThreadId(threadID uint64) *Unread { return nil } + +func (set MessageAttachmentSet) AttachmentIDs() (IDs []uint64) { + IDs = make([]uint64, len(set)) + + for i := range set { + IDs[i] = set[i].AttachmentID + } + + return +} diff --git a/messaging/types/type_set.gen.go b/messaging/types/type_set.gen.go index 498699193..1c69b9be4 100644 --- a/messaging/types/type_set.gen.go +++ b/messaging/types/type_set.gen.go @@ -45,6 +45,11 @@ type ( // This type is auto-generated. MessageSet []*Message + // MessageAttachmentSet slice of MessageAttachment + // + // This type is auto-generated. + MessageAttachmentSet []*MessageAttachment + // MessageFlagSet slice of MessageFlag // // This type is auto-generated. @@ -370,6 +375,36 @@ func (set MessageSet) IDs() (IDs []uint64) { return } +// Walk iterates through every slice item and calls w(MessageAttachment) err +// +// This function is auto-generated. +func (set MessageAttachmentSet) Walk(w func(*MessageAttachment) error) (err error) { + for i := range set { + if err = w(set[i]); err != nil { + return + } + } + + return +} + +// Filter iterates through every slice item, calls f(MessageAttachment) (bool, err) and return filtered slice +// +// This function is auto-generated. +func (set MessageAttachmentSet) Filter(f func(*MessageAttachment) (bool, error)) (out MessageAttachmentSet, err error) { + var ok bool + out = MessageAttachmentSet{} + for i := range set { + if ok, err = f(set[i]); err != nil { + return + } else if ok { + out = append(out, set[i]) + } + } + + return +} + // Walk iterates through every slice item and calls w(MessageFlag) err // // This function is auto-generated. diff --git a/messaging/types/type_set.gen_test.go b/messaging/types/type_set.gen_test.go index f096e4b90..6a99807c8 100644 --- a/messaging/types/type_set.gen_test.go +++ b/messaging/types/type_set.gen_test.go @@ -542,6 +542,62 @@ func TestMessageSetIDs(t *testing.T) { } } +func TestMessageAttachmentSetWalk(t *testing.T) { + var ( + value = make(MessageAttachmentSet, 3) + req = require.New(t) + ) + + // check walk with no errors + { + err := value.Walk(func(*MessageAttachment) error { + return nil + }) + req.NoError(err) + } + + // check walk with error + req.Error(value.Walk(func(*MessageAttachment) error { return fmt.Errorf("walk error") })) +} + +func TestMessageAttachmentSetFilter(t *testing.T) { + var ( + value = make(MessageAttachmentSet, 3) + req = require.New(t) + ) + + // filter nothing + { + set, err := value.Filter(func(*MessageAttachment) (bool, error) { + return true, nil + }) + req.NoError(err) + req.Equal(len(set), len(value)) + } + + // filter one item + { + found := false + set, err := value.Filter(func(*MessageAttachment) (bool, error) { + if !found { + found = true + return found, nil + } + return false, nil + }) + req.NoError(err) + req.Len(set, 1) + } + + // filter error + { + _, err := value.Filter(func(*MessageAttachment) (bool, error) { + return false, fmt.Errorf("filter error") + }) + req.Error(err) + } +} + func TestMessageFlagSetWalk(t *testing.T) { var ( value = make(MessageFlagSet, 3) diff --git a/messaging/types/types.yaml b/messaging/types/types.yaml index 93576f5e2..fcd8ef731 100644 --- a/messaging/types/types.yaml +++ b/messaging/types/types.yaml @@ -3,6 +3,8 @@ types: Mention: {} MessageFlag: {} Message: {} + MessageAttachment: + noIdField: true Channel: {} ChannelMember: noIdField: true diff --git a/store/messaging_attachments.yaml b/store/messaging_attachments.yaml index 683260356..1a482ab7b 100644 --- a/store/messaging_attachments.yaml +++ b/store/messaging_attachments.yaml @@ -25,8 +25,9 @@ lookups: search: enableSorting: false enablePaging: false + enableFilterCheckFunction: false + customFilterConverter: true rdbms: alias: att table: messaging_attachment - customFilterConverter: true diff --git a/store/messaging_message_attachments.gen.go b/store/messaging_message_attachments.gen.go index bc3ebd3cd..9dcb0f826 100644 --- a/store/messaging_message_attachments.gen.go +++ b/store/messaging_message_attachments.gen.go @@ -15,6 +15,7 @@ import ( type ( MessagingMessageAttachments interface { + SearchMessagingMessageAttachments(ctx context.Context, f types.MessageAttachmentFilter) (types.MessageAttachmentSet, types.MessageAttachmentFilter, error) LookupMessagingMessageAttachmentByMessageID(ctx context.Context, message_id uint64) (*types.MessageAttachment, error) CreateMessagingMessageAttachment(ctx context.Context, rr ...*types.MessageAttachment) error @@ -33,6 +34,11 @@ type ( var _ *types.MessageAttachment var _ context.Context +// SearchMessagingMessageAttachments returns all matching MessagingMessageAttachments from store +func SearchMessagingMessageAttachments(ctx context.Context, s MessagingMessageAttachments, f types.MessageAttachmentFilter) (types.MessageAttachmentSet, types.MessageAttachmentFilter, error) { + return s.SearchMessagingMessageAttachments(ctx, f) +} + // LookupMessagingMessageAttachmentByMessageID searches for message attachment by message ID func LookupMessagingMessageAttachmentByMessageID(ctx context.Context, s MessagingMessageAttachments, message_id uint64) (*types.MessageAttachment, error) { return s.LookupMessagingMessageAttachmentByMessageID(ctx, message_id) diff --git a/store/messaging_message_attachments.yaml b/store/messaging_message_attachments.yaml index 0309b47a1..a346ea19b 100644 --- a/store/messaging_message_attachments.yaml +++ b/store/messaging_message_attachments.yaml @@ -14,7 +14,10 @@ lookups: searches for message attachment by message ID search: - enable: false + enableSorting: false + enablePaging: false + enableFilterCheckFunction: false + customFilterConverter: true rdbms: alias: mma diff --git a/store/rdbms/messaging_attachments.gen.go b/store/rdbms/messaging_attachments.gen.go index abda14d8c..51b235d89 100644 --- a/store/rdbms/messaging_attachments.gen.go +++ b/store/rdbms/messaging_attachments.gen.go @@ -31,12 +31,9 @@ func (s Store) SearchMessagingAttachments(ctx context.Context, f types.Attachmen ) return set, f, func() error { - q, err = s.convertMessagingAttachmentFilter(f) - if err != nil { - return err - } + q = s.messagingAttachmentsSelectBuilder() - set, err = s.QueryMessagingAttachments(ctx, q, f.Check) + set, err = s.QueryMessagingAttachments(ctx, q, nil) return err }() } @@ -73,16 +70,6 @@ func (s Store) QueryMessagingAttachments( return nil, err } - // check fn set, call it and see if it passed the test - // if not, skip the item - if check != nil { - if chk, err := check(res); err != nil { - return nil, err - } else if !chk { - continue - } - } - set = append(set, res) } @@ -305,7 +292,7 @@ func (Store) messagingAttachmentColumns(aa ...string) []string { } } -// {true true false false false true} +// {true true false false false false} // internalMessagingAttachmentEncoder encodes fields from types.Attachment to store.Payload (map) // diff --git a/store/rdbms/messaging_attachments.go b/store/rdbms/messaging_attachments.go index 6f9850126..f0de55d1d 100644 --- a/store/rdbms/messaging_attachments.go +++ b/store/rdbms/messaging_attachments.go @@ -8,12 +8,9 @@ import ( func (s Store) convertMessagingAttachmentFilter(f types.AttachmentFilter) (query squirrel.SelectBuilder, err error) { query = s.messagingAttachmentsSelectBuilder() - if len(f.MessageID) > 0 { - //query = query.Where(squirrel.Eq{"att.id": f.MessageID}) - + if len(f.AttachmentID) > 0 { + query = query.Where(squirrel.Eq{"att.id": f.AttachmentID}) } - // @todo join & filter by message - return } diff --git a/store/rdbms/messaging_message_attachments.gen.go b/store/rdbms/messaging_message_attachments.gen.go index 81b7986fc..dd176ac99 100644 --- a/store/rdbms/messaging_message_attachments.gen.go +++ b/store/rdbms/messaging_message_attachments.gen.go @@ -19,6 +19,25 @@ import ( var _ = errors.Is +// SearchMessagingMessageAttachments returns all matching rows +// +// This function calls convertMessagingMessageAttachmentFilter with the given +// types.MessageAttachmentFilter and expects to receive a working squirrel.SelectBuilder +func (s Store) SearchMessagingMessageAttachments(ctx context.Context, f types.MessageAttachmentFilter) (types.MessageAttachmentSet, types.MessageAttachmentFilter, error) { + var ( + err error + set []*types.MessageAttachment + q squirrel.SelectBuilder + ) + + return set, f, func() error { + q = s.messagingMessageAttachmentsSelectBuilder() + + set, err = s.QueryMessagingMessageAttachments(ctx, q, nil) + return err + }() +} + // QueryMessagingMessageAttachments queries the database, converts and checks each row and // returns collected set // @@ -257,7 +276,7 @@ func (Store) messagingMessageAttachmentColumns(aa ...string) []string { } } -// {false true false false false false} +// {true true false false false false} // internalMessagingMessageAttachmentEncoder encodes fields from types.MessageAttachment to store.Payload (map) // diff --git a/store/rdbms/messaging_message_attachments.go b/store/rdbms/messaging_message_attachments.go new file mode 100644 index 000000000..ac5132721 --- /dev/null +++ b/store/rdbms/messaging_message_attachments.go @@ -0,0 +1,16 @@ +package rdbms + +import ( + "github.com/Masterminds/squirrel" + "github.com/cortezaproject/corteza-server/messaging/types" +) + +func (s Store) convertMessagingMessageAttachmentFilter(f types.MessageAttachmentFilter) (query squirrel.SelectBuilder, err error) { + query = s.messagingMessageAttachmentsSelectBuilder() + + if len(f.MessageID) > 0 { + query = query.Where(squirrel.Eq{"mma.rel_message": f.MessageID}) + } + + return +}