aboutsummaryrefslogtreecommitdiffstats
path: root/SQLiteStudio3/guiSQLiteStudio/constraints/columnforeignkeypanel.cpp
diff options
context:
space:
mode:
authorLibravatarUnit 193 <unit193@ubuntu.com>2014-12-06 17:33:25 -0500
committerLibravatarUnit 193 <unit193@ubuntu.com>2014-12-06 17:33:25 -0500
commit7167ce41b61d2ba2cdb526777a4233eb84a3b66a (patch)
treea35c14143716e1f2c98f808c81f89426045a946f /SQLiteStudio3/guiSQLiteStudio/constraints/columnforeignkeypanel.cpp
Imported Upstream version 2.99.6upstream/2.99.6
Diffstat (limited to 'SQLiteStudio3/guiSQLiteStudio/constraints/columnforeignkeypanel.cpp')
-rw-r--r--SQLiteStudio3/guiSQLiteStudio/constraints/columnforeignkeypanel.cpp266
1 files changed, 266 insertions, 0 deletions
diff --git a/SQLiteStudio3/guiSQLiteStudio/constraints/columnforeignkeypanel.cpp b/SQLiteStudio3/guiSQLiteStudio/constraints/columnforeignkeypanel.cpp
new file mode 100644
index 0000000..cf234f7
--- /dev/null
+++ b/SQLiteStudio3/guiSQLiteStudio/constraints/columnforeignkeypanel.cpp
@@ -0,0 +1,266 @@
+#include "columnforeignkeypanel.h"
+#include "ui_columnforeignkeypanel.h"
+#include "schemaresolver.h"
+#include "uiutils.h"
+#include <QDebug>
+#include <QSignalMapper>
+
+ColumnForeignKeyPanel::ColumnForeignKeyPanel(QWidget *parent) :
+ ConstraintPanel(parent),
+ ui(new Ui::ColumnForeignKeyPanel)
+{
+ ui->setupUi(this);
+ init();
+}
+
+ColumnForeignKeyPanel::~ColumnForeignKeyPanel()
+{
+ delete ui;
+}
+
+void ColumnForeignKeyPanel::changeEvent(QEvent *e)
+{
+ QWidget::changeEvent(e);
+ switch (e->type()) {
+ case QEvent::LanguageChange:
+ ui->retranslateUi(this);
+ break;
+ default:
+ break;
+ }
+}
+
+
+bool ColumnForeignKeyPanel::validate()
+{
+ bool tableOk = (ui->fkTableCombo->currentIndex() > -1);
+ bool columnOk = (ui->fkColumnCombo->currentIndex() > -1);
+ bool nameOk = !ui->namedCheckBox->isChecked() || !ui->nameEdit->text().isEmpty();
+
+ setValidState(ui->fkTableCombo, tableOk, tr("Pick the foreign table."));
+ setValidState(ui->fkColumnCombo, columnOk, tr("Pick the foreign column."));
+ setValidState(ui->nameEdit, nameOk, tr("Enter a name of the constraint."));
+
+ return tableOk && columnOk && nameOk;
+}
+
+void ColumnForeignKeyPanel::constraintAvailable()
+{
+ readTables();
+ readConstraint();
+}
+
+void ColumnForeignKeyPanel::init()
+{
+ setFocusProxy(ui->fkTableCombo);
+
+ ui->fkColumnCombo->setModel(&fkColumnsModel);
+ connect(ui->fkColumnCombo, SIGNAL(currentIndexChanged(int)), this, SIGNAL(updateValidation()));
+
+ connect(ui->namedCheckBox, SIGNAL(toggled(bool)), this, SIGNAL(updateValidation()));
+ connect(ui->nameEdit, SIGNAL(textChanged(QString)), this, SIGNAL(updateValidation()));
+ connect(ui->fkTableCombo, SIGNAL(currentIndexChanged(int)), this, SIGNAL(updateValidation()));
+ connect(ui->fkTableCombo, SIGNAL(currentIndexChanged(int)), this, SLOT(updateFkColumns()));
+ connect(ui->fkTableCombo, SIGNAL(currentIndexChanged(int)), this, SLOT(updateState()));
+ connect(ui->onDeleteCheckBox, SIGNAL(toggled(bool)), this, SLOT(updateState()));
+ connect(ui->onUpdateCheckBox, SIGNAL(toggled(bool)), this, SLOT(updateState()));
+ connect(ui->matchCheckBox, SIGNAL(toggled(bool)), this, SLOT(updateState()));
+
+ ui->deferrableCombo->addItems({
+ "",
+ sqliteDeferrable(SqliteDeferrable::DEFERRABLE),
+ sqliteDeferrable(SqliteDeferrable::NOT_DEFERRABLE)
+ });
+ ui->initiallyCombo->addItems({
+ "",
+ sqliteInitially(SqliteInitially::DEFERRED),
+ sqliteInitially(SqliteInitially::IMMEDIATE),
+ });
+
+ QStringList reactions = {
+ SqliteForeignKey::Condition::toString(SqliteForeignKey::Condition::NO_ACTION),
+ SqliteForeignKey::Condition::toString(SqliteForeignKey::Condition::SET_NULL),
+ SqliteForeignKey::Condition::toString(SqliteForeignKey::Condition::SET_DEFAULT),
+ SqliteForeignKey::Condition::toString(SqliteForeignKey::Condition::CASCADE),
+ SqliteForeignKey::Condition::toString(SqliteForeignKey::Condition::RESTRICT)
+ };
+ ui->onUpdateCombo->addItems(reactions);
+ ui->onDeleteCombo->addItems(reactions);
+ ui->matchCombo->addItems({"SIMPLE", "FULL", "PARTIAL"});
+
+ connect(ui->namedCheckBox, SIGNAL(toggled(bool)), this, SLOT(updateState()));
+ updateState();
+}
+
+void ColumnForeignKeyPanel::updateState()
+{
+ bool tableSelected = (ui->fkTableCombo->currentIndex() > -1);
+ ui->fkColumnCombo->setEnabled(tableSelected);
+ ui->deferrableCombo->setEnabled(tableSelected);
+ ui->initiallyCombo->setEnabled(tableSelected);
+ ui->namedCheckBox->setEnabled(tableSelected);
+ ui->nameEdit->setEnabled(tableSelected && ui->namedCheckBox->isChecked());
+ ui->onDeleteCheckBox->setEnabled(tableSelected);
+ ui->onUpdateCheckBox->setEnabled(tableSelected);
+ ui->matchCheckBox->setEnabled(tableSelected);
+ ui->onDeleteCombo->setEnabled(tableSelected && ui->onDeleteCheckBox->isChecked());
+ ui->onUpdateCombo->setEnabled(tableSelected && ui->onUpdateCheckBox->isChecked());
+ ui->matchCombo->setEnabled(tableSelected && ui->matchCheckBox->isChecked());
+}
+
+void ColumnForeignKeyPanel::updateFkColumns()
+{
+ QStringList columns;
+ if (ui->fkTableCombo->currentIndex() == -1)
+ {
+ fkColumnsModel.setStringList(columns);
+ updateState();
+ return;
+ }
+
+ SchemaResolver resolver(db);
+ columns = resolver.getTableColumns(ui->fkTableCombo->currentText()); // TODO named db attach not supported
+ fkColumnsModel.setStringList(columns);
+}
+
+void ColumnForeignKeyPanel::readConstraint()
+{
+ if (constraint.isNull())
+ return;
+
+ SqliteCreateTable::Column* column = dynamic_cast<SqliteCreateTable::Column*>(constraint->parent());
+ SqliteCreateTable::Column::Constraint* constr = dynamic_cast<SqliteCreateTable::Column::Constraint*>(constraint.data());
+ if (!constr->foreignKey)
+ return;
+
+ // Table
+ if (!constr->foreignKey->foreignTable.isNull())
+ ui->fkTableCombo->setCurrentText(constr->foreignKey->foreignTable);
+
+ // Conditions
+ foreach (SqliteForeignKey::Condition* condition, constr->foreignKey->conditions)
+ readCondition(condition);
+
+ // Initially, Deferrable
+ ui->deferrableCombo->setCurrentText(sqliteDeferrable(constr->foreignKey->deferrable));
+ ui->initiallyCombo->setCurrentText(sqliteInitially(constr->foreignKey->initially));
+
+ // Name
+ if (!constr->name.isNull())
+ {
+ ui->namedCheckBox->setChecked(true);
+ ui->nameEdit->setText(constr->name);
+ }
+
+ // Column
+ if (constr->foreignKey->indexedColumns.size() > 1)
+ {
+ qWarning() << "More than one referenced column in the column foreign key:" << constr->detokenize();
+ return;
+ }
+
+ QString fkColumn = column->name;
+ if (constr->foreignKey->indexedColumns.size() == 1)
+ fkColumn = constr->foreignKey->indexedColumns.first()->name;
+
+ ui->fkColumnCombo->setCurrentText(fkColumn);
+}
+
+void ColumnForeignKeyPanel::readCondition(SqliteForeignKey::Condition* condition)
+{
+ switch (condition->action)
+ {
+ case SqliteForeignKey::Condition::UPDATE:
+ ui->onUpdateCheckBox->setChecked(true);
+ ui->onUpdateCombo->setCurrentText(SqliteForeignKey::Condition::toString(condition->reaction));
+ break;
+ case SqliteForeignKey::Condition::INSERT:
+ // INSERT is not officially supported.
+ break;
+ case SqliteForeignKey::Condition::DELETE:
+ ui->onDeleteCheckBox->setChecked(true);
+ ui->onDeleteCombo->setCurrentText(SqliteForeignKey::Condition::toString(condition->reaction));
+ break;
+ case SqliteForeignKey::Condition::MATCH:
+ ui->matchCheckBox->setChecked(true);
+ ui->matchCombo->setCurrentText(SqliteForeignKey::Condition::toString(condition->reaction));
+ break;
+ }
+}
+
+void ColumnForeignKeyPanel::storeConfiguration()
+{
+ if (constraint.isNull())
+ return;
+
+ // Type
+ SqliteCreateTable::Column::Constraint* constr = dynamic_cast<SqliteCreateTable::Column::Constraint*>(constraint.data());
+ constr->type = SqliteCreateTable::Column::Constraint::FOREIGN_KEY;
+
+ // Cleanup & initial setup
+ if (constr->foreignKey)
+ delete constr->foreignKey;
+
+ constr->foreignKey = new SqliteForeignKey();
+ constr->foreignKey->setParent(constr);
+
+ // Foreign table
+ constr->foreignKey->foreignTable = ui->fkTableCombo->currentText();
+
+ // Column
+ SqliteIndexedColumn* idxCol = new SqliteIndexedColumn(ui->fkColumnCombo->currentText());
+ idxCol->setParent(constr->foreignKey);
+ constr->foreignKey->indexedColumns << idxCol;
+
+ // Actions/reactions
+ if (ui->onDeleteCheckBox->isChecked())
+ storeCondition(SqliteForeignKey::Condition::DELETE, ui->onDeleteCombo->currentText());
+
+ if (ui->onUpdateCheckBox->isChecked())
+ storeCondition(SqliteForeignKey::Condition::UPDATE, ui->onDeleteCombo->currentText());
+
+ if (ui->matchCheckBox->isChecked())
+ storeMatchCondition(ui->matchCombo->currentText());
+
+ // Deferred/initially
+ constr->foreignKey->deferrable = sqliteDeferrable(ui->deferrableCombo->currentText());
+ constr->foreignKey->initially = sqliteInitially(ui->initiallyCombo->currentText());
+
+ // Name
+ constr->name = QString::null;
+ if (ui->namedCheckBox->isChecked())
+ constr->name = ui->nameEdit->text();
+}
+
+void ColumnForeignKeyPanel::storeCondition(SqliteForeignKey::Condition::Action action, const QString& reaction)
+{
+ SqliteCreateTable::Column::Constraint* constr = dynamic_cast<SqliteCreateTable::Column::Constraint*>(constraint.data());
+
+ SqliteForeignKey::Condition* condition = new SqliteForeignKey::Condition(
+ action,
+ SqliteForeignKey::Condition::toEnum(reaction)
+ );
+ condition->setParent(constr->foreignKey);
+ constr->foreignKey->conditions << condition;
+}
+
+void ColumnForeignKeyPanel::storeMatchCondition(const QString& reaction)
+{
+ SqliteCreateTable::Column::Constraint* constr = dynamic_cast<SqliteCreateTable::Column::Constraint*>(constraint.data());
+
+ SqliteForeignKey::Condition* condition = new SqliteForeignKey::Condition(reaction);
+ condition->setParent(constr->foreignKey);
+ constr->foreignKey->conditions << condition;
+}
+
+void ColumnForeignKeyPanel::readTables()
+{
+ SchemaResolver resolver(db);
+ resolver.setIgnoreSystemObjects(true);
+ QStringList tables = resolver.getTables(); // TODO named db attach not supported
+
+ tables.sort(Qt::CaseInsensitive);
+
+ ui->fkTableCombo->addItems(tables);
+ ui->fkTableCombo->setCurrentIndex(-1);
+}