Initial commit
This commit is contained in:
@@ -0,0 +1,23 @@
|
||||
#include "base_sql_table_repository.h"
|
||||
|
||||
#include <QSqlError>
|
||||
#include <QSqlQuery>
|
||||
|
||||
BaseSqlTableRepository::BaseSqlTableRepository(QSqlDatabase &database,
|
||||
QObject *parent)
|
||||
: DataRepositorySignals(parent), database_(database) {
|
||||
if (!database_.isOpen()) {
|
||||
qWarning() << "Database is not open: Database name:"
|
||||
<< database_.databaseName()
|
||||
<< "Database connection name:" << database_.connectionName();
|
||||
}
|
||||
}
|
||||
|
||||
QSqlQuery BaseSqlTableRepository::foreignKeysOnQuery() const {
|
||||
QSqlQuery query(database_);
|
||||
if (!query.exec("PRAGMA foreign_keys = ON")) {
|
||||
qFatal() << "Failed to enable foreign keys:" << query.lastError().text();
|
||||
}
|
||||
|
||||
return query;
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
#ifndef BASE_REPOSITORY_H
|
||||
#define BASE_REPOSITORY_H
|
||||
|
||||
#include "data_repository_signals.h"
|
||||
#include <QSqlDatabase>
|
||||
|
||||
class BaseSqlTableRepository : public DataRepositorySignals {
|
||||
protected:
|
||||
QSqlDatabase database_;
|
||||
|
||||
public:
|
||||
BaseSqlTableRepository(QSqlDatabase &database, QObject *parent);
|
||||
|
||||
virtual ~BaseSqlTableRepository() = default;
|
||||
|
||||
protected:
|
||||
QSqlQuery foreignKeysOnQuery() const;
|
||||
};
|
||||
|
||||
#endif // BASE_REPOSITORY_H
|
||||
@@ -0,0 +1,32 @@
|
||||
#ifndef DATA_REPOSITORY_SIGNALS_H
|
||||
#define DATA_REPOSITORY_SIGNALS_H
|
||||
|
||||
#include <QObject>
|
||||
|
||||
// Inherits from QObject fore emitting signals
|
||||
class DataRepositorySignals : public QObject {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
// Parent is not required
|
||||
explicit DataRepositorySignals(QObject *parent = nullptr) : QObject(parent) {}
|
||||
|
||||
virtual ~DataRepositorySignals() = default;
|
||||
|
||||
signals:
|
||||
// Emitted when data is created
|
||||
void dataCreated();
|
||||
|
||||
// Emitted when data is updated
|
||||
void dataUpdated();
|
||||
|
||||
// Emitted when data is deleted
|
||||
void dataDeleted();
|
||||
|
||||
// WARNING: const context is required for emit in const methods
|
||||
|
||||
// Emitted when data is retrieved
|
||||
void dataRetrieved() const;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,99 @@
|
||||
#include "genres_repository.h"
|
||||
|
||||
#include "create_genre_request.h"
|
||||
#include "genre_dto.h"
|
||||
#include "repository_result.h"
|
||||
#include "update_genre_request.h"
|
||||
#include <QSqlError>
|
||||
#include <QSqlQuery>
|
||||
|
||||
GenresRepository::GenresRepository(QSqlDatabase &database, QObject *parent)
|
||||
: BaseSqlTableRepository(database, parent) {}
|
||||
|
||||
RepositoryResult
|
||||
GenresRepository::createGenre(const CreateGenreRequest &request) {
|
||||
QSqlQuery query = foreignKeysOnQuery();
|
||||
query.prepare("INSERT INTO genres (genre_name) VALUES (:genre_name)");
|
||||
query.bindValue(":genre_name", request.genreName());
|
||||
|
||||
if (!query.exec()) {
|
||||
return RepositoryResult::failureResult(query.lastError().text());
|
||||
}
|
||||
|
||||
emit dataCreated();
|
||||
return RepositoryResult::successResult();
|
||||
}
|
||||
|
||||
RepositoryResult GenresRepository::getGenreById(qint32 id,
|
||||
GenreDTO &genre) const {
|
||||
QSqlQuery query = foreignKeysOnQuery();
|
||||
query.prepare(
|
||||
"SELECT genre_id, genre_name FROM genres WHERE genre_id = :genre_id");
|
||||
query.bindValue(":genre_id", id);
|
||||
|
||||
if (!query.exec()) {
|
||||
return RepositoryResult::failureResult(query.lastError().text());
|
||||
}
|
||||
if (!query.next()) {
|
||||
return RepositoryResult::failureResult("Genre not found");
|
||||
}
|
||||
|
||||
genre = mapQueryToDTO(query);
|
||||
|
||||
emit dataRetrieved();
|
||||
return RepositoryResult::successResult();
|
||||
}
|
||||
|
||||
RepositoryResult
|
||||
GenresRepository::getAllGenres(QVector<GenreDTO> &genres) const {
|
||||
QSqlQuery query = foreignKeysOnQuery();
|
||||
query.prepare("SELECT genre_id, genre_name FROM genres");
|
||||
|
||||
if (!query.exec()) {
|
||||
return RepositoryResult::failureResult(query.lastError().text());
|
||||
}
|
||||
|
||||
while (query.next()) {
|
||||
genres.append(mapQueryToDTO(query));
|
||||
}
|
||||
|
||||
emit dataRetrieved();
|
||||
return RepositoryResult::successResult();
|
||||
}
|
||||
|
||||
RepositoryResult
|
||||
GenresRepository::updateGenre(const UpdateGenreRequest &request) {
|
||||
QSqlQuery query = foreignKeysOnQuery();
|
||||
query.prepare(
|
||||
"UPDATE genres SET genre_name = :genre_name WHERE genre_id = :genre_id");
|
||||
query.bindValue(":genre_name", request.genreName());
|
||||
query.bindValue(":genre_id", request.genreId());
|
||||
|
||||
if (!query.exec()) {
|
||||
return RepositoryResult::failureResult(query.lastError().text());
|
||||
}
|
||||
|
||||
emit dataUpdated();
|
||||
return RepositoryResult::successResult();
|
||||
}
|
||||
|
||||
RepositoryResult GenresRepository::deleteGenreById(qint32 genreId) {
|
||||
QSqlQuery query = foreignKeysOnQuery();
|
||||
query.prepare("DELETE FROM genres WHERE genre_id = :genre_id");
|
||||
query.bindValue(":genre_id", genreId);
|
||||
|
||||
if (!query.exec()) {
|
||||
return RepositoryResult::failureResult(query.lastError().text());
|
||||
}
|
||||
|
||||
emit dataDeleted();
|
||||
return RepositoryResult::successResult();
|
||||
}
|
||||
|
||||
GenreDTO GenresRepository::mapQueryToDTO(const QSqlQuery &query) const {
|
||||
GenreDTO genreDTO;
|
||||
genreDTO.setGenreId(query.value("genre_id").toInt());
|
||||
genreDTO.setGenreName(query.value("genre_name").toString());
|
||||
|
||||
return genreDTO;
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
#ifndef GENRES_REPOSITORY_H
|
||||
#define GENRES_REPOSITORY_H
|
||||
|
||||
#include "base_sql_table_repository.h"
|
||||
#include "genres_repository_interface.h"
|
||||
|
||||
#include <QSqlDatabase>
|
||||
|
||||
class GenresRepository : public GenresRepositoryInterface,
|
||||
public BaseSqlTableRepository {
|
||||
public:
|
||||
explicit GenresRepository(QSqlDatabase &database, QObject *parent);
|
||||
|
||||
// CRUD operations
|
||||
// clang-format off
|
||||
|
||||
RepositoryResult
|
||||
createGenre(const CreateGenreRequest &request) override;
|
||||
|
||||
RepositoryResult
|
||||
getGenreById(qint32 genreId, GenreDTO &genre) const override;
|
||||
|
||||
RepositoryResult
|
||||
getAllGenres(QVector<GenreDTO> &genres) const override;
|
||||
|
||||
RepositoryResult
|
||||
updateGenre(const UpdateGenreRequest &request) override;
|
||||
|
||||
RepositoryResult
|
||||
deleteGenreById(qint32 genreId) override;
|
||||
|
||||
// clang-format on
|
||||
|
||||
private:
|
||||
GenreDTO mapQueryToDTO(const QSqlQuery &query) const;
|
||||
};
|
||||
|
||||
#endif // GENRES_REPOSITORY_H
|
||||
@@ -0,0 +1,99 @@
|
||||
#include "halls_repository.h"
|
||||
|
||||
#include "create_hall_request.h"
|
||||
#include "hall_dto.h"
|
||||
#include "repository_result.h"
|
||||
#include "update_hall_request.h"
|
||||
#include <QSqlError>
|
||||
#include <QSqlQuery>
|
||||
|
||||
HallsRepository::HallsRepository(QSqlDatabase &database, QObject *parent)
|
||||
: BaseSqlTableRepository(database, parent) {}
|
||||
|
||||
RepositoryResult HallsRepository::createHall(const CreateHallRequest &request) {
|
||||
QSqlQuery query = foreignKeysOnQuery();
|
||||
query.prepare("INSERT INTO halls (hall_name, capacity) VALUES "
|
||||
"(:hall_name, :capacity)");
|
||||
query.bindValue(":hall_name", request.hallName());
|
||||
query.bindValue(":capacity", request.capacity());
|
||||
|
||||
if (!query.exec()) {
|
||||
return RepositoryResult::failureResult(query.lastError().text());
|
||||
}
|
||||
|
||||
emit dataCreated();
|
||||
return RepositoryResult::successResult();
|
||||
}
|
||||
|
||||
RepositoryResult HallsRepository::getHallById(qint32 id, HallDTO &hall) const {
|
||||
QSqlQuery query = foreignKeysOnQuery();
|
||||
query.prepare(
|
||||
"SELECT hall_id, hall_name, capacity FROM halls WHERE hall_id = :id");
|
||||
query.bindValue(":id", id);
|
||||
|
||||
if (!query.exec()) {
|
||||
return RepositoryResult::failureResult(query.lastError().text());
|
||||
}
|
||||
if (!query.next()) {
|
||||
return RepositoryResult::failureResult("Hall not found");
|
||||
}
|
||||
|
||||
hall = mapQueryToDTO(query);
|
||||
|
||||
emit dataRetrieved();
|
||||
return RepositoryResult::successResult();
|
||||
}
|
||||
|
||||
RepositoryResult HallsRepository::getAllHalls(QVector<HallDTO> &halls) const {
|
||||
QSqlQuery query = foreignKeysOnQuery();
|
||||
query.prepare("SELECT hall_id, hall_name, capacity FROM halls");
|
||||
|
||||
if (!query.exec()) {
|
||||
return RepositoryResult::failureResult(query.lastError().text());
|
||||
}
|
||||
|
||||
while (query.next()) {
|
||||
halls.append(mapQueryToDTO(query));
|
||||
}
|
||||
|
||||
emit dataRetrieved();
|
||||
return RepositoryResult::successResult();
|
||||
}
|
||||
|
||||
RepositoryResult HallsRepository::updateHall(const UpdateHallRequest &request) {
|
||||
QSqlQuery query = foreignKeysOnQuery();
|
||||
query.prepare("UPDATE halls SET hall_name = :hall_name, capacity = :capacity "
|
||||
"WHERE hall_id = :hall_id");
|
||||
query.bindValue(":capacity", request.capacity());
|
||||
query.bindValue(":hall_id", request.hallId());
|
||||
query.bindValue(":hall_name", request.hallName());
|
||||
|
||||
if (!query.exec()) {
|
||||
return RepositoryResult::failureResult(query.lastError().text());
|
||||
}
|
||||
|
||||
emit dataUpdated();
|
||||
return RepositoryResult::successResult();
|
||||
}
|
||||
|
||||
RepositoryResult HallsRepository::deleteHallById(qint32 hallId) {
|
||||
QSqlQuery query = foreignKeysOnQuery();
|
||||
query.prepare("DELETE FROM halls WHERE hall_id = :hall_id");
|
||||
query.bindValue(":hall_id", hallId);
|
||||
|
||||
if (!query.exec()) {
|
||||
return RepositoryResult::failureResult(query.lastError().text());
|
||||
}
|
||||
|
||||
emit dataDeleted();
|
||||
return RepositoryResult::successResult();
|
||||
}
|
||||
|
||||
HallDTO HallsRepository::mapQueryToDTO(const QSqlQuery &query) const {
|
||||
HallDTO hallDTO;
|
||||
hallDTO.setCapacity(query.value("capacity").toInt());
|
||||
hallDTO.setHallId(query.value("hall_id").toInt());
|
||||
hallDTO.setHallName(query.value("hall_name").toString());
|
||||
|
||||
return hallDTO;
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
#ifndef HALLS_REPOSITORY_H
|
||||
#define HALLS_REPOSITORY_H
|
||||
|
||||
#include "base_sql_table_repository.h"
|
||||
#include "halls_repository_interface.h"
|
||||
|
||||
#include <QSqlDatabase>
|
||||
#include <QVector>
|
||||
|
||||
class HallsRepository : public HallsRepositoryInterface,
|
||||
public BaseSqlTableRepository {
|
||||
public:
|
||||
explicit HallsRepository(QSqlDatabase &database, QObject *parent);
|
||||
|
||||
// CRUD operations
|
||||
// clang-format off
|
||||
|
||||
RepositoryResult
|
||||
createHall(const CreateHallRequest &request) override;
|
||||
|
||||
RepositoryResult
|
||||
getHallById(qint32 hallId, HallDTO &hall) const override;
|
||||
|
||||
RepositoryResult
|
||||
getAllHalls(QVector<HallDTO> &halls) const override;
|
||||
|
||||
RepositoryResult
|
||||
updateHall(const UpdateHallRequest &request) override;
|
||||
|
||||
RepositoryResult
|
||||
deleteHallById(qint32 hallId) override;
|
||||
|
||||
// clang-format on
|
||||
|
||||
private:
|
||||
HallDTO mapQueryToDTO(const QSqlQuery &query) const;
|
||||
};
|
||||
|
||||
#endif // HALLS_REPOSITORY_H
|
||||
@@ -0,0 +1,106 @@
|
||||
#include "movies_repository.h"
|
||||
|
||||
#include "create_movie_request.h"
|
||||
#include "movie_dto.h"
|
||||
#include "repository_result.h"
|
||||
#include "update_movie_request.h"
|
||||
#include <QSqlError>
|
||||
#include <QSqlQuery>
|
||||
|
||||
MoviesRepository::MoviesRepository(QSqlDatabase &database, QObject *parent)
|
||||
: BaseSqlTableRepository(database, parent) {}
|
||||
|
||||
RepositoryResult
|
||||
MoviesRepository::createMovie(const CreateMovieRequest &request) {
|
||||
QSqlQuery query = foreignKeysOnQuery();
|
||||
query.prepare("INSERT INTO movies (title, genre_id, duration) VALUES "
|
||||
"(:title, :genre_id, :duration)");
|
||||
query.bindValue(":title", request.title());
|
||||
query.bindValue(":genre_id", request.genreId());
|
||||
query.bindValue(":duration", request.duration());
|
||||
|
||||
if (!query.exec()) {
|
||||
return RepositoryResult::failureResult(query.lastError().text());
|
||||
}
|
||||
|
||||
emit dataCreated();
|
||||
return RepositoryResult::successResult();
|
||||
}
|
||||
|
||||
RepositoryResult
|
||||
MoviesRepository::getAllMovies(QVector<MovieDTO> &movies) const {
|
||||
QSqlQuery query = foreignKeysOnQuery();
|
||||
query.prepare("SELECT movie_id, title, genre_id, duration FROM movies");
|
||||
|
||||
if (!query.exec()) {
|
||||
return RepositoryResult::failureResult(query.lastError().text());
|
||||
}
|
||||
|
||||
while (query.next()) {
|
||||
movies.append(mapQueryToDTO(query));
|
||||
}
|
||||
|
||||
emit dataRetrieved();
|
||||
return RepositoryResult::successResult();
|
||||
}
|
||||
|
||||
RepositoryResult MoviesRepository::getMovieById(qint32 id,
|
||||
MovieDTO &movie) const {
|
||||
QSqlQuery query = foreignKeysOnQuery();
|
||||
query.prepare("SELECT movie_id, title, genre_id, duration FROM movies WHERE "
|
||||
"movie_id = :id");
|
||||
query.bindValue(":id", id);
|
||||
|
||||
if (!query.exec()) {
|
||||
return RepositoryResult::failureResult(query.lastError().text());
|
||||
}
|
||||
if (!query.next()) {
|
||||
return RepositoryResult::failureResult("Movie not found");
|
||||
}
|
||||
|
||||
movie = mapQueryToDTO(query);
|
||||
|
||||
emit dataRetrieved();
|
||||
return RepositoryResult::successResult();
|
||||
}
|
||||
|
||||
RepositoryResult
|
||||
MoviesRepository::updateMovie(const UpdateMovieRequest &request) {
|
||||
QSqlQuery query = foreignKeysOnQuery();
|
||||
query.prepare("UPDATE movies SET title = :title, genre_id = :genre_id, "
|
||||
"duration = :duration WHERE movie_id = :id");
|
||||
query.bindValue(":duration", request.duration());
|
||||
query.bindValue(":genre_id", request.genreId());
|
||||
query.bindValue(":id", request.movieId());
|
||||
query.bindValue(":title", request.title());
|
||||
|
||||
if (!query.exec()) {
|
||||
return RepositoryResult::failureResult(query.lastError().text());
|
||||
}
|
||||
|
||||
emit dataUpdated();
|
||||
return RepositoryResult::successResult();
|
||||
}
|
||||
|
||||
RepositoryResult MoviesRepository::deleteMovieById(qint32 movieId) {
|
||||
QSqlQuery query = foreignKeysOnQuery();
|
||||
query.prepare("DELETE FROM movies WHERE movie_id = :id");
|
||||
query.bindValue(":id", movieId);
|
||||
|
||||
if (!query.exec()) {
|
||||
return RepositoryResult::failureResult(query.lastError().text());
|
||||
}
|
||||
|
||||
emit dataDeleted();
|
||||
return RepositoryResult::successResult();
|
||||
}
|
||||
|
||||
MovieDTO MoviesRepository::mapQueryToDTO(const QSqlQuery &query) const {
|
||||
MovieDTO movieDTO;
|
||||
movieDTO.setDuration(query.value("duration").toInt());
|
||||
movieDTO.setGenreId(query.value("genre_id").toInt());
|
||||
movieDTO.setMovieId(query.value("movie_id").toInt());
|
||||
movieDTO.setTitle(query.value("title").toString());
|
||||
|
||||
return movieDTO;
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
#ifndef MOVIES_REPOSITORY_H
|
||||
#define MOVIES_REPOSITORY_H
|
||||
|
||||
#include "base_sql_table_repository.h"
|
||||
#include "movies_repository_interface.h"
|
||||
|
||||
#include <QSqlDatabase>
|
||||
|
||||
class MoviesRepository : public MoviesRepositoryInterface,
|
||||
public BaseSqlTableRepository {
|
||||
public:
|
||||
explicit MoviesRepository(QSqlDatabase &database, QObject *parent);
|
||||
|
||||
// CRUD operations
|
||||
// clang-format off
|
||||
|
||||
RepositoryResult
|
||||
createMovie(const CreateMovieRequest &request) override;
|
||||
|
||||
RepositoryResult
|
||||
getMovieById(qint32 movieId, MovieDTO &movie) const override;
|
||||
|
||||
RepositoryResult
|
||||
getAllMovies(QVector<MovieDTO> &movies) const override;
|
||||
|
||||
RepositoryResult
|
||||
updateMovie(const UpdateMovieRequest &request) override;
|
||||
|
||||
RepositoryResult
|
||||
deleteMovieById(qint32 movieId) override;
|
||||
|
||||
// clang-format on
|
||||
|
||||
private:
|
||||
MovieDTO mapQueryToDTO(const QSqlQuery &query) const;
|
||||
};
|
||||
|
||||
#endif // MOVIES_REPOSITORY_H
|
||||
@@ -0,0 +1,114 @@
|
||||
#include "refunds_repository.h"
|
||||
|
||||
#include "create_refund_request.h"
|
||||
#include "refund_dto.h"
|
||||
#include "repository_result.h"
|
||||
#include "update_refund_request.h"
|
||||
#include <QSqlError>
|
||||
#include <QSqlQuery>
|
||||
|
||||
RefundsRepository::RefundsRepository(QSqlDatabase &database, QObject *parent)
|
||||
: BaseSqlTableRepository(database, parent) {}
|
||||
|
||||
RepositoryResult
|
||||
RefundsRepository::createRefund(const CreateRefundRequest &request) {
|
||||
QSqlQuery query = foreignKeysOnQuery();
|
||||
query.prepare("INSERT INTO refunds (ticket_id, refund_at, refund_amount) "
|
||||
"VALUES (:ticket_id, :refund_at, :refund_amount)");
|
||||
query.bindValue(":ticket_id", request.ticketId());
|
||||
query.bindValue(":refund_at", request.refundAt());
|
||||
query.bindValue(":refund_amount", request.refundAmount());
|
||||
|
||||
if (!query.exec()) {
|
||||
return RepositoryResult::failureResult(query.lastError().text());
|
||||
}
|
||||
|
||||
emit dataCreated();
|
||||
return RepositoryResult::successResult();
|
||||
}
|
||||
|
||||
RepositoryResult RefundsRepository::getRefundById(qint32 id,
|
||||
RefundDTO &refund) const {
|
||||
QSqlQuery query = foreignKeysOnQuery();
|
||||
query.prepare("SELECT refund_id, ticket_id, refund_at, refund_amount FROM "
|
||||
"refunds WHERE refund_id = :id");
|
||||
query.bindValue(":id", id);
|
||||
|
||||
if (!query.exec()) {
|
||||
return RepositoryResult::failureResult(query.lastError().text());
|
||||
}
|
||||
if (!query.next()) {
|
||||
return RepositoryResult::failureResult("Refund not found");
|
||||
}
|
||||
|
||||
RefundDTO refundDTO;
|
||||
refundDTO.setRefundAmount(query.value("refund_amount").toDouble());
|
||||
refundDTO.setRefundAt(query.value("refund_at").toDateTime());
|
||||
refundDTO.setRefundId(query.value("refund_id").toInt());
|
||||
refundDTO.setTicketId(query.value("ticket_id").toInt());
|
||||
|
||||
refund = mapQueryToDTO(query);
|
||||
|
||||
emit dataRetrieved();
|
||||
return RepositoryResult::successResult();
|
||||
}
|
||||
|
||||
RepositoryResult
|
||||
RefundsRepository::getAllRefunds(QVector<RefundDTO> &refunds) const {
|
||||
QSqlQuery query = foreignKeysOnQuery();
|
||||
query.prepare(
|
||||
"SELECT refund_id, ticket_id, refund_at, refund_amount FROM refunds");
|
||||
|
||||
if (!query.exec()) {
|
||||
return RepositoryResult::failureResult(query.lastError().text());
|
||||
}
|
||||
|
||||
while (query.next()) {
|
||||
refunds.append(mapQueryToDTO(query));
|
||||
}
|
||||
|
||||
emit dataRetrieved();
|
||||
return RepositoryResult::successResult();
|
||||
}
|
||||
|
||||
RepositoryResult
|
||||
RefundsRepository::updateRefund(const UpdateRefundRequest &request) {
|
||||
QSqlQuery query = foreignKeysOnQuery();
|
||||
query.prepare(
|
||||
"UPDATE refunds SET ticket_id = :ticket_id, refund_at = :refund_at, "
|
||||
"refund_amount = :refund_amount WHERE refund_id = :refund_id");
|
||||
query.bindValue(":refund_amount", request.refundAmount());
|
||||
query.bindValue(":refund_at", request.refundAt());
|
||||
query.bindValue(":refund_id", request.refundId());
|
||||
query.bindValue(":ticket_id", request.ticketId());
|
||||
|
||||
if (!query.exec()) {
|
||||
return RepositoryResult::failureResult(query.lastError().text());
|
||||
}
|
||||
|
||||
emit dataUpdated();
|
||||
return RepositoryResult::successResult();
|
||||
}
|
||||
|
||||
RepositoryResult RefundsRepository::deleteRefundById(qint32 refundId) {
|
||||
QSqlQuery query = foreignKeysOnQuery();
|
||||
query.prepare("DELETE FROM refunds WHERE refund_id = :refund_id");
|
||||
query.bindValue(":refund_id", refundId);
|
||||
|
||||
if (!query.exec()) {
|
||||
return RepositoryResult::failureResult(query.lastError().text());
|
||||
}
|
||||
|
||||
emit dataDeleted();
|
||||
return RepositoryResult::successResult();
|
||||
}
|
||||
|
||||
RefundDTO RefundsRepository::mapQueryToDTO(const QSqlQuery &query) const {
|
||||
RefundDTO refundDTO;
|
||||
refundDTO.setRefundAmount(query.value("refund_amount").toDouble());
|
||||
refundDTO.setRefundAt(query.value("refund_at").toDateTime());
|
||||
refundDTO.setRefundId(query.value("refund_id").toInt());
|
||||
refundDTO.setTicketId(query.value("ticket_id").toInt());
|
||||
|
||||
return refundDTO;
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
#ifndef REFUNDS_REPOSITORY_H
|
||||
#define REFUNDS_REPOSITORY_H
|
||||
|
||||
#include "base_sql_table_repository.h"
|
||||
#include "refunds_repository_interface.h"
|
||||
|
||||
#include <QSqlDatabase>
|
||||
|
||||
class RefundsRepository : public RefundsRepositoryInterface,
|
||||
public BaseSqlTableRepository {
|
||||
public:
|
||||
explicit RefundsRepository(QSqlDatabase &database, QObject *parent);
|
||||
|
||||
// CRUD operations
|
||||
// clang-format off
|
||||
|
||||
RepositoryResult
|
||||
createRefund(const CreateRefundRequest &request) override;
|
||||
|
||||
RepositoryResult
|
||||
getRefundById(qint32 refundId, RefundDTO &refund) const override;
|
||||
|
||||
RepositoryResult
|
||||
getAllRefunds(QVector<RefundDTO> &refunds) const override;
|
||||
|
||||
RepositoryResult
|
||||
updateRefund(const UpdateRefundRequest &request) override;
|
||||
|
||||
RepositoryResult
|
||||
deleteRefundById(qint32 refundId) override;
|
||||
|
||||
// clang-format on
|
||||
private:
|
||||
RefundDTO mapQueryToDTO(const QSqlQuery &query) const;
|
||||
};
|
||||
|
||||
#endif // REFUNDS_REPOSITORY_H
|
||||
@@ -0,0 +1,98 @@
|
||||
#include "roles_repository.h"
|
||||
|
||||
#include "create_role_request.h"
|
||||
#include "repository_result.h"
|
||||
#include "role_dto.h"
|
||||
#include "update_role_request.h"
|
||||
#include <QSqlError>
|
||||
#include <QSqlQuery>
|
||||
|
||||
RolesRepository::RolesRepository(QSqlDatabase &database, QObject *parent)
|
||||
: BaseSqlTableRepository(database, parent) {}
|
||||
|
||||
RepositoryResult RolesRepository::createRole(const CreateRoleRequest &request) {
|
||||
QSqlQuery query = foreignKeysOnQuery();
|
||||
query.prepare("INSERT INTO roles (role_name, access_level) VALUES "
|
||||
"(:role_name, :access_level)");
|
||||
query.bindValue(":role_name", request.roleName());
|
||||
query.bindValue(":access_level", request.accessLevel());
|
||||
|
||||
if (!query.exec()) {
|
||||
return RepositoryResult::failureResult(query.lastError().text());
|
||||
}
|
||||
|
||||
emit dataCreated();
|
||||
return RepositoryResult::successResult();
|
||||
}
|
||||
|
||||
RepositoryResult RolesRepository::getRoleById(qint32 id, RoleDTO &role) const {
|
||||
QSqlQuery query = foreignKeysOnQuery();
|
||||
query.prepare("SELECT role_id, role_name, access_level FROM roles WHERE "
|
||||
"role_id = :role_id");
|
||||
query.bindValue(":role_id", id);
|
||||
|
||||
if (!query.exec()) {
|
||||
return RepositoryResult::failureResult(query.lastError().text());
|
||||
}
|
||||
if (!query.next()) {
|
||||
return RepositoryResult::failureResult("Role not found");
|
||||
}
|
||||
|
||||
role = mapQueryToDTO(query);
|
||||
|
||||
emit dataRetrieved();
|
||||
return RepositoryResult::successResult();
|
||||
}
|
||||
|
||||
RepositoryResult RolesRepository::getAllRoles(QVector<RoleDTO> &roles) const {
|
||||
QSqlQuery query = foreignKeysOnQuery();
|
||||
query.prepare("SELECT role_id, role_name, access_level FROM roles");
|
||||
|
||||
if (!query.exec()) {
|
||||
return RepositoryResult::failureResult(query.lastError().text());
|
||||
}
|
||||
|
||||
while (query.next()) {
|
||||
roles.append(mapQueryToDTO(query));
|
||||
}
|
||||
|
||||
emit dataRetrieved();
|
||||
return RepositoryResult::successResult();
|
||||
}
|
||||
|
||||
RepositoryResult RolesRepository::updateRole(const UpdateRoleRequest &request) {
|
||||
QSqlQuery query = foreignKeysOnQuery();
|
||||
query.prepare(
|
||||
"UPDATE roles SET role_name = :role_name WHERE role_id = :role_id");
|
||||
query.bindValue(":role_name", request.roleName());
|
||||
query.bindValue(":role_id", request.roleId());
|
||||
|
||||
if (!query.exec()) {
|
||||
return RepositoryResult::failureResult(query.lastError().text());
|
||||
}
|
||||
|
||||
emit dataUpdated();
|
||||
return RepositoryResult::successResult();
|
||||
}
|
||||
|
||||
RepositoryResult RolesRepository::deleteRoleById(qint32 roleId) {
|
||||
QSqlQuery query = foreignKeysOnQuery();
|
||||
query.prepare("DELETE FROM roles WHERE role_id = :role_id");
|
||||
query.bindValue(":role_id", roleId);
|
||||
|
||||
if (!query.exec()) {
|
||||
return RepositoryResult::failureResult(query.lastError().text());
|
||||
}
|
||||
|
||||
emit dataDeleted();
|
||||
return RepositoryResult::successResult();
|
||||
}
|
||||
|
||||
RoleDTO RolesRepository::mapQueryToDTO(const QSqlQuery &query) const {
|
||||
RoleDTO roleDTO;
|
||||
roleDTO.setAccessLevel(query.value("access_level").toInt());
|
||||
roleDTO.setRoleId(query.value("role_id").toInt());
|
||||
roleDTO.setRoleName(query.value("role_name").toString());
|
||||
|
||||
return roleDTO;
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
#ifndef ROLES_REPOSITORY_H
|
||||
#define ROLES_REPOSITORY_H
|
||||
|
||||
#include "base_sql_table_repository.h"
|
||||
#include "roles_repository_interface.h"
|
||||
|
||||
#include <QSqlDatabase>
|
||||
|
||||
class RolesRepository : public RolesRepositoryInterface,
|
||||
public BaseSqlTableRepository {
|
||||
public:
|
||||
explicit RolesRepository(QSqlDatabase &database, QObject *parent);
|
||||
|
||||
// CRUD operations
|
||||
// clang-format off
|
||||
|
||||
RepositoryResult
|
||||
createRole(const CreateRoleRequest &request) override;
|
||||
|
||||
RepositoryResult
|
||||
getRoleById(qint32 roleId, RoleDTO &role) const override;
|
||||
|
||||
RepositoryResult
|
||||
getAllRoles(QVector<RoleDTO> &roles) const override;
|
||||
|
||||
RepositoryResult
|
||||
updateRole(const UpdateRoleRequest &request) override;
|
||||
|
||||
RepositoryResult
|
||||
deleteRoleById(qint32 roleId) override;
|
||||
|
||||
// clang-format on
|
||||
|
||||
private:
|
||||
RoleDTO mapQueryToDTO(const QSqlQuery &query) const;
|
||||
};
|
||||
|
||||
#endif // ROLES_REPOSITORY_H
|
||||
@@ -0,0 +1,112 @@
|
||||
#include "sessions_repository.h"
|
||||
|
||||
#include "create_session_request.h"
|
||||
#include "repository_result.h"
|
||||
#include "session_dto.h"
|
||||
#include "update_session_request.h"
|
||||
#include <QSqlError>
|
||||
#include <QSqlQuery>
|
||||
|
||||
SessionsRepository::SessionsRepository(QSqlDatabase &database, QObject *parent)
|
||||
: BaseSqlTableRepository(database, parent) {}
|
||||
|
||||
RepositoryResult
|
||||
SessionsRepository::createSession(const CreateSessionRequest &request) {
|
||||
QSqlQuery query = foreignKeysOnQuery();
|
||||
query.prepare(
|
||||
"INSERT INTO sessions (movie_id, hall_id, begin_at, ticket_price) VALUES "
|
||||
"(:movie_id, :hall_id, :begin_at, :ticket_price)");
|
||||
query.bindValue(":begin_at", request.beginAt());
|
||||
query.bindValue(":hall_id", request.hallId());
|
||||
query.bindValue(":movie_id", request.movieId());
|
||||
query.bindValue(":ticket_price", request.ticketPrice());
|
||||
|
||||
if (!query.exec()) {
|
||||
return RepositoryResult::failureResult(query.lastError().text());
|
||||
}
|
||||
|
||||
emit dataCreated();
|
||||
return RepositoryResult::successResult();
|
||||
}
|
||||
|
||||
RepositoryResult SessionsRepository::getSessionById(qint32 id,
|
||||
SessionDTO &session) const {
|
||||
QSqlQuery query = foreignKeysOnQuery();
|
||||
query.prepare("SELECT session_id, movie_id, hall_id, begin_at, ticket_price "
|
||||
"FROM sessions WHERE session_id = :id");
|
||||
query.bindValue(":id", id);
|
||||
|
||||
if (!query.exec()) {
|
||||
return RepositoryResult::failureResult(query.lastError().text());
|
||||
}
|
||||
if (!query.next()) {
|
||||
return RepositoryResult::failureResult("Session not found");
|
||||
}
|
||||
|
||||
session = mapQueryToDTO(query);
|
||||
|
||||
emit dataRetrieved();
|
||||
return RepositoryResult::successResult();
|
||||
}
|
||||
|
||||
RepositoryResult
|
||||
SessionsRepository::getAllSessions(QVector<SessionDTO> &sessions) const {
|
||||
QSqlQuery query = foreignKeysOnQuery();
|
||||
query.prepare("SELECT session_id, movie_id, hall_id, begin_at, ticket_price "
|
||||
"FROM sessions");
|
||||
|
||||
if (!query.exec()) {
|
||||
return RepositoryResult::failureResult(query.lastError().text());
|
||||
}
|
||||
|
||||
while (query.next()) {
|
||||
sessions.append(mapQueryToDTO(query));
|
||||
}
|
||||
|
||||
emit dataRetrieved();
|
||||
return RepositoryResult::successResult();
|
||||
}
|
||||
|
||||
RepositoryResult
|
||||
SessionsRepository::updateSession(const UpdateSessionRequest &request) {
|
||||
QSqlQuery query = foreignKeysOnQuery();
|
||||
query.prepare("UPDATE sessions SET movie_id = :movie_id, hall_id = :hall_id, "
|
||||
"begin_at = :begin_at, ticket_price = :ticket_price WHERE "
|
||||
"session_id = :session_id");
|
||||
query.bindValue(":begin_at", request.beginAt());
|
||||
query.bindValue(":hall_id", request.hallId());
|
||||
query.bindValue(":movie_id", request.movieId());
|
||||
query.bindValue(":session_id", request.sessionId());
|
||||
query.bindValue(":ticket_price", request.ticketPrice());
|
||||
|
||||
if (!query.exec()) {
|
||||
return RepositoryResult::failureResult(query.lastError().text());
|
||||
}
|
||||
|
||||
emit dataUpdated();
|
||||
return RepositoryResult::successResult();
|
||||
}
|
||||
|
||||
RepositoryResult SessionsRepository::deleteSessionById(qint32 sessionId) {
|
||||
QSqlQuery query = foreignKeysOnQuery();
|
||||
query.prepare("DELETE FROM sessions WHERE session_id = :session_id");
|
||||
query.bindValue(":session_id", sessionId);
|
||||
|
||||
if (!query.exec()) {
|
||||
return RepositoryResult::failureResult(query.lastError().text());
|
||||
}
|
||||
|
||||
emit dataDeleted();
|
||||
return RepositoryResult::successResult();
|
||||
}
|
||||
|
||||
SessionDTO SessionsRepository::mapQueryToDTO(const QSqlQuery &query) const {
|
||||
SessionDTO sessionDTO;
|
||||
sessionDTO.setBeginAt(query.value("begin_at").toDateTime());
|
||||
sessionDTO.setHallId(query.value("hall_id").toInt());
|
||||
sessionDTO.setMovieId(query.value("movie_id").toInt());
|
||||
sessionDTO.setSessionId(query.value("session_id").toInt());
|
||||
sessionDTO.setTicketPrice(query.value("ticket_price").toDouble());
|
||||
|
||||
return sessionDTO;
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
#ifndef SESSIONS_REPOSITORY_H
|
||||
#define SESSIONS_REPOSITORY_H
|
||||
|
||||
#include "base_sql_table_repository.h"
|
||||
#include "sessions_repository_interface.h"
|
||||
|
||||
#include <QSqlDatabase>
|
||||
|
||||
class SessionsRepository : public SessionsRepositoryInterface,
|
||||
public BaseSqlTableRepository {
|
||||
public:
|
||||
explicit SessionsRepository(QSqlDatabase &database, QObject *parent);
|
||||
|
||||
// CRUD operations
|
||||
// clang-format off
|
||||
|
||||
RepositoryResult
|
||||
createSession(const CreateSessionRequest &request) override;
|
||||
|
||||
RepositoryResult
|
||||
getSessionById(qint32 sessionId, SessionDTO &session) const override;
|
||||
|
||||
RepositoryResult
|
||||
getAllSessions(QVector<SessionDTO> &sessions) const override;
|
||||
|
||||
RepositoryResult
|
||||
updateSession(const UpdateSessionRequest &request) override;
|
||||
|
||||
RepositoryResult
|
||||
deleteSessionById(qint32 sessionId) override;
|
||||
|
||||
// clang-format on
|
||||
|
||||
private:
|
||||
SessionDTO mapQueryToDTO(const QSqlQuery &query) const;
|
||||
};
|
||||
|
||||
#endif // SESSIONS_REPOSITORY_H
|
||||
@@ -0,0 +1,169 @@
|
||||
#include "sessions_statistics_repository.h"
|
||||
|
||||
#include "repository_result.h"
|
||||
#include "session_statistics_dto.h"
|
||||
|
||||
#include <QSqlError>
|
||||
#include <QSqlQuery>
|
||||
#include <QVariant>
|
||||
#include <QVector>
|
||||
|
||||
SessionsStatisticsRepository::SessionsStatisticsRepository(
|
||||
QSqlDatabase &database, QObject *parent)
|
||||
: BaseSqlTableRepository(database, parent) {}
|
||||
|
||||
SessionStatisticsDTO
|
||||
SessionsStatisticsRepository::mapQueryToDTO(const QSqlQuery &query) const {
|
||||
SessionStatisticsDTO sessionStatisticsDTO;
|
||||
|
||||
// clang-format off
|
||||
sessionStatisticsDTO.setSessionId(query.value("session_id").toInt());
|
||||
sessionStatisticsDTO.setBeginAt(query.value("begin_at").toDateTime());
|
||||
sessionStatisticsDTO.setTicketPrice(query.value("ticket_price").toDouble());
|
||||
sessionStatisticsDTO.setHallId(query.value("hall_id").toInt());
|
||||
sessionStatisticsDTO.setHallName(query.value("hall_name").toString());
|
||||
sessionStatisticsDTO.setTotalSeats(query.value("total_seats").toInt());
|
||||
sessionStatisticsDTO.setMovieId(query.value("movie_id").toInt());
|
||||
sessionStatisticsDTO.setMovieTitle(query.value("movie_title").toString());
|
||||
sessionStatisticsDTO.setDuration(query.value("duration").toInt());
|
||||
sessionStatisticsDTO.setGenreId(query.value("genre_id").toInt());
|
||||
sessionStatisticsDTO.setGenreName(query.value("genre_name").toString());
|
||||
sessionStatisticsDTO.setSoldTickets(query.value("sold_tickets").toInt());
|
||||
sessionStatisticsDTO.setRefundedTickets( query.value("refunded_tickets").toInt());
|
||||
sessionStatisticsDTO.setSalesRevenue(query.value("sales_revenue").toDouble());
|
||||
sessionStatisticsDTO.setRefundExpenses( query.value("refund_expenses").toDouble());
|
||||
// clang-format on
|
||||
|
||||
return sessionStatisticsDTO;
|
||||
}
|
||||
|
||||
RepositoryResult SessionsStatisticsRepository::executeAndMapQuery(
|
||||
QSqlQuery &query, QVector<SessionStatisticsDTO> &sessions) const {
|
||||
|
||||
qInfo() << "Executing query:" << query.executedQuery()
|
||||
<< " with values:" << query.boundValues();
|
||||
|
||||
if (!query.exec()) {
|
||||
return RepositoryResult::failureResult(query.lastError().text());
|
||||
}
|
||||
|
||||
while (query.next()) {
|
||||
sessions.append(mapQueryToDTO(query));
|
||||
}
|
||||
|
||||
emit dataRetrieved();
|
||||
return RepositoryResult::successResult();
|
||||
}
|
||||
|
||||
RepositoryResult SessionsStatisticsRepository::getSessionById(
|
||||
qint32 id, SessionStatisticsDTO &sessionStatisticsDTO) const {
|
||||
QSqlQuery query = foreignKeysOnQuery();
|
||||
query.prepare(QString("%1 WHERE session_id = :id").arg(SELECT_QUERY));
|
||||
query.bindValue(":id", id);
|
||||
|
||||
if (!query.exec()) {
|
||||
return RepositoryResult::failureResult(query.lastError().text());
|
||||
}
|
||||
if (!query.next()) {
|
||||
return RepositoryResult::failureResult("Session not found");
|
||||
}
|
||||
|
||||
sessionStatisticsDTO = mapQueryToDTO(query);
|
||||
|
||||
emit dataRetrieved();
|
||||
return RepositoryResult::successResult();
|
||||
}
|
||||
|
||||
RepositoryResult SessionsStatisticsRepository::getAllSessions(
|
||||
QVector<SessionStatisticsDTO> &sessions) const {
|
||||
QSqlQuery query = foreignKeysOnQuery();
|
||||
query.prepare(SELECT_QUERY);
|
||||
|
||||
if (!query.exec()) {
|
||||
return RepositoryResult::failureResult(query.lastError().text());
|
||||
}
|
||||
|
||||
while (query.next()) {
|
||||
sessions.append(mapQueryToDTO(query));
|
||||
}
|
||||
|
||||
emit dataRetrieved();
|
||||
return RepositoryResult::successResult();
|
||||
}
|
||||
|
||||
RepositoryResult SessionsStatisticsRepository::getSessionsForHall(
|
||||
qint32 hallId, std::optional<QDateTime> startDate,
|
||||
std::optional<QDateTime> endDate,
|
||||
QVector<SessionStatisticsDTO> &sessions) const {
|
||||
QSqlQuery query = foreignKeysOnQuery();
|
||||
QString queryString =
|
||||
QString("%1 WHERE hall_id = :hall_id").arg(SELECT_QUERY);
|
||||
|
||||
bindDateFilters(queryString, startDate, endDate);
|
||||
|
||||
query.prepare(queryString);
|
||||
query.bindValue(":hall_id", hallId);
|
||||
|
||||
bindDateValues(query, startDate, endDate);
|
||||
|
||||
return executeAndMapQuery(query, sessions);
|
||||
}
|
||||
|
||||
RepositoryResult SessionsStatisticsRepository::getSessionsForMovie(
|
||||
qint32 movieId, std::optional<QDateTime> startDate,
|
||||
std::optional<QDateTime> endDate,
|
||||
QVector<SessionStatisticsDTO> &sessions) const {
|
||||
QSqlQuery query = foreignKeysOnQuery();
|
||||
QString queryString =
|
||||
QString("%1 WHERE movie_id = :movie_id").arg(SELECT_QUERY);
|
||||
|
||||
bindDateFilters(queryString, startDate, endDate);
|
||||
|
||||
query.prepare(queryString);
|
||||
query.bindValue(":movie_id", movieId);
|
||||
|
||||
bindDateValues(query, startDate, endDate);
|
||||
|
||||
return executeAndMapQuery(query, sessions);
|
||||
}
|
||||
|
||||
RepositoryResult SessionsStatisticsRepository::getSessionsForGenre(
|
||||
qint32 genreId, std::optional<QDateTime> startDate,
|
||||
std::optional<QDateTime> endDate,
|
||||
QVector<SessionStatisticsDTO> &sessions) const {
|
||||
QSqlQuery query = foreignKeysOnQuery();
|
||||
QString queryString =
|
||||
QString("%1 WHERE genre_id = :genre_id").arg(SELECT_QUERY);
|
||||
|
||||
bindDateFilters(queryString, startDate, endDate);
|
||||
|
||||
query.prepare(queryString);
|
||||
query.bindValue(":genre_id", genreId);
|
||||
|
||||
bindDateValues(query, startDate, endDate);
|
||||
|
||||
return executeAndMapQuery(query, sessions);
|
||||
}
|
||||
|
||||
void SessionsStatisticsRepository::bindDateFilters(
|
||||
QString &queryString, const std::optional<QDateTime> &startDate,
|
||||
const std::optional<QDateTime> &endDate) const {
|
||||
if (startDate && endDate) {
|
||||
queryString += " AND begin_at BETWEEN :start_date AND :end_date";
|
||||
} else if (startDate) {
|
||||
queryString += " AND begin_at >= :start_date";
|
||||
} else if (endDate) {
|
||||
queryString += " AND begin_at <= :end_date";
|
||||
}
|
||||
}
|
||||
|
||||
void SessionsStatisticsRepository::bindDateValues(
|
||||
QSqlQuery &query, const std::optional<QDateTime> &startDate,
|
||||
const std::optional<QDateTime> &endDate) const {
|
||||
if (startDate) {
|
||||
query.bindValue(":start_date", *startDate);
|
||||
}
|
||||
if (endDate) {
|
||||
query.bindValue(":end_date", *endDate);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
#ifndef SESSION_INFO_REPOSITORY_H
|
||||
#define SESSION_INFO_REPOSITORY_H
|
||||
|
||||
#include "base_sql_table_repository.h"
|
||||
#include "sessions_statistics_repository_interface.h"
|
||||
|
||||
#include <QSqlDatabase>
|
||||
#include <optional>
|
||||
|
||||
class SessionsStatisticsRepository
|
||||
: public SessionsStatisticsRepositoryInterface,
|
||||
public BaseSqlTableRepository {
|
||||
private:
|
||||
static constexpr const char *SELECT_QUERY =
|
||||
"SELECT session_id, begin_at, ticket_price, hall_id, hall_name, "
|
||||
"total_seats, movie_id, movie_title, duration, genre_id, genre_name, "
|
||||
"sold_tickets, refunded_tickets, sales_revenue, refund_expenses FROM "
|
||||
"sessions_statistics";
|
||||
|
||||
// Overrides methods from SessionsStatisticRepositoryInterface
|
||||
public:
|
||||
explicit SessionsStatisticsRepository(QSqlDatabase &database,
|
||||
QObject *parent);
|
||||
|
||||
RepositoryResult
|
||||
getSessionById(qint32 sessionId,
|
||||
SessionStatisticsDTO &sessionStatistics) const override;
|
||||
|
||||
RepositoryResult
|
||||
getAllSessions(QVector<SessionStatisticsDTO> &sessions) const override;
|
||||
|
||||
// New methods
|
||||
public:
|
||||
RepositoryResult
|
||||
getSessionsForGenre(qint32 genreName, std::optional<QDateTime> startDate,
|
||||
std::optional<QDateTime> endDate,
|
||||
QVector<SessionStatisticsDTO> &sessions) const override;
|
||||
|
||||
RepositoryResult
|
||||
getSessionsForHall(qint32 hallId, std::optional<QDateTime> startDate,
|
||||
std::optional<QDateTime> endDate,
|
||||
QVector<SessionStatisticsDTO> &sessions) const override;
|
||||
|
||||
RepositoryResult
|
||||
getSessionsForMovie(qint32 movieId, std::optional<QDateTime> startDate,
|
||||
std::optional<QDateTime> endDate,
|
||||
QVector<SessionStatisticsDTO> &sessions) const override;
|
||||
|
||||
private:
|
||||
SessionStatisticsDTO mapQueryToDTO(const QSqlQuery &query) const;
|
||||
|
||||
void bindDateFilters(QString &queryString,
|
||||
const std::optional<QDateTime> &startDate,
|
||||
const std::optional<QDateTime> &endDate) const;
|
||||
|
||||
void bindDateValues(QSqlQuery &query,
|
||||
const std::optional<QDateTime> &startDate,
|
||||
const std::optional<QDateTime> &endDate) const;
|
||||
|
||||
RepositoryResult
|
||||
executeAndMapQuery(QSqlQuery &query,
|
||||
QVector<SessionStatisticsDTO> &sessions) const;
|
||||
};
|
||||
|
||||
#endif // SESSION_INFO_REPOSITORY_H
|
||||
@@ -0,0 +1,138 @@
|
||||
#include "table_info_sqlite.h"
|
||||
|
||||
#include <QDebug>
|
||||
#include <QMetaType>
|
||||
#include <QSqlError>
|
||||
|
||||
TableInfoSQLite::TableInfoSQLite() : databaseTableName_("") {}
|
||||
|
||||
TableInfoSQLite::TableInfoSQLite(const QString &databaseTableName)
|
||||
: databaseTableName_(databaseTableName) {
|
||||
loadColumnInfo();
|
||||
}
|
||||
|
||||
void TableInfoSQLite::loadColumnInfo() {
|
||||
QSqlDatabase defaultDatabase = QSqlDatabase::database();
|
||||
|
||||
if (!defaultDatabase.isValid()) {
|
||||
qCritical() << "TableInfoSQLite::loadColumnInfo: Database is invalid";
|
||||
}
|
||||
|
||||
if (!defaultDatabase.isOpen()) {
|
||||
qCritical() << "TableInfoSQLite::loadColumnInfo: Database is not open";
|
||||
|
||||
databaseTableName_.clear();
|
||||
columnNames_.clear();
|
||||
columnTypes_.clear();
|
||||
isPrimaryKey_.clear();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
QSqlQuery query(defaultDatabase);
|
||||
query.prepare(QString("PRAGMA table_info(%1)").arg(databaseTableName_));
|
||||
|
||||
if (!query.exec()) {
|
||||
qWarning() << "Failed to get table info: Error:" << query.lastError().text()
|
||||
<< "Database table name:" << databaseTableName_;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
while (query.next()) {
|
||||
columnNames_.append(query.value("name").toString());
|
||||
columnTypes_.append(query.value("type").toString());
|
||||
isPrimaryKey_.append(query.value("pk").toInt() > 0);
|
||||
}
|
||||
}
|
||||
|
||||
QString TableInfoSQLite::databaseTableName() const noexcept {
|
||||
return databaseTableName_;
|
||||
}
|
||||
|
||||
QString
|
||||
TableInfoSQLite::foreignKeyTable(const QString &columnName) const noexcept {
|
||||
if (databaseTableName_.isEmpty()) {
|
||||
qWarning() << "TableInfoSQLite::foreignKeyTable: No table name set";
|
||||
return QString();
|
||||
}
|
||||
|
||||
QSqlDatabase defaultDatabase = QSqlDatabase::database();
|
||||
if (!defaultDatabase.isOpen()) {
|
||||
qCritical() << "TableInfoSQLite::foreignKeyTable: Database is not open";
|
||||
return QString();
|
||||
}
|
||||
|
||||
QSqlQuery query(defaultDatabase);
|
||||
query.prepare(QString("PRAGMA foreign_key_list(%1)").arg(databaseTableName_));
|
||||
|
||||
if (!query.exec()) {
|
||||
qWarning() << "Failed to get foreign key info:" << query.lastError().text();
|
||||
return QString();
|
||||
}
|
||||
|
||||
while (query.next()) {
|
||||
QString fkColumn = query.value("from").toString();
|
||||
QString referencedTable = query.value("table").toString();
|
||||
|
||||
if (fkColumn == columnName) {
|
||||
return referencedTable;
|
||||
}
|
||||
}
|
||||
|
||||
return QString();
|
||||
}
|
||||
|
||||
QStringList TableInfoSQLite::columnNames() const noexcept {
|
||||
return QStringList(columnNames_.begin(), columnNames_.end());
|
||||
}
|
||||
|
||||
bool TableInfoSQLite::isPrimaryKey(const QString &columnName) const noexcept {
|
||||
int index = columnIndex(columnName);
|
||||
if (index == -1) {
|
||||
return false;
|
||||
}
|
||||
return isPrimaryKey_.at(index);
|
||||
}
|
||||
|
||||
qint32 TableInfoSQLite::columnIndex(const QString &columnName) const noexcept {
|
||||
return columnNames_.indexOf(columnName);
|
||||
}
|
||||
|
||||
QString TableInfoSQLite::columnName(qint32 columnIndex) const noexcept {
|
||||
if (columnIndex < 0 || columnIndex >= columnNames_.size()) {
|
||||
return QString();
|
||||
}
|
||||
return columnNames_.at(columnIndex);
|
||||
}
|
||||
|
||||
QMetaType::Type
|
||||
TableInfoSQLite::columnMetaType(const QString &columnName) const noexcept {
|
||||
int index = columnIndex(columnName);
|
||||
if (index == -1) {
|
||||
return QMetaType::UnknownType;
|
||||
}
|
||||
|
||||
QString typeName = columnTypes_.at(index).toLower();
|
||||
|
||||
if (typeName.contains("int")) {
|
||||
return QMetaType::Int;
|
||||
} else if (typeName.contains("double") || typeName.contains("real") ||
|
||||
typeName.contains("float")) {
|
||||
return QMetaType::Double;
|
||||
} else if (typeName.contains("date") || typeName.contains("time")) {
|
||||
return QMetaType::QDateTime;
|
||||
} else if (typeName.contains("bool")) {
|
||||
return QMetaType::Bool;
|
||||
} else if (typeName.contains("blob")) {
|
||||
return QMetaType::QByteArray;
|
||||
} else {
|
||||
return QMetaType::QString;
|
||||
}
|
||||
}
|
||||
|
||||
void TableInfoSQLite::setDatabaseTableName(
|
||||
const QString &databaseTableName) noexcept {
|
||||
databaseTableName_ = databaseTableName;
|
||||
loadColumnInfo();
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
#ifndef TABLE_INFO_SQLITE_H
|
||||
#define TABLE_INFO_SQLITE_H
|
||||
|
||||
#include "table_info_interface.h"
|
||||
#include <QMetaType>
|
||||
#include <QSqlDatabase>
|
||||
#include <QSqlQuery>
|
||||
#include <QSqlRecord>
|
||||
#include <QStringList>
|
||||
#include <QVector>
|
||||
|
||||
class TableInfoSQLite : public TableInfoInterface {
|
||||
private:
|
||||
QString databaseTableName_;
|
||||
QVector<QString> columnNames_;
|
||||
QVector<QString> columnTypes_;
|
||||
QVector<bool> isPrimaryKey_;
|
||||
|
||||
public:
|
||||
explicit TableInfoSQLite();
|
||||
explicit TableInfoSQLite(const QString &databaseTableName);
|
||||
~TableInfoSQLite() override = default;
|
||||
|
||||
QMetaType::Type
|
||||
columnMetaType(const QString &columnName) const noexcept override;
|
||||
|
||||
QString columnName(int columnIndex) const noexcept override;
|
||||
|
||||
QString databaseTableName() const noexcept override;
|
||||
|
||||
QString foreignKeyTable(const QString &columnName) const noexcept;
|
||||
|
||||
QStringList columnNames() const noexcept override;
|
||||
|
||||
bool isPrimaryKey(const QString &columnName) const noexcept;
|
||||
|
||||
int columnIndex(const QString &columnName) const noexcept override;
|
||||
|
||||
void
|
||||
setDatabaseTableName(const QString &databaseNametableName) noexcept override;
|
||||
|
||||
private:
|
||||
void loadColumnInfo();
|
||||
};
|
||||
|
||||
#endif // TABLE_INFO_SQLITE_H
|
||||
@@ -0,0 +1,108 @@
|
||||
#include "tickets_repository.h"
|
||||
|
||||
#include "create_ticket_request.h"
|
||||
#include "repository_result.h"
|
||||
#include "ticket_dto.h"
|
||||
#include "update_ticket_request.h"
|
||||
#include <QSqlError>
|
||||
#include <QSqlQuery>
|
||||
|
||||
TicketsRepository::TicketsRepository(QSqlDatabase &database, QObject *parent)
|
||||
: BaseSqlTableRepository(database, parent) {}
|
||||
|
||||
RepositoryResult
|
||||
TicketsRepository::createTicket(const CreateTicketRequest &request) {
|
||||
QSqlQuery query = foreignKeysOnQuery();
|
||||
query.prepare("INSERT INTO tickets (session_id, seat_number, sold_at) VALUES "
|
||||
"(:session_id, :seat_number, :sold_at)");
|
||||
query.bindValue(":seat_number", request.seatNumber());
|
||||
query.bindValue(":session_id", request.sessionId());
|
||||
query.bindValue(":sold_at", request.soldAt());
|
||||
|
||||
if (!query.exec()) {
|
||||
return RepositoryResult::failureResult(query.lastError().text());
|
||||
}
|
||||
|
||||
emit dataCreated();
|
||||
return RepositoryResult::successResult();
|
||||
}
|
||||
|
||||
RepositoryResult TicketsRepository::getTicketById(qint32 id,
|
||||
TicketDTO &ticket) const {
|
||||
QSqlQuery query = foreignKeysOnQuery();
|
||||
query.prepare("SELECT ticket_id, session_id, seat_number, sold_at FROM "
|
||||
"tickets WHERE ticket_id = :id");
|
||||
query.bindValue(":id", id);
|
||||
|
||||
if (!query.exec()) {
|
||||
return RepositoryResult::failureResult(query.lastError().text());
|
||||
}
|
||||
if (!query.next()) {
|
||||
return RepositoryResult::failureResult("Ticket not found");
|
||||
}
|
||||
|
||||
ticket = mapQueryToDTO(query);
|
||||
|
||||
emit dataRetrieved();
|
||||
return RepositoryResult::successResult();
|
||||
}
|
||||
|
||||
RepositoryResult
|
||||
TicketsRepository::getAllTickets(QVector<TicketDTO> &tickets) const {
|
||||
QSqlQuery query = foreignKeysOnQuery();
|
||||
query.prepare(
|
||||
"SELECT ticket_id, session_id, seat_number, sold_at FROM tickets");
|
||||
|
||||
if (!query.exec()) {
|
||||
return RepositoryResult::failureResult(query.lastError().text());
|
||||
}
|
||||
|
||||
while (query.next()) {
|
||||
tickets.append(mapQueryToDTO(query));
|
||||
}
|
||||
|
||||
emit dataRetrieved();
|
||||
return RepositoryResult::successResult();
|
||||
}
|
||||
|
||||
RepositoryResult
|
||||
TicketsRepository::updateTicket(const UpdateTicketRequest &request) {
|
||||
QSqlQuery query = foreignKeysOnQuery();
|
||||
query.prepare(
|
||||
"UPDATE tickets SET session_id = :session_id, seat_number = "
|
||||
":seat_number, sold_at = :sold_at WHERE ticket_id = :ticket_id");
|
||||
query.bindValue(":seat_number", request.seatNumber());
|
||||
query.bindValue(":session_id", request.sessionId());
|
||||
query.bindValue(":sold_at", request.soldAt());
|
||||
query.bindValue(":ticket_id", request.ticketId());
|
||||
|
||||
if (!query.exec()) {
|
||||
return RepositoryResult::failureResult(query.lastError().text());
|
||||
}
|
||||
|
||||
emit dataUpdated();
|
||||
return RepositoryResult::successResult();
|
||||
}
|
||||
|
||||
RepositoryResult TicketsRepository::deleteTicketById(qint32 ticketId) {
|
||||
QSqlQuery query = foreignKeysOnQuery();
|
||||
query.prepare("DELETE FROM tickets WHERE ticket_id = :ticket_id");
|
||||
query.bindValue(":ticket_id", ticketId);
|
||||
|
||||
if (!query.exec()) {
|
||||
return RepositoryResult::failureResult(query.lastError().text());
|
||||
}
|
||||
|
||||
emit dataDeleted();
|
||||
return RepositoryResult::successResult();
|
||||
}
|
||||
|
||||
TicketDTO TicketsRepository::mapQueryToDTO(const QSqlQuery &query) const {
|
||||
TicketDTO ticketDTO;
|
||||
ticketDTO.setSeatNumber(query.value("seat_number").toInt());
|
||||
ticketDTO.setSessionId(query.value("session_id").toInt());
|
||||
ticketDTO.setSoldAt(query.value("sold_at").toDateTime());
|
||||
ticketDTO.setTicketId(query.value("ticket_id").toInt());
|
||||
|
||||
return ticketDTO;
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
#ifndef TICKETS_REPOSITORY_H
|
||||
#define TICKETS_REPOSITORY_H
|
||||
|
||||
#include "base_sql_table_repository.h"
|
||||
#include "tickets_repository_interface.h"
|
||||
|
||||
#include <QSqlDatabase>
|
||||
|
||||
class TicketsRepository : public TicketsRepositoryInterface,
|
||||
public BaseSqlTableRepository {
|
||||
public:
|
||||
explicit TicketsRepository(QSqlDatabase &db, QObject *parent);
|
||||
|
||||
// CRUD operations
|
||||
// clang-format off
|
||||
|
||||
RepositoryResult
|
||||
createTicket(const CreateTicketRequest &request) override;
|
||||
|
||||
RepositoryResult
|
||||
getTicketById(qint32 ticketId, TicketDTO &ticket) const override;
|
||||
|
||||
RepositoryResult
|
||||
getAllTickets(QVector<TicketDTO> &tickets) const override;
|
||||
|
||||
RepositoryResult
|
||||
updateTicket(const UpdateTicketRequest &request) override;
|
||||
|
||||
RepositoryResult
|
||||
deleteTicketById(qint32 ticketId) override;
|
||||
|
||||
// clang-format on
|
||||
|
||||
private:
|
||||
TicketDTO mapQueryToDTO(const QSqlQuery &query) const;
|
||||
};
|
||||
|
||||
#endif // TICKETS_REPOSITORY_H
|
||||
@@ -0,0 +1,130 @@
|
||||
#include "users_repository.h"
|
||||
|
||||
#include "create_user_request.h"
|
||||
#include "repository_result.h"
|
||||
#include "update_user_request.h"
|
||||
#include "user_dto.h"
|
||||
#include <QSqlError>
|
||||
#include <QSqlQuery>
|
||||
|
||||
UsersRepository::UsersRepository(QSqlDatabase &database, QObject *parent)
|
||||
: BaseSqlTableRepository(database, parent) {}
|
||||
|
||||
RepositoryResult UsersRepository::createUser(const CreateUserRequest &request) {
|
||||
QSqlQuery query = foreignKeysOnQuery();
|
||||
query.prepare("INSERT INTO users (username, password_hash, salt, role_id) "
|
||||
"VALUES (:username, :password_hash, :salt, :role_id)");
|
||||
query.bindValue(":password_hash", request.passwordHash());
|
||||
query.bindValue(":role_id", request.roleId());
|
||||
query.bindValue(":salt", request.salt());
|
||||
query.bindValue(":username", request.username());
|
||||
|
||||
if (!query.exec()) {
|
||||
return RepositoryResult::failureResult(query.lastError().text());
|
||||
}
|
||||
|
||||
emit dataCreated();
|
||||
return RepositoryResult::successResult();
|
||||
}
|
||||
|
||||
RepositoryResult UsersRepository::getUserById(qint32 id, UserDTO &user) const {
|
||||
QSqlQuery query = foreignKeysOnQuery();
|
||||
query.prepare("SELECT user_id, username, password_hash, salt, role_id FROM "
|
||||
"users WHERE "
|
||||
"user_id = :user_id");
|
||||
query.bindValue(":user_id", id);
|
||||
|
||||
if (!query.exec()) {
|
||||
return RepositoryResult::failureResult(query.lastError().text());
|
||||
}
|
||||
if (!query.next()) {
|
||||
return RepositoryResult::failureResult("User not found");
|
||||
}
|
||||
|
||||
user = mapQueryToDTO(query);
|
||||
|
||||
emit dataRetrieved();
|
||||
return RepositoryResult::successResult();
|
||||
}
|
||||
|
||||
RepositoryResult UsersRepository::getUserByUsername(const QString &username,
|
||||
UserDTO &user) const {
|
||||
QSqlQuery query = foreignKeysOnQuery();
|
||||
query.prepare("SELECT user_id, username, password_hash, salt, role_id FROM "
|
||||
"users WHERE "
|
||||
"username = :username");
|
||||
query.bindValue(":username", username);
|
||||
|
||||
if (!query.exec()) {
|
||||
return RepositoryResult::failureResult(query.lastError().text());
|
||||
}
|
||||
if (!query.next()) {
|
||||
return RepositoryResult::failureResult("User not found");
|
||||
}
|
||||
|
||||
user = mapQueryToDTO(query);
|
||||
|
||||
emit dataRetrieved();
|
||||
return RepositoryResult::successResult();
|
||||
}
|
||||
|
||||
RepositoryResult UsersRepository::getAllUsers(QVector<UserDTO> &users) const {
|
||||
QSqlQuery query = foreignKeysOnQuery();
|
||||
query.prepare(
|
||||
"SELECT user_id, username, password_hash, salt, role_id FROM users");
|
||||
|
||||
if (!query.exec()) {
|
||||
return RepositoryResult::failureResult(query.lastError().text());
|
||||
}
|
||||
|
||||
while (query.next()) {
|
||||
users.append(mapQueryToDTO(query));
|
||||
}
|
||||
|
||||
emit dataRetrieved();
|
||||
return RepositoryResult::successResult();
|
||||
}
|
||||
|
||||
RepositoryResult UsersRepository::updateUser(const UpdateUserRequest &request) {
|
||||
QSqlQuery query = foreignKeysOnQuery();
|
||||
query.prepare("UPDATE users SET username = :username, password_hash = "
|
||||
":password_hash, "
|
||||
"salt = :salt, role_id = :role_id WHERE user_id = :user_id");
|
||||
|
||||
query.bindValue(":username", request.username());
|
||||
query.bindValue(":password_hash", request.passwordHash());
|
||||
query.bindValue(":salt", request.salt());
|
||||
query.bindValue(":role_id", request.roleId());
|
||||
query.bindValue(":user_id", request.userId());
|
||||
|
||||
if (!query.exec()) {
|
||||
return RepositoryResult::failureResult(query.lastError().text());
|
||||
}
|
||||
|
||||
emit dataUpdated();
|
||||
return RepositoryResult::successResult();
|
||||
}
|
||||
|
||||
RepositoryResult UsersRepository::deleteUserById(qint32 userId) {
|
||||
QSqlQuery query = foreignKeysOnQuery();
|
||||
query.prepare("DELETE FROM users WHERE user_id = :user_id");
|
||||
query.bindValue(":user_id", userId);
|
||||
|
||||
if (!query.exec()) {
|
||||
return RepositoryResult::failureResult(query.lastError().text());
|
||||
}
|
||||
|
||||
emit dataDeleted();
|
||||
return RepositoryResult::successResult();
|
||||
}
|
||||
|
||||
UserDTO UsersRepository::mapQueryToDTO(const QSqlQuery &query) const {
|
||||
UserDTO userDTO;
|
||||
userDTO.setPasswordHash(query.value("password_hash").toString());
|
||||
userDTO.setRoleId(query.value("role_id").toInt());
|
||||
userDTO.setSalt(query.value("salt").toString());
|
||||
userDTO.setUserId(query.value("user_id").toInt());
|
||||
userDTO.setUsername(query.value("username").toString());
|
||||
|
||||
return userDTO;
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
#ifndef USERS_REPOSITORY_H
|
||||
#define USERS_REPOSITORY_H
|
||||
|
||||
#include "base_sql_table_repository.h"
|
||||
#include "users_repository_interface.h"
|
||||
|
||||
#include <QSqlDatabase>
|
||||
|
||||
class UsersRepository : public UsersRepositoryInterface,
|
||||
public BaseSqlTableRepository {
|
||||
public:
|
||||
explicit UsersRepository(QSqlDatabase &db, QObject *parent);
|
||||
|
||||
// CRUD operations
|
||||
// clang-format off
|
||||
|
||||
RepositoryResult
|
||||
createUser(const CreateUserRequest &request) override;
|
||||
|
||||
RepositoryResult
|
||||
getUserById(qint32 userId, UserDTO &user) const override;
|
||||
|
||||
RepositoryResult
|
||||
getUserByUsername(const QString &username, UserDTO &user) const override;
|
||||
|
||||
RepositoryResult
|
||||
getAllUsers(QVector<UserDTO> &users) const override;
|
||||
|
||||
RepositoryResult
|
||||
updateUser(const UpdateUserRequest &request) override;
|
||||
|
||||
RepositoryResult
|
||||
deleteUserById(qint32 userId) override;
|
||||
|
||||
// clang-format on
|
||||
|
||||
private:
|
||||
UserDTO mapQueryToDTO(const QSqlQuery &query) const;
|
||||
};
|
||||
|
||||
#endif // USERS_REPOSITORY_H
|
||||
Reference in New Issue
Block a user