aboutsummaryrefslogtreecommitdiffstats
path: root/SQLiteStudio3/guiSQLiteStudio/dialogs/indexexprcolumndialog.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'SQLiteStudio3/guiSQLiteStudio/dialogs/indexexprcolumndialog.cpp')
-rw-r--r--SQLiteStudio3/guiSQLiteStudio/dialogs/indexexprcolumndialog.cpp151
1 files changed, 151 insertions, 0 deletions
diff --git a/SQLiteStudio3/guiSQLiteStudio/dialogs/indexexprcolumndialog.cpp b/SQLiteStudio3/guiSQLiteStudio/dialogs/indexexprcolumndialog.cpp
new file mode 100644
index 0000000..f041294
--- /dev/null
+++ b/SQLiteStudio3/guiSQLiteStudio/dialogs/indexexprcolumndialog.cpp
@@ -0,0 +1,151 @@
+#include "indexexprcolumndialog.h"
+#include "ui_indexexprcolumndialog.h"
+#include "parser/ast/sqliteexpr.h"
+#include "db/db.h"
+#include "uiutils.h"
+#include "parser/parser.h"
+#include "parser/ast/sqliteselect.h"
+#include <QPushButton>
+
+IndexExprColumnDialog::IndexExprColumnDialog(Db* db, QWidget* parent) :
+ QDialog(parent),
+ ui(new Ui::IndexExprColumnDialog)
+{
+ ui->setupUi(this);
+
+ this->db = db;
+ ui->sqlEditor->setDb(db);
+ ui->sqlEditor->setVirtualSqlExpression("CREATE INDEX idx ON tab (%1 COLLATE NOCASE ASC)");
+
+ connect(ui->sqlEditor, SIGNAL(textChanged()), this, SLOT(validate()));
+ connect(ui->sqlEditor, SIGNAL(errorsChecked(bool)), this, SLOT(validate()));
+}
+
+IndexExprColumnDialog::IndexExprColumnDialog(Db* db, SqliteExpr* col, QWidget *parent) :
+ IndexExprColumnDialog(db, parent)
+{
+ readColumn(col);
+}
+
+IndexExprColumnDialog::~IndexExprColumnDialog()
+{
+ delete ui;
+}
+
+void IndexExprColumnDialog::readColumn(SqliteExpr* col)
+{
+ ui->sqlEditor->setPlainText(col->tokens.detokenize());
+}
+
+void IndexExprColumnDialog::setOkEnabled(bool enabled)
+{
+ ui->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(enabled);
+}
+
+SqliteExpr* IndexExprColumnDialog::parseExpr()
+{
+ Parser parser(db->getDialect());
+ return parser.parseExpr(ui->sqlEditor->toPlainText());
+}
+
+bool IndexExprColumnDialog::checkRestrictions(QString& errorMsg)
+{
+ SqliteExprPtr expr = SqliteExprPtr(parseExpr());
+ if (!expr)
+ return false;
+
+ QString key = expr->tokens.filterWhiteSpaces(false).detokenize();
+ if (existingExprColumnKeys.contains(key))
+ {
+ errorMsg = tr("This expression is already indexed by the index.");
+ return false;
+ }
+
+ if (tableColumns.contains(key))
+ {
+ errorMsg = tr("Column should be indexed directly, not by expression. Either extend this expression to contain something more "
+ "than just column name, or abort and select this column in index dialog directly.");
+ return false;
+ }
+
+ QStringList usedColumns = expr->getContextColumns(false, true);
+ for (const QString& col : usedColumns)
+ {
+ if (!tableColumns.contains(col))
+ {
+ errorMsg = tr("Column '%1' does not belong to the table covered by this index. Indexed expressions can refer only to columns from the indexed table.").arg(col);
+ return false;
+ }
+ }
+
+ QList<SqliteSelect*> selects = expr->getAllTypedStatements<SqliteSelect>();
+ if (!selects.isEmpty())
+ {
+ errorMsg = tr("It's forbidden to use 'SELECT' statements in indexed expressions.");
+ return false;
+ }
+
+ return true;
+}
+
+void IndexExprColumnDialog::setExistingExprColumnKeys(const QStringList& value)
+{
+ existingExprColumnKeys = value;
+}
+
+void IndexExprColumnDialog::setTableColumns(const QStringList& value)
+{
+ tableColumns = value;
+}
+
+void IndexExprColumnDialog::validate()
+{
+ if (!ui->sqlEditor->isSyntaxChecked())
+ {
+ setValidState(ui->sqlEditor, false, tr("Enter an indexed expression."));
+ setOkEnabled(false);
+ return;
+ }
+
+ // First check if we already validated this text.
+ // This method is called twice, by both errorsChecked() and textChanged().
+ QString text = ui->sqlEditor->toPlainText();
+ if (!lastValidatedText.isNull() && lastValidatedText == text)
+ return;
+
+ lastValidatedText = text;
+
+ bool exprOk = !ui->sqlEditor->toPlainText().trimmed().isEmpty() && !ui->sqlEditor->haveErrors();
+ QString errorMsg = tr("Invalid expression.");
+ if (exprOk)
+ exprOk = checkRestrictions(errorMsg);
+
+ setValidState(ui->sqlEditor, exprOk, errorMsg);
+ setOkEnabled(exprOk);
+}
+
+SqliteExpr* IndexExprColumnDialog::getColumn() const
+{
+ return theColumn;
+}
+
+void IndexExprColumnDialog::accept()
+{
+ SqliteExpr* expr = parseExpr();
+ if (expr)
+ {
+ expr->rebuildTokens();
+ theColumn = expr;
+ }
+ else
+ qCritical() << "Accepted IndexExprColumnDialog with unparsable expr! This should not happen. IndexDialog will get null expr.";
+
+ QDialog::accept();
+}
+
+
+int IndexExprColumnDialog::exec()
+{
+ ui->sqlEditor->checkSyntaxNow();
+ return QDialog::exec();
+}