295 lines
9.6 KiB
C++
295 lines
9.6 KiB
C++
#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 ¤tList : 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;
|
|
};
|