QGIS API Documentation
4.3.0-Master (16eddb2670e)
Toggle main menu visibility
Loading...
Searching...
No Matches
src
core
qgspostgresstringutils.cpp
Go to the documentation of this file.
1
/***************************************************************************
2
qgspostgresstringutils.cpp
3
---------------------
4
begin : July 2019
5
copyright : (C) 2019 by David Signer
6
email : david at opengis dot ch
7
***************************************************************************
8
* *
9
* This program is free software; you can redistribute it and/or modify *
10
* it under the terms of the GNU General Public License as published by *
11
* the Free Software Foundation; either version 2 of the License, or *
12
* (at your option) any later version. *
13
* *
14
***************************************************************************/
15
16
#include "
qgspostgresstringutils.h
"
17
18
#include <nlohmann/json.hpp>
19
20
#include "
qgsmessagelog.h
"
21
22
#include <QRegularExpression>
23
#include <QString>
24
25
using namespace
Qt::StringLiterals;
26
27
using namespace
nlohmann;
28
29
static
void
jumpSpace(
const
QString &txt,
int
&i )
30
{
31
while
( i < txt.length() && txt.at( i ).isSpace() )
32
++i;
33
}
34
35
QString QgsPostgresStringUtils::getNextString(
const
QString &txt,
int
&i,
const
QString &sep )
36
{
37
jumpSpace( txt, i );
38
QString cur = txt.mid( i );
39
if
( cur.startsWith(
'"'
) )
40
{
41
const
thread_local
QRegularExpression stringRe( QRegularExpression::anchoredPattern(
"^\"((?:\\\\.|[^\"\\\\])*)\".*"
) );
42
const
QRegularExpressionMatch match = stringRe.match( cur );
43
if
( !match.hasMatch() )
44
{
45
QgsMessageLog::logMessage
( QObject::tr(
"Cannot find end of double quoted string: %1"
).arg( txt ), QObject::tr(
"PostgresStringUtils"
) );
46
return
QString();
47
}
48
i += match.captured( 1 ).length() + 2;
49
jumpSpace( txt, i );
50
if
( !QStringView { txt }.mid( i ).startsWith( sep ) && i < txt.length() )
51
{
52
QgsMessageLog::logMessage
( QObject::tr(
"Cannot find separator: %1"
).arg( txt.mid( i ) ), QObject::tr(
"PostgresStringUtils"
) );
53
return
QString();
54
}
55
i += sep.length();
56
return
match.captured( 1 ).replace(
"\\\""
_L1,
"\""
_L1 ).replace(
"\\\\"
_L1,
"\\"
_L1 );
57
}
58
else
59
{
60
int
sepPos = cur.indexOf( sep );
61
if
( sepPos < 0 )
62
{
63
i += cur.length();
64
return
cur.trimmed();
65
}
66
i += sepPos + sep.length();
67
return
cur.left( sepPos ).trimmed();
68
}
69
}
70
71
QVariantList
QgsPostgresStringUtils::parseArray
(
const
QString &
string
)
72
{
73
QVariantList variantList;
74
75
//it's a postgres array
76
QString newVal =
string
.mid( 1,
string
.length() - 2 );
77
78
if
( newVal.trimmed().startsWith(
'{'
) )
79
{
80
//it's a multidimensional array
81
QString subarray = newVal.trimmed();
82
while
( !subarray.isEmpty() )
83
{
84
bool
escaped =
false
;
85
int
openedBrackets = 1;
86
int
i = 0;
87
while
( openedBrackets > 0 )
88
{
89
++i;
90
if
( i >= subarray.length() )
91
break
;
92
93
if
( subarray.at( i ) ==
'}'
&& !escaped )
94
openedBrackets--;
95
else
if
( subarray.at( i ) ==
'{'
&& !escaped )
96
openedBrackets++;
97
98
escaped = !escaped ? subarray.at( i ) ==
'\\'
:
false
;
99
}
100
101
variantList.append( subarray.left( ++i ) );
102
i = subarray.indexOf(
','
, i );
103
i = i > 0 ? subarray.indexOf(
'{'
, i ) : -1;
104
if
( i == -1 )
105
break
;
106
107
subarray = subarray.mid( i );
108
}
109
}
110
else
111
{
112
int
i = 0;
113
while
( i < newVal.length() )
114
{
115
const
QString value = getNextString( newVal, i, u
","
_s );
116
if
( value.isNull() )
117
{
118
QgsMessageLog::logMessage
( QObject::tr(
"Error parsing PG like array: %1"
).arg( newVal ), QObject::tr(
"PostgresStringUtils"
) );
119
break
;
120
}
121
variantList.append( value );
122
}
123
}
124
125
return
variantList;
126
}
127
128
QString
QgsPostgresStringUtils::buildArray
(
const
QVariantList &list )
129
{
130
QStringList sl;
131
for
(
const
QVariant &v : std::as_const( list ) )
132
{
133
// Convert to proper type
134
switch
( v.userType() )
135
{
136
case
QMetaType::Type::Int:
137
case
QMetaType::Type::LongLong:
138
sl.push_back( v.toString() );
139
break
;
140
default
:
141
QString newS = v.toString();
142
if
( newS.startsWith(
'{'
) )
143
{
144
sl.push_back( newS );
145
}
146
else
147
{
148
newS.replace(
'\\'
, R
"(\\)"_L1 );
149
newS.replace(
'\"'
, R
"(\")"_L1 );
150
sl.push_back(
"\""
+ newS +
"\""
);
151
}
152
break
;
153
}
154
}
155
//store as a formatted string because the fields supports only string
156
QString s = sl.join(
','
).prepend(
'{'
).append(
'}'
);
157
158
return
s;
159
}
QgsMessageLog::logMessage
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(), Qgis::StringFormat format=Qgis::StringFormat::PlainText)
Adds a message to the log instance (and creates it if necessary).
Definition
qgsmessagelog.cpp:35
QgsPostgresStringUtils::buildArray
static QString buildArray(const QVariantList &list)
Build a postgres array like formatted list in a string from a QVariantList.
Definition
qgspostgresstringutils.cpp:128
QgsPostgresStringUtils::parseArray
static QVariantList parseArray(const QString &string)
Returns a QVariantList created out of a string containing an array in postgres array format {1,...
Definition
qgspostgresstringutils.cpp:71
qgsmessagelog.h
qgspostgresstringutils.h
Generated on
for QGIS API Documentation by
1.17.0