Add possibility to change the type of table constraints in Edit Table

Enable the combo box in the Edit Table dialog to change the type of a
table constraint and add the code to try to transform a constraint from
one type into another as best as possible.
This commit is contained in:
Martin Kleusberg
2019-07-28 22:33:36 +02:00
parent cb694dd2c6
commit 05e2defe33
3 changed files with 62 additions and 21 deletions

View File

@@ -232,29 +232,58 @@ void EditTableDialog::populateConstraints()
// Type
QComboBox* type = new QComboBox(this);
type->addItem(tr("Primary Key"));
type->addItem(tr("Primary Key")); // NOTE: The order of the items here have to match the order in the sqlb::Constraint::ConstraintTypes enum!
type->addItem(tr("Unique"));
type->addItem(tr("Foreign Key"));
type->addItem(tr("Check"));
switch(constraint->type())
{
case sqlb::Constraint::PrimaryKeyConstraintType:
type->setCurrentIndex(0);
break;
case sqlb::Constraint::UniqueConstraintType:
type->setCurrentIndex(1);
break;
case sqlb::Constraint::ForeignKeyConstraintType:
type->setCurrentIndex(2);
break;
case sqlb::Constraint::CheckConstraintType:
type->setCurrentIndex(3);
break;
default:
type->addItem(tr("Unknown"));
type->setCurrentIndex(type->count()-1);
}
type->setEnabled(false); // TODO Remove this once we have added support for changing constraint types
type->setCurrentIndex(constraint->type());
connect(type, static_cast<void(QComboBox::*)(int)>(&QComboBox::currentIndexChanged), [this, type, constraint](int index) {
// Handle change of constraint type. Effectively this means removing the old constraint and replacing it by an entirely new one.
// Only the column list and the name can be migrated to the new constraint.
// Create new constraint depending on selected type
sqlb::ConstraintPtr new_constraint;
switch(index)
{
case 0:
// Make sure there is only one primary key at a time
if(!m_table.primaryKey().empty())
{
QMessageBox::warning(this, qApp->applicationName(), tr("There can only be one primary key for each table. Please modify the existing primary "
"key instead."));
// Set combo box back to original constraint type
type->blockSignals(true);
type->setCurrentIndex(constraint->type());
type->blockSignals(false);
return;
}
new_constraint = sqlb::ConstraintPtr(new sqlb::PrimaryKeyConstraint());
break;
case 1:
new_constraint = sqlb::ConstraintPtr(new sqlb::UniqueConstraint());
break;
case 2:
new_constraint = sqlb::ConstraintPtr(new sqlb::ForeignKeyClause());
break;
case 3:
new_constraint = sqlb::ConstraintPtr(new sqlb::CheckConstraint());
break;
default:
return;
}
new_constraint->setName(constraint->name());
new_constraint->column_list = constraint->column_list;
// Replace old by new constraint
m_table.replaceConstraint(constraint, new_constraint);
// Update SQL and view
populateFields();
populateConstraints();
updateSqlText();
});
ui->tableConstraints->setCellWidget(row, kConstraintType, type);
// Name

View File

@@ -534,6 +534,16 @@ void Table::setConstraints(const ConstraintSet& constraints)
m_constraints = constraints;
}
void Table::replaceConstraint(ConstraintPtr from, ConstraintPtr to)
{
auto it = m_constraints.find(from);
if(it == m_constraints.end())
return;
m_constraints.erase(it); // Erase old constraint
m_constraints.insert(to); // Insert new constraint
}
StringVector& Table::primaryKeyRef()
{
return const_cast<StringVector&>(static_cast<const Table*>(this)->primaryKey());

View File

@@ -119,11 +119,12 @@ class Constraint
public:
enum ConstraintTypes
{
NoType,
PrimaryKeyConstraintType,
UniqueConstraintType,
ForeignKeyConstraintType,
CheckConstraintType,
NoType = 999,
};
explicit Constraint(const StringVector& columns = {}, const std::string& name = std::string())
@@ -338,6 +339,7 @@ public:
std::vector<ConstraintPtr> constraints(const StringVector& vStrFields = StringVector(), Constraint::ConstraintTypes type = Constraint::NoType) const;
ConstraintSet allConstraints() const { return m_constraints; }
void setConstraints(const ConstraintSet& constraints);
void replaceConstraint(ConstraintPtr from, ConstraintPtr to);
StringVector& primaryKeyRef();
const StringVector& primaryKey() const;
void removeKeyFromAllConstraints(const std::string& key);