diff options
| author | 2021-12-17 07:06:30 -0500 | |
|---|---|---|
| committer | 2021-12-17 07:06:30 -0500 | |
| commit | 1fdc150116cad39aae5c5da407c3312b47a59e3a (patch) | |
| tree | 123c79a4d7ad2d45781ba03ce939f7539fb428d8 /SQLiteStudio3/coreSQLiteStudio/common | |
| parent | feda8a7db8d1d7c5439aa8f8feef7cc0dd2b59a0 (diff) | |
New upstream version 3.3.3+dfsg1.upstream/3.3.3+dfsg1
Diffstat (limited to 'SQLiteStudio3/coreSQLiteStudio/common')
14 files changed, 346 insertions, 155 deletions
diff --git a/SQLiteStudio3/coreSQLiteStudio/common/bistrhash.cpp b/SQLiteStudio3/coreSQLiteStudio/common/bistrhash.cpp index 5f40521..5aac017 100644 --- a/SQLiteStudio3/coreSQLiteStudio/common/bistrhash.cpp +++ b/SQLiteStudio3/coreSQLiteStudio/common/bistrhash.cpp @@ -31,7 +31,7 @@ void BiStrHash::insert(const QString& left, const QString& right) lowerInverted.insert(right.toLower(), right); } -bool BiStrHash::containsLeft(const QString& left, Qt::CaseSensitivity cs) +bool BiStrHash::containsLeft(const QString& left, Qt::CaseSensitivity cs) const { if (cs == Qt::CaseSensitive) return hash.contains(left); @@ -39,7 +39,7 @@ bool BiStrHash::containsLeft(const QString& left, Qt::CaseSensitivity cs) return lowerHash.contains(left.toLower()); } -bool BiStrHash::containsRight(const QString& right, Qt::CaseSensitivity cs) +bool BiStrHash::containsRight(const QString& right, Qt::CaseSensitivity cs) const { if (cs == Qt::CaseSensitive) return inverted.contains(right); @@ -147,7 +147,10 @@ BiStrHash& BiStrHash::unite(const QHash<QString, QString>& other) { QHashIterator<QString, QString> it(other); while (it.hasNext()) - insert(it.next().key(), it.value()); + { + it.next(); + insert(it.key(), it.value()); + } return *this; } diff --git a/SQLiteStudio3/coreSQLiteStudio/common/bistrhash.h b/SQLiteStudio3/coreSQLiteStudio/common/bistrhash.h index 2089010..cec9b8a 100644 --- a/SQLiteStudio3/coreSQLiteStudio/common/bistrhash.h +++ b/SQLiteStudio3/coreSQLiteStudio/common/bistrhash.h @@ -60,7 +60,7 @@ class API_EXPORT BiStrHash * @param cs Case sensitivity flag.
* @return true if the key was matched in left side values, or false otherwise.
*/
- bool containsLeft(const QString& left, Qt::CaseSensitivity cs = Qt::CaseSensitive);
+ bool containsLeft(const QString& left, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
/**
* @brief Tests if given value is in the right values of the hash.
@@ -68,7 +68,7 @@ class API_EXPORT BiStrHash * @param cs Case sensitivity flag.
* @return true if the key was matched in right side values, or false otherwise.
*/
- bool containsRight(const QString& right, Qt::CaseSensitivity cs = Qt::CaseSensitive);
+ bool containsRight(const QString& right, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
/**
* @brief Removes entry matching given value in left-side values.
diff --git a/SQLiteStudio3/coreSQLiteStudio/common/column.cpp b/SQLiteStudio3/coreSQLiteStudio/common/column.cpp index cc282e6..852ff45 100644 --- a/SQLiteStudio3/coreSQLiteStudio/common/column.cpp +++ b/SQLiteStudio3/coreSQLiteStudio/common/column.cpp @@ -32,7 +32,55 @@ void Column::setColumn(const QString& value) column = value;
}
+QString Column::getDeclaredType() const
+{
+ return declaredType;
+}
+
+void Column::setDeclaredType(const QString& value)
+{
+ declaredType = value;
+}
+
int qHash(Column column)
{
- return qHash(column.getDatabase() + "." + column.getTable() + "." + column.getColumn());
+ return qHash(column.getDatabase() + "." + column.getTable() + "." + column.getColumn() + "/" + column.getDeclaredType());
+}
+
+AliasedColumn::AliasedColumn()
+{
+}
+
+AliasedColumn::AliasedColumn(const QString& database, const QString& table, const QString& column, const QString& alias) :
+ Column(database, table, column)
+{
+ setAlias(alias);
+}
+
+AliasedColumn::AliasedColumn(const AliasedColumn& other) :
+ Column(other)
+{
+ alias = other.alias;
+}
+
+int AliasedColumn::operator ==(const AliasedColumn& other) const
+{
+ return Column::operator==(other) && alias == other.alias;
+
+}
+
+QString AliasedColumn::getAlias() const
+{
+ return alias;
+}
+
+void AliasedColumn::setAlias(const QString& value)
+{
+ alias = value;
+}
+
+int qHash(AliasedColumn column)
+{
+ return qHash(column.getDatabase() + "." + column.getTable() + "." + column.getColumn() + "/" + column.getDeclaredType()
+ + "/" + column.getAlias());
}
diff --git a/SQLiteStudio3/coreSQLiteStudio/common/column.h b/SQLiteStudio3/coreSQLiteStudio/common/column.h index 18e5edd..4ddf3e1 100644 --- a/SQLiteStudio3/coreSQLiteStudio/common/column.h +++ b/SQLiteStudio3/coreSQLiteStudio/common/column.h @@ -17,10 +17,31 @@ struct API_EXPORT Column : public Table QString getColumn() const;
void setColumn(const QString& value);
+ QString getDeclaredType() const;
+ void setDeclaredType(const QString& value);
+
private:
QString column;
+ QString declaredType;
+};
+
+struct API_EXPORT AliasedColumn : public Column
+{
+ public:
+ AliasedColumn();
+ AliasedColumn(const QString& database, const QString& table, const QString& column, const QString& alias);
+ AliasedColumn(const AliasedColumn& other);
+
+ int operator ==(const AliasedColumn& other) const;
+
+ QString getAlias() const;
+ void setAlias(const QString& value);
+
+ private:
+ QString alias;
};
int API_EXPORT qHash(Column column);
+int API_EXPORT qHash(AliasedColumn column);
#endif // COLUMN_H
diff --git a/SQLiteStudio3/coreSQLiteStudio/common/compatibility.cpp b/SQLiteStudio3/coreSQLiteStudio/common/compatibility.cpp new file mode 100644 index 0000000..9676105 --- /dev/null +++ b/SQLiteStudio3/coreSQLiteStudio/common/compatibility.cpp @@ -0,0 +1,2 @@ +#include "compatibility.h" + diff --git a/SQLiteStudio3/coreSQLiteStudio/common/compatibility.h b/SQLiteStudio3/coreSQLiteStudio/common/compatibility.h new file mode 100644 index 0000000..5ed5c8b --- /dev/null +++ b/SQLiteStudio3/coreSQLiteStudio/common/compatibility.h @@ -0,0 +1,40 @@ +#ifndef COMPATIBILITY_H +#define COMPATIBILITY_H + +#include <QList> +#include <QSet> +#include <QHash> + +template <class T> +inline QSet<T> toSet(const QList<T>& list) +{ +#if (QT_VERSION >= QT_VERSION_CHECK(5, 14, 0)) + return QSet<T>(list.begin(), list.end()); +#else + return list.toSet(); +#endif +} + +template <class K, class V> +inline void unite(QHash<K, V>& h1, const QHash<K, V>& h2) +{ +#if (QT_VERSION >= QT_VERSION_CHECK(5, 15, 0)) + h1.insert(h2); +#else + h1.unite(h2); +#endif +} + +template <class T> +void sSort(T& collection) +{ + std::sort(collection.begin(), collection.end()); +} + +template <class T, class C> +void sSort(T& collection, C cmp) +{ + std::sort(collection.begin(), collection.end(), cmp); +} + +#endif // COMPATIBILITY_H diff --git a/SQLiteStudio3/coreSQLiteStudio/common/global.h b/SQLiteStudio3/coreSQLiteStudio/common/global.h index cfd8dc0..e09391a 100644 --- a/SQLiteStudio3/coreSQLiteStudio/common/global.h +++ b/SQLiteStudio3/coreSQLiteStudio/common/global.h @@ -39,6 +39,10 @@ var = nullptr; \ } +#define parser_safe_delete(var) \ + if (var) \ + delete var + #define static_char static constexpr const char #define static_qstring(N,V) const static QString N = QStringLiteral(V) diff --git a/SQLiteStudio3/coreSQLiteStudio/common/readwritelocker.cpp b/SQLiteStudio3/coreSQLiteStudio/common/readwritelocker.cpp index cdf8110..07752ff 100644 --- a/SQLiteStudio3/coreSQLiteStudio/common/readwritelocker.cpp +++ b/SQLiteStudio3/coreSQLiteStudio/common/readwritelocker.cpp @@ -11,9 +11,9 @@ ReadWriteLocker::ReadWriteLocker(QReadWriteLock* lock, Mode mode) init(lock, mode); } -ReadWriteLocker::ReadWriteLocker(QReadWriteLock* lock, const QString& query, Dialect dialect, bool noLock) +ReadWriteLocker::ReadWriteLocker(QReadWriteLock* lock, const QString& query, bool noLock) { - init(lock, getMode(query, dialect, noLock)); + init(lock, getMode(query, noLock)); } ReadWriteLocker::~ReadWriteLocker() @@ -47,12 +47,12 @@ void ReadWriteLocker::init(QReadWriteLock* lock, ReadWriteLocker::Mode mode) } } -ReadWriteLocker::Mode ReadWriteLocker::getMode(const QString &query, Dialect dialect, bool noLock) +ReadWriteLocker::Mode ReadWriteLocker::getMode(const QString &query, bool noLock) { if (noLock) return ReadWriteLocker::NONE; - QueryAccessMode queryMode = getQueryAccessMode(query, dialect); + QueryAccessMode queryMode = getQueryAccessMode(query); switch (queryMode) { case QueryAccessMode::READ: diff --git a/SQLiteStudio3/coreSQLiteStudio/common/readwritelocker.h b/SQLiteStudio3/coreSQLiteStudio/common/readwritelocker.h index cac9368..e12c4e6 100644 --- a/SQLiteStudio3/coreSQLiteStudio/common/readwritelocker.h +++ b/SQLiteStudio3/coreSQLiteStudio/common/readwritelocker.h @@ -2,7 +2,6 @@ #define READWRITELOCKER_H #include "coreSQLiteStudio_global.h" -#include "dialect.h" class QReadLocker; class QWriteLocker; @@ -31,7 +30,7 @@ class API_EXPORT ReadWriteLocker }; ReadWriteLocker(QReadWriteLock* lock, Mode mode); - ReadWriteLocker(QReadWriteLock* lock, const QString& query, Dialect dialect, bool noLock); + ReadWriteLocker(QReadWriteLock* lock, const QString& query, bool noLock); virtual ~ReadWriteLocker(); /** @@ -53,7 +52,7 @@ class API_EXPORT ReadWriteLocker * * In case of WITH statement it filters out the "WITH clause" and then checks for SELECT keyword. */ - static ReadWriteLocker::Mode getMode(const QString& query, Dialect dialect, bool noLock); + static ReadWriteLocker::Mode getMode(const QString& query, bool noLock); private: void init(QReadWriteLock* lock, Mode mode); diff --git a/SQLiteStudio3/coreSQLiteStudio/common/signalwait.cpp b/SQLiteStudio3/coreSQLiteStudio/common/signalwait.cpp index 4a22e83..45472f4 100644 --- a/SQLiteStudio3/coreSQLiteStudio/common/signalwait.cpp +++ b/SQLiteStudio3/coreSQLiteStudio/common/signalwait.cpp @@ -1,6 +1,6 @@ #include "signalwait.h" #include <QCoreApplication> -#include <QTime> +#include <QElapsedTimer> SignalWait::SignalWait(QObject* object, const char* signal) : QObject() @@ -10,7 +10,7 @@ SignalWait::SignalWait(QObject* object, const char* signal) : bool SignalWait::wait(int msTimeout) { - QTime timer(0, 0, 0, msTimeout); + QElapsedTimer timer; timer.start(); while (!called && !failed && timer.elapsed() < msTimeout) QCoreApplication::processEvents(QEventLoop::ExcludeUserInputEvents); diff --git a/SQLiteStudio3/coreSQLiteStudio/common/utils.cpp b/SQLiteStudio3/coreSQLiteStudio/common/utils.cpp index fd40355..0b95a85 100644 --- a/SQLiteStudio3/coreSQLiteStudio/common/utils.cpp +++ b/SQLiteStudio3/coreSQLiteStudio/common/utils.cpp @@ -2,6 +2,7 @@ #include "common/global.h" #include "dbobjecttype.h" #include "rsa/RSA.h" +#include "common/compatibility.h" #include <QTextCodec> #include <QString> #include <QSet> @@ -12,7 +13,9 @@ #include <QRegularExpression> #include <QDir> #include <QByteArray> +#include <QBitArray> #include <QDataStream> +#include <QRandomGenerator> #ifdef Q_OS_LINUX #include <sys/utsname.h> @@ -68,7 +71,7 @@ QChar charAt(const QString& str, int pos) int rand(int min, int max) { - return qrand() % (max-min) + min; + return QRandomGenerator::system()->generate() % (max-min) + min; } QString randStr(int length, bool numChars, bool whiteSpaces) @@ -414,7 +417,7 @@ QString shortest(const QStringList& strList) QString longestCommonPart(const QStringList& strList) { if (strList.size() == 0) - return QString::null; + return QString(); QString common; QString first = strList.first(); @@ -626,8 +629,8 @@ QStringList textCodecNames() for (const QByteArray& codec : codecs) nameSet << QString::fromLatin1(codec.constData()); - names = nameSet.toList(); - qSort(names); + names = nameSet.values(); + sSort(names); return names; } @@ -975,7 +978,7 @@ QString doubleToString(const QVariant& val) void sortWithReferenceList(QList<QString>& listToSort, const QList<QString>& referenceList, Qt::CaseSensitivity cs) { - qSort(listToSort.begin(), listToSort.end(), [referenceList, cs](const QString& s1, const QString& s2) -> bool + sSort(listToSort, [referenceList, cs](const QString& s1, const QString& s2) -> bool { int idx1 = indexOf(referenceList, s1, cs); int idx2 = indexOf(referenceList, s2, cs); @@ -1031,3 +1034,66 @@ QString readFileContents(const QString& path, QString* err) return contents; } + + +uint qHash(const QVariant& var) +{ + if (!var.isValid() || var.isNull()) + return -1; + + switch (var.type()) + { + case QVariant::Int: + return qHash(var.toInt()); + case QVariant::UInt: + return qHash(var.toUInt()); + case QVariant::Bool: + return qHash(var.toUInt()); + case QVariant::Double: + return qHash(var.toUInt()); + case QVariant::LongLong: + return qHash(var.toLongLong()); + case QVariant::ULongLong: + return qHash(var.toULongLong()); + case QVariant::String: + return qHash(var.toString()); + case QVariant::Char: + return qHash(var.toChar()); + case QVariant::StringList: + return qHash(var.toString()); + case QVariant::ByteArray: + return qHash(var.toByteArray()); + case QVariant::Date: + case QVariant::Time: + case QVariant::DateTime: + case QVariant::Url: + case QVariant::Locale: + case QVariant::RegExp: + return qHash(var.toString()); + case QVariant::Hash: + return qHash(var.toHash()); + case QVariant::Map: + return qHash(var.toMap()); + case QVariant::List: + return qHash(var.toList()); + case QVariant::BitArray: + return qHash(var.toBitArray()); + case QVariant::Size: + case QVariant::SizeF: + case QVariant::Rect: + case QVariant::LineF: + case QVariant::Line: + case QVariant::RectF: + case QVariant::Point: + case QVariant::PointF: + // not supported yet + break; + case QVariant::UserType: + case QVariant::Invalid: + default: + return -3; + } + + // could not generate a hash for the given variant + return -2; +} diff --git a/SQLiteStudio3/coreSQLiteStudio/common/utils.h b/SQLiteStudio3/coreSQLiteStudio/common/utils.h index 24ea150..f7317e2 100644 --- a/SQLiteStudio3/coreSQLiteStudio/common/utils.h +++ b/SQLiteStudio3/coreSQLiteStudio/common/utils.h @@ -140,6 +140,33 @@ QList<T> concat(const QList<QList<T>>& list) return result; } +template <class T, typename R = QList<T>> +R concat(const QList<QSet<T>>& list) +{ + R result; + for (const QSet<T>& itemSet : list) + for (const T& subitem : itemSet) + result << subitem; + + return result; +} + +template <class T> +QSet<T> concatSet(const QList<QSet<T>>& list) +{ + return concat<T, QSet<T>>(list); +} + +template <class T> +QSet<T> concat(const QSet<QSet<T>>& list) +{ + QSet<T> result; + for (const QSet<T>& item : list) + result.unite(item); + + return result; +} + API_EXPORT QStringList concat(const QList<QStringList>& list); /** @@ -293,6 +320,8 @@ void removeDuplicates(QList<T>& list) } } +API_EXPORT uint qHash(const QVariant& var); + API_EXPORT QByteArray serializeToBytes(const QVariant& value); API_EXPORT QVariant deserializeFromBytes(const QByteArray& bytes); diff --git a/SQLiteStudio3/coreSQLiteStudio/common/utils_sql.cpp b/SQLiteStudio3/coreSQLiteStudio/common/utils_sql.cpp index b5642ec..c8d63e1 100644 --- a/SQLiteStudio3/coreSQLiteStudio/common/utils_sql.cpp +++ b/SQLiteStudio3/coreSQLiteStudio/common/utils_sql.cpp @@ -15,7 +15,6 @@ QString invalidIdCharacters = "[]()\"'@*.,+-=/%&|:; \t\n<>"; QHash<NameWrapper,QPair<QChar,QChar>> wrapperChars; QHash<NameWrapper,QPair<QChar,bool>> wrapperEscapedEnding; QList<NameWrapper> sqlite3Wrappers; -QList<NameWrapper> sqlite2Wrappers; void initUtilsSql() { @@ -33,22 +32,19 @@ void initUtilsSql() << NameWrapper::BRACKET << NameWrapper::QUOTE << NameWrapper::BACK_QUOTE; - sqlite2Wrappers << NameWrapper::DOUBLE_QUOTE - << NameWrapper::BRACKET - << NameWrapper::QUOTE; qRegisterMetaType<SqlQueryPtr>("SqlQueryPtr"); } -bool doesObjectNeedWrapping(const QString& str, Dialect dialect) +bool doesObjectNeedWrapping(const QString& str) { if (str.isEmpty()) return true; - if (isObjWrapped(str, dialect)) + if (isObjWrapped(str)) return false; - if (isKeyword(str, dialect)) + if (isKeyword(str)) return true; for (int i = 0; i < str.size(); i++) @@ -66,41 +62,36 @@ bool doesObjectNeedWrapping(const QChar& c) return invalidIdCharacters.indexOf(c) >= 0; } -bool isObjectWrapped(const QChar& c, Dialect dialect) -{ - return !doesObjectNeedWrapping(c, dialect); -} - bool isObjectWrapped(const QChar& c) { return !doesObjectNeedWrapping(c); } -QString wrapObjIfNeeded(const QString& obj, Dialect dialect, NameWrapper favWrapper) +QString wrapObjIfNeeded(const QString& obj, NameWrapper favWrapper) { - if (doesObjectNeedWrapping(obj, dialect)) - return wrapObjName(obj, dialect, favWrapper); + if (doesObjectNeedWrapping(obj)) + return wrapObjName(obj, favWrapper); return obj; } -QString wrapObjIfNeeded(const QString& obj, Dialect dialect, bool useDoubleQuoteForEmptyValue, NameWrapper favWrapper) +QString wrapObjIfNeeded(const QString& obj, bool useDoubleQuoteForEmptyValue, NameWrapper favWrapper) { - return wrapObjIfNeeded(obj, dialect, ((useDoubleQuoteForEmptyValue && obj.isEmpty()) ? NameWrapper::DOUBLE_QUOTE : favWrapper)); + return wrapObjIfNeeded(obj, ((useDoubleQuoteForEmptyValue && obj.isEmpty()) ? NameWrapper::DOUBLE_QUOTE : favWrapper)); } -QString wrapObjName(const QString& obj, Dialect dialect, bool useDoubleQuoteForEmptyValue, NameWrapper favWrapper) +QString wrapObjName(const QString& obj, bool useDoubleQuoteForEmptyValue, NameWrapper favWrapper) { - return wrapObjName(obj, dialect, ((useDoubleQuoteForEmptyValue && obj.isEmpty()) ? NameWrapper::DOUBLE_QUOTE : favWrapper)); + return wrapObjName(obj, ((useDoubleQuoteForEmptyValue && obj.isEmpty()) ? NameWrapper::DOUBLE_QUOTE : favWrapper)); } -QString wrapObjName(const QString& obj, Dialect dialect, NameWrapper favWrapper) +QString wrapObjName(const QString& obj, NameWrapper favWrapper) { QString result = obj; if (result.isNull()) result = ""; - QPair<QChar,QChar> wrapChars = getQuoteCharacter(result, dialect, favWrapper); + QPair<QChar,QChar> wrapChars = getQuoteCharacter(result, favWrapper); if (wrapChars.first.isNull() || wrapChars.second.isNull()) { @@ -112,20 +103,9 @@ QString wrapObjName(const QString& obj, Dialect dialect, NameWrapper favWrapper) return result; } -QString wrapObjName(const QString& obj, NameWrapper wrapper) +QPair<QChar,QChar> getQuoteCharacter(QString& obj, NameWrapper favWrapper) { - QString result = obj; - if (wrapper == NameWrapper::null) - return result; - - result.prepend(wrapperChars[wrapper].first); - result.append(wrapperChars[wrapper].second); - return result; -} - -QPair<QChar,QChar> getQuoteCharacter(QString& obj, Dialect dialect, NameWrapper favWrapper) -{ - QList<NameWrapper> wrappers = (dialect == Dialect::Sqlite3) ? sqlite3Wrappers : sqlite2Wrappers; + QList<NameWrapper> wrappers = sqlite3Wrappers; // Move favourite wrapper to front of list if (wrappers.contains(favWrapper)) @@ -150,30 +130,27 @@ QPair<QChar,QChar> getQuoteCharacter(QString& obj, Dialect dialect, NameWrapper return QPair<QChar,QChar>(); } -QList<QString> wrapObjNames(const QList<QString>& objList, Dialect dialect, NameWrapper favWrapper) +QList<QString> wrapObjNames(const QList<QString>& objList, NameWrapper favWrapper) { QList<QString> results; for (int i = 0; i < objList.size(); i++) - results << wrapObjName(objList[i], dialect, favWrapper); + results << wrapObjName(objList[i], favWrapper); return results; } -QList<QString> wrapObjNamesIfNeeded(const QList<QString>& objList, Dialect dialect, NameWrapper favWrapper) +QList<QString> wrapObjNamesIfNeeded(const QList<QString>& objList, NameWrapper favWrapper) { QList<QString> results; for (int i = 0; i < objList.size(); i++) - results << wrapObjIfNeeded(objList[i], dialect, favWrapper); + results << wrapObjIfNeeded(objList[i], favWrapper); return results; } -QList<NameWrapper> getAllNameWrappers(Dialect dialect) +QList<NameWrapper> getAllNameWrappers() { - if (dialect == Dialect::Sqlite3) - return {NameWrapper::DOUBLE_QUOTE, NameWrapper::BRACKET, NameWrapper::BACK_QUOTE, NameWrapper::QUOTE}; - else - return {NameWrapper::DOUBLE_QUOTE, NameWrapper::BRACKET, NameWrapper::QUOTE}; + return {NameWrapper::DOUBLE_QUOTE, NameWrapper::BRACKET, NameWrapper::BACK_QUOTE, NameWrapper::QUOTE}; } QString wrapValueIfNeeded(const QString& str) @@ -183,7 +160,7 @@ QString wrapValueIfNeeded(const QString& str) QString wrapValueIfNeeded(const QVariant& value) { - if (value.canConvert(QMetaType::LongLong) || value.canConvert(QMetaType::Double)) + if (isNumeric(value)) return value.toString(); return wrapString(value.toString()); @@ -199,6 +176,9 @@ QString wrapString(const QString& str) bool doesStringNeedWrapping(const QString& str) { + if (str.size() == 0) + return false; + return str[0] == '\'' && str[str.length()-1] == '\''; } @@ -258,13 +238,13 @@ QString stripEndingSemicolon(const QString& str) return str; } -QString stripObjName(const QString &str, Dialect dialect) +QString stripObjName(const QString &str) { QString newStr = str; - return stripObjName(newStr, dialect); + return stripObjName(newStr); } -QString stripObjName(QString &str, Dialect dialect) +QString stripObjName(QString &str) { if (str.isNull()) return str; @@ -272,15 +252,15 @@ QString stripObjName(QString &str, Dialect dialect) if (str.length() <= 1) return str; - if (!isObjWrapped(str, dialect)) + if (!isObjWrapped(str)) return str; return str.mid(1, str.length()-2); } -bool isObjWrapped(const QString& str, Dialect dialect) +bool isObjWrapped(const QString& str) { - return getObjWrapper(str, dialect) != NameWrapper::null; + return getObjWrapper(str) != NameWrapper::null; } bool doesNotContainEndingWrapperChar(const QString& str, NameWrapper wrapper) @@ -300,19 +280,12 @@ bool doesNotContainEndingWrapperChar(const QString& str, NameWrapper wrapper) return true; } -NameWrapper getObjWrapper(const QString& str, Dialect dialect) +NameWrapper getObjWrapper(const QString& str) { if (str.isEmpty()) return NameWrapper::null; - QList<NameWrapper> wrappers; - - if (dialect == Dialect::Sqlite2) - wrappers = sqlite2Wrappers; - else - wrappers = sqlite3Wrappers; - - for (NameWrapper wrapper : wrappers) + for (NameWrapper wrapper : sqlite3Wrappers) { QPair<QChar,QChar> chars = wrapperChars[wrapper]; if (str[0] == chars.first && str[str.length()-1] == chars.second && doesNotContainEndingWrapperChar(str, wrapper)) @@ -321,15 +294,9 @@ NameWrapper getObjWrapper(const QString& str, Dialect dialect) return NameWrapper::null; } -bool isWrapperChar(const QChar& c, Dialect dialect) +bool isWrapperChar(const QChar& c) { - QList<NameWrapper> wrappers; - if (dialect == Dialect::Sqlite2) - wrappers = sqlite2Wrappers; - else - wrappers = sqlite3Wrappers; - - for (NameWrapper wrapper : wrappers) + for (NameWrapper wrapper : sqlite3Wrappers) { QPair<QChar,QChar> chars = wrapperChars[wrapper]; if (c == chars.first || c == chars.second) @@ -343,12 +310,12 @@ int qHash(NameWrapper wrapper) return (uint)wrapper; } -QString getPrefixDb(const QString& origDbName, Dialect dialect) +QString getPrefixDb(const QString& origDbName) { if (origDbName.isEmpty()) return "main"; else - return wrapObjIfNeeded(origDbName, dialect); + return wrapObjIfNeeded(origDbName); } bool isSystemTable(const QString &name) @@ -356,35 +323,24 @@ bool isSystemTable(const QString &name) return name.startsWith("sqlite_"); } -bool isSystemIndex(const QString &name, Dialect dialect) +bool isSystemIndex(const QString &name) { - switch (dialect) - { - case Dialect::Sqlite3: - return name.startsWith("sqlite_autoindex_"); - case Dialect::Sqlite2: - { - QRegExp re("*(*autoindex*)*"); - re.setPatternSyntax(QRegExp::Wildcard); - return re.exactMatch(name); - } - } - return false; + return name.startsWith("sqlite_autoindex_"); } -TokenPtr stripObjName(TokenPtr token, Dialect dialect) +TokenPtr stripObjName(TokenPtr token) { if (!token) return token; - token->value = stripObjName(token->value, dialect); + token->value = stripObjName(token->value); return token; } QString removeComments(const QString& value) { - Lexer lexer(Dialect::Sqlite3); + Lexer lexer; TokenList tokens = lexer.tokenize(value); while (tokens.remove(Token::COMMENT)) continue; @@ -569,9 +525,9 @@ QStringList quickSplitQueries(const QString& sql, bool keepEmptyQueries, bool re return queries; } -QStringList splitQueries(const QString& sql, Dialect dialect, bool keepEmptyQueries, bool removeComments, bool* complete) +QStringList splitQueries(const QString& sql, bool keepEmptyQueries, bool removeComments, bool* complete) { - TokenList tokens = Lexer::tokenize(sql, dialect); + TokenList tokens = Lexer::tokenize(sql); if (removeComments) tokens = tokens.filterOut(Token::COMMENT); @@ -621,12 +577,12 @@ QString getQueryWithPosition(const QStringList& queries, int position, int* star if (startPos) *startPos = -1; - return QString::null; + return QString(); } QString getQueryWithPosition(const QString& queries, int position, int* startPos) { - QStringList queryList = quickSplitQueries(queries); + QStringList queryList = splitQueries(queries); return getQueryWithPosition(queryList, position, startPos); } @@ -641,11 +597,11 @@ QString trimBindParamPrefix(const QString& param) return param; } -QList<QueryWithParamNames> getQueriesWithParamNames(const QString& query, Dialect dialect) +QList<QueryWithParamNames> getQueriesWithParamNames(const QString& query) { QList<QueryWithParamNames> results; - TokenList allTokens = Lexer::tokenize(query, dialect); + TokenList allTokens = Lexer::tokenize(query); QList<TokenList> queries = splitQueries(allTokens); QString queryStr; @@ -663,11 +619,11 @@ QList<QueryWithParamNames> getQueriesWithParamNames(const QString& query, Dialec return results; } -QList<QueryWithParamCount> getQueriesWithParamCount(const QString& query, Dialect dialect) +QList<QueryWithParamCount> getQueriesWithParamCount(const QString& query) { QList<QueryWithParamCount> results; - TokenList allTokens = Lexer::tokenize(query, dialect); + TokenList allTokens = Lexer::tokenize(query); QList<TokenList> queries = splitQueries(allTokens); QString queryStr; @@ -681,9 +637,9 @@ QList<QueryWithParamCount> getQueriesWithParamCount(const QString& query, Dialec return results; } -QueryWithParamNames getQueryWithParamNames(const QString& query, Dialect dialect) +QueryWithParamNames getQueryWithParamNames(const QString& query) { - TokenList allTokens = Lexer::tokenize(query, dialect); + TokenList allTokens = Lexer::tokenize(query); QStringList paramNames; for (const TokenPtr& token : allTokens.filter(Token::BIND_PARAM)) @@ -692,9 +648,9 @@ QueryWithParamNames getQueryWithParamNames(const QString& query, Dialect dialect return QueryWithParamNames(query, paramNames); } -QueryWithParamCount getQueryWithParamCount(const QString& query, Dialect dialect) +QueryWithParamCount getQueryWithParamCount(const QString& query) { - TokenList allTokens = Lexer::tokenize(query, dialect); + TokenList allTokens = Lexer::tokenize(query); return QueryWithParamCount(query, allTokens.filter(Token::BIND_PARAM).size()); } @@ -719,14 +675,14 @@ QString getBindTokenName(const TokenPtr& token) return token->value.mid(1); } -QueryAccessMode getQueryAccessMode(const QString& query, Dialect dialect, bool* isSelect) +QueryAccessMode getQueryAccessMode(const QString& query, bool* isSelect) { static QStringList readOnlyCommands = {"ANALYZE", "EXPLAIN", "PRAGMA", "SELECT"}; if (isSelect) *isSelect = false; - TokenList tokens = Lexer::tokenize(query, dialect); + TokenList tokens = Lexer::tokenize(query); int keywordIdx = tokens.indexOf(Token::KEYWORD); if (keywordIdx < 0) return QueryAccessMode::WRITE; @@ -790,7 +746,7 @@ QueryAccessMode getQueryAccessMode(const QString& query, Dialect dialect, bool* return QueryAccessMode::WRITE; } -QStringList valueListToSqlList(const QVariantList& values, Dialect dialect) +QStringList valueListToSqlList(const QVariantList& values) { QStringList argList; for (const QVariant& value : values) @@ -816,13 +772,8 @@ QStringList valueListToSqlList(const QVariantList& values, Dialect dialect) argList << QString::number(value.toInt()); break; case QVariant::ByteArray: - { - if (dialect == Dialect::Sqlite3) // version 2 will go to the regular string processing - { - argList << "X'" + value.toByteArray().toHex().toUpper() + "'"; - break; - } - } + argList << "X'" + value.toByteArray().toHex().toUpper() + "'"; + break; default: argList << wrapString(escapeString(value.toString())); break; @@ -850,3 +801,24 @@ QString trimQueryEnd(const QString &query) } return q; } + +SqliteDataType toSqliteDataType(const QString& typeStr) +{ + QString upperType = typeStr.trimmed().toUpper(); + if (upperType == "INTEGER") + return SqliteDataType::INTEGER; + + if (upperType == "REAL") + return SqliteDataType::REAL; + + if (upperType == "TEXT") + return SqliteDataType::TEXT; + + if (upperType == "BLOB") + return SqliteDataType::BLOB; + + if (upperType == "NULL") + return SqliteDataType::_NULL; + + return SqliteDataType::UNKNOWN; +} diff --git a/SQLiteStudio3/coreSQLiteStudio/common/utils_sql.h b/SQLiteStudio3/coreSQLiteStudio/common/utils_sql.h index 1da3108..b9cfdcf 100644 --- a/SQLiteStudio3/coreSQLiteStudio/common/utils_sql.h +++ b/SQLiteStudio3/coreSQLiteStudio/common/utils_sql.h @@ -1,7 +1,6 @@ #ifndef UTILS_SQL_H #define UTILS_SQL_H -#include "dialect.h" #include "parser/token.h" #include "coreSQLiteStudio_global.h" #include <QString> @@ -25,27 +24,36 @@ enum class QueryAccessMode WRITE }; +enum class SqliteDataType +{ + UNKNOWN = -1, + _NULL = 0, + INTEGER = 1, + REAL = 2, + TEXT = 3, + BLOB = 4 +}; + typedef QPair<QString,QStringList> QueryWithParamNames; typedef QPair<QString,int> QueryWithParamCount; API_EXPORT void initUtilsSql(); -API_EXPORT bool doesObjectNeedWrapping(const QString& str, Dialect dialect); +API_EXPORT SqliteDataType toSqliteDataType(const QString& typeStr); +API_EXPORT bool doesObjectNeedWrapping(const QString& str); API_EXPORT bool doesObjectNeedWrapping(const QChar& c); -API_EXPORT bool isObjectWrapped(const QChar& c, Dialect dialect); API_EXPORT bool isObjectWrapped(const QChar& c); API_EXPORT bool doesStringNeedWrapping(const QString& str); API_EXPORT bool isStringWrapped(const QString& str); -API_EXPORT QString wrapObjIfNeeded(const QString& obj, Dialect dialect, NameWrapper favWrapper = NameWrapper::null); -API_EXPORT QString wrapObjIfNeeded(const QString& obj, Dialect dialect, bool useDoubleQuoteForEmptyValue, NameWrapper favWrapper = NameWrapper::null); -API_EXPORT QString wrapObjName(const QString& obj, Dialect dialect, NameWrapper favWrapper = NameWrapper::null); -API_EXPORT QString wrapObjName(const QString& obj, Dialect dialect, bool useDoubleQuoteForEmptyValue, NameWrapper favWrapper = NameWrapper::null); -API_EXPORT QString wrapObjName(const QString& obj, NameWrapper wrapper); -API_EXPORT TokenPtr stripObjName(TokenPtr token, Dialect dialect); -API_EXPORT QString stripObjName(const QString &str, Dialect dialect); -API_EXPORT QString stripObjName(QString& str, Dialect dialect); -API_EXPORT bool isObjWrapped(const QString& str, Dialect dialect); -API_EXPORT NameWrapper getObjWrapper(const QString& str, Dialect dialect); -API_EXPORT bool isWrapperChar(const QChar& c, Dialect dialect); +API_EXPORT QString wrapObjIfNeeded(const QString& obj, NameWrapper favWrapper = NameWrapper::null); +API_EXPORT QString wrapObjIfNeeded(const QString& obj, bool useDoubleQuoteForEmptyValue, NameWrapper favWrapper = NameWrapper::null); +API_EXPORT QString wrapObjName(const QString& obj, NameWrapper favWrapper = NameWrapper::null); +API_EXPORT QString wrapObjName(const QString& obj, bool useDoubleQuoteForEmptyValue, NameWrapper favWrapper = NameWrapper::null); +API_EXPORT TokenPtr stripObjName(TokenPtr token); +API_EXPORT QString stripObjName(const QString &str); +API_EXPORT QString stripObjName(QString& str); +API_EXPORT bool isObjWrapped(const QString& str); +API_EXPORT NameWrapper getObjWrapper(const QString& str); +API_EXPORT bool isWrapperChar(const QChar& c); API_EXPORT QString wrapString(const QString& str); API_EXPORT QStringList wrapStrings(const QStringList& strList); API_EXPORT QString wrapStringIfNeeded(const QString& str); @@ -54,32 +62,31 @@ API_EXPORT QString escapeString(const QString& str); API_EXPORT QString stripString(QString& str); API_EXPORT QString stripString(const QString& str); API_EXPORT QString stripEndingSemicolon(const QString& str); -API_EXPORT QPair<QChar,QChar> getQuoteCharacter(QString& obj, Dialect dialect, - NameWrapper favWrapper = NameWrapper::null); -API_EXPORT QList<QString> wrapObjNames(const QList<QString>& objList, Dialect dialect = Dialect::Sqlite3, NameWrapper favWrapper = NameWrapper::null); -API_EXPORT QList<QString> wrapObjNamesIfNeeded(const QList<QString>& objList, Dialect dialect, NameWrapper favWrapper = NameWrapper::null); -API_EXPORT QList<NameWrapper> getAllNameWrappers(Dialect dialect = Dialect::Sqlite3); +API_EXPORT QPair<QChar,QChar> getQuoteCharacter(QString& obj, NameWrapper favWrapper = NameWrapper::null); +API_EXPORT QList<QString> wrapObjNames(const QList<QString>& objList, NameWrapper favWrapper = NameWrapper::null); +API_EXPORT QList<QString> wrapObjNamesIfNeeded(const QList<QString>& objList, NameWrapper favWrapper = NameWrapper::null); +API_EXPORT QList<NameWrapper> getAllNameWrappers(); API_EXPORT QString wrapValueIfNeeded(const QString& str); API_EXPORT QString wrapValueIfNeeded(const QVariant& value); API_EXPORT int qHash(NameWrapper wrapper); -API_EXPORT QString getPrefixDb(const QString& origDbName, Dialect dialect); +API_EXPORT QString getPrefixDb(const QString& origDbName); API_EXPORT bool isSystemTable(const QString& name); -API_EXPORT bool isSystemIndex(const QString& name, Dialect dialect); +API_EXPORT bool isSystemIndex(const QString& name); 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 removeComments = false, bool* complete = nullptr); +API_EXPORT QStringList splitQueries(const QString& sql, 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, 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); -API_EXPORT QueryWithParamCount getQueryWithParamCount(const QString& query, Dialect dialect); +API_EXPORT QList<QueryWithParamNames> getQueriesWithParamNames(const QString& query); +API_EXPORT QList<QueryWithParamCount> getQueriesWithParamCount(const QString& query); +API_EXPORT QueryWithParamNames getQueryWithParamNames(const QString& query); +API_EXPORT QueryWithParamCount getQueryWithParamCount(const QString& query); API_EXPORT QString trimBindParamPrefix(const QString& param); 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 QueryAccessMode getQueryAccessMode(const QString& query, bool* isSelect = nullptr); +API_EXPORT QStringList valueListToSqlList(const QList<QVariant>& values); API_EXPORT QString trimQueryEnd(const QString& query); |
