From 5c7238d3d096caa81dc4aa2d220006068563174e Mon Sep 17 00:00:00 2001 From: mgrojo Date: Mon, 18 Jun 2018 17:49:12 +0200 Subject: [PATCH 1/6] Preference for quoting identifier mechanism A new option is added to the SQL tab in Preferences for choosing which quoting characters must be used by the application when it inserts an identifier in SQL code. The three options supported by SQLite are available. Default quoting characters have been changed from `Grave accents` to "Double quotes" (SQL standard). This options also affect the highlighting of double quoted strings: when the SQL standard is selected, double quoted expressions are highlighted as identifiers, otherwise as literal strings. --- src/MainWindow.cpp | 2 + src/PreferencesDialog.cpp | 2 + src/PreferencesDialog.ui | 211 ++++++++++++++++++++++---------------- src/Settings.cpp | 4 + src/sqlitetypes.cpp | 19 +++- src/sqlitetypes.h | 9 ++ src/sqltextedit.cpp | 13 ++- 7 files changed, 170 insertions(+), 90 deletions(-) diff --git a/src/MainWindow.cpp b/src/MainWindow.cpp index 01f3a3f8..9037ad2e 100644 --- a/src/MainWindow.cpp +++ b/src/MainWindow.cpp @@ -1990,6 +1990,8 @@ void MainWindow::reloadSettings() // Reload remote dock settings remoteDock->reloadSettings(); + + sqlb::setIdentifierQuoting(static_cast(Settings::getValue("editor", "identifier_quotes").toInt())); } void MainWindow::checkNewVersion(const QString& versionstring, const QString& url) diff --git a/src/PreferencesDialog.cpp b/src/PreferencesDialog.cpp index c9299364..7a7dc1ba 100644 --- a/src/PreferencesDialog.cpp +++ b/src/PreferencesDialog.cpp @@ -168,6 +168,7 @@ void PreferencesDialog::loadSettings() ui->spinTabSize->setValue(Settings::getValue("editor", "tabsize").toInt()); ui->spinLogFontSize->setValue(Settings::getValue("log", "fontsize").toInt()); ui->wrapComboBox->setCurrentIndex(Settings::getValue("editor", "wrap_lines").toInt()); + ui->quoteComboBox->setCurrentIndex(Settings::getValue("editor", "identifier_quotes").toInt()); ui->checkAutoCompletion->setChecked(Settings::getValue("editor", "auto_completion").toBool()); ui->checkCompleteUpper->setEnabled(Settings::getValue("editor", "auto_completion").toBool()); ui->checkCompleteUpper->setChecked(Settings::getValue("editor", "upper_keywords").toBool()); @@ -223,6 +224,7 @@ void PreferencesDialog::saveSettings() Settings::setValue("editor", "tabsize", ui->spinTabSize->value()); Settings::setValue("log", "fontsize", ui->spinLogFontSize->value()); Settings::setValue("editor", "wrap_lines", ui->wrapComboBox->currentIndex()); + Settings::setValue("editor", "identifier_quotes", ui->quoteComboBox->currentIndex()); Settings::setValue("editor", "auto_completion", ui->checkAutoCompletion->isChecked()); Settings::setValue("editor", "upper_keywords", ui->checkCompleteUpper->isChecked()); Settings::setValue("editor", "error_indicators", ui->checkErrorIndicators->isChecked()); diff --git a/src/PreferencesDialog.ui b/src/PreferencesDialog.ui index 20ab6828..8323ec03 100644 --- a/src/PreferencesDialog.ui +++ b/src/PreferencesDialog.ui @@ -920,6 +920,19 @@ + + + + SQL editor &font + + + comboEditorFont + + + + + + @@ -977,93 +990,13 @@ - - + + - SQL editor &font + Wrap lines - comboEditorFont - - - - - - - - - - Code co&mpletion - - - checkAutoCompletion - - - - - - - enabled - - - - - - - Keywords in &UPPER CASE - - - checkCompleteUpper - - - - - - - When set, the SQL keywords are completed in UPPER CASE letters. - - - enabled - - - - - - - Error indicators - - - checkErrorIndicators - - - - - - - When set, the SQL code lines that caused errors during the last execution are highlighted and the results frame indicates the error in the background - - - enabled - - - - - - - Hori&zontal tiling - - - checkHorizontalTiling - - - - - - - If enabled the SQL code editor and the result table view are shown side by side instead of one over the other. - - - enabled + wrapComboBox @@ -1091,13 +1024,115 @@ - - + + + + Choose the quoting mechanism used by the application for identifiers in SQL code. + + + + + + + "Double quotes" + + + + + `Grave accents` + + + + + [Square brackets] + + + + + + - Wrap lines + Code co&mpletion - wrapComboBox + checkAutoCompletion + + + + + + + enabled + + + + + + + Keywords in &UPPER CASE + + + checkCompleteUpper + + + + + + + When set, the SQL keywords are completed in UPPER CASE letters. + + + enabled + + + + + + + Error indicators + + + checkErrorIndicators + + + + + + + When set, the SQL code lines that caused errors during the last execution are highlighted and the results frame indicates the error in the background + + + enabled + + + + + + + Hori&zontal tiling + + + checkHorizontalTiling + + + + + + + If enabled the SQL code editor and the result table view are shown side by side instead of one over the other. + + + enabled + + + + + + + Quotes for identifiers + + + quoteComboBox diff --git a/src/Settings.cpp b/src/Settings.cpp index 3e581b5d..64a0de6a 100644 --- a/src/Settings.cpp +++ b/src/Settings.cpp @@ -294,6 +294,10 @@ QVariant Settings::getDefaultValue(const QString& group, const QString& name) if(group == "editor" && name == "wrap_lines") return 0; // QsciScintilla::WrapNone + // editor/identifier_quotes + if(group == "editor" && name == "identifier_quotes") + return 0; // sqlb::DoubleQuotes + // editor/auto_completion? if(group == "editor" && name == "auto_completion") return true; diff --git a/src/sqlitetypes.cpp b/src/sqlitetypes.cpp index 0e398bc0..2271c6be 100644 --- a/src/sqlitetypes.cpp +++ b/src/sqlitetypes.cpp @@ -11,9 +11,26 @@ namespace sqlb { QStringList Field::Datatypes = QStringList() << "INTEGER" << "TEXT" << "BLOB" << "REAL" << "NUMERIC"; +escapeQuoting customQuoting = DoubleQuotes; + +void setIdentifierQuoting(escapeQuoting toQuoting) +{ + customQuoting = toQuoting; +} + QString escapeIdentifier(QString id) { - return '`' + id.replace('`', "``") + '`'; + switch(customQuoting) { + case DoubleQuotes: + return '"' + id.replace('"', "\"\"") + '"'; + case GraveAccents: + return '`' + id.replace('`', "``") + '`'; + case SquareBrackets: + // There aren't any escaping possibilities for square brackets inside the identifier, + // so we rely on the user to not enter these characters when this kind of quoting is + // selected. + return '[' + id + ']'; + } } QStringList fieldVectorToFieldNames(const FieldVector& vector) diff --git a/src/sqlitetypes.h b/src/sqlitetypes.h index b1e72b7c..4b40f3a8 100644 --- a/src/sqlitetypes.h +++ b/src/sqlitetypes.h @@ -38,6 +38,15 @@ uint qHash(const QVector& key, uint seed = 0) } #endif +enum escapeQuoting { + DoubleQuotes, + GraveAccents, + SquareBrackets +}; + +// Set quoting style for escapeIdentifier +void setIdentifierQuoting(escapeQuoting toQuoting); + QString escapeIdentifier(QString id); class ObjectIdentifier diff --git a/src/sqltextedit.cpp b/src/sqltextedit.cpp index a8302d2a..6a44c32a 100644 --- a/src/sqltextedit.cpp +++ b/src/sqltextedit.cpp @@ -1,3 +1,4 @@ +#include "sqlitetypes.h" #include "sqltextedit.h" #include "Settings.h" #include "SqlUiLexer.h" @@ -49,8 +50,18 @@ void SqlTextEdit::reloadSettings() setupSyntaxHighlightingFormat(sqlLexer, "keyword", QsciLexerSQL::Keyword); setupSyntaxHighlightingFormat(sqlLexer, "table", QsciLexerSQL::KeywordSet6); setupSyntaxHighlightingFormat(sqlLexer, "function", QsciLexerSQL::KeywordSet7); - setupSyntaxHighlightingFormat(sqlLexer, "string", QsciLexerSQL::DoubleQuotedString); setupSyntaxHighlightingFormat(sqlLexer, "string", QsciLexerSQL::SingleQuotedString); + + // Highlight double quote strings as identifier or as literal string depending on user preference + switch(static_cast(Settings::getValue("editor", "identifier_quotes").toInt())) { + case sqlb::DoubleQuotes: + setupSyntaxHighlightingFormat(sqlLexer, "identifier", QsciLexerSQL::DoubleQuotedString); + break; + case sqlb::GraveAccents: + case sqlb::SquareBrackets: + setupSyntaxHighlightingFormat(sqlLexer, "string", QsciLexerSQL::DoubleQuotedString); + break; + } setupSyntaxHighlightingFormat(sqlLexer, "identifier", QsciLexerSQL::Identifier); setupSyntaxHighlightingFormat(sqlLexer, "identifier", QsciLexerSQL::QuotedIdentifier); } From 265b077a5f8a60a28eae9d4ab43302f032191319 Mon Sep 17 00:00:00 2001 From: mgrojo Date: Mon, 18 Jun 2018 19:03:35 +0200 Subject: [PATCH 2/6] Revert to grave accents as default quoting The former quoting is expected by the tests, so the former behaviour is restored as default, until a decision about the best default value is made. --- src/Settings.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Settings.cpp b/src/Settings.cpp index 64a0de6a..83f17143 100644 --- a/src/Settings.cpp +++ b/src/Settings.cpp @@ -296,7 +296,7 @@ QVariant Settings::getDefaultValue(const QString& group, const QString& name) // editor/identifier_quotes if(group == "editor" && name == "identifier_quotes") - return 0; // sqlb::DoubleQuotes + return 1; // sqlb::GraveAccents // editor/auto_completion? if(group == "editor" && name == "auto_completion") From da8057c96459baea080023914e6e1107cedd169a Mon Sep 17 00:00:00 2001 From: mgrojo Date: Mon, 18 Jun 2018 19:37:26 +0200 Subject: [PATCH 3/6] Revert to grave accents as default quoting The former quoting is expected by the tests, so the former behaviour is restored as default, until a decision about the best default value is made. --- src/sqlitetypes.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sqlitetypes.cpp b/src/sqlitetypes.cpp index 2271c6be..4fa1d97e 100644 --- a/src/sqlitetypes.cpp +++ b/src/sqlitetypes.cpp @@ -11,7 +11,7 @@ namespace sqlb { QStringList Field::Datatypes = QStringList() << "INTEGER" << "TEXT" << "BLOB" << "REAL" << "NUMERIC"; -escapeQuoting customQuoting = DoubleQuotes; +escapeQuoting customQuoting = GraveAccents; void setIdentifierQuoting(escapeQuoting toQuoting) { From 9e0e3309df8ead33ec6a0b0bd16e73bfcc5ee877 Mon Sep 17 00:00:00 2001 From: Martin Kleusberg Date: Thu, 21 Jun 2018 11:11:47 +0200 Subject: [PATCH 4/6] Move font size settings into the same row in settings dialog --- src/PreferencesDialog.ui | 90 ++++++++++++++++++++++++---------------- 1 file changed, 55 insertions(+), 35 deletions(-) diff --git a/src/PreferencesDialog.ui b/src/PreferencesDialog.ui index 8323ec03..0d180cff 100644 --- a/src/PreferencesDialog.ui +++ b/src/PreferencesDialog.ui @@ -944,30 +944,50 @@ - - - 1 - - + + + + + 1 + + + + + + + Qt::Horizontal + + + QSizePolicy::Minimum + + + + 40 + 20 + + + + + + + + SQL &results font size + + + spinLogFontSize + + + + + + + 1 + + + + - - - SQL &results font size - - - spinLogFontSize - - - - - - - 1 - - - - Tab size @@ -977,7 +997,7 @@ - + 1 @@ -990,7 +1010,7 @@ - + Wrap lines @@ -1000,7 +1020,7 @@ - + @@ -1024,7 +1044,7 @@ - + Choose the quoting mechanism used by the application for identifiers in SQL code. @@ -1049,7 +1069,7 @@ - + Code co&mpletion @@ -1059,14 +1079,14 @@ - + enabled - + Keywords in &UPPER CASE @@ -1076,7 +1096,7 @@ - + When set, the SQL keywords are completed in UPPER CASE letters. @@ -1086,7 +1106,7 @@ - + Error indicators @@ -1096,7 +1116,7 @@ - + When set, the SQL code lines that caused errors during the last execution are highlighted and the results frame indicates the error in the background @@ -1106,7 +1126,7 @@ - + Hori&zontal tiling @@ -1116,7 +1136,7 @@ - + If enabled the SQL code editor and the result table view are shown side by side instead of one over the other. @@ -1126,7 +1146,7 @@ - + Quotes for identifiers From 2803e163e036b818e298b4b5dd175653a0df1342 Mon Sep 17 00:00:00 2001 From: mgrojo Date: Sat, 23 Jun 2018 17:57:18 +0200 Subject: [PATCH 5/6] New tests for the new standard quoting and for the other quoting styles Modified some tests for taking into account the new standard quoting and added some more for testing the quoting configuration and for correct parsing of different quoting styles. Default branch in escapeIdentifier() for trying to avoid warning. --- src/Settings.cpp | 2 +- src/sqlitetypes.cpp | 10 ++- src/sqltextedit.cpp | 3 + src/tests/testsqlobjects.cpp | 128 ++++++++++++++++++++++++++++------- src/tests/testsqlobjects.h | 5 ++ 5 files changed, 121 insertions(+), 27 deletions(-) diff --git a/src/Settings.cpp b/src/Settings.cpp index 83f17143..64a0de6a 100644 --- a/src/Settings.cpp +++ b/src/Settings.cpp @@ -296,7 +296,7 @@ QVariant Settings::getDefaultValue(const QString& group, const QString& name) // editor/identifier_quotes if(group == "editor" && name == "identifier_quotes") - return 1; // sqlb::GraveAccents + return 0; // sqlb::DoubleQuotes // editor/auto_completion? if(group == "editor" && name == "auto_completion") diff --git a/src/sqlitetypes.cpp b/src/sqlitetypes.cpp index 4fa1d97e..0f2836f3 100644 --- a/src/sqlitetypes.cpp +++ b/src/sqlitetypes.cpp @@ -11,7 +11,7 @@ namespace sqlb { QStringList Field::Datatypes = QStringList() << "INTEGER" << "TEXT" << "BLOB" << "REAL" << "NUMERIC"; -escapeQuoting customQuoting = GraveAccents; +static escapeQuoting customQuoting = DoubleQuotes; void setIdentifierQuoting(escapeQuoting toQuoting) { @@ -21,8 +21,6 @@ void setIdentifierQuoting(escapeQuoting toQuoting) QString escapeIdentifier(QString id) { switch(customQuoting) { - case DoubleQuotes: - return '"' + id.replace('"', "\"\"") + '"'; case GraveAccents: return '`' + id.replace('`', "``") + '`'; case SquareBrackets: @@ -30,6 +28,12 @@ QString escapeIdentifier(QString id) // so we rely on the user to not enter these characters when this kind of quoting is // selected. return '[' + id + ']'; + case DoubleQuotes: + default: + // This may produce a 'control reaches end of non-void function' warning if the + // default branch is removed, even though we have covered all possibilities in the + // switch statement. + return '"' + id.replace('"', "\"\"") + '"'; } } diff --git a/src/sqltextedit.cpp b/src/sqltextedit.cpp index 6a44c32a..6805820f 100644 --- a/src/sqltextedit.cpp +++ b/src/sqltextedit.cpp @@ -56,8 +56,11 @@ void SqlTextEdit::reloadSettings() switch(static_cast(Settings::getValue("editor", "identifier_quotes").toInt())) { case sqlb::DoubleQuotes: setupSyntaxHighlightingFormat(sqlLexer, "identifier", QsciLexerSQL::DoubleQuotedString); + sqlLexer->setQuotedIdentifiers(false); break; case sqlb::GraveAccents: + sqlLexer->setQuotedIdentifiers(true); + // Fall through, treat quoted string as literal string case sqlb::SquareBrackets: setupSyntaxHighlightingFormat(sqlLexer, "string", QsciLexerSQL::DoubleQuotedString); break; diff --git a/src/tests/testsqlobjects.cpp b/src/tests/testsqlobjects.cpp index 507499ca..5697862b 100644 --- a/src/tests/testsqlobjects.cpp +++ b/src/tests/testsqlobjects.cpp @@ -17,12 +17,55 @@ void TestTable::sqlOutput() tt.addField(fkm); tt.addConstraint({f, fkm}, ConstraintPtr(new PrimaryKeyConstraint())); + QCOMPARE(tt.sql(), QString("CREATE TABLE \"testtable\" (\n" + "\t\"id\"\tinteger,\n" + "\t\"car\"\ttext,\n" + "\t\"km\"\tinteger CHECK(km > 1000),\n" + "\tPRIMARY KEY(\"id\",\"km\")\n" + ");")); +} + +void TestTable::sqlGraveAccentOutput() +{ + Table tt("testtable"); + FieldPtr f = FieldPtr(new Field("id", "integer")); + FieldPtr fkm = FieldPtr(new Field("km", "integer", false, "", "km > 1000")); + tt.addField(f); + tt.addField(FieldPtr(new Field("car", "text"))); + tt.addField(fkm); + tt.addConstraint({f, fkm}, ConstraintPtr(new PrimaryKeyConstraint())); + sqlb::setIdentifierQuoting(sqlb::GraveAccents); + QCOMPARE(tt.sql(), QString("CREATE TABLE `testtable` (\n" "\t`id`\tinteger,\n" "\t`car`\ttext,\n" "\t`km`\tinteger CHECK(km > 1000),\n" "\tPRIMARY KEY(`id`,`km`)\n" ");")); + + sqlb::setIdentifierQuoting(sqlb::DoubleQuotes); +} + + +void TestTable::sqlSquareBracketsOutput() +{ + Table tt("testtable"); + FieldPtr f = FieldPtr(new Field("id", "integer")); + FieldPtr fkm = FieldPtr(new Field("km", "integer", false, "", "km > 1000")); + tt.addField(f); + tt.addField(FieldPtr(new Field("car", "text"))); + tt.addField(fkm); + tt.addConstraint({f, fkm}, ConstraintPtr(new PrimaryKeyConstraint())); + sqlb::setIdentifierQuoting(sqlb::SquareBrackets); + + QCOMPARE(tt.sql(), QString("CREATE TABLE [testtable] (\n" + "\t[id]\tinteger,\n" + "\t[car]\ttext,\n" + "\t[km]\tinteger CHECK(km > 1000),\n" + "\tPRIMARY KEY([id],[km])\n" + ");")); + + sqlb::setIdentifierQuoting(sqlb::DoubleQuotes); } void TestTable::autoincrement() @@ -36,10 +79,10 @@ void TestTable::autoincrement() tt.addField(fkm); tt.addConstraint({f}, ConstraintPtr(new PrimaryKeyConstraint())); - QCOMPARE(tt.sql(), QString("CREATE TABLE `testtable` (\n" - "\t`id`\tinteger PRIMARY KEY AUTOINCREMENT,\n" - "\t`car`\ttext,\n" - "\t`km`\tinteger\n" + QCOMPARE(tt.sql(), QString("CREATE TABLE \"testtable\" (\n" + "\t\"id\"\tinteger PRIMARY KEY AUTOINCREMENT,\n" + "\t\"car\"\ttext,\n" + "\t\"km\"\tinteger\n" ");")); } @@ -54,10 +97,10 @@ void TestTable::notnull() tt.addField(fkm); tt.addConstraint({f}, ConstraintPtr(new PrimaryKeyConstraint())); - QCOMPARE(tt.sql(), QString("CREATE TABLE `testtable` (\n" - "\t`id`\tinteger PRIMARY KEY AUTOINCREMENT,\n" - "\t`car`\ttext NOT NULL,\n" - "\t`km`\tinteger\n" + QCOMPARE(tt.sql(), QString("CREATE TABLE \"testtable\" (\n" + "\t\"id\"\tinteger PRIMARY KEY AUTOINCREMENT,\n" + "\t\"car\"\ttext NOT NULL,\n" + "\t\"km\"\tinteger\n" ");")); } @@ -71,9 +114,9 @@ void TestTable::withoutRowid() tt.setRowidColumn("a"); tt.addConstraint({f}, ConstraintPtr(new PrimaryKeyConstraint())); - QCOMPARE(tt.sql(), QString("CREATE TABLE `testtable` (\n" - "\t`a`\tinteger PRIMARY KEY AUTOINCREMENT,\n" - "\t`b`\tinteger\n" + QCOMPARE(tt.sql(), QString("CREATE TABLE \"testtable\" (\n" + "\t\"a\"\tinteger PRIMARY KEY AUTOINCREMENT,\n" + "\t\"b\"\tinteger\n" ") WITHOUT ROWID;")); } @@ -84,9 +127,9 @@ void TestTable::foreignKeys() tt.addField(f); tt.addConstraint({f}, sqlb::ConstraintPtr(new sqlb::ForeignKeyClause("b", QStringList("c")))); - QCOMPARE(tt.sql(), QString("CREATE TABLE `testtable` (\n" - "\t`a`\tinteger,\n" - "\tFOREIGN KEY(`a`) REFERENCES `b`(`c`)\n" + QCOMPARE(tt.sql(), QString("CREATE TABLE \"testtable\" (\n" + "\t\"a\"\tinteger,\n" + "\tFOREIGN KEY(\"a\") REFERENCES \"b\"(\"c\")\n" ");")); } @@ -102,11 +145,11 @@ void TestTable::uniqueConstraint() tt.addField(f3); tt.addConstraint({f2, f3}, sqlb::ConstraintPtr(new sqlb::UniqueConstraint())); - QCOMPARE(tt.sql(), QString("CREATE TABLE `testtable` (\n" - "\t`a`\tinteger UNIQUE,\n" - "\t`b`\tinteger,\n" - "\t`c`\tinteger,\n" - "\tUNIQUE(`b`,`c`)\n" + QCOMPARE(tt.sql(), QString("CREATE TABLE \"testtable\" (\n" + "\t\"a\"\tinteger UNIQUE,\n" + "\t\"b\"\tinteger,\n" + "\t\"c\"\tinteger,\n" + "\tUNIQUE(\"b\",\"c\")\n" ");")); } @@ -177,7 +220,7 @@ void TestTable::parseSQLMultiPk() "\tid1 integer,\n" "\tid2 integer,\n" "\tnonpkfield blob,\n" - "PRIMARY KEY(`id1`,`id2`)\n" + "PRIMARY KEY(\"id1\",\"id2\")\n" ");"; Table tab = *(Table::parseSQL(sSQL).dynamicCast()); @@ -215,6 +258,18 @@ void TestTable::parseSQLSingleQuotes() QVERIFY(tab.fields().at(1)->name() == "test"); } +void TestTable::parseSQLSquareBrackets() +{ + QString sSQL = "CREATE TABLE [test]([id],[test]);"; + + Table tab = *(Table::parseSQL(sSQL).dynamicCast()); + + QVERIFY(tab.name() == "test"); + QVERIFY(tab.fields().at(0)->name() == "id"); + QVERIFY(tab.fields().at(1)->name() == "test"); +} + + void TestTable::parseSQLKeywordInIdentifier() { QString sSQL = "CREATE TABLE deffered(key integer primary key, if text);"; @@ -226,6 +281,20 @@ void TestTable::parseSQLKeywordInIdentifier() QVERIFY(tab.fields().at(1)->name() == "if"); } + +void TestTable::parseSQLSomeKeywordsInIdentifier() +{ + QString sSQL = "CREATE TABLE \"Average Number of Volunteers by Area of Work\" (" + "`Area of Work` TEXT," + "`Average Number of Volunteers` INTEGER);"; + + Table tab = *(Table::parseSQL(sSQL).dynamicCast()); + + QVERIFY(tab.name() == "Average Number of Volunteers by Area of Work"); + QVERIFY(tab.fields().at(0)->name() == "Area of Work"); + QVERIFY(tab.fields().at(1)->name() == "Average Number of Volunteers"); +} + void TestTable::parseSQLWithoutRowid() { QString sSQL = "CREATE TABLE test(a integer primary key, b integer) WITHOUT ROWID;"; @@ -249,6 +318,19 @@ void TestTable::parseNonASCIIChars() QVERIFY(tab.fields().at(0)->name() == "Fieldöäüß"); } +void TestTable::parseNonASCIICharsEs() +{ + QString sSQL = "CREATE TABLE \"Cigüeñas de Alcalá\" (" + "\"Field áéíóúÁÉÍÓÚñÑçÇ\" INTEGER," + "PRIMARY KEY(\"Field áéíóúÁÉÍÓÚñÑçÇ\")" + ");"; + + Table tab = *(Table::parseSQL(sSQL).dynamicCast()); + + QVERIFY(tab.name() == "Cigüeñas de Alcalá"); + QVERIFY(tab.fields().at(0)->name() == "Field áéíóúÁÉÍÓÚñÑçÇ"); +} + void TestTable::parseSQLEscapedQuotes() { QString sSql = "CREATE TABLE double_quotes(a text default 'a''a');"; @@ -272,19 +354,19 @@ void TestTable::parseSQLForeignKeys() QCOMPARE(tab.constraint({tab.fields().at(0)}, sqlb::Constraint::ForeignKeyConstraintType).dynamicCast()->table(), QString("x")); QCOMPARE(tab.fields().at(1)->name(), QString("b")); QCOMPARE(tab.fields().at(1)->type(), QString("int")); - QCOMPARE(tab.constraint({tab.fields().at(1)}, sqlb::Constraint::ForeignKeyConstraintType).dynamicCast()->toString(), QString("`w`(`y`,`z`) on delete set null")); + QCOMPARE(tab.constraint({tab.fields().at(1)}, sqlb::Constraint::ForeignKeyConstraintType).dynamicCast()->toString(), QString("\"w\"(\"y\",\"z\") on delete set null")); } void TestTable::parseSQLCheckConstraint() { - QString sql = "CREATE TABLE a (`b` text CHECK(`b`='A' or `b`='B'));"; + QString sql = "CREATE TABLE a (\"b\" text CHECK(\"b\"='A' or \"b\"='B'));"; Table tab = *(Table::parseSQL(sql).dynamicCast()); QCOMPARE(tab.name(), QString("a")); QCOMPARE(tab.fields().at(0)->name(), QString("b")); QCOMPARE(tab.fields().at(0)->type(), QString("text")); - QCOMPARE(tab.fields().at(0)->check(), QString("`b` = 'A' or `b` = 'B'")); + QCOMPARE(tab.fields().at(0)->check(), QString("\"b\" = 'A' or \"b\" = 'B'")); } void TestTable::parseDefaultValues() diff --git a/src/tests/testsqlobjects.h b/src/tests/testsqlobjects.h index b03b78c4..3d3b7bf5 100644 --- a/src/tests/testsqlobjects.h +++ b/src/tests/testsqlobjects.h @@ -8,6 +8,8 @@ class TestTable: public QObject Q_OBJECT private slots: void sqlOutput(); + void sqlGraveAccentOutput(); + void sqlSquareBracketsOutput(); void autoincrement(); void notnull(); void withoutRowid(); @@ -15,13 +17,16 @@ private slots: void uniqueConstraint(); void parseSQL(); + void parseSQLSquareBrackets(); void parseSQLdefaultexpr(); void parseSQLMultiPk(); void parseSQLForeignKey(); void parseSQLSingleQuotes(); void parseSQLKeywordInIdentifier(); + void parseSQLSomeKeywordsInIdentifier(); void parseSQLWithoutRowid(); void parseNonASCIIChars(); + void parseNonASCIICharsEs(); void parseSQLEscapedQuotes(); void parseSQLForeignKeys(); void parseSQLCheckConstraint(); From 58a6dba1005fd3457aeb35721bf83d79b3af7f86 Mon Sep 17 00:00:00 2001 From: mgrojo Date: Sat, 23 Jun 2018 19:04:27 +0200 Subject: [PATCH 6/6] Pref: "SQL editor font" and its size on the same row and other improvements "SQL editor font" and "SQL editor font size" are located at the same row for saving vertical space in the Preferences dialog. Accelerator keys for "Wrap lines" and "Quotes for identifiers" have been added. Some buddies have been fixed. --- src/PreferencesDialog.ui | 112 +++++++++++++++++++-------------------- 1 file changed, 54 insertions(+), 58 deletions(-) diff --git a/src/PreferencesDialog.ui b/src/PreferencesDialog.ui index 0d180cff..91986182 100644 --- a/src/PreferencesDialog.ui +++ b/src/PreferencesDialog.ui @@ -128,7 +128,7 @@ Toolbar style - languageComboBox + toolbarStyleComboBox @@ -187,6 +187,9 @@ Show remote options + + checkUseRemotes + @@ -221,6 +224,9 @@ DB file extensions + + buttonManageFileExtension + @@ -382,6 +388,9 @@ Default field type + + defaultFieldTypeComboBox + @@ -931,20 +940,23 @@ - - - - - - SQL &editor font size - - - spinEditorFontSize - - - - + + + + + + + SQL &editor font size + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + spinEditorFontSize + + + @@ -952,41 +964,25 @@ - - - - Qt::Horizontal - - - QSizePolicy::Minimum - - - - 40 - 20 - - - - - - - - SQL &results font size - - - spinLogFontSize - - - - - - - 1 - - - + + + + SQL &results font size + + + spinLogFontSize + + + + + + + 1 + + + @@ -1013,7 +1009,7 @@ - Wrap lines + &Wrap lines wrapComboBox @@ -1044,6 +1040,16 @@ + + + + &Quotes for identifiers + + + quoteComboBox + + + @@ -1146,16 +1152,6 @@ - - - - Quotes for identifiers - - - quoteComboBox - - -