EHM DAL 0.2.3
Data abstraction layer for Eastside Hockey Manager
Loading...
Searching...
No Matches
game_child_table.h
1#pragma once
2
3// Application headers
4#include "include/column_data/column_data.h"
5#include "include/tables/game_table.h"
6
7// Qt headers
8#include <QDataStream>
9
10namespace ehm_dal::tables {
16template<class T_ChildAbstractTableItem,
17 class T_ParentAbstractTableItem,
18 class T_ColumnData = ehm_dal::column_data::ColumnData>
19class GameChildTable : public GameTable<T_ChildAbstractTableItem, T_ColumnData>
20{
21public:
22 GameChildTable(const QString &table_name,
23 const ehm_dal::tables::TableIndex table_id,
24 const TableType table_type);
25
26 // File i/o
27 bool readStream(QDataStream &in) override;
28
29 // Get data
30 QVariant data(const QModelIndex &index, qint32 role = Qt::DisplayRole) const override;
31
32 // Get data - counts
33 qint32 rowCount(const QModelIndex &parent = QModelIndex()) const override;
34
35 // Parent table - attributes
36 std::shared_ptr<ehm_dal::tables::AbstractTable> parentTable() const override
37 {
38 return parent_table_;
39 }
40 ehm_dal::tables::AbstractTable::ParentTableRelationshipType parentTableRelationship()
41 const override
42 {
43 return parent_table_relationship_;
44 }
45 void setParentTable(
46 const std::shared_ptr<ehm_dal::tables::AbstractTable> parent_table,
47 const ehm_dal::tables::AbstractTable::ParentTableRelationshipType relationship) override
48 {
49 parent_table_ = std::move(parent_table);
50 parent_table_relationship_ = std::move(relationship);
51 }
52
53 // Set data
54 bool setData(const QModelIndex &index,
55 const QVariant &value,
56 qint32 role = Qt::EditRole) override;
57
58 // Table model type
59 inline QString modelName() const override { return QStringLiteral("Game child table"); }
60 inline constexpr AbstractBaseModel::AbstractTableModelType modelType() const override
61 {
62 return AbstractBaseModel::AbstractTableModelType::GameChildTable;
63 }
64
65protected:
66 // Parent table
67 std::shared_ptr<ehm_dal::tables::AbstractTable> parent_table_;
68 ehm_dal::tables::AbstractTable::ParentTableRelationshipType parent_table_relationship_{
69 ehm_dal::tables::AbstractTable::ParentTableRelationshipType::ParentTableHasChildIdField};
70
71 // Parent table - transfer
72 bool transferChildDataToParent();
73
74 enum ENUM_FLAGS { NO_PARENT = 0, CHILD_INDEX_PARENT_ROW_MODIFIER = 1 };
75
76 // Modified columns
77 virtual bool emitModifiedColumns(const qint32 row,
78 const std::vector<qint32> &modified_columns,
79 const QModelIndex &parent,
80 const QList<qint32> &modified_roles = QList<qint32>())
81 {
82 for (const auto &itr : modified_columns) {
83 const auto parent_index{this->index(parent.row(), 0, QModelIndex())};
84 const auto modified_index{this->index(row, itr, parent_index)};
85
86 emit this->dataChanged(modified_index, modified_index, modified_roles);
87 }
88
89 return !modified_columns.empty();
90 }
91};
92
93/* ========================= */
94/* Game Child Table */
95/* ========================= */
96
97template<class T_ChildAbstractTableItem, class T_ParentAbstractTableItem, class T_ColumnData>
98GameChildTable<T_ChildAbstractTableItem, T_ParentAbstractTableItem, T_ColumnData>::GameChildTable(
99 const QString &table_name, const TableIndex table_id, const TableType table_type)
100 : GameTable<T_ChildAbstractTableItem, T_ColumnData>(table_name, table_id, table_type)
101{}
102
103/* ================= */
104/* File i/o */
105/* ================= */
106
107template<class T_ChildAbstractTableItem, class T_ParentAbstractTableItem, class T_ColumnData>
109 QDataStream &in)
110{
112
113 const auto transfer_result{transferChildDataToParent()};
114
115 return read_result && transfer_result;
116}
117
118/* ================= */
119/* Get Data */
120/* ================= */
121
122template<class T_ChildAbstractTableItem, class T_ParentAbstractTableItem, class T_ColumnData>
124 const QModelIndex &index, qint32 role) const
125{
126 if (!index.isValid())
127 return QVariant();
128
129 return this->parent_table_->childData(index,
130 role,
131 this->constColumnData(),
132 this->attributes()->id());
133}
134
135/* ========================== */
136/* Get Data - Counts */
137/* ========================== */
138
139template<class T_ChildAbstractTableItem, class T_ParentAbstractTableItem, class T_ColumnData>
140qint32 GameChildTable<T_ChildAbstractTableItem, T_ParentAbstractTableItem, T_ColumnData>::rowCount(
141 const QModelIndex &parent) const
142{
143 if (parent.isValid() || !this->parent_table_) // No children
144 return 0;
145
146 return this->parent_table_->rowCount();
147}
148
149/* ==================== */
150/* Parent Data */
151/* ==================== */
152
153// --- Transfer a child item to the parent --- //
154template<class T_ChildAbstractTableItem, class T_ParentAbstractTableItem, class T_ColumnData>
155bool GameChildTable<T_ChildAbstractTableItem, T_ParentAbstractTableItem, T_ColumnData>::
156 transferChildDataToParent()
157{
158 if (!parent_table_) {
159 qWarning().noquote() << QStringLiteral("No parent table assigned to '%1' child table")
160 .arg(this->table_attributes_.name());
161 return false;
162 }
163
164 const auto parent_size{parent_table_->rowCount()};
165 const auto child_table_index{this->attributes()->id()};
166
167 // Parent items have a child id
168 if (parent_table_relationship_
169 == ehm_dal::tables::AbstractTable::ParentTableRelationshipType::ParentTableHasChildIdField) {
170 for (auto parent_id = 0; parent_id < parent_size; ++parent_id) {
171 const auto child_id{parent_table_->childItemId(parent_id, child_table_index)};
172 if (this->isValidRow(child_id))
173 parent_table_->addChildItem(parent_id, this->data_[child_id], child_table_index);
174 }
175 }
176 // Child items have a parent id
177 else if (parent_table_relationship_
178 == ehm_dal::tables::AbstractTable::ParentTableRelationshipType::
179 ChildTableHasParentIdField) {
180 for (auto &itr : this->data_) {
181 const auto parent_id{itr->parentItemId()};
182 parent_table_->addChildItem(parent_id, itr, child_table_index);
183 }
184 }
185
186 // Clear the buffer
187 this->data_.clear();
188
189 return true;
190}
191
192/* ================= */
193/* Set Data */
194/* ================= */
195
196template<class T_ChildAbstractTableItem, class T_ParentAbstractTableItem, class T_ColumnData>
197bool GameChildTable<T_ChildAbstractTableItem, T_ParentAbstractTableItem, T_ColumnData>::setData(
198 const QModelIndex &index, const QVariant &value, qint32 role)
199{
200 if (!index.isValid() || role != Qt::EditRole)
201 return false;
202
203 std::vector<qint32> modified_columns{index.column()};
204
205 const auto result{parent_table_->setChildData(index,
206 value,
207 role,
208 modified_columns,
209 this->constColumnData(),
210 this->attributes()->id())};
211
212 if (result && this->emitModifiedColumns(index.row(), modified_columns, index.parent()))
213 return true;
214
215 return false;
216}
217
218} // namespace ehm_dal::tables
The ColumnData class represents a container of ehm_dal::column_data::Column and attributes relating t...
Definition: column_data.h:18
The GameChildTable class is a model for child data of a parent table. Each parent item has a single c...
Definition: game_child_table.h:20
bool readStream(QDataStream &in) override
Reads the table data from a QDataStream.
Definition: game_child_table.h:108
Definition: game_table.h:23
namespace ehm_dal::tables
Definition: column.h:4
TableType
The TableType enum denotes different types of database table.
Definition: table_type.h:12
TableIndex
The TableIndex enum represents the id number of each table within the database.
Definition: table_index.h:14