#ifndef PGCONTAINER_H #define PGCONTAINER_H #include "Pgsql_declare.h" #include "Pgsql_Result.h" #include #include #include #include class PgDatabaseCatalog; class IPgContainter { public: virtual ~IPgContainter() = default; virtual std::string getLoadQuery() const = 0; virtual void load(const Pgsql::Result &res) = 0; }; template class PgContainer: public IPgContainter { public: using t_Container = std::vector; ///< Do not assume it will stay a vector only expect bidirectional access explicit PgContainer(std::weak_ptr cat) : m_catalogue(cat) {} typename t_Container::const_iterator begin() const { return m_container.begin(); } typename t_Container::const_iterator end() const { return m_container.end(); } void clear() { m_container.clear(); } int count() const { return (int)m_container.size(); } const T& getByKey(const K &key) const { auto lb_result = std::lower_bound(m_container.begin(), m_container.end(), key); if (lb_result != m_container.end() && *lb_result == key) return *lb_result; return m_invalidInstance; } const T& getByName(const QString &name) const { auto find_res = std::find(m_container.begin(), m_container.end(), name); if (find_res != m_container.end()) return *find_res; return m_invalidInstance; } const T& getByIdx(int idx) const { return m_container.at(idx); } /** Override to implement complete loading logic. * * Do not override this function if you only want to implement * the loading of a single element. Override loadElem instead. */ virtual void load(const Pgsql::Result &res) override { m_container.clear(); m_container.reserve(res.rows()); for (auto row : res) m_container.push_back(loadElem(row)); std::sort(m_container.begin(), m_container.end()); } protected: std::weak_ptr m_catalogue; t_Container m_container; /** Override the implementation for this function to implement loading of single row. * * When overriding this function there is no need to override load. */ virtual T loadElem(const Pgsql::Row &) { return T(); } private: T m_invalidInstance; }; #endif // PGCONTAINER_H