Files

295 lines
9.6 KiB
C++
Raw Permalink Normal View History

2026-07-12 14:34:52 +04:00
#include "application_connector.h"
#include "model_manager.h"
#include "repository_manager.h"
#include "schema_metadata.h"
#include <QObject>
ApplicationConnector::ApplicationConnector(QObject *rootObject)
: modelManager_(ModelManager::instance()),
repositoryManager_(RepositoryManager::instance()),
rootObject_(rootObject) {}
bool ApplicationConnector::connect() {
if (!connectSelfReferenceTableLinks()) {
return false;
}
if (!connectTablePairLinks()) {
return false;
}
if (!connectUpdateDeleteRFLinks()) {
return false;
}
if (!connectDeleteRFLinks()) {
return false;
}
return true;
}
ApplicationConnector::RMLinkList
ApplicationConnector::initializeSelfReferenceTableLinks() {
return {linkRepositoryToModel("genres", "genres"),
linkRepositoryToModel("halls", "halls"),
linkRepositoryToModel("movies", "movies"),
linkRepositoryToModel("sessions", "sessions"),
linkRepositoryToModel("refunds", "refunds"),
linkRepositoryToModel("tickets", "tickets")};
}
ApplicationConnector::RMLinkList
ApplicationConnector::initializeTablePairLinks() {
return {linkRepositoryToModel("genres", "movies"),
linkRepositoryToModel("genres", "sessions"),
linkRepositoryToModel("genres", "tickets"),
linkRepositoryToModel("genres", "refunds"),
linkRepositoryToModel("halls", "sessions"),
linkRepositoryToModel("halls", "tickets"),
linkRepositoryToModel("halls", "refunds"),
linkRepositoryToModel("movies", "sessions"),
linkRepositoryToModel("movies", "tickets"),
linkRepositoryToModel("movies", "refunds"),
linkRepositoryToModel("sessions", "refunds"),
linkRepositoryToModel("tickets", "refunds")};
}
ApplicationConnector::RFLinkList
ApplicationConnector::flattenLinkList(const QVector<RFLinkList> &linkLists) {
RFLinkList result;
for (const RFLinkList &currentList : linkLists) {
std::move(currentList.cbegin(), currentList.cend(),
std::back_inserter(result));
}
return result;
}
ApplicationConnector::RFLinkList
ApplicationConnector::initializeUpdateDeleteCandidates() {
const QVector<RFLinkList> updateDeleteCandidates = {
linkRepositoryToFinder("genres", "genreFinder"),
linkRepositoryToFinder("genres", "movieFinder"),
linkRepositoryToFinder("genres", "sessionFinder"),
linkRepositoryToFinder("genres", "ticketFinder"),
linkRepositoryToFinder("genres", "entityFinder"),
linkRepositoryToFinder("halls", "hallFinder"),
linkRepositoryToFinder("halls", "movieFinder"),
linkRepositoryToFinder("halls", "sessionFinder"),
linkRepositoryToFinder("halls", "ticketFinder"),
linkRepositoryToFinder("halls", "entityFinder"),
linkRepositoryToFinder("movies", "movieFinder"),
linkRepositoryToFinder("movies", "sessionFinder"),
linkRepositoryToFinder("movies", "ticketFinder"),
linkRepositoryToFinder("movies", "entityFinder"),
linkRepositoryToFinder("sessions", "sessionFinder"),
linkRepositoryToFinder("sessions", "ticketFinder"),
linkRepositoryToFinder("sessions", "entityFinder"),
linkRepositoryToFinder("tickets", "ticketFinder"),
linkRepositoryToFinder("tickets", "entityFinder"),
linkRepositoryToFinder("refunds", "entityFinder")};
return flattenLinkList(updateDeleteCandidates);
}
ApplicationConnector::RFLinkList
ApplicationConnector::initializeDeleteCandidates() {
// foreignKeyFinder will reset to default on signal primaryKeyFinder
const QVector<RFLinkList> deleteCandidates = {
linkRepositoryToFinder("genres", "primaryKeyFinder"),
linkRepositoryToFinder("halls", "primaryKeyFinder"),
linkRepositoryToFinder("movies", "primaryKeyFinder"),
linkRepositoryToFinder("sessions", "primaryKeyFinder"),
linkRepositoryToFinder("tickets", "primaryKeyFinder"),
linkRepositoryToFinder("refunds", "primaryKeyFinder")};
return flattenLinkList(deleteCandidates);
}
bool ApplicationConnector::connectSelfReferenceTableLinks() {
const QList<RMLink> selfReferenceTableLinks =
initializeSelfReferenceTableLinks();
qInfo() << "Connecting self-reference tables...";
if (!connect(selfReferenceTableLinks, singleTableConnections())) {
qWarning() << "Failed to connect self-reference tables";
return false;
}
return true;
}
bool ApplicationConnector::connectTablePairLinks() {
const RMLinkList tablePairLinks = initializeTablePairLinks();
qInfo() << "Connecting pair tables...";
if (!connect(tablePairLinks, pairTableConnections())) {
qWarning() << "Failed to connect pair tables";
return false;
}
return true;
}
bool ApplicationConnector::connectUpdateDeleteRFLinks() {
const RFLinkList repositoryToFinderLinks = initializeUpdateDeleteCandidates();
qInfo() << "Connecting repository to finder...";
if (!connect(repositoryToFinderLinks, repositoryToFinderConnections())) {
qWarning() << "Failed to connect repository to finder";
return false;
}
return true;
}
bool ApplicationConnector::connectDeleteRFLinks() {
const RFLinkList repositoryToFinderLinks = initializeDeleteCandidates();
qInfo() << "Connecting repository to finder...";
using Signal = void (Repository::*)();
using Slot = void (Finder::*)();
RFConnectionList connections;
connections.append(Connection<Signal, Slot>(&Repository::dataDeleted,
&Finder::resetToDefault));
if (!connect(repositoryToFinderLinks, connections)) {
qWarning() << "Failed to connect repository to finder";
return false;
}
return true;
}
ApplicationConnector::RMConnectionList
ApplicationConnector::pairTableConnections() {
using Signal = void (Repository::*)();
using Slot = bool (Model::*)();
RMConnectionList result;
std::initializer_list<Connection<Signal, Slot>> initList = {
{&Repository::dataUpdated, &Model::refreshAll},
{&Repository::dataDeleted, &Model::refreshAll}};
for (const auto &connection : initList) {
result.append(connection);
}
return result;
}
ApplicationConnector::RMConnectionList
ApplicationConnector::singleTableConnections() {
using Signal = void (Repository::*)();
using Slot = bool (Model::*)();
RMConnectionList result;
std::initializer_list<Connection<Signal, Slot>> initList = {
{&Repository::dataCreated, &Model::refreshAll},
{&Repository::dataUpdated, &Model::refreshAll},
{&Repository::dataDeleted, &Model::refreshAll}};
for (const auto &connection : initList) {
result.append(connection);
}
return result;
}
ApplicationConnector::RMLink ApplicationConnector::linkRepositoryToModel(
const QString &senderDatabaseTableName,
const QString &receiverDatabaseTableName) {
SchemaMetadata metadata = SchemaMetadata::defaultSchema();
Repository *sender = repositoryManager_.getRepositoryAs<Repository>(
metadata.repositoryTableName(senderDatabaseTableName));
if (!sender) {
qWarning() << "Sender with type" << typeid(sender).name() << "is null";
}
Model *receiver = modelManager_.getModelAs<Model>(
metadata.modelTableName(receiverDatabaseTableName));
if (!receiver) {
qWarning() << "Receiver with type" << typeid(receiver).name() << "is null";
}
if (!sender || !receiver) {
return qMakePair(nullptr, nullptr);
}
return qMakePair(sender, receiver);
}
ApplicationConnector::RFLinkList ApplicationConnector::linkRepositoryToFinder(
const QString &senderDatabaseTableName,
const QString &receiverEntityFinderName) {
SchemaMetadata metadata = SchemaMetadata::defaultSchema();
Repository *sender = repositoryManager_.getRepositoryAs<Repository>(
metadata.repositoryTableName(senderDatabaseTableName));
if (!sender) {
qWarning() << "Sender with type" << typeid(sender).name() << "is null";
}
QList<Finder *> receiver =
rootObject_->findChildren<Finder *>(receiverEntityFinderName);
if (receiver.isEmpty()) {
qWarning() << "Receivers with type" << typeid(receiver).name()
<< "there is not";
}
if (!sender || receiver.isEmpty()) {
return QList<RFLink>();
}
RFLinkList result;
for (Finder *currentReceiver : receiver) {
result.append(qMakePair(sender, currentReceiver));
}
return result;
}
ApplicationConnector::RFConnectionList
ApplicationConnector::repositoryToFinderConnections() {
using Signal = void (Repository::*)();
using Slot = void (Finder::*)();
RFConnectionList result;
std::initializer_list<Connection<Signal, Slot>> initList = {
{&Repository::dataDeleted, &Finder::resetToDefault},
{&Repository::dataUpdated, &Finder::resetToDefault}};
for (const auto &connection : initList) {
result.append(connection);
}
return result;
}
QString ApplicationConnector::getAddress(const QObject *object) {
quintptr address = reinterpret_cast<quintptr>(object);
return object ? QString::number(address, 16) : "null";
};
QString ApplicationConnector::getMetaClassName(const QMetaObject *meta) {
return meta ? meta->className() : "Unknown";
};
QString ApplicationConnector::getMethodSignature(const QMetaObject *meta,
const char *methodType,
bool isSignal) {
if (!meta) {
return "Unknown";
}
QByteArray normalizedSignature = QMetaObject::normalizedSignature(methodType);
int methodIndex = isSignal ? meta->indexOfSignal(normalizedSignature)
: meta->indexOfSlot(normalizedSignature);
if (methodIndex < 0) {
return normalizedSignature;
}
QString result = meta->method(methodIndex).methodSignature();
return result;
};