BookList.hpp 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172
  1. #pragma once
  2. #include "Book.hpp"
  3. #include "DatabaseManager.hpp"
  4. #include <vector>
  5. #include <string>
  6. #include <optional>
  7. #include <mutex>
  8. #include <sigc++/signal.h>
  9. /**
  10. * @brief Thread-aware, signal-emitting container of @ref Book objects.
  11. *
  12. * BookList keeps an in-memory vector of books in sync with @ref DatabaseManager,
  13. * broadcasts fine-grained signals when the collection changes, and offers
  14. * helper methods that are safe to call from background threads (the *_enqueue
  15. * variants marshal work back onto the main loop).
  16. */
  17. class BookList {
  18. public:
  19. explicit BookList(DatabaseManager& database);
  20. // ---- Loading ----
  21. /// Load all rows from the database, replacing the in-memory vector.
  22. void loadAll();
  23. const std::vector<Book>& getBooks() const noexcept { return m_books; }
  24. std::size_t size() const noexcept { return m_books.size(); }
  25. // ---- CRUD ----
  26. /// Insert or update (by Book::id) and emit the relevant signal.
  27. bool upsert(const Book& book);
  28. /// Remove by id; returns false when the book was not present.
  29. bool removeById(const std::string& id);
  30. std::optional<Book> findById(const std::string& id) const;
  31. int indexOf(const std::string& id) const; // -1 if not found
  32. // ---- Bulk operations ----
  33. bool upsertMany(const std::vector<Book>& items);
  34. // ---- Worker-thread safe enqueue versions ----
  35. void upsertEnqueue(Book book);
  36. void removeByIdEnqueue(std::string id);
  37. void loadAllEnqueue();
  38. // ---- Signals ----
  39. /// Emitted after a new book enters the vector.
  40. sigc::signal<void(const Book&)>& signalBookAdded() { return m_signalBookAdded; }
  41. /// Emitted after a book already present changes.
  42. sigc::signal<void(const Book&)>& signalBookUpdated() { return m_signalBookUpdated; }
  43. /// Emitted after a book is removed from the vector.
  44. sigc::signal<void(const std::string&)>& signalBookRemoved() { return m_signalBookRemoved; }
  45. /// Emitted when the vector is cleared or reloaded wholesale.
  46. sigc::signal<void()>& signalReset() { return m_signalReset; }
  47. /// Emitted after batch operations that significantly mutate the list.
  48. sigc::signal<void()>& signalBulkChanged() { return m_signalBulkChanged; }
  49. private:
  50. DatabaseManager& m_database;
  51. std::vector<Book> m_books;
  52. mutable std::mutex m_mutex;
  53. int indexOfUnlocked(const std::string& id) const;
  54. // ---- Signals ----
  55. sigc::signal<void(const Book&)> m_signalBookAdded;
  56. sigc::signal<void(const Book&)> m_signalBookUpdated;
  57. sigc::signal<void(const std::string&)> m_signalBookRemoved;
  58. sigc::signal<void()> m_signalReset;
  59. sigc::signal<void()> m_signalBulkChanged;
  60. };