diff options
| author | 2014-12-06 17:33:25 -0500 | |
|---|---|---|
| committer | 2014-12-06 17:33:25 -0500 | |
| commit | 7167ce41b61d2ba2cdb526777a4233eb84a3b66a (patch) | |
| tree | a35c14143716e1f2c98f808c81f89426045a946f /SQLiteStudio3/coreSQLiteStudio/parser/statementtokenbuilder.h | |
Imported Upstream version 2.99.6upstream/2.99.6
Diffstat (limited to 'SQLiteStudio3/coreSQLiteStudio/parser/statementtokenbuilder.h')
| -rw-r--r-- | SQLiteStudio3/coreSQLiteStudio/parser/statementtokenbuilder.h | 290 |
1 files changed, 290 insertions, 0 deletions
diff --git a/SQLiteStudio3/coreSQLiteStudio/parser/statementtokenbuilder.h b/SQLiteStudio3/coreSQLiteStudio/parser/statementtokenbuilder.h new file mode 100644 index 0000000..fcf23be --- /dev/null +++ b/SQLiteStudio3/coreSQLiteStudio/parser/statementtokenbuilder.h @@ -0,0 +1,290 @@ +#ifndef STATEMENTTOKENBUILDER_H +#define STATEMENTTOKENBUILDER_H + +#include "token.h" +#include "ast/sqliteconflictalgo.h" +#include "ast/sqlitesortorder.h" +#include "dialect.h" + +class SqliteStatement; + +/** + * @brief Builder producing token list basing on certain inputs. + * + * This builder provides several methods to build list of tokens from various input values. It can produce + * token list for entire AST objects, or it can produce token list for list of names, etc. + * + * Token builder is used in SqliteStatement derived classes to rebuild SqliteStatement::tokens basing on the + * values in their class members. + * + * Typical use case: + * @code + * TokenList SqliteCreateView::rebuildTokensFromContents() + * { + * StatementTokenBuilder builder; + * + * builder.withKeyword("CREATE").withSpace(); + * if (tempKw) + * builder.withKeyword("TEMP").withSpace(); + * else if (temporaryKw) + * builder.withKeyword("TEMPORARY").withSpace(); + * + * builder.withKeyword("VIEW").withSpace(); + * if (ifNotExists) + * builder.withKeyword("IF").withSpace().withKeyword("NOT").withSpace().withKeyword("EXISTS").withSpace(); + * + * if (dialect == Dialect::Sqlite3 && !database.isNull()) + * builder.withOther(database, dialect).withOperator("."); + * + * builder.withOther(view, dialect).withSpace().withKeyword("AS").withStatement(select); + * + * return builder.build(); + * } + * @endcode + */ +class StatementTokenBuilder +{ + public: + /** + * @brief Adds keyword token. + * @param value Value of the keyword token. + * @return Reference to the builder for the further building. + * + * Keyword \p value gets converted to upper case. + */ + StatementTokenBuilder& withKeyword(const QString& value); + + /** + * @brief Adds "other" token (some object name, or other word). + * @param value Value for the token. + * @return Reference to the builder for the further building. + * + * This is used for table names, etc. The \p value is quoted just as passed. + */ + StatementTokenBuilder& withOther(const QString& value); + + /** + * @brief Adds "other" token (some object name, or other word). + * @param value Value for the token. + * @param dialect Dialect used for wrapping the value. + * @return Reference to the builder for the further building. + * + * The \p value is wrapped with the proper wrapper using wrapObjIfNeeded(). + * + * @overload + */ + StatementTokenBuilder& withOther(const QString& value, Dialect dialect); + + /** + * @brief Adds string using double-quote wrapping. + * @param value Value for the token. + * @param dialect Dialect used for wrapping the value if double-quote could not be used. + * @return Reference to the builder for the further building. + * + * The \p value is wrapped with double quote, but if it's not possible then the proper wrapper is used by wrapObjIfNeeded(). + * + * @overload + */ + StatementTokenBuilder& withStringPossiblyOther(const QString& value, Dialect dialect); + + /** + * @brief Adds list of "other" tokens. + * @param value List of values for tokens. + * @param dialect Dialect used for wrapping values. + * @param separator Optional value for separator tokens. + * @return Reference to the builder for the further building. + * + * Given the input \p value, this method produces list of tokens. Additionally it can put extra separator + * token between all produced tokens using the \p separator value. To skip separator tokens pass + * an empty string as the separator value. + */ + StatementTokenBuilder& withOtherList(const QList<QString>& value, Dialect dialect, const QString& separator = ","); + + /** + * @brief Adds list of "other" tokens. + * @param value List of values for tokens. + * @param separator Optional value for separator tokens. + * @return Reference to the builder for the further building. + * + * Works just like the other withOtherList() method, except it doesn't wrap values with wrapObjIfNeeded(). + * + * @overload + */ + StatementTokenBuilder& withOtherList(const QList<QString>& value, const QString& separator = ","); + + /** + * @brief Adds operator token. + * @param value Value of the operator (";", "+", etc). + * @return Reference to the builder for the further building. + */ + StatementTokenBuilder& withOperator(const QString& value); + + /** + * @brief Adds comment token. + * @param value Comment value, including start/end characters of the comment. + * @return Reference to the builder for the further building. + */ + StatementTokenBuilder& withComment(const QString& value); + + /** + * @brief Adds decimal number token. + * @param value Value for the token. + * @return Reference to the builder for the further building. + */ + StatementTokenBuilder& withFloat(double value); + + /** + * @brief Add integer numer token. + * @param value Value for the token. + * @return Reference to the builder for the further building. + */ + StatementTokenBuilder& withInteger(int value); + + /** + * @brief Adds bind parameter token. + * @param value Name of the bind parameter, including ":" or "@" at the begining. + * @return Reference to the builder for the further building. + */ + StatementTokenBuilder& withBindParam(const QString& value); + + /** + * @brief Adds left parenthesis token (<tt>"("</tt>). + * @return Reference to the builder for the further building. + */ + StatementTokenBuilder& withParLeft(); + + /** + * @brief Adds right parenthesis token (<tt>")"</tt>). + * @return Reference to the builder for the further building. + */ + StatementTokenBuilder& withParRight(); + + /** + * @brief Adds a single whitespace token. + * @return Reference to the builder for the further building. + */ + StatementTokenBuilder& withSpace(); + + /** + * @brief Adds BLOB value token. + * @param value BLOB value for the token. + * @return Reference to the builder for the further building. + */ + StatementTokenBuilder& withBlob(const QString& value); + + /** + * @brief Adds string value token. + * @param value Value for the token. + * @return Reference to the builder for the further building. + * + * The string is wrapped with single quote characters if it's not wrapped yet. + */ + StatementTokenBuilder& withString(const QString& value); + + /** + * @brief Adds set of tokens represeting "ON CONFLICT" statement. + * @param onConflict Conflict resolution algorithm to build for. + * @return Reference to the builder for the further building. + * + * If algorithm is SqliteConflictAlgo::null, no tokens are added. + */ + StatementTokenBuilder& withConflict(SqliteConflictAlgo onConflict); + + /** + * @brief Adds space and <tt>"ASC"/"DESC"</tt> token. + * @param sortOrder Sort order to use. + * @return Reference to the builder for the further building. + * + * If the sort order is SqliteSortOrder::null, no tokens are added. + */ + StatementTokenBuilder& withSortOrder(SqliteSortOrder sortOrder); + + /** + * @brief Adds set of tokens representing entire statement. + * @param stmt Statement to add tokens for. + * @return Reference to the builder for the further building. + */ + StatementTokenBuilder& withStatement(SqliteStatement* stmt); + + /** + * @brief Adds already defined list of tokens to this builder. + * @param tokens Tokens to add. + * @return Reference to the builder for the further building. + */ + StatementTokenBuilder& withTokens(TokenList tokens); + + /** + * @brief Adds literal value token (integer, decimal, string, BLOB). + * @param value Value for the token. + * @return Reference to the builder for the further building. + * + * This method tries to convert given \p value to integer, + * then to double, then it checks if the value has format <tt>X'...'</tt> + * and if if succeeded at any of those steps, then it adds appropriate + * token. If none of above succeeded, then the string token is added. + */ + StatementTokenBuilder& withLiteralValue(const QVariant& value); + + /** + * @brief Adds tokens representing list of entire statements. + * @param stmtList List of statements to add tokens for. + * @param separator Optional separator to be used for separator tokens. + * @return Reference to the builder for the further building. + * + * This method is very similar to withOtherList(), except it works + * on the entire statements. + */ + template <class T> + StatementTokenBuilder& withStatementList(QList<T*> stmtList, const QString& separator = ",") + { + bool first = true; + foreach (T* stmt, stmtList) + { + if (!first) + { + if (!separator.isEmpty()) + withOperator(separator); + + withSpace(); + } + withStatement(stmt); + first = false; + } + return *this; + } + + /** + * @brief Provides all tokens added so far as a compat token list. + * @return List of tokens built so far. + */ + TokenList build() const; + + /** + * @brief Cleans up all tokens added so far. + */ + void clear(); + + private: + /** + * @brief Adds token of given type and value. + * @param type Type of the token to add. + * @param value Value for the token to add. + * @return Reference to the builder for the further building. + */ + StatementTokenBuilder& with(Token::Type type, const QString& value); + + /** + * @brief List of tokens added so far. + */ + TokenList tokens; + + /** + * @brief Current character position index. + * + * This index is used to generate proper values for Token::start and Token::end. + * Each added token increments this index by the value length. + */ + int currentIdx = 0; +}; + +#endif // STATEMENTTOKENBUILDER_H |
