Initial commit
This commit is contained in:
@@ -0,0 +1,96 @@
|
||||
#include "base_sql_table_model.h"
|
||||
|
||||
#include "QSqlError"
|
||||
#include "table_info_sqlite.h"
|
||||
#include <QDateTime>
|
||||
#include <QSqlQuery>
|
||||
|
||||
BaseSqlTableModel::BaseSqlTableModel(QObject *parent, QSqlDatabase database)
|
||||
: QSqlRelationalTableModel(parent, database) {}
|
||||
|
||||
bool BaseSqlTableModel::refreshAll() {
|
||||
beginResetModel();
|
||||
bool result = select();
|
||||
endResetModel();
|
||||
|
||||
result ? qInfo() << "Model of table with database name" << tableName()
|
||||
<< "was refreshed successfully"
|
||||
: qWarning() << "Failed to refresh model: Database name of table:"
|
||||
<< tableName() << "Error:" << lastError().text();
|
||||
return result;
|
||||
}
|
||||
|
||||
QVariant BaseSqlTableModel::data(const QModelIndex &index, int role) const {
|
||||
// if (role != Qt::DisplayRole) {
|
||||
return QSqlRelationalTableModel::data(index, role);
|
||||
// }
|
||||
//
|
||||
// QVariant value = QSqlRelationalTableModel::data(index, role);
|
||||
//
|
||||
// QDateTime datetime = QDateTime::fromString(value.toString(), Qt::ISODate);
|
||||
//
|
||||
// if (!datetime.isValid()) {
|
||||
// return value;
|
||||
// }
|
||||
//
|
||||
// QLocale locale;
|
||||
// QString formattedDateTime = locale.toString(datetime, QLocale::LongFormat);
|
||||
//
|
||||
// formattedDateTime[0] = formattedDateTime[0].toUpper();
|
||||
//
|
||||
// return formattedDateTime;
|
||||
}
|
||||
|
||||
void BaseSqlTableModel::setTable(const QString &databaseTableName) {
|
||||
tableInfo_.setDatabaseTableName(databaseTableName);
|
||||
QSqlRelationalTableModel::setTable(databaseTableName);
|
||||
}
|
||||
|
||||
void BaseSqlTableModel::resetFilter() {
|
||||
qInfo().noquote() << createUpdateFilterMessage("");
|
||||
setFilter("");
|
||||
}
|
||||
|
||||
void BaseSqlTableModel::setMultiColumnFilter(const QString &filter) {
|
||||
if (filter.isEmpty()) {
|
||||
resetFilter();
|
||||
return;
|
||||
}
|
||||
|
||||
const QString filterQuery = createMultiColumnFilter(filter);
|
||||
|
||||
qInfo().noquote() << createUpdateFilterMessage(filter);
|
||||
|
||||
setFilter(filterQuery);
|
||||
}
|
||||
|
||||
QString
|
||||
BaseSqlTableModel::createMultiColumnFilter(const QString &filter) const {
|
||||
|
||||
QStringList conditions;
|
||||
for (const QString &column : columnNames()) {
|
||||
conditions.append(QString("%1 LIKE '%%2%'").arg(column).arg(filter));
|
||||
}
|
||||
|
||||
return conditions.join(" OR ");
|
||||
}
|
||||
|
||||
QString
|
||||
BaseSqlTableModel::createUpdateFilterMessage(const QString &filter) const {
|
||||
QString classInfoMessage =
|
||||
QString("Model manager class name: %1").arg(metaObject()->className());
|
||||
|
||||
QString tableInfoMessage =
|
||||
QString("Database table name: %1").arg(tableName());
|
||||
|
||||
QString filterInfoMessage = filter.isEmpty()
|
||||
? "The filter was reset"
|
||||
: QString("Filter: \"%1\"").arg(filter);
|
||||
|
||||
QString message = QString("The model was updated: %1: %2: %3")
|
||||
.arg(classInfoMessage)
|
||||
.arg(tableInfoMessage)
|
||||
.arg(filterInfoMessage);
|
||||
|
||||
return message;
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
#ifndef BASE_SQL_TABLE_MODEL_H
|
||||
#define BASE_SQL_TABLE_MODEL_H
|
||||
|
||||
#include "table_info_sqlite.h"
|
||||
#include <QSqlRelationalTableModel>
|
||||
|
||||
class BaseSqlTableModel : public QSqlRelationalTableModel {
|
||||
Q_OBJECT
|
||||
|
||||
private:
|
||||
TableInfoSQLite tableInfo_;
|
||||
|
||||
public:
|
||||
explicit BaseSqlTableModel(QObject *parent = nullptr,
|
||||
QSqlDatabase database = QSqlDatabase());
|
||||
|
||||
virtual ~BaseSqlTableModel() = default;
|
||||
|
||||
virtual QVariant data(const QModelIndex &index,
|
||||
int role = Qt::DisplayRole) const override;
|
||||
|
||||
virtual void setTable(const QString &databaseTableName) override;
|
||||
|
||||
virtual inline QString columnName(int index) const;
|
||||
|
||||
virtual inline QStringList columnNames() const;
|
||||
|
||||
virtual inline bool isCompleteDatabaseFiltering() const = 0;
|
||||
|
||||
virtual inline int columnIndex(const QString &columnName) const;
|
||||
|
||||
void resetFilter();
|
||||
|
||||
void setMultiColumnFilter(const QString &filter);
|
||||
|
||||
protected:
|
||||
virtual QString createMultiColumnFilter(const QString &filter) const;
|
||||
|
||||
public slots:
|
||||
// WARNING: I was too lazy and decided that I could do with one slot
|
||||
|
||||
// Refreshes the whole table
|
||||
bool refreshAll();
|
||||
|
||||
// Here can be additional slots
|
||||
// refreshByRowNumber(int row) = 0;
|
||||
// refreshRange(int from, int to) = 0;
|
||||
// refreshByFilter(QString filter) = 0;
|
||||
// etc
|
||||
|
||||
private:
|
||||
QString createUpdateFilterMessage(const QString &filter) const;
|
||||
};
|
||||
|
||||
QString BaseSqlTableModel::columnName(int index) const {
|
||||
return tableInfo_.columnName(index);
|
||||
}
|
||||
|
||||
QStringList BaseSqlTableModel::columnNames() const {
|
||||
return tableInfo_.columnNames();
|
||||
}
|
||||
|
||||
int BaseSqlTableModel::columnIndex(const QString &columnName) const {
|
||||
return tableInfo_.columnIndex(columnName);
|
||||
}
|
||||
|
||||
#endif // BASE_SQL_TABLE_MODEL_H
|
||||
@@ -0,0 +1,32 @@
|
||||
#include "genres_model.h"
|
||||
|
||||
#include <QSqlError>
|
||||
|
||||
GenresModel::GenresModel(QObject *parent, const QSqlDatabase &database)
|
||||
: BaseSqlTableModel(parent, database) {}
|
||||
|
||||
void GenresModel::initialize() {
|
||||
setTable("genres");
|
||||
|
||||
setEditStrategy(QSqlTableModel::OnFieldChange);
|
||||
|
||||
bool success = select();
|
||||
if (!success) {
|
||||
qWarning() << "Error:" << lastError().text();
|
||||
}
|
||||
}
|
||||
|
||||
QVariant GenresModel::headerData(int section, Qt::Orientation orientation,
|
||||
int role) const {
|
||||
if (role == Qt::DisplayRole && orientation == Qt::Horizontal) {
|
||||
switch (section) {
|
||||
case GenresColumns::Id:
|
||||
return tr("ID");
|
||||
case GenresColumns::Name:
|
||||
return tr("Name");
|
||||
default:
|
||||
return QVariant();
|
||||
}
|
||||
}
|
||||
return QSqlTableModel::headerData(section, orientation, role);
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
#ifndef GENRES_MODEL_H
|
||||
#define GENRES_MODEL_H
|
||||
|
||||
#include "base_sql_table_model.h"
|
||||
|
||||
class GenresModel : public BaseSqlTableModel {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
// Enum for columns
|
||||
enum GenresColumns { Id, Name };
|
||||
|
||||
public:
|
||||
explicit GenresModel(QObject *parent, const QSqlDatabase &database);
|
||||
|
||||
// Initialize the model
|
||||
void initialize();
|
||||
|
||||
// Overlooking class BaseSqlTableModel methods
|
||||
|
||||
QVariant headerData(int section, Qt::Orientation orientation,
|
||||
int role = Qt::DisplayRole) const override;
|
||||
|
||||
inline bool isCompleteDatabaseFiltering() const final { return true; };
|
||||
};
|
||||
|
||||
#endif // GENRES_MODEL_H
|
||||
@@ -0,0 +1,35 @@
|
||||
#include "halls_model.h"
|
||||
|
||||
#include <QSqlError>
|
||||
|
||||
HallsModel::HallsModel(QObject *parent, const QSqlDatabase &database)
|
||||
: BaseSqlTableModel(parent, database) {}
|
||||
|
||||
void HallsModel::initialize() {
|
||||
|
||||
setTable("halls");
|
||||
|
||||
setEditStrategy(QSqlTableModel::OnFieldChange);
|
||||
|
||||
bool success = select();
|
||||
if (!success) {
|
||||
qWarning() << "Error:" << lastError().text();
|
||||
}
|
||||
}
|
||||
|
||||
QVariant HallsModel::headerData(int section, Qt::Orientation orientation,
|
||||
int role) const {
|
||||
if (role == Qt::DisplayRole && orientation == Qt::Horizontal) {
|
||||
switch (section) {
|
||||
case HallsColumns::Id:
|
||||
return tr("ID");
|
||||
case HallsColumns::Name:
|
||||
return tr("Name");
|
||||
case HallsColumns::Capacity:
|
||||
return tr("Capacity");
|
||||
default:
|
||||
return QVariant();
|
||||
}
|
||||
}
|
||||
return QSqlTableModel::headerData(section, orientation, role);
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
#ifndef HALLS_MODEL_H
|
||||
#define HALLS_MODEL_H
|
||||
|
||||
#include "base_sql_table_model.h"
|
||||
|
||||
class HallsModel : public BaseSqlTableModel {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
// Enum for columns
|
||||
enum HallsColumns { Id, Name, Capacity };
|
||||
|
||||
public:
|
||||
explicit HallsModel(QObject *parent, const QSqlDatabase &database);
|
||||
|
||||
// Initealize the model
|
||||
void initialize();
|
||||
|
||||
// Overlooking class BaseSqlTableModel methods
|
||||
|
||||
QVariant headerData(int section, Qt::Orientation orientation,
|
||||
int role = Qt::DisplayRole) const override;
|
||||
|
||||
inline bool isCompleteDatabaseFiltering() const final { return true; };
|
||||
};
|
||||
|
||||
#endif // HALLS_MODEL_H
|
||||
@@ -0,0 +1,77 @@
|
||||
#include "movies_model.h"
|
||||
|
||||
#include <QSqlError>
|
||||
#include <QSqlQuery>
|
||||
|
||||
MoviesModel::MoviesModel(QObject *parent, const QSqlDatabase &database)
|
||||
: BaseSqlTableModel(parent, database) {}
|
||||
|
||||
void MoviesModel::initialize() {
|
||||
setTable("movies");
|
||||
|
||||
// Set up the relationship with the genres table
|
||||
setRelation(fieldIndex("genre_id"),
|
||||
QSqlRelation("genres", "genre_id", "genre_name"));
|
||||
|
||||
setEditStrategy(QSqlTableModel::OnFieldChange);
|
||||
|
||||
bool success = select();
|
||||
if (!success) {
|
||||
qWarning() << "Error:" << lastError().text();
|
||||
}
|
||||
}
|
||||
|
||||
QVariant MoviesModel::headerData(int section, Qt::Orientation orientation,
|
||||
int role) const {
|
||||
if (role == Qt::DisplayRole && orientation == Qt::Horizontal) {
|
||||
switch (section) {
|
||||
case MoviesColumns::Id:
|
||||
return tr("ID");
|
||||
case MoviesColumns::Title:
|
||||
return tr("Title");
|
||||
case MoviesColumns::GenreId:
|
||||
return tr("Genre");
|
||||
case MoviesColumns::Duration:
|
||||
return tr("Duration");
|
||||
default:
|
||||
return QVariant();
|
||||
}
|
||||
}
|
||||
return QSqlRelationalTableModel::headerData(section, orientation, role);
|
||||
}
|
||||
|
||||
bool MoviesModel::buildGenreIdFilterCondition(const QString &inFilter,
|
||||
QString &outFilter) const {
|
||||
QSqlQuery query;
|
||||
query.prepare("SELECT genre_id FROM genres WHERE genre_name LIKE ?");
|
||||
query.addBindValue("%" + inFilter + "%");
|
||||
query.exec();
|
||||
|
||||
QStringList genreIds;
|
||||
while (query.next()) {
|
||||
genreIds << query.value(0).toString();
|
||||
}
|
||||
|
||||
outFilter = QString("movies.genre_id IN (%1)").arg(genreIds.join(", "));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
QString MoviesModel::createMultiColumnFilter(const QString &filter) const {
|
||||
QStringList conditions;
|
||||
|
||||
QString buffer; // MoviesColumns::GenreId
|
||||
if (buildGenreIdFilterCondition(filter, buffer)) {
|
||||
conditions.append(buffer);
|
||||
}
|
||||
|
||||
using Columns = MoviesColumns;
|
||||
QStringList columns = {columnName(Columns::Id), columnName(Columns::Title),
|
||||
columnName(Columns::Duration)};
|
||||
|
||||
for (const QString &column : columns) {
|
||||
conditions.append(QString("%1 LIKE '%%2%'").arg(column).arg(filter));
|
||||
}
|
||||
|
||||
return conditions.join(" OR ");
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
#ifndef MOVIES_MODEL_H
|
||||
#define MOVIES_MODEL_H
|
||||
|
||||
#include "base_sql_table_model.h"
|
||||
|
||||
class MoviesModel : public BaseSqlTableModel {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
// Enum for columns
|
||||
enum MoviesColumns { Id, Title, GenreId, Duration };
|
||||
|
||||
public:
|
||||
explicit MoviesModel(QObject *parent, const QSqlDatabase &database);
|
||||
|
||||
// Initialize the model
|
||||
void initialize();
|
||||
|
||||
// Overlooking class BaseSqlTableModel methods
|
||||
|
||||
QVariant headerData(int section, Qt::Orientation orientation,
|
||||
int role = Qt::DisplayRole) const override;
|
||||
|
||||
inline bool isCompleteDatabaseFiltering() const final { return true; };
|
||||
|
||||
protected:
|
||||
QString createMultiColumnFilter(const QString &filter) const final;
|
||||
|
||||
private:
|
||||
bool buildGenreIdFilterCondition(const QString &inFilter,
|
||||
QString &outFilter) const;
|
||||
};
|
||||
|
||||
#endif // MOVIES_MODEL_H
|
||||
@@ -0,0 +1,32 @@
|
||||
#include "multi_column_filter_proxy_model.h"
|
||||
|
||||
#include <QDateTime>
|
||||
|
||||
MultiColumnSortFilterProxyModel::MultiColumnSortFilterProxyModel(
|
||||
QObject *parent)
|
||||
: QSortFilterProxyModel(parent) {}
|
||||
|
||||
bool MultiColumnSortFilterProxyModel::filterAcceptsRow(
|
||||
int sourceRow, const QModelIndex &sourceParent) const {
|
||||
|
||||
QRegularExpression regex = filterRegularExpression();
|
||||
if (!regex.isValid() || regex.pattern().isEmpty()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
int columnCount = sourceModel()->columnCount(sourceParent);
|
||||
for (int column = 0; column < columnCount; ++column) {
|
||||
QModelIndex sourceIndex =
|
||||
sourceModel()->index(sourceRow, column, sourceParent);
|
||||
QString dataValue =
|
||||
sourceModel()->data(sourceIndex, Qt::DisplayRole).toString();
|
||||
|
||||
dataValue.replace(QRegularExpression("\\s+"), " ");
|
||||
|
||||
if (regex.match(dataValue).hasMatch()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
#ifndef MULTI_COLUMN_FILTER_PROXY_MODEL
|
||||
#define MULTI_COLUMN_FILTER_PROXY_MODEL
|
||||
|
||||
#include <QSortFilterProxyModel>
|
||||
|
||||
class MultiColumnSortFilterProxyModel : public QSortFilterProxyModel {
|
||||
public:
|
||||
explicit MultiColumnSortFilterProxyModel(QObject *parent = nullptr);
|
||||
|
||||
protected:
|
||||
bool filterAcceptsRow(int sourceRow,
|
||||
const QModelIndex &sourceParent) const override;
|
||||
};
|
||||
|
||||
#endif // MULTI_COLUMN_FILTER_PROXY_MODEL
|
||||
@@ -0,0 +1,57 @@
|
||||
#include "refunds_model.h"
|
||||
|
||||
#include <QSqlError>
|
||||
|
||||
RefundsModel::RefundsModel(QObject *parent, const QSqlDatabase &database)
|
||||
: BaseSqlTableModel(parent, database) {}
|
||||
|
||||
void RefundsModel::initialize() {
|
||||
setTable("refunds");
|
||||
|
||||
setEditStrategy(QSqlTableModel::OnFieldChange);
|
||||
|
||||
bool success = select();
|
||||
if (!success) {
|
||||
qWarning() << "Error:" << lastError().text();
|
||||
}
|
||||
}
|
||||
|
||||
QVariant RefundsModel::headerData(int section, Qt::Orientation orientation,
|
||||
int role) const {
|
||||
if (role == Qt::DisplayRole && orientation == Qt::Horizontal) {
|
||||
switch (section) {
|
||||
case RefundsColumns::Id:
|
||||
return tr("ID");
|
||||
case RefundsColumns::TicketId:
|
||||
return tr("Ticket ID");
|
||||
case RefundsColumns::RefundAt:
|
||||
return tr("Refund At");
|
||||
case RefundsColumns::RefundAmount:
|
||||
return tr("Refund Amount");
|
||||
default:
|
||||
return QVariant();
|
||||
}
|
||||
}
|
||||
return QSqlTableModel::headerData(section, orientation, role);
|
||||
}
|
||||
|
||||
QString RefundsModel::createMultiColumnFilter(const QString &filter) const {
|
||||
QStringList conditions;
|
||||
|
||||
// WARNING: Does not filter these models transmitted through the data method,
|
||||
// such as QDatetime
|
||||
|
||||
using Columns = RefundsModel;
|
||||
QStringList columns = {columnName(Columns::Id), columnName(Columns::TicketId),
|
||||
columnName(Columns::RefundAmount)};
|
||||
|
||||
#ifndef NO_DATE_TIME_SEARCH
|
||||
columns.append(columnName(Columns::RefundAt));
|
||||
#endif
|
||||
|
||||
for (const QString &column : columns) {
|
||||
conditions.append(QString("%1 LIKE '%%2%'").arg(column).arg(filter));
|
||||
}
|
||||
|
||||
return conditions.join(" OR ");
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
#ifndef REFUNDS_MODEL_H
|
||||
#define REFUNDS_MODEL_H
|
||||
|
||||
#include "base_sql_table_model.h"
|
||||
|
||||
class RefundsModel : public BaseSqlTableModel {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
enum RefundsColumns { Id, TicketId, RefundAt, RefundAmount };
|
||||
|
||||
public:
|
||||
explicit RefundsModel(QObject *parent, const QSqlDatabase &database);
|
||||
|
||||
// Initialize the model
|
||||
void initialize();
|
||||
|
||||
// Overlooking class BaseSqlTableModel methods
|
||||
|
||||
QVariant headerData(int section, Qt::Orientation orientation,
|
||||
int role = Qt::DisplayRole) const override;
|
||||
|
||||
inline bool isCompleteDatabaseFiltering() const final {
|
||||
#ifdef NO_DATE_TIME_SEARCH
|
||||
return false;
|
||||
#else
|
||||
return true;
|
||||
#endif
|
||||
};
|
||||
|
||||
protected:
|
||||
QString createMultiColumnFilter(const QString &filter) const final;
|
||||
};
|
||||
|
||||
#endif // REFUNDS_MODEL_H
|
||||
@@ -0,0 +1,116 @@
|
||||
#include "sessions_model.h"
|
||||
|
||||
#include <QSqlError>
|
||||
#include <QSqlQuery>
|
||||
|
||||
SessionsModel::SessionsModel(QObject *parent, const QSqlDatabase &database)
|
||||
: BaseSqlTableModel(parent, database) {}
|
||||
|
||||
void SessionsModel::initialize() {
|
||||
setTable("sessions");
|
||||
|
||||
// Set up the relationship with the movies and halls tables
|
||||
setRelation(fieldIndex("movie_id"),
|
||||
QSqlRelation("movies", "movie_id", "title"));
|
||||
setRelation(fieldIndex("hall_id"),
|
||||
QSqlRelation("halls", "hall_id", "hall_name"));
|
||||
|
||||
setEditStrategy(QSqlTableModel::OnFieldChange);
|
||||
|
||||
bool success = select();
|
||||
if (!success) {
|
||||
qWarning() << "Error:" << lastError().text();
|
||||
}
|
||||
}
|
||||
|
||||
bool SessionsModel::buildHallIdFilterCondition(const QString &inFilter,
|
||||
QString &outFilter) const {
|
||||
QSqlQuery query;
|
||||
query.prepare("SELECT hall_id FROM halls WHERE hall_name LIKE ?");
|
||||
query.addBindValue("%" + inFilter + "%");
|
||||
query.exec();
|
||||
|
||||
QStringList hallIds;
|
||||
while (query.next()) {
|
||||
hallIds << query.value(0).toString();
|
||||
}
|
||||
|
||||
if (hallIds.isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
outFilter = QString("sessions.hall_id IN (%1)").arg(hallIds.join(", "));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SessionsModel::buildMovieIdFilterCondition(const QString &inFilter,
|
||||
QString &outFilter) const {
|
||||
QSqlQuery query;
|
||||
query.prepare("SELECT movie_id FROM movies WHERE title LIKE ?");
|
||||
query.addBindValue("%" + inFilter + "%");
|
||||
query.exec();
|
||||
|
||||
QStringList movieIds;
|
||||
while (query.next()) {
|
||||
movieIds << query.value(0).toString();
|
||||
}
|
||||
|
||||
if (movieIds.isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
outFilter = QString("sessions.movie_id IN (%1)").arg(movieIds.join(", "));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
QVariant SessionsModel::headerData(int section, Qt::Orientation orientation,
|
||||
int role) const {
|
||||
if (role == Qt::DisplayRole && orientation == Qt::Horizontal) {
|
||||
switch (section) {
|
||||
case SessionsColumns::Id:
|
||||
return tr("ID");
|
||||
case SessionsColumns::MovieId:
|
||||
return tr("Movie Title");
|
||||
case SessionsColumns::HallId:
|
||||
return tr("Hall Name");
|
||||
case SessionsColumns::BeginAt:
|
||||
return tr("Start Time");
|
||||
case SessionsColumns::TicketPrice:
|
||||
return tr("Ticket Price");
|
||||
default:
|
||||
return QVariant();
|
||||
}
|
||||
}
|
||||
return QSqlRelationalTableModel::headerData(section, orientation, role);
|
||||
}
|
||||
|
||||
QString SessionsModel::createMultiColumnFilter(const QString &filter) const {
|
||||
QStringList conditions;
|
||||
|
||||
QString buffer; // SessionsColumns::HallId And SessionsColumns::MovieId
|
||||
if (buildHallIdFilterCondition(filter, buffer)) {
|
||||
conditions.append(buffer);
|
||||
}
|
||||
if (buildMovieIdFilterCondition(filter, buffer)) {
|
||||
conditions.append(buffer);
|
||||
}
|
||||
|
||||
// WARNING: Does not filter these models transmitted through the data method,
|
||||
// such as QDatetime
|
||||
|
||||
using Columns = SessionsColumns;
|
||||
QStringList columns = {columnName(Columns::Id),
|
||||
columnName(Columns::TicketPrice)};
|
||||
|
||||
#ifndef NO_DATE_TIME_SEARCH
|
||||
columns.append(columnName(Columns::BeginAt));
|
||||
#endif
|
||||
|
||||
for (const QString &column : columns) {
|
||||
conditions.append(QString("%1 LIKE '%%2%'").arg(column).arg(filter));
|
||||
}
|
||||
|
||||
return conditions.join(" OR ");
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
#ifndef SESSIONS_MODEL_H
|
||||
#define SESSIONS_MODEL_H
|
||||
|
||||
#include "base_sql_table_model.h"
|
||||
|
||||
class SessionsModel : public BaseSqlTableModel {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
// Enum for columns
|
||||
enum SessionsColumns { Id, MovieId, HallId, BeginAt, TicketPrice };
|
||||
|
||||
public:
|
||||
explicit SessionsModel(QObject *parent, const QSqlDatabase &database);
|
||||
|
||||
// Initialize the model
|
||||
void initialize();
|
||||
|
||||
// Overlooking class BaseSqlTableModel methods
|
||||
|
||||
QVariant headerData(int section, Qt::Orientation orientation,
|
||||
int role = Qt::DisplayRole) const override;
|
||||
|
||||
inline bool isCompleteDatabaseFiltering() const final {
|
||||
#ifdef NO_DATE_TIME_SEARCH
|
||||
return false;
|
||||
#else
|
||||
return true;
|
||||
#endif
|
||||
};
|
||||
|
||||
protected:
|
||||
QString createMultiColumnFilter(const QString &filter) const final;
|
||||
|
||||
private:
|
||||
bool buildHallIdFilterCondition(const QString &inFilter,
|
||||
QString &outFilter) const;
|
||||
|
||||
bool buildMovieIdFilterCondition(const QString &inFilter,
|
||||
QString &outFilter) const;
|
||||
};
|
||||
|
||||
#endif // SESSIONS_MODEL_H
|
||||
@@ -0,0 +1,59 @@
|
||||
#include "tickets_model.h"
|
||||
|
||||
#include <QSqlError>
|
||||
#include <QSqlRecord>
|
||||
|
||||
TicketsModel::TicketsModel(QObject *parent, const QSqlDatabase &database)
|
||||
: BaseSqlTableModel(parent, database) {}
|
||||
|
||||
void TicketsModel::initialize() {
|
||||
setTable("tickets");
|
||||
|
||||
setEditStrategy(QSqlTableModel::OnFieldChange);
|
||||
|
||||
bool success = select();
|
||||
if (!success) {
|
||||
qWarning() << "Error:" << lastError().text();
|
||||
}
|
||||
}
|
||||
|
||||
QVariant TicketsModel::headerData(int section, Qt::Orientation orientation,
|
||||
int role) const {
|
||||
if (role == Qt::DisplayRole && orientation == Qt::Horizontal) {
|
||||
switch (section) {
|
||||
case TicketsColumns::Id:
|
||||
return tr("ID");
|
||||
case TicketsColumns::SessionId:
|
||||
return tr("Session ID");
|
||||
case TicketsColumns::SeatNumber:
|
||||
return tr("Seat Number");
|
||||
case TicketsColumns::SoldAt:
|
||||
return tr("Sold At");
|
||||
default:
|
||||
return QVariant();
|
||||
}
|
||||
}
|
||||
return QSqlTableModel::headerData(section, orientation, role);
|
||||
}
|
||||
|
||||
QString TicketsModel::createMultiColumnFilter(const QString &filter) const {
|
||||
QStringList conditions;
|
||||
|
||||
// WARNING: Does not filter these models transmitted through the data method,
|
||||
// such as QDatetime
|
||||
|
||||
using Columns = TicketsColumns;
|
||||
QStringList columns = {columnName(Columns::Id),
|
||||
columnName(Columns::SessionId),
|
||||
columnName(Columns::SeatNumber)};
|
||||
|
||||
#ifndef NO_DATE_TIME_SEARCH
|
||||
columns.append(columnName(Columns::SoldAt));
|
||||
#endif
|
||||
|
||||
for (const QString &column : columns) {
|
||||
conditions.append(QString("%1 LIKE '%%2%'").arg(column).arg(filter));
|
||||
}
|
||||
|
||||
return conditions.join(" OR ");
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
#ifndef TICKETS_MODEL_H
|
||||
#define TICKETS_MODEL_H
|
||||
|
||||
#include "base_sql_table_model.h"
|
||||
|
||||
class TicketsModel : public BaseSqlTableModel {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
enum TicketsColumns { Id, SessionId, SeatNumber, SoldAt };
|
||||
|
||||
public:
|
||||
explicit TicketsModel(QObject *parent, const QSqlDatabase &database);
|
||||
|
||||
// Initialize the model
|
||||
void initialize();
|
||||
|
||||
// Overlooking class BaseSqlTableModel methods
|
||||
|
||||
QVariant headerData(int section, Qt::Orientation orientation,
|
||||
int role = Qt::DisplayRole) const override;
|
||||
|
||||
inline bool isCompleteDatabaseFiltering() const final {
|
||||
#ifdef NO_DATE_TIME_SEARCH
|
||||
return false;
|
||||
#else
|
||||
return true;
|
||||
#endif
|
||||
};
|
||||
|
||||
protected:
|
||||
QString createMultiColumnFilter(const QString &filter) const final;
|
||||
};
|
||||
|
||||
#endif // TICKETS_MODEL_H
|
||||
Reference in New Issue
Block a user