1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 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;
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();
}
|