18#include <nlohmann/json.hpp>
22#include <QRegularExpression>
25using namespace Qt::StringLiterals;
27using namespace nlohmann;
29static void jumpSpace(
const QString &txt,
int &i )
31 while ( i < txt.length() && txt.at( i ).isSpace() )
35QString QgsPostgresStringUtils::getNextString(
const QString &txt,
int &i,
const QString &sep )
38 QString cur = txt.mid( i );
39 if ( cur.startsWith(
'"' ) )
41 const thread_local QRegularExpression stringRe( QRegularExpression::anchoredPattern(
"^\"((?:\\\\.|[^\"\\\\])*)\".*" ) );
42 const QRegularExpressionMatch match = stringRe.match( cur );
43 if ( !match.hasMatch() )
45 QgsMessageLog::logMessage( QObject::tr(
"Cannot find end of double quoted string: %1" ).arg( txt ), QObject::tr(
"PostgresStringUtils" ) );
48 i += match.captured( 1 ).length() + 2;
50 if ( !QStringView{txt}.mid( i ).startsWith( sep ) && i < txt.length() )
52 QgsMessageLog::logMessage( QObject::tr(
"Cannot find separator: %1" ).arg( txt.mid( i ) ), QObject::tr(
"PostgresStringUtils" ) );
56 return match.captured( 1 ).replace(
"\\\""_L1,
"\""_L1 ).replace(
"\\\\"_L1,
"\\"_L1 );
60 int sepPos = cur.indexOf( sep );
66 i += sepPos + sep.length();
67 return cur.left( sepPos ).trimmed();
73 QVariantList variantList;
76 QString newVal =
string.mid( 1,
string.length() - 2 );
78 if ( newVal.trimmed().startsWith(
'{' ) )
81 QString subarray = newVal.trimmed();
82 while ( !subarray.isEmpty() )
85 int openedBrackets = 1;
87 while ( openedBrackets > 0 )
90 if ( i >= subarray.length() )
93 if ( subarray.at( i ) ==
'}' && !escaped )
95 else if ( subarray.at( i ) ==
'{' && !escaped )
98 escaped = !escaped ? subarray.at( i ) ==
'\\' :
false;
101 variantList.append( subarray.left( ++i ) );
102 i = subarray.indexOf(
',', i );
103 i = i > 0 ? subarray.indexOf(
'{', i ) : -1;
107 subarray = subarray.mid( i );
113 while ( i < newVal.length() )
115 const QString value = getNextString( newVal, i, u
","_s );
116 if ( value.isNull() )
118 QgsMessageLog::logMessage( QObject::tr(
"Error parsing PG like array: %1" ).arg( newVal ), QObject::tr(
"PostgresStringUtils" ) );
121 variantList.append( value );
132 for (
const QVariant &v : std::as_const( list ) )
135 switch ( v.userType() )
137 case QMetaType::Type::Int:
138 case QMetaType::Type::LongLong:
139 sl.push_back( v.toString() );
142 QString newS = v.toString();
143 if ( newS.startsWith(
'{' ) )
145 sl.push_back( newS );
149 newS.replace(
'\\', R
"(\\)"_L1 );
150 newS.replace( '\"', R
"(\")"_L1 );
151 sl.push_back( "\"" + newS +
"\"" );
157 QString s = sl.join(
',' ).prepend(
'{' ).append(
'}' );
static void logMessage(const QString &message, const QString &tag=QString(), Qgis::MessageLevel level=Qgis::MessageLevel::Warning, bool notifyUser=true, const char *file=__builtin_FILE(), const char *function=__builtin_FUNCTION(), int line=__builtin_LINE())
Adds a message to the log instance (and creates it if necessary).
static QString buildArray(const QVariantList &list)
Build a postgres array like formatted list in a string from a QVariantList.
static QVariantList parseArray(const QString &string)
Returns a QVariantList created out of a string containing an array in postgres array format {1,...