Improve CrudModel code quality
This commit is contained in:
parent
82cc9f14bc
commit
550049ceff
6 changed files with 870 additions and 205 deletions
|
|
@ -60,11 +60,10 @@ signals:
|
|||
/// Emitted when the model goes from clean to having pending changes or back
|
||||
void pendingChangesChanged(bool hasChanges);
|
||||
|
||||
public slots:
|
||||
|
||||
private:
|
||||
|
||||
const int PreColumnCount = 1;
|
||||
/// Number of grid columns in front of the result columns (the row number column)
|
||||
static constexpr int PreColumnCount = 1;
|
||||
|
||||
|
||||
class ColumnSort {
|
||||
|
|
@ -125,17 +124,6 @@ private:
|
|||
public:
|
||||
using Map = std::map<int, PendingRow>;
|
||||
|
||||
PendingRow& getRow(int row)
|
||||
{
|
||||
auto iter = m_rows.lower_bound(row);
|
||||
if (iter != m_rows.end() && iter->first == row) {
|
||||
return iter->second;
|
||||
}
|
||||
else {
|
||||
return m_rows.insert(iter, {row, PendingRow(row)})->second;
|
||||
}
|
||||
}
|
||||
|
||||
void setValue(int col, int row, const Value &value)
|
||||
{
|
||||
auto iter = m_rows.find(row);
|
||||
|
|
@ -226,13 +214,7 @@ private:
|
|||
|
||||
std::shared_ptr<Pgsql::Result> m_roData;
|
||||
|
||||
struct ColumnData
|
||||
{
|
||||
std::string name;
|
||||
// identity allways or generated
|
||||
};
|
||||
|
||||
std::vector<std::optional<PgAttribute>> columnList; // attribute per column in m_roData, empty for expression columns
|
||||
std::vector<std::optional<PgAttribute>> m_columnList; // attribute per column in m_roData, empty for expression columns
|
||||
|
||||
PendingRowList m_pendingRowList;
|
||||
|
||||
|
|
@ -242,47 +224,64 @@ private:
|
|||
/// call on initial load to fill in the mappings
|
||||
void initRowMapping();
|
||||
|
||||
/// Value as shown in the grid, pending edits take precedence over saved data
|
||||
Value getLatestData(int column, int row) const;
|
||||
Value getLatestData(const QModelIndex &index) const
|
||||
{
|
||||
return getLatestData(index.column() - PreColumnCount, index.row());
|
||||
}
|
||||
Value getSavedData(int columnIndex, int rowIndex) const;
|
||||
/// Value as last loaded from or saved to the database
|
||||
Value getSavedData(const RowMapping &row_mapping, int columnIndex) const;
|
||||
|
||||
/// Mapping of the row with the given key, nullptr when the row is not in the grid (anymore)
|
||||
RowMapping* findRowMapping(int rowKey);
|
||||
/// Call after changing the pending rows to emit pendingChangesChanged when the state toggled
|
||||
void updatePendingState(bool was_dirty);
|
||||
|
||||
Oid getType(int column) const;
|
||||
|
||||
|
||||
/// Get the PKey values from when the row was last restored or retrieved.
|
||||
Pgsql::Params getPKeyParamsForRow(const RowMapping &row_mapping, Oid table_oid) const;
|
||||
// ---- Saving, all of these only use the data of the pending row and the row mapping
|
||||
|
||||
bool savePendingChanges();
|
||||
/// Inserts the row when it is new otherwise updates it. Returns the values of the row as stored in the database.
|
||||
std::tuple<bool, std::vector<Value>> saveRow(const PendingRow &pending_row, const RowMapping &row_mapping);
|
||||
std::tuple<bool, std::vector<Value>> saveUpdate(const PendingRow &pending_row, const RowMapping &row_mapping);
|
||||
|
||||
std::tuple<QString, Pgsql::Params> createUpdateQuery(Oid table_oid, const PendingRow &pending_row, const RowMapping &row_mapping);
|
||||
/// Get the PKey values from when the row was last restored or retrieved.
|
||||
Pgsql::Params getPKeyParamsForRow(const RowMapping &row_mapping, Oid table_oid) const;
|
||||
std::tuple<QString, Pgsql::Params> createUpdateQuery(Oid table_oid, const PendingRow &pending_row, const RowMapping &row_mapping);
|
||||
std::tuple<QString, Pgsql::Params> createInsertQuery(const PendingRow &pending_row);
|
||||
|
||||
QString createDeleteStatement() const;
|
||||
std::tuple<bool, std::vector<Value>> saveRow(const PendingRow &pending_row, const RowMapping &row_mapping);
|
||||
std::tuple<bool, std::vector<Value>> saveUpdate(const PendingRow &pending_row, const RowMapping &row_mapping);
|
||||
|
||||
/// Opens a separate connection for writing so edits don't interfere with the loading connection
|
||||
void connectForUpdate(Pgsql::Connection &connection) const;
|
||||
/// Tells the user about a failed write, the one place where the model shows a dialog
|
||||
void reportError(const QString &message) const;
|
||||
static std::vector<Value> rowValues(const Pgsql::Row &row);
|
||||
|
||||
// ---- Rows
|
||||
|
||||
void appendNewRow();
|
||||
void appendNewRowInternal();
|
||||
void appendNewRowInternal();
|
||||
|
||||
int lastRowKey = -1;
|
||||
int lastRowKey = -1;
|
||||
int allocNewRowKey() { return ++lastRowKey; }
|
||||
|
||||
/// Deletes the rows from the database in one transaction, throws on failure
|
||||
void deleteRowsFromDatabase(const std::set<IntegerRange<int>> &row_ranges);
|
||||
/// Removes the rows from the grid and drops their pending edits
|
||||
void removeRangesFromModel(const std::set<IntegerRange<int>> &row_ranges);
|
||||
void removeRangeFromModel(IntegerRange<int> row_range);
|
||||
|
||||
// ---- Table and column information
|
||||
|
||||
/// Name of the table with the given oid, quoted and schema qualified
|
||||
QString tableName(Oid table_oid) const;
|
||||
/// Result columns that are user columns (attnum > 0) of the given table, in result order
|
||||
std::vector<int> resultColumnsOfTable(Oid table_oid) const;
|
||||
/// Catalog name of the attribute behind a result column, falls back to the result column name
|
||||
QString attributeName(int col) const;
|
||||
bool columnIsReadOnly(int column_index) const;
|
||||
void initializeColumnList();
|
||||
|
||||
void RemoveRangesOfRowsFromModel(const std::set<IntegerRange<int>> &row_ranges);
|
||||
void RemoveRangeOfRowsFromModel(IntegerRange<int> row_range);
|
||||
|
||||
bool IsLastRow(RowMappingVector::iterator mapping_iter) const;
|
||||
bool columnIsReadOnly(int column_index) const;
|
||||
void initializeColumnList();
|
||||
private slots:
|
||||
|
||||
void loadIntoModel(std::shared_ptr<Pgsql::Result> data);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue