Change WHERE clauses of queries to use column names instead of indexes

For the same reasons we changed the ORDER BY part of query objects to
use their names instead of their indexes to address columns, this commit
changes the handling of the WHERE part of a query to use column names
too.
This commit is contained in:
Martin Kleusberg
2021-01-28 19:43:53 +01:00
parent 94023a55e8
commit 18c7e9c477
7 changed files with 25 additions and 25 deletions

View File

@@ -2539,7 +2539,7 @@ static void loadBrowseDataTableSettings(BrowseDataTableSettings& settings, sqlb:
size_t index = xml.attributes().value("index").toUInt();
QString value = xml.attributes().value("value").toString();
if(!value.isEmpty())
settings.filterValues[index] = value;
settings.filterValues[field_information.at(index).name] = value;
xml.skipCurrentElement();
}
}
@@ -2922,7 +2922,7 @@ static void saveBrowseDataTableSettings(const BrowseDataTableSettings& object, s
xml.writeStartElement("filter_values");
for(auto iter=object.filterValues.cbegin(); iter!=object.filterValues.cend(); ++iter) {
xml.writeStartElement("column");
xml.writeAttribute("index", QString::number(iter->first));
xml.writeAttribute("index", QString::number(sqlb::getFieldNumber(obj, iter->first)));
xml.writeAttribute("value", iter->second);
xml.writeEndElement();
}

View File

@@ -558,17 +558,18 @@ void TableBrowser::updateFilter(size_t column, const QString& value)
ui->dataTable->verticalHeader()->setMinimumWidth(ui->dataTable->verticalHeader()->width());
// Update the filter in the model and its query
m_model->updateFilter(column, value);
const std::string column_name = model()->headerData(static_cast<int>(column), Qt::Horizontal, Qt::EditRole).toString().toStdString();
m_model->updateFilter(column_name, value);
// Save the new filter settings
BrowseDataTableSettings& settings = m_settings[currentlyBrowsedTableName()];
if(value.isEmpty())
{
if(settings.filterValues.erase(column) > 0)
if(settings.filterValues.erase(column_name) > 0)
emit projectModified();
} else {
if (settings.filterValues[column] != value) {
settings.filterValues[column] = value;
if (settings.filterValues[column_name] != value) {
settings.filterValues[column_name] = value;
emit projectModified();
}
}
@@ -662,8 +663,9 @@ void TableBrowser::modifyFormat(std::function<void(CondFormat&)> changeFunction)
if (columns.size() > 0) {
for (size_t column : columns) {
QString filter;
if (m_settings[currentlyBrowsedTableName()].filterValues.count(column) > 0)
filter = m_settings[currentlyBrowsedTableName()].filterValues.at(column);
const std::string column_name = model()->headerData(static_cast<int>(column), Qt::Horizontal, Qt::EditRole).toString().toStdString();
if (m_settings[currentlyBrowsedTableName()].filterValues.count(column_name) > 0)
filter = m_settings[currentlyBrowsedTableName()].filterValues.at(column_name);
modifySingleFormat(false, filter, currentIndex().sibling(currentIndex().row(), static_cast<int>(column)), changeFunction);
}
} else {
@@ -928,8 +930,9 @@ void TableBrowser::generateFilters()
// Set filters blocking signals for this since the filter is already applied to the browse table model
FilterTableHeader* filterHeader = qobject_cast<FilterTableHeader*>(ui->dataTable->horizontalHeader());
bool oldState = filterHeader->blockSignals(true);
auto obj = db->getObjectByName(currentlyBrowsedTableName());
for(auto filterIt=settings.filterValues.cbegin();filterIt!=settings.filterValues.cend();++filterIt)
ui->dataTable->setFilter(static_cast<size_t>(filterIt->first), filterIt->second);
ui->dataTable->setFilter(sqlb::getFieldNumber(obj, filterIt->first) + 1, filterIt->second);
filterHeader->blockSignals(oldState);
}
@@ -1489,15 +1492,15 @@ void TableBrowser::jumpToRow(const sqlb::ObjectIdentifier& table, std::string co
column = obj->primaryKey()->columnList().front();
// If column doesn't exist don't do anything
auto column_index = sqlb::findField(obj, column);
if(column_index == obj->fields.end())
auto column_it = sqlb::findField(obj, column);
if(column_it == obj->fields.end())
return;
// Jump to table
setCurrentTable(table);
// Set filter
m_settings[table].filterValues[static_cast<size_t>(column_index-obj->fields.begin()+1)] = value;
m_settings[table].filterValues[column_it->name()] = value;
refresh();
}

View File

@@ -29,7 +29,7 @@ struct BrowseDataTableSettings
using CondFormatMap = std::map<size_t, std::vector<CondFormat>>;
std::vector<sqlb::OrderBy> sortColumns;
std::map<int, int> columnWidths;
std::map<size_t, QString> filterValues;
std::map<std::string, QString> filterValues;
CondFormatMap condFormats;
CondFormatMap rowIdFormats;
std::map<size_t, QString> displayFormats;

View File

@@ -25,11 +25,8 @@ std::string Query::buildWherePart() const
{
for(auto i=m_where.cbegin();i!=m_where.cend();++i)
{
if(i->first >= m_column_names.size())
continue;
const auto it = findSelectedColumnByName(m_column_names.at(i->first));
std::string column = sqlb::escapeIdentifier(m_column_names.at(i->first));
const auto it = findSelectedColumnByName(i->first);
std::string column = sqlb::escapeIdentifier(i->first);
if(it != m_selected_columns.cend() && it->selector != column)
column = it->selector;
where += column + " " + i->second + " AND ";

View File

@@ -79,8 +79,8 @@ public:
const std::vector<SelectedColumn>& selectedColumns() const { return m_selected_columns; }
std::vector<SelectedColumn>& selectedColumns() { return m_selected_columns; }
const std::unordered_map<size_t, std::string>& where() const { return m_where; }
std::unordered_map<size_t, std::string>& where() { return m_where; }
const std::unordered_map<std::string, std::string>& where() const { return m_where; }
std::unordered_map<std::string, std::string>& where() { return m_where; }
const std::vector<std::string>& globalWhere() const { return m_global_where; }
std::vector<std::string>& globalWhere() { return m_global_where; }
@@ -95,8 +95,8 @@ private:
sqlb::ObjectIdentifier m_table;
std::vector<std::string> m_rowid_columns;
std::vector<SelectedColumn> m_selected_columns;
std::unordered_map<size_t, std::string> m_where; // TODO The two where variables should be merged into a single variable which ...
std::vector<std::string> m_global_where; // ... holds some sort of general tree structure for all sorts of where conditions.
std::unordered_map<std::string, std::string> m_where; // TODO The two where variables should be merged into a single variable which ...
std::vector<std::string> m_global_where; // ... holds some sort of general tree structure for all sorts of where conditions.
std::vector<OrderBy> m_sort;
std::vector<SelectedColumn>::iterator findSelectedColumnByName(const std::string& name);

View File

@@ -839,12 +839,12 @@ void SqliteTableModel::setCondFormats(const bool isRowIdFormat, size_t column, c
emit layoutChanged();
}
void SqliteTableModel::updateFilter(size_t column, const QString& value)
void SqliteTableModel::updateFilter(const std::string& column, const QString& value)
{
std::string whereClause = CondFormat::filterToSqlCondition(value, m_encoding);
// If the value was set to an empty string remove any filter for this column. Otherwise insert a new filter rule or replace the old one if there is already one
if(whereClause.empty())
if(whereClause.empty())
m_query.where().erase(column);
else
m_query.where()[column] = whereClause;

View File

@@ -143,7 +143,7 @@ public:
void reloadSettings();
public slots:
void updateFilter(size_t column, const QString& value);
void updateFilter(const std::string& column, const QString& value);
void updateGlobalFilter(const std::vector<QString>& values);
signals: