Skip to content

Commit a9e6fe4

Browse files
committed
Support adding custom constraints in Edit Table dialog
This adds support for adding custom constraint in the Edit Table dialog, e.g. for adding multi-column unique constraints.
1 parent 99c7523 commit a9e6fe4

File tree

5 files changed

+113
-33
lines changed

5 files changed

+113
-33
lines changed

src/EditTableDialog.cpp

Lines changed: 50 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,13 @@
66
#include "sqlitedb.h"
77
#include "SelectItemsPopup.h"
88

9-
#include <QMessageBox>
10-
#include <QPushButton>
119
#include <QComboBox>
1210
#include <QDateTime>
1311
#include <QKeyEvent>
12+
#include <QMenu>
13+
#include <QMessageBox>
14+
#include <QPushButton>
15+
1416
#include <algorithm>
1517

1618
Q_DECLARE_METATYPE(sqlb::ConstraintPtr)
@@ -30,13 +32,22 @@ EditTableDialog::EditTableDialog(DBBrowserDB& db, const sqlb::ObjectIdentifier&
3032
connect(ui->treeWidget, &QTreeWidget::itemChanged, this, &EditTableDialog::fieldItemChanged);
3133
connect(ui->tableConstraints, &QTableWidget::itemChanged, this, &EditTableDialog::constraintItemChanged);
3234

33-
// TODO Remove this once we have added support for this button
34-
ui->buttonAddConstraint->setVisible(false);
35-
3635
// Set item delegate for foreign key column
3736
m_fkEditorDelegate = new ForeignKeyEditorDelegate(db, m_table, this);
3837
ui->treeWidget->setItemDelegateForColumn(kForeignKey, m_fkEditorDelegate);
3938

39+
// Set up popup menu for adding constraints
40+
QMenu* constraint_menu = new QMenu(this);
41+
constraint_menu->addAction(ui->actionAddPrimaryKey);
42+
constraint_menu->addAction(ui->actionAddForeignKey);
43+
constraint_menu->addAction(ui->actionAddUniqueConstraint);
44+
constraint_menu->addAction(ui->actionAddCheckConstraint);
45+
connect(ui->actionAddPrimaryKey, &QAction::triggered, [this]() { addConstraint(sqlb::Constraint::PrimaryKeyConstraintType); });
46+
connect(ui->actionAddForeignKey, &QAction::triggered, [this]() { addConstraint(sqlb::Constraint::ForeignKeyConstraintType); });
47+
connect(ui->actionAddUniqueConstraint, &QAction::triggered, [this]() { addConstraint(sqlb::Constraint::UniqueConstraintType); });
48+
connect(ui->actionAddCheckConstraint, &QAction::triggered, [this]() { addConstraint(sqlb::Constraint::CheckConstraintType); });
49+
ui->buttonAddConstraint->setMenu(constraint_menu);
50+
4051
// Editing an existing table?
4152
if(m_bNewTable == false)
4253
{
@@ -241,38 +252,21 @@ void EditTableDialog::populateConstraints()
241252
// Handle change of constraint type. Effectively this means removing the old constraint and replacing it by an entirely new one.
242253
// Only the column list and the name can be migrated to the new constraint.
243254

244-
// Create new constraint depending on selected type
245-
sqlb::ConstraintPtr new_constraint;
246-
switch(index)
255+
// Make sure there is only one primary key at a time
256+
if(index == 0 && !m_table.primaryKey().empty())
247257
{
248-
case 0:
249-
// Make sure there is only one primary key at a time
250-
if(!m_table.primaryKey().empty())
251-
{
252-
QMessageBox::warning(this, qApp->applicationName(), tr("There can only be one primary key for each table. Please modify the existing primary "
253-
"key instead."));
254-
255-
// Set combo box back to original constraint type
256-
type->blockSignals(true);
257-
type->setCurrentIndex(constraint->type());
258-
type->blockSignals(false);
259-
return;
260-
}
258+
QMessageBox::warning(this, qApp->applicationName(), tr("There can only be one primary key for each table. Please modify the existing primary "
259+
"key instead."));
261260

262-
new_constraint = sqlb::ConstraintPtr(new sqlb::PrimaryKeyConstraint());
263-
break;
264-
case 1:
265-
new_constraint = sqlb::ConstraintPtr(new sqlb::UniqueConstraint());
266-
break;
267-
case 2:
268-
new_constraint = sqlb::ConstraintPtr(new sqlb::ForeignKeyClause());
269-
break;
270-
case 3:
271-
new_constraint = sqlb::ConstraintPtr(new sqlb::CheckConstraint());
272-
break;
273-
default:
261+
// Set combo box back to original constraint type
262+
type->blockSignals(true);
263+
type->setCurrentIndex(constraint->type());
264+
type->blockSignals(false);
274265
return;
275266
}
267+
268+
// Create new constraint depending on selected type
269+
sqlb::ConstraintPtr new_constraint = sqlb::Constraint::makeConstraint(static_cast<sqlb::Constraint::ConstraintTypes>(index));
276270
new_constraint->setName(constraint->name());
277271
new_constraint->column_list = constraint->column_list;
278272

@@ -907,3 +901,26 @@ void EditTableDialog::removeConstraint()
907901
updateSqlText();
908902
populateFields();
909903
}
904+
905+
void EditTableDialog::addConstraint(sqlb::Constraint::ConstraintTypes type)
906+
{
907+
// There can only be one primary key
908+
if(type == sqlb::Constraint::PrimaryKeyConstraintType)
909+
{
910+
if(!m_table.primaryKey().empty())
911+
{
912+
QMessageBox::information(this, qApp->applicationName(), tr("There can only be one primary key for each table. Please modify the existing primary "
913+
"key instead."));
914+
return;
915+
}
916+
}
917+
918+
// Create new constraint
919+
sqlb::ConstraintPtr constraint = sqlb::Constraint::makeConstraint(type);
920+
m_table.addConstraint(constraint);
921+
922+
// Update SQL and view
923+
populateFields();
924+
populateConstraints();
925+
updateSqlText();
926+
}

src/EditTableDialog.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@ private slots:
7373
void setWithoutRowid(bool without_rowid);
7474
void changeSchema(const QString& schema);
7575
void removeConstraint();
76+
void addConstraint(sqlb::Constraint::ConstraintTypes type);
7677

7778
private:
7879
Ui::EditTableDialog* ui;

src/EditTableDialog.ui

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -300,6 +300,9 @@
300300
<iconset resource="icons/icons.qrc">
301301
<normaloff>:/icons/field_add</normaloff>:/icons/field_add</iconset>
302302
</property>
303+
<property name="popupMode">
304+
<enum>QToolButton::InstantPopup</enum>
305+
</property>
303306
<property name="toolButtonStyle">
304307
<enum>Qt::ToolButtonTextBesideIcon</enum>
305308
</property>
@@ -401,6 +404,46 @@
401404
</widget>
402405
</item>
403406
</layout>
407+
<action name="actionAddPrimaryKey">
408+
<property name="icon">
409+
<iconset resource="icons/icons.qrc">
410+
<normaloff>:/icons/field_key</normaloff>:/icons/field_key</iconset>
411+
</property>
412+
<property name="text">
413+
<string>Primary Key</string>
414+
</property>
415+
<property name="toolTip">
416+
<string>Add a primary key constraint</string>
417+
</property>
418+
</action>
419+
<action name="actionAddForeignKey">
420+
<property name="icon">
421+
<iconset resource="icons/icons.qrc">
422+
<normaloff>:/icons/field_fk</normaloff>:/icons/field_fk</iconset>
423+
</property>
424+
<property name="text">
425+
<string>Foreign Key</string>
426+
</property>
427+
<property name="toolTip">
428+
<string>Add a foreign key constraint</string>
429+
</property>
430+
</action>
431+
<action name="actionAddUniqueConstraint">
432+
<property name="text">
433+
<string>Unique</string>
434+
</property>
435+
<property name="toolTip">
436+
<string>Add a unique constraint</string>
437+
</property>
438+
</action>
439+
<action name="actionAddCheckConstraint">
440+
<property name="text">
441+
<string>Check</string>
442+
</property>
443+
<property name="toolTip">
444+
<string>Add a check constraint</string>
445+
</property>
446+
</action>
404447
</widget>
405448
<customwidgets>
406449
<customwidget>

src/sql/sqlitetypes.cpp

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,23 @@ std::string Object::typeToString(Types type)
131131
return "";
132132
}
133133

134+
ConstraintPtr Constraint::makeConstraint(ConstraintTypes type)
135+
{
136+
switch(type)
137+
{
138+
case PrimaryKeyConstraintType:
139+
return sqlb::ConstraintPtr(new sqlb::PrimaryKeyConstraint());
140+
case UniqueConstraintType:
141+
return sqlb::ConstraintPtr(new sqlb::UniqueConstraint());
142+
case ForeignKeyConstraintType:
143+
return sqlb::ConstraintPtr(new sqlb::ForeignKeyClause());
144+
case CheckConstraintType:
145+
return sqlb::ConstraintPtr(new sqlb::CheckConstraint());
146+
default:
147+
return nullptr;
148+
}
149+
}
150+
134151
bool ForeignKeyClause::isSet() const
135152
{
136153
return m_override.size() || m_table.size();

src/sql/sqlitetypes.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,8 @@ class Constraint
134134
}
135135
virtual ~Constraint() {}
136136

137+
static ConstraintPtr makeConstraint(ConstraintTypes type);
138+
137139
virtual ConstraintTypes type() const = 0;
138140

139141
void setName(const std::string& name) { m_name = name; }

0 commit comments

Comments
 (0)