#include "ColumnTableModel.h" #include "PgDatabaseCatalog.h" #include "PgAttribute.h" #include "PgAttributeContainer.h" #include "PgType.h" #include "PgTypeContainer.h" #include "PgIndexContainer.h" #include "ScopeGuard.h" #include void ColumnTableModel::setData(std::shared_ptr cat, Oid table_oid) { beginResetModel(); SCOPE_EXIT { endResetModel(); }; m_catalog = cat; m_columns = cat->attributes()->getColumnsForRelation(table_oid); // hide system columns m_columns.erase(std::remove_if(m_columns.begin(), m_columns.end(), [](auto &e) { return e.num <= 0; } ), m_columns.end()); // sort remaining columns by order in table std::sort(m_columns.begin(), m_columns.end(), [] (auto &l, auto &r) -> bool { return l.num < r.num; }); m_indexes = m_catalog->indexes()->getIndexesForTable(table_oid); std::sort(m_indexes.begin(), m_indexes.end(), [] (const auto &l, const auto &r) -> bool { return l.isprimary > r.isprimary || (l.isprimary == r.isprimary && l.indexrelid < r.indexrelid); }); } QVariant ColumnTableModel::headerData(int section, Qt::Orientation orientation, int role) const { QVariant v; if (orientation == Qt::Horizontal) { if (role == Qt::DisplayRole) { QString c; if (section >= colCount) { const auto &tbl_idx = m_indexes[section - colCount]; if (tbl_idx.isprimary) c = "Pri"; else if (tbl_idx.isunique) c = "Unq"; else c = "Idx"; } else { switch (section) { case NameCol: c = tr("Name"); break; case TypeCol: c = tr("Type"); break; case NullCol: c = tr("Nullable"); break; case DefaultCol: c = tr("Default"); break; case CollationCol: c = tr("Collation"); break; } } v = c; } } return v; } int ColumnTableModel::rowCount(const QModelIndex &/*parent*/) const { return m_columns.size(); } int ColumnTableModel::columnCount(const QModelIndex &/*parent*/) const { return colCount + m_indexes.size(); } Oid ColumnTableModel::getType(int /*column*/) const { Oid oid = Pgsql::VARCHAROID; // switch (column) { // case TypeCol: // case NameCol: // case NullCol: // case DefaultCol: // case CollationCol: // oid = VARCHAROID; // break; // c = tr("Collation"); // break; // } return oid; } QVariant ColumnTableModel::getData(const QModelIndex &index) const { QVariant v; const int row = index.row(); const auto &t = m_columns[row]; const int col = index.column(); if (col >= colCount) { const auto &tbl_idx = m_indexes[col - colCount]; int i = 1; for (auto attr : tbl_idx.key) { if (attr == t.num) { v = i; break; } ++i; } } else { QString s; switch (col) { case NameCol: s = t.name; break; case TypeCol: s = getTypeDisplayString(*m_catalog, t.typid); break; case NullCol: s = t.notnull ? "NOT NULL" : ""; break; case DefaultCol: s = ""; break; case CollationCol: s = ""; //t.collation; break; } v = s; } return v; } QVariant ColumnTableModel::data(const QModelIndex &index, int role) const { if (role == Qt::ForegroundRole && index.column() == TypeCol) { QVariant v; const auto &t = m_columns[index.row()]; auto c = m_catalog->types()->getByKey(t.typid); switch (c.category) { case TypCategory::Boolean: v = QBrush(Qt::darkGreen); break; case TypCategory::Numeric: v = QBrush(Qt::darkBlue); break; case TypCategory::DateTime: case TypCategory::Timespan: v = QBrush(Qt::darkMagenta); break; case TypCategory::String: v = QBrush(Qt::darkYellow); break; case TypCategory::Array: case TypCategory::Composite: case TypCategory::Enum: case TypCategory::Geometric: case TypCategory::NetworkAddress: case TypCategory::Pseudo: case TypCategory::Range: case TypCategory::UserDefined: case TypCategory::BitString: case TypCategory::Unknown: default: v = QBrush(Qt::black); } return v; } return BaseTableModel::data(index, role); }