Bezig met crudmodel/tab
This commit is contained in:
parent
ee321b3fb1
commit
14ab400ccb
15 changed files with 308 additions and 33 deletions
|
|
@ -26,12 +26,15 @@ enum class RelKind {
|
|||
|
||||
void operator<<(RelKind &s, const Pgsql::Value &v);
|
||||
|
||||
|
||||
class PgClass {
|
||||
public:
|
||||
|
||||
Oid oid = InvalidOid;
|
||||
QString name;
|
||||
Oid relnamespace = InvalidOid;
|
||||
QString relnamespace_name; // Transient, cached value from relnamespace
|
||||
bool system_namespace = false; // Transient, cached value from relnamespace
|
||||
Oid type = InvalidOid;
|
||||
Oid oftype = InvalidOid;
|
||||
Oid owner = InvalidOid;
|
||||
|
|
@ -56,6 +59,7 @@ public:
|
|||
bool operator<(Oid _oid) const { return oid < _oid; }
|
||||
bool operator<(const PgClass &rhs) const { return oid < rhs.oid; }
|
||||
|
||||
private:
|
||||
};
|
||||
|
||||
#endif // PGCLASS_H
|
||||
|
|
|
|||
|
|
@ -1,6 +1,8 @@
|
|||
#include "PgClassContainer.h"
|
||||
#include "Pgsql_Connection.h"
|
||||
#include "Pgsql_Col.h"
|
||||
#include "PgDatabaseCatalog.h"
|
||||
#include "PgNamespaceContainer.h"
|
||||
|
||||
std::string PgClassContainer::getLoadQuery() const
|
||||
{
|
||||
|
|
@ -21,5 +23,10 @@ PgClass PgClassContainer::loadElem(const Pgsql::Row &row)
|
|||
>> v.tuples_est >> v.toastrelid >> v.isshared >> v.persistence
|
||||
>> v.kind >> v.hasoids >> v.ispopulated >> v.frozenxid >> v.minmxid
|
||||
>> v.acl >> v.options;
|
||||
|
||||
auto cat = m_catalogue.lock();
|
||||
auto ns = cat->namespaces()->getByKey(v.relnamespace);
|
||||
v.relnamespace_name = ns.name;
|
||||
v.system_namespace = ns.isSystemCatalog();
|
||||
return v;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -72,3 +72,15 @@ std::vector<PgConstraint> PgConstraintContainer::getConstraintsForRelation(Oid r
|
|||
result.push_back(e);
|
||||
return result;
|
||||
}
|
||||
|
||||
boost::optional<PgConstraint> PgConstraintContainer::getPrimaryForRelation(Oid relid) const
|
||||
{
|
||||
boost::optional<PgConstraint> result;
|
||||
for (const auto &e : m_container) {
|
||||
if (e.relid == relid && e.type == ConstraintType::PrimaryKey) {
|
||||
result = e;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@
|
|||
#include "PgConstraint.h"
|
||||
#include "Pgsql_declare.h"
|
||||
#include <vector>
|
||||
#include <boost/optional.hpp>
|
||||
|
||||
class PgConstraintContainer : public PgContainer<PgConstraint> {
|
||||
public:
|
||||
|
|
@ -15,6 +16,7 @@ public:
|
|||
const PgConstraint* getFKeyForTableColumn(Oid relid, int16_t attnum) const;
|
||||
|
||||
std::vector<PgConstraint> getConstraintsForRelation(Oid relid) const;
|
||||
boost::optional<PgConstraint> getPrimaryForRelation(Oid relid) const;
|
||||
protected:
|
||||
virtual PgConstraint loadElem(const Pgsql::Row &row) override;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -101,4 +101,89 @@ private:
|
|||
|
||||
};
|
||||
|
||||
|
||||
template<typename T, typename K=Oid>
|
||||
class PgSPtrContainer: public IPgContainter {
|
||||
public:
|
||||
using t_Elem = std::shared_ptr<T>;
|
||||
using t_Container = std::vector<t_Elem>; ///< Do not assume it will stay a vector only expect bidirectional access
|
||||
|
||||
explicit PgSPtrContainer(std::weak_ptr<PgDatabaseCatalog> 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_Elem 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_Elem getByName(const QString name) const
|
||||
{
|
||||
auto find_res = std::find_if(m_container.begin(), m_container.end(),
|
||||
[name](auto e) -> bool { return *e = name; } );
|
||||
|
||||
if (find_res != m_container.end())
|
||||
return *find_res;
|
||||
|
||||
return m_invalidInstance;
|
||||
}
|
||||
|
||||
const t_Elem 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<PgDatabaseCatalog> 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_Elem loadElem(const Pgsql::Row &) = 0;
|
||||
private:
|
||||
|
||||
};
|
||||
|
||||
|
||||
#endif // PGCONTAINER_H
|
||||
|
|
|
|||
|
|
@ -121,31 +121,32 @@ void PgDatabaseCatalog::loadAll(Pgsql::Connection &conn,
|
|||
std::function<bool(int, int)> progress_callback)
|
||||
{
|
||||
loadInfo(conn);
|
||||
if (progress_callback && !progress_callback(1, 9))
|
||||
return;
|
||||
load2(m_attributes, conn);
|
||||
if (progress_callback && !progress_callback(2, 9))
|
||||
return;
|
||||
load2(m_authIds, conn);
|
||||
if (progress_callback && !progress_callback(3, 9))
|
||||
return;
|
||||
load2(m_classes, conn);
|
||||
if (progress_callback && !progress_callback(4, 9))
|
||||
return;
|
||||
load2(m_constraints, conn);
|
||||
if (progress_callback && !progress_callback(5, 9))
|
||||
return;
|
||||
load2(m_databases, conn);
|
||||
if (progress_callback && !progress_callback(6, 9))
|
||||
return;
|
||||
load2(m_indexes, conn);
|
||||
if (progress_callback && !progress_callback(7, 9))
|
||||
int n = 0;
|
||||
if (progress_callback && !progress_callback(++n, 9))
|
||||
return;
|
||||
load2(m_namespaces, conn);
|
||||
if (progress_callback && !progress_callback(8, 9))
|
||||
if (progress_callback && !progress_callback(++n, 9))
|
||||
return;
|
||||
load2(m_classes, conn); // needs namespaces
|
||||
if (progress_callback && !progress_callback(++n, 9))
|
||||
return;
|
||||
load2(m_attributes, conn);
|
||||
if (progress_callback && !progress_callback(++n, 9))
|
||||
return;
|
||||
load2(m_authIds, conn);
|
||||
if (progress_callback && !progress_callback(++n, 9))
|
||||
return;
|
||||
load2(m_constraints, conn);
|
||||
if (progress_callback && !progress_callback(++n, 9))
|
||||
return;
|
||||
load2(m_databases, conn);
|
||||
if (progress_callback && !progress_callback(++n, 9))
|
||||
return;
|
||||
load2(m_indexes, conn);
|
||||
if (progress_callback && !progress_callback(++n, 9))
|
||||
return;
|
||||
load2(m_types, conn);
|
||||
progress_callback && progress_callback(9, 9);
|
||||
progress_callback && progress_callback(++n, 9);
|
||||
}
|
||||
|
||||
void PgDatabaseCatalog::loadInfo(Pgsql::Connection &conn)
|
||||
|
|
@ -167,7 +168,7 @@ void load(Pgsql::Connection &conn, IPgContainter &pg_cont)
|
|||
std::string q = pg_cont.getLoadQuery();
|
||||
Pgsql::Result result = conn.query(q.c_str());
|
||||
if (result && result.resultStatus() == PGRES_TUPLES_OK) {
|
||||
boost::timer::auto_cpu_timer t;
|
||||
//boost::timer::auto_cpu_timer t;
|
||||
pg_cont.load(result);
|
||||
}
|
||||
else {
|
||||
|
|
|
|||
|
|
@ -4,9 +4,6 @@ PgNamespace::PgNamespace() = default;
|
|||
|
||||
bool PgNamespace::isSystemCatalog() const
|
||||
{
|
||||
return name == "pg_catalog"
|
||||
|| name == "pg_toast"
|
||||
|| name == "pg_temp_1"
|
||||
|| name == "pg_toast_temp_1"
|
||||
return name.startsWith("pg_")
|
||||
|| name == "information_schema";
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue