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