#include "EditIndexDialog.h"#include "ui_EditIndexDialog.h"#include "sqlitedb.h"#include <QMessageBox>#include <QPushButton>EditIndexDialog::EditIndexDialog(DBBrowserDB& db, const sqlb::ObjectIdentifier& indexName, bool createIndex, QWidget* parent): QDialog(parent),pdb(db),curIndex(indexName),index(indexName.name()),newIndex(createIndex),ui(new Ui::EditIndexDialog),m_sRestorePointName(pdb.generateSavepointName("editindex")){// Create UIui->setupUi(this);ui->sqlTextEdit->setReadOnly(true);// Get list of tables, sort it alphabetically and fill the comboboxstd::map<std::string, sqlb::ObjectIdentifier> dbobjs; // Map from display name to full object identifierif(newIndex) // If this is a new index, offer all tables of all database schemata{for(const auto& it : pdb.schemata){auto tables = it.second.equal_range("table");for(auto jt=tables.first;jt!=tables.second;++jt){// Only show the schema name for non-main schematasqlb::ObjectIdentifier obj(it.first, jt->second->name());dbobjs.insert({obj.toDisplayString(), obj});}}} else { // If this is an existing index, only offer tables of the current database schemaauto tables = pdb.schemata[curIndex.schema()].equal_range("table");for(auto it=tables.first;it!=tables.second;++it){// Only show the schema name for non-main schematasqlb::ObjectIdentifier obj(curIndex.schema(), it->second->name());dbobjs.insert({obj.toDisplayString(), obj});}}ui->comboTableName->blockSignals(true);for(auto it=dbobjs.cbegin();it!=dbobjs.cend();++it)ui->comboTableName->addItem(QIcon(QString(":icons/table")), QString::fromStdString(it->first), QString::fromStdString(it->second.toSerialised()));ui->comboTableName->blockSignals(false);QHeaderView *tableHeaderView = ui->tableIndexColumns->horizontalHeader();tableHeaderView->setSectionResizeMode(0, QHeaderView::Stretch);// Editing an existing index?if(!newIndex){// Load the current layout and fill in the dialog fieldsindex = *(pdb.getObjectByName<sqlb::Index>(curIndex));ui->editIndexName->blockSignals(true);ui->editIndexName->setText(QString::fromStdString(index.name()));ui->editIndexName->blockSignals(false);ui->checkIndexUnique->blockSignals(true);ui->checkIndexUnique->setChecked(index.unique());ui->checkIndexUnique->blockSignals(false);ui->comboTableName->blockSignals(true);ui->comboTableName->setCurrentText(QString::fromStdString(index.table()));ui->comboTableName->blockSignals(false);ui->editPartialClause->blockSignals(true);ui->editPartialClause->setText(QString::fromStdString(index.whereExpr()));ui->editPartialClause->blockSignals(false);tableChanged(QString::fromStdString(index.table()), true);} else {tableChanged(ui->comboTableName->currentText(), false);}// Add event handler for index column name changes. These are only allowed for expression columns, though.connect(ui->tableIndexColumns, &QTableWidget::itemChanged,[=](QTableWidgetItem* item){index.fields[static_cast<size_t>(item->row())].setName(item->text().toStdString());updateSqlText();});// Create a savepoint to revert back topdb.setSavepoint(m_sRestorePointName);}EditIndexDialog::~EditIndexDialog(){delete ui;}void EditIndexDialog::tableChanged(const QString& new_table, bool initialLoad){// Set the table name and clear all index columnsif(!initialLoad){index.setTable(sqlb::ObjectIdentifier(ui->comboTableName->currentData().toString().toStdString()).name());index.fields.clear();}// Stop here if table name is emptyif(new_table.isEmpty()){// Call checkInput() before to make sure the OK button is disabledcheckInput();return;}updateColumnLists();}void EditIndexDialog::updateColumnLists(){// Fill the table column listsqlb::TablePtr table = pdb.getObjectByName<sqlb::Table>(sqlb::ObjectIdentifier(ui->comboTableName->currentData().toString().toStdString()));if(!table)return;sqlb::FieldInfoList tableFields = table->fieldInformation();ui->tableTableColumns->setRowCount(static_cast<int>(tableFields.size()));int tableRows = 0;for(size_t i=0;i<tableFields.size();++i){// When we're doing the initial loading and this field already is in the index to edit, then don't add it to the// list of table columns. It will be added to the list of index columns in the next step. When this is not the initial// loading, the index column list is empty, so this check will always be true.if(sqlb::findField(index, tableFields.at(i).name) == index.fields.end()){// Put the name of the field in the first columnQTableWidgetItem* name = new QTableWidgetItem(QString::fromStdString(tableFields.at(i).name));name->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled);ui->tableTableColumns->setItem(tableRows, 0, name);// Put the data type in the second columnQTableWidgetItem* type = new QTableWidgetItem(QString::fromStdString(tableFields.at(i).type));type->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled);ui->tableTableColumns->setItem(tableRows, 1, type);tableRows++;}}// Set row count to actual count. This is needed for the intial loading, when some rows might have been omitted because they were used in the indexui->tableTableColumns->setRowCount(tableRows);// Fill the index column list. This is done separately from the table column to include expression columns (these are not found in the original// table) and to preserve the order of the index columnsauto indexFields = index.fields;ui->tableIndexColumns->blockSignals(true);ui->tableIndexColumns->setRowCount(static_cast<int>(indexFields.size()));for(size_t i=0;i<indexFields.size();++i){// Put the name of the field in the first columnQTableWidgetItem* name = new QTableWidgetItem(QString::fromStdString(indexFields.at(i).name()));Qt::ItemFlags flags = Qt::ItemIsSelectable | Qt::ItemIsEnabled;if(indexFields.at(i).expression())flags |= Qt::ItemIsEditable;name->setFlags(flags);ui->tableIndexColumns->setItem(static_cast<int>(i), 0, name);// And put a combobox to select the order in which to index the field in the last columnQComboBox* order = new QComboBox(this);order->addItem("");order->addItem("ASC");order->addItem("DESC");order->setCurrentText(QString::fromStdString(indexFields.at(i).order()).toUpper());ui->tableIndexColumns->setCellWidget(static_cast<int>(i), 1, order);connect(order, &QComboBox::currentTextChanged,[=](QString new_order){auto colnum = sqlb::findField(index, indexFields.at(i).name());if(colnum != index.fields.end()){colnum->setOrder(new_order.toStdString());updateSqlText();}});}ui->tableIndexColumns->blockSignals(false);checkInput();}void EditIndexDialog::addToIndex(const QModelIndex& idx){// Get current row numberint row;if(idx.isValid())row = idx.row();elserow = ui->tableTableColumns->currentRow();// No row selected? Abort.if(row == -1)return;// Add field to indexindex.fields.emplace_back(ui->tableTableColumns->item(row, 0)->text().toStdString(), // Column namefalse, // Is expression""); // Order// Update UIupdateColumnLists();}void EditIndexDialog::removeFromIndex(const QModelIndex& idx){// Get current row numberint row;if(idx.isValid())row = idx.row();elserow = ui->tableIndexColumns->currentRow();// No row selected? Abort.if(row == -1)return;// If this is an expression column and the action was triggered by a double click event instead of a button click,// we won't remove the expression column because it's too likely that this was only done by accident by the user.// Instead just open the expression column for editing.if(index.fields[static_cast<size_t>(row)].expression() && sender() != ui->buttonFromIndex){ui->tableIndexColumns->editItem(ui->tableIndexColumns->item(row, 0));return;}// Remove column from indexsqlb::removeField(index, ui->tableIndexColumns->item(row, 0)->text().toStdString());// Update UIupdateColumnLists();}void EditIndexDialog::checkInput(){// Check if index name is setbool valid = true;if(ui->editIndexName->text().isEmpty())valid = false;// Check if a table is selected (this is especially important in the case where there are no tables in the database yet).if(ui->comboTableName->currentText().isNull())valid = false;// Check if index has any columnsif(index.fields.size() == 0)valid = false;// Only activate OK button if index data is validui->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(valid);// Set the index name and the unique flagindex.setName(ui->editIndexName->text().toStdString());index.setUnique(ui->checkIndexUnique->isChecked());index.setWhereExpr(ui->editPartialClause->text().toStdString());updateSqlText();}void EditIndexDialog::accept(){// When editing an index, delete the old one firstif(!newIndex){if(!pdb.executeSQL(QString("DROP INDEX IF EXISTS %1;").arg(QString::fromStdString(curIndex.toString())))){QMessageBox::warning(this, qApp->applicationName(), tr("Deleting the old index failed:\n%1").arg(pdb.lastError()));return;}}// Create the new index in the schema of the selected tableif(pdb.executeSQL(QString::fromStdString(index.sql(sqlb::ObjectIdentifier(ui->comboTableName->currentData().toString().toStdString()).schema()))))QDialog::accept();elseQMessageBox::warning(this, QApplication::applicationName(), tr("Creating the index failed:\n%1").arg(pdb.lastError()));}void EditIndexDialog::reject(){// Rollback to our savepointpdb.revertToSavepoint(m_sRestorePointName);QDialog::reject();}void EditIndexDialog::updateSqlText(){ui->sqlTextEdit->setText(QString::fromStdString(index.sql(sqlb::ObjectIdentifier(ui->comboTableName->currentData().toString().toStdString()).schema())));}void EditIndexDialog::moveColumnUp(){moveCurrentColumn(false);}void EditIndexDialog::moveColumnDown(){moveCurrentColumn(true);}void EditIndexDialog::moveCurrentColumn(bool down){// Get current row number and calculate row number after the movement. Check the valuesint currentRow = ui->tableIndexColumns->currentRow();if(currentRow == -1)return;int newRow = currentRow + (down ? 1 : -1);if(newRow < 0)return;if(newRow >= ui->tableIndexColumns->rowCount())return;// Swap the columnsstd::swap(index.fields[static_cast<size_t>(currentRow)], index.fields[static_cast<size_t>(newRow)]);// Update UIupdateColumnLists();// Select old row at new positionui->tableIndexColumns->selectRow(newRow);}void EditIndexDialog::addExpressionColumn(){// Check if there already is an empty expression columnauto field_it = sqlb::findField(index, "");int row = static_cast<int>(std::distance(index.fields.begin(), field_it));if(field_it == index.fields.end()){// There is no empty expression column yet, so add one.// Add new expression column to the indexindex.fields.emplace_back("", // Column nametrue, // Is expression""); // Order// Update UIupdateColumnLists();// Get row number of new columnrow = ui->tableIndexColumns->rowCount() - 1;}// Now we should have the row number of the empty expression column, no matter if it was newly added or it already existed.// Select the row for editingui->tableIndexColumns->editItem(ui->tableIndexColumns->item(row, 0));}
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。