mirror of
https://github.com/sqlitebrowser/sqlitebrowser.git
synced 2026-01-20 11:00:44 -06:00
Support foreign key constraints referring to the same table (#933)
This commit is contained in:
@@ -26,7 +26,9 @@ EditTableDialog::EditTableDialog(DBBrowserDB& db, const QString& tableName, bool
|
||||
connect(ui->treeWidget, SIGNAL(itemChanged(QTreeWidgetItem*,int)),this,SLOT(itemChanged(QTreeWidgetItem*,int)));
|
||||
|
||||
// Set item delegate for foreign key column
|
||||
ui->treeWidget->setItemDelegateForColumn(kForeignKey, new ForeignKeyEditorDelegate(db, m_table, this));
|
||||
m_fkEditorDelegate = new ForeignKeyEditorDelegate(db, m_table, this);
|
||||
ui->treeWidget->setItemDelegateForColumn(kForeignKey, m_fkEditorDelegate);
|
||||
|
||||
// Editing an existing table?
|
||||
if(m_bNewTable == false)
|
||||
{
|
||||
@@ -194,7 +196,29 @@ void EditTableDialog::checkInput()
|
||||
valid = false;
|
||||
if(ui->treeWidget->topLevelItemCount() == 0)
|
||||
valid = false;
|
||||
m_table.setName(normTableName);
|
||||
if (normTableName != m_table.name()) {
|
||||
const QString oldTableName = m_table.name();
|
||||
m_table.setName(normTableName);
|
||||
m_fkEditorDelegate->updateTablesList(oldTableName);
|
||||
|
||||
bool fksEnabled = (pdb.getPragma("foreign_keys") == "1");
|
||||
|
||||
// update fk's that refer to table itself recursively
|
||||
sqlb::FieldVector fields = m_table.fields();
|
||||
foreach(sqlb::FieldPtr f, fields) {
|
||||
QSharedPointer<sqlb::ForeignKeyClause> fk = m_table.constraint({f}, sqlb::Constraint::ForeignKeyConstraintType).dynamicCast<sqlb::ForeignKeyClause>();
|
||||
if(!fk.isNull()) {
|
||||
if (oldTableName == fk->table()) {
|
||||
fk->setTable(normTableName);
|
||||
if(!fksEnabled)
|
||||
pdb.renameColumn(curTable, m_table, f->name(), f, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
populateFields();
|
||||
}
|
||||
|
||||
updateSqlText();
|
||||
ui->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(valid);
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
|
||||
class DBBrowserDB;
|
||||
class QTreeWidgetItem;
|
||||
class ForeignKeyEditorDelegate;
|
||||
|
||||
namespace Ui {
|
||||
class EditTableDialog;
|
||||
@@ -61,6 +62,7 @@ private slots:
|
||||
private:
|
||||
Ui::EditTableDialog* ui;
|
||||
DBBrowserDB& pdb;
|
||||
ForeignKeyEditorDelegate* m_fkEditorDelegate;
|
||||
QString curTable;
|
||||
sqlb::Table m_table;
|
||||
QStringList types;
|
||||
|
||||
@@ -78,7 +78,13 @@ ForeignKeyEditorDelegate::ForeignKeyEditorDelegate(const DBBrowserDB& db, sqlb::
|
||||
, m_db(db)
|
||||
, m_table(table)
|
||||
{
|
||||
|
||||
const auto objects = m_db.getBrowsableObjects();
|
||||
for (auto obj : objects) {
|
||||
if ("table" == obj.gettype()) {
|
||||
QString tableName = obj.table.name();
|
||||
m_tablesIds.insert(tableName, obj.table.fieldNames());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
QWidget* ForeignKeyEditorDelegate::createEditor(QWidget* parent, const QStyleOptionViewItem& option, const QModelIndex& index) const
|
||||
@@ -99,6 +105,9 @@ QWidget* ForeignKeyEditorDelegate::createEditor(QWidget* parent, const QStyleOpt
|
||||
box->setCurrentIndex(0);
|
||||
});
|
||||
|
||||
editor->tablesComboBox->clear();
|
||||
editor->tablesComboBox->addItems(m_tablesIds.keys());
|
||||
|
||||
return editor;
|
||||
}
|
||||
|
||||
@@ -106,17 +115,6 @@ void ForeignKeyEditorDelegate::setEditorData(QWidget* editor, const QModelIndex&
|
||||
{
|
||||
ForeignKeyEditor* fkEditor = static_cast<ForeignKeyEditor*>(editor);
|
||||
|
||||
m_tablesIds.clear();
|
||||
const auto objects = m_db.getBrowsableObjects();
|
||||
for (auto obj : objects) {
|
||||
if ("table" == obj.gettype()) {
|
||||
QString tableName = obj.table.name();
|
||||
m_tablesIds.insert(tableName, obj.table.fieldNames());
|
||||
}
|
||||
}
|
||||
|
||||
fkEditor->tablesComboBox->addItems(m_tablesIds.keys());
|
||||
|
||||
int column = index.row(); // weird? I know right
|
||||
sqlb::FieldPtr field = m_table.fields().at(column);
|
||||
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
|
||||
editor->setGeometry(option.rect);
|
||||
}
|
||||
|
||||
void ForeignKeyEditorDelegate::updateTablesList(const QString& oldTableName)
|
||||
{
|
||||
// this is used for recursive table constraints when
|
||||
// table column references column within same table
|
||||
m_tablesIds.remove(oldTableName);
|
||||
m_tablesIds.insert(m_table.name(), m_table.fieldNames());
|
||||
}
|
||||
|
||||
#include "ForeignKeyEditorDelegate.moc"
|
||||
|
||||
@@ -25,6 +25,8 @@ public:
|
||||
void setModelData(QWidget* editor, QAbstractItemModel* model, const QModelIndex& index) const Q_DECL_OVERRIDE;
|
||||
void updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index) const Q_DECL_OVERRIDE;
|
||||
|
||||
void updateTablesList(const QString& oldTableName);
|
||||
|
||||
private:
|
||||
const DBBrowserDB& m_db;
|
||||
sqlb::Table& m_table;
|
||||
|
||||
Reference in New Issue
Block a user