enclosure.go 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  1. // Copyright 2017 Frédéric Guillot. All rights reserved.
  2. // Use of this source code is governed by the Apache 2.0
  3. // license that can be found in the LICENSE file.
  4. package storage // import "miniflux.app/storage"
  5. import (
  6. "fmt"
  7. "miniflux.app/model"
  8. )
  9. // GetEnclosures returns all attachments for the given entry.
  10. func (s *Storage) GetEnclosures(entryID int64) (model.EnclosureList, error) {
  11. query := `
  12. SELECT
  13. id,
  14. user_id,
  15. entry_id,
  16. url,
  17. size,
  18. mime_type
  19. FROM
  20. enclosures
  21. WHERE
  22. entry_id = $1
  23. ORDER BY id ASC
  24. `
  25. rows, err := s.db.Query(query, entryID)
  26. if err != nil {
  27. return nil, fmt.Errorf(`store: unable to fetch enclosures: %v`, err)
  28. }
  29. defer rows.Close()
  30. enclosures := make(model.EnclosureList, 0)
  31. for rows.Next() {
  32. var enclosure model.Enclosure
  33. err := rows.Scan(
  34. &enclosure.ID,
  35. &enclosure.UserID,
  36. &enclosure.EntryID,
  37. &enclosure.URL,
  38. &enclosure.Size,
  39. &enclosure.MimeType,
  40. )
  41. if err != nil {
  42. return nil, fmt.Errorf(`store: unable to fetch enclosure row: %v`, err)
  43. }
  44. enclosures = append(enclosures, &enclosure)
  45. }
  46. return enclosures, nil
  47. }
  48. // CreateEnclosure creates a new attachment.
  49. func (s *Storage) CreateEnclosure(enclosure *model.Enclosure) error {
  50. if enclosure.URL == "" {
  51. return nil
  52. }
  53. query := `
  54. INSERT INTO enclosures
  55. (url, size, mime_type, entry_id, user_id)
  56. VALUES
  57. ($1, $2, $3, $4, $5)
  58. RETURNING
  59. id
  60. `
  61. err := s.db.QueryRow(
  62. query,
  63. enclosure.URL,
  64. enclosure.Size,
  65. enclosure.MimeType,
  66. enclosure.EntryID,
  67. enclosure.UserID,
  68. ).Scan(&enclosure.ID)
  69. if err != nil {
  70. return fmt.Errorf(`store: unable to create enclosure %q: %v`, enclosure.URL, err)
  71. }
  72. return nil
  73. }
  74. // IsEnclosureExists checks if an attachment exists.
  75. func (s *Storage) IsEnclosureExists(enclosure *model.Enclosure) bool {
  76. var result int
  77. query := `SELECT 1 FROM enclosures WHERE user_id=$1 AND entry_id=$2 AND url=$3`
  78. s.db.QueryRow(query, enclosure.UserID, enclosure.EntryID, enclosure.URL).Scan(&result)
  79. return result >= 1
  80. }
  81. // UpdateEnclosures add missing attachments while updating a feed.
  82. func (s *Storage) UpdateEnclosures(enclosures model.EnclosureList) error {
  83. for _, enclosure := range enclosures {
  84. if !s.IsEnclosureExists(enclosure) {
  85. err := s.CreateEnclosure(enclosure)
  86. if err != nil {
  87. return err
  88. }
  89. }
  90. }
  91. return nil
  92. }