From e5cd25cc77f58cedf378448e28d3ed98bdee1f5d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Du=C5=A1an=20Poizl?= Date: Mon, 11 Apr 2022 20:12:06 +0200 Subject: [PATCH] Multiple search support and SQL optimization --- database.cpp | 3 +- databaseview.cpp | 81 +++++++++++++++++++++++++++++++++++------------- databaseview.h | 9 +++--- 3 files changed, 66 insertions(+), 27 deletions(-) diff --git a/database.cpp b/database.cpp index 0c1adf7..c7d4ad3 100644 --- a/database.cpp +++ b/database.cpp @@ -30,7 +30,8 @@ bool Database::init() m_database.exec("CREATE TABLE IF NOT EXISTS fits_files (id INTEGER PRIMARY KEY AUTOINCREMENT, file VARCHAR(255) UNIQUE, mtime DATETIME)"); m_database.exec("CREATE TABLE IF NOT EXISTS fits_headers (id INTEGER PRIMARY KEY AUTOINCREMENT, id_file INTEGER," "key VARCHAR(81), value VARCHAR(81), comment VARCHAR(81), FOREIGN KEY(id_file) REFERENCES fits_files(id) ON DELETE CASCADE)"); - m_database.exec("CREATE INDEX IF NOT EXISTS key_value ON fits_headers(key, value)"); + m_database.exec("CREATE INDEX IF NOT EXISTS key_value ON fits_headers(key, value)"); + m_database.exec("CREATE INDEX IF NOT EXISTS id_file ON fits_headers(id_file)"); QSqlError error = m_database.lastError(); if(error.type() == QSqlError::NoError) diff --git a/databaseview.cpp b/databaseview.cpp index 153168e..4f6fb39 100644 --- a/databaseview.cpp +++ b/databaseview.cpp @@ -6,6 +6,7 @@ #include #include #include +#include const QStringList DEFAULT_COLUMNS = {"EXPTIME", "OBJECT", "RA", "DEC"}; @@ -57,8 +58,8 @@ void FITSFileModel::sort(int column, Qt::SortOrder order) m_sort.clear(); else if(column <= m_columns.size()) { - if(column == 0)m_sort = " ORDER BY file "; - else m_sort = QString(" ORDER BY \"%1\" ").arg(m_columns.at(column-1)); + if(column == 0)m_sort = " ORDER BY f.file "; + else m_sort = QString(" ORDER BY \"h%1_value\" ").arg(column-1); m_sort += order == Qt::AscendingOrder ? "ASC" : "DESC"; prepareQuery(); } @@ -70,31 +71,55 @@ void FITSFileModel::setColumns(const QStringList &columns) prepareQuery(); } -void FITSFileModel::setFilter(const QString &key, const QString &value) +void FITSFileModel::setFilter(const QStringList &key, const QStringList &value) { if(value.isEmpty()) { - m_having.clear(); + m_key.clear(); + m_value.clear(); } else { - if(!m_columns.contains(key) && key != "file")m_columns.append(key); - m_having = QString(" HAVING \"%1\" LIKE \"%2\"").arg(key).arg(value); + m_key = key; + m_value = value; } prepareQuery(); } void FITSFileModel::prepareQuery() { - QString sql = "SELECT file,"; + QString cols; + QString join; + QString where; + QString sql = "SELECT f.file,"; + for(int i=0; iaddWidget(selectColumnsButton); connect(selectColumnsButton, &QPushButton::pressed, this, &DataBaseView::selectColumns); - m_filterKeyword = new QComboBox(this); - m_filterKeyword->addItem("file"); - m_filterKeyword->addItems(m_database->getFitsKeywords()); - - m_search = new QLineEdit(this); - m_search->setPlaceholderText(tr("Text to search, you can % as wildcard")); - connect(m_search, &QLineEdit::returnPressed, this, &DataBaseView::applyFilter); + for(int i=0; i<3; i++) + { + m_filterKeyword[i] = new QComboBox(this); + m_filterKeyword[i]->addItem("file"); + m_filterKeyword[i]->addItems(m_database->getFitsKeywords()); + m_search[i] = new QLineEdit(this); + m_search[i]->setPlaceholderText(tr("Text to search, you can % as wildcard")); + connect(m_search[i], &QLineEdit::returnPressed, this, &DataBaseView::applyFilter); + hlayout->addWidget(m_filterKeyword[i]); + hlayout->addWidget(m_search[i]); + } QPushButton *filterButton = new QPushButton(tr("Filter"), this); connect(filterButton, SIGNAL(pressed()), this, SLOT(applyFilter())); - - hlayout->addWidget(m_filterKeyword); - hlayout->addWidget(m_search); hlayout->addWidget(filterButton); } @@ -175,6 +201,17 @@ void DataBaseView::itemActivated(const QModelIndex &index) void DataBaseView::applyFilter() { - m_model->setFilter(m_filterKeyword->currentText(), m_search->text()); + QStringList keys; + QStringList values; + for(int i=0; i<3; i++) + { + QString key = m_filterKeyword[i]->currentText(); + if(!m_search[i]->text().isEmpty() && !keys.contains(key)) + { + keys.append(key); + values.append(m_search[i]->text()); + } + } + m_model->setFilter(keys, values); } diff --git a/databaseview.h b/databaseview.h index 60c1aba..948a3f4 100644 --- a/databaseview.h +++ b/databaseview.h @@ -25,12 +25,13 @@ class FITSFileModel : public QSqlQueryModel Q_OBJECT QStringList m_columns; QString m_sort; - QString m_having; + QStringList m_key; + QStringList m_value; public: FITSFileModel(QObject *parent = nullptr); void sort(int column, Qt::SortOrder order); void setColumns(const QStringList &columns); - void setFilter(const QString &key, const QString &value); + void setFilter(const QStringList &key, const QStringList &value); protected: void prepareQuery(); }; @@ -41,8 +42,8 @@ class DataBaseView : public QWidget Database *m_database; QTableView *m_tableView; FITSFileModel *m_model; - QComboBox *m_filterKeyword; - QLineEdit *m_search; + QComboBox *m_filterKeyword[3]; + QLineEdit *m_search[3]; public: explicit DataBaseView(Database *database, QWidget *parent = nullptr); ~DataBaseView();