.. _program_listing_file_include_library.h: Program Listing for File library.h ================================== |exhale_lsh| :ref:`Return to documentation for file ` (``include/library.h``) .. |exhale_lsh| unicode:: U+021B0 .. UPWARDS ARROW WITH TIP LEFTWARDS .. code-block:: cpp /* * Copyright 2011 Emmanuel Engelhart * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, * MA 02110-1301, USA. */ #ifndef KIWIX_LIBRARY_H #define KIWIX_LIBRARY_H #include #include #include #include #include #include #include #include "book.h" #include "bookmark.h" #include "common.h" #define KIWIX_LIBRARY_VERSION "20110515" namespace Xapian { class WritableDatabase; }; namespace kiwix { class OPDSDumper; class Library; enum supportedListSortBy { UNSORTED, TITLE, SIZE, DATE, CREATOR, PUBLISHER }; enum supportedListMode { ALL = 0, LOCAL = 1, REMOTE = 1 << 1, NOLOCAL = 1 << 2, NOREMOTE = 1 << 3, VALID = 1 << 4, NOVALID = 1 << 5 }; enum MigrationMode { UPGRADE_ONLY = 0, ALLOW_DOWNGRADE = 1, }; class Filter { public: // types using Tags = std::vector; private: // data uint64_t activeFilters; Tags _acceptTags; Tags _rejectTags; std::string _category; std::string _lang; std::string _publisher; std::string _creator; size_t _maxSize; std::string _query; bool _queryIsPartial; std::string _name; std::string _flavour; public: // functions Filter(); ~Filter() = default; Filter& local(bool accept); Filter& remote(bool accept); Filter& valid(bool accept); Filter& acceptTags(const Tags& tags); Filter& rejectTags(const Tags& tags); Filter& category(std::string category); Filter& lang(std::string lang); Filter& publisher(std::string publisher); Filter& creator(std::string creator); Filter& maxSize(size_t size); Filter& query(std::string query, bool partial=true); Filter& name(std::string name); Filter& flavour(std::string flavour); Filter& clearLang(); Filter& clearCategory(); bool hasQuery() const; const std::string& getQuery() const { return _query; } bool queryIsPartial() const { return _queryIsPartial; } bool hasName() const; const std::string& getName() const { return _name; } bool hasCategory() const; const std::string& getCategory() const { return _category; } bool hasLang() const; const std::string& getLang() const { return _lang; } bool hasPublisher() const; const std::string& getPublisher() const { return _publisher; } bool hasCreator() const; const std::string& getCreator() const { return _creator; } bool hasFlavour() const; const std::string& getFlavour() const { return _flavour; } const Tags& getAcceptTags() const { return _acceptTags; } const Tags& getRejectTags() const { return _rejectTags; } private: // functions friend class Library; bool accept(const Book& book) const; }; class ZimSearcher : public zim::Searcher { public: explicit ZimSearcher(zim::Searcher&& searcher) : zim::Searcher(searcher) {} std::unique_lock getLock() { return std::unique_lock(m_mutex); } virtual ~ZimSearcher() = default; private: std::mutex m_mutex; }; template class ConcurrentCache; template class MultiKeyCache; using LibraryPtr = std::shared_ptr; using ConstLibraryPtr = std::shared_ptr; // Some compiler we use don't have [[nodiscard]] attribute. // We don't want to declare `create` with it in this case. #define LIBKIWIX_NODISCARD #if defined __has_cpp_attribute #if __has_cpp_attribute (nodiscard) #undef LIBKIWIX_NODISCARD #define LIBKIWIX_NODISCARD [[nodiscard]] #endif #endif class Library: public std::enable_shared_from_this { public: typedef uint64_t Revision; typedef std::vector BookIdCollection; typedef std::map AttributeCounts; typedef std::set BookIdSet; private: Library(); public: LIBKIWIX_NODISCARD static LibraryPtr create() { return LibraryPtr(new Library()); } ~Library(); Library(const Library& ) = delete; Library(Library&& ) = delete; void operator=(const Library& ) = delete; Library& operator=(Library&& ) = delete; bool addBook(const Book& book); bool addOrUpdateBook(const Book& book) { return addBook(book); } void addBookmark(const Bookmark& bookmark); bool removeBookmark(const std::string& zimId, const std::string& url); std::tuple migrateBookmarks(MigrationMode migrationMode = ALLOW_DOWNGRADE); int migrateBookmarks(const std::string& sourceBookId, MigrationMode migrationMode = UPGRADE_ONLY); int migrateBookmarks(const std::string& sourceBookId, const std::string& targetBookId); std::string getBestTargetBookId(const Bookmark& bookmark, MigrationMode migrationMode) const; std::string getBestTargetBookId(const std::string& bookName, const std::string& preferedFlavour="", const std::string& minDate="") const; // XXX: This is a non-thread-safe operation const Book& getBookById(const std::string& id) const; // XXX: This is a non-thread-safe operation const Book& getBookByPath(const std::string& path) const; Book getBookByIdThreadSafe(const std::string& id) const; std::shared_ptr getArchiveById(const std::string& id); std::shared_ptr getSearcherById(const std::string& id) { return getSearcherByIds(BookIdSet{id}); } std::shared_ptr getSearcherByIds(const BookIdSet& ids); bool removeBookById(const std::string& id); bool writeToFile(const std::string& path) const; bool writeBookmarksToFile(const std::string& path) const; unsigned int getBookCount(const bool localBooks, const bool remoteBooks) const; std::vector getBooksLanguages() const; AttributeCounts getBooksLanguagesWithCounts() const; std::vector getBooksCategories() const; std::vector getBooksCreators() const; std::vector getBooksPublishers() const; const std::vector getBookmarks(bool onlyValidBookmarks = true) const; BookIdCollection getBooksIds() const; BookIdCollection filter(const Filter& filter) const; void sort(BookIdCollection& bookIds, supportedListSortBy sortBy, bool ascending) const; Revision getRevision() const; uint32_t removeBooksNotUpdatedSince(Revision rev); friend class OPDSDumper; friend class libXMLDumper; private: // types typedef const std::string& (Book::*BookStrPropMemFn)() const; struct Entry : Book { Library::Revision lastUpdatedRevision = 0; }; private: // functions AttributeCounts getBookAttributeCounts(BookStrPropMemFn p) const; std::vector getBookPropValueSet(BookStrPropMemFn p) const; BookIdCollection filterViaBookDB(const Filter& filter) const; std::string getBestFromBookCollection(BookIdCollection books, const Bookmark& bookmark, MigrationMode migrationMode) const; unsigned int getBookCount_not_protected(const bool localBooks, const bool remoteBooks) const; void updateBookDB(const Book& book); void dropCache(const std::string& bookId); private: //data mutable std::recursive_mutex m_mutex; Library::Revision m_revision; std::map m_books; using ArchiveCache = ConcurrentCache>; std::unique_ptr mp_archiveCache; using SearcherCache = MultiKeyCache>; std::unique_ptr mp_searcherCache; std::vector m_bookmarks; std::unique_ptr m_bookDB; }; // We don't need it anymore and we don't want to polute any other potential usage // of `LIBKIWIX_NODISCARD` token. #undef LIBKIWIX_NODISCARD } #endif