91 lines
2.5 KiB
C++
91 lines
2.5 KiB
C++
|
|
// repository_manager.h
|
||
|
|
#ifndef REPOSITORY_MANAGER_H
|
||
|
|
#define REPOSITORY_MANAGER_H
|
||
|
|
|
||
|
|
#include "repository_interface.h"
|
||
|
|
|
||
|
|
#include <QMap>
|
||
|
|
#include <QSqlDatabase>
|
||
|
|
|
||
|
|
// The repository manager inherits the QObject class to delete child objects
|
||
|
|
class RepositoryManager : public QObject {
|
||
|
|
Q_OBJECT
|
||
|
|
|
||
|
|
private:
|
||
|
|
// Database connection
|
||
|
|
QSqlDatabase database_;
|
||
|
|
|
||
|
|
// Map of repository names to instances
|
||
|
|
QMap<QString, RepositoryInterface *> repositories_;
|
||
|
|
|
||
|
|
public:
|
||
|
|
// Singleton instance accessor
|
||
|
|
static RepositoryManager &instance();
|
||
|
|
|
||
|
|
// Get a repository by name
|
||
|
|
RepositoryInterface *getRepository(const QString &repositoryTableName) const;
|
||
|
|
|
||
|
|
// Get a repository by name and type
|
||
|
|
template <typename T>
|
||
|
|
T *getRepositoryAs(const QString &repositoryTableName) const;
|
||
|
|
|
||
|
|
private:
|
||
|
|
// Register a new repository
|
||
|
|
template <typename T>
|
||
|
|
bool registerRepository(const QString &repositoryTableName);
|
||
|
|
|
||
|
|
// Initialize repositories
|
||
|
|
void initialize();
|
||
|
|
|
||
|
|
// Private constructor for singleton
|
||
|
|
RepositoryManager();
|
||
|
|
|
||
|
|
// Destructor to clean up resources
|
||
|
|
~RepositoryManager();
|
||
|
|
|
||
|
|
// Delete copy constructor
|
||
|
|
RepositoryManager(const RepositoryManager &) = delete;
|
||
|
|
|
||
|
|
// Delete assignment operator
|
||
|
|
RepositoryManager &operator=(const RepositoryManager &) = delete;
|
||
|
|
};
|
||
|
|
|
||
|
|
// NOTE: Implementation of template methods
|
||
|
|
|
||
|
|
template <typename T>
|
||
|
|
T *RepositoryManager::getRepositoryAs(
|
||
|
|
const QString &repositoryTableName) const {
|
||
|
|
auto *repository = dynamic_cast<T *>(getRepository(repositoryTableName));
|
||
|
|
if (!repository) {
|
||
|
|
qFatal() << "Failed to downcast repository for" << repositoryTableName
|
||
|
|
<< "(typeid name):" << typeid(T).name();
|
||
|
|
return nullptr;
|
||
|
|
}
|
||
|
|
qInfo() << "Successfully downcast repository for" << repositoryTableName;
|
||
|
|
return repository;
|
||
|
|
}
|
||
|
|
|
||
|
|
template <typename T>
|
||
|
|
bool RepositoryManager::registerRepository(const QString &repositoryTableName) {
|
||
|
|
static_assert(
|
||
|
|
std::is_constructible<T, QSqlDatabase &, QObject *>::value,
|
||
|
|
"Repository class must have a constructor accepting QSqlDatabase& and "
|
||
|
|
"QObject*");
|
||
|
|
|
||
|
|
if (repositories_.contains(repositoryTableName)) {
|
||
|
|
qInfo() << "Repository" << repositoryTableName << "is already registered";
|
||
|
|
return true;
|
||
|
|
}
|
||
|
|
|
||
|
|
auto *repository = new T(database_, this); // Qt will delete the model
|
||
|
|
repository->setObjectName(repositoryTableName);
|
||
|
|
|
||
|
|
repositories_.insert(repositoryTableName, repository);
|
||
|
|
|
||
|
|
qInfo() << "Repository" << repositoryTableName
|
||
|
|
<< "was registered successfully";
|
||
|
|
return true;
|
||
|
|
}
|
||
|
|
|
||
|
|
#endif // REPOSITORY_MANAGER_H
|