492 lines
16 KiB
C++
492 lines
16 KiB
C++
#include "entity_updater_widget.h"
|
|
|
|
#include "genres_repository_interface.h"
|
|
#include "halls_repository_interface.h"
|
|
#include "movies_repository_interface.h"
|
|
#include "refunds_repository_interface.h"
|
|
#include "sessions_repository_interface.h"
|
|
#include "tickets_repository_interface.h"
|
|
|
|
#include "update_genre_request.h"
|
|
#include "update_hall_request.h"
|
|
#include "update_movie_request.h"
|
|
#include "update_refund_request.h"
|
|
#include "update_session_request.h"
|
|
#include "update_ticket_request.h"
|
|
|
|
#include "error_dialog.h"
|
|
#include "model_manager.h"
|
|
|
|
#include "base_sql_table_model.h"
|
|
#include <QMessageBox>
|
|
#include <qsqlrelationaltablemodel.h>
|
|
|
|
namespace DatabaseTableNames {
|
|
static constexpr char Genres[] = "genres";
|
|
static constexpr char Halls[] = "halls";
|
|
static constexpr char Movies[] = "movies";
|
|
static constexpr char Refunds[] = "refunds";
|
|
static constexpr char Sessions[] = "sessions";
|
|
static constexpr char Tickets[] = "tickets";
|
|
} // namespace DatabaseTableNames
|
|
|
|
EntityUpdaterWidget::EntityUpdaterWidget(QWidget *parent)
|
|
: QWidget(parent), primaryKey_(-1) {
|
|
setupUi(this);
|
|
|
|
setupConnections();
|
|
setupComboBoxCurrentTable(); // After setup connections
|
|
setupParentEntityFinderWidget();
|
|
setupChildEntityFinderWidget();
|
|
}
|
|
|
|
void EntityUpdaterWidget::setupComboBoxCurrentTable() {
|
|
SchemaMetadata metadata = SchemaMetadata::defaultSchema();
|
|
|
|
QList<QString> databaseTableNames = {
|
|
DatabaseTableNames::Genres, DatabaseTableNames::Halls,
|
|
DatabaseTableNames::Movies, DatabaseTableNames::Refunds,
|
|
DatabaseTableNames::Sessions, DatabaseTableNames::Tickets};
|
|
|
|
for (const QString &tableName : databaseTableNames) {
|
|
comboBoxCurrentTable->addItem(metadata.translatedTableName(tableName),
|
|
tableName);
|
|
}
|
|
}
|
|
|
|
void EntityUpdaterWidget::setupConnections() {
|
|
connect(foreignKeyFinder, &EntityFinderWidget::fieldRetrieved, this,
|
|
&EntityUpdaterWidget::onForeignFieldRetrieved);
|
|
|
|
connect(primaryKeyFinder, &EntityFinderWidget::fieldRetrieved, this,
|
|
&EntityUpdaterWidget::onPrimaryFieldRetrieved);
|
|
|
|
connect(primaryKeyFinder, &EntityFinderWidget::recordRetrieved, this,
|
|
&EntityUpdaterWidget::onPrimaryEntityRetrieved);
|
|
|
|
connect(comboBoxCurrentTable, &QComboBox::currentIndexChanged, this,
|
|
&EntityUpdaterWidget::onTableSelected);
|
|
|
|
connect(comboBoxCurrentColumn, &QComboBox::currentIndexChanged, this,
|
|
&EntityUpdaterWidget::onColumnSelected);
|
|
|
|
connect(pushButtonUpdate, &QPushButton::clicked, this,
|
|
&EntityUpdaterWidget::onPushButtonUpdateClicked);
|
|
}
|
|
|
|
void EntityUpdaterWidget::setupChildEntityFinderWidget() {
|
|
foreignKeyFinder->setLabelText(
|
|
EntityFinderWidget::tr("Select entity for replacement"));
|
|
foreignKeyFinder->setLineEditPlaceholder(
|
|
EntityFinderWidget::tr("Here will be information about selected entity"));
|
|
foreignKeyFinder->setHiddenFrame(true);
|
|
}
|
|
|
|
void EntityUpdaterWidget::setupParentEntityFinderWidget() {
|
|
primaryKeyFinder->setLabelText(
|
|
EntityFinderWidget::tr("Select entity for updating"));
|
|
primaryKeyFinder->setLineEditPlaceholder(
|
|
EntityFinderWidget::tr("Here will be information about selected entry"));
|
|
}
|
|
|
|
void EntityUpdaterWidget::configureForeignKeyFinder(
|
|
const QString &columnName, const QString &databaseTableName) {
|
|
TableInfoSQLite tableInfo(databaseTableName);
|
|
|
|
if (tableInfo.isPrimaryKey(columnName)) {
|
|
// NOTE: Change Primary Key is prohibited
|
|
|
|
// configurePrimaryKeyFinder(databaseTableName);
|
|
return;
|
|
}
|
|
|
|
QString foreignKeyDatabaseTableName = tableInfo.foreignKeyTable(columnName);
|
|
if (foreignKeyDatabaseTableName.isEmpty()) {
|
|
qCritical()
|
|
<< "Could not find the database table name for the key column, which "
|
|
"contains \"_id\":"
|
|
<< columnName;
|
|
return;
|
|
}
|
|
|
|
configureForeignKeyFinder(foreignKeyDatabaseTableName);
|
|
}
|
|
|
|
void EntityUpdaterWidget::configureForeignKeyFinder(
|
|
const QString &databaseTableName) {
|
|
foreignKeyFinder->resetToDefault();
|
|
foreignKeyFinder->setDefaultRelation(databaseTableName);
|
|
}
|
|
|
|
void EntityUpdaterWidget::configurePrimaryKeyFinder(
|
|
const QString &databaseTableName) {
|
|
primaryKeyFinder->resetToDefault();
|
|
primaryKeyFinder->setDefaultRelation(databaseTableName);
|
|
}
|
|
|
|
void EntityUpdaterWidget::onPrimaryFieldRetrieved(const QSqlField &field) {
|
|
qInfo() << "Selected primary field: Name:" << field.name()
|
|
<< "Value:" << field.value();
|
|
primaryKey_ = field.value().toInt();
|
|
}
|
|
|
|
void EntityUpdaterWidget::onForeignFieldRetrieved(const QSqlField &field) {
|
|
qInfo() << "Selected foreign field: Name:" << field.name()
|
|
<< "Value:" << field.value();
|
|
selectedForeignField_ = field;
|
|
}
|
|
|
|
void EntityUpdaterWidget::onPrimaryEntityRetrieved(const QSqlRecord &entity) {
|
|
qInfo() << "Retrieved foreign entity:" << entity;
|
|
selectedPrimaryEntity_ = entity;
|
|
}
|
|
|
|
template <>
|
|
QString EntityUpdaterWidget::actualColumnValue(const QString &columnName) {
|
|
QString value = isColumnsEqual(columnName)
|
|
? lineEdit->text()
|
|
: selectedPrimaryEntity_.value(columnName).toString();
|
|
|
|
qInfo() << "Actual column QString value:" << value;
|
|
return value;
|
|
}
|
|
|
|
template <>
|
|
QDateTime EntityUpdaterWidget::actualColumnValue(const QString &columnName) {
|
|
QDateTime value = isColumnsEqual(columnName)
|
|
? dateTimeEdit->dateTime()
|
|
: selectedPrimaryEntity_.value(columnName).toDateTime();
|
|
|
|
qInfo() << "Actual column QDateTime value:" << value;
|
|
return value;
|
|
}
|
|
|
|
template <>
|
|
int EntityUpdaterWidget::actualColumnValue(const QString &columnName) {
|
|
int value = isColumnsEqual(columnName)
|
|
? spinBox->value()
|
|
: selectedPrimaryEntity_.value(columnName).toInt();
|
|
|
|
qInfo() << "Actual column int value:" << value;
|
|
return value;
|
|
}
|
|
|
|
template <>
|
|
double EntityUpdaterWidget::actualColumnValue(const QString &columnName) {
|
|
double value = isColumnsEqual(columnName)
|
|
? doubleSpinBox->value()
|
|
: selectedPrimaryEntity_.value(columnName).toDouble();
|
|
|
|
qInfo() << "Actual column double value:" << value;
|
|
return value;
|
|
}
|
|
|
|
qint32 EntityUpdaterWidget::actualForeignKey(const QString &columnName) {
|
|
qint32 value = isColumnsEqual(columnName)
|
|
? selectedForeignField_.value().toInt()
|
|
: selectedPrimaryEntity_.value(columnName).toInt();
|
|
|
|
qInfo() << "Actual foreign key:" << value;
|
|
return value;
|
|
}
|
|
|
|
template <>
|
|
RepositoryResult
|
|
EntityUpdaterWidget::updateEntity<GenresRepositoryInterface>() {
|
|
UpdateGenreRequest request;
|
|
request.setGenreId(primaryKey_);
|
|
request.setGenreName(actualColumnValue<QString>("genre_name"));
|
|
|
|
return currentRepository<GenresRepositoryInterface>()->updateGenre(request);
|
|
}
|
|
|
|
template <>
|
|
RepositoryResult EntityUpdaterWidget::updateEntity<HallsRepositoryInterface>() {
|
|
UpdateHallRequest request;
|
|
request.setHallId(primaryKey_);
|
|
request.setCapacity(actualColumnValue<int>("capacity"));
|
|
request.setHallName(actualColumnValue<QString>("hall_name"));
|
|
|
|
return currentRepository<HallsRepositoryInterface>()->updateHall(request);
|
|
}
|
|
|
|
template <>
|
|
RepositoryResult
|
|
EntityUpdaterWidget::updateEntity<MoviesRepositoryInterface>() {
|
|
UpdateMovieRequest request;
|
|
request.setMovieId(primaryKey_);
|
|
request.setDuration(actualColumnValue<int>("duration"));
|
|
request.setGenreId(actualForeignKey("genre_id"));
|
|
request.setTitle(actualColumnValue<QString>("title"));
|
|
|
|
return currentRepository<MoviesRepositoryInterface>()->updateMovie(request);
|
|
}
|
|
|
|
template <>
|
|
RepositoryResult
|
|
EntityUpdaterWidget::updateEntity<RefundsRepositoryInterface>() {
|
|
UpdateRefundRequest request;
|
|
request.setRefundId(primaryKey_);
|
|
request.setRefundAmount(actualColumnValue<double>("refund_amount"));
|
|
request.setRefundAt(actualColumnValue<QDateTime>("refund_at"));
|
|
request.setTicketId(actualForeignKey("ticket_id"));
|
|
|
|
return currentRepository<RefundsRepositoryInterface>()->updateRefund(request);
|
|
}
|
|
|
|
template <>
|
|
RepositoryResult
|
|
EntityUpdaterWidget::updateEntity<SessionsRepositoryInterface>() {
|
|
UpdateSessionRequest request;
|
|
request.setSessionId(primaryKey_);
|
|
request.setHallId(actualForeignKey("hall_id"));
|
|
request.setMovieId(actualForeignKey("movie_id"));
|
|
request.setBeginAt(actualColumnValue<QDateTime>("begin_at"));
|
|
request.setTicketPrice(actualColumnValue<double>("ticket_price"));
|
|
|
|
return currentRepository<SessionsRepositoryInterface>()->updateSession(
|
|
request);
|
|
}
|
|
|
|
template <>
|
|
RepositoryResult
|
|
EntityUpdaterWidget::updateEntity<TicketsRepositoryInterface>() {
|
|
UpdateTicketRequest request;
|
|
request.setTicketId(primaryKey_);
|
|
request.setSeatNumber(actualColumnValue<int>("seat_number"));
|
|
request.setSessionId(actualForeignKey("session_id"));
|
|
request.setSoldAt(actualColumnValue<QDateTime>("sold_at"));
|
|
|
|
return currentRepository<TicketsRepositoryInterface>()->updateTicket(request);
|
|
}
|
|
|
|
template <>
|
|
void EntityUpdaterWidget::processEntityUpdate<DatabaseTableNames::Genres>(
|
|
RepositoryResult &resultOut) {
|
|
resultOut = updateEntity<GenresRepositoryInterface>();
|
|
if (!resultOut.success) {
|
|
ErrorDialog::displayError(this, resultOut.errorMessage);
|
|
return;
|
|
}
|
|
showMessageDialog(resultOut,
|
|
EntityUpdaterWidget::tr("Genre updated successfully"));
|
|
}
|
|
|
|
template <>
|
|
void EntityUpdaterWidget::processEntityUpdate<DatabaseTableNames::Halls>(
|
|
RepositoryResult &resultOut) {
|
|
resultOut = updateEntity<HallsRepositoryInterface>();
|
|
if (!resultOut.success) {
|
|
ErrorDialog::displayError(this, resultOut.errorMessage);
|
|
return;
|
|
}
|
|
showMessageDialog(resultOut,
|
|
EntityUpdaterWidget::tr("Hall updated successfully"));
|
|
}
|
|
|
|
template <>
|
|
void EntityUpdaterWidget::processEntityUpdate<DatabaseTableNames::Movies>(
|
|
RepositoryResult &resultOut) {
|
|
resultOut = updateEntity<MoviesRepositoryInterface>();
|
|
if (!resultOut.success) {
|
|
ErrorDialog::displayError(this, resultOut.errorMessage);
|
|
return;
|
|
}
|
|
showMessageDialog(resultOut,
|
|
EntityUpdaterWidget::tr("Movie updated successfully"));
|
|
}
|
|
|
|
template <>
|
|
void EntityUpdaterWidget::processEntityUpdate<DatabaseTableNames::Refunds>(
|
|
RepositoryResult &resultOut) {
|
|
resultOut = updateEntity<RefundsRepositoryInterface>();
|
|
if (!resultOut.success) {
|
|
ErrorDialog::displayError(this, resultOut.errorMessage);
|
|
return;
|
|
}
|
|
showMessageDialog(resultOut,
|
|
EntityUpdaterWidget::tr("Refund updated successfully"));
|
|
}
|
|
|
|
template <>
|
|
void EntityUpdaterWidget::processEntityUpdate<DatabaseTableNames::Sessions>(
|
|
RepositoryResult &resultOut) {
|
|
resultOut = updateEntity<SessionsRepositoryInterface>();
|
|
if (!resultOut.success) {
|
|
ErrorDialog::displayError(this, resultOut.errorMessage);
|
|
return;
|
|
}
|
|
showMessageDialog(resultOut,
|
|
EntityUpdaterWidget::tr("Session updated successfully"));
|
|
}
|
|
|
|
template <>
|
|
void EntityUpdaterWidget::processEntityUpdate<DatabaseTableNames::Tickets>(
|
|
RepositoryResult &resultOut) {
|
|
resultOut = updateEntity<TicketsRepositoryInterface>();
|
|
if (!resultOut.success) {
|
|
ErrorDialog::displayError(this, resultOut.errorMessage);
|
|
return;
|
|
}
|
|
showMessageDialog(resultOut,
|
|
EntityUpdaterWidget::tr("Ticket updated successfully"));
|
|
}
|
|
|
|
void EntityUpdaterWidget::onPushButtonUpdateClicked() {
|
|
const QString &databaseTableName =
|
|
comboBoxCurrentTable->currentData().toString();
|
|
|
|
RepositoryResult result;
|
|
|
|
if (databaseTableName == DatabaseTableNames::Genres) {
|
|
processEntityUpdate<DatabaseTableNames::Genres>(result);
|
|
|
|
} else if (databaseTableName == DatabaseTableNames::Halls) {
|
|
processEntityUpdate<DatabaseTableNames::Halls>(result);
|
|
|
|
} else if (databaseTableName == DatabaseTableNames::Movies) {
|
|
processEntityUpdate<DatabaseTableNames::Movies>(result);
|
|
|
|
} else if (databaseTableName == DatabaseTableNames::Refunds) {
|
|
processEntityUpdate<DatabaseTableNames::Refunds>(result);
|
|
|
|
} else if (databaseTableName == DatabaseTableNames::Sessions) {
|
|
processEntityUpdate<DatabaseTableNames::Sessions>(result);
|
|
|
|
} else if (databaseTableName == DatabaseTableNames::Tickets) {
|
|
processEntityUpdate<DatabaseTableNames::Tickets>(result);
|
|
|
|
} else {
|
|
qFatal() << "EntityDeleterWidget::onPressPushButtonDeleteEntity: "
|
|
"Unknown database table name:"
|
|
<< databaseTableName;
|
|
}
|
|
|
|
processUpdateResult(result);
|
|
}
|
|
|
|
void EntityUpdaterWidget::onTableSelected(int tableIndex) {
|
|
SchemaMetadata metadata = SchemaMetadata::defaultSchema();
|
|
|
|
const QString &databaseTableName =
|
|
comboBoxCurrentTable->itemData(tableIndex).toString();
|
|
|
|
ModelManager &modelManager = ModelManager::instance();
|
|
BaseSqlTableModel *model = modelManager.getModelAs<BaseSqlTableModel>(
|
|
metadata.modelTableName(databaseTableName));
|
|
|
|
comboBoxCurrentColumn->clear();
|
|
for (const auto &columnName : model->columnNames()) {
|
|
if (metadata.primaryIdColumnName(databaseTableName) == columnName) {
|
|
// NOTE: Change Primary Key is prohibited
|
|
continue;
|
|
}
|
|
|
|
int headerIndex = model->columnIndex(columnName);
|
|
QString displayName =
|
|
model->headerData(headerIndex, Qt::Horizontal).toString();
|
|
comboBoxCurrentColumn->addItem(displayName, columnName);
|
|
}
|
|
|
|
configurePrimaryKeyFinder(databaseTableName);
|
|
}
|
|
|
|
void EntityUpdaterWidget::onColumnSelected(int columnIndex) {
|
|
Q_UNUSED(columnIndex);
|
|
|
|
const QString &databaseTableName =
|
|
comboBoxCurrentTable->currentData().toString();
|
|
TableInfoSQLite tableInfoSQLite(databaseTableName);
|
|
|
|
QString columnName = comboBoxCurrentColumn->currentData().toString();
|
|
bool isKey = columnName.contains("_id", Qt::CaseInsensitive);
|
|
|
|
QWidget *page;
|
|
switch (tableInfoSQLite.columnMetaType(columnName)) {
|
|
case QMetaType::Int: {
|
|
page =
|
|
findChild<QWidget *>(isKey ? "pageChildFinderWidget" : "pageSpinBox");
|
|
} break;
|
|
case QMetaType::Double:
|
|
page = findChild<QWidget *>("pageDoubleSpinBox");
|
|
break;
|
|
case QMetaType::QString:
|
|
page = findChild<QWidget *>("pageLineEdit");
|
|
break;
|
|
case QMetaType::QDateTime:
|
|
page = findChild<QWidget *>("pageDateTimeEdit");
|
|
break;
|
|
default:
|
|
qCritical() << "Unknown column selected";
|
|
return;
|
|
}
|
|
stackedWidget->setCurrentWidget(page);
|
|
|
|
if (isKey) {
|
|
configureForeignKeyFinder(columnName, databaseTableName);
|
|
}
|
|
}
|
|
|
|
QModelIndex EntityUpdaterWidget::findIndexByColumn(QAbstractItemModel *model,
|
|
int column,
|
|
const QVariant &value) {
|
|
if (!model || column < 0 || column >= model->columnCount())
|
|
return QModelIndex();
|
|
|
|
for (int row = 0; row < model->rowCount(); ++row) {
|
|
QModelIndex index = model->index(row, column);
|
|
if (model->data(index) == value) {
|
|
return index;
|
|
}
|
|
}
|
|
|
|
return QModelIndex();
|
|
}
|
|
|
|
bool EntityUpdaterWidget::isColumnsEqual(const QString &other) {
|
|
TableInfoSQLite tableInfo(comboBoxCurrentTable->currentData().toString());
|
|
QString current = comboBoxCurrentColumn->currentData().toString();
|
|
|
|
bool isEqual = tableInfo.columnIndex(current) == tableInfo.columnIndex(other);
|
|
|
|
const static QString billet("Column \"%1\" and column \"%2\": %3");
|
|
qInfo().noquote() << billet.arg(current).arg(other).arg(
|
|
isEqual ? "Equal" : "Not equal");
|
|
|
|
return isEqual;
|
|
};
|
|
|
|
void EntityUpdaterWidget::processUpdateResult(const RepositoryResult &result) {
|
|
if (!result.success) {
|
|
return;
|
|
}
|
|
|
|
const QString &databaseTableName =
|
|
comboBoxCurrentTable->currentData().toString();
|
|
|
|
SchemaMetadata metadata = SchemaMetadata::defaultSchema();
|
|
ModelManager &modelManager = ModelManager::instance();
|
|
|
|
QSqlTableModel *model =
|
|
modelManager.getModel(metadata.modelTableName(databaseTableName));
|
|
|
|
QString primaryKeyColumnName =
|
|
metadata.primaryIdColumnName(databaseTableName);
|
|
|
|
int columnIndex = selectedPrimaryEntity_.indexOf(primaryKeyColumnName);
|
|
QModelIndex rowIndex = findIndexByColumn(model, columnIndex, primaryKey_);
|
|
selectedPrimaryEntity_ = model->record(rowIndex.row());
|
|
|
|
primaryKeyFinder->refreshLineEditText(selectedPrimaryEntity_);
|
|
foreignKeyFinder->resetToDefault();
|
|
}
|
|
|
|
void EntityUpdaterWidget::showMessageDialog(const RepositoryResult &result,
|
|
const QString &successMessage) {
|
|
if (!result.success) {
|
|
ErrorDialog::displayError(this, result.errorMessage);
|
|
} else {
|
|
QMessageBox::information(this, QMessageBox::tr("Success"), successMessage);
|
|
}
|
|
}
|