19 #include <QStringList> 26 : mFilePath( filePath )
37 const QString columnNameRx( QStringLiteral(
"[a-zA-Z_\x80-\xFF][a-zA-Z0-9_\x80-\xFF]*" ) );
43 const QList<QPair<QString, QString> > items = QUrlQuery( url ).queryItems( QUrl::FullyEncoded );
44 for (
int i = 0; i < items.size(); i++ )
46 QString key = items.
at( i ).first;
47 QString value = items.at( i ).second;
48 if ( key == QLatin1String(
"layer_ref" ) )
52 int pos = value.indexOf(
':' );
53 QString layerId, vlayerName;
57 vlayerName = QStringLiteral(
"vtab%1" ).arg( layerIdx );
61 layerId = value.left( pos );
62 vlayerName = QUrl::fromPercentEncoding( value.mid( pos + 1 ).toUtf8() );
67 else if ( key == QLatin1String(
"layer" ) )
71 int pos = value.indexOf(
':' );
74 QString providerKey, source, vlayerName, encoding = QStringLiteral(
"UTF-8" );
76 providerKey = value.left( pos );
77 int pos2 = value.indexOf(
':', pos + 1 );
78 if ( pos2 - pos == 2 )
79 pos2 = value.indexOf(
':', pos + 3 );
82 source = QUrl::fromPercentEncoding( value.mid( pos + 1, pos2 - pos - 1 ).toUtf8() );
83 int pos3 = value.indexOf(
':', pos2 + 1 );
86 vlayerName = QUrl::fromPercentEncoding( value.mid( pos2 + 1, pos3 - pos2 - 1 ).toUtf8() );
87 encoding = value.mid( pos3 + 1 );
91 vlayerName = QUrl::fromPercentEncoding( value.mid( pos2 + 1 ).toUtf8() );
96 source = QUrl::fromPercentEncoding( value.mid( pos + 1 ).toUtf8() );
97 vlayerName = QStringLiteral(
"vtab%1" ).arg( layerIdx );
100 def.
addSource( vlayerName, source, providerKey, encoding );
103 else if ( key == QLatin1String(
"geometry" ) )
107 QRegExp reGeom(
"(" + columnNameRx +
")(?::([a-zA-Z0-9]+):(\\d+))?" );
108 int pos = reGeom.indexIn( value );
112 if ( reGeom.captureCount() > 1 )
125 else if ( key == QLatin1String(
"nogeometry" ) )
129 else if ( key == QLatin1String(
"uid" ) )
133 else if ( key == QLatin1String(
"query" ) )
136 def.
setQuery( QUrl::fromPercentEncoding( value.toUtf8() ) );
138 else if ( key == QLatin1String(
"field" ) )
141 QRegExp reField(
"(" + columnNameRx +
"):(int|real|text)" );
142 int pos = reField.indexIn( value );
145 QString fieldName( reField.cap( 1 ) );
146 QString fieldType( reField.cap( 2 ) );
147 if ( fieldType == QLatin1String(
"int" ) )
151 else if ( fieldType == QLatin1String(
"real" ) )
153 fields.
append(
QgsField( fieldName, QVariant::Double, fieldType ) );
155 if ( fieldType == QLatin1String(
"text" ) )
157 fields.
append(
QgsField( fieldName, QVariant::String, fieldType ) );
161 else if ( key == QLatin1String(
"lazy" ) )
177 return "0123456789ABCDEF"[value & 0xF];
180 static inline ushort encodeNibble( ushort
c )
187 while ( ptr + 4 <= end )
189 quint32 data = qFromUnaligned<quint32>( ptr );
190 if ( data &= 0x80808080U )
192 #if Q_BYTE_ORDER == Q_BIG_ENDIAN 193 uint idx = qCountLeadingZeroBits( data );
195 uint idx = qCountTrailingZeroBits( data );
204 if ( quint8( *ptr ) & 0x80 )
217 const char *in = ba.constData();
218 const char *
const end = ba.constEnd();
222 return QString::fromLatin1( ba, ba.size() );
225 QByteArray intermediate = ba;
226 intermediate.resize( ba.size() * 3 - ( in - ba.constData() ) );
227 uchar *out =
reinterpret_cast<uchar *
>( intermediate.data() + ( in - ba.constData() ) );
228 for ( ; in < end; ++in )
234 *out++ = encodeNibble( uchar( *in ) >> 4 );
235 *out++ = encodeNibble( uchar( *in ) & 0xf );
240 *out++ = uchar( *in );
244 return QString::fromLatin1( intermediate, out - reinterpret_cast<uchar *>( intermediate.data() ) );
251 url = QUrl::fromLocalFile(
filePath() );
253 QUrlQuery urlQuery( url );
258 if ( l.isReferenced() )
259 urlQuery.addQueryItem( QStringLiteral(
"layer_ref" ), QStringLiteral(
"%1:%2" ).arg( l.reference(), l.name() ) );
266 QString( QUrl::toPercentEncoding( l.name() ) ),
268 QString( QUrl::toPercentEncoding( l.source() ) ) ).toUtf8() ) );
271 if ( !
query().isEmpty() )
273 urlQuery.addQueryItem( QStringLiteral(
"query" ),
query() );
276 if ( !
uid().isEmpty() )
277 urlQuery.addQueryItem( QStringLiteral(
"uid" ),
uid() );
280 urlQuery.addQueryItem( QStringLiteral(
"nogeometry" ), QString() );
286 urlQuery.addQueryItem( QStringLiteral(
"geometry" ),
geometryField() );
289 const auto constFields =
fields();
290 for (
const QgsField &f : constFields )
292 if ( f.type() == QVariant::Int )
293 urlQuery.addQueryItem( QStringLiteral(
"field" ), f.name() +
":int" );
294 else if ( f.type() == QVariant::Double )
295 urlQuery.addQueryItem( QStringLiteral(
"field" ), f.name() +
":real" );
296 else if ( f.type() == QVariant::String )
297 urlQuery.addQueryItem( QStringLiteral(
"field" ), f.name() +
":text" );
302 urlQuery.addQueryItem( QStringLiteral(
"lazy" ), QString() );
305 url.setQuery( urlQuery );
312 return QString(
toUrl().toEncoded() );
322 mSourceLayers.append(
SourceLayer( name, source, provider, encoding ) );
330 if ( l.name() == name )
343 if ( l.isReferenced() )
bool hasReferencedLayers() const
Convenience method to test whether the definition has referenced (live) layers.
bool qt_is_ascii(const char *&ptr, const char *end) noexcept
void setFields(const QgsFields &fields)
Sets field definitions.
QString uid() const
Gets the name of the field with unique identifiers.
static Type parseType(const QString &wktStr)
Attempts to extract the WKB type from a WKT string.
Container of fields for a vector layer.
QString toString() const
Convert into a QString that can be read by the virtual layer provider.
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...
void addSource(const QString &name, const QString &ref)
Add a live layer source layer.
void setFilePath(const QString &filePath)
Sets the file path.
QgsField at(int i) const
Gets field at particular index (must be in range 0..N-1)
QUrl toUrl() const
Convert the definition into a QUrl.
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
QString filePath() const
Gets the file path. May be empty.
Type
The WKB type describes the number of dimensions a geometry has.
void setQuery(const QString &query)
Sets the SQL query.
char toHexUpper(uint value) noexcept
void setGeometryField(const QString &geometryField)
Sets the name of the geometry field.
bool isLazy() const
Returns the lazy mode.
QString geometryField() const
Gets the name of the geometry field. Empty if no geometry field.
QgsFields fields() const
Gets field definitions.
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) ...
Encapsulate a field in an attribute table or data source.
QString fromEncodedComponent_helper(const QByteArray &ba)
bool hasSourceLayer(const QString &name) const
Convenience method to test if a given source layer is part of the definition.
const QgsVirtualLayerDefinition::SourceLayers & sourceLayers() const
Gets access to the source layers.
void setGeometryWkbType(QgsWkbTypes::Type t)
Sets the type of the geometry.
bool hasDefinedGeometry() const
Convenient method to test if the geometry is defined (not NoGeometry and not Unknown) ...
void setUid(const QString &uid)
Sets the name of the field with unique identifiers.
void setGeometrySrid(long srid)
Sets the SRID of the geometry.
QString query() const
Gets the SQL query.
void setLazy(bool lazy)
Sets the lazy mode.
QgsVirtualLayerDefinition(const QString &filePath="")
Constructor with an optional file path.
QgsWkbTypes::Type geometryWkbType() const
Gets the type of the geometry QgsWkbTypes::NoGeometry to hide any geometry QgsWkbTypes::Unknown for u...
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.
long geometrySrid() const
Gets the SRID of the geometry.