diff options
Diffstat (limited to 'SQLiteStudio3/coreSQLiteStudio/common')
| -rw-r--r-- | SQLiteStudio3/coreSQLiteStudio/common/table.cpp | 30 | ||||
| -rw-r--r-- | SQLiteStudio3/coreSQLiteStudio/common/table.h | 18 | ||||
| -rw-r--r-- | SQLiteStudio3/coreSQLiteStudio/common/utils.cpp | 21 | ||||
| -rw-r--r-- | SQLiteStudio3/coreSQLiteStudio/common/utils.h | 13 | ||||
| -rw-r--r-- | SQLiteStudio3/coreSQLiteStudio/common/utils_sql.cpp | 147 | ||||
| -rw-r--r-- | SQLiteStudio3/coreSQLiteStudio/common/utils_sql.h | 6 |
6 files changed, 223 insertions, 12 deletions
diff --git a/SQLiteStudio3/coreSQLiteStudio/common/table.cpp b/SQLiteStudio3/coreSQLiteStudio/common/table.cpp index a9b0f16..20a9864 100644 --- a/SQLiteStudio3/coreSQLiteStudio/common/table.cpp +++ b/SQLiteStudio3/coreSQLiteStudio/common/table.cpp @@ -90,3 +90,33 @@ int qHash(AliasedTable table) {
return qHash(table.getDatabase() + "." + table.getTable() + " " + table.getTableAlias());
}
+
+DbAndTable::DbAndTable() :
+ Table()
+{
+}
+
+DbAndTable::DbAndTable(Db *db, const QString &database, const QString &table) :
+ Table(database, table), db(db)
+{
+}
+
+DbAndTable::DbAndTable(const DbAndTable &other) :
+ Table(other), db(other.db)
+{
+}
+
+int DbAndTable::operator ==(const DbAndTable &other) const
+{
+ return other.database == this->database && other.table == this->table && other.db == this->db;
+}
+
+Db *DbAndTable::getDb() const
+{
+ return db;
+}
+
+void DbAndTable::setDb(Db *value)
+{
+ db = value;
+}
diff --git a/SQLiteStudio3/coreSQLiteStudio/common/table.h b/SQLiteStudio3/coreSQLiteStudio/common/table.h index 5cc4570..5460148 100644 --- a/SQLiteStudio3/coreSQLiteStudio/common/table.h +++ b/SQLiteStudio3/coreSQLiteStudio/common/table.h @@ -4,6 +4,8 @@ #include "coreSQLiteStudio_global.h"
#include <QString>
+class Db;
+
class API_EXPORT Table
{
public:
@@ -25,6 +27,22 @@ class API_EXPORT Table QString table;
};
+class API_EXPORT DbAndTable : public Table
+{
+public:
+ DbAndTable();
+ DbAndTable(Db* db, const QString& database, const QString& table);
+ DbAndTable(const DbAndTable& other);
+
+ int operator ==(const DbAndTable& other) const;
+
+ Db *getDb() const;
+ void setDb(Db *value);
+
+protected:
+ Db* db = nullptr;
+};
+
class API_EXPORT AliasedTable : public Table
{
public:
diff --git a/SQLiteStudio3/coreSQLiteStudio/common/utils.cpp b/SQLiteStudio3/coreSQLiteStudio/common/utils.cpp index 6cf1892..e3d2e47 100644 --- a/SQLiteStudio3/coreSQLiteStudio/common/utils.cpp +++ b/SQLiteStudio3/coreSQLiteStudio/common/utils.cpp @@ -694,6 +694,9 @@ QString getOsString() case QSysInfo::WV_WINDOWS8_1: os += " 8.1"; break; + case QSysInfo::WV_WINDOWS10: + os += " 10"; + break; case QSysInfo::WV_32s: case QSysInfo::WV_95: case QSysInfo::WV_98: @@ -707,6 +710,7 @@ QString getOsString() case QSysInfo::WV_CE_5: case QSysInfo::WV_CE_6: case QSysInfo::WV_CE_based: + case QSysInfo::WV_None: break; } #elif defined(Q_OS_LINUX) @@ -742,6 +746,12 @@ QString getOsString() case QSysInfo::MV_10_9: os += " 10.9 Mavericks"; break; + case QSysInfo::MV_10_10: + os += " 10.10 Yosemite"; + break; + case QSysInfo::MV_10_11: + os += " 10.11 El Capitan"; + break; case QSysInfo::MV_9: case QSysInfo::MV_10_0: case QSysInfo::MV_10_1: @@ -755,6 +765,13 @@ QString getOsString() case QSysInfo::MV_IOS_6_1: case QSysInfo::MV_IOS_7_0: case QSysInfo::MV_IOS_7_1: + case QSysInfo::MV_IOS_8_0: + case QSysInfo::MV_IOS_8_1: + case QSysInfo::MV_IOS_8_2: + case QSysInfo::MV_IOS_8_3: + case QSysInfo::MV_IOS_8_4: + case QSysInfo::MV_IOS_9_0: + case QSysInfo::MV_None: case QSysInfo::MV_Unknown: break; } @@ -899,9 +916,9 @@ QStringList concat(const QList<QStringList>& list) return result; } -QString doubleToString(double val) +QString doubleToString(const QVariant& val) { - return QString::number(val, 'g', 16); + return val.toString(); } void sortWithReferenceList(QList<QString>& listToSort, const QList<QString>& referenceList, Qt::CaseSensitivity cs) diff --git a/SQLiteStudio3/coreSQLiteStudio/common/utils.h b/SQLiteStudio3/coreSQLiteStudio/common/utils.h index 934e70a..c56a4db 100644 --- a/SQLiteStudio3/coreSQLiteStudio/common/utils.h +++ b/SQLiteStudio3/coreSQLiteStudio/common/utils.h @@ -87,6 +87,17 @@ int indexOf(const QList<T>& list, std::function<bool(const T&)> predicate) return -1; } +template <class T> +T* findFirst(const QList<T*>& list, std::function<bool(T*)> predicate) +{ + for (T* item : list) + { + if (predicate(item)) + return item; + } + return nullptr; +} + /** * @brief Returns only those elements from the list, which passed the filter. * @tparam T type for which the filter will be applied for. It should match the type in the list and in the function argument. @@ -231,7 +242,7 @@ API_EXPORT bool renameBetweenPartitions(const QString& src, const QString& dst); API_EXPORT bool isWritableRecursively(const QString& dir); API_EXPORT QString encryptRsa(const QString& input, const QString& modulus, const QString& exponent); API_EXPORT QString decryptRsa(const QString& input, const QString& modulus, const QString& exponent); -API_EXPORT QString doubleToString(double val); +API_EXPORT QString doubleToString(const QVariant& val); /** * @brief Sorts string list using reference list for ordering. diff --git a/SQLiteStudio3/coreSQLiteStudio/common/utils_sql.cpp b/SQLiteStudio3/coreSQLiteStudio/common/utils_sql.cpp index 5c7e7e9..ad37ff0 100644 --- a/SQLiteStudio3/coreSQLiteStudio/common/utils_sql.cpp +++ b/SQLiteStudio3/coreSQLiteStudio/common/utils_sql.cpp @@ -4,6 +4,7 @@ #include "parser/token.h" #include "parser/lexer.h" #include "parser/keywords.h" +#include "log.h" #include <QHash> #include <QPair> #include <QString> @@ -368,11 +369,23 @@ QString removeComments(const QString& value) return tokens.detokenize(); } +void splitQueriesUpdateCaseWhenDepth(Token::Type type, const QString& value, int& caseWhenDepth) +{ + if (type != Token::KEYWORD) + return; + + if (value == "CASE") + caseWhenDepth++; + else if (value == "END" && caseWhenDepth > 0) + caseWhenDepth--; +} + QList<TokenList> splitQueries(const TokenList& tokenizedQuery, bool* complete) { QList<TokenList> queries; TokenList currentQueryTokens; QString value; + int caseWhenDepth = 0; int createTriggerMeter = 0; bool insideTrigger = false; bool completeQuery = false; @@ -384,16 +397,19 @@ QList<TokenList> splitQueries(const TokenList& tokenizedQuery, bool* complete) if (insideTrigger) { - if (token->type == Token::KEYWORD && value == "END") + if (token->type == Token::KEYWORD && value == "END" && caseWhenDepth <= 0 && caseWhenDepth == 0) { insideTrigger = false; completeQuery = true; } currentQueryTokens << token; + splitQueriesUpdateCaseWhenDepth(token->type, value, caseWhenDepth); continue; } + splitQueriesUpdateCaseWhenDepth(token->type, value, caseWhenDepth); + if (token->type == Token::KEYWORD) { if (value == "CREATE" || value == "TRIGGER" || value == "BEGIN") @@ -407,6 +423,7 @@ QList<TokenList> splitQueries(const TokenList& tokenizedQuery, bool* complete) else if (token->type == Token::OPERATOR && value == ";") { createTriggerMeter = 0; + caseWhenDepth = 0; currentQueryTokens << token; queries << currentQueryTokens; currentQueryTokens.clear(); @@ -427,9 +444,114 @@ QList<TokenList> splitQueries(const TokenList& tokenizedQuery, bool* complete) return queries; } -QStringList splitQueries(const QString& sql, Dialect dialect, bool keepEmptyQueries, bool* complete) +QStringList quickSplitQueries(const QString& sql, bool keepEmptyQueries, bool removeComments) +{ + QChar c; + bool inString = false; + bool inMultiLineComment = false; + bool inSingleLineComment = false; + QStringList queries; + QString query; + QString trimmed; + for (int i = 0, total = sql.size(); i < total; ++i) + { + c = sql[i]; + + // String + if (inString) + { + query += c; + if (c == '\'') + { + inString = false; + } + continue; + } + + // One-line comment + if (inSingleLineComment) + { + if (!removeComments) + query += c; + + if (c == '\r' && (i + 1) < total && sql[i+1] == '\n') + { + if (!removeComments) + query += '\n'; + + i++; + inSingleLineComment = false; + } + else if (c == '\n' || c == '\r') + inSingleLineComment = false; + + continue; + } + + // Multi-line comment + if (inMultiLineComment) + { + if (!removeComments) + query += c; + + if (c == '*' && (i + 1) < total && sql[i+1] == '/') + { + if (!removeComments) + query += '/'; + + i++; + inMultiLineComment = false; + } + + continue; + } + + // Everything rest + if (c == '\'') + { + query += c; + inString = true; + } + else if (c == '-' && (i + 1) < total && sql[i+1] == '-') + { + inSingleLineComment = true; + i++; + if (!removeComments) + query += "--"; + } + else if (c == '/' && (i + 1) < total && sql[i+1] == '*') + { + inMultiLineComment = true; + i++; + if (!removeComments) + query += "/*"; + } + else if (c == ';') + { + query += c; + if (keepEmptyQueries || (!(trimmed = query.trimmed()).isEmpty() && trimmed != ";")) + queries << query; + + query.clear(); + } + else + { + query += c; + } + } + + if (!query.isNull() && (!(trimmed = query.trimmed()).isEmpty() && trimmed != ";")) + queries << query; + + return queries; +} + +QStringList splitQueries(const QString& sql, Dialect dialect, bool keepEmptyQueries, bool removeComments, bool* complete) { TokenList tokens = Lexer::tokenize(sql, dialect); + if (removeComments) + tokens = tokens.filterOut(Token::COMMENT); + QList<TokenList> tokenizedQueries = splitQueries(tokens, complete); QString query; @@ -437,7 +559,7 @@ QStringList splitQueries(const QString& sql, Dialect dialect, bool keepEmptyQuer foreach (const TokenList& queryTokens, tokenizedQueries) { query = queryTokens.detokenize(); - if (keepEmptyQueries || !query.trimmed().isEmpty()) + if (keepEmptyQueries || (!query.trimmed().isEmpty() && query.trimmed() != ";")) queries << query; } @@ -452,7 +574,7 @@ QString getQueryWithPosition(const QStringList& queries, int position, int* star if (startPos) *startPos = 0; - foreach (const QString& query, queries) + for (const QString& query : queries) { length = query.length(); if (position >= currentPos && position < currentPos+length) @@ -479,9 +601,9 @@ QString getQueryWithPosition(const QStringList& queries, int position, int* star return QString::null; } -QString getQueryWithPosition(const QString& queries, int position, Dialect dialect, int* startPos) +QString getQueryWithPosition(const QString& queries, int position, int* startPos) { - QStringList queryList = splitQueries(queries, dialect); + QStringList queryList = quickSplitQueries(queries); return getQueryWithPosition(queryList, position, startPos); } @@ -665,7 +787,7 @@ QStringList valueListToSqlList(const QVariantList& values, Dialect dialect) argList << value.toString(); break; case QVariant::Double: - argList << doubleToString(value.toDouble()); + argList << doubleToString(value); break; case QVariant::Bool: argList << QString::number(value.toInt()); @@ -694,3 +816,14 @@ QStringList wrapStrings(const QStringList& strList) return list; } + +QString trimQueryEnd(const QString &query) +{ + QString q = query.trimmed(); + while (q.endsWith(";")) + { + q.chop(1); + q = q.trimmed(); + } + return q; +} diff --git a/SQLiteStudio3/coreSQLiteStudio/common/utils_sql.h b/SQLiteStudio3/coreSQLiteStudio/common/utils_sql.h index ceccea0..1da3108 100644 --- a/SQLiteStudio3/coreSQLiteStudio/common/utils_sql.h +++ b/SQLiteStudio3/coreSQLiteStudio/common/utils_sql.h @@ -67,9 +67,10 @@ API_EXPORT bool isSystemTable(const QString& name); API_EXPORT bool isSystemIndex(const QString& name, Dialect dialect); API_EXPORT QString removeComments(const QString& value); API_EXPORT QList<TokenList> splitQueries(const TokenList& tokenizedQueries, bool* complete = nullptr); -API_EXPORT QStringList splitQueries(const QString& sql, Dialect dialect, bool keepEmptyQueries = true, bool* complete = nullptr); +API_EXPORT QStringList splitQueries(const QString& sql, Dialect dialect, bool keepEmptyQueries = true, bool removeComments = false, bool* complete = nullptr); +API_EXPORT QStringList quickSplitQueries(const QString& sql, bool keepEmptyQueries = true, bool removeComments = false); API_EXPORT QString getQueryWithPosition(const QStringList& queries, int position, int* startPos = nullptr); -API_EXPORT QString getQueryWithPosition(const QString& queries, int position, Dialect dialect, int* startPos = nullptr); +API_EXPORT QString getQueryWithPosition(const QString& queries, int position, int* startPos = nullptr); API_EXPORT QList<QueryWithParamNames> getQueriesWithParamNames(const QString& query, Dialect dialect); API_EXPORT QList<QueryWithParamCount> getQueriesWithParamCount(const QString& query, Dialect dialect); API_EXPORT QueryWithParamNames getQueryWithParamNames(const QString& query, Dialect dialect); @@ -79,6 +80,7 @@ API_EXPORT QString commentAllSqlLines(const QString& sql); API_EXPORT QString getBindTokenName(const TokenPtr& token); API_EXPORT QueryAccessMode getQueryAccessMode(const QString& query, Dialect dialect, bool* isSelect = nullptr); API_EXPORT QStringList valueListToSqlList(const QList<QVariant>& values, Dialect dialect); +API_EXPORT QString trimQueryEnd(const QString& query); #endif // UTILS_SQL_H |
