diff --git a/pkg/internal/server/api/attachment_dir_api.go b/pkg/internal/server/api/attachment_dir_api.go index 290cb54..a2aa19a 100644 --- a/pkg/internal/server/api/attachment_dir_api.go +++ b/pkg/internal/server/api/attachment_dir_api.go @@ -1,10 +1,12 @@ package api import ( + "strconv" "strings" "git.solsynth.dev/hydrogen/paperclip/pkg/internal/database" "git.solsynth.dev/hydrogen/paperclip/pkg/internal/models" + "git.solsynth.dev/hydrogen/paperclip/pkg/internal/services" "github.com/gofiber/fiber/v2" ) @@ -18,8 +20,26 @@ func listAttachment(c *fiber.Ctx) error { tx := database.C + var result = make([]models.Attachment, take) + var idxList []uint + if len(c.Query("id")) > 0 { - tx = tx.Where("id IN ?", strings.Split(c.Query("id"), ",")) + var pendingQueryId []uint + idx := strings.Split(c.Query("id"), ",") + for p, raw := range idx { + id, err := strconv.Atoi(raw) + if err != nil { + continue + } else { + idxList = append(idxList, uint(id)) + } + if val, ok := services.GetAttachmentCache(uint(id)); ok { + result[p] = val + } else { + pendingQueryId = append(pendingQueryId, uint(id)) + } + } + tx = tx.Where("id IN ?", pendingQueryId) } else { // Do sort this when doesn't filter by the id // Because the sort will mess up the result @@ -44,13 +64,25 @@ func listAttachment(c *fiber.Ctx) error { if err := countTx.Model(&models.Attachment{}).Count(&count).Error; err != nil { return fiber.NewError(fiber.StatusBadRequest, err.Error()) } - var attachments []models.Attachment - if err := tx.Offset(offset).Limit(take).Preload("Account").Find(&attachments).Error; err != nil { + var out []models.Attachment + if err := tx.Offset(offset).Limit(take).Preload("Account").Find(&out).Error; err != nil { return fiber.NewError(fiber.StatusBadRequest, err.Error()) } + if len(idxList) == 0 { + result = out + } else { + for _, item := range out { + for p, id := range idxList { + if item.ID == id { + result[p] = item + } + } + } + } + return c.JSON(fiber.Map{ "count": count, - "data": attachments, + "data": result, }) } diff --git a/pkg/internal/services/attachments.go b/pkg/internal/services/attachments.go index f584fc8..ab13318 100644 --- a/pkg/internal/services/attachments.go +++ b/pkg/internal/services/attachments.go @@ -21,7 +21,7 @@ const metadataCacheLimit = 512 var metadataCache sync.Map func GetAttachmentByID(id uint) (models.Attachment, error) { - if val, ok := metadataCache.Load(id); ok && val.(models.Attachment).AccountID > 0 { + if val, ok := metadataCache.Load(id); ok && val.(models.Attachment).Account.ID > 0 { return val.(models.Attachment), nil } @@ -48,6 +48,13 @@ func GetAttachmentByHash(hash string) (models.Attachment, error) { return attachment, nil } +func GetAttachmentCache(id uint) (models.Attachment, bool) { + if val, ok := metadataCache.Load(id); ok && val.(models.Attachment).Account.ID > 0 { + return val.(models.Attachment), ok + } + return models.Attachment{}, false +} + func NewAttachmentMetadata(tx *gorm.DB, user models.Account, file *multipart.FileHeader, attachment models.Attachment) (models.Attachment, error) { attachment.Uuid = uuid.NewString() attachment.Size = file.Size