diff options
| author | 2014-12-06 17:33:25 -0500 | |
|---|---|---|
| committer | 2014-12-06 17:33:25 -0500 | |
| commit | 7167ce41b61d2ba2cdb526777a4233eb84a3b66a (patch) | |
| tree | a35c14143716e1f2c98f808c81f89426045a946f /Plugins/SqlEnterpriseFormatter | |
Imported Upstream version 2.99.6upstream/2.99.6
Diffstat (limited to 'Plugins/SqlEnterpriseFormatter')
79 files changed, 4787 insertions, 0 deletions
diff --git a/Plugins/SqlEnterpriseFormatter/SqlEnterpriseFormatter.pro b/Plugins/SqlEnterpriseFormatter/SqlEnterpriseFormatter.pro new file mode 100644 index 0000000..ae68b60 --- /dev/null +++ b/Plugins/SqlEnterpriseFormatter/SqlEnterpriseFormatter.pro @@ -0,0 +1,100 @@ +#------------------------------------------------- +# +# Project created by QtCreator 2014-09-11T10:57:25 +# +#------------------------------------------------- + +include($$PWD/../../SQLiteStudio3/plugins.pri) + +QT -= gui + +TARGET = SqlEnterpriseFormatter +TEMPLATE = lib + +DEFINES += SQLENTERPRISEFORMATTER_LIBRARY + +SOURCES += sqlenterpriseformatter.cpp \ + formatstatement.cpp \ + formatselect.cpp \ + formatexpr.cpp \ + formatlimit.cpp \ + formatwith.cpp \ + formatraise.cpp \ + formatcreatetable.cpp \ + formatforeignkey.cpp \ + formatcolumntype.cpp \ + formatindexedcolumn.cpp \ + formatinsert.cpp \ + formatempty.cpp \ + formataltertable.cpp \ + formatanalyze.cpp \ + formatattach.cpp \ + formatbegintrans.cpp \ + formatcommittrans.cpp \ + formatcopy.cpp \ + formatcreateindex.cpp \ + formatcreatetrigger.cpp \ + formatdelete.cpp \ + formatupdate.cpp \ + formatcreateview.cpp \ + formatcreatevirtualtable.cpp \ + formatdetach.cpp \ + formatdropindex.cpp \ + formatdroptable.cpp \ + formatdroptrigger.cpp \ + formatdropview.cpp \ + formatpragma.cpp \ + formatreindex.cpp \ + formatrelease.cpp \ + formatrollback.cpp \ + formatsavepoint.cpp \ + formatvacuum.cpp \ + formatorderby.cpp + +HEADERS += sqlenterpriseformatter.h\ + sqlenterpriseformatter_global.h \ + formatstatement.h \ + formatselect.h \ + formatexpr.h \ + formatlimit.h \ + formatwith.h \ + formatraise.h \ + formatcreatetable.h \ + formatforeignkey.h \ + formatcolumntype.h \ + formatindexedcolumn.h \ + formatinsert.h \ + formatempty.h \ + formataltertable.h \ + formatanalyze.h \ + formatattach.h \ + formatbegintrans.h \ + formatcommittrans.h \ + formatcopy.h \ + formatcreateindex.h \ + formatcreatetrigger.h \ + formatdelete.h \ + formatupdate.h \ + formatcreateview.h \ + formatcreatevirtualtable.h \ + formatdetach.h \ + formatdropindex.h \ + formatdroptable.h \ + formatdroptrigger.h \ + formatdropview.h \ + formatpragma.h \ + formatreindex.h \ + formatrelease.h \ + formatrollback.h \ + formatsavepoint.h \ + formatvacuum.h \ + formatorderby.h + +OTHER_FILES += \ + sqlenterpriseformatter.json + +FORMS += \ + sqlenterpriseformatter.ui + +RESOURCES += \ + sqlenterpriseformatter.qrc diff --git a/Plugins/SqlEnterpriseFormatter/formataltertable.cpp b/Plugins/SqlEnterpriseFormatter/formataltertable.cpp new file mode 100644 index 0000000..d562e1b --- /dev/null +++ b/Plugins/SqlEnterpriseFormatter/formataltertable.cpp @@ -0,0 +1,31 @@ +#include "formataltertable.h" +#include "parser/ast/sqlitealtertable.h" + +FormatAlterTable::FormatAlterTable(SqliteAlterTable* alterTable) : + alterTable(alterTable) +{ +} + +void FormatAlterTable::formatInternal() +{ + withKeyword("ALTER").withKeyword("TABLE"); + + if (!alterTable->database.isNull()) + withId(alterTable->database).withIdDot(); + + withId(alterTable->table); + + if (alterTable->newColumn) + { + withKeyword("ADD"); + if (alterTable->columnKw) + withKeyword("COLUMN"); + + withStatement(alterTable->newColumn); + } + else if (!alterTable->newName.isNull()) + { + withKeyword("RENAME").withKeyword("TO").withId(alterTable->newName); + } + withSemicolon(); +} diff --git a/Plugins/SqlEnterpriseFormatter/formataltertable.h b/Plugins/SqlEnterpriseFormatter/formataltertable.h new file mode 100644 index 0000000..a041c9c --- /dev/null +++ b/Plugins/SqlEnterpriseFormatter/formataltertable.h @@ -0,0 +1,20 @@ +#ifndef FORMATALTERTABLE_H +#define FORMATALTERTABLE_H + +#include "formatstatement.h" + +class SqliteAlterTable; + +class FormatAlterTable : public FormatStatement +{ + public: + FormatAlterTable(SqliteAlterTable* alterTable); + + protected: + void formatInternal(); + + private: + SqliteAlterTable* alterTable = nullptr; +}; + +#endif // FORMATALTERTABLE_H diff --git a/Plugins/SqlEnterpriseFormatter/formatanalyze.cpp b/Plugins/SqlEnterpriseFormatter/formatanalyze.cpp new file mode 100644 index 0000000..1b7a939 --- /dev/null +++ b/Plugins/SqlEnterpriseFormatter/formatanalyze.cpp @@ -0,0 +1,18 @@ +#include "formatanalyze.h" +#include "parser/ast/sqliteanalyze.h" + +FormatAnalyze::FormatAnalyze(SqliteAnalyze* analyze) : + analyze(analyze) +{ +} + +void FormatAnalyze::formatInternal() +{ + withKeyword("ANALYZE"); + + if (!analyze->database.isNull()) + withId(analyze->database).withIdDot(); + + withId(analyze->table).withSemicolon(); + +} diff --git a/Plugins/SqlEnterpriseFormatter/formatanalyze.h b/Plugins/SqlEnterpriseFormatter/formatanalyze.h new file mode 100644 index 0000000..f9e8aee --- /dev/null +++ b/Plugins/SqlEnterpriseFormatter/formatanalyze.h @@ -0,0 +1,20 @@ +#ifndef FORMATANALYZE_H +#define FORMATANALYZE_H + +#include "formatstatement.h" + +class SqliteAnalyze; + +class FormatAnalyze : public FormatStatement +{ + public: + FormatAnalyze(SqliteAnalyze* analyze); + + protected: + void formatInternal(); + + private: + SqliteAnalyze* analyze = nullptr; +}; + +#endif // FORMATANALYZE_H diff --git a/Plugins/SqlEnterpriseFormatter/formatattach.cpp b/Plugins/SqlEnterpriseFormatter/formatattach.cpp new file mode 100644 index 0000000..e969495 --- /dev/null +++ b/Plugins/SqlEnterpriseFormatter/formatattach.cpp @@ -0,0 +1,22 @@ +#include "formatattach.h" +#include "parser/ast/sqliteattach.h" +#include "parser/ast/sqliteexpr.h" + +FormatAttach::FormatAttach(SqliteAttach* att) : + att(att) +{ +} + +void FormatAttach::formatInternal() +{ + withKeyword("ATTACH"); + + if (att->databaseKw) + withKeyword("DATABASE"); + + withStatement(att->databaseUrl).withKeyword("AS").withStatement(att->name); + if (att->key) + withKeyword("KEY").withStatement(att->key); + + withSemicolon(); +} diff --git a/Plugins/SqlEnterpriseFormatter/formatattach.h b/Plugins/SqlEnterpriseFormatter/formatattach.h new file mode 100644 index 0000000..cfd06f2 --- /dev/null +++ b/Plugins/SqlEnterpriseFormatter/formatattach.h @@ -0,0 +1,20 @@ +#ifndef FORMATATTACH_H +#define FORMATATTACH_H + +#include "formatstatement.h" + +class SqliteAttach; + +class FormatAttach : public FormatStatement +{ + public: + FormatAttach(SqliteAttach* att); + + protected: + void formatInternal(); + + private: + SqliteAttach* att = nullptr; +}; + +#endif // FORMATATTACH_H diff --git a/Plugins/SqlEnterpriseFormatter/formatbegintrans.cpp b/Plugins/SqlEnterpriseFormatter/formatbegintrans.cpp new file mode 100644 index 0000000..5a70d61 --- /dev/null +++ b/Plugins/SqlEnterpriseFormatter/formatbegintrans.cpp @@ -0,0 +1,24 @@ +#include "formatbegintrans.h" +#include "parser/ast/sqlitebegintrans.h" + +FormatBeginTrans::FormatBeginTrans(SqliteBeginTrans* bt) : + bt(bt) +{ +} + +void FormatBeginTrans::formatInternal() +{ + withKeyword("BEGIN"); + + if (bt->type != SqliteBeginTrans::Type::null) + withKeyword(SqliteBeginTrans::typeToString(bt->type)); + + if (bt->transactionKw) + { + withKeyword("TRANSACTION"); + if (!bt->name.isNull()) + withId(bt->name); + } + + withConflict(bt->onConflict).withSemicolon(); +} diff --git a/Plugins/SqlEnterpriseFormatter/formatbegintrans.h b/Plugins/SqlEnterpriseFormatter/formatbegintrans.h new file mode 100644 index 0000000..10d6dc1 --- /dev/null +++ b/Plugins/SqlEnterpriseFormatter/formatbegintrans.h @@ -0,0 +1,20 @@ +#ifndef FORMATBEGINTRANS_H +#define FORMATBEGINTRANS_H + +#include "formatstatement.h" + +class SqliteBeginTrans; + +class FormatBeginTrans : public FormatStatement +{ + public: + FormatBeginTrans(SqliteBeginTrans* bt); + + protected: + void formatInternal(); + + private: + SqliteBeginTrans* bt = nullptr; +}; + +#endif // FORMATBEGINTRANS_H diff --git a/Plugins/SqlEnterpriseFormatter/formatcolumntype.cpp b/Plugins/SqlEnterpriseFormatter/formatcolumntype.cpp new file mode 100644 index 0000000..1ff4c1d --- /dev/null +++ b/Plugins/SqlEnterpriseFormatter/formatcolumntype.cpp @@ -0,0 +1,43 @@ +#include "formatcolumntype.h" +#include "parser/ast/sqlitecolumntype.h" +#include "sqlenterpriseformatter.h" + +FormatColumnType::FormatColumnType(SqliteColumnType* colType) : + colType(colType) +{ +} + +void FormatColumnType::formatInternal() +{ + if (colType->name.isEmpty()) + return; + + withId(cfg->SqlEnterpriseFormatter.UppercaseDataTypes.get() ? colType->name.toUpper() : colType->name.toLower()); + + if (!colType->scale.isNull()) + { + withParExprLeft(); + if (colType->scale.userType() == QVariant::Int) + withInteger(colType->scale.toInt()); + else if (colType->scale.userType() == QVariant::LongLong) + withInteger(colType->scale.toLongLong()); + else if (colType->scale.userType() == QVariant::Double) + withFloat(colType->scale.toDouble()); + else + withId(colType->scale.toString()); + + if (!colType->precision.isNull()) + { + withCommaOper(); + if (colType->precision.userType() == QVariant::Int) + withInteger(colType->precision.toInt()); + else if (colType->precision.userType() == QVariant::LongLong) + withInteger(colType->precision.toLongLong()); + else if (colType->precision.userType() == QVariant::Double) + withFloat(colType->precision.toDouble()); + else + withId(colType->precision.toString()); + } + withParExprRight(); + } +} diff --git a/Plugins/SqlEnterpriseFormatter/formatcolumntype.h b/Plugins/SqlEnterpriseFormatter/formatcolumntype.h new file mode 100644 index 0000000..6404aa5 --- /dev/null +++ b/Plugins/SqlEnterpriseFormatter/formatcolumntype.h @@ -0,0 +1,20 @@ +#ifndef FORMATCOLUMNTYPE_H +#define FORMATCOLUMNTYPE_H + +#include "formatstatement.h" + +class SqliteColumnType; + +class FormatColumnType : public FormatStatement +{ + public: + FormatColumnType(SqliteColumnType* colType); + + protected: + void formatInternal(); + + private: + SqliteColumnType* colType = nullptr; +}; + +#endif // FORMATCOLUMNTYPE_H diff --git a/Plugins/SqlEnterpriseFormatter/formatcommittrans.cpp b/Plugins/SqlEnterpriseFormatter/formatcommittrans.cpp new file mode 100644 index 0000000..7fdafa3 --- /dev/null +++ b/Plugins/SqlEnterpriseFormatter/formatcommittrans.cpp @@ -0,0 +1,24 @@ +#include "formatcommittrans.h" +#include "parser/ast/sqlitecommittrans.h" + +FormatCommitTrans::FormatCommitTrans(SqliteCommitTrans* ct) : + ct(ct) +{ +} + +void FormatCommitTrans::formatInternal() +{ + if (ct->endKw) + withKeyword("END"); + else + withKeyword("COMMIT"); + + if (ct->transactionKw) + { + withKeyword("TRANSACTION"); + if (!ct->name.isNull()) + withId(ct->name); + } + + withOperator(";"); +} diff --git a/Plugins/SqlEnterpriseFormatter/formatcommittrans.h b/Plugins/SqlEnterpriseFormatter/formatcommittrans.h new file mode 100644 index 0000000..5de2a88 --- /dev/null +++ b/Plugins/SqlEnterpriseFormatter/formatcommittrans.h @@ -0,0 +1,20 @@ +#ifndef FORMATCOMMITTRANS_H +#define FORMATCOMMITTRANS_H + +#include "formatstatement.h" + +class SqliteCommitTrans; + +class FormatCommitTrans : public FormatStatement +{ + public: + FormatCommitTrans(SqliteCommitTrans* ct); + + protected: + void formatInternal(); + + private: + SqliteCommitTrans* ct = nullptr; +}; + +#endif // FORMATCOMMITTRANS_H diff --git a/Plugins/SqlEnterpriseFormatter/formatcopy.cpp b/Plugins/SqlEnterpriseFormatter/formatcopy.cpp new file mode 100644 index 0000000..fa07d48 --- /dev/null +++ b/Plugins/SqlEnterpriseFormatter/formatcopy.cpp @@ -0,0 +1,24 @@ +#include "formatcopy.h" +#include "parser/ast/sqlitecopy.h" + +FormatCopy::FormatCopy(SqliteCopy* copy) : + copy(copy) +{ +} + +void FormatCopy::formatInternal() +{ + withKeyword("COPY"); + if (copy->onConflict != SqliteConflictAlgo::null) + withKeyword("OR").withKeyword(sqliteConflictAlgo(copy->onConflict)); + + if (!copy->database.isNull()) + withId(copy->database); + + withId(copy->table).withKeyword("FROM").withString(copy->file); + + if (!copy->delimiter.isNull()) + withKeyword("USING").withKeyword("DELIMITERS").withString(copy->delimiter); + + withSemicolon(); +} diff --git a/Plugins/SqlEnterpriseFormatter/formatcopy.h b/Plugins/SqlEnterpriseFormatter/formatcopy.h new file mode 100644 index 0000000..c0125e9 --- /dev/null +++ b/Plugins/SqlEnterpriseFormatter/formatcopy.h @@ -0,0 +1,20 @@ +#ifndef FORMATCOPY_H +#define FORMATCOPY_H + +#include "formatstatement.h" + +class SqliteCopy; + +class FormatCopy : public FormatStatement +{ + public: + FormatCopy(SqliteCopy* copy); + + protected: + void formatInternal(); + + private: + SqliteCopy* copy = nullptr; +}; + +#endif // FORMATCOPY_H diff --git a/Plugins/SqlEnterpriseFormatter/formatcreateindex.cpp b/Plugins/SqlEnterpriseFormatter/formatcreateindex.cpp new file mode 100644 index 0000000..cc8f3f6 --- /dev/null +++ b/Plugins/SqlEnterpriseFormatter/formatcreateindex.cpp @@ -0,0 +1,42 @@ +#include "formatcreateindex.h" +#include "parser/ast/sqlitecreateindex.h" +#include "parser/ast/sqliteindexedcolumn.h" + +FormatCreateIndex::FormatCreateIndex(SqliteCreateIndex* createIndex) : + createIndex(createIndex) +{ +} + +void FormatCreateIndex::formatInternal() +{ + withKeyword("CREATE"); + if (createIndex->uniqueKw) + withKeyword("UNIQUE"); + + withKeyword("INDEX"); + + if (createIndex->ifNotExistsKw) + withKeyword("IF").withKeyword("NOT").withKeyword("EXISTS"); + + if (dialect == Dialect::Sqlite2) + { + withId(createIndex->index).withKeyword("ON"); + + if (!createIndex->database.isNull()) + withId(createIndex->database).withIdDot(); + + withId(createIndex->table).withParDefLeft().withStatementList(createIndex->indexedColumns).withParDefRight().withConflict(createIndex->onConflict); + } + else + { + if (!createIndex->database.isNull()) + withId(createIndex->database).withIdDot(); + + withId(createIndex->index).withKeyword("ON").withId(createIndex->table).withParDefLeft().withStatementList(createIndex->indexedColumns).withParDefRight(); + + if (createIndex->where) + withKeyword("WHERE").withStatement(createIndex->where); + } + + withSemicolon(); +} diff --git a/Plugins/SqlEnterpriseFormatter/formatcreateindex.h b/Plugins/SqlEnterpriseFormatter/formatcreateindex.h new file mode 100644 index 0000000..1f1b109 --- /dev/null +++ b/Plugins/SqlEnterpriseFormatter/formatcreateindex.h @@ -0,0 +1,20 @@ +#ifndef FORMATCREATEINDEX_H +#define FORMATCREATEINDEX_H + +#include "formatstatement.h" + +class SqliteCreateIndex; + +class FormatCreateIndex : public FormatStatement +{ + public: + FormatCreateIndex(SqliteCreateIndex* createIndex); + + protected: + void formatInternal(); + + private: + SqliteCreateIndex* createIndex = nullptr; +}; + +#endif // FORMATCREATEINDEX_H diff --git a/Plugins/SqlEnterpriseFormatter/formatcreatetable.cpp b/Plugins/SqlEnterpriseFormatter/formatcreatetable.cpp new file mode 100644 index 0000000..d37239a --- /dev/null +++ b/Plugins/SqlEnterpriseFormatter/formatcreatetable.cpp @@ -0,0 +1,224 @@ +#include "formatcolumntype.h" +#include "formatcreatetable.h" +#include "sqlenterpriseformatter.h" + +FormatCreateTable::FormatCreateTable(SqliteCreateTable* createTable) : + createTable(createTable) +{ +} + +void FormatCreateTable::formatInternal() +{ + withKeyword("CREATE"); + if (createTable->tempKw) + withKeyword("TEMP"); + else if (createTable->temporaryKw) + withKeyword("TEMPORARY"); + + withKeyword("TABLE"); + if (createTable->ifNotExistsKw) + withKeyword("IF").withKeyword("NOT").withKeyword("EXISTS"); + + if (dialect == Dialect::Sqlite3 && !createTable->database.isNull()) + withId(createTable->database).withIdDot(); + + withId(createTable->table); + + if (createTable->select) + withKeyword("AS").withStatement(createTable->select); + else + { + withParDefLeft(); + formatColumns(createTable->columns); + if (createTable->constraints.size() > 0) + withListComma().withStatementList(createTable->constraints); + + withParDefRight(); + + if (!createTable->withOutRowId.isNull()) + withKeyword("WITHOUT").withId("ROWID"); + } + + withSemicolon(); +} + +void FormatCreateTable::formatColumns(const QList<SqliteCreateTable::Column*>& columns) +{ + int maxColNameIndent = 0; + int maxColTypeIndent = 0; + FormatColumnType* formatColType = nullptr; + foreach (SqliteCreateTable::Column* stmt, columns) + { + maxColNameIndent = qMax(getColNameLength(stmt->name), maxColNameIndent); + + if (stmt->type) + { + + formatColType = getFormatStatement<FormatColumnType>(stmt->type); + maxColTypeIndent = qMax(formatColType->format().trimmed().length(), maxColTypeIndent); + delete formatColType; + } + } + + if (columns.size() > 1) + { + maxColNameIndent++; // for a single whitespace to line up with other columns + maxColTypeIndent++; // the same for constraints + } + + withStatementList(columns, "columns", ListSeparator::COMMA, [maxColNameIndent, maxColTypeIndent](FormatStatement* formatStmt) + { + FormatCreateTableColumn* colStmt = dynamic_cast<FormatCreateTableColumn*>(formatStmt); + if (colStmt) + { + colStmt->setColNameIndent(maxColNameIndent); + colStmt->setColTypeIndent(maxColTypeIndent); + } + }); +} + +int FormatCreateTable::getColNameLength(const QString& name) +{ + if (cfg->SqlEnterpriseFormatter.AlwaysUseNameWrapping.get()) + return wrapObjName(name, dialect, wrapper).length(); + else + return wrapObjIfNeeded(name, dialect, wrapper).length(); +} + +FormatCreateTableColumn::FormatCreateTableColumn(SqliteCreateTable::Column* column) : + column(column) +{ +} + +void FormatCreateTableColumn::setColNameIndent(int value) +{ + colNameIndent = value; +} + +void FormatCreateTableColumn::setColTypeIndent(int value) +{ + colTypeIndent = value; +} + +void FormatCreateTableColumn::formatInternal() +{ + ListSeparator sep = ListSeparator::NONE; + if (cfg->SqlEnterpriseFormatter.NlBetweenConstraints.get()) + sep = ListSeparator::NEW_LINE; + + withId(column->name).withIncrIndent(colNameIndent).withStatement(column->type).withIncrIndent(colTypeIndent) + .withStatementList(column->constraints, QString(), sep).withDecrIndent().withDecrIndent(); +} + + +FormatCreateTableColumnConstraint::FormatCreateTableColumnConstraint(SqliteCreateTable::Column::Constraint* constr) : + constr(constr) +{ +} + +void FormatCreateTableColumnConstraint::formatInternal() +{ + if (!constr->name.isNull()) + withKeyword("CONSTRAINT").withId(constr->name); + + switch (constr->type) + { + case SqliteCreateTable::Column::Constraint::PRIMARY_KEY: + { + withKeyword("PRIMARY").withKeyword("KEY").withSortOrder(constr->sortOrder).withConflict(constr->onConflict); + if (constr->autoincrKw) + withKeyword("AUTOINCREMENT"); + + break; + } + case SqliteCreateTable::Column::Constraint::NOT_NULL: + { + withKeyword("NOT").withKeyword("NULL").withConflict(constr->onConflict); + break; + } + case SqliteCreateTable::Column::Constraint::UNIQUE: + { + withKeyword("UNIQUE").withConflict(constr->onConflict); + break; + } + case SqliteCreateTable::Column::Constraint::CHECK: + { + withKeyword("CHECK").withParExprLeft().withStatement(constr->expr).withParExprRight().withConflict(constr->onConflict); + break; + } + case SqliteCreateTable::Column::Constraint::DEFAULT: + { + withKeyword("DEFAULT"); + if (!constr->id.isNull()) + withId(constr->id); + else if (!constr->ctime.isNull()) + withKeyword(constr->ctime); + else if (constr->expr) + withParExprLeft().withStatement(constr->expr).withParExprRight(); + else if (constr->literalNull) + withKeyword("NULL"); + else + withLiteral(constr->literalValue); + + break; + } + case SqliteCreateTable::Column::Constraint::COLLATE: + { + withKeyword("COLLATE").withId(constr->collationName); + break; + } + case SqliteCreateTable::Column::Constraint::FOREIGN_KEY: + { + withStatement(constr->foreignKey); + break; + } + case SqliteCreateTable::Column::Constraint::NULL_: + case SqliteCreateTable::Column::Constraint::NAME_ONLY: + case SqliteCreateTable::Column::Constraint::DEFERRABLE_ONLY: + break; + } +} + + +FormatCreateTableConstraint::FormatCreateTableConstraint(SqliteCreateTable::Constraint* constr) : + constr(constr) +{ +} + +void FormatCreateTableConstraint::formatInternal() +{ + if (!constr->name.isNull()) + withKeyword("CONSTRAINT").withId(constr->name); + + switch (constr->type) + { + case SqliteCreateTable::Constraint::PRIMARY_KEY: + { + withKeyword("PRIMARY").withKeyword("KEY").withParDefLeft().withStatementList(constr->indexedColumns).withParDefRight(); + + if (constr->autoincrKw) + withKeyword("AUTOINCREMENT"); + + withConflict(constr->onConflict); + break; + } + case SqliteCreateTable::Constraint::UNIQUE: + { + withKeyword("UNIQUE").withParDefLeft().withStatementList(constr->indexedColumns).withParDefRight().withConflict(constr->onConflict); + break; + } + case SqliteCreateTable::Constraint::CHECK: + { + withKeyword("CHECK").withParExprLeft().withStatement(constr->expr).withParExprRight().withConflict(constr->onConflict); + break; + } + case SqliteCreateTable::Constraint::FOREIGN_KEY: + { + withKeyword("FOREIGN").withKeyword("KEY").withParDefLeft().withStatementList(constr->indexedColumns) + .withParDefRight().withStatement(constr->foreignKey); + break; + } + case SqliteCreateTable::Constraint::NAME_ONLY: + break; + } +} diff --git a/Plugins/SqlEnterpriseFormatter/formatcreatetable.h b/Plugins/SqlEnterpriseFormatter/formatcreatetable.h new file mode 100644 index 0000000..8c1d720 --- /dev/null +++ b/Plugins/SqlEnterpriseFormatter/formatcreatetable.h @@ -0,0 +1,63 @@ +#ifndef FORMATCREATETABLE_H +#define FORMATCREATETABLE_H + +#include "formatstatement.h" +#include "parser/ast/sqlitecreatetable.h" + +class FormatCreateTable : public FormatStatement +{ + public: + FormatCreateTable(SqliteCreateTable* createTable); + + protected: + void formatInternal(); + + private: + void formatColumns(const QList<SqliteCreateTable::Column*>& columns); + int getColNameLength(const QString& name); + + SqliteCreateTable* createTable = nullptr; +}; + +class FormatCreateTableColumn : public FormatStatement +{ + public: + FormatCreateTableColumn(SqliteCreateTable::Column* column); + + void setColNameIndent(int value); + void setColTypeIndent(int value); + + protected: + void formatInternal(); + + private: + SqliteCreateTable::Column* column = nullptr; + int colNameIndent = 0; + int colTypeIndent = 0; +}; + +class FormatCreateTableColumnConstraint : public FormatStatement +{ + public: + FormatCreateTableColumnConstraint(SqliteCreateTable::Column::Constraint* constr); + + protected: + void formatInternal(); + + private: + SqliteCreateTable::Column::Constraint* constr = nullptr; +}; + +class FormatCreateTableConstraint : public FormatStatement +{ + public: + FormatCreateTableConstraint(SqliteCreateTable::Constraint* constr); + + protected: + void formatInternal(); + + private: + SqliteCreateTable::Constraint* constr = nullptr; +}; + +#endif // FORMATCREATETABLE_H diff --git a/Plugins/SqlEnterpriseFormatter/formatcreatetrigger.cpp b/Plugins/SqlEnterpriseFormatter/formatcreatetrigger.cpp new file mode 100644 index 0000000..d05d8cf --- /dev/null +++ b/Plugins/SqlEnterpriseFormatter/formatcreatetrigger.cpp @@ -0,0 +1,90 @@ +#include "formatcreatetrigger.h" +#include "parser/ast/sqliteexpr.h" + +FormatCreateTrigger::FormatCreateTrigger(SqliteCreateTrigger* createTrig) : + createTrig(createTrig) +{ +} + +void FormatCreateTrigger::formatInternal() +{ + withKeyword("CREATE"); + if (createTrig->tempKw) + withKeyword("TEMP"); + else if (createTrig->temporaryKw) + withKeyword("TEMPORARY"); + + withKeyword("TRIGGER"); + if (createTrig->ifNotExistsKw) + withKeyword("IF").withKeyword("NOT").withKeyword("EXISTS"); + + if (dialect == Dialect::Sqlite3 && !createTrig->database.isNull()) + withId(createTrig->database).withIdDot(); + + withId(createTrig->trigger); + switch (createTrig->eventTime) + { + case SqliteCreateTrigger::Time::BEFORE: + withKeyword("BEFORE"); + break; + case SqliteCreateTrigger::Time::AFTER: + withKeyword("AFTER"); + break; + case SqliteCreateTrigger::Time::INSTEAD_OF: + withKeyword("INSTEAD").withKeyword("OF"); + break; + case SqliteCreateTrigger::Time::null: + break; + } + + withStatement(createTrig->event).withKeyword("ON"); + if (dialect == Dialect::Sqlite2 && !createTrig->database.isNull()) + withId(createTrig->database).withIdDot(); + + withId(createTrig->table); + + switch (createTrig->scope) + { + case SqliteCreateTrigger::Scope::FOR_EACH_ROW: + withKeyword("FOR").withKeyword("EACH").withKeyword("ROW"); + break; + case SqliteCreateTrigger::Scope::FOR_EACH_STATEMENT: + withKeyword("FOR").withKeyword("EACH").withKeyword("STATEMENT"); + break; + case SqliteCreateTrigger::Scope::null: + break; + } + + if (createTrig->precondition) + withKeyword("WHEN").withStatement(createTrig->precondition); + + withNewLine().withKeyword("BEGIN").withNewLine().withIncrIndent().withStatementList(createTrig->queries, QString(), ListSeparator::SEMICOLON).withSemicolon(); + withDecrIndent().withKeyword("END").withSemicolon(); +} + + +FormatCreateTriggerEvent::FormatCreateTriggerEvent(SqliteCreateTrigger::Event* ev) : + ev(ev) +{ +} + +void FormatCreateTriggerEvent::formatInternal() +{ + switch (ev->type) + { + case SqliteCreateTrigger::Event::INSERT: + withKeyword("INSERT"); + break; + case SqliteCreateTrigger::Event::UPDATE: + withKeyword("UPDATE"); + break; + case SqliteCreateTrigger::Event::DELETE: + withKeyword("DELETE"); + break; + case SqliteCreateTrigger::Event::UPDATE_OF: + withKeyword("UPDATE").withKeyword("OF").withIdList(ev->columnNames); + break; + case SqliteCreateTrigger::Event::null: + break; + } +} diff --git a/Plugins/SqlEnterpriseFormatter/formatcreatetrigger.h b/Plugins/SqlEnterpriseFormatter/formatcreatetrigger.h new file mode 100644 index 0000000..795c2c7 --- /dev/null +++ b/Plugins/SqlEnterpriseFormatter/formatcreatetrigger.h @@ -0,0 +1,31 @@ +#ifndef FORMATCREATETRIGGER_H +#define FORMATCREATETRIGGER_H + +#include "formatstatement.h" +#include "parser/ast/sqlitecreatetrigger.h" + +class FormatCreateTrigger : public FormatStatement +{ + public: + FormatCreateTrigger(SqliteCreateTrigger* createTrig); + + protected: + void formatInternal(); + + private: + SqliteCreateTrigger* createTrig = nullptr; +}; + +class FormatCreateTriggerEvent : public FormatStatement +{ + public: + FormatCreateTriggerEvent(SqliteCreateTrigger::Event* ev); + + protected: + void formatInternal(); + + private: + SqliteCreateTrigger::Event* ev = nullptr; +}; + +#endif // FORMATCREATETRIGGER_H diff --git a/Plugins/SqlEnterpriseFormatter/formatcreateview.cpp b/Plugins/SqlEnterpriseFormatter/formatcreateview.cpp new file mode 100644 index 0000000..faec87a --- /dev/null +++ b/Plugins/SqlEnterpriseFormatter/formatcreateview.cpp @@ -0,0 +1,26 @@ +#include "formatcreateview.h" +#include "parser/ast/sqlitecreateview.h" +#include "parser/ast/sqliteselect.h" + +FormatCreateView::FormatCreateView(SqliteCreateView* createView) : + createView(createView) +{ +} + +void FormatCreateView::formatInternal() +{ + withKeyword("CREATE"); + if (createView->tempKw) + withKeyword("TEMP"); + else if (createView->temporaryKw) + withKeyword("TEMPORARY"); + + withKeyword("VIEW"); + if (createView->ifNotExists) + withKeyword("IF").withKeyword("NOT").withKeyword("EXISTS"); + + if (dialect == Dialect::Sqlite3 && !createView->database.isNull()) + withId(createView->database).withIdDot(); + + withId(createView->view).withKeyword("AS").withStatement(createView->select).withSemicolon(); +} diff --git a/Plugins/SqlEnterpriseFormatter/formatcreateview.h b/Plugins/SqlEnterpriseFormatter/formatcreateview.h new file mode 100644 index 0000000..77f6219 --- /dev/null +++ b/Plugins/SqlEnterpriseFormatter/formatcreateview.h @@ -0,0 +1,20 @@ +#ifndef FORMATCREATEVIEW_H +#define FORMATCREATEVIEW_H + +#include "formatstatement.h" + +class SqliteCreateView; + +class FormatCreateView : public FormatStatement +{ + public: + FormatCreateView(SqliteCreateView* createView); + + protected: + void formatInternal(); + + private: + SqliteCreateView* createView = nullptr; +}; + +#endif // FORMATCREATEVIEW_H diff --git a/Plugins/SqlEnterpriseFormatter/formatcreatevirtualtable.cpp b/Plugins/SqlEnterpriseFormatter/formatcreatevirtualtable.cpp new file mode 100644 index 0000000..d291eda --- /dev/null +++ b/Plugins/SqlEnterpriseFormatter/formatcreatevirtualtable.cpp @@ -0,0 +1,106 @@ +#include "formatcreatevirtualtable.h" +#include "parser/ast/sqlitecreatevirtualtable.h" +#include "parser/lexer.h" + +FormatCreateVirtualTable::FormatCreateVirtualTable(SqliteCreateVirtualTable* cvt) : + cvt(cvt) +{ +} + +void FormatCreateVirtualTable::formatInternal() +{ + withKeyword("CREATE").withKeyword("VIRTUAL").withKeyword("TABLE"); + if (cvt->ifNotExistsKw) + withKeyword("IF").withKeyword("NOT").withKeyword("EXISTS"); + + if (!cvt->database.isNull()) + withId(cvt->database).withIdDot(); + + withId(cvt->table).withKeyword("USING").withId(cvt->module); + if (!cvt->args.isEmpty()) + { + withParDefLeft(); + int i = 0; + for (const QString& arg : cvt->args) + { + if (i > 0) + withListComma(); + + for (const TokenPtr& tk : Lexer::tokenize(arg, Dialect::Sqlite3)) + handleToken(tk); + + i++; + } + withParDefRight(); + } + + withSemicolon(); +} + +void FormatCreateVirtualTable::handleToken(const TokenPtr& token) +{ + switch (token->type) + { + case Token::OTHER: + withId(token->value); + break; + case Token::STRING: + withString(token->value); + break; + case Token::COMMENT: + // TODO Format comment here + break; + case Token::FLOAT: + withFloat(token->value.toDouble()); + break; + case Token::INTEGER: + withInteger(token->value.toInt()); + break; + case Token::BIND_PARAM: + withBindParam(token->value); + break; + case Token::OPERATOR: + withOperator(token->value); + break; + case Token::PAR_LEFT: + withParDefLeft(); + break; + case Token::PAR_RIGHT: + withParDefRight(); + break; + case Token::BLOB: + withBlob(token->value); + break; + case Token::KEYWORD: + withKeyword(token->value); + break; + case Token::SPACE: + case Token::INVALID: + case Token::CTX_COLUMN: + case Token::CTX_TABLE: + case Token::CTX_DATABASE: + case Token::CTX_FUNCTION: + case Token::CTX_COLLATION: + case Token::CTX_INDEX: + case Token::CTX_TRIGGER: + case Token::CTX_VIEW: + case Token::CTX_JOIN_OPTS: + case Token::CTX_TABLE_NEW: + case Token::CTX_INDEX_NEW: + case Token::CTX_VIEW_NEW: + case Token::CTX_TRIGGER_NEW: + case Token::CTX_ALIAS: + case Token::CTX_TRANSACTION: + case Token::CTX_COLUMN_NEW: + case Token::CTX_COLUMN_TYPE: + case Token::CTX_CONSTRAINT: + case Token::CTX_FK_MATCH: + case Token::CTX_PRAGMA: + case Token::CTX_ROWID_KW: + case Token::CTX_NEW_KW: + case Token::CTX_OLD_KW: + case Token::CTX_ERROR_MESSAGE: + break; + } +} + diff --git a/Plugins/SqlEnterpriseFormatter/formatcreatevirtualtable.h b/Plugins/SqlEnterpriseFormatter/formatcreatevirtualtable.h new file mode 100644 index 0000000..ad99d39 --- /dev/null +++ b/Plugins/SqlEnterpriseFormatter/formatcreatevirtualtable.h @@ -0,0 +1,23 @@ +#ifndef FORMATCREATEVIRTUALTABLE_H +#define FORMATCREATEVIRTUALTABLE_H + +#include "formatstatement.h" +#include "parser/token.h" + +class SqliteCreateVirtualTable; + +class FormatCreateVirtualTable : public FormatStatement +{ + public: + FormatCreateVirtualTable(SqliteCreateVirtualTable* cvt); + + protected: + void formatInternal(); + + private: + void handleToken(const TokenPtr& token); + + SqliteCreateVirtualTable* cvt = nullptr; +}; + +#endif // FORMATCREATEVIRTUALTABLE_H diff --git a/Plugins/SqlEnterpriseFormatter/formatdelete.cpp b/Plugins/SqlEnterpriseFormatter/formatdelete.cpp new file mode 100644 index 0000000..ca6ac5b --- /dev/null +++ b/Plugins/SqlEnterpriseFormatter/formatdelete.cpp @@ -0,0 +1,33 @@ +#include "formatdelete.h" +#include "parser/ast/sqlitedelete.h" +#include "parser/ast/sqliteexpr.h" +#include "formatwith.h" + +FormatDelete::FormatDelete(SqliteDelete* del) : + del(del) +{ +} + +void FormatDelete::formatInternal() +{ + if (del->with) + withStatement(del->with); + + markKeywordLineUp("DELETE FROM"); + + withKeyword("DELETE").withKeyword("FROM"); + if (!del->database.isNull()) + withId(del->database).withIdDot(); + + withId(del->table); + + if (del->indexedByKw) + withKeyword("INDEXED").withKeyword("BY").withId(del->indexedBy); + else if (del->notIndexedKw) + withKeyword("NOT").withKeyword("INDEXED"); + + if (del->where) + withNewLine().withLinedUpKeyword("WHERE").withStatement(del->where); + + withSemicolon(); +} diff --git a/Plugins/SqlEnterpriseFormatter/formatdelete.h b/Plugins/SqlEnterpriseFormatter/formatdelete.h new file mode 100644 index 0000000..65489f8 --- /dev/null +++ b/Plugins/SqlEnterpriseFormatter/formatdelete.h @@ -0,0 +1,20 @@ +#ifndef FORMATDELETE_H +#define FORMATDELETE_H + +#include "formatstatement.h" + +class SqliteDelete; + +class FormatDelete : public FormatStatement +{ + public: + FormatDelete(SqliteDelete* del); + + protected: + void formatInternal(); + + private: + SqliteDelete* del = nullptr; +}; + +#endif // FORMATDELETE_H diff --git a/Plugins/SqlEnterpriseFormatter/formatdetach.cpp b/Plugins/SqlEnterpriseFormatter/formatdetach.cpp new file mode 100644 index 0000000..e788da7 --- /dev/null +++ b/Plugins/SqlEnterpriseFormatter/formatdetach.cpp @@ -0,0 +1,18 @@ +#include "formatdetach.h" +#include "parser/ast/sqlitedetach.h" +#include "parser/ast/sqliteexpr.h" + +FormatDetach::FormatDetach(SqliteDetach* detach) : + detach(detach) +{ +} + +void FormatDetach::formatInternal() +{ + withKeyword("DETACH"); + + if (detach->databaseKw) + withKeyword("DATABASE"); + + withStatement(detach->name).withSemicolon(); +} diff --git a/Plugins/SqlEnterpriseFormatter/formatdetach.h b/Plugins/SqlEnterpriseFormatter/formatdetach.h new file mode 100644 index 0000000..5f73a2c --- /dev/null +++ b/Plugins/SqlEnterpriseFormatter/formatdetach.h @@ -0,0 +1,20 @@ +#ifndef FORMATDETACH_H +#define FORMATDETACH_H + +#include "formatstatement.h" + +class SqliteDetach; + +class FormatDetach : public FormatStatement +{ + public: + FormatDetach(SqliteDetach* detach); + + protected: + void formatInternal(); + + private: + SqliteDetach* detach = nullptr; +}; + +#endif // FORMATDETACH_H diff --git a/Plugins/SqlEnterpriseFormatter/formatdropindex.cpp b/Plugins/SqlEnterpriseFormatter/formatdropindex.cpp new file mode 100644 index 0000000..1e85bb8 --- /dev/null +++ b/Plugins/SqlEnterpriseFormatter/formatdropindex.cpp @@ -0,0 +1,20 @@ +#include "formatdropindex.h" +#include "parser/ast/sqlitedropindex.h" + +FormatDropIndex::FormatDropIndex(SqliteDropIndex* dropIndex) : + dropIndex(dropIndex) +{ +} + +void FormatDropIndex::formatInternal() +{ + withKeyword("DROP").withKeyword("INDEX"); + + if (dropIndex->ifExistsKw) + withKeyword("IF").withKeyword("EXISTS"); + + if (!dropIndex->database.isNull()) + withId(dropIndex->database).withIdDot(); + + withId(dropIndex->index).withSemicolon(); +} diff --git a/Plugins/SqlEnterpriseFormatter/formatdropindex.h b/Plugins/SqlEnterpriseFormatter/formatdropindex.h new file mode 100644 index 0000000..2ecf51c --- /dev/null +++ b/Plugins/SqlEnterpriseFormatter/formatdropindex.h @@ -0,0 +1,20 @@ +#ifndef FORMATDROPINDEX_H +#define FORMATDROPINDEX_H + +#include "formatstatement.h" + +class SqliteDropIndex; + +class FormatDropIndex : public FormatStatement +{ + public: + FormatDropIndex(SqliteDropIndex* dropIndex); + + protected: + void formatInternal(); + + private: + SqliteDropIndex* dropIndex = nullptr; +}; + +#endif // FORMATDROPINDEX_H diff --git a/Plugins/SqlEnterpriseFormatter/formatdroptable.cpp b/Plugins/SqlEnterpriseFormatter/formatdroptable.cpp new file mode 100644 index 0000000..775adfe --- /dev/null +++ b/Plugins/SqlEnterpriseFormatter/formatdroptable.cpp @@ -0,0 +1,21 @@ +#include "formatdroptable.h" +#include "parser/ast/sqlitedroptable.h" + +FormatDropTable::FormatDropTable(SqliteDropTable* dropTable) : + dropTable(dropTable) +{ +} + +void FormatDropTable::formatInternal() +{ + withKeyword("DROP").withKeyword("TABLE"); + + if (dropTable->ifExistsKw) + withKeyword("IF").withKeyword("EXISTS"); + + if (!dropTable->database.isNull()) + withId(dropTable->database).withIdDot(); + + withId(dropTable->table).withSemicolon(); + +} diff --git a/Plugins/SqlEnterpriseFormatter/formatdroptable.h b/Plugins/SqlEnterpriseFormatter/formatdroptable.h new file mode 100644 index 0000000..1c0d456 --- /dev/null +++ b/Plugins/SqlEnterpriseFormatter/formatdroptable.h @@ -0,0 +1,20 @@ +#ifndef FORMATDROPTABLE_H +#define FORMATDROPTABLE_H + +#include "formatstatement.h" + +class SqliteDropTable; + +class FormatDropTable : public FormatStatement +{ + public: + FormatDropTable(SqliteDropTable* dropTable); + + protected: + void formatInternal(); + + private: + SqliteDropTable* dropTable = nullptr; +}; + +#endif // FORMATDROPTABLE_H diff --git a/Plugins/SqlEnterpriseFormatter/formatdroptrigger.cpp b/Plugins/SqlEnterpriseFormatter/formatdroptrigger.cpp new file mode 100644 index 0000000..ca8caa8 --- /dev/null +++ b/Plugins/SqlEnterpriseFormatter/formatdroptrigger.cpp @@ -0,0 +1,21 @@ +#include "formatdroptrigger.h" +#include "parser/ast/sqlitedroptrigger.h" + +FormatDropTrigger::FormatDropTrigger(SqliteDropTrigger* dropTrig) : + dropTrig(dropTrig) +{ +} + +void FormatDropTrigger::formatInternal() +{ + withKeyword("DROP").withKeyword("TRIGGER"); + + if (dropTrig->ifExistsKw) + withKeyword("IF").withKeyword("EXISTS"); + + if (!dropTrig->database.isNull()) + withId(dropTrig->database).withIdDot(); + + withId(dropTrig->trigger).withSemicolon(); + +} diff --git a/Plugins/SqlEnterpriseFormatter/formatdroptrigger.h b/Plugins/SqlEnterpriseFormatter/formatdroptrigger.h new file mode 100644 index 0000000..26f9ebe --- /dev/null +++ b/Plugins/SqlEnterpriseFormatter/formatdroptrigger.h @@ -0,0 +1,20 @@ +#ifndef FORMATDROPTRIGGER_H +#define FORMATDROPTRIGGER_H + +#include "formatstatement.h" + +class SqliteDropTrigger; + +class FormatDropTrigger : public FormatStatement +{ + public: + FormatDropTrigger(SqliteDropTrigger* dropTrig); + + protected: + void formatInternal(); + + private: + SqliteDropTrigger* dropTrig = nullptr; +}; + +#endif // FORMATDROPTRIGGER_H diff --git a/Plugins/SqlEnterpriseFormatter/formatdropview.cpp b/Plugins/SqlEnterpriseFormatter/formatdropview.cpp new file mode 100644 index 0000000..965d607 --- /dev/null +++ b/Plugins/SqlEnterpriseFormatter/formatdropview.cpp @@ -0,0 +1,20 @@ +#include "formatdropview.h" +#include "parser/ast/sqlitedropview.h" + +FormatDropView::FormatDropView(SqliteDropView* dropView) : + dropView(dropView) +{ +} + +void FormatDropView::formatInternal() +{ + withKeyword("DROP").withKeyword("VIEW"); + + if (dropView->ifExistsKw) + withKeyword("IF").withKeyword("EXISTS"); + + if (!dropView->database.isNull()) + withId(dropView->database).withIdDot(); + + withId(dropView->view).withSemicolon(); +} diff --git a/Plugins/SqlEnterpriseFormatter/formatdropview.h b/Plugins/SqlEnterpriseFormatter/formatdropview.h new file mode 100644 index 0000000..ab724f8 --- /dev/null +++ b/Plugins/SqlEnterpriseFormatter/formatdropview.h @@ -0,0 +1,20 @@ +#ifndef FORMATDROPVIEW_H +#define FORMATDROPVIEW_H + +#include "formatstatement.h" + +class SqliteDropView; + +class FormatDropView : public FormatStatement +{ + public: + FormatDropView(SqliteDropView* dropView); + + protected: + void formatInternal(); + + private: + SqliteDropView* dropView = nullptr; +}; + +#endif // FORMATDROPVIEW_H diff --git a/Plugins/SqlEnterpriseFormatter/formatempty.cpp b/Plugins/SqlEnterpriseFormatter/formatempty.cpp new file mode 100644 index 0000000..976694e --- /dev/null +++ b/Plugins/SqlEnterpriseFormatter/formatempty.cpp @@ -0,0 +1,11 @@ +#include "formatempty.h" + +FormatEmpty::FormatEmpty(SqliteEmptyQuery* eq) : + eq(eq) +{ +} + +void FormatEmpty::formatInternal() +{ + withSemicolon(); +} diff --git a/Plugins/SqlEnterpriseFormatter/formatempty.h b/Plugins/SqlEnterpriseFormatter/formatempty.h new file mode 100644 index 0000000..3279925 --- /dev/null +++ b/Plugins/SqlEnterpriseFormatter/formatempty.h @@ -0,0 +1,20 @@ +#ifndef FORMATEMPTY_H +#define FORMATEMPTY_H + +#include "formatstatement.h" + +class SqliteEmptyQuery; + +class FormatEmpty : public FormatStatement +{ + public: + FormatEmpty(SqliteEmptyQuery* eq); + + protected: + void formatInternal(); + + private: + SqliteEmptyQuery* eq = nullptr; +}; + +#endif // FORMATEMPTY_H diff --git a/Plugins/SqlEnterpriseFormatter/formatexpr.cpp b/Plugins/SqlEnterpriseFormatter/formatexpr.cpp new file mode 100644 index 0000000..2099126 --- /dev/null +++ b/Plugins/SqlEnterpriseFormatter/formatexpr.cpp @@ -0,0 +1,201 @@ +#include "formatexpr.h" +#include "sqlenterpriseformatter.h" +#include "parser/ast/sqliteexpr.h" +#include "parser/ast/sqlitecolumntype.h" +#include "parser/ast/sqliteselect.h" +#include "parser/ast/sqliteraise.h" +#include "sqlenterpriseformatter.h" + +FormatExpr::FormatExpr(SqliteExpr* expr) : + expr(expr) +{ +} + +void FormatExpr::formatInternal() +{ + static QStringList nlBiOp = {"AND", "OR"}; + + switch (expr->mode) + { + case SqliteExpr::Mode::null: + break; + case SqliteExpr::Mode::LITERAL_VALUE: + { + if (expr->literalNull) + withKeyword("NULL"); + else + withLiteral(expr->literalValue); + break; + } + case SqliteExpr::Mode::CTIME: + withKeyword(expr->ctime.toUpper()); + break; + case SqliteExpr::Mode::BIND_PARAM: + withBindParam(expr->bindParam); + break; + case SqliteExpr::Mode::ID: + { + if (!expr->database.isNull()) + withId(expr->database).withIdDot(); + + if (!expr->table.isNull()) + withId(expr->table).withIdDot(); + + if (expr->possibleDoubleQuotedString) + withStringOrId(expr->column); + else + withId(expr->column); + break; + } + case SqliteExpr::Mode::UNARY_OP: + { + // Operator can be a keyword + QString opStr = cfg->SqlEnterpriseFormatter.UppercaseKeywords.get() ? expr->unaryOp.toUpper() : expr->unaryOp.toLower(); + withOperator(opStr).withStatement(expr->expr1, "unaryOp"); + break; + } + case SqliteExpr::Mode::BINARY_OP: + { + bool multiLine = nlBiOp.contains(expr->binaryOp.toUpper()); + + // Operator can be a keyword + QString opStr = cfg->SqlEnterpriseFormatter.UppercaseKeywords.get() ? expr->binaryOp.toUpper() : expr->binaryOp.toLower(); + withStatement(expr->expr1, "binaryOp1").withOperator(opStr); + + if (multiLine) + withNewLine().withIncrIndent("binaryOp1"); + + withStatement(expr->expr2, "binaryOp2"); + if (multiLine) + withDecrIndent(); + break; + } + case SqliteExpr::Mode::FUNCTION: + withFuncId(expr->function).withParFuncLeft().withStatementList(expr->exprList, "funcArgs", FormatStatement::ListSeparator::EXPR_COMMA).withParFuncRight(); + break; + case SqliteExpr::Mode::SUB_EXPR: + withParExprLeft().withStatement(expr->expr1).withParExprRight(); + break; + case SqliteExpr::Mode::CAST: + withKeyword("CAST").withParExprLeft().withStatement(expr->expr1).withKeyword("AS") + .withStatement(expr->columnType, "colType").withParExprRight(); + break; + case SqliteExpr::Mode::COLLATE: + withStatement(expr->expr1).withKeyword("COLLATE").withId(expr->collation); + break; + case SqliteExpr::Mode::LIKE: + { + withStatement(expr->expr1); + if (expr->notKw) + withKeyword("NOT"); + + withKeyword(SqliteExpr::likeOp(expr->like)).withStatement(expr->expr2, "like"); + + if (expr->expr3) + withKeyword("ESCAPE").withStatement(expr->expr3, "likeEscape"); + + break; + } + case SqliteExpr::Mode::NULL_: + withKeyword("NULL"); + break; + case SqliteExpr::Mode::NOTNULL: + { + switch (expr->notNull) + { + case SqliteExpr::NotNull::ISNULL: + withKeyword("ISNULL"); + break; + case SqliteExpr::NotNull::NOT_NULL: + withKeyword("NOT").withKeyword("NULL"); + break; + case SqliteExpr::NotNull::NOTNULL: + withKeyword("NOTNULL"); + break; + case SqliteExpr::NotNull::null: + break; + } + break; + } + case SqliteExpr::Mode::IS: + { + withStatement(expr->expr1).withKeyword("IS"); + if (expr->notKw) + withKeyword("NOT"); + + withStatement(expr->expr2, "is"); + break; + } + case SqliteExpr::Mode::BETWEEN: + { + withStatement(expr->expr1); + + if (expr->notKw) + withKeyword("NOT"); + + withKeyword("BETWEEN").withStatement(expr->expr2, "between1").withKeyword("AND").withStatement(expr->expr3, "between2"); + break; + } + case SqliteExpr::Mode::IN: + { + withStatement(expr->expr1); + + if (expr->notKw) + withKeyword("NOT"); + + withKeyword("IN"); + if (expr->select) + { + withParDefLeft().withStatement(expr->select).withParDefRight(); + } + else if (expr->exprList.size() > 0) + { + withParExprLeft().withStatementList(expr->exprList).withParExprRight(); + } + else + { + if (!expr->database.isNull()) + withId(expr->database).withIdDot(); + + withId(expr->table); + } + break; + } + case SqliteExpr::Mode::EXISTS: + withKeyword("EXISTS").withParDefLeft().withStatement(expr->select).withParDefRight(); + break; + case SqliteExpr::Mode::CASE: + { + withKeyword("CASE"); + if (expr->expr1) + withStatement(expr->expr1, "case"); + + bool then = false; + foreach (SqliteExpr* expr, expr->exprList) + { + if (then) + withKeyword("THEN"); + else + withKeyword("WHEN"); + + withIncrIndent("case"); + withStatement(expr); + withDecrIndent(); + + then = !then; + } + + if (expr->expr2) + withKeyword("ELSE").withIncrIndent("case").withStatement(expr->expr2).withDecrIndent(); + + withKeyword("END"); + break; + } + case SqliteExpr::Mode::SUB_SELECT: + withParDefLeft().withStatement(expr->select).withParDefRight(); + break; + case SqliteExpr::Mode::RAISE: + withStatement(expr->raiseFunction); + break; + } +} diff --git a/Plugins/SqlEnterpriseFormatter/formatexpr.h b/Plugins/SqlEnterpriseFormatter/formatexpr.h new file mode 100644 index 0000000..2712adc --- /dev/null +++ b/Plugins/SqlEnterpriseFormatter/formatexpr.h @@ -0,0 +1,20 @@ +#ifndef FORMATEXPR_H +#define FORMATEXPR_H + +#include "formatstatement.h" + +class SqliteExpr; + +class FormatExpr : public FormatStatement +{ + public: + FormatExpr(SqliteExpr* expr); + + protected: + void formatInternal(); + + private: + SqliteExpr* expr = nullptr; +}; + +#endif // FORMATEXPR_H diff --git a/Plugins/SqlEnterpriseFormatter/formatforeignkey.cpp b/Plugins/SqlEnterpriseFormatter/formatforeignkey.cpp new file mode 100644 index 0000000..6b28a86 --- /dev/null +++ b/Plugins/SqlEnterpriseFormatter/formatforeignkey.cpp @@ -0,0 +1,78 @@ +#include "formatforeignkey.h" + +FormatForeignKey::FormatForeignKey(SqliteForeignKey* fk) : + fk(fk) +{ +} + +void FormatForeignKey::formatInternal() +{ + withKeyword("REFERENCES").withId(fk->foreignTable); + + if (fk->indexedColumns.size() > 0) + withParExprLeft().withStatementList(fk->indexedColumns).withParExprRight(); + + if (fk->conditions.size() > 0) + { + markAndKeepIndent("constr_conditions").withStatementList(fk->conditions, QString(), ListSeparator::NEW_LINE).withDecrIndent(); + } + + if (fk->deferrable != SqliteDeferrable::null) + { + if (fk->deferrable == SqliteDeferrable::NOT_DEFERRABLE) + withKeyword("NOT").withKeyword("DEFERRABLE"); + else if (fk->deferrable == SqliteDeferrable::DEFERRABLE) + withKeyword("DEFERRABLE"); + + if (fk->initially != SqliteInitially::null) + withKeyword("INITIALLY").withKeyword(sqliteInitially(fk->initially)); + } +} + + +FormatForeignKeyCondition::FormatForeignKeyCondition(SqliteForeignKey::Condition* cond) : + cond(cond) +{ +} + +void FormatForeignKeyCondition::formatInternal() +{ + switch (cond->action) + { + case SqliteForeignKey::Condition::UPDATE: + withKeyword("ON").withKeyword("UPDATE"); + break; + case SqliteForeignKey::Condition::INSERT: + withKeyword("ON").withKeyword("INSERT"); + break; + case SqliteForeignKey::Condition::DELETE: + withKeyword("ON").withKeyword("DELETE"); + break; + case SqliteForeignKey::Condition::MATCH: + withKeyword("MATCH").withId(cond->name); + return; + } + formatReaction(); +} + +void FormatForeignKeyCondition::formatReaction() +{ + switch (cond->reaction) + { + case SqliteForeignKey::Condition::SET_NULL: + withKeyword("SET").withKeyword("NULL"); + break; + case SqliteForeignKey::Condition::SET_DEFAULT: + withKeyword("SET").withKeyword("DEFAULT"); + break; + case SqliteForeignKey::Condition::CASCADE: + withKeyword("CASCADE"); + break; + case SqliteForeignKey::Condition::RESTRICT: + withKeyword("RESTRICT"); + break; + case SqliteForeignKey::Condition::NO_ACTION: + withKeyword("NO").withKeyword("ACTION"); + break; + } +} diff --git a/Plugins/SqlEnterpriseFormatter/formatforeignkey.h b/Plugins/SqlEnterpriseFormatter/formatforeignkey.h new file mode 100644 index 0000000..771fdba --- /dev/null +++ b/Plugins/SqlEnterpriseFormatter/formatforeignkey.h @@ -0,0 +1,33 @@ +#ifndef FORMATFOREIGNKEY_H +#define FORMATFOREIGNKEY_H + +#include "formatstatement.h" +#include "parser/ast/sqliteforeignkey.h" + +class FormatForeignKey : public FormatStatement +{ + public: + FormatForeignKey(SqliteForeignKey* fk); + + protected: + void formatInternal(); + + private: + SqliteForeignKey* fk = nullptr; +}; + +class FormatForeignKeyCondition : public FormatStatement +{ + public: + FormatForeignKeyCondition(SqliteForeignKey::Condition* cond); + + protected: + void formatInternal(); + + private: + void formatReaction(); + + SqliteForeignKey::Condition* cond = nullptr; +}; + +#endif // FORMATFOREIGNKEY_H diff --git a/Plugins/SqlEnterpriseFormatter/formatindexedcolumn.cpp b/Plugins/SqlEnterpriseFormatter/formatindexedcolumn.cpp new file mode 100644 index 0000000..eef8309 --- /dev/null +++ b/Plugins/SqlEnterpriseFormatter/formatindexedcolumn.cpp @@ -0,0 +1,17 @@ +#include "formatindexedcolumn.h" +#include "parser/ast/sqliteindexedcolumn.h" + +FormatIndexedColumn::FormatIndexedColumn(SqliteIndexedColumn* idxCol) : + idxCol(idxCol) +{ +} + + +void FormatIndexedColumn::formatInternal() +{ + withId(idxCol->name); + if (!idxCol->collate.isNull()) + withKeyword("COLLATE").withId(idxCol->collate); + + withSortOrder(idxCol->sortOrder); +} diff --git a/Plugins/SqlEnterpriseFormatter/formatindexedcolumn.h b/Plugins/SqlEnterpriseFormatter/formatindexedcolumn.h new file mode 100644 index 0000000..4bfb7dd --- /dev/null +++ b/Plugins/SqlEnterpriseFormatter/formatindexedcolumn.h @@ -0,0 +1,20 @@ +#ifndef FORMATINDEXEDCOLUMN_H +#define FORMATINDEXEDCOLUMN_H + +#include "formatstatement.h" + +class SqliteIndexedColumn; + +class FormatIndexedColumn : public FormatStatement +{ + public: + FormatIndexedColumn(SqliteIndexedColumn* idxCol); + + protected: + void formatInternal(); + + private: + SqliteIndexedColumn* idxCol = nullptr; +}; + +#endif // FORMATINDEXEDCOLUMN_H diff --git a/Plugins/SqlEnterpriseFormatter/formatinsert.cpp b/Plugins/SqlEnterpriseFormatter/formatinsert.cpp new file mode 100644 index 0000000..1ff0535 --- /dev/null +++ b/Plugins/SqlEnterpriseFormatter/formatinsert.cpp @@ -0,0 +1,54 @@ +#include "formatinsert.h" +#include "parser/ast/sqliteselect.h" +#include "parser/ast/sqliteinsert.h" +#include "formatwith.h" + +FormatInsert::FormatInsert(SqliteInsert* insert) : + insert(insert) +{ +} + +void FormatInsert::formatInternal() +{ + if (insert->replaceKw) + { + withStatement(insert->with); + withKeyword("REPLACE"); + } + else + { + withStatement(insert->with); + withKeyword("INSERT"); + if (insert->onConflict != SqliteConflictAlgo::null) + withKeyword("OR").withKeyword(sqliteConflictAlgo(insert->onConflict)); + } + + withKeyword("INTO"); + + if (!insert->database.isNull()) + withId(insert->database); + + withId(insert->table); + + if (insert->defaultValuesKw) + { + withKeyword("DEFAULT").withKeyword("VALUES"); + } + else + { + markAndKeepIndent("insertCols"); + if (insert->columnNames.size() > 0) + withParDefLeft().withIdList(insert->columnNames).withParDefRight(); + + if (insert->select) + { + withStatement(insert->select); + } + else if (dialect == Dialect::Sqlite2) // Sqlite2 uses classic single row values + { + withKeyword("VALUES").withParDefLeft().withStatementList(insert->values).withParDefRight(); + } + withDecrIndent(); + } + withSemicolon(); +} diff --git a/Plugins/SqlEnterpriseFormatter/formatinsert.h b/Plugins/SqlEnterpriseFormatter/formatinsert.h new file mode 100644 index 0000000..1d85c6a --- /dev/null +++ b/Plugins/SqlEnterpriseFormatter/formatinsert.h @@ -0,0 +1,20 @@ +#ifndef FORMATINSERT_H +#define FORMATINSERT_H + +#include "formatstatement.h" + +class SqliteInsert; + +class FormatInsert : public FormatStatement +{ + public: + FormatInsert(SqliteInsert* insert); + + protected: + void formatInternal(); + + private: + SqliteInsert* insert = nullptr; +}; + +#endif // FORMATINSERT_H diff --git a/Plugins/SqlEnterpriseFormatter/formatlimit.cpp b/Plugins/SqlEnterpriseFormatter/formatlimit.cpp new file mode 100644 index 0000000..7b4b4d6 --- /dev/null +++ b/Plugins/SqlEnterpriseFormatter/formatlimit.cpp @@ -0,0 +1,24 @@ +#include "formatlimit.h" +#include "parser/ast/sqlitelimit.h" +#include "parser/ast/sqliteexpr.h" + +FormatLimit::FormatLimit(SqliteLimit *limit) : + limit(limit) +{ +} + +void FormatLimit::formatInternal() +{ + if (limit->limit) + withStatement(limit->limit); + + if (limit->offset) + { + if (limit->offsetKw) + withKeyword("OFFSET"); + else + withCommaOper(); + + withStatement(limit->offset); + } +} diff --git a/Plugins/SqlEnterpriseFormatter/formatlimit.h b/Plugins/SqlEnterpriseFormatter/formatlimit.h new file mode 100644 index 0000000..bfd99f1 --- /dev/null +++ b/Plugins/SqlEnterpriseFormatter/formatlimit.h @@ -0,0 +1,19 @@ +#ifndef FORMATLIMIT_H +#define FORMATLIMIT_H + +#include "formatstatement.h" + +class SqliteLimit; + +class FormatLimit : public FormatStatement +{ + public: + FormatLimit(SqliteLimit* limit); + + void formatInternal(); + + private: + SqliteLimit *limit = nullptr; +}; + +#endif // FORMATLIMIT_H diff --git a/Plugins/SqlEnterpriseFormatter/formatorderby.cpp b/Plugins/SqlEnterpriseFormatter/formatorderby.cpp new file mode 100644 index 0000000..d7b2def --- /dev/null +++ b/Plugins/SqlEnterpriseFormatter/formatorderby.cpp @@ -0,0 +1,15 @@ +#include "formatorderby.h" +#include "parser/ast/sqliteorderby.h" +#include "parser/ast/sqliteexpr.h" + +FormatOrderBy::FormatOrderBy(SqliteOrderBy* orderBy) : + orderBy(orderBy) +{ +} + +void FormatOrderBy::formatInternal() +{ + withStatement(orderBy->expr); + if (orderBy->order != SqliteSortOrder::null) + withKeyword(sqliteSortOrder(orderBy->order)); +} diff --git a/Plugins/SqlEnterpriseFormatter/formatorderby.h b/Plugins/SqlEnterpriseFormatter/formatorderby.h new file mode 100644 index 0000000..ce380e5 --- /dev/null +++ b/Plugins/SqlEnterpriseFormatter/formatorderby.h @@ -0,0 +1,19 @@ +#ifndef FORMATORDERBY_H +#define FORMATORDERBY_H + +#include "formatstatement.h" + +class SqliteOrderBy; + +class FormatOrderBy : public FormatStatement +{ + public: + FormatOrderBy(SqliteOrderBy *orderBy); + + void formatInternal(); + + private: + SqliteOrderBy *orderBy = nullptr; +}; + +#endif // FORMATORDERBY_H diff --git a/Plugins/SqlEnterpriseFormatter/formatpragma.cpp b/Plugins/SqlEnterpriseFormatter/formatpragma.cpp new file mode 100644 index 0000000..0b6491a --- /dev/null +++ b/Plugins/SqlEnterpriseFormatter/formatpragma.cpp @@ -0,0 +1,24 @@ +#include "formatpragma.h" +#include "parser/ast/sqlitepragma.h" + +FormatPragma::FormatPragma(SqlitePragma* pragma) : + pragma(pragma) +{ +} + +void FormatPragma::formatInternal() +{ + withKeyword("PRAGMA"); + + if (!pragma->database.isNull()) + withId(pragma->database).withIdDot(); + + withId(pragma->pragmaName); + + if (pragma->equalsOp) + withOperator("=").withLiteral(pragma->value); + else if (pragma->parenthesis) + withParExprLeft().withLiteral(pragma->value).withParExprRight(); + + withSemicolon(); +} diff --git a/Plugins/SqlEnterpriseFormatter/formatpragma.h b/Plugins/SqlEnterpriseFormatter/formatpragma.h new file mode 100644 index 0000000..c720b35 --- /dev/null +++ b/Plugins/SqlEnterpriseFormatter/formatpragma.h @@ -0,0 +1,20 @@ +#ifndef FORMATPRAGMA_H +#define FORMATPRAGMA_H + +#include "formatstatement.h" + +class SqlitePragma; + +class FormatPragma : public FormatStatement +{ + public: + FormatPragma(SqlitePragma* pragma); + + protected: + void formatInternal(); + + private: + SqlitePragma* pragma = nullptr; +}; + +#endif // FORMATPRAGMA_H diff --git a/Plugins/SqlEnterpriseFormatter/formatraise.cpp b/Plugins/SqlEnterpriseFormatter/formatraise.cpp new file mode 100644 index 0000000..be3787e --- /dev/null +++ b/Plugins/SqlEnterpriseFormatter/formatraise.cpp @@ -0,0 +1,16 @@ +#include "formatraise.h" +#include "parser/ast/sqliteraise.h" + +FormatRaise::FormatRaise(SqliteRaise *raise) : + raise(raise) +{ +} + +void FormatRaise::formatInternal() +{ + withKeyword("RAISE").withParFuncLeft().withKeyword(SqliteRaise::raiseType(raise->type)); + if (raise->type != SqliteRaise::Type::IGNORE) + withCommaOper().withString(raise->message); + + withParFuncRight(); +} diff --git a/Plugins/SqlEnterpriseFormatter/formatraise.h b/Plugins/SqlEnterpriseFormatter/formatraise.h new file mode 100644 index 0000000..7292fba --- /dev/null +++ b/Plugins/SqlEnterpriseFormatter/formatraise.h @@ -0,0 +1,20 @@ +#ifndef FORMATRAISE_H +#define FORMATRAISE_H + +#include "formatstatement.h" + +class SqliteRaise; + +class FormatRaise : public FormatStatement +{ + public: + FormatRaise(SqliteRaise* raise); + + protected: + void formatInternal(); + + private: + SqliteRaise* raise = nullptr; +}; + +#endif // FORMATRAISE_H diff --git a/Plugins/SqlEnterpriseFormatter/formatreindex.cpp b/Plugins/SqlEnterpriseFormatter/formatreindex.cpp new file mode 100644 index 0000000..441032e --- /dev/null +++ b/Plugins/SqlEnterpriseFormatter/formatreindex.cpp @@ -0,0 +1,16 @@ +#include "formatreindex.h" +#include "parser/ast/sqlitereindex.h" + +FormatReindex::FormatReindex(SqliteReindex* reindex) : + reindex(reindex) +{ +} + +void FormatReindex::formatInternal() +{ + withKeyword("REINDEX"); + if (!reindex->database.isNull()) + withId(reindex->database).withIdDot(); + + withId(reindex->table).withSemicolon(); +} diff --git a/Plugins/SqlEnterpriseFormatter/formatreindex.h b/Plugins/SqlEnterpriseFormatter/formatreindex.h new file mode 100644 index 0000000..018d422 --- /dev/null +++ b/Plugins/SqlEnterpriseFormatter/formatreindex.h @@ -0,0 +1,20 @@ +#ifndef FORMATREINDEX_H +#define FORMATREINDEX_H + +#include "formatstatement.h" + +class SqliteReindex; + +class FormatReindex : public FormatStatement +{ + public: + FormatReindex(SqliteReindex* reindex); + + protected: + void formatInternal(); + + private: + SqliteReindex* reindex = nullptr; +}; + +#endif // FORMATREINDEX_H diff --git a/Plugins/SqlEnterpriseFormatter/formatrelease.cpp b/Plugins/SqlEnterpriseFormatter/formatrelease.cpp new file mode 100644 index 0000000..52c0b24 --- /dev/null +++ b/Plugins/SqlEnterpriseFormatter/formatrelease.cpp @@ -0,0 +1,16 @@ +#include "formatrelease.h" +#include "parser/ast/sqliterelease.h" + +FormatRelease::FormatRelease(SqliteRelease* release) : + release(release) +{ +} + +void FormatRelease::formatInternal() +{ + withKeyword("RELEASE"); + if (release->savepointKw) + withKeyword("SAVEPOINT"); + + withId(release->name).withSemicolon(); +} diff --git a/Plugins/SqlEnterpriseFormatter/formatrelease.h b/Plugins/SqlEnterpriseFormatter/formatrelease.h new file mode 100644 index 0000000..3df3d1a --- /dev/null +++ b/Plugins/SqlEnterpriseFormatter/formatrelease.h @@ -0,0 +1,20 @@ +#ifndef FORMATRELEASE_H +#define FORMATRELEASE_H + +#include "formatstatement.h" + +class SqliteRelease; + +class FormatRelease : public FormatStatement +{ + public: + FormatRelease(SqliteRelease* release); + + protected: + void formatInternal(); + + private: + SqliteRelease* release = nullptr; +}; + +#endif // FORMATRELEASE_H diff --git a/Plugins/SqlEnterpriseFormatter/formatrollback.cpp b/Plugins/SqlEnterpriseFormatter/formatrollback.cpp new file mode 100644 index 0000000..c55f5cc --- /dev/null +++ b/Plugins/SqlEnterpriseFormatter/formatrollback.cpp @@ -0,0 +1,24 @@ +#include "formatrollback.h" +#include "parser/ast/sqliterollback.h" + +FormatRollback::FormatRollback(SqliteRollback* rollback) : + rollback(rollback) +{ +} + +void FormatRollback::formatInternal() +{ + withKeyword("ROLLBACK"); + if (rollback->transactionKw) + withKeyword("TRANSACTION"); + + if (!rollback->name.isNull()) + { + withKeyword("TO"); + if (rollback->savepointKw) + withKeyword("SAVEPOINT"); + + withId(rollback->name); + } + withSemicolon(); +} diff --git a/Plugins/SqlEnterpriseFormatter/formatrollback.h b/Plugins/SqlEnterpriseFormatter/formatrollback.h new file mode 100644 index 0000000..4a69e14 --- /dev/null +++ b/Plugins/SqlEnterpriseFormatter/formatrollback.h @@ -0,0 +1,20 @@ +#ifndef FORMATROLLBACK_H +#define FORMATROLLBACK_H + +#include "formatstatement.h" + +class SqliteRollback; + +class FormatRollback : public FormatStatement +{ + public: + FormatRollback(SqliteRollback* rollback); + + protected: + void formatInternal(); + + private: + SqliteRollback* rollback = nullptr; +}; + +#endif // FORMATROLLBACK_H diff --git a/Plugins/SqlEnterpriseFormatter/formatsavepoint.cpp b/Plugins/SqlEnterpriseFormatter/formatsavepoint.cpp new file mode 100644 index 0000000..3f34679 --- /dev/null +++ b/Plugins/SqlEnterpriseFormatter/formatsavepoint.cpp @@ -0,0 +1,12 @@ +#include "formatsavepoint.h" +#include "parser/ast/sqlitesavepoint.h" + +FormatSavepoint::FormatSavepoint(SqliteSavepoint* savepoint) : + savepoint(savepoint) +{ +} + +void FormatSavepoint::formatInternal() +{ + withKeyword("SAVEPOINT").withId(savepoint->name).withSemicolon(); +} diff --git a/Plugins/SqlEnterpriseFormatter/formatsavepoint.h b/Plugins/SqlEnterpriseFormatter/formatsavepoint.h new file mode 100644 index 0000000..f9f31c1 --- /dev/null +++ b/Plugins/SqlEnterpriseFormatter/formatsavepoint.h @@ -0,0 +1,20 @@ +#ifndef FORMATSAVEPOINT_H +#define FORMATSAVEPOINT_H + +#include "formatstatement.h" + +class SqliteSavepoint; + +class FormatSavepoint : public FormatStatement +{ + public: + FormatSavepoint(SqliteSavepoint* savepoint); + + protected: + void formatInternal(); + + private: + SqliteSavepoint* savepoint = nullptr; +}; + +#endif // FORMATSAVEPOINT_H diff --git a/Plugins/SqlEnterpriseFormatter/formatselect.cpp b/Plugins/SqlEnterpriseFormatter/formatselect.cpp new file mode 100644 index 0000000..50aa8c2 --- /dev/null +++ b/Plugins/SqlEnterpriseFormatter/formatselect.cpp @@ -0,0 +1,261 @@ +#include "formatselect.h" +#include "formatwith.h" +#include "parser/ast/sqlitewith.h" + +FormatSelect::FormatSelect(SqliteSelect* select) : + select(select) +{ +} + +void FormatSelect::formatInternal() +{ + markKeywordLineUp("SELECT"); + + if (select->with) + withStatement(select->with); + + for (SqliteSelect::Core* core : select->coreSelects) + { + switch (core->compoundOp) + { + case SqliteSelect::CompoundOperator::UNION: + withNewLine().withKeyword("UNION").withNewLine(); + break; + case SqliteSelect::CompoundOperator::UNION_ALL: + withNewLine().withKeyword("UNION ALL").withNewLine(); + break; + case SqliteSelect::CompoundOperator::INTERSECT: + withNewLine().withKeyword("INTERSECT").withNewLine(); + break; + case SqliteSelect::CompoundOperator::EXCEPT: + withNewLine().withKeyword("EXCEPT").withNewLine(); + break; + case SqliteSelect::CompoundOperator::null: + break; + } + withStatement(core); + } + + if (select->parentStatement() == nullptr) // it's not a subselect, it's top-level select + withSemicolon(); +} + +FormatSelectCore::FormatSelectCore(SqliteSelect::Core *core) : + core(core) +{ +} + +void FormatSelectCore::formatInternal() +{ + markKeywordLineUp("SELECT", "selectCore"); + + if (core->valuesMode) + { + withKeyword("VALUES").withParDefLeft().withStatementList(core->resultColumns).withParDefRight(); + return; + } + + withKeyword("SELECT"); + if (core->distinctKw) + withKeyword("DISTINCT"); + else if (core->allKw) + withKeyword("ALL"); + + withStatementList(core->resultColumns, "resultColumns"); + + if (core->from) + withNewLine().withLinedUpKeyword("FROM", "selectCore").withStatement(core->from, "source"); + + if (core->where) + withNewLine().withLinedUpKeyword("WHERE", "selectCore").withStatement(core->where, "conditions"); + + if (core->groupBy.size() > 0) + withNewLine().withLinedUpKeyword("GROUP", "selectCore").withKeyword("BY").withStatementList(core->groupBy, "grouping"); + + if (core->having) + withNewLine().withLinedUpKeyword("HAVING", "selectCore").withStatement(core->having, "having"); + + if (core->orderBy.size() > 0) + withNewLine().withLinedUpKeyword("ORDER", "selectCore").withKeyword("BY").withStatementList(core->orderBy, "order"); + + if (core->limit) + withNewLine().withLinedUpKeyword("LIMIT", "selectCore").withStatement(core->limit, "limit"); +} + +FormatSelectCoreResultColumn::FormatSelectCoreResultColumn(SqliteSelect::Core::ResultColumn *resCol) : + resCol(resCol) +{ +} + +void FormatSelectCoreResultColumn::formatInternal() +{ + if (resCol->star) + { + if (!resCol->table.isNull()) + { + withId(resCol->table).withIdDot(); + } + withStar(); + } + else + { + withStatement(resCol->expr, "column"); + if (!resCol->alias.isNull()) + { + withIncrIndent("column"); + if (resCol->asKw) + withKeyword("AS"); + + withId(resCol->alias).withDecrIndent(); + } + } +} + +FormatSelectCoreSingleSource::FormatSelectCoreSingleSource(SqliteSelect::Core::SingleSource* singleSource) : + singleSource(singleSource) +{ +} + +void FormatSelectCoreSingleSource::formatInternal() +{ + if (!singleSource->table.isNull()) + { + if (!singleSource->database.isNull()) + withId(singleSource->database).withIdDot(); + + withId(singleSource->table); + + if (!singleSource->alias.isNull()) + { + if (singleSource->asKw) + withKeyword("AS"); + + withId(singleSource->alias); + + if (singleSource->indexedByKw) + withKeyword("INDEXED").withKeyword("BY").withId(singleSource->indexedBy); + else if (singleSource->notIndexedKw) + withKeyword("NOT").withKeyword("INDEXED"); + } + } + else if (singleSource->select) + { + withParDefLeft().withStatement(singleSource->select).withParDefRight(); + if (!singleSource->alias.isNull()) + { + if (singleSource->asKw) + withKeyword("AS"); + + withId(singleSource->alias); + } + } + else + { + withParDefLeft().withStatement(singleSource->joinSource).withParDefRight(); + } +} + +FormatSelectCoreJoinOp::FormatSelectCoreJoinOp(SqliteSelect::Core::JoinOp* joinOp) : + joinOp(joinOp) +{ +} + +void FormatSelectCoreJoinOp::formatInternal() +{ + if (joinOp->comma) + { + withListComma(); + return; + } + + withNewLine(); + QStringList keywords; + switch (dialect) + { + case Dialect::Sqlite3: + { + if (joinOp->naturalKw) + keywords << "NATURAL"; + + if (joinOp->leftKw) + { + keywords << "LEFT"; + if (joinOp->outerKw) + keywords << "OUTER"; + } + else if (joinOp->innerKw) + keywords << "INNER"; + else if (joinOp->crossKw) + keywords << "CROSS"; + + keywords << "JOIN"; + break; + } + case Dialect::Sqlite2: + { + if (joinOp->naturalKw) + keywords << "NATURAL"; + + if (joinOp->leftKw) + keywords << "LEFT"; + else if (joinOp->rightKw) + keywords << "RIGHT"; + else if (joinOp->fullKw) + keywords << "FULL"; + + if (joinOp->innerKw) + keywords << "INNER"; + else if (joinOp->crossKw) + keywords << "CROSS"; + else if (joinOp->outerKw) + keywords << "OUTER"; + + keywords << "JOIN"; + break; + } + } + + if (keywords.size() == 0) + return; + + for (const QString& kw : keywords) + withKeyword(kw); + + if (cfg->SqlEnterpriseFormatter.NlAfterJoinStmt.get()) + withNewLine(); +} + +FormatSelectCoreJoinConstraint::FormatSelectCoreJoinConstraint(SqliteSelect::Core::JoinConstraint* joinConstr) : + joinConstr(joinConstr) +{ +} + +void FormatSelectCoreJoinConstraint::formatInternal() +{ + if (joinConstr->expr) + withKeyword("ON").withStatement(joinConstr->expr, "joinConstr"); + else + withKeyword("USING").withParDefLeft().withIdList(joinConstr->columnNames).withParDefRight(); +} + +FormatSelectCoreJoinSourceOther::FormatSelectCoreJoinSourceOther(SqliteSelect::Core::JoinSourceOther* joinSourceOther) : + joinSourceOther(joinSourceOther) +{ +} + +void FormatSelectCoreJoinSourceOther::formatInternal() +{ + withStatement(joinSourceOther->joinOp).withStatement(joinSourceOther->singleSource).withStatement(joinSourceOther->joinConstraint); +} + + +FormatSelectCoreJoinSource::FormatSelectCoreJoinSource(SqliteSelect::Core::JoinSource* joinSource) : + joinSource(joinSource) +{ +} + +void FormatSelectCoreJoinSource::formatInternal() +{ +// withStatement(joinSource->singleSource).withStatementList(joinSource->otherSources, "otherSources", ListSeparator::NONE); + withStatement(joinSource->singleSource).withStatementList(joinSource->otherSources, QString(), ListSeparator::NONE); +} diff --git a/Plugins/SqlEnterpriseFormatter/formatselect.h b/Plugins/SqlEnterpriseFormatter/formatselect.h new file mode 100644 index 0000000..8cc4f5f --- /dev/null +++ b/Plugins/SqlEnterpriseFormatter/formatselect.h @@ -0,0 +1,103 @@ +#ifndef FORMATSELECT_H +#define FORMATSELECT_H + +#include "formatstatement.h" +#include "parser/ast/sqliteselect.h" + +class FormatSelect : public FormatStatement +{ + public: + FormatSelect(SqliteSelect *select); + + protected: + void formatInternal(); + + private: + SqliteSelect* select = nullptr; +}; + +class FormatSelectCore : public FormatStatement +{ + public: + FormatSelectCore(SqliteSelect::Core *core); + + protected: + void formatInternal(); + + private: + SqliteSelect::Core* core = nullptr; +}; + +class FormatSelectCoreResultColumn : public FormatStatement +{ + public: + FormatSelectCoreResultColumn(SqliteSelect::Core::ResultColumn *resCol); + + protected: + void formatInternal(); + + private: + SqliteSelect::Core::ResultColumn *resCol = nullptr; +}; + +class FormatSelectCoreSingleSource : public FormatStatement +{ + public: + FormatSelectCoreSingleSource(SqliteSelect::Core::SingleSource *singleSource); + + protected: + void formatInternal(); + + private: + SqliteSelect::Core::SingleSource *singleSource = nullptr; +}; + +class FormatSelectCoreJoinOp : public FormatStatement +{ + public: + FormatSelectCoreJoinOp(SqliteSelect::Core::JoinOp *joinOp); + + protected: + void formatInternal(); + + private: + SqliteSelect::Core::JoinOp *joinOp = nullptr; +}; + +class FormatSelectCoreJoinConstraint : public FormatStatement +{ + public: + FormatSelectCoreJoinConstraint(SqliteSelect::Core::JoinConstraint *joinConstr); + + protected: + void formatInternal(); + + private: + SqliteSelect::Core::JoinConstraint *joinConstr = nullptr; +}; + +class FormatSelectCoreJoinSourceOther : public FormatStatement +{ + public: + FormatSelectCoreJoinSourceOther(SqliteSelect::Core::JoinSourceOther *joinSourceOther); + + protected: + void formatInternal(); + + private: + SqliteSelect::Core::JoinSourceOther *joinSourceOther = nullptr; +}; + +class FormatSelectCoreJoinSource : public FormatStatement +{ + public: + FormatSelectCoreJoinSource(SqliteSelect::Core::JoinSource *joinSource); + + protected: + void formatInternal(); + + private: + SqliteSelect::Core::JoinSource *joinSource = nullptr; +}; + +#endif // FORMATSELECT_H diff --git a/Plugins/SqlEnterpriseFormatter/formatstatement.cpp b/Plugins/SqlEnterpriseFormatter/formatstatement.cpp new file mode 100644 index 0000000..04c6aae --- /dev/null +++ b/Plugins/SqlEnterpriseFormatter/formatstatement.cpp @@ -0,0 +1,1064 @@ +#include "formatstatement.h" +#include "formatselect.h" +#include "formatexpr.h" +#include "formatlimit.h" +#include "formatraise.h" +#include "formatwith.h" +#include "formatcreatetable.h" +#include "formatcreatevirtualtable.h" +#include "formatforeignkey.h" +#include "formatcolumntype.h" +#include "formatindexedcolumn.h" +#include "formatinsert.h" +#include "formatempty.h" +#include "formataltertable.h" +#include "formatanalyze.h" +#include "formatattach.h" +#include "formatbegintrans.h" +#include "formatcommittrans.h" +#include "formatcopy.h" +#include "formatcreateindex.h" +#include "formatcreatetrigger.h" +#include "formatdelete.h" +#include "formatupdate.h" +#include "formatdropindex.h" +#include "formatdroptable.h" +#include "formatdroptrigger.h" +#include "formatdropview.h" +#include "formatorderby.h" +#include "parser/ast/sqliteselect.h" +#include "parser/ast/sqliteexpr.h" +#include "parser/ast/sqlitelimit.h" +#include "parser/ast/sqliteraise.h" +#include "parser/ast/sqlitewith.h" +#include "parser/ast/sqlitecreatetable.h" +#include "parser/ast/sqlitecreatevirtualtable.h" +#include "parser/ast/sqliteforeignkey.h" +#include "parser/ast/sqlitecolumntype.h" +#include "parser/ast/sqliteindexedcolumn.h" +#include "parser/ast/sqliteinsert.h" +#include "parser/ast/sqliteemptyquery.h" +#include "parser/ast/sqlitealtertable.h" +#include "parser/ast/sqliteanalyze.h" +#include "parser/ast/sqliteattach.h" +#include "parser/ast/sqlitebegintrans.h" +#include "parser/ast/sqlitecommittrans.h" +#include "parser/ast/sqlitecopy.h" +#include "parser/ast/sqlitecreateindex.h" +#include "parser/ast/sqlitecreatetrigger.h" +#include "parser/ast/sqliteupdate.h" +#include "parser/ast/sqlitedelete.h" +#include "parser/ast/sqlitedropindex.h" +#include "parser/ast/sqlitedroptable.h" +#include "parser/ast/sqlitedroptrigger.h" +#include "parser/ast/sqlitedropview.h" +#include "parser/ast/sqliteorderby.h" +#include "sqlenterpriseformatter.h" +#include "common/utils_sql.h" +#include "common/global.h" +#include <QRegularExpression> +#include <QDebug> + +#define FORMATTER_FACTORY_ENTRY(query, Type, FormatType) \ + if (dynamic_cast<Type*>(query)) \ + return new FormatType(dynamic_cast<Type*>(query)) + +const QString FormatStatement::SPACE = " "; +const QString FormatStatement::NEWLINE = "\n"; +qint64 FormatStatement::nameSeq = 0; + +FormatStatement::FormatStatement() +{ + static_qstring(nameTpl, "statement_%1"); + + indents.push(0); + statementName = nameTpl.arg(QString::number(nameSeq++)); +} + +FormatStatement::~FormatStatement() +{ + cleanup(); +} + +QString FormatStatement::format() +{ + buildTokens(); + return detokenize() + NEWLINE; // extra space when formatting multiple top level (not in CREATE TRIGGER) queries +} + +void FormatStatement::setSelectedWrapper(NameWrapper wrapper) +{ + this->wrapper = wrapper; +} + +void FormatStatement::setConfig(Cfg::SqlEnterpriseFormatterConfig* cfg) +{ + this->cfg = cfg; +} + +void FormatStatement::buildTokens() +{ + cleanup(); + resetInternal(); + formatInternal(); +} + +FormatStatement *FormatStatement::forQuery(SqliteStatement *query) +{ + FormatStatement* stmt = nullptr; + FORMATTER_FACTORY_ENTRY(query, SqliteSelect, FormatSelect); + FORMATTER_FACTORY_ENTRY(query, SqliteSelect::Core, FormatSelectCore); + FORMATTER_FACTORY_ENTRY(query, SqliteSelect::Core::ResultColumn, FormatSelectCoreResultColumn); + FORMATTER_FACTORY_ENTRY(query, SqliteSelect::Core::JoinConstraint, FormatSelectCoreJoinConstraint); + FORMATTER_FACTORY_ENTRY(query, SqliteSelect::Core::JoinOp, FormatSelectCoreJoinOp); + FORMATTER_FACTORY_ENTRY(query, SqliteSelect::Core::JoinSource, FormatSelectCoreJoinSource); + FORMATTER_FACTORY_ENTRY(query, SqliteSelect::Core::JoinSourceOther, FormatSelectCoreJoinSourceOther); + FORMATTER_FACTORY_ENTRY(query, SqliteSelect::Core::SingleSource, FormatSelectCoreSingleSource); + FORMATTER_FACTORY_ENTRY(query, SqliteExpr, FormatExpr); + FORMATTER_FACTORY_ENTRY(query, SqliteWith, FormatWith); + FORMATTER_FACTORY_ENTRY(query, SqliteWith::CommonTableExpression, FormatWithCommonTableExpression); + FORMATTER_FACTORY_ENTRY(query, SqliteRaise, FormatRaise); + FORMATTER_FACTORY_ENTRY(query, SqliteLimit, FormatLimit); + FORMATTER_FACTORY_ENTRY(query, SqliteCreateTable, FormatCreateTable); + FORMATTER_FACTORY_ENTRY(query, SqliteCreateTable::Column, FormatCreateTableColumn); + FORMATTER_FACTORY_ENTRY(query, SqliteCreateTable::Column::Constraint, FormatCreateTableColumnConstraint); + FORMATTER_FACTORY_ENTRY(query, SqliteCreateTable::Constraint, FormatCreateTableConstraint); + FORMATTER_FACTORY_ENTRY(query, SqliteForeignKey, FormatForeignKey); + FORMATTER_FACTORY_ENTRY(query, SqliteForeignKey::Condition, FormatForeignKeyCondition); + FORMATTER_FACTORY_ENTRY(query, SqliteColumnType, FormatColumnType); + FORMATTER_FACTORY_ENTRY(query, SqliteIndexedColumn, FormatIndexedColumn); + FORMATTER_FACTORY_ENTRY(query, SqliteInsert, FormatInsert); + FORMATTER_FACTORY_ENTRY(query, SqliteEmptyQuery, FormatEmpty); + FORMATTER_FACTORY_ENTRY(query, SqliteAlterTable, FormatAlterTable); + FORMATTER_FACTORY_ENTRY(query, SqliteAnalyze, FormatAnalyze); + FORMATTER_FACTORY_ENTRY(query, SqliteAttach, FormatAttach); + FORMATTER_FACTORY_ENTRY(query, SqliteBeginTrans, FormatBeginTrans); + FORMATTER_FACTORY_ENTRY(query, SqliteCommitTrans, FormatCommitTrans); + FORMATTER_FACTORY_ENTRY(query, SqliteCopy, FormatCopy); + FORMATTER_FACTORY_ENTRY(query, SqliteCreateVirtualTable, FormatCreateVirtualTable); + FORMATTER_FACTORY_ENTRY(query, SqliteCreateIndex, FormatCreateIndex); + FORMATTER_FACTORY_ENTRY(query, SqliteCreateTrigger, FormatCreateTrigger); + FORMATTER_FACTORY_ENTRY(query, SqliteCreateTrigger::Event, FormatCreateTriggerEvent); + FORMATTER_FACTORY_ENTRY(query, SqliteUpdate, FormatUpdate); + FORMATTER_FACTORY_ENTRY(query, SqliteDelete, FormatDelete); + FORMATTER_FACTORY_ENTRY(query, SqliteDropIndex, FormatDropIndex); + FORMATTER_FACTORY_ENTRY(query, SqliteDropTable, FormatDropTable); + FORMATTER_FACTORY_ENTRY(query, SqliteDropTrigger, FormatDropTrigger); + FORMATTER_FACTORY_ENTRY(query, SqliteDropView, FormatDropView); + FORMATTER_FACTORY_ENTRY(query, SqliteOrderBy, FormatOrderBy); + + if (stmt) + stmt->dialect = query->dialect; + else if (query) + qWarning() << "Unhandled query passed to enterprise formatter!"; + else + qWarning() << "Null query passed to enterprise formatter!"; + + return stmt; +} + +void FormatStatement::resetInternal() +{ +} + +FormatStatement& FormatStatement::withKeyword(const QString& kw) +{ + withToken(FormatToken::KEYWORD, kw); + return *this; +} + +FormatStatement& FormatStatement::withLinedUpKeyword(const QString& kw, const QString& lineUpName) +{ + withToken(FormatToken::LINED_UP_KEYWORD, kw, getFinalLineUpName(lineUpName)); + return *this; +} + +FormatStatement& FormatStatement::withId(const QString& id) +{ + withToken(FormatToken::ID, id); + return *this; +} + +FormatStatement& FormatStatement::withOperator(const QString& oper) +{ + withToken(FormatToken::OPERATOR, oper); + return *this; +} + +FormatStatement&FormatStatement::withStringOrId(const QString& id) +{ + withToken(FormatToken::STRING_OR_ID, id); + return *this; +} + +FormatStatement& FormatStatement::withIdDot() +{ + withToken(FormatToken::ID_DOT, "."); + return *this; +} + +FormatStatement& FormatStatement::withStar() +{ + withToken(FormatToken::STAR, "*"); + return *this; +} + +FormatStatement& FormatStatement::withFloat(double value) +{ + withToken(FormatToken::FLOAT, value); + return *this; +} + +FormatStatement& FormatStatement::withInteger(qint64 value) +{ + withToken(FormatToken::INTEGER, value); + return *this; +} + +FormatStatement& FormatStatement::withString(const QString& value) +{ + withToken(FormatToken::STRING, value); + return *this; +} + +FormatStatement& FormatStatement::withBlob(const QString& value) +{ + withToken(FormatToken::BLOB, value); + return *this; +} + +FormatStatement& FormatStatement::withBindParam(const QString& name) +{ + withToken(FormatToken::BIND_PARAM, name); + return *this; +} + +FormatStatement& FormatStatement::withParDefLeft() +{ + withToken(FormatToken::PAR_DEF_LEFT, "("); + return *this; +} + +FormatStatement& FormatStatement::withParDefRight() +{ + withToken(FormatToken::PAR_DEF_RIGHT, ")"); + return *this; +} + +FormatStatement& FormatStatement::withParExprLeft() +{ + withToken(FormatToken::PAR_EXPR_LEFT, "("); + return *this; +} + +FormatStatement& FormatStatement::withParExprRight() +{ + withToken(FormatToken::PAR_EXPR_RIGHT, ")"); + return *this; +} + +FormatStatement& FormatStatement::withParFuncLeft() +{ + withToken(FormatToken::PAR_FUNC_LEFT, "("); + return *this; +} + +FormatStatement& FormatStatement::withParFuncRight() +{ + withToken(FormatToken::PAR_FUNC_RIGHT, ")"); + return *this; +} + +FormatStatement& FormatStatement::withSemicolon() +{ + FormatToken* lastRealToken = getLastRealToken(); + if ((lastRealToken && lastRealToken->type != FormatToken::SEMICOLON) || tokens.size() == 0) + withToken(FormatToken::SEMICOLON, ";"); + + return *this; +} + +FormatStatement& FormatStatement::withListComma() +{ + withToken(FormatToken::COMMA_LIST, ","); + return *this; +} + +FormatStatement& FormatStatement::withCommaOper() +{ + withToken(FormatToken::COMMA_OPER, ","); + return *this; +} + +FormatStatement&FormatStatement::withSortOrder(SqliteSortOrder sortOrder) +{ + if (sortOrder != SqliteSortOrder::null) + withKeyword(sqliteSortOrder(sortOrder)); + + return *this; +} + +FormatStatement&FormatStatement::withConflict(SqliteConflictAlgo onConflict) +{ + if (onConflict != SqliteConflictAlgo::null) + withKeyword("ON").withKeyword("CONFLICT").withKeyword(sqliteConflictAlgo(onConflict)); + + return *this; +} + +FormatStatement& FormatStatement::withFuncId(const QString& func) +{ + withToken(FormatToken::FUNC_ID, func); + return *this; +} + +FormatStatement& FormatStatement::withDataType(const QString& dataType) +{ + withToken(FormatToken::DATA_TYPE, dataType); + return *this; +} + +FormatStatement& FormatStatement::withNewLine() +{ + withToken(FormatToken::NEW_LINE, NEWLINE); + return *this; +} + +FormatStatement& FormatStatement::withLiteral(const QVariant& value) +{ + if (value.isNull()) + return *this; + + bool ok; + if (value.userType() == QVariant::Double) + { + value.toDouble(&ok); + if (ok) + { + withFloat(value.toDouble()); + return *this; + } + } + + value.toInt(&ok); + if (ok) + { + withInteger(value.toInt()); + return *this; + } + + QString str = value.toString(); + if (str.startsWith("x'", Qt::CaseInsensitive) && str.endsWith("'")) + { + withBlob(str); + return *this; + } + + withString(str); + return *this; +} + +FormatStatement& FormatStatement::withStatement(SqliteStatement* stmt, const QString& indentName, FormatStatementEnricher enricher) +{ + if (!stmt) + return *this; + + FormatStatement* formatStmt = forQuery(stmt, dialect, wrapper, cfg); + if (!formatStmt) + return *this; + + formatStmt->parentFormatStatement = this; + + if (enricher) + enricher(formatStmt); + + formatStmt->buildTokens(); + formatStmt->deleteTokens = false; + + if (!indentName.isNull()) + markAndKeepIndent(indentName); + + tokens += formatStmt->tokens; + + if (!indentName.isNull()) + withDecrIndent(); + + delete formatStmt; + return *this; +} + +FormatStatement& FormatStatement::markIndent(const QString& name) +{ + withToken(FormatToken::INDENT_MARKER, statementName + "_" + name); + return *this; +} + +FormatStatement& FormatStatement::markAndKeepIndent(const QString& name) +{ + markIndent(name); + withIncrIndent(name); + return *this; +} + +FormatStatement&FormatStatement::withIncrIndent(int newIndent) +{ + withToken(FormatToken::SET_INDENT, newIndent); + return *this; +} + +FormatStatement& FormatStatement::withIncrIndent(const QString& name) +{ + if (name.isNull()) + withToken(FormatToken::INCR_INDENT, name); + else + withToken(FormatToken::INCR_INDENT, statementName + "_" + name); + + return *this; +} + +FormatStatement& FormatStatement::withDecrIndent() +{ + withToken(FormatToken::DECR_INDENT, QString()); + return *this; +} + +FormatStatement&FormatStatement::markKeywordLineUp(const QString& keyword, const QString& lineUpName) +{ + withToken(FormatToken::MARK_KEYWORD_LINEUP, getFinalLineUpName(lineUpName), keyword.length()); + return *this; +} + +FormatStatement&FormatStatement::withSeparator(FormatStatement::ListSeparator sep) +{ + switch (sep) + { + case ListSeparator::COMMA: + withListComma(); + break; + case ListSeparator::EXPR_COMMA: + withCommaOper(); + break; + case ListSeparator::NEW_LINE: + withNewLine(); + break; + case ListSeparator::SEMICOLON: + withSemicolon(); + break; + case ListSeparator::NONE: + break; + } + return *this; +} + +FormatStatement& FormatStatement::withIdList(const QStringList& names, const QString& indentName, ListSeparator sep) +{ + if (!indentName.isNull()) + markAndKeepIndent(indentName); + + bool first = true; + foreach (const QString& name, names) + { + if (!first) + withSeparator(sep); + + withId(name); + first = false; + } + + if (!indentName.isNull()) + withDecrIndent(); + + return *this; +} + +void FormatStatement::withToken(FormatStatement::FormatToken::Type type, const QVariant& value, const QVariant& additionalValue) +{ + FormatToken* token = new FormatToken; + token->type = type; + token->value = value; + token->additionalValue = additionalValue; + tokens << token; +} + +void FormatStatement::cleanup() +{ + kwLineUpPosition.clear(); + line = ""; + lines.clear(); + namedIndents.clear(); + resetIndents(); + if (deleteTokens) + { + for (FormatToken* token : tokens) + delete token; + } + + tokens.clear(); +} + +int FormatStatement::getLineUpValue(const QString& lineUpName) +{ + if (kwLineUpPosition.contains(lineUpName)) + return kwLineUpPosition[lineUpName]; + + return 0; +} + +QString FormatStatement::detokenize() +{ + bool uppercaseKeywords = cfg->SqlEnterpriseFormatter.UppercaseKeywords.get(); + + for (FormatToken* token : tokens) + { + applySpace(token->type); + switch (token->type) + { + case FormatToken::LINED_UP_KEYWORD: + { + if (cfg->SqlEnterpriseFormatter.LineUpKeywords.get()) + { + QString kw = token->value.toString(); + QString lineUpName = token->additionalValue.toString(); + int lineUpValue = getLineUpValue(lineUpName); + + int indentLength = lineUpValue - kw.length(); + if (indentLength > 0) + line += SPACE.repeated(indentLength); + + line += uppercaseKeywords ? kw.toUpper() : kw.toLower(); + + break; + } + else + { + // No 'break', so we go to next case, the regular KEYWORD + } + } + case FormatToken::KEYWORD: + { + applyIndent(); + line += uppercaseKeywords ? token->value.toString().toUpper() : token->value.toString().toLower(); + break; + } + case FormatToken::FUNC_ID: + case FormatToken::DATA_TYPE: + { + applyIndent(); + line += wrapObjIfNeeded(token->value.toString(), dialect, wrapper); + break; + } + case FormatToken::ID: + { + applyIndent(); + formatId(token->value.toString()); + break; + } + case FormatToken::STRING_OR_ID: + { + applyIndent(); + QString val = token->value.toString(); + if (val.contains("\"")) + formatId(token->value.toString()); + else + line += wrapObjName(token->value.toString(), NameWrapper::DOUBLE_QUOTE); + + break; + } + case FormatToken::STAR: + case FormatToken::FLOAT: + case FormatToken::INTEGER: + case FormatToken::BLOB: + case FormatToken::BIND_PARAM: + case FormatToken::STRING: + { + applyIndent(); + line += token->value.toString(); + break; + } + case FormatToken::OPERATOR: + { + bool spaceAdded = endsWithSpace() || applyIndent(); + if (cfg->SqlEnterpriseFormatter.SpaceBeforeMathOp.get() && !spaceAdded) + line += SPACE; + + line += token->value.toString(); + if (cfg->SqlEnterpriseFormatter.SpaceAfterMathOp.get()) + line += SPACE; + + break; + } + case FormatToken::ID_DOT: + { + bool spaceAdded = endsWithSpace() || applyIndent(); + if (cfg->SqlEnterpriseFormatter.SpaceBeforeDot.get() && !spaceAdded) + line += SPACE; + + line += token->value.toString(); + if (cfg->SqlEnterpriseFormatter.SpaceAfterDot.get()) + line += SPACE; + + break; + } + case FormatToken::PAR_DEF_LEFT: + { + bool spaceBefore = cfg->SqlEnterpriseFormatter.SpaceBeforeOpenPar.get(); + bool spaceAfter = cfg->SqlEnterpriseFormatter.SpaceAfterOpenPar.get(); + bool nlBefore = cfg->SqlEnterpriseFormatter.NlBeforeOpenParDef.get(); + bool nlAfter = cfg->SqlEnterpriseFormatter.NlAfterOpenParDef.get(); + detokenizeLeftPar(token, spaceBefore, spaceAfter, nlBefore, nlAfter); + break; + } + case FormatToken::PAR_DEF_RIGHT: + { + bool spaceBefore = cfg->SqlEnterpriseFormatter.SpaceBeforeClosePar.get(); + bool spaceAfter = cfg->SqlEnterpriseFormatter.SpaceAfterClosePar.get(); + bool nlBefore = cfg->SqlEnterpriseFormatter.NlBeforeCloseParDef.get(); + bool nlAfter = cfg->SqlEnterpriseFormatter.NlAfterCloseParDef.get(); + detokenizeRightPar(token, spaceBefore, spaceAfter, nlBefore, nlAfter); + break; + } + case FormatToken::PAR_EXPR_LEFT: + { + bool spaceBefore = cfg->SqlEnterpriseFormatter.SpaceBeforeOpenPar.get(); + bool spaceAfter = cfg->SqlEnterpriseFormatter.SpaceAfterOpenPar.get(); + bool nlBefore = cfg->SqlEnterpriseFormatter.NlBeforeOpenParExpr.get(); + bool nlAfter = cfg->SqlEnterpriseFormatter.NlAfterOpenParExpr.get(); + detokenizeLeftPar(token, spaceBefore, spaceAfter, nlBefore, nlAfter); + break; + } + case FormatToken::PAR_EXPR_RIGHT: + { + bool spaceBefore = cfg->SqlEnterpriseFormatter.SpaceBeforeClosePar.get(); + bool spaceAfter = cfg->SqlEnterpriseFormatter.SpaceAfterClosePar.get(); + bool nlBefore = cfg->SqlEnterpriseFormatter.NlBeforeCloseParExpr.get(); + bool nlAfter = cfg->SqlEnterpriseFormatter.NlAfterCloseParExpr.get(); + detokenizeRightPar(token, spaceBefore, spaceAfter, nlBefore, nlAfter); + break; + } + case FormatToken::PAR_FUNC_LEFT: + { + bool spaceBefore = cfg->SqlEnterpriseFormatter.SpaceBeforeOpenPar.get() && !cfg->SqlEnterpriseFormatter.NoSpaceAfterFunctionName.get(); + bool spaceAfter = cfg->SqlEnterpriseFormatter.SpaceAfterOpenPar.get(); + bool nlBefore = cfg->SqlEnterpriseFormatter.NlBeforeOpenParExpr.get(); + bool nlAfter = cfg->SqlEnterpriseFormatter.NlAfterOpenParExpr.get(); + detokenizeLeftPar(token, spaceBefore, spaceAfter, nlBefore, nlAfter); + break; + } + case FormatToken::PAR_FUNC_RIGHT: + { + bool spaceBefore = cfg->SqlEnterpriseFormatter.SpaceBeforeClosePar.get(); + bool spaceAfter = cfg->SqlEnterpriseFormatter.SpaceAfterClosePar.get(); + bool nlBefore = cfg->SqlEnterpriseFormatter.NlBeforeCloseParExpr.get(); + bool nlAfter = cfg->SqlEnterpriseFormatter.NlAfterCloseParExpr.get(); + detokenizeRightPar(token, spaceBefore, spaceAfter, nlBefore, nlAfter); + break; + } + case FormatToken::SEMICOLON: + { + if (cfg->SqlEnterpriseFormatter.SpaceNeverBeforeSemicolon.get()) + { + removeAllSpaces(); + } + else + { + bool spaceAdded = endsWithSpace() || applyIndent(); + if (cfg->SqlEnterpriseFormatter.SpaceBeforeMathOp.get() && !spaceAdded) + line += SPACE; + } + + line += token->value.toString(); + if (cfg->SqlEnterpriseFormatter.NlAfterSemicolon.get()) + newLine(); + else if (cfg->SqlEnterpriseFormatter.SpaceAfterMathOp.get()) + line += SPACE; + + break; + } + case FormatToken::COMMA_LIST: + { + if (cfg->SqlEnterpriseFormatter.SpaceNeverBeforeComma.get()) + { + removeAllSpaces(); + } + else + { + bool spaceAdded = endsWithSpace() || applyIndent(); + if (cfg->SqlEnterpriseFormatter.SpaceBeforeCommaInList.get() && !spaceAdded) + line += SPACE; + } + + line += token->value.toString(); + if (cfg->SqlEnterpriseFormatter.NlAfterComma.get()) + newLine(); + else if (cfg->SqlEnterpriseFormatter.SpaceAfterCommaInList.get()) + line += SPACE; + + break; + } + case FormatToken::COMMA_OPER: + { + if (cfg->SqlEnterpriseFormatter.SpaceNeverBeforeComma.get()) + { + removeAllSpaces(); + } + else + { + bool spaceAdded = endsWithSpace() || applyIndent(); + if (cfg->SqlEnterpriseFormatter.SpaceBeforeCommaInList.get() && !spaceAdded) + line += SPACE; + } + + line += token->value.toString(); + if (cfg->SqlEnterpriseFormatter.NlAfterCommaInExpr.get()) + newLine(); + else if (cfg->SqlEnterpriseFormatter.SpaceAfterCommaInList.get()) + line += SPACE; + + break; + } + case FormatToken::NEW_LINE: + { + newLine(); + break; + } + case FormatToken::INDENT_MARKER: + { + QString indentName = token->value.toString(); + namedIndents[indentName] = predictCurrentIndent(token); + break; + } + case FormatToken::INCR_INDENT: + { + if (!token->value.isNull()) + incrIndent(token->value.toString()); + else + incrIndent(); + + break; + } + case FormatToken::SET_INDENT: + { + setIndent(indents.top() + token->value.toInt()); + break; + } + case FormatToken::DECR_INDENT: + { + decrIndent(); + break; + } + case FormatToken::MARK_KEYWORD_LINEUP: + { + QString lineUpName = token->value.toString(); + int lineUpLength = predictCurrentIndent(token) + token->additionalValue.toInt(); + if (!kwLineUpPosition.contains(lineUpName) || lineUpLength > kwLineUpPosition[lineUpName]) + kwLineUpPosition[lineUpName] = lineUpLength; + + break; + } + } + updateLastToken(token); + } + newLine(); + return lines.join(NEWLINE); +} + +bool FormatStatement::applyIndent() +{ + int indentToAdd = indents.top() - line.length(); + if (indentToAdd <= 0) + return false; + + line += SPACE.repeated(indentToAdd); + return true; +} + +void FormatStatement::applySpace(FormatToken::Type type) +{ + if (lastToken && isSpaceExpectingType(type) && isSpaceExpectingType(lastToken->type) && !endsWithSpace()) + line += SPACE; +} + +bool FormatStatement::isSpaceExpectingType(FormatStatement::FormatToken::Type type) +{ + switch (type) + { + case FormatToken::KEYWORD: + case FormatToken::LINED_UP_KEYWORD: + case FormatToken::ID: + case FormatToken::STRING_OR_ID: + case FormatToken::FLOAT: + case FormatToken::STRING: + case FormatToken::INTEGER: + case FormatToken::BLOB: + case FormatToken::BIND_PARAM: + case FormatToken::FUNC_ID: + case FormatToken::DATA_TYPE: + case FormatToken::STAR: + return true; + case FormatToken::OPERATOR: + case FormatToken::ID_DOT: + case FormatToken::PAR_DEF_LEFT: + case FormatToken::PAR_DEF_RIGHT: + case FormatToken::PAR_EXPR_LEFT: + case FormatToken::PAR_EXPR_RIGHT: + case FormatToken::PAR_FUNC_LEFT: + case FormatToken::PAR_FUNC_RIGHT: + case FormatToken::SEMICOLON: + case FormatToken::COMMA_LIST: + case FormatToken::COMMA_OPER: + case FormatToken::NEW_LINE: + case FormatToken::INDENT_MARKER: + case FormatToken::INCR_INDENT: + case FormatToken::DECR_INDENT: + case FormatToken::SET_INDENT: + case FormatToken::MARK_KEYWORD_LINEUP: + break; + } + return false; +} + +bool FormatStatement::isMetaType(FormatStatement::FormatToken::Type type) +{ + switch (type) + { + case FormatToken::INDENT_MARKER: + case FormatToken::INCR_INDENT: + case FormatToken::DECR_INDENT: + case FormatToken::SET_INDENT: + case FormatToken::MARK_KEYWORD_LINEUP: + return true; + case FormatToken::KEYWORD: + case FormatToken::LINED_UP_KEYWORD: + case FormatToken::ID: + case FormatToken::STRING_OR_ID: + case FormatToken::FLOAT: + case FormatToken::STRING: + case FormatToken::INTEGER: + case FormatToken::BLOB: + case FormatToken::BIND_PARAM: + case FormatToken::FUNC_ID: + case FormatToken::DATA_TYPE: + case FormatToken::OPERATOR: + case FormatToken::STAR: + case FormatToken::ID_DOT: + case FormatToken::PAR_DEF_LEFT: + case FormatToken::PAR_DEF_RIGHT: + case FormatToken::PAR_EXPR_LEFT: + case FormatToken::PAR_EXPR_RIGHT: + case FormatToken::PAR_FUNC_LEFT: + case FormatToken::PAR_FUNC_RIGHT: + case FormatToken::SEMICOLON: + case FormatToken::COMMA_LIST: + case FormatToken::COMMA_OPER: + case FormatToken::NEW_LINE: + break; + } + return false; +} + +void FormatStatement::newLine() +{ + if (line.length() == 0) // prevents double new-line when for example "))" occurs and it has new-line before and after + return; + + lines << line; + line = ""; +} + +void FormatStatement::incrIndent(const QString& name) +{ + if (!name.isNull()) + { + if (namedIndents.contains(name)) + { + indents.push(namedIndents[name]); + } + else + { + indents.push(indents.top() + cfg->SqlEnterpriseFormatter.TabSize.get()); + qCritical() << __func__ << "No named indent found:" << name; + } + } + else + indents.push(indents.top() + cfg->SqlEnterpriseFormatter.TabSize.get()); +} + +void FormatStatement::decrIndent() +{ + if (indents.size() <= 1) + return; + + indents.pop(); +} + +void FormatStatement::setIndent(int newIndent) +{ + indents.push(newIndent); +} + +bool FormatStatement::endsWithSpace() +{ + return line.length() == 0 || line[line.length() - 1].isSpace(); +} + +FormatStatement::FormatToken* FormatStatement::getLastRealToken(bool skipNewLines) +{ + for (FormatToken* tk : reverse(tokens)) + { + if (!isMetaType(tk->type) && (!skipNewLines || tk->type != FormatToken::NEW_LINE)) + return tk; + } + return nullptr; +} + +void FormatStatement::detokenizeLeftPar(FormatToken* token, bool spaceBefore, bool spaceAfter, bool nlBefore, bool nlAfter) +{ + bool spaceAdded = endsWithSpace(); + if (nlBefore) + { + newLine(); + spaceAdded = true; + } + + spaceAdded |= applyIndent(); + if (spaceBefore && !spaceAdded) + line += SPACE; + + line += token->value.toString(); + if (nlAfter) + { + newLine(); + if (cfg->SqlEnterpriseFormatter.IndentParenthesisBlock.get()) + incrIndent(); + } + else if (spaceAfter) + line += SPACE; +} + +void FormatStatement::detokenizeRightPar(FormatStatement::FormatToken* token, bool spaceBefore, bool spaceAfter, bool nlBefore, bool nlAfter) +{ + bool spaceAdded = endsWithSpace(); + if (nlBefore) + { + newLine(); + spaceAdded = true; + if (cfg->SqlEnterpriseFormatter.IndentParenthesisBlock.get()) + decrIndent(); + } + + spaceAdded |= applyIndent(); + if (spaceBefore && !spaceAdded) + line += SPACE; + + line += token->value.toString(); + if (nlAfter) + newLine(); + else if (spaceAfter) + line += SPACE; +} + +void FormatStatement::resetIndents() +{ + indents.clear(); + indents.push(0); +} + +void FormatStatement::removeAllSpaces() +{ + removeAllSpacesFromLine(); + while (endsWithSpace() && lines.size() > 0) + { + line = lines.takeLast(); + removeAllSpacesFromLine(); + + if (lines.size() == 0) + break; + } +} + +void FormatStatement::removeAllSpacesFromLine() +{ + while (endsWithSpace() && line.length() > 0) + line.chop(1); +} + +void FormatStatement::updateLastToken(FormatStatement::FormatToken* token) +{ + if (!isMetaType(token->type)) + lastToken = token; +} + +QString FormatStatement::getFinalLineUpName(const QString& lineUpName) +{ + QString finalName = statementName; + if (!lineUpName.isNull()) + finalName += "_" + lineUpName; + + return finalName; +} + +int FormatStatement::predictCurrentIndent(FormatToken* currentMetaToken) +{ + QString lineBackup = line; + bool isSpace = applyIndent() || endsWithSpace(); + + if (!isSpace) + { + // We haven't added any space and there is no space currently at the end of line. + // We need to predict if next real (printable) token will require space to be added. + // If yes, we add it virtually here, so we know the indent required afterwards. + // First we need to find next real token: + int tokenIdx = tokens.indexOf(currentMetaToken); + FormatToken* nextRealToken = nullptr; + for (FormatToken* tk : tokens.mid(tokenIdx + 1)) + { + if (!isMetaType(tk->type)) + { + nextRealToken = tk; + break; + } + } + + // If the real token was found we can see if it will require additional space for indent: + if ((nextRealToken && isSpaceExpectingType(lastToken->type) && isSpaceExpectingType(nextRealToken->type)) || willStartWithNewLine(nextRealToken)) + { + // Next real token does not start with new line, but it does require additional space: + line += SPACE; + } + } + + int result = line.length(); + line = lineBackup; + return result; +} + +bool FormatStatement::willStartWithNewLine(FormatStatement::FormatToken* token) +{ + return (token->type == FormatToken::PAR_DEF_LEFT && cfg->SqlEnterpriseFormatter.NlBeforeOpenParDef) || + (token->type == FormatToken::PAR_EXPR_LEFT && cfg->SqlEnterpriseFormatter.NlBeforeOpenParExpr) || + (token->type == FormatToken::PAR_FUNC_LEFT && cfg->SqlEnterpriseFormatter.NlBeforeOpenParExpr) || + (token->type == FormatToken::PAR_DEF_RIGHT && cfg->SqlEnterpriseFormatter.NlBeforeCloseParDef) || + (token->type == FormatToken::PAR_EXPR_RIGHT && cfg->SqlEnterpriseFormatter.NlBeforeCloseParExpr) || + (token->type == FormatToken::PAR_FUNC_RIGHT && cfg->SqlEnterpriseFormatter.NlBeforeCloseParExpr) || + (token->type == FormatToken::NEW_LINE); +} + +void FormatStatement::formatId(const QString& value) +{ + if (cfg->SqlEnterpriseFormatter.AlwaysUseNameWrapping.get()) + line += wrapObjName(value, dialect, wrapper); + else + line += wrapObjIfNeeded(value, dialect, wrapper); +} + +FormatStatement* FormatStatement::forQuery(SqliteStatement* query, Dialect dialect, NameWrapper wrapper, Cfg::SqlEnterpriseFormatterConfig* cfg) +{ + FormatStatement* formatStmt = forQuery(query); + if (formatStmt) + { + formatStmt->dialect = dialect; + formatStmt->wrapper = wrapper; + formatStmt->cfg = cfg; + } + return formatStmt; +} diff --git a/Plugins/SqlEnterpriseFormatter/formatstatement.h b/Plugins/SqlEnterpriseFormatter/formatstatement.h new file mode 100644 index 0000000..1702a3d --- /dev/null +++ b/Plugins/SqlEnterpriseFormatter/formatstatement.h @@ -0,0 +1,198 @@ +#ifndef FORMATSTATEMENT_H +#define FORMATSTATEMENT_H + +#include "parser/ast/sqlitestatement.h" +#include "parser/ast/sqlitesortorder.h" +#include "parser/ast/sqliteconflictalgo.h" +#include "common/utils_sql.h" +#include "sqlenterpriseformatter.h" +#include <QString> +#include <QStringList> +#include <QHash> +#include <QStack> +#include <QVariant> +#include <functional> + +class FormatStatement +{ + public: + enum class ListSeparator + { + NONE, + COMMA, + EXPR_COMMA, + NEW_LINE, + SEMICOLON + }; + + typedef std::function<void(FormatStatement*)> FormatStatementEnricher; + + FormatStatement(); + virtual ~FormatStatement(); + + QString format(); + void setSelectedWrapper(NameWrapper wrapper); + void setConfig(Cfg::SqlEnterpriseFormatterConfig* cfg); + + static FormatStatement* forQuery(SqliteStatement *query); + + FormatStatement& withKeyword(const QString& kw); + FormatStatement& withLinedUpKeyword(const QString& kw, const QString& lineUpName = QString()); + FormatStatement& withId(const QString& id); + FormatStatement& withIdList(const QStringList& names, const QString& indentName = QString(), ListSeparator sep = ListSeparator::COMMA); + FormatStatement& withOperator(const QString& oper); + FormatStatement& withStringOrId(const QString& id); + FormatStatement& withIdDot(); + FormatStatement& withStar(); + FormatStatement& withFloat(double value); + FormatStatement& withInteger(qint64 value); + FormatStatement& withString(const QString& value); + FormatStatement& withBlob(const QString& value); + FormatStatement& withBindParam(const QString& name); + FormatStatement& withParDefLeft(); + FormatStatement& withParDefRight(); + FormatStatement& withParExprLeft(); + FormatStatement& withParExprRight(); + FormatStatement& withParFuncLeft(); + FormatStatement& withParFuncRight(); + FormatStatement& withSemicolon(); + FormatStatement& withListComma(); + FormatStatement& withCommaOper(); + FormatStatement& withSortOrder(SqliteSortOrder sortOrder); + FormatStatement& withConflict(SqliteConflictAlgo onConflict); + FormatStatement& withFuncId(const QString& func); + FormatStatement& withDataType(const QString& dataType); + FormatStatement& withNewLine(); + FormatStatement& withLiteral(const QVariant& value); + FormatStatement& withStatement(SqliteStatement* stmt, const QString& indentName = QString(), FormatStatementEnricher enricher = nullptr); + FormatStatement& markIndent(const QString& name); + FormatStatement& markAndKeepIndent(const QString& name); + FormatStatement& withIncrIndent(int newIndent); + FormatStatement& withIncrIndent(const QString& name = QString()); + FormatStatement& withDecrIndent(); + FormatStatement& markKeywordLineUp(const QString& keyword, const QString& lineUpName = QString()); + FormatStatement& withSeparator(ListSeparator sep); + + template <class T> + FormatStatement& withStatementList(QList<T*> stmtList, const QString& indentName = QString(), ListSeparator sep = ListSeparator::COMMA, + FormatStatementEnricher enricher = nullptr) + { + if (!indentName.isNull()) + markAndKeepIndent(indentName); + + bool first = true; + foreach (T* stmt, stmtList) + { + if (!first) + withSeparator(sep); + + withStatement(stmt, QString(), enricher); + first = false; + } + + if (!indentName.isNull()) + withDecrIndent(); + + return *this; + } + + template <class T> + T* getFormatStatement(SqliteStatement* stmt) + { + return dynamic_cast<T*>(forQuery(stmt, dialect, wrapper, cfg)); + } + + protected: + virtual void formatInternal() = 0; + virtual void resetInternal(); + + Dialect dialect = Dialect::Sqlite3; + NameWrapper wrapper = NameWrapper::BRACKET; + Cfg::SqlEnterpriseFormatterConfig* cfg = nullptr; + + private: + struct FormatToken + { + enum Type + { + KEYWORD, + LINED_UP_KEYWORD, + ID, + STRING_OR_ID, + OPERATOR, + STAR, + FLOAT, + STRING, + INTEGER, + BLOB, + BIND_PARAM, + ID_DOT, + PAR_DEF_LEFT, + PAR_DEF_RIGHT, + PAR_EXPR_LEFT, + PAR_EXPR_RIGHT, + PAR_FUNC_LEFT, + PAR_FUNC_RIGHT, + SEMICOLON, + COMMA_LIST, + COMMA_OPER, // for example in LIMIT + FUNC_ID, + DATA_TYPE, + NEW_LINE, + INDENT_MARKER, + INCR_INDENT, + SET_INDENT, + DECR_INDENT, + MARK_KEYWORD_LINEUP + }; + + Type type; + QVariant value; + QVariant additionalValue; + }; + + void withToken(FormatToken::Type type, const QVariant& value, const QVariant& additionalValue = QVariant()); + void cleanup(); + void buildTokens(); + bool applyIndent(); + void applySpace(FormatToken::Type type); + bool isSpaceExpectingType(FormatToken::Type type); + bool isMetaType(FormatToken::Type type); + void newLine(); + void incrIndent(const QString& name = QString()); + void decrIndent(); + void setIndent(int newIndent); + bool endsWithSpace(); + FormatToken* getLastRealToken(bool skipNewLines = false); + QString detokenize(); + void detokenizeLeftPar(FormatToken* token, bool spaceBefore, bool spaceAfter, bool nlBefore, bool nlAfter); + void detokenizeRightPar(FormatToken* token, bool spaceBefore, bool spaceAfter, bool nlBefore, bool nlAfter); + void resetIndents(); + void removeAllSpaces(); + void removeAllSpacesFromLine(); + void updateLastToken(FormatToken* token); + QString getFinalLineUpName(const QString& lineUpName); + int predictCurrentIndent(FormatToken* currentMetaToken); + bool willStartWithNewLine(FormatToken* token); + void formatId(const QString& value); + int getLineUpValue(const QString& lineUpName); + + static FormatStatement* forQuery(SqliteStatement *query, Dialect dialect, NameWrapper wrapper, Cfg::SqlEnterpriseFormatterConfig* cfg); + + QHash<QString,int> kwLineUpPosition; + QHash<QString,int> namedIndents; + QStack<int> indents; + QList<FormatToken*> tokens; + bool deleteTokens = true; + QStringList lines; + QString line; + FormatToken* lastToken = nullptr; + QString statementName; + FormatStatement* parentFormatStatement = nullptr; + + static qint64 nameSeq; + static const QString SPACE; + static const QString NEWLINE; +}; + +#endif // FORMATSTATEMENT_H diff --git a/Plugins/SqlEnterpriseFormatter/formatupdate.cpp b/Plugins/SqlEnterpriseFormatter/formatupdate.cpp new file mode 100644 index 0000000..ffc3911 --- /dev/null +++ b/Plugins/SqlEnterpriseFormatter/formatupdate.cpp @@ -0,0 +1,47 @@ +#include "formatupdate.h" +#include "parser/ast/sqliteupdate.h" +#include "parser/ast/sqliteexpr.h" +#include "formatwith.h" + +FormatUpdate::FormatUpdate(SqliteUpdate* upd) : + upd(upd) +{ +} + +void FormatUpdate::formatInternal() +{ + if (upd->with) + withStatement(upd->with); + + markKeywordLineUp("UPDATE"); + withKeyword("UPDATE"); + if (upd->onConflict != SqliteConflictAlgo::null) + withKeyword("OR").withKeyword(sqliteConflictAlgo(upd->onConflict)); + + if (!upd->database.isNull()) + withId(upd->database).withIdDot(); + + withId(upd->table); + + if (upd->indexedByKw) + withKeyword("INDEXED").withKeyword("BY").withId(upd->indexedBy); + else if (upd->notIndexedKw) + withKeyword("NOT").withKeyword("INDEXED"); + + withNewLine().withLinedUpKeyword("SET"); + + bool first = true; + foreach (const SqliteUpdate::ColumnAndValue& keyVal, upd->keyValueMap) + { + if (!first) + withListComma(); + + withId(keyVal.first).withOperator("=").withStatement(keyVal.second); + first = false; + } + + if (upd->where) + withNewLine().withLinedUpKeyword("WHERE").withStatement(upd->where); + + withSemicolon(); +} diff --git a/Plugins/SqlEnterpriseFormatter/formatupdate.h b/Plugins/SqlEnterpriseFormatter/formatupdate.h new file mode 100644 index 0000000..ca5ee11 --- /dev/null +++ b/Plugins/SqlEnterpriseFormatter/formatupdate.h @@ -0,0 +1,20 @@ +#ifndef FORMATUPDATE_H +#define FORMATUPDATE_H + +#include "formatstatement.h" + +class SqliteUpdate; + +class FormatUpdate : public FormatStatement +{ + public: + FormatUpdate(SqliteUpdate* upd); + + protected: + void formatInternal(); + + private: + SqliteUpdate* upd = nullptr; +}; + +#endif // FORMATUPDATE_H diff --git a/Plugins/SqlEnterpriseFormatter/formatvacuum.cpp b/Plugins/SqlEnterpriseFormatter/formatvacuum.cpp new file mode 100644 index 0000000..29b95e4 --- /dev/null +++ b/Plugins/SqlEnterpriseFormatter/formatvacuum.cpp @@ -0,0 +1,11 @@ +#include "formatvacuum.h" + +FormatVacuum::FormatVacuum(SqliteVacuum* vacuum) : + vacuum(vacuum) +{ +} + +void FormatVacuum::formatInternal() +{ + withKeyword("VACUUM").withSemicolon(); +} diff --git a/Plugins/SqlEnterpriseFormatter/formatvacuum.h b/Plugins/SqlEnterpriseFormatter/formatvacuum.h new file mode 100644 index 0000000..34eedc9 --- /dev/null +++ b/Plugins/SqlEnterpriseFormatter/formatvacuum.h @@ -0,0 +1,20 @@ +#ifndef FORMATVACUUM_H +#define FORMATVACUUM_H + +#include "formatstatement.h" + +class SqliteVacuum; + +class FormatVacuum : public FormatStatement +{ + public: + FormatVacuum(SqliteVacuum* vacuum); + + protected: + void formatInternal(); + + private: + SqliteVacuum* vacuum = nullptr; +}; + +#endif // FORMATVACUUM_H diff --git a/Plugins/SqlEnterpriseFormatter/formatwith.cpp b/Plugins/SqlEnterpriseFormatter/formatwith.cpp new file mode 100644 index 0000000..d3d99d5 --- /dev/null +++ b/Plugins/SqlEnterpriseFormatter/formatwith.cpp @@ -0,0 +1,38 @@ +#include "formatwith.h" +#include "parser/ast/sqliteselect.h" + +FormatWith::FormatWith(SqliteWith *with) : + with(with) +{ +} + +void FormatWith::setLineUpKeyword(const QString& kw) +{ + lineUpKeyword = kw; +} + +void FormatWith::formatInternal() +{ + markKeywordLineUp(lineUpKeyword); + + withLinedUpKeyword("WITH"); + if (with->recursive) + withKeyword("RECURSIVE"); + + withStatementList(with->cteList); +} + + +FormatWithCommonTableExpression::FormatWithCommonTableExpression(SqliteWith::CommonTableExpression *cte) : + cte(cte) +{ +} + +void FormatWithCommonTableExpression::formatInternal() +{ + withId(cte->table); + if (cte->indexedColumns.size() > 0) + withParDefLeft().withStatementList(cte->indexedColumns, "idxCols").withParDefRight(); + + withKeyword("AS").withParDefLeft().withStatement(cte->select).withParDefRight(); +} diff --git a/Plugins/SqlEnterpriseFormatter/formatwith.h b/Plugins/SqlEnterpriseFormatter/formatwith.h new file mode 100644 index 0000000..618b73b --- /dev/null +++ b/Plugins/SqlEnterpriseFormatter/formatwith.h @@ -0,0 +1,31 @@ +#ifndef FORMATWITH_H +#define FORMATWITH_H + +#include "formatstatement.h" +#include "parser/ast/sqlitewith.h" + +class FormatWith : public FormatStatement +{ + public: + FormatWith(SqliteWith* with); + + void setLineUpKeyword(const QString& kw); + void formatInternal(); + + private: + SqliteWith *with = nullptr; + QString lineUpKeyword; +}; + +class FormatWithCommonTableExpression : public FormatStatement +{ + public: + FormatWithCommonTableExpression(SqliteWith::CommonTableExpression* cte); + + void formatInternal(); + + private: + SqliteWith::CommonTableExpression* cte = nullptr; +}; + +#endif // FORMATWITH_H diff --git a/Plugins/SqlEnterpriseFormatter/sqlenterpriseformatter.cpp b/Plugins/SqlEnterpriseFormatter/sqlenterpriseformatter.cpp new file mode 100644 index 0000000..8f75960 --- /dev/null +++ b/Plugins/SqlEnterpriseFormatter/sqlenterpriseformatter.cpp @@ -0,0 +1,112 @@ +#include "sqlenterpriseformatter.h" +#include "formatstatement.h" +#include "common/unused.h" +#include "common/global.h" +#include <QDebug> +#include <parser/parser.h> + +SqlEnterpriseFormatter::SqlEnterpriseFormatter() +{ +} + +QString SqlEnterpriseFormatter::format(SqliteQueryPtr query) +{ + int wrapperIdx = cfg.SqlEnterpriseFormatter.Wrappers.get().indexOf(cfg.SqlEnterpriseFormatter.PrefferedWrapper.get()); + + NameWrapper wrapper = getAllNameWrappers()[wrapperIdx]; + + FormatStatement *formatStmt = FormatStatement::forQuery(query.data()); + if (!formatStmt) + return query->detokenize(); + + formatStmt->setSelectedWrapper(wrapper); + formatStmt->setConfig(&cfg); + QString formatted = formatStmt->format(); + delete formatStmt; + + return formatted; +} + +bool SqlEnterpriseFormatter::init() +{ + Q_INIT_RESOURCE(sqlenterpriseformatter); + + static_qstring(query1, "SELECT (2 + 4) AND (3 + 5), 4 NOT IN (SELECT t1.'some[_]name' + t2.[some'name2] FROM xyz t1 JOIN zxc t2 ON (t1.aaa = t2.aaa)) " + "FROM a, (SELECT id FROM table2);"); + static_qstring(query2, "INSERT INTO table1 (id, value1, value2) VALUES (1, (2 + 5), (SELECT id FROM table2));"); + static_qstring(query3, "CREATE TABLE tab (id INTEGER PRIMARY KEY, value1 VARCHAR(6), value2 NUMBER(8,2) NOT NULL DEFAULT 1.0);"); + static_qstring(query4, "CREATE UNIQUE INDEX IF NOT EXISTS dbName.idx1 ON [messages column] (id COLLATE x ASC, lang DESC, description);"); + + Parser parser(Dialect::Sqlite3); + + for (const QString& q : {query1, query2, query3, query4}) + { + if (!parser.parse(q)) + { + qWarning() << "SqlEnterpriseFormatter preview query parsing error:" << parser.getErrorString(); + continue; + } + previewQueries << parser.getQueries().first(); + } + + updatePreview(); + + return GenericPlugin::init(); +} + +void SqlEnterpriseFormatter::deinit() +{ + Q_CLEANUP_RESOURCE(sqlenterpriseformatter); +} + + +void SqlEnterpriseFormatter::updatePreview() +{ + QStringList output; + for (const SqliteQueryPtr& q : previewQueries) + output << format(q); + + cfg.SqlEnterpriseFormatter.PreviewCode.set(output.join("\n\n")); +} + +void SqlEnterpriseFormatter::configModified(CfgEntry* entry) +{ + if (entry == &cfg.SqlEnterpriseFormatter.PreviewCode) + return; + + updatePreview(); +} + +QString Cfg::getNameWrapperStr(NameWrapper wrapper) +{ + return wrapObjName(QObject::tr("name", "example name wrapper"), wrapper); +} + +QStringList Cfg::getNameWrapperStrings() +{ + QStringList strings; + for (NameWrapper nw : getAllNameWrappers()) + strings << wrapObjName(QObject::tr("name", "example name wrapper"), nw); + + return strings; +} + +CfgMain* SqlEnterpriseFormatter::getMainUiConfig() +{ + return &cfg; +} + +QString SqlEnterpriseFormatter::getConfigUiForm() const +{ + return "SqlEnterpriseFormatter"; +} + +void SqlEnterpriseFormatter::configDialogOpen() +{ + connect(&cfg.SqlEnterpriseFormatter, SIGNAL(changed(CfgEntry*)), this, SLOT(configModified(CfgEntry*))); +} + +void SqlEnterpriseFormatter::configDialogClosed() +{ + disconnect(&cfg.SqlEnterpriseFormatter, SIGNAL(changed(CfgEntry*)), this, SLOT(configModified(CfgEntry*))); +} diff --git a/Plugins/SqlEnterpriseFormatter/sqlenterpriseformatter.h b/Plugins/SqlEnterpriseFormatter/sqlenterpriseformatter.h new file mode 100644 index 0000000..2701745 --- /dev/null +++ b/Plugins/SqlEnterpriseFormatter/sqlenterpriseformatter.h @@ -0,0 +1,84 @@ +#ifndef SQLENTERPRISEFORMATTER_H +#define SQLENTERPRISEFORMATTER_H + +#include "sqlenterpriseformatter_global.h" +#include "plugins/genericplugin.h" +#include "plugins/sqlformatterplugin.h" +#include "config_builder.h" +#include "common/utils_sql.h" +#include "plugins/uiconfiguredplugin.h" +#include "parser/ast/sqlitequery.h" + +namespace Cfg +{ + QString getNameWrapperStr(NameWrapper wrapper); + QStringList getNameWrapperStrings(); +} + +CFG_CATEGORIES(SqlEnterpriseFormatterConfig, + CFG_CATEGORY(SqlEnterpriseFormatter, + CFG_ENTRY(int, TabSize, 4) + CFG_ENTRY(bool, LineUpKeywords, true) + CFG_ENTRY(bool, IndentParenthesisBlock, true) + CFG_ENTRY(bool, NlBeforeOpenParDef, false) + CFG_ENTRY(bool, NlAfterOpenParDef, true) + CFG_ENTRY(bool, NlBeforeCloseParDef, true) + CFG_ENTRY(bool, NlAfterCloseParDef, true) + CFG_ENTRY(bool, NlBeforeOpenParExpr, false) + CFG_ENTRY(bool, NlAfterOpenParExpr, false) + CFG_ENTRY(bool, NlBeforeCloseParExpr, false) + CFG_ENTRY(bool, NlAfterCloseParExpr, false) + CFG_ENTRY(bool, NlAfterJoinStmt, true) + CFG_ENTRY(bool, NlAfterComma, true) + CFG_ENTRY(bool, NlAfterCommaInExpr, false) + CFG_ENTRY(bool, NlAfterSemicolon, true) + CFG_ENTRY(bool, NlNeverBeforeSemicolon, true) + CFG_ENTRY(bool, NlBetweenConstraints, true) + CFG_ENTRY(bool, SpaceBeforeCommaInList, false) + CFG_ENTRY(bool, SpaceAfterCommaInList, true) + CFG_ENTRY(bool, SpaceBeforeOpenPar, true) + CFG_ENTRY(bool, SpaceAfterOpenPar, false) + CFG_ENTRY(bool, SpaceBeforeClosePar, false) + CFG_ENTRY(bool, SpaceAfterClosePar, true) + CFG_ENTRY(bool, SpaceBeforeDot, false) + CFG_ENTRY(bool, SpaceAfterDot, false) + CFG_ENTRY(bool, SpaceBeforeMathOp, true) + CFG_ENTRY(bool, SpaceAfterMathOp, true) + CFG_ENTRY(bool, NoSpaceAfterFunctionName, true) + CFG_ENTRY(bool, SpaceNeverBeforeSemicolon, true) + CFG_ENTRY(bool, SpaceNeverBeforeComma, true) + CFG_ENTRY(bool, UppercaseKeywords, true) + CFG_ENTRY(bool, UppercaseDataTypes, true) + CFG_ENTRY(bool, AlwaysUseNameWrapping, false) + CFG_ENTRY(QString, PrefferedWrapper, getNameWrapperStr(NameWrapper::BRACKET)) + CFG_ENTRY(QStringList, Wrappers, getNameWrapperStrings(), false) + CFG_ENTRY(QString, PreviewCode, QString(), false) + ) +) + +class SQLENTERPRISEFORMATTERSHARED_EXPORT SqlEnterpriseFormatter : public GenericPlugin, public SqlFormatterPlugin, public UiConfiguredPlugin +{ + Q_OBJECT + SQLITESTUDIO_PLUGIN("sqlenterpriseformatter.json") + + public: + SqlEnterpriseFormatter(); + + QString format(SqliteQueryPtr query); + bool init(); + void deinit(); + CfgMain* getMainUiConfig(); + QString getConfigUiForm() const; + void configDialogOpen(); + void configDialogClosed(); + + private: + QList<SqliteQueryPtr> previewQueries; + CFG_LOCAL_PERSISTABLE(SqlEnterpriseFormatterConfig, cfg) + + private slots: + void updatePreview(); + void configModified(CfgEntry* entry); +}; + +#endif // SQLENTERPRISEFORMATTER_H diff --git a/Plugins/SqlEnterpriseFormatter/sqlenterpriseformatter.json b/Plugins/SqlEnterpriseFormatter/sqlenterpriseformatter.json new file mode 100644 index 0000000..2e6f543 --- /dev/null +++ b/Plugins/SqlEnterpriseFormatter/sqlenterpriseformatter.json @@ -0,0 +1,7 @@ +{ + "type": "CodeFormatterPlugin", + "title": "SQL Enterprise", + "description": "Advanced SQL formatter.", + "version": 10002, + "author": "SalSoft" +} diff --git a/Plugins/SqlEnterpriseFormatter/sqlenterpriseformatter.qrc b/Plugins/SqlEnterpriseFormatter/sqlenterpriseformatter.qrc new file mode 100644 index 0000000..bd23092 --- /dev/null +++ b/Plugins/SqlEnterpriseFormatter/sqlenterpriseformatter.qrc @@ -0,0 +1,5 @@ +<RCC> + <qresource prefix="/forms"> + <file>sqlenterpriseformatter.ui</file> + </qresource> +</RCC> diff --git a/Plugins/SqlEnterpriseFormatter/sqlenterpriseformatter.ui b/Plugins/SqlEnterpriseFormatter/sqlenterpriseformatter.ui new file mode 100644 index 0000000..49e8788 --- /dev/null +++ b/Plugins/SqlEnterpriseFormatter/sqlenterpriseformatter.ui @@ -0,0 +1,671 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>SqlEnterpriseFormatter</class> + <widget class="QWidget" name="SqlEnterpriseFormatter"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>612</width> + <height>464</height> + </rect> + </property> + <property name="windowTitle"> + <string>Form</string> + </property> + <layout class="QVBoxLayout" name="verticalLayout"> + <property name="leftMargin"> + <number>0</number> + </property> + <property name="topMargin"> + <number>0</number> + </property> + <property name="rightMargin"> + <number>0</number> + </property> + <property name="bottomMargin"> + <number>0</number> + </property> + <item> + <widget class="QSplitter" name="splitter"> + <property name="orientation"> + <enum>Qt::Vertical</enum> + </property> + <widget class="QTabWidget" name="tabWidget"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Expanding" vsizetype="Expanding"> + <horstretch>0</horstretch> + <verstretch>1</verstretch> + </sizepolicy> + </property> + <property name="currentIndex"> + <number>0</number> + </property> + <widget class="QWidget" name="indentTab"> + <attribute name="title"> + <string>Indentation</string> + </attribute> + <layout class="QGridLayout" name="gridLayout"> + <property name="topMargin"> + <number>4</number> + </property> + <property name="bottomMargin"> + <number>4</number> + </property> + <item row="1" column="0" colspan="3"> + <widget class="QCheckBox" name="checkBox"> + <property name="text"> + <string>Line up keywords in multi-line queries</string> + </property> + <property name="cfg" stdset="0"> + <string>SqlEnterpriseFormatter.LineUpKeywords</string> + </property> + </widget> + </item> + <item row="2" column="0" colspan="3"> + <widget class="QCheckBox" name="checkBox_2"> + <property name="text"> + <string>Indent contents of parenthesis block</string> + </property> + <property name="cfg" stdset="0"> + <string>SqlEnterpriseFormatter.IndentParenthesisBlock</string> + </property> + </widget> + </item> + <item row="4" column="1"> + <spacer name="verticalSpacer"> + <property name="orientation"> + <enum>Qt::Vertical</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>20</width> + <height>187</height> + </size> + </property> + </spacer> + </item> + <item row="3" column="0"> + <widget class="QLabel" name="label"> + <property name="text"> + <string>Tab size:</string> + </property> + </widget> + </item> + <item row="3" column="2"> + <widget class="QSpinBox" name="spinBox"> + <property name="cfg" stdset="0"> + <string>SqlEnterpriseFormatter.TabSize</string> + </property> + </widget> + </item> + </layout> + </widget> + <widget class="QWidget" name="newLinesTab"> + <attribute name="title"> + <string>New lines</string> + </attribute> + <layout class="QVBoxLayout" name="horizontalLayout_2"> + <property name="topMargin"> + <number>4</number> + </property> + <property name="bottomMargin"> + <number>4</number> + </property> + <item> + <widget class="QScrollArea" name="scrollArea"> + <property name="styleSheet"> + <string notr="true">#scrollArea { background: transparent; }</string> + </property> + <property name="frameShape"> + <enum>QFrame::NoFrame</enum> + </property> + <property name="frameShadow"> + <enum>QFrame::Plain</enum> + </property> + <property name="lineWidth"> + <number>0</number> + </property> + <property name="widgetResizable"> + <bool>true</bool> + </property> + <widget class="QWidget" name="scrollAreaWidgetContents"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>578</width> + <height>350</height> + </rect> + </property> + <property name="styleSheet"> + <string notr="true">#scrollAreaWidgetContents { background: transparent; }</string> + </property> + <layout class="QVBoxLayout" name="verticalLayout_5"> + <property name="leftMargin"> + <number>0</number> + </property> + <property name="topMargin"> + <number>0</number> + </property> + <property name="rightMargin"> + <number>0</number> + </property> + <property name="bottomMargin"> + <number>0</number> + </property> + <item> + <widget class="QCheckBox" name="checkBox_3"> + <property name="text"> + <string>Before opening parenthesis in column definitions</string> + </property> + <property name="cfg" stdset="0"> + <string>SqlEnterpriseFormatter.NlBeforeOpenParDef</string> + </property> + </widget> + </item> + <item> + <widget class="QCheckBox" name="checkBox_5"> + <property name="text"> + <string>After opening parenthesis in column definitions</string> + </property> + <property name="cfg" stdset="0"> + <string>SqlEnterpriseFormatter.NlAfterOpenParDef</string> + </property> + </widget> + </item> + <item> + <widget class="QCheckBox" name="checkBox_4"> + <property name="text"> + <string>Before closing parenthesis in column definitions</string> + </property> + <property name="cfg" stdset="0"> + <string>SqlEnterpriseFormatter.NlBeforeCloseParDef</string> + </property> + </widget> + </item> + <item> + <widget class="QCheckBox" name="checkBox_6"> + <property name="text"> + <string>After closing parenthesis in column definitions</string> + </property> + <property name="cfg" stdset="0"> + <string>SqlEnterpriseFormatter.NlAfterCloseParDef</string> + </property> + </widget> + </item> + <item> + <widget class="QCheckBox" name="checkBox_7"> + <property name="text"> + <string>Before opening parenthesis in expressions</string> + </property> + <property name="cfg" stdset="0"> + <string>SqlEnterpriseFormatter.NlBeforeOpenParExpr</string> + </property> + </widget> + </item> + <item> + <widget class="QCheckBox" name="checkBox_8"> + <property name="text"> + <string>After opening parenthesis in expressions</string> + </property> + <property name="cfg" stdset="0"> + <string>SqlEnterpriseFormatter.NlAfterOpenParExpr</string> + </property> + </widget> + </item> + <item> + <widget class="QCheckBox" name="checkBox_9"> + <property name="text"> + <string>Before closing parenthesis in expressions</string> + </property> + <property name="cfg" stdset="0"> + <string>SqlEnterpriseFormatter.NlBeforeCloseParExpr</string> + </property> + </widget> + </item> + <item> + <widget class="QCheckBox" name="checkBox_10"> + <property name="text"> + <string>After closing parenthesis in expressions</string> + </property> + <property name="cfg" stdset="0"> + <string>SqlEnterpriseFormatter.NlAfterCloseParExpr</string> + </property> + </widget> + </item> + <item> + <widget class="QCheckBox" name="checkBox_32"> + <property name="text"> + <string>After *JOIN keywords in FROM clause</string> + </property> + <property name="cfg" stdset="0"> + <string>SqlEnterpriseFormatter.NlAfterJoinStmt</string> + </property> + </widget> + </item> + <item> + <widget class="QCheckBox" name="checkBox_31"> + <property name="text"> + <string>Put each column constraint in CREATE TABLE into new line</string> + </property> + <property name="cfg" stdset="0"> + <string>SqlEnterpriseFormatter.NlBetweenConstraints</string> + </property> + </widget> + </item> + <item> + <widget class="QCheckBox" name="checkBox_11"> + <property name="text"> + <string>After comma</string> + </property> + <property name="cfg" stdset="0"> + <string>SqlEnterpriseFormatter.NlAfterComma</string> + </property> + </widget> + </item> + <item> + <widget class="QCheckBox" name="checkBox_12"> + <property name="text"> + <string>After comma in expressions</string> + </property> + <property name="cfg" stdset="0"> + <string>SqlEnterpriseFormatter.NlAfterCommaInExpr</string> + </property> + </widget> + </item> + <item> + <widget class="QCheckBox" name="checkBox_13"> + <property name="text"> + <string>After semicolon</string> + </property> + <property name="cfg" stdset="0"> + <string>SqlEnterpriseFormatter.NlAfterSemicolon</string> + </property> + </widget> + </item> + <item> + <widget class="QCheckBox" name="checkBox_25"> + <property name="text"> + <string>Never before semicolon</string> + </property> + <property name="cfg" stdset="0"> + <string>SqlEnterpriseFormatter.NlNeverBeforeSemicolon</string> + </property> + </widget> + </item> + <item> + <spacer name="verticalSpacer_2"> + <property name="orientation"> + <enum>Qt::Vertical</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>20</width> + <height>40</height> + </size> + </property> + </spacer> + </item> + </layout> + </widget> + </widget> + </item> + <item> + <widget class="QWidget" name="widget_2" native="true"> + <layout class="QVBoxLayout" name="verticalLayout_2"> + <property name="leftMargin"> + <number>0</number> + </property> + <property name="topMargin"> + <number>0</number> + </property> + <property name="rightMargin"> + <number>0</number> + </property> + <property name="bottomMargin"> + <number>0</number> + </property> + </layout> + </widget> + </item> + </layout> + <zorder>widget_2</zorder> + <zorder>scrollArea</zorder> + </widget> + <widget class="QWidget" name="whiteSpacesTab"> + <attribute name="title"> + <string>White spaces</string> + </attribute> + <layout class="QVBoxLayout" name="horizontalLayout_3"> + <property name="topMargin"> + <number>4</number> + </property> + <property name="bottomMargin"> + <number>4</number> + </property> + <item> + <widget class="QScrollArea" name="scrollArea_2"> + <property name="styleSheet"> + <string notr="true">#scrollArea_2 { background: transparent; }</string> + </property> + <property name="frameShape"> + <enum>QFrame::NoFrame</enum> + </property> + <property name="frameShadow"> + <enum>QFrame::Plain</enum> + </property> + <property name="lineWidth"> + <number>10</number> + </property> + <property name="widgetResizable"> + <bool>true</bool> + </property> + <widget class="QWidget" name="scrollAreaWidgetContents_2"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>424</width> + <height>325</height> + </rect> + </property> + <property name="styleSheet"> + <string notr="true">#scrollAreaWidgetContents_2 { background: transparent; }</string> + </property> + <layout class="QVBoxLayout" name="verticalLayout_6"> + <property name="leftMargin"> + <number>0</number> + </property> + <property name="topMargin"> + <number>0</number> + </property> + <property name="rightMargin"> + <number>0</number> + </property> + <property name="bottomMargin"> + <number>0</number> + </property> + <item> + <widget class="QCheckBox" name="checkBox_14"> + <property name="text"> + <string>Before comma in lists</string> + </property> + <property name="cfg" stdset="0"> + <string>SqlEnterpriseFormatter.SpaceBeforeCommaInList</string> + </property> + </widget> + </item> + <item> + <widget class="QCheckBox" name="checkBox_15"> + <property name="text"> + <string>After comma in lists</string> + </property> + <property name="cfg" stdset="0"> + <string>SqlEnterpriseFormatter.SpaceAfterCommaInList</string> + </property> + </widget> + </item> + <item> + <widget class="QCheckBox" name="checkBox_16"> + <property name="text"> + <string>Before opening parenthesis</string> + </property> + <property name="cfg" stdset="0"> + <string>SqlEnterpriseFormatter.SpaceBeforeOpenPar</string> + </property> + </widget> + </item> + <item> + <widget class="QCheckBox" name="checkBox_17"> + <property name="text"> + <string>After opening parenthesis</string> + </property> + <property name="cfg" stdset="0"> + <string>SqlEnterpriseFormatter.SpaceAfterOpenPar</string> + </property> + </widget> + </item> + <item> + <widget class="QCheckBox" name="checkBox_18"> + <property name="text"> + <string>Before closing parenthesis</string> + </property> + <property name="cfg" stdset="0"> + <string>SqlEnterpriseFormatter.SpaceBeforeClosePar</string> + </property> + </widget> + </item> + <item> + <widget class="QCheckBox" name="checkBox_19"> + <property name="text"> + <string>After closing parenthesis</string> + </property> + <property name="cfg" stdset="0"> + <string>SqlEnterpriseFormatter.SpaceAfterClosePar</string> + </property> + </widget> + </item> + <item> + <widget class="QCheckBox" name="checkBox_29"> + <property name="text"> + <string>No space between SQL function name and opening parenthesis</string> + </property> + <property name="cfg" stdset="0"> + <string>SqlEnterpriseFormatter.NoSpaceAfterFunctionName</string> + </property> + </widget> + </item> + <item> + <widget class="QCheckBox" name="checkBox_20"> + <property name="text"> + <string>Before dot operator (in path to database object)</string> + </property> + <property name="cfg" stdset="0"> + <string>SqlEnterpriseFormatter.SpaceBeforeDot</string> + </property> + </widget> + </item> + <item> + <widget class="QCheckBox" name="checkBox_21"> + <property name="text"> + <string>After dot operator (in path to database object)</string> + </property> + <property name="cfg" stdset="0"> + <string>SqlEnterpriseFormatter.SpaceAfterDot</string> + </property> + </widget> + </item> + <item> + <widget class="QCheckBox" name="checkBox_22"> + <property name="text"> + <string>Before mathematical operator</string> + </property> + <property name="cfg" stdset="0"> + <string>SqlEnterpriseFormatter.SpaceBeforeMathOp</string> + </property> + </widget> + </item> + <item> + <widget class="QCheckBox" name="checkBox_23"> + <property name="text"> + <string>After mathematical operator</string> + </property> + <property name="cfg" stdset="0"> + <string>SqlEnterpriseFormatter.SpaceAfterMathOp</string> + </property> + </widget> + </item> + <item> + <widget class="QCheckBox" name="checkBox_30"> + <property name="text"> + <string>Never before comma</string> + </property> + <property name="cfg" stdset="0"> + <string>SqlEnterpriseFormatter.SpaceNeverBeforeComma</string> + </property> + </widget> + </item> + <item> + <widget class="QCheckBox" name="checkBox_24"> + <property name="text"> + <string>Never before semicolon</string> + </property> + <property name="cfg" stdset="0"> + <string>SqlEnterpriseFormatter.SpaceNeverBeforeSemicolon</string> + </property> + </widget> + </item> + <item> + <spacer name="verticalSpacer_3"> + <property name="orientation"> + <enum>Qt::Vertical</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>20</width> + <height>40</height> + </size> + </property> + </spacer> + </item> + </layout> + </widget> + </widget> + </item> + <item> + <widget class="QWidget" name="widget_3" native="true"> + <layout class="QVBoxLayout" name="verticalLayout_3"> + <property name="leftMargin"> + <number>0</number> + </property> + <property name="topMargin"> + <number>0</number> + </property> + <property name="rightMargin"> + <number>0</number> + </property> + <property name="bottomMargin"> + <number>0</number> + </property> + </layout> + </widget> + </item> + </layout> + </widget> + <widget class="QWidget" name="namesTab"> + <attribute name="title"> + <string>Names</string> + </attribute> + <layout class="QGridLayout" name="gridLayout_2"> + <property name="topMargin"> + <number>4</number> + </property> + <property name="bottomMargin"> + <number>4</number> + </property> + <item row="5" column="0"> + <spacer name="verticalSpacer_4"> + <property name="orientation"> + <enum>Qt::Vertical</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>20</width> + <height>40</height> + </size> + </property> + </spacer> + </item> + <item row="3" column="0"> + <widget class="QLabel" name="label_2"> + <property name="text"> + <string>Preferred name wrapper</string> + </property> + </widget> + </item> + <item row="3" column="1"> + <widget class="ConfigComboBox" name="comboBox"> + <property name="cfg" stdset="0"> + <string>SqlEnterpriseFormatter.PrefferedWrapper</string> + </property> + <property name="modelName" stdset="0"> + <string>SqlEnterpriseFormatter.Wrappers</string> + </property> + </widget> + </item> + <item row="2" column="0" colspan="2"> + <widget class="QCheckBox" name="checkBox_28"> + <property name="text"> + <string>Always use name wrapping</string> + </property> + <property name="cfg" stdset="0"> + <string>SqlEnterpriseFormatter.AlwaysUseNameWrapping</string> + </property> + </widget> + </item> + <item row="1" column="0" colspan="2"> + <widget class="QCheckBox" name="checkBox_27"> + <property name="text"> + <string>Uppercase data type names</string> + </property> + <property name="cfg" stdset="0"> + <string>SqlEnterpriseFormatter.UppercaseDataTypes</string> + </property> + </widget> + </item> + <item row="0" column="0" colspan="2"> + <widget class="QCheckBox" name="checkBox_26"> + <property name="text"> + <string>Uppercase keywords</string> + </property> + <property name="cfg" stdset="0"> + <string>SqlEnterpriseFormatter.UppercaseKeywords</string> + </property> + </widget> + </item> + </layout> + </widget> + </widget> + <widget class="QGroupBox" name="groupBox"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Preferred" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>2</verstretch> + </sizepolicy> + </property> + <property name="title"> + <string>Preview</string> + </property> + <layout class="QVBoxLayout" name="verticalLayout_4"> + <item> + <widget class="SqlView" name="previewEdit"> + <property name="cfg" stdset="0"> + <string>SqlEnterpriseFormatter.PreviewCode</string> + </property> + <property name="preview" stdset="0"> + <bool>true</bool> + </property> + </widget> + </item> + </layout> + </widget> + </widget> + </item> + </layout> + </widget> + <customwidgets> + <customwidget> + <class>ConfigComboBox</class> + <extends>QComboBox</extends> + <header>common/configcombobox.h</header> + </customwidget> + <customwidget> + <class>SqlView</class> + <extends>QPlainTextEdit</extends> + <header>sqlview.h</header> + </customwidget> + </customwidgets> + <resources/> + <connections/> +</ui> diff --git a/Plugins/SqlEnterpriseFormatter/sqlenterpriseformatter_global.h b/Plugins/SqlEnterpriseFormatter/sqlenterpriseformatter_global.h new file mode 100644 index 0000000..e600191 --- /dev/null +++ b/Plugins/SqlEnterpriseFormatter/sqlenterpriseformatter_global.h @@ -0,0 +1,12 @@ +#ifndef SQLENTERPRISEFORMATTER_GLOBAL_H +#define SQLENTERPRISEFORMATTER_GLOBAL_H + +#include <QtCore/qglobal.h> + +#if defined(SQLENTERPRISEFORMATTER_LIBRARY) +# define SQLENTERPRISEFORMATTERSHARED_EXPORT Q_DECL_EXPORT +#else +# define SQLENTERPRISEFORMATTERSHARED_EXPORT Q_DECL_IMPORT +#endif + +#endif // SQLENTERPRISEFORMATTER_GLOBAL_H |
