Program Listing for File library.h

Return to documentation for file (include/library.h)

/*
 * Copyright 2011 Emmanuel Engelhart <kelson@kiwix.org>
 *
 * 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 <string>
#include <vector>
#include <map>
#include <memory>
#include <mutex>
#include <zim/archive.h>
#include <zim/search.h>

#include "book.h"
#include "bookmark.h"
#include "common.h"

#define KIWIX_LIBRARY_VERSION "20110515"

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
};

class Filter {
  public: // types
    using Tags = std::vector<std::string>;

  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;

  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);

    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; }

    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<std::mutex> getLock() {
      return std::unique_lock<std::mutex>(m_mutex);
    }
    virtual ~ZimSearcher() = default;
  private:
    std::mutex m_mutex;
};

class Library
{
  // all data fields must be added in LibraryBase
  mutable std::mutex m_mutex;

 public:
  typedef uint64_t Revision;
  typedef std::vector<std::string> BookIdCollection;
  typedef std::map<std::string, int> AttributeCounts;
  typedef std::set<std::string> BookIdSet;

 public:
  Library();
  ~Library();

  Library(const Library& ) = delete;
  Library(Library&& );
  void operator=(const Library& ) = delete;
  Library& operator=(Library&& );

  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);

  // 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<zim::Archive> getArchiveById(const std::string& id);
  std::shared_ptr<ZimSearcher> getSearcherById(const std::string& id) {
    return getSearcherByIds(BookIdSet{id});
  }
  std::shared_ptr<ZimSearcher> 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<std::string> getBooksLanguages() const;

  AttributeCounts getBooksLanguagesWithCounts() const;

  std::vector<std::string> getBooksCategories() const;

  std::vector<std::string> getBooksCreators() const;

  std::vector<std::string> getBooksPublishers() const;

  const std::vector<kiwix::Bookmark> 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 Impl;

private: // functions
  AttributeCounts getBookAttributeCounts(BookStrPropMemFn p) const;
  std::vector<std::string> getBookPropValueSet(BookStrPropMemFn p) const;
  BookIdCollection filterViaBookDB(const Filter& filter) const;
  void updateBookDB(const Book& book);
  void dropCache(const std::string& bookId);

private: //data
  std::unique_ptr<Impl> mp_impl;
};

}

#endif