23 #include <QRegularExpression> 
   24 #include <QStringList> 
   29   : mFilePath( filePath )
 
   40   const QString columnNameRx( QStringLiteral( 
"[a-zA-Z_\x80-\xFF][a-zA-Z0-9_\x80-\xFF]*" ) );
 
   46   const QList<QPair<QString, QString> > items = QUrlQuery( url ).queryItems( QUrl::FullyEncoded );
 
   47   for ( 
int i = 0; i < items.size(); i++ )
 
   49     const QString key = items.
at( i ).first;
 
   50     const QString value = items.at( i ).second;
 
   51     if ( key == QLatin1String( 
"layer_ref" ) )
 
   55       const int pos = value.indexOf( 
':' );
 
   56       QString layerId, vlayerName;
 
   59         layerId = QUrl::fromPercentEncoding( value.toUtf8() );
 
   60         vlayerName = QStringLiteral( 
"vtab%1" ).arg( layerIdx );
 
   64         layerId = QUrl::fromPercentEncoding( value.left( pos ).toUtf8() );
 
   65         vlayerName = QUrl::fromPercentEncoding( value.mid( pos + 1 ).toUtf8() );
 
   70     else if ( key == QLatin1String( 
"layer" ) )
 
   74       const int pos = value.indexOf( 
':' );
 
   77         QString providerKey, source, vlayerName, encoding = QStringLiteral( 
"UTF-8" );
 
   79         providerKey = value.left( pos );
 
   80         int pos2 = value.indexOf( 
':', pos + 1 );
 
   81         if ( pos2 - pos == 2 )
 
   82           pos2 = value.indexOf( 
':', pos + 3 );
 
   85           source = QUrl::fromPercentEncoding( value.mid( pos + 1, pos2 - pos - 1 ).toUtf8() );
 
   86           const int pos3 = value.indexOf( 
':', pos2 + 1 );
 
   89             vlayerName = QUrl::fromPercentEncoding( value.mid( pos2 + 1, pos3 - pos2 - 1 ).toUtf8() );
 
   90             encoding = value.mid( pos3 + 1 );
 
   94             vlayerName = QUrl::fromPercentEncoding( value.mid( pos2 + 1 ).toUtf8() );
 
   99           source = QUrl::fromPercentEncoding( value.mid( pos + 1 ).toUtf8() );
 
  100           vlayerName = QStringLiteral( 
"vtab%1" ).arg( layerIdx );
 
  103         def.
addSource( vlayerName, source, providerKey, encoding );
 
  106     else if ( key == QLatin1String( 
"geometry" ) )
 
  110       const QRegularExpression reGeom( 
"(" + columnNameRx + 
")(?::([a-zA-Z0-9]+):(\\d+))?" );
 
  111       const QRegularExpressionMatch match = reGeom.match( value );
 
  112       if ( match.hasMatch() )
 
  115         if ( match.capturedTexts().size() > 2 )
 
  128     else if ( key == QLatin1String( 
"nogeometry" ) )
 
  132     else if ( key == QLatin1String( 
"uid" ) )
 
  136     else if ( key == QLatin1String( 
"query" ) )
 
  139       def.
setQuery( QUrl::fromPercentEncoding( value.toUtf8() ) );
 
  141     else if ( key == QLatin1String( 
"field" ) )
 
  144       const QRegularExpression reField( 
"(" + columnNameRx + 
"):(int|real|text)" );
 
  145       const QRegularExpressionMatch match = reField.match( value );
 
  146       if ( match.hasMatch() )
 
  148         const QString fieldName( match.captured( 1 ) );
 
  149         const QString fieldType( match.captured( 2 ) );
 
  150         if ( fieldType == QLatin1String( 
"int" ) )
 
  154         else if ( fieldType == QLatin1String( 
"real" ) )
 
  158         if ( fieldType == QLatin1String( 
"text" ) )
 
  164     else if ( key == QLatin1String( 
"lazy" ) )
 
  168     else if ( key == QLatin1String( 
"subsetstring" ) )
 
  182     url = QUrl::fromLocalFile( 
filePath() );
 
  184   QUrlQuery urlQuery( url );
 
  189     if ( l.isReferenced() )
 
  190       urlQuery.addQueryItem( QStringLiteral( 
"layer_ref" ), QStringLiteral( 
"%1:%2" ).arg( l.reference(), l.name() ) );
 
  197                                        QString( QUrl::toPercentEncoding( l.name() ) ),
 
  199                                        QString( QUrl::toPercentEncoding( l.source() ) ) ).toUtf8() ) );
 
  202   if ( !
query().isEmpty() )
 
  204     urlQuery.addQueryItem( QStringLiteral( 
"query" ), 
query() );
 
  207   if ( !
uid().isEmpty() )
 
  208     urlQuery.addQueryItem( QStringLiteral( 
"uid" ), 
uid() );
 
  211     urlQuery.addQueryItem( QStringLiteral( 
"nogeometry" ), QString() );
 
  217       urlQuery.addQueryItem( QStringLiteral( 
"geometry" ), 
geometryField() );
 
  220   const auto constFields = 
fields();
 
  221   for ( 
const QgsField &f : constFields )
 
  223     if ( f.type() == QVariant::Int
 
  224          || f.type() == QVariant::UInt
 
  225          || f.type() == QVariant::Bool
 
  226          || f.type() == QVariant::LongLong )
 
  227       urlQuery.addQueryItem( QStringLiteral( 
"field" ), f.name() + 
":int" );
 
  228     else if ( f.type() == QVariant::Double )
 
  229       urlQuery.addQueryItem( QStringLiteral( 
"field" ), f.name() + 
":real" );
 
  230     else if ( f.type() == QVariant::String )
 
  231       urlQuery.addQueryItem( QStringLiteral( 
"field" ), f.name() + 
":text" );
 
  236     urlQuery.addQueryItem( QStringLiteral( 
"lazy" ), QString() );
 
  241     urlQuery.addQueryItem( QStringLiteral( 
"subsetstring" ), QUrl::toPercentEncoding( 
subsetString() ) );
 
  244   url.setQuery( urlQuery );
 
  251   return QString( 
toUrl().toEncoded() );
 
  261   mSourceLayers.append( 
SourceLayer( name, source, provider, encoding ) );
 
  269     if ( l.name() == name )
 
  282     if ( l.isReferenced() )
 
  292   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.
QString fromEncodedComponent_helper(const QByteArray &ba)