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
Returns the 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