19 #include <QStringList>
28 : mFilePath( filePath )
39 const QString columnNameRx( QStringLiteral(
"[a-zA-Z_\x80-\xFF][a-zA-Z0-9_\x80-\xFF]*" ) );
45 const QList<QPair<QString, QString> > items = QUrlQuery( url ).queryItems( QUrl::FullyEncoded );
46 for (
int i = 0; i < items.size(); i++ )
48 QString key = items.
at( i ).first;
49 QString value = items.at( i ).second;
50 if ( key == QLatin1String(
"layer_ref" ) )
54 int pos = value.indexOf(
':' );
55 QString layerId, vlayerName;
59 vlayerName = QStringLiteral(
"vtab%1" ).arg( layerIdx );
63 layerId = value.left( pos );
64 vlayerName = QUrl::fromPercentEncoding( value.mid( pos + 1 ).toUtf8() );
69 else if ( key == QLatin1String(
"layer" ) )
73 int pos = value.indexOf(
':' );
76 QString providerKey, source, vlayerName, encoding = QStringLiteral(
"UTF-8" );
78 providerKey = value.left( pos );
79 int pos2 = value.indexOf(
':', pos + 1 );
80 if ( pos2 - pos == 2 )
81 pos2 = value.indexOf(
':', pos + 3 );
84 source = QUrl::fromPercentEncoding( value.mid( pos + 1, pos2 - pos - 1 ).toUtf8() );
85 int pos3 = value.indexOf(
':', pos2 + 1 );
88 vlayerName = QUrl::fromPercentEncoding( value.mid( pos2 + 1, pos3 - pos2 - 1 ).toUtf8() );
89 encoding = value.mid( pos3 + 1 );
93 vlayerName = QUrl::fromPercentEncoding( value.mid( pos2 + 1 ).toUtf8() );
98 source = QUrl::fromPercentEncoding( value.mid( pos + 1 ).toUtf8() );
99 vlayerName = QStringLiteral(
"vtab%1" ).arg( layerIdx );
102 def.
addSource( vlayerName, source, providerKey, encoding );
105 else if ( key == QLatin1String(
"geometry" ) )
109 QRegExp reGeom(
"(" + columnNameRx +
")(?::([a-zA-Z0-9]+):(\\d+))?" );
110 int pos = reGeom.indexIn( value );
114 if ( reGeom.captureCount() > 1 )
127 else if ( key == QLatin1String(
"nogeometry" ) )
131 else if ( key == QLatin1String(
"uid" ) )
135 else if ( key == QLatin1String(
"query" ) )
138 def.
setQuery( QUrl::fromPercentEncoding( value.toUtf8() ) );
140 else if ( key == QLatin1String(
"field" ) )
143 QRegExp reField(
"(" + columnNameRx +
"):(int|real|text)" );
144 int pos = reField.indexIn( value );
147 QString fieldName( reField.cap( 1 ) );
148 QString fieldType( reField.cap( 2 ) );
149 if ( fieldType == QLatin1String(
"int" ) )
153 else if ( fieldType == QLatin1String(
"real" ) )
157 if ( fieldType == QLatin1String(
"text" ) )
163 else if ( key == QLatin1String(
"lazy" ) )
167 else if ( key == QLatin1String(
"subsetstring" ) )
183 return "0123456789ABCDEF"[value & 0xF];
186 static inline ushort encodeNibble( ushort
c )
191 static bool qt_is_ascii(
const char *&ptr,
const char *end ) noexcept
193 while ( ptr + 4 <= end )
195 quint32 data = qFromUnaligned<quint32>( ptr );
196 if ( data &= 0x80808080U )
198 #if Q_BYTE_ORDER == Q_BIG_ENDIAN
199 uint idx = qCountLeadingZeroBits( data );
201 uint idx = qCountTrailingZeroBits( data );
210 if ( quint8( *ptr ) & 0x80 )
223 const char *in = ba.constData();
224 const char *
const end = ba.constEnd();
228 return QString::fromLatin1( ba, ba.size() );
231 QByteArray intermediate = ba;
232 intermediate.resize( ba.size() * 3 - ( in - ba.constData() ) );
233 uchar *out =
reinterpret_cast<uchar *
>( intermediate.data() + ( in - ba.constData() ) );
234 for ( ; in < end; ++in )
240 *out++ = encodeNibble( uchar( *in ) >> 4 );
241 *out++ = encodeNibble( uchar( *in ) & 0xf );
246 *out++ = uchar( *in );
250 return QString::fromLatin1( intermediate, out -
reinterpret_cast<uchar *
>( intermediate.data() ) );
257 url = QUrl::fromLocalFile(
filePath() );
259 QUrlQuery urlQuery( url );
264 if ( l.isReferenced() )
265 urlQuery.addQueryItem( QStringLiteral(
"layer_ref" ), QStringLiteral(
"%1:%2" ).arg( l.reference(), l.name() ) );
272 QString( QUrl::toPercentEncoding( l.name() ) ),
274 QString( QUrl::toPercentEncoding( l.source() ) ) ).toUtf8() ) );
277 if ( !
query().isEmpty() )
279 urlQuery.addQueryItem( QStringLiteral(
"query" ),
query() );
282 if ( !
uid().isEmpty() )
283 urlQuery.addQueryItem( QStringLiteral(
"uid" ),
uid() );
286 urlQuery.addQueryItem( QStringLiteral(
"nogeometry" ), QString() );
292 urlQuery.addQueryItem( QStringLiteral(
"geometry" ),
geometryField() );
295 const auto constFields =
fields();
296 for (
const QgsField &f : constFields )
298 if ( f.type() == QVariant::Int
299 || f.type() == QVariant::UInt
300 || f.type() == QVariant::Bool
301 || f.type() == QVariant::LongLong )
302 urlQuery.addQueryItem( QStringLiteral(
"field" ), f.name() +
":int" );
303 else if ( f.type() == QVariant::Double )
304 urlQuery.addQueryItem( QStringLiteral(
"field" ), f.name() +
":real" );
305 else if ( f.type() == QVariant::String )
306 urlQuery.addQueryItem( QStringLiteral(
"field" ), f.name() +
":text" );
311 urlQuery.addQueryItem( QStringLiteral(
"lazy" ), QString() );
316 urlQuery.addQueryItem( QStringLiteral(
"subsetstring" ), QUrl::toPercentEncoding(
subsetString() ) );
319 url.setQuery( urlQuery );
326 return QString(
toUrl().toEncoded() );
336 mSourceLayers.append(
SourceLayer( name, source, provider, encoding ) );
344 if ( l.name() == name )
357 if ( l.isReferenced() )
367 return mSubsetString;
Encapsulate a field in an attribute table or data source.
Container of fields for a vector layer.
bool append(const QgsField &field, FieldOrigin origin=OriginProvider, int originIndex=-1)
Appends a field. The field must have unique name, otherwise it is rejected (returns false)
QgsField at(int i) const
Gets field at particular index (must be in range 0..N-1)
A SourceLayer is either a reference to a live layer in the registry or all the parameters needed to l...
Class to manipulate the definition of a virtual layer.
QString geometryField() const
Gets the name of the geometry field. Empty if no geometry field.
QString query() const
Gets the SQL query.
QgsFields fields() const
Gets field definitions.
long geometrySrid() const
Gets the SRID of the geometry.
bool hasSourceLayer(const QString &name) const
Convenience method to test if a given source layer is part of the definition.
QgsVirtualLayerDefinition(const QString &filePath="")
Constructor with an optional file path.
void setUid(const QString &uid)
Sets the name of the field with unique identifiers.
bool hasDefinedGeometry() const
Convenient method to test if the geometry is defined (not NoGeometry and not Unknown)
void setSubsetString(const QString &subsetString)
Sets the subsetString.
const QgsVirtualLayerDefinition::SourceLayers & sourceLayers() const
Gets access to the source layers.
void setLazy(bool lazy)
Sets the lazy mode.
bool hasReferencedLayers() const
Convenience method to test whether the definition has referenced (live) layers.
void setFilePath(const QString &filePath)
Sets the file path.
void setGeometryWkbType(QgsWkbTypes::Type t)
Sets the type of the geometry.
QString subsetString() const
Returns the subset string.
QUrl toUrl() const
Convert the definition into a QUrl.
void setGeometrySrid(long srid)
Sets the SRID of the geometry.
void addSource(const QString &name, const QString &ref)
Add a live layer source layer.
void setGeometryField(const QString &geometryField)
Sets the name of the geometry field.
QString uid() const
Gets the name of the field with unique identifiers.
QString filePath() const
Gets the file path. May be empty.
QgsWkbTypes::Type geometryWkbType() const
Gets the type of the geometry QgsWkbTypes::NoGeometry to hide any geometry QgsWkbTypes::Unknown for u...
static QgsVirtualLayerDefinition fromUrl(const QUrl &url)
Constructor to build a definition from a QUrl The path part of the URL is extracted as well as the fo...
QString toString() const
Convert into a QString that can be read by the virtual layer provider.
void setFields(const QgsFields &fields)
Sets field definitions.
void setQuery(const QString &query)
Sets the SQL query.
bool isLazy() const
Returns the lazy mode.
static Type parseType(const QString &wktStr)
Attempts to extract the WKB type from a WKT string.
Type
The WKB type describes the number of dimensions a geometry has.
As part of the API refactoring and improvements which landed in the Processing API was substantially reworked from the x version This was done in order to allow much of the underlying Processing framework to be ported into c
bool qt_is_ascii(const char *&ptr, const char *end) noexcept
QString fromEncodedComponent_helper(const QByteArray &ba)
char toHexUpper(uint value) noexcept