From 5d9314f134ddd3dc4c853e398ac90ba247fb2e4f Mon Sep 17 00:00:00 2001 From: Unit 193 Date: Mon, 13 Jun 2016 18:42:42 -0400 Subject: Imported Upstream version 3.1.0 --- .../coreSQLiteStudio/common/bistrhash.cpp | 213 +++++++++++++++++++++ SQLiteStudio3/coreSQLiteStudio/common/bistrhash.h | 213 +++------------------ SQLiteStudio3/coreSQLiteStudio/common/sortedset.h | 64 +++++++ SQLiteStudio3/coreSQLiteStudio/common/strhash.h | 23 ++- SQLiteStudio3/coreSQLiteStudio/common/utils.cpp | 43 ++++- SQLiteStudio3/coreSQLiteStudio/common/utils.h | 40 +++- .../coreSQLiteStudio/common/utils_sql.cpp | 62 ++++++ SQLiteStudio3/coreSQLiteStudio/common/utils_sql.h | 4 + 8 files changed, 459 insertions(+), 203 deletions(-) create mode 100644 SQLiteStudio3/coreSQLiteStudio/common/bistrhash.cpp create mode 100644 SQLiteStudio3/coreSQLiteStudio/common/sortedset.h (limited to 'SQLiteStudio3/coreSQLiteStudio/common') diff --git a/SQLiteStudio3/coreSQLiteStudio/common/bistrhash.cpp b/SQLiteStudio3/coreSQLiteStudio/common/bistrhash.cpp new file mode 100644 index 0000000..091121c --- /dev/null +++ b/SQLiteStudio3/coreSQLiteStudio/common/bistrhash.cpp @@ -0,0 +1,213 @@ +#include "bistrhash.h" + +BiStrHash::BiStrHash(std::initializer_list > list) +{ + hash = QHash(list); + initInvertedAndLower(); +} + +BiStrHash::BiStrHash(const QHash& other) +{ + unite(other); +} + +BiStrHash::BiStrHash(const BiStrHash& other) : hash(other.hash), inverted(other.inverted), + lowerHash(other.lowerHash), lowerInverted(other.lowerInverted) +{ +} + +void BiStrHash::insert(const QString& left, const QString& right) +{ + if (lowerHash.contains(left.toLower())) + removeLeft(left, Qt::CaseInsensitive); + + if (lowerInverted.contains(right.toLower())) + removeRight(right, Qt::CaseInsensitive); + + inverted.insert(right, left); + hash.insert(left, right); + lowerHash.insert(left.toLower(), left); + lowerInverted.insert(right.toLower(), right); +} + +bool BiStrHash::containsLeft(const QString& left, Qt::CaseSensitivity cs) +{ + if (cs == Qt::CaseSensitive) + return hash.contains(left); + else + return lowerHash.contains(left.toLower()); +} + +bool BiStrHash::containsRight(const QString& right, Qt::CaseSensitivity cs) +{ + if (cs == Qt::CaseSensitive) + return inverted.contains(right); + else + return lowerInverted.contains(right.toLower()); +} + +int BiStrHash::removeLeft(const QString& left, Qt::CaseSensitivity cs) +{ + if (cs == Qt::CaseSensitive) + { + if (!hash.contains(left)) + return 0; + + inverted.remove(hash.value(left)); + hash.remove(left); + + return 1; + } + else + { + QString lowerLeft = left.toLower(); + if (!lowerHash.contains(lowerLeft)) + return 0; + + QString right = hash.value(lowerHash.value(lowerLeft)); + + hash.remove(inverted.value(right)); + inverted.remove(right); + lowerHash.remove(lowerLeft); + lowerInverted.remove(right.toLower()); + + return 1; + } +} + +int BiStrHash::removeRight(const QString& right, Qt::CaseSensitivity cs) +{ + if (cs == Qt::CaseSensitive) + { + if (!inverted.contains(right)) + return 0; + + hash.remove(inverted.value(right)); + inverted.remove(right); + + return 1; + } + else + { + QString lowerRight = right.toLower(); + if (!lowerInverted.contains(lowerRight)) + return 0; + + QString left = inverted.value(lowerInverted.value(lowerRight)); + + inverted.remove(hash.value(left)); + hash.remove(left); + lowerHash.remove(left.toLower()); + lowerInverted.remove(lowerRight); + + return 1; + } +} + +QString BiStrHash::takeLeft(const QString& left, Qt::CaseSensitivity cs) +{ + if (cs == Qt::CaseSensitive) + { + QString right = hash.take(left); + inverted.remove(right); + return right; + } + else + { + QString right = hash.take(lowerHash.take(left.toLower())); + inverted.remove(lowerInverted.take(right.toLower())); + return right; + } +} + +QString BiStrHash::takeRight(const QString& right, Qt::CaseSensitivity cs) +{ + if (cs == Qt::CaseSensitive) + { + QString left = inverted.take(right); + hash.remove(left); + return left; + } + else + { + QString left = inverted.take(lowerInverted.take(right.toLower())); + hash.remove(lowerHash.take(left.toLower())); + return left; + } +} + +BiStrHash& BiStrHash::unite(const BiStrHash& other) +{ + unite(other.hash); + return *this; +} + +BiStrHash& BiStrHash::unite(const QHash& other) +{ + QHashIterator it(other); + while (it.hasNext()) + insert(it.next().key(), it.value()); + + return *this; +} + +QString BiStrHash::valueByLeft(const QString& left, Qt::CaseSensitivity cs) const +{ + if (cs == Qt::CaseSensitive) + return hash.value(left); + else + return hash.value(lowerHash.value(left.toLower())); +} + +QString BiStrHash::valueByRight(const QString& right, Qt::CaseSensitivity cs) const +{ + if (cs == Qt::CaseSensitive) + return inverted.value(right); + else + return inverted.value(lowerInverted.value(right.toLower())); +} + +QStringList BiStrHash::leftValues() const +{ + return hash.keys(); +} + +QStringList BiStrHash::rightValues() const +{ + return inverted.keys(); +} + +QHashIterator BiStrHash::iterator() const +{ + return QHashIterator(hash); +} + +void BiStrHash::clear() +{ + hash.clear(); + inverted.clear(); + lowerHash.clear(); + lowerInverted.clear(); +} + +int BiStrHash::count() const +{ + return hash.count(); +} + +bool BiStrHash::isEmpty() const +{ + return hash.isEmpty(); +} + +void BiStrHash::initInvertedAndLower() +{ + QHashIterator it(hash); + while (it.hasNext()) + { + it.next(); + inverted[it.value()] = it.key(); + lowerHash[it.key().toLower()] = it.key(); + lowerInverted[it.value().toLower()] = it.value(); + } +} diff --git a/SQLiteStudio3/coreSQLiteStudio/common/bistrhash.h b/SQLiteStudio3/coreSQLiteStudio/common/bistrhash.h index 65c907b..2089010 100644 --- a/SQLiteStudio3/coreSQLiteStudio/common/bistrhash.h +++ b/SQLiteStudio3/coreSQLiteStudio/common/bistrhash.h @@ -2,6 +2,7 @@ #define BISTRHASH_H #include "bihash.h" +#include "coreSQLiteStudio_global.h" #include #include @@ -14,7 +15,7 @@ * * Just like BiHash, the BiStrHash doesn't provide operator[]. For more details see BiHash. */ -class BiStrHash +class API_EXPORT BiStrHash { public: /** @@ -26,11 +27,7 @@ class BiStrHash * @brief Creates pre-initialized hash. * @param list C++11 style initializer list, like: {{"x"="y"}, {"a"="b"}} */ - BiStrHash(std::initializer_list> list) - { - hash = QHash(list); - initInvertedAndLower(); - } + BiStrHash(std::initializer_list> list); /** * @brief Creates BiStrHash basing on QHash. @@ -39,17 +36,13 @@ class BiStrHash * Any conflicting values from the \p other hash will overwrite * current values in the hash. */ - BiStrHash(const QHash & other) - { - unite(other); - } + BiStrHash(const QHash & other); /** * @brief Copy constructor. * @param other Other hash to copy. */ - BiStrHash(const BiStrHash& other) : hash(other.hash), inverted(other.inverted), - lowerHash(other.lowerHash), lowerInverted(other.lowerInverted) {} + BiStrHash(const BiStrHash& other); /** * @brief Inserts entry into the hash. @@ -59,19 +52,7 @@ class BiStrHash * Inserting to the hash is done in case-insensitive manner, hence any conflicting * values matched with case insensitive method will be replaced with the new entry. */ - void insert(const QString& left, const QString& right) - { - if (lowerHash.contains(left.toLower())) - removeLeft(left, Qt::CaseInsensitive); - - if (lowerInverted.contains(right.toLower())) - removeRight(right, Qt::CaseInsensitive); - - inverted.insert(right, left); - hash.insert(left, right); - lowerHash.insert(left.toLower(), left); - lowerInverted.insert(right.toLower(), right); - } + void insert(const QString& left, const QString& right); /** * @brief Tests if given value is in the left values of the hash. @@ -79,13 +60,7 @@ class 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) - { - if (cs == Qt::CaseSensitive) - return hash.contains(left); - else - return lowerHash.contains(left.toLower()); - } + bool containsLeft(const QString& left, Qt::CaseSensitivity cs = Qt::CaseSensitive); /** * @brief Tests if given value is in the right values of the hash. @@ -93,13 +68,7 @@ class 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) - { - if (cs == Qt::CaseSensitive) - return inverted.contains(right); - else - return lowerInverted.contains(right.toLower()); - } + bool containsRight(const QString& right, Qt::CaseSensitivity cs = Qt::CaseSensitive); /** * @brief Removes entry matching given value in left-side values. @@ -107,34 +76,7 @@ class BiStrHash * @param cs Case sensitivity flag. * @return Number of entries removed. */ - int removeLeft(const QString& left, Qt::CaseSensitivity cs = Qt::CaseSensitive) - { - if (cs == Qt::CaseSensitive) - { - if (!hash.contains(left)) - return 0; - - inverted.remove(hash.value(left)); - hash.remove(left); - - return 1; - } - else - { - QString lowerLeft = left.toLower(); - if (!lowerHash.contains(lowerLeft)) - return 0; - - QString right = hash.value(lowerHash.value(lowerLeft)); - - hash.remove(inverted.value(right)); - inverted.remove(right); - lowerHash.remove(lowerLeft); - lowerInverted.remove(right.toLower()); - - return 1; - } - } + int removeLeft(const QString& left, Qt::CaseSensitivity cs = Qt::CaseSensitive); /** * @brief Removes entry matching given value in right-side values. @@ -142,34 +84,7 @@ class BiStrHash * @param cs Case sensitivity flag. * @return Number of entries removed. */ - int removeRight(const QString& right, Qt::CaseSensitivity cs = Qt::CaseSensitive) - { - if (cs == Qt::CaseSensitive) - { - if (!inverted.contains(right)) - return 0; - - hash.remove(inverted.value(right)); - inverted.remove(right); - - return 1; - } - else - { - QString lowerRight = right.toLower(); - if (!lowerInverted.contains(lowerRight)) - return 0; - - QString left = inverted.value(lowerInverted.value(lowerRight)); - - inverted.remove(hash.value(left)); - hash.remove(left); - lowerHash.remove(left.toLower()); - lowerInverted.remove(lowerRight); - - return 1; - } - } + int removeRight(const QString& right, Qt::CaseSensitivity cs = Qt::CaseSensitive); /** * @brief Removes entry from hash and returns it. @@ -177,21 +92,7 @@ class BiStrHash * @param cs Case sensitivity flag. * @return Right side value, or null string if the \p left was not matched. */ - QString takeLeft(const QString& left, Qt::CaseSensitivity cs = Qt::CaseSensitive) - { - if (cs == Qt::CaseSensitive) - { - QString right = hash.take(left); - inverted.remove(right); - return right; - } - else - { - QString right = hash.take(lowerHash.take(left.toLower())); - inverted.remove(lowerInverted.take(right.toLower())); - return right; - } - } + QString takeLeft(const QString& left, Qt::CaseSensitivity cs = Qt::CaseSensitive); /** * @brief Removes entry from hash and returns it. @@ -199,44 +100,19 @@ class BiStrHash * @param cs Case sensitivity flag. * @return Left side value, or null string if the \p left was not matched. */ - QString takeRight(const QString& right, Qt::CaseSensitivity cs = Qt::CaseSensitive) - { - if (cs == Qt::CaseSensitive) - { - QString left = inverted.take(right); - hash.remove(left); - return left; - } - else - { - QString left = inverted.take(lowerInverted.take(right.toLower())); - hash.remove(lowerHash.take(left.toLower())); - return left; - } - } + QString takeRight(const QString& right, Qt::CaseSensitivity cs = Qt::CaseSensitive); /** * @brief Copies all entries from the other hash to this hash. * @param other Other hash to copy values from. * @return Reference to this hash, after update. */ - BiStrHash& unite(const BiStrHash& other) - { - unite(other.hash); - return *this; - } + BiStrHash& unite(const BiStrHash& other); /** * @overload */ - BiStrHash& unite(const QHash& other) - { - QHashIterator it(other); - while (it.hasNext()) - insert(it.next().key(), it.value()); - - return *this; - } + BiStrHash& unite(const QHash& other); /** * @brief Finds right-side value by matching the left-side value. @@ -244,13 +120,7 @@ class BiStrHash * @param cs Case sensitivity flag. * @return Right-side value, or null string if left-side value was not matched. */ - QString valueByLeft(const QString& left, Qt::CaseSensitivity cs = Qt::CaseSensitive) const - { - if (cs == Qt::CaseSensitive) - return hash.value(left); - else - return hash.value(lowerHash.value(left.toLower())); - } + QString valueByLeft(const QString& left, Qt::CaseSensitivity cs = Qt::CaseSensitive) const; /** * @brief Finds left-side value by matching the right-side value. @@ -258,85 +128,48 @@ class BiStrHash * @param cs Case sensitivity flag. * @return Left-side value, or null string if right-side value was not matched. */ - QString valueByRight(const QString& right, Qt::CaseSensitivity cs = Qt::CaseSensitive) const - { - if (cs == Qt::CaseSensitive) - return inverted.value(right); - else - return inverted.value(lowerInverted.value(right.toLower())); - } + QString valueByRight(const QString& right, Qt::CaseSensitivity cs = Qt::CaseSensitive) const; /** * @brief Gives all left-side values. * @return List of values. */ - QStringList leftValues() const - { - return hash.keys(); - } + QStringList leftValues() const; /** * @brief Gives all right-side values. * @return List of values. */ - QStringList rightValues() const - { - return inverted.keys(); - } + QStringList rightValues() const; /** * @brief Provides java-style iterator for this hash. * @return Iterator object. */ - QHashIterator iterator() const - { - return QHashIterator(hash); - } + QHashIterator iterator() const; /** * @brief Removes all entries from the hash. */ - void clear() - { - hash.clear(); - inverted.clear(); - lowerHash.clear(); - lowerInverted.clear(); - } + void clear(); /** * @brief Counts all entries in the hash. * @return Number of entries in the hash. */ - int count() const - { - return hash.count(); - } + int count() const; /** * @brief Tests whether the hash is empty or not. * @return true if the hash is empty, false otherwise. */ - bool isEmpty() const - { - return hash.isEmpty(); - } + bool isEmpty() const; private: /** * @brief Fills inverted and lower internal hashes basing on the main hash class member. */ - void initInvertedAndLower() - { - QHashIterator it(hash); - while (it.hasNext()) - { - it.next(); - inverted[it.value()] = it.key(); - lowerHash[it.key().toLower()] = it.key(); - lowerInverted[it.value().toLower()] = it.value(); - } - } + void initInvertedAndLower(); /** * @brief Standard mapping - left to right. diff --git a/SQLiteStudio3/coreSQLiteStudio/common/sortedset.h b/SQLiteStudio3/coreSQLiteStudio/common/sortedset.h new file mode 100644 index 0000000..266e409 --- /dev/null +++ b/SQLiteStudio3/coreSQLiteStudio/common/sortedset.h @@ -0,0 +1,64 @@ +#ifndef SORTEDSET_H +#define SORTEDSET_H + +#include "common/sortedhash.h" + +template +class SortedSet : private SortedHash +{ + public: + bool contains(const T &value) const + { + return QHash::containsKey(value); + } + + int count() const + { + return size(); + } + + bool isEmpty() const + { + return SortedHash::isEmpty(); + } + + bool remove(const T& value) + { + return SortedHash::remove(value); + } + + int size() const + { + return QHash::size(); + } + + void swap(SortedSet& other) + { + return SortedHash::swap(other); + } + + SortedSet& operator+=(const T& value) + { + SortedHash::insert(value, true); + return *this; + } + + SortedSet& operator-=(const T& value) + { + SortedHash::remove(value); + return *this; + } + + QSet& operator<<(const T &value) + { + SortedHash::insert(value, true); + return *this; + } + + QList toList() + { + return SortedHash::keys(); + } +}; + +#endif // SORTEDSET_H diff --git a/SQLiteStudio3/coreSQLiteStudio/common/strhash.h b/SQLiteStudio3/coreSQLiteStudio/common/strhash.h index 4fb7bb3..41b3d11 100644 --- a/SQLiteStudio3/coreSQLiteStudio/common/strhash.h +++ b/SQLiteStudio3/coreSQLiteStudio/common/strhash.h @@ -11,12 +11,12 @@ class StrHash { public: StrHash() {} - StrHash(std::initializer_list> list) : hash(QHash(list)) + StrHash(std::initializer_list> list) : hash(QHash(list)) { initLower(); } - StrHash(const QHash& other) : hash(QHash(other)) + StrHash(const QHash& other) : hash(QHash(other)) { initLower(); } @@ -87,9 +87,9 @@ class StrHash return *this; } - StrHash& unite(const QHash& other) + StrHash& unite(const QHash& other) { - QHashIterator it(other); + QHashIterator it(other); while (it.hasNext()) { it.next(); @@ -117,9 +117,9 @@ class StrHash return hash.keys(); } - QHashIterator iterator() const + QHashIterator iterator() const { - return QHashIterator(hash); + return QHashIterator(hash); } void clear() @@ -146,6 +146,11 @@ class StrHash return hash.isEmpty(); } + QHash toQHash() const + { + return hash; + } + T& operator[](const QString& key) { if (lowerCaseHash.contains(key.toLower()) && !hash.contains(key)) @@ -167,7 +172,7 @@ class StrHash private: void initLower() { - QHashIterator it(hash); + QHashIterator it(hash); while (it.hasNext()) { it.next(); @@ -175,8 +180,8 @@ class StrHash } } - QHash lowerCaseHash; - QHash hash; + QHash lowerCaseHash; + QHash hash; }; #endif // STRHASH_H diff --git a/SQLiteStudio3/coreSQLiteStudio/common/utils.cpp b/SQLiteStudio3/coreSQLiteStudio/common/utils.cpp index f2b3d1c..6cf1892 100644 --- a/SQLiteStudio3/coreSQLiteStudio/common/utils.cpp +++ b/SQLiteStudio3/coreSQLiteStudio/common/utils.cpp @@ -11,6 +11,8 @@ #include #include #include +#include +#include #ifdef Q_OS_LINUX #include @@ -214,12 +216,12 @@ qint64 Range::length() const return to - from + 1; } -QString generateUniqueName(const QString &baseName, const QStringList &existingNames) +QString generateUniqueName(const QString& baseName, const QStringList& existingNames, Qt::CaseSensitivity cs) { QString name = baseName; int i = 0; - while (existingNames.contains(name)) - name = baseName+QString::number(i++); + while (existingNames.contains(name, cs)) + name = baseName + QString::number(i++); return name; } @@ -887,3 +889,38 @@ QString decryptRsa(const QString& input, const QString& modulus, const QString& std::string result = RSA::Decrypt(inputStdStr, key); return QString::fromStdString(result); } + +QStringList concat(const QList& list) +{ + QStringList result; + for (const QStringList& item : list) + result.append(item); + + return result; +} + +QString doubleToString(double val) +{ + return QString::number(val, 'g', 16); +} + +void sortWithReferenceList(QList& listToSort, const QList& referenceList, Qt::CaseSensitivity cs) +{ + qSort(listToSort.begin(), listToSort.end(), [referenceList, cs](const QString& s1, const QString& s2) -> bool + { + int idx1 = indexOf(referenceList, s1, cs); + int idx2 = indexOf(referenceList, s2, cs); + if (idx1 == -1 || idx2 == -1) + { + if (idx1 == -1 && idx2 == -1) + return false; + + return (idx1 == -1); + } + + if (idx1 == idx2) + return false; + + return (idx1 > idx2); + }); +} diff --git a/SQLiteStudio3/coreSQLiteStudio/common/utils.h b/SQLiteStudio3/coreSQLiteStudio/common/utils.h index 90d2d62..934e70a 100644 --- a/SQLiteStudio3/coreSQLiteStudio/common/utils.h +++ b/SQLiteStudio3/coreSQLiteStudio/common/utils.h @@ -57,7 +57,7 @@ API_EXPORT QString randStr(int length, bool numChars = true, bool whiteSpaces = API_EXPORT QString randStr(int length, const QString& charCollection); API_EXPORT QString randBinStr(int length); API_EXPORT QString randStrNotIn(int length, const QSet set, bool numChars = true, bool whiteSpaces = false); -API_EXPORT QString generateUniqueName(const QString& prefix, const QStringList& existingNames); +API_EXPORT QString generateUniqueName(const QString& prefix, const QStringList& existingNames, Qt::CaseSensitivity cs = Qt::CaseSensitive); API_EXPORT bool isNumeric(const QVariant& value); API_EXPORT QString rStrip(const QString& str); API_EXPORT QStringList tokenizeArgs(const QString& str); @@ -73,6 +73,20 @@ API_EXPORT QHash bytesToHash(const QByteArray& bytes); API_EXPORT int indexOf(const QStringList& list, const QString& value, int from = 0, Qt::CaseSensitivity cs = Qt::CaseSensitive); API_EXPORT int indexOf(const QStringList& list, const QString& value, Qt::CaseSensitivity cs = Qt::CaseSensitive); +template +int indexOf(const QList& list, std::function predicate) +{ + int i = 0; + for (const T& item : list) + { + if (predicate(item)) + return i; + + ++i; + } + return -1; +} + /** * @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. @@ -103,6 +117,18 @@ bool contains(const QList& list, std::function testFunc return false; } +template +QList concat(const QList>& list) +{ + QList result; + for (const QList& item : list) + result.append(item); + + return result; +} + +API_EXPORT QStringList concat(const QList& list); + /** * @brief Appends or prepends characters to the string to make it of specified length. * @param str Input string to work with. @@ -205,6 +231,18 @@ 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); + +/** + * @brief Sorts string list using reference list for ordering. + * @param listToSort This list will be sorted. + * @param referenceList Should contain all elements from list to sort - it tells the order. + * @param cs Case sensitivity of the string comparision. + * + * Sorts \p listToSort using \p referenceList as a reference of what is the order. + * If any element from \p listToSort is not on the list of \p referenceList, then the element will be placed at the end. + */ +API_EXPORT void sortWithReferenceList(QList& listToSort, const QList& referenceList, Qt::CaseSensitivity cs = Qt::CaseSensitive); enum class DistributionType { diff --git a/SQLiteStudio3/coreSQLiteStudio/common/utils_sql.cpp b/SQLiteStudio3/coreSQLiteStudio/common/utils_sql.cpp index eba10fa..5c7e7e9 100644 --- a/SQLiteStudio3/coreSQLiteStudio/common/utils_sql.cpp +++ b/SQLiteStudio3/coreSQLiteStudio/common/utils_sql.cpp @@ -77,6 +77,16 @@ QString wrapObjIfNeeded(const QString& obj, Dialect dialect, NameWrapper favWrap return obj; } +QString wrapObjIfNeeded(const QString& obj, Dialect dialect, bool useDoubleQuoteForEmptyValue, NameWrapper favWrapper) +{ + return wrapObjIfNeeded(obj, dialect, ((useDoubleQuoteForEmptyValue && obj.isEmpty()) ? NameWrapper::DOUBLE_QUOTE : favWrapper)); +} + +QString wrapObjName(const QString& obj, Dialect dialect, bool useDoubleQuoteForEmptyValue, NameWrapper favWrapper) +{ + return wrapObjName(obj, dialect, ((useDoubleQuoteForEmptyValue && obj.isEmpty()) ? NameWrapper::DOUBLE_QUOTE : favWrapper)); +} + QString wrapObjName(const QString& obj, Dialect dialect, NameWrapper favWrapper) { QString result = obj; @@ -573,6 +583,8 @@ QueryAccessMode getQueryAccessMode(const QString& query, Dialect dialect, bool* TokenList tokens = Lexer::tokenize(query, dialect); int keywordIdx = tokens.indexOf(Token::KEYWORD); + if (keywordIdx < 0) + return QueryAccessMode::WRITE; int cmdIdx = readOnlyCommands.indexOf(tokens[keywordIdx]->value.toUpper()); if (keywordIdx > -1 && cmdIdx > -1) @@ -632,3 +644,53 @@ QueryAccessMode getQueryAccessMode(const QString& query, Dialect dialect, bool* return QueryAccessMode::WRITE; } + +QStringList valueListToSqlList(const QVariantList& values, Dialect dialect) +{ + QStringList argList; + for (const QVariant& value : values) + { + if (!value.isValid() || value.isNull()) + { + argList << "NULL"; + continue; + } + + switch (value.userType()) + { + case QVariant::Int: + case QVariant::UInt: + case QVariant::LongLong: + case QVariant::ULongLong: + argList << value.toString(); + break; + case QVariant::Double: + argList << doubleToString(value.toDouble()); + break; + case QVariant::Bool: + 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; + } + } + default: + argList << wrapString(escapeString(value.toString())); + break; + } + } + return argList; +} + +QStringList wrapStrings(const QStringList& strList) +{ + QStringList list; + for (const QString& str : strList) + list << wrapString(str); + + return list; +} diff --git a/SQLiteStudio3/coreSQLiteStudio/common/utils_sql.h b/SQLiteStudio3/coreSQLiteStudio/common/utils_sql.h index 038c146..ceccea0 100644 --- a/SQLiteStudio3/coreSQLiteStudio/common/utils_sql.h +++ b/SQLiteStudio3/coreSQLiteStudio/common/utils_sql.h @@ -36,7 +36,9 @@ 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); @@ -45,6 +47,7 @@ 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 wrapString(const QString& str); +API_EXPORT QStringList wrapStrings(const QStringList& strList); API_EXPORT QString wrapStringIfNeeded(const QString& str); API_EXPORT QString escapeString(QString &str); API_EXPORT QString escapeString(const QString& str); @@ -75,6 +78,7 @@ 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& values, Dialect dialect); #endif // UTILS_SQL_H -- cgit v1.2.3