175 lines
4.6 KiB
C++
Executable File
175 lines
4.6 KiB
C++
Executable File
/**
|
|
* Helper class for a vector of integer (stored as integer[] in the postgres database
|
|
* $Id$
|
|
* $HeadURL$
|
|
* $Author$
|
|
* Created by Christian Ehrlicher, SLSE, 2016-05-03
|
|
*/
|
|
|
|
#include "pgarray.h"
|
|
#include <QVector>
|
|
#include <QDebug>
|
|
|
|
#include <functional>
|
|
#include <LtsUtilsCore/ltsutilscore_export.h>
|
|
|
|
namespace LtsUtils
|
|
{
|
|
|
|
template<typename T>
|
|
static inline QString convertToPgString(const std::vector<T> &data)
|
|
{
|
|
if (data.size() == 0)
|
|
return QLatin1String("{}");
|
|
QString ret(QLatin1Char('{'));
|
|
for (T i : data)
|
|
ret += QString::number(i) + QLatin1Char(',');
|
|
ret.chop(1);
|
|
ret += QLatin1Char('}');
|
|
return ret;
|
|
}
|
|
|
|
template<>
|
|
LTSUTILSCORE_EXPORT QString IntArray::toPgString() const
|
|
{
|
|
return convertToPgString(m_data);
|
|
}
|
|
|
|
template<>
|
|
LTSUTILSCORE_EXPORT QString BigintArray::toPgString() const
|
|
{
|
|
return convertToPgString(m_data);
|
|
}
|
|
|
|
template<typename T>
|
|
static inline T convertFromPgString(const QString &str, const std::function<typename T::Type(const QStringRef &val, bool *bOk)> &convertFunc)
|
|
{
|
|
typename T::ContainerType result;
|
|
|
|
int idxStart = str.indexOf(QLatin1Char('{'));
|
|
int idxEnd = str.lastIndexOf(QLatin1Char('}'));
|
|
if (idxEnd < idxStart)
|
|
return T(result);
|
|
if (idxStart < 0 && idxEnd < 0)
|
|
{
|
|
// no {} around - fake midRef call
|
|
idxStart = -1;
|
|
idxEnd = str.length() + 1;
|
|
}
|
|
|
|
const QStringRef strRef = str.midRef(idxStart + 1, idxEnd - idxStart - 1);
|
|
const QVector<QStringRef> vec = strRef.split(QLatin1Char(','), QString::SkipEmptyParts);
|
|
result.reserve(vec.size());
|
|
for (const QStringRef &s : vec)
|
|
{
|
|
bool ok = false;
|
|
const typename T::Type i = convertFunc(s, &ok);
|
|
if (ok)
|
|
result.push_back(i);
|
|
}
|
|
|
|
return T(result);
|
|
}
|
|
|
|
template<>
|
|
LTSUTILSCORE_EXPORT IntArray IntArray::fromPgString(const QString &str)
|
|
{
|
|
return convertFromPgString<IntArray>(str,
|
|
[](const QStringRef & val, bool * bOk) { return val.toInt(bOk);});
|
|
}
|
|
|
|
template<>
|
|
LTSUTILSCORE_EXPORT BigintArray BigintArray::fromPgString(const QString &str)
|
|
{
|
|
return convertFromPgString<BigintArray>(str,
|
|
[](const QStringRef & val, bool * bOk) { return val.toLongLong(bOk);});
|
|
}
|
|
|
|
|
|
//
|
|
// 2D
|
|
//
|
|
|
|
template<typename T>
|
|
static inline QString convertToPgString(const std::map<T, T> &data)
|
|
{
|
|
if (data.size() == 0)
|
|
return QLatin1String("{}");
|
|
QString ret(QLatin1Char('{'));
|
|
for (const auto &it : data)
|
|
{
|
|
ret += QLatin1Char('{') + QString::number(it.first) +
|
|
QLatin1Char(',') + QString::number(it.second) + QLatin1String("},");
|
|
}
|
|
ret.chop(1);
|
|
ret += QLatin1Char('}');
|
|
return ret;
|
|
}
|
|
|
|
template<>
|
|
LTSUTILSCORE_EXPORT QString IntArray2D::toPgString() const
|
|
{
|
|
return convertToPgString<IntArray2D::Type>(m_data);
|
|
}
|
|
|
|
template<>
|
|
LTSUTILSCORE_EXPORT QString BigintArray2D::toPgString() const
|
|
{
|
|
return convertToPgString<BigintArray2D::Type>(m_data);
|
|
}
|
|
|
|
|
|
template<typename T>
|
|
static inline T convertFromPgString2D(const QString &str, const std::function<typename T::Type(const QStringRef &val)> &convertFunc)
|
|
{
|
|
typename T::ContainerType ret;
|
|
int idxStart = str.indexOf(QLatin1Char('{'));
|
|
int idxEnd = str.lastIndexOf(QLatin1Char('}'));
|
|
if (idxEnd < idxStart)
|
|
return T(ret);
|
|
if (idxStart < 0 && idxEnd < 0)
|
|
{
|
|
// no {} around - fake midRef call
|
|
idxStart = -1;
|
|
idxEnd = str.length() + 1;
|
|
}
|
|
// remove first { and last } --> { 1, 2 }, { 4, 3 }, { 10, 1 }
|
|
const QStringRef strRef = str.midRef(idxStart + 1, idxEnd - idxStart - 1);
|
|
idxStart = strRef.indexOf(QLatin1Char('{'));
|
|
while (idxStart >= 0)
|
|
{
|
|
idxEnd = strRef.indexOf(QLatin1Char('}'), idxStart);
|
|
if (idxEnd < 0)
|
|
break;
|
|
// '{ 1, 2 }' -> ' 1, 2 '
|
|
const QStringRef keyValueStr = strRef.mid(idxStart + 1, idxEnd - idxStart - 1);
|
|
const QVector<QStringRef> keyValuePair = keyValueStr.split(QLatin1Char(','), QString::SkipEmptyParts);
|
|
if (keyValuePair.size() != 2)
|
|
break;
|
|
const typename T::Type key = convertFunc(keyValuePair.at(0).trimmed());
|
|
const typename T::Type value = convertFunc(keyValuePair.at(1).trimmed());
|
|
ret.insert(std::make_pair(key, value));
|
|
|
|
// search next
|
|
idxStart = strRef.indexOf(QLatin1Char('{'), idxEnd + 1);
|
|
}
|
|
|
|
return T(ret);
|
|
}
|
|
|
|
template<>
|
|
LTSUTILSCORE_EXPORT IntArray2D IntArray2D::fromPgString(const QString &str)
|
|
{
|
|
return convertFromPgString2D<IntArray2D>(str,
|
|
[](const QStringRef & val) { return val.toInt();});
|
|
}
|
|
|
|
template<>
|
|
LTSUTILSCORE_EXPORT BigintArray2D BigintArray2D::fromPgString(const QString &str)
|
|
{
|
|
return convertFromPgString2D<BigintArray2D>(str,
|
|
[](const QStringRef & val) { return val.toLongLong();});
|
|
}
|
|
|
|
} // namespace LtsUtils
|