19#include <QRegularExpression>
21#include <nlohmann/json.hpp>
23using namespace nlohmann;
25static void jumpSpace(
const QString &txt,
int &i )
27 while ( i < txt.length() && txt.at( i ).isSpace() )
31QString QgsPostgresStringUtils::getNextString(
const QString &txt,
int &i,
const QString &sep )
34 QString cur = txt.mid( i );
35 if ( cur.startsWith(
'"' ) )
37 const thread_local QRegularExpression stringRe( QRegularExpression::anchoredPattern(
"^\"((?:\\\\.|[^\"\\\\])*)\".*" ) );
38 const QRegularExpressionMatch match = stringRe.match( cur );
39 if ( !match.hasMatch() )
41 QgsMessageLog::logMessage( QObject::tr(
"Cannot find end of double quoted string: %1" ).arg( txt ), QObject::tr(
"PostgresStringUtils" ) );
44 i += match.captured( 1 ).length() + 2;
46 if ( !QStringView{txt}.mid( i ).startsWith( sep ) && i < txt.length() )
48 QgsMessageLog::logMessage( QObject::tr(
"Cannot find separator: %1" ).arg( txt.mid( i ) ), QObject::tr(
"PostgresStringUtils" ) );
52 return match.captured( 1 ).replace( QLatin1String(
"\\\"" ), QLatin1String(
"\"" ) ).replace( QLatin1String(
"\\\\" ), QLatin1String(
"\\" ) );
56 int sepPos = cur.indexOf( sep );
62 i += sepPos + sep.length();
63 return cur.left( sepPos ).trimmed();
69 QVariantList variantList;
72 QString newVal =
string.mid( 1,
string.length() - 2 );
74 if ( newVal.trimmed().startsWith(
'{' ) )
77 QString subarray = newVal.trimmed();
78 while ( !subarray.isEmpty() )
81 int openedBrackets = 1;
83 while ( openedBrackets > 0 )
86 if ( i >= subarray.length() )
89 if ( subarray.at( i ) ==
'}' && !escaped )
91 else if ( subarray.at( i ) ==
'{' && !escaped )
94 escaped = !escaped ? subarray.at( i ) ==
'\\' :
false;
97 variantList.append( subarray.left( ++i ) );
98 i = subarray.indexOf(
',', i );
99 i = i > 0 ? subarray.indexOf(
'{', i ) : -1;
103 subarray = subarray.mid( i );
109 while ( i < newVal.length() )
111 const QString value = getNextString( newVal, i, QStringLiteral(
"," ) );
112 if ( value.isNull() )
114 QgsMessageLog::logMessage( QObject::tr(
"Error parsing PG like array: %1" ).arg( newVal ), QObject::tr(
"PostgresStringUtils" ) );
117 variantList.append( value );
128 for (
const QVariant &v : std::as_const( list ) )
133 case QVariant::Type::Int:
134 case QVariant::Type::LongLong:
135 sl.push_back( v.toString() );
138 QString newS = v.toString();
139 if ( newS.startsWith(
'{' ) )
141 sl.push_back( newS );
145 newS.replace(
'\\', QLatin1String( R
"(\\)" ) );
146 newS.replace( '\"', QLatin1String( R
"(\")" ) );
147 sl.push_back( "\"" + newS +
"\"" );
153 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)
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,...