[prev in list] [next in list] [prev in thread] [next in thread]
List: kde-commits
Subject: [kdb] src: Improve KDb::cstringToVariant()
From: Jaroslaw Staniek <staniek () kde ! org>
Date: 2015-06-30 22:09:07
Message-ID: E1ZA3iF-00042Q-Rj () scm ! kde ! org
[Download RAW message or body]
Git commit 3eed88bb098e3c42760ea7b0c4e364126e48d3c8 by Jaroslaw Staniek.
Committed on 30/06/2015 at 16:51.
Pushed by staniek into branch 'master'.
Improve KDb::cstringToVariant()
- add signedness support for integers
- extend the docs
- add more sanity checks
- fail on unsupported types (Null, etc.) or if data is 0
- set result in the ok OUT arg
- much better convert integers (check limits)
+Add KDb::iif helper
M +57 -15 src/KDb.cpp
M +25 -3 src/KDb.h
http://commits.kde.org/kdb/3eed88bb098e3c42760ea7b0c4e364126e48d3c8
diff --git a/src/KDb.cpp b/src/KDb.cpp
index cb716cb..6338880 100644
--- a/src/KDb.cpp
+++ b/src/KDb.cpp
@@ -43,6 +43,7 @@
#include <QApplication>
#include <QDir>
#include <QProcess>
+#include <QtDebug>
#include <memory>
@@ -1552,30 +1553,71 @@ QString KDb::defaultFileBasedDriverId()
return QLatin1String("org.kde.kdb.sqlite");
}
-/*! @return QVariant value converted from null-terminated @a data string.
- In case of BLOB type, @a data is not null terminated, so passing length \
is needed. */
-QVariant KDb::cstringToVariant(const char* data, KDbField* f, int length)
+// Try to convert from string to type T
+template <typename T>
+QVariant convert(T (QString::*ConvertToT)(bool*,int) const, const char \
*data, int size, + qlonglong minValue, qlonglong maxValue, \
bool *ok) {
- if (!data)
+ T v = (QString::fromLatin1(data, size).*ConvertToT)(ok, 10);
+ if (*ok) {
+ *ok = minValue <= v && v <= maxValue;
+ }
+ return KDb::iif(*ok, QVariant(v));
+}
+
+QVariant KDb::cstringToVariant(const char* data, KDbField::Type type, bool \
*ok, int length, + KDb::Signedness \
signedness) +{
+ bool tempOk;
+ bool *thisOk = ok ? ok : &tempOk;
+ if (!data || type > KDbField::LastType) {
+ *thisOk = false;
return QVariant();
+ }
// from most to least frequently used types:
- if (!f || f->isTextType())
+ if (KDbField::isTextType(type)) {
+ *thisOk = true;
+ //! @todo use KDbDriverBehaviour::TEXT_TYPE_MAX_LENGTH for Text \
type? return QString::fromUtf8(data, length);
- if (f->isIntegerType()) {
- if (f->type() == KDbField::BigInteger)
- return QVariant(QString::fromLatin1(data, \
length).toLongLong());
- return QVariant(QString::fromLatin1(data, length).toInt());
- }
- if (f->isFPNumericType())
- return QString::fromLatin1(data, length).toDouble();
- if (f->type() == KDbField::BLOB)
- return QByteArray(data, length);
+ }
+ if (KDbField::isIntegerType(type)) {
+ qlonglong minValue, maxValue;
+ const bool isUnsigned = signedness == KDb::Unsigned;
+ KDb::getLimitsForFieldType(type, &minValue, &maxValue, \
signedness); + switch (type) {
+ case KDbField::Byte: // Byte here too, minValue/maxValue will take \
care of limits + case KDbField::ShortInteger:
+ return isUnsigned ?
+ convert(&QString::toUShort, data, length, minValue, \
maxValue, thisOk) + : convert(&QString::toShort, data, \
length, minValue, maxValue, thisOk); + case KDbField::Integer:
+ return isUnsigned ?
+ convert(&QString::toUInt, data, length, minValue, \
maxValue, thisOk) + : convert(&QString::toInt, data, length, \
minValue, maxValue, thisOk); + case KDbField::BigInteger:
+ return isUnsigned ?
+ convert(&QString::toULongLong, data, length, minValue, \
maxValue, thisOk) + : convert(&QString::toLongLong, data, \
length, minValue, maxValue, thisOk); + default:
+ qFatal("Unsupported integer type %d", type);
+ }
+ }
+ if (KDbField::isFPNumericType(type)) {
+ return KDb::iif(*thisOk, QVariant(QString::fromLatin1(data, \
length).toDouble(thisOk))); + }
+ if (type == KDbField::BLOB) {
+ *thisOk = length >= 0;
+ return *thisOk ? QVariant(QByteArray(data, length)) : QVariant();
+ }
// the default
//! @todo date/time?
QVariant result(QString::fromUtf8(data, length));
- if (!result.convert(KDbField::variantType(f->type())))
+ if (!result.convert(KDbField::variantType(type))) {
+ *thisOk = false;
return QVariant();
+ }
+ *thisOk = true;
return result;
}
diff --git a/src/KDb.h b/src/KDb.h
index 7835464..f064247 100644
--- a/src/KDb.h
+++ b/src/KDb.h
@@ -418,9 +418,21 @@ KDB_EXPORT void getLimitsForFieldType(KDbField::Type \
type, qlonglong *minValue, of 100 * 100 exceeds the range of Byte. */
KDB_EXPORT KDbField::Type maximumForIntegerFieldTypes(KDbField::Type t1, \
KDbField::Type t2);
-/*! @return QVariant value converted from null-terminated @a data string.
- In case of BLOB type, @a data is not null terminated, so passing length \
is needed. */
-KDB_EXPORT QVariant cstringToVariant(const char* data, KDbField* f, int \
length = -1); +//! @return QVariant value converted from a @a data string
+/*! Conversion is based on the information about type @a type.
+ @a type has to be an element from KDbField::Type, not greater than \
KDbField::LastType. + For unsupported type this function fails. @a length \
value controls number of characters + used in the conversion. It is \
optional value for all cases but for the BLOB type because + for it @a data \
is not null-terminated so the length cannot be measured. + The value of @a \
signedness controls the conversion in case of integer types; numbers can be \
+ limited to unsigned or not. + If @a ok is not 0 *ok is set to false on \
failure and to true on success. On failure a null + QVariant is returned. \
The function fails if @a data is 0. + For rules of conversion to the \
boolean type see the documentation of @ref QVariant::toBool(), + \
QVariant::toDate() for date type, QVariant::toDateTime() for date+time \
type, + QVariant::toTime() for time type. */
+KDB_EXPORT QVariant cstringToVariant(const char* data, KDbField::Type \
type, bool *ok, int length = -1, + \
KDb::Signedness signedness = KDb::Signed);
/*! @return default file-based driver MIME type
(typically something like "application/x-kexiproject-sqlite") */
@@ -489,6 +501,16 @@ T iifNotEmpty(const T &string, const QByteArray \
&stringIfEmpty) return iifNotEmpty(string, QString(stringIfEmpty));
}
+//! @return @a value if @a ok is true, else returns default value T().
+template<typename T>
+T iif(bool ok, const T &value)
+{
+ if (ok) {
+ return value;
+ }
+ return T();
+}
+
/*! @return a list of paths that KDb will search when dynamically loading \
libraries (plugins) This is basicaly list of directories returned \
QCoreApplication::libraryPaths() that have readable subdirectory "kdb".
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic