Skip to content

Commit 46a55bd

Browse files
authored
Support foreign key constraints referring to the same table (#933)
1 parent 11ca36e commit 46a55bd

4 files changed

Lines changed: 48 additions & 14 deletions

File tree

src/EditTableDialog.cpp

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,9 @@ EditTableDialog::EditTableDialog(DBBrowserDB& db, const QString& tableName, bool
2626
connect(ui->treeWidget, SIGNAL(itemChanged(QTreeWidgetItem*,int)),this,SLOT(itemChanged(QTreeWidgetItem*,int)));
2727

2828
// Set item delegate for foreign key column
29-
ui->treeWidget->setItemDelegateForColumn(kForeignKey, new ForeignKeyEditorDelegate(db, m_table, this));
29+
m_fkEditorDelegate = new ForeignKeyEditorDelegate(db, m_table, this);
30+
ui->treeWidget->setItemDelegateForColumn(kForeignKey, m_fkEditorDelegate);
31+
3032
// Editing an existing table?
3133
if(m_bNewTable == false)
3234
{
@@ -194,7 +196,29 @@ void EditTableDialog::checkInput()
194196
valid = false;
195197
if(ui->treeWidget->topLevelItemCount() == 0)
196198
valid = false;
197-
m_table.setName(normTableName);
199+
if (normTableName != m_table.name()) {
200+
const QString oldTableName = m_table.name();
201+
m_table.setName(normTableName);
202+
m_fkEditorDelegate->updateTablesList(oldTableName);
203+
204+
bool fksEnabled = (pdb.getPragma("foreign_keys") == "1");
205+
206+
// update fk's that refer to table itself recursively
207+
sqlb::FieldVector fields = m_table.fields();
208+
foreach(sqlb::FieldPtr f, fields) {
209+
QSharedPointer<sqlb::ForeignKeyClause> fk = m_table.constraint({f}, sqlb::Constraint::ForeignKeyConstraintType).dynamicCast<sqlb::ForeignKeyClause>();
210+
if(!fk.isNull()) {
211+
if (oldTableName == fk->table()) {
212+
fk->setTable(normTableName);
213+
if(!fksEnabled)
214+
pdb.renameColumn(curTable, m_table, f->name(), f, 0);
215+
}
216+
}
217+
}
218+
219+
populateFields();
220+
}
221+
198222
updateSqlText();
199223
ui->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(valid);
200224
}

src/EditTableDialog.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77

88
class DBBrowserDB;
99
class QTreeWidgetItem;
10+
class ForeignKeyEditorDelegate;
1011

1112
namespace Ui {
1213
class EditTableDialog;
@@ -61,6 +62,7 @@ private slots:
6162
private:
6263
Ui::EditTableDialog* ui;
6364
DBBrowserDB& pdb;
65+
ForeignKeyEditorDelegate* m_fkEditorDelegate;
6466
QString curTable;
6567
sqlb::Table m_table;
6668
QStringList types;

src/ForeignKeyEditorDelegate.cpp

Lines changed: 18 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,13 @@ ForeignKeyEditorDelegate::ForeignKeyEditorDelegate(const DBBrowserDB& db, sqlb::
7878
, m_db(db)
7979
, m_table(table)
8080
{
81-
81+
const auto objects = m_db.getBrowsableObjects();
82+
for (auto obj : objects) {
83+
if ("table" == obj.gettype()) {
84+
QString tableName = obj.table.name();
85+
m_tablesIds.insert(tableName, obj.table.fieldNames());
86+
}
87+
}
8288
}
8389

8490
QWidget* ForeignKeyEditorDelegate::createEditor(QWidget* parent, const QStyleOptionViewItem& option, const QModelIndex& index) const
@@ -99,24 +105,16 @@ QWidget* ForeignKeyEditorDelegate::createEditor(QWidget* parent, const QStyleOpt
99105
box->setCurrentIndex(0);
100106
});
101107

108+
editor->tablesComboBox->clear();
109+
editor->tablesComboBox->addItems(m_tablesIds.keys());
110+
102111
return editor;
103112
}
104113

105114
void ForeignKeyEditorDelegate::setEditorData(QWidget* editor, const QModelIndex& index) const
106115
{
107116
ForeignKeyEditor* fkEditor = static_cast<ForeignKeyEditor*>(editor);
108117

109-
m_tablesIds.clear();
110-
const auto objects = m_db.getBrowsableObjects();
111-
for (auto obj : objects) {
112-
if ("table" == obj.gettype()) {
113-
QString tableName = obj.table.name();
114-
m_tablesIds.insert(tableName, obj.table.fieldNames());
115-
}
116-
}
117-
118-
fkEditor->tablesComboBox->addItems(m_tablesIds.keys());
119-
120118
int column = index.row(); // weird? I know right
121119
sqlb::FieldPtr field = m_table.fields().at(column);
122120
QSharedPointer<sqlb::ForeignKeyClause> fk = m_table.constraint({field}, sqlb::Constraint::ForeignKeyConstraintType).dynamicCast<sqlb::ForeignKeyClause>();
@@ -170,4 +168,12 @@ void ForeignKeyEditorDelegate::updateEditorGeometry(QWidget* editor, const QStyl
170168
editor->setGeometry(option.rect);
171169
}
172170

171+
void ForeignKeyEditorDelegate::updateTablesList(const QString& oldTableName)
172+
{
173+
// this is used for recursive table constraints when
174+
// table column references column within same table
175+
m_tablesIds.remove(oldTableName);
176+
m_tablesIds.insert(m_table.name(), m_table.fieldNames());
177+
}
178+
173179
#include "ForeignKeyEditorDelegate.moc"

src/ForeignKeyEditorDelegate.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@ class ForeignKeyEditorDelegate : public QStyledItemDelegate
2525
void setModelData(QWidget* editor, QAbstractItemModel* model, const QModelIndex& index) const Q_DECL_OVERRIDE;
2626
void updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index) const Q_DECL_OVERRIDE;
2727

28+
void updateTablesList(const QString& oldTableName);
29+
2830
private:
2931
const DBBrowserDB& m_db;
3032
sqlb::Table& m_table;

0 commit comments

Comments
 (0)